summaryrefslogtreecommitdiff
path: root/ldso/ldso/dl-hash.c
diff options
context:
space:
mode:
Diffstat (limited to 'ldso/ldso/dl-hash.c')
-rw-r--r--ldso/ldso/dl-hash.c49
1 files changed, 20 insertions, 29 deletions
diff --git a/ldso/ldso/dl-hash.c b/ldso/ldso/dl-hash.c
index f69f0c171..57fb995ab 100644
--- a/ldso/ldso/dl-hash.c
+++ b/ldso/ldso/dl-hash.c
@@ -154,7 +154,7 @@ struct elf_resolve *_dl_add_elf_hash_table(const char *libname,
* relocations or when we call an entry in the PLT table for the first time.
*/
char *_dl_find_hash(const char *name, struct dyn_elf *rpnt1,
- struct elf_resolve *f_tpnt, enum caller_type caller_type)
+ int type_class)
{
struct elf_resolve *tpnt;
int si;
@@ -163,23 +163,12 @@ char *_dl_find_hash(const char *name, struct dyn_elf *rpnt1,
Elf32_Sym *symtab;
unsigned long elf_hash_number, hn;
char *weak_result;
- struct dyn_elf *rpnt, first;
+ struct dyn_elf *rpnt;
const ElfW(Sym) *sym;
weak_result = 0;
elf_hash_number = _dl_elf_hash(name);
- /* A quick little hack to make sure that any symbol in the executable
- will be preferred to one in a shared library. This is necessary so
- that any shared library data symbols referenced in the executable
- will be seen at the same address by the executable, shared libraries
- and dynamically loaded code. -Rob Ryan (robr@cmu.edu) */
- if (_dl_symbol_tables && rpnt1) {
- first = (*_dl_symbol_tables);
- first.next = rpnt1;
- rpnt1 = (&first);
- }
-
/*
* The passes are so that we can first search the regular symbols
* for whatever module was specified, and then search anything
@@ -187,39 +176,35 @@ char *_dl_find_hash(const char *name, struct dyn_elf *rpnt1,
* starting the first dlopened module, and anything above that
* is just the next one in the chain.
*/
+ if (rpnt1 == NULL)
+ rpnt1 = _dl_symbol_tables;
+
for (pass = 0; (1 == 1); pass++) {
/*
* If we are just starting to search for RTLD_GLOBAL, setup
* the pointer for the start of the search.
*/
- if (pass == 1) {
+ if (pass == 1)
rpnt1 = _dl_handles;
- }
/*
* Anything after this, we need to skip to the next module.
*/
- else if (pass >= 2) {
+ else if (pass >= 2)
rpnt1 = rpnt1->next_handle;
- }
/*
- * Make sure we still have a module, and make sure that this
- * module was loaded with RTLD_GLOBAL.
+ * Make sure we still have a module.
*/
- if (pass != 0) {
if (rpnt1 == NULL)
break;
- //if ((rpnt1->flags & RTLD_GLOBAL) == 0)
- //continue;
- }
- for (rpnt = (rpnt1 ? rpnt1 : _dl_symbol_tables); rpnt; rpnt = rpnt->next) {
+ for (rpnt = rpnt1; rpnt; rpnt = rpnt->next) {
tpnt = rpnt->dyn;
/* Don't search the executable when resolving a copy reloc. */
- if (tpnt->libtype == elf_executable && caller_type == copyrel)
+ if ((type_class & ELF_RTYPE_CLASS_COPY) && tpnt->libtype == elf_executable)
continue;
/*
@@ -236,19 +221,25 @@ char *_dl_find_hash(const char *name, struct dyn_elf *rpnt1,
continue;
if (ELF32_ST_TYPE(sym->st_info) > STT_FUNC)
continue;
- if (sym->st_shndx == SHN_UNDEF && caller_type != copyrel)
+ if (type_class & (sym->st_shndx == SHN_UNDEF))
continue;
if (_dl_strcmp(strtab + sym->st_name, name) != 0)
continue;
switch (ELF32_ST_BIND(sym->st_info)) {
case STB_WEAK:
-//Disable this to match current glibc behavior. Of course,
-//this doesn't actually work yet and will cause segfaults...
-#if 1
+#ifndef __LIBDL_SHARED__
+/*
+Due to a special hack in libdl.c, one must handle the _dl_ symbols
+according to the OLD weak symbol scheme. This stuff can be deleted
+once that hack has been fixed.
+*/
+
+ if(_dl_symbol((char *)name)) {
if (!weak_result)
weak_result = (char *)tpnt->loadaddr + sym->st_value;
break;
+ }
#endif
case STB_GLOBAL:
return (char*)tpnt->loadaddr + sym->st_value;