diff --git a/elven-forest/src/main.rs b/elven-forest/src/main.rs index 854397e..46e398f 100644 --- a/elven-forest/src/main.rs +++ b/elven-forest/src/main.rs @@ -2,8 +2,8 @@ use std::{fmt::Display, fs::File}; use anyhow::Context; use elven_parser::{ - consts::{self as c, DynamicTag, ShType, RX86_64}, - defs::{Addr, Elf}, + consts::{self as c, DynamicTag, ShType, SymbolVisibility, RX86_64}, + defs::{Addr, Elf, Sym, SymInfo}, ElfParseError, }; use memmap2::Mmap; @@ -31,6 +31,16 @@ struct SectionTable { offset: u64, } +#[derive(Tabled)] +struct SymbolTable { + name: String, + info: SymInfo, + other: SymbolVisibility, + section: String, + value: Addr, + size: u64, +} + #[derive(Tabled)] struct RelaTable { section: String, @@ -92,6 +102,34 @@ fn print_file(path: &str) -> anyhow::Result<()> { print_table(Table::new(sections)); + println!("\nSymbols"); + + let symbols = elf + .symbols()? + .iter() + .map(|sym| { + let name = sym_display_name(elf, sym)?; + let section = match sym.shndx.0 { + c::SHN_ABS => " ".to_string(), + c::SHN_COMMON => "".to_string(), + _ => elf + .sh_string(elf.section_header(sym.shndx)?.name)? + .to_string(), + }; + + Ok(SymbolTable { + name, + info: sym.info, + other: sym.other, + section, + size: sym.size, + value: sym.value, + }) + }) + .collect::, ElfParseError>>()?; + + print_table(Table::new(symbols)); + println!("\nRelocations"); let relas = elf @@ -101,12 +139,7 @@ fn print_file(path: &str) -> anyhow::Result<()> { let sym = elf.symbol(rela.info.sym())?; - let symbol = if sym.info.r#type() == c::STT_SECTION { - elf.sh_string(elf.section_header(sym.shndx)?.name)? - .to_string() - } else { - elf.string(sym.name)?.to_string() - }; + let symbol = sym_display_name(elf, sym)?; let offset = Addr(rela.offset.0); let r#type = c::RX86_64(rela.info.r#type()); @@ -139,6 +172,15 @@ fn print_file(path: &str) -> anyhow::Result<()> { Ok(()) } +fn sym_display_name(elf: Elf<'_>, sym: &Sym) -> Result { + Ok(if sym.info.r#type() == c::STT_SECTION { + elf.sh_string(elf.section_header(sym.shndx)?.name)? + .to_string() + } else { + elf.string(sym.name)?.to_string() + }) +} + fn print_table(mut table: Table) { table.with(Style::blank()); println!("{table}"); diff --git a/elven-parser/src/defs.rs b/elven-parser/src/defs.rs index ccfdbcf..0307ebc 100644 --- a/elven-parser/src/defs.rs +++ b/elven-parser/src/defs.rs @@ -56,7 +56,7 @@ define_idx! { } /// A raw ELF. Does not come with cute ears for now. -#[derive(Debug)] +#[derive(Debug, Clone, Copy)] pub struct Elf<'a> { pub data: &'a [u8], } @@ -153,6 +153,12 @@ impl Debug for SymInfo { } } +impl Display for SymInfo { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!(f, "{:?},{:?}", self.r#type(), self.binding()) + } +} + #[derive(Debug, Clone, Copy, Zeroable, Pod)] #[repr(C)] pub struct Rel { diff --git a/test_data/calls_obj.c b/test_data/calls_obj.c new file mode 100644 index 0000000..dda4c80 --- /dev/null +++ b/test_data/calls_obj.c @@ -0,0 +1,12 @@ +#include + +int uwu() +{ + return 1; +} + +int main(int argc, char **argv) +{ + printf("%d", uwu()); + return 0; +} diff --git a/test_data/create_test_data.sh b/test_data/create_test_data.sh index 5718db9..591f3d0 100755 --- a/test_data/create_test_data.sh +++ b/test_data/create_test_data.sh @@ -8,6 +8,9 @@ for rust_file in $SCRIPT_DIR/*.rs; do done for c_obj_file in $SCRIPT_DIR/*_obj.c; do - echo $c_obj_file - cc "$c_obj_file" -c -o "$SCRIPT_DIR/out/$(basename $c_obj_file .c)" + cc "$c_obj_file" -c -o "$SCRIPT_DIR/out/$(basename $c_obj_file .c).o" +done + +for asm_file in $SCRIPT_DIR/*.asm; do + nasm "$asm_file" -felf64 -o "$SCRIPT_DIR/out/$(basename $asm_file .asm).o" done diff --git a/test_data/empty.asm b/test_data/empty.asm new file mode 100644 index 0000000..e20cc18 --- /dev/null +++ b/test_data/empty.asm @@ -0,0 +1,7 @@ +global _start + + section .text +_start: + mov rax, 60 + mov rdi, 0 + syscall \ No newline at end of file diff --git a/test_data/hello_world.rs b/test_data/hello_world.rs index f029519..0672e51 100644 --- a/test_data/hello_world.rs +++ b/test_data/hello_world.rs @@ -1,3 +1,3 @@ fn main() { println!("Hello, World!"); -} \ No newline at end of file +} diff --git a/test_data/hello_world_obj.c b/test_data/hello_world_obj.c index c866607..9321f4f 100644 --- a/test_data/hello_world_obj.c +++ b/test_data/hello_world_obj.c @@ -1,6 +1,7 @@ -#include +#include -int main(int argc, char **argv) { +int main(int argc, char **argv) +{ puts("Hello, World!"); return 0; }