ec06bb6ce5
This is a reland of d1b27019d3
Fixes include:
Adding missing file to bazel build
Forward-declaring classing before friend-classing them to fix win/gcc
Add missing v8-isolate.h include for vtune builds
Original change's description:
> [include] Split out v8.h
>
> This moves every single class/function out of include/v8.h into a
> separate header in include/, which v8.h then includes so that
> externally nothing appears to have changed.
>
> Every include of v8.h from inside v8 has been changed to a more
> fine-grained include.
>
> Previously inline functions defined at the bottom of v8.h would call
> private non-inline functions in the V8 class. Since that class is now
> in v8-initialization.h and is rarely included (as that would create
> dependency cycles), this is not possible and so those methods have been
> moved out of the V8 class into the namespace v8::api_internal.
>
> None of the previous files in include/ now #include v8.h, which means
> if embedders were relying on this transitive dependency then it will
> give compile failures.
>
> v8-inspector.h does depend on v8-scripts.h for the time being to ensure
> that Chrome continue to compile but that change will be reverted once
> those transitive #includes in chrome are changed to include it directly.
>
> Full design:
> https://docs.google.com/document/d/1rTD--I8hCAr-Rho1WTumZzFKaDpEp0IJ8ejZtk4nJdA/edit?usp=sharing
>
> Bug: v8:11965
> Change-Id: I53b84b29581632710edc80eb11f819c2097a2877
> Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3097448
> Reviewed-by: Yang Guo <yangguo@chromium.org>
> Reviewed-by: Camillo Bruni <cbruni@chromium.org>
> Reviewed-by: Jakob Kummerow <jkummerow@chromium.org>
> Reviewed-by: Leszek Swirski <leszeks@chromium.org>
> Reviewed-by: Michael Lippautz <mlippautz@chromium.org>
> Commit-Queue: Dan Elphick <delphick@chromium.org>
> Cr-Commit-Position: refs/heads/main@{#76424}
Cq-Include-Trybots: luci.v8.try:v8_linux_vtunejit
Bug: v8:11965
Change-Id: I99f5d3a73bf8fe25b650adfaf9567dc4e44a09e6
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3113629
Reviewed-by: Leszek Swirski <leszeks@chromium.org>
Reviewed-by: Camillo Bruni <cbruni@chromium.org>
Reviewed-by: Michael Lippautz <mlippautz@chromium.org>
Reviewed-by: Jakob Kummerow <jkummerow@chromium.org>
Reviewed-by: Simon Zünd <szuend@chromium.org>
Commit-Queue: Dan Elphick <delphick@chromium.org>
Cr-Commit-Position: refs/heads/main@{#76460}
126 lines
3.9 KiB
C++
126 lines
3.9 KiB
C++
// Copyright 2021 the V8 project authors. All rights reserved.
|
|
// Use of this source code is governed by a BSD-style license that can be
|
|
// found in the LICENSE file.
|
|
|
|
#include "src/trap-handler/trap-handler-simulator.h"
|
|
|
|
#include "include/v8-initialization.h"
|
|
#include "src/codegen/macro-assembler-inl.h"
|
|
#include "src/execution/simulator.h"
|
|
#include "src/trap-handler/trap-handler.h"
|
|
#include "test/common/assembler-tester.h"
|
|
#include "test/unittests/test-utils.h"
|
|
|
|
#if !V8_HOST_ARCH_X64 || !V8_TARGET_ARCH_ARM64
|
|
#error "Only include this file on arm64 simulator builds on x64."
|
|
#endif
|
|
|
|
namespace v8 {
|
|
namespace internal {
|
|
namespace trap_handler {
|
|
|
|
constexpr uintptr_t kFakePc = 11;
|
|
|
|
class SimulatorTrapHandlerTest : public TestWithIsolate {
|
|
public:
|
|
void SetThreadInWasm() {
|
|
EXPECT_EQ(0, *thread_in_wasm);
|
|
*thread_in_wasm = 1;
|
|
}
|
|
|
|
void ResetThreadInWasm() {
|
|
EXPECT_EQ(1, *thread_in_wasm);
|
|
*thread_in_wasm = 0;
|
|
}
|
|
|
|
int* thread_in_wasm = trap_handler::GetThreadInWasmThreadLocalAddress();
|
|
};
|
|
|
|
TEST_F(SimulatorTrapHandlerTest, ProbeMemorySuccess) {
|
|
int x = 47;
|
|
EXPECT_EQ(0u, ProbeMemory(reinterpret_cast<uintptr_t>(&x), kFakePc));
|
|
}
|
|
|
|
TEST_F(SimulatorTrapHandlerTest, ProbeMemoryFail) {
|
|
constexpr uintptr_t kNullAddress = 0;
|
|
EXPECT_DEATH_IF_SUPPORTED(ProbeMemory(kNullAddress, kFakePc), "");
|
|
}
|
|
|
|
TEST_F(SimulatorTrapHandlerTest, ProbeMemoryFailWhileInWasm) {
|
|
// Test that we still crash if the trap handler is set up and the "thread in
|
|
// wasm" flag is set, but the PC is not registered as a protected instruction.
|
|
constexpr bool kUseDefaultHandler = true;
|
|
CHECK(v8::V8::EnableWebAssemblyTrapHandler(kUseDefaultHandler));
|
|
|
|
constexpr uintptr_t kNullAddress = 0;
|
|
SetThreadInWasm();
|
|
EXPECT_DEATH_IF_SUPPORTED(ProbeMemory(kNullAddress, kFakePc), "");
|
|
}
|
|
|
|
TEST_F(SimulatorTrapHandlerTest, ProbeMemoryWithTrapHandled) {
|
|
constexpr uintptr_t kNullAddress = 0;
|
|
constexpr uintptr_t kFakeLandingPad = 19;
|
|
|
|
constexpr bool kUseDefaultHandler = true;
|
|
CHECK(v8::V8::EnableWebAssemblyTrapHandler(kUseDefaultHandler));
|
|
|
|
ProtectedInstructionData fake_protected_instruction{kFakePc, kFakeLandingPad};
|
|
int handler_data_index =
|
|
RegisterHandlerData(0, 128, 1, &fake_protected_instruction);
|
|
|
|
SetThreadInWasm();
|
|
EXPECT_EQ(kFakeLandingPad, ProbeMemory(kNullAddress, kFakePc));
|
|
|
|
// Reset everything.
|
|
ResetThreadInWasm();
|
|
ReleaseHandlerData(handler_data_index);
|
|
RemoveTrapHandler();
|
|
}
|
|
|
|
TEST_F(SimulatorTrapHandlerTest, ProbeMemoryWithLandingPad) {
|
|
EXPECT_EQ(0u, GetRecoveredTrapCount());
|
|
|
|
// Test that the trap handler can recover a memory access violation in
|
|
// wasm code (we fake the wasm code and the access violation).
|
|
std::unique_ptr<TestingAssemblerBuffer> buffer = AllocateAssemblerBuffer();
|
|
constexpr Register scratch = x0;
|
|
MacroAssembler masm(nullptr, AssemblerOptions{}, CodeObjectRequired::kNo,
|
|
buffer->CreateView());
|
|
// Generate an illegal memory access.
|
|
masm.Mov(scratch, 0);
|
|
uint32_t crash_offset = masm.pc_offset();
|
|
masm.Str(scratch, MemOperand(scratch, 0)); // nullptr access
|
|
uint32_t recovery_offset = masm.pc_offset();
|
|
// Return.
|
|
masm.Ret();
|
|
|
|
CodeDesc desc;
|
|
masm.GetCode(nullptr, &desc);
|
|
|
|
constexpr bool kUseDefaultHandler = true;
|
|
CHECK(v8::V8::EnableWebAssemblyTrapHandler(kUseDefaultHandler));
|
|
|
|
ProtectedInstructionData protected_instruction{crash_offset, recovery_offset};
|
|
int handler_data_index =
|
|
RegisterHandlerData(reinterpret_cast<Address>(desc.buffer),
|
|
desc.instr_size, 1, &protected_instruction);
|
|
|
|
// Now execute the code.
|
|
buffer->MakeExecutable();
|
|
GeneratedCode<void> code = GeneratedCode<void>::FromAddress(
|
|
i_isolate(), reinterpret_cast<Address>(desc.buffer));
|
|
|
|
SetThreadInWasm();
|
|
code.Call();
|
|
ResetThreadInWasm();
|
|
|
|
ReleaseHandlerData(handler_data_index);
|
|
RemoveTrapHandler();
|
|
|
|
EXPECT_EQ(1u, GetRecoveredTrapCount());
|
|
}
|
|
|
|
} // namespace trap_handler
|
|
} // namespace internal
|
|
} // namespace v8
|