(root)/
binutils-2.41/
bfd/
coff-go32.c
       1  /* BFD back-end for Intel 386 COFF files (DJGPP variant).
       2     Copyright (C) 1990-2023 Free Software Foundation, Inc.
       3     Written by DJ Delorie.
       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  #define TARGET_SYM		i386_coff_go32_vec
      23  #define TARGET_NAME		"coff-go32"
      24  #define TARGET_UNDERSCORE	'_'
      25  #define COFF_GO32
      26  #define COFF_LONG_SECTION_NAMES
      27  #define COFF_SUPPORT_GNU_LINKONCE
      28  #define COFF_LONG_FILENAMES
      29  
      30  #define COFF_SECTION_ALIGNMENT_ENTRIES \
      31  { COFF_SECTION_NAME_PARTIAL_MATCH (".data"), \
      32    COFF_ALIGNMENT_FIELD_EMPTY, COFF_ALIGNMENT_FIELD_EMPTY, 4 }, \
      33  { COFF_SECTION_NAME_PARTIAL_MATCH (".text"), \
      34    COFF_ALIGNMENT_FIELD_EMPTY, COFF_ALIGNMENT_FIELD_EMPTY, 4 }, \
      35  { COFF_SECTION_NAME_PARTIAL_MATCH (".const"), \
      36    COFF_ALIGNMENT_FIELD_EMPTY, COFF_ALIGNMENT_FIELD_EMPTY, 4 }, \
      37  { COFF_SECTION_NAME_PARTIAL_MATCH (".rodata"), \
      38    COFF_ALIGNMENT_FIELD_EMPTY, COFF_ALIGNMENT_FIELD_EMPTY, 4 }, \
      39  { COFF_SECTION_NAME_PARTIAL_MATCH (".bss"), \
      40    COFF_ALIGNMENT_FIELD_EMPTY, COFF_ALIGNMENT_FIELD_EMPTY, 4 }, \
      41  { COFF_SECTION_NAME_PARTIAL_MATCH (".gnu.linkonce.d"), \
      42    COFF_ALIGNMENT_FIELD_EMPTY, COFF_ALIGNMENT_FIELD_EMPTY, 4 }, \
      43  { COFF_SECTION_NAME_PARTIAL_MATCH (".gnu.linkonce.t"), \
      44    COFF_ALIGNMENT_FIELD_EMPTY, COFF_ALIGNMENT_FIELD_EMPTY, 4 }, \
      45  { COFF_SECTION_NAME_PARTIAL_MATCH (".gnu.linkonce.r"), \
      46    COFF_ALIGNMENT_FIELD_EMPTY, COFF_ALIGNMENT_FIELD_EMPTY, 4 }, \
      47  { COFF_SECTION_NAME_PARTIAL_MATCH (".gnu.linkonce.b"), \
      48    COFF_ALIGNMENT_FIELD_EMPTY, COFF_ALIGNMENT_FIELD_EMPTY, 4 }, \
      49  { COFF_SECTION_NAME_PARTIAL_MATCH (".debug"), \
      50    COFF_ALIGNMENT_FIELD_EMPTY, COFF_ALIGNMENT_FIELD_EMPTY, 0 }, \
      51  { COFF_SECTION_NAME_PARTIAL_MATCH (".gnu.linkonce.wi"), \
      52    COFF_ALIGNMENT_FIELD_EMPTY, COFF_ALIGNMENT_FIELD_EMPTY, 0 }
      53  
      54  /* Section contains extended relocations. */
      55  #define IMAGE_SCN_LNK_NRELOC_OVFL (0x01000000)
      56  
      57  #include "sysdep.h"
      58  #include "bfd.h"
      59  
      60  /* The following functions are not static, because they are also
      61     used for coff-go32-exe (coff-stgo32.c).  */
      62  bool _bfd_go32_mkobject (bfd *);
      63  void _bfd_go32_swap_scnhdr_in (bfd *, void *, void *);
      64  unsigned int _bfd_go32_swap_scnhdr_out (bfd *, void *, void *);
      65  
      66  #define coff_mkobject _bfd_go32_mkobject
      67  #define coff_SWAP_scnhdr_in _bfd_go32_swap_scnhdr_in
      68  #define coff_SWAP_scnhdr_out _bfd_go32_swap_scnhdr_out
      69  
      70  #include "coff-i386.c"
      71  
      72  bool
      73  _bfd_go32_mkobject (bfd * abfd)
      74  {
      75    const bfd_size_type amt = sizeof (coff_data_type);
      76  
      77    abfd->tdata.coff_obj_data = bfd_zalloc (abfd, amt);
      78    if (abfd->tdata.coff_obj_data == NULL)
      79      return false;
      80  
      81    coff_data (abfd)->go32 = true;
      82  
      83    bfd_coff_long_section_names (abfd)
      84      = coff_backend_info (abfd)->_bfd_coff_long_section_names;
      85  
      86    return true;
      87  }
      88  
      89  void
      90  _bfd_go32_swap_scnhdr_in (bfd * abfd, void * ext, void * in)
      91  {
      92    SCNHDR *scnhdr_ext = (SCNHDR *) ext;
      93    struct internal_scnhdr *scnhdr_int = (struct internal_scnhdr *) in;
      94  
      95    memcpy (scnhdr_int->s_name, scnhdr_ext->s_name, sizeof (scnhdr_int->s_name));
      96  
      97    scnhdr_int->s_vaddr = GET_SCNHDR_VADDR (abfd, scnhdr_ext->s_vaddr);
      98    scnhdr_int->s_paddr = GET_SCNHDR_PADDR (abfd, scnhdr_ext->s_paddr);
      99    scnhdr_int->s_size = GET_SCNHDR_SIZE (abfd, scnhdr_ext->s_size);
     100  
     101    scnhdr_int->s_scnptr = GET_SCNHDR_SCNPTR (abfd, scnhdr_ext->s_scnptr);
     102    scnhdr_int->s_relptr = GET_SCNHDR_RELPTR (abfd, scnhdr_ext->s_relptr);
     103    scnhdr_int->s_lnnoptr = GET_SCNHDR_LNNOPTR (abfd, scnhdr_ext->s_lnnoptr);
     104    scnhdr_int->s_flags = GET_SCNHDR_FLAGS (abfd, scnhdr_ext->s_flags);
     105    scnhdr_int->s_nreloc = GET_SCNHDR_NRELOC (abfd, scnhdr_ext->s_nreloc);
     106    scnhdr_int->s_nlnno = GET_SCNHDR_NLNNO (abfd, scnhdr_ext->s_nlnno);
     107  
     108    /* DJGPP follows the same strategy as PE COFF.
     109       Iff the file is an executable then the higher 16 bits
     110       of the line number have been stored in the relocation
     111       counter field.  */
     112    if (abfd->flags & EXEC_P && (strcmp (scnhdr_ext->s_name, ".text") == 0))
     113      {
     114        scnhdr_int->s_nlnno
     115  	= (GET_SCNHDR_NRELOC (abfd, scnhdr_ext->s_nreloc) << 16)
     116  	  + GET_SCNHDR_NLNNO (abfd, scnhdr_ext->s_nlnno);
     117        scnhdr_int->s_nreloc = 0;
     118      }
     119  }
     120  
     121  unsigned int
     122  _bfd_go32_swap_scnhdr_out (bfd * abfd, void * in, void * out)
     123  {
     124    struct internal_scnhdr *scnhdr_int = (struct internal_scnhdr *) in;
     125    SCNHDR *scnhdr_ext = (SCNHDR *) out;
     126    unsigned int ret = bfd_coff_scnhsz (abfd);
     127  
     128    memcpy (scnhdr_ext->s_name, scnhdr_int->s_name, sizeof (scnhdr_int->s_name));
     129  
     130    PUT_SCNHDR_VADDR (abfd, scnhdr_int->s_vaddr, scnhdr_ext->s_vaddr);
     131    PUT_SCNHDR_PADDR (abfd, scnhdr_int->s_paddr, scnhdr_ext->s_paddr);
     132    PUT_SCNHDR_SIZE (abfd, scnhdr_int->s_size, scnhdr_ext->s_size);
     133    PUT_SCNHDR_SCNPTR (abfd, scnhdr_int->s_scnptr, scnhdr_ext->s_scnptr);
     134    PUT_SCNHDR_RELPTR (abfd, scnhdr_int->s_relptr, scnhdr_ext->s_relptr);
     135    PUT_SCNHDR_LNNOPTR (abfd, scnhdr_int->s_lnnoptr, scnhdr_ext->s_lnnoptr);
     136    PUT_SCNHDR_FLAGS (abfd, scnhdr_int->s_flags, scnhdr_ext->s_flags);
     137  
     138    if (abfd->flags & EXEC_P && (strcmp (scnhdr_int->s_name, ".text") == 0))
     139      {
     140        /* DJGPP follows the same strategy as PE COFF.
     141  	 By inference from looking at MS output, the 32 bit field
     142  	 which is the combination of the number_of_relocs and
     143  	 number_of_linenos is used for the line number count in
     144  	 executables.  A 16-bit field won't do for cc1.  The MS
     145  	 document says that the number of relocs is zero for
     146  	 executables, but the 17-th bit has been observed to be there.
     147  	 Overflow is not an issue: a 4G-line program will overflow a
     148  	 bunch of other fields long before this!  */
     149        PUT_SCNHDR_NLNNO (abfd, (scnhdr_int->s_nlnno & 0xffff),
     150  			scnhdr_ext->s_nlnno);
     151        PUT_SCNHDR_NRELOC (abfd, (scnhdr_int->s_nlnno >> 16),
     152  			 scnhdr_ext->s_nreloc);
     153      }
     154    else
     155      {
     156        /* DJGPP follows the same strategy as PE COFF.  */
     157        if (scnhdr_int->s_nlnno <= MAX_SCNHDR_NLNNO)
     158  	PUT_SCNHDR_NLNNO (abfd, scnhdr_int->s_nlnno, scnhdr_ext->s_nlnno);
     159        else
     160  	{
     161  	  char buf[sizeof (scnhdr_int->s_name) + 1];
     162  
     163  	  memcpy (buf, scnhdr_int->s_name, sizeof (scnhdr_int->s_name));
     164  	  buf[sizeof (scnhdr_int->s_name)] = '\0';
     165  	  _bfd_error_handler
     166  	    /* xgettext:c-format */
     167  	    (_("%pB: warning: %s: line number overflow: 0x%lx > 0xffff"),
     168  	     abfd, buf, scnhdr_int->s_nlnno);
     169  	  bfd_set_error (bfd_error_file_truncated);
     170  	  PUT_SCNHDR_NLNNO (abfd, 0xffff, scnhdr_ext->s_nlnno);
     171  	  ret = 0;
     172  	}
     173  
     174        /* Although we could encode 0xffff relocs here, we do not, to be
     175  	 consistent with other parts of bfd.  Also it lets us warn, as
     176  	 we should never see 0xffff here w/o having the overflow flag
     177  	 set.  */
     178        if (scnhdr_int->s_nreloc < MAX_SCNHDR_NRELOC)
     179  	PUT_SCNHDR_NRELOC (abfd, scnhdr_int->s_nreloc, scnhdr_ext->s_nreloc);
     180        else
     181  	{
     182  	  /* DJGPP can deal with large #s of relocs, but not here.  */
     183  	  PUT_SCNHDR_NRELOC (abfd, 0xffff, scnhdr_ext->s_nreloc);
     184  	  scnhdr_int->s_flags |= IMAGE_SCN_LNK_NRELOC_OVFL;
     185  	  PUT_SCNHDR_FLAGS (abfd, scnhdr_int->s_flags, scnhdr_ext->s_flags);
     186  	}
     187      }
     188  
     189    return ret;
     190  }