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

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-stable/] [binutils-2.20.1/] [bfd/] [coff-stgo32.c] - Blame information for rev 843

Go to most recent revision | Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

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