From 532356254dcc6061c34ef96dd59be0e5a47d9cb4 Mon Sep 17 00:00:00 2001 From: Ferdia McKeogh Date: Mon, 1 Apr 2024 17:10:13 +0100 Subject: [PATCH] Allowlist more functions, tested standalone and in brig --- borealis/src/brig/codegen.rs | 13 +++- borealis/src/brig/mod.rs | 131 ++++++++++++++++++++++++++--------- borealis/src/rudder/build.rs | 46 +++++++----- 3 files changed, 138 insertions(+), 52 deletions(-) diff --git a/borealis/src/brig/codegen.rs b/borealis/src/brig/codegen.rs index 22753d7..6a38ba7 100644 --- a/borealis/src/brig/codegen.rs +++ b/borealis/src/brig/codegen.rs @@ -129,6 +129,15 @@ pub fn codegen(rudder: Context, entrypoint: InternedString) -> TokenStream { #entrypoint + // increment PC if no branch was taken + let branch_taken = unsafe { (state.data.as_mut_ptr().byte_offset(14856) as *mut bool) }; + + if !unsafe { *branch_taken } { + unsafe { *(state.data.as_ptr().byte_offset(12704) as *mut usize) += 4 }; + } + + unsafe { *branch_taken = false }; + ExecuteResult::Ok } @@ -203,7 +212,7 @@ pub fn codegen_type(typ: Rc) -> TokenStream { let element_type = codegen_type(element_type.clone()); if *element_count == 0 { - quote!(Vec<#element_type>) + quote!(alloc::vec::Vec<#element_type>) } else { let count = quote!(#element_count); quote!([#element_type; #count]) @@ -463,7 +472,7 @@ fn codegen_stmt(stmt: Statement) -> TokenStream { ((#ident) != 0) } } else if target.is_unknown_length_vector() { - quote!(Vec::from(#ident)) + quote!(alloc::vec::Vec::from(#ident)) } else { match kind { CastOperationKind::ZeroExtend => { diff --git a/borealis/src/brig/mod.rs b/borealis/src/brig/mod.rs index badc83b..ac0be35 100644 --- a/borealis/src/brig/mod.rs +++ b/borealis/src/brig/mod.rs @@ -96,6 +96,23 @@ const FN_ALLOWLIST: &[&str] = &[ "decode_hvc_aarch64_instrs_system_exceptions_runtime_hvc", "DebugTarget", "CurrentSecurityState", + "SecurityStateAtEL", + "HaveRME", + "DebugTargetFrom", + "HaveSecureEL2Ext", + "_get_MDSCR_EL1_Type_SS", + "EL2Enabled", + "decode_ccmp_imm_aarch64_instrs_integer_conditional_compare_immediate", + "IsSecureEL2Enabled", + "execute_aarch64_instrs_integer_conditional_compare_immediate", + "decode_bl_aarch64_instrs_branch_unconditional_immediate", + "HaveGCS", + "decode_mrs_aarch64_instrs_system_register_system", + "NextInstrAddr", + "ThisInstrLength", + "AArch64_CheckSystemAccess", + "HaveBTIExt", + "fdiv_int", ]; mod codegen; @@ -172,9 +189,11 @@ pub fn sail_to_brig>( let prelude = if standalone { quote! { - struct ConsoleTracer; + extern crate alloc; - impl Tracer for ConsoleTracer { + struct PrintlnTracer; + + impl Tracer for PrintlnTracer { fn begin(&self, pc: u64) { println!("begin @ {pc:x}"); } @@ -225,19 +244,11 @@ pub fn sail_to_brig>( ] }; - loop { - let pc = unsafe { (state.data.as_mut_ptr().byte_offset(12704) as *mut u64) }; - let insr = unsafe { *(text.as_ptr().offset(dbg!(unsafe {*pc}) as isize) as *mut u32) }; - dbg!(decode_execute(insr, &mut state, &mut ConsoleTracer)); - - let branch_taken = unsafe { (state.data.as_mut_ptr().byte_offset(14856) as *mut bool) }; - - if !unsafe {*branch_taken} { - unsafe { *pc += 4}; - } - - unsafe {*branch_taken = false}; + let pc_ptr = unsafe { (state.data.as_mut_ptr().byte_offset(12704) as *mut u64) }; + let pc = dbg!(unsafe { *pc_ptr }); + let insr = unsafe { *(text.as_ptr().offset(pc as isize) as *mut u32) }; + dbg!(decode_execute(insr, &mut state, &mut PrintlnTracer)); } } } @@ -245,32 +256,81 @@ pub fn sail_to_brig>( quote! { use super::{CoreState, ExecutionEngine}; - pub struct AArch64Interpreter; + pub struct Interpreter; impl CoreState for State { fn pc(&self) -> usize { - self.pc as usize + unsafe { *(self.data.as_ptr().byte_offset(12704) as *const usize) } } fn new(pc: usize) -> Self { - Self { pc: pc as u64, sp: 0, x: [0; 31] } + let mut celf = State::default(); + unsafe { *(celf.data.as_mut_ptr().byte_offset(12704) as *mut usize) = pc }; + + // set enabled features + unsafe { + *(celf.data.as_mut_ptr().byte_offset(0x18ed0) as *mut [bool; 259]) = [ + false, false, false, false, true, true, true, false, false, true, true, false, false, + false, false, false, false, false, false, false, false, false, false, false, false, + false, false, false, false, false, false, false, false, false, false, false, false, + false, false, false, false, false, false, false, false, false, false, false, false, + false, false, false, false, false, false, false, false, false, false, false, false, + false, false, false, false, false, false, false, false, false, false, false, false, + false, false, false, false, false, false, false, false, false, false, false, false, + false, false, false, false, false, false, false, false, false, false, false, false, + false, false, false, false, false, false, false, false, false, false, false, false, + false, false, false, false, false, false, false, false, false, false, false, false, + false, false, false, false, false, false, false, false, false, false, false, false, + false, false, false, false, false, false, false, false, false, false, false, false, + false, false, false, false, false, false, false, false, false, false, false, false, + false, false, false, false, false, false, false, false, false, false, false, false, + false, false, false, false, false, false, false, false, false, false, false, false, + false, false, false, false, false, false, false, false, false, false, false, false, + false, false, false, false, false, false, false, false, false, false, false, false, + false, false, false, false, false, false, false, false, false, false, false, false, + false, false, false, false, false, false, false, false, false, false, false, false, + false, false, false, false, false, false, false, false, false, false, false, false, + false, false, false, false, false, false, false, false, false, false, false, false, + false, false, false, false, false, false, + ] + }; + + celf + } + } + + struct LogTracer; + + impl Tracer for LogTracer { + fn begin(&self, pc: u64) { + log::trace!("begin @ {pc:x}"); + } + + fn end(&self) { + log::trace!("end"); + } + + fn read_register(&self, offset: usize, value: T) { + log::trace!("read-register {offset:x} = {value:?}"); + } + fn write_register(&self, offset: usize, value: T) { + log::trace!("write-register {offset:x} = {value:?}"); } } + fn fetch(pc: usize) -> u32 { unsafe { *(pc as *const u32) } } - impl ExecutionEngine for AArch64Interpreter { + impl ExecutionEngine for Interpreter { fn step(amount: super::StepAmount, state: &mut State) -> super::StepResult { let insn_data = fetch(state.pc()); log::trace!("fetch @ {} = {:08x}", state.pc(), insn_data); - match decode_execute(insn_data, state) { + match decode_execute(insn_data, state, &mut LogTracer) { ExecuteResult::Ok => { - state.pc += 4; - super::StepResult::Ok - + super::StepResult::Ok }, ExecuteResult::EndOfBlock => { super::StepResult::Ok @@ -372,24 +432,34 @@ pub fn sail_to_brig>( } } - - impl, L> core::ops::Sub for Bundle { + impl core::ops::Sub for Bundle where core::num::Wrapping: core::ops::Sub> { type Output = Self; fn sub(self, rhs: Self) -> Self::Output { Self { - value: self.value - rhs.value, + value: (core::num::Wrapping(self.value) - core::num::Wrapping(rhs.value)).0, length: self.length } } } - impl, L> core::ops::Add for Bundle { + impl core::ops::Add for Bundle where core::num::Wrapping: core::ops::Add> { type Output = Self; fn add(self, rhs: Self) -> Self::Output { Self { - value: self.value + rhs.value, + value: (core::num::Wrapping(self.value) + core::num::Wrapping(rhs.value)).0, + length: self.length + } + } + } + + impl core::ops::Div for Bundle where core::num::Wrapping: core::ops::Div> { + type Output = Self; + + fn div(self, rhs: Self) -> Self::Output { + Self { + value: (core::num::Wrapping(self.value) / core::num::Wrapping(rhs.value)).0, length: self.length } } @@ -417,12 +487,7 @@ pub fn sail_to_brig>( } } - impl core::cmp::Eq for Bundle { - - } - - - + impl core::cmp::Eq for Bundle {} #prelude diff --git a/borealis/src/rudder/build.rs b/borealis/src/rudder/build.rs index b1db255..f35c747 100644 --- a/borealis/src/rudder/build.rs +++ b/borealis/src/rudder/build.rs @@ -69,7 +69,7 @@ impl BuildContext { self.registers .insert(name, (typ.clone(), self.next_register_offset)); - log::warn!("adding register {name} @ {:x}", self.next_register_offset); + log::debug!("adding register {name} @ {:x}", self.next_register_offset); // 8 byte aligned self.next_register_offset += typ.width_bytes().next_multiple_of(8) @@ -654,22 +654,25 @@ impl<'ctx: 'fn_ctx, 'fn_ctx> BlockBuildContext<'ctx, 'fn_ctx> { length: len, })) } - "eq_bits" | "eq_int" | "eq_any" | "eq_any" => Some( - self.statement_builder - .build(StatementKind::BinaryOperation { - kind: BinaryOperationKind::CompareEqual, - lhs: args[0].clone(), - rhs: args[1].clone(), - }), - ), - "neq_bits" => Some( - self.statement_builder - .build(StatementKind::BinaryOperation { - kind: BinaryOperationKind::CompareNotEqual, - lhs: args[0].clone(), - rhs: args[1].clone(), - }), - ), + "eq_bits" + | "eq_int" + | "eq_any" + | "eq_any" + | "eq_any" + | "eq_any" => Some(self.statement_builder.build( + StatementKind::BinaryOperation { + kind: BinaryOperationKind::CompareEqual, + lhs: args[0].clone(), + rhs: args[1].clone(), + }, + )), + "neq_bits" | "neq_any" => Some(self.statement_builder.build( + StatementKind::BinaryOperation { + kind: BinaryOperationKind::CompareNotEqual, + lhs: args[0].clone(), + rhs: args[1].clone(), + }, + )), "add_atom" | "add_bits" | "add_bits_int" => Some(self.statement_builder.build( StatementKind::BinaryOperation { kind: BinaryOperationKind::Add, @@ -684,6 +687,14 @@ impl<'ctx: 'fn_ctx, 'fn_ctx> BlockBuildContext<'ctx, 'fn_ctx> { rhs: args[1].clone(), }, )), + "tdiv_int" => Some( + self.statement_builder + .build(StatementKind::BinaryOperation { + kind: BinaryOperationKind::Divide, + lhs: args[0].clone(), + rhs: args[1].clone(), + }), + ), "lt_int" => Some( self.statement_builder .build(StatementKind::BinaryOperation { @@ -746,6 +757,7 @@ impl<'ctx: 'fn_ctx, 'fn_ctx> BlockBuildContext<'ctx, 'fn_ctx> { rhs: args[1].clone(), }), ), + "sail_shiftright" => { Some(self.statement_builder.build(StatementKind::ShiftOperation { kind: ShiftOperationKind::LogicalShiftRight,