diff --git a/elven-forest/src/main.rs b/elven-forest/src/main.rs index fc3a2b5..8b329df 100644 --- a/elven-forest/src/main.rs +++ b/elven-forest/src/main.rs @@ -3,7 +3,8 @@ use std::{fmt::Display, fs::File}; use anyhow::Context; use elven_parser::{ consts::{self as c, DynamicTag, PhFlags, PhType, ShFlags, ShType, SymbolVisibility, RX86_64}, - read::{Addr, ElfReadError, ElfReader, Offset, Sym, SymInfo}, + read::{ElfReadError, ElfReader, Sym, SymInfo}, + Addr, Offset, }; use memmap2::Mmap; use tabled::{object::Rows, Disable, Style, Table, Tabled}; @@ -21,13 +22,16 @@ fn main() -> anyhow::Result<()> { #[derive(Tabled)] struct HeaderTable<'a>(&'static str, &'a dyn Display); +// Not really an addr but just display it as hex. +type Hex = Addr; + #[derive(Tabled)] struct SectionTable { name: String, #[tabled(rename = "type")] r#type: ShType, - size: Addr, - offset: Addr, + size: Hex, + offset: Offset, flags: ShFlags, } @@ -36,14 +40,14 @@ struct ProgramHeaderTable { #[tabled(rename = "type")] r#type: PhType, flags: PhFlags, - offset: Addr, + offset: Offset, virtual_addr: Addr, phys_addr: Addr, - file_size: Addr, - mem_size: Addr, - align: Addr, + file_size: Hex, + mem_size: Hex, + align: Hex, inside_section: String, - inside_section_offset: Addr, + inside_section_offset: Offset, } #[derive(Tabled)] @@ -113,7 +117,7 @@ fn print_file(path: &str) -> anyhow::Result<()> { name, r#type: sh.r#type, size: Addr(sh.size), - offset: Addr(sh.offset.0), + offset: sh.offset, flags: sh.flags, }) }) @@ -132,14 +136,14 @@ fn print_file(path: &str) -> anyhow::Result<()> { Ok(ProgramHeaderTable { r#type: ph.r#type, flags: ph.flags, - offset: Addr(ph.offset.0), + offset: ph.offset, virtual_addr: ph.vaddr, phys_addr: ph.paddr, file_size: Addr(ph.filesz), mem_size: Addr(ph.memsz), align: Addr(ph.align), inside_section, - inside_section_offset: Addr(inside_section_offset), + inside_section_offset: Offset(inside_section_offset), }) }) .collect::, ElfReadError>>()?; diff --git a/elven-parser/src/lib.rs b/elven-parser/src/lib.rs index 7cbf244..095c7ec 100644 --- a/elven-parser/src/lib.rs +++ b/elven-parser/src/lib.rs @@ -1,6 +1,45 @@ #![allow(clippy::must_use_candidate, clippy::missing_errors_doc)] +use std::fmt::{Debug, Display}; + +use bytemuck::{Pod, Zeroable}; +use idx::ToIdxUsize; + pub mod consts; mod idx; pub mod read; pub mod write; + +/// A _run time_ address inside an object file. +#[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, "0x{:x}", self.0) + } +} + +impl Display for Addr { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!(f, "0x{:x}", self.0) + } +} + +/// An offset into an object file. Either absolut or relative to a particular section. +#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Zeroable, Pod)] +#[repr(transparent)] +pub struct Offset(pub u64); + +impl ToIdxUsize for Offset { + fn to_idx_usize(self) -> usize { + self.0.to_idx_usize() + } +} + +impl Display for Offset { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!(f, "0x{:x}", self.0) + } +} diff --git a/elven-parser/src/read.rs b/elven-parser/src/read.rs index ad83360..e5bed83 100644 --- a/elven-parser/src/read.rs +++ b/elven-parser/src/read.rs @@ -5,6 +5,7 @@ use crate::{ consts::{self as c, DynamicTag, ShType}, idx::{define_idx, ElfIndexExt, ToIdxUsize}, + Addr, Offset, }; use bstr::BStr; @@ -44,32 +45,6 @@ pub enum ElfReadError { pub type Result = std::result::Result; -#[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, "0x{:x}", self.0) - } -} - -impl Display for Addr { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - write!(f, "0x{:x}", self.0) - } -} - -#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Zeroable, Pod)] -#[repr(transparent)] -pub struct Offset(pub u64); - -impl ToIdxUsize for Offset { - fn to_idx_usize(self) -> usize { - self.0.to_idx_usize() - } -} - define_idx! { pub struct ShStringIdx(u32); } @@ -107,16 +82,6 @@ pub struct ElfHeader { pub shstrndex: c::SectionIdx, } -pub const HEADER_ENTRY_OFFSET: usize = 24; - -#[test] -fn elf_header_entry_offset() { - let mut header = ElfHeader::zeroed(); - let buf = bytemuck::cast_mut::() / 8]>(&mut header); - buf[HEADER_ENTRY_OFFSET / 8] = 0x001122334455667788; - assert_eq!(header.entry, Addr(0x001122334455667788)); -} - #[derive(Debug, Clone, Copy, Zeroable, Pod)] #[repr(C)] pub struct ElfIdent { diff --git a/elven-parser/src/write.rs b/elven-parser/src/write.rs index e508196..4260551 100644 --- a/elven-parser/src/write.rs +++ b/elven-parser/src/write.rs @@ -3,7 +3,8 @@ use bytemuck::Pod; use crate::consts::{ Machine, PhFlags, PhType, SectionIdx, ShFlags, ShType, Type, SHT_NULL, SHT_STRTAB, }; -use crate::read::{self, Addr, ElfHeader, ElfIdent, Offset, Phdr, ShStringIdx, Shdr}; +use crate::read::{self, ElfHeader, ElfIdent, Phdr, ShStringIdx, Shdr}; +use crate::{Addr, Offset}; use std::io::Write; use std::mem::size_of; use std::num::NonZeroU64; @@ -355,7 +356,7 @@ fn align_up(n: u64, align: u64) -> u64 { let next_down = n - masked; // 0b0100 let ret = next_down + align; // 0b0110 debug_assert!(ret >= n); - debug_assert!(ret & align == 0); + debug_assert!(ret & required_mask == 0); ret } diff --git a/elven-wald/src/lib.rs b/elven-wald/src/lib.rs index b197d9a..3e551bd 100644 --- a/elven-wald/src/lib.rs +++ b/elven-wald/src/lib.rs @@ -5,8 +5,9 @@ use anyhow::{bail, Context, Result}; use clap::Parser; use elven_parser::{ consts::{self as c, PhFlags, SectionIdx, ShFlags, ShType, PT_LOAD, SHT_PROGBITS}, - read::{Addr, ElfIdent, ElfReader, Offset}, + read::{ElfIdent, ElfReader}, write::{self, ElfWriter, ProgramHeader, Section, SectionRelativeAbsoluteAddr}, + Addr, Offset, }; use memmap2::Mmap; use std::{