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 static hashval_t
660 htab_hash_section_index (const void * entry)
661 {
662 const struct bfd_section * sec = entry;
663 return sec->index;
664 }
665
666 static int
667 htab_eq_section_index (const void * e1, const void * e2)
668 {
669 const struct bfd_section * sec1 = e1;
670 const struct bfd_section * sec2 = e2;
671 return sec1->index == sec2->index;
672 }
673 #endif /* COFF_WITH_PE */
674
675 /* Convert an rtype to howto for the COFF backend linker. */
676
677 static reloc_howto_type *
678 coff_amd64_rtype_to_howto (bfd *abfd ATTRIBUTE_UNUSED,
679 asection *sec,
680 struct internal_reloc *rel,
681 struct coff_link_hash_entry *h,
682 struct internal_syment *sym,
683 bfd_vma *addendp)
684 {
685 reloc_howto_type *howto;
686
687 if (rel->r_type >= NUM_HOWTOS)
688 {
689 bfd_set_error (bfd_error_bad_value);
690 return NULL;
691 }
692 howto = howto_table + rel->r_type;
693
694 #if defined(COFF_WITH_PE)
695 /* Cancel out code in _bfd_coff_generic_relocate_section. */
696 *addendp = 0;
697 if (rel->r_type >= R_AMD64_PCRLONG_1 && rel->r_type <= R_AMD64_PCRLONG_5)
698 {
699 *addendp -= (bfd_vma)(rel->r_type - R_AMD64_PCRLONG);
700 rel->r_type = R_AMD64_PCRLONG;
701 }
702 #endif
703
704 if (howto->pc_relative)
705 *addendp += sec->vma;
706
707 if (sym != NULL && sym->n_scnum == 0 && sym->n_value != 0)
708 {
709 /* This is a common symbol. The section contents include the
710 size (sym->n_value) as an addend. The relocate_section
711 function will be adding in the final value of the symbol. We
712 need to subtract out the current size in order to get the
713 correct result. */
714 BFD_ASSERT (h != NULL);
715
716 #if !defined(COFF_WITH_PE)
717 /* I think we *do* want to bypass this. If we don't, I have
718 seen some data parameters get the wrong relocation address.
719 If I link two versions with and without this section bypassed
720 and then do a binary comparison, the addresses which are
721 different can be looked up in the map. The case in which
722 this section has been bypassed has addresses which correspond
723 to values I can find in the map. */
724 *addendp -= sym->n_value;
725 #endif
726 }
727
728 #if !defined(COFF_WITH_PE)
729 /* If the output symbol is common (in which case this must be a
730 relocatable link), we need to add in the final size of the
731 common symbol. */
732 if (h != NULL && h->root.type == bfd_link_hash_common)
733 *addendp += h->root.u.c.size;
734 #endif
735
736 #if defined(COFF_WITH_PE)
737 if (howto->pc_relative)
738 {
739 #ifndef DONT_EXTEND_AMD64
740 if (rel->r_type == R_AMD64_PCRQUAD)
741 *addendp -= 8;
742 else
743 #endif
744 *addendp -= 4;
745
746 /* If the symbol is defined, then the generic code is going to
747 add back the symbol value in order to cancel out an
748 adjustment it made to the addend. However, we set the addend
749 to 0 at the start of this function. We need to adjust here,
750 to avoid the adjustment the generic code will make. FIXME:
751 This is getting a bit hackish. */
752 if (sym != NULL && sym->n_scnum != 0)
753 *addendp -= sym->n_value;
754 }
755
756 if (rel->r_type == R_AMD64_IMAGEBASE
757 && (bfd_get_flavour (sec->output_section->owner) == bfd_target_coff_flavour))
758 *addendp -= pe_data (sec->output_section->owner)->pe_opthdr.ImageBase;
759
760 if (rel->r_type == R_AMD64_SECREL)
761 {
762 bfd_vma osect_vma = 0;
763
764 if (h != NULL
765 && (h->root.type == bfd_link_hash_defined
766 || h->root.type == bfd_link_hash_defweak))
767 osect_vma = h->root.u.def.section->output_section->vma;
768 else
769 {
770 htab_t table = coff_data (abfd)->section_by_index;
771 asection *s;
772
773 if (!table)
774 {
775 table = htab_create (10, htab_hash_section_index,
776 htab_eq_section_index, NULL);
777 if (table == NULL)
778 return NULL;
779 coff_data (abfd)->section_by_index = table;
780 }
781
782 if (htab_elements (table) == 0)
783 {
784 for (s = abfd->sections; s != NULL; s = s->next)
785 {
786 void ** slot = htab_find_slot (table, s, INSERT);
787
788 if (slot != NULL)
789 *slot = s;
790 }
791 }
792
793 struct bfd_section needle;
794
795 needle.index = sym->n_scnum - 1;
796 s = htab_find (table, &needle);
797 if (s != NULL)
798 osect_vma = s->output_section->vma;
799 }
800
801 *addendp -= osect_vma;
802 }
803 #endif
804
805 return howto;
806 }
807
808 #define coff_bfd_reloc_type_lookup coff_amd64_reloc_type_lookup
809 #define coff_bfd_reloc_name_lookup coff_amd64_reloc_name_lookup
810
811 static reloc_howto_type *
812 coff_amd64_reloc_type_lookup (bfd *abfd ATTRIBUTE_UNUSED, bfd_reloc_code_real_type code)
813 {
814 switch (code)
815 {
816 case BFD_RELOC_RVA:
817 return howto_table + R_AMD64_IMAGEBASE;
818 case BFD_RELOC_32:
819 return howto_table + R_AMD64_DIR32;
820 case BFD_RELOC_64:
821 return howto_table + R_AMD64_DIR64;
822 case BFD_RELOC_64_PCREL:
823 #ifndef DONT_EXTEND_AMD64
824 return howto_table + R_AMD64_PCRQUAD;
825 #else
826 /* Fall through. */
827 #endif
828 case BFD_RELOC_32_PCREL:
829 return howto_table + R_AMD64_PCRLONG;
830 case BFD_RELOC_X86_64_32S:
831 return howto_table + R_RELLONG;
832 case BFD_RELOC_16:
833 return howto_table + R_RELWORD;
834 case BFD_RELOC_16_PCREL:
835 return howto_table + R_PCRWORD;
836 case BFD_RELOC_8:
837 return howto_table + R_RELBYTE;
838 case BFD_RELOC_8_PCREL:
839 return howto_table + R_PCRBYTE;
840 #if defined(COFF_WITH_PE)
841 case BFD_RELOC_32_SECREL:
842 return howto_table + R_AMD64_SECREL;
843 case BFD_RELOC_16_SECIDX:
844 return howto_table + R_AMD64_SECTION;
845 #endif
846 default:
847 BFD_FAIL ();
848 return 0;
849 }
850 }
851
852 static reloc_howto_type *
853 coff_amd64_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED,
854 const char *r_name)
855 {
856 unsigned int i;
857
858 for (i = 0; i < NUM_HOWTOS; i++)
859 if (howto_table[i].name != NULL
860 && strcasecmp (howto_table[i].name, r_name) == 0)
861 return &howto_table[i];
862
863 return NULL;
864 }
865
866 #define coff_rtype_to_howto coff_amd64_rtype_to_howto
867
868 #ifdef TARGET_UNDERSCORE
869
870 /* If amd64 gcc uses underscores for symbol names, then it does not use
871 a leading dot for local labels, so if TARGET_UNDERSCORE is defined
872 we treat all symbols starting with L as local. */
873
874 static bool
875 coff_amd64_is_local_label_name (bfd *abfd, const char *name)
876 {
877 if (name[0] == 'L')
878 return true;
879
880 return _bfd_coff_is_local_label_name (abfd, name);
881 }
882
883 #define coff_bfd_is_local_label_name coff_amd64_is_local_label_name
884
885 #endif /* TARGET_UNDERSCORE */
886
887 #ifndef bfd_pe_print_pdata
888 #define bfd_pe_print_pdata NULL
889 #endif
890
891 #include "coffcode.h"
892
893 #ifdef PE
894 #define amd64coff_object_p pe_bfd_object_p
895 #else
896 #define amd64coff_object_p coff_object_p
897 #endif
898
899 const bfd_target
900 #ifdef TARGET_SYM
901 TARGET_SYM =
902 #else
903 x86_64_coff_vec =
904 #endif
905 {
906 #ifdef TARGET_NAME
907 TARGET_NAME,
908 #else
909 "coff-x86-64", /* Name. */
910 #endif
911 bfd_target_coff_flavour,
912 BFD_ENDIAN_LITTLE, /* Data byte order is little. */
913 BFD_ENDIAN_LITTLE, /* Header byte order is little. */
914
915 (HAS_RELOC | EXEC_P /* Object flags. */
916 | HAS_LINENO | HAS_DEBUG
917 | HAS_SYMS | HAS_LOCALS | WP_TEXT | D_PAGED | BFD_COMPRESS | BFD_DECOMPRESS),
918
919 (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC /* Section flags. */
920 #if defined(COFF_WITH_PE)
921 | SEC_LINK_ONCE | SEC_LINK_DUPLICATES | SEC_READONLY | SEC_DEBUGGING
922 #endif
923 | SEC_CODE | SEC_DATA | SEC_EXCLUDE ),
924
925 #ifdef TARGET_UNDERSCORE
926 TARGET_UNDERSCORE, /* Leading underscore. */
927 #else
928 0, /* Leading underscore. */
929 #endif
930 '/', /* Ar_pad_char. */
931 15, /* Ar_max_namelen. */
932 0, /* match priority. */
933 TARGET_KEEP_UNUSED_SECTION_SYMBOLS, /* keep unused section symbols. */
934
935 bfd_getl64, bfd_getl_signed_64, bfd_putl64,
936 bfd_getl32, bfd_getl_signed_32, bfd_putl32,
937 bfd_getl16, bfd_getl_signed_16, bfd_putl16, /* Data. */
938 bfd_getl64, bfd_getl_signed_64, bfd_putl64,
939 bfd_getl32, bfd_getl_signed_32, bfd_putl32,
940 bfd_getl16, bfd_getl_signed_16, bfd_putl16, /* Hdrs. */
941
942 /* Note that we allow an object file to be treated as a core file as well. */
943 { /* bfd_check_format. */
944 _bfd_dummy_target,
945 amd64coff_object_p,
946 bfd_generic_archive_p,
947 amd64coff_object_p
948 },
949 { /* bfd_set_format. */
950 _bfd_bool_bfd_false_error,
951 coff_mkobject,
952 _bfd_generic_mkarchive,
953 _bfd_bool_bfd_false_error
954 },
955 { /* bfd_write_contents. */
956 _bfd_bool_bfd_false_error,
957 coff_write_object_contents,
958 _bfd_write_archive_contents,
959 _bfd_bool_bfd_false_error
960 },
961
962 BFD_JUMP_TABLE_GENERIC (coff),
963 BFD_JUMP_TABLE_COPY (coff),
964 BFD_JUMP_TABLE_CORE (_bfd_nocore),
965 BFD_JUMP_TABLE_ARCHIVE (_bfd_archive_coff),
966 BFD_JUMP_TABLE_SYMBOLS (coff),
967 BFD_JUMP_TABLE_RELOCS (coff),
968 BFD_JUMP_TABLE_WRITE (coff),
969 BFD_JUMP_TABLE_LINK (coff),
970 BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic),
971
972 NULL,
973
974 COFF_SWAP_TABLE
975 };
976
977 /* Entry for big object files. */
978
979 #ifdef COFF_WITH_PE_BIGOBJ
980 const bfd_target
981 TARGET_SYM_BIG =
982 {
983 TARGET_NAME_BIG,
984 bfd_target_coff_flavour,
985 BFD_ENDIAN_LITTLE, /* Data byte order is little. */
986 BFD_ENDIAN_LITTLE, /* Header byte order is little. */
987
988 (HAS_RELOC | EXEC_P /* Object flags. */
989 | HAS_LINENO | HAS_DEBUG
990 | HAS_SYMS | HAS_LOCALS | WP_TEXT | D_PAGED | BFD_COMPRESS | BFD_DECOMPRESS),
991
992 (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC /* Section flags. */
993 #if defined(COFF_WITH_PE)
994 | SEC_LINK_ONCE | SEC_LINK_DUPLICATES | SEC_READONLY | SEC_DEBUGGING
995 #endif
996 | SEC_CODE | SEC_DATA | SEC_EXCLUDE ),
997
998 #ifdef TARGET_UNDERSCORE
999 TARGET_UNDERSCORE, /* Leading underscore. */
1000 #else
1001 0, /* Leading underscore. */
1002 #endif
1003 '/', /* Ar_pad_char. */
1004 15, /* Ar_max_namelen. */
1005 0, /* match priority. */
1006 TARGET_KEEP_UNUSED_SECTION_SYMBOLS, /* keep unused section symbols. */
1007
1008 bfd_getl64, bfd_getl_signed_64, bfd_putl64,
1009 bfd_getl32, bfd_getl_signed_32, bfd_putl32,
1010 bfd_getl16, bfd_getl_signed_16, bfd_putl16, /* Data. */
1011 bfd_getl64, bfd_getl_signed_64, bfd_putl64,
1012 bfd_getl32, bfd_getl_signed_32, bfd_putl32,
1013 bfd_getl16, bfd_getl_signed_16, bfd_putl16, /* Hdrs. */
1014
1015 /* Note that we allow an object file to be treated as a core file as well. */
1016 { /* bfd_check_format. */
1017 _bfd_dummy_target,
1018 amd64coff_object_p,
1019 bfd_generic_archive_p,
1020 amd64coff_object_p
1021 },
1022 { /* bfd_set_format. */
1023 _bfd_bool_bfd_false_error,
1024 coff_mkobject,
1025 _bfd_generic_mkarchive,
1026 _bfd_bool_bfd_false_error
1027 },
1028 { /* bfd_write_contents. */
1029 _bfd_bool_bfd_false_error,
1030 coff_write_object_contents,
1031 _bfd_write_archive_contents,
1032 _bfd_bool_bfd_false_error
1033 },
1034
1035 BFD_JUMP_TABLE_GENERIC (coff),
1036 BFD_JUMP_TABLE_COPY (coff),
1037 BFD_JUMP_TABLE_CORE (_bfd_nocore),
1038 BFD_JUMP_TABLE_ARCHIVE (_bfd_archive_coff),
1039 BFD_JUMP_TABLE_SYMBOLS (coff),
1040 BFD_JUMP_TABLE_RELOCS (coff),
1041 BFD_JUMP_TABLE_WRITE (coff),
1042 BFD_JUMP_TABLE_LINK (coff),
1043 BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic),
1044
1045 NULL,
1046
1047 &bigobj_swap_table
1048 };
1049 #endif