1179404Sobrien/* ECOFF support on MIPS machines.
2179404Sobrien   coff/ecoff.h must be included before this file.
3179404Sobrien
4218822Sdim   Copyright 1999, 2004 Free Software Foundation, Inc.
5179404Sobrien
6179404Sobrien   This program is free software; you can redistribute it and/or modify
7179404Sobrien   it under the terms of the GNU General Public License as published by
8179404Sobrien   the Free Software Foundation; either version 2 of the License, or
9179404Sobrien   (at your option) any later version.
10179404Sobrien
11179404Sobrien   This program is distributed in the hope that it will be useful,
12179404Sobrien   but WITHOUT ANY WARRANTY; without even the implied warranty of
13179404Sobrien   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14179404Sobrien   GNU General Public License for more details.
15179404Sobrien
16179404Sobrien   You should have received a copy of the GNU General Public License
17179404Sobrien   along with this program; if not, write to the Free Software
18218822Sdim   Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.  */
19179404Sobrien
20179404Sobrien#define DO_NOT_DEFINE_AOUTHDR
21179404Sobrien#define L_LNNO_SIZE 4
22179404Sobrien#include "coff/external.h"
23179404Sobrien
24179404Sobrien/* Magic numbers are defined in coff/ecoff.h.  */
25179404Sobrien#define MIPS_ECOFF_BADMAG(x) (((x).f_magic!=MIPS_MAGIC_1) && \
26179404Sobrien			      ((x).f_magic!=MIPS_MAGIC_LITTLE) &&\
27179404Sobrien			      ((x).f_magic!=MIPS_MAGIC_BIG) && \
28179404Sobrien			      ((x).f_magic!=MIPS_MAGIC_LITTLE2) && \
29179404Sobrien			      ((x).f_magic!=MIPS_MAGIC_BIG2) && \
30179404Sobrien			      ((x).f_magic!=MIPS_MAGIC_LITTLE3) && \
31179404Sobrien			      ((x).f_magic!=MIPS_MAGIC_BIG3))
32179404Sobrien
33179404Sobrien
34179404Sobrien/********************** AOUT "OPTIONAL HEADER" **********************/
35179404Sobrien
36179404Sobrientypedef struct external_aouthdr
37179404Sobrien{
38179404Sobrien  unsigned char magic[2];	/* type of file				*/
39179404Sobrien  unsigned char	vstamp[2];	/* version stamp			*/
40179404Sobrien  unsigned char	tsize[4];	/* text size in bytes, padded to FW bdry*/
41179404Sobrien  unsigned char	dsize[4];	/* initialized data "  "		*/
42179404Sobrien  unsigned char	bsize[4];	/* uninitialized data "   "		*/
43179404Sobrien  unsigned char	entry[4];	/* entry pt.				*/
44179404Sobrien  unsigned char text_start[4];	/* base of text used for this file */
45179404Sobrien  unsigned char data_start[4];	/* base of data used for this file */
46179404Sobrien  unsigned char bss_start[4];	/* base of bss used for this file */
47179404Sobrien  unsigned char gprmask[4];	/* ?? */
48179404Sobrien  unsigned char cprmask[4][4];	/* ?? */
49179404Sobrien  unsigned char gp_value[4];	/* value for gp register */
50179404Sobrien} AOUTHDR;
51179404Sobrien
52179404Sobrien/* compute size of a header */
53179404Sobrien
54179404Sobrien#define AOUTSZ 56
55179404Sobrien#define AOUTHDRSZ 56
56179404Sobrien
57179404Sobrien/********************** RELOCATION DIRECTIVES **********************/
58179404Sobrien
59179404Sobrienstruct external_reloc
60179404Sobrien  {
61179404Sobrien    unsigned char r_vaddr[4];
62179404Sobrien    unsigned char r_bits[4];
63179404Sobrien  };
64179404Sobrien
65179404Sobrien#define RELOC struct external_reloc
66179404Sobrien#define RELSZ 8
67179404Sobrien
68179404Sobrien/* MIPS ECOFF uses a packed 8 byte format for relocs.  These constants
69179404Sobrien   are used to unpack the r_bits field.  */
70179404Sobrien
71179404Sobrien#define RELOC_BITS0_SYMNDX_SH_LEFT_BIG		16
72179404Sobrien#define RELOC_BITS0_SYMNDX_SH_LEFT_LITTLE	0
73179404Sobrien
74179404Sobrien#define RELOC_BITS1_SYMNDX_SH_LEFT_BIG		8
75179404Sobrien#define RELOC_BITS1_SYMNDX_SH_LEFT_LITTLE	8
76179404Sobrien
77179404Sobrien#define RELOC_BITS2_SYMNDX_SH_LEFT_BIG		0
78179404Sobrien#define RELOC_BITS2_SYMNDX_SH_LEFT_LITTLE	16
79179404Sobrien
80179404Sobrien/* Originally, ECOFF used four bits for the reloc type and had three
81179404Sobrien   reserved bits.  Irix 4 added another bit for the reloc type, which
82179404Sobrien   was easy because it was big endian and one of the spare bits became
83179404Sobrien   the new most significant bit.  To make this also work for little
84179404Sobrien   endian ECOFF, we need to wrap one of the reserved bits around to
85179404Sobrien   become the most significant bit of the reloc type.  */
86179404Sobrien#define RELOC_BITS3_TYPE_BIG			0x3E
87179404Sobrien#define RELOC_BITS3_TYPE_SH_BIG			1
88179404Sobrien#define RELOC_BITS3_TYPE_LITTLE			0x78
89179404Sobrien#define RELOC_BITS3_TYPE_SH_LITTLE		3
90179404Sobrien#define RELOC_BITS3_TYPEHI_LITTLE		0x04
91179404Sobrien#define RELOC_BITS3_TYPEHI_SH_LITTLE		2
92179404Sobrien
93179404Sobrien#define RELOC_BITS3_EXTERN_BIG			0x01
94179404Sobrien#define RELOC_BITS3_EXTERN_LITTLE		0x80
95179404Sobrien
96179404Sobrien/* The r_type field in a reloc is one of the following values.  I
97179404Sobrien   don't know if any other values can appear.  These seem to be all
98179404Sobrien   that occur in the Ultrix 4.2 libraries.  */
99179404Sobrien#define MIPS_R_IGNORE	0
100179404Sobrien#define MIPS_R_REFHALF	1
101179404Sobrien#define MIPS_R_REFWORD	2
102179404Sobrien#define MIPS_R_JMPADDR	3
103179404Sobrien#define MIPS_R_REFHI	4
104179404Sobrien#define MIPS_R_REFLO	5
105179404Sobrien#define MIPS_R_GPREL	6
106179404Sobrien#define MIPS_R_LITERAL	7
107179404Sobrien
108218822Sdim/* FIXME: This relocation is used (internally only) to represent branches
109218822Sdim   when assembling.  It should never appear in output files, and
110218822Sdim   be removed.  (It used to be used for embedded-PIC support.)  */
111179404Sobrien#define MIPS_R_PCREL16	12
112179404Sobrien
113179404Sobrien/********************** STABS **********************/
114179404Sobrien
115179404Sobrien#define MIPS_IS_STAB ECOFF_IS_STAB
116179404Sobrien#define MIPS_MARK_STAB ECOFF_MARK_STAB
117179404Sobrien#define MIPS_UNMARK_STAB ECOFF_UNMARK_STAB
118179404Sobrien
119179404Sobrien/********************** SYMBOLIC INFORMATION **********************/
120179404Sobrien
121179404Sobrien/* Written by John Gilmore.  */
122179404Sobrien
123179404Sobrien/* ECOFF uses COFF-like section structures, but its own symbol format.
124179404Sobrien   This file defines the symbol format in fields whose size and alignment
125179404Sobrien   will not vary on different host systems.  */
126179404Sobrien
127179404Sobrien/* File header as a set of bytes */
128179404Sobrien
129179404Sobrienstruct hdr_ext
130179404Sobrien{
131179404Sobrien	unsigned char 	h_magic[2];
132179404Sobrien	unsigned char	h_vstamp[2];
133179404Sobrien	unsigned char	h_ilineMax[4];
134179404Sobrien	unsigned char	h_cbLine[4];
135179404Sobrien	unsigned char	h_cbLineOffset[4];
136179404Sobrien	unsigned char	h_idnMax[4];
137179404Sobrien	unsigned char	h_cbDnOffset[4];
138179404Sobrien	unsigned char	h_ipdMax[4];
139179404Sobrien	unsigned char	h_cbPdOffset[4];
140179404Sobrien	unsigned char	h_isymMax[4];
141179404Sobrien	unsigned char	h_cbSymOffset[4];
142179404Sobrien	unsigned char	h_ioptMax[4];
143179404Sobrien	unsigned char	h_cbOptOffset[4];
144179404Sobrien	unsigned char	h_iauxMax[4];
145179404Sobrien	unsigned char	h_cbAuxOffset[4];
146179404Sobrien	unsigned char	h_issMax[4];
147179404Sobrien	unsigned char	h_cbSsOffset[4];
148179404Sobrien	unsigned char	h_issExtMax[4];
149179404Sobrien	unsigned char	h_cbSsExtOffset[4];
150179404Sobrien	unsigned char	h_ifdMax[4];
151179404Sobrien	unsigned char	h_cbFdOffset[4];
152179404Sobrien	unsigned char	h_crfd[4];
153179404Sobrien	unsigned char	h_cbRfdOffset[4];
154179404Sobrien	unsigned char	h_iextMax[4];
155179404Sobrien	unsigned char	h_cbExtOffset[4];
156179404Sobrien};
157179404Sobrien
158179404Sobrien/* File descriptor external record */
159179404Sobrien
160179404Sobrienstruct fdr_ext
161179404Sobrien{
162179404Sobrien	unsigned char	f_adr[4];
163179404Sobrien	unsigned char	f_rss[4];
164179404Sobrien	unsigned char	f_issBase[4];
165179404Sobrien	unsigned char	f_cbSs[4];
166179404Sobrien	unsigned char	f_isymBase[4];
167179404Sobrien	unsigned char	f_csym[4];
168179404Sobrien	unsigned char	f_ilineBase[4];
169179404Sobrien	unsigned char	f_cline[4];
170179404Sobrien	unsigned char	f_ioptBase[4];
171179404Sobrien	unsigned char	f_copt[4];
172179404Sobrien	unsigned char	f_ipdFirst[2];
173179404Sobrien	unsigned char	f_cpd[2];
174179404Sobrien	unsigned char	f_iauxBase[4];
175179404Sobrien	unsigned char	f_caux[4];
176179404Sobrien	unsigned char	f_rfdBase[4];
177179404Sobrien	unsigned char	f_crfd[4];
178179404Sobrien	unsigned char	f_bits1[1];
179179404Sobrien	unsigned char	f_bits2[3];
180179404Sobrien	unsigned char	f_cbLineOffset[4];
181179404Sobrien	unsigned char	f_cbLine[4];
182179404Sobrien};
183179404Sobrien
184179404Sobrien#define	FDR_BITS1_LANG_BIG		0xF8
185179404Sobrien#define	FDR_BITS1_LANG_SH_BIG		3
186179404Sobrien#define	FDR_BITS1_LANG_LITTLE		0x1F
187179404Sobrien#define	FDR_BITS1_LANG_SH_LITTLE	0
188179404Sobrien
189179404Sobrien#define	FDR_BITS1_FMERGE_BIG		0x04
190179404Sobrien#define	FDR_BITS1_FMERGE_LITTLE		0x20
191179404Sobrien
192179404Sobrien#define	FDR_BITS1_FREADIN_BIG		0x02
193179404Sobrien#define	FDR_BITS1_FREADIN_LITTLE	0x40
194179404Sobrien
195179404Sobrien#define	FDR_BITS1_FBIGENDIAN_BIG	0x01
196179404Sobrien#define	FDR_BITS1_FBIGENDIAN_LITTLE	0x80
197179404Sobrien
198179404Sobrien#define	FDR_BITS2_GLEVEL_BIG		0xC0
199179404Sobrien#define	FDR_BITS2_GLEVEL_SH_BIG		6
200179404Sobrien#define	FDR_BITS2_GLEVEL_LITTLE		0x03
201179404Sobrien#define	FDR_BITS2_GLEVEL_SH_LITTLE	0
202179404Sobrien
203179404Sobrien/* We ignore the `reserved' field in bits2. */
204179404Sobrien
205179404Sobrien/* Procedure descriptor external record */
206179404Sobrien
207179404Sobrienstruct pdr_ext
208179404Sobrien{
209179404Sobrien	unsigned char	p_adr[4];
210179404Sobrien	unsigned char	p_isym[4];
211179404Sobrien	unsigned char	p_iline[4];
212179404Sobrien	unsigned char	p_regmask[4];
213179404Sobrien	unsigned char	p_regoffset[4];
214179404Sobrien	unsigned char	p_iopt[4];
215179404Sobrien	unsigned char	p_fregmask[4];
216179404Sobrien	unsigned char	p_fregoffset[4];
217179404Sobrien	unsigned char	p_frameoffset[4];
218179404Sobrien	unsigned char	p_framereg[2];
219179404Sobrien	unsigned char	p_pcreg[2];
220179404Sobrien	unsigned char	p_lnLow[4];
221179404Sobrien	unsigned char	p_lnHigh[4];
222179404Sobrien	unsigned char	p_cbLineOffset[4];
223179404Sobrien};
224179404Sobrien
225179404Sobrien/* Runtime procedure table */
226179404Sobrien
227179404Sobrienstruct rpdr_ext
228179404Sobrien{
229179404Sobrien	unsigned char	p_adr[4];
230179404Sobrien	unsigned char	p_regmask[4];
231179404Sobrien	unsigned char	p_regoffset[4];
232179404Sobrien	unsigned char	p_fregmask[4];
233179404Sobrien	unsigned char	p_fregoffset[4];
234179404Sobrien	unsigned char	p_frameoffset[4];
235179404Sobrien	unsigned char	p_framereg[2];
236179404Sobrien	unsigned char	p_pcreg[2];
237179404Sobrien	unsigned char	p_irpss[4];
238179404Sobrien	unsigned char	p_reserved[4];
239179404Sobrien	unsigned char	p_exception_info[4];
240179404Sobrien};
241179404Sobrien
242179404Sobrien/* Line numbers */
243179404Sobrien
244179404Sobrienstruct line_ext
245179404Sobrien{
246179404Sobrien	unsigned char	l_line[4];
247179404Sobrien};
248179404Sobrien
249179404Sobrien/* Symbol external record */
250179404Sobrien
251179404Sobrienstruct sym_ext
252179404Sobrien{
253179404Sobrien	unsigned char	s_iss[4];
254179404Sobrien	unsigned char	s_value[4];
255179404Sobrien	unsigned char	s_bits1[1];
256179404Sobrien	unsigned char	s_bits2[1];
257179404Sobrien	unsigned char	s_bits3[1];
258179404Sobrien	unsigned char	s_bits4[1];
259179404Sobrien};
260179404Sobrien
261179404Sobrien#define	SYM_BITS1_ST_BIG		0xFC
262179404Sobrien#define	SYM_BITS1_ST_SH_BIG		2
263179404Sobrien#define	SYM_BITS1_ST_LITTLE		0x3F
264179404Sobrien#define	SYM_BITS1_ST_SH_LITTLE		0
265179404Sobrien
266179404Sobrien#define	SYM_BITS1_SC_BIG		0x03
267179404Sobrien#define	SYM_BITS1_SC_SH_LEFT_BIG	3
268179404Sobrien#define	SYM_BITS1_SC_LITTLE		0xC0
269179404Sobrien#define	SYM_BITS1_SC_SH_LITTLE		6
270179404Sobrien
271179404Sobrien#define	SYM_BITS2_SC_BIG		0xE0
272179404Sobrien#define	SYM_BITS2_SC_SH_BIG		5
273179404Sobrien#define	SYM_BITS2_SC_LITTLE		0x07
274179404Sobrien#define	SYM_BITS2_SC_SH_LEFT_LITTLE	2
275179404Sobrien
276179404Sobrien#define	SYM_BITS2_RESERVED_BIG		0x10
277179404Sobrien#define	SYM_BITS2_RESERVED_LITTLE	0x08
278179404Sobrien
279179404Sobrien#define	SYM_BITS2_INDEX_BIG		0x0F
280179404Sobrien#define	SYM_BITS2_INDEX_SH_LEFT_BIG	16
281179404Sobrien#define	SYM_BITS2_INDEX_LITTLE		0xF0
282179404Sobrien#define	SYM_BITS2_INDEX_SH_LITTLE	4
283179404Sobrien
284179404Sobrien#define	SYM_BITS3_INDEX_SH_LEFT_BIG	8
285179404Sobrien#define	SYM_BITS3_INDEX_SH_LEFT_LITTLE	4
286179404Sobrien
287179404Sobrien#define	SYM_BITS4_INDEX_SH_LEFT_BIG	0
288179404Sobrien#define	SYM_BITS4_INDEX_SH_LEFT_LITTLE	12
289179404Sobrien
290179404Sobrien/* External symbol external record */
291179404Sobrien
292179404Sobrienstruct ext_ext
293179404Sobrien{
294179404Sobrien	unsigned char	es_bits1[1];
295179404Sobrien	unsigned char	es_bits2[1];
296179404Sobrien	unsigned char	es_ifd[2];
297179404Sobrien	struct	sym_ext es_asym;
298179404Sobrien};
299179404Sobrien
300179404Sobrien#define	EXT_BITS1_JMPTBL_BIG		0x80
301179404Sobrien#define	EXT_BITS1_JMPTBL_LITTLE		0x01
302179404Sobrien
303179404Sobrien#define	EXT_BITS1_COBOL_MAIN_BIG	0x40
304179404Sobrien#define	EXT_BITS1_COBOL_MAIN_LITTLE	0x02
305179404Sobrien
306179404Sobrien#define	EXT_BITS1_WEAKEXT_BIG		0x20
307179404Sobrien#define	EXT_BITS1_WEAKEXT_LITTLE	0x04
308179404Sobrien
309179404Sobrien/* Dense numbers external record */
310179404Sobrien
311179404Sobrienstruct dnr_ext
312179404Sobrien{
313179404Sobrien	unsigned char	d_rfd[4];
314179404Sobrien	unsigned char	d_index[4];
315179404Sobrien};
316179404Sobrien
317179404Sobrien/* Relative file descriptor */
318179404Sobrien
319179404Sobrienstruct rfd_ext
320179404Sobrien{
321179404Sobrien  unsigned char	rfd[4];
322179404Sobrien};
323179404Sobrien
324179404Sobrien/* Optimizer symbol external record */
325179404Sobrien
326179404Sobrienstruct opt_ext
327179404Sobrien{
328179404Sobrien  unsigned char o_bits1[1];
329179404Sobrien  unsigned char o_bits2[1];
330179404Sobrien  unsigned char o_bits3[1];
331179404Sobrien  unsigned char o_bits4[1];
332179404Sobrien  struct rndx_ext o_rndx;
333179404Sobrien  unsigned char o_offset[4];
334179404Sobrien};
335179404Sobrien
336179404Sobrien#define OPT_BITS2_VALUE_SH_LEFT_BIG	16
337179404Sobrien#define OPT_BITS2_VALUE_SH_LEFT_LITTLE	0
338179404Sobrien
339179404Sobrien#define OPT_BITS3_VALUE_SH_LEFT_BIG	8
340179404Sobrien#define OPT_BITS3_VALUE_SH_LEFT_LITTLE	8
341179404Sobrien
342179404Sobrien#define OPT_BITS4_VALUE_SH_LEFT_BIG	0
343179404Sobrien#define OPT_BITS4_VALUE_SH_LEFT_LITTLE	16
344