| 1 | /* |
| 2 | * Copyright (c) 1993 Paul Kranenburg |
| 3 | * All rights reserved. |
| 4 | * |
| 5 | * Redistribution and use in source and binary forms, with or without |
| 6 | * modification, are permitted provided that the following conditions |
| 7 | * are met: |
| 8 | * 1. Redistributions of source code must retain the above copyright |
| 9 | * notice, this list of conditions and the following disclaimer. |
| 10 | * 2. Redistributions in binary form must reproduce the above copyright |
| 11 | * notice, this list of conditions and the following disclaimer in the |
| 12 | * documentation and/or other materials provided with the distribution. |
| 13 | * 3. All advertising materials mentioning features or use of this software |
| 14 | * must display the following acknowledgement: |
| 15 | * This product includes software developed by Paul Kranenburg. |
| 16 | * 4. The name of the author may not be used to endorse or promote products |
| 17 | * derived from this software withough specific prior written permission |
| 18 | * |
| 19 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
| 20 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
| 21 | * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
| 22 | * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
| 23 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
| 24 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
| 25 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
| 26 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
| 27 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
| 28 | * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
| 29 | * |
| 30 | * $Id$ |
| 31 | */ |
| 32 | |
| 33 | /* |
| 34 | * RRS section definitions. |
| 35 | * |
| 36 | * The layout of some data structures defined in this header file is |
| 37 | * such that we can provide compatibility with the SunOS 4.x shared |
| 38 | * library scheme. |
| 39 | */ |
| 40 | |
| 41 | #ifndef _LINK_H_ |
| 42 | #define _LINK_H_ |
| 43 | |
| 44 | /* |
| 45 | * A `Shared Object Descriptor' descibes a shared object that is needed |
| 46 | * to complete the link edit process of the object containing it. |
| 47 | * A list of such objects (chained through `sod_next') is pointed at |
| 48 | * by `sdt_sods' in the section_dispatch_table structure. |
| 49 | */ |
| 50 | |
| 51 | struct sod { /* Shared Object Descriptor */ |
| 52 | long sod_name; /* name (relative to load address) */ |
| 53 | u_int sod_library : 1, /* Searched for by library rules */ |
| 54 | sod_reserved : 31; |
| 55 | short sod_major; /* major version number */ |
| 56 | short sod_minor; /* minor version number */ |
| 57 | long sod_next; /* next sod */ |
| 58 | }; |
| 59 | |
| 60 | /* |
| 61 | * `Shared Object Map's are used by the run-time link editor (ld.so) to |
| 62 | * keep track of all shared objects loaded into a process' address space. |
| 63 | * These structures are only used at run-time and do not occur within |
| 64 | * the text or data segment of an executable or shared library. |
| 65 | */ |
| 66 | struct so_map { /* Shared Object Map */ |
| 67 | caddr_t som_addr; /* Address at which object mapped */ |
| 68 | char *som_path; /* Path to mmap'ed file */ |
| 69 | struct so_map *som_next; /* Next map in chain */ |
| 70 | struct sod *som_sod; /* Sod responsible for this map */ |
| 71 | caddr_t som_sodbase; /* Base address of this sod */ |
| 72 | u_int som_write : 1; /* Text is currently writable */ |
| 73 | struct _dynamic *som_dynamic; /* _dynamic structure */ |
| 74 | caddr_t som_spd; /* Private data */ |
| 75 | }; |
| 76 | |
| 77 | /* |
| 78 | * Symbol description with size. This is simply an `nlist' with |
| 79 | * one field (nz_size) added. |
| 80 | * Used to convey size information on items in the data segment |
| 81 | * of shared objects. An array of these live in the shared object's |
| 82 | * text segment and is addressed by the `sdt_nzlist' field. |
| 83 | */ |
| 84 | struct nzlist { |
| 85 | struct nlist nlist; |
| 86 | u_long nz_size; |
| 87 | #define nz_un nlist.n_un |
| 88 | #define nz_strx nlist.n_un.n_strx |
| 89 | #define nz_name nlist.n_un.n_name |
| 90 | #define nz_type nlist.n_type |
| 91 | #define nz_value nlist.n_value |
| 92 | #define nz_desc nlist.n_desc |
| 93 | #define nz_other nlist.n_other |
| 94 | }; |
| 95 | |
| 96 | #define N_AUX(p) ((p)->n_other & 0xf) |
| 97 | #define N_RESERVED(p) (((unsigned int)(p)->n_other >> 4) & 0xf) |
| 98 | #define N_OTHER(r, v) (((unsigned int)(r) << 4) | ((v) & 0xf)) |
| 99 | |
| 100 | #define AUX_OBJECT 1 |
| 101 | #define AUX_FUNC 2 |
| 102 | |
| 103 | |
| 104 | /* |
| 105 | * The `section_dispatch_table' structure contains offsets to various data |
| 106 | * structures needed to do run-time relocation. |
| 107 | */ |
| 108 | struct section_dispatch_table { |
| 109 | struct so_map *sdt_loaded; /* List of loaded objects */ |
| 110 | long sdt_sods; /* List of shared objects descriptors */ |
| 111 | long sdt_filler1; /* Unused (was: search rules) */ |
| 112 | long sdt_got; /* Global offset table */ |
| 113 | long sdt_plt; /* Procedure linkage table */ |
| 114 | long sdt_rel; /* Relocation table */ |
| 115 | long sdt_hash; /* Symbol hash table */ |
| 116 | long sdt_nzlist; /* Symbol table itself */ |
| 117 | long sdt_filler2; /* Unused (was: stab_hash) */ |
| 118 | long sdt_buckets; /* Number of hash buckets */ |
| 119 | long sdt_strings; /* Symbol strings */ |
| 120 | long sdt_str_sz; /* Size of symbol strings */ |
| 121 | long sdt_text_sz; /* Size of text area */ |
| 122 | long sdt_plt_sz; /* Size of procedure linkage table */ |
| 123 | }; |
| 124 | |
| 125 | /* |
| 126 | * RRS symbol hash table, addressed by `sdt_hash' in section_dispatch_table. |
| 127 | * Used to quickly lookup symbols of the shared object by hashing |
| 128 | * on the symbol's name. `rh_symbolnum' is the index of the symbol |
| 129 | * in the shared object's symbol list (`sdt_nzlist'), `rh_next' is |
| 130 | * the next symbol in the hash bucket (in case of collisions). |
| 131 | */ |
| 132 | struct rrs_hash { |
| 133 | int rh_symbolnum; /* Symbol number */ |
| 134 | int rh_next; /* Next hash entry */ |
| 135 | }; |
| 136 | |
| 137 | /* |
| 138 | * `rt_symbols' is used to keep track of run-time allocated commons |
| 139 | * and data items copied from shared objects. |
| 140 | */ |
| 141 | struct rt_symbol { |
| 142 | struct nzlist *rt_sp; /* The symbol */ |
| 143 | struct rt_symbol *rt_next; /* Next in linear list */ |
| 144 | struct rt_symbol *rt_link; /* Next in bucket */ |
| 145 | caddr_t rt_srcaddr; /* Address of "master" copy */ |
| 146 | struct so_map *rt_smp; /* Originating map */ |
| 147 | }; |
| 148 | |
| 149 | /* |
| 150 | * Debugger interface structure. |
| 151 | */ |
| 152 | struct so_debug { |
| 153 | int dd_version; /* Version # of interface */ |
| 154 | int dd_in_debugger; /* Set when run by debugger */ |
| 155 | int dd_sym_loaded; /* Run-time linking brought more |
| 156 | symbols into scope */ |
| 157 | char *dd_bpt_addr; /* Address of rtld-generated bpt */ |
| 158 | int dd_bpt_shadow; /* Original contents of bpt */ |
| 159 | struct rt_symbol *dd_cc; /* Allocated commons/copied data */ |
| 160 | }; |
| 161 | |
| 162 | /* |
| 163 | * Entry points into ld.so - user interface to the run-time linker. |
| 164 | */ |
| 165 | struct ld_entry { |
| 166 | void *(*dlopen) __P((char *, int)); |
| 167 | int (*dlclose) __P((void *)); |
| 168 | void *(*dlsym) __P((void *, char *)); |
| 169 | int (*dlctl) __P((void *, int, void *)); |
| 170 | }; |
| 171 | |
| 172 | /* |
| 173 | * dlctl() commands |
| 174 | */ |
| 175 | #define DL_GETERRNO 1 |
| 176 | |
| 177 | /* |
| 178 | * dl*() prototypes. |
| 179 | */ |
| 180 | extern void *dlopen __P((char *, int)); |
| 181 | extern int dlclose __P((void *)); |
| 182 | extern void *dlsym __P((void *, char *)); |
| 183 | extern int dlctl __P((void *, int, void *)); |
| 184 | |
| 185 | |
| 186 | /* |
| 187 | * This is the structure pointed at by the __DYNAMIC symbol if an |
| 188 | * executable requires the attention of the run-time link editor. |
| 189 | * __DYNAMIC is given the value zero if no run-time linking needs to |
| 190 | * be done (it is always present in shared objects). |
| 191 | * The union `d_un' provides for different versions of the dynamic |
| 192 | * linking mechanism (switched on by `d_version'). The last version |
| 193 | * used by Sun is 3. We leave some room here and go to version number |
| 194 | * 8 for NetBSD, the main difference lying in the support for the |
| 195 | * `nz_list' type of symbols. |
| 196 | */ |
| 197 | |
| 198 | struct _dynamic { |
| 199 | int d_version; /* version # of this interface */ |
| 200 | struct so_debug *d_debug; |
| 201 | union { |
| 202 | struct section_dispatch_table *d_sdt; |
| 203 | } d_un; |
| 204 | struct ld_entry *d_entry; |
| 205 | }; |
| 206 | |
| 207 | #define LD_VERSION_SUN (3) |
| 208 | #define LD_VERSION_BSD (8) |
| 209 | #define LD_VERSION_NZLIST_P(v) ((v) >= 8) |
| 210 | |
| 211 | #define LD_GOT(x) ((x)->d_un.d_sdt->sdt_got) |
| 212 | #define LD_PLT(x) ((x)->d_un.d_sdt->sdt_plt) |
| 213 | #define LD_REL(x) ((x)->d_un.d_sdt->sdt_rel) |
| 214 | #define LD_SYMBOL(x) ((x)->d_un.d_sdt->sdt_nzlist) |
| 215 | #define LD_HASH(x) ((x)->d_un.d_sdt->sdt_hash) |
| 216 | #define LD_STRINGS(x) ((x)->d_un.d_sdt->sdt_strings) |
| 217 | #define LD_NEED(x) ((x)->d_un.d_sdt->sdt_sods) |
| 218 | #define LD_BUCKETS(x) ((x)->d_un.d_sdt->sdt_buckets) |
| 219 | |
| 220 | #define LD_GOTSZ(x) ((x)->d_un.d_sdt->sdt_plt - (x)->d_un.d_sdt->sdt_got) |
| 221 | #define LD_RELSZ(x) ((x)->d_un.d_sdt->sdt_hash - (x)->d_un.d_sdt->sdt_rel) |
| 222 | #define LD_HASHSZ(x) ((x)->d_un.d_sdt->sdt_nzlist - (x)->d_un.d_sdt->sdt_hash) |
| 223 | #define LD_STABSZ(x) ((x)->d_un.d_sdt->sdt_strings - (x)->d_un.d_sdt->sdt_nzlist) |
| 224 | #define LD_PLTSZ(x) ((x)->d_un.d_sdt->sdt_plt_sz) |
| 225 | #define LD_STRSZ(x) ((x)->d_un.d_sdt->sdt_str_sz) |
| 226 | #define LD_TEXTSZ(x) ((x)->d_un.d_sdt->sdt_text_sz) |
| 227 | |
| 228 | /* |
| 229 | * Interface to ld.so |
| 230 | */ |
| 231 | struct crt_ldso { |
| 232 | int crt_ba; /* Base address of ld.so */ |
| 233 | int crt_dzfd; /* "/dev/zero" file decriptor (SunOS) */ |
| 234 | int crt_ldfd; /* ld.so file descriptor */ |
| 235 | struct _dynamic *crt_dp; /* Main's __DYNAMIC */ |
| 236 | char **crt_ep; /* environment strings */ |
| 237 | caddr_t crt_bp; /* Breakpoint if run from debugger */ |
| 238 | char *crt_prog; /* Program name */ |
| 239 | }; |
| 240 | |
| 241 | /* |
| 242 | * Version passed from crt0 to ld.so (1st argument to _rtld()). |
| 243 | */ |
| 244 | #define CRT_VERSION_SUN 1 |
| 245 | #define CRT_VERSION_BSD 2 |
| 246 | #define CRT_VERSION_BSD_2 2 |
| 247 | #define CRT_VERSION_BSD_3 3 |
| 248 | |
| 249 | |
| 250 | /* |
| 251 | * Maximum number of recognized shared object version numbers. |
| 252 | */ |
| 253 | #define MAXDEWEY 8 |
| 254 | |
| 255 | /* |
| 256 | * Header of the hints file. |
| 257 | */ |
| 258 | struct hints_header { |
| 259 | long hh_magic; |
| 260 | #define HH_MAGIC 011421044151 |
| 261 | long hh_version; /* Interface version number */ |
| 262 | #define LD_HINTS_VERSION_1 1 |
| 263 | long hh_hashtab; /* Location of hash table */ |
| 264 | long hh_nbucket; /* Number of buckets in hashtab */ |
| 265 | long hh_strtab; /* Location of strings */ |
| 266 | long hh_strtab_sz; /* Size of strings */ |
| 267 | long hh_ehints; /* End of hints (max offset in file) */ |
| 268 | }; |
| 269 | |
| 270 | #define HH_BADMAG(hdr) ((hdr).hh_magic != HH_MAGIC) |
| 271 | |
| 272 | /* |
| 273 | * Hash table element in hints file. |
| 274 | */ |
| 275 | struct hints_bucket { |
| 276 | /* namex and pathx are indices into the string table */ |
| 277 | int hi_namex; /* Library name */ |
| 278 | int hi_pathx; /* Full path */ |
| 279 | int hi_dewey[MAXDEWEY]; /* The versions */ |
| 280 | int hi_ndewey; /* Number of version numbers */ |
| 281 | #define hi_major hi_dewey[0] |
| 282 | #define hi_minor hi_dewey[1] |
| 283 | int hi_next; /* Next in this bucket */ |
| 284 | }; |
| 285 | |
| 286 | #define _PATH_LD_HINTS "/var/run/ld.so.hints" |
| 287 | |
| 288 | #endif /* _LINK_H_ */ |
| 289 | |