From fe0045c0c9ed576d31fa0359775b6fecd534f4aa Mon Sep 17 00:00:00 2001
From: WangRunji <wangrunji0408@163.com>
Date: Fri, 12 Apr 2019 19:23:45 +0800
Subject: [PATCH 1/2] remove legacy 'is32' code

---
 kernel/src/arch/aarch64/consts.rs             |  1 -
 kernel/src/arch/aarch64/interrupt/context.rs  |  1 -
 kernel/src/arch/mipsel/consts.rs              |  1 -
 kernel/src/arch/mipsel/context.rs             |  1 -
 kernel/src/arch/riscv32/consts.rs             |  1 -
 kernel/src/arch/riscv32/context.rs            |  1 -
 kernel/src/arch/x86_64/consts.rs              |  1 -
 kernel/src/arch/x86_64/interrupt/trapframe.rs | 14 +++-----------
 kernel/src/process/structs.rs                 | 14 ++++----------
 9 files changed, 7 insertions(+), 28 deletions(-)

diff --git a/kernel/src/arch/aarch64/consts.rs b/kernel/src/arch/aarch64/consts.rs
index ea71e7a..3a7c500 100644
--- a/kernel/src/arch/aarch64/consts.rs
+++ b/kernel/src/arch/aarch64/consts.rs
@@ -5,4 +5,3 @@ pub const KERNEL_HEAP_SIZE: usize = 8 * 1024 * 1024;
 pub const MEMORY_OFFSET: usize = 0;
 pub const USER_STACK_OFFSET: usize = 0x0000_8000_0000_0000 - USER_STACK_SIZE;
 pub const USER_STACK_SIZE: usize = 1 * 1024 * 1024;
