rust_debug/evaluate/
attributes.rs

1use gimli::{
2    AttributeValue::{
3        AddressClass, Data1, Data2, Data4, Data8, DebugStrRef, Encoding, Sdata, Udata,
4    },
5    DebuggingInformationEntry, DwAddr, DwAte, Reader, Unit,
6};
7
8use anyhow::{anyhow, Result};
9use log::error;
10
11/// This function will return the value of the name attribute in the given DIE.
12///
13/// Description:
14///
15/// * `dwarf` - A reference to gimli-rs `Dwarf` struct.
16/// * `die` - A reference to a gimli-rs `Die` struct.
17///
18/// This function will try to retrieve the value of the attribute `DW_AT_name` from the given DIE.
19pub fn name_attribute<R: Reader<Offset = usize>>(
20    dwarf: &gimli::Dwarf<R>,
21    die: &DebuggingInformationEntry<R>,
22) -> Result<Option<String>> {
23    match die.attr_value(gimli::DW_AT_name)? {
24        Some(DebugStrRef(offset)) => Ok(Some(dwarf.string(offset)?.to_string()?.to_string())),
25        Some(unknown) => {
26            error!("Unimplemented for {:?}", unknown);
27            Err(anyhow!("Unimplemented for {:?}", unknown))
28        }
29        None => Ok(None),
30    }
31}
32
33/// This function will return the value of the byte_size attribute in the given DIE.
34///
35/// Description:
36///
37/// * `die` - A reference to a gimli-rs `Die` struct.
38///
39/// This function will try to retrieve the value of the attribute `DW_AT_byte_size` from the given DIE.
40pub fn byte_size_attribute<R: Reader<Offset = usize>>(
41    die: &DebuggingInformationEntry<R>,
42) -> Result<Option<u64>> {
43    match die.attr_value(gimli::DW_AT_byte_size)? {
44        Some(Udata(val)) => Ok(Some(val)),
45        Some(unknown) => {
46            error!("Unimplemented for {:?}", unknown);
47            Err(anyhow!("Unimplemented for {:?}", unknown))
48        }
49        _ => Ok(None),
50    }
51}
52
53/// This function will return the value of the alignment attribute in the given DIE.
54///
55/// Description:
56///
57/// * `die` - A reference to a gimli-rs `Die` struct.
58///
59/// This function will try to retrieve the value of the attribute `DW_AT_alignment` from the given DIE.
60pub fn alignment_attribute<R: Reader<Offset = usize>>(
61    die: &DebuggingInformationEntry<R>,
62) -> Result<Option<u64>> {
63    match die.attr_value(gimli::DW_AT_alignment)? {
64        Some(Udata(val)) => Ok(Some(val)),
65        Some(unknown) => {
66            error!("Unimplemented for {:?}", unknown);
67            Err(anyhow!("Unimplemented for {:?}", unknown))
68        }
69        _ => Ok(None),
70    }
71}
72
73/// This function will return the value of the data_member_location attribute in the given DIE.
74///
75/// Description:
76///
77/// * `die` - A reference to a gimli-rs `Die` struct.
78///
79/// This function will try to retrieve the value of the attribute `DW_AT_data_member_location` from the given DIE.
80pub fn data_member_location_attribute<R: Reader<Offset = usize>>(
81    die: &DebuggingInformationEntry<R>,
82) -> Result<Option<u64>> {
83    match die.attr_value(gimli::DW_AT_data_member_location)? {
84        Some(Udata(val)) => Ok(Some(val)),
85        Some(unknown) => {
86            error!("Unimplemented for {:?}", unknown);
87            Err(anyhow!("Unimplemented for {:?}", unknown))
88        }
89        _ => Ok(None),
90    }
91}
92
93/// This function will return the value of the type attribute in the given DIE.
94///
95/// Description:
96///
97/// * `dwarf` - A reference to gimli-rs `Dwarf` struct.
98/// * `unit` - A reference to gimli-rs `Unit` struct which contains the given DIE.
99/// * `die` - A reference to a gimli-rs `Die` struct.
100///
101/// This function will try to retrieve the value of the attribute `DW_AT_type` from the given DIE.
102pub fn type_attribute<R: Reader<Offset = usize>>(
103    dwarf: &gimli::Dwarf<R>,
104    unit: &Unit<R>,
105    die: &DebuggingInformationEntry<R>,
106) -> Result<Option<(gimli::UnitSectionOffset, gimli::UnitOffset)>> {
107    match die.attr_value(gimli::DW_AT_type)? {
108        Some(gimli::AttributeValue::UnitRef(offset)) => Ok(Some((unit.header.offset(), offset))),
109        Some(gimli::AttributeValue::DebugInfoRef(di_offset)) => {
110            let offset = gimli::UnitSectionOffset::DebugInfoOffset(di_offset);
111            let mut iter = dwarf.debug_info.units();
112            while let Ok(Some(header)) = iter.next() {
113                let unit = dwarf.unit(header)?;
114                if let Some(offset) = offset.to_unit_offset(&unit) {
115                    return Ok(Some((unit.header.offset(), offset)));
116                }
117            }
118            error!("Could not find type attribute value");
119            Ok(None)
120        }
121        _ => Ok(None),
122    }
123}
124
125/// This function will return the value of the address_class attribute in the given DIE.
126///
127/// Description:
128///
129/// * `die` - A reference to a gimli-rs `Die` struct.
130///
131/// This function will try to retrieve the value of the attribute `DW_AT_address_class` from the given DIE.
132pub fn address_class_attribute<R: Reader<Offset = usize>>(
133    die: &DebuggingInformationEntry<R>,
134) -> Result<Option<DwAddr>> {
135    match die.attr_value(gimli::DW_AT_address_class)? {
136        Some(AddressClass(val)) => Ok(Some(val)),
137        Some(unknown) => {
138            error!("Unimplemented for {:?}", unknown);
139            Err(anyhow!("Unimplemented for {:?}", unknown))
140        }
141        _ => Ok(None),
142    }
143}
144
145/// This function will return the value of the const_value attribute in the given DIE.
146///
147/// Description:
148///
149/// * `die` - A reference to a gimli-rs `Die` struct.
150///
151/// This function will try to retrieve the value of the attribute `DW_AT_cont_value` from the given DIE.
152pub fn const_value_attribute<R: Reader<Offset = usize>>(
153    die: &DebuggingInformationEntry<R>,
154) -> Result<Option<u64>> {
155    Ok(match die.attr_value(gimli::DW_AT_const_value)? {
156        Some(Udata(val)) => Some(val),
157        Some(Sdata(val)) => Some(val as u64), // TODO: Should not be converted to unsigned
158        Some(unknown) => {
159            error!("Unimplemented for {:?}", unknown);
160            return Err(anyhow!("Unimplemented for {:?}", unknown));
161        }
162        _ => None,
163    })
164}
165
166/// This function will return the value of the count attribute in the given DIE.
167///
168/// Description:
169///
170/// * `die` - A reference to a gimli-rs `Die` struct.
171///
172/// This function will try to retrieve the value of the attribute `DW_AT_count` from the given DIE.
173pub fn count_attribute<R: Reader<Offset = usize>>(
174    die: &DebuggingInformationEntry<R>,
175) -> Result<Option<u64>> {
176    Ok(match die.attr_value(gimli::DW_AT_count)? {
177        Some(Udata(val)) => Some(val),
178        Some(Data1(val)) => Some(val as u64),
179        Some(Data2(val)) => Some(val as u64),
180        Some(Data4(val)) => Some(val as u64),
181        Some(Data8(val)) => Some(val),
182        Some(unknown) => {
183            error!("Unimplemented for {:?}", unknown);
184            return Err(anyhow!("Unimplemented for {:?}", unknown));
185        }
186        _ => None,
187    })
188}
189
190/// This function will return the value of the encoding attribute in the given DIE.
191///
192/// Description:
193///
194/// * `die` - A reference to a gimli-rs `Die` struct.
195///
196/// This function will try to retrieve the value of the attribute `DW_AT_encoding` from the given DIE.
197pub fn encoding_attribute<R: Reader<Offset = usize>>(
198    die: &DebuggingInformationEntry<R>,
199) -> Result<Option<DwAte>> {
200    Ok(match die.attr_value(gimli::DW_AT_encoding)? {
201        Some(Encoding(val)) => Some(val),
202        Some(unknown) => {
203            error!("Unimplemented for {:?}", unknown);
204            return Err(anyhow!("Unimplemented for {:?}", unknown));
205        }
206        _ => None,
207    })
208}
209
210/// This function will return the value of the discr attribute in the given DIE.
211///
212/// Description:
213///
214/// * `die` - A reference to a gimli-rs `Die` struct.
215///
216/// This function will try to retrieve the value of the attribute `DW_AT_discr` from the given DIE.
217pub fn discr_attribute<R: Reader<Offset = usize>>(
218    die: &DebuggingInformationEntry<R>,
219) -> Result<Option<gimli::UnitOffset>> {
220    Ok(match die.attr_value(gimli::DW_AT_discr)? {
221        Some(gimli::AttributeValue::UnitRef(offset)) => Some(offset),
222        Some(unknown) => {
223            error!("Unimplemented for {:?}", unknown);
224            return Err(anyhow!("Unimplemented for {:?}", unknown));
225        }
226        _ => None,
227    })
228}
229
230/// This function will return the value of the discr_value attribute in the given DIE.
231///
232/// Description:
233///
234/// * `die` - A reference to a gimli-rs `Die` struct.
235///
236/// This function will try to retrieve the value of the attribute `DW_AT_discr_value` from the given DIE.
237pub fn discr_value_attribute<R: Reader<Offset = usize>>(
238    die: &DebuggingInformationEntry<R>,
239) -> Result<Option<u64>> {
240    Ok(match die.attr_value(gimli::DW_AT_discr_value)? {
241        Some(Data1(val)) => Some(val as u64),
242        Some(Udata(val)) => Some(val),
243        Some(unknown) => {
244            error!("Unimplemented for {:?}", unknown);
245            return Err(anyhow!("Unimplemented for {:?}", unknown));
246        }
247        _ => None,
248    })
249}
250
251/// This function will return the value of the lower_bound attribute in the given DIE.
252///
253/// Description:
254///
255/// * `die` - A reference to a gimli-rs `Die` struct.
256///
257/// This function will try to retrieve the value of the attribute `DW_AT_lower_bound` from the given DIE.
258pub fn lower_bound_attribute<R: Reader<Offset = usize>>(
259    die: &DebuggingInformationEntry<R>,
260) -> Result<Option<u64>> {
261    Ok(match die.attr_value(gimli::DW_AT_lower_bound)? {
262        Some(Data1(val)) => Some(val as u64),
263        Some(Udata(val)) => Some(val),
264        Some(Sdata(val)) => Some(val as u64),
265        Some(unknown) => {
266            error!("Unimplemented for {:?}", unknown);
267            return Err(anyhow!("Unimplemented for {:?}", unknown));
268        }
269        _ => None,
270    })
271}