Coverage Report

Created: 2026-09-14 08:07

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/binutils-gdb/bfd/coff-x86_64.c
Line
Count
Source
1
/* BFD back-end for AMD 64 COFF files.
2
   Copyright (C) 2006-2026 Free Software Foundation, Inc.
3
4
   This file is part of BFD, the Binary File Descriptor library.
5
6
   This program is free software; you can redistribute it and/or modify
7
   it under the terms of the GNU General Public License as published by
8
   the Free Software Foundation; either version 3 of the License, or
9
   (at your option) any later version.
10
11
   This program is distributed in the hope that it will be useful,
12
   but WITHOUT ANY WARRANTY; without even the implied warranty of
13
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
   GNU General Public License for more details.
15
16
   You should have received a copy of the GNU General Public License
17
   along with this program; if not, write to the Free Software
18
   Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
19
   MA 02110-1301, USA.
20
21
   Written by Kai Tietz, OneVision Software GmbH&CoKg.  */
22
23
#include "sysdep.h"
24
#include "bfd.h"
25
#include "libbfd.h"
26
#include "coff/x86_64.h"
27
#include "coff/internal.h"
28
#include "libcoff.h"
29
#include "libiberty.h"
30
31
646k
#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
544k
#define COFF_DEFAULT_SECTION_ALIGNMENT_POWER (2)
40
41
/* The page size is a guess based on ELF.  */
42
43
253
#define COFF_PAGE_SIZE 0x1000
44
45
/* All users of this file have bfd_octets_per_byte (abfd, sec) == 1.  */
46
0
#define OCTETS_PER_BYTE(ABFD, SEC) 1
47
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
57
static bfd_reloc_status_type
58
coff_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
0
{
66
0
  symvalue diff;
67
68
#if !defined (COFF_WITH_PE)
69
0
  if (output_bfd == NULL)
70
0
    return bfd_reloc_continue;
71
0
#endif
72
73
0
  if (bfd_is_com_section (symbol->section))
74
0
    {
75
#if !defined (COFF_WITH_PE)
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
0
    }
93
0
  else
94
0
    {
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.  */
99
#if defined (COFF_WITH_PE)
100
0
      if (output_bfd == NULL)
101
0
  {
102
0
    if (symbol->flags & BSF_WEAK)
103
0
      diff = reloc_entry->addend - symbol->value;
104
0
    else
105
0
      diff = -reloc_entry->addend;
106
0
  }
107
0
      else
108
0
#endif
109
0
  diff = reloc_entry->addend;
110
0
    }
111
112
#if defined (COFF_WITH_PE)
113
0
  if (output_bfd == NULL)
114
0
    {
115
      /* PC relative relocations are off by their size.  */
116
0
      if (reloc_entry->howto->pc_relative)
117
0
  diff -= bfd_get_reloc_size (reloc_entry->howto);
118
119
0
      if (reloc_entry->howto->type >= R_AMD64_PCRLONG_1
120
0
    && reloc_entry->howto->type <= R_AMD64_PCRLONG_5)
121
0
  diff -= reloc_entry->howto->type - R_AMD64_PCRLONG;
122
0
    }
123
124
0
  if (reloc_entry->howto->type == R_AMD64_IMAGEBASE
125
0
      && output_bfd == NULL)
126
0
    {
127
0
      bfd *obfd = input_section->output_section->owner;
128
0
      struct bfd_link_info *link_info;
129
0
      struct bfd_link_hash_entry *h;
130
0
      switch (bfd_get_flavour (obfd))
131
0
  {
132
0
  case bfd_target_coff_flavour:
133
0
    diff -= pe_data (obfd)->pe_opthdr.ImageBase;
134
0
    break;
135
0
  case bfd_target_elf_flavour:
136
    /* Subtract __ImageBase.  */
137
0
    h = NULL;
138
0
    link_info = _bfd_get_link_info (obfd);
139
0
    if (link_info != NULL)
140
0
      h = bfd_link_hash_lookup (link_info->hash, "__ImageBase",
141
0
              false, false, true);
142
0
    if (h == NULL
143
0
        || (h->type != bfd_link_hash_defined
144
0
      && h->type != bfd_link_hash_defweak))
145
0
      {
146
0
        *error_message
147
0
    = (char *) _("R_AMD64_IMAGEBASE with __ImageBase undefined");
148
0
        return bfd_reloc_dangerous;
149
0
      }
150
    /* ELF symbols in relocatable files are section relative,
151
       but in nonrelocatable files they are virtual addresses.  */
152
0
    diff -= (h->u.def.value
153
0
       + h->u.def.section->output_offset
154
0
       + h->u.def.section->output_section->vma);
155
0
    break;
156
0
  default:
157
0
    break;
158
0
  }
159
0
    }
160
0
#endif
161
162
0
#define DOIT(x) \
163
0
  x = ((x & ~howto->dst_mask) | (((x & howto->src_mask) + diff) & howto->dst_mask))
164
165
0
  if (diff != 0)
166
0
    {
167
0
      reloc_howto_type *howto = reloc_entry->howto;
168
0
      bfd_size_type octets = (reloc_entry->address
169
0
            * OCTETS_PER_BYTE (abfd, input_section));
170
0
      unsigned char *addr = (unsigned char *) data + octets;
171
172
0
      if (!bfd_reloc_offset_in_range (howto, abfd, input_section, octets))
173
0
  return bfd_reloc_outofrange;
174
175
0
      switch (bfd_get_reloc_size (howto))
176
0
  {
177
0
  case 1:
178
0
    {
179
0
      char x = bfd_get_8 (abfd, addr);
180
0
      DOIT (x);
181
0
      bfd_put_8 (abfd, x, addr);
182
0
    }
183
0
    break;
184
185
0
  case 2:
186
0
    {
187
0
      short x = bfd_get_16 (abfd, addr);
188
0
      DOIT (x);
189
0
      bfd_put_16 (abfd, (bfd_vma) x, addr);
190
0
    }
191
0
    break;
192
193
0
  case 4:
194
0
    {
195
0
      long x = bfd_get_32 (abfd, addr);
196
0
      DOIT (x);
197
0
      bfd_put_32 (abfd, (bfd_vma) x, addr);
198
0
    }
199
0
    break;
200
201
0
  case 8:
202
0
    {
203
0
      uint64_t x = bfd_get_64 (abfd, addr);
204
0
      DOIT (x);
205
0
      bfd_put_64 (abfd, x, addr);
206
0
    }
207
0
    break;
208
209
0
  default:
210
0
    bfd_set_error (bfd_error_bad_value);
211
0
    return bfd_reloc_notsupported;
212
0
  }
213
0
    }
214
215
  /* Now let bfd_perform_relocation finish everything up.  */
216
0
  return bfd_reloc_continue;
217
0
}
Unexecuted instantiation: pe-x86_64.c:coff_amd64_reloc
Unexecuted instantiation: pei-x86_64.c:coff_amd64_reloc
Unexecuted instantiation: coff-x86_64.c:coff_amd64_reloc
218
219
#if defined(COFF_WITH_PE)
220
/* Return TRUE if this relocation should appear in the output .reloc
221
   section.  */
