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

Subversion Repositories or1k

[/] [or1k/] [tags/] [start/] [gdb-5.0/] [bfd/] [peigen.c] - Blame information for rev 1778

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

Line No. Rev Author Line
1 104 markom
/* Support for the generic parts of PE/PEI; the common executable parts.
2
   Copyright 1995, 1996, 1997, 1998, 1999 Free Software Foundation, Inc.
3
   Written by Cygnus Solutions.
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
/*
22
Most of this hacked by  Steve Chamberlain,
23
                        sac@cygnus.com
24
 
25
PE/PEI rearrangement (and code added): Donn Terry
26
                                       Softway Systems, Inc.
27
*/
28
 
29
/* Hey look, some documentation [and in a place you expect to find it]!
30
 
31
   The main reference for the pei format is "Microsoft Portable Executable
32
   and Common Object File Format Specification 4.1".  Get it if you need to
33
   do some serious hacking on this code.
34
 
35
   Another reference:
36
   "Peering Inside the PE: A Tour of the Win32 Portable Executable
37
   File Format", MSJ 1994, Volume 9.
38
 
39
   The *sole* difference between the pe format and the pei format is that the
40
   latter has an MSDOS 2.0 .exe header on the front that prints the message
41
   "This app must be run under Windows." (or some such).
42
   (FIXME: Whether that statement is *really* true or not is unknown.
43
   Are there more subtle differences between pe and pei formats?
44
   For now assume there aren't.  If you find one, then for God sakes
45
   document it here!)
46
 
47
   The Microsoft docs use the word "image" instead of "executable" because
48
   the former can also refer to a DLL (shared library).  Confusion can arise
49
   because the `i' in `pei' also refers to "image".  The `pe' format can
50
   also create images (i.e. executables), it's just that to run on a win32
51
   system you need to use the pei format.
52
 
53
   FIXME: Please add more docs here so the next poor fool that has to hack
54
   on this code has a chance of getting something accomplished without
55
   wasting too much time.
56
*/
57
 
58
#include "bfd.h"
59
#include "sysdep.h"
60
#include "libbfd.h"
61
#include "coff/internal.h"
62
 
63
/* NOTE: it's strange to be including an architecture specific header
64
   in what's supposed to be general (to PE/PEI) code.  However, that's
65
   where the definitions are, and they don't vary per architecture
66
   within PE/PEI, so we get them from there.  FIXME: The lack of
67
   variance is an assumption which may prove to be incorrect if new
68
   PE/PEI targets are created.  */
69
#include "coff/i386.h"
70
 
71
#include "coff/pe.h"
72
#include "libcoff.h"
73
#include "libpei.h"
74
 
75
/* FIXME: This file has various tests of POWERPC_LE_PE.  Those tests
76
   worked when the code was in peicode.h, but no longer work now that
77
   the code is in peigen.c.  PowerPC NT is said to be dead.  If
78
   anybody wants to revive the code, you will have to figure out how
79
   to handle those issues.  */
80
 
81
static void add_data_entry
82
  PARAMS ((bfd *, struct internal_extra_pe_aouthdr *, int, char *, bfd_vma));
83
static boolean pe_print_pdata PARAMS ((bfd *, PTR));
84
static boolean pe_print_reloc PARAMS ((bfd *, PTR));
85
 
86
/**********************************************************************/
87
 
88
void
89
_bfd_pei_swap_sym_in (abfd, ext1, in1)
90
     bfd *abfd;
91
     PTR ext1;
92
     PTR in1;
93
{
94
  SYMENT *ext = (SYMENT *)ext1;
95
  struct internal_syment      *in = (struct internal_syment *)in1;
96
 
97
  if( ext->e.e_name[0] == 0) {
98
    in->_n._n_n._n_zeroes = 0;
99
    in->_n._n_n._n_offset = bfd_h_get_32(abfd, (bfd_byte *) ext->e.e.e_offset);
100
  }
101
  else {
102
    memcpy(in->_n._n_name, ext->e.e_name, SYMNMLEN);
103
  }
104
 
105
  in->n_value = bfd_h_get_32(abfd, (bfd_byte *) ext->e_value);
106
  in->n_scnum = bfd_h_get_16(abfd, (bfd_byte *) ext->e_scnum);
107
  if (sizeof(ext->e_type) == 2){
108
    in->n_type = bfd_h_get_16(abfd, (bfd_byte *) ext->e_type);
109
  }
110
  else {
111
    in->n_type = bfd_h_get_32(abfd, (bfd_byte *) ext->e_type);
112
  }
113
  in->n_sclass = bfd_h_get_8(abfd, ext->e_sclass);
114
  in->n_numaux = bfd_h_get_8(abfd, ext->e_numaux);
115
 
116
#ifndef STRICT_PE_FORMAT
117
  /* This is for Gnu-created DLLs */
118
 
119
  /* The section symbols for the .idata$ sections have class 0x68
120
     (C_SECTION), which MS documentation indicates is a section
121
     symbol.  Unfortunately, the value field in the symbol is simply a
122
     copy of the .idata section's flags rather than something useful.
123
     When these symbols are encountered, change the value to 0 so that
124
     they will be handled somewhat correctly in the bfd code.  */
125
  if (in->n_sclass == C_SECTION)
126
    {
127
      in->n_value = 0x0;
128
 
129
#if 0
130
      /* FIXME: This is clearly wrong.  The problem seems to be that
131
         undefined C_SECTION symbols appear in the first object of a
132
         MS generated .lib file, and the symbols are not defined
133
         anywhere.  */
134
      in->n_scnum = 1;
135
 
136
      /* I have tried setting the class to 3 and using the following
137
         to set the section number.  This will put the address of the
138
         pointer to the string kernel32.dll at addresses 0 and 0x10
139
         off start of idata section which is not correct */
140
      /*    if (strcmp (in->_n._n_name, ".idata$4") == 0) */
141
      /*      in->n_scnum = 3; */
142
      /*    else */
143
      /*      in->n_scnum = 2; */
144
#else
145
      /* Create synthetic empty sections as needed.  DJ */
146
      if (in->n_scnum == 0)
147
        {
148
          asection *sec;
149
          for (sec=abfd->sections; sec; sec=sec->next)
150
            {
151
              if (strcmp (sec->name, in->n_name) == 0)
152
                {
153
                  in->n_scnum = sec->target_index;
154
                  break;
155
                }
156
            }
157
        }
158
      if (in->n_scnum == 0)
159
        {
160
          int unused_section_number = 0;
161
          asection *sec;
162
          char *name;
163
          for (sec=abfd->sections; sec; sec=sec->next)
164
            if (unused_section_number <= sec->target_index)
165
              unused_section_number = sec->target_index+1;
166
 
167
          name = bfd_alloc (abfd, strlen (in->n_name) + 10);
168
          if (name == NULL)
169
            return;
170
          strcpy (name, in->n_name);
171
          sec = bfd_make_section_anyway (abfd, name);
172
 
173
          sec->vma = 0;
174
          sec->lma = 0;
175
          sec->_cooked_size = 0;
176
          sec->_raw_size = 0;
177
          sec->filepos = 0;
178
          sec->rel_filepos = 0;
179
          sec->reloc_count = 0;
180
          sec->line_filepos = 0;
181
          sec->lineno_count = 0;
182
          sec->userdata = NULL;
183
          sec->next = (asection *) NULL;
184
          sec->flags = 0;
185
          sec->alignment_power = 2;
186
          sec->flags = SEC_HAS_CONTENTS | SEC_ALLOC | SEC_DATA | SEC_LOAD;
187
 
188
          sec->target_index = unused_section_number;
189
 
190
          in->n_scnum = unused_section_number;
191
        }
192
      in->n_sclass = C_STAT;
193
#endif
194
    }
195
#endif
196
 
197
#ifdef coff_swap_sym_in_hook
198
  /* This won't work in peigen.c, but since it's for PPC PE, it's not
199
     worth fixing. */
200
  coff_swap_sym_in_hook(abfd, ext1, in1);
201
#endif
202
}
203
 
204
unsigned int
205
_bfd_pei_swap_sym_out (abfd, inp, extp)
206
     bfd       *abfd;
207
     PTR        inp;
208
     PTR        extp;
209
{
210
  struct internal_syment *in = (struct internal_syment *)inp;
211
  SYMENT *ext =(SYMENT *)extp;
212
  if(in->_n._n_name[0] == 0) {
213
    bfd_h_put_32(abfd, 0, (bfd_byte *) ext->e.e.e_zeroes);
214
    bfd_h_put_32(abfd, in->_n._n_n._n_offset, (bfd_byte *)  ext->e.e.e_offset);
215
  }
216
  else {
217
    memcpy(ext->e.e_name, in->_n._n_name, SYMNMLEN);
218
  }
219
 
220
  bfd_h_put_32(abfd,  in->n_value , (bfd_byte *) ext->e_value);
221
  bfd_h_put_16(abfd,  in->n_scnum , (bfd_byte *) ext->e_scnum);
222
  if (sizeof(ext->e_type) == 2)
223
    {
224
      bfd_h_put_16(abfd,  in->n_type , (bfd_byte *) ext->e_type);
225
    }
226
  else
227
    {
228
      bfd_h_put_32(abfd,  in->n_type , (bfd_byte *) ext->e_type);
229
    }
230
  bfd_h_put_8(abfd,  in->n_sclass , ext->e_sclass);
231
  bfd_h_put_8(abfd,  in->n_numaux , ext->e_numaux);
232
 
233
  return SYMESZ;
234
}
235
 
236
void
237
_bfd_pei_swap_aux_in (abfd, ext1, type, class, indx, numaux, in1)
238
     bfd            *abfd;
239
     PTR             ext1;
240
     int             type;
241
     int             class;
242
     int             indx ATTRIBUTE_UNUSED;
243
     int             numaux ATTRIBUTE_UNUSED;
244
     PTR             in1;
