xref: /openbsd-src/gnu/usr.bin/binutils-2.17/include/aout/adobe.h (revision 3d8817e467ea46cf4772788d6804dd293abfb01a)
1*3d8817e4Smiod /* `a.out.adobe' differences from standard a.out files
2*3d8817e4Smiod 
3*3d8817e4Smiod    Copyright 2001 Free Software Foundation, Inc.
4*3d8817e4Smiod 
5*3d8817e4Smiod    This program is free software; you can redistribute it and/or modify
6*3d8817e4Smiod    it under the terms of the GNU General Public License as published by
7*3d8817e4Smiod    the Free Software Foundation; either version 2 of the License, or
8*3d8817e4Smiod    (at your option) any later version.
9*3d8817e4Smiod 
10*3d8817e4Smiod    This program is distributed in the hope that it will be useful,
11*3d8817e4Smiod    but WITHOUT ANY WARRANTY; without even the implied warranty of
12*3d8817e4Smiod    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13*3d8817e4Smiod    GNU General Public License for more details.
14*3d8817e4Smiod 
15*3d8817e4Smiod    You should have received a copy of the GNU General Public License
16*3d8817e4Smiod    along with this program; if not, write to the Free Software
17*3d8817e4Smiod    Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.  */
18*3d8817e4Smiod 
19*3d8817e4Smiod #ifndef __A_OUT_ADOBE_H__
20*3d8817e4Smiod #define __A_OUT_ADOBE_H__
21*3d8817e4Smiod 
22*3d8817e4Smiod #define	BYTES_IN_WORD	4
23*3d8817e4Smiod 
24*3d8817e4Smiod /* Struct external_exec is the same.  */
25*3d8817e4Smiod 
26*3d8817e4Smiod /* This is the layout on disk of the 32-bit or 64-bit exec header. */
27*3d8817e4Smiod 
28*3d8817e4Smiod struct external_exec
29*3d8817e4Smiod {
30*3d8817e4Smiod   bfd_byte e_info[4];		/* magic number and stuff		*/
31*3d8817e4Smiod   bfd_byte e_text[BYTES_IN_WORD]; /* length of text section in bytes	*/
32*3d8817e4Smiod   bfd_byte e_data[BYTES_IN_WORD]; /* length of data section in bytes	*/
33*3d8817e4Smiod   bfd_byte e_bss[BYTES_IN_WORD]; /* length of bss area in bytes 		*/
34*3d8817e4Smiod   bfd_byte e_syms[BYTES_IN_WORD]; /* length of symbol table in bytes 	*/
35*3d8817e4Smiod   bfd_byte e_entry[BYTES_IN_WORD]; /* start address 			*/
36*3d8817e4Smiod   bfd_byte e_trsize[BYTES_IN_WORD]; /* length of text relocation info	*/
37*3d8817e4Smiod   bfd_byte e_drsize[BYTES_IN_WORD]; /* length of data relocation info 	*/
38*3d8817e4Smiod };
39*3d8817e4Smiod 
40*3d8817e4Smiod #define	EXEC_BYTES_SIZE	(4 + BYTES_IN_WORD * 7)
41*3d8817e4Smiod 
42*3d8817e4Smiod /* Magic numbers for a.out files */
43*3d8817e4Smiod 
44*3d8817e4Smiod #undef	ZMAGIC
45*3d8817e4Smiod #define	ZMAGIC	0xAD0BE		/* Cute, eh?  */
46*3d8817e4Smiod #undef	OMAGIC
47*3d8817e4Smiod #undef	NMAGIC
48*3d8817e4Smiod 
49*3d8817e4Smiod #define N_BADMAG(x)	  ((x).a_info != ZMAGIC)
50*3d8817e4Smiod 
51*3d8817e4Smiod /* By default, segment size is constant.  But some machines override this
52*3d8817e4Smiod    to be a function of the a.out header (e.g. machine type).  */
53*3d8817e4Smiod #ifndef	N_SEGSIZE
54*3d8817e4Smiod #define	N_SEGSIZE(x)	SEGMENT_SIZE
55*3d8817e4Smiod #endif
56*3d8817e4Smiod #undef N_SEGSIZE   /* FIXMEXXXX */
57*3d8817e4Smiod 
58*3d8817e4Smiod /* Segment information for the a.out.Adobe format is specified after the
59*3d8817e4Smiod    file header.  It contains N segment descriptors, followed by one with
60*3d8817e4Smiod    a type of zero.
61*3d8817e4Smiod 
62*3d8817e4Smiod    The actual text of the segments starts at N_TXTOFF in the file,
63*3d8817e4Smiod    regardless of how many or how few segment headers there are.  */
64*3d8817e4Smiod 
65*3d8817e4Smiod struct external_segdesc {
66*3d8817e4Smiod 	unsigned char e_type[1];
67*3d8817e4Smiod 	unsigned char e_size[3];
68*3d8817e4Smiod 	unsigned char e_virtbase[4];
69*3d8817e4Smiod 	unsigned char e_filebase[4];
70*3d8817e4Smiod };
71*3d8817e4Smiod 
72*3d8817e4Smiod struct internal_segdesc {
73*3d8817e4Smiod 	unsigned int	a_type:8;	/* Segment type N_TEXT, N_DATA, 0 */
74*3d8817e4Smiod 	unsigned int 	a_size:24;	/* Segment size */
75*3d8817e4Smiod 	bfd_vma		a_virtbase;	/* Virtual address */
76*3d8817e4Smiod 	unsigned int	a_filebase;	/* Base address in object file */
77*3d8817e4Smiod };
78*3d8817e4Smiod 
79*3d8817e4Smiod #define N_TXTADDR(x) \
80*3d8817e4Smiod 
81*3d8817e4Smiod /* This is documented to be at 1024, but appears to really be at 2048.
82*3d8817e4Smiod    FIXME?!  */
83*3d8817e4Smiod #define N_TXTOFF(x)	2048
84*3d8817e4Smiod 
85*3d8817e4Smiod #define	N_TXTSIZE(x) ((x).a_text)
86*3d8817e4Smiod 
87*3d8817e4Smiod #define N_DATADDR(x)
88*3d8817e4Smiod 
89*3d8817e4Smiod #define N_BSSADDR(x)
90*3d8817e4Smiod 
91*3d8817e4Smiod /* Offsets of the various portions of the file after the text segment.  */
92*3d8817e4Smiod 
93*3d8817e4Smiod #define N_DATOFF(x)	( N_TXTOFF(x) + N_TXTSIZE(x) )
94*3d8817e4Smiod #define N_TRELOFF(x)	( N_DATOFF(x) + (x).a_data )
95*3d8817e4Smiod #define N_DRELOFF(x)	( N_TRELOFF(x) + (x).a_trsize )
96*3d8817e4Smiod #define N_SYMOFF(x)	( N_DRELOFF(x) + (x).a_drsize )
97*3d8817e4Smiod #define N_STROFF(x)	( N_SYMOFF(x) + (x).a_syms )
98*3d8817e4Smiod 
99*3d8817e4Smiod /* Symbols */
100*3d8817e4Smiod struct external_nlist {
101*3d8817e4Smiod   bfd_byte e_strx[BYTES_IN_WORD];	/* index into string table of name */
102*3d8817e4Smiod   bfd_byte e_type[1];			/* type of symbol */
103*3d8817e4Smiod   bfd_byte e_other[1];			/* misc info (usually empty) */
104*3d8817e4Smiod   bfd_byte e_desc[2];			/* description field */
105*3d8817e4Smiod   bfd_byte e_value[BYTES_IN_WORD];	/* value of symbol */
106*3d8817e4Smiod };
107*3d8817e4Smiod 
108*3d8817e4Smiod #define EXTERNAL_NLIST_SIZE (BYTES_IN_WORD+4+BYTES_IN_WORD)
109*3d8817e4Smiod 
110*3d8817e4Smiod struct internal_nlist {
111*3d8817e4Smiod   unsigned long n_strx;			/* index into string table of name */
112*3d8817e4Smiod   unsigned char n_type;			/* type of symbol */
113*3d8817e4Smiod   unsigned char n_other;		/* misc info (usually empty) */
114*3d8817e4Smiod   unsigned short n_desc;		/* description field */
115*3d8817e4Smiod   bfd_vma n_value;			/* value of symbol */
116*3d8817e4Smiod };
117*3d8817e4Smiod 
118*3d8817e4Smiod /* The n_type field is the symbol type, containing:  */
119*3d8817e4Smiod 
120*3d8817e4Smiod #define N_UNDF	0	/* Undefined symbol */
121*3d8817e4Smiod #define N_ABS 	2	/* Absolute symbol -- defined at particular addr */
122*3d8817e4Smiod #define N_TEXT 	4	/* Text sym -- defined at offset in text seg */
123*3d8817e4Smiod #define N_DATA 	6	/* Data sym -- defined at offset in data seg */
124*3d8817e4Smiod #define N_BSS 	8	/* BSS  sym -- defined at offset in zero'd seg */
125*3d8817e4Smiod #define	N_COMM	0x12	/* Common symbol (visible after shared lib dynlink) */
126*3d8817e4Smiod #define N_FN	0x1f	/* File name of .o file */
127*3d8817e4Smiod #define	N_FN_SEQ 0x0C	/* N_FN from Sequent compilers (sigh) */
128*3d8817e4Smiod /* Note: N_EXT can only be usefully OR-ed with N_UNDF, N_ABS, N_TEXT,
129*3d8817e4Smiod    N_DATA, or N_BSS.  When the low-order bit of other types is set,
130*3d8817e4Smiod    (e.g. N_WARNING versus N_FN), they are two different types.  */
131*3d8817e4Smiod #define N_EXT 	1	/* External symbol (as opposed to local-to-this-file) */
132*3d8817e4Smiod #define N_TYPE  0x1e
133*3d8817e4Smiod #define N_STAB 	0xe0	/* If any of these bits are on, it's a debug symbol */
134*3d8817e4Smiod 
135*3d8817e4Smiod #define N_INDR 0x0a
136*3d8817e4Smiod 
137*3d8817e4Smiod /* The following symbols refer to set elements.
138*3d8817e4Smiod    All the N_SET[ATDB] symbols with the same name form one set.
139*3d8817e4Smiod    Space is allocated for the set in the text section, and each set
140*3d8817e4Smiod    elements value is stored into one word of the space.
141*3d8817e4Smiod    The first word of the space is the length of the set (number of elements).
142*3d8817e4Smiod 
143*3d8817e4Smiod    The address of the set is made into an N_SETV symbol
144*3d8817e4Smiod    whose name is the same as the name of the set.
145*3d8817e4Smiod    This symbol acts like a N_DATA global symbol
146*3d8817e4Smiod    in that it can satisfy undefined external references.  */
147*3d8817e4Smiod 
148*3d8817e4Smiod /* These appear as input to LD, in a .o file.  */
149*3d8817e4Smiod #define	N_SETA	0x14		/* Absolute set element symbol */
150*3d8817e4Smiod #define	N_SETT	0x16		/* Text set element symbol */
151*3d8817e4Smiod #define	N_SETD	0x18		/* Data set element symbol */
152*3d8817e4Smiod #define	N_SETB	0x1A		/* Bss set element symbol */
153*3d8817e4Smiod 
154*3d8817e4Smiod /* This is output from LD.  */
155*3d8817e4Smiod #define N_SETV	0x1C		/* Pointer to set vector in data area.  */
156*3d8817e4Smiod 
157*3d8817e4Smiod /* Warning symbol. The text gives a warning message, the next symbol
158*3d8817e4Smiod    in the table will be undefined. When the symbol is referenced, the
159*3d8817e4Smiod    message is printed.  */
160*3d8817e4Smiod 
161*3d8817e4Smiod #define	N_WARNING 0x1e
162*3d8817e4Smiod 
163*3d8817e4Smiod /* Relocations
164*3d8817e4Smiod 
165*3d8817e4Smiod   There	are two types of relocation flavours for a.out systems,
166*3d8817e4Smiod   standard and extended. The standard form is used on systems where the
167*3d8817e4Smiod   instruction has room for all the bits of an offset to the operand, whilst
168*3d8817e4Smiod   the extended form is used when an address operand has to be split over n
169*3d8817e4Smiod   instructions. Eg, on the 68k, each move instruction can reference
170*3d8817e4Smiod   the target with a displacement of 16 or 32 bits. On the sparc, move
171*3d8817e4Smiod   instructions use an offset of 14 bits, so the offset is stored in
172*3d8817e4Smiod   the reloc field, and the data in the section is ignored.
173*3d8817e4Smiod */
174*3d8817e4Smiod 
175*3d8817e4Smiod /* This structure describes a single relocation to be performed.
176*3d8817e4Smiod    The text-relocation section of the file is a vector of these structures,
177*3d8817e4Smiod    all of which apply to the text section.
178*3d8817e4Smiod    Likewise, the data-relocation section applies to the data section.  */
179*3d8817e4Smiod 
180*3d8817e4Smiod struct reloc_std_external {
181*3d8817e4Smiod   bfd_byte r_address[BYTES_IN_WORD];	/* offset of of data to relocate */
182*3d8817e4Smiod   bfd_byte r_index[3];	/* symbol table index of symbol 	*/
183*3d8817e4Smiod   bfd_byte r_type[1];	/* relocation type			*/
184*3d8817e4Smiod };
185*3d8817e4Smiod 
186*3d8817e4Smiod #define	RELOC_STD_BITS_PCREL_BIG	0x80
187*3d8817e4Smiod #define	RELOC_STD_BITS_PCREL_LITTLE	0x01
188*3d8817e4Smiod 
189*3d8817e4Smiod #define	RELOC_STD_BITS_LENGTH_BIG	0x60
190*3d8817e4Smiod #define	RELOC_STD_BITS_LENGTH_SH_BIG	5	/* To shift to units place */
191*3d8817e4Smiod #define	RELOC_STD_BITS_LENGTH_LITTLE	0x06
192*3d8817e4Smiod #define	RELOC_STD_BITS_LENGTH_SH_LITTLE	1
193*3d8817e4Smiod 
194*3d8817e4Smiod #define	RELOC_STD_BITS_EXTERN_BIG	0x10
195*3d8817e4Smiod #define	RELOC_STD_BITS_EXTERN_LITTLE	0x08
196*3d8817e4Smiod 
197*3d8817e4Smiod #define	RELOC_STD_BITS_BASEREL_BIG	0x08
198*3d8817e4Smiod #define	RELOC_STD_BITS_BASEREL_LITTLE	0x08
199*3d8817e4Smiod 
200*3d8817e4Smiod #define	RELOC_STD_BITS_JMPTABLE_BIG	0x04
201*3d8817e4Smiod #define	RELOC_STD_BITS_JMPTABLE_LITTLE	0x04
202*3d8817e4Smiod 
203*3d8817e4Smiod #define	RELOC_STD_BITS_RELATIVE_BIG	0x02
204*3d8817e4Smiod #define	RELOC_STD_BITS_RELATIVE_LITTLE	0x02
205*3d8817e4Smiod 
206*3d8817e4Smiod #define	RELOC_STD_SIZE	(BYTES_IN_WORD + 3 + 1)		/* Bytes per relocation entry */
207*3d8817e4Smiod 
208*3d8817e4Smiod struct reloc_std_internal
209*3d8817e4Smiod {
210*3d8817e4Smiod   bfd_vma r_address;		/* Address (within segment) to be relocated.  */
211*3d8817e4Smiod   /* The meaning of r_symbolnum depends on r_extern.  */
212*3d8817e4Smiod   unsigned int r_symbolnum:24;
213*3d8817e4Smiod   /* Nonzero means value is a pc-relative offset
214*3d8817e4Smiod      and it should be relocated for changes in its own address
215*3d8817e4Smiod      as well as for changes in the symbol or section specified.  */
216*3d8817e4Smiod   unsigned int r_pcrel:1;
217*3d8817e4Smiod   /* Length (as exponent of 2) of the field to be relocated.
218*3d8817e4Smiod      Thus, a value of 2 indicates 1<<2 bytes.  */
219*3d8817e4Smiod   unsigned int r_length:2;
220*3d8817e4Smiod   /* 1 => relocate with value of symbol.
221*3d8817e4Smiod      r_symbolnum is the index of the symbol
222*3d8817e4Smiod      in files the symbol table.
223*3d8817e4Smiod      0 => relocate with the address of a segment.
224*3d8817e4Smiod      r_symbolnum is N_TEXT, N_DATA, N_BSS or N_ABS
225*3d8817e4Smiod      (the N_EXT bit may be set also, but signifies nothing).  */
226*3d8817e4Smiod   unsigned int r_extern:1;
227*3d8817e4Smiod   /* The next three bits are for SunOS shared libraries, and seem to
228*3d8817e4Smiod      be undocumented.  */
229*3d8817e4Smiod   unsigned int r_baserel:1;	/* Linkage table relative */
230*3d8817e4Smiod   unsigned int r_jmptable:1;	/* pc-relative to jump table */
231*3d8817e4Smiod   unsigned int r_relative:1;	/* "relative relocation" */
232*3d8817e4Smiod   /* unused */
233*3d8817e4Smiod   unsigned int r_pad:1;		/* Padding -- set to zero */
234*3d8817e4Smiod };
235*3d8817e4Smiod 
236*3d8817e4Smiod 
237*3d8817e4Smiod /* EXTENDED RELOCS  */
238*3d8817e4Smiod 
239*3d8817e4Smiod struct reloc_ext_external {
240*3d8817e4Smiod   bfd_byte r_address[BYTES_IN_WORD];	/* offset of of data to relocate 	*/
241*3d8817e4Smiod   bfd_byte r_index[3];	/* symbol table index of symbol 	*/
242*3d8817e4Smiod   bfd_byte r_type[1];	/* relocation type			*/
243*3d8817e4Smiod   bfd_byte r_addend[BYTES_IN_WORD];	/* datum addend				*/
244*3d8817e4Smiod };
245*3d8817e4Smiod 
246*3d8817e4Smiod #define	RELOC_EXT_BITS_EXTERN_BIG	0x80
247*3d8817e4Smiod #define	RELOC_EXT_BITS_EXTERN_LITTLE	0x01
248*3d8817e4Smiod 
249*3d8817e4Smiod #define	RELOC_EXT_BITS_TYPE_BIG		0x1F
250*3d8817e4Smiod #define	RELOC_EXT_BITS_TYPE_SH_BIG	0
251*3d8817e4Smiod #define	RELOC_EXT_BITS_TYPE_LITTLE	0xF8
252*3d8817e4Smiod #define	RELOC_EXT_BITS_TYPE_SH_LITTLE	3
253*3d8817e4Smiod 
254*3d8817e4Smiod /* Bytes per relocation entry */
255*3d8817e4Smiod #define	RELOC_EXT_SIZE	(BYTES_IN_WORD + 3 + 1 + BYTES_IN_WORD)
256*3d8817e4Smiod 
257*3d8817e4Smiod enum reloc_type
258*3d8817e4Smiod {
259*3d8817e4Smiod   /* simple relocations */
260*3d8817e4Smiod   RELOC_8,			/* data[0:7] = addend + sv 		*/
261*3d8817e4Smiod   RELOC_16,			/* data[0:15] = addend + sv 		*/
262*3d8817e4Smiod   RELOC_32,			/* data[0:31] = addend + sv 		*/
263*3d8817e4Smiod   /* pc-rel displacement */
264*3d8817e4Smiod   RELOC_DISP8,			/* data[0:7] = addend - pc + sv 	*/
265*3d8817e4Smiod   RELOC_DISP16,			/* data[0:15] = addend - pc + sv 	*/
266*3d8817e4Smiod   RELOC_DISP32,			/* data[0:31] = addend - pc + sv 	*/
267*3d8817e4Smiod   /* Special */
268*3d8817e4Smiod   RELOC_WDISP30,		/* data[0:29] = (addend + sv - pc)>>2 	*/
269*3d8817e4Smiod   RELOC_WDISP22,		/* data[0:21] = (addend + sv - pc)>>2 	*/
270*3d8817e4Smiod   RELOC_HI22,			/* data[0:21] = (addend + sv)>>10 	*/
271*3d8817e4Smiod   RELOC_22,			/* data[0:21] = (addend + sv) 		*/
272*3d8817e4Smiod   RELOC_13,			/* data[0:12] = (addend + sv)		*/
273*3d8817e4Smiod   RELOC_LO10,			/* data[0:9] = (addend + sv)		*/
274*3d8817e4Smiod   RELOC_SFA_BASE,
275*3d8817e4Smiod   RELOC_SFA_OFF13,
276*3d8817e4Smiod   /* P.I.C. (base-relative) */
277*3d8817e4Smiod   RELOC_BASE10,  		/* Not sure - maybe we can do this the */
278*3d8817e4Smiod   RELOC_BASE13,			/* right way now */
279*3d8817e4Smiod   RELOC_BASE22,
280*3d8817e4Smiod   /* for some sort of pc-rel P.I.C. (?) */
281*3d8817e4Smiod   RELOC_PC10,
282*3d8817e4Smiod   RELOC_PC22,
283*3d8817e4Smiod   /* P.I.C. jump table */
284*3d8817e4Smiod   RELOC_JMP_TBL,
285*3d8817e4Smiod   /* reputedly for shared libraries somehow */
286*3d8817e4Smiod   RELOC_SEGOFF16,
287*3d8817e4Smiod   RELOC_GLOB_DAT,
288*3d8817e4Smiod   RELOC_JMP_SLOT,
289*3d8817e4Smiod   RELOC_RELATIVE,
290*3d8817e4Smiod 
291*3d8817e4Smiod   RELOC_11,
292*3d8817e4Smiod   RELOC_WDISP2_14,
293*3d8817e4Smiod   RELOC_WDISP19,
294*3d8817e4Smiod   RELOC_HHI22,			/* data[0:21] = (addend + sv) >> 42     */
295*3d8817e4Smiod   RELOC_HLO10,			/* data[0:9] = (addend + sv) >> 32      */
296*3d8817e4Smiod 
297*3d8817e4Smiod   /* 29K relocation types */
298*3d8817e4Smiod   RELOC_JUMPTARG,
299*3d8817e4Smiod   RELOC_CONST,
300*3d8817e4Smiod   RELOC_CONSTH,
301*3d8817e4Smiod 
302*3d8817e4Smiod   NO_RELOC
303*3d8817e4Smiod   };
304*3d8817e4Smiod 
305*3d8817e4Smiod 
306*3d8817e4Smiod struct reloc_internal {
307*3d8817e4Smiod   bfd_vma r_address;		/* offset of of data to relocate 	*/
308*3d8817e4Smiod   long	r_index;		/* symbol table index of symbol 	*/
309*3d8817e4Smiod   enum reloc_type r_type;	/* relocation type			*/
310*3d8817e4Smiod   bfd_vma r_addend;		/* datum addend				*/
311*3d8817e4Smiod };
312*3d8817e4Smiod 
313*3d8817e4Smiod #endif				/* __A_OUT_ADOBE_H__ */
314