[PATCH] Arm - exceptions stack pointer initialization hook
Alexander Fedotov <[email protected]>
| Newsgroups | gmane.comp.lib.newlib |
|---|---|
| Message-ID | <CAN8C2CphbcXPHVMqGq35ceZjWo+gsoqvwDc=MF7wkd4-VACDqA@mail.gmail.com> |
Please find attached patch that adds new hook "_exceptions_stack_init". Hook is defined as "weak" to give user ability to override by it's own implementation. Also added new macro for .fnstart and .fnend to improve readability. Alex
0001-Provide-stack-initialization-hook-for-exception-mode.patch
(application/octet-stream, 5 KB)
From 71726dae9df713a60bddce31839b778545a0fc4a Mon Sep 17 00:00:00 2001 From: Alexander Fedotov <[email protected]> Date: Sun, 3 Feb 2019 22:49:38 +0300 Subject: [PATCH] Provide stack initialization hook for exception modes. Add new macro FN_START and FN_END --- libgloss/arm/crt0.S | 120 ++++++++++++++++++++++++++++---------------- 1 file changed, 76 insertions(+), 44 deletions(-) diff --git a/libgloss/arm/crt0.S b/libgloss/arm/crt0.S index 48f3d6b1d..c822d5ad8 100644 --- a/libgloss/arm/crt0.S +++ b/libgloss/arm/crt0.S @@ -59,6 +59,21 @@ .endm #endif +/* Annotation for EABI unwinding tables. */ +.macro FN_START +#if defined(__ELF__) && !defined(__USING_SJLJ_EXCEPTIONS__) + .fnstart +#endif +.endm + +.macro FN_END +#if defined(__ELF__) && !defined(__USING_SJLJ_EXCEPTIONS__) + /* Protect against unhandled exceptions. */ + .cantunwind + .fnend +#endif +.endm + .macro indirect_call reg #ifdef HAVE_CALL_INDIRECT blx \reg @@ -68,14 +83,65 @@ #endif .endm - .align 0 + +/******************************************************************************* +* Target specific stack pointer initialization for different exception modes. +* Declared as "weak" so that user can write and use its own version. +*******************************************************************************/ + .align 0 + FUNC_START _exceptions_stack_init + .weak FUNCTION (_exceptions_stack_init) + FN_START + +#ifdef PREFER_THUMB + /* XXX Fill in stack assignments for interrupt modes. */ +#else + mrs r2, CPSR + tst r2, #0x0F /* Test mode bits - in User of all are 0 */ + beq .LC23 /* "eq" means r2 AND #0x0F is 0 */ + + msr CPSR_c, #0xD1 /* FIRQ mode, interrupts disabled */ + mov sp, r3 + sub sl, sp, #0x1000 /* This mode also has its own sl (see below) */ + + mov r3, sl + msr CPSR_c, #0xD7 /* Abort mode, interrupts disabled */ + mov sp, r3 + sub r3, r3, #0x1000 + + msr CPSR_c, #0xDB /* Undefined mode, interrupts disabled */ + mov sp, r3 + sub r3, r3, #0x1000 + + msr CPSR_c, #0xD2 /* IRQ mode, interrupts disabled */ + mov sp, r3 + sub r3, r3, #0x2000 + + msr CPSR_c, #0xD3 /* Supervisory mode, interrupts disabled */ + + mov sp, r3 + sub r3, r3, #0x8000 /* Min size 32k */ + bic r3, r3, #0x00FF /* Align with current 64k block */ + bic r3, r3, #0xFF00 + + str r3, [r3, #-4] /* Move value into user mode sp without */ + ldmdb r3, {sp}^ /* changing modes, via '^' form of ldm */ + orr r2, r2, #0xC0 /* Back to original mode, presumably SVC, */ + msr CPSR_c, r2 /* with FIQ/IRQ disable bits forced to 1 */ +.LC23: +#endif + bx lr + FN_END + + +/******************************************************************************* +* Main library startup code. +*******************************************************************************/ + .align 0 FUNC_START _mainCRTStartup FUNC_START _start -#if defined(__ELF__) && !defined(__USING_SJLJ_EXCEPTIONS__) - /* Annotation for EABI unwinding tables. */ - .fnstart -#endif + FN_START /* __ARM_ARCH_PROFILE is defined from GCC 4.8 onwards, however __ARM_ARCH_7A has been defined since 4.2 onwards, which is when v7-a support was added @@ -153,6 +219,9 @@ beq .LC26 mov sp, r1 .LC26: + + bl FUNCTION (_exceptions_stack_init) + cmp r2, #0 beq .LC27 /* allow slop for stack overflow handling and small frames */ @@ -194,42 +263,9 @@ have somehow missed it below (in which case it gets the same value as FIQ - not ideal, but better than nothing.) */ mov sp, r3 -#ifdef PREFER_THUMB - /* XXX Fill in stack assignments for interrupt modes. */ -#else - mrs r2, CPSR - tst r2, #0x0F /* Test mode bits - in User of all are 0 */ - beq .LC23 /* "eq" means r2 AND #0x0F is 0 */ - msr CPSR_c, #0xD1 /* FIRQ mode, interrupts disabled */ - mov sp, r3 - sub sl, sp, #0x1000 /* This mode also has its own sl (see below) */ - - mov r3, sl - msr CPSR_c, #0xD7 /* Abort mode, interrupts disabled */ - mov sp, r3 - sub r3, r3, #0x1000 - msr CPSR_c, #0xDB /* Undefined mode, interrupts disabled */ - mov sp, r3 - sub r3, r3, #0x1000 - - msr CPSR_c, #0xD2 /* IRQ mode, interrupts disabled */ - mov sp, r3 - sub r3, r3, #0x2000 - - msr CPSR_c, #0xD3 /* Supervisory mode, interrupts disabled */ + bl FUNCTION (_exceptions_stack_init) - mov sp, r3 - sub r3, r3, #0x8000 /* Min size 32k */ - bic r3, r3, #0x00FF /* Align with current 64k block */ - bic r3, r3, #0xFF00 - - str r3, [r3, #-4] /* Move value into user mode sp without */ - ldmdb r3, {sp}^ /* changing modes, via '^' form of ldm */ - orr r2, r2, #0xC0 /* Back to original mode, presumably SVC, */ - msr CPSR_c, r2 /* with FIQ/IRQ disable bits forced to 1 */ -#endif -.LC23: /* Setup a default stack-limit in-case the code has been compiled with "-mapcs-stack-check". Hard-wiring this value is not ideal, since there is currently no support for @@ -484,11 +520,7 @@ change_back: #endif #endif -#if defined(__ELF__) && !defined(__USING_SJLJ_EXCEPTIONS__) - /* Protect against unhandled exceptions. */ - .cantunwind - .fnend -#endif + FN_END .LC1: .word __bss_start__ .LC2: -- 2.20.1.windows.1