rapx/analysis/senryx/
matcher.rs1use crate::{analysis::utils::fn_info::get_sp_json, rap_warn};
2use rustc_middle::mir::Const;
3use rustc_middle::mir::Operand;
4use std::collections::{HashMap, HashSet};
5
6#[derive(Debug, PartialEq, Eq)]
7pub struct Sp {
8 pub sp_name: String,
9 pub sank_set: HashSet<usize>,
10}
11
12impl std::hash::Hash for Sp {
13 fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
14 self.sp_name.hash(state);
15 }
16}
17
18#[derive(Debug)]
19pub struct UnsafeApi {
20 pub api_name: String,
21 pub sps: Vec<HashSet<Sp>>,
22}
23
24pub fn parse_unsafe_api(func_name: &str) -> Option<UnsafeApi> {
25 let json_data = get_sp_json();
26 let function_info = json_data.get(func_name)?;
27
28 let params = function_info.as_object().map(|obj| {
29 obj.iter()
30 .filter_map(|(param_idx, props)| {
31 let param_num: usize = param_idx.parse().ok()?;
32 let sp_set = props.as_array().map(|arr| {
33 arr.iter()
34 .filter_map(|v| v.as_str())
35 .filter_map(|s| {
36 let (name, nums) = match s.split_once(':') {
38 Some((n, ns)) => (n, ns.split(',')),
39 None => (s, "".split(',')),
40 };
41
42 let sank_set = nums.filter_map(|n| n.trim().parse().ok()).collect();
44
45 Some(Sp {
46 sp_name: name.to_string(),
47 sank_set,
48 })
49 })
50 .collect::<HashSet<_>>()
51 })?;
52 Some((param_num, sp_set))
53 })
54 .collect::<HashMap<_, _>>()
55 })?;
56
57 let mut sorted_params: Vec<_> = params.into_iter().collect();
58 sorted_params.sort_by_key(|(k, _)| *k);
59
60 Some(UnsafeApi {
61 api_name: func_name.to_string(),
62 sps: sorted_params.into_iter().map(|(_, v)| v).collect(),
63 })
64}
65
66pub fn get_arg_place(arg: &Operand) -> (bool, usize) {
68 match arg {
69 Operand::Move(place) | Operand::Copy(place) => return (false, place.local.as_usize()),
70 Operand::Constant(constant) => {
71 let mut val = 0;
72 match constant.const_ {
73 Const::Ty(_ty, _const_value) => {
74 rap_warn!("const ty found!");
75 }
76 Const::Unevaluated(_unevaluated, _ty) => {}
77 Const::Val(const_value, _ty) => {
78 if let Some(scalar) = const_value.try_to_scalar_int() {
79 val = scalar.to_uint(scalar.size()) as usize;
80 }
81 }
82 }
83 return (true, val);
84 }
85 }
86}