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