Remove useless libc, elf and ucontext, add comments to exceptions
improve propagation of errors in raise_exception
This commit is contained in:
parent
41611b54e8
commit
44cfb828fb
7
Cargo.lock
generated
7
Cargo.lock
generated
@ -7,7 +7,6 @@ name = "burritos"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"cc",
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -15,9 +14,3 @@ name = "cc"
|
||||
version = "1.0.79"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "50d30906286121d95be3d479533b458f87493b30a4b5f79a607db8f5d11aa91f"
|
||||
|
||||
[[package]]
|
||||
name = "libc"
|
||||
version = "0.2.140"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "99227334921fae1a979cf0bfdfcc6b3e5ce376ef57e16fb6fb3ea2ed6095f80c"
|
||||
|
@ -3,9 +3,6 @@ name = "burritos"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
|
||||
[dependencies]
|
||||
libc = { version = "0.2.139", features = ["extra_traits"] }
|
||||
|
||||
[registries.crates-io]
|
||||
protocol = "sparse"
|
||||
|
||||
|
@ -1,143 +0,0 @@
|
||||
//Declaration des alias
|
||||
|
||||
/*
|
||||
Def ELF :
|
||||
|
||||
The header file <elf.h> defines the format of ELF executable binary
|
||||
files. Amongst these files are normal executable files, relocatable
|
||||
object files, core files and shared libraries.
|
||||
|
||||
An executable file using the ELF file format consists of an ELF header,
|
||||
followed by a program header table or a section header table, or both.
|
||||
The ELF header is always at offset zero of the file. The program
|
||||
header table and the section header table's offset in the file are
|
||||
defined in the ELF header. The two tables describe the rest of the
|
||||
particularities of the file
|
||||
*/
|
||||
|
||||
|
||||
/* Type for a 16-bit quantity. */
|
||||
|
||||
type Elf32_Half = u16;
|
||||
|
||||
type Elf64_Half = u16;
|
||||
|
||||
/* Types for signed and unsigned 32-bit quantities. */
|
||||
|
||||
type Elf32_Word = u32;
|
||||
|
||||
type Elf32_Sword = i32;
|
||||
|
||||
type Elf64_Word = u32;
|
||||
|
||||
type Elf64_Sword = i32;
|
||||
|
||||
/* Types for signed and unsigned 64-bit quantities. */
|
||||
|
||||
type Elf32_Xword = u64;
|
||||
|
||||
type Elf32_Sxword = i64;
|
||||
|
||||
type Elf64_Xword = u64;
|
||||
|
||||
type Elf64_Sxword = i64;
|
||||
|
||||
/* Type of addresses. */
|
||||
|
||||
type Elf32_Addr = u32;
|
||||
|
||||
type Elf64_Addr = u64;
|
||||
|
||||
/* Type of file offsets. */
|
||||
|
||||
type Elf32_Off = u32;
|
||||
|
||||
type Elf64_Off = u64;
|
||||
|
||||
//role de ce truc ?
|
||||
const EI_NIDENT : u8 = 16;
|
||||
|
||||
//ELF file header 32 bits
|
||||
struct Elf32Ehdr{
|
||||
e_ident : [u8;EI_NIDENT],//16 octects décrivant comment le fichier doit etre parsé
|
||||
//e_ident must starts with magice number : 0x 7f 45 4c 46
|
||||
e_type : Elf32_Half,//type of the file
|
||||
e_machine : Elf32_Half,//type architecture machine
|
||||
e_version : Elf32_Word,//always 1
|
||||
e_entry : Elf32_Addr,//entry point @ for executable
|
||||
e_phoff : Elf32_Off,//Offset of the program header table
|
||||
e_shoff : Elf32_Off,//Offset of the section header table
|
||||
e_flags : Elf32_Word,//des flags ?
|
||||
e_ehsize : Elf32_Half,//size of this (the header), redundant
|
||||
e_phentsize : Elf32_Half,//size per program header
|
||||
e_phnum : Elf32_Half,//number of program header
|
||||
e_shentsize : Elf32_Half,//size per section header
|
||||
e_shnum : Elf32_Half,//number of section header
|
||||
e_shstrndx : Elf32_Half//section header string table index
|
||||
}
|
||||
|
||||
|
||||
//ELF file header 64 bits
|
||||
//les champs ont le meme rôle que dans le header 32 bits
|
||||
struct Elf64Ehdr{
|
||||
e_ident : [u8;EI_NIDENT],
|
||||
e_type : Elf64_Half,
|
||||
e_machine : Elf64_Half,
|
||||
e_version : Elf64_Word,
|
||||
e_entry : Elf64_Addr,
|
||||
e_phoff : Elf64_Off,
|
||||
e_shoff : Elf64_Off,
|
||||
e_flags : Elf64_Word,
|
||||
e_ehsize : Elf64_Half,
|
||||
e_phentsize : Elf64_Half,
|
||||
e_phnum : Elf64_Half,
|
||||
e_shentsize : Elf64_Half,
|
||||
e_shnum : Elf64_Half,
|
||||
e_shstrndx : Elf64_Half
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* e_ident offsets */
|
||||
const EI_MAG0 : u32 = 0;
|
||||
const EI_MAG1 : u32 = 1;
|
||||
const EI_MAG2 : u32 = 2;
|
||||
const EI_MAG3 : u32 = 3;
|
||||
const EI_CLASS : u32 = 4;
|
||||
const EI_DATA : u32 = 5;
|
||||
const EI_VERSION : u32 = 6;
|
||||
const EI_PAD : u32 = 7;
|
||||
|
||||
/* e_ident[EI_CLASS] */
|
||||
const ELFCLASSNONE : u32 = 0;
|
||||
const ELFCLASS32 : u32 = 1;
|
||||
const ELFCLASS64 : u32 = 2;
|
||||
|
||||
/* e_ident[EI_DATA] */
|
||||
const ELFDATANONE : u32 = 0;
|
||||
const ELFDATA2LSB : u32 = 1;
|
||||
const ELFDATA2MSB : u32 = 2;
|
||||
|
||||
/* e_type */
|
||||
const ET_NONE : u32 = 0; /* No file type */
|
||||
const ET_REL : u32 = 1; /* Relocatable file */
|
||||
const ET_EXEC : u32 = 2; /* Executable file */
|
||||
const ET_DYN : u32 = 3; /* Shared object file */
|
||||
const ET_CORE : u32 = 4; /* Core file */
|
||||
const ET_LOPROC : u32 = 0xff00; /* Processor-specific */
|
||||
const ET_HIPROC : u32 = 0xffff; /* Processor-specific */
|
||||
|
||||
/* e_machine */
|
||||
const EM_NONE : u32 = 0; /* No machine */
|
||||
const EM_M32 : u32 = 1; /* AT&T WE 32100 */
|
||||
const EM_SPARC : u32 = 2; /* SPARC */
|
||||
const EM_386 : u32 = 3; /* Intel 80386 */
|
||||
const EM_68K : u32 = 4; /* Motorola 68000 */
|
||||
const EM_88K : u32 = 5; /* Motorola 88000 */
|
||||
const EM_860 : u32 = 7; /* Intel 80860 */
|
||||
const EM_MIPS : u32 = 8; /* MIPS R3000 */
|
||||
const EM_RISC : u32 = 243; /* RISCV */
|
||||
|
||||
/* e_version */
|
||||
const EV_NONE : u32 = 0; /* invalid version */
|
||||
const EV_CURRENT : u32 = 1; /* current version */
|
@ -4,41 +4,109 @@ use crate::simulator::{machine::{ExceptionType, Machine}, error::{MachineOk, Mac
|
||||
|
||||
use super::system::System;
|
||||
|
||||
|
||||
/// The halt system call. Stops Burritos.
|
||||
pub const SC_SHUTDOWN: u8 = 0;
|
||||
/// The exit system call
|
||||
///
|
||||
/// Ends the calling thread
|
||||
pub const SC_EXIT: u8 = 1;
|
||||
/// The exec system call
|
||||
///
|
||||
/// Creates a new process (thread+address space)
|
||||
pub const SC_EXEC: u8 = 2;
|
||||
/// The join system call
|
||||
///
|
||||
/// Wait for the thread idThread to finish
|
||||
pub const SC_JOIN: u8 = 3;
|
||||
/// The create system call
|
||||
///
|
||||
/// Create a new file in nachos file system
|
||||
pub const SC_CREATE: u8 = 4;
|
||||
/// The open system call
|
||||
///
|
||||
/// Opens a file and returns an openfile identifier
|
||||
pub const SC_OPEN: u8 = 5;
|
||||
/// The read system call
|
||||
///
|
||||
/// Read in a file or the console
|
||||
pub const SC_READ: u8 = 6;
|
||||
/// The write system call
|
||||
///
|
||||
/// Write in a file or at the console
|
||||
pub const SC_WRITE: u8 = 7;
|
||||
/// Seek to a given position in an opened file
|
||||
pub const SC_SEEK: u8 = 8;
|
||||
/// The close system call
|
||||
///
|
||||
/// Close a file
|
||||
pub const SC_CLOSE: u8 = 9;
|
||||
/// The newThread system call
|
||||
///
|
||||
/// Create a new thread in the same address space
|
||||
pub const SC_NEW_THREAD: u8 = 10;
|
||||
/// The Yield System call
|
||||
///
|
||||
/// Relinquish the CPU if any other thread is runnable
|
||||
pub const SC_YIELD: u8 = 11;
|
||||
/// the PError system call
|
||||
///
|
||||
/// print the last error message
|
||||
pub const SC_PERROR: u8 = 12;
|
||||
/// carry out P() on the semaphore
|
||||
pub const SC_P: u8 = 13;
|
||||
/// carry out V() on the semaphore
|
||||
pub const SC_V: u8 = 14;
|
||||
pub const SC_SEM_CREATE: u8 = 15 ;
|
||||
/// create a semaphore and add it in g_objects_addrs
|
||||
pub const SC_SEM_CREATE: u8 = 15;
|
||||
/// destroy the semaphore corresponding to the id
|
||||
pub const SC_SEM_DESTROY: u8 = 16;
|
||||
pub const SC_LOCK_CREATE: u8 = 17 ;
|
||||
pub const SC_LOCK_DESTROY: u8 = 18 ;
|
||||
pub const SC_LOCK_ACQUIRE: u8 = 19 ;
|
||||
pub const SC_LOCK_RELEASE: u8 = 20 ;
|
||||
pub const SC_COND_CREATE: u8 = 21 ;
|
||||
pub const SC_COND_DESTROY: u8 = 22 ;
|
||||
pub const SC_COND_WAIT: u8 = 23 ;
|
||||
/// create a lock and add it to g_object_addrs
|
||||
pub const SC_LOCK_CREATE: u8 = 17;
|
||||
/// destroy the lock corresponding to the id
|
||||
pub const SC_LOCK_DESTROY: u8 = 18;
|
||||
/// carry out acquire() on the lock
|
||||
pub const SC_LOCK_ACQUIRE: u8 = 19;
|
||||
/// carry out release() on the lock
|
||||
pub const SC_LOCK_RELEASE: u8 = 20;
|
||||
/// create a condition variable and add it to g_object_addrs
|
||||
pub const SC_COND_CREATE: u8 = 21;
|
||||
/// destroy the condition variable corresponding to the id
|
||||
pub const SC_COND_DESTROY: u8 = 22;
|
||||
/// carry out wait() on the condition
|
||||
pub const SC_COND_WAIT: u8 = 23;
|
||||
/// carry out signal() on the condition
|
||||
pub const SC_COND_SIGNAL: u8 = 24;
|
||||
/// carry out broadcast() on the condition
|
||||
pub const SC_COND_BROADCAST: u8 = 25;
|
||||
/// the TtySend system call
|
||||
///
|
||||
/// Sends some char by the serial line emulated
|
||||
pub const SC_TTY_SEND: u8 = 26;
|
||||
/// the TtyReceive system call
|
||||
///
|
||||
/// read some char on the serial line
|
||||
pub const SC_TTY_RECEIVE: u8 = 27;
|
||||
/// the Mkdir system call
|
||||
///
|
||||
/// make a new directory in the file system
|
||||
pub const SC_MKDIR: u8 = 28;
|
||||
/// the Rmdir system call
|
||||
///
|
||||
/// remove a directory from the file system
|
||||
pub const SC_RMDIR: u8 = 29;
|
||||
/// The Remove system call
|
||||
///
|
||||
/// Remove a file from the file system
|
||||
pub const SC_REMOVE: u8 = 30;
|
||||
/// The FSList system call
|
||||
///
|
||||
/// Lists all the file and directories in the filesystem
|
||||
pub const SC_FSLIST: u8 = 31;
|
||||
pub const SC_SYS_TIME: u8 = 32 ;
|
||||
// The systime system call. Gets the system time
|
||||
pub const SC_SYS_TIME: u8 = 32;
|
||||
/// Map a file in memory
|
||||
pub const SC_MMAP: u8 = 33;
|
||||
/// Behaviour undefined and currently unused
|
||||
pub const SC_DEBUG: u8 = 34;
|
||||
|
||||
pub const CONSOLE_OUTPUT: u8 = 1;
|
||||
@ -47,15 +115,15 @@ pub const CONSOLE_OUTPUT: u8 = 1;
|
||||
pub fn call(exception: &ExceptionType, machine: &mut Machine, system: &mut System) -> Result<MachineOk, MachineError> {
|
||||
|
||||
match exception {
|
||||
ExceptionType::NoException => todo!(),
|
||||
ExceptionType::NoException => Err("No Exception no yet implemented")?,
|
||||
ExceptionType::SyscallException => syscall(machine, system),
|
||||
ExceptionType::PagefaultException => todo!(),
|
||||
ExceptionType::ReadOnlyException => todo!(),
|
||||
ExceptionType::BusErrorException => todo!(),
|
||||
ExceptionType::AddressErrorException => todo!(),
|
||||
ExceptionType::OverflowException => todo!(),
|
||||
ExceptionType::IllegalInstrException => todo!(),
|
||||
ExceptionType::NumExceptionTypes => todo!(),
|
||||
ExceptionType::PagefaultException => Err("Page Fault Exception not yet implemented")?,
|
||||
ExceptionType::ReadOnlyException => Err("Read Only Exception not yet implemented")?,
|
||||
ExceptionType::BusErrorException => Err("Bus Error Exception not yet implemented")?,
|
||||
ExceptionType::AddressErrorException => Err("AddressErrorException not yet implemented")?,
|
||||
ExceptionType::OverflowException => Err("OverflowException not yet implemented")?,
|
||||
ExceptionType::IllegalInstrException => Err("IllegalInstrException not yet implemented")?,
|
||||
ExceptionType::NumExceptionTypes => Err("NumExceptionTypes not yet implemented")?,
|
||||
}
|
||||
}
|
||||
|
||||
@ -92,11 +160,10 @@ fn syscall(machine: &mut Machine, system: &mut System) -> Result<MachineOk, Mach
|
||||
|
||||
if f as u8 == CONSOLE_OUTPUT {
|
||||
println!("{}", buffer); // todo replace with console driver in the future
|
||||
} else {
|
||||
todo!("SC_WRITE to file is not yet implemented")
|
||||
}
|
||||
|
||||
Ok(MachineOk::Ok)
|
||||
} else {
|
||||
Err("SC_WRITE to file is not yet implemented")?
|
||||
}
|
||||
},
|
||||
SC_SEEK => todo!(),
|
||||
SC_CLOSE => todo!(),
|
||||
|
@ -2,7 +2,6 @@ pub mod process;
|
||||
pub mod thread;
|
||||
pub mod mgerror;
|
||||
pub mod system;
|
||||
mod ucontext;
|
||||
mod synch;
|
||||
mod thread_manager;
|
||||
pub mod exception;
|
@ -1,74 +0,0 @@
|
||||
#[cfg(not(target_os = "windows"))]
|
||||
use std::mem::MaybeUninit;
|
||||
|
||||
/// Safe wrapper for ucontext_t struct of linux-gnu libc
|
||||
///
|
||||
/// setcontext and getcontext are unsafe function, this wrap unsafe libc functions
|
||||
///
|
||||
/// This struct doesn't work on windows, because this struct is unavailable
|
||||
///
|
||||
/// todo ucontext_t is not thread-safe (doesn't implements Send and Sync trait), and cannot be use in Threads as rust require var in Mutex (see system.rs) to have everything inside to implements thread-safe traits
|
||||
#[derive(PartialEq)]
|
||||
pub struct UContextT {
|
||||
#[cfg(not(target_os = "windows"))] // struct non disponible sur la libc sur windows
|
||||
pub buf: libc::ucontext_t,
|
||||
pub stack_bottom: Vec<i8>
|
||||
}
|
||||
|
||||
#[cfg(not(target_os = "windows"))]
|
||||
#[allow(unused)] // Temporary as we currently doesn't use this structure (this structure may disapear in a near future)
|
||||
impl UContextT {
|
||||
|
||||
pub fn new() -> Self {
|
||||
let mut context = MaybeUninit::<libc::ucontext_t>::uninit();
|
||||
unsafe { libc::getcontext(context.as_mut_ptr()) };
|
||||
Self {
|
||||
buf: unsafe { context.assume_init() },
|
||||
stack_bottom: Vec::default(),
|
||||
}
|
||||
}
|
||||
|
||||
/// Get user context and store it in variable pointed to by UCP.
|
||||
///
|
||||
/// Use `man getcontext` for more informations
|
||||
pub fn get_context(&mut self) -> i32 {
|
||||
unsafe {
|
||||
libc::getcontext(&mut self.buf)
|
||||
}
|
||||
}
|
||||
|
||||
/// Set user context from information of variable pointed to by UCP.
|
||||
///
|
||||
/// Use `man setcontext` for more informations
|
||||
pub fn set_context(&mut self) -> i32 {
|
||||
unsafe {
|
||||
libc::setcontext(&self.buf)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn make_context(&mut self, func: extern "C" fn(), args: i32) {
|
||||
unsafe {
|
||||
libc::makecontext(&mut self.buf, func, args)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#[cfg(target_os = "windows")]
|
||||
#[allow(unused)]
|
||||
impl UContextT {
|
||||
|
||||
pub fn new() -> Self {
|
||||
Self {
|
||||
stack_bottom: Vec::default()
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_context(&mut self) {
|
||||
// no op
|
||||
}
|
||||
|
||||
pub fn set_context(&mut self) {
|
||||
// no op
|
||||
}
|
||||
}
|
@ -231,14 +231,12 @@ impl Machine {
|
||||
self.set_status(MachineStatus::SystemMode);
|
||||
// Handle the interruption
|
||||
match exception::call(&exception, self, system) {
|
||||
Ok(MachineOk::Shutdown) => {
|
||||
Ok(r) => {
|
||||
self.set_status(MachineStatus::UserMode);
|
||||
return Ok(MachineOk::Shutdown);
|
||||
Ok(r)
|
||||
},
|
||||
Err(e) => Err(format!("Syscall {:?} invalid or not implemented", e))?
|
||||
}
|
||||
_ => Err(format!("Syscall {:?} invalid or not implemented", exception))?
|
||||
} // todo: return error if the syscall code is invalid
|
||||
self.set_status(MachineStatus::UserMode);
|
||||
Ok(MachineOk::Ok)
|
||||
}
|
||||
|
||||
/// Execute the instructions table of a machine putted in param
|
||||
@ -249,7 +247,7 @@ impl Machine {
|
||||
pub fn run(&mut self, system: &mut System) {
|
||||
loop {
|
||||
match self.one_instruction(system) {
|
||||
Ok(MachineOk::Ok) => println!("hello"),
|
||||
Ok(MachineOk::Ok) => {},
|
||||
Ok(MachineOk::Shutdown) => break,
|
||||
Err(e) => panic!("FATAL at pc {} -> {}", self.pc, e)
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user