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