1/* ECOFF support on MIPS machines.
2   coff/ecoff.h must be included before this file.
3
4   Copyright 2001 Free Software Foundation, Inc.
5
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.
10
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.
15
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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
19
20#define DO_NOT_DEFINE_AOUTHDR
21#define L_LNNO_SIZE 4
22#include "coff/external.h"
23
24/* Magic numbers are defined in coff/ecoff.h.  */
25#define MIPS_ECOFF_BADMAG(x) (((x).f_magic!=MIPS_MAGIC_1) && \
26			      ((x).f_magic!=MIPS_MAGIC_LITTLE) &&\
27			      ((x).f_magic!=MIPS_MAGIC_BIG) && \
28			      ((x).f_magic!=MIPS_MAGIC_LITTLE2) && \
29			      ((x).f_magic!=MIPS_MAGIC_BIG2) && \
30			      ((x).f_magic!=MIPS_MAGIC_LITTLE3) && \
31			      ((x).f_magic!=MIPS_MAGIC_BIG3))
32
33
34/********************** AOUT "OPTIONAL HEADER" **********************/
35
36typedef struct external_aouthdr
37{
38  unsigned char magic[2];	/* type of file				*/
39  unsigned char	vstamp[2];	/* version stamp			*/
40  unsigned char	tsize[4];	/* text size in bytes, padded to FW bdry*/
41  unsigned char	dsize[4];	/* initialized data "  "		*/
42  unsigned char	bsize[4];	/* uninitialized data "   "		*/
43  unsigned char	entry[4];	/* entry pt.				*/
44  unsigned char text_start[4];	/* base of text used for this file */
45  unsigned char data_start[4];	/* base of data used for this file */
46  unsigned char bss_start[4];	/* base of bss used for this file */
47  unsigned char gprmask[4];	/* ?? */
48  unsigned char cprmask[4][4];	/* ?? */
49  unsigned char gp_value[4];	/* value for gp register */
50} AOUTHDR;
51
52/* compute size of a header */
53
54#define AOUTSZ 56
55#define AOUTHDRSZ 56
56
57/********************** RELOCATION DIRECTIVES **********************/
58
59struct external_reloc
60  {
61    unsigned char r_vaddr[4];
62    unsigned char r_bits[4];
63  };
64
65#define RELOC struct external_reloc
66#define RELSZ 8
67
68/* MIPS ECOFF uses a packed 8 byte format for relocs.  These constants
69   are used to unpack the r_bits field.  */
70
71#define RELOC_BITS0_SYMNDX_SH_LEFT_BIG		16
72#define RELOC_BITS0_SYMNDX_SH_LEFT_LITTLE	0
73
74#define RELOC_BITS1_SYMNDX_SH_LEFT_BIG		8
75#define RELOC_BITS1_SYMNDX_SH_LEFT_LITTLE	8
76
77#define RELOC_BITS2_SYMNDX_SH_LEFT_BIG		0
78#define RELOC_BITS2_SYMNDX_SH_LEFT_LITTLE	16
79
80/* Originally, ECOFF used four bits for the reloc type and had three
81   reserved bits.  Irix 4 added another bit for the reloc type, which
82   was easy because it was big endian and one of the spare bits became
83   the new most significant bit.  To make this also work for little
84   endian ECOFF, we need to wrap one of the reserved bits around to
85   become the most significant bit of the reloc type.  */
86#define RELOC_BITS3_TYPE_BIG			0x3E
87#define RELOC_BITS3_TYPE_SH_BIG			1
88#define RELOC_BITS3_TYPE_LITTLE			0x78
89#define RELOC_BITS3_TYPE_SH_LITTLE		3
90#define RELOC_BITS3_TYPEHI_LITTLE		0x04
91#define RELOC_BITS3_TYPEHI_SH_LITTLE		2
92
93#define RELOC_BITS3_EXTERN_BIG			0x01
94#define RELOC_BITS3_EXTERN_LITTLE		0x80
95
96/* The r_type field in a reloc is one of the following values.  I
97   don't know if any other values can appear.  These seem to be all
98   that occur in the Ultrix 4.2 libraries.  */
99#define MIPS_R_IGNORE	0
100#define MIPS_R_REFHALF	1
101#define MIPS_R_REFWORD	2
102#define MIPS_R_JMPADDR	3
103#define MIPS_R_REFHI	4
104#define MIPS_R_REFLO	5
105#define MIPS_R_GPREL	6
106#define MIPS_R_LITERAL	7
107
108/* FIXME: This relocation is used (internally only) to represent branches
109   when assembling.  It should never appear in output files, and
110   be removed.  (It used to be used for embedded-PIC support.)  */
111#define MIPS_R_PCREL16	12
112
113/********************** STABS **********************/
114
115#define MIPS_IS_STAB ECOFF_IS_STAB
116#define MIPS_MARK_STAB ECOFF_MARK_STAB
117#define MIPS_UNMARK_STAB ECOFF_UNMARK_STAB
118
119/********************** SYMBOLIC INFORMATION **********************/
120
121/* Written by John Gilmore.  */
122
123/* ECOFF uses COFF-like section structures, but its own symbol format.
124   This file defines the symbol format in fields whose size and alignment
125   will not vary on different host systems.  */
126
127/* File header as a set of bytes */
128
129struct hdr_ext
130{
131	unsigned char 	h_magic[2];
132	unsigned char	h_vstamp[2];
133	unsigned char	h_ilineMax[4];
134	unsigned char	h_cbLine[4];
135	unsigned char	h_cbLineOffset[4];
136	unsigned char	h_idnMax[4];
137	unsigned char	h_cbDnOffset[4];
138	unsigned char	h_ipdMax[4];
139	unsigned char	h_cbPdOffset[4];
140	unsigned char	h_isymMax[4];
141	unsigned char	h_cbSymOffset[4];
142	unsigned char	h_ioptMax[4];
143	unsigned char	h_cbOptOffset[4];
144	unsigned char	h_iauxMax[4];
145	unsigned char	h_cbAuxOffset[4];
146	unsigned char	h_issMax[4];
147	unsigned char	h_cbSsOffset[4];
148	unsigned char	h_issExtMax[4];
149	unsigned char	h_cbSsExtOffset[4];
150	unsigned char	h_ifdMax[4];
151	unsigned char	h_cbFdOffset[4];
152	unsigned char	h_crfd[4];
153	unsigned char	h_cbRfdOffset[4];
154	unsigned char	h_iextMax[4];
155	unsigned char	h_cbExtOffset[4];
156};
157
158/* File descriptor external record */
159
160struct fdr_ext
161{
162	unsigned char	f_adr[4];
163	unsigned char	f_rss[4];
164	unsigned char	f_issBase[4];
165	unsigned char	f_cbSs[4];
166	unsigned char	f_isymBase[4];
167	unsigned char	f_csym[4];
168	unsigned char	f_ilineBase[4];
169	unsigned char	f_cline[4];
170	unsigned char	f_ioptBase[4];
171	unsigned char	f_copt[4];
172	unsigned char	f_ipdFirst[2];
173	unsigned char	f_cpd[2];
174	unsigned char	f_iauxBase[4];
175	unsigned char	f_caux[4];
176	unsigned char	f_rfdBase[4];
177	unsigned char	f_crfd[4];
178	unsigned char	f_bits1[1];
179	unsigned char	f_bits2[3];
180	unsigned char	f_cbLineOffset[4];
181	unsigned char	f_cbLine[4];
182};
183
184#define	FDR_BITS1_LANG_BIG		0xF8
185#define	FDR_BITS1_LANG_SH_BIG		3
186#define	FDR_BITS1_LANG_LITTLE		0x1F
187#define	FDR_BITS1_LANG_SH_LITTLE	0
188
189#define	FDR_BITS1_FMERGE_BIG		0x04
190#define	FDR_BITS1_FMERGE_LITTLE		0x20
191
192#define	FDR_BITS1_FREADIN_BIG		0x02
193#define	FDR_BITS1_FREADIN_LITTLE	0x40
194
195#define	FDR_BITS1_FBIGENDIAN_BIG	0x01
196#define	FDR_BITS1_FBIGENDIAN_LITTLE	0x80
197
198#define	FDR_BITS2_GLEVEL_BIG		0xC0
199#define	FDR_BITS2_GLEVEL_SH_BIG		6
200#define	FDR_BITS2_GLEVEL_LITTLE		0x03
201#define	FDR_BITS2_GLEVEL_SH_LITTLE	0
202
203/* We ignore the `reserved' field in bits2. */
204
205/* Procedure descriptor external record */
206
207struct pdr_ext
208{
209	unsigned char	p_adr[4];
210	unsigned char	p_isym[4];
211	unsigned char	p_iline[4];
212	unsigned char	p_regmask[4];
213	unsigned char	p_regoffset[4];
214	unsigned char	p_iopt[4];
215	unsigned char	p_fregmask[4];
216	unsigned char	p_fregoffset[4];
217	unsigned char	p_frameoffset[4];
218	unsigned char	p_framereg[2];
219	unsigned char	p_pcreg[2];
220	unsigned char	p_lnLow[4];
221	unsigned char	p_lnHigh[4];
222	unsigned char	p_cbLineOffset[4];
223};
224
225/* Runtime procedure table */
226
227struct rpdr_ext
228{
229	unsigned char	p_adr[4];
230	unsigned char	p_regmask[4];
231	unsigned char	p_regoffset[4];
232	unsigned char	p_fregmask[4];
233	unsigned char	p_fregoffset[4];
234	unsigned char	p_frameoffset[4];
235	unsigned char	p_framereg[2];
236	unsigned char	p_pcreg[2];
237	unsigned char	p_irpss[4];
238	unsigned char	p_reserved[4];
239	unsigned char	p_exception_info[4];
240};
241
242/* Line numbers */
243
244struct line_ext
245{
246	unsigned char	l_line[4];
247};
248
249/* Symbol external record */
250
251struct sym_ext
252{
253	unsigned char	s_iss[4];
254	unsigned char	s_value[4];
255	unsigned char	s_bits1[1];
256	unsigned char	s_bits2[1];
257	unsigned char	s_bits3[1];
258	unsigned char	s_bits4[1];
259};
260
261#define	SYM_BITS1_ST_BIG		0xFC
262#define	SYM_BITS1_ST_SH_BIG		2
263#define	SYM_BITS1_ST_LITTLE		0x3F
264#define	SYM_BITS1_ST_SH_LITTLE		0
265
266#define	SYM_BITS1_SC_BIG		0x03
267#define	SYM_BITS1_SC_SH_LEFT_BIG	3
268#define	SYM_BITS1_SC_LITTLE		0xC0
269#define	SYM_BITS1_SC_SH_LITTLE		6
270
271#define	SYM_BITS2_SC_BIG		0xE0
272#define	SYM_BITS2_SC_SH_BIG		5
273#define	SYM_BITS2_SC_LITTLE		0x07
274#define	SYM_BITS2_SC_SH_LEFT_LITTLE	2
275
276#define	SYM_BITS2_RESERVED_BIG		0x10
277#define	SYM_BITS2_RESERVED_LITTLE	0x08
278
279#define	SYM_BITS2_INDEX_BIG		0x0F
280#define	SYM_BITS2_INDEX_SH_LEFT_BIG	16
281#define	SYM_BITS2_INDEX_LITTLE		0xF0
282#define	SYM_BITS2_INDEX_SH_LITTLE	4
283
284#define	SYM_BITS3_INDEX_SH_LEFT_BIG	8
285#define	SYM_BITS3_INDEX_SH_LEFT_LITTLE	4
286
287#define	SYM_BITS4_INDEX_SH_LEFT_BIG	0
288#define	SYM_BITS4_INDEX_SH_LEFT_LITTLE	12
289
290/* External symbol external record */
291
292struct ext_ext
293{
294	unsigned char	es_bits1[1];
295	unsigned char	es_bits2[1];
296	unsigned char	es_ifd[2];
297	struct	sym_ext es_asym;
298};
299
300#define	EXT_BITS1_JMPTBL_BIG		0x80
301#define	EXT_BITS1_JMPTBL_LITTLE		0x01
302
303#define	EXT_BITS1_COBOL_MAIN_BIG	0x40
304#define	EXT_BITS1_COBOL_MAIN_LITTLE	0x02
305
306#define	EXT_BITS1_WEAKEXT_BIG		0x20
307#define	EXT_BITS1_WEAKEXT_LITTLE	0x04
308
309/* Dense numbers external record */
310
311struct dnr_ext
312{
313	unsigned char	d_rfd[4];
314	unsigned char	d_index[4];
315};
316
317/* Relative file descriptor */
318
319struct rfd_ext
320{
321  unsigned char	rfd[4];
322};
323
324/* Optimizer symbol external record */
325
326struct opt_ext
327{
328  unsigned char o_bits1[1];
329  unsigned char o_bits2[1];
330  unsigned char o_bits3[1];
331  unsigned char o_bits4[1];
332  struct rndx_ext o_rndx;
333  unsigned char o_offset[4];
334};
335
336#define OPT_BITS2_VALUE_SH_LEFT_BIG	16
337#define OPT_BITS2_VALUE_SH_LEFT_LITTLE	0
338
339#define OPT_BITS3_VALUE_SH_LEFT_BIG	8
340#define OPT_BITS3_VALUE_SH_LEFT_LITTLE	8
341
342#define OPT_BITS4_VALUE_SH_LEFT_BIG	0
343#define OPT_BITS4_VALUE_SH_LEFT_LITTLE	16
344