+
Skip to content

Add support for reading items from .debug_macinfo #759

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
May 8, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
85 changes: 85 additions & 0 deletions crates/examples/src/bin/dwarfdump.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1142,6 +1142,7 @@ fn dump_entries<R: Reader, W: Write>(
flags: &Flags,
) -> Result<()> {
let mut spaces_buf = String::new();
let mut deferred_macinfo = Vec::new();

let mut entries = unit.entries_raw(None)?;
while !entries.is_empty() {
Expand Down Expand Up @@ -1186,9 +1187,23 @@ fn dump_entries<R: Reader, W: Write>(
writeln_error(w, unit.dwarf, err, "Failed to dump attribute value")?
}
};
// dump_attr_value only prints the offset for the macro info attribute.
// The content is too long to print inline, so store the offset to print later.
if attr.name() == gimli::DW_AT_macro_info {
if let gimli::AttributeValue::DebugMacinfoRef(offset) = attr.value() {
deferred_macinfo.push(offset);
}
}
}
}
}

for offset in deferred_macinfo {
writeln!(w)?;
writeln!(w, "Macros <.debug_macinfo+0x{:08x}>", offset.0)?;
dump_macinfo_list(w, unit, offset)?;
}

Ok(())
}

Expand Down Expand Up @@ -2266,3 +2281,73 @@ fn dump_addr<R: Reader, W: Write>(w: &mut W, debug_addr: &gimli::DebugAddr<R>) -
}
Ok(())
}

fn dump_macinfo_list<R: Reader, W: Write>(
w: &mut W,
unit: gimli::UnitRef<'_, R>,
offset: gimli::DebugMacinfoOffset,
) -> Result<()> {
let mut indent = 2; // base indent is 2 spaces
let mut macinfo_iter = unit.macinfo(offset)?;
while let Some(macinfo) = macinfo_iter.next()? {
match macinfo {
gimli::DebugMacInfoItem::StartFile { .. } => {
// print the item first, then indent
write!(w, "{:indent$}", "", indent = indent)?;
dump_macinfo(w, unit, macinfo)?;
indent += 2;
}
gimli::DebugMacInfoItem::EndFile => {
// unindent first, then print the item
indent -= 2;
write!(w, "{:indent$}", "", indent = indent)?;
dump_macinfo(w, unit, macinfo)?;
}
_ => {
// no indentation change
write!(w, "{:indent$}", "", indent = indent)?;
dump_macinfo(w, unit, macinfo)?;
}
}
}
Ok(())
}

fn dump_macinfo<R: Reader, W: Write>(
w: &mut W,
unit: gimli::UnitRef<'_, R>,
macinfo: gimli::DebugMacInfoItem<R>,
) -> Result<()> {
match macinfo {
gimli::DebugMacInfoItem::Define { line, text } => {
writeln!(
w,
"DW_MACINFO_define - lineno: {line}, macro: {}",
text.to_string_lossy()?
)?;
}
gimli::DebugMacInfoItem::Undef { line, name } => {
writeln!(
w,
"DW_MACINFO_undef - lineno: {line}, macro: {}",
name.to_string_lossy()?
)?;
}
gimli::DebugMacInfoItem::StartFile { line, file } => {
write!(w, "DW_MACINFO_start_file - lineno: {line}, file: ")?;
dump_file_index(w, file, unit)?;
writeln!(w)?;
}
gimli::DebugMacInfoItem::EndFile => {
writeln!(w, "DW_MACINFO_end_file")?;
}
gimli::DebugMacInfoItem::VendorExt { numeric, string } => {
writeln!(
w,
"DW_MACINFO_vendor_ext - number: {numeric}, string: {}",
string.to_string_lossy()?
)?;
}
}
Ok(())
}
20 changes: 20 additions & 0 deletions src/constants.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1402,6 +1402,26 @@ impl DwEhPe {
}
}

