Skip to content

Commit

Permalink
fix errno to error
Browse files Browse the repository at this point in the history
  • Loading branch information
templexxx committed Nov 5, 2022
1 parent 2ce8ad6 commit eb53480
Show file tree
Hide file tree
Showing 3 changed files with 97 additions and 94 deletions.
6 changes: 5 additions & 1 deletion omo/src/errors.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use std::io;
use std::{io, io::Error};

use thiserror::Error;
use unicorn_engine::unicorn_const::uc_error;
Expand All @@ -15,6 +15,10 @@ pub enum EmulatorError {
Custom(#[from] anyhow::Error),
}

pub fn from_raw_syscall_ret(ret: i64) -> EmulatorError {
EmulatorError::IOError(Error::from_raw_os_error(-ret as i32))
}

impl From<uc_error> for EmulatorError {
fn from(e: uc_error) -> Self {
Self::UcError(e)
Expand Down
108 changes: 57 additions & 51 deletions omo/src/os/linux/file.rs
Original file line number Diff line number Diff line change
@@ -1,127 +1,133 @@
use std::io;
use crate::{
errors::{from_raw_syscall_ret, EmulatorError},
os::linux::syscall::*,
};

use crate::{errors::EmulatorError, os::linux::syscall::*};

pub fn open(path: &str, flags: u64, mode: u64) -> Result<i64, EmulatorError> {
pub fn open(path: *const u8, flags: u64, mode: u64) -> Result<i64, EmulatorError> {
let flags = flags & 0xffffffff;
let open_mode = mode & 0x7fffffff;
let fd = syscall_3(
LinuxSysCalls::Open as u64,
path.as_ptr() as u64,
flags,
open_mode,
);
let fd = unsafe { syscall_3(LinuxSysCalls::Open as u64, path as u64, flags, open_mode) };
if fd < 0 {
Err(EmulatorError::IOError(io::Error::last_os_error()))
Err(from_raw_syscall_ret(fd))
} else {
Ok(fd)
}
}

pub fn read(fd: u64, buf: u64, size: u64) -> Result<i64, EmulatorError> {
let size = syscall_3(LinuxSysCalls::Read as u64, fd, buf, size);
pub fn read(fd: u64, buf: *mut u8, size: u64) -> Result<i64, EmulatorError> {
let size = unsafe { syscall_3(LinuxSysCalls::Read as u64, fd, buf as u64, size) };
if size < 0 {
Err(EmulatorError::IOError(io::Error::last_os_error()))
Err(from_raw_syscall_ret(size))
} else {
Ok(size)
}
}

pub fn write(fd: u64, data: u64, len: u64) -> Result<i64, EmulatorError> {
let size = syscall_3(LinuxSysCalls::Write as u64, fd, data, len);
pub fn write(fd: u64, data: *const u8, len: u64) -> Result<i64, EmulatorError> {
let size = unsafe { syscall_3(LinuxSysCalls::Write as u64, fd, data as u64, len) };
if size < 0 {
Err(EmulatorError::IOError(io::Error::last_os_error()))
Err(from_raw_syscall_ret(size))
} else {
Ok(size)
}
}

pub fn close(fd: u64) -> Result<i64, EmulatorError> {
let ret = syscall_1(LinuxSysCalls::Close as u64, fd);
let ret = unsafe { syscall_1(LinuxSysCalls::Close as u64, fd) };
if ret < 0 {
Err(EmulatorError::IOError(io::Error::last_os_error()))
Err(from_raw_syscall_ret(ret))
} else {
Ok(ret)
}
}

pub fn lseek(fd: u64, offset: u64, whence: u64) -> Result<i64, EmulatorError> {
let off = syscall_3(LinuxSysCalls::Lseek as u64, fd, offset, whence);
let off = unsafe { syscall_3(LinuxSysCalls::Lseek as u64, fd, offset, whence) };
if off < 0 {
Err(EmulatorError::IOError(io::Error::last_os_error()))
Err(from_raw_syscall_ret(off))
} else {
Ok(off)
}
}

pub fn fcntl(fd: u64, cmd: u64, arg: u64) -> Result<i64, EmulatorError> {
let ret = syscall_3(LinuxSysCalls::Fcntl as u64, fd, cmd, arg);
let ret = unsafe { syscall_3(LinuxSysCalls::Fcntl as u64, fd, cmd, arg) };
if ret < 0 {
Err(EmulatorError::IOError(io::Error::last_os_error()))
Err(from_raw_syscall_ret(ret))
} else {
Ok(ret)
}
}

pub fn readlink(path: &str, buf: u64, buf_size: u64) -> Result<i64, EmulatorError> {
let ret = syscall_3(
LinuxSysCalls::Readlink as u64,
path.as_ptr() as u64,
buf,
buf_size,
);
pub fn readlink(path: *const u8, buf: *mut u8, buf_size: u64) -> Result<i64, EmulatorError> {
let ret = unsafe {
syscall_3(
LinuxSysCalls::Readlink as u64,
path as u64,
buf as u64,
buf_size,
)
};
if ret < 0 {
Err(EmulatorError::IOError(io::Error::last_os_error()))
Err(from_raw_syscall_ret(ret))
} else {
Ok(ret)
}
}

pub fn stat(path: &str, stat_buf: u64) -> Result<i64, EmulatorError> {
let ret = syscall_2(LinuxSysCalls::Stat as u64, path.as_ptr() as u64, stat_buf);
pub fn stat(path: *const u8, stat_buf: *mut StatX8664) -> Result<i64, EmulatorError> {
let ret = unsafe { syscall_2(LinuxSysCalls::Stat as u64, path as u64, stat_buf as u64) };
if ret < 0 {
Err(EmulatorError::IOError(io::Error::last_os_error()))
Err(from_raw_syscall_ret(ret))
} else {
Ok(ret)
}
}

pub fn fstat(fd: u64, stat_buf: u64) -> Result<i64, EmulatorError> {
let ret = syscall_2(LinuxSysCalls::Fstat as u64, fd, stat_buf);
pub fn fstat(fd: u64, stat_buf: *mut StatX8664) -> Result<i64, EmulatorError> {
let ret = unsafe { syscall_2(LinuxSysCalls::Fstat as u64, fd, stat_buf as u64) };
if ret < 0 {
Err(EmulatorError::IOError(io::Error::last_os_error()))
Err(from_raw_syscall_ret(ret))
} else {
Ok(ret)
}
}

pub fn lstat(path: &str, stat_buf: u64) -> Result<i64, EmulatorError> {
let ret = syscall_2(LinuxSysCalls::Lstat as u64, path.as_ptr() as u64, stat_buf);
pub fn lstat(path: *const u8, stat_buf: *mut StatX8664) -> Result<i64, EmulatorError> {
let ret = unsafe { syscall_2(LinuxSysCalls::Lstat as u64, path as u64, stat_buf as u64) };
if ret < 0 {
Err(EmulatorError::IOError(io::Error::last_os_error()))
Err(from_raw_syscall_ret(ret))
} else {
Ok(ret)
}
}

pub fn fstatat64(dir_fd: u64, path: &str, stat_buf: u64, flags: u64) -> Result<i64, EmulatorError> {
let ret = syscall_4(
LinuxSysCalls::Newfstatat as u64,
dir_fd,
path.as_ptr() as u64,
stat_buf,
flags,
);
pub fn fstatat64(
dir_fd: u64,
path: *const u8,
stat_buf: *mut StatX8664,
flags: u64,
) -> Result<i64, EmulatorError> {
let ret = unsafe {
syscall_4(
LinuxSysCalls::Newfstatat as u64,
dir_fd,
path as u64,
stat_buf as u64,
flags,
)
};
if ret < 0 {
Err(EmulatorError::IOError(io::Error::last_os_error()))
Err(from_raw_syscall_ret(ret))
} else {
Ok(ret)
}
}

pub fn ioctl(fd: u64, cmd: u64, arg: u64) -> Result<i64, EmulatorError> {
let ret = syscall_3(LinuxSysCalls::Ioctl as u64, fd, cmd, arg);
let ret = unsafe { syscall_3(LinuxSysCalls::Ioctl as u64, fd, cmd, arg) };
if ret < 0 {
Err(EmulatorError::IOError(io::Error::last_os_error()))
Err(from_raw_syscall_ret(ret))
} else {
Ok(ret)
}
Expand Down
77 changes: 35 additions & 42 deletions omo/src/os/linux/syscall.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,61 +26,54 @@ pub enum LinuxSysCalls {
}

// x86_64 raw syscall.
pub fn syscall_1(trap: u64, arg1: u64) -> i64 {
pub unsafe fn syscall_1(trap: u64, arg1: u64) -> i64 {
let res;
unsafe {
asm!(
"syscall",
in("rax") trap,
in("rdi") arg1,
lateout("rax") res,
);
}
asm!(
"syscall",
in("rax") trap,
in("rdi") arg1,
lateout("rax") res,
);
res
}

pub fn syscall_2(trap: u64, arg1: u64, arg2: u64) -> i64 {
pub unsafe fn syscall_2(trap: u64, arg1: u64, arg2: u64) -> i64 {
let res;
unsafe {
asm!(
"syscall",
in("rax") trap,
in("rdi") arg1,
in("rsi") arg2,
lateout("rax") res,
);
}
asm!(
"syscall",
in("rax") trap,
in("rdi") arg1,
in("rsi") arg2,
lateout("rax") res,
);
res
}

pub fn syscall_3(trap: u64, arg1: u64, arg2: u64, arg3: u64) -> i64 {
pub unsafe fn syscall_3(trap: u64, arg1: u64, arg2: u64, arg3: u64) -> i64 {
let res;
unsafe {
asm!(
"syscall",
in("rax") trap,
in("rdi") arg1,
in("rsi") arg2,
in("rdx") arg3,
lateout("rax") res,
);
}
asm!(
"syscall",
in("rax") trap,
in("rdi") arg1,
in("rsi") arg2,
in("rdx") arg3,
lateout("rax") res,
);

res
}

pub fn syscall_4(trap: u64, arg1: u64, arg2: u64, arg3: u64, arg4: u64) -> i64 {
pub unsafe fn syscall_4(trap: u64, arg1: u64, arg2: u64, arg3: u64, arg4: u64) -> i64 {
let res;
unsafe {
asm!(
"syscall",
in("rax") trap,
in("rdi") arg1,
in("rsi") arg2,
in("rdx") arg3,
in("r10") arg4,
lateout("rax") res,
);
}
asm!(
"syscall",
in("rax") trap,
in("rdi") arg1,
in("rsi") arg2,
in("rdx") arg3,
in("r10") arg4,
lateout("rax") res,
);
res
}

Expand Down

0 comments on commit eb53480

Please sign in to comment.