tangled
alpha
login
or
join now
huwcampbell.com
/
reactos
0
fork
atom
Reactos
0
fork
atom
overview
issues
pulls
pipelines
[NTDLL_APITEST] Implement NtContinue test for x64
Timo Kreuzer
3 years ago
67443687
f7024d6c
+122
-18
3 changed files
expand all
collapse all
unified
split
modules
rostests
apitests
ntdll
CMakeLists.txt
NtContinue.c
amd64
NtContinue.S
+2
modules/rostests/apitests/ntdll/CMakeLists.txt
reviewed
···
100
100
101
101
if(ARCH STREQUAL "i386")
102
102
add_asm_files(ntdll_apitest_asm i386/NtContinue.S)
103
103
+
elseif(ARCH STREQUAL "amd64")
104
104
+
add_asm_files(ntdll_apitest_asm amd64/NtContinue.S)
103
105
endif()
104
106
105
107
list(APPEND PCH_SKIP_SOURCE
+82
-18
modules/rostests/apitests/ntdll/NtContinue.c
reviewed
···
10
10
#include <setjmp.h>
11
11
#include <time.h>
12
12
13
13
+
#ifdef _MSC_VER
14
14
+
#pragma runtime_checks("s", off)
15
15
+
#endif
16
16
+
17
17
+
#define ok_eq_print(value, expected, spec) ok((value) == (expected), #value " = " spec ", expected " spec "\n", value, expected)
18
18
+
#define ok_eq_hex(value, expected) ok_eq_print(value, expected, "%lx")
19
19
+
#define ok_eq_hex64(value, expected) ok_eq_print(value, expected, "%I64x")
20
20
+
#define ok_eq_xmm(value, expected) ok((value).Low == (expected).Low, #value " = %I64x'%08I64x, expected %I64x'%08I64x\n", (value).Low, (value).High, (expected).Low, (expected).High)
21
21
+
13
22
#ifdef _M_IX86
14
23
#define NTC_SEGMENT_BITS (0xFFFF)
15
24
#define NTC_EFLAGS_BITS (0x3C0CD5)
···
121
130
ok((pContext->SegSs & NTC_SEGMENT_BITS) ==
122
131
(continueContext.SegSs & NTC_SEGMENT_BITS),
123
132
"SegSs: 0x%lx != 0x%lx\n", pContext->SegSs, continueContext.SegSs);
133
133
+
#else
134
134
+
ok_eq_hex64(pContext->ContextFlags, CONTEXT_FULL | CONTEXT_SEGMENTS);
135
135
+
ok_eq_hex(pContext->MxCsr, continueContext.MxCsr);
136
136
+
ok_eq_hex(pContext->SegCs, continueContext.SegCs);
137
137
+
ok_eq_hex(pContext->SegDs, 0x2B);
138
138
+
ok_eq_hex(pContext->SegEs, 0x2B);
139
139
+
ok_eq_hex(pContext->SegFs, 0x53);
140
140
+
ok_eq_hex(pContext->SegGs, 0x2B);
141
141
+
ok_eq_hex(pContext->SegSs, continueContext.SegSs);
142
142
+
ok_eq_hex(pContext->EFlags, (continueContext.EFlags & ~0x1C0000) | 0x202);
143
143
+
144
144
+
ok_eq_hex64(pContext->Rax, continueContext.Rax);
145
145
+
ok_eq_hex64(pContext->Rdx, continueContext.Rdx);
146
146
+
ok_eq_hex64(pContext->Rbx, continueContext.Rbx);
147
147
+
ok_eq_hex64(pContext->Rsp, continueContext.Rsp);
148
148
+
ok_eq_hex64(pContext->Rbp, continueContext.Rbp);
149
149
+
ok_eq_hex64(pContext->Rsi, continueContext.Rsi);
150
150
+
ok_eq_hex64(pContext->Rdi, continueContext.Rdi);
151
151
+
ok_eq_hex64(pContext->R8, continueContext.R8);
152
152
+
ok_eq_hex64(pContext->R9, continueContext.R9);
153
153
+
ok_eq_hex64(pContext->R10, continueContext.R10);
154
154
+
ok_eq_hex64(pContext->R11, continueContext.R11);
155
155
+
ok_eq_hex64(pContext->R12, continueContext.R12);
156
156
+
ok_eq_hex64(pContext->R13, continueContext.R13);
157
157
+
ok_eq_hex64(pContext->R14, continueContext.R14);
158
158
+
ok_eq_hex64(pContext->R15, continueContext.R15);
159
159
+
ok_eq_xmm(pContext->Xmm0, continueContext.Xmm0);
160
160
+
ok_eq_xmm(pContext->Xmm1, continueContext.Xmm1);
161
161
+
ok_eq_xmm(pContext->Xmm2, continueContext.Xmm2);
162
162
+
ok_eq_xmm(pContext->Xmm3, continueContext.Xmm3);
163
163
+
ok_eq_xmm(pContext->Xmm4, continueContext.Xmm4);
164
164
+
ok_eq_xmm(pContext->Xmm5, continueContext.Xmm5);
165
165
+
ok_eq_xmm(pContext->Xmm6, continueContext.Xmm6);
166
166
+
ok_eq_xmm(pContext->Xmm7, continueContext.Xmm7);
167
167
+
ok_eq_xmm(pContext->Xmm8, continueContext.Xmm8);
168
168
+
ok_eq_xmm(pContext->Xmm9, continueContext.Xmm9);
169
169
+
ok_eq_xmm(pContext->Xmm10, continueContext.Xmm10);
170
170
+
ok_eq_xmm(pContext->Xmm11, continueContext.Xmm11);
171
171
+
ok_eq_xmm(pContext->Xmm12, continueContext.Xmm12);
172
172
+
ok_eq_xmm(pContext->Xmm13, continueContext.Xmm13);
173
173
+
ok_eq_xmm(pContext->Xmm14, continueContext.Xmm14);
174
174
+
ok_eq_xmm(pContext->Xmm15, continueContext.Xmm15);
175
175
+
176
176
+
// Clear the frame register to prevent unwinding, which is broken
177
177
+
((_JUMP_BUFFER*)&jmpbuf)->Frame = 0;
124
178
#endif
125
179
126
180
/* Return where we came from */
···
129
183
130
184
START_TEST(NtContinue)
131
185
{
132
132
-
#ifdef __RUNTIME_CHECKS__
133
133
-
skip("This test breaks MSVC runtime checks!\n");
134
134
-
return;
135
135
-
#endif /* __RUNTIME_CHECKS__ */
136
186
initrand();
187
187
+
188
188
+
RtlFillMemory(&continueContext, sizeof(continueContext), 0xBBBBBBBB);
137
189
138
190
/* First time */
139
191
if(setjmp(jmpbuf) == 0)
140
192
{
141
141
-
CONTEXT bogus;
193
193
+
CONTEXT bogus[2];
194
194
+
195
195
+
RtlFillMemory(&bogus, sizeof(bogus), 0xCCCCCCCC);
142
196
143
197
continueContext.ContextFlags = CONTEXT_FULL;
144
198
GetThreadContext(GetCurrentThread(), &continueContext);
···
167
221
168
222
/* Can't do a lot about segments */
169
223
#elif defined(_M_AMD64)
170
170
-
continueContext.ContextFlags = CONTEXT_FULL;
224
224
+
continueContext.ContextFlags = CONTEXT_FULL | CONTEXT_DEBUG_REGISTERS;
171
225
172
226
/* Fill the integer registers with random values */
173
173
-
continueContext.Rdi = randULONG64();
174
174
-
continueContext.Rsi = randULONG64();
175
175
-
continueContext.Rbx = randULONG64();
176
176
-
continueContext.Rdx = randULONG64();
177
177
-
continueContext.Rcx = randULONG64();
178
178
-
continueContext.Rax = randULONG64();
179
179
-
continueContext.Rbp = randULONG64();
227
227
+
PULONG64 Registers = &continueContext.Rax;
228
228
+
for (ULONG i = 0; i < 16; i++)
229
229
+
{
230
230
+
Registers[i] = randULONG64();
231
231
+
}
232
232
+
233
233
+
/* Fill the XMM registers with random values */
234
234
+
Registers = (PULONG64)&continueContext.Xmm0;
235
235
+
for (ULONG i = 0; i < 32; i++)
236
236
+
{
237
237
+
Registers[i] = randULONG64();
238
238
+
}
239
239
+
240
240
+
continueContext.Dr0 = randULONG64() & 0xFFFF;
241
241
+
continueContext.Dr1 = randULONG64() & 0xFFFF;
242
242
+
continueContext.Dr2 = randULONG64() & 0xFFFF;
243
243
+
continueContext.Dr3 = randULONG64() & 0xFFFF;
244
244
+
continueContext.Dr6 = randULONG64() & 0xFFFF;
245
245
+
continueContext.Dr7 = randULONG64() & 0xFFFF;
180
246
181
247
/* Randomize all the allowed flags (determined experimentally with WinDbg) */
182
248
continueContext.EFlags = randULONG64() & 0x3C0CD5;
183
249
184
250
/* Randomize the stack pointer as much as possible */
185
185
-
continueContext.Rsp = (((ULONG_PTR)&bogus)) +
186
186
-
sizeof(bogus) - (randULONG() & 0xF) * 4;
251
251
+
continueContext.Rsp = (((ULONG_PTR)&bogus)) + (randULONG() & 0xF) * 16;
252
252
+
continueContext.Rsp = ALIGN_DOWN_BY(continueContext.Rsp, 16);
187
253
188
254
/* continuePoint() is implemented in assembler */
189
189
-
//continueContext.Rip = ((ULONG_PTR)continuePoint);
190
190
-
skip("NtContinue test does not yet work on x64.");
191
191
-
return;
255
255
+
continueContext.Rip = ((ULONG_PTR)continuePoint);
192
256
#endif
193
257
194
258
NtContinue(&continueContext, FALSE);
+38
modules/rostests/apitests/ntdll/amd64/NtContinue.S
reviewed
···
1
1
+
/*
2
2
+
* PROJECT: ReactOS API tests
3
3
+
* LICENSE: GPL-2.0+ (https://spdx.org/licenses/GPL-2.0+)
4
4
+
* PURPOSE: Helper functions for NtContinue test
5
5
+
* COPYRIGHT: Copyright 2022 Timo Kreuzer (timo.kreuzer@reactos.org)
6
6
+
*/
7
7
+
8
8
+
#include <asm.inc>
9
9
+
#include <ksamd64.inc>
10
10
+
11
11
+
.code64
12
12
+
13
13
+
EXTERN RtlCaptureContext:PROC
14
14
+
EXTERN check:PROC
15
15
+
16
16
+
PUBLIC continuePoint
17
17
+
.PROC continuePoint
18
18
+
19
19
+
// Allocate space for a CONTEXT structure
20
20
+
.ALLOCSTACK CONTEXT_FRAME_LENGTH + 8
21
21
+
.ENDPROLOG
22
22
+
23
23
+
// Capture the current CONTEXT
24
24
+
mov rcx, rsp
25
25
+
call RtlCaptureContext
26
26
+
27
27
+
// Call the function that will compare the current context with the expected one
28
28
+
cld
29
29
+
mov rcx, rsp
30
30
+
call check
31
31
+
32
32
+
// check() must not return
33
33
+
int 3
34
34
+
35
35
+
.ENDP
36
36
+
37
37
+
// EOF
38
38
+
END