Enable back-edge CFI by default on macOS (#4720)
Also, adjust the tests that are executed on that platform. Finally, fix a bug with obtaining backtraces when back-edge CFI is enabled. Copyright (c) 2022, Arm Limited.
This commit is contained in:
@@ -780,6 +780,11 @@
|
|||||||
(Pacisp
|
(Pacisp
|
||||||
(key APIKey))
|
(key APIKey))
|
||||||
|
|
||||||
|
;; Strip pointer authentication code from instruction address in LR;
|
||||||
|
;; equivalent to a no-op if Pointer authentication (FEAT_PAuth) is not
|
||||||
|
;; supported.
|
||||||
|
(Xpaclri)
|
||||||
|
|
||||||
;; Marker, no-op in generated code: SP "virtual offset" is adjusted. This
|
;; Marker, no-op in generated code: SP "virtual offset" is adjusted. This
|
||||||
;; controls how AMode::NominalSPOffset args are lowered.
|
;; controls how AMode::NominalSPOffset args are lowered.
|
||||||
(VirtualSPOffsetAdj
|
(VirtualSPOffsetAdj
|
||||||
@@ -1356,6 +1361,9 @@
|
|||||||
))
|
))
|
||||||
|
|
||||||
;; Extractors for target features ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
;; Extractors for target features ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||||
|
(decl pure sign_return_address_disabled () Unit)
|
||||||
|
(extern constructor sign_return_address_disabled sign_return_address_disabled)
|
||||||
|
|
||||||
(decl use_lse () Inst)
|
(decl use_lse () Inst)
|
||||||
(extern extractor use_lse use_lse)
|
(extern extractor use_lse use_lse)
|
||||||
|
|
||||||
@@ -2577,4 +2585,11 @@
|
|||||||
|
|
||||||
(decl aarch64_link () Reg)
|
(decl aarch64_link () Reg)
|
||||||
(rule (aarch64_link)
|
(rule (aarch64_link)
|
||||||
|
(if (sign_return_address_disabled))
|
||||||
(mov_preg (preg_link)))
|
(mov_preg (preg_link)))
|
||||||
|
|
||||||
|
(rule (aarch64_link)
|
||||||
|
;; This constructor is always used for non-leaf functions, so it is safe
|
||||||
|
;; to clobber LR.
|
||||||
|
(let ((_ Unit (emit (MInst.Xpaclri))))
|
||||||
|
(mov_preg (preg_link))))
|
||||||
|
|||||||
@@ -3121,6 +3121,7 @@ impl MachInstEmit for Inst {
|
|||||||
|
|
||||||
sink.put4(0xd503233f | key << 6);
|
sink.put4(0xd503233f | key << 6);
|
||||||
}
|
}
|
||||||
|
&Inst::Xpaclri => sink.put4(0xd50320ff),
|
||||||
&Inst::VirtualSPOffsetAdj { offset } => {
|
&Inst::VirtualSPOffsetAdj { offset } => {
|
||||||
trace!(
|
trace!(
|
||||||
"virtual sp offset adjusted by {} -> {}",
|
"virtual sp offset adjusted by {} -> {}",
|
||||||
|
|||||||
@@ -57,6 +57,7 @@ fn test_aarch64_binemit() {
|
|||||||
"retab",
|
"retab",
|
||||||
));
|
));
|
||||||
insns.push((Inst::Pacisp { key: APIKey::B }, "7F2303D5", "pacibsp"));
|
insns.push((Inst::Pacisp { key: APIKey::B }, "7F2303D5", "pacibsp"));
|
||||||
|
insns.push((Inst::Xpaclri, "FF2003D5", "xpaclri"));
|
||||||
insns.push((Inst::Nop0, "", "nop-zero-len"));
|
insns.push((Inst::Nop0, "", "nop-zero-len"));
|
||||||
insns.push((Inst::Nop4, "1F2003D5", "nop"));
|
insns.push((Inst::Nop4, "1F2003D5", "nop"));
|
||||||
insns.push((Inst::Csdb, "9F2203D5", "csdb"));
|
insns.push((Inst::Csdb, "9F2203D5", "csdb"));
|
||||||
|
|||||||
@@ -981,12 +981,7 @@ fn aarch64_get_operands<F: Fn(VReg) -> VReg>(inst: &Inst, collector: &mut Operan
|
|||||||
collector.reg_def(rd);
|
collector.reg_def(rd);
|
||||||
collector.reg_use(rn);
|
collector.reg_use(rn);
|
||||||
}
|
}
|
||||||
&Inst::Ret { ref rets } => {
|
&Inst::Ret { ref rets } | &Inst::AuthenticatedRet { ref rets, .. } => {
|
||||||
for &ret in rets {
|
|
||||||
collector.reg_use(ret);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
&Inst::AuthenticatedRet { ref rets, .. } => {
|
|
||||||
for &ret in rets {
|
for &ret in rets {
|
||||||
collector.reg_use(ret);
|
collector.reg_use(ret);
|
||||||
}
|
}
|
||||||
@@ -1039,7 +1034,10 @@ fn aarch64_get_operands<F: Fn(VReg) -> VReg>(inst: &Inst, collector: &mut Operan
|
|||||||
collector.reg_def(rd);
|
collector.reg_def(rd);
|
||||||
memarg_operands(mem, collector);
|
memarg_operands(mem, collector);
|
||||||
}
|
}
|
||||||
&Inst::Pacisp { .. } => {}
|
&Inst::Pacisp { .. } | &Inst::Xpaclri => {
|
||||||
|
// Neither LR nor SP is an allocatable register, so there is no need
|
||||||
|
// to do anything.
|
||||||
|
}
|
||||||
&Inst::VirtualSPOffsetAdj { .. } => {}
|
&Inst::VirtualSPOffsetAdj { .. } => {}
|
||||||
|
|
||||||
&Inst::ElfTlsGetAddr { .. } => {
|
&Inst::ElfTlsGetAddr { .. } => {
|
||||||
@@ -2715,6 +2713,7 @@ impl Inst {
|
|||||||
|
|
||||||
"paci".to_string() + key + "sp"
|
"paci".to_string() + key + "sp"
|
||||||
}
|
}
|
||||||
|
&Inst::Xpaclri => "xpaclri".to_string(),
|
||||||
&Inst::VirtualSPOffsetAdj { offset } => {
|
&Inst::VirtualSPOffsetAdj { offset } => {
|
||||||
state.virtual_sp_offset += offset;
|
state.virtual_sp_offset += offset;
|
||||||
format!("virtual_sp_offset_adjust {}", offset)
|
format!("virtual_sp_offset_adjust {}", offset)
|
||||||
|
|||||||
@@ -71,6 +71,14 @@ pub struct SinkableAtomicLoad {
|
|||||||
impl generated_code::Context for IsleContext<'_, '_, MInst, Flags, IsaFlags, 6> {
|
impl generated_code::Context for IsleContext<'_, '_, MInst, Flags, IsaFlags, 6> {
|
||||||
isle_prelude_methods!();
|
isle_prelude_methods!();
|
||||||
|
|
||||||
|
fn sign_return_address_disabled(&mut self) -> Option<()> {
|
||||||
|
if self.isa_flags.sign_return_address() {
|
||||||
|
None
|
||||||
|
} else {
|
||||||
|
Some(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn use_lse(&mut self, _: Inst) -> Option<()> {
|
fn use_lse(&mut self, _: Inst) -> Option<()> {
|
||||||
if self.isa_flags.use_lse() {
|
if self.isa_flags.use_lse() {
|
||||||
Some(())
|
Some(())
|
||||||
|
|||||||
@@ -138,6 +138,9 @@ pub fn builder_with_options(infer_native_flags: bool) -> Result<isa::Builder, &'
|
|||||||
}
|
}
|
||||||
|
|
||||||
if cfg!(target_os = "macos") {
|
if cfg!(target_os = "macos") {
|
||||||
|
// Pointer authentication is always available on Apple Silicon.
|
||||||
|
isa_builder.enable("sign_return_address").unwrap();
|
||||||
|
// macOS enforces the use of the B key for return addresses.
|
||||||
isa_builder.enable("sign_return_address_with_bkey").unwrap();
|
isa_builder.enable("sign_return_address_with_bkey").unwrap();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -234,6 +234,8 @@ mod tests {
|
|||||||
.any(|s| s.contains("look_for_me"))
|
.any(|s| s.contains("look_for_me"))
|
||||||
// TODO: apparently windows unwind routines don't unwind through fibers, so this will always fail. Is there a way we can fix that?
|
// TODO: apparently windows unwind routines don't unwind through fibers, so this will always fail. Is there a way we can fix that?
|
||||||
|| cfg!(windows)
|
|| cfg!(windows)
|
||||||
|
// TODO: the system libunwind is broken (#2808)
|
||||||
|
|| cfg!(all(target_os = "macos", target_arch = "aarch64"))
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -22,17 +22,15 @@ use wasmtime_asm_macros::asm_func;
|
|||||||
|
|
||||||
cfg_if::cfg_if! {
|
cfg_if::cfg_if! {
|
||||||
if #[cfg(target_os = "macos")] {
|
if #[cfg(target_os = "macos")] {
|
||||||
macro_rules! cfi_window_save { () => (""); }
|
macro_rules! paci1716 { () => ("pacib1716\n"); }
|
||||||
macro_rules! pacia1716 { () => (""); }
|
macro_rules! pacisp { () => ("pacibsp\n"); }
|
||||||
macro_rules! paciasp { () => (""); }
|
macro_rules! autisp { () => ("autibsp\n"); }
|
||||||
macro_rules! autiasp { () => (""); }
|
|
||||||
macro_rules! sym_adrp { ($s:tt) => (concat!("_", $s, "@PAGE")); }
|
macro_rules! sym_adrp { ($s:tt) => (concat!("_", $s, "@PAGE")); }
|
||||||
macro_rules! sym_add { ($s:tt) => (concat!("_", $s, "@PAGEOFF")); }
|
macro_rules! sym_add { ($s:tt) => (concat!("_", $s, "@PAGEOFF")); }
|
||||||
} else {
|
} else {
|
||||||
macro_rules! cfi_window_save { () => (".cfi_window_save\n"); }
|
macro_rules! paci1716 { () => ("pacia1716\n"); }
|
||||||
macro_rules! pacia1716 { () => ("pacia1716\n"); }
|
macro_rules! pacisp { () => ("paciasp\n"); }
|
||||||
macro_rules! paciasp { () => ("paciasp\n"); }
|
macro_rules! autisp { () => ("autiasp\n"); }
|
||||||
macro_rules! autiasp { () => ("autiasp\n"); }
|
|
||||||
macro_rules! sym_adrp { ($s:tt) => (concat!($s, "")); }
|
macro_rules! sym_adrp { ($s:tt) => (concat!($s, "")); }
|
||||||
macro_rules! sym_add { ($s:tt) => (concat!(":lo12:", $s)); }
|
macro_rules! sym_add { ($s:tt) => (concat!(":lo12:", $s)); }
|
||||||
}
|
}
|
||||||
@@ -44,9 +42,9 @@ asm_func!(
|
|||||||
"
|
"
|
||||||
.cfi_startproc
|
.cfi_startproc
|
||||||
",
|
",
|
||||||
paciasp!(),
|
pacisp!(),
|
||||||
cfi_window_save!(),
|
|
||||||
"
|
"
|
||||||
|
.cfi_window_save
|
||||||
// Save all callee-saved registers on the stack since we're
|
// Save all callee-saved registers on the stack since we're
|
||||||
// assuming they're clobbered as a result of the stack switch.
|
// assuming they're clobbered as a result of the stack switch.
|
||||||
stp x29, x30, [sp, -16]!
|
stp x29, x30, [sp, -16]!
|
||||||
@@ -81,9 +79,9 @@ asm_func!(
|
|||||||
ldp x20, x19, [sp], 16
|
ldp x20, x19, [sp], 16
|
||||||
ldp x29, x30, [sp], 16
|
ldp x29, x30, [sp], 16
|
||||||
",
|
",
|
||||||
autiasp!(),
|
autisp!(),
|
||||||
cfi_window_save!(),
|
|
||||||
"
|
"
|
||||||
|
.cfi_window_save
|
||||||
ret
|
ret
|
||||||
.cfi_endproc
|
.cfi_endproc
|
||||||
",
|
",
|
||||||
@@ -121,7 +119,7 @@ asm_func!(
|
|||||||
adrp x17, ", sym_adrp!("wasmtime_fiber_start"), "
|
adrp x17, ", sym_adrp!("wasmtime_fiber_start"), "
|
||||||
add x17, x17, ", sym_add!("wasmtime_fiber_start"), "
|
add x17, x17, ", sym_add!("wasmtime_fiber_start"), "
|
||||||
",
|
",
|
||||||
pacia1716!(),
|
paci1716!(),
|
||||||
"
|
"
|
||||||
str x17, [x16, -0x8] // x17 => lr
|
str x17, [x16, -0x8] // x17 => lr
|
||||||
str x0, [x16, -0x18] // x0 => x19
|
str x0, [x16, -0x18] // x0 => x19
|
||||||
@@ -151,9 +149,7 @@ asm_func!(
|
|||||||
0x23, 0xa0, 0x1 /* DW_OP_plus_uconst 0xa0 */
|
0x23, 0xa0, 0x1 /* DW_OP_plus_uconst 0xa0 */
|
||||||
.cfi_rel_offset x29, -0x10
|
.cfi_rel_offset x29, -0x10
|
||||||
.cfi_rel_offset x30, -0x08
|
.cfi_rel_offset x30, -0x08
|
||||||
",
|
.cfi_window_save
|
||||||
cfi_window_save!(),
|
|
||||||
"
|
|
||||||
.cfi_rel_offset x19, -0x18
|
.cfi_rel_offset x19, -0x18
|
||||||
.cfi_rel_offset x20, -0x20
|
.cfi_rel_offset x20, -0x20
|
||||||
.cfi_rel_offset x21, -0x28
|
.cfi_rel_offset x21, -0x28
|
||||||
|
|||||||
@@ -128,6 +128,16 @@ impl<'a> Arbitrary<'a> for CodegenSettings {
|
|||||||
test: is_aarch64_feature_detected,
|
test: is_aarch64_feature_detected,
|
||||||
|
|
||||||
std: "lse" => clif: "has_lse",
|
std: "lse" => clif: "has_lse",
|
||||||
|
// even though the natural correspondence seems to be
|
||||||
|
// between "paca" and "has_pauth", the latter has no effect
|
||||||
|
// in isolation, so we actually use the setting that affects
|
||||||
|
// code generation
|
||||||
|
std: "paca" => clif: "sign_return_address",
|
||||||
|
// "paca" and "pacg" check for the same underlying
|
||||||
|
// architectural feature, so we use the latter to cover more
|
||||||
|
// code generation settings, of which we have chosen the one
|
||||||
|
// with the most significant effect
|
||||||
|
std: "pacg" => clif: "sign_return_address_all" ratio: 1 in 2,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
return Ok(CodegenSettings::Target {
|
return Ok(CodegenSettings::Target {
|
||||||
|
|||||||
Reference in New Issue
Block a user