This commit is contained in:
nora 2023-02-11 18:45:40 +01:00
parent af7a575a22
commit d3118af82d
3 changed files with 59 additions and 18 deletions

21
Cargo.lock generated
View file

@ -2,10 +2,31 @@
# It is not intended for manual editing. # It is not intended for manual editing.
version = 3 version = 3
[[package]]
name = "bytemuck"
version = "1.13.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c041d3eab048880cb0b86b256447da3f18859a163c3b8d8893f4e6368abe6393"
dependencies = [
"bytemuck_derive",
]
[[package]]
name = "bytemuck_derive"
version = "1.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1aca418a974d83d40a0c1f0c5cba6ff4bc28d8df099109ca459a2118d40b6322"
dependencies = [
"proc-macro2",
"quote",
"syn",
]
[[package]] [[package]]
name = "elven-parser" name = "elven-parser"
version = "0.1.0" version = "0.1.0"
dependencies = [ dependencies = [
"bytemuck",
"memmap2", "memmap2",
"thiserror", "thiserror",
] ]

View file

@ -6,5 +6,6 @@ edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies] [dependencies]
bytemuck = { version = "1.13.0", features = ["derive", "min_const_generics"] }
memmap2 = "0.5.8" memmap2 = "0.5.8"
thiserror = "1.0.38" thiserror = "1.0.38"

View file

@ -2,13 +2,23 @@
use std::mem; use std::mem;
#[derive(Debug)] use bytemuck::{Pod, PodCastError, Zeroable};
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Zeroable, Pod)]
#[repr(transparent)]
pub struct Addr(u64); pub struct Addr(u64);
#[derive(Debug)]
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Zeroable, Pod)]
#[repr(transparent)]
pub struct Offset(u64); pub struct Offset(u64);
#[derive(Debug)]
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Zeroable, Pod)]
#[repr(transparent)]
pub struct Section(u16); pub struct Section(u16);
#[derive(Debug)]
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Zeroable, Pod)]
#[repr(transparent)]
pub struct Versym(u16); pub struct Versym(u16);
#[derive(Debug, Clone, thiserror::Error)] #[derive(Debug, Clone, thiserror::Error)]
@ -27,7 +37,7 @@ pub struct Elf<'a> {
pub header: &'a ElfHeader, pub header: &'a ElfHeader,
} }
#[derive(Debug)] #[derive(Debug, Clone, Copy, Zeroable, Pod)]
#[repr(C)] #[repr(C)]
pub struct ElfHeader { pub struct ElfHeader {
pub ident: [u8; 16], pub ident: [u8; 16],
@ -46,6 +56,10 @@ pub struct ElfHeader {
pub shstrndex: u16, pub shstrndex: u16,
} }
#[derive(Debug)]
#[repr(C)]
pub struct Phdr {}
impl<'a> Elf<'a> { impl<'a> Elf<'a> {
pub fn parse(input: &'a [u8]) -> Result<Self, ElfParseError> { pub fn parse(input: &'a [u8]) -> Result<Self, ElfParseError> {
const HEADER_SIZE: usize = mem::size_of::<ElfHeader>(); const HEADER_SIZE: usize = mem::size_of::<ElfHeader>();
@ -55,19 +69,26 @@ impl<'a> Elf<'a> {
return Err(ElfParseError::FileTooSmall(HEADER_SIZE, input.len())); return Err(ElfParseError::FileTooSmall(HEADER_SIZE, input.len()));
} }
let input_ptr = input as *const [u8]; let input_addr = input as *const [u8] as *const u8 as usize;
let input_align = input_addr.trailing_zeros() as usize;
let input_addr = input_ptr as *const u8 as usize; let input_header = &input[..HEADER_SIZE];
let align = input_addr.trailing_zeros() as usize;
if align < HEADER_ALIGN { let header_slice = match bytemuck::try_cast_slice::<_, ElfHeader>(input_header) {
return Err(ElfParseError::UnalignedInput(HEADER_ALIGN, align)); Ok(slice) => slice,
} Err(
PodCastError::SizeMismatch
| PodCastError::OutputSliceWouldHaveSlop
| PodCastError::AlignmentMismatch,
) => {
unreachable!()
}
Err(PodCastError::TargetAlignmentGreaterAndInputNotAligned) => {
return Err(ElfParseError::UnalignedInput(HEADER_ALIGN, input_align))
}
};
let header = input_ptr as *const ElfHeader; let header = &header_slice[0];
// SAFETY: We checked that the size is enough. We checked that the alignment matches.
// ElfHeader is POD.
let header = unsafe { &*header };
let magic = header.ident[..4].try_into().unwrap(); let magic = header.ident[..4].try_into().unwrap();
@ -107,8 +128,6 @@ mod tests {
#[test] #[test]
fn rust_hello_world_bin() { fn rust_hello_world_bin() {
let file = load_test_file("hello_world"); let file = load_test_file("hello_world");
let elf = Elf::parse(&file).unwrap(); let _ = Elf::parse(&file).unwrap();
dbg!(elf);
panic!()
} }
} }