chiark / gitweb /
[PATCH] sync with latest version of klibc (0.107)
[elogind.git] / klibc / klibc / __shared_init.c
1 /*
2  * __shared_init.c
3  *
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.
8  *
9  * The arguments are:
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
13  */
14
15 #include <stddef.h>
16 #include <stdlib.h>
17 #include <stdint.h>
18 #include <klibc/compiler.h>
19 #include <elf.h>
20
21 char **environ;
22
23 __noreturn __libc_init(uintptr_t *elfdata, void (*onexit)(void))
24 {
25   int argc;
26   char **argv, **envp, **envend;
27   struct auxentry {
28     uintptr_t type;
29     uintptr_t v;
30   } *auxentry;
31   typedef int (*main_t)(int, char **, char **);
32   main_t main_ptr = NULL;
33
34   (void)onexit;                 /* For now, we ignore this... */
35
36   argc = (int)*elfdata++;
37   argv = (char **)elfdata;
38   envp = argv+(argc+1);
39
40   /* The auxillary entry vector is after all the environment vars */
41   for ( envend = envp ; *envend ; envend++ );
42   auxentry = (struct auxentry *)(envend+1);
43
44   while ( auxentry->type ) {
45     if ( auxentry->type == AT_ENTRY ) {
46       main_ptr = (main_t)(auxentry->v);
47       break;
48     }
49     auxentry++;
50   }
51
52   environ = envp;
53   exit(main_ptr(argc, argv, envp));
54 }
55
56