mirror of
https://github.com/Noratrieb/elven-forest.git
synced 2026-03-14 21:26:04 +01:00
csv
This commit is contained in:
parent
e998012a18
commit
40af8cd09f
2 changed files with 55 additions and 19 deletions
|
|
@ -32,6 +32,8 @@ struct Opts {
|
|||
dyns: bool,
|
||||
#[arg(long("text-bloat"))]
|
||||
text_bloat: bool,
|
||||
#[arg(long("csv"))]
|
||||
csv: bool,
|
||||
files: Vec<PathBuf>,
|
||||
}
|
||||
|
||||
|
|
@ -258,7 +260,7 @@ fn print_file(opts: &Opts, path: &Path) -> anyhow::Result<()> {
|
|||
}
|
||||
|
||||
if opts.text_bloat {
|
||||
size::analyze_text_bloat(elf)?;
|
||||
size::analyze_text_bloat(elf, opts.csv)?;
|
||||
}
|
||||
|
||||
println!();
|
||||
|
|
|
|||
|
|
@ -1,7 +1,9 @@
|
|||
use std::borrow::Cow;
|
||||
|
||||
use anyhow::{Context, Result};
|
||||
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
|
||||
.section_header_by_name(b".text")
|
||||
.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.reverse();
|
||||
|
||||
for (sym, size) in symbol_sizes {
|
||||
let components =
|
||||
symbol_components(std::str::from_utf8(sym)?).with_context(|| sym.to_string())?;
|
||||
let depth = 3;
|
||||
|
||||
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}");
|
||||
}
|
||||
|
||||
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();
|
||||
|
||||
if demangled.starts_with('<') {
|
||||
if !csv {
|
||||
return Ok(demangled);
|
||||
}
|
||||
|
||||
let mut components = if demangled.starts_with('<') {
|
||||
let qpath = parse_qpath(&demangled).context("invalid qpath")?;
|
||||
let components = qpath_components(qpath)?;
|
||||
qpath_components(qpath)?
|
||||
} else {
|
||||
// normal path
|
||||
demangled.split("::").collect::<Vec<_>>()
|
||||
};
|
||||
|
||||
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(","));
|
||||
} else {
|
||||
// normal path
|
||||
let components = demangled.split("::").collect::<Vec<_>>();
|
||||
let path = components.join(",");
|
||||
return Ok(path);
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy, PartialEq)]
|
||||
|
|
@ -165,11 +202,8 @@ mod tests {
|
|||
fn path_debug_helper() {
|
||||
// <<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 components = symbol_components(sym).unwrap();
|
||||
let components = symbol_components(sym, 6).unwrap();
|
||||
|
||||
assert_eq!(
|
||||
components,
|
||||
"std,path,Iter,fmt,DebugHelper,fmt,h4f87ac80fb33df05"
|
||||
)
|
||||
assert_eq!(components, "std,path,Iter,fmt,DebugHelper,fmt")
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue