fix resolving symbols in objects loaded in RTLD_LOCAL mode
authorRich Felker <dalias@aerifal.cx>
Mon, 27 Jun 2011 01:21:04 +0000 (21:21 -0400)
committerRich Felker <dalias@aerifal.cx>
Mon, 27 Jun 2011 01:21:04 +0000 (21:21 -0400)
basically we temporarily make the library and all its dependencies
part of the global namespace but only for the duration of performing
relocations, then return them to their former state.

src/ldso/dynlink.c

index 35ff9626ae4ee91ae7151e5ddd05463b7ad7b89b..305d70e010bcdcfff655351b59c92f90ea545fdb 100644 (file)
@@ -493,6 +493,9 @@ void *dlopen(const char *file, int mode)
 
        if (setjmp(rtld_fail)) {
                /* Clean up anything new that was (partially) loaded */
+               if (p->deps) for (i=0; p->deps[i]; i++)
+                       if (p->deps[i]->global < 0)
+                               p->deps[i]->global = 0;
                for (p=orig_tail->next; p; p=next) {
                        next = p->next;
                        munmap(p->map, p->map_len);
@@ -511,7 +514,15 @@ void *dlopen(const char *file, int mode)
        /* First load handling */
        if (!p->deps) {
                load_deps(p);
+               for (i=0; p->deps[i]; i++)
+                       if (!p->deps[i]->global)
+                               p->deps[i]->global = -1;
+               if (!p->global) p->global = -1;
                reloc_all(p);
+               for (i=0; p->deps[i]; i++)
+                       if (p->deps[i]->global < 0)
+                               p->deps[i]->global = 0;
+               if (p->global < 0) p->global = 0;
        }
 
        if (mode & RTLD_GLOBAL) {