lh | 9ed821d | 2023-04-07 01:36:19 -0700 | [diff] [blame^] | 1 | /* vi: set sw=4 ts=4: */ |
| 2 | /* |
| 3 | * Copyright (C) 2000-2006 by Erik Andersen <andersen@codepoet.org> |
| 4 | * |
| 5 | * GNU Lesser General Public License version 2.1 or later. |
| 6 | */ |
| 7 | |
| 8 | #ifndef _LD_DEFS_H |
| 9 | #define _LD_DEFS_H |
| 10 | |
| 11 | #define FLAG_ANY -1 |
| 12 | #define FLAG_TYPE_MASK 0x00ff |
| 13 | #define FLAG_LIBC4 0x0000 |
| 14 | #define FLAG_ELF 0x0001 |
| 15 | #define FLAG_ELF_LIBC5 0x0002 |
| 16 | #define FLAG_ELF_LIBC6 0x0003 |
| 17 | #define FLAG_ELF_UCLIBC 0x0004 |
| 18 | #define FLAG_REQUIRED_MASK 0xff00 |
| 19 | #define FLAG_SPARC_LIB64 0x0100 |
| 20 | #define FLAG_IA64_LIB64 0x0200 |
| 21 | #define FLAG_X8664_LIB64 0x0300 |
| 22 | #define FLAG_S390_LIB64 0x0400 |
| 23 | #define FLAG_POWERPC_LIB64 0x0500 |
| 24 | #define FLAG_MIPS64_LIBN32 0x0600 |
| 25 | #define FLAG_MIPS64_LIBN64 0x0700 |
| 26 | |
| 27 | #define LIB_ANY -1 |
| 28 | #define LIB_DLL 0 |
| 29 | #define LIB_ELF 1 |
| 30 | #define LIB_ELF64 0x80 |
| 31 | #define LIB_ELF_LIBC5 2 |
| 32 | #define LIB_ELF_LIBC6 3 |
| 33 | #define LIB_ELF_LIBC0 4 |
| 34 | |
| 35 | #if defined(__LDSO_PRELOAD_FILE_SUPPORT__) || defined(__LDSO_CACHE_SUPPORT__) |
| 36 | #ifndef __LDSO_BASE_FILENAME__ |
| 37 | #define __LDSO_BASE_FILENAME__ "ld.so" |
| 38 | #endif |
| 39 | #define LDSO_BASE_PATH UCLIBC_RUNTIME_PREFIX "etc/" __LDSO_BASE_FILENAME__ |
| 40 | |
| 41 | #ifdef __LDSO_PRELOAD_FILE_SUPPORT__ |
| 42 | #define LDSO_PRELOAD LDSO_BASE_PATH ".preload" |
| 43 | #endif |
| 44 | |
| 45 | #ifdef __LDSO_CACHE_SUPPORT__ |
| 46 | #define LDSO_CONF LDSO_BASE_PATH ".conf" |
| 47 | #define LDSO_CACHE LDSO_BASE_PATH ".cache" |
| 48 | |
| 49 | #define LDSO_CACHE_MAGIC "ld.so-" |
| 50 | #define LDSO_CACHE_MAGIC_LEN (sizeof LDSO_CACHE_MAGIC -1) |
| 51 | #define LDSO_CACHE_VER "1.7.0" |
| 52 | #define LDSO_CACHE_VER_LEN (sizeof LDSO_CACHE_VER -1) |
| 53 | |
| 54 | typedef struct { |
| 55 | char magic [LDSO_CACHE_MAGIC_LEN]; |
| 56 | char version [LDSO_CACHE_VER_LEN]; |
| 57 | int nlibs; |
| 58 | } header_t; |
| 59 | |
| 60 | typedef struct { |
| 61 | int flags; |
| 62 | int sooffset; |
| 63 | int liboffset; |
| 64 | } libentry_t; |
| 65 | |
| 66 | #ifdef __ARCH_USE_MMU__ |
| 67 | #define LDSO_CACHE_MMAP_FLAGS (MAP_SHARED) |
| 68 | #else |
| 69 | #define LDSO_CACHE_MMAP_FLAGS (MAP_PRIVATE) |
| 70 | #endif |
| 71 | #endif /* __LDSO_CACHE_SUPPORT__ */ |
| 72 | |
| 73 | #endif |
| 74 | |
| 75 | /* Provide a means for a port to pass additional arguments to the _dl_start |
| 76 | function. */ |
| 77 | #ifndef DL_START |
| 78 | # define DL_START(X) static void * __attribute_used__ _dl_start(X) |
| 79 | #endif |
| 80 | |
| 81 | /* Machines in which different sections may be relocated by different |
| 82 | * amounts should define this and LD_RELOC_ADDR. If you change this, |
| 83 | * make sure you change struct link_map in include/link.h accordingly |
| 84 | * such that it matches a prefix of struct elf_resolve. |
| 85 | */ |
| 86 | #ifndef DL_LOADADDR_TYPE |
| 87 | # define DL_LOADADDR_TYPE ElfW(Addr) |
| 88 | #endif |
| 89 | |
| 90 | /* When DL_LOADADDR_TYPE is not a scalar value, or some different |
| 91 | * computation is needed to relocate an address, define this. |
| 92 | */ |
| 93 | #ifndef DL_RELOC_ADDR |
| 94 | # define DL_RELOC_ADDR(LOADADDR, ADDR) \ |
| 95 | ((LOADADDR) + (ADDR)) |
| 96 | #endif |
| 97 | |
| 98 | /* Initialize the location of the dynamic addr. This is only called |
| 99 | * from DL_START, so additional arguments passed to it may be referenced. */ |
| 100 | #ifndef DL_BOOT_COMPUTE_DYN |
| 101 | #define DL_BOOT_COMPUTE_DYN(DPNT, GOT, LOAD_ADDR) \ |
| 102 | ((DPNT) = ((ElfW(Dyn) *) DL_RELOC_ADDR(LOAD_ADDR, GOT))) |
| 103 | #endif |
| 104 | |
| 105 | /* Initialize the location of the global offset table. This is only called |
| 106 | * from DL_START, so additional arguments passed to it may be referenced. */ |
| 107 | #ifndef DL_BOOT_COMPUTE_GOT |
| 108 | #define DL_BOOT_COMPUTE_GOT(GOT) \ |
| 109 | ((GOT) = elf_machine_dynamic()) |
| 110 | #endif |
| 111 | |
| 112 | /* Initialize a LOADADDR representing the loader itself. It's only |
| 113 | * called from DL_START, so additional arguments passed to it may be |
| 114 | * referenced. |
| 115 | */ |
| 116 | #ifndef DL_INIT_LOADADDR_BOOT |
| 117 | # define DL_INIT_LOADADDR_BOOT(LOADADDR, BASEADDR) \ |
| 118 | ((LOADADDR) = (BASEADDR)) |
| 119 | #endif |
| 120 | |
| 121 | /* Define if any declarations/definitions of local variables are |
| 122 | * needed in a function that calls DT_INIT_LOADADDR or |
| 123 | * DL_INIT_LOADADDR_HDR. Declarations must be properly terminated |
| 124 | * with a semicolon, and non-declaration statements are forbidden. |
| 125 | */ |
| 126 | #ifndef DL_INIT_LOADADDR_EXTRA_DECLS |
| 127 | # define DL_INIT_LOADADDR_EXTRA_DECLS /* int i; */ |
| 128 | #endif |
| 129 | |
| 130 | /* Prepare a DL_LOADADDR_TYPE data structure for incremental |
| 131 | * initialization with DL_INIT_LOADADDR_HDR, given pointers to a base |
| 132 | * load address and to program headers. |
| 133 | */ |
| 134 | #ifndef DL_INIT_LOADADDR |
| 135 | # define DL_INIT_LOADADDR(LOADADDR, BASEADDR, PHDR, PHDRCNT) \ |
| 136 | ((LOADADDR) = (BASEADDR)) |
| 137 | #endif |
| 138 | |
| 139 | /* Initialize a LOADADDR representing the program. It's called from |
| 140 | * DL_BOOT only. |
| 141 | */ |
| 142 | #ifndef DL_INIT_LOADADDR_PROG |
| 143 | # define DL_INIT_LOADADDR_PROG(LOADADDR, BASEADDR) \ |
| 144 | ((LOADADDR) = (DL_LOADADDR_TYPE)(BASEADDR)) |
| 145 | #endif |
| 146 | |
| 147 | /* Update LOADADDR with information about PHDR, just mapped to the |
| 148 | given ADDR. */ |
| 149 | #ifndef DL_INIT_LOADADDR_HDR |
| 150 | # define DL_INIT_LOADADDR_HDR(LOADADDR, ADDR, PHDR) /* Do nothing. */ |
| 151 | #endif |
| 152 | |
| 153 | /* Convert a DL_LOADADDR_TYPE to an identifying pointer. Used mostly |
| 154 | * for debugging. |
| 155 | */ |
| 156 | #ifndef DL_LOADADDR_BASE |
| 157 | # define DL_LOADADDR_BASE(LOADADDR) (LOADADDR) |
| 158 | #endif |
| 159 | |
| 160 | /* Test whether a given ADDR is more likely to be within the memory |
| 161 | * region mapped to TPNT (a struct elf_resolve *) than to TFROM. |
| 162 | * Everywhere that this is used, TFROM is initially NULL, and whenever |
| 163 | * a potential match is found, it's updated. One might want to walk |
| 164 | * the chain of elf_resolve to locate the best match and return false |
| 165 | * whenever TFROM is non-NULL, or use an exact-matching algorithm |
| 166 | * using additional information encoded in DL_LOADADDR_TYPE to test |
| 167 | * for exact containment. |
| 168 | */ |
| 169 | #ifndef DL_ADDR_IN_LOADADDR |
| 170 | # define DL_ADDR_IN_LOADADDR(ADDR, TPNT, TFROM) \ |
| 171 | ((void*)(TPNT)->mapaddr < (void*)(ADDR) \ |
| 172 | && (!(TFROM) || (TFROM)->mapaddr < (TPNT)->mapaddr)) |
| 173 | #endif |
| 174 | |
| 175 | /* This is called from dladdr() to give targets that use function descriptors |
| 176 | * a chance to map a function descriptor's address to the function's entry |
| 177 | * point before trying to find in which library it's defined. */ |
| 178 | #ifndef DL_LOOKUP_ADDRESS |
| 179 | #define DL_LOOKUP_ADDRESS(ADDRESS) (ADDRESS) |
| 180 | #endif |
| 181 | |
| 182 | /* On some architectures dladdr can't use st_size of all symbols this way. */ |
| 183 | #define DL_ADDR_SYM_MATCH(SYM_ADDR, SYM, MATCHSYM, ADDR) \ |
| 184 | ((ADDR) >= (SYM_ADDR) \ |
| 185 | && ((((SYM)->st_shndx == SHN_UNDEF || (SYM)->st_size == 0) \ |
| 186 | && (ADDR) == (SYM_ADDR)) \ |
| 187 | || (ADDR) < (SYM_ADDR) + (SYM)->st_size) \ |
| 188 | && (!(MATCHSYM) || MATCHSYM < (SYM_ADDR))) |
| 189 | |
| 190 | /* Use this macro to convert a pointer to a function's entry point to |
| 191 | * a pointer to function. The pointer is assumed to have already been |
| 192 | * relocated. LOADADDR is passed because it may contain additional |
| 193 | * information needed to compute the pointer to function. |
| 194 | */ |
| 195 | #ifndef DL_ADDR_TO_FUNC_PTR |
| 196 | # define DL_ADDR_TO_FUNC_PTR(ADDR, LOADADDR) ((void(*)(void))(ADDR)) |
| 197 | #endif |
| 198 | |
| 199 | /* On some platforms, computing a pointer to function is more |
| 200 | expensive than calling a function at a given address, so this |
| 201 | alternative is provided. The function signature must be given |
| 202 | within parentheses, as in a type cast. */ |
| 203 | #ifndef DL_CALL_FUNC_AT_ADDR |
| 204 | # define DL_CALL_FUNC_AT_ADDR(ADDR, LOADADDR, SIGNATURE, ...) \ |
| 205 | ((*SIGNATURE DL_ADDR_TO_FUNC_PTR ((ADDR), (LOADADDR)))(__VA_ARGS__)) |
| 206 | #endif |
| 207 | |
| 208 | /* An alignment value for a memory block returned by _dl_malloc. */ |
| 209 | #ifndef DL_MALLOC_ALIGN |
| 210 | # define DL_MALLOC_ALIGN (__WORDSIZE / 8) |
| 211 | #endif |
| 212 | |
| 213 | #ifdef __UCLIBC_UNDERSCORES__ |
| 214 | # define __C_SYMBOL_PREFIX__ "_" |
| 215 | #else |
| 216 | # define __C_SYMBOL_PREFIX__ "" |
| 217 | #endif |
| 218 | |
| 219 | /* Define this if you want to modify the VALUE returned by |
| 220 | _dl_find_hash for this reloc TYPE. TPNT is the module in which the |
| 221 | matching SYM was found. */ |
| 222 | #ifndef DL_FIND_HASH_VALUE |
| 223 | # define DL_FIND_HASH_VALUE(TPNT, TYPE, SYM) (DL_RELOC_ADDR ((TPNT)->loadaddr, (SYM)->st_value)) |
| 224 | #endif |
| 225 | |
| 226 | /* Unmap all previously-mapped segments accumulated in LOADADDR. |
| 227 | Generally used when an error occurs during loading. */ |
| 228 | #ifndef DL_LOADADDR_UNMAP |
| 229 | # define DL_LOADADDR_UNMAP(LOADADDR, LEN) \ |
| 230 | _dl_munmap((char *) (LOADADDR), (LEN)) |
| 231 | #endif |
| 232 | |
| 233 | /* Similar to DL_LOADADDR_UNMAP, but used for libraries that have been |
| 234 | dlopen()ed successfully, when they're dlclose()d. */ |
| 235 | #ifndef DL_LIB_UNMAP |
| 236 | # define DL_LIB_UNMAP(LIB, LEN) (DL_LOADADDR_UNMAP ((LIB)->mapaddr, (LEN))) |
| 237 | #endif |
| 238 | |
| 239 | /* Define this to verify that a library named LIBNAME, whose ELF |
| 240 | headers are pointed to by EPNT, is suitable for dynamic linking. |
| 241 | If it is not, print an error message (optional) and return NULL. |
| 242 | If the library can have its segments relocated independently, |
| 243 | arrange for PICLIB to be set to 2. If all segments have to be |
| 244 | relocated by the same amount, set it to 1. If it has to be loaded |
| 245 | at physical addresses as specified in the program headers, set it |
| 246 | to 0. A reasonable (?) guess for PICLIB will already be in place, |
| 247 | so it is safe to do nothing here. */ |
| 248 | #ifndef DL_CHECK_LIB_TYPE |
| 249 | # define DL_CHECK_LIB_TYPE(EPNT, PICLIB, PROGNAME, LIBNAME) (void)0 |
| 250 | #endif |
| 251 | |
| 252 | /* Define this if you have special segment. */ |
| 253 | #ifndef DL_IS_SPECIAL_SEGMENT |
| 254 | # define DL_IS_SPECIAL_SEGMENT(EPNT, PPNT) 0 |
| 255 | #endif |
| 256 | |
| 257 | /* Define this if you want to use special method to map the segment. */ |
| 258 | #ifndef DL_MAP_SEGMENT |
| 259 | # define DL_MAP_SEGMENT(EPNT, PPNT, INFILE, FLAGS) 0 |
| 260 | #endif |
| 261 | |
| 262 | /* Define this to declare the library offset. */ |
| 263 | #ifndef DL_DEF_LIB_OFFSET |
| 264 | # define DL_DEF_LIB_OFFSET static unsigned long _dl_library_offset |
| 265 | #endif |
| 266 | |
| 267 | /* Define this to get the library offset. */ |
| 268 | #ifndef DL_GET_LIB_OFFSET |
| 269 | # define DL_GET_LIB_OFFSET() _dl_library_offset |
| 270 | #endif |
| 271 | |
| 272 | /* Define this to set the library offset as difference beetwen the mapped |
| 273 | library address and the smallest virtual address of the first PT_LOAD |
| 274 | segment. */ |
| 275 | #ifndef DL_SET_LIB_OFFSET |
| 276 | # define DL_SET_LIB_OFFSET(offset) (_dl_library_offset = (offset)) |
| 277 | #endif |
| 278 | |
| 279 | /* Define this to get the real object's runtime address. */ |
| 280 | #ifndef DL_GET_RUN_ADDR |
| 281 | # define DL_GET_RUN_ADDR(loadaddr, mapaddr) (mapaddr) |
| 282 | #endif |
| 283 | |
| 284 | #endif /* _LD_DEFS_H */ |