]> sourceware.org Git - newlib-cygwin.git/blob - libgloss/aarch64/crt0.S
cygwin: export __getpagesize
[newlib-cygwin.git] / libgloss / aarch64 / crt0.S
1 /* Copyright (c) 2009, 2010, 2011, 2012 ARM Ltd. All rights reserved.
2
3 Redistribution and use in source and binary forms, with or without
4 modification, are permitted provided that the following conditions
5 are met:
6 1. Redistributions of source code must retain the above copyright
7 notice, this list of conditions and the following disclaimer.
8 2. Redistributions in binary form must reproduce the above copyright
9 notice, this list of conditions and the following disclaimer in the
10 documentation and/or other materials provided with the distribution.
11 3. The name of the company may not be used to endorse or promote
12 products derived from this software without specific prior written
13 permission.
14
15 THIS SOFTWARE IS PROVIDED BY ARM LTD ``AS IS'' AND ANY EXPRESS OR IMPLIED
16 WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
17 MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
18 IN NO EVENT SHALL ARM LTD BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
19 SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
20 TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
21 PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
22 LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
23 NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
24 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */
25
26 #include "newlib.h"
27 #include "svc.h"
28
29 /* ANSI concatenation macros. */
30 #define CONCAT(a, b) CONCAT2(a, b)
31 #define CONCAT2(a, b) a ## b
32
33 #ifdef __USER_LABEL_PREFIX__
34 #define FUNCTION( name ) CONCAT (__USER_LABEL_PREFIX__, name)
35 #else
36 #error __USER_LABEL_PREFIX is not defined
37 #endif
38
39 #ifdef HAVE_INITFINI_ARRAY
40 #define _init __libc_init_array
41 #define _fini __libc_fini_array
42 #endif
43
44 /* In ELF64, the large addressing model is used and R_AARCH64_ABS64
45 reloc is generated to relocate a 64-bit address. Since 64-bit
46 relocation is not available in ELF32, in order to have
47 a single code path for both ELF64 and ELF32 classes, we synthesize
48 a 64-bit relocation by using R_AARCH64_P32_ABS32 on one of the two
49 .word directives, depending on the endianness. */
50
51 .macro GEN_DWORD name
52 #if defined(__ILP32__) && __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
53 .word \name
54 .word 0
55 #elif defined(__ILP32__) && __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
56 .word 0
57 .word \name
58 #else
59 .dword \name
60 #endif
61 .endm
62
63 /* Help tackle the pointer size difference between ELF64 and ELF32. */
64 #ifdef __ILP32__
65 #define PTR_REG(n) w##n
66 #define PTR_SIZE 4
67 #define PTR_LOG_SIZE 2
68 #else
69 #define PTR_REG(n) x##n
70 #define PTR_SIZE 8
71 #define PTR_LOG_SIZE 3
72 #endif
73
74 .text
75 .macro FUNC_START name
76 .global \name
77 \name:
78 .endm
79
80 .align 2
81
82 FUNC_START _mainCRTStartup
83 FUNC_START _start
84
85 /* Start by setting up a stack */
86
87 /* Issue Angel SVC to read memory info.
88
89 ptr to ptr to 4 words to receive data. */
90 adr x1, .LC0
91 mov w0, #AngelSVC_Reason_HeapInfo
92 AngelSVCAsm AngelSVC
93
94 /* Initialise the stack pointer */
95
96 /* We currently choose to use the heap_limit field rather than
97 stack_base because the AEM validation model
98 returns sane values in the heap fields, but 0 in the stack
99 fields. Note on the VE AEM model it is necessary to pass
100 command line options to the AEM in order to define the values
101 exposed here in the HeapInfo Angel call. */
102 ldr x0, .LC0 /* point at returned values */
103 ldr x1, [x0, #8] /* get heap_limit */
104 #ifdef __ILP32__
105 /* Sanity check on the heap base. */
106 ldr x0, [x0] /* get heap_base */
107 tst x0, #0xffffffff00000000
108 beq 1f
109 /* Exit with 1 if the heap base is not within the 32-bit address
110 space. */
111 mov x0, ADP_Stopped_ApplicationExit & 0xff
112 movk x0, ADP_Stopped_ApplicationExit >> 16, lsl #16
113 adrp x1, HeapBase /* Reuse to construct the parameter block. */
114 add x1, x1, #:lo12:HeapBase
115 str x0, [x1]
116 mov x0, 1
117 str x0, [x1, #8]
118 mov w0, #AngelSVC_Reason_ReportException
119 AngelSVCAsm AngelSVC
120 1:
121 /* For the sake of safety, set the stack base to the top end of
122 the 32-bit address space if the returned value from the
123 Angel API call is larger than or equal to 4 GiB. */
124 tst x1, #0xffffffff00000000
125 csinv w1, w1, wzr, eq
126 #endif
127
128 /* Ensure quad-word stack alignment. */
129 and x0, x1, #~15
130 mov sp, x0
131
132 /* Setup an initial dummy frame with saved fp=0 and saved lr=0 */
133 mov x29, 0
134 stp x29, x29, [sp, #-16]!
135 mov x29, sp
136
137 /* Initialize exception vector table, flatmap, etc. */
138 bl FUNCTION (_cpu_init_hook)
139
140 /* Zero the memory in the .bss section. */
141 ldr x0, .LC1 /* First arg: start of memory block */
142 mov w1, #0 /* Second arg: fill value */
143 ldr x2, .LC2
144 sub x2, x2, x0 /* Third arg: length of block */
145 bl FUNCTION (memset)
146
147 /* Need to set up standard file handles */
148 bl FUNCTION (initialise_monitor_handles)
149
150 /* .init and .fini sections are used to create constructors
151 and destructors. Here we call the _init function and arrange
152 for _fini to be called at program exit. */
153 ldr x0, .Lfini
154 bl FUNCTION (atexit)
155
156 bl FUNCTION (_init)
157
158 /* Fetch and parse the command line. */
159 adr x1, .Lcmdline /* Command line descriptor. */
160 mov w0, #AngelSVC_Reason_GetCmdLine
161 AngelSVCAsm AngelSVC
162 ldr x8, .Lcmdline
163
164 mov x0, #0 /* argc */
165 mov x1, sp /* argv */
166 ldr x2, .Lenvp /* envp */
167
168 /* Put NULL at end of argv array. */
169 str PTR_REG (0), [x1, #-PTR_SIZE]!
170
171 /* Skip leading blanks. */
172 .Lnext: ldrb w3, [x8], #1
173 cbz w3, .Lendstr
174 cmp w3, #' '
175 b.eq .Lnext
176
177 mov w4, #' ' /* Terminator is space. */
178
179 /* See whether we are scanning a quoted string by checking for
180 opening quote (" or '). */
181 subs w9, w3, #'\"'
182 sub x8, x8, #1 /* Backup if no match. */
183 ccmp w9, #('\'' - '\"'), 0x4 /* FLG_Z */, ne
184 csel w4, w3, w4, eq /* Terminator = quote if match. */
185 cinc x8, x8, eq
186
187 /* Push arg pointer to argv, and bump argc. */
188 str PTR_REG (8), [x1, #-PTR_SIZE]!
189 add x0, x0, #1
190
191 /* Find end of arg string. */
192 1: ldrb w3, [x8], #1
193 cbz w3, .Lendstr
194 cmp w4, w3 /* Reached terminator? */
195 b.ne 1b
196
197 /* Terminate the arg string with NUL char. */
198 mov w4, #0
199 strb w4, [x8, #-1]
200 b .Lnext
201
202 /* Reverse argv array. */
203 .Lendstr:
204 add x3, x1, #0 /* sp = &argv[0] */
205 add x4, x1, w0, uxtw #PTR_LOG_SIZE /* ep = &argv[argc] */
206 cmp x4, x3
207 b.lo 2f
208 1: ldr PTR_REG (5), [x4, #-PTR_SIZE] /* PTR_REG (5) = ep[-1] */
209 ldr PTR_REG (6), [x3] /* PTR_REG (6) = *sp */
210 str PTR_REG (6), [x4, #-PTR_SIZE]! /* *--ep = PTR_REG (6) */
211 str PTR_REG (5), [x3], #PTR_SIZE /* *sp++ = PTR_REG (5) */
212 cmp x4, x3
213 b.hi 1b
214 2:
215 /* Move sp to the 16B boundary below argv. */
216 and x4, x1, ~15
217 mov sp, x4
218
219 bl FUNCTION (main)
220
221 b FUNCTION (exit) /* Cannot return. */
222
223 /* Function initializing exception vector table, flatmap, etc.
224 Declared as weak symbol so that user can override this definition
225 by linking in their own version of the function. */
226 .weak FUNCTION (_cpu_init_hook)
227 FUNCTION (_cpu_init_hook):
228 ret
229
230 .align 3
231 .LC0:
232 GEN_DWORD HeapBase
233 .LC1:
234 GEN_DWORD __bss_start__
235 .LC2:
236 GEN_DWORD __bss_end__
237 .Lfini:
238 GEN_DWORD FUNCTION(_fini)
239 .Lenvp:
240 GEN_DWORD env
241 .Lcmdline:
242 GEN_DWORD CommandLine
243 .dword 255
244
245 /* Workspace for Angel calls. */
246 .data
247 .align 3
248 /* Data returned by monitor SVC. */
249 #if defined(__ILP32__) && __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
250 .set __stack_base__, StackBase + 4
251 #else
252 .set __stack_base__, StackBase
253 #endif
254 .global __stack_base__
255 HeapBase: .dword 0
256 HeapLimit: .dword 0
257 StackBase: .dword 0
258 StackLimit: .dword 0
259 env: .dword 0 /* Dummy environment array */
260 CommandLine: .space 256,0 /* Maximum length of 255 chars handled. */
This page took 0.047829 seconds and 5 git commands to generate.