222
223
static bool
224
in_reloc_p (bfd *abfd ATTRIBUTE_UNUSED, reloc_howto_type *howto)
225
0
{
226
0
  return ! howto->pc_relative
227
0
    && howto->type != R_AMD64_IMAGEBASE
228
0
    && howto->type != R_AMD64_SECREL
229
0
    && howto->type != R_AMD64_SECTION;
230
0
}
Unexecuted instantiation: pe-x86_64.c:in_reloc_p
Unexecuted instantiation: pei-x86_64.c:in_reloc_p
231
#endif /* COFF_WITH_PE */
232
233
#ifndef PCRELOFFSET
234
#define PCRELOFFSET true
235
#endif
236
237
static reloc_howto_type howto_table[] =
238
{
239
  EMPTY_HOWTO (0),
240
  HOWTO (R_AMD64_DIR64,   /* type  1*/
241
   0,     /* rightshift */
242
   8,     /* size */
243
   64,      /* bitsize */
244
   false,     /* pc_relative */
245
   0,     /* bitpos */
246
   complain_overflow_bitfield, /* complain_on_overflow */
247
   coff_amd64_reloc,  /* special_function */
248
   "IMAGE_REL_AMD64_ADDR64", /* name */
249
   true,      /* partial_inplace */
250
   0xffffffffffffffffll,  /* src_mask */
251
   0xffffffffffffffffll,  /* dst_mask */
252
   true),     /* pcrel_offset */
253
  HOWTO (R_AMD64_DIR32,   /* type 2 */
254
   0,     /* rightshift */
255
   4,     /* size */
256
   32,      /* bitsize */
257
   false,     /* pc_relative */
258
   0,     /* bitpos */
259
   complain_overflow_bitfield, /* complain_on_overflow */
260
   coff_amd64_reloc,  /* special_function */
261
   "IMAGE_REL_AMD64_ADDR32", /* name */
262
   true,      /* partial_inplace */
263
   0xffffffff,    /* src_mask */
264
   0xffffffff,    /* dst_mask */
265
   true),     /* pcrel_offset */
266
  /* PE IMAGE_REL_AMD64_ADDR32NB relocation (3).  */
267
  HOWTO (R_AMD64_IMAGEBASE, /* type */
268
   0,     /* rightshift */
269
   4,     /* size */
270
   32,      /* bitsize */
271
   false,     /* pc_relative */
272
   0,     /* bitpos */
273
   complain_overflow_bitfield, /* complain_on_overflow */
274
   coff_amd64_reloc,  /* special_function */
275
   "IMAGE_REL_AMD64_ADDR32NB", /* name */
276
   true,      /* partial_inplace */
277
   0xffffffff,    /* src_mask */
278
   0xffffffff,    /* dst_mask */
279
   false),    /* pcrel_offset */
280
  /* 32-bit longword PC relative relocation (4).  */
281
  HOWTO (R_AMD64_PCRLONG, /* type 4 */
282
   0,     /* rightshift */
283
   4,     /* size */
284
   32,      /* bitsize */
285
   true,      /* pc_relative */
286
   0,     /* bitpos */
287
   complain_overflow_signed, /* complain_on_overflow */
288
   coff_amd64_reloc,  /* special_function */
289
   "IMAGE_REL_AMD64_REL32", /* name */
290
   true,      /* partial_inplace */
291
   0xffffffff,    /* src_mask */
292
   0xffffffff,    /* dst_mask */
293
   PCRELOFFSET),    /* pcrel_offset */
294
295
 HOWTO (R_AMD64_PCRLONG_1,  /* type 5 */
296
   0,     /* rightshift */
297
   4,     /* size */
298
   32,      /* bitsize */
299
   true,      /* pc_relative */
300
   0,     /* bitpos */
301
   complain_overflow_signed, /* complain_on_overflow */
302
   coff_amd64_reloc,  /* special_function */
303
   "IMAGE_REL_AMD64_REL32_1", /* name */
304
   true,      /* partial_inplace */
305
   0xffffffff,    /* src_mask */
306
   0xffffffff,    /* dst_mask */
307
   PCRELOFFSET),    /* pcrel_offset */
308
 HOWTO (R_AMD64_PCRLONG_2,  /* type 6 */
309
   0,     /* rightshift */
310
   4,     /* size */
311
   32,      /* bitsize */
312
   true,      /* pc_relative */
313
   0,     /* bitpos */
314
   complain_overflow_signed, /* complain_on_overflow */
315
   coff_amd64_reloc,  /* special_function */
316
   "IMAGE_REL_AMD64_REL32_2", /* name */
317
   true,      /* partial_inplace */
318
   0xffffffff,    /* src_mask */
319
   0xffffffff,    /* dst_mask */
320
   PCRELOFFSET),    /* pcrel_offset */
321
 HOWTO (R_AMD64_PCRLONG_3,  /* type 7 */
322
   0,     /* rightshift */
323
   4,     /* size */
324
   32,      /* bitsize */
325
   true,      /* pc_relative */
326
   0,     /* bitpos */
327
   complain_overflow_signed, /* complain_on_overflow */
328
   coff_amd64_reloc,  /* special_function */
329
   "IMAGE_REL_AMD64_REL32_3", /* name */
330
   true,      /* partial_inplace */
331
   0xffffffff,    /* src_mask */
332
   0xffffffff,    /* dst_mask */
333
   PCRELOFFSET),    /* pcrel_offset */
334
 HOWTO (R_AMD64_PCRLONG_4,  /* type 8 */
335
   0,     /* rightshift */
336
   4,     /* size */
337
   32,      /* bitsize */
338
   true,      /* pc_relative */
339
   0,     /* bitpos */
340
   complain_overflow_signed, /* complain_on_overflow */
341
   coff_amd64_reloc,  /* special_function */
342
   "IMAGE_REL_AMD64_REL32_4", /* name */
343
   true,      /* partial_inplace */
344
   0xffffffff,    /* src_mask */
345
   0xffffffff,    /* dst_mask */
346
   PCRELOFFSET),    /* pcrel_offset */
347
 HOWTO (R_AMD64_PCRLONG_5,  /* type 9 */
348
   0,     /* rightshift */
349
   4,     /* size */
350
   32,      /* bitsize */
351
   true,      /* pc_relative */
352
   0,     /* bitpos */
353
   complain_overflow_signed, /* complain_on_overflow */
354
   coff_amd64_reloc,  /* special_function */
355
   "IMAGE_REL_AMD64_REL32_5", /* name */
356
   true,      /* partial_inplace */
357
   0xffffffff,    /* src_mask */
358
   0xffffffff,    /* dst_mask */
359
   PCRELOFFSET),    /* pcrel_offset */
360
#if defined(COFF_WITH_PE)
361
  /* 16-bit word section relocation (10).  */
362
  HOWTO (R_AMD64_SECTION, /* type */
363
   0,     /* rightshift */
364
   2,     /* size */
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),
375
  /* 32-bit longword section relative relocation (11).  */
376
  HOWTO (R_AMD64_SECREL,  /* type */
377
   0,     /* rightshift */
378
   4,     /* size */
379
   32,      /* bitsize */
380
   false,     /* pc_relative */
381
   0,     /* bitpos */
382
   complain_overflow_bitfield, /* complain_on_overflow */
383
   coff_amd64_reloc,  /* special_function */
384
   "IMAGE_REL_AMD64_SECREL", /* name */
385
   true,      /* partial_inplace */
386
   0xffffffff,    /* src_mask */
387
   0xffffffff,    /* dst_mask */
388
   true),     /* pcrel_offset */
389
#else
390
  EMPTY_HOWTO (10),
391
  EMPTY_HOWTO (11),
392
#endif
393
  EMPTY_HOWTO (12),
394
  EMPTY_HOWTO (13),
395
#ifndef DONT_EXTEND_AMD64
396
  HOWTO (R_AMD64_PCRQUAD,
397
   0,     /* rightshift */
398
   8,     /* size */
399
   64,      /* bitsize */
400
   true,      /* pc_relative */
401
   0,     /* bitpos */
402
   complain_overflow_signed, /* complain_on_overflow */
403
   coff_amd64_reloc,  /* special_function */
404
   "R_X86_64_PC64", /* name */
405
   true,      /* partial_inplace */
406
   0xffffffffffffffffll,  /* src_mask */
407
   0xffffffffffffffffll,  /* dst_mask */
408
   PCRELOFFSET),     /* pcrel_offset */
409
#else
410
  EMPTY_HOWTO (14),
411
#endif
412
  /* Byte relocation (15).  */
413
  HOWTO (R_RELBYTE,   /* type */
414
   0,     /* rightshift */
415
   1,     /* size */
416
   8,     /* bitsize */
417
   false,     /* pc_relative */
418
   0,     /* bitpos */
419
   complain_overflow_bitfield, /* complain_on_overflow */
420
   coff_amd64_reloc,  /* special_function */
421
   "R_X86_64_8",    /* name */
422
   true,      /* partial_inplace */
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 */
429
   2,     /* size */
430
   16,      /* bitsize */
431
   false,     /* pc_relative */
432
   0,     /* bitpos */
433
   complain_overflow_bitfield, /* complain_on_overflow */
434
   coff_amd64_reloc,  /* special_function */
435
   "R_X86_64_16",   /* name */
436
   true,      /* partial_inplace */
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 */
443
   4,     /* size */
444
   32,      /* bitsize */
445
   false,     /* pc_relative */
446
   0,     /* bitpos */
447
   complain_overflow_bitfield, /* complain_on_overflow */
448
   coff_amd64_reloc,  /* special_function */
449
   "R_X86_64_32S",  /* name */
450
   true,      /* partial_inplace */
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 */
457
   1,     /* size */
458
   8,     /* bitsize */
459
   true,      /* pc_relative */
460
   0,     /* bitpos */
461
   complain_overflow_signed, /* complain_on_overflow */
462
   coff_amd64_reloc,  /* special_function */
463
   "R_X86_64_PC8",  /* name */
464
   true,      /* partial_inplace */
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 */
471
   2,     /* size */
472
   16,      /* bitsize */
473
   true,      /* pc_relative */
474
   0,     /* bitpos */
475
   complain_overflow_signed, /* complain_on_overflow */
476
   coff_amd64_reloc,  /* special_function */
477
   "R_X86_64_PC16", /* name */
478
   true,      /* partial_inplace */
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 */
485
   4,     /* size */
486
   32,      /* bitsize */
487
   true,      /* pc_relative */
488
   0,     /* bitpos */
489
   complain_overflow_signed, /* complain_on_overflow */
490
   coff_amd64_reloc,  /* special_function */
491
   "R_X86_64_PC32", /* name */
492
   true,      /* partial_inplace */
493
   0xffffffff,    /* src_mask */
494
   0xffffffff,    /* dst_mask */
495
   PCRELOFFSET)   /* pcrel_offset */
496
};
497
498
2.00k
#define NUM_HOWTOS ARRAY_SIZE (howto_table)
499
500
/* Turn a howto into a reloc  nunmber */
501
502
12
#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
1.64k
  ((cache_ptr)->howto =       \
508
1.64k
   ((dst)->r_type < NUM_HOWTOS)     \
509
1.64k
    ? howto_table + (dst)->r_type    \
510
1.64k
    : 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
1.64k
  {               \
532
1.64k
    coff_symbol_type *coffsym = NULL;       \
533
1.64k
                \
534
1.64k
    if (ptr && bfd_asymbol_bfd (ptr) != abfd)     \
535
1.64k
      coffsym = (obj_symbols (abfd)       \
536
0
     + (cache_ptr->sym_ptr_ptr - symbols));   \
537
1.64k
    else if (ptr)           \
538
1.64k
      coffsym = coff_symbol_from (ptr);       \
539
1.64k
                \
540
1.64k
    if (coffsym != NULL            \
541
1.64k
  && coffsym->native->u.syment.n_scnum == 0)   \
542
1.64k
      cache_ptr->addend = - coffsym->native->u.syment.n_value; \
543
1.64k
    else if (ptr && bfd_asymbol_bfd (ptr) == abfd    \
544
1.55k
       && ptr->section != NULL)       \
545
1.55k
      cache_ptr->addend = - (ptr->section->vma      \
546
275
           + COFF_PE_ADDEND_BIAS (ptr)); \
547
1.55k
    else              \
548
1.55k
      cache_ptr->addend = 0;         \
549
1.64k
    if (ptr && reloc.r_type < NUM_HOWTOS      \
550
1.64k
  && howto_table[reloc.r_type].pc_relative)   \
551
1.64k
      cache_ptr->addend += asect->vma;       \
552
1.64k
  }
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
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.  */
567
568
static bool
569
coff_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
0
{
578
0
  struct internal_reloc *rel;
579
0
  struct internal_reloc *relend;
580
581
0
  if (bfd_link_relocatable (info))
582
0
    return true;
583
584
0
  rel = relocs;
585
0
  relend = rel + input_section->reloc_count;
586
587
0
  for (; rel < relend; rel++)
588
0
    {
589
0
      long symndx;
590
0
      struct coff_link_hash_entry *h;
591
0
      asection *sec, *s;
592
0
      uint16_t idx = 0, i = 1;
593
594
0
      if (rel->r_type != R_AMD64_SECTION)
595
0
  continue;
596
597
      /* Make sure that _bfd_coff_generic_relocate_section won't parse
598
         this reloc after us.  */
599
0
      rel->r_ignore = 1;
600
601
0
      symndx = rel->r_symndx;
602
603
0
      if (symndx < 0
604
0
    || (unsigned long) symndx >= obj_raw_syment_count (input_bfd))
605
0
  continue;
606
607
0
      h = obj_coff_sym_hashes (input_bfd)[symndx];
608
609
0
      if (h == NULL)
610
0
  sec = sections[symndx];
611
0
      else
612
0
  {
613
0
    if (h->root.type == bfd_link_hash_defined
614
0
        || h->root.type == bfd_link_hash_defweak)
615
0
      {
616
        /* Defined weak symbols are a GNU extension.  */
617
0
        sec = h->root.u.def.section;
618
0
      }
619
0
    else
620
0
      {
621
0
        sec = NULL;
622
0
      }
623
0
  }
624
625
0
      if (!sec)
626
0
  continue;
627
628
0
      if (bfd_is_abs_section (sec))
629
0
  continue;
630
631
0
      if (discarded_section (sec))
632
0
  continue;
633
634
0
      s = output_bfd->sections;
635
0
      while (s)
636
0
  {
637
0
    if (s == sec->output_section)
638
0
      {
639
0
        idx = i;
640
0
        break;
641
0
      }
642
643
0
    i++;
644
0
    s = s->next;
645
0
  }
646
647
0
      bfd_putl16 (idx, contents + rel->r_vaddr - input_section->vma);
648
0
    }
649
650
0
  return _bfd_coff_generic_relocate_section (output_bfd, info, input_bfd,
651
0
               input_section, contents,
652
0
               relocs, syms, sections);
653
0
}
Unexecuted instantiation: pe-x86_64.c:coff_pe_amd64_relocate_section
Unexecuted instantiation: pei-x86_64.c:coff_pe_amd64_relocate_section
654
655
#define coff_relocate_section coff_pe_amd64_relocate_section
656
657
static hashval_t
658
htab_hash_section_index (const void * entry)
659
0
{
660
0
  const struct bfd_section * sec = entry;
661
0
  return sec->index;
662
0
}
Unexecuted instantiation: pe-x86_64.c:htab_hash_section_index
Unexecuted instantiation: pei-x86_64.c:htab_hash_section_index
663
664
static int
665
htab_eq_section_index (const void * e1, const void * e2)
666
0
{
667
0
  const struct bfd_section * sec1 = e1;
668
0
  const struct bfd_section * sec2 = e2;
669
0
  return sec1->index == sec2->index;
670
0
}
Unexecuted instantiation: pe-x86_64.c:htab_eq_section_index
Unexecuted instantiation: pei-x86_64.c:htab_eq_section_index
671
#endif /* COFF_WITH_PE */
672
673
/* Convert an rtype to howto for the COFF backend linker.  */
674
675
static reloc_howto_type *
676
coff_amd64_rtype_to_howto (bfd *abfd ATTRIBUTE_UNUSED,
677
         asection *sec,
678
         struct internal_reloc *rel,
679
         struct coff_link_hash_entry *h,
680
         struct internal_syment *sym,
681
         bfd_vma *addendp)
682
0
{
683
0
  reloc_howto_type *howto;
684
685
0
  if (rel->r_type >= NUM_HOWTOS)
686
0
    {
687
0
      bfd_set_error (bfd_error_bad_value);
688
0
      return NULL;
689
0
    }
690
0
  howto = howto_table + rel->r_type;
691
692
#if defined(COFF_WITH_PE)
693
  /* Cancel out code in _bfd_coff_generic_relocate_section.  */
694
  *addendp = 0;
695
0
  if (rel->r_type >= R_AMD64_PCRLONG_1 && rel->r_type <= R_AMD64_PCRLONG_5)
696
0
    {
697
0
      *addendp -= (bfd_vma)(rel->r_type - R_AMD64_PCRLONG);
698
0
      rel->r_type = R_AMD64_PCRLONG;
699
0
    }
700
#endif
701
702
0
  if (howto->pc_relative)
703
0
    *addendp += sec->vma;
704
705
0
  if (sym != NULL && sym->n_scnum == 0 && sym->n_value != 0)
706
0
    {
707
      /* This is a common symbol.  The section contents include the
708
   size (sym->n_value) as an addend.  The relocate_section
709
   function will be adding in the final value of the symbol.  We
710
   need to subtract out the current size in order to get the
711
   correct result.  */
712
0
      BFD_ASSERT (h != NULL);
713
714
#if !defined(COFF_WITH_PE)
715
      /* I think we *do* want to bypass this.  If we don't, I have
716
   seen some data parameters get the wrong relocation address.
717
   If I link two versions with and without this section bypassed
718
   and then do a binary comparison, the addresses which are
719
   different can be looked up in the map.  The case in which
720
   this section has been bypassed has addresses which correspond
721
   to values I can find in the map.  */
722
      *addendp -= sym->n_value;
723
#endif
724
0
    }
725
726
#if !defined(COFF_WITH_PE)
727
  /* If the output symbol is common (in which case this must be a
728
     relocatable link), we need to add in the final size of the
729
     common symbol.  */
730
0
  if (h != NULL && h->root.type == bfd_link_hash_common)
731
0
    *addendp += h->root.u.c.size;
732
#endif
733
734
#if defined(COFF_WITH_PE)
735
0
  if (howto->pc_relative)
736
0
    {
737
0
#ifndef DONT_EXTEND_AMD64
738
0
      if (rel->r_type == R_AMD64_PCRQUAD)
739
0
  *addendp -= 8;
740
0
      else
741
0
#endif
742
0
  *addendp -= 4;
743
744
      /* If the symbol is defined, then the generic code is going to
745
   add back the symbol value in order to cancel out an
746
   adjustment it made to the addend.  However, we set the addend
747
   to 0 at the start of this function.  We need to adjust here,
748
   to avoid the adjustment the generic code will make.  FIXME:
749
   This is getting a bit hackish.  */
750
0
      if (sym != NULL && sym->n_scnum != 0)
751
0
  *addendp -= sym->n_value;
752
0
    }
753
754
0
  if (rel->r_type == R_AMD64_IMAGEBASE
755
0
      && (bfd_get_flavour (sec->output_section->owner) == bfd_target_coff_flavour))
756
0
    *addendp -= pe_data (sec->output_section->owner)->pe_opthdr.ImageBase;
757
758
0
  if (rel->r_type == R_AMD64_SECREL)
759
0
    {
760
0
      bfd_vma osect_vma = 0;
761
762
0
      if (h != NULL
763
0
    && (h->root.type == bfd_link_hash_defined
764
0
        || h->root.type == bfd_link_hash_defweak))
765
0
  osect_vma = h->root.u.def.section->output_section->vma;
766
0
      else
767
0
  {
768
0
    htab_t table = coff_data (abfd)->section_by_index;
769
0
    asection *s;
770
771
0
    if (!table)
772
0
      {
773
0
        table = htab_create (10, htab_hash_section_index,
774
0
           htab_eq_section_index, NULL);
775
0
        if (table == NULL)
776
0
    return NULL;
777
0
        coff_data (abfd)->section_by_index = table;
778
0
      }
779
780
0
    if (htab_elements (table) == 0)
781
0
      {
782
0
        for (s = abfd->sections; s != NULL; s = s->next)
783
0
    {
784
0
      void ** slot = htab_find_slot (table, s, INSERT);
785
786
0
      if (slot != NULL)
787
0
        *slot = s;
788
0
    }
789
0
      }
790
791
0
    struct bfd_section needle;
792
793
0
    needle.index = sym->n_scnum - 1;
794
0
    s = htab_find (table, &needle);
795
0
    if (s != NULL)
796
0
      osect_vma = s->output_section->vma;
797
0
  }
798
799
0
      *addendp -= osect_vma;
800
0
    }
801
0
#endif
802
803
0
  return howto;
804
0
}
Unexecuted instantiation: pe-x86_64.c:coff_amd64_rtype_to_howto
Unexecuted instantiation: pei-x86_64.c:coff_amd64_rtype_to_howto
Unexecuted instantiation: coff-x86_64.c:coff_amd64_rtype_to_howto
805
806
#define coff_bfd_reloc_type_lookup coff_amd64_reloc_type_lookup
807
#define coff_bfd_reloc_name_lookup coff_amd64_reloc_name_lookup
808
809
static reloc_howto_type *
810
coff_amd64_reloc_type_lookup (bfd *abfd ATTRIBUTE_UNUSED, bfd_reloc_code_real_type code)
811
230
{
812
230
  switch (code)
813
230
    {
814
186
    case BFD_RELOC_RVA:
815
186
      return howto_table + R_AMD64_IMAGEBASE;
816
0
    case BFD_RELOC_32:
817
0
      return howto_table + R_AMD64_DIR32;
818
0
    case BFD_RELOC_64:
819
0
      return howto_table + R_AMD64_DIR64;
820
0
    case BFD_RELOC_64_PCREL:
821
0
#ifndef DONT_EXTEND_AMD64
822
0
      return howto_table + R_AMD64_PCRQUAD;
823
#else
824
      /* Fall through.  */
825
#endif
826
44
    case BFD_RELOC_32_PCREL:
827
44
      return howto_table + R_AMD64_PCRLONG;
828
0
    case BFD_RELOC_X86_64_32S:
829
0
      return howto_table + R_RELLONG;
830
0
    case BFD_RELOC_16:
831
0
      return howto_table + R_RELWORD;
832
0
    case BFD_RELOC_16_PCREL:
833
0
      return howto_table + R_PCRWORD;
834
0
    case BFD_RELOC_8:
835
0
      return howto_table + R_RELBYTE;
836
0
    case BFD_RELOC_8_PCREL:
837
0
      return howto_table + R_PCRBYTE;
838
#if defined(COFF_WITH_PE)
839
0
    case BFD_RELOC_32_SECREL:
840
0
      return howto_table + R_AMD64_SECREL;
841
0
    case BFD_RELOC_16_SECIDX:
842
0
      return howto_table + R_AMD64_SECTION;
843
0
#endif
844
0
    default:
845
0
      BFD_FAIL ();
846
0
      return 0;
847
230
    }
848
230
}
Unexecuted instantiation: pe-x86_64.c:coff_amd64_reloc_type_lookup
pei-x86_64.c:coff_amd64_reloc_type_lookup
Line
Count
Source
811
230
{
812
230
  switch (code)
813
230
    {
814
186
    case BFD_RELOC_RVA:
815
186
      return howto_table + R_AMD64_IMAGEBASE;
816
0
    case BFD_RELOC_32:
817
0
      return howto_table + R_AMD64_DIR32;
818
0
    case BFD_RELOC_64:
819
0
      return howto_table + R_AMD64_DIR64;
820
0
    case BFD_RELOC_64_PCREL:
821
0
#ifndef DONT_EXTEND_AMD64
822
0
      return howto_table + R_AMD64_PCRQUAD;
823
#else
824
      /* Fall through.  */
825
#endif
826
44
    case BFD_RELOC_32_PCREL:
827
44
      return howto_table + R_AMD64_PCRLONG;
828
0
    case BFD_RELOC_X86_64_32S:
829
0
      return howto_table + R_RELLONG;
830
0
    case BFD_RELOC_16:
831
0
      return howto_table + R_RELWORD;
832
0
    case BFD_RELOC_16_PCREL:
833
0
      return howto_table + R_PCRWORD;
834
0
    case BFD_RELOC_8:
835
0
      return howto_table + R_RELBYTE;
836
0
    case BFD_RELOC_8_PCREL:
837
0
      return howto_table + R_PCRBYTE;
838
0
#if defined(COFF_WITH_PE)
839
0
    case BFD_RELOC_32_SECREL:
840
0
      return howto_table + R_AMD64_SECREL;
841
0
    case BFD_RELOC_16_SECIDX:
842
0
      return howto_table + R_AMD64_SECTION;
843
0
#endif
844
0
    default:
845
0
      BFD_FAIL ();
846
0
      return 0;
847
230
    }
848
230
}
Unexecuted instantiation: coff-x86_64.c:coff_amd64_reloc_type_lookup
849
850
static reloc_howto_type *
851
coff_amd64_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED,
852
            const char *r_name)
