This commit is contained in:
nora 2023-02-21 12:24:53 +01:00
parent d849e07c58
commit e8195f32f6
3 changed files with 149 additions and 111 deletions

5
Cargo.lock generated
View file

@ -66,9 +66,9 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
[[package]] [[package]]
name = "clap" name = "clap"
version = "4.1.4" version = "4.1.6"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f13b9c79b5d1dd500d20ef541215a6423c75829ef43117e1b4d17fd8af0b5d76" checksum = "ec0b0588d44d4d63a87dbd75c136c166bbfd9a86a31cb89e09906521c7d3f5e3"
dependencies = [ dependencies = [
"bitflags", "bitflags",
"clap_derive", "clap_derive",
@ -106,6 +106,7 @@ name = "elven-forest"
version = "0.1.0" version = "0.1.0"
dependencies = [ dependencies = [
"anyhow", "anyhow",
"clap",
"elven-parser", "elven-parser",
"memmap2", "memmap2",
"tabled", "tabled",

View file

@ -7,6 +7,7 @@ edition = "2021"
[dependencies] [dependencies]
anyhow = "1.0.69" anyhow = "1.0.69"
clap = { version = "4.1.6", features = ["derive"] }
elven-parser = { path = "../elven-parser" } elven-parser = { path = "../elven-parser" }
memmap2 = "0.5.8" memmap2 = "0.5.8"
tabled = "0.10.0" tabled = "0.10.0"

View file

@ -1,6 +1,11 @@
use std::{fmt::Display, fs::File}; use std::{
fmt::Display,
fs::File,
path::{Path, PathBuf},
};
use anyhow::Context; use anyhow::Context;
use clap::Parser;
use elven_parser::{ use elven_parser::{
consts::{self as c, DynamicTag, PhFlags, PhType, ShFlags, ShType, SymbolVisibility, RX86_64}, consts::{self as c, DynamicTag, PhFlags, PhType, ShFlags, ShType, SymbolVisibility, RX86_64},
read::{ElfReadError, ElfReader, Sym, SymInfo}, read::{ElfReadError, ElfReader, Sym, SymInfo},
@ -9,11 +14,29 @@ use elven_parser::{
use memmap2::Mmap; use memmap2::Mmap;
use tabled::{object::Rows, Disable, Style, Table, Tabled}; use tabled::{object::Rows, Disable, Style, Table, Tabled};
fn main() -> anyhow::Result<()> { #[derive(Parser)]
let objs = std::env::args().skip(1); struct Opts {
#[arg(long("file-header"), long("header"))]
header: bool,
#[arg(short('l'), long("program-headers"), long("segments"))]
program_headers: bool,
#[arg(short('S'), long("section-headers"), long("sections"))]
section_headers: bool,
#[arg(short('s'), long("symbols"), long("syms"))]
symbols: bool,
#[arg(short('r'), long("relocs"))]
relocs: bool,
/// Not in readelf.
#[arg(short('d'), long("dyns"))]
dyns: bool,
files: Vec<PathBuf>,
}
for obj in objs { fn main() -> anyhow::Result<()> {
print_file(&obj).with_context(|| format!("Failed to print {obj}"))?; let opts = Opts::parse();
for obj in &opts.files {
print_file(&opts, obj).with_context(|| format!("Failed to print {}", obj.display()))?;
} }
Ok(()) Ok(())
@ -76,14 +99,15 @@ struct DynTable {
value: Addr, value: Addr,
} }
fn print_file(path: &str) -> anyhow::Result<()> { fn print_file(opts: &Opts, path: &Path) -> anyhow::Result<()> {
println!("{path}"); println!("{}", path.display());
let file = File::open(path)?; let file = File::open(path)?;
let mmap = unsafe { Mmap::map(&file) }?; let mmap = unsafe { Mmap::map(&file) }?;
let elf = ElfReader::new(&mmap)?; let elf = ElfReader::new(&mmap)?;
if opts.header {
println!("\nHeader"); println!("\nHeader");
let header = elf.header()?; let header = elf.header()?;
@ -105,7 +129,9 @@ fn print_file(path: &str) -> anyhow::Result<()> {
// No header // No header
table.with(Disable::row(Rows::first())); table.with(Disable::row(Rows::first()));
print_table(table); print_table(table);
}
if opts.section_headers {
println!("\nSections"); println!("\nSections");
let sections = elf let sections = elf
@ -124,14 +150,17 @@ fn print_file(path: &str) -> anyhow::Result<()> {
.collect::<Result<Vec<_>, ElfReadError>>()?; .collect::<Result<Vec<_>, ElfReadError>>()?;
print_table(Table::new(sections)); print_table(Table::new(sections));
}
if opts.program_headers {
println!("\nProgram headers"); println!("\nProgram headers");
let sections = elf let sections = elf
.program_headers()? .program_headers()?
.iter() .iter()
.map(|ph| { .map(|ph| {
let (inside_section, inside_section_offset) = section_name_of_offset(elf, ph.offset)?; let (inside_section, inside_section_offset) =
section_name_of_offset(elf, ph.offset)?;
Ok(ProgramHeaderTable { Ok(ProgramHeaderTable {
r#type: ph.r#type, r#type: ph.r#type,
@ -149,7 +178,9 @@ fn print_file(path: &str) -> anyhow::Result<()> {
.collect::<Result<Vec<_>, ElfReadError>>()?; .collect::<Result<Vec<_>, ElfReadError>>()?;
print_table(Table::new(sections)); print_table(Table::new(sections));
}
if opts.symbols {
println!("\nSymbols"); println!("\nSymbols");
let symbols = elf let symbols = elf
@ -176,7 +207,9 @@ fn print_file(path: &str) -> anyhow::Result<()> {
.collect::<Result<Vec<_>, ElfReadError>>()?; .collect::<Result<Vec<_>, ElfReadError>>()?;
print_table(Table::new(symbols)); print_table(Table::new(symbols));
}
if opts.relocs {
println!("\nRelocations"); println!("\nRelocations");
let relas = elf let relas = elf
@ -203,7 +236,9 @@ fn print_file(path: &str) -> anyhow::Result<()> {
.collect::<Result<Vec<_>, ElfReadError>>()?; .collect::<Result<Vec<_>, ElfReadError>>()?;
print_table(Table::new(relas)); print_table(Table::new(relas));
}
if opts.dyns {
if let Ok(dyns) = elf.dyn_entries() { if let Ok(dyns) = elf.dyn_entries() {
println!("\nDynamic entries"); println!("\nDynamic entries");
@ -213,6 +248,7 @@ fn print_file(path: &str) -> anyhow::Result<()> {
}); });
print_table(Table::new(dyns)); print_table(Table::new(dyns));
} }
}
println!(); println!();