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

Subversion Repositories scarts

[/] [scarts/] [trunk/] [toolchain/] [scarts-binutils/] [binutils-2.19.1/] [bfd/] [coff-stgo32.c] - Blame information for rev 6

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 6 jlechner
/* BFD back-end for Intel 386 COFF files (DJGPP variant with a stub).
2
   Copyright 1997, 1998, 1999, 2000, 2001, 2002, 2006, 2007
3
   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
static bfd_boolean
99
  go32_stubbed_coff_bfd_copy_private_bfd_data PARAMS ((bfd *, bfd *));
100
 
101
#define coff_bfd_copy_private_bfd_data go32_stubbed_coff_bfd_copy_private_bfd_data
102
 
103
#include "coff-i386.c"
104
 
105
/* I hold in the usrdata the stub.  */
106
#define bfd_coff_go32stub bfd_usrdata
107
 
108
/* This macro is used, because I cannot assume the endianess of the
109
   host system.  */
110
#define _H(index) (H_GET_16 (abfd, (header+index*2)))
111
 
112
/* These bytes are a 2048-byte DOS executable, which loads the COFF
113
   image into memory and then runs it. It is called 'stub'.  */
114
 
115
static const unsigned char stub_bytes[STUBSIZE] =
116
{
117
#include "go32stub.h"
118
};
119
 
120
/*
121
   I have not commented each swap function below, because the
122
   technique is in any function the same. For the ...in function,
123
   all the pointers are adjusted by adding STUBSIZE and for the
124
   ...out function, it is subtracted first and after calling the
125
   standard swap function it is reset to the old value.  */
126
 
127
/* This macro is used for adjusting the filepointers, which
128
   is done only, if the pointer is nonzero.  */
129
 
130
#define ADJUST_VAL(val,diff) \
131
  if (val != 0) val += diff
132
 
133
static void
134
adjust_filehdr_in_post  (abfd, src, dst)
135
     bfd *abfd;
136
     PTR src;
137
     PTR dst;
138
{
139
  FILHDR *filehdr_src = (FILHDR *) src;
140
  struct internal_filehdr *filehdr_dst = (struct internal_filehdr *) dst;
141
 
142
  ADJUST_VAL (filehdr_dst->f_symptr, STUBSIZE);
143
 
144
  /* Save now the stub to be used later.  */
145
  bfd_coff_go32stub (abfd) = (PTR) bfd_alloc (abfd, (bfd_size_type) STUBSIZE);
146
 
147
  /* Since this function returns no status, I do not set here
148
     any bfd_error_...
149
     That means, before the use of bfd_coff_go32stub (), this value
150
     should be checked if it is != NULL.  */
151
  if (bfd_coff_go32stub (abfd) == NULL)
152
    return;
153
  memcpy (bfd_coff_go32stub (abfd), filehdr_src->stub, STUBSIZE);
154
}
155
 
156
static void
157
adjust_filehdr_out_pre  (abfd, in, out)
158
     bfd *abfd;
159
     PTR in;
160
     PTR out;
161
{
162
  struct internal_filehdr *filehdr_in = (struct internal_filehdr *) in;
163
  FILHDR *filehdr_out = (FILHDR *) out;
164
 
165
  /* Generate the stub.  */
166
  create_go32_stub (abfd);
167
 
168
  /* Copy the stub to the file header.  */
169
  if (bfd_coff_go32stub (abfd) != NULL)
170
    memcpy (filehdr_out->stub, bfd_coff_go32stub (abfd), STUBSIZE);
171
  else
172
    /* Use the default.  */
173
    memcpy (filehdr_out->stub, stub_bytes, STUBSIZE);
174
 
175
  ADJUST_VAL (filehdr_in->f_symptr, -STUBSIZE);
176
}
177
 
178
static void
179
adjust_filehdr_out_post  (abfd, in, out)
180
     bfd *abfd ATTRIBUTE_UNUSED;
181
     PTR in;
182
     PTR out ATTRIBUTE_UNUSED;
183
{
184
  struct internal_filehdr *filehdr_in = (struct internal_filehdr *) in;
185
  /* Undo the above change.  */
186
  ADJUST_VAL (filehdr_in->f_symptr, STUBSIZE);
187
}
188
 
189
static void
190
adjust_scnhdr_in_post  (abfd, ext, in)
191
     bfd *abfd ATTRIBUTE_UNUSED;
192
     PTR ext ATTRIBUTE_UNUSED;
193
     PTR in;
194
{
195
  struct internal_scnhdr *scnhdr_int = (struct internal_scnhdr *) in;
196
 
197
  ADJUST_VAL (scnhdr_int->s_scnptr, STUBSIZE);
198
  ADJUST_VAL (scnhdr_int->s_relptr, STUBSIZE);
199
  ADJUST_VAL (scnhdr_int->s_lnnoptr, STUBSIZE);
200
}
201
 
202
static void
203
adjust_scnhdr_out_pre  (abfd, in, out)
204
     bfd *abfd ATTRIBUTE_UNUSED;
205
     PTR in;
206
     PTR out ATTRIBUTE_UNUSED;
207
{
208
  struct internal_scnhdr *scnhdr_int = (struct internal_scnhdr *) in;
209
 
210
  ADJUST_VAL (scnhdr_int->s_scnptr, -STUBSIZE);
211
  ADJUST_VAL (scnhdr_int->s_relptr, -STUBSIZE);
212
  ADJUST_VAL (scnhdr_int->s_lnnoptr, -STUBSIZE);
213
}
214
 
215
static void
216
adjust_scnhdr_out_post (abfd, in, out)
217
     bfd *abfd ATTRIBUTE_UNUSED;
218
     PTR in;
219
     PTR out ATTRIBUTE_UNUSED;
220
{
221
  struct internal_scnhdr *scnhdr_int = (struct internal_scnhdr *) in;
222
 
223
  ADJUST_VAL (scnhdr_int->s_scnptr, STUBSIZE);
224
  ADJUST_VAL (scnhdr_int->s_relptr, STUBSIZE);
225
  ADJUST_VAL (scnhdr_int->s_lnnoptr, STUBSIZE);
226
}
227
 
228
static void
229
adjust_aux_in_post  (abfd, ext1, type, class, indx, numaux, in1)
230
     bfd *abfd ATTRIBUTE_UNUSED;
231
     PTR ext1 ATTRIBUTE_UNUSED;
232
     int type;
233
     int class;
234
     int indx ATTRIBUTE_UNUSED;
235
     int numaux ATTRIBUTE_UNUSED;
236
     PTR in1;
237
{
238
  union internal_auxent *in = (union internal_auxent *) in1;
239
 
240
  if (class == C_BLOCK || class == C_FCN || ISFCN (type) || ISTAG (class))
241
    {
242
      ADJUST_VAL (in->x_sym.x_fcnary.x_fcn.x_lnnoptr, STUBSIZE);
243
    }
244
}
245
 
246
static void
247
adjust_aux_out_pre  (abfd, inp, type, class, indx, numaux, extp)
248
     bfd *abfd ATTRIBUTE_UNUSED;
249
     PTR inp;
250
     int type;
251
     int class;
252
     int indx ATTRIBUTE_UNUSED;
253
     int numaux ATTRIBUTE_UNUSED;
254
     PTR extp ATTRIBUTE_UNUSED;
255
{
256
  union internal_auxent *in = (union internal_auxent *) inp;
257
 
258
  if (class == C_BLOCK || class == C_FCN || ISFCN (type) || ISTAG (class))
259
    {
260
      ADJUST_VAL (in->x_sym.x_fcnary.x_fcn.x_lnnoptr, -STUBSIZE);
261
    }
262
}
263
 
264
static void
265
adjust_aux_out_post (abfd, inp, type, class, indx, numaux, extp)
266
     bfd *abfd ATTRIBUTE_UNUSED;
267
     PTR inp;
268
     int type;
269
     int class;
270
     int indx ATTRIBUTE_UNUSED;
271
     int numaux ATTRIBUTE_UNUSED;
272
     PTR extp ATTRIBUTE_UNUSED;
273
{
274
  union internal_auxent *in = (union internal_auxent *) inp;
275
 
276
  if (class == C_BLOCK || class == C_FCN || ISFCN (type) || ISTAG (class))
277
    {
278
      ADJUST_VAL (in->x_sym.x_fcnary.x_fcn.x_lnnoptr, STUBSIZE);
279
    }
280
}
281
 
282
/* That's the function, which creates the stub. There are
283
   different cases from where the stub is taken.
284
   At first the environment variable $(GO32STUB) is checked and then
285
   $(STUB) if it was not set.
286
   If it exists and points to a valid stub the stub is taken from
287
   that file. This file can be also a whole executable file, because
288
   the stub is computed from the exe information at the start of that
289
   file.
290
 
291
   If there was any error, the standard stub (compiled in this file)
292
   is taken.  */