853
0
{
854
0
  unsigned int i;
855
856
0
  for (i = 0; i < NUM_HOWTOS; i++)
857
0
    if (howto_table[i].name != NULL
858
0
  && strcasecmp (howto_table[i].name, r_name) == 0)
859
0
      return &howto_table[i];
860
861
0
  return NULL;
862
0
}
Unexecuted instantiation: pe-x86_64.c:coff_amd64_reloc_name_lookup
Unexecuted instantiation: pei-x86_64.c:coff_amd64_reloc_name_lookup
Unexecuted instantiation: coff-x86_64.c:coff_amd64_reloc_name_lookup
863
864
#define coff_rtype_to_howto coff_amd64_rtype_to_howto
865
866
#ifdef TARGET_UNDERSCORE
867
868
/* If amd64 gcc uses underscores for symbol names, then it does not use
869
   a leading dot for local labels, so if TARGET_UNDERSCORE is defined
870
   we treat all symbols starting with L as local.  */
871
872
static bool
873
coff_amd64_is_local_label_name (bfd *abfd, const char *name)
874
0
{
875
0
  if (name[0] == 'L')
876
0
    return true;
877
878
0
  return _bfd_coff_is_local_label_name (abfd, name);
879
0
}
Unexecuted instantiation: pe-x86_64.c:coff_amd64_is_local_label_name
Unexecuted instantiation: pei-x86_64.c:coff_amd64_is_local_label_name
880
881
#define coff_bfd_is_local_label_name coff_amd64_is_local_label_name
882
883
#endif /* TARGET_UNDERSCORE */
884
885
#ifndef bfd_pe_print_pdata
886
#define bfd_pe_print_pdata   NULL
887
#endif
888
889
#include "coffcode.h"
890
891
#ifdef PE
892
#define amd64coff_object_p pe_bfd_object_p
893
#else
894
#define amd64coff_object_p coff_object_p
895
#endif
896
897
const bfd_target
898
#ifdef TARGET_SYM
899
  TARGET_SYM =
