1 /* Generic ECOFF swapping routines, for BFD.
2    Copyright (C) 1992-2016 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 
68 extern void _bfd_ecoff_swap_tir_in
69   (int, const struct tir_ext *, TIR *);
70 extern void _bfd_ecoff_swap_tir_out
71   (int, const TIR *, struct tir_ext *);
72 extern void _bfd_ecoff_swap_rndx_in
73   (int, const struct rndx_ext *, RNDXR *);
74 extern void _bfd_ecoff_swap_rndx_out
75   (int, const RNDXR *, struct rndx_ext *);
76 
77 /* Prototypes for functions defined in this file.  */
78 
79 static void ecoff_swap_hdr_in (bfd *, void *, HDRR *);
80 static void ecoff_swap_hdr_out (bfd *, const HDRR *, void *);
81 static void ecoff_swap_fdr_in (bfd *, void *, FDR *);
82 static void ecoff_swap_fdr_out (bfd *, const FDR *, void *);
83 static void ecoff_swap_pdr_in (bfd *, void *, PDR *);
84 static void ecoff_swap_pdr_out (bfd *, const PDR *, void *);
85 static void ecoff_swap_sym_in (bfd *, void *, SYMR *);
86 static void ecoff_swap_sym_out (bfd *, const SYMR *, void *);
87 static void ecoff_swap_ext_in (bfd *, void *, EXTR *);
88 static void ecoff_swap_ext_out (bfd *, const EXTR *, void *);
89 static void ecoff_swap_rfd_in (bfd *, void *, RFDT *);
90 static void ecoff_swap_rfd_out (bfd *, const RFDT *, void *);
91 static void ecoff_swap_opt_in (bfd *, void *, OPTR *);
92 static void ecoff_swap_opt_out (bfd *, const OPTR *, void *);
93 static void ecoff_swap_dnr_in (bfd *, void *, DNR *);
94 static void ecoff_swap_dnr_out (bfd *, const DNR *, void *);
95 
96 /* Swap in the symbolic header.  */
97 
98 static void
ecoff_swap_hdr_in(bfd * abfd,void * ext_copy,HDRR * intern)99 ecoff_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 
139 static void
ecoff_swap_hdr_out(bfd * abfd,const HDRR * intern_copy,void * ext_ptr)140 ecoff_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 
181 static void
ecoff_swap_fdr_in(bfd * abfd,void * ext_copy,FDR * intern)182 ecoff_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 
249 static void
ecoff_swap_fdr_out(bfd * abfd,const FDR * intern_copy,void * ext_ptr)250 ecoff_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 
318 static void
ecoff_swap_pdr_in(bfd * abfd,void * ext_copy,PDR * intern)319 ecoff_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 
380 static void
ecoff_swap_pdr_out(bfd * abfd,const PDR * intern_copy,void * ext_ptr)381 ecoff_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 
440 static void
ecoff_swap_sym_in(bfd * abfd,void * ext_copy,SYMR * intern)441 ecoff_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 
494 static void
ecoff_swap_sym_out(bfd * abfd,const SYMR * intern_copy,void * ext_ptr)495 ecoff_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 
544 static void
ecoff_swap_ext_in(bfd * abfd,void * ext_copy,EXTR * intern)545 ecoff_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 
583 static void
ecoff_swap_ext_out(bfd * abfd,const EXTR * intern_copy,void * ext_ptr)584 ecoff_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 
633 static void
ecoff_swap_rfd_in(bfd * abfd,void * ext_ptr,RFDT * intern)634 ecoff_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 
648 static void
ecoff_swap_rfd_out(bfd * abfd,const RFDT * intern,void * ext_ptr)649 ecoff_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 
663 static void
ecoff_swap_opt_in(bfd * abfd,void * ext_copy,OPTR * intern)664 ecoff_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 
701 static void
ecoff_swap_opt_out(bfd * abfd,const OPTR * intern_copy,void * ext_ptr)702 ecoff_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 
738 static void
ecoff_swap_dnr_in(bfd * abfd,void * ext_copy,DNR * intern)739 ecoff_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 
756 static void
ecoff_swap_dnr_out(bfd * abfd,const DNR * intern_copy,void * ext_ptr)757 ecoff_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