diff options
author | Steve MacLean <sdmaclea@qti.qualcomm.com> | 2017-02-17 13:25:37 -0500 |
---|---|---|
committer | Jan Vorlicek <janvorli@microsoft.com> | 2017-02-17 19:25:37 +0100 |
commit | 9baa44aa334cf6f032e4abeae10dc1b960aaeb57 (patch) | |
tree | 9db49209ed0728eab25458e22f7416a0d31e0690 /src/pal | |
parent | 9f4aae6ac42f846473e6f70f2ac19e8910c97ccc (diff) | |
download | coreclr-9baa44aa334cf6f032e4abeae10dc1b960aaeb57.tar.gz coreclr-9baa44aa334cf6f032e4abeae10dc1b960aaeb57.tar.bz2 coreclr-9baa44aa334cf6f032e4abeae10dc1b960aaeb57.zip |
[ARM64/Unix] (#9500)
* [Arm64/Unix] Update arm64 *.S files to match *.asm
* [Arm64/Unix] Fix CONTEXTToNativeContext()
* [Arm64/Unix] ThrowExceptionFromContextInternal
* [Arm64/Unix] Preserve x8 argument register
* [ARM64/Unix] Add CFI directives
Add native unwind info
* [Arm64/Unix] Fix RtlRestoreContext
* [Arm64/Unix] Restore FP from CurrentContextPointers
* [Arm64/Unix] fix pointer math
* [Arm64/Unix] Fix CallDescrWorkerInternal personality
* [Arm64/Unix] More Fp fixups
* [Arm64/Unix] CallEHFunclet machine state
Restore non-volatile machine state in CallEHFunclet
* [Arm64/Unix] CallDescrWorkerInternal
Use empty stack slot to save argument
* [Arm64/Unix] RtlVirtualUnwind update pointers
* [Arm64] LazyMachState fixes
* [Arm64/Unix] disable USE_REDIRECT_FOR_GCSTRESS
When FEATURE_PAL is enableds USE_REDIRECT_FOR_GCSTRESS
is not supported
* [Arm64] ClearRegDisplayArgumentAndScratchRegisters()
* [Arm64] Remove unnecesary copy in TransitionFrame
* [Arm64/Unix] Fix comment per review
* [Arm64/Unix] move constants per review
* [Arm64/Unix] Use ldp per review
Also fix indentation
* [Arm64/Unix] Fix indentation per review
* [Arm64/Unix] Remove m_Unwound per review comments
* [Arm64/Unix] Use PREPARE_EXTERNAL_VAR to access globals
* [Arm64/Unix] Fix more whitespace per earlier review comments
Diffstat (limited to 'src/pal')
-rw-r--r-- | src/pal/inc/unixasmmacrosarm64.inc | 151 | ||||
-rw-r--r-- | src/pal/src/arch/arm64/asmconstants.h | 95 | ||||
-rw-r--r-- | src/pal/src/arch/arm64/context2.S | 114 | ||||
-rw-r--r-- | src/pal/src/arch/arm64/exceptionhelper.S | 25 | ||||
-rw-r--r-- | src/pal/src/exception/seh-unwind.cpp | 1 | ||||
-rw-r--r-- | src/pal/src/include/pal/context.h | 3 | ||||
-rw-r--r-- | src/pal/src/thread/context.cpp | 2 |
7 files changed, 235 insertions, 156 deletions
diff --git a/src/pal/inc/unixasmmacrosarm64.inc b/src/pal/inc/unixasmmacrosarm64.inc index 359f27f878..ed73748e41 100644 --- a/src/pal/inc/unixasmmacrosarm64.inc +++ b/src/pal/inc/unixasmmacrosarm64.inc @@ -31,8 +31,8 @@ C_FUNC(\Name): .endm .macro LEAF_END_MARKED Name, Section - .global C_FUNC(\Name\()_End) C_FUNC(\Name\()_End): + .global C_FUNC(\Name\()_End) LEAF_END \Name, \Section .endm @@ -48,18 +48,23 @@ C_FUNC(\Name\()_End): .macro EPILOG_STACK_FREE Size add sp, sp, \Size + .cfi_adjust_cfa_offset -\Size .endm .macro EPILOG_STACK_RESTORE mov sp, fp + .cfi_restore sp .endm .macro PROLOG_SAVE_REG reg, ofs str \reg, [sp, \ofs] + .cfi_rel_offset \reg, \ofs .endm .macro PROLOG_SAVE_REG_PAIR reg1, reg2, ofs stp \reg1, \reg2, [sp, \ofs] + .cfi_rel_offset \reg1, \ofs + .cfi_rel_offset \reg2, \ofs + 8 .ifc \reg1, fp mov fp, sp .endif @@ -67,6 +72,9 @@ C_FUNC(\Name\()_End): .macro PROLOG_SAVE_REG_PAIR_INDEXED reg1, reg2, ofs stp \reg1, \reg2, [sp, \ofs]! + .cfi_adjust_cfa_offset -\ofs + .cfi_rel_offset \reg1, 0 + .cfi_rel_offset \reg2, 8 .ifc \reg1, fp mov fp, sp .endif @@ -74,14 +82,20 @@ C_FUNC(\Name\()_End): .macro EPILOG_RESTORE_REG reg, ofs ldr \reg, [sp, \ofs] + .cfi_restore \reg1 .endm .macro EPILOG_RESTORE_REG_PAIR reg1, reg2, ofs ldp \reg1, \reg2, [sp, \ofs] + .cfi_restore \reg1 + .cfi_restore \reg2 .endm .macro EPILOG_RESTORE_REG_PAIR_INDEXED reg1, reg2, ofs ldp \reg1, \reg2, [sp], \ofs + .cfi_restore \reg1 + .cfi_restore \reg2 + .cfi_adjust_cfa_offset -\ofs .endm .macro EPILOG_RETURN @@ -94,14 +108,14 @@ C_FUNC(\Name\()_End): //----------------------------------------------------------------------------- // Define the prolog for a TransitionFrame-based method. This macro should be called first in the method and -// comprises the entire prolog (i.e. don't modify SP after calling this).The locals must be 8 byte aligned +// comprises the entire prolog (i.e. don't modify SP after calling this).The locals must be 8 byte aligned // // Stack layout: // // (stack parameters) // ... // fp -// lr +// lr // CalleeSavedRegisters::x28 // CalleeSavedRegisters::x27 // CalleeSavedRegisters::x26 @@ -133,6 +147,7 @@ C_FUNC(\Name\()_End): .macro PROLOG_WITH_TRANSITION_BLOCK extraLocals = 0, SaveFPArgs = 1 __PWTB_FloatArgumentRegisters = \extraLocals + __PWTB_SaveFPArgs = \SaveFPArgs .if ((__PWTB_FloatArgumentRegisters % 16) != 0) __PWTB_FloatArgumentRegisters = __PWTB_FloatArgumentRegisters + 8 @@ -140,74 +155,114 @@ C_FUNC(\Name\()_End): __PWTB_TransitionBlock = __PWTB_FloatArgumentRegisters - .if \SaveFPArgs > 0 + .if (__PWTB_SaveFPArgs == 1) __PWTB_TransitionBlock = __PWTB_TransitionBlock + SIZEOF__FloatArgumentRegisters .endif __PWTB_StackAlloc = __PWTB_TransitionBlock - __PWTB_ArgumentRegisters = __PWTB_StackAlloc + 96 - - PROLOG_SAVE_REG_PAIR_INDEXED fp, lr, #-160 - // Spill callee saved registers - PROLOG_SAVE_REG_PAIR x19, x20, #16 - PROLOG_SAVE_REG_PAIR x21, x22, #32 - PROLOG_SAVE_REG_PAIR x23, x24, #48 - PROLOG_SAVE_REG_PAIR x25, x26, #64 - PROLOG_SAVE_REG_PAIR x27, x28, #80 - + __PWTB_ArgumentRegisters = __PWTB_StackAlloc + 96 + + PROLOG_SAVE_REG_PAIR_INDEXED fp, lr, -176 + // Spill callee saved registers + PROLOG_SAVE_REG_PAIR x19, x20, 16 + PROLOG_SAVE_REG_PAIR x21, x22, 32 + PROLOG_SAVE_REG_PAIR x23, x24, 48 + PROLOG_SAVE_REG_PAIR x25, x26, 64 + PROLOG_SAVE_REG_PAIR x27, x28, 80 + // Allocate space for the rest of the frame PROLOG_STACK_ALLOC __PWTB_StackAlloc - + // Spill argument registers. SAVE_ARGUMENT_REGISTERS sp, __PWTB_ArgumentRegisters - .if \SaveFPArgs > 0 + .if (__PWTB_SaveFPArgs == 1) SAVE_FLOAT_ARGUMENT_REGISTERS sp, \extraLocals .endif .endm //----------------------------------------------------------------------------- -// The Following sets of SAVE_*_REGISTERS expect the memory to be reserved and +// The Following sets of SAVE_*_REGISTERS expect the memory to be reserved and // base address to be passed in $reg // // Reserve 64 bytes of memory before calling SAVE_ARGUMENT_REGISTERS -.macro SAVE_ARGUMENT_REGISTERS reg, ofs +.macro SAVE_ARGUMENT_REGISTERS reg, ofs stp x0, x1, [\reg, #(\ofs)] + .cfi_rel_offset x0, \ofs + .cfi_rel_offset x1, \ofs + 8 stp x2, x3, [\reg, #(\ofs + 16)] + .cfi_rel_offset x2, \ofs + 16 + .cfi_rel_offset x3, \ofs + 24 stp x4, x5, [\reg, #(\ofs + 32)] + .cfi_rel_offset x4, \ofs + 32 + .cfi_rel_offset x5, \ofs + 40 stp x6, x7, [\reg, #(\ofs + 48)] + .cfi_rel_offset x6, \ofs + 48 + .cfi_rel_offset x7, \ofs + 56 + str x8, [\reg, #(\ofs + 64)] + .cfi_rel_offset x8, \ofs + 64 .endm // Reserve 64 bytes of memory before calling SAVE_FLOAT_ARGUMENT_REGISTERS -.macro SAVE_FLOAT_ARGUMENT_REGISTERS reg, ofs +.macro SAVE_FLOAT_ARGUMENT_REGISTERS reg, ofs stp d0, d1, [\reg, #(\ofs)] + .cfi_rel_offset d0, \ofs + 0 + .cfi_rel_offset d1, \ofs + 8 stp d2, d3, [\reg, #(\ofs + 16)] + .cfi_rel_offset d2, \ofs + 16 + .cfi_rel_offset d3, \ofs + 24 stp d4, d5, [\reg, #(\ofs + 32)] + .cfi_rel_offset d4, \ofs + 32 + .cfi_rel_offset d5, \ofs + 40 stp d6, d7, [\reg, #(\ofs + 48)] + .cfi_rel_offset d6, \ofs + 48 + .cfi_rel_offset d7, \ofs + 56 .endm -.macro RESTORE_ARGUMENT_REGISTERS reg, ofs +.macro RESTORE_ARGUMENT_REGISTERS reg, ofs ldp x0, x1, [\reg, #(\ofs)] + .cfi_restore x0 + .cfi_restore x1 ldp x2, x3, [\reg, #(\ofs + 16)] + .cfi_restore x2 + .cfi_restore x3 ldp x4, x5, [\reg, #(\ofs + 32)] + .cfi_restore x4 + .cfi_restore x5 ldp x6, x7, [\reg, #(\ofs + 48)] + .cfi_restore x6 + .cfi_restore x7 + ldr x8, [\reg, #(\ofs + 64)] + .cfi_restore x8 .endm -.macro RESTORE_FLOAT_ARGUMENT_REGISTERS reg, ofs +.macro RESTORE_FLOAT_ARGUMENT_REGISTERS reg, ofs ldp d0, d1, [\reg, #(\ofs)] + .cfi_restore d0 + .cfi_restore d1 ldp d2, d3, [\reg, #(\ofs + 16)] + .cfi_restore d2 + .cfi_restore d3 ldp d4, d5, [\reg, #(\ofs + 32)] + .cfi_restore d4 + .cfi_restore d5 ldp d6, d7, [\reg, #(\ofs + 48)] + .cfi_restore d6 + .cfi_restore d7 + +.endm +.macro EPILOG_BRANCH Target + b \Target .endm .macro EPILOG_BRANCH_REG reg @@ -216,40 +271,42 @@ C_FUNC(\Name\()_End): .endm -//----------------------------------------------------------------------------- -// Provides a matching epilog to PROLOG_WITH_TRANSITION_BLOCK and ends by preparing for tail-calling. -// Since this is a tail call argument registers are restored. -// -.macro EPILOG_WITH_TRANSITION_BLOCK_TAILCALL extraLocals = 0, SaveFPArgs =1 - __PWTB_FloatArgumentRegisters = \extraLocals +.macro EPILOG_WITH_TRANSITION_BLOCK_RETURN - .if ((__PWTB_FloatArgumentRegisters % 16) != 0) - __PWTB_FloatArgumentRegisters = __PWTB_FloatArgumentRegisters + 8 - .endif + EPILOG_STACK_FREE __PWTB_StackAlloc - __PWTB_TransitionBlock = __PWTB_FloatArgumentRegisters + EPILOG_RESTORE_REG_PAIR x19, x20, 16 + EPILOG_RESTORE_REG_PAIR x21, x22, 32 + EPILOG_RESTORE_REG_PAIR x23, x24, 48 + EPILOG_RESTORE_REG_PAIR x25, x26, 64 + EPILOG_RESTORE_REG_PAIR x27, x28, 80 + EPILOG_RESTORE_REG_PAIR_INDEXED fp, lr, 176 + ret - .if \SaveFPArgs > 0 - __PWTB_TransitionBlock = __PWTB_TransitionBlock + SIZEOF__FloatArgumentRegisters - .endif +.endm - __PWTB_StackAlloc = __PWTB_TransitionBlock - __PWTB_ArgumentRegisters = __PWTB_StackAlloc + 96 - .if \SaveFPArgs > 0 - RESTORE_FLOAT_ARGUMENT_REGISTERS sp, __PWTB_FloatArgumentRegisters +//----------------------------------------------------------------------------- +// Provides a matching epilog to PROLOG_WITH_TRANSITION_BLOCK and ends by preparing for tail-calling. +// Since this is a tail call argument registers are restored. +// +.macro EPILOG_WITH_TRANSITION_BLOCK_TAILCALL + + .if (__PWTB_SaveFPArgs == 1) + RESTORE_FLOAT_ARGUMENT_REGISTERS sp, __PWTB_FloatArgumentRegisters .endif RESTORE_ARGUMENT_REGISTERS sp, __PWTB_ArgumentRegisters + EPILOG_STACK_FREE __PWTB_StackAlloc - - EPILOG_RESTORE_REG_PAIR x19, x20, #16 - EPILOG_RESTORE_REG_PAIR x21, x22, #32 - EPILOG_RESTORE_REG_PAIR x23, x24, #48 - EPILOG_RESTORE_REG_PAIR x25, x26, #64 - EPILOG_RESTORE_REG_PAIR x27, x28, #80 - EPILOG_RESTORE_REG_PAIR_INDEXED fp, lr, #160 + + EPILOG_RESTORE_REG_PAIR x19, x20, 16 + EPILOG_RESTORE_REG_PAIR x21, x22, 32 + EPILOG_RESTORE_REG_PAIR x23, x24, 48 + EPILOG_RESTORE_REG_PAIR x25, x26, 64 + EPILOG_RESTORE_REG_PAIR x27, x28, 80 + EPILOG_RESTORE_REG_PAIR_INDEXED fp, lr, 176 .endm @@ -273,8 +330,8 @@ __RedirectionFuncName SETS "|?RedirectedHandledJITCaseFor":CC:"$reason":CC:"@Thr IMPORT $__RedirectionFuncName NESTED_ENTRY $__RedirectionStubFuncName - PROLOG_SAVE_REG_PAIR fp, lr, #-16 - sub sp, sp, #16 // stack slot for CONTEXT * and padding + PROLOG_SAVE_REG_PAIR fp, lr, -16 + sub sp, sp, #16 // stack slot for CONTEXT * and padding //REDIRECTSTUB_SP_OFFSET_CONTEXT is defined in asmconstants.h and is used in GetCONTEXTFromRedirectedStubStackFrame //If CONTEXT is not saved at 0 offset from SP it must be changed as well. diff --git a/src/pal/src/arch/arm64/asmconstants.h b/src/pal/src/arch/arm64/asmconstants.h new file mode 100644 index 0000000000..b2bf74461f --- /dev/null +++ b/src/pal/src/arch/arm64/asmconstants.h @@ -0,0 +1,95 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +#ifndef __PAL_ARM64_ASMCONSTANTS_H__ +#define __PAL_ARM64_ASMCONSTANTS_H__ + +#define CONTEXT_ARM64 0x00400000L + +#define CONTEXT_CONTROL_BIT (0) +#define CONTEXT_INTEGER_BIT (1) +#define CONTEXT_FLOATING_POINT_BIT (2) +#define CONTEXT_DEBUG_REGISTERS_BIT (3) + +#define CONTEXT_CONTROL (CONTEXT_ARM64 | (1L << CONTEXT_CONTROL_BIT)) +#define CONTEXT_INTEGER (CONTEXT_ARM64 | (1 << CONTEXT_INTEGER_BIT)) +#define CONTEXT_FLOATING_POINT (CONTEXT_ARM64 | (1 << CONTEXT_FLOATING_POINT_BIT)) +#define CONTEXT_DEBUG_REGISTERS (CONTEXT_ARM64 | (1 << CONTEXT_DEBUG_REGISTERS_BIT)) + +#define CONTEXT_FULL (CONTEXT_CONTROL | CONTEXT_INTEGER | CONTEXT_FLOATING_POINT) + + +#define CONTEXT_ContextFlags 0 +#define CONTEXT_Cpsr CONTEXT_ContextFlags+4 +#define CONTEXT_X0 CONTEXT_Cpsr+4 +#define CONTEXT_X1 CONTEXT_X0+8 +#define CONTEXT_X2 CONTEXT_X1+8 +#define CONTEXT_X3 CONTEXT_X2+8 +#define CONTEXT_X4 CONTEXT_X3+8 +#define CONTEXT_X5 CONTEXT_X4+8 +#define CONTEXT_X6 CONTEXT_X5+8 +#define CONTEXT_X7 CONTEXT_X6+8 +#define CONTEXT_X8 CONTEXT_X7+8 +#define CONTEXT_X9 CONTEXT_X8+8 +#define CONTEXT_X10 CONTEXT_X9+8 +#define CONTEXT_X11 CONTEXT_X10+8 +#define CONTEXT_X12 CONTEXT_X11+8 +#define CONTEXT_X13 CONTEXT_X12+8 +#define CONTEXT_X14 CONTEXT_X13+8 +#define CONTEXT_X15 CONTEXT_X14+8 +#define CONTEXT_X16 CONTEXT_X15+8 +#define CONTEXT_X17 CONTEXT_X16+8 +#define CONTEXT_X18 CONTEXT_X17+8 +#define CONTEXT_X19 CONTEXT_X18+8 +#define CONTEXT_X20 CONTEXT_X19+8 +#define CONTEXT_X21 CONTEXT_X20+8 +#define CONTEXT_X22 CONTEXT_X21+8 +#define CONTEXT_X23 CONTEXT_X22+8 +#define CONTEXT_X24 CONTEXT_X23+8 +#define CONTEXT_X25 CONTEXT_X24+8 +#define CONTEXT_X26 CONTEXT_X25+8 +#define CONTEXT_X27 CONTEXT_X26+8 +#define CONTEXT_X28 CONTEXT_X27+8 +#define CONTEXT_Fp CONTEXT_X28+8 +#define CONTEXT_Lr CONTEXT_Fp+8 +#define CONTEXT_Sp CONTEXT_Lr+8 +#define CONTEXT_Pc CONTEXT_Sp+8 +#define CONTEXT_NEON_OFFSET CONTEXT_Pc+8 +#define CONTEXT_V0 0 +#define CONTEXT_V1 CONTEXT_V0+16 +#define CONTEXT_V2 CONTEXT_V1+16 +#define CONTEXT_V3 CONTEXT_V2+16 +#define CONTEXT_V4 CONTEXT_V3+16 +#define CONTEXT_V5 CONTEXT_V4+16 +#define CONTEXT_V6 CONTEXT_V5+16 +#define CONTEXT_V7 CONTEXT_V6+16 +#define CONTEXT_V8 CONTEXT_V7+16 +#define CONTEXT_V9 CONTEXT_V8+16 +#define CONTEXT_V10 CONTEXT_V9+16 +#define CONTEXT_V11 CONTEXT_V10+16 +#define CONTEXT_V12 CONTEXT_V11+16 +#define CONTEXT_V13 CONTEXT_V12+16 +#define CONTEXT_V14 CONTEXT_V13+16 +#define CONTEXT_V15 CONTEXT_V14+16 +#define CONTEXT_V16 CONTEXT_V15+16 +#define CONTEXT_V17 CONTEXT_V16+16 +#define CONTEXT_V18 CONTEXT_V17+16 +#define CONTEXT_V19 CONTEXT_V18+16 +#define CONTEXT_V20 CONTEXT_V19+16 +#define CONTEXT_V21 CONTEXT_V20+16 +#define CONTEXT_V22 CONTEXT_V21+16 +#define CONTEXT_V23 CONTEXT_V22+16 +#define CONTEXT_V24 CONTEXT_V23+16 +#define CONTEXT_V25 CONTEXT_V24+16 +#define CONTEXT_V26 CONTEXT_V25+16 +#define CONTEXT_V27 CONTEXT_V26+16 +#define CONTEXT_V28 CONTEXT_V27+16 +#define CONTEXT_V29 CONTEXT_V28+16 +#define CONTEXT_V30 CONTEXT_V29+16 +#define CONTEXT_V31 CONTEXT_V30+16 +#define CONTEXT_FLOAT_CONTROL_OFFSET CONTEXT_V31 +#define CONTEXT_Fpcr 0 +#define CONTEXT_Fpsr CONTEXT_Fpcr+4 + +#endif diff --git a/src/pal/src/arch/arm64/context2.S b/src/pal/src/arch/arm64/context2.S index a64e62c94d..e62a9ac4d9 100644 --- a/src/pal/src/arch/arm64/context2.S +++ b/src/pal/src/arch/arm64/context2.S @@ -8,87 +8,7 @@ // #include "unixasmmacros.inc" - -#define CONTEXT_ARM64 0x00400000L - -#define CONTEXT_CONTROL (CONTEXT_ARM64 | 0x1L) -#define CONTEXT_INTEGER (CONTEXT_ARM64 | 0x2L) -#define CONTEXT_FLOATING_POINT (CONTEXT_ARM64 | 0x4L) -#define CONTEXT_DEBUG_REGISTERS (CONTEXT_ARM64 | 0x8L) - -#define CONTEXT_FULL (CONTEXT_CONTROL | CONTEXT_INTEGER | CONTEXT_FLOATING_POINT) - -#define CONTEXT_ContextFlags 0 -#define CONTEXT_Cpsr CONTEXT_ContextFlags+4 -#define CONTEXT_X0 CONTEXT_Cpsr+4 -#define CONTEXT_X1 CONTEXT_X0+8 -#define CONTEXT_X2 CONTEXT_X1+8 -#define CONTEXT_X3 CONTEXT_X2+8 -#define CONTEXT_X4 CONTEXT_X3+8 -#define CONTEXT_X5 CONTEXT_X4+8 -#define CONTEXT_X6 CONTEXT_X5+8 -#define CONTEXT_X7 CONTEXT_X6+8 -#define CONTEXT_X8 CONTEXT_X7+8 -#define CONTEXT_X9 CONTEXT_X8+8 -#define CONTEXT_X10 CONTEXT_X9+8 -#define CONTEXT_X11 CONTEXT_X10+8 -#define CONTEXT_X12 CONTEXT_X11+8 -#define CONTEXT_X13 CONTEXT_X12+8 -#define CONTEXT_X14 CONTEXT_X13+8 -#define CONTEXT_X15 CONTEXT_X14+8 -#define CONTEXT_X16 CONTEXT_X15+8 -#define CONTEXT_X17 CONTEXT_X16+8 -#define CONTEXT_X18 CONTEXT_X17+8 -#define CONTEXT_X19 CONTEXT_X18+8 -#define CONTEXT_X20 CONTEXT_X19+8 -#define CONTEXT_X21 CONTEXT_X20+8 -#define CONTEXT_X22 CONTEXT_X21+8 -#define CONTEXT_X23 CONTEXT_X22+8 -#define CONTEXT_X24 CONTEXT_X23+8 -#define CONTEXT_X25 CONTEXT_X24+8 -#define CONTEXT_X26 CONTEXT_X25+8 -#define CONTEXT_X27 CONTEXT_X26+8 -#define CONTEXT_X28 CONTEXT_X27+8 -#define CONTEXT_Fp CONTEXT_X28+8 -#define CONTEXT_Lr CONTEXT_Fp+8 -#define CONTEXT_Sp CONTEXT_Lr+8 -#define CONTEXT_Pc CONTEXT_Sp+8 -#define CONTEXT_NEON_OFFSET CONTEXT_Pc+8 -#define CONTEXT_V0 0 -#define CONTEXT_V1 CONTEXT_V0+16 -#define CONTEXT_V2 CONTEXT_V1+16 -#define CONTEXT_V3 CONTEXT_V2+16 -#define CONTEXT_V4 CONTEXT_V3+16 -#define CONTEXT_V5 CONTEXT_V4+16 -#define CONTEXT_V6 CONTEXT_V5+16 -#define CONTEXT_V7 CONTEXT_V6+16 -#define CONTEXT_V8 CONTEXT_V7+16 -#define CONTEXT_V9 CONTEXT_V8+16 -#define CONTEXT_V10 CONTEXT_V9+16 -#define CONTEXT_V11 CONTEXT_V10+16 -#define CONTEXT_V12 CONTEXT_V11+16 -#define CONTEXT_V13 CONTEXT_V12+16 -#define CONTEXT_V14 CONTEXT_V13+16 -#define CONTEXT_V15 CONTEXT_V14+16 -#define CONTEXT_V16 CONTEXT_V15+16 -#define CONTEXT_V17 CONTEXT_V16+16 -#define CONTEXT_V18 CONTEXT_V17+16 -#define CONTEXT_V19 CONTEXT_V18+16 -#define CONTEXT_V20 CONTEXT_V19+16 -#define CONTEXT_V21 CONTEXT_V20+16 -#define CONTEXT_V22 CONTEXT_V21+16 -#define CONTEXT_V23 CONTEXT_V22+16 -#define CONTEXT_V24 CONTEXT_V23+16 -#define CONTEXT_V25 CONTEXT_V24+16 -#define CONTEXT_V26 CONTEXT_V25+16 -#define CONTEXT_V27 CONTEXT_V26+16 -#define CONTEXT_V28 CONTEXT_V27+16 -#define CONTEXT_V29 CONTEXT_V28+16 -#define CONTEXT_V30 CONTEXT_V29+16 -#define CONTEXT_V31 CONTEXT_V30+16 -#define CONTEXT_FLOAT_CONTROL_OFFSET CONTEXT_V31 -#define CONTEXT_Fpcr 0 -#define CONTEXT_Fpsr CONTEXT_Fpcr+4 +#include "asmconstants.h" // Incoming: // x0: Context* @@ -115,10 +35,8 @@ LEAF_ENTRY CONTEXT_CaptureContext, _TEXT ldr x2, [sp, 24] str w2, [x0, CONTEXT_Cpsr] stp fp, lr, [x0, CONTEXT_Fp] - add sp, sp, #32 - mov x2, sp + add x2, sp, #32 stp x2, lr, [x0, CONTEXT_Sp] - sub sp, sp, #32 LOCAL_LABEL(Done_CONTEXT_CONTROL): // we dont clobber x1 in the CONTEXT_CONTROL case @@ -224,14 +142,8 @@ LEAF_ENTRY RtlRestoreContext, _TEXT // since we potentially clobber x0 below, we'll bank it in x16 mov x16, x0 - ldr w2, [x16, CONTEXT_ContextFlags] - // clangs assembler doesn't seem to support the mov Wx, imm32 yet - movz w3, #0x40, lsl #16 - movk w3, #0x4 - mov w4, w3 - and w3, w2, w3 - cmp w3, w4 - b.ne LOCAL_LABEL(No_Restore_CONTEXT_FLOATING_POINT) + ldr w17, [x16, CONTEXT_ContextFlags] + tbz w17, #CONTEXT_FLOATING_POINT_BIT, LOCAL_LABEL(No_Restore_CONTEXT_FLOATING_POINT) add x16, x16, CONTEXT_NEON_OFFSET ldp q0, q1, [x16, CONTEXT_V0] @@ -256,12 +168,7 @@ LEAF_ENTRY RtlRestoreContext, _TEXT sub x16, x16, CONTEXT_NEON_OFFSET LOCAL_LABEL(No_Restore_CONTEXT_FLOATING_POINT): - movz w2, #0x40, lsl #16 - movk w2, #0x2 - mov w3, w2 - and w2, w1, w2 - cmp w2, w3 - b.ne LOCAL_LABEL(No_Restore_CONTEXT_INTEGER) + tbz w17, #CONTEXT_INTEGER_BIT, LOCAL_LABEL(No_Restore_CONTEXT_INTEGER) ldp x0, x1, [x16, CONTEXT_X0] ldp x2, x3, [x16, CONTEXT_X2] @@ -279,12 +186,7 @@ LOCAL_LABEL(No_Restore_CONTEXT_FLOATING_POINT): ldr x28, [x16, CONTEXT_X28] LOCAL_LABEL(No_Restore_CONTEXT_INTEGER): - movz w2, #0x40, lsl #16 - movk w2, #0x2 - mov w3, w2 - and w2, w1, w2 - cmp w2, w3 - b.ne LOCAL_LABEL(No_Restore_CONTEXT_CONTROL) + tbz w17, #CONTEXT_CONTROL_BIT, LOCAL_LABEL(No_Restore_CONTEXT_CONTROL) ldr w17, [x16, CONTEXT_Cpsr] msr nzcv, x17 @@ -293,8 +195,8 @@ LOCAL_LABEL(No_Restore_CONTEXT_INTEGER): mov sp, x17 ldr x17, [x16, CONTEXT_Pc] br x17 - + LOCAL_LABEL(No_Restore_CONTEXT_CONTROL): - ret + ret LEAF_END RtlRestoreContext, _TEXT diff --git a/src/pal/src/arch/arm64/exceptionhelper.S b/src/pal/src/arch/arm64/exceptionhelper.S index 4fdcfc5eb1..480846eb61 100644 --- a/src/pal/src/arch/arm64/exceptionhelper.S +++ b/src/pal/src/arch/arm64/exceptionhelper.S @@ -3,7 +3,30 @@ // See the LICENSE file in the project root for more information. #include "unixasmmacros.inc" +#include "asmconstants.h" +////////////////////////////////////////////////////////////////////////// +// +// This function creates a stack frame right below the target frame, restores all callee +// saved registers, SP, and LR from the passed in context. +// Then it uses the ThrowExceptionHelper to throw the passed in exception from that context. +// EXTERN_C void ThrowExceptionFromContextInternal(CONTEXT* context, PAL_SEHException* ex); LEAF_ENTRY ThrowExceptionFromContextInternal, _TEXT - EMIT_BREAKPOINT + // Save the FP & LR to the stack so that the unwind can work at the instruction after + // loading the FP from the context, but before loading the SP from the context. + stp fp, lr, [sp, -16]! + + ldp x19,x20, [x0, #(CONTEXT_X19)] + ldp x21,x22, [x0, #(CONTEXT_X21)] + ldp x23,x24, [x0, #(CONTEXT_X23)] + ldp x24,x25, [x0, #(CONTEXT_X24)] + ldp x26,x27, [x0, #(CONTEXT_X26)] + ldp x28,fp, [x0, #(CONTEXT_X28)] + ldr lr, [x0, #(CONTEXT_Pc)] + ldr x2, [x0, #(CONTEXT_Sp)] + mov sp, x2 + + // The PAL_SEHException pointer + mov x0, x1 + b EXTERNAL_C_FUNC(ThrowExceptionHelper) LEAF_END ThrowExceptionFromContextInternal, _TEXT diff --git a/src/pal/src/exception/seh-unwind.cpp b/src/pal/src/exception/seh-unwind.cpp index aeb6fa4b6a..1f20ee0cad 100644 --- a/src/pal/src/exception/seh-unwind.cpp +++ b/src/pal/src/exception/seh-unwind.cpp @@ -244,6 +244,7 @@ static void GetContextPointers(unw_cursor_t *cursor, unw_context_t *unwContext, GetContextPointer(cursor, unwContext, UNW_AARCH64_X26, &contextPointers->X26); GetContextPointer(cursor, unwContext, UNW_AARCH64_X27, &contextPointers->X27); GetContextPointer(cursor, unwContext, UNW_AARCH64_X28, &contextPointers->X28); + GetContextPointer(cursor, unwContext, UNW_AARCH64_X29, &contextPointers->Fp); #else #error unsupported architecture #endif diff --git a/src/pal/src/include/pal/context.h b/src/pal/src/include/pal/context.h index 6857c130ee..08fa05da7d 100644 --- a/src/pal/src/include/pal/context.h +++ b/src/pal/src/include/pal/context.h @@ -248,8 +248,7 @@ inline void *FPREG_Xstate_Ymmh(const ucontext_t *uc) #define MCREG_Sp(mc) ((mc).sp) #define MCREG_Pc(mc) ((mc).pc) -#define MCREG_PState(mc) ((mc).pstate) -#define MCREG_Cpsr(mc) ((mc).cpsr) +#define MCREG_Cpsr(mc) ((mc).pstate) #else // For FreeBSD, as found in x86/ucontext.h #define MCREG_Rbp(mc) ((mc).mc_rbp) diff --git a/src/pal/src/thread/context.cpp b/src/pal/src/thread/context.cpp index bee6ddd449..98867c9554 100644 --- a/src/pal/src/thread/context.cpp +++ b/src/pal/src/thread/context.cpp @@ -127,6 +127,8 @@ typedef int __ptrace_request; ASSIGN_REG(R12) #elif defined(_ARM64_) #define ASSIGN_CONTROL_REGS \ + ASSIGN_REG(Cpsr) \ + ASSIGN_REG(Fp) \ ASSIGN_REG(Sp) \ ASSIGN_REG(Lr) \ ASSIGN_REG(Pc) |