Author: olista01 Date: Mon Jul 25 04:21:56 2016 New Revision: 276625 URL: http://llvm.org/viewvc/llvm-project?rev=276625&view=rev Log: [libunwind][ARM] Add support for Thumb1 targets
The Thumb1 version of the code for saving and restoring the unwind context has a few bugs which prevent it from working: * It uses the STM instruction without writeback, which is not valid for Thumb1 (It was introduced in Thumb2). * It only saves/restores the low 8 registers, the sp and the lr, so if a program uses r8-r12 they will not be correctly restored when throwing an exception. There aren't currently any Thumb1 build-bots to test this, but we have been successfully running the libc++abi and libc++ test suites on Cortex-M0 models, as well as some other test suites that use C++ exceptions on a downstream version of libunwind with this patch applied. Differential Revision: https://reviews.llvm.org/D22292 Modified: libunwind/trunk/src/UnwindRegistersRestore.S libunwind/trunk/src/UnwindRegistersSave.S Modified: libunwind/trunk/src/UnwindRegistersRestore.S URL: http://llvm.org/viewvc/llvm-project/libunwind/trunk/src/UnwindRegistersRestore.S?rev=276625&r1=276624&r2=276625&view=diff ============================================================================== --- libunwind/trunk/src/UnwindRegistersRestore.S (original) +++ libunwind/trunk/src/UnwindRegistersRestore.S Mon Jul 25 04:21:56 2016 @@ -322,9 +322,18 @@ DEFINE_LIBUNWIND_PRIVATE_FUNCTION(_ZN9li @ .p2align 2 DEFINE_LIBUNWIND_PRIVATE_FUNCTION(_ZN9libunwind13Registers_arm20restoreCoreAndJumpToEv) -#if !defined(__ARM_ARCH_ISA_ARM) - ldr r2, [r0, #52] - ldr r3, [r0, #60] +#if !defined(__ARM_ARCH_ISA_ARM) && __ARM_ARCH_ISA_THUMB == 1 + @ r8-r11: ldm into r1-r4, then mov to r8-r11 + adds r0, #0x20 + ldm r0!, {r1-r4} + subs r0, #0x30 + mov r8, r1 + mov r9, r2 + mov r10, r3 + mov r11, r4 + @ r12 does not need loading, it it the intra-procedure-call scratch register + ldr r2, [r0, #0x34] + ldr r3, [r0, #0x3c] mov sp, r2 mov lr, r3 @ restore pc into lr ldm r0, {r0-r7} Modified: libunwind/trunk/src/UnwindRegistersSave.S URL: http://llvm.org/viewvc/llvm-project/libunwind/trunk/src/UnwindRegistersSave.S?rev=276625&r1=276624&r2=276625&view=diff ============================================================================== --- libunwind/trunk/src/UnwindRegistersSave.S (original) +++ libunwind/trunk/src/UnwindRegistersSave.S Mon Jul 25 04:21:56 2016 @@ -309,13 +309,24 @@ DEFINE_LIBUNWIND_FUNCTION(unw_getcontext @ .p2align 2 DEFINE_LIBUNWIND_FUNCTION(unw_getcontext) -#if !defined(__ARM_ARCH_ISA_ARM) - stm r0, {r0-r7} +#if !defined(__ARM_ARCH_ISA_ARM) && __ARM_ARCH_ISA_THUMB == 1 + stm r0!, {r0-r7} + mov r1, r8 + mov r2, r9 + mov r3, r10 + stm r0!, {r1-r3} + mov r1, r11 mov r2, sp mov r3, lr - str r2, [r0, #52] - str r3, [r0, #56] - str r3, [r0, #60] @ store return address as pc + str r1, [r0, #0] @ r11 + @ r12 does not need storing, it it the intra-procedure-call scratch register + str r2, [r0, #8] @ sp + str r3, [r0, #12] @ lr + str r3, [r0, #16] @ store return address as pc + @ T1 does not have a non-cpsr-clobbering register-zeroing instruction. + @ It is safe to use here though because we are about to return, and cpsr is + @ not expected to be preserved. + movs r0, #0 @ return UNW_ESUCCESS #else @ 32bit thumb-2 restrictions for stm: @ . the sp (r13) cannot be in the list @@ -324,13 +335,6 @@ DEFINE_LIBUNWIND_FUNCTION(unw_getcontext str sp, [r0, #52] str lr, [r0, #56] str lr, [r0, #60] @ store return address as pc -#endif -#if __ARM_ARCH_ISA_THUMB == 1 - @ T1 does not have a non-cpsr-clobbering register-zeroing instruction. - @ It is safe to use here though because we are about to return, and cpsr is - @ not expected to be preserved. - movs r0, #0 @ return UNW_ESUCCESS -#else mov r0, #0 @ return UNW_ESUCCESS #endif JMP(lr) _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits