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

Subversion Repositories or1k

[/] [or1k/] [branches/] [oc/] [gdb-5.0/] [bfd/] [coff-stgo32.c] - Blame information for rev 1765

Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

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