From 1c1083e667b30c4a9f14992e891e0500256de09f Mon Sep 17 00:00:00 2001 From: Steve MacLean Date: Mon, 3 Aug 2020 15:19:00 -0700 Subject: [PATCH 01/89] Add initial CoreCLR compilation support for Apple Silicon Initial draft of CoreCLR runtime native code to supprt Apple Silicon Fixes native runtime compitation issues Draft implementation Testing linited to compilation on Apple Does not fix Arm64 ABI issues Does not fix write no execute issues --- src/coreclr/src/debug/createdump/mac.h | 20 ++ .../src/debug/createdump/memoryregion.h | 2 +- .../src/debug/createdump/threadinfomac.cpp | 33 +++ src/coreclr/src/debug/ee/arm64/dbghelpers.S | 4 +- src/coreclr/src/gc/unix/gcenv.unix.cpp | 2 +- src/coreclr/src/pal/inc/pal.h | 4 + .../src/pal/inc/unixasmmacrosarm64.inc | 29 +- src/coreclr/src/pal/src/CMakeLists.txt | 29 +- .../src/arch/arm64/activationhandlerwrapper.S | 22 ++ .../src/pal/src/arch/arm64/asmconstants.h | 1 + src/coreclr/src/pal/src/arch/arm64/context.S | 15 + .../src/arch/arm64/dispatchexceptionwrapper.S | 49 ++++ .../src/pal/src/exception/machexception.cpp | 277 ++++++++++++++++-- .../src/pal/src/exception/machmessage.cpp | 14 + .../src/pal/src/exception/machmessage.h | 9 +- .../src/pal/src/exception/remote-unwind.cpp | 119 +++++++- .../src/pal/src/exception/seh-unwind.cpp | 41 ++- src/coreclr/src/pal/src/include/pal/context.h | 5 +- .../src/libunwind_mac/src/missing-functions.c | 6 + src/coreclr/src/pal/src/misc/sysinfo.cpp | 4 +- src/coreclr/src/pal/src/thread/context.cpp | 71 ++++- src/coreclr/src/vm/arm64/asmhelpers.S | 38 +-- src/coreclr/src/vm/arm64/pinvokestubs.S | 6 +- 23 files changed, 717 insertions(+), 83 deletions(-) create mode 100644 src/coreclr/src/pal/src/arch/arm64/activationhandlerwrapper.S create mode 100644 src/coreclr/src/pal/src/arch/arm64/context.S create mode 100644 src/coreclr/src/pal/src/arch/arm64/dispatchexceptionwrapper.S diff --git a/src/coreclr/src/debug/createdump/mac.h b/src/coreclr/src/debug/createdump/mac.h index 16b198e935514..48ab16cb84c99 100644 --- a/src/coreclr/src/debug/createdump/mac.h +++ b/src/coreclr/src/debug/createdump/mac.h @@ -68,6 +68,7 @@ typedef struct elf64_note { Elf64_Word n_type; /* Content type */ } Elf64_Nhdr; +#if defined(TARGET_AMD64) || defined(TARGET_X86) struct user_fpregs_struct { unsigned short int cwd; @@ -113,6 +114,25 @@ struct user_regs_struct unsigned long long int fs; unsigned long long int gs; }; +#elif defined(TARGET_ARM64) +struct user_fpsimd_struct +{ + uint64_t vregs[2*32]; + uint32_t fpcr; + uint32_t fpsr; +}; + +struct user_regs_struct +{ + uint64_t regs[31]; + uint64_t sp; + uint64_t pc; + uint32_t pstate; +}; +#else +#error Unexpected architecture +#endif + typedef pid_t __pid_t; diff --git a/src/coreclr/src/debug/createdump/memoryregion.h b/src/coreclr/src/debug/createdump/memoryregion.h index c3085108ac7ca..21a19f349164b 100644 --- a/src/coreclr/src/debug/createdump/memoryregion.h +++ b/src/coreclr/src/debug/createdump/memoryregion.h @@ -1,7 +1,7 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -#if defined(__arm__) || defined(__aarch64__) +#if !defined(PAGE_SIZE) && (defined(__arm__) || defined(__aarch64__)) #define PAGE_SIZE sysconf(_SC_PAGESIZE) #endif diff --git a/src/coreclr/src/debug/createdump/threadinfomac.cpp b/src/coreclr/src/debug/createdump/threadinfomac.cpp index a33395f41dad8..d17eed24bc98f 100644 --- a/src/coreclr/src/debug/createdump/threadinfomac.cpp +++ b/src/coreclr/src/debug/createdump/threadinfomac.cpp @@ -25,6 +25,7 @@ ThreadInfo::Initialize() m_ppid = 0; m_tgid = 0; +#if defined(TARGET_AMD64) || defined(TARGET_X86) x86_thread_state64_t state; mach_msg_type_number_t stateCount = x86_THREAD_STATE64_COUNT; kern_return_t result = ::thread_get_state(Port(), x86_THREAD_STATE64, (thread_state_t)&state, &stateCount); @@ -88,6 +89,38 @@ ThreadInfo::Initialize() memcpy(m_fpRegisters.st_space, &fpstate.__fpu_stmm0, sizeof(m_fpRegisters.st_space)); memcpy(m_fpRegisters.xmm_space, &fpstate.__fpu_xmm0, sizeof(m_fpRegisters.xmm_space)); +#elif defined(TARGET_ARM64) + arm_thread_state64_t state; + mach_msg_type_number_t stateCount = ARM_THREAD_STATE64_COUNT; + kern_return_t result = ::thread_get_state(Port(), ARM_THREAD_STATE64, (thread_state_t)&state, &stateCount); + if (result != KERN_SUCCESS) + { + fprintf(stderr, "thread_get_state(%x) FAILED %x %s\n", m_tid, result, mach_error_string(result)); + return false; + } + + memcpy(m_gpRegisters.regs, &state.__x, sizeof(state.__x)); + m_gpRegisters.regs[29] = arm_thread_state64_get_fp(state); + m_gpRegisters.regs[30] = arm_thread_state64_get_lr(state); + + m_gpRegisters.sp = arm_thread_state64_get_sp(state); + m_gpRegisters.pc = arm_thread_state64_get_pc(state); + + arm_neon_state64_t fpstate; + stateCount = ARM_NEON_STATE64_COUNT; + result = ::thread_get_state(Port(), ARM_NEON_STATE64, (thread_state_t)&fpstate, &stateCount); + if (result != KERN_SUCCESS) + { + fprintf(stderr, "thread_get_state(%x) FAILED %x %s\n", m_tid, result, mach_error_string(result)); + return false; + } + + memcpy(m_fpRegisters.vregs, &fpstate.__v, sizeof(m_fpRegisters.vregs)); + m_fpRegisters.fpsr = fpstate.__fpsr; + m_fpRegisters.fpcr = fpstate.__fpcr; +#else +#error Unexpected architecture +#endif return true; } diff --git a/src/coreclr/src/debug/ee/arm64/dbghelpers.S b/src/coreclr/src/debug/ee/arm64/dbghelpers.S index 8fc88fa257350..4b9504efec859 100644 --- a/src/coreclr/src/debug/ee/arm64/dbghelpers.S +++ b/src/coreclr/src/debug/ee/arm64/dbghelpers.S @@ -22,7 +22,7 @@ NESTED_ENTRY FuncEvalHijack, _TEXT, UnhandledExceptionHandlerUnix PROLOG_SAVE_REG_PAIR_INDEXED fp, lr, -32 str x0, [sp, #16] // FuncEvalHijackWorker returns the address we should jump to. - bl FuncEvalHijackWorker + bl C_FUNC(FuncEvalHijackWorker) EPILOG_STACK_FREE 32 EPILOG_BRANCH_REG x0 @@ -33,7 +33,7 @@ NESTED_END FuncEvalHijack NESTED_ENTRY ExceptionHijack, _TEXT, UnhandledExceptionHandlerUnix // make the call - bl ExceptionHijackWorker + bl C_FUNC(ExceptionHijackWorker) // effective NOP to terminate unwind mov x3, x3 diff --git a/src/coreclr/src/gc/unix/gcenv.unix.cpp b/src/coreclr/src/gc/unix/gcenv.unix.cpp index 76a9efaf36e56..eb62f4293dcaf 100644 --- a/src/coreclr/src/gc/unix/gcenv.unix.cpp +++ b/src/coreclr/src/gc/unix/gcenv.unix.cpp @@ -834,7 +834,7 @@ static size_t GetLogicalProcessorCacheSizeFromOS() cacheSize = std::max(cacheSize, ( size_t) sysconf(_SC_LEVEL4_CACHE_SIZE)); #endif -#if defined(HOST_ARM64) +#if defined(HOST_ARM64) && !defined(TARGET_OSX) if (cacheSize == 0) { size_t size; diff --git a/src/coreclr/src/pal/inc/pal.h b/src/coreclr/src/pal/inc/pal.h index fd56fc90c3535..e3223ba7d4858 100644 --- a/src/coreclr/src/pal/inc/pal.h +++ b/src/coreclr/src/pal/inc/pal.h @@ -2078,6 +2078,10 @@ typedef struct _IMAGE_ARM_RUNTIME_FUNCTION_ENTRY { #define CONTEXT_FLOATING_POINT (CONTEXT_ARM64 | 0x4L) #define CONTEXT_DEBUG_REGISTERS (CONTEXT_ARM64 | 0x8L) +// There is no segment context for Arm64 +#define CONTEXT_SEGMENTS (0) + + #define CONTEXT_FULL (CONTEXT_CONTROL | CONTEXT_INTEGER | CONTEXT_FLOATING_POINT) #define CONTEXT_ALL (CONTEXT_CONTROL | CONTEXT_INTEGER | CONTEXT_FLOATING_POINT | CONTEXT_DEBUG_REGISTERS) diff --git a/src/coreclr/src/pal/inc/unixasmmacrosarm64.inc b/src/coreclr/src/pal/inc/unixasmmacrosarm64.inc index 69cdcb3f48ba5..faacbb90ea089 100644 --- a/src/coreclr/src/pal/inc/unixasmmacrosarm64.inc +++ b/src/coreclr/src/pal/inc/unixasmmacrosarm64.inc @@ -4,12 +4,25 @@ .macro NESTED_ENTRY Name, Section, Handler LEAF_ENTRY \Name, \Section .ifnc \Handler, NoHandler +#if defined(__APPLE__) + .cfi_personality 0x9b, C_FUNC(\Handler) // 0x9b == DW_EH_PE_indirect | DW_EH_PE_pcrel | DW_EH_PE_sdata4 +#else .cfi_personality 0x1b, C_FUNC(\Handler) // 0x1b == DW_EH_PE_pcrel | DW_EH_PE_sdata4 +#endif .endif .endm .macro NESTED_END Name, Section LEAF_END \Name, \Section +#if defined(__APPLE__) + .set LOCAL_LABEL(\Name\()_Size), . - C_FUNC(\Name) + .section __LD,__compact_unwind,regular,debug + .quad C_FUNC(\Name) + .long LOCAL_LABEL(\Name\()_Size) + .long 0x04000000 // DWARF + .quad 0 + .quad 0 +#endif .endm .macro PATCH_LABEL Name @@ -19,13 +32,20 @@ C_FUNC(\Name): .macro LEAF_ENTRY Name, Section .global C_FUNC(\Name) +#if defined(__APPLE__) + .text + .p2align 2 +#else .type \Name, %function +#endif C_FUNC(\Name): .cfi_startproc .endm .macro LEAF_END Name, Section +#if !defined(__APPLE__) .size \Name, .-\Name +#endif .cfi_endproc .endm @@ -36,8 +56,13 @@ C_FUNC(\Name\()_End): .endm .macro PREPARE_EXTERNAL_VAR Name, HelperReg - adrp \HelperReg, \Name - add \HelperReg, \HelperReg, :lo12:\Name +#if defined(__APPLE__) + adrp \HelperReg, C_FUNC(\Name)@GOTPAGE + ldr \HelperReg, [\HelperReg, C_FUNC(\Name)@GOTPAGEOFF] +#else + adrp \HelperReg, C_FUNC(\Name) + add \HelperReg, \HelperReg, :lo12:C_FUNC(\Name) +#endif .endm .macro PROLOG_STACK_ALLOC Size diff --git a/src/coreclr/src/pal/src/CMakeLists.txt b/src/coreclr/src/pal/src/CMakeLists.txt index 712dabf46a3e6..45ec15efa7d33 100644 --- a/src/coreclr/src/pal/src/CMakeLists.txt +++ b/src/coreclr/src/pal/src/CMakeLists.txt @@ -41,17 +41,29 @@ include_directories(include) # Compile options +if(CLR_CMAKE_HOST_ARCH_AMD64) + set(PAL_ARCH_SOURCES_DIR amd64) +elseif(CLR_CMAKE_HOST_ARCH_ARM) + set(PAL_ARCH_SOURCES_DIR arm) +elseif(CLR_CMAKE_HOST_ARCH_ARM64) + set(PAL_ARCH_SOURCES_DIR arm64) +elseif(CLR_CMAKE_HOST_ARCH_I386) + set(PAL_ARCH_SOURCES_DIR i386) +endif() + if(CLR_CMAKE_USE_SYSTEM_LIBUNWIND) add_definitions(-DFEATURE_USE_SYSTEM_LIBUNWIND) endif(CLR_CMAKE_USE_SYSTEM_LIBUNWIND) if(CLR_CMAKE_TARGET_OSX) add_definitions(-DTARGET_OSX) - add_definitions(-DXSTATE_SUPPORTED) + if(CLR_CMAKE_TARGET_ARCH_AMD64) + add_definitions(-DXSTATE_SUPPORTED) + endif() set(PLATFORM_SOURCES - arch/amd64/activationhandlerwrapper.S - arch/amd64/context.S - arch/amd64/dispatchexceptionwrapper.S + arch/${PAL_ARCH_SOURCES_DIR}/activationhandlerwrapper.S + arch/${PAL_ARCH_SOURCES_DIR}/context.S + arch/${PAL_ARCH_SOURCES_DIR}/dispatchexceptionwrapper.S exception/machexception.cpp exception/machmessage.cpp ) @@ -64,15 +76,6 @@ add_definitions(-DLP64COMPATIBLE) add_definitions(-DCORECLR) add_definitions(-DPIC) add_definitions(-D_FILE_OFFSET_BITS=64) -if(CLR_CMAKE_HOST_ARCH_AMD64) - set(PAL_ARCH_SOURCES_DIR amd64) -elseif(CLR_CMAKE_HOST_ARCH_ARM) - set(PAL_ARCH_SOURCES_DIR arm) -elseif(CLR_CMAKE_HOST_ARCH_ARM64) - set(PAL_ARCH_SOURCES_DIR arm64) -elseif(CLR_CMAKE_HOST_ARCH_I386) - set(PAL_ARCH_SOURCES_DIR i386) -endif() if(CLR_CMAKE_HOST_ARCH_AMD64 AND CLR_CMAKE_TARGET_LINUX AND NOT CLR_CMAKE_HOST_ALPINE_LINUX) # Currently the _xstate is not available on Alpine Linux diff --git a/src/coreclr/src/pal/src/arch/arm64/activationhandlerwrapper.S b/src/coreclr/src/pal/src/arch/arm64/activationhandlerwrapper.S new file mode 100644 index 0000000000000..240757fa506e2 --- /dev/null +++ b/src/coreclr/src/pal/src/arch/arm64/activationhandlerwrapper.S @@ -0,0 +1,22 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +#include "unixasmmacros.inc" +#include "asmconstants.h" + +// Offset of the return address from the ActivationHandler in the ActivationHandlerWrapper +.globl C_FUNC(ActivationHandlerReturnOffset) +C_FUNC(ActivationHandlerReturnOffset): + .int LOCAL_LABEL(ActivationHandlerReturn)-C_FUNC(ActivationHandlerWrapper) + +NESTED_ENTRY ActivationHandlerWrapper, _TEXT, NoHandler + PROLOG_SAVE_REG_PAIR_INDEXED fp, lr, -(16 + CONTEXT_Size) + // Should never actually run + EMIT_BREAKPOINT + bl EXTERNAL_C_FUNC(ActivationHandler) +LOCAL_LABEL(ActivationHandlerReturn): + // Should never return + EMIT_BREAKPOINT + EPILOG_RESTORE_REG_PAIR_INDEXED fp, lr, (16 + CONTEXT_Size) + ret +NESTED_END ActivationHandlerWrapper, _TEXT diff --git a/src/coreclr/src/pal/src/arch/arm64/asmconstants.h b/src/coreclr/src/pal/src/arch/arm64/asmconstants.h index ad7d09e6efbbf..a657b8e5eb1c5 100644 --- a/src/coreclr/src/pal/src/arch/arm64/asmconstants.h +++ b/src/coreclr/src/pal/src/arch/arm64/asmconstants.h @@ -90,5 +90,6 @@ #define CONTEXT_FLOAT_CONTROL_OFFSET CONTEXT_V31+16 #define CONTEXT_Fpcr 0 #define CONTEXT_Fpsr CONTEXT_Fpcr+8 +#define CONTEXT_Size ((CONTEXT_NEON_OFFSET + CONTEXT_Fpsr + 8 + 0xf) & ~0xf) #endif diff --git a/src/coreclr/src/pal/src/arch/arm64/context.S b/src/coreclr/src/pal/src/arch/arm64/context.S new file mode 100644 index 0000000000000..1323c72fa2ca1 --- /dev/null +++ b/src/coreclr/src/pal/src/arch/arm64/context.S @@ -0,0 +1,15 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +#include "unixasmmacros.inc" + +#if defined(_DEBUG) +NESTED_ENTRY DBG_CheckStackAlignment, _TEXT, NoHandler + PROLOG_SAVE_REG_PAIR_INDEXED fp, lr, -16 + // Reading from an unaligned stack pointer will trigger a stack alignment fault + ldr x0, [sp] + EPILOG_RESTORE_REG_PAIR_INDEXED fp, lr, 16 + ret +NESTED_END _DBG_CheckStackAlignment, _TEXT +#endif + diff --git a/src/coreclr/src/pal/src/arch/arm64/dispatchexceptionwrapper.S b/src/coreclr/src/pal/src/arch/arm64/dispatchexceptionwrapper.S new file mode 100644 index 0000000000000..c7989377758f7 --- /dev/null +++ b/src/coreclr/src/pal/src/arch/arm64/dispatchexceptionwrapper.S @@ -0,0 +1,49 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +// ==++== +// + +// ==--== +// +// Implementation of the PAL_DispatchExceptionWrapper that is +// interposed between a function that caused a hardware fault +// and PAL_DispatchException that throws an SEH exception for +// the fault, to make the stack unwindable. +// + +#include "unixasmmacros.inc" + +// Offset of the return address from the PAL_DispatchException in the PAL_DispatchExceptionWrapper +.globl C_FUNC(PAL_DispatchExceptionReturnOffset) +C_FUNC(PAL_DispatchExceptionReturnOffset): + .int LOCAL_LABEL(PAL_DispatchExceptionReturn) - C_FUNC(PAL_DispatchExceptionWrapper) + +// +// PAL_DispatchExceptionWrapper will never be called; it only serves +// to be referenced from a stack frame on the faulting thread. Its +// unwinding behavior is equivalent to any standard function. +// It is analogous to the following source file. +// +// extern "C" void PAL_DispatchException(CONTEXT *pContext, EXCEPTION_RECORD *pExceptionRecord, MachExceptionInfo *pMachExceptionInfo); +// +// extern "C" void PAL_DispatchExceptionWrapper() +// { +// CONTEXT Context; +// EXCEPTION_RECORD ExceptionRecord; +// MachExceptionInfo MachExceptionInfo; +// PAL_DispatchException(&Context, &ExceptionRecord, &MachExceptionInfo); +// } +// + +NESTED_ENTRY PAL_DispatchExceptionWrapper, _TEXT, NoHandler + PROLOG_SAVE_REG_PAIR_INDEXED fp, lr, -16 + // Should never actually run + EMIT_BREAKPOINT + bl EXTERNAL_C_FUNC(PAL_DispatchException) +LOCAL_LABEL(PAL_DispatchExceptionReturn): + // Should never return + EMIT_BREAKPOINT + EPILOG_RESTORE_REG_PAIR_INDEXED fp, lr, 16 + ret +NESTED_END PAL_DispatchExceptionWrapper, _TEXT diff --git a/src/coreclr/src/pal/src/exception/machexception.cpp b/src/coreclr/src/pal/src/exception/machexception.cpp index de50fd6be99da..b045fb47ae33f 100644 --- a/src/coreclr/src/pal/src/exception/machexception.cpp +++ b/src/coreclr/src/pal/src/exception/machexception.cpp @@ -356,11 +356,16 @@ PAL_ERROR CorUnix::CPalThread::DisableMachExceptions() return palError; } +#if defined(HOST_AMD64) || defined(HOST_X86) // Since HijackFaultingThread pushed the context, exception record and info on the stack, we need to adjust the // signature of PAL_DispatchException such that the corresponding arguments are considered to be on the stack // per GCC64 calling convention rules. Hence, the first 6 dummy arguments (corresponding to RDI, RSI, RDX,RCX, R8, R9). extern "C" void PAL_DispatchException(DWORD64 dwRDI, DWORD64 dwRSI, DWORD64 dwRDX, DWORD64 dwRCX, DWORD64 dwR8, DWORD64 dwR9, PCONTEXT pContext, PEXCEPTION_RECORD pExRecord, MachExceptionInfo *pMachExceptionInfo) +#elif defined(HOST_ARM64) +extern "C" +void PAL_DispatchException(PCONTEXT pContext, PEXCEPTION_RECORD pExRecord, MachExceptionInfo *pMachExceptionInfo) +#endif { CPalThread *pThread = InternalGetCurrentThread(); @@ -441,12 +446,36 @@ BuildExceptionRecord( } else { +#if defined(HOST_AMD64) || defined(HOST_X86) exceptionCode = EXCEPTION_ACCESS_VIOLATION; +#elif defined(HOST_ARM64) + switch (exceptionInfo.Subcodes[0]) + { + case EXC_ARM_DA_ALIGN: + exceptionCode = EXCEPTION_DATATYPE_MISALIGNMENT; + break; + case EXC_ARM_DA_DEBUG: + exceptionCode = EXCEPTION_BREAKPOINT; + break; + case EXC_ARM_SP_ALIGN: + exceptionCode = EXCEPTION_DATATYPE_MISALIGNMENT; + break; + case EXC_ARM_SWP: + exceptionCode = EXCEPTION_ILLEGAL_INSTRUCTION; + break; + case EXC_ARM_PAC_FAIL: + // PAC Authentication failure fall through + default: + exceptionCode = EXCEPTION_ACCESS_VIOLATION; + } +#else +#error Unexpected architecture +#endif pExceptionRecord->NumberParameters = 2; pExceptionRecord->ExceptionInformation[0] = 0; pExceptionRecord->ExceptionInformation[1] = exceptionInfo.Subcodes[1]; - NONPAL_TRACE("subcodes[1] = %llx\n", exceptionInfo.Subcodes[1]); + NONPAL_TRACE("subcodes[1] = %llx\n", (uint64_t) exceptionInfo.Subcodes[1]); } break; @@ -468,6 +497,7 @@ BuildExceptionRecord( { switch (exceptionInfo.Subcodes[0]) { +#if defined(HOST_AMD64) || defined(HOST_X86) case EXC_I386_DIV: exceptionCode = EXCEPTION_INT_DIVIDE_BY_ZERO; break; @@ -480,6 +510,28 @@ BuildExceptionRecord( case EXC_I386_BOUND: exceptionCode = EXCEPTION_ARRAY_BOUNDS_EXCEEDED; break; +#elif defined(HOST_ARM64) + case EXC_ARM_FP_IO: + exceptionCode = EXCEPTION_FLT_INVALID_OPERATION; + break; + case EXC_ARM_FP_DZ: + exceptionCode = EXCEPTION_FLT_DIVIDE_BY_ZERO; + break; + case EXC_ARM_FP_OF: + exceptionCode = EXCEPTION_FLT_OVERFLOW; + break; + case EXC_ARM_FP_UF: + exceptionCode = EXCEPTION_FLT_UNDERFLOW; + break; + case EXC_ARM_FP_IX: + exceptionCode = EXCEPTION_FLT_INEXACT_RESULT; + break; + case EXC_ARM_FP_ID: + exceptionCode = EXCEPTION_FLT_DENORMAL_OPERAND; + break; +#else +#error Unexpected architecture +#endif default: exceptionCode = EXCEPTION_ILLEGAL_INSTRUCTION; break; @@ -493,6 +545,7 @@ BuildExceptionRecord( // Trace, breakpoint, etc. Details in subcode field. case EXC_BREAKPOINT: +#if defined(HOST_AMD64) || defined(HOST_X86) if (exceptionInfo.Subcodes[0] == EXC_I386_SGL) { exceptionCode = EXCEPTION_SINGLE_STEP; @@ -501,6 +554,14 @@ BuildExceptionRecord( { exceptionCode = EXCEPTION_BREAKPOINT; } +#elif defined(HOST_ARM64) + if (exceptionInfo.Subcodes[0] == EXC_ARM_BREAKPOINT) + { + exceptionCode = EXCEPTION_BREAKPOINT; + } +#else +#error Unexpected architecture +#endif else { WARN("unexpected subcode %d for EXC_BREAKPOINT", exceptionInfo.Subcodes[0]); @@ -594,11 +655,25 @@ HijackFaultingThread( // Fill in the exception record from the exception info BuildExceptionRecord(exceptionInfo, &exceptionRecord); +#if defined(HOST_AMD64) || defined(HOST_X86) + void **targetSP = (void **)threadContext.Rsp; + threadContext.ContextFlags = CONTEXT_FLOATING_POINT; CONTEXT_GetThreadContextFromThreadState(x86_FLOAT_STATE, (thread_state_t)&exceptionInfo.FloatState, &threadContext); threadContext.ContextFlags |= CONTEXT_CONTROL | CONTEXT_INTEGER | CONTEXT_SEGMENTS; CONTEXT_GetThreadContextFromThreadState(x86_THREAD_STATE, (thread_state_t)&exceptionInfo.ThreadState, &threadContext); +#elif defined(HOST_ARM64) + void **targetSP = (void **)threadContext.Sp; + + threadContext.ContextFlags = CONTEXT_FLOATING_POINT; + CONTEXT_GetThreadContextFromThreadState(ARM_NEON_STATE64, (thread_state_t)&exceptionInfo.FloatState, &threadContext); + + threadContext.ContextFlags |= CONTEXT_CONTROL | CONTEXT_INTEGER | CONTEXT_SEGMENTS; + CONTEXT_GetThreadContextFromThreadState(ARM_THREAD_STATE64, (thread_state_t)&exceptionInfo.ThreadState, &threadContext); +#else +#error Unexpected architecture +#endif // For CoreCLR we look more deeply at access violations to determine whether they're the result of a stack // overflow. If so we'll terminate the process immediately (the current default policy of the CoreCLR EE). @@ -653,7 +728,7 @@ HijackFaultingThread( // Calculate the page base addresses for the fault and the faulting thread's SP. int cbPage = getpagesize(); char *pFaultPage = (char*)(exceptionRecord.ExceptionInformation[1] & ~(cbPage - 1)); - char *pStackTopPage = (char*)(threadContext.Rsp & ~(cbPage - 1)); + char *pStackTopPage = (char*)((size_t)targetSP & ~(cbPage - 1)); if (pFaultPage == pStackTopPage || pFaultPage == (pStackTopPage - cbPage)) { @@ -697,7 +772,6 @@ HijackFaultingThread( { // Check if we can read pointer sizeD bytes below the target thread's stack pointer. // If we are unable to, then it implies we have run into SO. - void **targetSP = (void **)threadContext.Rsp; vm_address_t targetAddr = (mach_vm_address_t)(targetSP); targetAddr -= sizeof(void *); vm_size_t vm_size = sizeof(void *); @@ -711,6 +785,15 @@ HijackFaultingThread( } } + if (fIsStackOverflow) + { + exceptionRecord.ExceptionCode = EXCEPTION_STACK_OVERFLOW; + } + + exceptionRecord.ExceptionFlags = EXCEPTION_IS_SIGNAL; + exceptionRecord.ExceptionRecord = NULL; + +#if defined(HOST_AMD64) || defined(HOST_X86) NONPAL_ASSERTE(exceptionInfo.ThreadState.tsh.flavor == x86_THREAD_STATE64); // Make a copy of the thread state because the one in exceptionInfo needs to be preserved to restore @@ -723,16 +806,20 @@ HijackFaultingThread( ts64.__rflags &= ~EFL_TF; } - if (fIsStackOverflow) - { - exceptionRecord.ExceptionCode = EXCEPTION_STACK_OVERFLOW; - } - - exceptionRecord.ExceptionFlags = EXCEPTION_IS_SIGNAL; - exceptionRecord.ExceptionRecord = NULL; exceptionRecord.ExceptionAddress = (void *)ts64.__rip; - void **FramePointer; + void **FramePointer = (void **)ts64.__rsp; +#elif defined(HOST_ARM64) + // Make a copy of the thread state because the one in exceptionInfo needs to be preserved to restore + // the state if the exception is forwarded. + arm_thread_state64_t ts64 = exceptionInfo.ThreadState; + + exceptionRecord.ExceptionAddress = (void *)arm_thread_state64_get_pc(ts64); + + void **FramePointer = (void **)arm_thread_state64_get_sp(ts64); +#else +#error Unexpected architecture +#endif if (fIsStackOverflow) { @@ -751,12 +838,6 @@ HijackFaultingThread( FramePointer = (void**)((size_t)stackOverflowHandlerStack + stackOverflowStackSize); } - else - { - FramePointer = (void **)ts64.__rsp; - } - - *--FramePointer = (void *)ts64.__rip; // Construct a stack frame for a pretend activation of the function // PAL_DispatchExceptionWrapper that serves only to make the stack @@ -764,8 +845,19 @@ HijackFaultingThread( // PAL_DispatchExceptionWrapper has an ebp frame, its local variables // are the context and exception record, and it has just "called" // PAL_DispatchException. +#if defined(HOST_AMD64) || defined(HOST_X86) + *--FramePointer = (void *)ts64.__rip; *--FramePointer = (void *)ts64.__rbp; + ts64.__rbp = (SIZE_T)FramePointer; +#elif defined(HOST_ARM64) + *--FramePointer = (void *)arm_thread_state64_get_pc(ts64); + *--FramePointer = (void *)arm_thread_state64_get_fp(ts64); + + arm_thread_state64_set_fp(ts64, FramePointer); +#else +#error Unexpected architecture +#endif // Put the context on the stack FramePointer = (void **)((ULONG_PTR)FramePointer - sizeof(CONTEXT)); @@ -783,6 +875,7 @@ HijackFaultingThread( MachExceptionInfo *pMachExceptionInfo = (MachExceptionInfo *)FramePointer; *pMachExceptionInfo = exceptionInfo; +#if defined(HOST_AMD64) || defined(HOST_X86) // Push arguments to PAL_DispatchException FramePointer = (void **)((ULONG_PTR)FramePointer - 3 * sizeof(void *)); @@ -802,6 +895,26 @@ HijackFaultingThread( // Now set the thread state for the faulting thread so that PAL_DispatchException executes next machret = thread_set_state(thread, x86_THREAD_STATE64, (thread_state_t)&ts64, x86_THREAD_STATE64_COUNT); CHECK_MACH("thread_set_state(thread)", machret); +#elif defined(HOST_ARM64) + // Setup arguments to PAL_DispatchException + ts64.__x[0] = (uint64_t)pContext; + ts64.__x[1] = (uint64_t)pExceptionRecord; + ts64.__x[2] = (uint64_t)pMachExceptionInfo; + + // Make sure it's aligned - SP has 16-byte alignment + FramePointer = (void **)((ULONG_PTR)FramePointer - ((ULONG_PTR)FramePointer % 16)); + arm_thread_state64_set_sp(ts64, FramePointer); + + // Make the call to DispatchException + arm_thread_state64_set_lr_fptr(ts64, (uint64_t)PAL_DispatchExceptionWrapper + PAL_DispatchExceptionReturnOffset); + arm_thread_state64_set_pc_fptr(ts64, PAL_DispatchException); + + // Now set the thread state for the faulting thread so that PAL_DispatchException executes next + machret = thread_set_state(thread, ARM_THREAD_STATE64, (thread_state_t)&ts64, ARM_THREAD_STATE64_COUNT); + CHECK_MACH("thread_set_state(thread)", machret); +#else +#error Unexpected architecture +#endif } /*++ @@ -932,8 +1045,9 @@ SEHExceptionThread(void *args) int subcode_count = sMessage.GetExceptionCodeCount(); for (int i = 0; i < subcode_count; i++) - NONPAL_TRACE("ExceptionNotification subcode[%d] = %llx\n", i, sMessage.GetExceptionCode(i)); + NONPAL_TRACE("ExceptionNotification subcode[%d] = %llx\n", i, (uint64_t) sMessage.GetExceptionCode(i)); +#if defined(HOST_AMD64) || defined(HOST_X86) x86_thread_state64_t threadStateActual; unsigned int count = sizeof(threadStateActual) / sizeof(unsigned); machret = thread_get_state(thread, x86_THREAD_STATE64, (thread_state_t)&threadStateActual, &count); @@ -957,6 +1071,31 @@ SEHExceptionThread(void *args) threadExceptionState.__cpu, threadExceptionState.__err, threadExceptionState.__faultvaddr); +#elif defined(HOST_ARM64) + arm_thread_state64_t threadStateActual; + unsigned int count = sizeof(threadStateActual) / sizeof(unsigned); + machret = thread_get_state(thread, ARM_THREAD_STATE64, (thread_state_t)&threadStateActual, &count); + CHECK_MACH("thread_get_state", machret); + + NONPAL_TRACE("ExceptionNotification actual lr %016llx sp %016llx fp %016llx pc %016llx cpsr %08x\n", + arm_thread_state64_get_lr(threadStateActual), + arm_thread_state64_get_sp(threadStateActual), + arm_thread_state64_get_fp(threadStateActual), + arm_thread_state64_get_pc(threadStateActual), + threadStateActual.__cpsr); + + arm_exception_state64_t threadExceptionState; + unsigned int ehStateCount = sizeof(threadExceptionState) / sizeof(unsigned); + machret = thread_get_state(thread, ARM_EXCEPTION_STATE64, (thread_state_t)&threadExceptionState, &ehStateCount); + CHECK_MACH("thread_get_state", machret); + + NONPAL_TRACE("ExceptionNotification far %016llx esr %08x exception %08x\n", + threadExceptionState.__far, + threadExceptionState.__esr, + threadExceptionState.__exception); +#else +#error Unexpected architecture +#endif } #endif // _DEBUG @@ -1081,6 +1220,7 @@ MachExceptionInfo::MachExceptionInfo(mach_port_t thread, MachMessage& message) for (int i = 0; i < SubcodeCount; i++) Subcodes[i] = message.GetExceptionCode(i); +#if defined(HOST_AMD64) || defined(HOST_X86) mach_msg_type_number_t count = x86_THREAD_STATE_COUNT; machret = thread_get_state(thread, x86_THREAD_STATE, (thread_state_t)&ThreadState, &count); CHECK_MACH("thread_get_state", machret); @@ -1092,6 +1232,21 @@ MachExceptionInfo::MachExceptionInfo(mach_port_t thread, MachMessage& message) count = x86_DEBUG_STATE_COUNT; machret = thread_get_state(thread, x86_DEBUG_STATE, (thread_state_t)&DebugState, &count); CHECK_MACH("thread_get_state(debug)", machret); +#elif defined(HOST_ARM64) + mach_msg_type_number_t count = ARM_THREAD_STATE64_COUNT; + machret = thread_get_state(thread, ARM_THREAD_STATE64, (thread_state_t)&ThreadState, &count); + CHECK_MACH("thread_get_state", machret); + + count = ARM_NEON_STATE64_COUNT; + machret = thread_get_state(thread, ARM_NEON_STATE64, (thread_state_t)&FloatState, &count); + CHECK_MACH("thread_get_state(float)", machret); + + count = ARM_DEBUG_STATE64_COUNT; + machret = thread_get_state(thread, ARM_DEBUG_STATE64, (thread_state_t)&DebugState, &count); + CHECK_MACH("thread_get_state(debug)", machret); +#else +#error Unexpected architecture +#endif } /*++ @@ -1108,6 +1263,7 @@ Return value : --*/ void MachExceptionInfo::RestoreState(mach_port_t thread) { +#if defined(HOST_AMD64) || defined(HOST_X86) // If we are restarting a breakpoint, we need to bump the IP back one to // point at the actual int 3 instructions. if (ExceptionType == EXC_BREAKPOINT) @@ -1125,6 +1281,18 @@ void MachExceptionInfo::RestoreState(mach_port_t thread) machret = thread_set_state(thread, x86_DEBUG_STATE, (thread_state_t)&DebugState, x86_DEBUG_STATE_COUNT); CHECK_MACH("thread_set_state(debug)", machret); +#elif defined(HOST_ARM64) + kern_return_t machret = thread_set_state(thread, ARM_THREAD_STATE64, (thread_state_t)&ThreadState, ARM_THREAD_STATE64_COUNT); + CHECK_MACH("thread_set_state(thread)", machret); + + machret = thread_set_state(thread, ARM_NEON_STATE64, (thread_state_t)&FloatState, ARM_NEON_STATE64_COUNT); + CHECK_MACH("thread_set_state(float)", machret); + + machret = thread_set_state(thread, ARM_DEBUG_STATE64, (thread_state_t)&DebugState, ARM_DEBUG_STATE64_COUNT); + CHECK_MACH("thread_set_state(debug)", machret); +#else +#error Unexpected architecture +#endif } /*++ @@ -1289,28 +1457,51 @@ InjectActivationInternal(CPalThread* pThread) if (palError == NO_ERROR) { - mach_msg_type_number_t count; - +#if defined(HOST_AMD64) || defined(HOST_X86) x86_exception_state64_t ExceptionState; - count = x86_EXCEPTION_STATE64_COUNT; + 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, - x86_EXCEPTION_STATE64, + exceptionFlavor, (thread_state_t)&ExceptionState, &count); - _ASSERT_MSG(MachRet == KERN_SUCCESS, "thread_get_state for x86_EXCEPTION_STATE64\n"); + _ASSERT_MSG(MachRet == KERN_SUCCESS, "thread_get_state for *_EXCEPTION_STATE64\n"); +#if defined(HOST_AMD64) || defined(HOST_X86) // Inject the activation only if the thread doesn't have a pending hardware exception static const int MaxHardwareExceptionVector = 31; if (ExceptionState.__trapno > MaxHardwareExceptionVector) +#elif defined(HOST_ARM64) + // TBD // Inject the activation only if the thread doesn't have a pending hardware exception +#else +#error Unexpected architecture +#endif { - x86_thread_state64_t ThreadState; - count = x86_THREAD_STATE64_COUNT; + count = threadCount; MachRet = thread_get_state(threadPort, - x86_THREAD_STATE64, + threadFlavor, (thread_state_t)&ThreadState, &count); - _ASSERT_MSG(MachRet == KERN_SUCCESS, "thread_get_state for x86_THREAD_STATE64\n"); + _ASSERT_MSG(MachRet == KERN_SUCCESS, "thread_get_state for *_THREAD_STATE64\n"); +#if defined(HOST_AMD64) || defined(HOST_X86) 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 @@ -1319,9 +1510,19 @@ InjectActivationInternal(CPalThread* pThread) *(--sp) = ThreadState.__rip; *(--sp) = ThreadState.__rbp; size_t rbpAddress = (size_t)sp; +#elif defined(HOST_ARM64) + if ((g_safeActivationCheckFunction != NULL) && g_safeActivationCheckFunction(arm_thread_state64_get_lr(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) = arm_thread_state64_get_pc(ThreadState); + *(--sp) = arm_thread_state64_get_lr(ThreadState); + size_t rfpAddress = (size_t)sp; +#else +#error Unexpected architecture +#endif size_t contextAddress = (((size_t)sp) - sizeof(CONTEXT)) & ~15; - size_t returnAddressAddress = contextAddress - sizeof(size_t); - *(size_t*)(returnAddressAddress) = ActivationHandlerReturnOffset + (size_t)ActivationHandlerWrapper; // 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 @@ -1337,16 +1538,30 @@ InjectActivationInternal(CPalThread* pThread) MachRet = CONTEXT_GetThreadContextFromPort(threadPort, pContext); _ASSERT_MSG(MachRet == KERN_SUCCESS, "CONTEXT_GetThreadContextFromPort\n"); +#if defined(HOST_AMD64) || defined(HOST_X86) + 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, rfpAddress); + ThreadState.__x[0] = contextAddress; +#else +#error Unexpected architecture +#endif MachRet = thread_set_state(threadPort, - x86_THREAD_STATE64, + threadFlavor, (thread_state_t)&ThreadState, - count); + threadCount); _ASSERT_MSG(MachRet == KERN_SUCCESS, "thread_set_state\n"); } } diff --git a/src/coreclr/src/pal/src/exception/machmessage.cpp b/src/coreclr/src/pal/src/exception/machmessage.cpp index 0c0021855395f..b4157b5fc3660 100644 --- a/src/coreclr/src/pal/src/exception/machmessage.cpp +++ b/src/coreclr/src/pal/src/exception/machmessage.cpp @@ -1013,6 +1013,10 @@ thread_act_t MachMessage::GetThreadFromState(thread_state_flavor_t eFlavor, thre case x86_THREAD_STATE64: targetSP = ((x86_thread_state64_t*)pState)->__rsp; break; +#elif defined(HOST_ARM64) + case ARM_THREAD_STATE64: + targetSP = arm_thread_state64_get_sp(*(arm_thread_state64_t*)pState); + break; #else #error Unexpected architecture. #endif @@ -1031,9 +1035,17 @@ thread_act_t MachMessage::GetThreadFromState(thread_state_flavor_t eFlavor, thre for (mach_msg_type_number_t i = 0; i < cThreads; i++) { // Get the general register state of each thread. +#if defined(HOST_AMD64) || defined(HOST_X86) x86_thread_state_t threadState; mach_msg_type_number_t count = x86_THREAD_STATE_COUNT; machret = thread_get_state(pThreads[i], x86_THREAD_STATE, (thread_state_t)&threadState, &count); +#elif defined(HOST_ARM64) + arm_thread_state64_t threadState; + mach_msg_type_number_t count = ARM_THREAD_STATE64_COUNT; + machret = thread_get_state(pThreads[i], ARM_THREAD_STATE64, (thread_state_t)&threadState, &count); +#else +#error Unexpected architecture +#endif if (machret == KERN_SUCCESS) { // If a thread has the same SP as our target it should be the same thread (otherwise we have two @@ -1044,6 +1056,8 @@ thread_act_t MachMessage::GetThreadFromState(thread_state_flavor_t eFlavor, thre if (threadState.uts.ts32.esp == targetSP) #elif defined(HOST_AMD64) if (threadState.uts.ts64.__rsp == targetSP) +#elif defined(HOST_ARM64) + if (arm_thread_state64_get_sp(threadState) == targetSP) #else #error Unexpected architecture. #endif diff --git a/src/coreclr/src/pal/src/exception/machmessage.h b/src/coreclr/src/pal/src/exception/machmessage.h index bf544d66f98c4..f43999b201ac0 100644 --- a/src/coreclr/src/pal/src/exception/machmessage.h +++ b/src/coreclr/src/pal/src/exception/machmessage.h @@ -87,10 +87,17 @@ struct MachExceptionInfo exception_type_t ExceptionType; mach_msg_type_number_t SubcodeCount; MACH_EH_TYPE(exception_data_type_t) Subcodes[2]; +#if defined(HOST_AMD64) || defined(HOST_X86) x86_thread_state_t ThreadState; x86_float_state_t FloatState; x86_debug_state_t DebugState; - +#elif defined(HOST_ARM64) + arm_thread_state64_t ThreadState; + arm_neon_state64_t FloatState; + arm_debug_state64_t DebugState; +#else +#error Unexpected architecture +#endif MachExceptionInfo(mach_port_t thread, MachMessage& message); void RestoreState(mach_port_t thread); }; diff --git a/src/coreclr/src/pal/src/exception/remote-unwind.cpp b/src/coreclr/src/pal/src/exception/remote-unwind.cpp index 91f819370f405..89301718234d1 100644 --- a/src/coreclr/src/pal/src/exception/remote-unwind.cpp +++ b/src/coreclr/src/pal/src/exception/remote-unwind.cpp @@ -1296,6 +1296,7 @@ GetProcInfo(unw_word_t ip, unw_proc_info_t *pip, const libunwindInfo* info, bool return false; } +#if defined(TARGET_X86) || defined(TARGET_AMD64) static bool StepWithCompactEncodingRBPFrame(const libunwindInfo* info, compact_unwind_encoding_t compactEncoding) { @@ -1364,10 +1365,101 @@ StepWithCompactEncodingRBPFrame(const libunwindInfo* info, compact_unwind_encodi compactEncoding, (void*)context->Rip, (void*)context->Rsp, (void*)context->Rbp); return true; } +#endif + +#if defined(TARGET_ARM64) +static bool +StepWithCompactEncodingArm64Frame(const libunwindInfo* info, compact_unwind_encoding_t compactEncoding) +{ + CONTEXT* context = info->Context; + + unw_word_t fp = context->Fp; + unw_word_t sp = context->Sp; + + // caller Sp is callee Fp less saved FP and LR + context->Sp = fp + (sizeof(uint64_t) * 2); + + context->Pc = context->Lr; + + unw_word_t addr = fp; + + if (!ReadValue64(info, &addr, (uint64_t*)&context->Fp)) { + return false; + } + addr += sizeof(uint64_t); + + + if (!ReadValue64(info, &addr, (uint64_t*)&context->Lr)) { + return false; + } + addr += sizeof(uint64_t); + + if (compactEncoding & UNWIND_ARM64_FRAME_X19_X20_PAIR) + { + if (!ReadValue64(info, &addr, (uint64_t*)&context->X[19])) { + return false; + } + addr += sizeof(uint64_t); + if (!ReadValue64(info, &addr, (uint64_t*)&context->X[20])) { + return false; + } + addr += sizeof(uint64_t); + } + if (compactEncoding & UNWIND_ARM64_FRAME_X21_X22_PAIR) + { + if (!ReadValue64(info, &addr, (uint64_t*)&context->X[21])) { + return false; + } + addr += sizeof(uint64_t); + if (!ReadValue64(info, &addr, (uint64_t*)&context->X[22])) { + return false; + } + addr += sizeof(uint64_t); + } + if (compactEncoding & UNWIND_ARM64_FRAME_X23_X24_PAIR) + { + if (!ReadValue64(info, &addr, (uint64_t*)&context->X[23])) { + return false; + } + addr += sizeof(uint64_t); + if (!ReadValue64(info, &addr, (uint64_t*)&context->X[24])) { + return false; + } + addr += sizeof(uint64_t); + } + if (compactEncoding & UNWIND_ARM64_FRAME_X25_X26_PAIR) + { + if (!ReadValue64(info, &addr, (uint64_t*)&context->X[25])) { + return false; + } + addr += sizeof(uint64_t); + if (!ReadValue64(info, &addr, (uint64_t*)&context->X[26])) { + return false; + } + addr += sizeof(uint64_t); + } + if (compactEncoding & UNWIND_ARM64_FRAME_X27_X28_PAIR) + { + if (!ReadValue64(info, &addr, (uint64_t*)&context->X[27])) { + return false; + } + addr += sizeof(uint64_t); + if (!ReadValue64(info, &addr, (uint64_t*)&context->X[28])) { + return false; + } + addr += sizeof(uint64_t); + } + + TRACE("SUCCESS: compact step encoding %08x pc %p sp %p fp %p lr %p\n", + compactEncoding, (void*)context->Pc, (void*)context->Sp, (void*)context->Fp, (void*)context->Lr); + return true; +} +#endif static bool StepWithCompactEncoding(const libunwindInfo* info, compact_unwind_encoding_t compactEncoding, unw_word_t functionStart) { +#if defined(TARGET_X86) || defined(TARGET_AMD64) if (compactEncoding == 0) { TRACE("Compact unwind missing for %p\n", (void*)info->Context->Rip); @@ -1384,6 +1476,24 @@ StepWithCompactEncoding(const libunwindInfo* info, compact_unwind_encoding_t com } ERROR("Invalid encoding %08x\n", compactEncoding); +#elif defined(TARGET_ARM64) + if (compactEncoding == 0) + { + TRACE("Compact unwind missing for %p\n", (void*)info->Context->Pc); + return false; + } + switch (compactEncoding & UNWIND_ARM64_MODE_MASK) + { + case UNWIND_ARM64_MODE_FRAME: + return StepWithCompactEncodingArm64Frame(info, compactEncoding); + + case UNWIND_ARM64_MODE_FRAMELESS: + break; + } + ERROR("Invalid encoding %08x\n", compactEncoding); +#else + ERROR("Unsupported architecture. encoding %08x\n", compactEncoding); +#endif return false; } @@ -1853,10 +1963,17 @@ PAL_VirtualUnwindOutOfProc(CONTEXT *context, KNONVOLATILE_CONTEXT_POINTERS *cont info.ReadMemory = readMemoryCallback; #ifdef __APPLE__ - TRACE("Unwind: rip %p rsp %p rbp %p\n", (void*)context->Rip, (void*)context->Rsp, (void*)context->Rbp); unw_proc_info_t procInfo; bool step; +#if defined(TARGET_X86) || defined(TARGET_AMD64) + TRACE("Unwind: rip %p rsp %p rbp %p\n", (void*)context->Rip, (void*)context->Rsp, (void*)context->Rbp); result = GetProcInfo(context->Rip, &procInfo, &info, &step, false); +#elif defined(TARGET_ARM64) + TRACE("Unwind: pc %p sp %p fp %p\n", (void*)context->Pc, (void*)context->Sp, (void*)context->Fp); + result = GetProcInfo(context->Pc, &procInfo, &info, &step, false); +#else +#error Unexpected architecture +#endif if (!result) { goto exit; diff --git a/src/coreclr/src/pal/src/exception/seh-unwind.cpp b/src/coreclr/src/pal/src/exception/seh-unwind.cpp index 524d7252bbfff..358467a6b1d15 100644 --- a/src/coreclr/src/pal/src/exception/seh-unwind.cpp +++ b/src/coreclr/src/pal/src/exception/seh-unwind.cpp @@ -54,6 +54,27 @@ Module Name: #endif // HOST_UNIX +#if defined(TARGET_OSX) && defined(TARGET_ARM64) +// MacOS uses ARM64 instead of AARCH64 to describe these registers +// Create aliases to reuse more code +enum +{ + UNW_AARCH64_X19 = UNW_ARM64_X19, + UNW_AARCH64_X20 = UNW_ARM64_X20, + UNW_AARCH64_X21 = UNW_ARM64_X21, + UNW_AARCH64_X22 = UNW_ARM64_X22, + UNW_AARCH64_X23 = UNW_ARM64_X23, + UNW_AARCH64_X24 = UNW_ARM64_X24, + UNW_AARCH64_X25 = UNW_ARM64_X25, + UNW_AARCH64_X26 = UNW_ARM64_X26, + UNW_AARCH64_X27 = UNW_ARM64_X27, + UNW_AARCH64_X28 = UNW_ARM64_X28, + UNW_AARCH64_X29 = UNW_ARM64_X29, + UNW_AARCH64_X30 = UNW_ARM64_X30 +}; +#endif // defined(TARGET_OSX) && defined(TARGET_ARM64) + + //---------------------------------------------------------------------- // Virtual Unwinding //---------------------------------------------------------------------- @@ -129,7 +150,7 @@ static void WinContextToUnwindContext(CONTEXT *winContext, unw_context_t *unwCon unwContext->regs[13] = winContext->Sp; unwContext->regs[14] = winContext->Lr; unwContext->regs[15] = winContext->Pc; -#elif defined(HOST_ARM64) +#elif defined(HOST_ARM64) && !defined(TARGET_OSX) unwContext->uc_mcontext.pc = winContext->Pc; unwContext->uc_mcontext.sp = winContext->Sp; unwContext->uc_mcontext.regs[29] = winContext->Fp; @@ -166,6 +187,24 @@ static void WinContextToUnwindCursor(CONTEXT *winContext, unw_cursor_t *cursor) unw_set_reg(cursor, UNW_X86_EBX, winContext->Ebx); unw_set_reg(cursor, UNW_X86_ESI, winContext->Esi); unw_set_reg(cursor, UNW_X86_EDI, winContext->Edi); +#elif defined(HOST_ARM64) && defined(TARGET_OSX) + // unw_cursor_t is an opaque data structure on macOS + // As noted in WinContextToUnwindContext this didn't work for Linux + // TBD whether this will work for macOS. + unw_set_reg(cursor, UNW_REG_IP, winContext->Pc); + unw_set_reg(cursor, UNW_REG_SP, winContext->Sp); + unw_set_reg(cursor, UNW_AARCH64_X29, winContext->Fp); + unw_set_reg(cursor, UNW_AARCH64_X30, winContext->Lr); + unw_set_reg(cursor, UNW_AARCH64_X19, winContext->X19); + unw_set_reg(cursor, UNW_AARCH64_X20, winContext->X20); + unw_set_reg(cursor, UNW_AARCH64_X21, winContext->X21); + unw_set_reg(cursor, UNW_AARCH64_X22, winContext->X22); + unw_set_reg(cursor, UNW_AARCH64_X23, winContext->X23); + unw_set_reg(cursor, UNW_AARCH64_X24, winContext->X24); + unw_set_reg(cursor, UNW_AARCH64_X25, winContext->X25); + unw_set_reg(cursor, UNW_AARCH64_X26, winContext->X26); + unw_set_reg(cursor, UNW_AARCH64_X27, winContext->X27); + unw_set_reg(cursor, UNW_AARCH64_X28, winContext->X28); #endif } #endif diff --git a/src/coreclr/src/pal/src/include/pal/context.h b/src/coreclr/src/pal/src/include/pal/context.h index db0baec111919..73de448dfcf2f 100644 --- a/src/coreclr/src/pal/src/include/pal/context.h +++ b/src/coreclr/src/pal/src/include/pal/context.h @@ -305,6 +305,7 @@ inline void *FPREG_Xstate_Ymmh(const ucontext_t *uc) #define MCREG_Cpsr(mc) ((mc).pstate) +#ifndef TARGET_OSX inline fpsimd_context* GetNativeSigSimdContext(native_context_t *mc) { @@ -341,7 +342,9 @@ const fpsimd_context* GetConstNativeSigSimdContext(const native_context_t *mc) return GetNativeSigSimdContext(const_cast(mc)); } -#else +#endif // TARGET_OSX + +#else // HOST_ARM64 // For FreeBSD, as found in x86/ucontext.h #define MCREG_Rbp(mc) ((mc).mc_rbp) #define MCREG_Rip(mc) ((mc).mc_rip) diff --git a/src/coreclr/src/pal/src/libunwind_mac/src/missing-functions.c b/src/coreclr/src/pal/src/libunwind_mac/src/missing-functions.c index 8399214e49520..1da065c051e40 100644 --- a/src/coreclr/src/pal/src/libunwind_mac/src/missing-functions.c +++ b/src/coreclr/src/pal/src/libunwind_mac/src/missing-functions.c @@ -51,7 +51,13 @@ int unw_is_signal_frame (unw_cursor_t *cursor) { struct cursor *c = (struct cursor *) cursor; +#ifdef TARGET_AMD64 return c->sigcontext_format != X86_64_SCF_NONE; +#elif defined(TARGET_ARM64) + return c->sigcontext_format != AARCH64_SCF_NONE; +#else + #error Unexpected target +#endif } int diff --git a/src/coreclr/src/pal/src/misc/sysinfo.cpp b/src/coreclr/src/pal/src/misc/sysinfo.cpp index 4592aa2a14342..9dfc34632b57d 100644 --- a/src/coreclr/src/pal/src/misc/sysinfo.cpp +++ b/src/coreclr/src/pal/src/misc/sysinfo.cpp @@ -565,10 +565,10 @@ PAL_GetLogicalProcessorCacheSizeFromOS() cacheSize = std::max(cacheSize, (size_t)sysconf(_SC_LEVEL4_CACHE_SIZE)); #endif -#if defined(HOST_ARM64) +#if defined(HOST_ARM64) && !defined(TARGET_OSX) if(cacheSize == 0) { - size_t size; + uint64_t size; if(ReadMemoryValueFromFile("/sys/devices/system/cpu/cpu0/cache/index0/size", &size)) cacheSize = std::max(cacheSize, size); diff --git a/src/coreclr/src/pal/src/thread/context.cpp b/src/coreclr/src/pal/src/thread/context.cpp index ca0b60e449252..dfb171b85bb58 100644 --- a/src/coreclr/src/pal/src/thread/context.cpp +++ b/src/coreclr/src/pal/src/thread/context.cpp @@ -952,9 +952,12 @@ CONTEXT_GetThreadContextFromPort( if (lpContext->ContextFlags & (CONTEXT_CONTROL | CONTEXT_INTEGER | CONTEXT_SEGMENTS) & CONTEXT_AREA_MASK) { -#ifdef HOST_AMD64 +#if defined(HOST_AMD64) x86_thread_state64_t State; StateFlavor = x86_THREAD_STATE64; +#elif defined(HOST_ARM64) + arm_thread_state64_t State; + StateFlavor = ARM_THREAD_STATE64; #else #error Unexpected architecture. #endif @@ -969,7 +972,9 @@ CONTEXT_GetThreadContextFromPort( CONTEXT_GetThreadContextFromThreadState(StateFlavor, (thread_state_t)&State, lpContext); } - if (lpContext->ContextFlags & CONTEXT_ALL_FLOATING & CONTEXT_AREA_MASK) { + if (lpContext->ContextFlags & CONTEXT_ALL_FLOATING & CONTEXT_AREA_MASK) + { +#if defined(HOST_AMD64) // The thread_get_state for floating point state can fail for some flavors when the processor is not // in the right mode at the time we are taking the state. So we will try to get the AVX state first and // if it fails, get the FLOAT state and if that fails, take AVX512 state. Both AVX and AVX512 states @@ -1008,6 +1013,20 @@ CONTEXT_GetThreadContextFromPort( } } } +#elif defined(HOST_ARM64) + arm_neon_state64_t State; + + StateFlavor = ARM_NEON_STATE64; + StateCount = sizeof(arm_neon_state64_t) / sizeof(natural_t); + MachRet = thread_get_state(Port, StateFlavor, (thread_state_t)&State, &StateCount); + if (MachRet != KERN_SUCCESS) + { + // We were unable to get any floating point state. + lpContext->ContextFlags &= ~((CONTEXT_ALL_FLOATING) & CONTEXT_AREA_MASK); + } +#else +#error Unexpected architecture. +#endif CONTEXT_GetThreadContextFromThreadState(StateFlavor, (thread_state_t)&State, lpContext); } @@ -1029,6 +1048,7 @@ CONTEXT_GetThreadContextFromThreadState( { switch (threadStateFlavor) { +#if defined (HOST_AMD64) || defined(HOST_X86) #ifdef HOST_AMD64 case x86_THREAD_STATE64: if (lpContext->ContextFlags & (CONTEXT_CONTROL | CONTEXT_INTEGER | CONTEXT_SEGMENTS) & CONTEXT_AREA_MASK) @@ -1100,9 +1120,7 @@ CONTEXT_GetThreadContextFromThreadState( memcpy(&lpContext->Xmm0, &pState->__fpu_xmm0, 16 * 16); } break; -#else -#error Unexpected architecture. -#endif +#endif // HOST_AMD64 case x86_THREAD_STATE: { x86_thread_state_t *pState = (x86_thread_state_t *)threadState; @@ -1116,6 +1134,31 @@ CONTEXT_GetThreadContextFromThreadState( CONTEXT_GetThreadContextFromThreadState((thread_state_flavor_t)pState->fsh.flavor, (thread_state_t)&pState->ufs, lpContext); } break; +#elif defined(HOST_ARM64) + case ARM_THREAD_STATE64: + if (lpContext->ContextFlags & (CONTEXT_CONTROL | CONTEXT_INTEGER | CONTEXT_SEGMENTS) & CONTEXT_AREA_MASK) + { + arm_thread_state64_t *pState = (arm_thread_state64_t*)threadState; + memcpy(&lpContext->X0, &pState->__x[0], 29 * 8); + lpContext->Cpsr = pState->__cpsr; + lpContext->Fp = arm_thread_state64_get_fp(*pState); + lpContext->Sp = arm_thread_state64_get_sp(*pState); + lpContext->Lr = arm_thread_state64_get_lr(*pState); + lpContext->Pc = arm_thread_state64_get_pc(*pState); + } + break; + case ARM_NEON_STATE64: + if (lpContext->ContextFlags & CONTEXT_FLOATING_POINT & CONTEXT_AREA_MASK) + { + arm_neon_state64_t *pState = (arm_neon_state64_t*)threadState; + memcpy(&lpContext->V[0], &pState->__v, 32 * 16); + lpContext->Fpsr = pState->__fpsr; + lpContext->Fpcr = pState->__fpcr; + } + break; +#else +#error Unexpected architecture. +#endif default: ASSERT("Invalid thread state flavor %d\n", threadStateFlavor); @@ -1216,6 +1259,16 @@ CONTEXT_SetThreadContextOnPort( // State.es = lpContext->SegEs_PAL_Undefined; State.__fs = lpContext->SegFs; State.__gs = lpContext->SegGs; +#elif defined(HOST_ARM64) + arm_thread_state64_t State; + StateFlavor = ARM_THREAD_STATE64; + + memcpy(&State.__x[0], &lpContext->X0, 29 * 8); + State.__cpsr = lpContext->Cpsr; + arm_thread_state64_set_fp(State, lpContext->Fp); + arm_thread_state64_set_sp(State, lpContext->Sp); + arm_thread_state64_set_lr_fptr(State, lpContext->Lr); + arm_thread_state64_set_pc_fptr(State, lpContext->Pc); #else #error Unexpected architecture. #endif @@ -1261,6 +1314,10 @@ CONTEXT_SetThreadContextOnPort( StateFlavor = x86_FLOAT_STATE64; StateCount = sizeof(State) / sizeof(natural_t); #endif +#elif defined(HOST_ARM64) + arm_neon_state64_t State; + StateFlavor = ARM_NEON_STATE64; + StateCount = sizeof(State) / sizeof(natural_t); #else #error Unexpected architecture. #endif @@ -1306,6 +1363,10 @@ CONTEXT_SetThreadContextOnPort( memcpy((&State.__fpu_stmm0)[i].__mmst_reg, &lpContext->FltSave.FloatRegisters[i], 10); memcpy(&State.__fpu_xmm0, &lpContext->Xmm0, 16 * 16); +#elif defined(HOST_ARM64) + memcpy(&State.__v, &lpContext->V[0], 32 * 16); + State.__fpsr = lpContext->Fpsr; + State.__fpcr = lpContext->Fpcr; #else #error Unexpected architecture. #endif diff --git a/src/coreclr/src/vm/arm64/asmhelpers.S b/src/coreclr/src/vm/arm64/asmhelpers.S index a8b0a7c07873a..07ceab27585c6 100644 --- a/src/coreclr/src/vm/arm64/asmhelpers.S +++ b/src/coreclr/src/vm/arm64/asmhelpers.S @@ -125,7 +125,7 @@ NESTED_ENTRY NDirectImportThunk, _TEXT, NoHandler SAVE_FLOAT_ARGUMENT_REGISTERS sp, 96 mov x0, x12 - bl NDirectImportWorker + bl C_FUNC(NDirectImportWorker) mov x12, x0 // pop the stack and restore original register state @@ -156,7 +156,7 @@ NESTED_ENTRY PrecodeFixupThunk, _TEXT, NoHandler ldr x13, [x13, #SIZEOF__FixupPrecode] add x12, x13, w14, uxtw #MethodDesc_ALIGNMENT_SHIFT - b ThePreStub + b C_FUNC(ThePreStub) NESTED_END PrecodeFixupThunk, _TEXT // ------------------------------------------------------------------ @@ -167,7 +167,7 @@ NESTED_ENTRY ThePreStub, _TEXT, NoHandler add x0, sp, #__PWTB_TransitionBlock // pTransitionBlock mov x1, METHODDESC_REGISTER // pMethodDesc - bl PreStubWorker + bl C_FUNC(PreStubWorker) mov x9, x0 @@ -610,9 +610,9 @@ NESTED_ENTRY ComCallPreStub, _TEXT, NoHandler str x12, [sp, #(ComCallPreStub_FrameOffset + UnmanagedToManagedFrame__m_pvDatum)] add x0, sp, #(ComCallPreStub_FrameOffset) add x1, sp, #(ComCallPreStub_ErrorReturnOffset) - bl ComPreStubWorker + bl C_FUNC(ComPreStubWorker) - cbz x0, ComCallPreStub_ErrorExit + cbz x0, LOCAL_LABEL(ComCallPreStub_ErrorExit) mov x12, x0 @@ -658,7 +658,7 @@ NESTED_END ComCallPreStub, _TEXT str x12, [sp, #(GenericComCallStub_FrameOffset + UnmanagedToManagedFrame__m_pvDatum)] add x1, sp, #GenericComCallStub_FrameOffset - bl COMToCLRWorker + bl C_FUNC(COMToCLRWorker) // pop the stack EPILOG_STACK_FREE GenericComCallStub_StackAlloc @@ -685,7 +685,7 @@ NESTED_END ComCallPreStub, _TEXT PROLOG_SAVE_REG_PAIR fp, lr, -16! - cbz x0, COMToCLRDispatchHelper_RegSetup + cbz x0, LOCAL_LABEL(COMToCLRDispatchHelper_RegSetup) add x9, x1, #SIZEOF__ComMethodFrame add x9, x9, x0, LSL #3 @@ -693,7 +693,7 @@ COMToCLRDispatchHelper_StackLoop ldr x8, [x9, #-8]! str x8, [sp, #-8]! sub x0, x0, #1 - cbnz x0, COMToCLRDispatchHelper_StackLoop + cbnz x0, LOCAL_LABEL(COMToCLRDispatchHelper_StackLoop) COMToCLRDispatchHelper_RegSetup @@ -766,7 +766,7 @@ NESTED_ENTRY OnHijackTripThread, _TEXT, NoHandler stp q2, q3, [sp, #144] mov x0, sp - bl OnHijackWorker + bl C_FUNC(OnHijackWorker) // restore any integral return value(s) ldp x0, x1, [sp, #96] @@ -987,7 +987,7 @@ LOCAL_LABEL(Promote): mov x12, x9 // We pass the ResolveCacheElem to ResolveWorkerAsmStub instead of the DispatchToken LOCAL_LABEL(Fail): - b ResolveWorkerAsmStub // call the ResolveWorkerAsmStub method to transition into the VM + b C_FUNC(ResolveWorkerAsmStub) // call the ResolveWorkerAsmStub method to transition into the VM NESTED_END ResolveWorkerChainLookupAsmStub, _TEXT @@ -1003,7 +1003,7 @@ NESTED_ENTRY ResolveWorkerAsmStub, _TEXT, NoHandler and x1, x11, #-4 // Indirection cell mov x2, x12 // DispatchToken and x3, x11, #3 // flag - bl VSD_ResolveWorker + bl C_FUNC(VSD_ResolveWorker) mov x9, x0 EPILOG_WITH_TRANSITION_BLOCK_TAILCALL @@ -1015,28 +1015,28 @@ NESTED_END ResolveWorkerAsmStub, _TEXT #ifdef FEATURE_READYTORUN NESTED_ENTRY DelayLoad_MethodCall_FakeProlog, _TEXT, NoHandler -DelayLoad_MethodCall: - .global DelayLoad_MethodCall +C_FUNC(DelayLoad_MethodCall): + .global C_FUNC(DelayLoad_MethodCall) PROLOG_WITH_TRANSITION_BLOCK add x0, sp, #__PWTB_TransitionBlock // pTransitionBlock mov x1, x11 // Indirection cell mov x2, x9 // sectionIndex mov x3, x10 // Module* - bl ExternalMethodFixupWorker + bl C_FUNC(ExternalMethodFixupWorker) mov x12, x0 EPILOG_WITH_TRANSITION_BLOCK_TAILCALL // Share patch label - b ExternalMethodFixupPatchLabel + b C_FUNC(ExternalMethodFixupPatchLabel) NESTED_END DelayLoad_MethodCall_FakeProlog, _TEXT .macro DynamicHelper frameFlags, suffix NESTED_ENTRY DelayLoad_Helper\suffix\()_FakeProlog, _TEXT, NoHandler -DelayLoad_Helper\suffix: - .global DelayLoad_Helper\suffix +C_FUNC(DelayLoad_Helper\suffix): + .global C_FUNC(DelayLoad_Helper\suffix) PROLOG_WITH_TRANSITION_BLOCK @@ -1045,7 +1045,7 @@ DelayLoad_Helper\suffix: mov x2, x9 // sectionIndex mov x3, x10 // Module* mov x4, \frameFlags - bl DynamicHelperWorker + bl C_FUNC(DynamicHelperWorker) cbnz x0, LOCAL_LABEL(FakeProlog\suffix\()_0) ldr x0, [sp, #__PWTB_ArgumentRegister_FirstArg] EPILOG_WITH_TRANSITION_BLOCK_RETURN @@ -1226,7 +1226,7 @@ NESTED_ENTRY \helper\()Naked, _TEXT, NoHandler mov x0, x10 mov x1, sp - bl \helper + bl C_FUNC(\helper) RESTORE_ARGUMENT_REGISTERS sp, 16 // Restore x8 and argument registers. RESTORE_FLOAT_ARGUMENT_REGISTERS sp, 96 // Restore floating-point/SIMD registers. diff --git a/src/coreclr/src/vm/arm64/pinvokestubs.S b/src/coreclr/src/vm/arm64/pinvokestubs.S index 8002ea2b4e03a..ff16e14674ef3 100644 --- a/src/coreclr/src/vm/arm64/pinvokestubs.S +++ b/src/coreclr/src/vm/arm64/pinvokestubs.S @@ -45,7 +45,7 @@ LOCAL_LABEL(\__PInvokeStubFuncName\()_0): - EPILOG_BRANCH \__PInvokeGenStubFuncName + EPILOG_BRANCH C_FUNC(\__PInvokeGenStubFuncName) NESTED_END \__PInvokeStubFuncName, _TEXT @@ -69,7 +69,7 @@ LOCAL_LABEL(\__PInvokeStubFuncName\()_0): // save VASigCookieReg mov x20, \VASigCookieReg - bl \__PInvokeStubWorkerName + bl C_FUNC(\__PInvokeStubWorkerName) // restore VASigCookieReg mov \VASigCookieReg, x20 @@ -80,7 +80,7 @@ LOCAL_LABEL(\__PInvokeStubFuncName\()_0): EPILOG_WITH_TRANSITION_BLOCK_TAILCALL - EPILOG_BRANCH \__PInvokeStubFuncName + EPILOG_BRANCH C_FUNC(\__PInvokeStubFuncName) NESTED_END \__PInvokeGenStubFuncName, _TEXT .endm From 83a45b848f0ab167bbed880f6c2fdb2f560c78f5 Mon Sep 17 00:00:00 2001 From: Steve MacLean Date: Wed, 5 Aug 2020 16:14:03 -0700 Subject: [PATCH 02/89] Remove compact unwind entries from assembly files --- src/coreclr/src/pal/inc/unixasmmacrosarm64.inc | 9 --------- 1 file changed, 9 deletions(-) diff --git a/src/coreclr/src/pal/inc/unixasmmacrosarm64.inc b/src/coreclr/src/pal/inc/unixasmmacrosarm64.inc index faacbb90ea089..9545afb9f8e58 100644 --- a/src/coreclr/src/pal/inc/unixasmmacrosarm64.inc +++ b/src/coreclr/src/pal/inc/unixasmmacrosarm64.inc @@ -14,15 +14,6 @@ .macro NESTED_END Name, Section LEAF_END \Name, \Section -#if defined(__APPLE__) - .set LOCAL_LABEL(\Name\()_Size), . - C_FUNC(\Name) - .section __LD,__compact_unwind,regular,debug - .quad C_FUNC(\Name) - .long LOCAL_LABEL(\Name\()_Size) - .long 0x04000000 // DWARF - .quad 0 - .quad 0 -#endif .endm .macro PATCH_LABEL Name From af1acc48d3033835b0fb82dd69870bd0505e07c8 Mon Sep 17 00:00:00 2001 From: Steve MacLean Date: Wed, 5 Aug 2020 16:16:34 -0700 Subject: [PATCH 03/89] Disable FEATURE_WRITEBARRIER_COPY --- src/coreclr/clrdefinitions.cmake | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/coreclr/clrdefinitions.cmake b/src/coreclr/clrdefinitions.cmake index b717c10d840a4..d8c57d1032119 100644 --- a/src/coreclr/clrdefinitions.cmake +++ b/src/coreclr/clrdefinitions.cmake @@ -226,7 +226,7 @@ if(CLR_CMAKE_TARGET_WIN32) endif(CLR_CMAKE_TARGET_ARCH_AMD64 OR CLR_CMAKE_TARGET_ARCH_I386) endif(CLR_CMAKE_TARGET_WIN32) -if(CLR_CMAKE_TARGET_OSX) +if(CLR_CMAKE_TARGET_OSX AND NOT CLR_CMAKE_TARGET_ARCH_ARM64) add_definitions(-DFEATURE_WRITEBARRIER_COPY) endif(CLR_CMAKE_TARGET_OSX) From 37d29f80da2d7b6d69506201ad7a756eed1a982c Mon Sep 17 00:00:00 2001 From: Steve MacLean Date: Thu, 6 Aug 2020 10:37:04 -0700 Subject: [PATCH 04/89] CONTEXT_SEGMENTS feedback --- src/coreclr/src/pal/inc/pal.h | 4 ---- src/coreclr/src/pal/src/exception/machexception.cpp | 6 +++++- src/coreclr/src/pal/src/thread/context.cpp | 7 ++++--- 3 files changed, 9 insertions(+), 8 deletions(-) diff --git a/src/coreclr/src/pal/inc/pal.h b/src/coreclr/src/pal/inc/pal.h index e3223ba7d4858..fd56fc90c3535 100644 --- a/src/coreclr/src/pal/inc/pal.h +++ b/src/coreclr/src/pal/inc/pal.h @@ -2078,10 +2078,6 @@ typedef struct _IMAGE_ARM_RUNTIME_FUNCTION_ENTRY { #define CONTEXT_FLOATING_POINT (CONTEXT_ARM64 | 0x4L) #define CONTEXT_DEBUG_REGISTERS (CONTEXT_ARM64 | 0x8L) -// There is no segment context for Arm64 -#define CONTEXT_SEGMENTS (0) - - #define CONTEXT_FULL (CONTEXT_CONTROL | CONTEXT_INTEGER | CONTEXT_FLOATING_POINT) #define CONTEXT_ALL (CONTEXT_CONTROL | CONTEXT_INTEGER | CONTEXT_FLOATING_POINT | CONTEXT_DEBUG_REGISTERS) diff --git a/src/coreclr/src/pal/src/exception/machexception.cpp b/src/coreclr/src/pal/src/exception/machexception.cpp index b045fb47ae33f..2560f6464930f 100644 --- a/src/coreclr/src/pal/src/exception/machexception.cpp +++ b/src/coreclr/src/pal/src/exception/machexception.cpp @@ -669,7 +669,7 @@ HijackFaultingThread( threadContext.ContextFlags = CONTEXT_FLOATING_POINT; CONTEXT_GetThreadContextFromThreadState(ARM_NEON_STATE64, (thread_state_t)&exceptionInfo.FloatState, &threadContext); - threadContext.ContextFlags |= CONTEXT_CONTROL | CONTEXT_INTEGER | CONTEXT_SEGMENTS; + threadContext.ContextFlags |= CONTEXT_CONTROL | CONTEXT_INTEGER; CONTEXT_GetThreadContextFromThreadState(ARM_THREAD_STATE64, (thread_state_t)&exceptionInfo.ThreadState, &threadContext); #else #error Unexpected architecture @@ -1528,7 +1528,11 @@ InjectActivationInternal(CPalThread* pThread) // 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) || defined(HOST_X86) pContext->ContextFlags = CONTEXT_FULL | CONTEXT_SEGMENTS; +#else + pContext->ContextFlags = CONTEXT_FULL; +#endif #ifdef XSTATE_SUPPORTED if (XmmYmmStateSupport() == 1) { diff --git a/src/coreclr/src/pal/src/thread/context.cpp b/src/coreclr/src/pal/src/thread/context.cpp index dfb171b85bb58..65d02fc67eb42 100644 --- a/src/coreclr/src/pal/src/thread/context.cpp +++ b/src/coreclr/src/pal/src/thread/context.cpp @@ -949,13 +949,14 @@ CONTEXT_GetThreadContextFromPort( mach_msg_type_number_t StateCount; thread_state_flavor_t StateFlavor; +#if defined(HOST_AMD64) if (lpContext->ContextFlags & (CONTEXT_CONTROL | CONTEXT_INTEGER | CONTEXT_SEGMENTS) & CONTEXT_AREA_MASK) { - -#if defined(HOST_AMD64) x86_thread_state64_t State; StateFlavor = x86_THREAD_STATE64; #elif defined(HOST_ARM64) + if (lpContext->ContextFlags & (CONTEXT_CONTROL | CONTEXT_INTEGER) & CONTEXT_AREA_MASK) + { arm_thread_state64_t State; StateFlavor = ARM_THREAD_STATE64; #else @@ -1136,7 +1137,7 @@ CONTEXT_GetThreadContextFromThreadState( break; #elif defined(HOST_ARM64) case ARM_THREAD_STATE64: - if (lpContext->ContextFlags & (CONTEXT_CONTROL | CONTEXT_INTEGER | CONTEXT_SEGMENTS) & CONTEXT_AREA_MASK) + if (lpContext->ContextFlags & (CONTEXT_CONTROL | CONTEXT_INTEGER) & CONTEXT_AREA_MASK) { arm_thread_state64_t *pState = (arm_thread_state64_t*)threadState; memcpy(&lpContext->X0, &pState->__x[0], 29 * 8); From 8d21b27efd845b8a3622e28b2b719bc0b4357496 Mon Sep 17 00:00:00 2001 From: Steve MacLean Date: Thu, 6 Aug 2020 11:41:00 -0700 Subject: [PATCH 05/89] Revert incidental change --- src/coreclr/src/pal/src/misc/sysinfo.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/coreclr/src/pal/src/misc/sysinfo.cpp b/src/coreclr/src/pal/src/misc/sysinfo.cpp index 9dfc34632b57d..e75cb2f1b89a3 100644 --- a/src/coreclr/src/pal/src/misc/sysinfo.cpp +++ b/src/coreclr/src/pal/src/misc/sysinfo.cpp @@ -568,7 +568,7 @@ PAL_GetLogicalProcessorCacheSizeFromOS() #if defined(HOST_ARM64) && !defined(TARGET_OSX) if(cacheSize == 0) { - uint64_t size; + size_t size; if(ReadMemoryValueFromFile("/sys/devices/system/cpu/cpu0/cache/index0/size", &size)) cacheSize = std::max(cacheSize, size); From e72e45c8ef7ba0d39e8c1afbd220b63e0dd2c993 Mon Sep 17 00:00:00 2001 From: Steve MacLean Date: Thu, 6 Aug 2020 15:28:59 -0700 Subject: [PATCH 06/89] Revise StepWithCompactEncoding --- .../src/pal/src/exception/remote-unwind.cpp | 170 +++++++++++------- 1 file changed, 108 insertions(+), 62 deletions(-) diff --git a/src/coreclr/src/pal/src/exception/remote-unwind.cpp b/src/coreclr/src/pal/src/exception/remote-unwind.cpp index 89301718234d1..58bd59abc49d8 100644 --- a/src/coreclr/src/pal/src/exception/remote-unwind.cpp +++ b/src/coreclr/src/pal/src/exception/remote-unwind.cpp @@ -1368,86 +1368,128 @@ StepWithCompactEncodingRBPFrame(const libunwindInfo* info, compact_unwind_encodi #endif #if defined(TARGET_ARM64) -static bool -StepWithCompactEncodingArm64Frame(const libunwindInfo* info, compact_unwind_encoding_t compactEncoding) +inline static bool +ReadCompactEncodingRegister(const libunwindInfo* info, unw_word_t* addr, DWORD64* reg) { - CONTEXT* context = info->Context; + *addr -= sizeof(uint64_t); + if (!ReadValue64(info, addr, (uint64_t*)reg)) { + return false; + } + return true; +} - unw_word_t fp = context->Fp; - unw_word_t sp = context->Sp; +inline static bool +ReadCompactEncodingRegisterPair(const libunwindInfo* info, unw_word_t* addr, DWORD64*second, DWORD64* first) +{ + // Registers are effectively pushed in pairs + // + // *addr -= 8 + // **addr = *first + // *addr -= 8 + // **addr = *second + if (!ReadCompactEncodingRegister(info, addr, first)) { + return false; + } + if (!ReadCompactEncodingRegister(info, addr, second)) { + return false; + } + return true; +} - // caller Sp is callee Fp less saved FP and LR - context->Sp = fp + (sizeof(uint64_t) * 2); +inline static bool +ReadCompactEncodingRegisterPair(const libunwindInfo* info, unw_word_t* addr, NEON128*second, NEON128* first) +{ + if (!ReadCompactEncodingRegisterPair(info, addr, &first->Low, &second->Low)) { + return false; + } + first->High = 0; + second->High = 0; + return true; +} - context->Pc = context->Lr; +// Saved registers are pushed +// + in pairs +// + in register number order (after the option frame registers) +// + after the callers SP +// +// Given C++ code that generates this prologue spill sequence +// +// sub sp, sp, #128 ; =128 +// stp d15, d14, [sp, #16] ; 16-byte Folded Spill +// stp d13, d12, [sp, #32] ; 16-byte Folded Spill +// stp d11, d10, [sp, #48] ; 16-byte Folded Spill +// stp d9, d8, [sp, #64] ; 16-byte Folded Spill +// stp x22, x21, [sp, #80] ; 16-byte Folded Spill +// stp x20, x19, [sp, #96] ; 16-byte Folded Spill +// stp x29, x30, [sp, #112] ; 16-byte Folded Spill +// add x29, sp, #112 ; =112 +// +// The compiler generates: +// compactEncoding = 0x04000f03; +static bool +StepWithCompactEncodingArm64(const libunwindInfo* info, compact_unwind_encoding_t compactEncoding, bool hasFrame) +{ + CONTEXT* context = info->Context; - unw_word_t addr = fp; + unw_word_t callerSp; - if (!ReadValue64(info, &addr, (uint64_t*)&context->Fp)) { - return false; + if (hasFrame) { + // caller Sp is callee Fp plus saved FP and LR + callerSp = context->Fp + 2 * sizeof(uint64_t); + } else { + // Get the leat significant bit in UNWIND_ARM64_FRAMELESS_STACK_SIZE_MASK + uint64_t stackSizeScale = UNWIND_ARM64_FRAMELESS_STACK_SIZE_MASK & ~(UNWIND_ARM64_FRAMELESS_STACK_SIZE_MASK - 1); + uint64_t stackSize = (compactEncoding & UNWIND_ARM64_FRAMELESS_STACK_SIZE_MASK) / stackSizeScale * 16; + + callerSp = context->Sp + stackSize; } - addr += sizeof(uint64_t); + context->Sp = callerSp; - if (!ReadValue64(info, &addr, (uint64_t*)&context->Lr)) { - return false; - } - addr += sizeof(uint64_t); + // return address is stored in Lr + context->Pc = context->Lr; - if (compactEncoding & UNWIND_ARM64_FRAME_X19_X20_PAIR) - { - if (!ReadValue64(info, &addr, (uint64_t*)&context->X[19])) { + unw_word_t addr = callerSp; + + if (hasFrame && + !ReadCompactEncodingRegisterPair(info, &addr, &context->Lr, &context->Fp)) { return false; - } - addr += sizeof(uint64_t); - if (!ReadValue64(info, &addr, (uint64_t*)&context->X[20])) { + } + if (compactEncoding & UNWIND_ARM64_FRAME_X19_X20_PAIR && + !ReadCompactEncodingRegisterPair(info, &addr, &context->X[19], &context->X[20])) { return false; - } - addr += sizeof(uint64_t); } - if (compactEncoding & UNWIND_ARM64_FRAME_X21_X22_PAIR) - { - if (!ReadValue64(info, &addr, (uint64_t*)&context->X[21])) { + if (compactEncoding & UNWIND_ARM64_FRAME_X21_X22_PAIR && + !ReadCompactEncodingRegisterPair(info, &addr, &context->X[21], &context->X[22])) { return false; - } - addr += sizeof(uint64_t); - if (!ReadValue64(info, &addr, (uint64_t*)&context->X[22])) { + } + if (compactEncoding & UNWIND_ARM64_FRAME_X23_X24_PAIR && + !ReadCompactEncodingRegisterPair(info, &addr, &context->X[23], &context->X[24])) { return false; - } - addr += sizeof(uint64_t); } - if (compactEncoding & UNWIND_ARM64_FRAME_X23_X24_PAIR) - { - if (!ReadValue64(info, &addr, (uint64_t*)&context->X[23])) { + if (compactEncoding & UNWIND_ARM64_FRAME_X25_X26_PAIR && + !ReadCompactEncodingRegisterPair(info, &addr, &context->X[25], &context->X[26])) { return false; - } - addr += sizeof(uint64_t); - if (!ReadValue64(info, &addr, (uint64_t*)&context->X[24])) { + } + if (compactEncoding & UNWIND_ARM64_FRAME_X27_X28_PAIR && + !ReadCompactEncodingRegisterPair(info, &addr, &context->X[27], &context->X[28])) { return false; - } - addr += sizeof(uint64_t); } - if (compactEncoding & UNWIND_ARM64_FRAME_X25_X26_PAIR) - { - if (!ReadValue64(info, &addr, (uint64_t*)&context->X[25])) { + if (compactEncoding & UNWIND_ARM64_FRAME_D8_D9_PAIR && + !ReadCompactEncodingRegisterPair(info, &addr, &context->V[8], &context->V[9])) { return false; - } - addr += sizeof(uint64_t); - if (!ReadValue64(info, &addr, (uint64_t*)&context->X[26])) { + } + if (compactEncoding & UNWIND_ARM64_FRAME_D10_D11_PAIR && + !ReadCompactEncodingRegisterPair(info, &addr, &context->V[10], &context->V[11])) { return false; - } - addr += sizeof(uint64_t); } - if (compactEncoding & UNWIND_ARM64_FRAME_X27_X28_PAIR) - { - if (!ReadValue64(info, &addr, (uint64_t*)&context->X[27])) { + if (compactEncoding & UNWIND_ARM64_FRAME_D12_D13_PAIR && + !ReadCompactEncodingRegisterPair(info, &addr, &context->V[12], &context->V[13])) { return false; - } - addr += sizeof(uint64_t); - if (!ReadValue64(info, &addr, (uint64_t*)&context->X[28])) { + } + if (compactEncoding & UNWIND_ARM64_FRAME_D14_D15_PAIR && + !ReadCompactEncodingRegisterPair(info, &addr, &context->V[14], &context->V[15])) { return false; - } - addr += sizeof(uint64_t); } TRACE("SUCCESS: compact step encoding %08x pc %p sp %p fp %p lr %p\n", @@ -1473,9 +1515,10 @@ StepWithCompactEncoding(const libunwindInfo* info, compact_unwind_encoding_t com case UNWIND_X86_64_MODE_STACK_IMMD: case UNWIND_X86_64_MODE_STACK_IND: break; - + + case UNWIND_X86_64_MODE_DWARF: + return false; } - ERROR("Invalid encoding %08x\n", compactEncoding); #elif defined(TARGET_ARM64) if (compactEncoding == 0) { @@ -1485,15 +1528,18 @@ StepWithCompactEncoding(const libunwindInfo* info, compact_unwind_encoding_t com switch (compactEncoding & UNWIND_ARM64_MODE_MASK) { case UNWIND_ARM64_MODE_FRAME: - return StepWithCompactEncodingArm64Frame(info, compactEncoding); + return StepWithCompactEncodingArm64(info, compactEncoding, true); case UNWIND_ARM64_MODE_FRAMELESS: - break; + return StepWithCompactEncodingArm64(info, compactEncoding, false); + + case UNWIND_ARM64_MODE_DWARF: + return false; } - ERROR("Invalid encoding %08x\n", compactEncoding); #else - ERROR("Unsupported architecture. encoding %08x\n", compactEncoding); +#error unsupported architecture #endif + ERROR("Invalid encoding %08x\n", compactEncoding); return false; } From 657a57be3b328658ad8713ee73ef3573bad875c3 Mon Sep 17 00:00:00 2001 From: Steve MacLean Date: Sat, 8 Aug 2020 09:14:04 -0700 Subject: [PATCH 07/89] Fix CLR_CMAKE_HOST_* arch --- eng/native/configureplatform.cmake | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/eng/native/configureplatform.cmake b/eng/native/configureplatform.cmake index dbfadfda59914..9b0f1e5212265 100644 --- a/eng/native/configureplatform.cmake +++ b/eng/native/configureplatform.cmake @@ -79,7 +79,11 @@ if(CLR_CMAKE_HOST_OS STREQUAL Darwin) set(CLR_CMAKE_HOST_UNIX 1) set(CLR_CMAKE_HOST_OSX 1) if(CMAKE_SYSTEM_PROCESSOR STREQUAL x86_64) - set(CLR_CMAKE_HOST_UNIX_AMD64 1) + if(NOT CLR_CROSS_COMPONENTS_BUILD AND CLR_CMAKE_TARGET_ARCH STREQUAL arm64) + set(CLR_CMAKE_HOST_UNIX_ARM64 1) + else(CLR_CMAKE_TARGET_ARCH STREQUAL arm64) + set(CLR_CMAKE_HOST_UNIX_AMD64 1) + endif(CLR_CMAKE_TARGET_ARCH STREQUAL arm64) elseif(CMAKE_SYSTEM_PROCESSOR STREQUAL arm64) set(CLR_CMAKE_HOST_UNIX_ARM64 1) else() From 7457f371870b81b2e21d9cb2ae14be65eca8509f Mon Sep 17 00:00:00 2001 From: Steve MacLean Date: Sat, 8 Aug 2020 09:19:28 -0700 Subject: [PATCH 08/89] Workaround using dotnet/msbuild with rosetta When using the osx-x64 version of dotnet to build on a osx-arm64 machine. The uname -m is spoofed by rosetta to return x64 on a arm64 machine. As a temporary workaround allow CPUName as an environment variable override the arch discovered by eng/native/init-os-and-arch.sh Also modify crossgen2.csproj to use CLR_CMAKE_HOST_ARCH when calculating CrossHostArch --- eng/native/init-os-and-arch.sh | 2 +- src/coreclr/src/tools/aot/crossgen2/crossgen2.csproj | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/eng/native/init-os-and-arch.sh b/eng/native/init-os-and-arch.sh index 0a6018386575e..c021edec32649 100644 --- a/eng/native/init-os-and-arch.sh +++ b/eng/native/init-os-and-arch.sh @@ -29,7 +29,7 @@ if [ "$os" = "SunOS" ]; then CPUName=$(isainfo -n) else # For rest of the operating systems, use uname(1) to determine what the CPU is. - CPUName=$(uname -m) + CPUName=${CPUName:=$(uname -m)} fi case "$CPUName" in diff --git a/src/coreclr/src/tools/aot/crossgen2/crossgen2.csproj b/src/coreclr/src/tools/aot/crossgen2/crossgen2.csproj index 2de5f56821453..68afd815ec6c2 100644 --- a/src/coreclr/src/tools/aot/crossgen2/crossgen2.csproj +++ b/src/coreclr/src/tools/aot/crossgen2/crossgen2.csproj @@ -42,7 +42,7 @@ - x64 + x64 unix win From f3dcdf30440368b7c7ac3bb763bb203ab3bf46b4 Mon Sep 17 00:00:00 2001 From: Steve MacLean Date: Mon, 10 Aug 2020 11:29:17 -0700 Subject: [PATCH 09/89] Feedback on OSX does not support X86 --- src/coreclr/src/debug/createdump/mac.h | 2 +- .../src/debug/createdump/threadinfomac.cpp | 2 +- .../src/pal/src/exception/machexception.cpp | 32 +++++++++---------- .../src/pal/src/exception/machmessage.cpp | 2 +- .../src/pal/src/exception/machmessage.h | 2 +- .../src/pal/src/exception/remote-unwind.cpp | 6 ++-- src/coreclr/src/pal/src/thread/context.cpp | 4 +-- 7 files changed, 24 insertions(+), 26 deletions(-) diff --git a/src/coreclr/src/debug/createdump/mac.h b/src/coreclr/src/debug/createdump/mac.h index 48ab16cb84c99..87745903ab183 100644 --- a/src/coreclr/src/debug/createdump/mac.h +++ b/src/coreclr/src/debug/createdump/mac.h @@ -68,7 +68,7 @@ typedef struct elf64_note { Elf64_Word n_type; /* Content type */ } Elf64_Nhdr; -#if defined(TARGET_AMD64) || defined(TARGET_X86) +#if defined(TARGET_AMD64) struct user_fpregs_struct { unsigned short int cwd; diff --git a/src/coreclr/src/debug/createdump/threadinfomac.cpp b/src/coreclr/src/debug/createdump/threadinfomac.cpp index d17eed24bc98f..c2a1b3cfd3282 100644 --- a/src/coreclr/src/debug/createdump/threadinfomac.cpp +++ b/src/coreclr/src/debug/createdump/threadinfomac.cpp @@ -25,7 +25,7 @@ ThreadInfo::Initialize() m_ppid = 0; m_tgid = 0; -#if defined(TARGET_AMD64) || defined(TARGET_X86) +#if defined(TARGET_AMD64) x86_thread_state64_t state; mach_msg_type_number_t stateCount = x86_THREAD_STATE64_COUNT; kern_return_t result = ::thread_get_state(Port(), x86_THREAD_STATE64, (thread_state_t)&state, &stateCount); diff --git a/src/coreclr/src/pal/src/exception/machexception.cpp b/src/coreclr/src/pal/src/exception/machexception.cpp index 2560f6464930f..7b02f9f605c15 100644 --- a/src/coreclr/src/pal/src/exception/machexception.cpp +++ b/src/coreclr/src/pal/src/exception/machexception.cpp @@ -356,7 +356,7 @@ PAL_ERROR CorUnix::CPalThread::DisableMachExceptions() return palError; } -#if defined(HOST_AMD64) || defined(HOST_X86) +#if defined(HOST_AMD64) // Since HijackFaultingThread pushed the context, exception record and info on the stack, we need to adjust the // signature of PAL_DispatchException such that the corresponding arguments are considered to be on the stack // per GCC64 calling convention rules. Hence, the first 6 dummy arguments (corresponding to RDI, RSI, RDX,RCX, R8, R9). @@ -446,7 +446,7 @@ BuildExceptionRecord( } else { -#if defined(HOST_AMD64) || defined(HOST_X86) +#if defined(HOST_AMD64) exceptionCode = EXCEPTION_ACCESS_VIOLATION; #elif defined(HOST_ARM64) switch (exceptionInfo.Subcodes[0]) @@ -497,7 +497,7 @@ BuildExceptionRecord( { switch (exceptionInfo.Subcodes[0]) { -#if defined(HOST_AMD64) || defined(HOST_X86) +#if defined(HOST_AMD64) case EXC_I386_DIV: exceptionCode = EXCEPTION_INT_DIVIDE_BY_ZERO; break; @@ -545,7 +545,7 @@ BuildExceptionRecord( // Trace, breakpoint, etc. Details in subcode field. case EXC_BREAKPOINT: -#if defined(HOST_AMD64) || defined(HOST_X86) +#if defined(HOST_AMD64) if (exceptionInfo.Subcodes[0] == EXC_I386_SGL) { exceptionCode = EXCEPTION_SINGLE_STEP; @@ -655,7 +655,7 @@ HijackFaultingThread( // Fill in the exception record from the exception info BuildExceptionRecord(exceptionInfo, &exceptionRecord); -#if defined(HOST_AMD64) || defined(HOST_X86) +#if defined(HOST_AMD64) void **targetSP = (void **)threadContext.Rsp; threadContext.ContextFlags = CONTEXT_FLOATING_POINT; @@ -793,7 +793,7 @@ HijackFaultingThread( exceptionRecord.ExceptionFlags = EXCEPTION_IS_SIGNAL; exceptionRecord.ExceptionRecord = NULL; -#if defined(HOST_AMD64) || defined(HOST_X86) +#if defined(HOST_AMD64) NONPAL_ASSERTE(exceptionInfo.ThreadState.tsh.flavor == x86_THREAD_STATE64); // Make a copy of the thread state because the one in exceptionInfo needs to be preserved to restore @@ -845,7 +845,7 @@ HijackFaultingThread( // PAL_DispatchExceptionWrapper has an ebp frame, its local variables // are the context and exception record, and it has just "called" // PAL_DispatchException. -#if defined(HOST_AMD64) || defined(HOST_X86) +#if defined(HOST_AMD64) *--FramePointer = (void *)ts64.__rip; *--FramePointer = (void *)ts64.__rbp; @@ -875,7 +875,7 @@ HijackFaultingThread( MachExceptionInfo *pMachExceptionInfo = (MachExceptionInfo *)FramePointer; *pMachExceptionInfo = exceptionInfo; -#if defined(HOST_AMD64) || defined(HOST_X86) +#if defined(HOST_AMD64) // Push arguments to PAL_DispatchException FramePointer = (void **)((ULONG_PTR)FramePointer - 3 * sizeof(void *)); @@ -1047,7 +1047,7 @@ SEHExceptionThread(void *args) for (int i = 0; i < subcode_count; i++) NONPAL_TRACE("ExceptionNotification subcode[%d] = %llx\n", i, (uint64_t) sMessage.GetExceptionCode(i)); -#if defined(HOST_AMD64) || defined(HOST_X86) +#if defined(HOST_AMD64) x86_thread_state64_t threadStateActual; unsigned int count = sizeof(threadStateActual) / sizeof(unsigned); machret = thread_get_state(thread, x86_THREAD_STATE64, (thread_state_t)&threadStateActual, &count); @@ -1220,7 +1220,7 @@ MachExceptionInfo::MachExceptionInfo(mach_port_t thread, MachMessage& message) for (int i = 0; i < SubcodeCount; i++) Subcodes[i] = message.GetExceptionCode(i); -#if defined(HOST_AMD64) || defined(HOST_X86) +#if defined(HOST_AMD64) mach_msg_type_number_t count = x86_THREAD_STATE_COUNT; machret = thread_get_state(thread, x86_THREAD_STATE, (thread_state_t)&ThreadState, &count); CHECK_MACH("thread_get_state", machret); @@ -1263,7 +1263,7 @@ Return value : --*/ void MachExceptionInfo::RestoreState(mach_port_t thread) { -#if defined(HOST_AMD64) || defined(HOST_X86) +#if defined(HOST_AMD64) // If we are restarting a breakpoint, we need to bump the IP back one to // point at the actual int 3 instructions. if (ExceptionType == EXC_BREAKPOINT) @@ -1457,7 +1457,7 @@ InjectActivationInternal(CPalThread* pThread) if (palError == NO_ERROR) { -#if defined(HOST_AMD64) || defined(HOST_X86) +#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; @@ -1484,7 +1484,7 @@ InjectActivationInternal(CPalThread* pThread) &count); _ASSERT_MSG(MachRet == KERN_SUCCESS, "thread_get_state for *_EXCEPTION_STATE64\n"); -#if defined(HOST_AMD64) || defined(HOST_X86) +#if defined(HOST_AMD64) // Inject the activation only if the thread doesn't have a pending hardware exception static const int MaxHardwareExceptionVector = 31; if (ExceptionState.__trapno > MaxHardwareExceptionVector) @@ -1501,7 +1501,7 @@ InjectActivationInternal(CPalThread* pThread) &count); _ASSERT_MSG(MachRet == KERN_SUCCESS, "thread_get_state for *_THREAD_STATE64\n"); -#if defined(HOST_AMD64) || defined(HOST_X86) +#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 @@ -1528,7 +1528,7 @@ InjectActivationInternal(CPalThread* pThread) // 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) || defined(HOST_X86) +#if defined(HOST_AMD64) pContext->ContextFlags = CONTEXT_FULL | CONTEXT_SEGMENTS; #else pContext->ContextFlags = CONTEXT_FULL; @@ -1542,7 +1542,7 @@ InjectActivationInternal(CPalThread* pThread) MachRet = CONTEXT_GetThreadContextFromPort(threadPort, pContext); _ASSERT_MSG(MachRet == KERN_SUCCESS, "CONTEXT_GetThreadContextFromPort\n"); -#if defined(HOST_AMD64) || defined(HOST_X86) +#if defined(HOST_AMD64) size_t returnAddressAddress = contextAddress - sizeof(size_t); *(size_t*)(returnAddressAddress) = ActivationHandlerReturnOffset + (size_t)ActivationHandlerWrapper; diff --git a/src/coreclr/src/pal/src/exception/machmessage.cpp b/src/coreclr/src/pal/src/exception/machmessage.cpp index b4157b5fc3660..049b93500bcec 100644 --- a/src/coreclr/src/pal/src/exception/machmessage.cpp +++ b/src/coreclr/src/pal/src/exception/machmessage.cpp @@ -1035,7 +1035,7 @@ thread_act_t MachMessage::GetThreadFromState(thread_state_flavor_t eFlavor, thre for (mach_msg_type_number_t i = 0; i < cThreads; i++) { // Get the general register state of each thread. -#if defined(HOST_AMD64) || defined(HOST_X86) +#if defined(HOST_AMD64) x86_thread_state_t threadState; mach_msg_type_number_t count = x86_THREAD_STATE_COUNT; machret = thread_get_state(pThreads[i], x86_THREAD_STATE, (thread_state_t)&threadState, &count); diff --git a/src/coreclr/src/pal/src/exception/machmessage.h b/src/coreclr/src/pal/src/exception/machmessage.h index f43999b201ac0..ff288ad6f25b2 100644 --- a/src/coreclr/src/pal/src/exception/machmessage.h +++ b/src/coreclr/src/pal/src/exception/machmessage.h @@ -87,7 +87,7 @@ struct MachExceptionInfo exception_type_t ExceptionType; mach_msg_type_number_t SubcodeCount; MACH_EH_TYPE(exception_data_type_t) Subcodes[2]; -#if defined(HOST_AMD64) || defined(HOST_X86) +#if defined(HOST_AMD64) x86_thread_state_t ThreadState; x86_float_state_t FloatState; x86_debug_state_t DebugState; diff --git a/src/coreclr/src/pal/src/exception/remote-unwind.cpp b/src/coreclr/src/pal/src/exception/remote-unwind.cpp index 58bd59abc49d8..53b50c3b963c3 100644 --- a/src/coreclr/src/pal/src/exception/remote-unwind.cpp +++ b/src/coreclr/src/pal/src/exception/remote-unwind.cpp @@ -1296,7 +1296,7 @@ GetProcInfo(unw_word_t ip, unw_proc_info_t *pip, const libunwindInfo* info, bool return false; } -#if defined(TARGET_X86) || defined(TARGET_AMD64) +#if defined(TARGET_AMD64) static bool StepWithCompactEncodingRBPFrame(const libunwindInfo* info, compact_unwind_encoding_t compactEncoding) { @@ -1501,7 +1501,7 @@ StepWithCompactEncodingArm64(const libunwindInfo* info, compact_unwind_encoding_ static bool StepWithCompactEncoding(const libunwindInfo* info, compact_unwind_encoding_t compactEncoding, unw_word_t functionStart) { -#if defined(TARGET_X86) || defined(TARGET_AMD64) +#if defined(TARGET_AMD64) if (compactEncoding == 0) { TRACE("Compact unwind missing for %p\n", (void*)info->Context->Rip); @@ -2011,7 +2011,7 @@ PAL_VirtualUnwindOutOfProc(CONTEXT *context, KNONVOLATILE_CONTEXT_POINTERS *cont #ifdef __APPLE__ unw_proc_info_t procInfo; bool step; -#if defined(TARGET_X86) || defined(TARGET_AMD64) +#if defined(TARGET_AMD64) TRACE("Unwind: rip %p rsp %p rbp %p\n", (void*)context->Rip, (void*)context->Rsp, (void*)context->Rbp); result = GetProcInfo(context->Rip, &procInfo, &info, &step, false); #elif defined(TARGET_ARM64) diff --git a/src/coreclr/src/pal/src/thread/context.cpp b/src/coreclr/src/pal/src/thread/context.cpp index 65d02fc67eb42..5e733103ba768 100644 --- a/src/coreclr/src/pal/src/thread/context.cpp +++ b/src/coreclr/src/pal/src/thread/context.cpp @@ -1049,8 +1049,7 @@ CONTEXT_GetThreadContextFromThreadState( { switch (threadStateFlavor) { -#if defined (HOST_AMD64) || defined(HOST_X86) -#ifdef HOST_AMD64 +#if defined (HOST_AMD64) case x86_THREAD_STATE64: if (lpContext->ContextFlags & (CONTEXT_CONTROL | CONTEXT_INTEGER | CONTEXT_SEGMENTS) & CONTEXT_AREA_MASK) { @@ -1121,7 +1120,6 @@ CONTEXT_GetThreadContextFromThreadState( memcpy(&lpContext->Xmm0, &pState->__fpu_xmm0, 16 * 16); } break; -#endif // HOST_AMD64 case x86_THREAD_STATE: { x86_thread_state_t *pState = (x86_thread_state_t *)threadState; From 96d4787bf7e296b89a99671242aca163aa8c2a11 Mon Sep 17 00:00:00 2001 From: Steve MacLean Date: Mon, 10 Aug 2020 11:43:41 -0700 Subject: [PATCH 10/89] Feedback fix typo --- src/coreclr/src/pal/src/exception/machexception.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/coreclr/src/pal/src/exception/machexception.cpp b/src/coreclr/src/pal/src/exception/machexception.cpp index 7b02f9f605c15..d85f1a6d4b7d6 100644 --- a/src/coreclr/src/pal/src/exception/machexception.cpp +++ b/src/coreclr/src/pal/src/exception/machexception.cpp @@ -1511,7 +1511,7 @@ InjectActivationInternal(CPalThread* pThread) *(--sp) = ThreadState.__rbp; size_t rbpAddress = (size_t)sp; #elif defined(HOST_ARM64) - if ((g_safeActivationCheckFunction != NULL) && g_safeActivationCheckFunction(arm_thread_state64_get_lr(ThreadState), /* checkingCurrentThread */ FALSE)) + if ((g_safeActivationCheckFunction != NULL) && g_safeActivationCheckFunction(arm_thread_state64_get_ip(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? From ba2f9ae8663415198666af522647fa51e4686f49 Mon Sep 17 00:00:00 2001 From: Steve MacLean Date: Mon, 10 Aug 2020 13:28:55 -0700 Subject: [PATCH 11/89] Fix init-os-and-arch.sh --- eng/native/init-os-and-arch.sh | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/eng/native/init-os-and-arch.sh b/eng/native/init-os-and-arch.sh index c021edec32649..7bda16f77a275 100644 --- a/eng/native/init-os-and-arch.sh +++ b/eng/native/init-os-and-arch.sh @@ -27,9 +27,20 @@ if [ "$os" = "SunOS" ]; then os="Solaris" fi CPUName=$(isainfo -n) +elif [ "$os" = "OSX" ]; then + # On OSX universal binaries make uname -m unreliable. The uname -m response changes + # based on what hardware is being emulated. + # Use sysctl instead + if [ "$(sysctl -q -n hw.optional.arm64)" = "1" ]; then + CPUName=arm64 + elif [ "$(sysctl -q -n hw.optional.x86_64)" = "1" ]; then + CPUName=x86_64 + else + CPUName=$(uname -m) + fi else # For rest of the operating systems, use uname(1) to determine what the CPU is. - CPUName=${CPUName:=$(uname -m)} + CPUName=$(uname -m) fi case "$CPUName" in From 6cb8cebf6ea5828dfacdb53dd57274bb337bfeac Mon Sep 17 00:00:00 2001 From: Steve MacLean Date: Mon, 10 Aug 2020 13:38:21 -0700 Subject: [PATCH 12/89] Fix cmake closing conditonal mismatch --- src/coreclr/clrdefinitions.cmake | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/coreclr/clrdefinitions.cmake b/src/coreclr/clrdefinitions.cmake index d8c57d1032119..8f8e8a0f08c0b 100644 --- a/src/coreclr/clrdefinitions.cmake +++ b/src/coreclr/clrdefinitions.cmake @@ -228,7 +228,7 @@ endif(CLR_CMAKE_TARGET_WIN32) if(CLR_CMAKE_TARGET_OSX AND NOT CLR_CMAKE_TARGET_ARCH_ARM64) add_definitions(-DFEATURE_WRITEBARRIER_COPY) -endif(CLR_CMAKE_TARGET_OSX) +endif(CLR_CMAKE_TARGET_OSX AND NOT CLR_CMAKE_TARGET_ARCH_ARM64) if (NOT CLR_CMAKE_TARGET_ARCH_I386 OR NOT CLR_CMAKE_TARGET_WIN32) add_definitions(-DFEATURE_EH_FUNCLETS) From 27ebc7a36376fb7035c95bbc7e60f25fdee2cfca Mon Sep 17 00:00:00 2001 From: Steve MacLean Date: Mon, 10 Aug 2020 15:40:55 -0700 Subject: [PATCH 13/89] Fix crossgen2 by adding HostArchitecture --- Directory.Build.props | 1 + eng/build.sh | 4 +++- src/coreclr/src/tools/aot/crossgen2/crossgen2.csproj | 2 +- 3 files changed, 5 insertions(+), 2 deletions(-) diff --git a/Directory.Build.props b/Directory.Build.props index c4bcb9a625589..1061c0ed3a77a 100644 --- a/Directory.Build.props +++ b/Directory.Build.props @@ -101,6 +101,7 @@ Properties $([System.Runtime.InteropServices.RuntimeInformation]::ProcessArchitecture.ToString().ToLowerInvariant()) + $(BuildArchitecture) diff --git a/eng/build.sh b/eng/build.sh index da8e3770f595a..d7625bfde2e9f 100755 --- a/eng/build.sh +++ b/eng/build.sh @@ -147,6 +147,8 @@ portableBuild=1 source $scriptroot/native/init-os-and-arch.sh +hostArch=$arch + # Check if an action is passed in declare -a actions=("b" "build" "r" "restore" "rebuild" "testnobuild" "sign" "publish" "clean") actInt=($(comm -12 <(printf '%s\n' "${actions[@]/#/-}" | sort) <(printf '%s\n' "${@/#--/-}" | sort))) @@ -393,6 +395,6 @@ initDistroRid $os $arch $crossBuild $portableBuild # URL-encode space (%20) to avoid quoting issues until the msbuild call in /eng/common/tools.sh. # In *proj files (XML docs), URL-encoded string are rendered in their decoded form. cmakeargs="${cmakeargs// /%20}" -arguments="$arguments /p:TargetArchitecture=$arch" +arguments="$arguments /p:TargetArchitecture=$arch /p:HostArchitecture:$hostArch" arguments="$arguments /p:CMakeArgs=\"$cmakeargs\" $extraargs" "$scriptroot/common/build.sh" $arguments diff --git a/src/coreclr/src/tools/aot/crossgen2/crossgen2.csproj b/src/coreclr/src/tools/aot/crossgen2/crossgen2.csproj index 68afd815ec6c2..5157677d6c810 100644 --- a/src/coreclr/src/tools/aot/crossgen2/crossgen2.csproj +++ b/src/coreclr/src/tools/aot/crossgen2/crossgen2.csproj @@ -42,7 +42,7 @@ - x64 + x64 unix win From b80e9c0bc86aca1f76415e5d40d63d6aecd0d891 Mon Sep 17 00:00:00 2001 From: Steve MacLean Date: Wed, 12 Aug 2020 10:38:22 -0700 Subject: [PATCH 14/89] Fix typo --- eng/build.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/eng/build.sh b/eng/build.sh index 58e1016398ea5..cd837619bae43 100755 --- a/eng/build.sh +++ b/eng/build.sh @@ -398,6 +398,6 @@ initDistroRid $os $arch $crossBuild $portableBuild # URL-encode space (%20) to avoid quoting issues until the msbuild call in /eng/common/tools.sh. # In *proj files (XML docs), URL-encoded string are rendered in their decoded form. cmakeargs="${cmakeargs// /%20}" -arguments="$arguments /p:TargetArchitecture=$arch /p:HostArchitecture:$hostArch" +arguments="$arguments /p:TargetArchitecture=$arch /p:HostArchitecture=$hostArch" arguments="$arguments /p:CMakeArgs=\"$cmakeargs\" $extraargs" "$scriptroot/common/build.sh" $arguments From bca94f70dbb07cb936091267824959bfa58d0dd5 Mon Sep 17 00:00:00 2001 From: Steve MacLean Date: Wed, 12 Aug 2020 13:07:41 -0700 Subject: [PATCH 15/89] Fix HostArchitecture Condition --- Directory.Build.props | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Directory.Build.props b/Directory.Build.props index 849639d7e2f45..82e6284aace3c 100644 --- a/Directory.Build.props +++ b/Directory.Build.props @@ -101,7 +101,7 @@ Properties $([System.Runtime.InteropServices.RuntimeInformation]::ProcessArchitecture.ToString().ToLowerInvariant()) - $(BuildArchitecture) + $(BuildArchitecture) false From 0e7b3c89b665963294b8a924fe84c9bd2b4d1da2 Mon Sep 17 00:00:00 2001 From: Steve MacLean Date: Thu, 13 Aug 2020 15:28:46 -0700 Subject: [PATCH 16/89] Fix libraries native build --- src/libraries/Native/build-native.sh | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/src/libraries/Native/build-native.sh b/src/libraries/Native/build-native.sh index fb8b183403eb5..4fa1fc12ad025 100755 --- a/src/libraries/Native/build-native.sh +++ b/src/libraries/Native/build-native.sh @@ -69,7 +69,7 @@ else __CMakeArgs="-DFEATURE_DISTRO_AGNOSTIC_SSL=$__PortableBuild $__CMakeArgs" __CMakeArgs="-DCMAKE_STATIC_LIB_LINK=$__StaticLibLink $__CMakeArgs" - if [[ "$__BuildArch" != x86 && "$__BuildArch" != x64 ]]; then + if [[ "$__BuildArch" != x86 && "$__BuildArch" != x64 && "$__BuildArch" != "$__HostArch" ]]; then __CrossBuild=1 echo "Set CrossBuild for $__BuildArch build" fi @@ -78,6 +78,14 @@ fi if [[ "$__TargetOS" == OSX ]]; then # set default OSX deployment target __CMakeArgs="-DCMAKE_OSX_DEPLOYMENT_TARGET=10.13 $__CMakeArgs" + if [[ "$__BuildArch" == x64 ]]; then + __CMakeArgs="-DCMAKE_OSX_ARCHITECTURES=\"x86_64\" $__CMakeArgs" + elif [[ "$__BuildArch" == arm64 ]]; then + __CMakeArgs="-DCMAKE_OSX_ARCHITECTURES=\"arm64\" $__CMakeArgs" + else + echo "Error: Unknown OSX architecture $__BuildArch." + exit 1 + fi elif [[ "$__TargetOS" == Android && -z "$ROOTFS_DIR" ]]; then if [[ -z "$ANDROID_NDK_ROOT" ]]; then echo "Error: You need to set the ANDROID_NDK_ROOT environment variable pointing to the Android NDK root." From 06eef47411776a81eb2b977df919647dac7fb71a Mon Sep 17 00:00:00 2001 From: Steve MacLean Date: Fri, 14 Aug 2020 16:32:22 -0700 Subject: [PATCH 17/89] Fix typo --- src/coreclr/src/pal/src/exception/machexception.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/coreclr/src/pal/src/exception/machexception.cpp b/src/coreclr/src/pal/src/exception/machexception.cpp index d85f1a6d4b7d6..9b4e482c96990 100644 --- a/src/coreclr/src/pal/src/exception/machexception.cpp +++ b/src/coreclr/src/pal/src/exception/machexception.cpp @@ -1511,7 +1511,7 @@ InjectActivationInternal(CPalThread* pThread) *(--sp) = ThreadState.__rbp; size_t rbpAddress = (size_t)sp; #elif defined(HOST_ARM64) - if ((g_safeActivationCheckFunction != NULL) && g_safeActivationCheckFunction(arm_thread_state64_get_ip(ThreadState), /* checkingCurrentThread */ FALSE)) + if ((g_safeActivationCheckFunction != NULL) && g_safeActivationCheckFunction(arm_thread_state64_get_pc(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? From d13d6bcd4994f75079f15fdedfb6c7e2bf8f410e Mon Sep 17 00:00:00 2001 From: Steve MacLean Date: Fri, 14 Aug 2020 16:33:48 -0700 Subject: [PATCH 18/89] Reenable FEATURE_WRITEBARRIER_COPY --- src/coreclr/clrdefinitions.cmake | 4 +- src/coreclr/src/vm/arm64/asmhelpers.S | 122 ++++++++++++++++---------- src/coreclr/src/vm/threads.cpp | 14 ++- 3 files changed, 90 insertions(+), 50 deletions(-) diff --git a/src/coreclr/clrdefinitions.cmake b/src/coreclr/clrdefinitions.cmake index 8f8e8a0f08c0b..b717c10d840a4 100644 --- a/src/coreclr/clrdefinitions.cmake +++ b/src/coreclr/clrdefinitions.cmake @@ -226,9 +226,9 @@ if(CLR_CMAKE_TARGET_WIN32) endif(CLR_CMAKE_TARGET_ARCH_AMD64 OR CLR_CMAKE_TARGET_ARCH_I386) endif(CLR_CMAKE_TARGET_WIN32) -if(CLR_CMAKE_TARGET_OSX AND NOT CLR_CMAKE_TARGET_ARCH_ARM64) +if(CLR_CMAKE_TARGET_OSX) add_definitions(-DFEATURE_WRITEBARRIER_COPY) -endif(CLR_CMAKE_TARGET_OSX AND NOT CLR_CMAKE_TARGET_ARCH_ARM64) +endif(CLR_CMAKE_TARGET_OSX) if (NOT CLR_CMAKE_TARGET_ARCH_I386 OR NOT CLR_CMAKE_TARGET_WIN32) add_definitions(-DFEATURE_EH_FUNCLETS) diff --git a/src/coreclr/src/vm/arm64/asmhelpers.S b/src/coreclr/src/vm/arm64/asmhelpers.S index 07ceab27585c6..1e88eab383595 100644 --- a/src/coreclr/src/vm/arm64/asmhelpers.S +++ b/src/coreclr/src/vm/arm64/asmhelpers.S @@ -206,12 +206,6 @@ LEAF_END ThePreStubPatch, _TEXT LEAF_END_MARKED \name, _TEXT .endm -// ------------------------------------------------------------------ -// Start of the writeable code region -LEAF_ENTRY JIT_PatchedCodeStart, _TEXT - ret lr -LEAF_END JIT_PatchedCodeStart, _TEXT - // void JIT_UpdateWriteBarrierState(bool skipEphemeralCheck) // // Update shadow copies of the various state info required for barrier @@ -268,7 +262,11 @@ LOCAL_LABEL(EphemeralCheckEnabled): ldr x7, [x12] // Update wbs state +#ifdef FEATURE_WRITEBARRIER_COPY + PREPARE_EXTERNAL_VAR JIT_WriteBarrier_Table_Loc, x12 +#else // FEATURE_WRITEBARRIER_COPY adr x12, LOCAL_LABEL(wbs_begin) +#endif // FEATURE_WRITEBARRIER_COPY stp x0, x1, [x12], 16 stp x2, x3, [x12], 16 @@ -277,35 +275,8 @@ LOCAL_LABEL(EphemeralCheckEnabled): EPILOG_RESTORE_REG_PAIR_INDEXED fp, lr, 16 EPILOG_RETURN - - // Begin patchable literal pool - .balign 64 // Align to power of two at least as big as patchable literal pool so that it fits optimally in cache line -LOCAL_LABEL(wbs_begin): -LOCAL_LABEL(wbs_card_table): - .quad 0 -LOCAL_LABEL(wbs_card_bundle_table): - .quad 0 -LOCAL_LABEL(wbs_GCShadow): - .quad 0 -LOCAL_LABEL(wbs_sw_ww_table): - .quad 0 -LOCAL_LABEL(wbs_ephemeral_low): - .quad 0 -LOCAL_LABEL(wbs_ephemeral_high): - .quad 0 -LOCAL_LABEL(wbs_lowest_address): - .quad 0 -LOCAL_LABEL(wbs_highest_address): - .quad 0 WRITE_BARRIER_END JIT_UpdateWriteBarrierState - -// ------------------------------------------------------------------ -// End of the writeable code region -LEAF_ENTRY JIT_PatchedCodeLast, _TEXT - ret lr -LEAF_END JIT_PatchedCodeLast, _TEXT - // void JIT_ByRefWriteBarrier // On entry: // x13 : the source address (points to object reference to write) @@ -350,13 +321,56 @@ WRITE_BARRIER_ENTRY JIT_CheckedWriteBarrier // branch below is not taken. ccmp x14, x12, #0x2, hs +#ifdef FEATURE_WRITEBARRIER_COPY + blo LOCAL_LABEL(Branch_JIT_WriteBarrier_Copy) +#else // FEATURE_WRITEBARRIER_COPY blo C_FUNC(JIT_WriteBarrier) +#endif // FEATURE_WRITEBARRIER_COPY LOCAL_LABEL(NotInHeap): str x15, [x14], 8 ret lr WRITE_BARRIER_END JIT_CheckedWriteBarrier +// ------------------------// ------------------------------------------------------------------ +// __declspec(naked) void F_CALL_CONV JIT_WriteBarrier_Callable(Object **dst, Object* val) +LEAF_ENTRY JIT_WriteBarrier_Callable, _TEXT + + // Setup args for JIT_WriteBarrier. x14 = dst ; x15 = val + mov x14, x0 // x14 = dst + mov x15, x1 // x15 = val + +#ifdef FEATURE_WRITEBARRIER_COPY +LOCAL_LABEL(Branch_JIT_WriteBarrier_Copy): + // Branch to the write barrier + PREPARE_EXTERNAL_VAR JIT_WriteBarrier_Loc, x17 + br x17 +#else // FEATURE_WRITEBARRIER_COPY + // Branch to the write barrier + b C_FUNC(JIT_WriteBarrier) +#endif // FEATURE_WRITEBARRIER_COPY +LEAF_END JIT_WriteBarrier_Callable, _TEXT + +#ifdef FEATURE_WRITEBARRIER_COPY +.data +// When JIT_WriteBarrier is copied into an allocated page, +// helpers use this global variable to jump to it. This variable is set in InitThreadManager. +PATCH_LABEL JIT_WriteBarrier_Loc + .zero 8 + +// When JIT_WriteBarrier is copied into an allocated page, this variable is used to update the +// associated pc relative table. +PATCH_LABEL JIT_WriteBarrier_Table_Loc + .zero 8 +#endif // FEATURE_WRITEBARRIER_COPY + + +//------------------------------------------ +// Start of the writeable code region +LEAF_ENTRY JIT_PatchedCodeStart, _TEXT + ret lr +LEAF_END JIT_PatchedCodeStart, _TEXT + // void JIT_WriteBarrier(Object** dst, Object* src) // On entry: // x14 : the destination address (LHS of the assignment) @@ -473,6 +487,35 @@ LOCAL_LABEL(Exit): ret lr WRITE_BARRIER_END JIT_WriteBarrier + // Begin patchable literal pool + .balign 64 // Align to power of two at least as big as patchable literal pool so that it fits optimally in cache line +WRITE_BARRIER_ENTRY JIT_WriteBarrier_Table +LOCAL_LABEL(wbs_begin): +LOCAL_LABEL(wbs_card_table): + .quad 0 +LOCAL_LABEL(wbs_card_bundle_table): + .quad 0 +LOCAL_LABEL(wbs_GCShadow): + .quad 0 +LOCAL_LABEL(wbs_sw_ww_table): + .quad 0 +LOCAL_LABEL(wbs_ephemeral_low): + .quad 0 +LOCAL_LABEL(wbs_ephemeral_high): + .quad 0 +LOCAL_LABEL(wbs_lowest_address): + .quad 0 +LOCAL_LABEL(wbs_highest_address): + .quad 0 +WRITE_BARRIER_END JIT_WriteBarrier_Table + + +// ------------------------------------------------------------------ +// End of the writeable code region +LEAF_ENTRY JIT_PatchedCodeLast, _TEXT + ret lr +LEAF_END JIT_PatchedCodeLast, _TEXT + #ifdef FEATURE_PREJIT //------------------------------------------------ // VirtualMethodFixupStub @@ -1176,19 +1219,6 @@ LEAF_ENTRY JIT_GetSharedGCStaticBaseNoCtor_SingleAppDomain, _TEXT LEAF_END JIT_GetSharedGCStaticBaseNoCtor_SingleAppDomain, _TEXT -// ------------------------------------------------------------------ -// __declspec(naked) void F_CALL_CONV JIT_WriteBarrier_Callable(Object **dst, Object* val) -LEAF_ENTRY JIT_WriteBarrier_Callable, _TEXT - - // Setup args for JIT_WriteBarrier. x14 = dst ; x15 = val - mov x14, x0 // x14 = dst - mov x15, x1 // x15 = val - - // Branch to the write barrier (which is already correctly overwritten with - // single or multi-proc code based on the current CPU - b C_FUNC(JIT_WriteBarrier) -LEAF_END JIT_WriteBarrier_Callable, _TEXT - #ifdef PROFILING_SUPPORTED // ------------------------------------------------------------------ diff --git a/src/coreclr/src/vm/threads.cpp b/src/coreclr/src/vm/threads.cpp index 9dae20e9d487a..c53c94739c3a1 100644 --- a/src/coreclr/src/vm/threads.cpp +++ b/src/coreclr/src/vm/threads.cpp @@ -1121,9 +1121,13 @@ PCODE AdjustWriteBarrierIP(PCODE controlPc) return (PCODE)JIT_PatchedCodeStart + (controlPc - (PCODE)s_barrierCopy); } -#endif // FEATURE_WRITEBARRIER_COPY - extern "C" void *JIT_WriteBarrier_Loc; +#ifdef TARGET_ARM64 +extern "C" void* JIT_WriteBarrier_Table; +extern "C" void *JIT_WriteBarrier_Table_Loc; +#endif // TARGET_ARM64 + +#endif // FEATURE_WRITEBARRIER_COPY #ifndef TARGET_UNIX // g_TlsIndex is only used by the DAC. Disable optimizations around it to prevent it from getting optimized out. @@ -1168,6 +1172,12 @@ void InitThreadManager() JIT_WriteBarrier_Loc = GetWriteBarrierCodeLocation((void*)JIT_WriteBarrier); SetJitHelperFunction(CORINFO_HELP_ASSIGN_REF, GetWriteBarrierCodeLocation((void*)JIT_WriteBarrier)); + +#ifdef TARGET_ARM64 + // Store the JIT_WriteBarrier_Table copy location to a global variable so that it can be updated. + JIT_WriteBarrier_Table_Loc = GetWriteBarrierCodeLocation((void*)JIT_WriteBarrier_Table); +#endif // TARGET_ARM64 + #else // FEATURE_WRITEBARRIER_COPY // I am using virtual protect to cover the entire range that this code falls in. From 0a827d5fe27a6a95a2193d862b234c3d3dfb6fdc Mon Sep 17 00:00:00 2001 From: Steve MacLean Date: Fri, 14 Aug 2020 16:41:14 -0700 Subject: [PATCH 19/89] Add crude os-arm64 generate layout script --- src/coreclr/generate-osx-arm64-layout.sh | 66 ++++++++++++++++++++++++ 1 file changed, 66 insertions(+) create mode 100755 src/coreclr/generate-osx-arm64-layout.sh diff --git a/src/coreclr/generate-osx-arm64-layout.sh b/src/coreclr/generate-osx-arm64-layout.sh new file mode 100755 index 0000000000000..ad513656e0ac4 --- /dev/null +++ b/src/coreclr/generate-osx-arm64-layout.sh @@ -0,0 +1,66 @@ +#! /bin/bash + +# This is a simple and currently crude script to gernetate an osx-arm64 Core_Root +# It takes a reference osx-x64 Core_Root and replaces the native bits and +# System.Private.CoreLib.dll from thode built lovally. +# It then removes any remaining x64 native binaries + +# ToDo +# Error checking!!! +# Options ... build config!!! + +source="${BASH_SOURCE[0]}" + +# resolve $SOURCE until the file is no longer a symlink +while [[ -h $source ]]; do + scriptroot="$( cd -P "$( dirname "$source" )" && pwd )" + source="$(readlink "$source")" + + # if $source was a relative symlink, we need to resolve it relative to the path where the + # symlink file was located + [[ $source != /* ]] && source="$scriptroot/$source" +done + +RepoRoot="$( cd -P "$( dirname "$source" )/../.." && pwd )" + +Reference_Core_Root=${RepoRoot}/artifacts/tests/coreclr/OSX.x64.Debug/Tests/Core_Root +Core_Root=${RepoRoot}/artifacts/tests/coreclr/OSX.arm64.Debug/Tests/Core_Root +Arm64_Native_Paths="${RepoRoot}/artifacts/bin/coreclr/OSX.arm64.Debug ${RepoRoot}/artifacts/bin/native/net5.0-OSX-Debug-arm64" +Arm64_SPC_Path=${RepoRoot}/artifacts/bin/coreclr/OSX.arm64.Release/IL + +function x64NativeFiles() +{ + for i in $(find ${Core_Root} -type f) + do + (file $i | grep -q x86_64) && echo $i + done +} + +# Remove any existing Core Root +rm -rf ${Core_Root} + +# Create empty directory path +mkdir -p ${Core_Root} + +# Copy reference Core Root +cp -r ${Reference_Core_Root}/* ${Core_Root} + +# Copy crossgened arm64 S.P.C.dll +cp ${Arm64_SPC_Path}/System.Private.CoreLib.dll ${Core_Root} + +# Replace osx-x64 native files with their arm64 counterparts +for i in $(x64NativeFiles) +do + echo + echo $i + find ${Arm64_Native_Paths} -name $(basename $i) -exec md5 "{}" ';' -exec cp "{}" $i ';' +done 2>&1 + +echo + +# Remove any residual osx-x64 native files +for i in $(x64NativeFiles) +do + echo Removing native x86_64 file $i + rm $i +done 2>&1 From 7d202fae736316dbe9e74893990b23a181fafb1b Mon Sep 17 00:00:00 2001 From: Steve MacLean Date: Fri, 14 Aug 2020 16:44:23 -0700 Subject: [PATCH 20/89] First Write^Execute patch The memcpy below will fail on macos arm64 if the allocated page has write and execute permissions. It results in a bad access. This is an incomplete solution as the barrier code can not yet be executed. --- src/coreclr/src/vm/threads.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/coreclr/src/vm/threads.cpp b/src/coreclr/src/vm/threads.cpp index c53c94739c3a1..2e4f10434f050 100644 --- a/src/coreclr/src/vm/threads.cpp +++ b/src/coreclr/src/vm/threads.cpp @@ -1158,7 +1158,11 @@ void InitThreadManager() _ASSERTE_ALL_BUILDS("clr/src/VM/threads.cpp", (BYTE*)JIT_PatchedCodeLast - (BYTE*)JIT_PatchedCodeStart < (ptrdiff_t)GetOsPageSize()); #ifdef FEATURE_WRITEBARRIER_COPY +#ifdef TARGET_ARM64 + s_barrierCopy = ClrVirtualAlloc(NULL, g_SystemInfo.dwAllocationGranularity, MEM_COMMIT, PAGE_READWRITE); +#else s_barrierCopy = ClrVirtualAlloc(NULL, g_SystemInfo.dwAllocationGranularity, MEM_COMMIT, PAGE_EXECUTE_READWRITE); +#endif // TARGET_ARM64 if (s_barrierCopy == NULL) { _ASSERTE(!"ClrVirtualAlloc of GC barrier code page failed"); From 69d14eda28ef4c02578bb491613053b7af39e1e2 Mon Sep 17 00:00:00 2001 From: Steve MacLean Date: Sat, 15 Aug 2020 10:16:02 -0700 Subject: [PATCH 21/89] Fix comment typos --- src/coreclr/generate-osx-arm64-layout.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/coreclr/generate-osx-arm64-layout.sh b/src/coreclr/generate-osx-arm64-layout.sh index ad513656e0ac4..10ca13bdb0e99 100755 --- a/src/coreclr/generate-osx-arm64-layout.sh +++ b/src/coreclr/generate-osx-arm64-layout.sh @@ -1,8 +1,8 @@ #! /bin/bash -# This is a simple and currently crude script to gernetate an osx-arm64 Core_Root +# This is a simple and currently crude script to generate an osx-arm64 Core_Root # It takes a reference osx-x64 Core_Root and replaces the native bits and -# System.Private.CoreLib.dll from thode built lovally. +# System.Private.CoreLib.dll from those built locally. # It then removes any remaining x64 native binaries # ToDo From 8f678c033cf1d7b69e43fcb5976681c63da05404 Mon Sep 17 00:00:00 2001 From: Steve MacLean Date: Mon, 17 Aug 2020 14:40:37 -0700 Subject: [PATCH 22/89] Fix IsRunningOnMojaveHardenedRuntime() --- src/coreclr/src/pal/src/misc/utils.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/coreclr/src/pal/src/misc/utils.cpp b/src/coreclr/src/pal/src/misc/utils.cpp index de604fe96dc47..f279ef3d580c1 100644 --- a/src/coreclr/src/pal/src/misc/utils.cpp +++ b/src/coreclr/src/pal/src/misc/utils.cpp @@ -332,6 +332,9 @@ void UTIL_SetLastErrorFromMach(kern_return_t MachReturn) --*/ BOOL IsRunningOnMojaveHardenedRuntime() { +#if defined(TARGET_ARM64) + return true; +#else // defined(TARGET_ARM64) static volatile int isRunningOnMojaveHardenedRuntime = -1; if (isRunningOnMojaveHardenedRuntime == -1) @@ -359,6 +362,7 @@ BOOL IsRunningOnMojaveHardenedRuntime() } return (BOOL)isRunningOnMojaveHardenedRuntime; +#endif // defined(TARGET_ARM64) } #endif // __APPLE__ From d8935a7fd9035c72f970f2545f410cfa39aa0d95 Mon Sep 17 00:00:00 2001 From: Steve MacLean Date: Mon, 17 Aug 2020 14:42:12 -0700 Subject: [PATCH 23/89] Add comment --- Directory.Build.props | 1 + 1 file changed, 1 insertion(+) diff --git a/Directory.Build.props b/Directory.Build.props index 82e6284aace3c..11d675443fa15 100644 --- a/Directory.Build.props +++ b/Directory.Build.props @@ -101,6 +101,7 @@ Properties $([System.Runtime.InteropServices.RuntimeInformation]::ProcessArchitecture.ToString().ToLowerInvariant()) + $(BuildArchitecture) From 061ecc4245f0b1b80068ffbc1f726291cdd236c8 Mon Sep 17 00:00:00 2001 From: Steve MacLean Date: Mon, 17 Aug 2020 14:50:57 -0700 Subject: [PATCH 24/89] Set CMAKE_OSX_ARCHITECTURES in configureplatform.cmake --- eng/native/configureplatform.cmake | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/eng/native/configureplatform.cmake b/eng/native/configureplatform.cmake index 9b0f1e5212265..c5765e5d82a24 100644 --- a/eng/native/configureplatform.cmake +++ b/eng/native/configureplatform.cmake @@ -81,11 +81,19 @@ if(CLR_CMAKE_HOST_OS STREQUAL Darwin) if(CMAKE_SYSTEM_PROCESSOR STREQUAL x86_64) if(NOT CLR_CROSS_COMPONENTS_BUILD AND CLR_CMAKE_TARGET_ARCH STREQUAL arm64) set(CLR_CMAKE_HOST_UNIX_ARM64 1) - else(CLR_CMAKE_TARGET_ARCH STREQUAL arm64) + set(CMAKE_OSX_ARCHITECTURES arm64) + else() set(CLR_CMAKE_HOST_UNIX_AMD64 1) - endif(CLR_CMAKE_TARGET_ARCH STREQUAL arm64) + set(CMAKE_OSX_ARCHITECTURES x86_64) + endif() elseif(CMAKE_SYSTEM_PROCESSOR STREQUAL arm64) - set(CLR_CMAKE_HOST_UNIX_ARM64 1) + if(NOT CLR_CROSS_COMPONENTS_BUILD AND CLR_CMAKE_TARGET_ARCH STREQUAL x64) + set(CLR_CMAKE_HOST_UNIX_AMD64 1) + set(CMAKE_OSX_ARCHITECTURES x86_64) + else() + set(CLR_CMAKE_HOST_UNIX_ARM64 1) + set(CMAKE_OSX_ARCHITECTURES arm64) + endif() else() clr_unknown_arch() endif() From 3c1a8307ca3f1472f100a18ade0932f2fe148f8e Mon Sep 17 00:00:00 2001 From: Steve MacLean Date: Thu, 20 Aug 2020 12:58:55 -0700 Subject: [PATCH 25/89] Fix threadSP initialization order --- .../src/pal/src/exception/machexception.cpp | 24 +++++++++---------- 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/src/coreclr/src/pal/src/exception/machexception.cpp b/src/coreclr/src/pal/src/exception/machexception.cpp index 9b4e482c96990..f0334922416cc 100644 --- a/src/coreclr/src/pal/src/exception/machexception.cpp +++ b/src/coreclr/src/pal/src/exception/machexception.cpp @@ -656,21 +656,21 @@ HijackFaultingThread( BuildExceptionRecord(exceptionInfo, &exceptionRecord); #if defined(HOST_AMD64) - void **targetSP = (void **)threadContext.Rsp; - threadContext.ContextFlags = CONTEXT_FLOATING_POINT; CONTEXT_GetThreadContextFromThreadState(x86_FLOAT_STATE, (thread_state_t)&exceptionInfo.FloatState, &threadContext); threadContext.ContextFlags |= CONTEXT_CONTROL | CONTEXT_INTEGER | CONTEXT_SEGMENTS; CONTEXT_GetThreadContextFromThreadState(x86_THREAD_STATE, (thread_state_t)&exceptionInfo.ThreadState, &threadContext); -#elif defined(HOST_ARM64) - void **targetSP = (void **)threadContext.Sp; + void **targetSP = (void **)threadContext.Rsp; +#elif defined(HOST_ARM64) threadContext.ContextFlags = CONTEXT_FLOATING_POINT; CONTEXT_GetThreadContextFromThreadState(ARM_NEON_STATE64, (thread_state_t)&exceptionInfo.FloatState, &threadContext); threadContext.ContextFlags |= CONTEXT_CONTROL | CONTEXT_INTEGER; CONTEXT_GetThreadContextFromThreadState(ARM_THREAD_STATE64, (thread_state_t)&exceptionInfo.ThreadState, &threadContext); + + void **targetSP = (void **)threadContext.Sp; #else #error Unexpected architecture #endif @@ -814,7 +814,7 @@ HijackFaultingThread( // the state if the exception is forwarded. arm_thread_state64_t ts64 = exceptionInfo.ThreadState; - exceptionRecord.ExceptionAddress = (void *)arm_thread_state64_get_pc(ts64); + exceptionRecord.ExceptionAddress = (void *)arm_thread_state64_get_pc_fptr(ts64); void **FramePointer = (void **)arm_thread_state64_get_sp(ts64); #else @@ -851,7 +851,7 @@ HijackFaultingThread( ts64.__rbp = (SIZE_T)FramePointer; #elif defined(HOST_ARM64) - *--FramePointer = (void *)arm_thread_state64_get_pc(ts64); + *--FramePointer = (void *)arm_thread_state64_get_pc_fptr(ts64); *--FramePointer = (void *)arm_thread_state64_get_fp(ts64); arm_thread_state64_set_fp(ts64, FramePointer); @@ -1077,11 +1077,11 @@ SEHExceptionThread(void *args) machret = thread_get_state(thread, ARM_THREAD_STATE64, (thread_state_t)&threadStateActual, &count); CHECK_MACH("thread_get_state", machret); - NONPAL_TRACE("ExceptionNotification actual lr %016llx sp %016llx fp %016llx pc %016llx cpsr %08x\n", - arm_thread_state64_get_lr(threadStateActual), + NONPAL_TRACE("ExceptionNotification actual lr %p sp %016llx fp %016llx pc %p cpsr %08x\n", + arm_thread_state64_get_lr_fptr(threadStateActual), arm_thread_state64_get_sp(threadStateActual), arm_thread_state64_get_fp(threadStateActual), - arm_thread_state64_get_pc(threadStateActual), + arm_thread_state64_get_pc_fptr(threadStateActual), threadStateActual.__cpsr); arm_exception_state64_t threadExceptionState; @@ -1511,13 +1511,13 @@ InjectActivationInternal(CPalThread* pThread) *(--sp) = ThreadState.__rbp; size_t rbpAddress = (size_t)sp; #elif defined(HOST_ARM64) - if ((g_safeActivationCheckFunction != NULL) && g_safeActivationCheckFunction(arm_thread_state64_get_pc(ThreadState), /* checkingCurrentThread */ FALSE)) + 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) = arm_thread_state64_get_pc(ThreadState); - *(--sp) = arm_thread_state64_get_lr(ThreadState); + *(--sp) = (size_t)arm_thread_state64_get_pc_fptr(ThreadState); + *(--sp) = arm_thread_state64_get_fp(ThreadState); size_t rfpAddress = (size_t)sp; #else #error Unexpected architecture From cdd5da3fd3397d0b01dca1c248185e567d84ce15 Mon Sep 17 00:00:00 2001 From: Steve MacLean Date: Thu, 20 Aug 2020 13:02:11 -0700 Subject: [PATCH 26/89] Add PAL_JITWriteEnable() --- eng/native/configurecompiler.cmake | 7 ++++- src/coreclr/src/inc/loaderheap.h | 6 ++++ src/coreclr/src/pal/inc/pal.h | 5 ++++ src/coreclr/src/pal/src/map/virtual.cpp | 25 +++++++++++++++++ src/coreclr/src/utilcode/loaderheap.cpp | 7 +++++ src/coreclr/src/vm/arm64/stubs.cpp | 28 +++++++++++++++---- src/coreclr/src/vm/callcounting.cpp | 4 +++ src/coreclr/src/vm/callhelpers.cpp | 4 +++ src/coreclr/src/vm/ceemain.cpp | 2 ++ src/coreclr/src/vm/codeman.cpp | 3 ++ src/coreclr/src/vm/dllimportcallback.h | 3 ++ .../src/vm/methoddescbackpatchinfo.cpp | 3 ++ src/coreclr/src/vm/precode.cpp | 8 ++++++ src/coreclr/src/vm/prestub.cpp | 8 ++++++ src/coreclr/src/vm/threads.cpp | 8 +++--- src/coreclr/src/vm/virtualcallstub.cpp | 8 ++++++ 16 files changed, 118 insertions(+), 11 deletions(-) diff --git a/eng/native/configurecompiler.cmake b/eng/native/configurecompiler.cmake index 02611fa19272e..cf94b5f5d2a50 100644 --- a/eng/native/configurecompiler.cmake +++ b/eng/native/configurecompiler.cmake @@ -367,7 +367,12 @@ if (CLR_CMAKE_HOST_UNIX) # Specify the minimum supported version of macOS if(CLR_CMAKE_HOST_OSX) - set(MACOS_VERSION_MIN_FLAGS -mmacosx-version-min=10.12) + if(CLR_CMAKE_HOST_ARCH_ARM64) + # 'pthread_jit_write_protect_np' is only available on macOS 11.0 or newer + set(MACOS_VERSION_MIN_FLAGS -mmacosx-version-min=11.0) + else() + set(MACOS_VERSION_MIN_FLAGS -mmacosx-version-min=10.12) + endif() add_compile_options(${MACOS_VERSION_MIN_FLAGS}) add_linker_flag(${MACOS_VERSION_MIN_FLAGS}) endif(CLR_CMAKE_HOST_OSX) diff --git a/src/coreclr/src/inc/loaderheap.h b/src/coreclr/src/inc/loaderheap.h index 8008a3a829b8b..aecb316ae658c 100644 --- a/src/coreclr/src/inc/loaderheap.h +++ b/src/coreclr/src/inc/loaderheap.h @@ -549,6 +549,7 @@ class LoaderHeap : public UnlockedLoaderHeap, public ILoaderHeapBackout { WRAPPER_NO_CONTRACT; + bool jitWriteEnabled = PAL_JITWriteEnable(true); void *pResult; TaggedMemAllocPtr tmap; @@ -568,6 +569,8 @@ class LoaderHeap : public UnlockedLoaderHeap, public ILoaderHeapBackout tmap.m_szFile = szFile; tmap.m_lineNum = lineNum; #endif + PAL_JITWriteEnable(jitWriteEnabled); + return tmap; } @@ -625,6 +628,8 @@ class LoaderHeap : public UnlockedLoaderHeap, public ILoaderHeapBackout { WRAPPER_NO_CONTRACT; + bool jitWriteEnabled = PAL_JITWriteEnable(true); + CRITSEC_Holder csh(m_CriticalSection); @@ -649,6 +654,7 @@ class LoaderHeap : public UnlockedLoaderHeap, public ILoaderHeapBackout tmap.m_szFile = szFile; tmap.m_lineNum = lineNum; #endif + PAL_JITWriteEnable(jitWriteEnabled); return tmap; } diff --git a/src/coreclr/src/pal/inc/pal.h b/src/coreclr/src/pal/inc/pal.h index fd56fc90c3535..560ab4968cc28 100644 --- a/src/coreclr/src/pal/inc/pal.h +++ b/src/coreclr/src/pal/inc/pal.h @@ -2714,6 +2714,11 @@ VirtualFree( IN SIZE_T dwSize, IN DWORD dwFreeType); +PALIMPORT +bool +PALAPI +PAL_JITWriteEnable(IN bool enable); + PALIMPORT BOOL PALAPI diff --git a/src/coreclr/src/pal/src/map/virtual.cpp b/src/coreclr/src/pal/src/map/virtual.cpp index edac877580216..2815489e25f49 100644 --- a/src/coreclr/src/pal/src/map/virtual.cpp +++ b/src/coreclr/src/pal/src/map/virtual.cpp @@ -1760,6 +1760,31 @@ VirtualProtect( return bRetVal; } +#if defined(TARGET_OSX) && defined(TARGET_ARM64) +bool +PALAPI +PAL_JITWriteEnable(bool writeEnable) +{ + // Use a thread local to track per thread JIT Write enable state + // Threads start with MAP_JIT pages readable and executable (R-X) by default. + thread_local bool enabled = false; + bool result = enabled; + if (enabled != writeEnable) + { + pthread_jit_write_protect_np(writeEnable ? 0 : 1); + enabled = writeEnable; + } + return result; +} +#else +bool +PALAPI +PAL_JITWriteEnable(bool) +{ + return true; +} +#endif + #if HAVE_VM_ALLOCATE //--------------------------------------------------------------------------------------- // diff --git a/src/coreclr/src/utilcode/loaderheap.cpp b/src/coreclr/src/utilcode/loaderheap.cpp index 37d1e2f4ce569..8d07ed8a10e5e 100644 --- a/src/coreclr/src/utilcode/loaderheap.cpp +++ b/src/coreclr/src/utilcode/loaderheap.cpp @@ -1159,6 +1159,10 @@ BOOL UnlockedLoaderHeap::UnlockedReservePages(size_t dwSizeToCommit) LoaderHeapBlock *pNewBlock; + bool jitWriteEnable = false; + if (m_Options & LHF_EXECUTABLE) + jitWriteEnable = PAL_JITWriteEnable(true); + pNewBlock = (LoaderHeapBlock *) pData; pNewBlock->dwVirtualSize = dwSizeToReserve; @@ -1183,6 +1187,9 @@ BOOL UnlockedLoaderHeap::UnlockedReservePages(size_t dwSizeToCommit) SETUP_NEW_BLOCK(pData, dwSizeToCommit, dwSizeToReserve); + if (m_Options & LHF_EXECUTABLE) + PAL_JITWriteEnable(jitWriteEnable); + return TRUE; } diff --git a/src/coreclr/src/vm/arm64/stubs.cpp b/src/coreclr/src/vm/arm64/stubs.cpp index ac8466c22faca..e9b79a3765219 100644 --- a/src/coreclr/src/vm/arm64/stubs.cpp +++ b/src/coreclr/src/vm/arm64/stubs.cpp @@ -637,6 +637,8 @@ void FixupPrecode::Init(MethodDesc* pMD, LoaderAllocator *pLoaderAllocator, int { WRAPPER_NO_CONTRACT; + bool jitWriteEnabled = PAL_JITWriteEnable(true); + InitCommon(); // Initialize chunk indices only if they are not initialized yet. This is necessary to make MethodDesc::Reset work. @@ -664,6 +666,8 @@ void FixupPrecode::Init(MethodDesc* pMD, LoaderAllocator *pLoaderAllocator, int { m_pTarget = GetEEFuncEntryPoint(PrecodeFixupThunk); } + + PAL_JITWriteEnable(jitWriteEnabled); } #ifdef FEATURE_NATIVE_IMAGE_GENERATION @@ -1058,6 +1062,17 @@ void JIT_TailCall() } #if !defined(DACCESS_COMPILE) && !defined(CROSSGEN_COMPILE) +EXTERN_C void JIT_UpdateWriteBarrierState(bool skipEphemeralCheck); + +static void SafeUpdateWriteBarrierState(bool skipEphemeralCheck) +{ + bool jitWriteEnabled = PAL_JITWriteEnable(true); + + JIT_UpdateWriteBarrierState(GCHeapUtilities::IsServerHeap()); + + PAL_JITWriteEnable(jitWriteEnabled); +} + void InitJITHelpers1() { STANDARD_VM_CONTRACT; @@ -1083,11 +1098,12 @@ void InitJITHelpers1() } } - JIT_UpdateWriteBarrierState(GCHeapUtilities::IsServerHeap()); + SafeUpdateWriteBarrierState(GCHeapUtilities::IsServerHeap()); } + #else -EXTERN_C void JIT_UpdateWriteBarrierState(bool) {} +void SafeUpdateWriteBarrierState(bool) {} #endif // !defined(DACCESS_COMPILE) && !defined(CROSSGEN_COMPILE) PTR_CONTEXT GetCONTEXTFromRedirectedStubStackFrame(T_DISPATCHER_CONTEXT * pDispatcherContext) @@ -1251,26 +1267,26 @@ void FlushWriteBarrierInstructionCache() #ifndef CROSSGEN_COMPILE int StompWriteBarrierEphemeral(bool isRuntimeSuspended) { - JIT_UpdateWriteBarrierState(GCHeapUtilities::IsServerHeap()); + SafeUpdateWriteBarrierState(GCHeapUtilities::IsServerHeap()); return SWB_PASS; } int StompWriteBarrierResize(bool isRuntimeSuspended, bool bReqUpperBoundsCheck) { - JIT_UpdateWriteBarrierState(GCHeapUtilities::IsServerHeap()); + SafeUpdateWriteBarrierState(GCHeapUtilities::IsServerHeap()); return SWB_PASS; } #ifdef FEATURE_USE_SOFTWARE_WRITE_WATCH_FOR_GC_HEAP int SwitchToWriteWatchBarrier(bool isRuntimeSuspended) { - JIT_UpdateWriteBarrierState(GCHeapUtilities::IsServerHeap()); + SafeUpdateWriteBarrierState(GCHeapUtilities::IsServerHeap()); return SWB_PASS; } int SwitchToNonWriteWatchBarrier(bool isRuntimeSuspended) { - JIT_UpdateWriteBarrierState(GCHeapUtilities::IsServerHeap()); + SafeUpdateWriteBarrierState(GCHeapUtilities::IsServerHeap()); return SWB_PASS; } #endif // FEATURE_USE_SOFTWARE_WRITE_WATCH_FOR_GC_HEAP diff --git a/src/coreclr/src/vm/callcounting.cpp b/src/coreclr/src/vm/callcounting.cpp index 8c3678bfd8536..cde52f3916a92 100644 --- a/src/coreclr/src/vm/callcounting.cpp +++ b/src/coreclr/src/vm/callcounting.cpp @@ -251,6 +251,8 @@ const CallCountingStub *CallCountingManager::CallCountingStubAllocator::Allocate } CONTRACTL_END; + bool jitWriteEnabled = PAL_JITWriteEnable(true); + LoaderHeap *heap = m_heap; if (heap == nullptr) { @@ -292,6 +294,8 @@ const CallCountingStub *CallCountingManager::CallCountingStubAllocator::Allocate #endif } while (false); + PAL_JITWriteEnable(jitWriteEnabled); + ClrFlushInstructionCache(stub, sizeInBytes); return stub; } diff --git a/src/coreclr/src/vm/callhelpers.cpp b/src/coreclr/src/vm/callhelpers.cpp index 910cc060f74ae..1695811c18278 100644 --- a/src/coreclr/src/vm/callhelpers.cpp +++ b/src/coreclr/src/vm/callhelpers.cpp @@ -62,12 +62,16 @@ void CallDescrWorkerWithHandler( #endif + bool jitWriteEnabled = PAL_JITWriteEnable(false); + BEGIN_CALL_TO_MANAGEDEX(fCriticalCall ? EEToManagedCriticalCall : EEToManagedDefault); CallDescrWorker(pCallDescrData); END_CALL_TO_MANAGED(); + + PAL_JITWriteEnable(jitWriteEnabled); } diff --git a/src/coreclr/src/vm/ceemain.cpp b/src/coreclr/src/vm/ceemain.cpp index 962ba0d2298ac..0ceb684ce52a8 100644 --- a/src/coreclr/src/vm/ceemain.cpp +++ b/src/coreclr/src/vm/ceemain.cpp @@ -969,6 +969,8 @@ void EEStartupHelper() #endif // CROSSGEN_COMPILE + PAL_JITWriteEnable(true); + SystemDomain::System()->Init(); #ifdef PROFILING_SUPPORTED diff --git a/src/coreclr/src/vm/codeman.cpp b/src/coreclr/src/vm/codeman.cpp index 3f48cb00db59b..00b04635fceeb 100644 --- a/src/coreclr/src/vm/codeman.cpp +++ b/src/coreclr/src/vm/codeman.cpp @@ -1829,6 +1829,8 @@ TaggedMemAllocPtr CodeFragmentHeap::RealAllocAlignedMem(size_t dwRequestedSize { CrstHolder ch(&m_CritSec); + bool jitWriteEnabled = PAL_JITWriteEnable(true); + dwRequestedSize = ALIGN_UP(dwRequestedSize, sizeof(TADDR)); if (dwRequestedSize < sizeof(FreeBlock)) @@ -1893,6 +1895,7 @@ TaggedMemAllocPtr CodeFragmentHeap::RealAllocAlignedMem(size_t dwRequestedSize tmap.m_szFile = szFile; tmap.m_lineNum = lineNum; #endif + PAL_JITWriteEnable(jitWriteEnabled); return tmap; } diff --git a/src/coreclr/src/vm/dllimportcallback.h b/src/coreclr/src/vm/dllimportcallback.h index b98f0743213f0..9befa328bff95 100644 --- a/src/coreclr/src/vm/dllimportcallback.h +++ b/src/coreclr/src/vm/dllimportcallback.h @@ -267,6 +267,8 @@ class UMEntryThunk } CONTRACTL_END; + bool jitWriteEnabled = PAL_JITWriteEnable(true); + m_pManagedTarget = pManagedTarget; m_pObjectHandle = pObjectHandle; m_pUMThunkMarshInfo = pUMThunkMarshInfo; @@ -278,6 +280,7 @@ class UMEntryThunk #ifdef _DEBUG m_state = kLoadTimeInited; #endif + PAL_JITWriteEnable(jitWriteEnabled); } void Terminate(); diff --git a/src/coreclr/src/vm/methoddescbackpatchinfo.cpp b/src/coreclr/src/vm/methoddescbackpatchinfo.cpp index efe1d04cf6f82..79620ecc00d4f 100644 --- a/src/coreclr/src/vm/methoddescbackpatchinfo.cpp +++ b/src/coreclr/src/vm/methoddescbackpatchinfo.cpp @@ -28,6 +28,8 @@ void EntryPointSlots::Backpatch_Locked(TADDR slot, SlotType slotType, PCODE entr _ASSERTE(entryPoint != NULL); _ASSERTE(IS_ALIGNED((SIZE_T)slot, GetRequiredSlotAlignment(slotType))); + bool jitWriteEnabled = PAL_JITWriteEnable(true); + switch (slotType) { case SlotType_Normal: @@ -50,6 +52,7 @@ void EntryPointSlots::Backpatch_Locked(TADDR slot, SlotType slotType, PCODE entr // fall through Flush: + PAL_JITWriteEnable(jitWriteEnabled); ClrFlushInstructionCache((LPCVOID)slot, sizeof(PCODE)); break; diff --git a/src/coreclr/src/vm/precode.cpp b/src/coreclr/src/vm/precode.cpp index 0228d860c5358..da4f2c5a2e7b3 100644 --- a/src/coreclr/src/vm/precode.cpp +++ b/src/coreclr/src/vm/precode.cpp @@ -404,6 +404,8 @@ void Precode::ResetTargetInterlocked() { WRAPPER_NO_CONTRACT; + bool jitWriteEnabled = PAL_JITWriteEnable(true); + PrecodeType precodeType = GetType(); switch (precodeType) { @@ -422,6 +424,8 @@ void Precode::ResetTargetInterlocked() break; } + PAL_JITWriteEnable(jitWriteEnabled); + // Although executable code is modified on x86/x64, a FlushInstructionCache() is not necessary on those platforms due to the // interlocked operation above (see ClrFlushInstructionCache()) } @@ -437,6 +441,8 @@ BOOL Precode::SetTargetInterlocked(PCODE target, BOOL fOnlyRedirectFromPrestub) if (fOnlyRedirectFromPrestub && !IsPointingToPrestub(expected)) return FALSE; + bool jitWriteEnabled = PAL_JITWriteEnable(true); + g_IBCLogger.LogMethodPrecodeWriteAccess(GetMethodDesc()); PrecodeType precodeType = GetType(); @@ -463,6 +469,8 @@ BOOL Precode::SetTargetInterlocked(PCODE target, BOOL fOnlyRedirectFromPrestub) break; } + PAL_JITWriteEnable(jitWriteEnabled); + // Although executable code is modified on x86/x64, a FlushInstructionCache() is not necessary on those platforms due to the // interlocked operation above (see ClrFlushInstructionCache()) diff --git a/src/coreclr/src/vm/prestub.cpp b/src/coreclr/src/vm/prestub.cpp index d44c3cc062f85..89cf97f6a3bc6 100644 --- a/src/coreclr/src/vm/prestub.cpp +++ b/src/coreclr/src/vm/prestub.cpp @@ -326,6 +326,8 @@ PCODE MethodDesc::PrepareCode(PrepareCodeConfig* pConfig) { STANDARD_VM_CONTRACT; + bool jitWriteEnabled = PAL_JITWriteEnable(true); + // If other kinds of code need multi-versioning we could add more cases here, // but for now generation of all other code/stubs occurs in other code paths _ASSERTE(IsIL() || IsNoMetadata()); @@ -335,6 +337,8 @@ PCODE MethodDesc::PrepareCode(PrepareCodeConfig* pConfig) NotifyGdb::MethodPrepared(this); #endif + PAL_JITWriteEnable(jitWriteEnabled); + return pCode; } @@ -1880,6 +1884,8 @@ extern "C" PCODE STDCALL PreStubWorker(TransitionBlock* pTransitionBlock, Method ETWOnStartup(PrestubWorker_V1, PrestubWorkerEnd_V1); + bool jitWriteEnabled = PAL_JITWriteEnable(true); + MAKE_CURRENT_THREAD_AVAILABLE(); // Attempt to check what GC mode we are running under. @@ -1964,6 +1970,8 @@ extern "C" PCODE STDCALL PreStubWorker(TransitionBlock* pTransitionBlock, Method pPFrame->Pop(CURRENT_THREAD); } + PAL_JITWriteEnable(jitWriteEnabled); + POSTCONDITION(pbRetVal != NULL); END_PRESERVE_LAST_ERROR; diff --git a/src/coreclr/src/vm/threads.cpp b/src/coreclr/src/vm/threads.cpp index 2e4f10434f050..1dcc5a92152b7 100644 --- a/src/coreclr/src/vm/threads.cpp +++ b/src/coreclr/src/vm/threads.cpp @@ -1158,17 +1158,15 @@ void InitThreadManager() _ASSERTE_ALL_BUILDS("clr/src/VM/threads.cpp", (BYTE*)JIT_PatchedCodeLast - (BYTE*)JIT_PatchedCodeStart < (ptrdiff_t)GetOsPageSize()); #ifdef FEATURE_WRITEBARRIER_COPY -#ifdef TARGET_ARM64 - s_barrierCopy = ClrVirtualAlloc(NULL, g_SystemInfo.dwAllocationGranularity, MEM_COMMIT, PAGE_READWRITE); -#else s_barrierCopy = ClrVirtualAlloc(NULL, g_SystemInfo.dwAllocationGranularity, MEM_COMMIT, PAGE_EXECUTE_READWRITE); -#endif // TARGET_ARM64 if (s_barrierCopy == NULL) { _ASSERTE(!"ClrVirtualAlloc of GC barrier code page failed"); COMPlusThrowWin32(); } + bool jitWriteEnabled = PAL_JITWriteEnable(true); + memcpy(s_barrierCopy, (BYTE*)JIT_PatchedCodeStart, (BYTE*)JIT_PatchedCodeLast - (BYTE*)JIT_PatchedCodeStart); // Store the JIT_WriteBarrier copy location to a global variable so that helpers @@ -1182,6 +1180,8 @@ void InitThreadManager() JIT_WriteBarrier_Table_Loc = GetWriteBarrierCodeLocation((void*)JIT_WriteBarrier_Table); #endif // TARGET_ARM64 + PAL_JITWriteEnable(jitWriteEnabled); + #else // FEATURE_WRITEBARRIER_COPY // I am using virtual protect to cover the entire range that this code falls in. diff --git a/src/coreclr/src/vm/virtualcallstub.cpp b/src/coreclr/src/vm/virtualcallstub.cpp index 1f05aef258880..b6ed62177cb86 100644 --- a/src/coreclr/src/vm/virtualcallstub.cpp +++ b/src/coreclr/src/vm/virtualcallstub.cpp @@ -1708,6 +1708,8 @@ PCODE VirtualCallStubManager::ResolveWorker(StubCallSite* pCallSite, PRECONDITION(IsProtectedByGCFrame(protectedObj)); } CONTRACTL_END; + bool jitWriteEnabled = PAL_JITWriteEnable(true); + MethodTable* objectType = (*protectedObj)->GetMethodTable(); CONSISTENCY_CHECK(CheckPointer(objectType)); @@ -2131,6 +2133,8 @@ PCODE VirtualCallStubManager::ResolveWorker(StubCallSite* pCallSite, // Target can be NULL only if we can't resolve to an address _ASSERTE(target != NULL); + PAL_JITWriteEnable(jitWriteEnabled); + return target; } @@ -2960,6 +2964,8 @@ LookupHolder *VirtualCallStubManager::GenerateLookupStub(PCODE addrOfResolver, s POSTCONDITION(CheckPointer(RETVAL)); } CONTRACT_END; + bool jitWriteEnabled = PAL_JITWriteEnable(true); + //allocate from the requisite heap and copy the template over it. LookupHolder * holder = (LookupHolder*) (void*) lookup_heap->AllocAlignedMem(sizeof(LookupHolder), CODE_SIZE_ALIGN); @@ -2978,6 +2984,8 @@ LookupHolder *VirtualCallStubManager::GenerateLookupStub(PCODE addrOfResolver, s PerfMap::LogStubs(__FUNCTION__, "GenerateLookupStub", (PCODE)holder->stub(), holder->stub()->size()); #endif + PAL_JITWriteEnable(jitWriteEnabled); + RETURN (holder); } From 59e9888683cc116950aa182e18263eae83e45d1d Mon Sep 17 00:00:00 2001 From: Steve MacLean Date: Thu, 20 Aug 2020 13:05:17 -0700 Subject: [PATCH 27/89] Fix JIT_WriteBarrier --- src/coreclr/src/vm/arm64/asmhelpers.S | 16 ++-------------- src/coreclr/src/vm/arm64/stubs.cpp | 2 -- src/coreclr/src/vm/threads.cpp | 7 ++++--- 3 files changed, 6 insertions(+), 19 deletions(-) diff --git a/src/coreclr/src/vm/arm64/asmhelpers.S b/src/coreclr/src/vm/arm64/asmhelpers.S index 1e88eab383595..70dc204afa6a3 100644 --- a/src/coreclr/src/vm/arm64/asmhelpers.S +++ b/src/coreclr/src/vm/arm64/asmhelpers.S @@ -264,6 +264,7 @@ LOCAL_LABEL(EphemeralCheckEnabled): // Update wbs state #ifdef FEATURE_WRITEBARRIER_COPY PREPARE_EXTERNAL_VAR JIT_WriteBarrier_Table_Loc, x12 + ldr x12, [x12] #else // FEATURE_WRITEBARRIER_COPY adr x12, LOCAL_LABEL(wbs_begin) #endif // FEATURE_WRITEBARRIER_COPY @@ -351,20 +352,7 @@ LOCAL_LABEL(Branch_JIT_WriteBarrier_Copy): #endif // FEATURE_WRITEBARRIER_COPY LEAF_END JIT_WriteBarrier_Callable, _TEXT -#ifdef FEATURE_WRITEBARRIER_COPY -.data -// When JIT_WriteBarrier is copied into an allocated page, -// helpers use this global variable to jump to it. This variable is set in InitThreadManager. -PATCH_LABEL JIT_WriteBarrier_Loc - .zero 8 - -// When JIT_WriteBarrier is copied into an allocated page, this variable is used to update the -// associated pc relative table. -PATCH_LABEL JIT_WriteBarrier_Table_Loc - .zero 8 -#endif // FEATURE_WRITEBARRIER_COPY - - +.balign 64 // Align to power of two at least as big as patchable literal pool so that it fits optimally in cache line //------------------------------------------ // Start of the writeable code region LEAF_ENTRY JIT_PatchedCodeStart, _TEXT diff --git a/src/coreclr/src/vm/arm64/stubs.cpp b/src/coreclr/src/vm/arm64/stubs.cpp index e9b79a3765219..e316bb4504eea 100644 --- a/src/coreclr/src/vm/arm64/stubs.cpp +++ b/src/coreclr/src/vm/arm64/stubs.cpp @@ -14,8 +14,6 @@ #include "jitinterface.h" #include "ecall.h" -EXTERN_C void JIT_UpdateWriteBarrierState(bool skipEphemeralCheck); - #ifndef DACCESS_COMPILE //----------------------------------------------------------------------- diff --git a/src/coreclr/src/vm/threads.cpp b/src/coreclr/src/vm/threads.cpp index 1dcc5a92152b7..b73d67b0dc56b 100644 --- a/src/coreclr/src/vm/threads.cpp +++ b/src/coreclr/src/vm/threads.cpp @@ -1123,8 +1123,9 @@ PCODE AdjustWriteBarrierIP(PCODE controlPc) extern "C" void *JIT_WriteBarrier_Loc; #ifdef TARGET_ARM64 -extern "C" void* JIT_WriteBarrier_Table; -extern "C" void *JIT_WriteBarrier_Table_Loc; +extern "C" void (*JIT_WriteBarrier_Table)(); +extern "C" void *JIT_WriteBarrier_Loc = 0; +extern "C" void *JIT_WriteBarrier_Table_Loc = 0; #endif // TARGET_ARM64 #endif // FEATURE_WRITEBARRIER_COPY @@ -1177,7 +1178,7 @@ void InitThreadManager() #ifdef TARGET_ARM64 // Store the JIT_WriteBarrier_Table copy location to a global variable so that it can be updated. - JIT_WriteBarrier_Table_Loc = GetWriteBarrierCodeLocation((void*)JIT_WriteBarrier_Table); + JIT_WriteBarrier_Table_Loc = GetWriteBarrierCodeLocation((void*)&JIT_WriteBarrier_Table); #endif // TARGET_ARM64 PAL_JITWriteEnable(jitWriteEnabled); From 7ffe655b2dd18d86dac15fc2be4a375eb752830d Mon Sep 17 00:00:00 2001 From: Steve MacLean Date: Thu, 20 Aug 2020 13:06:32 -0700 Subject: [PATCH 28/89] Prefer arm_thread_state64_get_*_fptr() form --- src/coreclr/src/debug/createdump/threadinfomac.cpp | 4 ++-- src/coreclr/src/pal/src/thread/context.cpp | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/coreclr/src/debug/createdump/threadinfomac.cpp b/src/coreclr/src/debug/createdump/threadinfomac.cpp index c2a1b3cfd3282..c9c8db8bb5058 100644 --- a/src/coreclr/src/debug/createdump/threadinfomac.cpp +++ b/src/coreclr/src/debug/createdump/threadinfomac.cpp @@ -101,10 +101,10 @@ ThreadInfo::Initialize() memcpy(m_gpRegisters.regs, &state.__x, sizeof(state.__x)); m_gpRegisters.regs[29] = arm_thread_state64_get_fp(state); - m_gpRegisters.regs[30] = arm_thread_state64_get_lr(state); + m_gpRegisters.regs[30] = (uint64_t)arm_thread_state64_get_lr_fptr(state); m_gpRegisters.sp = arm_thread_state64_get_sp(state); - m_gpRegisters.pc = arm_thread_state64_get_pc(state); + m_gpRegisters.pc = (uint64_t)arm_thread_state64_get_pc_fptr(state); arm_neon_state64_t fpstate; stateCount = ARM_NEON_STATE64_COUNT; diff --git a/src/coreclr/src/pal/src/thread/context.cpp b/src/coreclr/src/pal/src/thread/context.cpp index 5e733103ba768..8d53e80af0115 100644 --- a/src/coreclr/src/pal/src/thread/context.cpp +++ b/src/coreclr/src/pal/src/thread/context.cpp @@ -1142,8 +1142,8 @@ CONTEXT_GetThreadContextFromThreadState( lpContext->Cpsr = pState->__cpsr; lpContext->Fp = arm_thread_state64_get_fp(*pState); lpContext->Sp = arm_thread_state64_get_sp(*pState); - lpContext->Lr = arm_thread_state64_get_lr(*pState); - lpContext->Pc = arm_thread_state64_get_pc(*pState); + lpContext->Lr = (uint64_t)arm_thread_state64_get_lr_fptr(*pState); + lpContext->Pc = (uint64_t)arm_thread_state64_get_pc_fptr(*pState); } break; case ARM_NEON_STATE64: From e588304d8767f22bbb239a988a0db0160521f379 Mon Sep 17 00:00:00 2001 From: Steve MacLean Date: Thu, 20 Aug 2020 13:14:19 -0700 Subject: [PATCH 29/89] Strip libunwind pointer authentication bits --- src/coreclr/src/pal/src/exception/seh-unwind.cpp | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/coreclr/src/pal/src/exception/seh-unwind.cpp b/src/coreclr/src/pal/src/exception/seh-unwind.cpp index 358467a6b1d15..93e0129d48b5c 100644 --- a/src/coreclr/src/pal/src/exception/seh-unwind.cpp +++ b/src/coreclr/src/pal/src/exception/seh-unwind.cpp @@ -254,6 +254,13 @@ void UnwindContextToWinContext(unw_cursor_t *cursor, CONTEXT *winContext) unw_get_reg(cursor, UNW_AARCH64_X26, (unw_word_t *) &winContext->X26); unw_get_reg(cursor, UNW_AARCH64_X27, (unw_word_t *) &winContext->X27); unw_get_reg(cursor, UNW_AARCH64_X28, (unw_word_t *) &winContext->X28); + +#if defined(TARGET_OSX) && defined(TARGET_ARM64) + // Strip pointer authentication bits which seem to be leaking out of libunwind + // Seems like ptrauth_strip() / __builtin_ptrauth_strip() should work, but currently + // errors with "this target does not support pointer authentication" + winContext->Pc = winContext->Pc & 0x7fffffffffffull; +#endif // defined(TARGET_OSX) && defined(TARGET_ARM64) #else #error unsupported architecture #endif From c6658cdbb5b804ec7f63209da6faa368f674e95f Mon Sep 17 00:00:00 2001 From: Steve MacLean Date: Thu, 20 Aug 2020 13:20:53 -0700 Subject: [PATCH 30/89] Disable RunStartupHooks() --- src/coreclr/src/vm/assembly.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/coreclr/src/vm/assembly.cpp b/src/coreclr/src/vm/assembly.cpp index 4934ae689708c..dd5fb1607cdf6 100644 --- a/src/coreclr/src/vm/assembly.cpp +++ b/src/coreclr/src/vm/assembly.cpp @@ -1643,7 +1643,13 @@ INT32 Assembly::ExecuteMainMethod(PTRARRAYREF *stringArgs, BOOL waitForOtherThre AppDomain * pDomain = pThread->GetDomain(); pDomain->SetRootAssembly(pMeth->GetAssembly()); +#if defined(TARGET_OSX) && defined(TARGET_ARM64) + // FIXME-OSX-ARM64 RunStartupHooks() calls managed code + // which breaks on osx-arm64 currently. + // Disable this advanced feature during platform bringup. +#else RunStartupHooks(); +#endif // defined(TARGET_OSX) && defined(TARGET_ARM64) hr = RunMain(pMeth, 1, &iRetVal, stringArgs); } From a051fe7ccb7154435f0cf42f1833b727ae4b718e Mon Sep 17 00:00:00 2001 From: Steve MacLean Date: Thu, 20 Aug 2020 13:25:25 -0700 Subject: [PATCH 31/89] Remove incorrect consistency check --- src/coreclr/src/vm/stackwalk.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/src/coreclr/src/vm/stackwalk.cpp b/src/coreclr/src/vm/stackwalk.cpp index dcd2cb97e034e..380a7543dfcb2 100644 --- a/src/coreclr/src/vm/stackwalk.cpp +++ b/src/coreclr/src/vm/stackwalk.cpp @@ -2266,7 +2266,6 @@ StackWalkAction StackFrameIterator::NextRaw(void) // make sure we're not skipping a different transition if (m_crawl.pFrame->NeedsUpdateRegDisplay()) { - CONSISTENCY_CHECK(m_crawl.pFrame->IsTransitionToNativeFrame()); if (m_crawl.pFrame->GetVTablePtr() == InlinedCallFrame::GetMethodFrameVPtr()) { // ControlPC may be different as the InlinedCallFrame stays active throughout From 740460589f3921bdf0b1415243002656cc59d85f Mon Sep 17 00:00:00 2001 From: Steve MacLean Date: Fri, 21 Aug 2020 11:00:53 -0700 Subject: [PATCH 32/89] Fix Windows compilation --- src/coreclr/src/inc/loaderheap.h | 8 ++++++++ src/coreclr/src/vm/arm64/stubs.cpp | 8 ++++++++ src/coreclr/src/vm/callcounting.cpp | 4 ++++ src/coreclr/src/vm/callhelpers.cpp | 2 ++ src/coreclr/src/vm/codeman.cpp | 4 ++++ src/coreclr/src/vm/dllimportcallback.h | 4 ++++ src/coreclr/src/vm/methoddescbackpatchinfo.cpp | 4 ++++ src/coreclr/src/vm/precode.cpp | 8 ++++++++ src/coreclr/src/vm/prestub.cpp | 8 ++++++++ src/coreclr/src/vm/threads.cpp | 4 ++++ src/coreclr/src/vm/virtualcallstub.cpp | 8 ++++++++ 11 files changed, 62 insertions(+) diff --git a/src/coreclr/src/inc/loaderheap.h b/src/coreclr/src/inc/loaderheap.h index aecb316ae658c..f482703931679 100644 --- a/src/coreclr/src/inc/loaderheap.h +++ b/src/coreclr/src/inc/loaderheap.h @@ -549,7 +549,9 @@ class LoaderHeap : public UnlockedLoaderHeap, public ILoaderHeapBackout { WRAPPER_NO_CONTRACT; +#if defined(HOST_OSX) && defined(HOST_ARM64) bool jitWriteEnabled = PAL_JITWriteEnable(true); +#endif // defined(HOST_OSX) && defined(HOST_ARM64) void *pResult; TaggedMemAllocPtr tmap; @@ -569,7 +571,9 @@ class LoaderHeap : public UnlockedLoaderHeap, public ILoaderHeapBackout tmap.m_szFile = szFile; tmap.m_lineNum = lineNum; #endif +#if defined(HOST_OSX) && defined(HOST_ARM64) PAL_JITWriteEnable(jitWriteEnabled); +#endif // defined(HOST_OSX) && defined(HOST_ARM64) return tmap; } @@ -628,7 +632,9 @@ class LoaderHeap : public UnlockedLoaderHeap, public ILoaderHeapBackout { WRAPPER_NO_CONTRACT; +#if defined(HOST_OSX) && defined(HOST_ARM64) bool jitWriteEnabled = PAL_JITWriteEnable(true); +#endif // defined(HOST_OSX) && defined(HOST_ARM64) CRITSEC_Holder csh(m_CriticalSection); @@ -654,7 +660,9 @@ class LoaderHeap : public UnlockedLoaderHeap, public ILoaderHeapBackout tmap.m_szFile = szFile; tmap.m_lineNum = lineNum; #endif +#if defined(HOST_OSX) && defined(HOST_ARM64) PAL_JITWriteEnable(jitWriteEnabled); +#endif // defined(HOST_OSX) && defined(HOST_ARM64) return tmap; } diff --git a/src/coreclr/src/vm/arm64/stubs.cpp b/src/coreclr/src/vm/arm64/stubs.cpp index e316bb4504eea..47b7387bb081c 100644 --- a/src/coreclr/src/vm/arm64/stubs.cpp +++ b/src/coreclr/src/vm/arm64/stubs.cpp @@ -635,7 +635,9 @@ void FixupPrecode::Init(MethodDesc* pMD, LoaderAllocator *pLoaderAllocator, int { WRAPPER_NO_CONTRACT; +#if defined(HOST_OSX) && defined(HOST_ARM64) bool jitWriteEnabled = PAL_JITWriteEnable(true); +#endif // defined(HOST_OSX) && defined(HOST_ARM64) InitCommon(); @@ -665,7 +667,9 @@ void FixupPrecode::Init(MethodDesc* pMD, LoaderAllocator *pLoaderAllocator, int m_pTarget = GetEEFuncEntryPoint(PrecodeFixupThunk); } +#if defined(HOST_OSX) && defined(HOST_ARM64) PAL_JITWriteEnable(jitWriteEnabled); +#endif // defined(HOST_OSX) && defined(HOST_ARM64) } #ifdef FEATURE_NATIVE_IMAGE_GENERATION @@ -1064,11 +1068,15 @@ EXTERN_C void JIT_UpdateWriteBarrierState(bool skipEphemeralCheck); static void SafeUpdateWriteBarrierState(bool skipEphemeralCheck) { +#if defined(HOST_OSX) && defined(HOST_ARM64) bool jitWriteEnabled = PAL_JITWriteEnable(true); +#endif // defined(HOST_OSX) && defined(HOST_ARM64) JIT_UpdateWriteBarrierState(GCHeapUtilities::IsServerHeap()); +#if defined(HOST_OSX) && defined(HOST_ARM64) PAL_JITWriteEnable(jitWriteEnabled); +#endif // defined(HOST_OSX) && defined(HOST_ARM64) } void InitJITHelpers1() diff --git a/src/coreclr/src/vm/callcounting.cpp b/src/coreclr/src/vm/callcounting.cpp index cde52f3916a92..dcde53dd71afb 100644 --- a/src/coreclr/src/vm/callcounting.cpp +++ b/src/coreclr/src/vm/callcounting.cpp @@ -251,7 +251,9 @@ const CallCountingStub *CallCountingManager::CallCountingStubAllocator::Allocate } CONTRACTL_END; +#if defined(HOST_OSX) && defined(HOST_ARM64) bool jitWriteEnabled = PAL_JITWriteEnable(true); +#endif // defined(HOST_OSX) && defined(HOST_ARM64) LoaderHeap *heap = m_heap; if (heap == nullptr) @@ -294,7 +296,9 @@ const CallCountingStub *CallCountingManager::CallCountingStubAllocator::Allocate #endif } while (false); +#if defined(HOST_OSX) && defined(HOST_ARM64) PAL_JITWriteEnable(jitWriteEnabled); +#endif // defined(HOST_OSX) && defined(HOST_ARM64) ClrFlushInstructionCache(stub, sizeInBytes); return stub; diff --git a/src/coreclr/src/vm/callhelpers.cpp b/src/coreclr/src/vm/callhelpers.cpp index 1695811c18278..2706518fe0ab6 100644 --- a/src/coreclr/src/vm/callhelpers.cpp +++ b/src/coreclr/src/vm/callhelpers.cpp @@ -71,7 +71,9 @@ void CallDescrWorkerWithHandler( END_CALL_TO_MANAGED(); +#if defined(HOST_OSX) && defined(HOST_ARM64) PAL_JITWriteEnable(jitWriteEnabled); +#endif // defined(HOST_OSX) && defined(HOST_ARM64) } diff --git a/src/coreclr/src/vm/codeman.cpp b/src/coreclr/src/vm/codeman.cpp index 00b04635fceeb..0887cfdcdc1eb 100644 --- a/src/coreclr/src/vm/codeman.cpp +++ b/src/coreclr/src/vm/codeman.cpp @@ -1829,7 +1829,9 @@ TaggedMemAllocPtr CodeFragmentHeap::RealAllocAlignedMem(size_t dwRequestedSize { CrstHolder ch(&m_CritSec); +#if defined(HOST_OSX) && defined(HOST_ARM64) bool jitWriteEnabled = PAL_JITWriteEnable(true); +#endif // defined(HOST_OSX) && defined(HOST_ARM64) dwRequestedSize = ALIGN_UP(dwRequestedSize, sizeof(TADDR)); @@ -1895,7 +1897,9 @@ TaggedMemAllocPtr CodeFragmentHeap::RealAllocAlignedMem(size_t dwRequestedSize tmap.m_szFile = szFile; tmap.m_lineNum = lineNum; #endif +#if defined(HOST_OSX) && defined(HOST_ARM64) PAL_JITWriteEnable(jitWriteEnabled); +#endif // defined(HOST_OSX) && defined(HOST_ARM64) return tmap; } diff --git a/src/coreclr/src/vm/dllimportcallback.h b/src/coreclr/src/vm/dllimportcallback.h index 9befa328bff95..5ee382eed26d6 100644 --- a/src/coreclr/src/vm/dllimportcallback.h +++ b/src/coreclr/src/vm/dllimportcallback.h @@ -267,7 +267,9 @@ class UMEntryThunk } CONTRACTL_END; +#if defined(HOST_OSX) && defined(HOST_ARM64) bool jitWriteEnabled = PAL_JITWriteEnable(true); +#endif // defined(HOST_OSX) && defined(HOST_ARM64) m_pManagedTarget = pManagedTarget; m_pObjectHandle = pObjectHandle; @@ -280,7 +282,9 @@ class UMEntryThunk #ifdef _DEBUG m_state = kLoadTimeInited; #endif +#if defined(HOST_OSX) && defined(HOST_ARM64) PAL_JITWriteEnable(jitWriteEnabled); +#endif // defined(HOST_OSX) && defined(HOST_ARM64) } void Terminate(); diff --git a/src/coreclr/src/vm/methoddescbackpatchinfo.cpp b/src/coreclr/src/vm/methoddescbackpatchinfo.cpp index 79620ecc00d4f..d3b73d36ac18d 100644 --- a/src/coreclr/src/vm/methoddescbackpatchinfo.cpp +++ b/src/coreclr/src/vm/methoddescbackpatchinfo.cpp @@ -28,7 +28,9 @@ void EntryPointSlots::Backpatch_Locked(TADDR slot, SlotType slotType, PCODE entr _ASSERTE(entryPoint != NULL); _ASSERTE(IS_ALIGNED((SIZE_T)slot, GetRequiredSlotAlignment(slotType))); +#if defined(HOST_OSX) && defined(HOST_ARM64) bool jitWriteEnabled = PAL_JITWriteEnable(true); +#endif // defined(HOST_OSX) && defined(HOST_ARM64) switch (slotType) { @@ -52,7 +54,9 @@ void EntryPointSlots::Backpatch_Locked(TADDR slot, SlotType slotType, PCODE entr // fall through Flush: +#if defined(HOST_OSX) && defined(HOST_ARM64) PAL_JITWriteEnable(jitWriteEnabled); +#endif // defined(HOST_OSX) && defined(HOST_ARM64) ClrFlushInstructionCache((LPCVOID)slot, sizeof(PCODE)); break; diff --git a/src/coreclr/src/vm/precode.cpp b/src/coreclr/src/vm/precode.cpp index da4f2c5a2e7b3..5b599ab915da0 100644 --- a/src/coreclr/src/vm/precode.cpp +++ b/src/coreclr/src/vm/precode.cpp @@ -404,7 +404,9 @@ void Precode::ResetTargetInterlocked() { WRAPPER_NO_CONTRACT; +#if defined(HOST_OSX) && defined(HOST_ARM64) bool jitWriteEnabled = PAL_JITWriteEnable(true); +#endif // defined(HOST_OSX) && defined(HOST_ARM64) PrecodeType precodeType = GetType(); switch (precodeType) @@ -424,7 +426,9 @@ void Precode::ResetTargetInterlocked() break; } +#if defined(HOST_OSX) && defined(HOST_ARM64) PAL_JITWriteEnable(jitWriteEnabled); +#endif // defined(HOST_OSX) && defined(HOST_ARM64) // Although executable code is modified on x86/x64, a FlushInstructionCache() is not necessary on those platforms due to the // interlocked operation above (see ClrFlushInstructionCache()) @@ -441,7 +445,9 @@ BOOL Precode::SetTargetInterlocked(PCODE target, BOOL fOnlyRedirectFromPrestub) if (fOnlyRedirectFromPrestub && !IsPointingToPrestub(expected)) return FALSE; +#if defined(HOST_OSX) && defined(HOST_ARM64) bool jitWriteEnabled = PAL_JITWriteEnable(true); +#endif // defined(HOST_OSX) && defined(HOST_ARM64) g_IBCLogger.LogMethodPrecodeWriteAccess(GetMethodDesc()); @@ -469,7 +475,9 @@ BOOL Precode::SetTargetInterlocked(PCODE target, BOOL fOnlyRedirectFromPrestub) break; } +#if defined(HOST_OSX) && defined(HOST_ARM64) PAL_JITWriteEnable(jitWriteEnabled); +#endif // defined(HOST_OSX) && defined(HOST_ARM64) // Although executable code is modified on x86/x64, a FlushInstructionCache() is not necessary on those platforms due to the // interlocked operation above (see ClrFlushInstructionCache()) diff --git a/src/coreclr/src/vm/prestub.cpp b/src/coreclr/src/vm/prestub.cpp index 89cf97f6a3bc6..c70fe266d84be 100644 --- a/src/coreclr/src/vm/prestub.cpp +++ b/src/coreclr/src/vm/prestub.cpp @@ -326,7 +326,9 @@ PCODE MethodDesc::PrepareCode(PrepareCodeConfig* pConfig) { STANDARD_VM_CONTRACT; +#if defined(HOST_OSX) && defined(HOST_ARM64) bool jitWriteEnabled = PAL_JITWriteEnable(true); +#endif // defined(HOST_OSX) && defined(HOST_ARM64) // If other kinds of code need multi-versioning we could add more cases here, // but for now generation of all other code/stubs occurs in other code paths @@ -337,7 +339,9 @@ PCODE MethodDesc::PrepareCode(PrepareCodeConfig* pConfig) NotifyGdb::MethodPrepared(this); #endif +#if defined(HOST_OSX) && defined(HOST_ARM64) PAL_JITWriteEnable(jitWriteEnabled); +#endif // defined(HOST_OSX) && defined(HOST_ARM64) return pCode; } @@ -1884,7 +1888,9 @@ extern "C" PCODE STDCALL PreStubWorker(TransitionBlock* pTransitionBlock, Method ETWOnStartup(PrestubWorker_V1, PrestubWorkerEnd_V1); +#if defined(HOST_OSX) && defined(HOST_ARM64) bool jitWriteEnabled = PAL_JITWriteEnable(true); +#endif // defined(HOST_OSX) && defined(HOST_ARM64) MAKE_CURRENT_THREAD_AVAILABLE(); @@ -1970,7 +1976,9 @@ extern "C" PCODE STDCALL PreStubWorker(TransitionBlock* pTransitionBlock, Method pPFrame->Pop(CURRENT_THREAD); } +#if defined(HOST_OSX) && defined(HOST_ARM64) PAL_JITWriteEnable(jitWriteEnabled); +#endif // defined(HOST_OSX) && defined(HOST_ARM64) POSTCONDITION(pbRetVal != NULL); diff --git a/src/coreclr/src/vm/threads.cpp b/src/coreclr/src/vm/threads.cpp index b73d67b0dc56b..b754c4d4a3368 100644 --- a/src/coreclr/src/vm/threads.cpp +++ b/src/coreclr/src/vm/threads.cpp @@ -1166,7 +1166,9 @@ void InitThreadManager() COMPlusThrowWin32(); } +#if defined(HOST_OSX) && defined(HOST_ARM64) bool jitWriteEnabled = PAL_JITWriteEnable(true); +#endif // defined(HOST_OSX) && defined(HOST_ARM64) memcpy(s_barrierCopy, (BYTE*)JIT_PatchedCodeStart, (BYTE*)JIT_PatchedCodeLast - (BYTE*)JIT_PatchedCodeStart); @@ -1181,7 +1183,9 @@ void InitThreadManager() JIT_WriteBarrier_Table_Loc = GetWriteBarrierCodeLocation((void*)&JIT_WriteBarrier_Table); #endif // TARGET_ARM64 +#if defined(HOST_OSX) && defined(HOST_ARM64) PAL_JITWriteEnable(jitWriteEnabled); +#endif // defined(HOST_OSX) && defined(HOST_ARM64) #else // FEATURE_WRITEBARRIER_COPY diff --git a/src/coreclr/src/vm/virtualcallstub.cpp b/src/coreclr/src/vm/virtualcallstub.cpp index b6ed62177cb86..73c256f0bbbab 100644 --- a/src/coreclr/src/vm/virtualcallstub.cpp +++ b/src/coreclr/src/vm/virtualcallstub.cpp @@ -1708,7 +1708,9 @@ PCODE VirtualCallStubManager::ResolveWorker(StubCallSite* pCallSite, PRECONDITION(IsProtectedByGCFrame(protectedObj)); } CONTRACTL_END; +#if defined(HOST_OSX) && defined(HOST_ARM64) bool jitWriteEnabled = PAL_JITWriteEnable(true); +#endif // defined(HOST_OSX) && defined(HOST_ARM64) MethodTable* objectType = (*protectedObj)->GetMethodTable(); CONSISTENCY_CHECK(CheckPointer(objectType)); @@ -2133,7 +2135,9 @@ PCODE VirtualCallStubManager::ResolveWorker(StubCallSite* pCallSite, // Target can be NULL only if we can't resolve to an address _ASSERTE(target != NULL); +#if defined(HOST_OSX) && defined(HOST_ARM64) PAL_JITWriteEnable(jitWriteEnabled); +#endif // defined(HOST_OSX) && defined(HOST_ARM64) return target; } @@ -2964,7 +2968,9 @@ LookupHolder *VirtualCallStubManager::GenerateLookupStub(PCODE addrOfResolver, s POSTCONDITION(CheckPointer(RETVAL)); } CONTRACT_END; +#if defined(HOST_OSX) && defined(HOST_ARM64) bool jitWriteEnabled = PAL_JITWriteEnable(true); +#endif // defined(HOST_OSX) && defined(HOST_ARM64) //allocate from the requisite heap and copy the template over it. LookupHolder * holder = (LookupHolder*) (void*) lookup_heap->AllocAlignedMem(sizeof(LookupHolder), CODE_SIZE_ALIGN); @@ -2984,7 +2990,9 @@ LookupHolder *VirtualCallStubManager::GenerateLookupStub(PCODE addrOfResolver, s PerfMap::LogStubs(__FUNCTION__, "GenerateLookupStub", (PCODE)holder->stub(), holder->stub()->size()); #endif +#if defined(HOST_OSX) && defined(HOST_ARM64) PAL_JITWriteEnable(jitWriteEnabled); +#endif // defined(HOST_OSX) && defined(HOST_ARM64) RETURN (holder); } From 7ca8f3e61bf775541b3c0d916966f5d04fef30f5 Mon Sep 17 00:00:00 2001 From: Steve MacLean Date: Fri, 21 Aug 2020 11:37:05 -0700 Subject: [PATCH 33/89] Set OSX_ARCHITECTURES to fix 41164 --- eng/native/configureplatform.cmake | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/eng/native/configureplatform.cmake b/eng/native/configureplatform.cmake index c5765e5d82a24..7bf600cf6b16a 100644 --- a/eng/native/configureplatform.cmake +++ b/eng/native/configureplatform.cmake @@ -82,17 +82,21 @@ if(CLR_CMAKE_HOST_OS STREQUAL Darwin) if(NOT CLR_CROSS_COMPONENTS_BUILD AND CLR_CMAKE_TARGET_ARCH STREQUAL arm64) set(CLR_CMAKE_HOST_UNIX_ARM64 1) set(CMAKE_OSX_ARCHITECTURES arm64) + set(OSX_ARCHITECTURES arm64) else() set(CLR_CMAKE_HOST_UNIX_AMD64 1) set(CMAKE_OSX_ARCHITECTURES x86_64) + set(OSX_ARCHITECTURES x86_64) endif() elseif(CMAKE_SYSTEM_PROCESSOR STREQUAL arm64) if(NOT CLR_CROSS_COMPONENTS_BUILD AND CLR_CMAKE_TARGET_ARCH STREQUAL x64) set(CLR_CMAKE_HOST_UNIX_AMD64 1) set(CMAKE_OSX_ARCHITECTURES x86_64) + set(OSX_ARCHITECTURES x86_64) else() set(CLR_CMAKE_HOST_UNIX_ARM64 1) set(CMAKE_OSX_ARCHITECTURES arm64) + set(OSX_ARCHITECTURES arm64) endif() else() clr_unknown_arch() From 82ff7680f26847f249a42c8fe72301c856cb5af1 Mon Sep 17 00:00:00 2001 From: Steve MacLean Date: Fri, 21 Aug 2020 11:48:21 -0700 Subject: [PATCH 34/89] Fix Windows compilation+ --- src/coreclr/src/inc/loaderheap.h | 2 ++ src/coreclr/src/pal/inc/pal.h | 2 ++ src/coreclr/src/pal/src/map/virtual.cpp | 7 ------- src/coreclr/src/utilcode/loaderheap.cpp | 4 ++++ src/coreclr/src/vm/callhelpers.cpp | 3 ++- src/coreclr/src/vm/ceemain.cpp | 2 ++ 6 files changed, 12 insertions(+), 8 deletions(-) diff --git a/src/coreclr/src/inc/loaderheap.h b/src/coreclr/src/inc/loaderheap.h index f482703931679..8ce81fb4d7388 100644 --- a/src/coreclr/src/inc/loaderheap.h +++ b/src/coreclr/src/inc/loaderheap.h @@ -571,6 +571,7 @@ class LoaderHeap : public UnlockedLoaderHeap, public ILoaderHeapBackout tmap.m_szFile = szFile; tmap.m_lineNum = lineNum; #endif + #if defined(HOST_OSX) && defined(HOST_ARM64) PAL_JITWriteEnable(jitWriteEnabled); #endif // defined(HOST_OSX) && defined(HOST_ARM64) @@ -660,6 +661,7 @@ class LoaderHeap : public UnlockedLoaderHeap, public ILoaderHeapBackout tmap.m_szFile = szFile; tmap.m_lineNum = lineNum; #endif + #if defined(HOST_OSX) && defined(HOST_ARM64) PAL_JITWriteEnable(jitWriteEnabled); #endif // defined(HOST_OSX) && defined(HOST_ARM64) diff --git a/src/coreclr/src/pal/inc/pal.h b/src/coreclr/src/pal/inc/pal.h index 560ab4968cc28..3ca7dc7986f4a 100644 --- a/src/coreclr/src/pal/inc/pal.h +++ b/src/coreclr/src/pal/inc/pal.h @@ -2714,10 +2714,12 @@ VirtualFree( IN SIZE_T dwSize, IN DWORD dwFreeType); +#if defined(HOST_OSX) && defined(HOST_ARM64) PALIMPORT bool PALAPI PAL_JITWriteEnable(IN bool enable); +#endif // defined(HOST_OSX) && defined(HOST_ARM64) PALIMPORT BOOL diff --git a/src/coreclr/src/pal/src/map/virtual.cpp b/src/coreclr/src/pal/src/map/virtual.cpp index 2815489e25f49..02eee4e503684 100644 --- a/src/coreclr/src/pal/src/map/virtual.cpp +++ b/src/coreclr/src/pal/src/map/virtual.cpp @@ -1776,13 +1776,6 @@ PAL_JITWriteEnable(bool writeEnable) } return result; } -#else -bool -PALAPI -PAL_JITWriteEnable(bool) -{ - return true; -} #endif #if HAVE_VM_ALLOCATE diff --git a/src/coreclr/src/utilcode/loaderheap.cpp b/src/coreclr/src/utilcode/loaderheap.cpp index 8d07ed8a10e5e..214f1f7348d82 100644 --- a/src/coreclr/src/utilcode/loaderheap.cpp +++ b/src/coreclr/src/utilcode/loaderheap.cpp @@ -1159,9 +1159,11 @@ BOOL UnlockedLoaderHeap::UnlockedReservePages(size_t dwSizeToCommit) LoaderHeapBlock *pNewBlock; +#if defined(HOST_OSX) && defined(HOST_ARM64) bool jitWriteEnable = false; if (m_Options & LHF_EXECUTABLE) jitWriteEnable = PAL_JITWriteEnable(true); +#endif // defined(HOST_OSX) && defined(HOST_ARM64) pNewBlock = (LoaderHeapBlock *) pData; @@ -1187,8 +1189,10 @@ BOOL UnlockedLoaderHeap::UnlockedReservePages(size_t dwSizeToCommit) SETUP_NEW_BLOCK(pData, dwSizeToCommit, dwSizeToReserve); +#if defined(HOST_OSX) && defined(HOST_ARM64) if (m_Options & LHF_EXECUTABLE) PAL_JITWriteEnable(jitWriteEnable); +#endif // defined(HOST_OSX) && defined(HOST_ARM64) return TRUE; } diff --git a/src/coreclr/src/vm/callhelpers.cpp b/src/coreclr/src/vm/callhelpers.cpp index 2706518fe0ab6..3c736359086c1 100644 --- a/src/coreclr/src/vm/callhelpers.cpp +++ b/src/coreclr/src/vm/callhelpers.cpp @@ -62,8 +62,9 @@ void CallDescrWorkerWithHandler( #endif +#if defined(HOST_OSX) && defined(HOST_ARM64) bool jitWriteEnabled = PAL_JITWriteEnable(false); - +#endif // defined(HOST_OSX) && defined(HOST_ARM64) BEGIN_CALL_TO_MANAGEDEX(fCriticalCall ? EEToManagedCriticalCall : EEToManagedDefault); diff --git a/src/coreclr/src/vm/ceemain.cpp b/src/coreclr/src/vm/ceemain.cpp index 0ceb684ce52a8..3d35d80454d20 100644 --- a/src/coreclr/src/vm/ceemain.cpp +++ b/src/coreclr/src/vm/ceemain.cpp @@ -969,7 +969,9 @@ void EEStartupHelper() #endif // CROSSGEN_COMPILE +#if defined(HOST_OSX) && defined(HOST_ARM64) PAL_JITWriteEnable(true); +#endif // defined(HOST_OSX) && defined(HOST_ARM64) SystemDomain::System()->Init(); From c38cd7cf3e73f18ec571d54aee625c39f38bdb18 Mon Sep 17 00:00:00 2001 From: Steve MacLean Date: Fri, 21 Aug 2020 17:00:08 -0700 Subject: [PATCH 35/89] Add HOST_OSX --- eng/native/configurecompiler.cmake | 1 + 1 file changed, 1 insertion(+) diff --git a/eng/native/configurecompiler.cmake b/eng/native/configurecompiler.cmake index eb97131e7c4a3..bffb794197548 100644 --- a/eng/native/configurecompiler.cmake +++ b/eng/native/configurecompiler.cmake @@ -234,6 +234,7 @@ if (CLR_CMAKE_HOST_UNIX) add_definitions(-DHOST_UNIX) if(CLR_CMAKE_HOST_OSX) + add_definitions(-DHOST_OSX) if(CLR_CMAKE_HOST_UNIX_AMD64) message("Detected OSX x86_64") elseif(CLR_CMAKE_HOST_UNIX_ARM64) From 8aa138101195eab6b80183951c2c5d7d31d373f4 Mon Sep 17 00:00:00 2001 From: Steve MacLean Date: Fri, 21 Aug 2020 17:01:03 -0700 Subject: [PATCH 36/89] Fix JIT_WriteBarrier_Loc usage --- src/coreclr/src/vm/arm64/asmhelpers.S | 1 + 1 file changed, 1 insertion(+) diff --git a/src/coreclr/src/vm/arm64/asmhelpers.S b/src/coreclr/src/vm/arm64/asmhelpers.S index 70dc204afa6a3..8ae043c5ff8a4 100644 --- a/src/coreclr/src/vm/arm64/asmhelpers.S +++ b/src/coreclr/src/vm/arm64/asmhelpers.S @@ -345,6 +345,7 @@ LEAF_ENTRY JIT_WriteBarrier_Callable, _TEXT LOCAL_LABEL(Branch_JIT_WriteBarrier_Copy): // Branch to the write barrier PREPARE_EXTERNAL_VAR JIT_WriteBarrier_Loc, x17 + ldr x17, [x17] br x17 #else // FEATURE_WRITEBARRIER_COPY // Branch to the write barrier From 26ff8a3ea14eff6e0cecb26ffdf91ba0283eb8e5 Mon Sep 17 00:00:00 2001 From: Steve MacLean Date: Fri, 21 Aug 2020 17:19:59 -0700 Subject: [PATCH 37/89] Revise generate-osx-arm64-layout.sh --- src/coreclr/generate-osx-arm64-layout.sh | 31 +++++++++++++----------- 1 file changed, 17 insertions(+), 14 deletions(-) diff --git a/src/coreclr/generate-osx-arm64-layout.sh b/src/coreclr/generate-osx-arm64-layout.sh index 10ca13bdb0e99..abbedf107ea13 100755 --- a/src/coreclr/generate-osx-arm64-layout.sh +++ b/src/coreclr/generate-osx-arm64-layout.sh @@ -1,9 +1,7 @@ #! /bin/bash # This is a simple and currently crude script to generate an osx-arm64 Core_Root -# It takes a reference osx-x64 Core_Root and replaces the native bits and -# System.Private.CoreLib.dll from those built locally. -# It then removes any remaining x64 native binaries +# It works around issues with native files being built and/or included with the wrong arch # ToDo # Error checking!!! @@ -23,10 +21,9 @@ done RepoRoot="$( cd -P "$( dirname "$source" )/../.." && pwd )" -Reference_Core_Root=${RepoRoot}/artifacts/tests/coreclr/OSX.x64.Debug/Tests/Core_Root Core_Root=${RepoRoot}/artifacts/tests/coreclr/OSX.arm64.Debug/Tests/Core_Root -Arm64_Native_Paths="${RepoRoot}/artifacts/bin/coreclr/OSX.arm64.Debug ${RepoRoot}/artifacts/bin/native/net5.0-OSX-Debug-arm64" -Arm64_SPC_Path=${RepoRoot}/artifacts/bin/coreclr/OSX.arm64.Release/IL +Arm64_Native_Paths="${RepoRoot}/artifacts/bin/coreclr/OSX.arm64.Debug ${RepoRoot}/artifacts/bin/native/OSX-arm64-Debug" +Arm64_SPC_Path=${RepoRoot}/artifacts/bin/coreclr/OSX.arm64.Debug/IL function x64NativeFiles() { @@ -36,16 +33,19 @@ function x64NativeFiles() done } -# Remove any existing Core Root -rm -rf ${Core_Root} +# Remove any arm64 native files which were built with x86_64 architecture +for n in $(find ${Arm64_Native_Paths} -type f) +do + (file $n | grep -q x86_64) && rm $n +done -# Create empty directory path -mkdir -p ${Core_Root} +# Rebuild native arm64 files +${RepoRoot}/src/libraries/Native/build-native.sh -arm64 +${RepoRoot}/src/coreclr/build-runtime.sh -arm64 -# Copy reference Core Root -cp -r ${Reference_Core_Root}/* ${Core_Root} +${RepoRoot}/src/coreclr/build-test.sh arm64 generatelayoutonly /p:LibrariesConfiguration=Debug -# Copy crossgened arm64 S.P.C.dll +# Copy arm64 IL S.P.C.dll cp ${Arm64_SPC_Path}/System.Private.CoreLib.dll ${Core_Root} # Replace osx-x64 native files with their arm64 counterparts @@ -53,7 +53,10 @@ for i in $(x64NativeFiles) do echo echo $i - find ${Arm64_Native_Paths} -name $(basename $i) -exec md5 "{}" ';' -exec cp "{}" $i ';' + for n in $(find ${Arm64_Native_Paths} -name $(basename $i)) + do + (file $n | grep -q x86_64) || (md5 $n; cp $n $i) + done done 2>&1 echo From 2564ebd69bb08ca005efeb6796721d1089e5d733 Mon Sep 17 00:00:00 2001 From: Steve MacLean Date: Sat, 22 Aug 2020 13:36:34 -0700 Subject: [PATCH 38/89] Reenable RunStartupHooks() --- src/coreclr/src/vm/assembly.cpp | 6 ------ 1 file changed, 6 deletions(-) diff --git a/src/coreclr/src/vm/assembly.cpp b/src/coreclr/src/vm/assembly.cpp index dd5fb1607cdf6..4934ae689708c 100644 --- a/src/coreclr/src/vm/assembly.cpp +++ b/src/coreclr/src/vm/assembly.cpp @@ -1643,13 +1643,7 @@ INT32 Assembly::ExecuteMainMethod(PTRARRAYREF *stringArgs, BOOL waitForOtherThre AppDomain * pDomain = pThread->GetDomain(); pDomain->SetRootAssembly(pMeth->GetAssembly()); -#if defined(TARGET_OSX) && defined(TARGET_ARM64) - // FIXME-OSX-ARM64 RunStartupHooks() calls managed code - // which breaks on osx-arm64 currently. - // Disable this advanced feature during platform bringup. -#else RunStartupHooks(); -#endif // defined(TARGET_OSX) && defined(TARGET_ARM64) hr = RunMain(pMeth, 1, &iRetVal, stringArgs); } From 325d1840073c17157b82a13fccea6bbd761913ac Mon Sep 17 00:00:00 2001 From: Steve MacLean Date: Tue, 25 Aug 2020 16:08:13 -0700 Subject: [PATCH 39/89] Rework CMAKE_OSX_ARCHITECTURES again --- eng/native/configureplatform.cmake | 24 ++++-------------------- src/coreclr/build-runtime.sh | 24 ++++++++++++++++++++++++ src/coreclr/generate-osx-arm64-layout.sh | 4 +++- 3 files changed, 31 insertions(+), 21 deletions(-) diff --git a/eng/native/configureplatform.cmake b/eng/native/configureplatform.cmake index 7bf600cf6b16a..38294abd3f6ab 100644 --- a/eng/native/configureplatform.cmake +++ b/eng/native/configureplatform.cmake @@ -78,26 +78,10 @@ endif(CLR_CMAKE_HOST_OS STREQUAL Linux) if(CLR_CMAKE_HOST_OS STREQUAL Darwin) set(CLR_CMAKE_HOST_UNIX 1) set(CLR_CMAKE_HOST_OSX 1) - if(CMAKE_SYSTEM_PROCESSOR STREQUAL x86_64) - if(NOT CLR_CROSS_COMPONENTS_BUILD AND CLR_CMAKE_TARGET_ARCH STREQUAL arm64) - set(CLR_CMAKE_HOST_UNIX_ARM64 1) - set(CMAKE_OSX_ARCHITECTURES arm64) - set(OSX_ARCHITECTURES arm64) - else() - set(CLR_CMAKE_HOST_UNIX_AMD64 1) - set(CMAKE_OSX_ARCHITECTURES x86_64) - set(OSX_ARCHITECTURES x86_64) - endif() - elseif(CMAKE_SYSTEM_PROCESSOR STREQUAL arm64) - if(NOT CLR_CROSS_COMPONENTS_BUILD AND CLR_CMAKE_TARGET_ARCH STREQUAL x64) - set(CLR_CMAKE_HOST_UNIX_AMD64 1) - set(CMAKE_OSX_ARCHITECTURES x86_64) - set(OSX_ARCHITECTURES x86_64) - else() - set(CLR_CMAKE_HOST_UNIX_ARM64 1) - set(CMAKE_OSX_ARCHITECTURES arm64) - set(OSX_ARCHITECTURES arm64) - endif() + if(CMAKE_OSX_ARCHITECTURES STREQUAL x86_64) + set(CLR_CMAKE_HOST_UNIX_AMD64 1) + elseif(CMAKE_OSX_ARCHITECTURES STREQUAL arm64) + set(CLR_CMAKE_HOST_UNIX_ARM64 1) else() clr_unknown_arch() endif() diff --git a/src/coreclr/build-runtime.sh b/src/coreclr/build-runtime.sh index 24bb0067380b5..54b56e226da59 100755 --- a/src/coreclr/build-runtime.sh +++ b/src/coreclr/build-runtime.sh @@ -95,6 +95,17 @@ build_cross_architecture_components() export __CMakeBinDir CROSSCOMPILE __CMakeArgs="-DCLR_CMAKE_TARGET_ARCH=$__BuildArch -DCLR_CROSS_COMPONENTS_BUILD=1 $__CMakeArgs" + if [[ "$__TargetOS" == OSX ]]; then + if [[ "$__CrossArch" == x64 ]]; then + __CMakeArgs="-DCMAKE_OSX_ARCHITECTURES=\"x86_64\" $__CMakeArgs" + elif [[ "$__CrossArch" == arm64 ]]; then + __CMakeArgs="-DCMAKE_OSX_ARCHITECTURES=\"arm64\" $__CMakeArgs" + else + echo "Error: Unknown OSX architecture $__BuildArch." + exit 1 + fi + fi + build_native "$__CrossArch" "$__ProjectRoot" "$__ProjectRoot" "$intermediatesForBuild" "cross-architecture components" CROSSCOMPILE=1 @@ -234,6 +245,19 @@ if [[ "$__SkipConfigure" == 0 && "$__CodeCoverage" == 1 ]]; then __CMakeArgs="-DCLR_CMAKE_ENABLE_CODE_COVERAGE=1 $__CMakeArgs" fi +if [[ "$__TargetOS" == OSX ]]; then + # set default OSX deployment target + __CMakeArgs="-DCMAKE_OSX_DEPLOYMENT_TARGET=10.13 $__CMakeArgs" + if [[ "$__BuildArch" == x64 ]]; then + __CMakeArgs="-DCMAKE_OSX_ARCHITECTURES=\"x86_64\" $__CMakeArgs" + elif [[ "$__BuildArch" == arm64 ]]; then + __CMakeArgs="-DCMAKE_OSX_ARCHITECTURES=\"arm64\" $__CMakeArgs" + else + echo "Error: Unknown OSX architecture $__BuildArch." + exit 1 + fi +fi + if [[ "$__SkipNative" == 1 ]]; then echo "Skipping CoreCLR component build." else diff --git a/src/coreclr/generate-osx-arm64-layout.sh b/src/coreclr/generate-osx-arm64-layout.sh index abbedf107ea13..d645b154c12c7 100755 --- a/src/coreclr/generate-osx-arm64-layout.sh +++ b/src/coreclr/generate-osx-arm64-layout.sh @@ -22,7 +22,9 @@ done RepoRoot="$( cd -P "$( dirname "$source" )/../.." && pwd )" Core_Root=${RepoRoot}/artifacts/tests/coreclr/OSX.arm64.Debug/Tests/Core_Root -Arm64_Native_Paths="${RepoRoot}/artifacts/bin/coreclr/OSX.arm64.Debug ${RepoRoot}/artifacts/bin/native/OSX-arm64-Debug" +Arm64_Native_Obj_Paths="${RepoRoot}/artifacts/obj/coreclr/OSX.arm64.Debug ${RepoRoot}/artifacts/obj/native/OSX-arm64-Debug" +Arm64_Native_Bin_Paths="${RepoRoot}/artifacts/bin/coreclr/OSX.arm64.Debug ${RepoRoot}/artifacts/bin/native/OSX-arm64-Debug" +Arm64_Native_Paths="${Arm64_Native_Obj_Paths} ${Arm64_Native_Bin_Paths}" Arm64_SPC_Path=${RepoRoot}/artifacts/bin/coreclr/OSX.arm64.Debug/IL function x64NativeFiles() From 8b4fd1ff32d5fe6eed24a65cf2d0df10e752ad5a Mon Sep 17 00:00:00 2001 From: Steve MacLean Date: Tue, 25 Aug 2020 20:10:01 -0700 Subject: [PATCH 40/89] Set clang -arch flag --- eng/native/configurecompiler.cmake | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/eng/native/configurecompiler.cmake b/eng/native/configurecompiler.cmake index bffb794197548..ca0c5422ded19 100644 --- a/eng/native/configurecompiler.cmake +++ b/eng/native/configurecompiler.cmake @@ -371,8 +371,12 @@ if (CLR_CMAKE_HOST_UNIX) if(CLR_CMAKE_HOST_ARCH_ARM64) # 'pthread_jit_write_protect_np' is only available on macOS 11.0 or newer set(MACOS_VERSION_MIN_FLAGS -mmacosx-version-min=11.0) - else() + add_compile_options(-arch arm64) + elseif(CLR_CMAKE_HOST_ARCH_X64) set(MACOS_VERSION_MIN_FLAGS -mmacosx-version-min=10.12) + add_compile_options(-arch x86_64) + else() + clr_unknown_arch() endif() add_compile_options(${MACOS_VERSION_MIN_FLAGS}) add_linker_flag(${MACOS_VERSION_MIN_FLAGS}) From e48b63b9c56edfacd353c00a9055a207d9c1eb39 Mon Sep 17 00:00:00 2001 From: Steve MacLean Date: Tue, 25 Aug 2020 22:10:43 -0700 Subject: [PATCH 41/89] Remove workarounds from generate-osx-arm64-layout.sh --- src/coreclr/generate-osx-arm64-layout.sh | 35 ++---------------------- 1 file changed, 2 insertions(+), 33 deletions(-) diff --git a/src/coreclr/generate-osx-arm64-layout.sh b/src/coreclr/generate-osx-arm64-layout.sh index d645b154c12c7..51682d50b2620 100755 --- a/src/coreclr/generate-osx-arm64-layout.sh +++ b/src/coreclr/generate-osx-arm64-layout.sh @@ -22,10 +22,6 @@ done RepoRoot="$( cd -P "$( dirname "$source" )/../.." && pwd )" Core_Root=${RepoRoot}/artifacts/tests/coreclr/OSX.arm64.Debug/Tests/Core_Root -Arm64_Native_Obj_Paths="${RepoRoot}/artifacts/obj/coreclr/OSX.arm64.Debug ${RepoRoot}/artifacts/obj/native/OSX-arm64-Debug" -Arm64_Native_Bin_Paths="${RepoRoot}/artifacts/bin/coreclr/OSX.arm64.Debug ${RepoRoot}/artifacts/bin/native/OSX-arm64-Debug" -Arm64_Native_Paths="${Arm64_Native_Obj_Paths} ${Arm64_Native_Bin_Paths}" -Arm64_SPC_Path=${RepoRoot}/artifacts/bin/coreclr/OSX.arm64.Debug/IL function x64NativeFiles() { @@ -35,37 +31,10 @@ function x64NativeFiles() done } -# Remove any arm64 native files which were built with x86_64 architecture -for n in $(find ${Arm64_Native_Paths} -type f) -do - (file $n | grep -q x86_64) && rm $n -done - -# Rebuild native arm64 files -${RepoRoot}/src/libraries/Native/build-native.sh -arm64 -${RepoRoot}/src/coreclr/build-runtime.sh -arm64 - ${RepoRoot}/src/coreclr/build-test.sh arm64 generatelayoutonly /p:LibrariesConfiguration=Debug -# Copy arm64 IL S.P.C.dll -cp ${Arm64_SPC_Path}/System.Private.CoreLib.dll ${Core_Root} - -# Replace osx-x64 native files with their arm64 counterparts -for i in $(x64NativeFiles) -do - echo - echo $i - for n in $(find ${Arm64_Native_Paths} -name $(basename $i)) - do - (file $n | grep -q x86_64) || (md5 $n; cp $n $i) - done -done 2>&1 - -echo - -# Remove any residual osx-x64 native files +# Warn for any residual osx-x64 native files for i in $(x64NativeFiles) do - echo Removing native x86_64 file $i - rm $i + echo Warning native x86_64 file $i done 2>&1 From 1a87f7d5361b8e117bfa32b95683ec85567c98ae Mon Sep 17 00:00:00 2001 From: Steve MacLean Date: Tue, 25 Aug 2020 22:11:59 -0700 Subject: [PATCH 42/89] Remove generate-osx-arm64-layout.sh --- src/coreclr/generate-osx-arm64-layout.sh | 40 ------------------------ 1 file changed, 40 deletions(-) delete mode 100755 src/coreclr/generate-osx-arm64-layout.sh diff --git a/src/coreclr/generate-osx-arm64-layout.sh b/src/coreclr/generate-osx-arm64-layout.sh deleted file mode 100755 index 51682d50b2620..0000000000000 --- a/src/coreclr/generate-osx-arm64-layout.sh +++ /dev/null @@ -1,40 +0,0 @@ -#! /bin/bash - -# This is a simple and currently crude script to generate an osx-arm64 Core_Root -# It works around issues with native files being built and/or included with the wrong arch - -# ToDo -# Error checking!!! -# Options ... build config!!! - -source="${BASH_SOURCE[0]}" - -# resolve $SOURCE until the file is no longer a symlink -while [[ -h $source ]]; do - scriptroot="$( cd -P "$( dirname "$source" )" && pwd )" - source="$(readlink "$source")" - - # if $source was a relative symlink, we need to resolve it relative to the path where the - # symlink file was located - [[ $source != /* ]] && source="$scriptroot/$source" -done - -RepoRoot="$( cd -P "$( dirname "$source" )/../.." && pwd )" - -Core_Root=${RepoRoot}/artifacts/tests/coreclr/OSX.arm64.Debug/Tests/Core_Root - -function x64NativeFiles() -{ - for i in $(find ${Core_Root} -type f) - do - (file $i | grep -q x86_64) && echo $i - done -} - -${RepoRoot}/src/coreclr/build-test.sh arm64 generatelayoutonly /p:LibrariesConfiguration=Debug - -# Warn for any residual osx-x64 native files -for i in $(x64NativeFiles) -do - echo Warning native x86_64 file $i -done 2>&1 From 79ee527f97c0bbecdd6b4f272b6d9e6ed1112bc3 Mon Sep 17 00:00:00 2001 From: Steve MacLean Date: Wed, 26 Aug 2020 02:45:38 -0700 Subject: [PATCH 43/89] More CMAKE_OSX_ARCH rework --- src/coreclr/build-runtime.sh | 2 -- src/coreclr/build-test.sh | 11 +++++++++++ 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/src/coreclr/build-runtime.sh b/src/coreclr/build-runtime.sh index 54b56e226da59..77f0fc58d9daa 100755 --- a/src/coreclr/build-runtime.sh +++ b/src/coreclr/build-runtime.sh @@ -246,8 +246,6 @@ if [[ "$__SkipConfigure" == 0 && "$__CodeCoverage" == 1 ]]; then fi if [[ "$__TargetOS" == OSX ]]; then - # set default OSX deployment target - __CMakeArgs="-DCMAKE_OSX_DEPLOYMENT_TARGET=10.13 $__CMakeArgs" if [[ "$__BuildArch" == x64 ]]; then __CMakeArgs="-DCMAKE_OSX_ARCHITECTURES=\"x86_64\" $__CMakeArgs" elif [[ "$__BuildArch" == arm64 ]]; then diff --git a/src/coreclr/build-test.sh b/src/coreclr/build-test.sh index b67fbef45f92a..71ed478b2cfee 100755 --- a/src/coreclr/build-test.sh +++ b/src/coreclr/build-test.sh @@ -369,6 +369,17 @@ build_Tests() fi if [[ "$__SkipNative" != 1 ]]; then + if [[ "$__TargetOS" == OSX ]]; then + if [[ "$__BuildArch" == x64 ]]; then + __CMakeArgs="-DCMAKE_OSX_ARCHITECTURES=\"x86_64\" $__CMakeArgs" + elif [[ "$__BuildArch" == arm64 ]]; then + __CMakeArgs="-DCMAKE_OSX_ARCHITECTURES=\"arm64\" $__CMakeArgs" + else + echo "Error: Unknown OSX architecture $__BuildArch." + exit 1 + fi + fi + build_native "$__BuildArch" "$__TestDir" "$__ProjectRoot" "$__NativeTestIntermediatesDir" "CoreCLR test component" if [[ "$?" -ne 0 ]]; then From 9d2d5dd8d5a1e0f94302c5d04064723425be62a9 Mon Sep 17 00:00:00 2001 From: Steve MacLean Date: Wed, 26 Aug 2020 02:46:23 -0700 Subject: [PATCH 44/89] Handle osx-arm64 uname parsing --- src/coreclr/tests/runtest.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/coreclr/tests/runtest.sh b/src/coreclr/tests/runtest.sh index a157f601724a7..fe64b0a151988 100755 --- a/src/coreclr/tests/runtest.sh +++ b/src/coreclr/tests/runtest.sh @@ -87,7 +87,7 @@ function check_cpu_architecture { armv7l) __arch=arm ;; - aarch64) + aarch64|arm64) __arch=arm64 ;; *) From ab869de184f65e71363f105adbbccded5b654763 Mon Sep 17 00:00:00 2001 From: Steve MacLean Date: Wed, 26 Aug 2020 11:27:45 -0700 Subject: [PATCH 45/89] Fix arm64/stubs.cpp W^X --- src/coreclr/src/vm/arm64/stubs.cpp | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/src/coreclr/src/vm/arm64/stubs.cpp b/src/coreclr/src/vm/arm64/stubs.cpp index 47b7387bb081c..2c9d373d60316 100644 --- a/src/coreclr/src/vm/arm64/stubs.cpp +++ b/src/coreclr/src/vm/arm64/stubs.cpp @@ -1220,6 +1220,9 @@ UMEntryThunk * UMEntryThunk::Decode(void *pCallback) void UMEntryThunkCode::Encode(BYTE* pTargetCode, void* pvSecretParam) { +#if defined(HOST_OSX) && defined(HOST_ARM64) + bool jitWriteEnabled = PAL_JITWriteEnable(true); +#endif // defined(HOST_OSX) && defined(HOST_ARM64) // adr x12, _label // ldp x16, x12, [x12] // br x16 @@ -1236,6 +1239,9 @@ void UMEntryThunkCode::Encode(BYTE* pTargetCode, void* pvSecretParam) m_pTargetCode = (TADDR)pTargetCode; m_pvSecretParam = (TADDR)pvSecretParam; +#if defined(HOST_OSX) && defined(HOST_ARM64) + PAL_JITWriteEnable(jitWriteEnabled); +#endif // defined(HOST_OSX) && defined(HOST_ARM64) FlushInstructionCache(GetCurrentProcess(),&m_code,sizeof(m_code)); } @@ -1243,11 +1249,18 @@ void UMEntryThunkCode::Encode(BYTE* pTargetCode, void* pvSecretParam) void UMEntryThunkCode::Poison() { +#if defined(HOST_OSX) && defined(HOST_ARM64) + bool jitWriteEnabled = PAL_JITWriteEnable(true); +#endif // defined(HOST_OSX) && defined(HOST_ARM64) + m_pTargetCode = (TADDR)UMEntryThunk::ReportViolation; // ldp x16, x0, [x12] m_code[1] = 0xa9400190; +#if defined(HOST_OSX) && defined(HOST_ARM64) + PAL_JITWriteEnable(jitWriteEnabled); +#endif // defined(HOST_OSX) && defined(HOST_ARM64) ClrFlushInstructionCache(&m_code,sizeof(m_code)); } @@ -1826,6 +1839,21 @@ void StubLinkerCPU::EmitCallManagedMethod(MethodDesc *pMD, BOOL fTailCall) #define DYNAMIC_HELPER_ALIGNMENT sizeof(TADDR) +#if defined(HOST_OSX) && defined(HOST_ARM64) +#define BEGIN_DYNAMIC_HELPER_EMIT(size) \ + SIZE_T cb = size; \ + SIZE_T cbAligned = ALIGN_UP(cb, DYNAMIC_HELPER_ALIGNMENT); \ + BYTE * pStart = (BYTE *)(void *)pAllocator->GetDynamicHelpersHeap()->AllocAlignedMem(cbAligned, DYNAMIC_HELPER_ALIGNMENT); \ + BYTE * p = pStart; \ + bool jitWriteEnabled = PAL_JITWriteEnable(true); + +#define END_DYNAMIC_HELPER_EMIT() \ + _ASSERTE(pStart + cb == p); \ + while (p < pStart + cbAligned) { *(DWORD*)p = 0xBADC0DF0; p += 4; }\ + PAL_JITWriteEnable(jitWriteEnabled); \ + ClrFlushInstructionCache(pStart, cbAligned); \ + return (PCODE)pStart +#else // defined(HOST_OSX) && defined(HOST_ARM64) #define BEGIN_DYNAMIC_HELPER_EMIT(size) \ SIZE_T cb = size; \ SIZE_T cbAligned = ALIGN_UP(cb, DYNAMIC_HELPER_ALIGNMENT); \ @@ -1837,6 +1865,7 @@ void StubLinkerCPU::EmitCallManagedMethod(MethodDesc *pMD, BOOL fTailCall) while (p < pStart + cbAligned) { *(DWORD*)p = 0xBADC0DF0; p += 4; }\ ClrFlushInstructionCache(pStart, cbAligned); \ return (PCODE)pStart +#endif // defined(HOST_OSX) && defined(HOST_ARM64) // Uses x8 as scratch register to store address of data label // After load x8 is increment to point to next data From 45788c52e247972abb24d2af7fa234f43a4936df Mon Sep 17 00:00:00 2001 From: Steve MacLean Date: Wed, 26 Aug 2020 13:29:51 -0700 Subject: [PATCH 46/89] Fix TheUMEntryPrestubWorker --- src/coreclr/src/vm/dllimportcallback.cpp | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/coreclr/src/vm/dllimportcallback.cpp b/src/coreclr/src/vm/dllimportcallback.cpp index c3c69ddbf3488..852e8c6fd5cee 100644 --- a/src/coreclr/src/vm/dllimportcallback.cpp +++ b/src/coreclr/src/vm/dllimportcallback.cpp @@ -1034,8 +1034,16 @@ PCODE TheUMEntryPrestubWorker(UMEntryThunk * pUMEntryThunk) if (pThread->IsAbortRequested()) pThread->HandleThreadAbort(); +#if defined(HOST_OSX) && defined(HOST_ARM64) + bool jitWriteEnabled = PAL_JITWriteEnable(true); +#endif // defined(HOST_OSX) && defined(HOST_ARM64) + UMEntryThunk::DoRunTimeInit(pUMEntryThunk); +#if defined(HOST_OSX) && defined(HOST_ARM64) + PAL_JITWriteEnable(jitWriteEnabled); +#endif // defined(HOST_OSX) && defined(HOST_ARM64) + return (PCODE)pUMEntryThunk->GetCode(); } From 5440278283c7299e9a7e035a2ae4be51a23edc98 Mon Sep 17 00:00:00 2001 From: Steve MacLean Date: Thu, 27 Aug 2020 08:35:25 -0700 Subject: [PATCH 47/89] Fix GetCapturedRegister --- src/coreclr/src/vm/gcinfodecoder.cpp | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/src/coreclr/src/vm/gcinfodecoder.cpp b/src/coreclr/src/vm/gcinfodecoder.cpp index ac28d049891e0..1e8f2e86f2936 100644 --- a/src/coreclr/src/vm/gcinfodecoder.cpp +++ b/src/coreclr/src/vm/gcinfodecoder.cpp @@ -1686,7 +1686,17 @@ OBJECTREF* GcInfoDecoder::GetCapturedRegister( PREGDISPLAY pRD ) { - _ASSERTE(regNum >= 0 && regNum <= 28); + _ASSERTE(regNum >= 0 && regNum <= 30); + _ASSERTE(regNum != 18); + + if(regNum == 29) + { + return (OBJECTREF*) &pRD->pCurrentContext->Fp; + } + else if(regNum == 30) + { + return (OBJECTREF*) &pRD->pCurrentContext->Lr; + } // The fields of CONTEXT are in the same order as // the processor encoding numbers. From 8015a0ce0934c47a43d523afe5b336ee921dc069 Mon Sep 17 00:00:00 2001 From: Steve MacLean Date: Thu, 27 Aug 2020 08:47:47 -0700 Subject: [PATCH 48/89] Revert "Fix TheUMEntryPrestubWorker" This reverts commit 45788c52e247972abb24d2af7fa234f43a4936df. --- src/coreclr/src/vm/dllimportcallback.cpp | 8 -------- 1 file changed, 8 deletions(-) diff --git a/src/coreclr/src/vm/dllimportcallback.cpp b/src/coreclr/src/vm/dllimportcallback.cpp index 852e8c6fd5cee..c3c69ddbf3488 100644 --- a/src/coreclr/src/vm/dllimportcallback.cpp +++ b/src/coreclr/src/vm/dllimportcallback.cpp @@ -1034,16 +1034,8 @@ PCODE TheUMEntryPrestubWorker(UMEntryThunk * pUMEntryThunk) if (pThread->IsAbortRequested()) pThread->HandleThreadAbort(); -#if defined(HOST_OSX) && defined(HOST_ARM64) - bool jitWriteEnabled = PAL_JITWriteEnable(true); -#endif // defined(HOST_OSX) && defined(HOST_ARM64) - UMEntryThunk::DoRunTimeInit(pUMEntryThunk); -#if defined(HOST_OSX) && defined(HOST_ARM64) - PAL_JITWriteEnable(jitWriteEnabled); -#endif // defined(HOST_OSX) && defined(HOST_ARM64) - return (PCODE)pUMEntryThunk->GetCode(); } From 389c9cb6ff7b51d44933a36c9ece34a2bc803c42 Mon Sep 17 00:00:00 2001 From: Steve MacLean Date: Thu, 27 Aug 2020 09:30:50 -0700 Subject: [PATCH 49/89] Fix kRunTimeInited write --- src/coreclr/src/vm/dllimportcallback.h | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/src/coreclr/src/vm/dllimportcallback.h b/src/coreclr/src/vm/dllimportcallback.h index 5ee382eed26d6..edb198c3c36c9 100644 --- a/src/coreclr/src/vm/dllimportcallback.h +++ b/src/coreclr/src/vm/dllimportcallback.h @@ -305,8 +305,16 @@ class UMEntryThunk m_code.Encode((BYTE*)m_pUMThunkMarshInfo->GetExecStubEntryPoint(), this); #ifdef _DEBUG +#if defined(HOST_OSX) && defined(HOST_ARM64) + bool jitWriteEnabled = PAL_JITWriteEnable(true); +#endif // defined(HOST_OSX) && defined(HOST_ARM64) + m_state = kRunTimeInited; -#endif + +#if defined(HOST_OSX) && defined(HOST_ARM64) + PAL_JITWriteEnable(jitWriteEnabled); +#endif // defined(HOST_OSX) && defined(HOST_ARM64) +#endif // _DEBUG } // asm entrypoint From af4db134ddd9deea10e75d3f732cc35d3b61119e Mon Sep 17 00:00:00 2001 From: Steve MacLean Date: Thu, 27 Aug 2020 14:34:09 -0700 Subject: [PATCH 50/89] Fix more W^X issues --- src/coreclr/src/vm/arm64/stubs.cpp | 16 ++++++++++++++++ src/coreclr/src/vm/codeman.cpp | 16 ++++++++++++++++ src/coreclr/src/vm/comdelegate.cpp | 17 +++++++++++++++++ 3 files changed, 49 insertions(+) diff --git a/src/coreclr/src/vm/arm64/stubs.cpp b/src/coreclr/src/vm/arm64/stubs.cpp index 2c9d373d60316..5604541cb9f4d 100644 --- a/src/coreclr/src/vm/arm64/stubs.cpp +++ b/src/coreclr/src/vm/arm64/stubs.cpp @@ -569,6 +569,10 @@ void StubPrecode::Init(MethodDesc* pMD, LoaderAllocator *pLoaderAllocator) { WRAPPER_NO_CONTRACT; +#if defined(HOST_OSX) && defined(HOST_ARM64) + bool jitWriteEnabled = PAL_JITWriteEnable(true); +#endif // defined(HOST_OSX) && defined(HOST_ARM64) + int n = 0; m_rgCode[n++] = 0x10000089; // adr x9, #16 @@ -579,6 +583,10 @@ void StubPrecode::Init(MethodDesc* pMD, LoaderAllocator *pLoaderAllocator) m_pTarget = GetPreStubEntryPoint(); m_pMethodDesc = (TADDR)pMD; + +#if defined(HOST_OSX) && defined(HOST_ARM64) + PAL_JITWriteEnable(jitWriteEnabled); +#endif // defined(HOST_OSX) && defined(HOST_ARM64) } #ifdef FEATURE_NATIVE_IMAGE_GENERATION @@ -602,6 +610,10 @@ void NDirectImportPrecode::Init(MethodDesc* pMD, LoaderAllocator *pLoaderAllocat { WRAPPER_NO_CONTRACT; +#if defined(HOST_OSX) && defined(HOST_ARM64) + bool jitWriteEnabled = PAL_JITWriteEnable(true); +#endif // defined(HOST_OSX) && defined(HOST_ARM64) + int n = 0; m_rgCode[n++] = 0x1000008B; // adr x11, #16 @@ -612,6 +624,10 @@ void NDirectImportPrecode::Init(MethodDesc* pMD, LoaderAllocator *pLoaderAllocat m_pTarget = GetEEFuncEntryPoint(NDirectImportThunk); m_pMethodDesc = (TADDR)pMD; + +#if defined(HOST_OSX) && defined(HOST_ARM64) + PAL_JITWriteEnable(jitWriteEnabled); +#endif // defined(HOST_OSX) && defined(HOST_ARM64) } #ifdef FEATURE_NATIVE_IMAGE_GENERATION diff --git a/src/coreclr/src/vm/codeman.cpp b/src/coreclr/src/vm/codeman.cpp index 0887cfdcdc1eb..8a243beb69fb5 100644 --- a/src/coreclr/src/vm/codeman.cpp +++ b/src/coreclr/src/vm/codeman.cpp @@ -1917,6 +1917,10 @@ void CodeFragmentHeap::RealBackoutMem(void *pMem _ASSERTE(dwSize >= sizeof(FreeBlock)); +#if defined(HOST_OSX) && defined(HOST_ARM64) + bool jitWriteEnabled = PAL_JITWriteEnable(true); +#endif // defined(HOST_OSX) && defined(HOST_ARM64) + ZeroMemory((BYTE *)pMem, dwSize); // @@ -1947,6 +1951,10 @@ void CodeFragmentHeap::RealBackoutMem(void *pMem } AddBlock(pMem, dwSize); + +#if defined(HOST_OSX) && defined(HOST_ARM64) + PAL_JITWriteEnable(jitWriteEnabled); +#endif // defined(HOST_OSX) && defined(HOST_ARM64) } #endif // !CROSSGEN_COMPILE @@ -4831,6 +4839,10 @@ void ExecutionManager::Unload(LoaderAllocator *pLoaderAllocator) GC_NOTRIGGER; } CONTRACTL_END; +#if defined(HOST_OSX) && defined(HOST_ARM64) + bool jitWriteEnabled = PAL_JITWriteEnable(true); +#endif // defined(HOST_OSX) && defined(HOST_ARM64) + // a size of 0 is a signal to Nirvana to flush the entire cache FlushInstructionCache(GetCurrentProcess(),0,0); @@ -4850,6 +4862,10 @@ void ExecutionManager::Unload(LoaderAllocator *pLoaderAllocator) } GetEEJitManager()->Unload(pLoaderAllocator); + +#if defined(HOST_OSX) && defined(HOST_ARM64) + PAL_JITWriteEnable(jitWriteEnabled); +#endif // defined(HOST_OSX) && defined(HOST_ARM64) } // This method is used by the JIT and the runtime for PreStubs. It will return diff --git a/src/coreclr/src/vm/comdelegate.cpp b/src/coreclr/src/vm/comdelegate.cpp index 9c5b48cc8ce73..e330d60ff81e6 100644 --- a/src/coreclr/src/vm/comdelegate.cpp +++ b/src/coreclr/src/vm/comdelegate.cpp @@ -969,12 +969,20 @@ FCIMPL5(FC_BOOL_RET, COMDelegate::BindToMethodInfo, Object* refThisUNSAFE, Objec flags, &fIsOpenDelegate)) { +#if defined(HOST_OSX) && defined(HOST_ARM64) + bool jitWriteEnabled = PAL_JITWriteEnable(true); +#endif // defined(HOST_OSX) && defined(HOST_ARM64) + // Initialize the delegate to point to the target method. BindToMethod(&gc.refThis, &gc.refFirstArg, method, pMethMT, fIsOpenDelegate); + +#if defined(HOST_OSX) && defined(HOST_ARM64) + PAL_JITWriteEnable(jitWriteEnabled); +#endif // defined(HOST_OSX) && defined(HOST_ARM64) } else result = FALSE; @@ -1588,6 +1596,10 @@ FCIMPL3(void, COMDelegate::DelegateConstruct, Object* refThisUNSAFE, Object* tar // try to catch the easy garbage. _ASSERTE(isMemoryReadable(method, 1)); +#if defined(HOST_OSX) && defined(HOST_ARM64) + bool jitWriteEnabled = PAL_JITWriteEnable(true); +#endif // defined(HOST_OSX) && defined(HOST_ARM64) + MethodTable *pMTTarg = NULL; if (gc.target != NULL) @@ -1717,6 +1729,11 @@ FCIMPL3(void, COMDelegate::DelegateConstruct, Object* refThisUNSAFE, Object* tar gc.refThis->SetTarget(gc.target); gc.refThis->SetMethodPtr((PCODE)(void *)method); } + +#if defined(HOST_OSX) && defined(HOST_ARM64) + PAL_JITWriteEnable(jitWriteEnabled); +#endif // defined(HOST_OSX) && defined(HOST_ARM64) + HELPER_METHOD_FRAME_END(); } FCIMPLEND From 49eb289210c2097aed15560b4b000b3e64bc5f66 Mon Sep 17 00:00:00 2001 From: Steve MacLean Date: Mon, 31 Aug 2020 15:54:37 -0700 Subject: [PATCH 51/89] Add/use PAL_JITWriteEnableHolder --- src/coreclr/src/inc/loaderheap.h | 12 +----- src/coreclr/src/pal/inc/pal.h | 28 +++++++++++-- src/coreclr/src/pal/src/map/virtual.cpp | 3 +- src/coreclr/src/utilcode/loaderheap.cpp | 10 +---- src/coreclr/src/vm/arm64/stubs.cpp | 39 ++++--------------- src/coreclr/src/vm/callcounting.cpp | 6 +-- src/coreclr/src/vm/callhelpers.cpp | 6 +-- src/coreclr/src/vm/codeman.cpp | 17 ++------ src/coreclr/src/vm/comdelegate.cpp | 12 +----- src/coreclr/src/vm/dllimportcallback.h | 11 +----- .../src/vm/methoddescbackpatchinfo.cpp | 5 +-- src/coreclr/src/vm/precode.cpp | 12 +----- src/coreclr/src/vm/prestub.cpp | 12 +----- src/coreclr/src/vm/threads.cpp | 6 +-- src/coreclr/src/vm/virtualcallstub.cpp | 12 +----- 15 files changed, 53 insertions(+), 138 deletions(-) diff --git a/src/coreclr/src/inc/loaderheap.h b/src/coreclr/src/inc/loaderheap.h index 8ce81fb4d7388..68d50f6d637d3 100644 --- a/src/coreclr/src/inc/loaderheap.h +++ b/src/coreclr/src/inc/loaderheap.h @@ -550,7 +550,7 @@ class LoaderHeap : public UnlockedLoaderHeap, public ILoaderHeapBackout WRAPPER_NO_CONTRACT; #if defined(HOST_OSX) && defined(HOST_ARM64) - bool jitWriteEnabled = PAL_JITWriteEnable(true); + auto jitWriteEnableHolder = PAL_JITWriteEnable(true); #endif // defined(HOST_OSX) && defined(HOST_ARM64) void *pResult; @@ -572,10 +572,6 @@ class LoaderHeap : public UnlockedLoaderHeap, public ILoaderHeapBackout tmap.m_lineNum = lineNum; #endif -#if defined(HOST_OSX) && defined(HOST_ARM64) - PAL_JITWriteEnable(jitWriteEnabled); -#endif // defined(HOST_OSX) && defined(HOST_ARM64) - return tmap; } @@ -634,7 +630,7 @@ class LoaderHeap : public UnlockedLoaderHeap, public ILoaderHeapBackout WRAPPER_NO_CONTRACT; #if defined(HOST_OSX) && defined(HOST_ARM64) - bool jitWriteEnabled = PAL_JITWriteEnable(true); + auto jitWriteEnableHolder = PAL_JITWriteEnable(true); #endif // defined(HOST_OSX) && defined(HOST_ARM64) CRITSEC_Holder csh(m_CriticalSection); @@ -662,10 +658,6 @@ class LoaderHeap : public UnlockedLoaderHeap, public ILoaderHeapBackout tmap.m_lineNum = lineNum; #endif -#if defined(HOST_OSX) && defined(HOST_ARM64) - PAL_JITWriteEnable(jitWriteEnabled); -#endif // defined(HOST_OSX) && defined(HOST_ARM64) - return tmap; } diff --git a/src/coreclr/src/pal/inc/pal.h b/src/coreclr/src/pal/inc/pal.h index 3ca7dc7986f4a..32f9c4f4abf97 100644 --- a/src/coreclr/src/pal/inc/pal.h +++ b/src/coreclr/src/pal/inc/pal.h @@ -2715,10 +2715,30 @@ VirtualFree( IN DWORD dwFreeType); #if defined(HOST_OSX) && defined(HOST_ARM64) -PALIMPORT -bool -PALAPI -PAL_JITWriteEnable(IN bool enable); +#ifdef __cplusplus +extern "C++" { +struct PAL_JITWriteEnableHolder +{ +public: + PAL_JITWriteEnableHolder(bool jitWriteEnable) + { + m_jitWriteEnableRestore = JITWriteEnable(jitWriteEnable); + }; + ~PAL_JITWriteEnableHolder() + { + JITWriteEnable(m_jitWriteEnableRestore); + } + +private: + bool JITWriteEnable(bool enable); + bool m_jitWriteEnableRestore; +}; + +inline +PAL_JITWriteEnableHolder +PAL_JITWriteEnable(IN bool enable) { return PAL_JITWriteEnableHolder(enable); } +} +#endif // __cplusplus #endif // defined(HOST_OSX) && defined(HOST_ARM64) PALIMPORT diff --git a/src/coreclr/src/pal/src/map/virtual.cpp b/src/coreclr/src/pal/src/map/virtual.cpp index 02eee4e503684..75c067554e4bd 100644 --- a/src/coreclr/src/pal/src/map/virtual.cpp +++ b/src/coreclr/src/pal/src/map/virtual.cpp @@ -1762,8 +1762,7 @@ VirtualProtect( #if defined(TARGET_OSX) && defined(TARGET_ARM64) bool -PALAPI -PAL_JITWriteEnable(bool writeEnable) +PAL_JITWriteEnableHolder::JITWriteEnable(bool writeEnable) { // Use a thread local to track per thread JIT Write enable state // Threads start with MAP_JIT pages readable and executable (R-X) by default. diff --git a/src/coreclr/src/utilcode/loaderheap.cpp b/src/coreclr/src/utilcode/loaderheap.cpp index 214f1f7348d82..8cfbba756592c 100644 --- a/src/coreclr/src/utilcode/loaderheap.cpp +++ b/src/coreclr/src/utilcode/loaderheap.cpp @@ -1160,9 +1160,8 @@ BOOL UnlockedLoaderHeap::UnlockedReservePages(size_t dwSizeToCommit) LoaderHeapBlock *pNewBlock; #if defined(HOST_OSX) && defined(HOST_ARM64) - bool jitWriteEnable = false; - if (m_Options & LHF_EXECUTABLE) - jitWriteEnable = PAL_JITWriteEnable(true); + // Always assume we are touching executable heap + auto jitWriteEnableHolder = PAL_JITWriteEnable(true); #endif // defined(HOST_OSX) && defined(HOST_ARM64) pNewBlock = (LoaderHeapBlock *) pData; @@ -1189,11 +1188,6 @@ BOOL UnlockedLoaderHeap::UnlockedReservePages(size_t dwSizeToCommit) SETUP_NEW_BLOCK(pData, dwSizeToCommit, dwSizeToReserve); -#if defined(HOST_OSX) && defined(HOST_ARM64) - if (m_Options & LHF_EXECUTABLE) - PAL_JITWriteEnable(jitWriteEnable); -#endif // defined(HOST_OSX) && defined(HOST_ARM64) - return TRUE; } diff --git a/src/coreclr/src/vm/arm64/stubs.cpp b/src/coreclr/src/vm/arm64/stubs.cpp index 5604541cb9f4d..91a84d2e611e5 100644 --- a/src/coreclr/src/vm/arm64/stubs.cpp +++ b/src/coreclr/src/vm/arm64/stubs.cpp @@ -570,7 +570,7 @@ void StubPrecode::Init(MethodDesc* pMD, LoaderAllocator *pLoaderAllocator) WRAPPER_NO_CONTRACT; #if defined(HOST_OSX) && defined(HOST_ARM64) - bool jitWriteEnabled = PAL_JITWriteEnable(true); + auto jitWriteEnableHolder = PAL_JITWriteEnable(true); #endif // defined(HOST_OSX) && defined(HOST_ARM64) int n = 0; @@ -583,10 +583,6 @@ void StubPrecode::Init(MethodDesc* pMD, LoaderAllocator *pLoaderAllocator) m_pTarget = GetPreStubEntryPoint(); m_pMethodDesc = (TADDR)pMD; - -#if defined(HOST_OSX) && defined(HOST_ARM64) - PAL_JITWriteEnable(jitWriteEnabled); -#endif // defined(HOST_OSX) && defined(HOST_ARM64) } #ifdef FEATURE_NATIVE_IMAGE_GENERATION @@ -611,7 +607,7 @@ void NDirectImportPrecode::Init(MethodDesc* pMD, LoaderAllocator *pLoaderAllocat WRAPPER_NO_CONTRACT; #if defined(HOST_OSX) && defined(HOST_ARM64) - bool jitWriteEnabled = PAL_JITWriteEnable(true); + auto jitWriteEnableHolder = PAL_JITWriteEnable(true); #endif // defined(HOST_OSX) && defined(HOST_ARM64) int n = 0; @@ -624,10 +620,6 @@ void NDirectImportPrecode::Init(MethodDesc* pMD, LoaderAllocator *pLoaderAllocat m_pTarget = GetEEFuncEntryPoint(NDirectImportThunk); m_pMethodDesc = (TADDR)pMD; - -#if defined(HOST_OSX) && defined(HOST_ARM64) - PAL_JITWriteEnable(jitWriteEnabled); -#endif // defined(HOST_OSX) && defined(HOST_ARM64) } #ifdef FEATURE_NATIVE_IMAGE_GENERATION @@ -652,7 +644,7 @@ void FixupPrecode::Init(MethodDesc* pMD, LoaderAllocator *pLoaderAllocator, int WRAPPER_NO_CONTRACT; #if defined(HOST_OSX) && defined(HOST_ARM64) - bool jitWriteEnabled = PAL_JITWriteEnable(true); + auto jitWriteEnableHolder = PAL_JITWriteEnable(true); #endif // defined(HOST_OSX) && defined(HOST_ARM64) InitCommon(); @@ -682,10 +674,6 @@ void FixupPrecode::Init(MethodDesc* pMD, LoaderAllocator *pLoaderAllocator, int { m_pTarget = GetEEFuncEntryPoint(PrecodeFixupThunk); } - -#if defined(HOST_OSX) && defined(HOST_ARM64) - PAL_JITWriteEnable(jitWriteEnabled); -#endif // defined(HOST_OSX) && defined(HOST_ARM64) } #ifdef FEATURE_NATIVE_IMAGE_GENERATION @@ -1085,14 +1073,10 @@ EXTERN_C void JIT_UpdateWriteBarrierState(bool skipEphemeralCheck); static void SafeUpdateWriteBarrierState(bool skipEphemeralCheck) { #if defined(HOST_OSX) && defined(HOST_ARM64) - bool jitWriteEnabled = PAL_JITWriteEnable(true); + auto jitWriteEnableHolder = PAL_JITWriteEnable(true); #endif // defined(HOST_OSX) && defined(HOST_ARM64) JIT_UpdateWriteBarrierState(GCHeapUtilities::IsServerHeap()); - -#if defined(HOST_OSX) && defined(HOST_ARM64) - PAL_JITWriteEnable(jitWriteEnabled); -#endif // defined(HOST_OSX) && defined(HOST_ARM64) } void InitJITHelpers1() @@ -1237,7 +1221,7 @@ UMEntryThunk * UMEntryThunk::Decode(void *pCallback) void UMEntryThunkCode::Encode(BYTE* pTargetCode, void* pvSecretParam) { #if defined(HOST_OSX) && defined(HOST_ARM64) - bool jitWriteEnabled = PAL_JITWriteEnable(true); + auto jitWriteEnableHolder = PAL_JITWriteEnable(true); #endif // defined(HOST_OSX) && defined(HOST_ARM64) // adr x12, _label // ldp x16, x12, [x12] @@ -1254,10 +1238,6 @@ void UMEntryThunkCode::Encode(BYTE* pTargetCode, void* pvSecretParam) m_pTargetCode = (TADDR)pTargetCode; m_pvSecretParam = (TADDR)pvSecretParam; - -#if defined(HOST_OSX) && defined(HOST_ARM64) - PAL_JITWriteEnable(jitWriteEnabled); -#endif // defined(HOST_OSX) && defined(HOST_ARM64) FlushInstructionCache(GetCurrentProcess(),&m_code,sizeof(m_code)); } @@ -1266,17 +1246,13 @@ void UMEntryThunkCode::Encode(BYTE* pTargetCode, void* pvSecretParam) void UMEntryThunkCode::Poison() { #if defined(HOST_OSX) && defined(HOST_ARM64) - bool jitWriteEnabled = PAL_JITWriteEnable(true); + auto jitWriteEnableHolder = PAL_JITWriteEnable(true); #endif // defined(HOST_OSX) && defined(HOST_ARM64) m_pTargetCode = (TADDR)UMEntryThunk::ReportViolation; // ldp x16, x0, [x12] m_code[1] = 0xa9400190; - -#if defined(HOST_OSX) && defined(HOST_ARM64) - PAL_JITWriteEnable(jitWriteEnabled); -#endif // defined(HOST_OSX) && defined(HOST_ARM64) ClrFlushInstructionCache(&m_code,sizeof(m_code)); } @@ -1861,12 +1837,11 @@ void StubLinkerCPU::EmitCallManagedMethod(MethodDesc *pMD, BOOL fTailCall) SIZE_T cbAligned = ALIGN_UP(cb, DYNAMIC_HELPER_ALIGNMENT); \ BYTE * pStart = (BYTE *)(void *)pAllocator->GetDynamicHelpersHeap()->AllocAlignedMem(cbAligned, DYNAMIC_HELPER_ALIGNMENT); \ BYTE * p = pStart; \ - bool jitWriteEnabled = PAL_JITWriteEnable(true); + auto jitWriteEnableHolder = PAL_JITWriteEnable(true); #define END_DYNAMIC_HELPER_EMIT() \ _ASSERTE(pStart + cb == p); \ while (p < pStart + cbAligned) { *(DWORD*)p = 0xBADC0DF0; p += 4; }\ - PAL_JITWriteEnable(jitWriteEnabled); \ ClrFlushInstructionCache(pStart, cbAligned); \ return (PCODE)pStart #else // defined(HOST_OSX) && defined(HOST_ARM64) diff --git a/src/coreclr/src/vm/callcounting.cpp b/src/coreclr/src/vm/callcounting.cpp index dcde53dd71afb..eaf18aaff909b 100644 --- a/src/coreclr/src/vm/callcounting.cpp +++ b/src/coreclr/src/vm/callcounting.cpp @@ -252,7 +252,7 @@ const CallCountingStub *CallCountingManager::CallCountingStubAllocator::Allocate CONTRACTL_END; #if defined(HOST_OSX) && defined(HOST_ARM64) - bool jitWriteEnabled = PAL_JITWriteEnable(true); + auto jitWriteEnableHolder = PAL_JITWriteEnable(true); #endif // defined(HOST_OSX) && defined(HOST_ARM64) LoaderHeap *heap = m_heap; @@ -296,10 +296,6 @@ const CallCountingStub *CallCountingManager::CallCountingStubAllocator::Allocate #endif } while (false); -#if defined(HOST_OSX) && defined(HOST_ARM64) - PAL_JITWriteEnable(jitWriteEnabled); -#endif // defined(HOST_OSX) && defined(HOST_ARM64) - ClrFlushInstructionCache(stub, sizeInBytes); return stub; } diff --git a/src/coreclr/src/vm/callhelpers.cpp b/src/coreclr/src/vm/callhelpers.cpp index 3c736359086c1..492869f1c328f 100644 --- a/src/coreclr/src/vm/callhelpers.cpp +++ b/src/coreclr/src/vm/callhelpers.cpp @@ -63,7 +63,7 @@ void CallDescrWorkerWithHandler( #endif #if defined(HOST_OSX) && defined(HOST_ARM64) - bool jitWriteEnabled = PAL_JITWriteEnable(false); + auto jitWriteEnableHolder = PAL_JITWriteEnable(false); #endif // defined(HOST_OSX) && defined(HOST_ARM64) BEGIN_CALL_TO_MANAGEDEX(fCriticalCall ? EEToManagedCriticalCall : EEToManagedDefault); @@ -71,10 +71,6 @@ void CallDescrWorkerWithHandler( CallDescrWorker(pCallDescrData); END_CALL_TO_MANAGED(); - -#if defined(HOST_OSX) && defined(HOST_ARM64) - PAL_JITWriteEnable(jitWriteEnabled); -#endif // defined(HOST_OSX) && defined(HOST_ARM64) } diff --git a/src/coreclr/src/vm/codeman.cpp b/src/coreclr/src/vm/codeman.cpp index 8a243beb69fb5..6eea4589a8c7d 100644 --- a/src/coreclr/src/vm/codeman.cpp +++ b/src/coreclr/src/vm/codeman.cpp @@ -1830,7 +1830,7 @@ TaggedMemAllocPtr CodeFragmentHeap::RealAllocAlignedMem(size_t dwRequestedSize CrstHolder ch(&m_CritSec); #if defined(HOST_OSX) && defined(HOST_ARM64) - bool jitWriteEnabled = PAL_JITWriteEnable(true); + auto jitWriteEnableHolder = PAL_JITWriteEnable(true); #endif // defined(HOST_OSX) && defined(HOST_ARM64) dwRequestedSize = ALIGN_UP(dwRequestedSize, sizeof(TADDR)); @@ -1897,9 +1897,6 @@ TaggedMemAllocPtr CodeFragmentHeap::RealAllocAlignedMem(size_t dwRequestedSize tmap.m_szFile = szFile; tmap.m_lineNum = lineNum; #endif -#if defined(HOST_OSX) && defined(HOST_ARM64) - PAL_JITWriteEnable(jitWriteEnabled); -#endif // defined(HOST_OSX) && defined(HOST_ARM64) return tmap; } @@ -1918,7 +1915,7 @@ void CodeFragmentHeap::RealBackoutMem(void *pMem _ASSERTE(dwSize >= sizeof(FreeBlock)); #if defined(HOST_OSX) && defined(HOST_ARM64) - bool jitWriteEnabled = PAL_JITWriteEnable(true); + auto jitWriteEnableHolder = PAL_JITWriteEnable(true); #endif // defined(HOST_OSX) && defined(HOST_ARM64) ZeroMemory((BYTE *)pMem, dwSize); @@ -1951,10 +1948,6 @@ void CodeFragmentHeap::RealBackoutMem(void *pMem } AddBlock(pMem, dwSize); - -#if defined(HOST_OSX) && defined(HOST_ARM64) - PAL_JITWriteEnable(jitWriteEnabled); -#endif // defined(HOST_OSX) && defined(HOST_ARM64) } #endif // !CROSSGEN_COMPILE @@ -4840,7 +4833,7 @@ void ExecutionManager::Unload(LoaderAllocator *pLoaderAllocator) } CONTRACTL_END; #if defined(HOST_OSX) && defined(HOST_ARM64) - bool jitWriteEnabled = PAL_JITWriteEnable(true); + auto jitWriteEnableHolder = PAL_JITWriteEnable(true); #endif // defined(HOST_OSX) && defined(HOST_ARM64) // a size of 0 is a signal to Nirvana to flush the entire cache @@ -4862,10 +4855,6 @@ void ExecutionManager::Unload(LoaderAllocator *pLoaderAllocator) } GetEEJitManager()->Unload(pLoaderAllocator); - -#if defined(HOST_OSX) && defined(HOST_ARM64) - PAL_JITWriteEnable(jitWriteEnabled); -#endif // defined(HOST_OSX) && defined(HOST_ARM64) } // This method is used by the JIT and the runtime for PreStubs. It will return diff --git a/src/coreclr/src/vm/comdelegate.cpp b/src/coreclr/src/vm/comdelegate.cpp index e330d60ff81e6..5f12dc5fa0ce8 100644 --- a/src/coreclr/src/vm/comdelegate.cpp +++ b/src/coreclr/src/vm/comdelegate.cpp @@ -970,7 +970,7 @@ FCIMPL5(FC_BOOL_RET, COMDelegate::BindToMethodInfo, Object* refThisUNSAFE, Objec &fIsOpenDelegate)) { #if defined(HOST_OSX) && defined(HOST_ARM64) - bool jitWriteEnabled = PAL_JITWriteEnable(true); + auto jitWriteEnableHolder = PAL_JITWriteEnable(true); #endif // defined(HOST_OSX) && defined(HOST_ARM64) // Initialize the delegate to point to the target method. @@ -979,10 +979,6 @@ FCIMPL5(FC_BOOL_RET, COMDelegate::BindToMethodInfo, Object* refThisUNSAFE, Objec method, pMethMT, fIsOpenDelegate); - -#if defined(HOST_OSX) && defined(HOST_ARM64) - PAL_JITWriteEnable(jitWriteEnabled); -#endif // defined(HOST_OSX) && defined(HOST_ARM64) } else result = FALSE; @@ -1597,7 +1593,7 @@ FCIMPL3(void, COMDelegate::DelegateConstruct, Object* refThisUNSAFE, Object* tar _ASSERTE(isMemoryReadable(method, 1)); #if defined(HOST_OSX) && defined(HOST_ARM64) - bool jitWriteEnabled = PAL_JITWriteEnable(true); + auto jitWriteEnableHolder = PAL_JITWriteEnable(true); #endif // defined(HOST_OSX) && defined(HOST_ARM64) MethodTable *pMTTarg = NULL; @@ -1730,10 +1726,6 @@ FCIMPL3(void, COMDelegate::DelegateConstruct, Object* refThisUNSAFE, Object* tar gc.refThis->SetMethodPtr((PCODE)(void *)method); } -#if defined(HOST_OSX) && defined(HOST_ARM64) - PAL_JITWriteEnable(jitWriteEnabled); -#endif // defined(HOST_OSX) && defined(HOST_ARM64) - HELPER_METHOD_FRAME_END(); } FCIMPLEND diff --git a/src/coreclr/src/vm/dllimportcallback.h b/src/coreclr/src/vm/dllimportcallback.h index edb198c3c36c9..8a483808d3d28 100644 --- a/src/coreclr/src/vm/dllimportcallback.h +++ b/src/coreclr/src/vm/dllimportcallback.h @@ -268,7 +268,7 @@ class UMEntryThunk CONTRACTL_END; #if defined(HOST_OSX) && defined(HOST_ARM64) - bool jitWriteEnabled = PAL_JITWriteEnable(true); + auto jitWriteEnableHolder = PAL_JITWriteEnable(true); #endif // defined(HOST_OSX) && defined(HOST_ARM64) m_pManagedTarget = pManagedTarget; @@ -282,9 +282,6 @@ class UMEntryThunk #ifdef _DEBUG m_state = kLoadTimeInited; #endif -#if defined(HOST_OSX) && defined(HOST_ARM64) - PAL_JITWriteEnable(jitWriteEnabled); -#endif // defined(HOST_OSX) && defined(HOST_ARM64) } void Terminate(); @@ -306,14 +303,10 @@ class UMEntryThunk #ifdef _DEBUG #if defined(HOST_OSX) && defined(HOST_ARM64) - bool jitWriteEnabled = PAL_JITWriteEnable(true); + auto jitWriteEnableHolder = PAL_JITWriteEnable(true); #endif // defined(HOST_OSX) && defined(HOST_ARM64) m_state = kRunTimeInited; - -#if defined(HOST_OSX) && defined(HOST_ARM64) - PAL_JITWriteEnable(jitWriteEnabled); -#endif // defined(HOST_OSX) && defined(HOST_ARM64) #endif // _DEBUG } diff --git a/src/coreclr/src/vm/methoddescbackpatchinfo.cpp b/src/coreclr/src/vm/methoddescbackpatchinfo.cpp index d3b73d36ac18d..000b56dbc5bbd 100644 --- a/src/coreclr/src/vm/methoddescbackpatchinfo.cpp +++ b/src/coreclr/src/vm/methoddescbackpatchinfo.cpp @@ -29,7 +29,7 @@ void EntryPointSlots::Backpatch_Locked(TADDR slot, SlotType slotType, PCODE entr _ASSERTE(IS_ALIGNED((SIZE_T)slot, GetRequiredSlotAlignment(slotType))); #if defined(HOST_OSX) && defined(HOST_ARM64) - bool jitWriteEnabled = PAL_JITWriteEnable(true); + auto jitWriteEnableHolder = PAL_JITWriteEnable(true); #endif // defined(HOST_OSX) && defined(HOST_ARM64) switch (slotType) @@ -54,9 +54,6 @@ void EntryPointSlots::Backpatch_Locked(TADDR slot, SlotType slotType, PCODE entr // fall through Flush: -#if defined(HOST_OSX) && defined(HOST_ARM64) - PAL_JITWriteEnable(jitWriteEnabled); -#endif // defined(HOST_OSX) && defined(HOST_ARM64) ClrFlushInstructionCache((LPCVOID)slot, sizeof(PCODE)); break; diff --git a/src/coreclr/src/vm/precode.cpp b/src/coreclr/src/vm/precode.cpp index 5b599ab915da0..2ef201d629654 100644 --- a/src/coreclr/src/vm/precode.cpp +++ b/src/coreclr/src/vm/precode.cpp @@ -405,7 +405,7 @@ void Precode::ResetTargetInterlocked() WRAPPER_NO_CONTRACT; #if defined(HOST_OSX) && defined(HOST_ARM64) - bool jitWriteEnabled = PAL_JITWriteEnable(true); + auto jitWriteEnableHolder = PAL_JITWriteEnable(true); #endif // defined(HOST_OSX) && defined(HOST_ARM64) PrecodeType precodeType = GetType(); @@ -426,10 +426,6 @@ void Precode::ResetTargetInterlocked() break; } -#if defined(HOST_OSX) && defined(HOST_ARM64) - PAL_JITWriteEnable(jitWriteEnabled); -#endif // defined(HOST_OSX) && defined(HOST_ARM64) - // Although executable code is modified on x86/x64, a FlushInstructionCache() is not necessary on those platforms due to the // interlocked operation above (see ClrFlushInstructionCache()) } @@ -446,7 +442,7 @@ BOOL Precode::SetTargetInterlocked(PCODE target, BOOL fOnlyRedirectFromPrestub) return FALSE; #if defined(HOST_OSX) && defined(HOST_ARM64) - bool jitWriteEnabled = PAL_JITWriteEnable(true); + auto jitWriteEnableHolder = PAL_JITWriteEnable(true); #endif // defined(HOST_OSX) && defined(HOST_ARM64) g_IBCLogger.LogMethodPrecodeWriteAccess(GetMethodDesc()); @@ -475,10 +471,6 @@ BOOL Precode::SetTargetInterlocked(PCODE target, BOOL fOnlyRedirectFromPrestub) break; } -#if defined(HOST_OSX) && defined(HOST_ARM64) - PAL_JITWriteEnable(jitWriteEnabled); -#endif // defined(HOST_OSX) && defined(HOST_ARM64) - // Although executable code is modified on x86/x64, a FlushInstructionCache() is not necessary on those platforms due to the // interlocked operation above (see ClrFlushInstructionCache()) diff --git a/src/coreclr/src/vm/prestub.cpp b/src/coreclr/src/vm/prestub.cpp index c70fe266d84be..a1b299d553bd4 100644 --- a/src/coreclr/src/vm/prestub.cpp +++ b/src/coreclr/src/vm/prestub.cpp @@ -327,7 +327,7 @@ PCODE MethodDesc::PrepareCode(PrepareCodeConfig* pConfig) STANDARD_VM_CONTRACT; #if defined(HOST_OSX) && defined(HOST_ARM64) - bool jitWriteEnabled = PAL_JITWriteEnable(true); + auto jitWriteEnableHolder = PAL_JITWriteEnable(true); #endif // defined(HOST_OSX) && defined(HOST_ARM64) // If other kinds of code need multi-versioning we could add more cases here, @@ -339,10 +339,6 @@ PCODE MethodDesc::PrepareCode(PrepareCodeConfig* pConfig) NotifyGdb::MethodPrepared(this); #endif -#if defined(HOST_OSX) && defined(HOST_ARM64) - PAL_JITWriteEnable(jitWriteEnabled); -#endif // defined(HOST_OSX) && defined(HOST_ARM64) - return pCode; } @@ -1889,7 +1885,7 @@ extern "C" PCODE STDCALL PreStubWorker(TransitionBlock* pTransitionBlock, Method ETWOnStartup(PrestubWorker_V1, PrestubWorkerEnd_V1); #if defined(HOST_OSX) && defined(HOST_ARM64) - bool jitWriteEnabled = PAL_JITWriteEnable(true); + auto jitWriteEnableHolder = PAL_JITWriteEnable(true); #endif // defined(HOST_OSX) && defined(HOST_ARM64) MAKE_CURRENT_THREAD_AVAILABLE(); @@ -1976,10 +1972,6 @@ extern "C" PCODE STDCALL PreStubWorker(TransitionBlock* pTransitionBlock, Method pPFrame->Pop(CURRENT_THREAD); } -#if defined(HOST_OSX) && defined(HOST_ARM64) - PAL_JITWriteEnable(jitWriteEnabled); -#endif // defined(HOST_OSX) && defined(HOST_ARM64) - POSTCONDITION(pbRetVal != NULL); END_PRESERVE_LAST_ERROR; diff --git a/src/coreclr/src/vm/threads.cpp b/src/coreclr/src/vm/threads.cpp index 9007aa8e55d8b..bc47d94226453 100644 --- a/src/coreclr/src/vm/threads.cpp +++ b/src/coreclr/src/vm/threads.cpp @@ -1143,7 +1143,7 @@ void InitThreadManager() } #if defined(HOST_OSX) && defined(HOST_ARM64) - bool jitWriteEnabled = PAL_JITWriteEnable(true); + auto jitWriteEnableHolder = PAL_JITWriteEnable(true); #endif // defined(HOST_OSX) && defined(HOST_ARM64) memcpy(s_barrierCopy, (BYTE*)JIT_PatchedCodeStart, (BYTE*)JIT_PatchedCodeLast - (BYTE*)JIT_PatchedCodeStart); @@ -1159,10 +1159,6 @@ void InitThreadManager() JIT_WriteBarrier_Table_Loc = GetWriteBarrierCodeLocation((void*)&JIT_WriteBarrier_Table); #endif // TARGET_ARM64 -#if defined(HOST_OSX) && defined(HOST_ARM64) - PAL_JITWriteEnable(jitWriteEnabled); -#endif // defined(HOST_OSX) && defined(HOST_ARM64) - #else // FEATURE_WRITEBARRIER_COPY // I am using virtual protect to cover the entire range that this code falls in. diff --git a/src/coreclr/src/vm/virtualcallstub.cpp b/src/coreclr/src/vm/virtualcallstub.cpp index 73c256f0bbbab..3d494992274fe 100644 --- a/src/coreclr/src/vm/virtualcallstub.cpp +++ b/src/coreclr/src/vm/virtualcallstub.cpp @@ -1709,7 +1709,7 @@ PCODE VirtualCallStubManager::ResolveWorker(StubCallSite* pCallSite, } CONTRACTL_END; #if defined(HOST_OSX) && defined(HOST_ARM64) - bool jitWriteEnabled = PAL_JITWriteEnable(true); + auto jitWriteEnableHolder = PAL_JITWriteEnable(true); #endif // defined(HOST_OSX) && defined(HOST_ARM64) MethodTable* objectType = (*protectedObj)->GetMethodTable(); @@ -2135,10 +2135,6 @@ PCODE VirtualCallStubManager::ResolveWorker(StubCallSite* pCallSite, // Target can be NULL only if we can't resolve to an address _ASSERTE(target != NULL); -#if defined(HOST_OSX) && defined(HOST_ARM64) - PAL_JITWriteEnable(jitWriteEnabled); -#endif // defined(HOST_OSX) && defined(HOST_ARM64) - return target; } @@ -2969,7 +2965,7 @@ LookupHolder *VirtualCallStubManager::GenerateLookupStub(PCODE addrOfResolver, s } CONTRACT_END; #if defined(HOST_OSX) && defined(HOST_ARM64) - bool jitWriteEnabled = PAL_JITWriteEnable(true); + auto jitWriteEnableHolder = PAL_JITWriteEnable(true); #endif // defined(HOST_OSX) && defined(HOST_ARM64) //allocate from the requisite heap and copy the template over it. @@ -2990,10 +2986,6 @@ LookupHolder *VirtualCallStubManager::GenerateLookupStub(PCODE addrOfResolver, s PerfMap::LogStubs(__FUNCTION__, "GenerateLookupStub", (PCODE)holder->stub(), holder->stub()->size()); #endif -#if defined(HOST_OSX) && defined(HOST_ARM64) - PAL_JITWriteEnable(jitWriteEnabled); -#endif // defined(HOST_OSX) && defined(HOST_ARM64) - RETURN (holder); } From af0d7ebccd22af26906ca4026a292cb723a67b24 Mon Sep 17 00:00:00 2001 From: Steve MacLean Date: Mon, 31 Aug 2020 16:11:31 -0700 Subject: [PATCH 52/89] Restore constistency check --- src/coreclr/src/vm/stackwalk.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/coreclr/src/vm/stackwalk.cpp b/src/coreclr/src/vm/stackwalk.cpp index 0baf52d17124f..a13127e3c6569 100644 --- a/src/coreclr/src/vm/stackwalk.cpp +++ b/src/coreclr/src/vm/stackwalk.cpp @@ -2266,6 +2266,7 @@ StackWalkAction StackFrameIterator::NextRaw(void) // make sure we're not skipping a different transition if (m_crawl.pFrame->NeedsUpdateRegDisplay()) { + CONSISTENCY_CHECK(m_crawl.pFrame->IsTransitionToNativeFrame()); if (m_crawl.pFrame->GetVTablePtr() == InlinedCallFrame::GetMethodFrameVPtr()) { // ControlPC may be different as the InlinedCallFrame stays active throughout From 6677bce4e0859b7b1fb3ebf2b88f4c5b1c8e6ac8 Mon Sep 17 00:00:00 2001 From: Steve MacLean Date: Mon, 31 Aug 2020 16:46:11 -0700 Subject: [PATCH 53/89] Use fpAddress name --- src/coreclr/src/pal/src/exception/machexception.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/coreclr/src/pal/src/exception/machexception.cpp b/src/coreclr/src/pal/src/exception/machexception.cpp index f0334922416cc..35a4daa76bdac 100644 --- a/src/coreclr/src/pal/src/exception/machexception.cpp +++ b/src/coreclr/src/pal/src/exception/machexception.cpp @@ -1518,7 +1518,7 @@ InjectActivationInternal(CPalThread* pThread) 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 rfpAddress = (size_t)sp; + size_t fpAddress = (size_t)sp; #else #error Unexpected architecture #endif @@ -1556,7 +1556,7 @@ InjectActivationInternal(CPalThread* pThread) 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, rfpAddress); + arm_thread_state64_set_fp(ThreadState, fpAddress); ThreadState.__x[0] = contextAddress; #else #error Unexpected architecture From 6a884d02f06b10a5da93447e52d90c2977db1673 Mon Sep 17 00:00:00 2001 From: Steve MacLean Date: Tue, 1 Sep 2020 09:26:13 -0700 Subject: [PATCH 54/89] Add HAVE_SYSCTLBYNAME to PAL_GetJitCpuCapabilityFlags --- src/coreclr/src/pal/src/misc/jitsupport.cpp | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/src/coreclr/src/pal/src/misc/jitsupport.cpp b/src/coreclr/src/pal/src/misc/jitsupport.cpp index 89e90c23812aa..13ffa029424dc 100644 --- a/src/coreclr/src/pal/src/misc/jitsupport.cpp +++ b/src/coreclr/src/pal/src/misc/jitsupport.cpp @@ -13,6 +13,10 @@ SET_DEFAULT_DEBUG_CHANNEL(MISC); #include #endif +#if HAVE_SYSCTLBYNAME +#include +#endif + #if defined(HOST_ARM64) && defined(__linux__) struct CpuCapability { @@ -254,6 +258,16 @@ PAL_GetJitCpuCapabilityFlags(CORJIT_FLAGS *flags) // CPUCompileFlags.Set(CORJIT_FLAGS::CORJIT_FLAG_HAS_ARM64_SVE); #endif #else // !HAVE_AUXV_HWCAP_H +#if HAVE_SYSCTLBYNAME + int64_t valueFromSysctl = 0; + size_t sz = sizeof(valueFromSysctl); + + if ((sysctlbyname("hw.optional.armv8_1_atomics", &valueFromSysctl, &sz, nullptr, 0) == 0) && (valueFromSysctl != 0)) + CPUCompileFlags.Set(InstructionSet_Atomics); + + if ((sysctlbyname("hw.optional.armv8_crc32", &valueFromSysctl, &sz, nullptr, 0) == 0) && (valueFromSysctl != 0)) + CPUCompileFlags.Set(InstructionSet_Crc32); +#endif // HAVE_SYSCTLBYNAME // CoreCLR SIMD and FP support is included in ARM64 baseline // On exceptional basis platforms may leave out support, but CoreCLR does not // yet support such platforms From 29edb16cb7049709decba6b2d8cccdb5030855e4 Mon Sep 17 00:00:00 2001 From: Steve MacLean Date: Tue, 1 Sep 2020 09:40:37 -0700 Subject: [PATCH 55/89] Rename SafeUpdateWriteBarrierState --- src/coreclr/src/vm/arm64/stubs.cpp | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/coreclr/src/vm/arm64/stubs.cpp b/src/coreclr/src/vm/arm64/stubs.cpp index 91a84d2e611e5..d89b9c68364f8 100644 --- a/src/coreclr/src/vm/arm64/stubs.cpp +++ b/src/coreclr/src/vm/arm64/stubs.cpp @@ -1070,7 +1070,7 @@ void JIT_TailCall() #if !defined(DACCESS_COMPILE) && !defined(CROSSGEN_COMPILE) EXTERN_C void JIT_UpdateWriteBarrierState(bool skipEphemeralCheck); -static void SafeUpdateWriteBarrierState(bool skipEphemeralCheck) +static void UpdateWriteBarrierState (bool skipEphemeralCheck) { #if defined(HOST_OSX) && defined(HOST_ARM64) auto jitWriteEnableHolder = PAL_JITWriteEnable(true); @@ -1104,12 +1104,12 @@ void InitJITHelpers1() } } - SafeUpdateWriteBarrierState(GCHeapUtilities::IsServerHeap()); + UpdateWriteBarrierState (GCHeapUtilities::IsServerHeap()); } #else -void SafeUpdateWriteBarrierState(bool) {} +void UpdateWriteBarrierState (bool) {} #endif // !defined(DACCESS_COMPILE) && !defined(CROSSGEN_COMPILE) PTR_CONTEXT GetCONTEXTFromRedirectedStubStackFrame(T_DISPATCHER_CONTEXT * pDispatcherContext) @@ -1278,26 +1278,26 @@ void FlushWriteBarrierInstructionCache() #ifndef CROSSGEN_COMPILE int StompWriteBarrierEphemeral(bool isRuntimeSuspended) { - SafeUpdateWriteBarrierState(GCHeapUtilities::IsServerHeap()); + UpdateWriteBarrierState (GCHeapUtilities::IsServerHeap()); return SWB_PASS; } int StompWriteBarrierResize(bool isRuntimeSuspended, bool bReqUpperBoundsCheck) { - SafeUpdateWriteBarrierState(GCHeapUtilities::IsServerHeap()); + UpdateWriteBarrierState (GCHeapUtilities::IsServerHeap()); return SWB_PASS; } #ifdef FEATURE_USE_SOFTWARE_WRITE_WATCH_FOR_GC_HEAP int SwitchToWriteWatchBarrier(bool isRuntimeSuspended) { - SafeUpdateWriteBarrierState(GCHeapUtilities::IsServerHeap()); + UpdateWriteBarrierState (GCHeapUtilities::IsServerHeap()); return SWB_PASS; } int SwitchToNonWriteWatchBarrier(bool isRuntimeSuspended) { - SafeUpdateWriteBarrierState(GCHeapUtilities::IsServerHeap()); + UpdateWriteBarrierState (GCHeapUtilities::IsServerHeap()); return SWB_PASS; } #endif // FEATURE_USE_SOFTWARE_WRITE_WATCH_FOR_GC_HEAP From 012febf0afb8c677578a71a8ed02c885b643a6bb Mon Sep 17 00:00:00 2001 From: Steve MacLean Date: Wed, 2 Sep 2020 11:21:20 -0700 Subject: [PATCH 56/89] Fix LazyMachState::setLazyStateFromUnwind(...) --- src/coreclr/src/vm/arm64/gmscpu.h | 1 + 1 file changed, 1 insertion(+) diff --git a/src/coreclr/src/vm/arm64/gmscpu.h b/src/coreclr/src/vm/arm64/gmscpu.h index 0c48f007b7bde..887a41b4f07c1 100644 --- a/src/coreclr/src/vm/arm64/gmscpu.h +++ b/src/coreclr/src/vm/arm64/gmscpu.h @@ -80,6 +80,7 @@ inline void LazyMachState::setLazyStateFromUnwind(MachState* copy) } *pDst++ = valueSrc; + captureX19_X29[i] = copy->captureX19_X29[i]; } From b06e8b32199c59e2d4c8af67eae2c4cf80b8958a Mon Sep 17 00:00:00 2001 From: Steve MacLean Date: Wed, 2 Sep 2020 20:06:46 -0700 Subject: [PATCH 57/89] Flush NONPAL_TRACE messages --- src/coreclr/src/pal/src/exception/machmessage.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/coreclr/src/pal/src/exception/machmessage.h b/src/coreclr/src/pal/src/exception/machmessage.h index ff288ad6f25b2..27ed9e9243133 100644 --- a/src/coreclr/src/pal/src/exception/machmessage.h +++ b/src/coreclr/src/pal/src/exception/machmessage.h @@ -67,7 +67,7 @@ using namespace CorUnix; // Debug-only output with printf-style formatting. #define NONPAL_TRACE(_format, ...) do { \ - if (NONPAL_TRACE_ENABLED) printf("NONPAL_TRACE: " _format, ## __VA_ARGS__); \ + if (NONPAL_TRACE_ENABLED) { printf("NONPAL_TRACE: " _format, ## __VA_ARGS__); fflush(stdout); } \ } while (false) #else // _DEBUG From b7253129e69f477c5eca8c22f6ec1e94662b8ef2 Mon Sep 17 00:00:00 2001 From: Steve MacLean Date: Wed, 2 Sep 2020 20:07:49 -0700 Subject: [PATCH 58/89] Fix PAL_JITWriteEnableHolder::JITWriteEnable --- src/coreclr/src/pal/src/map/virtual.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/coreclr/src/pal/src/map/virtual.cpp b/src/coreclr/src/pal/src/map/virtual.cpp index 75c067554e4bd..c1dd5da5536bd 100644 --- a/src/coreclr/src/pal/src/map/virtual.cpp +++ b/src/coreclr/src/pal/src/map/virtual.cpp @@ -1766,7 +1766,7 @@ PAL_JITWriteEnableHolder::JITWriteEnable(bool writeEnable) { // Use a thread local to track per thread JIT Write enable state // Threads start with MAP_JIT pages readable and executable (R-X) by default. - thread_local bool enabled = false; + thread_local int enabled = 0xdeadbeef; bool result = enabled; if (enabled != writeEnable) { From 923ecbb73bf9da216c34a158b4bf789a0789b0a0 Mon Sep 17 00:00:00 2001 From: Steve MacLean Date: Wed, 2 Sep 2020 20:09:45 -0700 Subject: [PATCH 59/89] Fix exception handling --- src/coreclr/src/vm/exceptionhandling.cpp | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/coreclr/src/vm/exceptionhandling.cpp b/src/coreclr/src/vm/exceptionhandling.cpp index 84a65d8687e24..7d329902e42ab 100644 --- a/src/coreclr/src/vm/exceptionhandling.cpp +++ b/src/coreclr/src/vm/exceptionhandling.cpp @@ -3312,6 +3312,10 @@ DWORD_PTR ExceptionTracker::CallHandler( break; } +#if defined(HOST_OSX) && defined(HOST_ARM64) + auto jitWriteEnableHolder = PAL_JITWriteEnable(false); +#endif // defined(HOST_OSX) && defined(HOST_ARM64) + #ifdef USE_FUNCLET_CALL_HELPER // Invoke the funclet. We pass throwable only when invoking the catch block. // Since the actual caller of the funclet is the assembly helper, pass the reference @@ -3948,6 +3952,10 @@ void ExceptionTracker::ResumeExecution( EH_LOG((LL_INFO100, "resuming execution at 0x%p\n", GetIP(pContextRecord))); EH_LOG((LL_INFO100, "^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n")); +#if defined(HOST_OSX) && defined(HOST_ARM64) + auto jitWriteEnableHolder = PAL_JITWriteEnable(false); +#endif // defined(HOST_OSX) && defined(HOST_ARM64) + RtlRestoreContext(pContextRecord, pExceptionRecord); UNREACHABLE(); From ad5eabc763a41d781c282cd2d13304e1b5d819da Mon Sep 17 00:00:00 2001 From: Steve MacLean Date: Thu, 3 Sep 2020 13:46:12 -0700 Subject: [PATCH 60/89] Fix assertion when crossgen prints an empty string --- src/coreclr/src/pal/src/cruntime/printfcpp.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/coreclr/src/pal/src/cruntime/printfcpp.cpp b/src/coreclr/src/pal/src/cruntime/printfcpp.cpp index a71814e0dd4e8..0f7cb682650f8 100644 --- a/src/coreclr/src/pal/src/cruntime/printfcpp.cpp +++ b/src/coreclr/src/pal/src/cruntime/printfcpp.cpp @@ -59,6 +59,7 @@ static int Internal_Convertfwrite(CPalThread *pthrCurrent, const void *buffer, s clearerr (stream); #endif + if(convert) { int nsize; @@ -66,6 +67,8 @@ static int Internal_Convertfwrite(CPalThread *pthrCurrent, const void *buffer, s nsize = WideCharToMultiByte(CP_ACP, 0,(LPCWSTR)buffer, count, 0, 0, 0, 0); if (!nsize) { + if (count == 0) + return 0; ASSERT("WideCharToMultiByte failed. Error is %d\n", GetLastError()); return -1; } From 7eced9dcae1a40146a183662b14e9332f31e6059 Mon Sep 17 00:00:00 2001 From: Steve MacLean Date: Thu, 3 Sep 2020 13:47:05 -0700 Subject: [PATCH 61/89] Fix EventPipe::InvokeCallback --- src/coreclr/src/vm/eventpipe.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/coreclr/src/vm/eventpipe.cpp b/src/coreclr/src/vm/eventpipe.cpp index 4c5918ffc2032..7ececd40be3e2 100644 --- a/src/coreclr/src/vm/eventpipe.cpp +++ b/src/coreclr/src/vm/eventpipe.cpp @@ -1043,6 +1043,10 @@ HANDLE EventPipe::GetWaitHandle(EventPipeSessionID sessionID) void EventPipe::InvokeCallback(EventPipeProviderCallbackData eventPipeProviderCallbackData) { +#if defined(HOST_OSX) && defined(HOST_ARM64) + auto jitWriteEnableHolder = PAL_JITWriteEnable(false); +#endif // defined(HOST_OSX) && defined(HOST_ARM64) + EventPipeProvider::InvokeCallback(eventPipeProviderCallbackData); } From d94eba5e0895a1e56c4289926f8ad5dbc5706983 Mon Sep 17 00:00:00 2001 From: Steve MacLean Date: Thu, 3 Sep 2020 13:48:08 -0700 Subject: [PATCH 62/89] Fix GcInfoDecoder::ReportRegisterToGC --- src/coreclr/src/vm/gcinfodecoder.cpp | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/src/coreclr/src/vm/gcinfodecoder.cpp b/src/coreclr/src/vm/gcinfodecoder.cpp index 1e8f2e86f2936..31e0615608a00 100644 --- a/src/coreclr/src/vm/gcinfodecoder.cpp +++ b/src/coreclr/src/vm/gcinfodecoder.cpp @@ -1659,6 +1659,27 @@ void GcInfoDecoder::ReportRegisterToGC( // ARM64 LOG((LF_GCROOTS, LL_INFO1000, "Reporting " FMT_REG, regNum )); OBJECTREF* pObjRef = GetRegisterSlot( regNum, pRD ); +#if defined(TARGET_UNIX) && !defined(SOS_TARGET_ARM64) + // On PAL, we don't always have the context pointers available due to + // a limitation of an unwinding library. In such case, the context + // pointers for some nonvolatile registers are NULL. + // In such case, we let the pObjRef point to the captured register + // value in the context and pin the object itself. + if (pObjRef == NULL) + { + // Report a pinned object to GC only in the promotion phase when the + // GC is scanning roots. + GCCONTEXT* pGCCtx = (GCCONTEXT*)(hCallBack); + if (!pGCCtx->sc->promotion) + { + return; + } + + pObjRef = GetCapturedRegister(regNum, pRD); + + gcFlags |= GC_CALL_PINNED; + } +#endif // TARGET_UNIX && !SOS_TARGET_ARM64 #ifdef _DEBUG if(IsScratchRegister(regNum, pRD)) From 05214eff482589b5cfff0b8c9a867f50de580074 Mon Sep 17 00:00:00 2001 From: Steve MacLean Date: Thu, 3 Sep 2020 18:05:12 -0700 Subject: [PATCH 63/89] Disable JITWrite on Activation --- src/coreclr/src/pal/src/exception/machexception.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/coreclr/src/pal/src/exception/machexception.cpp b/src/coreclr/src/pal/src/exception/machexception.cpp index 35a4daa76bdac..45c534a0e1485 100644 --- a/src/coreclr/src/pal/src/exception/machexception.cpp +++ b/src/coreclr/src/pal/src/exception/machexception.cpp @@ -1422,6 +1422,9 @@ ActivationHandler(CONTEXT* context) { if (g_activationFunction != NULL) { +#if defined(HOST_OSX) && defined(HOST_ARM64) + auto jitWriteEnableHolder = PAL_JITWriteEnable(false); +#endif // defined(HOST_OSX) && defined(HOST_ARM64) g_activationFunction(context); } From 03af208fa4e3c29260b0ea9671036d021c91494f Mon Sep 17 00:00:00 2001 From: Steve MacLean Date: Thu, 3 Sep 2020 18:06:07 -0700 Subject: [PATCH 64/89] Only activate for ESR.EC == SVC --- src/coreclr/src/pal/src/exception/machexception.cpp | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/coreclr/src/pal/src/exception/machexception.cpp b/src/coreclr/src/pal/src/exception/machexception.cpp index 45c534a0e1485..550a649baa4b6 100644 --- a/src/coreclr/src/pal/src/exception/machexception.cpp +++ b/src/coreclr/src/pal/src/exception/machexception.cpp @@ -1492,7 +1492,13 @@ InjectActivationInternal(CPalThread* pThread) static const int MaxHardwareExceptionVector = 31; if (ExceptionState.__trapno > MaxHardwareExceptionVector) #elif defined(HOST_ARM64) - // TBD // Inject the activation only if the thread doesn't have a pending hardware exception + NONPAL_TRACE("InjectActivationInternal IsHardwareException? far %016llx esr %08x exception %08x\n", + ExceptionState.__far, + ExceptionState.__esr, + ExceptionState.__exception); + // Inject the activation only if the last ESR was an SVC and therefore the thread doesn't have + // a pending hardware exception + if ((ExceptionState.__esr >> 26) == 0x15) #else #error Unexpected architecture #endif From 24532ac8ee28e6d1ccfdd96d9b2fc0b7b3ecf7cc Mon Sep 17 00:00:00 2001 From: Steve MacLean Date: Thu, 3 Sep 2020 18:07:12 -0700 Subject: [PATCH 65/89] Fix HostCodeHeap::AddToFreeList --- src/coreclr/src/vm/dynamicmethod.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/coreclr/src/vm/dynamicmethod.cpp b/src/coreclr/src/vm/dynamicmethod.cpp index 51ce113d1adb7..22785e9d60362 100644 --- a/src/coreclr/src/vm/dynamicmethod.cpp +++ b/src/coreclr/src/vm/dynamicmethod.cpp @@ -551,6 +551,10 @@ void HostCodeHeap::AddToFreeList(TrackAllocation *pBlockToInsert) LOG((LF_BCL, LL_INFO100, "Level2 - CodeHeap [0x%p] - Add to FreeList [%p, 0x%X]\n", this, pBlockToInsert, pBlockToInsert->size)); +#if defined(HOST_OSX) && defined(HOST_ARM64) + auto jitWriteEnableHolder = PAL_JITWriteEnable(true); +#endif // defined(HOST_OSX) && defined(HOST_ARM64) + // append to the list in the proper position and coalesce if needed if (m_pFreeList) { From c291613cce70eacf89fc08d18af323d64d379f4b Mon Sep 17 00:00:00 2001 From: Steve MacLean Date: Thu, 3 Sep 2020 18:07:52 -0700 Subject: [PATCH 66/89] Fix comment --- src/coreclr/src/pal/src/exception/machexception.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/coreclr/src/pal/src/exception/machexception.cpp b/src/coreclr/src/pal/src/exception/machexception.cpp index 550a649baa4b6..7b23c57616598 100644 --- a/src/coreclr/src/pal/src/exception/machexception.cpp +++ b/src/coreclr/src/pal/src/exception/machexception.cpp @@ -1496,7 +1496,7 @@ InjectActivationInternal(CPalThread* pThread) ExceptionState.__far, ExceptionState.__esr, ExceptionState.__exception); - // Inject the activation only if the last ESR was an SVC and therefore the thread doesn't have + // Inject the activation only if the last ESR.EC was an SVC and therefore the thread doesn't have // a pending hardware exception if ((ExceptionState.__esr >> 26) == 0x15) #else From 60ac6e5fc8944db693e13f8068cf6f5754071a2a Mon Sep 17 00:00:00 2001 From: Steve MacLean Date: Thu, 3 Sep 2020 18:28:52 -0700 Subject: [PATCH 67/89] Fix NONPAL_TRACING induced deadlock --- src/coreclr/src/pal/src/exception/machexception.cpp | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/coreclr/src/pal/src/exception/machexception.cpp b/src/coreclr/src/pal/src/exception/machexception.cpp index 7b23c57616598..e8c1814b17bb8 100644 --- a/src/coreclr/src/pal/src/exception/machexception.cpp +++ b/src/coreclr/src/pal/src/exception/machexception.cpp @@ -1492,10 +1492,6 @@ InjectActivationInternal(CPalThread* pThread) static const int MaxHardwareExceptionVector = 31; if (ExceptionState.__trapno > MaxHardwareExceptionVector) #elif defined(HOST_ARM64) - NONPAL_TRACE("InjectActivationInternal IsHardwareException? far %016llx esr %08x exception %08x\n", - ExceptionState.__far, - ExceptionState.__esr, - ExceptionState.__exception); // Inject the activation only if the last ESR.EC was an SVC and therefore the thread doesn't have // a pending hardware exception if ((ExceptionState.__esr >> 26) == 0x15) From 6ba565a425de9b8f15f97c89e99e5b91c868bfd1 Mon Sep 17 00:00:00 2001 From: Steve MacLean Date: Sat, 5 Sep 2020 09:38:29 -0700 Subject: [PATCH 68/89] Use MachSetThreadContext for RtlRestoreContext --- src/coreclr/src/pal/src/arch/arm64/context2.S | 3 ++- .../src/pal/src/exception/machexception.cpp | 16 +++++++++++++--- 2 files changed, 15 insertions(+), 4 deletions(-) diff --git a/src/coreclr/src/pal/src/arch/arm64/context2.S b/src/coreclr/src/pal/src/arch/arm64/context2.S index 2ebce4b440048..065dac3b5bee9 100644 --- a/src/coreclr/src/pal/src/arch/arm64/context2.S +++ b/src/coreclr/src/pal/src/arch/arm64/context2.S @@ -111,7 +111,6 @@ LEAF_END CONTEXT_CaptureContext, _TEXT // Incoming: // x0: Context* - LEAF_ENTRY RtlCaptureContext, _TEXT PROLOG_STACK_ALLOC 16 .cfi_adjust_cfa_offset 16 @@ -129,6 +128,7 @@ LEAF_ENTRY RtlCaptureContext, _TEXT b C_FUNC(CONTEXT_CaptureContext) LEAF_END RtlCaptureContext, _TEXT +#ifndef HOST_OSX // Incoming: // x0: Context* // x1: Exception* @@ -213,3 +213,4 @@ LOCAL_LABEL(No_Restore_CONTEXT_CONTROL): ret LEAF_END RtlRestoreContext, _TEXT +#endif // !HOST_OSX diff --git a/src/coreclr/src/pal/src/exception/machexception.cpp b/src/coreclr/src/pal/src/exception/machexception.cpp index e8c1814b17bb8..6bef9edc3e0fb 100644 --- a/src/coreclr/src/pal/src/exception/machexception.cpp +++ b/src/coreclr/src/pal/src/exception/machexception.cpp @@ -1422,9 +1422,6 @@ ActivationHandler(CONTEXT* context) { if (g_activationFunction != NULL) { -#if defined(HOST_OSX) && defined(HOST_ARM64) - auto jitWriteEnableHolder = PAL_JITWriteEnable(false); -#endif // defined(HOST_OSX) && defined(HOST_ARM64) g_activationFunction(context); } @@ -1432,6 +1429,19 @@ ActivationHandler(CONTEXT* context) DebugBreak(); } +#if defined(TARGET_ARM64) +extern "C" +void +RtlRestoreContext(CONTEXT* context, PEXCEPTION_RECORD ExceptionRecord) +{ + // RtlRestoreContext assembly corrupts X16 & X17, so it cannot be + // used in thread hijacking situations + // Since we have the higher fidelity MachSetThreadContext, use it in + // all situations + MachSetThreadContext(context); +} +#endif + extern "C" void ActivationHandlerWrapper(); extern "C" int ActivationHandlerReturnOffset; extern "C" unsigned int XmmYmmStateSupport(); From 80b91260152e76b022b49fabf721a833a8702ad7 Mon Sep 17 00:00:00 2001 From: Steve MacLean Date: Tue, 8 Sep 2020 11:25:55 -0700 Subject: [PATCH 69/89] Revert "Use MachSetThreadContext for RtlRestoreContext" This reverts commit 6ba565a425de9b8f15f97c89e99e5b91c868bfd1. --- src/coreclr/src/pal/src/arch/arm64/context2.S | 3 +-- .../src/pal/src/exception/machexception.cpp | 16 +++------------- 2 files changed, 4 insertions(+), 15 deletions(-) diff --git a/src/coreclr/src/pal/src/arch/arm64/context2.S b/src/coreclr/src/pal/src/arch/arm64/context2.S index 065dac3b5bee9..2ebce4b440048 100644 --- a/src/coreclr/src/pal/src/arch/arm64/context2.S +++ b/src/coreclr/src/pal/src/arch/arm64/context2.S @@ -111,6 +111,7 @@ LEAF_END CONTEXT_CaptureContext, _TEXT // Incoming: // x0: Context* + LEAF_ENTRY RtlCaptureContext, _TEXT PROLOG_STACK_ALLOC 16 .cfi_adjust_cfa_offset 16 @@ -128,7 +129,6 @@ LEAF_ENTRY RtlCaptureContext, _TEXT b C_FUNC(CONTEXT_CaptureContext) LEAF_END RtlCaptureContext, _TEXT -#ifndef HOST_OSX // Incoming: // x0: Context* // x1: Exception* @@ -213,4 +213,3 @@ LOCAL_LABEL(No_Restore_CONTEXT_CONTROL): ret LEAF_END RtlRestoreContext, _TEXT -#endif // !HOST_OSX diff --git a/src/coreclr/src/pal/src/exception/machexception.cpp b/src/coreclr/src/pal/src/exception/machexception.cpp index 6bef9edc3e0fb..e8c1814b17bb8 100644 --- a/src/coreclr/src/pal/src/exception/machexception.cpp +++ b/src/coreclr/src/pal/src/exception/machexception.cpp @@ -1422,6 +1422,9 @@ ActivationHandler(CONTEXT* context) { if (g_activationFunction != NULL) { +#if defined(HOST_OSX) && defined(HOST_ARM64) + auto jitWriteEnableHolder = PAL_JITWriteEnable(false); +#endif // defined(HOST_OSX) && defined(HOST_ARM64) g_activationFunction(context); } @@ -1429,19 +1432,6 @@ ActivationHandler(CONTEXT* context) DebugBreak(); } -#if defined(TARGET_ARM64) -extern "C" -void -RtlRestoreContext(CONTEXT* context, PEXCEPTION_RECORD ExceptionRecord) -{ - // RtlRestoreContext assembly corrupts X16 & X17, so it cannot be - // used in thread hijacking situations - // Since we have the higher fidelity MachSetThreadContext, use it in - // all situations - MachSetThreadContext(context); -} -#endif - extern "C" void ActivationHandlerWrapper(); extern "C" int ActivationHandlerReturnOffset; extern "C" unsigned int XmmYmmStateSupport(); From 62575e2debed82880925f861f89f7d354f3b7f73 Mon Sep 17 00:00:00 2001 From: Steve MacLean Date: Tue, 8 Sep 2020 11:30:49 -0700 Subject: [PATCH 70/89] Use MachSetThreadContext in ActivationHandler --- src/coreclr/src/pal/src/exception/machexception.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/coreclr/src/pal/src/exception/machexception.cpp b/src/coreclr/src/pal/src/exception/machexception.cpp index e8c1814b17bb8..8ba49ad5630d5 100644 --- a/src/coreclr/src/pal/src/exception/machexception.cpp +++ b/src/coreclr/src/pal/src/exception/machexception.cpp @@ -1428,7 +1428,13 @@ ActivationHandler(CONTEXT* context) 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(); } From 68a08bfbdab0f4569367384b41cd25c87253ddf3 Mon Sep 17 00:00:00 2001 From: Steve MacLean Date: Tue, 8 Sep 2020 12:50:34 -0700 Subject: [PATCH 71/89] Remove unnecessary PAL_JITWriteEnable --- src/coreclr/src/pal/src/exception/machexception.cpp | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/coreclr/src/pal/src/exception/machexception.cpp b/src/coreclr/src/pal/src/exception/machexception.cpp index 8ba49ad5630d5..a5dabace80695 100644 --- a/src/coreclr/src/pal/src/exception/machexception.cpp +++ b/src/coreclr/src/pal/src/exception/machexception.cpp @@ -1422,9 +1422,6 @@ ActivationHandler(CONTEXT* context) { if (g_activationFunction != NULL) { -#if defined(HOST_OSX) && defined(HOST_ARM64) - auto jitWriteEnableHolder = PAL_JITWriteEnable(false); -#endif // defined(HOST_OSX) && defined(HOST_ARM64) g_activationFunction(context); } From 10251805298f3a29c5ba48010e64f5694c9b588d Mon Sep 17 00:00:00 2001 From: Steve MacLean Date: Tue, 8 Sep 2020 14:06:17 -0700 Subject: [PATCH 72/89] Fix configurecompiler.cmake typo --- eng/native/configurecompiler.cmake | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/eng/native/configurecompiler.cmake b/eng/native/configurecompiler.cmake index 1b5342ffbff76..c2855d1ec85ab 100644 --- a/eng/native/configurecompiler.cmake +++ b/eng/native/configurecompiler.cmake @@ -372,7 +372,7 @@ if (CLR_CMAKE_HOST_UNIX) # 'pthread_jit_write_protect_np' is only available on macOS 11.0 or newer set(MACOS_VERSION_MIN_FLAGS -mmacosx-version-min=11.0) add_compile_options(-arch arm64) - elseif(CLR_CMAKE_HOST_ARCH_X64) + elseif(CLR_CMAKE_HOST_ARCH_AMD64) set(MACOS_VERSION_MIN_FLAGS -mmacosx-version-min=10.13) add_compile_options(-arch x86_64) else() From 44eeb38e7f32eef16b2de74fe41d1a7f98c92001 Mon Sep 17 00:00:00 2001 From: Steve MacLean Date: Wed, 9 Sep 2020 09:08:38 -0700 Subject: [PATCH 73/89] Fix foreign thread callbacks to managed code --- src/coreclr/src/pal/src/map/virtual.cpp | 4 ++-- src/coreclr/src/vm/threads.cpp | 5 +++++ 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/src/coreclr/src/pal/src/map/virtual.cpp b/src/coreclr/src/pal/src/map/virtual.cpp index c1dd5da5536bd..7e337b9edeb5e 100644 --- a/src/coreclr/src/pal/src/map/virtual.cpp +++ b/src/coreclr/src/pal/src/map/virtual.cpp @@ -1765,8 +1765,8 @@ bool PAL_JITWriteEnableHolder::JITWriteEnable(bool writeEnable) { // Use a thread local to track per thread JIT Write enable state - // Threads start with MAP_JIT pages readable and executable (R-X) by default. - thread_local int enabled = 0xdeadbeef; + // Initialize threads to start with MAP_JIT pages readable and executable (R-X) by default. + thread_local bool enabled = (pthread_jit_write_protect_np(1), false); bool result = enabled; if (enabled != writeEnable) { diff --git a/src/coreclr/src/vm/threads.cpp b/src/coreclr/src/vm/threads.cpp index 8d4e2ec7f9726..1c1cba7d102aa 100644 --- a/src/coreclr/src/vm/threads.cpp +++ b/src/coreclr/src/vm/threads.cpp @@ -707,6 +707,11 @@ Thread* SetupThread() } #endif +#if defined(HOST_OSX) && defined(HOST_ARM64) + // Initialize new threads to JIT Write disabled + auto jitWriteEnableHolder = PAL_JITWriteEnable(false); +#endif // defined(HOST_OSX) && defined(HOST_ARM64) + // Normally, HasStarted is called from the thread's entrypoint to introduce it to // the runtime. But sometimes that thread is used for DLL_THREAD_ATTACH notifications // that call into managed code. In that case, a call to SetupThread here must From ef69659019075283314d775281a0b02bb310e26c Mon Sep 17 00:00:00 2001 From: Steve MacLean Date: Wed, 9 Sep 2020 10:07:21 -0700 Subject: [PATCH 74/89] Fix corehost build --- src/installer/corehost/build.sh | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/src/installer/corehost/build.sh b/src/installer/corehost/build.sh index c0bbce8e591ae..9d81e15853e1f 100755 --- a/src/installer/corehost/build.sh +++ b/src/installer/corehost/build.sh @@ -93,6 +93,17 @@ __CMakeArgs="-DCLI_CMAKE_HOST_VER=\"$__host_ver\" -DCLI_CMAKE_COMMON_HOST_VER=\" __CMakeArgs="-DCLI_CMAKE_HOST_POLICY_VER=\"$__policy_ver\" -DCLI_CMAKE_PKG_RID=\"$__DistroRid\" -DCLI_CMAKE_COMMIT_HASH=\"$__commit_hash\" $__CMakeArgs" __CMakeArgs="-DCORECLR_ARTIFACTS=\"$__CoreClrArtifacts\" -DNATIVE_LIBS_ARTIFACTS=\"$__NativeLibsArtifacts\" $__CMakeArgs" +if [[ "$__TargetOS" == OSX ]]; then + if [[ "$__BuildArch" == x64 ]]; then + __CMakeArgs="-DCMAKE_OSX_ARCHITECTURES=\"x86_64\" $__CMakeArgs" + elif [[ "$__BuildArch" == arm64 ]]; then + __CMakeArgs="-DCMAKE_OSX_ARCHITECTURES=\"arm64\" $__CMakeArgs" + else + echo "Error: Unknown OSX architecture $__BuildArch." + exit 1 + fi +fi + if [[ "$__PortableBuild" == 1 ]]; then __CMakeArgs="-DCLI_CMAKE_PORTABLE_BUILD=1 $__CMakeArgs" fi From 50c931cc6082e73068a98760857b440ceecf7930 Mon Sep 17 00:00:00 2001 From: Steve MacLean Date: Wed, 9 Sep 2020 12:00:56 -0700 Subject: [PATCH 75/89] Fix more dllimportcallback W^X issues --- src/coreclr/src/vm/dllimportcallback.cpp | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/coreclr/src/vm/dllimportcallback.cpp b/src/coreclr/src/vm/dllimportcallback.cpp index c3c69ddbf3488..f25da147690eb 100644 --- a/src/coreclr/src/vm/dllimportcallback.cpp +++ b/src/coreclr/src/vm/dllimportcallback.cpp @@ -78,6 +78,10 @@ class UMEntryThunkFreeList CrstHolder ch(&m_crst); +#if defined(HOST_OSX) && defined(HOST_ARM64) + auto jitWriteEnableHolder = PAL_JITWriteEnable(true); +#endif // defined(HOST_OSX) && defined(HOST_ARM64) + if (m_pHead == NULL) { m_pHead = pThunk; @@ -1111,6 +1115,10 @@ void UMEntryThunk::Terminate() if (GetObjectHandle()) { +#if defined(HOST_OSX) && defined(HOST_ARM64) + auto jitWriteEnableHolder = PAL_JITWriteEnable(true); +#endif // defined(HOST_OSX) && defined(HOST_ARM64) + DestroyLongWeakHandle(GetObjectHandle()); m_pObjectHandle = 0; } From 5c725cec64939f63d82c007a82bafb6ec3b7b368 Mon Sep 17 00:00:00 2001 From: Jan Vorlicek Date: Fri, 18 Sep 2020 00:14:52 +0200 Subject: [PATCH 76/89] Enable cross-build of coreclr on OSX x64 --- eng/build.sh | 4 +- eng/native/build-commons.sh | 34 ++++++--- eng/native/configureplatform.cmake | 21 ++++-- eng/native/gen-buildsys.sh | 11 ++- src/coreclr/build-runtime.sh | 35 ++-------- src/coreclr/crosscomponents.cmake | 2 +- src/coreclr/src/gc/unix/config.gc.h.in | 2 +- src/coreclr/src/gc/unix/configure.cmake | 20 +++--- src/coreclr/src/gc/unix/events.cpp | 27 +++----- src/coreclr/src/gc/unix/gcenv.unix.cpp | 8 --- src/coreclr/src/gc/unix/globals.h | 8 --- src/coreclr/src/inc/crosscomp.h | 32 +++++++++ src/coreclr/src/pal/inc/pal_error.h | 1 - src/coreclr/src/pal/src/config.h.in | 2 +- src/coreclr/src/pal/src/configure.cmake | 11 ++- .../src/pal/src/exception/remote-unwind.cpp | 29 ++++---- src/coreclr/src/pal/src/include/pal/misc.h | 11 --- src/coreclr/src/pal/src/init/pal.cpp | 7 -- .../src/libunwind_mac/src/missing-functions.c | 4 +- src/coreclr/src/pal/src/map/virtual.cpp | 2 +- src/coreclr/src/pal/src/misc/time.cpp | 69 ++----------------- src/coreclr/tryrun.cmake | 48 ++++++++++++- 22 files changed, 189 insertions(+), 199 deletions(-) diff --git a/eng/build.sh b/eng/build.sh index c2007473d2f85..0f609eb171c49 100755 --- a/eng/build.sh +++ b/eng/build.sh @@ -130,8 +130,8 @@ initDistroRid() local isCrossBuild="$3" local isPortableBuild="$4" - # Only pass ROOTFS_DIR if __DoCrossArchBuild is specified. - if (( isCrossBuild == 1 )); then + # Only pass ROOTFS_DIR if __DoCrossArchBuild is specified and the current platform is not OSX that doesn't use rootfs + if [[ $isCrossBuild == 1 && "$targetOs" != "OSX" ]]; then passedRootfsDir=${ROOTFS_DIR} fi initDistroRidGlobal ${targetOs} ${buildArch} ${isPortableBuild} ${passedRootfsDir} diff --git a/eng/native/build-commons.sh b/eng/native/build-commons.sh index 7315e43f27614..e23a90f747400 100755 --- a/eng/native/build-commons.sh +++ b/eng/native/build-commons.sh @@ -6,8 +6,8 @@ initTargetDistroRid() local passedRootfsDir="" - # Only pass ROOTFS_DIR if cross is specified. - if [[ "$__CrossBuild" == 1 ]]; then + # Only pass ROOTFS_DIR if cross is specified and the target platform is not Darwin that doesn't use rootfs + if [[ "$__CrossBuild" == 1 && "$platform" != "Darwin" ]]; then passedRootfsDir="$ROOTFS_DIR" fi @@ -68,15 +68,28 @@ check_prereqs() build_native() { - platformArch="$1" - cmakeDir="$2" - tryrunDir="$3" - intermediatesDir="$4" - message="$5" + targetOS="$1" + platformArch="$2" + cmakeDir="$3" + tryrunDir="$4" + intermediatesDir="$5" + cmakeArgs="$6" + message="$7" # All set to commence the build echo "Commencing build of \"$message\" for $__TargetOS.$__BuildArch.$__BuildType in $intermediatesDir" + if [[ "$targetOS" == OSX ]]; then + if [[ "$platformArch" == x64 ]]; then + cmakeArgs="-DCMAKE_OSX_ARCHITECTURES=\"x86_64\" $cmakeArgs" + elif [[ "$platformArch" == arm64 ]]; then + cmakeArgs="-DCMAKE_OSX_ARCHITECTURES=\"arm64\" $cmakeArgs" + else + echo "Error: Unknown OSX architecture $platformArch." + exit 1 + fi + fi + if [[ "$__UseNinja" == 1 ]]; then generator="ninja" buildTool="$(command -v ninja || command -v ninja-build)" @@ -134,8 +147,8 @@ EOF fi engNativeDir="$__RepoRootDir/eng/native" - __CMakeArgs="-DCLR_ENG_NATIVE_DIR=\"$engNativeDir\" $__CMakeArgs" - nextCommand="\"$engNativeDir/gen-buildsys.sh\" \"$cmakeDir\" \"$tryrunDir\" \"$intermediatesDir\" $platformArch $__Compiler \"$__CompilerMajorVersion\" \"$__CompilerMinorVersion\" $__BuildType \"$generator\" $scan_build $__CMakeArgs" + cmakeArgs="-DCLR_ENG_NATIVE_DIR=\"$engNativeDir\" $cmakeArgs" + nextCommand="\"$engNativeDir/gen-buildsys.sh\" \"$cmakeDir\" \"$tryrunDir\" \"$intermediatesDir\" $platformArch $__Compiler \"$__CompilerMajorVersion\" \"$__CompilerMinorVersion\" $__BuildType \"$generator\" $scan_build $cmakeArgs" echo "Invoking $nextCommand" eval $nextCommand @@ -441,7 +454,8 @@ fi if [[ "$__CrossBuild" == 1 ]]; then CROSSCOMPILE=1 export CROSSCOMPILE - if [[ ! -n "$ROOTFS_DIR" ]]; then + # Darwin that doesn't use rootfs + if [[ ! -n "$ROOTFS_DIR" && "$platform" != "Darwin" ]]; then ROOTFS_DIR="$__RepoRootDir/.tools/rootfs/$__BuildArch" export ROOTFS_DIR fi diff --git a/eng/native/configureplatform.cmake b/eng/native/configureplatform.cmake index 0d4ee0dae6def..2ee1cf27deee3 100644 --- a/eng/native/configureplatform.cmake +++ b/eng/native/configureplatform.cmake @@ -78,12 +78,23 @@ endif(CLR_CMAKE_HOST_OS STREQUAL Linux) if(CLR_CMAKE_HOST_OS STREQUAL Darwin) set(CLR_CMAKE_HOST_UNIX 1) set(CLR_CMAKE_HOST_OSX 1) - if(CMAKE_OSX_ARCHITECTURES STREQUAL x86_64) - set(CLR_CMAKE_HOST_UNIX_AMD64 1) - elseif(CMAKE_OSX_ARCHITECTURES STREQUAL arm64) - set(CLR_CMAKE_HOST_UNIX_ARM64 1) + if(CLR_CROSS_COMPONENTS_BUILD) + # CMAKE_HOST_SYSTEM_PROCESSOR returns the value of `uname -p` on host. + if(CMAKE_HOST_SYSTEM_PROCESSOR STREQUAL x86_64) + set(CLR_CMAKE_HOST_UNIX_AMD64 1) + elseif(CMAKE_OSX_ARCHITECTURES STREQUAL arm64) + set(CLR_CMAKE_HOST_UNIX_ARM64 1) + else() + clr_unknown_arch() + endif() else() - clr_unknown_arch() + if(CMAKE_OSX_ARCHITECTURES STREQUAL x86_64) + set(CLR_CMAKE_HOST_UNIX_AMD64 1) + elseif(CMAKE_OSX_ARCHITECTURES STREQUAL arm64) + set(CLR_CMAKE_HOST_UNIX_ARM64 1) + else() + clr_unknown_arch() + endif() endif() set(CMAKE_ASM_COMPILE_OBJECT "${CMAKE_C_COMPILER} -o -c ") endif(CLR_CMAKE_HOST_OS STREQUAL Darwin) diff --git a/eng/native/gen-buildsys.sh b/eng/native/gen-buildsys.sh index 1b4c2e02c597f..9e166550616f6 100755 --- a/eng/native/gen-buildsys.sh +++ b/eng/native/gen-buildsys.sh @@ -63,7 +63,9 @@ done cmake_extra_defines= if [[ "$CROSSCOMPILE" == "1" ]]; then - if ! [[ -n "$ROOTFS_DIR" ]]; then + platform="$(uname)" + # OSX doesn't use rootfs + if ! [[ -n "$ROOTFS_DIR" || "$platform" == "Darwin" ]]; then echo "ROOTFS_DIR not set for crosscompile" exit 1 fi @@ -74,7 +76,12 @@ if [[ "$CROSSCOMPILE" == "1" ]]; then if [[ -n "$tryrun_dir" ]]; then cmake_extra_defines="$cmake_extra_defines -C $tryrun_dir/tryrun.cmake" fi - cmake_extra_defines="$cmake_extra_defines -DCMAKE_TOOLCHAIN_FILE=$scriptroot/../common/cross/toolchain.cmake" + + if [[ "$platform" == "Darwin" ]]; then + cmake_extra_defines="$cmake_extra_defines -DCMAKE_SYSTEM_NAME=Darwin" + else + cmake_extra_defines="$cmake_extra_defines -DCMAKE_TOOLCHAIN_FILE=$scriptroot/../common/cross/toolchain.cmake" + fi fi if [[ "$build_arch" == "armel" ]]; then diff --git a/src/coreclr/build-runtime.sh b/src/coreclr/build-runtime.sh index 1e19028dceced..ada2e03016b5e 100755 --- a/src/coreclr/build-runtime.sh +++ b/src/coreclr/build-runtime.sh @@ -97,19 +97,7 @@ build_cross_architecture_components() CROSSCOMPILE=0 export __CMakeBinDir CROSSCOMPILE - __CMakeArgs="-DCLR_CMAKE_TARGET_ARCH=$__BuildArch -DCLR_CROSS_COMPONENTS_BUILD=1 $__CMakeArgs" - if [[ "$__TargetOS" == OSX ]]; then - if [[ "$__CrossArch" == x64 ]]; then - __CMakeArgs="-DCMAKE_OSX_ARCHITECTURES=\"x86_64\" $__CMakeArgs" - elif [[ "$__CrossArch" == arm64 ]]; then - __CMakeArgs="-DCMAKE_OSX_ARCHITECTURES=\"arm64\" $__CMakeArgs" - else - echo "Error: Unknown OSX architecture $__BuildArch." - exit 1 - fi - fi - - build_native "$__CrossArch" "$__ProjectRoot" "$__ProjectRoot" "$intermediatesForBuild" "cross-architecture components" + build_native "$__TargetOS" "$__CrossArch" "$__ProjectRoot" "$__ProjectRoot" "$intermediatesForBuild" "$__CMakeArgs" "cross-architecture components" CROSSCOMPILE=1 export CROSSCOMPILE @@ -202,11 +190,11 @@ __BuildJit=1 __BuildAllJits=1 __BuildRuntime=1 -source "$__ProjectRoot"/_build-commons.sh +#if [[ "${__BuildArch}" != "${__HostArch}" && "${__BuildOS}" == "OSX" ]]; then +# __CrossBuild=1 +#fi -if [[ "${__BuildArch}" != "${__HostArch}" ]]; then - __CrossBuild=1 -fi +source "$__ProjectRoot"/_build-commons.sh # Set dependent variables @@ -263,21 +251,10 @@ if [[ "$__SkipConfigure" == 0 && "$__CodeCoverage" == 1 ]]; then __CMakeArgs="-DCLR_CMAKE_ENABLE_CODE_COVERAGE=1 $__CMakeArgs" fi -if [[ "$__TargetOS" == OSX ]]; then - if [[ "$__BuildArch" == x64 ]]; then - __CMakeArgs="-DCMAKE_OSX_ARCHITECTURES=\"x86_64\" $__CMakeArgs" - elif [[ "$__BuildArch" == arm64 ]]; then - __CMakeArgs="-DCMAKE_OSX_ARCHITECTURES=\"arm64\" $__CMakeArgs" - else - echo "Error: Unknown OSX architecture $__BuildArch." - exit 1 - fi -fi - if [[ "$__SkipNative" == 1 ]]; then echo "Skipping CoreCLR component build." else - build_native "$__BuildArch" "$__ProjectRoot" "$__ProjectRoot" "$__IntermediatesDir" "CoreCLR component" + build_native "$__TargetOS" "$__BuildArch" "$__ProjectRoot" "$__ProjectRoot" "$__IntermediatesDir" "$__CMakeArgs" "CoreCLR component" # Build cross-architecture components if [[ "$__SkipCrossArchNative" != 1 ]]; then diff --git a/src/coreclr/crosscomponents.cmake b/src/coreclr/crosscomponents.cmake index b2b010fdd6659..c66531887daa0 100644 --- a/src/coreclr/crosscomponents.cmake +++ b/src/coreclr/crosscomponents.cmake @@ -23,7 +23,7 @@ if (CLR_CMAKE_HOST_OS STREQUAL CLR_CMAKE_TARGET_OS) endif(CLR_CMAKE_TARGET_UNIX) endif() -if(NOT CLR_CMAKE_HOST_LINUX AND NOT FEATURE_CROSSBITNESS) +if(NOT CLR_CMAKE_HOST_LINUX AND NOT CLR_CMAKE_HOST_OSX AND NOT FEATURE_CROSSBITNESS) list (APPEND CLR_CROSS_COMPONENTS_LIST mscordaccore mscordbi diff --git a/src/coreclr/src/gc/unix/config.gc.h.in b/src/coreclr/src/gc/unix/config.gc.h.in index 42b6429be80e5..e633193218a2d 100644 --- a/src/coreclr/src/gc/unix/config.gc.h.in +++ b/src/coreclr/src/gc/unix/config.gc.h.in @@ -16,7 +16,7 @@ #cmakedefine01 HAVE_SWAPCTL #cmakedefine01 HAVE_SYSCTLBYNAME #cmakedefine01 HAVE_PTHREAD_CONDATTR_SETCLOCK -#cmakedefine01 HAVE_MACH_ABSOLUTE_TIME +#cmakedefine01 HAVE_CLOCK_GETTIME_NSEC_NP #cmakedefine01 HAVE_SCHED_GETAFFINITY #cmakedefine01 HAVE_SCHED_SETAFFINITY #cmakedefine01 HAVE_PTHREAD_SETAFFINITY_NP diff --git a/src/coreclr/src/gc/unix/configure.cmake b/src/coreclr/src/gc/unix/configure.cmake index 6d190a8c46735..54c3d0f899d9c 100644 --- a/src/coreclr/src/gc/unix/configure.cmake +++ b/src/coreclr/src/gc/unix/configure.cmake @@ -72,17 +72,15 @@ check_cxx_source_runs(" check_library_exists(pthread pthread_condattr_setclock "" HAVE_PTHREAD_CONDATTR_SETCLOCK) check_cxx_source_runs(" - #include - #include - int main() - { - int ret; - mach_timebase_info_data_t timebaseInfo; - ret = mach_timebase_info(&timebaseInfo); - mach_absolute_time(); - exit(ret); - } - " HAVE_MACH_ABSOLUTE_TIME) +#include +#include + +int main() +{ + int ret; + ret = clock_gettime_nsec_np(CLOCK_UPTIME_RAW); + exit((ret == 0) ? 1 : 0); +}" HAVE_CLOCK_GETTIME_NSEC_NP) check_library_exists(c sched_getaffinity "" HAVE_SCHED_GETAFFINITY) diff --git a/src/coreclr/src/gc/unix/events.cpp b/src/coreclr/src/gc/unix/events.cpp index 88797741fa7ea..7cc55680aaf2f 100644 --- a/src/coreclr/src/gc/unix/events.cpp +++ b/src/coreclr/src/gc/unix/events.cpp @@ -16,10 +16,6 @@ #include "gcenv.os.h" #include "globals.h" -#if HAVE_MACH_ABSOLUTE_TIME -mach_timebase_info_data_t g_TimebaseInfo; -#endif // MACH_ABSOLUTE_TIME - namespace { @@ -37,7 +33,7 @@ void TimeSpecAdd(timespec* time, uint32_t milliseconds) } #endif // HAVE_PTHREAD_CONDATTR_SETCLOCK -#if HAVE_MACH_ABSOLUTE_TIME +#if HAVE_CLOCK_GETTIME_NSEC_NP // Convert nanoseconds to the timespec structure // Parameters: // nanoseconds - time in nanoseconds to convert @@ -47,7 +43,7 @@ void NanosecondsToTimeSpec(uint64_t nanoseconds, timespec* t) t->tv_sec = nanoseconds / tccSecondsToNanoSeconds; t->tv_nsec = nanoseconds % tccSecondsToNanoSeconds; } -#endif // HAVE_PTHREAD_CONDATTR_SETCLOCK +#endif // HAVE_CLOCK_GETTIME_NSEC_NP } // anonymous namespace @@ -81,7 +77,7 @@ class GCEvent::Impl // TODO(segilles) implement this for CoreCLR //PthreadCondAttrHolder attrsHolder(&attrs); -#if HAVE_PTHREAD_CONDATTR_SETCLOCK && !HAVE_MACH_ABSOLUTE_TIME +#if HAVE_PTHREAD_CONDATTR_SETCLOCK && !HAVE_CLOCK_GETTIME_NSEC_NP // Ensure that the pthread_cond_timedwait will use CLOCK_MONOTONIC st = pthread_condattr_setclock(&attrs, CLOCK_MONOTONIC); if (st != 0) @@ -89,7 +85,7 @@ class GCEvent::Impl assert(!"Failed to set UnixEvent condition variable wait clock"); return false; } -#endif // HAVE_PTHREAD_CONDATTR_SETCLOCK && !HAVE_MACH_ABSOLUTE_TIME +#endif // HAVE_PTHREAD_CONDATTR_SETCLOCK && !HAVE_CLOCK_GETTIME_NSEC_NP st = pthread_mutex_init(&m_mutex, NULL); if (st != 0) @@ -130,13 +126,12 @@ class GCEvent::Impl UNREFERENCED_PARAMETER(alertable); timespec endTime; -#if HAVE_MACH_ABSOLUTE_TIME +#if HAVE_CLOCK_GETTIME_NSEC_NP uint64_t endMachTime; if (milliseconds != INFINITE) { uint64_t nanoseconds = (uint64_t)milliseconds * tccMilliSecondsToNanoSeconds; - NanosecondsToTimeSpec(nanoseconds, &endTime); - endMachTime = mach_absolute_time() + nanoseconds * g_TimebaseInfo.denom / g_TimebaseInfo.numer; + endMachTime = clock_gettime_nsec_np(CLOCK_UPTIME_RAW) + nanoseconds; } #elif HAVE_PTHREAD_CONDATTR_SETCLOCK if (milliseconds != INFINITE) @@ -159,17 +154,17 @@ class GCEvent::Impl } else { -#if HAVE_MACH_ABSOLUTE_TIME +#if HAVE_CLOCK_GETTIME_NSEC_NP // Since OSX doesn't support CLOCK_MONOTONIC, we use relative variant of the // timed wait and we need to handle spurious wakeups properly. st = pthread_cond_timedwait_relative_np(&m_condition, &m_mutex, &endTime); if ((st == 0) && !m_state) { - uint64_t machTime = mach_absolute_time(); + uint64_t machTime = clock_gettime_nsec_np(CLOCK_UPTIME_RAW); if (machTime < endMachTime) { // The wake up was spurious, recalculate the relative endTime - uint64_t remainingNanoseconds = (endMachTime - machTime) * g_TimebaseInfo.numer / g_TimebaseInfo.denom; + uint64_t remainingNanoseconds = endMachTime - machTime; NanosecondsToTimeSpec(remainingNanoseconds, &endTime); } else @@ -180,9 +175,9 @@ class GCEvent::Impl st = ETIMEDOUT; } } -#else // HAVE_MACH_ABSOLUTE_TIME +#else // HAVE_CLOCK_GETTIME_NSEC_NP st = pthread_cond_timedwait(&m_condition, &m_mutex, &endTime); -#endif // HAVE_MACH_ABSOLUTE_TIME +#endif // HAVE_CLOCK_GETTIME_NSEC_NP // Verify that if the wait timed out, the event was not set assert((st != ETIMEDOUT) || !m_state); } diff --git a/src/coreclr/src/gc/unix/gcenv.unix.cpp b/src/coreclr/src/gc/unix/gcenv.unix.cpp index 77cb6ed374ae0..dfaf397fdf935 100644 --- a/src/coreclr/src/gc/unix/gcenv.unix.cpp +++ b/src/coreclr/src/gc/unix/gcenv.unix.cpp @@ -366,14 +366,6 @@ bool GCToOSInterface::Initialize() } } -#if HAVE_MACH_ABSOLUTE_TIME - kern_return_t machRet; - if ((machRet = mach_timebase_info(&g_TimebaseInfo)) != KERN_SUCCESS) - { - return false; - } -#endif // HAVE_MACH_ABSOLUTE_TIME - InitializeCGroup(); #if HAVE_SCHED_GETAFFINITY diff --git a/src/coreclr/src/gc/unix/globals.h b/src/coreclr/src/gc/unix/globals.h index fe0d76a36a4cd..aca43064f28c4 100644 --- a/src/coreclr/src/gc/unix/globals.h +++ b/src/coreclr/src/gc/unix/globals.h @@ -4,10 +4,6 @@ #ifndef __GLOBALS_H__ #define __GLOBALS_H__ -#if HAVE_MACH_ABSOLUTE_TIME -#include -#endif // HAVE_MACH_ABSOLUTE_TIME - const int tccSecondsToMilliSeconds = 1000; // The number of microseconds in a second. @@ -22,8 +18,4 @@ const int tccMilliSecondsToMicroSeconds = 1000; // The number of nanoseconds in a millisecond. const int tccMilliSecondsToNanoSeconds = 1000000; -#if HAVE_MACH_ABSOLUTE_TIME -extern mach_timebase_info_data_t g_TimebaseInfo; -#endif // HAVE_MACH_ABSOLUTE_TIME - #endif // __GLOBALS_H__ diff --git a/src/coreclr/src/inc/crosscomp.h b/src/coreclr/src/inc/crosscomp.h index ce494af3700d1..454e7ada956f3 100644 --- a/src/coreclr/src/inc/crosscomp.h +++ b/src/coreclr/src/inc/crosscomp.h @@ -297,6 +297,17 @@ typedef struct _T_RUNTIME_FUNCTION { } T_RUNTIME_FUNCTION, *PT_RUNTIME_FUNCTION; +#ifdef TARGET_UNIX + +typedef +EXCEPTION_DISPOSITION +(*PEXCEPTION_ROUTINE) ( + PEXCEPTION_RECORD ExceptionRecord, + ULONG64 EstablisherFrame, + PCONTEXT ContextRecord, + PVOID DispatcherContext + ); +#endif // // Define exception dispatch context structure. // @@ -348,6 +359,27 @@ typedef struct _T_KNONVOLATILE_CONTEXT_POINTERS { } T_KNONVOLATILE_CONTEXT_POINTERS, *PT_KNONVOLATILE_CONTEXT_POINTERS; +#if defined(TARGET_ARM64) && !defined(HOST_ARM64) +enum +{ + UNW_AARCH64_X19 = 19, + UNW_AARCH64_X20 = 20, + UNW_AARCH64_X21 = 21, + UNW_AARCH64_X22 = 22, + UNW_AARCH64_X23 = 23, + UNW_AARCH64_X24 = 24, + UNW_AARCH64_X25 = 25, + UNW_AARCH64_X26 = 26, + UNW_AARCH64_X27 = 27, + UNW_AARCH64_X28 = 28, + UNW_AARCH64_X29 = 29, + UNW_AARCH64_X30 = 30, + UNW_AARCH64_SP = 31, + UNW_AARCH64_PC = 32 +}; + +#endif // TARGET_ARM64 && !HOST_ARM64 + #else #define T_CONTEXT CONTEXT diff --git a/src/coreclr/src/pal/inc/pal_error.h b/src/coreclr/src/pal/inc/pal_error.h index be9350d333e93..b387e68540060 100644 --- a/src/coreclr/src/pal/inc/pal_error.h +++ b/src/coreclr/src/pal/inc/pal_error.h @@ -133,7 +133,6 @@ #define ERROR_PALINIT_INITIALIZE_MACH_EXCEPTION 65280L #define ERROR_PALINIT_PROCABORT_INITIALIZE 65281L #define ERROR_PALINIT_INITIALIZE_FLUSH_PROCESS_WRITE_BUFFERS 65282L -#define ERROR_PALINIT_TIME 65283L #define ERROR_PALINIT_MAP 65284L #define ERROR_PALINIT_VIRTUAL 65285L #define ERROR_PALINIT_SEH 65286L diff --git a/src/coreclr/src/pal/src/config.h.in b/src/coreclr/src/pal/src/config.h.in index 0319c6da77989..728c49d350ba1 100644 --- a/src/coreclr/src/pal/src/config.h.in +++ b/src/coreclr/src/pal/src/config.h.in @@ -114,7 +114,7 @@ #cmakedefine01 HAVE_WORKING_CLOCK_GETTIME #cmakedefine01 HAVE_CLOCK_MONOTONIC #cmakedefine01 HAVE_CLOCK_MONOTONIC_COARSE -#cmakedefine01 HAVE_MACH_ABSOLUTE_TIME +#cmakedefine01 HAVE_CLOCK_GETTIME_NSEC_NP #cmakedefine01 HAVE_CLOCK_THREAD_CPUTIME #cmakedefine01 HAVE_PTHREAD_CONDATTR_SETCLOCK #cmakedefine01 HAVE_MMAP_DEV_ZERO diff --git a/src/coreclr/src/pal/src/configure.cmake b/src/coreclr/src/pal/src/configure.cmake index 893f88c44f3da..03ad87e74e858 100644 --- a/src/coreclr/src/pal/src/configure.cmake +++ b/src/coreclr/src/pal/src/configure.cmake @@ -44,7 +44,6 @@ check_include_files(runetype.h HAVE_RUNETYPE_H) check_include_files(semaphore.h HAVE_SEMAPHORE_H) check_include_files(sys/prctl.h HAVE_PRCTL_H) check_include_files(numa.h HAVE_NUMA_H) -check_include_files(pthread_np.h HAVE_PTHREAD_NP_H) check_include_files("sys/auxv.h;asm/hwcap.h" HAVE_AUXV_HWCAP_H) check_include_files("sys/ptrace.h" HAVE_SYS_PTRACE_H) check_symbol_exists(getauxval sys/auxv.h HAVE_GETAUXVAL) @@ -446,16 +445,14 @@ set(CMAKE_REQUIRED_LIBRARIES) check_cxx_source_runs(" #include -#include +#include int main() { int ret; - mach_timebase_info_data_t timebaseInfo; - ret = mach_timebase_info(&timebaseInfo); - mach_absolute_time(); - exit(ret); -}" HAVE_MACH_ABSOLUTE_TIME) + ret = clock_gettime_nsec_np(CLOCK_UPTIME_RAW); + exit((ret == 0) ? 1 : 0); +}" HAVE_CLOCK_GETTIME_NSEC_NP) set(CMAKE_REQUIRED_LIBRARIES ${CMAKE_RT_LIBS}) check_cxx_source_runs(" diff --git a/src/coreclr/src/pal/src/exception/remote-unwind.cpp b/src/coreclr/src/pal/src/exception/remote-unwind.cpp index 53b50c3b963c3..4f045e7701758 100644 --- a/src/coreclr/src/pal/src/exception/remote-unwind.cpp +++ b/src/coreclr/src/pal/src/exception/remote-unwind.cpp @@ -75,6 +75,11 @@ SET_DEFAULT_DEBUG_CHANNEL(EXCEPT); #define TRACE_VERBOSE +#include "crosscomp.h" + +#define KNONVOLATILE_CONTEXT_POINTERS T_KNONVOLATILE_CONTEXT_POINTERS +#define CONTEXT T_CONTEXT + #else // HOST_UNIX #include @@ -1567,19 +1572,19 @@ static void GetContextPointer(unw_cursor_t *cursor, unw_context_t *unwContext, i static void GetContextPointers(unw_cursor_t *cursor, unw_context_t *unwContext, KNONVOLATILE_CONTEXT_POINTERS *contextPointers) { -#if (defined(HOST_UNIX) && defined(HOST_AMD64)) || (defined(HOST_WINDOWS) && defined(TARGET_AMD64)) +#if (defined(HOST_UNIX) && defined(TARGET_AMD64)) || (defined(HOST_WINDOWS) && defined(TARGET_AMD64)) GetContextPointer(cursor, unwContext, UNW_X86_64_RBP, &contextPointers->Rbp); GetContextPointer(cursor, unwContext, UNW_X86_64_RBX, &contextPointers->Rbx); GetContextPointer(cursor, unwContext, UNW_X86_64_R12, &contextPointers->R12); GetContextPointer(cursor, unwContext, UNW_X86_64_R13, &contextPointers->R13); GetContextPointer(cursor, unwContext, UNW_X86_64_R14, &contextPointers->R14); GetContextPointer(cursor, unwContext, UNW_X86_64_R15, &contextPointers->R15); -#elif (defined(HOST_UNIX) && defined(HOST_X86)) || (defined(HOST_WINDOWS) && defined(TARGET_X86)) +#elif (defined(HOST_UNIX) && defined(TARGET_X86)) || (defined(HOST_WINDOWS) && defined(TARGET_X86)) GetContextPointer(cursor, unwContext, UNW_X86_EBX, &contextPointers->Ebx); GetContextPointer(cursor, unwContext, UNW_X86_EBP, &contextPointers->Ebp); GetContextPointer(cursor, unwContext, UNW_X86_ESI, &contextPointers->Esi); GetContextPointer(cursor, unwContext, UNW_X86_EDI, &contextPointers->Edi); -#elif (defined(HOST_UNIX) && defined(HOST_ARM)) || (defined(HOST_WINDOWS) && defined(TARGET_ARM)) +#elif (defined(HOST_UNIX) && defined(TARGET_ARM)) || (defined(HOST_WINDOWS) && defined(TARGET_ARM)) GetContextPointer(cursor, unwContext, UNW_ARM_R4, &contextPointers->R4); GetContextPointer(cursor, unwContext, UNW_ARM_R5, &contextPointers->R5); GetContextPointer(cursor, unwContext, UNW_ARM_R6, &contextPointers->R6); @@ -1588,7 +1593,7 @@ static void GetContextPointers(unw_cursor_t *cursor, unw_context_t *unwContext, GetContextPointer(cursor, unwContext, UNW_ARM_R9, &contextPointers->R9); GetContextPointer(cursor, unwContext, UNW_ARM_R10, &contextPointers->R10); GetContextPointer(cursor, unwContext, UNW_ARM_R11, &contextPointers->R11); -#elif (defined(HOST_UNIX) && defined(HOST_ARM64)) || (defined(HOST_WINDOWS) && defined(TARGET_ARM64)) +#elif (defined(HOST_UNIX) && defined(TARGET_ARM64)) || (defined(HOST_WINDOWS) && defined(TARGET_ARM64)) GetContextPointer(cursor, unwContext, UNW_AARCH64_X19, &contextPointers->X19); GetContextPointer(cursor, unwContext, UNW_AARCH64_X20, &contextPointers->X20); GetContextPointer(cursor, unwContext, UNW_AARCH64_X21, &contextPointers->X21); @@ -1607,7 +1612,7 @@ static void GetContextPointers(unw_cursor_t *cursor, unw_context_t *unwContext, static void UnwindContextToContext(unw_cursor_t *cursor, CONTEXT *winContext) { -#if (defined(HOST_UNIX) && defined(HOST_AMD64)) || (defined(HOST_WINDOWS) && defined(TARGET_AMD64)) +#if (defined(HOST_UNIX) && defined(TARGET_AMD64)) || (defined(HOST_WINDOWS) && defined(TARGET_AMD64)) unw_get_reg(cursor, UNW_REG_IP, (unw_word_t *) &winContext->Rip); unw_get_reg(cursor, UNW_REG_SP, (unw_word_t *) &winContext->Rsp); unw_get_reg(cursor, UNW_X86_64_RBP, (unw_word_t *) &winContext->Rbp); @@ -1616,14 +1621,14 @@ static void UnwindContextToContext(unw_cursor_t *cursor, CONTEXT *winContext) unw_get_reg(cursor, UNW_X86_64_R13, (unw_word_t *) &winContext->R13); unw_get_reg(cursor, UNW_X86_64_R14, (unw_word_t *) &winContext->R14); unw_get_reg(cursor, UNW_X86_64_R15, (unw_word_t *) &winContext->R15); -#elif (defined(HOST_UNIX) && defined(HOST_X86)) || (defined(HOST_WINDOWS) && defined(TARGET_X86)) +#elif (defined(HOST_UNIX) && defined(TARGET_X86)) || (defined(HOST_WINDOWS) && defined(TARGET_X86)) unw_get_reg(cursor, UNW_REG_IP, (unw_word_t *) &winContext->Eip); unw_get_reg(cursor, UNW_REG_SP, (unw_word_t *) &winContext->Esp); unw_get_reg(cursor, UNW_X86_EBP, (unw_word_t *) &winContext->Ebp); unw_get_reg(cursor, UNW_X86_EBX, (unw_word_t *) &winContext->Ebx); unw_get_reg(cursor, UNW_X86_ESI, (unw_word_t *) &winContext->Esi); unw_get_reg(cursor, UNW_X86_EDI, (unw_word_t *) &winContext->Edi); -#elif (defined(HOST_UNIX) && defined(HOST_ARM)) || (defined(HOST_WINDOWS) && defined(TARGET_ARM)) +#elif (defined(HOST_UNIX) && defined(TARGET_ARM)) || (defined(HOST_WINDOWS) && defined(TARGET_ARM)) unw_get_reg(cursor, UNW_REG_IP, (unw_word_t *) &winContext->Pc); unw_get_reg(cursor, UNW_REG_SP, (unw_word_t *) &winContext->Sp); unw_get_reg(cursor, UNW_ARM_R4, (unw_word_t *) &winContext->R4); @@ -1636,7 +1641,7 @@ static void UnwindContextToContext(unw_cursor_t *cursor, CONTEXT *winContext) unw_get_reg(cursor, UNW_ARM_R11, (unw_word_t *) &winContext->R11); unw_get_reg(cursor, UNW_ARM_R14, (unw_word_t *) &winContext->Lr); TRACE("sp %p pc %p lr %p\n", winContext->Sp, winContext->Pc, winContext->Lr); -#elif (defined(HOST_UNIX) && defined(HOST_ARM64)) || (defined(HOST_WINDOWS) && defined(TARGET_ARM64)) +#elif (defined(HOST_UNIX) && defined(TARGET_ARM64)) || (defined(HOST_WINDOWS) && defined(TARGET_ARM64)) unw_get_reg(cursor, UNW_REG_IP, (unw_word_t *) &winContext->Pc); unw_get_reg(cursor, UNW_REG_SP, (unw_word_t *) &winContext->Sp); unw_get_reg(cursor, UNW_AARCH64_X19, (unw_word_t *) &winContext->X19); @@ -1697,7 +1702,7 @@ access_reg(unw_addr_space_t as, unw_regnum_t regnum, unw_word_t *valp, int write switch (regnum) { -#if (defined(HOST_UNIX) && defined(HOST_AMD64)) || (defined(HOST_WINDOWS) && defined(TARGET_AMD64)) +#if (defined(HOST_UNIX) && defined(TARGET_AMD64)) || (defined(HOST_WINDOWS) && defined(TARGET_AMD64)) case UNW_REG_IP: *valp = (unw_word_t)winContext->Rip; break; case UNW_REG_SP: *valp = (unw_word_t)winContext->Rsp; break; case UNW_X86_64_RBP: *valp = (unw_word_t)winContext->Rbp; break; @@ -1706,14 +1711,14 @@ access_reg(unw_addr_space_t as, unw_regnum_t regnum, unw_word_t *valp, int write case UNW_X86_64_R13: *valp = (unw_word_t)winContext->R13; break; case UNW_X86_64_R14: *valp = (unw_word_t)winContext->R14; break; case UNW_X86_64_R15: *valp = (unw_word_t)winContext->R15; break; -#elif (defined(HOST_UNIX) && defined(HOST_X86)) || (defined(HOST_WINDOWS) && defined(TARGET_X86)) +#elif (defined(HOST_UNIX) && defined(TARGET_X86)) || (defined(HOST_WINDOWS) && defined(TARGET_X86)) case UNW_REG_IP: *valp = (unw_word_t)winContext->Eip; break; case UNW_REG_SP: *valp = (unw_word_t)winContext->Esp; break; case UNW_X86_EBX: *valp = (unw_word_t)winContext->Ebx; break; case UNW_X86_ESI: *valp = (unw_word_t)winContext->Esi; break; case UNW_X86_EDI: *valp = (unw_word_t)winContext->Edi; break; case UNW_X86_EBP: *valp = (unw_word_t)winContext->Ebp; break; -#elif (defined(HOST_UNIX) && defined(HOST_ARM)) || (defined(HOST_WINDOWS) && defined(TARGET_ARM)) +#elif (defined(HOST_UNIX) && defined(TARGET_ARM)) || (defined(HOST_WINDOWS) && defined(TARGET_ARM)) case UNW_ARM_R4: *valp = (unw_word_t)winContext->R4; break; case UNW_ARM_R5: *valp = (unw_word_t)winContext->R5; break; case UNW_ARM_R6: *valp = (unw_word_t)winContext->R6; break; @@ -1725,7 +1730,7 @@ access_reg(unw_addr_space_t as, unw_regnum_t regnum, unw_word_t *valp, int write case UNW_ARM_R13: *valp = (unw_word_t)winContext->Sp; break; case UNW_ARM_R14: *valp = (unw_word_t)winContext->Lr; break; case UNW_ARM_R15: *valp = (unw_word_t)winContext->Pc; break; -#elif (defined(HOST_UNIX) && defined(HOST_ARM64)) || (defined(HOST_WINDOWS) && defined(TARGET_ARM64)) +#elif (defined(HOST_UNIX) && defined(TARGET_ARM64)) || (defined(HOST_WINDOWS) && defined(TARGET_ARM64)) case UNW_AARCH64_X19: *valp = (unw_word_t)winContext->X19; break; case UNW_AARCH64_X20: *valp = (unw_word_t)winContext->X20; break; case UNW_AARCH64_X21: *valp = (unw_word_t)winContext->X21; break; diff --git a/src/coreclr/src/pal/src/include/pal/misc.h b/src/coreclr/src/pal/src/include/pal/misc.h index 1a555f4fb2bb2..aa5b2b4852b6e 100644 --- a/src/coreclr/src/pal/src/include/pal/misc.h +++ b/src/coreclr/src/pal/src/include/pal/misc.h @@ -42,17 +42,6 @@ Function : --*/ PAL_time_t __cdecl PAL_time(PAL_time_t*); -/*++ -Function: -TIMEInitialize - -Return value: -TRUE if initialize succeeded -FALSE otherwise - ---*/ -BOOL TIMEInitialize( void ); - /*++ Function : MsgBoxInitialize diff --git a/src/coreclr/src/pal/src/init/pal.cpp b/src/coreclr/src/pal/src/init/pal.cpp index 0b4876eb0a551..488ff6a4d79bc 100644 --- a/src/coreclr/src/pal/src/init/pal.cpp +++ b/src/coreclr/src/pal/src/init/pal.cpp @@ -626,13 +626,6 @@ Initialize( palError = ERROR_GEN_FAILURE; - if (FALSE == TIMEInitialize()) - { - ERROR("Unable to initialize TIME support\n"); - palError = ERROR_PALINIT_TIME; - goto CLEANUP6; - } - /* Initialize the File mapping critical section. */ if (FALSE == MAPInitialize()) { diff --git a/src/coreclr/src/pal/src/libunwind_mac/src/missing-functions.c b/src/coreclr/src/pal/src/libunwind_mac/src/missing-functions.c index 1da065c051e40..b4d8d0a2ff77d 100644 --- a/src/coreclr/src/pal/src/libunwind_mac/src/missing-functions.c +++ b/src/coreclr/src/pal/src/libunwind_mac/src/missing-functions.c @@ -51,9 +51,9 @@ int unw_is_signal_frame (unw_cursor_t *cursor) { struct cursor *c = (struct cursor *) cursor; -#ifdef TARGET_AMD64 +#ifdef HOST_AMD64 return c->sigcontext_format != X86_64_SCF_NONE; -#elif defined(TARGET_ARM64) +#elif defined(HOST_ARM64) return c->sigcontext_format != AARCH64_SCF_NONE; #else #error Unexpected target diff --git a/src/coreclr/src/pal/src/map/virtual.cpp b/src/coreclr/src/pal/src/map/virtual.cpp index 7e337b9edeb5e..456254bdbbb9a 100644 --- a/src/coreclr/src/pal/src/map/virtual.cpp +++ b/src/coreclr/src/pal/src/map/virtual.cpp @@ -1760,7 +1760,7 @@ VirtualProtect( return bRetVal; } -#if defined(TARGET_OSX) && defined(TARGET_ARM64) +#if defined(HOST_OSX) && defined(HOST_ARM64) bool PAL_JITWriteEnableHolder::JITWriteEnable(bool writeEnable) { diff --git a/src/coreclr/src/pal/src/misc/time.cpp b/src/coreclr/src/pal/src/misc/time.cpp index 0d56e411e4ccc..ec71e5c72b06c 100644 --- a/src/coreclr/src/pal/src/misc/time.cpp +++ b/src/coreclr/src/pal/src/misc/time.cpp @@ -27,45 +27,10 @@ Module Name: #include #include -#if HAVE_MACH_ABSOLUTE_TIME -#include -static mach_timebase_info_data_t s_TimebaseInfo; -#endif - using namespace CorUnix; SET_DEFAULT_DEBUG_CHANNEL(MISC); -/*++ -Function : -TIMEInitialize - -Initialize all Time-related stuff related - -(no parameters) - -Return value : -TRUE if Time support initialization succeeded -FALSE otherwise ---*/ -BOOL TIMEInitialize(void) -{ - BOOL retval = TRUE; - -#if HAVE_MACH_ABSOLUTE_TIME - kern_return_t result = mach_timebase_info(&s_TimebaseInfo); - - if (result != KERN_SUCCESS) - { - ASSERT("mach_timebase_info() failed: %s\n", mach_error_string(result)); - retval = FALSE; - } -#endif - - return retval; -} - - /*++ Function: GetSystemTime @@ -203,8 +168,8 @@ QueryPerformanceCounter( PERF_ENTRY(QueryPerformanceCounter); ENTRY("QueryPerformanceCounter()\n"); -#if HAVE_MACH_ABSOLUTE_TIME - lpPerformanceCount->QuadPart = (LONGLONG)mach_absolute_time(); +#if HAVE_CLOCK_GETTIME_NSEC_NP + lpPerformanceCount->QuadPart = (LONGLONG)clock_gettime_nsec_np(CLOCK_UPTIME_RAW); #elif HAVE_CLOCK_MONOTONIC struct timespec ts; int result = clock_gettime(CLOCK_MONOTONIC, &ts); @@ -238,21 +203,8 @@ QueryPerformanceFrequency( PERF_ENTRY(QueryPerformanceFrequency); ENTRY("QueryPerformanceFrequency()\n"); -#if HAVE_MACH_ABSOLUTE_TIME - // use denom == 0 to indicate that s_TimebaseInfo is uninitialised. - if (s_TimebaseInfo.denom == 0) - { - ASSERT("s_TimebaseInfo is uninitialized.\n"); - retval = FALSE; - } - else - { - // (numer / denom) gives you the nanoseconds per tick, so the below code - // computes the number of ticks per second. We explicitly do the multiplication - // first in order to help minimize the error that is produced by integer division. - - lpFrequency->QuadPart = ((LONGLONG)(tccSecondsToNanoSeconds) * (LONGLONG)(s_TimebaseInfo.denom)) / (LONGLONG)(s_TimebaseInfo.numer); - } +#if HAVE_CLOCK_GETTIME_NSEC_NP + lpFrequency->QuadPart = (LONGLONG)(tccSecondsToNanoSeconds); #elif HAVE_CLOCK_MONOTONIC // clock_gettime() returns a result in terms of nanoseconds rather than a count. This // means that we need to either always scale the result by the actual resolution (to @@ -323,17 +275,8 @@ GetTickCount64() { LONGLONG retval = 0; -#if HAVE_MACH_ABSOLUTE_TIME - // use denom == 0 to indicate that s_TimebaseInfo is uninitialised. - if (s_TimebaseInfo.denom == 0) - { - ASSERT("s_TimebaseInfo is uninitialized.\n"); - retval = FALSE; - } - else - { - retval = ((LONGLONG)mach_absolute_time() * (LONGLONG)(s_TimebaseInfo.numer)) / ((LONGLONG)(tccMillieSecondsToNanoSeconds) * (LONGLONG)(s_TimebaseInfo.denom)); - } +#if HAVE_CLOCK_GETTIME_NSEC_NP + return (LONGLONG)clock_gettime_nsec_np(CLOCK_UPTIME_RAW) / (LONGLONG)(tccMillieSecondsToNanoSeconds); #elif HAVE_CLOCK_MONOTONIC || HAVE_CLOCK_MONOTONIC_COARSE struct timespec ts; diff --git a/src/coreclr/tryrun.cmake b/src/coreclr/tryrun.cmake index a70a7b6936bab..6abee4c3f3fff 100644 --- a/src/coreclr/tryrun.cmake +++ b/src/coreclr/tryrun.cmake @@ -18,9 +18,55 @@ elseif(EXISTS ${CROSS_ROOTFS}/bin/freebsd-version) elseif(EXISTS ${CROSS_ROOTFS}/usr/platform/i86pc) set(ILLUMOS 1) set(CLR_CMAKE_TARGET_OS SunOS) +elseif(EXISTS /System/Library/CoreServices) + set(DARWIN 1) endif() -if(TARGET_ARCH_NAME MATCHES "^(armel|arm|arm64|x86)$" OR FREEBSD OR ILLUMOS) +if(DARWIN) + if(TARGET_ARCH_NAME STREQUAL "arm64") + set_cache_value(FILE_OPS_CHECK_FERROR_OF_PREVIOUS_CALL_EXITCODE 1) + set_cache_value(GETPWUID_R_SETS_ERRNO_EXITCODE 1) + set_cache_value(HAS_POSIX_SEMAPHORES_EXITCODE 1) + set_cache_value(HAVE_BROKEN_FIFO_KEVENT_EXITCODE 1) + set_cache_value(HAVE_BROKEN_FIFO_SELECT_EXITCODE 1) + set_cache_value(HAVE_CLOCK_MONOTONIC_COARSE_EXITCODE 1) + set_cache_value(HAVE_CLOCK_MONOTONIC_EXITCODE 0) + set_cache_value(HAVE_CLOCK_THREAD_CPUTIME_EXITCODE 0) + set_cache_value(HAVE_CLOCK_GETTIME_NSEC_NP_EXITCODE 0) + set_cache_value(HAVE_COMPATIBLE_ACOS_EXITCODE 0) + set_cache_value(HAVE_COMPATIBLE_ASIN_EXITCODE 0) + set_cache_value(HAVE_COMPATIBLE_ATAN2_EXITCODE 0) + set_cache_value(HAVE_COMPATIBLE_EXP_EXITCODE 1) + set_cache_value(HAVE_COMPATIBLE_ILOGB0_EXITCODE 0) + set_cache_value(HAVE_COMPATIBLE_ILOGBNAN_EXITCODE 1) + set_cache_value(HAVE_COMPATIBLE_LOG10_EXITCODE 0) + set_cache_value(HAVE_COMPATIBLE_LOG_EXITCODE 0) + set_cache_value(HAVE_COMPATIBLE_POW_EXITCODE 0) + set_cache_value(HAVE_FUNCTIONAL_PTHREAD_ROBUST_MUTEXES_EXITCODE 1) + set_cache_value(HAVE_LARGE_SNPRINTF_SUPPORT_EXITCODE 0) + set_cache_value(HAVE_MMAP_DEV_ZERO_EXITCODE 1) + set_cache_value(HAVE_PROCFS_CTL_EXITCODE 1) + set_cache_value(HAVE_PROCFS_MAPS_EXITCODE 1) + set_cache_value(HAVE_PROCFS_STATUS_EXITCODE 1) + set_cache_value(HAVE_PROCFS_STAT_EXITCODE 1) + set_cache_value(HAVE_SCHED_GETCPU_EXITCODE 1) + set_cache_value(HAVE_SCHED_GET_PRIORITY_EXITCODE 0) + set_cache_value(HAVE_VALID_NEGATIVE_INF_POW_EXITCODE 0) + set_cache_value(HAVE_VALID_POSITIVE_INF_POW_EXITCODE 0) + set_cache_value(HAVE_WORKING_CLOCK_GETTIME_EXITCODE 0) + set_cache_value(HAVE_WORKING_GETTIMEOFDAY_EXITCODE 0) + set_cache_value(MMAP_ANON_IGNORES_PROTECTION_EXITCODE 1) + set_cache_value(ONE_SHARED_MAPPING_PER_FILEREGION_PER_PROCESS_EXITCODE 1) + set_cache_value(PTHREAD_CREATE_MODIFIES_ERRNO_EXITCODE 1) + set_cache_value(REALPATH_SUPPORTS_NONEXISTENT_FILES_EXITCODE 1) + set_cache_value(SEM_INIT_MODIFIES_ERRNO_EXITCODE 1) + set_cache_value(SSCANF_CANNOT_HANDLE_MISSING_EXPONENT_EXITCODE 1) + set_cache_value(SSCANF_SUPPORT_ll_EXITCODE 0) + set_cache_value(UNGETC_NOT_RETURN_EOF_EXITCODE 1) + else() + message(FATAL_ERROR "Arch is ${TARGET_ARCH_NAME}. Only arm64 is supported for OSX cross build!") + endif() +elseif(TARGET_ARCH_NAME MATCHES "^(armel|arm|arm64|x86)$" OR FREEBSD OR ILLUMOS) set_cache_value(FILE_OPS_CHECK_FERROR_OF_PREVIOUS_CALL_EXITCODE 1) set_cache_value(GETPWUID_R_SETS_ERRNO_EXITCODE 0) set_cache_value(HAS_POSIX_SEMAPHORES_EXITCODE 0) From 0e611032e6b4dfa1dbe93ef19354d92118697e63 Mon Sep 17 00:00:00 2001 From: Jan Vorlicek Date: Fri, 18 Sep 2020 01:26:21 +0200 Subject: [PATCH 77/89] Fix JIT bug --- src/coreclr/src/jit/emitarm.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/coreclr/src/jit/emitarm.cpp b/src/coreclr/src/jit/emitarm.cpp index 3d3168b0c51f2..27a7131f271fd 100644 --- a/src/coreclr/src/jit/emitarm.cpp +++ b/src/coreclr/src/jit/emitarm.cpp @@ -5550,7 +5550,7 @@ BYTE* emitter::emitOutputShortBranch(BYTE* dst, instruction ins, insFormat fmt, else if (fmt == IF_T1_I) { assert(id != NULL); - assert(ins == INS_cbz || INS_cbnz); + assert(ins == INS_cbz || ins == INS_cbnz); assert((distVal & 1) == 0); assert(distVal >= 0); assert(distVal <= 126); From ef57726486d5cc056e6477cbc3e3a5e9d43737df Mon Sep 17 00:00:00 2001 From: Jan Vorlicek Date: Fri, 18 Sep 2020 03:42:45 -0700 Subject: [PATCH 78/89] Fix shell build scripts --- src/coreclr/build-runtime.sh | 1 + src/installer/corehost/build.sh | 13 +------------ src/libraries/Native/build-native.sh | 10 +--------- 3 files changed, 3 insertions(+), 21 deletions(-) diff --git a/src/coreclr/build-runtime.sh b/src/coreclr/build-runtime.sh index ada2e03016b5e..ae477fc35eeac 100755 --- a/src/coreclr/build-runtime.sh +++ b/src/coreclr/build-runtime.sh @@ -97,6 +97,7 @@ build_cross_architecture_components() CROSSCOMPILE=0 export __CMakeBinDir CROSSCOMPILE + __CMakeArgs="-DCLR_CMAKE_TARGET_ARCH=$__BuildArch -DCLR_CROSS_COMPONENTS_BUILD=1 $__CMakeArgs" build_native "$__TargetOS" "$__CrossArch" "$__ProjectRoot" "$__ProjectRoot" "$intermediatesForBuild" "$__CMakeArgs" "cross-architecture components" CROSSCOMPILE=1 diff --git a/src/installer/corehost/build.sh b/src/installer/corehost/build.sh index 9d81e15853e1f..c87e98c679327 100755 --- a/src/installer/corehost/build.sh +++ b/src/installer/corehost/build.sh @@ -93,17 +93,6 @@ __CMakeArgs="-DCLI_CMAKE_HOST_VER=\"$__host_ver\" -DCLI_CMAKE_COMMON_HOST_VER=\" __CMakeArgs="-DCLI_CMAKE_HOST_POLICY_VER=\"$__policy_ver\" -DCLI_CMAKE_PKG_RID=\"$__DistroRid\" -DCLI_CMAKE_COMMIT_HASH=\"$__commit_hash\" $__CMakeArgs" __CMakeArgs="-DCORECLR_ARTIFACTS=\"$__CoreClrArtifacts\" -DNATIVE_LIBS_ARTIFACTS=\"$__NativeLibsArtifacts\" $__CMakeArgs" -if [[ "$__TargetOS" == OSX ]]; then - if [[ "$__BuildArch" == x64 ]]; then - __CMakeArgs="-DCMAKE_OSX_ARCHITECTURES=\"x86_64\" $__CMakeArgs" - elif [[ "$__BuildArch" == arm64 ]]; then - __CMakeArgs="-DCMAKE_OSX_ARCHITECTURES=\"arm64\" $__CMakeArgs" - else - echo "Error: Unknown OSX architecture $__BuildArch." - exit 1 - fi -fi - if [[ "$__PortableBuild" == 1 ]]; then __CMakeArgs="-DCLI_CMAKE_PORTABLE_BUILD=1 $__CMakeArgs" fi @@ -120,4 +109,4 @@ setup_dirs check_prereqs # Build the installer native components. -build_native "$__BuildArch" "$__scriptpath" "$__scriptpath" "$__IntermediatesDir" "installer component" +build_native "$__TargetOS" "$__BuildArch" "$__scriptpath" "$__scriptpath" "$__IntermediatesDir" "$__CMakeArgs" "installer component" diff --git a/src/libraries/Native/build-native.sh b/src/libraries/Native/build-native.sh index 4fa1fc12ad025..440ddd643bb1b 100755 --- a/src/libraries/Native/build-native.sh +++ b/src/libraries/Native/build-native.sh @@ -78,14 +78,6 @@ fi if [[ "$__TargetOS" == OSX ]]; then # set default OSX deployment target __CMakeArgs="-DCMAKE_OSX_DEPLOYMENT_TARGET=10.13 $__CMakeArgs" - if [[ "$__BuildArch" == x64 ]]; then - __CMakeArgs="-DCMAKE_OSX_ARCHITECTURES=\"x86_64\" $__CMakeArgs" - elif [[ "$__BuildArch" == arm64 ]]; then - __CMakeArgs="-DCMAKE_OSX_ARCHITECTURES=\"arm64\" $__CMakeArgs" - else - echo "Error: Unknown OSX architecture $__BuildArch." - exit 1 - fi elif [[ "$__TargetOS" == Android && -z "$ROOTFS_DIR" ]]; then if [[ -z "$ANDROID_NDK_ROOT" ]]; then echo "Error: You need to set the ANDROID_NDK_ROOT environment variable pointing to the Android NDK root." @@ -165,4 +157,4 @@ setup_dirs check_prereqs # Build the corefx native components. -build_native "$__BuildArch" "$__nativeroot" "$__nativeroot" "$__IntermediatesDir" "native libraries component" +build_native "$__TargetOS" "$__BuildArch" "$__nativeroot" "$__nativeroot" "$__IntermediatesDir" "$__CMakeArgs" "native libraries component" From 9667e8c5a321c926733a01938fd2b4aa7e6b6b1f Mon Sep 17 00:00:00 2001 From: Steve MacLean Date: Mon, 21 Sep 2020 13:13:15 -0400 Subject: [PATCH 79/89] Remove stray comment --- src/coreclr/build-runtime.sh | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/coreclr/build-runtime.sh b/src/coreclr/build-runtime.sh index 151662a82efec..a2e7313f4f3db 100755 --- a/src/coreclr/build-runtime.sh +++ b/src/coreclr/build-runtime.sh @@ -196,10 +196,6 @@ __BuildPALTests=0 __BuildAllJits=1 __BuildRuntime=1 -#if [[ "${__BuildArch}" != "${__HostArch}" && "${__BuildOS}" == "OSX" ]]; then -# __CrossBuild=1 -#fi - source "$__ProjectRoot"/_build-commons.sh # Set dependent variables From c5cee94521813540042c523f31358b88b037a9a4 Mon Sep 17 00:00:00 2001 From: Steve MacLean Date: Mon, 21 Sep 2020 13:18:58 -0400 Subject: [PATCH 80/89] Fix SSLSetEnabledCiphers call --- .../Unix/System.Security.Cryptography.Native.Apple/pal_ssl.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libraries/Native/Unix/System.Security.Cryptography.Native.Apple/pal_ssl.c b/src/libraries/Native/Unix/System.Security.Cryptography.Native.Apple/pal_ssl.c index 78497cefb3946..ac0d06b172a48 100644 --- a/src/libraries/Native/Unix/System.Security.Cryptography.Native.Apple/pal_ssl.c +++ b/src/libraries/Native/Unix/System.Security.Cryptography.Native.Apple/pal_ssl.c @@ -594,7 +594,7 @@ int32_t AppleCryptoNative_SslSetEnabledCipherSuites(SSLContextRef sslContext, co #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wdeprecated-declarations" // macOS - return SSLSetEnabledCiphers(sslContext, cipherSuites, (size_t)numCipherSuites); + return SSLSetEnabledCiphers(sslContext, (const SSLCipherSuite *)cipherSuites, (size_t)numCipherSuites); #pragma clang diagnostic pop } else From bcdc03273adf2236478541980dd5bd887a58ed7f Mon Sep 17 00:00:00 2001 From: Steve MacLean Date: Tue, 22 Sep 2020 14:20:37 -0400 Subject: [PATCH 81/89] Fix test build script --- src/tests/build.sh | 13 +------------ 1 file changed, 1 insertion(+), 12 deletions(-) diff --git a/src/tests/build.sh b/src/tests/build.sh index 89b787e7bb55e..c3de6c9505fc6 100755 --- a/src/tests/build.sh +++ b/src/tests/build.sh @@ -368,18 +368,7 @@ build_Tests() fi if [[ "$__SkipNative" != 1 && "$__BuildArch" != "wasm" ]]; then - if [[ "$__TargetOS" == OSX ]]; then - if [[ "$__BuildArch" == x64 ]]; then - __CMakeArgs="-DCMAKE_OSX_ARCHITECTURES=\"x86_64\" $__CMakeArgs" - elif [[ "$__BuildArch" == arm64 ]]; then - __CMakeArgs="-DCMAKE_OSX_ARCHITECTURES=\"arm64\" $__CMakeArgs" - else - echo "Error: Unknown OSX architecture $__BuildArch." - exit 1 - fi - fi - - build_native "$__BuildArch" "$__TestDir" "$__TryRunDir" "$__NativeTestIntermediatesDir" "CoreCLR test component" + build_native "$__TargetOS" "$__BuildArch" "$__TestDir" "$__TryRunDir" "$__NativeTestIntermediatesDir" "CoreCLR test component" if [[ "$?" -ne 0 ]]; then echo "${__ErrMsgPrefix}${__MsgPrefix}Error: native test build failed. Refer to the build log files for details (above)" From 260b5dd6e8adfa82b248ff9146815b34ee47018d Mon Sep 17 00:00:00 2001 From: Steve MacLean Date: Thu, 24 Sep 2020 14:30:31 -0700 Subject: [PATCH 82/89] Fix x64 cross compile --- src/coreclr/tryrun.cmake | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/coreclr/tryrun.cmake b/src/coreclr/tryrun.cmake index 6abee4c3f3fff..4b23122b91c2b 100644 --- a/src/coreclr/tryrun.cmake +++ b/src/coreclr/tryrun.cmake @@ -23,7 +23,7 @@ elseif(EXISTS /System/Library/CoreServices) endif() if(DARWIN) - if(TARGET_ARCH_NAME STREQUAL "arm64") + if(TARGET_ARCH_NAME MATCHES "^(arm64|x64)$") set_cache_value(FILE_OPS_CHECK_FERROR_OF_PREVIOUS_CALL_EXITCODE 1) set_cache_value(GETPWUID_R_SETS_ERRNO_EXITCODE 1) set_cache_value(HAS_POSIX_SEMAPHORES_EXITCODE 1) @@ -64,7 +64,7 @@ if(DARWIN) set_cache_value(SSCANF_SUPPORT_ll_EXITCODE 0) set_cache_value(UNGETC_NOT_RETURN_EOF_EXITCODE 1) else() - message(FATAL_ERROR "Arch is ${TARGET_ARCH_NAME}. Only arm64 is supported for OSX cross build!") + message(FATAL_ERROR "Arch is ${TARGET_ARCH_NAME}. Only arm64 or x64 is supported for OSX cross build!") endif() elseif(TARGET_ARCH_NAME MATCHES "^(armel|arm|arm64|x86)$" OR FREEBSD OR ILLUMOS) set_cache_value(FILE_OPS_CHECK_FERROR_OF_PREVIOUS_CALL_EXITCODE 1) From 271d396c8607e03eb18827f30318d11e9182e2ac Mon Sep 17 00:00:00 2001 From: Steve MacLean Date: Thu, 24 Sep 2020 18:26:44 -0400 Subject: [PATCH 83/89] Move remote-unwind to coreclrpal_dac library for Unix --- src/coreclr/src/dlls/mscordac/CMakeLists.txt | 4 ++-- src/coreclr/src/pal/src/CMakeLists.txt | 24 +++++++++---------- .../src/pal/src/exception/remote-unwind.cpp | 24 +++++++++---------- 3 files changed, 25 insertions(+), 27 deletions(-) diff --git a/src/coreclr/src/dlls/mscordac/CMakeLists.txt b/src/coreclr/src/dlls/mscordac/CMakeLists.txt index f1acbdce5f907..be18d5e4bf6cb 100644 --- a/src/coreclr/src/dlls/mscordac/CMakeLists.txt +++ b/src/coreclr/src/dlls/mscordac/CMakeLists.txt @@ -179,11 +179,11 @@ if(CLR_CMAKE_HOST_WIN32 AND CLR_CMAKE_TARGET_UNIX) ) endif(CLR_CMAKE_HOST_WIN32 AND CLR_CMAKE_TARGET_UNIX) -if(CLR_CMAKE_HOST_OSX) +if(CLR_CMAKE_HOST_UNIX) list(APPEND COREDAC_LIBRARIES coreclrpal_dac ) -endif(CLR_CMAKE_HOST_OSX) +endif(CLR_CMAKE_HOST_UNIX) target_link_libraries(mscordaccore PRIVATE ${COREDAC_LIBRARIES}) diff --git a/src/coreclr/src/pal/src/CMakeLists.txt b/src/coreclr/src/pal/src/CMakeLists.txt index c4d32de8cd8b3..dd6fb75347720 100644 --- a/src/coreclr/src/pal/src/CMakeLists.txt +++ b/src/coreclr/src/pal/src/CMakeLists.txt @@ -221,12 +221,6 @@ set(SOURCES thread/threadsusp.cpp ) -if(NOT CLR_CMAKE_TARGET_OSX) - list(APPEND SOURCES - exception/remote-unwind.cpp - ) -endif(NOT CLR_CMAKE_TARGET_OSX) - if(NOT CLR_CMAKE_USE_SYSTEM_LIBUNWIND) set(LIBUNWIND_OBJECTS $) endif(NOT CLR_CMAKE_USE_SYSTEM_LIBUNWIND) @@ -252,16 +246,20 @@ if(CLR_CMAKE_TARGET_OSX) "-D_XOPEN_SOURCE" "-DUNW_REMOTE_ONLY" ) - - target_include_directories(coreclrpal_dac PUBLIC - ${CMAKE_CURRENT_SOURCE_DIR}/libunwind/include - ${CMAKE_CURRENT_SOURCE_DIR}/libunwind/include/tdep - ${CMAKE_CURRENT_BINARY_DIR} - ${CMAKE_CURRENT_BINARY_DIR}/libunwind/include - ${CMAKE_CURRENT_BINARY_DIR}/libunwind/include/tdep +else() + add_library(coreclrpal_dac STATIC + exception/remote-unwind.cpp ) endif(CLR_CMAKE_TARGET_OSX) +target_include_directories(coreclrpal_dac PUBLIC + ${CMAKE_CURRENT_SOURCE_DIR}/libunwind/include + ${CMAKE_CURRENT_SOURCE_DIR}/libunwind/include/tdep + ${CMAKE_CURRENT_BINARY_DIR} + ${CMAKE_CURRENT_BINARY_DIR}/libunwind/include + ${CMAKE_CURRENT_BINARY_DIR}/libunwind/include/tdep +) + # There is only one function exported in 'tracepointprovider.cpp' namely 'PAL_InitializeTracing', # which is guarded with '#if defined(__linux__)'. On macOS, Xcode issues the following warning: # diff --git a/src/coreclr/src/pal/src/exception/remote-unwind.cpp b/src/coreclr/src/pal/src/exception/remote-unwind.cpp index 4f045e7701758..4226e55097ca3 100644 --- a/src/coreclr/src/pal/src/exception/remote-unwind.cpp +++ b/src/coreclr/src/pal/src/exception/remote-unwind.cpp @@ -1572,19 +1572,19 @@ static void GetContextPointer(unw_cursor_t *cursor, unw_context_t *unwContext, i static void GetContextPointers(unw_cursor_t *cursor, unw_context_t *unwContext, KNONVOLATILE_CONTEXT_POINTERS *contextPointers) { -#if (defined(HOST_UNIX) && defined(TARGET_AMD64)) || (defined(HOST_WINDOWS) && defined(TARGET_AMD64)) +#if defined(TARGET_AMD64) GetContextPointer(cursor, unwContext, UNW_X86_64_RBP, &contextPointers->Rbp); GetContextPointer(cursor, unwContext, UNW_X86_64_RBX, &contextPointers->Rbx); GetContextPointer(cursor, unwContext, UNW_X86_64_R12, &contextPointers->R12); GetContextPointer(cursor, unwContext, UNW_X86_64_R13, &contextPointers->R13); GetContextPointer(cursor, unwContext, UNW_X86_64_R14, &contextPointers->R14); GetContextPointer(cursor, unwContext, UNW_X86_64_R15, &contextPointers->R15); -#elif (defined(HOST_UNIX) && defined(TARGET_X86)) || (defined(HOST_WINDOWS) && defined(TARGET_X86)) +#elif defined(TARGET_X86) GetContextPointer(cursor, unwContext, UNW_X86_EBX, &contextPointers->Ebx); GetContextPointer(cursor, unwContext, UNW_X86_EBP, &contextPointers->Ebp); GetContextPointer(cursor, unwContext, UNW_X86_ESI, &contextPointers->Esi); GetContextPointer(cursor, unwContext, UNW_X86_EDI, &contextPointers->Edi); -#elif (defined(HOST_UNIX) && defined(TARGET_ARM)) || (defined(HOST_WINDOWS) && defined(TARGET_ARM)) +#elif defined(TARGET_ARM) GetContextPointer(cursor, unwContext, UNW_ARM_R4, &contextPointers->R4); GetContextPointer(cursor, unwContext, UNW_ARM_R5, &contextPointers->R5); GetContextPointer(cursor, unwContext, UNW_ARM_R6, &contextPointers->R6); @@ -1593,7 +1593,7 @@ static void GetContextPointers(unw_cursor_t *cursor, unw_context_t *unwContext, GetContextPointer(cursor, unwContext, UNW_ARM_R9, &contextPointers->R9); GetContextPointer(cursor, unwContext, UNW_ARM_R10, &contextPointers->R10); GetContextPointer(cursor, unwContext, UNW_ARM_R11, &contextPointers->R11); -#elif (defined(HOST_UNIX) && defined(TARGET_ARM64)) || (defined(HOST_WINDOWS) && defined(TARGET_ARM64)) +#elif defined(TARGET_ARM64) GetContextPointer(cursor, unwContext, UNW_AARCH64_X19, &contextPointers->X19); GetContextPointer(cursor, unwContext, UNW_AARCH64_X20, &contextPointers->X20); GetContextPointer(cursor, unwContext, UNW_AARCH64_X21, &contextPointers->X21); @@ -1612,7 +1612,7 @@ static void GetContextPointers(unw_cursor_t *cursor, unw_context_t *unwContext, static void UnwindContextToContext(unw_cursor_t *cursor, CONTEXT *winContext) { -#if (defined(HOST_UNIX) && defined(TARGET_AMD64)) || (defined(HOST_WINDOWS) && defined(TARGET_AMD64)) +#if defined(TARGET_AMD64) unw_get_reg(cursor, UNW_REG_IP, (unw_word_t *) &winContext->Rip); unw_get_reg(cursor, UNW_REG_SP, (unw_word_t *) &winContext->Rsp); unw_get_reg(cursor, UNW_X86_64_RBP, (unw_word_t *) &winContext->Rbp); @@ -1621,14 +1621,14 @@ static void UnwindContextToContext(unw_cursor_t *cursor, CONTEXT *winContext) unw_get_reg(cursor, UNW_X86_64_R13, (unw_word_t *) &winContext->R13); unw_get_reg(cursor, UNW_X86_64_R14, (unw_word_t *) &winContext->R14); unw_get_reg(cursor, UNW_X86_64_R15, (unw_word_t *) &winContext->R15); -#elif (defined(HOST_UNIX) && defined(TARGET_X86)) || (defined(HOST_WINDOWS) && defined(TARGET_X86)) +#elif defined(TARGET_X86) unw_get_reg(cursor, UNW_REG_IP, (unw_word_t *) &winContext->Eip); unw_get_reg(cursor, UNW_REG_SP, (unw_word_t *) &winContext->Esp); unw_get_reg(cursor, UNW_X86_EBP, (unw_word_t *) &winContext->Ebp); unw_get_reg(cursor, UNW_X86_EBX, (unw_word_t *) &winContext->Ebx); unw_get_reg(cursor, UNW_X86_ESI, (unw_word_t *) &winContext->Esi); unw_get_reg(cursor, UNW_X86_EDI, (unw_word_t *) &winContext->Edi); -#elif (defined(HOST_UNIX) && defined(TARGET_ARM)) || (defined(HOST_WINDOWS) && defined(TARGET_ARM)) +#elif defined(TARGET_ARM) unw_get_reg(cursor, UNW_REG_IP, (unw_word_t *) &winContext->Pc); unw_get_reg(cursor, UNW_REG_SP, (unw_word_t *) &winContext->Sp); unw_get_reg(cursor, UNW_ARM_R4, (unw_word_t *) &winContext->R4); @@ -1641,7 +1641,7 @@ static void UnwindContextToContext(unw_cursor_t *cursor, CONTEXT *winContext) unw_get_reg(cursor, UNW_ARM_R11, (unw_word_t *) &winContext->R11); unw_get_reg(cursor, UNW_ARM_R14, (unw_word_t *) &winContext->Lr); TRACE("sp %p pc %p lr %p\n", winContext->Sp, winContext->Pc, winContext->Lr); -#elif (defined(HOST_UNIX) && defined(TARGET_ARM64)) || (defined(HOST_WINDOWS) && defined(TARGET_ARM64)) +#elif defined(TARGET_ARM64) unw_get_reg(cursor, UNW_REG_IP, (unw_word_t *) &winContext->Pc); unw_get_reg(cursor, UNW_REG_SP, (unw_word_t *) &winContext->Sp); unw_get_reg(cursor, UNW_AARCH64_X19, (unw_word_t *) &winContext->X19); @@ -1702,7 +1702,7 @@ access_reg(unw_addr_space_t as, unw_regnum_t regnum, unw_word_t *valp, int write switch (regnum) { -#if (defined(HOST_UNIX) && defined(TARGET_AMD64)) || (defined(HOST_WINDOWS) && defined(TARGET_AMD64)) +#if defined(TARGET_AMD64) case UNW_REG_IP: *valp = (unw_word_t)winContext->Rip; break; case UNW_REG_SP: *valp = (unw_word_t)winContext->Rsp; break; case UNW_X86_64_RBP: *valp = (unw_word_t)winContext->Rbp; break; @@ -1711,14 +1711,14 @@ access_reg(unw_addr_space_t as, unw_regnum_t regnum, unw_word_t *valp, int write case UNW_X86_64_R13: *valp = (unw_word_t)winContext->R13; break; case UNW_X86_64_R14: *valp = (unw_word_t)winContext->R14; break; case UNW_X86_64_R15: *valp = (unw_word_t)winContext->R15; break; -#elif (defined(HOST_UNIX) && defined(TARGET_X86)) || (defined(HOST_WINDOWS) && defined(TARGET_X86)) +#elif defined(TARGET_X86) case UNW_REG_IP: *valp = (unw_word_t)winContext->Eip; break; case UNW_REG_SP: *valp = (unw_word_t)winContext->Esp; break; case UNW_X86_EBX: *valp = (unw_word_t)winContext->Ebx; break; case UNW_X86_ESI: *valp = (unw_word_t)winContext->Esi; break; case UNW_X86_EDI: *valp = (unw_word_t)winContext->Edi; break; case UNW_X86_EBP: *valp = (unw_word_t)winContext->Ebp; break; -#elif (defined(HOST_UNIX) && defined(TARGET_ARM)) || (defined(HOST_WINDOWS) && defined(TARGET_ARM)) +#elif defined(TARGET_ARM) case UNW_ARM_R4: *valp = (unw_word_t)winContext->R4; break; case UNW_ARM_R5: *valp = (unw_word_t)winContext->R5; break; case UNW_ARM_R6: *valp = (unw_word_t)winContext->R6; break; @@ -1730,7 +1730,7 @@ access_reg(unw_addr_space_t as, unw_regnum_t regnum, unw_word_t *valp, int write case UNW_ARM_R13: *valp = (unw_word_t)winContext->Sp; break; case UNW_ARM_R14: *valp = (unw_word_t)winContext->Lr; break; case UNW_ARM_R15: *valp = (unw_word_t)winContext->Pc; break; -#elif (defined(HOST_UNIX) && defined(TARGET_ARM64)) || (defined(HOST_WINDOWS) && defined(TARGET_ARM64)) +#elif defined(TARGET_ARM64) case UNW_AARCH64_X19: *valp = (unw_word_t)winContext->X19; break; case UNW_AARCH64_X20: *valp = (unw_word_t)winContext->X20; break; case UNW_AARCH64_X21: *valp = (unw_word_t)winContext->X21; break; From 78d00a2ab663c55af626216416ef9e4c886bbb35 Mon Sep 17 00:00:00 2001 From: Steve MacLean Date: Mon, 28 Sep 2020 15:41:51 -0400 Subject: [PATCH 84/89] Disable coreclrpal_dac in cross bit compiles --- src/coreclr/src/pal/src/CMakeLists.txt | 24 ++++++++++++++---------- 1 file changed, 14 insertions(+), 10 deletions(-) diff --git a/src/coreclr/src/pal/src/CMakeLists.txt b/src/coreclr/src/pal/src/CMakeLists.txt index dd6fb75347720..4d4839675db0d 100644 --- a/src/coreclr/src/pal/src/CMakeLists.txt +++ b/src/coreclr/src/pal/src/CMakeLists.txt @@ -247,18 +247,22 @@ if(CLR_CMAKE_TARGET_OSX) "-DUNW_REMOTE_ONLY" ) else() - add_library(coreclrpal_dac STATIC - exception/remote-unwind.cpp - ) + if(NOT FEATURE_CROSSBITNESS) + add_library(coreclrpal_dac STATIC + exception/remote-unwind.cpp + ) + endif(NOT FEATURE_CROSSBITNESS) endif(CLR_CMAKE_TARGET_OSX) -target_include_directories(coreclrpal_dac PUBLIC - ${CMAKE_CURRENT_SOURCE_DIR}/libunwind/include - ${CMAKE_CURRENT_SOURCE_DIR}/libunwind/include/tdep - ${CMAKE_CURRENT_BINARY_DIR} - ${CMAKE_CURRENT_BINARY_DIR}/libunwind/include - ${CMAKE_CURRENT_BINARY_DIR}/libunwind/include/tdep -) +if(NOT FEATURE_CROSSBITNESS) + target_include_directories(coreclrpal_dac PUBLIC + ${CMAKE_CURRENT_SOURCE_DIR}/libunwind/include + ${CMAKE_CURRENT_SOURCE_DIR}/libunwind/include/tdep + ${CMAKE_CURRENT_BINARY_DIR} + ${CMAKE_CURRENT_BINARY_DIR}/libunwind/include + ${CMAKE_CURRENT_BINARY_DIR}/libunwind/include/tdep + ) +endif(NOT FEATURE_CROSSBITNESS) # There is only one function exported in 'tracepointprovider.cpp' namely 'PAL_InitializeTracing', # which is guarded with '#if defined(__linux__)'. On macOS, Xcode issues the following warning: From fcf34246150d734f100f7f9a0ee676f04a950c9b Mon Sep 17 00:00:00 2001 From: Steve MacLean Date: Tue, 29 Sep 2020 15:03:40 -0400 Subject: [PATCH 85/89] Fix Windows build --- src/coreclr/src/inc/crosscomp.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/coreclr/src/inc/crosscomp.h b/src/coreclr/src/inc/crosscomp.h index 454e7ada956f3..047267f2ba3ff 100644 --- a/src/coreclr/src/inc/crosscomp.h +++ b/src/coreclr/src/inc/crosscomp.h @@ -297,7 +297,7 @@ typedef struct _T_RUNTIME_FUNCTION { } T_RUNTIME_FUNCTION, *PT_RUNTIME_FUNCTION; -#ifdef TARGET_UNIX +#ifdef HOST_UNIX typedef EXCEPTION_DISPOSITION From e186f0106acfd8ebba311581ddbc4e0877442f46 Mon Sep 17 00:00:00 2001 From: Steve MacLean Date: Tue, 29 Sep 2020 17:10:11 -0400 Subject: [PATCH 86/89] Fix arm64 crossdac build --- src/coreclr/src/inc/crosscomp.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/coreclr/src/inc/crosscomp.h b/src/coreclr/src/inc/crosscomp.h index 047267f2ba3ff..e942db59e4a63 100644 --- a/src/coreclr/src/inc/crosscomp.h +++ b/src/coreclr/src/inc/crosscomp.h @@ -359,7 +359,7 @@ typedef struct _T_KNONVOLATILE_CONTEXT_POINTERS { } T_KNONVOLATILE_CONTEXT_POINTERS, *PT_KNONVOLATILE_CONTEXT_POINTERS; -#if defined(TARGET_ARM64) && !defined(HOST_ARM64) +#if defined(HOST_UNIX) && defined(TARGET_ARM64) && !defined(HOST_ARM64) enum { UNW_AARCH64_X19 = 19, From f9b9fff32bb050d1b1da26bdc3086a2f375852ad Mon Sep 17 00:00:00 2001 From: Steve MacLean Date: Thu, 1 Oct 2020 17:32:15 -0400 Subject: [PATCH 87/89] Review feedback --- eng/native/configureplatform.cmake | 21 +++++-------------- .../src/pal/src/exception/machexception.cpp | 18 +++++++++++++++- .../src/pal/src/exception/machmessage.h | 2 +- .../src/libunwind_mac/src/missing-functions.c | 12 +++++++++-- src/coreclr/src/vm/arm64/stubs.cpp | 14 ++++++------- src/coreclr/src/vm/gcinfodecoder.cpp | 4 ++-- 6 files changed, 42 insertions(+), 29 deletions(-) diff --git a/eng/native/configureplatform.cmake b/eng/native/configureplatform.cmake index 2ee1cf27deee3..0d4ee0dae6def 100644 --- a/eng/native/configureplatform.cmake +++ b/eng/native/configureplatform.cmake @@ -78,23 +78,12 @@ endif(CLR_CMAKE_HOST_OS STREQUAL Linux) if(CLR_CMAKE_HOST_OS STREQUAL Darwin) set(CLR_CMAKE_HOST_UNIX 1) set(CLR_CMAKE_HOST_OSX 1) - if(CLR_CROSS_COMPONENTS_BUILD) - # CMAKE_HOST_SYSTEM_PROCESSOR returns the value of `uname -p` on host. - if(CMAKE_HOST_SYSTEM_PROCESSOR STREQUAL x86_64) - set(CLR_CMAKE_HOST_UNIX_AMD64 1) - elseif(CMAKE_OSX_ARCHITECTURES STREQUAL arm64) - set(CLR_CMAKE_HOST_UNIX_ARM64 1) - else() - clr_unknown_arch() - endif() + if(CMAKE_OSX_ARCHITECTURES STREQUAL x86_64) + set(CLR_CMAKE_HOST_UNIX_AMD64 1) + elseif(CMAKE_OSX_ARCHITECTURES STREQUAL arm64) + set(CLR_CMAKE_HOST_UNIX_ARM64 1) else() - if(CMAKE_OSX_ARCHITECTURES STREQUAL x86_64) - set(CLR_CMAKE_HOST_UNIX_AMD64 1) - elseif(CMAKE_OSX_ARCHITECTURES STREQUAL arm64) - set(CLR_CMAKE_HOST_UNIX_ARM64 1) - else() - clr_unknown_arch() - endif() + clr_unknown_arch() endif() set(CMAKE_ASM_COMPILE_OBJECT "${CMAKE_C_COMPILER} -o -c ") endif(CLR_CMAKE_HOST_OS STREQUAL Darwin) diff --git a/src/coreclr/src/pal/src/exception/machexception.cpp b/src/coreclr/src/pal/src/exception/machexception.cpp index a5dabace80695..53cf78535f50b 100644 --- a/src/coreclr/src/pal/src/exception/machexception.cpp +++ b/src/coreclr/src/pal/src/exception/machexception.cpp @@ -1439,6 +1439,22 @@ extern "C" void ActivationHandlerWrapper(); extern "C" int ActivationHandlerReturnOffset; extern "C" unsigned int XmmYmmStateSupport(); +#ifdef HOST_ARM64 +bool isHardwareException(uint64_t esr) +{ + // 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 = (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) +} +#endif + /*++ Function : InjectActivationInternal @@ -1497,7 +1513,7 @@ InjectActivationInternal(CPalThread* pThread) #elif defined(HOST_ARM64) // Inject the activation only if the last ESR.EC was an SVC and therefore the thread doesn't have // a pending hardware exception - if ((ExceptionState.__esr >> 26) == 0x15) + if (!isHardwareException(ExceptionState.__esr)) #else #error Unexpected architecture #endif diff --git a/src/coreclr/src/pal/src/exception/machmessage.h b/src/coreclr/src/pal/src/exception/machmessage.h index 27ed9e9243133..ff288ad6f25b2 100644 --- a/src/coreclr/src/pal/src/exception/machmessage.h +++ b/src/coreclr/src/pal/src/exception/machmessage.h @@ -67,7 +67,7 @@ using namespace CorUnix; // Debug-only output with printf-style formatting. #define NONPAL_TRACE(_format, ...) do { \ - if (NONPAL_TRACE_ENABLED) { printf("NONPAL_TRACE: " _format, ## __VA_ARGS__); fflush(stdout); } \ + if (NONPAL_TRACE_ENABLED) printf("NONPAL_TRACE: " _format, ## __VA_ARGS__); \ } while (false) #else // _DEBUG diff --git a/src/coreclr/src/pal/src/libunwind_mac/src/missing-functions.c b/src/coreclr/src/pal/src/libunwind_mac/src/missing-functions.c index b4d8d0a2ff77d..9ccb1df07b6e6 100644 --- a/src/coreclr/src/pal/src/libunwind_mac/src/missing-functions.c +++ b/src/coreclr/src/pal/src/libunwind_mac/src/missing-functions.c @@ -47,13 +47,21 @@ unw_get_accessors_int (unw_addr_space_t as) return unw_get_accessors(as); } +#if defined(TARGET_AMD64) && !defined(HOST_AMD64) +#define X86_64_SCF_NONE 0 +#endif + +#if defined(TARGET_ARM64) && !defined(HOST_ARM64) +#define AARCH64_SCF_NONE 0 +#endif + int unw_is_signal_frame (unw_cursor_t *cursor) { struct cursor *c = (struct cursor *) cursor; -#ifdef HOST_AMD64 +#ifdef TARGET_AMD64 return c->sigcontext_format != X86_64_SCF_NONE; -#elif defined(HOST_ARM64) +#elif defined(TARGET_ARM64) return c->sigcontext_format != AARCH64_SCF_NONE; #else #error Unexpected target diff --git a/src/coreclr/src/vm/arm64/stubs.cpp b/src/coreclr/src/vm/arm64/stubs.cpp index d89b9c68364f8..27943954b318a 100644 --- a/src/coreclr/src/vm/arm64/stubs.cpp +++ b/src/coreclr/src/vm/arm64/stubs.cpp @@ -1070,7 +1070,7 @@ void JIT_TailCall() #if !defined(DACCESS_COMPILE) && !defined(CROSSGEN_COMPILE) EXTERN_C void JIT_UpdateWriteBarrierState(bool skipEphemeralCheck); -static void UpdateWriteBarrierState (bool skipEphemeralCheck) +static void UpdateWriteBarrierState(bool skipEphemeralCheck) { #if defined(HOST_OSX) && defined(HOST_ARM64) auto jitWriteEnableHolder = PAL_JITWriteEnable(true); @@ -1104,12 +1104,12 @@ void InitJITHelpers1() } } - UpdateWriteBarrierState (GCHeapUtilities::IsServerHeap()); + UpdateWriteBarrierState(GCHeapUtilities::IsServerHeap()); } #else -void UpdateWriteBarrierState (bool) {} +void UpdateWriteBarrierState(bool) {} #endif // !defined(DACCESS_COMPILE) && !defined(CROSSGEN_COMPILE) PTR_CONTEXT GetCONTEXTFromRedirectedStubStackFrame(T_DISPATCHER_CONTEXT * pDispatcherContext) @@ -1278,26 +1278,26 @@ void FlushWriteBarrierInstructionCache() #ifndef CROSSGEN_COMPILE int StompWriteBarrierEphemeral(bool isRuntimeSuspended) { - UpdateWriteBarrierState (GCHeapUtilities::IsServerHeap()); + UpdateWriteBarrierState(GCHeapUtilities::IsServerHeap()); return SWB_PASS; } int StompWriteBarrierResize(bool isRuntimeSuspended, bool bReqUpperBoundsCheck) { - UpdateWriteBarrierState (GCHeapUtilities::IsServerHeap()); + UpdateWriteBarrierState(GCHeapUtilities::IsServerHeap()); return SWB_PASS; } #ifdef FEATURE_USE_SOFTWARE_WRITE_WATCH_FOR_GC_HEAP int SwitchToWriteWatchBarrier(bool isRuntimeSuspended) { - UpdateWriteBarrierState (GCHeapUtilities::IsServerHeap()); + UpdateWriteBarrierState(GCHeapUtilities::IsServerHeap()); return SWB_PASS; } int SwitchToNonWriteWatchBarrier(bool isRuntimeSuspended) { - UpdateWriteBarrierState (GCHeapUtilities::IsServerHeap()); + UpdateWriteBarrierState(GCHeapUtilities::IsServerHeap()); return SWB_PASS; } #endif // FEATURE_USE_SOFTWARE_WRITE_WATCH_FOR_GC_HEAP diff --git a/src/coreclr/src/vm/gcinfodecoder.cpp b/src/coreclr/src/vm/gcinfodecoder.cpp index 2df2fd5fb9716..52c2c3c649c0d 100644 --- a/src/coreclr/src/vm/gcinfodecoder.cpp +++ b/src/coreclr/src/vm/gcinfodecoder.cpp @@ -1709,11 +1709,11 @@ OBJECTREF* GcInfoDecoder::GetCapturedRegister( _ASSERTE(regNum >= 0 && regNum <= 30); _ASSERTE(regNum != 18); - if(regNum == 29) + if (regNum == 29) { return (OBJECTREF*) &pRD->pCurrentContext->Fp; } - else if(regNum == 30) + else if (regNum == 30) { return (OBJECTREF*) &pRD->pCurrentContext->Lr; } From d3e49f07bd8e776ebaec86bc33db1ba921ad8995 Mon Sep 17 00:00:00 2001 From: Steve MacLean Date: Tue, 6 Oct 2020 11:05:45 -0700 Subject: [PATCH 88/89] Add missing semicolon --- src/coreclr/src/pal/src/exception/machexception.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/coreclr/src/pal/src/exception/machexception.cpp b/src/coreclr/src/pal/src/exception/machexception.cpp index 53cf78535f50b..b7f77f13bcc62 100644 --- a/src/coreclr/src/pal/src/exception/machexception.cpp +++ b/src/coreclr/src/pal/src/exception/machexception.cpp @@ -1451,7 +1451,7 @@ bool isHardwareException(uint64_t esr) 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) + return (esr_ec != ESR_EC_SVC); } #endif From 0d4eba8e80c12f15aa91a8e265790566f2d22fae Mon Sep 17 00:00:00 2001 From: Steve MacLean Date: Wed, 7 Oct 2020 14:11:00 -0400 Subject: [PATCH 89/89] PR Feedback --- src/coreclr/src/gc/unix/gcenv.unix.cpp | 2 +- .../src/pal/src/exception/machexception.cpp | 25 +++++++++---------- src/coreclr/src/pal/src/misc/sysinfo.cpp | 2 +- 3 files changed, 14 insertions(+), 15 deletions(-) diff --git a/src/coreclr/src/gc/unix/gcenv.unix.cpp b/src/coreclr/src/gc/unix/gcenv.unix.cpp index dfaf397fdf935..f1e411982f766 100644 --- a/src/coreclr/src/gc/unix/gcenv.unix.cpp +++ b/src/coreclr/src/gc/unix/gcenv.unix.cpp @@ -826,7 +826,7 @@ static size_t GetLogicalProcessorCacheSizeFromOS() cacheSize = std::max(cacheSize, ( size_t) sysconf(_SC_LEVEL4_CACHE_SIZE)); #endif -#if defined(TARGET_LINUX) && !defined(HOST_ARM) && !defined(TARGET_OSX) +#if defined(TARGET_LINUX) && !defined(HOST_ARM) if (cacheSize == 0) { // diff --git a/src/coreclr/src/pal/src/exception/machexception.cpp b/src/coreclr/src/pal/src/exception/machexception.cpp index b7f77f13bcc62..442e77d4a15e2 100644 --- a/src/coreclr/src/pal/src/exception/machexception.cpp +++ b/src/coreclr/src/pal/src/exception/machexception.cpp @@ -1439,20 +1439,28 @@ extern "C" void ActivationHandlerWrapper(); extern "C" int ActivationHandlerReturnOffset; extern "C" unsigned int XmmYmmStateSupport(); -#ifdef HOST_ARM64 -bool isHardwareException(uint64_t esr) +#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 = (esr >> ESR_EC_SHIFT) & ESR_EC_MASK; + 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 /*++ @@ -1506,17 +1514,8 @@ InjectActivationInternal(CPalThread* pThread) &count); _ASSERT_MSG(MachRet == KERN_SUCCESS, "thread_get_state for *_EXCEPTION_STATE64\n"); -#if defined(HOST_AMD64) // Inject the activation only if the thread doesn't have a pending hardware exception - static const int MaxHardwareExceptionVector = 31; - if (ExceptionState.__trapno > MaxHardwareExceptionVector) -#elif defined(HOST_ARM64) - // Inject the activation only if the last ESR.EC was an SVC and therefore the thread doesn't have - // a pending hardware exception - if (!isHardwareException(ExceptionState.__esr)) -#else -#error Unexpected architecture -#endif + if (!IsHardwareException(ExceptionState)) { count = threadCount; MachRet = thread_get_state(threadPort, diff --git a/src/coreclr/src/pal/src/misc/sysinfo.cpp b/src/coreclr/src/pal/src/misc/sysinfo.cpp index 5d3985b84de64..7df3d5e34f1e5 100644 --- a/src/coreclr/src/pal/src/misc/sysinfo.cpp +++ b/src/coreclr/src/pal/src/misc/sysinfo.cpp @@ -565,7 +565,7 @@ PAL_GetLogicalProcessorCacheSizeFromOS() cacheSize = std::max(cacheSize, (size_t)sysconf(_SC_LEVEL4_CACHE_SIZE)); #endif -#if defined(TARGET_LINUX) && !defined(HOST_ARM) && !defined(TARGET_OSX) +#if defined(TARGET_LINUX) && !defined(HOST_ARM) if (cacheSize == 0) { //