summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorRich Felker <dalias@aerifal.cx>2011-07-24 00:26:12 -0400
committerRich Felker <dalias@aerifal.cx>2011-07-24 00:26:12 -0400
commita53de812d258a7b0be44ce5dfc96e0f8ce137817 (patch)
tree7c7a84aee7a4ff0c6622edffd5f77231c7ec69b4 /src
parente3eb49321c85e43fcc6842f3f57ee097b32555e4 (diff)
downloadmusl-a53de812d258a7b0be44ce5dfc96e0f8ce137817.tar.gz
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.
Diffstat (limited to 'src')
-rw-r--r--src/ldso/dynlink.c40
1 files changed, 17 insertions, 23 deletions
diff --git a/src/ldso/dynlink.c b/src/ldso/dynlink.c
index 33937e76..226e174f 100644
--- a/src/ldso/dynlink.c
+++ b/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;