Skip to content

Commit

Permalink
Delete STUBLINKER_GENERATES_UNWIND_INFO (#108684)
Browse files Browse the repository at this point in the history
None of the stublinker stubs need this anymore
  • Loading branch information
jkotas authored and pull[bot] committed Oct 30, 2024
1 parent 5f44aea commit 1642664
Show file tree
Hide file tree
Showing 28 changed files with 70 additions and 3,130 deletions.
181 changes: 5 additions & 176 deletions src/coreclr/debug/daccess/fntableaccess.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -139,11 +139,11 @@ static NTSTATUS OutOfProcessFindHeader(ReadMemoryFunction fpReadMemory,PVOID pUs
pHeader = tmp; \
}

static NTSTATUS OutOfProcessFunctionTableCallback_JIT(IN ReadMemoryFunction fpReadMemory,
IN PVOID pUserContext,
IN PVOID TableAddress,
OUT PULONG pnEntries,
OUT PT_RUNTIME_FUNCTION* ppFunctions)
extern "C" NTSTATUS OutOfProcessFunctionTableCallbackEx(IN ReadMemoryFunction fpReadMemory,
IN PVOID pUserContext,
IN PVOID TableAddress,
OUT PULONG pnEntries,
OUT PT_RUNTIME_FUNCTION* ppFunctions)
{
if (NULL == pnEntries) { return STATUS_INVALID_PARAMETER_3; }
if (NULL == ppFunctions) { return STATUS_INVALID_PARAMETER_4; }
Expand Down Expand Up @@ -270,135 +270,6 @@ static NTSTATUS OutOfProcessFunctionTableCallback_JIT(IN ReadMemoryFunction
return STATUS_SUCCESS;
}


#ifdef DEBUGSUPPORT_STUBS_HAVE_UNWIND_INFO

static NTSTATUS OutOfProcessFunctionTableCallback_Stub(IN ReadMemoryFunction fpReadMemory,
IN PVOID pUserContext,
IN PVOID TableAddress,
OUT PULONG pnEntries,
OUT PT_RUNTIME_FUNCTION* ppFunctions)
{
if (NULL == pnEntries) { return STATUS_INVALID_PARAMETER_3; }
if (NULL == ppFunctions) { return STATUS_INVALID_PARAMETER_4; }

*ppFunctions = 0;
*pnEntries = 0;

PVOID pvContext;
move_field(pvContext, TableAddress, DYNAMIC_FUNCTION_TABLE, Context);

SIZE_T pStubHeapSegment = ((SIZE_T)pvContext & ~3);

FakeStubUnwindInfoHeapSegment stubHeapSegment;
move(stubHeapSegment, pStubHeapSegment);

UINT nEntries = 0;
UINT nEntriesAllocated = 0;
PT_RUNTIME_FUNCTION rgFunctions = NULL;

for (int pass = 1; pass <= 2; pass++)
{
// Use the same initial header for both passes. The process may still be running,
// and so new entries could be added at the beginning of the list. Using the initial header
// makes sure new entries are not picked up in the second pass. Entries could also be deleted,
// and there is a small time window here where we could read invalid memory. This just means
// that ReadProcessMemory() may fail. As long as we don't crash the host process (e.g. WER)
// we are fine.
SIZE_T pHeader = (SIZE_T)stubHeapSegment.pUnwindHeaderList;

while (pHeader)
{
FakeStubUnwindInfoHeader unwindInfoHeader;
move(unwindInfoHeader, pHeader);
#if defined(TARGET_AMD64)
// Consistency checks to detect corrupted process state
if (unwindInfoHeader.FunctionEntry.BeginAddress > unwindInfoHeader.FunctionEntry.EndAddress ||
unwindInfoHeader.FunctionEntry.EndAddress > stubHeapSegment.cbSegment)
{
_ASSERTE(1 == pass);
return STATUS_UNSUCCESSFUL;
}

if ((SIZE_T)stubHeapSegment.pbBaseAddress + unwindInfoHeader.FunctionEntry.UnwindData !=
pHeader + offsetof(FakeStubUnwindInfoHeader, UnwindInfo))
{
_ASSERTE(1 == pass);
return STATUS_UNSUCCESSFUL;
}
#elif defined(TARGET_ARM)

// Skip checking the corrupted process stateon ARM

#elif defined(TARGET_ARM64)
// Compute the function length
ULONG64 functionLength = 0;
ULONG64 unwindData = unwindInfoHeader.FunctionEntry.UnwindData;
if (( unwindData & 3) != 0) {
// the unwindData contains the function length, retrieve it directly from unwindData
functionLength = (unwindInfoHeader.FunctionEntry.UnwindData >> 2) & 0x7ff;
} else {
// the unwindData is an RVA to the .xdata record which contains the function length
DWORD xdataHeader=0;
if ((SIZE_T)stubHeapSegment.pbBaseAddress + unwindData != pHeader + offsetof(FakeStubUnwindInfoHeader, UnwindInfo))
{
_ASSERTE(1 == pass);
return STATUS_UNSUCCESSFUL;
}
move(xdataHeader, stubHeapSegment.pbBaseAddress + unwindData);
functionLength = (xdataHeader & 0x3ffff) << 2;
}
if (unwindInfoHeader.FunctionEntry.BeginAddress + functionLength > stubHeapSegment.cbSegment)
{
_ASSERTE(1 == pass);
return STATUS_UNSUCCESSFUL;
}
#else
PORTABILITY_ASSERT("OutOfProcessFunctionTableCallback_Stub");
#endif
if (nEntriesAllocated)
{
if (nEntries >= nEntriesAllocated)
break;
rgFunctions[nEntries] = unwindInfoHeader.FunctionEntry;
}
nEntries++;

pHeader = (SIZE_T)unwindInfoHeader.pNext;
}

if (1 == pass)
{
if (!nEntries)
break;

_ASSERTE(!nEntriesAllocated);
nEntriesAllocated = nEntries;

S_SIZE_T blockSize = S_SIZE_T(nEntries) * S_SIZE_T(sizeof(T_RUNTIME_FUNCTION));
if (blockSize.IsOverflow())
return STATUS_UNSUCCESSFUL;

rgFunctions = (PT_RUNTIME_FUNCTION)HeapAlloc(GetProcessHeap(), 0, blockSize.Value());
if (rgFunctions == NULL)
return STATUS_NO_MEMORY;
nEntries = 0;
}
else
{
_ASSERTE(nEntriesAllocated >= nEntries);
}
}

*ppFunctions = rgFunctions;
*pnEntries = nEntries; // return the final count

return STATUS_SUCCESS;
}

#endif // DEBUGSUPPORT_STUBS_HAVE_UNWIND_INFO


BOOL ReadMemory(PVOID pUserContext, LPCVOID lpBaseAddress, PVOID lpBuffer, SIZE_T nSize, SIZE_T* lpNumberOfBytesRead)
{
HANDLE hProcess = (HANDLE)pUserContext;
Expand All @@ -413,48 +284,6 @@ extern "C" NTSTATUS OutOfProcessFunctionTableCallback(IN HANDLE
return OutOfProcessFunctionTableCallbackEx(&ReadMemory, hProcess, TableAddress, pnEntries, ppFunctions);
}

extern "C" NTSTATUS OutOfProcessFunctionTableCallbackEx(IN ReadMemoryFunction fpReadMemory,
IN PVOID pUserContext,
IN PVOID TableAddress,
OUT PULONG pnEntries,
OUT PT_RUNTIME_FUNCTION* ppFunctions)
{
if (NULL == pnEntries) { return STATUS_INVALID_PARAMETER_3; }
if (NULL == ppFunctions) { return STATUS_INVALID_PARAMETER_4; }

DYNAMIC_FUNCTION_TABLE * pTable = (DYNAMIC_FUNCTION_TABLE *) TableAddress;
PVOID pvContext;

move(pvContext, &pTable->Context);

FakeEEDynamicFunctionTableType type = (FakeEEDynamicFunctionTableType)((SIZE_T)pvContext & 3);

switch (type)
{
case FAKEDYNFNTABLE_JIT:
return OutOfProcessFunctionTableCallback_JIT(
fpReadMemory,
pUserContext,
TableAddress,
pnEntries,
ppFunctions);

#ifdef DEBUGSUPPORT_STUBS_HAVE_UNWIND_INFO
case FAKEDYNFNTABLE_STUB:
return OutOfProcessFunctionTableCallback_Stub(
fpReadMemory,
pUserContext,
TableAddress,
pnEntries,
ppFunctions);
#endif // DEBUGSUPPORT_STUBS_HAVE_UNWIND_INFO
default:
break;
}

return STATUS_UNSUCCESSFUL;
}

#else

extern "C" NTSTATUS OutOfProcessFunctionTableCallback()
Expand Down
61 changes: 0 additions & 61 deletions src/coreclr/debug/daccess/fntableaccess.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,6 @@
#define _FN_TABLE_ACCESS_H


#if !defined(TARGET_X86)

#ifndef TARGET_UNIX
#define DEBUGSUPPORT_STUBS_HAVE_UNWIND_INFO
#endif // !TARGET_UNIX
#endif

struct FakeEEJitManager
{
LPVOID __VFN_table;
Expand Down Expand Up @@ -71,40 +64,6 @@ typedef struct _FakeHpCodeHdr

#define FAKE_STUB_CODE_BLOCK_LAST 0xF

#ifdef DEBUGSUPPORT_STUBS_HAVE_UNWIND_INFO

struct FakeStubUnwindInfoHeaderSuffix
{
UCHAR nUnwindInfoSize;
};

// Variable-sized struct that precedes a Stub when the stub requires unwind
// information. Followed by a StubUnwindInfoHeaderSuffix.
struct FakeStubUnwindInfoHeader
{
FakeStubUnwindInfoHeader *pNext;
T_RUNTIME_FUNCTION FunctionEntry;
UNWIND_INFO UnwindInfo; // variable length
};

// List of stub address ranges, in increasing address order.
struct FakeStubUnwindInfoHeapSegment
{
PBYTE pbBaseAddress;
SIZE_T cbSegment;
FakeStubUnwindInfoHeader *pUnwindHeaderList;
FakeStubUnwindInfoHeapSegment *pNext;
};

#endif // DEBUGSUPPORT_STUBS_HAVE_UNWIND_INFO


enum FakeEEDynamicFunctionTableType
{
FAKEDYNFNTABLE_JIT = 0,
FAKEDYNFNTABLE_STUB = 1,
};


#ifdef CHECK_DUPLICATED_STRUCT_LAYOUTS

Expand All @@ -130,29 +89,9 @@ class CheckDuplicatedStructLayouts
CHECK_OFFSET(RealCodeHeader, unwindInfos);
#endif // !TARGET_X86

#ifdef DEBUGSUPPORT_STUBS_HAVE_UNWIND_INFO
CHECK_OFFSET(StubUnwindInfoHeader, pNext);

CHECK_OFFSET(StubUnwindInfoHeapSegment, pbBaseAddress);
CHECK_OFFSET(StubUnwindInfoHeapSegment, cbSegment);
CHECK_OFFSET(StubUnwindInfoHeapSegment, pUnwindHeaderList);
CHECK_OFFSET(StubUnwindInfoHeapSegment, pNext);

#endif // DEBUGSUPPORT_STUBS_HAVE_UNWIND_INFO

#undef CHECK_OFFSET
};

#ifdef DEBUGSUPPORT_STUBS_HAVE_UNWIND_INFO

static_assert_no_msg( FAKEDYNFNTABLE_JIT
== DYNFNTABLE_JIT);

static_assert_no_msg( FAKEDYNFNTABLE_STUB
== DYNFNTABLE_STUB);

#endif // DEBUGSUPPORT_STUBS_HAVE_UNWIND_INFO

#else // CHECK_DUPLICATED_STRUCT_LAYOUTS

BOOL WINAPI DllMain(HINSTANCE hDLL, DWORD dwReason, LPVOID pReserved);
Expand Down
10 changes: 3 additions & 7 deletions src/coreclr/inc/CrstTypes.def
Original file line number Diff line number Diff line change
Expand Up @@ -256,7 +256,7 @@ End
Crst Interop
AcquiredBefore PinnedHeapHandleTable AvailableParamTypes ClassInit DeadlockDetection GenericDictionaryExpansion
HandleTable InstMethodHashTable InteropData LoaderHeap SigConvert
StubDispatchCache StubUnwindInfoHeapSegments SyncBlockCache TypeIDMap UnresolvedClassLock
StubDispatchCache SyncBlockCache TypeIDMap UnresolvedClassLock
PendingTypeLoadEntry
End

Expand Down Expand Up @@ -339,7 +339,7 @@ Crst PendingTypeLoadEntry
FusionAppCtx GlobalStrLiteralMap HandleTable IbcProfile
IJWFixupData IJWHash ISymUnmanagedReader Jit JumpStubCache LoaderHeap
Module ModuleLookupTable PEImage
SigConvert SingleUseLock StubDispatchCache StubUnwindInfoHeapSegments
SigConvert SingleUseLock StubDispatchCache
SyncBlockCache SystemDomain ThreadIdDispenser ThreadStore TypeIDMap UnresolvedClassLock
SameLevelAs PendingTypeLoadEntry
End
Expand Down Expand Up @@ -399,7 +399,7 @@ Crst SingleUseLock
End

Crst UnwindInfoTableLock
AcquiredAfter StubUnwindInfoHeapSegments SingleUseLock
AcquiredAfter SingleUseLock
AcquiredBefore StressLog
End

Expand All @@ -414,10 +414,6 @@ End
Crst StubDispatchCache
End

Crst StubUnwindInfoHeapSegments
AcquiredAfter StubCache
End

Crst SyncBlockCache
AcquiredBefore ThreadIdDispenser
End
Expand Down
2 changes: 0 additions & 2 deletions src/coreclr/inc/clrconfigvalues.h
Original file line number Diff line number Diff line change
Expand Up @@ -309,7 +309,6 @@ RETAIL_CONFIG_DWORD_INFO(UNSUPPORTED_JitFramed, W("JitFramed"), 0, "Forces EBP f
CONFIG_DWORD_INFO(INTERNAL_JitThrowOnAssertionFailure, W("JitThrowOnAssertionFailure"), 0, "Throw managed exception on assertion failures during JIT instead of failfast")
CONFIG_DWORD_INFO(INTERNAL_JitGCStress, W("JitGCStress"), 0, "GC stress mode for jit")
CONFIG_DWORD_INFO(INTERNAL_JitHeartbeat, W("JitHeartbeat"), 0, "")
CONFIG_DWORD_INFO(INTERNAL_JitHelperLogging, W("JitHelperLogging"), 0, "")
RETAIL_CONFIG_DWORD_INFO(UNSUPPORTED_JITMinOpts, W("JITMinOpts"), 0, "Forces MinOpts")

// *Some* relocs are just opportunistic optimizations and can be non-deterministic - it might produce
Expand Down Expand Up @@ -853,7 +852,6 @@ CONFIG_DWORD_INFO(INTERNAL_SBDumpOnNewIndex, W("SBDumpOnNewIndex"), 0, "Used for
CONFIG_DWORD_INFO(INTERNAL_SBDumpOnResize, W("SBDumpOnResize"), 0, "Used for Syncblock debugging. It's been a while since any of those have been used.")
CONFIG_DWORD_INFO(INTERNAL_SBDumpStyle, W("SBDumpStyle"), 0, "Used for Syncblock debugging. It's been a while since any of those have been used.")
RETAIL_CONFIG_DWORD_INFO(UNSUPPORTED_SleepOnExit, W("SleepOnExit"), 0, "Used for lrak detection. I'd say deprecated by umdh.")
CONFIG_DWORD_INFO(INTERNAL_StubLinkerUnwindInfoVerificationOn, W("StubLinkerUnwindInfoVerificationOn"), 0, "")
RETAIL_CONFIG_DWORD_INFO(UNSUPPORTED_SuccessExit, W("SuccessExit"), 0, "")
RETAIL_CONFIG_DWORD_INFO(UNSUPPORTED_TestDataConsistency, W("TestDataConsistency"), FALSE, "Allows ensuring the left side is not holding locks (and may thus be in an inconsistent state) when inspection occurs")
RETAIL_CONFIG_DWORD_INFO(EXTERNAL_ThreadGuardPages, W("ThreadGuardPages"), 0, "")
Expand Down
Loading

0 comments on commit 1642664

Please sign in to comment.