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, Version 1.0 only 6 * (the "License"). You may not use this file except in compliance 7 * with the License. 8 * 9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10 * or http://www.opensolaris.org/os/licensing. 11 * See the License for the specific language governing permissions 12 * and limitations under the License. 13 * 14 * When distributing Covered Code, include this CDDL HEADER in each 15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16 * If applicable, add the following below this CDDL HEADER, with the 17 * fields enclosed by brackets "[]" replaced with your own identifying 18 * information: Portions Copyright [yyyy] [name of copyright owner] 19 * 20 * CDDL HEADER END 21 */ 22 /* 23 * Copyright 2005 Sun Microsystems, Inc. All rights reserved. 24 * Use is subject to license terms. 25 */ 26 27 #ifndef _A_DOT_OUT_DOT_H 28 #define _A_DOT_OUT_DOT_H 29 30 #pragma ident "%Z%%M% %I% %E% SMI" 31 32 #include <sys/types.h> 33 #include <a.out.h> 34 #include <_rtld.h> 35 36 #ifdef __cplusplus 37 extern "C" { 38 #endif 39 40 #define max(a, b) ((a) < (b) ? (b) : (a)) 41 42 typedef struct link_dynamic Link_dynamic; 43 44 /* 45 * Extern functions for a.out format file class. 46 */ 47 extern ulong_t aout_bndr(caddr_t); 48 extern Sym *aout_lookup_sym(Slookup *, Rt_map **, uint_t *); 49 extern Rt_map *aout_new_lm(Lm_list *, const char *, const char *, 50 Link_dynamic *, caddr_t, size_t, Aliste); 51 extern void aout_plt_write(caddr_t, ulong_t); 52 extern int aout_reloc(Rt_map *, uint_t); 53 extern void aout_rtbndr(caddr_t); 54 extern int aout_set_prot(Rt_map *, int); 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 * Code collapsing macros. 270 */ 271 #define v2 ld_un.ld_2 272 #define v1 ld_un.ld_1 273 #define JMPOFF(x) (x)->v2->ld_plt 274 #define RELOCOFF(x) (x)->v2->ld_rel 275 #define HASHOFF(x) (x)->v2->ld_hash 276 #define SYMOFF(x) (x)->v2->ld_stab 277 #define STROFF(x) (x)->v2->ld_symbols 278 279 struct jbind { 280 int jb_inst[3]; /* need 4 instructions for jump slot */ 281 }; 282 283 struct fshash { 284 int fssymbno; /* ordinal symbol number */ 285 int next; /* index to the hash array pointed by fs_hash */ 286 }; 287 288 /* 289 * Sparc relocation types. 290 */ 291 enum reloc_type 292 { 293 RELOC_8, RELOC_16, RELOC_32, /* simplest relocs */ 294 RELOC_DISP8, RELOC_DISP16, RELOC_DISP32, /* Disp's (pc-rel) */ 295 RELOC_WDISP30, RELOC_WDISP22, /* SR word disp's */ 296 RELOC_HI22, RELOC_22, /* SR 22-bit relocs */ 297 RELOC_13, RELOC_LO10, /* SR 13&10-bit reloc */ 298 RELOC_SFA_BASE, RELOC_SFA_OFF13, /* SR S.F.A. relocs */ 299 RELOC_BASE10, RELOC_BASE13, RELOC_BASE22, /* base_relative pic */ 300 RELOC_PC10, RELOC_PC22, /* special pc-rel pic */ 301 RELOC_JMP_TBL, /* jmp_tbl_rel in pic */ 302 RELOC_SEGOFF16, /* Shlib off-in-seg */ 303 RELOC_GLOB_DAT, RELOC_JMP_SLOT, RELOC_RELATIVE /* rtld relocs */ 304 }; 305 306 /* 307 * Format of a relocation datum. 308 */ 309 #define r_symbolnum r_index 310 311 struct relocation_info /* used when header.a_machtype == M_SPARC */ 312 { 313 ulong_t r_address; /* relocation addr (offset in seg) */ 314 uint_t r_index :24; /* segment index or symbol index */ 315 uint_t r_extern : 1; /* if F, r_index==SEG#; if T, SYM idx */ 316 int : 2; /* <unused> */ 317 enum reloc_type r_type : 5; /* type of relocation to perform */ 318 long r_addend; /* addend for relocation value */ 319 }; 320 321 struct ld_private { 322 struct jbind *lp_plt; /* procedure linkage table */ 323 struct relocation_info *lp_rp; /* relocation table */ 324 struct fshash *lp_hash; /* hash table */ 325 struct nlist *lp_symtab; /* symbol table */ 326 char *lp_symstr; /* symbol strings */ 327 caddr_t lp_textbase; /* base address for text addressing */ 328 struct nlist *(*lp_interp)(); /* link map interpreter */ 329 long lp_refcnt; /* reference count of link map */ 330 struct dl_object *lp_dlp; /* pointer to a dlopen object */ 331 caddr_t lp_symbol_base; /* base address for symbols */ 332 }; 333 334 335 /* 336 * Offsets of various sections of an object file. 337 */ 338 #define PAGSIZ 0x02000 339 #define SEGSIZ PAGSIZ 340 341 #define N_TXTOFF(x) \ 342 /* text segment */ \ 343 ((x).a_magic == ZMAGIC ? 0 : sizeof (struct exec)) 344 345 #define N_SYMOFF(x) \ 346 /* symbol table */ \ 347 (N_TXTOFF(x) + (x).a_text + (x).a_data + (x).a_trsize + (x).a_drsize) 348 349 #define SIZE(x) \ 350 /* round to segment size */ \ 351 (M_SROUND((x).a_text) + (x).a_data + (x).a_bss) 352 353 #ifdef __cplusplus 354 } 355 #endif 356 357 #endif /* _A_DOT_OUT_DOT_H */ 358