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