PR23652, Use symbols from debug bfd for _bfd_elf_find_function
[deliverable/binutils-gdb.git] / bfd / coff-x86_64.c
CommitLineData
99ad8390 1/* BFD back-end for AMD 64 COFF files.
82704155 2 Copyright (C) 2006-2019 Free Software Foundation, Inc.
99ad8390
NC
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
cd123cb7 8 the Free Software Foundation; either version 3 of the License, or
99ad8390
NC
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
cd123cb7
NC
18 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
19 MA 02110-1301, USA.
68ffbac6 20
99ad8390
NC
21 Written by Kai Tietz, OneVision Software GmbH&CoKg. */
22
23#ifndef COFF_WITH_pex64
24#define COFF_WITH_pex64
25#endif
26
e48570bb
DK
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
99ad8390 31#include "sysdep.h"
3db64b00 32#include "bfd.h"
99ad8390
NC
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"
e48570bb 39#endif
99ad8390
NC
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
bb294208
AM
55/* All users of this file have bfd_octets_per_byte (abfd, sec) == 1. */
56#define OCTETS_PER_BYTE(ABFD, SEC) 1
57
99ad8390
NC
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
67static bfd_reloc_status_type
68coff_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
c9f20320
L
144 if (diff != 0)
145 {
146 reloc_howto_type *howto = reloc_entry->howto;
bb294208
AM
147 bfd_size_type octets = (reloc_entry->address
148 * OCTETS_PER_BYTE (abfd, input_section));
149 unsigned char *addr = (unsigned char *) data + octets;
07d6d2b8 150
bb294208 151 if (!bfd_reloc_offset_in_range (howto, abfd, input_section, octets))
b23dc97f 152 return bfd_reloc_outofrange;
c9f20320
L
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:
a1165289 173 {
c9f20320
L
174 long x = bfd_get_32 (abfd, addr);
175 DOIT (x);
176 bfd_put_32 (abfd, (bfd_vma) x, addr);
a1165289 177 }
c9f20320 178 break;
a1165289 179
c9f20320 180 case 4:
99ad8390 181 {
ce9116fd 182 bfd_uint64_t x = bfd_get_64 (abfd, addr);
c9f20320 183 DOIT (x);
ce9116fd 184 bfd_put_64 (abfd, x, addr);
99ad8390 185 }
c9f20320
L
186 break;
187
188 default:
189 bfd_set_error (bfd_error_bad_value);
190 return bfd_reloc_notsupported;
191 }
192 }
99ad8390
NC
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
202static bfd_boolean
203in_reloc_p (bfd *abfd ATTRIBUTE_UNUSED, reloc_howto_type *howto)
204{
b706dc83
KT
205 return ! howto->pc_relative && howto->type != R_AMD64_IMAGEBASE
206 && howto->type != R_AMD64_SECREL;
99ad8390
NC
207}
208#endif /* COFF_WITH_PE */
209
210#ifndef PCRELOFFSET
211#define PCRELOFFSET TRUE
212#endif
213
214static 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 "R_X86_64_64", /* 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 "R_X86_64_32", /* 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 "rva32", /* 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 "R_X86_64_PC32", /* 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 "DISP32+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 "DISP32+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 "DISP32+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 "DISP32+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 "DISP32+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 "secrel32", /* 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,
07d6d2b8
AM
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 */
99ad8390
NC
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
36e9d67b
NC
461#define NUM_HOWTOS ARRAY_SIZE (howto_table)
462
99ad8390
NC
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 = \
36e9d67b 471 ((dst)->r_type < NUM_HOWTOS) \
99ad8390
NC
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; \
07d6d2b8 496 \
99ad8390
NC
497 if (ptr && bfd_asymbol_bfd (ptr) != abfd) \
498 coffsym = (obj_symbols (abfd) \
07d6d2b8 499 + (cache_ptr->sym_ptr_ptr - symbols)); \
99ad8390 500 else if (ptr) \
f4943d82 501 coffsym = coff_symbol_from (ptr); \
07d6d2b8 502 \
99ad8390
NC
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; \
36e9d67b
NC
511 if (ptr && reloc.r_type < NUM_HOWTOS \
512 && howto_table[reloc.r_type].pc_relative) \
99ad8390
NC
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
530static bfd_boolean
531coff_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{
0e1862bb 540 if (bfd_link_relocatable (info))
99ad8390
NC
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
552static reloc_howto_type *
553coff_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
36e9d67b 562 if (rel->r_type >= NUM_HOWTOS)
99ad8390
NC
563 {
564 bfd_set_error (bfd_error_bad_value);
565 return NULL;
566 }
99ad8390
NC
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;
b706dc83
KT
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;
406dba13 576 }
99ad8390
NC
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 {
384f7503
A
614#ifndef DONT_EXTEND_AMD64
615 if (rel->r_type == R_AMD64_PCRQUAD)
616 *addendp -= 8;
617 else
618#endif
619 *addendp -= 4;
99ad8390
NC
620
621 /* If the symbol is defined, then the generic code is going to
07d6d2b8
AM
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. */
99ad8390
NC
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
8a5dcf53
AM
639 if (h && (h->root.type == bfd_link_hash_defined
640 || h->root.type == bfd_link_hash_defweak))
99ad8390
NC
641 osect_vma = h->root.u.def.section->output_section->vma;
642 else
643 {
91d6fa6a 644 asection *s;
99ad8390
NC
645 int i;
646
647 /* Sigh, the only way to get the section to offset against
648 is to find it the hard way. */
91d6fa6a
NC
649 for (s = abfd->sections, i = 1; i < sym->n_scnum; i++)
650 s = s->next;
99ad8390 651
91d6fa6a 652 osect_vma = s->output_section->vma;
99ad8390
NC
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
157090f7 663#define coff_bfd_reloc_name_lookup coff_amd64_reloc_name_lookup
99ad8390
NC
664
665static reloc_howto_type *
666coff_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
157090f7
AM
704static reloc_howto_type *
705coff_amd64_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED,
706 const char *r_name)
707{
708 unsigned int i;
709
36e9d67b 710 for (i = 0; i < NUM_HOWTOS; i++)
157090f7
AM
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
99ad8390
NC
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
726static bfd_boolean
727coff_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
db1fe6e9
L
739#ifndef bfd_pe_print_pdata
740#define bfd_pe_print_pdata NULL
741#endif
2b5c217d 742
99ad8390
NC
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
751const bfd_target
752#ifdef TARGET_SYM
753 TARGET_SYM =
754#else
6d00b590 755 x86_64_coff_vec =
99ad8390
NC
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
d00dd7dc
AM
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),
99ad8390
NC
770
771 (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC /* Section flags. */
772#if defined(COFF_WITH_PE)
a29a8af8 773 | SEC_LINK_ONCE | SEC_LINK_DUPLICATES | SEC_READONLY | SEC_DEBUGGING
99ad8390 774#endif
a29a8af8 775 | SEC_CODE | SEC_DATA | SEC_EXCLUDE ),
99ad8390
NC
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. */
0aabe54e 784 0, /* match priority. */
99ad8390
NC
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. */
d00dd7dc
AM
794 { /* bfd_check_format. */
795 _bfd_dummy_target,
796 amd64coff_object_p,
797 bfd_generic_archive_p,
4b24dd1a 798 amd64coff_object_p
d00dd7dc
AM
799 },
800 { /* bfd_set_format. */
801 _bfd_bool_bfd_false_error,
802 coff_mkobject,
803 _bfd_generic_mkarchive,
4b24dd1a 804 _bfd_bool_bfd_false_error
d00dd7dc
AM
805 },
806 { /* bfd_write_contents. */
807 _bfd_bool_bfd_false_error,
808 coff_write_object_contents,
809 _bfd_write_archive_contents,
4b24dd1a 810 _bfd_bool_bfd_false_error
d00dd7dc 811 },
99ad8390
NC
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};
This page took 0.795939 seconds and 4 git commands to generate.