245
{
246
  AUXENT    *ext = (AUXENT *)ext1;
247
  union internal_auxent *in = (union internal_auxent *)in1;
248
 
249
  switch (class) {
250
  case C_FILE:
251
    if (ext->x_file.x_fname[0] == 0) {
252
      in->x_file.x_n.x_zeroes = 0;
253
      in->x_file.x_n.x_offset =
254
        bfd_h_get_32(abfd, (bfd_byte *) ext->x_file.x_n.x_offset);
255
    } else {
256
      memcpy (in->x_file.x_fname, ext->x_file.x_fname, FILNMLEN);
257
    }
258
    return;
259
 
260
 
261
  case C_STAT:
262
  case C_LEAFSTAT:
263
  case C_HIDDEN:
264
    if (type == T_NULL) {
265
      in->x_scn.x_scnlen = GET_SCN_SCNLEN(abfd, ext);
266
      in->x_scn.x_nreloc = GET_SCN_NRELOC(abfd, ext);
267
      in->x_scn.x_nlinno = GET_SCN_NLINNO(abfd, ext);
268
      in->x_scn.x_checksum = bfd_h_get_32 (abfd,
269
                                           (bfd_byte *) ext->x_scn.x_checksum);
270
      in->x_scn.x_associated =
271
        bfd_h_get_16 (abfd, (bfd_byte *) ext->x_scn.x_associated);
272
      in->x_scn.x_comdat = bfd_h_get_8 (abfd,
273
                                        (bfd_byte *) ext->x_scn.x_comdat);
274
      return;
275
    }
276
    break;
277
  }
278
 
279
  in->x_sym.x_tagndx.l = bfd_h_get_32(abfd, (bfd_byte *) ext->x_sym.x_tagndx);
280
  in->x_sym.x_tvndx = bfd_h_get_16(abfd, (bfd_byte *) ext->x_sym.x_tvndx);
281
 
282
  if (class == C_BLOCK || class == C_FCN || ISFCN (type) || ISTAG (class))
283
    {
284
      in->x_sym.x_fcnary.x_fcn.x_lnnoptr = GET_FCN_LNNOPTR (abfd, ext);
285
      in->x_sym.x_fcnary.x_fcn.x_endndx.l = GET_FCN_ENDNDX (abfd, ext);
286
    }
287
  else
288
    {
289
      in->x_sym.x_fcnary.x_ary.x_dimen[0] =
290
        bfd_h_get_16 (abfd, (bfd_byte *) ext->x_sym.x_fcnary.x_ary.x_dimen[0]);
291
      in->x_sym.x_fcnary.x_ary.x_dimen[1] =
292
        bfd_h_get_16 (abfd, (bfd_byte *) ext->x_sym.x_fcnary.x_ary.x_dimen[1]);
293
      in->x_sym.x_fcnary.x_ary.x_dimen[2] =
294
        bfd_h_get_16 (abfd, (bfd_byte *) ext->x_sym.x_fcnary.x_ary.x_dimen[2]);
295
      in->x_sym.x_fcnary.x_ary.x_dimen[3] =
296
        bfd_h_get_16 (abfd, (bfd_byte *) ext->x_sym.x_fcnary.x_ary.x_dimen[3]);
297
    }
298
 
299
  if (ISFCN(type)) {
300
    in->x_sym.x_misc.x_fsize = bfd_h_get_32(abfd, (bfd_byte *) ext->x_sym.x_misc.x_fsize);
301
  }
302
  else {
303
    in->x_sym.x_misc.x_lnsz.x_lnno = GET_LNSZ_LNNO(abfd, ext);
304
    in->x_sym.x_misc.x_lnsz.x_size = GET_LNSZ_SIZE(abfd, ext);
305
  }
306
}
307
 
308
unsigned int
309
_bfd_pei_swap_aux_out (abfd, inp, type, class, indx, numaux, extp)
310
     bfd  *abfd;
311
     PTR   inp;
312
     int   type;
313
     int   class;
314
     int   indx ATTRIBUTE_UNUSED;
315
     int   numaux ATTRIBUTE_UNUSED;
316
     PTR   extp;
317
{
318
  union internal_auxent *in = (union internal_auxent *)inp;
319
  AUXENT *ext = (AUXENT *)extp;
320
 
321
  memset((PTR)ext, 0, AUXESZ);
322
  switch (class) {
323
  case C_FILE:
324
    if (in->x_file.x_fname[0] == 0) {
325
      bfd_h_put_32(abfd, 0, (bfd_byte *) ext->x_file.x_n.x_zeroes);
326
      bfd_h_put_32(abfd,
327
              in->x_file.x_n.x_offset,
328
              (bfd_byte *) ext->x_file.x_n.x_offset);
329
    }
330
    else {
331
      memcpy (ext->x_file.x_fname, in->x_file.x_fname, FILNMLEN);
332
    }
333
    return AUXESZ;
334
 
335
 
336
  case C_STAT:
337
  case C_LEAFSTAT:
338
  case C_HIDDEN:
339
    if (type == T_NULL) {
340
      PUT_SCN_SCNLEN(abfd, in->x_scn.x_scnlen, ext);
341
      PUT_SCN_NRELOC(abfd, in->x_scn.x_nreloc, ext);
342
      PUT_SCN_NLINNO(abfd, in->x_scn.x_nlinno, ext);
343
      bfd_h_put_32 (abfd, in->x_scn.x_checksum,
344
                    (bfd_byte *) ext->x_scn.x_checksum);
345
      bfd_h_put_16 (abfd, in->x_scn.x_associated,
346
                    (bfd_byte *) ext->x_scn.x_associated);
347
      bfd_h_put_8 (abfd, in->x_scn.x_comdat,
348
                   (bfd_byte *) ext->x_scn.x_comdat);
349
      return AUXESZ;
350
    }
351
    break;
352
  }
353
 
354
  bfd_h_put_32(abfd, in->x_sym.x_tagndx.l, (bfd_byte *) ext->x_sym.x_tagndx);
355
  bfd_h_put_16(abfd, in->x_sym.x_tvndx , (bfd_byte *) ext->x_sym.x_tvndx);
356
 
357
  if (class == C_BLOCK || class == C_FCN || ISFCN (type) || ISTAG (class))
358
    {
359
      PUT_FCN_LNNOPTR(abfd,  in->x_sym.x_fcnary.x_fcn.x_lnnoptr, ext);
360
      PUT_FCN_ENDNDX(abfd,  in->x_sym.x_fcnary.x_fcn.x_endndx.l, ext);
361
    }
362
  else
363
    {
364
      bfd_h_put_16 (abfd, in->x_sym.x_fcnary.x_ary.x_dimen[0],
365
                    (bfd_byte *) ext->x_sym.x_fcnary.x_ary.x_dimen[0]);
366
      bfd_h_put_16 (abfd, in->x_sym.x_fcnary.x_ary.x_dimen[1],
367
                    (bfd_byte *) ext->x_sym.x_fcnary.x_ary.x_dimen[1]);
368
      bfd_h_put_16 (abfd, in->x_sym.x_fcnary.x_ary.x_dimen[2],
369
                    (bfd_byte *) ext->x_sym.x_fcnary.x_ary.x_dimen[2]);
370
      bfd_h_put_16 (abfd, in->x_sym.x_fcnary.x_ary.x_dimen[3],
371
                    (bfd_byte *) ext->x_sym.x_fcnary.x_ary.x_dimen[3]);
372
    }
373
 
374
  if (ISFCN (type))
375
    bfd_h_put_32 (abfd, in->x_sym.x_misc.x_fsize,
376
             (bfd_byte *)  ext->x_sym.x_misc.x_fsize);
377
  else
378
    {
379
      PUT_LNSZ_LNNO (abfd, in->x_sym.x_misc.x_lnsz.x_lnno, ext);
380
      PUT_LNSZ_SIZE (abfd, in->x_sym.x_misc.x_lnsz.x_size, ext);
381
    }
382
 
383
  return AUXESZ;
384
}
385
 
386
void
387
_bfd_pei_swap_lineno_in (abfd, ext1, in1)
388
     bfd *abfd;
389
     PTR ext1;
390
     PTR in1;
391
{
392
  LINENO *ext = (LINENO *)ext1;
393
  struct internal_lineno      *in = (struct internal_lineno *)in1;
394
 
395
  in->l_addr.l_symndx = bfd_h_get_32(abfd, (bfd_byte *) ext->l_addr.l_symndx);
396
  in->l_lnno = GET_LINENO_LNNO(abfd, ext);
397
}
398
 
399
unsigned int
400
_bfd_pei_swap_lineno_out (abfd, inp, outp)
401
     bfd       *abfd;
402
     PTR        inp;
403
     PTR        outp;
404
{
405
  struct internal_lineno *in = (struct internal_lineno *)inp;
406
  struct external_lineno *ext = (struct external_lineno *)outp;
407
  bfd_h_put_32(abfd, in->l_addr.l_symndx, (bfd_byte *)
408
          ext->l_addr.l_symndx);
409
 
410
  PUT_LINENO_LNNO (abfd, in->l_lnno, ext);
411
  return LINESZ;
412
}
413
 
414
void
415
_bfd_pei_swap_aouthdr_in (abfd, aouthdr_ext1, aouthdr_int1)
416
     bfd *abfd;
417
     PTR aouthdr_ext1;
418
     PTR aouthdr_int1;
419
{
420
  struct internal_extra_pe_aouthdr *a;
421
  PEAOUTHDR *src = (PEAOUTHDR *)(aouthdr_ext1);
422
  AOUTHDR        *aouthdr_ext = (AOUTHDR *) aouthdr_ext1;
423
  struct internal_aouthdr *aouthdr_int = (struct internal_aouthdr *)aouthdr_int1;
424
 
425
  aouthdr_int->magic = bfd_h_get_16(abfd, (bfd_byte *) aouthdr_ext->magic);
426
  aouthdr_int->vstamp = bfd_h_get_16(abfd, (bfd_byte *) aouthdr_ext->vstamp);
427
  aouthdr_int->tsize =
428
    GET_AOUTHDR_TSIZE (abfd, (bfd_byte *) aouthdr_ext->tsize);
429
  aouthdr_int->dsize =
430
    GET_AOUTHDR_DSIZE (abfd, (bfd_byte *) aouthdr_ext->dsize);
431
  aouthdr_int->bsize =
432
    GET_AOUTHDR_BSIZE (abfd, (bfd_byte *) aouthdr_ext->bsize);
433
  aouthdr_int->entry =
434
    GET_AOUTHDR_ENTRY (abfd, (bfd_byte *) aouthdr_ext->entry);
435
  aouthdr_int->text_start =
436
    GET_AOUTHDR_TEXT_START (abfd, (bfd_byte *) aouthdr_ext->text_start);
437
  aouthdr_int->data_start =
438
    GET_AOUTHDR_DATA_START (abfd, (bfd_byte *) aouthdr_ext->data_start);
439
 
440
  a = &aouthdr_int->pe;
441
  a->ImageBase = bfd_h_get_32 (abfd, (bfd_byte *)src->ImageBase);
442
  a->SectionAlignment = bfd_h_get_32 (abfd, (bfd_byte *)src->SectionAlignment);
443
  a->FileAlignment = bfd_h_get_32 (abfd, (bfd_byte *)src->FileAlignment);
444
  a->MajorOperatingSystemVersion =
445
    bfd_h_get_16 (abfd, (bfd_byte *)src->MajorOperatingSystemVersion);
446
  a->MinorOperatingSystemVersion =
447
    bfd_h_get_16 (abfd, (bfd_byte *)src->MinorOperatingSystemVersion);
448
  a->MajorImageVersion = bfd_h_get_16 (abfd, (bfd_byte *)src->MajorImageVersion);
449
  a->MinorImageVersion = bfd_h_get_16 (abfd, (bfd_byte *)src->MinorImageVersion);
450
  a->MajorSubsystemVersion = bfd_h_get_16 (abfd, (bfd_byte *)src->MajorSubsystemVersion);
451
  a->MinorSubsystemVersion = bfd_h_get_16 (abfd, (bfd_byte *)src->MinorSubsystemVersion);
452
  a->Reserved1 = bfd_h_get_32 (abfd, (bfd_byte *)src->Reserved1);
453
  a->SizeOfImage = bfd_h_get_32 (abfd, (bfd_byte *)src->SizeOfImage);
454
  a->SizeOfHeaders = bfd_h_get_32 (abfd, (bfd_byte *)src->SizeOfHeaders);
455
  a->CheckSum = bfd_h_get_32 (abfd, (bfd_byte *)src->CheckSum);
456
  a->Subsystem = bfd_h_get_16 (abfd, (bfd_byte *)src->Subsystem);
457
  a->DllCharacteristics = bfd_h_get_16 (abfd, (bfd_byte *)src->DllCharacteristics);
458
  a->SizeOfStackReserve = bfd_h_get_32 (abfd, (bfd_byte *)src->SizeOfStackReserve);
459
  a->SizeOfStackCommit = bfd_h_get_32 (abfd, (bfd_byte *)src->SizeOfStackCommit);
460
  a->SizeOfHeapReserve = bfd_h_get_32 (abfd, (bfd_byte *)src->SizeOfHeapReserve);
461
  a->SizeOfHeapCommit = bfd_h_get_32 (abfd, (bfd_byte *)src->SizeOfHeapCommit);
462
  a->LoaderFlags = bfd_h_get_32 (abfd, (bfd_byte *)src->LoaderFlags);
463
  a->NumberOfRvaAndSizes = bfd_h_get_32 (abfd, (bfd_byte *)src->NumberOfRvaAndSizes);
464
 
465
  {
466
    int idx;
467
    for (idx=0; idx < 16; idx++)
468
      {
469
        a->DataDirectory[idx].VirtualAddress =
470
          bfd_h_get_32 (abfd, (bfd_byte *)src->DataDirectory[idx][0]);
471
        a->DataDirectory[idx].Size =
472
          bfd_h_get_32 (abfd, (bfd_byte *)src->DataDirectory[idx][1]);
473
      }
474
  }
475
 
476
  if (aouthdr_int->entry)
477
    {
478
      aouthdr_int->entry += a->ImageBase;
479
      aouthdr_int->entry &= 0xffffffff;
480
    }
481
  if (aouthdr_int->tsize)
482
    {
483
      aouthdr_int->text_start += a->ImageBase;
484
      aouthdr_int->text_start &= 0xffffffff;
485
    }
486
  if (aouthdr_int->dsize)
487
    {
488
      aouthdr_int->data_start += a->ImageBase;
489
      aouthdr_int->data_start &= 0xffffffff;
490
    }
491
 
492
#ifdef POWERPC_LE_PE
493
  /* These three fields are normally set up by ppc_relocate_section.
494
     In the case of reading a file in, we can pick them up from the
495
     DataDirectory.  */
496
  first_thunk_address = a->DataDirectory[12].VirtualAddress ;
497
  thunk_size = a->DataDirectory[12].Size;
498
  import_table_size = a->DataDirectory[1].Size;
499
#endif
500
 
501
}
502
 
