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// crosscomp.h - cross-compilation enablement structures.
6//
7
8
9#pragma once
10
11#if (!defined(_WIN64) && defined(_TARGET_64BIT_)) || (defined(_WIN64) && !defined(_TARGET_64BIT_))
12#define CROSSBITNESS_COMPILE
13#endif
14
15#if !defined(_ARM_) && defined(_TARGET_ARM_) // Non-ARM Host managing ARM related code
16
17#ifndef CROSS_COMPILE
18#define CROSS_COMPILE
19#endif
20
21#define ARM_MAX_BREAKPOINTS 8
22#define ARM_MAX_WATCHPOINTS 1
23
24#define CONTEXT_UNWOUND_TO_CALL 0x20000000
25
26typedef struct _NEON128 {
27 ULONGLONG Low;
28 LONGLONG High;
29} NEON128, *PNEON128;
30
31typedef struct DECLSPEC_ALIGN(8) _T_CONTEXT {
32 //
33 // Control flags.
34 //
35
36 DWORD ContextFlags;
37
38 //
39 // Integer registers
40 //
41
42 DWORD R0;
43 DWORD R1;
44 DWORD R2;
45 DWORD R3;
46 DWORD R4;
47 DWORD R5;
48 DWORD R6;
49 DWORD R7;
50 DWORD R8;
51 DWORD R9;
52 DWORD R10;
53 DWORD R11;
54 DWORD R12;
55
56 //
57 // Control Registers
58 //
59
60 DWORD Sp;
61 DWORD Lr;
62 DWORD Pc;
63 DWORD Cpsr;
64
65 //
66 // Floating Point/NEON Registers
67 //
68
69 DWORD Fpscr;
70 DWORD Padding;
71 union {
72 NEON128 Q[16];
73 ULONGLONG D[32];
74 DWORD S[32];
75 };
76
77 //
78 // Debug registers
79 //
80
81 DWORD Bvr[ARM_MAX_BREAKPOINTS];
82 DWORD Bcr[ARM_MAX_BREAKPOINTS];
83 DWORD Wvr[ARM_MAX_WATCHPOINTS];
84 DWORD Wcr[ARM_MAX_WATCHPOINTS];
85
86 DWORD Padding2[2];
87
88} T_CONTEXT, *PT_CONTEXT;
89
90//
91// Define function table entry - a function table entry is generated for
92// each frame function.
93//
94
95#ifndef FEATURE_PAL
96#ifdef _X86_
97typedef struct _RUNTIME_FUNCTION {
98 DWORD BeginAddress;
99 DWORD UnwindData;
100} RUNTIME_FUNCTION, *PRUNTIME_FUNCTION;
101
102//
103// Define unwind history table structure.
104//
105
106#define UNWIND_HISTORY_TABLE_SIZE 12
107
108typedef struct _UNWIND_HISTORY_TABLE_ENTRY {
109 DWORD ImageBase;
110 PRUNTIME_FUNCTION FunctionEntry;
111} UNWIND_HISTORY_TABLE_ENTRY, *PUNWIND_HISTORY_TABLE_ENTRY;
112
113typedef struct _UNWIND_HISTORY_TABLE {
114 DWORD Count;
115 BYTE LocalHint;
116 BYTE GlobalHint;
117 BYTE Search;
118 BYTE Once;
119 DWORD LowAddress;
120 DWORD HighAddress;
121 UNWIND_HISTORY_TABLE_ENTRY Entry[UNWIND_HISTORY_TABLE_SIZE];
122} UNWIND_HISTORY_TABLE, *PUNWIND_HISTORY_TABLE;
123#endif // _X86_
124#endif // !FEATURE_PAL
125
126
127//
128// Nonvolatile context pointer record.
129//
130
131typedef struct _T_KNONVOLATILE_CONTEXT_POINTERS {
132
133 PDWORD R4;
134 PDWORD R5;
135 PDWORD R6;
136 PDWORD R7;
137 PDWORD R8;
138 PDWORD R9;
139 PDWORD R10;
140 PDWORD R11;
141 PDWORD Lr;
142
143 PULONGLONG D8;
144 PULONGLONG D9;
145 PULONGLONG D10;
146 PULONGLONG D11;
147 PULONGLONG D12;
148 PULONGLONG D13;
149 PULONGLONG D14;
150 PULONGLONG D15;
151
152} T_KNONVOLATILE_CONTEXT_POINTERS, *PT_KNONVOLATILE_CONTEXT_POINTERS;
153
154//
155// Define dynamic function table entry.
156//
157
158typedef
159PRUNTIME_FUNCTION
160(*PGET_RUNTIME_FUNCTION_CALLBACK) (
161 IN DWORD64 ControlPc,
162 IN PVOID Context
163 );
164
165typedef struct _T_DISPATCHER_CONTEXT {
166 ULONG ControlPc;
167 ULONG ImageBase;
168 PRUNTIME_FUNCTION FunctionEntry;
169 ULONG EstablisherFrame;
170 ULONG TargetPc;
171 PT_CONTEXT ContextRecord;
172 PEXCEPTION_ROUTINE LanguageHandler;
173 PVOID HandlerData;
174 PUNWIND_HISTORY_TABLE HistoryTable;
175 ULONG ScopeIndex;
176 BOOLEAN ControlPcIsUnwound;
177 PUCHAR NonVolatileRegisters;
178} T_DISPATCHER_CONTEXT, *PT_DISPATCHER_CONTEXT;
179
180#if defined(FEATURE_PAL) || defined(_X86_)
181#define T_RUNTIME_FUNCTION RUNTIME_FUNCTION
182#define PT_RUNTIME_FUNCTION PRUNTIME_FUNCTION
183#else
184typedef struct _T_RUNTIME_FUNCTION {
185 DWORD BeginAddress;
186 DWORD UnwindData;
187} T_RUNTIME_FUNCTION, *PT_RUNTIME_FUNCTION;
188#endif
189
190#elif defined(_AMD64_) && defined(_TARGET_ARM64_) // Host amd64 managing ARM64 related code
191
192#ifndef CROSS_COMPILE
193#define CROSS_COMPILE
194#endif
195
196//
197// Specify the number of breakpoints and watchpoints that the OS
198// will track. Architecturally, ARM64 supports up to 16. In practice,
199// however, almost no one implements more than 4 of each.
200//
201
202#define ARM64_MAX_BREAKPOINTS 8
203#define ARM64_MAX_WATCHPOINTS 2
204
205#define CONTEXT_UNWOUND_TO_CALL 0x20000000
206
207typedef union _NEON128 {
208 struct {
209 ULONGLONG Low;
210 LONGLONG High;
211 };
212 double D[2];
213 float S[4];
214 WORD H[8];
215 BYTE B[16];
216} NEON128, *PNEON128;
217
218typedef struct DECLSPEC_ALIGN(16) _T_CONTEXT {
219
220 //
221 // Control flags.
222 //
223
224 /* +0x000 */ DWORD ContextFlags;
225
226 //
227 // Integer registers
228 //
229
230 /* +0x004 */ DWORD Cpsr; // NZVF + DAIF + CurrentEL + SPSel
231 /* +0x008 */ union {
232 struct {
233 DWORD64 X0;
234 DWORD64 X1;
235 DWORD64 X2;
236 DWORD64 X3;
237 DWORD64 X4;
238 DWORD64 X5;
239 DWORD64 X6;
240 DWORD64 X7;
241 DWORD64 X8;
242 DWORD64 X9;
243 DWORD64 X10;
244 DWORD64 X11;
245 DWORD64 X12;
246 DWORD64 X13;
247 DWORD64 X14;
248 DWORD64 X15;
249 DWORD64 X16;
250 DWORD64 X17;
251 DWORD64 X18;
252 DWORD64 X19;
253 DWORD64 X20;
254 DWORD64 X21;
255 DWORD64 X22;
256 DWORD64 X23;
257 DWORD64 X24;
258 DWORD64 X25;
259 DWORD64 X26;
260 DWORD64 X27;
261 DWORD64 X28;
262 };
263 DWORD64 X[29];
264 };
265 /* +0x0f0 */ DWORD64 Fp;
266 /* +0x0f8 */ DWORD64 Lr;
267 /* +0x100 */ DWORD64 Sp;
268 /* +0x108 */ DWORD64 Pc;
269
270 //
271 // Floating Point/NEON Registers
272 //
273
274 /* +0x110 */ NEON128 V[32];
275 /* +0x310 */ DWORD Fpcr;
276 /* +0x314 */ DWORD Fpsr;
277
278 //
279 // Debug registers
280 //
281
282 /* +0x318 */ DWORD Bcr[ARM64_MAX_BREAKPOINTS];
283 /* +0x338 */ DWORD64 Bvr[ARM64_MAX_BREAKPOINTS];
284 /* +0x378 */ DWORD Wcr[ARM64_MAX_WATCHPOINTS];
285 /* +0x380 */ DWORD64 Wvr[ARM64_MAX_WATCHPOINTS];
286 /* +0x390 */
287
288} T_CONTEXT, *PT_CONTEXT;
289
290// _IMAGE_ARM64_RUNTIME_FUNCTION_ENTRY (see ExternalAPIs\Win9CoreSystem\inc\winnt.h)
291typedef struct _T_RUNTIME_FUNCTION {
292 DWORD BeginAddress;
293 union {
294 DWORD UnwindData;
295 struct {
296 DWORD Flag : 2;
297 DWORD FunctionLength : 11;
298 DWORD RegF : 3;
299 DWORD RegI : 4;
300 DWORD H : 1;
301 DWORD CR : 2;
302 DWORD FrameSize : 9;
303 } PackedUnwindData;
304 };
305} T_RUNTIME_FUNCTION, *PT_RUNTIME_FUNCTION;
306
307
308//
309// Define exception dispatch context structure.
310//
311
312typedef struct _T_DISPATCHER_CONTEXT {
313 DWORD64 ControlPc;
314 DWORD64 ImageBase;
315 PT_RUNTIME_FUNCTION FunctionEntry;
316 DWORD64 EstablisherFrame;
317 DWORD64 TargetPc;
318 PCONTEXT ContextRecord;
319 PEXCEPTION_ROUTINE LanguageHandler;
320 PVOID HandlerData;
321 PUNWIND_HISTORY_TABLE HistoryTable;
322 DWORD ScopeIndex;
323 BOOLEAN ControlPcIsUnwound;
324 PBYTE NonVolatileRegisters;
325} T_DISPATCHER_CONTEXT, *PT_DISPATCHER_CONTEXT;
326
327
328
329//
330// Nonvolatile context pointer record.
331//
332
333typedef struct _T_KNONVOLATILE_CONTEXT_POINTERS {
334
335 PDWORD64 X19;
336 PDWORD64 X20;
337 PDWORD64 X21;
338 PDWORD64 X22;
339 PDWORD64 X23;
340 PDWORD64 X24;
341 PDWORD64 X25;
342 PDWORD64 X26;
343 PDWORD64 X27;
344 PDWORD64 X28;
345 PDWORD64 Fp;
346 PDWORD64 Lr;
347
348 PDWORD64 D8;
349 PDWORD64 D9;
350 PDWORD64 D10;
351 PDWORD64 D11;
352 PDWORD64 D12;
353 PDWORD64 D13;
354 PDWORD64 D14;
355 PDWORD64 D15;
356
357} T_KNONVOLATILE_CONTEXT_POINTERS, *PT_KNONVOLATILE_CONTEXT_POINTERS;
358
359#else
360
361#define T_CONTEXT CONTEXT
362#define PT_CONTEXT PCONTEXT
363
364#define T_DISPATCHER_CONTEXT DISPATCHER_CONTEXT
365#define PT_DISPATCHER_CONTEXT PDISPATCHER_CONTEXT
366
367#define T_KNONVOLATILE_CONTEXT_POINTERS KNONVOLATILE_CONTEXT_POINTERS
368#define PT_KNONVOLATILE_CONTEXT_POINTERS PKNONVOLATILE_CONTEXT_POINTERS
369
370#define T_RUNTIME_FUNCTION RUNTIME_FUNCTION
371#define PT_RUNTIME_FUNCTION PRUNTIME_FUNCTION
372
373#endif
374
375
376#ifdef CROSSGEN_COMPILE
377void CrossGenNotSupported(const char * message);
378#endif
379