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