Просмотр исходного кода

fix resolving symbols in objects loaded in RTLD_LOCAL mode

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.
Rich Felker 13 лет назад
Родитель
Сommit
92ab5d8d15
1 измененных файлов с 11 добавлено и 0 удалено
  1. 11 0
      src/ldso/dynlink.c

+ 11 - 0
src/ldso/dynlink.c

@@ -493,6 +493,9 @@ void *dlopen(const char *file, int mode)
 
 
 	if (setjmp(rtld_fail)) {
 	if (setjmp(rtld_fail)) {
 		/* Clean up anything new that was (partially) loaded */
 		/* 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) {
 		for (p=orig_tail->next; p; p=next) {
 			next = p->next;
 			next = p->next;
 			munmap(p->map, p->map_len);
 			munmap(p->map, p->map_len);
@@ -511,7 +514,15 @@ void *dlopen(const char *file, int mode)
 	/* First load handling */
 	/* First load handling */
 	if (!p->deps) {
 	if (!p->deps) {
 		load_deps(p);
 		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);
 		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) {
 	if (mode & RTLD_GLOBAL) {