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