1/* Copyright (C) 1991, 1992, 2003, 2004 Free Software Foundation, Inc. 2This file is part of the GNU C Library. 3 4The GNU C Library is free software; you can redistribute it and/or 5modify it under the terms of the GNU Lesser General Public License as 6published by the Free Software Foundation; either version 2.1 of the 7License, or (at your option) any later version. 8 9The GNU C Library is distributed in the hope that it will be useful, 10but WITHOUT ANY WARRANTY; without even the implied warranty of 11MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12Library General Public License for more details. 13 14In addition to the permissions in the GNU Lesser General Public 15License, the Free Software Foundation gives you unlimited 16permission to link the compiled version of this file with other 17programs, and to distribute those programs without any restriction 18coming from the use of this file. (The GNU Lesser General Public 19License restrictions do apply in other respects; for example, they 20cover modification of the file, and distribution when not linked 21into another program.) 22 23You should have received a copy of the GNU Lesser General Public 24License along with the GNU C Library; see the file COPYING.LIB. If 25not, see <http://www.gnu.org/licenses/>. */ 26 27 28/* Based on ../i386/crt0.S and newlib's libgloss/frv/crt0.S */ 29 30/* 31 When we enter this piece of code, the program stack looks like this: 32 argc argument counter (integer) 33 argv[0] program name (pointer) 34 argv[1...N] program args (pointers) 35 argv[argc-1] end of args (integer) 36 NULL 37 env[0...N] environment variables (pointers) 38 NULL 39 40 Also, GR16 holds a pointer to a memory map. */ 41 42#include <features.h> 43 44 .text 45 .global _start 46 .type _start,%function 47 .weak _init 48 .weak _fini 49 .type __uClibc_main,%function 50 51_start: 52 /* Make sure the stack pointer is properly aligned. Save the 53 original value in gr21 such that we can get to arguments and 54 such from there. */ 55 mov.p sp, gr21 56 andi sp, #-8, sp 57 /* At program start-up, gr16 contains a pointer to a memory 58 map, that we use to relocate addresses. */ 59 call .Lcall 60.Lcall: 61 movsg lr, gr4 62 sethi.p #gprelhi(.Lcall), gr5 63 setlo #gprello(.Lcall), gr5 64 sub.p gr4, gr5, gr4 65 /* gr4 now holds the _gp address. */ 66 67 mov gr16, gr8 68 sethi.p #gprelhi(__ROFIXUP_LIST__), gr9 69 sethi #gprelhi(__ROFIXUP_END__), gr10 70 setlo.p #gprello(__ROFIXUP_LIST__), gr9 71 setlo #gprello(__ROFIXUP_END__), gr10 72 add.p gr9, gr4, gr9 73 add gr10, gr4, gr10 74 call __self_reloc 75 mov.p gr8, gr17 76 mov gr8, gr15 77 /* gr17 now holds the self-relocated _GLOBAL_OFFSET_TABLE_ 78 address, because the linker added its unrelocated address as 79 the last entry in the ROFIXUP list, and __self_reloc returns 80 the last entry, relocated. */ 81 82 /* Prepare arguments for uClibc main. */ 83 ld @(gr21, gr0), gr8 84 slli gr8, #2, gr10 85 add gr21, gr10, gr10 86 addi.p gr21, #4, gr9 87 addi gr10, #8, gr10 88 89 /* Set up an invalid (NULL return address, NULL frame pointer) 90 callers stack frame so anybody unrolling the stack knows where 91 to stop */ 92 mov gr0, fp 93 movgs gr0, lr 94 95#if (defined L_crt1 || defined L_Scrt1) && defined __UCLIBC_CTOR_DTOR__ 96 /* Pass .init and .fini arguments to __uClibc_start_main(). */ 97 sethi.p #gotfuncdeschi(_init), gr11 98 sethi #gotfuncdeschi(_fini), gr12 99 setlo.p #gotfuncdesclo(_init), gr11 100 setlo #gotfuncdesclo(_fini), gr12 101 ld.p @(gr11, gr17), gr11 102 mov gr17, gr15 103 ld.p @(gr12, gr17), gr12 104 call __uClibc_main 105#else 106 mov.p gr17, gr15 107 call __uClibc_main 108#endif 109 110 /* Crash if somehow `exit' returns anyways. */ 111 jmpl @(gr0,gr0) 112.size _start,.-_start 113 114/* Define a symbol for the first piece of initialized data. */ 115 .data 116 .globl __data_start 117__data_start: 118 .long 0 119 .weak data_start 120 data_start = __data_start 121 122