feat: introduce HOT! executable format and Ring 3 process isolation (v0.5.2)
- Implement custom 'HOT!' binary format and Rust-based elf2hot converter. - Upgrade kernel loader with segment-based loading and BSS zeroing. - Refactor scheduler for Ring 3 IRET frames and fix CS/SS selector swap. - Add user stack allocation (0x70000000) and linker scripts for binary cleanup.
This commit is contained in:
Generated
+88
@@ -0,0 +1,88 @@
|
||||
# This file is automatically @generated by Cargo.
|
||||
# It is not intended for manual editing.
|
||||
version = 4
|
||||
|
||||
[[package]]
|
||||
name = "elf2hot"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"goblin",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "goblin"
|
||||
version = "0.10.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4db6758c546e6f81f265638c980e5e84dfbda80cfd8e89e02f83454c8e8124bd"
|
||||
dependencies = [
|
||||
"log",
|
||||
"plain",
|
||||
"scroll",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "log"
|
||||
version = "0.4.29"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5e5032e24019045c762d3c0f28f5b6b8bbf38563a65908389bf7978758920897"
|
||||
|
||||
[[package]]
|
||||
name = "plain"
|
||||
version = "0.2.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b4596b6d070b27117e987119b4dac604f3c58cfb0b191112e24771b2faeac1a6"
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro2"
|
||||
version = "1.0.106"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8fd00f0bb2e90d81d1044c2b32617f68fcb9fa3bb7640c23e9c748e53fb30934"
|
||||
dependencies = [
|
||||
"unicode-ident",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "quote"
|
||||
version = "1.0.44"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "21b2ebcf727b7760c461f091f9f0f539b77b8e87f2fd88131e7f1b433b3cece4"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "scroll"
|
||||
version = "0.13.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c1257cd4248b4132760d6524d6dda4e053bc648c9070b960929bf50cfb1e7add"
|
||||
dependencies = [
|
||||
"scroll_derive",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "scroll_derive"
|
||||
version = "0.13.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ed76efe62313ab6610570951494bdaa81568026e0318eaa55f167de70eeea67d"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "syn"
|
||||
version = "2.0.114"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d4d107df263a3013ef9b1879b0df87d706ff80f65a86ea879bd9c31f9b307c2a"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"unicode-ident",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "unicode-ident"
|
||||
version = "1.0.22"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9312f7c4f6ff9069b165498234ce8be658059c6728633667c526e27dc2cf1df5"
|
||||
@@ -0,0 +1,7 @@
|
||||
[package]
|
||||
name = "elf2hot"
|
||||
version = "0.1.0"
|
||||
edition = "2024"
|
||||
|
||||
[dependencies]
|
||||
goblin = "0.10.4"
|
||||
@@ -0,0 +1,98 @@
|
||||
use goblin::elf::program_header::PT_LOAD;
|
||||
use std::env;
|
||||
use std::fs::File;
|
||||
use std::io::{Read, Write};
|
||||
|
||||
#[repr(C, packed)]
|
||||
#[derive(Default, Debug)]
|
||||
struct HotHeader {
|
||||
magic: u32,
|
||||
version: u8,
|
||||
reserved_pad: [u8; 3],
|
||||
entry_point: u64,
|
||||
segments_count: u64,
|
||||
reserved: u64,
|
||||
}
|
||||
|
||||
#[repr(C, packed)]
|
||||
#[derive(Default, Debug, Clone, Copy)]
|
||||
struct HotSegment {
|
||||
stype: u64,
|
||||
vaddr: u64,
|
||||
offset: u64,
|
||||
filesz: u64,
|
||||
memsz: u64,
|
||||
}
|
||||
|
||||
const HOT_MAGIC: u32 = 0x21544F48; // "HOT!"
|
||||
|
||||
fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||
let args: Vec<String> = env::args().collect();
|
||||
if args.len() < 3 {
|
||||
println!("Usage: elf2hot <input_elf> <output_hot>");
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
let input_path = &args[1];
|
||||
let output_path = &args[2];
|
||||
|
||||
let mut f = File::open(input_path)?;
|
||||
let mut buffer = Vec::new();
|
||||
f.read_to_end(&mut buffer)?;
|
||||
|
||||
let elf = goblin::elf::Elf::parse(&buffer)?;
|
||||
|
||||
let mut hot_segments = Vec::new();
|
||||
let mut segment_data = Vec::new();
|
||||
|
||||
let mut current_offset = std::mem::size_of::<HotHeader>() as u64;
|
||||
|
||||
let load_segments: Vec<_> = elf.program_headers.iter()
|
||||
.filter(|ph| ph.p_type == PT_LOAD)
|
||||
.collect();
|
||||
|
||||
current_offset += (load_segments.len() * std::mem::size_of::<HotSegment>()) as u64;
|
||||
|
||||
for ph in load_segments {
|
||||
let is_code = ph.is_executable();
|
||||
|
||||
let data = &buffer[ph.p_offset as usize..(ph.p_offset + ph.p_filesz) as usize];
|
||||
segment_data.push(data);
|
||||
|
||||
hot_segments.push(HotSegment {
|
||||
stype: if is_code { 1 } else { 2 },
|
||||
vaddr: ph.p_vaddr,
|
||||
offset: current_offset,
|
||||
filesz: ph.p_filesz,
|
||||
memsz: ph.p_memsz,
|
||||
});
|
||||
|
||||
current_offset += ph.p_filesz;
|
||||
}
|
||||
|
||||
let header = HotHeader {
|
||||
magic: HOT_MAGIC,
|
||||
version: 1,
|
||||
entry_point: elf.entry,
|
||||
segments_count: hot_segments.len() as u64,
|
||||
..Default::default()
|
||||
};
|
||||
|
||||
let mut out = File::create(output_path)?;
|
||||
|
||||
let header_bytes: [u8; std::mem::size_of::<HotHeader>()] = unsafe { std::mem::transmute(header) };
|
||||
out.write_all(&header_bytes)?;
|
||||
|
||||
for seg in hot_segments {
|
||||
let seg_bytes: [u8; std::mem::size_of::<HotSegment>()] = unsafe { std::mem::transmute(seg) };
|
||||
out.write_all(&seg_bytes)?;
|
||||
}
|
||||
|
||||
for data in segment_data {
|
||||
out.write_all(data)?;
|
||||
}
|
||||
|
||||
println!("Successfully converted {} to {}!", input_path, output_path);
|
||||
println!("Entry point: 0x{:X}", elf.entry);
|
||||
Ok(())
|
||||
}
|
||||
Reference in New Issue
Block a user