1 //! A simple example of parsing `.debug_info`.
3 use object
::{Object, ObjectSection}
;
4 use std
::{borrow, env, fs}
;
7 for path
in env
::args().skip(1) {
8 let file
= fs
::File
::open(&path
).unwrap();
9 let mmap
= unsafe { memmap2::Mmap::map(&file).unwrap() }
;
10 let object
= object
::File
::parse(&*mmap
).unwrap();
11 let endian
= if object
.is_little_endian() {
12 gimli
::RunTimeEndian
::Little
14 gimli
::RunTimeEndian
::Big
16 dump_file(&object
, endian
).unwrap();
20 fn dump_file(object
: &object
::File
, endian
: gimli
::RunTimeEndian
) -> Result
<(), gimli
::Error
> {
21 // Load a section and return as `Cow<[u8]>`.
22 let load_section
= |id
: gimli
::SectionId
| -> Result
<borrow
::Cow
<[u8]>, gimli
::Error
> {
23 match object
.section_by_name(id
.name()) {
24 Some(ref section
) => Ok(section
26 .unwrap_or(borrow
::Cow
::Borrowed(&[][..]))),
27 None
=> Ok(borrow
::Cow
::Borrowed(&[][..])),
31 // Load all of the sections.
32 let dwarf_cow
= gimli
::Dwarf
::load(&load_section
)?
;
34 // Borrow a `Cow<[u8]>` to create an `EndianSlice`.
35 let borrow_section
: &dyn for<'a
> Fn(
36 &'a borrow
::Cow
<[u8]>,
37 ) -> gimli
::EndianSlice
<'a
, gimli
::RunTimeEndian
> =
38 &|section
| gimli
::EndianSlice
::new(&*section
, endian
);
40 // Create `EndianSlice`s for all of the sections.
41 let dwarf
= dwarf_cow
.borrow(&borrow_section
);
43 // Iterate over the compilation units.
44 let mut iter
= dwarf
.units();
45 while let Some(header
) = iter
.next()?
{
47 "Unit at <.debug_info+0x{:x}>",
48 header
.offset().as_debug_info_offset().unwrap().0
50 let unit
= dwarf
.unit(header
)?
;
52 // Iterate over the Debugging Information Entries (DIEs) in the unit.
54 let mut entries
= unit
.entries();
55 while let Some((delta_depth
, entry
)) = entries
.next_dfs()?
{
57 println
!("<{}><{:x}> {}", depth
, entry
.offset().0, entry
.tag());
59 // Iterate over the attributes in the DIE.
60 let mut attrs
= entry
.attrs();
61 while let Some(attr
) = attrs
.next()?
{
62 println
!(" {}: {:?}", attr
.name(), attr
.value());