idalib/
decompiler.rs

1use std::marker::PhantomData;
2
3use crate::ffi::hexrays::{
4    cblock_iter, cblock_t, cfunc_t, cfuncptr_t, cinsn_t, idalib_hexrays_cblock_iter,
5    idalib_hexrays_cblock_iter_next, idalib_hexrays_cblock_len, idalib_hexrays_cfunc_pseudocode,
6    idalib_hexrays_cfuncptr_inner,
7};
8use crate::idb::IDB;
9
10pub use crate::ffi::hexrays::{HexRaysError, HexRaysErrorCode};
11
12pub struct CFunction<'a> {
13    ptr: *mut cfunc_t,
14    _obj: cxx::UniquePtr<cfuncptr_t>,
15    _marker: PhantomData<&'a IDB>,
16}
17
18pub struct CBlock<'a> {
19    ptr: *mut cblock_t,
20    _marker: PhantomData<&'a ()>,
21}
22
23pub struct CBlockIter<'a> {
24    it: cxx::UniquePtr<cblock_iter>,
25    _marker: PhantomData<&'a ()>,
26}
27
28impl<'a> Iterator for CBlockIter<'a> {
29    type Item = CInsn<'a>;
30
31    fn next(&mut self) -> Option<Self::Item> {
32        let ptr = unsafe { idalib_hexrays_cblock_iter_next(self.it.pin_mut()) };
33
34        if ptr.is_null() {
35            None
36        } else {
37            Some(CInsn {
38                ptr,
39                _marker: PhantomData,
40            })
41        }
42    }
43}
44
45pub struct CInsn<'a> {
46    #[allow(unused)]
47    ptr: *mut cinsn_t,
48    _marker: PhantomData<&'a ()>,
49}
50
51impl<'a> CFunction<'a> {
52    pub(crate) fn new(obj: cxx::UniquePtr<cfuncptr_t>) -> Option<Self> {
53        let ptr = unsafe { idalib_hexrays_cfuncptr_inner(obj.as_ref().expect("valid pointer")) };
54
55        if ptr.is_null() {
56            return None;
57        }
58
59        Some(Self {
60            ptr,
61            _obj: obj,
62            _marker: PhantomData,
63        })
64    }
65
66    pub fn pseudocode(&self) -> String {
67        unsafe { idalib_hexrays_cfunc_pseudocode(self.ptr) }
68    }
69
70    fn as_cfunc(&self) -> &cfunc_t {
71        unsafe { self.ptr.as_ref().expect("valid pointer") }
72    }
73
74    pub fn body(&self) -> CBlock {
75        let cf = self.as_cfunc();
76        let ptr = unsafe { cf.body.__bindgen_anon_1.cblock };
77
78        CBlock {
79            ptr,
80            _marker: PhantomData,
81        }
82    }
83}
84
85impl<'a> CBlock<'a> {
86    pub fn iter(&self) -> CBlockIter {
87        CBlockIter {
88            it: unsafe { idalib_hexrays_cblock_iter(self.ptr) },
89            _marker: PhantomData,
90        }
91    }
92
93    pub fn len(&self) -> usize {
94        unsafe { idalib_hexrays_cblock_len(self.ptr) }
95    }
96
97    pub fn is_empty(&self) -> bool {
98        self.len() == 0
99    }
100}