xref: /netbsd-src/external/gpl3/gdb/dist/bfd/ecoffswap.h (revision 230b95665bbd3a9d1a53658a36b1053f8382a519)
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 
69 extern void _bfd_ecoff_swap_tir_in
70   (int, const struct tir_ext *, TIR *);
71 extern void _bfd_ecoff_swap_tir_out
72   (int, const TIR *, struct tir_ext *);
73 extern void _bfd_ecoff_swap_rndx_in
74   (int, const struct rndx_ext *, RNDXR *);
75 extern void _bfd_ecoff_swap_rndx_out
76   (int, const RNDXR *, struct rndx_ext *);
77 
78 /* Prototypes for functions defined in this file.  */
79 
80 static void ecoff_swap_hdr_in (bfd *, void *, HDRR *);
81 static void ecoff_swap_hdr_out (bfd *, const HDRR *, void *);
82 static void ecoff_swap_fdr_in (bfd *, void *, FDR *);
83 static void ecoff_swap_fdr_out (bfd *, const FDR *, void *);
84 static void ecoff_swap_pdr_in (bfd *, void *, PDR *);
85 static void ecoff_swap_pdr_out (bfd *, const PDR *, void *);
86 static void ecoff_swap_sym_in (bfd *, void *, SYMR *);
87 static void ecoff_swap_sym_out (bfd *, const SYMR *, void *);
88 static void ecoff_swap_ext_in (bfd *, void *, EXTR *);
89 static void ecoff_swap_ext_out (bfd *, const EXTR *, void *);
90 static void ecoff_swap_rfd_in (bfd *, void *, RFDT *);
91 static void ecoff_swap_rfd_out (bfd *, const RFDT *, void *);
92 static void ecoff_swap_opt_in (bfd *, void *, OPTR *);
93 static void ecoff_swap_opt_out (bfd *, const OPTR *, void *);
94 static void ecoff_swap_dnr_in (bfd *, void *, DNR *);
95 static void ecoff_swap_dnr_out (bfd *, const DNR *, void *);
96 
97 /* Swap in the symbolic header.  */
98 
99 static void
100 ecoff_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 
140 static void
141 ecoff_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 
182 static void
183 ecoff_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 
250 static void
251 ecoff_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 
319 static void
320 ecoff_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 
381 static void
382 ecoff_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 
441 static void
442 ecoff_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 
495 static void
496 ecoff_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 
545 static void
546 ecoff_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 
584 static void
585 ecoff_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 
634 static void
635 ecoff_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 
649 static void
650 ecoff_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 
664 static void
665 ecoff_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 
702 static void
703 ecoff_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 
739 static void
740 ecoff_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 
757 static void
758 ecoff_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