ecoffswap.h revision 78828
1/* Generic ECOFF swapping routines, for BFD.
2   Copyright 1992, 1993, 1994, 1995, 1996, 2000, 2001
3   Free Software Foundation, Inc.
4   Written by Cygnus Support.
5
6This file is part of BFD, the Binary File Descriptor library.
7
8This program is free software; you can redistribute it and/or modify
9it under the terms of the GNU General Public License as published by
10the Free Software Foundation; either version 2 of the License, or
11(at your option) any later version.
12
13This program is distributed in the hope that it will be useful,
14but WITHOUT ANY WARRANTY; without even the implied warranty of
15MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16GNU General Public License for more details.
17
18You should have received a copy of the GNU General Public License
19along with this program; if not, write to the Free Software
20Foundation, 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 bfd_h_get_32
49#define ecoff_put_off bfd_h_put_32
50#endif
51#ifdef ECOFF_64
52#define ecoff_get_off bfd_h_get_64
53#define ecoff_put_off bfd_h_put_64
54#endif
55#ifdef ECOFF_SIGNED_32
56#define ecoff_get_off bfd_h_get_signed_32
57#define ecoff_put_off bfd_h_put_signed_32
58#endif
59#ifdef ECOFF_SIGNED_64
60#define ecoff_get_off bfd_h_get_signed_64
61#define ecoff_put_off bfd_h_put_signed_64
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         = bfd_h_get_signed_16 (abfd, (bfd_byte *)ext->h_magic);
108  intern->vstamp        = bfd_h_get_signed_16 (abfd, (bfd_byte *)ext->h_vstamp);
109  intern->ilineMax      = bfd_h_get_32 (abfd, (bfd_byte *)ext->h_ilineMax);
110  intern->cbLine        = ecoff_get_off (abfd, (bfd_byte *)ext->h_cbLine);
111  intern->cbLineOffset  = ecoff_get_off (abfd, (bfd_byte *)ext->h_cbLineOffset);
112  intern->idnMax        = bfd_h_get_32 (abfd, (bfd_byte *)ext->h_idnMax);
113  intern->cbDnOffset    = ecoff_get_off (abfd, (bfd_byte *)ext->h_cbDnOffset);
114  intern->ipdMax        = bfd_h_get_32 (abfd, (bfd_byte *)ext->h_ipdMax);
115  intern->cbPdOffset    = ecoff_get_off (abfd, (bfd_byte *)ext->h_cbPdOffset);
116  intern->isymMax       = bfd_h_get_32 (abfd, (bfd_byte *)ext->h_isymMax);
117  intern->cbSymOffset   = ecoff_get_off (abfd, (bfd_byte *)ext->h_cbSymOffset);
118  intern->ioptMax       = bfd_h_get_32 (abfd, (bfd_byte *)ext->h_ioptMax);
119  intern->cbOptOffset   = ecoff_get_off (abfd, (bfd_byte *)ext->h_cbOptOffset);
120  intern->iauxMax       = bfd_h_get_32 (abfd, (bfd_byte *)ext->h_iauxMax);
121  intern->cbAuxOffset   = ecoff_get_off (abfd, (bfd_byte *)ext->h_cbAuxOffset);
122  intern->issMax        = bfd_h_get_32 (abfd, (bfd_byte *)ext->h_issMax);
123  intern->cbSsOffset    = ecoff_get_off (abfd, (bfd_byte *)ext->h_cbSsOffset);
124  intern->issExtMax     = bfd_h_get_32 (abfd, (bfd_byte *)ext->h_issExtMax);
125  intern->cbSsExtOffset = ecoff_get_off (abfd, (bfd_byte *)ext->h_cbSsExtOffset);
126  intern->ifdMax        = bfd_h_get_32 (abfd, (bfd_byte *)ext->h_ifdMax);
127  intern->cbFdOffset    = ecoff_get_off (abfd, (bfd_byte *)ext->h_cbFdOffset);
128  intern->crfd          = bfd_h_get_32 (abfd, (bfd_byte *)ext->h_crfd);
129  intern->cbRfdOffset   = ecoff_get_off (abfd, (bfd_byte *)ext->h_cbRfdOffset);
130  intern->iextMax       = bfd_h_get_32 (abfd, (bfd_byte *)ext->h_iextMax);
131  intern->cbExtOffset   = ecoff_get_off (abfd, (bfd_byte *)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  bfd_h_put_signed_16 (abfd, intern->magic, (bfd_byte *)ext->h_magic);
153  bfd_h_put_signed_16 (abfd, intern->vstamp, (bfd_byte *)ext->h_vstamp);
154  bfd_h_put_32 (abfd, intern->ilineMax, (bfd_byte *)ext->h_ilineMax);
155  ecoff_put_off (abfd, intern->cbLine, (bfd_byte *)ext->h_cbLine);
156  ecoff_put_off (abfd, intern->cbLineOffset, (bfd_byte *)ext->h_cbLineOffset);
157  bfd_h_put_32 (abfd, intern->idnMax, (bfd_byte *)ext->h_idnMax);
158  ecoff_put_off (abfd, intern->cbDnOffset, (bfd_byte *)ext->h_cbDnOffset);
159  bfd_h_put_32 (abfd, intern->ipdMax, (bfd_byte *)ext->h_ipdMax);
160  ecoff_put_off (abfd, intern->cbPdOffset, (bfd_byte *)ext->h_cbPdOffset);
161  bfd_h_put_32 (abfd, intern->isymMax, (bfd_byte *)ext->h_isymMax);
162  ecoff_put_off (abfd, intern->cbSymOffset, (bfd_byte *)ext->h_cbSymOffset);
163  bfd_h_put_32 (abfd, intern->ioptMax, (bfd_byte *)ext->h_ioptMax);
164  ecoff_put_off (abfd, intern->cbOptOffset, (bfd_byte *)ext->h_cbOptOffset);
165  bfd_h_put_32 (abfd, intern->iauxMax, (bfd_byte *)ext->h_iauxMax);
166  ecoff_put_off (abfd, intern->cbAuxOffset, (bfd_byte *)ext->h_cbAuxOffset);
167  bfd_h_put_32 (abfd, intern->issMax, (bfd_byte *)ext->h_issMax);
168  ecoff_put_off (abfd, intern->cbSsOffset, (bfd_byte *)ext->h_cbSsOffset);
169  bfd_h_put_32 (abfd, intern->issExtMax, (bfd_byte *)ext->h_issExtMax);
170  ecoff_put_off (abfd, intern->cbSsExtOffset, (bfd_byte *)ext->h_cbSsExtOffset);
171  bfd_h_put_32 (abfd, intern->ifdMax, (bfd_byte *)ext->h_ifdMax);
172  ecoff_put_off (abfd, intern->cbFdOffset, (bfd_byte *)ext->h_cbFdOffset);
173  bfd_h_put_32 (abfd, intern->crfd, (bfd_byte *)ext->h_crfd);
174  ecoff_put_off (abfd, intern->cbRfdOffset, (bfd_byte *)ext->h_cbRfdOffset);
175  bfd_h_put_32 (abfd, intern->iextMax, (bfd_byte *)ext->h_iextMax);
176  ecoff_put_off (abfd, intern->cbExtOffset, (bfd_byte *)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, (bfd_byte *)ext->f_adr);
197  intern->rss           = bfd_h_get_32 (abfd, (bfd_byte *)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       = bfd_h_get_32 (abfd, (bfd_byte *)ext->f_issBase);
203  intern->cbSs          = ecoff_get_off (abfd, (bfd_byte *)ext->f_cbSs);
204  intern->isymBase      = bfd_h_get_32 (abfd, (bfd_byte *)ext->f_isymBase);
205  intern->csym          = bfd_h_get_32 (abfd, (bfd_byte *)ext->f_csym);
206  intern->ilineBase     = bfd_h_get_32 (abfd, (bfd_byte *)ext->f_ilineBase);
207  intern->cline         = bfd_h_get_32 (abfd, (bfd_byte *)ext->f_cline);
208  intern->ioptBase      = bfd_h_get_32 (abfd, (bfd_byte *)ext->f_ioptBase);
209  intern->copt          = bfd_h_get_32 (abfd, (bfd_byte *)ext->f_copt);
210#if defined (ECOFF_32) || defined (ECOFF_SIGNED_32)
211  intern->ipdFirst      = bfd_h_get_16 (abfd, (bfd_byte *)ext->f_ipdFirst);
212  intern->cpd           = bfd_h_get_16 (abfd, (bfd_byte *)ext->f_cpd);
213#endif
214#if defined (ECOFF_64) || defined (ECOFF_SIGNED_64)
215  intern->ipdFirst      = bfd_h_get_32 (abfd, (bfd_byte *)ext->f_ipdFirst);
216  intern->cpd           = bfd_h_get_32 (abfd, (bfd_byte *)ext->f_cpd);
217#endif
218  intern->iauxBase      = bfd_h_get_32 (abfd, (bfd_byte *)ext->f_iauxBase);
219  intern->caux          = bfd_h_get_32 (abfd, (bfd_byte *)ext->f_caux);
220  intern->rfdBase       = bfd_h_get_32 (abfd, (bfd_byte *)ext->f_rfdBase);
221  intern->crfd          = bfd_h_get_32 (abfd, (bfd_byte *)ext->f_crfd);
222
223  /* now the fun stuff...  */
224  if (bfd_header_big_endian (abfd)) {
225    intern->lang        = (ext->f_bits1[0] & FDR_BITS1_LANG_BIG)
226					>> FDR_BITS1_LANG_SH_BIG;
227    intern->fMerge      = 0 != (ext->f_bits1[0] & FDR_BITS1_FMERGE_BIG);
228    intern->fReadin     = 0 != (ext->f_bits1[0] & FDR_BITS1_FREADIN_BIG);
229    intern->fBigendian  = 0 != (ext->f_bits1[0] & FDR_BITS1_FBIGENDIAN_BIG);
230    intern->glevel      = (ext->f_bits2[0] & FDR_BITS2_GLEVEL_BIG)
231					>> FDR_BITS2_GLEVEL_SH_BIG;
232  } else {
233    intern->lang        = (ext->f_bits1[0] & FDR_BITS1_LANG_LITTLE)
234					>> FDR_BITS1_LANG_SH_LITTLE;
235    intern->fMerge      = 0 != (ext->f_bits1[0] & FDR_BITS1_FMERGE_LITTLE);
236    intern->fReadin     = 0 != (ext->f_bits1[0] & FDR_BITS1_FREADIN_LITTLE);
237    intern->fBigendian  = 0 != (ext->f_bits1[0] & FDR_BITS1_FBIGENDIAN_LITTLE);
238    intern->glevel      = (ext->f_bits2[0] & FDR_BITS2_GLEVEL_LITTLE)
239					>> FDR_BITS2_GLEVEL_SH_LITTLE;
240  }
241  intern->reserved = 0;
242
243  intern->cbLineOffset  = ecoff_get_off (abfd, (bfd_byte *)ext->f_cbLineOffset);
244  intern->cbLine        = ecoff_get_off (abfd, (bfd_byte *)ext->f_cbLine);
245
246#ifdef TEST
247  if (memcmp ((char *)ext, (char *)intern, sizeof (*intern)) != 0)
248    abort ();
249#endif
250}
251
252/* Swap out the file descriptor record.  */
253
254static void
255ecoff_swap_fdr_out (abfd, intern_copy, ext_ptr)
256     bfd *abfd;
257     const FDR *intern_copy;
258     PTR ext_ptr;
259{
260  struct fdr_ext *ext = (struct fdr_ext *) ext_ptr;
261  FDR intern[1];
262
263  *intern = *intern_copy;	/* Make it reasonable to do in-place.  */
264
265  ecoff_put_off (abfd, intern->adr, (bfd_byte *)ext->f_adr);
266  bfd_h_put_32 (abfd, intern->rss, (bfd_byte *)ext->f_rss);
267  bfd_h_put_32 (abfd, intern->issBase, (bfd_byte *)ext->f_issBase);
268  ecoff_put_off (abfd, intern->cbSs, (bfd_byte *)ext->f_cbSs);
269  bfd_h_put_32 (abfd, intern->isymBase, (bfd_byte *)ext->f_isymBase);
270  bfd_h_put_32 (abfd, intern->csym, (bfd_byte *)ext->f_csym);
271  bfd_h_put_32 (abfd, intern->ilineBase, (bfd_byte *)ext->f_ilineBase);
272  bfd_h_put_32 (abfd, intern->cline, (bfd_byte *)ext->f_cline);
273  bfd_h_put_32 (abfd, intern->ioptBase, (bfd_byte *)ext->f_ioptBase);
274  bfd_h_put_32 (abfd, intern->copt, (bfd_byte *)ext->f_copt);
275#if defined (ECOFF_32) || defined (ECOFF_SIGNED_32)
276  bfd_h_put_16 (abfd, intern->ipdFirst, (bfd_byte *)ext->f_ipdFirst);
277  bfd_h_put_16 (abfd, intern->cpd, (bfd_byte *)ext->f_cpd);
278#endif
279#if defined (ECOFF_64) || defined (ECOFF_SIGNED_64)
280  bfd_h_put_32 (abfd, intern->ipdFirst, (bfd_byte *)ext->f_ipdFirst);
281  bfd_h_put_32 (abfd, intern->cpd, (bfd_byte *)ext->f_cpd);
282#endif
283  bfd_h_put_32 (abfd, intern->iauxBase, (bfd_byte *)ext->f_iauxBase);
284  bfd_h_put_32 (abfd, intern->caux, (bfd_byte *)ext->f_caux);
285  bfd_h_put_32 (abfd, intern->rfdBase, (bfd_byte *)ext->f_rfdBase);
286  bfd_h_put_32 (abfd, intern->crfd, (bfd_byte *)ext->f_crfd);
287
288  /* now the fun stuff...  */
289  if (bfd_header_big_endian (abfd)) {
290    ext->f_bits1[0] = (((intern->lang << FDR_BITS1_LANG_SH_BIG)
291			& FDR_BITS1_LANG_BIG)
292		       | (intern->fMerge ? FDR_BITS1_FMERGE_BIG : 0)
293		       | (intern->fReadin ? FDR_BITS1_FREADIN_BIG : 0)
294		       | (intern->fBigendian ? FDR_BITS1_FBIGENDIAN_BIG : 0));
295    ext->f_bits2[0] = ((intern->glevel << FDR_BITS2_GLEVEL_SH_BIG)
296		       & FDR_BITS2_GLEVEL_BIG);
297    ext->f_bits2[1] = 0;
298    ext->f_bits2[2] = 0;
299  } else {
300    ext->f_bits1[0] = (((intern->lang << FDR_BITS1_LANG_SH_LITTLE)
301			& FDR_BITS1_LANG_LITTLE)
302		       | (intern->fMerge ? FDR_BITS1_FMERGE_LITTLE : 0)
303		       | (intern->fReadin ? FDR_BITS1_FREADIN_LITTLE : 0)
304		       | (intern->fBigendian ? FDR_BITS1_FBIGENDIAN_LITTLE : 0));
305    ext->f_bits2[0] = ((intern->glevel << FDR_BITS2_GLEVEL_SH_LITTLE)
306		       & FDR_BITS2_GLEVEL_LITTLE);
307    ext->f_bits2[1] = 0;
308    ext->f_bits2[2] = 0;
309  }
310
311  ecoff_put_off (abfd, intern->cbLineOffset, (bfd_byte *)ext->f_cbLineOffset);
312  ecoff_put_off (abfd, intern->cbLine, (bfd_byte *)ext->f_cbLine);
313
314#ifdef TEST
315  if (memcmp ((char *)ext, (char *)intern, sizeof (*intern)) != 0)
316    abort ();
317#endif
318}
319
320#ifndef MPW_C
321
322/* Swap in the procedure descriptor record.  */
323
324static void
325ecoff_swap_pdr_in (abfd, ext_copy, intern)
326     bfd *abfd;
327     PTR ext_copy;
328     PDR *intern;
329{
330  struct pdr_ext ext[1];
331
332  *ext = *(struct pdr_ext *) ext_copy;
333
334  memset ((PTR) intern, 0, sizeof (*intern));
335
336  intern->adr           = ecoff_get_off (abfd, (bfd_byte *)ext->p_adr);
337  intern->isym          = bfd_h_get_32 (abfd, (bfd_byte *)ext->p_isym);
338  intern->iline         = bfd_h_get_32 (abfd, (bfd_byte *)ext->p_iline);
339  intern->regmask       = bfd_h_get_32 (abfd, (bfd_byte *)ext->p_regmask);
340  intern->regoffset     = bfd_h_get_signed_32 (abfd,
341					       (bfd_byte *)ext->p_regoffset);
342  intern->iopt          = bfd_h_get_signed_32 (abfd, (bfd_byte *)ext->p_iopt);
343  intern->fregmask      = bfd_h_get_32 (abfd, (bfd_byte *)ext->p_fregmask);
344  intern->fregoffset    = bfd_h_get_signed_32 (abfd,
345					       (bfd_byte *)ext->p_fregoffset);
346  intern->frameoffset   = bfd_h_get_signed_32 (abfd,
347					       (bfd_byte *)ext->p_frameoffset);
348  intern->framereg      = bfd_h_get_16 (abfd, (bfd_byte *)ext->p_framereg);
349  intern->pcreg         = bfd_h_get_16 (abfd, (bfd_byte *)ext->p_pcreg);
350  intern->lnLow         = bfd_h_get_32 (abfd, (bfd_byte *)ext->p_lnLow);
351  intern->lnHigh        = bfd_h_get_32 (abfd, (bfd_byte *)ext->p_lnHigh);
352  intern->cbLineOffset  = ecoff_get_off (abfd, (bfd_byte *)ext->p_cbLineOffset);
353
354#if defined (ECOFF_64) || defined (ECOFF_SIGNED_64)
355  intern->gp_prologue = bfd_h_get_8 (abfd, (bfd_byte *) ext->p_gp_prologue);
356  if (bfd_header_big_endian (abfd))
357    {
358      intern->gp_used = 0 != (ext->p_bits1[0] & PDR_BITS1_GP_USED_BIG);
359      intern->reg_frame = 0 != (ext->p_bits1[0] & PDR_BITS1_REG_FRAME_BIG);
360      intern->prof = 0 != (ext->p_bits1[0] & PDR_BITS1_PROF_BIG);
361      intern->reserved = (((ext->p_bits1[0] & PDR_BITS1_RESERVED_BIG)
362			   << PDR_BITS1_RESERVED_SH_LEFT_BIG)
363			  | ((ext->p_bits2[0] & PDR_BITS2_RESERVED_BIG)
364			     >> PDR_BITS2_RESERVED_SH_BIG));
365    }
366  else
367    {
368      intern->gp_used = 0 != (ext->p_bits1[0] & PDR_BITS1_GP_USED_LITTLE);
369      intern->reg_frame = 0 != (ext->p_bits1[0] & PDR_BITS1_REG_FRAME_LITTLE);
370      intern->prof = 0 != (ext->p_bits1[0] & PDR_BITS1_PROF_LITTLE);
371      intern->reserved = (((ext->p_bits1[0] & PDR_BITS1_RESERVED_LITTLE)
372			   >> PDR_BITS1_RESERVED_SH_LITTLE)
373			  | ((ext->p_bits2[0] & PDR_BITS2_RESERVED_LITTLE)
374			     << PDR_BITS2_RESERVED_SH_LEFT_LITTLE));
375    }
376  intern->localoff = bfd_h_get_8 (abfd, (bfd_byte *) ext->p_localoff);
377#endif
378
379#ifdef TEST
380  if (memcmp ((char *)ext, (char *)intern, sizeof (*intern)) != 0)
381    abort ();
382#endif
383}
384
385/* Swap out the procedure descriptor record.  */
386
387static void
388ecoff_swap_pdr_out (abfd, intern_copy, ext_ptr)
389     bfd *abfd;
390     const PDR *intern_copy;
391     PTR ext_ptr;
392{
393  struct pdr_ext *ext = (struct pdr_ext *) ext_ptr;
394  PDR intern[1];
395
396  *intern = *intern_copy;	/* Make it reasonable to do in-place.  */
397
398  ecoff_put_off (abfd, intern->adr, (bfd_byte *)ext->p_adr);
399  bfd_h_put_32 (abfd, intern->isym, (bfd_byte *)ext->p_isym);
400  bfd_h_put_32 (abfd, intern->iline, (bfd_byte *)ext->p_iline);
401  bfd_h_put_32 (abfd, intern->regmask, (bfd_byte *)ext->p_regmask);
402  bfd_h_put_32 (abfd, intern->regoffset, (bfd_byte *)ext->p_regoffset);
403  bfd_h_put_32 (abfd, intern->iopt, (bfd_byte *)ext->p_iopt);
404  bfd_h_put_32 (abfd, intern->fregmask, (bfd_byte *)ext->p_fregmask);
405  bfd_h_put_32 (abfd, intern->fregoffset, (bfd_byte *)ext->p_fregoffset);
406  bfd_h_put_32 (abfd, intern->frameoffset, (bfd_byte *)ext->p_frameoffset);
407  bfd_h_put_16 (abfd, intern->framereg, (bfd_byte *)ext->p_framereg);
408  bfd_h_put_16 (abfd, intern->pcreg, (bfd_byte *)ext->p_pcreg);
409  bfd_h_put_32 (abfd, intern->lnLow, (bfd_byte *)ext->p_lnLow);
410  bfd_h_put_32 (abfd, intern->lnHigh, (bfd_byte *)ext->p_lnHigh);
411  ecoff_put_off (abfd, intern->cbLineOffset, (bfd_byte *)ext->p_cbLineOffset);
412
413#if defined (ECOFF_64) || defined (ECOFF_SIGNED_64)
414  bfd_h_put_8 (abfd, intern->gp_prologue, (bfd_byte *) ext->p_gp_prologue);
415  if (bfd_header_big_endian (abfd))
416    {
417      ext->p_bits1[0] = ((intern->gp_used ? PDR_BITS1_GP_USED_BIG : 0)
418			 | (intern->reg_frame ? PDR_BITS1_REG_FRAME_BIG : 0)
419			 | (intern->prof ? PDR_BITS1_PROF_BIG : 0)
420			 | ((intern->reserved
421			     >> PDR_BITS1_RESERVED_SH_LEFT_BIG)
422			    & PDR_BITS1_RESERVED_BIG));
423      ext->p_bits2[0] = ((intern->reserved << PDR_BITS2_RESERVED_SH_BIG)
424			 & PDR_BITS2_RESERVED_BIG);
425    }
426  else
427    {
428      ext->p_bits1[0] = ((intern->gp_used ? PDR_BITS1_GP_USED_LITTLE : 0)
429			 | (intern->reg_frame ? PDR_BITS1_REG_FRAME_LITTLE : 0)
430			 | (intern->prof ? PDR_BITS1_PROF_LITTLE : 0)
431			 | ((intern->reserved << PDR_BITS1_RESERVED_SH_LITTLE)
432			    & PDR_BITS1_RESERVED_LITTLE));
433      ext->p_bits2[0] = ((intern->reserved >>
434			  PDR_BITS2_RESERVED_SH_LEFT_LITTLE)
435			 & PDR_BITS2_RESERVED_LITTLE);
436    }
437  bfd_h_put_8 (abfd, intern->localoff, (bfd_byte *) ext->p_localoff);
438#endif
439
440#ifdef TEST
441  if (memcmp ((char *)ext, (char *)intern, sizeof (*intern)) != 0)
442    abort ();
443#endif
444}
445
446#else /* MPW_C */
447/* Same routines, but with ECOFF_64 code removed, so ^&%$#&! MPW C doesn't
448   corrupt itself and then freak out.  */
449/* Swap in the procedure descriptor record.  */
450
451static void
452ecoff_swap_pdr_in (abfd, ext_copy, intern)
453     bfd *abfd;
454     PTR ext_copy;
455     PDR *intern;
456{
457  struct pdr_ext ext[1];
458
459  *ext = *(struct pdr_ext *) ext_copy;
460
461  intern->adr           = ecoff_get_off (abfd, (bfd_byte *)ext->p_adr);
462  intern->isym          = bfd_h_get_32 (abfd, (bfd_byte *)ext->p_isym);
463  intern->iline         = bfd_h_get_32 (abfd, (bfd_byte *)ext->p_iline);
464  intern->regmask       = bfd_h_get_32 (abfd, (bfd_byte *)ext->p_regmask);
465  intern->regoffset     = bfd_h_get_signed_32 (abfd,
466					       (bfd_byte *)ext->p_regoffset);
467  intern->iopt          = bfd_h_get_signed_32 (abfd, (bfd_byte *)ext->p_iopt);
468  intern->fregmask      = bfd_h_get_32 (abfd, (bfd_byte *)ext->p_fregmask);
469  intern->fregoffset    = bfd_h_get_signed_32 (abfd,
470					       (bfd_byte *)ext->p_fregoffset);
471  intern->frameoffset   = bfd_h_get_signed_32 (abfd,
472					       (bfd_byte *)ext->p_frameoffset);
473  intern->framereg      = bfd_h_get_16 (abfd, (bfd_byte *)ext->p_framereg);
474  intern->pcreg         = bfd_h_get_16 (abfd, (bfd_byte *)ext->p_pcreg);
475  intern->lnLow         = bfd_h_get_32 (abfd, (bfd_byte *)ext->p_lnLow);
476  intern->lnHigh        = bfd_h_get_32 (abfd, (bfd_byte *)ext->p_lnHigh);
477  intern->cbLineOffset  = ecoff_get_off (abfd, (bfd_byte *)ext->p_cbLineOffset);
478
479#ifdef TEST
480  if (memcmp ((char *)ext, (char *)intern, sizeof (*intern)) != 0)
481    abort ();
482#endif
483}
484
485/* Swap out the procedure descriptor record.  */
486
487static void
488ecoff_swap_pdr_out (abfd, intern_copy, ext_ptr)
489     bfd *abfd;
490     const PDR *intern_copy;
491     PTR ext_ptr;
492{
493  struct pdr_ext *ext = (struct pdr_ext *) ext_ptr;
494  PDR intern[1];
495
496  *intern = *intern_copy;	/* Make it reasonable to do in-place.  */
497
498  ecoff_put_off (abfd, intern->adr, (bfd_byte *)ext->p_adr);
499  bfd_h_put_32 (abfd, intern->isym, (bfd_byte *)ext->p_isym);
500  bfd_h_put_32 (abfd, intern->iline, (bfd_byte *)ext->p_iline);
501  bfd_h_put_32 (abfd, intern->regmask, (bfd_byte *)ext->p_regmask);
502  bfd_h_put_32 (abfd, intern->regoffset, (bfd_byte *)ext->p_regoffset);
503  bfd_h_put_32 (abfd, intern->iopt, (bfd_byte *)ext->p_iopt);
504  bfd_h_put_32 (abfd, intern->fregmask, (bfd_byte *)ext->p_fregmask);
505  bfd_h_put_32 (abfd, intern->fregoffset, (bfd_byte *)ext->p_fregoffset);
506  bfd_h_put_32 (abfd, intern->frameoffset, (bfd_byte *)ext->p_frameoffset);
507  bfd_h_put_16 (abfd, intern->framereg, (bfd_byte *)ext->p_framereg);
508  bfd_h_put_16 (abfd, intern->pcreg, (bfd_byte *)ext->p_pcreg);
509  bfd_h_put_32 (abfd, intern->lnLow, (bfd_byte *)ext->p_lnLow);
510  bfd_h_put_32 (abfd, intern->lnHigh, (bfd_byte *)ext->p_lnHigh);
511  ecoff_put_off (abfd, intern->cbLineOffset, (bfd_byte *)ext->p_cbLineOffset);
512
513#ifdef TEST
514  if (memcmp ((char *)ext, (char *)intern, sizeof (*intern)) != 0)
515    abort ();
516#endif
517}
518#endif /* MPW_C */
519
520/* Swap in a symbol record.  */
521
522static void
523ecoff_swap_sym_in (abfd, ext_copy, intern)
524     bfd *abfd;
525     PTR ext_copy;
526     SYMR *intern;
527{
528  struct sym_ext ext[1];
529
530  *ext = *(struct sym_ext *) ext_copy;
531
532  intern->iss           = bfd_h_get_32 (abfd, (bfd_byte *)ext->s_iss);
533  intern->value         = ecoff_get_off (abfd, (bfd_byte *)ext->s_value);
534
535  /* now the fun stuff...  */
536  if (bfd_header_big_endian (abfd)) {
537    intern->st          =  (ext->s_bits1[0] & SYM_BITS1_ST_BIG)
538					   >> SYM_BITS1_ST_SH_BIG;
539    intern->sc          = ((ext->s_bits1[0] & SYM_BITS1_SC_BIG)
540					   << SYM_BITS1_SC_SH_LEFT_BIG)
541			| ((ext->s_bits2[0] & SYM_BITS2_SC_BIG)
542					   >> SYM_BITS2_SC_SH_BIG);
543    intern->reserved    = 0 != (ext->s_bits2[0] & SYM_BITS2_RESERVED_BIG);
544    intern->index       = ((ext->s_bits2[0] & SYM_BITS2_INDEX_BIG)
545					   << SYM_BITS2_INDEX_SH_LEFT_BIG)
546			| (ext->s_bits3[0] << SYM_BITS3_INDEX_SH_LEFT_BIG)
547			| (ext->s_bits4[0] << SYM_BITS4_INDEX_SH_LEFT_BIG);
548  } else {
549    intern->st          =  (ext->s_bits1[0] & SYM_BITS1_ST_LITTLE)
550					   >> SYM_BITS1_ST_SH_LITTLE;
551    intern->sc          = ((ext->s_bits1[0] & SYM_BITS1_SC_LITTLE)
552					   >> SYM_BITS1_SC_SH_LITTLE)
553			| ((ext->s_bits2[0] & SYM_BITS2_SC_LITTLE)
554					   << SYM_BITS2_SC_SH_LEFT_LITTLE);
555    intern->reserved    = 0 != (ext->s_bits2[0] & SYM_BITS2_RESERVED_LITTLE);
556    intern->index       = ((ext->s_bits2[0] & SYM_BITS2_INDEX_LITTLE)
557					   >> SYM_BITS2_INDEX_SH_LITTLE)
558			| (ext->s_bits3[0] << SYM_BITS3_INDEX_SH_LEFT_LITTLE)
559			| ((unsigned int) ext->s_bits4[0]
560			   << SYM_BITS4_INDEX_SH_LEFT_LITTLE);
561  }
562
563#ifdef TEST
564  if (memcmp ((char *)ext, (char *)intern, sizeof (*intern)) != 0)
565    abort ();
566#endif
567}
568
569/* Swap out a symbol record.  */
570
571static void
572ecoff_swap_sym_out (abfd, intern_copy, ext_ptr)
573     bfd *abfd;
574     const SYMR *intern_copy;
575     PTR ext_ptr;
576{
577  struct sym_ext *ext = (struct sym_ext *) ext_ptr;
578  SYMR intern[1];
579
580  *intern = *intern_copy;	/* Make it reasonable to do in-place.  */
581
582  bfd_h_put_32 (abfd, intern->iss, (bfd_byte *)ext->s_iss);
583  ecoff_put_off (abfd, intern->value, (bfd_byte *)ext->s_value);
584
585  /* now the fun stuff...  */
586  if (bfd_header_big_endian (abfd)) {
587    ext->s_bits1[0] = (((intern->st << SYM_BITS1_ST_SH_BIG)
588			& SYM_BITS1_ST_BIG)
589		       | ((intern->sc >> SYM_BITS1_SC_SH_LEFT_BIG)
590			  & SYM_BITS1_SC_BIG));
591    ext->s_bits2[0] = (((intern->sc << SYM_BITS2_SC_SH_BIG)
592			& SYM_BITS2_SC_BIG)
593		       | (intern->reserved ? SYM_BITS2_RESERVED_BIG : 0)
594		       | ((intern->index >> SYM_BITS2_INDEX_SH_LEFT_BIG)
595			  & SYM_BITS2_INDEX_BIG));
596    ext->s_bits3[0] = (intern->index >> SYM_BITS3_INDEX_SH_LEFT_BIG) & 0xff;
597    ext->s_bits4[0] = (intern->index >> SYM_BITS4_INDEX_SH_LEFT_BIG) & 0xff;
598  } else {
599    ext->s_bits1[0] = (((intern->st << SYM_BITS1_ST_SH_LITTLE)
600			& SYM_BITS1_ST_LITTLE)
601		       | ((intern->sc << SYM_BITS1_SC_SH_LITTLE)
602			  & SYM_BITS1_SC_LITTLE));
603    ext->s_bits2[0] = (((intern->sc >> SYM_BITS2_SC_SH_LEFT_LITTLE)
604			& SYM_BITS2_SC_LITTLE)
605		       | (intern->reserved ? SYM_BITS2_RESERVED_LITTLE : 0)
606		       | ((intern->index << SYM_BITS2_INDEX_SH_LITTLE)
607			  & SYM_BITS2_INDEX_LITTLE));
608    ext->s_bits3[0] = (intern->index >> SYM_BITS3_INDEX_SH_LEFT_LITTLE) & 0xff;
609    ext->s_bits4[0] = (intern->index >> SYM_BITS4_INDEX_SH_LEFT_LITTLE) & 0xff;
610  }
611
612#ifdef TEST
613  if (memcmp ((char *)ext, (char *)intern, sizeof (*intern)) != 0)
614    abort ();
615#endif
616}
617
618/* Swap in an external symbol record.  */
619
620static void
621ecoff_swap_ext_in (abfd, ext_copy, intern)
622     bfd *abfd;
623     PTR ext_copy;
624     EXTR *intern;
625{
626  struct ext_ext ext[1];
627
628  *ext = *(struct ext_ext *) ext_copy;
629
630  /* now the fun stuff...  */
631  if (bfd_header_big_endian (abfd)) {
632    intern->jmptbl      = 0 != (ext->es_bits1[0] & EXT_BITS1_JMPTBL_BIG);
633    intern->cobol_main  = 0 != (ext->es_bits1[0] & EXT_BITS1_COBOL_MAIN_BIG);
634    intern->weakext     = 0 != (ext->es_bits1[0] & EXT_BITS1_WEAKEXT_BIG);
635  } else {
636    intern->jmptbl      = 0 != (ext->es_bits1[0] & EXT_BITS1_JMPTBL_LITTLE);
637    intern->cobol_main  = 0 != (ext->es_bits1[0] & EXT_BITS1_COBOL_MAIN_LITTLE);
638    intern->weakext     = 0 != (ext->es_bits1[0] & EXT_BITS1_WEAKEXT_LITTLE);
639  }
640  intern->reserved = 0;
641
642#if defined (ECOFF_32) || defined (ECOFF_SIGNED_32)
643  intern->ifd           = bfd_h_get_signed_16 (abfd, (bfd_byte *)ext->es_ifd);
644#endif
645#if defined (ECOFF_64) || defined (ECOFF_SIGNED_64)
646  intern->ifd           = bfd_h_get_signed_32 (abfd, (bfd_byte *)ext->es_ifd);
647#endif
648
649  ecoff_swap_sym_in (abfd, &ext->es_asym, &intern->asym);
650
651#ifdef TEST
652  if (memcmp ((char *)ext, (char *)intern, sizeof (*intern)) != 0)
653    abort ();
654#endif
655}
656
657/* Swap out an external symbol record.  */
658
659static void
660ecoff_swap_ext_out (abfd, intern_copy, ext_ptr)
661     bfd *abfd;
662     const EXTR *intern_copy;
663     PTR ext_ptr;
664{
665  struct ext_ext *ext = (struct ext_ext *) ext_ptr;
666  EXTR intern[1];
667
668  *intern = *intern_copy;	/* Make it reasonable to do in-place.  */
669
670  /* now the fun stuff...  */
671  if (bfd_header_big_endian (abfd)) {
672    ext->es_bits1[0] = ((intern->jmptbl ? EXT_BITS1_JMPTBL_BIG : 0)
673			| (intern->cobol_main ? EXT_BITS1_COBOL_MAIN_BIG : 0)
674			| (intern->weakext ? EXT_BITS1_WEAKEXT_BIG : 0));
675    ext->es_bits2[0] = 0;
676#if defined (ECOFF_64) || defined (ECOFF_SIGNED_64)
677    ext->es_bits2[1] = 0;
678    ext->es_bits2[2] = 0;
679#endif
680  } else {
681    ext->es_bits1[0] = ((intern->jmptbl ? EXT_BITS1_JMPTBL_LITTLE : 0)
682			| (intern->cobol_main ? EXT_BITS1_COBOL_MAIN_LITTLE : 0)
683			| (intern->weakext ? EXT_BITS1_WEAKEXT_LITTLE : 0));
684    ext->es_bits2[0] = 0;
685#if defined (ECOFF_64) || defined (ECOFF_SIGNED_64)
686    ext->es_bits2[1] = 0;
687    ext->es_bits2[2] = 0;
688#endif
689  }
690
691#if defined (ECOFF_32) || defined (ECOFF_SIGNED_32)
692  bfd_h_put_signed_16 (abfd, intern->ifd, (bfd_byte *)ext->es_ifd);
693#endif
694#if defined (ECOFF_64) || defined (ECOFF_SIGNED_64)
695  bfd_h_put_signed_32 (abfd, intern->ifd, (bfd_byte *)ext->es_ifd);
696#endif
697
698  ecoff_swap_sym_out (abfd, &intern->asym, &ext->es_asym);
699
700#ifdef TEST
701  if (memcmp ((char *)ext, (char *)intern, sizeof (*intern)) != 0)
702    abort ();
703#endif
704}
705
706/* Swap in a relative file descriptor.  */
707
708static void
709ecoff_swap_rfd_in (abfd, ext_ptr, intern)
710     bfd *abfd;
711     PTR ext_ptr;
712     RFDT *intern;
713{
714  struct rfd_ext *ext = (struct rfd_ext *) ext_ptr;
715
716  *intern = bfd_h_get_32 (abfd, (bfd_byte *)ext->rfd);
717
718#ifdef TEST
719  if (memcmp ((char *)ext, (char *)intern, sizeof (*intern)) != 0)
720    abort ();
721#endif
722}
723
724/* Swap out a relative file descriptor.  */
725
726static void
727ecoff_swap_rfd_out (abfd, intern, ext_ptr)
728     bfd *abfd;
729     const RFDT *intern;
730     PTR ext_ptr;
731{
732  struct rfd_ext *ext = (struct rfd_ext *) ext_ptr;
733
734  bfd_h_put_32 (abfd, *intern, (bfd_byte *)ext->rfd);
735
736#ifdef TEST
737  if (memcmp ((char *)ext, (char *)intern, sizeof (*intern)) != 0)
738    abort ();
739#endif
740}
741
742/* Swap in an optimization symbol.  */
743
744static void
745ecoff_swap_opt_in (abfd, ext_copy, intern)
746     bfd *abfd;
747     PTR ext_copy;
748     OPTR *intern;
749{
750  struct opt_ext ext[1];
751
752  *ext = *(struct opt_ext *) ext_copy;
753
754  if (bfd_header_big_endian (abfd))
755    {
756      intern->ot = ext->o_bits1[0];
757      intern->value = (((unsigned int) ext->o_bits2[0]
758			<< OPT_BITS2_VALUE_SH_LEFT_BIG)
759		       | ((unsigned int) ext->o_bits3[0]
760			  << OPT_BITS2_VALUE_SH_LEFT_BIG)
761		       | ((unsigned int) ext->o_bits4[0]
762			  << OPT_BITS2_VALUE_SH_LEFT_BIG));
763    }
764  else
765    {
766      intern->ot = ext->o_bits1[0];
767      intern->value = ((ext->o_bits2[0] << OPT_BITS2_VALUE_SH_LEFT_LITTLE)
768		       | (ext->o_bits3[0] << OPT_BITS2_VALUE_SH_LEFT_LITTLE)
769		       | (ext->o_bits4[0] << OPT_BITS2_VALUE_SH_LEFT_LITTLE));
770    }
771
772  _bfd_ecoff_swap_rndx_in (bfd_header_big_endian (abfd),
773			   &ext->o_rndx, &intern->rndx);
774
775  intern->offset = bfd_h_get_32 (abfd, (bfd_byte *) ext->o_offset);
776
777#ifdef TEST
778  if (memcmp ((char *)ext, (char *)intern, sizeof (*intern)) != 0)
779    abort ();
780#endif
781}
782
783/* Swap out an optimization symbol.  */
784
785static void
786ecoff_swap_opt_out (abfd, intern_copy, ext_ptr)
787     bfd *abfd;
788     const OPTR *intern_copy;
789     PTR ext_ptr;
790{
791  struct opt_ext *ext = (struct opt_ext *) ext_ptr;
792  OPTR intern[1];
793
794  *intern = *intern_copy;	/* Make it reasonable to do in-place.  */
795
796  if (bfd_header_big_endian (abfd))
797    {
798      ext->o_bits1[0] = intern->ot;
799      ext->o_bits2[0] = intern->value >> OPT_BITS2_VALUE_SH_LEFT_BIG;
800      ext->o_bits3[0] = intern->value >> OPT_BITS3_VALUE_SH_LEFT_BIG;
801      ext->o_bits4[0] = intern->value >> OPT_BITS4_VALUE_SH_LEFT_BIG;
802    }
803  else
804    {
805      ext->o_bits1[0] = intern->ot;
806      ext->o_bits2[0] = intern->value >> OPT_BITS2_VALUE_SH_LEFT_LITTLE;
807      ext->o_bits3[0] = intern->value >> OPT_BITS3_VALUE_SH_LEFT_LITTLE;
808      ext->o_bits4[0] = intern->value >> OPT_BITS4_VALUE_SH_LEFT_LITTLE;
809    }
810
811  _bfd_ecoff_swap_rndx_out (bfd_header_big_endian (abfd),
812			    &intern->rndx, &ext->o_rndx);
813
814  bfd_h_put_32 (abfd, intern->value, (bfd_byte *) ext->o_offset);
815
816#ifdef TEST
817  if (memcmp ((char *)ext, (char *)intern, sizeof (*intern)) != 0)
818    abort ();
819#endif
820}
821
822/* Swap in a dense number.  */
823
824static void
825ecoff_swap_dnr_in (abfd, ext_copy, intern)
826     bfd *abfd;
827     PTR ext_copy;
828     DNR *intern;
829{
830  struct dnr_ext ext[1];
831
832  *ext = *(struct dnr_ext *) ext_copy;
833
834  intern->rfd = bfd_h_get_32 (abfd, (bfd_byte *) ext->d_rfd);
835  intern->index = bfd_h_get_32 (abfd, (bfd_byte *) ext->d_index);
836
837#ifdef TEST
838  if (memcmp ((char *)ext, (char *)intern, sizeof (*intern)) != 0)
839    abort ();
840#endif
841}
842
843/* Swap out a dense number.  */
844
845static void
846ecoff_swap_dnr_out (abfd, intern_copy, ext_ptr)
847     bfd *abfd;
848     const DNR *intern_copy;
849     PTR ext_ptr;
850{
851  struct dnr_ext *ext = (struct dnr_ext *) ext_ptr;
852  DNR intern[1];
853
854  *intern = *intern_copy;	/* Make it reasonable to do in-place.  */
855
856  bfd_h_put_32 (abfd, intern->rfd, (bfd_byte *) ext->d_rfd);
857  bfd_h_put_32 (abfd, intern->index, (bfd_byte *) ext->d_index);
858
859#ifdef TEST
860  if (memcmp ((char *)ext, (char *)intern, sizeof (*intern)) != 0)
861    abort ();
862#endif
863}
864