5 /* ANSI concatenation macros. */
6 #define CONCAT(a, b) CONCAT2(a, b)
7 #define CONCAT2(a, b) a ## b
9 #ifdef __USER_LABEL_PREFIX__
10 #define FUNCTION( name ) CONCAT (__USER_LABEL_PREFIX__, name)
12 #error __USER_LABEL_PREFIX is not defined
15 #ifdef _HAVE_INITFINI_ARRAY
16 #define _init __libc_init_array
17 #define _fini __libc_fini_array
20 #if defined(__ARM_EABI__) && defined(__thumb__) && !defined(__thumb2__)
21 /* For Thumb1 we need to force the architecture to be sure that we get the
22 correct attributes on the object file; otherwise the assembler will get
23 confused and mark the object as being v6T2. */
24 #if defined(__ARM_ARCH_4T__)
26 #elif defined(__ARM_ARCH_5T__) || defined(__ARM_ARCH_5TE__)
27 /* Nothing in this object requires higher than v5. */
29 #elif defined(__ARM_ARCH_6__) || defined(__ARM_ARCH_6J__) \
30 || defined(__ARM_ARCH_6K__) || defined(__ARM_ARCH_6Z__) \
31 || defined(__ARM_ARCH_6ZK__)
32 /* Nothing in this object requires higher than v6. */
34 #elif defined(__ARM_ARCH_6M__)
35 #ifdef ARM_RDP_MONITOR
36 /* Object file uses SVC, so mark as v6s-m. */
44 /* .text is used instead of .section .text so it works with arm-aout too. */
49 .macro FUNC_START name
51 .type \name, %function
57 .macro FUNC_START name
59 .type \name, %function
64 /* Annotation for EABI unwinding tables. */
66 #if defined(__ELF__) && !defined(__USING_SJLJ_EXCEPTIONS__)
72 #if defined(__ELF__) && !defined(__USING_SJLJ_EXCEPTIONS__)
73 /* Protect against unhandled exceptions. */
79 .macro indirect_call reg
80 #ifdef HAVE_CALL_INDIRECT
88 /* For armv4t and newer, toolchains will transparently convert
89 'bx lr' to 'mov pc, lr' if needed. GCC has deprecated support
90 for anything older than armv4t, but this should handle that
91 corner case in case anyone needs it anyway. */
93 #if __ARM_ARCH <= 4 && __ARM_ARCH_ISA_THUMB == 0
102 /******************************************************************************
103 * User mode only: This routine makes default target specific Stack
104 * +-----+ <- SL_sys, Pointer initialization for different processor modes:
105 * | | SL_usr FIQ, Abort, IRQ, Undefined, Supervisor, System (User)
106 * | SYS | and setups a default Stack Limit in-case the code has
107 * | USR | -=0x10000 been compiled with "-mapcs-stack-check" for FIQ and
108 * | | System (User) modes.
110 * +-----+ <- initial SP,
111 * becomes SP_sys Hard-wiring SL value is not ideal, since there is
112 * and SL_usr currently no support for checking that the heap and
113 * stack have not collided, or that this default 64k is
114 * All modes: is enough for the program being executed. However,
115 * +-----+ <- SL_sys, it ensures that this simple crt0 world will not
116 * | | SL_usr immediately cause an overflow event.
118 * | USR | -=0x10000 We go through all execution modes and set up SP
119 * | | for each of them.
122 * | SVC | -= 0x8000 - This code will not work as intended if the system
123 * | | starts in secure mode. In particular the methods
124 * +-----+ <- SP_svc of getting in and out of secure state are not as
125 * | | simple as writing to the CPSR mode bits.
126 * | IRQ | -= 0x2000 - Mode switch via CPSR is not allowed once in
127 * | | non-privileged mode or in hypervisor mode, so we
128 * ^ +-----+ <- SP_und take care not to enter "User" or "Hypervisor" mode
129 * s | | to set up its SP, and also skip most operations if
130 * t | UND | -= 0x1000 already in these modes.
131 * a | | Input parameters:
132 * c +-----+ <- SP_und - sp - Initialized SP
133 * k | | - r2 - May contain SL value from semihosting
134 * | ABT | -= 0x1000 SYS_HEAPINFO call
135 * g | | Scratch registers:
136 * r +-----+ <- SP_abt, - r1 - new value of CPSR
137 * o | | SL_fiq - r2 - intermediate value (in standalone mode)
138 * w | FIQ | -= 0x1000 - r3 - new SP value
139 * t | | - r4 - save/restore CPSR on entry/exit
140 * h +-----+ <- initial SP,
141 * becomes SP_fiq Declared as "weak" so that user can write and use
142 * his own implementation if current doesn't fit.
144 ******************************************************************************/
146 FUNC_START _stack_init
147 .weak FUNCTION (_stack_init)
150 /* M profile doesn't have CPSR register. */
151 #if (__ARM_ARCH_PROFILE != 'M')
152 /* Following code is compatible for both ARM and Thumb ISA. */
154 mov r3, sp /* Save input SP value. */
155 ands r1, r4, #(CPSR_M_MASK)
157 cmp r1, #(CPSR_M_HYP)
160 /* FIQ mode, interrupts disabled. */
161 mov r1, #(CPSR_M_FIQ|CPSR_M_32BIT|CPSR_I_MASK|CPSR_F_MASK)
164 sub sl, sp, #0x1000 /* FIQ mode has its own SL. */
166 /* Abort mode, interrupts disabled. */
168 mov r1, #(CPSR_M_ABT|CPSR_M_32BIT|CPSR_I_MASK|CPSR_F_MASK)
173 /* Undefined mode, interrupts disabled. */
174 mov r1, #(CPSR_M_UND|CPSR_M_32BIT|CPSR_I_MASK|CPSR_F_MASK)
179 /* IRQ mode, interrupts disabled. */
180 mov r1, #(CPSR_M_IRQ|CPSR_M_32BIT|CPSR_I_MASK|CPSR_F_MASK)
185 /* Supervisory mode, interrupts disabled. */
186 mov r1, #(CPSR_M_SVR|CPSR_M_32BIT|CPSR_I_MASK|CPSR_F_MASK)
190 sub r3, r3, #0x8000 /* Min size 32k. */
191 bic r3, r3, #0x00FF /* Align with current 64k block. */
195 /* System (shares regs with User) mode, interrupts disabled. */
196 mov r1, #(CPSR_M_SYS|CPSR_M_32BIT|CPSR_I_MASK|CPSR_F_MASK)
200 /* Keep this for ARMv3, but GCC actually dropped it. */
201 /* Move value into user mode SP without changing modes, */
202 /* via '^' form of ldm. */
207 /* Back to original mode, presumably SVC, with diabled FIQ/IRQ. */
208 orr r4, r4, #(CPSR_I_MASK|CPSR_F_MASK)
214 /* Set SL register. */
215 #if defined (ARM_RDI_MONITOR) /* semihosting */
218 /* Allow slop for stack overflow handling and small frames. */
228 #else /* standalone */
229 /* r3 contains SP for System/User mode. Set SL = SP - 0x10000. */
236 /* Still assumes 256bytes below SL. */
237 sub sl, r3, #64 << 10
245 /*******************************************************************************
246 * Main library startup code.
247 *******************************************************************************/
249 FUNC_START _mainCRTStartup
253 /* Start by setting up a stack. */
254 #ifdef ARM_RDP_MONITOR
255 /* Issue Demon SWI to read stack info. */
256 swi SWI_GetEnv /* Returns command line in r0. */
257 mov sp,r1 /* and the highest memory address in r1. */
259 /* Stack limit is at end of data. */
260 /* Allow slop for stack overflow handling and small frames. */
271 #ifdef ARM_RDI_MONITOR
272 /* Issue Angel SWI to read stack info. */
273 movs r0, #AngelSWI_Reason_HeapInfo
274 adr r1, .LC0 /* Point at ptr to 4 words to receive data. */
277 #elif defined(__thumb2__)
278 /* We are in thumb mode for startup on armv7 architectures. */
281 /* We are always in ARM mode for startup on pre armv7 archs. */
282 AngelSWIAsm AngelSWI_ARM
284 ldr r0, .LC0 /* Point at values read. */
286 /* Set __heap_limit. */
290 ldr r2, =__heap_limit
296 /* If the heap base value [r0, #0] is 0 then the heap base is actually
297 at the end of program data (i.e. __end__). See:
298 http://infocenter.arm.com/help/topic/com.arm.doc.dui0471-/Bacbefaa.html
299 for more information. */
305 /* We skip setting SP/SL if 0 returned from semihosting.
306 - According to semihosting docs, if 0 returned from semihosting,
307 the system was unable to calculate the real value, so it's ok
308 to skip setting SP/SL to 0 here.
309 - Considering M-profile processors, We might want to initialize
310 SP by the first entry of vector table and return 0 to SYS_HEAPINFO
311 semihosting call, which will be skipped here.
312 - Considering R-profile processors there is no automatic SP init by hardware
313 so we need to initialize it by default value. */
321 /* r2 (SL value) will be used in _stack_init. */
322 bl FUNCTION (_stack_init)
325 #else /* standalone */
326 /* Set up the stack pointer to a fixed value. */
327 /* Changes by toralf:
328 - Allow linker script to provide stack via __stack symbol - see
330 - Provide "hooks" that may be used by the application to add
331 custom init code - see .Lhwinit and .Lswinit. */
345 /* Note: This 'mov' is essential when starting in User, and ensures we
346 always get *some* SP value for the initial mode, even if we
347 have somehow missed it below (in which case it gets the same
348 value as FIQ - not ideal, but better than nothing). */
351 /* We don't care of r2 value in standalone. */
352 bl FUNCTION (_stack_init)
356 /* Zero the memory in the .bss section. */
357 movs a2, #0 /* Second arg: fill value. */
358 mov fp, a2 /* Null frame pointer. */
359 mov r7, a2 /* Null frame pointer for Thumb. */
361 ldr a1, .LC1 /* First arg: start of memory block. */
363 subs a3, a3, a1 /* Third arg: length of block. */
366 #if __thumb__ && !defined(PREFER_THUMB)
367 /* Enter Thumb mode... */
368 add a4, pc, #1 /* Get the address of the Thumb block. */
369 bx a4 /* Go there and start Thumb decoding. */
372 .global __change_mode
378 #if !defined (ARM_RDP_MONITOR) && !defined (ARM_RDI_MONITOR)
379 /* Changes by toralf: Taken from libgloss/m68k/crt0.S
380 initialize target specific stuff. Only execute these
381 functions it they exist. */
393 movs r0, #0 /* No arguments. */
394 movs r1, #0 /* No argv either. */
396 /* Need to set up standard file handles. */
397 bl FUNCTION (initialise_monitor_handles)
399 #ifdef ARM_RDP_MONITOR
400 swi SWI_GetEnv /* Sets r0 to point to the command line. */
403 movs r0, #AngelSWI_Reason_GetCmdLine
404 ldr r1, .LC30 /* Space for command line. */
413 /* Parse string at r1. */
414 movs r0, #0 /* Count of arguments so far. */
415 /* Push a NULL argument onto the end of the list. */
422 /* Skip leading blanks. */
434 /* See whether we are scanning a string. */
445 movs r2, #' ' /* Terminator type. */
446 subs r1, r1, #1 /* Adjust back to point at start char. */
451 movne r2, #' ' /* Terminator type. */
452 subne r1, r1, #1 /* Adjust back to point at start char. */
455 /* Stack a pointer to the current argument. */
471 cmp r2, r3 /* Reached terminator ? */
475 strb r2, [r3] /* Terminate the arg string. */
479 mov r1, sp /* Point at stacked arg pointers. */
480 /* We've now got the stacked args in order, reverse them. */
496 /* Ensure doubleword stack alignment. */
502 add r2, sp, r0, LSL #2 /* End of args. */
503 mov r3, sp /* Start of args. */
505 ldrhi r4,[r2, #-4] /* Reverse ends of list. */
510 /* Ensure doubleword stack alignment. */
515 #ifdef __USES_INITFINI__
516 /* Some arm/elf targets use the .init and .fini sections
517 to create constructors and destructors, and for these
518 targets we need to call the _init function and arrange
519 for _fini to be called at program exit. */
523 /* Make reference to atexit weak to avoid unconditionally pulling in
524 support code. Refer to comments in __atexit.c for more details. */
525 .weak FUNCTION(atexit)
539 bl FUNCTION (exit) /* Should not return. */
541 #if __thumb__ && !defined(PREFER_THUMB)
542 /* Come out of Thumb mode. This code should be redundant. */
549 /* Halt the execution. This code should never be executed. */
550 /* With no debug monitor, this probably aborts (eventually).
551 With a Demon debug monitor, this halts cleanly.
552 With an Angel debug monitor, this will report 'Unknown SWI'. */
558 /* For Thumb, constants must be after the code since only
559 positive offsets are supported for PC relative addresses. */
562 #ifdef ARM_RDI_MONITOR
565 #ifndef ARM_RDP_MONITOR
566 /* Changes by toralf: Provide alternative "stack" variable whose value
567 may be defined externally; .Lstack will be used instead of .LC0 if
568 it points to a non-0 value. Also set up references to "hooks" that
569 may be used by the application to provide additional init code. */
573 .word 0x80000 /* Top of RAM on the PIE board. */
576 .word FUNCTION (hardware_init_hook)
578 .word FUNCTION (software_init_hook)
580 /* Set up defaults for the above variables in the form of weak symbols
581 - so that application will link correctly, and get value 0 in
582 runtime (meaning "ignore setting") for the variables, when the user
583 does not provide the symbols. (The linker uses a weak symbol if,
584 and only if, a normal version of the same symbol isn't provided
585 e.g. by a linker script or another object file.) */
587 .weak FUNCTION (hardware_init_hook)
588 .weak FUNCTION (software_init_hook)
601 #ifdef __USES_INITFINI__
604 .word FUNCTION(atexit)
606 /* Weak reference _fini in case of lite exit. */
607 .weak FUNCTION(_fini)
610 .word FUNCTION(_fini)
612 #ifdef ARM_RDI_MONITOR
618 /* Workspace for Angel calls. */
620 /* Data returned by monitor SWI. */
621 .global __stack_base__
624 __stack_base__: .word 0
626 CommandLine: .space 256,0 /* Maximum length of 255 chars handled. */
634 .long 0,0,0,0,0,0,0,0