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