Coverage Report

Created: 2023-06-29 07:06

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