aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrew Waterman <waterman@cs.berkeley.edu>2016-02-19 12:39:15 -0800
committerAndrew Waterman <waterman@cs.berkeley.edu>2016-02-19 12:39:15 -0800
commit7016bac5dfb70a63c5041edc0c2922b9d6e3fd89 (patch)
treee064560c0e5d22e2f61403af90f356918f012288
parent31ad71b8a4a2ef1b9692a844c3b9a938a22fb9b1 (diff)
downloadpk-7016bac5dfb70a63c5041edc0c2922b9d6e3fd89.zip
pk-7016bac5dfb70a63c5041edc0c2922b9d6e3fd89.tar.gz
pk-7016bac5dfb70a63c5041edc0c2922b9d6e3fd89.tar.bz2
Fix struct stat size mismatch for RV32
-rw-r--r--pk/file.c6
-rw-r--r--pk/frontend.c17
-rw-r--r--pk/frontend.h26
-rw-r--r--pk/syscall.c12
4 files changed, 55 insertions, 6 deletions
diff --git a/pk/file.c b/pk/file.c
index 0c9c96a..e522685 100644
--- a/pk/file.c
+++ b/pk/file.c
@@ -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;
}