-
Notifications
You must be signed in to change notification settings - Fork 21
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #102 from syswonder/dev
Merge dev into main
- Loading branch information
Showing
132 changed files
with
2,610 additions
and
1,530 deletions.
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -11,14 +11,15 @@ authors = [ | |
"Shiping Yuan <[email protected]>", | ||
] | ||
description = "POSIX-compatible APIs for Ruxos modules" | ||
license = "GPL-3.0-or-later OR Apache-2.0" | ||
license = "Mulan PSL v2" | ||
repository = "https://github.com/syswonder/ruxos/tree/main/api/ruxos_posix_api" | ||
|
||
[features] | ||
default = [] | ||
|
||
smp = ["ruxfeat/smp"] | ||
alloc = ["dep:axalloc", "ruxfeat/alloc"] | ||
paging = ["alloc", "ruxfeat/paging"] | ||
multitask = ["ruxfeat/multitask", "ruxtask/multitask", "dep:ruxfutex"] | ||
fd = ["alloc"] | ||
fs = ["dep:ruxfs", "ruxfeat/fs", "fd"] | ||
|
@@ -51,12 +52,17 @@ axnet = { path = "../../modules/axnet", optional = true } | |
# Other crates | ||
axio = { path = "../../crates/axio" } | ||
axerrno = { path = "../../crates/axerrno" } | ||
memory_addr = { path = "../../crates/memory_addr" } | ||
memory_addr = "0.1.0" | ||
static_assertions = "1.1.0" | ||
spin = { version = "0.9" } | ||
spinlock = { path = "../../crates/spinlock" } | ||
lazy_static = { version = "1.4", features = ["spin_no_std"] } | ||
flatten_objects = { path = "../../crates/flatten_objects" } | ||
page_table = { path = "../../crates/page_table" } | ||
crate_interface = "0.1.1" | ||
|
||
cfg-if = "1.0" | ||
elf = { version = "0.7", default-features = false } | ||
bitflags = "2.2" | ||
|
||
[build-dependencies] | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
use core::ffi::c_int; | ||
|
||
#[derive(Debug, Clone, Copy)] | ||
struct UserCapHeader { | ||
/// Linux Cap Version: | ||
/// Version1 = 0x19980330, | ||
/// Version2 = 0x20071026, | ||
/// Version3 = 0x20080522, | ||
version: u32, | ||
pid: i32, | ||
} | ||
|
||
/// The effective, permitted, and inheritable fields are bit masks of the capabilities. | ||
/// Note that the CAP_* values are bit indexes and need to be bit-shifted before ORing into the bit fields. | ||
#[derive(Debug, Clone, Copy)] | ||
struct UserCapData { | ||
effective: u32, | ||
permitted: u32, | ||
inheritable: u32, | ||
} | ||
|
||
/// get thread capabilities. specific to Linux. | ||
pub fn sys_cap_get(cap_user_header: usize, cap_user_data: usize) -> c_int { | ||
let hdrp = cap_user_header as *const UserCapHeader; | ||
let datap = cap_user_data as *mut UserCapData; | ||
unsafe { | ||
debug!( | ||
"sys_cap_get <= pid {:?}, version {:x?} ", | ||
(*hdrp).pid, | ||
(*hdrp).version | ||
); | ||
} | ||
syscall_body!(sys_cap_get, { | ||
unsafe { | ||
// allow all | ||
(*datap).effective = u32::MAX; | ||
(*datap).inheritable = u32::MAX; | ||
(*datap).permitted = u32::MAX; | ||
}; | ||
Ok(0) | ||
}) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
#![allow(unused)] | ||
|
||
pub const AT_NULL: usize = 0; | ||
pub const AT_IGNORE: usize = 1; | ||
|
||
pub const AT_EXECFD: usize = 2; | ||
|
||
/// The address of the program headers of the executable. | ||
pub const AT_PHDR: usize = 3; | ||
|
||
pub const AT_PHENT: usize = 4; | ||
pub const AT_PHNUM: usize = 5; | ||
pub const AT_PAGESZ: usize = 6; | ||
|
||
/// The base address of the program interpreter (usually, the dynamic linker). | ||
pub const AT_BASE: usize = 7; | ||
|
||
pub const AT_FLAGS: usize = 8; | ||
pub const AT_ENTRY: usize = 9; | ||
pub const AT_NOTELF: usize = 10; | ||
pub const AT_UID: usize = 11; | ||
pub const AT_EUID: usize = 12; | ||
pub const AT_GID: usize = 13; | ||
pub const AT_EGID: usize = 14; | ||
pub const AT_PLATFORM: usize = 15; | ||
pub const AT_HWCAP: usize = 16; | ||
pub const AT_CLKTCK: usize = 17; | ||
pub const AT_DCACHEBSIZE: usize = 19; | ||
pub const AT_ICACHEBSIZE: usize = 20; | ||
pub const AT_UCACHEBSIZE: usize = 21; | ||
pub const AT_SECURE: usize = 23; | ||
pub const AT_RANDOM: usize = 25; | ||
|
||
/// A pointer to a string containing the pathname used to execute the program. | ||
pub const AT_EXECFN: usize = 31; | ||
|
||
/// The address of a page containing the vDSO that the kernel creates | ||
pub const AT_SYSINFO_EHDR: usize = 33; | ||
|
||
/// The entry point to the system call function in the vDSO. Not present/needed on all architectures (e.g., absent on x86-64). | ||
pub const AT_SYSINFO: usize = 32; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,106 @@ | ||
use crate::{ctypes::kstat, *}; | ||
use alloc::{vec, vec::Vec}; | ||
use core::ptr::null_mut; | ||
|
||
#[derive(Debug)] | ||
pub struct ElfProg { | ||
pub base: usize, | ||
pub entry: usize, | ||
pub interp_path: Vec<u8>, | ||
pub phent: usize, | ||
pub phnum: usize, | ||
pub phdr: usize, | ||
} | ||
|
||
impl ElfProg { | ||
/// read elf from `path`, and copy LOAD segments to a alloacated memory | ||
/// | ||
/// and load interp, if needed. | ||
pub fn new(filepath: &str) -> Self { | ||
debug!("sys_execve: new elf prog: {filepath}"); | ||
|
||
// open file | ||
let fd = sys_open(filepath.as_ptr() as _, ctypes::O_RDWR as _, 0); | ||
|
||
// get file size | ||
let mut buf = ctypes::kstat { | ||
..Default::default() | ||
}; | ||
sys_fstat(fd, &mut buf as *const kstat as *mut _); | ||
let filesize = buf.st_size as usize; | ||
|
||
// read file | ||
let mut file = vec![0u8; filesize]; | ||
sys_read(fd, file.as_mut_ptr() as *mut _, filesize); | ||
debug!("sys_execve: read file size 0x{filesize:x}"); | ||
sys_close(fd); | ||
|
||
// parse elf | ||
let file = elf::ElfBytes::<elf::endian::AnyEndian>::minimal_parse(&file) | ||
.expect("parse ELF failed"); | ||
|
||
// get program's LOAD mem size | ||
let mut min_addr = 0; | ||
let mut max_addr = 0; | ||
let segs = file.segments().unwrap(); | ||
for seg in segs { | ||
if seg.p_type == elf::abi::PT_LOAD { | ||
min_addr = min_addr.min(seg.p_vaddr); | ||
max_addr = max_addr.max(seg.p_vaddr + seg.p_memsz); | ||
} | ||
} | ||
let msize = (max_addr - min_addr) as usize; | ||
|
||
// alloc memory for LOAD | ||
let prot = ctypes::PROT_WRITE | ctypes::PROT_READ | ctypes::PROT_EXEC; | ||
let flags = ctypes::MAP_ANONYMOUS | ctypes::MAP_PRIVATE; | ||
let base = crate::sys_mmap(null_mut(), msize, prot as _, flags as _, -1, 0) as usize; | ||
|
||
// copy LOAD segments | ||
for seg in segs { | ||
if seg.p_type == elf::abi::PT_LOAD { | ||
let data = file.segment_data(&seg).unwrap(); | ||
let dst = (seg.p_vaddr as usize + base) as *mut u8; | ||
unsafe { dst.copy_from_nonoverlapping(data.as_ptr(), data.len()) }; | ||
} | ||
} | ||
|
||
// phdr | ||
let phdr = base + file.ehdr.e_phoff as usize; | ||
|
||
// get entry | ||
let entry = file.ehdr.e_entry as usize + base; | ||
|
||
// parse interpreter | ||
let mut interp_path = vec![]; | ||
for seg in file.segments().unwrap() { | ||
if seg.p_type == elf::abi::PT_INTERP { | ||
let data = file.segment_data(&seg).unwrap().to_vec(); | ||
interp_path = data; | ||
break; | ||
} | ||
} | ||
|
||
// get address of .text for debugging | ||
let text_section_addr = base | ||
+ file | ||
.section_header_by_name(".text") | ||
.unwrap() | ||
.unwrap() | ||
.sh_offset as usize; | ||
debug!( | ||
"sys_execve: loaded ELF in 0x{:x}, .text is 0x{:x}", | ||
base, text_section_addr | ||
); | ||
|
||
// create retval | ||
Self { | ||
base, | ||
entry, | ||
interp_path, | ||
phent: file.ehdr.e_phentsize as usize, | ||
phnum: file.ehdr.e_phnum as usize, | ||
phdr, | ||
} | ||
} | ||
} |
Oops, something went wrong.