Skip to content

Commit

Permalink
add handle call logic in senryx
Browse files Browse the repository at this point in the history
  • Loading branch information
DiuDiu777 committed Nov 9, 2024
1 parent a4fce81 commit 633cfb2
Show file tree
Hide file tree
Showing 5 changed files with 78 additions and 29 deletions.
1 change: 1 addition & 0 deletions rap/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ name = "cargo-rap"
name = "rap"

[dependencies]
lazy_static = "1.4"
snafu = "0.7.0"
chrono = "0.4.19"
serde_json = "1.0.72"
Expand Down
7 changes: 4 additions & 3 deletions rap/src/analysis/senryx.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
pub mod contracts;
pub mod inter_record;
pub mod matcher;
pub mod visitor;

Expand All @@ -21,7 +22,7 @@ impl<'tcx> SenryxCheck<'tcx> {
}

pub fn start(&self) {
let related_items = RelatedFnCollector::collect(self.tcx);
let related_items = RelatedFnCollector::collect(self.tcx); // find all func
let hir_map = self.tcx.hir();
for (_, &ref vec) in &related_items {
for (body_id, _span) in vec {
Expand Down Expand Up @@ -57,11 +58,11 @@ impl<'tcx> SenryxCheck<'tcx> {
pub fn pre_handle_type(&self, def_id: DefId) {
let mut uig_checker = UnsafetyIsolationCheck::new(self.tcx);
let func_type = uig_checker.get_type(def_id);
let mut body_visitor = BodyVisitor::new(self.tcx, def_id);
let mut body_visitor = BodyVisitor::new(self.tcx, def_id, true);
if func_type == 1 {
let func_cons = uig_checker.search_constructor(def_id);
for func_con in func_cons {
let mut cons_body_visitor = BodyVisitor::new(self.tcx, func_con);
let mut cons_body_visitor = BodyVisitor::new(self.tcx, func_con, true);
cons_body_visitor.path_forward_check();
// TODO: cache fields' states

Expand Down
1 change: 1 addition & 0 deletions rap/src/analysis/senryx/contracts/abstract_state.rs
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,7 @@ impl AbstractStateItem {
}
}

#[derive(PartialEq)]
pub struct AbstractState {
pub state_map: HashMap<usize, AbstractStateItem>,
}
Expand Down
32 changes: 32 additions & 0 deletions rap/src/analysis/senryx/inter_record.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
use lazy_static::lazy_static;
use rustc_hir::def_id::DefId;
use std::{collections::HashMap, sync::Mutex};

use super::contracts::abstract_state::AbstractStateItem;

lazy_static! {
pub static ref GLOBAL_INTER_RECORDER: Mutex<HashMap<DefId, InterAnalysisRecord>> =
Mutex::new(HashMap::new());
}
// static mut GLOBAL_INTER_RECORDER: HashMap<DefId,InterAnalysisRecord> = HashMap::new();

pub struct InterAnalysisRecord {
pub pre_analysis_state: HashMap<usize, AbstractStateItem>,
pub post_analysis_state: HashMap<usize, AbstractStateItem>,
}

impl InterAnalysisRecord {
pub fn new(
pre_analysis_state: HashMap<usize, AbstractStateItem>,
post_analysis_state: HashMap<usize, AbstractStateItem>,
) -> Self {
Self {
pre_analysis_state,
post_analysis_state,
}
}

pub fn is_pre_state_same(&self, other_pre_state: &HashMap<usize, AbstractStateItem>) -> bool {
self.pre_analysis_state == *other_pre_state
}
}
66 changes: 40 additions & 26 deletions rap/src/analysis/senryx/visitor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ use std::collections::{HashMap, HashSet};
use super::contracts::abstract_state::{
AbstractState, AbstractStateItem, AlignState, StateType, VType, Value,
};
use super::inter_record::{InterAnalysisRecord, GLOBAL_INTER_RECORDER};
use super::matcher::match_unsafe_api_and_check_contracts;
use rustc_hir::def_id::DefId;
use rustc_middle::ty::TyCtxt;
Expand All @@ -23,17 +24,19 @@ pub struct BodyVisitor<'tcx> {
// abstract_states records the path index and variables' ab states in this path
pub abstract_states: HashMap<usize, AbstractState>,
pub unsafe_callee_report: HashMap<String, usize>,
pub first_layer_flag: bool,
}

impl<'tcx> BodyVisitor<'tcx> {
pub fn new(tcx: TyCtxt<'tcx>, def_id: DefId) -> Self {
pub fn new(tcx: TyCtxt<'tcx>, def_id: DefId, first_layer_flag: bool) -> Self {
let body = tcx.optimized_mir(def_id);
Self {
tcx,
def_id,
safedrop_graph: SafeDropGraph::new(body, tcx, def_id),
abstract_states: HashMap::new(),
unsafe_callee_report: HashMap::new(),
first_layer_flag,
}
}

Expand Down Expand Up @@ -97,23 +100,25 @@ impl<'tcx> BodyVisitor<'tcx> {
} => {
let func_name = format!("{:?}", func);
if let Operand::Constant(func_constant) = func {
if let ty::FnDef(ref _callee_def_id, raw_list) =
func_constant.const_.ty().kind()
if let ty::FnDef(ref callee_def_id, raw_list) = func_constant.const_.ty().kind()
{
for generic_arg in raw_list.iter() {
match generic_arg.unpack() {
GenericArgKind::Type(ty) => {
match_unsafe_api_and_check_contracts(
func_name.as_str(),
args,
&self.abstract_states.get(&path_index).unwrap(),
ty,
);
if self.first_layer_flag {
for generic_arg in raw_list.iter() {
match generic_arg.unpack() {
GenericArgKind::Type(ty) => {
match_unsafe_api_and_check_contracts(
func_name.as_str(),
args,
&self.abstract_states.get(&path_index).unwrap(),
ty,
);
}
_ => {}
}
_ => {}
}
}
//TODO:path_inter_analyze
self.handle_call(callee_def_id);
}
}
}
Expand Down Expand Up @@ -185,19 +190,6 @@ impl<'tcx> BodyVisitor<'tcx> {
);
self.insert_path_abstate(path_index, lpjc_local, abitem);
}
// Rvalue::AddressOf(_, rplace) => {
// let align = 0;
// let size = 0;
// let abitem = AbstractStateItem::new(
// (Value::None, Value::None),
// VType::Pointer(align, size),
// HashSet::from([StateType::AlignState(AlignState::Aligned)]),
// );
// self.insert_path_abstate(path_index, lpjc_local, abitem);
// let _rpjc_local = self
// .safedrop_graph
// .projection(self.tcx, true, rplace.clone());
// }
Rvalue::Cast(_cast_kind, op, ty) => match op {
Operand::Move(rplace) | Operand::Copy(rplace) => {
let rpjc_local = self
Expand Down Expand Up @@ -243,6 +235,26 @@ impl<'tcx> BodyVisitor<'tcx> {
}
}

pub fn handle_call(&mut self, def_id: &DefId) {
let pre_analysis_state = HashMap::new();
let mut recorder = GLOBAL_INTER_RECORDER.lock().unwrap();
if let Some(record) = recorder.get_mut(def_id) {
if record.is_pre_state_same(&pre_analysis_state) {
// update directly
self.update_inter_state_directly();
return;
}
}
let _inter_body_visitor = BodyVisitor::new(self.tcx, *def_id, false).path_forward_check();
let post_analysis_state = HashMap::new();
recorder.insert(
*def_id,
InterAnalysisRecord::new(pre_analysis_state, post_analysis_state),
);
}

pub fn update_inter_state_directly(&mut self) {}

pub fn visit_ty_and_get_layout(&self, ty: Ty<'tcx>) -> (usize, usize) {
match ty.kind() {
TyKind::RawPtr(ty, _) | TyKind::Ref(_, ty, _) | TyKind::Slice(ty) => {
Expand Down Expand Up @@ -364,4 +376,6 @@ impl<'tcx> BodyVisitor<'tcx> {
let size = layout.size.bytes() as usize;
(align, size)
}

pub fn get_abstate_by_place(&self) {}
}

0 comments on commit 633cfb2

Please sign in to comment.