mirror of
https://github.com/DragonOS-Community/DragonOS.git
synced 2025-06-08 18:26:48 +00:00
fix: 修复由于升级到2024-07-23工具链之后,某些机器上面内核运行一直fault的问题。 (#870)
* fix: 修复由于升级到2024-07-23工具链之后,某些机器上面内核运行一直fault的问题。
This commit is contained in:
parent
3c0a1c8fa2
commit
703ce5a77c
4
Makefile
4
Makefile
@ -156,14 +156,14 @@ log-monitor:
|
|||||||
.PHONY: update-submodules
|
.PHONY: update-submodules
|
||||||
update-submodules:
|
update-submodules:
|
||||||
@echo "更新子模块"
|
@echo "更新子模块"
|
||||||
@git submodule update --recursive
|
@git submodule update --recursive --init
|
||||||
@git submodule foreach git pull origin master
|
@git submodule foreach git pull origin master
|
||||||
|
|
||||||
.PHONY: update-submodules-by-mirror
|
.PHONY: update-submodules-by-mirror
|
||||||
update-submodules-by-mirror:
|
update-submodules-by-mirror:
|
||||||
@echo "从镜像更新子模块"
|
@echo "从镜像更新子模块"
|
||||||
@git config --global url."https://git.mirrors.dragonos.org.cn/DragonOS-Community/".insteadOf https://github.com/DragonOS-Community/
|
@git config --global url."https://git.mirrors.dragonos.org.cn/DragonOS-Community/".insteadOf https://github.com/DragonOS-Community/
|
||||||
@$(MAKE) update-submodules
|
@$(MAKE) update-submodules --init
|
||||||
@git config --global --unset url."https://git.mirrors.dragonos.org.cn/DragonOS-Community/".insteadOf
|
@git config --global --unset url."https://git.mirrors.dragonos.org.cn/DragonOS-Community/".insteadOf
|
||||||
|
|
||||||
help:
|
help:
|
||||||
|
@ -6,8 +6,7 @@
|
|||||||
runner = "bootimage runner"
|
runner = "bootimage runner"
|
||||||
|
|
||||||
[build]
|
[build]
|
||||||
# '-Zlinker-features=-lld' 禁用rustlld(20240723),因为它与linkme0.3版本冲突
|
rustflags = ["-Clink-args=-znostart-stop-gc"]
|
||||||
rustflags = ["-Zlinker-features=-lld"]
|
rustdocflags = ["-Clink-args=-znostart-stop-gc"]
|
||||||
rustdocflags = ["-Zlinker-features=-lld"]
|
|
||||||
|
|
||||||
[env]
|
[env]
|
||||||
|
@ -25,9 +25,9 @@ clean:
|
|||||||
|
|
||||||
.PHONY: fmt
|
.PHONY: fmt
|
||||||
fmt:
|
fmt:
|
||||||
@cargo fmt --all $(FMT_CHECK)
|
RUSTFLAGS="$(RUSTFLAGS)" cargo fmt --all $(FMT_CHECK)
|
||||||
ifeq ($(ARCH), x86_64)
|
ifeq ($(ARCH), x86_64)
|
||||||
@cargo clippy --all-features
|
RUSTFLAGS="$(RUSTFLAGS)" cargo clippy --all-features
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
|
||||||
@ -36,12 +36,12 @@ check: ECHO
|
|||||||
# @echo "Checking kernel... ARCH=$(ARCH)"
|
# @echo "Checking kernel... ARCH=$(ARCH)"
|
||||||
# @exit 1
|
# @exit 1
|
||||||
ifeq ($(ARCH), x86_64)
|
ifeq ($(ARCH), x86_64)
|
||||||
@cargo +nightly-2024-07-23 check --workspace $(CARGO_ZBUILD) --message-format=json --target ./src/$(TARGET_JSON)
|
RUSTFLAGS="$(RUSTFLAGS)" cargo +nightly-2024-07-23 check --workspace $(CARGO_ZBUILD) --message-format=json --target ./src/$(TARGET_JSON)
|
||||||
else ifeq ($(ARCH), riscv64)
|
else ifeq ($(ARCH), riscv64)
|
||||||
@cargo +nightly-2024-07-23 check --workspace $(CARGO_ZBUILD) --message-format=json --target $(TARGET_JSON)
|
RUSTFLAGS="$(RUSTFLAGS)" cargo +nightly-2024-07-23 check --workspace $(CARGO_ZBUILD) --message-format=json --target $(TARGET_JSON)
|
||||||
endif
|
endif
|
||||||
|
|
||||||
test:
|
test:
|
||||||
# 测试内核库
|
# 测试内核库
|
||||||
@cargo +nightly-2024-07-23 test --workspace --exclude dragonos_kernel
|
RUSTFLAGS="$(RUSTFLAGS)" cargo +nightly-2024-07-23 test --workspace --exclude dragonos_kernel
|
||||||
|
|
||||||
|
@ -42,3 +42,6 @@ endif
|
|||||||
ifeq ($(DEBUG), DEBUG)
|
ifeq ($(DEBUG), DEBUG)
|
||||||
GLOBAL_CFLAGS += -g
|
GLOBAL_CFLAGS += -g
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
export RUSTFLAGS := -C link-args=-znostart-stop-gc
|
||||||
|
export RUSTDOCFLAGS := -C link-args=-znostart-stop-gc
|
@ -1,4 +1,4 @@
|
|||||||
use alloc::{string::String, vec::Vec};
|
use alloc::{ffi::CString, string::String, vec::Vec};
|
||||||
use riscv::register::sstatus::{FS, SPP};
|
use riscv::register::sstatus::{FS, SPP};
|
||||||
use system_error::SystemError;
|
use system_error::SystemError;
|
||||||
|
|
||||||
@ -16,8 +16,8 @@ use crate::{
|
|||||||
impl Syscall {
|
impl Syscall {
|
||||||
pub fn do_execve(
|
pub fn do_execve(
|
||||||
path: String,
|
path: String,
|
||||||
argv: Vec<String>,
|
argv: Vec<CString>,
|
||||||
envp: Vec<String>,
|
envp: Vec<CString>,
|
||||||
regs: &mut TrapFrame,
|
regs: &mut TrapFrame,
|
||||||
) -> Result<(), SystemError> {
|
) -> Result<(), SystemError> {
|
||||||
// 关中断,防止在设置地址空间的时候,发生中断,然后进调度器,出现错误。
|
// 关中断,防止在设置地址空间的时候,发生中断,然后进调度器,出现错误。
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
use alloc::{string::String, sync::Arc, vec::Vec};
|
use alloc::{ffi::CString, string::String, sync::Arc, vec::Vec};
|
||||||
use system_error::SystemError;
|
use system_error::SystemError;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
@ -19,14 +19,14 @@ use crate::{
|
|||||||
impl Syscall {
|
impl Syscall {
|
||||||
pub fn do_execve(
|
pub fn do_execve(
|
||||||
path: String,
|
path: String,
|
||||||
argv: Vec<String>,
|
argv: Vec<CString>,
|
||||||
envp: Vec<String>,
|
envp: Vec<CString>,
|
||||||
regs: &mut TrapFrame,
|
regs: &mut TrapFrame,
|
||||||
) -> Result<(), SystemError> {
|
) -> Result<(), SystemError> {
|
||||||
// 关中断,防止在设置地址空间的时候,发生中断,然后进调度器,出现错误。
|
// 关中断,防止在设置地址空间的时候,发生中断,然后进调度器,出现错误。
|
||||||
let irq_guard = unsafe { CurrentIrqArch::save_and_disable_irq() };
|
let irq_guard = unsafe { CurrentIrqArch::save_and_disable_irq() };
|
||||||
let pcb = ProcessManager::current_pcb();
|
let pcb = ProcessManager::current_pcb();
|
||||||
// crate::debug!(
|
// log::debug!(
|
||||||
// "pid: {:?} do_execve: path: {:?}, argv: {:?}, envp: {:?}\n",
|
// "pid: {:?} do_execve: path: {:?}, argv: {:?}, envp: {:?}\n",
|
||||||
// pcb.pid(),
|
// pcb.pid(),
|
||||||
// path,
|
// path,
|
||||||
|
@ -38,8 +38,9 @@ pub(super) fn do_faccessat(
|
|||||||
// let follow_symlink = flags & AtFlags::AT_SYMLINK_NOFOLLOW.bits() as u32 == 0;
|
// let follow_symlink = flags & AtFlags::AT_SYMLINK_NOFOLLOW.bits() as u32 == 0;
|
||||||
|
|
||||||
let path = check_and_clone_cstr(path, Some(MAX_PATHLEN))?;
|
let path = check_and_clone_cstr(path, Some(MAX_PATHLEN))?;
|
||||||
|
let path = path.to_str().map_err(|_| SystemError::EINVAL)?;
|
||||||
|
|
||||||
let (inode, path) = user_path_at(&ProcessManager::current_pcb(), dirfd, &path)?;
|
let (inode, path) = user_path_at(&ProcessManager::current_pcb(), dirfd, path)?;
|
||||||
|
|
||||||
// 如果找不到文件,则返回错误码ENOENT
|
// 如果找不到文件,则返回错误码ENOENT
|
||||||
let _inode = inode.lookup_follow_symlink(path.as_str(), VFS_MAX_FOLLOW_SYMLINK_TIMES)?;
|
let _inode = inode.lookup_follow_symlink(path.as_str(), VFS_MAX_FOLLOW_SYMLINK_TIMES)?;
|
||||||
@ -50,8 +51,9 @@ pub(super) fn do_faccessat(
|
|||||||
|
|
||||||
pub fn do_fchmodat(dirfd: i32, path: *const u8, _mode: ModeType) -> Result<usize, SystemError> {
|
pub fn do_fchmodat(dirfd: i32, path: *const u8, _mode: ModeType) -> Result<usize, SystemError> {
|
||||||
let path = check_and_clone_cstr(path, Some(MAX_PATHLEN))?;
|
let path = check_and_clone_cstr(path, Some(MAX_PATHLEN))?;
|
||||||
|
let path = path.to_str().map_err(|_| SystemError::EINVAL)?;
|
||||||
|
|
||||||
let (inode, path) = user_path_at(&ProcessManager::current_pcb(), dirfd, &path)?;
|
let (inode, path) = user_path_at(&ProcessManager::current_pcb(), dirfd, path)?;
|
||||||
|
|
||||||
// 如果找不到文件,则返回错误码ENOENT
|
// 如果找不到文件,则返回错误码ENOENT
|
||||||
let _inode = inode.lookup_follow_symlink(path.as_str(), VFS_MAX_FOLLOW_SYMLINK_TIMES)?;
|
let _inode = inode.lookup_follow_symlink(path.as_str(), VFS_MAX_FOLLOW_SYMLINK_TIMES)?;
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
use core::ffi::c_void;
|
use core::ffi::c_void;
|
||||||
use core::mem::size_of;
|
use core::mem::size_of;
|
||||||
|
|
||||||
use alloc::string::ToString;
|
|
||||||
use alloc::{string::String, sync::Arc, vec::Vec};
|
use alloc::{string::String, sync::Arc, vec::Vec};
|
||||||
use log::warn;
|
use log::warn;
|
||||||
use system_error::SystemError;
|
use system_error::SystemError;
|
||||||
@ -484,7 +483,10 @@ impl Syscall {
|
|||||||
mode: u32,
|
mode: u32,
|
||||||
follow_symlink: bool,
|
follow_symlink: bool,
|
||||||
) -> Result<usize, SystemError> {
|
) -> Result<usize, SystemError> {
|
||||||
let path = check_and_clone_cstr(path, Some(MAX_PATHLEN))?;
|
let path = check_and_clone_cstr(path, Some(MAX_PATHLEN))?
|
||||||
|
.into_string()
|
||||||
|
.map_err(|_| SystemError::EINVAL)?;
|
||||||
|
|
||||||
let open_flags: FileMode = FileMode::from_bits(o_flags).ok_or(SystemError::EINVAL)?;
|
let open_flags: FileMode = FileMode::from_bits(o_flags).ok_or(SystemError::EINVAL)?;
|
||||||
let mode = ModeType::from_bits(mode).ok_or(SystemError::EINVAL)?;
|
let mode = ModeType::from_bits(mode).ok_or(SystemError::EINVAL)?;
|
||||||
return do_sys_open(
|
return do_sys_open(
|
||||||
@ -503,7 +505,10 @@ impl Syscall {
|
|||||||
mode: u32,
|
mode: u32,
|
||||||
follow_symlink: bool,
|
follow_symlink: bool,
|
||||||
) -> Result<usize, SystemError> {
|
) -> Result<usize, SystemError> {
|
||||||
let path = check_and_clone_cstr(path, Some(MAX_PATHLEN))?;
|
let path = check_and_clone_cstr(path, Some(MAX_PATHLEN))?
|
||||||
|
.into_string()
|
||||||
|
.map_err(|_| SystemError::EINVAL)?;
|
||||||
|
|
||||||
let open_flags: FileMode = FileMode::from_bits(o_flags).ok_or(SystemError::EINVAL)?;
|
let open_flags: FileMode = FileMode::from_bits(o_flags).ok_or(SystemError::EINVAL)?;
|
||||||
let mode = ModeType::from_bits(mode).ok_or(SystemError::EINVAL)?;
|
let mode = ModeType::from_bits(mode).ok_or(SystemError::EINVAL)?;
|
||||||
return do_sys_open(dirfd, &path, open_flags, mode, follow_symlink);
|
return do_sys_open(dirfd, &path, open_flags, mode, follow_symlink);
|
||||||
@ -682,7 +687,10 @@ impl Syscall {
|
|||||||
return Err(SystemError::EFAULT);
|
return Err(SystemError::EFAULT);
|
||||||
}
|
}
|
||||||
|
|
||||||
let path = check_and_clone_cstr(path, Some(MAX_PATHLEN))?;
|
let path = check_and_clone_cstr(path, Some(MAX_PATHLEN))?
|
||||||
|
.into_string()
|
||||||
|
.map_err(|_| SystemError::EINVAL)?;
|
||||||
|
|
||||||
let proc = ProcessManager::current_pcb();
|
let proc = ProcessManager::current_pcb();
|
||||||
// Copy path to kernel space to avoid some security issues
|
// Copy path to kernel space to avoid some security issues
|
||||||
let mut new_path = String::from("");
|
let mut new_path = String::from("");
|
||||||
@ -786,7 +794,10 @@ impl Syscall {
|
|||||||
///
|
///
|
||||||
/// @return uint64_t 负数错误码 / 0表示成功
|
/// @return uint64_t 负数错误码 / 0表示成功
|
||||||
pub fn mkdir(path: *const u8, mode: usize) -> Result<usize, SystemError> {
|
pub fn mkdir(path: *const u8, mode: usize) -> Result<usize, SystemError> {
|
||||||
let path = check_and_clone_cstr(path, Some(MAX_PATHLEN))?;
|
let path = check_and_clone_cstr(path, Some(MAX_PATHLEN))?
|
||||||
|
.into_string()
|
||||||
|
.map_err(|_| SystemError::EINVAL)?;
|
||||||
|
|
||||||
do_mkdir_at(
|
do_mkdir_at(
|
||||||
AtFlags::AT_FDCWD.bits(),
|
AtFlags::AT_FDCWD.bits(),
|
||||||
&path,
|
&path,
|
||||||
@ -861,7 +872,10 @@ impl Syscall {
|
|||||||
|
|
||||||
pub fn link(old: *const u8, new: *const u8) -> Result<usize, SystemError> {
|
pub fn link(old: *const u8, new: *const u8) -> Result<usize, SystemError> {
|
||||||
let get_path = |cstr: *const u8| -> Result<String, SystemError> {
|
let get_path = |cstr: *const u8| -> Result<String, SystemError> {
|
||||||
let res = check_and_clone_cstr(cstr, Some(MAX_PATHLEN))?;
|
let res = check_and_clone_cstr(cstr, Some(MAX_PATHLEN))?
|
||||||
|
.into_string()
|
||||||
|
.map_err(|_| SystemError::EINVAL)?;
|
||||||
|
|
||||||
if res.len() >= MAX_PATHLEN {
|
if res.len() >= MAX_PATHLEN {
|
||||||
return Err(SystemError::ENAMETOOLONG);
|
return Err(SystemError::ENAMETOOLONG);
|
||||||
}
|
}
|
||||||
@ -888,8 +902,12 @@ impl Syscall {
|
|||||||
new: *const u8,
|
new: *const u8,
|
||||||
flags: i32,
|
flags: i32,
|
||||||
) -> Result<usize, SystemError> {
|
) -> Result<usize, SystemError> {
|
||||||
let old = check_and_clone_cstr(old, Some(MAX_PATHLEN))?;
|
let old = check_and_clone_cstr(old, Some(MAX_PATHLEN))?
|
||||||
let new = check_and_clone_cstr(new, Some(MAX_PATHLEN))?;
|
.into_string()
|
||||||
|
.map_err(|_| SystemError::EINVAL)?;
|
||||||
|
let new = check_and_clone_cstr(new, Some(MAX_PATHLEN))?
|
||||||
|
.into_string()
|
||||||
|
.map_err(|_| SystemError::EINVAL)?;
|
||||||
if old.len() >= MAX_PATHLEN || new.len() >= MAX_PATHLEN {
|
if old.len() >= MAX_PATHLEN || new.len() >= MAX_PATHLEN {
|
||||||
return Err(SystemError::ENAMETOOLONG);
|
return Err(SystemError::ENAMETOOLONG);
|
||||||
}
|
}
|
||||||
@ -913,7 +931,9 @@ impl Syscall {
|
|||||||
pub fn unlinkat(dirfd: i32, path: *const u8, flags: u32) -> Result<usize, SystemError> {
|
pub fn unlinkat(dirfd: i32, path: *const u8, flags: u32) -> Result<usize, SystemError> {
|
||||||
let flags = AtFlags::from_bits(flags as i32).ok_or(SystemError::EINVAL)?;
|
let flags = AtFlags::from_bits(flags as i32).ok_or(SystemError::EINVAL)?;
|
||||||
|
|
||||||
let path = check_and_clone_cstr(path, Some(MAX_PATHLEN))?;
|
let path = check_and_clone_cstr(path, Some(MAX_PATHLEN))?
|
||||||
|
.into_string()
|
||||||
|
.map_err(|_| SystemError::EINVAL)?;
|
||||||
|
|
||||||
if flags.contains(AtFlags::AT_REMOVEDIR) {
|
if flags.contains(AtFlags::AT_REMOVEDIR) {
|
||||||
// debug!("rmdir");
|
// debug!("rmdir");
|
||||||
@ -938,12 +958,16 @@ impl Syscall {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn rmdir(path: *const u8) -> Result<usize, SystemError> {
|
pub fn rmdir(path: *const u8) -> Result<usize, SystemError> {
|
||||||
let path = check_and_clone_cstr(path, Some(MAX_PATHLEN))?;
|
let path = check_and_clone_cstr(path, Some(MAX_PATHLEN))?
|
||||||
|
.into_string()
|
||||||
|
.map_err(|_| SystemError::EINVAL)?;
|
||||||
return do_remove_dir(AtFlags::AT_FDCWD.bits(), &path).map(|v| v as usize);
|
return do_remove_dir(AtFlags::AT_FDCWD.bits(), &path).map(|v| v as usize);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn unlink(path: *const u8) -> Result<usize, SystemError> {
|
pub fn unlink(path: *const u8) -> Result<usize, SystemError> {
|
||||||
let path = check_and_clone_cstr(path, Some(MAX_PATHLEN))?;
|
let path = check_and_clone_cstr(path, Some(MAX_PATHLEN))?
|
||||||
|
.into_string()
|
||||||
|
.map_err(|_| SystemError::EINVAL)?;
|
||||||
return do_unlink_at(AtFlags::AT_FDCWD.bits(), &path).map(|v| v as usize);
|
return do_unlink_at(AtFlags::AT_FDCWD.bits(), &path).map(|v| v as usize);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -970,8 +994,14 @@ impl Syscall {
|
|||||||
filename_to: *const u8,
|
filename_to: *const u8,
|
||||||
_flags: u32,
|
_flags: u32,
|
||||||
) -> Result<usize, SystemError> {
|
) -> Result<usize, SystemError> {
|
||||||
let filename_from = check_and_clone_cstr(filename_from, Some(MAX_PATHLEN)).unwrap();
|
let filename_from = check_and_clone_cstr(filename_from, Some(MAX_PATHLEN))
|
||||||
let filename_to = check_and_clone_cstr(filename_to, Some(MAX_PATHLEN)).unwrap();
|
.unwrap()
|
||||||
|
.into_string()
|
||||||
|
.map_err(|_| SystemError::EINVAL)?;
|
||||||
|
let filename_to = check_and_clone_cstr(filename_to, Some(MAX_PATHLEN))
|
||||||
|
.unwrap()
|
||||||
|
.into_string()
|
||||||
|
.map_err(|_| SystemError::EINVAL)?;
|
||||||
// 文件名过长
|
// 文件名过长
|
||||||
if filename_from.len() > MAX_PATHLEN || filename_to.len() > MAX_PATHLEN {
|
if filename_from.len() > MAX_PATHLEN || filename_to.len() > MAX_PATHLEN {
|
||||||
return Err(SystemError::ENAMETOOLONG);
|
return Err(SystemError::ENAMETOOLONG);
|
||||||
@ -1315,7 +1345,10 @@ impl Syscall {
|
|||||||
ModeType::empty().bits(),
|
ModeType::empty().bits(),
|
||||||
true,
|
true,
|
||||||
)?;
|
)?;
|
||||||
let path = check_and_clone_cstr(path, Some(MAX_PATHLEN)).unwrap();
|
let path = check_and_clone_cstr(path, Some(MAX_PATHLEN))
|
||||||
|
.unwrap()
|
||||||
|
.into_string()
|
||||||
|
.map_err(|_| SystemError::EINVAL)?;
|
||||||
let pcb = ProcessManager::current_pcb();
|
let pcb = ProcessManager::current_pcb();
|
||||||
let (_inode_begin, remain_path) = user_path_at(&pcb, fd as i32, &path)?;
|
let (_inode_begin, remain_path) = user_path_at(&pcb, fd as i32, &path)?;
|
||||||
let inode = ROOT_INODE().lookup_follow_symlink(&remain_path, MAX_PATHLEN)?;
|
let inode = ROOT_INODE().lookup_follow_symlink(&remain_path, MAX_PATHLEN)?;
|
||||||
@ -1450,7 +1483,9 @@ impl Syscall {
|
|||||||
mode: ModeType,
|
mode: ModeType,
|
||||||
dev_t: DeviceNumber,
|
dev_t: DeviceNumber,
|
||||||
) -> Result<usize, SystemError> {
|
) -> Result<usize, SystemError> {
|
||||||
let path = check_and_clone_cstr(path, Some(MAX_PATHLEN))?;
|
let path = check_and_clone_cstr(path, Some(MAX_PATHLEN))?
|
||||||
|
.into_string()
|
||||||
|
.map_err(|_| SystemError::EINVAL)?;
|
||||||
let path = path.as_str().trim();
|
let path = path.as_str().trim();
|
||||||
|
|
||||||
let inode: Result<Arc<dyn IndexNode>, SystemError> =
|
let inode: Result<Arc<dyn IndexNode>, SystemError> =
|
||||||
@ -1499,7 +1534,9 @@ impl Syscall {
|
|||||||
user_buf: *mut u8,
|
user_buf: *mut u8,
|
||||||
buf_size: usize,
|
buf_size: usize,
|
||||||
) -> Result<usize, SystemError> {
|
) -> Result<usize, SystemError> {
|
||||||
let path = check_and_clone_cstr(path, Some(MAX_PATHLEN))?;
|
let path = check_and_clone_cstr(path, Some(MAX_PATHLEN))?
|
||||||
|
.into_string()
|
||||||
|
.map_err(|_| SystemError::EINVAL)?;
|
||||||
let path = path.as_str().trim();
|
let path = path.as_str().trim();
|
||||||
let mut user_buf = UserBufferWriter::new(user_buf, buf_size, true)?;
|
let mut user_buf = UserBufferWriter::new(user_buf, buf_size, true)?;
|
||||||
|
|
||||||
@ -1601,13 +1638,16 @@ impl Syscall {
|
|||||||
_mountflags: usize,
|
_mountflags: usize,
|
||||||
_data: *const c_void,
|
_data: *const c_void,
|
||||||
) -> Result<usize, SystemError> {
|
) -> Result<usize, SystemError> {
|
||||||
let target = user_access::check_and_clone_cstr(target, Some(MAX_PATHLEN))?;
|
let target = user_access::check_and_clone_cstr(target, Some(MAX_PATHLEN))?
|
||||||
|
.into_string()
|
||||||
|
.map_err(|_| SystemError::EINVAL)?;
|
||||||
|
|
||||||
let filesystemtype = user_access::check_and_clone_cstr(filesystemtype, Some(MAX_PATHLEN))?;
|
let fstype_str = user_access::check_and_clone_cstr(filesystemtype, Some(MAX_PATHLEN))?;
|
||||||
|
let fstype_str = fstype_str.to_str().map_err(|_| SystemError::EINVAL)?;
|
||||||
|
|
||||||
let filesystemtype = producefs!(FSMAKER, filesystemtype)?;
|
let fstype = producefs!(FSMAKER, fstype_str)?;
|
||||||
|
|
||||||
Vcore::do_mount(filesystemtype, target.to_string().as_str())?;
|
Vcore::do_mount(fstype, &target)?;
|
||||||
|
|
||||||
return Ok(0);
|
return Ok(0);
|
||||||
}
|
}
|
||||||
@ -1621,7 +1661,9 @@ impl Syscall {
|
|||||||
///
|
///
|
||||||
/// [umount(2) — Linux manual page](https://www.man7.org/linux/man-pages/man2/umount.2.html)
|
/// [umount(2) — Linux manual page](https://www.man7.org/linux/man-pages/man2/umount.2.html)
|
||||||
pub fn umount2(target: *const u8, flags: i32) -> Result<(), SystemError> {
|
pub fn umount2(target: *const u8, flags: i32) -> Result<(), SystemError> {
|
||||||
let target = user_access::check_and_clone_cstr(target, Some(MAX_PATHLEN))?;
|
let target = user_access::check_and_clone_cstr(target, Some(MAX_PATHLEN))?
|
||||||
|
.into_string()
|
||||||
|
.map_err(|_| SystemError::EINVAL)?;
|
||||||
Vcore::do_umount2(
|
Vcore::do_umount2(
|
||||||
AtFlags::AT_FDCWD.bits(),
|
AtFlags::AT_FDCWD.bits(),
|
||||||
&target,
|
&target,
|
||||||
@ -1639,7 +1681,9 @@ impl Syscall {
|
|||||||
let pathname = if pathname.is_null() {
|
let pathname = if pathname.is_null() {
|
||||||
None
|
None
|
||||||
} else {
|
} else {
|
||||||
let pathname = check_and_clone_cstr(pathname, Some(MAX_PATHLEN))?;
|
let pathname = check_and_clone_cstr(pathname, Some(MAX_PATHLEN))?
|
||||||
|
.into_string()
|
||||||
|
.map_err(|_| SystemError::EINVAL)?;
|
||||||
Some(pathname)
|
Some(pathname)
|
||||||
};
|
};
|
||||||
let flags = UtimensFlags::from_bits(flags).ok_or(SystemError::EINVAL)?;
|
let flags = UtimensFlags::from_bits(flags).ok_or(SystemError::EINVAL)?;
|
||||||
@ -1657,7 +1701,9 @@ impl Syscall {
|
|||||||
pathname: *const u8,
|
pathname: *const u8,
|
||||||
times: *const PosixTimeval,
|
times: *const PosixTimeval,
|
||||||
) -> Result<usize, SystemError> {
|
) -> Result<usize, SystemError> {
|
||||||
let pathname = check_and_clone_cstr(pathname, Some(MAX_PATHLEN))?;
|
let pathname = check_and_clone_cstr(pathname, Some(MAX_PATHLEN))?
|
||||||
|
.into_string()
|
||||||
|
.map_err(|_| SystemError::EINVAL)?;
|
||||||
let times = if times.is_null() {
|
let times = if times.is_null() {
|
||||||
None
|
None
|
||||||
} else {
|
} else {
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
use core::sync::atomic::{compiler_fence, Ordering};
|
use core::sync::atomic::{compiler_fence, Ordering};
|
||||||
|
|
||||||
use alloc::string::{String, ToString};
|
use alloc::{ffi::CString, string::ToString};
|
||||||
use log::{debug, error};
|
use log::{debug, error};
|
||||||
use system_error::SystemError;
|
use system_error::SystemError;
|
||||||
|
|
||||||
@ -86,7 +86,7 @@ fn switch_to_user() -> ! {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn try_to_run_init_process(path: &str, trap_frame: &mut TrapFrame) -> Result<(), SystemError> {
|
fn try_to_run_init_process(path: &str, trap_frame: &mut TrapFrame) -> Result<(), SystemError> {
|
||||||
if let Err(e) = run_init_process(path.to_string(), trap_frame) {
|
if let Err(e) = run_init_process(path, trap_frame) {
|
||||||
if e != SystemError::ENOENT {
|
if e != SystemError::ENOENT {
|
||||||
error!(
|
error!(
|
||||||
"Failed to run init process: {path} exists but couldn't execute it (error {:?})",
|
"Failed to run init process: {path} exists but couldn't execute it (error {:?})",
|
||||||
@ -98,11 +98,11 @@ fn try_to_run_init_process(path: &str, trap_frame: &mut TrapFrame) -> Result<(),
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn run_init_process(path: String, trap_frame: &mut TrapFrame) -> Result<(), SystemError> {
|
fn run_init_process(path: &str, trap_frame: &mut TrapFrame) -> Result<(), SystemError> {
|
||||||
let argv = vec![path.clone()];
|
let argv = vec![CString::new(path).unwrap()];
|
||||||
let envp = vec![String::from("PATH=/")];
|
let envp = vec![CString::new("PATH=/").unwrap()];
|
||||||
|
|
||||||
compiler_fence(Ordering::SeqCst);
|
compiler_fence(Ordering::SeqCst);
|
||||||
Syscall::do_execve(path, argv, envp, trap_frame)?;
|
Syscall::do_execve(path.to_string(), argv, envp, trap_frame)?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
use core::{fmt::Debug, ptr::null};
|
use core::{fmt::Debug, ptr::null};
|
||||||
|
|
||||||
use alloc::{collections::BTreeMap, string::String, sync::Arc, vec::Vec};
|
use alloc::{collections::BTreeMap, ffi::CString, string::String, sync::Arc, vec::Vec};
|
||||||
use system_error::SystemError;
|
use system_error::SystemError;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
@ -16,6 +16,8 @@ use crate::{
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
use super::ProcessManager;
|
||||||
|
|
||||||
/// 系统支持的所有二进制文件加载器的列表
|
/// 系统支持的所有二进制文件加载器的列表
|
||||||
const BINARY_LOADERS: [&'static dyn BinaryLoader; 1] = [&ELF_LOADER];
|
const BINARY_LOADERS: [&'static dyn BinaryLoader; 1] = [&ELF_LOADER];
|
||||||
|
|
||||||
@ -125,7 +127,7 @@ impl ExecParam {
|
|||||||
file,
|
file,
|
||||||
vm,
|
vm,
|
||||||
flags,
|
flags,
|
||||||
init_info: ProcInitInfo::new(),
|
init_info: ProcInitInfo::new(ProcessManager::current_pcb().basic().name()),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -195,16 +197,16 @@ pub fn load_binary_file(param: &mut ExecParam) -> Result<BinaryLoaderResult, Sys
|
|||||||
/// 程序初始化信息,这些信息会被压入用户栈中
|
/// 程序初始化信息,这些信息会被压入用户栈中
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct ProcInitInfo {
|
pub struct ProcInitInfo {
|
||||||
pub proc_name: String,
|
pub proc_name: CString,
|
||||||
pub args: Vec<String>,
|
pub args: Vec<CString>,
|
||||||
pub envs: Vec<String>,
|
pub envs: Vec<CString>,
|
||||||
pub auxv: BTreeMap<u8, usize>,
|
pub auxv: BTreeMap<u8, usize>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ProcInitInfo {
|
impl ProcInitInfo {
|
||||||
pub fn new() -> Self {
|
pub fn new(proc_name: &str) -> Self {
|
||||||
Self {
|
Self {
|
||||||
proc_name: String::new(),
|
proc_name: CString::new(proc_name).unwrap_or(CString::new("").unwrap()),
|
||||||
args: Vec::new(),
|
args: Vec::new(),
|
||||||
envs: Vec::new(),
|
envs: Vec::new(),
|
||||||
auxv: BTreeMap::new(),
|
auxv: BTreeMap::new(),
|
||||||
@ -229,17 +231,16 @@ impl ProcInitInfo {
|
|||||||
.envs
|
.envs
|
||||||
.iter()
|
.iter()
|
||||||
.map(|s| {
|
.map(|s| {
|
||||||
self.push_str(ustack, s.as_str()).expect("push_str failed");
|
self.push_str(ustack, s).expect("push_str failed");
|
||||||
ustack.sp()
|
ustack.sp()
|
||||||
})
|
})
|
||||||
.collect::<Vec<_>>();
|
.collect::<Vec<_>>();
|
||||||
|
|
||||||
// 然后把参数压入栈中
|
// 然后把参数压入栈中
|
||||||
let argps = self
|
let argps = self
|
||||||
.args
|
.args
|
||||||
.iter()
|
.iter()
|
||||||
.map(|s| {
|
.map(|s| {
|
||||||
self.push_str(ustack, s.as_str()).expect("push_str failed");
|
self.push_str(ustack, s).expect("push_str failed");
|
||||||
ustack.sp()
|
ustack.sp()
|
||||||
})
|
})
|
||||||
.collect::<Vec<_>>();
|
.collect::<Vec<_>>();
|
||||||
@ -280,9 +281,9 @@ impl ProcInitInfo {
|
|||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
|
|
||||||
fn push_str(&self, ustack: &mut UserStack, s: &str) -> Result<(), SystemError> {
|
fn push_str(&self, ustack: &mut UserStack, s: &CString) -> Result<(), SystemError> {
|
||||||
self.push_slice(ustack, &[b"\0"])?;
|
let bytes = s.as_bytes_with_nul();
|
||||||
self.push_slice(ustack, s.as_bytes())?;
|
self.push_slice(ustack, bytes)?;
|
||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -8,6 +8,7 @@ use core::{
|
|||||||
};
|
};
|
||||||
|
|
||||||
use alloc::{
|
use alloc::{
|
||||||
|
ffi::CString,
|
||||||
string::{String, ToString},
|
string::{String, ToString},
|
||||||
sync::{Arc, Weak},
|
sync::{Arc, Weak},
|
||||||
vec::Vec,
|
vec::Vec,
|
||||||
@ -922,11 +923,11 @@ impl ProcessControlBlock {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// 生成进程的名字
|
/// 生成进程的名字
|
||||||
pub fn generate_name(program_path: &str, args: &Vec<String>) -> String {
|
pub fn generate_name(program_path: &str, args: &Vec<CString>) -> String {
|
||||||
let mut name = program_path.to_string();
|
let mut name = program_path.to_string();
|
||||||
for arg in args {
|
for arg in args {
|
||||||
name.push(' ');
|
name.push(' ');
|
||||||
name.push_str(arg);
|
name.push_str(arg.to_string_lossy().as_ref());
|
||||||
}
|
}
|
||||||
return name;
|
return name;
|
||||||
}
|
}
|
||||||
|
@ -1,10 +1,7 @@
|
|||||||
use core::ffi::c_void;
|
use core::ffi::c_void;
|
||||||
|
|
||||||
use alloc::{
|
use alloc::{ffi::CString, string::ToString, sync::Arc, vec::Vec};
|
||||||
string::{String, ToString},
|
use log::error;
|
||||||
sync::Arc,
|
|
||||||
vec::Vec,
|
|
||||||
};
|
|
||||||
use system_error::SystemError;
|
use system_error::SystemError;
|
||||||
|
|
||||||
use super::{
|
use super::{
|
||||||
@ -114,16 +111,16 @@ impl Syscall {
|
|||||||
}
|
}
|
||||||
|
|
||||||
let x = || {
|
let x = || {
|
||||||
let path: String = check_and_clone_cstr(path, Some(MAX_PATHLEN))?;
|
let path: CString = check_and_clone_cstr(path, Some(MAX_PATHLEN))?;
|
||||||
let argv: Vec<String> = check_and_clone_cstr_array(argv)?;
|
let argv: Vec<CString> = check_and_clone_cstr_array(argv)?;
|
||||||
let envp: Vec<String> = check_and_clone_cstr_array(envp)?;
|
let envp: Vec<CString> = check_and_clone_cstr_array(envp)?;
|
||||||
Ok((path, argv, envp))
|
Ok((path, argv, envp))
|
||||||
};
|
};
|
||||||
let r: Result<(String, Vec<String>, Vec<String>), SystemError> = x();
|
let (path, argv, envp) = x().inspect_err(|e: &SystemError| {
|
||||||
if let Err(e) = r {
|
error!("Failed to execve: {:?}", e);
|
||||||
panic!("Failed to execve: {:?}", e);
|
})?;
|
||||||
}
|
|
||||||
let (path, argv, envp) = r.unwrap();
|
let path = path.into_string().map_err(|_| SystemError::EINVAL)?;
|
||||||
ProcessManager::current_pcb()
|
ProcessManager::current_pcb()
|
||||||
.basic_mut()
|
.basic_mut()
|
||||||
.set_name(ProcessControlBlock::generate_name(&path, &argv));
|
.set_name(ProcessControlBlock::generate_name(&path, &argv));
|
||||||
|
@ -1150,7 +1150,9 @@ impl Syscall {
|
|||||||
back_color: u32,
|
back_color: u32,
|
||||||
) -> Result<usize, SystemError> {
|
) -> Result<usize, SystemError> {
|
||||||
// todo: 删除这个系统调用
|
// todo: 删除这个系统调用
|
||||||
let s = check_and_clone_cstr(s, Some(4096))?;
|
let s = check_and_clone_cstr(s, Some(4096))?
|
||||||
|
.into_string()
|
||||||
|
.map_err(|_| SystemError::EINVAL)?;
|
||||||
let fr = (front_color & 0x00ff0000) >> 16;
|
let fr = (front_color & 0x00ff0000) >> 16;
|
||||||
let fg = (front_color & 0x0000ff00) >> 8;
|
let fg = (front_color & 0x0000ff00) >> 8;
|
||||||
let fb = front_color & 0x000000ff;
|
let fb = front_color & 0x000000ff;
|
||||||
|
@ -2,10 +2,11 @@
|
|||||||
|
|
||||||
use core::{
|
use core::{
|
||||||
mem::size_of,
|
mem::size_of,
|
||||||
|
num::NonZero,
|
||||||
slice::{from_raw_parts, from_raw_parts_mut},
|
slice::{from_raw_parts, from_raw_parts_mut},
|
||||||
};
|
};
|
||||||
|
|
||||||
use alloc::{string::String, vec::Vec};
|
use alloc::{ffi::CString, vec::Vec};
|
||||||
|
|
||||||
use crate::mm::{verify_area, VirtAddr};
|
use crate::mm::{verify_area, VirtAddr};
|
||||||
|
|
||||||
@ -70,10 +71,11 @@ pub unsafe fn copy_from_user(dst: &mut [u8], src: VirtAddr) -> Result<usize, Sys
|
|||||||
/// ## 错误
|
/// ## 错误
|
||||||
///
|
///
|
||||||
/// - `EFAULT`:用户态地址不合法
|
/// - `EFAULT`:用户态地址不合法
|
||||||
|
/// - `EINVAL`:字符串不是合法的 C 字符串
|
||||||
pub fn check_and_clone_cstr(
|
pub fn check_and_clone_cstr(
|
||||||
user: *const u8,
|
user: *const u8,
|
||||||
max_length: Option<usize>,
|
max_length: Option<usize>,
|
||||||
) -> Result<String, SystemError> {
|
) -> Result<CString, SystemError> {
|
||||||
if user.is_null() {
|
if user.is_null() {
|
||||||
return Err(SystemError::EFAULT);
|
return Err(SystemError::EFAULT);
|
||||||
}
|
}
|
||||||
@ -93,9 +95,12 @@ pub fn check_and_clone_cstr(
|
|||||||
if c[0] == 0 {
|
if c[0] == 0 {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
buffer.push(c[0]);
|
buffer.push(NonZero::new(c[0]).ok_or(SystemError::EINVAL)?);
|
||||||
}
|
}
|
||||||
String::from_utf8(buffer).map_err(|_| SystemError::EFAULT)
|
|
||||||
|
let cstr = CString::from(buffer);
|
||||||
|
|
||||||
|
return Ok(cstr);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// 检查并从用户态拷贝一个 C 字符串数组
|
/// 检查并从用户态拷贝一个 C 字符串数组
|
||||||
@ -112,7 +117,7 @@ pub fn check_and_clone_cstr(
|
|||||||
/// ## 错误
|
/// ## 错误
|
||||||
///
|
///
|
||||||
/// - `EFAULT`:用户态地址不合法
|
/// - `EFAULT`:用户态地址不合法
|
||||||
pub fn check_and_clone_cstr_array(user: *const *const u8) -> Result<Vec<String>, SystemError> {
|
pub fn check_and_clone_cstr_array(user: *const *const u8) -> Result<Vec<CString>, SystemError> {
|
||||||
if user.is_null() {
|
if user.is_null() {
|
||||||
Ok(Vec::new())
|
Ok(Vec::new())
|
||||||
} else {
|
} else {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user