add_definitions(-DXSTATE_SUPPORTED)
endif()
set(PLATFORM_SOURCES
- arch/${PAL_ARCH_SOURCES_DIR}/activationhandlerwrapper.S
arch/${PAL_ARCH_SOURCES_DIR}/context.S
arch/${PAL_ARCH_SOURCES_DIR}/dispatchexceptionwrapper.S
exception/machexception.cpp
set(CMAKE_EXTRA_INCLUDE_FILES)
set(CMAKE_EXTRA_INCLUDE_FILES signal.h)
set(CMAKE_EXTRA_INCLUDE_FILES)
-set(CMAKE_EXTRA_INCLUDE_FILES ucontext.h)
+set(CMAKE_EXTRA_INCLUDE_FILES sys/ucontext.h)
check_type_size(ucontext_t UCONTEXT_T)
set(CMAKE_EXTRA_INCLUDE_FILES)
set(CMAKE_EXTRA_INCLUDE_FILES pthread.h)
return TRUE;
}
-extern "C"
-void
-ActivationHandler(CONTEXT* context)
-{
- if (g_activationFunction != NULL)
- {
- g_activationFunction(context);
- }
-
-#ifdef TARGET_ARM64
- // RtlRestoreContext assembly corrupts X16 & X17, so it cannot be
- // used for Activation restore
- MachSetThreadContext(context);
-#else
- RtlRestoreContext(context, NULL);
-#endif
- DebugBreak();
-}
-
-extern "C" void ActivationHandlerWrapper();
-extern "C" int ActivationHandlerReturnOffset;
-extern "C" unsigned int XmmYmmStateSupport();
-
-#if defined(HOST_AMD64)
-bool IsHardwareException(x86_exception_state64_t exceptionState)
-{
- static const int MaxHardwareExceptionVector = 31;
- return exceptionState.__trapno <= MaxHardwareExceptionVector;
-}
-#elif defined(HOST_ARM64)
-bool IsHardwareException(arm_exception_state64_t exceptionState)
-{
- // Infer exception state from the ESR_EL* register value.
- // Bits 31-26 represent the ESR.EC field
- const int ESR_EC_SHIFT = 26;
- const int ESR_EC_MASK = 0x3f;
- const int esr_ec = (exceptionState.__esr >> ESR_EC_SHIFT) & ESR_EC_MASK;
-
- const int ESR_EC_SVC = 0x15; // Supervisor Call exception from aarch64.
-
- // Assume only supervisor calls from aarch64 are not hardware exceptions
- return (esr_ec != ESR_EC_SVC);
-}
-#else
-#error Unexpected architecture
-#endif
-
-/*++
-Function :
- InjectActivationInternal
-
- Sets up the specified thread to call the ActivationHandler.
-
-Parameters:
- pThread - PAL thread instance
-
-Return value :
- PAL_ERROR
---*/
-PAL_ERROR
-InjectActivationInternal(CPalThread* pThread)
-{
- PAL_ERROR palError;
-
- mach_port_t threadPort = pThread->GetMachPortSelf();
-
- kern_return_t MachRet = SuspendMachThread(threadPort);
- palError = (MachRet == KERN_SUCCESS) ? NO_ERROR : ERROR_GEN_FAILURE;
-
- if (palError == NO_ERROR)
- {
-#if defined(HOST_AMD64)
- x86_exception_state64_t ExceptionState;
- const thread_state_flavor_t exceptionFlavor = x86_EXCEPTION_STATE64;
- const mach_msg_type_number_t exceptionCount = x86_EXCEPTION_STATE64_COUNT;
-
- x86_thread_state64_t ThreadState;
- const thread_state_flavor_t threadFlavor = x86_THREAD_STATE64;
- const mach_msg_type_number_t threadCount = x86_THREAD_STATE64_COUNT;
-#elif defined(HOST_ARM64)
- arm_exception_state64_t ExceptionState;
- const thread_state_flavor_t exceptionFlavor = ARM_EXCEPTION_STATE64;
- const mach_msg_type_number_t exceptionCount = ARM_EXCEPTION_STATE64_COUNT;
-
- arm_thread_state64_t ThreadState;
- const thread_state_flavor_t threadFlavor = ARM_THREAD_STATE64;
- const mach_msg_type_number_t threadCount = ARM_THREAD_STATE64_COUNT;
-#else
-#error Unexpected architecture
-#endif
- mach_msg_type_number_t count = exceptionCount;
-
- MachRet = thread_get_state(threadPort,
- exceptionFlavor,
- (thread_state_t)&ExceptionState,
- &count);
- _ASSERT_MSG(MachRet == KERN_SUCCESS, "thread_get_state for *_EXCEPTION_STATE64\n");
-
- // Inject the activation only if the thread doesn't have a pending hardware exception
- if (!IsHardwareException(ExceptionState))
- {
- count = threadCount;
- MachRet = thread_get_state(threadPort,
- threadFlavor,
- (thread_state_t)&ThreadState,
- &count);
- _ASSERT_MSG(MachRet == KERN_SUCCESS, "thread_get_state for *_THREAD_STATE64\n");
-
-#if defined(HOST_AMD64)
- if ((g_safeActivationCheckFunction != NULL) && g_safeActivationCheckFunction(ThreadState.__rip, /* checkingCurrentThread */ FALSE))
- {
- // TODO: it would be nice to preserve the red zone in case a jitter would want to use it
- // Do we really care about unwinding through the wrapper?
- size_t* sp = (size_t*)ThreadState.__rsp;
- *(--sp) = ThreadState.__rip;
- *(--sp) = ThreadState.__rbp;
- size_t rbpAddress = (size_t)sp;
-#elif defined(HOST_ARM64)
- if ((g_safeActivationCheckFunction != NULL) && g_safeActivationCheckFunction((size_t)arm_thread_state64_get_pc_fptr(ThreadState), /* checkingCurrentThread */ FALSE))
- {
- // TODO: it would be nice to preserve the red zone in case a jitter would want to use it
- // Do we really care about unwinding through the wrapper?
- size_t* sp = (size_t*)arm_thread_state64_get_sp(ThreadState);
- *(--sp) = (size_t)arm_thread_state64_get_pc_fptr(ThreadState);
- *(--sp) = arm_thread_state64_get_fp(ThreadState);
- size_t fpAddress = (size_t)sp;
-#else
-#error Unexpected architecture
-#endif
- size_t contextAddress = (((size_t)sp) - sizeof(CONTEXT)) & ~15;
-
- // Fill in the context in the helper frame with the full context of the suspended thread.
- // The ActivationHandler will use the context to resume the execution of the thread
- // after the activation function returns.
- CONTEXT *pContext = (CONTEXT *)contextAddress;
-#if defined(HOST_AMD64)
- pContext->ContextFlags = CONTEXT_FULL | CONTEXT_SEGMENTS;
-#else
- pContext->ContextFlags = CONTEXT_FULL;
-#endif
-#ifdef XSTATE_SUPPORTED
- if (XmmYmmStateSupport() == 1)
- {
- pContext->ContextFlags |= CONTEXT_XSTATE;
- }
-#endif
- MachRet = CONTEXT_GetThreadContextFromPort(threadPort, pContext);
- _ASSERT_MSG(MachRet == KERN_SUCCESS, "CONTEXT_GetThreadContextFromPort\n");
-
-#if defined(HOST_AMD64)
- size_t returnAddressAddress = contextAddress - sizeof(size_t);
- *(size_t*)(returnAddressAddress) = ActivationHandlerReturnOffset + (size_t)ActivationHandlerWrapper;
-
- // Make the instruction register point to ActivationHandler
- ThreadState.__rip = (size_t)ActivationHandler;
- ThreadState.__rsp = returnAddressAddress;
- ThreadState.__rbp = rbpAddress;
- ThreadState.__rdi = contextAddress;
-#elif defined(HOST_ARM64)
- // Make the call to ActivationHandler
- arm_thread_state64_set_lr_fptr(ThreadState, ActivationHandlerReturnOffset + (size_t)ActivationHandlerWrapper);
- arm_thread_state64_set_pc_fptr(ThreadState, ActivationHandler);
- arm_thread_state64_set_sp(ThreadState, contextAddress);
- arm_thread_state64_set_fp(ThreadState, fpAddress);
- ThreadState.__x[0] = contextAddress;
-#else
-#error Unexpected architecture
-#endif
-
- MachRet = thread_set_state(threadPort,
- threadFlavor,
- (thread_state_t)&ThreadState,
- threadCount);
- _ASSERT_MSG(MachRet == KERN_SUCCESS, "thread_set_state\n");
- }
- }
-
- MachRet = thread_resume(threadPort);
- palError = (MachRet == ERROR_SUCCESS) ? NO_ERROR : ERROR_GEN_FAILURE;
- }
- else
- {
- printf("Suspension failed with error 0x%x\n", palError);
- }
-
- return palError;
-}
-
#endif // HAVE_MACH_EXCEPTIONS
#include <unistd.h>
#include <sys/mman.h>
+
+#endif // !HAVE_MACH_EXCEPTIONS
#include "pal/context.h"
#ifdef SIGRTMIN
#define INJECT_ACTIVATION_SIGNAL SIGRTMIN
+#else
+#define INJECT_ACTIVATION_SIGNAL SIGUSR1
#endif
#if !defined(INJECT_ACTIVATION_SIGNAL) && defined(FEATURE_HIJACK)
#error FEATURE_HIJACK requires INJECT_ACTIVATION_SIGNAL to be defined
#endif
-#endif // !HAVE_MACH_EXCEPTIONS
using namespace CorUnix;
/* internal function declarations *********************************************/
static void sigterm_handler(int code, siginfo_t *siginfo, void *context);
+#ifdef INJECT_ACTIVATION_SIGNAL
+static void inject_activation_handler(int code, siginfo_t *siginfo, void *context);
+#endif
#if !HAVE_MACH_EXCEPTIONS
static void sigill_handler(int code, siginfo_t *siginfo, void *context);
static void sigfpe_handler(int code, siginfo_t *siginfo, void *context);
static bool common_signal_handler(int code, siginfo_t *siginfo, void *sigcontext, int numParams, ...);
-#ifdef INJECT_ACTIVATION_SIGNAL
-static void inject_activation_handler(int code, siginfo_t *siginfo, void *context);
-#endif
#endif // !HAVE_MACH_EXCEPTIONS
static void handle_signal(int signal_id, SIGFUNC sigfunc, struct sigaction *previousAction, int additionalFlags = 0, bool skipIgnored = false);
#endif // !HAVE_MACH_EXCEPTIONS
static bool g_registered_sigterm_handler = false;
+static bool g_registered_activation_handler = false;
struct sigaction g_previous_sigterm;
+#ifdef INJECT_ACTIVATION_SIGNAL
+struct sigaction g_previous_activation;
+#endif
+
#if !HAVE_MACH_EXCEPTIONS
struct sigaction g_previous_sigill;
struct sigaction g_previous_sigtrap;
struct sigaction g_previous_sigint;
struct sigaction g_previous_sigquit;
-#ifdef INJECT_ACTIVATION_SIGNAL
-struct sigaction g_previous_activation;
-#endif
-
// Offset of the local variable containing pointer to windows style context in the common_signal_handler function.
// This offset is relative to the frame pointer.
int g_common_signal_handler_context_locvar_offset = 0;
handle_signal(SIGINT, sigint_handler, &g_previous_sigint, 0 /* additionalFlags */, true /* skipIgnored */);
handle_signal(SIGQUIT, sigquit_handler, &g_previous_sigquit, 0 /* additionalFlags */, true /* skipIgnored */);
-#ifdef INJECT_ACTIVATION_SIGNAL
- handle_signal(INJECT_ACTIVATION_SIGNAL, inject_activation_handler, &g_previous_activation);
-#endif
if (!pthrCurrent->EnsureSignalAlternateStack())
{
return FALSE;
handle_signal(SIGTERM, sigterm_handler, &g_previous_sigterm);
}
+#ifdef INJECT_ACTIVATION_SIGNAL
+ handle_signal(INJECT_ACTIVATION_SIGNAL, inject_activation_handler, &g_previous_activation);
+ g_registered_activation_handler = true;
+#endif
+
return TRUE;
}
restore_signal(SIGSEGV, &g_previous_sigsegv);
restore_signal(SIGINT, &g_previous_sigint);
restore_signal(SIGQUIT, &g_previous_sigquit);
+ }
+#endif // !HAVE_MACH_EXCEPTIONS
+
#ifdef INJECT_ACTIVATION_SIGNAL
+ if (g_registered_activation_handler)
+ {
restore_signal(INJECT_ACTIVATION_SIGNAL, &g_previous_activation);
-#endif
}
-#endif // !HAVE_MACH_EXCEPTIONS
+#endif
if (g_registered_sigterm_handler)
{
}
}
-#if !HAVE_MACH_EXCEPTIONS
#ifdef INJECT_ACTIVATION_SIGNAL
/*++
Function :
static void inject_activation_handler(int code, siginfo_t *siginfo, void *context)
{
// Only accept activations from the current process
- if (g_activationFunction != NULL && siginfo->si_pid == getpid())
+ if (g_activationFunction != NULL && (siginfo->si_pid == getpid()
+#ifdef HOST_OSX
+ // On OSX si_pid is sometimes 0. It was confirmed by Apple to be expected, as the si_pid is tracked at the process level. So when multiple
+ // signals are in flight in the same process at the same time, it may be overwritten / zeroed.
+ || siginfo->si_pid == 0
+#endif
+ ))
{
_ASSERTE(g_safeActivationCheckFunction != NULL);
CONTEXTFromNativeContext(
ucontext,
&winContext,
- CONTEXT_CONTROL | CONTEXT_INTEGER | CONTEXT_FLOATING_POINT);
+ CONTEXT_CONTROL | CONTEXT_INTEGER);
if (g_safeActivationCheckFunction(CONTEXTGetPC(&winContext), /* checkingCurrentThread */ TRUE))
{
#endif
}
+#if !HAVE_MACH_EXCEPTIONS
+
/*++
Function :
signal_ignore_handler
#include <signal.h>
#include <pthread.h>
-#if !HAVE_MACH_EXCEPTIONS
/* A type to wrap the native context type, which is ucontext_t on some
* platforms and another type elsewhere. */
#if HAVE_UCONTEXT_T
-#include <ucontext.h>
+#include <sys/ucontext.h>
typedef ucontext_t native_context_t;
#else // HAVE_UCONTEXT_T
#error Native context type is not known on this platform!
#endif // HAVE_UCONTEXT_T
+#if !HAVE_MACH_EXCEPTIONS
+
#if defined(XSTATE_SUPPORTED) && !HAVE_PUBLIC_XSTATE_STRUCT
namespace asm_sigcontext
{
#ifdef HOST_64BIT
#if defined(HOST_ARM64)
+
+#ifndef TARGET_OSX
+
#define MCREG_X0(mc) ((mc).regs[0])
#define MCREG_X1(mc) ((mc).regs[1])
#define MCREG_X2(mc) ((mc).regs[2])
#define MCREG_Cpsr(mc) ((mc).pstate)
-#ifndef TARGET_OSX
inline
fpsimd_context* GetNativeSigSimdContext(native_context_t *mc)
{
return GetNativeSigSimdContext(const_cast<native_context_t*>(mc));
}
+#else // TARGET_OSX
+
+#define MCREG_X0(mc) ((mc)->__ss.__x[0])
+#define MCREG_X1(mc) ((mc)->__ss.__x[1])
+#define MCREG_X2(mc) ((mc)->__ss.__x[2])
+#define MCREG_X3(mc) ((mc)->__ss.__x[3])
+#define MCREG_X4(mc) ((mc)->__ss.__x[4])
+#define MCREG_X5(mc) ((mc)->__ss.__x[5])
+#define MCREG_X6(mc) ((mc)->__ss.__x[6])
+#define MCREG_X7(mc) ((mc)->__ss.__x[7])
+#define MCREG_X8(mc) ((mc)->__ss.__x[8])
+#define MCREG_X9(mc) ((mc)->__ss.__x[9])
+#define MCREG_X10(mc) ((mc)->__ss.__x[10])
+#define MCREG_X11(mc) ((mc)->__ss.__x[11])
+#define MCREG_X12(mc) ((mc)->__ss.__x[12])
+#define MCREG_X13(mc) ((mc)->__ss.__x[13])
+#define MCREG_X14(mc) ((mc)->__ss.__x[14])
+#define MCREG_X15(mc) ((mc)->__ss.__x[15])
+#define MCREG_X16(mc) ((mc)->__ss.__x[16])
+#define MCREG_X17(mc) ((mc)->__ss.__x[17])
+#define MCREG_X18(mc) ((mc)->__ss.__x[18])
+#define MCREG_X19(mc) ((mc)->__ss.__x[19])
+#define MCREG_X20(mc) ((mc)->__ss.__x[20])
+#define MCREG_X21(mc) ((mc)->__ss.__x[21])
+#define MCREG_X22(mc) ((mc)->__ss.__x[22])
+#define MCREG_X23(mc) ((mc)->__ss.__x[23])
+#define MCREG_X24(mc) ((mc)->__ss.__x[24])
+#define MCREG_X25(mc) ((mc)->__ss.__x[25])
+#define MCREG_X26(mc) ((mc)->__ss.__x[26])
+#define MCREG_X27(mc) ((mc)->__ss.__x[27])
+#define MCREG_X28(mc) ((mc)->__ss.__x[28])
+#define MCREG_Fp(mc) ((mc)->__ss.__fp)
+#define MCREG_Lr(mc) ((mc)->__ss.__lr)
+
+#define MCREG_Sp(mc) ((mc)->__ss.__sp)
+#define MCREG_Pc(mc) ((mc)->__ss.__pc)
+#define MCREG_Cpsr(mc) ((mc)->__ss.__cpsr)
+
+inline
+_STRUCT_ARM_NEON_STATE64* GetNativeSigSimdContext(native_context_t *mc)
+{
+ return &(mc)->uc_mcontext->__ns;
+}
+
+inline
+const _STRUCT_ARM_NEON_STATE64* GetConstNativeSigSimdContext(const native_context_t *mc)
+{
+ return GetNativeSigSimdContext(const_cast<native_context_t*>(mc));
+}
+
#endif // TARGET_OSX
#else // HOST_ARM64
+
+#ifdef TARGET_OSX
+
+#define MCREG_Rbp(mc) ((mc)->__ss.__rbp)
+#define MCREG_Rip(mc) ((mc)->__ss.__rip)
+#define MCREG_Rsp(mc) ((mc)->__ss.__rsp)
+#define MCREG_Rsi(mc) ((mc)->__ss.__rsi)
+#define MCREG_Rdi(mc) ((mc)->__ss.__rdi)
+#define MCREG_Rbx(mc) ((mc)->__ss.__rbx)
+#define MCREG_Rdx(mc) ((mc)->__ss.__rdx)
+#define MCREG_Rcx(mc) ((mc)->__ss.__rcx)
+#define MCREG_Rax(mc) ((mc)->__ss.__rax)
+#define MCREG_R8(mc) ((mc)->__ss.__r8)
+#define MCREG_R9(mc) ((mc)->__ss.__r9)
+#define MCREG_R10(mc) ((mc)->__ss.__r10)
+#define MCREG_R11(mc) ((mc)->__ss.__r11)
+#define MCREG_R12(mc) ((mc)->__ss.__r12)
+#define MCREG_R13(mc) ((mc)->__ss.__r13)
+#define MCREG_R14(mc) ((mc)->__ss.__r14)
+#define MCREG_R15(mc) ((mc)->__ss.__r15)
+#define MCREG_EFlags(mc) ((mc)->__ss.__rflags)
+#define MCREG_SegCs(mc) ((mc)->__ss.__cs)
+
+#define FPSTATE(uc) ((uc)->uc_mcontext->__fs)
+#define FPREG_ControlWord(uc) *((WORD*)&FPSTATE(uc).__fpu_fcw)
+#define FPREG_StatusWord(uc) *((WORD*)&FPSTATE(uc).__fpu_fsw)
+#define FPREG_TagWord(uc) FPSTATE(uc).__fpu_ftw
+#define FPREG_MxCsr(uc) FPSTATE(uc).__fpu_mxcsr
+#define FPREG_MxCsr_Mask(uc) FPSTATE(uc).__fpu_mxcsrmask
+#define FPREG_ErrorOffset(uc) *(DWORD*) &(FPSTATE(uc).__fpu_ip)
+#define FPREG_ErrorSelector(uc) *((WORD*) &(FPSTATE(uc).__fpu_ip) + 2)
+#define FPREG_DataOffset(uc) *(DWORD*) &(FPSTATE(uc).__fpu_dp)
+#define FPREG_DataSelector(uc) *((WORD*) &(FPSTATE(uc).__fpu_dp) + 2)
+
+#define FPREG_Xmm(uc, index) *(M128A*) &((&FPSTATE(uc).__fpu_xmm0)[index])
+#define FPREG_St(uc, index) *(M128A*) &((&FPSTATE(uc).__fpu_stmm0)[index]) //.fp_acc)
+
+inline bool FPREG_HasYmmRegisters(const ucontext_t *uc)
+{
+ _ASSERTE((uc->uc_mcsize == sizeof(_STRUCT_MCONTEXT_AVX64)) || (uc->uc_mcsize == sizeof(_STRUCT_MCONTEXT_AVX512_64)));
+ return (uc->uc_mcsize == sizeof(_STRUCT_MCONTEXT_AVX64)) || (uc->uc_mcsize == sizeof(_STRUCT_MCONTEXT_AVX512_64));
+}
+
+static_assert_no_msg(offsetof(_STRUCT_X86_AVX_STATE64, __fpu_ymmh0) == offsetof(_STRUCT_X86_AVX512_STATE64, __fpu_ymmh0));
+inline void *FPREG_Xstate_Ymmh(const ucontext_t *uc)
+{
+ return reinterpret_cast<void *>(&((_STRUCT_X86_AVX_STATE64&)FPSTATE(uc)).__fpu_ymmh0);
+}
+
+#else //TARGET_OSX
+
// For FreeBSD, as found in x86/ucontext.h
#define MCREG_Rbp(mc) ((mc).mc_rbp)
#define MCREG_Rip(mc) ((mc).mc_rip)
#define FPREG_Xmm(uc, index) *(M128A*) &(FPSTATE(uc)->sv_xmm[index])
#define FPREG_St(uc, index) *(M128A*) &(FPSTATE(uc)->sv_fp[index].fp_acc)
-#endif
+#endif // TARGET_OSX
+#endif // HOST_ARM64
#else // HOST_64BIT
thread_state_t threadState,
LPCONTEXT lpContext);
-#else // HAVE_MACH_EXCEPTIONS
+#endif // HAVE_MACH_EXCEPTIONS
+
/*++
Function :
CONTEXTToNativeContext
void CONTEXTFromNativeContext(const native_context_t *native, LPCONTEXT lpContext,
ULONG contextFlags);
+#if !HAVE_MACH_EXCEPTIONS
+
/*++
Function :
GetNativeContextPC
#include <asm/ptrace.h>
#endif // HAVE_PT_REGS
+#endif // !HAVE_MACH_EXCEPTIONS
+
#ifdef HOST_AMD64
#define ASSIGN_CONTROL_REGS \
ASSIGN_REG(Rbp) \
ASSIGN_CONTROL_REGS \
ASSIGN_INTEGER_REGS \
+#if !HAVE_MACH_EXCEPTIONS
+
/*++
Function:
CONTEXT_GetRegisters
return ret;
}
+#endif // !HAVE_MACH_EXCEPTIONS
+
/*++
Function :
CONTEXTToNativeContext
FPREG_Xmm(native, i) = lpContext->FltSave.XmmRegisters[i];
}
#elif defined(HOST_ARM64)
+#ifdef TARGET_OSX
+ _STRUCT_ARM_NEON_STATE64* fp = GetNativeSigSimdContext(native);
+ fp->__fpsr = lpContext->Fpsr;
+ fp->__fpcr = lpContext->Fpcr;
+ for (int i = 0; i < 32; i++)
+ {
+ *(NEON128*) &fp->__v[i] = lpContext->V[i];
+ }
+#else // TARGET_OSX
fpsimd_context* fp = GetNativeSigSimdContext(native);
if (fp)
{
*(NEON128*) &fp->vregs[i] = lpContext->V[i];
}
}
+#endif // TARGET_OSX
#elif defined(HOST_ARM)
VfpSigFrame* fp = GetNativeSigSimdContext(native);
if (fp)
lpContext->FltSave.XmmRegisters[i] = FPREG_Xmm(native, i);
}
#elif defined(HOST_ARM64)
+#ifdef TARGET_OSX
+ const _STRUCT_ARM_NEON_STATE64* fp = GetConstNativeSigSimdContext(native);
+ lpContext->Fpsr = fp->__fpsr;
+ lpContext->Fpcr = fp->__fpcr;
+ for (int i = 0; i < 32; i++)
+ {
+ lpContext->V[i] = *(NEON128*) &fp->__v[i];
+ }
+#else // TARGET_OSX
const fpsimd_context* fp = GetConstNativeSigSimdContext(native);
if (fp)
{
lpContext->V[i] = *(NEON128*) &fp->vregs[i];
}
}
+#endif // TARGET_OSX
#elif defined(HOST_ARM)
const VfpSigFrame* fp = GetConstNativeSigSimdContext(native);
if (fp)
#endif // HOST_AMD64
}
+#if !HAVE_MACH_EXCEPTIONS
+
/*++
Function :
GetNativeContextPC