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