-pub const USER32_STACK_OFFSET: usize = USER_STACK_OFFSET;
diff --git a/kernel/src/arch/aarch64/interrupt/context.rs b/kernel/src/arch/aarch64/interrupt/context.rs
index 6639ab8..87f3a4e 100644
--- a/kernel/src/arch/aarch64/interrupt/context.rs
+++ b/kernel/src/arch/aarch64/interrupt/context.rs
@@ -163,7 +163,6 @@ impl Context {
         entry_addr: usize,
         ustack_top: usize,
         kstack_top: usize,
-        _is32: bool,
         ttbr: usize,
     ) -> Self {
         InitStack {
diff --git a/kernel/src/arch/mipsel/consts.rs b/kernel/src/arch/mipsel/consts.rs
index ff2ef0c..48b1b82 100644
--- a/kernel/src/arch/mipsel/consts.rs
+++ b/kernel/src/arch/mipsel/consts.rs
@@ -8,6 +8,5 @@ pub const MEMORY_OFFSET: usize = 0x8000_0000;
 
 pub const USER_STACK_OFFSET: usize = 0x80000000 - USER_STACK_SIZE;
 pub const USER_STACK_SIZE: usize = 0x10000;
-pub const USER32_STACK_OFFSET: usize = 0x80000000 - USER_STACK_SIZE;
 
 pub const MAX_DTB_SIZE: usize = 0x2000;
diff --git a/kernel/src/arch/mipsel/context.rs b/kernel/src/arch/mipsel/context.rs
index 85bc56b..69f9016 100644
--- a/kernel/src/arch/mipsel/context.rs
+++ b/kernel/src/arch/mipsel/context.rs
@@ -206,7 +206,6 @@ impl Context {
         entry_addr: usize,
         ustack_top: usize,
         kstack_top: usize,
-        _is32: bool,
         satp: usize,
     ) -> Self {
         info!(
diff --git a/kernel/src/arch/riscv32/consts.rs b/kernel/src/arch/riscv32/consts.rs
index a3004b0..45fa998 100644
--- a/kernel/src/arch/riscv32/consts.rs
+++ b/kernel/src/arch/riscv32/consts.rs
@@ -37,6 +37,5 @@ pub const MEMORY_END: usize = 0x8100_0000;
 // FIXME: rv64 `sh` and `ls` will crash if stack top > 0x80000000 ???
 pub const USER_STACK_OFFSET: usize = 0x80000000 - USER_STACK_SIZE;
 pub const USER_STACK_SIZE: usize = 0x10000;
-pub const USER32_STACK_OFFSET: usize = 0xC0000000 - USER_STACK_SIZE;
 
 pub const MAX_DTB_SIZE: usize = 0x2000;
diff --git a/kernel/src/arch/riscv32/context.rs b/kernel/src/arch/riscv32/context.rs
index e05dafe..51df0c1 100644
--- a/kernel/src/arch/riscv32/context.rs
+++ b/kernel/src/arch/riscv32/context.rs
@@ -236,7 +236,6 @@ impl Context {
         entry_addr: usize,
         ustack_top: usize,
         kstack_top: usize,
-        _is32: bool,
         satp: usize,
     ) -> Self {
         InitStack {
diff --git a/kernel/src/arch/x86_64/consts.rs b/kernel/src/arch/x86_64/consts.rs
index 7543779..2095e39 100644
--- a/kernel/src/arch/x86_64/consts.rs
+++ b/kernel/src/arch/x86_64/consts.rs
@@ -53,7 +53,6 @@ pub const USER_GRANT_PML4: usize = (USER_GRANT_OFFSET & PML4_MASK) / PML4_SIZE;
 
 /// Offset to user stack
 pub const USER_STACK_OFFSET: usize = USER_GRANT_OFFSET + PML4_SIZE;
-pub const USER32_STACK_OFFSET: usize = 0xB000_0000;
 pub const USER_STACK_PML4: usize = (USER_STACK_OFFSET & PML4_MASK) / PML4_SIZE;
 /// Size of user stack
 pub const USER_STACK_SIZE: usize = 1024 * 1024; // 1 MB
diff --git a/kernel/src/arch/x86_64/interrupt/trapframe.rs b/kernel/src/arch/x86_64/interrupt/trapframe.rs
index 03f4c32..d9ab7f7 100644
--- a/kernel/src/arch/x86_64/interrupt/trapframe.rs
+++ b/kernel/src/arch/x86_64/interrupt/trapframe.rs
@@ -73,14 +73,10 @@ impl TrapFrame {
         tf.fpstate_offset = 16; // skip restoring for first time
         tf
     }
-    fn new_user_thread(entry_addr: usize, rsp: usize, is32: bool) -> Self {
+    fn new_user_thread(entry_addr: usize, rsp: usize) -> Self {
         use crate::arch::gdt;
         let mut tf = TrapFrame::default();
-        tf.cs = if is32 {
-            gdt::UCODE32_SELECTOR.0
-        } else {
-            gdt::UCODE_SELECTOR.0
-        } as usize;
+        tf.cs = gdt::UCODE_SELECTOR.0 as usize;
         tf.rip = entry_addr;
         tf.ss = gdt::UDATA32_SELECTOR.0 as usize;
         tf.rsp = rsp;
@@ -88,9 +84,6 @@ impl TrapFrame {
         tf.fpstate_offset = 16; // skip restoring for first time
         tf
     }
-    pub fn is_user(&self) -> bool {
-        self.cs & 0x3 == 0x3
-    }
 }
 
 #[derive(Debug, Default)]
@@ -203,12 +196,11 @@ impl Context {
         entry_addr: usize,
         ustack_top: usize,
         kstack_top: usize,
-        is32: bool,
         cr3: usize,
     ) -> Self {
         InitStack {
             context: ContextData::new(cr3),
-            tf: TrapFrame::new_user_thread(entry_addr, ustack_top, is32),
+            tf: TrapFrame::new_user_thread(entry_addr, ustack_top),
         }
         .push_at(kstack_top)
     }
diff --git a/kernel/src/process/structs.rs b/kernel/src/process/structs.rs
index 057af1c..084469f 100644
--- a/kernel/src/process/structs.rs
+++ b/kernel/src/process/structs.rs
@@ -175,10 +175,6 @@ impl Thread {
     {
         // Parse ELF
         let elf = ElfFile::new(data).expect("failed to read elf");
-        let is32 = match elf.header.pt2 {
-            header::HeaderPt2::Header32(_) => true,
-            header::HeaderPt2::Header64(_) => false,
-        };
 
         // Check ELF type
         match elf.header.pt2.type_().as_type() {
@@ -210,12 +206,10 @@ impl Thread {
         let mut vm = elf.make_memory_set();
 
         // User stack
-        use crate::consts::{USER32_STACK_OFFSET, USER_STACK_OFFSET, USER_STACK_SIZE};
+        use crate::consts::{USER_STACK_OFFSET, USER_STACK_SIZE};
         let mut ustack_top = {
-            let (ustack_buttom, ustack_top) = match is32 {
-                true => (USER32_STACK_OFFSET, USER32_STACK_OFFSET + USER_STACK_SIZE),
-                false => (USER_STACK_OFFSET, USER_STACK_OFFSET + USER_STACK_SIZE),
-            };
+            let ustack_buttom = USER_STACK_OFFSET;
+            let ustack_top = USER_STACK_OFFSET + USER_STACK_SIZE;
             vm.push(
                 ustack_buttom,
                 ustack_top,
@@ -288,7 +282,7 @@ impl Thread {
 
         Box::new(Thread {
             context: unsafe {
-                Context::new_user_thread(entry_addr, ustack_top, kstack.top(), is32, vm.token())
+                Context::new_user_thread(entry_addr, ustack_top, kstack.top(), vm.token())
             },
             kstack,
             clear_child_tid: 0,

From 3556c758db105bf22ed7fc87beb3e6f0106c8fec Mon Sep 17 00:00:00 2001
From: WangRunji <wangrunji0408@163.com>
Date: Sun, 14 Apr 2019 15:47:42 +0800
Subject: [PATCH 2/2] impl more file system *at syscalls

---
 kernel/src/process/structs.rs |  15 +--
 kernel/src/syscall/fs.rs      | 197 +++++++++++++++++++++-------------
 kernel/src/syscall/mod.rs     |  15 +--
 3 files changed, 135 insertions(+), 92 deletions(-)

diff --git a/kernel/src/process/structs.rs b/kernel/src/process/structs.rs
index 084469f..700d4c2 100644
--- a/kernel/src/process/structs.rs
+++ b/kernel/src/process/structs.rs
@@ -123,24 +123,13 @@ impl rcore_thread::Context for Thread {
 
 impl Thread {
     /// Make a struct for the init thread
-    /// TODO: remove this, we only need `Context::null()`
     pub unsafe fn new_init() -> Box<Thread> {
         Box::new(Thread {
             context: Context::null(),
             kstack: KernelStack::new(),
             clear_child_tid: 0,
-            proc: Arc::new(Mutex::new(Process {
-                vm: MemorySet::new(),
-                files: BTreeMap::default(),
-                cwd: String::from("/"),
-                futexes: BTreeMap::default(),
-                pid: Pid::uninitialized(),
-                parent: None,
-                children: Vec::new(),
-                threads: Vec::new(),
-                child_exit: Arc::new(Condvar::new()),
-                child_exit_code: BTreeMap::new(),
-            })),
+            // safety: this field will never be used
+            proc: core::mem::uninitialized(),
         })
     }
 
diff --git a/kernel/src/syscall/fs.rs b/kernel/src/syscall/fs.rs
index f59c203..274154c 100644
--- a/kernel/src/syscall/fs.rs
+++ b/kernel/src/syscall/fs.rs
@@ -237,49 +237,24 @@ pub fn sys_openat(dir_fd: usize, path: *const u8, flags: usize, mode: usize) ->
         dir_fd as isize, path, flags, mode
     );
 
-    let inode = if dir_fd == AT_FDCWD {
-        // from process cwd
-        if flags.contains(OpenFlags::CREATE) {
-            let (dir_path, file_name) = split_path(&path);
-            // relative to cwd
-            let dir_inode = proc.lookup_inode(dir_path)?;
-            match dir_inode.find(file_name) {
-                Ok(file_inode) => {
-                    if flags.contains(OpenFlags::EXCLUSIVE) {
-                        return Err(SysError::EEXIST);
-                    }
-                    file_inode
+    let inode = if flags.contains(OpenFlags::CREATE) {
+        let (dir_path, file_name) = split_path(&path);
+        // relative to cwd
+        let dir_inode = proc.lookup_inode_at(dir_fd, dir_path)?;
+        match dir_inode.find(file_name) {
+            Ok(file_inode) => {
+                if flags.contains(OpenFlags::EXCLUSIVE) {
+                    return Err(SysError::EEXIST);
                 }
-                Err(FsError::EntryNotFound) => {
-                    dir_inode.create(file_name, FileType::File, mode as u32)?
-                }
-                Err(e) => return Err(SysError::from(e)),
+                file_inode
             }
-        } else {
-            proc.lookup_inode(&path)?
-        }
-    } else {
-        // relative to dir_fd
-        let dir_file = proc.get_file(dir_fd)?;
-        if flags.contains(OpenFlags::CREATE) {
-            let (dir_path, file_name) = split_path(&path);
-            // relative to cwd
-            let dir_inode = dir_file.lookup_follow(dir_path, FOLLOW_MAX_DEPTH)?;
-            match dir_inode.find(file_name) {
-                Ok(file_inode) => {
-                    if flags.contains(OpenFlags::EXCLUSIVE) {
-                        return Err(SysError::EEXIST);
-                    }
-                    file_inode
-                }
-                Err(FsError::EntryNotFound) => {
-                    dir_inode.create(file_name, FileType::File, mode as u32)?
-                }
-                Err(e) => return Err(SysError::from(e)),
+            Err(FsError::EntryNotFound) => {
+                dir_inode.create(file_name, FileType::File, mode as u32)?
             }
-        } else {
-            dir_file.lookup_follow(&path, FOLLOW_MAX_DEPTH)?
+            Err(e) => return Err(SysError::from(e)),
         }
+    } else {
+        proc.lookup_inode_at(dir_fd, &path)?
     };
 
     let fd = proc.get_free_fd();
@@ -297,14 +272,22 @@ pub fn sys_close(fd: usize) -> SysResult {
 }
 
 pub fn sys_access(path: *const u8, mode: usize) -> SysResult {
+    sys_faccessat(AT_FDCWD, path, mode, 0)
+}
+
+pub fn sys_faccessat(dirfd: usize, path: *const u8, mode: usize, flags: usize) -> SysResult {
     // TODO: check permissions based on uid/gid
     let proc = process();
     let path = unsafe { proc.vm.check_and_clone_cstr(path)? };
+    let flags = AtFlags::from_bits_truncate(flags);
     if !proc.pid.is_init() {
         // we trust pid 0 process
-        info!("access: path: {:?}, mode: {:#o}", path, mode);
+        info!(
+            "faccessat: dirfd: {}, path: {:?}, mode: {:#o}, flags: {:?}",
+            dirfd, path, mode, flags
+        );
     }
-    let inode = proc.lookup_inode(&path)?;
+    let inode = proc.lookup_inode_at(dirfd, &path)?;
     Ok(0)
 }
 
@@ -322,9 +305,9 @@ pub fn sys_getcwd(buf: *mut u8, len: usize) -> SysResult {
     Ok(buf as usize)
 }
 
-pub fn sys_stat(path: *const u8, stat_ptr: *mut Stat) -> SysResult {
-    warn!("stat is partial implemented as lstat");
-    sys_lstat(path, stat_ptr)
+pub fn sys_lstat(path: *const u8, stat_ptr: *mut Stat) -> SysResult {
+    warn!("lstat is partial implemented as stat");
+    sys_stat(path, stat_ptr)
 }
 
 pub fn sys_fstat(fd: usize, stat_ptr: *mut Stat) -> SysResult {
@@ -333,20 +316,23 @@ pub fn sys_fstat(fd: usize, stat_ptr: *mut Stat) -> SysResult {
     proc.vm.check_write_ptr(stat_ptr)?;
     let file = proc.get_file(fd)?;
     let stat = Stat::from(file.metadata()?);
-    // TODO: handle symlink
     unsafe {
         stat_ptr.write(stat);
     }
     Ok(0)
 }
 
-pub fn sys_lstat(path: *const u8, stat_ptr: *mut Stat) -> SysResult {
+pub fn sys_fstatat(dirfd: usize, path: *const u8, stat_ptr: *mut Stat, flags: usize) -> SysResult {
     let proc = process();
     let path = unsafe { proc.vm.check_and_clone_cstr(path)? };
     proc.vm.check_write_ptr(stat_ptr)?;
-    info!("lstat: path: {:?}, stat_ptr: {:?}", path, stat_ptr);
+    let flags = AtFlags::from_bits_truncate(flags);
+    info!(
+        "fstatat: dirfd: {}, path: {:?}, stat_ptr: {:?}, flags: {:?}",
+        dirfd, path, stat_ptr, flags
+    );
 
-    let inode = proc.lookup_inode(&path)?;
+    let inode = proc.lookup_inode_at(dirfd, &path)?;
     let stat = Stat::from(inode.metadata()?);
     unsafe {
         stat_ptr.write(stat);
@@ -354,13 +340,21 @@ pub fn sys_lstat(path: *const u8, stat_ptr: *mut Stat) -> SysResult {
     Ok(0)
 }
 
+pub fn sys_stat(path: *const u8, stat_ptr: *mut Stat) -> SysResult {
+    sys_fstatat(AT_FDCWD, path, stat_ptr, 0)
+}
+
 pub fn sys_readlink(path: *const u8, base: *mut u8, len: usize) -> SysResult {
+    sys_readlinkat(AT_FDCWD, path, base, len)
+}
+
+pub fn sys_readlinkat(dirfd: usize, path: *const u8, base: *mut u8, len: usize) -> SysResult {
     let proc = process();
     let path = unsafe { proc.vm.check_and_clone_cstr(path)? };
     proc.vm.check_write_array(base, len)?;
     info!("readlink: path: {:?}, base: {:?}, len: {}", path, base, len);
 
-    let inode = proc.lookup_inode(&path)?;
+    let inode = proc.lookup_inode_at(dirfd, &path)?;
     if inode.metadata()?.type_ == FileType::SymLink {
         // TODO: recursive link resolution and loop detection
         let mut slice = unsafe { slice::from_raw_parts_mut(base, len) };
@@ -504,30 +498,27 @@ pub fn sys_renameat(
 
     let (old_dir_path, old_file_name) = split_path(&oldpath);
     let (new_dir_path, new_file_name) = split_path(&newpath);
-    let old_dir_inode = if olddirfd == AT_FDCWD {
-        proc.lookup_inode(old_dir_path)?
-    } else {
-        proc.get_file(olddirfd)?
-            .lookup_follow(old_dir_path, FOLLOW_MAX_DEPTH)?
-    };
-    let new_dir_inode = if newdirfd == AT_FDCWD {
-        proc.lookup_inode(new_dir_path)?
-    } else {
-        proc.get_file(newdirfd)?
-            .lookup_follow(new_dir_path, FOLLOW_MAX_DEPTH)?
-    };
+    let old_dir_inode = proc.lookup_inode_at(olddirfd, old_dir_path)?;
+    let new_dir_inode = proc.lookup_inode_at(newdirfd, new_dir_path)?;
     old_dir_inode.move_(old_file_name, &new_dir_inode, new_file_name)?;
     Ok(0)
 }
 
 pub fn sys_mkdir(path: *const u8, mode: usize) -> SysResult {
+    sys_mkdirat(AT_FDCWD, path, mode)
+}
+
+pub fn sys_mkdirat(dirfd: usize, path: *const u8, mode: usize) -> SysResult {
     let proc = process();
     let path = unsafe { proc.vm.check_and_clone_cstr(path)? };
     // TODO: check pathname
-    info!("mkdir: path: {:?}, mode: {:#o}", path, mode);
+    info!(
+        "mkdirat: dirfd: {}, path: {:?}, mode: {:#o}",
+        dirfd, path, mode
+    );
 
     let (dir_path, file_name) = split_path(&path);
-    let inode = proc.lookup_inode(dir_path)?;
+    let inode = proc.lookup_inode_at(dirfd, dir_path)?;
     if inode.find(file_name).is_ok() {
         return Err(SysError::EEXIST);
     }
@@ -551,25 +542,47 @@ pub fn sys_rmdir(path: *const u8) -> SysResult {
 }
 
 pub fn sys_link(oldpath: *const u8, newpath: *const u8) -> SysResult {
+    sys_linkat(AT_FDCWD, oldpath, AT_FDCWD, newpath, 0)
+}
+
+pub fn sys_linkat(
+    olddirfd: usize,
+    oldpath: *const u8,
+    newdirfd: usize,
+    newpath: *const u8,
+    flags: usize,
+) -> SysResult {
     let proc = process();
     let oldpath = unsafe { proc.vm.check_and_clone_cstr(oldpath)? };
     let newpath = unsafe { proc.vm.check_and_clone_cstr(newpath)? };
-    info!("link: oldpath: {:?}, newpath: {:?}", oldpath, newpath);
+    let flags = AtFlags::from_bits_truncate(flags);
+    info!(
+        "linkat: olddirfd: {}, oldpath: {:?}, newdirfd: {}, newpath: {:?}, flags: {:?}",
+        olddirfd, oldpath, newdirfd, newpath, flags
+    );
 
     let (new_dir_path, new_file_name) = split_path(&newpath);
-    let inode = proc.lookup_inode(&oldpath)?;
-    let new_dir_inode = proc.lookup_inode(new_dir_path)?;
+    let inode = proc.lookup_inode_at(olddirfd, &oldpath)?;
+    let new_dir_inode = proc.lookup_inode_at(newdirfd, new_dir_path)?;
     new_dir_inode.link(new_file_name, &inode)?;
     Ok(0)
 }
 
 pub fn sys_unlink(path: *const u8) -> SysResult {
+    sys_unlinkat(AT_FDCWD, path, 0)
+}
+
+pub fn sys_unlinkat(dirfd: usize, path: *const u8, flags: usize) -> SysResult {
     let proc = process();
     let path = unsafe { proc.vm.check_and_clone_cstr(path)? };
-    info!("unlink: path: {:?}", path);
+    let flags = AtFlags::from_bits_truncate(flags);
+    info!(
+        "unlinkat: dirfd: {}, path: {:?}, flags: {:?}",
+        dirfd, path, flags
+    );
 
     let (dir_path, file_name) = split_path(&path);
-    let dir_inode = proc.lookup_inode(dir_path)?;
+    let dir_inode = proc.lookup_inode_at(dirfd, dir_path)?;
     let file_inode = dir_inode.find(file_name)?;
     if file_inode.metadata()?.type_ == FileType::Dir {
         return Err(SysError::EISDIR);
@@ -701,11 +714,44 @@ impl Process {
             _ => Err(SysError::EBADF),
         }
     }
+    /// Lookup INode from the process.
+    ///
+    /// - If `path` is relative, then it is interpreted relative to the directory
+    ///   referred to by the file descriptor `dirfd`.
+    ///
+    /// - If the `dirfd` is the special value `AT_FDCWD`, then the directory is
+    ///   current working directory of the process.
+    ///
+    /// - If `path` is absolute, then `dirfd` is ignored.
+    ///
+    /// - If `follow` is true, then dereference `path` if it is a symbolic link.
+    pub fn lookup_inode_at(
+        &self,
+        dirfd: usize,
+        path: &str,
+        //        follow: bool,
+    ) -> Result<Arc<INode>, SysError> {
+        let follow = true;
+        debug!(
+            "lookup_inode_at: fd: {:?}, cwd: {:?}, path: {:?}, follow: {:?}",
+            dirfd, self.cwd, path, follow
+        );
+        let follow_max_depth = if follow { FOLLOW_MAX_DEPTH } else { 0 };
+        if dirfd == AT_FDCWD {
+            Ok(ROOT_INODE
+                .lookup(&self.cwd)?
+                .lookup_follow(path, follow_max_depth)?)
+        } else {
+            let file = match self.files.get(&dirfd).ok_or(SysError::EBADF)? {
+                FileLike::File(file) => file,
+                _ => return Err(SysError::EBADF),
+            };
+            Ok(file.lookup_follow(path, follow_max_depth)?)
+        }
+    }
+
     pub fn lookup_inode(&self, path: &str) -> Result<Arc<INode>, SysError> {
-        debug!("lookup_inode: cwd {} path {}", self.cwd, path);
-        Ok(ROOT_INODE
-            .lookup(&self.cwd)?
-            .lookup_follow(path, FOLLOW_MAX_DEPTH)?)
+        self.lookup_inode_at(AT_FDCWD, path)
     }
 }
 
@@ -740,6 +786,13 @@ impl From<FsError> for SysError {
     }
 }
 
+bitflags! {
+    struct AtFlags: usize {
+        const EMPTY_PATH = 0x1000;
+        const SYMLINK_NOFOLLOW = 0x100;
+    }
+}
+
 bitflags! {
     struct OpenFlags: usize {
         /// read only
diff --git a/kernel/src/syscall/mod.rs b/kernel/src/syscall/mod.rs
index d74e125..ef12052 100644
--- a/kernel/src/syscall/mod.rs
+++ b/kernel/src/syscall/mod.rs
@@ -244,20 +244,21 @@ pub fn syscall(id: usize, args: [usize; 6], tf: &mut TrapFrame) -> isize {
         }
         SYS_CLOCK_GETTIME => sys_clock_gettime(args[0], args[1] as *mut TimeSpec),
         SYS_EXIT_GROUP => sys_exit_group(args[0]),
-        SYS_OPENAT => sys_openat(args[0], args[1] as *const u8, args[2], args[3]), // TODO: handle `dfd`
-        SYS_MKDIRAT => sys_mkdir(args[1] as *const u8, args[2]), // TODO: handle `dfd`
+        SYS_OPENAT => sys_openat(args[0], args[1] as *const u8, args[2], args[3]),
+        SYS_MKDIRAT => sys_mkdirat(args[0], args[1] as *const u8, args[2]),
         //        SYS_MKNODAT => sys_mknod(),
         // 260
         SYS_FCHOWNAT => {
             warn!("sys_fchownat is unimplemented");
             Ok(0)
         }
-        SYS_NEWFSTATAT => sys_stat(args[1] as *const u8, args[2] as *mut Stat), // TODO: handle `dfd`, `flag`
-        SYS_UNLINKAT => sys_unlink(args[1] as *const u8), // TODO: handle `dfd`, `flag`
-        SYS_RENAMEAT => sys_renameat(args[0], args[1] as *const u8, args[2], args[3] as *const u8), // TODO: handle `olddfd`, `newdfd`
-        SYS_LINKAT => sys_link(args[1] as *const u8, args[3] as *const u8), // TODO: handle `olddfd`, `newdfd`, `flags`
+        SYS_NEWFSTATAT => sys_fstatat(args[0], args[1] as *const u8, args[2] as *mut Stat, args[3]),
+        SYS_UNLINKAT => sys_unlinkat(args[0], args[1] as *const u8, args[2]),
+        SYS_READLINKAT => sys_readlinkat(args[0], args[1] as *const u8, args[2] as *mut u8, args[3]),
+        SYS_RENAMEAT => sys_renameat(args[0], args[1] as *const u8, args[2], args[3] as *const u8),
+        SYS_LINKAT => sys_linkat(args[0], args[1] as *const u8, args[2], args[3] as *const u8, args[4]),
         SYS_SYMLINKAT => Err(SysError::EACCES),
-        SYS_FACCESSAT => sys_access(args[1] as *const u8, args[2]), // TODO: handle `dfd`
+        SYS_FACCESSAT => sys_faccessat(args[0], args[1] as *const u8, args[2], args[3]),
         // 280
         SYS_UTIMENSAT => {
             warn!("sys_utimensat is unimplemented");