[arm] Update unwinder for JSEntry frames for arm32

Reading the proper pc, fp and sp in a JSEntry frame is in a different
offset than in the regular frames.

Bug: v8:10779, v8:10833
Fixes: v8:10779
Change-Id: I9aec44276fba0aab95b761ab17a16ec3767f4eb8
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2369173
Commit-Queue: Santiago Aboy Solanes <solanes@chromium.org>
Reviewed-by: Ross McIlroy <rmcilroy@chromium.org>
Cr-Commit-Position: refs/heads/master@{#69582}
This commit is contained in:
Santiago Aboy Solanes 2020-08-27 10:04:44 +01:00 committed by Commit Bot
parent c75f19bbee
commit ab4ae86060
4 changed files with 57 additions and 3 deletions

View File

@ -532,6 +532,13 @@ constexpr int kPushedStackSpace = kNumCalleeSaved * kPointerSize +
4 * kPointerSize /* r5, r6, r7, scratch */ + 4 * kPointerSize /* r5, r6, r7, scratch */ +
EntryFrameConstants::kCallerFPOffset; EntryFrameConstants::kCallerFPOffset;
// Assert that the EntryFrameConstants are in sync with the builtin.
static_assert(kPushedStackSpace == EntryFrameConstants::kDirectCallerSPOffset +
3 * kPointerSize /* r5, r6, r7*/ +
EntryFrameConstants::kCallerFPOffset,
"Pushed stack space and frame constants do not match. See "
"frame-constants-arm.h");
// Called with the native C calling convention. The corresponding function // Called with the native C calling convention. The corresponding function
// signature is either: // signature is either:
// //

View File

@ -68,7 +68,7 @@ i::Address Load(i::Address address) {
void* GetReturnAddressFromFP(void* fp, void* pc, void* GetReturnAddressFromFP(void* fp, void* pc,
const JSEntryStubs& entry_stubs) { const JSEntryStubs& entry_stubs) {
int caller_pc_offset = i::CommonFrameConstants::kCallerPCOffset; int caller_pc_offset = i::CommonFrameConstants::kCallerPCOffset;
#ifdef V8_TARGET_ARCH_ARM64 #if V8_TARGET_ARCH_ARM64 || V8_TARGET_ARCH_ARM
if (IsInJSEntryRange(entry_stubs, pc)) { if (IsInJSEntryRange(entry_stubs, pc)) {
caller_pc_offset = i::EntryFrameConstants::kDirectCallerPCOffset; caller_pc_offset = i::EntryFrameConstants::kDirectCallerPCOffset;
} }
@ -80,7 +80,7 @@ void* GetReturnAddressFromFP(void* fp, void* pc,
void* GetCallerFPFromFP(void* fp, void* pc, const JSEntryStubs& entry_stubs) { void* GetCallerFPFromFP(void* fp, void* pc, const JSEntryStubs& entry_stubs) {
int caller_fp_offset = i::CommonFrameConstants::kCallerFPOffset; int caller_fp_offset = i::CommonFrameConstants::kCallerFPOffset;
#ifdef V8_TARGET_ARCH_ARM64 #if V8_TARGET_ARCH_ARM64 || V8_TARGET_ARCH_ARM
if (IsInJSEntryRange(entry_stubs, pc)) { if (IsInJSEntryRange(entry_stubs, pc)) {
caller_fp_offset = i::EntryFrameConstants::kDirectCallerFPOffset; caller_fp_offset = i::EntryFrameConstants::kDirectCallerFPOffset;
} }
@ -91,7 +91,7 @@ void* GetCallerFPFromFP(void* fp, void* pc, const JSEntryStubs& entry_stubs) {
void* GetCallerSPFromFP(void* fp, void* pc, const JSEntryStubs& entry_stubs) { void* GetCallerSPFromFP(void* fp, void* pc, const JSEntryStubs& entry_stubs) {
int caller_sp_offset = i::CommonFrameConstants::kCallerSPOffset; int caller_sp_offset = i::CommonFrameConstants::kCallerSPOffset;
#ifdef V8_TARGET_ARCH_ARM64 #if V8_TARGET_ARCH_ARM64 || V8_TARGET_ARCH_ARM
if (IsInJSEntryRange(entry_stubs, pc)) { if (IsInJSEntryRange(entry_stubs, pc)) {
caller_sp_offset = i::EntryFrameConstants::kDirectCallerSPOffset; caller_sp_offset = i::EntryFrameConstants::kDirectCallerSPOffset;
} }

View File

@ -7,11 +7,31 @@
#include "src/base/bits.h" #include "src/base/bits.h"
#include "src/base/macros.h" #include "src/base/macros.h"
#include "src/codegen/arm/register-arm.h"
#include "src/execution/frame-constants.h" #include "src/execution/frame-constants.h"
namespace v8 { namespace v8 {
namespace internal { namespace internal {
// The layout of an EntryFrame is as follows:
// TOP OF THE STACK LOWEST ADDRESS
// +---------------------+-----------------------
// 0 | bad frame pointer | <-- frame ptr
// | (0xFFF.. FF) |
// |- - - - - - - - - - -|
// 1..2 | saved register d8 |
// ... | ... |
// 15..16 | saved register d15 |
// |- - - - - - - - - - -|
// 17 | saved register r4 |
// ... | ... |
// 23 | saved register r10 |
// |- - - - - - - - - - -|
// 24 | saved fp (r11) |
// |- - - - - - - - - - -|
// 25 | saved lr (r14) |
// -----+---------------------+-----------------------
// BOTTOM OF THE STACK HIGHEST ADDRESS
class EntryFrameConstants : public AllStatic { class EntryFrameConstants : public AllStatic {
public: public:
// This is the offset to where JSEntry pushes the current value of // This is the offset to where JSEntry pushes the current value of
@ -22,6 +42,19 @@ class EntryFrameConstants : public AllStatic {
// Stack offsets for arguments passed to JSEntry. // Stack offsets for arguments passed to JSEntry.
static constexpr int kArgcOffset = +0 * kSystemPointerSize; static constexpr int kArgcOffset = +0 * kSystemPointerSize;
static constexpr int kArgvOffset = +1 * kSystemPointerSize; static constexpr int kArgvOffset = +1 * kSystemPointerSize;
// These offsets refer to the immediate caller (i.e a native frame).
static constexpr int kDirectCallerFPOffset =
/* bad frame pointer (-1) */
kPointerSize +
/* d8...d15 */
kNumDoubleCalleeSaved * kDoubleSize +
/* r4...r10 (i.e callee saved without fp) */
(kNumCalleeSaved - 1) * kPointerSize;
static constexpr int kDirectCallerPCOffset =
kDirectCallerFPOffset + 1 * kSystemPointerSize;
static constexpr int kDirectCallerSPOffset =
kDirectCallerPCOffset + 1 * kSystemPointerSize;
}; };
class WasmCompileLazyFrameConstants : public TypedFrameConstants { class WasmCompileLazyFrameConstants : public TypedFrameConstants {

View File

@ -469,6 +469,20 @@
'test-unwinder-code-pages/*': [SKIP] 'test-unwinder-code-pages/*': [SKIP]
}], }],
# TODO(solanes, v8:10833): Re-enable these tests or create specific ones for
# Arm. They are disabled because the stack is not being set up the way it does
# in the wild.
['arch == arm64 or arch == arm', {
'test-unwinder-code-pages/Unwind_BuiltinPCInMiddle_Success_CodePagesAPI': [SKIP],
'test-unwinder-code-pages/Unwind_BuiltinPCAtStart_Success_CodePagesAPI': [SKIP],
'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_StackBounds_Basic_CodePagesAPI': [SKIP],
'test-unwinder-code-pages/Unwind_StackBounds_WithUnwinding_CodePagesAPI': [SKIP],
}],
############################################################################## ##############################################################################
['lite_mode or variant == jitless', { ['lite_mode or variant == jitless', {