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