4 * This function takes the raw data block set up by the ELF loader
5 * in the kernel and parses it. It is invoked by crt0.S which makes
6 * any necessary adjustments and passes calls this function using
7 * the standard C calling convention.
10 * uintptr_t *elfdata -- The ELF loader data block; usually from the stack.
11 * Basically a pointer to argc.
12 * void (*onexit)(void) -- Function to install into onexit
18 #include <klibc/compiler.h>
21 /* This file is included from __static_init.c or __shared_init.c */
23 # error "SHARED should be defined to 0 or 1"
27 unsigned int __page_size, __page_shift;
34 __noreturn __libc_init(uintptr_t *elfdata, void (*onexit)(void))
37 char **argv, **envp, **envend;
38 struct auxentry *auxentry;
40 typedef int (*main_t)(int, char **, char **);
43 extern int main(int, char **, char **);
46 unsigned int page_size = 0, page_shift = 0;
48 (void)onexit; /* For now, we ignore this... */
50 argc = (int)*elfdata++;
51 argv = (char **)elfdata;
54 /* The auxillary entry vector is after all the environment vars */
55 for ( envend = envp ; *envend ; envend++ );
56 auxentry = (struct auxentry *)(envend+1);
58 while ( auxentry->type ) {
59 switch ( auxentry->type ) {
62 MAIN = (main_t)(auxentry->v);
66 page_size = (int)(auxentry->v);
72 __page_size = page_size;
74 #if defined(__i386__) || defined(__x86_64__)
75 asm("bsrl %1,%0" : "=r" (page_shift) : "rm" (page_size));
77 while ( page_size > 1 ) {
82 __page_shift = page_shift;
85 exit(MAIN(argc, argv, envp));