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