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