Преглед на файлове

simplify dynamic linker startup

instead of creating temp dso objects on the stack and moving them to
the heap if dlopen/dlsym are used, use static objects to begin with,
and just donate them to malloc if we no longer need them.
Rich Felker преди 13 години
родител
ревизия
a53de812d2
променени са 1 файла, в които са добавени 17 реда и са изтрити 23 реда
  1. 17 23
      src/ldso/dynlink.c

+ 17 - 23
src/ldso/dynlink.c

@@ -443,7 +443,9 @@ void *__dynlink(int argc, char **argv, size_t *got)
 	size_t i;
 	Phdr *phdr;
 	Ehdr *ehdr;
-	struct dso lib, app;
+	static struct dso builtin_dsos[2];
+	struct dso *const app = builtin_dsos+0;
+	struct dso *const lib = builtin_dsos+1;
 
 	/* Find aux vector just past environ[] */
 	for (i=argc+1; argv[i]; i++)
@@ -471,7 +473,7 @@ void *__dynlink(int argc, char **argv, size_t *got)
 		}
 	}
 
-	app = (struct dso){
+	*app = (struct dso){
 		.base = 0,
 		.strings = (void *)(app_dyn[DT_STRTAB]),
 		.hashtab = (void *)(app_dyn[DT_HASH]),
@@ -479,10 +481,10 @@ void *__dynlink(int argc, char **argv, size_t *got)
 		.dynv = (void *)(phdr->p_vaddr),
 		.name = argv[0],
 		.global = 1,
-		.next = &lib
+		.next = lib
 	};
 
-	lib = (struct dso){
+	*lib = (struct dso){
 		.base = (void *)aux[AT_BASE],
 		.strings = (void *)(aux[AT_BASE]+lib_dyn[DT_STRTAB]),
 		.hashtab = (void *)(aux[AT_BASE]+lib_dyn[DT_HASH]),
@@ -495,39 +497,31 @@ void *__dynlink(int argc, char **argv, size_t *got)
 
 	/* Relocate the dynamic linker/libc */
 	do_relocs((void *)aux[AT_BASE], (void *)(aux[AT_BASE]+lib_dyn[DT_REL]),
-		lib_dyn[DT_RELSZ], 2, lib.syms, lib.strings, &app);
+		lib_dyn[DT_RELSZ], 2, lib->syms, lib->strings, app);
 	do_relocs((void *)aux[AT_BASE], (void *)(aux[AT_BASE]+lib_dyn[DT_RELA]),
-		lib_dyn[DT_RELASZ], 3, lib.syms, lib.strings, &app);
+		lib_dyn[DT_RELASZ], 3, lib->syms, lib->strings, app);
 
 	/* At this point the standard library is fully functional */
 
-	reclaim_gaps(app.base, (void *)aux[AT_PHDR], aux[AT_PHENT], aux[AT_PHNUM]);
-	ehdr = (void *)lib.base;
-	reclaim_gaps(lib.base, (void *)(lib.base+ehdr->e_phoff),
+	reclaim_gaps(app->base, (void *)aux[AT_PHDR], aux[AT_PHENT], aux[AT_PHNUM]);
+	ehdr = (void *)lib->base;
+	reclaim_gaps(lib->base, (void *)(lib->base+ehdr->e_phoff),
 		ehdr->e_phentsize, ehdr->e_phnum);
 
-	head = tail = &app;
-	libc = &lib;
-	app.next = 0;
+	head = tail = app;
+	libc = lib;
+	app->next = 0;
 	load_deps(head);
 
 	make_global(head);
 	reloc_all(head->next);
 	reloc_all(head);
 
-	if (rtld_used) {
-		runtime = 1;
-		head->next->prev = malloc(sizeof *head);
-		*head->next->prev = *head;
-		head = head->next->prev;
-		libc->prev->next = malloc(sizeof *libc);
-		*libc->prev->next = *libc;
-		libc = libc->prev->next;
-		if (libc->next) libc->next->prev = libc;
-		if (tail == &lib) tail = libc;
-	} else {
+	runtime = 1;
+	if (!rtld_used) {
 		free_all(head);
 		free(sys_path);
+		reclaim((void *)builtin_dsos, 0, sizeof builtin_dsos);
 	}
 
 	errno = 0;