Commit 2ce64d53 authored by Georgia Kouveli's avatar Georgia Kouveli Committed by Commit Bot

[liftoff] Do not sign-extend memory access offset.

Memory access offsets are unsigned. Sign-extending them incorrectly
treats some large offsets as negative numbers and results in
out-of-bounds errors for in-bounds accesses.

This caused a failure in test/mjsunit/wasm/huge-memory.js for arm64, and
for x64 with --nowasm_trap_handler.

Change-Id: If58fead1d115f16ba4a6c3680252111fba6843d1
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2002821
Commit-Queue: Georgia Kouveli <georgia.kouveli@arm.com>
Reviewed-by: 's avatarClemens Backes <clemensb@chromium.org>
Cr-Commit-Position: refs/heads/master@{#65838}
parent 16a04110
......@@ -1192,7 +1192,7 @@ void LiftoffAssembler::emit_f64_max(DoubleRegister dst, DoubleRegister lhs,
liftoff::EmitFloatMinOrMax(this, dst, lhs, rhs, liftoff::MinOrMax::kMax);
}
void LiftoffAssembler::emit_i32_to_intptr(Register dst, Register src) {
void LiftoffAssembler::emit_u32_to_intptr(Register dst, Register src) {
// This is a nop on arm.
}
......
......@@ -91,10 +91,8 @@ inline CPURegister AcquireByType(UseScratchRegisterScope* temps,
inline MemOperand GetMemOp(LiftoffAssembler* assm,
UseScratchRegisterScope* temps, Register addr,
Register offset, uint32_t offset_imm) {
// Wasm memory is limited to a size <2GB, so all offsets can be encoded as
// immediate value (in 31 bits, interpreted as signed value).
// If the offset is bigger, we always trap and this code is not reached.
DCHECK(is_uint31(offset_imm));
// Wasm memory is limited to a size <4GB.
DCHECK(is_uint32(offset_imm));
if (offset.is_valid()) {
if (offset_imm == 0) return MemOperand(addr.X(), offset.W(), UXTW);
Register tmp = temps->AcquireW();
......@@ -781,8 +779,8 @@ bool LiftoffAssembler::emit_i64_remu(LiftoffRegister dst, LiftoffRegister lhs,
return true;
}
void LiftoffAssembler::emit_i32_to_intptr(Register dst, Register src) {
Sxtw(dst, src);
void LiftoffAssembler::emit_u32_to_intptr(Register dst, Register src) {
Uxtw(dst, src);
}
void LiftoffAssembler::emit_f32_copysign(DoubleRegister dst, DoubleRegister lhs,
......
......@@ -1151,7 +1151,7 @@ bool LiftoffAssembler::emit_i64_popcnt(LiftoffRegister dst,
return true;
}
void LiftoffAssembler::emit_i32_to_intptr(Register dst, Register src) {
void LiftoffAssembler::emit_u32_to_intptr(Register dst, Register src) {
// This is a nop on ia32.
}
......
......@@ -540,7 +540,7 @@ class LiftoffAssembler : public TurboAssembler {
inline void emit_i64_ctz(LiftoffRegister dst, LiftoffRegister src);
inline bool emit_i64_popcnt(LiftoffRegister dst, LiftoffRegister src);
inline void emit_i32_to_intptr(Register dst, Register src);
inline void emit_u32_to_intptr(Register dst, Register src);
inline void emit_ptrsize_add(Register dst, Register lhs, Register rhs) {
if (kSystemPointerSize == 8) {
......
......@@ -1748,7 +1748,7 @@ class LiftoffCompiler {
LiftoffRegister effective_size_reg = end_offset_reg;
__ emit_ptrsize_sub(effective_size_reg.gp(), mem_size, end_offset_reg.gp());
__ emit_i32_to_intptr(index, index);
__ emit_u32_to_intptr(index, index);
__ emit_cond_jump(kUnsignedGreaterEqual, trap_label,
LiftoffAssembler::kWasmIntPtr, index,
......
......@@ -980,7 +980,7 @@ bool LiftoffAssembler::emit_i64_popcnt(LiftoffRegister dst,
return true;
}
void LiftoffAssembler::emit_i32_to_intptr(Register dst, Register src) {
void LiftoffAssembler::emit_u32_to_intptr(Register dst, Register src) {
// This is a nop on mips32.
}
......
......@@ -801,7 +801,7 @@ I64_SHIFTOP_I(shr, dsrl)
#undef I64_SHIFTOP
#undef I64_SHIFTOP_I
void LiftoffAssembler::emit_i32_to_intptr(Register dst, Register src) {
void LiftoffAssembler::emit_u32_to_intptr(Register dst, Register src) {
addu(dst, src, zero_reg);
}
......
......@@ -404,9 +404,9 @@ void LiftoffAssembler::emit_i64_ctz(LiftoffRegister dst, LiftoffRegister src) {
bailout(kUnsupportedArchitecture, "i64_ctz");
}
void LiftoffAssembler::emit_i32_to_intptr(Register dst, Register src) {
void LiftoffAssembler::emit_u32_to_intptr(Register dst, Register src) {
#ifdef V8_TARGET_ARCH_PPC64
bailout(kUnsupportedArchitecture, "emit_i32_to_intptr");
bailout(kUnsupportedArchitecture, "emit_u32_to_intptr");
#else
// This is a nop on ppc32.
#endif
......
......@@ -408,9 +408,9 @@ void LiftoffAssembler::emit_i64_ctz(LiftoffRegister dst, LiftoffRegister src) {
bailout(kUnsupportedArchitecture, "i64_ctz");
}
void LiftoffAssembler::emit_i32_to_intptr(Register dst, Register src) {
void LiftoffAssembler::emit_u32_to_intptr(Register dst, Register src) {
#ifdef V8_TARGET_ARCH_S390X
bailout(kUnsupportedArchitecture, "emit_i32_to_intptr");
bailout(kUnsupportedArchitecture, "emit_u32_to_intptr");
#else
// This is a nop on s390.
#endif
......
......@@ -979,8 +979,8 @@ bool LiftoffAssembler::emit_i64_popcnt(LiftoffRegister dst,
return true;
}
void LiftoffAssembler::emit_i32_to_intptr(Register dst, Register src) {
movsxlq(dst, src);
void LiftoffAssembler::emit_u32_to_intptr(Register dst, Register src) {
movl(dst, src);
}
void LiftoffAssembler::emit_f32_add(DoubleRegister dst, DoubleRegister lhs,
......
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