Update.
[glibc.git] / sysdeps / cris / elf / start.S
blobeef5c7543b910107d2589cf19b31304b1e63c219
1 /* Startup code compliant to the ELF CRIS ABI (to-be-written).
2    Copyright (C) 2001 Free Software Foundation, Inc.
3    This file is part of the GNU C Library.
5    The GNU C Library is free software; you can redistribute it and/or
6    modify it under the terms of the GNU Library General Public License as
7    published by the Free Software Foundation; either version 2 of the
8    License, or (at your option) any later version.
10    The GNU C Library is distributed in the hope that it will be useful,
11    but WITHOUT ANY WARRANTY; without even the implied warranty of
12    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13    Library General Public License for more details.
15    You should have received a copy of the GNU Library General Public
16    License along with the GNU C Library; see the file COPYING.LIB.  If not,
17    write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18    Boston, MA 02111-1307, USA.  */
20 #include <sysdep.h>
22 /* This is the canonical entry point, usually the first thing in the text
23    segment.  When the entry point runs, most registers' values are
24    unspecified, except for:
26    R10          Contains a function pointer to be registered with `atexit'.
27                 This is how the dynamic linker arranges to have DT_FINI
28                 functions called for shared libraries that have been loaded
29                 before this code runs.
31    SP           The stack contains the arguments and environment:
32                 [SP]                    argc
33                 [SP+4]                  argv[0]
34                 ...
35                 [SP+4*argc]             NULL
36                 [SP+4*(argc+1)]         envp[0]
37                 ...
38                                         NULL
41         .syntax no_register_prefix
43         .text
44         .globl  _start
45         type _start,@function
46 _start:
47         /* Clear the frame pointer, to mark the outermost frame.  */
48         moveq   0,r8
50         /* Move the shared library termination function to the right place
51            for __libc_main.  */
52         move.d  r10,r9
54         /* Extract the arguments as encoded on the stack and set up the
55            arguments for `main': argc, argv.  envp will be determined
56            later in __libc_start_main.  */
58         /* Get the argument count.  */
59         move.d  [sp],r11
61         /* Store the stack pointer as end of stack.  We overwrite
62            the incoming argc.  */
63         move.d  sp,[sp]
65         /* The argument vector starts just after the argument count.  */
66         move.d  sp,r12
67         addq    4,r12
69         /* There are seven arguments to __libc_start_main:
70            r10:  main - Address of it.
71            r11:  argc
72            r12:  argv
73            r13:  init - Function to call.
75            [sp]: fini - Function to register with atexit.
76            [sp+4]: rtld_fini - Another function to register with atexit.
77            [sp+8]: stack_end - Top of stack (actually same as argv).
79            The last two are passed on stack.  */
81         /* Store the fini function coming from the dynamic loader.  */
82         push    r9
84         /* Get the addresses of our own entry points to `.fini' and
85            `.init'.  */
87 #ifdef __PIC__
88         /* If for some reason this program is compiled as PIC, set up R0.  */
89         move.d  pc,r0
90         sub.d   .:GOTOFF,r0
92         move.d  _init:PLTG,r13
93         add.d   r0,r13
94         move.d  _fini:PLTG,r9
95         add.d   r0,r9
96         move.d  main:PLTG,r10
97         add.d   r0,r10
98 #else
99         move.d  _init,r13
100         move.d  _fini,r9
101         move.d  main,r10
102 #endif
103         push    r9
105         /* Call the user's main function, and exit with its value.  But
106            let the libc call main.  */
107         PLTCALL (__libc_start_main)
109         /* Crash if somehow `exit' does return.  We have at least 8192
110            invalid addresses to choose from.  */
111         test.d  [6502]
113         /* Stop the unstoppable.  */
115         ba      0b
116         nop
118 /* Define a symbol for the first piece of initialized data.  */
119         .data
120         .globl __data_start
121 __data_start:
122         .long   0
123         .weak   data_start
124         data_start = __data_start