summaryrefslogtreecommitdiff
path: root/ldso
diff options
context:
space:
mode:
authorJoakim Tjernlund <joakim.tjernlund@transmode.se>2007-01-26 00:25:10 +0000
committerJoakim Tjernlund <joakim.tjernlund@transmode.se>2007-01-26 00:25:10 +0000
commit7a9cec961bb9ec7862751ac7d142b689aaf82841 (patch)
tree0e81f37774dcd0cfe7ad81b6cb43e07c0fe2f98d /ldso
parent4a38f88b2caeac2faee85fb80606cc9732faa1f7 (diff)
Fix libdl bug reported by Cedric Hombourger in
http://uclibc.org/lists/uclibc/2007-January/017165.html
Diffstat (limited to 'ldso')
-rw-r--r--ldso/ldso/ldso.c5
-rw-r--r--ldso/libdl/libdl.c57
2 files changed, 32 insertions, 30 deletions
diff --git a/ldso/ldso/ldso.c b/ldso/ldso/ldso.c
index f8f3dc67c..d31ae1d73 100644
--- a/ldso/ldso/ldso.c
+++ b/ldso/ldso/ldso.c
@@ -192,6 +192,7 @@ void _dl_get_ready_to_run(struct elf_resolve *tpnt, DL_LOADADDR_TYPE load_addr,
unsigned long *_dl_envp; /* The environment address */
ElfW(Addr) relro_addr = 0;
size_t relro_size = 0;
+ struct stat st;
/* Wahoo!!! We managed to make a function call! Get malloc
* setup so we can use _dl_dprintf() to print debug noise
@@ -725,6 +726,10 @@ void _dl_get_ready_to_run(struct elf_resolve *tpnt, DL_LOADADDR_TYPE load_addr,
(unsigned long)tpnt->dynamic_addr,
0);
+ 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 e7e33c426..505f09546 100644
--- a/ldso/libdl/libdl.c
+++ b/ldso/libdl/libdl.c
@@ -246,36 +246,31 @@ void *dlopen(const char *libname, int flag)
tpnt1->rtld_flags |= (flag & RTLD_GLOBAL);
- if (tpnt1->usage_count == 1) {
- tpnt1->init_flag |= DL_OPENED;
- /* This list is for dlsym() and relocation */
- dyn_ptr->next = (struct dyn_elf *) malloc(sizeof(struct dyn_elf));
- _dl_memset (dyn_ptr->next, 0, sizeof (struct dyn_elf));
- dyn_ptr = dyn_ptr->next;
- dyn_ptr->dyn = tpnt1;
- }
- if (tpnt1->init_flag & DL_OPENED) {
- /* Used to record RTLD_LOCAL scope */
- tmp = alloca(sizeof(struct init_fini_list));
- tmp->tpnt = tpnt1;
- tmp->next = runp->tpnt->init_fini;
- runp->tpnt->init_fini = tmp;
-
- for (tmp=dep_list; tmp; tmp = tmp->next) {
- if (tpnt1 == tmp->tpnt) { /* if match => cirular dependency, drop it */
- _dl_if_debug_print("Circular dependency, skipping '%s',\n",
- tmp->tpnt->libname);
- tpnt1->usage_count--;
- break;
- }
- }
- if (!tmp) { /* Don't add if circular dependency detected */
- runp2->next = alloca(sizeof(*runp));
- runp2 = runp2->next;
- runp2->tpnt = tpnt1;
- runp2->next = NULL;
+ /* This list is for dlsym() and relocation */
+ dyn_ptr->next = (struct dyn_elf *) malloc(sizeof(struct dyn_elf));
+ _dl_memset (dyn_ptr->next, 0, sizeof (struct dyn_elf));
+ dyn_ptr = dyn_ptr->next;
+ dyn_ptr->dyn = tpnt1;
+ /* Used to record RTLD_LOCAL scope */
+ tmp = alloca(sizeof(struct init_fini_list));
+ tmp->tpnt = tpnt1;
+ tmp->next = runp->tpnt->init_fini;
+ runp->tpnt->init_fini = tmp;
+
+ for (tmp=dep_list; tmp; tmp = tmp->next) {
+ if (tpnt1 == tmp->tpnt) { /* if match => cirular dependency, drop it */
+ _dl_if_debug_print("Circular dependency, skipping '%s',\n",
+ tmp->tpnt->libname);
+ tpnt1->usage_count--;
+ break;
}
}
+ if (!tmp) { /* Don't add if circular dependency detected */
+ runp2->next = alloca(sizeof(*runp));
+ runp2 = runp2->next;
+ runp2->tpnt = tpnt1;
+ runp2->next = NULL;
+ }
}
}
}
@@ -441,8 +436,10 @@ void *dlsym(void *vhandle, const char *name)
}
}
}
-
- ret = _dl_find_hash((char*)name, handle, NULL, 0);
+ tpnt = NULL;
+ if (handle == _dl_symbol_tables)
+ tpnt = handle->dyn; /* Only search RTLD_GLOBAL objs if global object */
+ ret = _dl_find_hash((char*)name, handle, tpnt, 0);
/*
* Nothing found.