1/* Generic COFF swapping routines, for BFD.
2   Copyright (C) 1990-2017 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#ifdef TIC80_TARGET_ID
268  filehdr_dst->f_target_id = H_GET_16 (abfd, filehdr_src->f_target_id);
269#endif
270
271#ifdef COFF_ADJUST_FILEHDR_IN_POST
272  COFF_ADJUST_FILEHDR_IN_POST (abfd, src, dst);
273#endif
274}
275
276static  unsigned int
277coff_swap_filehdr_out (bfd *abfd, void * in, void * out)
278{
279  struct internal_filehdr *filehdr_in = (struct internal_filehdr *) in;
280  FILHDR *filehdr_out = (FILHDR *) out;
281
282#ifdef COFF_ADJUST_FILEHDR_OUT_PRE
283  COFF_ADJUST_FILEHDR_OUT_PRE (abfd, in, out);
284#endif
285  H_PUT_16 (abfd, filehdr_in->f_magic, filehdr_out->f_magic);
286  H_PUT_16 (abfd, filehdr_in->f_nscns, filehdr_out->f_nscns);
287  H_PUT_32 (abfd, filehdr_in->f_timdat, filehdr_out->f_timdat);
288  PUT_FILEHDR_SYMPTR (abfd, filehdr_in->f_symptr, filehdr_out->f_symptr);
289  H_PUT_32 (abfd, filehdr_in->f_nsyms, filehdr_out->f_nsyms);
290  H_PUT_16 (abfd, filehdr_in->f_opthdr, filehdr_out->f_opthdr);
291  H_PUT_16 (abfd, filehdr_in->f_flags, filehdr_out->f_flags);
292#ifdef TIC80_TARGET_ID
293  H_PUT_16 (abfd, filehdr_in->f_target_id, filehdr_out->f_target_id);
294#endif
295
296#ifdef COFF_ADJUST_FILEHDR_OUT_POST
297  COFF_ADJUST_FILEHDR_OUT_POST (abfd, in, out);
298#endif
299  return bfd_coff_filhsz (abfd);
300}
301
302#ifndef NO_COFF_SYMBOLS
303
304static void
305coff_swap_sym_in (bfd * abfd, void * ext1, void * in1)
306{
307  SYMENT *ext = (SYMENT *) ext1;
308  struct internal_syment *in = (struct internal_syment *) in1;
309
310  if (ext->e.e_name[0] == 0)
311    {
312      in->_n._n_n._n_zeroes = 0;
313      in->_n._n_n._n_offset = H_GET_32 (abfd, ext->e.e.e_offset);
314    }
315  else
316    {
317#if SYMNMLEN != E_SYMNMLEN
318#error we need to cope with truncating or extending SYMNMLEN
319#else
320      memcpy (in->_n._n_name, ext->e.e_name, SYMNMLEN);
321#endif
322    }
323
324  in->n_value = H_GET_32 (abfd, ext->e_value);
325  in->n_scnum = (short) H_GET_16 (abfd, ext->e_scnum);
326  if (sizeof (ext->e_type) == 2)
327    in->n_type = H_GET_16 (abfd, ext->e_type);
328  else
329    in->n_type = H_GET_32 (abfd, ext->e_type);
330  in->n_sclass = H_GET_8 (abfd, ext->e_sclass);
331  in->n_numaux = H_GET_8 (abfd, ext->e_numaux);
332#ifdef COFF_ADJUST_SYM_IN_POST
333  COFF_ADJUST_SYM_IN_POST (abfd, ext1, in1);
334#endif
335}
336
337static unsigned int
338coff_swap_sym_out (bfd * abfd, void * inp, void * extp)
339{
340  struct internal_syment *in = (struct internal_syment *) inp;
341  SYMENT *ext =(SYMENT *) extp;
342
343#ifdef COFF_ADJUST_SYM_OUT_PRE
344  COFF_ADJUST_SYM_OUT_PRE (abfd, inp, extp);
345#endif
346
347  if (in->_n._n_name[0] == 0)
348    {
349      H_PUT_32 (abfd, 0, ext->e.e.e_zeroes);
350      H_PUT_32 (abfd, in->_n._n_n._n_offset, ext->e.e.e_offset);
351    }
352  else
353    {
354#if SYMNMLEN != E_SYMNMLEN
355#error we need to cope with truncating or extending SYMNMLEN
356#else
357      memcpy (ext->e.e_name, in->_n._n_name, SYMNMLEN);
358#endif
359    }
360
361  H_PUT_32 (abfd, in->n_value, ext->e_value);
362  H_PUT_16 (abfd, in->n_scnum, ext->e_scnum);
363
364  if (sizeof (ext->e_type) == 2)
365    H_PUT_16 (abfd, in->n_type, ext->e_type);
366  else
367    H_PUT_32 (abfd, in->n_type, ext->e_type);
368
369  H_PUT_8 (abfd, in->n_sclass, ext->e_sclass);
370  H_PUT_8 (abfd, in->n_numaux, ext->e_numaux);
371
372#ifdef COFF_ADJUST_SYM_OUT_POST
373  COFF_ADJUST_SYM_OUT_POST (abfd, inp, extp);
374#endif
375
376  return SYMESZ;
377}
378
379static void
380coff_swap_aux_in (bfd *abfd,
381		  void * ext1,
382		  int type,
383		  int in_class,
384		  int indx,
385		  int numaux,
386		  void * in1)
387{
388  AUXENT *ext = (AUXENT *) ext1;
389  union internal_auxent *in = (union internal_auxent *) in1;
390
391#ifdef COFF_ADJUST_AUX_IN_PRE
392  COFF_ADJUST_AUX_IN_PRE (abfd, ext1, type, in_class, indx, numaux, in1);
393#endif
394
395  switch (in_class)
396    {
397    case C_FILE:
398      if (ext->x_file.x_fname[0] == 0)
399	{
400	  in->x_file.x_n.x_zeroes = 0;
401	  in->x_file.x_n.x_offset = H_GET_32 (abfd, ext->x_file.x_n.x_offset);
402	}
403      else
404	{
405#if FILNMLEN != E_FILNMLEN
406#error we need to cope with truncating or extending FILNMLEN
407#else
408	  if (numaux > 1)
409	    {
410	      if (indx == 0)
411		memcpy (in->x_file.x_fname, ext->x_file.x_fname,
412			numaux * sizeof (AUXENT));
413	    }
414	  else
415	    memcpy (in->x_file.x_fname, ext->x_file.x_fname, FILNMLEN);
416#endif
417	}
418      goto end;
419
420    case C_STAT:
421#ifdef C_LEAFSTAT
422    case C_LEAFSTAT:
423#endif
424    case C_HIDDEN:
425      if (type == T_NULL)
426	{
427	  in->x_scn.x_scnlen = GET_SCN_SCNLEN (abfd, ext);
428	  in->x_scn.x_nreloc = GET_SCN_NRELOC (abfd, ext);
429	  in->x_scn.x_nlinno = GET_SCN_NLINNO (abfd, ext);
430
431	  /* PE defines some extra fields; we zero them out for
432             safety.  */
433	  in->x_scn.x_checksum = 0;
434	  in->x_scn.x_associated = 0;
435	  in->x_scn.x_comdat = 0;
436
437	  goto end;
438	}
439      break;
440    }
441
442  in->x_sym.x_tagndx.l = H_GET_32 (abfd, ext->x_sym.x_tagndx);
443#ifndef NO_TVNDX
444  in->x_sym.x_tvndx = H_GET_16 (abfd, ext->x_sym.x_tvndx);
445#endif
446
447  if (in_class == C_BLOCK || in_class == C_FCN || ISFCN (type)
448      || ISTAG (in_class))
449    {
450      in->x_sym.x_fcnary.x_fcn.x_lnnoptr = GET_FCN_LNNOPTR (abfd, ext);
451      in->x_sym.x_fcnary.x_fcn.x_endndx.l = GET_FCN_ENDNDX (abfd, ext);
452    }
453  else
454    {
455#if DIMNUM != E_DIMNUM
456#error we need to cope with truncating or extending DIMNUM
457#endif
458      in->x_sym.x_fcnary.x_ary.x_dimen[0] =
459	H_GET_16 (abfd, ext->x_sym.x_fcnary.x_ary.x_dimen[0]);
460      in->x_sym.x_fcnary.x_ary.x_dimen[1] =
461	H_GET_16 (abfd, ext->x_sym.x_fcnary.x_ary.x_dimen[1]);
462      in->x_sym.x_fcnary.x_ary.x_dimen[2] =
463	H_GET_16 (abfd, ext->x_sym.x_fcnary.x_ary.x_dimen[2]);
464      in->x_sym.x_fcnary.x_ary.x_dimen[3] =
465	H_GET_16 (abfd, ext->x_sym.x_fcnary.x_ary.x_dimen[3]);
466    }
467
468  if (ISFCN (type))
469    in->x_sym.x_misc.x_fsize = H_GET_32 (abfd, ext->x_sym.x_misc.x_fsize);
470  else
471    {
472      in->x_sym.x_misc.x_lnsz.x_lnno = GET_LNSZ_LNNO (abfd, ext);
473      in->x_sym.x_misc.x_lnsz.x_size = GET_LNSZ_SIZE (abfd, ext);
474    }
475
476 end: ;
477
478#ifdef COFF_ADJUST_AUX_IN_POST
479  COFF_ADJUST_AUX_IN_POST (abfd, ext1, type, in_class, indx, numaux, in1);
480#endif
481}
482
483static unsigned int
484coff_swap_aux_out (bfd * abfd,
485		   void * inp,
486		   int type,
487		   int in_class,
488		   int indx ATTRIBUTE_UNUSED,
489		   int numaux ATTRIBUTE_UNUSED,
490		   void * extp)
491{
492  union internal_auxent * in = (union internal_auxent *) inp;
493  AUXENT *ext = (AUXENT *) extp;
494
495#ifdef COFF_ADJUST_AUX_OUT_PRE
496  COFF_ADJUST_AUX_OUT_PRE (abfd, inp, type, in_class, indx, numaux, extp);
497#endif
498
499  memset (ext, 0, AUXESZ);
500
501  switch (in_class)
502    {
503    case C_FILE:
504      if (in->x_file.x_fname[0] == 0)
505	{
506	  H_PUT_32 (abfd, 0, ext->x_file.x_n.x_zeroes);
507	  H_PUT_32 (abfd, in->x_file.x_n.x_offset, ext->x_file.x_n.x_offset);
508	}
509      else
510	{
511#if FILNMLEN != E_FILNMLEN
512#error we need to cope with truncating or extending FILNMLEN
513#else
514	  memcpy (ext->x_file.x_fname, in->x_file.x_fname, FILNMLEN);
515#endif
516	}
517      goto end;
518
519    case C_STAT:
520#ifdef C_LEAFSTAT
521    case C_LEAFSTAT:
522#endif
523    case C_HIDDEN:
524      if (type == T_NULL)
525	{
526	  PUT_SCN_SCNLEN (abfd, in->x_scn.x_scnlen, ext);
527	  PUT_SCN_NRELOC (abfd, in->x_scn.x_nreloc, ext);
528	  PUT_SCN_NLINNO (abfd, in->x_scn.x_nlinno, ext);
529	  goto end;
530	}
531      break;
532    }
533
534  H_PUT_32 (abfd, in->x_sym.x_tagndx.l, ext->x_sym.x_tagndx);
535#ifndef NO_TVNDX
536  H_PUT_16 (abfd, in->x_sym.x_tvndx, ext->x_sym.x_tvndx);
537#endif
538
539  if (in_class == C_BLOCK || in_class == C_FCN || ISFCN (type)
540      || ISTAG (in_class))
541    {
542      PUT_FCN_LNNOPTR (abfd, in->x_sym.x_fcnary.x_fcn.x_lnnoptr, ext);
543      PUT_FCN_ENDNDX (abfd, in->x_sym.x_fcnary.x_fcn.x_endndx.l, ext);
544    }
545  else
546    {
547#if DIMNUM != E_DIMNUM
548#error we need to cope with truncating or extending DIMNUM
549#endif
550      H_PUT_16 (abfd, in->x_sym.x_fcnary.x_ary.x_dimen[0],
551	       ext->x_sym.x_fcnary.x_ary.x_dimen[0]);
552      H_PUT_16 (abfd, in->x_sym.x_fcnary.x_ary.x_dimen[1],
553	       ext->x_sym.x_fcnary.x_ary.x_dimen[1]);
554      H_PUT_16 (abfd, in->x_sym.x_fcnary.x_ary.x_dimen[2],
555	       ext->x_sym.x_fcnary.x_ary.x_dimen[2]);
556      H_PUT_16 (abfd, in->x_sym.x_fcnary.x_ary.x_dimen[3],
557	       ext->x_sym.x_fcnary.x_ary.x_dimen[3]);
558    }
559
560  if (ISFCN (type))
561    H_PUT_32 (abfd, in->x_sym.x_misc.x_fsize, ext->x_sym.x_misc.x_fsize);
562  else
563    {
564      PUT_LNSZ_LNNO (abfd, in->x_sym.x_misc.x_lnsz.x_lnno, ext);
565      PUT_LNSZ_SIZE (abfd, in->x_sym.x_misc.x_lnsz.x_size, ext);
566    }
567
568 end:
569#ifdef COFF_ADJUST_AUX_OUT_POST
570  COFF_ADJUST_AUX_OUT_POST (abfd, inp, type, in_class, indx, numaux, extp);
571#endif
572  return AUXESZ;
573}
574
575#endif /* NO_COFF_SYMBOLS */
576
577#ifndef NO_COFF_LINENOS
578
579static void
580coff_swap_lineno_in (bfd * abfd, void * ext1, void * in1)
581{
582  LINENO *ext = (LINENO *) ext1;
583  struct internal_lineno *in = (struct internal_lineno *) in1;
584
585  in->l_addr.l_symndx = H_GET_32 (abfd, ext->l_addr.l_symndx);
586  in->l_lnno = GET_LINENO_LNNO (abfd, ext);
587}
588
589static unsigned int
590coff_swap_lineno_out (bfd * abfd, void * inp, void * outp)
591{
592  struct internal_lineno *in = (struct internal_lineno *) inp;
593  struct external_lineno *ext = (struct external_lineno *) outp;
594  H_PUT_32 (abfd, in->l_addr.l_symndx, ext->l_addr.l_symndx);
595
596  PUT_LINENO_LNNO (abfd, in->l_lnno, ext);
597  return LINESZ;
598}
599
600#endif /* NO_COFF_LINENOS */
601
602static void
603coff_swap_aouthdr_in (bfd * abfd, void * aouthdr_ext1, void * aouthdr_int1)
604{
605  AOUTHDR *aouthdr_ext;
606  struct internal_aouthdr *aouthdr_int;
607
608  aouthdr_ext = (AOUTHDR *) aouthdr_ext1;
609  aouthdr_int = (struct internal_aouthdr *) aouthdr_int1;
610  aouthdr_int->magic = H_GET_16 (abfd, aouthdr_ext->magic);
611  aouthdr_int->vstamp = H_GET_16 (abfd, aouthdr_ext->vstamp);
612  aouthdr_int->tsize = GET_AOUTHDR_TSIZE (abfd, aouthdr_ext->tsize);
613  aouthdr_int->dsize = GET_AOUTHDR_DSIZE (abfd, aouthdr_ext->dsize);
614  aouthdr_int->bsize = GET_AOUTHDR_BSIZE (abfd, aouthdr_ext->bsize);
615  aouthdr_int->entry = GET_AOUTHDR_ENTRY (abfd, aouthdr_ext->entry);
616  aouthdr_int->text_start =
617    GET_AOUTHDR_TEXT_START (abfd, aouthdr_ext->text_start);
618  aouthdr_int->data_start =
619    GET_AOUTHDR_DATA_START (abfd, aouthdr_ext->data_start);
620
621#ifdef I960
622  aouthdr_int->tagentries = H_GET_32 (abfd, aouthdr_ext->tagentries);
623#endif
624
625#ifdef APOLLO_M68
626  H_PUT_32 (abfd, aouthdr_int->o_inlib, aouthdr_ext->o_inlib);
627  H_PUT_32 (abfd, aouthdr_int->o_sri, aouthdr_ext->o_sri);
628  H_PUT_32 (abfd, aouthdr_int->vid[0], aouthdr_ext->vid);
629  H_PUT_32 (abfd, aouthdr_int->vid[1], aouthdr_ext->vid + 4);
630#endif
631
632#ifdef RS6000COFF_C
633#ifdef XCOFF64
634  aouthdr_int->o_toc = H_GET_64 (abfd, aouthdr_ext->o_toc);
635#else
636  aouthdr_int->o_toc = H_GET_32 (abfd, aouthdr_ext->o_toc);
637#endif
638  aouthdr_int->o_snentry  = H_GET_16 (abfd, aouthdr_ext->o_snentry);
639  aouthdr_int->o_sntext   = H_GET_16 (abfd, aouthdr_ext->o_sntext);
640  aouthdr_int->o_sndata   = H_GET_16 (abfd, aouthdr_ext->o_sndata);
641  aouthdr_int->o_sntoc    = H_GET_16 (abfd, aouthdr_ext->o_sntoc);
642  aouthdr_int->o_snloader = H_GET_16 (abfd, aouthdr_ext->o_snloader);
643  aouthdr_int->o_snbss    = H_GET_16 (abfd, aouthdr_ext->o_snbss);
644  aouthdr_int->o_algntext = H_GET_16 (abfd, aouthdr_ext->o_algntext);
645  aouthdr_int->o_algndata = H_GET_16 (abfd, aouthdr_ext->o_algndata);
646  aouthdr_int->o_modtype  = H_GET_16 (abfd, aouthdr_ext->o_modtype);
647  aouthdr_int->o_cputype  = H_GET_16 (abfd, aouthdr_ext->o_cputype);
648#ifdef XCOFF64
649  aouthdr_int->o_maxstack = H_GET_64 (abfd, aouthdr_ext->o_maxstack);
650  aouthdr_int->o_maxdata  = H_GET_64 (abfd, aouthdr_ext->o_maxdata);
651#else
652  aouthdr_int->o_maxstack = H_GET_32 (abfd, aouthdr_ext->o_maxstack);
653  aouthdr_int->o_maxdata  = H_GET_32 (abfd, aouthdr_ext->o_maxdata);
654#endif
655#endif
656
657#ifdef MIPSECOFF
658  aouthdr_int->bss_start  = H_GET_32 (abfd, aouthdr_ext->bss_start);
659  aouthdr_int->gp_value   = H_GET_32 (abfd, aouthdr_ext->gp_value);
660  aouthdr_int->gprmask    = H_GET_32 (abfd, aouthdr_ext->gprmask);
661  aouthdr_int->cprmask[0] = H_GET_32 (abfd, aouthdr_ext->cprmask[0]);
662  aouthdr_int->cprmask[1] = H_GET_32 (abfd, aouthdr_ext->cprmask[1]);
663  aouthdr_int->cprmask[2] = H_GET_32 (abfd, aouthdr_ext->cprmask[2]);
664  aouthdr_int->cprmask[3] = H_GET_32 (abfd, aouthdr_ext->cprmask[3]);
665#endif
666
667#ifdef ALPHAECOFF
668  aouthdr_int->bss_start = H_GET_64 (abfd, aouthdr_ext->bss_start);
669  aouthdr_int->gp_value  = H_GET_64 (abfd, aouthdr_ext->gp_value);
670  aouthdr_int->gprmask   = H_GET_32 (abfd, aouthdr_ext->gprmask);
671  aouthdr_int->fprmask   = H_GET_32 (abfd, aouthdr_ext->fprmask);
672#endif
673}
674
675static unsigned int
676coff_swap_aouthdr_out (bfd * abfd, void * in, void * out)
677{
678  struct internal_aouthdr *aouthdr_in = (struct internal_aouthdr *) in;
679  AOUTHDR *aouthdr_out = (AOUTHDR *) out;
680
681  H_PUT_16 (abfd, aouthdr_in->magic, aouthdr_out->magic);
682  H_PUT_16 (abfd, aouthdr_in->vstamp, aouthdr_out->vstamp);
683  PUT_AOUTHDR_TSIZE (abfd, aouthdr_in->tsize, aouthdr_out->tsize);
684  PUT_AOUTHDR_DSIZE (abfd, aouthdr_in->dsize, aouthdr_out->dsize);
685  PUT_AOUTHDR_BSIZE (abfd, aouthdr_in->bsize, aouthdr_out->bsize);
686  PUT_AOUTHDR_ENTRY (abfd, aouthdr_in->entry, aouthdr_out->entry);
687  PUT_AOUTHDR_TEXT_START (abfd, aouthdr_in->text_start,
688			  aouthdr_out->text_start);
689  PUT_AOUTHDR_DATA_START (abfd, aouthdr_in->data_start,
690			  aouthdr_out->data_start);
691
692#ifdef I960
693  H_PUT_32 (abfd, aouthdr_in->tagentries, aouthdr_out->tagentries);
694#endif
695
696#ifdef RS6000COFF_C
697#ifdef XCOFF64
698  H_PUT_64 (abfd, aouthdr_in->o_toc, aouthdr_out->o_toc);
699#else
700  H_PUT_32 (abfd, aouthdr_in->o_toc, aouthdr_out->o_toc);
701#endif
702  H_PUT_16 (abfd, aouthdr_in->o_snentry, aouthdr_out->o_snentry);
703  H_PUT_16 (abfd, aouthdr_in->o_sntext, aouthdr_out->o_sntext);
704  H_PUT_16 (abfd, aouthdr_in->o_sndata, aouthdr_out->o_sndata);
705  H_PUT_16 (abfd, aouthdr_in->o_sntoc, aouthdr_out->o_sntoc);
706  H_PUT_16 (abfd, aouthdr_in->o_snloader, aouthdr_out->o_snloader);
707  H_PUT_16 (abfd, aouthdr_in->o_snbss, aouthdr_out->o_snbss);
708  H_PUT_16 (abfd, aouthdr_in->o_algntext, aouthdr_out->o_algntext);
709  H_PUT_16 (abfd, aouthdr_in->o_algndata, aouthdr_out->o_algndata);
710  H_PUT_16 (abfd, aouthdr_in->o_modtype, aouthdr_out->o_modtype);
711  H_PUT_16 (abfd, aouthdr_in->o_cputype, aouthdr_out->o_cputype);
712#ifdef XCOFF64
713  H_PUT_64 (abfd, aouthdr_in->o_maxstack, aouthdr_out->o_maxstack);
714  H_PUT_64 (abfd, aouthdr_in->o_maxdata, aouthdr_out->o_maxdata);
715#else
716  H_PUT_32 (abfd, aouthdr_in->o_maxstack, aouthdr_out->o_maxstack);
717  H_PUT_32 (abfd, aouthdr_in->o_maxdata, aouthdr_out->o_maxdata);
718#endif
719  memset (aouthdr_out->o_resv2, 0, sizeof aouthdr_out->o_resv2);
720#ifdef XCOFF64
721  memset (aouthdr_out->o_debugger, 0, sizeof aouthdr_out->o_debugger);
722  memset (aouthdr_out->o_resv3, 0, sizeof aouthdr_out->o_resv3);
723#endif
724#endif
725
726#ifdef MIPSECOFF
727  H_PUT_32 (abfd, aouthdr_in->bss_start, aouthdr_out->bss_start);
728  H_PUT_32 (abfd, aouthdr_in->gp_value, aouthdr_out->gp_value);
729  H_PUT_32 (abfd, aouthdr_in->gprmask, aouthdr_out->gprmask);
730  H_PUT_32 (abfd, aouthdr_in->cprmask[0], aouthdr_out->cprmask[0]);
731  H_PUT_32 (abfd, aouthdr_in->cprmask[1], aouthdr_out->cprmask[1]);
732  H_PUT_32 (abfd, aouthdr_in->cprmask[2], aouthdr_out->cprmask[2]);
733  H_PUT_32 (abfd, aouthdr_in->cprmask[3], aouthdr_out->cprmask[3]);
734#endif
735
736#ifdef ALPHAECOFF
737  /* FIXME: What does bldrev mean?  */
738  H_PUT_16 (abfd, 2, aouthdr_out->bldrev);
739  H_PUT_16 (abfd, 0, aouthdr_out->padding);
740  H_PUT_64 (abfd, aouthdr_in->bss_start, aouthdr_out->bss_start);
741  H_PUT_64 (abfd, aouthdr_in->gp_value, aouthdr_out->gp_value);
742  H_PUT_32 (abfd, aouthdr_in->gprmask, aouthdr_out->gprmask);
743  H_PUT_32 (abfd, aouthdr_in->fprmask, aouthdr_out->fprmask);
744#endif
745
746  return AOUTSZ;
747}
748
749static void
750coff_swap_scnhdr_in (bfd * abfd, void * ext, void * in)
751{
752  SCNHDR *scnhdr_ext = (SCNHDR *) ext;
753  struct internal_scnhdr *scnhdr_int = (struct internal_scnhdr *) in;
754
755#ifdef COFF_ADJUST_SCNHDR_IN_PRE
756  COFF_ADJUST_SCNHDR_IN_PRE (abfd, ext, in);
757#endif
758  memcpy (scnhdr_int->s_name, scnhdr_ext->s_name, sizeof (scnhdr_int->s_name));
759
760  scnhdr_int->s_vaddr = GET_SCNHDR_VADDR (abfd, scnhdr_ext->s_vaddr);
761  scnhdr_int->s_paddr = GET_SCNHDR_PADDR (abfd, scnhdr_ext->s_paddr);
762  scnhdr_int->s_size = GET_SCNHDR_SIZE (abfd, scnhdr_ext->s_size);
763
764  scnhdr_int->s_scnptr = GET_SCNHDR_SCNPTR (abfd, scnhdr_ext->s_scnptr);
765  scnhdr_int->s_relptr = GET_SCNHDR_RELPTR (abfd, scnhdr_ext->s_relptr);
766  scnhdr_int->s_lnnoptr = GET_SCNHDR_LNNOPTR (abfd, scnhdr_ext->s_lnnoptr);
767  scnhdr_int->s_flags = GET_SCNHDR_FLAGS (abfd, scnhdr_ext->s_flags);
768  scnhdr_int->s_nreloc = GET_SCNHDR_NRELOC (abfd, scnhdr_ext->s_nreloc);
769  scnhdr_int->s_nlnno = GET_SCNHDR_NLNNO (abfd, scnhdr_ext->s_nlnno);
770#ifdef I960
771  scnhdr_int->s_align = GET_SCNHDR_ALIGN (abfd, scnhdr_ext->s_align);
772#endif
773#ifdef COFF_ADJUST_SCNHDR_IN_POST
774  COFF_ADJUST_SCNHDR_IN_POST (abfd, ext, in);
775#endif
776}
777
778static unsigned int
779coff_swap_scnhdr_out (bfd * abfd, void * in, void * out)
780{
781  struct internal_scnhdr *scnhdr_int = (struct internal_scnhdr *) in;
782  SCNHDR *scnhdr_ext = (SCNHDR *) out;
783  unsigned int ret = bfd_coff_scnhsz (abfd);
784
785#ifdef COFF_ADJUST_SCNHDR_OUT_PRE
786  COFF_ADJUST_SCNHDR_OUT_PRE (abfd, in, out);
787#endif
788  memcpy (scnhdr_ext->s_name, scnhdr_int->s_name, sizeof (scnhdr_int->s_name));
789
790  PUT_SCNHDR_VADDR (abfd, scnhdr_int->s_vaddr, scnhdr_ext->s_vaddr);
791  PUT_SCNHDR_PADDR (abfd, scnhdr_int->s_paddr, scnhdr_ext->s_paddr);
792  PUT_SCNHDR_SIZE (abfd, scnhdr_int->s_size, scnhdr_ext->s_size);
793  PUT_SCNHDR_SCNPTR (abfd, scnhdr_int->s_scnptr, scnhdr_ext->s_scnptr);
794  PUT_SCNHDR_RELPTR (abfd, scnhdr_int->s_relptr, scnhdr_ext->s_relptr);
795  PUT_SCNHDR_LNNOPTR (abfd, scnhdr_int->s_lnnoptr, scnhdr_ext->s_lnnoptr);
796  PUT_SCNHDR_FLAGS (abfd, scnhdr_int->s_flags, scnhdr_ext->s_flags);
797#if defined(M88)
798  H_PUT_32 (abfd, scnhdr_int->s_nlnno, scnhdr_ext->s_nlnno);
799  H_PUT_32 (abfd, scnhdr_int->s_nreloc, scnhdr_ext->s_nreloc);
800#else
801  if (scnhdr_int->s_nlnno <= MAX_SCNHDR_NLNNO)
802    PUT_SCNHDR_NLNNO (abfd, scnhdr_int->s_nlnno, scnhdr_ext->s_nlnno);
803  else
804    {
805      char buf[sizeof (scnhdr_int->s_name) + 1];
806
807      memcpy (buf, scnhdr_int->s_name, sizeof (scnhdr_int->s_name));
808      buf[sizeof (scnhdr_int->s_name)] = '\0';
809      _bfd_error_handler
810	/* xgettext:c-format */
811	(_("%s: warning: %s: line number overflow: 0x%lx > 0xffff"),
812	 bfd_get_filename (abfd),
813	 buf, scnhdr_int->s_nlnno);
814      PUT_SCNHDR_NLNNO (abfd, 0xffff, scnhdr_ext->s_nlnno);
815    }
816
817  if (scnhdr_int->s_nreloc <= MAX_SCNHDR_NRELOC)
818    PUT_SCNHDR_NRELOC (abfd, scnhdr_int->s_nreloc, scnhdr_ext->s_nreloc);
819  else
820    {
821      char buf[sizeof (scnhdr_int->s_name) + 1];
822
823      memcpy (buf, scnhdr_int->s_name, sizeof (scnhdr_int->s_name));
824      buf[sizeof (scnhdr_int->s_name)] = '\0';
825      /* xgettext:c-format */
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}
843