Commit 5154f22c authored by Thibaud Michaud's avatar Thibaud Michaud Committed by Commit Bot

Reland "[wasm][mac][arm64] Enable OOB trap handler"

This is a reland of a80d51d4

There were two main issues:
- Liftoff did 32 bit addition to get the offset, which overflowed and
created a valid address where an OOB was expected
- The access mode and landing pad was missing for SIMD load and store
instructions
Also fixed the macros to disable trap handlers from simulator builds.

Original change's description:
> [wasm][mac][arm64] Enable OOB trap handler
>
> R=ahaas@chromium.org,mark@chromium.org,mseaborn@chromium.org
>
> Bug: v8:11098
> Change-Id: Ic4eb02a96805e49da71f301269567a6e0ac1b843
> Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2519555
> Commit-Queue: Thibaud Michaud <thibaudm@chromium.org>
> Reviewed-by: Zhi An Ng <zhin@chromium.org>
> Reviewed-by: Igor Sheludko <ishell@chromium.org>
> Reviewed-by: Andreas Haas <ahaas@chromium.org>
> Cr-Commit-Position: refs/heads/master@{#72136}

Bug: v8:11098
Change-Id: I2ebe434577f2cbe168f0bccf2936f69ca211e3c1
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2637223Reviewed-by: 's avatarClemens Backes <clemensb@chromium.org>
Reviewed-by: 's avatarZhi An Ng <zhin@chromium.org>
Reviewed-by: 's avatarAndreas Haas <ahaas@chromium.org>
Commit-Queue: Thibaud Michaud <thibaudm@chromium.org>
Cr-Commit-Position: refs/heads/master@{#72401}
parent 0cd79797
......@@ -3806,6 +3806,13 @@ v8_source_set("v8_base_without_compiler") {
if (v8_control_flow_integrity) {
sources += [ "src/execution/arm64/pointer-authentication-arm64.h" ]
}
if (current_cpu == "arm64" && is_mac) {
sources += [
"src/trap-handler/handler-inside-posix.cc",
"src/trap-handler/handler-inside-posix.h",
"src/trap-handler/handler-outside-posix.cc",
]
}
if (is_win) {
sources += [
"src/diagnostics/unwinding-info-win64.cc",
......
......@@ -5911,7 +5911,13 @@ bool v8::V8::Initialize(const int build_config) {
#if V8_OS_LINUX || V8_OS_MACOSX
bool TryHandleWebAssemblyTrapPosix(int sig_code, siginfo_t* info,
void* context) {
#if V8_TARGET_ARCH_X64 && !V8_OS_ANDROID
// When the target code runs on the V8 arm simulator, the trap handler does
// not behave as expected: the instruction pointer points inside the simulator
// code rather than the wasm code, so the trap handler cannot find the landing
// pad and lets the process crash. Therefore, only enable trap handlers if
// the host and target arch are the same.
#if (V8_TARGET_ARCH_X64 && !V8_OS_ANDROID) || \
(V8_HOST_ARCH_ARM64 && V8_TARGET_ARCH_ARM64 && V8_OS_MACOSX)
return i::trap_handler::TryHandleSignal(sig_code, info, context);
#else
return false;
......
......@@ -673,6 +673,9 @@ void InstructionSelector::VisitLoadLane(Node* node) {
InstructionCode opcode = kArm64LoadLane;
opcode |= LaneSizeField::encode(params.rep.MemSize() * kBitsPerByte);
if (params.kind == MemoryAccessKind::kProtected) {
opcode |= AccessModeField::encode(kMemoryAccessProtected);
}
Arm64OperandGenerator g(this);
InstructionOperand addr = EmitAddBeforeLoadOrStore(this, node, &opcode);
......@@ -688,6 +691,9 @@ void InstructionSelector::VisitStoreLane(Node* node) {
InstructionCode opcode = kArm64StoreLane;
opcode |=
LaneSizeField::encode(ElementSizeInBytes(params.rep) * kBitsPerByte);
if (params.kind == MemoryAccessKind::kProtected) {
opcode |= AccessModeField::encode(kMemoryAccessProtected);
}
Arm64OperandGenerator g(this);
InstructionOperand addr = EmitAddBeforeLoadOrStore(this, node, &opcode);
......@@ -775,6 +781,9 @@ void InstructionSelector::VisitLoadTransform(Node* node) {
} else {
opcode |= AddressingModeField::encode(kMode_MRR);
}
if (params.kind == MemoryAccessKind::kProtected) {
opcode |= MiscField::encode(kMemoryAccessProtected);
}
Emit(opcode, 1, outputs, 2, inputs);
}
......@@ -847,16 +856,16 @@ void InstructionSelector::VisitLoad(Node* node) {
CHECK_NE(poisoning_level_, PoisoningMitigationLevel::kDontPoison);
opcode |= AccessModeField::encode(kMemoryAccessPoisoned);
}
if (node->opcode() == IrOpcode::kProtectedLoad) {
opcode |= MiscField::encode(kMemoryAccessProtected);
}
EmitLoad(this, node, opcode, immediate_mode, rep);
}
void InstructionSelector::VisitPoisonedLoad(Node* node) { VisitLoad(node); }
void InstructionSelector::VisitProtectedLoad(Node* node) {
// TODO(eholk)
UNIMPLEMENTED();
}
void InstructionSelector::VisitProtectedLoad(Node* node) { VisitLoad(node); }
void InstructionSelector::VisitStore(Node* node) {
Arm64OperandGenerator g(this);
......@@ -988,14 +997,15 @@ void InstructionSelector::VisitStore(Node* node) {
opcode |= AddressingModeField::encode(kMode_MRR);
}
if (node->opcode() == IrOpcode::kProtectedStore) {
opcode |= MiscField::encode(kMemoryAccessProtected);
}
Emit(opcode, 0, nullptr, input_count, inputs);
}
}
void InstructionSelector::VisitProtectedStore(Node* node) {
// TODO(eholk)
UNIMPLEMENTED();
}
void InstructionSelector::VisitProtectedStore(Node* node) { VisitStore(node); }
void InstructionSelector::VisitSimd128ReverseBytes(Node* node) {
UNREACHABLE();
......
......@@ -106,20 +106,22 @@ bool TryHandleSignal(int signum, siginfo_t* info, void* context) {
SigUnmaskStack unmask(sigs);
ucontext_t* uc = reinterpret_cast<ucontext_t*>(context);
#if V8_OS_LINUX
auto* context_rip = &uc->uc_mcontext.gregs[REG_RIP];
#elif V8_OS_MACOSX
auto* context_rip = &uc->uc_mcontext->__ss.__rip;
#elif V8_OS_FREEBSD
auto* context_rip = &uc->uc_mcontext.mc_rip;
#if V8_OS_LINUX && V8_TARGET_ARCH_X64
auto* context_ip = &uc->uc_mcontext.gregs[REG_RIP];
#elif V8_OS_MACOSX && V8_TARGET_ARCH_ARM64
auto* context_ip = &uc->uc_mcontext->__ss.__pc;
#elif V8_OS_MACOSX && V8_TARGET_ARCH_X64
auto* context_ip = &uc->uc_mcontext->__ss.__rip;
#elif V8_OS_FREEBSD && V8_TARGET_ARCH_X64
auto* context_ip = &uc->uc_mcontext.mc_rip;
#else
#error Unsupported platform
#endif
uintptr_t fault_addr = *context_rip;
uintptr_t fault_addr = *context_ip;
uintptr_t landing_pad = 0;
if (TryFindLandingPad(fault_addr, &landing_pad)) {
// Tell the caller to return to the landing pad.
*context_rip = landing_pad;
*context_ip = landing_pad;
// We will return to wasm code, so restore the g_thread_in_wasm_code flag.
g_thread_in_wasm_code = true;
return true;
......
......@@ -27,6 +27,8 @@ namespace trap_handler {
#define V8_TRAP_HANDLER_SUPPORTED true
#elif V8_TARGET_ARCH_X64 && V8_OS_FREEBSD
#define V8_TRAP_HANDLER_SUPPORTED true
#elif V8_HOST_ARCH_ARM64 && V8_TARGET_ARCH_ARM64 && V8_OS_MACOSX
#define V8_TRAP_HANDLER_SUPPORTED true
#else
#define V8_TRAP_HANDLER_SUPPORTED false
#endif
......
......@@ -125,11 +125,10 @@ inline MemOperand GetMemOp(LiftoffAssembler* assm,
Register offset, T offset_imm) {
if (offset.is_valid()) {
if (offset_imm == 0) return MemOperand(addr.X(), offset.W(), UXTW);
Register tmp = temps->AcquireW();
// TODO(clemensb): Do a 64-bit addition if memory64 is used.
Register tmp = temps->AcquireX();
DCHECK_GE(kMaxUInt32, offset_imm);
assm->Add(tmp, offset.W(), offset_imm);
return MemOperand(addr.X(), tmp, UXTW);
assm->Add(tmp, offset.X(), offset_imm);
return MemOperand(addr.X(), tmp);
}
return MemOperand(addr.X(), offset_imm);
}
......
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