Module: wine Branch: master Commit: 6c35e3f47c6c7e6f7e8da8e3c20b0784cc5ca8f2 URL: http://source.winehq.org/git/wine.git/?a=commit;h=6c35e3f47c6c7e6f7e8da8e3c2...
Author: Alexandre Julliard julliard@winehq.org Date: Wed May 20 13:33:32 2009 +0200
ntdll: Add test cases for the returned frame value in RtlVirtualUnwind.
---
dlls/ntdll/signal_x86_64.c | 5 +-- dlls/ntdll/tests/exception.c | 57 ++++++++++++++++++++++-------------------- 2 files changed, 32 insertions(+), 30 deletions(-)
diff --git a/dlls/ntdll/signal_x86_64.c b/dlls/ntdll/signal_x86_64.c index bf78685..1c315d1 100644 --- a/dlls/ntdll/signal_x86_64.c +++ b/dlls/ntdll/signal_x86_64.c @@ -1202,7 +1202,7 @@ PVOID WINAPI RtlVirtualUnwind( ULONG type, ULONG64 base, ULONG64 pc,
dump_unwind_info( base, function );
- frame = context->Rsp; + frame = *frame_ret = context->Rsp; for (;;) { info = (struct UNWIND_INFO *)((char *)base + function->UnwindData); @@ -1251,7 +1251,7 @@ PVOID WINAPI RtlVirtualUnwind( ULONG type, ULONG64 base, ULONG64 pc, context->Rsp += (info->opcodes[i].info + 1) * 8; break; case UWOP_SET_FPREG: /* leaq nn(%rsp),%framereg */ - context->Rsp = frame; + context->Rsp = *frame_ret = frame; break; case UWOP_SAVE_NONVOL: /* movq %reg,n(%rsp) */ off = frame + *(USHORT *)&info->opcodes[i+1] * 8; @@ -1285,7 +1285,6 @@ PVOID WINAPI RtlVirtualUnwind( ULONG type, ULONG64 base, ULONG64 pc, /* now pop return address */ context->Rip = *(ULONG64 *)context->Rsp; context->Rsp += sizeof(ULONG64); - *frame_ret = frame;
if (!(info->flags & type)) return NULL; /* no matching handler */ if (prolog_offset != ~0) return NULL; /* inside prolog */ diff --git a/dlls/ntdll/tests/exception.c b/dlls/ntdll/tests/exception.c index ff4125f..aefce8b 100644 --- a/dlls/ntdll/tests/exception.c +++ b/dlls/ntdll/tests/exception.c @@ -941,6 +941,7 @@ struct results int rbp_offset; /* rbp offset from stack pointer */ int handler; /* expect handler to be set? */ int rip; /* expected final rip value */ + int frame; /* expected frame return value */ int regs[8][2]; /* expected values for registers */ };
@@ -1022,6 +1023,8 @@ static void call_virtual_unwind( int testnum, const struct unwind_test *test )
ok( context.Rip == test->results[i].rip, "%u/%u: wrong rip %p/%x\n", testnum, i, (void *)context.Rip, test->results[i].rip ); + ok( frame == (ULONG64)fake_stack + test->results[i].frame, "%u/%u: wrong frame %p/%p\n", + testnum, i, (void *)frame, (char *)fake_stack + test->results[i].frame );
for (j = 0; j < 16; j++) { @@ -1107,18 +1110,18 @@ static void test_virtual_unwind(void)
static const struct results results_0[] = { - /* offset rbp handler rip registers */ - { 0x00, 0x40, FALSE, 0x000, { {rsp,0x008}, {-1,-1} }}, - { 0x02, 0x40, FALSE, 0x008, { {rsp,0x010}, {rbp,0x000}, {-1,-1} }}, - { 0x09, 0x40, FALSE, 0x118, { {rsp,0x120}, {rbp,0x110}, {-1,-1} }}, - { 0x0e, 0x40, FALSE, 0x128, { {rsp,0x130}, {rbp,0x120}, {-1,-1} }}, - { 0x15, 0x40, FALSE, 0x128, { {rsp,0x130}, {rbp,0x120}, {rbx,0x130}, {-1,-1} }}, - { 0x1c, 0x40, TRUE, 0x128, { {rsp,0x130}, {rbp,0x120}, {rbx,0x130}, {rsi,0x138}, {-1,-1}}}, - { 0x1d, 0x40, TRUE, 0x128, { {rsp,0x130}, {rbp,0x120}, {rbx,0x130}, {rsi,0x138}, {-1,-1}}}, - { 0x24, 0x40, TRUE, 0x128, { {rsp,0x130}, {rbp,0x120}, {rbx,0x130}, {rsi,0x138}, {-1,-1}}}, - { 0x2b, 0x40, FALSE, 0x128, { {rsp,0x130}, {rbp,0x120}, {-1,-1}}}, - { 0x32, 0x40, FALSE, 0x008, { {rsp,0x010}, {rbp,0x000}, {-1,-1}}}, - { 0x33, 0x40, FALSE, 0x000, { {rsp,0x008}, {-1,-1}}}, + /* offset rbp handler rip frame registers */ + { 0x00, 0x40, FALSE, 0x000, 0x000, { {rsp,0x008}, {-1,-1} }}, + { 0x02, 0x40, FALSE, 0x008, 0x000, { {rsp,0x010}, {rbp,0x000}, {-1,-1} }}, + { 0x09, 0x40, FALSE, 0x118, 0x000, { {rsp,0x120}, {rbp,0x110}, {-1,-1} }}, + { 0x0e, 0x40, FALSE, 0x128, 0x010, { {rsp,0x130}, {rbp,0x120}, {-1,-1} }}, + { 0x15, 0x40, FALSE, 0x128, 0x010, { {rsp,0x130}, {rbp,0x120}, {rbx,0x130}, {-1,-1} }}, + { 0x1c, 0x40, TRUE, 0x128, 0x010, { {rsp,0x130}, {rbp,0x120}, {rbx,0x130}, {rsi,0x138}, {-1,-1}}}, + { 0x1d, 0x40, TRUE, 0x128, 0x010, { {rsp,0x130}, {rbp,0x120}, {rbx,0x130}, {rsi,0x138}, {-1,-1}}}, + { 0x24, 0x40, TRUE, 0x128, 0x010, { {rsp,0x130}, {rbp,0x120}, {rbx,0x130}, {rsi,0x138}, {-1,-1}}}, + { 0x2b, 0x40, FALSE, 0x128, 0x010, { {rsp,0x130}, {rbp,0x120}, {-1,-1}}}, + { 0x32, 0x40, FALSE, 0x008, 0x010, { {rsp,0x010}, {rbp,0x000}, {-1,-1}}}, + { 0x33, 0x40, FALSE, 0x000, 0x010, { {rsp,0x008}, {-1,-1}}}, };
@@ -1160,21 +1163,21 @@ static void test_virtual_unwind(void)
static const struct results results_1[] = { - /* offset rbp handler rip registers */ - { 0x00, 0x50, FALSE, 0x000, { {rsp,0x008}, {-1,-1} }}, - { 0x01, 0x50, FALSE, 0x008, { {rsp,0x010}, {rbx,0x000}, {-1,-1} }}, - { 0x02, 0x50, FALSE, 0x010, { {rsp,0x018}, {rbx,0x008}, {rbp,0x000}, {-1,-1} }}, - { 0x03, 0x50, FALSE, 0x018, { {rsp,0x020}, {rbx,0x010}, {rbp,0x008}, {rsi,0x000}, {-1,-1} }}, - { 0x04, 0x50, FALSE, 0x020, { {rsp,0x028}, {rbx,0x018}, {rbp,0x010}, {rsi,0x008}, {rdi,0x000}, {-1,-1} }}, - { 0x06, 0x50, FALSE, 0x028, { {rsp,0x030}, {rbx,0x020}, {rbp,0x018}, {rsi,0x010}, {rdi,0x008}, {r12,0x000}, {-1,-1} }}, - { 0x0a, 0x50, TRUE, 0x058, { {rsp,0x060}, {rbx,0x050}, {rbp,0x048}, {rsi,0x040}, {rdi,0x038}, {r12,0x030}, {-1,-1} }}, - { 0x0c, 0x50, FALSE, 0x058, { {rsp,0x060}, {rbx,0x050}, {rbp,0x048}, {rsi,0x040}, {rdi,0x038}, {r12,0x030}, {-1,-1} }}, - { 0x10, 0x50, FALSE, 0x028, { {rsp,0x030}, {rbx,0x020}, {rbp,0x018}, {rsi,0x010}, {rdi,0x008}, {r12,0x000}, {-1,-1} }}, - { 0x12, 0x50, FALSE, 0x020, { {rsp,0x028}, {rbx,0x018}, {rbp,0x010}, {rsi,0x008}, {rdi,0x000}, {-1,-1} }}, - { 0x13, 0x50, FALSE, 0x018, { {rsp,0x020}, {rbx,0x010}, {rbp,0x008}, {rsi,0x000}, {-1,-1} }}, - { 0x14, 0x50, FALSE, 0x010, { {rsp,0x018}, {rbx,0x008}, {rbp,0x000}, {-1,-1} }}, - { 0x15, 0x50, FALSE, 0x008, { {rsp,0x010}, {rbx,0x000}, {-1,-1} }}, - { 0x16, 0x50, FALSE, 0x000, { {rsp,0x008}, {-1,-1} }}, + /* offset rbp handler rip frame registers */ + { 0x00, 0x50, FALSE, 0x000, 0x000, { {rsp,0x008}, {-1,-1} }}, + { 0x01, 0x50, FALSE, 0x008, 0x000, { {rsp,0x010}, {rbx,0x000}, {-1,-1} }}, + { 0x02, 0x50, FALSE, 0x010, 0x000, { {rsp,0x018}, {rbx,0x008}, {rbp,0x000}, {-1,-1} }}, + { 0x03, 0x50, FALSE, 0x018, 0x000, { {rsp,0x020}, {rbx,0x010}, {rbp,0x008}, {rsi,0x000}, {-1,-1} }}, + { 0x04, 0x50, FALSE, 0x020, 0x000, { {rsp,0x028}, {rbx,0x018}, {rbp,0x010}, {rsi,0x008}, {rdi,0x000}, {-1,-1} }}, + { 0x06, 0x50, FALSE, 0x028, 0x000, { {rsp,0x030}, {rbx,0x020}, {rbp,0x018}, {rsi,0x010}, {rdi,0x008}, {r12,0x000}, {-1,-1} }}, + { 0x0a, 0x50, TRUE, 0x058, 0x000, { {rsp,0x060}, {rbx,0x050}, {rbp,0x048}, {rsi,0x040}, {rdi,0x038}, {r12,0x030}, {-1,-1} }}, + { 0x0c, 0x50, FALSE, 0x058, 0x000, { {rsp,0x060}, {rbx,0x050}, {rbp,0x048}, {rsi,0x040}, {rdi,0x038}, {r12,0x030}, {-1,-1} }}, + { 0x10, 0x50, FALSE, 0x028, 0x000, { {rsp,0x030}, {rbx,0x020}, {rbp,0x018}, {rsi,0x010}, {rdi,0x008}, {r12,0x000}, {-1,-1} }}, + { 0x12, 0x50, FALSE, 0x020, 0x000, { {rsp,0x028}, {rbx,0x018}, {rbp,0x010}, {rsi,0x008}, {rdi,0x000}, {-1,-1} }}, + { 0x13, 0x50, FALSE, 0x018, 0x000, { {rsp,0x020}, {rbx,0x010}, {rbp,0x008}, {rsi,0x000}, {-1,-1} }}, + { 0x14, 0x50, FALSE, 0x010, 0x000, { {rsp,0x018}, {rbx,0x008}, {rbp,0x000}, {-1,-1} }}, + { 0x15, 0x50, FALSE, 0x008, 0x000, { {rsp,0x010}, {rbx,0x000}, {-1,-1} }}, + { 0x16, 0x50, FALSE, 0x000, 0x000, { {rsp,0x008}, {-1,-1} }}, };
static const struct unwind_test tests[] =