293
 
294
static void
295
create_go32_stub (abfd)
296
     bfd *abfd;
297
{
298
  /* Do it only once.  */
299
  if (bfd_coff_go32stub (abfd) == NULL)
300
    {
301
      char *stub;
302
      struct stat st;
303
      int f;
304
      unsigned char header[10];
305
      char magic[8];
306
      unsigned long coff_start;
307
      long exe_start;
308
 
309
      /* Check at first the environment variable $(GO32STUB).  */
310
      stub = getenv ("GO32STUB");
311
      /* Now check the environment variable $(STUB).  */
312
      if (stub == NULL)
313
        stub = getenv ("STUB");
314
      if (stub == NULL)
315
        goto stub_end;
316
      if (stat (stub, &st) != 0)
317
        goto stub_end;
318
#ifdef O_BINARY
319
      f = open (stub, O_RDONLY | O_BINARY);
320
#else
321
      f = open (stub, O_RDONLY);
322
#endif
323
      if (f < 0)
324
        goto stub_end;
325
      if (read (f, &header, sizeof (header)) < 0)
326
        {
327
          close (f);
328
          goto stub_end;
329
        }
330
      if (_H (0) != 0x5a4d)      /* It is not an exe file.  */
331
        {
332
          close (f);
333
          goto stub_end;
334
        }
335
      /* Compute the size of the stub (it is every thing up
336
         to the beginning of the coff image).  */
337
      coff_start = (long) _H (2) * 512L;
338
      if (_H (1))
339
        coff_start += (long) _H (1) - 512L;
340
 
341
      /* Currently there is only a fixed stub size of 2048 bytes
342
         supported.  */
343
      if (coff_start != 2048)
344
        {
345
          close (f);
346
          goto stub_end;
347
        }
348
      exe_start = _H (4) * 16;
349
      if ((long) lseek (f, exe_start, SEEK_SET) != exe_start)
350
        {
351
          close (f);
352
          goto stub_end;
353
        }
354
      if (read (f, &magic, 8) != 8)
355
        {
356
          close (f);
357
          goto stub_end;
358
        }
359
      if (! CONST_STRNEQ (magic, "go32stub"))
360
        {
361
          close (f);
362
          goto stub_end;
363
        }
364
      /* Now we found a correct stub (hopefully).  */
365
      bfd_coff_go32stub (abfd)
366
        = (PTR) bfd_alloc (abfd, (bfd_size_type) coff_start);
367
      if (bfd_coff_go32stub (abfd) == NULL)
368
        {
369
          close (f);
370
          return;
371
        }
372
      lseek (f, 0L, SEEK_SET);
373
      if ((unsigned long) read (f, bfd_coff_go32stub (abfd), coff_start)
374
          != coff_start)
375
        {
376
          bfd_release (abfd, bfd_coff_go32stub (abfd));
377
          bfd_coff_go32stub (abfd) = NULL;
378
        }
379
      close (f);
380
    }
381
stub_end:
382
  /* There was something wrong above, so use now the standard builtin
383
     stub.  */
384
  if (bfd_coff_go32stub (abfd) == NULL)
385
    {
386
      bfd_coff_go32stub (abfd)
387
        = (PTR) bfd_alloc (abfd, (bfd_size_type) STUBSIZE);
388
      if (bfd_coff_go32stub (abfd) == NULL)
389
        return;
390
      memcpy (bfd_coff_go32stub (abfd), stub_bytes, STUBSIZE);
391
    }
392
}
393
 
394
/* If ibfd was a stubbed coff image, copy the stub from that bfd
395
   to the new obfd.  */
396
 
397
static bfd_boolean
398
go32_stubbed_coff_bfd_copy_private_bfd_data  (ibfd, obfd)
399
     bfd *ibfd;
400
     bfd *obfd;
401
{
402
  /* Check if both are the same targets.  */
403
  if (ibfd->xvec != obfd->xvec)
404
    return TRUE;
405
 
406
  /* Check if both have a valid stub.  */
407
  if (bfd_coff_go32stub (ibfd) == NULL
408
      || bfd_coff_go32stub (obfd) == NULL)
409
    return TRUE;
410
 
411
  /* Now copy the stub.  */
412
  memcpy (bfd_coff_go32stub (obfd), bfd_coff_go32stub (ibfd), STUBSIZE);
413
 
414
  return TRUE;
415
}

powered by: WebSVN 2.1.0

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