1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
|
/*
* Copyright (C) 2003 by Erik Andersen
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU Library General Public License as published by
* the Free Software Foundation; either version 2 of the License, or (at your
* option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License
* for more details.
*
* You should have received a copy of the GNU Library General Public License
* along with this program; see the file COPYING.LIB. If not, see
* <http://www.gnu.org/licenses/>.
*/
#include <features.h>
/* Integer registers. */
#define r0 0
#define r1 1
#define r2 2
#define r3 3
#define r4 4
#define r5 5
#define r6 6
#define r7 7
#define r8 8
#define r9 9
#define r10 10
#define r13 13
#define r31 31
.text
.globl _start
.type _start,%function
.type _init,%function
.type _fini,%function
#ifndef __UCLIBC_CTOR_DTOR__
.weak _init
.weak _fini
#endif
#ifdef L_rcrt1
.type reloc_static_pie,%function
#endif
.type main,%function
.type __uClibc_main,%function
_start:
mr r9,r1 /* Save the stack pointer and pass it to __uClibc_main */
clrrwi r1,r1,4 /* Align stack ptr to 16 bytes */
#ifdef __PIC__
# ifdef HAVE_ASM_PPC_REL16
bcl 20,31,1f
1: mflr r31
addis r31,r31,_GLOBAL_OFFSET_TABLE_-1b@ha
addi r31,r31,_GLOBAL_OFFSET_TABLE_-1b@l
# else
bl _GLOBAL_OFFSET_TABLE_-4@local
mflr r31
# endif
/* in PIC/PIE, plt stubs need r30 to point to the GOT if using secure-plt */
# ifdef PPC_HAS_SECUREPLT
mr 30,31
# endif
#ifdef L_rcrt1
stwu r3, -4(r1) /* Save r3 */
stwu r9, -16(r1) /* Save r9 */
bcl 20,31,2f /* Jump to label 2 */
2: mflr r3 /* Load lr into r3 */
addis r3, r3, _DYNAMIC-2b@ha /* Add high half of _DYNAMIC to r3 */
addi r3,r3,_DYNAMIC-2b@l /* Add low half of _DYNAMIC */
lwz r4, 0(r31) /* load _DYNAMIC from the GOT */
subf r3, r4, r3 /* sub _DYNAMIC@got and it's actual address */
bl reloc_static_pie /* Call reloc_static_pie */
lwzu r9, 0(r1) /* restore r9 */
addi r1, r1, 16 /* update stack pointer */
lwzu r3, 0(r1) /* restore r3 */
addi r1, r1, 4 /* update stack pointer */
li r5, 0 /* zero r5 */
#endif
#endif
/* Set up the small data pointer in r13. */
#ifdef __PIC__
lwz r13,_SDA_BASE_@got(r31)
#else
lis r13,_SDA_BASE_@ha
addi r13,r13,_SDA_BASE_@l
#endif
/* Set up an initial stack frame, and clear the LR. */
li r0,0
stwu r1,-16(r1)
mtlr r0
stw r0,0(r1)
/* find argc from the stack pointer */
lwz r4,0(r9)
/* find argv one word offset from the stack pointer */
addi r5,r9,4
mr r8,r3 /* Pass _dl_fini from ldso or NULL if statically linked */
/* Note: PPC depends on the kernel to zero r3 before */
/* handing over to user space, otherwise static apps */
/* will SEGV during exit() */
/* Ok, now run uClibc's main() -- shouldn't return */
#ifdef __PIC__
lwz r6,_init@got(r31)
lwz r7,_fini@got(r31)
lwz r3,main@got(r31)
b __uClibc_main@plt
#else
lis r6,_init@ha # load top 16 bits
addi r6,r6,_init@l # load bottom 16 bits
lis r7,_fini@ha # load top 16 bits
addi r7,r7,_fini@l # load bottom 16 bits
lis r3,main@ha # load top 16 bits
addi r3,r3,main@l # load bottom 16 bits
b __uClibc_main
#endif
.size _start,.-_start
/* Define a symbol for the first piece of initialized data. */
.data
.globl __data_start
__data_start:
.long 0
.weak data_start
data_start = __data_start
|