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