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