use gimli::{
AttributeValue::{
AddressClass, Data1, Data2, Data4, Data8, DebugStrRef, Encoding, Sdata, Udata,
},
DebuggingInformationEntry, DwAddr, DwAte, Reader, Unit,
};
use anyhow::{anyhow, Result};
use log::error;
pub fn name_attribute<R: Reader<Offset = usize>>(
dwarf: &gimli::Dwarf<R>,
die: &DebuggingInformationEntry<R>,
) -> Result<Option<String>> {
match die.attr_value(gimli::DW_AT_name)? {
Some(DebugStrRef(offset)) => Ok(Some(dwarf.string(offset)?.to_string()?.to_string())),
Some(unknown) => {
error!("Unimplemented for {:?}", unknown);
Err(anyhow!("Unimplemented for {:?}", unknown))
}
None => Ok(None),
}
}
pub fn byte_size_attribute<R: Reader<Offset = usize>>(
die: &DebuggingInformationEntry<R>,
) -> Result<Option<u64>> {
match die.attr_value(gimli::DW_AT_byte_size)? {
Some(Udata(val)) => Ok(Some(val)),
Some(unknown) => {
error!("Unimplemented for {:?}", unknown);
Err(anyhow!("Unimplemented for {:?}", unknown))
}
_ => Ok(None),
}
}
pub fn alignment_attribute<R: Reader<Offset = usize>>(
die: &DebuggingInformationEntry<R>,
) -> Result<Option<u64>> {
match die.attr_value(gimli::DW_AT_alignment)? {
Some(Udata(val)) => Ok(Some(val)),
Some(unknown) => {
error!("Unimplemented for {:?}", unknown);
Err(anyhow!("Unimplemented for {:?}", unknown))
}
_ => Ok(None),
}
}
pub fn data_member_location_attribute<R: Reader<Offset = usize>>(
die: &DebuggingInformationEntry<R>,
) -> Result<Option<u64>> {
match die.attr_value(gimli::DW_AT_data_member_location)? {
Some(Udata(val)) => Ok(Some(val)),
Some(unknown) => {
error!("Unimplemented for {:?}", unknown);
Err(anyhow!("Unimplemented for {:?}", unknown))
}
_ => Ok(None),
}
}
pub fn type_attribute<R: Reader<Offset = usize>>(
dwarf: &gimli::Dwarf<R>,
unit: &Unit<R>,
die: &DebuggingInformationEntry<R>,
) -> Result<Option<(gimli::UnitSectionOffset, gimli::UnitOffset)>> {
match die.attr_value(gimli::DW_AT_type)? {
Some(gimli::AttributeValue::UnitRef(offset)) => Ok(Some((unit.header.offset(), offset))),
Some(gimli::AttributeValue::DebugInfoRef(di_offset)) => {
let offset = gimli::UnitSectionOffset::DebugInfoOffset(di_offset);
let mut iter = dwarf.debug_info.units();
while let Ok(Some(header)) = iter.next() {
let unit = dwarf.unit(header)?;
if let Some(offset) = offset.to_unit_offset(&unit) {
return Ok(Some((unit.header.offset(), offset)));
}
}
error!("Could not find type attribute value");
Ok(None)
}
_ => Ok(None),
}
}
pub fn address_class_attribute<R: Reader<Offset = usize>>(
die: &DebuggingInformationEntry<R>,
) -> Result<Option<DwAddr>> {
match die.attr_value(gimli::DW_AT_address_class)? {
Some(AddressClass(val)) => Ok(Some(val)),
Some(unknown) => {
error!("Unimplemented for {:?}", unknown);
Err(anyhow!("Unimplemented for {:?}", unknown))
}
_ => Ok(None),
}
}
pub fn const_value_attribute<R: Reader<Offset = usize>>(
die: &DebuggingInformationEntry<R>,
) -> Result<Option<u64>> {
Ok(match die.attr_value(gimli::DW_AT_const_value)? {
Some(Udata(val)) => Some(val),
Some(Sdata(val)) => Some(val as u64), Some(unknown) => {
error!("Unimplemented for {:?}", unknown);
return Err(anyhow!("Unimplemented for {:?}", unknown));
}
_ => None,
})
}
pub fn count_attribute<R: Reader<Offset = usize>>(
die: &DebuggingInformationEntry<R>,
) -> Result<Option<u64>> {
Ok(match die.attr_value(gimli::DW_AT_count)? {
Some(Udata(val)) => Some(val),
Some(Data1(val)) => Some(val as u64),
Some(Data2(val)) => Some(val as u64),
Some(Data4(val)) => Some(val as u64),
Some(Data8(val)) => Some(val),
Some(unknown) => {
error!("Unimplemented for {:?}", unknown);
return Err(anyhow!("Unimplemented for {:?}", unknown));
}
_ => None,
})
}
pub fn encoding_attribute<R: Reader<Offset = usize>>(
die: &DebuggingInformationEntry<R>,
) -> Result<Option<DwAte>> {
Ok(match die.attr_value(gimli::DW_AT_encoding)? {
Some(Encoding(val)) => Some(val),
Some(unknown) => {
error!("Unimplemented for {:?}", unknown);
return Err(anyhow!("Unimplemented for {:?}", unknown));
}
_ => None,
})
}
pub fn discr_attribute<R: Reader<Offset = usize>>(
die: &DebuggingInformationEntry<R>,
) -> Result<Option<gimli::UnitOffset>> {
Ok(match die.attr_value(gimli::DW_AT_discr)? {
Some(gimli::AttributeValue::UnitRef(offset)) => Some(offset),
Some(unknown) => {
error!("Unimplemented for {:?}", unknown);
return Err(anyhow!("Unimplemented for {:?}", unknown));
}
_ => None,
})
}
pub fn discr_value_attribute<R: Reader<Offset = usize>>(
die: &DebuggingInformationEntry<R>,
) -> Result<Option<u64>> {
Ok(match die.attr_value(gimli::DW_AT_discr_value)? {
Some(Data1(val)) => Some(val as u64),
Some(Udata(val)) => Some(val),
Some(unknown) => {
error!("Unimplemented for {:?}", unknown);
return Err(anyhow!("Unimplemented for {:?}", unknown));
}
_ => None,
})
}
pub fn lower_bound_attribute<R: Reader<Offset = usize>>(
die: &DebuggingInformationEntry<R>,
) -> Result<Option<u64>> {
Ok(match die.attr_value(gimli::DW_AT_lower_bound)? {
Some(Data1(val)) => Some(val as u64),
Some(Udata(val)) => Some(val),
Some(Sdata(val)) => Some(val as u64),
Some(unknown) => {
error!("Unimplemented for {:?}", unknown);
return Err(anyhow!("Unimplemented for {:?}", unknown));
}
_ => None,
})
}