1
0
mirror of https://github.com/sgmarz/osblog.git synced 2024-11-24 02:16:19 +04:00

Use Result instead of Option with LoadErrors

This commit is contained in:
Stephen Marz 2020-05-15 12:11:28 -04:00
parent 4a9aa3f658
commit 8e414c62be
2 changed files with 21 additions and 18 deletions

View File

@ -79,13 +79,20 @@ pub struct Program {
pub data: Buffer pub data: Buffer
} }
pub enum LoadErrors {
Magic,
Machine,
TypeExec,
FileRead
}
pub struct File { pub struct File {
pub header: Header, pub header: Header,
pub programs: VecDeque<Program> pub programs: VecDeque<Program>
} }
impl File { impl File {
pub fn load(buffer: &Buffer) -> Option<Self> { pub fn load(buffer: &Buffer) -> Result<Self, LoadErrors> {
let elf_hdr; let elf_hdr;
unsafe { unsafe {
// Load the ELF // Load the ELF
@ -94,19 +101,16 @@ impl File {
} }
// The ELF magic is 0x75, followed by ELF // The ELF magic is 0x75, followed by ELF
if elf_hdr.magic != MAGIC { if elf_hdr.magic != MAGIC {
println!("ELF magic didn't match."); return Err(LoadErrors::Magic);
return None;
} }
// We need to make sure we're built for RISC-V // We need to make sure we're built for RISC-V
if elf_hdr.machine != MACHINE_RISCV { if elf_hdr.machine != MACHINE_RISCV {
println!("ELF loaded is not RISC-V."); return Err(LoadErrors::Machine);
return None;
} }
// ELF has several types. However, we can only load // ELF has several types. However, we can only load
// executables. // executables.
if elf_hdr.obj_type != TYPE_EXEC { if elf_hdr.obj_type != TYPE_EXEC {
println!("ELF is not an executable."); return Err(LoadErrors::TypeExec);
return None;
} }
let ph_tab = unsafe { buffer.get().add(elf_hdr.phoff) } let ph_tab = unsafe { buffer.get().add(elf_hdr.phoff) }
as *const ProgramHeader; as *const ProgramHeader;
@ -140,17 +144,16 @@ impl File {
data: ph_buffer }); data: ph_buffer });
} }
} }
Some(ret) Ok(ret)
} }
// load // load
pub fn load_proc(buffer: &Buffer, sz: usize) -> Option<Process> { pub fn load_proc(buffer: &Buffer, sz: usize) -> Result<Process, LoadErrors> {
let elf_fl = Self::load(&buffer); let elf_fl = Self::load(&buffer);
if elf_fl.is_none() { if elf_fl.is_err() {
println!("Error reading elf file."); return Err(elf_fl.err().unwrap());
return None; }
} let elf_fl = elf_fl.ok().unwrap();
let elf_fl = elf_fl.unwrap();
let program_pages = (sz as usize / PAGE_SIZE) + 1; let program_pages = (sz as usize / PAGE_SIZE) + 1;
// I did this to demonstrate the expressive nature of Rust. Kinda cool, no? // I did this to demonstrate the expressive nature of Rust. Kinda cool, no?
@ -262,6 +265,6 @@ impl File {
// now. Since we don't reuse PIDs, this means that we can only spawn // now. Since we don't reuse PIDs, this means that we can only spawn
// 65534 processes. // 65534 processes.
satp_fence_asid(my_pid as usize); satp_fence_asid(my_pid as usize);
Some(my_proc) Ok(my_proc)
} }
} }

View File

@ -44,11 +44,11 @@ pub fn test_elf() {
// user space. So, we need to know how many program pages we // user space. So, we need to know how many program pages we
// need. Each page is 4096 bytes. // need. Each page is 4096 bytes.
let my_proc = elf::File::load_proc(&buffer, bytes_read as usize); let my_proc = elf::File::load_proc(&buffer, bytes_read as usize);
if my_proc.is_none() { if my_proc.is_err() {
println!("Unable to load process"); println!("Unable to load process");
return; return;
} }
let my_proc = my_proc.unwrap(); let my_proc = my_proc.ok().unwrap();
// I took a different tact here than in process.rs. In there I created // I took a different tact here than in process.rs. In there I created
// the process while holding onto the process list. It might // the process while holding onto the process list. It might
// matter since this is asynchronous--it is being ran as a kernel process. // matter since this is asynchronous--it is being ran as a kernel process.