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