Change PAGE_SIZE to TARGET_PAGE_SIZE
[platform/upstream/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                         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
32
33 #ifndef GET_FCN_LNNOPTR
34 #define GET_FCN_LNNOPTR(abfd, ext)  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)  bfd_h_get_32(abfd, (bfd_byte *) ext->x_sym.x_fcnary.x_fcn.x_endndx)
39 #endif
40
41 #ifndef PUT_FCN_LNNOPTR
42 #define PUT_FCN_LNNOPTR(abfd, in, ext)  bfd_h_put_32(abfd,  in, (bfd_byte *) ext->x_sym.x_fcnary.x_fcn.x_lnnoptr)
43 #endif
44 #ifndef PUT_FCN_ENDNDX
45 #define PUT_FCN_ENDNDX(abfd, in, ext) bfd_h_put_32(abfd, in, (bfd_byte *) ext->x_sym.x_fcnary.x_fcn.x_endndx)
46 #endif
47 #ifndef GET_LNSZ_LNNO
48 #define GET_LNSZ_LNNO(abfd, ext) bfd_h_get_16(abfd, (bfd_byte *) ext->x_sym.x_misc.x_lnsz.x_lnno)
49 #endif
50 #ifndef GET_LNSZ_SIZE
51 #define GET_LNSZ_SIZE(abfd, ext) bfd_h_get_16(abfd, (bfd_byte *) ext->x_sym.x_misc.x_lnsz.x_size)
52 #endif
53 #ifndef PUT_LNSZ_LNNO
54 #define PUT_LNSZ_LNNO(abfd, in, ext) bfd_h_put_16(abfd, in, (bfd_byte *)ext->x_sym.x_misc.x_lnsz.x_lnno)
55 #endif
56 #ifndef PUT_LNSZ_SIZE
57 #define PUT_LNSZ_SIZE(abfd, in, ext) bfd_h_put_16(abfd, in, (bfd_byte*) ext->x_sym.x_misc.x_lnsz.x_size)
58 #endif
59 #ifndef GET_SCN_SCNLEN
60 #define GET_SCN_SCNLEN(abfd,  ext) bfd_h_get_32(abfd, (bfd_byte *) ext->x_scn.x_scnlen)
61 #endif
62 #ifndef GET_SCN_NRELOC
63 #define GET_SCN_NRELOC(abfd,  ext) bfd_h_get_16(abfd, (bfd_byte *)ext->x_scn.x_nreloc)
64 #endif
65 #ifndef GET_SCN_NLINNO
66 #define GET_SCN_NLINNO(abfd, ext)  bfd_h_get_16(abfd, (bfd_byte *)ext->x_scn.x_nlinno)
67 #endif
68 #ifndef PUT_SCN_SCNLEN
69 #define PUT_SCN_SCNLEN(abfd,in, ext) bfd_h_put_32(abfd, in, (bfd_byte *) ext->x_scn.x_scnlen)
70 #endif
71 #ifndef PUT_SCN_NRELOC
72 #define PUT_SCN_NRELOC(abfd,in, ext) bfd_h_put_16(abfd, in, (bfd_byte *)ext->x_scn.x_nreloc)
73 #endif
74 #ifndef PUT_SCN_NLINNO
75 #define PUT_SCN_NLINNO(abfd,in, ext)  bfd_h_put_16(abfd,in, (bfd_byte  *) ext->x_scn.x_nlinno)
76 #endif
77 #ifndef GET_LINENO_LNNO
78 #define GET_LINENO_LNNO(abfd, ext) bfd_h_get_16(abfd, (bfd_byte *) (ext->l_lnno));
79 #endif
80 #ifndef PUT_LINENO_LNNO
81 #define PUT_LINENO_LNNO(abfd,val, ext) bfd_h_put_16(abfd,val,  (bfd_byte *) (ext->l_lnno));
82 #endif
83
84 /* The f_symptr field in the filehdr is sometimes 64 bits.  */
85 #ifndef GET_FILEHDR_SYMPTR
86 #define GET_FILEHDR_SYMPTR bfd_h_get_32
87 #endif
88 #ifndef PUT_FILEHDR_SYMPTR
89 #define PUT_FILEHDR_SYMPTR bfd_h_put_32
90 #endif
91
92 /* Some fields in the aouthdr are sometimes 64 bits.  */
93 #ifndef GET_AOUTHDR_TSIZE
94 #define GET_AOUTHDR_TSIZE bfd_h_get_32
95 #endif
96 #ifndef PUT_AOUTHDR_TSIZE
97 #define PUT_AOUTHDR_TSIZE bfd_h_put_32
98 #endif
99 #ifndef GET_AOUTHDR_DSIZE
100 #define GET_AOUTHDR_DSIZE bfd_h_get_32
101 #endif
102 #ifndef PUT_AOUTHDR_DSIZE
103 #define PUT_AOUTHDR_DSIZE bfd_h_put_32
104 #endif
105 #ifndef GET_AOUTHDR_BSIZE
106 #define GET_AOUTHDR_BSIZE bfd_h_get_32
107 #endif
108 #ifndef PUT_AOUTHDR_BSIZE
109 #define PUT_AOUTHDR_BSIZE bfd_h_put_32
110 #endif
111 #ifndef GET_AOUTHDR_ENTRY
112 #define GET_AOUTHDR_ENTRY bfd_h_get_32
113 #endif
114 #ifndef PUT_AOUTHDR_ENTRY
115 #define PUT_AOUTHDR_ENTRY bfd_h_put_32
116 #endif
117 #ifndef GET_AOUTHDR_TEXT_START
118 #define GET_AOUTHDR_TEXT_START bfd_h_get_32
119 #endif
120 #ifndef PUT_AOUTHDR_TEXT_START
121 #define PUT_AOUTHDR_TEXT_START bfd_h_put_32
122 #endif
123 #ifndef GET_AOUTHDR_DATA_START
124 #define GET_AOUTHDR_DATA_START bfd_h_get_32
125 #endif
126 #ifndef PUT_AOUTHDR_DATA_START
127 #define PUT_AOUTHDR_DATA_START bfd_h_put_32
128 #endif
129
130 /* Some fields in the scnhdr are sometimes 64 bits.  */
131 #ifndef GET_SCNHDR_PADDR
132 #define GET_SCNHDR_PADDR bfd_h_get_32
133 #endif
134 #ifndef PUT_SCNHDR_PADDR
135 #define PUT_SCNHDR_PADDR bfd_h_put_32
136 #endif
137 #ifndef GET_SCNHDR_VADDR
138 #define GET_SCNHDR_VADDR bfd_h_get_32
139 #endif
140 #ifndef PUT_SCNHDR_VADDR
141 #define PUT_SCNHDR_VADDR bfd_h_put_32
142 #endif
143 #ifndef GET_SCNHDR_SIZE
144 #define GET_SCNHDR_SIZE bfd_h_get_32
145 #endif
146 #ifndef PUT_SCNHDR_SIZE
147 #define PUT_SCNHDR_SIZE bfd_h_put_32
148 #endif
149 #ifndef GET_SCNHDR_SCNPTR
150 #define GET_SCNHDR_SCNPTR bfd_h_get_32
151 #endif
152 #ifndef PUT_SCNHDR_SCNPTR
153 #define PUT_SCNHDR_SCNPTR bfd_h_put_32
154 #endif
155 #ifndef GET_SCNHDR_RELPTR
156 #define GET_SCNHDR_RELPTR bfd_h_get_32
157 #endif
158 #ifndef PUT_SCNHDR_RELPTR
159 #define PUT_SCNHDR_RELPTR bfd_h_put_32
160 #endif
161 #ifndef GET_SCNHDR_LNNOPTR
162 #define GET_SCNHDR_LNNOPTR bfd_h_get_32
163 #endif
164 #ifndef PUT_SCNHDR_LNNOPTR
165 #define PUT_SCNHDR_LNNOPTR bfd_h_put_32
166 #endif
167
168
169
170 /**********************************************************************/
171
172 static void
173 coff_swap_reloc_in (abfd, src, dst)
174      bfd *abfd;
175      PTR src;
176      PTR dst;
177 {
178   RELOC *reloc_src = (RELOC *) src;
179   struct internal_reloc *reloc_dst = (struct internal_reloc *) dst;
180
181   reloc_dst->r_vaddr = bfd_h_get_32(abfd, (bfd_byte *)reloc_src->r_vaddr);
182   reloc_dst->r_symndx = bfd_h_get_signed_32(abfd, (bfd_byte *) reloc_src->r_symndx);
183
184   reloc_dst->r_type = bfd_h_get_16(abfd, (bfd_byte *) reloc_src->r_type);
185
186 #ifdef SWAP_IN_RELOC_OFFSET
187   reloc_dst->r_offset = SWAP_IN_RELOC_OFFSET(abfd,
188                                              (bfd_byte *) reloc_src->r_offset);
189 #endif
190
191 }
192
193
194 static unsigned int
195 coff_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
220 static void
221 coff_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);
231   filehdr_dst->f_symptr =
232     bfd_h_get_32 (abfd, (bfd_byte *) filehdr_src->f_symptr);
233   filehdr_dst->f_nsyms = bfd_h_get_32(abfd, (bfd_byte *)filehdr_src-> f_nsyms);
234   filehdr_dst->f_opthdr = bfd_h_get_16(abfd, (bfd_byte *)filehdr_src-> f_opthdr);
235   filehdr_dst->f_flags = bfd_h_get_16(abfd, (bfd_byte *)filehdr_src-> f_flags);
236 }
237
238 #ifdef COFF_IMAGE_WITH_PE
239
240 static  unsigned int
241 coff_swap_filehdr_out (abfd, in, out)
242      bfd       *abfd;
243      PTR        in;
244      PTR        out;
245 {
246   int idx;
247   struct internal_filehdr *filehdr_in = (struct internal_filehdr *)in;
248   FILHDR *filehdr_out = (FILHDR *)out;
249
250   if (pe_data (abfd)->has_reloc_section)
251     filehdr_in->f_flags &= ~F_RELFLG;
252
253   if (pe_data (abfd)->dll)
254     filehdr_in->f_flags |= F_DLL;
255
256   filehdr_in->pe.e_magic    = DOSMAGIC;
257   filehdr_in->pe.e_cblp     = 0x90;
258   filehdr_in->pe.e_cp       = 0x3;
259   filehdr_in->pe.e_crlc     = 0x0;
260   filehdr_in->pe.e_cparhdr  = 0x4;
261   filehdr_in->pe.e_minalloc = 0x0;
262   filehdr_in->pe.e_maxalloc = 0xffff;
263   filehdr_in->pe.e_ss       = 0x0;
264   filehdr_in->pe.e_sp       = 0xb8;
265   filehdr_in->pe.e_csum     = 0x0;
266   filehdr_in->pe.e_ip       = 0x0;
267   filehdr_in->pe.e_cs       = 0x0;
268   filehdr_in->pe.e_lfarlc   = 0x40;
269   filehdr_in->pe.e_ovno     = 0x0;
270
271   for (idx=0; idx < 4; idx++)
272     filehdr_in->pe.e_res[idx] = 0x0;
273
274   filehdr_in->pe.e_oemid   = 0x0;
275   filehdr_in->pe.e_oeminfo = 0x0;
276
277   for (idx=0; idx < 10; idx++)
278     filehdr_in->pe.e_res2[idx] = 0x0;
279
280   filehdr_in->pe.e_lfanew = 0x80;
281
282   /* this next collection of data are mostly just characters.  It appears
283      to be constant within the headers put on NT exes */
284   filehdr_in->pe.dos_message[0]  = 0x0eba1f0e;
285   filehdr_in->pe.dos_message[1]  = 0xcd09b400;
286   filehdr_in->pe.dos_message[2]  = 0x4c01b821;
287   filehdr_in->pe.dos_message[3]  = 0x685421cd;
288   filehdr_in->pe.dos_message[4]  = 0x70207369;
289   filehdr_in->pe.dos_message[5]  = 0x72676f72;
290   filehdr_in->pe.dos_message[6]  = 0x63206d61;
291   filehdr_in->pe.dos_message[7]  = 0x6f6e6e61;
292   filehdr_in->pe.dos_message[8]  = 0x65622074;
293   filehdr_in->pe.dos_message[9]  = 0x6e757220;
294   filehdr_in->pe.dos_message[10] = 0x206e6920;
295   filehdr_in->pe.dos_message[11] = 0x20534f44;
296   filehdr_in->pe.dos_message[12] = 0x65646f6d;
297   filehdr_in->pe.dos_message[13] = 0x0a0d0d2e;
298   filehdr_in->pe.dos_message[14] = 0x24;
299   filehdr_in->pe.dos_message[15] = 0x0;
300   filehdr_in->pe.nt_signature = NT_SIGNATURE;
301
302
303
304   bfd_h_put_16(abfd, filehdr_in->f_magic, (bfd_byte *) filehdr_out->f_magic);
305   bfd_h_put_16(abfd, filehdr_in->f_nscns, (bfd_byte *) filehdr_out->f_nscns);
306
307   bfd_h_put_32(abfd, time (0), (bfd_byte *) filehdr_out->f_timdat);
308   PUT_FILEHDR_SYMPTR (abfd, (bfd_vma) filehdr_in->f_symptr,
309                       (bfd_byte *) filehdr_out->f_symptr);
310   bfd_h_put_32(abfd, filehdr_in->f_nsyms, (bfd_byte *) filehdr_out->f_nsyms);
311   bfd_h_put_16(abfd, filehdr_in->f_opthdr, (bfd_byte *) filehdr_out->f_opthdr);
312   bfd_h_put_16(abfd, filehdr_in->f_flags, (bfd_byte *) filehdr_out->f_flags);
313
314
315   /* put in extra dos header stuff.  This data remains essentially
316      constant, it just has to be tacked on to the beginning of all exes 
317      for NT */
318   bfd_h_put_16(abfd, filehdr_in->pe.e_magic, (bfd_byte *) filehdr_out->e_magic);
319   bfd_h_put_16(abfd, filehdr_in->pe.e_cblp, (bfd_byte *) filehdr_out->e_cblp);
320   bfd_h_put_16(abfd, filehdr_in->pe.e_cp, (bfd_byte *) filehdr_out->e_cp);
321   bfd_h_put_16(abfd, filehdr_in->pe.e_crlc, (bfd_byte *) filehdr_out->e_crlc);
322   bfd_h_put_16(abfd, filehdr_in->pe.e_cparhdr, 
323                (bfd_byte *) filehdr_out->e_cparhdr);
324   bfd_h_put_16(abfd, filehdr_in->pe.e_minalloc, 
325                (bfd_byte *) filehdr_out->e_minalloc);
326   bfd_h_put_16(abfd, filehdr_in->pe.e_maxalloc, 
327                (bfd_byte *) filehdr_out->e_maxalloc);
328   bfd_h_put_16(abfd, filehdr_in->pe.e_ss, (bfd_byte *) filehdr_out->e_ss);
329   bfd_h_put_16(abfd, filehdr_in->pe.e_sp, (bfd_byte *) filehdr_out->e_sp);
330   bfd_h_put_16(abfd, filehdr_in->pe.e_csum, (bfd_byte *) filehdr_out->e_csum);
331   bfd_h_put_16(abfd, filehdr_in->pe.e_ip, (bfd_byte *) filehdr_out->e_ip);
332   bfd_h_put_16(abfd, filehdr_in->pe.e_cs, (bfd_byte *) filehdr_out->e_cs);
333   bfd_h_put_16(abfd, filehdr_in->pe.e_lfarlc, (bfd_byte *) filehdr_out->e_lfarlc);
334   bfd_h_put_16(abfd, filehdr_in->pe.e_ovno, (bfd_byte *) filehdr_out->e_ovno);
335   {
336     int idx;
337     for (idx=0; idx < 4; idx++)
338       bfd_h_put_16(abfd, filehdr_in->pe.e_res[idx], 
339                    (bfd_byte *) filehdr_out->e_res[idx]);
340   }
341   bfd_h_put_16(abfd, filehdr_in->pe.e_oemid, (bfd_byte *) filehdr_out->e_oemid);
342   bfd_h_put_16(abfd, filehdr_in->pe.e_oeminfo,
343                (bfd_byte *) filehdr_out->e_oeminfo);
344   {
345     int idx;
346     for (idx=0; idx < 10; idx++)
347       bfd_h_put_16(abfd, filehdr_in->pe.e_res2[idx],
348                    (bfd_byte *) filehdr_out->e_res2[idx]);
349   }
350   bfd_h_put_32(abfd, filehdr_in->pe.e_lfanew, (bfd_byte *) filehdr_out->e_lfanew);
351
352   {
353     int idx;
354     for (idx=0; idx < 16; idx++)
355       bfd_h_put_32(abfd, filehdr_in->pe.dos_message[idx],
356                    (bfd_byte *) filehdr_out->dos_message[idx]);
357   }
358
359   /* also put in the NT signature */
360   bfd_h_put_32(abfd, filehdr_in->pe.nt_signature, 
361                (bfd_byte *) filehdr_out->nt_signature);
362
363
364
365
366   return sizeof(FILHDR);
367 }
368 #else
369
370 static  unsigned int
371 coff_swap_filehdr_out (abfd, in, out)
372      bfd       *abfd;
373      PTR        in;
374      PTR        out;
375 {
376   struct internal_filehdr *filehdr_in = (struct internal_filehdr *)in;
377   FILHDR *filehdr_out = (FILHDR *)out;
378
379   bfd_h_put_16(abfd, filehdr_in->f_magic, (bfd_byte *) filehdr_out->f_magic);
380   bfd_h_put_16(abfd, filehdr_in->f_nscns, (bfd_byte *) filehdr_out->f_nscns);
381   bfd_h_put_32(abfd, filehdr_in->f_timdat, (bfd_byte *) filehdr_out->f_timdat);
382   PUT_FILEHDR_SYMPTR (abfd, (bfd_vma) filehdr_in->f_symptr,
383                       (bfd_byte *) filehdr_out->f_symptr);
384   bfd_h_put_32(abfd, filehdr_in->f_nsyms, (bfd_byte *) filehdr_out->f_nsyms);
385   bfd_h_put_16(abfd, filehdr_in->f_opthdr, (bfd_byte *) filehdr_out->f_opthdr);
386   bfd_h_put_16(abfd, filehdr_in->f_flags, (bfd_byte *) filehdr_out->f_flags);
387
388   return sizeof(FILHDR);
389 }
390
391 #endif
392
393
394 static void
395 coff_swap_sym_in (abfd, ext1, in1)
396      bfd            *abfd;
397      PTR ext1;
398      PTR in1;
399 {
400   SYMENT *ext = (SYMENT *)ext1;
401   struct internal_syment      *in = (struct internal_syment *)in1;
402
403   if( ext->e.e_name[0] == 0) {
404     in->_n._n_n._n_zeroes = 0;
405     in->_n._n_n._n_offset = bfd_h_get_32(abfd, (bfd_byte *) ext->e.e.e_offset);
406   }
407   else {
408 #if SYMNMLEN != E_SYMNMLEN
409     -> Error, we need to cope with truncating or extending SYMNMLEN!;
410 #else
411     memcpy(in->_n._n_name, ext->e.e_name, SYMNMLEN);
412 #endif
413   }
414   in->n_value = bfd_h_get_32(abfd, (bfd_byte *) ext->e_value); 
415   in->n_scnum = bfd_h_get_16(abfd, (bfd_byte *) ext->e_scnum);
416   if (sizeof(ext->e_type) == 2){
417     in->n_type = bfd_h_get_16(abfd, (bfd_byte *) ext->e_type);
418   }
419   else {
420     in->n_type = bfd_h_get_32(abfd, (bfd_byte *) ext->e_type);
421   }
422   in->n_sclass = bfd_h_get_8(abfd, ext->e_sclass);
423   in->n_numaux = bfd_h_get_8(abfd, ext->e_numaux);
424
425   /* The section symbols for the .idata$ sections have class 68, which MS
426      documentation indicates is a section symbol.  The problem is that the
427      value field in the symbol is simply a copy of the .idata section's flags
428      rather than something useful.  When these symbols are encountered, change
429      the value to 0 and the section number to 1 so that they will be handled
430      somewhat correctly in the bfd code. */
431   if (in->n_sclass == 0x68) {
432     in->n_value = 0x0;
433     in->n_scnum = 1;
434     /* I have tried setting the class to 3 and using the following to set
435        the section number.  This will put the address of the pointer to the
436        string kernel32.dll at addresses 0 and 0x10 off start of idata section
437        which is not correct */
438     /*    if (strcmp (in->_n._n_name, ".idata$4") == 0) */
439     /*      in->n_scnum = 3; */
440     /*    else */
441     /*      in->n_scnum = 2; */
442   }
443 }
444
445 static unsigned int
446 coff_swap_sym_out (abfd, inp, extp)
447      bfd       *abfd;
448      PTR        inp;
449      PTR        extp;
450 {
451   struct internal_syment *in = (struct internal_syment *)inp;
452   SYMENT *ext =(SYMENT *)extp;
453   if(in->_n._n_name[0] == 0) {
454     bfd_h_put_32(abfd, 0, (bfd_byte *) ext->e.e.e_zeroes);
455     bfd_h_put_32(abfd, in->_n._n_n._n_offset, (bfd_byte *)  ext->e.e.e_offset);
456   }
457   else {
458 #if SYMNMLEN != E_SYMNMLEN
459     -> Error, we need to cope with truncating or extending SYMNMLEN!;
460 #else
461     memcpy(ext->e.e_name, in->_n._n_name, SYMNMLEN);
462 #endif
463   }
464   bfd_h_put_32(abfd,  in->n_value , (bfd_byte *) ext->e_value);
465   bfd_h_put_16(abfd,  in->n_scnum , (bfd_byte *) ext->e_scnum);
466   if (sizeof(ext->e_type) == 2)
467     {
468       bfd_h_put_16(abfd,  in->n_type , (bfd_byte *) ext->e_type);
469     }
470   else
471     {
472       bfd_h_put_32(abfd,  in->n_type , (bfd_byte *) ext->e_type);
473     }
474   bfd_h_put_8(abfd,  in->n_sclass , ext->e_sclass);
475   bfd_h_put_8(abfd,  in->n_numaux , ext->e_numaux);
476   return sizeof(SYMENT);
477 }
478
479 static void
480 coff_swap_aux_in (abfd, ext1, type, class, indx, numaux, in1)
481      bfd            *abfd;
482      PTR              ext1;
483      int             type;
484      int             class;
485      int              indx;
486      int              numaux;
487      PTR              in1;
488 {
489   AUXENT    *ext = (AUXENT *)ext1;
490   union internal_auxent *in = (union internal_auxent *)in1;
491
492   switch (class) {
493   case C_FILE:
494     if (ext->x_file.x_fname[0] == 0) {
495       in->x_file.x_n.x_zeroes = 0;
496       in->x_file.x_n.x_offset = 
497         bfd_h_get_32(abfd, (bfd_byte *) ext->x_file.x_n.x_offset);
498     } else {
499 #if FILNMLEN != E_FILNMLEN
500       -> Error, we need to cope with truncating or extending FILNMLEN!;
501 #else
502       memcpy (in->x_file.x_fname, ext->x_file.x_fname, FILNMLEN);
503 #endif
504     }
505     return;
506
507
508   case C_STAT:
509 #ifdef C_LEAFSTAT
510   case C_LEAFSTAT:
511 #endif
512   case C_HIDDEN:
513     if (type == T_NULL) {
514       in->x_scn.x_scnlen = GET_SCN_SCNLEN(abfd, ext);
515       in->x_scn.x_nreloc = GET_SCN_NRELOC(abfd, ext);
516       in->x_scn.x_nlinno = GET_SCN_NLINNO(abfd, ext);
517       return;
518     }
519     break;
520   }
521
522   in->x_sym.x_tagndx.l = bfd_h_get_32(abfd, (bfd_byte *) ext->x_sym.x_tagndx);
523 #ifndef NO_TVNDX
524   in->x_sym.x_tvndx = bfd_h_get_16(abfd, (bfd_byte *) ext->x_sym.x_tvndx);
525 #endif
526
527   if (class == C_BLOCK || ISFCN (type) || ISTAG (class))
528     {
529       in->x_sym.x_fcnary.x_fcn.x_lnnoptr = GET_FCN_LNNOPTR (abfd, ext);
530       in->x_sym.x_fcnary.x_fcn.x_endndx.l = GET_FCN_ENDNDX (abfd, ext);
531     }
532   else
533     {
534 #if DIMNUM != E_DIMNUM
535  #error we need to cope with truncating or extending DIMNUM
536 #endif
537       in->x_sym.x_fcnary.x_ary.x_dimen[0] =
538         bfd_h_get_16 (abfd, (bfd_byte *) ext->x_sym.x_fcnary.x_ary.x_dimen[0]);
539       in->x_sym.x_fcnary.x_ary.x_dimen[1] =
540         bfd_h_get_16 (abfd, (bfd_byte *) ext->x_sym.x_fcnary.x_ary.x_dimen[1]);
541       in->x_sym.x_fcnary.x_ary.x_dimen[2] =
542         bfd_h_get_16 (abfd, (bfd_byte *) ext->x_sym.x_fcnary.x_ary.x_dimen[2]);
543       in->x_sym.x_fcnary.x_ary.x_dimen[3] =
544         bfd_h_get_16 (abfd, (bfd_byte *) ext->x_sym.x_fcnary.x_ary.x_dimen[3]);
545     }
546
547   if (ISFCN(type)) {
548     in->x_sym.x_misc.x_fsize = bfd_h_get_32(abfd, (bfd_byte *) ext->x_sym.x_misc.x_fsize);
549   }
550   else {
551     in->x_sym.x_misc.x_lnsz.x_lnno = GET_LNSZ_LNNO(abfd, ext);
552     in->x_sym.x_misc.x_lnsz.x_size = GET_LNSZ_SIZE(abfd, ext);
553   }
554 }
555
556 static unsigned int
557 coff_swap_aux_out (abfd, inp, type, class, indx, numaux, extp)
558      bfd   *abfd;
559      PTR        inp;
560      int   type;
561      int   class;
562      int   indx;
563      int   numaux;
564      PTR        extp;
565 {
566   union internal_auxent *in = (union internal_auxent *)inp;
567   AUXENT *ext = (AUXENT *)extp;
568
569   memset((PTR)ext, 0, AUXESZ);
570   switch (class) {
571   case C_FILE:
572     if (in->x_file.x_fname[0] == 0) {
573       bfd_h_put_32(abfd, 0, (bfd_byte *) ext->x_file.x_n.x_zeroes);
574       bfd_h_put_32(abfd,
575               in->x_file.x_n.x_offset,
576               (bfd_byte *) ext->x_file.x_n.x_offset);
577     }
578     else {
579 #if FILNMLEN != E_FILNMLEN
580       -> Error, we need to cope with truncating or extending FILNMLEN!;
581 #else
582       memcpy (ext->x_file.x_fname, in->x_file.x_fname, FILNMLEN);
583 #endif
584     }
585     return sizeof (AUXENT);
586
587
588   case C_STAT:
589 #ifdef C_LEAFSTAT
590   case C_LEAFSTAT:
591 #endif
592   case C_HIDDEN:
593     if (type == T_NULL) {
594       PUT_SCN_SCNLEN(abfd, in->x_scn.x_scnlen, ext);
595       PUT_SCN_NRELOC(abfd, in->x_scn.x_nreloc, ext);
596       PUT_SCN_NLINNO(abfd, in->x_scn.x_nlinno, ext);
597       return sizeof (AUXENT);
598     }
599     break;
600   }
601
602   bfd_h_put_32(abfd, in->x_sym.x_tagndx.l, (bfd_byte *) ext->x_sym.x_tagndx);
603 #ifndef NO_TVNDX
604   bfd_h_put_16(abfd, in->x_sym.x_tvndx , (bfd_byte *) ext->x_sym.x_tvndx);
605 #endif
606
607   if (class == C_BLOCK || ISFCN (type) || ISTAG (class))
608     {
609       PUT_FCN_LNNOPTR(abfd,  in->x_sym.x_fcnary.x_fcn.x_lnnoptr, ext);
610       PUT_FCN_ENDNDX(abfd,  in->x_sym.x_fcnary.x_fcn.x_endndx.l, ext);
611     }
612   else
613     {
614 #if DIMNUM != E_DIMNUM
615  #error we need to cope with truncating or extending DIMNUM
616 #endif
617       bfd_h_put_16 (abfd, in->x_sym.x_fcnary.x_ary.x_dimen[0],
618                     (bfd_byte *) ext->x_sym.x_fcnary.x_ary.x_dimen[0]);
619       bfd_h_put_16 (abfd, in->x_sym.x_fcnary.x_ary.x_dimen[1],
620                     (bfd_byte *) ext->x_sym.x_fcnary.x_ary.x_dimen[1]);
621       bfd_h_put_16 (abfd, in->x_sym.x_fcnary.x_ary.x_dimen[2],
622                     (bfd_byte *) ext->x_sym.x_fcnary.x_ary.x_dimen[2]);
623       bfd_h_put_16 (abfd, in->x_sym.x_fcnary.x_ary.x_dimen[3],
624                     (bfd_byte *) ext->x_sym.x_fcnary.x_ary.x_dimen[3]);
625     }
626
627   if (ISFCN (type))
628     bfd_h_put_32 (abfd, in->x_sym.x_misc.x_fsize,
629              (bfd_byte *)  ext->x_sym.x_misc.x_fsize);
630   else
631     {
632       PUT_LNSZ_LNNO (abfd, in->x_sym.x_misc.x_lnsz.x_lnno, ext);
633       PUT_LNSZ_SIZE (abfd, in->x_sym.x_misc.x_lnsz.x_size, ext);
634     }
635
636   return sizeof(AUXENT);
637 }
638
639
640 static void
641 coff_swap_lineno_in (abfd, ext1, in1)
642      bfd            *abfd;
643      PTR ext1;
644      PTR in1;
645 {
646   LINENO *ext = (LINENO *)ext1;
647   struct internal_lineno      *in = (struct internal_lineno *)in1;
648
649   in->l_addr.l_symndx = bfd_h_get_32(abfd, (bfd_byte *) ext->l_addr.l_symndx);
650   in->l_lnno = GET_LINENO_LNNO(abfd, ext);
651 }
652
653 static unsigned int
654 coff_swap_lineno_out (abfd, inp, outp)
655      bfd       *abfd;
656      PTR        inp;
657      PTR        outp;
658 {
659   struct internal_lineno *in = (struct internal_lineno *)inp;
660   struct external_lineno *ext = (struct external_lineno *)outp;
661   bfd_h_put_32(abfd, in->l_addr.l_symndx, (bfd_byte *)
662           ext->l_addr.l_symndx);
663
664   PUT_LINENO_LNNO (abfd, in->l_lnno, ext);
665   return sizeof(struct external_lineno);
666 }
667
668
669
670 static void
671 coff_swap_aouthdr_in (abfd, aouthdr_ext1, aouthdr_int1)
672      bfd            *abfd;
673      PTR aouthdr_ext1;
674      PTR aouthdr_int1;
675 {
676   struct internal_extra_pe_aouthdr *a;
677   PEAOUTHDR *src = (PEAOUTHDR *)(aouthdr_ext1);
678   AOUTHDR        *aouthdr_ext = (AOUTHDR *) aouthdr_ext1;
679   struct internal_aouthdr *aouthdr_int = (struct internal_aouthdr *)aouthdr_int1;
680
681   aouthdr_int->magic = bfd_h_get_16(abfd, (bfd_byte *) aouthdr_ext->magic);
682   aouthdr_int->vstamp = bfd_h_get_16(abfd, (bfd_byte *) aouthdr_ext->vstamp);
683   aouthdr_int->tsize =
684     GET_AOUTHDR_TSIZE (abfd, (bfd_byte *) aouthdr_ext->tsize);
685   aouthdr_int->dsize =
686     GET_AOUTHDR_DSIZE (abfd, (bfd_byte *) aouthdr_ext->dsize);
687   aouthdr_int->bsize =
688     GET_AOUTHDR_BSIZE (abfd, (bfd_byte *) aouthdr_ext->bsize);
689   aouthdr_int->entry =
690     GET_AOUTHDR_ENTRY (abfd, (bfd_byte *) aouthdr_ext->entry);
691   aouthdr_int->text_start =
692     GET_AOUTHDR_TEXT_START (abfd, (bfd_byte *) aouthdr_ext->text_start);
693   aouthdr_int->data_start =
694     GET_AOUTHDR_DATA_START (abfd, (bfd_byte *) aouthdr_ext->data_start);
695
696   a = &aouthdr_int->pe;
697   a->ImageBase = bfd_h_get_32 (abfd, src->ImageBase);
698   a->SectionAlignment = bfd_h_get_32 (abfd, src->SectionAlignment);
699   a->FileAlignment = bfd_h_get_32 (abfd, src->FileAlignment);
700   a->MajorOperatingSystemVersion = 
701     bfd_h_get_16 (abfd, src->MajorOperatingSystemVersion);
702   a->MinorOperatingSystemVersion = 
703     bfd_h_get_16 (abfd, src->MinorOperatingSystemVersion);
704   a->MajorImageVersion = bfd_h_get_16 (abfd, src->MajorImageVersion);
705   a->MinorImageVersion = bfd_h_get_16 (abfd, src->MinorImageVersion);
706   a->MajorSubsystemVersion = bfd_h_get_16 (abfd, src->MajorSubsystemVersion);
707   a->MinorSubsystemVersion = bfd_h_get_16 (abfd, src->MinorSubsystemVersion);
708   a->Reserved1 = bfd_h_get_32 (abfd, src->Reserved1);
709   a->SizeOfImage = bfd_h_get_32 (abfd, src->SizeOfImage);
710   a->SizeOfHeaders = bfd_h_get_32 (abfd, src->SizeOfHeaders);
711   a->CheckSum = bfd_h_get_32 (abfd, src->CheckSum);
712   a->Subsystem = bfd_h_get_16 (abfd, src->Subsystem);
713   a->DllCharacteristics = bfd_h_get_16 (abfd, src->DllCharacteristics);
714   a->SizeOfStackReserve = bfd_h_get_32 (abfd, src->SizeOfStackReserve);
715   a->SizeOfStackCommit = bfd_h_get_32 (abfd, src->SizeOfStackCommit);
716   a->SizeOfHeapReserve = bfd_h_get_32 (abfd, src->SizeOfHeapReserve);
717   a->SizeOfHeapCommit = bfd_h_get_32 (abfd, src->SizeOfHeapCommit);
718   a->LoaderFlags = bfd_h_get_32 (abfd, src->LoaderFlags);
719   a->NumberOfRvaAndSizes = bfd_h_get_32 (abfd, src->NumberOfRvaAndSizes);
720
721   {
722     int idx;
723     for (idx=0; idx < 16; idx++)
724       {
725         a->DataDirectory[idx].VirtualAddress =
726           bfd_h_get_32 (abfd, src->DataDirectory[idx][0]);
727         a->DataDirectory[idx].Size =
728           bfd_h_get_32 (abfd, src->DataDirectory[idx][1]);
729       }
730   }
731
732   if (aouthdr_int->entry)
733     aouthdr_int->entry += a->ImageBase;
734   if (aouthdr_int->tsize) 
735     aouthdr_int->text_start += a->ImageBase;
736   if (aouthdr_int->dsize) 
737     aouthdr_int->data_start += a->ImageBase;
738 }
739
740
741 static void add_data_entry (abfd, aout, idx, name, base)
742      bfd *abfd;
743      struct internal_extra_pe_aouthdr *aout;
744      int idx;
745      char *name;
746      bfd_vma base;
747 {
748   asection *sec = bfd_get_section_by_name (abfd, name);
749
750   /* add import directory information if it exists */
751   if (sec != NULL)
752     {
753       aout->DataDirectory[idx].VirtualAddress = sec->lma - base;
754       aout->DataDirectory[idx].Size = sec->_raw_size;
755       sec->flags |= SEC_DATA;
756     }
757 }
758
759
760 static unsigned int
761 coff_swap_aouthdr_out (abfd, in, out)
762      bfd       *abfd;
763      PTR        in;
764      PTR        out;
765 {
766   struct internal_aouthdr *aouthdr_in = (struct internal_aouthdr *)in;
767   struct internal_extra_pe_aouthdr *extra = &pe_data (abfd)->pe_opthdr;
768   PEAOUTHDR *aouthdr_out = (PEAOUTHDR *)out;
769
770   bfd_vma sa = extra->SectionAlignment;
771   bfd_vma fa = extra->FileAlignment;
772   bfd_vma ib = extra->ImageBase ;
773
774   if (aouthdr_in->tsize) 
775     aouthdr_in->text_start -= ib;
776   if (aouthdr_in->dsize) 
777     aouthdr_in->data_start -= ib;
778   if (aouthdr_in->entry) 
779     aouthdr_in->entry -= ib;
780
781 #define FA(x)  (((x) + fa -1 ) & (- fa))
782 #define SA(x)  (((x) + sa -1 ) & (- sa))
783
784   /* We like to have the sizes aligned */
785
786   aouthdr_in->bsize = FA (aouthdr_in->bsize);
787
788
789   extra->NumberOfRvaAndSizes = IMAGE_NUMBEROF_DIRECTORY_ENTRIES;
790
791   /* first null out all data directory entries .. */
792   memset (extra->DataDirectory, sizeof (extra->DataDirectory), 0);
793
794   add_data_entry (abfd, extra, 0, ".edata", ib);
795   add_data_entry (abfd, extra, 1, ".idata", ib);
796   add_data_entry (abfd, extra, 2, ".rsrc" ,ib);
797   add_data_entry (abfd, extra, 5, ".reloc", ib);
798   {
799     asection *sec;
800     bfd_vma dsize= 0;
801     bfd_vma isize = SA(abfd->sections->filepos);
802     bfd_vma tsize= 0;
803     for (sec = abfd->sections; sec; sec = sec->next)
804       {
805         int rounded = FA(sec->_raw_size);
806         if (sec->flags & SEC_DATA) 
807           dsize += rounded;
808         if (sec->flags & SEC_CODE)
809           tsize += rounded;
810         isize += SA(rounded);
811       }
812
813     aouthdr_in->dsize = dsize;
814     aouthdr_in->tsize = tsize;
815     extra->SizeOfImage = isize;
816   }
817
818   extra->SizeOfHeaders = abfd->sections->filepos;
819   bfd_h_put_16(abfd, aouthdr_in->magic, (bfd_byte *) aouthdr_out->standard.magic);
820   bfd_h_put_16(abfd, aouthdr_in->vstamp, (bfd_byte *) aouthdr_out->standard.vstamp);
821   PUT_AOUTHDR_TSIZE (abfd, aouthdr_in->tsize, (bfd_byte *) aouthdr_out->standard.tsize);
822   PUT_AOUTHDR_DSIZE (abfd, aouthdr_in->dsize, (bfd_byte *) aouthdr_out->standard.dsize);
823   PUT_AOUTHDR_BSIZE (abfd, aouthdr_in->bsize, (bfd_byte *) aouthdr_out->standard.bsize);
824   PUT_AOUTHDR_ENTRY (abfd, aouthdr_in->entry, (bfd_byte *) aouthdr_out->standard.entry);
825   PUT_AOUTHDR_TEXT_START (abfd, aouthdr_in->text_start,
826                           (bfd_byte *) aouthdr_out->standard.text_start);
827   PUT_AOUTHDR_DATA_START (abfd, aouthdr_in->data_start,
828                           (bfd_byte *) aouthdr_out->standard.data_start);
829
830
831   bfd_h_put_32 (abfd, extra->ImageBase, 
832                 (bfd_byte *) aouthdr_out->ImageBase);
833   bfd_h_put_32 (abfd, extra->SectionAlignment,
834                 (bfd_byte *) aouthdr_out->SectionAlignment);
835   bfd_h_put_32 (abfd, extra->FileAlignment,
836                 (bfd_byte *) aouthdr_out->FileAlignment);
837   bfd_h_put_16 (abfd, extra->MajorOperatingSystemVersion,
838                 (bfd_byte *) aouthdr_out->MajorOperatingSystemVersion);
839   bfd_h_put_16 (abfd, extra->MinorOperatingSystemVersion,
840                 (bfd_byte *) aouthdr_out->MinorOperatingSystemVersion);
841   bfd_h_put_16 (abfd, extra->MajorImageVersion,
842                 (bfd_byte *) aouthdr_out->MajorImageVersion);
843   bfd_h_put_16 (abfd, extra->MinorImageVersion,
844                 (bfd_byte *) aouthdr_out->MinorImageVersion);
845   bfd_h_put_16 (abfd, extra->MajorSubsystemVersion,
846                 (bfd_byte *) aouthdr_out->MajorSubsystemVersion);
847   bfd_h_put_16 (abfd, extra->MinorSubsystemVersion,
848                 (bfd_byte *) aouthdr_out->MinorSubsystemVersion);
849   bfd_h_put_32 (abfd, extra->Reserved1,
850                 (bfd_byte *) aouthdr_out->Reserved1);
851   bfd_h_put_32 (abfd, extra->SizeOfImage,
852                 (bfd_byte *) aouthdr_out->SizeOfImage);
853   bfd_h_put_32 (abfd, extra->SizeOfHeaders,
854                 (bfd_byte *) aouthdr_out->SizeOfHeaders);
855   bfd_h_put_32 (abfd, extra->CheckSum,
856                 (bfd_byte *) aouthdr_out->CheckSum);
857   bfd_h_put_16 (abfd, extra->Subsystem,
858                 (bfd_byte *) aouthdr_out->Subsystem);
859   bfd_h_put_16 (abfd, extra->DllCharacteristics,
860                 (bfd_byte *) aouthdr_out->DllCharacteristics);
861   bfd_h_put_32 (abfd, extra->SizeOfStackReserve,
862                 (bfd_byte *) aouthdr_out->SizeOfStackReserve);
863   bfd_h_put_32 (abfd, extra->SizeOfStackCommit,
864                 (bfd_byte *) aouthdr_out->SizeOfStackCommit);
865   bfd_h_put_32 (abfd, extra->SizeOfHeapReserve,
866                 (bfd_byte *) aouthdr_out->SizeOfHeapReserve);
867   bfd_h_put_32 (abfd, extra->SizeOfHeapCommit,
868                 (bfd_byte *) aouthdr_out->SizeOfHeapCommit);
869   bfd_h_put_32 (abfd, extra->LoaderFlags,
870                 (bfd_byte *) aouthdr_out->LoaderFlags);
871   bfd_h_put_32 (abfd, extra->NumberOfRvaAndSizes,
872                 (bfd_byte *) aouthdr_out->NumberOfRvaAndSizes);
873   {
874     int idx;
875     for (idx=0; idx < 16; idx++)
876       {
877         bfd_h_put_32 (abfd, extra->DataDirectory[idx].VirtualAddress,
878                       (bfd_byte *) aouthdr_out->DataDirectory[idx][0]);
879         bfd_h_put_32 (abfd, extra->DataDirectory[idx].Size,
880                       (bfd_byte *) aouthdr_out->DataDirectory[idx][1]);
881       }
882   }
883
884
885   return sizeof(AOUTHDR);
886 }
887
888 static void
889     coff_swap_scnhdr_in (abfd, ext, in)
890       bfd            *abfd;
891   PTR        ext;
892   PTR        in;
893 {
894   SCNHDR *scnhdr_ext = (SCNHDR *) ext;
895   struct internal_scnhdr *scnhdr_int = (struct internal_scnhdr *) in;
896
897   memcpy(scnhdr_int->s_name, scnhdr_ext->s_name, sizeof(scnhdr_int->s_name));
898   scnhdr_int->s_vaddr =
899     GET_SCNHDR_VADDR (abfd, (bfd_byte *) scnhdr_ext->s_vaddr);
900   scnhdr_int->s_paddr =
901     GET_SCNHDR_PADDR (abfd, (bfd_byte *) scnhdr_ext->s_paddr);
902   scnhdr_int->s_size =
903     GET_SCNHDR_SIZE (abfd, (bfd_byte *) scnhdr_ext->s_size);
904   scnhdr_int->s_scnptr =
905     GET_SCNHDR_SCNPTR (abfd, (bfd_byte *) scnhdr_ext->s_scnptr);
906   scnhdr_int->s_relptr =
907     GET_SCNHDR_RELPTR (abfd, (bfd_byte *) scnhdr_ext->s_relptr);
908   scnhdr_int->s_lnnoptr =
909     GET_SCNHDR_LNNOPTR (abfd, (bfd_byte *) scnhdr_ext->s_lnnoptr);
910   scnhdr_int->s_flags = bfd_h_get_32(abfd, (bfd_byte *) scnhdr_ext->s_flags);
911
912   scnhdr_int->s_nreloc = bfd_h_get_16(abfd, (bfd_byte *) scnhdr_ext->s_nreloc);
913   scnhdr_int->s_nlnno = bfd_h_get_16(abfd, (bfd_byte *) scnhdr_ext->s_nlnno);
914
915   if (scnhdr_int->s_vaddr != 0) 
916     {
917       scnhdr_int->s_vaddr += pe_data (abfd)->pe_opthdr.ImageBase;
918     }
919   if (strcmp (scnhdr_int->s_name, _BSS) == 0) 
920     {
921       scnhdr_int->s_size = scnhdr_int->s_paddr;
922       scnhdr_int->s_paddr = 0;
923     }
924 }
925
926 static unsigned int
927 coff_swap_scnhdr_out (abfd, in, out)
928      bfd       *abfd;
929      PTR        in;
930      PTR        out;
931 {
932   struct internal_scnhdr *scnhdr_int = (struct internal_scnhdr *)in;
933   SCNHDR *scnhdr_ext = (SCNHDR *)out;
934   unsigned int ret = sizeof (SCNHDR);
935   bfd_vma ps;
936   bfd_vma ss;
937
938   memcpy(scnhdr_ext->s_name, scnhdr_int->s_name, sizeof(scnhdr_int->s_name));
939
940
941   PUT_SCNHDR_VADDR (abfd, 
942                     (scnhdr_int->s_vaddr 
943                      - pe_data(abfd)->pe_opthdr.ImageBase),
944                     (bfd_byte *) scnhdr_ext->s_vaddr);
945
946   /* NT wants the size data to be rounded up to the next NT_FILE_ALIGNMENT
947      value except for the BSS section, its s_size should be 0 */
948
949
950   if (strcmp (scnhdr_int->s_name, _BSS) == 0) 
951     {
952       ps = scnhdr_int->s_size;
953       ss = 0;
954     }
955   else
956     {
957       ps = scnhdr_int->s_paddr;
958       ss = scnhdr_int->s_size;
959     }
960
961   PUT_SCNHDR_SIZE (abfd, ss,
962                    (bfd_byte *) scnhdr_ext->s_size);
963
964
965   PUT_SCNHDR_PADDR (abfd, ps, (bfd_byte *) scnhdr_ext->s_paddr);
966
967   PUT_SCNHDR_SCNPTR (abfd, scnhdr_int->s_scnptr,
968                      (bfd_byte *) scnhdr_ext->s_scnptr);
969   PUT_SCNHDR_RELPTR (abfd, scnhdr_int->s_relptr,
970                      (bfd_byte *) scnhdr_ext->s_relptr);
971   PUT_SCNHDR_LNNOPTR (abfd, scnhdr_int->s_lnnoptr,
972                       (bfd_byte *) scnhdr_ext->s_lnnoptr);
973
974   /* Extra flags must be set when dealing with NT.  All sections should also
975      have the IMAGE_SCN_MEM_READ (0x40000000) flag set.  In addition, the
976      .text section must have IMAGE_SCN_MEM_EXECUTE (0x20000000) and the data
977      sections (.idata, .data, .bss, .CRT) must have IMAGE_SCN_MEM_WRITE set
978      (this is especially important when dealing with the .idata section since
979      the addresses for routines from .dlls must be overwritten).  If .reloc
980      section data is ever generated, we must add IMAGE_SCN_MEM_DISCARDABLE
981      (0x02000000).  Also, the resource data should also be read and
982      writable.  */
983
984   /* FIXME: alignment is also encoded in this field, at least on ppc (krk) */
985   /* FIXME: even worse, I don't see how to get the original alignment field*/
986   /*        back...                                                        */
987
988   {
989     int flags = scnhdr_int->s_flags;
990     if (strcmp (scnhdr_int->s_name, ".data")  == 0 ||
991         strcmp (scnhdr_int->s_name, ".CRT")   == 0 ||
992         strcmp (scnhdr_int->s_name, ".rsrc")  == 0 ||
993         strcmp (scnhdr_int->s_name, ".bss")   == 0)
994       flags |= IMAGE_SCN_MEM_READ | IMAGE_SCN_MEM_WRITE;
995     else if (strcmp (scnhdr_int->s_name, ".text") == 0)
996       flags |= IMAGE_SCN_MEM_READ | IMAGE_SCN_MEM_EXECUTE;
997     else if (strcmp (scnhdr_int->s_name, ".reloc") == 0)
998       flags = SEC_DATA| IMAGE_SCN_MEM_READ | IMAGE_SCN_MEM_DISCARDABLE;
999     else if (strcmp (scnhdr_int->s_name, ".idata") == 0)
1000       flags = IMAGE_SCN_MEM_READ | IMAGE_SCN_MEM_WRITE | SEC_DATA;     
1001     else if (strcmp (scnhdr_int->s_name, ".rdata") == 0
1002              || strcmp (scnhdr_int->s_name, ".edata") == 0)
1003       flags =  IMAGE_SCN_MEM_READ | SEC_DATA;     
1004     /* ppc-nt additions */
1005     else if (strcmp (scnhdr_int->s_name, ".pdata") == 0)
1006       flags = IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_ALIGN_4BYTES |
1007                           IMAGE_SCN_MEM_READ ;
1008     else if (strcmp (scnhdr_int->s_name, ".reldata") == 0)
1009       flags =  IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_ALIGN_8BYTES |
1010                IMAGE_SCN_MEM_READ | IMAGE_SCN_MEM_WRITE ;
1011     else if (strcmp (scnhdr_int->s_name, ".ydata") == 0)
1012       flags =  IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_ALIGN_8BYTES |
1013                IMAGE_SCN_MEM_READ | IMAGE_SCN_MEM_WRITE ;
1014     else if (strcmp (scnhdr_int->s_name, ".drectve") == 0)
1015       flags =  IMAGE_SCN_LNK_INFO | IMAGE_SCN_LNK_REMOVE ;
1016     /* end of ppc-nt additions */
1017
1018     bfd_h_put_32(abfd, flags, (bfd_byte *) scnhdr_ext->s_flags);
1019   }
1020
1021   if (scnhdr_int->s_nlnno <= 0xffff)
1022     bfd_h_put_16(abfd, scnhdr_int->s_nlnno, (bfd_byte *) scnhdr_ext->s_nlnno);
1023   else
1024     {
1025       (*_bfd_error_handler) ("%s: line number overflow: 0x%lx > 0xffff",
1026                              bfd_get_filename (abfd),
1027                              scnhdr_int->s_nlnno);
1028       bfd_set_error (bfd_error_file_truncated);
1029       bfd_h_put_16 (abfd, 0xffff, (bfd_byte *) scnhdr_ext->s_nlnno);
1030       ret = 0;
1031     }
1032   if (scnhdr_int->s_nreloc <= 0xffff)
1033     bfd_h_put_16(abfd, scnhdr_int->s_nreloc, (bfd_byte *) scnhdr_ext->s_nreloc);
1034   else
1035     {
1036       (*_bfd_error_handler) ("%s: reloc overflow: 0x%lx > 0xffff",
1037                              bfd_get_filename (abfd),
1038                              scnhdr_int->s_nreloc);
1039       bfd_set_error (bfd_error_file_truncated);
1040       bfd_h_put_16 (abfd, 0xffff, (bfd_byte *) scnhdr_ext->s_nreloc);
1041       ret = 0;
1042     }
1043   return ret;
1044 }
1045 /**********************************************************************/
1046 static boolean
1047 pe_print_private_bfd_data (abfd, vfile)
1048      bfd*abfd;
1049      void *vfile;
1050 {
1051   FILE *file = vfile;
1052   int j;
1053   pe_data_type *pe = pe_data (abfd);
1054   struct internal_extra_pe_aouthdr *i = &pe->pe_opthdr;
1055   fprintf (file,"\nImageBase\t\t");
1056   fprintf_vma (file, i->ImageBase);
1057   fprintf (file,"\nSectionAlignment\t");
1058   fprintf_vma (file, i->SectionAlignment);
1059   fprintf (file,"\nFileAlignment\t\t");
1060   fprintf_vma (file, i->FileAlignment);
1061   fprintf (file,"\nMajorOSystemVersion\t%d\n", i->MajorOperatingSystemVersion);
1062   fprintf (file,"MinorOSystemVersion\t%d\n", i->MinorOperatingSystemVersion);
1063   fprintf (file,"MajorImageVersion\t%d\n", i->MajorImageVersion);
1064   fprintf (file,"MinorImageVersion\t%d\n", i->MinorImageVersion);
1065   fprintf (file,"MajorSubsystemVersion\t%d\n", i->MajorSubsystemVersion);
1066   fprintf (file,"MinorSubsystemVersion\t%d\n", i->MinorSubsystemVersion);
1067   fprintf (file,"Reserved1\t\t%08lx\n", i->Reserved1);
1068   fprintf (file,"SizeOfImage\t\t%08lx\n", i->SizeOfImage);
1069   fprintf (file,"SizeOfHeaders\t\t%08lx\n", i->SizeOfHeaders);
1070   fprintf (file,"CheckSum\t\t%08lx\n", i->CheckSum);
1071   fprintf (file,"Subsystem\t\t%08x\n", i->Subsystem);
1072   fprintf (file,"DllCharacteristics\t%08x\n", i->DllCharacteristics);
1073   fprintf (file,"SizeOfStackReserve\t");
1074   fprintf_vma (file, i->SizeOfStackReserve);
1075   fprintf (file,"\nSizeOfStackCommit\t");
1076   fprintf_vma (file, i->SizeOfStackCommit);
1077   fprintf (file,"\nSizeOfHeapReserve\t");
1078   fprintf_vma (file, i->SizeOfHeapReserve);
1079   fprintf (file,"\nSizeOfHeapCommit\t");
1080   fprintf_vma (file, i->SizeOfHeapCommit);
1081   fprintf (file,"\nLoaderFlags\t\t%08lx\n", i->LoaderFlags);
1082   fprintf (file,"NumberOfRvaAndSizes\t%08lx\n", i->NumberOfRvaAndSizes);
1083
1084   for (j = 0; j < IMAGE_NUMBEROF_DIRECTORY_ENTRIES; j++) 
1085     {
1086       fprintf (file, "Entry %2d ", j);
1087       fprintf_vma (file, i->DataDirectory[j].VirtualAddress);
1088       fprintf (file, " %08lx\n", i->DataDirectory[j].Size);
1089     }
1090
1091   return true;
1092 }
1093
1094 static boolean
1095 pe_mkobject (abfd)
1096      bfd * abfd;
1097 {
1098   pe_data_type *pe;
1099
1100   abfd->tdata.pe_obj_data = 
1101     (struct pe_tdata *) bfd_zalloc (abfd, sizeof (pe_data_type));
1102   if (abfd->tdata.pe_obj_data == 0)
1103     {
1104       bfd_set_error (bfd_error_no_memory);
1105       return false;
1106     }
1107   pe =pe_data (abfd);
1108   pe->coff.pe = 1;
1109   return true;
1110 }
1111
1112 /* Create the COFF backend specific information.  */
1113 static PTR
1114 pe_mkobject_hook (abfd, filehdr, aouthdr)
1115      bfd * abfd;
1116      PTR filehdr;
1117      PTR aouthdr;
1118 {
1119   struct internal_filehdr *internal_f = (struct internal_filehdr *) filehdr;
1120   pe_data_type *pe;
1121
1122   if (pe_mkobject (abfd) == false)
1123     return NULL;
1124
1125   pe = pe_data (abfd);
1126
1127   pe->coff.sym_filepos = internal_f->f_symptr;
1128
1129   /* These members communicate important constants about the symbol
1130      table to GDB's symbol-reading code.  These `constants'
1131      unfortunately vary among coff implementations...  */
1132   pe->coff.local_n_btmask = N_BTMASK;
1133   pe->coff.local_n_btshft = N_BTSHFT;
1134   pe->coff.local_n_tmask = N_TMASK;
1135   pe->coff.local_n_tshift = N_TSHIFT;
1136   pe->coff.local_symesz = SYMESZ;
1137   pe->coff.local_auxesz = AUXESZ;
1138   pe->coff.local_linesz = LINESZ;
1139
1140   obj_raw_syment_count (abfd) =
1141     obj_conv_table_size (abfd) =
1142       internal_f->f_nsyms;
1143
1144 #ifdef COFF_IMAGE_WITH_PE
1145   pe->pe_opthdr = ((struct internal_aouthdr *)aouthdr)->pe;
1146 #endif
1147
1148   return (PTR) pe;
1149 }
1150
1151
1152
1153 /* Copy any private info we understand from the input bfd
1154    to the output bfd.  */
1155
1156 #define coff_bfd_copy_private_bfd_data pe_bfd_copy_private_bfd_data
1157
1158 static boolean
1159 pe_bfd_copy_private_bfd_data (ibfd, obfd)
1160      bfd *ibfd, *obfd;
1161 {
1162   /* One day we may try to grok other private data.  */
1163   if (ibfd->xvec->flavour != bfd_target_coff_flavour
1164       || obfd->xvec->flavour != bfd_target_coff_flavour)
1165     return true;
1166
1167   pe_data(obfd)->pe_opthdr = pe_data (ibfd)->pe_opthdr;
1168
1169   return true;
1170 }
1171
1172