1/* BFD back-end for MIPS PE COFF files. 2 Copyright 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 3 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc. 4 Modified from coff-i386.c by DJ Delorie, dj@cygnus.com 5 6This file is part of BFD, the Binary File Descriptor library. 7 8This program is free software; you can redistribute it and/or modify 9it under the terms of the GNU General Public License as published by 10the Free Software Foundation; either version 2 of the License, or 11(at your option) any later version. 12 13This program is distributed in the hope that it will be useful, 14but WITHOUT ANY WARRANTY; without even the implied warranty of 15MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16GNU General Public License for more details. 17 18You should have received a copy of the GNU General Public License 19along with this program; if not, write to the Free Software 20Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ 21 22#define COFF_WITH_PE 23#define COFF_LONG_SECTION_NAMES 24#define PCRELOFFSET TRUE 25 26#include "bfd.h" 27#include "sysdep.h" 28#include "libbfd.h" 29 30#include "coff/mipspe.h" 31 32#include "coff/internal.h" 33 34#include "coff/pe.h" 35 36#include "libcoff.h" 37 38static bfd_reloc_status_type coff_mips_reloc 39 PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **)); 40static reloc_howto_type *coff_mips_rtype_to_howto 41 PARAMS ((bfd *, asection *, struct internal_reloc *, 42 struct coff_link_hash_entry *, struct internal_syment *, 43 bfd_vma *)); 44 45static bfd_boolean in_reloc_p 46 PARAMS ((bfd *, reloc_howto_type *)); 47static reloc_howto_type * coff_mips_reloc_type_lookup 48 PARAMS ((bfd *, bfd_reloc_code_real_type)); 49static void mips_swap_reloc_in 50 PARAMS ((bfd *, PTR, PTR)); 51static unsigned int mips_swap_reloc_out 52 PARAMS ((bfd *, PTR, PTR)); 53static bfd_boolean coff_pe_mips_relocate_section 54 PARAMS ((bfd *, struct bfd_link_info *, bfd *, asection *, bfd_byte *, 55 struct internal_reloc *, struct internal_syment *, asection **)); 56 57#define COFF_DEFAULT_SECTION_ALIGNMENT_POWER (2) 58/* The page size is a guess based on ELF. */ 59 60#define COFF_PAGE_SIZE 0x1000 61 62/* For some reason when using mips COFF the value stored in the .text 63 section for a reference to a common symbol is the value itself plus 64 any desired offset. Ian Taylor, Cygnus Support. */ 65 66/* If we are producing relocatable output, we need to do some 67 adjustments to the object file that are not done by the 68 bfd_perform_relocation function. This function is called by every 69 reloc type to make any required adjustments. */ 70 71static bfd_reloc_status_type 72coff_mips_reloc (abfd, reloc_entry, symbol, data, input_section, output_bfd, 73 error_message) 74 bfd *abfd; 75 arelent *reloc_entry; 76 asymbol *symbol; 77 PTR data; 78 asection *input_section ATTRIBUTE_UNUSED; 79 bfd *output_bfd; 80 char **error_message ATTRIBUTE_UNUSED; 81{ 82 symvalue diff; 83 84 if (output_bfd == (bfd *) NULL) 85 return bfd_reloc_continue; 86 87 if (bfd_is_com_section (symbol->section)) 88 { 89#ifndef COFF_WITH_PE 90 /* We are relocating a common symbol. The current value in the 91 object file is ORIG + OFFSET, where ORIG is the value of the 92 common symbol as seen by the object file when it was compiled 93 (this may be zero if the symbol was undefined) and OFFSET is 94 the offset into the common symbol (normally zero, but may be 95 non-zero when referring to a field in a common structure). 96 ORIG is the negative of reloc_entry->addend, which is set by 97 the CALC_ADDEND macro below. We want to replace the value in 98 the object file with NEW + OFFSET, where NEW is the value of 99 the common symbol which we are going to put in the final 100 object file. NEW is symbol->value. */ 101 diff = symbol->value + reloc_entry->addend; 102#else 103 /* In PE mode, we do not offset the common symbol. */ 104 diff = reloc_entry->addend; 105#endif 106 } 107 else 108 { 109 /* For some reason bfd_perform_relocation always effectively 110 ignores the addend for a COFF target when producing 111 relocatable output. This seems to be always wrong for 386 112 COFF, so we handle the addend here instead. */ 113 diff = reloc_entry->addend; 114 } 115 116#ifdef COFF_WITH_PE 117#if 0 118 /* dj - handle it like any other reloc? */ 119 /* FIXME: How should this case be handled? */ 120 if (reloc_entry->howto->type == MIPS_R_RVA && diff != 0) 121 abort (); 122#endif 123#endif 124 125#define DOIT(x) \ 126 x = ((x & ~howto->dst_mask) | (((x & howto->src_mask) + (diff >> howto->rightshift)) & howto->dst_mask)) 127 128 if (diff != 0) 129 { 130 reloc_howto_type *howto = reloc_entry->howto; 131 unsigned char *addr = (unsigned char *) data + reloc_entry->address; 132 133 switch (howto->size) 134 { 135 case 0: 136 { 137 char x = bfd_get_8 (abfd, addr); 138 DOIT (x); 139 bfd_put_8 (abfd, x, addr); 140 } 141 break; 142 143 case 1: 144 { 145 short x = bfd_get_16 (abfd, addr); 146 DOIT (x); 147 bfd_put_16 (abfd, (bfd_vma) x, addr); 148 } 149 break; 150 151 case 2: 152 { 153 long x = bfd_get_32 (abfd, addr); 154 DOIT (x); 155 bfd_put_32 (abfd, (bfd_vma) x, addr); 156 } 157 break; 158 159 default: 160 abort (); 161 } 162 } 163 164 /* Now let bfd_perform_relocation finish everything up. */ 165 return bfd_reloc_continue; 166} 167 168#ifdef COFF_WITH_PE 169/* Return TRUE if this relocation should 170 appear in the output .reloc section. */ 171 172static bfd_boolean 173in_reloc_p (abfd, howto) 174 bfd * abfd ATTRIBUTE_UNUSED; 175 reloc_howto_type *howto; 176{ 177 return ! howto->pc_relative && howto->type != MIPS_R_RVA; 178} 179#endif 180 181#ifndef PCRELOFFSET 182#define PCRELOFFSET FALSE 183#endif 184 185static reloc_howto_type howto_table[] = 186{ 187 /* Reloc type 0 is ignored. The reloc reading code ensures that 188 this is a reference to the .abs section, which will cause 189 bfd_perform_relocation to do nothing. */ 190 HOWTO (MIPS_R_ABSOLUTE, /* type */ 191 0, /* rightshift */ 192 0, /* size (0 = byte, 1 = short, 2 = long) */ 193 8, /* bitsize */ 194 FALSE, /* pc_relative */ 195 0, /* bitpos */ 196 complain_overflow_dont, /* complain_on_overflow */ 197 0, /* special_function */ 198 "IGNORE", /* name */ 199 FALSE, /* partial_inplace */ 200 0, /* src_mask */ 201 0, /* dst_mask */ 202 FALSE), /* pcrel_offset */ 203 204 /* A 16 bit reference to a symbol, normally from a data section. */ 205 HOWTO (MIPS_R_REFHALF, /* type */ 206 0, /* rightshift */ 207 1, /* size (0 = byte, 1 = short, 2 = long) */ 208 16, /* bitsize */ 209 FALSE, /* pc_relative */ 210 0, /* bitpos */ 211 complain_overflow_bitfield, /* complain_on_overflow */ 212 coff_mips_reloc, /* special_function */ 213 "REFHALF", /* name */ 214 TRUE, /* partial_inplace */ 215 0xffff, /* src_mask */ 216 0xffff, /* dst_mask */ 217 FALSE), /* pcrel_offset */ 218 219 /* A 32 bit reference to a symbol, normally from a data section. */ 220 HOWTO (MIPS_R_REFWORD, /* type */ 221 0, /* rightshift */ 222 2, /* size (0 = byte, 1 = short, 2 = long) */ 223 32, /* bitsize */ 224 FALSE, /* pc_relative */ 225 0, /* bitpos */ 226 complain_overflow_bitfield, /* complain_on_overflow */ 227 coff_mips_reloc, /* special_function */ 228 "REFWORD", /* name */ 229 TRUE, /* partial_inplace */ 230 0xffffffff, /* src_mask */ 231 0xffffffff, /* dst_mask */ 232 FALSE), /* pcrel_offset */ 233 234 /* A 26 bit absolute jump address. */ 235 HOWTO (MIPS_R_JMPADDR, /* type */ 236 2, /* rightshift */ 237 2, /* size (0 = byte, 1 = short, 2 = long) */ 238 26, /* bitsize */ 239 FALSE, /* pc_relative */ 240 0, /* bitpos */ 241 complain_overflow_dont, /* complain_on_overflow */ 242 /* This needs complex overflow 243 detection, because the upper four 244 bits must match the PC. */ 245 coff_mips_reloc, /* special_function */ 246 "JMPADDR", /* name */ 247 TRUE, /* partial_inplace */ 248 0x3ffffff, /* src_mask */ 249 0x3ffffff, /* dst_mask */ 250 FALSE), /* pcrel_offset */ 251 252 /* The high 16 bits of a symbol value. Handled by the function 253 mips_refhi_reloc. */ 254 HOWTO (MIPS_R_REFHI, /* type */ 255 16, /* rightshift */ 256 2, /* size (0 = byte, 1 = short, 2 = long) */ 257 16, /* bitsize */ 258 FALSE, /* pc_relative */ 259 0, /* bitpos */ 260 complain_overflow_bitfield, /* complain_on_overflow */ 261 coff_mips_reloc, /* special_function */ 262 "REFHI", /* name */ 263 TRUE, /* partial_inplace */ 264 0xffff, /* src_mask */ 265 0xffff, /* dst_mask */ 266 FALSE), /* pcrel_offset */ 267 268 /* The low 16 bits of a symbol value. */ 269 HOWTO (MIPS_R_REFLO, /* type */ 270 0, /* rightshift */ 271 2, /* size (0 = byte, 1 = short, 2 = long) */ 272 16, /* bitsize */ 273 FALSE, /* pc_relative */ 274 0, /* bitpos */ 275 complain_overflow_dont, /* complain_on_overflow */ 276 coff_mips_reloc, /* special_function */ 277 "REFLO", /* name */ 278 TRUE, /* partial_inplace */ 279 0xffff, /* src_mask */ 280 0xffff, /* dst_mask */ 281 FALSE), /* pcrel_offset */ 282 283 /* A reference to an offset from the gp register. Handled by the 284 function mips_gprel_reloc. */ 285 HOWTO (MIPS_R_GPREL, /* type */ 286 0, /* rightshift */ 287 2, /* size (0 = byte, 1 = short, 2 = long) */ 288 16, /* bitsize */ 289 FALSE, /* pc_relative */ 290 0, /* bitpos */ 291 complain_overflow_signed, /* complain_on_overflow */ 292 coff_mips_reloc, /* special_function */ 293 "GPREL", /* name */ 294 TRUE, /* partial_inplace */ 295 0xffff, /* src_mask */ 296 0xffff, /* dst_mask */ 297 FALSE), /* pcrel_offset */ 298 299 /* A reference to a literal using an offset from the gp register. 300 Handled by the function mips_gprel_reloc. */ 301 HOWTO (MIPS_R_LITERAL, /* type */ 302 0, /* rightshift */ 303 2, /* size (0 = byte, 1 = short, 2 = long) */ 304 16, /* bitsize */ 305 FALSE, /* pc_relative */ 306 0, /* bitpos */ 307 complain_overflow_signed, /* complain_on_overflow */ 308 coff_mips_reloc, /* special_function */ 309 "LITERAL", /* name */ 310 TRUE, /* partial_inplace */ 311 0xffff, /* src_mask */ 312 0xffff, /* dst_mask */ 313 FALSE), /* pcrel_offset */ 314 315 EMPTY_HOWTO (8), 316 EMPTY_HOWTO (9), 317 EMPTY_HOWTO (10), 318 EMPTY_HOWTO (11), 319 EMPTY_HOWTO (12), 320 EMPTY_HOWTO (13), 321 EMPTY_HOWTO (14), 322 EMPTY_HOWTO (15), 323 EMPTY_HOWTO (16), 324 EMPTY_HOWTO (17), 325 EMPTY_HOWTO (18), 326 EMPTY_HOWTO (19), 327 EMPTY_HOWTO (20), 328 EMPTY_HOWTO (21), 329 EMPTY_HOWTO (22), 330 EMPTY_HOWTO (23), 331 EMPTY_HOWTO (24), 332 EMPTY_HOWTO (25), 333 EMPTY_HOWTO (26), 334 EMPTY_HOWTO (27), 335 EMPTY_HOWTO (28), 336 EMPTY_HOWTO (29), 337 EMPTY_HOWTO (30), 338 EMPTY_HOWTO (31), 339 EMPTY_HOWTO (32), 340 EMPTY_HOWTO (33), 341 HOWTO (MIPS_R_RVA, /* type */ 342 0, /* rightshift */ 343 2, /* size (0 = byte, 1 = short, 2 = long) */ 344 32, /* bitsize */ 345 FALSE, /* pc_relative */ 346 0, /* bitpos */ 347 complain_overflow_bitfield, /* complain_on_overflow */ 348 coff_mips_reloc, /* special_function */ 349 "rva32", /* name */ 350 TRUE, /* partial_inplace */ 351 0xffffffff, /* src_mask */ 352 0xffffffff, /* dst_mask */ 353 FALSE), /* pcrel_offset */ 354 EMPTY_HOWTO (35), 355 EMPTY_HOWTO (36), 356 HOWTO (MIPS_R_PAIR, /* type */ 357 0, /* rightshift */ 358 2, /* size (0 = byte, 1 = short, 2 = long) */ 359 32, /* bitsize */ 360 FALSE, /* pc_relative */ 361 0, /* bitpos */ 362 complain_overflow_bitfield, /* complain_on_overflow */ 363 coff_mips_reloc, /* special_function */ 364 "PAIR", /* name */ 365 TRUE, /* partial_inplace */ 366 0xffffffff, /* src_mask */ 367 0xffffffff, /* dst_mask */ 368 FALSE), /* pcrel_offset */ 369}; 370 371/* Turn a howto into a reloc nunmber */ 372 373#define SELECT_RELOC(x,howto) { x.r_type = howto->type; } 374#define BADMAG(x) MIPSBADMAG(x) 375#define MIPS 1 /* Customize coffcode.h */ 376 377#define RTYPE2HOWTO(cache_ptr, dst) \ 378 (cache_ptr)->howto = howto_table + (dst)->r_type; 379 380/* Compute the addend of a reloc. If the reloc is to a common symbol, 381 the object file contains the value of the common symbol. By the 382 time this is called, the linker may be using a different symbol 383 from a different object file with a different value. Therefore, we 384 hack wildly to locate the original symbol from this file so that we 385 can make the correct adjustment. This macro sets coffsym to the 386 symbol from the original file, and uses it to set the addend value 387 correctly. If this is not a common symbol, the usual addend 388 calculation is done, except that an additional tweak is needed for 389 PC relative relocs. 390 FIXME: This macro refers to symbols and asect; these are from the 391 calling function, not the macro arguments. */ 392 393#define CALC_ADDEND(abfd, ptr, reloc, cache_ptr) \ 394 { \ 395 coff_symbol_type *coffsym = (coff_symbol_type *) NULL; \ 396 if (ptr && bfd_asymbol_bfd (ptr) != abfd) \ 397 coffsym = (obj_symbols (abfd) \ 398 + (cache_ptr->sym_ptr_ptr - symbols)); \ 399 else if (ptr) \ 400 coffsym = coff_symbol_from (abfd, ptr); \ 401 if (coffsym != (coff_symbol_type *) NULL \ 402 && coffsym->native->u.syment.n_scnum == 0) \ 403 cache_ptr->addend = - coffsym->native->u.syment.n_value; \ 404 else if (ptr && bfd_asymbol_bfd (ptr) == abfd \ 405 && ptr->section != (asection *) NULL) \ 406 cache_ptr->addend = - (ptr->section->vma + ptr->value); \ 407 else \ 408 cache_ptr->addend = 0; \ 409 if (ptr && howto_table[reloc.r_type].pc_relative) \ 410 cache_ptr->addend += asect->vma; \ 411 } 412 413/* Convert an rtype to howto for the COFF backend linker. */ 414 415static reloc_howto_type * 416coff_mips_rtype_to_howto (abfd, sec, rel, h, sym, addendp) 417 bfd *abfd ATTRIBUTE_UNUSED; 418 asection *sec; 419 struct internal_reloc *rel; 420 struct coff_link_hash_entry *h; 421 struct internal_syment *sym; 422 bfd_vma *addendp; 423{ 424 425 reloc_howto_type *howto; 426 427 howto = howto_table + rel->r_type; 428 429#ifdef COFF_WITH_PE 430 *addendp = 0; 431#endif 432 433 if (howto->pc_relative) 434 *addendp += sec->vma; 435 436 if (sym != NULL && sym->n_scnum == 0 && sym->n_value != 0) 437 { 438 /* This is a common symbol. The section contents include the 439 size (sym->n_value) as an addend. The relocate_section 440 function will be adding in the final value of the symbol. We 441 need to subtract out the current size in order to get the 442 correct result. */ 443 444 BFD_ASSERT (h != NULL); 445 446#ifndef COFF_WITH_PE 447 /* I think we *do* want to bypass this. If we don't, I have 448 seen some data parameters get the wrong relocation address. 449 If I link two versions with and without this section bypassed 450 and then do a binary comparison, the addresses which are 451 different can be looked up in the map. The case in which 452 this section has been bypassed has addresses which correspond 453 to values I can find in the map. */ 454 *addendp -= sym->n_value; 455#endif 456 } 457 458#ifndef COFF_WITH_PE 459 /* If the output symbol is common (in which case this must be a 460 relocatable link), we need to add in the final size of the 461 common symbol. */ 462 if (h != NULL && h->root.type == bfd_link_hash_common) 463 *addendp += h->root.u.c.size; 464#endif 465 466#ifdef COFF_WITH_PE 467 if (howto->pc_relative) 468 { 469 *addendp -= 4; 470 471 /* If the symbol is defined, then the generic code is going to 472 add back the symbol value in order to cancel out an 473 adjustment it made to the addend. However, we set the addend 474 to 0 at the start of this function. We need to adjust here, 475 to avoid the adjustment the generic code will make. FIXME: 476 This is getting a bit hackish. */ 477 if (sym != NULL && sym->n_scnum != 0) 478 *addendp -= sym->n_value; 479 } 480 481 if (rel->r_type == MIPS_R_RVA) 482 { 483 *addendp -= pe_data(sec->output_section->owner)->pe_opthdr.ImageBase; 484 } 485#endif 486 487 return howto; 488} 489 490#define coff_rtype_to_howto coff_mips_rtype_to_howto 491 492#define coff_bfd_reloc_type_lookup coff_mips_reloc_type_lookup 493 494/* Get the howto structure for a generic reloc type. */ 495 496static reloc_howto_type * 497coff_mips_reloc_type_lookup (abfd, code) 498 bfd *abfd ATTRIBUTE_UNUSED; 499 bfd_reloc_code_real_type code; 500{ 501 int mips_type; 502 503 switch (code) 504 { 505 case BFD_RELOC_16: 506 mips_type = MIPS_R_REFHALF; 507 break; 508 case BFD_RELOC_32: 509 case BFD_RELOC_CTOR: 510 mips_type = MIPS_R_REFWORD; 511 break; 512 case BFD_RELOC_MIPS_JMP: 513 mips_type = MIPS_R_JMPADDR; 514 break; 515 case BFD_RELOC_HI16_S: 516 mips_type = MIPS_R_REFHI; 517 break; 518 case BFD_RELOC_LO16: 519 mips_type = MIPS_R_REFLO; 520 break; 521 case BFD_RELOC_GPREL16: 522 mips_type = MIPS_R_GPREL; 523 break; 524 case BFD_RELOC_MIPS_LITERAL: 525 mips_type = MIPS_R_LITERAL; 526 break; 527 case BFD_RELOC_RVA: 528 mips_type = MIPS_R_RVA; 529 break; 530 default: 531 return (reloc_howto_type *) NULL; 532 } 533 534 return &howto_table[mips_type]; 535} 536 537static void 538mips_swap_reloc_in (abfd, src, dst) 539 bfd *abfd; 540 PTR src; 541 PTR dst; 542{ 543 static struct internal_reloc pair_prev; 544 RELOC *reloc_src = (RELOC *) src; 545 struct internal_reloc *reloc_dst = (struct internal_reloc *) dst; 546 547 reloc_dst->r_vaddr = H_GET_32 (abfd, reloc_src->r_vaddr); 548 reloc_dst->r_symndx = H_GET_S32 (abfd, reloc_src->r_symndx); 549 reloc_dst->r_type = H_GET_16 (abfd, reloc_src->r_type); 550 reloc_dst->r_size = 0; 551 reloc_dst->r_extern = 0; 552 reloc_dst->r_offset = 0; 553 554 switch (reloc_dst->r_type) 555 { 556 case MIPS_R_REFHI: 557 pair_prev = *reloc_dst; 558 break; 559 case MIPS_R_PAIR: 560 reloc_dst->r_offset = reloc_dst->r_symndx; 561 if (reloc_dst->r_offset & 0x8000) 562 reloc_dst->r_offset -= 0x10000; 563 /*printf ("dj: pair offset is %08x\n", reloc_dst->r_offset);*/ 564 reloc_dst->r_symndx = pair_prev.r_symndx; 565 break; 566 } 567} 568 569static unsigned int 570mips_swap_reloc_out (abfd, src, dst) 571 bfd *abfd; 572 PTR src; 573 PTR dst; 574{ 575 static int prev_offset = 1; 576 static bfd_vma prev_addr = 0; 577 struct internal_reloc *reloc_src = (struct internal_reloc *)src; 578 struct external_reloc *reloc_dst = (struct external_reloc *)dst; 579 580 switch (reloc_src->r_type) 581 { 582 case MIPS_R_REFHI: 583 prev_addr = reloc_src->r_vaddr; 584 prev_offset = reloc_src->r_offset; 585 break; 586 case MIPS_R_REFLO: 587 if (reloc_src->r_vaddr == prev_addr) 588 { 589 /* FIXME: only slightly hackish. If we see a REFLO pointing to 590 the same address as a REFHI, we assume this is the matching 591 PAIR reloc and output it accordingly. The symndx is really 592 the low 16 bits of the addend */ 593 H_PUT_32 (abfd, reloc_src->r_vaddr, reloc_dst->r_vaddr); 594 H_PUT_32 (abfd, reloc_src->r_symndx, reloc_dst->r_symndx); 595 H_PUT_16 (abfd, MIPS_R_PAIR, reloc_dst->r_type); 596 return RELSZ; 597 } 598 break; 599 } 600 601 H_PUT_32 (abfd, reloc_src->r_vaddr, reloc_dst->r_vaddr); 602 H_PUT_32 (abfd, reloc_src->r_symndx, reloc_dst->r_symndx); 603 604 H_PUT_16 (abfd, reloc_src->r_type, reloc_dst->r_type); 605 return RELSZ; 606} 607 608#define coff_swap_reloc_in mips_swap_reloc_in 609#define coff_swap_reloc_out mips_swap_reloc_out 610#define NO_COFF_RELOCS 611 612static bfd_boolean 613coff_pe_mips_relocate_section (output_bfd, info, input_bfd, 614 input_section, contents, relocs, syms, 615 sections) 616 bfd *output_bfd; 617 struct bfd_link_info *info; 618 bfd *input_bfd; 619 asection *input_section; 620 bfd_byte *contents; 621 struct internal_reloc *relocs; 622 struct internal_syment *syms; 623 asection **sections; 624{ 625 bfd_vma gp; 626 bfd_boolean gp_undefined; 627 size_t adjust; 628 struct internal_reloc *rel; 629 struct internal_reloc *rel_end; 630 unsigned int i; 631 bfd_boolean got_lo; 632 633 if (info->relocatable) 634 { 635 (*_bfd_error_handler) 636 (_("%B: `ld -r' not supported with PE MIPS objects\n"), input_bfd); 637 bfd_set_error (bfd_error_bad_value); 638 return FALSE; 639 } 640 641 BFD_ASSERT (input_bfd->xvec->byteorder 642 == output_bfd->xvec->byteorder); 643 644#if 0 645 printf ("dj: relocate %s(%s) %08x\n", 646 input_bfd->filename, input_section->name, 647 input_section->output_section->vma + input_section->output_offset); 648#endif 649 650 gp = _bfd_get_gp_value (output_bfd); 651 if (gp == 0) 652 gp_undefined = TRUE; 653 else 654 gp_undefined = FALSE; 655 656 got_lo = FALSE; 657 658 adjust = 0; 659 660 rel = relocs; 661 rel_end = rel + input_section->reloc_count; 662 for (i = 0; rel < rel_end; rel++, i++) 663 { 664 long symndx; 665 struct coff_link_hash_entry *h; 666 struct internal_syment *sym; 667 bfd_vma addend = 0; 668 bfd_vma val, tmp, targ, src, low; 669 reloc_howto_type *howto; 670 unsigned char *mem = contents + rel->r_vaddr; 671 672 symndx = rel->r_symndx; 673 674 if (symndx == -1) 675 { 676 h = NULL; 677 sym = NULL; 678 } 679 else 680 { 681 h = obj_coff_sym_hashes (input_bfd)[symndx]; 682 sym = syms + symndx; 683 } 684 685 /* COFF treats common symbols in one of two ways. Either the 686 size of the symbol is included in the section contents, or it 687 is not. We assume that the size is not included, and force 688 the rtype_to_howto function to adjust the addend as needed. */ 689 690 if (sym != NULL && sym->n_scnum != 0) 691 addend = - sym->n_value; 692 else 693 addend = 0; 694 695 howto = bfd_coff_rtype_to_howto (input_bfd, input_section, rel, h, 696 sym, &addend); 697 if (howto == NULL) 698 return FALSE; 699 700 /* If we are doing a relocatable link, then we can just ignore 701 a PC relative reloc that is pcrel_offset. It will already 702 have the correct value. If this is not a relocatable link, 703 then we should ignore the symbol value. */ 704 if (howto->pc_relative && howto->pcrel_offset) 705 { 706 if (info->relocatable) 707 continue; 708 if (sym != NULL && sym->n_scnum != 0) 709 addend += sym->n_value; 710 } 711 712 val = 0; 713 714 if (h == NULL) 715 { 716 asection *sec; 717 718 if (symndx == -1) 719 { 720 sec = bfd_abs_section_ptr; 721 val = 0; 722 } 723 else 724 { 725 sec = sections[symndx]; 726 val = (sec->output_section->vma 727 + sec->output_offset 728 + sym->n_value); 729 if (! obj_pe (input_bfd)) 730 val -= sec->vma; 731 } 732 } 733 else 734 { 735 if (h->root.type == bfd_link_hash_defined 736 || h->root.type == bfd_link_hash_defweak) 737 { 738 asection *sec; 739 740 sec = h->root.u.def.section; 741 val = (h->root.u.def.value 742 + sec->output_section->vma 743 + sec->output_offset); 744 } 745 746 else if (! info->relocatable) 747 { 748 if (! ((*info->callbacks->undefined_symbol) 749 (info, h->root.root.string, input_bfd, input_section, 750 rel->r_vaddr - input_section->vma, TRUE))) 751 return FALSE; 752 } 753 } 754 755 src = rel->r_vaddr + input_section->output_section->vma 756 + input_section->output_offset; 757#if 0 758 printf ("dj: reloc %02x %-8s a=%08x/%08x(%08x) v=%08x+%08x %s\n", 759 rel->r_type, howto_table[rel->r_type].name, 760 src, rel->r_vaddr, *(unsigned long *)mem, val, rel->r_offset, 761 h?h->root.root.string:"(none)"); 762#endif 763 764 /* OK, at this point the following variables are set up: 765 src = VMA of the memory we're fixing up 766 mem = pointer to memory we're fixing up 767 val = VMA of what we need to refer to 768 */ 769 770#define UI(x) (*_bfd_error_handler) (_("%B: unimplemented %s\n"), \ 771 input_bfd, x); \ 772 bfd_set_error (bfd_error_bad_value); 773 774 switch (rel->r_type) 775 { 776 case MIPS_R_ABSOLUTE: 777 /* ignore these */ 778 break; 779 780 case MIPS_R_REFHALF: 781 UI("refhalf"); 782 break; 783 784 case MIPS_R_REFWORD: 785 tmp = bfd_get_32(input_bfd, mem); 786 /* printf ("refword: src=%08x targ=%08x+%08x\n", src, tmp, val); */ 787 tmp += val; 788 bfd_put_32(input_bfd, tmp, mem); 789 break; 790 791 case MIPS_R_JMPADDR: 792 tmp = bfd_get_32(input_bfd, mem); 793 targ = val + (tmp&0x03ffffff)*4; 794 if ((src & 0xf0000000) != (targ & 0xf0000000)) 795 { 796 (*_bfd_error_handler) (_("%B: jump too far away\n"), input_bfd); 797 bfd_set_error (bfd_error_bad_value); 798 return FALSE; 799 } 800 tmp &= 0xfc000000; 801 tmp |= (targ/4) & 0x3ffffff; 802 bfd_put_32(input_bfd, tmp, mem); 803 break; 804 805 case MIPS_R_REFHI: 806 tmp = bfd_get_32(input_bfd, mem); 807 switch (rel[1].r_type) 808 { 809 case MIPS_R_PAIR: 810 /* MS PE object */ 811 targ = val + rel[1].r_offset + ((tmp & 0xffff) << 16); 812 break; 813 case MIPS_R_REFLO: 814 /* GNU COFF object */ 815 low = bfd_get_32(input_bfd, contents + rel[1].r_vaddr); 816 low &= 0xffff; 817 if (low & 0x8000) 818 low -= 0x10000; 819 targ = val + low + ((tmp & 0xffff) << 16); 820 break; 821 default: 822 (*_bfd_error_handler) (_("%B: bad pair/reflo after refhi\n"), 823 input_bfd); 824 bfd_set_error (bfd_error_bad_value); 825 return FALSE; 826 } 827 tmp &= 0xffff0000; 828 tmp |= (targ >> 16) & 0xffff; 829 bfd_put_32(input_bfd, tmp, mem); 830 break; 831 832 case MIPS_R_REFLO: 833 tmp = bfd_get_32(input_bfd, mem); 834 targ = val + (tmp & 0xffff); 835 /* printf ("refword: src=%08x targ=%08x\n", src, targ); */ 836 tmp &= 0xffff0000; 837 tmp |= targ & 0xffff; 838 bfd_put_32(input_bfd, tmp, mem); 839 break; 840 841 case MIPS_R_GPREL: 842 case MIPS_R_LITERAL: 843 UI("gprel"); 844 break; 845 846 case MIPS_R_SECTION: 847 UI("section"); 848 break; 849 850 case MIPS_R_SECREL: 851 UI("secrel"); 852 break; 853 854 case MIPS_R_SECRELLO: 855 UI("secrello"); 856 break; 857 858 case MIPS_R_SECRELHI: 859 UI("secrelhi"); 860 break; 861 862 case MIPS_R_RVA: 863 tmp = bfd_get_32 (input_bfd, mem); 864 /* printf ("rva: src=%08x targ=%08x+%08x\n", src, tmp, val); */ 865 tmp += val 866 - pe_data (input_section->output_section->owner)->pe_opthdr.ImageBase; 867 bfd_put_32 (input_bfd, tmp, mem); 868 break; 869 870 case MIPS_R_PAIR: 871 /* ignore these */ 872 break; 873 } 874 } 875 876 return TRUE; 877} 878 879#define coff_relocate_section coff_pe_mips_relocate_section 880 881#ifdef TARGET_UNDERSCORE 882 883/* If mips gcc uses underscores for symbol names, then it does not use 884 a leading dot for local labels, so if TARGET_UNDERSCORE is defined 885 we treat all symbols starting with L as local. */ 886 887static bfd_boolean coff_mips_is_local_label_name 888 PARAMS ((bfd *, const char *)); 889 890static bfd_boolean 891coff_mips_is_local_label_name (abfd, name) 892 bfd *abfd; 893 const char *name; 894{ 895 if (name[0] == 'L') 896 return TRUE; 897 898 return _bfd_coff_is_local_label_name (abfd, name); 899} 900 901#define coff_bfd_is_local_label_name coff_mips_is_local_label_name 902 903#endif /* TARGET_UNDERSCORE */ 904 905#define COFF_NO_HACK_SCNHDR_SIZE 906 907#include "coffcode.h" 908 909const bfd_target 910#ifdef TARGET_SYM 911 TARGET_SYM = 912#else 913 mipslpe_vec = 914#endif 915{ 916#ifdef TARGET_NAME 917 TARGET_NAME, 918#else 919 "pe-mips", /* name */ 920#endif 921 bfd_target_coff_flavour, 922 BFD_ENDIAN_LITTLE, /* data byte order is little */ 923 BFD_ENDIAN_LITTLE, /* header byte order is little */ 924 925 (HAS_RELOC | EXEC_P | /* object flags */ 926 HAS_LINENO | HAS_DEBUG | 927 HAS_SYMS | HAS_LOCALS | WP_TEXT | D_PAGED), 928 929#ifndef COFF_WITH_PE 930 (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC /* section flags */ 931 | SEC_CODE | SEC_DATA), 932#else 933 (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC /* section flags */ 934 | SEC_CODE | SEC_DATA 935 | SEC_LINK_ONCE | SEC_LINK_DUPLICATES), 936#endif 937 938#ifdef TARGET_UNDERSCORE 939 TARGET_UNDERSCORE, /* leading underscore */ 940#else 941 0, /* leading underscore */ 942#endif 943 '/', /* ar_pad_char */ 944 15, /* ar_max_namelen */ 945 946 bfd_getl64, bfd_getl_signed_64, bfd_putl64, 947 bfd_getl32, bfd_getl_signed_32, bfd_putl32, 948 bfd_getl16, bfd_getl_signed_16, bfd_putl16, /* data */ 949 bfd_getl64, bfd_getl_signed_64, bfd_putl64, 950 bfd_getl32, bfd_getl_signed_32, bfd_putl32, 951 bfd_getl16, bfd_getl_signed_16, bfd_putl16, /* hdrs */ 952 953/* Note that we allow an object file to be treated as a core file as well. */ 954 {_bfd_dummy_target, coff_object_p, /* bfd_check_format */ 955 bfd_generic_archive_p, coff_object_p}, 956 {bfd_false, coff_mkobject, _bfd_generic_mkarchive, /* bfd_set_format */ 957 bfd_false}, 958 {bfd_false, coff_write_object_contents, /* bfd_write_contents */ 959 _bfd_write_archive_contents, bfd_false}, 960 961 BFD_JUMP_TABLE_GENERIC (coff), 962 BFD_JUMP_TABLE_COPY (coff), 963 BFD_JUMP_TABLE_CORE (_bfd_nocore), 964 BFD_JUMP_TABLE_ARCHIVE (_bfd_archive_coff), 965 BFD_JUMP_TABLE_SYMBOLS (coff), 966 BFD_JUMP_TABLE_RELOCS (coff), 967 BFD_JUMP_TABLE_WRITE (coff), 968 BFD_JUMP_TABLE_LINK (coff), 969 BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic), 970 971 NULL, 972 973 COFF_SWAP_TABLE 974}; 975