Syncs up Makeconfig and the Makelocal.template
[akaros.git] / tools / compilers / gcc-glibc / glibc-2.11.1-ros / sysdeps / ros / start.c
1 #include <abort-instr.h>
2 #include <string.h>
3 #include <vcore.h>
4 #include <stdio.h>
5 #include <ros/syscall.h>
6 #include <ros/procinfo.h>
7 #include <unistd.h>
8 #include <tls.h>
9
10 void** __vcore_thread_control_blocks = NULL;
11 weak_alias(__vcore_thread_control_blocks,vcore_thread_control_blocks)
12
13 __thread int __vcoreid = 0;
14
15 void
16 __vcore_entry(void)
17 {
18         fputs("define a vcore_entry() function, foo!",stderr);
19         abort();
20 }
21 weak_alias(__vcore_entry,vcore_entry)
22
23 #define failmsg(str) write(2,str"\n",sizeof(str"\n")-1)
24
25 void
26 _start(void)
27 {
28         // WARNING: __vcore_self_on_entry must be read before
29         // anything is register-allocated!
30         int id = __vcore_id_on_entry;
31         static int init = 0;
32         // For dynamically-linked programs, the first time through,
33         // __vcore_self_on_entry could be clobbered (on x86), because
34         // the linker will have overwritten eax.  Happily, the first
35         // time through, we know we are vcore 0.  Subsequent entries
36         // into this routine do not have this problem.
37         if(init == 0)
38                 id = 0;
39         
40         // vcore0 when it comes up again, and all threads besides thread 0 must
41         // acquire a TCB.
42         if(init || (id != 0))
43         {
44                 set_tls_desc(__vcore_thread_control_blocks[id],id);
45                 __vcoreid = id;
46                 vcore_entry();
47                 failmsg("why did vcore_entry() return?");
48                 goto diediedie;
49         }
50
51         init = 1;
52
53         extern int main(int,char**,char**);
54         extern void __libc_csu_init(int,char**,char**);
55         extern void __libc_csu_fini(void);
56         extern void __libc_start_main(typeof(&main),int,char**,
57                       typeof(&__libc_csu_init),
58                       typeof(&__libc_csu_fini),
59                       void*,void*);
60
61         char** argv = (char**)alloca(sizeof(__procinfo.argp));
62         memcpy(argv,__procinfo.argp,sizeof(__procinfo.argp));
63
64         char* argbuf = (char*)alloca(sizeof(__procinfo.argbuf));
65         memcpy(argbuf,__procinfo.argbuf,sizeof(__procinfo.argbuf));
66
67         // touch up pointers, but don't mess up auxp!
68         for(int i = 0, zeros = 0; i < PROCINFO_MAX_ARGP; i++)
69         {
70                 if(argv[i])
71                         argv[i] += argbuf - __procinfo.argbuf;
72                 else if(++zeros == 2)
73                         break;
74         }
75
76         int argc = 0;
77         while(argv[argc])
78                 argc++;
79
80         extern char** _environ;
81         _environ = argv+argc+1;
82
83         __libc_start_main(&main,argc,argv,&__libc_csu_init,&__libc_csu_fini,0,0);
84
85         failmsg("why did main() return?");
86
87 diediedie:
88         abort();
89         #ifdef ABORT_INSTRUCTION
90         ABORT_INSTRUCTION;
91         #endif
92         while(1);
93 }