diff options
-rw-r--r-- | ldso/include/dl-defs.h | 66 | ||||
-rw-r--r-- | ldso/include/dl-elf.h | 9 | ||||
-rw-r--r-- | ldso/include/dl-hash.h | 4 | ||||
-rw-r--r-- | ldso/include/ldso.h | 2 | ||||
-rw-r--r-- | ldso/ldso/dl-elf.c | 38 | ||||
-rw-r--r-- | ldso/ldso/dl-hash.c | 16 | ||||
-rw-r--r-- | ldso/ldso/dl-startup.c | 15 | ||||
-rw-r--r-- | ldso/ldso/ldso.c | 73 | ||||
-rw-r--r-- | ldso/libdl/libdl.c | 22 |
9 files changed, 78 insertions, 167 deletions
diff --git a/ldso/include/dl-defs.h b/ldso/include/dl-defs.h index dc6531d19..878ebc3b8 100644 --- a/ldso/include/dl-defs.h +++ b/ldso/include/dl-defs.h @@ -66,70 +66,4 @@ typedef struct { #endif -/* Machines in which different sections may be relocated by different - amounts should define this and LD_RELOC_ADDR. If you change this, - make sure you change struct link_map in include/link.h accordingly - such that it matches a prefix of struct elf_resolve. */ -#ifndef DL_LOADADDR_TYPE -# define DL_LOADADDR_TYPE ElfW(Addr) -#endif - -/* When DL_LOADADDR_TYPE is not a scalar value, or some different - computation is needed to relocate an address, define this. */ -#ifndef DL_RELOC_ADDR -# define DL_RELOC_ADDR(ADDR, LOADADDR) \ - ((void*)((intptr_t)(ADDR) + (intptr_t)(LOADADDR))) -#endif - -/* Define if any declarations/definitions of local variables are - needed in a function that calls DT_INIT_LOADADDR or - DL_INIT_LOADADDR_HDR. Declarations must be properly terminated - with a semicolon, and non-declaration statements are forbidden. */ -#ifndef DL_INIT_LOADADDR_EXTRA_DECLS -# define DL_INIT_LOADADDR_EXTRA_DECLS /* int i; */ -#endif - -/* Prepare a DL_LOADADDR_TYPE data structure for incremental - initialization with DL_INIT_LOADADDR_HDR, given pointers to a base - load address and to program headers. */ -#ifndef DL_INIT_LOADADDR -# define DL_INIT_LOADADDR(LOADADDR, BASEADDR, PHDR, PHDRCNT) \ - ((LOADADDR) = (BASEADDR)) -#endif - -/* Convert a DL_LOADADDR_TYPE to an identifying pointer. Used mostly - for debugging. */ -#ifndef DL_LOADADDR_BASE -# define DL_LOADADDR_BASE(LOADADDR) (LOADADDR) -#endif - -/* Initialize a LOADADDR representing the loader itself. It's only - called from DL_BOOT, so additional arguments passed to it may be - referenced. */ -#ifndef DL_INIT_LOADADDR_BOOT -# define DL_INIT_LOADADDR_BOOT(LOADADDR, BASEADDR) \ - ((LOADADDR) = (BASEADDR)) -#endif - -/* Initialize a LOADADDR representing the program. It's called from - DL_BOOT only. */ -#ifndef DL_INIT_LOADADDR_PROG -# define DL_INIT_LOADADDR_PROG(LOADADDR, BASEADDR) \ - ((LOADADDR) = (BASEADDR)) -#endif - -/* Test whether a given ADDR is more likely to be within the memory - region mapped to TPNT (a struct elf_resolve *) than to TFROM. - Everywhere that this is used, TFROM is initially NULL, and whenever - a potential match is found, it's updated. One might want to walk - the chain of elf_resolve to locate the best match and return false - whenever TFROM is non-NULL, or use an exact-matching algorithm - using additional information encoded in DL_LOADADDR_TYPE to test - for exact containment. */ -#ifndef DL_ADDR_IN_LOADADDR -# define DL_ADDR_IN_LOADADDR(ADDR, TPNT, TFROM) \ - ((void*)(TPNT)->loadaddr < (void*)(ADDR) \ - && (! (TFROM) || (TFROM)->loadaddr < (TPNT)->loadaddr)) -#endif - #endif /* _LD_DEFS_H */ diff --git a/ldso/include/dl-elf.h b/ldso/include/dl-elf.h index 9e364d680..de404aec1 100644 --- a/ldso/include/dl-elf.h +++ b/ldso/include/dl-elf.h @@ -94,12 +94,10 @@ extern void _dl_protect_relro (struct elf_resolve *l); #define DYNAMIC_SIZE (DT_NUM+OS_NUM+ARCH_NUM) -extern void _dl_parse_dynamic_info(ElfW(Dyn) *dpnt, unsigned long dynamic_info[], void *debug_addr, - DL_LOADADDR_TYPE load_off); +extern void _dl_parse_dynamic_info(ElfW(Dyn) *dpnt, unsigned long dynamic_info[], void *debug_addr, ElfW(Addr) load_off); static __always_inline -void __dl_parse_dynamic_info(ElfW(Dyn) *dpnt, unsigned long dynamic_info[], void *debug_addr, - DL_LOADADDR_TYPE load_off) +void __dl_parse_dynamic_info(ElfW(Dyn) *dpnt, unsigned long dynamic_info[], void *debug_addr, ElfW(Addr) load_off) { for (; dpnt->d_tag; dpnt++) { if (dpnt->d_tag < DT_NUM) { @@ -141,8 +139,7 @@ void __dl_parse_dynamic_info(ElfW(Dyn) *dpnt, unsigned long dynamic_info[], void #define ADJUST_DYN_INFO(tag, load_off) \ do { \ if (dynamic_info[tag]) \ - dynamic_info[tag] = (unsigned long)DL_RELOC_ADDR (dynamic_info[tag], \ - load_off); \ + dynamic_info[tag] += load_off; \ } while(0) ADJUST_DYN_INFO(DT_HASH, load_off); ADJUST_DYN_INFO(DT_PLTGOT, load_off); diff --git a/ldso/include/dl-hash.h b/ldso/include/dl-hash.h index 26fb334fe..b12b36f3b 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. */ + ElfW(Addr) 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; @@ -77,7 +77,7 @@ extern struct elf_resolve * _dl_loaded_modules; extern struct dyn_elf * _dl_handles; extern struct elf_resolve * _dl_add_elf_hash_table(const char * libname, - DL_LOADADDR_TYPE loadaddr, unsigned long * dynamic_info, + char * loadaddr, unsigned long * dynamic_info, unsigned long dynamic_addr, unsigned long dynamic_size); extern char * _dl_find_hash(const char * name, struct dyn_elf * rpnt1, diff --git a/ldso/include/ldso.h b/ldso/include/ldso.h index 573652e61..0a3f70691 100644 --- a/ldso/include/ldso.h +++ b/ldso/include/ldso.h @@ -88,7 +88,7 @@ extern void _dl_unsetenv(const char *symbol, char **envp); extern char *_dl_strdup(const char *string); extern void _dl_dprintf(int, const char *, ...); -extern void _dl_get_ready_to_run(struct elf_resolve *tpnt, DL_LOADADDR_TYPE load_addr, +extern void _dl_get_ready_to_run(struct elf_resolve *tpnt, unsigned long load_addr, ElfW(auxv_t) auxvt[AT_EGID + 1], char **envp, char **argv); #endif /* _LDSO_H_ */ diff --git a/ldso/ldso/dl-elf.c b/ldso/ldso/dl-elf.c index f98d76b88..d0ea4dac7 100644 --- a/ldso/ldso/dl-elf.c +++ b/ldso/ldso/dl-elf.c @@ -118,10 +118,10 @@ int _dl_unmap_cache(void) void _dl_protect_relro (struct elf_resolve *l) { - ElfW(Addr) base = (ElfW(Addr)) DL_RELOC_ADDR (l->relro_addr, - l->loadaddr); - ElfW(Addr) start = (base & ~(_dl_pagesize - 1)); - ElfW(Addr) end = ((base + l->relro_size) & ~(_dl_pagesize - 1)); + ElfW(Addr) start = ((l->loadaddr + l->relro_addr) + & ~(_dl_pagesize - 1)); + ElfW(Addr) end = ((l->loadaddr + l->relro_addr + 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) { @@ -262,8 +262,7 @@ struct elf_resolve *_dl_load_shared_library(int secure, struct dyn_elf **rpnt, #ifdef __LDSO_RUNPATH__ pnt = (tpnt ? (char *)tpnt->dynamic_info[DT_RUNPATH] : NULL); if (pnt) { - pnt += (intptr_t) DL_RELOC_ADDR (tpnt->dynamic_info[DT_STRTAB], - tpnt->loadaddr); + pnt += (unsigned long) tpnt->dynamic_info[DT_STRTAB]; _dl_if_debug_dprint("\tsearching RUNPATH='%s'\n", pnt); if ((tpnt1 = search_for_named_library(libname, secure, pnt, rpnt)) != NULL) return tpnt1; @@ -353,8 +352,6 @@ struct elf_resolve *_dl_load_elf_shared_library(int secure, ElfW(Addr) relro_addr = 0; size_t relro_size = 0; struct stat st; - DL_LOADADDR_TYPE lib_loadaddr; - DL_INIT_LOADADDR_EXTRA_DECLS libaddr = 0; infile = _dl_open(libname, O_RDONLY, 0); @@ -470,10 +467,7 @@ struct elf_resolve *_dl_load_elf_shared_library(int secure, } libaddr = (unsigned long) status; flags |= MAP_FIXED; - DL_INIT_LOADADDR (lib_loadaddr, libaddr, - (Elf32_Phdr *)& header[epnt->e_phoff], - epnt->e_phnum); - + /* Get the memory to store the library */ ppnt = (ElfW(Phdr) *)(intptr_t) & header[epnt->e_phoff]; @@ -553,8 +547,7 @@ struct elf_resolve *_dl_load_elf_shared_library(int secure, /* For a non-PIC library, the addresses are all absolute */ if (piclib) { - dynamic_addr = (unsigned long) DL_RELOC_ADDR (dynamic_addr, - lib_loadaddr); + dynamic_addr += (unsigned long) libaddr; } /* @@ -574,7 +567,7 @@ struct elf_resolve *_dl_load_elf_shared_library(int secure, dpnt = (ElfW(Dyn) *) dynamic_addr; _dl_memset(dynamic_info, 0, sizeof(dynamic_info)); - _dl_parse_dynamic_info(dpnt, dynamic_info, NULL, lib_loadaddr); + _dl_parse_dynamic_info(dpnt, dynamic_info, NULL, libaddr); /* If the TEXTREL is set, this means that we need to make the pages writable before we perform relocations. Do this now. They get set back again later. */ @@ -595,14 +588,13 @@ struct elf_resolve *_dl_load_elf_shared_library(int secure, #endif } - tpnt = _dl_add_elf_hash_table(libname, lib_loadaddr, dynamic_info, + tpnt = _dl_add_elf_hash_table(libname, (char *) libaddr, dynamic_info, dynamic_addr, 0); tpnt->relro_addr = relro_addr; tpnt->relro_size = relro_size; tpnt->st_dev = st.st_dev; tpnt->st_ino = st.st_ino; - tpnt->ppnt = (ElfW(Phdr) *) DL_RELOC_ADDR (epnt->e_phoff, - tpnt->loadaddr); + tpnt->ppnt = (ElfW(Phdr) *)(intptr_t) (tpnt->loadaddr + epnt->e_phoff); tpnt->n_phent = epnt->e_phnum; /* @@ -633,11 +625,9 @@ 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, libaddr); _dl_if_debug_dprint("\t\t entry: %x phdr: %x phnum: %x\n\n", - DL_RELOC_ADDR (epnt->e_entry, lib_loadaddr), - tpnt->ppnt, tpnt->n_phent); + epnt->e_entry + libaddr, tpnt->ppnt, tpnt->n_phent); _dl_munmap(header, _dl_pagesize); @@ -811,7 +801,7 @@ char *_dl_strdup(const char *string) return retval; } -void _dl_parse_dynamic_info(ElfW(Dyn) *dpnt, unsigned long dynamic_info[], void *debug_addr, DL_LOADADDR_TYPE load_off) +void _dl_parse_dynamic_info(ElfW(Dyn) *dpnt, unsigned long dynamic_info[], void *debug_addr, ElfW(Addr) load_off) { __dl_parse_dynamic_info(dpnt, dynamic_info, debug_addr, load_off); } @@ -828,7 +818,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 = (ElfW(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-hash.c b/ldso/ldso/dl-hash.c index 85b2b403f..ed55031ed 100644 --- a/ldso/ldso/dl-hash.c +++ b/ldso/ldso/dl-hash.c @@ -83,7 +83,7 @@ static inline Elf_Symndx _dl_elf_hash(const char *name) * externals properly. */ struct elf_resolve *_dl_add_elf_hash_table(const char *libname, - DL_LOADADDR_TYPE loadaddr, unsigned long *dynamic_info, unsigned long dynamic_addr, + char *loadaddr, unsigned long *dynamic_info, unsigned long dynamic_addr, attribute_unused unsigned long dynamic_size) { Elf_Symndx *hash_addr; @@ -117,7 +117,7 @@ struct elf_resolve *_dl_add_elf_hash_table(const char *libname, hash_addr += tpnt->nbucket; tpnt->chains = hash_addr; } - tpnt->loadaddr = loadaddr; + tpnt->loadaddr = (ElfW(Addr))loadaddr; for (i = 0; i < DYNAMIC_SIZE; i++) tpnt->dynamic_info[i] = dynamic_info[i]; return tpnt; @@ -163,10 +163,8 @@ char *_dl_find_hash(const char *name, struct dyn_elf *rpnt, struct elf_resolve * /* Avoid calling .urem here. */ do_rem(hn, elf_hash_number, tpnt->nbucket); - symtab = (ElfW(Sym) *) DL_RELOC_ADDR (tpnt->dynamic_info[DT_SYMTAB], - tpnt->loadaddr); - strtab = (char *) DL_RELOC_ADDR (tpnt->dynamic_info[DT_STRTAB], - tpnt->loadaddr); + symtab = (ElfW(Sym) *) (intptr_t) (tpnt->dynamic_info[DT_SYMTAB]); + strtab = (char *) (tpnt->dynamic_info[DT_STRTAB]); for (si = tpnt->elf_buckets[hn]; si != STN_UNDEF; si = tpnt->chains[si]) { sym = &symtab[si]; @@ -186,13 +184,11 @@ char *_dl_find_hash(const char *name, struct dyn_elf *rpnt, struct elf_resolve * /* Perhaps we should support old style weak symbol handling * per what glibc does when you export LD_DYNAMIC_WEAK */ if (!weak_result) - weak_result = (char *) DL_RELOC_ADDR (sym->st_value, - tpnt->loadaddr); + weak_result = (char *)tpnt->loadaddr + sym->st_value; break; #endif case STB_GLOBAL: - return (char*) DL_RELOC_ADDR (sym->st_value, - tpnt->loadaddr); + return (char*)tpnt->loadaddr + sym->st_value; default: /* Local symbols not handled here */ break; } diff --git a/ldso/ldso/dl-startup.c b/ldso/ldso/dl-startup.c index 908ba7cb3..451edbf1b 100644 --- a/ldso/ldso/dl-startup.c +++ b/ldso/ldso/dl-startup.c @@ -114,7 +114,7 @@ static void * __attribute_used__ _dl_start(unsigned long args) { unsigned int argc; char **argv, **envp; - DL_LOADADDR_TYPE load_addr; + ElfW(Addr) load_addr; ElfW(Addr) got; unsigned long *aux_dat; ElfW(Ehdr) *header; @@ -168,7 +168,7 @@ static void * __attribute_used__ _dl_start(unsigned long args) * (esp since SEND_STDERR() needs this on some platforms... */ if (!auxvt[AT_BASE].a_un.a_val) auxvt[AT_BASE].a_un.a_val = elf_machine_load_address(); - DL_INIT_LOADADDR_BOOT(load_addr, auxvt[AT_BASE].a_un.a_val); + load_addr = auxvt[AT_BASE].a_un.a_val; header = (ElfW(Ehdr) *) auxvt[AT_BASE].a_un.a_val; /* Check the ELF header to make sure everything looks ok. */ @@ -186,14 +186,14 @@ static void * __attribute_used__ _dl_start(unsigned long args) _dl_exit(0); } SEND_STDERR_DEBUG("ELF header="); - SEND_ADDRESS_STDERR_DEBUG(DL_LOADADDR_BASE (load_addr), 1); + SEND_ADDRESS_STDERR_DEBUG(load_addr, 1); /* Locate the global offset table. Since this code must be PIC * we can take advantage of the magic offset register, if we * happen to know what that is for this architecture. If not, * we can always read stuff out of the ELF file to find it... */ got = elf_machine_dynamic(); - dpnt = (ElfW(Dyn) *) DL_RELOC_ADDR (got, load_addr); + dpnt = (ElfW(Dyn) *) (got + load_addr); SEND_STDERR_DEBUG("First Dynamic section entry="); SEND_ADDRESS_STDERR_DEBUG(dpnt, 1); _dl_memset(tpnt, 0, sizeof(struct elf_resolve)); @@ -259,10 +259,9 @@ static void * __attribute_used__ _dl_start(unsigned long args) rel_addr += relative_count * sizeof(ELF_RELOC); } - rpnt = (ELF_RELOC *) DL_RELOC_ADDR (rel_addr, load_addr); + rpnt = (ELF_RELOC *) (rel_addr + load_addr); for (i = 0; i < rel_size; i += sizeof(ELF_RELOC), rpnt++) { - reloc_addr = (unsigned long *) DL_RELOC_ADDR ((unsigned long) rpnt->r_offset, - load_addr); + reloc_addr = (unsigned long *) (load_addr + (unsigned long) rpnt->r_offset); symtab_index = ELF_R_SYM(rpnt->r_info); symbol_addr = 0; sym = NULL; @@ -273,7 +272,7 @@ static void * __attribute_used__ _dl_start(unsigned long args) symtab = (ElfW(Sym) *) tpnt->dynamic_info[DT_SYMTAB]; strtab = (char *) tpnt->dynamic_info[DT_STRTAB]; sym = &symtab[symtab_index]; - symbol_addr = (unsigned long) DL_RELOC_ADDR (sym->st_value, load_addr); + symbol_addr = load_addr + sym->st_value; SEND_STDERR_DEBUG("relocating symbol: "); SEND_STDERR_DEBUG(strtab + sym->st_name); diff --git a/ldso/ldso/ldso.c b/ldso/ldso/ldso.c index 2afd97797..2234623e3 100644 --- a/ldso/ldso/ldso.c +++ b/ldso/ldso/ldso.c @@ -102,18 +102,17 @@ uintptr_t __guard attribute_relro; #endif static void _dl_run_array_forward(unsigned long array, unsigned long size, - DL_LOADADDR_TYPE loadaddr) + ElfW(Addr) loadaddr) { if (array != 0) { unsigned int j; unsigned int jm; ElfW(Addr) *addrs; jm = size / sizeof (ElfW(Addr)); - addrs = (ElfW(Addr) *) DL_RELOC_ADDR (array, loadaddr); + addrs = (ElfW(Addr) *) (array + loadaddr); for (j = 0; j < jm; ++j) { void (*dl_elf_func) (void); - dl_elf_func = (void (*)(void)) DL_RELOC_ADDR (addrs[j], - loadaddr); + dl_elf_func = (void (*)(void)) (intptr_t) addrs[j]; (*dl_elf_func) (); } } @@ -137,13 +136,11 @@ void _dl_run_fini_array(struct elf_resolve *tpnt); void _dl_run_fini_array(struct elf_resolve *tpnt) { if (tpnt->dynamic_info[DT_FINI_ARRAY]) { - ElfW(Addr) *array = (ElfW(Addr) *) DL_RELOC_ADDR (tpnt->dynamic_info[DT_FINI_ARRAY], - tpnt->loadaddr); + ElfW(Addr) *array = (ElfW(Addr) *) (tpnt->loadaddr + tpnt->dynamic_info[DT_FINI_ARRAY]); unsigned int i = (tpnt->dynamic_info[DT_FINI_ARRAYSZ] / sizeof(ElfW(Addr))); while (i-- > 0) { void (*dl_elf_func) (void); - dl_elf_func = (void (*)(void)) DL_RELOC_ADDR (array[i], - tpnt->loadaddr); + dl_elf_func = (void (*)(void)) (intptr_t) array[i]; (*dl_elf_func) (); } } @@ -169,15 +166,14 @@ static void __attribute__ ((destructor)) __attribute_used__ _dl_fini(void) if (tpnt->dynamic_info[DT_FINI]) { void (*dl_elf_func) (void); - dl_elf_func = (void (*)(void)) DL_RELOC_ADDR (tpnt->dynamic_info[DT_FINI], - tpnt->loadaddr); + dl_elf_func = (void (*)(void)) (intptr_t) (tpnt->loadaddr + tpnt->dynamic_info[DT_FINI]); _dl_if_debug_dprint("\ncalling FINI: %s\n\n", tpnt->libname); (*dl_elf_func) (); } } } -void _dl_get_ready_to_run(struct elf_resolve *tpnt, DL_LOADADDR_TYPE load_addr, +void _dl_get_ready_to_run(struct elf_resolve *tpnt, unsigned long load_addr, ElfW(auxv_t) auxvt[AT_EGID + 1], char **envp, char **argv) { @@ -299,13 +295,13 @@ void _dl_get_ready_to_run(struct elf_resolve *tpnt, DL_LOADADDR_TYPE load_addr, for (idx = 0; idx < auxvt[AT_PHNUM].a_un.a_val; idx++, phdr++) if (phdr->p_type == PT_PHDR) { - DL_INIT_LOADADDR_PROG (app_tpnt->loadaddr, (ElfW(Addr)) (auxvt[AT_PHDR].a_un.a_val - ppnt->p_vaddr)); + app_tpnt->loadaddr = (ElfW(Addr)) (auxvt[AT_PHDR].a_un.a_val - phdr->p_vaddr); break; } - if (DL_LOADADDR_BASE (app_tpnt->loadaddr)) + if (app_tpnt->loadaddr) _dl_debug_early("Position Independent Executable: " - "app_tpnt->loadaddr=%x\n", DL_LOADADDR_BASE (app_tpnt->loadaddr)); + "app_tpnt->loadaddr=%x\n", app_tpnt->loadaddr); } /* @@ -322,7 +318,7 @@ void _dl_get_ready_to_run(struct elf_resolve *tpnt, DL_LOADADDR_TYPE load_addr, relro_size = ppnt->p_memsz; } if (ppnt->p_type == PT_DYNAMIC) { - dpnt = (ElfW(Dyn) *) DL_RELOC_ADDR (ppnt->p_vaddr, app_tpnt->loadaddr); + dpnt = (ElfW(Dyn) *) (ppnt->p_vaddr + app_tpnt->loadaddr); _dl_parse_dynamic_info(dpnt, app_tpnt->dynamic_info, debug_addr, app_tpnt->loadaddr); #ifndef __FORCE_SHAREABLE_TEXT_SEGMENTS__ /* Ugly, ugly. We need to call mprotect to change the @@ -335,11 +331,11 @@ void _dl_get_ready_to_run(struct elf_resolve *tpnt, DL_LOADADDR_TYPE load_addr, if (app_tpnt->dynamic_info[DT_TEXTREL]) { ppnt = (ElfW(Phdr) *) auxvt[AT_PHDR].a_un.a_val; for (i = 0; i < auxvt[AT_PHNUM].a_un.a_val; i++, ppnt++) { - if (ppnt->p_type == PT_LOAD && !(ppnt->p_flags & PF_W)) { - void *base = DL_RELOC_ADDR (ppnt->p_vaddr & PAGE_ALIGN, app_tpnt->loadaddr); - _dl_mprotect(base, (ppnt->p_vaddr & ADDR_ALIGN) + (unsigned long) ppnt->p_filesz, + if (ppnt->p_type == PT_LOAD && !(ppnt->p_flags & PF_W)) + _dl_mprotect((void *) ((ppnt->p_vaddr + app_tpnt->loadaddr) & PAGE_ALIGN), + ((ppnt->p_vaddr + app_tpnt->loadaddr) & ADDR_ALIGN) + + (unsigned long) ppnt->p_filesz, PROT_READ | PROT_WRITE | PROT_EXEC); - } } } #endif @@ -350,10 +346,8 @@ void _dl_get_ready_to_run(struct elf_resolve *tpnt, DL_LOADADDR_TYPE load_addr, continue; #endif /* OK, we have what we need - slip this one into the list. */ - app_tpnt = _dl_add_elf_hash_table(_dl_progname, app_tpnt->loadaddr, - app_tpnt->dynamic_info, - (unsigned long) DL_RELOC_ADDR (ppnt->p_vaddr, app_tpnt->loadaddr), - ppnt->p_filesz); + app_tpnt = _dl_add_elf_hash_table(_dl_progname, (char *)app_tpnt->loadaddr, + app_tpnt->dynamic_info, ppnt->p_vaddr + app_tpnt->loadaddr, ppnt->p_filesz); _dl_loaded_modules->libtype = elf_executable; _dl_loaded_modules->ppnt = (ElfW(Phdr) *) auxvt[AT_PHDR].a_un.a_val; _dl_loaded_modules->n_phent = auxvt[AT_PHNUM].a_un.a_val; @@ -374,7 +368,7 @@ void _dl_get_ready_to_run(struct elf_resolve *tpnt, DL_LOADADDR_TYPE load_addr, if (ppnt->p_type == PT_INTERP) { char *ptmp; - tpnt->libname = (char *) DL_RELOC_ADDR (ppnt->p_vaddr, app_tpnt->loadaddr); + tpnt->libname = (char *) ppnt->p_vaddr + app_tpnt->loadaddr; /* Store the path where the shared lib loader was found * for later use @@ -384,8 +378,7 @@ void _dl_get_ready_to_run(struct elf_resolve *tpnt, DL_LOADADDR_TYPE load_addr, if (ptmp != _dl_ldsopath) *ptmp = '\0'; - _dl_debug_early("Lib Loader: (%x) %s\n", (unsigned) DL_LOADADDR_BASE (tpnt->loadaddr), - tpnt->libname); + _dl_debug_early("Lib Loader: (%x) %s\n", tpnt->loadaddr, tpnt->libname); } } app_tpnt->relro_addr = relro_addr; @@ -457,7 +450,7 @@ void _dl_get_ready_to_run(struct elf_resolve *tpnt, DL_LOADADDR_TYPE load_addr, */ debug_addr->r_map = (struct link_map *) _dl_loaded_modules; debug_addr->r_version = 1; - debug_addr->r_ldbase = (ElfW(Addr)) DL_LOADADDR_BASE (load_addr); + debug_addr->r_ldbase = load_addr; debug_addr->r_brk = (unsigned long) &_dl_debug_state; _dl_debug_addr = debug_addr; @@ -504,7 +497,7 @@ void _dl_get_ready_to_run(struct elf_resolve *tpnt, DL_LOADADDR_TYPE load_addr, } else { tpnt1->rtld_flags = unlazy | RTLD_GLOBAL; - _dl_debug_early("Loading: (%x) %s\n", (unsigned) DL_LOADADDR_BASE (tpnt1->loadaddr), tpnt1->libname); + _dl_debug_early("Loading: (%x) %s\n", tpnt1->loadaddr, tpnt1->libname); #ifdef __LDSO_LDD_SUPPORT__ if (trace_loaded_objects && @@ -516,7 +509,7 @@ void _dl_get_ready_to_run(struct elf_resolve *tpnt, DL_LOADADDR_TYPE load_addr, */ if (_dl_strcmp(_dl_progname, str) != 0) _dl_dprintf(1, "\t%s => %s (%x)\n", str, tpnt1->libname, - (unsigned) DL_LOADADDR_BASE (tpnt1->loadaddr)); + tpnt1->loadaddr); } #endif } @@ -595,14 +588,14 @@ void _dl_get_ready_to_run(struct elf_resolve *tpnt, DL_LOADADDR_TYPE load_addr, } else { tpnt1->rtld_flags = unlazy | RTLD_GLOBAL; - _dl_debug_early("Loading: (%x) %s\n", (unsigned) DL_LOADADDR_BASE (tpnt1->loadaddr), tpnt1->libname); + _dl_debug_early("Loading: (%x) %s\n", tpnt1->loadaddr, tpnt1->libname); #ifdef __LDSO_LDD_SUPPORT__ if (trace_loaded_objects && tpnt1->usage_count == 1) { _dl_dprintf(1, "\t%s => %s (%x)\n", cp2, tpnt1->libname, - (unsigned) DL_LOADADDR_BASE (tpnt1->loadaddr)); + (unsigned)tpnt1->loadaddr); } #endif } @@ -654,14 +647,14 @@ void _dl_get_ready_to_run(struct elf_resolve *tpnt, DL_LOADADDR_TYPE load_addr, tpnt1->rtld_flags = unlazy | RTLD_GLOBAL; - _dl_debug_early("Loading: (%x) %s\n", (unsigned) DL_LOADADDR_BASE (tpnt1->loadaddr), tpnt1->libname); + _dl_debug_early("Loading: (%x) %s\n", tpnt1->loadaddr, tpnt1->libname); #ifdef __LDSO_LDD_SUPPORT__ if (trace_loaded_objects && tpnt1->usage_count == 1) { _dl_dprintf(1, "\t%s => %s (%x)\n", lpntstr, tpnt1->libname, - (unsigned) DL_LOADADDR_BASE (tpnt1->loadaddr)); + (unsigned)tpnt1->loadaddr); } #endif } @@ -722,10 +715,10 @@ void _dl_get_ready_to_run(struct elf_resolve *tpnt, DL_LOADADDR_TYPE load_addr, */ if (tpnt) { ElfW(Ehdr) *epnt = (ElfW(Ehdr) *) auxvt[AT_BASE].a_un.a_val; - ElfW(Phdr) *myppnt = (ElfW(Phdr) *) DL_RELOC_ADDR (epnt->e_phoff, load_addr); + ElfW(Phdr) *myppnt = (ElfW(Phdr) *) (load_addr + epnt->e_phoff); int j; - tpnt = _dl_add_elf_hash_table(tpnt->libname, load_addr, + tpnt = _dl_add_elf_hash_table(tpnt->libname, (char *)load_addr, tpnt->dynamic_info, (unsigned long)tpnt->dynamic_addr, 0); @@ -772,7 +765,7 @@ void _dl_get_ready_to_run(struct elf_resolve *tpnt, DL_LOADADDR_TYPE load_addr, if (trace_loaded_objects) { _dl_dprintf(1, "\t%s => %s (%x)\n", rpnt->dyn->libname + _dl_strlen(_dl_ldsopath) + 1, - rpnt->dyn->libname, (unsigned) DL_LOADADDR_BASE (rpnt->dyn->loadaddr)); + rpnt->dyn->libname, rpnt->dyn->loadaddr); _dl_exit(0); } #endif @@ -824,10 +817,8 @@ void _dl_get_ready_to_run(struct elf_resolve *tpnt, DL_LOADADDR_TYPE load_addr, for (tpnt = _dl_loaded_modules; tpnt; tpnt = tpnt->next) { for (myppnt = tpnt->ppnt, j = 0; j < tpnt->n_phent; j++, myppnt++) { if (myppnt->p_type == PT_LOAD && !(myppnt->p_flags & PF_W) && tpnt->dynamic_info[DT_TEXTREL]) { - void *base = DL_RELOC_ADDR (myppnt->p_vaddr & PAGE_ALIGN, tpnt->loadaddr); - _dl_mprotect(base, - (myppnt->p_vaddr & ADDR_ALIGN) + (unsigned long) myppnt->p_filesz, - LXFLAGS(myppnt->p_flags)); + _dl_mprotect((void *) (tpnt->loadaddr + (myppnt->p_vaddr & PAGE_ALIGN)), + (myppnt->p_vaddr & ADDR_ALIGN) + (unsigned long) myppnt->p_filesz, LXFLAGS(myppnt->p_flags)); } } } @@ -855,7 +846,7 @@ void _dl_get_ready_to_run(struct elf_resolve *tpnt, DL_LOADADDR_TYPE load_addr, if (tpnt->dynamic_info[DT_INIT]) { void (*dl_elf_func) (void); - dl_elf_func = (void (*)(void)) DL_RELOC_ADDR (tpnt->dynamic_info[DT_INIT], tpnt->loadaddr); + dl_elf_func = (void (*)(void)) (intptr_t) (tpnt->loadaddr + tpnt->dynamic_info[DT_INIT]); _dl_if_debug_dprint("calling INIT: %s\n\n", tpnt->libname); diff --git a/ldso/libdl/libdl.c b/ldso/libdl/libdl.c index b533a2da1..322230860 100644 --- a/ldso/libdl/libdl.c +++ b/ldso/libdl/libdl.c @@ -175,7 +175,8 @@ void *dlopen(const char *libname, int flag) tfrom = NULL; for (dpnt = _dl_symbol_tables; dpnt; dpnt = dpnt->next) { tpnt = dpnt->dyn; - if (DL_ADDR_IN_LOADADDR (from, tpnt, tfrom)) + if (tpnt->loadaddr < from + && (tfrom == NULL || tfrom->loadaddr < tpnt->loadaddr)) tfrom = tpnt; } } @@ -377,7 +378,7 @@ 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->dynamic_info[DT_INIT], tpnt->loadaddr); + dl_elf_func = (void (*)(void)) (tpnt->loadaddr + tpnt->dynamic_info[DT_INIT]); if (dl_elf_func && *dl_elf_func != NULL) { _dl_if_debug_print("running ctors for library %s at '%p'\n", tpnt->libname, dl_elf_func); @@ -435,7 +436,8 @@ void *dlsym(void *vhandle, const char *name) tfrom = NULL; for (rpnt = _dl_symbol_tables; rpnt; rpnt = rpnt->next) { tpnt = rpnt->dyn; - if (DL_ADDR_IN_LOADADDR (from, tpnt, tfrom)) { + if (tpnt->loadaddr < from + && (tfrom == NULL || tfrom->loadaddr < tpnt->loadaddr)) { tfrom = tpnt; handle = rpnt->next; } @@ -510,7 +512,7 @@ static int do_dlclose(void *vhandle, int need_fini) #endif if (tpnt->dynamic_info[DT_FINI]) { - dl_elf_fini = (int (*)(void)) DL_RELOC_ADDR (tpnt->dynamic_info[DT_FINI], tpnt->loadaddr); + dl_elf_fini = (int (*)(void)) (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) (); @@ -620,7 +622,7 @@ int dlinfo(void) /* First start with a complete list of all of the loaded files. */ for (tpnt = _dl_loaded_modules; tpnt; tpnt = tpnt->next) { fprintf(stderr, "\t%p %p %p %s %d %s\n", - DL_LOADADDR_BASE (tpnt->loadaddr), tpnt, tpnt->symbol_scope, + tpnt->loadaddr, tpnt, tpnt->symbol_scope, type[tpnt->libtype], tpnt->usage_count, tpnt->libname); } @@ -660,10 +662,12 @@ int dladdr(const void *__address, Dl_info * __info) tpnt = rpnt; #if 0 fprintf(stderr, "Module \"%s\" at %p\n", - tpnt->libname, DL_LOADADDR_BASE (tpnt->loadaddr)); + tpnt->libname, tpnt->loadaddr); #endif - if (DL_ADDR_IN_LOADADDR ((ElfW(Addr)) __address, tpnt, pelf)) + if (tpnt->loadaddr < (ElfW(Addr)) __address + && (pelf == NULL || pelf->loadaddr < tpnt->loadaddr)) { pelf = tpnt; + } } if (!pelf) { @@ -689,7 +693,7 @@ int dladdr(const void *__address, Dl_info * __info) for (si = pelf->elf_buckets[hn]; si; si = pelf->chains[si]) { ElfW(Addr) symbol_addr; - symbol_addr = (ElfW(Addr)) DL_RELOC_ADDR (symtab[si].st_value, pelf->loadaddr); + symbol_addr = pelf->loadaddr + symtab[si].st_value; if (symbol_addr <= (ElfW(Addr))__address && (!sf || sa < symbol_addr)) { sa = symbol_addr; sn = si; @@ -704,7 +708,7 @@ int dladdr(const void *__address, Dl_info * __info) if (sf) { __info->dli_fname = pelf->libname; - __info->dli_fbase = DL_LOADADDR_BASE (pelf->loadaddr); + __info->dli_fbase = (void *)pelf->loadaddr; __info->dli_sname = strtab + symtab[sn].st_name; __info->dli_saddr = (void *)sa; } |