]> rtime.felk.cvut.cz Git - l4.git/blob - l4/pkg/l4re-core/uclibc/lib/contrib/uclibc/libc/sysdeps/linux/avr32/crt1.S
Update
[l4.git] / l4 / pkg / l4re-core / uclibc / lib / contrib / uclibc / libc / sysdeps / linux / avr32 / crt1.S
1 /*
2  * Copyright (C) 2004-2007 Atmel Corporation
3  *
4  * This file is subject to the terms and conditions of the GNU Lesser General
5  * Public License.  See the file "COPYING.LIB" in the main directory of this
6  * archive for more details.
7  *
8  * When we enter _start, the stack looks like this:
9  *      argc            argument counter
10  *      argv[0]         pointer to program name
11  *      argv[1..argc-1] pointers to program args
12  *      NULL
13  *      env[0..N]       pointers to environment variables
14  *      NULL
15  *
16  * r12 contains a function pointer to be registered with `atexit'.
17  * This is how the dynamic linker arranges to have DT_FINI functions
18  * called for shared libraries that have been loaded before this
19  * code runs.
20  *
21  * We're going to call the following function:
22  * __uClibc_main(int (*main)(int, char **, char **), int argc,
23  *               char **argv, void (*app_init)(void), void (*app_fini)(void),
24  *               void (*rtld_fini)(void), void *stack_end)
25  *
26  * So we need to set up things as follows:
27  *      r12 = address of main
28  *      r11 = argc
29  *      r10 = &argv[0]
30  *      r9  = address of _init
31  *      r8  = address of _fini
32  *      sp[0] = whatever we got passed in r12
33  */
34
35 #include <features.h>
36
37         .text
38         .global _start
39         .type   _start, @function
40 _start:
41         /* Clear the frame pointer and link register since this is the outermost frame.  */
42         mov     r7, 0
43         mov     lr, 0
44
45         ld.w    r11, sp++               /* argc         */
46         mov     r10, sp                 /* &argv[0]     */
47
48         st.w    --sp, r10               /* stack_end */
49         st.w    --sp, r12               /* rtld_fini */
50
51 #ifdef __PIC__
52         lddpc   r6, .L_GOT
53 .L_RGOT:
54         rsub    r6, pc
55         lda.w   r9, _init
56         lda.w   r8, _fini
57         lda.w   r12, main
58
59         /* Ok, now run uClibc's main() -- should not return */
60         call    __uClibc_main
61
62         .align  2
63 .L_GOT:
64         .long   .L_RGOT - _GLOBAL_OFFSET_TABLE_
65 #else
66         lddpc   r9, __init_addr         /* app_init */
67         lddpc   r8, __fini_addr         /* app_fini */
68         lddpc   r12, __main_addr        /* main */
69
70         /* Ok, now run uClibc's main() -- should not return */
71         lddpc   pc, ___uClibc_main_addr
72
73         .align  2
74 __init_addr:
75         .long   _init
76 __fini_addr:
77         .long   _fini
78 __main_addr:
79         .long   main
80 ___uClibc_main_addr:
81         .long   __uClibc_main
82 #endif
83         .size   _start, . - _start
84
85         /*
86          * The LSB says we need this.
87          */
88         .section ".note.ABI-tag", "a"
89         .align  4
90         .long   2f - 1f         /* namesz */
91         .long   4f - 3f         /* descsz */
92         .long   1               /* type   */
93 1:      .asciz  "GNU"           /* name */
94 2:      .align  4
95 3:      .long   0               /* Linux executable */
96         .long   2,6,0           /* Earliest compatible kernel */
97 4:      .align  4