503
/* A support function for below.  */
504
 
505
static void
506
add_data_entry (abfd, aout, idx, name, base)
507
     bfd *abfd;
508
     struct internal_extra_pe_aouthdr *aout;
509
     int idx;
510
     char *name;
511
     bfd_vma base;
512
{
513
  asection *sec = bfd_get_section_by_name (abfd, name);
514
 
515
  /* add import directory information if it exists */
516
  if ((sec != NULL)
517
      && (coff_section_data (abfd, sec) != NULL)
518
      && (pei_section_data (abfd, sec) != NULL))
519
    {
520
      aout->DataDirectory[idx].VirtualAddress = (sec->vma - base) & 0xffffffff;
521
      aout->DataDirectory[idx].Size = pei_section_data (abfd, sec)->virt_size;
522
      sec->flags |= SEC_DATA;
523
    }
524
}
525
 
526
unsigned int
527
_bfd_pei_swap_aouthdr_out (abfd, in, out)
528
     bfd       *abfd;
529
     PTR        in;
530
     PTR        out;
531
{
532
  struct internal_aouthdr *aouthdr_in = (struct internal_aouthdr *)in;
533
  struct internal_extra_pe_aouthdr *extra = &pe_data (abfd)->pe_opthdr;
534
  PEAOUTHDR *aouthdr_out = (PEAOUTHDR *)out;
535
 
536
  bfd_vma sa = extra->SectionAlignment;
537
  bfd_vma fa = extra->FileAlignment;
538
  bfd_vma ib = extra->ImageBase ;
539
 
540
  if (aouthdr_in->tsize)
541
    {
542
      aouthdr_in->text_start -= ib;
543
      aouthdr_in->text_start &= 0xffffffff;
544
    }
545
  if (aouthdr_in->dsize)
546
    {
547
      aouthdr_in->data_start -= ib;
548
      aouthdr_in->data_start &= 0xffffffff;
549
    }
550
  if (aouthdr_in->entry)
551
    {
552
      aouthdr_in->entry -= ib;
553
      aouthdr_in->entry &= 0xffffffff;
554
    }
555
 
556
#define FA(x)  (((x) + fa -1 ) & (- fa))
557
#define SA(x)  (((x) + sa -1 ) & (- sa))
558
 
559
  /* We like to have the sizes aligned */
560
 
561
  aouthdr_in->bsize = FA (aouthdr_in->bsize);
562
 
563
 
564
  extra->NumberOfRvaAndSizes = IMAGE_NUMBEROF_DIRECTORY_ENTRIES;
565
 
566
  /* first null out all data directory entries .. */
567
  memset (extra->DataDirectory, sizeof (extra->DataDirectory), 0);
568
 
569
  add_data_entry (abfd, extra, 0, ".edata", 0);
570
 
571
  /* Don't call add_data_entry for .idata$2 or .idata$5.  It's done in
572
     bfd_coff_final_link where all the required information is
573
     available.  */
574
 
575
  /* However, until other .idata fixes are made (pending patch), the
576
     entry for .idata is needed for backwards compatability.  FIXME.  */
577
  add_data_entry (abfd, extra, 1, ".idata" ,0);
578
 
579
  add_data_entry (abfd, extra, 2, ".rsrc" ,0);
580
 
581
  add_data_entry (abfd, extra, 3, ".pdata", 0);
582
 
583
  /* For some reason, the virtual size (which is what's set by
584
     add_data_entry) for .reloc is not the same as the size recorded
585
     in this slot by MSVC; it doesn't seem to cause problems (so far),
586
     but since it's the best we've got, use it.  It does do the right
587
     thing for .pdata.  */
588
  if (pe_data (abfd)->has_reloc_section)
589
    add_data_entry (abfd, extra, 5, ".reloc", 0);
590
 
591
  {
592
    asection *sec;
593
    bfd_vma dsize= 0;
594
    bfd_vma isize = SA(abfd->sections->filepos);
595
    bfd_vma tsize= 0;
596
 
597
    for (sec = abfd->sections; sec; sec = sec->next)
598
      {
599
        int rounded = FA(sec->_raw_size);
600
 
601
        if (sec->flags & SEC_DATA)
602
          dsize += rounded;
603
        if (sec->flags & SEC_CODE)
604
          tsize += rounded;
605
        /* The image size is the total VIRTUAL size (which is what is
606
           in the virt_size field).  Files have been seen (from MSVC
607
           5.0 link.exe) where the file size of the .data segment is
608
           quite small compared to the virtual size.  Without this
609
           fix, strip munges the file.  */
610
        isize += SA (FA (pei_section_data (abfd, sec)->virt_size));
611
      }
612
 
613
    aouthdr_in->dsize = dsize;
614
    aouthdr_in->tsize = tsize;
615
    extra->SizeOfImage = isize;
616
  }
617
 
618
  extra->SizeOfHeaders = abfd->sections->filepos;
619
  bfd_h_put_16(abfd, aouthdr_in->magic, (bfd_byte *) aouthdr_out->standard.magic);
620
 
621
#define LINKER_VERSION 256 /* That is, 2.56 */
622
 
623
  /* This piece of magic sets the "linker version" field to
624
     LINKER_VERSION.  */
625
  bfd_h_put_16 (abfd,
626
                LINKER_VERSION / 100 + (LINKER_VERSION % 100) * 256,
627
                (bfd_byte *) aouthdr_out->standard.vstamp);
628
 
629
  PUT_AOUTHDR_TSIZE (abfd, aouthdr_in->tsize, (bfd_byte *) aouthdr_out->standard.tsize);
630
  PUT_AOUTHDR_DSIZE (abfd, aouthdr_in->dsize, (bfd_byte *) aouthdr_out->standard.dsize);
631
  PUT_AOUTHDR_BSIZE (abfd, aouthdr_in->bsize, (bfd_byte *) aouthdr_out->standard.bsize);
632
  PUT_AOUTHDR_ENTRY (abfd, aouthdr_in->entry, (bfd_byte *) aouthdr_out->standard.entry);
633
  PUT_AOUTHDR_TEXT_START (abfd, aouthdr_in->text_start,
634
                          (bfd_byte *) aouthdr_out->standard.text_start);
635
 
636
  PUT_AOUTHDR_DATA_START (abfd, aouthdr_in->data_start,
637
                          (bfd_byte *) aouthdr_out->standard.data_start);
638
 
639
 
640
  bfd_h_put_32 (abfd, extra->ImageBase,
641
                (bfd_byte *) aouthdr_out->ImageBase);
642
  bfd_h_put_32 (abfd, extra->SectionAlignment,
643
                (bfd_byte *) aouthdr_out->SectionAlignment);
644
  bfd_h_put_32 (abfd, extra->FileAlignment,
645
                (bfd_byte *) aouthdr_out->FileAlignment);
646
  bfd_h_put_16 (abfd, extra->MajorOperatingSystemVersion,
647
                (bfd_byte *) aouthdr_out->MajorOperatingSystemVersion);
648
  bfd_h_put_16 (abfd, extra->MinorOperatingSystemVersion,
649
                (bfd_byte *) aouthdr_out->MinorOperatingSystemVersion);
650
  bfd_h_put_16 (abfd, extra->MajorImageVersion,
651
                (bfd_byte *) aouthdr_out->MajorImageVersion);
652
  bfd_h_put_16 (abfd, extra->MinorImageVersion,
653
                (bfd_byte *) aouthdr_out->MinorImageVersion);
654
  bfd_h_put_16 (abfd, extra->MajorSubsystemVersion,
655
                (bfd_byte *) aouthdr_out->MajorSubsystemVersion);
656
  bfd_h_put_16 (abfd, extra->MinorSubsystemVersion,
657
                (bfd_byte *) aouthdr_out->MinorSubsystemVersion);
658
  bfd_h_put_32 (abfd, extra->Reserved1,
659
                (bfd_byte *) aouthdr_out->Reserved1);
660
  bfd_h_put_32 (abfd, extra->SizeOfImage,
661
                (bfd_byte *) aouthdr_out->SizeOfImage);
662
  bfd_h_put_32 (abfd, extra->SizeOfHeaders,
663
                (bfd_byte *) aouthdr_out->SizeOfHeaders);
664
  bfd_h_put_32 (abfd, extra->CheckSum,
665
                (bfd_byte *) aouthdr_out->CheckSum);
666
  bfd_h_put_16 (abfd, extra->Subsystem,
667
                (bfd_byte *) aouthdr_out->Subsystem);
668
  bfd_h_put_16 (abfd, extra->DllCharacteristics,
669
                (bfd_byte *) aouthdr_out->DllCharacteristics);
670
  bfd_h_put_32 (abfd, extra->SizeOfStackReserve,
671
                (bfd_byte *) aouthdr_out->SizeOfStackReserve);
672
  bfd_h_put_32 (abfd, extra->SizeOfStackCommit,
673
                (bfd_byte *) aouthdr_out->SizeOfStackCommit);
674
  bfd_h_put_32 (abfd, extra->SizeOfHeapReserve,
675
                (bfd_byte *) aouthdr_out->SizeOfHeapReserve);
676
  bfd_h_put_32 (abfd, extra->SizeOfHeapCommit,
677
                (bfd_byte *) aouthdr_out->SizeOfHeapCommit);
678
  bfd_h_put_32 (abfd, extra->LoaderFlags,
679
                (bfd_byte *) aouthdr_out->LoaderFlags);
680
  bfd_h_put_32 (abfd, extra->NumberOfRvaAndSizes,
681
                (bfd_byte *) aouthdr_out->NumberOfRvaAndSizes);
682
  {
683
    int idx;
684
    for (idx=0; idx < 16; idx++)
685
      {
686
        bfd_h_put_32 (abfd, extra->DataDirectory[idx].VirtualAddress,
687
                      (bfd_byte *) aouthdr_out->DataDirectory[idx][0]);
688
        bfd_h_put_32 (abfd, extra->DataDirectory[idx].Size,
689
                      (bfd_byte *) aouthdr_out->DataDirectory[idx][1]);
690
      }
691
  }
692
 
693
  return AOUTSZ;
694
}
695
 
