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.
This commit is contained in:
Rich Felker
2012-10-07 21:43:46 -04:00
parent 017bf140ff
commit 0a96a37f06
6 changed files with 33 additions and 34 deletions

View File

@ -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);