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