696
unsigned int
697
_bfd_pei_only_swap_filehdr_out (abfd, in, out)
698
     bfd       *abfd;
699
     PTR        in;
700
     PTR        out;
701
{
702
  int idx;
703
  struct internal_filehdr *filehdr_in = (struct internal_filehdr *)in;
704
  struct external_PEI_filehdr *filehdr_out = (struct external_PEI_filehdr *)out;
705
 
706
  if (pe_data (abfd)->has_reloc_section)
707
    filehdr_in->f_flags &= ~F_RELFLG;
708
 
709
  if (pe_data (abfd)->dll)
710
    filehdr_in->f_flags |= F_DLL;
711
 
712
  filehdr_in->pe.e_magic    = DOSMAGIC;
713
  filehdr_in->pe.e_cblp     = 0x90;
714
  filehdr_in->pe.e_cp       = 0x3;
715
  filehdr_in->pe.e_crlc     = 0x0;
716
  filehdr_in->pe.e_cparhdr  = 0x4;
717
  filehdr_in->pe.e_minalloc = 0x0;
718
  filehdr_in->pe.e_maxalloc = 0xffff;
719
  filehdr_in->pe.e_ss       = 0x0;
720
  filehdr_in->pe.e_sp       = 0xb8;
721
  filehdr_in->pe.e_csum     = 0x0;
722
  filehdr_in->pe.e_ip       = 0x0;
723
  filehdr_in->pe.e_cs       = 0x0;
724
  filehdr_in->pe.e_lfarlc   = 0x40;
725
  filehdr_in->pe.e_ovno     = 0x0;
726
 
727
  for (idx=0; idx < 4; idx++)
728
    filehdr_in->pe.e_res[idx] = 0x0;
729
 
730
  filehdr_in->pe.e_oemid   = 0x0;
731
  filehdr_in->pe.e_oeminfo = 0x0;
732
 
733
  for (idx=0; idx < 10; idx++)
734
    filehdr_in->pe.e_res2[idx] = 0x0;
735
 
736
  filehdr_in->pe.e_lfanew = 0x80;
737
 
738
  /* this next collection of data are mostly just characters.  It appears
739
     to be constant within the headers put on NT exes */
740
  filehdr_in->pe.dos_message[0]  = 0x0eba1f0e;
741
  filehdr_in->pe.dos_message[1]  = 0xcd09b400;
742
  filehdr_in->pe.dos_message[2]  = 0x4c01b821;
743
  filehdr_in->pe.dos_message[3]  = 0x685421cd;
744
  filehdr_in->pe.dos_message[4]  = 0x70207369;
745
  filehdr_in->pe.dos_message[5]  = 0x72676f72;
746
  filehdr_in->pe.dos_message[6]  = 0x63206d61;
747
  filehdr_in->pe.dos_message[7]  = 0x6f6e6e61;
748
  filehdr_in->pe.dos_message[8]  = 0x65622074;
749
  filehdr_in->pe.dos_message[9]  = 0x6e757220;
750
  filehdr_in->pe.dos_message[10] = 0x206e6920;
751
  filehdr_in->pe.dos_message[11] = 0x20534f44;
752
  filehdr_in->pe.dos_message[12] = 0x65646f6d;
753
  filehdr_in->pe.dos_message[13] = 0x0a0d0d2e;
754
  filehdr_in->pe.dos_message[14] = 0x24;
755
  filehdr_in->pe.dos_message[15] = 0x0;
756
  filehdr_in->pe.nt_signature = NT_SIGNATURE;
757
 
758
 
759
 
760
  bfd_h_put_16(abfd, filehdr_in->f_magic, (bfd_byte *) filehdr_out->f_magic);
761
  bfd_h_put_16(abfd, filehdr_in->f_nscns, (bfd_byte *) filehdr_out->f_nscns);
762
 
763
  bfd_h_put_32(abfd, time (0), (bfd_byte *) filehdr_out->f_timdat);
764
  PUT_FILEHDR_SYMPTR (abfd, (bfd_vma) filehdr_in->f_symptr,
765
                      (bfd_byte *) filehdr_out->f_symptr);
766
  bfd_h_put_32(abfd, filehdr_in->f_nsyms, (bfd_byte *) filehdr_out->f_nsyms);
767
  bfd_h_put_16(abfd, filehdr_in->f_opthdr, (bfd_byte *) filehdr_out->f_opthdr);
768
  bfd_h_put_16(abfd, filehdr_in->f_flags, (bfd_byte *) filehdr_out->f_flags);
769
 
770
  /* put in extra dos header stuff.  This data remains essentially
771
     constant, it just has to be tacked on to the beginning of all exes
772
     for NT */
773
  bfd_h_put_16(abfd, filehdr_in->pe.e_magic, (bfd_byte *) filehdr_out->e_magic);
774
  bfd_h_put_16(abfd, filehdr_in->pe.e_cblp, (bfd_byte *) filehdr_out->e_cblp);
775
  bfd_h_put_16(abfd, filehdr_in->pe.e_cp, (bfd_byte *) filehdr_out->e_cp);
776
  bfd_h_put_16(abfd, filehdr_in->pe.e_crlc, (bfd_byte *) filehdr_out->e_crlc);
777
  bfd_h_put_16(abfd, filehdr_in->pe.e_cparhdr,
778
               (bfd_byte *) filehdr_out->e_cparhdr);
779
  bfd_h_put_16(abfd, filehdr_in->pe.e_minalloc,
780
               (bfd_byte *) filehdr_out->e_minalloc);
781
  bfd_h_put_16(abfd, filehdr_in->pe.e_maxalloc,
782
               (bfd_byte *) filehdr_out->e_maxalloc);
783
  bfd_h_put_16(abfd, filehdr_in->pe.e_ss, (bfd_byte *) filehdr_out->e_ss);
784
  bfd_h_put_16(abfd, filehdr_in->pe.e_sp, (bfd_byte *) filehdr_out->e_sp);
785
  bfd_h_put_16(abfd, filehdr_in->pe.e_csum, (bfd_byte *) filehdr_out->e_csum);
786
  bfd_h_put_16(abfd, filehdr_in->pe.e_ip, (bfd_byte *) filehdr_out->e_ip);
787
  bfd_h_put_16(abfd, filehdr_in->pe.e_cs, (bfd_byte *) filehdr_out->e_cs);
788
  bfd_h_put_16(abfd, filehdr_in->pe.e_lfarlc, (bfd_byte *) filehdr_out->e_lfarlc);
789
  bfd_h_put_16(abfd, filehdr_in->pe.e_ovno, (bfd_byte *) filehdr_out->e_ovno);
790
  {
791
    int idx;
792
    for (idx=0; idx < 4; idx++)
793
      bfd_h_put_16(abfd, filehdr_in->pe.e_res[idx],
794
                   (bfd_byte *) filehdr_out->e_res[idx]);
795
  }
796
  bfd_h_put_16(abfd, filehdr_in->pe.e_oemid, (bfd_byte *) filehdr_out->e_oemid);
797
  bfd_h_put_16(abfd, filehdr_in->pe.e_oeminfo,
798
               (bfd_byte *) filehdr_out->e_oeminfo);
799
  {
800
    int idx;
801
    for (idx=0; idx < 10; idx++)
802
      bfd_h_put_16(abfd, filehdr_in->pe.e_res2[idx],
803
                   (bfd_byte *) filehdr_out->e_res2[idx]);
804
  }
805
  bfd_h_put_32(abfd, filehdr_in->pe.e_lfanew, (bfd_byte *) filehdr_out->e_lfanew);
806
 
807
  {
808
    int idx;
809
    for (idx=0; idx < 16; idx++)
810
      bfd_h_put_32(abfd, filehdr_in->pe.dos_message[idx],
811
                   (bfd_byte *) filehdr_out->dos_message[idx]);
812
  }
813
 
814
  /* also put in the NT signature */
815
  bfd_h_put_32(abfd, filehdr_in->pe.nt_signature,
816
               (bfd_byte *) filehdr_out->nt_signature);
817
 
818
 
819
 
820
 
821
  return FILHSZ;
822
}
823
 
824
unsigned int
825
_bfd_pe_only_swap_filehdr_out (abfd, in, out)
826
     bfd       *abfd;
827
     PTR        in;
828
     PTR        out;
829
{
830
  struct internal_filehdr *filehdr_in = (struct internal_filehdr *)in;
831
  FILHDR *filehdr_out = (FILHDR *)out;
832
 
833
  bfd_h_put_16(abfd, filehdr_in->f_magic, (bfd_byte *) filehdr_out->f_magic);
834
  bfd_h_put_16(abfd, filehdr_in->f_nscns, (bfd_byte *) filehdr_out->f_nscns);
835
  bfd_h_put_32(abfd, filehdr_in->f_timdat, (bfd_byte *) filehdr_out->f_timdat);
836
  PUT_FILEHDR_SYMPTR (abfd, (bfd_vma) filehdr_in->f_symptr,
837
                      (bfd_byte *) filehdr_out->f_symptr);
838
  bfd_h_put_32(abfd, filehdr_in->f_nsyms, (bfd_byte *) filehdr_out->f_nsyms);
839
  bfd_h_put_16(abfd, filehdr_in->f_opthdr, (bfd_byte *) filehdr_out->f_opthdr);
840
  bfd_h_put_16(abfd, filehdr_in->f_flags, (bfd_byte *) filehdr_out->f_flags);
841
 
842
  return FILHSZ;
843
}
844
 
845
unsigned int
846
_bfd_pei_swap_scnhdr_out (abfd, in, out)
847
     bfd       *abfd;
848
     PTR        in;
849
     PTR        out;
