ReactOS 0.4.17-dev-37-g0bfb40d
unwind.c File Reference
#include <stdarg.h>
#include <stdio.h>
#include "ntstatus.h"
#include "windef.h"
#include "winbase.h"
#include "winnt.h"
#include "winreg.h"
#include "winternl.h"
#include "rtlsupportapi.h"
#include "wine/test.h"
Include dependency graph for unwind.c:

Go to the source code of this file.

Macros

#define WIN32_NO_STATUS
 
#define SET_RUNTIME_FUNC_LEN(func, len)   do { (func)->FunctionLength = len / 4; (func)->Flag = 1; } while(0)
 
#define X(f)   p##f = (void*)GetProcAddress(ntdll, #f)
 

Functions

static PRUNTIME_FUNCTION (WINAPI *pRtlLookupFunctionEntry)(ULONG_PTR
 
static ULONG_PTR UNWIND_HISTORY_TABLE *static ULONG_PTR ULONG *static BOOLEAN (CDECL *pRtlInstallFunctionTableCallback)(DWORD64
 
static DWORD (WINAPI *pRtlAddGrowableFunctionTable)(void **
 
static void (WINAPI *pRtlGrowFunctionTable)(void *
 
static NTSTATUS (WINAPI *pRtlVirtualUnwind2)(ULONG
 
static RUNTIME_FUNCTION *CALLBACK dynamic_unwind_callback (DWORD_PTR pc, PVOID context)
 
static void test_dynamic_unwind (void)
 
 START_TEST (unwind)
 

Variables

static voidcode_mem
 
static HMODULE ntdll
 
static ULONG_PTR UNWIND_HISTORY_TABLE *static ULONG_PTR ULONG *static DWORD64
 
static ULONG_PTR UNWIND_HISTORY_TABLE *static ULONG_PTR ULONG *static DWORD
 
static ULONG_PTR UNWIND_HISTORY_TABLE *static ULONG_PTR ULONG *static PGET_RUNTIME_FUNCTION_CALLBACK
 
static ULONG_PTR UNWIND_HISTORY_TABLE *static ULONG_PTR ULONG *static PVOID
 
static ULONG_PTR UNWIND_HISTORY_TABLE *static ULONG_PTR ULONG *static PCWSTR
 
static RUNTIME_FUNCTION ULONG_PTR
 
static RUNTIME_FUNCTION CONTEXT BOOLEAN void ULONG_PTR KNONVOLATILE_CONTEXT_POINTERS ULONG_PTR ULONG_PTR PEXCEPTION_ROUTINE ULONG
 

Macro Definition Documentation

◆ SET_RUNTIME_FUNC_LEN

#define SET_RUNTIME_FUNC_LEN (   func,
  len 
)    do { (func)->FunctionLength = len / 4; (func)->Flag = 1; } while(0)

Definition at line 3112 of file unwind.c.

◆ WIN32_NO_STATUS

#define WIN32_NO_STATUS

Definition at line 26 of file unwind.c.

◆ X

#define X (   f)    p##f = (void*)GetProcAddress(ntdll, #f)

Function Documentation

◆ BOOLEAN()

static ULONG_PTR UNWIND_HISTORY_TABLE *static ULONG_PTR ULONG *static BOOLEAN ( CDECL pRtlInstallFunctionTableCallback)
static

◆ DWORD()

static DWORD ( WINAPI pRtlAddGrowableFunctionTable)
static

◆ dynamic_unwind_callback()

static RUNTIME_FUNCTION *CALLBACK dynamic_unwind_callback ( DWORD_PTR  pc,
PVOID  context 
)
static

Definition at line 3115 of file unwind.c.

3116{
3117 static const int code_offset = 1024;
3118 static RUNTIME_FUNCTION runtime_func;
3119 (*(DWORD *)context)++;
3120
3121 runtime_func.BeginAddress = code_offset + 16;
3122 runtime_func.UnwindData = 0;
3123 SET_RUNTIME_FUNC_LEN( &runtime_func, 16 );
3124 return &runtime_func;
3125}
unsigned long DWORD
Definition: ntddk_ex.h:95
#define SET_RUNTIME_FUNC_LEN(func, len)
Definition: unwind.c:3112
Definition: http.c:7252

Referenced by test_dynamic_unwind().

◆ NTSTATUS()

static NTSTATUS ( WINAPI pRtlVirtualUnwind2)
static

◆ PRUNTIME_FUNCTION()

◆ START_TEST()

START_TEST ( unwind  )

Definition at line 3421 of file unwind.c.

3422{
3423 ntdll = GetModuleHandleA("ntdll.dll");
3425
3426#define X(f) p##f = (void*)GetProcAddress(ntdll, #f)
3437#undef X
3438
3439#ifdef __arm__
3440 test_virtual_unwind_arm();
3441#elif defined(__aarch64__)
3442 test_virtual_unwind_arm64();
3443#elif defined(__x86_64__)
3444 test_virtual_unwind_x86();
3445#ifndef __REACTOS__
3446 test_virtual_unwind_arm64();
3447#endif // __REACTOS__
3448#endif
3449
3451}
#define NULL
Definition: types.h:112
HMODULE WINAPI DECLSPEC_HOTPATCH GetModuleHandleA(LPCSTR lpModuleName)
Definition: loader.c:812
static void * code_mem
Definition: unwind.c:38
#define X(f)
static HMODULE ntdll
Definition: unwind.c:39
static void test_dynamic_unwind(void)
Definition: unwind.c:3127
#define MEM_RESERVE
Definition: nt_native.h:1317
#define MEM_COMMIT
Definition: nt_native.h:1316
#define PAGE_EXECUTE_READWRITE
Definition: nt_native.h:1311
NTSYSAPI NTSTATUS WINAPI RtlAddGrowableFunctionTable(void **, PRUNTIME_FUNCTION, ULONG, ULONG, ULONG_PTR, ULONG_PTR)
NTSYSAPI BOOLEAN CDECL RtlAddFunctionTable(RUNTIME_FUNCTION *, ULONG, ULONG_PTR)
NTSYSAPI void WINAPI RtlGrowFunctionTable(void *, ULONG)
NTSYSAPI NTSTATUS WINAPI RtlVirtualUnwind2(ULONG, ULONG_PTR, ULONG_PTR, RUNTIME_FUNCTION *, CONTEXT *, BOOLEAN *, void **, ULONG_PTR *, KNONVOLATILE_CONTEXT_POINTERS *, ULONG_PTR *, ULONG_PTR *, PEXCEPTION_ROUTINE *, ULONG)
NTSYSAPI PRUNTIME_FUNCTION WINAPI RtlLookupFunctionEntry(ULONG_PTR, ULONG_PTR *, UNWIND_HISTORY_TABLE *)
NTSYSAPI BOOLEAN CDECL RtlDeleteFunctionTable(RUNTIME_FUNCTION *)
NTSYSAPI void WINAPI RtlDeleteGrowableFunctionTable(void *)
NTSYSAPI BOOLEAN CDECL RtlInstallFunctionTableCallback(ULONG_PTR, ULONG_PTR, ULONG, PGET_RUNTIME_FUNCTION_CALLBACK, PVOID, PCWSTR)
NTSYSAPI PRUNTIME_FUNCTION WINAPI RtlLookupFunctionTable(ULONG_PTR, ULONG_PTR *, ULONG *)
LPVOID NTAPI VirtualAlloc(IN LPVOID lpAddress, IN SIZE_T dwSize, IN DWORD flAllocationType, IN DWORD flProtect)
Definition: virtmem.c:65
NTSYSAPI NTSTATUS WINAPI NtAllocateVirtualMemoryEx(HANDLE, PVOID *, SIZE_T *, ULONG, ULONG, MEM_EXTENDED_PARAMETER *, ULONG)

◆ test_dynamic_unwind()

static void test_dynamic_unwind ( void  )
static

Definition at line 3127 of file unwind.c.

3128{
3129 static const int code_offset = 1024;
3130 char buf[2 * sizeof(RUNTIME_FUNCTION) + 4];
3132 RUNTIME_FUNCTION *runtime_func, *func;
3133 ULONG_PTR table, base, ec_code;
3134 void *growable_table, *ptr;
3136 SIZE_T size = 0x1000;
3137 DWORD count;
3138 ULONG len, len2;
3139
3140 if (!pRtlInstallFunctionTableCallback || !pRtlLookupFunctionEntry)
3141 {
3142 win_skip( "Dynamic unwind functions not found\n" );
3143 return;
3144 }
3145
3146 /* Test RtlAddFunctionTable with aligned RUNTIME_FUNCTION pointer */
3147 runtime_func = (RUNTIME_FUNCTION *)buf;
3148 runtime_func->BeginAddress = code_offset;
3149 runtime_func->UnwindData = 0;
3150 SET_RUNTIME_FUNC_LEN( runtime_func, 16 );
3151 ok( pRtlAddFunctionTable( runtime_func, 1, (ULONG_PTR)code_mem ),
3152 "RtlAddFunctionTable failed for runtime_func = %p (aligned)\n", runtime_func );
3153
3154 /* Lookup function outside of any function table */
3155 base = 0xdeadbeef;
3156 func = pRtlLookupFunctionEntry( (ULONG_PTR)code_mem + code_offset + 16, &base, NULL );
3157 ok( func == NULL,
3158 "RtlLookupFunctionEntry returned unexpected function, expected: NULL, got: %p\n", func );
3159 ok( !base || broken(base == 0xdeadbeef),
3160 "RtlLookupFunctionEntry modified base address, expected: 0, got: %Ix\n", base );
3161
3162 /* Test with pointer inside of our function */
3163 base = 0xdeadbeef;
3164 func = pRtlLookupFunctionEntry( (ULONG_PTR)code_mem + code_offset + 8, &base, NULL );
3165 ok( func == runtime_func,
3166 "RtlLookupFunctionEntry didn't return expected function, expected: %p, got: %p\n", runtime_func, func );
3168 "RtlLookupFunctionEntry returned invalid base, expected: %Ix, got: %Ix\n", (ULONG_PTR)code_mem, base );
3169
3170 /* Test RtlDeleteFunctionTable */
3171 ok( pRtlDeleteFunctionTable( runtime_func ),
3172 "RtlDeleteFunctionTable failed for runtime_func = %p (aligned)\n", runtime_func );
3173 ok( !pRtlDeleteFunctionTable( runtime_func ),
3174 "RtlDeleteFunctionTable returned success for nonexistent table runtime_func = %p\n", runtime_func );
3175
3176 /* Unaligned RUNTIME_FUNCTION pointer */
3177 runtime_func = (RUNTIME_FUNCTION *)((ULONG_PTR)buf | 0x3);
3178 runtime_func->BeginAddress = code_offset;
3179 runtime_func->UnwindData = 0;
3180 SET_RUNTIME_FUNC_LEN( runtime_func, 16 );
3181 ok( pRtlAddFunctionTable( runtime_func, 1, (ULONG_PTR)code_mem ),
3182 "RtlAddFunctionTable failed for runtime_func = %p (unaligned)\n", runtime_func );
3183 ok( pRtlDeleteFunctionTable( runtime_func ),
3184 "RtlDeleteFunctionTable failed for runtime_func = %p (unaligned)\n", runtime_func );
3185
3186 /* Attempt to insert the same entry twice */
3187 runtime_func = (RUNTIME_FUNCTION *)buf;
3188 runtime_func->BeginAddress = code_offset;
3189 runtime_func->UnwindData = 0;
3190 SET_RUNTIME_FUNC_LEN( runtime_func, 16 );
3191 ok( pRtlAddFunctionTable( runtime_func, 1, (ULONG_PTR)code_mem ),
3192 "RtlAddFunctionTable failed for runtime_func = %p (first attempt)\n", runtime_func );
3193 ok( pRtlAddFunctionTable( runtime_func, 1, (ULONG_PTR)code_mem ),
3194 "RtlAddFunctionTable failed for runtime_func = %p (second attempt)\n", runtime_func );
3195 ok( pRtlDeleteFunctionTable( runtime_func ),
3196 "RtlDeleteFunctionTable failed for runtime_func = %p (first attempt)\n", runtime_func );
3197 ok( pRtlDeleteFunctionTable( runtime_func ),
3198 "RtlDeleteFunctionTable failed for runtime_func = %p (second attempt)\n", runtime_func );
3199 ok( !pRtlDeleteFunctionTable( runtime_func ),
3200 "RtlDeleteFunctionTable returned success for nonexistent table runtime_func = %p\n", runtime_func );
3201
3202 /* Empty table */
3203 ok( pRtlAddFunctionTable( runtime_func, 0, (ULONG_PTR)code_mem ),
3204 "RtlAddFunctionTable failed for empty table\n" );
3205 ok( pRtlDeleteFunctionTable( runtime_func ),
3206 "RtlDeleteFunctionTable failed for empty table\n" );
3207 ok( !pRtlDeleteFunctionTable( runtime_func ),
3208 "RtlDeleteFunctionTable succeeded twice for empty table\n" );
3209
3210 /* Test RtlInstallFunctionTableCallback with both low bits unset */
3212 ok( !pRtlInstallFunctionTableCallback( table, (ULONG_PTR)code_mem, code_offset + 32, &dynamic_unwind_callback, (PVOID*)&count, NULL ),
3213 "RtlInstallFunctionTableCallback returned success for table = %Ix\n", table );
3214
3215 /* Test RtlInstallFunctionTableCallback with both low bits set */
3216 table = (ULONG_PTR)code_mem | 0x3;
3217 ok( pRtlInstallFunctionTableCallback( table, (ULONG_PTR)code_mem, code_offset + 32, &dynamic_unwind_callback, (PVOID*)&count, NULL ),
3218 "RtlInstallFunctionTableCallback failed for table = %Ix\n", table );
3219
3220 /* Lookup function outside of any function table */
3221 count = 0;
3222 base = 0xdeadbeef;
3223 func = pRtlLookupFunctionEntry( (ULONG_PTR)code_mem + code_offset + 32, &base, NULL );
3224 ok( func == NULL,
3225 "RtlLookupFunctionEntry returned unexpected function, expected: NULL, got: %p\n", func );
3226 ok( !base || broken(base == 0xdeadbeef),
3227 "RtlLookupFunctionEntry modified base address, expected: 0, got: %Ix\n", base );
3228 ok( !count,
3229 "RtlLookupFunctionEntry issued %ld unexpected calls to dynamic_unwind_callback\n", count );
3230
3231 /* Test with pointer inside of our function */
3232 count = 0;
3233 base = 0xdeadbeef;
3234 func = pRtlLookupFunctionEntry( (ULONG_PTR)code_mem + code_offset + 24, &base, NULL );
3235 ok( count == 1 || broken(!count), /* win10 arm */
3236 "RtlLookupFunctionEntry issued %ld calls to dynamic_unwind_callback, expected: 1\n", count );
3237 if (count)
3238 {
3239 ok( func != NULL && func->BeginAddress == code_offset + 16,
3240 "RtlLookupFunctionEntry didn't return expected function, got: %p\n", func );
3242 "RtlLookupFunctionEntry returned invalid base: %Ix / %Ix\n", (ULONG_PTR)code_mem, base );
3243 }
3244
3245 /* Clean up again */
3246 ok( pRtlDeleteFunctionTable( (PRUNTIME_FUNCTION)table ),
3247 "RtlDeleteFunctionTable failed for table = %p\n", (PVOID)table );
3248 ok( !pRtlDeleteFunctionTable( (PRUNTIME_FUNCTION)table ),
3249 "RtlDeleteFunctionTable returned success for nonexistent table = %p\n", (PVOID)table );
3250
3251 if (!pRtlAddGrowableFunctionTable)
3252 {
3253 win_skip("Growable function tables are not supported.\n");
3254 return;
3255 }
3256
3257 runtime_func = (RUNTIME_FUNCTION *)buf;
3258 runtime_func->BeginAddress = code_offset;
3259 runtime_func->UnwindData = 0;
3260 SET_RUNTIME_FUNC_LEN( runtime_func, 16 );
3261 runtime_func++;
3262 runtime_func->BeginAddress = code_offset + 16;
3263 runtime_func->UnwindData = 0;
3264 SET_RUNTIME_FUNC_LEN( runtime_func, 16 );
3265 runtime_func = (RUNTIME_FUNCTION *)buf;
3266
3267 growable_table = NULL;
3268 status = pRtlAddGrowableFunctionTable( &growable_table, runtime_func, 1, 1, (ULONG_PTR)code_mem, (ULONG_PTR)code_mem + 64 );
3269 ok(!status, "RtlAddGrowableFunctionTable failed for runtime_func = %p (aligned), %#lx.\n", runtime_func, status );
3270 ok(growable_table != 0, "Unexpected table value.\n");
3271 pRtlDeleteGrowableFunctionTable( growable_table );
3272
3273 growable_table = NULL;
3274 status = pRtlAddGrowableFunctionTable( &growable_table, runtime_func, 2, 2, (ULONG_PTR)code_mem, (ULONG_PTR)code_mem + 64 );
3275 ok(!status, "RtlAddGrowableFunctionTable failed for runtime_func = %p (aligned), %#lx.\n", runtime_func, status );
3276 ok(growable_table != 0, "Unexpected table value.\n");
3277 pRtlDeleteGrowableFunctionTable( growable_table );
3278
3279 growable_table = NULL;
3280 status = pRtlAddGrowableFunctionTable( &growable_table, runtime_func, 1, 2, (ULONG_PTR)code_mem, (ULONG_PTR)code_mem + 64 );
3281 ok(!status, "RtlAddGrowableFunctionTable failed for runtime_func = %p (aligned), %#lx.\n", runtime_func, status );
3282 ok(growable_table != 0, "Unexpected table value.\n");
3283 pRtlDeleteGrowableFunctionTable( growable_table );
3284
3285 growable_table = NULL;
3286 status = pRtlAddGrowableFunctionTable( &growable_table, runtime_func, 0, 2, (ULONG_PTR)code_mem,
3287 (ULONG_PTR)code_mem + code_offset + 64 );
3288 ok(!status, "RtlAddGrowableFunctionTable failed for runtime_func = %p (aligned), %#lx.\n", runtime_func, status );
3289 ok(growable_table != 0, "Unexpected table value.\n");
3290
3291 /* Current count is 0. */
3292 func = pRtlLookupFunctionEntry( (ULONG_PTR)code_mem + code_offset + 8, &base, NULL );
3293 ok( func == NULL,
3294 "RtlLookupFunctionEntry didn't return expected function, expected: %p, got: %p\n", runtime_func, func );
3295
3296 pRtlGrowFunctionTable( growable_table, 1 );
3297
3298 base = 0xdeadbeef;
3299 func = pRtlLookupFunctionEntry( (ULONG_PTR)code_mem + code_offset + 8, &base, NULL );
3300 ok( func == runtime_func,
3301 "RtlLookupFunctionEntry didn't return expected function, expected: %p, got: %p\n", runtime_func, func );
3303 "RtlLookupFunctionEntry returned invalid base, expected: %Ix, got: %Ix\n", (ULONG_PTR)code_mem, base );
3304
3305 /* Second function is inaccessible yet. */
3306 base = 0xdeadbeef;
3307 func = pRtlLookupFunctionEntry( (ULONG_PTR)code_mem + code_offset + 16, &base, NULL );
3308 ok( func == NULL,
3309 "RtlLookupFunctionEntry didn't return expected function, expected: %p, got: %p\n", runtime_func, func );
3310
3311 pRtlGrowFunctionTable( growable_table, 2 );
3312
3313 base = 0xdeadbeef;
3314 func = pRtlLookupFunctionEntry( (ULONG_PTR)code_mem + code_offset + 16, &base, NULL );
3315 ok( func == runtime_func + 1,
3316 "RtlLookupFunctionEntry didn't return expected function, expected: %p, got: %p\n", runtime_func, func );
3318 "RtlLookupFunctionEntry returned invalid base, expected: %Ix, got: %Ix\n", (ULONG_PTR)code_mem, base );
3319
3320 base = 0xdeadbeef;
3321 func = pRtlLookupFunctionEntry( (ULONG_PTR)code_mem + code_offset + 32, &base, NULL );
3322 ok( func == NULL, "RtlLookupFunctionEntry got %p\n", func );
3323 ok( base == 0xdeadbeef, "RtlLookupFunctionTable wrong base, got: %Ix\n", base );
3324
3325 base = 0xdeadbeef;
3326 func = pRtlLookupFunctionTable( (ULONG_PTR)code_mem + code_offset + 8, &base, &len );
3327 ok( func == NULL, "RtlLookupFunctionTable wrong table, got: %p\n", func );
3328 ok( base == 0xdeadbeef, "RtlLookupFunctionTable wrong base, got: %Ix\n", base );
3329
3330 base = 0xdeadbeef;
3331 len = 0xdeadbeef;
3332 func = pRtlLookupFunctionTable( (ULONG_PTR)pRtlLookupFunctionEntry, &base, &len );
3333 ok( base == (ULONG_PTR)GetModuleHandleA("ntdll.dll"),
3334 "RtlLookupFunctionTable wrong base, got: %Ix / %p\n", base, GetModuleHandleA("ntdll.dll") );
3336 ok( func == ptr, "RtlLookupFunctionTable wrong table, got: %p / %p\n", func, ptr );
3337 ok( len == len2 || !ptr, "RtlLookupFunctionTable wrong len, got: %lu / %lu\n", len, len2 );
3338
3339 pRtlDeleteGrowableFunctionTable( growable_table );
3340
3341#ifndef __REACTOS__
3344 ec_code = 0;
3345 if (pNtAllocateVirtualMemoryEx &&
3346 !pNtAllocateVirtualMemoryEx( GetCurrentProcess(), (void **)&ec_code, &size,
3348 {
3349 static const BYTE fast_forward[] = { 0x48, 0x8b, 0xc4, 0x48, 0x89, 0x58, 0x20, 0x55, 0x5d, 0xe9 };
3350 IMAGE_ARM64EC_METADATA *metadata;
3352
3353 trace( "running arm64ec tests\n" );
3354
3355 if (!memcmp( pRtlLookupFunctionEntry, fast_forward, sizeof(fast_forward) ))
3356 {
3357 ptr = (char *)pRtlLookupFunctionEntry + sizeof(fast_forward);
3358 ptr = (char *)ptr + 4 + *(int *)ptr;
3359 base = 0xdeadbeef;
3360 func = pRtlLookupFunctionTable( (ULONG_PTR)ptr, &base, &len );
3361 ok( base == (ULONG_PTR)GetModuleHandleA("ntdll.dll"),
3362 "RtlLookupFunctionTable wrong base, got: %Ix / %p\n", base, GetModuleHandleA("ntdll.dll") );
3364 ok( func != ptr, "RtlLookupFunctionTable wrong table, got: %p / %p\n", func, ptr );
3366 metadata = (void *)((IMAGE_LOAD_CONFIG_DIRECTORY *)ptr)->CHPEMetadataPointer;
3367 ok( (char *)func == (char *)base + metadata->ExtraRFETable,
3368 "RtlLookupFunctonTable wrong table, got: %p / %p\n", func, (char *)base + metadata->ExtraRFETable );
3369 ok( len == metadata->ExtraRFETableSize, "RtlLookupFunctionTable wrong len, got: %lu / %lu\n",
3370 len, metadata->ExtraRFETableSize );
3371 }
3372
3373 arm64func->BeginAddress = code_offset;
3374 arm64func->Flag = 1;
3375 arm64func->FunctionLength = 4;
3376 arm64func->RegF = 1;
3377 arm64func->RegI = 1;
3378 arm64func->H = 1;
3379 arm64func->CR = 1;
3380 arm64func->FrameSize = 1;
3381 arm64func++;
3382 arm64func->BeginAddress = code_offset + 16;
3383 arm64func->Flag = 1;
3384 arm64func->FunctionLength = 4;
3385 arm64func->RegF = 1;
3386 arm64func->RegI = 1;
3387 arm64func->H = 1;
3388 arm64func->CR = 1;
3389 arm64func->FrameSize = 1;
3390
3391 growable_table = NULL;
3392 status = pRtlAddGrowableFunctionTable( &growable_table, (RUNTIME_FUNCTION *)buf,
3393 2, 2, ec_code, ec_code + code_offset + 64 );
3394 ok( !status, "RtlAddGrowableFunctionTable failed %lx\n", status );
3395
3396 base = 0xdeadbeef;
3397 func = pRtlLookupFunctionEntry( ec_code + code_offset + 8, &base, NULL );
3398 ok( func == (RUNTIME_FUNCTION *)buf, "RtlLookupFunctionEntry expected func: %p, got: %p\n",
3399 buf, func );
3400 ok( base == ec_code, "RtlLookupFunctionEntry expected base: %Ix, got: %Ix\n",
3401 ec_code, base );
3402
3403 base = 0xdeadbeef;
3404 func = pRtlLookupFunctionEntry( ec_code + code_offset + 16, &base, NULL );
3405 ok( func == (RUNTIME_FUNCTION *)(buf + sizeof(*arm64func)),
3406 "RtlLookupFunctionEntry expected func: %p, got: %p\n", buf + sizeof(*arm64func), func );
3407 ok( base == ec_code, "RtlLookupFunctionEntry expected base: %Ix, got: %Ix\n", ec_code, base );
3408
3409 base = 0xdeadbeef;
3410 func = pRtlLookupFunctionEntry( ec_code + code_offset + 32, &base, NULL );
3411 ok( !func, "RtlLookupFunctionEntry got: %p\n", func );
3412 ok( base == 0xdeadbeef, "RtlLookupFunctionEntry got: %Ix\n", base );
3413
3414 pRtlDeleteGrowableFunctionTable( growable_table );
3415 VirtualFree( (void *)ec_code, 0, MEM_RELEASE );
3416 }
3417#endif // __REACTOS__
3418}
#define trace
Definition: atltest.h:70
#define ok(value,...)
Definition: atltest.h:57
#define broken(x)
Definition: atltest.h:178
LONG NTSTATUS
Definition: precomp.h:26
#define TRUE
Definition: types.h:120
#define GetCurrentProcess()
Definition: compat.h:759
#define RtlImageDirectoryEntryToData
Definition: compat.h:809
#define IMAGE_DIRECTORY_ENTRY_LOAD_CONFIG
Definition: compat.h:153
_ACRTIMP int __cdecl memcmp(const void *, const void *, size_t)
Definition: string.c:2802
GLuint GLuint GLsizei count
Definition: gl.h:1545
GLenum func
Definition: glext.h:6028
GLsizeiptr size
Definition: glext.h:5919
GLenum GLuint GLenum GLsizei const GLchar * buf
Definition: glext.h:7751
GLfloat param
Definition: glext.h:5796
GLenum GLsizei len
Definition: glext.h:6722
#define win_skip
Definition: minitest.h:67
static PVOID ptr
Definition: dispmode.c:27
static RUNTIME_FUNCTION ULONG_PTR
Definition: unwind.c:46
static PRUNTIME_FUNCTION(WINAPI *pRtlLookupFunctionEntry)(ULONG_PTR
static RUNTIME_FUNCTION *CALLBACK dynamic_unwind_callback(DWORD_PTR pc, PVOID context)
Definition: unwind.c:3115
#define MEM_RELEASE
Definition: nt_native.h:1319
#define IMAGE_DIRECTORY_ENTRY_EXCEPTION
Definition: pedump.c:262
Definition: winnt_old.h:1280
DWORD BeginAddress
Definition: winnt_old.h:1281
DWORD RegF
Definition: winnt_old.h:1287
DWORD FrameSize
Definition: winnt_old.h:1291
DWORD H
Definition: winnt_old.h:1289
DWORD RegI
Definition: winnt_old.h:1288
DWORD CR
Definition: winnt_old.h:1290
DWORD FunctionLength
Definition: winnt_old.h:1286
DWORD Flag
Definition: winnt_old.h:1285
Definition: ps.c:97
ULONG_PTR SIZE_T
Definition: typedefs.h:80
uint32_t ULONG_PTR
Definition: typedefs.h:65
uint32_t ULONG
Definition: typedefs.h:59
BOOL NTAPI VirtualFree(IN LPVOID lpAddress, IN SIZE_T dwSize, IN DWORD dwFreeType)
Definition: virtmem.c:119
MEM_EXTENDED_PARAMETER
Definition: winnt_old.h:1265
#define MEM_EXTENDED_PARAMETER_EC_CODE
Definition: winnt_old.h:597
@ MemExtendedParameterAttributeFlags
Definition: winnt_old.h:1237
unsigned char BYTE
Definition: xxhash.c:193

Referenced by START_TEST().

◆ void()

static void ( WINAPI pRtlGrowFunctionTable)
static

Variable Documentation

◆ code_mem

void* code_mem
static

Definition at line 38 of file unwind.c.

Referenced by START_TEST(), and test_dynamic_unwind().

◆ DWORD

Definition at line 43 of file unwind.c.

◆ DWORD64

Definition at line 43 of file unwind.c.

Referenced by PopReg(), and RtlVirtualUnwind().

◆ ntdll

HMODULE ntdll
static

Definition at line 39 of file unwind.c.

Referenced by START_TEST().

◆ PCWSTR

Definition at line 43 of file unwind.c.

◆ PGET_RUNTIME_FUNCTION_CALLBACK

ULONG_PTR UNWIND_HISTORY_TABLE *static ULONG_PTR ULONG *static PGET_RUNTIME_FUNCTION_CALLBACK

Definition at line 43 of file unwind.c.

◆ PVOID

Definition at line 43 of file unwind.c.

Referenced by RtlRestoreContext(), RtlUnwindEx(), and RtlWalkFrameChain().

◆ ULONG

◆ ULONG_PTR

Definition at line 46 of file unwind.c.

Referenced by test_dynamic_unwind().