PR binutils/15462
[platform/upstream/binutils.git] / bfd / coffswap.h
1 /* Generic COFF swapping routines, for BFD.
2    Copyright 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1999, 2000,
3    2001, 2002, 2004, 2005, 2007
4    Free Software Foundation, Inc.
5    Written by Cygnus Support.
6
7    This file is part of BFD, the Binary File Descriptor library.
8
9    This program is free software; you can redistribute it and/or modify
10    it under the terms of the GNU General Public License as published by
11    the Free Software Foundation; either version 3 of the License, or
12    (at your option) any later version.
13
14    This program is distributed in the hope that it will be useful,
15    but WITHOUT ANY WARRANTY; without even the implied warranty of
16    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17    GNU General Public License for more details.
18
19    You should have received a copy of the GNU General Public License
20    along with this program; if not, write to the Free Software
21    Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
22    MA 02110-1301, USA.  */
23
24 /* This file contains routines used to swap COFF data.  It is a header
25    file because the details of swapping depend on the details of the
26    structures used by each COFF implementation.  This is included by
27    coffcode.h, as well as by the ECOFF backend.
28
29    Any file which uses this must first include "coff/internal.h" and
30    "coff/CPU.h".  The functions will then be correct for that CPU.  */
31
32 #ifndef GET_FCN_LNNOPTR
33 #define GET_FCN_LNNOPTR(abfd, ext) \
34   H_GET_32 (abfd, 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   H_GET_32 (abfd, 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) \
44   H_PUT_32 (abfd,  in, ext->x_sym.x_fcnary.x_fcn.x_lnnoptr)
45 #endif
46 #ifndef PUT_FCN_ENDNDX
47 #define PUT_FCN_ENDNDX(abfd, in, ext) \
48   H_PUT_32 (abfd, in, ext->x_sym.x_fcnary.x_fcn.x_endndx)
49 #endif
50 #ifndef GET_LNSZ_LNNO
51 #define GET_LNSZ_LNNO(abfd, ext) \
52   H_GET_16 (abfd, ext->x_sym.x_misc.x_lnsz.x_lnno)
53 #endif
54 #ifndef GET_LNSZ_SIZE
55 #define GET_LNSZ_SIZE(abfd, ext) \
56   H_GET_16 (abfd, ext->x_sym.x_misc.x_lnsz.x_size)
57 #endif
58 #ifndef PUT_LNSZ_LNNO
59 #define PUT_LNSZ_LNNO(abfd, in, ext) \
60   H_PUT_16 (abfd, in, ext->x_sym.x_misc.x_lnsz.x_lnno)
61 #endif
62 #ifndef PUT_LNSZ_SIZE
63 #define PUT_LNSZ_SIZE(abfd, in, ext) \
64   H_PUT_16 (abfd, in, ext->x_sym.x_misc.x_lnsz.x_size)
65 #endif
66 #ifndef GET_SCN_SCNLEN
67 #define GET_SCN_SCNLEN(abfd, ext) \
68   H_GET_32 (abfd, ext->x_scn.x_scnlen)
69 #endif
70 #ifndef GET_SCN_NRELOC
71 #define GET_SCN_NRELOC(abfd, ext) \
72   H_GET_16 (abfd, ext->x_scn.x_nreloc)
73 #endif
74 #ifndef GET_SCN_NLINNO
75 #define GET_SCN_NLINNO(abfd, ext) \
76   H_GET_16 (abfd, ext->x_scn.x_nlinno)
77 #endif
78 #ifndef PUT_SCN_SCNLEN
79 #define PUT_SCN_SCNLEN(abfd, in, ext) \
80   H_PUT_32 (abfd, in, ext->x_scn.x_scnlen)
81 #endif
82 #ifndef PUT_SCN_NRELOC
83 #define PUT_SCN_NRELOC(abfd, in, ext) \
84   H_PUT_16 (abfd, in, ext->x_scn.x_nreloc)
85 #endif
86 #ifndef PUT_SCN_NLINNO
87 #define PUT_SCN_NLINNO(abfd, in, ext) \
88   H_PUT_16 (abfd, in, ext->x_scn.x_nlinno)
89 #endif
90 #ifndef GET_LINENO_LNNO
91 #define GET_LINENO_LNNO(abfd, ext) \
92   H_GET_16 (abfd, ext->l_lnno);
93 #endif
94 #ifndef PUT_LINENO_LNNO
95 #define PUT_LINENO_LNNO(abfd, val, ext) \
96   H_PUT_16 (abfd, val, ext->l_lnno);
97 #endif
98
99 /* The f_symptr field in the filehdr is sometimes 64 bits.  */
100 #ifndef GET_FILEHDR_SYMPTR
101 #define GET_FILEHDR_SYMPTR H_GET_32
102 #endif
103 #ifndef PUT_FILEHDR_SYMPTR
104 #define PUT_FILEHDR_SYMPTR H_PUT_32
105 #endif
106
107 /* Some fields in the aouthdr are sometimes 64 bits.  */
108 #ifndef GET_AOUTHDR_TSIZE
109 #define GET_AOUTHDR_TSIZE H_GET_32
110 #endif
111 #ifndef PUT_AOUTHDR_TSIZE
112 #define PUT_AOUTHDR_TSIZE H_PUT_32
113 #endif
114 #ifndef GET_AOUTHDR_DSIZE
115 #define GET_AOUTHDR_DSIZE H_GET_32
116 #endif
117 #ifndef PUT_AOUTHDR_DSIZE
118 #define PUT_AOUTHDR_DSIZE H_PUT_32
119 #endif
120 #ifndef GET_AOUTHDR_BSIZE
121 #define GET_AOUTHDR_BSIZE H_GET_32
122 #endif
123 #ifndef PUT_AOUTHDR_BSIZE
124 #define PUT_AOUTHDR_BSIZE H_PUT_32
125 #endif
126 #ifndef GET_AOUTHDR_ENTRY
127 #define GET_AOUTHDR_ENTRY H_GET_32
128 #endif
129 #ifndef PUT_AOUTHDR_ENTRY
130 #define PUT_AOUTHDR_ENTRY H_PUT_32
131 #endif
132 #ifndef GET_AOUTHDR_TEXT_START
133 #define GET_AOUTHDR_TEXT_START H_GET_32
134 #endif
135 #ifndef PUT_AOUTHDR_TEXT_START
136 #define PUT_AOUTHDR_TEXT_START H_PUT_32
137 #endif
138 #ifndef GET_AOUTHDR_DATA_START
139 #define GET_AOUTHDR_DATA_START H_GET_32
140 #endif
141 #ifndef PUT_AOUTHDR_DATA_START
142 #define PUT_AOUTHDR_DATA_START H_PUT_32
143 #endif
144
145 /* Some fields in the scnhdr are sometimes 64 bits.  */
146 #ifndef GET_SCNHDR_PADDR
147 #define GET_SCNHDR_PADDR H_GET_32
148 #endif
149 #ifndef PUT_SCNHDR_PADDR
150 #define PUT_SCNHDR_PADDR H_PUT_32
151 #endif
152 #ifndef GET_SCNHDR_VADDR
153 #define GET_SCNHDR_VADDR H_GET_32
154 #endif
155 #ifndef PUT_SCNHDR_VADDR
156 #define PUT_SCNHDR_VADDR H_PUT_32
157 #endif
158 #ifndef GET_SCNHDR_SIZE
159 #define GET_SCNHDR_SIZE H_GET_32
160 #endif
161 #ifndef PUT_SCNHDR_SIZE
162 #define PUT_SCNHDR_SIZE H_PUT_32
163 #endif
164 #ifndef GET_SCNHDR_SCNPTR
165 #define GET_SCNHDR_SCNPTR H_GET_32
166 #endif
167 #ifndef PUT_SCNHDR_SCNPTR
168 #define PUT_SCNHDR_SCNPTR H_PUT_32
169 #endif
170 #ifndef GET_SCNHDR_RELPTR
171 #define GET_SCNHDR_RELPTR H_GET_32
172 #endif
173 #ifndef PUT_SCNHDR_RELPTR
174 #define PUT_SCNHDR_RELPTR H_PUT_32
175 #endif
176 #ifndef GET_SCNHDR_LNNOPTR
177 #define GET_SCNHDR_LNNOPTR H_GET_32
178 #endif
179 #ifndef PUT_SCNHDR_LNNOPTR
180 #define PUT_SCNHDR_LNNOPTR H_PUT_32
181 #endif
182 #ifndef GET_SCNHDR_NRELOC
183 #define GET_SCNHDR_NRELOC H_GET_16
184 #endif
185 #ifndef MAX_SCNHDR_NRELOC
186 #define MAX_SCNHDR_NRELOC 0xffff
187 #endif
188 #ifndef PUT_SCNHDR_NRELOC
189 #define PUT_SCNHDR_NRELOC H_PUT_16
190 #endif
191 #ifndef GET_SCNHDR_NLNNO
192 #define GET_SCNHDR_NLNNO H_GET_16
193 #endif
194 #ifndef MAX_SCNHDR_NLNNO
195 #define MAX_SCNHDR_NLNNO 0xffff
196 #endif
197 #ifndef PUT_SCNHDR_NLNNO
198 #define PUT_SCNHDR_NLNNO H_PUT_16
199 #endif
200 #ifndef GET_SCNHDR_FLAGS
201 #define GET_SCNHDR_FLAGS H_GET_32
202 #endif
203 #ifndef PUT_SCNHDR_FLAGS
204 #define PUT_SCNHDR_FLAGS H_PUT_32
205 #endif
206
207 #ifndef GET_RELOC_VADDR
208 #define GET_RELOC_VADDR H_GET_32
209 #endif
210 #ifndef PUT_RELOC_VADDR
211 #define PUT_RELOC_VADDR H_PUT_32
212 #endif
213
214 #ifndef NO_COFF_RELOCS
215
216 static void
217 coff_swap_reloc_in (bfd * abfd, void * src, void * dst)
218 {
219   RELOC *reloc_src = (RELOC *) src;
220   struct internal_reloc *reloc_dst = (struct internal_reloc *) dst;
221
222   reloc_dst->r_vaddr  = GET_RELOC_VADDR (abfd, reloc_src->r_vaddr);
223   reloc_dst->r_symndx = H_GET_S32 (abfd, reloc_src->r_symndx);
224   reloc_dst->r_type   = H_GET_16 (abfd, reloc_src->r_type);
225
226 #ifdef SWAP_IN_RELOC_OFFSET
227   reloc_dst->r_offset = SWAP_IN_RELOC_OFFSET (abfd, reloc_src->r_offset);
228 #endif
229 }
230
231 static unsigned int
232 coff_swap_reloc_out (bfd * abfd, void * src, void * dst)
233 {
234   struct internal_reloc *reloc_src = (struct internal_reloc *) src;
235   struct external_reloc *reloc_dst = (struct external_reloc *) dst;
236
237   PUT_RELOC_VADDR (abfd, reloc_src->r_vaddr, reloc_dst->r_vaddr);
238   H_PUT_32 (abfd, reloc_src->r_symndx, reloc_dst->r_symndx);
239   H_PUT_16 (abfd, reloc_src->r_type, reloc_dst->r_type);
240
241 #ifdef SWAP_OUT_RELOC_OFFSET
242   SWAP_OUT_RELOC_OFFSET (abfd, reloc_src->r_offset, reloc_dst->r_offset);
243 #endif
244 #ifdef SWAP_OUT_RELOC_EXTRA
245   SWAP_OUT_RELOC_EXTRA (abfd, reloc_src, reloc_dst);
246 #endif
247
248   return bfd_coff_relsz (abfd);
249 }
250
251 #endif /* NO_COFF_RELOCS */
252
253 static void
254 coff_swap_filehdr_in (bfd * abfd, void * src, void * dst)
255 {
256   FILHDR *filehdr_src = (FILHDR *) src;
257   struct internal_filehdr *filehdr_dst = (struct internal_filehdr *) dst;
258
259 #ifdef COFF_ADJUST_FILEHDR_IN_PRE
260   COFF_ADJUST_FILEHDR_IN_PRE (abfd, src, dst);
261 #endif
262   filehdr_dst->f_magic  = H_GET_16 (abfd, filehdr_src->f_magic);
263   filehdr_dst->f_nscns  = H_GET_16 (abfd, filehdr_src->f_nscns);
264   filehdr_dst->f_timdat = H_GET_32 (abfd, filehdr_src->f_timdat);
265   filehdr_dst->f_symptr = GET_FILEHDR_SYMPTR (abfd, filehdr_src->f_symptr);
266   filehdr_dst->f_nsyms  = H_GET_32 (abfd, filehdr_src->f_nsyms);
267   filehdr_dst->f_opthdr = H_GET_16 (abfd, filehdr_src->f_opthdr);
268   filehdr_dst->f_flags  = H_GET_16 (abfd, filehdr_src->f_flags);
269 #ifdef TIC80_TARGET_ID
270   filehdr_dst->f_target_id = H_GET_16 (abfd, filehdr_src->f_target_id);
271 #endif
272
273 #ifdef COFF_ADJUST_FILEHDR_IN_POST
274   COFF_ADJUST_FILEHDR_IN_POST (abfd, src, dst);
275 #endif
276 }
277
278 static  unsigned int
279 coff_swap_filehdr_out (bfd *abfd, void * in, void * out)
280 {
281   struct internal_filehdr *filehdr_in = (struct internal_filehdr *) in;
282   FILHDR *filehdr_out = (FILHDR *) out;
283
284 #ifdef COFF_ADJUST_FILEHDR_OUT_PRE
285   COFF_ADJUST_FILEHDR_OUT_PRE (abfd, in, out);
286 #endif
287   H_PUT_16 (abfd, filehdr_in->f_magic, filehdr_out->f_magic);
288   H_PUT_16 (abfd, filehdr_in->f_nscns, filehdr_out->f_nscns);
289   H_PUT_32 (abfd, filehdr_in->f_timdat, filehdr_out->f_timdat);
290   PUT_FILEHDR_SYMPTR (abfd, filehdr_in->f_symptr, filehdr_out->f_symptr);
291   H_PUT_32 (abfd, filehdr_in->f_nsyms, filehdr_out->f_nsyms);
292   H_PUT_16 (abfd, filehdr_in->f_opthdr, filehdr_out->f_opthdr);
293   H_PUT_16 (abfd, filehdr_in->f_flags, filehdr_out->f_flags);
294 #ifdef TIC80_TARGET_ID
295   H_PUT_16 (abfd, filehdr_in->f_target_id, filehdr_out->f_target_id);
296 #endif
297
298 #ifdef COFF_ADJUST_FILEHDR_OUT_POST
299   COFF_ADJUST_FILEHDR_OUT_POST (abfd, in, out);
300 #endif
301   return bfd_coff_filhsz (abfd);
302 }
303
304 #ifndef NO_COFF_SYMBOLS
305
306 static void
307 coff_swap_sym_in (bfd * abfd, void * ext1, void * in1)
308 {
309   SYMENT *ext = (SYMENT *) ext1;
310   struct internal_syment *in = (struct internal_syment *) in1;
311
312   if (ext->e.e_name[0] == 0)
313     {
314       in->_n._n_n._n_zeroes = 0;
315       in->_n._n_n._n_offset = H_GET_32 (abfd, ext->e.e.e_offset);
316     }
317   else
318     {
319 #if SYMNMLEN != E_SYMNMLEN
320 #error we need to cope with truncating or extending SYMNMLEN
321 #else
322       memcpy (in->_n._n_name, ext->e.e_name, SYMNMLEN);
323 #endif
324     }
325
326   in->n_value = H_GET_32 (abfd, ext->e_value);
327   in->n_scnum = H_GET_16 (abfd, ext->e_scnum);
328   if (sizeof (ext->e_type) == 2)
329     in->n_type = H_GET_16 (abfd, ext->e_type);
330   else
331     in->n_type = H_GET_32 (abfd, ext->e_type);
332   in->n_sclass = H_GET_8 (abfd, ext->e_sclass);
333   in->n_numaux = H_GET_8 (abfd, ext->e_numaux);
334 #ifdef COFF_ADJUST_SYM_IN_POST
335   COFF_ADJUST_SYM_IN_POST (abfd, ext1, in1);
336 #endif
337 }
338
339 static unsigned int
340 coff_swap_sym_out (bfd * abfd, void * inp, void * extp)
341 {
342   struct internal_syment *in = (struct internal_syment *) inp;
343   SYMENT *ext =(SYMENT *) extp;
344
345 #ifdef COFF_ADJUST_SYM_OUT_PRE
346   COFF_ADJUST_SYM_OUT_PRE (abfd, inp, extp);
347 #endif
348
349   if (in->_n._n_name[0] == 0)
350     {
351       H_PUT_32 (abfd, 0, ext->e.e.e_zeroes);
352       H_PUT_32 (abfd, in->_n._n_n._n_offset, ext->e.e.e_offset);
353     }
354   else
355     {
356 #if SYMNMLEN != E_SYMNMLEN
357 #error we need to cope with truncating or extending SYMNMLEN
358 #else
359       memcpy (ext->e.e_name, in->_n._n_name, SYMNMLEN);
360 #endif
361     }
362
363   H_PUT_32 (abfd, in->n_value, ext->e_value);
364   H_PUT_16 (abfd, in->n_scnum, ext->e_scnum);
365
366   if (sizeof (ext->e_type) == 2)
367     H_PUT_16 (abfd, in->n_type, ext->e_type);
368   else
369     H_PUT_32 (abfd, in->n_type, ext->e_type);
370
371   H_PUT_8 (abfd, in->n_sclass, ext->e_sclass);
372   H_PUT_8 (abfd, in->n_numaux, ext->e_numaux);
373
374 #ifdef COFF_ADJUST_SYM_OUT_POST
375   COFF_ADJUST_SYM_OUT_POST (abfd, inp, extp);
376 #endif
377
378   return SYMESZ;
379 }
380
381 static void
382 coff_swap_aux_in (bfd *abfd,
383                   void * ext1,
384                   int type,
385                   int in_class,
386                   int indx,
387                   int numaux,
388                   void * in1)
389 {
390   AUXENT *ext = (AUXENT *) ext1;
391   union internal_auxent *in = (union internal_auxent *) in1;
392
393 #ifdef COFF_ADJUST_AUX_IN_PRE
394   COFF_ADJUST_AUX_IN_PRE (abfd, ext1, type, in_class, indx, numaux, in1);
395 #endif
396
397   switch (in_class)
398     {
399     case C_FILE:
400       if (ext->x_file.x_fname[0] == 0)
401         {
402           in->x_file.x_n.x_zeroes = 0;
403           in->x_file.x_n.x_offset = H_GET_32 (abfd, ext->x_file.x_n.x_offset);
404         }
405       else
406         {
407 #if FILNMLEN != E_FILNMLEN
408 #error we need to cope with truncating or extending FILNMLEN
409 #else
410           if (numaux > 1)
411             {
412               if (indx == 0)
413                 memcpy (in->x_file.x_fname, ext->x_file.x_fname,
414                         numaux * sizeof (AUXENT));
415             }
416           else
417             memcpy (in->x_file.x_fname, ext->x_file.x_fname, FILNMLEN);
418 #endif
419         }
420       goto end;
421
422     case C_STAT:
423 #ifdef C_LEAFSTAT
424     case C_LEAFSTAT:
425 #endif
426     case C_HIDDEN:
427       if (type == T_NULL)
428         {
429           in->x_scn.x_scnlen = GET_SCN_SCNLEN (abfd, ext);
430           in->x_scn.x_nreloc = GET_SCN_NRELOC (abfd, ext);
431           in->x_scn.x_nlinno = GET_SCN_NLINNO (abfd, ext);
432
433           /* PE defines some extra fields; we zero them out for
434              safety.  */
435           in->x_scn.x_checksum = 0;
436           in->x_scn.x_associated = 0;
437           in->x_scn.x_comdat = 0;
438
439           goto end;
440         }
441       break;
442     }
443
444   in->x_sym.x_tagndx.l = H_GET_32 (abfd, ext->x_sym.x_tagndx);
445 #ifndef NO_TVNDX
446   in->x_sym.x_tvndx = H_GET_16 (abfd, ext->x_sym.x_tvndx);
447 #endif
448
449   if (in_class == C_BLOCK || in_class == C_FCN || ISFCN (type)
450       || ISTAG (in_class))
451     {
452       in->x_sym.x_fcnary.x_fcn.x_lnnoptr = GET_FCN_LNNOPTR (abfd, ext);
453       in->x_sym.x_fcnary.x_fcn.x_endndx.l = GET_FCN_ENDNDX (abfd, ext);
454     }
455   else
456     {
457 #if DIMNUM != E_DIMNUM
458 #error we need to cope with truncating or extending DIMNUM
459 #endif
460       in->x_sym.x_fcnary.x_ary.x_dimen[0] =
461         H_GET_16 (abfd, ext->x_sym.x_fcnary.x_ary.x_dimen[0]);
462       in->x_sym.x_fcnary.x_ary.x_dimen[1] =
463         H_GET_16 (abfd, ext->x_sym.x_fcnary.x_ary.x_dimen[1]);
464       in->x_sym.x_fcnary.x_ary.x_dimen[2] =
465         H_GET_16 (abfd, ext->x_sym.x_fcnary.x_ary.x_dimen[2]);
466       in->x_sym.x_fcnary.x_ary.x_dimen[3] =
467         H_GET_16 (abfd, ext->x_sym.x_fcnary.x_ary.x_dimen[3]);
468     }
469
470   if (ISFCN (type))
471     in->x_sym.x_misc.x_fsize = H_GET_32 (abfd, ext->x_sym.x_misc.x_fsize);
472   else
473     {
474       in->x_sym.x_misc.x_lnsz.x_lnno = GET_LNSZ_LNNO (abfd, ext);
475       in->x_sym.x_misc.x_lnsz.x_size = GET_LNSZ_SIZE (abfd, ext);
476     }
477
478  end: ;
479
480 #ifdef COFF_ADJUST_AUX_IN_POST
481   COFF_ADJUST_AUX_IN_POST (abfd, ext1, type, in_class, indx, numaux, in1);
482 #endif
483 }
484
485 static unsigned int
486 coff_swap_aux_out (bfd * abfd,
487                    void * inp,
488                    int type,
489                    int in_class,
490                    int indx ATTRIBUTE_UNUSED,
491                    int numaux ATTRIBUTE_UNUSED,
492                    void * extp)
493 {
494   union internal_auxent * in = (union internal_auxent *) inp;
495   AUXENT *ext = (AUXENT *) extp;
496
497 #ifdef COFF_ADJUST_AUX_OUT_PRE
498   COFF_ADJUST_AUX_OUT_PRE (abfd, inp, type, in_class, indx, numaux, extp);
499 #endif
500
501   memset (ext, 0, AUXESZ);
502
503   switch (in_class)
504     {
505     case C_FILE:
506       if (in->x_file.x_fname[0] == 0)
507         {
508           H_PUT_32 (abfd, 0, ext->x_file.x_n.x_zeroes);
509           H_PUT_32 (abfd, in->x_file.x_n.x_offset, ext->x_file.x_n.x_offset);
510         }
511       else
512         {
513 #if FILNMLEN != E_FILNMLEN
514 #error we need to cope with truncating or extending FILNMLEN
515 #else
516           memcpy (ext->x_file.x_fname, in->x_file.x_fname, FILNMLEN);
517 #endif
518         }
519       goto end;
520
521     case C_STAT:
522 #ifdef C_LEAFSTAT
523     case C_LEAFSTAT:
524 #endif
525     case C_HIDDEN:
526       if (type == T_NULL)
527         {
528           PUT_SCN_SCNLEN (abfd, in->x_scn.x_scnlen, ext);
529           PUT_SCN_NRELOC (abfd, in->x_scn.x_nreloc, ext);
530           PUT_SCN_NLINNO (abfd, in->x_scn.x_nlinno, ext);
531           goto end;
532         }
533       break;
534     }
535
536   H_PUT_32 (abfd, in->x_sym.x_tagndx.l, ext->x_sym.x_tagndx);
537 #ifndef NO_TVNDX
538   H_PUT_16 (abfd, in->x_sym.x_tvndx, ext->x_sym.x_tvndx);
539 #endif
540
541   if (in_class == C_BLOCK || in_class == C_FCN || ISFCN (type)
542       || ISTAG (in_class))
543     {
544       PUT_FCN_LNNOPTR (abfd, in->x_sym.x_fcnary.x_fcn.x_lnnoptr, ext);
545       PUT_FCN_ENDNDX (abfd, in->x_sym.x_fcnary.x_fcn.x_endndx.l, ext);
546     }
547   else
548     {
549 #if DIMNUM != E_DIMNUM
550 #error we need to cope with truncating or extending DIMNUM
551 #endif
552       H_PUT_16 (abfd, in->x_sym.x_fcnary.x_ary.x_dimen[0],
553                ext->x_sym.x_fcnary.x_ary.x_dimen[0]);
554       H_PUT_16 (abfd, in->x_sym.x_fcnary.x_ary.x_dimen[1],
555                ext->x_sym.x_fcnary.x_ary.x_dimen[1]);
556       H_PUT_16 (abfd, in->x_sym.x_fcnary.x_ary.x_dimen[2],
557                ext->x_sym.x_fcnary.x_ary.x_dimen[2]);
558       H_PUT_16 (abfd, in->x_sym.x_fcnary.x_ary.x_dimen[3],
559                ext->x_sym.x_fcnary.x_ary.x_dimen[3]);
560     }
561
562   if (ISFCN (type))
563     H_PUT_32 (abfd, in->x_sym.x_misc.x_fsize, ext->x_sym.x_misc.x_fsize);
564   else
565     {
566       PUT_LNSZ_LNNO (abfd, in->x_sym.x_misc.x_lnsz.x_lnno, ext);
567       PUT_LNSZ_SIZE (abfd, in->x_sym.x_misc.x_lnsz.x_size, ext);
568     }
569
570  end:
571 #ifdef COFF_ADJUST_AUX_OUT_POST
572   COFF_ADJUST_AUX_OUT_POST (abfd, inp, type, in_class, indx, numaux, extp);
573 #endif
574   return AUXESZ;
575 }
576
577 #endif /* NO_COFF_SYMBOLS */
578
579 #ifndef NO_COFF_LINENOS
580
581 static void
582 coff_swap_lineno_in (bfd * abfd, void * ext1, void * in1)
583 {
584   LINENO *ext = (LINENO *) ext1;
585   struct internal_lineno *in = (struct internal_lineno *) in1;
586
587   in->l_addr.l_symndx = H_GET_32 (abfd, ext->l_addr.l_symndx);
588   in->l_lnno = GET_LINENO_LNNO (abfd, ext);
589 }
590
591 static unsigned int
592 coff_swap_lineno_out (bfd * abfd, void * inp, void * outp)
593 {
594   struct internal_lineno *in = (struct internal_lineno *) inp;
595   struct external_lineno *ext = (struct external_lineno *) outp;
596   H_PUT_32 (abfd, in->l_addr.l_symndx, ext->l_addr.l_symndx);
597
598   PUT_LINENO_LNNO (abfd, in->l_lnno, ext);
599   return LINESZ;
600 }
601
602 #endif /* NO_COFF_LINENOS */
603
604 static void
605 coff_swap_aouthdr_in (bfd * abfd, void * aouthdr_ext1, void * aouthdr_int1)
606 {
607   AOUTHDR *aouthdr_ext;
608   struct internal_aouthdr *aouthdr_int;
609
610   aouthdr_ext = (AOUTHDR *) aouthdr_ext1;
611   aouthdr_int = (struct internal_aouthdr *) aouthdr_int1;
612   aouthdr_int->magic = H_GET_16 (abfd, aouthdr_ext->magic);
613   aouthdr_int->vstamp = H_GET_16 (abfd, aouthdr_ext->vstamp);
614   aouthdr_int->tsize = GET_AOUTHDR_TSIZE (abfd, aouthdr_ext->tsize);
615   aouthdr_int->dsize = GET_AOUTHDR_DSIZE (abfd, aouthdr_ext->dsize);
616   aouthdr_int->bsize = GET_AOUTHDR_BSIZE (abfd, aouthdr_ext->bsize);
617   aouthdr_int->entry = GET_AOUTHDR_ENTRY (abfd, aouthdr_ext->entry);
618   aouthdr_int->text_start =
619     GET_AOUTHDR_TEXT_START (abfd, aouthdr_ext->text_start);
620   aouthdr_int->data_start =
621     GET_AOUTHDR_DATA_START (abfd, aouthdr_ext->data_start);
622
623 #ifdef I960
624   aouthdr_int->tagentries = H_GET_32 (abfd, aouthdr_ext->tagentries);
625 #endif
626
627 #ifdef APOLLO_M68
628   H_PUT_32 (abfd, aouthdr_int->o_inlib, aouthdr_ext->o_inlib);
629   H_PUT_32 (abfd, aouthdr_int->o_sri, aouthdr_ext->o_sri);
630   H_PUT_32 (abfd, aouthdr_int->vid[0], aouthdr_ext->vid);
631   H_PUT_32 (abfd, aouthdr_int->vid[1], aouthdr_ext->vid + 4);
632 #endif
633
634 #ifdef RS6000COFF_C
635 #ifdef XCOFF64
636   aouthdr_int->o_toc = H_GET_64 (abfd, aouthdr_ext->o_toc);
637 #else
638   aouthdr_int->o_toc = H_GET_32 (abfd, aouthdr_ext->o_toc);
639 #endif
640   aouthdr_int->o_snentry  = H_GET_16 (abfd, aouthdr_ext->o_snentry);
641   aouthdr_int->o_sntext   = H_GET_16 (abfd, aouthdr_ext->o_sntext);
642   aouthdr_int->o_sndata   = H_GET_16 (abfd, aouthdr_ext->o_sndata);
643   aouthdr_int->o_sntoc    = H_GET_16 (abfd, aouthdr_ext->o_sntoc);
644   aouthdr_int->o_snloader = H_GET_16 (abfd, aouthdr_ext->o_snloader);
645   aouthdr_int->o_snbss    = H_GET_16 (abfd, aouthdr_ext->o_snbss);
646   aouthdr_int->o_algntext = H_GET_16 (abfd, aouthdr_ext->o_algntext);
647   aouthdr_int->o_algndata = H_GET_16 (abfd, aouthdr_ext->o_algndata);
648   aouthdr_int->o_modtype  = H_GET_16 (abfd, aouthdr_ext->o_modtype);
649   aouthdr_int->o_cputype  = H_GET_16 (abfd, aouthdr_ext->o_cputype);
650 #ifdef XCOFF64
651   aouthdr_int->o_maxstack = H_GET_64 (abfd, aouthdr_ext->o_maxstack);
652   aouthdr_int->o_maxdata  = H_GET_64 (abfd, aouthdr_ext->o_maxdata);
653 #else
654   aouthdr_int->o_maxstack = H_GET_32 (abfd, aouthdr_ext->o_maxstack);
655   aouthdr_int->o_maxdata  = H_GET_32 (abfd, aouthdr_ext->o_maxdata);
656 #endif
657 #endif
658
659 #ifdef MIPSECOFF
660   aouthdr_int->bss_start  = H_GET_32 (abfd, aouthdr_ext->bss_start);
661   aouthdr_int->gp_value   = H_GET_32 (abfd, aouthdr_ext->gp_value);
662   aouthdr_int->gprmask    = H_GET_32 (abfd, aouthdr_ext->gprmask);
663   aouthdr_int->cprmask[0] = H_GET_32 (abfd, aouthdr_ext->cprmask[0]);
664   aouthdr_int->cprmask[1] = H_GET_32 (abfd, aouthdr_ext->cprmask[1]);
665   aouthdr_int->cprmask[2] = H_GET_32 (abfd, aouthdr_ext->cprmask[2]);
666   aouthdr_int->cprmask[3] = H_GET_32 (abfd, aouthdr_ext->cprmask[3]);
667 #endif
668
669 #ifdef ALPHAECOFF
670   aouthdr_int->bss_start = H_GET_64 (abfd, aouthdr_ext->bss_start);
671   aouthdr_int->gp_value  = H_GET_64 (abfd, aouthdr_ext->gp_value);
672   aouthdr_int->gprmask   = H_GET_32 (abfd, aouthdr_ext->gprmask);
673   aouthdr_int->fprmask   = H_GET_32 (abfd, aouthdr_ext->fprmask);
674 #endif
675 }
676
677 static unsigned int
678 coff_swap_aouthdr_out (bfd * abfd, void * in, void * out)
679 {
680   struct internal_aouthdr *aouthdr_in = (struct internal_aouthdr *) in;
681   AOUTHDR *aouthdr_out = (AOUTHDR *) out;
682
683   H_PUT_16 (abfd, aouthdr_in->magic, aouthdr_out->magic);
684   H_PUT_16 (abfd, aouthdr_in->vstamp, aouthdr_out->vstamp);
685   PUT_AOUTHDR_TSIZE (abfd, aouthdr_in->tsize, aouthdr_out->tsize);
686   PUT_AOUTHDR_DSIZE (abfd, aouthdr_in->dsize, aouthdr_out->dsize);
687   PUT_AOUTHDR_BSIZE (abfd, aouthdr_in->bsize, aouthdr_out->bsize);
688   PUT_AOUTHDR_ENTRY (abfd, aouthdr_in->entry, aouthdr_out->entry);
689   PUT_AOUTHDR_TEXT_START (abfd, aouthdr_in->text_start,
690                           aouthdr_out->text_start);
691   PUT_AOUTHDR_DATA_START (abfd, aouthdr_in->data_start,
692                           aouthdr_out->data_start);
693
694 #ifdef I960
695   H_PUT_32 (abfd, aouthdr_in->tagentries, aouthdr_out->tagentries);
696 #endif
697
698 #ifdef RS6000COFF_C
699 #ifdef XCOFF64
700   H_PUT_64 (abfd, aouthdr_in->o_toc, aouthdr_out->o_toc);
701 #else
702   H_PUT_32 (abfd, aouthdr_in->o_toc, aouthdr_out->o_toc);
703 #endif
704   H_PUT_16 (abfd, aouthdr_in->o_snentry, aouthdr_out->o_snentry);
705   H_PUT_16 (abfd, aouthdr_in->o_sntext, aouthdr_out->o_sntext);
706   H_PUT_16 (abfd, aouthdr_in->o_sndata, aouthdr_out->o_sndata);
707   H_PUT_16 (abfd, aouthdr_in->o_sntoc, aouthdr_out->o_sntoc);
708   H_PUT_16 (abfd, aouthdr_in->o_snloader, aouthdr_out->o_snloader);
709   H_PUT_16 (abfd, aouthdr_in->o_snbss, aouthdr_out->o_snbss);
710   H_PUT_16 (abfd, aouthdr_in->o_algntext, aouthdr_out->o_algntext);
711   H_PUT_16 (abfd, aouthdr_in->o_algndata, aouthdr_out->o_algndata);
712   H_PUT_16 (abfd, aouthdr_in->o_modtype, aouthdr_out->o_modtype);
713   H_PUT_16 (abfd, aouthdr_in->o_cputype, aouthdr_out->o_cputype);
714 #ifdef XCOFF64
715   H_PUT_64 (abfd, aouthdr_in->o_maxstack, aouthdr_out->o_maxstack);
716   H_PUT_64 (abfd, aouthdr_in->o_maxdata, aouthdr_out->o_maxdata);
717 #else
718   H_PUT_32 (abfd, aouthdr_in->o_maxstack, aouthdr_out->o_maxstack);
719   H_PUT_32 (abfd, aouthdr_in->o_maxdata, aouthdr_out->o_maxdata);
720 #endif
721   memset (aouthdr_out->o_resv2, 0, sizeof aouthdr_out->o_resv2);
722 #ifdef XCOFF64
723   memset (aouthdr_out->o_debugger, 0, sizeof aouthdr_out->o_debugger);
724   memset (aouthdr_out->o_resv3, 0, sizeof aouthdr_out->o_resv3);
725 #endif
726 #endif
727
728 #ifdef MIPSECOFF
729   H_PUT_32 (abfd, aouthdr_in->bss_start, aouthdr_out->bss_start);
730   H_PUT_32 (abfd, aouthdr_in->gp_value, aouthdr_out->gp_value);
731   H_PUT_32 (abfd, aouthdr_in->gprmask, aouthdr_out->gprmask);
732   H_PUT_32 (abfd, aouthdr_in->cprmask[0], aouthdr_out->cprmask[0]);
733   H_PUT_32 (abfd, aouthdr_in->cprmask[1], aouthdr_out->cprmask[1]);
734   H_PUT_32 (abfd, aouthdr_in->cprmask[2], aouthdr_out->cprmask[2]);
735   H_PUT_32 (abfd, aouthdr_in->cprmask[3], aouthdr_out->cprmask[3]);
736 #endif
737
738 #ifdef ALPHAECOFF
739   /* FIXME: What does bldrev mean?  */
740   H_PUT_16 (abfd, 2, aouthdr_out->bldrev);
741   H_PUT_16 (abfd, 0, aouthdr_out->padding);
742   H_PUT_64 (abfd, aouthdr_in->bss_start, aouthdr_out->bss_start);
743   H_PUT_64 (abfd, aouthdr_in->gp_value, aouthdr_out->gp_value);
744   H_PUT_32 (abfd, aouthdr_in->gprmask, aouthdr_out->gprmask);
745   H_PUT_32 (abfd, aouthdr_in->fprmask, aouthdr_out->fprmask);
746 #endif
747
748   return AOUTSZ;
749 }
750
751 static void
752 coff_swap_scnhdr_in (bfd * abfd, void * ext, void * in)
753 {
754   SCNHDR *scnhdr_ext = (SCNHDR *) ext;
755   struct internal_scnhdr *scnhdr_int = (struct internal_scnhdr *) in;
756
757 #ifdef COFF_ADJUST_SCNHDR_IN_PRE
758   COFF_ADJUST_SCNHDR_IN_PRE (abfd, ext, in);
759 #endif
760   memcpy (scnhdr_int->s_name, scnhdr_ext->s_name, sizeof (scnhdr_int->s_name));
761
762   scnhdr_int->s_vaddr = GET_SCNHDR_VADDR (abfd, scnhdr_ext->s_vaddr);
763   scnhdr_int->s_paddr = GET_SCNHDR_PADDR (abfd, scnhdr_ext->s_paddr);
764   scnhdr_int->s_size = GET_SCNHDR_SIZE (abfd, scnhdr_ext->s_size);
765
766   scnhdr_int->s_scnptr = GET_SCNHDR_SCNPTR (abfd, scnhdr_ext->s_scnptr);
767   scnhdr_int->s_relptr = GET_SCNHDR_RELPTR (abfd, scnhdr_ext->s_relptr);
768   scnhdr_int->s_lnnoptr = GET_SCNHDR_LNNOPTR (abfd, scnhdr_ext->s_lnnoptr);
769   scnhdr_int->s_flags = GET_SCNHDR_FLAGS (abfd, scnhdr_ext->s_flags);
770   scnhdr_int->s_nreloc = GET_SCNHDR_NRELOC (abfd, scnhdr_ext->s_nreloc);
771   scnhdr_int->s_nlnno = GET_SCNHDR_NLNNO (abfd, scnhdr_ext->s_nlnno);
772 #ifdef I960
773   scnhdr_int->s_align = GET_SCNHDR_ALIGN (abfd, scnhdr_ext->s_align);
774 #endif
775 #ifdef COFF_ADJUST_SCNHDR_IN_POST
776   COFF_ADJUST_SCNHDR_IN_POST (abfd, ext, in);
777 #endif
778 }
779
780 static unsigned int
781 coff_swap_scnhdr_out (bfd * abfd, void * in, void * out)
782 {
783   struct internal_scnhdr *scnhdr_int = (struct internal_scnhdr *) in;
784   SCNHDR *scnhdr_ext = (SCNHDR *) out;
785   unsigned int ret = bfd_coff_scnhsz (abfd);
786
787 #ifdef COFF_ADJUST_SCNHDR_OUT_PRE
788   COFF_ADJUST_SCNHDR_OUT_PRE (abfd, in, out);
789 #endif
790   memcpy (scnhdr_ext->s_name, scnhdr_int->s_name, sizeof (scnhdr_int->s_name));
791
792   PUT_SCNHDR_VADDR (abfd, scnhdr_int->s_vaddr, scnhdr_ext->s_vaddr);
793   PUT_SCNHDR_PADDR (abfd, scnhdr_int->s_paddr, scnhdr_ext->s_paddr);
794   PUT_SCNHDR_SIZE (abfd, scnhdr_int->s_size, scnhdr_ext->s_size);
795   PUT_SCNHDR_SCNPTR (abfd, scnhdr_int->s_scnptr, scnhdr_ext->s_scnptr);
796   PUT_SCNHDR_RELPTR (abfd, scnhdr_int->s_relptr, scnhdr_ext->s_relptr);
797   PUT_SCNHDR_LNNOPTR (abfd, scnhdr_int->s_lnnoptr, scnhdr_ext->s_lnnoptr);
798   PUT_SCNHDR_FLAGS (abfd, scnhdr_int->s_flags, scnhdr_ext->s_flags);
799 #if defined(M88)
800   H_PUT_32 (abfd, scnhdr_int->s_nlnno, scnhdr_ext->s_nlnno);
801   H_PUT_32 (abfd, scnhdr_int->s_nreloc, scnhdr_ext->s_nreloc);
802 #else
803   if (scnhdr_int->s_nlnno <= MAX_SCNHDR_NLNNO)
804     PUT_SCNHDR_NLNNO (abfd, scnhdr_int->s_nlnno, scnhdr_ext->s_nlnno);
805   else
806     {
807       char buf[sizeof (scnhdr_int->s_name) + 1];
808
809       memcpy (buf, scnhdr_int->s_name, sizeof (scnhdr_int->s_name));
810       buf[sizeof (scnhdr_int->s_name)] = '\0';
811       (*_bfd_error_handler)
812         (_("%s: warning: %s: line number overflow: 0x%lx > 0xffff"),
813          bfd_get_filename (abfd),
814          buf, scnhdr_int->s_nlnno);
815       PUT_SCNHDR_NLNNO (abfd, 0xffff, scnhdr_ext->s_nlnno);
816     }
817
818   if (scnhdr_int->s_nreloc <= MAX_SCNHDR_NRELOC)
819     PUT_SCNHDR_NRELOC (abfd, scnhdr_int->s_nreloc, scnhdr_ext->s_nreloc);
820   else
821     {
822       char buf[sizeof (scnhdr_int->s_name) + 1];
823
824       memcpy (buf, scnhdr_int->s_name, sizeof (scnhdr_int->s_name));
825       buf[sizeof (scnhdr_int->s_name)] = '\0';
826       (*_bfd_error_handler) (_("%s: %s: reloc overflow: 0x%lx > 0xffff"),
827                              bfd_get_filename (abfd),
828                              buf, scnhdr_int->s_nreloc);
829       bfd_set_error (bfd_error_file_truncated);
830       PUT_SCNHDR_NRELOC (abfd, 0xffff, scnhdr_ext->s_nreloc);
831       ret = 0;
832     }
833 #endif
834
835 #ifdef I960
836   PUT_SCNHDR_ALIGN (abfd, scnhdr_int->s_align, scnhdr_ext->s_align);
837 #endif
838 #ifdef COFF_ADJUST_SCNHDR_OUT_POST
839   COFF_ADJUST_SCNHDR_OUT_POST (abfd, in, out);
840 #endif
841   return ret;
842 }