850
{
851
  struct internal_scnhdr *scnhdr_int = (struct internal_scnhdr *)in;
852
  SCNHDR *scnhdr_ext = (SCNHDR *)out;
853
  unsigned int ret = SCNHSZ;
854
  bfd_vma ps;
855
  bfd_vma ss;
856
 
857
  memcpy(scnhdr_ext->s_name, scnhdr_int->s_name, sizeof(scnhdr_int->s_name));
858
 
859
  PUT_SCNHDR_VADDR (abfd,
860
                    ((scnhdr_int->s_vaddr
861
                      - pe_data(abfd)->pe_opthdr.ImageBase)
862
                     & 0xffffffff),
863
                    (bfd_byte *) scnhdr_ext->s_vaddr);
864
 
865
  /* NT wants the size data to be rounded up to the next
866
     NT_FILE_ALIGNMENT, but zero if it has no content (as in .bss,
867
     sometimes).  */
868
 
869
  if ((scnhdr_int->s_flags & IMAGE_SCN_CNT_UNINITIALIZED_DATA) != 0)
870
    {
871
      ps = scnhdr_int->s_size;
872
      ss = 0;
873
    }
874
  else
875
    {
876
      ps = scnhdr_int->s_paddr;
877
      ss = scnhdr_int->s_size;
878
    }
879
 
880
  PUT_SCNHDR_SIZE (abfd, ss,
881
                   (bfd_byte *) scnhdr_ext->s_size);
882
 
883
 
884
  /* s_paddr in PE is really the virtual size.  */
885
  PUT_SCNHDR_PADDR (abfd, ps, (bfd_byte *) scnhdr_ext->s_paddr);
886
 
887
  PUT_SCNHDR_SCNPTR (abfd, scnhdr_int->s_scnptr,
888
                     (bfd_byte *) scnhdr_ext->s_scnptr);
889
  PUT_SCNHDR_RELPTR (abfd, scnhdr_int->s_relptr,
890
                     (bfd_byte *) scnhdr_ext->s_relptr);
891
  PUT_SCNHDR_LNNOPTR (abfd, scnhdr_int->s_lnnoptr,
892
                      (bfd_byte *) scnhdr_ext->s_lnnoptr);
893
 
894
  /* Extra flags must be set when dealing with NT.  All sections should also
895
     have the IMAGE_SCN_MEM_READ (0x40000000) flag set.  In addition, the
896
     .text section must have IMAGE_SCN_MEM_EXECUTE (0x20000000) and the data
897
     sections (.idata, .data, .bss, .CRT) must have IMAGE_SCN_MEM_WRITE set
898
     (this is especially important when dealing with the .idata section since
899
     the addresses for routines from .dlls must be overwritten).  If .reloc
900
     section data is ever generated, we must add IMAGE_SCN_MEM_DISCARDABLE
901
     (0x02000000).  Also, the resource data should also be read and
902
     writable.  */
903
 
904
  /* FIXME: alignment is also encoded in this field, at least on ppc (krk) */
905
  /* FIXME: even worse, I don't see how to get the original alignment field*/
906
  /*        back...                                                        */
907
 
908
  {
909
    int flags = scnhdr_int->s_flags;
910
    bfd_h_put_32(abfd, flags, (bfd_byte *) scnhdr_ext->s_flags);
911
  }
912
 
913
  if (coff_data (abfd)->link_info
914
      && ! coff_data (abfd)->link_info->relocateable
915
      && ! coff_data (abfd)->link_info->shared
916
      && strcmp (scnhdr_int->s_name, ".text") == 0)
917
    {
918
      /* By inference from looking at MS output, the 32 bit field
919
         which is the combintion of the number_of_relocs and
920
         number_of_linenos is used for the line number count in
921
         executables.  A 16-bit field won't do for cc1.  The MS
922
         document says that the number of relocs is zero for
923
         executables, but the 17-th bit has been observed to be there.
924
         Overflow is not an issue: a 4G-line program will overflow a
925
         bunch of other fields long before this!  */
926
      bfd_h_put_16 (abfd, scnhdr_int->s_nlnno & 0xffff,
927
                    (bfd_byte *) scnhdr_ext->s_nlnno);
928
      bfd_h_put_16 (abfd, scnhdr_int->s_nlnno >> 16,
929
                    (bfd_byte *) scnhdr_ext->s_nreloc);
930
    }
931
  else
932
    {
933
      if (scnhdr_int->s_nlnno <= 0xffff)
934
        bfd_h_put_16 (abfd, scnhdr_int->s_nlnno,
935
                      (bfd_byte *) scnhdr_ext->s_nlnno);
936
      else
937
        {
938
          (*_bfd_error_handler) (_("%s: line number overflow: 0x%lx > 0xffff"),
939
                                 bfd_get_filename (abfd),
940
                                 scnhdr_int->s_nlnno);
941
          bfd_set_error (bfd_error_file_truncated);
942
          bfd_h_put_16 (abfd, 0xffff, (bfd_byte *) scnhdr_ext->s_nlnno);
943
          ret = 0;
944
        }
945
      if (scnhdr_int->s_nreloc <= 0xffff)
946
        bfd_h_put_16 (abfd, scnhdr_int->s_nreloc,
947
                      (bfd_byte *) scnhdr_ext->s_nreloc);
948
      else
949
        {
950
          (*_bfd_error_handler) (_("%s: reloc overflow: 0x%lx > 0xffff"),
951
                                 bfd_get_filename (abfd),
952
                                 scnhdr_int->s_nreloc);
953
          bfd_set_error (bfd_error_file_truncated);
954
          bfd_h_put_16 (abfd, 0xffff, (bfd_byte *) scnhdr_ext->s_nreloc);
955
          ret = 0;
956
        }
957
    }
958
  return ret;
959
}
960
 
961
static char * dir_names[IMAGE_NUMBEROF_DIRECTORY_ENTRIES] =
962
{
963
  N_ ("Export Directory [.edata (or where ever we found it)]"),
964
  N_ ("Import Directory [parts of .idata]"),
965
  N_ ("Resource Directory [.rsrc]"),
966
  N_ ("Exception Directory [.pdata]"),
967
  N_ ("Security Directory"),
968
  N_ ("Base Relocation Directory [.reloc]"),
969
  N_ ("Debug Directory"),
970
  N_ ("Description Directory"),
971
  N_ ("Special Directory"),
972
  N_ ("Thread Storage Directory [.tls]"),
973
  N_ ("Load Configuration Directory"),
974
  N_ ("Bound Import Directory"),
975
  N_ ("Import Address Table Directory"),
976
  N_ ("Reserved"),
977
  N_ ("Reserved"),
978
  N_ ("Reserved")
979
};
980
 
981
/**********************************************************************/
982
#ifdef POWERPC_LE_PE
983
/* The code for the PPC really falls in the "architecture dependent"
984
   category.  However, it's not clear that anyone will ever care, so
985
   we're ignoring the issue for now; if/when PPC matters, some of this
986
   may need to go into peicode.h, or arguments passed to enable the
987
   PPC- specific code.  */
988
#endif
989
 
990
/**********************************************************************/
991
static boolean
992
pe_print_idata (abfd, vfile)
993
     bfd *abfd;
994
     PTR vfile;
