1/* Generic ECOFF swapping routines, for BFD.
2   Copyright 1992, 1993, 1994, 1995, 1996, 2000, 2001, 2002, 2004, 2005
3   Free Software Foundation, Inc.
4   Written by Cygnus Support.
5
6   This file is part of BFD, the Binary File Descriptor library.
7
8   This program is free software; you can redistribute it and/or modify
9   it under the terms of the GNU General Public License as published by
10   the Free Software Foundation; either version 2 of the License, or
11   (at your option) any later version.
12
13   This program is distributed in the hope that it will be useful,
14   but WITHOUT ANY WARRANTY; without even the implied warranty of
15   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16   GNU General Public License for more details.
17
18   You should have received a copy of the GNU General Public License
19   along with this program; if not, write to the Free Software
20   Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.  */
21
22/* NOTE: This is a header file, but it contains executable routines.
23   This is done this way because these routines are substantially
24   similar, but are not identical, for all ECOFF targets.
25
26   These are routines to swap the ECOFF symbolic information in and
27   out.  The routines are defined statically.  You can set breakpoints
28   on them in gdb by naming the including source file; e.g.,
29   'coff-mips.c':ecoff_swap_hdr_in.
30
31   Before including this header file, one of ECOFF_32, ECOFF_64,
32   ECOFF_SIGNED_32 or ECOFF_SIGNED_64 must be defined.  These are
33   checked when swapping information that depends upon the target
34   size.  This code works for 32 bit and 64 bit ECOFF, but may need to
35   be generalized in the future.
36
37   Some header file which defines the external forms of these
38   structures must also be included before including this header file.
39   Currently this is either coff/mips.h or coff/alpha.h.
40
41   If the symbol TEST is defined when this file is compiled, a
42   comparison is made to ensure that, in fact, the output is
43   bit-for-bit the same as the input.  Of course, this symbol should
44   only be defined when deliberately testing the code on a machine
45   with the proper byte sex and such.  */
46
47#ifdef ECOFF_32
48#define ECOFF_GET_OFF H_GET_32
49#define ECOFF_PUT_OFF H_PUT_32
50#endif
51#ifdef ECOFF_64
52#define ECOFF_GET_OFF H_GET_64
53#define ECOFF_PUT_OFF H_PUT_64
54#endif
55#ifdef ECOFF_SIGNED_32
56#define ECOFF_GET_OFF H_GET_S32
57#define ECOFF_PUT_OFF H_PUT_S32
58#endif
59#ifdef ECOFF_SIGNED_64
60#define ECOFF_GET_OFF H_GET_S64
61#define ECOFF_PUT_OFF H_PUT_S64
62#endif
63
64/* ECOFF auxiliary information swapping routines.  These are the same
65   for all ECOFF targets, so they are defined in ecofflink.c.  */
66
67extern void _bfd_ecoff_swap_tir_in
68  (int, const struct tir_ext *, TIR *);
69extern void _bfd_ecoff_swap_tir_out
70  (int, const TIR *, struct tir_ext *);
71extern void _bfd_ecoff_swap_rndx_in
72  (int, const struct rndx_ext *, RNDXR *);
73extern void _bfd_ecoff_swap_rndx_out
74  (int, const RNDXR *, struct rndx_ext *);
75
76/* Prototypes for functions defined in this file.  */
77
78static void ecoff_swap_hdr_in (bfd *, void *, HDRR *);
79static void ecoff_swap_hdr_out (bfd *, const HDRR *, void *);
80static void ecoff_swap_fdr_in (bfd *, void *, FDR *);
81static void ecoff_swap_fdr_out (bfd *, const FDR *, void *);
82static void ecoff_swap_pdr_in (bfd *, void *, PDR *);
83static void ecoff_swap_pdr_out (bfd *, const PDR *, void *);
84static void ecoff_swap_sym_in (bfd *, void *, SYMR *);
85static void ecoff_swap_sym_out (bfd *, const SYMR *, void *);
86static void ecoff_swap_ext_in (bfd *, void *, EXTR *);
87static void ecoff_swap_ext_out (bfd *, const EXTR *, void *);
88static void ecoff_swap_rfd_in (bfd *, void *, RFDT *);
89static void ecoff_swap_rfd_out (bfd *, const RFDT *, void *);
90static void ecoff_swap_opt_in (bfd *, void *, OPTR *);
91static void ecoff_swap_opt_out (bfd *, const OPTR *, void *);
92static void ecoff_swap_dnr_in (bfd *, void *, DNR *);
93static void ecoff_swap_dnr_out (bfd *, const DNR *, void *);
94
95/* Swap in the symbolic header.  */
96
97static void
98ecoff_swap_hdr_in (bfd *abfd, void * ext_copy, HDRR *intern)
99{
100  struct hdr_ext ext[1];
101
102  *ext = *(struct hdr_ext *) ext_copy;
103
104  intern->magic         = H_GET_S16     (abfd, ext->h_magic);
105  intern->vstamp        = H_GET_S16     (abfd, ext->h_vstamp);
106  intern->ilineMax      = H_GET_32      (abfd, ext->h_ilineMax);
107  intern->cbLine        = ECOFF_GET_OFF (abfd, ext->h_cbLine);
108  intern->cbLineOffset  = ECOFF_GET_OFF (abfd, ext->h_cbLineOffset);
109  intern->idnMax        = H_GET_32      (abfd, ext->h_idnMax);
110  intern->cbDnOffset    = ECOFF_GET_OFF (abfd, ext->h_cbDnOffset);
111  intern->ipdMax        = H_GET_32      (abfd, ext->h_ipdMax);
112  intern->cbPdOffset    = ECOFF_GET_OFF (abfd, ext->h_cbPdOffset);
113  intern->isymMax       = H_GET_32      (abfd, ext->h_isymMax);
114  intern->cbSymOffset   = ECOFF_GET_OFF (abfd, ext->h_cbSymOffset);
115  intern->ioptMax       = H_GET_32      (abfd, ext->h_ioptMax);
116  intern->cbOptOffset   = ECOFF_GET_OFF (abfd, ext->h_cbOptOffset);
117  intern->iauxMax       = H_GET_32      (abfd, ext->h_iauxMax);
118  intern->cbAuxOffset   = ECOFF_GET_OFF (abfd, ext->h_cbAuxOffset);
119  intern->issMax        = H_GET_32      (abfd, ext->h_issMax);
120  intern->cbSsOffset    = ECOFF_GET_OFF (abfd, ext->h_cbSsOffset);
121  intern->issExtMax     = H_GET_32      (abfd, ext->h_issExtMax);
122  intern->cbSsExtOffset = ECOFF_GET_OFF (abfd, ext->h_cbSsExtOffset);
123  intern->ifdMax        = H_GET_32      (abfd, ext->h_ifdMax);
124  intern->cbFdOffset    = ECOFF_GET_OFF (abfd, ext->h_cbFdOffset);
125  intern->crfd          = H_GET_32      (abfd, ext->h_crfd);
126  intern->cbRfdOffset   = ECOFF_GET_OFF (abfd, ext->h_cbRfdOffset);
127  intern->iextMax       = H_GET_32      (abfd, ext->h_iextMax);
128  intern->cbExtOffset   = ECOFF_GET_OFF (abfd, ext->h_cbExtOffset);
129
130#ifdef TEST
131  if (memcmp ((char *) ext, (char *) intern, sizeof (*intern)) != 0)
132    abort ();
133#endif
134}
135
136/* Swap out the symbolic header.  */
137
138static void
139ecoff_swap_hdr_out (bfd *abfd, const HDRR *intern_copy, void * ext_ptr)
140{
141  struct hdr_ext *ext = (struct hdr_ext *) ext_ptr;
142  HDRR intern[1];
143
144  *intern = *intern_copy;
145
146  H_PUT_S16     (abfd, intern->magic,         ext->h_magic);
147  H_PUT_S16     (abfd, intern->vstamp,        ext->h_vstamp);
148  H_PUT_32      (abfd, intern->ilineMax,      ext->h_ilineMax);
149  ECOFF_PUT_OFF (abfd, intern->cbLine,        ext->h_cbLine);
150  ECOFF_PUT_OFF (abfd, intern->cbLineOffset,  ext->h_cbLineOffset);
151  H_PUT_32      (abfd, intern->idnMax,        ext->h_idnMax);
152  ECOFF_PUT_OFF (abfd, intern->cbDnOffset,    ext->h_cbDnOffset);
153  H_PUT_32      (abfd, intern->ipdMax,        ext->h_ipdMax);
154  ECOFF_PUT_OFF (abfd, intern->cbPdOffset,    ext->h_cbPdOffset);
155  H_PUT_32      (abfd, intern->isymMax,       ext->h_isymMax);
156  ECOFF_PUT_OFF (abfd, intern->cbSymOffset,   ext->h_cbSymOffset);
157  H_PUT_32      (abfd, intern->ioptMax,       ext->h_ioptMax);
158  ECOFF_PUT_OFF (abfd, intern->cbOptOffset,   ext->h_cbOptOffset);
159  H_PUT_32      (abfd, intern->iauxMax,       ext->h_iauxMax);
160  ECOFF_PUT_OFF (abfd, intern->cbAuxOffset,   ext->h_cbAuxOffset);
161  H_PUT_32      (abfd, intern->issMax,        ext->h_issMax);
162  ECOFF_PUT_OFF (abfd, intern->cbSsOffset,    ext->h_cbSsOffset);
163  H_PUT_32      (abfd, intern->issExtMax,     ext->h_issExtMax);
164  ECOFF_PUT_OFF (abfd, intern->cbSsExtOffset, ext->h_cbSsExtOffset);
165  H_PUT_32      (abfd, intern->ifdMax,        ext->h_ifdMax);
166  ECOFF_PUT_OFF (abfd, intern->cbFdOffset,    ext->h_cbFdOffset);
167  H_PUT_32      (abfd, intern->crfd,          ext->h_crfd);
168  ECOFF_PUT_OFF (abfd, intern->cbRfdOffset,   ext->h_cbRfdOffset);
169  H_PUT_32      (abfd, intern->iextMax,       ext->h_iextMax);
170  ECOFF_PUT_OFF (abfd, intern->cbExtOffset,   ext->h_cbExtOffset);
171
172#ifdef TEST
173  if (memcmp ((char *) ext, (char *) intern, sizeof (*intern)) != 0)
174    abort ();
175#endif
176}
177
178/* Swap in the file descriptor record.  */
179
180static void
181ecoff_swap_fdr_in (bfd *abfd, void * ext_copy, FDR *intern)
182{
183  struct fdr_ext ext[1];
184
185  *ext = *(struct fdr_ext *) ext_copy;
186
187  intern->adr           = ECOFF_GET_OFF (abfd, ext->f_adr);
188  intern->rss           = H_GET_32 (abfd, ext->f_rss);
189#if defined (ECOFF_64) || defined (ECOFF_SIGNED_64)
190  if (intern->rss == (signed long) 0xffffffff)
191    intern->rss = -1;
192#endif
193  intern->issBase       = H_GET_32 (abfd, ext->f_issBase);
194  intern->cbSs          = ECOFF_GET_OFF (abfd, ext->f_cbSs);
195  intern->isymBase      = H_GET_32 (abfd, ext->f_isymBase);
196  intern->csym          = H_GET_32 (abfd, ext->f_csym);
197  intern->ilineBase     = H_GET_32 (abfd, ext->f_ilineBase);
198  intern->cline         = H_GET_32 (abfd, ext->f_cline);
199  intern->ioptBase      = H_GET_32 (abfd, ext->f_ioptBase);
200  intern->copt          = H_GET_32 (abfd, ext->f_copt);
201#if defined (ECOFF_32) || defined (ECOFF_SIGNED_32)
202  intern->ipdFirst      = H_GET_16 (abfd, ext->f_ipdFirst);
203  intern->cpd           = H_GET_16 (abfd, ext->f_cpd);
204#endif
205#if defined (ECOFF_64) || defined (ECOFF_SIGNED_64)
206  intern->ipdFirst      = H_GET_32 (abfd, ext->f_ipdFirst);
207  intern->cpd           = H_GET_32 (abfd, ext->f_cpd);
208#endif
209  intern->iauxBase      = H_GET_32 (abfd, ext->f_iauxBase);
210  intern->caux          = H_GET_32 (abfd, ext->f_caux);
211  intern->rfdBase       = H_GET_32 (abfd, ext->f_rfdBase);
212  intern->crfd          = H_GET_32 (abfd, ext->f_crfd);
213
214  /* Now the fun stuff...  */
215  if (bfd_header_big_endian (abfd))
216    {
217      intern->lang       = ((ext->f_bits1[0] & FDR_BITS1_LANG_BIG)
218			    >> FDR_BITS1_LANG_SH_BIG);
219      intern->fMerge     = 0 != (ext->f_bits1[0] & FDR_BITS1_FMERGE_BIG);
220      intern->fReadin    = 0 != (ext->f_bits1[0] & FDR_BITS1_FREADIN_BIG);
221      intern->fBigendian = 0 != (ext->f_bits1[0] & FDR_BITS1_FBIGENDIAN_BIG);
222      intern->glevel     = ((ext->f_bits2[0] & FDR_BITS2_GLEVEL_BIG)
223			    >> FDR_BITS2_GLEVEL_SH_BIG);
224    }
225  else
226    {
227      intern->lang       = ((ext->f_bits1[0] & FDR_BITS1_LANG_LITTLE)
228			    >> FDR_BITS1_LANG_SH_LITTLE);
229      intern->fMerge     = 0 != (ext->f_bits1[0] & FDR_BITS1_FMERGE_LITTLE);
230      intern->fReadin    = 0 != (ext->f_bits1[0] & FDR_BITS1_FREADIN_LITTLE);
231      intern->fBigendian = 0 != (ext->f_bits1[0] & FDR_BITS1_FBIGENDIAN_LITTLE);
232      intern->glevel     = ((ext->f_bits2[0] & FDR_BITS2_GLEVEL_LITTLE)
233			    >> FDR_BITS2_GLEVEL_SH_LITTLE);
234    }
235  intern->reserved = 0;
236
237  intern->cbLineOffset  = ECOFF_GET_OFF (abfd, ext->f_cbLineOffset);
238  intern->cbLine        = ECOFF_GET_OFF (abfd, ext->f_cbLine);
239
240#ifdef TEST
241  if (memcmp ((char *) ext, (char *) intern, sizeof (*intern)) != 0)
242    abort ();
243#endif
244}
245
246/* Swap out the file descriptor record.  */
247
248static void
249ecoff_swap_fdr_out (bfd *abfd, const FDR *intern_copy, void * ext_ptr)
250{
251  struct fdr_ext *ext = (struct fdr_ext *) ext_ptr;
252  FDR intern[1];
253
254  /* Make it reasonable to do in-place.  */
255  *intern = *intern_copy;
256
257  ECOFF_PUT_OFF (abfd, intern->adr,       ext->f_adr);
258  H_PUT_32      (abfd, intern->rss,       ext->f_rss);
259  H_PUT_32      (abfd, intern->issBase,   ext->f_issBase);
260  ECOFF_PUT_OFF (abfd, intern->cbSs,      ext->f_cbSs);
261  H_PUT_32      (abfd, intern->isymBase,  ext->f_isymBase);
262  H_PUT_32      (abfd, intern->csym,      ext->f_csym);
263  H_PUT_32      (abfd, intern->ilineBase, ext->f_ilineBase);
264  H_PUT_32      (abfd, intern->cline,     ext->f_cline);
265  H_PUT_32      (abfd, intern->ioptBase,  ext->f_ioptBase);
266  H_PUT_32      (abfd, intern->copt,      ext->f_copt);
267#if defined (ECOFF_32) || defined (ECOFF_SIGNED_32)
268  H_PUT_16      (abfd, intern->ipdFirst,  ext->f_ipdFirst);
269  H_PUT_16      (abfd, intern->cpd,       ext->f_cpd);
270#endif
271#if defined (ECOFF_64) || defined (ECOFF_SIGNED_64)
272  H_PUT_32      (abfd, intern->ipdFirst,  ext->f_ipdFirst);
273  H_PUT_32      (abfd, intern->cpd,       ext->f_cpd);
274#endif
275  H_PUT_32      (abfd, intern->iauxBase,  ext->f_iauxBase);
276  H_PUT_32      (abfd, intern->caux,      ext->f_caux);
277  H_PUT_32      (abfd, intern->rfdBase,   ext->f_rfdBase);
278  H_PUT_32      (abfd, intern->crfd,      ext->f_crfd);
279
280  /* Now the fun stuff...  */
281  if (bfd_header_big_endian (abfd))
282    {
283      ext->f_bits1[0] = (((intern->lang << FDR_BITS1_LANG_SH_BIG)
284			  & FDR_BITS1_LANG_BIG)
285			 | (intern->fMerge ? FDR_BITS1_FMERGE_BIG : 0)
286			 | (intern->fReadin ? FDR_BITS1_FREADIN_BIG : 0)
287			 | (intern->fBigendian ? FDR_BITS1_FBIGENDIAN_BIG : 0));
288      ext->f_bits2[0] = ((intern->glevel << FDR_BITS2_GLEVEL_SH_BIG)
289			 & FDR_BITS2_GLEVEL_BIG);
290      ext->f_bits2[1] = 0;
291      ext->f_bits2[2] = 0;
292    }
293  else
294    {
295      ext->f_bits1[0] = (((intern->lang << FDR_BITS1_LANG_SH_LITTLE)
296			  & FDR_BITS1_LANG_LITTLE)
297			 | (intern->fMerge ? FDR_BITS1_FMERGE_LITTLE : 0)
298			 | (intern->fReadin ? FDR_BITS1_FREADIN_LITTLE : 0)
299			 | (intern->fBigendian ? FDR_BITS1_FBIGENDIAN_LITTLE : 0));
300      ext->f_bits2[0] = ((intern->glevel << FDR_BITS2_GLEVEL_SH_LITTLE)
301			 & FDR_BITS2_GLEVEL_LITTLE);
302      ext->f_bits2[1] = 0;
303      ext->f_bits2[2] = 0;
304    }
305
306  ECOFF_PUT_OFF (abfd, intern->cbLineOffset, ext->f_cbLineOffset);
307  ECOFF_PUT_OFF (abfd, intern->cbLine, ext->f_cbLine);
308
309#ifdef TEST
310  if (memcmp ((char *) ext, (char *) intern, sizeof (*intern)) != 0)
311    abort ();
312#endif
313}
314
315/* Swap in the procedure descriptor record.  */
316
317static void
318ecoff_swap_pdr_in (bfd *abfd, void * ext_copy, PDR *intern)
319{
320  struct pdr_ext ext[1];
321
322  *ext = *(struct pdr_ext *) ext_copy;
323
324  memset ((void *) intern, 0, sizeof (*intern));
325
326  intern->adr           = ECOFF_GET_OFF (abfd, ext->p_adr);
327  intern->isym          = H_GET_32 (abfd, ext->p_isym);
328  intern->iline         = H_GET_32 (abfd, ext->p_iline);
329  intern->regmask       = H_GET_32 (abfd, ext->p_regmask);
330  intern->regoffset     = H_GET_S32 (abfd, ext->p_regoffset);
331  intern->iopt          = H_GET_S32 (abfd, ext->p_iopt);
332  intern->fregmask      = H_GET_32 (abfd, ext->p_fregmask);
333  intern->fregoffset    = H_GET_S32 (abfd, ext->p_fregoffset);
334  intern->frameoffset   = H_GET_S32 (abfd, ext->p_frameoffset);
335  intern->framereg      = H_GET_16 (abfd, ext->p_framereg);
336  intern->pcreg         = H_GET_16 (abfd, ext->p_pcreg);
337  intern->lnLow         = H_GET_32 (abfd, ext->p_lnLow);
338  intern->lnHigh        = H_GET_32 (abfd, ext->p_lnHigh);
339  intern->cbLineOffset  = ECOFF_GET_OFF (abfd, ext->p_cbLineOffset);
340
341#if defined (ECOFF_64) || defined (ECOFF_SIGNED_64)
342  if (intern->isym == (signed long) 0xffffffff)
343    intern->isym = -1;
344  if (intern->iline == (signed long) 0xffffffff)
345    intern->iline = -1;
346
347  intern->gp_prologue = H_GET_8 (abfd, ext->p_gp_prologue);
348  if (bfd_header_big_endian (abfd))
349    {
350      intern->gp_used = 0 != (ext->p_bits1[0] & PDR_BITS1_GP_USED_BIG);
351      intern->reg_frame = 0 != (ext->p_bits1[0] & PDR_BITS1_REG_FRAME_BIG);
352      intern->prof = 0 != (ext->p_bits1[0] & PDR_BITS1_PROF_BIG);
353      intern->reserved = (((ext->p_bits1[0] & PDR_BITS1_RESERVED_BIG)
354			   << PDR_BITS1_RESERVED_SH_LEFT_BIG)
355			  | ((ext->p_bits2[0] & PDR_BITS2_RESERVED_BIG)
356			     >> PDR_BITS2_RESERVED_SH_BIG));
357    }
358  else
359    {
360      intern->gp_used = 0 != (ext->p_bits1[0] & PDR_BITS1_GP_USED_LITTLE);
361      intern->reg_frame = 0 != (ext->p_bits1[0] & PDR_BITS1_REG_FRAME_LITTLE);
362      intern->prof = 0 != (ext->p_bits1[0] & PDR_BITS1_PROF_LITTLE);
363      intern->reserved = (((ext->p_bits1[0] & PDR_BITS1_RESERVED_LITTLE)
364			   >> PDR_BITS1_RESERVED_SH_LITTLE)
365			  | ((ext->p_bits2[0] & PDR_BITS2_RESERVED_LITTLE)
366			     << PDR_BITS2_RESERVED_SH_LEFT_LITTLE));
367    }
368  intern->localoff = H_GET_8 (abfd, ext->p_localoff);
369#endif
370
371#ifdef TEST
372  if (memcmp ((char *) ext, (char *) intern, sizeof (*intern)) != 0)
373    abort ();
374#endif
375}
376
377/* Swap out the procedure descriptor record.  */
378
379static void
380ecoff_swap_pdr_out (bfd *abfd, const PDR *intern_copy, void * ext_ptr)
381{
382  struct pdr_ext *ext = (struct pdr_ext *) ext_ptr;
383  PDR intern[1];
384
385  /* Make it reasonable to do in-place.  */
386  *intern = *intern_copy;
387
388  ECOFF_PUT_OFF (abfd, intern->adr,          ext->p_adr);
389  H_PUT_32      (abfd, intern->isym,         ext->p_isym);
390  H_PUT_32      (abfd, intern->iline,        ext->p_iline);
391  H_PUT_32      (abfd, intern->regmask,      ext->p_regmask);
392  H_PUT_32      (abfd, intern->regoffset,    ext->p_regoffset);
393  H_PUT_32      (abfd, intern->iopt,         ext->p_iopt);
394  H_PUT_32      (abfd, intern->fregmask,     ext->p_fregmask);
395  H_PUT_32      (abfd, intern->fregoffset,   ext->p_fregoffset);
396  H_PUT_32      (abfd, intern->frameoffset,  ext->p_frameoffset);
397  H_PUT_16      (abfd, intern->framereg,     ext->p_framereg);
398  H_PUT_16      (abfd, intern->pcreg,        ext->p_pcreg);
399  H_PUT_32      (abfd, intern->lnLow,        ext->p_lnLow);
400  H_PUT_32      (abfd, intern->lnHigh,       ext->p_lnHigh);
401  ECOFF_PUT_OFF (abfd, intern->cbLineOffset, ext->p_cbLineOffset);
402
403#if defined (ECOFF_64) || defined (ECOFF_SIGNED_64)
404  H_PUT_8       (abfd, intern->gp_prologue,  ext->p_gp_prologue);
405
406  if (bfd_header_big_endian (abfd))
407    {
408      ext->p_bits1[0] = ((intern->gp_used ? PDR_BITS1_GP_USED_BIG : 0)
409			 | (intern->reg_frame ? PDR_BITS1_REG_FRAME_BIG : 0)
410			 | (intern->prof ? PDR_BITS1_PROF_BIG : 0)
411			 | ((intern->reserved
412			     >> PDR_BITS1_RESERVED_SH_LEFT_BIG)
413			    & PDR_BITS1_RESERVED_BIG));
414      ext->p_bits2[0] = ((intern->reserved << PDR_BITS2_RESERVED_SH_BIG)
415			 & PDR_BITS2_RESERVED_BIG);
416    }
417  else
418    {
419      ext->p_bits1[0] = ((intern->gp_used ? PDR_BITS1_GP_USED_LITTLE : 0)
420			 | (intern->reg_frame ? PDR_BITS1_REG_FRAME_LITTLE : 0)
421			 | (intern->prof ? PDR_BITS1_PROF_LITTLE : 0)
422			 | ((intern->reserved << PDR_BITS1_RESERVED_SH_LITTLE)
423			    & PDR_BITS1_RESERVED_LITTLE));
424      ext->p_bits2[0] = ((intern->reserved >>
425			  PDR_BITS2_RESERVED_SH_LEFT_LITTLE)
426			 & PDR_BITS2_RESERVED_LITTLE);
427    }
428  H_PUT_8 (abfd, intern->localoff, ext->p_localoff);
429#endif
430
431#ifdef TEST
432  if (memcmp ((char *) ext, (char *) intern, sizeof (*intern)) != 0)
433    abort ();
434#endif
435}
436
437/* Swap in a symbol record.  */
438
439static void
440ecoff_swap_sym_in (bfd *abfd, void * ext_copy, SYMR *intern)
441{
442  struct sym_ext ext[1];
443
444  *ext = *(struct sym_ext *) ext_copy;
445
446  intern->iss           = H_GET_32 (abfd, ext->s_iss);
447  intern->value         = ECOFF_GET_OFF (abfd, ext->s_value);
448
449#if defined (ECOFF_64) || defined (ECOFF_SIGNED_64)
450  if (intern->iss == (signed long) 0xffffffff)
451    intern->iss = -1;
452#endif
453
454  /* Now the fun stuff...  */
455  if (bfd_header_big_endian (abfd))
456    {
457      intern->st          =  (ext->s_bits1[0] & SYM_BITS1_ST_BIG)
458					     >> SYM_BITS1_ST_SH_BIG;
459      intern->sc          = ((ext->s_bits1[0] & SYM_BITS1_SC_BIG)
460					     << SYM_BITS1_SC_SH_LEFT_BIG)
461			  | ((ext->s_bits2[0] & SYM_BITS2_SC_BIG)
462					     >> SYM_BITS2_SC_SH_BIG);
463      intern->reserved    = 0 != (ext->s_bits2[0] & SYM_BITS2_RESERVED_BIG);
464      intern->index       = ((ext->s_bits2[0] & SYM_BITS2_INDEX_BIG)
465					     << SYM_BITS2_INDEX_SH_LEFT_BIG)
466			  | (ext->s_bits3[0] << SYM_BITS3_INDEX_SH_LEFT_BIG)
467			  | (ext->s_bits4[0] << SYM_BITS4_INDEX_SH_LEFT_BIG);
468    }
469  else
470    {
471      intern->st          =  (ext->s_bits1[0] & SYM_BITS1_ST_LITTLE)
472					     >> SYM_BITS1_ST_SH_LITTLE;
473      intern->sc          = ((ext->s_bits1[0] & SYM_BITS1_SC_LITTLE)
474					     >> SYM_BITS1_SC_SH_LITTLE)
475			  | ((ext->s_bits2[0] & SYM_BITS2_SC_LITTLE)
476					     << SYM_BITS2_SC_SH_LEFT_LITTLE);
477      intern->reserved    = 0 != (ext->s_bits2[0] & SYM_BITS2_RESERVED_LITTLE);
478      intern->index       = ((ext->s_bits2[0] & SYM_BITS2_INDEX_LITTLE)
479					     >> SYM_BITS2_INDEX_SH_LITTLE)
480			  | (ext->s_bits3[0] << SYM_BITS3_INDEX_SH_LEFT_LITTLE)
481			  | ((unsigned int) ext->s_bits4[0]
482			     << SYM_BITS4_INDEX_SH_LEFT_LITTLE);
483    }
484
485#ifdef TEST
486  if (memcmp ((char *) ext, (char *) intern, sizeof (*intern)) != 0)
487    abort ();
488#endif
489}
490
491/* Swap out a symbol record.  */
492
493static void
494ecoff_swap_sym_out (bfd *abfd, const SYMR *intern_copy, void * ext_ptr)
495{
496  struct sym_ext *ext = (struct sym_ext *) ext_ptr;
497  SYMR intern[1];
498
499  /* Make it reasonable to do in-place.  */
500  *intern = *intern_copy;
501
502  H_PUT_32 (abfd, intern->iss, ext->s_iss);
503  ECOFF_PUT_OFF (abfd, intern->value, ext->s_value);
504
505  /* Now the fun stuff...  */
506  if (bfd_header_big_endian (abfd))
507    {
508      ext->s_bits1[0] = (((intern->st << SYM_BITS1_ST_SH_BIG)
509			  & SYM_BITS1_ST_BIG)
510			 | ((intern->sc >> SYM_BITS1_SC_SH_LEFT_BIG)
511			    & SYM_BITS1_SC_BIG));
512      ext->s_bits2[0] = (((intern->sc << SYM_BITS2_SC_SH_BIG)
513			  & SYM_BITS2_SC_BIG)
514			 | (intern->reserved ? SYM_BITS2_RESERVED_BIG : 0)
515			 | ((intern->index >> SYM_BITS2_INDEX_SH_LEFT_BIG)
516			    & SYM_BITS2_INDEX_BIG));
517      ext->s_bits3[0] = (intern->index >> SYM_BITS3_INDEX_SH_LEFT_BIG) & 0xff;
518      ext->s_bits4[0] = (intern->index >> SYM_BITS4_INDEX_SH_LEFT_BIG) & 0xff;
519    }
520  else
521    {
522      ext->s_bits1[0] = (((intern->st << SYM_BITS1_ST_SH_LITTLE)
523			  & SYM_BITS1_ST_LITTLE)
524			 | ((intern->sc << SYM_BITS1_SC_SH_LITTLE)
525			    & SYM_BITS1_SC_LITTLE));
526      ext->s_bits2[0] = (((intern->sc >> SYM_BITS2_SC_SH_LEFT_LITTLE)
527			  & SYM_BITS2_SC_LITTLE)
528			 | (intern->reserved ? SYM_BITS2_RESERVED_LITTLE : 0)
529			 | ((intern->index << SYM_BITS2_INDEX_SH_LITTLE)
530			    & SYM_BITS2_INDEX_LITTLE));
531      ext->s_bits3[0] = (intern->index >> SYM_BITS3_INDEX_SH_LEFT_LITTLE) & 0xff;
532      ext->s_bits4[0] = (intern->index >> SYM_BITS4_INDEX_SH_LEFT_LITTLE) & 0xff;
533    }
534
535#ifdef TEST
536  if (memcmp ((char *) ext, (char *) intern, sizeof (*intern)) != 0)
537    abort ();
538#endif
539}
540
541/* Swap in an external symbol record.  */
542
543static void
544ecoff_swap_ext_in (bfd *abfd, void * ext_copy, EXTR *intern)
545{
546  struct ext_ext ext[1];
547
548  *ext = *(struct ext_ext *) ext_copy;
549
550  /* Now the fun stuff...  */
551  if (bfd_header_big_endian (abfd))
552    {
553      intern->jmptbl      = 0 != (ext->es_bits1[0] & EXT_BITS1_JMPTBL_BIG);
554      intern->cobol_main  = 0 != (ext->es_bits1[0] & EXT_BITS1_COBOL_MAIN_BIG);
555      intern->weakext     = 0 != (ext->es_bits1[0] & EXT_BITS1_WEAKEXT_BIG);
556    }
557  else
558    {
559      intern->jmptbl      = 0 != (ext->es_bits1[0] & EXT_BITS1_JMPTBL_LITTLE);
560      intern->cobol_main  = 0 != (ext->es_bits1[0] & EXT_BITS1_COBOL_MAIN_LITTLE);
561      intern->weakext     = 0 != (ext->es_bits1[0] & EXT_BITS1_WEAKEXT_LITTLE);
562    }
563  intern->reserved = 0;
564
565#if defined (ECOFF_32) || defined (ECOFF_SIGNED_32)
566  intern->ifd = H_GET_S16 (abfd, ext->es_ifd);
567#endif
568#if defined (ECOFF_64) || defined (ECOFF_SIGNED_64)
569  intern->ifd = H_GET_S32 (abfd, ext->es_ifd);
570#endif
571
572  ecoff_swap_sym_in (abfd, &ext->es_asym, &intern->asym);
573
574#ifdef TEST
575  if (memcmp ((char *) ext, (char *) intern, sizeof (*intern)) != 0)
576    abort ();
577#endif
578}
579
580/* Swap out an external symbol record.  */
581
582static void
583ecoff_swap_ext_out (bfd *abfd, const EXTR *intern_copy, void * ext_ptr)
584{
585  struct ext_ext *ext = (struct ext_ext *) ext_ptr;
586  EXTR intern[1];
587
588  /* Make it reasonable to do in-place.  */
589  *intern = *intern_copy;
590
591  /* Now the fun stuff...  */
592  if (bfd_header_big_endian (abfd))
593    {
594      ext->es_bits1[0] = ((intern->jmptbl ? EXT_BITS1_JMPTBL_BIG : 0)
595			  | (intern->cobol_main ? EXT_BITS1_COBOL_MAIN_BIG : 0)
596			  | (intern->weakext ? EXT_BITS1_WEAKEXT_BIG : 0));
597      ext->es_bits2[0] = 0;
598#if defined (ECOFF_64) || defined (ECOFF_SIGNED_64)
599      ext->es_bits2[1] = 0;
600      ext->es_bits2[2] = 0;
601#endif
602    }
603  else
604    {
605      ext->es_bits1[0] = ((intern->jmptbl ? EXT_BITS1_JMPTBL_LITTLE : 0)
606			  | (intern->cobol_main ? EXT_BITS1_COBOL_MAIN_LITTLE : 0)
607			  | (intern->weakext ? EXT_BITS1_WEAKEXT_LITTLE : 0));
608      ext->es_bits2[0] = 0;
609#if defined (ECOFF_64) || defined (ECOFF_SIGNED_64)
610      ext->es_bits2[1] = 0;
611      ext->es_bits2[2] = 0;
612#endif
613    }
614
615#if defined (ECOFF_32) || defined (ECOFF_SIGNED_32)
616  H_PUT_S16 (abfd, intern->ifd, ext->es_ifd);
617#endif
618#if defined (ECOFF_64) || defined (ECOFF_SIGNED_64)
619  H_PUT_S32 (abfd, intern->ifd, ext->es_ifd);
620#endif
621
622  ecoff_swap_sym_out (abfd, &intern->asym, &ext->es_asym);
623
624#ifdef TEST
625  if (memcmp ((char *) ext, (char *) intern, sizeof (*intern)) != 0)
626    abort ();
627#endif
628}
629
630/* Swap in a relative file descriptor.  */
631
632static void
633ecoff_swap_rfd_in (bfd *abfd, void * ext_ptr, RFDT *intern)
634{
635  struct rfd_ext *ext = (struct rfd_ext *) ext_ptr;
636
637  *intern = H_GET_32 (abfd, ext->rfd);
638
639#ifdef TEST
640  if (memcmp ((char *) ext, (char *) intern, sizeof (*intern)) != 0)
641    abort ();
642#endif
643}
644
645/* Swap out a relative file descriptor.  */
646
647static void
648ecoff_swap_rfd_out (bfd *abfd, const RFDT *intern, void * ext_ptr)
649{
650  struct rfd_ext *ext = (struct rfd_ext *) ext_ptr;
651
652  H_PUT_32 (abfd, *intern, ext->rfd);
653
654#ifdef TEST
655  if (memcmp ((char *) ext, (char *) intern, sizeof (*intern)) != 0)
656    abort ();
657#endif
658}
659
660/* Swap in an optimization symbol.  */
661
662static void
663ecoff_swap_opt_in (bfd *abfd, void * ext_copy, OPTR * intern)
664{
665  struct opt_ext ext[1];
666
667  *ext = *(struct opt_ext *) ext_copy;
668
669  if (bfd_header_big_endian (abfd))
670    {
671      intern->ot = ext->o_bits1[0];
672      intern->value = (((unsigned int) ext->o_bits2[0]
673			<< OPT_BITS2_VALUE_SH_LEFT_BIG)
674		       | ((unsigned int) ext->o_bits3[0]
675			  << OPT_BITS2_VALUE_SH_LEFT_BIG)
676		       | ((unsigned int) ext->o_bits4[0]
677			  << OPT_BITS2_VALUE_SH_LEFT_BIG));
678    }
679  else
680    {
681      intern->ot = ext->o_bits1[0];
682      intern->value = ((ext->o_bits2[0] << OPT_BITS2_VALUE_SH_LEFT_LITTLE)
683		       | (ext->o_bits3[0] << OPT_BITS2_VALUE_SH_LEFT_LITTLE)
684		       | (ext->o_bits4[0] << OPT_BITS2_VALUE_SH_LEFT_LITTLE));
685    }
686
687  _bfd_ecoff_swap_rndx_in (bfd_header_big_endian (abfd),
688			   &ext->o_rndx, &intern->rndx);
689
690  intern->offset = H_GET_32 (abfd, ext->o_offset);
691
692#ifdef TEST
693  if (memcmp ((char *) ext, (char *) intern, sizeof (*intern)) != 0)
694    abort ();
695#endif
696}
697
698/* Swap out an optimization symbol.  */
699
700static void
701ecoff_swap_opt_out (bfd *abfd, const OPTR *intern_copy, void * ext_ptr)
702{
703  struct opt_ext *ext = (struct opt_ext *) ext_ptr;
704  OPTR intern[1];
705
706  /* Make it reasonable to do in-place.  */
707  *intern = *intern_copy;
708
709  if (bfd_header_big_endian (abfd))
710    {
711      ext->o_bits1[0] = intern->ot;
712      ext->o_bits2[0] = intern->value >> OPT_BITS2_VALUE_SH_LEFT_BIG;
713      ext->o_bits3[0] = intern->value >> OPT_BITS3_VALUE_SH_LEFT_BIG;
714      ext->o_bits4[0] = intern->value >> OPT_BITS4_VALUE_SH_LEFT_BIG;
715    }
716  else
717    {
718      ext->o_bits1[0] = intern->ot;
719      ext->o_bits2[0] = intern->value >> OPT_BITS2_VALUE_SH_LEFT_LITTLE;
720      ext->o_bits3[0] = intern->value >> OPT_BITS3_VALUE_SH_LEFT_LITTLE;
721      ext->o_bits4[0] = intern->value >> OPT_BITS4_VALUE_SH_LEFT_LITTLE;
722    }
723
724  _bfd_ecoff_swap_rndx_out (bfd_header_big_endian (abfd),
725			    &intern->rndx, &ext->o_rndx);
726
727  H_PUT_32 (abfd, intern->value, ext->o_offset);
728
729#ifdef TEST
730  if (memcmp ((char *) ext, (char *) intern, sizeof (*intern)) != 0)
731    abort ();
732#endif
733}
734
735/* Swap in a dense number.  */
736
737static void
738ecoff_swap_dnr_in (bfd *abfd, void * ext_copy, DNR *intern)
739{
740  struct dnr_ext ext[1];
741
742  *ext = *(struct dnr_ext *) ext_copy;
743
744  intern->rfd = H_GET_32 (abfd, ext->d_rfd);
745  intern->index = H_GET_32 (abfd, ext->d_index);
746
747#ifdef TEST
748  if (memcmp ((char *) ext, (char *) intern, sizeof (*intern)) != 0)
749    abort ();
750#endif
751}
752
753/* Swap out a dense number.  */
754
755static void
756ecoff_swap_dnr_out (bfd *abfd, const DNR *intern_copy, void * ext_ptr)
757{
758  struct dnr_ext *ext = (struct dnr_ext *) ext_ptr;
759  DNR intern[1];
760
761  /* Make it reasonable to do in-place.  */
762  *intern = *intern_copy;
763
764  H_PUT_32 (abfd, intern->rfd, ext->d_rfd);
765  H_PUT_32 (abfd, intern->index, ext->d_index);
766
767#ifdef TEST
768  if (memcmp ((char *) ext, (char *) intern, sizeof (*intern)) != 0)
769    abort ();
770#endif
771}
772