mirror of
https://github.com/Noratrieb/elven-forest.git
synced 2026-01-14 18:55:01 +01:00
more things
This commit is contained in:
parent
f861e0511d
commit
d6daaea999
7 changed files with 114 additions and 24 deletions
1
.gitignore
vendored
1
.gitignore
vendored
|
|
@ -1 +1,2 @@
|
|||
/target
|
||||
a.out
|
||||
|
|
|
|||
|
|
@ -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::<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>>()?;
|
||||
|
|
@ -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<String, ElfReadError> {
|
||||
Ok(if sym.info.r#type() == c::STT_SECTION {
|
||||
elf.sh_string(elf.section_header(sym.shndx)?.name)?
|
||||
|
|
|
|||
|
|
@ -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
|
||||
// ------------------
|
||||
|
|
|
|||
|
|
@ -134,7 +134,7 @@ const _: [u8; c::EI_NIDENT] = [0; mem::size_of::<ElfIdent>()];
|
|||
#[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,
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@ pub type Result<T> = std::result::Result<T, WriteElfError>;
|
|||
#[derive(Debug, Clone)]
|
||||
pub struct ElfWriter {
|
||||
header: read::ElfHeader,
|
||||
entry: Entry,
|
||||
entry: SectionRelativeAbsoluteAddr,
|
||||
sections_headers: Vec<Section>,
|
||||
programs_headers: Vec<ProgramHeader>,
|
||||
}
|
||||
|
|
@ -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<u8>,
|
||||
}
|
||||
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::<read::ElfHeader> as u16,
|
||||
ehsize: size_of::<read::ElfHeader>() as u16,
|
||||
phentsize: size_of::<read::Phdr>() as u16,
|
||||
phnum: u16::MAX,
|
||||
phnum: 0x3333,
|
||||
shentsize: size_of::<read::Shdr>() 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;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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),
|
||||
};
|
||||
|
||||
|
|
|
|||
BIN
ld-a.out
Executable file
BIN
ld-a.out
Executable file
Binary file not shown.
Loading…
Add table
Add a link
Reference in a new issue