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