From 74c15e27d55f62bb70e0b5078676d4295c5496ed Mon Sep 17 00:00:00 2001 From: Jan Vorlicek Date: Thu, 8 Jul 2021 23:39:42 +0200 Subject: [PATCH] Reflect PR feedback and fix old macOS x64 --- src/coreclr/inc/CrstTypes.def | 2 +- src/coreclr/inc/clrconfigvalues.h | 2 +- src/coreclr/inc/crsttypes.h | 40 +++++++++--------- src/coreclr/minipal/Unix/doublemapping.cpp | 41 ++++++++++++++++++- src/coreclr/minipal/Windows/doublemapping.cpp | 41 ------------------- src/coreclr/utilcode/executableallocator.cpp | 2 +- src/coreclr/vm/jitinterface.h | 37 ++++++++--------- src/coreclr/vm/threads.cpp | 18 +++++--- 8 files changed, 92 insertions(+), 91 deletions(-) diff --git a/src/coreclr/inc/CrstTypes.def b/src/coreclr/inc/CrstTypes.def index 3b67b14834e29..74b8c165ca934 100644 --- a/src/coreclr/inc/CrstTypes.def +++ b/src/coreclr/inc/CrstTypes.def @@ -202,7 +202,7 @@ Crst Exception End Crst ExecutableAllocatorLock - Unordered + AcquiredAfter LoaderHeap End Crst ExecuteManRangeLock diff --git a/src/coreclr/inc/clrconfigvalues.h b/src/coreclr/inc/clrconfigvalues.h index 1c57796cb2e39..bfd43629017a3 100644 --- a/src/coreclr/inc/clrconfigvalues.h +++ b/src/coreclr/inc/clrconfigvalues.h @@ -738,7 +738,7 @@ RETAIL_CONFIG_DWORD_INFO(UNSUPPORTED_LTTng, W("LTTng"), 1, "If COMPlus_LTTng is // // Executable code // -RETAIL_CONFIG_DWORD_INFO(EXTERNAL_EnableWXORX, W("EnableWXORX"), 1, "Enable W^X for executable memory."); +RETAIL_CONFIG_DWORD_INFO(EXTERNAL_EnableWriteXorExecute, W("EnableWriteXorExecute"), 1, "Enable W^X for executable memory."); #ifdef FEATURE_GDBJIT /// diff --git a/src/coreclr/inc/crsttypes.h b/src/coreclr/inc/crsttypes.h index 462a654a62c5f..015199f390fd0 100644 --- a/src/coreclr/inc/crsttypes.h +++ b/src/coreclr/inc/crsttypes.h @@ -151,8 +151,8 @@ int g_rgCrstLevelMap[] = 0, // CrstArgBasedStubCache 0, // CrstAssemblyList 12, // CrstAssemblyLoader - 3, // CrstAvailableClass - 4, // CrstAvailableParamTypes + 4, // CrstAvailableClass + 5, // CrstAvailableParamTypes 7, // CrstBaseDomain -1, // CrstCCompRC 13, // CrstClassFactInfoHash @@ -161,7 +161,7 @@ int g_rgCrstLevelMap[] = 6, // CrstCodeFragmentHeap 9, // CrstCodeVersioning 0, // CrstCOMCallWrapper - 4, // CrstCOMWrapperCache + 5, // CrstCOMWrapperCache 3, // CrstDataTest1 0, // CrstDataTest2 0, // CrstDbgTransport @@ -180,10 +180,10 @@ int g_rgCrstLevelMap[] = 18, // CrstEventPipe 0, // CrstEventStore 0, // CrstException - -1, // CrstExecutableAllocatorLock + 0, // CrstExecutableAllocatorLock 0, // CrstExecuteManRangeLock 0, // CrstExternalObjectContextCache - 3, // CrstFCall + 4, // CrstFCall 7, // CrstFuncPtrStubs 10, // CrstFusionAppCtx 10, // CrstGCCover @@ -198,25 +198,25 @@ int g_rgCrstLevelMap[] = 3, // CrstInlineTrackingMap 17, // CrstInstMethodHashTable 20, // CrstInterop - 4, // CrstInteropData + 5, // CrstInteropData 0, // CrstIsJMCMethod 7, // CrstISymUnmanagedReader 11, // CrstJit 0, // CrstJitGenericHandleCache 16, // CrstJitInlineTrackingMap - 3, // CrstJitPatchpoint + 4, // CrstJitPatchpoint -1, // CrstJitPerf 6, // CrstJumpStubCache 0, // CrstLeafLock -1, // CrstListLock 15, // CrstLoaderAllocator 16, // CrstLoaderAllocatorReferences - 0, // CrstLoaderHeap + 3, // CrstLoaderHeap 3, // CrstManagedObjectWrapperMap 14, // CrstMethodDescBackpatchInfoTracker - 4, // CrstModule + 5, // CrstModule 15, // CrstModuleFixup - 3, // CrstModuleLookupTable + 4, // CrstModuleLookupTable 0, // CrstMulticoreJitHash 13, // CrstMulticoreJitManager 0, // CrstNativeImageEagerFixups @@ -224,22 +224,22 @@ int g_rgCrstLevelMap[] = 0, // CrstNls 0, // CrstNotifyGdb 2, // CrstObjectList - 4, // CrstPEImage + 5, // CrstPEImage 19, // CrstPendingTypeLoadEntry - 3, // CrstPgoData + 4, // CrstPgoData 0, // CrstPinnedByrefValidation 0, // CrstProfilerGCRefDataFreeList 0, // CrstProfilingAPIStatus - 3, // CrstRCWCache + 4, // CrstRCWCache 0, // CrstRCWCleanupList 10, // CrstReadyToRunEntryPointToMethodDescMap 8, // CrstReflection 17, // CrstReJITGlobalRequest - 3, // CrstRetThunkCache + 4, // CrstRetThunkCache 3, // CrstSavedExceptionInfo 0, // CrstSaveModuleProfileData 0, // CrstSecurityStackwalkCache - 3, // CrstSigConvert + 4, // CrstSigConvert 5, // CrstSingleUseLock 0, // CrstSpecialStatics 0, // CrstStackSampler @@ -249,7 +249,7 @@ int g_rgCrstLevelMap[] = 4, // CrstStubUnwindInfoHeapSegments 3, // CrstSyncBlockCache 0, // CrstSyncHashLock - 4, // CrstSystemBaseDomain + 5, // CrstSystemBaseDomain 13, // CrstSystemDomain 0, // CrstSystemDomainDelayedUnloadList 0, // CrstThreadIdDispenser @@ -258,13 +258,13 @@ int g_rgCrstLevelMap[] = 13, // CrstThreadpoolWorker 12, // CrstThreadStore 8, // CrstTieredCompilation - 3, // CrstTypeEquivalenceMap + 4, // CrstTypeEquivalenceMap 10, // CrstTypeIDMap - 3, // CrstUMEntryThunkCache - 3, // CrstUniqueStack + 4, // CrstUMEntryThunkCache + 4, // CrstUniqueStack 7, // CrstUnresolvedClassLock 3, // CrstUnwindInfoTableLock - 3, // CrstVSDIndirectionCellLock + 4, // CrstVSDIndirectionCellLock 3, // CrstWrapperTemplate }; diff --git a/src/coreclr/minipal/Unix/doublemapping.cpp b/src/coreclr/minipal/Unix/doublemapping.cpp index 924196551e900..a50b326861aad 100644 --- a/src/coreclr/minipal/Unix/doublemapping.cpp +++ b/src/coreclr/minipal/Unix/doublemapping.cpp @@ -13,6 +13,7 @@ #include #include #include +#include #ifdef TARGET_LINUX #include #include // __NR_memfd_create @@ -77,6 +78,39 @@ void VMToOSInterface::DestroyDoubleMemoryMapper(void *mapperHandle) extern "C" void* PAL_VirtualReserveFromExecutableMemoryAllocatorWithinRange(const void* lpBeginAddress, const void* lpEndAddress, size_t dwSize); +#ifdef TARGET_OSX +bool IsMapJitFlagNeeded() +{ + static volatile int isMapJitFlagNeeded = -1; + + if (isMapJitFlagNeeded == -1) + { + int mapJitFlagCheckResult = 0; + int pageSize = sysconf(_SC_PAGE_SIZE); + // Try to map a page with read-write-execute protection. It should fail on Mojave hardened runtime and higher. + void* testPage = mmap(NULL, pageSize, PROT_READ | PROT_WRITE | PROT_EXEC, MAP_ANONYMOUS | MAP_PRIVATE, -1, 0); + if (testPage == MAP_FAILED && (errno == EACCES)) + { + // The mapping has failed with EACCES, check if making the same mapping with MAP_JIT flag works + testPage = mmap(NULL, pageSize, PROT_READ | PROT_WRITE | PROT_EXEC, MAP_ANONYMOUS | MAP_PRIVATE | MAP_JIT, -1, 0); + if (testPage != MAP_FAILED) + { + mapJitFlagCheckResult = 1; + } + } + + if (testPage != MAP_FAILED) + { + munmap(testPage, pageSize); + } + + isMapJitFlagNeeded = mapJitFlagCheckResult; + } + + return (bool)isMapJitFlagNeeded; +} +#endif // TARGET_OSX + void* VMToOSInterface::ReserveDoubleMappedMemory(void *mapperHandle, size_t offset, size_t size, const void *rangeStart, const void* rangeEnd) { int fd = (int)(size_t)mapperHandle; @@ -103,7 +137,12 @@ void* VMToOSInterface::ReserveDoubleMappedMemory(void *mapperHandle, size_t offs #ifndef TARGET_OSX void* result = mmap(NULL, size, PROT_NONE, MAP_SHARED, fd, offset); #else - void* result = mmap(NULL, size, PROT_NONE, MAP_JIT | MAP_ANON | MAP_PRIVATE, -1, 0); + int mmapFlags = MAP_ANON | MAP_PRIVATE; + if (IsMapJitFlagNeeded()) + { + mmapFlags |= MAP_JIT; + } + void* result = mmap(NULL, size, PROT_NONE, mmapFlags, -1, 0); #endif if (result == MAP_FAILED) { diff --git a/src/coreclr/minipal/Windows/doublemapping.cpp b/src/coreclr/minipal/Windows/doublemapping.cpp index 5edda681f2598..e265f1d139ad0 100644 --- a/src/coreclr/minipal/Windows/doublemapping.cpp +++ b/src/coreclr/minipal/Windows/doublemapping.cpp @@ -163,19 +163,6 @@ void* VMToOSInterface::ReserveDoubleMappedMemory(void *mapperHandle, size_t offs break; } -#ifdef _DEBUG - // if (ShouldInjectFaultInRange()) - // { - // // return nullptr (failure) - // faultInjected = true; - // break; - // } -#endif // _DEBUG - - // On UNIX we can also fail if our request size 'dwSize' is larger than 64K and - // and our tryAddr is pointing at a small MEM_FREE region (smaller than 'dwSize') - // However we can't distinguish between this and the race case. - // We might fail in a race. So just move on to next region and continue trying tryAddr = tryAddr + VIRTUAL_ALLOC_RESERVE_GRANULARITY; } @@ -187,35 +174,7 @@ void* VMToOSInterface::ReserveDoubleMappedMemory(void *mapperHandle, size_t offs } } - // STRESS_LOG7(LF_JIT, LL_INFO100, - // "ClrVirtualAllocWithinRange request #%u for %08x bytes in [ %p .. %p ], query count was %u - returned %s: %p\n", - // countOfCalls, (DWORD)dwSize, pMinAddr, pMaxAddr, - // virtualQueryCount, (pResult != nullptr) ? "success" : "failure", pResult); - - // If we failed this call the process will typically be terminated - // so we log any additional reason for failing this call. - // - if (pResult == nullptr) - { - // if ((tryAddr + dwSize) > (BYTE *)pMaxAddr) - // { - // // Our tryAddr reached pMaxAddr - // STRESS_LOG0(LF_JIT, LL_INFO100, "Additional reason: Address space exhausted.\n"); - // } - - // if (virtualQueryFailed) - // { - // STRESS_LOG0(LF_JIT, LL_INFO100, "Additional reason: VirtualQuery operation failed.\n"); - // } - - // if (faultInjected) - // { - // STRESS_LOG0(LF_JIT, LL_INFO100, "Additional reason: fault injected.\n"); - // } - } - return pResult; - } void *VMToOSInterface::CommitDoubleMappedMemory(void* pStart, size_t size, bool isExecutable) diff --git a/src/coreclr/utilcode/executableallocator.cpp b/src/coreclr/utilcode/executableallocator.cpp index 4d461e66e7e51..ac4c326c83784 100644 --- a/src/coreclr/utilcode/executableallocator.cpp +++ b/src/coreclr/utilcode/executableallocator.cpp @@ -154,7 +154,7 @@ HRESULT ExecutableAllocator::StaticInitialize(FatalErrorHandler fatalErrorHandle LIMITED_METHOD_CONTRACT; g_fatalErrorHandler = fatalErrorHandler; - g_isWXorXEnabled = CLRConfig::GetConfigValue(CLRConfig::EXTERNAL_EnableWXORX) != 0; + g_isWXorXEnabled = CLRConfig::GetConfigValue(CLRConfig::EXTERNAL_EnableWriteXorExecute) != 0; g_instance = new (nothrow) ExecutableAllocator(); if (g_instance == NULL) { diff --git a/src/coreclr/vm/jitinterface.h b/src/coreclr/vm/jitinterface.h index cf9617a353282..e071d0717d179 100644 --- a/src/coreclr/vm/jitinterface.h +++ b/src/coreclr/vm/jitinterface.h @@ -339,28 +339,25 @@ EXTERN_C FCDECL2_VV(UINT64, JIT_LRsz, UINT64 num, int shift); #ifdef TARGET_X86 +#define ENUM_X86_WRITE_BARRIER_REGISTERS() \ + X86_WRITE_BARRIER_REGISTER(EAX) \ + X86_WRITE_BARRIER_REGISTER(ECX) \ + X86_WRITE_BARRIER_REGISTER(EBX) \ + X86_WRITE_BARRIER_REGISTER(ESI) \ + X86_WRITE_BARRIER_REGISTER(EDI) \ + X86_WRITE_BARRIER_REGISTER(EBP) + extern "C" { - void STDCALL JIT_CheckedWriteBarrierEAX(); // JIThelp.asm/JIThelp.s - void STDCALL JIT_CheckedWriteBarrierEBX(); // JIThelp.asm/JIThelp.s - void STDCALL JIT_CheckedWriteBarrierECX(); // JIThelp.asm/JIThelp.s - void STDCALL JIT_CheckedWriteBarrierESI(); // JIThelp.asm/JIThelp.s - void STDCALL JIT_CheckedWriteBarrierEDI(); // JIThelp.asm/JIThelp.s - void STDCALL JIT_CheckedWriteBarrierEBP(); // JIThelp.asm/JIThelp.s - - void STDCALL JIT_DebugWriteBarrierEAX(); // JIThelp.asm/JIThelp.s - void STDCALL JIT_DebugWriteBarrierEBX(); // JIThelp.asm/JIThelp.s - void STDCALL JIT_DebugWriteBarrierECX(); // JIThelp.asm/JIThelp.s - void STDCALL JIT_DebugWriteBarrierESI(); // JIThelp.asm/JIThelp.s - void STDCALL JIT_DebugWriteBarrierEDI(); // JIThelp.asm/JIThelp.s - void STDCALL JIT_DebugWriteBarrierEBP(); // JIThelp.asm/JIThelp.s - - void STDCALL JIT_WriteBarrierEAX(); // JIThelp.asm/JIThelp.s - void STDCALL JIT_WriteBarrierEBX(); // JIThelp.asm/JIThelp.s - void STDCALL JIT_WriteBarrierECX(); // JIThelp.asm/JIThelp.s - void STDCALL JIT_WriteBarrierESI(); // JIThelp.asm/JIThelp.s - void STDCALL JIT_WriteBarrierEDI(); // JIThelp.asm/JIThelp.s - void STDCALL JIT_WriteBarrierEBP(); // JIThelp.asm/JIThelp.s + +// JIThelp.asm/JIThelp.s +#define X86_WRITE_BARRIER_REGISTER(reg) \ + void STDCALL JIT_CheckedWriteBarrier##reg(); \ + void STDCALL JIT_DebugWriteBarrier##reg(); \ + void STDCALL JIT_WriteBarrier##reg(); + + ENUM_X86_WRITE_BARRIER_REGISTERS() +#undef X86_WRITE_BARRIER_REGISTER void STDCALL JIT_WriteBarrierGroup(); void STDCALL JIT_WriteBarrierGroup_End(); diff --git a/src/coreclr/vm/threads.cpp b/src/coreclr/vm/threads.cpp index 2302617614efd..c4a16d0b04484 100644 --- a/src/coreclr/vm/threads.cpp +++ b/src/coreclr/vm/threads.cpp @@ -1177,16 +1177,20 @@ void InitThreadManager() // can jump to it. #ifdef TARGET_X86 JIT_WriteBarrierEAX_Loc = GetWriteBarrierCodeLocation((void*)JIT_WriteBarrierEAX); - SetJitHelperFunction(CORINFO_HELP_ASSIGN_REF_EAX, GetWriteBarrierCodeLocation((void*)JIT_WriteBarrierEAX)); - SetJitHelperFunction(CORINFO_HELP_ASSIGN_REF_ECX, GetWriteBarrierCodeLocation((void*)JIT_WriteBarrierECX)); - SetJitHelperFunction(CORINFO_HELP_ASSIGN_REF_EBX, GetWriteBarrierCodeLocation((void*)JIT_WriteBarrierEBX)); - SetJitHelperFunction(CORINFO_HELP_ASSIGN_REF_ESI, GetWriteBarrierCodeLocation((void*)JIT_WriteBarrierESI)); - SetJitHelperFunction(CORINFO_HELP_ASSIGN_REF_EDI, GetWriteBarrierCodeLocation((void*)JIT_WriteBarrierEDI)); - SetJitHelperFunction(CORINFO_HELP_ASSIGN_REF_EBP, GetWriteBarrierCodeLocation((void*)JIT_WriteBarrierEBP)); + +#define X86_WRITE_BARRIER_REGISTER(reg) \ + SetJitHelperFunction(CORINFO_HELP_ASSIGN_REF_##reg, GetWriteBarrierCodeLocation((void*)JIT_WriteBarrier##reg)); \ + ETW::MethodLog::StubInitialized((ULONGLONG)GetWriteBarrierCodeLocation((void*)JIT_WriteBarrier##reg), W("@WriteBarrier" #reg)); + + ENUM_X86_WRITE_BARRIER_REGISTERS() + +#undef X86_WRITE_BARRIER_REGISTER + #else // TARGET_X86 JIT_WriteBarrier_Loc = GetWriteBarrierCodeLocation((void*)JIT_WriteBarrier); #endif // TARGET_X86 SetJitHelperFunction(CORINFO_HELP_ASSIGN_REF, GetWriteBarrierCodeLocation((void*)JIT_WriteBarrier)); + ETW::MethodLog::StubInitialized((ULONGLONG)GetWriteBarrierCodeLocation((void*)JIT_WriteBarrier), W("@WriteBarrier")); #ifdef TARGET_ARM64 // Store the JIT_WriteBarrier_Table copy location to a global variable so that it can be updated. @@ -1195,7 +1199,9 @@ void InitThreadManager() #if defined(TARGET_ARM64) || defined(TARGET_ARM) SetJitHelperFunction(CORINFO_HELP_CHECKED_ASSIGN_REF, GetWriteBarrierCodeLocation((void*)JIT_CheckedWriteBarrier)); + ETW::MethodLog::StubInitialized((ULONGLONG)GetWriteBarrierCodeLocation((void*)JIT_CheckedWriteBarrier), W("@CheckedWriteBarrier")); SetJitHelperFunction(CORINFO_HELP_ASSIGN_BYREF, GetWriteBarrierCodeLocation((void*)JIT_ByRefWriteBarrier)); + ETW::MethodLog::StubInitialized((ULONGLONG)GetWriteBarrierCodeLocation((void*)JIT_ByRefWriteBarrier), W("@ByRefWriteBarrier")); #endif // TARGET_ARM64 || TARGET_ARM }