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
11pub 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
33pub 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
53pub 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
73pub 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
93pub 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
125pub 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
145pub 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), Some(unknown) => {
159 error!("Unimplemented for {:?}", unknown);
160 return Err(anyhow!("Unimplemented for {:?}", unknown));
161 }
162 _ => None,
163 })
164}
165
166pub 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
190pub 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
210pub 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
230pub 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
251pub 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}