108 lines
2.0 KiB
Rust
108 lines
2.0 KiB
Rust
|
|
use crate::vm::obj::error::ParseError;
|
||
|
|
use std::{
|
||
|
|
convert::TryFrom,
|
||
|
|
fmt::Debug,
|
||
|
|
};
|
||
|
|
|
||
|
|
pub const MAGIC: u64 = 0xDEAD_BEA7_BA5E_BA11;
|
||
|
|
|
||
|
|
#[derive(Debug)]
|
||
|
|
pub struct Object {
|
||
|
|
pub header: Header,
|
||
|
|
pub sections: Vec<Box<dyn Section>>,
|
||
|
|
}
|
||
|
|
|
||
|
|
#[derive(Debug, Clone, Copy)]
|
||
|
|
pub struct Header {
|
||
|
|
pub version: u16,
|
||
|
|
pub sections: u16,
|
||
|
|
}
|
||
|
|
|
||
|
|
macro_rules! section_kind {
|
||
|
|
(
|
||
|
|
pub enum $enum_name:ident {
|
||
|
|
$($name:ident = $value:expr),* $(,)?
|
||
|
|
}
|
||
|
|
) => {
|
||
|
|
|
||
|
|
#[derive(Debug, Clone, Copy)]
|
||
|
|
#[repr(u8)]
|
||
|
|
pub enum $enum_name {
|
||
|
|
$($name = $value),*
|
||
|
|
}
|
||
|
|
|
||
|
|
impl TryFrom<u8> for SectionKind {
|
||
|
|
type Error = ParseError;
|
||
|
|
|
||
|
|
fn try_from(other: u8) -> std::result::Result<Self, Self::Error> {
|
||
|
|
match other {
|
||
|
|
$(
|
||
|
|
$value => Ok($enum_name::$name),
|
||
|
|
)*
|
||
|
|
_ => Err(ParseError::UnknownSectionKind { kind: other }),
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
};
|
||
|
|
}
|
||
|
|
|
||
|
|
section_kind! {
|
||
|
|
pub enum SectionKind {
|
||
|
|
Data = 0x00,
|
||
|
|
Code = 0x10,
|
||
|
|
Meta = 0xFF,
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
pub trait Section: Debug {
|
||
|
|
fn header(&self) -> SectionHeader;
|
||
|
|
}
|
||
|
|
|
||
|
|
#[derive(Debug, Clone, Copy)]
|
||
|
|
pub struct SectionHeader {
|
||
|
|
pub kind: SectionKind,
|
||
|
|
pub checksum: u32,
|
||
|
|
pub len: u64,
|
||
|
|
}
|
||
|
|
|
||
|
|
#[derive(Debug, Clone)]
|
||
|
|
pub struct DataSection {
|
||
|
|
pub header: SectionHeader,
|
||
|
|
pub load_location: u64,
|
||
|
|
pub contents: Vec<u8>,
|
||
|
|
}
|
||
|
|
|
||
|
|
impl Section for DataSection {
|
||
|
|
fn header(&self) -> SectionHeader {
|
||
|
|
self.header
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
#[derive(Debug, Clone)]
|
||
|
|
pub struct CodeSection {
|
||
|
|
pub header: SectionHeader,
|
||
|
|
pub load_location: u64,
|
||
|
|
pub contents: Vec<u8>,
|
||
|
|
}
|
||
|
|
|
||
|
|
impl Section for CodeSection {
|
||
|
|
fn header(&self) -> SectionHeader {
|
||
|
|
self.header
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
#[derive(Debug, Clone)]
|
||
|
|
pub struct MetaSection {
|
||
|
|
pub header: SectionHeader,
|
||
|
|
pub entry_count: u64,
|
||
|
|
pub entries: Vec<(String, Vec<u8>)>,
|
||
|
|
}
|
||
|
|
|
||
|
|
impl Section for MetaSection {
|
||
|
|
fn header(&self) -> SectionHeader {
|
||
|
|
self.header
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
|