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