Refactor DWARF endian handling & some fixes

This commit is contained in:
Luke Street 2023-12-11 12:50:54 -05:00
parent 5f0befc69d
commit b2d0b124a5
3 changed files with 297 additions and 256 deletions

View File

@ -20,8 +20,6 @@ use crate::util::{
},
file::{buf_writer, map_file},
};
use crate::util::dwarf::ENDIAN;
use crate::util::reader::Endian;
#[derive(FromArgs, PartialEq, Debug)]
/// Commands for processing DWARF 1.1 information.
@ -111,11 +109,6 @@ fn dump(args: DumpArgs) -> Result<()> {
}
} else {
let obj_file = object::read::File::parse(buf)?;
// [.elf] e_ident.ei_data == ELFDATA2LSB
if obj_file.endianness() == object::Endianness::Little {
unsafe { ENDIAN = Endian::Little };
}
let debug_section = obj_file
.section_by_name(".debug")
.ok_or_else(|| anyhow!("Failed to locate .debug section"))?;
@ -138,8 +131,8 @@ fn dump_debug_section<W>(
obj_file: &object::File<'_>,
debug_section: Section,
) -> Result<()>
where
W: Write + ?Sized,
where
W: Write + ?Sized,
{
let mut data = debug_section.uncompressed_data()?.into_owned();
@ -162,14 +155,14 @@ fn dump_debug_section<W>(
}
let mut reader = Cursor::new(&*data);
let tags = read_debug_section(&mut reader)?;
let info = read_debug_section(&mut reader, obj_file.endianness().into())?;
for (&addr, tag) in &tags {
for (&addr, tag) in &info.tags {
log::debug!("{}: {:?}", addr, tag);
}
let mut units = Vec::<String>::new();
if let Some((_, mut tag)) = tags.first_key_value() {
if let Some((_, mut tag)) = info.tags.first_key_value() {
loop {
match tag.kind {
TagKind::CompileUnit => {
@ -183,10 +176,10 @@ fn dump_debug_section<W>(
}
writeln!(w, "\n// Compile unit: {}", unit)?;
let children = tag.children(&tags);
let children = tag.children(&info.tags);
let mut typedefs = BTreeMap::<u32, Vec<u32>>::new();
for child in children {
let tag_type = match process_root_tag(&tags, child) {
let tag_type = match process_root_tag(&info, child) {
Ok(tag_type) => tag_type,
Err(e) => {
log::error!(
@ -206,7 +199,7 @@ fn dump_debug_section<W>(
if should_skip_tag(&tag_type) {
continue;
}
match tag_type_string(&tags, &typedefs, &tag_type) {
match tag_type_string(&info, &typedefs, &tag_type) {
Ok(s) => writeln!(w, "{}", s)?,
Err(e) => {
log::error!(
@ -246,7 +239,7 @@ fn dump_debug_section<W>(
break;
}
}
if let Some(next) = tag.next_sibling(&tags) {
if let Some(next) = tag.next_sibling(&info.tags) {
tag = next;
} else {
break;

File diff suppressed because it is too large Load Diff

View File

@ -11,6 +11,15 @@ pub enum Endian {
Little,
}
impl From<object::Endianness> for Endian {
fn from(value: object::Endianness) -> Self {
match value {
object::Endianness::Big => Endian::Big,
object::Endianness::Little => Endian::Little,
}
}
}
pub const DYNAMIC_SIZE: usize = 0;
pub const fn struct_size<const N: usize>(fields: [usize; N]) -> usize {
@ -52,9 +61,23 @@ pub trait FromReader: Sized {
}
}
pub trait FromBytes<const N: usize>: Sized {
fn from_bytes(bytes: [u8; N], e: Endian) -> Self;
}
macro_rules! impl_from_reader {
($($t:ty),*) => {
$(
impl FromBytes<{ <$t>::STATIC_SIZE }> for $t {
#[inline]
fn from_bytes(bytes: [u8; Self::STATIC_SIZE], e: Endian) -> Self {
match e {
Endian::Big => Self::from_be_bytes(bytes),
Endian::Little => Self::from_le_bytes(bytes),
}
}
}
impl FromReader for $t {
const STATIC_SIZE: usize = std::mem::size_of::<Self>();
@ -65,10 +88,7 @@ macro_rules! impl_from_reader {
where R: Read + Seek + ?Sized {
let mut buf = [0u8; Self::STATIC_SIZE];
reader.read_exact(&mut buf)?;
Ok(match e {
Endian::Big => Self::from_be_bytes(buf),
Endian::Little => Self::from_le_bytes(buf),
})
Ok(Self::from_bytes(buf, e))
}
}
)*
@ -252,4 +272,4 @@ where
item.to_writer(writer, e)?;
}
Ok(())
}
}