OpenCores
URL https://opencores.org/ocsvn/open8_urisc/open8_urisc/trunk

Subversion Repositories open8_urisc

[/] [open8_urisc/] [trunk/] [gnu/] [binutils/] [bfd/] [coff-stgo32.c] - Blame information for rev 161

Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.