Added: Switch for Little Endian DWARF Dump

This commit is contained in:
sewer56 2023-12-07 14:00:57 +00:00
parent 6cdf46b4fe
commit d142c9d6ba
2 changed files with 32 additions and 18 deletions

View File

@ -20,6 +20,8 @@ use crate::util::{
}, },
file::{buf_writer, map_file}, file::{buf_writer, map_file},
}; };
use crate::util::dwarf::ENDIAN;
use crate::util::reader::Endian;
#[derive(FromArgs, PartialEq, Debug)] #[derive(FromArgs, PartialEq, Debug)]
/// Commands for processing DWARF 1.1 information. /// Commands for processing DWARF 1.1 information.
@ -48,6 +50,9 @@ pub struct DumpArgs {
#[argp(switch)] #[argp(switch)]
/// Disable color output. /// Disable color output.
no_color: bool, no_color: bool,
/// Whether to use Little Endian for DWARF parsing.
#[argp(switch)]
little_endian: bool,
} }
pub fn run(args: Args) -> Result<()> { pub fn run(args: Args) -> Result<()> {
@ -66,6 +71,11 @@ fn dump(args: DumpArgs) -> Result<()> {
let theme = theme_set.themes.get("Solarized (dark)").context("Failed to load theme")?; let theme = theme_set.themes.get("Solarized (dark)").context("Failed to load theme")?;
let syntax = syntax_set.find_syntax_by_name("C++").context("Failed to find syntax")?.clone(); let syntax = syntax_set.find_syntax_by_name("C++").context("Failed to find syntax")?.clone();
// Set Endian
if args.little_endian {
unsafe { ENDIAN = Endian::Little };
}
let file = map_file(&args.in_file)?; let file = map_file(&args.in_file)?;
let buf = file.as_slice(); let buf = file.as_slice();
if buf.starts_with(b"!<arch>\n") { if buf.starts_with(b"!<arch>\n") {

View File

@ -17,7 +17,11 @@ use crate::{
}; };
use super::reader; use super::reader;
pub const ENDIAN: reader::Endian = Endian::Big; pub static mut ENDIAN: reader::Endian = Endian::Big;
pub fn get_endian() -> reader::Endian {
unsafe { ENDIAN }
}
#[derive(Debug, Eq, PartialEq, Copy, Clone, IntoPrimitive, TryFromPrimitive)] #[derive(Debug, Eq, PartialEq, Copy, Clone, IntoPrimitive, TryFromPrimitive)]
#[repr(u16)] #[repr(u16)]
@ -476,14 +480,14 @@ where R: BufRead + Seek + ?Sized {
break; break;
} }
let size = u32::from_reader(reader, ENDIAN)?; let size = u32::from_reader(reader, get_endian())?;
let version = u8::from_reader(reader, ENDIAN)?; let version = u8::from_reader(reader, get_endian())?;
ensure!(version == 1, "Expected version 1, got {version}"); ensure!(version == 1, "Expected version 1, got {version}");
let _debug_offs = u32::from_reader(reader, ENDIAN)?; let _debug_offs = u32::from_reader(reader, get_endian())?;
let _debug_size = u32::from_reader(reader, ENDIAN)?; let _debug_size = u32::from_reader(reader, get_endian())?;
while reader.stream_position()? < position + size as u64 { while reader.stream_position()? < position + size as u64 {
let _address = u32::from_reader(reader, ENDIAN)?; let _address = u32::from_reader(reader, get_endian())?;
let _length = u32::from_reader(reader, ENDIAN)?; let _length = u32::from_reader(reader, get_endian())?;
} }
} }
Ok(()) Ok(())
@ -492,7 +496,7 @@ where R: BufRead + Seek + ?Sized {
fn read_tag<R>(reader: &mut R) -> Result<Tag> fn read_tag<R>(reader: &mut R) -> Result<Tag>
where R: BufRead + Seek + ?Sized { where R: BufRead + Seek + ?Sized {
let position = reader.stream_position()?; let position = reader.stream_position()?;
let size = u32::from_reader(reader, ENDIAN)?; let size = u32::from_reader(reader, get_endian())?;
if size < 8 { if size < 8 {
// Null entry // Null entry
if size > 4 { if size > 4 {
@ -501,7 +505,7 @@ where R: BufRead + Seek + ?Sized {
return Ok(Tag { key: position as u32, kind: TagKind::Padding, attributes: vec![] }); return Ok(Tag { key: position as u32, kind: TagKind::Padding, attributes: vec![] });
} }
let tag_num = u16::from_reader(reader, ENDIAN)?; let tag_num = u16::from_reader(reader, get_endian())?;
let tag = TagKind::try_from(tag_num).context("Unknown DWARF tag type")?; let tag = TagKind::try_from(tag_num).context("Unknown DWARF tag type")?;
let mut attributes = Vec::new(); let mut attributes = Vec::new();
if tag == TagKind::Padding { if tag == TagKind::Padding {
@ -532,27 +536,27 @@ where R: BufRead + ?Sized {
fn read_attribute<R>(reader: &mut R) -> Result<Attribute> fn read_attribute<R>(reader: &mut R) -> Result<Attribute>
where R: BufRead + Seek + ?Sized { where R: BufRead + Seek + ?Sized {
let attr_type = u16::from_reader(reader, ENDIAN)?; let attr_type = u16::from_reader(reader, get_endian())?;
let attr = AttributeKind::try_from(attr_type).context("Unknown DWARF attribute type")?; let attr = AttributeKind::try_from(attr_type).context("Unknown DWARF attribute type")?;
let form = FormKind::try_from(attr_type & FORM_MASK).context("Unknown DWARF form type")?; let form = FormKind::try_from(attr_type & FORM_MASK).context("Unknown DWARF form type")?;
let value = match form { let value = match form {
FormKind::Addr => AttributeValue::Address(u32::from_reader(reader, ENDIAN)?), FormKind::Addr => AttributeValue::Address(u32::from_reader(reader, get_endian())?),
FormKind::Ref => AttributeValue::Reference(u32::from_reader(reader, ENDIAN)?), FormKind::Ref => AttributeValue::Reference(u32::from_reader(reader, get_endian())?),
FormKind::Block2 => { FormKind::Block2 => {
let size = u16::from_reader(reader, ENDIAN)?; let size = u16::from_reader(reader, get_endian())?;
let mut data = vec![0u8; size as usize]; let mut data = vec![0u8; size as usize];
reader.read_exact(&mut data)?; reader.read_exact(&mut data)?;
AttributeValue::Block(data) AttributeValue::Block(data)
} }
FormKind::Block4 => { FormKind::Block4 => {
let size = u32::from_reader(reader, ENDIAN)?; let size = u32::from_reader(reader, get_endian())?;
let mut data = vec![0u8; size as usize]; let mut data = vec![0u8; size as usize];
reader.read_exact(&mut data)?; reader.read_exact(&mut data)?;
AttributeValue::Block(data) AttributeValue::Block(data)
} }
FormKind::Data2 => AttributeValue::Data2(u16::from_reader(reader, ENDIAN)?), FormKind::Data2 => AttributeValue::Data2(u16::from_reader(reader, get_endian())?),
FormKind::Data4 => AttributeValue::Data4(u32::from_reader(reader, ENDIAN)?), FormKind::Data4 => AttributeValue::Data4(u32::from_reader(reader, get_endian())?),
FormKind::Data8 => AttributeValue::Data8(u64::from_reader(reader, ENDIAN)?), FormKind::Data8 => AttributeValue::Data8(u64::from_reader(reader, get_endian())?),
FormKind::String => AttributeValue::String(read_string(reader)?), FormKind::String => AttributeValue::String(read_string(reader)?),
}; };
Ok(Attribute { kind: attr, value }) Ok(Attribute { kind: attr, value })
@ -1724,7 +1728,7 @@ fn process_enumeration_tag(tags: &TagMap, tag: &Tag) -> Result<EnumerationType>
(AttributeKind::ElementList, AttributeValue::Block(data)) => { (AttributeKind::ElementList, AttributeValue::Block(data)) => {
let mut cursor = Cursor::new(data); let mut cursor = Cursor::new(data);
while cursor.position() < data.len() as u64 { while cursor.position() < data.len() as u64 {
let value = i32::from_reader(&mut cursor, ENDIAN)?; let value = i32::from_reader(&mut cursor, get_endian())?;
let name = read_string(&mut cursor)?; let name = read_string(&mut cursor)?;
members.push(EnumerationMember { name, value }); members.push(EnumerationMember { name, value });
} }