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