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