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

Subversion Repositories or1k

[/] [or1k/] [tags/] [VER_5_3/] [gdb-5.3/] [bfd/] [coff-stgo32.c] - Blame information for rev 1765

Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

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