提交 0a96a37f 编写于 作者: R Rich Felker

clean up and refactor program initialization

the code in __libc_start_main is now responsible for parsing auxv,
rather than duplicating the parsing all over the place. this should
shave off a few cycles and some code size. __init_libc is left as an
external-linkage function despite the fact that it could be static, to
prevent it from being inlined and permanently wasting stack space when
main is called.

a few other minor changes are included, like eliminating per-thread
ssp canaries (they were likely broken when combined with certain
dlopen usages, and completely unnecessary) and some other unnecessary
checks. since this code gets linked into every program, it should be
as small and simple as possible.
上级 017bf140
......@@ -6,31 +6,26 @@
#include "libc.h"
#include "atomic.h"
#define AUX_CNT 24
static void dummy(size_t *auxv)
static void dummy(void *ent)
{
}
weak_alias(dummy, __init_ssp);
void __init_security(size_t *auxv)
void __init_security(size_t *aux)
{
size_t i, aux[AUX_CNT] = { 0 };
struct pollfd pfd[3] = { {.fd=0}, {.fd=1}, {.fd=2} };
int i;
#ifndef SHARED
__init_ssp(auxv);
__init_ssp((void *)aux[AT_RANDOM]);
#endif
for (; auxv[0]; auxv+=2) if (auxv[0]<AUX_CNT) aux[auxv[0]] = auxv[1];
__hwcap = aux[AT_HWCAP];
if (aux[AT_UID]==aux[AT_EUID] && aux[AT_GID]==aux[AT_EGID]
&& !aux[AT_SECURE]) return;
__syscall(SYS_poll, pfd, 3, 0);
for (i=0; i<3; i++)
if (pfd[i].revents&POLLNVAL)
if (__syscall(SYS_open, "/dev/null", O_RDWR|O_LARGEFILE)<0)
a_crash();
for (i=0; i<3; i++) if (pfd[i].revents&POLLNVAL)
if (__syscall(SYS_open, "/dev/null", O_RDWR|O_LARGEFILE)<0)
a_crash();
libc.secure = 1;
}
......@@ -46,19 +46,14 @@ typedef Elf32_Phdr Phdr;
typedef Elf64_Phdr Phdr;
#endif
#define AUX_CNT 6
void __init_tls(size_t *auxv)
void __init_tls(size_t *aux)
{
size_t i, aux[AUX_CNT] = { 0 };
unsigned char *p, *mem;
size_t n, d;
Phdr *phdr, *tls_phdr=0;
size_t base = 0;
for (; auxv[0]; auxv+=2) if (auxv[0]<AUX_CNT) aux[auxv[0]] = auxv[1];
p = (void *)aux[AT_PHDR];
for (p=(void *)aux[AT_PHDR]; aux[AT_PHNUM]--; p+=aux[AT_PHENT]) {
for (p=(void *)aux[AT_PHDR],n=aux[AT_PHNUM]; n; n--,p+=aux[AT_PHENT]) {
phdr = (void *)p;
if (phdr->p_type == PT_PHDR)
base = aux[AT_PHDR] - phdr->p_vaddr;
......@@ -79,8 +74,6 @@ void __init_tls(size_t *auxv)
mem = __mmap(0, libc.tls_size, PROT_READ|PROT_WRITE,
MAP_ANONYMOUS|MAP_PRIVATE, -1, 0);
if (mem == MAP_FAILED) a_crash();
if (!__install_initial_tls(__copy_tls(mem))) a_crash();
}
#else
......
#include <elf.h>
#include "libc.h"
void __init_tls(size_t *);
void __init_security(size_t *);
#define AUX_CNT 38
void __init_libc(char **envp)
{
size_t i, *auxv, aux[AUX_CNT];
__environ = envp;
for (i=0; envp[i]; i++);
libc.auxv = auxv = (void *)(envp+i+1);
for (i=0; auxv[i]; i+=2) if (auxv[i]<AUX_CNT) aux[auxv[i]] = auxv[i+1];
__hwcap = aux[AT_HWCAP];
__init_tls(aux);
__init_security(aux);
}
int __libc_start_main(
int (*main)(int, char **, char **), int argc, char **argv,
int (*init)(int, char **, char **), void (*fini)(void),
void (*ldso_fini)(void))
{
char **envp = argv+argc+1, **auxv = envp;
char **envp = argv+argc+1;
__init_libc(envp);
__environ = envp;
do auxv++; while (*auxv);
libc.auxv = (void *)++auxv;
libc.ldso_fini = ldso_fini;
libc.fini = fini;
__init_tls((void *)auxv);
__init_security((void *)auxv);
/* Execute constructors (static) linked into the application */
if (init) init(argc, argv, envp);
......
......@@ -6,13 +6,12 @@
uintptr_t __stack_chk_guard;
void __init_ssp(size_t *auxv)
void __init_ssp(void *entropy)
{
size_t i;
pthread_t self = __pthread_self_init();
uintptr_t canary;
for (i=0; auxv[i] && auxv[i]!=AT_RANDOM; i+=2);
if (auxv[i]) memcpy(&canary, (void *)auxv[i+1], sizeof canary);
if (entropy) memcpy(&canary, entropy, sizeof canary);
else canary = (uintptr_t)&canary * 1103515245;
a_cas_l(&__stack_chk_guard, 0, canary);
self->canary = __stack_chk_guard;
......
......@@ -105,7 +105,7 @@ static pthread_mutex_t init_fini_lock = { ._m_type = PTHREAD_MUTEX_RECURSIVE };
struct debug *_dl_debug_addr = &debug;
#define AUX_CNT 24
#define AUX_CNT 38
#define DYN_CNT 34
static void decode_vec(size_t *v, size_t *a, size_t cnt)
......@@ -967,7 +967,7 @@ void *__dynlink(int argc, char **argv)
debug.state = 0;
_dl_debug_state();
if (ssp_used) __init_ssp(auxv);
if (ssp_used) __init_ssp((void *)aux[AT_RANDOM]);
atexit(do_fini);
do_init_fini(tail);
......
......@@ -144,7 +144,7 @@ int pthread_create(pthread_t *restrict res, const pthread_attr_t *restrict attr,
flags -= 0x200000;
}
new->unblock_cancel = self->cancel;
new->canary = self->canary ^ (uintptr_t)&new;
new->canary = self->canary;
stack = (void *)new;
a_inc(&libc.threads_minus_1);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册