mirror of
git://git.musl-libc.org/musl
synced 2024-12-19 05:14:47 +00:00
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.
This commit is contained in:
parent
e3eb49321c
commit
a53de812d2
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user