1 /* vi: set sw=4 ts=4: */
3 * Copyright (C) 2000-2006 by Erik Andersen <andersen@codepoet.org>
5 * GNU Lesser General Public License version 2.1 or later.
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
30 #define LIB_ELF64 0x80
31 #define LIB_ELF_LIBC5 2
32 #define LIB_ELF_LIBC6 3
33 #define LIB_ELF_LIBC0 4
35 #if defined(__LDSO_PRELOAD_FILE_SUPPORT__) || defined(__LDSO_CACHE_SUPPORT__)
36 #ifndef __LDSO_BASE_FILENAME__
37 #define __LDSO_BASE_FILENAME__ "ld.so"
39 #define LDSO_BASE_PATH UCLIBC_RUNTIME_PREFIX "etc/" __LDSO_BASE_FILENAME__
41 #ifdef __LDSO_PRELOAD_FILE_SUPPORT__
42 #define LDSO_PRELOAD LDSO_BASE_PATH ".preload"
45 #ifdef __LDSO_CACHE_SUPPORT__
46 #define LDSO_CONF LDSO_BASE_PATH ".conf"
47 #define LDSO_CACHE LDSO_BASE_PATH ".cache"
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)
55 char magic
[LDSO_CACHE_MAGIC_LEN
];
56 char version
[LDSO_CACHE_VER_LEN
];
66 #ifdef __ARCH_USE_MMU__
67 #define LDSO_CACHE_MMAP_FLAGS (MAP_SHARED)
69 #define LDSO_CACHE_MMAP_FLAGS (MAP_PRIVATE)
71 #endif /* __LDSO_CACHE_SUPPORT__ */
76 #ifndef __ARCH_HAS_NO_SHARED__
77 /* arch specific defines */
78 #include <dl-sysdep.h>
82 /* Provide a means for a port to pass additional arguments to the _dl_start
85 # define DL_START(X) static void * __attribute_used__ _dl_start(X)
88 /* Machines in which different sections may be relocated by different
89 * amounts should define this and LD_RELOC_ADDR. If you change this,
90 * make sure you change struct link_map in include/link.h accordingly
91 * such that it matches a prefix of struct elf_resolve.
93 #ifndef DL_LOADADDR_TYPE
94 # define DL_LOADADDR_TYPE ElfW(Addr)
97 /* When DL_LOADADDR_TYPE is not a scalar value, or some different
98 * computation is needed to relocate an address, define this.
100 #ifndef DL_RELOC_ADDR
101 # define DL_RELOC_ADDR(LOADADDR, ADDR) \
102 ((LOADADDR) + (ADDR))
105 /* Initialize the location of the dynamic addr. This is only called
106 * from DL_START, so additional arguments passed to it may be referenced. */
107 #ifndef DL_BOOT_COMPUTE_DYN
108 #define DL_BOOT_COMPUTE_DYN(DPNT, GOT, LOAD_ADDR) \
109 ((DPNT) = ((ElfW(Dyn) *) DL_RELOC_ADDR(LOAD_ADDR, GOT)))
112 /* Initialize the location of the global offset table. This is only called
113 * from DL_START, so additional arguments passed to it may be referenced. */
114 #ifndef DL_BOOT_COMPUTE_GOT
115 #define DL_BOOT_COMPUTE_GOT(GOT) \
116 ((GOT) = elf_machine_dynamic())
119 /* Initialize a LOADADDR representing the loader itself. It's only
120 * called from DL_START, so additional arguments passed to it may be
123 #ifndef DL_INIT_LOADADDR_BOOT
124 # define DL_INIT_LOADADDR_BOOT(LOADADDR, BASEADDR) \
125 ((LOADADDR) = (BASEADDR))
128 /* Define if any declarations/definitions of local variables are
129 * needed in a function that calls DT_INIT_LOADADDR or
130 * DL_INIT_LOADADDR_HDR. Declarations must be properly terminated
131 * with a semicolon, and non-declaration statements are forbidden.
133 #ifndef DL_INIT_LOADADDR_EXTRA_DECLS
134 # define DL_INIT_LOADADDR_EXTRA_DECLS /* int i; */
137 /* Prepare a DL_LOADADDR_TYPE data structure for incremental
138 * initialization with DL_INIT_LOADADDR_HDR, given pointers to a base
139 * load address and to program headers.
141 #ifndef DL_INIT_LOADADDR
142 # define DL_INIT_LOADADDR(LOADADDR, BASEADDR, PHDR, PHDRCNT) \
143 ((LOADADDR) = (BASEADDR))
146 /* Initialize a LOADADDR representing the program. It's called from
149 #ifndef DL_INIT_LOADADDR_PROG
150 # define DL_INIT_LOADADDR_PROG(LOADADDR, BASEADDR) \
151 ((LOADADDR) = (DL_LOADADDR_TYPE)(BASEADDR))
154 /* Update LOADADDR with information about PHDR, just mapped to the
156 #ifndef DL_INIT_LOADADDR_HDR
157 # define DL_INIT_LOADADDR_HDR(LOADADDR, ADDR, PHDR) /* Do nothing. */
160 /* Convert a DL_LOADADDR_TYPE to an identifying pointer. Used mostly
163 #ifndef DL_LOADADDR_BASE
164 # define DL_LOADADDR_BASE(LOADADDR) (LOADADDR)
167 /* Test whether a given ADDR is more likely to be within the memory
168 * region mapped to TPNT (a struct elf_resolve *) than to TFROM.
169 * Everywhere that this is used, TFROM is initially NULL, and whenever
170 * a potential match is found, it's updated. One might want to walk
171 * the chain of elf_resolve to locate the best match and return false
172 * whenever TFROM is non-NULL, or use an exact-matching algorithm
173 * using additional information encoded in DL_LOADADDR_TYPE to test
174 * for exact containment.
176 #ifndef DL_ADDR_IN_LOADADDR
177 # define DL_ADDR_IN_LOADADDR(ADDR, TPNT, TFROM) \
178 ((void*)(TPNT)->mapaddr < (void*)(ADDR) \
179 && (!(TFROM) || (TFROM)->mapaddr < (TPNT)->mapaddr))
182 /* This is called from dladdr() to give targets that use function descriptors
183 * a chance to map a function descriptor's address to the function's entry
184 * point before trying to find in which library it's defined. */
185 #ifndef DL_LOOKUP_ADDRESS
186 #define DL_LOOKUP_ADDRESS(ADDRESS) (ADDRESS)
189 /* On some architectures dladdr can't use st_size of all symbols this way. */
190 #define DL_ADDR_SYM_MATCH(SYM_ADDR, SYM, MATCHSYM, ADDR) \
191 ((ADDR) >= (SYM_ADDR) \
192 && ((((SYM)->st_shndx == SHN_UNDEF || (SYM)->st_size == 0) \
193 && (ADDR) == (SYM_ADDR)) \
194 || (ADDR) < (SYM_ADDR) + (SYM)->st_size) \
195 && (!(MATCHSYM) || MATCHSYM < (SYM_ADDR)))
197 /* Use this macro to convert a pointer to a function's entry point to
198 * a pointer to function. The pointer is assumed to have already been
199 * relocated. LOADADDR is passed because it may contain additional
200 * information needed to compute the pointer to function.
202 #ifndef DL_ADDR_TO_FUNC_PTR
203 # define DL_ADDR_TO_FUNC_PTR(ADDR, LOADADDR) ((void(*)(void))(ADDR))
206 /* On some platforms, computing a pointer to function is more
207 expensive than calling a function at a given address, so this
208 alternative is provided. The function signature must be given
209 within parentheses, as in a type cast. */
210 #ifndef DL_CALL_FUNC_AT_ADDR
211 # define DL_CALL_FUNC_AT_ADDR(ADDR, LOADADDR, SIGNATURE, ...) \
212 ((*SIGNATURE DL_ADDR_TO_FUNC_PTR ((ADDR), (LOADADDR)))(__VA_ARGS__))
215 /* An alignment value for a memory block returned by _dl_malloc. */
216 #ifndef DL_MALLOC_ALIGN
217 # define DL_MALLOC_ALIGN (__WORDSIZE / 8)
220 #ifdef __UCLIBC_UNDERSCORES__
221 # define __C_SYMBOL_PREFIX__ "_"
223 # define __C_SYMBOL_PREFIX__ ""
226 /* Define this if you want to modify the VALUE returned by
227 _dl_find_hash for this reloc TYPE. TPNT is the module in which the
228 matching SYM was found. */
229 #ifndef DL_FIND_HASH_VALUE
230 # define DL_FIND_HASH_VALUE(TPNT, TYPE, SYM) (DL_RELOC_ADDR ((TPNT)->loadaddr, (SYM)->st_value))
233 /* Unmap all previously-mapped segments accumulated in LOADADDR.
234 Generally used when an error occurs during loading. */
235 #ifndef DL_LOADADDR_UNMAP
236 # define DL_LOADADDR_UNMAP(LOADADDR, LEN) \
237 _dl_munmap((char *) (LOADADDR), (LEN))
240 /* Similar to DL_LOADADDR_UNMAP, but used for libraries that have been
241 dlopen()ed successfully, when they're dlclose()d. */
243 # define DL_LIB_UNMAP(LIB, LEN) (DL_LOADADDR_UNMAP ((LIB)->mapaddr, (LEN)))
246 /* Define this to verify that a library named LIBNAME, whose ELF
247 headers are pointed to by EPNT, is suitable for dynamic linking.
248 If it is not, print an error message (optional) and return NULL.
249 If the library can have its segments relocated independently,
250 arrange for PICLIB to be set to 2. If all segments have to be
251 relocated by the same amount, set it to 1. If it has to be loaded
252 at physical addresses as specified in the program headers, set it
253 to 0. A reasonable (?) guess for PICLIB will already be in place,
254 so it is safe to do nothing here. */
255 #ifndef DL_CHECK_LIB_TYPE
256 # define DL_CHECK_LIB_TYPE(EPNT, PICLIB, PROGNAME, LIBNAME) (void)0
259 /* Define this if you have special segment. */
260 #ifndef DL_IS_SPECIAL_SEGMENT
261 # define DL_IS_SPECIAL_SEGMENT(EPNT, PPNT) 0
264 /* Define this if you want to use special method to map the segment. */
265 #ifndef DL_MAP_SEGMENT
266 # define DL_MAP_SEGMENT(EPNT, PPNT, INFILE, FLAGS) 0
269 /* Define this to declare the library offset. */
270 #ifndef DL_DEF_LIB_OFFSET
271 # define DL_DEF_LIB_OFFSET static unsigned long _dl_library_offset
274 /* Define this to get the library offset. */
275 #ifndef DL_GET_LIB_OFFSET
276 # define DL_GET_LIB_OFFSET() _dl_library_offset
279 /* Define this to set the library offset as difference beetwen the mapped
280 library address and the smallest virtual address of the first PT_LOAD
282 #ifndef DL_SET_LIB_OFFSET
283 # define DL_SET_LIB_OFFSET(offset) (_dl_library_offset = (offset))
286 /* Define this to get the real object's runtime address. */
287 #ifndef DL_GET_RUN_ADDR
288 # define DL_GET_RUN_ADDR(loadaddr, mapaddr) (mapaddr)
291 #endif /* _DL_DEFS_H */