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