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