(root)/
binutils-2.41/
bfd/
coff-i386.c
       1  /* BFD back-end for Intel 386 COFF files.
       2     Copyright (C) 1990-2023 Free Software Foundation, Inc.
       3     Written by Cygnus Support.
       4  
       5     This file is part of BFD, the Binary File Descriptor library.
       6  
       7     This program is free software; you can redistribute it and/or modify
       8     it under the terms of the GNU General Public License as published by
       9     the Free Software Foundation; either version 3 of the License, or
      10     (at your option) any later version.
      11  
      12     This program is distributed in the hope that it will be useful,
      13     but WITHOUT ANY WARRANTY; without even the implied warranty of
      14     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      15     GNU General Public License for more details.
      16  
      17     You should have received a copy of the GNU General Public License
      18     along with this program; if not, write to the Free Software
      19     Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
      20     MA 02110-1301, USA.  */
      21  
      22  #include "sysdep.h"
      23  #include "bfd.h"
      24  #include "libbfd.h"
      25  
      26  #include "coff/i386.h"
      27  
      28  #include "coff/internal.h"
      29  
      30  #ifdef COFF_WITH_PE
      31  #include "coff/pe.h"
      32  #endif
      33  
      34  #ifndef bfd_pe_print_pdata
      35  #define bfd_pe_print_pdata	NULL
      36  #endif
      37  
      38  #include "libcoff.h"
      39  
      40  /* All users of this file have bfd_octets_per_byte (abfd, sec) == 1.  */
      41  #define OCTETS_PER_BYTE(ABFD, SEC) 1
      42  
      43  static reloc_howto_type *coff_i386_rtype_to_howto
      44    (bfd *, asection *, struct internal_reloc *,
      45     struct coff_link_hash_entry *, struct internal_syment *,
      46     bfd_vma *);
      47  static reloc_howto_type *coff_i386_reloc_type_lookup
      48    (bfd *, bfd_reloc_code_real_type);
      49  
      50  #define COFF_DEFAULT_SECTION_ALIGNMENT_POWER (2)
      51  /* The page size is a guess based on ELF.  */
      52  
      53  #define COFF_PAGE_SIZE 0x1000
      54  
      55  /* For some reason when using i386 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  
      64  static bfd_reloc_status_type
      65  coff_i386_reloc (bfd *abfd,
      66  		 arelent *reloc_entry,
      67  		 asymbol *symbol,
      68  		 void * data,
      69  		 asection *input_section,
      70  		 bfd *output_bfd,
      71  		 char **error_message ATTRIBUTE_UNUSED)
      72  {
      73    symvalue diff;
      74  
      75  #ifndef COFF_WITH_PE
      76    if (output_bfd == (bfd *) NULL)
      77      return bfd_reloc_continue;
      78  #endif
      79  
      80    if (bfd_is_com_section (symbol->section))
      81      {
      82  #ifndef 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  #ifdef COFF_WITH_PE
     107        if (output_bfd == (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 howto->size
     113  	     bytes. For the external relocation, PE is very different
     114  	     from others. See md_apply_fix3 () in gas/config/tc-i386.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 = -bfd_get_reloc_size (howto);
     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  #ifdef COFF_WITH_PE
     131    /* FIXME: How should this case be handled?  */
     132    if (reloc_entry->howto->type == R_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        bfd_size_type octets = (reloc_entry->address
     145  			      * OCTETS_PER_BYTE (abfd, input_section));
     146        unsigned char *addr = (unsigned char *) data + octets;
     147  
     148        if (!bfd_reloc_offset_in_range (howto, abfd, input_section, octets))
     149  	return bfd_reloc_outofrange;
     150  
     151        switch (bfd_get_reloc_size (howto))
     152  	{
     153  	case 1:
     154  	  {
     155  	    char x = bfd_get_8 (abfd, addr);
     156  	    DOIT (x);
     157  	    bfd_put_8 (abfd, x, addr);
     158  	  }
     159  	  break;
     160  
     161  	case 2:
     162  	  {
     163  	    short x = bfd_get_16 (abfd, addr);
     164  	    DOIT (x);
     165  	    bfd_put_16 (abfd, (bfd_vma) x, addr);
     166  	  }
     167  	  break;
     168  
     169  	case 4:
     170  	  {
     171  	    long x = bfd_get_32 (abfd, addr);
     172  	    DOIT (x);
     173  	    bfd_put_32 (abfd, (bfd_vma) x, addr);
     174  	  }
     175  	  break;
     176  
     177  	default:
     178  	  abort ();
     179  	}
     180      }
     181  
     182    /* Now let bfd_perform_relocation finish everything up.  */
     183    return bfd_reloc_continue;
     184  }
     185  
     186  #ifdef COFF_WITH_PE
     187  /* Return TRUE if this relocation should appear in the output .reloc
     188     section.  */
     189  
     190  static bool
     191  in_reloc_p (bfd *abfd ATTRIBUTE_UNUSED, reloc_howto_type *howto)
     192  {
     193    return ! howto->pc_relative
     194      && howto->type != R_IMAGEBASE
     195      && howto->type != R_SECREL32
     196      && howto->type != R_SECTION;
     197  }
     198  #endif /* COFF_WITH_PE */
     199  
     200  #ifndef PCRELOFFSET
     201  #define PCRELOFFSET false
     202  #endif
     203  
     204  static reloc_howto_type howto_table[] =
     205  {
     206    EMPTY_HOWTO (0),
     207    EMPTY_HOWTO (1),
     208    EMPTY_HOWTO (2),
     209    EMPTY_HOWTO (3),
     210    EMPTY_HOWTO (4),
     211    EMPTY_HOWTO (5),
     212    HOWTO (R_DIR32,		/* type */
     213  	 0,			/* rightshift */
     214  	 4,			/* size */
     215  	 32,			/* bitsize */
     216  	 false,			/* pc_relative */
     217  	 0,			/* bitpos */
     218  	 complain_overflow_bitfield, /* complain_on_overflow */
     219  	 coff_i386_reloc,	/* special_function */
     220  	 "dir32",		/* name */
     221  	 true,			/* partial_inplace */
     222  	 0xffffffff,		/* src_mask */
     223  	 0xffffffff,		/* dst_mask */
     224  	 true),			/* pcrel_offset */
     225    /* PE IMAGE_REL_I386_DIR32NB relocation (7).	*/
     226    HOWTO (R_IMAGEBASE,		/* type */
     227  	 0,			/* rightshift */
     228  	 4,			/* size */
     229  	 32,			/* bitsize */
     230  	 false,			/* pc_relative */
     231  	 0,			/* bitpos */
     232  	 complain_overflow_bitfield, /* complain_on_overflow */
     233  	 coff_i386_reloc,	/* special_function */
     234  	 "rva32",		/* name */
     235  	 true,			/* partial_inplace */
     236  	 0xffffffff,		/* src_mask */
     237  	 0xffffffff,		/* dst_mask */
     238  	 false),		/* pcrel_offset */
     239    EMPTY_HOWTO (010),
     240    EMPTY_HOWTO (011),
     241  #ifdef COFF_WITH_PE
     242    /* 16-bit word section relocation (012).  */
     243    HOWTO (R_SECTION,		/* type */
     244  	 0,			/* rightshift */
     245  	 2,			/* size */
     246  	 16,			/* bitsize */
     247  	 false,			/* pc_relative */
     248  	 0,			/* bitpos */
     249  	 complain_overflow_bitfield, /* complain_on_overflow */
     250  	 coff_i386_reloc,	/* special_function */
     251  	 "secidx",		/* name */
     252  	 true,			/* partial_inplace */
     253  	 0xffffffff,		/* src_mask */
     254  	 0xffffffff,		/* dst_mask */
     255  	 true),			/* pcrel_offset */
     256    /* 32-bit longword section relative relocation (013).  */
     257    HOWTO (R_SECREL32,		/* type */
     258  	 0,			/* rightshift */
     259  	 4,			/* size */
     260  	 32,			/* bitsize */
     261  	 false,			/* pc_relative */
     262  	 0,			/* bitpos */
     263  	 complain_overflow_bitfield, /* complain_on_overflow */
     264  	 coff_i386_reloc,	/* special_function */
     265  	 "secrel32",		/* name */
     266  	 true,			/* partial_inplace */
     267  	 0xffffffff,		/* src_mask */
     268  	 0xffffffff,		/* dst_mask */
     269  	 true),			/* pcrel_offset */
     270  #else
     271    EMPTY_HOWTO (012),
     272    EMPTY_HOWTO (013),
     273  #endif
     274    EMPTY_HOWTO (014),
     275    EMPTY_HOWTO (015),
     276    EMPTY_HOWTO (016),
     277    /* Byte relocation (017).  */
     278    HOWTO (R_RELBYTE,		/* type */
     279  	 0,			/* rightshift */
     280  	 1,			/* size */
     281  	 8,			/* bitsize */
     282  	 false,			/* pc_relative */
     283  	 0,			/* bitpos */
     284  	 complain_overflow_bitfield, /* complain_on_overflow */
     285  	 coff_i386_reloc,	/* special_function */
     286  	 "8",			/* name */
     287  	 true,			/* partial_inplace */
     288  	 0x000000ff,		/* src_mask */
     289  	 0x000000ff,		/* dst_mask */
     290  	 PCRELOFFSET),		/* pcrel_offset */
     291    /* 16-bit word relocation (020).  */
     292    HOWTO (R_RELWORD,		/* type */
     293  	 0,			/* rightshift */
     294  	 2,			/* size */
     295  	 16,			/* bitsize */
     296  	 false,			/* pc_relative */
     297  	 0,			/* bitpos */
     298  	 complain_overflow_bitfield, /* complain_on_overflow */
     299  	 coff_i386_reloc,	/* special_function */
     300  	 "16",			/* name */
     301  	 true,			/* partial_inplace */
     302  	 0x0000ffff,		/* src_mask */
     303  	 0x0000ffff,		/* dst_mask */
     304  	 PCRELOFFSET),		/* pcrel_offset */
     305    /* 32-bit longword relocation (021).	*/
     306    HOWTO (R_RELLONG,		/* type */
     307  	 0,			/* rightshift */
     308  	 4,			/* size */
     309  	 32,			/* bitsize */
     310  	 false,			/* pc_relative */
     311  	 0,			/* bitpos */
     312  	 complain_overflow_bitfield, /* complain_on_overflow */
     313  	 coff_i386_reloc,	/* special_function */
     314  	 "32",			/* name */
     315  	 true,			/* partial_inplace */
     316  	 0xffffffff,		/* src_mask */
     317  	 0xffffffff,		/* dst_mask */
     318  	 PCRELOFFSET),		/* pcrel_offset */
     319    /* Byte PC relative relocation (022).	 */
     320    HOWTO (R_PCRBYTE,		/* type */
     321  	 0,			/* rightshift */
     322  	 1,			/* size */
     323  	 8,			/* bitsize */
     324  	 true,			/* pc_relative */
     325  	 0,			/* bitpos */
     326  	 complain_overflow_signed, /* complain_on_overflow */
     327  	 coff_i386_reloc,	/* special_function */
     328  	 "DISP8",		/* name */
     329  	 true,			/* partial_inplace */
     330  	 0x000000ff,		/* src_mask */
     331  	 0x000000ff,		/* dst_mask */
     332  	 PCRELOFFSET),		/* pcrel_offset */
     333    /* 16-bit word PC relative relocation (023).	*/
     334    HOWTO (R_PCRWORD,		/* type */
     335  	 0,			/* rightshift */
     336  	 2,			/* size */
     337  	 16,			/* bitsize */
     338  	 true,			/* pc_relative */
     339  	 0,			/* bitpos */
     340  	 complain_overflow_signed, /* complain_on_overflow */
     341  	 coff_i386_reloc,	/* special_function */
     342  	 "DISP16",		/* name */
     343  	 true,			/* partial_inplace */
     344  	 0x0000ffff,		/* src_mask */
     345  	 0x0000ffff,		/* dst_mask */
     346  	 PCRELOFFSET),		/* pcrel_offset */
     347    /* 32-bit longword PC relative relocation (024).  */
     348    HOWTO (R_PCRLONG,		/* type */
     349  	 0,			/* rightshift */
     350  	 4,			/* size */
     351  	 32,			/* bitsize */
     352  	 true,			/* pc_relative */
     353  	 0,			/* bitpos */
     354  	 complain_overflow_signed, /* complain_on_overflow */
     355  	 coff_i386_reloc,	/* special_function */
     356  	 "DISP32",		/* name */
     357  	 true,			/* partial_inplace */
     358  	 0xffffffff,		/* src_mask */
     359  	 0xffffffff,		/* dst_mask */
     360  	 PCRELOFFSET)		/* pcrel_offset */
     361  };
     362  
     363  #define NUM_HOWTOS (sizeof (howto_table) / sizeof (howto_table[0]))
     364  
     365  /* Turn a howto into a reloc  nunmber */
     366  
     367  #define SELECT_RELOC(x,howto) { x.r_type = howto->type; }
     368  #define BADMAG(x) I386BADMAG(x)
     369  #define I386 1			/* Customize coffcode.h */
     370  
     371  #define RTYPE2HOWTO(cache_ptr, dst)				\
     372    ((cache_ptr)->howto =						\
     373     ((dst)->r_type < NUM_HOWTOS					\
     374      ? howto_table + (dst)->r_type				\
     375      : NULL))
     376  
     377  /* For 386 COFF a STYP_NOLOAD | STYP_BSS section is part of a shared
     378     library.  On some other COFF targets STYP_BSS is normally
     379     STYP_NOLOAD.  */
     380  #define BSS_NOLOAD_IS_SHARED_LIBRARY
     381  
     382  /* Compute the addend of a reloc.  If the reloc is to a common symbol,
     383     the object file contains the value of the common symbol.  By the
     384     time this is called, the linker may be using a different symbol
     385     from a different object file with a different value.  Therefore, we
     386     hack wildly to locate the original symbol from this file so that we
     387     can make the correct adjustment.  This macro sets coffsym to the
     388     symbol from the original file, and uses it to set the addend value
     389     correctly.  If this is not a common symbol, the usual addend
     390     calculation is done, except that an additional tweak is needed for
     391     PC relative relocs.
     392     FIXME: This macro refers to symbols and asect; these are from the
     393     calling function, not the macro arguments.  */
     394  
     395  #define CALC_ADDEND(abfd, ptr, reloc, cache_ptr)		\
     396    {								\
     397      coff_symbol_type *coffsym = (coff_symbol_type *) NULL;	\
     398      if (ptr && bfd_asymbol_bfd (ptr) != abfd)			\
     399        coffsym = (obj_symbols (abfd)				\
     400  		 + (cache_ptr->sym_ptr_ptr - symbols));		\
     401      else if (ptr)						\
     402        coffsym = coff_symbol_from (ptr);				\
     403      if (coffsym != (coff_symbol_type *) NULL			\
     404  	&& coffsym->native->u.syment.n_scnum == 0)		\
     405        cache_ptr->addend = - coffsym->native->u.syment.n_value;	\
     406      else if (ptr && bfd_asymbol_bfd (ptr) == abfd		\
     407  	     && ptr->section != (asection *) NULL)		\
     408        cache_ptr->addend = - (ptr->section->vma + ptr->value);	\
     409      else							\
     410        cache_ptr->addend = 0;					\
     411      if (ptr && reloc.r_type < NUM_HOWTOS			\
     412  	&& howto_table[reloc.r_type].pc_relative)		\
     413        cache_ptr->addend += asect->vma;				\
     414    }
     415  
     416  /* We use the special COFF backend linker.  For normal i386 COFF, we
     417     can use the generic relocate_section routine.  For PE, we need our
     418     own routine.  */
     419  
     420  #ifndef COFF_WITH_PE
     421  
     422  #define coff_relocate_section _bfd_coff_generic_relocate_section
     423  
     424  #else /* COFF_WITH_PE */
     425  
     426  /* The PE relocate section routine.  We handle secidx relocations here,
     427     as well as making sure that we don't do anything for a relocatable
     428     link.  */
     429  
     430  static bool
     431  coff_pe_i386_relocate_section (bfd *output_bfd,
     432  			       struct bfd_link_info *info,
     433  			       bfd *input_bfd,
     434  			       asection *input_section,
     435  			       bfd_byte *contents,
     436  			       struct internal_reloc *relocs,
     437  			       struct internal_syment *syms,
     438  			       asection **sections)
     439  {
     440    struct internal_reloc *rel;
     441    struct internal_reloc *relend;
     442  
     443    if (bfd_link_relocatable (info))
     444      return true;
     445  
     446    rel = relocs;
     447    relend = rel + input_section->reloc_count;
     448  
     449    for (; rel < relend; rel++)
     450      {
     451        long symndx;
     452        struct coff_link_hash_entry *h;
     453        asection *sec, *s;
     454        uint16_t idx = 0, i = 1;
     455  
     456        if (rel->r_type != R_SECTION)
     457  	continue;
     458  
     459        /* Make sure that _bfd_coff_generic_relocate_section won't parse
     460           this reloc after us.  */
     461        rel->r_type = 0;
     462  
     463        symndx = rel->r_symndx;
     464  
     465        if (symndx < 0
     466  	  || (unsigned long) symndx >= obj_raw_syment_count (input_bfd))
     467  	continue;
     468  
     469        h = obj_coff_sym_hashes (input_bfd)[symndx];
     470  
     471        if (h == NULL)
     472  	sec = sections[symndx];
     473        else
     474  	{
     475  	  if (h->root.type == bfd_link_hash_defined
     476  	      || h->root.type == bfd_link_hash_defweak)
     477  	    {
     478  	      /* Defined weak symbols are a GNU extension.  */
     479  	      sec = h->root.u.def.section;
     480  	    }
     481  	  else
     482  	    {
     483  	      sec = NULL;
     484  	    }
     485  	}
     486  
     487        if (!sec)
     488  	continue;
     489  
     490        if (bfd_is_abs_section (sec))
     491  	continue;
     492  
     493        if (discarded_section (sec))
     494  	continue;
     495  
     496        s = output_bfd->sections;
     497        while (s)
     498  	{
     499  	  if (s == sec->output_section)
     500  	    {
     501  	      idx = i;
     502  	      break;
     503  	    }
     504  
     505  	  i++;
     506  	  s = s->next;
     507  	}
     508  
     509        bfd_putl16 (idx, contents + rel->r_vaddr - input_section->vma);
     510      }
     511  
     512    return _bfd_coff_generic_relocate_section (output_bfd, info, input_bfd,
     513  					     input_section, contents,
     514  					     relocs, syms, sections);
     515  }
     516  
     517  #define coff_relocate_section coff_pe_i386_relocate_section
     518  
     519  #endif /* COFF_WITH_PE */
     520  
     521  /* Convert an rtype to howto for the COFF backend linker.  */
     522  
     523  static reloc_howto_type *
     524  coff_i386_rtype_to_howto (bfd *abfd ATTRIBUTE_UNUSED,
     525  			  asection *sec,
     526  			  struct internal_reloc *rel,
     527  			  struct coff_link_hash_entry *h,
     528  			  struct internal_syment *sym,
     529  			  bfd_vma *addendp)
     530  {
     531    reloc_howto_type *howto;
     532  
     533    if (rel->r_type >= NUM_HOWTOS)
     534      {
     535        bfd_set_error (bfd_error_bad_value);
     536        return NULL;
     537      }
     538  
     539    howto = howto_table + rel->r_type;
     540  
     541  #ifdef COFF_WITH_PE
     542    /* Cancel out code in _bfd_coff_generic_relocate_section.  */
     543    *addendp = 0;
     544  #endif
     545  
     546    if (howto->pc_relative)
     547      *addendp += sec->vma;
     548  
     549    if (sym != NULL && sym->n_scnum == 0 && sym->n_value != 0)
     550      {
     551        /* This is a common symbol.  The section contents include the
     552  	 size (sym->n_value) as an addend.  The relocate_section
     553  	 function will be adding in the final value of the symbol.  We
     554  	 need to subtract out the current size in order to get the
     555  	 correct result.  */
     556  
     557        BFD_ASSERT (h != NULL);
     558  
     559  #ifndef COFF_WITH_PE
     560        /* I think we *do* want to bypass this.  If we don't, I have
     561  	 seen some data parameters get the wrong relocation address.
     562  	 If I link two versions with and without this section bypassed
     563  	 and then do a binary comparison, the addresses which are
     564  	 different can be looked up in the map.  The case in which
     565  	 this section has been bypassed has addresses which correspond
     566  	 to values I can find in the map.  */
     567        *addendp -= sym->n_value;
     568  #endif
     569      }
     570  
     571  #ifndef COFF_WITH_PE
     572    /* If the output symbol is common (in which case this must be a
     573       relocatable link), we need to add in the final size of the
     574       common symbol.  */
     575    if (h != NULL && h->root.type == bfd_link_hash_common)
     576      *addendp += h->root.u.c.size;
     577  #endif
     578  
     579  #ifdef COFF_WITH_PE
     580    if (howto->pc_relative)
     581      {
     582        *addendp -= 4;
     583  
     584        /* If the symbol is defined, then the generic code is going to
     585  	 add back the symbol value in order to cancel out an
     586  	 adjustment it made to the addend.  However, we set the addend
     587  	 to 0 at the start of this function.  We need to adjust here,
     588  	 to avoid the adjustment the generic code will make.  FIXME:
     589  	 This is getting a bit hackish.  */
     590        if (sym != NULL && sym->n_scnum != 0)
     591  	*addendp -= sym->n_value;
     592      }
     593  
     594    if (rel->r_type == R_IMAGEBASE
     595        && (bfd_get_flavour(sec->output_section->owner)
     596  	  == bfd_target_coff_flavour))
     597      {
     598        *addendp -= pe_data(sec->output_section->owner)->pe_opthdr.ImageBase;
     599      }
     600  
     601    /* PR 17099 - Absolute R_PCRLONG relocations do not need a symbol.  */
     602    if (rel->r_type == R_PCRLONG && sym == NULL)
     603      *addendp -= rel->r_vaddr;
     604    else
     605      BFD_ASSERT (sym != NULL);
     606  
     607    if (rel->r_type == R_SECREL32 && sym != NULL)
     608      {
     609        bfd_vma osect_vma;
     610  
     611        if (h && (h->root.type == bfd_link_hash_defined
     612  		|| h->root.type == bfd_link_hash_defweak))
     613  	osect_vma = h->root.u.def.section->output_section->vma;
     614        else
     615  	{
     616  	  asection *s;
     617  	  int i;
     618  
     619  	  /* Sigh, the only way to get the section to offset against
     620  	     is to find it the hard way.  */
     621  
     622  	  for (s = abfd->sections, i = 1; i < sym->n_scnum; i++)
     623  	    s = s->next;
     624  
     625  	  osect_vma = s->output_section->vma;
     626  	}
     627  
     628        *addendp -= osect_vma;
     629      }
     630  #endif
     631  
     632    return howto;
     633  }
     634  
     635  #define coff_bfd_reloc_type_lookup coff_i386_reloc_type_lookup
     636  #define coff_bfd_reloc_name_lookup coff_i386_reloc_name_lookup
     637  
     638  static reloc_howto_type *
     639  coff_i386_reloc_type_lookup (bfd *abfd ATTRIBUTE_UNUSED,
     640  			     bfd_reloc_code_real_type code)
     641  {
     642    switch (code)
     643      {
     644      case BFD_RELOC_RVA:
     645        return howto_table + R_IMAGEBASE;
     646      case BFD_RELOC_32:
     647        return howto_table + R_DIR32;
     648      case BFD_RELOC_32_PCREL:
     649        return howto_table + R_PCRLONG;
     650      case BFD_RELOC_16:
     651        return howto_table + R_RELWORD;
     652      case BFD_RELOC_16_PCREL:
     653        return howto_table + R_PCRWORD;
     654      case BFD_RELOC_8:
     655        return howto_table + R_RELBYTE;
     656      case BFD_RELOC_8_PCREL:
     657        return howto_table + R_PCRBYTE;
     658  #ifdef COFF_WITH_PE
     659      case BFD_RELOC_32_SECREL:
     660        return howto_table + R_SECREL32;
     661      case BFD_RELOC_16_SECIDX:
     662        return howto_table + R_SECTION;
     663  #endif
     664      default:
     665        BFD_FAIL ();
     666        return 0;
     667      }
     668  }
     669  
     670  static reloc_howto_type *
     671  coff_i386_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED,
     672  			     const char *r_name)
     673  {
     674    unsigned int i;
     675  
     676    for (i = 0; i < NUM_HOWTOS; i++)
     677      if (howto_table[i].name != NULL
     678  	&& strcasecmp (howto_table[i].name, r_name) == 0)
     679        return &howto_table[i];
     680  
     681    return NULL;
     682  }
     683  
     684  #define coff_rtype_to_howto coff_i386_rtype_to_howto
     685  
     686  #ifdef TARGET_UNDERSCORE
     687  
     688  /* If i386 gcc uses underscores for symbol names, then it does not use
     689     a leading dot for local labels, so if TARGET_UNDERSCORE is defined
     690     we treat all symbols starting with L as local.  */
     691  
     692  static bool
     693  coff_i386_is_local_label_name (bfd *abfd, const char *name)
     694  {
     695    if (name[0] == 'L')
     696      return true;
     697  
     698    return _bfd_coff_is_local_label_name (abfd, name);
     699  }
     700  
     701  #define coff_bfd_is_local_label_name coff_i386_is_local_label_name
     702  
     703  #endif /* TARGET_UNDERSCORE */
     704  
     705  #include "coffcode.h"
     706  
     707  const bfd_target
     708  #ifdef TARGET_SYM
     709    TARGET_SYM =
     710  #else
     711    i386_coff_vec =
     712  #endif
     713  {
     714  #ifdef TARGET_NAME
     715    TARGET_NAME,
     716  #else
     717    "coff-i386",			/* name */
     718  #endif
     719    bfd_target_coff_flavour,
     720    BFD_ENDIAN_LITTLE,		/* data byte order is little */
     721    BFD_ENDIAN_LITTLE,		/* header byte order is little */
     722  
     723    (HAS_RELOC | EXEC_P |		/* object flags */
     724     HAS_LINENO | HAS_DEBUG |
     725     HAS_SYMS | HAS_LOCALS | WP_TEXT | D_PAGED | BFD_COMPRESS | BFD_DECOMPRESS ),
     726  
     727    (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC /* section flags */
     728  #ifdef COFF_WITH_PE
     729     | SEC_LINK_ONCE | SEC_LINK_DUPLICATES | SEC_READONLY | SEC_DEBUGGING
     730  #endif
     731     | SEC_CODE | SEC_DATA | SEC_EXCLUDE ),
     732  
     733  #ifdef TARGET_UNDERSCORE
     734    TARGET_UNDERSCORE,		/* leading underscore */
     735  #else
     736    0,				/* leading underscore */
     737  #endif
     738    '/',				/* ar_pad_char */
     739    15,				/* ar_max_namelen */
     740    0,				/* match priority.  */
     741    TARGET_KEEP_UNUSED_SECTION_SYMBOLS, /* keep unused section symbols.  */
     742  
     743    bfd_getl64, bfd_getl_signed_64, bfd_putl64,
     744       bfd_getl32, bfd_getl_signed_32, bfd_putl32,
     745       bfd_getl16, bfd_getl_signed_16, bfd_putl16, /* data */
     746    bfd_getl64, bfd_getl_signed_64, bfd_putl64,
     747       bfd_getl32, bfd_getl_signed_32, bfd_putl32,
     748       bfd_getl16, bfd_getl_signed_16, bfd_putl16, /* hdrs */
     749  
     750  #ifndef COFF_CHECK_FORMAT
     751  #define COFF_CHECK_FORMAT coff_object_p
     752  #endif
     753  #ifndef COFF_WRITE_CONTENTS
     754  #define COFF_WRITE_CONTENTS coff_write_object_contents
     755  #endif
     756  
     757  /* Note that we allow an object file to be treated as a core file as well.  */
     758  
     759    {				/* bfd_check_format */
     760      _bfd_dummy_target,
     761      COFF_CHECK_FORMAT,
     762      bfd_generic_archive_p,
     763      COFF_CHECK_FORMAT
     764    },
     765    {				/* bfd_set_format */
     766      _bfd_bool_bfd_false_error,
     767      coff_mkobject,
     768      _bfd_generic_mkarchive,
     769      _bfd_bool_bfd_false_error
     770    },
     771    {				/* bfd_write_contents */
     772      _bfd_bool_bfd_false_error,
     773      COFF_WRITE_CONTENTS,
     774      _bfd_write_archive_contents,
     775      _bfd_bool_bfd_false_error
     776    },
     777  
     778    BFD_JUMP_TABLE_GENERIC (coff),
     779    BFD_JUMP_TABLE_COPY (coff),
     780    BFD_JUMP_TABLE_CORE (_bfd_nocore),
     781    BFD_JUMP_TABLE_ARCHIVE (_bfd_archive_coff),
     782    BFD_JUMP_TABLE_SYMBOLS (coff),
     783    BFD_JUMP_TABLE_RELOCS (coff),
     784    BFD_JUMP_TABLE_WRITE (coff),
     785    BFD_JUMP_TABLE_LINK (coff),
     786    BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic),
     787  
     788    NULL,
     789  
     790    COFF_SWAP_TABLE
     791  };
     792  
     793  #ifdef COFF_WITH_PE_BIGOBJ
     794  const bfd_target
     795    TARGET_SYM_BIG =
     796  {
     797    TARGET_NAME_BIG,
     798    bfd_target_coff_flavour,
     799    BFD_ENDIAN_LITTLE,		/* data byte order is little */
     800    BFD_ENDIAN_LITTLE,		/* header byte order is little */
     801  
     802    (HAS_RELOC | EXEC_P |		/* object flags */
     803     HAS_LINENO | HAS_DEBUG |
     804     HAS_SYMS | HAS_LOCALS | WP_TEXT | D_PAGED | BFD_COMPRESS | BFD_DECOMPRESS ),
     805  
     806    (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC /* section flags */
     807  #ifdef COFF_WITH_PE
     808     | SEC_LINK_ONCE | SEC_LINK_DUPLICATES | SEC_READONLY | SEC_DEBUGGING
     809  #endif
     810     | SEC_CODE | SEC_DATA | SEC_EXCLUDE ),
     811  
     812  #ifdef TARGET_UNDERSCORE
     813    TARGET_UNDERSCORE,		/* leading underscore */
     814  #else
     815    0,				/* leading underscore */
     816  #endif
     817    '/',				/* ar_pad_char */
     818    15,				/* ar_max_namelen */
     819    0,				/* match priority.  */
     820    TARGET_KEEP_UNUSED_SECTION_SYMBOLS, /* keep unused section symbols.  */
     821  
     822    bfd_getl64, bfd_getl_signed_64, bfd_putl64,
     823       bfd_getl32, bfd_getl_signed_32, bfd_putl32,
     824       bfd_getl16, bfd_getl_signed_16, bfd_putl16, /* data */
     825    bfd_getl64, bfd_getl_signed_64, bfd_putl64,
     826       bfd_getl32, bfd_getl_signed_32, bfd_putl32,
     827       bfd_getl16, bfd_getl_signed_16, bfd_putl16, /* hdrs */
     828  
     829  /* Note that we allow an object file to be treated as a core file as well.  */
     830  
     831    {				/* bfd_check_format */
     832      _bfd_dummy_target,
     833      COFF_CHECK_FORMAT,
     834      bfd_generic_archive_p,
     835      COFF_CHECK_FORMAT
     836    },
     837    {				/* bfd_set_format */
     838      _bfd_bool_bfd_false_error,
     839      coff_mkobject,
     840      _bfd_generic_mkarchive,
     841      _bfd_bool_bfd_false_error
     842    },
     843    {				/* bfd_write_contents */
     844      _bfd_bool_bfd_false_error,
     845      COFF_WRITE_CONTENTS,
     846      _bfd_write_archive_contents,
     847      _bfd_bool_bfd_false_error
     848    },
     849  
     850    BFD_JUMP_TABLE_GENERIC (coff),
     851    BFD_JUMP_TABLE_COPY (coff),
     852    BFD_JUMP_TABLE_CORE (_bfd_nocore),
     853    BFD_JUMP_TABLE_ARCHIVE (_bfd_archive_coff),
     854    BFD_JUMP_TABLE_SYMBOLS (coff),
     855    BFD_JUMP_TABLE_RELOCS (coff),
     856    BFD_JUMP_TABLE_WRITE (coff),
     857    BFD_JUMP_TABLE_LINK (coff),
     858    BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic),
     859  
     860    NULL,
     861  
     862    &bigobj_swap_table
     863  };
     864  #endif