This commit is contained in:
nora 2023-05-07 13:15:01 +02:00
parent e998012a18
commit 40af8cd09f
2 changed files with 55 additions and 19 deletions

View file

@ -32,6 +32,8 @@ struct Opts {
dyns: bool, dyns: bool,
#[arg(long("text-bloat"))] #[arg(long("text-bloat"))]
text_bloat: bool, text_bloat: bool,
#[arg(long("csv"))]
csv: bool,
files: Vec<PathBuf>, files: Vec<PathBuf>,
} }
@ -258,7 +260,7 @@ fn print_file(opts: &Opts, path: &Path) -> anyhow::Result<()> {
} }
if opts.text_bloat { if opts.text_bloat {
size::analyze_text_bloat(elf)?; size::analyze_text_bloat(elf, opts.csv)?;
} }
println!(); println!();

View file

@ -1,7 +1,9 @@
use std::borrow::Cow;
use anyhow::{Context, Result}; use anyhow::{Context, Result};
use elven_parser::read::ElfReader; use elven_parser::read::ElfReader;
pub fn analyze_text_bloat(elf: ElfReader<'_>) -> Result<()> { pub fn analyze_text_bloat(elf: ElfReader<'_>, csv: bool) -> Result<()> {
let text = elf let text = elf
.section_header_by_name(b".text") .section_header_by_name(b".text")
.context(".text not found")?; .context(".text not found")?;
@ -33,31 +35,66 @@ pub fn analyze_text_bloat(elf: ElfReader<'_>) -> Result<()> {
symbol_sizes.sort_by_key(|&(_, size)| size); symbol_sizes.sort_by_key(|&(_, size)| size);
symbol_sizes.reverse(); symbol_sizes.reverse();
for (sym, size) in symbol_sizes { let depth = 3;
let components =
symbol_components(std::str::from_utf8(sym)?).with_context(|| sym.to_string())?;
if csv {
println!(
"size,{}",
(1..=depth)
.map(|x| x.to_string())
.collect::<Vec<_>>()
.join(",")
);
}
for (sym, size) in symbol_sizes {
let components = symbol_components(std::str::from_utf8(sym)?, depth, csv)
.with_context(|| sym.to_string())?;
if csv {
println!("{size},{components}");
} else {
}
println!("{size} {components}"); println!("{size} {components}");
} }
Ok(()) Ok(())
} }
fn symbol_components(sym: &str) -> Result<String> { fn symbol_components(sym: &str, depth: usize, csv: bool) -> Result<String> {
let demangled = rustc_demangle::demangle(sym).to_string(); let demangled = rustc_demangle::demangle(sym).to_string();
if demangled.starts_with('<') { if !csv {
let qpath = parse_qpath(&demangled).context("invalid qpath")?; return Ok(demangled);
let components = qpath_components(qpath)?; }
// qpath let mut components = if demangled.starts_with('<') {
return Ok(components.join(",")); let qpath = parse_qpath(&demangled).context("invalid qpath")?;
qpath_components(qpath)?
} else { } else {
// normal path // normal path
let components = demangled.split("::").collect::<Vec<_>>(); demangled.split("::").collect::<Vec<_>>()
let path = components.join(","); };
return Ok(path);
if components.len() >= depth {
components.truncate(depth);
} else {
components.extend(std::iter::repeat("").take(depth - components.len()));
} }
let components = components
.into_iter()
.map(|c| {
if c.contains(",") {
Cow::Owned(format!("\"{c}\""))
} else {
Cow::Borrowed(c)
}
})
.collect::<Vec<_>>();
// qpath
return Ok(components.join(","));
} }
#[derive(Debug, Clone, Copy, PartialEq)] #[derive(Debug, Clone, Copy, PartialEq)]
@ -165,11 +202,8 @@ mod tests {
fn path_debug_helper() { fn path_debug_helper() {
// <<std::path::Components as core::fmt::Debug>::fmt::DebugHelper as core::fmt::Debug>::fmt::h4f87ac80fb33df05 // <<std::path::Components as core::fmt::Debug>::fmt::DebugHelper as core::fmt::Debug>::fmt::h4f87ac80fb33df05
let sym = "_ZN106_$LT$$LT$std..path..Iter$u20$as$u20$core..fmt..Debug$GT$..fmt..DebugHelper$u20$as$u20$core..fmt..Debug$GT$3fmt17h4f87ac80fb33df05E"; let sym = "_ZN106_$LT$$LT$std..path..Iter$u20$as$u20$core..fmt..Debug$GT$..fmt..DebugHelper$u20$as$u20$core..fmt..Debug$GT$3fmt17h4f87ac80fb33df05E";
let components = symbol_components(sym).unwrap(); let components = symbol_components(sym, 6).unwrap();
assert_eq!( assert_eq!(components, "std,path,Iter,fmt,DebugHelper,fmt")
components,
"std,path,Iter,fmt,DebugHelper,fmt,h4f87ac80fb33df05"
)
} }
} }