1 /* Copyright (c) 2009, 2010, 2011, 2012 ARM Ltd. All rights reserved.
3 Redistribution and use in source and binary forms, with or without
4 modification, are permitted provided that the following conditions
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
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. */
29 /* ANSI concatenation macros. */
30 #define CONCAT(a, b) CONCAT2(a, b)
31 #define CONCAT2(a, b) a ## b
33 #ifdef __USER_LABEL_PREFIX__
34 #define FUNCTION( name ) CONCAT (__USER_LABEL_PREFIX__, name)
36 #error __USER_LABEL_PREFIX is not defined
39 #ifdef HAVE_INITFINI_ARRAY
40 #define _init __libc_init_array
41 #define _fini __libc_fini_array
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. */
52 #if defined(__ILP32__) && __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
55 #elif defined(__ILP32__) && __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
63 /* Help tackle the pointer size difference between ELF64 and ELF32. */
65 #define PTR_REG(n) w##n
67 #define PTR_LOG_SIZE 2
69 #define PTR_REG(n) x##n
71 #define PTR_LOG_SIZE 3
75 .macro FUNC_START name
82 FUNC_START _mainCRTStartup
85 /* Start by setting up a stack */
87 /* Issue Angel SVC to read memory info.
89 ptr to ptr to 4 words to receive data. */
91 mov w0, #AngelSVC_Reason_HeapInfo
94 /* Initialise the stack pointer */
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 */
105 /* Sanity check on the heap base. */
106 ldr x0, [x0] /* get heap_base */
107 tst x0, #0xffffffff00000000
109 /* Exit with 1 if the heap base is not within the 32-bit address
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
118 mov w0, #AngelSVC_Reason_ReportException
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
128 /* Ensure quad-word stack alignment. */
132 /* Setup an initial dummy frame with saved fp=0 and saved lr=0 */
134 stp x29, x29, [sp, #-16]!
137 /* Initialize exception vector table, flatmap, etc. */
138 bl FUNCTION (_cpu_init_hook)
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 */
144 sub x2, x2, x0 /* Third arg: length of block */
147 /* Need to set up standard file handles */
148 bl FUNCTION (initialise_monitor_handles)
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. */
158 /* Fetch and parse the command line. */
159 adr x1, .Lcmdline /* Command line descriptor. */
160 mov w0, #AngelSVC_Reason_GetCmdLine
164 mov x0, #0 /* argc */
165 mov x1, sp /* argv */
166 ldr x2, .Lenvp /* envp */
168 /* Put NULL at end of argv array. */
169 str PTR_REG (0), [x1, #-PTR_SIZE]!
171 /* Skip leading blanks. */
172 .Lnext: ldrb w3, [x8], #1
177 mov w4, #' ' /* Terminator is space. */
179 /* See whether we are scanning a quoted string by checking for
180 opening quote (" or '). */
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. */
187 /* Push arg pointer to argv, and bump argc. */
188 str PTR_REG (8), [x1, #-PTR_SIZE]!
191 /* Find end of arg string. */
194 cmp w4, w3 /* Reached terminator? */
197 /* Terminate the arg string with NUL char. */
202 /* Reverse argv array. */
204 add x3, x1, #0 /* sp = &argv[0] */
205 add x4, x1, w0, uxtw #PTR_LOG_SIZE /* ep = &argv[argc] */
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) */
215 /* Move sp to the 16B boundary below argv. */
221 b FUNCTION (exit) /* Cannot return. */
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):
234 GEN_DWORD __bss_start__
236 GEN_DWORD __bss_end__
238 GEN_DWORD FUNCTION(_fini)
242 GEN_DWORD CommandLine
245 /* Workspace for Angel calls. */
248 /* Data returned by monitor SVC. */
249 #if defined(__ILP32__) && __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
250 .set __stack_base__, StackBase + 4
252 .set __stack_base__, StackBase
254 .global __stack_base__
259 env: .dword 0 /* Dummy environment array */
260 CommandLine: .space 256,0 /* Maximum length of 255 chars handled. */