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