* peicode.h (coff_swap_aux_in): Swap in extra PE x_scn fields.
[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);
8230f31c
ILT
538 in->x_scn.x_checksum = bfd_h_get_32 (abfd,
539 (bfd_byte *) ext->x_scn.x_checksum);
540 in->x_scn.x_associated =
541 bfd_h_get_16 (abfd, (bfd_byte *) ext->x_scn.x_associated);
542 in->x_scn.x_comdat = bfd_h_get_8 (abfd,
543 (bfd_byte *) ext->x_scn.x_comdat);
4e98461f
SC
544 return;
545 }
546 break;
547 }
548
549 in->x_sym.x_tagndx.l = bfd_h_get_32(abfd, (bfd_byte *) ext->x_sym.x_tagndx);
550#ifndef NO_TVNDX
551 in->x_sym.x_tvndx = bfd_h_get_16(abfd, (bfd_byte *) ext->x_sym.x_tvndx);
552#endif
553
554 if (class == C_BLOCK || ISFCN (type) || ISTAG (class))
555 {
556 in->x_sym.x_fcnary.x_fcn.x_lnnoptr = GET_FCN_LNNOPTR (abfd, ext);
557 in->x_sym.x_fcnary.x_fcn.x_endndx.l = GET_FCN_ENDNDX (abfd, ext);
558 }
559 else
560 {
561#if DIMNUM != E_DIMNUM
562 #error we need to cope with truncating or extending DIMNUM
563#endif
564 in->x_sym.x_fcnary.x_ary.x_dimen[0] =
565 bfd_h_get_16 (abfd, (bfd_byte *) ext->x_sym.x_fcnary.x_ary.x_dimen[0]);
566 in->x_sym.x_fcnary.x_ary.x_dimen[1] =
567 bfd_h_get_16 (abfd, (bfd_byte *) ext->x_sym.x_fcnary.x_ary.x_dimen[1]);
568 in->x_sym.x_fcnary.x_ary.x_dimen[2] =
569 bfd_h_get_16 (abfd, (bfd_byte *) ext->x_sym.x_fcnary.x_ary.x_dimen[2]);
570 in->x_sym.x_fcnary.x_ary.x_dimen[3] =
571 bfd_h_get_16 (abfd, (bfd_byte *) ext->x_sym.x_fcnary.x_ary.x_dimen[3]);
572 }
573
574 if (ISFCN(type)) {
575 in->x_sym.x_misc.x_fsize = bfd_h_get_32(abfd, (bfd_byte *) ext->x_sym.x_misc.x_fsize);
576 }
577 else {
578 in->x_sym.x_misc.x_lnsz.x_lnno = GET_LNSZ_LNNO(abfd, ext);
579 in->x_sym.x_misc.x_lnsz.x_size = GET_LNSZ_SIZE(abfd, ext);
580 }
581}
582
583static unsigned int
584coff_swap_aux_out (abfd, inp, type, class, indx, numaux, extp)
585 bfd *abfd;
586 PTR inp;
587 int type;
588 int class;
589 int indx;
590 int numaux;
591 PTR extp;
592{
593 union internal_auxent *in = (union internal_auxent *)inp;
594 AUXENT *ext = (AUXENT *)extp;
595
596 memset((PTR)ext, 0, AUXESZ);
597 switch (class) {
598 case C_FILE:
599 if (in->x_file.x_fname[0] == 0) {
600 bfd_h_put_32(abfd, 0, (bfd_byte *) ext->x_file.x_n.x_zeroes);
601 bfd_h_put_32(abfd,
602 in->x_file.x_n.x_offset,
603 (bfd_byte *) ext->x_file.x_n.x_offset);
604 }
605 else {
606#if FILNMLEN != E_FILNMLEN
607 -> Error, we need to cope with truncating or extending FILNMLEN!;
608#else
609 memcpy (ext->x_file.x_fname, in->x_file.x_fname, FILNMLEN);
610#endif
611 }
612 return sizeof (AUXENT);
613
614
615 case C_STAT:
616#ifdef C_LEAFSTAT
617 case C_LEAFSTAT:
618#endif
619 case C_HIDDEN:
620 if (type == T_NULL) {
621 PUT_SCN_SCNLEN(abfd, in->x_scn.x_scnlen, ext);
622 PUT_SCN_NRELOC(abfd, in->x_scn.x_nreloc, ext);
623 PUT_SCN_NLINNO(abfd, in->x_scn.x_nlinno, ext);
8230f31c
ILT
624 bfd_h_put_32 (abfd, in->x_scn.x_checksum,
625 (bfd_byte *) ext->x_scn.x_checksum);
626 bfd_h_put_16 (abfd, in->x_scn.x_associated,
627 (bfd_byte *) ext->x_scn.x_associated);
628 bfd_h_put_8 (abfd, in->x_scn.x_comdat,
629 (bfd_byte *) ext->x_scn.x_comdat);
4e98461f
SC
630 return sizeof (AUXENT);
631 }
632 break;
633 }
634
635 bfd_h_put_32(abfd, in->x_sym.x_tagndx.l, (bfd_byte *) ext->x_sym.x_tagndx);
636#ifndef NO_TVNDX
637 bfd_h_put_16(abfd, in->x_sym.x_tvndx , (bfd_byte *) ext->x_sym.x_tvndx);
638#endif
639
640 if (class == C_BLOCK || ISFCN (type) || ISTAG (class))
641 {
642 PUT_FCN_LNNOPTR(abfd, in->x_sym.x_fcnary.x_fcn.x_lnnoptr, ext);
643 PUT_FCN_ENDNDX(abfd, in->x_sym.x_fcnary.x_fcn.x_endndx.l, ext);
644 }
645 else
646 {
647#if DIMNUM != E_DIMNUM
648 #error we need to cope with truncating or extending DIMNUM
649#endif
650 bfd_h_put_16 (abfd, in->x_sym.x_fcnary.x_ary.x_dimen[0],
651 (bfd_byte *) ext->x_sym.x_fcnary.x_ary.x_dimen[0]);
652 bfd_h_put_16 (abfd, in->x_sym.x_fcnary.x_ary.x_dimen[1],
653 (bfd_byte *) ext->x_sym.x_fcnary.x_ary.x_dimen[1]);
654 bfd_h_put_16 (abfd, in->x_sym.x_fcnary.x_ary.x_dimen[2],
655 (bfd_byte *) ext->x_sym.x_fcnary.x_ary.x_dimen[2]);
656 bfd_h_put_16 (abfd, in->x_sym.x_fcnary.x_ary.x_dimen[3],
657 (bfd_byte *) ext->x_sym.x_fcnary.x_ary.x_dimen[3]);
658 }
659
660 if (ISFCN (type))
661 bfd_h_put_32 (abfd, in->x_sym.x_misc.x_fsize,
662 (bfd_byte *) ext->x_sym.x_misc.x_fsize);
663 else
664 {
665 PUT_LNSZ_LNNO (abfd, in->x_sym.x_misc.x_lnsz.x_lnno, ext);
666 PUT_LNSZ_SIZE (abfd, in->x_sym.x_misc.x_lnsz.x_size, ext);
667 }
668
669 return sizeof(AUXENT);
670}
671
672
673static void
674coff_swap_lineno_in (abfd, ext1, in1)
675 bfd *abfd;
676 PTR ext1;
677 PTR in1;
678{
679 LINENO *ext = (LINENO *)ext1;
680 struct internal_lineno *in = (struct internal_lineno *)in1;
681
682 in->l_addr.l_symndx = bfd_h_get_32(abfd, (bfd_byte *) ext->l_addr.l_symndx);
683 in->l_lnno = GET_LINENO_LNNO(abfd, ext);
684}
685
686static unsigned int
687coff_swap_lineno_out (abfd, inp, outp)
688 bfd *abfd;
689 PTR inp;
690 PTR outp;
691{
692 struct internal_lineno *in = (struct internal_lineno *)inp;
693 struct external_lineno *ext = (struct external_lineno *)outp;
694 bfd_h_put_32(abfd, in->l_addr.l_symndx, (bfd_byte *)
695 ext->l_addr.l_symndx);
696
697 PUT_LINENO_LNNO (abfd, in->l_lnno, ext);
698 return sizeof(struct external_lineno);
699}
700
701
702
703static void
704coff_swap_aouthdr_in (abfd, aouthdr_ext1, aouthdr_int1)
705 bfd *abfd;
706 PTR aouthdr_ext1;
707 PTR aouthdr_int1;
708{
709 struct internal_extra_pe_aouthdr *a;
710 PEAOUTHDR *src = (PEAOUTHDR *)(aouthdr_ext1);
711 AOUTHDR *aouthdr_ext = (AOUTHDR *) aouthdr_ext1;
712 struct internal_aouthdr *aouthdr_int = (struct internal_aouthdr *)aouthdr_int1;
713
714 aouthdr_int->magic = bfd_h_get_16(abfd, (bfd_byte *) aouthdr_ext->magic);
715 aouthdr_int->vstamp = bfd_h_get_16(abfd, (bfd_byte *) aouthdr_ext->vstamp);
716 aouthdr_int->tsize =
717 GET_AOUTHDR_TSIZE (abfd, (bfd_byte *) aouthdr_ext->tsize);
718 aouthdr_int->dsize =
719 GET_AOUTHDR_DSIZE (abfd, (bfd_byte *) aouthdr_ext->dsize);
720 aouthdr_int->bsize =
721 GET_AOUTHDR_BSIZE (abfd, (bfd_byte *) aouthdr_ext->bsize);
722 aouthdr_int->entry =
723 GET_AOUTHDR_ENTRY (abfd, (bfd_byte *) aouthdr_ext->entry);
724 aouthdr_int->text_start =
725 GET_AOUTHDR_TEXT_START (abfd, (bfd_byte *) aouthdr_ext->text_start);
726 aouthdr_int->data_start =
727 GET_AOUTHDR_DATA_START (abfd, (bfd_byte *) aouthdr_ext->data_start);
728
729 a = &aouthdr_int->pe;
730 a->ImageBase = bfd_h_get_32 (abfd, src->ImageBase);
731 a->SectionAlignment = bfd_h_get_32 (abfd, src->SectionAlignment);
732 a->FileAlignment = bfd_h_get_32 (abfd, src->FileAlignment);
733 a->MajorOperatingSystemVersion =
734 bfd_h_get_16 (abfd, src->MajorOperatingSystemVersion);
735 a->MinorOperatingSystemVersion =
736 bfd_h_get_16 (abfd, src->MinorOperatingSystemVersion);
737 a->MajorImageVersion = bfd_h_get_16 (abfd, src->MajorImageVersion);
738 a->MinorImageVersion = bfd_h_get_16 (abfd, src->MinorImageVersion);
739 a->MajorSubsystemVersion = bfd_h_get_16 (abfd, src->MajorSubsystemVersion);
740 a->MinorSubsystemVersion = bfd_h_get_16 (abfd, src->MinorSubsystemVersion);
741 a->Reserved1 = bfd_h_get_32 (abfd, src->Reserved1);
742 a->SizeOfImage = bfd_h_get_32 (abfd, src->SizeOfImage);
743 a->SizeOfHeaders = bfd_h_get_32 (abfd, src->SizeOfHeaders);
744 a->CheckSum = bfd_h_get_32 (abfd, src->CheckSum);
745 a->Subsystem = bfd_h_get_16 (abfd, src->Subsystem);
746 a->DllCharacteristics = bfd_h_get_16 (abfd, src->DllCharacteristics);
747 a->SizeOfStackReserve = bfd_h_get_32 (abfd, src->SizeOfStackReserve);
748 a->SizeOfStackCommit = bfd_h_get_32 (abfd, src->SizeOfStackCommit);
749 a->SizeOfHeapReserve = bfd_h_get_32 (abfd, src->SizeOfHeapReserve);
750 a->SizeOfHeapCommit = bfd_h_get_32 (abfd, src->SizeOfHeapCommit);
751 a->LoaderFlags = bfd_h_get_32 (abfd, src->LoaderFlags);
752 a->NumberOfRvaAndSizes = bfd_h_get_32 (abfd, src->NumberOfRvaAndSizes);
753
754 {
755 int idx;
756 for (idx=0; idx < 16; idx++)
757 {
758 a->DataDirectory[idx].VirtualAddress =
759 bfd_h_get_32 (abfd, src->DataDirectory[idx][0]);
760 a->DataDirectory[idx].Size =
761 bfd_h_get_32 (abfd, src->DataDirectory[idx][1]);
762 }
763 }
ae115e51
ILT
764
765 if (aouthdr_int->entry)
766 aouthdr_int->entry += a->ImageBase;
767 if (aouthdr_int->tsize)
768 aouthdr_int->text_start += a->ImageBase;
769 if (aouthdr_int->dsize)
770 aouthdr_int->data_start += a->ImageBase;
4e98461f
SC
771}
772
773
774static void add_data_entry (abfd, aout, idx, name, base)
775 bfd *abfd;
776 struct internal_extra_pe_aouthdr *aout;
777 int idx;
778 char *name;
779 bfd_vma base;
780{
781 asection *sec = bfd_get_section_by_name (abfd, name);
782
783 /* add import directory information if it exists */
784 if (sec != NULL)
785 {
187783e0 786 aout->DataDirectory[idx].VirtualAddress = sec->vma - base;
dff77ed7 787 aout->DataDirectory[idx].Size = sec->_cooked_size;
4e98461f
SC
788 sec->flags |= SEC_DATA;
789 }
790}
791
4e98461f
SC
792static unsigned int
793coff_swap_aouthdr_out (abfd, in, out)
794 bfd *abfd;
795 PTR in;
796 PTR out;
797{
798 struct internal_aouthdr *aouthdr_in = (struct internal_aouthdr *)in;
799 struct internal_extra_pe_aouthdr *extra = &pe_data (abfd)->pe_opthdr;
800 PEAOUTHDR *aouthdr_out = (PEAOUTHDR *)out;
801
802 bfd_vma sa = extra->SectionAlignment;
803 bfd_vma fa = extra->FileAlignment;
804 bfd_vma ib = extra->ImageBase ;
805
806 if (aouthdr_in->tsize)
807 aouthdr_in->text_start -= ib;
808 if (aouthdr_in->dsize)
809 aouthdr_in->data_start -= ib;
810 if (aouthdr_in->entry)
811 aouthdr_in->entry -= ib;
812
813#define FA(x) (((x) + fa -1 ) & (- fa))
814#define SA(x) (((x) + sa -1 ) & (- sa))
815
816 /* We like to have the sizes aligned */
817
818 aouthdr_in->bsize = FA (aouthdr_in->bsize);
819
820
821 extra->NumberOfRvaAndSizes = IMAGE_NUMBEROF_DIRECTORY_ENTRIES;
822
823 /* first null out all data directory entries .. */
824 memset (extra->DataDirectory, sizeof (extra->DataDirectory), 0);
825
826 add_data_entry (abfd, extra, 0, ".edata", ib);
827 add_data_entry (abfd, extra, 1, ".idata", ib);
828 add_data_entry (abfd, extra, 2, ".rsrc" ,ib);
4b71e164
ILT
829
830#ifdef POWERPC_LE_PE
831 /* FIXME: do other PE platforms use this? */
832 add_data_entry (abfd, extra, 3, ".pdata" ,ib);
833#endif
834
4e98461f 835 add_data_entry (abfd, extra, 5, ".reloc", ib);
4b71e164
ILT
836
837#ifdef POWERPC_LE_PE
838 /* On the PPC NT system, this field is set up as follows. It is
839 not an "officially" reserved field, so it currently has no title.
840 first_thunk_address is idata$5, and the thunk_size is the size
841 of the idata$5 chunk of the idata section.
842 */
843 extra->DataDirectory[12].VirtualAddress = first_thunk_address;
844 extra->DataDirectory[12].Size = thunk_size;
845
846 /* On the PPC NT system, the size of the directory entry is not the
847 size of the entire section. It's actually offset to the end of
848 the idata$3 component of the idata section. This is the size of
849 the entire import table. (also known as the start of idata$4)
850 */
851 extra->DataDirectory[1].Size = import_table_size;
852#endif
853
4e98461f
SC
854 {
855 asection *sec;
856 bfd_vma dsize= 0;
857 bfd_vma isize = SA(abfd->sections->filepos);
858 bfd_vma tsize= 0;
187783e0 859
4e98461f
SC
860 for (sec = abfd->sections; sec; sec = sec->next)
861 {
862 int rounded = FA(sec->_raw_size);
187783e0
ILT
863
864 if (strcmp(sec->name,".junk") == 0)
865 {
866 continue;
867 }
868
4e98461f
SC
869 if (sec->flags & SEC_DATA)
870 dsize += rounded;
871 if (sec->flags & SEC_CODE)
872 tsize += rounded;
873 isize += SA(rounded);
874 }
875
876 aouthdr_in->dsize = dsize;
877 aouthdr_in->tsize = tsize;
878 extra->SizeOfImage = isize;
879 }
880
881 extra->SizeOfHeaders = abfd->sections->filepos;
882 bfd_h_put_16(abfd, aouthdr_in->magic, (bfd_byte *) aouthdr_out->standard.magic);
4b71e164
ILT
883
884#ifdef POWERPC_LE_PE
885 /* this little piece of magic sets the "linker version" field to 2.60 */
886 bfd_h_put_16(abfd, 2 + 60 * 256, (bfd_byte *) aouthdr_out->standard.vstamp);
887#else
888 /* this little piece of magic sets the "linker version" field to 2.55 */
dff77ed7 889 bfd_h_put_16(abfd, 2 + 55 * 256, (bfd_byte *) aouthdr_out->standard.vstamp);
4b71e164
ILT
890#endif
891
4e98461f
SC
892 PUT_AOUTHDR_TSIZE (abfd, aouthdr_in->tsize, (bfd_byte *) aouthdr_out->standard.tsize);
893 PUT_AOUTHDR_DSIZE (abfd, aouthdr_in->dsize, (bfd_byte *) aouthdr_out->standard.dsize);
894 PUT_AOUTHDR_BSIZE (abfd, aouthdr_in->bsize, (bfd_byte *) aouthdr_out->standard.bsize);
895 PUT_AOUTHDR_ENTRY (abfd, aouthdr_in->entry, (bfd_byte *) aouthdr_out->standard.entry);
896 PUT_AOUTHDR_TEXT_START (abfd, aouthdr_in->text_start,
897 (bfd_byte *) aouthdr_out->standard.text_start);
dff77ed7 898
4e98461f
SC
899 PUT_AOUTHDR_DATA_START (abfd, aouthdr_in->data_start,
900 (bfd_byte *) aouthdr_out->standard.data_start);
901
902
903 bfd_h_put_32 (abfd, extra->ImageBase,
904 (bfd_byte *) aouthdr_out->ImageBase);
905 bfd_h_put_32 (abfd, extra->SectionAlignment,
906 (bfd_byte *) aouthdr_out->SectionAlignment);
907 bfd_h_put_32 (abfd, extra->FileAlignment,
908 (bfd_byte *) aouthdr_out->FileAlignment);
909 bfd_h_put_16 (abfd, extra->MajorOperatingSystemVersion,
910 (bfd_byte *) aouthdr_out->MajorOperatingSystemVersion);
911 bfd_h_put_16 (abfd, extra->MinorOperatingSystemVersion,
912 (bfd_byte *) aouthdr_out->MinorOperatingSystemVersion);
913 bfd_h_put_16 (abfd, extra->MajorImageVersion,
914 (bfd_byte *) aouthdr_out->MajorImageVersion);
915 bfd_h_put_16 (abfd, extra->MinorImageVersion,
916 (bfd_byte *) aouthdr_out->MinorImageVersion);
917 bfd_h_put_16 (abfd, extra->MajorSubsystemVersion,
918 (bfd_byte *) aouthdr_out->MajorSubsystemVersion);
919 bfd_h_put_16 (abfd, extra->MinorSubsystemVersion,
920 (bfd_byte *) aouthdr_out->MinorSubsystemVersion);
921 bfd_h_put_32 (abfd, extra->Reserved1,
922 (bfd_byte *) aouthdr_out->Reserved1);
923 bfd_h_put_32 (abfd, extra->SizeOfImage,
924 (bfd_byte *) aouthdr_out->SizeOfImage);
925 bfd_h_put_32 (abfd, extra->SizeOfHeaders,
926 (bfd_byte *) aouthdr_out->SizeOfHeaders);
927 bfd_h_put_32 (abfd, extra->CheckSum,
928 (bfd_byte *) aouthdr_out->CheckSum);
929 bfd_h_put_16 (abfd, extra->Subsystem,
930 (bfd_byte *) aouthdr_out->Subsystem);
931 bfd_h_put_16 (abfd, extra->DllCharacteristics,
932 (bfd_byte *) aouthdr_out->DllCharacteristics);
933 bfd_h_put_32 (abfd, extra->SizeOfStackReserve,
934 (bfd_byte *) aouthdr_out->SizeOfStackReserve);
935 bfd_h_put_32 (abfd, extra->SizeOfStackCommit,
936 (bfd_byte *) aouthdr_out->SizeOfStackCommit);
937 bfd_h_put_32 (abfd, extra->SizeOfHeapReserve,
938 (bfd_byte *) aouthdr_out->SizeOfHeapReserve);
939 bfd_h_put_32 (abfd, extra->SizeOfHeapCommit,
940 (bfd_byte *) aouthdr_out->SizeOfHeapCommit);
941 bfd_h_put_32 (abfd, extra->LoaderFlags,
942 (bfd_byte *) aouthdr_out->LoaderFlags);
943 bfd_h_put_32 (abfd, extra->NumberOfRvaAndSizes,
944 (bfd_byte *) aouthdr_out->NumberOfRvaAndSizes);
945 {
946 int idx;
947 for (idx=0; idx < 16; idx++)
948 {
949 bfd_h_put_32 (abfd, extra->DataDirectory[idx].VirtualAddress,
950 (bfd_byte *) aouthdr_out->DataDirectory[idx][0]);
951 bfd_h_put_32 (abfd, extra->DataDirectory[idx].Size,
952 (bfd_byte *) aouthdr_out->DataDirectory[idx][1]);
953 }
954 }
955
4e98461f
SC
956 return sizeof(AOUTHDR);
957}
958
959static void
960 coff_swap_scnhdr_in (abfd, ext, in)
961 bfd *abfd;
962 PTR ext;
963 PTR in;
964{
965 SCNHDR *scnhdr_ext = (SCNHDR *) ext;
966 struct internal_scnhdr *scnhdr_int = (struct internal_scnhdr *) in;
967
968 memcpy(scnhdr_int->s_name, scnhdr_ext->s_name, sizeof(scnhdr_int->s_name));
969 scnhdr_int->s_vaddr =
970 GET_SCNHDR_VADDR (abfd, (bfd_byte *) scnhdr_ext->s_vaddr);
971 scnhdr_int->s_paddr =
972 GET_SCNHDR_PADDR (abfd, (bfd_byte *) scnhdr_ext->s_paddr);
973 scnhdr_int->s_size =
974 GET_SCNHDR_SIZE (abfd, (bfd_byte *) scnhdr_ext->s_size);
4e98461f
SC
975 scnhdr_int->s_scnptr =
976 GET_SCNHDR_SCNPTR (abfd, (bfd_byte *) scnhdr_ext->s_scnptr);
977 scnhdr_int->s_relptr =
978 GET_SCNHDR_RELPTR (abfd, (bfd_byte *) scnhdr_ext->s_relptr);
979 scnhdr_int->s_lnnoptr =
980 GET_SCNHDR_LNNOPTR (abfd, (bfd_byte *) scnhdr_ext->s_lnnoptr);
981 scnhdr_int->s_flags = bfd_h_get_32(abfd, (bfd_byte *) scnhdr_ext->s_flags);
982
983 scnhdr_int->s_nreloc = bfd_h_get_16(abfd, (bfd_byte *) scnhdr_ext->s_nreloc);
984 scnhdr_int->s_nlnno = bfd_h_get_16(abfd, (bfd_byte *) scnhdr_ext->s_nlnno);
985
986 if (scnhdr_int->s_vaddr != 0)
987 {
988 scnhdr_int->s_vaddr += pe_data (abfd)->pe_opthdr.ImageBase;
989 }
db344f82
SC
990 if (strcmp (scnhdr_int->s_name, _BSS) == 0)
991 {
992 scnhdr_int->s_size = scnhdr_int->s_paddr;
993 scnhdr_int->s_paddr = 0;
994 }
4e98461f
SC
995}
996
997static unsigned int
500d7394
SC
998coff_swap_scnhdr_out (abfd, in, out)
999 bfd *abfd;
1000 PTR in;
1001 PTR out;
4e98461f
SC
1002{
1003 struct internal_scnhdr *scnhdr_int = (struct internal_scnhdr *)in;
1004 SCNHDR *scnhdr_ext = (SCNHDR *)out;
1005 unsigned int ret = sizeof (SCNHDR);
500d7394
SC
1006 bfd_vma ps;
1007 bfd_vma ss;
4e98461f
SC
1008
1009 memcpy(scnhdr_ext->s_name, scnhdr_int->s_name, sizeof(scnhdr_int->s_name));
1010
4e98461f
SC
1011 PUT_SCNHDR_VADDR (abfd,
1012 (scnhdr_int->s_vaddr
1013 - pe_data(abfd)->pe_opthdr.ImageBase),
1014 (bfd_byte *) scnhdr_ext->s_vaddr);
1015
4e98461f
SC
1016 /* NT wants the size data to be rounded up to the next NT_FILE_ALIGNMENT
1017 value except for the BSS section, its s_size should be 0 */
beee31b1 1018
500d7394 1019
beee31b1 1020 if (strcmp (scnhdr_int->s_name, _BSS) == 0)
500d7394
SC
1021 {
1022 ps = scnhdr_int->s_size;
1023 ss = 0;
1024 }
4e98461f 1025 else
500d7394
SC
1026 {
1027 ps = scnhdr_int->s_paddr;
1028 ss = scnhdr_int->s_size;
1029 }
1030
1031 PUT_SCNHDR_SIZE (abfd, ss,
1032 (bfd_byte *) scnhdr_ext->s_size);
1033
beee31b1 1034
500d7394 1035 PUT_SCNHDR_PADDR (abfd, ps, (bfd_byte *) scnhdr_ext->s_paddr);
4e98461f
SC
1036
1037 PUT_SCNHDR_SCNPTR (abfd, scnhdr_int->s_scnptr,
1038 (bfd_byte *) scnhdr_ext->s_scnptr);
1039 PUT_SCNHDR_RELPTR (abfd, scnhdr_int->s_relptr,
1040 (bfd_byte *) scnhdr_ext->s_relptr);
1041 PUT_SCNHDR_LNNOPTR (abfd, scnhdr_int->s_lnnoptr,
1042 (bfd_byte *) scnhdr_ext->s_lnnoptr);
1043
1044 /* Extra flags must be set when dealing with NT. All sections should also
1045 have the IMAGE_SCN_MEM_READ (0x40000000) flag set. In addition, the
1046 .text section must have IMAGE_SCN_MEM_EXECUTE (0x20000000) and the data
1047 sections (.idata, .data, .bss, .CRT) must have IMAGE_SCN_MEM_WRITE set
1048 (this is especially important when dealing with the .idata section since
1049 the addresses for routines from .dlls must be overwritten). If .reloc
1050 section data is ever generated, we must add IMAGE_SCN_MEM_DISCARDABLE
1051 (0x02000000). Also, the resource data should also be read and
1052 writable. */
db344f82
SC
1053
1054 /* FIXME: alignment is also encoded in this field, at least on ppc (krk) */
1055 /* FIXME: even worse, I don't see how to get the original alignment field*/
1056 /* back... */
1057
4e98461f
SC
1058 {
1059 int flags = scnhdr_int->s_flags;
1060 if (strcmp (scnhdr_int->s_name, ".data") == 0 ||
1061 strcmp (scnhdr_int->s_name, ".CRT") == 0 ||
1062 strcmp (scnhdr_int->s_name, ".rsrc") == 0 ||
1063 strcmp (scnhdr_int->s_name, ".bss") == 0)
1064 flags |= IMAGE_SCN_MEM_READ | IMAGE_SCN_MEM_WRITE;
1065 else if (strcmp (scnhdr_int->s_name, ".text") == 0)
1066 flags |= IMAGE_SCN_MEM_READ | IMAGE_SCN_MEM_EXECUTE;
1067 else if (strcmp (scnhdr_int->s_name, ".reloc") == 0)
1068 flags = SEC_DATA| IMAGE_SCN_MEM_READ | IMAGE_SCN_MEM_DISCARDABLE;
1069 else if (strcmp (scnhdr_int->s_name, ".idata") == 0)
1070 flags = IMAGE_SCN_MEM_READ | IMAGE_SCN_MEM_WRITE | SEC_DATA;
1071 else if (strcmp (scnhdr_int->s_name, ".rdata") == 0
1072 || strcmp (scnhdr_int->s_name, ".edata") == 0)
1073 flags = IMAGE_SCN_MEM_READ | SEC_DATA;
db344f82
SC
1074 /* ppc-nt additions */
1075 else if (strcmp (scnhdr_int->s_name, ".pdata") == 0)
1076 flags = IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_ALIGN_4BYTES |
1077 IMAGE_SCN_MEM_READ ;
4b71e164
ILT
1078 /* Remember this field is a max of 8 chars, so the null is _not_ there
1079 for an 8 character name like ".reldata". (yep. Stupid bug) */
1080 else if (strncmp (scnhdr_int->s_name, ".reldata", strlen(".reldata")) == 0)
db344f82
SC
1081 flags = IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_ALIGN_8BYTES |
1082 IMAGE_SCN_MEM_READ | IMAGE_SCN_MEM_WRITE ;
1083 else if (strcmp (scnhdr_int->s_name, ".ydata") == 0)
1084 flags = IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_ALIGN_8BYTES |
1085 IMAGE_SCN_MEM_READ | IMAGE_SCN_MEM_WRITE ;
1086 else if (strcmp (scnhdr_int->s_name, ".drectve") == 0)
1087 flags = IMAGE_SCN_LNK_INFO | IMAGE_SCN_LNK_REMOVE ;
1088 /* end of ppc-nt additions */
187783e0
ILT
1089#ifdef POWERPC_LE_PE
1090 else if (strncmp (scnhdr_int->s_name, ".stabstr", strlen(".stabstr")) == 0)
1091 {
1092 flags = IMAGE_SCN_LNK_INFO;
1093 }
1094 else if (strcmp (scnhdr_int->s_name, ".stab") == 0)
1095 {
1096 flags = IMAGE_SCN_LNK_INFO;
1097 }
1098#endif
4e98461f
SC
1099
1100 bfd_h_put_32(abfd, flags, (bfd_byte *) scnhdr_ext->s_flags);
1101 }
1102
1103 if (scnhdr_int->s_nlnno <= 0xffff)
1104 bfd_h_put_16(abfd, scnhdr_int->s_nlnno, (bfd_byte *) scnhdr_ext->s_nlnno);
1105 else
1106 {
1107 (*_bfd_error_handler) ("%s: line number overflow: 0x%lx > 0xffff",
1108 bfd_get_filename (abfd),
1109 scnhdr_int->s_nlnno);
1110 bfd_set_error (bfd_error_file_truncated);
1111 bfd_h_put_16 (abfd, 0xffff, (bfd_byte *) scnhdr_ext->s_nlnno);
1112 ret = 0;
1113 }
1114 if (scnhdr_int->s_nreloc <= 0xffff)
1115 bfd_h_put_16(abfd, scnhdr_int->s_nreloc, (bfd_byte *) scnhdr_ext->s_nreloc);
1116 else
1117 {
1118 (*_bfd_error_handler) ("%s: reloc overflow: 0x%lx > 0xffff",
1119 bfd_get_filename (abfd),
1120 scnhdr_int->s_nreloc);
1121 bfd_set_error (bfd_error_file_truncated);
1122 bfd_h_put_16 (abfd, 0xffff, (bfd_byte *) scnhdr_ext->s_nreloc);
1123 ret = 0;
1124 }
1125 return ret;
1126}
4b71e164
ILT
1127
1128static char * dir_names[IMAGE_NUMBEROF_DIRECTORY_ENTRIES] =
1129{
1130 "Export Directory [.edata]",
1131 "Import Directory [parts of .idata]",
1132 "Resource Directory [.rsrc]",
1133 "Exception Directory [.pdata]",
1134 "Security Directory",
1135 "Base Relocation Directory [.reloc]",
1136 "Debug Directory",
1137 "Description Directory",
1138 "Special Directory",
1139 "Thread Storage Directory [.tls]",
1140 "Load Configuration Directory",
a9713b91
ILT
1141 "Bound Import Directory",
1142 "Import Address Table Directory",
4b71e164
ILT
1143 "Reserved",
1144 "Reserved",
1145 "Reserved"
1146};
1147
4e98461f
SC
1148/**********************************************************************/
1149static boolean
4b71e164
ILT
1150pe_print_idata(abfd, vfile)
1151 bfd*abfd;
1152 void *vfile;
1153{
1154 FILE *file = vfile;
1155 bfd_byte *data = 0;
1156 asection *section = bfd_get_section_by_name (abfd, ".idata");
1157
1158#ifdef POWERPC_LE_PE
1159 asection *rel_section = bfd_get_section_by_name (abfd, ".reldata");
1160#endif
1161
1162 bfd_size_type datasize = 0;
1163 bfd_size_type i;
1164 bfd_size_type start, stop;
1165 int onaline = 20;
4b71e164
ILT
1166
1167 pe_data_type *pe = pe_data (abfd);
1168 struct internal_extra_pe_aouthdr *extra = &pe->pe_opthdr;
1169
1170 if (section == 0)
1171 return true;
1172
1173#ifdef POWERPC_LE_PE
1174 if (rel_section != 0 && bfd_section_size (abfd, rel_section) != 0)
1175 {
1176 /* The toc address can be found by taking the starting address,
1177 which on the PPC locates a function descriptor. The descriptor
1178 consists of the function code starting address followed by the
1179 address of the toc. The starting address we get from the bfd,
1180 and the descriptor is supposed to be in the .reldata section.
1181 */
1182
187783e0
ILT
1183 bfd_vma loadable_toc_address;
1184 bfd_vma toc_address;
1185 bfd_vma start_address;
4b71e164
ILT
1186 bfd_byte *data = 0;
1187 int offset;
58142f10
ILT
1188 data = (bfd_byte *) bfd_malloc ((size_t) bfd_section_size (abfd,
1189 rel_section));
b00c57ec 1190 if (data == NULL && bfd_section_size (abfd, rel_section) != 0)
58142f10 1191 return false;
53d45489 1192
4b71e164
ILT
1193 datasize = bfd_section_size (abfd, rel_section);
1194
1195 bfd_get_section_contents (abfd,
1196 rel_section,
1197 (PTR) data, 0,
1198 bfd_section_size (abfd, rel_section));
1199
1200 offset = abfd->start_address - rel_section->vma;
1201
1202 start_address = bfd_get_32(abfd, data+offset);
1203 loadable_toc_address = bfd_get_32(abfd, data+offset+4);
1204 toc_address = loadable_toc_address - 32768;
53d45489 1205
4b71e164 1206 fprintf(file,
53d45489
KK
1207 "\nFunction descriptor located at the start address: %04lx\n",
1208 (unsigned long int) (abfd->start_address));
4b71e164 1209 fprintf (file,
53d45489 1210 "\tcode-base %08lx toc (loadable/actual) %08lx/%08lx\n",
4b71e164
ILT
1211 start_address, loadable_toc_address, toc_address);
1212 }
4b71e164
ILT
1213#endif
1214
1215 fprintf(file,
1216 "\nThe Import Tables (interpreted .idata section contents)\n");
1217 fprintf(file,
1218 " vma: Hint Time Forward DLL First\n");
1219 fprintf(file,
1220 " Table Stamp Chain Name Thunk\n");
1221
1222 if (bfd_section_size (abfd, section) == 0)
1223 return true;
1224
58142f10 1225 data = (bfd_byte *) bfd_malloc ((size_t) bfd_section_size (abfd, section));
4b71e164 1226 datasize = bfd_section_size (abfd, section);
b00c57ec 1227 if (data == NULL && datasize != 0)
58142f10 1228 return false;
4b71e164
ILT
1229
1230 bfd_get_section_contents (abfd,
1231 section,
1232 (PTR) data, 0,
1233 bfd_section_size (abfd, section));
1234
1235 start = 0;
1236
1237 stop = bfd_section_size (abfd, section);
1238
1239 for (i = start; i < stop; i += onaline)
1240 {
1241 bfd_vma hint_addr;
1242 bfd_vma time_stamp;
1243 bfd_vma forward_chain;
1244 bfd_vma dll_name;
1245 bfd_vma first_thunk;
1246 int idx;
1247 int j;
1248 char *dll;
1249 int adj = extra->ImageBase - section->vma;
1250
1251 fprintf (file,
1252 " %04lx\t",
1253 (unsigned long int) (i + section->vma));
1254
1255 if (i+20 > stop)
1256 {
1257 /* check stuff */
1258 ;
1259 }
1260
1261 hint_addr = bfd_get_32(abfd, data+i);
1262 time_stamp = bfd_get_32(abfd, data+i+4);
1263 forward_chain = bfd_get_32(abfd, data+i+8);
1264 dll_name = bfd_get_32(abfd, data+i+12);
1265 first_thunk = bfd_get_32(abfd, data+i+16);
1266
1267 fprintf(file, "%08lx %08lx %08lx %08lx %08lx\n",
1268 hint_addr,
1269 time_stamp,
1270 forward_chain,
1271 dll_name,
1272 first_thunk);
1273
1274 if (hint_addr ==0)
1275 {
1276 break;
1277 }
1278
1279 /* the image base is present in the section->vma */
1280 dll = data + dll_name + adj;
1281 fprintf(file, "\n\tDLL Name: %s\n", dll);
1282 fprintf(file, "\tvma: Ordinal Member-Name\n");
1283
1284 idx = hint_addr + adj;
1285
1286 for (j=0;j<stop;j+=4)
1287 {
1288 int ordinal;
1289 char *member_name;
1290 bfd_vma member = bfd_get_32(abfd, data + idx + j);
1291 if (member == 0)
1292 break;
1293 ordinal = bfd_get_16(abfd,
1294 data + member + adj);
1295 member_name = data + member + adj + 2;
1296 fprintf(file, "\t%04lx\t %4d %s\n",
1297 member, ordinal, member_name);
1298 }
1299
1300 if (hint_addr != first_thunk)
1301 {
1302 int differ = 0;
1303 int idx2;
1304
1305 idx2 = first_thunk + adj;
1306
1307 for (j=0;j<stop;j+=4)
1308 {
1309 int ordinal;
1310 char *member_name;
1311 bfd_vma hint_member = bfd_get_32(abfd, data + idx + j);
1312 bfd_vma iat_member = bfd_get_32(abfd, data + idx2 + j);
1313 if (hint_member != iat_member)
1314 {
1315 if (differ == 0)
1316 {
1317 fprintf(file,
1318 "\tThe Import Address Table (difference found)\n");
1319 fprintf(file, "\tvma: Ordinal Member-Name\n");
1320 differ = 1;
1321 }
1322 if (iat_member == 0)
1323 {
1324 fprintf(file,
1325 "\t>>> Ran out of IAT members!\n");
1326 }
1327 else
1328 {
1329 ordinal = bfd_get_16(abfd,
1330 data + iat_member + adj);
1331 member_name = data + iat_member + adj + 2;
1332 fprintf(file, "\t%04lx\t %4d %s\n",
1333 iat_member, ordinal, member_name);
1334 }
1335 break;
1336 }
1337 if (hint_member == 0)
1338 break;
1339 }
1340 if (differ == 0)
1341 {
1342 fprintf(file,
1343 "\tThe Import Address Table is identical\n");
1344 }
1345 }
1346
1347 fprintf(file, "\n");
1348
1349 }
1350
53d45489 1351 free (data);
187783e0
ILT
1352
1353 return true;
53d45489
KK
1354}
1355
1356static boolean
1357pe_print_edata(abfd, vfile)
1358 bfd*abfd;
1359 void *vfile;
1360{
1361 FILE *file = vfile;
1362 bfd_byte *data = 0;
1363 asection *section = bfd_get_section_by_name (abfd, ".edata");
1364
1365 bfd_size_type datasize = 0;
1366 bfd_size_type i;
1367
1368 int adj;
1369 struct EDT_type
1370 {
1371 long export_flags; /* reserved - should be zero */
1372 long time_stamp;
1373 short major_ver;
1374 short minor_ver;
1375 bfd_vma name; /* rva - relative to image base */
1376 long base; /* ordinal base */
1377 long num_functions; /* Number in the export address table */
1378 long num_names; /* Number in the name pointer table */
1379 bfd_vma eat_addr; /* rva to the export address table */
1380 bfd_vma npt_addr; /* rva to the Export Name Pointer Table */
1381 bfd_vma ot_addr; /* rva to the Ordinal Table */
1382 } edt;
1383
1384 pe_data_type *pe = pe_data (abfd);
1385 struct internal_extra_pe_aouthdr *extra = &pe->pe_opthdr;
1386
1387 if (section == 0)
1388 return true;
1389
1390 data = (bfd_byte *) bfd_malloc ((size_t) bfd_section_size (abfd,
1391 section));
1392 datasize = bfd_section_size (abfd, section);
1393
1394 if (data == NULL && datasize != 0)
1395 return false;
1396
1397 bfd_get_section_contents (abfd,
1398 section,
1399 (PTR) data, 0,
1400 bfd_section_size (abfd, section));
1401
1402 /* Go get Export Directory Table */
1403 edt.export_flags = bfd_get_32(abfd, data+0);
1404 edt.time_stamp = bfd_get_32(abfd, data+4);
1405 edt.major_ver = bfd_get_16(abfd, data+8);
1406 edt.minor_ver = bfd_get_16(abfd, data+10);
1407 edt.name = bfd_get_32(abfd, data+12);
1408 edt.base = bfd_get_32(abfd, data+16);
1409 edt.num_functions = bfd_get_32(abfd, data+20);
1410 edt.num_names = bfd_get_32(abfd, data+24);
1411 edt.eat_addr = bfd_get_32(abfd, data+28);
1412 edt.npt_addr = bfd_get_32(abfd, data+32);
1413 edt.ot_addr = bfd_get_32(abfd, data+36);
1414
1415 adj = extra->ImageBase - section->vma;
1416
1417
1418 /* Dump the EDT first first */
1419 fprintf(file,
1420 "\nThe Export Tables (interpreted .edata section contents)\n\n");
1421
1422 fprintf(file,
187783e0 1423 "Export Flags \t\t\t%lx\n", (unsigned long) edt.export_flags);
53d45489
KK
1424
1425 fprintf(file,
187783e0 1426 "Time/Date stamp \t\t%lx\n", (unsigned long) edt.time_stamp);
53d45489
KK
1427
1428 fprintf(file,
1429 "Major/Minor \t\t\t%d/%d\n", edt.major_ver, edt.minor_ver);
1430
187783e0
ILT
1431 fprintf (file,
1432 "Name \t\t\t\t");
1433 fprintf_vma (file, edt.name);
1434 fprintf (file,
1435 "%s\n", data + edt.name + adj);
53d45489
KK
1436
1437 fprintf(file,
187783e0 1438 "Ordinal Base \t\t\t%ld\n", edt.base);
53d45489
KK
1439
1440 fprintf(file,
1441 "Number in:\n");
1442
1443 fprintf(file,
187783e0
ILT
1444 "\tExport Address Table \t\t%lx\n",
1445 (unsigned long) edt.num_functions);
53d45489
KK
1446
1447 fprintf(file,
187783e0 1448 "\t[Name Pointer/Ordinal] Table\t%ld\n", edt.num_names);
53d45489
KK
1449
1450 fprintf(file,
1451 "Table Addresses\n");
1452
187783e0
ILT
1453 fprintf (file,
1454 "\tExport Address Table \t\t");
1455 fprintf_vma (file, edt.eat_addr);
1456 fprintf (file, "\n");
53d45489 1457
187783e0
ILT
1458 fprintf (file,
1459 "\tName Pointer Table \t\t");
1460 fprintf_vma (file, edt.npt_addr);
1461 fprintf (file, "\n");
53d45489 1462
187783e0
ILT
1463 fprintf (file,
1464 "\tOrdinal Table \t\t\t");
1465 fprintf_vma (file, edt.ot_addr);
1466 fprintf (file, "\n");
53d45489
KK
1467
1468
1469 /* The next table to find si the Export Address Table. It's basically
1470 a list of pointers that either locate a function in this dll, or
1471 forward the call to another dll. Something like:
1472 typedef union
1473 {
1474 long export_rva;
1475 long forwarder_rva;
1476 } export_address_table_entry;
1477 */
1478
1479 fprintf(file,
187783e0 1480 "\nExport Address Table -- Ordinal Base %ld\n",
53d45489
KK
1481 edt.base);
1482
1483 for (i = 0; i < edt.num_functions; ++i)
1484 {
1485 bfd_vma eat_member = bfd_get_32(abfd,
1486 data + edt.eat_addr + (i*4) + adj);
1487 bfd_vma eat_actual = extra->ImageBase + eat_member;
1488 bfd_vma edata_start = bfd_get_section_vma(abfd,section);
1489 bfd_vma edata_end = edata_start + bfd_section_size (abfd, section);
1490
1491
1492 if (eat_member == 0)
1493 continue;
1494
1495 if (edata_start < eat_actual && eat_actual < edata_end)
1496 {
1497 /* this rva is to a name (forwarding function) in our section */
1498 /* Should locate a function descriptor */
1499 fprintf(file,
187783e0
ILT
1500 "\t[%4ld] +base[%4ld] %04lx %s -- %s\n",
1501 (long) i, (long) (i + edt.base), eat_member,
1502 "Forwarder RVA", data + eat_member + adj);
53d45489
KK
1503 }
1504 else
1505 {
1506 /* Should locate a function descriptor in the reldata section */
1507 fprintf(file,
187783e0
ILT
1508 "\t[%4ld] +base[%4ld] %04lx %s\n",
1509 (long) i, (long) (i + edt.base), eat_member, "Export RVA");
53d45489
KK
1510 }
1511 }
1512
1513 /* The Export Name Pointer Table is paired with the Export Ordinal Table */
1514 /* Dump them in parallel for clarity */
1515 fprintf(file,
1516 "\n[Ordinal/Name Pointer] Table\n");
1517
1518 for (i = 0; i < edt.num_names; ++i)
1519 {
1520 bfd_vma name_ptr = bfd_get_32(abfd,
1521 data +
1522 edt.npt_addr
1523 + (i*4) + adj);
1524
1525 char *name = data + name_ptr + adj;
1526
1527 bfd_vma ord = bfd_get_16(abfd,
1528 data +
1529 edt.ot_addr
1530 + (i*2) + adj);
1531 fprintf(file,
187783e0 1532 "\t[%4ld] %s\n", (long) ord, name);
53d45489
KK
1533
1534 }
4b71e164
ILT
1535
1536 free (data);
187783e0
ILT
1537
1538 return true;
4b71e164 1539}
53d45489 1540
4b71e164
ILT
1541static boolean
1542pe_print_pdata(abfd, vfile)
4e98461f
SC
1543 bfd*abfd;
1544 void *vfile;
4b71e164
ILT
1545{
1546 FILE *file = vfile;
1547 bfd_byte *data = 0;
1548 asection *section = bfd_get_section_by_name (abfd, ".pdata");
1549 bfd_size_type datasize = 0;
1550 bfd_size_type i;
1551 bfd_size_type start, stop;
1552 int onaline = 20;
4b71e164
ILT
1553
1554 if (section == 0)
1555 return true;
1556
187783e0
ILT
1557 stop = bfd_section_size (abfd, section);
1558 if ((stop % onaline) != 0)
1559 fprintf (file, "Warning, .pdata section size (%ld) is not a multiple of %d\n",
1560 (long)stop, onaline);
1561
4b71e164
ILT
1562 fprintf(file,
1563 "\nThe Function Table (interpreted .pdata section contents)\n");
1564 fprintf(file,
53d45489 1565 " vma:\t\tBegin End EH EH PrologEnd\n");
4b71e164 1566 fprintf(file,
53d45489 1567 " \t\tAddress Address Handler Data Address\n");
4b71e164
ILT
1568
1569 if (bfd_section_size (abfd, section) == 0)
1570 return true;
1571
58142f10 1572 data = (bfd_byte *) bfd_malloc ((size_t) bfd_section_size (abfd, section));
4b71e164 1573 datasize = bfd_section_size (abfd, section);
b00c57ec 1574 if (data == NULL && datasize != 0)
58142f10 1575 return false;
4b71e164
ILT
1576
1577 bfd_get_section_contents (abfd,
1578 section,
1579 (PTR) data, 0,
1580 bfd_section_size (abfd, section));
1581
1582 start = 0;
1583
4b71e164
ILT
1584 for (i = start; i < stop; i += onaline)
1585 {
1586 bfd_vma begin_addr;
1587 bfd_vma end_addr;
1588 bfd_vma eh_handler;
1589 bfd_vma eh_data;
1590 bfd_vma prolog_end_addr;
1591
1592 if (i+20 > stop)
1593 break;
1594
1595 begin_addr = bfd_get_32(abfd, data+i);
1596 end_addr = bfd_get_32(abfd, data+i+4);
1597 eh_handler = bfd_get_32(abfd, data+i+8);
1598 eh_data = bfd_get_32(abfd, data+i+12);
1599 prolog_end_addr = bfd_get_32(abfd, data+i+16);
1600
187783e0
ILT
1601 if (begin_addr == 0 && end_addr == 0 && eh_handler == 0
1602 && eh_data == 0 && prolog_end_addr == 0)
4b71e164
ILT
1603 {
1604 /* We are probably into the padding of the
1605 section now */
1606 break;
1607 }
1608
1609 fprintf (file,
53d45489 1610 " %08lx\t",
4b71e164
ILT
1611 (unsigned long int) (i + section->vma));
1612
1613 fprintf(file, "%08lx %08lx %08lx %08lx %08lx",
1614 begin_addr,
1615 end_addr,
1616 eh_handler,
1617 eh_data,
1618 prolog_end_addr);
1619
1620#ifdef POWERPC_LE_PE
1621 if (eh_handler == 0 && eh_data != 0)
1622 {
1623 /* Special bits here, although the meaning may */
1624 /* be a little mysterious. The only one I know */
1625 /* for sure is 0x03. */
1626 /* Code Significance */
1627 /* 0x00 None */
1628 /* 0x01 Register Save Millicode */
1629 /* 0x02 Register Restore Millicode */
1630 /* 0x03 Glue Code Sequence */
1631 switch (eh_data)
1632 {
1633 case 0x01:
1634 fprintf(file, " Register save millicode");
1635 break;
1636 case 0x02:
1637 fprintf(file, " Register restore millicode");
1638 break;
1639 case 0x03:
1640 fprintf(file, " Glue code sequence");
1641 break;
1642 default:
1643 break;
1644 }
1645 }
1646#endif
1647 fprintf(file, "\n");
1648 }
1649
1650 free (data);
187783e0
ILT
1651
1652 return true;
4b71e164
ILT
1653}
1654
caa740be
KK
1655static const char *tbl[6] =
1656{
1657"ABSOLUTE",
1658"HIGH",
1659"LOW",
1660"HIGHLOW",
1661"HIGHADJ",
1662"unknown"
1663};
1664
1665static boolean
1666pe_print_reloc(abfd, vfile)
1667 bfd*abfd;
1668 void *vfile;
1669{
1670 FILE *file = vfile;
1671 bfd_byte *data = 0;
1672 asection *section = bfd_get_section_by_name (abfd, ".reloc");
1673 bfd_size_type datasize = 0;
1674 bfd_size_type i;
1675 bfd_size_type start, stop;
caa740be
KK
1676
1677 if (section == 0)
1678 return true;
1679
1680 if (bfd_section_size (abfd, section) == 0)
1681 return true;
1682
1683 fprintf(file,
1684 "\n\nPE File Base Relocations (interpreted .reloc"
1685 " section contents)\n");
1686
1687 data = (bfd_byte *) bfd_malloc ((size_t) bfd_section_size (abfd, section));
1688 datasize = bfd_section_size (abfd, section);
1689 if (data == NULL && datasize != 0)
1690 return false;
1691
1692 bfd_get_section_contents (abfd,
1693 section,
1694 (PTR) data, 0,
1695 bfd_section_size (abfd, section));
1696
1697 start = 0;
1698
1699 stop = bfd_section_size (abfd, section);
1700
1701 for (i = start; i < stop;)
1702 {
1703 int j;
1704 bfd_vma virtual_address;
1705 long number, size;
1706
1707 /* The .reloc section is a sequence of blocks, with a header consisting
1708 of two 32 bit quantities, followed by a number of 16 bit entries */
1709
1710 virtual_address = bfd_get_32(abfd, data+i);
1711 size = bfd_get_32(abfd, data+i+4);
1712 number = (size - 8) / 2;
1713
1714 if (size == 0)
1715 {
1716 break;
1717 }
1718
1719 fprintf (file,
187783e0 1720 "\nVirtual Address: %08lx Chunk size %ld (0x%lx) Number of fixups %ld\n",
caa740be
KK
1721 virtual_address, size, size, number);
1722
1723 for (j = 0; j < number; ++j)
1724 {
1725 unsigned short e = bfd_get_16(abfd, data + i + 8 + j*2);
1726 int t = (e & 0xF000) >> 12;
1727 int off = e & 0x0FFF;
1728
1729 if (t > 5)
1730 abort();
1731
1732 fprintf(file,
187783e0
ILT
1733 "\treloc %4d offset %4x [%4lx] %s\n",
1734 j, off, (long) (off + virtual_address), tbl[t]);
caa740be
KK
1735
1736 }
1737 i += size;
1738 }
1739
1740 free (data);
187783e0
ILT
1741
1742 return true;
caa740be
KK
1743}
1744
4b71e164
ILT
1745static boolean
1746pe_print_private_bfd_data (abfd, vfile)
1747 bfd *abfd;
a9713b91 1748 PTR vfile;
4e98461f 1749{
a9713b91 1750 FILE *file = (FILE *) vfile;
4e98461f
SC
1751 int j;
1752 pe_data_type *pe = pe_data (abfd);
1753 struct internal_extra_pe_aouthdr *i = &pe->pe_opthdr;
4b71e164 1754
db344f82 1755 fprintf (file,"\nImageBase\t\t");
ae115e51 1756 fprintf_vma (file, i->ImageBase);
db344f82 1757 fprintf (file,"\nSectionAlignment\t");
ae115e51 1758 fprintf_vma (file, i->SectionAlignment);
db344f82 1759 fprintf (file,"\nFileAlignment\t\t");
ae115e51 1760 fprintf_vma (file, i->FileAlignment);
db344f82 1761 fprintf (file,"\nMajorOSystemVersion\t%d\n", i->MajorOperatingSystemVersion);
4e98461f
SC
1762 fprintf (file,"MinorOSystemVersion\t%d\n", i->MinorOperatingSystemVersion);
1763 fprintf (file,"MajorImageVersion\t%d\n", i->MajorImageVersion);
1764 fprintf (file,"MinorImageVersion\t%d\n", i->MinorImageVersion);
1765 fprintf (file,"MajorSubsystemVersion\t%d\n", i->MajorSubsystemVersion);
1766 fprintf (file,"MinorSubsystemVersion\t%d\n", i->MinorSubsystemVersion);
ae115e51
ILT
1767 fprintf (file,"Reserved1\t\t%08lx\n", i->Reserved1);
1768 fprintf (file,"SizeOfImage\t\t%08lx\n", i->SizeOfImage);
1769 fprintf (file,"SizeOfHeaders\t\t%08lx\n", i->SizeOfHeaders);
1770 fprintf (file,"CheckSum\t\t%08lx\n", i->CheckSum);
4e98461f
SC
1771 fprintf (file,"Subsystem\t\t%08x\n", i->Subsystem);
1772 fprintf (file,"DllCharacteristics\t%08x\n", i->DllCharacteristics);
ae115e51
ILT
1773 fprintf (file,"SizeOfStackReserve\t");
1774 fprintf_vma (file, i->SizeOfStackReserve);
db344f82 1775 fprintf (file,"\nSizeOfStackCommit\t");
ae115e51 1776 fprintf_vma (file, i->SizeOfStackCommit);
db344f82 1777 fprintf (file,"\nSizeOfHeapReserve\t");
ae115e51 1778 fprintf_vma (file, i->SizeOfHeapReserve);
db344f82 1779 fprintf (file,"\nSizeOfHeapCommit\t");
ae115e51 1780 fprintf_vma (file, i->SizeOfHeapCommit);
db344f82 1781 fprintf (file,"\nLoaderFlags\t\t%08lx\n", i->LoaderFlags);
ae115e51 1782 fprintf (file,"NumberOfRvaAndSizes\t%08lx\n", i->NumberOfRvaAndSizes);
4e98461f 1783
4b71e164 1784 fprintf (file,"\nThe Data Directory\n");
4e98461f
SC
1785 for (j = 0; j < IMAGE_NUMBEROF_DIRECTORY_ENTRIES; j++)
1786 {
4b71e164 1787 fprintf (file, "Entry %1x ", j);
ae115e51 1788 fprintf_vma (file, i->DataDirectory[j].VirtualAddress);
4b71e164
ILT
1789 fprintf (file, " %08lx ", i->DataDirectory[j].Size);
1790 fprintf (file, "%s\n", dir_names[j]);
4e98461f 1791 }
ae115e51 1792
4b71e164 1793 pe_print_idata(abfd, vfile);
53d45489 1794 pe_print_edata(abfd, vfile);
4b71e164 1795 pe_print_pdata(abfd, vfile);
caa740be 1796 pe_print_reloc(abfd, vfile);
4b71e164 1797
ae115e51 1798 return true;
4e98461f
SC
1799}
1800
1801static boolean
1802pe_mkobject (abfd)
1803 bfd * abfd;
1804{
1805 pe_data_type *pe;
4e98461f
SC
1806 abfd->tdata.pe_obj_data =
1807 (struct pe_tdata *) bfd_zalloc (abfd, sizeof (pe_data_type));
dff77ed7 1808
4e98461f 1809 if (abfd->tdata.pe_obj_data == 0)
a9713b91 1810 return false;
dff77ed7
SC
1811
1812 pe = pe_data (abfd);
1813
4e98461f 1814 pe->coff.pe = 1;
dff77ed7 1815 pe->in_reloc_p = in_reloc_p;
4e98461f
SC
1816 return true;
1817}
1818
1819/* Create the COFF backend specific information. */
1820static PTR
1821pe_mkobject_hook (abfd, filehdr, aouthdr)
1822 bfd * abfd;
1823 PTR filehdr;
1824 PTR aouthdr;
1825{
1826 struct internal_filehdr *internal_f = (struct internal_filehdr *) filehdr;
1827 pe_data_type *pe;
1828
1829 if (pe_mkobject (abfd) == false)
1830 return NULL;
1831
1832 pe = pe_data (abfd);
4e98461f 1833 pe->coff.sym_filepos = internal_f->f_symptr;
4e98461f
SC
1834 /* These members communicate important constants about the symbol
1835 table to GDB's symbol-reading code. These `constants'
1836 unfortunately vary among coff implementations... */
1837 pe->coff.local_n_btmask = N_BTMASK;
1838 pe->coff.local_n_btshft = N_BTSHFT;
1839 pe->coff.local_n_tmask = N_TMASK;
1840 pe->coff.local_n_tshift = N_TSHIFT;
1841 pe->coff.local_symesz = SYMESZ;
1842 pe->coff.local_auxesz = AUXESZ;
1843 pe->coff.local_linesz = LINESZ;
1844
1845 obj_raw_syment_count (abfd) =
1846 obj_conv_table_size (abfd) =
1847 internal_f->f_nsyms;
1848
4b71e164 1849 pe->real_flags = internal_f->f_flags;
dff77ed7 1850
db344f82 1851#ifdef COFF_IMAGE_WITH_PE
dff77ed7
SC
1852 if (aouthdr)
1853 {
1854 pe->pe_opthdr = ((struct internal_aouthdr *)aouthdr)->pe;
1855 }
db344f82
SC
1856#endif
1857
4e98461f
SC
1858 return (PTR) pe;
1859}
1860
1861
1862
db344f82
SC
1863/* Copy any private info we understand from the input bfd
1864 to the output bfd. */
1865
1866#define coff_bfd_copy_private_bfd_data pe_bfd_copy_private_bfd_data
1867
1868static boolean
1869pe_bfd_copy_private_bfd_data (ibfd, obfd)
1870 bfd *ibfd, *obfd;
1871{
1872 /* One day we may try to grok other private data. */
1873 if (ibfd->xvec->flavour != bfd_target_coff_flavour
1874 || obfd->xvec->flavour != bfd_target_coff_flavour)
1875 return true;
1876
1877 pe_data(obfd)->pe_opthdr = pe_data (ibfd)->pe_opthdr;
1878
1879 return true;
1880}
This page took 0.154481 seconds and 4 git commands to generate.