diff options
Diffstat (limited to 'src/debug/daccess/fntableaccess.h')
-rw-r--r-- | src/debug/daccess/fntableaccess.h | 216 |
1 files changed, 216 insertions, 0 deletions
diff --git a/src/debug/daccess/fntableaccess.h b/src/debug/daccess/fntableaccess.h new file mode 100644 index 0000000000..0dbabdf8c9 --- /dev/null +++ b/src/debug/daccess/fntableaccess.h @@ -0,0 +1,216 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +// + +#ifdef _MSC_VER +#pragma once +#endif + +#ifndef _FN_TABLE_ACCESS_H +#define _FN_TABLE_ACCESS_H + + +#if !defined(_TARGET_X86_) + +#ifndef FEATURE_PAL +#define DEBUGSUPPORT_STUBS_HAVE_UNWIND_INFO +#endif // !FEATURE_PAL + +#ifndef USE_INDIRECT_CODEHEADER +#define USE_INDIRECT_CODEHEADER +#endif // USE_INDIRECT_CODEHEADER +#endif + + +struct FakeEEJitManager +{ + LPVOID __VFN_table; + LPVOID m_runtimeSupport; + LPVOID m_pCodeHeap; + // Nothing after this point matters: we only need the correct offset of m_pCodeHeap. +}; + +struct FakeHeapList +{ + FakeHeapList* hpNext; + LPVOID pHeap; // changed type from LoaderHeap* + DWORD_PTR startAddress; // changed from PBYTE + DWORD_PTR endAddress; // changed from PBYTE + DWORD_PTR mapBase; // changed from PBYTE + DWORD_PTR pHdrMap; // changed from DWORD* + size_t maxCodeHeapSize; + DWORD cBlocks; + bool bFull; // Heap is considered full do not use for new allocations + bool bFullForJumpStubs; // Heap is considered full do not use for new allocations of jump stubs +}; + +typedef struct _FakeHpRealCodeHdr +{ + LPVOID phdrDebugInfo; + LPVOID phdrJitEHInfo; // changed from EE_ILEXCEPTION* + LPVOID phdrJitGCInfo; // changed from BYTE* + LPVOID hdrMDesc; // changed from MethodDesc* + DWORD nUnwindInfos; + T_RUNTIME_FUNCTION unwindInfos[0]; +} FakeRealCodeHeader; + +typedef struct _FakeHpCodeHdr +{ + LPVOID pRealCodeHeader; +} FakeCodeHeader; + +#define FAKE_STUB_CODE_BLOCK_LAST 0xF + +#ifdef DEBUGSUPPORT_STUBS_HAVE_UNWIND_INFO + +struct FakeStubUnwindInfoHeaderSuffix +{ + UCHAR nUnwindInfoSize; +}; + +// Variable-sized struct that preceeds 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; +}; + +#define FAKE_STUB_EXTERNAL_ENTRY_BIT 0x40000000 +#define FAKE_STUB_INTERCEPT_BIT 0x10000000 +#define FAKE_STUB_UNWIND_INFO_BIT 0x08000000 + +#ifdef _DEBUG +#define FAKE_STUB_SIGNATURE 0x42555453 +#endif + +struct FakeStub +{ + ULONG m_refcount; + ULONG m_patchOffset; + + UINT m_numCodeBytes; +#ifdef _DEBUG + UINT32 m_signature; +#else +#ifdef _WIN64 + //README ALIGNEMENT: in retail mode UINT m_numCodeBytes does not align to 16byte for the code + // after the Stub struct. This is to pad properly + UINT m_pad_code_bytes; +#endif // _WIN64 +#endif // _DEBUG +}; + +#endif // DEBUGSUPPORT_STUBS_HAVE_UNWIND_INFO + + +enum FakeEEDynamicFunctionTableType +{ + FAKEDYNFNTABLE_JIT = 0, + FAKEDYNFNTABLE_STUB = 1, +}; + + +#ifdef CHECK_DUPLICATED_STRUCT_LAYOUTS + +// +// These are the fields of the above structs that we use. +// We need to assert that their layout matches the layout +// in the EE. +// +class CheckDuplicatedStructLayouts +{ +#define CHECK_OFFSET(cls, fld) CPP_ASSERT(cls##fld, offsetof(Fake##cls, fld) == offsetof(cls, fld)) + + CHECK_OFFSET(EEJitManager, m_pCodeHeap); + + CHECK_OFFSET(HeapList, hpNext); + CHECK_OFFSET(HeapList, startAddress); + CHECK_OFFSET(HeapList, endAddress); + CHECK_OFFSET(HeapList, mapBase); + CHECK_OFFSET(HeapList, pHdrMap); + +#if !defined(_TARGET_X86_) + CHECK_OFFSET(RealCodeHeader, nUnwindInfos); + 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); + + + CHECK_OFFSET(Stub, m_refcount); + CHECK_OFFSET(Stub, m_patchOffset); + CHECK_OFFSET(Stub, m_numCodeBytes); +#ifdef _DEBUG + CHECK_OFFSET(Stub, m_signature); +#endif // _DEBUG + +#endif // DEBUGSUPPORT_STUBS_HAVE_UNWIND_INFO + +#undef CHECK_OFFSET + +#ifdef DEBUGSUPPORT_STUBS_HAVE_UNWIND_INFO + + static_assert_no_msg( Stub::EXTERNAL_ENTRY_BIT + == FAKE_STUB_EXTERNAL_ENTRY_BIT); + + static_assert_no_msg( Stub::INTERCEPT_BIT + == FAKE_STUB_INTERCEPT_BIT); + + static_assert_no_msg( Stub::UNWIND_INFO_BIT + == FAKE_STUB_UNWIND_INFO_BIT); + +#ifdef _DEBUG + static_assert_no_msg( FAKE_STUB_SIGNATURE + == Stub::kUsedStub); +#endif + +#endif // DEBUGSUPPORT_STUBS_HAVE_UNWIND_INFO +}; + +#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); +//NTSTATUS OutOfProcessFindHeader(HANDLE hProcess, DWORD_PTR pMapIn, DWORD_PTR addr, DWORD_PTR &codeHead); +extern "C" NTSTATUS OutOfProcessFunctionTableCallback(IN HANDLE hProcess, IN PVOID TableAddress, OUT PULONG pnEntries, OUT PT_RUNTIME_FUNCTION* ppFunctions); + + +// OutOfProcessFunctionTableCallbackEx is like the standard OS-defined OutOfProcessFunctionTableCallback, but rather +// than take a handle to a process, it takes a callback function which can read from the target. This allows the API to work on +// targets other than live processes (such as TTT trace files). +// pUserContext is passed directly to fpReadMemory, and the semantics of all other ReadMemoryFunction arguments (and return value) are +// the same as those for kernel32!ReadProcessMemory. +typedef BOOL (ReadMemoryFunction)(PVOID pUserContext, LPCVOID lpBaseAddress, PVOID lpBuffer, SIZE_T nSize, SIZE_T* lpNumberOfBytesRead); +extern "C" NTSTATUS OutOfProcessFunctionTableCallbackEx(IN ReadMemoryFunction fpReadMemory, IN PVOID pUserContext, IN PVOID TableAddress, OUT PULONG pnEntries, OUT PT_RUNTIME_FUNCTION* ppFunctions); + +#endif // CHECK_DUPLICATED_STRUCT_LAYOUTS + +#endif //_FN_TABLE_ACCESS_H |