995
{
996
  FILE *file = (FILE *) vfile;
997
  bfd_byte *data = 0;
998
  asection *section = bfd_get_section_by_name (abfd, ".idata");
999
  unsigned long adj;
1000
 
1001
#ifdef POWERPC_LE_PE
1002
  asection *rel_section = bfd_get_section_by_name (abfd, ".reldata");
1003
#endif
1004
 
1005
  bfd_size_type datasize;
1006
  bfd_size_type dataoff;
1007
  bfd_size_type secsize;
1008
  bfd_size_type i;
1009
  int onaline = 20;
1010
 
1011
  pe_data_type *pe = pe_data (abfd);
1012
  struct internal_extra_pe_aouthdr *extra = &pe->pe_opthdr;
1013
 
1014
  if (section != NULL)
1015
    {
1016
      datasize = bfd_section_size (abfd, section);
1017
      dataoff = 0;
1018
 
1019
      if (datasize == 0)
1020
        return true;
1021
 
1022
      fprintf (file, _("\nThe import table is the .idata section\n"));
1023
    }
1024
  else
1025
    {
1026
      /* idata buried in some other section: e.g. KERNEL32.DLL.  */
1027
      bfd_vma addr, size;
1028
 
1029
      addr = extra->DataDirectory[1].VirtualAddress;
1030
      size = extra->DataDirectory[1].Size;
1031
 
1032
      if (addr == 0 || size == 0)
1033
        return true;
1034
 
1035
      for (section = abfd->sections; section != NULL; section = section->next)
1036
        {
1037
           if (addr >= section->vma
1038
               && addr < section->vma + bfd_section_size(abfd,section))
1039
                 break;
1040
        }
1041
      if (section == NULL)
1042
        {
1043
           fprintf (file,
1044
                    _("\nThere is an import table, but the section containing it could not be found\n"));
1045
           return true;
1046
        }
1047
 
1048
      fprintf (file, _("\nThere is an import table in %s at 0x%lx\n"),
1049
               section->name, (unsigned long)addr);
1050
 
1051
      dataoff = addr - section->vma;
1052
      datasize = size;
1053
    }
1054
 
1055
#ifdef POWERPC_LE_PE
1056
  if (rel_section != 0 && bfd_section_size (abfd, rel_section) != 0)
1057
    {
1058
      /* The toc address can be found by taking the starting address,
1059
         which on the PPC locates a function descriptor. The
1060
         descriptor consists of the function code starting address
1061
         followed by the address of the toc. The starting address we
1062
         get from the bfd, and the descriptor is supposed to be in the
1063
         .reldata section.  */
1064
 
1065
      bfd_vma loadable_toc_address;
1066
      bfd_vma toc_address;
1067
      bfd_vma start_address;
1068
      bfd_byte *data = 0;
1069
      int offset;
1070
      data = (bfd_byte *) bfd_malloc ((size_t) bfd_section_size (abfd,
1071
                                                                 rel_section));
1072
      if (data == NULL && bfd_section_size (abfd, rel_section) != 0)
1073
        return false;
1074
 
1075
      datasize = bfd_section_size (abfd, rel_section);
1076
 
1077
      bfd_get_section_contents (abfd,
1078
                                rel_section,
1079
                                (PTR) data, 0,
1080
                                bfd_section_size (abfd, rel_section));
1081
 
1082
      offset = abfd->start_address - rel_section->vma;
1083
 
1084
      start_address = bfd_get_32(abfd, data+offset);
1085
      loadable_toc_address = bfd_get_32(abfd, data+offset+4);
1086
      toc_address = loadable_toc_address - 32768;
1087
 
1088
      fprintf(file,
1089
              _("\nFunction descriptor located at the start address: %04lx\n"),
1090
              (unsigned long int) (abfd->start_address));
1091
      fprintf (file,
1092
               _("\tcode-base %08lx toc (loadable/actual) %08lx/%08lx\n"),
1093
               start_address, loadable_toc_address, toc_address);
1094
    }
1095
  else
1096
    {
1097
      fprintf(file,
1098
              _("\nNo reldata section! Function descriptor not decoded.\n"));
1099
    }
1100
#endif
1101
 
1102
  fprintf(file,
1103
          _("\nThe Import Tables (interpreted .idata section contents)\n"));
1104
  fprintf(file,
1105
          _(" vma:            Hint    Time      Forward  DLL       First\n"));
1106
  fprintf(file,
1107
          _("                 Table   Stamp     Chain    Name      Thunk\n"));
1108
 
1109
  secsize = bfd_section_size (abfd, section);
1110
  data = (bfd_byte *) bfd_malloc (secsize);
1111
  if (data == NULL && secsize != 0)
1112
    return false;
1113
 
1114
  if (! bfd_get_section_contents (abfd, section, (PTR) data, 0, secsize))
1115
    return false;
1116
 
1117
  adj = - section->vma;
1118
 
1119
  for (i = 0; i < datasize; i += onaline)
1120
    {
1121
      bfd_vma hint_addr;
1122
      bfd_vma time_stamp;
1123
      bfd_vma forward_chain;
1124
      bfd_vma dll_name;
1125
      bfd_vma first_thunk;
1126
      int idx = 0;
1127
      bfd_size_type j;
1128
      char *dll;
1129
 
1130
      fprintf (file,
1131
               " %08lx\t",
1132
               (unsigned long int) (i + section->vma + dataoff));
1133
 
1134
      if (i + 20 > datasize)
1135
        {
1136
          /* check stuff */
1137
          ;
1138
        }
1139
 
1140
      hint_addr = bfd_get_32 (abfd, data + i + dataoff);
1141
      time_stamp = bfd_get_32 (abfd, data + i + 4 + dataoff);
1142
      forward_chain = bfd_get_32 (abfd, data + i + 8 + dataoff);
1143
      dll_name = bfd_get_32 (abfd, data + i + 12 + dataoff);
1144
      first_thunk = bfd_get_32 (abfd, data + i + 16 + dataoff);
1145
 
1146
      fprintf (file, "%08lx %08lx %08lx %08lx %08lx\n",
1147
               hint_addr,
1148
               time_stamp,
1149
               forward_chain,
1150
               dll_name,
1151
               first_thunk);
1152
 
1153
      if (hint_addr == 0 && first_thunk == 0)
1154
        break;
1155
 
1156
      dll = (char *) data + dll_name - section->vma + dataoff;
1157
      fprintf(file, _("\n\tDLL Name: %s\n"), dll);
1158
 
1159
      if (hint_addr != 0)
1160
        {
1161
          fprintf (file, _("\tvma:  Hint/Ord Member-Name\n"));
1162
 
1163
          idx = hint_addr + adj;
1164
 
1165
          for (j = 0; j < datasize; j += 4)
1166
            {
1167
              unsigned long member = bfd_get_32 (abfd, data + idx + j);
1168
 
1169
              if (member == 0)
1170
                break;
1171
              if (member & 0x80000000)
1172
                fprintf (file, "\t%04lx\t %4lu", member,
1173
                         member & 0x7fffffff);
1174
              else
1175
                {
1176
                  int ordinal;
1177
                  char *member_name;
1178
 
1179
                  ordinal = bfd_get_16 (abfd, data + member + adj);
1180
                  member_name = (char *) data + member + adj + 2;
1181
                  fprintf (file, "\t%04lx\t %4d  %s",
1182
                           member, ordinal, member_name);
1183
                }
1184
 
1185
              /* If the time stamp is not zero, the import address
1186
                 table holds actual addresses.  */
1187
              if (time_stamp != 0
1188
                  && first_thunk != 0
1189
                  && first_thunk != hint_addr)
1190
                fprintf (file, "\t%04lx",
1191
                         bfd_get_32 (abfd, data + first_thunk + adj + j));
1192
 
1193
              fprintf (file, "\n");
1194
            }
1195
        }
1196
 
1197
      if (hint_addr != first_thunk && time_stamp == 0)
1198
        {
1199
          int differ = 0;
1200
          int idx2;
1201
 
1202
          idx2 = first_thunk + adj;
1203
 
1204
          for (j = 0; j < datasize; j += 4)
1205
            {
1206
              int ordinal;
1207
              char *member_name;
1208
              bfd_vma hint_member = 0;
1209
              bfd_vma iat_member;
1210
 
1211
              if (hint_addr != 0)
1212
                hint_member = bfd_get_32 (abfd, data + idx + j);
1213
              iat_member = bfd_get_32 (abfd, data + idx2 + j);
1214
 
1215
              if (hint_addr == 0 && iat_member == 0)
1216
                break;
1217
 
1218
              if (hint_addr == 0 || hint_member != iat_member)
1219
                {
1220
                  if (differ == 0)
1221
                    {
1222
                      fprintf (file,
1223
                               _("\tThe Import Address Table (difference found)\n"));
1224
                      fprintf(file, _("\tvma:  Hint/Ord Member-Name\n"));
1225
                      differ = 1;
1226
                    }
1227
                  if (iat_member == 0)
1228
                    {
1229
                      fprintf(file,
1230
                              _("\t>>> Ran out of IAT members!\n"));
1231
                    }
1232
                  else
1233
                    {
1234
                      ordinal = bfd_get_16(abfd,
1235
                                           data + iat_member + adj);
1236
                      member_name = (char *) data + iat_member + adj + 2;
1237
                      fprintf(file, "\t%04lx\t %4d  %s\n",
1238
                              iat_member, ordinal, member_name);
1239
                    }
1240
                }
1241
 
1242
              if (hint_addr != 0 && hint_member == 0)
1243
                break;
1244
            }
1245
          if (differ == 0)
1246
            {
1247
              fprintf(file,
1248
                      _("\tThe Import Address Table is identical\n"));
1249
            }
1250
        }
1251
 
1252
      fprintf(file, "\n");
1253
 
1254
    }
1255
 
1256
  free (data);
1257
 
1258
  return true;
1259
}
1260
 
1261
static boolean
1262
pe_print_edata (abfd, vfile)
1263
     bfd *abfd;
1264
     PTR vfile;
1265
{
1266
  FILE *file = (FILE *) vfile;
1267
  bfd_byte *data = 0;
1268
  asection *section = bfd_get_section_by_name (abfd, ".edata");
1269
 
1270
  bfd_size_type datasize;
1271
  bfd_size_type dataoff;
1272
  bfd_size_type i;
1273
 
1274
  int adj;
1275
  struct EDT_type
1276
    {
1277
      long export_flags;             /* reserved - should be zero */
1278
      long time_stamp;
1279
      short major_ver;
1280
      short minor_ver;
1281
      bfd_vma name;                  /* rva - relative to image base */
1282
      long base;                     /* ordinal base */
1283
      unsigned long num_functions;   /* Number in the export address table */
1284
      unsigned long num_names;       /* Number in the name pointer table */
1285
      bfd_vma eat_addr;    /* rva to the export address table */
1286
      bfd_vma npt_addr;        /* rva to the Export Name Pointer Table */
1287
      bfd_vma ot_addr; /* rva to the Ordinal Table */
1288
    } edt;
1289
 
1290
  pe_data_type *pe = pe_data (abfd);
1291
  struct internal_extra_pe_aouthdr *extra = &pe->pe_opthdr;
1292
 
1293
  if (section != NULL)
1294
    {
1295
      datasize = bfd_section_size (abfd, section);
1296
      dataoff = 0;
1297
      fprintf (file, _("\nThe export table is the .edata section\n"));
1298
    }
1299
  else
1300
    {
1301
      /* edata is buried in some other section: e.g. NTDLL.DLL.  */
1302
      bfd_vma addr, size;
1303
 
1304
      addr = extra->DataDirectory[0].VirtualAddress;
1305
      size = extra->DataDirectory[0].Size;
1306
 
1307
      if (addr == 0 || size == 0)
1308
        return true;
1309
 
1310
      for (section = abfd->sections; section != NULL; section = section->next)
1311
        {
1312
           if (addr >= section->vma
1313
               && addr < section->vma + bfd_section_size (abfd, section))
1314
             break;
1315
        }
1316
      if (section == NULL)
1317
        {
1318
           fprintf (file,
1319
                    _("\nThere is an export table, but the section containing it could not be found\n"));
1320
           return true;
1321
        }
1322
 
1323
      fprintf (file, _("\nThere is an export table in %s at 0x%lx\n"),
1324
               section->name, (unsigned long) addr);
1325
 
1326
      datasize = size;
1327
      dataoff = addr - section->vma;
1328
    }
1329
 
1330
  data = (bfd_byte *) bfd_malloc (datasize);
1331
  if (data == NULL && datasize != 0)
1332
    return false;
1333
 
1334
  if (! bfd_get_section_contents (abfd, section, (PTR) data, dataoff,
1335
                                  datasize))
1336
    return false;
1337
 
1338
  /* Go get Export Directory Table */
1339
  edt.export_flags   = bfd_get_32(abfd, data+0);
1340
  edt.time_stamp     = bfd_get_32(abfd, data+4);
1341
  edt.major_ver      = bfd_get_16(abfd, data+8);
1342
  edt.minor_ver      = bfd_get_16(abfd, data+10);
1343
  edt.name           = bfd_get_32(abfd, data+12);
1344
  edt.base           = bfd_get_32(abfd, data+16);
1345
  edt.num_functions  = bfd_get_32(abfd, data+20);
1346
  edt.num_names      = bfd_get_32(abfd, data+24);
1347
  edt.eat_addr       = bfd_get_32(abfd, data+28);
1348
  edt.npt_addr       = bfd_get_32(abfd, data+32);
1349
  edt.ot_addr        = bfd_get_32(abfd, data+36);
1350
 
1351
  adj = - (section->vma + dataoff);
1352
 
1353
  /* Dump the EDT first first */
1354
  fprintf(file,
1355
          _("\nThe Export Tables (interpreted .edata section contents)\n\n"));
1356
 
1357
  fprintf(file,
1358
          _("Export Flags \t\t\t%lx\n"), (unsigned long) edt.export_flags);
1359
 
1360
  fprintf(file,
1361
          _("Time/Date stamp \t\t%lx\n"), (unsigned long) edt.time_stamp);
1362
 
1363
  fprintf(file,
1364
          _("Major/Minor \t\t\t%d/%d\n"), edt.major_ver, edt.minor_ver);
1365
 
1366
  fprintf (file,
1367
           _("Name \t\t\t\t"));
1368
  fprintf_vma (file, edt.name);
1369
  fprintf (file,
1370
           " %s\n", data + edt.name + adj);
1371
 
1372
  fprintf(file,
1373
          _("Ordinal Base \t\t\t%ld\n"), edt.base);
1374
 
1375
  fprintf(file,
1376
          _("Number in:\n"));
1377
 
1378
  fprintf(file,
1379
          _("\tExport Address Table \t\t%lx\n"),
1380
          edt.num_functions);
1381
 
1382
  fprintf(file,
1383
          _("\t[Name Pointer/Ordinal] Table\t%lu\n"), edt.num_names);
1384
 
1385
  fprintf(file,
1386
          _("Table Addresses\n"));
1387
 
1388
  fprintf (file,
1389
           _("\tExport Address Table \t\t"));
1390
  fprintf_vma (file, edt.eat_addr);
1391
  fprintf (file, "\n");
1392
 
1393
  fprintf (file,
1394
          _("\tName Pointer Table \t\t"));
1395
  fprintf_vma (file, edt.npt_addr);
1396
  fprintf (file, "\n");
1397
 
1398
  fprintf (file,
1399
           _("\tOrdinal Table \t\t\t"));
1400
  fprintf_vma (file, edt.ot_addr);
1401
  fprintf (file, "\n");
1402
 
1403
 
1404
  /* The next table to find is the Export Address Table. It's basically
1405
     a list of pointers that either locate a function in this dll, or
1406
     forward the call to another dll. Something like:
1407
      typedef union
1408
      {
1409
        long export_rva;
1410
        long forwarder_rva;
1411
      } export_address_table_entry;
1412
  */
1413
 
1414
  fprintf(file,
1415
          _("\nExport Address Table -- Ordinal Base %ld\n"),
1416
          edt.base);
1417
 
1418
  for (i = 0; i < edt.num_functions; ++i)
1419
    {
1420
      bfd_vma eat_member = bfd_get_32 (abfd,
1421
                                       data + edt.eat_addr + (i * 4) + adj);
1422
      bfd_vma eat_actual = eat_member;
1423
      bfd_vma edata_start = bfd_get_section_vma (abfd, section);
1424
      bfd_vma edata_end = edata_start + datasize;
1425
 
1426
      if (eat_member == 0)
1427
        continue;
1428
 
1429
      if (edata_start < eat_actual && eat_actual < edata_end)
1430
        {
1431
          /* this rva is to a name (forwarding function) in our section */
1432
          /* Should locate a function descriptor */
1433
          fprintf (file,
1434
                   "\t[%4ld] +base[%4ld] %04lx %s -- %s\n",
1435
                   (long) i, (long) (i + edt.base), eat_member,
1436
                   _("Forwarder RVA"), data + eat_member + adj);
1437
        }
1438
      else
1439
        {
1440
          /* Should locate a function descriptor in the reldata section */
1441
          fprintf (file,
1442
                   "\t[%4ld] +base[%4ld] %04lx %s\n",
1443
                   (long) i, (long) (i + edt.base), eat_member,
1444
                   _("Export RVA"));
1445
        }
1446
    }
1447
 
1448
  /* The Export Name Pointer Table is paired with the Export Ordinal Table */
1449
  /* Dump them in parallel for clarity */
1450
  fprintf(file,
1451
          _("\n[Ordinal/Name Pointer] Table\n"));
1452
 
1453
  for (i = 0; i < edt.num_names; ++i)
1454
    {
1455
      bfd_vma name_ptr = bfd_get_32(abfd,
1456
                                    data +
1457
                                    edt.npt_addr
1458
                                    + (i*4) + adj);
1459
 
1460
      char *name = (char *) data + name_ptr + adj;
1461
 
1462
      bfd_vma ord = bfd_get_16(abfd,
1463
                                    data +
1464
                                    edt.ot_addr
1465
                                    + (i*2) + adj);
1466
      fprintf(file,
1467
              "\t[%4ld] %s\n", (long) ord, name);
1468
 
1469
    }
1470
 
1471
  free (data);
1472
 
1473
  return true;
1474
}
1475
 
