1/* Generic ECOFF swapping routines, for BFD.
2   Copyright 1992, 1993, 1994, 1995, 1996, 2000, 2001, 2002
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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, 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  PARAMS ((int, const struct tir_ext *, TIR *));
69extern void _bfd_ecoff_swap_tir_out
70  PARAMS ((int, const TIR *, struct tir_ext *));
71extern void _bfd_ecoff_swap_rndx_in
72  PARAMS ((int, const struct rndx_ext *, RNDXR *));
73extern void _bfd_ecoff_swap_rndx_out
74  PARAMS ((int, const RNDXR *, struct rndx_ext *));
75
76/* Prototypes for functions defined in this file.  */
77
78static void ecoff_swap_hdr_in PARAMS ((bfd *, PTR, HDRR *));
79static void ecoff_swap_hdr_out PARAMS ((bfd *, const HDRR *, PTR));
80static void ecoff_swap_fdr_in PARAMS ((bfd *, PTR, FDR *));
81static void ecoff_swap_fdr_out PARAMS ((bfd *, const FDR *, PTR));
82static void ecoff_swap_pdr_in PARAMS ((bfd *, PTR, PDR *));
83static void ecoff_swap_pdr_out PARAMS ((bfd *, const PDR *, PTR));
84static void ecoff_swap_sym_in PARAMS ((bfd *, PTR, SYMR *));
85static void ecoff_swap_sym_out PARAMS ((bfd *, const SYMR *, PTR));
86static void ecoff_swap_ext_in PARAMS ((bfd *, PTR, EXTR *));
87static void ecoff_swap_ext_out PARAMS ((bfd *, const EXTR *, PTR));
88static void ecoff_swap_rfd_in PARAMS ((bfd *, PTR, RFDT *));
89static void ecoff_swap_rfd_out PARAMS ((bfd *, const RFDT *, PTR));
90static void ecoff_swap_opt_in PARAMS ((bfd *, PTR, OPTR *));
91static void ecoff_swap_opt_out PARAMS ((bfd *, const OPTR *, PTR));
92static void ecoff_swap_dnr_in PARAMS ((bfd *, PTR, DNR *));
93static void ecoff_swap_dnr_out PARAMS ((bfd *, const DNR *, PTR));
94
95/* Swap in the symbolic header.  */
96
97static void
98ecoff_swap_hdr_in (abfd, ext_copy, intern)
99     bfd *abfd;
100     PTR ext_copy;
101     HDRR *intern;
102{
103  struct hdr_ext ext[1];
104
105  *ext = *(struct hdr_ext *) ext_copy;
106
107  intern->magic         = H_GET_S16     (abfd, ext->h_magic);
108  intern->vstamp        = H_GET_S16     (abfd, ext->h_vstamp);
109  intern->ilineMax      = H_GET_32      (abfd, ext->h_ilineMax);
110  intern->cbLine        = ECOFF_GET_OFF (abfd, ext->h_cbLine);
111  intern->cbLineOffset  = ECOFF_GET_OFF (abfd, ext->h_cbLineOffset);
112  intern->idnMax        = H_GET_32      (abfd, ext->h_idnMax);
113  intern->cbDnOffset    = ECOFF_GET_OFF (abfd, ext->h_cbDnOffset);
114  intern->ipdMax        = H_GET_32      (abfd, ext->h_ipdMax);
115  intern->cbPdOffset    = ECOFF_GET_OFF (abfd, ext->h_cbPdOffset);
116  intern->isymMax       = H_GET_32      (abfd, ext->h_isymMax);
117  intern->cbSymOffset   = ECOFF_GET_OFF (abfd, ext->h_cbSymOffset);
118  intern->ioptMax       = H_GET_32      (abfd, ext->h_ioptMax);
119  intern->cbOptOffset   = ECOFF_GET_OFF (abfd, ext->h_cbOptOffset);
120  intern->iauxMax       = H_GET_32      (abfd, ext->h_iauxMax);
121  intern->cbAuxOffset   = ECOFF_GET_OFF (abfd, ext->h_cbAuxOffset);
122  intern->issMax        = H_GET_32      (abfd, ext->h_issMax);
123  intern->cbSsOffset    = ECOFF_GET_OFF (abfd, ext->h_cbSsOffset);
124  intern->issExtMax     = H_GET_32      (abfd, ext->h_issExtMax);
125  intern->cbSsExtOffset = ECOFF_GET_OFF (abfd, ext->h_cbSsExtOffset);
126  intern->ifdMax        = H_GET_32      (abfd, ext->h_ifdMax);
127  intern->cbFdOffset    = ECOFF_GET_OFF (abfd, ext->h_cbFdOffset);
128  intern->crfd          = H_GET_32      (abfd, ext->h_crfd);
129  intern->cbRfdOffset   = ECOFF_GET_OFF (abfd, ext->h_cbRfdOffset);
130  intern->iextMax       = H_GET_32      (abfd, ext->h_iextMax);
131  intern->cbExtOffset   = ECOFF_GET_OFF (abfd, ext->h_cbExtOffset);
132
133#ifdef TEST
134  if (memcmp ((char *)ext, (char *)intern, sizeof (*intern)) != 0)
135    abort ();
136#endif
137}
138
139/* Swap out the symbolic header.  */
140
141static void
142ecoff_swap_hdr_out (abfd, intern_copy, ext_ptr)
143     bfd *abfd;
144     const HDRR *intern_copy;
145     PTR ext_ptr;
146{
147  struct hdr_ext *ext = (struct hdr_ext *) ext_ptr;
148  HDRR intern[1];
149
150  *intern = *intern_copy;
151
152  H_PUT_S16     (abfd, intern->magic,         ext->h_magic);
153  H_PUT_S16     (abfd, intern->vstamp,        ext->h_vstamp);
154  H_PUT_32      (abfd, intern->ilineMax,      ext->h_ilineMax);
155  ECOFF_PUT_OFF (abfd, intern->cbLine,        ext->h_cbLine);
156  ECOFF_PUT_OFF (abfd, intern->cbLineOffset,  ext->h_cbLineOffset);
157  H_PUT_32      (abfd, intern->idnMax,        ext->h_idnMax);
158  ECOFF_PUT_OFF (abfd, intern->cbDnOffset,    ext->h_cbDnOffset);
159  H_PUT_32      (abfd, intern->ipdMax,        ext->h_ipdMax);
160  ECOFF_PUT_OFF (abfd, intern->cbPdOffset,    ext->h_cbPdOffset);
161  H_PUT_32      (abfd, intern->isymMax,       ext->h_isymMax);
162  ECOFF_PUT_OFF (abfd, intern->cbSymOffset,   ext->h_cbSymOffset);
163  H_PUT_32      (abfd, intern->ioptMax,       ext->h_ioptMax);
164  ECOFF_PUT_OFF (abfd, intern->cbOptOffset,   ext->h_cbOptOffset);
165  H_PUT_32      (abfd, intern->iauxMax,       ext->h_iauxMax);
166  ECOFF_PUT_OFF (abfd, intern->cbAuxOffset,   ext->h_cbAuxOffset);
167  H_PUT_32      (abfd, intern->issMax,        ext->h_issMax);
168  ECOFF_PUT_OFF (abfd, intern->cbSsOffset,    ext->h_cbSsOffset);
169  H_PUT_32      (abfd, intern->issExtMax,     ext->h_issExtMax);
170  ECOFF_PUT_OFF (abfd, intern->cbSsExtOffset, ext->h_cbSsExtOffset);
171  H_PUT_32      (abfd, intern->ifdMax,        ext->h_ifdMax);
172  ECOFF_PUT_OFF (abfd, intern->cbFdOffset,    ext->h_cbFdOffset);
173  H_PUT_32      (abfd, intern->crfd,          ext->h_crfd);
174  ECOFF_PUT_OFF (abfd, intern->cbRfdOffset,   ext->h_cbRfdOffset);
175  H_PUT_32      (abfd, intern->iextMax,       ext->h_iextMax);
176  ECOFF_PUT_OFF (abfd, intern->cbExtOffset,   ext->h_cbExtOffset);
177
178#ifdef TEST
179  if (memcmp ((char *) ext, (char *) intern, sizeof (*intern)) != 0)
180    abort ();
181#endif
182}
183
184/* Swap in the file descriptor record.  */
185
186static void
187ecoff_swap_fdr_in (abfd, ext_copy, intern)
188     bfd *abfd;
189     PTR ext_copy;
190     FDR *intern;
191{
192  struct fdr_ext ext[1];
193
194  *ext = *(struct fdr_ext *) ext_copy;
195
196  intern->adr           = ECOFF_GET_OFF (abfd, ext->f_adr);
197  intern->rss           = H_GET_32 (abfd, ext->f_rss);
198#if defined (ECOFF_64) || defined (ECOFF_SIGNED_64)
199  if (intern->rss == (signed long) 0xffffffff)
200    intern->rss = -1;
201#endif
202  intern->issBase       = H_GET_32 (abfd, ext->f_issBase);
203  intern->cbSs          = ECOFF_GET_OFF (abfd, ext->f_cbSs);
204  intern->isymBase      = H_GET_32 (abfd, ext->f_isymBase);
205  intern->csym          = H_GET_32 (abfd, ext->f_csym);
206  intern->ilineBase     = H_GET_32 (abfd, ext->f_ilineBase);
207  intern->cline         = H_GET_32 (abfd, ext->f_cline);
208  intern->ioptBase      = H_GET_32 (abfd, ext->f_ioptBase);
209  intern->copt          = H_GET_32 (abfd, ext->f_copt);
210#if defined (ECOFF_32) || defined (ECOFF_SIGNED_32)
211  intern->ipdFirst      = H_GET_16 (abfd, ext->f_ipdFirst);
212  intern->cpd           = H_GET_16 (abfd, ext->f_cpd);
213#endif
214#if defined (ECOFF_64) || defined (ECOFF_SIGNED_64)
215  intern->ipdFirst      = H_GET_32 (abfd, ext->f_ipdFirst);
216  intern->cpd           = H_GET_32 (abfd, ext->f_cpd);
217#endif
218  intern->iauxBase      = H_GET_32 (abfd, ext->f_iauxBase);
219  intern->caux          = H_GET_32 (abfd, ext->f_caux);
220  intern->rfdBase       = H_GET_32 (abfd, ext->f_rfdBase);
221  intern->crfd          = H_GET_32 (abfd, ext->f_crfd);
222
223  /* Now the fun stuff...  */
224  if (bfd_header_big_endian (abfd))
225    {
226      intern->lang       = ((ext->f_bits1[0] & FDR_BITS1_LANG_BIG)
227			    >> FDR_BITS1_LANG_SH_BIG);
228      intern->fMerge     = 0 != (ext->f_bits1[0] & FDR_BITS1_FMERGE_BIG);
229      intern->fReadin    = 0 != (ext->f_bits1[0] & FDR_BITS1_FREADIN_BIG);
230      intern->fBigendian = 0 != (ext->f_bits1[0] & FDR_BITS1_FBIGENDIAN_BIG);
231      intern->glevel     = ((ext->f_bits2[0] & FDR_BITS2_GLEVEL_BIG)
232			    >> FDR_BITS2_GLEVEL_SH_BIG);
233    }
234  else
235    {
236      intern->lang       = ((ext->f_bits1[0] & FDR_BITS1_LANG_LITTLE)
237			    >> FDR_BITS1_LANG_SH_LITTLE);
238      intern->fMerge     = 0 != (ext->f_bits1[0] & FDR_BITS1_FMERGE_LITTLE);
239      intern->fReadin    = 0 != (ext->f_bits1[0] & FDR_BITS1_FREADIN_LITTLE);
240      intern->fBigendian = 0 != (ext->f_bits1[0] & FDR_BITS1_FBIGENDIAN_LITTLE);
241      intern->glevel     = ((ext->f_bits2[0] & FDR_BITS2_GLEVEL_LITTLE)
242			    >> FDR_BITS2_GLEVEL_SH_LITTLE);
243    }
244  intern->reserved = 0;
245
246  intern->cbLineOffset  = ECOFF_GET_OFF (abfd, ext->f_cbLineOffset);
247  intern->cbLine        = ECOFF_GET_OFF (abfd, ext->f_cbLine);
248
249#ifdef TEST
250  if (memcmp ((char *)ext, (char *)intern, sizeof (*intern)) != 0)
251    abort ();
252#endif
253}
254
255/* Swap out the file descriptor record.  */
256
257static void
258ecoff_swap_fdr_out (abfd, intern_copy, ext_ptr)
259     bfd *abfd;
260     const FDR *intern_copy;
261     PTR ext_ptr;
262{
263  struct fdr_ext *ext = (struct fdr_ext *) ext_ptr;
264  FDR intern[1];
265
266  /* Make it reasonable to do in-place.  */
267  *intern = *intern_copy;
268
269  ECOFF_PUT_OFF (abfd, intern->adr,       ext->f_adr);
270  H_PUT_32      (abfd, intern->rss,       ext->f_rss);
271  H_PUT_32      (abfd, intern->issBase,   ext->f_issBase);
272  ECOFF_PUT_OFF (abfd, intern->cbSs,      ext->f_cbSs);
273  H_PUT_32      (abfd, intern->isymBase,  ext->f_isymBase);
274  H_PUT_32      (abfd, intern->csym,      ext->f_csym);
275  H_PUT_32      (abfd, intern->ilineBase, ext->f_ilineBase);
276  H_PUT_32      (abfd, intern->cline,     ext->f_cline);
277  H_PUT_32      (abfd, intern->ioptBase,  ext->f_ioptBase);
278  H_PUT_32      (abfd, intern->copt,      ext->f_copt);
279#if defined (ECOFF_32) || defined (ECOFF_SIGNED_32)
280  H_PUT_16      (abfd, intern->ipdFirst,  ext->f_ipdFirst);
281  H_PUT_16      (abfd, intern->cpd,       ext->f_cpd);
282#endif
283#if defined (ECOFF_64) || defined (ECOFF_SIGNED_64)
284  H_PUT_32      (abfd, intern->ipdFirst,  ext->f_ipdFirst);
285  H_PUT_32      (abfd, intern->cpd,       ext->f_cpd);
286#endif
287  H_PUT_32      (abfd, intern->iauxBase,  ext->f_iauxBase);
288  H_PUT_32      (abfd, intern->caux,      ext->f_caux);
289  H_PUT_32      (abfd, intern->rfdBase,   ext->f_rfdBase);
290  H_PUT_32      (abfd, intern->crfd,      ext->f_crfd);
291
292  /* Now the fun stuff...  */
293  if (bfd_header_big_endian (abfd))
294    {
295      ext->f_bits1[0] = (((intern->lang << FDR_BITS1_LANG_SH_BIG)
296			  & FDR_BITS1_LANG_BIG)
297			 | (intern->fMerge ? FDR_BITS1_FMERGE_BIG : 0)
298			 | (intern->fReadin ? FDR_BITS1_FREADIN_BIG : 0)
299			 | (intern->fBigendian ? FDR_BITS1_FBIGENDIAN_BIG : 0));
300      ext->f_bits2[0] = ((intern->glevel << FDR_BITS2_GLEVEL_SH_BIG)
301			 & FDR_BITS2_GLEVEL_BIG);
302      ext->f_bits2[1] = 0;
303      ext->f_bits2[2] = 0;
304    }
305  else
306    {
307      ext->f_bits1[0] = (((intern->lang << FDR_BITS1_LANG_SH_LITTLE)
308			  & FDR_BITS1_LANG_LITTLE)
309			 | (intern->fMerge ? FDR_BITS1_FMERGE_LITTLE : 0)
310			 | (intern->fReadin ? FDR_BITS1_FREADIN_LITTLE : 0)
311			 | (intern->fBigendian ? FDR_BITS1_FBIGENDIAN_LITTLE : 0));
312      ext->f_bits2[0] = ((intern->glevel << FDR_BITS2_GLEVEL_SH_LITTLE)
313			 & FDR_BITS2_GLEVEL_LITTLE);
314      ext->f_bits2[1] = 0;
315      ext->f_bits2[2] = 0;
316    }
317
318  ECOFF_PUT_OFF (abfd, intern->cbLineOffset, ext->f_cbLineOffset);
319  ECOFF_PUT_OFF (abfd, intern->cbLine, ext->f_cbLine);
320
321#ifdef TEST
322  if (memcmp ((char *)ext, (char *)intern, sizeof (*intern)) != 0)
323    abort ();
324#endif
325}
326
327/* Swap in the procedure descriptor record.  */
328
329static void
330ecoff_swap_pdr_in (abfd, ext_copy, intern)
331     bfd *abfd;
332     PTR ext_copy;
333     PDR *intern;
334{
335  struct pdr_ext ext[1];
336
337  *ext = *(struct pdr_ext *) ext_copy;
338
339  memset ((PTR) intern, 0, sizeof (*intern));
340
341  intern->adr           = ECOFF_GET_OFF (abfd, ext->p_adr);
342  intern->isym          = H_GET_32 (abfd, ext->p_isym);
343  intern->iline         = H_GET_32 (abfd, ext->p_iline);
344  intern->regmask       = H_GET_32 (abfd, ext->p_regmask);
345  intern->regoffset     = H_GET_S32 (abfd, ext->p_regoffset);
346  intern->iopt          = H_GET_S32 (abfd, ext->p_iopt);
347  intern->fregmask      = H_GET_32 (abfd, ext->p_fregmask);
348  intern->fregoffset    = H_GET_S32 (abfd, ext->p_fregoffset);
349  intern->frameoffset   = H_GET_S32 (abfd, ext->p_frameoffset);
350  intern->framereg      = H_GET_16 (abfd, ext->p_framereg);
351  intern->pcreg         = H_GET_16 (abfd, ext->p_pcreg);
352  intern->lnLow         = H_GET_32 (abfd, ext->p_lnLow);
353  intern->lnHigh        = H_GET_32 (abfd, ext->p_lnHigh);
354  intern->cbLineOffset  = ECOFF_GET_OFF (abfd, ext->p_cbLineOffset);
355
356#if defined (ECOFF_64) || defined (ECOFF_SIGNED_64)
357  if (intern->isym == (signed long) 0xffffffff)
358    intern->isym = -1;
359  if (intern->iline == (signed long) 0xffffffff)
360    intern->iline = -1;
361
362  intern->gp_prologue = H_GET_8 (abfd, ext->p_gp_prologue);
363  if (bfd_header_big_endian (abfd))
364    {
365      intern->gp_used = 0 != (ext->p_bits1[0] & PDR_BITS1_GP_USED_BIG);
366      intern->reg_frame = 0 != (ext->p_bits1[0] & PDR_BITS1_REG_FRAME_BIG);
367      intern->prof = 0 != (ext->p_bits1[0] & PDR_BITS1_PROF_BIG);
368      intern->reserved = (((ext->p_bits1[0] & PDR_BITS1_RESERVED_BIG)
369			   << PDR_BITS1_RESERVED_SH_LEFT_BIG)
370			  | ((ext->p_bits2[0] & PDR_BITS2_RESERVED_BIG)
371			     >> PDR_BITS2_RESERVED_SH_BIG));
372    }
373  else
374    {
375      intern->gp_used = 0 != (ext->p_bits1[0] & PDR_BITS1_GP_USED_LITTLE);
376      intern->reg_frame = 0 != (ext->p_bits1[0] & PDR_BITS1_REG_FRAME_LITTLE);
377      intern->prof = 0 != (ext->p_bits1[0] & PDR_BITS1_PROF_LITTLE);
378      intern->reserved = (((ext->p_bits1[0] & PDR_BITS1_RESERVED_LITTLE)
379			   >> PDR_BITS1_RESERVED_SH_LITTLE)
380			  | ((ext->p_bits2[0] & PDR_BITS2_RESERVED_LITTLE)
381			     << PDR_BITS2_RESERVED_SH_LEFT_LITTLE));
382    }
383  intern->localoff = H_GET_8 (abfd, ext->p_localoff);
384#endif
385
386#ifdef TEST
387  if (memcmp ((char *)ext, (char *)intern, sizeof (*intern)) != 0)
388    abort ();
389#endif
390}
391
392/* Swap out the procedure descriptor record.  */
393
394static void
395ecoff_swap_pdr_out (abfd, intern_copy, ext_ptr)
396     bfd *abfd;
397     const PDR *intern_copy;
398     PTR ext_ptr;
399{
400  struct pdr_ext *ext = (struct pdr_ext *) ext_ptr;
401  PDR intern[1];
402
403  /* Make it reasonable to do in-place.  */
404  *intern = *intern_copy;
405
406  ECOFF_PUT_OFF (abfd, intern->adr,          ext->p_adr);
407  H_PUT_32      (abfd, intern->isym,         ext->p_isym);
408  H_PUT_32      (abfd, intern->iline,        ext->p_iline);
409  H_PUT_32      (abfd, intern->regmask,      ext->p_regmask);
410  H_PUT_32      (abfd, intern->regoffset,    ext->p_regoffset);
411  H_PUT_32      (abfd, intern->iopt,         ext->p_iopt);
412  H_PUT_32      (abfd, intern->fregmask,     ext->p_fregmask);
413  H_PUT_32      (abfd, intern->fregoffset,   ext->p_fregoffset);
414  H_PUT_32      (abfd, intern->frameoffset,  ext->p_frameoffset);
415  H_PUT_16      (abfd, intern->framereg,     ext->p_framereg);
416  H_PUT_16      (abfd, intern->pcreg,        ext->p_pcreg);
417  H_PUT_32      (abfd, intern->lnLow,        ext->p_lnLow);
418  H_PUT_32      (abfd, intern->lnHigh,       ext->p_lnHigh);
419  ECOFF_PUT_OFF (abfd, intern->cbLineOffset, ext->p_cbLineOffset);
420
421#if defined (ECOFF_64) || defined (ECOFF_SIGNED_64)
422  H_PUT_8       (abfd, intern->gp_prologue,  ext->p_gp_prologue);
423
424  if (bfd_header_big_endian (abfd))
425    {
426      ext->p_bits1[0] = ((intern->gp_used ? PDR_BITS1_GP_USED_BIG : 0)
427			 | (intern->reg_frame ? PDR_BITS1_REG_FRAME_BIG : 0)
428			 | (intern->prof ? PDR_BITS1_PROF_BIG : 0)
429			 | ((intern->reserved
430			     >> PDR_BITS1_RESERVED_SH_LEFT_BIG)
431			    & PDR_BITS1_RESERVED_BIG));
432      ext->p_bits2[0] = ((intern->reserved << PDR_BITS2_RESERVED_SH_BIG)
433			 & PDR_BITS2_RESERVED_BIG);
434    }
435  else
436    {
437      ext->p_bits1[0] = ((intern->gp_used ? PDR_BITS1_GP_USED_LITTLE : 0)
438			 | (intern->reg_frame ? PDR_BITS1_REG_FRAME_LITTLE : 0)
439			 | (intern->prof ? PDR_BITS1_PROF_LITTLE : 0)
440			 | ((intern->reserved << PDR_BITS1_RESERVED_SH_LITTLE)
441			    & PDR_BITS1_RESERVED_LITTLE));
442      ext->p_bits2[0] = ((intern->reserved >>
443			  PDR_BITS2_RESERVED_SH_LEFT_LITTLE)
444			 & PDR_BITS2_RESERVED_LITTLE);
445    }
446  H_PUT_8 (abfd, intern->localoff, ext->p_localoff);
447#endif
448
449#ifdef TEST
450  if (memcmp ((char *)ext, (char *)intern, sizeof (*intern)) != 0)
451    abort ();
452#endif
453}
454
455/* Swap in a symbol record.  */
456
457static void
458ecoff_swap_sym_in (abfd, ext_copy, intern)
459     bfd *abfd;
460     PTR ext_copy;
461     SYMR *intern;
462{
463  struct sym_ext ext[1];
464
465  *ext = *(struct sym_ext *) ext_copy;
466
467  intern->iss           = H_GET_32 (abfd, ext->s_iss);
468  intern->value         = ECOFF_GET_OFF (abfd, ext->s_value);
469
470#if defined (ECOFF_64) || defined (ECOFF_SIGNED_64)
471  if (intern->iss == (signed long) 0xffffffff)
472    intern->iss = -1;
473#endif
474
475  /* Now the fun stuff...  */
476  if (bfd_header_big_endian (abfd))
477    {
478      intern->st          =  (ext->s_bits1[0] & SYM_BITS1_ST_BIG)
479					     >> SYM_BITS1_ST_SH_BIG;
480      intern->sc          = ((ext->s_bits1[0] & SYM_BITS1_SC_BIG)
481					     << SYM_BITS1_SC_SH_LEFT_BIG)
482			  | ((ext->s_bits2[0] & SYM_BITS2_SC_BIG)
483					     >> SYM_BITS2_SC_SH_BIG);
484      intern->reserved    = 0 != (ext->s_bits2[0] & SYM_BITS2_RESERVED_BIG);
485      intern->index       = ((ext->s_bits2[0] & SYM_BITS2_INDEX_BIG)
486					     << SYM_BITS2_INDEX_SH_LEFT_BIG)
487			  | (ext->s_bits3[0] << SYM_BITS3_INDEX_SH_LEFT_BIG)
488			  | (ext->s_bits4[0] << SYM_BITS4_INDEX_SH_LEFT_BIG);
489    }
490  else
491    {
492      intern->st          =  (ext->s_bits1[0] & SYM_BITS1_ST_LITTLE)
493					     >> SYM_BITS1_ST_SH_LITTLE;
494      intern->sc          = ((ext->s_bits1[0] & SYM_BITS1_SC_LITTLE)
495					     >> SYM_BITS1_SC_SH_LITTLE)
496			  | ((ext->s_bits2[0] & SYM_BITS2_SC_LITTLE)
497					     << SYM_BITS2_SC_SH_LEFT_LITTLE);
498      intern->reserved    = 0 != (ext->s_bits2[0] & SYM_BITS2_RESERVED_LITTLE);
499      intern->index       = ((ext->s_bits2[0] & SYM_BITS2_INDEX_LITTLE)
500					     >> SYM_BITS2_INDEX_SH_LITTLE)
501			  | (ext->s_bits3[0] << SYM_BITS3_INDEX_SH_LEFT_LITTLE)
502			  | ((unsigned int) ext->s_bits4[0]
503			     << SYM_BITS4_INDEX_SH_LEFT_LITTLE);
504    }
505
506#ifdef TEST
507  if (memcmp ((char *)ext, (char *)intern, sizeof (*intern)) != 0)
508    abort ();
509#endif
510}
511
512/* Swap out a symbol record.  */
513
514static void
515ecoff_swap_sym_out (abfd, intern_copy, ext_ptr)
516     bfd *abfd;
517     const SYMR *intern_copy;
518     PTR ext_ptr;
519{
520  struct sym_ext *ext = (struct sym_ext *) ext_ptr;
521  SYMR intern[1];
522
523  /* Make it reasonable to do in-place.  */
524  *intern = *intern_copy;
525
526  H_PUT_32 (abfd, intern->iss, ext->s_iss);
527  ECOFF_PUT_OFF (abfd, intern->value, ext->s_value);
528
529  /* Now the fun stuff...  */
530  if (bfd_header_big_endian (abfd))
531    {
532      ext->s_bits1[0] = (((intern->st << SYM_BITS1_ST_SH_BIG)
533			  & SYM_BITS1_ST_BIG)
534			 | ((intern->sc >> SYM_BITS1_SC_SH_LEFT_BIG)
535			    & SYM_BITS1_SC_BIG));
536      ext->s_bits2[0] = (((intern->sc << SYM_BITS2_SC_SH_BIG)
537			  & SYM_BITS2_SC_BIG)
538			 | (intern->reserved ? SYM_BITS2_RESERVED_BIG : 0)
539			 | ((intern->index >> SYM_BITS2_INDEX_SH_LEFT_BIG)
540			    & SYM_BITS2_INDEX_BIG));
541      ext->s_bits3[0] = (intern->index >> SYM_BITS3_INDEX_SH_LEFT_BIG) & 0xff;
542      ext->s_bits4[0] = (intern->index >> SYM_BITS4_INDEX_SH_LEFT_BIG) & 0xff;
543    }
544  else
545    {
546      ext->s_bits1[0] = (((intern->st << SYM_BITS1_ST_SH_LITTLE)
547			  & SYM_BITS1_ST_LITTLE)
548			 | ((intern->sc << SYM_BITS1_SC_SH_LITTLE)
549			    & SYM_BITS1_SC_LITTLE));
550      ext->s_bits2[0] = (((intern->sc >> SYM_BITS2_SC_SH_LEFT_LITTLE)
551			  & SYM_BITS2_SC_LITTLE)
552			 | (intern->reserved ? SYM_BITS2_RESERVED_LITTLE : 0)
553			 | ((intern->index << SYM_BITS2_INDEX_SH_LITTLE)
554			    & SYM_BITS2_INDEX_LITTLE));
555      ext->s_bits3[0] = (intern->index >> SYM_BITS3_INDEX_SH_LEFT_LITTLE) & 0xff;
556      ext->s_bits4[0] = (intern->index >> SYM_BITS4_INDEX_SH_LEFT_LITTLE) & 0xff;
557    }
558
559#ifdef TEST
560  if (memcmp ((char *)ext, (char *)intern, sizeof (*intern)) != 0)
561    abort ();
562#endif
563}
564
565/* Swap in an external symbol record.  */
566
567static void
568ecoff_swap_ext_in (abfd, ext_copy, intern)
569     bfd *abfd;
570     PTR ext_copy;
571     EXTR *intern;
572{
573  struct ext_ext ext[1];
574
575  *ext = *(struct ext_ext *) ext_copy;
576
577  /* Now the fun stuff...  */
578  if (bfd_header_big_endian (abfd))
579    {
580      intern->jmptbl      = 0 != (ext->es_bits1[0] & EXT_BITS1_JMPTBL_BIG);
581      intern->cobol_main  = 0 != (ext->es_bits1[0] & EXT_BITS1_COBOL_MAIN_BIG);
582      intern->weakext     = 0 != (ext->es_bits1[0] & EXT_BITS1_WEAKEXT_BIG);
583    }
584  else
585    {
586      intern->jmptbl      = 0 != (ext->es_bits1[0] & EXT_BITS1_JMPTBL_LITTLE);
587      intern->cobol_main  = 0 != (ext->es_bits1[0] & EXT_BITS1_COBOL_MAIN_LITTLE);
588      intern->weakext     = 0 != (ext->es_bits1[0] & EXT_BITS1_WEAKEXT_LITTLE);
589    }
590  intern->reserved = 0;
591
592#if defined (ECOFF_32) || defined (ECOFF_SIGNED_32)
593  intern->ifd = H_GET_S16 (abfd, ext->es_ifd);
594#endif
595#if defined (ECOFF_64) || defined (ECOFF_SIGNED_64)
596  intern->ifd = H_GET_S32 (abfd, ext->es_ifd);
597#endif
598
599  ecoff_swap_sym_in (abfd, &ext->es_asym, &intern->asym);
600
601#ifdef TEST
602  if (memcmp ((char *)ext, (char *)intern, sizeof (*intern)) != 0)
603    abort ();
604#endif
605}
606
607/* Swap out an external symbol record.  */
608
609static void
610ecoff_swap_ext_out (abfd, intern_copy, ext_ptr)
611     bfd *abfd;
612     const EXTR *intern_copy;
613     PTR ext_ptr;
614{
615  struct ext_ext *ext = (struct ext_ext *) ext_ptr;
616  EXTR intern[1];
617
618  /* Make it reasonable to do in-place.  */
619  *intern = *intern_copy;
620
621  /* Now the fun stuff...  */
622  if (bfd_header_big_endian (abfd))
623    {
624      ext->es_bits1[0] = ((intern->jmptbl ? EXT_BITS1_JMPTBL_BIG : 0)
625			  | (intern->cobol_main ? EXT_BITS1_COBOL_MAIN_BIG : 0)
626			  | (intern->weakext ? EXT_BITS1_WEAKEXT_BIG : 0));
627      ext->es_bits2[0] = 0;
628#if defined (ECOFF_64) || defined (ECOFF_SIGNED_64)
629      ext->es_bits2[1] = 0;
630      ext->es_bits2[2] = 0;
631#endif
632    }
633  else
634    {
635      ext->es_bits1[0] = ((intern->jmptbl ? EXT_BITS1_JMPTBL_LITTLE : 0)
636			  | (intern->cobol_main ? EXT_BITS1_COBOL_MAIN_LITTLE : 0)
637			  | (intern->weakext ? EXT_BITS1_WEAKEXT_LITTLE : 0));
638      ext->es_bits2[0] = 0;
639#if defined (ECOFF_64) || defined (ECOFF_SIGNED_64)
640      ext->es_bits2[1] = 0;
641      ext->es_bits2[2] = 0;
642#endif
643    }
644
645#if defined (ECOFF_32) || defined (ECOFF_SIGNED_32)
646  H_PUT_S16 (abfd, intern->ifd, ext->es_ifd);
647#endif
648#if defined (ECOFF_64) || defined (ECOFF_SIGNED_64)
649  H_PUT_S32 (abfd, intern->ifd, ext->es_ifd);
650#endif
651
652  ecoff_swap_sym_out (abfd, &intern->asym, &ext->es_asym);
653
654#ifdef TEST
655  if (memcmp ((char *)ext, (char *)intern, sizeof (*intern)) != 0)
656    abort ();
657#endif
658}
659
660/* Swap in a relative file descriptor.  */
661
662static void
663ecoff_swap_rfd_in (abfd, ext_ptr, intern)
664     bfd *abfd;
665     PTR ext_ptr;
666     RFDT *intern;
667{
668  struct rfd_ext *ext = (struct rfd_ext *) ext_ptr;
669
670  *intern = H_GET_32 (abfd, ext->rfd);
671
672#ifdef TEST
673  if (memcmp ((char *)ext, (char *)intern, sizeof (*intern)) != 0)
674    abort ();
675#endif
676}
677
678/* Swap out a relative file descriptor.  */
679
680static void
681ecoff_swap_rfd_out (abfd, intern, ext_ptr)
682     bfd *abfd;
683     const RFDT *intern;
684     PTR ext_ptr;
685{
686  struct rfd_ext *ext = (struct rfd_ext *) ext_ptr;
687
688  H_PUT_32 (abfd, *intern, ext->rfd);
689
690#ifdef TEST
691  if (memcmp ((char *)ext, (char *)intern, sizeof (*intern)) != 0)
692    abort ();
693#endif
694}
695
696/* Swap in an optimization symbol.  */
697
698static void
699ecoff_swap_opt_in (abfd, ext_copy, intern)
700     bfd *abfd;
701     PTR ext_copy;
702     OPTR *intern;
703{
704  struct opt_ext ext[1];
705
706  *ext = *(struct opt_ext *) ext_copy;
707
708  if (bfd_header_big_endian (abfd))
709    {
710      intern->ot = ext->o_bits1[0];
711      intern->value = (((unsigned int) ext->o_bits2[0]
712			<< OPT_BITS2_VALUE_SH_LEFT_BIG)
713		       | ((unsigned int) ext->o_bits3[0]
714			  << OPT_BITS2_VALUE_SH_LEFT_BIG)
715		       | ((unsigned int) ext->o_bits4[0]
716			  << OPT_BITS2_VALUE_SH_LEFT_BIG));
717    }
718  else
719    {
720      intern->ot = ext->o_bits1[0];
721      intern->value = ((ext->o_bits2[0] << OPT_BITS2_VALUE_SH_LEFT_LITTLE)
722		       | (ext->o_bits3[0] << OPT_BITS2_VALUE_SH_LEFT_LITTLE)
723		       | (ext->o_bits4[0] << OPT_BITS2_VALUE_SH_LEFT_LITTLE));
724    }
725
726  _bfd_ecoff_swap_rndx_in (bfd_header_big_endian (abfd),
727			   &ext->o_rndx, &intern->rndx);
728
729  intern->offset = H_GET_32 (abfd, ext->o_offset);
730
731#ifdef TEST
732  if (memcmp ((char *)ext, (char *)intern, sizeof (*intern)) != 0)
733    abort ();
734#endif
735}
736
737/* Swap out an optimization symbol.  */
738
739static void
740ecoff_swap_opt_out (abfd, intern_copy, ext_ptr)
741     bfd *abfd;
742     const OPTR *intern_copy;
743     PTR ext_ptr;
744{
745  struct opt_ext *ext = (struct opt_ext *) ext_ptr;
746  OPTR intern[1];
747
748  /* Make it reasonable to do in-place.  */
749  *intern = *intern_copy;
750
751  if (bfd_header_big_endian (abfd))
752    {
753      ext->o_bits1[0] = intern->ot;
754      ext->o_bits2[0] = intern->value >> OPT_BITS2_VALUE_SH_LEFT_BIG;
755      ext->o_bits3[0] = intern->value >> OPT_BITS3_VALUE_SH_LEFT_BIG;
756      ext->o_bits4[0] = intern->value >> OPT_BITS4_VALUE_SH_LEFT_BIG;
757    }
758  else
759    {
760      ext->o_bits1[0] = intern->ot;
761      ext->o_bits2[0] = intern->value >> OPT_BITS2_VALUE_SH_LEFT_LITTLE;
762      ext->o_bits3[0] = intern->value >> OPT_BITS3_VALUE_SH_LEFT_LITTLE;
763      ext->o_bits4[0] = intern->value >> OPT_BITS4_VALUE_SH_LEFT_LITTLE;
764    }
765
766  _bfd_ecoff_swap_rndx_out (bfd_header_big_endian (abfd),
767			    &intern->rndx, &ext->o_rndx);
768
769  H_PUT_32 (abfd, intern->value, ext->o_offset);
770
771#ifdef TEST
772  if (memcmp ((char *)ext, (char *)intern, sizeof (*intern)) != 0)
773    abort ();
774#endif
775}
776
777/* Swap in a dense number.  */
778
779static void
780ecoff_swap_dnr_in (abfd, ext_copy, intern)
781     bfd *abfd;
782     PTR ext_copy;
783     DNR *intern;
784{
785  struct dnr_ext ext[1];
786
787  *ext = *(struct dnr_ext *) ext_copy;
788
789  intern->rfd = H_GET_32 (abfd, ext->d_rfd);
790  intern->index = H_GET_32 (abfd, ext->d_index);
791
792#ifdef TEST
793  if (memcmp ((char *)ext, (char *)intern, sizeof (*intern)) != 0)
794    abort ();
795#endif
796}
797
798/* Swap out a dense number.  */
799
800static void
801ecoff_swap_dnr_out (abfd, intern_copy, ext_ptr)
802     bfd *abfd;
803     const DNR *intern_copy;
804     PTR ext_ptr;
805{
806  struct dnr_ext *ext = (struct dnr_ext *) ext_ptr;
807  DNR intern[1];
808
809  /* Make it reasonable to do in-place.  */
810  *intern = *intern_copy;
811
812  H_PUT_32 (abfd, intern->rfd, ext->d_rfd);
813  H_PUT_32 (abfd, intern->index, ext->d_index);
814
815#ifdef TEST
816  if (memcmp ((char *)ext, (char *)intern, sizeof (*intern)) != 0)
817    abort ();
818#endif
819}
820