This commit is contained in:
nora 2023-02-12 11:11:53 +01:00
parent 478a3c15e1
commit 98eaa92612
6 changed files with 263 additions and 3 deletions

105
Cargo.lock generated
View file

@ -2,6 +2,12 @@
# It is not intended for manual editing.
version = 3
[[package]]
name = "anyhow"
version = "1.0.69"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "224afbd727c3d6e4b90103ece64b8d1b67fbb1973b1046c2281eed3f3803f800"
[[package]]
name = "bstr"
version = "1.2.0"
@ -14,6 +20,12 @@ dependencies = [
"serde",
]
[[package]]
name = "bytecount"
version = "0.6.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2c676a478f63e9fa2dd5368a42f28bba0d6c560b775f38583c8bbaa7fcd67c9c"
[[package]]
name = "bytemuck"
version = "1.13.0"
@ -34,6 +46,16 @@ dependencies = [
"syn",
]
[[package]]
name = "elven-forest"
version = "0.1.0"
dependencies = [
"anyhow",
"elven-parser",
"memmap2",
"tabled",
]
[[package]]
name = "elven-parser"
version = "0.1.0"
@ -44,6 +66,18 @@ dependencies = [
"thiserror",
]
[[package]]
name = "fnv"
version = "1.0.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1"
[[package]]
name = "heck"
version = "0.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8"
[[package]]
name = "libc"
version = "0.2.139"
@ -71,6 +105,41 @@ version = "1.17.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6f61fba1741ea2b3d6a1e3178721804bb716a68a6aeba1149b5d52e3d464ea66"
[[package]]
name = "papergrid"
version = "0.7.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1526bb6aa9f10ec339fb10360f22c57edf81d5678d0278e93bc12a47ffbe4b01"
dependencies = [
"bytecount",
"fnv",
"unicode-width",
]
[[package]]
name = "proc-macro-error"
version = "1.0.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38c"
dependencies = [
"proc-macro-error-attr",
"proc-macro2",
"quote",
"syn",
"version_check",
]
[[package]]
name = "proc-macro-error-attr"
version = "1.0.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869"
dependencies = [
"proc-macro2",
"quote",
"version_check",
]
[[package]]
name = "proc-macro2"
version = "1.0.51"
@ -112,6 +181,30 @@ dependencies = [
"unicode-ident",
]
[[package]]
name = "tabled"
version = "0.10.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "56c3ee73732ffceaea7b8f6b719ce3bb17f253fa27461ffeaf568ebd0cdb4b85"
dependencies = [
"papergrid",
"tabled_derive",
"unicode-width",
]
[[package]]
name = "tabled_derive"
version = "0.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "beca1b4eaceb4f2755df858b88d9b9315b7ccfd1ffd0d7a48a52602301f01a57"
dependencies = [
"heck",
"proc-macro-error",
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "thiserror"
version = "1.0.38"
@ -137,3 +230,15 @@ name = "unicode-ident"
version = "1.0.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "84a22b9f218b40614adcb3f4ff08b703773ad44fa9423e4e0d346d5db86e4ebc"
[[package]]
name = "unicode-width"
version = "0.1.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c0edd1e5b14653f783770bce4a4dabb4a5108a5370a5f5d8cfe8710c361f6c8b"
[[package]]
name = "version_check"
version = "0.9.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f"

View file

@ -1,2 +1,2 @@
[workspace]
members = ["elven-parser"]
members = ["elven-parser", "elven-forest"]

12
elven-forest/Cargo.toml Normal file
View file

@ -0,0 +1,12 @@
[package]
name = "elven-forest"
version = "0.1.0"
edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
anyhow = "1.0.69"
elven-parser = { path = "../elven-parser" }
memmap2 = "0.5.8"
tabled = "0.10.0"

119
elven-forest/src/main.rs Normal file
View file

@ -0,0 +1,119 @@
use std::{fmt::Display, fs::File};
use anyhow::Context;
use elven_parser::{
consts::{ShType, RX86_64},
defs::Elf,
ElfParseError,
};
use memmap2::Mmap;
use tabled::{object::Rows, Disable, Style, Table, Tabled};
fn main() -> anyhow::Result<()> {
let objs = std::env::args().skip(1);
for obj in objs {
print_file(&obj).with_context(|| format!("Failed to print {obj}"))?;
}
Ok(())
}
#[derive(Tabled)]
struct HeaderTable<'a>(&'static str, &'a dyn Display);
#[derive(Tabled)]
struct SectionTable {
name: String,
size: u64,
#[tabled(rename = "type")]
r#type: ShType,
}
#[derive(Tabled)]
struct RelaTable {
section: String,
symbol: String,
offset: u64,
#[tabled(rename = "type")]
r#type: RX86_64,
addend: u64,
}
fn print_file(path: &str) -> anyhow::Result<()> {
println!("{path}");
let file = File::open(path)?;
let mmap = unsafe { Mmap::map(&file) }?;
let elf = Elf::new(&mmap)?;
println!("\nHeader");
let header = elf.header()?;
let ident = header.ident;
let header_tab = vec![
HeaderTable("class", &ident.class),
HeaderTable("data", &ident.data),
HeaderTable("version", &ident.version),
HeaderTable("osabi", &ident.osabi),
HeaderTable("type", &header.r#type),
HeaderTable("machine", &header.machine),
HeaderTable("entrypoint (hex)", &header.entry),
];
let mut table = Table::new(header_tab);
// No header
table.with(Disable::row(Rows::first()));
print_table(table);
println!("\nSections");
let sections = elf
.section_headers()?
.iter()
.map(|sh| {
let name = elf.sh_string(sh.name)?.to_string();
Ok(SectionTable {
name,
size: sh.size,
r#type: sh.r#type,
})
})
.collect::<Result<Vec<_>, ElfParseError>>()?;
print_table(Table::new(sections));
println!("\nRelocations");
let relas = elf
.relas()?
.map(|(sh, rela)| {
let section = elf.sh_string(sh.name)?.to_string();
let sym = elf.symbol(rela.info.sym())?;
let symbol = elf.string(sym.name)?.to_string();
let offset = rela.offset.0;
let r#type = elven_parser::consts::RX86_64(rela.info.r#type());
let addend = rela.addend;
Ok(RelaTable {
section,
symbol,
offset,
r#type,
addend,
})
})
.collect::<Result<Vec<_>, ElfParseError>>()?;
print_table(Table::new(relas));
println!();
Ok(())
}
fn print_table(mut table: Table) {
table.with(Style::blank());
println!("{table}");
}

View file

@ -27,6 +27,18 @@ macro_rules! const_group_with_fmt {
}
}
impl std::fmt::Display for $struct_name {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self.0 {
$(
$value => f.write_str(stringify!($name)),
)*
a => write!(f, "{}({a})", $group_name)
}
}
}
impl PartialEq<$ty> for $struct_name {
fn eq(&self, other: &$ty) -> bool {
self.0 == *other

View file

@ -9,15 +9,27 @@ use crate::{
};
use bstr::BStr;
use std::{fmt::Debug, mem, string};
use std::{fmt::{Debug, Display}, mem, string};
use bytemuck::{Pod, PodCastError, Zeroable};
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Zeroable, Pod)]
#[derive(Clone, Copy, PartialEq, Eq, Hash, Zeroable, Pod)]
#[repr(transparent)]
pub struct Addr(pub u64);
impl Debug for Addr {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "{:x}", self.0)
}
}
impl Display for Addr {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "{:x}", self.0)
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Zeroable, Pod)]
#[repr(transparent)]
pub struct Offset(pub u64);