Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Mach ports continued + support aarch64-apple unwinding #2723

Merged
merged 6 commits into from
Mar 17, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

9 changes: 9 additions & 0 deletions cranelift/codegen/src/isa/aarch64/abi.rs
Original file line number Diff line number Diff line change
Expand Up @@ -475,6 +475,15 @@ impl ABIMachineSpec for AArch64MachineDeps {

fn gen_prologue_frame_setup(flags: &settings::Flags) -> SmallInstVec<Inst> {
let mut insts = SmallVec::new();

if flags.unwind_info() {
insts.push(Inst::Unwind {
inst: UnwindInst::Aarch64SetPointerAuth {
return_addresses: false,
},
});
}

// stp fp (x29), lr (x30), [sp, #-16]!
insts.push(Inst::StoreP64 {
rt: fp_reg(),
Expand Down
11 changes: 11 additions & 0 deletions cranelift/codegen/src/isa/unwind.rs
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,11 @@ pub mod input {
RememberState,
/// Restores the state.
RestoreState,
/// On aarch64 ARMv8.3+ devices, enables or disables pointer authentication.
Aarch64SetPointerAuth {
/// Whether return addresses (hold in LR) contain a pointer-authentication code.
return_addresses: bool,
},
}

/// Unwind information as generated by a backend.
Expand Down Expand Up @@ -234,4 +239,10 @@ pub enum UnwindInst {
/// The saved register.
reg: RealReg,
},
/// Defines if the aarch64-specific pointer authentication available for ARM v8.3+ devices
/// is enabled for certain pointers or not.
Aarch64SetPointerAuth {
/// Whether return addresses (hold in LR) contain a pointer-authentication code.
return_addresses: bool,
},
}
38 changes: 37 additions & 1 deletion cranelift/codegen/src/isa/unwind/systemv.rs
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,11 @@ pub(crate) enum CallFrameInstruction {
RememberState,
RestoreState,
ArgsSize(u32),
/// Enables or disables pointer authentication on aarch64 platforms post ARMv8.3. This
/// particular item maps to gimli::ValExpression(RA_SIGN_STATE, lit0/lit1).
Aarch64SetPointerAuth {
return_addresses: bool,
},
}

impl From<gimli::write::CallFrameInstruction> for CallFrameInstruction {
Expand Down Expand Up @@ -75,7 +80,7 @@ impl From<gimli::write::CallFrameInstruction> for CallFrameInstruction {

impl Into<gimli::write::CallFrameInstruction> for CallFrameInstruction {
fn into(self) -> gimli::write::CallFrameInstruction {
use gimli::{write::CallFrameInstruction, Register};
use gimli::{write::CallFrameInstruction, write::Expression, Register};

match self {
Self::Cfa(reg, offset) => CallFrameInstruction::Cfa(Register(reg), offset),
Expand All @@ -92,6 +97,21 @@ impl Into<gimli::write::CallFrameInstruction> for CallFrameInstruction {
Self::RememberState => CallFrameInstruction::RememberState,
Self::RestoreState => CallFrameInstruction::RestoreState,
Self::ArgsSize(size) => CallFrameInstruction::ArgsSize(size),
Self::Aarch64SetPointerAuth { return_addresses } => {
// To enable pointer authentication for return addresses in dwarf directives, we
// use a small dwarf expression that sets the value of the pseudo-register
// RA_SIGN_STATE (RA stands for return address) to 0 or 1. This behavior is
// documented in
// https://github.com/ARM-software/abi-aa/blob/master/aadwarf64/aadwarf64.rst#41dwarf-register-names.
let mut expr = Expression::new();
expr.op(if return_addresses {
gimli::DW_OP_lit1
} else {
gimli::DW_OP_lit0
});
const RA_SIGN_STATE: Register = Register(34);
CallFrameInstruction::ValExpression(RA_SIGN_STATE, expr)
}
}
}
}
Expand Down Expand Up @@ -187,6 +207,12 @@ pub(crate) fn create_unwind_info_from_insts<MR: RegisterMapper<regalloc::Reg>>(
let off = (clobber_offset as i32) - (clobber_offset_to_cfa as i32);
instructions.push((instruction_offset, CallFrameInstruction::Offset(reg, off)));
}
&UnwindInst::Aarch64SetPointerAuth { return_addresses } => {
instructions.push((
instruction_offset,
CallFrameInstruction::Aarch64SetPointerAuth { return_addresses },
));
}
}
}

Expand Down Expand Up @@ -245,6 +271,9 @@ impl UnwindInfo {
UnwindCode::RestoreState => {
builder.restore_state(*offset);
}
UnwindCode::Aarch64SetPointerAuth { return_addresses } => {
builder.set_aarch64_pauth(*offset, *return_addresses);
}
}
}

Expand Down Expand Up @@ -399,4 +428,11 @@ impl<'a, Reg: PartialEq + Copy> InstructionBuilder<'a, Reg> {
self.instructions
.push((offset, CallFrameInstruction::RestoreState));
}

fn set_aarch64_pauth(&mut self, offset: u32, return_addresses: bool) {
self.instructions.push((
offset,
CallFrameInstruction::Aarch64SetPointerAuth { return_addresses },
));
}
}
3 changes: 3 additions & 0 deletions cranelift/codegen/src/isa/unwind/winx64.rs
Original file line number Diff line number Diff line change
Expand Up @@ -379,6 +379,9 @@ pub(crate) fn create_unwind_info_from_insts<MR: RegisterMapper<regalloc::Reg>>(
});
}
},
&UnwindInst::Aarch64SetPointerAuth { .. } => {
unreachable!("no aarch64 on x64");
}
}
max_unwind_offset = instruction_offset;
}
Expand Down
6 changes: 3 additions & 3 deletions crates/fiber/src/arch/aarch64.S
Original file line number Diff line number Diff line change
Expand Up @@ -107,9 +107,9 @@ FUNCTION(wasmtime_fiber_start):
// ... and then we call the function! Note that this is a function call so
// our frame stays on the stack to backtrace through.
blr x20
// .. technically we shouldn't get here, and I would like to write in an
// instruction which just aborts, but I don't know such an instruction in
// aarch64 land.
// Unreachable, here for safety. This should help catch unexpected behaviors.
// Use a noticeable payload so one can grep for it in the codebase.
brk 0xf1b3
.cfi_endproc
SIZE(wasmtime_fiber_start)

Expand Down
3 changes: 3 additions & 0 deletions crates/runtime/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,9 @@ psm = "0.1.11"
rand = "0.7.3"
anyhow = "1.0.38"

[target.'cfg(target_os = "macos")'.dependencies]
mach = "0.3.2"

[target.'cfg(target_os = "windows")'.dependencies]
winapi = { version = "0.3.7", features = ["winbase", "memoryapi", "errhandlingapi"] }

Expand Down
Loading