diff options
-rw-r--r-- | ldso/include/dl-defs.h | 12 | ||||
-rw-r--r-- | ldso/include/dl-hash.h | 2 | ||||
-rw-r--r-- | ldso/ldso/dl-elf.c | 11 | ||||
-rw-r--r-- | ldso/ldso/dl-startup.c | 2 | ||||
-rw-r--r-- | ldso/ldso/ldso.c | 8 | ||||
-rw-r--r-- | ldso/libdl/libdl.c | 8 |
6 files changed, 27 insertions, 16 deletions
diff --git a/ldso/include/dl-defs.h b/ldso/include/dl-defs.h index 932f6ac53..d0c61d44e 100644 --- a/ldso/include/dl-defs.h +++ b/ldso/include/dl-defs.h @@ -140,4 +140,16 @@ typedef struct { && (!(TFROM) || (TFROM)->loadaddr < (TPNT)->loadaddr)) #endif +/* On some platforms, computing a pointer to function is more + expensive than calling a function at a given address, so this + alternative is provided. The function signature must be given + within parentheses, as in a type cast. */ +#ifndef DL_ADDR_TO_FUNC_PTR +# define DL_ADDR_TO_FUNC_PTR(ADDR, LOADADDR) (ADDR) +#endif +#ifndef DL_CALL_FUNC_AT_ADDR +# define DL_CALL_FUNC_AT_ADDR(ADDR, LOADADDR, SIGNATURE, ...) \ + ((*SIGNATURE DL_ADDR_TO_FUNC_PTR ((ADDR), (LOADADDR)))(__VA_ARGS__)) +#endif + #endif /* _LD_DEFS_H */ diff --git a/ldso/include/dl-hash.h b/ldso/include/dl-hash.h index 8f30688d1..c21094020 100644 --- a/ldso/include/dl-hash.h +++ b/ldso/include/dl-hash.h @@ -28,7 +28,7 @@ struct dyn_elf { struct elf_resolve { /* These entries must be in this order to be compatible with the interface used by gdb to obtain the list of symbols. */ - DL_LOADADDR_TYPE loadaddr; /* Base address shared object is loaded at. */ + DL_LOADADDR_TYPE loadaddr; /* Base address shared object is loaded at. */ char *libname; /* Absolute file name object was found in. */ ElfW(Dyn) *dynamic_addr; /* Dynamic section of the shared object. */ struct elf_resolve * next; diff --git a/ldso/ldso/dl-elf.c b/ldso/ldso/dl-elf.c index 443b0802e..31dd75729 100644 --- a/ldso/ldso/dl-elf.c +++ b/ldso/ldso/dl-elf.c @@ -118,10 +118,9 @@ int _dl_unmap_cache(void) void _dl_protect_relro (struct elf_resolve *l) { - ElfW(Addr) start = (DL_RELOC_ADDR(l->loadaddr, l->relro_addr) - & ~(_dl_pagesize - 1)); - ElfW(Addr) end = ((DL_RELOC_ADDR(l->loadaddr, l->relro_addr) + l->relro_size) - & ~(_dl_pagesize - 1)); + ElfW(Addr) base = (ElfW(Addr)) DL_RELOC_ADDR(l->loadaddr, l->relro_addr); + ElfW(Addr) start = (base & ~(_dl_pagesize - 1)); + ElfW(Addr) end = ((base + l->relro_size) & ~(_dl_pagesize - 1)); _dl_if_debug_dprint("RELRO protecting %s: start:%x, end:%x\n", l->libname, start, end); if (start != end && _dl_mprotect ((void *) start, end - start, PROT_READ) < 0) { @@ -628,7 +627,7 @@ struct elf_resolve *_dl_load_elf_shared_library(int secure, } _dl_if_debug_dprint("\n\tfile='%s'; generating link map\n", libname); - _dl_if_debug_dprint("\t\tdynamic: %x base: %x\n", dynamic_addr, DL_LOADADDR_BASE(libaddr)); + _dl_if_debug_dprint("\t\tdynamic: %x base: %x\n", dynamic_addr, DL_LOADADDR_BASE(lib_loadaddr)); _dl_if_debug_dprint("\t\t entry: %x phdr: %x phnum: %x\n\n", DL_RELOC_ADDR(lib_loadaddr, epnt->e_entry), tpnt->ppnt, tpnt->n_phent); @@ -822,7 +821,7 @@ __dl_iterate_phdr (int (*callback) (struct dl_phdr_info *info, size_t size, void int ret = 0; for (l = _dl_loaded_modules; l != NULL; l = l->next) { - info.dlpi_addr = DL_LOADADDR_BASE(l->loadaddr); + info.dlpi_addr = l->loadaddr; info.dlpi_name = l->libname; info.dlpi_phdr = l->ppnt; info.dlpi_phnum = l->n_phent; diff --git a/ldso/ldso/dl-startup.c b/ldso/ldso/dl-startup.c index a3764449e..e3bbfa3a1 100644 --- a/ldso/ldso/dl-startup.c +++ b/ldso/ldso/dl-startup.c @@ -259,7 +259,7 @@ static void * __attribute_used__ _dl_start(unsigned long args) rel_addr += relative_count * sizeof(ELF_RELOC); } - rpnt = (ELF_RELOC *) DL_RELOC_ADDR(load_addr, rel_addr); + rpnt = (ELF_RELOC *) rel_addr; for (i = 0; i < rel_size; i += sizeof(ELF_RELOC), rpnt++) { reloc_addr = (unsigned long *) DL_RELOC_ADDR(load_addr, (unsigned long)rpnt->r_offset); symtab_index = ELF_R_SYM(rpnt->r_info); diff --git a/ldso/ldso/ldso.c b/ldso/ldso/ldso.c index d5b87d5eb..f8f3dc67c 100644 --- a/ldso/ldso/ldso.c +++ b/ldso/ldso/ldso.c @@ -113,7 +113,7 @@ static void _dl_run_array_forward(unsigned long array, unsigned long size, for (j = 0; j < jm; ++j) { void (*dl_elf_func) (void); dl_elf_func = (void (*)(void)) (intptr_t) addrs[j]; - (*dl_elf_func) (); + DL_CALL_FUNC_AT_ADDR (dl_elf_func, loadaddr, (void (*)(void))); } } } @@ -141,7 +141,7 @@ void _dl_run_fini_array(struct elf_resolve *tpnt) while (i-- > 0) { void (*dl_elf_func) (void); dl_elf_func = (void (*)(void)) (intptr_t) array[i]; - (*dl_elf_func) (); + DL_CALL_FUNC_AT_ADDR (dl_elf_func, tpnt->loadaddr, (void (*)(void))); } } } @@ -168,7 +168,7 @@ static void __attribute__ ((destructor)) __attribute_used__ _dl_fini(void) dl_elf_func = (void (*)(void)) (intptr_t) DL_RELOC_ADDR(tpnt->loadaddr, tpnt->dynamic_info[DT_FINI]); _dl_if_debug_dprint("\ncalling FINI: %s\n\n", tpnt->libname); - (*dl_elf_func) (); + DL_CALL_FUNC_AT_ADDR (dl_elf_func, tpnt->loadaddr, (void(*)(void))); } } } @@ -852,7 +852,7 @@ void _dl_get_ready_to_run(struct elf_resolve *tpnt, DL_LOADADDR_TYPE load_addr, _dl_if_debug_dprint("calling INIT: %s\n\n", tpnt->libname); - (*dl_elf_func) (); + DL_CALL_FUNC_AT_ADDR (dl_elf_func, tpnt->loadaddr, (void(*)(void))); } _dl_run_init_array(tpnt); diff --git a/ldso/libdl/libdl.c b/ldso/libdl/libdl.c index 79b181628..e7e33c426 100644 --- a/ldso/libdl/libdl.c +++ b/ldso/libdl/libdl.c @@ -378,10 +378,10 @@ void *dlopen(const char *libname, int flag) if (tpnt->dynamic_info[DT_INIT]) { void (*dl_elf_func) (void); dl_elf_func = (void (*)(void)) DL_RELOC_ADDR(tpnt->loadaddr, tpnt->dynamic_info[DT_INIT]); - if (dl_elf_func && *dl_elf_func != NULL) { + if (dl_elf_func) { _dl_if_debug_print("running ctors for library %s at '%p'\n", tpnt->libname, dl_elf_func); - (*dl_elf_func) (); + DL_CALL_FUNC_AT_ADDR (dl_elf_func, tpnt->loadaddr, (void(*)(void))); } } @@ -513,7 +513,7 @@ static int do_dlclose(void *vhandle, int need_fini) dl_elf_fini = (int (*)(void)) DL_RELOC_ADDR(tpnt->loadaddr, tpnt->dynamic_info[DT_FINI]); _dl_if_debug_print("running dtors for library %s at '%p'\n", tpnt->libname, dl_elf_fini); - (*dl_elf_fini) (); + DL_CALL_FUNC_AT_ADDR (dl_elf_fini, tpnt->loadaddr, (int (*)(void))); } } @@ -660,7 +660,7 @@ int dladdr(const void *__address, Dl_info * __info) _dl_if_debug_print("Module \"%s\" at %p\n", tpnt->libname, DL_LOADADDR_BASE(tpnt->loadaddr)); - if (DL_ADDR_IN_LOADADDR((ElfW(Addr)) __address, tpnt, pelf)) + if (DL_ADDR_IN_LOADADDR((ElfW(Addr)) __address, tpnt, pelf)) pelf = tpnt; } |