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 /ldso/libdl/libdl.c | |
parent | 4a38f88b2caeac2faee85fb80606cc9732faa1f7 (diff) |
Fix libdl bug reported by Cedric Hombourger in
http://uclibc.org/lists/uclibc/2007-January/017165.html
Diffstat (limited to 'ldso/libdl/libdl.c')
-rw-r--r-- | ldso/libdl/libdl.c | 57 |
1 files changed, 27 insertions, 30 deletions
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. |