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