3128{
3129 static const int code_offset = 1024;
3130 char buf[2 *
sizeof(RUNTIME_FUNCTION) + 4];
3132 RUNTIME_FUNCTION *runtime_func, *
func;
3134 void *growable_table, *
ptr;
3139
3140 if (!pRtlInstallFunctionTableCallback || !pRtlLookupFunctionEntry)
3141 {
3142 win_skip(
"Dynamic unwind functions not found\n" );
3143 return;
3144 }
3145
3146
3147 runtime_func = (RUNTIME_FUNCTION *)
buf;
3148 runtime_func->BeginAddress = code_offset;
3149 runtime_func->UnwindData = 0;
3152 "RtlAddFunctionTable failed for runtime_func = %p (aligned)\n", runtime_func );
3153
3154
3158 "RtlLookupFunctionEntry returned unexpected function, expected: NULL, got: %p\n",
func );
3160 "RtlLookupFunctionEntry modified base address, expected: 0, got: %Ix\n",
base );
3161
3162
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
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
3177 runtime_func = (RUNTIME_FUNCTION *)((
ULONG_PTR)
buf | 0x3);
3178 runtime_func->BeginAddress = code_offset;
3179 runtime_func->UnwindData = 0;
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
3187 runtime_func = (RUNTIME_FUNCTION *)
buf;
3188 runtime_func->BeginAddress = code_offset;
3189 runtime_func->UnwindData = 0;
3192 "RtlAddFunctionTable failed for runtime_func = %p (first attempt)\n", runtime_func );
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
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
3213 "RtlInstallFunctionTableCallback returned success for table = %Ix\n",
table );
3214
3215
3218 "RtlInstallFunctionTableCallback failed for table = %Ix\n",
table );
3219
3220
3225 "RtlLookupFunctionEntry returned unexpected function, expected: NULL, got: %p\n",
func );
3227 "RtlLookupFunctionEntry modified base address, expected: 0, got: %Ix\n",
base );
3229 "RtlLookupFunctionEntry issued %ld unexpected calls to dynamic_unwind_callback\n",
count );
3230
3231
3236 "RtlLookupFunctionEntry issued %ld calls to dynamic_unwind_callback, expected: 1\n",
count );
3238 {
3240 "RtlLookupFunctionEntry didn't return expected function, got: %p\n",
func );
3243 }
3244
3245
3247 "RtlDeleteFunctionTable failed for table = %p\n", (
PVOID)
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;
3261 runtime_func++;
3262 runtime_func->BeginAddress = code_offset + 16;
3263 runtime_func->UnwindData = 0;
3265 runtime_func = (RUNTIME_FUNCTION *)
buf;
3266
3267 growable_table =
NULL;
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;
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;
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;
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
3294 "RtlLookupFunctionEntry didn't return expected function, expected: %p, got: %p\n", runtime_func,
func );
3295
3296 pRtlGrowFunctionTable( growable_table, 1 );
3297
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
3309 "RtlLookupFunctionEntry didn't return expected function, expected: %p, got: %p\n", runtime_func,
func );
3310
3311 pRtlGrowFunctionTable( growable_table, 2 );
3312
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
3323 ok(
base == 0xdeadbeef,
"RtlLookupFunctionTable wrong base, got: %Ix\n",
base );
3324
3327 ok(
func ==
NULL,
"RtlLookupFunctionTable wrong table, got: %p\n",
func );
3328 ok(
base == 0xdeadbeef,
"RtlLookupFunctionTable wrong base, got: %Ix\n",
base );
3329
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 &&
3348 {
3349 static const BYTE fast_forward[] = { 0x48, 0x8b, 0xc4, 0x48, 0x89, 0x58, 0x20, 0x55, 0x5d, 0xe9 };
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);
3364 ok(
func !=
ptr,
"RtlLookupFunctionTable wrong table, got: %p / %p\n",
func,
ptr );
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",
3371 }
3372
3374 arm64func->
Flag = 1;
3376 arm64func->
RegF = 1;
3377 arm64func->
RegI = 1;
3381 arm64func++;
3383 arm64func->
Flag = 1;
3385 arm64func->
RegF = 1;
3386 arm64func->
RegI = 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
3397 func = pRtlLookupFunctionEntry( ec_code + code_offset + 8, &
base,
NULL );
3398 ok(
func == (RUNTIME_FUNCTION *)
buf,
"RtlLookupFunctionEntry expected func: %p, got: %p\n",
3400 ok(
base == ec_code,
"RtlLookupFunctionEntry expected base: %Ix, got: %Ix\n",
3402
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
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 );
3416 }
3417#endif
3418}
#define GetCurrentProcess()
#define RtlImageDirectoryEntryToData
#define IMAGE_DIRECTORY_ENTRY_LOAD_CONFIG
_ACRTIMP int __cdecl memcmp(const void *, const void *, size_t)
GLuint GLuint GLsizei count
GLenum GLuint GLenum GLsizei const GLchar * buf
static RUNTIME_FUNCTION ULONG_PTR
static PRUNTIME_FUNCTION(WINAPI *pRtlLookupFunctionEntry)(ULONG_PTR
static RUNTIME_FUNCTION *CALLBACK dynamic_unwind_callback(DWORD_PTR pc, PVOID context)
#define IMAGE_DIRECTORY_ENTRY_EXCEPTION
BOOL NTAPI VirtualFree(IN LPVOID lpAddress, IN SIZE_T dwSize, IN DWORD dwFreeType)
#define MEM_EXTENDED_PARAMETER_EC_CODE
@ MemExtendedParameterAttributeFlags