900
#else
901
  x86_64_coff_vec =
902
#endif
903
{
904
#ifdef TARGET_NAME
905
  TARGET_NAME,
906
#else
907
 "coff-x86-64",     /* Name.  */
908
#endif
909
  bfd_target_coff_flavour,
910
  BFD_ENDIAN_LITTLE,    /* Data byte order is little.  */
911
  BFD_ENDIAN_LITTLE,    /* Header byte order is little.  */
912
913
  (HAS_RELOC | EXEC_P   /* Object flags.  */
914
   | HAS_LINENO | HAS_DEBUG
915
   | HAS_SYMS | HAS_LOCALS | WP_TEXT | D_PAGED | BFD_COMPRESS | BFD_DECOMPRESS),
916
917
  (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC /* Section flags.  */
918
#if defined(COFF_WITH_PE)
919
   | SEC_LINK_ONCE | SEC_LINK_DUPLICATES | SEC_READONLY | SEC_DEBUGGING
920
#endif
921
   | SEC_CODE | SEC_DATA | SEC_EXCLUDE ),
922
923
#ifdef TARGET_UNDERSCORE
924
  TARGET_UNDERSCORE,    /* Leading underscore.  */
925
#else
926
  0,        /* Leading underscore.  */
927
#endif
928
  '/',        /* Ar_pad_char.  */
929
  15,       /* Ar_max_namelen.  */
930
  0,        /* match priority.  */
931
  TARGET_KEEP_UNUSED_SECTION_SYMBOLS, /* keep unused section symbols.  */
932
  TARGET_MERGE_SECTIONS,
933
934
  bfd_getl64, bfd_getl_signed_64, bfd_putl64,
935
     bfd_getl32, bfd_getl_signed_32, bfd_putl32,
936
     bfd_getl16, bfd_getl_signed_16, bfd_putl16, /* Data.  */
937
  bfd_getl64, bfd_getl_signed_64, bfd_putl64,
938
     bfd_getl32, bfd_getl_signed_32, bfd_putl32,
939
     bfd_getl16, bfd_getl_signed_16, bfd_putl16, /* Hdrs.  */
940
941
  /* Note that we allow an object file to be treated as a core file as well.  */
942
  {       /* bfd_check_format.  */
943
    _bfd_dummy_target,
944
    amd64coff_object_p,
945
    bfd_generic_archive_p,
946
    amd64coff_object_p
947
  },
948
  {       /* bfd_set_format.  */
949
    _bfd_bool_bfd_false_error,
950
    coff_mkobject,
951
    _bfd_generic_mkarchive,
952
    _bfd_bool_bfd_false_error
953
  },
954
  {       /* bfd_write_contents.  */
955
    _bfd_bool_bfd_false_error,
956
    coff_write_object_contents,
957
    _bfd_write_archive_contents,
958
    _bfd_bool_bfd_false_error
959
  },
960
961
  BFD_JUMP_TABLE_GENERIC (coff),
962
  BFD_JUMP_TABLE_COPY (coff),
963
  BFD_JUMP_TABLE_CORE (_bfd_nocore),
964
  BFD_JUMP_TABLE_ARCHIVE (_bfd_archive_coff),
965
  BFD_JUMP_TABLE_SYMBOLS (coff),
966
  BFD_JUMP_TABLE_RELOCS (coff),
967
  BFD_JUMP_TABLE_WRITE (coff),
968
  BFD_JUMP_TABLE_LINK (coff),
969
  BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic),
