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