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