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:
@@ -1,7 +1,7 @@
|
||||
//! ABI definitions.
|
||||
|
||||
use crate::binemit::Stackmap;
|
||||
use crate::ir::{ArgumentExtension, StackSlot};
|
||||
use crate::ir::StackSlot;
|
||||
use crate::machinst::*;
|
||||
use crate::settings;
|
||||
|
||||
@@ -52,12 +52,7 @@ pub trait ABIBody {
|
||||
fn gen_retval_area_setup(&self) -> Option<Self::I>;
|
||||
|
||||
/// Generate an instruction which copies a source register to a return value slot.
|
||||
fn gen_copy_reg_to_retval(
|
||||
&self,
|
||||
idx: usize,
|
||||
from_reg: Writable<Reg>,
|
||||
ext: ArgumentExtension,
|
||||
) -> Vec<Self::I>;
|
||||
fn gen_copy_reg_to_retval(&self, idx: usize, from_reg: Writable<Reg>) -> Vec<Self::I>;
|
||||
|
||||
/// Generate a return instruction.
|
||||
fn gen_ret(&self) -> Self::I;
|
||||
|
||||
@@ -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> {
|
||||
|
||||
Reference in New Issue
Block a user