From 4f9fe856a25ab29345b90e7725509e9ee38a37be Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Wed, 17 Apr 2024 14:19:41 +0200 Subject: Adding upstream version 1.69.0+dfsg1. Signed-off-by: Daniel Baumann --- vendor/gimli-0.26.2/examples/simple_line.rs | 106 ++++++++++++++++++++++++++++ 1 file changed, 106 insertions(+) create mode 100644 vendor/gimli-0.26.2/examples/simple_line.rs (limited to 'vendor/gimli-0.26.2/examples/simple_line.rs') diff --git a/vendor/gimli-0.26.2/examples/simple_line.rs b/vendor/gimli-0.26.2/examples/simple_line.rs new file mode 100644 index 000000000..87b224cda --- /dev/null +++ b/vendor/gimli-0.26.2/examples/simple_line.rs @@ -0,0 +1,106 @@ +//! A simple example of parsing `.debug_line`. + +use object::{Object, ObjectSection}; +use std::{borrow, env, fs, path}; + +fn main() { + for path in env::args().skip(1) { + let file = fs::File::open(&path).unwrap(); + let mmap = unsafe { memmap2::Mmap::map(&file).unwrap() }; + let object = object::File::parse(&*mmap).unwrap(); + let endian = if object.is_little_endian() { + gimli::RunTimeEndian::Little + } else { + gimli::RunTimeEndian::Big + }; + dump_file(&object, endian).unwrap(); + } +} + +fn dump_file(object: &object::File, endian: gimli::RunTimeEndian) -> Result<(), gimli::Error> { + // Load a section and return as `Cow<[u8]>`. + let load_section = |id: gimli::SectionId| -> Result, gimli::Error> { + match object.section_by_name(id.name()) { + Some(ref section) => Ok(section + .uncompressed_data() + .unwrap_or(borrow::Cow::Borrowed(&[][..]))), + None => Ok(borrow::Cow::Borrowed(&[][..])), + } + }; + + // Load all of the sections. + let dwarf_cow = gimli::Dwarf::load(&load_section)?; + + // Borrow a `Cow<[u8]>` to create an `EndianSlice`. + let borrow_section: &dyn for<'a> Fn( + &'a borrow::Cow<[u8]>, + ) -> gimli::EndianSlice<'a, gimli::RunTimeEndian> = + &|section| gimli::EndianSlice::new(&*section, endian); + + // Create `EndianSlice`s for all of the sections. + let dwarf = dwarf_cow.borrow(&borrow_section); + + // Iterate over the compilation units. + let mut iter = dwarf.units(); + while let Some(header) = iter.next()? { + println!( + "Line number info for unit at <.debug_info+0x{:x}>", + header.offset().as_debug_info_offset().unwrap().0 + ); + let unit = dwarf.unit(header)?; + + // Get the line program for the compilation unit. + if let Some(program) = unit.line_program.clone() { + let comp_dir = if let Some(ref dir) = unit.comp_dir { + path::PathBuf::from(dir.to_string_lossy().into_owned()) + } else { + path::PathBuf::new() + }; + + // Iterate over the line program rows. + let mut rows = program.rows(); + while let Some((header, row)) = rows.next_row()? { + if row.end_sequence() { + // End of sequence indicates a possible gap in addresses. + println!("{:x} end-sequence", row.address()); + } else { + // Determine the path. Real applications should cache this for performance. + let mut path = path::PathBuf::new(); + if let Some(file) = row.file(header) { + path = comp_dir.clone(); + + // The directory index 0 is defined to correspond to the compilation unit directory. + if file.directory_index() != 0 { + if let Some(dir) = file.directory(header) { + path.push( + dwarf.attr_string(&unit, dir)?.to_string_lossy().as_ref(), + ); + } + } + + path.push( + dwarf + .attr_string(&unit, file.path_name())? + .to_string_lossy() + .as_ref(), + ); + } + + // Determine line/column. DWARF line/column is never 0, so we use that + // but other applications may want to display this differently. + let line = match row.line() { + Some(line) => line.get(), + None => 0, + }; + let column = match row.column() { + gimli::ColumnType::LeftEdge => 0, + gimli::ColumnType::Column(column) => column.get(), + }; + + println!("{:x} {}:{}:{}", row.address(), path.display(), line, column); + } + } + } + } + Ok(()) +} -- cgit v1.2.3