diff --git a/src/coreclr/debug/daccess/daccess.cpp b/src/coreclr/debug/daccess/daccess.cpp index 8af160fd73d064..17a327dba01d1e 100644 --- a/src/coreclr/debug/daccess/daccess.cpp +++ b/src/coreclr/debug/daccess/daccess.cpp @@ -5825,7 +5825,7 @@ ClrDataAccess::RawGetMethodName( { // Try to find matching precode entrypoint Precode* pPrecode = Precode::GetPrecodeFromEntryPoint(alignedAddress, TRUE); - if (pPrecode != NULL) + if (pPrecode != NULL && pPrecode->GetType() != PRECODE_UMENTRY_THUNK) { methodDesc = pPrecode->GetMethodDesc(); if (methodDesc != NULL) diff --git a/src/coreclr/debug/daccess/request.cpp b/src/coreclr/debug/daccess/request.cpp index 9c6669b0810f76..b6d981973a12c8 100644 --- a/src/coreclr/debug/daccess/request.cpp +++ b/src/coreclr/debug/daccess/request.cpp @@ -1783,7 +1783,6 @@ ClrDataAccess::GetModuleData(CLRDATA_ADDRESS addr, struct DacpModuleData *Module ModuleData->dwModuleIndex = 0; // CoreCLR no longer has this concept ModuleData->dwTransientFlags = pModule->m_dwTransientFlags; ModuleData->LoaderAllocator = HOST_CDADDR(pModule->m_loaderAllocator); - ModuleData->ThunkHeap = HOST_CDADDR(pModule->m_pThunkHeap); EX_TRY { diff --git a/src/coreclr/debug/runtimeinfo/datadescriptor.h b/src/coreclr/debug/runtimeinfo/datadescriptor.h index e58d91bd6cab3a..a5438b8f58738d 100644 --- a/src/coreclr/debug/runtimeinfo/datadescriptor.h +++ b/src/coreclr/debug/runtimeinfo/datadescriptor.h @@ -223,7 +223,6 @@ CDAC_TYPE_FIELD(Module, /*pointer*/, Assembly, cdac_data::Assembly) CDAC_TYPE_FIELD(Module, /*pointer*/, Base, cdac_data::Base) CDAC_TYPE_FIELD(Module, /*uint32*/, Flags, cdac_data::Flags) CDAC_TYPE_FIELD(Module, /*pointer*/, LoaderAllocator, cdac_data::LoaderAllocator) -CDAC_TYPE_FIELD(Module, /*pointer*/, ThunkHeap, cdac_data::ThunkHeap) CDAC_TYPE_FIELD(Module, /*pointer*/, DynamicMetadata, cdac_data::DynamicMetadata) CDAC_TYPE_FIELD(Module, /*pointer*/, Path, cdac_data::Path) CDAC_TYPE_FIELD(Module, /*pointer*/, FileName, cdac_data::FileName) @@ -441,7 +440,7 @@ CDAC_TYPE_END(PlatformMetadata) CDAC_TYPE_BEGIN(StubPrecodeData) CDAC_TYPE_INDETERMINATE(StubPrecodeData) -CDAC_TYPE_FIELD(StubPrecodeData, /*pointer*/, MethodDesc, offsetof(StubPrecodeData, MethodDesc)) +CDAC_TYPE_FIELD(StubPrecodeData, /*pointer*/, MethodDesc, offsetof(StubPrecodeData, SecretParam)) CDAC_TYPE_FIELD(StubPrecodeData, /*uint8*/, Type, offsetof(StubPrecodeData, Type)) CDAC_TYPE_END(StubPrecodeData) diff --git a/src/coreclr/inc/CrstTypes.def b/src/coreclr/inc/CrstTypes.def index f51399812a0826..a63679a9fe71e8 100644 --- a/src/coreclr/inc/CrstTypes.def +++ b/src/coreclr/inc/CrstTypes.def @@ -175,9 +175,6 @@ End Crst DbgTransport End -Crst DelegateToFPtrHash -End - Crst GenericDictionaryExpansion AcquiredBefore PinnedHeapHandleTable IbcProfile LoaderHeap SystemDomainDelayedUnloadList UniqueStack End diff --git a/src/coreclr/inc/crsttypes_generated.h b/src/coreclr/inc/crsttypes_generated.h index 8fde9aa204abf9..410fb884de27d9 100644 --- a/src/coreclr/inc/crsttypes_generated.h +++ b/src/coreclr/inc/crsttypes_generated.h @@ -38,88 +38,87 @@ enum CrstType CrstDebuggerHeapLock = 20, CrstDebuggerJitInfo = 21, CrstDebuggerMutex = 22, - CrstDelegateToFPtrHash = 23, - CrstDynamicIL = 24, - CrstDynamicMT = 25, - CrstEtwTypeLogHash = 26, - CrstEventPipe = 27, - CrstEventStore = 28, - CrstException = 29, - CrstExecutableAllocatorLock = 30, - CrstFCall = 31, - CrstFrozenObjectHeap = 32, - CrstFuncPtrStubs = 33, - CrstFusionAppCtx = 34, - CrstGCCover = 35, - CrstGenericDictionaryExpansion = 36, - CrstGlobalStrLiteralMap = 37, - CrstHandleTable = 38, - CrstIbcProfile = 39, - CrstIJWFixupData = 40, - CrstIJWHash = 41, - CrstILStubGen = 42, - CrstInlineTrackingMap = 43, - CrstInstMethodHashTable = 44, - CrstInterop = 45, - CrstInteropData = 46, - CrstIsJMCMethod = 47, - CrstISymUnmanagedReader = 48, - CrstJit = 49, - CrstJitInlineTrackingMap = 50, - CrstJitPatchpoint = 51, - CrstJumpStubCache = 52, - CrstLeafLock = 53, - CrstListLock = 54, - CrstLoaderAllocator = 55, - CrstLoaderAllocatorReferences = 56, - CrstLoaderHeap = 57, - CrstManagedObjectWrapperMap = 58, - CrstMethodDescBackpatchInfoTracker = 59, - CrstMethodTableExposedObject = 60, - CrstModule = 61, - CrstModuleLookupTable = 62, - CrstMulticoreJitHash = 63, - CrstMulticoreJitManager = 64, - CrstNativeImageEagerFixups = 65, - CrstNativeImageLoad = 66, - CrstNotifyGdb = 67, - CrstPEImage = 68, - CrstPendingTypeLoadEntry = 69, - CrstPerfMap = 70, - CrstPgoData = 71, - CrstPinnedByrefValidation = 72, - CrstPinnedHeapHandleTable = 73, - CrstProfilerGCRefDataFreeList = 74, - CrstProfilingAPIStatus = 75, - CrstRCWCache = 76, - CrstRCWCleanupList = 77, - CrstReadyToRunEntryPointToMethodDescMap = 78, - CrstReflection = 79, - CrstReJITGlobalRequest = 80, - CrstRetThunkCache = 81, - CrstSigConvert = 82, - CrstSingleUseLock = 83, - CrstStressLog = 84, - CrstStubCache = 85, - CrstStubDispatchCache = 86, - CrstSyncBlockCache = 87, - CrstSyncHashLock = 88, - CrstSystemDomain = 89, - CrstSystemDomainDelayedUnloadList = 90, - CrstThreadIdDispenser = 91, - CrstThreadLocalStorageLock = 92, - CrstThreadStore = 93, - CrstTieredCompilation = 94, - CrstTypeEquivalenceMap = 95, - CrstTypeIDMap = 96, - CrstUMEntryThunkCache = 97, - CrstUMEntryThunkFreeListLock = 98, - CrstUniqueStack = 99, - CrstUnresolvedClassLock = 100, - CrstUnwindInfoTableLock = 101, - CrstVSDIndirectionCellLock = 102, - CrstWrapperTemplate = 103, - kNumberOfCrstTypes = 104 + CrstDynamicIL = 23, + CrstDynamicMT = 24, + CrstEtwTypeLogHash = 25, + CrstEventPipe = 26, + CrstEventStore = 27, + CrstException = 28, + CrstExecutableAllocatorLock = 29, + CrstFCall = 30, + CrstFrozenObjectHeap = 31, + CrstFuncPtrStubs = 32, + CrstFusionAppCtx = 33, + CrstGCCover = 34, + CrstGenericDictionaryExpansion = 35, + CrstGlobalStrLiteralMap = 36, + CrstHandleTable = 37, + CrstIbcProfile = 38, + CrstIJWFixupData = 39, + CrstIJWHash = 40, + CrstILStubGen = 41, + CrstInlineTrackingMap = 42, + CrstInstMethodHashTable = 43, + CrstInterop = 44, + CrstInteropData = 45, + CrstIsJMCMethod = 46, + CrstISymUnmanagedReader = 47, + CrstJit = 48, + CrstJitInlineTrackingMap = 49, + CrstJitPatchpoint = 50, + CrstJumpStubCache = 51, + CrstLeafLock = 52, + CrstListLock = 53, + CrstLoaderAllocator = 54, + CrstLoaderAllocatorReferences = 55, + CrstLoaderHeap = 56, + CrstManagedObjectWrapperMap = 57, + CrstMethodDescBackpatchInfoTracker = 58, + CrstMethodTableExposedObject = 59, + CrstModule = 60, + CrstModuleLookupTable = 61, + CrstMulticoreJitHash = 62, + CrstMulticoreJitManager = 63, + CrstNativeImageEagerFixups = 64, + CrstNativeImageLoad = 65, + CrstNotifyGdb = 66, + CrstPEImage = 67, + CrstPendingTypeLoadEntry = 68, + CrstPerfMap = 69, + CrstPgoData = 70, + CrstPinnedByrefValidation = 71, + CrstPinnedHeapHandleTable = 72, + CrstProfilerGCRefDataFreeList = 73, + CrstProfilingAPIStatus = 74, + CrstRCWCache = 75, + CrstRCWCleanupList = 76, + CrstReadyToRunEntryPointToMethodDescMap = 77, + CrstReflection = 78, + CrstReJITGlobalRequest = 79, + CrstRetThunkCache = 80, + CrstSigConvert = 81, + CrstSingleUseLock = 82, + CrstStressLog = 83, + CrstStubCache = 84, + CrstStubDispatchCache = 85, + CrstSyncBlockCache = 86, + CrstSyncHashLock = 87, + CrstSystemDomain = 88, + CrstSystemDomainDelayedUnloadList = 89, + CrstThreadIdDispenser = 90, + CrstThreadLocalStorageLock = 91, + CrstThreadStore = 92, + CrstTieredCompilation = 93, + CrstTypeEquivalenceMap = 94, + CrstTypeIDMap = 95, + CrstUMEntryThunkCache = 96, + CrstUMEntryThunkFreeListLock = 97, + CrstUniqueStack = 98, + CrstUnresolvedClassLock = 99, + CrstUnwindInfoTableLock = 100, + CrstVSDIndirectionCellLock = 101, + CrstWrapperTemplate = 102, + kNumberOfCrstTypes = 103 }; #endif // __CRST_TYPES_INCLUDED @@ -153,7 +152,6 @@ int g_rgCrstLevelMap[] = 0, // CrstDebuggerHeapLock 3, // CrstDebuggerJitInfo 12, // CrstDebuggerMutex - 0, // CrstDelegateToFPtrHash 0, // CrstDynamicIL 9, // CrstDynamicMT 0, // CrstEtwTypeLogHash @@ -262,7 +260,6 @@ LPCSTR g_rgCrstNameMap[] = "CrstDebuggerHeapLock", "CrstDebuggerJitInfo", "CrstDebuggerMutex", - "CrstDelegateToFPtrHash", "CrstDynamicIL", "CrstDynamicMT", "CrstEtwTypeLogHash", diff --git a/src/coreclr/inc/dacvars.h b/src/coreclr/inc/dacvars.h index ffe2be90ffb8fa..7df74b3c480732 100644 --- a/src/coreclr/inc/dacvars.h +++ b/src/coreclr/inc/dacvars.h @@ -91,7 +91,6 @@ DEFINE_DACVAR(VMHELPDEF *, dac__hlpDynamicFuncTable, ::hlpDynamicFuncTable) DEFINE_DACVAR(PTR_StubManager, StubManager__g_pFirstManager, StubManager::g_pFirstManager) DEFINE_DACVAR(PTR_PrecodeStubManager, PrecodeStubManager__g_pManager, PrecodeStubManager::g_pManager) DEFINE_DACVAR(PTR_StubLinkStubManager, StubLinkStubManager__g_pManager, StubLinkStubManager::g_pManager) -DEFINE_DACVAR(PTR_ThunkHeapStubManager, ThunkHeapStubManager__g_pManager, ThunkHeapStubManager::g_pManager) DEFINE_DACVAR(PTR_JumpStubStubManager, JumpStubStubManager__g_pManager, JumpStubStubManager::g_pManager) DEFINE_DACVAR(PTR_RangeSectionStubManager, RangeSectionStubManager__g_pManager, RangeSectionStubManager::g_pManager) DEFINE_DACVAR(PTR_VirtualCallStubManagerManager, VirtualCallStubManagerManager__g_pManager, VirtualCallStubManagerManager::g_pManager) diff --git a/src/coreclr/inc/vptr_list.h b/src/coreclr/inc/vptr_list.h index 17e1867aa79b95..fd684b932bae41 100644 --- a/src/coreclr/inc/vptr_list.h +++ b/src/coreclr/inc/vptr_list.h @@ -24,7 +24,6 @@ VPTR_CLASS(ReflectionModule) VPTR_CLASS(PrecodeStubManager) VPTR_CLASS(StubLinkStubManager) VPTR_CLASS(ThePreStubManager) -VPTR_CLASS(ThunkHeapStubManager) VPTR_CLASS(VirtualCallStubManager) VPTR_CLASS(VirtualCallStubManagerManager) VPTR_CLASS(JumpStubStubManager) diff --git a/src/coreclr/vm/amd64/asmconstants.h b/src/coreclr/vm/amd64/asmconstants.h index 4b38aeeaca52d7..deea662878bf5c 100644 --- a/src/coreclr/vm/amd64/asmconstants.h +++ b/src/coreclr/vm/amd64/asmconstants.h @@ -526,8 +526,8 @@ ASMCONSTANTS_C_ASSERT(FixupPrecodeData__PrecodeFixupThunk == offsetof(FixupPreco #define StubPrecodeData__Target 0x08 ASMCONSTANTS_C_ASSERT(StubPrecodeData__Target == offsetof(StubPrecodeData, Target)) -#define StubPrecodeData__MethodDesc 0x00 -ASMCONSTANTS_C_ASSERT(StubPrecodeData__MethodDesc == offsetof(StubPrecodeData, MethodDesc)) +#define StubPrecodeData__SecretParam 0x00 +ASMCONSTANTS_C_ASSERT(StubPrecodeData__SecretParam == offsetof(StubPrecodeData, SecretParam)) #define CallCountingStubData__RemainingCallCountCell 0x00 ASMCONSTANTS_C_ASSERT(CallCountingStubData__RemainingCallCountCell == offsetof(CallCountingStubData, RemainingCallCountCell)) diff --git a/src/coreclr/vm/amd64/cgenamd64.cpp b/src/coreclr/vm/amd64/cgenamd64.cpp index 7548cd8a1742b5..c9685ff7496c5b 100644 --- a/src/coreclr/vm/amd64/cgenamd64.cpp +++ b/src/coreclr/vm/amd64/cgenamd64.cpp @@ -553,77 +553,6 @@ void emitJump(LPBYTE pBufferRX, LPBYTE pBufferRW, LPVOID target) _ASSERTE(DbgIsExecutable(pBufferRX, 12)); } -void UMEntryThunkCode::Encode(UMEntryThunkCode *pEntryThunkCodeRX, BYTE* pTargetCode, void* pvSecretParam) -{ - CONTRACTL - { - NOTHROW; - GC_NOTRIGGER; - MODE_ANY; - } - CONTRACTL_END; - - // padding // CC CC CC CC - // mov r10, pUMEntryThunk // 49 ba xx xx xx xx xx xx xx xx // METHODDESC_REGISTER - // mov rax, pJmpDest // 48 b8 xx xx xx xx xx xx xx xx // need to ensure this imm64 is qword aligned - // TAILJMP_RAX // 48 FF E0 - -#ifdef _DEBUG - m_padding[0] = X86_INSTR_INT3; - m_padding[1] = X86_INSTR_INT3; - m_padding[2] = X86_INSTR_INT3; - m_padding[3] = X86_INSTR_INT3; -#endif // _DEBUG - m_movR10[0] = REX_PREFIX_BASE | REX_OPERAND_SIZE_64BIT | REX_OPCODE_REG_EXT; - m_movR10[1] = 0xBA; - m_uet = pvSecretParam; - m_movRAX[0] = REX_PREFIX_BASE | REX_OPERAND_SIZE_64BIT; - m_movRAX[1] = 0xB8; - m_execstub = pTargetCode; - m_jmpRAX[0] = REX_PREFIX_BASE | REX_OPERAND_SIZE_64BIT; - m_jmpRAX[1] = 0xFF; - m_jmpRAX[2] = 0xE0; - - _ASSERTE(DbgIsExecutable(&pEntryThunkCodeRX->m_movR10[0], &pEntryThunkCodeRX->m_jmpRAX[3]-&pEntryThunkCodeRX->m_movR10[0])); - FlushInstructionCache(GetCurrentProcess(),pEntryThunkCodeRX,sizeof(UMEntryThunkCode)); -} - -void UMEntryThunkCode::Poison() -{ - CONTRACTL - { - NOTHROW; - GC_NOTRIGGER; - MODE_ANY; - } - CONTRACTL_END; - - ExecutableWriterHolder thunkWriterHolder(this, sizeof(UMEntryThunkCode)); - UMEntryThunkCode *pThisRW = thunkWriterHolder.GetRW(); - - pThisRW->m_execstub = (BYTE *)UMEntryThunk::ReportViolation; - - pThisRW->m_movR10[0] = REX_PREFIX_BASE | REX_OPERAND_SIZE_64BIT; -#ifdef _WIN32 - // mov rcx, pUMEntryThunk // 48 b9 xx xx xx xx xx xx xx xx - pThisRW->m_movR10[1] = 0xB9; -#else - // mov rdi, pUMEntryThunk // 48 bf xx xx xx xx xx xx xx xx - pThisRW->m_movR10[1] = 0xBF; -#endif - - ClrFlushInstructionCache(&m_movR10[0], &m_jmpRAX[3]-&m_movR10[0], /* hasCodeExecutedBefore */ true); -} - -UMEntryThunk* UMEntryThunk::Decode(LPVOID pCallback) -{ - LIMITED_METHOD_CONTRACT; - - UMEntryThunkCode *pThunkCode = (UMEntryThunkCode*)((BYTE*)pCallback - UMEntryThunkCode::GetEntryPointOffset()); - - return (UMEntryThunk*)pThunkCode->m_uet; -} - INT32 rel32UsingJumpStub(INT32 UNALIGNED * pRel32, PCODE target, MethodDesc *pMethod, LoaderAllocator *pLoaderAllocator /* = NULL */, bool throwOnOutOfMemoryWithinRange /*= true*/) { diff --git a/src/coreclr/vm/amd64/cgencpu.h b/src/coreclr/vm/amd64/cgencpu.h index a1bf37c295ab95..825b116095a76e 100644 --- a/src/coreclr/vm/amd64/cgencpu.h +++ b/src/coreclr/vm/amd64/cgencpu.h @@ -505,43 +505,6 @@ inline PCODE decodeBackToBackJump(PCODE pCode) extern "C" void setFPReturn(int fpSize, INT64 retVal); extern "C" void getFPReturn(int fpSize, INT64 *retval); - -#include -struct DECLSPEC_ALIGN(8) UMEntryThunkCode -{ - // padding // CC CC CC CC - // mov r10, pUMEntryThunk // 49 ba xx xx xx xx xx xx xx xx // METHODDESC_REGISTER - // mov rax, pJmpDest // 48 b8 xx xx xx xx xx xx xx xx // need to ensure this imm64 is qword aligned - // TAILJMP_RAX // 48 FF E0 - - BYTE m_padding[4]; - BYTE m_movR10[2]; // MOV R10, - LPVOID m_uet; // pointer to start of this structure - BYTE m_movRAX[2]; // MOV RAX, - DECLSPEC_ALIGN(8) - const BYTE* m_execstub; // pointer to destination code // ensure this is qword aligned - BYTE m_jmpRAX[3]; // JMP RAX - BYTE m_padding2[5]; - - void Encode(UMEntryThunkCode *pEntryThunkCodeRX, BYTE* pTargetCode, void* pvSecretParam); - void Poison(); - - LPCBYTE GetEntryPoint() const - { - LIMITED_METHOD_CONTRACT; - - return (LPCBYTE)&m_movR10; - } - - static int GetEntryPointOffset() - { - LIMITED_METHOD_CONTRACT; - - return offsetof(UMEntryThunkCode, m_movR10); - } -}; -#include - struct HijackArgs { #ifndef FEATURE_MULTIREG_RETURN diff --git a/src/coreclr/vm/amd64/thunktemplates.S b/src/coreclr/vm/amd64/thunktemplates.S index c13a79067cc64a..ebb0f6f67f193d 100644 --- a/src/coreclr/vm/amd64/thunktemplates.S +++ b/src/coreclr/vm/amd64/thunktemplates.S @@ -11,7 +11,7 @@ STUB_PAGE_SIZE = 16384 #define DATA_SLOT(stub, field) C_FUNC(stub##Code) + STUB_PAGE_SIZE + stub##Data__##field LEAF_ENTRY StubPrecodeCode, _TEXT - mov r10, [rip + DATA_SLOT(StubPrecode, MethodDesc)] + mov r10, [rip + DATA_SLOT(StubPrecode, SecretParam)] jmp [rip + DATA_SLOT(StubPrecode, Target)] LEAF_END_MARKED StubPrecodeCode, _TEXT diff --git a/src/coreclr/vm/amd64/thunktemplates.asm b/src/coreclr/vm/amd64/thunktemplates.asm index c841a38b4f5a30..4c462df6ea1933 100644 --- a/src/coreclr/vm/amd64/thunktemplates.asm +++ b/src/coreclr/vm/amd64/thunktemplates.asm @@ -12,7 +12,7 @@ DATA_SLOT macro stub, field endm LEAF_ENTRY StubPrecodeCode, _TEXT - mov r10, QWORD PTR [DATA_SLOT(StubPrecode, MethodDesc)] + mov r10, QWORD PTR [DATA_SLOT(StubPrecode, SecretParam)] jmp QWORD PTR [DATA_SLOT(StubPrecode, Target)] LEAF_END_MARKED StubPrecodeCode, _TEXT diff --git a/src/coreclr/vm/appdomain.cpp b/src/coreclr/vm/appdomain.cpp index 7762d755052033..1ac843760cb065 100644 --- a/src/coreclr/vm/appdomain.cpp +++ b/src/coreclr/vm/appdomain.cpp @@ -726,7 +726,6 @@ void SystemDomain::Attach() ILStubManager::Init(); InteropDispatchStubManager::Init(); StubLinkStubManager::Init(); - ThunkHeapStubManager::Init(); TailCallStubManager::Init(); #ifdef FEATURE_TIERED_COMPILATION CallCountingStubManager::Init(); diff --git a/src/coreclr/vm/arm/asmconstants.h b/src/coreclr/vm/arm/asmconstants.h index dbd83bd6a947a2..efaf4417e58b1e 100644 --- a/src/coreclr/vm/arm/asmconstants.h +++ b/src/coreclr/vm/arm/asmconstants.h @@ -192,8 +192,8 @@ ASMCONSTANTS_C_ASSERT(FixupPrecodeData__MethodDesc == offsetof(FixupPrecodeData, #define FixupPrecodeData__PrecodeFixupThunk 0x08 ASMCONSTANTS_C_ASSERT(FixupPrecodeData__PrecodeFixupThunk == offsetof(FixupPrecodeData, PrecodeFixupThunk)) -#define StubPrecodeData__MethodDesc 0x00 -ASMCONSTANTS_C_ASSERT(StubPrecodeData__MethodDesc == offsetof(StubPrecodeData, MethodDesc)) +#define StubPrecodeData__SecretParam 0x00 +ASMCONSTANTS_C_ASSERT(StubPrecodeData__SecretParam == offsetof(StubPrecodeData, SecretParam)) #define StubPrecodeData__Target 0x04 ASMCONSTANTS_C_ASSERT(StubPrecodeData__Target == offsetof(StubPrecodeData, Target)) diff --git a/src/coreclr/vm/arm/cgencpu.h b/src/coreclr/vm/arm/cgencpu.h index 864b4bd48a42f2..9d205824fc1808 100644 --- a/src/coreclr/vm/arm/cgencpu.h +++ b/src/coreclr/vm/arm/cgencpu.h @@ -914,40 +914,6 @@ class StubLinkerCPU : public StubLinker VOID EmitComputedInstantiatingMethodStub(MethodDesc* pSharedMD, struct ShuffleEntry *pShuffleEntryArray, void* extraArg); }; -#ifdef _MSC_VER -#pragma warning(push) -#pragma warning(disable:4359) // Prevent "warning C4359: 'UMEntryThunkCode': Alignment specifier is less than actual alignment (8), and will be ignored." in crossbitness scenario -#endif // _MSC_VER - -struct DECLSPEC_ALIGN(4) UMEntryThunkCode -{ - WORD m_code[4]; - - TADDR m_pTargetCode; - TADDR m_pvSecretParam; - - void Encode(UMEntryThunkCode *pEntryThunkCodeRX, BYTE* pTargetCode, void* pvSecretParam); - void Poison(); - - LPCBYTE GetEntryPoint() const - { - LIMITED_METHOD_CONTRACT; - - return (LPCBYTE)((TADDR)this | THUMB_CODE); - } - - static int GetEntryPointOffset() - { - LIMITED_METHOD_CONTRACT; - - return 0; - } -}; - -#ifdef _MSC_VER -#pragma warning(pop) -#endif // _MSC_VER - struct HijackArgs { union diff --git a/src/coreclr/vm/arm/stubs.cpp b/src/coreclr/vm/arm/stubs.cpp index 57594beb859d82..5aabcea5839ab4 100644 --- a/src/coreclr/vm/arm/stubs.cpp +++ b/src/coreclr/vm/arm/stubs.cpp @@ -1701,60 +1701,6 @@ void HijackFrame::UpdateRegDisplay(const PREGDISPLAY pRD, bool updateFloats) } #endif // FEATURE_HIJACK -class UMEntryThunk * UMEntryThunk::Decode(void *pCallback) -{ - _ASSERTE(offsetof(UMEntryThunkCode, m_code) == 0); - UMEntryThunkCode * pCode = (UMEntryThunkCode*)((ULONG_PTR)pCallback & ~THUMB_CODE); - - // We may be called with an unmanaged external code pointer instead. So if it doesn't look like one of our - // stubs (see UMEntryThunkCode::Encode below) then we'll return NULL. Luckily in these scenarios our - // caller will perform a hash lookup on successful return to verify our result in case random unmanaged - // code happens to look like ours. - if ((pCode->m_code[0] == 0xf8df) && - (pCode->m_code[1] == 0xc008) && - (pCode->m_code[2] == 0xf8df) && - (pCode->m_code[3] == 0xf000)) - { - return (UMEntryThunk*)pCode->m_pvSecretParam; - } - - return NULL; -} - -void UMEntryThunkCode::Encode(UMEntryThunkCode *pEntryThunkCodeRX, BYTE* pTargetCode, void* pvSecretParam) -{ - // ldr r12, [pc + 8] - m_code[0] = 0xf8df; - m_code[1] = 0xc008; - // ldr pc, [pc] - m_code[2] = 0xf8df; - m_code[3] = 0xf000; - - m_pTargetCode = (TADDR)pTargetCode; - m_pvSecretParam = (TADDR)pvSecretParam; - - FlushInstructionCache(GetCurrentProcess(),&pEntryThunkCodeRX->m_code,sizeof(m_code)); -} - -#ifndef DACCESS_COMPILE - -void UMEntryThunkCode::Poison() -{ - ExecutableWriterHolder thunkWriterHolder(this, sizeof(UMEntryThunkCode)); - UMEntryThunkCode *pThisRW = thunkWriterHolder.GetRW(); - - pThisRW->m_pTargetCode = (TADDR)UMEntryThunk::ReportViolation; - - // ldr r0, [pc + 8] - pThisRW->m_code[0] = 0x4802; - // nop - pThisRW->m_code[1] = 0xbf00; - - ClrFlushInstructionCache(&m_code,sizeof(m_code)); -} - -#endif // DACCESS_COMPILE - ///////////////////////////// UNIMPLEMENTED ////////////////////////////////// #ifndef DACCESS_COMPILE diff --git a/src/coreclr/vm/arm/thunktemplates.S b/src/coreclr/vm/arm/thunktemplates.S index 8744c8ebb63264..b535090660a612 100644 --- a/src/coreclr/vm/arm/thunktemplates.S +++ b/src/coreclr/vm/arm/thunktemplates.S @@ -14,7 +14,7 @@ PAGE_SIZE = 4096 #define DATA_SLOT(stub, field) . - (. - stub##Code) + PAGE_SIZE + stub##Data__##field LEAF_ENTRY StubPrecodeCode - ldr r12, DATA_SLOT(StubPrecode, MethodDesc) + ldr r12, DATA_SLOT(StubPrecode, SecretParam) ldr pc, DATA_SLOT(StubPrecode, Target) LEAF_END_MARKED StubPrecodeCode diff --git a/src/coreclr/vm/arm64/asmconstants.h b/src/coreclr/vm/arm64/asmconstants.h index 9c263b945a84f9..757d8f2aac71e3 100644 --- a/src/coreclr/vm/arm64/asmconstants.h +++ b/src/coreclr/vm/arm64/asmconstants.h @@ -223,8 +223,8 @@ ASMCONSTANTS_C_ASSERT(FixupPrecodeData__PrecodeFixupThunk == offsetof(FixupPreco #define StubPrecodeData__Target 0x08 ASMCONSTANTS_C_ASSERT(StubPrecodeData__Target == offsetof(StubPrecodeData, Target)) -#define StubPrecodeData__MethodDesc 0x00 -ASMCONSTANTS_C_ASSERT(StubPrecodeData__MethodDesc == offsetof(StubPrecodeData, MethodDesc)) +#define StubPrecodeData__SecretParam 0x00 +ASMCONSTANTS_C_ASSERT(StubPrecodeData__SecretParam == offsetof(StubPrecodeData, SecretParam)) #define CallCountingStubData__RemainingCallCountCell 0x00 ASMCONSTANTS_C_ASSERT(CallCountingStubData__RemainingCallCountCell == offsetof(CallCountingStubData, RemainingCallCountCell)) diff --git a/src/coreclr/vm/arm64/cgencpu.h b/src/coreclr/vm/arm64/cgencpu.h index f83de42fecc368..6e875ebe6c439d 100644 --- a/src/coreclr/vm/arm64/cgencpu.h +++ b/src/coreclr/vm/arm64/cgencpu.h @@ -515,31 +515,6 @@ class StubLinkerCPU : public StubLinker // preferred alignment for data #define DATA_ALIGNMENT 8 -struct DECLSPEC_ALIGN(16) UMEntryThunkCode -{ - DWORD m_code[4]; - - TADDR m_pTargetCode; - TADDR m_pvSecretParam; - - void Encode(UMEntryThunkCode *pEntryThunkCodeRX, BYTE* pTargetCode, void* pvSecretParam); - void Poison(); - - LPCBYTE GetEntryPoint() const - { - LIMITED_METHOD_CONTRACT; - - return (LPCBYTE)this; - } - - static int GetEntryPointOffset() - { - LIMITED_METHOD_CONTRACT; - - return 0; - } -}; - struct HijackArgs { DWORD64 X29; // frame pointer diff --git a/src/coreclr/vm/arm64/stubs.cpp b/src/coreclr/vm/arm64/stubs.cpp index fdc54c5815918a..41c0be5c7fdf05 100644 --- a/src/coreclr/vm/arm64/stubs.cpp +++ b/src/coreclr/vm/arm64/stubs.cpp @@ -999,62 +999,6 @@ AdjustContextForVirtualStub( } #endif // !DACCESS_COMPILE -UMEntryThunk * UMEntryThunk::Decode(void *pCallback) -{ - _ASSERTE(offsetof(UMEntryThunkCode, m_code) == 0); - UMEntryThunkCode * pCode = (UMEntryThunkCode*)pCallback; - - // We may be called with an unmanaged external code pointer instead. So if it doesn't look like one of our - // stubs (see UMEntryThunkCode::Encode below) then we'll return NULL. Luckily in these scenarios our - // caller will perform a hash lookup on successful return to verify our result in case random unmanaged - // code happens to look like ours. - if ((pCode->m_code[0] == 0x1000008c) && - (pCode->m_code[1] == 0xa9403190) && - (pCode->m_code[2] == 0xd61f0200)) - { - return (UMEntryThunk*)pCode->m_pvSecretParam; - } - - return NULL; -} - -void UMEntryThunkCode::Encode(UMEntryThunkCode *pEntryThunkCodeRX, BYTE* pTargetCode, void* pvSecretParam) -{ - // adr x12, _label - // ldp x16, x12, [x12] - // br x16 - // 4bytes padding - // _label - // m_pTargetCode data - // m_pvSecretParam data - - m_code[0] = 0x1000008c; - m_code[1] = 0xa9403190; - m_code[2] = 0xd61f0200; - - - m_pTargetCode = (TADDR)pTargetCode; - m_pvSecretParam = (TADDR)pvSecretParam; - FlushInstructionCache(GetCurrentProcess(),&pEntryThunkCodeRX->m_code,sizeof(m_code)); -} - -#ifndef DACCESS_COMPILE - -void UMEntryThunkCode::Poison() -{ - ExecutableWriterHolder thunkWriterHolder(this, sizeof(UMEntryThunkCode)); - UMEntryThunkCode *pThisRW = thunkWriterHolder.GetRW(); - - pThisRW->m_pTargetCode = (TADDR)UMEntryThunk::ReportViolation; - - // ldp x16, x0, [x12] - pThisRW->m_code[1] = 0xa9400190; - - ClrFlushInstructionCache(&m_code,sizeof(m_code)); -} - -#endif // DACCESS_COMPILE - #if !defined(DACCESS_COMPILE) VOID ResetCurrentContext() { diff --git a/src/coreclr/vm/arm64/thunktemplates.S b/src/coreclr/vm/arm64/thunktemplates.S index 5f4a728139d775..df2abf7c29e0f7 100644 --- a/src/coreclr/vm/arm64/thunktemplates.S +++ b/src/coreclr/vm/arm64/thunktemplates.S @@ -10,7 +10,7 @@ LEAF_ENTRY StubPrecodeCode\STUB_PAGE_SIZE ldr x10, DATA_SLOT(StubPrecode, Target) - ldr x12, DATA_SLOT(StubPrecode, MethodDesc) + ldr x12, DATA_SLOT(StubPrecode, SecretParam) br x10 LEAF_END_MARKED StubPrecodeCode\STUB_PAGE_SIZE diff --git a/src/coreclr/vm/arm64/thunktemplates.asm b/src/coreclr/vm/arm64/thunktemplates.asm index e582a4cc1154a6..48f6c16aadeb92 100644 --- a/src/coreclr/vm/arm64/thunktemplates.asm +++ b/src/coreclr/vm/arm64/thunktemplates.asm @@ -12,7 +12,7 @@ LEAF_ENTRY StubPrecodeCode ldr x10, DATA_SLOT(StubPrecode, Target) - ldr x12, DATA_SLOT(StubPrecode, MethodDesc) + ldr x12, DATA_SLOT(StubPrecode, SecretParam) br x10 LEAF_END_MARKED StubPrecodeCode diff --git a/src/coreclr/vm/ceeload.cpp b/src/coreclr/vm/ceeload.cpp index 219d3eaa5f0246..8e8416b651db65 100644 --- a/src/coreclr/vm/ceeload.cpp +++ b/src/coreclr/vm/ceeload.cpp @@ -3335,16 +3335,12 @@ void Module::FixupVTables() LOG((LF_INTEROP, LL_INFO10, "[0x%p] <-- VTable thunk for \"%s\" (pMD = 0x%p)\n", (UINT_PTR)&(pPointers[iMethod]), pMD->m_pszDebugMethodName, pMD)); - UMEntryThunk *pUMEntryThunk = (UMEntryThunk*)(void*)(GetDllThunkHeap()->AllocAlignedMem(sizeof(UMEntryThunk), CODE_SIZE_ALIGN)); // UMEntryThunk contains code - ExecutableWriterHolder uMEntryThunkWriterHolder(pUMEntryThunk, sizeof(UMEntryThunk)); - FillMemory(uMEntryThunkWriterHolder.GetRW(), sizeof(UMEntryThunk), 0); + UMEntryThunk *pUMEntryThunk = UMEntryThunk::CreateUMEntryThunk(); - UMThunkMarshInfo *pUMThunkMarshInfo = (UMThunkMarshInfo*)(void*)(GetThunkHeap()->AllocAlignedMem(sizeof(UMThunkMarshInfo), CODE_SIZE_ALIGN)); - ExecutableWriterHolder uMThunkMarshInfoWriterHolder(pUMThunkMarshInfo, sizeof(UMThunkMarshInfo)); - FillMemory(uMThunkMarshInfoWriterHolder.GetRW(), sizeof(UMThunkMarshInfo), 0); + UMThunkMarshInfo *pUMThunkMarshInfo = (UMThunkMarshInfo*)(void*)(SystemDomain::GetGlobalLoaderAllocator()->GetLowFrequencyHeap()->AllocAlignedMem(sizeof(UMThunkMarshInfo), CODE_SIZE_ALIGN)); - uMThunkMarshInfoWriterHolder.GetRW()->LoadTimeInit(pMD); - uMEntryThunkWriterHolder.GetRW()->LoadTimeInit(pUMEntryThunk, (PCODE)0, NULL, pUMThunkMarshInfo, pMD); + pUMThunkMarshInfo->LoadTimeInit(pMD); + pUMEntryThunk->LoadTimeInit((PCODE)0, NULL, pUMThunkMarshInfo, pMD); SetTargetForVTableEntry(hInstThis, (BYTE **)&pPointers[iMethod], (BYTE *)pUMEntryThunk->GetCode()); @@ -3368,49 +3364,6 @@ void Module::FixupVTables() } // End of Stage 3 } -// Self-initializing accessor for m_pThunkHeap -LoaderHeap *Module::GetDllThunkHeap() -{ - CONTRACTL - { - THROWS; - GC_TRIGGERS; - MODE_ANY; - } - CONTRACTL_END; - return PEImage::GetDllThunkHeap(GetPEAssembly()->GetIJWBase()); - -} - -LoaderHeap *Module::GetThunkHeap() -{ - CONTRACT(LoaderHeap *) - { - INSTANCE_CHECK; - THROWS; - GC_NOTRIGGER; - MODE_ANY; - INJECT_FAULT(COMPlusThrowOM()); - POSTCONDITION(CheckPointer(RETVAL)); - } - CONTRACT_END - - if (!m_pThunkHeap) - { - LoaderHeap *pNewHeap = new LoaderHeap(VIRTUAL_ALLOC_RESERVE_GRANULARITY, // DWORD dwReserveBlockSize - 0, // DWORD dwCommitBlockSize - ThunkHeapStubManager::g_pManager->GetRangeList(), - UnlockedLoaderHeap::HeapKind::Executable); - - if (InterlockedCompareExchangeT(&m_pThunkHeap, pNewHeap, 0) != 0) - { - delete pNewHeap; - } - } - - RETURN m_pThunkHeap; -} - ModuleBase *Module::GetModuleFromIndex(DWORD ix) { CONTRACT(ModuleBase*) diff --git a/src/coreclr/vm/ceeload.h b/src/coreclr/vm/ceeload.h index 66ef93ee8988f2..9f6c87e5d787e5 100644 --- a/src/coreclr/vm/ceeload.h +++ b/src/coreclr/vm/ceeload.h @@ -1499,14 +1499,6 @@ class Module : public ModuleBase InstrumentedILOffsetMapping GetInstrumentedILOffsetMapping(mdMethodDef token); public: - // LoaderHeap for storing IJW thunks - PTR_LoaderHeap m_pThunkHeap; - - // Self-initializing accessor for IJW thunk heap - LoaderHeap *GetThunkHeap(); - // Self-initializing accessor for domain-independent IJW thunk heap - LoaderHeap *GetDllThunkHeap(); - const ReadyToRun_MethodIsGenericMap *m_pMethodIsGenericMap = &ReadyToRun_MethodIsGenericMap::EmptyInstance; const ReadyToRun_TypeGenericInfoMap *m_pTypeGenericInfoMap = &ReadyToRun_TypeGenericInfoMap::EmptyInstance; @@ -1645,7 +1637,6 @@ struct cdac_data static constexpr size_t Base = offsetof(Module, m_baseAddress); static constexpr size_t Flags = offsetof(Module, m_dwTransientFlags); static constexpr size_t LoaderAllocator = offsetof(Module, m_loaderAllocator); - static constexpr size_t ThunkHeap = offsetof(Module, m_pThunkHeap); static constexpr size_t DynamicMetadata = offsetof(Module, m_pDynamicMetadata); static constexpr size_t Path = offsetof(Module, m_path); static constexpr size_t FileName = offsetof(Module, m_fileName); diff --git a/src/coreclr/vm/comdelegate.cpp b/src/coreclr/vm/comdelegate.cpp index c6e9ff7444ed8b..366fa211095a6e 100644 --- a/src/coreclr/vm/comdelegate.cpp +++ b/src/coreclr/vm/comdelegate.cpp @@ -763,9 +763,6 @@ BOOL GenerateShuffleArray(MethodDesc* pInvoke, MethodDesc *pTargetMeth, SArrayFPtr pairs - // passed out to unmanaged code. // One time init. void COMDelegate::Init() @@ -778,13 +775,6 @@ void COMDelegate::Init() } CONTRACTL_END; - s_DelegateToFPtrHashCrst.Init(CrstDelegateToFPtrHash, CRST_UNSAFE_ANYMODE); - - s_pDelegateToFPtrHash = ::new PtrHashMap(); - - LockOwner lock = {&s_DelegateToFPtrHashCrst, IsOwnerOfCrst}; - s_pDelegateToFPtrHash->Init(TRUE, &lock); - s_pShuffleThunkCache = new ShuffleThunkCache(SystemDomain::GetGlobalLoaderAllocator()->GetStubHeap()); } @@ -1349,16 +1339,14 @@ LPVOID COMDelegate::ConvertToCallback(OBJECTREF pDelegateObj) { GCX_PREEMP(); - pUMThunkMarshInfo = (UMThunkMarshInfo*)(void*)pMT->GetLoaderAllocator()->GetStubHeap()->AllocMem(S_SIZE_T(sizeof(UMThunkMarshInfo))); - - ExecutableWriterHolder uMThunkMarshInfoWriterHolder(pUMThunkMarshInfo, sizeof(UMThunkMarshInfo)); - uMThunkMarshInfoWriterHolder.GetRW()->LoadTimeInit(pInvokeMeth); + pUMThunkMarshInfo = (UMThunkMarshInfo*)(void*)pMT->GetLoaderAllocator()->GetLowFrequencyHeap()->AllocMem(S_SIZE_T(sizeof(UMThunkMarshInfo))); + pUMThunkMarshInfo->LoadTimeInit(pInvokeMeth); if (InterlockedCompareExchangeT(&(pClass->m_pUMThunkMarshInfo), pUMThunkMarshInfo, NULL ) != NULL) { - pMT->GetLoaderAllocator()->GetStubHeap()->BackoutMem(pUMThunkMarshInfo, sizeof(UMThunkMarshInfo)); + pMT->GetLoaderAllocator()->GetLowFrequencyHeap()->BackoutMem(pUMThunkMarshInfo, sizeof(UMThunkMarshInfo)); pUMThunkMarshInfo = pClass->m_pUMThunkMarshInfo; } } @@ -1377,11 +1365,8 @@ LPVOID COMDelegate::ConvertToCallback(OBJECTREF pDelegateObj) // This target should not ever be used. We are storing it in the thunk for better diagnostics of "call on collected delegate" crashes. PCODE pManagedTargetForDiagnostics = (pDelegate->GetMethodPtrAux() != (PCODE)NULL) ? pDelegate->GetMethodPtrAux() : pDelegate->GetMethodPtr(); - ExecutableWriterHolder uMEntryThunkWriterHolder(pUMEntryThunk, sizeof(UMEntryThunk)); - // MethodDesc is passed in for profiling to know the method desc of target - uMEntryThunkWriterHolder.GetRW()->LoadTimeInit( - pUMEntryThunk, + pUMEntryThunk->LoadTimeInit( pManagedTargetForDiagnostics, objhnd, pUMThunkMarshInfo, pInvokeMeth); @@ -1393,16 +1378,6 @@ LPVOID COMDelegate::ConvertToCallback(OBJECTREF pDelegateObj) else { umHolder.SuppressRelease(); - // Insert the delegate handle / UMEntryThunk* into the hash - LPVOID key = (LPVOID)pUMEntryThunk; - - // Assert that the entry isn't already in the hash. - _ASSERTE((LPVOID)INVALIDENTRY == s_pDelegateToFPtrHash->LookupValue((UPTR)key, 0)); - - { - CrstHolder ch(&s_DelegateToFPtrHashCrst); - s_pDelegateToFPtrHash->InsertValue((UPTR)key, pUMEntryThunk->GetObjectHandle()); - } } _ASSERTE(pUMEntryThunk != NULL); @@ -1434,19 +1409,30 @@ OBJECTREF COMDelegate::ConvertToDelegate(LPVOID pCallback, MethodTable* pMT) // Check if this callback was originally a managed method passed out to unmanaged code. // - UMEntryThunk* pUMEntryThunk = UMEntryThunk::Decode(pCallback); + UMEntryThunk* pUMEntryThunk = NULL; + + auto stubKind = RangeSectionStubManager::GetStubKind((PCODE)pCallback); + if (stubKind == STUB_CODE_BLOCK_STUBPRECODE) + { + Precode* pPrecode = Precode::GetPrecodeFromEntryPoint((PCODE)pCallback); + if (pPrecode->GetType() == PRECODE_UMENTRY_THUNK) + { + pUMEntryThunk = pPrecode->AsUMEntryThunk(); + } + } + // Lookup the callsite in the hash, if found, we can map this call back to its managed function. // Otherwise, we'll treat this as an unmanaged callsite. // Make sure that the pointer doesn't have the value of 1 which is our hash table deleted item marker. - LPVOID DelegateHnd = (pUMEntryThunk != NULL) && ((UPTR)pUMEntryThunk != (UPTR)1) - ? s_pDelegateToFPtrHash->LookupValue((UPTR)pUMEntryThunk, 0) - : (LPVOID)INVALIDENTRY; + OBJECTHANDLE DelegateHnd = (pUMEntryThunk != NULL) + ? pUMEntryThunk->GetObjectHandle() + : (OBJECTHANDLE)NULL; - if (DelegateHnd != (LPVOID)INVALIDENTRY) + if (DelegateHnd != (OBJECTHANDLE)NULL) { // Found a managed callsite - return ObjectFromHandle((OBJECTHANDLE)DelegateHnd); + return ObjectFromHandle(DelegateHnd); } // Validate the MethodTable is a delegate type @@ -1569,15 +1555,6 @@ MethodDesc* COMDelegate::GetILStubMethodDesc(EEImplMethodDesc* pDelegateMD, DWOR return NDirect::CreateCLRToNativeILStub(&sigInfo, dwStubFlags, pDelegateMD); } -void COMDelegate::RemoveEntryFromFPtrHash(UPTR key) -{ - WRAPPER_NO_CONTRACT; - - // Remove this entry from the lookup hash. - CrstHolder ch(&s_DelegateToFPtrHashCrst); - s_pDelegateToFPtrHash->DeleteValue(key, NULL); -} - extern "C" void QCALLTYPE Delegate_InitializeVirtualCallStub(QCall::ObjectHandleOnStack d, PCODE method) { QCALL_CONTRACT; diff --git a/src/coreclr/vm/comdelegate.h b/src/coreclr/vm/comdelegate.h index 064d6d0177b843..1b6ba80b7adb27 100644 --- a/src/coreclr/vm/comdelegate.h +++ b/src/coreclr/vm/comdelegate.h @@ -57,8 +57,6 @@ class COMDelegate static void ValidateDelegatePInvoke(MethodDesc* pMD); - static void RemoveEntryFromFPtrHash(UPTR key); - // Decides if pcls derives from Delegate. static BOOL IsDelegate(MethodTable *pMT); diff --git a/src/coreclr/vm/dllimport.cpp b/src/coreclr/vm/dllimport.cpp index 55ba8dc4151bdd..5b000e50428295 100644 --- a/src/coreclr/vm/dllimport.cpp +++ b/src/coreclr/vm/dllimport.cpp @@ -1970,7 +1970,7 @@ void NDirectStubLinker::Begin(DWORD dwStubFlags) EmitLoadStubContext(m_pcsDispatch, dwStubFlags); // load UMEntryThunk* - m_pcsDispatch->EmitLDC(offsetof(UMEntryThunk, m_pObjectHandle)); + m_pcsDispatch->EmitLDC(offsetof(UMEntryThunkData, m_pObjectHandle)); m_pcsDispatch->EmitADD(); m_pcsDispatch->EmitLDIND_I(); // get OBJECTHANDLE m_pcsDispatch->EmitLDIND_REF(); // get Delegate object @@ -2141,7 +2141,7 @@ void NDirectStubLinker::DoNDirect(ILCodeStream *pcsEmit, DWORD dwStubFlags, Meth int tokDelegate_methodPtr = pcsEmit->GetToken(CoreLibBinder::GetField(FIELD__DELEGATE__METHOD_PTR)); EmitLoadStubContext(pcsEmit, dwStubFlags); - pcsEmit->EmitLDC(offsetof(UMEntryThunk, m_pObjectHandle)); + pcsEmit->EmitLDC(offsetof(UMEntryThunkData, m_pObjectHandle)); pcsEmit->EmitADD(); pcsEmit->EmitLDIND_I(); // Get OBJECTHANDLE pcsEmit->EmitLDIND_REF(); // Get Delegate object @@ -2157,8 +2157,8 @@ void NDirectStubLinker::DoNDirect(ILCodeStream *pcsEmit, DWORD dwStubFlags, Meth else // direct reverse P/Invoke (CoreCLR hosting) { EmitLoadStubContext(pcsEmit, dwStubFlags); - CONSISTENCY_CHECK(0 == offsetof(UMEntryThunk, m_pManagedTarget)); // if this changes, just add back the EmitLDC/EmitADD below - // pcsEmit->EmitLDC(offsetof(UMEntryThunk, m_pManagedTarget)); + CONSISTENCY_CHECK(0 == offsetof(UMEntryThunkData, m_pManagedTarget)); // if this changes, just add back the EmitLDC/EmitADD below + // pcsEmit->EmitLDC(offsetof(UMEntryThunkData, m_pManagedTarget)); // pcsEmit->EmitADD(); pcsEmit->EmitLDIND_I(); // Get UMEntryThunk::m_pManagedTarget } diff --git a/src/coreclr/vm/dllimportcallback.cpp b/src/coreclr/vm/dllimportcallback.cpp index b9befb2d4c5efd..f9e3ea038d99a8 100644 --- a/src/coreclr/vm/dllimportcallback.cpp +++ b/src/coreclr/vm/dllimportcallback.cpp @@ -57,13 +57,13 @@ class UMEntryThunkFreeList if (pThunk == NULL) return NULL; - m_pHead = m_pHead->m_pNextFreeThunk; + m_pHead = m_pHead->GetData()->m_pNextFreeThunk; --m_count; return pThunk; } - void AddToList(UMEntryThunk *pThunkRX, UMEntryThunk *pThunkRW) + void AddToList(UMEntryThunk *pThunk) { CONTRACTL { @@ -75,17 +75,16 @@ class UMEntryThunkFreeList if (m_pHead == NULL) { - m_pHead = pThunkRX; - m_pTail = pThunkRX; + m_pHead = pThunk; + m_pTail = pThunk; } else { - ExecutableWriterHolder tailThunkWriterHolder(m_pTail, sizeof(UMEntryThunk)); - tailThunkWriterHolder.GetRW()->m_pNextFreeThunk = pThunkRX; - m_pTail = pThunkRX; + m_pTail->GetData()->m_pNextFreeThunk = pThunk; + m_pTail = pThunk; } - pThunkRW->m_pNextFreeThunk = NULL; + pThunk->GetData()->m_pNextFreeThunk = NULL; ++m_count; } @@ -158,15 +157,13 @@ UMEntryThunk *UMEntryThunkCache::GetUMEntryThunk(MethodDesc *pMD) Holder umHolder; umHolder.Assign(pThunk); - UMThunkMarshInfo *pMarshInfo = (UMThunkMarshInfo *)(void *)(m_pDomain->GetStubHeap()->AllocMem(S_SIZE_T(sizeof(UMThunkMarshInfo)))); + UMThunkMarshInfo *pMarshInfo = (UMThunkMarshInfo *)(void *)(m_pDomain->GetLowFrequencyHeap()->AllocMem(S_SIZE_T(sizeof(UMThunkMarshInfo)))); Holder miHolder; miHolder.Assign(pMarshInfo); - ExecutableWriterHolder marshInfoWriterHolder(pMarshInfo, sizeof(UMThunkMarshInfo)); - marshInfoWriterHolder.GetRW()->LoadTimeInit(pMD); + pMarshInfo->LoadTimeInit(pMD); - ExecutableWriterHolder thunkWriterHolder(pThunk, sizeof(UMEntryThunk)); - thunkWriterHolder.GetRW()->LoadTimeInit(pThunk, (PCODE)NULL, NULL, pMarshInfo, pMD); + pThunk->LoadTimeInit((PCODE)NULL, NULL, pMarshInfo, pMD); // add it to the cache CacheElement element; @@ -195,7 +192,7 @@ extern "C" VOID STDCALL ReversePInvokeBadTransition() ); } -PCODE TheUMEntryPrestubWorker(UMEntryThunk * pUMEntryThunk) +PCODE TheUMEntryPrestubWorker(UMEntryThunkData * pUMEntryThunkData) { STATIC_CONTRACT_THROWS; STATIC_CONTRACT_GC_TRIGGERS; @@ -207,6 +204,8 @@ PCODE TheUMEntryPrestubWorker(UMEntryThunk * pUMEntryThunk) CREATETHREAD_IF_NULL_FAILFAST(pThread, W("Failed to setup new thread during reverse P/Invoke")); } + UMEntryThunk* pUMEntryThunk = pUMEntryThunkData->m_pUMEntryThunk; + // Verify the current thread isn't in COOP mode. if (pThread->PreemptiveGCDisabled()) ReversePInvokeBadTransition(); @@ -217,8 +216,7 @@ PCODE TheUMEntryPrestubWorker(UMEntryThunk * pUMEntryThunk) // exceptions don't leak out into managed code. INSTALL_UNWIND_AND_CONTINUE_HANDLER; - ExecutableWriterHolder uMEntryThunkWriterHolder(pUMEntryThunk, sizeof(UMEntryThunk)); - uMEntryThunkWriterHolder.GetRW()->RunTimeInit(pUMEntryThunk); + pUMEntryThunk->RunTimeInit(); UNINSTALL_UNWIND_AND_CONTINUE_HANDLER; UNINSTALL_MANAGED_EXCEPTION_DISPATCHER; @@ -243,7 +241,18 @@ UMEntryThunk* UMEntryThunk::CreateUMEntryThunk() p = s_thunkFreeList.GetUMEntryThunk(); if (p == NULL) - p = (UMEntryThunk *)(void *)SystemDomain::GetGlobalLoaderAllocator()->GetExecutableHeap()->AllocMem(S_SIZE_T(sizeof(UMEntryThunk))); + { + SIZE_T size = sizeof(UMEntryThunk); + LoaderAllocator *pLoaderAllocator = SystemDomain::GetGlobalLoaderAllocator(); + AllocMemTracker amTracker; + AllocMemTracker *pamTracker = &amTracker; + + UMEntryThunkData *pData = (UMEntryThunkData *)pamTracker->Track(pLoaderAllocator->GetLowFrequencyHeap()->AllocMem(S_SIZE_T(sizeof(UMEntryThunkData)))); + p = (UMEntryThunk*)pamTracker->Track(pLoaderAllocator->GetNewStubPrecodeHeap()->AllocAlignedMem(size, 1)); + pData->m_pUMEntryThunk = p; + p->Init(p, dac_cast(pData), NULL, dac_cast(PRECODE_UMENTRY_THUNK)); + pamTracker->SuppressRelease(); + } RETURN p; } @@ -257,16 +266,15 @@ void UMEntryThunk::Terminate() } CONTRACTL_END; - ExecutableWriterHolder thunkWriterHolder(this, sizeof(UMEntryThunk)); - m_code.Poison(); + SetTargetUnconditional((TADDR)UMEntryThunk::ReportViolation); if (GetObjectHandle()) { DestroyLongWeakHandle(GetObjectHandle()); - thunkWriterHolder.GetRW()->m_pObjectHandle = 0; + GetData()->m_pObjectHandle = 0; } - s_thunkFreeList.AddToList(this, thunkWriterHolder.GetRW()); + s_thunkFreeList.AddToList(this); } VOID UMEntryThunk::FreeUMEntryThunk(UMEntryThunk* p) @@ -290,17 +298,19 @@ VOID UMEntryThunk::FreeUMEntryThunk(UMEntryThunk* p) // function will not be called in all cases of the collected delegate call, // also it may crash while trying to report the problem. //------------------------------------------------------------------------- -VOID __fastcall UMEntryThunk::ReportViolation(UMEntryThunk* pEntryThunk) +VOID __fastcall UMEntryThunk::ReportViolation(UMEntryThunkData* pEntryThunkData) { CONTRACTL { THROWS; GC_TRIGGERS; MODE_COOPERATIVE; - PRECONDITION(CheckPointer(pEntryThunk)); + PRECONDITION(CheckPointer(pEntryThunkData)); } CONTRACTL_END; + UMEntryThunk* pEntryThunk = pEntryThunkData->m_pUMEntryThunk; + MethodDesc* pMethodDesc = pEntryThunk->GetMethod(); SString namespaceOrClassName; diff --git a/src/coreclr/vm/dllimportcallback.h b/src/coreclr/vm/dllimportcallback.h index 5a15cb971a082f..72ce30b9d471bf 100644 --- a/src/coreclr/vm/dllimportcallback.h +++ b/src/coreclr/vm/dllimportcallback.h @@ -113,6 +113,38 @@ class UMThunkMarshInfo Signature m_sig; }; +struct UMEntryThunkData +{ + friend class NDirectStubLinker; + + // The start of the managed code. + // if m_pObjectHandle is non-NULL, this field is still set to help with diagnostic of call on collected delegate crashes + // but it may not have the correct value. + PCODE m_pManagedTarget; + + // This is used for profiling. + PTR_MethodDesc m_pMD; + + // Object handle holding "this" reference. May be a strong or weak handle. + // Field is NULL for a static method. + OBJECTHANDLE m_pObjectHandle; + + union + { + // Pointer to the shared structure containing everything else + PTR_UMThunkMarshInfo m_pUMThunkMarshInfo; + // Pointer to the next UMEntryThunk in the free list. Used when it is freed. + UMEntryThunk *m_pNextFreeThunk; + }; + + PTR_UMEntryThunk m_pUMEntryThunk; + +#ifdef _DEBUG + DWORD m_state; // the initialization state +#endif +}; + +typedef DPTR(struct UMEntryThunkData) PTR_UMEntryThunkData; //---------------------------------------------------------------------- // This structure contains the minimal information required to @@ -123,10 +155,8 @@ class UMThunkMarshInfo // front end of the thunk. A pointer to the m_code[] byte array is // what is actually handed to unmanaged client code. //---------------------------------------------------------------------- -class UMEntryThunk +class UMEntryThunk : private StubPrecode { - friend class CheckAsmOffsets; - friend class NDirectStubLinker; friend class UMEntryThunkFreeList; private: @@ -138,13 +168,22 @@ class UMEntryThunk }; #endif + PTR_UMEntryThunkData GetData() const + { + LIMITED_METHOD_CONTRACT; + + return dac_cast(GetSecretParam()); + } + public: + + static const int Type = PRECODE_UMENTRY_THUNK; + static UMEntryThunk* CreateUMEntryThunk(); static VOID FreeUMEntryThunk(UMEntryThunk* p); #ifndef DACCESS_COMPILE - VOID LoadTimeInit(UMEntryThunk *pUMEntryThunkRX, - PCODE pManagedTarget, + VOID LoadTimeInit(PCODE pManagedTarget, OBJECTHANDLE pObjectHandle, UMThunkMarshInfo *pUMThunkMarshInfo, MethodDesc *pMD) @@ -159,39 +198,40 @@ class UMEntryThunk } CONTRACTL_END; - m_pManagedTarget = pManagedTarget; - m_pObjectHandle = pObjectHandle; - m_pUMThunkMarshInfo = pUMThunkMarshInfo; + PTR_UMEntryThunkData data = GetData(); + data->m_pManagedTarget = pManagedTarget; + data->m_pObjectHandle = pObjectHandle; + data->m_pUMThunkMarshInfo = pUMThunkMarshInfo; - m_pMD = pMD; // For debugging and profiling, so they can identify the target + data->m_pMD = pMD; // For debugging and profiling, so they can identify the target - m_code.Encode(&pUMEntryThunkRX->m_code, (BYTE*)TheUMThunkPreStub(), pUMEntryThunkRX); + SetTargetUnconditional(TheUMThunkPreStub()); #ifdef _DEBUG - m_state = kLoadTimeInited; + data->m_state = kLoadTimeInited; #endif } void Terminate(); - VOID RunTimeInit(UMEntryThunk *pUMEntryThunkRX) + VOID RunTimeInit() { STANDARD_VM_CONTRACT; + PTR_UMEntryThunkData data = GetData(); // Ensure method's module is activate in app domain - m_pMD->EnsureActive(); + data->m_pMD->EnsureActive(); - ExecutableWriterHolder uMThunkMarshInfoWriterHolder(m_pUMThunkMarshInfo, sizeof(UMThunkMarshInfo)); - uMThunkMarshInfoWriterHolder.GetRW()->RunTimeInit(); + data->m_pUMThunkMarshInfo->RunTimeInit(); // Ensure that we have either the managed target or the delegate. - if (m_pObjectHandle == NULL && m_pManagedTarget == (TADDR)0) - m_pManagedTarget = m_pMD->GetMultiCallableAddrOfCode(); + if (data->m_pObjectHandle == NULL && data->m_pManagedTarget == (TADDR)0) + data->m_pManagedTarget = data->m_pMD->GetMultiCallableAddrOfCode(); - m_code.Encode(&pUMEntryThunkRX->m_code, (BYTE*)m_pUMThunkMarshInfo->GetExecStubEntryPoint(), pUMEntryThunkRX); + SetTargetUnconditional(data->m_pUMThunkMarshInfo->GetExecStubEntryPoint()); #ifdef _DEBUG - m_state = kRunTimeInited; + data->m_state = kRunTimeInited; #endif // _DEBUG } @@ -202,7 +242,7 @@ class UMEntryThunk THROWS; GC_TRIGGERS; MODE_ANY; - PRECONDITION(m_state == kRunTimeInited || m_state == kLoadTimeInited); + PRECONDITION(GetData()->m_state == kRunTimeInited || GetData()->m_state == kLoadTimeInited); POSTCONDITION(RETVAL != NULL); } CONTRACT_END; @@ -214,7 +254,7 @@ class UMEntryThunk DELEGATEREF orDelegate = (DELEGATEREF)ObjectFromHandle(hndDelegate); _ASSERTE(orDelegate != NULL); - _ASSERTE(m_pMD->IsEEImpl()); + _ASSERTE(GetData()->m_pMD->IsEEImpl()); // We have optimizations that skip the Invoke method and call directly the // delegate's target method. We need to return the target in that case, @@ -223,13 +263,14 @@ class UMEntryThunk } else { - if (m_pManagedTarget != (TADDR)0) + PTR_UMEntryThunkData data = GetData(); + if (data->m_pManagedTarget != (TADDR)0) { - RETURN m_pManagedTarget; + RETURN data->m_pManagedTarget; } else { - RETURN m_pMD->GetMultiCallableAddrOfCode(); + RETURN data->m_pMD->GetMultiCallableAddrOfCode(); } } } @@ -245,13 +286,13 @@ class UMEntryThunk // If we OOM after we create the holder but // before we set the m_state we can have // m_state == 0 and m_pObjectHandle == NULL - PRECONDITION(m_state == kRunTimeInited || - m_state == kLoadTimeInited || - m_pObjectHandle == NULL); + PRECONDITION(GetData()->m_state == kRunTimeInited || + GetData()->m_state == kLoadTimeInited || + GetData()->m_pObjectHandle == NULL); } CONTRACT_END; - RETURN m_pObjectHandle; + RETURN GetData()->m_pObjectHandle; } UMThunkMarshInfo* GetUMThunkMarshInfo() const @@ -262,37 +303,30 @@ class UMEntryThunk GC_NOTRIGGER; MODE_ANY; SUPPORTS_DAC; - PRECONDITION(m_state == kRunTimeInited || m_state == kLoadTimeInited); + PRECONDITION(GetData()->m_state == kRunTimeInited || GetData()->m_state == kLoadTimeInited); POSTCONDITION(CheckPointer(RETVAL)); } CONTRACT_END; - RETURN m_pUMThunkMarshInfo; + RETURN GetData()->m_pUMThunkMarshInfo; } - const BYTE* GetCode() const + PCODE GetCode() const { - CONTRACT (const BYTE*) + CONTRACT (PCODE) { NOTHROW; GC_NOTRIGGER; MODE_ANY; - PRECONDITION(m_state == kRunTimeInited || m_state == kLoadTimeInited); - POSTCONDITION(CheckPointer(RETVAL, NULL_OK)); + PRECONDITION(GetData()->m_state == kRunTimeInited || GetData()->m_state == kLoadTimeInited); + POSTCONDITION(CheckPointer(dac_cast(RETVAL), NULL_OK)); } CONTRACT_END; - RETURN m_code.GetEntryPoint(); - } - - static UMEntryThunk* RecoverUMEntryThunk(const VOID* pCode) - { - LIMITED_METHOD_CONTRACT; - return (UMEntryThunk*)( ((LPBYTE)pCode) - offsetof(UMEntryThunk, m_code) ); + RETURN PINSTRToPCODE(dac_cast(this)); } - MethodDesc* GetMethod() const { CONTRACT (MethodDesc*) @@ -300,50 +334,15 @@ class UMEntryThunk NOTHROW; GC_NOTRIGGER; MODE_ANY; - PRECONDITION(m_state == kRunTimeInited || m_state == kLoadTimeInited); + PRECONDITION(GetData()->m_state == kRunTimeInited || GetData()->m_state == kLoadTimeInited); POSTCONDITION(CheckPointer(RETVAL,NULL_OK)); } CONTRACT_END; - RETURN m_pMD; - } - - static DWORD GetCodeOffset() - { - LIMITED_METHOD_CONTRACT; - return offsetof(UMEntryThunk, m_code); + RETURN GetData()->m_pMD; } - static UMEntryThunk* Decode(LPVOID pCallback); - - static VOID __fastcall ReportViolation(UMEntryThunk* p); - -private: - // The start of the managed code. - // if m_pObjectHandle is non-NULL, this field is still set to help with diagnostic of call on collected delegate crashes - // but it may not have the correct value. - PCODE m_pManagedTarget; - - // This is used for profiling. - PTR_MethodDesc m_pMD; - - // Object handle holding "this" reference. May be a strong or weak handle. - // Field is NULL for a static method. - OBJECTHANDLE m_pObjectHandle; - - union - { - // Pointer to the shared structure containing everything else - PTR_UMThunkMarshInfo m_pUMThunkMarshInfo; - // Pointer to the next UMEntryThunk in the free list. Used when it is freed. - UMEntryThunk *m_pNextFreeThunk; - }; - -#ifdef _DEBUG - DWORD m_state; // the initialization state -#endif - - UMEntryThunkCode m_code; + static VOID __fastcall ReportViolation(UMEntryThunkData* pEntryThunkData); }; // Cache to hold UMEntryThunk/UMThunkMarshInfo instances associated with MethodDescs. @@ -397,7 +396,7 @@ EXCEPTION_HANDLER_DECL(FastNExportExceptHandler); #endif // FEATURE_EH_FUNCLETS extern "C" void TheUMEntryPrestub(void); -extern "C" PCODE TheUMEntryPrestubWorker(UMEntryThunk * pUMEntryThunk); +extern "C" PCODE TheUMEntryPrestubWorker(UMEntryThunkData * pUMEntryThunk); #ifdef _DEBUG void STDCALL LogUMTransition(UMEntryThunk* thunk); diff --git a/src/coreclr/vm/gccover.cpp b/src/coreclr/vm/gccover.cpp index 3df7fe4448322f..e9d829a2a04d0b 100644 --- a/src/coreclr/vm/gccover.cpp +++ b/src/coreclr/vm/gccover.cpp @@ -409,7 +409,15 @@ static MethodDesc* getTargetMethodDesc(PCODE target) if (stubKind == STUB_CODE_BLOCK_STUBPRECODE) { - return (MethodDesc*)((StubPrecode*)PCODEToPINSTR(target))->GetMethodDesc(); + Precode* pPrecode = Precode::GetPrecodeFromEntryPoint(target); + switch (pPrecode->GetType()) + { + case PRECODE_STUB: + case PRECODE_NDIRECT_IMPORT: + return dac_cast(pPrecode->AsStubPrecode()->GetMethodDesc()); + default: + return nullptr; + } } if (stubKind == STUB_CODE_BLOCK_FIXUPPRECODE) diff --git a/src/coreclr/vm/i386/asmconstants.h b/src/coreclr/vm/i386/asmconstants.h index 396381f6c1f539..8bc0b0b3587266 100644 --- a/src/coreclr/vm/i386/asmconstants.h +++ b/src/coreclr/vm/i386/asmconstants.h @@ -254,12 +254,6 @@ ASMCONSTANTS_C_ASSERT(CallDescrData__fpReturnSize == offsetof(CallDescrD ASMCONSTANTS_C_ASSERT(CallDescrData__pTarget == offsetof(CallDescrData, pTarget)) ASMCONSTANTS_C_ASSERT(CallDescrData__returnValue == offsetof(CallDescrData, returnValue)) -#define UMEntryThunk__m_pUMThunkMarshInfo 0x0C -ASMCONSTANTS_C_ASSERT(UMEntryThunk__m_pUMThunkMarshInfo == offsetof(UMEntryThunk, m_pUMThunkMarshInfo)) - -#define UMThunkMarshInfo__m_pILStub 0x00 -ASMCONSTANTS_C_ASSERT(UMThunkMarshInfo__m_pILStub == offsetof(UMThunkMarshInfo, m_pILStub)) - // For JIT_PInvokeBegin and JIT_PInvokeEnd helpers #define Frame__m_Next 0x04 ASMCONSTANTS_C_ASSERT(Frame__m_Next == offsetof(Frame, m_Next)); @@ -296,8 +290,8 @@ ASMCONSTANTS_C_ASSERT(FixupPrecodeData__PrecodeFixupThunk == offsetof(FixupPreco #define StubPrecodeData__Target 0x04 ASMCONSTANTS_C_ASSERT(StubPrecodeData__Target == offsetof(StubPrecodeData, Target)) -#define StubPrecodeData__MethodDesc 0x00 -ASMCONSTANTS_C_ASSERT(StubPrecodeData__MethodDesc == offsetof(StubPrecodeData, MethodDesc)) +#define StubPrecodeData__SecretParam 0x00 +ASMCONSTANTS_C_ASSERT(StubPrecodeData__SecretParam == offsetof(StubPrecodeData, SecretParam)) #define CallCountingStubData__RemainingCallCountCell 0x00 ASMCONSTANTS_C_ASSERT(CallCountingStubData__RemainingCallCountCell == offsetof(CallCountingStubData, RemainingCallCountCell)) diff --git a/src/coreclr/vm/i386/asmhelpers.asm b/src/coreclr/vm/i386/asmhelpers.asm index 2f1d12c6d9a71e..71f17741c35118 100644 --- a/src/coreclr/vm/i386/asmhelpers.asm +++ b/src/coreclr/vm/i386/asmhelpers.asm @@ -1155,7 +1155,7 @@ _TheUMEntryPrestub@0 proc public push ecx push edx - push eax ; UMEntryThunk* + push eax ; UMEntryThunkData* call _TheUMEntryPrestubWorker@4 ; pop argument registers diff --git a/src/coreclr/vm/i386/cgencpu.h b/src/coreclr/vm/i386/cgencpu.h index b87527be323331..a7b22d2c4824ac 100644 --- a/src/coreclr/vm/i386/cgencpu.h +++ b/src/coreclr/vm/i386/cgencpu.h @@ -401,34 +401,6 @@ EXTERN_C void __stdcall getFPReturn(int fpSize, INT64 *pretval); // SEH info forward declarations -#include -struct DECLSPEC_ALIGN(4) UMEntryThunkCode -{ - BYTE m_alignpad[2]; // used to guarantee alignment of backpactched portion - BYTE m_movEAX; //MOV EAX,imm32 - LPVOID m_uet; // pointer to start of this structure - BYTE m_jmp; //JMP NEAR32 - const BYTE * m_execstub; // pointer to destination code // make sure the backpatched portion is dword aligned. - - void Encode(UMEntryThunkCode *pEntryThunkCodeRX, BYTE* pTargetCode, void* pvSecretParam); - void Poison(); - - LPCBYTE GetEntryPoint() const - { - LIMITED_METHOD_CONTRACT; - - return (LPCBYTE)&m_movEAX; - } - - static int GetEntryPointOffset() - { - LIMITED_METHOD_CONTRACT; - - return 2; - } -}; -#include - struct HijackArgs { DWORD FPUState[3]; // 12 bytes for FPU state (10 bytes for FP top-of-stack + 2 bytes padding) diff --git a/src/coreclr/vm/i386/cgenx86.cpp b/src/coreclr/vm/i386/cgenx86.cpp index c4fe9b265ed62e..940234907abfaa 100644 --- a/src/coreclr/vm/i386/cgenx86.cpp +++ b/src/coreclr/vm/i386/cgenx86.cpp @@ -977,49 +977,6 @@ void ResumeAtJit(PCONTEXT pContext, LPVOID oldESP) #pragma warning (default : 4731) #endif // !FEATURE_METADATA_UPDATER - -void UMEntryThunkCode::Encode(UMEntryThunkCode *pEntryThunkCodeRX, BYTE* pTargetCode, void* pvSecretParam) -{ - LIMITED_METHOD_CONTRACT; - -#ifdef _DEBUG - m_alignpad[0] = X86_INSTR_INT3; - m_alignpad[1] = X86_INSTR_INT3; -#endif // _DEBUG - m_movEAX = X86_INSTR_MOV_EAX_IMM32; - m_uet = pvSecretParam; - m_jmp = X86_INSTR_JMP_REL32; - m_execstub = (BYTE*) ((pTargetCode) - (4+((BYTE*)&pEntryThunkCodeRX->m_execstub))); - - ClrFlushInstructionCache(pEntryThunkCodeRX->GetEntryPoint(),sizeof(UMEntryThunkCode) - GetEntryPointOffset(), /* hasCodeExecutedBefore */ true); -} - -void UMEntryThunkCode::Poison() -{ - LIMITED_METHOD_CONTRACT; - - ExecutableWriterHolder thunkWriterHolder(this, sizeof(UMEntryThunkCode)); - UMEntryThunkCode *pThisRW = thunkWriterHolder.GetRW(); - - pThisRW->m_execstub = (BYTE*) ((BYTE*)UMEntryThunk::ReportViolation - (4+((BYTE*)&m_execstub))); - - // mov ecx, imm32 - pThisRW->m_movEAX = 0xb9; - - ClrFlushInstructionCache(GetEntryPoint(),sizeof(UMEntryThunkCode) - GetEntryPointOffset(), /* hasCodeExecutedBefore */ true); -} - -UMEntryThunk* UMEntryThunk::Decode(LPVOID pCallback) -{ - LIMITED_METHOD_CONTRACT; - - if (*((BYTE*)pCallback) != X86_INSTR_MOV_EAX_IMM32 || - ( ((size_t)pCallback) & 3) != 2) { - return NULL; - } - return *(UMEntryThunk**)( 1 + (BYTE*)pCallback ); -} - #ifdef FEATURE_READYTORUN // diff --git a/src/coreclr/vm/i386/thunktemplates.S b/src/coreclr/vm/i386/thunktemplates.S index 128eba016b490b..d0b8257e32f50e 100644 --- a/src/coreclr/vm/i386/thunktemplates.S +++ b/src/coreclr/vm/i386/thunktemplates.S @@ -28,7 +28,7 @@ PAGE_SIZE = 16384 .endm LEAF_ENTRY StubPrecodeCode - mov eax, dword ptr [DATA_SLOT(StubPrecode, MethodDesc)] + mov eax, dword ptr [DATA_SLOT(StubPrecode, SecretParam)] SLOT_ADDRESS_PATCH_LABEL StubPrecode, MethodDesc INDJMP DATA_SLOT(StubPrecode, Target) SLOT_ADDRESS_PATCH_LABEL StubPrecode, Target diff --git a/src/coreclr/vm/i386/thunktemplates.asm b/src/coreclr/vm/i386/thunktemplates.asm index 5e3203a46859ce..8edec3997a69d2 100644 --- a/src/coreclr/vm/i386/thunktemplates.asm +++ b/src/coreclr/vm/i386/thunktemplates.asm @@ -28,7 +28,7 @@ labelValue TEXTEQU @CatStr(<$>, offset, <-_>, stub, ) endm LEAF_ENTRY _StubPrecodeCode@0 - mov eax, dword ptr DATA_SLOT(StubPrecode, MethodDesc) + mov eax, dword ptr DATA_SLOT(StubPrecode, SecretParam) SLOT_ADDRESS_PATCH_LABEL StubPrecode, MethodDesc jmp dword ptr DATA_SLOT(StubPrecode, Target) SLOT_ADDRESS_PATCH_LABEL StubPrecode, Target diff --git a/src/coreclr/vm/i386/umthunkstub.S b/src/coreclr/vm/i386/umthunkstub.S index 24392b3fd82689..d757443a874cfd 100644 --- a/src/coreclr/vm/i386/umthunkstub.S +++ b/src/coreclr/vm/i386/umthunkstub.S @@ -11,7 +11,7 @@ NESTED_ENTRY TheUMEntryPrestub, _TEXT, UnhandledExceptionHandlerUnix #define STK_ALIGN_PADDING 8 sub esp, STK_ALIGN_PADDING - push eax // UMEntryThunk* + push eax // UMEntryThunkData* CHECK_STACK_ALIGNMENT call C_FUNC(TheUMEntryPrestubWorker) add esp, (4 + STK_ALIGN_PADDING) diff --git a/src/coreclr/vm/jithelpers.cpp b/src/coreclr/vm/jithelpers.cpp index 81d3481124ef1a..7493380ae943aa 100644 --- a/src/coreclr/vm/jithelpers.cpp +++ b/src/coreclr/vm/jithelpers.cpp @@ -3381,40 +3381,40 @@ HCIMPL3_RAW(void, JIT_ReversePInvokeEnterTrackTransitions, ReversePInvokeFrame* MethodDesc* pMD = GetMethod(handle); if (pMD->IsILStub() && secretArg != NULL) { - pMD = ((UMEntryThunk*)secretArg)->GetMethod(); + pMD = ((UMEntryThunkData*)secretArg)->m_pMD; } frame->pMD = pMD; Thread* thread = GetThreadNULLOk(); - + // If a thread instance exists and is in the // correct GC mode attempt a quick transition. if (thread != NULL && !thread->PreemptiveGCDisabled()) { frame->currentThread = thread; - + #ifdef PROFILING_SUPPORTED if (CORProfilerTrackTransitions()) { ProfilerUnmanagedToManagedTransitionMD(frame->pMD, COR_PRF_TRANSITION_CALL); } #endif - + // Manually inline the fast path in Thread::DisablePreemptiveGC(). thread->m_fPreemptiveGCDisabled.StoreWithoutBarrier(1); if (g_TrapReturningThreads != 0) { // If we're in an IL stub, we want to trace the address of the target method, // not the next instruction in the stub. - JIT_ReversePInvokeEnterRare2(frame, _ReturnAddress(), GetMethod(handle)->IsILStub() ? (UMEntryThunk*)secretArg : (UMEntryThunk*)NULL); + JIT_ReversePInvokeEnterRare2(frame, _ReturnAddress(), GetMethod(handle)->IsILStub() ? ((UMEntryThunkData*)secretArg)->m_pUMEntryThunk : (UMEntryThunk*)NULL); } } else { // If we're in an IL stub, we want to trace the address of the target method, // not the next instruction in the stub. - JIT_ReversePInvokeEnterRare(frame, _ReturnAddress(), GetMethod(handle)->IsILStub() ? (UMEntryThunk*)secretArg : (UMEntryThunk*)NULL); + JIT_ReversePInvokeEnterRare(frame, _ReturnAddress(), GetMethod(handle)->IsILStub() ? ((UMEntryThunkData*)secretArg)->m_pUMEntryThunk : (UMEntryThunk*)NULL); } #ifndef FEATURE_EH_FUNCLETS diff --git a/src/coreclr/vm/loongarch64/asmconstants.h b/src/coreclr/vm/loongarch64/asmconstants.h index bc78b33707f9f2..4834b105b3fa7a 100644 --- a/src/coreclr/vm/loongarch64/asmconstants.h +++ b/src/coreclr/vm/loongarch64/asmconstants.h @@ -207,8 +207,8 @@ ASMCONSTANTS_C_ASSERT(FixupPrecodeData__PrecodeFixupThunk == offsetof(FixupPreco #define StubPrecodeData__Target 0x08 ASMCONSTANTS_C_ASSERT(StubPrecodeData__Target == offsetof(StubPrecodeData, Target)) -#define StubPrecodeData__MethodDesc 0x00 -ASMCONSTANTS_C_ASSERT(StubPrecodeData__MethodDesc == offsetof(StubPrecodeData, MethodDesc)) +#define StubPrecodeData__SecretParam 0x00 +ASMCONSTANTS_C_ASSERT(StubPrecodeData__SecretParam == offsetof(StubPrecodeData, SecretParam)) #define CallCountingStubData__RemainingCallCountCell 0x00 ASMCONSTANTS_C_ASSERT(CallCountingStubData__RemainingCallCountCell == offsetof(CallCountingStubData, RemainingCallCountCell)) diff --git a/src/coreclr/vm/loongarch64/cgencpu.h b/src/coreclr/vm/loongarch64/cgencpu.h index 2d3b2d028b2c2f..1938eeb100b235 100644 --- a/src/coreclr/vm/loongarch64/cgencpu.h +++ b/src/coreclr/vm/loongarch64/cgencpu.h @@ -412,31 +412,6 @@ class StubLinkerCPU : public StubLinker // preferred alignment for data #define DATA_ALIGNMENT 8 -struct DECLSPEC_ALIGN(16) UMEntryThunkCode -{ - DWORD m_code[4]; - - TADDR m_pTargetCode; - TADDR m_pvSecretParam; - - void Encode(UMEntryThunkCode *pEntryThunkCodeRX, BYTE* pTargetCode, void* pvSecretParam); - void Poison(); - - LPCBYTE GetEntryPoint() const - { - LIMITED_METHOD_CONTRACT; - - return (LPCBYTE)this; - } - - static int GetEntryPointOffset() - { - LIMITED_METHOD_CONTRACT; - - return 0; - } -}; - struct HijackArgs { DWORD64 Fp; // frame pointer diff --git a/src/coreclr/vm/loongarch64/stubs.cpp b/src/coreclr/vm/loongarch64/stubs.cpp index d636410940a704..e57af5c1347839 100644 --- a/src/coreclr/vm/loongarch64/stubs.cpp +++ b/src/coreclr/vm/loongarch64/stubs.cpp @@ -994,63 +994,6 @@ AdjustContextForVirtualStub( } #endif // !DACCESS_COMPILE -UMEntryThunk * UMEntryThunk::Decode(void *pCallback) -{ - _ASSERTE(offsetof(UMEntryThunkCode, m_code) == 0); - UMEntryThunkCode * pCode = (UMEntryThunkCode*)pCallback; - - // We may be called with an unmanaged external code pointer instead. So if it doesn't look like one of our - // stubs (see UMEntryThunkCode::Encode below) then we'll return NULL. Luckily in these scenarios our - // caller will perform a hash lookup on successful return to verify our result in case random unmanaged - // code happens to look like ours. - if ((pCode->m_code[0] == 0x18000095) && //pcaddi $r21,4 - (pCode->m_code[1] == 0x28c022ae) && //ld.d $t2,$r21,8 - (pCode->m_code[2] == 0x28c002b5) && //ld.d $r21,$r21,0 - (pCode->m_code[3] == 0x4c0002a0)) //jirl $r0,$r21,0 - { - return (UMEntryThunk*)pCode->m_pvSecretParam; - } - - return NULL; -} - -void UMEntryThunkCode::Encode(UMEntryThunkCode *pEntryThunkCodeRX, BYTE* pTargetCode, void* pvSecretParam) -{ - // pcaddi $r21,4 - // ld.d $t2,$r21,8 - // ld.d $r21,$r21,0 - // jirl $r0,$r21,0 - // m_pTargetCode data - // m_pvSecretParam data - - m_code[0] = 0x18000095; //pcaddi $r21,4 - m_code[1] = 0x28c022ae; //ld.d $t2,$r21,8 - m_code[2] = 0x28c002b5; //ld.d $r21,$r21,0 - m_code[3] = 0x4c0002a0; //jirl $r0,$r21,0 - - m_pTargetCode = (TADDR)pTargetCode; - m_pvSecretParam = (TADDR)pvSecretParam; - FlushInstructionCache(GetCurrentProcess(),&pEntryThunkCodeRX->m_code,sizeof(m_code)); -} - -#ifndef DACCESS_COMPILE - -void UMEntryThunkCode::Poison() -{ - ExecutableWriterHolder thunkWriterHolder(this, sizeof(UMEntryThunkCode)); - UMEntryThunkCode *pThisRW = thunkWriterHolder.GetRW(); - - pThisRW->m_pTargetCode = (TADDR)UMEntryThunk::ReportViolation; - - // ld.d $a0,$r21,8 - pThisRW->m_code[1] = 0x28c022a4; - - ClrFlushInstructionCache(&m_code,sizeof(m_code)); -} - -#endif // DACCESS_COMPILE - - #if !defined(DACCESS_COMPILE) VOID ResetCurrentContext() { diff --git a/src/coreclr/vm/loongarch64/thunktemplates.S b/src/coreclr/vm/loongarch64/thunktemplates.S index e53d2b9626a8e6..7deab2b6eadf29 100644 --- a/src/coreclr/vm/loongarch64/thunktemplates.S +++ b/src/coreclr/vm/loongarch64/thunktemplates.S @@ -8,7 +8,7 @@ LEAF_ENTRY StubPrecodeCode pcaddi $r21, 0x1004 //4, for Type encoding. - ld.d $t2,$r21, (StubPrecodeData__MethodDesc - 4*4) + ld.d $t2,$r21, (StubPrecodeData__SecretParam - 4*4) ld.d $r21,$r21, (StubPrecodeData__Target - 4*4) jirl $r0,$r21,0 LEAF_END_MARKED StubPrecodeCode diff --git a/src/coreclr/vm/peimage.cpp b/src/coreclr/vm/peimage.cpp index 7592ef2a3bf3b7..ebd83155e94ecb 100644 --- a/src/coreclr/vm/peimage.cpp +++ b/src/coreclr/vm/peimage.cpp @@ -385,49 +385,11 @@ void PEImage::GetMVID(GUID *pMvid) //may outlive PEImage PEImage::IJWFixupData::IJWFixupData(void *pBase) : m_lock(CrstIJWFixupData), - m_base(pBase), m_flags(0), m_DllThunkHeap(NULL), m_iNextFixup(0), m_iNextMethod(0) + m_base(pBase), m_flags(0), m_iNextFixup(0), m_iNextMethod(0) { WRAPPER_NO_CONTRACT; } -PEImage::IJWFixupData::~IJWFixupData() -{ - WRAPPER_NO_CONTRACT; - if (m_DllThunkHeap) - delete m_DllThunkHeap; -} - - -// Self-initializing accessor for m_DllThunkHeap -LoaderHeap *PEImage::IJWFixupData::GetThunkHeap() -{ - CONTRACT(LoaderHeap *) - { - INSTANCE_CHECK; - THROWS; - GC_NOTRIGGER; - MODE_ANY; - INJECT_FAULT(COMPlusThrowOM()); - POSTCONDITION(CheckPointer(RETVAL)); - } - CONTRACT_END - - if (!m_DllThunkHeap) - { - LoaderHeap *pNewHeap = new LoaderHeap(VIRTUAL_ALLOC_RESERVE_GRANULARITY, // DWORD dwReserveBlockSize - 0, // DWORD dwCommitBlockSize - ThunkHeapStubManager::g_pManager->GetRangeList(), - UnlockedLoaderHeap::HeapKind::Executable); - - if (InterlockedCompareExchangeT((PVOID*)&m_DllThunkHeap, (VOID*)pNewHeap, (VOID*)0) != 0) - { - delete pNewHeap; - } - } - - RETURN m_DllThunkHeap; -} - void PEImage::IJWFixupData::MarkMethodFixedUp(COUNT_T iFixup, COUNT_T iMethod) { LIMITED_METHOD_CONTRACT; @@ -452,19 +414,6 @@ BOOL PEImage::IJWFixupData::IsMethodFixedUp(COUNT_T iFixup, COUNT_T iMethod) return FALSE; } -/*static */ -PTR_LoaderHeap PEImage::GetDllThunkHeap(void *pBase) -{ - CONTRACTL - { - THROWS; - GC_TRIGGERS; - MODE_ANY; - } - CONTRACTL_END; - return GetIJWData(pBase)->GetThunkHeap(); -} - /* static */ PEImage::IJWFixupData *PEImage::GetIJWData(void *pBase) { @@ -492,29 +441,6 @@ PEImage::IJWFixupData *PEImage::GetIJWData(void *pBase) return (pData); } -/* static */ -void PEImage::UnloadIJWModule(void *pBase) -{ - CONTRACTL{ - NOTHROW; - GC_TRIGGERS; - MODE_ANY; - } CONTRACTL_END - - // Take the IJW hash lock - CrstHolder hashLockHolder(&s_ijwHashLock); - - // Try to delete the hash entry - IJWFixupData *pData = (IJWFixupData *)s_ijwFixupDataHash->DeleteValue((UPTR)pBase, pBase); - - // Now delete the data - if ((UPTR)pData != (UPTR)INVALIDENTRY) - delete pData; -} - - - - #endif // #ifndef DACCESS_COMPILE #ifdef DACCESS_COMPILE diff --git a/src/coreclr/vm/peimage.h b/src/coreclr/vm/peimage.h index ad885ebbabc9c7..1555194a99e0ec 100644 --- a/src/coreclr/vm/peimage.h +++ b/src/coreclr/vm/peimage.h @@ -237,7 +237,6 @@ class PEImage final Crst m_lock; void* m_base; DWORD m_flags; - PTR_LoaderHeap m_DllThunkHeap; // the fixup for the next iteration in FixupVTables // we use it to make sure that we do not try to fix up the same entry twice @@ -251,19 +250,15 @@ class PEImage final public: IJWFixupData(void* pBase); - ~IJWFixupData(); void* GetBase() { LIMITED_METHOD_CONTRACT; return m_base; } Crst* GetLock() { LIMITED_METHOD_CONTRACT; return &m_lock; } BOOL IsFixedUp() { LIMITED_METHOD_CONTRACT; return m_flags & e_FIXED_UP; } void SetIsFixedUp() { LIMITED_METHOD_CONTRACT; m_flags |= e_FIXED_UP; } - PTR_LoaderHeap GetThunkHeap(); void MarkMethodFixedUp(COUNT_T iFixup, COUNT_T iMethod); BOOL IsMethodFixedUp(COUNT_T iFixup, COUNT_T iMethod); }; static IJWFixupData* GetIJWData(void* pBase); - static PTR_LoaderHeap GetDllThunkHeap(void* pBase); - static void UnloadIJWModule(void* pBase); private: diff --git a/src/coreclr/vm/precode.cpp b/src/coreclr/vm/precode.cpp index 08d4c164585e46..75743dbd9e5258 100644 --- a/src/coreclr/vm/precode.cpp +++ b/src/coreclr/vm/precode.cpp @@ -9,6 +9,7 @@ #include "common.h" +#include "dllimportcallback.h" #ifdef FEATURE_PERFMAP #include "perfmap.h" @@ -33,12 +34,21 @@ BOOL Precode::IsValidType(PrecodeType t) #ifdef HAS_THISPTR_RETBUF_PRECODE case PRECODE_THISPTR_RETBUF: #endif // HAS_THISPTR_RETBUF_PRECODE + case PRECODE_UMENTRY_THUNK: return TRUE; default: return FALSE; } } +UMEntryThunk* Precode::AsUMEntryThunk() +{ + LIMITED_METHOD_CONTRACT; + SUPPORTS_DAC; + + return dac_cast(this); +} + SIZE_T Precode::SizeOf(PrecodeType t) { LIMITED_METHOD_CONTRACT; @@ -247,7 +257,7 @@ void Precode::Init(Precode* pPrecodeRX, PrecodeType t, MethodDesc* pMD, LoaderAl switch (t) { case PRECODE_STUB: - ((StubPrecode*)this)->Init((StubPrecode*)pPrecodeRX, pMD, pLoaderAllocator); + ((StubPrecode*)this)->Init((StubPrecode*)pPrecodeRX, (TADDR)pMD, pLoaderAllocator); break; #ifdef HAS_NDIRECT_IMPORT_PRECODE case PRECODE_NDIRECT_IMPORT: @@ -388,8 +398,8 @@ void FixupPrecode::EnumMemoryRegions(CLRDataEnumMemoryFlags flags) #ifndef DACCESS_COMPILE -void StubPrecode::Init(StubPrecode* pPrecodeRX, MethodDesc* pMD, LoaderAllocator *pLoaderAllocator /* = NULL */, - BYTE type /* = StubPrecode::Type */, TADDR target /* = NULL */) +void StubPrecode::Init(StubPrecode* pPrecodeRX, TADDR secretParam, LoaderAllocator *pLoaderAllocator /* = NULL */, + TADDR type /* = StubPrecode::Type */, TADDR target /* = NULL */) { WRAPPER_NO_CONTRACT; @@ -404,7 +414,7 @@ void StubPrecode::Init(StubPrecode* pPrecodeRX, MethodDesc* pMD, LoaderAllocator pStubData->Target = target; } - pStubData->MethodDesc = pMD; + pStubData->SecretParam = secretParam; pStubData->Type = type; } @@ -474,7 +484,7 @@ void StubPrecode::GenerateCodePage(BYTE* pageBase, BYTE* pageBaseRX, SIZE_T page BYTE* pTargetSlot = pageBaseRX + i + pageSize + offsetof(StubPrecodeData, Target); *(BYTE**)(pageBase + i + SYMBOL_VALUE(StubPrecodeCode_Target_Offset)) = pTargetSlot; - BYTE* pMethodDescSlot = pageBaseRX + i + pageSize + offsetof(StubPrecodeData, MethodDesc); + BYTE* pMethodDescSlot = pageBaseRX + i + pageSize + offsetof(StubPrecodeData, SecretParam); *(BYTE**)(pageBase + i + SYMBOL_VALUE(StubPrecodeCode_MethodDesc_Offset)) = pMethodDescSlot; } #else // TARGET_X86 @@ -487,7 +497,7 @@ BOOL StubPrecode::IsStubPrecodeByASM(PCODE addr) BYTE *pInstr = (BYTE*)PCODEToPINSTR(addr); #ifdef TARGET_X86 return *pInstr == *(BYTE*)(StubPrecodeCode) && - *(DWORD*)(pInstr + SYMBOL_VALUE(StubPrecodeCode_MethodDesc_Offset)) == (DWORD)(pInstr + GetStubCodePageSize() + offsetof(StubPrecodeData, MethodDesc)) && + *(DWORD*)(pInstr + SYMBOL_VALUE(StubPrecodeCode_MethodDesc_Offset)) == (DWORD)(pInstr + GetStubCodePageSize() + offsetof(StubPrecodeData, SecretParam)) && *(WORD*)(pInstr + 5) == *(WORD*)((BYTE*)StubPrecodeCode + 5) && *(DWORD*)(pInstr + SYMBOL_VALUE(StubPrecodeCode_Target_Offset)) == (DWORD)(pInstr + GetStubCodePageSize() + offsetof(StubPrecodeData, Target)); #else // TARGET_X86 @@ -520,7 +530,7 @@ void InterpreterPrecode::Init(InterpreterPrecode* pPrecodeRX, TADDR byteCodeAddr void NDirectImportPrecode::Init(NDirectImportPrecode* pPrecodeRX, MethodDesc* pMD, LoaderAllocator *pLoaderAllocator) { WRAPPER_NO_CONTRACT; - StubPrecode::Init(pPrecodeRX, pMD, pLoaderAllocator, NDirectImportPrecode::Type, GetEEFuncEntryPoint(NDirectImportThunk)); + StubPrecode::Init(pPrecodeRX, (TADDR)pMD, pLoaderAllocator, NDirectImportPrecode::Type, GetEEFuncEntryPoint(NDirectImportThunk)); } #endif // HAS_NDIRECT_IMPORT_PRECODE diff --git a/src/coreclr/vm/precode.h b/src/coreclr/vm/precode.h index ebe53d16463d60..c9a07e8751b217 100644 --- a/src/coreclr/vm/precode.h +++ b/src/coreclr/vm/precode.h @@ -76,9 +76,10 @@ struct InvalidPrecode struct StubPrecodeData { - PTR_MethodDesc MethodDesc; + TADDR SecretParam; PCODE Target; - BYTE Type; + TADDR Type; // Use a TADDR here instead of just a byte, so that different offsets into the StubPrecode can't mistakenly + // match the Type field. This is a defense-in-depth measure (and only matters for access from the debugger) }; typedef DPTR(StubPrecodeData) PTR_StubPrecodeData; @@ -92,6 +93,10 @@ extern "C" void StubPrecodeCode_End(); extern "C" void InterpreterStub(); #endif +class UMEntryThunk; +typedef DPTR(class UMEntryThunk) PTR_UMEntryThunk; +#define PRECODE_UMENTRY_THUNK_VALUE 0x7 // Define the value here and not in UMEntryThunk to avoid circular dependency with the dllimportcallback.h header + // Regular precode struct StubPrecode { @@ -122,7 +127,7 @@ struct StubPrecode static void (*StubPrecodeCode_End)(); #endif - void Init(StubPrecode* pPrecodeRX, MethodDesc* pMD, LoaderAllocator *pLoaderAllocator = NULL, BYTE type = StubPrecode::Type, TADDR target = 0); + void Init(StubPrecode* pPrecodeRX, TADDR secretParam, LoaderAllocator *pLoaderAllocator = NULL, TADDR type = StubPrecode::Type, TADDR target = 0); static void StaticInitialize(); @@ -132,11 +137,22 @@ struct StubPrecode return dac_cast(dac_cast(this) + GetStubCodePageSize()); } - TADDR GetMethodDesc() + TADDR GetMethodDesc(); + +#ifndef DACCESS_COMPILE + void SetSecretParam(TADDR secretParam) { - LIMITED_METHOD_DAC_CONTRACT; + LIMITED_METHOD_CONTRACT; + + GetData()->SecretParam = secretParam; + } +#endif // DACCESS_COMPILE + + TADDR GetSecretParam() const + { + LIMITED_METHOD_CONTRACT; - return dac_cast(GetData()->MethodDesc); + return GetData()->SecretParam; } PCODE GetTarget() @@ -146,10 +162,7 @@ struct StubPrecode return GetData()->Target; } - BYTE GetType() - { - return GetData()->Type; - } + BYTE GetType(); #ifndef DACCESS_COMPILE static BOOL IsStubPrecodeByASM(PCODE addr); @@ -178,7 +191,21 @@ struct StubPrecode StubPrecodeData *pData = GetData(); return InterlockedCompareExchangeT(&pData->Target, (PCODE)target, (PCODE)expected) == expected; - } + } + + void SetTargetUnconditional(TADDR target) + { + CONTRACTL + { + NOTHROW; + GC_NOTRIGGER; + MODE_ANY; + } + CONTRACTL_END; + + StubPrecodeData *pData = GetData(); + pData->Target = (PCODE)target; + } static void GenerateCodePage(BYTE* pageBase, BYTE* pageBaseRX, SIZE_T size); @@ -394,13 +421,60 @@ enum PrecodeType { #ifdef HAS_THISPTR_RETBUF_PRECODE PRECODE_THISPTR_RETBUF = ThisPtrRetBufPrecode::Type, #endif // HAS_THISPTR_RETBUF_PRECODE + PRECODE_UMENTRY_THUNK = PRECODE_UMENTRY_THUNK_VALUE, // Set the value here and not in UMEntryThunk to avoid circular dependency }; +inline TADDR StubPrecode::GetMethodDesc() +{ + LIMITED_METHOD_DAC_CONTRACT; + + switch (GetType()) + { + case PRECODE_STUB: + case PRECODE_NDIRECT_IMPORT: + return GetSecretParam(); + + case PRECODE_UMENTRY_THUNK: +#ifdef FEATURE_INTERPRETER + case PRECODE_INTERPRETER: +#endif // FEATURE_INTERPRETER + return 0; + } + + _ASSERTE(!"Unknown precode type"); + return 0; +} + +inline BYTE StubPrecode::GetType() +{ + LIMITED_METHOD_DAC_CONTRACT; + TADDR type = GetData()->Type; + + // There are a limited number of valid bit patterns here. Restrict to those, so that the + // speculative variant of GetPrecodeFromEntryPoint is more robust. Type is stored as a TADDR + // so that a single byte matching is not enough to cause a false match. + switch (type) + { + case PRECODE_UMENTRY_THUNK: + case PRECODE_STUB: + case PRECODE_NDIRECT_IMPORT: +#ifdef FEATURE_INTERPRETER + case PRECODE_INTERPRETER: +#endif // FEATURE_INTERPRETER + return (BYTE)type; + } + + return 0; +} + + // For more details see. file:../../doc/BookOfTheRuntime/ClassLoader/MethodDescDesign.doc class Precode { BYTE m_data[SIZEOF_PRECODE_BASE]; +public: + UMEntryThunk* AsUMEntryThunk(); StubPrecode* AsStubPrecode() { LIMITED_METHOD_CONTRACT; @@ -408,6 +482,7 @@ class Precode { return dac_cast(this); } +private: #ifdef HAS_NDIRECT_IMPORT_PRECODE public: diff --git a/src/coreclr/vm/riscv64/asmconstants.h b/src/coreclr/vm/riscv64/asmconstants.h index a79476b33eda27..e1e890efad0272 100644 --- a/src/coreclr/vm/riscv64/asmconstants.h +++ b/src/coreclr/vm/riscv64/asmconstants.h @@ -202,8 +202,8 @@ ASMCONSTANTS_C_ASSERT(FixupPrecodeData__PrecodeFixupThunk == offsetof(FixupPreco #define StubPrecodeData__Target 0x08 ASMCONSTANTS_C_ASSERT(StubPrecodeData__Target == offsetof(StubPrecodeData, Target)) -#define StubPrecodeData__MethodDesc 0x00 -ASMCONSTANTS_C_ASSERT(StubPrecodeData__MethodDesc == offsetof(StubPrecodeData, MethodDesc)) +#define StubPrecodeData__SecretParam 0x00 +ASMCONSTANTS_C_ASSERT(StubPrecodeData__SecretParam == offsetof(StubPrecodeData, SecretParam)) #define CallCountingStubData__RemainingCallCountCell 0x00 ASMCONSTANTS_C_ASSERT(CallCountingStubData__RemainingCallCountCell == offsetof(CallCountingStubData, RemainingCallCountCell)) diff --git a/src/coreclr/vm/riscv64/cgencpu.h b/src/coreclr/vm/riscv64/cgencpu.h index 1d7dec10ce889b..b6dac4cc709ec0 100644 --- a/src/coreclr/vm/riscv64/cgencpu.h +++ b/src/coreclr/vm/riscv64/cgencpu.h @@ -390,32 +390,6 @@ class StubLinkerCPU : public StubLinker // preferred alignment for data #define DATA_ALIGNMENT 8 -// TODO RISCV64 -struct DECLSPEC_ALIGN(16) UMEntryThunkCode -{ - DWORD m_code[4]; - - TADDR m_pTargetCode; - TADDR m_pvSecretParam; - - void Encode(UMEntryThunkCode *pEntryThunkCodeRX, BYTE* pTargetCode, void* pvSecretParam); - void Poison(); - - LPCBYTE GetEntryPoint() const - { - LIMITED_METHOD_CONTRACT; - - return (LPCBYTE)this; - } - - static int GetEntryPointOffset() - { - LIMITED_METHOD_CONTRACT; - - return 0; - } -}; - struct HijackArgs { DWORD64 Fp; // frame pointer diff --git a/src/coreclr/vm/riscv64/stubs.cpp b/src/coreclr/vm/riscv64/stubs.cpp index 0d3d0e2f80d7cd..e5f91333c7f00a 100644 --- a/src/coreclr/vm/riscv64/stubs.cpp +++ b/src/coreclr/vm/riscv64/stubs.cpp @@ -909,62 +909,6 @@ AdjustContextForVirtualStub( } #endif // !DACCESS_COMPILE -UMEntryThunk * UMEntryThunk::Decode(void *pCallback) -{ - _ASSERTE(offsetof(UMEntryThunkCode, m_code) == 0); - UMEntryThunkCode * pCode = (UMEntryThunkCode*)pCallback; - - // We may be called with an unmanaged external code pointer instead. So if it doesn't look like one of our - // stubs (see UMEntryThunkCode::Encode below) then we'll return NULL. Luckily in these scenarios our - // caller will perform a hash lookup on successful return to verify our result in case random unmanaged - // code happens to look like ours. - if ((pCode->m_code[0] == 0x00000f97) && // auipc t6, 0 - (pCode->m_code[1] == 0x018fb383) && // ld t2, 24(t6) - (pCode->m_code[2] == 0x010fbf83) && // ld t6, 16(t6) - (pCode->m_code[3] == 0x000f8067)) // jalr x0, 0(t6) - { - return (UMEntryThunk*)pCode->m_pvSecretParam; - } - - return NULL; -} - -void UMEntryThunkCode::Encode(UMEntryThunkCode *pEntryThunkCodeRX, BYTE* pTargetCode, void* pvSecretParam) -{ - // auipc t6, 0 - // ld t2, 24(t6) - // ld t6, 16(t6) - // jalr x0, 0(t6) - // m_pTargetCode data - // m_pvSecretParam data - - m_code[0] = 0x00000f97; // auipc t6, 0 - m_code[1] = 0x018fb383; // ld t2, 24(t6) - m_code[2] = 0x010fbf83; // ld t6, 16(t6) - m_code[3] = 0x000f8067; // jalr x0, 0(t6) - - m_pTargetCode = (TADDR)pTargetCode; - m_pvSecretParam = (TADDR)pvSecretParam; - FlushInstructionCache(GetCurrentProcess(),&pEntryThunkCodeRX->m_code,sizeof(m_code)); -} - -#ifndef DACCESS_COMPILE - -void UMEntryThunkCode::Poison() -{ - ExecutableWriterHolder thunkWriterHolder(this, sizeof(UMEntryThunkCode)); - UMEntryThunkCode *pThisRW = thunkWriterHolder.GetRW(); - - pThisRW->m_pTargetCode = (TADDR)UMEntryThunk::ReportViolation; - - // ld a0, 24(t6) - pThisRW->m_code[1] = 0x018fb503; - - ClrFlushInstructionCache(&m_code,sizeof(m_code)); -} - -#endif // DACCESS_COMPILE - #if !defined(DACCESS_COMPILE) VOID ResetCurrentContext() { diff --git a/src/coreclr/vm/riscv64/thunktemplates.S b/src/coreclr/vm/riscv64/thunktemplates.S index 1bc674688daafe..8b58b4ec48b0db 100644 --- a/src/coreclr/vm/riscv64/thunktemplates.S +++ b/src/coreclr/vm/riscv64/thunktemplates.S @@ -6,7 +6,7 @@ LEAF_ENTRY StubPrecodeCode auipc t1, 0x4 - ld t2, (StubPrecodeData__MethodDesc)(t1) + ld t2, (StubPrecodeData__SecretParam)(t1) ld t1, (StubPrecodeData__Target)(t1) jr t1 LEAF_END_MARKED StubPrecodeCode diff --git a/src/coreclr/vm/stubmgr.cpp b/src/coreclr/vm/stubmgr.cpp index d7474b7ea98615..df6b385d30ccd8 100644 --- a/src/coreclr/vm/stubmgr.cpp +++ b/src/coreclr/vm/stubmgr.cpp @@ -992,7 +992,6 @@ void PrecodeStubManager::Init() #endif // #ifndef DACCESS_COMPILE -/* static */ BOOL PrecodeStubManager::CheckIsStub_Internal(PCODE stubStartAddress) { CONTRACTL @@ -1004,7 +1003,24 @@ BOOL PrecodeStubManager::CheckIsStub_Internal(PCODE stubStartAddress) CONTRACTL_END; auto stubKind = RangeSectionStubManager::GetStubKind(stubStartAddress); - return (stubKind == STUB_CODE_BLOCK_FIXUPPRECODE) || (stubKind == STUB_CODE_BLOCK_STUBPRECODE); + if (stubKind == STUB_CODE_BLOCK_FIXUPPRECODE) + { + return TRUE; + } + else if (stubKind == STUB_CODE_BLOCK_STUBPRECODE) + { + Precode* pPrecode = Precode::GetPrecodeFromEntryPoint(stubStartAddress); + switch (pPrecode->GetType()) + { + case PRECODE_STUB: + case PRECODE_NDIRECT_IMPORT: + case PRECODE_UMENTRY_THUNK: + return TRUE; + default: + return FALSE; + } + } + return FALSE; } BOOL PrecodeStubManager::DoTraceStub(PCODE stubStartAddress, @@ -1027,8 +1043,16 @@ BOOL PrecodeStubManager::DoTraceStub(PCODE stubStartAddress, { // When the target slot points to the fixup part of the fixup precode, we need to compensate // for that to get the actual stub address - Precode* pPrecode = Precode::GetPrecodeFromEntryPoint(stubStartAddress - FixupPrecode::FixupCodeOffset, TRUE /* speculative */); - if ((pPrecode == NULL) || (pPrecode->GetType() != PRECODE_FIXUP)) + Precode* pPrecode = NULL; + if (RangeSectionStubManager::GetStubKind(stubStartAddress) == STUB_CODE_BLOCK_FIXUPPRECODE) + { + pPrecode = Precode::GetPrecodeFromEntryPoint(stubStartAddress - FixupPrecode::FixupCodeOffset, TRUE /* speculative */); + if (pPrecode != NULL && pPrecode->GetType() != PRECODE_FIXUP) + { + pPrecode = NULL; + } + } + if (pPrecode == NULL) { pPrecode = Precode::GetPrecodeFromEntryPoint(stubStartAddress); } @@ -1037,6 +1061,12 @@ BOOL PrecodeStubManager::DoTraceStub(PCODE stubStartAddress, switch (pPrecode->GetType()) { + case PRECODE_UMENTRY_THUNK: + LOG((LF_CORDB, LL_EVERYTHING, "PrecodeStubManager::DoTraceStub called on UMEntryThunk\n")); + // We never trace through these stubs when stepping through managed code. The reason we handle this at all is so that + // is so that IsTransitionStub can recognize UMEntryThunks. + return FALSE; + case PRECODE_STUB: break; @@ -1391,54 +1421,6 @@ BOOL StubLinkStubManager::TraceManager(Thread *thread, #endif // #ifndef DACCESS_COMPILE -// ------------------------------------------------------- -// Stub manager for thunks. -// -// Note, the only reason we have this stub manager is so that we can recgonize UMEntryThunks for IsTransitionStub. If it -// turns out that having a full-blown stub manager for these things causes problems else where, then we can just attach -// a range list to the thunk heap and have IsTransitionStub check that after checking with the main stub manager. -// ------------------------------------------------------- - -SPTR_IMPL(ThunkHeapStubManager, ThunkHeapStubManager, g_pManager); - -#ifndef DACCESS_COMPILE - -/* static */ -void ThunkHeapStubManager::Init() -{ - CONTRACTL - { - THROWS; - GC_NOTRIGGER; - MODE_ANY; - INJECT_FAULT(COMPlusThrowOM()); - } - CONTRACTL_END; - - g_pManager = new ThunkHeapStubManager(); - StubManager::AddStubManager(g_pManager); -} - -#endif // !DACCESS_COMPILE - -BOOL ThunkHeapStubManager::CheckIsStub_Internal(PCODE stubStartAddress) -{ - WRAPPER_NO_CONTRACT; - SUPPORTS_DAC; - - // Its a stub if its in our heaps range. - return GetRangeList()->IsInRange(stubStartAddress); -} - -BOOL ThunkHeapStubManager::DoTraceStub(PCODE stubStartAddress, - TraceDestination *trace) -{ - LIMITED_METHOD_CONTRACT; - // We never trace through these stubs when stepping through managed code. The only reason we have this stub manager - // is so that IsTransitionStub can recgonize UMEntryThunks. - return FALSE; -} - // ------------------------------------------------------- // JumpStub stubs // @@ -2181,16 +2163,6 @@ StubLinkStubManager::DoEnumMemoryRegions(CLRDataEnumMemoryFlags flags) GetRangeList()->EnumMemoryRegions(flags); } -void -ThunkHeapStubManager::DoEnumMemoryRegions(CLRDataEnumMemoryFlags flags) -{ - SUPPORTS_DAC; - WRAPPER_NO_CONTRACT; - DAC_ENUM_VTHIS(); - EMEM_OUT(("MEM: %p ThunkHeapStubManager\n", dac_cast(this))); - GetRangeList()->EnumMemoryRegions(flags); -} - void JumpStubStubManager::DoEnumMemoryRegions(CLRDataEnumMemoryFlags flags) { diff --git a/src/coreclr/vm/stubmgr.h b/src/coreclr/vm/stubmgr.h index 7446ac54190c5e..a79ad2eb88110a 100644 --- a/src/coreclr/vm/stubmgr.h +++ b/src/coreclr/vm/stubmgr.h @@ -502,53 +502,6 @@ class StubLinkStubManager : public StubManager #endif } ; -// Stub manager for thunks. - -typedef VPTR(class ThunkHeapStubManager) PTR_ThunkHeapStubManager; - -class ThunkHeapStubManager : public StubManager -{ - VPTR_VTABLE_CLASS(ThunkHeapStubManager, StubManager) - - public: - - SPTR_DECL(ThunkHeapStubManager, g_pManager); - - static void Init(); - -#ifndef DACCESS_COMPILE - ThunkHeapStubManager() : StubManager(), m_rangeList() { LIMITED_METHOD_CONTRACT; } - ~ThunkHeapStubManager() {WRAPPER_NO_CONTRACT;} -#endif - -#ifdef _DEBUG - virtual const char * DbgGetName() { LIMITED_METHOD_CONTRACT; return "ThunkHeapStubManager"; } -#endif - - protected: - LockedRangeList m_rangeList; - public: - // Get dac-ized pointer to rangelist. - PTR_RangeList GetRangeList() - { - SUPPORTS_DAC; - TADDR addr = PTR_HOST_MEMBER_TADDR(ThunkHeapStubManager, this, m_rangeList); - return PTR_RangeList(addr); - } - virtual BOOL CheckIsStub_Internal(PCODE stubStartAddress); - - private: - virtual BOOL DoTraceStub(PCODE stubStartAddress, TraceDestination *trace); - -#ifdef DACCESS_COMPILE - virtual void DoEnumMemoryRegions(CLRDataEnumMemoryFlags flags); - - protected: - virtual LPCWSTR GetStubManagerName(PCODE addr) - { LIMITED_METHOD_CONTRACT; return W("ThunkHeapStub"); } -#endif -}; - // // Stub manager for jump stubs created by ExecutionManager::jumpStub() // These are currently used only on the 64-bit targets IA64 and AMD64 diff --git a/src/coreclr/vm/syncblk.cpp b/src/coreclr/vm/syncblk.cpp index 3fb9089bf31c54..f10943af954c8b 100644 --- a/src/coreclr/vm/syncblk.cpp +++ b/src/coreclr/vm/syncblk.cpp @@ -115,7 +115,6 @@ void InteropSyncBlockInfo::FreeUMEntryThunk() void *pUMEntryThunk = GetUMEntryThunk(); if (pUMEntryThunk != NULL) { - COMDelegate::RemoveEntryFromFPtrHash((UPTR)pUMEntryThunk); UMEntryThunk::FreeUMEntryThunk((UMEntryThunk *)pUMEntryThunk); } }