mirror of git://git.musl-libc.org/musl
load vdso, if present, into the dso list
This commit is contained in:
parent
f7adc39e37
commit
6ab444d97a
|
@ -298,7 +298,7 @@ static struct dso *load_library(const char *name)
|
|||
if (!libc->prev) {
|
||||
tail->next = libc;
|
||||
libc->prev = tail;
|
||||
tail = libc;
|
||||
tail = libc->next ? libc->next : libc;
|
||||
}
|
||||
return libc;
|
||||
}
|
||||
|
@ -440,12 +440,15 @@ void *__dynlink(int argc, char **argv, size_t *got)
|
|||
size_t *auxv, aux[AUX_CNT] = {0};
|
||||
size_t app_dyn[DYN_CNT] = {0};
|
||||
size_t lib_dyn[DYN_CNT] = {0};
|
||||
size_t vdso_dyn[DYN_CNT] = {0};
|
||||
size_t i;
|
||||
Phdr *phdr;
|
||||
Ehdr *ehdr;
|
||||
static struct dso builtin_dsos[2];
|
||||
static struct dso builtin_dsos[3];
|
||||
struct dso *const app = builtin_dsos+0;
|
||||
struct dso *const lib = builtin_dsos+1;
|
||||
struct dso *const vdso = builtin_dsos+2;
|
||||
size_t vdso_base=0;
|
||||
|
||||
/* Find aux vector just past environ[] */
|
||||
for (i=argc+1; argv[i]; i++)
|
||||
|
@ -455,6 +458,13 @@ void *__dynlink(int argc, char **argv, size_t *got)
|
|||
|
||||
decode_vec(auxv, aux, AUX_CNT);
|
||||
|
||||
for (i=0; auxv[i]; i+=2) {
|
||||
if (auxv[i]==AT_SYSINFO_EHDR) {
|
||||
vdso_base = auxv[i+1];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* Only trust user/env if kernel says we're not suid/sgid */
|
||||
if ((aux[0]&0x7800)!=0x7800 || aux[AT_UID]!=aux[AT_EUID]
|
||||
|| aux[AT_GID]!=aux[AT_EGID]) {
|
||||
|
@ -495,6 +505,25 @@ void *__dynlink(int argc, char **argv, size_t *got)
|
|||
.relocated = 1
|
||||
};
|
||||
|
||||
if (vdso_base) {
|
||||
ehdr = (void *)vdso_base;
|
||||
phdr = (void *)(vdso_base + ehdr->e_phoff);
|
||||
for (i=ehdr->e_phnum; i; i--, phdr=(void *)((char *)phdr + ehdr->e_phentsize)) {
|
||||
if (phdr->p_type == PT_DYNAMIC)
|
||||
vdso->dynv = (void *)(vdso_base + phdr->p_offset);
|
||||
if (phdr->p_type == PT_LOAD)
|
||||
vdso->base = (void *)(vdso_base - phdr->p_vaddr + phdr->p_offset);
|
||||
}
|
||||
decode_vec(vdso->dynv, vdso_dyn, DYN_CNT);
|
||||
vdso->syms = (void *)(vdso->base + vdso_dyn[DT_SYMTAB]);
|
||||
vdso->hashtab = (void *)(vdso->base + vdso_dyn[DT_HASH]);
|
||||
vdso->strings = (void *)(vdso->base + vdso_dyn[DT_STRTAB]);
|
||||
vdso->name = "linux-gate.so.1";
|
||||
|
||||
vdso->prev = lib;
|
||||
lib->next = vdso;
|
||||
}
|
||||
|
||||
/* 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);
|
||||
|
|
Loading…
Reference in New Issue