1 /* Target-dependent code for GNU/Linux on MIPS processors. 2 3 Copyright 2001, 2002, 2004 Free Software Foundation, Inc. 4 5 This file is part of GDB. 6 7 This program is free software; you can redistribute it and/or modify 8 it under the terms of the GNU General Public License as published by 9 the Free Software Foundation; either version 2 of the License, or 10 (at your option) any later version. 11 12 This program is distributed in the hope that it will be useful, 13 but WITHOUT ANY WARRANTY; without even the implied warranty of 14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 GNU General Public License for more details. 16 17 You should have received a copy of the GNU General Public License 18 along with this program; if not, write to the Free Software 19 Foundation, Inc., 59 Temple Place - Suite 330, 20 Boston, MA 02111-1307, USA. */ 21 22 #include "defs.h" 23 #include "gdbcore.h" 24 #include "target.h" 25 #include "solib-svr4.h" 26 #include "osabi.h" 27 #include "mips-tdep.h" 28 #include "gdb_string.h" 29 #include "gdb_assert.h" 30 #include "frame.h" 31 #include "trad-frame.h" 32 #include "tramp-frame.h" 33 34 /* Copied from <asm/elf.h>. */ 35 #define ELF_NGREG 45 36 #define ELF_NFPREG 33 37 38 typedef unsigned char elf_greg_t[4]; 39 typedef elf_greg_t elf_gregset_t[ELF_NGREG]; 40 41 typedef unsigned char elf_fpreg_t[8]; 42 typedef elf_fpreg_t elf_fpregset_t[ELF_NFPREG]; 43 44 /* 0 - 31 are integer registers, 32 - 63 are fp registers. */ 45 #define FPR_BASE 32 46 #define PC 64 47 #define CAUSE 65 48 #define BADVADDR 66 49 #define MMHI 67 50 #define MMLO 68 51 #define FPC_CSR 69 52 #define FPC_EIR 70 53 54 #define EF_REG0 6 55 #define EF_REG31 37 56 #define EF_LO 38 57 #define EF_HI 39 58 #define EF_CP0_EPC 40 59 #define EF_CP0_BADVADDR 41 60 #define EF_CP0_STATUS 42 61 #define EF_CP0_CAUSE 43 62 63 #define EF_SIZE 180 64 65 /* Figure out where the longjmp will land. 66 We expect the first arg to be a pointer to the jmp_buf structure from 67 which we extract the pc (MIPS_LINUX_JB_PC) that we will land at. The pc 68 is copied into PC. This routine returns 1 on success. */ 69 70 #define MIPS_LINUX_JB_ELEMENT_SIZE 4 71 #define MIPS_LINUX_JB_PC 0 72 73 static int 74 mips_linux_get_longjmp_target (CORE_ADDR *pc) 75 { 76 CORE_ADDR jb_addr; 77 char buf[TARGET_PTR_BIT / TARGET_CHAR_BIT]; 78 79 jb_addr = read_register (A0_REGNUM); 80 81 if (target_read_memory (jb_addr 82 + MIPS_LINUX_JB_PC * MIPS_LINUX_JB_ELEMENT_SIZE, 83 buf, TARGET_PTR_BIT / TARGET_CHAR_BIT)) 84 return 0; 85 86 *pc = extract_unsigned_integer (buf, TARGET_PTR_BIT / TARGET_CHAR_BIT); 87 88 return 1; 89 } 90 91 /* Transform the bits comprising a 32-bit register to the right size 92 for regcache_raw_supply(). This is needed when mips_isa_regsize() 93 is 8. */ 94 95 static void 96 supply_32bit_reg (int regnum, const void *addr) 97 { 98 char buf[MAX_REGISTER_SIZE]; 99 store_signed_integer (buf, register_size (current_gdbarch, regnum), 100 extract_signed_integer (addr, 4)); 101 regcache_raw_supply (current_regcache, regnum, buf); 102 } 103 104 /* Unpack an elf_gregset_t into GDB's register cache. */ 105 106 void 107 supply_gregset (elf_gregset_t *gregsetp) 108 { 109 int regi; 110 elf_greg_t *regp = *gregsetp; 111 char zerobuf[MAX_REGISTER_SIZE]; 112 113 memset (zerobuf, 0, MAX_REGISTER_SIZE); 114 115 for (regi = EF_REG0; regi <= EF_REG31; regi++) 116 supply_32bit_reg ((regi - EF_REG0), (char *)(regp + regi)); 117 118 supply_32bit_reg (mips_regnum (current_gdbarch)->lo, 119 (char *)(regp + EF_LO)); 120 supply_32bit_reg (mips_regnum (current_gdbarch)->hi, 121 (char *)(regp + EF_HI)); 122 123 supply_32bit_reg (mips_regnum (current_gdbarch)->pc, 124 (char *)(regp + EF_CP0_EPC)); 125 supply_32bit_reg (mips_regnum (current_gdbarch)->badvaddr, 126 (char *)(regp + EF_CP0_BADVADDR)); 127 supply_32bit_reg (PS_REGNUM, (char *)(regp + EF_CP0_STATUS)); 128 supply_32bit_reg (mips_regnum (current_gdbarch)->cause, 129 (char *)(regp + EF_CP0_CAUSE)); 130 131 /* Fill inaccessible registers with zero. */ 132 regcache_raw_supply (current_regcache, UNUSED_REGNUM, zerobuf); 133 for (regi = FIRST_EMBED_REGNUM; regi < LAST_EMBED_REGNUM; regi++) 134 regcache_raw_supply (current_regcache, regi, zerobuf); 135 } 136 137 /* Pack our registers (or one register) into an elf_gregset_t. */ 138 139 void 140 fill_gregset (elf_gregset_t *gregsetp, int regno) 141 { 142 int regaddr, regi; 143 elf_greg_t *regp = *gregsetp; 144 void *dst; 145 146 if (regno == -1) 147 { 148 memset (regp, 0, sizeof (elf_gregset_t)); 149 for (regi = 0; regi < 32; regi++) 150 fill_gregset (gregsetp, regi); 151 fill_gregset (gregsetp, mips_regnum (current_gdbarch)->lo); 152 fill_gregset (gregsetp, mips_regnum (current_gdbarch)->hi); 153 fill_gregset (gregsetp, mips_regnum (current_gdbarch)->pc); 154 fill_gregset (gregsetp, mips_regnum (current_gdbarch)->badvaddr); 155 fill_gregset (gregsetp, PS_REGNUM); 156 fill_gregset (gregsetp, mips_regnum (current_gdbarch)->cause); 157 158 return; 159 } 160 161 if (regno < 32) 162 { 163 dst = regp + regno + EF_REG0; 164 regcache_raw_collect (current_regcache, regno, dst); 165 return; 166 } 167 168 if (regno == mips_regnum (current_gdbarch)->lo) 169 regaddr = EF_LO; 170 else if (regno == mips_regnum (current_gdbarch)->hi) 171 regaddr = EF_HI; 172 else if (regno == mips_regnum (current_gdbarch)->pc) 173 regaddr = EF_CP0_EPC; 174 else if (regno == mips_regnum (current_gdbarch)->badvaddr) 175 regaddr = EF_CP0_BADVADDR; 176 else if (regno == PS_REGNUM) 177 regaddr = EF_CP0_STATUS; 178 else if (regno == mips_regnum (current_gdbarch)->cause) 179 regaddr = EF_CP0_CAUSE; 180 else 181 regaddr = -1; 182 183 if (regaddr != -1) 184 { 185 dst = regp + regaddr; 186 regcache_raw_collect (current_regcache, regno, dst); 187 } 188 } 189 190 /* Likewise, unpack an elf_fpregset_t. */ 191 192 void 193 supply_fpregset (elf_fpregset_t *fpregsetp) 194 { 195 int regi; 196 char zerobuf[MAX_REGISTER_SIZE]; 197 198 memset (zerobuf, 0, MAX_REGISTER_SIZE); 199 200 for (regi = 0; regi < 32; regi++) 201 regcache_raw_supply (current_regcache, FP0_REGNUM + regi, 202 (char *)(*fpregsetp + regi)); 203 204 regcache_raw_supply (current_regcache, 205 mips_regnum (current_gdbarch)->fp_control_status, 206 (char *)(*fpregsetp + 32)); 207 208 /* FIXME: how can we supply FCRIR? The ABI doesn't tell us. */ 209 regcache_raw_supply (current_regcache, 210 mips_regnum (current_gdbarch)->fp_implementation_revision, 211 zerobuf); 212 } 213 214 /* Likewise, pack one or all floating point registers into an 215 elf_fpregset_t. */ 216 217 void 218 fill_fpregset (elf_fpregset_t *fpregsetp, int regno) 219 { 220 char *from, *to; 221 222 if ((regno >= FP0_REGNUM) && (regno < FP0_REGNUM + 32)) 223 { 224 from = (char *) &deprecated_registers[DEPRECATED_REGISTER_BYTE (regno)]; 225 to = (char *) (*fpregsetp + regno - FP0_REGNUM); 226 memcpy (to, from, register_size (current_gdbarch, regno - FP0_REGNUM)); 227 } 228 else if (regno == mips_regnum (current_gdbarch)->fp_control_status) 229 { 230 from = (char *) &deprecated_registers[DEPRECATED_REGISTER_BYTE (regno)]; 231 to = (char *) (*fpregsetp + 32); 232 memcpy (to, from, register_size (current_gdbarch, regno)); 233 } 234 else if (regno == -1) 235 { 236 int regi; 237 238 for (regi = 0; regi < 32; regi++) 239 fill_fpregset (fpregsetp, FP0_REGNUM + regi); 240 fill_fpregset(fpregsetp, mips_regnum (current_gdbarch)->fp_control_status); 241 } 242 } 243 244 /* Map gdb internal register number to ptrace ``address''. 245 These ``addresses'' are normally defined in <asm/ptrace.h>. */ 246 247 static CORE_ADDR 248 mips_linux_register_addr (int regno, CORE_ADDR blockend) 249 { 250 int regaddr; 251 252 if (regno < 0 || regno >= NUM_REGS) 253 error ("Bogon register number %d.", regno); 254 255 if (regno < 32) 256 regaddr = regno; 257 else if ((regno >= mips_regnum (current_gdbarch)->fp0) 258 && (regno < mips_regnum (current_gdbarch)->fp0 + 32)) 259 regaddr = FPR_BASE + (regno - mips_regnum (current_gdbarch)->fp0); 260 else if (regno == mips_regnum (current_gdbarch)->pc) 261 regaddr = PC; 262 else if (regno == mips_regnum (current_gdbarch)->cause) 263 regaddr = CAUSE; 264 else if (regno == mips_regnum (current_gdbarch)->badvaddr) 265 regaddr = BADVADDR; 266 else if (regno == mips_regnum (current_gdbarch)->lo) 267 regaddr = MMLO; 268 else if (regno == mips_regnum (current_gdbarch)->hi) 269 regaddr = MMHI; 270 else if (regno == mips_regnum (current_gdbarch)->fp_control_status) 271 regaddr = FPC_CSR; 272 else if (regno == mips_regnum (current_gdbarch)->fp_implementation_revision) 273 regaddr = FPC_EIR; 274 else 275 error ("Unknowable register number %d.", regno); 276 277 return regaddr; 278 } 279 280 281 /* Fetch (and possibly build) an appropriate link_map_offsets 282 structure for native GNU/Linux MIPS targets using the struct offsets 283 defined in link.h (but without actual reference to that file). 284 285 This makes it possible to access GNU/Linux MIPS shared libraries from a 286 GDB that was built on a different host platform (for cross debugging). */ 287 288 static struct link_map_offsets * 289 mips_linux_svr4_fetch_link_map_offsets (void) 290 { 291 static struct link_map_offsets lmo; 292 static struct link_map_offsets *lmp = NULL; 293 294 if (lmp == NULL) 295 { 296 lmp = &lmo; 297 298 lmo.r_debug_size = 8; /* The actual size is 20 bytes, but 299 this is all we need. */ 300 lmo.r_map_offset = 4; 301 lmo.r_map_size = 4; 302 303 lmo.link_map_size = 20; 304 305 lmo.l_addr_offset = 0; 306 lmo.l_addr_size = 4; 307 308 lmo.l_name_offset = 4; 309 lmo.l_name_size = 4; 310 311 lmo.l_next_offset = 12; 312 lmo.l_next_size = 4; 313 314 lmo.l_prev_offset = 16; 315 lmo.l_prev_size = 4; 316 } 317 318 return lmp; 319 } 320 321 /* Support for 64-bit ABIs. */ 322 323 /* Copied from <asm/elf.h>. */ 324 #define MIPS64_ELF_NGREG 45 325 #define MIPS64_ELF_NFPREG 33 326 327 typedef unsigned char mips64_elf_greg_t[8]; 328 typedef mips64_elf_greg_t mips64_elf_gregset_t[MIPS64_ELF_NGREG]; 329 330 typedef unsigned char mips64_elf_fpreg_t[8]; 331 typedef mips64_elf_fpreg_t mips64_elf_fpregset_t[MIPS64_ELF_NFPREG]; 332 333 /* 0 - 31 are integer registers, 32 - 63 are fp registers. */ 334 #define MIPS64_FPR_BASE 32 335 #define MIPS64_PC 64 336 #define MIPS64_CAUSE 65 337 #define MIPS64_BADVADDR 66 338 #define MIPS64_MMHI 67 339 #define MIPS64_MMLO 68 340 #define MIPS64_FPC_CSR 69 341 #define MIPS64_FPC_EIR 70 342 343 #define MIPS64_EF_REG0 0 344 #define MIPS64_EF_REG31 31 345 #define MIPS64_EF_LO 32 346 #define MIPS64_EF_HI 33 347 #define MIPS64_EF_CP0_EPC 34 348 #define MIPS64_EF_CP0_BADVADDR 35 349 #define MIPS64_EF_CP0_STATUS 36 350 #define MIPS64_EF_CP0_CAUSE 37 351 352 #define MIPS64_EF_SIZE 304 353 354 /* Figure out where the longjmp will land. 355 We expect the first arg to be a pointer to the jmp_buf structure from 356 which we extract the pc (MIPS_LINUX_JB_PC) that we will land at. The pc 357 is copied into PC. This routine returns 1 on success. */ 358 359 /* Details about jmp_buf. */ 360 361 #define MIPS64_LINUX_JB_PC 0 362 363 static int 364 mips64_linux_get_longjmp_target (CORE_ADDR *pc) 365 { 366 CORE_ADDR jb_addr; 367 void *buf = alloca (TARGET_PTR_BIT / TARGET_CHAR_BIT); 368 int element_size = TARGET_PTR_BIT == 32 ? 4 : 8; 369 370 jb_addr = read_register (A0_REGNUM); 371 372 if (target_read_memory (jb_addr + MIPS64_LINUX_JB_PC * element_size, 373 buf, TARGET_PTR_BIT / TARGET_CHAR_BIT)) 374 return 0; 375 376 *pc = extract_unsigned_integer (buf, TARGET_PTR_BIT / TARGET_CHAR_BIT); 377 378 return 1; 379 } 380 381 /* Unpack an elf_gregset_t into GDB's register cache. */ 382 383 static void 384 mips64_supply_gregset (mips64_elf_gregset_t *gregsetp) 385 { 386 int regi; 387 mips64_elf_greg_t *regp = *gregsetp; 388 char zerobuf[MAX_REGISTER_SIZE]; 389 390 memset (zerobuf, 0, MAX_REGISTER_SIZE); 391 392 for (regi = MIPS64_EF_REG0; regi <= MIPS64_EF_REG31; regi++) 393 regcache_raw_supply (current_regcache, (regi - MIPS64_EF_REG0), 394 (char *)(regp + regi)); 395 396 regcache_raw_supply (current_regcache, mips_regnum (current_gdbarch)->lo, 397 (char *)(regp + MIPS64_EF_LO)); 398 regcache_raw_supply (current_regcache, mips_regnum (current_gdbarch)->hi, 399 (char *)(regp + MIPS64_EF_HI)); 400 401 regcache_raw_supply (current_regcache, mips_regnum (current_gdbarch)->pc, 402 (char *)(regp + MIPS64_EF_CP0_EPC)); 403 regcache_raw_supply (current_regcache, mips_regnum (current_gdbarch)->badvaddr, 404 (char *)(regp + MIPS64_EF_CP0_BADVADDR)); 405 regcache_raw_supply (current_regcache, PS_REGNUM, 406 (char *)(regp + MIPS64_EF_CP0_STATUS)); 407 regcache_raw_supply (current_regcache, mips_regnum (current_gdbarch)->cause, 408 (char *)(regp + MIPS64_EF_CP0_CAUSE)); 409 410 /* Fill inaccessible registers with zero. */ 411 regcache_raw_supply (current_regcache, UNUSED_REGNUM, zerobuf); 412 for (regi = FIRST_EMBED_REGNUM; regi < LAST_EMBED_REGNUM; regi++) 413 regcache_raw_supply (current_regcache, regi, zerobuf); 414 } 415 416 /* Pack our registers (or one register) into an elf_gregset_t. */ 417 418 static void 419 mips64_fill_gregset (mips64_elf_gregset_t *gregsetp, int regno) 420 { 421 int regaddr, regi; 422 mips64_elf_greg_t *regp = *gregsetp; 423 void *src, *dst; 424 425 if (regno == -1) 426 { 427 memset (regp, 0, sizeof (mips64_elf_gregset_t)); 428 for (regi = 0; regi < 32; regi++) 429 mips64_fill_gregset (gregsetp, regi); 430 mips64_fill_gregset (gregsetp, mips_regnum (current_gdbarch)->lo); 431 mips64_fill_gregset (gregsetp, mips_regnum (current_gdbarch)->hi); 432 mips64_fill_gregset (gregsetp, mips_regnum (current_gdbarch)->pc); 433 mips64_fill_gregset (gregsetp, mips_regnum (current_gdbarch)->badvaddr); 434 mips64_fill_gregset (gregsetp, PS_REGNUM); 435 mips64_fill_gregset (gregsetp, mips_regnum (current_gdbarch)->cause); 436 437 return; 438 } 439 440 if (regno < 32) 441 { 442 dst = regp + regno + MIPS64_EF_REG0; 443 regcache_raw_collect (current_regcache, regno, dst); 444 return; 445 } 446 447 if (regno == mips_regnum (current_gdbarch)->lo) 448 regaddr = MIPS64_EF_LO; 449 else if (regno == mips_regnum (current_gdbarch)->hi) 450 regaddr = MIPS64_EF_HI; 451 else if (regno == mips_regnum (current_gdbarch)->pc) 452 regaddr = MIPS64_EF_CP0_EPC; 453 else if (regno == mips_regnum (current_gdbarch)->badvaddr) 454 regaddr = MIPS64_EF_CP0_BADVADDR; 455 else if (regno == PS_REGNUM) 456 regaddr = MIPS64_EF_CP0_STATUS; 457 else if (regno == mips_regnum (current_gdbarch)->cause) 458 regaddr = MIPS64_EF_CP0_CAUSE; 459 else 460 regaddr = -1; 461 462 if (regaddr != -1) 463 { 464 dst = regp + regaddr; 465 regcache_raw_collect (current_regcache, regno, dst); 466 } 467 } 468 469 /* Likewise, unpack an elf_fpregset_t. */ 470 471 static void 472 mips64_supply_fpregset (mips64_elf_fpregset_t *fpregsetp) 473 { 474 int regi; 475 char zerobuf[MAX_REGISTER_SIZE]; 476 477 memset (zerobuf, 0, MAX_REGISTER_SIZE); 478 479 for (regi = 0; regi < 32; regi++) 480 regcache_raw_supply (current_regcache, FP0_REGNUM + regi, 481 (char *)(*fpregsetp + regi)); 482 483 regcache_raw_supply (current_regcache, 484 mips_regnum (current_gdbarch)->fp_control_status, 485 (char *)(*fpregsetp + 32)); 486 487 /* FIXME: how can we supply FCRIR? The ABI doesn't tell us. */ 488 regcache_raw_supply (current_regcache, 489 mips_regnum (current_gdbarch)->fp_implementation_revision, 490 zerobuf); 491 } 492 493 /* Likewise, pack one or all floating point registers into an 494 elf_fpregset_t. */ 495 496 static void 497 mips64_fill_fpregset (mips64_elf_fpregset_t *fpregsetp, int regno) 498 { 499 char *from, *to; 500 501 if ((regno >= FP0_REGNUM) && (regno < FP0_REGNUM + 32)) 502 { 503 from = (char *) &deprecated_registers[DEPRECATED_REGISTER_BYTE (regno)]; 504 to = (char *) (*fpregsetp + regno - FP0_REGNUM); 505 memcpy (to, from, register_size (current_gdbarch, regno - FP0_REGNUM)); 506 } 507 else if (regno == mips_regnum (current_gdbarch)->fp_control_status) 508 { 509 from = (char *) &deprecated_registers[DEPRECATED_REGISTER_BYTE (regno)]; 510 to = (char *) (*fpregsetp + 32); 511 memcpy (to, from, register_size (current_gdbarch, regno)); 512 } 513 else if (regno == -1) 514 { 515 int regi; 516 517 for (regi = 0; regi < 32; regi++) 518 mips64_fill_fpregset (fpregsetp, FP0_REGNUM + regi); 519 mips64_fill_fpregset(fpregsetp, 520 mips_regnum (current_gdbarch)->fp_control_status); 521 } 522 } 523 524 525 /* Map gdb internal register number to ptrace ``address''. 526 These ``addresses'' are normally defined in <asm/ptrace.h>. */ 527 528 static CORE_ADDR 529 mips64_linux_register_addr (int regno, CORE_ADDR blockend) 530 { 531 int regaddr; 532 533 if (regno < 0 || regno >= NUM_REGS) 534 error ("Bogon register number %d.", regno); 535 536 if (regno < 32) 537 regaddr = regno; 538 else if ((regno >= mips_regnum (current_gdbarch)->fp0) 539 && (regno < mips_regnum (current_gdbarch)->fp0 + 32)) 540 regaddr = MIPS64_FPR_BASE + (regno - FP0_REGNUM); 541 else if (regno == mips_regnum (current_gdbarch)->pc) 542 regaddr = MIPS64_PC; 543 else if (regno == mips_regnum (current_gdbarch)->cause) 544 regaddr = MIPS64_CAUSE; 545 else if (regno == mips_regnum (current_gdbarch)->badvaddr) 546 regaddr = MIPS64_BADVADDR; 547 else if (regno == mips_regnum (current_gdbarch)->lo) 548 regaddr = MIPS64_MMLO; 549 else if (regno == mips_regnum (current_gdbarch)->hi) 550 regaddr = MIPS64_MMHI; 551 else if (regno == mips_regnum (current_gdbarch)->fp_control_status) 552 regaddr = MIPS64_FPC_CSR; 553 else if (regno == mips_regnum (current_gdbarch)->fp_implementation_revision) 554 regaddr = MIPS64_FPC_EIR; 555 else 556 error ("Unknowable register number %d.", regno); 557 558 return regaddr; 559 } 560 561 /* Use a local version of this function to get the correct types for 562 regsets, until multi-arch core support is ready. */ 563 564 static void 565 fetch_core_registers (char *core_reg_sect, unsigned core_reg_size, 566 int which, CORE_ADDR reg_addr) 567 { 568 elf_gregset_t gregset; 569 elf_fpregset_t fpregset; 570 mips64_elf_gregset_t gregset64; 571 mips64_elf_fpregset_t fpregset64; 572 573 if (which == 0) 574 { 575 if (core_reg_size == sizeof (gregset)) 576 { 577 memcpy ((char *) &gregset, core_reg_sect, sizeof (gregset)); 578 supply_gregset (&gregset); 579 } 580 else if (core_reg_size == sizeof (gregset64)) 581 { 582 memcpy ((char *) &gregset64, core_reg_sect, sizeof (gregset64)); 583 mips64_supply_gregset (&gregset64); 584 } 585 else 586 { 587 warning ("wrong size gregset struct in core file"); 588 } 589 } 590 else if (which == 2) 591 { 592 if (core_reg_size == sizeof (fpregset)) 593 { 594 memcpy ((char *) &fpregset, core_reg_sect, sizeof (fpregset)); 595 supply_fpregset (&fpregset); 596 } 597 else if (core_reg_size == sizeof (fpregset64)) 598 { 599 memcpy ((char *) &fpregset64, core_reg_sect, sizeof (fpregset64)); 600 mips64_supply_fpregset (&fpregset64); 601 } 602 else 603 { 604 warning ("wrong size fpregset struct in core file"); 605 } 606 } 607 } 608 609 /* Register that we are able to handle ELF file formats using standard 610 procfs "regset" structures. */ 611 612 static struct core_fns regset_core_fns = 613 { 614 bfd_target_elf_flavour, /* core_flavour */ 615 default_check_format, /* check_format */ 616 default_core_sniffer, /* core_sniffer */ 617 fetch_core_registers, /* core_read_registers */ 618 NULL /* next */ 619 }; 620 621 /* Fetch (and possibly build) an appropriate link_map_offsets 622 structure for native GNU/Linux MIPS targets using the struct offsets 623 defined in link.h (but without actual reference to that file). 624 625 This makes it possible to access GNU/Linux MIPS shared libraries from a 626 GDB that was built on a different host platform (for cross debugging). */ 627 628 static struct link_map_offsets * 629 mips64_linux_svr4_fetch_link_map_offsets (void) 630 { 631 static struct link_map_offsets lmo; 632 static struct link_map_offsets *lmp = NULL; 633 634 if (lmp == NULL) 635 { 636 lmp = &lmo; 637 638 lmo.r_debug_size = 16; /* The actual size is 40 bytes, but 639 this is all we need. */ 640 lmo.r_map_offset = 8; 641 lmo.r_map_size = 8; 642 643 lmo.link_map_size = 40; 644 645 lmo.l_addr_offset = 0; 646 lmo.l_addr_size = 8; 647 648 lmo.l_name_offset = 8; 649 lmo.l_name_size = 8; 650 651 lmo.l_next_offset = 24; 652 lmo.l_next_size = 8; 653 654 lmo.l_prev_offset = 32; 655 lmo.l_prev_size = 8; 656 } 657 658 return lmp; 659 } 660 661 /* Handle for obtaining pointer to the current register_addr() function 662 for a given architecture. */ 663 static struct gdbarch_data *register_addr_data; 664 665 CORE_ADDR 666 register_addr (int regno, CORE_ADDR blockend) 667 { 668 CORE_ADDR (*register_addr_ptr) (int, CORE_ADDR) = 669 gdbarch_data (current_gdbarch, register_addr_data); 670 671 gdb_assert (register_addr_ptr != 0); 672 673 return register_addr_ptr (regno, blockend); 674 } 675 676 static void 677 set_mips_linux_register_addr (struct gdbarch *gdbarch, 678 CORE_ADDR (*register_addr_ptr) (int, CORE_ADDR)) 679 { 680 deprecated_set_gdbarch_data (gdbarch, register_addr_data, register_addr_ptr); 681 } 682 683 static void * 684 init_register_addr_data (struct gdbarch *gdbarch) 685 { 686 return 0; 687 } 688 689 /* Check the code at PC for a dynamic linker lazy resolution stub. Because 690 they aren't in the .plt section, we pattern-match on the code generated 691 by GNU ld. They look like this: 692 693 lw t9,0x8010(gp) 694 addu t7,ra 695 jalr t9,ra 696 addiu t8,zero,INDEX 697 698 (with the appropriate doubleword instructions for N64). Also return the 699 dynamic symbol index used in the last instruction. */ 700 701 static int 702 mips_linux_in_dynsym_stub (CORE_ADDR pc, char *name) 703 { 704 unsigned char buf[28], *p; 705 ULONGEST insn, insn1; 706 int n64 = (mips_abi (current_gdbarch) == MIPS_ABI_N64); 707 708 read_memory (pc - 12, buf, 28); 709 710 if (n64) 711 { 712 /* ld t9,0x8010(gp) */ 713 insn1 = 0xdf998010; 714 } 715 else 716 { 717 /* lw t9,0x8010(gp) */ 718 insn1 = 0x8f998010; 719 } 720 721 p = buf + 12; 722 while (p >= buf) 723 { 724 insn = extract_unsigned_integer (p, 4); 725 if (insn == insn1) 726 break; 727 p -= 4; 728 } 729 if (p < buf) 730 return 0; 731 732 insn = extract_unsigned_integer (p + 4, 4); 733 if (n64) 734 { 735 /* daddu t7,ra */ 736 if (insn != 0x03e0782d) 737 return 0; 738 } 739 else 740 { 741 /* addu t7,ra */ 742 if (insn != 0x03e07821) 743 return 0; 744 } 745 746 insn = extract_unsigned_integer (p + 8, 4); 747 /* jalr t9,ra */ 748 if (insn != 0x0320f809) 749 return 0; 750 751 insn = extract_unsigned_integer (p + 12, 4); 752 if (n64) 753 { 754 /* daddiu t8,zero,0 */ 755 if ((insn & 0xffff0000) != 0x64180000) 756 return 0; 757 } 758 else 759 { 760 /* addiu t8,zero,0 */ 761 if ((insn & 0xffff0000) != 0x24180000) 762 return 0; 763 } 764 765 return (insn & 0xffff); 766 } 767 768 /* Return non-zero iff PC belongs to the dynamic linker resolution code 769 or to a stub. */ 770 771 int 772 mips_linux_in_dynsym_resolve_code (CORE_ADDR pc) 773 { 774 /* Check whether PC is in the dynamic linker. This also checks whether 775 it is in the .plt section, which MIPS does not use. */ 776 if (in_solib_dynsym_resolve_code (pc)) 777 return 1; 778 779 /* Pattern match for the stub. It would be nice if there were a more 780 efficient way to avoid this check. */ 781 if (mips_linux_in_dynsym_stub (pc, NULL)) 782 return 1; 783 784 return 0; 785 } 786 787 /* See the comments for SKIP_SOLIB_RESOLVER at the top of infrun.c, 788 and glibc_skip_solib_resolver in glibc-tdep.c. The normal glibc 789 implementation of this triggers at "fixup" from the same objfile as 790 "_dl_runtime_resolve"; MIPS GNU/Linux can trigger at 791 "__dl_runtime_resolve" directly. An unresolved PLT entry will 792 point to _dl_runtime_resolve, which will first call 793 __dl_runtime_resolve, and then pass control to the resolved 794 function. */ 795 796 static CORE_ADDR 797 mips_linux_skip_resolver (struct gdbarch *gdbarch, CORE_ADDR pc) 798 { 799 struct minimal_symbol *resolver; 800 801 resolver = lookup_minimal_symbol ("__dl_runtime_resolve", NULL, NULL); 802 803 if (resolver && SYMBOL_VALUE_ADDRESS (resolver) == pc) 804 return frame_pc_unwind (get_current_frame ()); 805 806 return 0; 807 } 808 809 /* Signal trampoline support. There are four supported layouts for a 810 signal frame: o32 sigframe, o32 rt_sigframe, n32 rt_sigframe, and 811 n64 rt_sigframe. We handle them all independently; not the most 812 efficient way, but simplest. First, declare all the unwinders. */ 813 814 static void mips_linux_o32_sigframe_init (const struct tramp_frame *self, 815 struct frame_info *next_frame, 816 struct trad_frame_cache *this_cache, 817 CORE_ADDR func); 818 819 static void mips_linux_n32n64_sigframe_init (const struct tramp_frame *self, 820 struct frame_info *next_frame, 821 struct trad_frame_cache *this_cache, 822 CORE_ADDR func); 823 824 #define MIPS_NR_LINUX 4000 825 #define MIPS_NR_N64_LINUX 5000 826 #define MIPS_NR_N32_LINUX 6000 827 828 #define MIPS_NR_sigreturn MIPS_NR_LINUX + 119 829 #define MIPS_NR_rt_sigreturn MIPS_NR_LINUX + 193 830 #define MIPS_NR_N64_rt_sigreturn MIPS_NR_N64_LINUX + 211 831 #define MIPS_NR_N32_rt_sigreturn MIPS_NR_N32_LINUX + 211 832 833 #define MIPS_INST_LI_V0_SIGRETURN 0x24020000 + MIPS_NR_sigreturn 834 #define MIPS_INST_LI_V0_RT_SIGRETURN 0x24020000 + MIPS_NR_rt_sigreturn 835 #define MIPS_INST_LI_V0_N64_RT_SIGRETURN 0x24020000 + MIPS_NR_N64_rt_sigreturn 836 #define MIPS_INST_LI_V0_N32_RT_SIGRETURN 0x24020000 + MIPS_NR_N32_rt_sigreturn 837 #define MIPS_INST_SYSCALL 0x0000000c 838 839 static const struct tramp_frame mips_linux_o32_sigframe = { 840 SIGTRAMP_FRAME, 841 4, 842 { 843 { MIPS_INST_LI_V0_SIGRETURN, -1 }, 844 { MIPS_INST_SYSCALL, -1 }, 845 { TRAMP_SENTINEL_INSN, -1 } 846 }, 847 mips_linux_o32_sigframe_init 848 }; 849 850 static const struct tramp_frame mips_linux_o32_rt_sigframe = { 851 SIGTRAMP_FRAME, 852 4, 853 { 854 { MIPS_INST_LI_V0_RT_SIGRETURN, -1 }, 855 { MIPS_INST_SYSCALL, -1 }, 856 { TRAMP_SENTINEL_INSN, -1 } }, 857 mips_linux_o32_sigframe_init 858 }; 859 860 static const struct tramp_frame mips_linux_n32_rt_sigframe = { 861 SIGTRAMP_FRAME, 862 4, 863 { 864 { MIPS_INST_LI_V0_N32_RT_SIGRETURN, -1 }, 865 { MIPS_INST_SYSCALL, -1 }, 866 { TRAMP_SENTINEL_INSN, -1 } 867 }, 868 mips_linux_n32n64_sigframe_init 869 }; 870 871 static const struct tramp_frame mips_linux_n64_rt_sigframe = { 872 SIGTRAMP_FRAME, 873 4, 874 { MIPS_INST_LI_V0_N64_RT_SIGRETURN, MIPS_INST_SYSCALL, TRAMP_SENTINEL_INSN }, 875 mips_linux_n32n64_sigframe_init 876 }; 877 878 /* *INDENT-OFF* */ 879 /* The unwinder for o32 signal frames. The legacy structures look 880 like this: 881 882 struct sigframe { 883 u32 sf_ass[4]; [argument save space for o32] 884 u32 sf_code[2]; [signal trampoline] 885 struct sigcontext sf_sc; 886 sigset_t sf_mask; 887 }; 888 889 struct sigcontext { 890 unsigned int sc_regmask; [Unused] 891 unsigned int sc_status; 892 unsigned long long sc_pc; 893 unsigned long long sc_regs[32]; 894 unsigned long long sc_fpregs[32]; 895 unsigned int sc_ownedfp; 896 unsigned int sc_fpc_csr; 897 unsigned int sc_fpc_eir; [Unused] 898 unsigned int sc_used_math; 899 unsigned int sc_ssflags; [Unused] 900 [Alignment hole of four bytes] 901 unsigned long long sc_mdhi; 902 unsigned long long sc_mdlo; 903 904 unsigned int sc_cause; [Unused] 905 unsigned int sc_badvaddr; [Unused] 906 907 unsigned long sc_sigset[4]; [kernel's sigset_t] 908 }; 909 910 The RT signal frames look like this: 911 912 struct rt_sigframe { 913 u32 rs_ass[4]; [argument save space for o32] 914 u32 rs_code[2] [signal trampoline] 915 struct siginfo rs_info; 916 struct ucontext rs_uc; 917 }; 918 919 struct ucontext { 920 unsigned long uc_flags; 921 struct ucontext *uc_link; 922 stack_t uc_stack; 923 [Alignment hole of four bytes] 924 struct sigcontext uc_mcontext; 925 sigset_t uc_sigmask; 926 }; */ 927 /* *INDENT-ON* */ 928 929 #define SIGFRAME_CODE_OFFSET (4 * 4) 930 #define SIGFRAME_SIGCONTEXT_OFFSET (6 * 4) 931 932 #define RTSIGFRAME_SIGINFO_SIZE 128 933 #define STACK_T_SIZE (3 * 4) 934 #define UCONTEXT_SIGCONTEXT_OFFSET (2 * 4 + STACK_T_SIZE + 4) 935 #define RTSIGFRAME_SIGCONTEXT_OFFSET (SIGFRAME_SIGCONTEXT_OFFSET \ 936 + RTSIGFRAME_SIGINFO_SIZE \ 937 + UCONTEXT_SIGCONTEXT_OFFSET) 938 939 #define SIGCONTEXT_PC (1 * 8) 940 #define SIGCONTEXT_REGS (2 * 8) 941 #define SIGCONTEXT_FPREGS (34 * 8) 942 #define SIGCONTEXT_FPCSR (66 * 8 + 4) 943 #define SIGCONTEXT_HI (69 * 8) 944 #define SIGCONTEXT_LO (70 * 8) 945 #define SIGCONTEXT_CAUSE (71 * 8 + 0) 946 #define SIGCONTEXT_BADVADDR (71 * 8 + 4) 947 948 #define SIGCONTEXT_REG_SIZE 8 949 950 static void 951 mips_linux_o32_sigframe_init (const struct tramp_frame *self, 952 struct frame_info *next_frame, 953 struct trad_frame_cache *this_cache, 954 CORE_ADDR func) 955 { 956 int ireg, reg_position; 957 CORE_ADDR sigcontext_base = func - SIGFRAME_CODE_OFFSET; 958 const struct mips_regnum *regs = mips_regnum (current_gdbarch); 959 960 if (self == &mips_linux_o32_sigframe) 961 sigcontext_base += SIGFRAME_SIGCONTEXT_OFFSET; 962 else 963 sigcontext_base += RTSIGFRAME_SIGCONTEXT_OFFSET; 964 965 /* I'm not proud of this hack. Eventually we will have the infrastructure 966 to indicate the size of saved registers on a per-frame basis, but 967 right now we don't; the kernel saves eight bytes but we only want 968 four. */ 969 if (TARGET_BYTE_ORDER == BFD_ENDIAN_BIG) 970 sigcontext_base += 4; 971 972 #if 0 973 trad_frame_set_reg_addr (this_cache, ORIG_ZERO_REGNUM + NUM_REGS, 974 sigcontext_base + SIGCONTEXT_REGS); 975 #endif 976 977 for (ireg = 1; ireg < 32; ireg++) 978 trad_frame_set_reg_addr (this_cache, ireg + ZERO_REGNUM + NUM_REGS, 979 sigcontext_base + SIGCONTEXT_REGS 980 + ireg * SIGCONTEXT_REG_SIZE); 981 982 for (ireg = 0; ireg < 32; ireg++) 983 trad_frame_set_reg_addr (this_cache, ireg + regs->fp0 + NUM_REGS, 984 sigcontext_base + SIGCONTEXT_FPREGS 985 + ireg * SIGCONTEXT_REG_SIZE); 986 987 trad_frame_set_reg_addr (this_cache, regs->pc + NUM_REGS, 988 sigcontext_base + SIGCONTEXT_PC); 989 990 trad_frame_set_reg_addr (this_cache, regs->fp_control_status + NUM_REGS, 991 sigcontext_base + SIGCONTEXT_FPCSR); 992 trad_frame_set_reg_addr (this_cache, regs->hi + NUM_REGS, 993 sigcontext_base + SIGCONTEXT_HI); 994 trad_frame_set_reg_addr (this_cache, regs->lo + NUM_REGS, 995 sigcontext_base + SIGCONTEXT_LO); 996 trad_frame_set_reg_addr (this_cache, regs->cause + NUM_REGS, 997 sigcontext_base + SIGCONTEXT_CAUSE); 998 trad_frame_set_reg_addr (this_cache, regs->badvaddr + NUM_REGS, 999 sigcontext_base + SIGCONTEXT_BADVADDR); 1000 1001 /* Choice of the bottom of the sigframe is somewhat arbitrary. */ 1002 trad_frame_set_id (this_cache, 1003 frame_id_build (func - SIGFRAME_CODE_OFFSET, func)); 1004 } 1005 1006 /* *INDENT-OFF* */ 1007 /* For N32/N64 things look different. There is no non-rt signal frame. 1008 1009 struct rt_sigframe_n32 { 1010 u32 rs_ass[4]; [ argument save space for o32 ] 1011 u32 rs_code[2]; [ signal trampoline ] 1012 struct siginfo rs_info; 1013 struct ucontextn32 rs_uc; 1014 }; 1015 1016 struct ucontextn32 { 1017 u32 uc_flags; 1018 s32 uc_link; 1019 stack32_t uc_stack; 1020 struct sigcontext uc_mcontext; 1021 sigset_t uc_sigmask; [ mask last for extensibility ] 1022 }; 1023 1024 struct rt_sigframe_n32 { 1025 u32 rs_ass[4]; [ argument save space for o32 ] 1026 u32 rs_code[2]; [ signal trampoline ] 1027 struct siginfo rs_info; 1028 struct ucontext rs_uc; 1029 }; 1030 1031 struct ucontext { 1032 unsigned long uc_flags; 1033 struct ucontext *uc_link; 1034 stack_t uc_stack; 1035 struct sigcontext uc_mcontext; 1036 sigset_t uc_sigmask; [ mask last for extensibility ] 1037 }; 1038 1039 And the sigcontext is different (this is for both n32 and n64): 1040 1041 struct sigcontext { 1042 unsigned long long sc_regs[32]; 1043 unsigned long long sc_fpregs[32]; 1044 unsigned long long sc_mdhi; 1045 unsigned long long sc_mdlo; 1046 unsigned long long sc_pc; 1047 unsigned int sc_status; 1048 unsigned int sc_fpc_csr; 1049 unsigned int sc_fpc_eir; 1050 unsigned int sc_used_math; 1051 unsigned int sc_cause; 1052 unsigned int sc_badvaddr; 1053 }; */ 1054 /* *INDENT-ON* */ 1055 1056 #define N32_STACK_T_SIZE STACK_T_SIZE 1057 #define N64_STACK_T_SIZE (2 * 8 + 4) 1058 #define N32_UCONTEXT_SIGCONTEXT_OFFSET (2 * 4 + N32_STACK_T_SIZE + 4) 1059 #define N64_UCONTEXT_SIGCONTEXT_OFFSET (2 * 8 + N64_STACK_T_SIZE + 4) 1060 #define N32_SIGFRAME_SIGCONTEXT_OFFSET (SIGFRAME_SIGCONTEXT_OFFSET \ 1061 + RTSIGFRAME_SIGINFO_SIZE \ 1062 + N32_UCONTEXT_SIGCONTEXT_OFFSET) 1063 #define N64_SIGFRAME_SIGCONTEXT_OFFSET (SIGFRAME_SIGCONTEXT_OFFSET \ 1064 + RTSIGFRAME_SIGINFO_SIZE \ 1065 + N64_UCONTEXT_SIGCONTEXT_OFFSET) 1066 1067 #define N64_SIGCONTEXT_REGS (0 * 8) 1068 #define N64_SIGCONTEXT_FPREGS (32 * 8) 1069 #define N64_SIGCONTEXT_HI (64 * 8) 1070 #define N64_SIGCONTEXT_LO (65 * 8) 1071 #define N64_SIGCONTEXT_PC (66 * 8) 1072 #define N64_SIGCONTEXT_FPCSR (67 * 8 + 1 * 4) 1073 #define N64_SIGCONTEXT_FIR (67 * 8 + 2 * 4) 1074 #define N64_SIGCONTEXT_CAUSE (67 * 8 + 4 * 4) 1075 #define N64_SIGCONTEXT_BADVADDR (67 * 8 + 5 * 4) 1076 1077 #define N64_SIGCONTEXT_REG_SIZE 8 1078 1079 static void 1080 mips_linux_n32n64_sigframe_init (const struct tramp_frame *self, 1081 struct frame_info *next_frame, 1082 struct trad_frame_cache *this_cache, 1083 CORE_ADDR func) 1084 { 1085 int ireg, reg_position; 1086 CORE_ADDR sigcontext_base = func - SIGFRAME_CODE_OFFSET; 1087 const struct mips_regnum *regs = mips_regnum (current_gdbarch); 1088 1089 if (self == &mips_linux_n32_rt_sigframe) 1090 sigcontext_base += N32_SIGFRAME_SIGCONTEXT_OFFSET; 1091 else 1092 sigcontext_base += N64_SIGFRAME_SIGCONTEXT_OFFSET; 1093 1094 #if 0 1095 trad_frame_set_reg_addr (this_cache, ORIG_ZERO_REGNUM + NUM_REGS, 1096 sigcontext_base + N64_SIGCONTEXT_REGS); 1097 #endif 1098 1099 for (ireg = 1; ireg < 32; ireg++) 1100 trad_frame_set_reg_addr (this_cache, ireg + ZERO_REGNUM + NUM_REGS, 1101 sigcontext_base + N64_SIGCONTEXT_REGS 1102 + ireg * N64_SIGCONTEXT_REG_SIZE); 1103 1104 for (ireg = 0; ireg < 32; ireg++) 1105 trad_frame_set_reg_addr (this_cache, ireg + regs->fp0 + NUM_REGS, 1106 sigcontext_base + N64_SIGCONTEXT_FPREGS 1107 + ireg * N64_SIGCONTEXT_REG_SIZE); 1108 1109 trad_frame_set_reg_addr (this_cache, regs->pc + NUM_REGS, 1110 sigcontext_base + N64_SIGCONTEXT_PC); 1111 1112 trad_frame_set_reg_addr (this_cache, regs->fp_control_status + NUM_REGS, 1113 sigcontext_base + N64_SIGCONTEXT_FPCSR); 1114 trad_frame_set_reg_addr (this_cache, regs->hi + NUM_REGS, 1115 sigcontext_base + N64_SIGCONTEXT_HI); 1116 trad_frame_set_reg_addr (this_cache, regs->lo + NUM_REGS, 1117 sigcontext_base + N64_SIGCONTEXT_LO); 1118 trad_frame_set_reg_addr (this_cache, regs->cause + NUM_REGS, 1119 sigcontext_base + N64_SIGCONTEXT_CAUSE); 1120 trad_frame_set_reg_addr (this_cache, regs->badvaddr + NUM_REGS, 1121 sigcontext_base + N64_SIGCONTEXT_BADVADDR); 1122 1123 /* Choice of the bottom of the sigframe is somewhat arbitrary. */ 1124 trad_frame_set_id (this_cache, 1125 frame_id_build (func - SIGFRAME_CODE_OFFSET, func)); 1126 } 1127 1128 /* Initialize one of the GNU/Linux OS ABIs. */ 1129 1130 static void 1131 mips_linux_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch) 1132 { 1133 struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); 1134 enum mips_abi abi = mips_abi (gdbarch); 1135 1136 switch (abi) 1137 { 1138 case MIPS_ABI_O32: 1139 set_gdbarch_get_longjmp_target (gdbarch, 1140 mips_linux_get_longjmp_target); 1141 set_solib_svr4_fetch_link_map_offsets 1142 (gdbarch, mips_linux_svr4_fetch_link_map_offsets); 1143 set_mips_linux_register_addr (gdbarch, mips_linux_register_addr); 1144 tramp_frame_prepend_unwinder (gdbarch, &mips_linux_o32_sigframe); 1145 tramp_frame_prepend_unwinder (gdbarch, &mips_linux_o32_rt_sigframe); 1146 break; 1147 case MIPS_ABI_N32: 1148 set_gdbarch_get_longjmp_target (gdbarch, 1149 mips_linux_get_longjmp_target); 1150 set_solib_svr4_fetch_link_map_offsets 1151 (gdbarch, mips_linux_svr4_fetch_link_map_offsets); 1152 set_mips_linux_register_addr (gdbarch, mips64_linux_register_addr); 1153 tramp_frame_prepend_unwinder (gdbarch, &mips_linux_n32_rt_sigframe); 1154 break; 1155 case MIPS_ABI_N64: 1156 set_gdbarch_get_longjmp_target (gdbarch, 1157 mips64_linux_get_longjmp_target); 1158 set_solib_svr4_fetch_link_map_offsets 1159 (gdbarch, mips64_linux_svr4_fetch_link_map_offsets); 1160 set_mips_linux_register_addr (gdbarch, mips64_linux_register_addr); 1161 tramp_frame_prepend_unwinder (gdbarch, &mips_linux_n64_rt_sigframe); 1162 break; 1163 default: 1164 internal_error (__FILE__, __LINE__, "can't handle ABI"); 1165 break; 1166 } 1167 1168 set_gdbarch_skip_solib_resolver (gdbarch, mips_linux_skip_resolver); 1169 1170 /* This overrides the MIPS16 stub support from mips-tdep. But no 1171 one uses MIPS16 on GNU/Linux yet, so this isn't much of a loss. */ 1172 set_gdbarch_in_solib_call_trampoline (gdbarch, mips_linux_in_dynsym_stub); 1173 } 1174 1175 void 1176 _initialize_mips_linux_tdep (void) 1177 { 1178 const struct bfd_arch_info *arch_info; 1179 1180 register_addr_data = 1181 gdbarch_data_register_post_init (init_register_addr_data); 1182 1183 for (arch_info = bfd_lookup_arch (bfd_arch_mips, 0); 1184 arch_info != NULL; 1185 arch_info = arch_info->next) 1186 { 1187 gdbarch_register_osabi (bfd_arch_mips, arch_info->mach, GDB_OSABI_LINUX, 1188 mips_linux_init_abi); 1189 } 1190 1191 deprecated_add_core_fns (®set_core_fns); 1192 } 1193