1 /* coff-msym.c: Byte-swap a symbol table in MIPS' format (Third-Eye, `ecoff').
2 Copyright 1992 Free Software Foundation, Inc.
4 This file is part of BFD, the Binary File Descriptor library.
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
20 /* These routines are not yet called from BFD. They are called from
21 the MIPS symbol reading code in GDB. However, they are in the BFD
22 library because they will eventually be useful if and when BFD
23 supports reading or writing of MIPS symbol tables.
25 FLASH! FIXME! Unfortunately MIPS has these *%&%&$#^# copyrighted
26 include files defining the symbol format (which I've been politely
27 asking them to release for public use for about a year now). Since
28 this function can only compile if these include files are available,
29 the config files for MIPS-based hosts configure the Makefile so that
30 this file will be compiled only if on a MIPS-based host. FIXME!
32 The routines in this file convert the external representation of
33 ECOFF symbol tables to the internal (usual struct) representation.
34 On a machine with the same byte-order and the same basic type
35 sizes and alignments as a MIPS machine, this is a no-op.
36 If the symbol TEST is defined when this file is compiled, a comparison
37 is made to ensure that, in fact, the output is bit-for-bit the same as
38 the input. Of course, this symbol should only be defined when
39 deliberately testing the code on a machine with the proper byte sex
44 #define LANGUAGE_C /* Wierd MIPS crap */
45 #include "sym.h" /* MIPS symbols */
46 #include "symconst.h" /* MIPS symbols */
47 #include "coff/ecoff-ext.h" /* ECOFF external struct defns */
50 ecoff_swap_hdr_in (abfd
, ext_copy
, intern
)
52 struct hdr_ext
*ext_copy
;
55 struct hdr_ext ext
[1];
59 intern
->magic
= bfd_h_get_16 (abfd
, (bfd_byte
*)ext
->h_magic
);
60 intern
->vstamp
= bfd_h_get_16 (abfd
, (bfd_byte
*)ext
->h_vstamp
);
61 intern
->ilineMax
= bfd_h_get_32 (abfd
, (bfd_byte
*)ext
->h_ilineMax
);
62 intern
->cbLine
= bfd_h_get_32 (abfd
, (bfd_byte
*)ext
->h_cbLine
);
63 intern
->cbLineOffset
= bfd_h_get_32 (abfd
, (bfd_byte
*)ext
->h_cbLineOffset
);
64 intern
->idnMax
= bfd_h_get_32 (abfd
, (bfd_byte
*)ext
->h_idnMax
);
65 intern
->cbDnOffset
= bfd_h_get_32 (abfd
, (bfd_byte
*)ext
->h_cbDnOffset
);
66 intern
->ipdMax
= bfd_h_get_32 (abfd
, (bfd_byte
*)ext
->h_ipdMax
);
67 intern
->cbPdOffset
= bfd_h_get_32 (abfd
, (bfd_byte
*)ext
->h_cbPdOffset
);
68 intern
->isymMax
= bfd_h_get_32 (abfd
, (bfd_byte
*)ext
->h_isymMax
);
69 intern
->cbSymOffset
= bfd_h_get_32 (abfd
, (bfd_byte
*)ext
->h_cbSymOffset
);
70 intern
->ioptMax
= bfd_h_get_32 (abfd
, (bfd_byte
*)ext
->h_ioptMax
);
71 intern
->cbOptOffset
= bfd_h_get_32 (abfd
, (bfd_byte
*)ext
->h_cbOptOffset
);
72 intern
->iauxMax
= bfd_h_get_32 (abfd
, (bfd_byte
*)ext
->h_iauxMax
);
73 intern
->cbAuxOffset
= bfd_h_get_32 (abfd
, (bfd_byte
*)ext
->h_cbAuxOffset
);
74 intern
->issMax
= bfd_h_get_32 (abfd
, (bfd_byte
*)ext
->h_issMax
);
75 intern
->cbSsOffset
= bfd_h_get_32 (abfd
, (bfd_byte
*)ext
->h_cbSsOffset
);
76 intern
->issExtMax
= bfd_h_get_32 (abfd
, (bfd_byte
*)ext
->h_issExtMax
);
77 intern
->cbSsExtOffset
= bfd_h_get_32 (abfd
, (bfd_byte
*)ext
->h_cbSsExtOffset
);
78 intern
->ifdMax
= bfd_h_get_32 (abfd
, (bfd_byte
*)ext
->h_ifdMax
);
79 intern
->cbFdOffset
= bfd_h_get_32 (abfd
, (bfd_byte
*)ext
->h_cbFdOffset
);
80 intern
->crfd
= bfd_h_get_32 (abfd
, (bfd_byte
*)ext
->h_crfd
);
81 intern
->cbRfdOffset
= bfd_h_get_32 (abfd
, (bfd_byte
*)ext
->h_cbRfdOffset
);
82 intern
->iextMax
= bfd_h_get_32 (abfd
, (bfd_byte
*)ext
->h_iextMax
);
83 intern
->cbExtOffset
= bfd_h_get_32 (abfd
, (bfd_byte
*)ext
->h_cbExtOffset
);
86 if (memcmp ((char *)ext
, (char *)intern
, sizeof (*intern
)) != 0)
91 /* Swap in the file descriptor record. */
94 ecoff_swap_fdr_in (abfd
, ext_copy
, intern
)
96 struct fdr_ext
*ext_copy
;
99 struct fdr_ext ext
[1];
101 *ext
= *ext_copy
; /* Make it reasonable to do in-place. */
103 intern
->adr
= bfd_h_get_32 (abfd
, (bfd_byte
*)ext
->f_adr
);
104 intern
->rss
= bfd_h_get_32 (abfd
, (bfd_byte
*)ext
->f_rss
);
105 intern
->issBase
= bfd_h_get_32 (abfd
, (bfd_byte
*)ext
->f_issBase
);
106 intern
->cbSs
= bfd_h_get_32 (abfd
, (bfd_byte
*)ext
->f_cbSs
);
107 intern
->isymBase
= bfd_h_get_32 (abfd
, (bfd_byte
*)ext
->f_isymBase
);
108 intern
->csym
= bfd_h_get_32 (abfd
, (bfd_byte
*)ext
->f_csym
);
109 intern
->ilineBase
= bfd_h_get_32 (abfd
, (bfd_byte
*)ext
->f_ilineBase
);
110 intern
->cline
= bfd_h_get_32 (abfd
, (bfd_byte
*)ext
->f_cline
);
111 intern
->ioptBase
= bfd_h_get_32 (abfd
, (bfd_byte
*)ext
->f_ioptBase
);
112 intern
->copt
= bfd_h_get_32 (abfd
, (bfd_byte
*)ext
->f_copt
);
113 intern
->ipdFirst
= bfd_h_get_16 (abfd
, (bfd_byte
*)ext
->f_ipdFirst
);
114 intern
->cpd
= bfd_h_get_16 (abfd
, (bfd_byte
*)ext
->f_cpd
);
115 intern
->iauxBase
= bfd_h_get_32 (abfd
, (bfd_byte
*)ext
->f_iauxBase
);
116 intern
->caux
= bfd_h_get_32 (abfd
, (bfd_byte
*)ext
->f_caux
);
117 intern
->rfdBase
= bfd_h_get_32 (abfd
, (bfd_byte
*)ext
->f_rfdBase
);
118 intern
->crfd
= bfd_h_get_32 (abfd
, (bfd_byte
*)ext
->f_crfd
);
120 /* now the fun stuff... */
121 if (abfd
->xvec
->header_byteorder_big_p
!= false) {
122 intern
->lang
= (ext
->f_bits1
[0] & FDR_BITS1_LANG_BIG
)
123 >> FDR_BITS1_LANG_SH_BIG
;
124 intern
->fMerge
= 0 != (ext
->f_bits1
[0] & FDR_BITS1_FMERGE_BIG
);
125 intern
->fReadin
= 0 != (ext
->f_bits1
[0] & FDR_BITS1_FREADIN_BIG
);
126 intern
->fBigendian
= 0 != (ext
->f_bits1
[0] & FDR_BITS1_FBIGENDIAN_BIG
);
127 intern
->glevel
= (ext
->f_bits2
[0] & FDR_BITS2_GLEVEL_BIG
)
128 >> FDR_BITS2_GLEVEL_SH_BIG
;
129 /* intern->reserved we ignore. */
131 intern
->lang
= (ext
->f_bits1
[0] & FDR_BITS1_LANG_LITTLE
)
132 >> FDR_BITS1_LANG_SH_LITTLE
;
133 intern
->fMerge
= 0 != (ext
->f_bits1
[0] & FDR_BITS1_FMERGE_LITTLE
);
134 intern
->fReadin
= 0 != (ext
->f_bits1
[0] & FDR_BITS1_FREADIN_LITTLE
);
135 intern
->fBigendian
= 0 != (ext
->f_bits1
[0] & FDR_BITS1_FBIGENDIAN_LITTLE
);
136 intern
->glevel
= (ext
->f_bits2
[0] & FDR_BITS2_GLEVEL_LITTLE
)
137 >> FDR_BITS2_GLEVEL_SH_LITTLE
;
138 /* intern->reserved we ignore. */
141 intern
->cbLineOffset
= bfd_h_get_32 (abfd
, (bfd_byte
*)ext
->f_cbLineOffset
);
142 intern
->cbLine
= bfd_h_get_32 (abfd
, (bfd_byte
*)ext
->f_cbLine
);
145 if (memcmp ((char *)ext
, (char *)intern
, sizeof (*intern
)) != 0)
152 /* Swap in the procedure descriptor record. */
155 ecoff_swap_pdr_in (abfd
, ext_copy
, intern
)
157 struct pdr_ext
*ext_copy
;
160 struct pdr_ext ext
[1];
162 *ext
= *ext_copy
; /* Make it reasonable to do in-place. */
164 intern
->adr
= bfd_h_get_32 (abfd
, (bfd_byte
*)ext
->p_adr
);
165 intern
->isym
= bfd_h_get_32 (abfd
, (bfd_byte
*)ext
->p_isym
);
166 intern
->iline
= bfd_h_get_32 (abfd
, (bfd_byte
*)ext
->p_iline
);
167 intern
->regmask
= bfd_h_get_32 (abfd
, (bfd_byte
*)ext
->p_regmask
);
168 intern
->regoffset
= bfd_h_get_32 (abfd
, (bfd_byte
*)ext
->p_regoffset
);
169 intern
->iopt
= bfd_h_get_32 (abfd
, (bfd_byte
*)ext
->p_iopt
);
170 intern
->fregmask
= bfd_h_get_32 (abfd
, (bfd_byte
*)ext
->p_fregmask
);
171 intern
->fregoffset
= bfd_h_get_32 (abfd
, (bfd_byte
*)ext
->p_fregoffset
);
172 intern
->frameoffset
= bfd_h_get_32 (abfd
, (bfd_byte
*)ext
->p_frameoffset
);
173 intern
->framereg
= bfd_h_get_16 (abfd
, (bfd_byte
*)ext
->p_framereg
);
174 intern
->pcreg
= bfd_h_get_16 (abfd
, (bfd_byte
*)ext
->p_pcreg
);
175 intern
->lnLow
= bfd_h_get_32 (abfd
, (bfd_byte
*)ext
->p_lnLow
);
176 intern
->lnHigh
= bfd_h_get_32 (abfd
, (bfd_byte
*)ext
->p_lnHigh
);
177 intern
->cbLineOffset
= bfd_h_get_32 (abfd
, (bfd_byte
*)ext
->p_cbLineOffset
);
180 if (memcmp ((char *)ext
, (char *)intern
, sizeof (*intern
)) != 0)
186 /* Swap in a symbol record. */
189 ecoff_swap_sym_in (abfd
, ext_copy
, intern
)
191 struct sym_ext
*ext_copy
;
194 struct sym_ext ext
[1];
196 *ext
= *ext_copy
; /* Make it reasonable to do in-place. */
198 intern
->iss
= bfd_h_get_32 (abfd
, (bfd_byte
*)ext
->s_iss
);
199 intern
->value
= bfd_h_get_32 (abfd
, (bfd_byte
*)ext
->s_value
);
201 /* now the fun stuff... */
202 if (abfd
->xvec
->header_byteorder_big_p
!= false) {
203 intern
->st
= (ext
->s_bits1
[0] & SYM_BITS1_ST_BIG
)
204 >> SYM_BITS1_ST_SH_BIG
;
205 intern
->sc
= ((ext
->s_bits1
[0] & SYM_BITS1_SC_BIG
)
206 << SYM_BITS1_SC_SH_LEFT_BIG
)
207 | ((ext
->s_bits2
[0] & SYM_BITS2_SC_BIG
)
208 >> SYM_BITS2_SC_SH_BIG
);
209 intern
->reserved
= 0 != (ext
->s_bits2
[0] & SYM_BITS2_RESERVED_BIG
);
210 intern
->index
= ((ext
->s_bits2
[0] & SYM_BITS2_INDEX_BIG
)
211 << SYM_BITS2_INDEX_SH_LEFT_BIG
)
212 | (ext
->s_bits3
[0] << SYM_BITS3_INDEX_SH_LEFT_BIG
)
213 | (ext
->s_bits4
[0] << SYM_BITS4_INDEX_SH_LEFT_BIG
);
215 intern
->st
= (ext
->s_bits1
[0] & SYM_BITS1_ST_LITTLE
)
216 >> SYM_BITS1_ST_SH_LITTLE
;
217 intern
->sc
= ((ext
->s_bits1
[0] & SYM_BITS1_SC_LITTLE
)
218 >> SYM_BITS1_SC_SH_LITTLE
)
219 | ((ext
->s_bits2
[0] & SYM_BITS2_SC_LITTLE
)
220 << SYM_BITS2_SC_SH_LEFT_LITTLE
);
221 intern
->reserved
= 0 != (ext
->s_bits2
[0] & SYM_BITS2_RESERVED_LITTLE
);
222 intern
->index
= ((ext
->s_bits2
[0] & SYM_BITS2_INDEX_LITTLE
)
223 >> SYM_BITS2_INDEX_SH_LITTLE
)
224 | (ext
->s_bits3
[0] << SYM_BITS3_INDEX_SH_LEFT_LITTLE
)
225 | (ext
->s_bits4
[0] << SYM_BITS4_INDEX_SH_LEFT_LITTLE
);
229 if (memcmp ((char *)ext
, (char *)intern
, sizeof (*intern
)) != 0)
235 /* Swap in an external symbol record. */
238 ecoff_swap_ext_in (abfd
, ext_copy
, intern
)
240 struct ext_ext
*ext_copy
;
243 struct ext_ext ext
[1];
245 *ext
= *ext_copy
; /* Make it reasonable to do in-place. */
247 /* now the fun stuff... */
248 if (abfd
->xvec
->header_byteorder_big_p
!= false) {
249 intern
->jmptbl
= 0 != (ext
->es_bits1
[0] & EXT_BITS1_JMPTBL_BIG
);
250 intern
->cobol_main
= 0 != (ext
->es_bits1
[0] & EXT_BITS1_COBOL_MAIN_BIG
);
252 intern
->jmptbl
= 0 != (ext
->es_bits1
[0] & EXT_BITS1_JMPTBL_LITTLE
);
253 intern
->cobol_main
= 0 != (ext
->es_bits1
[0] & EXT_BITS1_COBOL_MAIN_LITTLE
);
256 intern
->ifd
= bfd_h_get_16 (abfd
, (bfd_byte
*)ext
->es_ifd
);
257 ecoff_swap_sym_in (abfd
, &ext
->es_asym
, &intern
->asym
);
260 if (memcmp ((char *)ext
, (char *)intern
, sizeof (*intern
)) != 0)
265 /* Swap in a type information record.
266 BIGEND says whether AUX symbols are big-endian or little-endian; this
267 info comes from the file header record (fh-fBigendian). */
270 ecoff_swap_tir_in (bigend
, ext_copy
, intern
)
272 struct tir_ext
*ext_copy
;
275 struct tir_ext ext
[1];
277 *ext
= *ext_copy
; /* Make it reasonable to do in-place. */
279 /* now the fun stuff... */
281 intern
->fBitfield
= 0 != (ext
->t_bits1
[0] & TIR_BITS1_FBITFIELD_BIG
);
282 intern
->continued
= 0 != (ext
->t_bits1
[0] & TIR_BITS1_CONTINUED_BIG
);
283 intern
->bt
= (ext
->t_bits1
[0] & TIR_BITS1_BT_BIG
)
284 >> TIR_BITS1_BT_SH_BIG
;
285 intern
->tq4
= (ext
->t_tq45
[0] & TIR_BITS_TQ4_BIG
)
286 >> TIR_BITS_TQ4_SH_BIG
;
287 intern
->tq5
= (ext
->t_tq45
[0] & TIR_BITS_TQ5_BIG
)
288 >> TIR_BITS_TQ5_SH_BIG
;
289 intern
->tq0
= (ext
->t_tq01
[0] & TIR_BITS_TQ0_BIG
)
290 >> TIR_BITS_TQ0_SH_BIG
;
291 intern
->tq1
= (ext
->t_tq01
[0] & TIR_BITS_TQ1_BIG
)
292 >> TIR_BITS_TQ1_SH_BIG
;
293 intern
->tq2
= (ext
->t_tq23
[0] & TIR_BITS_TQ2_BIG
)
294 >> TIR_BITS_TQ2_SH_BIG
;
295 intern
->tq3
= (ext
->t_tq23
[0] & TIR_BITS_TQ3_BIG
)
296 >> TIR_BITS_TQ3_SH_BIG
;
298 intern
->fBitfield
= 0 != (ext
->t_bits1
[0] & TIR_BITS1_FBITFIELD_LITTLE
);
299 intern
->continued
= 0 != (ext
->t_bits1
[0] & TIR_BITS1_CONTINUED_LITTLE
);
300 intern
->bt
= (ext
->t_bits1
[0] & TIR_BITS1_BT_LITTLE
)
301 >> TIR_BITS1_BT_SH_LITTLE
;
302 intern
->tq4
= (ext
->t_tq45
[0] & TIR_BITS_TQ4_LITTLE
)
303 >> TIR_BITS_TQ4_SH_LITTLE
;
304 intern
->tq5
= (ext
->t_tq45
[0] & TIR_BITS_TQ5_LITTLE
)
305 >> TIR_BITS_TQ5_SH_LITTLE
;
306 intern
->tq0
= (ext
->t_tq01
[0] & TIR_BITS_TQ0_LITTLE
)
307 >> TIR_BITS_TQ0_SH_LITTLE
;
308 intern
->tq1
= (ext
->t_tq01
[0] & TIR_BITS_TQ1_LITTLE
)
309 >> TIR_BITS_TQ1_SH_LITTLE
;
310 intern
->tq2
= (ext
->t_tq23
[0] & TIR_BITS_TQ2_LITTLE
)
311 >> TIR_BITS_TQ2_SH_LITTLE
;
312 intern
->tq3
= (ext
->t_tq23
[0] & TIR_BITS_TQ3_LITTLE
)
313 >> TIR_BITS_TQ3_SH_LITTLE
;
317 if (memcmp ((char *)ext
, (char *)intern
, sizeof (*intern
)) != 0)
322 /* Swap in a relative symbol record. BIGEND says whether it is in
323 big-endian or little-endian format.*/
326 ecoff_swap_rndx_in (bigend
, ext_copy
, intern
)
328 struct rndx_ext
*ext_copy
;
331 struct rndx_ext ext
[1];
333 *ext
= *ext_copy
; /* Make it reasonable to do in-place. */
335 /* now the fun stuff... */
337 intern
->rfd
= (ext
->r_bits
[0] << RNDX_BITS0_RFD_SH_LEFT_BIG
)
338 | ((ext
->r_bits
[1] & RNDX_BITS1_RFD_BIG
)
339 >> RNDX_BITS1_RFD_SH_BIG
);
340 intern
->index
= ((ext
->r_bits
[1] & RNDX_BITS1_INDEX_BIG
)
341 << RNDX_BITS1_INDEX_SH_LEFT_BIG
)
342 | (ext
->r_bits
[2] << RNDX_BITS2_INDEX_SH_LEFT_BIG
)
343 | (ext
->r_bits
[3] << RNDX_BITS3_INDEX_SH_LEFT_BIG
);
345 intern
->rfd
= (ext
->r_bits
[0] << RNDX_BITS0_RFD_SH_LEFT_LITTLE
)
346 | ((ext
->r_bits
[1] & RNDX_BITS1_RFD_LITTLE
)
347 << RNDX_BITS1_RFD_SH_LEFT_LITTLE
);
348 intern
->index
= ((ext
->r_bits
[1] & RNDX_BITS1_INDEX_LITTLE
)
349 >> RNDX_BITS1_INDEX_SH_LITTLE
)
350 | (ext
->r_bits
[2] << RNDX_BITS2_INDEX_SH_LEFT_LITTLE
)
351 | (ext
->r_bits
[3] << RNDX_BITS3_INDEX_SH_LEFT_LITTLE
);
355 if (memcmp ((char *)ext
, (char *)intern
, sizeof (*intern
)) != 0)
360 /* Swap in a relative file descriptor. */
363 ecoff_swap_rfd_in (abfd
, ext
, intern
)
369 *intern
= bfd_h_get_32 (abfd
, (bfd_byte
*)&ext
->rfd
);
372 if (memcmp ((char *)ext
, (char *)intern
, sizeof (*intern
)) != 0)