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