dw!(
/// Type codes for macro definitions in the `.debug_macinfo section`.
///
/// `.debug_macinfo` is defined in Dwarf 2, 3, and 4. Dwarf 5 defines `.debug_macro` instead.
/// See Section 7.22 (Macro Information) in the Dwarf 4 Standard.
DwMacInfo(u8) {
// "The series of entries for a given compilation unit ends with an entry containing a type code of 0"
DW_MACINFO_null = 0x00,
// macro definition; uses two operands: line number (LEB128) and the defined macro symbol (null terminated string)
DW_MACINFO_define = 0x01,
// macro undefinition; uses two operands: line number (LEB128) and the undefined macro symbol (null terminated string)
DW_MACINFO_undef = 0x02,
// The start of a new source file inclusion. Uses two operands: line number (LEB128) and an index into the line number table of the compilation unit (LEB128).
DW_MACINFO_start_file = 0x03,
// The end of the current source file inclusion. Has no operands.
DW_MACINFO_end_file = 0x04,
// Vendor specific macro information directives. Has two operands: a constant (LEB128) and a null terminated string, whose meaning is vendor specific.
DW_MACINFO_vendor_ext = 0xff,
});

#[cfg(test)]
mod tests {
use super::*;
Expand Down
46 changes: 37 additions & 9 deletions src/read/dwarf.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,20 +3,21 @@ use alloc::sync::Arc;

use crate::common::{
DebugAddrBase, DebugAddrIndex, DebugInfoOffset, DebugLineStrOffset, DebugLocListsBase,
DebugLocListsIndex, DebugRngListsBase, DebugRngListsIndex, DebugStrOffset, DebugStrOffsetsBase,
DebugStrOffsetsIndex, DebugTypeSignature, DebugTypesOffset, DwarfFileType, DwoId, Encoding,
LocationListsOffset, RangeListsOffset, RawRangeListsOffset, SectionId, UnitSectionOffset,
DebugLocListsIndex, DebugMacinfoOffset, DebugRngListsBase, DebugRngListsIndex, DebugStrOffset,
DebugStrOffsetsBase, DebugStrOffsetsIndex, DebugTypeSignature, DebugTypesOffset, DwarfFileType,
DwoId, Encoding, LocationListsOffset, RangeListsOffset, RawRangeListsOffset, SectionId,
UnitSectionOffset,
};
use crate::constants;
use crate::read::{
Abbreviations, AbbreviationsCache, AbbreviationsCacheStrategy, AttributeValue, DebugAbbrev,
DebugAddr, DebugAranges, DebugCuIndex, DebugInfo, DebugInfoUnitHeadersIter, DebugLine,
DebugLineStr, DebugLoc, DebugLocLists, DebugRanges, DebugRngLists, DebugStr, DebugStrOffsets,
DebugTuIndex, DebugTypes, DebugTypesUnitHeadersIter, DebuggingInformationEntry, EntriesCursor,
EntriesRaw, EntriesTree, Error, IncompleteLineProgram, IndexSectionId, LocListIter,
LocationLists, Range, RangeLists, RawLocListIter, RawRngListIter, Reader, ReaderOffset,
ReaderOffsetId, Result, RngListIter, Section, UnitHeader, UnitIndex, UnitIndexSectionIterator,
UnitOffset, UnitType,
DebugLineStr, DebugLoc, DebugLocLists, DebugMacInfo, DebugMacInfoIterator, DebugRanges,
DebugRngLists, DebugStr, DebugStrOffsets, DebugTuIndex, DebugTypes, DebugTypesUnitHeadersIter,
DebuggingInformationEntry, EntriesCursor, EntriesRaw, EntriesTree, Error,
IncompleteLineProgram, IndexSectionId, LocListIter, LocationLists, Range, RangeLists,
RawLocListIter, RawRngListIter, Reader, ReaderOffset, ReaderOffsetId, Result, RngListIter,
Section, UnitHeader, UnitIndex, UnitIndexSectionIterator, UnitOffset, UnitType,
};

/// All of the commonly used DWARF sections.
Expand Down Expand Up @@ -60,6 +61,8 @@ pub struct DwarfSections<T> {
pub debug_line: DebugLine<T>,
/// The `.debug_line_str` section.
pub debug_line_str: DebugLineStr<T>,
/// The `.debug_macinfo` section.
pub debug_macinfo: DebugMacInfo<T>,
/// The `.debug_str` section.
pub debug_str: DebugStr<T>,
/// The `.debug_str_offsets` section.
Expand Down Expand Up @@ -93,6 +96,7 @@ impl<T> DwarfSections<T> {
debug_info: Section::load(&mut section)?,
debug_line: Section::load(&mut section)?,
debug_line_str: Section::load(&mut section)?,
debug_macinfo: Section::load(&mut section)?,
debug_str: Section::load(&mut section)?,
debug_str_offsets: Section::load(&mut section)?,
debug_types: Section::load(&mut section)?,
Expand All @@ -115,6 +119,7 @@ impl<T> DwarfSections<T> {
debug_info: self.debug_info.borrow(&mut borrow),
debug_line: self.debug_line.borrow(&mut borrow),
debug_line_str: self.debug_line_str.borrow(&mut borrow),
debug_macinfo: self.debug_macinfo.borrow(&mut borrow),
debug_str: self.debug_str.borrow(&mut borrow),
debug_str_offsets: self.debug_str_offsets.borrow(&mut borrow),
debug_types: self.debug_types.borrow(&mut borrow),
Expand Down Expand Up @@ -177,6 +182,9 @@ pub struct Dwarf<R> {
/// The `.debug_line_str` section.
pub debug_line_str: DebugLineStr<R>,

/// The `.debug_macinfo` section.
pub debug_macinfo: DebugMacInfo<R>,

/// The `.debug_str` section.
pub debug_str: DebugStr<R>,

Expand Down Expand Up @@ -242,6 +250,7 @@ impl<T> Dwarf<T> {
debug_info: sections.debug_info,
debug_line: sections.debug_line,
debug_line_str: sections.debug_line_str,
debug_macinfo: sections.debug_macinfo,
debug_str: sections.debug_str,
debug_str_offsets: sections.debug_str_offsets,
debug_types: sections.debug_types,
Expand Down Expand Up @@ -292,6 +301,7 @@ impl<T> Dwarf<T> {
debug_info: self.debug_info.borrow(&mut borrow),
debug_line: self.debug_line.borrow(&mut borrow),
debug_line_str: self.debug_line_str.borrow(&mut borrow),
debug_macinfo: self.debug_macinfo.borrow(&mut borrow),
debug_str: self.debug_str.borrow(&mut borrow),
debug_str_offsets: self.debug_str_offsets.borrow(&mut borrow),
debug_types: self.debug_types.borrow(&mut borrow),
Expand Down Expand Up @@ -725,6 +735,14 @@ impl<R: Reader> Dwarf<R> {
}
err.description().into()
}

/// Return a fallible iterator over the macro information from `.debug_macinfo` for the given offset.
pub fn macinfo(
&self,
offset: DebugMacinfoOffset<R::Offset>,
) -> Result<DebugMacInfoIterator<R>> {
self.debug_macinfo.get_macinfo(offset)
}
}

impl<R: Clone> Dwarf<R> {
Expand Down Expand Up @@ -1074,6 +1092,7 @@ impl<R: Reader> DwarfPackage<R> {

let debug_aranges = self.empty.clone().into();
let debug_line_str = self.empty.clone().into();
let debug_macinfo = self.empty.clone().into();

Ok(Dwarf {
debug_abbrev,
Expand All @@ -1082,6 +1101,7 @@ impl<R: Reader> DwarfPackage<R> {
debug_info,
debug_line,
debug_line_str,
debug_macinfo,
debug_str,
debug_str_offsets,
debug_types,
Expand Down Expand Up @@ -1527,6 +1547,14 @@ impl<'a, R: Reader> UnitRef<'a, R> {
pub fn attr_locations(&self, attr: AttributeValue<R>) -> Result<Option<LocListIter<R>>> {
self.dwarf.attr_locations(self.unit, attr)
}

/// Try to return an iterator for the list of `DebugMacInfoItem` at the given offset.
pub fn macinfo(
&self,
offset: DebugMacinfoOffset<R::Offset>,
) -> Result<DebugMacInfoIterator<R>> {
self.dwarf.macinfo(offset)
}
}

impl<T: ReaderOffset> UnitSectionOffset<T> {
Expand Down
Loading
点击 这是indexloc提供的php浏览器服务,不要输入任何密码和下载