Commit 6094c2e4 authored by Santiago Aboy Solanes's avatar Santiago Aboy Solanes Committed by Commit Bot

[unwinder] Update tests that starting unwinding from JSEntry frame

As a drive-by, enable tests that are safe for Arm32/64 to run.

Bug: v8:10833
Change-Id: I8fed5651399852f9ce8ba7d5acdb7ed27ca28e89
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2467841Reviewed-by: 's avatarRoss McIlroy <rmcilroy@chromium.org>
Commit-Queue: Santiago Aboy Solanes <solanes@chromium.org>
Cr-Commit-Position: refs/heads/master@{#70491}
parent 4d4f716b
...@@ -483,11 +483,7 @@ ...@@ -483,11 +483,7 @@
# Arm. They are disabled because the stack is not being set up the way it does # Arm. They are disabled because the stack is not being set up the way it does
# in the wild. # in the wild.
['arch == arm64 or arch == arm', { ['arch == arm64 or arch == arm', {
'test-unwinder-code-pages/Unwind_CodeObjectPCInMiddle_Success_CodePagesAPI': [SKIP],
'test-unwinder-code-pages/Unwind_JSEntryBeforeFrame_Fail_CodePagesAPI': [SKIP],
'test-unwinder-code-pages/Unwind_OneJSFrame_Success_CodePagesAPI': [SKIP],
'test-unwinder-code-pages/Unwind_TwoJSFrames_Success_CodePagesAPI': [SKIP], 'test-unwinder-code-pages/Unwind_TwoJSFrames_Success_CodePagesAPI': [SKIP],
'test-unwinder-code-pages/Unwind_StackBounds_Basic_CodePagesAPI': [SKIP],
'test-unwinder-code-pages/Unwind_StackBounds_WithUnwinding_CodePagesAPI': [SKIP], 'test-unwinder-code-pages/Unwind_StackBounds_WithUnwinding_CodePagesAPI': [SKIP],
}], }],
......
...@@ -282,54 +282,6 @@ TEST(Unwind_JSEntryBeforeFrame_Fail_CodePagesAPI) { ...@@ -282,54 +282,6 @@ TEST(Unwind_JSEntryBeforeFrame_Fail_CodePagesAPI) {
CHECK_EQ(jsentry_pc_value, register_state.pc); CHECK_EQ(jsentry_pc_value, register_state.pc);
} }
TEST(Unwind_OneJSFrame_Success_CodePagesAPI) {
LocalContext env;
v8::Isolate* isolate = env->GetIsolate();
JSEntryStubs entry_stubs = isolate->GetJSEntryStubs();
MemoryRange code_pages[1];
size_t pages_length = 1;
RegisterState register_state;
// Use a fake code range so that we can initialize it to 0s.
const size_t code_length = 40;
uintptr_t code[code_length] = {0};
code_pages[0].start = code;
code_pages[0].length_in_bytes = code_length * sizeof(uintptr_t);
// Our fake stack has two frames - one C++ frame and one JS frame (on top).
// The stack grows from high addresses to low addresses.
uintptr_t stack[10];
void* stack_base = stack + arraysize(stack);
stack[0] = 101;
stack[1] = 111;
stack[2] = 121;
stack[3] = 131;
stack[4] = 141;
// Index on the stack for the topmost fp (i.e the one right before the C++
// frame).
const int topmost_fp_index = 5;
stack[5] = reinterpret_cast<uintptr_t>(stack + 9); // saved FP.
stack[6] = 100; // Return address into C++ code.
stack[7] = reinterpret_cast<uintptr_t>(stack + 7); // saved SP.
stack[8] = 404;
stack[9] = 505;
register_state.sp = stack;
register_state.fp = stack + 5;
// Put the current PC inside of the code range so it looks valid.
register_state.pc = code + 30;
bool unwound = v8::Unwinder::TryUnwindV8Frames(
entry_stubs, pages_length, code_pages, &register_state, stack_base);
CHECK(unwound);
CHECK_EQ_STACK_REGISTER(stack[topmost_fp_index], register_state.fp);
CHECK_EQ_STACK_REGISTER(stack[topmost_fp_index + 1], register_state.pc);
CHECK_EQ_STACK_REGISTER(stack[topmost_fp_index + 2], register_state.sp);
}
// Creates a fake stack with two JS frames on top of a C++ frame and checks that // Creates a fake stack with two JS frames on top of a C++ frame and checks that
// the unwinder correctly unwinds past the JS frames and returns the C++ frame's // the unwinder correctly unwinds past the JS frames and returns the C++ frame's
// details. // details.
...@@ -356,7 +308,8 @@ TEST(Unwind_TwoJSFrames_Success_CodePagesAPI) { ...@@ -356,7 +308,8 @@ TEST(Unwind_TwoJSFrames_Success_CodePagesAPI) {
stack[1] = 111; stack[1] = 111;
stack[2] = reinterpret_cast<uintptr_t>(stack + 5); // saved FP. stack[2] = reinterpret_cast<uintptr_t>(stack + 5); // saved FP.
// The fake return address is in the JS code range. // The fake return address is in the JS code range.
stack[3] = reinterpret_cast<uintptr_t>(code + 10); const void* jsentry_pc = code + 10;
stack[3] = reinterpret_cast<uintptr_t>(jsentry_pc);
stack[4] = 141; stack[4] = 141;
// Index on the stack for the topmost fp (i.e the one right before the C++ // Index on the stack for the topmost fp (i.e the one right before the C++
// frame). // frame).
...@@ -373,6 +326,10 @@ TEST(Unwind_TwoJSFrames_Success_CodePagesAPI) { ...@@ -373,6 +326,10 @@ TEST(Unwind_TwoJSFrames_Success_CodePagesAPI) {
// Put the current PC inside of the code range so it looks valid. // Put the current PC inside of the code range so it looks valid.
register_state.pc = code + 30; register_state.pc = code + 30;
// Put the PC in the JSEntryRange.
entry_stubs.js_entry_stub.code.start = jsentry_pc;
entry_stubs.js_entry_stub.code.length_in_bytes = sizeof(uintptr_t);
bool unwound = v8::Unwinder::TryUnwindV8Frames( bool unwound = v8::Unwinder::TryUnwindV8Frames(
entry_stubs, pages_length, code_pages, &register_state, stack_base); entry_stubs, pages_length, code_pages, &register_state, stack_base);
...@@ -409,6 +366,8 @@ TEST(Unwind_JSEntry_Fail_CodePagesAPI) { ...@@ -409,6 +366,8 @@ TEST(Unwind_JSEntry_Fail_CodePagesAPI) {
CHECK_EQ(start + 10, register_state.pc); CHECK_EQ(start + 10, register_state.pc);
} }
// Tries to unwind a middle frame (i.e not a JSEntry frame) first with a wrong
// stack base, and then with the correct one.
TEST(Unwind_StackBounds_Basic_CodePagesAPI) { TEST(Unwind_StackBounds_Basic_CodePagesAPI) {
LocalContext env; LocalContext env;
v8::Isolate* isolate = env->GetIsolate(); v8::Isolate* isolate = env->GetIsolate();
...@@ -425,7 +384,7 @@ TEST(Unwind_StackBounds_Basic_CodePagesAPI) { ...@@ -425,7 +384,7 @@ TEST(Unwind_StackBounds_Basic_CodePagesAPI) {
uintptr_t stack[3]; uintptr_t stack[3];
stack[0] = reinterpret_cast<uintptr_t>(stack + 2); // saved FP. stack[0] = reinterpret_cast<uintptr_t>(stack + 2); // saved FP.
stack[1] = 202; // Return address into C++ code. stack[1] = 202; // saved PC.
stack[2] = 303; // saved SP. stack[2] = 303; // saved SP.
register_state.sp = stack; register_state.sp = stack;
...@@ -471,8 +430,9 @@ TEST(Unwind_StackBounds_WithUnwinding_CodePagesAPI) { ...@@ -471,8 +430,9 @@ TEST(Unwind_StackBounds_WithUnwinding_CodePagesAPI) {
stack[3] = 131; stack[3] = 131;
stack[4] = 141; stack[4] = 141;
stack[5] = reinterpret_cast<uintptr_t>(stack + 9); // saved FP. stack[5] = reinterpret_cast<uintptr_t>(stack + 9); // saved FP.
stack[6] = reinterpret_cast<uintptr_t>(code + 20); // JS code. const void* jsentry_pc = code + 20;
stack[7] = 303; // saved SP. stack[6] = reinterpret_cast<uintptr_t>(jsentry_pc); // JS code.
stack[7] = 303; // saved SP.
stack[8] = 404; stack[8] = 404;
stack[9] = reinterpret_cast<uintptr_t>(stack) + stack[9] = reinterpret_cast<uintptr_t>(stack) +
(12 * sizeof(uintptr_t)); // saved FP (OOB). (12 * sizeof(uintptr_t)); // saved FP (OOB).
...@@ -484,6 +444,10 @@ TEST(Unwind_StackBounds_WithUnwinding_CodePagesAPI) { ...@@ -484,6 +444,10 @@ TEST(Unwind_StackBounds_WithUnwinding_CodePagesAPI) {
// Put the current PC inside of the code range so it looks valid. // Put the current PC inside of the code range so it looks valid.
register_state.pc = code + 30; register_state.pc = code + 30;
// Put the PC in the JSEntryRange.
entry_stubs.js_entry_stub.code.start = jsentry_pc;
entry_stubs.js_entry_stub.code.length_in_bytes = sizeof(uintptr_t);
// Unwind will fail because stack[9] FP points outside of the stack. // Unwind will fail because stack[9] FP points outside of the stack.
bool unwound = v8::Unwinder::TryUnwindV8Frames( bool unwound = v8::Unwinder::TryUnwindV8Frames(
entry_stubs, pages_length, code_pages, &register_state, stack_base); entry_stubs, pages_length, code_pages, &register_state, stack_base);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment