diff options
author | Joakim Tjernlund <joakim.tjernlund@transmode.se> | 2005-04-23 16:54:05 +0000 |
---|---|---|
committer | Joakim Tjernlund <joakim.tjernlund@transmode.se> | 2005-04-23 16:54:05 +0000 |
commit | 52b5a52b480f35928fccdff7298edf92736564ed (patch) | |
tree | 9dafd4f83e3b34b56efa43034ee5ff071bc5cc66 /ldso | |
parent | fdaf1b4fa8a79ce82b0c5f5a840ae98c7cb74786 (diff) |
Fix dlopen to handle circular dependency libs. Wouldn't surprise me if something else
broke. I hate libdl :(
Diffstat (limited to 'ldso')
-rw-r--r-- | ldso/libdl/libdl.c | 23 |
1 files changed, 18 insertions, 5 deletions
diff --git a/ldso/libdl/libdl.c b/ldso/libdl/libdl.c index 222c7743f..0c744c210 100644 --- a/ldso/libdl/libdl.c +++ b/ldso/libdl/libdl.c @@ -255,15 +255,28 @@ void *dlopen(const char *libname, int flag) } if (tpnt1->init_flag & DL_OPENED) { /* Used to record RTLD_LOCAL scope */ - tmp = alloca(sizeof(struct init_fini_list)); /* Allocates on stack, no need to free this memory */ + tmp = alloca(sizeof(struct init_fini_list)); tmp->tpnt = tpnt1; tmp->next = runp->tpnt->init_fini; runp->tpnt->init_fini = tmp; - runp2->next = alloca(sizeof(*runp)); /* Allocates on stack, no need to free this memory */ - runp2 = runp2->next; - runp2->tpnt = tpnt1; - runp2->next = NULL; + for (tmp=dep_list; tmp; tmp = tmp->next) { + if (tpnt1 == tmp->tpnt) { /* if match => cirular dependency, drop it */ +#ifdef __SUPPORT_LD_DEBUG__ + if(_dl_debug) + fprintf(stderr, "Circular dependency, skipping '%s',\n", + tmp->tpnt->libname); +#endif + 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; + } } } } |