1 /* BFD back-end for MIPS Extended-Coff files. 2 Copyright (C) 1990-2016 Free Software Foundation, Inc. 3 Original version by Per Bothner. 4 Full support added by Ian Lance Taylor, ian (at) cygnus.com. 5 6 This file is part of BFD, the Binary File Descriptor library. 7 8 This program is free software; you can redistribute it and/or modify 9 it under the terms of the GNU General Public License as published by 10 the Free Software Foundation; either version 3 of the License, or 11 (at your option) any later version. 12 13 This program is distributed in the hope that it will be useful, 14 but WITHOUT ANY WARRANTY; without even the implied warranty of 15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 GNU General Public License for more details. 17 18 You should have received a copy of the GNU General Public License 19 along with this program; if not, write to the Free Software 20 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, 21 MA 02110-1301, USA. */ 22 23 #include "sysdep.h" 24 #include "bfd.h" 25 #include "bfdlink.h" 26 #include "libbfd.h" 27 #include "coff/internal.h" 28 #include "coff/sym.h" 29 #include "coff/symconst.h" 30 #include "coff/ecoff.h" 31 #include "coff/mips.h" 32 #include "libcoff.h" 33 #include "libecoff.h" 34 35 /* Prototypes for static functions. */ 37 static bfd_reloc_status_type 38 mips_generic_reloc 39 (bfd *, arelent *, asymbol *, void *, asection *, bfd *, char **); 40 static bfd_reloc_status_type 41 mips_refhi_reloc 42 (bfd *, arelent *, asymbol *, void *, asection *, bfd *, char **); 43 static bfd_reloc_status_type 44 mips_reflo_reloc 45 (bfd *, arelent *, asymbol *, void *, asection *, bfd *, char **); 46 static bfd_reloc_status_type 47 mips_gprel_reloc 48 (bfd *, arelent *, asymbol *, void *, asection *, bfd *, char **); 49 50 51 /* ECOFF has COFF sections, but the debugging information is stored in 53 a completely different format. ECOFF targets use some of the 54 swapping routines from coffswap.h, and some of the generic COFF 55 routines in coffgen.c, but, unlike the real COFF targets, do not 56 use coffcode.h itself. 57 58 Get the generic COFF swapping routines, except for the reloc, 59 symbol, and lineno ones. Give them ECOFF names. */ 60 #define MIPSECOFF 61 #define NO_COFF_RELOCS 62 #define NO_COFF_SYMBOLS 63 #define NO_COFF_LINENOS 64 #define coff_swap_filehdr_in mips_ecoff_swap_filehdr_in 65 #define coff_swap_filehdr_out mips_ecoff_swap_filehdr_out 66 #define coff_swap_aouthdr_in mips_ecoff_swap_aouthdr_in 67 #define coff_swap_aouthdr_out mips_ecoff_swap_aouthdr_out 68 #define coff_swap_scnhdr_in mips_ecoff_swap_scnhdr_in 69 #define coff_swap_scnhdr_out mips_ecoff_swap_scnhdr_out 70 71 #include "coffswap.h" 72 73 /* Get the ECOFF swapping routines. */ 74 #define ECOFF_32 75 #include "ecoffswap.h" 76 77 /* How to process the various relocs types. */ 79 80 static reloc_howto_type mips_howto_table[] = 81 { 82 /* Reloc type 0 is ignored. The reloc reading code ensures that 83 this is a reference to the .abs section, which will cause 84 bfd_perform_relocation to do nothing. */ 85 HOWTO (MIPS_R_IGNORE, /* type */ 86 0, /* rightshift */ 87 0, /* size (0 = byte, 1 = short, 2 = long) */ 88 8, /* bitsize */ 89 FALSE, /* pc_relative */ 90 0, /* bitpos */ 91 complain_overflow_dont, /* complain_on_overflow */ 92 0, /* special_function */ 93 "IGNORE", /* name */ 94 FALSE, /* partial_inplace */ 95 0, /* src_mask */ 96 0, /* dst_mask */ 97 FALSE), /* pcrel_offset */ 98 99 /* A 16 bit reference to a symbol, normally from a data section. */ 100 HOWTO (MIPS_R_REFHALF, /* type */ 101 0, /* rightshift */ 102 1, /* size (0 = byte, 1 = short, 2 = long) */ 103 16, /* bitsize */ 104 FALSE, /* pc_relative */ 105 0, /* bitpos */ 106 complain_overflow_bitfield, /* complain_on_overflow */ 107 mips_generic_reloc, /* special_function */ 108 "REFHALF", /* name */ 109 TRUE, /* partial_inplace */ 110 0xffff, /* src_mask */ 111 0xffff, /* dst_mask */ 112 FALSE), /* pcrel_offset */ 113 114 /* A 32 bit reference to a symbol, normally from a data section. */ 115 HOWTO (MIPS_R_REFWORD, /* type */ 116 0, /* rightshift */ 117 2, /* size (0 = byte, 1 = short, 2 = long) */ 118 32, /* bitsize */ 119 FALSE, /* pc_relative */ 120 0, /* bitpos */ 121 complain_overflow_bitfield, /* complain_on_overflow */ 122 mips_generic_reloc, /* special_function */ 123 "REFWORD", /* name */ 124 TRUE, /* partial_inplace */ 125 0xffffffff, /* src_mask */ 126 0xffffffff, /* dst_mask */ 127 FALSE), /* pcrel_offset */ 128 129 /* A 26 bit absolute jump address. */ 130 HOWTO (MIPS_R_JMPADDR, /* type */ 131 2, /* rightshift */ 132 2, /* size (0 = byte, 1 = short, 2 = long) */ 133 26, /* bitsize */ 134 FALSE, /* pc_relative */ 135 0, /* bitpos */ 136 complain_overflow_dont, /* complain_on_overflow */ 137 /* This needs complex overflow 138 detection, because the upper four 139 bits must match the PC. */ 140 mips_generic_reloc, /* special_function */ 141 "JMPADDR", /* name */ 142 TRUE, /* partial_inplace */ 143 0x3ffffff, /* src_mask */ 144 0x3ffffff, /* dst_mask */ 145 FALSE), /* pcrel_offset */ 146 147 /* The high 16 bits of a symbol value. Handled by the function 148 mips_refhi_reloc. */ 149 HOWTO (MIPS_R_REFHI, /* type */ 150 16, /* rightshift */ 151 2, /* size (0 = byte, 1 = short, 2 = long) */ 152 16, /* bitsize */ 153 FALSE, /* pc_relative */ 154 0, /* bitpos */ 155 complain_overflow_bitfield, /* complain_on_overflow */ 156 mips_refhi_reloc, /* special_function */ 157 "REFHI", /* name */ 158 TRUE, /* partial_inplace */ 159 0xffff, /* src_mask */ 160 0xffff, /* dst_mask */ 161 FALSE), /* pcrel_offset */ 162 163 /* The low 16 bits of a symbol value. */ 164 HOWTO (MIPS_R_REFLO, /* type */ 165 0, /* rightshift */ 166 2, /* size (0 = byte, 1 = short, 2 = long) */ 167 16, /* bitsize */ 168 FALSE, /* pc_relative */ 169 0, /* bitpos */ 170 complain_overflow_dont, /* complain_on_overflow */ 171 mips_reflo_reloc, /* special_function */ 172 "REFLO", /* name */ 173 TRUE, /* partial_inplace */ 174 0xffff, /* src_mask */ 175 0xffff, /* dst_mask */ 176 FALSE), /* pcrel_offset */ 177 178 /* A reference to an offset from the gp register. Handled by the 179 function mips_gprel_reloc. */ 180 HOWTO (MIPS_R_GPREL, /* type */ 181 0, /* rightshift */ 182 2, /* size (0 = byte, 1 = short, 2 = long) */ 183 16, /* bitsize */ 184 FALSE, /* pc_relative */ 185 0, /* bitpos */ 186 complain_overflow_signed, /* complain_on_overflow */ 187 mips_gprel_reloc, /* special_function */ 188 "GPREL", /* name */ 189 TRUE, /* partial_inplace */ 190 0xffff, /* src_mask */ 191 0xffff, /* dst_mask */ 192 FALSE), /* pcrel_offset */ 193 194 /* A reference to a literal using an offset from the gp register. 195 Handled by the function mips_gprel_reloc. */ 196 HOWTO (MIPS_R_LITERAL, /* type */ 197 0, /* rightshift */ 198 2, /* size (0 = byte, 1 = short, 2 = long) */ 199 16, /* bitsize */ 200 FALSE, /* pc_relative */ 201 0, /* bitpos */ 202 complain_overflow_signed, /* complain_on_overflow */ 203 mips_gprel_reloc, /* special_function */ 204 "LITERAL", /* name */ 205 TRUE, /* partial_inplace */ 206 0xffff, /* src_mask */ 207 0xffff, /* dst_mask */ 208 FALSE), /* pcrel_offset */ 209 210 EMPTY_HOWTO (8), 211 EMPTY_HOWTO (9), 212 EMPTY_HOWTO (10), 213 EMPTY_HOWTO (11), 214 215 /* FIXME: This relocation is used (internally only) to represent branches 216 when assembling. It should never appear in output files, and 217 be removed. (It used to be used for embedded-PIC support.) */ 218 HOWTO (MIPS_R_PCREL16, /* type */ 219 2, /* rightshift */ 220 2, /* size (0 = byte, 1 = short, 2 = long) */ 221 16, /* bitsize */ 222 TRUE, /* pc_relative */ 223 0, /* bitpos */ 224 complain_overflow_signed, /* complain_on_overflow */ 225 mips_generic_reloc, /* special_function */ 226 "PCREL16", /* name */ 227 TRUE, /* partial_inplace */ 228 0xffff, /* src_mask */ 229 0xffff, /* dst_mask */ 230 TRUE), /* pcrel_offset */ 231 }; 232 233 #define MIPS_HOWTO_COUNT \ 234 (sizeof mips_howto_table / sizeof mips_howto_table[0]) 235 236 /* See whether the magic number matches. */ 238 239 static bfd_boolean 240 mips_ecoff_bad_format_hook (bfd * abfd, void * filehdr) 241 { 242 struct internal_filehdr *internal_f = (struct internal_filehdr *) filehdr; 243 244 switch (internal_f->f_magic) 245 { 246 case MIPS_MAGIC_1: 247 /* I don't know what endianness this implies. */ 248 return TRUE; 249 250 case MIPS_MAGIC_BIG: 251 case MIPS_MAGIC_BIG2: 252 case MIPS_MAGIC_BIG3: 253 return bfd_big_endian (abfd); 254 255 case MIPS_MAGIC_LITTLE: 256 case MIPS_MAGIC_LITTLE2: 257 case MIPS_MAGIC_LITTLE3: 258 return bfd_little_endian (abfd); 259 260 default: 261 return FALSE; 262 } 263 } 264 265 /* Reloc handling. MIPS ECOFF relocs are packed into 8 bytes in 267 external form. They use a bit which indicates whether the symbol 268 is external. */ 269 270 /* Swap a reloc in. */ 271 272 static void 273 mips_ecoff_swap_reloc_in (bfd * abfd, 274 void * ext_ptr, 275 struct internal_reloc *intern) 276 { 277 const RELOC *ext = (RELOC *) ext_ptr; 278 279 intern->r_vaddr = H_GET_32 (abfd, ext->r_vaddr); 280 if (bfd_header_big_endian (abfd)) 281 { 282 intern->r_symndx = (((int) ext->r_bits[0] 283 << RELOC_BITS0_SYMNDX_SH_LEFT_BIG) 284 | ((int) ext->r_bits[1] 285 << RELOC_BITS1_SYMNDX_SH_LEFT_BIG) 286 | ((int) ext->r_bits[2] 287 << RELOC_BITS2_SYMNDX_SH_LEFT_BIG)); 288 intern->r_type = ((ext->r_bits[3] & RELOC_BITS3_TYPE_BIG) 289 >> RELOC_BITS3_TYPE_SH_BIG); 290 intern->r_extern = (ext->r_bits[3] & RELOC_BITS3_EXTERN_BIG) != 0; 291 } 292 else 293 { 294 intern->r_symndx = (((int) ext->r_bits[0] 295 << RELOC_BITS0_SYMNDX_SH_LEFT_LITTLE) 296 | ((int) ext->r_bits[1] 297 << RELOC_BITS1_SYMNDX_SH_LEFT_LITTLE) 298 | ((int) ext->r_bits[2] 299 << RELOC_BITS2_SYMNDX_SH_LEFT_LITTLE)); 300 intern->r_type = (((ext->r_bits[3] & RELOC_BITS3_TYPE_LITTLE) 301 >> RELOC_BITS3_TYPE_SH_LITTLE) 302 | ((ext->r_bits[3] & RELOC_BITS3_TYPEHI_LITTLE) 303 << RELOC_BITS3_TYPEHI_SH_LITTLE)); 304 intern->r_extern = (ext->r_bits[3] & RELOC_BITS3_EXTERN_LITTLE) != 0; 305 } 306 } 307 308 /* Swap a reloc out. */ 309 310 static void 311 mips_ecoff_swap_reloc_out (bfd * abfd, 312 const struct internal_reloc * intern, 313 void * dst) 314 { 315 RELOC *ext = (RELOC *) dst; 316 long r_symndx; 317 318 BFD_ASSERT (intern->r_extern 319 || (intern->r_symndx >= 0 && intern->r_symndx <= 12)); 320 321 r_symndx = intern->r_symndx; 322 323 H_PUT_32 (abfd, intern->r_vaddr, ext->r_vaddr); 324 if (bfd_header_big_endian (abfd)) 325 { 326 ext->r_bits[0] = r_symndx >> RELOC_BITS0_SYMNDX_SH_LEFT_BIG; 327 ext->r_bits[1] = r_symndx >> RELOC_BITS1_SYMNDX_SH_LEFT_BIG; 328 ext->r_bits[2] = r_symndx >> RELOC_BITS2_SYMNDX_SH_LEFT_BIG; 329 ext->r_bits[3] = (((intern->r_type << RELOC_BITS3_TYPE_SH_BIG) 330 & RELOC_BITS3_TYPE_BIG) 331 | (intern->r_extern ? RELOC_BITS3_EXTERN_BIG : 0)); 332 } 333 else 334 { 335 ext->r_bits[0] = r_symndx >> RELOC_BITS0_SYMNDX_SH_LEFT_LITTLE; 336 ext->r_bits[1] = r_symndx >> RELOC_BITS1_SYMNDX_SH_LEFT_LITTLE; 337 ext->r_bits[2] = r_symndx >> RELOC_BITS2_SYMNDX_SH_LEFT_LITTLE; 338 ext->r_bits[3] = (((intern->r_type << RELOC_BITS3_TYPE_SH_LITTLE) 339 & RELOC_BITS3_TYPE_LITTLE) 340 | ((intern->r_type >> RELOC_BITS3_TYPEHI_SH_LITTLE 341 & RELOC_BITS3_TYPEHI_LITTLE)) 342 | (intern->r_extern ? RELOC_BITS3_EXTERN_LITTLE : 0)); 343 } 344 } 345 346 /* Finish canonicalizing a reloc. Part of this is generic to all 347 ECOFF targets, and that part is in ecoff.c. The rest is done in 348 this backend routine. It must fill in the howto field. */ 349 350 static void 351 mips_adjust_reloc_in (bfd *abfd, 352 const struct internal_reloc *intern, 353 arelent *rptr) 354 { 355 if (intern->r_type > MIPS_R_PCREL16) 356 abort (); 357 358 if (! intern->r_extern 359 && (intern->r_type == MIPS_R_GPREL 360 || intern->r_type == MIPS_R_LITERAL)) 361 rptr->addend += ecoff_data (abfd)->gp; 362 363 /* If the type is MIPS_R_IGNORE, make sure this is a reference to 364 the absolute section so that the reloc is ignored. */ 365 if (intern->r_type == MIPS_R_IGNORE) 366 rptr->sym_ptr_ptr = bfd_abs_section_ptr->symbol_ptr_ptr; 367 368 rptr->howto = &mips_howto_table[intern->r_type]; 369 } 370 371 /* Make any adjustments needed to a reloc before writing it out. None 372 are needed for MIPS. */ 373 374 static void 375 mips_adjust_reloc_out (bfd *abfd ATTRIBUTE_UNUSED, 376 const arelent *rel ATTRIBUTE_UNUSED, 377 struct internal_reloc *intern ATTRIBUTE_UNUSED) 378 { 379 } 380 381 /* ECOFF relocs are either against external symbols, or against 382 sections. If we are producing relocatable output, and the reloc 383 is against an external symbol, and nothing has given us any 384 additional addend, the resulting reloc will also be against the 385 same symbol. In such a case, we don't want to change anything 386 about the way the reloc is handled, since it will all be done at 387 final link time. Rather than put special case code into 388 bfd_perform_relocation, all the reloc types use this howto 389 function. It just short circuits the reloc if producing 390 relocatable output against an external symbol. */ 391 392 static bfd_reloc_status_type 393 mips_generic_reloc (bfd *abfd ATTRIBUTE_UNUSED, 394 arelent *reloc_entry, 395 asymbol *symbol, 396 void * data ATTRIBUTE_UNUSED, 397 asection *input_section, 398 bfd *output_bfd, 399 char **error_message ATTRIBUTE_UNUSED) 400 { 401 if (output_bfd != (bfd *) NULL 402 && (symbol->flags & BSF_SECTION_SYM) == 0 403 && reloc_entry->addend == 0) 404 { 405 reloc_entry->address += input_section->output_offset; 406 return bfd_reloc_ok; 407 } 408 409 return bfd_reloc_continue; 410 } 411 412 /* Do a REFHI relocation. This has to be done in combination with a 413 REFLO reloc, because there is a carry from the REFLO to the REFHI. 414 Here we just save the information we need; we do the actual 415 relocation when we see the REFLO. MIPS ECOFF requires that the 416 REFLO immediately follow the REFHI. As a GNU extension, we permit 417 an arbitrary number of HI relocs to be associated with a single LO 418 reloc. This extension permits gcc to output the HI and LO relocs 419 itself. */ 420 421 struct mips_hi 422 { 423 struct mips_hi *next; 424 bfd_byte *addr; 425 bfd_vma addend; 426 }; 427 428 /* FIXME: This should not be a static variable. */ 429 430 static struct mips_hi *mips_refhi_list; 431 432 static bfd_reloc_status_type 433 mips_refhi_reloc (bfd *abfd ATTRIBUTE_UNUSED, 434 arelent *reloc_entry, 435 asymbol *symbol, 436 void * data, 437 asection *input_section, 438 bfd *output_bfd, 439 char **error_message ATTRIBUTE_UNUSED) 440 { 441 bfd_reloc_status_type ret; 442 bfd_vma relocation; 443 struct mips_hi *n; 444 445 /* If we're relocating, and this an external symbol, we don't want 446 to change anything. */ 447 if (output_bfd != (bfd *) NULL 448 && (symbol->flags & BSF_SECTION_SYM) == 0 449 && reloc_entry->addend == 0) 450 { 451 reloc_entry->address += input_section->output_offset; 452 return bfd_reloc_ok; 453 } 454 455 ret = bfd_reloc_ok; 456 if (bfd_is_und_section (symbol->section) 457 && output_bfd == (bfd *) NULL) 458 ret = bfd_reloc_undefined; 459 460 if (bfd_is_com_section (symbol->section)) 461 relocation = 0; 462 else 463 relocation = symbol->value; 464 465 relocation += symbol->section->output_section->vma; 466 relocation += symbol->section->output_offset; 467 relocation += reloc_entry->addend; 468 469 if (reloc_entry->address > bfd_get_section_limit (abfd, input_section)) 470 return bfd_reloc_outofrange; 471 472 /* Save the information, and let REFLO do the actual relocation. */ 473 n = (struct mips_hi *) bfd_malloc ((bfd_size_type) sizeof *n); 474 if (n == NULL) 475 return bfd_reloc_outofrange; 476 n->addr = (bfd_byte *) data + reloc_entry->address; 477 n->addend = relocation; 478 n->next = mips_refhi_list; 479 mips_refhi_list = n; 480 481 if (output_bfd != (bfd *) NULL) 482 reloc_entry->address += input_section->output_offset; 483 484 return ret; 485 } 486 487 /* Do a REFLO relocation. This is a straightforward 16 bit inplace 488 relocation; this function exists in order to do the REFHI 489 relocation described above. */ 490 491 static bfd_reloc_status_type 492 mips_reflo_reloc (bfd *abfd ATTRIBUTE_UNUSED, 493 arelent *reloc_entry, 494 asymbol *symbol, 495 void * data, 496 asection *input_section, 497 bfd *output_bfd, 498 char **error_message ATTRIBUTE_UNUSED) 499 { 500 if (mips_refhi_list != NULL) 501 { 502 struct mips_hi *l; 503 504 l = mips_refhi_list; 505 while (l != NULL) 506 { 507 unsigned long insn; 508 unsigned long val; 509 unsigned long vallo; 510 struct mips_hi *next; 511 512 /* Do the REFHI relocation. Note that we actually don't 513 need to know anything about the REFLO itself, except 514 where to find the low 16 bits of the addend needed by the 515 REFHI. */ 516 insn = bfd_get_32 (abfd, l->addr); 517 vallo = (bfd_get_32 (abfd, (bfd_byte *) data + reloc_entry->address) 518 & 0xffff); 519 val = ((insn & 0xffff) << 16) + vallo; 520 val += l->addend; 521 522 /* The low order 16 bits are always treated as a signed 523 value. Therefore, a negative value in the low order bits 524 requires an adjustment in the high order bits. We need 525 to make this adjustment in two ways: once for the bits we 526 took from the data, and once for the bits we are putting 527 back in to the data. */ 528 if ((vallo & 0x8000) != 0) 529 val -= 0x10000; 530 if ((val & 0x8000) != 0) 531 val += 0x10000; 532 533 insn = (insn &~ (unsigned) 0xffff) | ((val >> 16) & 0xffff); 534 bfd_put_32 (abfd, (bfd_vma) insn, l->addr); 535 536 next = l->next; 537 free (l); 538 l = next; 539 } 540 541 mips_refhi_list = NULL; 542 } 543 544 /* Now do the REFLO reloc in the usual way. */ 545 return mips_generic_reloc (abfd, reloc_entry, symbol, data, 546 input_section, output_bfd, error_message); 547 } 548 549 /* Do a GPREL relocation. This is a 16 bit value which must become 550 the offset from the gp register. */ 551 552 static bfd_reloc_status_type 553 mips_gprel_reloc (bfd *abfd ATTRIBUTE_UNUSED, 554 arelent *reloc_entry, 555 asymbol *symbol, 556 void * data, 557 asection *input_section, 558 bfd *output_bfd, 559 char **error_message ATTRIBUTE_UNUSED) 560 { 561 bfd_boolean relocatable; 562 bfd_vma gp; 563 bfd_vma relocation; 564 unsigned long val; 565 unsigned long insn; 566 567 /* If we're relocating, and this is an external symbol with no 568 addend, we don't want to change anything. We will only have an 569 addend if this is a newly created reloc, not read from an ECOFF 570 file. */ 571 if (output_bfd != (bfd *) NULL 572 && (symbol->flags & BSF_SECTION_SYM) == 0 573 && reloc_entry->addend == 0) 574 { 575 reloc_entry->address += input_section->output_offset; 576 return bfd_reloc_ok; 577 } 578 579 if (output_bfd != (bfd *) NULL) 580 relocatable = TRUE; 581 else 582 { 583 relocatable = FALSE; 584 output_bfd = symbol->section->output_section->owner; 585 } 586 587 if (bfd_is_und_section (symbol->section) && ! relocatable) 588 return bfd_reloc_undefined; 589 590 /* We have to figure out the gp value, so that we can adjust the 591 symbol value correctly. We look up the symbol _gp in the output 592 BFD. If we can't find it, we're stuck. We cache it in the ECOFF 593 target data. We don't need to adjust the symbol value for an 594 external symbol if we are producing relocatable output. */ 595 gp = _bfd_get_gp_value (output_bfd); 596 if (gp == 0 597 && (! relocatable 598 || (symbol->flags & BSF_SECTION_SYM) != 0)) 599 { 600 if (relocatable) 601 { 602 /* Make up a value. */ 603 gp = symbol->section->output_section->vma + 0x4000; 604 _bfd_set_gp_value (output_bfd, gp); 605 } 606 else 607 { 608 unsigned int count; 609 asymbol **sym; 610 unsigned int i; 611 612 count = bfd_get_symcount (output_bfd); 613 sym = bfd_get_outsymbols (output_bfd); 614 615 if (sym == (asymbol **) NULL) 616 i = count; 617 else 618 { 619 for (i = 0; i < count; i++, sym++) 620 { 621 register const char *name; 622 623 name = bfd_asymbol_name (*sym); 624 if (*name == '_' && strcmp (name, "_gp") == 0) 625 { 626 gp = bfd_asymbol_value (*sym); 627 _bfd_set_gp_value (output_bfd, gp); 628 break; 629 } 630 } 631 } 632 633 if (i >= count) 634 { 635 /* Only get the error once. */ 636 gp = 4; 637 _bfd_set_gp_value (output_bfd, gp); 638 *error_message = 639 (char *) _("GP relative relocation when _gp not defined"); 640 return bfd_reloc_dangerous; 641 } 642 } 643 } 644 645 if (bfd_is_com_section (symbol->section)) 646 relocation = 0; 647 else 648 relocation = symbol->value; 649 650 relocation += symbol->section->output_section->vma; 651 relocation += symbol->section->output_offset; 652 653 if (reloc_entry->address > bfd_get_section_limit (abfd, input_section)) 654 return bfd_reloc_outofrange; 655 656 insn = bfd_get_32 (abfd, (bfd_byte *) data + reloc_entry->address); 657 658 /* Set val to the offset into the section or symbol. */ 659 val = ((insn & 0xffff) + reloc_entry->addend) & 0xffff; 660 if (val & 0x8000) 661 val -= 0x10000; 662 663 /* Adjust val for the final section location and GP value. If we 664 are producing relocatable output, we don't want to do this for 665 an external symbol. */ 666 if (! relocatable 667 || (symbol->flags & BSF_SECTION_SYM) != 0) 668 val += relocation - gp; 669 670 insn = (insn &~ (unsigned) 0xffff) | (val & 0xffff); 671 bfd_put_32 (abfd, (bfd_vma) insn, (bfd_byte *) data + reloc_entry->address); 672 673 if (relocatable) 674 reloc_entry->address += input_section->output_offset; 675 676 /* Make sure it fit in 16 bits. */ 677 if ((long) val >= 0x8000 || (long) val < -0x8000) 678 return bfd_reloc_overflow; 679 680 return bfd_reloc_ok; 681 } 682 683 /* Get the howto structure for a generic reloc type. */ 684 685 static reloc_howto_type * 686 mips_bfd_reloc_type_lookup (bfd *abfd ATTRIBUTE_UNUSED, 687 bfd_reloc_code_real_type code) 688 { 689 int mips_type; 690 691 switch (code) 692 { 693 case BFD_RELOC_16: 694 mips_type = MIPS_R_REFHALF; 695 break; 696 case BFD_RELOC_32: 697 case BFD_RELOC_CTOR: 698 mips_type = MIPS_R_REFWORD; 699 break; 700 case BFD_RELOC_MIPS_JMP: 701 mips_type = MIPS_R_JMPADDR; 702 break; 703 case BFD_RELOC_HI16_S: 704 mips_type = MIPS_R_REFHI; 705 break; 706 case BFD_RELOC_LO16: 707 mips_type = MIPS_R_REFLO; 708 break; 709 case BFD_RELOC_GPREL16: 710 mips_type = MIPS_R_GPREL; 711 break; 712 case BFD_RELOC_MIPS_LITERAL: 713 mips_type = MIPS_R_LITERAL; 714 break; 715 case BFD_RELOC_16_PCREL_S2: 716 mips_type = MIPS_R_PCREL16; 717 break; 718 default: 719 return (reloc_howto_type *) NULL; 720 } 721 722 return &mips_howto_table[mips_type]; 723 } 724 725 static reloc_howto_type * 726 mips_bfd_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED, 727 const char *r_name) 728 { 729 unsigned int i; 730 731 for (i = 0; 732 i < sizeof (mips_howto_table) / sizeof (mips_howto_table[0]); 733 i++) 734 if (mips_howto_table[i].name != NULL 735 && strcasecmp (mips_howto_table[i].name, r_name) == 0) 736 return &mips_howto_table[i]; 737 738 return NULL; 739 } 740 741 /* A helper routine for mips_relocate_section which handles the REFHI 743 relocations. The REFHI relocation must be followed by a REFLO 744 relocation, and the addend used is formed from the addends of both 745 instructions. */ 746 747 static void 748 mips_relocate_hi (struct internal_reloc *refhi, 749 struct internal_reloc *reflo, 750 bfd *input_bfd, 751 asection *input_section, 752 bfd_byte *contents, 753 bfd_vma relocation) 754 { 755 unsigned long insn; 756 unsigned long val; 757 unsigned long vallo; 758 759 if (refhi == NULL) 760 return; 761 762 insn = bfd_get_32 (input_bfd, 763 contents + refhi->r_vaddr - input_section->vma); 764 if (reflo == NULL) 765 vallo = 0; 766 else 767 vallo = (bfd_get_32 (input_bfd, 768 contents + reflo->r_vaddr - input_section->vma) 769 & 0xffff); 770 771 val = ((insn & 0xffff) << 16) + vallo; 772 val += relocation; 773 774 /* The low order 16 bits are always treated as a signed value. 775 Therefore, a negative value in the low order bits requires an 776 adjustment in the high order bits. We need to make this 777 adjustment in two ways: once for the bits we took from the data, 778 and once for the bits we are putting back in to the data. */ 779 if ((vallo & 0x8000) != 0) 780 val -= 0x10000; 781 782 if ((val & 0x8000) != 0) 783 val += 0x10000; 784 785 insn = (insn &~ (unsigned) 0xffff) | ((val >> 16) & 0xffff); 786 bfd_put_32 (input_bfd, (bfd_vma) insn, 787 contents + refhi->r_vaddr - input_section->vma); 788 } 789 790 /* Relocate a section while linking a MIPS ECOFF file. */ 791 792 static bfd_boolean 793 mips_relocate_section (bfd *output_bfd, 794 struct bfd_link_info *info, 795 bfd *input_bfd, 796 asection *input_section, 797 bfd_byte *contents, 798 void * external_relocs) 799 { 800 asection **symndx_to_section; 801 struct ecoff_link_hash_entry **sym_hashes; 802 bfd_vma gp; 803 bfd_boolean gp_undefined; 804 struct external_reloc *ext_rel; 805 struct external_reloc *ext_rel_end; 806 unsigned int i; 807 bfd_boolean got_lo; 808 struct internal_reloc lo_int_rel; 809 bfd_size_type amt; 810 811 BFD_ASSERT (input_bfd->xvec->byteorder 812 == output_bfd->xvec->byteorder); 813 814 /* We keep a table mapping the symndx found in an internal reloc to 815 the appropriate section. This is faster than looking up the 816 section by name each time. */ 817 symndx_to_section = ecoff_data (input_bfd)->symndx_to_section; 818 if (symndx_to_section == (asection **) NULL) 819 { 820 amt = NUM_RELOC_SECTIONS * sizeof (asection *); 821 symndx_to_section = (asection **) bfd_alloc (input_bfd, amt); 822 if (!symndx_to_section) 823 return FALSE; 824 825 symndx_to_section[RELOC_SECTION_NONE] = NULL; 826 symndx_to_section[RELOC_SECTION_TEXT] = 827 bfd_get_section_by_name (input_bfd, ".text"); 828 symndx_to_section[RELOC_SECTION_RDATA] = 829 bfd_get_section_by_name (input_bfd, ".rdata"); 830 symndx_to_section[RELOC_SECTION_DATA] = 831 bfd_get_section_by_name (input_bfd, ".data"); 832 symndx_to_section[RELOC_SECTION_SDATA] = 833 bfd_get_section_by_name (input_bfd, ".sdata"); 834 symndx_to_section[RELOC_SECTION_SBSS] = 835 bfd_get_section_by_name (input_bfd, ".sbss"); 836 symndx_to_section[RELOC_SECTION_BSS] = 837 bfd_get_section_by_name (input_bfd, ".bss"); 838 symndx_to_section[RELOC_SECTION_INIT] = 839 bfd_get_section_by_name (input_bfd, ".init"); 840 symndx_to_section[RELOC_SECTION_LIT8] = 841 bfd_get_section_by_name (input_bfd, ".lit8"); 842 symndx_to_section[RELOC_SECTION_LIT4] = 843 bfd_get_section_by_name (input_bfd, ".lit4"); 844 symndx_to_section[RELOC_SECTION_XDATA] = NULL; 845 symndx_to_section[RELOC_SECTION_PDATA] = NULL; 846 symndx_to_section[RELOC_SECTION_FINI] = 847 bfd_get_section_by_name (input_bfd, ".fini"); 848 symndx_to_section[RELOC_SECTION_LITA] = NULL; 849 symndx_to_section[RELOC_SECTION_ABS] = NULL; 850 851 ecoff_data (input_bfd)->symndx_to_section = symndx_to_section; 852 } 853 854 sym_hashes = ecoff_data (input_bfd)->sym_hashes; 855 856 gp = _bfd_get_gp_value (output_bfd); 857 if (gp == 0) 858 gp_undefined = TRUE; 859 else 860 gp_undefined = FALSE; 861 862 got_lo = FALSE; 863 864 ext_rel = (struct external_reloc *) external_relocs; 865 ext_rel_end = ext_rel + input_section->reloc_count; 866 for (i = 0; ext_rel < ext_rel_end; ext_rel++, i++) 867 { 868 struct internal_reloc int_rel; 869 bfd_boolean use_lo = FALSE; 870 bfd_vma addend; 871 reloc_howto_type *howto; 872 struct ecoff_link_hash_entry *h = NULL; 873 asection *s = NULL; 874 bfd_vma relocation; 875 bfd_reloc_status_type r; 876 877 if (! got_lo) 878 mips_ecoff_swap_reloc_in (input_bfd, ext_rel, &int_rel); 879 else 880 { 881 int_rel = lo_int_rel; 882 got_lo = FALSE; 883 } 884 885 BFD_ASSERT (int_rel.r_type 886 < sizeof mips_howto_table / sizeof mips_howto_table[0]); 887 888 /* The REFHI reloc requires special handling. It must be followed 889 by a REFLO reloc, and the addend is formed from both relocs. */ 890 if (int_rel.r_type == MIPS_R_REFHI) 891 { 892 struct external_reloc *lo_ext_rel; 893 894 /* As a GNU extension, permit an arbitrary number of REFHI 895 relocs before the REFLO reloc. This permits gcc to emit 896 the HI and LO relocs itself. */ 897 for (lo_ext_rel = ext_rel + 1; 898 lo_ext_rel < ext_rel_end; 899 lo_ext_rel++) 900 { 901 mips_ecoff_swap_reloc_in (input_bfd, lo_ext_rel, 902 &lo_int_rel); 903 if (lo_int_rel.r_type != int_rel.r_type) 904 break; 905 } 906 907 if (lo_ext_rel < ext_rel_end 908 && lo_int_rel.r_type == MIPS_R_REFLO 909 && int_rel.r_extern == lo_int_rel.r_extern 910 && int_rel.r_symndx == lo_int_rel.r_symndx) 911 { 912 use_lo = TRUE; 913 if (lo_ext_rel == ext_rel + 1) 914 got_lo = TRUE; 915 } 916 } 917 918 howto = &mips_howto_table[int_rel.r_type]; 919 920 if (int_rel.r_extern) 921 { 922 h = sym_hashes[int_rel.r_symndx]; 923 /* If h is NULL, that means that there is a reloc against an 924 external symbol which we thought was just a debugging 925 symbol. This should not happen. */ 926 if (h == (struct ecoff_link_hash_entry *) NULL) 927 abort (); 928 } 929 else 930 { 931 if (int_rel.r_symndx < 0 || int_rel.r_symndx >= NUM_RELOC_SECTIONS) 932 s = NULL; 933 else 934 s = symndx_to_section[int_rel.r_symndx]; 935 936 if (s == (asection *) NULL) 937 abort (); 938 } 939 940 /* The GPREL reloc uses an addend: the difference in the GP 941 values. */ 942 if (int_rel.r_type != MIPS_R_GPREL 943 && int_rel.r_type != MIPS_R_LITERAL) 944 addend = 0; 945 else 946 { 947 if (gp_undefined) 948 { 949 (*info->callbacks->reloc_dangerous) 950 (info, _("GP relative relocation used when GP not defined"), 951 input_bfd, input_section, 952 int_rel.r_vaddr - input_section->vma); 953 /* Only give the error once per link. */ 954 gp = 4; 955 _bfd_set_gp_value (output_bfd, gp); 956 gp_undefined = FALSE; 957 } 958 if (! int_rel.r_extern) 959 { 960 /* This is a relocation against a section. The current 961 addend in the instruction is the difference between 962 INPUT_SECTION->vma and the GP value of INPUT_BFD. We 963 must change this to be the difference between the 964 final definition (which will end up in RELOCATION) 965 and the GP value of OUTPUT_BFD (which is in GP). */ 966 addend = ecoff_data (input_bfd)->gp - gp; 967 } 968 else if (! bfd_link_relocatable (info) 969 || h->root.type == bfd_link_hash_defined 970 || h->root.type == bfd_link_hash_defweak) 971 { 972 /* This is a relocation against a defined symbol. The 973 current addend in the instruction is simply the 974 desired offset into the symbol (normally zero). We 975 are going to change this into a relocation against a 976 defined symbol, so we want the instruction to hold 977 the difference between the final definition of the 978 symbol (which will end up in RELOCATION) and the GP 979 value of OUTPUT_BFD (which is in GP). */ 980 addend = - gp; 981 } 982 else 983 { 984 /* This is a relocation against an undefined or common 985 symbol. The current addend in the instruction is 986 simply the desired offset into the symbol (normally 987 zero). We are generating relocatable output, and we 988 aren't going to define this symbol, so we just leave 989 the instruction alone. */ 990 addend = 0; 991 } 992 } 993 994 if (bfd_link_relocatable (info)) 995 { 996 /* We are generating relocatable output, and must convert 997 the existing reloc. */ 998 if (int_rel.r_extern) 999 { 1000 if ((h->root.type == bfd_link_hash_defined 1001 || h->root.type == bfd_link_hash_defweak) 1002 && ! bfd_is_abs_section (h->root.u.def.section)) 1003 { 1004 const char *name; 1005 1006 /* This symbol is defined in the output. Convert 1007 the reloc from being against the symbol to being 1008 against the section. */ 1009 1010 /* Clear the r_extern bit. */ 1011 int_rel.r_extern = 0; 1012 1013 /* Compute a new r_symndx value. */ 1014 s = h->root.u.def.section; 1015 name = bfd_get_section_name (output_bfd, 1016 s->output_section); 1017 1018 int_rel.r_symndx = -1; 1019 switch (name[1]) 1020 { 1021 case 'b': 1022 if (strcmp (name, ".bss") == 0) 1023 int_rel.r_symndx = RELOC_SECTION_BSS; 1024 break; 1025 case 'd': 1026 if (strcmp (name, ".data") == 0) 1027 int_rel.r_symndx = RELOC_SECTION_DATA; 1028 break; 1029 case 'f': 1030 if (strcmp (name, ".fini") == 0) 1031 int_rel.r_symndx = RELOC_SECTION_FINI; 1032 break; 1033 case 'i': 1034 if (strcmp (name, ".init") == 0) 1035 int_rel.r_symndx = RELOC_SECTION_INIT; 1036 break; 1037 case 'l': 1038 if (strcmp (name, ".lit8") == 0) 1039 int_rel.r_symndx = RELOC_SECTION_LIT8; 1040 else if (strcmp (name, ".lit4") == 0) 1041 int_rel.r_symndx = RELOC_SECTION_LIT4; 1042 break; 1043 case 'r': 1044 if (strcmp (name, ".rdata") == 0) 1045 int_rel.r_symndx = RELOC_SECTION_RDATA; 1046 break; 1047 case 's': 1048 if (strcmp (name, ".sdata") == 0) 1049 int_rel.r_symndx = RELOC_SECTION_SDATA; 1050 else if (strcmp (name, ".sbss") == 0) 1051 int_rel.r_symndx = RELOC_SECTION_SBSS; 1052 break; 1053 case 't': 1054 if (strcmp (name, ".text") == 0) 1055 int_rel.r_symndx = RELOC_SECTION_TEXT; 1056 break; 1057 } 1058 1059 if (int_rel.r_symndx == -1) 1060 abort (); 1061 1062 /* Add the section VMA and the symbol value. */ 1063 relocation = (h->root.u.def.value 1064 + s->output_section->vma 1065 + s->output_offset); 1066 1067 /* For a PC relative relocation, the object file 1068 currently holds just the addend. We must adjust 1069 by the address to get the right value. */ 1070 if (howto->pc_relative) 1071 relocation -= int_rel.r_vaddr - input_section->vma; 1072 1073 h = NULL; 1074 } 1075 else 1076 { 1077 /* Change the symndx value to the right one for the 1078 output BFD. */ 1079 int_rel.r_symndx = h->indx; 1080 if (int_rel.r_symndx == -1) 1081 { 1082 /* This symbol is not being written out. */ 1083 (*info->callbacks->unattached_reloc) 1084 (info, h->root.root.string, input_bfd, input_section, 1085 int_rel.r_vaddr - input_section->vma); 1086 int_rel.r_symndx = 0; 1087 } 1088 relocation = 0; 1089 } 1090 } 1091 else 1092 { 1093 /* This is a relocation against a section. Adjust the 1094 value by the amount the section moved. */ 1095 relocation = (s->output_section->vma 1096 + s->output_offset 1097 - s->vma); 1098 } 1099 1100 relocation += addend; 1101 addend = 0; 1102 1103 /* Adjust a PC relative relocation by removing the reference 1104 to the original address in the section and including the 1105 reference to the new address. */ 1106 if (howto->pc_relative) 1107 relocation -= (input_section->output_section->vma 1108 + input_section->output_offset 1109 - input_section->vma); 1110 1111 /* Adjust the contents. */ 1112 if (relocation == 0) 1113 r = bfd_reloc_ok; 1114 else 1115 { 1116 if (int_rel.r_type != MIPS_R_REFHI) 1117 r = _bfd_relocate_contents (howto, input_bfd, relocation, 1118 (contents 1119 + int_rel.r_vaddr 1120 - input_section->vma)); 1121 else 1122 { 1123 mips_relocate_hi (&int_rel, 1124 use_lo ? &lo_int_rel : NULL, 1125 input_bfd, input_section, contents, 1126 relocation); 1127 r = bfd_reloc_ok; 1128 } 1129 } 1130 1131 /* Adjust the reloc address. */ 1132 int_rel.r_vaddr += (input_section->output_section->vma 1133 + input_section->output_offset 1134 - input_section->vma); 1135 1136 /* Save the changed reloc information. */ 1137 mips_ecoff_swap_reloc_out (input_bfd, &int_rel, ext_rel); 1138 } 1139 else 1140 { 1141 /* We are producing a final executable. */ 1142 if (int_rel.r_extern) 1143 { 1144 /* This is a reloc against a symbol. */ 1145 if (h->root.type == bfd_link_hash_defined 1146 || h->root.type == bfd_link_hash_defweak) 1147 { 1148 asection *hsec; 1149 1150 hsec = h->root.u.def.section; 1151 relocation = (h->root.u.def.value 1152 + hsec->output_section->vma 1153 + hsec->output_offset); 1154 } 1155 else 1156 { 1157 (*info->callbacks->undefined_symbol) 1158 (info, h->root.root.string, input_bfd, input_section, 1159 int_rel.r_vaddr - input_section->vma, TRUE); 1160 relocation = 0; 1161 } 1162 } 1163 else 1164 { 1165 /* This is a reloc against a section. */ 1166 relocation = (s->output_section->vma 1167 + s->output_offset 1168 - s->vma); 1169 1170 /* A PC relative reloc is already correct in the object 1171 file. Make it look like a pcrel_offset relocation by 1172 adding in the start address. */ 1173 if (howto->pc_relative) 1174 relocation += int_rel.r_vaddr; 1175 } 1176 1177 if (int_rel.r_type != MIPS_R_REFHI) 1178 r = _bfd_final_link_relocate (howto, 1179 input_bfd, 1180 input_section, 1181 contents, 1182 (int_rel.r_vaddr 1183 - input_section->vma), 1184 relocation, 1185 addend); 1186 else 1187 { 1188 mips_relocate_hi (&int_rel, 1189 use_lo ? &lo_int_rel : NULL, 1190 input_bfd, input_section, contents, 1191 relocation); 1192 r = bfd_reloc_ok; 1193 } 1194 } 1195 1196 /* MIPS_R_JMPADDR requires peculiar overflow detection. The 1197 instruction provides a 28 bit address (the two lower bits are 1198 implicit zeroes) which is combined with the upper four bits 1199 of the instruction address. */ 1200 if (r == bfd_reloc_ok 1201 && int_rel.r_type == MIPS_R_JMPADDR 1202 && (((relocation 1203 + addend 1204 + (int_rel.r_extern ? 0 : s->vma)) 1205 & 0xf0000000) 1206 != ((input_section->output_section->vma 1207 + input_section->output_offset 1208 + (int_rel.r_vaddr - input_section->vma)) 1209 & 0xf0000000))) 1210 r = bfd_reloc_overflow; 1211 1212 if (r != bfd_reloc_ok) 1213 { 1214 switch (r) 1215 { 1216 default: 1217 case bfd_reloc_outofrange: 1218 abort (); 1219 case bfd_reloc_overflow: 1220 { 1221 const char *name; 1222 1223 if (int_rel.r_extern) 1224 name = NULL; 1225 else 1226 name = bfd_section_name (input_bfd, s); 1227 (*info->callbacks->reloc_overflow) 1228 (info, (h ? &h->root : NULL), name, howto->name, 1229 (bfd_vma) 0, input_bfd, input_section, 1230 int_rel.r_vaddr - input_section->vma); 1231 } 1232 break; 1233 } 1234 } 1235 } 1236 1237 return TRUE; 1238 } 1239 1240 /* This is the ECOFF backend structure. The backend field of the 1242 target vector points to this. */ 1243 1244 static const struct ecoff_backend_data mips_ecoff_backend_data = 1245 { 1246 /* COFF backend structure. */ 1247 { 1248 (void (*) (bfd *,void *,int,int,int,int,void *)) bfd_void, /* aux_in */ 1249 (void (*) (bfd *,void *,void *)) bfd_void, /* sym_in */ 1250 (void (*) (bfd *,void *,void *)) bfd_void, /* lineno_in */ 1251 (unsigned (*) (bfd *,void *,int,int,int,int,void *)) bfd_void,/*aux_out*/ 1252 (unsigned (*) (bfd *,void *,void *)) bfd_void, /* sym_out */ 1253 (unsigned (*) (bfd *,void *,void *)) bfd_void, /* lineno_out */ 1254 (unsigned (*) (bfd *,void *,void *)) bfd_void, /* reloc_out */ 1255 mips_ecoff_swap_filehdr_out, mips_ecoff_swap_aouthdr_out, 1256 mips_ecoff_swap_scnhdr_out, 1257 FILHSZ, AOUTSZ, SCNHSZ, 0, 0, 0, 0, FILNMLEN, TRUE, 1258 ECOFF_NO_LONG_SECTION_NAMES, 4, FALSE, 2, 32768, 1259 mips_ecoff_swap_filehdr_in, mips_ecoff_swap_aouthdr_in, 1260 mips_ecoff_swap_scnhdr_in, NULL, 1261 mips_ecoff_bad_format_hook, _bfd_ecoff_set_arch_mach_hook, 1262 _bfd_ecoff_mkobject_hook, _bfd_ecoff_styp_to_sec_flags, 1263 _bfd_ecoff_set_alignment_hook, _bfd_ecoff_slurp_symbol_table, 1264 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 1265 NULL, NULL, NULL 1266 }, 1267 /* Supported architecture. */ 1268 bfd_arch_mips, 1269 /* Initial portion of armap string. */ 1270 "__________", 1271 /* The page boundary used to align sections in a demand-paged 1272 executable file. E.g., 0x1000. */ 1273 0x1000, 1274 /* TRUE if the .rdata section is part of the text segment, as on the 1275 Alpha. FALSE if .rdata is part of the data segment, as on the 1276 MIPS. */ 1277 FALSE, 1278 /* Bitsize of constructor entries. */ 1279 32, 1280 /* Reloc to use for constructor entries. */ 1281 &mips_howto_table[MIPS_R_REFWORD], 1282 { 1283 /* Symbol table magic number. */ 1284 magicSym, 1285 /* Alignment of debugging information. E.g., 4. */ 1286 4, 1287 /* Sizes of external symbolic information. */ 1288 sizeof (struct hdr_ext), 1289 sizeof (struct dnr_ext), 1290 sizeof (struct pdr_ext), 1291 sizeof (struct sym_ext), 1292 sizeof (struct opt_ext), 1293 sizeof (struct fdr_ext), 1294 sizeof (struct rfd_ext), 1295 sizeof (struct ext_ext), 1296 /* Functions to swap in external symbolic data. */ 1297 ecoff_swap_hdr_in, 1298 ecoff_swap_dnr_in, 1299 ecoff_swap_pdr_in, 1300 ecoff_swap_sym_in, 1301 ecoff_swap_opt_in, 1302 ecoff_swap_fdr_in, 1303 ecoff_swap_rfd_in, 1304 ecoff_swap_ext_in, 1305 _bfd_ecoff_swap_tir_in, 1306 _bfd_ecoff_swap_rndx_in, 1307 /* Functions to swap out external symbolic data. */ 1308 ecoff_swap_hdr_out, 1309 ecoff_swap_dnr_out, 1310 ecoff_swap_pdr_out, 1311 ecoff_swap_sym_out, 1312 ecoff_swap_opt_out, 1313 ecoff_swap_fdr_out, 1314 ecoff_swap_rfd_out, 1315 ecoff_swap_ext_out, 1316 _bfd_ecoff_swap_tir_out, 1317 _bfd_ecoff_swap_rndx_out, 1318 /* Function to read in symbolic data. */ 1319 _bfd_ecoff_slurp_symbolic_info 1320 }, 1321 /* External reloc size. */ 1322 RELSZ, 1323 /* Reloc swapping functions. */ 1324 mips_ecoff_swap_reloc_in, 1325 mips_ecoff_swap_reloc_out, 1326 /* Backend reloc tweaking. */ 1327 mips_adjust_reloc_in, 1328 mips_adjust_reloc_out, 1329 /* Relocate section contents while linking. */ 1330 mips_relocate_section, 1331 /* Do final adjustments to filehdr and aouthdr. */ 1332 NULL, 1333 /* Read an element from an archive at a given file position. */ 1334 _bfd_get_elt_at_filepos 1335 }; 1336 1337 /* Looking up a reloc type is MIPS specific. */ 1338 #define _bfd_ecoff_bfd_reloc_type_lookup mips_bfd_reloc_type_lookup 1339 #define _bfd_ecoff_bfd_reloc_name_lookup mips_bfd_reloc_name_lookup 1340 1341 /* Getting relocated section contents is generic. */ 1342 #define _bfd_ecoff_bfd_get_relocated_section_contents \ 1343 bfd_generic_get_relocated_section_contents 1344 1345 /* Handling file windows is generic. */ 1346 #define _bfd_ecoff_get_section_contents_in_window \ 1347 _bfd_generic_get_section_contents_in_window 1348 1349 /* Relaxing sections is MIPS specific. */ 1350 #define _bfd_ecoff_bfd_relax_section bfd_generic_relax_section 1351 1352 /* GC of sections is not done. */ 1353 #define _bfd_ecoff_bfd_gc_sections bfd_generic_gc_sections 1354 1355 /* Input section flags is not implemented. */ 1356 #define _bfd_ecoff_bfd_lookup_section_flags bfd_generic_lookup_section_flags 1357 1358 /* Merging of sections is not done. */ 1359 #define _bfd_ecoff_bfd_merge_sections bfd_generic_merge_sections 1360 1361 #define _bfd_ecoff_bfd_is_group_section bfd_generic_is_group_section 1362 #define _bfd_ecoff_bfd_discard_group bfd_generic_discard_group 1363 #define _bfd_ecoff_section_already_linked \ 1364 _bfd_coff_section_already_linked 1365 #define _bfd_ecoff_bfd_define_common_symbol bfd_generic_define_common_symbol 1366 1367 extern const bfd_target mips_ecoff_be_vec; 1368 1369 const bfd_target mips_ecoff_le_vec = 1370 { 1371 "ecoff-littlemips", /* name */ 1372 bfd_target_ecoff_flavour, 1373 BFD_ENDIAN_LITTLE, /* data byte order is little */ 1374 BFD_ENDIAN_LITTLE, /* header byte order is little */ 1375 1376 (HAS_RELOC | EXEC_P | /* object flags */ 1377 HAS_LINENO | HAS_DEBUG | 1378 HAS_SYMS | HAS_LOCALS | WP_TEXT | D_PAGED), 1379 1380 (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC | SEC_CODE | SEC_DATA), 1381 0, /* leading underscore */ 1382 ' ', /* ar_pad_char */ 1383 15, /* ar_max_namelen */ 1384 0, /* match priority. */ 1385 bfd_getl64, bfd_getl_signed_64, bfd_putl64, 1386 bfd_getl32, bfd_getl_signed_32, bfd_putl32, 1387 bfd_getl16, bfd_getl_signed_16, bfd_putl16, /* data */ 1388 bfd_getl64, bfd_getl_signed_64, bfd_putl64, 1389 bfd_getl32, bfd_getl_signed_32, bfd_putl32, 1390 bfd_getl16, bfd_getl_signed_16, bfd_putl16, /* hdrs */ 1391 1392 {_bfd_dummy_target, coff_object_p, /* bfd_check_format */ 1393 bfd_generic_archive_p, _bfd_dummy_target}, 1394 {bfd_false, _bfd_ecoff_mkobject, /* bfd_set_format */ 1395 _bfd_generic_mkarchive, bfd_false}, 1396 {bfd_false, _bfd_ecoff_write_object_contents, /* bfd_write_contents */ 1397 _bfd_write_archive_contents, bfd_false}, 1398 1399 BFD_JUMP_TABLE_GENERIC (_bfd_ecoff), 1400 BFD_JUMP_TABLE_COPY (_bfd_ecoff), 1401 BFD_JUMP_TABLE_CORE (_bfd_nocore), 1402 BFD_JUMP_TABLE_ARCHIVE (_bfd_ecoff), 1403 BFD_JUMP_TABLE_SYMBOLS (_bfd_ecoff), 1404 BFD_JUMP_TABLE_RELOCS (_bfd_ecoff), 1405 BFD_JUMP_TABLE_WRITE (_bfd_ecoff), 1406 BFD_JUMP_TABLE_LINK (_bfd_ecoff), 1407 BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic), 1408 1409 & mips_ecoff_be_vec, 1410 1411 & mips_ecoff_backend_data 1412 }; 1413 1414 const bfd_target mips_ecoff_be_vec = 1415 { 1416 "ecoff-bigmips", /* name */ 1417 bfd_target_ecoff_flavour, 1418 BFD_ENDIAN_BIG, /* data byte order is big */ 1419 BFD_ENDIAN_BIG, /* header byte order is big */ 1420 1421 (HAS_RELOC | EXEC_P | /* object flags */ 1422 HAS_LINENO | HAS_DEBUG | 1423 HAS_SYMS | HAS_LOCALS | WP_TEXT | D_PAGED), 1424 1425 (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC | SEC_CODE | SEC_DATA), 1426 0, /* leading underscore */ 1427 ' ', /* ar_pad_char */ 1428 15, /* ar_max_namelen */ 1429 0, /* match priority. */ 1430 bfd_getb64, bfd_getb_signed_64, bfd_putb64, 1431 bfd_getb32, bfd_getb_signed_32, bfd_putb32, 1432 bfd_getb16, bfd_getb_signed_16, bfd_putb16, 1433 bfd_getb64, bfd_getb_signed_64, bfd_putb64, 1434 bfd_getb32, bfd_getb_signed_32, bfd_putb32, 1435 bfd_getb16, bfd_getb_signed_16, bfd_putb16, 1436 {_bfd_dummy_target, coff_object_p, /* bfd_check_format */ 1437 bfd_generic_archive_p, _bfd_dummy_target}, 1438 {bfd_false, _bfd_ecoff_mkobject, /* bfd_set_format */ 1439 _bfd_generic_mkarchive, bfd_false}, 1440 {bfd_false, _bfd_ecoff_write_object_contents, /* bfd_write_contents */ 1441 _bfd_write_archive_contents, bfd_false}, 1442 1443 BFD_JUMP_TABLE_GENERIC (_bfd_ecoff), 1444 BFD_JUMP_TABLE_COPY (_bfd_ecoff), 1445 BFD_JUMP_TABLE_CORE (_bfd_nocore), 1446 BFD_JUMP_TABLE_ARCHIVE (_bfd_ecoff), 1447 BFD_JUMP_TABLE_SYMBOLS (_bfd_ecoff), 1448 BFD_JUMP_TABLE_RELOCS (_bfd_ecoff), 1449 BFD_JUMP_TABLE_WRITE (_bfd_ecoff), 1450 BFD_JUMP_TABLE_LINK (_bfd_ecoff), 1451 BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic), 1452 1453 & mips_ecoff_le_vec, 1454 1455 & mips_ecoff_backend_data 1456 }; 1457 1458 const bfd_target mips_ecoff_bele_vec = 1459 { 1460 "ecoff-biglittlemips", /* name */ 1461 bfd_target_ecoff_flavour, 1462 BFD_ENDIAN_LITTLE, /* data byte order is little */ 1463 BFD_ENDIAN_BIG, /* header byte order is big */ 1464 1465 (HAS_RELOC | EXEC_P | /* object flags */ 1466 HAS_LINENO | HAS_DEBUG | 1467 HAS_SYMS | HAS_LOCALS | WP_TEXT | D_PAGED), 1468 1469 (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC | SEC_CODE | SEC_DATA), 1470 0, /* leading underscore */ 1471 ' ', /* ar_pad_char */ 1472 15, /* ar_max_namelen */ 1473 0, /* match priority. */ 1474 bfd_getl64, bfd_getl_signed_64, bfd_putl64, 1475 bfd_getl32, bfd_getl_signed_32, bfd_putl32, 1476 bfd_getl16, bfd_getl_signed_16, bfd_putl16, /* data */ 1477 bfd_getb64, bfd_getb_signed_64, bfd_putb64, 1478 bfd_getb32, bfd_getb_signed_32, bfd_putb32, 1479 bfd_getb16, bfd_getb_signed_16, bfd_putb16, /* hdrs */ 1480 1481 {_bfd_dummy_target, coff_object_p, /* bfd_check_format */ 1482 bfd_generic_archive_p, _bfd_dummy_target}, 1483 {bfd_false, _bfd_ecoff_mkobject, /* bfd_set_format */ 1484 _bfd_generic_mkarchive, bfd_false}, 1485 {bfd_false, _bfd_ecoff_write_object_contents, /* bfd_write_contents */ 1486 _bfd_write_archive_contents, bfd_false}, 1487 1488 BFD_JUMP_TABLE_GENERIC (_bfd_ecoff), 1489 BFD_JUMP_TABLE_COPY (_bfd_ecoff), 1490 BFD_JUMP_TABLE_CORE (_bfd_nocore), 1491 BFD_JUMP_TABLE_ARCHIVE (_bfd_ecoff), 1492 BFD_JUMP_TABLE_SYMBOLS (_bfd_ecoff), 1493 BFD_JUMP_TABLE_RELOCS (_bfd_ecoff), 1494 BFD_JUMP_TABLE_WRITE (_bfd_ecoff), 1495 BFD_JUMP_TABLE_LINK (_bfd_ecoff), 1496 BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic), 1497 1498 NULL, 1499 1500 & mips_ecoff_backend_data 1501 }; 1502