| 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 without 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 | * $FreeBSD: src/include/link.h,v 1.20.2.2 2003/02/20 20:42:45 kan Exp $ |
| 31 | * $DragonFly: src/include/link.h,v 1.3 2003/11/14 01:01:43 dillon Exp $ |
| 32 | */ |
| 33 | |
| 34 | /* |
| 35 | * RRS section definitions. |
| 36 | * |
| 37 | * The layout of some data structures defined in this header file is |
| 38 | * such that we can provide compatibility with the SunOS 4.x shared |
| 39 | * library scheme. |
| 40 | */ |
| 41 | |
| 42 | #ifndef _LINK_H_ |
| 43 | #define _LINK_H_ |
| 44 | |
| 45 | #if (defined(FREEBSD_ELF) || defined(__ELF__)) && !defined(FREEBSD_AOUT) |
| 46 | |
| 47 | #include <sys/types.h> |
| 48 | |
| 49 | /* |
| 50 | * Flags that describe the origin of the entries in Dl_serinfo. |
| 51 | * SunOS has these in <sys/link.h>, we follow the suit. |
| 52 | */ |
| 53 | #define LA_SER_ORIG 0x01 /* original (needed) name */ |
| 54 | #define LA_SER_LIBPATH 0x02 /* LD_LIBRARY_PATH entry prepended */ |
| 55 | #define LA_SER_RUNPATH 0x04 /* runpath entry prepended */ |
| 56 | #define LA_SER_CONFIG 0x08 /* configuration entry prepended */ |
| 57 | #define LA_SER_DEFAULT 0x40 /* default path prepended */ |
| 58 | #define LA_SER_SECURE 0x80 /* default (secure) path prepended */ |
| 59 | |
| 60 | typedef struct link_map { |
| 61 | caddr_t l_addr; /* Base Address of library */ |
| 62 | #ifdef __mips__ |
| 63 | caddr_t l_offs; /* Load Offset of library */ |
| 64 | #endif |
| 65 | const char *l_name; /* Absolute Path to Library */ |
| 66 | const void *l_ld; /* Pointer to .dynamic in memory */ |
| 67 | struct link_map *l_next, *l_prev; /* linked list of of mapped libs */ |
| 68 | } Link_map; |
| 69 | |
| 70 | struct r_debug { |
| 71 | int r_version; /* not used */ |
| 72 | struct link_map *r_map; /* list of loaded images */ |
| 73 | void (*r_brk)(struct r_debug *, struct link_map *); |
| 74 | /* pointer to break point */ |
| 75 | enum { |
| 76 | RT_CONSISTENT, /* things are stable */ |
| 77 | RT_ADD, /* adding a shared library */ |
| 78 | RT_DELETE /* removing a shared library */ |
| 79 | } r_state; |
| 80 | }; |
| 81 | |
| 82 | #else /* !__ELF__ */ |
| 83 | |
| 84 | struct dl_info; |
| 85 | |
| 86 | /* |
| 87 | * A `Shared Object Descriptor' describes a shared object that is needed |
| 88 | * to complete the link edit process of the object containing it. |
| 89 | * A list of such objects (chained through `sod_next') is pointed at |
| 90 | * by `sdt_sods' in the section_dispatch_table structure. |
| 91 | */ |
| 92 | |
| 93 | struct sod { /* Shared Object Descriptor */ |
| 94 | long sod_name; /* name (relative to load address) */ |
| 95 | u_int sod_library : 1, /* Searched for by library rules */ |
| 96 | sod_reserved : 31; |
| 97 | short sod_major; /* major version number */ |
| 98 | short sod_minor; /* minor version number */ |
| 99 | long sod_next; /* next sod */ |
| 100 | }; |
| 101 | |
| 102 | /* |
| 103 | * `Shared Object Map's are used by the run-time link editor (ld.so) to |
| 104 | * keep track of all shared objects loaded into a process' address space. |
| 105 | * These structures are only used at run-time and do not occur within |
| 106 | * the text or data segment of an executable or shared library. |
| 107 | */ |
| 108 | struct so_map { /* Shared Object Map */ |
| 109 | caddr_t som_addr; /* Address at which object mapped */ |
| 110 | char *som_path; /* Path to mmap'ed file */ |
| 111 | struct so_map *som_next; /* Next map in chain */ |
| 112 | struct sod *som_sod; /* Sod responsible for this map */ |
| 113 | caddr_t som_sodbase; /* Base address of this sod */ |
| 114 | u_int som_write : 1; /* Text is currently writable */ |
| 115 | struct _dynamic *som_dynamic; /* _dynamic structure */ |
| 116 | caddr_t som_spd; /* Private data */ |
| 117 | }; |
| 118 | |
| 119 | /* |
| 120 | * Symbol description with size. This is simply an `nlist' with |
| 121 | * one field (nz_size) added. |
| 122 | * Used to convey size information on items in the data segment |
| 123 | * of shared objects. An array of these live in the shared object's |
| 124 | * text segment and is addressed by the `sdt_nzlist' field. |
| 125 | */ |
| 126 | struct nzlist { |
| 127 | struct nlist nlist; |
| 128 | u_long nz_size; |
| 129 | }; |
| 130 | |
| 131 | #define nz_un nlist.n_un |
| 132 | #define nz_strx nlist.n_un.n_strx |
| 133 | #define nz_name nlist.n_un.n_name |
| 134 | #define nz_type nlist.n_type |
| 135 | #define nz_value nlist.n_value |
| 136 | #define nz_desc nlist.n_desc |
| 137 | #define nz_other nlist.n_other |
| 138 | |
| 139 | /* |
| 140 | * The `section_dispatch_table' structure contains offsets to various data |
| 141 | * structures needed to do run-time relocation. |
| 142 | */ |
| 143 | struct section_dispatch_table { |
| 144 | struct so_map *sdt_loaded; /* List of loaded objects */ |
| 145 | long sdt_sods; /* List of shared objects descriptors */ |
| 146 | long sdt_paths; /* Library search paths */ |
| 147 | long sdt_got; /* Global offset table */ |
| 148 | long sdt_plt; /* Procedure linkage table */ |
| 149 | long sdt_rel; /* Relocation table */ |
| 150 | long sdt_hash; /* Symbol hash table */ |
| 151 | long sdt_nzlist; /* Symbol table itself */ |
| 152 | long sdt_filler2; /* Unused (was: stab_hash) */ |
| 153 | long sdt_buckets; /* Number of hash buckets */ |
| 154 | long sdt_strings; /* Symbol strings */ |
| 155 | long sdt_str_sz; /* Size of symbol strings */ |
| 156 | long sdt_text_sz; /* Size of text area */ |
| 157 | long sdt_plt_sz; /* Size of procedure linkage table */ |
| 158 | }; |
| 159 | |
| 160 | /* |
| 161 | * RRS symbol hash table, addressed by `sdt_hash' in section_dispatch_table. |
| 162 | * Used to quickly lookup symbols of the shared object by hashing |
| 163 | * on the symbol's name. `rh_symbolnum' is the index of the symbol |
| 164 | * in the shared object's symbol list (`sdt_nzlist'), `rh_next' is |
| 165 | * the next symbol in the hash bucket (in case of collisions). |
| 166 | */ |
| 167 | struct rrs_hash { |
| 168 | int rh_symbolnum; /* Symbol number */ |
| 169 | int rh_next; /* Next hash entry */ |
| 170 | }; |
| 171 | |
| 172 | /* |
| 173 | * `rt_symbols' is used to keep track of run-time allocated commons |
| 174 | * and data items copied from shared objects. |
| 175 | */ |
| 176 | struct rt_symbol { |
| 177 | struct nzlist *rt_sp; /* The symbol */ |
| 178 | struct rt_symbol *rt_next; /* Next in linear list */ |
| 179 | struct rt_symbol *rt_link; /* Next in bucket */ |
| 180 | caddr_t rt_srcaddr; /* Address of "master" copy */ |
| 181 | struct so_map *rt_smp; /* Originating map */ |
| 182 | }; |
| 183 | |
| 184 | /* |
| 185 | * Debugger interface structure. |
| 186 | */ |
| 187 | struct so_debug { |
| 188 | int dd_version; /* Version # of interface */ |
| 189 | int dd_in_debugger; /* Set when run by debugger */ |
| 190 | int dd_sym_loaded; /* Run-time linking brought more |
| 191 | symbols into scope */ |
| 192 | char *dd_bpt_addr; /* Address of rtld-generated bpt */ |
| 193 | int dd_bpt_shadow; /* Original contents of bpt */ |
| 194 | struct rt_symbol *dd_cc; /* Allocated commons/copied data */ |
| 195 | }; |
| 196 | |
| 197 | /* |
| 198 | * Version returned to crt0 from ld.so |
| 199 | */ |
| 200 | #define LDSO_VERSION_NONE 0 /* FreeBSD2.0, 2.0.5 */ |
| 201 | #define LDSO_VERSION_HAS_DLEXIT 1 /* includes dlexit in ld_entry */ |
| 202 | #define LDSO_VERSION_HAS_DLSYM3 2 /* includes 3-argument dlsym */ |
| 203 | #define LDSO_VERSION_HAS_DLADDR 3 /* includes dladdr in ld_entry */ |
| 204 | |
| 205 | /* |
| 206 | * Entry points into ld.so - user interface to the run-time linker. |
| 207 | * Entries are valid for the given version numbers returned by ld.so |
| 208 | * to crt0. |
| 209 | */ |
| 210 | struct ld_entry { |
| 211 | void *(*dlopen) (const char *, int); /* NONE */ |
| 212 | int (*dlclose) (void *); /* NONE */ |
| 213 | void *(*dlsym) (void *, const char *); /* NONE */ |
| 214 | const char *(*dlerror) (void); /* NONE */ |
| 215 | void (*dlexit) (void); /* HAS_DLEXIT */ |
| 216 | void *(*dlsym3) (void *, const char *, void *); /* HAS_DLSYM3 */ |
| 217 | int (*dladdr) (const void *, |
| 218 | struct dl_info *); /* HAS_DLADDR */ |
| 219 | }; |
| 220 | |
| 221 | /* |
| 222 | * This is the structure pointed at by the __DYNAMIC symbol if an |
| 223 | * executable requires the attention of the run-time link editor. |
| 224 | * __DYNAMIC is given the value zero if no run-time linking needs to |
| 225 | * be done (it is always present in shared objects). |
| 226 | * The union `d_un' provides for different versions of the dynamic |
| 227 | * linking mechanism (switched on by `d_version'). The last version |
| 228 | * used by Sun is 3. We leave some room here and go to version number |
| 229 | * 8 for NetBSD, the main difference lying in the support for the |
| 230 | * `nz_list' type of symbols. |
| 231 | */ |
| 232 | |
| 233 | struct _dynamic { |
| 234 | int d_version; /* version # of this interface */ |
| 235 | struct so_debug *d_debug; |
| 236 | union { |
| 237 | struct section_dispatch_table *d_sdt; |
| 238 | } d_un; |
| 239 | struct ld_entry *d_entry; /* XXX */ |
| 240 | }; |
| 241 | |
| 242 | #define LD_VERSION_SUN (3) |
| 243 | #define LD_VERSION_BSD (8) |
| 244 | #define LD_VERSION_NZLIST_P(v) ((v) >= 8) |
| 245 | |
| 246 | #define LD_GOT(x) ((x)->d_un.d_sdt->sdt_got) |
| 247 | #define LD_PLT(x) ((x)->d_un.d_sdt->sdt_plt) |
| 248 | #define LD_REL(x) ((x)->d_un.d_sdt->sdt_rel) |
| 249 | #define LD_SYMBOL(x) ((x)->d_un.d_sdt->sdt_nzlist) |
| 250 | #define LD_HASH(x) ((x)->d_un.d_sdt->sdt_hash) |
| 251 | #define LD_STRINGS(x) ((x)->d_un.d_sdt->sdt_strings) |
| 252 | #define LD_NEED(x) ((x)->d_un.d_sdt->sdt_sods) |
| 253 | #define LD_BUCKETS(x) ((x)->d_un.d_sdt->sdt_buckets) |
| 254 | #define LD_PATHS(x) ((x)->d_un.d_sdt->sdt_paths) |
| 255 | |
| 256 | #define LD_GOTSZ(x) ((x)->d_un.d_sdt->sdt_plt - (x)->d_un.d_sdt->sdt_got) |
| 257 | #define LD_RELSZ(x) ((x)->d_un.d_sdt->sdt_hash - (x)->d_un.d_sdt->sdt_rel) |
| 258 | #define LD_HASHSZ(x) ((x)->d_un.d_sdt->sdt_nzlist - (x)->d_un.d_sdt->sdt_hash) |
| 259 | #define LD_STABSZ(x) ((x)->d_un.d_sdt->sdt_strings - (x)->d_un.d_sdt->sdt_nzlist) |
| 260 | #define LD_PLTSZ(x) ((x)->d_un.d_sdt->sdt_plt_sz) |
| 261 | #define LD_STRSZ(x) ((x)->d_un.d_sdt->sdt_str_sz) |
| 262 | #define LD_TEXTSZ(x) ((x)->d_un.d_sdt->sdt_text_sz) |
| 263 | |
| 264 | /* |
| 265 | * Interface to ld.so |
| 266 | */ |
| 267 | struct crt_ldso { |
| 268 | int crt_ba; /* Base address of ld.so */ |
| 269 | int crt_dzfd; /* "/dev/zero" file descriptor (SunOS) */ |
| 270 | int crt_ldfd; /* ld.so file descriptor */ |
| 271 | struct _dynamic *crt_dp; /* Main's __DYNAMIC */ |
| 272 | char **crt_ep; /* environment strings */ |
| 273 | caddr_t crt_bp; /* Breakpoint if run from debugger */ |
| 274 | char *crt_prog; /* Program name (v3) */ |
| 275 | char *crt_ldso; /* Link editor name (v4) */ |
| 276 | struct ld_entry *crt_ldentry; /* dl*() access (v4) */ |
| 277 | char **crt_argv; /* argument strings (v5) */ |
| 278 | }; |
| 279 | |
| 280 | /* |
| 281 | * Version passed from crt0 to ld.so (1st argument to _rtld()). |
| 282 | */ |
| 283 | #define CRT_VERSION_SUN 1 |
| 284 | #define CRT_VERSION_BSD_2 2 |
| 285 | #define CRT_VERSION_BSD_3 3 |
| 286 | #define CRT_VERSION_BSD_4 4 |
| 287 | #define CRT_VERSION_BSD_5 5 |
| 288 | |
| 289 | /* |
| 290 | * Maximum number of recognized shared object version numbers. |
| 291 | */ |
| 292 | #define MAXDEWEY 8 |
| 293 | |
| 294 | /* |
| 295 | * Header of the hints file. |
| 296 | */ |
| 297 | struct hints_header { |
| 298 | long hh_magic; |
| 299 | #define HH_MAGIC 011421044151 |
| 300 | long hh_version; /* Interface version number */ |
| 301 | #define LD_HINTS_VERSION_1 1 |
| 302 | #define LD_HINTS_VERSION_2 2 |
| 303 | long hh_hashtab; /* Location of hash table */ |
| 304 | long hh_nbucket; /* Number of buckets in hashtab */ |
| 305 | long hh_strtab; /* Location of strings */ |
| 306 | long hh_strtab_sz; /* Size of strings */ |
| 307 | long hh_ehints; /* End of hints (max offset in file) */ |
| 308 | long hh_dirlist; /* Colon-separated list of srch dirs */ |
| 309 | }; |
| 310 | |
| 311 | #define HH_BADMAG(hdr) ((hdr).hh_magic != HH_MAGIC) |
| 312 | |
| 313 | /* |
| 314 | * Hash table element in hints file. |
| 315 | */ |
| 316 | struct hints_bucket { |
| 317 | /* namex and pathx are indices into the string table */ |
| 318 | int hi_namex; /* Library name */ |
| 319 | int hi_pathx; /* Full path */ |
| 320 | int hi_dewey[MAXDEWEY]; /* The versions */ |
| 321 | int hi_ndewey; /* Number of version numbers */ |
| 322 | #define hi_major hi_dewey[0] |
| 323 | #define hi_minor hi_dewey[1] |
| 324 | int hi_next; /* Next in this bucket */ |
| 325 | }; |
| 326 | |
| 327 | #define _PATH_LD_HINTS "/var/run/ld.so.hints" |
| 328 | |
| 329 | #endif /* !__ELF__ */ |
| 330 | |
| 331 | #endif /* _LINK_H_ */ |