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