diff options
Diffstat (limited to 'ldso')
-rw-r--r-- | ldso/include/dl-elf.h | 8 | ||||
-rw-r--r-- | ldso/include/dl-hash.h | 11 | ||||
-rw-r--r-- | ldso/include/ldso.h | 2 | ||||
-rw-r--r-- | ldso/include/unsecvars.h | 4 | ||||
-rw-r--r-- | ldso/ldso/dl-elf.c | 2 | ||||
-rw-r--r-- | ldso/ldso/dl-hash.c | 142 | ||||
-rw-r--r-- | ldso/ldso/ldso.c | 2 | ||||
-rw-r--r-- | ldso/libdl/libdl.c | 18 |
8 files changed, 94 insertions, 95 deletions
diff --git a/ldso/include/dl-elf.h b/ldso/include/dl-elf.h index 320a0f920..08b1c8b50 100644 --- a/ldso/include/dl-elf.h +++ b/ldso/include/dl-elf.h @@ -141,10 +141,10 @@ void __dl_parse_dynamic_info(ElfW(Dyn) *dpnt, unsigned long dynamic_info[], if (dpnt->d_tag == DT_FLAGS_1 && (dpnt->d_un.d_val & DF_1_NOW)) dynamic_info[DT_BIND_NOW] = 1; -#ifdef __LDSO_GNU_HASH_SUPPORT__ +#ifdef __LDSO_GNU_HASH_SUPPORT__ if (dpnt->d_tag == DT_GNU_HASH) dynamic_info[DT_GNU_HASH_IDX] = dpnt->d_un.d_ptr; -#endif +#endif } #ifdef ARCH_DYNAMIC_INFO else { @@ -156,7 +156,7 @@ void __dl_parse_dynamic_info(ElfW(Dyn) *dpnt, unsigned long dynamic_info[], do { \ if (dynamic_info[tag]) \ dynamic_info[tag] = (unsigned long) DL_RELOC_ADDR(load_off, dynamic_info[tag]); \ - } while(0) + } while (0) ADJUST_DYN_INFO(DT_HASH, load_off); ADJUST_DYN_INFO(DT_PLTGOT, load_off); ADJUST_DYN_INFO(DT_STRTAB, load_off); @@ -165,7 +165,7 @@ void __dl_parse_dynamic_info(ElfW(Dyn) *dpnt, unsigned long dynamic_info[], ADJUST_DYN_INFO(DT_JMPREL, load_off); #ifdef __LDSO_GNU_HASH_SUPPORT__ ADJUST_DYN_INFO(DT_GNU_HASH_IDX, load_off); -#endif +#endif #undef ADJUST_DYN_INFO } diff --git a/ldso/include/dl-hash.h b/ldso/include/dl-hash.h index d5c63fa28..5bb1f47e1 100644 --- a/ldso/include/dl-hash.h +++ b/ldso/include/dl-hash.h @@ -40,7 +40,7 @@ struct elf_resolve { unsigned short int init_flag; unsigned long rtld_flags; /* RTLD_GLOBAL, RTLD_NOW etc. */ Elf_Symndx nbucket; - + #ifdef __LDSO_GNU_HASH_SUPPORT__ /* Data needed to support GNU hash style */ Elf32_Word l_gnu_bitmask_idxbits; @@ -55,7 +55,7 @@ struct elf_resolve { #else Elf_Symndx *elf_buckets; #endif - + struct init_fini_list *init_fini; struct init_fini_list *rtld_local; /* keep tack of RTLD_LOCAL libs in same group */ /* @@ -69,10 +69,9 @@ struct elf_resolve { const Elf32_Word *l_gnu_buckets; const Elf_Symndx *chains; }; -#else +#else Elf_Symndx *chains; -#endif - +#endif unsigned long dynamic_info[DYNAMIC_SIZE]; unsigned long n_phent; @@ -136,7 +135,7 @@ extern char * _dl_not_lazy; static inline int _dl_symbol(char * name) { - if(name[0] != '_' || name[1] != 'd' || name[2] != 'l' || name[3] != '_') + if (name[0] != '_' || name[1] != 'd' || name[2] != 'l' || name[3] != '_') return 0; return 1; } diff --git a/ldso/include/ldso.h b/ldso/include/ldso.h index 029922747..a9d3609d0 100644 --- a/ldso/include/ldso.h +++ b/ldso/include/ldso.h @@ -65,7 +65,7 @@ extern int _dl_debug_file; # define __dl_debug_dprint(fmt, args...) \ _dl_dprintf(_dl_debug_file, "%s:%i: " fmt, __FUNCTION__, __LINE__, ## args); # define _dl_if_debug_dprint(fmt, args...) \ - do { if (_dl_debug) __dl_debug_dprint(fmt, ## args); } while (0) + do { if (_dl_debug) __dl_debug_dprint(fmt, ## args); } while (0) #else # define __dl_debug_dprint(fmt, args...) # define _dl_if_debug_dprint(fmt, args...) diff --git a/ldso/include/unsecvars.h b/ldso/include/unsecvars.h index 0ce3ebfea..f1ef381ee 100644 --- a/ldso/include/unsecvars.h +++ b/ldso/include/unsecvars.h @@ -5,7 +5,7 @@ * GNU Lesser General Public License version 2.1 or later. */ -/* +/* * Environment variable to be removed for SUID programs. The names are all * stuffed in a single string which means they have to be terminated with a * '\0' explicitly. @@ -19,7 +19,7 @@ "LD_TRACE_LOADED_OBJECTS\0" \ "TMPDIR\0" -/* +/* * LD_TRACE_LOADED_OBJECTS is not in glibc-2.3.5's unsecvars.h * though used by ldd * diff --git a/ldso/ldso/dl-elf.c b/ldso/ldso/dl-elf.c index 071a6e4ef..b2aabc2fa 100644 --- a/ldso/ldso/dl-elf.c +++ b/ldso/ldso/dl-elf.c @@ -732,7 +732,7 @@ struct elf_resolve *_dl_load_elf_shared_library(int secure, /* When statically linked, the first time we dlopen a DSO * the *rpnt is NULL, so we need to allocate memory for it, * and initialize the _dl_symbol_table. - */ + */ else { *rpnt = _dl_symbol_tables = (struct dyn_elf *) _dl_malloc(sizeof(struct dyn_elf)); _dl_memset(*rpnt, 0, sizeof(struct dyn_elf)); diff --git a/ldso/ldso/dl-hash.c b/ldso/ldso/dl-hash.c index f9c316281..8d2ae3e38 100644 --- a/ldso/ldso/dl-hash.c +++ b/ldso/ldso/dl-hash.c @@ -114,33 +114,32 @@ struct elf_resolve *_dl_add_elf_hash_table(const char *libname, _dl_memset(tpnt->next, 0, sizeof(struct elf_resolve)); tpnt->next->prev = tpnt; tpnt = tpnt->next; - }; + } tpnt->next = NULL; tpnt->init_flag = 0; tpnt->libname = _dl_strdup(libname); tpnt->dynamic_addr = (ElfW(Dyn) *)dynamic_addr; tpnt->libtype = loaded_file; - + #ifdef __LDSO_GNU_HASH_SUPPORT__ if (dynamic_info[DT_GNU_HASH_IDX] != 0) { - - Elf32_Word *hash32 = (Elf_Symndx*)dynamic_info[DT_GNU_HASH_IDX]; - - tpnt->nbucket = *hash32++; - Elf32_Word symbias = *hash32++; - Elf32_Word bitmask_nwords = *hash32++; - /* Must be a power of two. */ - _dl_assert ((bitmask_nwords & (bitmask_nwords - 1)) == 0); - tpnt->l_gnu_bitmask_idxbits = bitmask_nwords - 1; - tpnt->l_gnu_shift = *hash32++; - - tpnt->l_gnu_bitmask = (ElfW(Addr) *) hash32; - hash32 += __ELF_NATIVE_CLASS / 32 * bitmask_nwords; - - tpnt->l_gnu_buckets = hash32; - hash32 += tpnt->nbucket; - tpnt->l_gnu_chain_zero = hash32 - symbias; + Elf32_Word *hash32 = (Elf_Symndx*)dynamic_info[DT_GNU_HASH_IDX]; + + tpnt->nbucket = *hash32++; + Elf32_Word symbias = *hash32++; + Elf32_Word bitmask_nwords = *hash32++; + /* Must be a power of two. */ + _dl_assert ((bitmask_nwords & (bitmask_nwords - 1)) == 0); + tpnt->l_gnu_bitmask_idxbits = bitmask_nwords - 1; + tpnt->l_gnu_shift = *hash32++; + + tpnt->l_gnu_bitmask = (ElfW(Addr) *) hash32; + hash32 += __ELF_NATIVE_CLASS / 32 * bitmask_nwords; + + tpnt->l_gnu_buckets = hash32; + hash32 += tpnt->nbucket; + tpnt->l_gnu_chain_zero = hash32 - symbias; } else /* Fall using old SysV hash table if GNU hash is not present */ #endif @@ -162,45 +161,45 @@ struct elf_resolve *_dl_add_elf_hash_table(const char *libname, /* Routine to check whether the symbol matches. */ static __attribute_noinline__ const ElfW(Sym) * -check_match (const ElfW(Sym) *sym, char *strtab, const char* undef_name, int type_class) { - - if (type_class & (sym->st_shndx == SHN_UNDEF)) - /* undefined symbol itself */ - return NULL; - - if (sym->st_value == 0) - /* No value */ - return NULL; - - if (ELF_ST_TYPE(sym->st_info) > STT_FUNC - && ELF_ST_TYPE(sym->st_info) != STT_COMMON) - /* Ignore all but STT_NOTYPE, STT_OBJECT, STT_FUNC - * and STT_COMMON entries since these are no - * code/data definitions - */ - return NULL; - - if (_dl_strcmp(strtab + sym->st_name, undef_name) != 0) - return NULL; - - /* This is the matching symbol */ - return sym; +check_match (const ElfW(Sym) *sym, char *strtab, const char* undef_name, int type_class) +{ + if (type_class & (sym->st_shndx == SHN_UNDEF)) + /* undefined symbol itself */ + return NULL; + + if (sym->st_value == 0) + /* No value */ + return NULL; + + if (ELF_ST_TYPE(sym->st_info) > STT_FUNC + && ELF_ST_TYPE(sym->st_info) != STT_COMMON) + /* Ignore all but STT_NOTYPE, STT_OBJECT, STT_FUNC + * and STT_COMMON entries since these are no + * code/data definitions + */ + return NULL; + + if (_dl_strcmp(strtab + sym->st_name, undef_name) != 0) + return NULL; + + /* This is the matching symbol */ + return sym; } #ifdef __LDSO_GNU_HASH_SUPPORT__ -static __always_inline const ElfW(Sym) * -_dl_lookup_gnu_hash(struct elf_resolve *tpnt, ElfW(Sym) *symtab, unsigned long hash, - const char* undef_name, int type_class) { - +static __always_inline const ElfW(Sym) * +_dl_lookup_gnu_hash(struct elf_resolve *tpnt, ElfW(Sym) *symtab, unsigned long hash, + const char* undef_name, int type_class) +{ Elf_Symndx symidx; const ElfW(Sym) *sym; char *strtab; - + const ElfW(Addr) *bitmask = tpnt->l_gnu_bitmask; - ElfW(Addr) bitmask_word = bitmask[(hash / __ELF_NATIVE_CLASS) & tpnt->l_gnu_bitmask_idxbits]; + ElfW(Addr) bitmask_word = bitmask[(hash / __ELF_NATIVE_CLASS) & tpnt->l_gnu_bitmask_idxbits]; unsigned int hashbit1 = hash & (__ELF_NATIVE_CLASS - 1); unsigned int hashbit2 = ((hash >> tpnt->l_gnu_shift) & (__ELF_NATIVE_CLASS - 1)); @@ -208,9 +207,8 @@ _dl_lookup_gnu_hash(struct elf_resolve *tpnt, ElfW(Sym) *symtab, unsigned long h _dl_assert (bitmask != NULL); if (unlikely((bitmask_word >> hashbit1) & (bitmask_word >> hashbit2) & 1)) { - Elf32_Word bucket = tpnt->l_gnu_buckets[hash % tpnt->nbucket]; - + if (bucket != 0) { const Elf32_Word *hasharr = &tpnt->l_gnu_chain_zero[bucket]; do { @@ -229,20 +227,20 @@ _dl_lookup_gnu_hash(struct elf_resolve *tpnt, ElfW(Sym) *symtab, unsigned long h } #endif -static __always_inline const ElfW(Sym) * -_dl_lookup_sysv_hash(struct elf_resolve *tpnt, ElfW(Sym) *symtab, unsigned long hash, const char* undef_name, int type_class) { - +static __always_inline const ElfW(Sym) * +_dl_lookup_sysv_hash(struct elf_resolve *tpnt, ElfW(Sym) *symtab, unsigned long hash, const char* undef_name, int type_class) +{ unsigned long hn; char *strtab; const ElfW(Sym) *sym; Elf_Symndx symidx; - + /* Avoid calling .urem here. */ do_rem(hn, hash, tpnt->nbucket); strtab = (char *) (tpnt->dynamic_info[DT_STRTAB]); - + _dl_assert(tpnt->elf_buckets != NULL); - + for (symidx = tpnt->elf_buckets[hn]; symidx != STN_UNDEF; symidx = tpnt->chains[symidx]) { sym = check_match (&symtab[symidx], strtab, undef_name, type_class); if (sym != NULL) @@ -251,7 +249,7 @@ _dl_lookup_sysv_hash(struct elf_resolve *tpnt, ElfW(Sym) *symtab, unsigned long } /* No symbol found into the current module*/ return NULL; -} +} /* * This function resolves externals, and this is either called when we process @@ -276,7 +274,7 @@ char *_dl_lookup_hash(const char *name, struct dyn_elf *rpnt, #ifdef __LDSO_GNU_HASH_SUPPORT__ unsigned long gnu_hash_number = _dl_gnu_hash((const unsigned char *)name); #endif - + for (; rpnt; rpnt = rpnt->next) { tpnt = rpnt->dyn; @@ -302,30 +300,32 @@ char *_dl_lookup_hash(const char *name, struct dyn_elf *rpnt, if (tpnt->nbucket == 0) continue; - symtab = (ElfW(Sym) *) (intptr_t) (tpnt->dynamic_info[DT_SYMTAB]); - + symtab = (ElfW(Sym) *) (intptr_t) (tpnt->dynamic_info[DT_SYMTAB]); + #ifdef __LDSO_GNU_HASH_SUPPORT__ /* Prefer GNU hash style, if any */ - if(tpnt->l_gnu_bitmask) { - if((sym = _dl_lookup_gnu_hash(tpnt, symtab, gnu_hash_number, name, type_class)) != NULL) - /* If sym has been found, do not search further */ - break; + if (tpnt->l_gnu_bitmask) { + sym = _dl_lookup_gnu_hash(tpnt, symtab, gnu_hash_number, name, type_class); + if (sym != NULL) + /* If sym has been found, do not search further */ + break; } else { -#endif +#endif /* Use the old SysV-style hash table */ - + /* Calculate the old sysv hash number only once */ - if(elf_hash_number == 0xffffffff) + if (elf_hash_number == 0xffffffff) elf_hash_number = _dl_elf_hash((const unsigned char *)name); - if((sym = _dl_lookup_sysv_hash(tpnt, symtab, elf_hash_number, name, type_class)) != NULL ) + sym = _dl_lookup_sysv_hash(tpnt, symtab, elf_hash_number, name, type_class); + if (sym != NULL) break; -#ifdef __LDSO_GNU_HASH_SUPPORT__ +#ifdef __LDSO_GNU_HASH_SUPPORT__ } -#endif +#endif } /* end of for (; rpnt; rpnt = rpnt->next) { */ - if(sym) { + if (sym) { /* At this point we have found the requested symbol, do binding */ switch (ELF_ST_BIND(sym->st_info)) { case STB_WEAK: diff --git a/ldso/ldso/ldso.c b/ldso/ldso/ldso.c index 31185fd3c..d6aa0b17e 100644 --- a/ldso/ldso/ldso.c +++ b/ldso/ldso/ldso.c @@ -694,7 +694,7 @@ void _dl_get_ready_to_run(struct elf_resolve *tpnt, DL_LOADADDR_TYPE load_addr, if (_dl_stat(tpnt->libname, &st) >= 0) { tpnt->st_dev = st.st_dev; tpnt->st_ino = st.st_ino; - } + } tpnt->n_phent = epnt->e_phnum; tpnt->ppnt = myppnt; for (j = 0; j < epnt->e_phnum; j++, myppnt++) { diff --git a/ldso/libdl/libdl.c b/ldso/libdl/libdl.c index 4538d91e7..edf336684 100644 --- a/ldso/libdl/libdl.c +++ b/ldso/libdl/libdl.c @@ -199,7 +199,7 @@ void *dlopen(const char *libname, int flag) _dl_debug_bindings = strstr(_dl_debug, "bind"); } } -# endif +# endif #endif _dl_map_cache(); @@ -221,7 +221,7 @@ void *dlopen(const char *libname, int flag) tfrom = tpnt; } } - for(rpnt = _dl_symbol_tables; rpnt && rpnt->next; rpnt=rpnt->next); + for (rpnt = _dl_symbol_tables; rpnt && rpnt->next; rpnt=rpnt->next); relro_ptr = rpnt; now_flag = (flag & RTLD_NOW) ? RTLD_NOW : 0; @@ -231,8 +231,8 @@ void *dlopen(const char *libname, int flag) #ifndef SHARED /* When statically linked, the _dl_library_path is not yet initialized */ _dl_library_path = getenv("LD_LIBRARY_PATH"); -#endif - +#endif + /* Try to load the specified library */ _dl_if_debug_print("Trying to dlopen '%s', RTLD_GLOBAL:%d RTLD_NOW:%d\n", (char*)libname, (flag & RTLD_GLOBAL ? 1:0), (now_flag & RTLD_NOW ? 1:0)); @@ -257,7 +257,7 @@ void *dlopen(const char *libname, int flag) if (handle->dyn == tpnt) { dyn_chain->init_fini.init_fini = handle->init_fini.init_fini; dyn_chain->init_fini.nlist = handle->init_fini.nlist; - for(i=0; i < dyn_chain->init_fini.nlist; i++) + for (i = 0; i < dyn_chain->init_fini.nlist; i++) dyn_chain->init_fini.init_fini[i]->rtld_flags |= (flag & RTLD_GLOBAL); dyn_chain->next = handle->next; break; @@ -327,7 +327,7 @@ void *dlopen(const char *libname, int flag) i = 0; for (runp2 = dep_list; runp2; runp2 = runp2->next) { init_fini_list[i++] = runp2->tpnt; - for(runp = runp2->tpnt->init_fini; runp; runp = runp->next){ + for (runp = runp2->tpnt->init_fini; runp; runp = runp->next) { if (!(runp->tpnt->rtld_flags & RTLD_GLOBAL)) { tmp = malloc(sizeof(struct init_fini_list)); tmp->tpnt = runp->tpnt; @@ -359,9 +359,9 @@ void *dlopen(const char *libname, int flag) } } #ifdef __SUPPORT_LD_DEBUG__ - if(_dl_debug) { + if (_dl_debug) { fprintf(stderr, "\nINIT/FINI order and dependencies:\n"); - for (i=0;i < nlist;i++) { + for (i = 0; i < nlist; i++) { fprintf(stderr, "lib: %s has deps:\n", init_fini_list[i]->libname); runp = init_fini_list[i]->init_fini; for (; runp; runp = runp->next) @@ -588,7 +588,7 @@ static int do_dlclose(void *vhandle, int need_fini) end = ppnt->p_vaddr + ppnt->p_memsz; } DL_LIB_UNMAP (tpnt, end); - /* Free elements in RTLD_LOCAL scope list */ + /* Free elements in RTLD_LOCAL scope list */ for (runp = tpnt->rtld_local; runp; runp = tmp) { tmp = runp->next; free(runp); |