From d6daaea999f1fcc0ad1698240b11035581a10a4c Mon Sep 17 00:00:00 2001 From: Nilstrieb <48135649+Nilstrieb@users.noreply.github.com> Date: Mon, 13 Feb 2023 20:42:50 +0100 Subject: [PATCH] more things --- .gitignore | 1 + elven-forest/src/main.rs | 72 +++++++++++++++++++++++++++++++++---- elven-parser/src/consts.rs | 35 ++++++++++++++++-- elven-parser/src/read.rs | 2 +- elven-parser/src/write.rs | 20 +++++------ elven-wald/src/lib.rs | 8 ++--- ld-a.out | Bin 0 -> 4688 bytes 7 files changed, 114 insertions(+), 24 deletions(-) create mode 100755 ld-a.out diff --git a/.gitignore b/.gitignore index ea8c4bf..5aa569a 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,2 @@ /target +a.out diff --git a/elven-forest/src/main.rs b/elven-forest/src/main.rs index ad97e88..b3f9895 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, SymbolVisibility, RX86_64}, - read::{Addr, ElfReadError, ElfReader, Sym, SymInfo}, + consts::{self as c, DynamicTag, PhType, ShType, SymbolVisibility, RX86_64}, + read::{Addr, ElfReadError, ElfReader, Offset, Sym, SymInfo}, }; use memmap2::Mmap; use tabled::{object::Rows, Disable, Style, Table, Tabled}; @@ -26,8 +26,23 @@ struct SectionTable { name: String, #[tabled(rename = "type")] r#type: ShType, - size: u64, - offset: u64, + size: Addr, + offset: Addr, +} + +#[derive(Tabled)] +struct ProgramHeaderTable { + #[tabled(rename = "type")] + r#type: PhType, + flags: u32, + offset: Addr, + virtual_addr: Addr, + phys_addr: Addr, + file_size: Addr, + mem_size: Addr, + align: Addr, + inside_section: String, + inside_section_offset: Addr, } #[derive(Tabled)] @@ -76,6 +91,9 @@ fn print_file(path: &str) -> anyhow::Result<()> { HeaderTable("type", &header.r#type), HeaderTable("machine", &header.machine), HeaderTable("entrypoint", &header.entry), + HeaderTable("header size", &header.ehsize), + HeaderTable("program header size", &header.phentsize), + HeaderTable("section header size", &header.shentsize), ]; let mut table = Table::new(header_tab); @@ -93,8 +111,33 @@ fn print_file(path: &str) -> anyhow::Result<()> { Ok(SectionTable { name, r#type: sh.r#type, - size: sh.size, - offset: sh.offset.0, + size: Addr(sh.size), + offset: Addr(sh.offset.0), + }) + }) + .collect::, ElfReadError>>()?; + + print_table(Table::new(sections)); + + println!("\nProgram headers"); + + let sections = elf + .program_headers()? + .iter() + .map(|ph| { + let (inside_section, inside_section_offset) = section_name_of_offset(elf, ph.offset)?; + + Ok(ProgramHeaderTable { + r#type: ph.r#type, + flags: ph.flags, + offset: Addr(ph.offset.0), + 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), }) }) .collect::, ElfReadError>>()?; @@ -170,6 +213,23 @@ fn print_file(path: &str) -> anyhow::Result<()> { Ok(()) } +fn section_name_of_offset(elf: ElfReader<'_>, addr: Offset) -> Result<(String, u64), ElfReadError> { + let addr = addr.0; + for sh in elf.section_headers()?.iter() { + let range = sh.offset.0..(sh.offset.0 + sh.size); + if range.contains(&addr) { + let name = sh.name; + let name = elf.sh_string(name)?; + + let offset = addr - sh.offset.0; + + return Ok((name.to_string(), offset)); + } + } + + Ok((String::new(), addr)) +} + fn sym_display_name(elf: ElfReader<'_>, sym: &Sym) -> Result { Ok(if sym.info.r#type() == c::STT_SECTION { elf.sh_string(elf.section_header(sym.shndx)?.name)? diff --git a/elven-parser/src/consts.rs b/elven-parser/src/consts.rs index bf415eb..5672abd 100644 --- a/elven-parser/src/consts.rs +++ b/elven-parser/src/consts.rs @@ -125,7 +125,7 @@ pub const EI_PAD: usize = 9; /* Byte index of padding bytes */ pub const EI_NIDENT: usize = 16; const_group_with_fmt! { - pub struct Type(u16): "type" + pub struct Type(u16): "ET" pub const ET_NONE = 0; pub const ET_REL = 1; @@ -135,7 +135,7 @@ const_group_with_fmt! { } const_group_with_fmt! { - pub struct Machine(u16): "machine" + pub struct Machine(u16): "EM" pub const EM_NONE = 0; /* No machine */ pub const EM_X86_64 = 62; /* AMD x86-64 architecture */ @@ -207,6 +207,37 @@ pub const SHT_LOSUNW: u32 = 0x6ffffffa; /* Sun-specific low bound. */ pub const SHT_HISUNW: u32 = 0x6fffffff; /* Sun-specific high bound. */ pub const SHT_HIOS: u32 = 0x6fffffff; /* End OS-specific type */ +// ------------------ +// Program headers +// ------------------ + +const_group_with_fmt! { + pub struct PhType(u32): "PT" + + pub const PT_NULL = 0; /* Program header table entry unused */ + pub const PT_LOAD = 1; /* Loadable program segment */ + pub const PT_DYNAMIC = 2; /* Dynamic linking information */ + pub const PT_INTERP = 3; /* Program interpreter */ + pub const PT_NOTE = 4; /* Auxiliary information */ + pub const PT_SHLIB = 5; /* Reserved */ + pub const PT_PHDR = 6; /* Entry for header table itself */ + pub const PT_TLS = 7; /* Thread-local storage segment */ + pub const PT_NUM = 8; /* Number of defined types */ + pub const PT_GNU_EH_FRAME = 0x6474e550; /* GCC .eh_frame_hdr segment */ + pub const PT_GNU_STACK = 0x6474e551; /* Indicates stack executability */ + pub const PT_GNU_RELRO = 0x6474e552; /* Read-only after relocation */ + pub const PT_GNU_PROPERTY = 0x6474e553; /* GNU property */ + pub const PT_SUNWBSS = 0x6ffffffa; /* Sun Specific segment */ + pub const PT_SUNWSTACK = 0x6ffffffb; /* Stack segment */ + pub const PT_HISUNW = 0x6fffffff; +} + +pub const PT_LOOS: u32 = 0x60000000; /* Start of OS-specific */ +pub const PT_LOSUNW: u32 = 0x6ffffffa; +pub const PT_HIOS: u32 = 0x6fffffff; /* End of OS-specific */ +pub const PT_LOPROC: u32 = 0x70000000; /* Start of processor-specific */ +pub const PT_HIPROC: u32 = 0x7fffffff; /* End of processor-specific */ + // ------------------ // Symbols // ------------------ diff --git a/elven-parser/src/read.rs b/elven-parser/src/read.rs index 3a14a04..1ae112b 100644 --- a/elven-parser/src/read.rs +++ b/elven-parser/src/read.rs @@ -134,7 +134,7 @@ const _: [u8; c::EI_NIDENT] = [0; mem::size_of::()]; #[derive(Debug, Clone, Copy, Zeroable, Pod)] #[repr(C)] pub struct Phdr { - pub r#type: u32, + pub r#type: c::PhType, pub flags: u32, pub offset: Offset, pub vaddr: Addr, diff --git a/elven-parser/src/write.rs b/elven-parser/src/write.rs index 82263ad..3c6be68 100644 --- a/elven-parser/src/write.rs +++ b/elven-parser/src/write.rs @@ -17,7 +17,7 @@ pub type Result = std::result::Result; #[derive(Debug, Clone)] pub struct ElfWriter { header: read::ElfHeader, - entry: Entry, + entry: SectionRelativeAbsoluteAddr, sections_headers: Vec
, programs_headers: Vec, } @@ -30,7 +30,7 @@ pub struct Header { } #[derive(Debug, Clone)] -pub struct Entry { +pub struct SectionRelativeAbsoluteAddr { pub section: SectionIdx, pub rel_offset: Offset, } @@ -45,9 +45,7 @@ pub struct Section { } #[derive(Debug, Clone)] -pub struct ProgramHeader { - pub content: Vec, -} +pub struct ProgramHeader {} const SH_STRTAB: usize = 1; @@ -58,15 +56,15 @@ impl ElfWriter { r#type: header.r#type, machine: header.machine, version: 1, - entry: Addr(u64::MAX), + entry: Addr(0x3333333333333333), phoff: Offset(0), shoff: Offset(0), flags: u32::MAX, - ehsize: size_of:: as u16, + ehsize: size_of::() as u16, phentsize: size_of::() as u16, - phnum: u16::MAX, + phnum: 0x3333, shentsize: size_of::() as u16, - shnum: u16::MAX, + shnum: 0x3333, // Set below. shstrndex: SectionIdx(SH_STRTAB as u16), }; @@ -92,7 +90,7 @@ impl ElfWriter { Self { header, - entry: Entry { + entry: SectionRelativeAbsoluteAddr { section: SectionIdx(0), rel_offset: Offset(0), }, @@ -101,7 +99,7 @@ impl ElfWriter { } } - pub fn set_entry(&mut self, entry: Entry) { + pub fn set_entry(&mut self, entry: SectionRelativeAbsoluteAddr) { self.entry = entry; } diff --git a/elven-wald/src/lib.rs b/elven-wald/src/lib.rs index 0fb4df2..4715714 100644 --- a/elven-wald/src/lib.rs +++ b/elven-wald/src/lib.rs @@ -6,7 +6,7 @@ use clap::Parser; use elven_parser::{ consts::{self as c, ShType, SHT_PROGBITS}, read::{ElfIdent, ElfReader, Offset}, - write::{self, ElfWriter, Entry, Section}, + write::{self, ElfWriter, SectionRelativeAbsoluteAddr, Section}, }; use memmap2::Mmap; use std::{ @@ -60,7 +60,7 @@ pub fn run(opts: Opts) -> Result<()> { let section = _start_sym.shndx; - let entry = Entry { + let entry = SectionRelativeAbsoluteAddr { section, rel_offset: Offset(_start_sym.value.0), }; @@ -70,7 +70,7 @@ pub fn run(opts: Opts) -> Result<()> { Ok(()) } -fn write_output(text: &[u8], entry: Entry) -> Result<()> { +fn write_output(text: &[u8], entry: SectionRelativeAbsoluteAddr) -> Result<()> { let ident = ElfIdent { magic: *c::ELFMAG, class: c::Class(c::ELFCLASS64), @@ -83,7 +83,7 @@ fn write_output(text: &[u8], entry: Entry) -> Result<()> { let header = write::Header { ident, - r#type: c::Type(c::ET_DYN), + r#type: c::Type(c::ET_EXEC), machine: c::Machine(c::EM_X86_64), }; diff --git a/ld-a.out b/ld-a.out new file mode 100755 index 0000000000000000000000000000000000000000..b3fea9946c94a0ed0cde5a89ccaca2cf6ed23378 GIT binary patch literal 4688 zcmb<-^>JfjWMqH=CI&kOFi*e%ECeAL7z6~tTrlClV8Ot|;K0Djzyemw0v3f4FdYzj z15_ABGYCKgKz6W#m{2|g)IJ!^1CnE4V1UsueNf?1YBU5!Ltr!nMnhmU1V%$(Gz3ON zU^E0qLtr!nMnhmU1V%%Egb>(a!@$6>AEbdF+#Lt8uwhVtorU4!e{?yJb^*{R0IdHG zRbbA*zyKCkfQ$n`g&CZ2hXVA~c&rQ|O%giax&@U*;&q_@$Db`QTDND`MP0KGz zEiTb7Ni8mkPf09E)KASVD5=y-EY4+!k54KtjxR1rEGl7$PX$Rb#HZ$^Ffiy9SLT)^ zCNbz0mlQ$h3>d24Iz`y`f#{uO_Kxs|}1_qEElnbX8K=u2>MIa1Nyh2zI5;V+%P5*nSenp5fIEk(w E0EiMe6#xJL literal 0 HcmV?d00001