1476
static boolean
1477
pe_print_pdata (abfd, vfile)
1478
     bfd  *abfd;
1479
     PTR vfile;
1480
{
1481
  FILE *file = (FILE *) vfile;
1482
  bfd_byte *data = 0;
1483
  asection *section = bfd_get_section_by_name (abfd, ".pdata");
1484
  bfd_size_type datasize = 0;
1485
  bfd_size_type i;
1486
  bfd_size_type start, stop;
1487
  int onaline = 20;
1488
 
1489
  if (section == NULL
1490
      || coff_section_data (abfd, section) == NULL
1491
      || pei_section_data (abfd, section) == NULL)
1492
     return true;
1493
 
1494
  stop = pei_section_data (abfd, section)->virt_size;
1495
  if ((stop % onaline) != 0)
1496
    fprintf (file, _("Warning, .pdata section size (%ld) is not a multiple of %d\n"),
1497
             (long)stop, onaline);
1498
 
1499
  fprintf (file,
1500
           _("\nThe Function Table (interpreted .pdata section contents)\n"));
1501
  fprintf (file,
1502
           _(" vma:\t\tBegin    End      EH       EH       PrologEnd  Exception\n"));
1503
  fprintf (file,
1504
           _("     \t\tAddress  Address  Handler  Data     Address    Mask\n"));
1505
 
1506
  if (bfd_section_size (abfd, section) == 0)
1507
    return true;
1508
 
1509
  data = (bfd_byte *) bfd_malloc ((size_t) bfd_section_size (abfd, section));
1510
  datasize = bfd_section_size (abfd, section);
1511
  if (data == NULL && datasize != 0)
1512
    return false;
1513
 
1514
  bfd_get_section_contents (abfd,
1515
                            section,
1516
                            (PTR) data, 0,
1517
                            bfd_section_size (abfd, section));
1518
 
1519
  start = 0;
1520
 
1521
  for (i = start; i < stop; i += onaline)
1522
    {
1523
      bfd_vma begin_addr;
1524
      bfd_vma end_addr;
1525
      bfd_vma eh_handler;
1526
      bfd_vma eh_data;
1527
      bfd_vma prolog_end_addr;
1528
      int em_data;
1529
 
1530
      if (i + 20 > stop)
1531
        break;
1532
 
1533
      begin_addr = bfd_get_32(abfd, data+i);
1534
      end_addr = bfd_get_32(abfd, data+i+4);
1535
      eh_handler = bfd_get_32(abfd, data+i+8);
1536
      eh_data = bfd_get_32(abfd, data+i+12);
1537
      prolog_end_addr = bfd_get_32(abfd, data+i+16);
1538
 
1539
      if (begin_addr == 0 && end_addr == 0 && eh_handler == 0
1540
          && eh_data == 0 && prolog_end_addr == 0)
1541
        {
1542
          /* We are probably into the padding of the section now.  */
1543
          break;
1544
        }
1545
 
1546
      fprintf (file,
1547
               " %08lx\t",
1548
               (unsigned long int) (i + section->vma));
1549
 
1550
      em_data = ((eh_handler & 0x1) << 2) | (prolog_end_addr & 0x3);
1551
      eh_handler &= 0xfffffffc;
1552
      prolog_end_addr &= 0xfffffffc;
1553
 
1554
      fprintf (file, "%08lx %08lx %08lx %08lx %08lx   %x",
1555
               begin_addr,
1556
               end_addr,
1557
               eh_handler,
1558
               eh_data,
1559
               prolog_end_addr,
1560
               em_data);
1561
 
1562
#ifdef POWERPC_LE_PE
1563
      if (eh_handler == 0 && eh_data != 0)
1564
        {
1565
          /* Special bits here, although the meaning may */
1566
          /* be a little mysterious. The only one I know */
1567
          /* for sure is 0x03.                           */
1568
          /* Code Significance                           */
1569
          /* 0x00 None                                   */
1570
          /* 0x01 Register Save Millicode                */
1571
          /* 0x02 Register Restore Millicode             */
1572
          /* 0x03 Glue Code Sequence                     */
1573
          switch (eh_data)
1574
            {
1575
            case 0x01:
1576
              fprintf(file, _(" Register save millicode"));
1577
              break;
1578
            case 0x02:
1579
              fprintf(file, _(" Register restore millicode"));
1580
              break;
1581
            case 0x03:
1582
              fprintf(file, _(" Glue code sequence"));
1583
              break;
1584
            default:
1585
              break;
1586
            }
1587
        }
1588
#endif
1589
      fprintf(file, "\n");
1590
    }
1591
 
1592
  free (data);
1593
 
1594
  return true;
1595
}
1596
 
1597
#define IMAGE_REL_BASED_HIGHADJ 4
1598
static const char * const tbl[] =
1599
{
1600
"ABSOLUTE",
1601
"HIGH",
1602
"LOW",
1603
"HIGHLOW",
1604
"HIGHADJ",
1605
"MIPS_JMPADDR",
1606
"UNKNOWN",   /* MUST be last */
1607
};
1608
 
1609
static boolean
1610
pe_print_reloc (abfd, vfile)
1611
     bfd *abfd;
1612
     PTR vfile;
1613
{
1614
  FILE *file = (FILE *) vfile;
1615
  bfd_byte *data = 0;
1616
  asection *section = bfd_get_section_by_name (abfd, ".reloc");
1617
  bfd_size_type datasize = 0;
1618
  bfd_size_type i;
1619
  bfd_size_type start, stop;
1620
 
1621
  if (section == NULL)
1622
    return true;
1623
 
1624
  if (bfd_section_size (abfd, section) == 0)
1625
    return true;
1626
 
1627
  fprintf (file,
1628
           _("\n\nPE File Base Relocations (interpreted .reloc section contents)\n"));
1629
 
1630
  data = (bfd_byte *) bfd_malloc ((size_t) bfd_section_size (abfd, section));
1631
  datasize = bfd_section_size (abfd, section);
1632
  if (data == NULL && datasize != 0)
1633
    return false;
1634
 
1635
  bfd_get_section_contents (abfd,
1636
                            section,
1637
                            (PTR) data, 0,
1638
                            bfd_section_size (abfd, section));
1639
 
1640
  start = 0;
1641
 
1642
  stop = bfd_section_size (abfd, section);
1643
 
1644
  for (i = start; i < stop;)
1645
    {
1646
      int j;
1647
      bfd_vma virtual_address;
1648
      long number, size;
1649
 
1650
      /* The .reloc section is a sequence of blocks, with a header consisting
1651
         of two 32 bit quantities, followed by a number of 16 bit entries */
1652
 
1653
      virtual_address = bfd_get_32(abfd, data+i);
1654
      size = bfd_get_32(abfd, data+i+4);
1655
      number = (size - 8) / 2;
1656
 
1657
      if (size == 0)
1658
        {
1659
          break;
1660
        }
1661
 
1662
      fprintf (file,
1663
               _("\nVirtual Address: %08lx Chunk size %ld (0x%lx) Number of fixups %ld\n"),
1664
               virtual_address, size, size, number);
1665
 
1666
      for (j = 0; j < number; ++j)
1667
        {
1668
          unsigned short e = bfd_get_16 (abfd, data + i + 8 + j * 2);
1669
          unsigned int t = (e & 0xF000) >> 12;
1670
          int off = e & 0x0FFF;
1671
 
1672
          if (t >= sizeof (tbl) / sizeof (tbl[0]))
1673
            t = (sizeof (tbl) / sizeof (tbl[0])) - 1;
1674
 
1675
          fprintf (file,
1676
                   _("\treloc %4d offset %4x [%4lx] %s"),
1677
                   j, off, (long) (off + virtual_address), tbl[t]);
1678
 
1679
          /* HIGHADJ takes an argument, - the next record *is* the
1680
             low 16 bits of addend.  */
1681
          if (t == IMAGE_REL_BASED_HIGHADJ)
1682
            {
1683
               fprintf (file, " (%4x)",
1684
                        ((unsigned int)
1685
                         bfd_get_16 (abfd, data + i + 8 + j * 2 + 2)));
1686
               j++;
1687
            }
1688
 
1689
          fprintf (file, "\n");
1690
        }
1691
      i += size;
1692
    }
1693
 
1694
  free (data);
1695
 
1696
  return true;
1697
}
1698
 
