Line data Source code
1 : use lief_ffi as ffi;
2 :
3 : use crate::common::FromFFI;
4 :
5 : use crate::dwarf::editor::types::EditorType;
6 : use crate::dwarf::editor::Variable;
7 :
8 : /// This structure represents an **editable** DWARF function (`DW_TAG_subprogram`)
9 : pub struct Function {
10 : ptr: cxx::UniquePtr<ffi::DWARF_editor_Function>,
11 : }
12 :
13 : impl FromFFI<ffi::DWARF_editor_Function> for Function {
14 0 : fn from_ffi(ptr: cxx::UniquePtr<ffi::DWARF_editor_Function>) -> Self {
15 0 : Self {
16 0 : ptr,
17 0 : }
18 0 : }
19 : }
20 :
21 : /// This structure defines an implementation range
22 : pub struct Range {
23 : start: u64,
24 : end: u64,
25 : }
26 :
27 :
28 : /// This structure represents a parameter of the current function (`DW_TAG_formal_parameter`)
29 : #[allow(dead_code)]
30 : pub struct Parameter {
31 : ptr: cxx::UniquePtr<ffi::DWARF_editor_Function_Parameter>,
32 : }
33 :
34 : impl FromFFI<ffi::DWARF_editor_Function_Parameter> for Parameter {
35 0 : fn from_ffi(ptr: cxx::UniquePtr<ffi::DWARF_editor_Function_Parameter>) -> Self {
36 0 : Self {
37 0 : ptr,
38 0 : }
39 0 : }
40 : }
41 :
42 : /// This structure mirrors the `DW_TAG_lexical_block` DWARF tag
43 : #[allow(dead_code)]
44 : pub struct LexicalBlock {
45 : ptr: cxx::UniquePtr<ffi::DWARF_editor_Function_LexicalBlock>,
46 : }
47 :
48 : impl FromFFI<ffi::DWARF_editor_Function_LexicalBlock> for LexicalBlock {
49 0 : fn from_ffi(ptr: cxx::UniquePtr<ffi::DWARF_editor_Function_LexicalBlock>) -> Self {
50 0 : Self {
51 0 : ptr,
52 0 : }
53 0 : }
54 : }
55 :
56 : /// This class mirrors the `DW_TAG_label` DWARF tag
57 : #[allow(dead_code)]
58 : pub struct Label {
59 : ptr: cxx::UniquePtr<ffi::DWARF_editor_Function_Label>,
60 : }
61 :
62 : impl FromFFI<ffi::DWARF_editor_Function_Label> for Label {
63 0 : fn from_ffi(ptr: cxx::UniquePtr<ffi::DWARF_editor_Function_Label>) -> Self {
64 0 : Self {
65 0 : ptr,
66 0 : }
67 0 : }
68 : }
69 :
70 : impl Function {
71 : /// Set the address of this function by defining `DW_AT_entry_pc`
72 0 : pub fn set_address(&mut self, addr: u64) -> &mut Self {
73 0 : self.ptr.pin_mut().set_address(addr);
74 0 : self
75 0 : }
76 :
77 : /// Set the upper and lower bound addresses for this function. This assumes
78 : /// that the function is contiguous between `low` and `high`.
79 : ///
80 : /// Underneath, the function defines `DW_AT_low_pc` and `DW_AT_high_pc`
81 0 : pub fn set_low_high(&mut self, low: u64, high: u64) -> &mut Self {
82 0 : self.ptr.pin_mut().set_low_high(low, high);
83 0 : self
84 0 : }
85 :
86 : /// Set the ranges of addresses owned by the implementation of this function
87 : /// by setting the `DW_AT_ranges` attribute.
88 : ///
89 : /// This setter should be used for non-contiguous function.
90 0 : pub fn set_ranges(&mut self, ranges: &[Range]) -> &mut Self {
91 0 : let mut ffi_ranges = cxx::CxxVector::new();
92 0 : for range in ranges {
93 0 : let ffi_range = ffi::DWARF_editor_Function_Range {
94 0 : start: range.start,
95 0 : end: range.end,
96 0 : };
97 0 : ffi_ranges.as_mut().unwrap().push(ffi_range);
98 0 : }
99 0 : self.ptr.pin_mut().set_ranges(&ffi_ranges);
100 0 : self
101 0 : }
102 :
103 : /// Set the function as external by defining `DW_AT_external` to true.
104 : /// This means that the function is **imported** by the current compilation unit.
105 0 : pub fn set_external(&mut self) -> &mut Self {
106 0 : self.ptr.pin_mut().set_external();
107 0 : self
108 0 : }
109 :
110 : /// Set the return type of this function
111 0 : pub fn set_return_type(&mut self, ty: &dyn EditorType) -> &mut Self {
112 0 : self.ptr.pin_mut().set_return_type(ty.get_base());
113 0 : self
114 0 : }
115 :
116 : /// Add a parameter to the current function
117 0 : pub fn add_parameter(&mut self, name: &str, ty: &dyn EditorType) -> Parameter {
118 0 : Parameter::from_ffi(self.ptr.pin_mut().add_parameter(name, ty.get_base()))
119 0 : }
120 :
121 : /// Create a stack-based variable owned by the current function
122 0 : pub fn create_stack_variable(&mut self, name: &str) -> Variable {
123 0 : Variable::from_ffi(self.ptr.pin_mut().create_stack_variable(name))
124 0 : }
125 :
126 : /// Add a lexical block with the given range
127 0 : pub fn add_lexical_block(&mut self, start: u64, end: u64) -> LexicalBlock {
128 0 : LexicalBlock::from_ffi(self.ptr.pin_mut().add_lexical_block(start, end))
129 0 : }
130 :
131 : /// Add a label at the given address
132 0 : pub fn add_label(&mut self, addr: u64, name: &str) -> Label {
133 0 : Label::from_ffi(self.ptr.pin_mut().add_label(addr, name))
134 0 : }
135 : }
|