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