From fa1628f76785e18240c7c7aca63b99d490879461 Mon Sep 17 00:00:00 2001 From: Jiaxun Yang Date: Tue, 12 May 2020 12:40:05 +0800 Subject: Bug 1323136 - wasm: MIPS: Do bounds check in 32-bit Tag: #1542 --- js/src/jit/mips-shared/Assembler-mips-shared.cpp | 9 +++++++ js/src/jit/mips-shared/Assembler-mips-shared.h | 2 ++ .../jit/mips-shared/MacroAssembler-mips-shared.cpp | 11 +++++++++ .../jit/mips-shared/MacroAssembler-mips-shared.h | 7 ++++++ js/src/jit/mips32/Assembler-mips32.cpp | 28 +++++++--------------- js/src/jit/mips32/Assembler-mips32.h | 1 - js/src/jit/mips32/MacroAssembler-mips32-inl.h | 2 +- js/src/jit/mips32/MacroAssembler-mips32.cpp | 11 --------- js/src/jit/mips32/MacroAssembler-mips32.h | 7 ------ js/src/jit/mips64/MacroAssembler-mips64-inl.h | 6 ++++- js/src/jit/mips64/MacroAssembler-mips64.h | 6 ----- 11 files changed, 44 insertions(+), 46 deletions(-) diff --git a/js/src/jit/mips-shared/Assembler-mips-shared.cpp b/js/src/jit/mips-shared/Assembler-mips-shared.cpp index f813eb946..58af49dda 100644 --- a/js/src/jit/mips-shared/Assembler-mips-shared.cpp +++ b/js/src/jit/mips-shared/Assembler-mips-shared.cpp @@ -1744,3 +1744,12 @@ AssemblerMIPSShared::ToggleToCmp(CodeLocationLabel inst_) AutoFlushICache::flush(uintptr_t(inst), 4); } +void +AssemblerMIPSShared::UpdateLuiOriValue(Instruction* inst0, Instruction* inst1, uint32_t value) +{ + MOZ_ASSERT(inst0->extractOpcode() == ((uint32_t)op_lui >> OpcodeShift)); + MOZ_ASSERT(inst1->extractOpcode() == ((uint32_t)op_ori >> OpcodeShift)); + + ((InstImm*) inst0)->setImm16(Imm16::Upper(Imm32(value))); + ((InstImm*) inst1)->setImm16(Imm16::Lower(Imm32(value))); +} diff --git a/js/src/jit/mips-shared/Assembler-mips-shared.h b/js/src/jit/mips-shared/Assembler-mips-shared.h index a619fa0e0..fbf1fefdd 100644 --- a/js/src/jit/mips-shared/Assembler-mips-shared.h +++ b/js/src/jit/mips-shared/Assembler-mips-shared.h @@ -1273,6 +1273,8 @@ class AssemblerMIPSShared : public AssemblerShared static void ToggleToJmp(CodeLocationLabel inst_); static void ToggleToCmp(CodeLocationLabel inst_); + static void UpdateLuiOriValue(Instruction* inst0, Instruction* inst1, uint32_t value); + void processCodeLabels(uint8_t* rawCode); bool bailed() { diff --git a/js/src/jit/mips-shared/MacroAssembler-mips-shared.cpp b/js/src/jit/mips-shared/MacroAssembler-mips-shared.cpp index 18997e542..658cafd36 100644 --- a/js/src/jit/mips-shared/MacroAssembler-mips-shared.cpp +++ b/js/src/jit/mips-shared/MacroAssembler-mips-shared.cpp @@ -39,6 +39,17 @@ MacroAssemblerMIPSShared::ma_li(Register dest, Imm32 imm) } } +// This method generates lui and ori instruction pair that can be modified by +// UpdateLuiOriValue, either during compilation (eg. Assembler::bind), or +// during execution (eg. jit::PatchJump). +void +MacroAssemblerMIPSShared::ma_liPatchable(Register dest, Imm32 imm) +{ + m_buffer.ensureSpace(2 * sizeof(uint32_t)); + as_lui(dest, Imm16::Upper(imm).encode()); + as_ori(dest, dest, Imm16::Lower(imm).encode()); +} + // Shifts void MacroAssemblerMIPSShared::ma_sll(Register rd, Register rt, Imm32 shift) diff --git a/js/src/jit/mips-shared/MacroAssembler-mips-shared.h b/js/src/jit/mips-shared/MacroAssembler-mips-shared.h index c9bd4a4d9..aea389d8a 100644 --- a/js/src/jit/mips-shared/MacroAssembler-mips-shared.h +++ b/js/src/jit/mips-shared/MacroAssembler-mips-shared.h @@ -65,6 +65,7 @@ class MacroAssemblerMIPSShared : public Assembler void ma_li(Register dest, ImmGCPtr ptr); void ma_li(Register dest, Imm32 imm); + void ma_liPatchable(Register dest, Imm32 imm); // Shift operations void ma_sll(Register rd, Register rt, Imm32 shift); @@ -184,6 +185,12 @@ class MacroAssemblerMIPSShared : public Assembler void ma_cmp_set_double(Register dst, FloatRegister lhs, FloatRegister rhs, DoubleCondition c); void ma_cmp_set_float32(Register dst, FloatRegister lhs, FloatRegister rhs, DoubleCondition c); + BufferOffset ma_BoundsCheck(Register bounded) { + BufferOffset bo = m_buffer.nextOffset(); + ma_liPatchable(bounded, Imm32(0)); + return bo; + } + void moveToDoubleLo(Register src, FloatRegister dest) { as_mtc1(src, dest); } diff --git a/js/src/jit/mips32/Assembler-mips32.cpp b/js/src/jit/mips32/Assembler-mips32.cpp index 6283c1d5a..1b86e9d32 100644 --- a/js/src/jit/mips32/Assembler-mips32.cpp +++ b/js/src/jit/mips32/Assembler-mips32.cpp @@ -124,7 +124,7 @@ jit::PatchJump(CodeLocationJump& jump_, CodeLocationLabel label, ReprotectCode r Instruction* inst2 = inst1->next(); MaybeAutoWritableJitCode awjc(inst1, 8, reprotect); - Assembler::UpdateLuiOriValue(inst1, inst2, (uint32_t)label.raw()); + AssemblerMIPSShared::UpdateLuiOriValue(inst1, inst2, (uint32_t)label.raw()); AutoFlushICache::flush(uintptr_t(inst1), 8); } @@ -146,12 +146,12 @@ jit::PatchBackedge(CodeLocationJump& jump, CodeLocationLabel label, } else { if (target == JitRuntime::BackedgeLoopHeader) { Instruction* lui = &branch[1]; - Assembler::UpdateLuiOriValue(lui, lui->next(), targetAddr); + AssemblerMIPSShared::UpdateLuiOriValue(lui, lui->next(), targetAddr); // Jump to ori. The lui will be executed in delay slot. branch->setBOffImm16(BOffImm16(2 * sizeof(uint32_t))); } else { Instruction* lui = &branch[4]; - Assembler::UpdateLuiOriValue(lui, lui->next(), targetAddr); + AssemblerMIPSShared::UpdateLuiOriValue(lui, lui->next(), targetAddr); branch->setBOffImm16(BOffImm16(4 * sizeof(uint32_t))); } } @@ -168,7 +168,7 @@ Assembler::executableCopy(uint8_t* buffer) Instruction* inst1 = (Instruction*) ((uint32_t)buffer + longJumps_[i]); uint32_t value = Assembler::ExtractLuiOriValue(inst1, inst1->next()); - Assembler::UpdateLuiOriValue(inst1, inst1->next(), (uint32_t)buffer + value); + AssemblerMIPSShared::UpdateLuiOriValue(inst1, inst1->next(), (uint32_t)buffer + value); } AutoFlushICache::setRange(uintptr_t(buffer), m_buffer.size()); @@ -207,7 +207,7 @@ TraceOneDataRelocation(JSTracer* trc, Instruction* inst) TraceManuallyBarrieredGenericPointerEdge(trc, reinterpret_cast(&ptr), "ion-masm-ptr"); if (ptr != prior) { - Assembler::UpdateLuiOriValue(inst, inst->next(), uint32_t(ptr)); + AssemblerMIPSShared::UpdateLuiOriValue(inst, inst->next(), uint32_t(ptr)); AutoFlushICache::flush(uintptr_t(inst), 8); } } @@ -306,7 +306,7 @@ Assembler::Bind(uint8_t* rawCode, CodeOffset* label, const void* address) if (label->bound()) { intptr_t offset = label->offset(); Instruction* inst = (Instruction*) (rawCode + offset); - Assembler::UpdateLuiOriValue(inst, inst->next(), (uint32_t)address); + AssemblerMIPSShared::UpdateLuiOriValue(inst, inst->next(), (uint32_t)address); } } @@ -385,7 +385,7 @@ Assembler::bind(RepatchLabel* label) // For unconditional long branches generated by ma_liPatchable, // such as under: // jumpWithpatch - Assembler::UpdateLuiOriValue(inst, inst->next(), dest.getOffset()); + AssemblerMIPSShared::UpdateLuiOriValue(inst, inst->next(), dest.getOffset()); } else if (inst[1].extractOpcode() == (uint32_t(op_lui) >> OpcodeShift) || BOffImm16::IsInRange(offset)) { @@ -466,16 +466,6 @@ Assembler::ExtractLuiOriValue(Instruction* inst0, Instruction* inst1) return value; } -void -Assembler::UpdateLuiOriValue(Instruction* inst0, Instruction* inst1, uint32_t value) -{ - MOZ_ASSERT(inst0->extractOpcode() == ((uint32_t)op_lui >> OpcodeShift)); - MOZ_ASSERT(inst1->extractOpcode() == ((uint32_t)op_ori >> OpcodeShift)); - - ((InstImm*) inst0)->setImm16(Imm16::Upper(Imm32(value))); - ((InstImm*) inst1)->setImm16(Imm16::Lower(Imm32(value))); -} - void Assembler::WriteLuiOriInstructions(Instruction* inst0, Instruction* inst1, Register reg, uint32_t value) @@ -503,7 +493,7 @@ Assembler::PatchDataWithValueCheck(CodeLocationLabel label, PatchedImmPtr newVal MOZ_ASSERT(value == uint32_t(expectedValue.value)); // Replace with new value - Assembler::UpdateLuiOriValue(inst, inst->next(), uint32_t(newValue.value)); + AssemblerMIPSShared::UpdateLuiOriValue(inst, inst->next(), uint32_t(newValue.value)); AutoFlushICache::flush(uintptr_t(inst), 8); } @@ -512,7 +502,7 @@ void Assembler::PatchInstructionImmediate(uint8_t* code, PatchedImmPtr imm) { InstImm* inst = (InstImm*)code; - Assembler::UpdateLuiOriValue(inst, inst->next(), (uint32_t)imm.value); + AssemblerMIPSShared::UpdateLuiOriValue(inst, inst->next(), (uint32_t)imm.value); } uint32_t diff --git a/js/src/jit/mips32/Assembler-mips32.h b/js/src/jit/mips32/Assembler-mips32.h index 9fdbcda98..cf7f0d228 100644 --- a/js/src/jit/mips32/Assembler-mips32.h +++ b/js/src/jit/mips32/Assembler-mips32.h @@ -161,7 +161,6 @@ class Assembler : public AssemblerMIPSShared static uint32_t PatchWrite_NearCallSize(); static uint32_t ExtractLuiOriValue(Instruction* inst0, Instruction* inst1); - static void UpdateLuiOriValue(Instruction* inst0, Instruction* inst1, uint32_t value); static void WriteLuiOriInstructions(Instruction* inst, Instruction* inst1, Register reg, uint32_t value); diff --git a/js/src/jit/mips32/MacroAssembler-mips32-inl.h b/js/src/jit/mips32/MacroAssembler-mips32-inl.h index 2dae8fb87..4331e050e 100644 --- a/js/src/jit/mips32/MacroAssembler-mips32-inl.h +++ b/js/src/jit/mips32/MacroAssembler-mips32-inl.h @@ -1042,7 +1042,7 @@ MacroAssembler::wasmPatchBoundsCheck(uint8_t* patchAt, uint32_t limit) InstImm* i1 = (InstImm*) i0->next(); // Replace with new value - Assembler::UpdateLuiOriValue(i0, i1, limit); + AssemblerMIPSShared::UpdateLuiOriValue(i0, i1, limit); } //}}} check_macroassembler_style diff --git a/js/src/jit/mips32/MacroAssembler-mips32.cpp b/js/src/jit/mips32/MacroAssembler-mips32.cpp index 2b2fab92d..d3d3a75d1 100644 --- a/js/src/jit/mips32/MacroAssembler-mips32.cpp +++ b/js/src/jit/mips32/MacroAssembler-mips32.cpp @@ -202,17 +202,6 @@ MacroAssemblerMIPS::ma_li(Register dest, ImmWord imm) ma_li(dest, Imm32(uint32_t(imm.value))); } -// This method generates lui and ori instruction pair that can be modified by -// UpdateLuiOriValue, either during compilation (eg. Assembler::bind), or -// during execution (eg. jit::PatchJump). -void -MacroAssemblerMIPS::ma_liPatchable(Register dest, Imm32 imm) -{ - m_buffer.ensureSpace(2 * sizeof(uint32_t)); - as_lui(dest, Imm16::Upper(imm).encode()); - as_ori(dest, dest, Imm16::Lower(imm).encode()); -} - void MacroAssemblerMIPS::ma_liPatchable(Register dest, ImmPtr imm) { diff --git a/js/src/jit/mips32/MacroAssembler-mips32.h b/js/src/jit/mips32/MacroAssembler-mips32.h index adb626bb0..9b846e25d 100644 --- a/js/src/jit/mips32/MacroAssembler-mips32.h +++ b/js/src/jit/mips32/MacroAssembler-mips32.h @@ -55,7 +55,6 @@ class MacroAssemblerMIPS : public MacroAssemblerMIPSShared void ma_li(Register dest, CodeOffset* label); - void ma_liPatchable(Register dest, Imm32 imm); void ma_li(Register dest, ImmWord imm); void ma_liPatchable(Register dest, ImmPtr imm); void ma_liPatchable(Register dest, ImmWord imm); @@ -990,12 +989,6 @@ class MacroAssemblerMIPSCompat : public MacroAssemblerMIPS ma_sw(imm, addr); } - BufferOffset ma_BoundsCheck(Register bounded) { - BufferOffset bo = m_buffer.nextOffset(); - ma_liPatchable(bounded, ImmWord(0)); - return bo; - } - void moveFloat32(FloatRegister src, FloatRegister dest) { as_movs(dest, src); } diff --git a/js/src/jit/mips64/MacroAssembler-mips64-inl.h b/js/src/jit/mips64/MacroAssembler-mips64-inl.h index f5737748b..a07619b94 100644 --- a/js/src/jit/mips64/MacroAssembler-mips64-inl.h +++ b/js/src/jit/mips64/MacroAssembler-mips64-inl.h @@ -706,8 +706,12 @@ MacroAssembler::wasmBoundsCheck(Condition cond, Register index, L label) void MacroAssembler::wasmPatchBoundsCheck(uint8_t* patchAt, uint32_t limit) { + Instruction* inst = (Instruction*) patchAt; + InstImm* i0 = (InstImm*) inst; + InstImm* i1 = (InstImm*) i0->next(); + // Replace with new value - Assembler::UpdateLoad64Value((Instruction*) patchAt, limit); + AssemblerMIPSShared::UpdateLuiOriValue(i0, i1, limit); } //}}} check_macroassembler_style diff --git a/js/src/jit/mips64/MacroAssembler-mips64.h b/js/src/jit/mips64/MacroAssembler-mips64.h index bfe452974..6b98f1f2c 100644 --- a/js/src/jit/mips64/MacroAssembler-mips64.h +++ b/js/src/jit/mips64/MacroAssembler-mips64.h @@ -1009,12 +1009,6 @@ class MacroAssemblerMIPS64Compat : public MacroAssemblerMIPS64 as_nop(); } - BufferOffset ma_BoundsCheck(Register bounded) { - BufferOffset bo = m_buffer.nextOffset(); - ma_liPatchable(bounded, ImmWord(0)); - return bo; - } - void moveFloat32(FloatRegister src, FloatRegister dest) { as_movs(dest, src); } -- cgit v1.2.3