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