This commit is contained in:
nora 2023-02-16 20:40:05 +01:00
parent 4b41166d5f
commit c38aa61857
5 changed files with 60 additions and 50 deletions

View file

@ -3,7 +3,8 @@ use std::{fmt::Display, fs::File};
use anyhow::Context; use anyhow::Context;
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::{Addr, ElfReadError, ElfReader, Offset, Sym, SymInfo}, read::{ElfReadError, ElfReader, Sym, SymInfo},
Addr, Offset,
}; };
use memmap2::Mmap; use memmap2::Mmap;
use tabled::{object::Rows, Disable, Style, Table, Tabled}; use tabled::{object::Rows, Disable, Style, Table, Tabled};
@ -21,13 +22,16 @@ fn main() -> anyhow::Result<()> {
#[derive(Tabled)] #[derive(Tabled)]
struct HeaderTable<'a>(&'static str, &'a dyn Display); struct HeaderTable<'a>(&'static str, &'a dyn Display);
// Not really an addr but just display it as hex.
type Hex = Addr;
#[derive(Tabled)] #[derive(Tabled)]
struct SectionTable { struct SectionTable {
name: String, name: String,
#[tabled(rename = "type")] #[tabled(rename = "type")]
r#type: ShType, r#type: ShType,
size: Addr, size: Hex,
offset: Addr, offset: Offset,
flags: ShFlags, flags: ShFlags,
} }
@ -36,14 +40,14 @@ struct ProgramHeaderTable {
#[tabled(rename = "type")] #[tabled(rename = "type")]
r#type: PhType, r#type: PhType,
flags: PhFlags, flags: PhFlags,
offset: Addr, offset: Offset,
virtual_addr: Addr, virtual_addr: Addr,
phys_addr: Addr, phys_addr: Addr,
file_size: Addr, file_size: Hex,
mem_size: Addr, mem_size: Hex,
align: Addr, align: Hex,
inside_section: String, inside_section: String,
inside_section_offset: Addr, inside_section_offset: Offset,
} }
#[derive(Tabled)] #[derive(Tabled)]
@ -113,7 +117,7 @@ fn print_file(path: &str) -> anyhow::Result<()> {
name, name,
r#type: sh.r#type, r#type: sh.r#type,
size: Addr(sh.size), size: Addr(sh.size),
offset: Addr(sh.offset.0), offset: sh.offset,
flags: sh.flags, flags: sh.flags,
}) })
}) })
@ -132,14 +136,14 @@ fn print_file(path: &str) -> anyhow::Result<()> {
Ok(ProgramHeaderTable { Ok(ProgramHeaderTable {
r#type: ph.r#type, r#type: ph.r#type,
flags: ph.flags, flags: ph.flags,
offset: Addr(ph.offset.0), offset: ph.offset,
virtual_addr: ph.vaddr, virtual_addr: ph.vaddr,
phys_addr: ph.paddr, phys_addr: ph.paddr,
file_size: Addr(ph.filesz), file_size: Addr(ph.filesz),
mem_size: Addr(ph.memsz), mem_size: Addr(ph.memsz),
align: Addr(ph.align), align: Addr(ph.align),
inside_section, inside_section,
inside_section_offset: Addr(inside_section_offset), inside_section_offset: Offset(inside_section_offset),
}) })
}) })
.collect::<Result<Vec<_>, ElfReadError>>()?; .collect::<Result<Vec<_>, ElfReadError>>()?;

View file

@ -1,6 +1,45 @@
#![allow(clippy::must_use_candidate, clippy::missing_errors_doc)] #![allow(clippy::must_use_candidate, clippy::missing_errors_doc)]
use std::fmt::{Debug, Display};
use bytemuck::{Pod, Zeroable};
use idx::ToIdxUsize;
pub mod consts; pub mod consts;
mod idx; mod idx;
pub mod read; pub mod read;
pub mod write; 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)
}
}

View file

@ -5,6 +5,7 @@
use crate::{ use crate::{
consts::{self as c, DynamicTag, ShType}, consts::{self as c, DynamicTag, ShType},
idx::{define_idx, ElfIndexExt, ToIdxUsize}, idx::{define_idx, ElfIndexExt, ToIdxUsize},
Addr, Offset,
}; };
use bstr::BStr; use bstr::BStr;
@ -44,32 +45,6 @@ pub enum ElfReadError {
pub type Result<T> = std::result::Result<T, ElfReadError>; pub type Result<T> = std::result::Result<T, ElfReadError>;
#[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! { define_idx! {
pub struct ShStringIdx(u32); pub struct ShStringIdx(u32);
} }
@ -107,16 +82,6 @@ pub struct ElfHeader {
pub shstrndex: c::SectionIdx, 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::<ElfHeader, [u64; mem::size_of::<ElfHeader>() / 8]>(&mut header);
buf[HEADER_ENTRY_OFFSET / 8] = 0x001122334455667788;
assert_eq!(header.entry, Addr(0x001122334455667788));
}
#[derive(Debug, Clone, Copy, Zeroable, Pod)] #[derive(Debug, Clone, Copy, Zeroable, Pod)]
#[repr(C)] #[repr(C)]
pub struct ElfIdent { pub struct ElfIdent {

View file

@ -3,7 +3,8 @@ use bytemuck::Pod;
use crate::consts::{ use crate::consts::{
Machine, PhFlags, PhType, SectionIdx, ShFlags, ShType, Type, SHT_NULL, SHT_STRTAB, 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::io::Write;
use std::mem::size_of; use std::mem::size_of;
use std::num::NonZeroU64; use std::num::NonZeroU64;
@ -355,7 +356,7 @@ fn align_up(n: u64, align: u64) -> u64 {
let next_down = n - masked; // 0b0100 let next_down = n - masked; // 0b0100
let ret = next_down + align; // 0b0110 let ret = next_down + align; // 0b0110
debug_assert!(ret >= n); debug_assert!(ret >= n);
debug_assert!(ret & align == 0); debug_assert!(ret & required_mask == 0);
ret ret
} }

View file

@ -5,8 +5,9 @@ use anyhow::{bail, Context, Result};
use clap::Parser; use clap::Parser;
use elven_parser::{ use elven_parser::{
consts::{self as c, PhFlags, SectionIdx, ShFlags, ShType, PT_LOAD, SHT_PROGBITS}, 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}, write::{self, ElfWriter, ProgramHeader, Section, SectionRelativeAbsoluteAddr},
Addr, Offset,
}; };
use memmap2::Mmap; use memmap2::Mmap;
use std::{ use std::{