gmp-utils: New API to simply use of GMP's integer/rational/float objects
[binutils-gdb.git] / bfd / coff-x86_64.c
blob3cad00a6361a4050d779293d8b992c7fbec2a142
1 /* BFD back-end for AMD 64 COFF files.
2 Copyright (C) 2006-2020 Free Software Foundation, Inc.
4 This file is part of BFD, the Binary File Descriptor library.
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 3 of the License, or
9 (at your option) any later version.
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
19 MA 02110-1301, USA.
21 Written by Kai Tietz, OneVision Software GmbH&CoKg. */
23 #ifndef COFF_WITH_pex64
24 #define COFF_WITH_pex64
25 #endif
27 /* Note we have to make sure not to include headers twice.
28 Not all headers are wrapped in #ifdef guards, so we define
29 PEI_HEADERS to prevent double including here. */
30 #ifndef PEI_HEADERS
31 #include "sysdep.h"
32 #include "bfd.h"
33 #include "libbfd.h"
34 #include "coff/x86_64.h"
35 #include "coff/internal.h"
36 #include "coff/pe.h"
37 #include "libcoff.h"
38 #include "libiberty.h"
39 #endif
41 #define BADMAG(x) AMD64BADMAG(x)
43 #ifdef COFF_WITH_pex64
44 # undef AOUTSZ
45 # define AOUTSZ PEPAOUTSZ
46 # define PEAOUTHDR PEPAOUTHDR
47 #endif
49 #define COFF_DEFAULT_SECTION_ALIGNMENT_POWER (2)
51 /* The page size is a guess based on ELF. */
53 #define COFF_PAGE_SIZE 0x1000
55 /* All users of this file have bfd_octets_per_byte (abfd, sec) == 1. */
56 #define OCTETS_PER_BYTE(ABFD, SEC) 1
58 /* For some reason when using AMD COFF the value stored in the .text
59 section for a reference to a common symbol is the value itself plus
60 any desired offset. Ian Taylor, Cygnus Support. */
62 /* If we are producing relocatable output, we need to do some
63 adjustments to the object file that are not done by the
64 bfd_perform_relocation function. This function is called by every
65 reloc type to make any required adjustments. */
67 static bfd_reloc_status_type
68 coff_amd64_reloc (bfd *abfd,
69 arelent *reloc_entry,
70 asymbol *symbol,
71 void * data,
72 asection *input_section ATTRIBUTE_UNUSED,
73 bfd *output_bfd,
74 char **error_message ATTRIBUTE_UNUSED)
76 symvalue diff;
78 #if !defined(COFF_WITH_PE)
79 if (output_bfd == NULL)
80 return bfd_reloc_continue;
81 #endif
83 if (bfd_is_com_section (symbol->section))
85 #if !defined(COFF_WITH_PE)
86 /* We are relocating a common symbol. The current value in the
87 object file is ORIG + OFFSET, where ORIG is the value of the
88 common symbol as seen by the object file when it was compiled
89 (this may be zero if the symbol was undefined) and OFFSET is
90 the offset into the common symbol (normally zero, but may be
91 non-zero when referring to a field in a common structure).
92 ORIG is the negative of reloc_entry->addend, which is set by
93 the CALC_ADDEND macro below. We want to replace the value in
94 the object file with NEW + OFFSET, where NEW is the value of
95 the common symbol which we are going to put in the final
96 object file. NEW is symbol->value. */
97 diff = symbol->value + reloc_entry->addend;
98 #else
99 /* In PE mode, we do not offset the common symbol. */
100 diff = reloc_entry->addend;
101 #endif
103 else
105 /* For some reason bfd_perform_relocation always effectively
106 ignores the addend for a COFF target when producing
107 relocatable output. This seems to be always wrong for 386
108 COFF, so we handle the addend here instead. */
109 #if defined(COFF_WITH_PE)
110 if (output_bfd == NULL)
112 reloc_howto_type *howto = reloc_entry->howto;
114 /* Although PC relative relocations are very similar between
115 PE and non-PE formats, but they are off by 1 << howto->size
116 bytes. For the external relocation, PE is very different
117 from others. See md_apply_fix3 () in gas/config/tc-amd64.c.
118 When we link PE and non-PE object files together to
119 generate a non-PE executable, we have to compensate it
120 here. */
121 if(howto->pc_relative && howto->pcrel_offset)
122 diff = -(1 << howto->size);
123 else if(symbol->flags & BSF_WEAK)
124 diff = reloc_entry->addend - symbol->value;
125 else
126 diff = -reloc_entry->addend;
128 else
129 #endif
130 diff = reloc_entry->addend;
133 #if defined(COFF_WITH_PE)
134 /* FIXME: How should this case be handled? */
135 if (reloc_entry->howto->type == R_AMD64_IMAGEBASE
136 && output_bfd != NULL
137 && bfd_get_flavour (output_bfd) == bfd_target_coff_flavour)
138 diff -= pe_data (output_bfd)->pe_opthdr.ImageBase;
139 #endif
141 #define DOIT(x) \
142 x = ((x & ~howto->dst_mask) | (((x & howto->src_mask) + diff) & howto->dst_mask))
144 if (diff != 0)
146 reloc_howto_type *howto = reloc_entry->howto;
147 bfd_size_type octets = (reloc_entry->address
148 * OCTETS_PER_BYTE (abfd, input_section));
149 unsigned char *addr = (unsigned char *) data + octets;
151 if (!bfd_reloc_offset_in_range (howto, abfd, input_section, octets))
152 return bfd_reloc_outofrange;
154 switch (howto->size)
156 case 0:
158 char x = bfd_get_8 (abfd, addr);
159 DOIT (x);
160 bfd_put_8 (abfd, x, addr);
162 break;
164 case 1:
166 short x = bfd_get_16 (abfd, addr);
167 DOIT (x);
168 bfd_put_16 (abfd, (bfd_vma) x, addr);
170 break;
172 case 2:
174 long x = bfd_get_32 (abfd, addr);
175 DOIT (x);
176 bfd_put_32 (abfd, (bfd_vma) x, addr);
178 break;
180 case 4:
182 bfd_uint64_t x = bfd_get_64 (abfd, addr);
183 DOIT (x);
184 bfd_put_64 (abfd, x, addr);
186 break;
188 default:
189 bfd_set_error (bfd_error_bad_value);
190 return bfd_reloc_notsupported;
194 /* Now let bfd_perform_relocation finish everything up. */
195 return bfd_reloc_continue;
198 #if defined(COFF_WITH_PE)
199 /* Return TRUE if this relocation should appear in the output .reloc
200 section. */
202 static bfd_boolean
203 in_reloc_p (bfd *abfd ATTRIBUTE_UNUSED, reloc_howto_type *howto)
205 return ! howto->pc_relative && howto->type != R_AMD64_IMAGEBASE
206 && howto->type != R_AMD64_SECREL;
208 #endif /* COFF_WITH_PE */
210 #ifndef PCRELOFFSET
211 #define PCRELOFFSET TRUE
212 #endif
214 static reloc_howto_type howto_table[] =
216 EMPTY_HOWTO (0),
217 HOWTO (R_AMD64_DIR64, /* type 1*/
218 0, /* rightshift */
219 4, /* size (0 = byte, 1 = short, 2 = long, 4 = long long) */
220 64, /* bitsize */
221 FALSE, /* pc_relative */
222 0, /* bitpos */
223 complain_overflow_bitfield, /* complain_on_overflow */
224 coff_amd64_reloc, /* special_function */
225 "IMAGE_REL_AMD64_ADDR64", /* name */
226 TRUE, /* partial_inplace */
227 0xffffffffffffffffll, /* src_mask */
228 0xffffffffffffffffll, /* dst_mask */
229 TRUE), /* pcrel_offset */
230 HOWTO (R_AMD64_DIR32, /* type 2 */
231 0, /* rightshift */
232 2, /* size (0 = byte, 1 = short, 2 = long) */
233 32, /* bitsize */
234 FALSE, /* pc_relative */
235 0, /* bitpos */
236 complain_overflow_bitfield, /* complain_on_overflow */
237 coff_amd64_reloc, /* special_function */
238 "IMAGE_REL_AMD64_ADDR32", /* name */
239 TRUE, /* partial_inplace */
240 0xffffffff, /* src_mask */
241 0xffffffff, /* dst_mask */
242 TRUE), /* pcrel_offset */
243 /* PE IMAGE_REL_AMD64_ADDR32NB relocation (3). */
244 HOWTO (R_AMD64_IMAGEBASE, /* type */
245 0, /* rightshift */
246 2, /* size (0 = byte, 1 = short, 2 = long) */
247 32, /* bitsize */
248 FALSE, /* pc_relative */
249 0, /* bitpos */
250 complain_overflow_bitfield, /* complain_on_overflow */
251 coff_amd64_reloc, /* special_function */
252 "IMAGE_REL_AMD64_ADDR32NB", /* name */
253 TRUE, /* partial_inplace */
254 0xffffffff, /* src_mask */
255 0xffffffff, /* dst_mask */
256 FALSE), /* pcrel_offset */
257 /* 32-bit longword PC relative relocation (4). */
258 HOWTO (R_AMD64_PCRLONG, /* type 4 */
259 0, /* rightshift */
260 2, /* size (0 = byte, 1 = short, 2 = long) */
261 32, /* bitsize */
262 TRUE, /* pc_relative */
263 0, /* bitpos */
264 complain_overflow_signed, /* complain_on_overflow */
265 coff_amd64_reloc, /* special_function */
266 "IMAGE_REL_AMD64_REL32", /* name */
267 TRUE, /* partial_inplace */
268 0xffffffff, /* src_mask */
269 0xffffffff, /* dst_mask */
270 PCRELOFFSET), /* pcrel_offset */
272 HOWTO (R_AMD64_PCRLONG_1, /* type 5 */
273 0, /* rightshift */
274 2, /* size (0 = byte, 1 = short, 2 = long) */
275 32, /* bitsize */
276 TRUE, /* pc_relative */
277 0, /* bitpos */
278 complain_overflow_signed, /* complain_on_overflow */
279 coff_amd64_reloc, /* special_function */
280 "IMAGE_REL_AMD64_REL32_1", /* name */
281 TRUE, /* partial_inplace */
282 0xffffffff, /* src_mask */
283 0xffffffff, /* dst_mask */
284 PCRELOFFSET), /* pcrel_offset */
285 HOWTO (R_AMD64_PCRLONG_2, /* type 6 */
286 0, /* rightshift */
287 2, /* size (0 = byte, 1 = short, 2 = long) */
288 32, /* bitsize */
289 TRUE, /* pc_relative */
290 0, /* bitpos */
291 complain_overflow_signed, /* complain_on_overflow */
292 coff_amd64_reloc, /* special_function */
293 "IMAGE_REL_AMD64_REL32_2", /* name */
294 TRUE, /* partial_inplace */
295 0xffffffff, /* src_mask */
296 0xffffffff, /* dst_mask */
297 PCRELOFFSET), /* pcrel_offset */
298 HOWTO (R_AMD64_PCRLONG_3, /* type 7 */
299 0, /* rightshift */
300 2, /* size (0 = byte, 1 = short, 2 = long) */
301 32, /* bitsize */
302 TRUE, /* pc_relative */
303 0, /* bitpos */
304 complain_overflow_signed, /* complain_on_overflow */
305 coff_amd64_reloc, /* special_function */
306 "IMAGE_REL_AMD64_REL32_3", /* name */
307 TRUE, /* partial_inplace */
308 0xffffffff, /* src_mask */
309 0xffffffff, /* dst_mask */
310 PCRELOFFSET), /* pcrel_offset */
311 HOWTO (R_AMD64_PCRLONG_4, /* type 8 */
312 0, /* rightshift */
313 2, /* size (0 = byte, 1 = short, 2 = long) */
314 32, /* bitsize */
315 TRUE, /* pc_relative */
316 0, /* bitpos */
317 complain_overflow_signed, /* complain_on_overflow */
318 coff_amd64_reloc, /* special_function */
319 "IMAGE_REL_AMD64_REL32_4", /* name */
320 TRUE, /* partial_inplace */
321 0xffffffff, /* src_mask */
322 0xffffffff, /* dst_mask */
323 PCRELOFFSET), /* pcrel_offset */
324 HOWTO (R_AMD64_PCRLONG_5, /* type 9 */
325 0, /* rightshift */
326 2, /* size (0 = byte, 1 = short, 2 = long) */
327 32, /* bitsize */
328 TRUE, /* pc_relative */
329 0, /* bitpos */
330 complain_overflow_signed, /* complain_on_overflow */
331 coff_amd64_reloc, /* special_function */
332 "IMAGE_REL_AMD64_REL32_5", /* name */
333 TRUE, /* partial_inplace */
334 0xffffffff, /* src_mask */
335 0xffffffff, /* dst_mask */
336 PCRELOFFSET), /* pcrel_offset */
337 EMPTY_HOWTO (10), /* R_AMD64_SECTION 10 */
338 #if defined(COFF_WITH_PE)
339 /* 32-bit longword section relative relocation (11). */
340 HOWTO (R_AMD64_SECREL, /* type */
341 0, /* rightshift */
342 2, /* size (0 = byte, 1 = short, 2 = long) */
343 32, /* bitsize */
344 FALSE, /* pc_relative */
345 0, /* bitpos */
346 complain_overflow_bitfield, /* complain_on_overflow */
347 coff_amd64_reloc, /* special_function */
348 "IMAGE_REL_AMD64_SECREL", /* name */
349 TRUE, /* partial_inplace */
350 0xffffffff, /* src_mask */
351 0xffffffff, /* dst_mask */
352 TRUE), /* pcrel_offset */
353 #else
354 EMPTY_HOWTO (11),
355 #endif
356 EMPTY_HOWTO (12),
357 EMPTY_HOWTO (13),
358 #ifndef DONT_EXTEND_AMD64
359 HOWTO (R_AMD64_PCRQUAD,
360 0, /* rightshift */
361 4, /* size (0 = byte, 1 = short, 2 = long) */
362 64, /* bitsize */
363 TRUE, /* pc_relative */
364 0, /* bitpos */
365 complain_overflow_signed, /* complain_on_overflow */
366 coff_amd64_reloc, /* special_function */
367 "R_X86_64_PC64", /* name */
368 TRUE, /* partial_inplace */
369 0xffffffffffffffffll, /* src_mask */
370 0xffffffffffffffffll, /* dst_mask */
371 PCRELOFFSET), /* pcrel_offset */
372 #else
373 EMPTY_HOWTO (14),
374 #endif
375 /* Byte relocation (15). */
376 HOWTO (R_RELBYTE, /* type */
377 0, /* rightshift */
378 0, /* size (0 = byte, 1 = short, 2 = long) */
379 8, /* bitsize */
380 FALSE, /* pc_relative */
381 0, /* bitpos */
382 complain_overflow_bitfield, /* complain_on_overflow */
383 coff_amd64_reloc, /* special_function */
384 "R_X86_64_8", /* name */
385 TRUE, /* partial_inplace */
386 0x000000ff, /* src_mask */
387 0x000000ff, /* dst_mask */
388 PCRELOFFSET), /* pcrel_offset */
389 /* 16-bit word relocation (16). */
390 HOWTO (R_RELWORD, /* type */
391 0, /* rightshift */
392 1, /* size (0 = byte, 1 = short, 2 = long) */
393 16, /* bitsize */
394 FALSE, /* pc_relative */
395 0, /* bitpos */
396 complain_overflow_bitfield, /* complain_on_overflow */
397 coff_amd64_reloc, /* special_function */
398 "R_X86_64_16", /* name */
399 TRUE, /* partial_inplace */
400 0x0000ffff, /* src_mask */
401 0x0000ffff, /* dst_mask */
402 PCRELOFFSET), /* pcrel_offset */
403 /* 32-bit longword relocation (17). */
404 HOWTO (R_RELLONG, /* type */
405 0, /* rightshift */
406 2, /* size (0 = byte, 1 = short, 2 = long) */
407 32, /* bitsize */
408 FALSE, /* pc_relative */
409 0, /* bitpos */
410 complain_overflow_bitfield, /* complain_on_overflow */
411 coff_amd64_reloc, /* special_function */
412 "R_X86_64_32S", /* name */
413 TRUE, /* partial_inplace */
414 0xffffffff, /* src_mask */
415 0xffffffff, /* dst_mask */
416 PCRELOFFSET), /* pcrel_offset */
417 /* Byte PC relative relocation (18). */
418 HOWTO (R_PCRBYTE, /* type */
419 0, /* rightshift */
420 0, /* size (0 = byte, 1 = short, 2 = long) */
421 8, /* bitsize */
422 TRUE, /* pc_relative */
423 0, /* bitpos */
424 complain_overflow_signed, /* complain_on_overflow */
425 coff_amd64_reloc, /* special_function */
426 "R_X86_64_PC8", /* name */
427 TRUE, /* partial_inplace */
428 0x000000ff, /* src_mask */
429 0x000000ff, /* dst_mask */
430 PCRELOFFSET), /* pcrel_offset */
431 /* 16-bit word PC relative relocation (19). */
432 HOWTO (R_PCRWORD, /* type */
433 0, /* rightshift */
434 1, /* size (0 = byte, 1 = short, 2 = long) */
435 16, /* bitsize */
436 TRUE, /* pc_relative */
437 0, /* bitpos */
438 complain_overflow_signed, /* complain_on_overflow */
439 coff_amd64_reloc, /* special_function */
440 "R_X86_64_PC16", /* name */
441 TRUE, /* partial_inplace */
442 0x0000ffff, /* src_mask */
443 0x0000ffff, /* dst_mask */
444 PCRELOFFSET), /* pcrel_offset */
445 /* 32-bit longword PC relative relocation (20). */
446 HOWTO (R_PCRLONG, /* type */
447 0, /* rightshift */
448 2, /* size (0 = byte, 1 = short, 2 = long) */
449 32, /* bitsize */
450 TRUE, /* pc_relative */
451 0, /* bitpos */
452 complain_overflow_signed, /* complain_on_overflow */
453 coff_amd64_reloc, /* special_function */
454 "R_X86_64_PC32", /* name */
455 TRUE, /* partial_inplace */
456 0xffffffff, /* src_mask */
457 0xffffffff, /* dst_mask */
458 PCRELOFFSET) /* pcrel_offset */
461 #define NUM_HOWTOS ARRAY_SIZE (howto_table)
463 /* Turn a howto into a reloc nunmber */
465 #define SELECT_RELOC(x,howto) { x.r_type = howto->type; }
466 #define I386 1 /* Customize coffcode.h */
467 #define AMD64 1
469 #define RTYPE2HOWTO(cache_ptr, dst) \
470 ((cache_ptr)->howto = \
471 ((dst)->r_type < NUM_HOWTOS) \
472 ? howto_table + (dst)->r_type \
473 : NULL)
475 /* For 386 COFF a STYP_NOLOAD | STYP_BSS section is part of a shared
476 library. On some other COFF targets STYP_BSS is normally
477 STYP_NOLOAD. */
478 #define BSS_NOLOAD_IS_SHARED_LIBRARY
480 /* Compute the addend of a reloc. If the reloc is to a common symbol,
481 the object file contains the value of the common symbol. By the
482 time this is called, the linker may be using a different symbol
483 from a different object file with a different value. Therefore, we
484 hack wildly to locate the original symbol from this file so that we
485 can make the correct adjustment. This macro sets coffsym to the
486 symbol from the original file, and uses it to set the addend value
487 correctly. If this is not a common symbol, the usual addend
488 calculation is done, except that an additional tweak is needed for
489 PC relative relocs.
490 FIXME: This macro refers to symbols and asect; these are from the
491 calling function, not the macro arguments. */
493 #define CALC_ADDEND(abfd, ptr, reloc, cache_ptr) \
495 coff_symbol_type *coffsym = NULL; \
497 if (ptr && bfd_asymbol_bfd (ptr) != abfd) \
498 coffsym = (obj_symbols (abfd) \
499 + (cache_ptr->sym_ptr_ptr - symbols)); \
500 else if (ptr) \
501 coffsym = coff_symbol_from (ptr); \
503 if (coffsym != NULL \
504 && coffsym->native->u.syment.n_scnum == 0) \
505 cache_ptr->addend = - coffsym->native->u.syment.n_value; \
506 else if (ptr && bfd_asymbol_bfd (ptr) == abfd \
507 && ptr->section != NULL) \
508 cache_ptr->addend = - (ptr->section->vma + ptr->value); \
509 else \
510 cache_ptr->addend = 0; \
511 if (ptr && reloc.r_type < NUM_HOWTOS \
512 && howto_table[reloc.r_type].pc_relative) \
513 cache_ptr->addend += asect->vma; \
516 /* We use the special COFF backend linker. For normal AMD64 COFF, we
517 can use the generic relocate_section routine. For PE, we need our
518 own routine. */
520 #if !defined(COFF_WITH_PE)
522 #define coff_relocate_section _bfd_coff_generic_relocate_section
524 #else /* COFF_WITH_PE */
526 /* The PE relocate section routine. The only difference between this
527 and the regular routine is that we don't want to do anything for a
528 relocatable link. */
530 static bfd_boolean
531 coff_pe_amd64_relocate_section (bfd *output_bfd,
532 struct bfd_link_info *info,
533 bfd *input_bfd,
534 asection *input_section,
535 bfd_byte *contents,
536 struct internal_reloc *relocs,
537 struct internal_syment *syms,
538 asection **sections)
540 if (bfd_link_relocatable (info))
541 return TRUE;
543 return _bfd_coff_generic_relocate_section (output_bfd, info, input_bfd,input_section, contents,relocs, syms, sections);
546 #define coff_relocate_section coff_pe_amd64_relocate_section
548 #endif /* COFF_WITH_PE */
550 /* Convert an rtype to howto for the COFF backend linker. */
552 static reloc_howto_type *
553 coff_amd64_rtype_to_howto (bfd *abfd ATTRIBUTE_UNUSED,
554 asection *sec,
555 struct internal_reloc *rel,
556 struct coff_link_hash_entry *h,
557 struct internal_syment *sym,
558 bfd_vma *addendp)
560 reloc_howto_type *howto;
562 if (rel->r_type >= NUM_HOWTOS)
564 bfd_set_error (bfd_error_bad_value);
565 return NULL;
567 howto = howto_table + rel->r_type;
569 #if defined(COFF_WITH_PE)
570 /* Cancel out code in _bfd_coff_generic_relocate_section. */
571 *addendp = 0;
572 if (rel->r_type >= R_AMD64_PCRLONG_1 && rel->r_type <= R_AMD64_PCRLONG_5)
574 *addendp -= (bfd_vma)(rel->r_type - R_AMD64_PCRLONG);
575 rel->r_type = R_AMD64_PCRLONG;
577 #endif
579 if (howto->pc_relative)
580 *addendp += sec->vma;
582 if (sym != NULL && sym->n_scnum == 0 && sym->n_value != 0)
584 /* This is a common symbol. The section contents include the
585 size (sym->n_value) as an addend. The relocate_section
586 function will be adding in the final value of the symbol. We
587 need to subtract out the current size in order to get the
588 correct result. */
589 BFD_ASSERT (h != NULL);
591 #if !defined(COFF_WITH_PE)
592 /* I think we *do* want to bypass this. If we don't, I have
593 seen some data parameters get the wrong relocation address.
594 If I link two versions with and without this section bypassed
595 and then do a binary comparison, the addresses which are
596 different can be looked up in the map. The case in which
597 this section has been bypassed has addresses which correspond
598 to values I can find in the map. */
599 *addendp -= sym->n_value;
600 #endif
603 #if !defined(COFF_WITH_PE)
604 /* If the output symbol is common (in which case this must be a
605 relocatable link), we need to add in the final size of the
606 common symbol. */
607 if (h != NULL && h->root.type == bfd_link_hash_common)
608 *addendp += h->root.u.c.size;
609 #endif
611 #if defined(COFF_WITH_PE)
612 if (howto->pc_relative)
614 #ifndef DONT_EXTEND_AMD64
615 if (rel->r_type == R_AMD64_PCRQUAD)
616 *addendp -= 8;
617 else
618 #endif
619 *addendp -= 4;
621 /* If the symbol is defined, then the generic code is going to
622 add back the symbol value in order to cancel out an
623 adjustment it made to the addend. However, we set the addend
624 to 0 at the start of this function. We need to adjust here,
625 to avoid the adjustment the generic code will make. FIXME:
626 This is getting a bit hackish. */
627 if (sym != NULL && sym->n_scnum != 0)
628 *addendp -= sym->n_value;
631 if (rel->r_type == R_AMD64_IMAGEBASE
632 && (bfd_get_flavour (sec->output_section->owner) == bfd_target_coff_flavour))
633 *addendp -= pe_data (sec->output_section->owner)->pe_opthdr.ImageBase;
635 if (rel->r_type == R_AMD64_SECREL)
637 bfd_vma osect_vma;
639 if (h && (h->root.type == bfd_link_hash_defined
640 || h->root.type == bfd_link_hash_defweak))
641 osect_vma = h->root.u.def.section->output_section->vma;
642 else
644 asection *s;
645 int i;
647 /* Sigh, the only way to get the section to offset against
648 is to find it the hard way. */
649 for (s = abfd->sections, i = 1; i < sym->n_scnum; i++)
650 s = s->next;
652 osect_vma = s->output_section->vma;
655 *addendp -= osect_vma;
657 #endif
659 return howto;
662 #define coff_bfd_reloc_type_lookup coff_amd64_reloc_type_lookup
663 #define coff_bfd_reloc_name_lookup coff_amd64_reloc_name_lookup
665 static reloc_howto_type *
666 coff_amd64_reloc_type_lookup (bfd *abfd ATTRIBUTE_UNUSED, bfd_reloc_code_real_type code)
668 switch (code)
670 case BFD_RELOC_RVA:
671 return howto_table + R_AMD64_IMAGEBASE;
672 case BFD_RELOC_32:
673 return howto_table + R_AMD64_DIR32;
674 case BFD_RELOC_64:
675 return howto_table + R_AMD64_DIR64;
676 case BFD_RELOC_64_PCREL:
677 #ifndef DONT_EXTEND_AMD64
678 return howto_table + R_AMD64_PCRQUAD;
679 #else
680 /* Fall through. */
681 #endif
682 case BFD_RELOC_32_PCREL:
683 return howto_table + R_AMD64_PCRLONG;
684 case BFD_RELOC_X86_64_32S:
685 return howto_table + R_RELLONG;
686 case BFD_RELOC_16:
687 return howto_table + R_RELWORD;
688 case BFD_RELOC_16_PCREL:
689 return howto_table + R_PCRWORD;
690 case BFD_RELOC_8:
691 return howto_table + R_RELBYTE;
692 case BFD_RELOC_8_PCREL:
693 return howto_table + R_PCRBYTE;
694 #if defined(COFF_WITH_PE)
695 case BFD_RELOC_32_SECREL:
696 return howto_table + R_AMD64_SECREL;
697 #endif
698 default:
699 BFD_FAIL ();
700 return 0;
704 static reloc_howto_type *
705 coff_amd64_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED,
706 const char *r_name)
708 unsigned int i;
710 for (i = 0; i < NUM_HOWTOS; i++)
711 if (howto_table[i].name != NULL
712 && strcasecmp (howto_table[i].name, r_name) == 0)
713 return &howto_table[i];
715 return NULL;
718 #define coff_rtype_to_howto coff_amd64_rtype_to_howto
720 #ifdef TARGET_UNDERSCORE
722 /* If amd64 gcc uses underscores for symbol names, then it does not use
723 a leading dot for local labels, so if TARGET_UNDERSCORE is defined
724 we treat all symbols starting with L as local. */
726 static bfd_boolean
727 coff_amd64_is_local_label_name (bfd *abfd, const char *name)
729 if (name[0] == 'L')
730 return TRUE;
732 return _bfd_coff_is_local_label_name (abfd, name);
735 #define coff_bfd_is_local_label_name coff_amd64_is_local_label_name
737 #endif /* TARGET_UNDERSCORE */
739 #ifndef bfd_pe_print_pdata
740 #define bfd_pe_print_pdata NULL
741 #endif
743 #include "coffcode.h"
745 #ifdef PE
746 #define amd64coff_object_p pe_bfd_object_p
747 #else
748 #define amd64coff_object_p coff_object_p
749 #endif
751 const bfd_target
752 #ifdef TARGET_SYM
753 TARGET_SYM =
754 #else
755 x86_64_coff_vec =
756 #endif
758 #ifdef TARGET_NAME
759 TARGET_NAME,
760 #else
761 "coff-x86-64", /* Name. */
762 #endif
763 bfd_target_coff_flavour,
764 BFD_ENDIAN_LITTLE, /* Data byte order is little. */
765 BFD_ENDIAN_LITTLE, /* Header byte order is little. */
767 (HAS_RELOC | EXEC_P /* Object flags. */
768 | HAS_LINENO | HAS_DEBUG
769 | HAS_SYMS | HAS_LOCALS | WP_TEXT | D_PAGED | BFD_COMPRESS | BFD_DECOMPRESS),
771 (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC /* Section flags. */
772 #if defined(COFF_WITH_PE)
773 | SEC_LINK_ONCE | SEC_LINK_DUPLICATES | SEC_READONLY | SEC_DEBUGGING
774 #endif
775 | SEC_CODE | SEC_DATA | SEC_EXCLUDE ),
777 #ifdef TARGET_UNDERSCORE
778 TARGET_UNDERSCORE, /* Leading underscore. */
779 #else
780 0, /* Leading underscore. */
781 #endif
782 '/', /* Ar_pad_char. */
783 15, /* Ar_max_namelen. */
784 0, /* match priority. */
786 bfd_getl64, bfd_getl_signed_64, bfd_putl64,
787 bfd_getl32, bfd_getl_signed_32, bfd_putl32,
788 bfd_getl16, bfd_getl_signed_16, bfd_putl16, /* Data. */
789 bfd_getl64, bfd_getl_signed_64, bfd_putl64,
790 bfd_getl32, bfd_getl_signed_32, bfd_putl32,
791 bfd_getl16, bfd_getl_signed_16, bfd_putl16, /* Hdrs. */
793 /* Note that we allow an object file to be treated as a core file as well. */
794 { /* bfd_check_format. */
795 _bfd_dummy_target,
796 amd64coff_object_p,
797 bfd_generic_archive_p,
798 amd64coff_object_p
800 { /* bfd_set_format. */
801 _bfd_bool_bfd_false_error,
802 coff_mkobject,
803 _bfd_generic_mkarchive,
804 _bfd_bool_bfd_false_error
806 { /* bfd_write_contents. */
807 _bfd_bool_bfd_false_error,
808 coff_write_object_contents,
809 _bfd_write_archive_contents,
810 _bfd_bool_bfd_false_error
813 BFD_JUMP_TABLE_GENERIC (coff),
814 BFD_JUMP_TABLE_COPY (coff),
815 BFD_JUMP_TABLE_CORE (_bfd_nocore),
816 BFD_JUMP_TABLE_ARCHIVE (_bfd_archive_coff),
817 BFD_JUMP_TABLE_SYMBOLS (coff),
818 BFD_JUMP_TABLE_RELOCS (coff),
819 BFD_JUMP_TABLE_WRITE (coff),
820 BFD_JUMP_TABLE_LINK (coff),
821 BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic),
823 NULL,
825 COFF_SWAP_TABLE
828 /* Entry for big object files. */
830 #ifdef COFF_WITH_PE_BIGOBJ
831 const bfd_target
832 TARGET_SYM_BIG =
834 TARGET_NAME_BIG,
835 bfd_target_coff_flavour,
836 BFD_ENDIAN_LITTLE, /* Data byte order is little. */
837 BFD_ENDIAN_LITTLE, /* Header byte order is little. */
839 (HAS_RELOC | EXEC_P /* Object flags. */
840 | HAS_LINENO | HAS_DEBUG
841 | HAS_SYMS | HAS_LOCALS | WP_TEXT | D_PAGED | BFD_COMPRESS | BFD_DECOMPRESS),
843 (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC /* Section flags. */
844 #if defined(COFF_WITH_PE)
845 | SEC_LINK_ONCE | SEC_LINK_DUPLICATES | SEC_READONLY | SEC_DEBUGGING
846 #endif
847 | SEC_CODE | SEC_DATA | SEC_EXCLUDE ),
849 #ifdef TARGET_UNDERSCORE
850 TARGET_UNDERSCORE, /* Leading underscore. */
851 #else
852 0, /* Leading underscore. */
853 #endif
854 '/', /* Ar_pad_char. */
855 15, /* Ar_max_namelen. */
856 0, /* match priority. */
858 bfd_getl64, bfd_getl_signed_64, bfd_putl64,
859 bfd_getl32, bfd_getl_signed_32, bfd_putl32,
860 bfd_getl16, bfd_getl_signed_16, bfd_putl16, /* Data. */
861 bfd_getl64, bfd_getl_signed_64, bfd_putl64,
862 bfd_getl32, bfd_getl_signed_32, bfd_putl32,
863 bfd_getl16, bfd_getl_signed_16, bfd_putl16, /* Hdrs. */
865 /* Note that we allow an object file to be treated as a core file as well. */
866 { /* bfd_check_format. */
867 _bfd_dummy_target,
868 amd64coff_object_p,
869 bfd_generic_archive_p,
870 amd64coff_object_p
872 { /* bfd_set_format. */
873 _bfd_bool_bfd_false_error,
874 coff_mkobject,
875 _bfd_generic_mkarchive,
876 _bfd_bool_bfd_false_error
878 { /* bfd_write_contents. */
879 _bfd_bool_bfd_false_error,
880 coff_write_object_contents,
881 _bfd_write_archive_contents,
882 _bfd_bool_bfd_false_error
885 BFD_JUMP_TABLE_GENERIC (coff),
886 BFD_JUMP_TABLE_COPY (coff),
887 BFD_JUMP_TABLE_CORE (_bfd_nocore),
888 BFD_JUMP_TABLE_ARCHIVE (_bfd_archive_coff),
889 BFD_JUMP_TABLE_SYMBOLS (coff),
890 BFD_JUMP_TABLE_RELOCS (coff),
891 BFD_JUMP_TABLE_WRITE (coff),
892 BFD_JUMP_TABLE_LINK (coff),
893 BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic),
895 NULL,
897 &bigobj_swap_table
899 #endif