more things

This commit is contained in:
nora 2023-02-13 20:42:50 +01:00
parent f861e0511d
commit d6daaea999
7 changed files with 114 additions and 24 deletions

1
.gitignore vendored
View file

@ -1 +1,2 @@
/target /target
a.out

View file

@ -2,8 +2,8 @@ use std::{fmt::Display, fs::File};
use anyhow::Context; use anyhow::Context;
use elven_parser::{ use elven_parser::{
consts::{self as c, DynamicTag, ShType, SymbolVisibility, RX86_64}, consts::{self as c, DynamicTag, PhType, ShType, SymbolVisibility, RX86_64},
read::{Addr, ElfReadError, ElfReader, Sym, SymInfo}, read::{Addr, ElfReadError, ElfReader, Offset, Sym, SymInfo},
}; };
use memmap2::Mmap; use memmap2::Mmap;
use tabled::{object::Rows, Disable, Style, Table, Tabled}; use tabled::{object::Rows, Disable, Style, Table, Tabled};
@ -26,8 +26,23 @@ struct SectionTable {
name: String, name: String,
#[tabled(rename = "type")] #[tabled(rename = "type")]
r#type: ShType, r#type: ShType,
size: u64, size: Addr,
offset: u64, 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)] #[derive(Tabled)]
@ -76,6 +91,9 @@ fn print_file(path: &str) -> anyhow::Result<()> {
HeaderTable("type", &header.r#type), HeaderTable("type", &header.r#type),
HeaderTable("machine", &header.machine), HeaderTable("machine", &header.machine),
HeaderTable("entrypoint", &header.entry), 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); let mut table = Table::new(header_tab);
@ -93,8 +111,33 @@ fn print_file(path: &str) -> anyhow::Result<()> {
Ok(SectionTable { Ok(SectionTable {
name, name,
r#type: sh.r#type, r#type: sh.r#type,
size: sh.size, size: Addr(sh.size),
offset: sh.offset.0, offset: Addr(sh.offset.0),
})
})
.collect::<Result<Vec<_>, 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::<Result<Vec<_>, ElfReadError>>()?; .collect::<Result<Vec<_>, ElfReadError>>()?;
@ -170,6 +213,23 @@ fn print_file(path: &str) -> anyhow::Result<()> {
Ok(()) 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<String, ElfReadError> { fn sym_display_name(elf: ElfReader<'_>, sym: &Sym) -> Result<String, ElfReadError> {
Ok(if sym.info.r#type() == c::STT_SECTION { Ok(if sym.info.r#type() == c::STT_SECTION {
elf.sh_string(elf.section_header(sym.shndx)?.name)? elf.sh_string(elf.section_header(sym.shndx)?.name)?

View file

@ -125,7 +125,7 @@ pub const EI_PAD: usize = 9; /* Byte index of padding bytes */
pub const EI_NIDENT: usize = 16; pub const EI_NIDENT: usize = 16;
const_group_with_fmt! { const_group_with_fmt! {
pub struct Type(u16): "type" pub struct Type(u16): "ET"
pub const ET_NONE = 0; pub const ET_NONE = 0;
pub const ET_REL = 1; pub const ET_REL = 1;
@ -135,7 +135,7 @@ const_group_with_fmt! {
} }
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_NONE = 0; /* No machine */
pub const EM_X86_64 = 62; /* AMD x86-64 architecture */ 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_HISUNW: u32 = 0x6fffffff; /* Sun-specific high bound. */
pub const SHT_HIOS: u32 = 0x6fffffff; /* End OS-specific type */ 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 // Symbols
// ------------------ // ------------------

View file

@ -134,7 +134,7 @@ const _: [u8; c::EI_NIDENT] = [0; mem::size_of::<ElfIdent>()];
#[derive(Debug, Clone, Copy, Zeroable, Pod)] #[derive(Debug, Clone, Copy, Zeroable, Pod)]
#[repr(C)] #[repr(C)]
pub struct Phdr { pub struct Phdr {
pub r#type: u32, pub r#type: c::PhType,
pub flags: u32, pub flags: u32,
pub offset: Offset, pub offset: Offset,
pub vaddr: Addr, pub vaddr: Addr,

View file

@ -17,7 +17,7 @@ pub type Result<T> = std::result::Result<T, WriteElfError>;
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
pub struct ElfWriter { pub struct ElfWriter {
header: read::ElfHeader, header: read::ElfHeader,
entry: Entry, entry: SectionRelativeAbsoluteAddr,
sections_headers: Vec<Section>, sections_headers: Vec<Section>,
programs_headers: Vec<ProgramHeader>, programs_headers: Vec<ProgramHeader>,
} }
@ -30,7 +30,7 @@ pub struct Header {
} }
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
pub struct Entry { pub struct SectionRelativeAbsoluteAddr {
pub section: SectionIdx, pub section: SectionIdx,
pub rel_offset: Offset, pub rel_offset: Offset,
} }
@ -45,9 +45,7 @@ pub struct Section {
} }
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
pub struct ProgramHeader { pub struct ProgramHeader {}
pub content: Vec<u8>,
}
const SH_STRTAB: usize = 1; const SH_STRTAB: usize = 1;
@ -58,15 +56,15 @@ impl ElfWriter {
r#type: header.r#type, r#type: header.r#type,
machine: header.machine, machine: header.machine,
version: 1, version: 1,
entry: Addr(u64::MAX), entry: Addr(0x3333333333333333),
phoff: Offset(0), phoff: Offset(0),
shoff: Offset(0), shoff: Offset(0),
flags: u32::MAX, flags: u32::MAX,
ehsize: size_of::<read::ElfHeader> as u16, ehsize: size_of::<read::ElfHeader>() as u16,
phentsize: size_of::<read::Phdr>() as u16, phentsize: size_of::<read::Phdr>() as u16,
phnum: u16::MAX, phnum: 0x3333,
shentsize: size_of::<read::Shdr>() as u16, shentsize: size_of::<read::Shdr>() as u16,
shnum: u16::MAX, shnum: 0x3333,
// Set below. // Set below.
shstrndex: SectionIdx(SH_STRTAB as u16), shstrndex: SectionIdx(SH_STRTAB as u16),
}; };
@ -92,7 +90,7 @@ impl ElfWriter {
Self { Self {
header, header,
entry: Entry { entry: SectionRelativeAbsoluteAddr {
section: SectionIdx(0), section: SectionIdx(0),
rel_offset: Offset(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; self.entry = entry;
} }

View file

@ -6,7 +6,7 @@ use clap::Parser;
use elven_parser::{ use elven_parser::{
consts::{self as c, ShType, SHT_PROGBITS}, consts::{self as c, ShType, SHT_PROGBITS},
read::{ElfIdent, ElfReader, Offset}, read::{ElfIdent, ElfReader, Offset},
write::{self, ElfWriter, Entry, Section}, write::{self, ElfWriter, SectionRelativeAbsoluteAddr, Section},
}; };
use memmap2::Mmap; use memmap2::Mmap;
use std::{ use std::{
@ -60,7 +60,7 @@ pub fn run(opts: Opts) -> Result<()> {
let section = _start_sym.shndx; let section = _start_sym.shndx;
let entry = Entry { let entry = SectionRelativeAbsoluteAddr {
section, section,
rel_offset: Offset(_start_sym.value.0), rel_offset: Offset(_start_sym.value.0),
}; };
@ -70,7 +70,7 @@ pub fn run(opts: Opts) -> Result<()> {
Ok(()) Ok(())
} }
fn write_output(text: &[u8], entry: Entry) -> Result<()> { fn write_output(text: &[u8], entry: SectionRelativeAbsoluteAddr) -> Result<()> {
let ident = ElfIdent { let ident = ElfIdent {
magic: *c::ELFMAG, magic: *c::ELFMAG,
class: c::Class(c::ELFCLASS64), class: c::Class(c::ELFCLASS64),
@ -83,7 +83,7 @@ fn write_output(text: &[u8], entry: Entry) -> Result<()> {
let header = write::Header { let header = write::Header {
ident, ident,
r#type: c::Type(c::ET_DYN), r#type: c::Type(c::ET_EXEC),
machine: c::Machine(c::EM_X86_64), machine: c::Machine(c::EM_X86_64),
}; };

BIN
ld-a.out Executable file

Binary file not shown.