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