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