summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorRich Felker <dalias@aerifal.cx>2012-10-07 21:43:46 -0400
committerRich Felker <dalias@aerifal.cx>2012-10-07 21:43:46 -0400
commit0a96a37f06fda78ce3674b425888b1fc090578aa (patch)
tree562b45acc1191a74bca5db876b44fd652678c94f /src
parent017bf140ffb41e9a016df84dc4c1806e0686b28a (diff)
downloadmusl-0a96a37f06fda78ce3674b425888b1fc090578aa.tar.gz
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.
Diffstat (limited to 'src')
-rw-r--r--src/env/__init_security.c19
-rw-r--r--src/env/__init_tls.c11
-rw-r--r--src/env/__libc_start_main.c26
-rw-r--r--src/env/__stack_chk_fail.c5
-rw-r--r--src/ldso/dynlink.c4
-rw-r--r--src/thread/pthread_create.c2
6 files changed, 33 insertions, 34 deletions
diff --git a/src/env/__init_security.c b/src/env/__init_security.c
index f9de9c62..91b9b100 100644
--- a/src/env/__init_security.c
+++ b/src/env/__init_security.c
@@ -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;
}
diff --git a/src/env/__init_tls.c b/src/env/__init_tls.c
index 6b3cd28b..e70025d7 100644
--- a/src/env/__init_tls.c
+++ b/src/env/__init_tls.c
@@ -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
diff --git a/src/env/__libc_start_main.c b/src/env/__libc_start_main.c
index a38569d5..07613a52 100644
--- a/src/env/__libc_start_main.c
+++ b/src/env/__libc_start_main.c
@@ -1,24 +1,36 @@
+#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);
diff --git a/src/env/__stack_chk_fail.c b/src/env/__stack_chk_fail.c
index eac852b7..3e2e4b6d 100644
--- a/src/env/__stack_chk_fail.c
+++ b/src/env/__stack_chk_fail.c
@@ -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;
diff --git a/src/ldso/dynlink.c b/src/ldso/dynlink.c
index 33ef7e55..c3cb6115 100644
--- a/src/ldso/dynlink.c
+++ b/src/ldso/dynlink.c
@@ -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);
diff --git a/src/thread/pthread_create.c b/src/thread/pthread_create.c
index 92ce9ffb..6327a942 100644
--- a/src/thread/pthread_create.c
+++ b/src/thread/pthread_create.c
@@ -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);