]> Git Repo - binutils.git/blob - bfd/peicode.h
* xcofflink.c (xcoff_mark_symbol): New static function, broken out
[binutils.git] / bfd / peicode.h
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
5 This file is part of BFD, the Binary File Descriptor library.
6
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
11
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
20
21 /*
22 Most of this hacked by  Steve Chamberlain,
23                         [email protected]
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
32 #ifndef GET_FCN_LNNOPTR
33 #define GET_FCN_LNNOPTR(abfd, ext) \
34      bfd_h_get_32(abfd, (bfd_byte *) ext->x_sym.x_fcnary.x_fcn.x_lnnoptr)
35 #endif
36
37 #ifndef GET_FCN_ENDNDX
38 #define GET_FCN_ENDNDX(abfd, ext)  \
39         bfd_h_get_32(abfd, (bfd_byte *) ext->x_sym.x_fcnary.x_fcn.x_endndx)
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
173 static void
174 coff_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
191
192 }
193
194
195 static unsigned int
196 coff_swap_reloc_out (abfd, src, dst)
197      bfd       *abfd;
198      PTR        src;
199      PTR        dst;
200 {
201   struct internal_reloc *reloc_src = (struct internal_reloc *)src;
202   struct external_reloc *reloc_dst = (struct external_reloc *)dst;
203   bfd_h_put_32(abfd, reloc_src->r_vaddr, (bfd_byte *) reloc_dst->r_vaddr);
204   bfd_h_put_32(abfd, reloc_src->r_symndx, (bfd_byte *) reloc_dst->r_symndx);
205
206   bfd_h_put_16(abfd, reloc_src->r_type, (bfd_byte *)
207                reloc_dst->r_type);
208
209 #ifdef SWAP_OUT_RELOC_OFFSET
210   SWAP_OUT_RELOC_OFFSET(abfd,
211                         reloc_src->r_offset,
212                         (bfd_byte *) reloc_dst->r_offset);
213 #endif
214 #ifdef SWAP_OUT_RELOC_EXTRA
215   SWAP_OUT_RELOC_EXTRA(abfd,reloc_src, reloc_dst);
216 #endif
217   return sizeof(struct external_reloc);
218 }
219
220
221 static void
222 coff_swap_filehdr_in (abfd, src, dst)
223      bfd            *abfd;
224      PTR             src;
225      PTR             dst;
226 {
227   FILHDR *filehdr_src = (FILHDR *) src;
228   struct internal_filehdr *filehdr_dst = (struct internal_filehdr *) dst;
229   filehdr_dst->f_magic = bfd_h_get_16(abfd, (bfd_byte *) filehdr_src->f_magic);
230   filehdr_dst->f_nscns = bfd_h_get_16(abfd, (bfd_byte *)filehdr_src-> f_nscns);
231   filehdr_dst->f_timdat = bfd_h_get_32(abfd, (bfd_byte *)filehdr_src-> f_timdat);
232
233   filehdr_dst->f_nsyms = bfd_h_get_32(abfd, (bfd_byte *)filehdr_src-> f_nsyms);
234   filehdr_dst->f_flags = bfd_h_get_16(abfd, (bfd_byte *)filehdr_src-> f_flags);
235   filehdr_dst->f_symptr = bfd_h_get_32 (abfd, (bfd_byte *) filehdr_src->f_symptr);
236
237   /* Other people's tools sometimes generate headers
238      with an nsyms but a zero symptr. */
239   if (filehdr_dst->f_nsyms && filehdr_dst->f_symptr)
240     {
241       filehdr_dst->f_flags |= HAS_SYMS;
242     }
243   else 
244     {
245       filehdr_dst->f_symptr = 0;
246       filehdr_dst->f_nsyms = 0;
247       filehdr_dst->f_flags &= ~HAS_SYMS;
248     }
249
250   filehdr_dst->f_opthdr = bfd_h_get_16(abfd, (bfd_byte *)filehdr_src-> f_opthdr);
251 }
252
253 #ifdef COFF_IMAGE_WITH_PE
254
255 static  unsigned int
256 coff_swap_filehdr_out (abfd, in, out)
257      bfd       *abfd;
258      PTR        in;
259      PTR        out;
260 {
261   int idx;
262   struct internal_filehdr *filehdr_in = (struct internal_filehdr *)in;
263   FILHDR *filehdr_out = (FILHDR *)out;
264
265   if (pe_data (abfd)->has_reloc_section)
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;
285
286   for (idx=0; idx < 4; idx++)
287     filehdr_in->pe.e_res[idx] = 0x0;
288
289   filehdr_in->pe.e_oemid   = 0x0;
290   filehdr_in->pe.e_oeminfo = 0x0;
291
292   for (idx=0; idx < 10; idx++)
293     filehdr_in->pe.e_res2[idx] = 0x0;
294
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
329
330   /* put in extra dos header stuff.  This data remains essentially
331      constant, it just has to be tacked on to the beginning of all exes 
332      for NT */
333   bfd_h_put_16(abfd, filehdr_in->pe.e_magic, (bfd_byte *) filehdr_out->e_magic);
334   bfd_h_put_16(abfd, filehdr_in->pe.e_cblp, (bfd_byte *) filehdr_out->e_cblp);
335   bfd_h_put_16(abfd, filehdr_in->pe.e_cp, (bfd_byte *) filehdr_out->e_cp);
336   bfd_h_put_16(abfd, filehdr_in->pe.e_crlc, (bfd_byte *) filehdr_out->e_crlc);
337   bfd_h_put_16(abfd, filehdr_in->pe.e_cparhdr, 
338                (bfd_byte *) filehdr_out->e_cparhdr);
339   bfd_h_put_16(abfd, filehdr_in->pe.e_minalloc, 
340                (bfd_byte *) filehdr_out->e_minalloc);
341   bfd_h_put_16(abfd, filehdr_in->pe.e_maxalloc, 
342                (bfd_byte *) filehdr_out->e_maxalloc);
343   bfd_h_put_16(abfd, filehdr_in->pe.e_ss, (bfd_byte *) filehdr_out->e_ss);
344   bfd_h_put_16(abfd, filehdr_in->pe.e_sp, (bfd_byte *) filehdr_out->e_sp);
345   bfd_h_put_16(abfd, filehdr_in->pe.e_csum, (bfd_byte *) filehdr_out->e_csum);
346   bfd_h_put_16(abfd, filehdr_in->pe.e_ip, (bfd_byte *) filehdr_out->e_ip);
347   bfd_h_put_16(abfd, filehdr_in->pe.e_cs, (bfd_byte *) filehdr_out->e_cs);
348   bfd_h_put_16(abfd, filehdr_in->pe.e_lfarlc, (bfd_byte *) filehdr_out->e_lfarlc);
349   bfd_h_put_16(abfd, filehdr_in->pe.e_ovno, (bfd_byte *) filehdr_out->e_ovno);
350   {
351     int idx;
352     for (idx=0; idx < 4; idx++)
353       bfd_h_put_16(abfd, filehdr_in->pe.e_res[idx], 
354                    (bfd_byte *) filehdr_out->e_res[idx]);
355   }
356   bfd_h_put_16(abfd, filehdr_in->pe.e_oemid, (bfd_byte *) filehdr_out->e_oemid);
357   bfd_h_put_16(abfd, filehdr_in->pe.e_oeminfo,
358                (bfd_byte *) filehdr_out->e_oeminfo);
359   {
360     int idx;
361     for (idx=0; idx < 10; idx++)
362       bfd_h_put_16(abfd, filehdr_in->pe.e_res2[idx],
363                    (bfd_byte *) filehdr_out->e_res2[idx]);
364   }
365   bfd_h_put_32(abfd, filehdr_in->pe.e_lfanew, (bfd_byte *) filehdr_out->e_lfanew);
366
367   {
368     int idx;
369     for (idx=0; idx < 16; idx++)
370       bfd_h_put_32(abfd, filehdr_in->pe.dos_message[idx],
371                    (bfd_byte *) filehdr_out->dos_message[idx]);
372   }
373
374   /* also put in the NT signature */
375   bfd_h_put_32(abfd, filehdr_in->pe.nt_signature, 
376                (bfd_byte *) filehdr_out->nt_signature);
377
378
379
380
381   return sizeof(FILHDR);
382 }
383 #else
384
385 static  unsigned int
386 coff_swap_filehdr_out (abfd, in, out)
387      bfd       *abfd;
388      PTR        in;
389      PTR        out;
390 {
391   struct internal_filehdr *filehdr_in = (struct internal_filehdr *)in;
392   FILHDR *filehdr_out = (FILHDR *)out;
393
394   bfd_h_put_16(abfd, filehdr_in->f_magic, (bfd_byte *) filehdr_out->f_magic);
395   bfd_h_put_16(abfd, filehdr_in->f_nscns, (bfd_byte *) filehdr_out->f_nscns);
396   bfd_h_put_32(abfd, filehdr_in->f_timdat, (bfd_byte *) filehdr_out->f_timdat);
397   PUT_FILEHDR_SYMPTR (abfd, (bfd_vma) filehdr_in->f_symptr,
398                       (bfd_byte *) filehdr_out->f_symptr);
399   bfd_h_put_32(abfd, filehdr_in->f_nsyms, (bfd_byte *) filehdr_out->f_nsyms);
400   bfd_h_put_16(abfd, filehdr_in->f_opthdr, (bfd_byte *) filehdr_out->f_opthdr);
401   bfd_h_put_16(abfd, filehdr_in->f_flags, (bfd_byte *) filehdr_out->f_flags);
402
403   return sizeof(FILHDR);
404 }
405
406 #endif
407
408
409 static void
410 coff_swap_sym_in (abfd, ext1, in1)
411      bfd            *abfd;
412      PTR ext1;
413      PTR in1;
414 {
415   SYMENT *ext = (SYMENT *)ext1;
416   struct internal_syment      *in = (struct internal_syment *)in1;
417
418   if( ext->e.e_name[0] == 0) {
419     in->_n._n_n._n_zeroes = 0;
420     in->_n._n_n._n_offset = bfd_h_get_32(abfd, (bfd_byte *) ext->e.e.e_offset);
421   }
422   else {
423 #if SYMNMLEN != E_SYMNMLEN
424     -> Error, we need to cope with truncating or extending SYMNMLEN!;
425 #else
426     memcpy(in->_n._n_name, ext->e.e_name, SYMNMLEN);
427 #endif
428   }
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   }
458 }
459
460 static unsigned int
461 coff_swap_sym_out (abfd, inp, extp)
462      bfd       *abfd;
463      PTR        inp;
464      PTR        extp;
465 {
466   struct internal_syment *in = (struct internal_syment *)inp;
467   SYMENT *ext =(SYMENT *)extp;
468   if(in->_n._n_name[0] == 0) {
469     bfd_h_put_32(abfd, 0, (bfd_byte *) ext->e.e.e_zeroes);
470     bfd_h_put_32(abfd, in->_n._n_n._n_offset, (bfd_byte *)  ext->e.e.e_offset);
471   }
472   else {
473 #if SYMNMLEN != E_SYMNMLEN
474     -> Error, we need to cope with truncating or extending SYMNMLEN!;
475 #else
476     memcpy(ext->e.e_name, in->_n._n_name, SYMNMLEN);
477 #endif
478   }
479   bfd_h_put_32(abfd,  in->n_value , (bfd_byte *) ext->e_value);
480   bfd_h_put_16(abfd,  in->n_scnum , (bfd_byte *) ext->e_scnum);
481   if (sizeof(ext->e_type) == 2)
482     {
483       bfd_h_put_16(abfd,  in->n_type , (bfd_byte *) ext->e_type);
484     }
485   else
486     {
487       bfd_h_put_32(abfd,  in->n_type , (bfd_byte *) ext->e_type);
488     }
489   bfd_h_put_8(abfd,  in->n_sclass , ext->e_sclass);
490   bfd_h_put_8(abfd,  in->n_numaux , ext->e_numaux);
491   return sizeof(SYMENT);
492 }
493
494 static void
495 coff_swap_aux_in (abfd, ext1, type, class, indx, numaux, in1)
496      bfd            *abfd;
497      PTR              ext1;
498      int             type;
499      int             class;
500      int              indx;
501      int              numaux;
502      PTR              in1;
503 {
504   AUXENT    *ext = (AUXENT *)ext1;
505   union internal_auxent *in = (union internal_auxent *)in1;
506
507   switch (class) {
508   case C_FILE:
509     if (ext->x_file.x_fname[0] == 0) {
510       in->x_file.x_n.x_zeroes = 0;
511       in->x_file.x_n.x_offset = 
512         bfd_h_get_32(abfd, (bfd_byte *) ext->x_file.x_n.x_offset);
513     } else {
514 #if FILNMLEN != E_FILNMLEN
515       -> Error, we need to cope with truncating or extending FILNMLEN!;
516 #else
517       memcpy (in->x_file.x_fname, ext->x_file.x_fname, FILNMLEN);
518 #endif
519     }
520     return;
521
522
523   case C_STAT:
524 #ifdef C_LEAFSTAT
525   case C_LEAFSTAT:
526 #endif
527   case C_HIDDEN:
528     if (type == T_NULL) {
529       in->x_scn.x_scnlen = GET_SCN_SCNLEN(abfd, ext);
530       in->x_scn.x_nreloc = GET_SCN_NRELOC(abfd, ext);
531       in->x_scn.x_nlinno = GET_SCN_NLINNO(abfd, ext);
532       return;
533     }
534     break;
535   }
536
537   in->x_sym.x_tagndx.l = bfd_h_get_32(abfd, (bfd_byte *) ext->x_sym.x_tagndx);
538 #ifndef NO_TVNDX
539   in->x_sym.x_tvndx = bfd_h_get_16(abfd, (bfd_byte *) ext->x_sym.x_tvndx);
540 #endif
541
542   if (class == C_BLOCK || ISFCN (type) || ISTAG (class))
543     {
544       in->x_sym.x_fcnary.x_fcn.x_lnnoptr = GET_FCN_LNNOPTR (abfd, ext);
545       in->x_sym.x_fcnary.x_fcn.x_endndx.l = GET_FCN_ENDNDX (abfd, ext);
546     }
547   else
548     {
549 #if DIMNUM != E_DIMNUM
550  #error we need to cope with truncating or extending DIMNUM
551 #endif
552       in->x_sym.x_fcnary.x_ary.x_dimen[0] =
553         bfd_h_get_16 (abfd, (bfd_byte *) ext->x_sym.x_fcnary.x_ary.x_dimen[0]);
554       in->x_sym.x_fcnary.x_ary.x_dimen[1] =
555         bfd_h_get_16 (abfd, (bfd_byte *) ext->x_sym.x_fcnary.x_ary.x_dimen[1]);
556       in->x_sym.x_fcnary.x_ary.x_dimen[2] =
557         bfd_h_get_16 (abfd, (bfd_byte *) ext->x_sym.x_fcnary.x_ary.x_dimen[2]);
558       in->x_sym.x_fcnary.x_ary.x_dimen[3] =
559         bfd_h_get_16 (abfd, (bfd_byte *) ext->x_sym.x_fcnary.x_ary.x_dimen[3]);
560     }
561
562   if (ISFCN(type)) {
563     in->x_sym.x_misc.x_fsize = bfd_h_get_32(abfd, (bfd_byte *) ext->x_sym.x_misc.x_fsize);
564   }
565   else {
566     in->x_sym.x_misc.x_lnsz.x_lnno = GET_LNSZ_LNNO(abfd, ext);
567     in->x_sym.x_misc.x_lnsz.x_size = GET_LNSZ_SIZE(abfd, ext);
568   }
569 }
570
571 static unsigned int
572 coff_swap_aux_out (abfd, inp, type, class, indx, numaux, extp)
573      bfd   *abfd;
574      PTR        inp;
575      int   type;
576      int   class;
577      int   indx;
578      int   numaux;
579      PTR        extp;
580 {
581   union internal_auxent *in = (union internal_auxent *)inp;
582   AUXENT *ext = (AUXENT *)extp;
583
584   memset((PTR)ext, 0, AUXESZ);
585   switch (class) {
586   case C_FILE:
587     if (in->x_file.x_fname[0] == 0) {
588       bfd_h_put_32(abfd, 0, (bfd_byte *) ext->x_file.x_n.x_zeroes);
589       bfd_h_put_32(abfd,
590               in->x_file.x_n.x_offset,
591               (bfd_byte *) ext->x_file.x_n.x_offset);
592     }
593     else {
594 #if FILNMLEN != E_FILNMLEN
595       -> Error, we need to cope with truncating or extending FILNMLEN!;
596 #else
597       memcpy (ext->x_file.x_fname, in->x_file.x_fname, FILNMLEN);
598 #endif
599     }
600     return sizeof (AUXENT);
601
602
603   case C_STAT:
604 #ifdef C_LEAFSTAT
605   case C_LEAFSTAT:
606 #endif
607   case C_HIDDEN:
608     if (type == T_NULL) {
609       PUT_SCN_SCNLEN(abfd, in->x_scn.x_scnlen, ext);
610       PUT_SCN_NRELOC(abfd, in->x_scn.x_nreloc, ext);
611       PUT_SCN_NLINNO(abfd, in->x_scn.x_nlinno, ext);
612       return sizeof (AUXENT);
613     }
614     break;
615   }
616
617   bfd_h_put_32(abfd, in->x_sym.x_tagndx.l, (bfd_byte *) ext->x_sym.x_tagndx);
618 #ifndef NO_TVNDX
619   bfd_h_put_16(abfd, in->x_sym.x_tvndx , (bfd_byte *) ext->x_sym.x_tvndx);
620 #endif
621
622   if (class == C_BLOCK || ISFCN (type) || ISTAG (class))
623     {
624       PUT_FCN_LNNOPTR(abfd,  in->x_sym.x_fcnary.x_fcn.x_lnnoptr, ext);
625       PUT_FCN_ENDNDX(abfd,  in->x_sym.x_fcnary.x_fcn.x_endndx.l, ext);
626     }
627   else
628     {
629 #if DIMNUM != E_DIMNUM
630  #error we need to cope with truncating or extending DIMNUM
631 #endif
632       bfd_h_put_16 (abfd, in->x_sym.x_fcnary.x_ary.x_dimen[0],
633                     (bfd_byte *) ext->x_sym.x_fcnary.x_ary.x_dimen[0]);
634       bfd_h_put_16 (abfd, in->x_sym.x_fcnary.x_ary.x_dimen[1],
635                     (bfd_byte *) ext->x_sym.x_fcnary.x_ary.x_dimen[1]);
636       bfd_h_put_16 (abfd, in->x_sym.x_fcnary.x_ary.x_dimen[2],
637                     (bfd_byte *) ext->x_sym.x_fcnary.x_ary.x_dimen[2]);
638       bfd_h_put_16 (abfd, in->x_sym.x_fcnary.x_ary.x_dimen[3],
639                     (bfd_byte *) ext->x_sym.x_fcnary.x_ary.x_dimen[3]);
640     }
641
642   if (ISFCN (type))
643     bfd_h_put_32 (abfd, in->x_sym.x_misc.x_fsize,
644              (bfd_byte *)  ext->x_sym.x_misc.x_fsize);
645   else
646     {
647       PUT_LNSZ_LNNO (abfd, in->x_sym.x_misc.x_lnsz.x_lnno, ext);
648       PUT_LNSZ_SIZE (abfd, in->x_sym.x_misc.x_lnsz.x_size, ext);
649     }
650
651   return sizeof(AUXENT);
652 }
653
654
655 static void
656 coff_swap_lineno_in (abfd, ext1, in1)
657      bfd            *abfd;
658      PTR ext1;
659      PTR in1;
660 {
661   LINENO *ext = (LINENO *)ext1;
662   struct internal_lineno      *in = (struct internal_lineno *)in1;
663
664   in->l_addr.l_symndx = bfd_h_get_32(abfd, (bfd_byte *) ext->l_addr.l_symndx);
665   in->l_lnno = GET_LINENO_LNNO(abfd, ext);
666 }
667
668 static unsigned int
669 coff_swap_lineno_out (abfd, inp, outp)
670      bfd       *abfd;
671      PTR        inp;
672      PTR        outp;
673 {
674   struct internal_lineno *in = (struct internal_lineno *)inp;
675   struct external_lineno *ext = (struct external_lineno *)outp;
676   bfd_h_put_32(abfd, in->l_addr.l_symndx, (bfd_byte *)
677           ext->l_addr.l_symndx);
678
679   PUT_LINENO_LNNO (abfd, in->l_lnno, ext);
680   return sizeof(struct external_lineno);
681 }
682
683
684
685 static void
686 coff_swap_aouthdr_in (abfd, aouthdr_ext1, aouthdr_int1)
687      bfd            *abfd;
688      PTR aouthdr_ext1;
689      PTR aouthdr_int1;
690 {
691   struct internal_extra_pe_aouthdr *a;
692   PEAOUTHDR *src = (PEAOUTHDR *)(aouthdr_ext1);
693   AOUTHDR        *aouthdr_ext = (AOUTHDR *) aouthdr_ext1;
694   struct internal_aouthdr *aouthdr_int = (struct internal_aouthdr *)aouthdr_int1;
695
696   aouthdr_int->magic = bfd_h_get_16(abfd, (bfd_byte *) aouthdr_ext->magic);
697   aouthdr_int->vstamp = bfd_h_get_16(abfd, (bfd_byte *) aouthdr_ext->vstamp);
698   aouthdr_int->tsize =
699     GET_AOUTHDR_TSIZE (abfd, (bfd_byte *) aouthdr_ext->tsize);
700   aouthdr_int->dsize =
701     GET_AOUTHDR_DSIZE (abfd, (bfd_byte *) aouthdr_ext->dsize);
702   aouthdr_int->bsize =
703     GET_AOUTHDR_BSIZE (abfd, (bfd_byte *) aouthdr_ext->bsize);
704   aouthdr_int->entry =
705     GET_AOUTHDR_ENTRY (abfd, (bfd_byte *) aouthdr_ext->entry);
706   aouthdr_int->text_start =
707     GET_AOUTHDR_TEXT_START (abfd, (bfd_byte *) aouthdr_ext->text_start);
708   aouthdr_int->data_start =
709     GET_AOUTHDR_DATA_START (abfd, (bfd_byte *) aouthdr_ext->data_start);
710
711   a = &aouthdr_int->pe;
712   a->ImageBase = bfd_h_get_32 (abfd, src->ImageBase);
713   a->SectionAlignment = bfd_h_get_32 (abfd, src->SectionAlignment);
714   a->FileAlignment = bfd_h_get_32 (abfd, src->FileAlignment);
715   a->MajorOperatingSystemVersion = 
716     bfd_h_get_16 (abfd, src->MajorOperatingSystemVersion);
717   a->MinorOperatingSystemVersion = 
718     bfd_h_get_16 (abfd, src->MinorOperatingSystemVersion);
719   a->MajorImageVersion = bfd_h_get_16 (abfd, src->MajorImageVersion);
720   a->MinorImageVersion = bfd_h_get_16 (abfd, src->MinorImageVersion);
721   a->MajorSubsystemVersion = bfd_h_get_16 (abfd, src->MajorSubsystemVersion);
722   a->MinorSubsystemVersion = bfd_h_get_16 (abfd, src->MinorSubsystemVersion);
723   a->Reserved1 = bfd_h_get_32 (abfd, src->Reserved1);
724   a->SizeOfImage = bfd_h_get_32 (abfd, src->SizeOfImage);
725   a->SizeOfHeaders = bfd_h_get_32 (abfd, src->SizeOfHeaders);
726   a->CheckSum = bfd_h_get_32 (abfd, src->CheckSum);
727   a->Subsystem = bfd_h_get_16 (abfd, src->Subsystem);
728   a->DllCharacteristics = bfd_h_get_16 (abfd, src->DllCharacteristics);
729   a->SizeOfStackReserve = bfd_h_get_32 (abfd, src->SizeOfStackReserve);
730   a->SizeOfStackCommit = bfd_h_get_32 (abfd, src->SizeOfStackCommit);
731   a->SizeOfHeapReserve = bfd_h_get_32 (abfd, src->SizeOfHeapReserve);
732   a->SizeOfHeapCommit = bfd_h_get_32 (abfd, src->SizeOfHeapCommit);
733   a->LoaderFlags = bfd_h_get_32 (abfd, src->LoaderFlags);
734   a->NumberOfRvaAndSizes = bfd_h_get_32 (abfd, src->NumberOfRvaAndSizes);
735
736   {
737     int idx;
738     for (idx=0; idx < 16; idx++)
739       {
740         a->DataDirectory[idx].VirtualAddress =
741           bfd_h_get_32 (abfd, src->DataDirectory[idx][0]);
742         a->DataDirectory[idx].Size =
743           bfd_h_get_32 (abfd, src->DataDirectory[idx][1]);
744       }
745   }
746
747   if (aouthdr_int->entry)
748     aouthdr_int->entry += a->ImageBase;
749   if (aouthdr_int->tsize) 
750     aouthdr_int->text_start += a->ImageBase;
751   if (aouthdr_int->dsize) 
752     aouthdr_int->data_start += a->ImageBase;
753 }
754
755
756 static void add_data_entry (abfd, aout, idx, name, base)
757      bfd *abfd;
758      struct internal_extra_pe_aouthdr *aout;
759      int idx;
760      char *name;
761      bfd_vma base;
762 {
763   asection *sec = bfd_get_section_by_name (abfd, name);
764
765   /* add import directory information if it exists */
766   if (sec != NULL)
767     {
768       aout->DataDirectory[idx].VirtualAddress = sec->lma - base;
769       aout->DataDirectory[idx].Size = sec->_cooked_size;
770       sec->flags |= SEC_DATA;
771     }
772 }
773
774
775 static unsigned int
776 coff_swap_aouthdr_out (abfd, in, out)
777      bfd       *abfd;
778      PTR        in;
779      PTR        out;
780 {
781   struct internal_aouthdr *aouthdr_in = (struct internal_aouthdr *)in;
782   struct internal_extra_pe_aouthdr *extra = &pe_data (abfd)->pe_opthdr;
783   PEAOUTHDR *aouthdr_out = (PEAOUTHDR *)out;
784
785   bfd_vma sa = extra->SectionAlignment;
786   bfd_vma fa = extra->FileAlignment;
787   bfd_vma ib = extra->ImageBase ;
788
789   if (aouthdr_in->tsize) 
790     aouthdr_in->text_start -= ib;
791   if (aouthdr_in->dsize) 
792     aouthdr_in->data_start -= ib;
793   if (aouthdr_in->entry) 
794     aouthdr_in->entry -= ib;
795
796 #define FA(x)  (((x) + fa -1 ) & (- fa))
797 #define SA(x)  (((x) + sa -1 ) & (- sa))
798
799   /* We like to have the sizes aligned */
800
801   aouthdr_in->bsize = FA (aouthdr_in->bsize);
802
803
804   extra->NumberOfRvaAndSizes = IMAGE_NUMBEROF_DIRECTORY_ENTRIES;
805
806   /* first null out all data directory entries .. */
807   memset (extra->DataDirectory, sizeof (extra->DataDirectory), 0);
808
809   add_data_entry (abfd, extra, 0, ".edata", ib);
810   add_data_entry (abfd, extra, 1, ".idata", ib);
811   add_data_entry (abfd, extra, 2, ".rsrc" ,ib);
812   add_data_entry (abfd, extra, 5, ".reloc", ib);
813   {
814     asection *sec;
815     bfd_vma dsize= 0;
816     bfd_vma isize = SA(abfd->sections->filepos);
817     bfd_vma tsize= 0;
818     for (sec = abfd->sections; sec; sec = sec->next)
819       {
820         int rounded = FA(sec->_raw_size);
821         if (sec->flags & SEC_DATA) 
822           dsize += rounded;
823         if (sec->flags & SEC_CODE)
824           tsize += rounded;
825         isize += SA(rounded);
826       }
827
828     aouthdr_in->dsize = dsize;
829     aouthdr_in->tsize = tsize;
830     extra->SizeOfImage = isize;
831   }
832
833   extra->SizeOfHeaders = abfd->sections->filepos;
834   bfd_h_put_16(abfd, aouthdr_in->magic, (bfd_byte *) aouthdr_out->standard.magic);
835   bfd_h_put_16(abfd, 2  + 55 * 256, (bfd_byte *) aouthdr_out->standard.vstamp);
836   PUT_AOUTHDR_TSIZE (abfd, aouthdr_in->tsize, (bfd_byte *) aouthdr_out->standard.tsize);
837   PUT_AOUTHDR_DSIZE (abfd, aouthdr_in->dsize, (bfd_byte *) aouthdr_out->standard.dsize);
838   PUT_AOUTHDR_BSIZE (abfd, aouthdr_in->bsize, (bfd_byte *) aouthdr_out->standard.bsize);
839   PUT_AOUTHDR_ENTRY (abfd, aouthdr_in->entry, (bfd_byte *) aouthdr_out->standard.entry);
840   PUT_AOUTHDR_TEXT_START (abfd, aouthdr_in->text_start,
841                           (bfd_byte *) aouthdr_out->standard.text_start);
842
843   PUT_AOUTHDR_DATA_START (abfd, aouthdr_in->data_start,
844                           (bfd_byte *) aouthdr_out->standard.data_start);
845
846
847   bfd_h_put_32 (abfd, extra->ImageBase, 
848                 (bfd_byte *) aouthdr_out->ImageBase);
849   bfd_h_put_32 (abfd, extra->SectionAlignment,
850                 (bfd_byte *) aouthdr_out->SectionAlignment);
851   bfd_h_put_32 (abfd, extra->FileAlignment,
852                 (bfd_byte *) aouthdr_out->FileAlignment);
853   bfd_h_put_16 (abfd, extra->MajorOperatingSystemVersion,
854                 (bfd_byte *) aouthdr_out->MajorOperatingSystemVersion);
855   bfd_h_put_16 (abfd, extra->MinorOperatingSystemVersion,
856                 (bfd_byte *) aouthdr_out->MinorOperatingSystemVersion);
857   bfd_h_put_16 (abfd, extra->MajorImageVersion,
858                 (bfd_byte *) aouthdr_out->MajorImageVersion);
859   bfd_h_put_16 (abfd, extra->MinorImageVersion,
860                 (bfd_byte *) aouthdr_out->MinorImageVersion);
861   bfd_h_put_16 (abfd, extra->MajorSubsystemVersion,
862                 (bfd_byte *) aouthdr_out->MajorSubsystemVersion);
863   bfd_h_put_16 (abfd, extra->MinorSubsystemVersion,
864                 (bfd_byte *) aouthdr_out->MinorSubsystemVersion);
865   bfd_h_put_32 (abfd, extra->Reserved1,
866                 (bfd_byte *) aouthdr_out->Reserved1);
867   bfd_h_put_32 (abfd, extra->SizeOfImage,
868                 (bfd_byte *) aouthdr_out->SizeOfImage);
869   bfd_h_put_32 (abfd, extra->SizeOfHeaders,
870                 (bfd_byte *) aouthdr_out->SizeOfHeaders);
871   bfd_h_put_32 (abfd, extra->CheckSum,
872                 (bfd_byte *) aouthdr_out->CheckSum);
873   bfd_h_put_16 (abfd, extra->Subsystem,
874                 (bfd_byte *) aouthdr_out->Subsystem);
875   bfd_h_put_16 (abfd, extra->DllCharacteristics,
876                 (bfd_byte *) aouthdr_out->DllCharacteristics);
877   bfd_h_put_32 (abfd, extra->SizeOfStackReserve,
878                 (bfd_byte *) aouthdr_out->SizeOfStackReserve);
879   bfd_h_put_32 (abfd, extra->SizeOfStackCommit,
880                 (bfd_byte *) aouthdr_out->SizeOfStackCommit);
881   bfd_h_put_32 (abfd, extra->SizeOfHeapReserve,
882                 (bfd_byte *) aouthdr_out->SizeOfHeapReserve);
883   bfd_h_put_32 (abfd, extra->SizeOfHeapCommit,
884                 (bfd_byte *) aouthdr_out->SizeOfHeapCommit);
885   bfd_h_put_32 (abfd, extra->LoaderFlags,
886                 (bfd_byte *) aouthdr_out->LoaderFlags);
887   bfd_h_put_32 (abfd, extra->NumberOfRvaAndSizes,
888                 (bfd_byte *) aouthdr_out->NumberOfRvaAndSizes);
889   {
890     int idx;
891     for (idx=0; idx < 16; idx++)
892       {
893         bfd_h_put_32 (abfd, extra->DataDirectory[idx].VirtualAddress,
894                       (bfd_byte *) aouthdr_out->DataDirectory[idx][0]);
895         bfd_h_put_32 (abfd, extra->DataDirectory[idx].Size,
896                       (bfd_byte *) aouthdr_out->DataDirectory[idx][1]);
897       }
898   }
899
900
901   return sizeof(AOUTHDR);
902 }
903
904 static void
905     coff_swap_scnhdr_in (abfd, ext, in)
906       bfd            *abfd;
907   PTR        ext;
908   PTR        in;
909 {
910   SCNHDR *scnhdr_ext = (SCNHDR *) ext;
911   struct internal_scnhdr *scnhdr_int = (struct internal_scnhdr *) in;
912
913   memcpy(scnhdr_int->s_name, scnhdr_ext->s_name, sizeof(scnhdr_int->s_name));
914   scnhdr_int->s_vaddr =
915     GET_SCNHDR_VADDR (abfd, (bfd_byte *) scnhdr_ext->s_vaddr);
916   scnhdr_int->s_paddr =
917     GET_SCNHDR_PADDR (abfd, (bfd_byte *) scnhdr_ext->s_paddr);
918   scnhdr_int->s_size =
919     GET_SCNHDR_SIZE (abfd, (bfd_byte *) scnhdr_ext->s_size);
920   scnhdr_int->s_scnptr =
921     GET_SCNHDR_SCNPTR (abfd, (bfd_byte *) scnhdr_ext->s_scnptr);
922   scnhdr_int->s_relptr =
923     GET_SCNHDR_RELPTR (abfd, (bfd_byte *) scnhdr_ext->s_relptr);
924   scnhdr_int->s_lnnoptr =
925     GET_SCNHDR_LNNOPTR (abfd, (bfd_byte *) scnhdr_ext->s_lnnoptr);
926   scnhdr_int->s_flags = bfd_h_get_32(abfd, (bfd_byte *) scnhdr_ext->s_flags);
927
928   scnhdr_int->s_nreloc = bfd_h_get_16(abfd, (bfd_byte *) scnhdr_ext->s_nreloc);
929   scnhdr_int->s_nlnno = bfd_h_get_16(abfd, (bfd_byte *) scnhdr_ext->s_nlnno);
930
931   if (scnhdr_int->s_vaddr != 0) 
932     {
933       scnhdr_int->s_vaddr += pe_data (abfd)->pe_opthdr.ImageBase;
934     }
935   if (strcmp (scnhdr_int->s_name, _BSS) == 0) 
936     {
937       scnhdr_int->s_size = scnhdr_int->s_paddr;
938       scnhdr_int->s_paddr = 0;
939     }
940 }
941
942 static unsigned int
943 coff_swap_scnhdr_out (abfd, in, out)
944      bfd       *abfd;
945      PTR        in;
946      PTR        out;
947 {
948   struct internal_scnhdr *scnhdr_int = (struct internal_scnhdr *)in;
949   SCNHDR *scnhdr_ext = (SCNHDR *)out;
950   unsigned int ret = sizeof (SCNHDR);
951   bfd_vma ps;
952   bfd_vma ss;
953
954   memcpy(scnhdr_ext->s_name, scnhdr_int->s_name, sizeof(scnhdr_int->s_name));
955
956
957   PUT_SCNHDR_VADDR (abfd, 
958                     (scnhdr_int->s_vaddr 
959                      - pe_data(abfd)->pe_opthdr.ImageBase),
960                     (bfd_byte *) scnhdr_ext->s_vaddr);
961
962   /* NT wants the size data to be rounded up to the next NT_FILE_ALIGNMENT
963      value except for the BSS section, its s_size should be 0 */
964
965
966   if (strcmp (scnhdr_int->s_name, _BSS) == 0) 
967     {
968       ps = scnhdr_int->s_size;
969       ss = 0;
970     }
971   else
972     {
973       ps = scnhdr_int->s_paddr;
974       ss = scnhdr_int->s_size;
975     }
976
977   PUT_SCNHDR_SIZE (abfd, ss,
978                    (bfd_byte *) scnhdr_ext->s_size);
979
980
981   PUT_SCNHDR_PADDR (abfd, ps, (bfd_byte *) scnhdr_ext->s_paddr);
982
983   PUT_SCNHDR_SCNPTR (abfd, scnhdr_int->s_scnptr,
984                      (bfd_byte *) scnhdr_ext->s_scnptr);
985   PUT_SCNHDR_RELPTR (abfd, scnhdr_int->s_relptr,
986                      (bfd_byte *) scnhdr_ext->s_relptr);
987   PUT_SCNHDR_LNNOPTR (abfd, scnhdr_int->s_lnnoptr,
988                       (bfd_byte *) scnhdr_ext->s_lnnoptr);
989
990   /* Extra flags must be set when dealing with NT.  All sections should also
991      have the IMAGE_SCN_MEM_READ (0x40000000) flag set.  In addition, the
992      .text section must have IMAGE_SCN_MEM_EXECUTE (0x20000000) and the data
993      sections (.idata, .data, .bss, .CRT) must have IMAGE_SCN_MEM_WRITE set
994      (this is especially important when dealing with the .idata section since
995      the addresses for routines from .dlls must be overwritten).  If .reloc
996      section data is ever generated, we must add IMAGE_SCN_MEM_DISCARDABLE
997      (0x02000000).  Also, the resource data should also be read and
998      writable.  */
999
1000   /* FIXME: alignment is also encoded in this field, at least on ppc (krk) */
1001   /* FIXME: even worse, I don't see how to get the original alignment field*/
1002   /*        back...                                                        */
1003
1004   {
1005     int flags = scnhdr_int->s_flags;
1006     if (strcmp (scnhdr_int->s_name, ".data")  == 0 ||
1007         strcmp (scnhdr_int->s_name, ".CRT")   == 0 ||
1008         strcmp (scnhdr_int->s_name, ".rsrc")  == 0 ||
1009         strcmp (scnhdr_int->s_name, ".bss")   == 0)
1010       flags |= IMAGE_SCN_MEM_READ | IMAGE_SCN_MEM_WRITE;
1011     else if (strcmp (scnhdr_int->s_name, ".text") == 0)
1012       flags |= IMAGE_SCN_MEM_READ | IMAGE_SCN_MEM_EXECUTE;
1013     else if (strcmp (scnhdr_int->s_name, ".reloc") == 0)
1014       flags = SEC_DATA| IMAGE_SCN_MEM_READ | IMAGE_SCN_MEM_DISCARDABLE;
1015     else if (strcmp (scnhdr_int->s_name, ".idata") == 0)
1016       flags = IMAGE_SCN_MEM_READ | IMAGE_SCN_MEM_WRITE | SEC_DATA;     
1017     else if (strcmp (scnhdr_int->s_name, ".rdata") == 0
1018              || strcmp (scnhdr_int->s_name, ".edata") == 0)
1019       flags =  IMAGE_SCN_MEM_READ | SEC_DATA;     
1020     /* ppc-nt additions */
1021     else if (strcmp (scnhdr_int->s_name, ".pdata") == 0)
1022       flags = IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_ALIGN_4BYTES |
1023                           IMAGE_SCN_MEM_READ ;
1024     else if (strcmp (scnhdr_int->s_name, ".reldata") == 0)
1025       flags =  IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_ALIGN_8BYTES |
1026                IMAGE_SCN_MEM_READ | IMAGE_SCN_MEM_WRITE ;
1027     else if (strcmp (scnhdr_int->s_name, ".ydata") == 0)
1028       flags =  IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_ALIGN_8BYTES |
1029                IMAGE_SCN_MEM_READ | IMAGE_SCN_MEM_WRITE ;
1030     else if (strcmp (scnhdr_int->s_name, ".drectve") == 0)
1031       flags =  IMAGE_SCN_LNK_INFO | IMAGE_SCN_LNK_REMOVE ;
1032     /* end of ppc-nt additions */
1033
1034     bfd_h_put_32(abfd, flags, (bfd_byte *) scnhdr_ext->s_flags);
1035   }
1036
1037   if (scnhdr_int->s_nlnno <= 0xffff)
1038     bfd_h_put_16(abfd, scnhdr_int->s_nlnno, (bfd_byte *) scnhdr_ext->s_nlnno);
1039   else
1040     {
1041       (*_bfd_error_handler) ("%s: line number overflow: 0x%lx > 0xffff",
1042                              bfd_get_filename (abfd),
1043                              scnhdr_int->s_nlnno);
1044       bfd_set_error (bfd_error_file_truncated);
1045       bfd_h_put_16 (abfd, 0xffff, (bfd_byte *) scnhdr_ext->s_nlnno);
1046       ret = 0;
1047     }
1048   if (scnhdr_int->s_nreloc <= 0xffff)
1049     bfd_h_put_16(abfd, scnhdr_int->s_nreloc, (bfd_byte *) scnhdr_ext->s_nreloc);
1050   else
1051     {
1052       (*_bfd_error_handler) ("%s: reloc overflow: 0x%lx > 0xffff",
1053                              bfd_get_filename (abfd),
1054                              scnhdr_int->s_nreloc);
1055       bfd_set_error (bfd_error_file_truncated);
1056       bfd_h_put_16 (abfd, 0xffff, (bfd_byte *) scnhdr_ext->s_nreloc);
1057       ret = 0;
1058     }
1059   return ret;
1060 }
1061 /**********************************************************************/
1062 static boolean
1063 pe_print_private_bfd_data (abfd, vfile)
1064      bfd*abfd;
1065      void *vfile;
1066 {
1067   FILE *file = vfile;
1068   int j;
1069   pe_data_type *pe = pe_data (abfd);
1070   struct internal_extra_pe_aouthdr *i = &pe->pe_opthdr;
1071   fprintf (file,"\nImageBase\t\t");
1072   fprintf_vma (file, i->ImageBase);
1073   fprintf (file,"\nSectionAlignment\t");
1074   fprintf_vma (file, i->SectionAlignment);
1075   fprintf (file,"\nFileAlignment\t\t");
1076   fprintf_vma (file, i->FileAlignment);
1077   fprintf (file,"\nMajorOSystemVersion\t%d\n", i->MajorOperatingSystemVersion);
1078   fprintf (file,"MinorOSystemVersion\t%d\n", i->MinorOperatingSystemVersion);
1079   fprintf (file,"MajorImageVersion\t%d\n", i->MajorImageVersion);
1080   fprintf (file,"MinorImageVersion\t%d\n", i->MinorImageVersion);
1081   fprintf (file,"MajorSubsystemVersion\t%d\n", i->MajorSubsystemVersion);
1082   fprintf (file,"MinorSubsystemVersion\t%d\n", i->MinorSubsystemVersion);
1083   fprintf (file,"Reserved1\t\t%08lx\n", i->Reserved1);
1084   fprintf (file,"SizeOfImage\t\t%08lx\n", i->SizeOfImage);
1085   fprintf (file,"SizeOfHeaders\t\t%08lx\n", i->SizeOfHeaders);
1086   fprintf (file,"CheckSum\t\t%08lx\n", i->CheckSum);
1087   fprintf (file,"Subsystem\t\t%08x\n", i->Subsystem);
1088   fprintf (file,"DllCharacteristics\t%08x\n", i->DllCharacteristics);
1089   fprintf (file,"SizeOfStackReserve\t");
1090   fprintf_vma (file, i->SizeOfStackReserve);
1091   fprintf (file,"\nSizeOfStackCommit\t");
1092   fprintf_vma (file, i->SizeOfStackCommit);
1093   fprintf (file,"\nSizeOfHeapReserve\t");
1094   fprintf_vma (file, i->SizeOfHeapReserve);
1095   fprintf (file,"\nSizeOfHeapCommit\t");
1096   fprintf_vma (file, i->SizeOfHeapCommit);
1097   fprintf (file,"\nLoaderFlags\t\t%08lx\n", i->LoaderFlags);
1098   fprintf (file,"NumberOfRvaAndSizes\t%08lx\n", i->NumberOfRvaAndSizes);
1099
1100   for (j = 0; j < IMAGE_NUMBEROF_DIRECTORY_ENTRIES; j++) 
1101     {
1102       fprintf (file, "Entry %2d ", j);
1103       fprintf_vma (file, i->DataDirectory[j].VirtualAddress);
1104       fprintf (file, " %08lx\n", i->DataDirectory[j].Size);
1105     }
1106
1107   return true;
1108 }
1109
1110 static boolean
1111 pe_mkobject (abfd)
1112      bfd * abfd;
1113 {
1114   pe_data_type *pe;
1115   abfd->tdata.pe_obj_data = 
1116     (struct pe_tdata *) bfd_zalloc (abfd, sizeof (pe_data_type));
1117
1118   if (abfd->tdata.pe_obj_data == 0)
1119     {
1120       bfd_set_error (bfd_error_no_memory);
1121       return false;
1122     }
1123
1124   pe = pe_data (abfd);
1125
1126   pe->coff.pe = 1;
1127   pe->in_reloc_p = in_reloc_p;
1128   return true;
1129 }
1130
1131 /* Create the COFF backend specific information.  */
1132 static PTR
1133 pe_mkobject_hook (abfd, filehdr, aouthdr)
1134      bfd * abfd;
1135      PTR filehdr;
1136      PTR aouthdr;
1137 {
1138   struct internal_filehdr *internal_f = (struct internal_filehdr *) filehdr;
1139   pe_data_type *pe;
1140
1141   if (pe_mkobject (abfd) == false)
1142     return NULL;
1143
1144   pe = pe_data (abfd);
1145   pe->coff.sym_filepos = internal_f->f_symptr;
1146   /* These members communicate important constants about the symbol
1147      table to GDB's symbol-reading code.  These `constants'
1148      unfortunately vary among coff implementations...  */
1149   pe->coff.local_n_btmask = N_BTMASK;
1150   pe->coff.local_n_btshft = N_BTSHFT;
1151   pe->coff.local_n_tmask = N_TMASK;
1152   pe->coff.local_n_tshift = N_TSHIFT;
1153   pe->coff.local_symesz = SYMESZ;
1154   pe->coff.local_auxesz = AUXESZ;
1155   pe->coff.local_linesz = LINESZ;
1156
1157   obj_raw_syment_count (abfd) =
1158     obj_conv_table_size (abfd) =
1159       internal_f->f_nsyms;
1160
1161
1162 #ifdef COFF_IMAGE_WITH_PE
1163   if (aouthdr) 
1164     {
1165       pe->pe_opthdr = ((struct internal_aouthdr *)aouthdr)->pe;
1166     }
1167 #endif
1168
1169   return (PTR) pe;
1170 }
1171
1172
1173
1174 /* Copy any private info we understand from the input bfd
1175    to the output bfd.  */
1176
1177 #define coff_bfd_copy_private_bfd_data pe_bfd_copy_private_bfd_data
1178
1179 static boolean
1180 pe_bfd_copy_private_bfd_data (ibfd, obfd)
1181      bfd *ibfd, *obfd;
1182 {
1183   /* One day we may try to grok other private data.  */
1184   if (ibfd->xvec->flavour != bfd_target_coff_flavour
1185       || obfd->xvec->flavour != bfd_target_coff_flavour)
1186     return true;
1187
1188   pe_data(obfd)->pe_opthdr = pe_data (ibfd)->pe_opthdr;
1189
1190   return true;
1191 }
This page took 0.08819 seconds and 4 git commands to generate.