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