Alexandre Julliard : ntdll: Add test cases for the returned frame value in RtlVirtualUnwind.
Alexandre Julliard
julliard at winehq.org
Wed May 20 08:29:34 CDT 2009
Module: wine
Branch: master
Commit: 6c35e3f47c6c7e6f7e8da8e3c20b0784cc5ca8f2
URL: http://source.winehq.org/git/wine.git/?a=commit;h=6c35e3f47c6c7e6f7e8da8e3c20b0784cc5ca8f2
Author: Alexandre Julliard <julliard at 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[] =
More information about the wine-cvs
mailing list