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