Debugging: Add code to print backtrace for guest on SIGSEGV
[nativeclient.git] / tools / stubs / crt1.S
blobdef889e02f4e9f962d426fcaefc344b0c85af2cf
1 /*
2  * Copyright 2008, Google Inc.
3  * All rights reserved.
4  * 
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions are
7  * met:
8  * 
9  *     * Redistributions of source code must retain the above copyright
10  * notice, this list of conditions and the following disclaimer.
11  *     * Redistributions in binary form must reproduce the above
12  * copyright notice, this list of conditions and the following disclaimer
13  * in the documentation and/or other materials provided with the
14  * distribution.
15  *     * Neither the name of Google Inc. nor the names of its
16  * contributors may be used to endorse or promote products derived from
17  * this software without specific prior written permission.
18  * 
19  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
22  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
23  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
25  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30  */
32 /* Native Client crt0 startup code */
34         .data
35         .globl environ
37         .text
38         .p2align NACLENTRYALIGN,0xf4,
40         .global _start
41 _start:
42         /*
43          *  The i386 ELF ABI specifies that on entry the stack looks like:
44          *            --------------------------------
45          *            |          Unspecified         |
46          *            --------------------------------
47          *            | Information block, including |
48          *            |       argument strings,      |
49          *            |      environment strings,    |
50          *            |     auxiliary information    |
51          *            |              ...             |
52          *            |        (size varies)         |
53          *            --------------------------------
54          *            |         Unspecified          |
55          *            --------------------------------
56          *            | Null auxiliary vector entry  |
57          *            --------------------------------
58          *            |        Auxiliary vector      |
59          *            |              ...             |
60          *            |        (2-word entries)      |
61          *            --------------------------------
62          *            |            0 word            |
63          *            --------------------------------
64          *            |      Environment pointers    |
65          *            |              ...             |
66          *            |         (one word each)      |
67          *            --------------------------------
68          *            |       Argument pointers      |
69          *            |              ...             |
70          *  4(%esp)   |    (Argument count words)    |
71          *            --------------------------------
72          *  0(%esp)   |        Argument count        |
73          *            --------------------------------
74          *            |           Undefined          |
75          *            --------------------------------
76          *  TODO: fix stack alignments of atexit, _init, _fini, and
77          *              exit.
78          */
80         /*
81          * The ABI uses a null frame pointer to say when to stop backtracing.
82          */
83         xorl    %ebp, %ebp
85         /*
86          *  Because we are going to align the stack 0mod16 for SSE2,
87          *  We need to gather the argc, argv, and envp pointers before
88          *  moving esp.
89          */
90         popl    %esi               /* Remove argc from the top of the stack */
91         movl    %esp, %ecx         /* Save the argv pointer */
93         /*
94          * Finding envp requires skipping over argc+1 words.
95          */
96         leal    4(%esp, %esi, 4), %ebx
98         /*
99          * environ is initiallly set to point to the same location as envp.
100          * setenv, etc., may change this pointer later.
101          */
102         movl    %ebx, environ
104         /*
105          * Align the stack 0mod16, for SSE2
106          */
107         andl    $0xfffffff0, %esp
109         /*
110          * Push the arguments to main.
111          */
112         pushl   %ebp  /* Padding to maintain 0mod16 alignment */
113         pushl   %ebx  /* Push envp onto the stack */
114         pushl   %ecx  /* Push argv onto the stack */
115         pushl   %esi  /* Push argc back onto the stack */
117         /*
118          * Install the fini section for use at exit.  The C++ static object
119          * destructors are invoked from here.
120          */
121         subl    $12, %esp  /* Padding to maintain 0mod16 alignment */
122         pushl   $_fini
123         call    atexit
124         addl    $16, %esp  /* Pop parameter and padding */
126         /*
127          * Initialize the pthreads library.  We need to do at least a minimal
128          * amount of initialization (e.g., set up gs) to allow thread local
129          * storage references to work.  The default binding of the symbol
130          * is weak, replaced by the real pthread library initialization when
131          * present.
132          */
133         call    __pthread_initialize
134         
135         /*
136          * Install the pthread_shutdown call to be called at exit.  
137          */
138         subl    $12, %esp  /* Padding to maintain 0mod16 alignment */
139         pushl   $__pthread_shutdown
140         call    atexit
141         addl    $16, %esp  /* Pop parameter and padding */
143         /*
144          * Execute the init section before starting main.  The C++ static
145          * object constructors are invoked from here.
146          */
147         call    _init
149         /*
150          * Invoke main, the start of the user's code.
151          */
152         call    main
153         subl    $12, %esp  /* Make space for the return value */
155         /*
156          * Call exit from the C library so atexit gets called, and the
157          * C++ destructors get run. This calls our exit routine below
158          * when it's done.
159          */
160         pushl   %eax
161         call    exit
162         addl    $32, %esp  /* Clean up all the arguments */
164 halt_loop:
165         hlt
166         jmp     halt_loop