1 /* BFD back-end for AMD 64 COFF files. 2 Copyright (C) 2006-2020 Free Software Foundation, Inc. 3 4 This file is part of BFD, the Binary File Descriptor library. 5 6 This program is free software; you can redistribute it and/or modify 7 it under the terms of the GNU General Public License as published by 8 the Free Software Foundation; either version 3 of the License, or 9 (at your option) any later version. 10 11 This program is distributed in the hope that it will be useful, 12 but WITHOUT ANY WARRANTY; without even the implied warranty of 13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 GNU General Public License for more details. 15 16 You should have received a copy of the GNU General Public License 17 along with this program; if not, write to the Free Software 18 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, 19 MA 02110-1301, USA. 20 21 Written by Kai Tietz, OneVision Software GmbH&CoKg. */ 22 23 #ifndef COFF_WITH_pex64 24 #define COFF_WITH_pex64 25 #endif 26 27 /* Note we have to make sure not to include headers twice. 28 Not all headers are wrapped in #ifdef guards, so we define 29 PEI_HEADERS to prevent double including here. */ 30 #ifndef PEI_HEADERS 31 #include "sysdep.h" 32 #include "bfd.h" 33 #include "libbfd.h" 34 #include "coff/x86_64.h" 35 #include "coff/internal.h" 36 #include "coff/pe.h" 37 #include "libcoff.h" 38 #include "libiberty.h" 39 #endif 40 41 #define BADMAG(x) AMD64BADMAG(x) 42 43 #ifdef COFF_WITH_pex64 44 # undef AOUTSZ 45 # define AOUTSZ PEPAOUTSZ 46 # define PEAOUTHDR PEPAOUTHDR 47 #endif 48 49 #define COFF_DEFAULT_SECTION_ALIGNMENT_POWER (2) 50 51 /* The page size is a guess based on ELF. */ 52 53 #define COFF_PAGE_SIZE 0x1000 54 55 /* All users of this file have bfd_octets_per_byte (abfd, sec) == 1. */ 56 #define OCTETS_PER_BYTE(ABFD, SEC) 1 57 58 /* For some reason when using AMD COFF the value stored in the .text 59 section for a reference to a common symbol is the value itself plus 60 any desired offset. Ian Taylor, Cygnus Support. */ 61 62 /* If we are producing relocatable output, we need to do some 63 adjustments to the object file that are not done by the 64 bfd_perform_relocation function. This function is called by every 65 reloc type to make any required adjustments. */ 66 67 static bfd_reloc_status_type 68 coff_amd64_reloc (bfd *abfd, 69 arelent *reloc_entry, 70 asymbol *symbol, 71 void * data, 72 asection *input_section ATTRIBUTE_UNUSED, 73 bfd *output_bfd, 74 char **error_message ATTRIBUTE_UNUSED) 75 { 76 symvalue diff; 77 78 #if !defined(COFF_WITH_PE) 79 if (output_bfd == NULL) 80 return bfd_reloc_continue; 81 #endif 82 83 if (bfd_is_com_section (symbol->section)) 84 { 85 #if !defined(COFF_WITH_PE) 86 /* We are relocating a common symbol. The current value in the 87 object file is ORIG + OFFSET, where ORIG is the value of the 88 common symbol as seen by the object file when it was compiled 89 (this may be zero if the symbol was undefined) and OFFSET is 90 the offset into the common symbol (normally zero, but may be 91 non-zero when referring to a field in a common structure). 92 ORIG is the negative of reloc_entry->addend, which is set by 93 the CALC_ADDEND macro below. We want to replace the value in 94 the object file with NEW + OFFSET, where NEW is the value of 95 the common symbol which we are going to put in the final 96 object file. NEW is symbol->value. */ 97 diff = symbol->value + reloc_entry->addend; 98 #else 99 /* In PE mode, we do not offset the common symbol. */ 100 diff = reloc_entry->addend; 101 #endif 102 } 103 else 104 { 105 /* For some reason bfd_perform_relocation always effectively 106 ignores the addend for a COFF target when producing 107 relocatable output. This seems to be always wrong for 386 108 COFF, so we handle the addend here instead. */ 109 #if defined(COFF_WITH_PE) 110 if (output_bfd == NULL) 111 { 112 reloc_howto_type *howto = reloc_entry->howto; 113 114 /* Although PC relative relocations are very similar between 115 PE and non-PE formats, but they are off by 1 << howto->size 116 bytes. For the external relocation, PE is very different 117 from others. See md_apply_fix3 () in gas/config/tc-amd64.c. 118 When we link PE and non-PE object files together to 119 generate a non-PE executable, we have to compensate it 120 here. */ 121 if(howto->pc_relative && howto->pcrel_offset) 122 diff = -(1 << howto->size); 123 else if(symbol->flags & BSF_WEAK) 124 diff = reloc_entry->addend - symbol->value; 125 else 126 diff = -reloc_entry->addend; 127 } 128 else 129 #endif 130 diff = reloc_entry->addend; 131 } 132 133 #if defined(COFF_WITH_PE) 134 /* FIXME: How should this case be handled? */ 135 if (reloc_entry->howto->type == R_AMD64_IMAGEBASE 136 && output_bfd != NULL 137 && bfd_get_flavour (output_bfd) == bfd_target_coff_flavour) 138 diff -= pe_data (output_bfd)->pe_opthdr.ImageBase; 139 #endif 140 141 #define DOIT(x) \ 142 x = ((x & ~howto->dst_mask) | (((x & howto->src_mask) + diff) & howto->dst_mask)) 143 144 if (diff != 0) 145 { 146 reloc_howto_type *howto = reloc_entry->howto; 147 bfd_size_type octets = (reloc_entry->address 148 * OCTETS_PER_BYTE (abfd, input_section)); 149 unsigned char *addr = (unsigned char *) data + octets; 150 151 if (!bfd_reloc_offset_in_range (howto, abfd, input_section, octets)) 152 return bfd_reloc_outofrange; 153 154 switch (howto->size) 155 { 156 case 0: 157 { 158 char x = bfd_get_8 (abfd, addr); 159 DOIT (x); 160 bfd_put_8 (abfd, x, addr); 161 } 162 break; 163 164 case 1: 165 { 166 short x = bfd_get_16 (abfd, addr); 167 DOIT (x); 168 bfd_put_16 (abfd, (bfd_vma) x, addr); 169 } 170 break; 171 172 case 2: 173 { 174 long x = bfd_get_32 (abfd, addr); 175 DOIT (x); 176 bfd_put_32 (abfd, (bfd_vma) x, addr); 177 } 178 break; 179 180 case 4: 181 { 182 bfd_uint64_t x = bfd_get_64 (abfd, addr); 183 DOIT (x); 184 bfd_put_64 (abfd, x, addr); 185 } 186 break; 187 188 default: 189 bfd_set_error (bfd_error_bad_value); 190 return bfd_reloc_notsupported; 191 } 192 } 193 194 /* Now let bfd_perform_relocation finish everything up. */ 195 return bfd_reloc_continue; 196 } 197 198 #if defined(COFF_WITH_PE) 199 /* Return TRUE if this relocation should appear in the output .reloc 200 section. */ 201 202 static bfd_boolean 203 in_reloc_p (bfd *abfd ATTRIBUTE_UNUSED, reloc_howto_type *howto) 204 { 205 return ! howto->pc_relative && howto->type != R_AMD64_IMAGEBASE 206 && howto->type != R_AMD64_SECREL; 207 } 208 #endif /* COFF_WITH_PE */ 209 210 #ifndef PCRELOFFSET 211 #define PCRELOFFSET TRUE 212 #endif 213 214 static reloc_howto_type howto_table[] = 215 { 216 EMPTY_HOWTO (0), 217 HOWTO (R_AMD64_DIR64, /* type 1*/ 218 0, /* rightshift */ 219 4, /* size (0 = byte, 1 = short, 2 = long, 4 = long long) */ 220 64, /* bitsize */ 221 FALSE, /* pc_relative */ 222 0, /* bitpos */ 223 complain_overflow_bitfield, /* complain_on_overflow */ 224 coff_amd64_reloc, /* special_function */ 225 "R_X86_64_64", /* name */ 226 TRUE, /* partial_inplace */ 227 0xffffffffffffffffll, /* src_mask */ 228 0xffffffffffffffffll, /* dst_mask */ 229 TRUE), /* pcrel_offset */ 230 HOWTO (R_AMD64_DIR32, /* type 2 */ 231 0, /* rightshift */ 232 2, /* size (0 = byte, 1 = short, 2 = long) */ 233 32, /* bitsize */ 234 FALSE, /* pc_relative */ 235 0, /* bitpos */ 236 complain_overflow_bitfield, /* complain_on_overflow */ 237 coff_amd64_reloc, /* special_function */ 238 "R_X86_64_32", /* name */ 239 TRUE, /* partial_inplace */ 240 0xffffffff, /* src_mask */ 241 0xffffffff, /* dst_mask */ 242 TRUE), /* pcrel_offset */ 243 /* PE IMAGE_REL_AMD64_ADDR32NB relocation (3). */ 244 HOWTO (R_AMD64_IMAGEBASE, /* type */ 245 0, /* rightshift */ 246 2, /* size (0 = byte, 1 = short, 2 = long) */ 247 32, /* bitsize */ 248 FALSE, /* pc_relative */ 249 0, /* bitpos */ 250 complain_overflow_bitfield, /* complain_on_overflow */ 251 coff_amd64_reloc, /* special_function */ 252 "rva32", /* name */ 253 TRUE, /* partial_inplace */ 254 0xffffffff, /* src_mask */ 255 0xffffffff, /* dst_mask */ 256 FALSE), /* pcrel_offset */ 257 /* 32-bit longword PC relative relocation (4). */ 258 HOWTO (R_AMD64_PCRLONG, /* type 4 */ 259 0, /* rightshift */ 260 2, /* size (0 = byte, 1 = short, 2 = long) */ 261 32, /* bitsize */ 262 TRUE, /* pc_relative */ 263 0, /* bitpos */ 264 complain_overflow_signed, /* complain_on_overflow */ 265 coff_amd64_reloc, /* special_function */ 266 "R_X86_64_PC32", /* name */ 267 TRUE, /* partial_inplace */ 268 0xffffffff, /* src_mask */ 269 0xffffffff, /* dst_mask */ 270 PCRELOFFSET), /* pcrel_offset */ 271 272 HOWTO (R_AMD64_PCRLONG_1, /* type 5 */ 273 0, /* rightshift */ 274 2, /* size (0 = byte, 1 = short, 2 = long) */ 275 32, /* bitsize */ 276 TRUE, /* pc_relative */ 277 0, /* bitpos */ 278 complain_overflow_signed, /* complain_on_overflow */ 279 coff_amd64_reloc, /* special_function */ 280 "DISP32+1", /* name */ 281 TRUE, /* partial_inplace */ 282 0xffffffff, /* src_mask */ 283 0xffffffff, /* dst_mask */ 284 PCRELOFFSET), /* pcrel_offset */ 285 HOWTO (R_AMD64_PCRLONG_2, /* type 6 */ 286 0, /* rightshift */ 287 2, /* size (0 = byte, 1 = short, 2 = long) */ 288 32, /* bitsize */ 289 TRUE, /* pc_relative */ 290 0, /* bitpos */ 291 complain_overflow_signed, /* complain_on_overflow */ 292 coff_amd64_reloc, /* special_function */ 293 "DISP32+2", /* name */ 294 TRUE, /* partial_inplace */ 295 0xffffffff, /* src_mask */ 296 0xffffffff, /* dst_mask */ 297 PCRELOFFSET), /* pcrel_offset */ 298 HOWTO (R_AMD64_PCRLONG_3, /* type 7 */ 299 0, /* rightshift */ 300 2, /* size (0 = byte, 1 = short, 2 = long) */ 301 32, /* bitsize */ 302 TRUE, /* pc_relative */ 303 0, /* bitpos */ 304 complain_overflow_signed, /* complain_on_overflow */ 305 coff_amd64_reloc, /* special_function */ 306 "DISP32+3", /* name */ 307 TRUE, /* partial_inplace */ 308 0xffffffff, /* src_mask */ 309 0xffffffff, /* dst_mask */ 310 PCRELOFFSET), /* pcrel_offset */ 311 HOWTO (R_AMD64_PCRLONG_4, /* type 8 */ 312 0, /* rightshift */ 313 2, /* size (0 = byte, 1 = short, 2 = long) */ 314 32, /* bitsize */ 315 TRUE, /* pc_relative */ 316 0, /* bitpos */ 317 complain_overflow_signed, /* complain_on_overflow */ 318 coff_amd64_reloc, /* special_function */ 319 "DISP32+4", /* name */ 320 TRUE, /* partial_inplace */ 321 0xffffffff, /* src_mask */ 322 0xffffffff, /* dst_mask */ 323 PCRELOFFSET), /* pcrel_offset */ 324 HOWTO (R_AMD64_PCRLONG_5, /* type 9 */ 325 0, /* rightshift */ 326 2, /* size (0 = byte, 1 = short, 2 = long) */ 327 32, /* bitsize */ 328 TRUE, /* pc_relative */ 329 0, /* bitpos */ 330 complain_overflow_signed, /* complain_on_overflow */ 331 coff_amd64_reloc, /* special_function */ 332 "DISP32+5", /* name */ 333 TRUE, /* partial_inplace */ 334 0xffffffff, /* src_mask */ 335 0xffffffff, /* dst_mask */ 336 PCRELOFFSET), /* pcrel_offset */ 337 EMPTY_HOWTO (10), /* R_AMD64_SECTION 10 */ 338 #if defined(COFF_WITH_PE) 339 /* 32-bit longword section relative relocation (11). */ 340 HOWTO (R_AMD64_SECREL, /* type */ 341 0, /* rightshift */ 342 2, /* size (0 = byte, 1 = short, 2 = long) */ 343 32, /* bitsize */ 344 FALSE, /* pc_relative */ 345 0, /* bitpos */ 346 complain_overflow_bitfield, /* complain_on_overflow */ 347 coff_amd64_reloc, /* special_function */ 348 "secrel32", /* name */ 349 TRUE, /* partial_inplace */ 350 0xffffffff, /* src_mask */ 351 0xffffffff, /* dst_mask */ 352 TRUE), /* pcrel_offset */ 353 #else 354 EMPTY_HOWTO (11), 355 #endif 356 EMPTY_HOWTO (12), 357 EMPTY_HOWTO (13), 358 #ifndef DONT_EXTEND_AMD64 359 HOWTO (R_AMD64_PCRQUAD, 360 0, /* rightshift */ 361 4, /* size (0 = byte, 1 = short, 2 = long) */ 362 64, /* bitsize */ 363 TRUE, /* pc_relative */ 364 0, /* bitpos */ 365 complain_overflow_signed, /* complain_on_overflow */ 366 coff_amd64_reloc, /* special_function */ 367 "R_X86_64_PC64", /* name */ 368 TRUE, /* partial_inplace */ 369 0xffffffffffffffffll, /* src_mask */ 370 0xffffffffffffffffll, /* dst_mask */ 371 PCRELOFFSET), /* pcrel_offset */ 372 #else 373 EMPTY_HOWTO (14), 374 #endif 375 /* Byte relocation (15). */ 376 HOWTO (R_RELBYTE, /* type */ 377 0, /* rightshift */ 378 0, /* size (0 = byte, 1 = short, 2 = long) */ 379 8, /* bitsize */ 380 FALSE, /* pc_relative */ 381 0, /* bitpos */ 382 complain_overflow_bitfield, /* complain_on_overflow */ 383 coff_amd64_reloc, /* special_function */ 384 "R_X86_64_8", /* name */ 385 TRUE, /* partial_inplace */ 386 0x000000ff, /* src_mask */ 387 0x000000ff, /* dst_mask */ 388 PCRELOFFSET), /* pcrel_offset */ 389 /* 16-bit word relocation (16). */ 390 HOWTO (R_RELWORD, /* type */ 391 0, /* rightshift */ 392 1, /* size (0 = byte, 1 = short, 2 = long) */ 393 16, /* bitsize */ 394 FALSE, /* pc_relative */ 395 0, /* bitpos */ 396 complain_overflow_bitfield, /* complain_on_overflow */ 397 coff_amd64_reloc, /* special_function */ 398 "R_X86_64_16", /* name */ 399 TRUE, /* partial_inplace */ 400 0x0000ffff, /* src_mask */ 401 0x0000ffff, /* dst_mask */ 402 PCRELOFFSET), /* pcrel_offset */ 403 /* 32-bit longword relocation (17). */ 404 HOWTO (R_RELLONG, /* type */ 405 0, /* rightshift */ 406 2, /* size (0 = byte, 1 = short, 2 = long) */ 407 32, /* bitsize */ 408 FALSE, /* pc_relative */ 409 0, /* bitpos */ 410 complain_overflow_bitfield, /* complain_on_overflow */ 411 coff_amd64_reloc, /* special_function */ 412 "R_X86_64_32S", /* name */ 413 TRUE, /* partial_inplace */ 414 0xffffffff, /* src_mask */ 415 0xffffffff, /* dst_mask */ 416 PCRELOFFSET), /* pcrel_offset */ 417 /* Byte PC relative relocation (18). */ 418 HOWTO (R_PCRBYTE, /* type */ 419 0, /* rightshift */ 420 0, /* size (0 = byte, 1 = short, 2 = long) */ 421 8, /* bitsize */ 422 TRUE, /* pc_relative */ 423 0, /* bitpos */ 424 complain_overflow_signed, /* complain_on_overflow */ 425 coff_amd64_reloc, /* special_function */ 426 "R_X86_64_PC8", /* name */ 427 TRUE, /* partial_inplace */ 428 0x000000ff, /* src_mask */ 429 0x000000ff, /* dst_mask */ 430 PCRELOFFSET), /* pcrel_offset */ 431 /* 16-bit word PC relative relocation (19). */ 432 HOWTO (R_PCRWORD, /* type */ 433 0, /* rightshift */ 434 1, /* size (0 = byte, 1 = short, 2 = long) */ 435 16, /* bitsize */ 436 TRUE, /* pc_relative */ 437 0, /* bitpos */ 438 complain_overflow_signed, /* complain_on_overflow */ 439 coff_amd64_reloc, /* special_function */ 440 "R_X86_64_PC16", /* name */ 441 TRUE, /* partial_inplace */ 442 0x0000ffff, /* src_mask */ 443 0x0000ffff, /* dst_mask */ 444 PCRELOFFSET), /* pcrel_offset */ 445 /* 32-bit longword PC relative relocation (20). */ 446 HOWTO (R_PCRLONG, /* type */ 447 0, /* rightshift */ 448 2, /* size (0 = byte, 1 = short, 2 = long) */ 449 32, /* bitsize */ 450 TRUE, /* pc_relative */ 451 0, /* bitpos */ 452 complain_overflow_signed, /* complain_on_overflow */ 453 coff_amd64_reloc, /* special_function */ 454 "R_X86_64_PC32", /* name */ 455 TRUE, /* partial_inplace */ 456 0xffffffff, /* src_mask */ 457 0xffffffff, /* dst_mask */ 458 PCRELOFFSET) /* pcrel_offset */ 459 }; 460 461 #define NUM_HOWTOS ARRAY_SIZE (howto_table) 462 463 /* Turn a howto into a reloc nunmber */ 464 465 #define SELECT_RELOC(x,howto) { x.r_type = howto->type; } 466 #define I386 1 /* Customize coffcode.h */ 467 #define AMD64 1 468 469 #define RTYPE2HOWTO(cache_ptr, dst) \ 470 ((cache_ptr)->howto = \ 471 ((dst)->r_type < NUM_HOWTOS) \ 472 ? howto_table + (dst)->r_type \ 473 : NULL) 474 475 /* For 386 COFF a STYP_NOLOAD | STYP_BSS section is part of a shared 476 library. On some other COFF targets STYP_BSS is normally 477 STYP_NOLOAD. */ 478 #define BSS_NOLOAD_IS_SHARED_LIBRARY 479 480 /* Compute the addend of a reloc. If the reloc is to a common symbol, 481 the object file contains the value of the common symbol. By the 482 time this is called, the linker may be using a different symbol 483 from a different object file with a different value. Therefore, we 484 hack wildly to locate the original symbol from this file so that we 485 can make the correct adjustment. This macro sets coffsym to the 486 symbol from the original file, and uses it to set the addend value 487 correctly. If this is not a common symbol, the usual addend 488 calculation is done, except that an additional tweak is needed for 489 PC relative relocs. 490 FIXME: This macro refers to symbols and asect; these are from the 491 calling function, not the macro arguments. */ 492 493 #define CALC_ADDEND(abfd, ptr, reloc, cache_ptr) \ 494 { \ 495 coff_symbol_type *coffsym = NULL; \ 496 \ 497 if (ptr && bfd_asymbol_bfd (ptr) != abfd) \ 498 coffsym = (obj_symbols (abfd) \ 499 + (cache_ptr->sym_ptr_ptr - symbols)); \ 500 else if (ptr) \ 501 coffsym = coff_symbol_from (ptr); \ 502 \ 503 if (coffsym != NULL \ 504 && coffsym->native->u.syment.n_scnum == 0) \ 505 cache_ptr->addend = - coffsym->native->u.syment.n_value; \ 506 else if (ptr && bfd_asymbol_bfd (ptr) == abfd \ 507 && ptr->section != NULL) \ 508 cache_ptr->addend = - (ptr->section->vma + ptr->value); \ 509 else \ 510 cache_ptr->addend = 0; \ 511 if (ptr && reloc.r_type < NUM_HOWTOS \ 512 && howto_table[reloc.r_type].pc_relative) \ 513 cache_ptr->addend += asect->vma; \ 514 } 515 516 /* We use the special COFF backend linker. For normal AMD64 COFF, we 517 can use the generic relocate_section routine. For PE, we need our 518 own routine. */ 519 520 #if !defined(COFF_WITH_PE) 521 522 #define coff_relocate_section _bfd_coff_generic_relocate_section 523 524 #else /* COFF_WITH_PE */ 525 526 /* The PE relocate section routine. The only difference between this 527 and the regular routine is that we don't want to do anything for a 528 relocatable link. */ 529 530 static bfd_boolean 531 coff_pe_amd64_relocate_section (bfd *output_bfd, 532 struct bfd_link_info *info, 533 bfd *input_bfd, 534 asection *input_section, 535 bfd_byte *contents, 536 struct internal_reloc *relocs, 537 struct internal_syment *syms, 538 asection **sections) 539 { 540 if (bfd_link_relocatable (info)) 541 return TRUE; 542 543 return _bfd_coff_generic_relocate_section (output_bfd, info, input_bfd,input_section, contents,relocs, syms, sections); 544 } 545 546 #define coff_relocate_section coff_pe_amd64_relocate_section 547 548 #endif /* COFF_WITH_PE */ 549 550 /* Convert an rtype to howto for the COFF backend linker. */ 551 552 static reloc_howto_type * 553 coff_amd64_rtype_to_howto (bfd *abfd ATTRIBUTE_UNUSED, 554 asection *sec, 555 struct internal_reloc *rel, 556 struct coff_link_hash_entry *h, 557 struct internal_syment *sym, 558 bfd_vma *addendp) 559 { 560 reloc_howto_type *howto; 561 562 if (rel->r_type >= NUM_HOWTOS) 563 { 564 bfd_set_error (bfd_error_bad_value); 565 return NULL; 566 } 567 howto = howto_table + rel->r_type; 568 569 #if defined(COFF_WITH_PE) 570 /* Cancel out code in _bfd_coff_generic_relocate_section. */ 571 *addendp = 0; 572 if (rel->r_type >= R_AMD64_PCRLONG_1 && rel->r_type <= R_AMD64_PCRLONG_5) 573 { 574 *addendp -= (bfd_vma)(rel->r_type - R_AMD64_PCRLONG); 575 rel->r_type = R_AMD64_PCRLONG; 576 } 577 #endif 578 579 if (howto->pc_relative) 580 *addendp += sec->vma; 581 582 if (sym != NULL && sym->n_scnum == 0 && sym->n_value != 0) 583 { 584 /* This is a common symbol. The section contents include the 585 size (sym->n_value) as an addend. The relocate_section 586 function will be adding in the final value of the symbol. We 587 need to subtract out the current size in order to get the 588 correct result. */ 589 BFD_ASSERT (h != NULL); 590 591 #if !defined(COFF_WITH_PE) 592 /* I think we *do* want to bypass this. If we don't, I have 593 seen some data parameters get the wrong relocation address. 594 If I link two versions with and without this section bypassed 595 and then do a binary comparison, the addresses which are 596 different can be looked up in the map. The case in which 597 this section has been bypassed has addresses which correspond 598 to values I can find in the map. */ 599 *addendp -= sym->n_value; 600 #endif 601 } 602 603 #if !defined(COFF_WITH_PE) 604 /* If the output symbol is common (in which case this must be a 605 relocatable link), we need to add in the final size of the 606 common symbol. */ 607 if (h != NULL && h->root.type == bfd_link_hash_common) 608 *addendp += h->root.u.c.size; 609 #endif 610 611 #if defined(COFF_WITH_PE) 612 if (howto->pc_relative) 613 { 614 #ifndef DONT_EXTEND_AMD64 615 if (rel->r_type == R_AMD64_PCRQUAD) 616 *addendp -= 8; 617 else 618 #endif 619 *addendp -= 4; 620 621 /* If the symbol is defined, then the generic code is going to 622 add back the symbol value in order to cancel out an 623 adjustment it made to the addend. However, we set the addend 624 to 0 at the start of this function. We need to adjust here, 625 to avoid the adjustment the generic code will make. FIXME: 626 This is getting a bit hackish. */ 627 if (sym != NULL && sym->n_scnum != 0) 628 *addendp -= sym->n_value; 629 } 630 631 if (rel->r_type == R_AMD64_IMAGEBASE 632 && (bfd_get_flavour (sec->output_section->owner) == bfd_target_coff_flavour)) 633 *addendp -= pe_data (sec->output_section->owner)->pe_opthdr.ImageBase; 634 635 if (rel->r_type == R_AMD64_SECREL) 636 { 637 bfd_vma osect_vma; 638 639 if (h && (h->root.type == bfd_link_hash_defined 640 || h->root.type == bfd_link_hash_defweak)) 641 osect_vma = h->root.u.def.section->output_section->vma; 642 else 643 { 644 asection *s; 645 int i; 646 647 /* Sigh, the only way to get the section to offset against 648 is to find it the hard way. */ 649 for (s = abfd->sections, i = 1; i < sym->n_scnum; i++) 650 s = s->next; 651 652 osect_vma = s->output_section->vma; 653 } 654 655 *addendp -= osect_vma; 656 } 657 #endif 658 659 return howto; 660 } 661 662 #define coff_bfd_reloc_type_lookup coff_amd64_reloc_type_lookup 663 #define coff_bfd_reloc_name_lookup coff_amd64_reloc_name_lookup 664 665 static reloc_howto_type * 666 coff_amd64_reloc_type_lookup (bfd *abfd ATTRIBUTE_UNUSED, bfd_reloc_code_real_type code) 667 { 668 switch (code) 669 { 670 case BFD_RELOC_RVA: 671 return howto_table + R_AMD64_IMAGEBASE; 672 case BFD_RELOC_32: 673 return howto_table + R_AMD64_DIR32; 674 case BFD_RELOC_64: 675 return howto_table + R_AMD64_DIR64; 676 case BFD_RELOC_64_PCREL: 677 #ifndef DONT_EXTEND_AMD64 678 return howto_table + R_AMD64_PCRQUAD; 679 #else 680 /* Fall through. */ 681 #endif 682 case BFD_RELOC_32_PCREL: 683 return howto_table + R_AMD64_PCRLONG; 684 case BFD_RELOC_X86_64_32S: 685 return howto_table + R_RELLONG; 686 case BFD_RELOC_16: 687 return howto_table + R_RELWORD; 688 case BFD_RELOC_16_PCREL: 689 return howto_table + R_PCRWORD; 690 case BFD_RELOC_8: 691 return howto_table + R_RELBYTE; 692 case BFD_RELOC_8_PCREL: 693 return howto_table + R_PCRBYTE; 694 #if defined(COFF_WITH_PE) 695 case BFD_RELOC_32_SECREL: 696 return howto_table + R_AMD64_SECREL; 697 #endif 698 default: 699 BFD_FAIL (); 700 return 0; 701 } 702 } 703 704 static reloc_howto_type * 705 coff_amd64_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED, 706 const char *r_name) 707 { 708 unsigned int i; 709 710 for (i = 0; i < NUM_HOWTOS; i++) 711 if (howto_table[i].name != NULL 712 && strcasecmp (howto_table[i].name, r_name) == 0) 713 return &howto_table[i]; 714 715 return NULL; 716 } 717 718 #define coff_rtype_to_howto coff_amd64_rtype_to_howto 719 720 #ifdef TARGET_UNDERSCORE 721 722 /* If amd64 gcc uses underscores for symbol names, then it does not use 723 a leading dot for local labels, so if TARGET_UNDERSCORE is defined 724 we treat all symbols starting with L as local. */ 725 726 static bfd_boolean 727 coff_amd64_is_local_label_name (bfd *abfd, const char *name) 728 { 729 if (name[0] == 'L') 730 return TRUE; 731 732 return _bfd_coff_is_local_label_name (abfd, name); 733 } 734 735 #define coff_bfd_is_local_label_name coff_amd64_is_local_label_name 736 737 #endif /* TARGET_UNDERSCORE */ 738 739 #ifndef bfd_pe_print_pdata 740 #define bfd_pe_print_pdata NULL 741 #endif 742 743 #include "coffcode.h" 744 745 #ifdef PE 746 #define amd64coff_object_p pe_bfd_object_p 747 #else 748 #define amd64coff_object_p coff_object_p 749 #endif 750 751 const bfd_target 752 #ifdef TARGET_SYM 753 TARGET_SYM = 754 #else 755 x86_64_coff_vec = 756 #endif 757 { 758 #ifdef TARGET_NAME 759 TARGET_NAME, 760 #else 761 "coff-x86-64", /* Name. */ 762 #endif 763 bfd_target_coff_flavour, 764 BFD_ENDIAN_LITTLE, /* Data byte order is little. */ 765 BFD_ENDIAN_LITTLE, /* Header byte order is little. */ 766 767 (HAS_RELOC | EXEC_P /* Object flags. */ 768 | HAS_LINENO | HAS_DEBUG 769 | HAS_SYMS | HAS_LOCALS | WP_TEXT | D_PAGED | BFD_COMPRESS | BFD_DECOMPRESS), 770 771 (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC /* Section flags. */ 772 #if defined(COFF_WITH_PE) 773 | SEC_LINK_ONCE | SEC_LINK_DUPLICATES | SEC_READONLY | SEC_DEBUGGING 774 #endif 775 | SEC_CODE | SEC_DATA | SEC_EXCLUDE ), 776 777 #ifdef TARGET_UNDERSCORE 778 TARGET_UNDERSCORE, /* Leading underscore. */ 779 #else 780 0, /* Leading underscore. */ 781 #endif 782 '/', /* Ar_pad_char. */ 783 15, /* Ar_max_namelen. */ 784 0, /* match priority. */ 785 786 bfd_getl64, bfd_getl_signed_64, bfd_putl64, 787 bfd_getl32, bfd_getl_signed_32, bfd_putl32, 788 bfd_getl16, bfd_getl_signed_16, bfd_putl16, /* Data. */ 789 bfd_getl64, bfd_getl_signed_64, bfd_putl64, 790 bfd_getl32, bfd_getl_signed_32, bfd_putl32, 791 bfd_getl16, bfd_getl_signed_16, bfd_putl16, /* Hdrs. */ 792 793 /* Note that we allow an object file to be treated as a core file as well. */ 794 { /* bfd_check_format. */ 795 _bfd_dummy_target, 796 amd64coff_object_p, 797 bfd_generic_archive_p, 798 amd64coff_object_p 799 }, 800 { /* bfd_set_format. */ 801 _bfd_bool_bfd_false_error, 802 coff_mkobject, 803 _bfd_generic_mkarchive, 804 _bfd_bool_bfd_false_error 805 }, 806 { /* bfd_write_contents. */ 807 _bfd_bool_bfd_false_error, 808 coff_write_object_contents, 809 _bfd_write_archive_contents, 810 _bfd_bool_bfd_false_error 811 }, 812 813 BFD_JUMP_TABLE_GENERIC (coff), 814 BFD_JUMP_TABLE_COPY (coff), 815 BFD_JUMP_TABLE_CORE (_bfd_nocore), 816 BFD_JUMP_TABLE_ARCHIVE (_bfd_archive_coff), 817 BFD_JUMP_TABLE_SYMBOLS (coff), 818 BFD_JUMP_TABLE_RELOCS (coff), 819 BFD_JUMP_TABLE_WRITE (coff), 820 BFD_JUMP_TABLE_LINK (coff), 821 BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic), 822 823 NULL, 824 825 COFF_SWAP_TABLE 826 }; 827