Skip to content

Instantly share code, notes, and snippets.

@nbdd0121

nbdd0121/main.rs Secret

Created August 7, 2024 19:29
Show Gist options
  • Save nbdd0121/449692570622c2f46a29ad9f47c3379a to your computer and use it in GitHub Desktop.
Save nbdd0121/449692570622c2f46a29ad9f47c3379a to your computer and use it in GitHub Desktop.
Find noreturn symbols from object files
#!/usr/bin/env -S cargo -Zscript
---
[dependencies]
object = "0.36"
gimli = "0.31"
---
use gimli::read::EndianSlice;
use object::{Object, ObjectSection};
use std::error::Error;
fn main() -> Result<(), Box<dyn Error>> {
let name = std::env::args()
.skip(1)
.next()
.ok_or_else(|| "no argument")?;
let data = std::fs::read(&name)?;
let file = object::File::parse(&*data)?;
let loader = |section: gimli::SectionId| -> Result<_, Box<dyn Error>> {
let data = match file.section_by_name(section.name()) {
Some(section) => section.data()?,
None => &[],
};
Ok(EndianSlice::new(data, gimli::LittleEndian))
};
let dwarf = gimli::Dwarf::load(loader)?;
let mut iter = dwarf.units();
while let Some(header) = iter.next()? {
let unit = dwarf.unit(header)?;
let mut entries = unit.entries();
while let Some((_, entry)) = entries.next_dfs()? {
if entry.tag() == gimli::DW_TAG_subprogram {
let Some(attr) = entry.attr(gimli::DW_AT_linkage_name)? else {
continue;
};
let name = attr
.string_value(&dwarf.debug_str)
.ok_or_else(|| "name is not str?")?
.to_string()?;
if let Some(attr) = entry.attr(gimli::DW_AT_noreturn)? {
if matches!(attr.value(), gimli::read::AttributeValue::Flag(true)) {
println!("{name}");
}
}
}
}
}
Ok(())
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment