1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
|
/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License (the "License").
* You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
* Copyright (c) 1990, 2010, Oracle and/or its affiliates. All rights reserved.
*/
#ifndef _A_DOT_OUT_DOT_H
#define _A_DOT_OUT_DOT_H
#include <sys/types.h>
#include <sys/null.h>
#include <sys/mman.h>
#include <a.out.h>
#include <_rtld.h>
#ifdef __cplusplus
extern "C" {
#endif
#define max(a, b) ((a) < (b) ? (b) : (a))
typedef struct link_dynamic Link_dynamic;
/*
* Extern functions for a.out format file class.
*/
extern ulong_t aout_bndr(caddr_t);
extern int aout_get_mmap(Lm_list *, mmapobj_result_t *);
extern int aout_lookup_sym(Slookup *, Sresult *, uint_t *, int *);
extern Rt_map *aout_new_lmp(Lm_list *, Aliste, Fdesc *, Addr, size_t, void *,
Rt_map *, int *);
extern void aout_plt_write(caddr_t, ulong_t);
extern int aout_reloc(Rt_map *, uint_t, int *, APlist **);
extern void aout_rtbndr(caddr_t);
extern Fct *aout_verify(caddr_t, size_t, Fdesc *, const char *,
Rej_desc *);
/*
* Private data for an a.out format file class.
*/
typedef struct _rt_aout_private {
struct link_dynamic *lm_ld; /* 4.x aout dynamic pointer */
struct ld_private *lm_lpd; /* private aout object area */
} Rt_aoutp;
/*
* Special defines for a.out format file class.
*/
#define N_UNDF 0x0 /* undefined */
#define N_ABS 0x2 /* absolute */
#define N_COMM 0x12 /* common (internal to ld) */
#define N_EXT 01 /* external bit, or'ed in */
/*
* Format of a symbol table entry.
*/
struct nlist {
union {
char *n_name; /* for use when in-core */
long n_strx; /* index into file string table */
} n_un;
uchar_t n_type; /* type flag (N_TEXT,..) */
char n_other; /* unused */
short n_desc; /* see <stab.h> */
ulong_t n_value; /* value of symbol (or sdb offset) */
};
/*
* Link editor public definitions.
*/
#ifndef _link_h
#define _link_h
/*
* Structure describing logical name and requirements on an object
* which is to be loaded dynamically.
*/
struct old_link_object {
char *lo_name; /* name of object */
int lo_library : 1, /* searched for by library rules */
lo_unused : 31;
short lo_major; /* major version number */
short lo_minor; /* minor version number */
};
struct link_object {
long lo_name; /* name (often relative) */
int lo_library : 1, /* searched for by library rules */
lo_unused : 31;
short lo_major; /* major version number */
short lo_minor; /* minor version number */
long lo_next; /* next one (often relative) */
};
typedef struct link_object Lnk_obj;
/*
* Structure describing name and placement of dynamically loaded
* objects in a process' address space.
*/
typedef struct a_link_map A_link_map;
struct a_link_map {
caddr_t lm_addr; /* address at which object mapped */
char *lm_name; /* full name of loaded object */
struct a_link_map *lm_next; /* next object in map */
struct link_object *lm_lop; /* link object that got us here */
caddr_t lm_lob; /* base address for said link object */
int lm_rwt : 1; /* text is read/write */
struct link_dynamic *lm_ld; /* dynamic structure */
caddr_t lm_lpd; /* loader private data */
};
/*
* Version 1 of dynamic linking information. With the exception of
* ld_loaded (determined at execution time) and ld_stab_hash (a special
* case of relocation handled at execution time), the values in this
* structure reflect offsets from the containing link_dynamic structure.
*/
struct link_dynamic_1 {
struct a_link_map *ld_loaded; /* list of loaded objects */
long ld_need; /* list of needed objects */
long ld_rules; /* search rules for library objects */
long ld_got; /* global offset table */
long ld_plt; /* procedure linkage table */
long ld_rel; /* relocation table */
long ld_hash; /* symbol hash table */
long ld_stab; /* symbol table itself */
long (*ld_stab_hash)(); /* "pointer" to symbol hash function */
long ld_buckets; /* number of hash buckets */
long ld_symbols; /* symbol strings */
long ld_symb_size; /* size of symbol strings */
long ld_text; /* size of text area */
};
struct link_dynamic_2 {
struct a_link_map *ld_loaded; /* list of loaded objects */
long ld_need; /* list of needed objects */
long ld_rules; /* search rules for library objects */
long ld_got; /* global offset table */
long ld_plt; /* procedure linkage table */
long ld_rel; /* relocation table */
long ld_hash; /* symbol hash table */
long ld_stab; /* symbol table itself */
long (*ld_stab_hash)(); /* "pointer" to symbol hash function */
long ld_buckets; /* number of hash buckets */
long ld_symbols; /* symbol strings */
long ld_symb_size; /* size of symbol strings */
long ld_text; /* size of text area */
long ld_plt_sz; /* size of procedure linkage table */
};
/*
* Structure pointing to run time allocated common symbols and
* its string.
*/
struct rtc_symb {
struct nlist *rtc_sp; /* symbol for common */
struct rtc_symb *rtc_next; /* next common */
};
/*
* Debugger interface structure.
*/
struct ld_debug {
int ldd_version; /* version # of interface */
int ldd_in_debugger; /* a debugger is running us */
int ldd_sym_loaded; /* we loaded some symbols */
char *ldd_bp_addr; /* place for ld-generated bpt */
int ldd_bp_inst; /* instruction which was there */
struct rtc_symb *ldd_cp; /* commons we built */
};
/*
* Structure associated with each object which may be or which requires
* execution-time link editing. Used by the run-time linkage editor to
* identify needed objects and symbol definitions and references.
*/
struct old_link_dynamic {
int ld_version; /* version # of this structure */
union {
struct link_dynamic_1 ld_1;
} ld_un;
int in_debugging;
int sym_loaded;
char *bp_addr;
int bp_inst;
struct rtc_symb *cp; /* pointer to an array of runtime */
/* allocated common symbols. */
};
struct link_dynamic {
int ld_version; /* version # of this structure */
struct ld_debug *ldd;
union {
struct link_dynamic_1 *ld_1;
struct link_dynamic_2 *ld_2;
} ld_un;
};
/*
* Get size of relocations.
*/
#define GETGOTSZ(x) (x->ld_version < 2 ? \
((struct old_link_dynamic *)x)->v1.ld_plt - \
((struct old_link_dynamic *)x)->v1.ld_got : \
(x)->v2->ld_plt - (x)->v2->ld_got)
#define GETPLTSZ(x) (x->ld_version < 2 ? \
((struct old_link_dynamic *)x)->v1.ld_rel - \
((struct old_link_dynamic *)x)->v1.ld_plt : \
(x)->v2->ld_rel - (x)->v2->ld_plt)
#define GETRELSZ(x) (x->ld_version < 2 ? \
((struct old_link_dynamic *)x)->v1.ld_hash - \
((struct old_link_dynamic *)x)->v1.ld_rel : \
(x)->v2->ld_hash - (x)->v2->ld_rel)
#define GETHASHSZ(x) (x->ld_version < 2 ? \
((struct old_link_dynamic *)x)->v1.ld_stab - \
((struct old_link_dynamic *)x)->v1.ld_hash : \
(x)->v2->ld_stab - (x)->v2->ld_hash)
#define GETSTABSZ(x) (x->ld_version < 2 ? \
((struct old_link_dynamic *)x)->v1.ld_symbols -\
((struct old_link_dynamic *)x)->v1.ld_stab : \
(x)->v2->ld_symbols - (x)->v2->ld_stab)
#undef v2
#undef v1
#endif /* !_link_h */
#define MAIN_BASE 0x2000 /* base address of a.out in 4.x system */
/*
* Macros for getting to linker a.out format private data.
*/
#define AOUTPRV(X) ((X)->rt_priv)
#define AOUTDYN(X) (((Rt_aoutp *)(X)->rt_priv)->lm_ld)
#define LM2LP(X) ((struct ld_private *)((Rt_aoutp *) \
(X)->rt_priv)->lm_lpd)
#define TEXTBASE(X) (LM2LP(X)->lp_textbase)
/*
* Most of the above macros are used from AOUT specific routines, however there
* are a couple of instances where we need to ensure the file being processed
* is AOUT before dereferencing the macro.
*/
#define THIS_IS_AOUT(X) (FCT(X) == &aout_fct)
/*
* Code collapsing macros.
*/
#define v2 ld_un.ld_2
#define v1 ld_un.ld_1
#define JMPOFF(x) (x)->v2->ld_plt
#define RELOCOFF(x) (x)->v2->ld_rel
#define HASHOFF(x) (x)->v2->ld_hash
#define SYMOFF(x) (x)->v2->ld_stab
#define STROFF(x) (x)->v2->ld_symbols
struct jbind {
int jb_inst[3]; /* need 4 instructions for jump slot */
};
struct fshash {
int fssymbno; /* ordinal symbol number */
int next; /* index to the hash array pointed by fs_hash */
};
/*
* Sparc relocation types.
*/
enum reloc_type
{
RELOC_8, RELOC_16, RELOC_32, /* simplest relocs */
RELOC_DISP8, RELOC_DISP16, RELOC_DISP32, /* Disp's (pc-rel) */
RELOC_WDISP30, RELOC_WDISP22, /* SR word disp's */
RELOC_HI22, RELOC_22, /* SR 22-bit relocs */
RELOC_13, RELOC_LO10, /* SR 13&10-bit reloc */
RELOC_SFA_BASE, RELOC_SFA_OFF13, /* SR S.F.A. relocs */
RELOC_BASE10, RELOC_BASE13, RELOC_BASE22, /* base_relative pic */
RELOC_PC10, RELOC_PC22, /* special pc-rel pic */
RELOC_JMP_TBL, /* jmp_tbl_rel in pic */
RELOC_SEGOFF16, /* Shlib off-in-seg */
RELOC_GLOB_DAT, RELOC_JMP_SLOT, RELOC_RELATIVE /* rtld relocs */
};
/*
* Format of a relocation datum.
*/
#define r_symbolnum r_index
struct relocation_info /* used when header.a_machtype == M_SPARC */
{
ulong_t r_address; /* relocation addr (offset in seg) */
uint_t r_index :24; /* segment index or symbol index */
uint_t r_extern : 1; /* if F, r_index==SEG#; if T, SYM idx */
int : 2; /* <unused> */
enum reloc_type r_type : 5; /* type of relocation to perform */
long r_addend; /* addend for relocation value */
};
struct ld_private {
struct jbind *lp_plt; /* procedure linkage table */
struct relocation_info *lp_rp; /* relocation table */
struct fshash *lp_hash; /* hash table */
struct nlist *lp_symtab; /* symbol table */
char *lp_symstr; /* symbol strings */
caddr_t lp_textbase; /* base address for text addressing */
struct nlist *(*lp_interp)(); /* link map interpreter */
long lp_refcnt; /* reference count of link map */
struct dl_object *lp_dlp; /* pointer to a dlopen object */
caddr_t lp_symbol_base; /* base address for symbols */
};
/*
* Offsets of various sections of an object file.
*/
#define PAGSIZ 0x02000
#define SEGSIZ PAGSIZ
#define N_TXTOFF(x) \
/* text segment */ \
((x).a_magic == ZMAGIC ? 0 : sizeof (struct exec))
#define N_SYMOFF(x) \
/* symbol table */ \
(N_TXTOFF(x) + (x).a_text + (x).a_data + (x).a_trsize + (x).a_drsize)
#define SIZE(x) \
/* round to segment size */ \
(M_SROUND((x).a_text) + (x).a_data + (x).a_bss)
#ifdef __cplusplus
}
#endif
#endif /* _A_DOT_OUT_DOT_H */
|