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