diff options
author | Joakim Tjernlund <joakim.tjernlund@transmode.se> | 2007-01-26 00:25:10 +0000 |
---|---|---|
committer | Joakim Tjernlund <joakim.tjernlund@transmode.se> | 2007-01-26 00:25:10 +0000 |
commit | 7a9cec961bb9ec7862751ac7d142b689aaf82841 (patch) | |
tree | 0e81f37774dcd0cfe7ad81b6cb43e07c0fe2f98d | |
parent | 4a38f88b2caeac2faee85fb80606cc9732faa1f7 (diff) |
Fix libdl bug reported by Cedric Hombourger in
http://uclibc.org/lists/uclibc/2007-January/017165.html
-rw-r--r-- | ldso/ldso/ldso.c | 5 | ||||
-rw-r--r-- | ldso/libdl/libdl.c | 57 |
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. |