Automatic date update in version.in
[deliverable/binutils-gdb.git] / bfd / coff-x86_64.c
1 /* BFD back-end for AMD 64 COFF files.
2 Copyright (C) 2006-2020 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 #ifndef COFF_WITH_pex64
24 #define COFF_WITH_pex64
25 #endif
26
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
40
41 #define BADMAG(x) AMD64BADMAG(x)
42
43 #ifdef COFF_WITH_pex64
44 # undef AOUTSZ
45 # define AOUTSZ PEPAOUTSZ
46 # define PEAOUTHDR PEPAOUTHDR
47 #endif
48
49 #define COFF_DEFAULT_SECTION_ALIGNMENT_POWER (2)
50
51 /* The page size is a guess based on ELF. */
52
53 #define COFF_PAGE_SIZE 0x1000
54
55 /* All users of this file have bfd_octets_per_byte (abfd, sec) == 1. */
56 #define OCTETS_PER_BYTE(ABFD, SEC) 1
57
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. */
61
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. */
66
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)
75 {
76 symvalue diff;
77
78 #if !defined(COFF_WITH_PE)
79 if (output_bfd == NULL)
80 return bfd_reloc_continue;
81 #endif
82
83 if (bfd_is_com_section (symbol->section))
84 {
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
102 }
103 else
104 {
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)
111 {
112 reloc_howto_type *howto = reloc_entry->howto;
113
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;
127 }
128 else
129 #endif
130 diff = reloc_entry->addend;
131 }
132
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
140
141 #define DOIT(x) \
142 x = ((x & ~howto->dst_mask) | (((x & howto->src_mask) + diff) & howto->dst_mask))
143
144 if (diff != 0)
145 {
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;
150
151 if (!bfd_reloc_offset_in_range (howto, abfd, input_section, octets))
152 return bfd_reloc_outofrange;
153
154 switch (howto->size)
155 {
156 case 0:
157 {
158 char x = bfd_get_8 (abfd, addr);
159 DOIT (x);
160 bfd_put_8 (abfd, x, addr);
161 }
162 break;
163
164 case 1:
165 {
166 short x = bfd_get_16 (abfd, addr);
167 DOIT (x);
168 bfd_put_16 (abfd, (bfd_vma) x, addr);
169 }
170 break;
171
172 case 2:
173 {
174 long x = bfd_get_32 (abfd, addr);
175 DOIT (x);
176 bfd_put_32 (abfd, (bfd_vma) x, addr);
177 }
178 break;
179
180 case 4:
181 {
182 bfd_uint64_t x = bfd_get_64 (abfd, addr);
183 DOIT (x);
184 bfd_put_64 (abfd, x, addr);
185 }
186 break;
187
188 default:
189 bfd_set_error (bfd_error_bad_value);
190 return bfd_reloc_notsupported;
191 }
192 }
193
194 /* Now let bfd_perform_relocation finish everything up. */
195 return bfd_reloc_continue;
196 }
197
198 #if defined(COFF_WITH_PE)
199 /* Return TRUE if this relocation should appear in the output .reloc
200 section. */
201
202 static bfd_boolean
203 in_reloc_p (bfd *abfd ATTRIBUTE_UNUSED, reloc_howto_type *howto)
204 {
205 return ! howto->pc_relative && howto->type != R_AMD64_IMAGEBASE
206 && howto->type != R_AMD64_SECREL;
207 }
208 #endif /* COFF_WITH_PE */
209
210 #ifndef PCRELOFFSET
211 #define PCRELOFFSET TRUE
212 #endif
213
214 static reloc_howto_type howto_table[] =
215 {
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 */
271
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 */
459 };
460
461 #define NUM_HOWTOS ARRAY_SIZE (howto_table)
462
463 /* Turn a howto into a reloc nunmber */
464
465 #define SELECT_RELOC(x,howto) { x.r_type = howto->type; }
466 #define I386 1 /* Customize coffcode.h */
467 #define AMD64 1
468
469 #define RTYPE2HOWTO(cache_ptr, dst) \
470 ((cache_ptr)->howto = \
471 ((dst)->r_type < NUM_HOWTOS) \
472 ? howto_table + (dst)->r_type \
473 : NULL)
474
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
479
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. */
492
493 #define CALC_ADDEND(abfd, ptr, reloc, cache_ptr) \
494 { \
495 coff_symbol_type *coffsym = NULL; \
496 \
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); \
502 \
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; \
514 }
515
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. */
519
520 #if !defined(COFF_WITH_PE)
521
522 #define coff_relocate_section _bfd_coff_generic_relocate_section
523
524 #else /* COFF_WITH_PE */
525
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. */
529
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)
539 {
540 if (bfd_link_relocatable (info))
541 return TRUE;
542
543 return _bfd_coff_generic_relocate_section (output_bfd, info, input_bfd,input_section, contents,relocs, syms, sections);
544 }
545
546 #define coff_relocate_section coff_pe_amd64_relocate_section
547
548 #endif /* COFF_WITH_PE */
549
550 /* Convert an rtype to howto for the COFF backend linker. */
551
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)
559 {
560 reloc_howto_type *howto;
561
562 if (rel->r_type >= NUM_HOWTOS)
563 {
564 bfd_set_error (bfd_error_bad_value);
565 return NULL;
566 }
567 howto = howto_table + rel->r_type;
568
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)
573 {
574 *addendp -= (bfd_vma)(rel->r_type - R_AMD64_PCRLONG);
575 rel->r_type = R_AMD64_PCRLONG;
576 }
577 #endif
578
579 if (howto->pc_relative)
580 *addendp += sec->vma;
581
582 if (sym != NULL && sym->n_scnum == 0 && sym->n_value != 0)
583 {
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);
590
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
601 }
602
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
610
611 #if defined(COFF_WITH_PE)
612 if (howto->pc_relative)
613 {
614 #ifndef DONT_EXTEND_AMD64
615 if (rel->r_type == R_AMD64_PCRQUAD)
616 *addendp -= 8;
617 else
618 #endif
619 *addendp -= 4;
620
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;
629 }
630
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;
634
635 if (rel->r_type == R_AMD64_SECREL)
636 {
637 bfd_vma osect_vma;
638
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
643 {
644 asection *s;
645 int i;
646
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;
651
652 osect_vma = s->output_section->vma;
653 }
654
655 *addendp -= osect_vma;
656 }
657 #endif
658
659 return howto;
660 }
661
662 #define coff_bfd_reloc_type_lookup coff_amd64_reloc_type_lookup
663 #define coff_bfd_reloc_name_lookup coff_amd64_reloc_name_lookup
664
665 static reloc_howto_type *
666 coff_amd64_reloc_type_lookup (bfd *abfd ATTRIBUTE_UNUSED, bfd_reloc_code_real_type code)
667 {
668 switch (code)
669 {
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;
701 }
702 }
703
704 static reloc_howto_type *
705 coff_amd64_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED,
706 const char *r_name)
707 {
708 unsigned int i;
709
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];
714
715 return NULL;
716 }
717
718 #define coff_rtype_to_howto coff_amd64_rtype_to_howto
719
720 #ifdef TARGET_UNDERSCORE
721
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. */
725
726 static bfd_boolean
727 coff_amd64_is_local_label_name (bfd *abfd, const char *name)
728 {
729 if (name[0] == 'L')
730 return TRUE;
731
732 return _bfd_coff_is_local_label_name (abfd, name);
733 }
734
735 #define coff_bfd_is_local_label_name coff_amd64_is_local_label_name
736
737 #endif /* TARGET_UNDERSCORE */
738
739 #ifndef bfd_pe_print_pdata
740 #define bfd_pe_print_pdata NULL
741 #endif
742
743 #include "coffcode.h"
744
745 #ifdef PE
746 #define amd64coff_object_p pe_bfd_object_p
747 #else
748 #define amd64coff_object_p coff_object_p
749 #endif
750
751 const bfd_target
752 #ifdef TARGET_SYM
753 TARGET_SYM =
754 #else
755 x86_64_coff_vec =
756 #endif
757 {
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. */
766
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),
770
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 ),
776
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. */
785
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. */
792
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
799 },
800 { /* bfd_set_format. */
801 _bfd_bool_bfd_false_error,
802 coff_mkobject,
803 _bfd_generic_mkarchive,
804 _bfd_bool_bfd_false_error
805 },
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
811 },
812
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),
822
823 NULL,
824
825 COFF_SWAP_TABLE
826 };
827
828 /* Entry for big object files. */
829
830 #ifdef COFF_WITH_PE_BIGOBJ
831 const bfd_target
832 TARGET_SYM_BIG =
833 {
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. */
838
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),
842
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 ),
848
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. */
857
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. */
864
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
871 },
872 { /* bfd_set_format. */
873 _bfd_bool_bfd_false_error,
874 coff_mkobject,
875 _bfd_generic_mkarchive,
876 _bfd_bool_bfd_false_error
877 },
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
883 },
884
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),
894
895 NULL,
896
897 &bigobj_swap_table
898 };
899 #endif
This page took 0.050299 seconds and 4 git commands to generate.