yuezonghe | 824eb0c | 2024-06-27 02:32:26 -0700 | [diff] [blame^] | 1 | /* Copyright (C) 1991, 1992 Free Software Foundation, Inc. |
| 2 | |
| 3 | This file is part of the GNU C Library. |
| 4 | |
| 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. |
| 9 | |
| 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. |
| 14 | |
| 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 |
| 17 | not, write to the Free Software Foundation, Inc., 675 Mass Ave, |
| 18 | Cambridge, MA 02139, USA. */ |
| 19 | |
| 20 | |
| 21 | /* When we enter this piece of code, the user stack looks like this: |
| 22 | * argc argument counter (integer) |
| 23 | * argv[0] program name (pointer) |
| 24 | * argv[1...N] program args (pointers) |
| 25 | * NULL |
| 26 | * env[0...N] environment variables (pointers) |
| 27 | * NULL |
| 28 | |
| 29 | * When we are done here, we want |
| 30 | * R0=argc |
| 31 | * R1=*argv[0] |
| 32 | * R2=*envp[0] |
| 33 | */ |
| 34 | |
| 35 | #include <features.h> |
| 36 | |
| 37 | #undef USE_GOT |
| 38 | #if defined (__UCLIBC_FORMAT_SHARED_FLAT__) || defined (__UCLIBC_FORMAT_FLAT_SEP_DATA__) |
| 39 | #define USE_GOT |
| 40 | #endif |
| 41 | |
| 42 | #if !(defined L_Scrt1 && defined __UCLIBC_FORMAT_SHARED_FLAT__) |
| 43 | |
| 44 | .text |
| 45 | .align 2 |
| 46 | .global __start; |
| 47 | .type __start,STT_FUNC; |
| 48 | .weak __init; |
| 49 | .weak __fini; |
| 50 | .global ___uClibc_main; |
| 51 | .type ___uClibc_main,STT_FUNC; |
| 52 | |
| 53 | /* Stick in a dummy reference to main(), so that if an application |
| 54 | * is linking when the main() function is in a static library (.a) |
| 55 | * we can be sure that main() actually gets linked in */ |
| 56 | |
| 57 | .type _main,STT_FUNC; |
| 58 | |
| 59 | __start: |
| 60 | |
| 61 | #if defined(__BFIN_FDPIC__) && !defined(L_Scrt1) |
| 62 | /* P0 contains a pointer to the program's load map. */ |
| 63 | call .Lcall; |
| 64 | .Lcall: |
| 65 | R4 = RETS; |
| 66 | SP += -12; |
| 67 | R0.L = .Lcall; |
| 68 | R0.H = .Lcall; |
| 69 | R1.L = __ROFIXUP_LIST__; |
| 70 | R1.H = __ROFIXUP_LIST__; |
| 71 | R2.L = __ROFIXUP_END__; |
| 72 | R2.H = __ROFIXUP_END__; |
| 73 | R1 = R1 - R0; |
| 74 | R1 = R1 + R4; |
| 75 | R2 = R2 - R0; |
| 76 | R2 = R2 + R4; |
| 77 | R0 = P0; |
| 78 | CALL ___self_reloc; |
| 79 | SP += 12; |
| 80 | P3 = R0; |
| 81 | #endif |
| 82 | |
| 83 | /* clear the frame pointer and the L registers. */ |
| 84 | FP = 0; |
| 85 | L0 = 0; |
| 86 | L1 = 0; |
| 87 | L2 = 0; |
| 88 | L3 = 0; |
| 89 | |
| 90 | #ifdef __ID_SHARED_LIB__ |
| 91 | /* We know we have a local copy, so we can avoid the GOT. */ |
| 92 | CALL ___shared_flat_add_library; |
| 93 | #endif |
| 94 | /* Load register R1 (argc) from the stack to its final resting place */ |
| 95 | P0 = SP; |
| 96 | R1 = [P0++]; |
| 97 | |
| 98 | /* Copy argv pointer into R2 -- which its final resting place */ |
| 99 | R2 = P0; |
| 100 | |
| 101 | SP += -28; |
| 102 | |
| 103 | #ifndef __BFIN_FDPIC__ |
| 104 | R7 = 0; |
| 105 | #endif |
| 106 | /* Pass highest stack pointer to the app. */ |
| 107 | [SP + 24] = P2; |
| 108 | /* Store the pointer to ld.so's fini that we got in P1. */ |
| 109 | [SP + 20] = R7; |
| 110 | |
| 111 | /* Ok, now run uClibc's main() -- shouldn't return */ |
| 112 | #if (defined L_crt1 || defined L_Scrt1) && defined __UCLIBC_CTOR_DTOR__ |
| 113 | |
| 114 | #ifdef __BFIN_FDPIC__ |
| 115 | R3 = [P3 + __init@FUNCDESC_GOT17M4]; |
| 116 | #elif defined USE_GOT |
| 117 | R3 = [P5 + ___shared_flat_init@GOT]; |
| 118 | #else |
| 119 | R3.H = __init; |
| 120 | R3.L = __init; |
| 121 | #endif |
| 122 | [SP+12] = R3; |
| 123 | |
| 124 | |
| 125 | #ifdef __BFIN_FDPIC__ |
| 126 | R3 = [P3 + __fini@FUNCDESC_GOT17M4]; |
| 127 | #elif defined USE_GOT |
| 128 | R3 = [P5 + ___shared_flat_fini@GOT]; |
| 129 | #else |
| 130 | R3.H = __fini; |
| 131 | R3.L = __fini; |
| 132 | #endif |
| 133 | [SP+16] = R3; |
| 134 | #else /* no ctor/dtor handling */ |
| 135 | R3 = 0; |
| 136 | [SP + 12] = R3; |
| 137 | [SP + 16] = R3; |
| 138 | #endif |
| 139 | |
| 140 | #ifdef __BFIN_FDPIC__ |
| 141 | R0 = [P3 + _main@FUNCDESC_GOT17M4]; |
| 142 | #elif defined USE_GOT |
| 143 | R0 = [P5 + _main@GOT]; |
| 144 | #else |
| 145 | R0.H = _main; |
| 146 | R0.L = _main; |
| 147 | #endif |
| 148 | #ifdef USE_GOT |
| 149 | P0 = [P5 + ___uClibc_main@GOT]; |
| 150 | jump (P0) |
| 151 | #else |
| 152 | jump.l ___uClibc_main; |
| 153 | #endif |
| 154 | |
| 155 | #else |
| 156 | .text |
| 157 | .global lib_main |
| 158 | .hidden lib_main |
| 159 | .type lib_main,@function |
| 160 | lib_main: |
| 161 | RETS = [SP++]; |
| 162 | /* We know we have a local copy, so we can avoid the GOT. */ |
| 163 | JUMP.L ___shared_flat_add_library; |
| 164 | |
| 165 | .hidden _current_shared_library_p5_offset_ |
| 166 | #endif |
| 167 | |
| 168 | .section .note.GNU-stack,"",%progbits |