mirror of
https://github.com/Noratrieb/elven-forest.git
synced 2026-01-14 18:55:01 +01:00
so safe
This commit is contained in:
parent
af7a575a22
commit
d3118af82d
3 changed files with 59 additions and 18 deletions
21
Cargo.lock
generated
21
Cargo.lock
generated
|
|
@ -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",
|
||||||
]
|
]
|
||||||
|
|
|
||||||
|
|
@ -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"
|
||||||
|
|
|
||||||
|
|
@ -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!()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue