зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1437510 - ARM: Zero the payload if the Value tag does not match the expected tag. r=jandem
This commit is contained in:
Родитель
1c77b34e03
Коммит
35a6c3e5b3
|
@ -1430,6 +1430,8 @@ CodeGenerator::visitUnbox(LUnbox* unbox)
|
||||||
// inputs.
|
// inputs.
|
||||||
MUnbox* mir = unbox->mir();
|
MUnbox* mir = unbox->mir();
|
||||||
Register type = ToRegister(unbox->type());
|
Register type = ToRegister(unbox->type());
|
||||||
|
Register payload = ToRegister(unbox->payload());
|
||||||
|
Register output = ToRegister(unbox->output());
|
||||||
|
|
||||||
mozilla::Maybe<ScratchRegisterScope> scratch;
|
mozilla::Maybe<ScratchRegisterScope> scratch;
|
||||||
scratch.emplace(masm);
|
scratch.emplace(masm);
|
||||||
|
@ -1448,6 +1450,11 @@ CodeGenerator::visitUnbox(LUnbox* unbox)
|
||||||
masm.bind(&ok);
|
masm.bind(&ok);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Note: If spectreValueMasking is disabled, then this instruction will
|
||||||
|
// default to a no-op as long as the lowering allocate the same register for
|
||||||
|
// the output and the payload.
|
||||||
|
masm.unboxNonDouble(ValueOperand(type, payload), output, ValueTypeFromMIRType(mir->type()));
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
|
@ -3000,26 +3000,62 @@ MacroAssemblerARMCompat::testGCThing(Condition cond, const BaseIndex& address)
|
||||||
|
|
||||||
// Unboxing code.
|
// Unboxing code.
|
||||||
void
|
void
|
||||||
MacroAssemblerARMCompat::unboxNonDouble(const ValueOperand& operand, Register dest, JSValueType)
|
MacroAssemblerARMCompat::unboxNonDouble(const ValueOperand& operand, Register dest, JSValueType type)
|
||||||
{
|
{
|
||||||
if (operand.payloadReg() != dest)
|
auto movPayloadToDest = [&]() {
|
||||||
ma_mov(operand.payloadReg(), dest);
|
if (operand.payloadReg() != dest)
|
||||||
|
ma_mov(operand.payloadReg(), dest, LeaveCC);
|
||||||
|
};
|
||||||
|
if (!JitOptions.spectreValueMasking) {
|
||||||
|
movPayloadToDest();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Spectre mitigation: We zero the payload if the tag does not match the
|
||||||
|
// expected type and if this is a pointer type.
|
||||||
|
if (type == JSVAL_TYPE_INT32 || type == JSVAL_TYPE_BOOLEAN) {
|
||||||
|
movPayloadToDest();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// We zero the destination register and move the payload into it if
|
||||||
|
// the tag corresponds to the given type.
|
||||||
|
ma_cmp(operand.typeReg(), ImmType(type));
|
||||||
|
movPayloadToDest();
|
||||||
|
ma_mov(Imm32(0), dest, NotEqual);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
MacroAssemblerARMCompat::unboxNonDouble(const Address& src, Register dest, JSValueType)
|
MacroAssemblerARMCompat::unboxNonDouble(const Address& src, Register dest, JSValueType type)
|
||||||
{
|
{
|
||||||
ScratchRegisterScope scratch(asMasm());
|
ScratchRegisterScope scratch(asMasm());
|
||||||
ma_ldr(ToPayload(src), dest, scratch);
|
if (!JitOptions.spectreValueMasking) {
|
||||||
|
ma_ldr(ToPayload(src), dest, scratch);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Spectre mitigation: We zero the payload if the tag does not match the
|
||||||
|
// expected type and if this is a pointer type.
|
||||||
|
if (type == JSVAL_TYPE_INT32 || type == JSVAL_TYPE_BOOLEAN) {
|
||||||
|
ma_ldr(ToPayload(src), dest, scratch);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// We zero the destination register and move the payload into it if
|
||||||
|
// the tag corresponds to the given type.
|
||||||
|
ma_ldr(ToType(src), scratch, scratch);
|
||||||
|
ma_cmp(scratch, ImmType(type));
|
||||||
|
ma_ldr(ToPayload(src), dest, scratch, Offset, Equal);
|
||||||
|
ma_mov(Imm32(0), dest, NotEqual);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
MacroAssemblerARMCompat::unboxNonDouble(const BaseIndex& src, Register dest, JSValueType)
|
MacroAssemblerARMCompat::unboxNonDouble(const BaseIndex& src, Register dest, JSValueType type)
|
||||||
{
|
{
|
||||||
ScratchRegisterScope scratch(asMasm());
|
|
||||||
SecondScratchRegisterScope scratch2(asMasm());
|
SecondScratchRegisterScope scratch2(asMasm());
|
||||||
ma_alu(src.base, lsl(src.index, src.scale), scratch, OpAdd);
|
ma_alu(src.base, lsl(src.index, src.scale), scratch2, OpAdd);
|
||||||
ma_ldr(Address(scratch, src.offset), dest, scratch2);
|
Address value(scratch2, src.offset);
|
||||||
|
unboxNonDouble(value, dest, type);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -3048,8 +3084,8 @@ MacroAssemblerARMCompat::unboxValue(const ValueOperand& src, AnyRegister dest, J
|
||||||
bind(¬Int32);
|
bind(¬Int32);
|
||||||
unboxDouble(src, dest.fpu());
|
unboxDouble(src, dest.fpu());
|
||||||
bind(&end);
|
bind(&end);
|
||||||
} else if (src.payloadReg() != dest.gpr()) {
|
} else {
|
||||||
as_mov(dest.gpr(), O2Reg(src.payloadReg()));
|
unboxNonDouble(src, dest.gpr(), type);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -829,12 +829,15 @@ class MacroAssemblerARMCompat : public MacroAssemblerARM
|
||||||
// and returns that.
|
// and returns that.
|
||||||
Register extractObject(const Address& address, Register scratch);
|
Register extractObject(const Address& address, Register scratch);
|
||||||
Register extractObject(const ValueOperand& value, Register scratch) {
|
Register extractObject(const ValueOperand& value, Register scratch) {
|
||||||
|
unboxNonDouble(value, value.payloadReg(), JSVAL_TYPE_OBJECT);
|
||||||
return value.payloadReg();
|
return value.payloadReg();
|
||||||
}
|
}
|
||||||
Register extractString(const ValueOperand& value, Register scratch) {
|
Register extractString(const ValueOperand& value, Register scratch) {
|
||||||
|
unboxNonDouble(value, value.payloadReg(), JSVAL_TYPE_STRING);
|
||||||
return value.payloadReg();
|
return value.payloadReg();
|
||||||
}
|
}
|
||||||
Register extractSymbol(const ValueOperand& value, Register scratch) {
|
Register extractSymbol(const ValueOperand& value, Register scratch) {
|
||||||
|
unboxNonDouble(value, value.payloadReg(), JSVAL_TYPE_SYMBOL);
|
||||||
return value.payloadReg();
|
return value.payloadReg();
|
||||||
}
|
}
|
||||||
Register extractInt32(const ValueOperand& value, Register scratch) {
|
Register extractInt32(const ValueOperand& value, Register scratch) {
|
||||||
|
|
Загрузка…
Ссылка в новой задаче