1699
/* Print out the program headers.  */
1700
 
1701
boolean
1702
_bfd_pe_print_private_bfd_data_common (abfd, vfile)
1703
     bfd *abfd;
1704
     PTR vfile;
1705
{
1706
  FILE *file = (FILE *) vfile;
1707
  int j;
1708
  pe_data_type *pe = pe_data (abfd);
1709
  struct internal_extra_pe_aouthdr *i = &pe->pe_opthdr;
1710
 
1711
  /* The MS dumpbin program reportedly ands with 0xff0f before
1712
     printing the characteristics field.  Not sure why.  No reason to
1713
     emulate it here.  */
1714
  fprintf (file, _("\nCharacteristics 0x%x\n"), pe->real_flags);
1715
#undef PF
1716
#define PF(x, y)    if (pe->real_flags & x) { fprintf (file, "\t%s\n", y); }
1717
  PF (F_RELFLG, "relocations stripped");
1718
  PF (F_EXEC, "executable");
1719
  PF (F_LNNO, "line numbers stripped");
1720
  PF (F_LSYMS, "symbols stripped");
1721
  PF (0x80, "little endian");
1722
  PF (F_AR32WR, "32 bit words");
1723
  PF (0x200, "debugging information removed");
1724
  PF (0x1000, "system file");
1725
  PF (F_DLL, "DLL");
1726
  PF (0x8000, "big endian");
1727
#undef PF
1728
 
1729
  /* ctime implies '\n'.  */
1730
  fprintf (file, "\nTime/Date\t\t%s", ctime (&pe->coff.timestamp));
1731
  fprintf (file,"\nImageBase\t\t");
1732
  fprintf_vma (file, i->ImageBase);
1733
  fprintf (file,"\nSectionAlignment\t");
1734
  fprintf_vma (file, i->SectionAlignment);
1735
  fprintf (file,"\nFileAlignment\t\t");
1736
  fprintf_vma (file, i->FileAlignment);
1737
  fprintf (file,"\nMajorOSystemVersion\t%d\n", i->MajorOperatingSystemVersion);
1738
  fprintf (file,"MinorOSystemVersion\t%d\n", i->MinorOperatingSystemVersion);
1739
  fprintf (file,"MajorImageVersion\t%d\n", i->MajorImageVersion);
1740
  fprintf (file,"MinorImageVersion\t%d\n", i->MinorImageVersion);
1741
  fprintf (file,"MajorSubsystemVersion\t%d\n", i->MajorSubsystemVersion);
1742
  fprintf (file,"MinorSubsystemVersion\t%d\n", i->MinorSubsystemVersion);
1743
  fprintf (file,"Reserved1\t\t%08lx\n", i->Reserved1);
1744
  fprintf (file,"SizeOfImage\t\t%08lx\n", i->SizeOfImage);
1745
  fprintf (file,"SizeOfHeaders\t\t%08lx\n", i->SizeOfHeaders);
1746
  fprintf (file,"CheckSum\t\t%08lx\n", i->CheckSum);
1747
  fprintf (file,"Subsystem\t\t%08x\n", i->Subsystem);
1748
  fprintf (file,"DllCharacteristics\t%08x\n", i->DllCharacteristics);
1749
  fprintf (file,"SizeOfStackReserve\t");
1750
  fprintf_vma (file, i->SizeOfStackReserve);
1751
  fprintf (file,"\nSizeOfStackCommit\t");
1752
  fprintf_vma (file, i->SizeOfStackCommit);
1753
  fprintf (file,"\nSizeOfHeapReserve\t");
1754
  fprintf_vma (file, i->SizeOfHeapReserve);
1755
  fprintf (file,"\nSizeOfHeapCommit\t");
1756
  fprintf_vma (file, i->SizeOfHeapCommit);
1757
  fprintf (file,"\nLoaderFlags\t\t%08lx\n", i->LoaderFlags);
1758
  fprintf (file,"NumberOfRvaAndSizes\t%08lx\n", i->NumberOfRvaAndSizes);
1759
 
1760
  fprintf (file,"\nThe Data Directory\n");
1761
  for (j = 0; j < IMAGE_NUMBEROF_DIRECTORY_ENTRIES; j++)
1762
    {
1763
      fprintf (file, "Entry %1x ", j);
1764
      fprintf_vma (file, i->DataDirectory[j].VirtualAddress);
1765
      fprintf (file, " %08lx ", i->DataDirectory[j].Size);
1766
      fprintf (file, "%s\n", dir_names[j]);
1767
    }
1768
 
1769
  pe_print_idata (abfd, vfile);
1770
  pe_print_edata (abfd, vfile);
1771
  pe_print_pdata (abfd, vfile);
1772
  pe_print_reloc (abfd, vfile);
1773
 
1774
  return true;
1775
}
1776
 
1777
/* Copy any private info we understand from the input bfd
1778
   to the output bfd.  */
1779
 
1780
boolean
1781
_bfd_pe_bfd_copy_private_bfd_data_common (ibfd, obfd)
1782
     bfd *ibfd, *obfd;
1783
{
1784
  /* One day we may try to grok other private data.  */
1785
  if (ibfd->xvec->flavour != bfd_target_coff_flavour
1786
      || obfd->xvec->flavour != bfd_target_coff_flavour)
1787
    return true;
1788
 
1789
  pe_data (obfd)->pe_opthdr = pe_data (ibfd)->pe_opthdr;
1790
  pe_data (obfd)->dll = pe_data (ibfd)->dll;
1791
 
1792
  /* for strip: if we removed .reloc, we'll make a real mess of things
1793
     if we don't remove this entry as well.  */
1794
  if (! pe_data (obfd)->has_reloc_section)
1795
    {
1796
      pe_data(obfd)->pe_opthdr.DataDirectory[5].VirtualAddress = 0;
1797
      pe_data(obfd)->pe_opthdr.DataDirectory[5].Size = 0;
1798
    }
1799
  return true;
1800
}
1801
 
1802
/* Copy private section data. */
1803
boolean
1804
_bfd_pe_bfd_copy_private_section_data (ibfd, isec, obfd, osec)
1805
     bfd *ibfd;
1806
     asection *isec;
1807
     bfd *obfd;
1808
     asection *osec;
1809
{
1810
  if (bfd_get_flavour (ibfd) != bfd_target_coff_flavour
1811
      || bfd_get_flavour (obfd) != bfd_target_coff_flavour)
1812
    return true;
1813
 
1814
  if (coff_section_data (ibfd, isec) != NULL
1815
      && pei_section_data (ibfd, isec) != NULL)
1816
    {
1817
      if (coff_section_data (obfd, osec) == NULL)
1818
        {
1819
          osec->used_by_bfd =
1820
            (PTR) bfd_zalloc (obfd, sizeof (struct coff_section_tdata));
1821
          if (osec->used_by_bfd == NULL)
1822
            return false;
1823
        }
1824
      if (pei_section_data (obfd, osec) == NULL)
1825
        {
1826
          coff_section_data (obfd, osec)->tdata =
1827
            (PTR) bfd_zalloc (obfd, sizeof (struct pei_section_tdata));
1828
          if (coff_section_data (obfd, osec)->tdata == NULL)
1829
            return false;
1830
        }
1831
      pei_section_data (obfd, osec)->virt_size =
1832
        pei_section_data (ibfd, isec)->virt_size;
1833
      pei_section_data (obfd, osec)->pe_flags =
1834
        pei_section_data (ibfd, isec)->pe_flags;
1835
    }
1836
 
1837
  return true;
1838
}
1839
 
1840
void
1841
_bfd_pe_get_symbol_info (abfd, symbol, ret)
1842
     bfd *abfd;
1843
     asymbol *symbol;
1844
     symbol_info *ret;
1845
{
1846
  coff_get_symbol_info (abfd, symbol, ret);
1847
 
1848
  if (pe_data (abfd) != NULL
1849
      && ((symbol->flags & BSF_DEBUGGING) == 0
1850
          || (symbol->flags & BSF_DEBUGGING_RELOC) != 0)
1851
      && ! bfd_is_abs_section (symbol->section))
1852
    ret->value += pe_data (abfd)->pe_opthdr.ImageBase;
1853
}
1854
 
1855
/* Handle the .idata section and other things that need symbol table
1856
   access.  */
1857
 
1858
boolean
1859
_bfd_pei_final_link_postscript (abfd, pfinfo)
1860
     bfd *abfd;
1861
     struct coff_final_link_info *pfinfo;
1862
{
1863
  struct coff_link_hash_entry *h1;
1864
  struct bfd_link_info *info = pfinfo->info;
1865
 
1866
  /* There are a few fields that need to be filled in now while we
1867
     have symbol table access.
1868
 
1869
     The .idata subsections aren't directly available as sections, but
1870
     they are in the symbol table, so get them from there.  */
1871
 
1872
  /* The import directory.  This is the address of .idata$2, with size
1873
     of .idata$2 + .idata$3.  */
1874
  h1 = coff_link_hash_lookup (coff_hash_table (info),
1875
                              ".idata$2", false, false, true);
1876
  if (h1 != NULL)
1877
    {
1878
      pe_data(abfd)->pe_opthdr.DataDirectory[1].VirtualAddress =
1879
        (h1->root.u.def.value
1880
         + h1->root.u.def.section->output_section->vma
1881
         + h1->root.u.def.section->output_offset);
1882
      h1 = coff_link_hash_lookup (coff_hash_table (info),
1883
                                  ".idata$4", false, false, true);
1884
      pe_data (abfd)->pe_opthdr.DataDirectory[1].Size =
1885
        ((h1->root.u.def.value
1886
          + h1->root.u.def.section->output_section->vma
1887
          + h1->root.u.def.section->output_offset)
1888
         - pe_data(abfd)->pe_opthdr.DataDirectory[1].VirtualAddress);
1889
 
1890
      /* The import address table.  This is the size/address of
1891
         .idata$5.  */
1892
      h1 = coff_link_hash_lookup (coff_hash_table (info),
1893
                                  ".idata$5", false, false, true);
1894
      pe_data (abfd)->pe_opthdr.DataDirectory[12].VirtualAddress =
1895
        (h1->root.u.def.value
1896
         + h1->root.u.def.section->output_section->vma
1897
         + h1->root.u.def.section->output_offset);
1898
      h1 = coff_link_hash_lookup (coff_hash_table (info),
1899
                                  ".idata$6", false, false, true);
1900
      pe_data (abfd)->pe_opthdr.DataDirectory[12].Size =
1901
        ((h1->root.u.def.value
1902
          + h1->root.u.def.section->output_section->vma
1903
          + h1->root.u.def.section->output_offset)
1904
         - pe_data(abfd)->pe_opthdr.DataDirectory[12].VirtualAddress);
1905
    }
1906
 
1907
  /* If we couldn't find idata$2, we either have an excessively
1908
     trivial program or are in DEEP trouble; we have to assume trivial
1909
     program....  */
1910
  return true;
1911
}

powered by: WebSVN 2.1.0

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