970
971
  NULL,
972
973
  COFF_SWAP_TABLE
974
};
975
976
/* Entry for big object files.  */
977
978
#ifdef COFF_WITH_PE_BIGOBJ
979
const bfd_target
980
  TARGET_SYM_BIG =
981
{
982
  TARGET_NAME_BIG,
983
  bfd_target_coff_flavour,
984
  BFD_ENDIAN_LITTLE,    /* Data byte order is little.  */
985
  BFD_ENDIAN_LITTLE,    /* Header byte order is little.  */
986
987
  (HAS_RELOC | EXEC_P   /* Object flags.  */
988
   | HAS_LINENO | HAS_DEBUG
989
   | HAS_SYMS | HAS_LOCALS | WP_TEXT | D_PAGED | BFD_COMPRESS | BFD_DECOMPRESS),
990
991
  (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC /* Section flags.  */
992
#if defined(COFF_WITH_PE)
993
   | SEC_LINK_ONCE | SEC_LINK_DUPLICATES | SEC_READONLY | SEC_DEBUGGING
994
#endif
995
   | SEC_CODE | SEC_DATA | SEC_EXCLUDE ),
996
997
#ifdef TARGET_UNDERSCORE
998
  TARGET_UNDERSCORE,    /* Leading underscore.  */
999
#else
1000
  0,        /* Leading underscore.  */
1001
#endif
1002
  '/',        /* Ar_pad_char.  */
1003
  15,       /* Ar_max_namelen.  */
1004
  0,        /* match priority.  */
1005
  TARGET_KEEP_UNUSED_SECTION_SYMBOLS, /* keep unused section symbols.  */
1006
  TARGET_MERGE_SECTIONS,
1007
1008
  bfd_getl64, bfd_getl_signed_64, bfd_putl64,
1009
     bfd_getl32, bfd_getl_signed_32, bfd_putl32,
1010
     bfd_getl16, bfd_getl_signed_16, bfd_putl16, /* Data.  */
1011
  bfd_getl64, bfd_getl_signed_64, bfd_putl64,
1012
     bfd_getl32, bfd_getl_signed_32, bfd_putl32,
1013
     bfd_getl16, bfd_getl_signed_16, bfd_putl16, /* Hdrs.  */
1014
1015
  /* Note that we allow an object file to be treated as a core file as well.  */
1016
  {       /* bfd_check_format.  */
1017
    _bfd_dummy_target,
1018
    amd64coff_object_p,
1019
    bfd_generic_archive_p,
1020
    amd64coff_object_p
1021
  },
1022
  {       /* bfd_set_format.  */
1023
    _bfd_bool_bfd_false_error,
1024
    coff_mkobject,
1025
    _bfd_generic_mkarchive,
1026
    _bfd_bool_bfd_false_error
1027
  },
1028
  {       /* bfd_write_contents.  */
1029
    _bfd_bool_bfd_false_error,
1030
    coff_write_object_contents,
1031
    _bfd_write_archive_contents,
1032
    _bfd_bool_bfd_false_error
1033
  },
1034
1035
  BFD_JUMP_TABLE_GENERIC (coff),
1036
  BFD_JUMP_TABLE_COPY (coff),
1037
  BFD_JUMP_TABLE_CORE (_bfd_nocore),
1038
  BFD_JUMP_TABLE_ARCHIVE (_bfd_archive_coff),
1039
  BFD_JUMP_TABLE_SYMBOLS (coff),
1040
  BFD_JUMP_TABLE_RELOCS (coff),
1041
  BFD_JUMP_TABLE_WRITE (coff),
1042
  BFD_JUMP_TABLE_LINK (coff),
1043
  BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic),
1044
1045
  NULL,
1046
1047
  &bigobj_swap_table
1048
};
1049
#endif