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