Aarch64: fix narrow integer-register extension with Baldrdash ABI.

In the Baldrdash (SpiderMonkey) embedding, we must take care to
zero-extend all function arguments to callees in integer registers when
the types are narrower than 64 bits. This is because, unlike the native
SysV ABI, the Baldrdash ABI expects high bits to be cleared. Not doing
so leads to difficult-to-trace errors where high bits falsely tag an
int32 as e.g. an object pointer, leading to potential security issues.
This commit is contained in:
Chris Fallin
2020-07-29 14:28:07 -07:00
parent 8fd92093a4
commit 1fbdf169b5
5 changed files with 258 additions and 71 deletions

View File

@@ -8,9 +8,8 @@ use crate::inst_predicates::{has_side_effect_or_load, is_constant_64bit};
use crate::ir::instructions::BranchInfo;
use crate::ir::types::I64;
use crate::ir::{
ArgumentExtension, ArgumentPurpose, Block, Constant, ConstantData, ExternalName, Function,
GlobalValueData, Inst, InstructionData, MemFlags, Opcode, Signature, SourceLoc, Type, Value,
ValueDef,
ArgumentPurpose, Block, Constant, ConstantData, ExternalName, Function, GlobalValueData, Inst,
InstructionData, MemFlags, Opcode, Signature, SourceLoc, Type, Value, ValueDef,
};
use crate::machinst::{
ABIBody, BlockIndex, BlockLoweringOrder, LoweredBlock, MachLabel, VCode, VCodeBuilder,
@@ -232,7 +231,7 @@ pub struct Lower<'func, I: VCodeInst> {
value_regs: SecondaryMap<Value, Reg>,
/// Return-value vregs.
retval_regs: Vec<(Reg, ArgumentExtension)>,
retval_regs: Vec<Reg>,
/// Instruction colors.
inst_colors: SecondaryMap<Inst, InstColor>,
@@ -354,7 +353,7 @@ impl<'func, I: VCodeInst> Lower<'func, I> {
next_vreg += 1;
let regclass = I::rc_for_type(ret.value_type)?;
let vreg = Reg::new_virtual(regclass, v);
retval_regs.push((vreg, ret.extension));
retval_regs.push(vreg);
vcode.set_vreg_type(vreg.as_virtual_reg().unwrap(), ret.value_type);
}
@@ -427,9 +426,9 @@ impl<'func, I: VCodeInst> Lower<'func, I> {
fn gen_retval_setup(&mut self, gen_ret_inst: GenerateReturn) {
let retval_regs = self.retval_regs.clone();
for (i, (reg, ext)) in retval_regs.into_iter().enumerate() {
for (i, reg) in retval_regs.into_iter().enumerate() {
let reg = Writable::from_reg(reg);
let insns = self.vcode.abi().gen_copy_reg_to_retval(i, reg, ext);
let insns = self.vcode.abi().gen_copy_reg_to_retval(i, reg);
for insn in insns {
self.emit(insn);
}
@@ -844,7 +843,7 @@ impl<'func, I: VCodeInst> LowerCtx for Lower<'func, I> {
}
fn retval(&self, idx: usize) -> Writable<Reg> {
Writable::from_reg(self.retval_regs[idx].0)
Writable::from_reg(self.retval_regs[idx])
}
fn get_vm_context(&self) -> Option<Reg> {