diff options
author | Andrew Waterman <waterman@cs.berkeley.edu> | 2016-02-19 12:39:15 -0800 |
---|---|---|
committer | Andrew Waterman <waterman@cs.berkeley.edu> | 2016-02-19 12:39:15 -0800 |
commit | 7016bac5dfb70a63c5041edc0c2922b9d6e3fd89 (patch) | |
tree | e064560c0e5d22e2f61403af90f356918f012288 | |
parent | 31ad71b8a4a2ef1b9692a844c3b9a938a22fb9b1 (diff) | |
download | pk-7016bac5dfb70a63c5041edc0c2922b9d6e3fd89.zip pk-7016bac5dfb70a63c5041edc0c2922b9d6e3fd89.tar.gz pk-7016bac5dfb70a63c5041edc0c2922b9d6e3fd89.tar.bz2 |
Fix struct stat size mismatch for RV32
-rw-r--r-- | pk/file.c | 6 | ||||
-rw-r--r-- | pk/frontend.c | 17 | ||||
-rw-r--r-- | pk/frontend.h | 26 | ||||
-rw-r--r-- | pk/syscall.c | 12 |
4 files changed, 55 insertions, 6 deletions
@@ -141,8 +141,10 @@ ssize_t file_pwrite(file_t* f, const void* buf, size_t size, off_t offset) int file_stat(file_t* f, struct stat* s) { - populate_mapping(s, sizeof(*s), PROT_WRITE); - return frontend_syscall(SYS_fstat, f->kfd, (uintptr_t)s, 0, 0, 0, 0, 0); + struct frontend_stat buf; + long ret = frontend_syscall(SYS_fstat, f->kfd, (uintptr_t)&buf, 0, 0, 0, 0, 0); + copy_stat(s, &buf); + return ret; } int file_truncate(file_t* f, off_t len) diff --git a/pk/frontend.c b/pk/frontend.c index 52e26fa..b2d26ce 100644 --- a/pk/frontend.c +++ b/pk/frontend.c @@ -51,3 +51,20 @@ void die(int code) frontend_syscall(SYS_exit, code, 0, 0, 0, 0, 0, 0); while (1); } + +void copy_stat(struct stat* dest, struct frontend_stat* src) +{ + dest->st_dev = src->dev; + dest->st_ino = src->ino; + dest->st_mode = src->mode; + dest->st_nlink = src->nlink; + dest->st_uid = src->uid; + dest->st_gid = src->gid; + dest->st_rdev = src->rdev; + dest->st_size = src->size; + dest->st_blksize = src->blksize; + dest->st_blocks = src->blocks; + dest->st_atime = src->atime; + dest->st_mtime = src->mtime; + dest->st_ctime = src->ctime; +} diff --git a/pk/frontend.h b/pk/frontend.h index 40f7c19..65f3c47 100644 --- a/pk/frontend.h +++ b/pk/frontend.h @@ -4,6 +4,7 @@ #define _RISCV_FRONTEND_H #include <stdint.h> +#include <sys/stat.h> #ifdef __riscv64 # define TOHOST_CMD(dev, cmd, payload) \ @@ -21,4 +22,29 @@ void die(int) __attribute__((noreturn)); long frontend_syscall(long n, long a0, long a1, long a2, long a3, long a4, long a5, long a6); uint64_t tohost_sync(unsigned dev, unsigned cmd, uint64_t payload); +struct frontend_stat { + uint64_t dev; + uint64_t ino; + uint32_t mode; + uint32_t nlink; + uint32_t uid; + uint32_t gid; + uint64_t rdev; + uint64_t __pad1; + uint64_t size; + uint32_t blksize; + uint32_t __pad2; + uint64_t blocks; + uint64_t atime; + uint64_t __pad3; + uint64_t mtime; + uint64_t __pad4; + uint64_t ctime; + uint64_t __pad5; + uint32_t __unused4; + uint32_t __unused5; +}; + +void copy_stat(struct stat* dest, struct frontend_stat* src); + #endif diff --git a/pk/syscall.c b/pk/syscall.c index 1ba40bf..6af78ee 100644 --- a/pk/syscall.c +++ b/pk/syscall.c @@ -212,18 +212,22 @@ ssize_t sys_lseek(int fd, size_t ptr, int dir) long sys_lstat(const char* name, void* st) { + struct frontend_stat buf; size_t name_size = strlen(name)+1; - populate_mapping(st, sizeof(struct stat), PROT_WRITE); - return frontend_syscall(SYS_lstat, (uintptr_t)name, name_size, (uintptr_t)st, 0, 0, 0, 0); + long ret = frontend_syscall(SYS_lstat, (uintptr_t)name, name_size, (uintptr_t)&buf, 0, 0, 0, 0); + copy_stat(st, &buf); + return ret; } long sys_fstatat(int dirfd, const char* name, void* st, int flags) { int kfd = at_kfd(dirfd); if (kfd != -1) { + struct frontend_stat buf; size_t name_size = strlen(name)+1; - populate_mapping(st, sizeof(struct stat), PROT_WRITE); - return frontend_syscall(SYS_fstatat, kfd, (uintptr_t)name, name_size, (uintptr_t)st, flags, 0, 0); + long ret = frontend_syscall(SYS_fstatat, kfd, (uintptr_t)name, name_size, (uintptr_t)&buf, flags, 0, 0); + copy_stat(st, &buf); + return ret; } return -EBADF; } |