Home | History | Annotate | Line # | Download | only in bfd
coff-stgo32.c revision 1.1.1.2.8.1
      1          1.1     skrll /* BFD back-end for Intel 386 COFF files (DJGPP variant with a stub).
      2  1.1.1.2.8.1       tls    Copyright 1997, 1998, 1999, 2000, 2001, 2002, 2005, 2006, 2007, 2009,
      3  1.1.1.2.8.1       tls    2011, 2012  Free Software Foundation, Inc.
      4          1.1     skrll    Written by Robert Hoehne.
      5          1.1     skrll 
      6          1.1     skrll    This file is part of BFD, the Binary File Descriptor library.
      7          1.1     skrll 
      8          1.1     skrll    This program is free software; you can redistribute it and/or modify
      9          1.1     skrll    it under the terms of the GNU General Public License as published by
     10          1.1     skrll    the Free Software Foundation; either version 3 of the License, or
     11          1.1     skrll    (at your option) any later version.
     12          1.1     skrll 
     13          1.1     skrll    This program is distributed in the hope that it will be useful,
     14          1.1     skrll    but WITHOUT ANY WARRANTY; without even the implied warranty of
     15          1.1     skrll    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     16          1.1     skrll    GNU General Public License for more details.
     17          1.1     skrll 
     18          1.1     skrll    You should have received a copy of the GNU General Public License
     19          1.1     skrll    along with this program; if not, write to the Free Software
     20          1.1     skrll    Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
     21          1.1     skrll    MA 02110-1301, USA.  */
     22          1.1     skrll 
     23          1.1     skrll /* This file handles now also stubbed coff images. The stub is a small
     24          1.1     skrll    DOS executable program before the coff image to load it in memory
     25          1.1     skrll    and execute it. This is needed, because DOS cannot run coff files.
     26          1.1     skrll 
     27          1.1     skrll    All the functions below are called by the corresponding functions
     28          1.1     skrll    from coffswap.h.
     29          1.1     skrll    The only thing what they do is to adjust the information stored in
     30          1.1     skrll    the COFF file which are offset into the file.
     31          1.1     skrll    This is needed, because DJGPP uses a very special way to load and run
     32          1.1     skrll    the coff image. It loads the image in memory and assumes then, that the
     33          1.1     skrll    image had no stub by using the filepointers as pointers in the coff
     34          1.1     skrll    image and NOT in the file.
     35          1.1     skrll 
     36          1.1     skrll    To be compatible with any existing executables I have fixed this
     37          1.1     skrll    here and NOT in the DJGPP startup code.  */
     38          1.1     skrll 
     39          1.1     skrll #define TARGET_SYM		go32stubbedcoff_vec
     40          1.1     skrll #define TARGET_NAME		"coff-go32-exe"
     41          1.1     skrll #define TARGET_UNDERSCORE	'_'
     42          1.1     skrll #define COFF_GO32_EXE
     43          1.1     skrll #define COFF_LONG_SECTION_NAMES
     44          1.1     skrll #define COFF_SUPPORT_GNU_LINKONCE
     45          1.1     skrll #define COFF_LONG_FILENAMES
     46          1.1     skrll 
     47          1.1     skrll #define COFF_SECTION_ALIGNMENT_ENTRIES \
     48          1.1     skrll { COFF_SECTION_NAME_EXACT_MATCH (".data"), \
     49          1.1     skrll   COFF_ALIGNMENT_FIELD_EMPTY, COFF_ALIGNMENT_FIELD_EMPTY, 4 }, \
     50          1.1     skrll { COFF_SECTION_NAME_EXACT_MATCH (".text"), \
     51          1.1     skrll   COFF_ALIGNMENT_FIELD_EMPTY, COFF_ALIGNMENT_FIELD_EMPTY, 4 }, \
     52          1.1     skrll { COFF_SECTION_NAME_PARTIAL_MATCH (".debug"), \
     53          1.1     skrll   COFF_ALIGNMENT_FIELD_EMPTY, COFF_ALIGNMENT_FIELD_EMPTY, 0 }, \
     54          1.1     skrll { COFF_SECTION_NAME_PARTIAL_MATCH (".gnu.linkonce.wi"), \
     55          1.1     skrll   COFF_ALIGNMENT_FIELD_EMPTY, COFF_ALIGNMENT_FIELD_EMPTY, 0 }
     56          1.1     skrll 
     57  1.1.1.2.8.1       tls #include "sysdep.h"
     58          1.1     skrll #include "bfd.h"
     59          1.1     skrll 
     60  1.1.1.2.8.1       tls /* All that ..._PRE and ...POST functions are called from the corresponding
     61  1.1.1.2.8.1       tls    coff_swap... functions. The ...PRE functions are called at the beginning
     62  1.1.1.2.8.1       tls    of the function and the ...POST functions at the end of the swap routines.  */
     63          1.1     skrll 
     64          1.1     skrll static void
     65  1.1.1.2.8.1       tls adjust_filehdr_in_post  (bfd *, void *, void *);
     66          1.1     skrll static void
     67  1.1.1.2.8.1       tls adjust_filehdr_out_pre  (bfd *, void *, void *);
     68          1.1     skrll static void
     69  1.1.1.2.8.1       tls adjust_filehdr_out_post  (bfd *, void *, void *);
     70          1.1     skrll static void
     71  1.1.1.2.8.1       tls adjust_scnhdr_in_post  (bfd *, void *, void *);
     72          1.1     skrll static void
     73  1.1.1.2.8.1       tls adjust_scnhdr_out_pre  (bfd *, void *, void *);
     74          1.1     skrll static void
     75  1.1.1.2.8.1       tls adjust_scnhdr_out_post (bfd *, void *, void *);
     76          1.1     skrll static void
     77  1.1.1.2.8.1       tls adjust_aux_in_post (bfd *, void *, int, int, int, int, void *);
     78          1.1     skrll static void
     79  1.1.1.2.8.1       tls adjust_aux_out_pre (bfd *, void *, int, int, int, int, void *);
     80          1.1     skrll static void
     81  1.1.1.2.8.1       tls adjust_aux_out_post (bfd *, void *, int, int, int, int, void *);
     82          1.1     skrll static void
     83  1.1.1.2.8.1       tls create_go32_stub (bfd *);
     84          1.1     skrll 
     85          1.1     skrll #define COFF_ADJUST_FILEHDR_IN_POST adjust_filehdr_in_post
     86          1.1     skrll #define COFF_ADJUST_FILEHDR_OUT_PRE adjust_filehdr_out_pre
     87          1.1     skrll #define COFF_ADJUST_FILEHDR_OUT_POST adjust_filehdr_out_post
     88          1.1     skrll 
     89          1.1     skrll #define COFF_ADJUST_SCNHDR_IN_POST adjust_scnhdr_in_post
     90          1.1     skrll #define COFF_ADJUST_SCNHDR_OUT_PRE adjust_scnhdr_out_pre
     91          1.1     skrll #define COFF_ADJUST_SCNHDR_OUT_POST adjust_scnhdr_out_post
     92          1.1     skrll 
     93          1.1     skrll #define COFF_ADJUST_AUX_IN_POST adjust_aux_in_post
     94          1.1     skrll #define COFF_ADJUST_AUX_OUT_PRE adjust_aux_out_pre
     95          1.1     skrll #define COFF_ADJUST_AUX_OUT_POST adjust_aux_out_post
     96          1.1     skrll 
     97  1.1.1.2.8.1       tls static const bfd_target *go32_check_format (bfd *);
     98  1.1.1.2.8.1       tls 
     99  1.1.1.2.8.1       tls #define COFF_CHECK_FORMAT go32_check_format
    100  1.1.1.2.8.1       tls 
    101          1.1     skrll static bfd_boolean
    102  1.1.1.2.8.1       tls   go32_stubbed_coff_bfd_copy_private_bfd_data (bfd *, bfd *);
    103          1.1     skrll 
    104          1.1     skrll #define coff_bfd_copy_private_bfd_data go32_stubbed_coff_bfd_copy_private_bfd_data
    105          1.1     skrll 
    106          1.1     skrll #include "coff-i386.c"
    107          1.1     skrll 
    108  1.1.1.2.8.1       tls /* This macro is used, because I cannot assume the endianness of the
    109          1.1     skrll    host system.  */
    110  1.1.1.2.8.1       tls #define _H(index) (H_GET_16 (abfd, (header + index * 2)))
    111          1.1     skrll 
    112          1.1     skrll /* These bytes are a 2048-byte DOS executable, which loads the COFF
    113          1.1     skrll    image into memory and then runs it. It is called 'stub'.  */
    114          1.1     skrll 
    115      1.1.1.2  christos static const unsigned char stub_bytes[GO32_STUBSIZE] =
    116          1.1     skrll {
    117          1.1     skrll #include "go32stub.h"
    118          1.1     skrll };
    119          1.1     skrll 
    120          1.1     skrll /*
    121          1.1     skrll    I have not commented each swap function below, because the
    122          1.1     skrll    technique is in any function the same. For the ...in function,
    123      1.1.1.2  christos    all the pointers are adjusted by adding GO32_STUBSIZE and for the
    124          1.1     skrll    ...out function, it is subtracted first and after calling the
    125          1.1     skrll    standard swap function it is reset to the old value.  */
    126          1.1     skrll 
    127          1.1     skrll /* This macro is used for adjusting the filepointers, which
    128          1.1     skrll    is done only, if the pointer is nonzero.  */
    129          1.1     skrll 
    130          1.1     skrll #define ADJUST_VAL(val,diff) \
    131          1.1     skrll   if (val != 0) val += diff
    132          1.1     skrll 
    133          1.1     skrll static void
    134  1.1.1.2.8.1       tls adjust_filehdr_in_post  (bfd *  abfd ATTRIBUTE_UNUSED,
    135  1.1.1.2.8.1       tls 			 void * src,
    136  1.1.1.2.8.1       tls 			 void * dst)
    137          1.1     skrll {
    138          1.1     skrll   FILHDR *filehdr_src = (FILHDR *) src;
    139          1.1     skrll   struct internal_filehdr *filehdr_dst = (struct internal_filehdr *) dst;
    140          1.1     skrll 
    141      1.1.1.2  christos   ADJUST_VAL (filehdr_dst->f_symptr, GO32_STUBSIZE);
    142          1.1     skrll 
    143      1.1.1.2  christos   /* Save now the stub to be used later.  Put the stub data to FILEHDR_DST
    144      1.1.1.2  christos      first as coff_data (abfd) still does not exist.  It may not even be ever
    145      1.1.1.2  christos      created as we are just checking the file format of ABFD.  */
    146      1.1.1.2  christos   memcpy (filehdr_dst->go32stub, filehdr_src->stub, GO32_STUBSIZE);
    147      1.1.1.2  christos   filehdr_dst->f_flags |= F_GO32STUB;
    148          1.1     skrll }
    149          1.1     skrll 
    150          1.1     skrll static void
    151  1.1.1.2.8.1       tls adjust_filehdr_out_pre  (bfd * abfd, void * in, void * out)
    152          1.1     skrll {
    153          1.1     skrll   struct internal_filehdr *filehdr_in = (struct internal_filehdr *) in;
    154          1.1     skrll   FILHDR *filehdr_out = (FILHDR *) out;
    155          1.1     skrll 
    156          1.1     skrll   /* Generate the stub.  */
    157          1.1     skrll   create_go32_stub (abfd);
    158          1.1     skrll 
    159          1.1     skrll   /* Copy the stub to the file header.  */
    160      1.1.1.2  christos   if (coff_data (abfd)->go32stub != NULL)
    161      1.1.1.2  christos     memcpy (filehdr_out->stub, coff_data (abfd)->go32stub, GO32_STUBSIZE);
    162          1.1     skrll   else
    163          1.1     skrll     /* Use the default.  */
    164      1.1.1.2  christos     memcpy (filehdr_out->stub, stub_bytes, GO32_STUBSIZE);
    165          1.1     skrll 
    166      1.1.1.2  christos   ADJUST_VAL (filehdr_in->f_symptr, -GO32_STUBSIZE);
    167          1.1     skrll }
    168          1.1     skrll 
    169          1.1     skrll static void
    170  1.1.1.2.8.1       tls adjust_filehdr_out_post  (bfd *  abfd ATTRIBUTE_UNUSED,
    171  1.1.1.2.8.1       tls 			  void * in,
    172  1.1.1.2.8.1       tls 			  void * out ATTRIBUTE_UNUSED)
    173          1.1     skrll {
    174          1.1     skrll   struct internal_filehdr *filehdr_in = (struct internal_filehdr *) in;
    175          1.1     skrll   /* Undo the above change.  */
    176      1.1.1.2  christos   ADJUST_VAL (filehdr_in->f_symptr, GO32_STUBSIZE);
    177          1.1     skrll }
    178          1.1     skrll 
    179          1.1     skrll static void
    180  1.1.1.2.8.1       tls adjust_scnhdr_in_post  (bfd *  abfd ATTRIBUTE_UNUSED,
    181  1.1.1.2.8.1       tls 			void * ext ATTRIBUTE_UNUSED,
    182  1.1.1.2.8.1       tls 			void * in)
    183          1.1     skrll {
    184          1.1     skrll   struct internal_scnhdr *scnhdr_int = (struct internal_scnhdr *) in;
    185          1.1     skrll 
    186      1.1.1.2  christos   ADJUST_VAL (scnhdr_int->s_scnptr, GO32_STUBSIZE);
    187      1.1.1.2  christos   ADJUST_VAL (scnhdr_int->s_relptr, GO32_STUBSIZE);
    188      1.1.1.2  christos   ADJUST_VAL (scnhdr_int->s_lnnoptr, GO32_STUBSIZE);
    189          1.1     skrll }
    190          1.1     skrll 
    191          1.1     skrll static void
    192  1.1.1.2.8.1       tls adjust_scnhdr_out_pre  (bfd *  abfd ATTRIBUTE_UNUSED,
    193  1.1.1.2.8.1       tls 			void * in,
    194  1.1.1.2.8.1       tls 			void * out ATTRIBUTE_UNUSED)
    195          1.1     skrll {
    196          1.1     skrll   struct internal_scnhdr *scnhdr_int = (struct internal_scnhdr *) in;
    197          1.1     skrll 
    198      1.1.1.2  christos   ADJUST_VAL (scnhdr_int->s_scnptr, -GO32_STUBSIZE);
    199      1.1.1.2  christos   ADJUST_VAL (scnhdr_int->s_relptr, -GO32_STUBSIZE);
    200      1.1.1.2  christos   ADJUST_VAL (scnhdr_int->s_lnnoptr, -GO32_STUBSIZE);
    201          1.1     skrll }
    202          1.1     skrll 
    203          1.1     skrll static void
    204  1.1.1.2.8.1       tls adjust_scnhdr_out_post (bfd *  abfd ATTRIBUTE_UNUSED,
    205  1.1.1.2.8.1       tls 			void * in,
    206  1.1.1.2.8.1       tls 			void * out ATTRIBUTE_UNUSED)
    207          1.1     skrll {
    208          1.1     skrll   struct internal_scnhdr *scnhdr_int = (struct internal_scnhdr *) in;
    209          1.1     skrll 
    210      1.1.1.2  christos   ADJUST_VAL (scnhdr_int->s_scnptr, GO32_STUBSIZE);
    211      1.1.1.2  christos   ADJUST_VAL (scnhdr_int->s_relptr, GO32_STUBSIZE);
    212      1.1.1.2  christos   ADJUST_VAL (scnhdr_int->s_lnnoptr, GO32_STUBSIZE);
    213          1.1     skrll }
    214          1.1     skrll 
    215          1.1     skrll static void
    216  1.1.1.2.8.1       tls adjust_aux_in_post (bfd * abfd ATTRIBUTE_UNUSED,
    217  1.1.1.2.8.1       tls 		    void * ext1 ATTRIBUTE_UNUSED,
    218  1.1.1.2.8.1       tls 		    int type,
    219  1.1.1.2.8.1       tls 		    int in_class,
    220  1.1.1.2.8.1       tls 		    int indx ATTRIBUTE_UNUSED,
    221  1.1.1.2.8.1       tls 		    int numaux ATTRIBUTE_UNUSED,
    222  1.1.1.2.8.1       tls 		    void * in1)
    223          1.1     skrll {
    224          1.1     skrll   union internal_auxent *in = (union internal_auxent *) in1;
    225          1.1     skrll 
    226      1.1.1.2  christos   if (in_class == C_BLOCK || in_class == C_FCN || ISFCN (type)
    227      1.1.1.2  christos       || ISTAG (in_class))
    228          1.1     skrll     {
    229      1.1.1.2  christos       ADJUST_VAL (in->x_sym.x_fcnary.x_fcn.x_lnnoptr, GO32_STUBSIZE);
    230          1.1     skrll     }
    231          1.1     skrll }
    232          1.1     skrll 
    233          1.1     skrll static void
    234  1.1.1.2.8.1       tls adjust_aux_out_pre (bfd *abfd ATTRIBUTE_UNUSED,
    235  1.1.1.2.8.1       tls 		    void * inp,
    236  1.1.1.2.8.1       tls 		    int type,
    237  1.1.1.2.8.1       tls 		    int in_class,
    238  1.1.1.2.8.1       tls 		    int indx ATTRIBUTE_UNUSED,
    239  1.1.1.2.8.1       tls 		    int numaux ATTRIBUTE_UNUSED,
    240  1.1.1.2.8.1       tls 		    void * extp ATTRIBUTE_UNUSED)
    241          1.1     skrll {
    242          1.1     skrll   union internal_auxent *in = (union internal_auxent *) inp;
    243          1.1     skrll 
    244      1.1.1.2  christos   if (in_class == C_BLOCK || in_class == C_FCN || ISFCN (type)
    245      1.1.1.2  christos       || ISTAG (in_class))
    246          1.1     skrll     {
    247      1.1.1.2  christos       ADJUST_VAL (in->x_sym.x_fcnary.x_fcn.x_lnnoptr, -GO32_STUBSIZE);
    248          1.1     skrll     }
    249          1.1     skrll }
    250          1.1     skrll 
    251          1.1     skrll static void
    252  1.1.1.2.8.1       tls adjust_aux_out_post (bfd *abfd ATTRIBUTE_UNUSED,
    253  1.1.1.2.8.1       tls 		     void * inp,
    254  1.1.1.2.8.1       tls 		     int type,
    255  1.1.1.2.8.1       tls 		     int in_class,
    256  1.1.1.2.8.1       tls 		     int indx ATTRIBUTE_UNUSED,
    257  1.1.1.2.8.1       tls 		     int numaux ATTRIBUTE_UNUSED,
    258  1.1.1.2.8.1       tls 		     void * extp ATTRIBUTE_UNUSED)
    259          1.1     skrll {
    260          1.1     skrll   union internal_auxent *in = (union internal_auxent *) inp;
    261          1.1     skrll 
    262      1.1.1.2  christos   if (in_class == C_BLOCK || in_class == C_FCN || ISFCN (type)
    263      1.1.1.2  christos       || ISTAG (in_class))
    264          1.1     skrll     {
    265      1.1.1.2  christos       ADJUST_VAL (in->x_sym.x_fcnary.x_fcn.x_lnnoptr, GO32_STUBSIZE);
    266          1.1     skrll     }
    267          1.1     skrll }
    268          1.1     skrll 
    269          1.1     skrll /* That's the function, which creates the stub. There are
    270          1.1     skrll    different cases from where the stub is taken.
    271          1.1     skrll    At first the environment variable $(GO32STUB) is checked and then
    272          1.1     skrll    $(STUB) if it was not set.
    273          1.1     skrll    If it exists and points to a valid stub the stub is taken from
    274          1.1     skrll    that file. This file can be also a whole executable file, because
    275          1.1     skrll    the stub is computed from the exe information at the start of that
    276          1.1     skrll    file.
    277          1.1     skrll 
    278          1.1     skrll    If there was any error, the standard stub (compiled in this file)
    279          1.1     skrll    is taken.  */
    280          1.1     skrll 
    281          1.1     skrll static void
    282  1.1.1.2.8.1       tls create_go32_stub (bfd *abfd)
    283          1.1     skrll {
    284          1.1     skrll   /* Do it only once.  */
    285      1.1.1.2  christos   if (coff_data (abfd)->go32stub == NULL)
    286          1.1     skrll     {
    287          1.1     skrll       char *stub;
    288          1.1     skrll       struct stat st;
    289          1.1     skrll       int f;
    290          1.1     skrll       unsigned char header[10];
    291          1.1     skrll       char magic[8];
    292          1.1     skrll       unsigned long coff_start;
    293          1.1     skrll       long exe_start;
    294          1.1     skrll 
    295          1.1     skrll       /* Check at first the environment variable $(GO32STUB).  */
    296          1.1     skrll       stub = getenv ("GO32STUB");
    297          1.1     skrll       /* Now check the environment variable $(STUB).  */
    298          1.1     skrll       if (stub == NULL)
    299          1.1     skrll 	stub = getenv ("STUB");
    300          1.1     skrll       if (stub == NULL)
    301          1.1     skrll 	goto stub_end;
    302          1.1     skrll       if (stat (stub, &st) != 0)
    303          1.1     skrll 	goto stub_end;
    304          1.1     skrll #ifdef O_BINARY
    305          1.1     skrll       f = open (stub, O_RDONLY | O_BINARY);
    306          1.1     skrll #else
    307          1.1     skrll       f = open (stub, O_RDONLY);
    308          1.1     skrll #endif
    309          1.1     skrll       if (f < 0)
    310          1.1     skrll 	goto stub_end;
    311          1.1     skrll       if (read (f, &header, sizeof (header)) < 0)
    312          1.1     skrll 	{
    313          1.1     skrll 	  close (f);
    314          1.1     skrll 	  goto stub_end;
    315          1.1     skrll 	}
    316          1.1     skrll       if (_H (0) != 0x5a4d)	/* It is not an exe file.  */
    317          1.1     skrll 	{
    318          1.1     skrll 	  close (f);
    319          1.1     skrll 	  goto stub_end;
    320          1.1     skrll 	}
    321          1.1     skrll       /* Compute the size of the stub (it is every thing up
    322          1.1     skrll          to the beginning of the coff image).  */
    323          1.1     skrll       coff_start = (long) _H (2) * 512L;
    324          1.1     skrll       if (_H (1))
    325          1.1     skrll 	coff_start += (long) _H (1) - 512L;
    326          1.1     skrll 
    327          1.1     skrll       /* Currently there is only a fixed stub size of 2048 bytes
    328          1.1     skrll          supported.  */
    329          1.1     skrll       if (coff_start != 2048)
    330          1.1     skrll 	{
    331          1.1     skrll 	  close (f);
    332          1.1     skrll 	  goto stub_end;
    333          1.1     skrll 	}
    334          1.1     skrll       exe_start = _H (4) * 16;
    335          1.1     skrll       if ((long) lseek (f, exe_start, SEEK_SET) != exe_start)
    336          1.1     skrll 	{
    337          1.1     skrll 	  close (f);
    338          1.1     skrll 	  goto stub_end;
    339          1.1     skrll 	}
    340          1.1     skrll       if (read (f, &magic, 8) != 8)
    341          1.1     skrll 	{
    342          1.1     skrll 	  close (f);
    343          1.1     skrll 	  goto stub_end;
    344          1.1     skrll 	}
    345          1.1     skrll       if (! CONST_STRNEQ (magic, "go32stub"))
    346          1.1     skrll 	{
    347          1.1     skrll 	  close (f);
    348          1.1     skrll 	  goto stub_end;
    349          1.1     skrll 	}
    350          1.1     skrll       /* Now we found a correct stub (hopefully).  */
    351      1.1.1.2  christos       coff_data (abfd)->go32stub = bfd_alloc (abfd, (bfd_size_type) coff_start);
    352      1.1.1.2  christos       if (coff_data (abfd)->go32stub == NULL)
    353          1.1     skrll 	{
    354          1.1     skrll 	  close (f);
    355          1.1     skrll 	  return;
    356          1.1     skrll 	}
    357          1.1     skrll       lseek (f, 0L, SEEK_SET);
    358      1.1.1.2  christos       if ((unsigned long) read (f, coff_data (abfd)->go32stub, coff_start)
    359          1.1     skrll 	  != coff_start)
    360          1.1     skrll 	{
    361      1.1.1.2  christos 	  bfd_release (abfd, coff_data (abfd)->go32stub);
    362      1.1.1.2  christos 	  coff_data (abfd)->go32stub = NULL;
    363          1.1     skrll 	}
    364          1.1     skrll       close (f);
    365          1.1     skrll     }
    366          1.1     skrll stub_end:
    367          1.1     skrll   /* There was something wrong above, so use now the standard builtin
    368          1.1     skrll      stub.  */
    369      1.1.1.2  christos   if (coff_data (abfd)->go32stub == NULL)
    370          1.1     skrll     {
    371      1.1.1.2  christos       coff_data (abfd)->go32stub
    372      1.1.1.2  christos 	= bfd_alloc (abfd, (bfd_size_type) GO32_STUBSIZE);
    373      1.1.1.2  christos       if (coff_data (abfd)->go32stub == NULL)
    374          1.1     skrll 	return;
    375      1.1.1.2  christos       memcpy (coff_data (abfd)->go32stub, stub_bytes, GO32_STUBSIZE);
    376          1.1     skrll     }
    377          1.1     skrll }
    378          1.1     skrll 
    379          1.1     skrll /* If ibfd was a stubbed coff image, copy the stub from that bfd
    380          1.1     skrll    to the new obfd.  */
    381          1.1     skrll 
    382          1.1     skrll static bfd_boolean
    383  1.1.1.2.8.1       tls go32_stubbed_coff_bfd_copy_private_bfd_data (bfd *ibfd, bfd *obfd)
    384          1.1     skrll {
    385          1.1     skrll   /* Check if both are the same targets.  */
    386          1.1     skrll   if (ibfd->xvec != obfd->xvec)
    387          1.1     skrll     return TRUE;
    388          1.1     skrll 
    389      1.1.1.2  christos   /* Check if we have a source stub.  */
    390      1.1.1.2  christos   if (coff_data (ibfd)->go32stub == NULL)
    391          1.1     skrll     return TRUE;
    392          1.1     skrll 
    393      1.1.1.2  christos   /* As adjust_filehdr_out_pre may get called only after this function,
    394      1.1.1.2  christos      optionally allocate the output stub.  */
    395      1.1.1.2  christos   if (coff_data (obfd)->go32stub == NULL)
    396      1.1.1.2  christos     coff_data (obfd)->go32stub = bfd_alloc (obfd,
    397      1.1.1.2  christos 					  (bfd_size_type) GO32_STUBSIZE);
    398      1.1.1.2  christos 
    399          1.1     skrll   /* Now copy the stub.  */
    400      1.1.1.2  christos   if (coff_data (obfd)->go32stub != NULL)
    401      1.1.1.2  christos     memcpy (coff_data (obfd)->go32stub, coff_data (ibfd)->go32stub,
    402      1.1.1.2  christos 	    GO32_STUBSIZE);
    403          1.1     skrll 
    404          1.1     skrll   return TRUE;
    405          1.1     skrll }
    406  1.1.1.2.8.1       tls 
    407  1.1.1.2.8.1       tls /* coff_object_p only checks 2 bytes F_MAGIC at GO32_STUBSIZE inside the file
    408  1.1.1.2.8.1       tls    which is too fragile.  */
    409  1.1.1.2.8.1       tls 
    410  1.1.1.2.8.1       tls static const bfd_target *
    411  1.1.1.2.8.1       tls go32_check_format (bfd *abfd)
    412  1.1.1.2.8.1       tls {
    413  1.1.1.2.8.1       tls   char mz[2];
    414  1.1.1.2.8.1       tls 
    415  1.1.1.2.8.1       tls   if (bfd_bread (mz, 2, abfd) != 2 || mz[0] != 'M' || mz[1] != 'Z')
    416  1.1.1.2.8.1       tls     {
    417  1.1.1.2.8.1       tls       bfd_set_error (bfd_error_wrong_format);
    418  1.1.1.2.8.1       tls       return NULL;
    419  1.1.1.2.8.1       tls     }
    420  1.1.1.2.8.1       tls 
    421  1.1.1.2.8.1       tls   if (bfd_seek (abfd, 0, SEEK_SET) != 0)
    422  1.1.1.2.8.1       tls     return NULL;
    423  1.1.1.2.8.1       tls 
    424  1.1.1.2.8.1       tls   return coff_object_p (abfd);
    425  1.1.1.2.8.1       tls }
    426