Line data Source code
1 : use lief_ffi as ffi;
2 :
3 : use super::variable::Variables;
4 : use super::{Scope, Type, Parameters};
5 : use crate::common::{into_optional, into_ranges, FromFFI};
6 : use crate::declare_fwd_iterator;
7 : use crate::to_result;
8 : use crate::DebugLocation;
9 : use crate::Error;
10 : use crate::Range;
11 : use crate::assembly;
12 : use std::marker::PhantomData;
13 :
14 : /// This structure represents a DWARF function which can be associated with either:
15 : /// `DW_TAG_subprogram` or `DW_TAG_inlined_subroutine`.
16 : pub struct Function<'a> {
17 : ptr: cxx::UniquePtr<ffi::DWARF_Function>,
18 : _owner: PhantomData<&'a ()>,
19 : }
20 :
21 : impl FromFFI<ffi::DWARF_Function> for Function<'_> {
22 0 : fn from_ffi(ptr: cxx::UniquePtr<ffi::DWARF_Function>) -> Self {
23 0 : Self {
24 0 : ptr,
25 0 : _owner: PhantomData,
26 0 : }
27 0 : }
28 : }
29 :
30 : impl Function<'_> {
31 : /// The name of the function (`DW_AT_name`)
32 0 : pub fn name(&self) -> String {
33 0 : self.ptr.name().to_string()
34 0 : }
35 :
36 : /// The name of the function which is used for linking (`DW_AT_linkage_name`).
37 : ///
38 : /// This name differs from [`Function::name`] as it is usually mangled. The function
39 : /// return an empty string if the linkage name is not available.
40 0 : pub fn linkage_name(&self) -> String {
41 0 : self.ptr.linkage_name().to_string()
42 0 : }
43 :
44 : /// Return the address of the function (`DW_AT_entry_pc` or `DW_AT_low_pc`).
45 0 : pub fn address(&self) -> Result<u64, Error> {
46 0 : to_result!(ffi::DWARF_Function::address, self);
47 0 : }
48 :
49 : /// Return an iterator of variables (`DW_TAG_variable`) defined within the
50 : /// scope of this function. This includes regular stack-based variables as
51 : /// well as static ones.
52 0 : pub fn variables(&self) -> Variables {
53 0 : Variables::new(self.ptr.variables())
54 0 : }
55 :
56 : /// Whether this function is created by the compiler and not
57 : /// present in the original source code
58 0 : pub fn is_artificial(&self) -> bool {
59 0 : self.ptr.is_artificial()
60 0 : }
61 :
62 : /// Whether the function is defined **outside** the compilation unit (`DW_AT_external`)
63 0 : pub fn is_external(&self) -> bool {
64 0 : self.ptr.is_external()
65 0 : }
66 :
67 : /// Return the size taken by this function in the binary
68 0 : pub fn size(&self) -> u64 {
69 0 : self.ptr.size()
70 0 : }
71 :
72 : /// Ranges of virtual addresses owned by this function
73 0 : pub fn ranges(&self) -> Vec<Range> {
74 0 : into_ranges(self.ptr.ranges())
75 0 : }
76 :
77 : /// Original source code location
78 0 : pub fn debug_location(&self) -> DebugLocation {
79 0 : DebugLocation::from_ffi(self.ptr.debug_location())
80 0 : }
81 :
82 : /// Return the [`Type`] associated with the **return type** of this function.
83 0 : pub fn return_type(&self) -> Option<Type> {
84 0 : into_optional(self.ptr.get_type())
85 0 : }
86 :
87 : /// Return an iterator over the [`Parameters`] of this function
88 0 : pub fn parameters(&self) -> ParametersIt {
89 0 : ParametersIt::new(self.ptr.parameters())
90 0 : }
91 :
92 : /// List of exceptions (types) that can be thrown by the function.
93 : ///
94 : /// For instance, given this Swift code:
95 : ///
96 : /// ```swift
97 : /// func summarize(_ ratings: [Int]) throws(StatisticsError) {
98 : /// // ...
99 : /// }
100 : /// ```
101 : ///
102 : /// [`Function::thrown_types`] returns one element associated with the [`Type`]:
103 : /// `StatisticsError`.
104 0 : pub fn thrown_types(&self) -> ThrownTypes {
105 0 : ThrownTypes::new(self.ptr.thrown_types())
106 0 : }
107 :
108 : /// The scope in which this function is defined
109 0 : pub fn scope(&self) -> Option<Scope> {
110 0 : into_optional(self.ptr.scope())
111 0 : }
112 :
113 : /// Disassemble the current function by returning an iterator over
114 : /// the [`assembly::Instructions`]
115 0 : pub fn instructions(&self) -> Instructions {
116 0 : Instructions::new(self.ptr.instructions())
117 0 : }
118 : }
119 :
120 0 : declare_fwd_iterator!(
121 0 : Functions,
122 0 : Function<'a>,
123 0 : ffi::DWARF_Function,
124 0 : ffi::DWARF_CompilationUnit,
125 0 : ffi::DWARF_CompilationUnit_it_functions
126 0 : );
127 :
128 0 : declare_fwd_iterator!(
129 0 : ParametersIt,
130 0 : Parameters<'a>,
131 0 : ffi::DWARF_Parameter,
132 0 : ffi::DWARF_Function,
133 0 : ffi::DWARF_Function_it_parameters
134 0 : );
135 :
136 0 : declare_fwd_iterator!(
137 0 : ThrownTypes,
138 0 : Type<'a>,
139 0 : ffi::DWARF_Type,
140 0 : ffi::DWARF_Function,
141 0 : ffi::DWARF_Function_it_thrown_types
142 0 : );
143 :
144 :
145 0 : declare_fwd_iterator!(
146 0 : Instructions,
147 0 : assembly::Instructions,
148 0 : ffi::asm_Instruction,
149 0 : ffi::DWARF_Function,
150 0 : ffi::DWARF_Function_it_instructions
151 0 : );
|