1/* Startup code compliant to the ELF Mips ABI. 2 Copyright (C) 1995, 1997, 2000, 2001, 2002, 2003, 2004 3 Free Software Foundation, Inc. 4 This file is part of the GNU C Library. 5 6 The GNU C Library is free software; you can redistribute it and/or 7 modify it under the terms of the GNU Lesser General Public 8 License as published by the Free Software Foundation; either 9 version 2.1 of the License, or (at your option) any later version. 10 11 In addition to the permissions in the GNU Lesser General Public 12 License, the Free Software Foundation gives you unlimited 13 permission to link the compiled version of this file with other 14 programs, and to distribute those programs without any restriction 15 coming from the use of this file. (The GNU Lesser General Public 16 License restrictions do apply in other respects; for example, they 17 cover modification of the file, and distribution when not linked 18 into another program.) 19 20 Note that people who make modified versions of this file are not 21 obligated to grant this special exception for their modified 22 versions; it is their choice whether to do so. The GNU Lesser 23 General Public License gives permission to release a modified 24 version without this exception; this exception also makes it 25 possible to release a modified version which carries forward this 26 exception. 27 28 The GNU C Library is distributed in the hope that it will be useful, 29 but WITHOUT ANY WARRANTY; without even the implied warranty of 30 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 31 Lesser General Public License for more details. 32 33 You should have received a copy of the GNU Lesser General Public 34 License along with the GNU C Library; if not, see 35 <http://www.gnu.org/licenses/>. */ 36 37 38#include <sys/regdef.h> 39#include <sys/asm.h> 40#include <features.h> 41 42 43/* This is the canonical entry point, usually the first thing in the text 44 segment. The SVR4/Mips ABI (pages 3-31, 3-32) says that when the entry 45 point runs, most registers' values are unspecified, except for: 46 47 v0 ($2) Contains a function pointer to be registered with `atexit'. 48 This is how the dynamic linker arranges to have DT_FINI 49 functions called for shared libraries that have been loaded 50 before this code runs. 51 52 sp ($29) The stack contains the arguments and environment: 53 0(%esp) argc 54 4(%esp) argv[0] 55 ... 56 (4*argc)(%esp) NULL 57 (4*(argc+1))(%esp) envp[0] 58 ... 59 NULL 60 ra ($31) The return address register is set to zero so that programs 61 that search backword through stack frames recognize the last 62 stack frame. 63*/ 64 65 66/* We need to call: 67 __uClibc_main (int (*main) (int, char **, char **), int argc, 68 char **argv, void (*init) (void), void (*fini) (void), 69 void (*rtld_fini) (void), void *stack_end) 70*/ 71 72.text 73 .globl __start 74 .type __start,@function 75 .type _init,@function 76 .type _fini,@function 77#ifndef __UCLIBC_CTOR_DTOR__ 78 .weak _init 79 .weak _fini 80#endif 81#ifdef L_rcrt1 82 .type reloc_static_pie,@function 83 .hidden .L0 84#endif 85 .type main,@function 86 .type __uClibc_main,@function 87 .ent __start 88 89__start: 90#ifdef __PIC__ 91 SETUP_GPX($0) 92 SETUP_GPX64($25,$0) 93#else 94 PTR_LA $28, _gp /* Setup GP correctly if we're non-PIC. */ 95 move $31, $0 96#endif 97#ifdef L_rcrt1 98 PTR_LA $4, _DYNAMIC /* Place _DYNAMIC into the GOT */ 99 REG_S $4, -0x7ff0($28) /* offset to GOT stolen from dl-startup */ 100 jal .L0 /* Get the current $pc address */ 101.L0: 102 PTR_SUBU $4, $31, $25 /* Calculate load addr */ 103 move $31, $0 /* Clear ra */ 104 and $29, -2 * SZREG /* Ensure stack is aligned */ 105 PTR_ADDIU $29, (-2 * SZREG) /* Allocate 2 register spaces on stack */ 106 REG_S $2, SZREG($29) /* Store atexit in case it exists */ 107 PTR_LA $5, reloc_static_pie /* function calls before relocation 108 don't work unless we set $t9 manually */ 109 PTR_ADDU $25, $4, $5 /* store reloc_static_pie in $t9 */ 110 jalr $25 /* call reloc_static_pie */ 111 nop /* delay slot, just in case */ 112 REG_L $2, SZREG($29) /* cleanup stack */ 113 PTR_ADDIU $29, $29, (2 * SZREG) 114 115#endif 116 117 PTR_LA $4, main /* main */ 118 PTR_L $5, 0($29) /* argc */ 119 PTR_ADDIU $6, $29, PTRSIZE /* argv */ 120 121 /* Allocate space on the stack for seven arguments and 122 * make sure the stack is aligned to double words (8 bytes) */ 123 124 and $29, -2 * SZREG 125 126#if _MIPS_SIM == _MIPS_SIM_ABI32 127 PTR_SUBIU $29, 32 128#endif 129 PTR_LA $7, _init /* init */ 130 PTR_LA $8, _fini 131#if _MIPS_SIM == _MIPS_SIM_ABI32 132 PTR_S $8, 16($29) /* fini */ 133 PTR_S $2, 20($29) /* rtld_fini */ 134 PTR_S $29, 24($29) /* stack_end */ 135#else 136 move $9, $2 /* rtld_fini */ 137 move $10, $29 /* stack_end */ 138#endif 139 jal __uClibc_main 140hlt: 141 /* Crash if somehow `__uClibc_main' returns anyway. */ 142 b hlt 143.size __start,.-__start 144.end __start 145 146/* Define a symbol for the first piece of initialized data. */ 147 .data 148 .globl __data_start 149__data_start: 150 .long 0 151 .weak data_start 152 data_start = __data_start 153 154