1// Licensed to the .NET Foundation under one or more agreements.
2// The .NET Foundation licenses this file to you under the MIT license.
3// See the LICENSE file in the project root for more information.
4
5//
6
7#ifdef _MSC_VER
8#pragma once
9#endif
10
11#ifndef _FN_TABLE_ACCESS_H
12#define _FN_TABLE_ACCESS_H
13
14
15#if !defined(_TARGET_X86_)
16
17#ifndef FEATURE_PAL
18#define DEBUGSUPPORT_STUBS_HAVE_UNWIND_INFO
19#endif // !FEATURE_PAL
20
21#ifndef USE_INDIRECT_CODEHEADER
22#define USE_INDIRECT_CODEHEADER
23#endif // USE_INDIRECT_CODEHEADER
24#endif
25
26
27struct FakeEEJitManager
28{
29 LPVOID __VFN_table;
30 LPVOID m_runtimeSupport;
31 LPVOID m_pCodeHeap;
32 // Nothing after this point matters: we only need the correct offset of m_pCodeHeap.
33};
34
35struct FakeHeapList
36{
37 FakeHeapList* hpNext;
38 LPVOID pHeap; // changed type from LoaderHeap*
39 DWORD_PTR startAddress; // changed from PBYTE
40 DWORD_PTR endAddress; // changed from PBYTE
41 DWORD_PTR mapBase; // changed from PBYTE
42 DWORD_PTR pHdrMap; // changed from DWORD*
43 size_t maxCodeHeapSize;
44 size_t reserveForJumpStubs;
45};
46
47typedef struct _FakeHpRealCodeHdr
48{
49 LPVOID phdrDebugInfo;
50 LPVOID phdrJitEHInfo; // changed from EE_ILEXCEPTION*
51 LPVOID phdrJitGCInfo; // changed from BYTE*
52#if defined (FEATURE_GDBJIT)
53 LPVOID pCalledMethods;
54#endif
55 LPVOID hdrMDesc; // changed from MethodDesc*
56 DWORD nUnwindInfos;
57 T_RUNTIME_FUNCTION unwindInfos[0];
58} FakeRealCodeHeader;
59
60typedef struct _FakeHpCodeHdr
61{
62 LPVOID pRealCodeHeader;
63} FakeCodeHeader;
64
65#define FAKE_STUB_CODE_BLOCK_LAST 0xF
66
67#ifdef DEBUGSUPPORT_STUBS_HAVE_UNWIND_INFO
68
69struct FakeStubUnwindInfoHeaderSuffix
70{
71 UCHAR nUnwindInfoSize;
72};
73
74// Variable-sized struct that preceeds a Stub when the stub requires unwind
75// information. Followed by a StubUnwindInfoHeaderSuffix.
76struct FakeStubUnwindInfoHeader
77{
78 FakeStubUnwindInfoHeader *pNext;
79 T_RUNTIME_FUNCTION FunctionEntry;
80 UNWIND_INFO UnwindInfo; // variable length
81};
82
83// List of stub address ranges, in increasing address order.
84struct FakeStubUnwindInfoHeapSegment
85{
86 PBYTE pbBaseAddress;
87 SIZE_T cbSegment;
88 FakeStubUnwindInfoHeader *pUnwindHeaderList;
89 FakeStubUnwindInfoHeapSegment *pNext;
90};
91
92#define FAKE_STUB_EXTERNAL_ENTRY_BIT 0x40000000
93#define FAKE_STUB_INTERCEPT_BIT 0x10000000
94#define FAKE_STUB_UNWIND_INFO_BIT 0x08000000
95
96#ifdef _DEBUG
97#define FAKE_STUB_SIGNATURE 0x42555453
98#endif
99
100struct FakeStub
101{
102 ULONG m_refcount;
103 ULONG m_patchOffset;
104
105 UINT m_numCodeBytes;
106#ifdef _DEBUG
107 UINT32 m_signature;
108#else
109#ifdef _WIN64
110 //README ALIGNEMENT: in retail mode UINT m_numCodeBytes does not align to 16byte for the code
111 // after the Stub struct. This is to pad properly
112 UINT m_pad_code_bytes;
113#endif // _WIN64
114#endif // _DEBUG
115};
116
117#endif // DEBUGSUPPORT_STUBS_HAVE_UNWIND_INFO
118
119
120enum FakeEEDynamicFunctionTableType
121{
122 FAKEDYNFNTABLE_JIT = 0,
123 FAKEDYNFNTABLE_STUB = 1,
124};
125
126
127#ifdef CHECK_DUPLICATED_STRUCT_LAYOUTS
128
129//
130// These are the fields of the above structs that we use.
131// We need to assert that their layout matches the layout
132// in the EE.
133//
134class CheckDuplicatedStructLayouts
135{
136#define CHECK_OFFSET(cls, fld) CPP_ASSERT(cls##fld, offsetof(Fake##cls, fld) == offsetof(cls, fld))
137
138 CHECK_OFFSET(EEJitManager, m_pCodeHeap);
139
140 CHECK_OFFSET(HeapList, hpNext);
141 CHECK_OFFSET(HeapList, startAddress);
142 CHECK_OFFSET(HeapList, endAddress);
143 CHECK_OFFSET(HeapList, mapBase);
144 CHECK_OFFSET(HeapList, pHdrMap);
145
146#if !defined(_TARGET_X86_)
147 CHECK_OFFSET(RealCodeHeader, nUnwindInfos);
148 CHECK_OFFSET(RealCodeHeader, unwindInfos);
149#endif // !_TARGET_X86_
150
151#ifdef DEBUGSUPPORT_STUBS_HAVE_UNWIND_INFO
152 CHECK_OFFSET(StubUnwindInfoHeader, pNext);
153
154 CHECK_OFFSET(StubUnwindInfoHeapSegment, pbBaseAddress);
155 CHECK_OFFSET(StubUnwindInfoHeapSegment, cbSegment);
156 CHECK_OFFSET(StubUnwindInfoHeapSegment, pUnwindHeaderList);
157 CHECK_OFFSET(StubUnwindInfoHeapSegment, pNext);
158
159
160 CHECK_OFFSET(Stub, m_refcount);
161 CHECK_OFFSET(Stub, m_patchOffset);
162 CHECK_OFFSET(Stub, m_numCodeBytes);
163#ifdef _DEBUG
164 CHECK_OFFSET(Stub, m_signature);
165#endif // _DEBUG
166
167#endif // DEBUGSUPPORT_STUBS_HAVE_UNWIND_INFO
168
169#undef CHECK_OFFSET
170
171#ifdef DEBUGSUPPORT_STUBS_HAVE_UNWIND_INFO
172
173 static_assert_no_msg( Stub::EXTERNAL_ENTRY_BIT
174 == FAKE_STUB_EXTERNAL_ENTRY_BIT);
175
176 static_assert_no_msg( Stub::INTERCEPT_BIT
177 == FAKE_STUB_INTERCEPT_BIT);
178
179 static_assert_no_msg( Stub::UNWIND_INFO_BIT
180 == FAKE_STUB_UNWIND_INFO_BIT);
181
182#ifdef _DEBUG
183 static_assert_no_msg( FAKE_STUB_SIGNATURE
184 == Stub::kUsedStub);
185#endif
186
187#endif // DEBUGSUPPORT_STUBS_HAVE_UNWIND_INFO
188};
189
190#ifdef DEBUGSUPPORT_STUBS_HAVE_UNWIND_INFO
191
192static_assert_no_msg( FAKEDYNFNTABLE_JIT
193 == DYNFNTABLE_JIT);
194
195static_assert_no_msg( FAKEDYNFNTABLE_STUB
196 == DYNFNTABLE_STUB);
197
198#endif // DEBUGSUPPORT_STUBS_HAVE_UNWIND_INFO
199
200#else // CHECK_DUPLICATED_STRUCT_LAYOUTS
201
202BOOL WINAPI DllMain(HINSTANCE hDLL, DWORD dwReason, LPVOID pReserved);
203//NTSTATUS OutOfProcessFindHeader(HANDLE hProcess, DWORD_PTR pMapIn, DWORD_PTR addr, DWORD_PTR &codeHead);
204extern "C" NTSTATUS OutOfProcessFunctionTableCallback(IN HANDLE hProcess, IN PVOID TableAddress, OUT PULONG pnEntries, OUT PT_RUNTIME_FUNCTION* ppFunctions);
205
206
207// OutOfProcessFunctionTableCallbackEx is like the standard OS-defined OutOfProcessFunctionTableCallback, but rather
208// 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
209// targets other than live processes (such as TTT trace files).
210// pUserContext is passed directly to fpReadMemory, and the semantics of all other ReadMemoryFunction arguments (and return value) are
211// the same as those for kernel32!ReadProcessMemory.
212typedef BOOL (ReadMemoryFunction)(PVOID pUserContext, LPCVOID lpBaseAddress, PVOID lpBuffer, SIZE_T nSize, SIZE_T* lpNumberOfBytesRead);
213extern "C" NTSTATUS OutOfProcessFunctionTableCallbackEx(IN ReadMemoryFunction fpReadMemory, IN PVOID pUserContext, IN PVOID TableAddress, OUT PULONG pnEntries, OUT PT_RUNTIME_FUNCTION* ppFunctions);
214
215#endif // CHECK_DUPLICATED_STRUCT_LAYOUTS
216
217#endif //_FN_TABLE_ACCESS_H
218