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
214static void
215coff_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
229static unsigned int
230coff_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
251static void
252coff_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
273static  unsigned int
274coff_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
298static void
299coff_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
331static unsigned int
332coff_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
373static void
374coff_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 && coff_data (abfd)->pe)
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
477static unsigned int
478coff_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
573static void
574coff_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
583static unsigned int
584coff_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
596static void
597coff_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
658static unsigned int
659coff_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
728ATTRIBUTE_UNUSED
729static void
730coff_swap_scnhdr_in (bfd * abfd, void * ext, void * in)
731{
732  SCNHDR *scnhdr_ext = (SCNHDR *) ext;
733  struct internal_scnhdr *scnhdr_int = (struct internal_scnhdr *) in;
734
735#ifdef COFF_ADJUST_SCNHDR_IN_PRE
736  COFF_ADJUST_SCNHDR_IN_PRE (abfd, ext, in);
737#endif
738  memcpy (scnhdr_int->s_name, scnhdr_ext->s_name, sizeof (scnhdr_int->s_name));
739
740  scnhdr_int->s_vaddr = GET_SCNHDR_VADDR (abfd, scnhdr_ext->s_vaddr);
741  scnhdr_int->s_paddr = GET_SCNHDR_PADDR (abfd, scnhdr_ext->s_paddr);
742  scnhdr_int->s_size = GET_SCNHDR_SIZE (abfd, scnhdr_ext->s_size);
743
744  scnhdr_int->s_scnptr = GET_SCNHDR_SCNPTR (abfd, scnhdr_ext->s_scnptr);
745  scnhdr_int->s_relptr = GET_SCNHDR_RELPTR (abfd, scnhdr_ext->s_relptr);
746  scnhdr_int->s_lnnoptr = GET_SCNHDR_LNNOPTR (abfd, scnhdr_ext->s_lnnoptr);
747  scnhdr_int->s_flags = GET_SCNHDR_FLAGS (abfd, scnhdr_ext->s_flags);
748  scnhdr_int->s_nreloc = GET_SCNHDR_NRELOC (abfd, scnhdr_ext->s_nreloc);
749  scnhdr_int->s_nlnno = GET_SCNHDR_NLNNO (abfd, scnhdr_ext->s_nlnno);
750#ifdef COFF_ADJUST_SCNHDR_IN_POST
751  COFF_ADJUST_SCNHDR_IN_POST (abfd, ext, in);
752#endif
753}
754
755ATTRIBUTE_UNUSED
756static unsigned int
757coff_swap_scnhdr_out (bfd * abfd, void * in, void * out)
758{
759  struct internal_scnhdr *scnhdr_int = (struct internal_scnhdr *) in;
760  SCNHDR *scnhdr_ext = (SCNHDR *) out;
761  unsigned int ret = bfd_coff_scnhsz (abfd);
762
763#ifdef COFF_ADJUST_SCNHDR_OUT_PRE
764  COFF_ADJUST_SCNHDR_OUT_PRE (abfd, in, out);
765#endif
766  memcpy (scnhdr_ext->s_name, scnhdr_int->s_name, sizeof (scnhdr_int->s_name));
767
768  PUT_SCNHDR_VADDR (abfd, scnhdr_int->s_vaddr, scnhdr_ext->s_vaddr);
769  PUT_SCNHDR_PADDR (abfd, scnhdr_int->s_paddr, scnhdr_ext->s_paddr);
770  PUT_SCNHDR_SIZE (abfd, scnhdr_int->s_size, scnhdr_ext->s_size);
771  PUT_SCNHDR_SCNPTR (abfd, scnhdr_int->s_scnptr, scnhdr_ext->s_scnptr);
772  PUT_SCNHDR_RELPTR (abfd, scnhdr_int->s_relptr, scnhdr_ext->s_relptr);
773  PUT_SCNHDR_LNNOPTR (abfd, scnhdr_int->s_lnnoptr, scnhdr_ext->s_lnnoptr);
774  PUT_SCNHDR_FLAGS (abfd, scnhdr_int->s_flags, scnhdr_ext->s_flags);
775  if (scnhdr_int->s_nlnno <= MAX_SCNHDR_NLNNO)
776    PUT_SCNHDR_NLNNO (abfd, scnhdr_int->s_nlnno, scnhdr_ext->s_nlnno);
777  else
778    {
779      char buf[sizeof (scnhdr_int->s_name) + 1];
780
781      memcpy (buf, scnhdr_int->s_name, sizeof (scnhdr_int->s_name));
782      buf[sizeof (scnhdr_int->s_name)] = '\0';
783      _bfd_error_handler
784	/* xgettext:c-format */
785	(_("%pB: warning: %s: line number overflow: 0x%lx > 0xffff"),
786	 abfd, buf, scnhdr_int->s_nlnno);
787      PUT_SCNHDR_NLNNO (abfd, 0xffff, scnhdr_ext->s_nlnno);
788    }
789
790  if (scnhdr_int->s_nreloc <= MAX_SCNHDR_NRELOC)
791    PUT_SCNHDR_NRELOC (abfd, scnhdr_int->s_nreloc, scnhdr_ext->s_nreloc);
792  else
793    {
794      char buf[sizeof (scnhdr_int->s_name) + 1];
795
796      memcpy (buf, scnhdr_int->s_name, sizeof (scnhdr_int->s_name));
797      buf[sizeof (scnhdr_int->s_name)] = '\0';
798      /* xgettext:c-format */
799      _bfd_error_handler (_("%pB: %s: reloc overflow: 0x%lx > 0xffff"),
800			  abfd, buf, scnhdr_int->s_nreloc);
801      bfd_set_error (bfd_error_file_truncated);
802      PUT_SCNHDR_NRELOC (abfd, 0xffff, scnhdr_ext->s_nreloc);
803      ret = 0;
804    }
805
806#ifdef COFF_ADJUST_SCNHDR_OUT_POST
807  COFF_ADJUST_SCNHDR_OUT_POST (abfd, in, out);
808#endif
809  return ret;
810}
811