[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[PATCH 31/43] semihosting: Create semihost_sys_{stat,fstat}
From: |
Richard Henderson |
Subject: |
[PATCH 31/43] semihosting: Create semihost_sys_{stat,fstat} |
Date: |
Sat, 30 Apr 2022 06:29:20 -0700 |
These syscalls will be used by m68k and nios2 semihosting.
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
include/semihosting/guestfd.h | 7 ++
semihosting/guestfd.c | 137 ++++++++++++++++++++++++++++++++++
2 files changed, 144 insertions(+)
diff --git a/include/semihosting/guestfd.h b/include/semihosting/guestfd.h
index a6d34e8141..315cac1c44 100644
--- a/include/semihosting/guestfd.h
+++ b/include/semihosting/guestfd.h
@@ -82,4 +82,11 @@ void semihost_sys_rename(CPUState *cs,
gdb_syscall_complete_cb complete,
void semihost_sys_system(CPUState *cs, gdb_syscall_complete_cb complete,
target_ulong cmd, target_ulong cmd_len);
+void semihost_sys_fstat(CPUState *cs, gdb_syscall_complete_cb complete,
+ int fd, target_ulong addr);
+
+void semihost_sys_stat(CPUState *cs, gdb_syscall_complete_cb complete,
+ target_ulong fname, target_ulong fname_len,
+ target_ulong addr);
+
#endif /* SEMIHOSTING_GUESTFD_H */
diff --git a/semihosting/guestfd.c b/semihosting/guestfd.c
index 9176ddd301..c182d5b7e6 100644
--- a/semihosting/guestfd.c
+++ b/semihosting/guestfd.c
@@ -563,12 +563,95 @@ void semihost_sys_isatty(CPUState *cs,
gdb_syscall_complete_cb complete, int fd)
}
}
+/*
+ * TODO: Note that gdb always stores the stat structure big-endian.
+ * So far, that's ok, as the only two targets using this are also
+ * big-endian. Until we do something with gdb, also produce the
+ * same big-endian result from the host.
+ */
+static int copy_stat_to_user(CPUState *cs, target_ulong addr,
+ const struct stat *s)
+{
+ CPUArchState *env G_GNUC_UNUSED = cs->env_ptr;
+ struct gdb_stat *p;
+
+ if (s->st_dev != (uint32_t)s->st_dev ||
+ s->st_ino != (uint32_t)s->st_ino) {
+ return -EOVERFLOW;
+ }
+
+ p = lock_user(VERIFY_WRITE, addr, sizeof(struct gdb_stat), 0);
+ if (!p) {
+ return -EFAULT;
+ }
+
+ p->gdb_st_dev = cpu_to_be32(s->st_dev);
+ p->gdb_st_ino = cpu_to_be32(s->st_ino);
+ p->gdb_st_mode = cpu_to_be32(s->st_mode);
+ p->gdb_st_nlink = cpu_to_be32(s->st_nlink);
+ p->gdb_st_uid = cpu_to_be32(s->st_uid);
+ p->gdb_st_gid = cpu_to_be32(s->st_gid);
+ p->gdb_st_rdev = cpu_to_be32(s->st_rdev);
+ p->gdb_st_size = cpu_to_be64(s->st_size);
+#ifdef _WIN32
+ /* Windows stat is missing some fields. */
+ p->gdb_st_blksize = 0;
+ p->gdb_st_blocks = 0;
+#else
+ p->gdb_st_blksize = cpu_to_be64(s->st_blksize);
+ p->gdb_st_blocks = cpu_to_be64(s->st_blocks);
+#endif
+ p->gdb_st_atime = cpu_to_be32(s->st_atime);
+ p->gdb_st_mtime = cpu_to_be32(s->st_mtime);
+ p->gdb_st_ctime = cpu_to_be32(s->st_ctime);
+
+ unlock_user(p, addr, sizeof(struct gdb_stat));
+ return 0;
+}
+
static void gdb_fstat(CPUState *cs, gdb_syscall_complete_cb complete,
GuestFD *gf, target_ulong addr)
{
gdb_do_syscall(complete, "fstat,%x,%x", (target_ulong)gf->hostfd, addr);
}
+static void host_fstat(CPUState *cs, gdb_syscall_complete_cb complete,
+ GuestFD *gf, target_ulong addr)
+{
+ struct stat buf;
+ int ret;
+
+ ret = fstat(gf->hostfd, &buf);
+ if (ret) {
+ complete(cs, -1, errno);
+ return;
+ }
+ ret = copy_stat_to_user(cs, addr, &buf);
+ complete(cs, ret ? -1 : 0, ret ? -ret : 0);
+}
+
+void semihost_sys_fstat(CPUState *cs, gdb_syscall_complete_cb complete,
+ int fd, target_ulong addr)
+{
+ GuestFD *gf = get_guestfd(fd);
+
+ if (!gf) {
+ complete(cs, -1, EBADF);
+ return;
+ }
+ switch (gf->type) {
+ case GuestFDGDB:
+ gdb_fstat(cs, complete, gf, addr);
+ break;
+ case GuestFDHost:
+ host_fstat(cs, complete, gf, addr);
+ break;
+ case GuestFDStatic:
+ default:
+ g_assert_not_reached();
+ }
+}
+
static void host_flen(CPUState *cs, gdb_syscall_complete_cb complete,
GuestFD *gf)
{
@@ -754,3 +837,57 @@ void semihost_sys_system(CPUState *cs,
gdb_syscall_complete_cb complete,
host_system(cs, complete, cmd, cmd_len);
}
}
+
+static void gdb_stat(CPUState *cs, gdb_syscall_complete_cb complete,
+ target_ulong fname, target_ulong fname_len,
+ target_ulong addr)
+{
+ int len = validate_strlen(cs, fname, fname_len);
+ if (len < 0) {
+ complete(cs, -1, -len);
+ return;
+ }
+
+ gdb_do_syscall(complete, "stat,%s,%x", fname, len, addr);
+}
+
+static void host_stat(CPUState *cs, gdb_syscall_complete_cb complete,
+ target_ulong fname, target_ulong fname_len,
+ target_ulong addr)
+{
+ CPUArchState *env G_GNUC_UNUSED = cs->env_ptr;
+ struct stat buf;
+ char *name;
+ int ret, err;
+
+ ret = validate_lock_user_string(&name, cs, fname, fname_len);
+ if (ret < 0) {
+ complete(cs, -1, -ret);
+ return;
+ }
+
+ ret = stat(name, &buf);
+ if (ret) {
+ err = errno;
+ } else {
+ ret = copy_stat_to_user(cs, addr, &buf);
+ err = 0;
+ if (ret < 0) {
+ err = -ret;
+ ret = -1;
+ }
+ }
+ complete(cs, ret, err);
+ unlock_user(name, fname, 0);
+}
+
+void semihost_sys_stat(CPUState *cs, gdb_syscall_complete_cb complete,
+ target_ulong fname, target_ulong fname_len,
+ target_ulong addr)
+{
+ if (use_gdb_syscalls()) {
+ gdb_stat(cs, complete, fname, fname_len, addr);
+ } else {
+ host_stat(cs, complete, fname, fname_len, addr);
+ }
+}
--
2.34.1
- [PATCH 35/43] target/m68k: Make semihosting system only, (continued)
- [PATCH 35/43] target/m68k: Make semihosting system only, Richard Henderson, 2022/04/30
- [PATCH 39/43] target/m68k: Remove EXCP_HALT_INSN, Richard Henderson, 2022/04/30
- [PATCH 09/43] semihosting: Return void from do_common_semihosting, Richard Henderson, 2022/04/30
- [PATCH 15/43] semihosting: Split is_64bit_semihosting per target, Richard Henderson, 2022/04/30
- [PATCH 14/43] semihosting: Use struct gdb_stat in common_semi_flen_cb, Richard Henderson, 2022/04/30
- [PATCH 22/43] semihosting: Split out semihost_sys_read, Richard Henderson, 2022/04/30
- [PATCH 21/43] semihosting: Split out semihost_sys_close, Richard Henderson, 2022/04/30
- [PATCH 26/43] semihosting: Split out semihost_sys_isatty, Richard Henderson, 2022/04/30
- [PATCH 27/43] semihosting: Split out semihost_sys_flen, Richard Henderson, 2022/04/30
- [PATCH 30/43] semihosting: Split out semihost_sys_system, Richard Henderson, 2022/04/30
- [PATCH 31/43] semihosting: Create semihost_sys_{stat,fstat},
Richard Henderson <=
- [PATCH 38/43] target/m68k: Enable semihosting for non-coldfire, Richard Henderson, 2022/04/30
- [PATCH 34/43] target/m68k: Eliminate m68k_semi_is_fseek, Richard Henderson, 2022/04/30
- [PATCH 16/43] semihosting: Split common_semi_flen_buf per target, Richard Henderson, 2022/04/30
- [PATCH 23/43] semihosting: Split out semihost_sys_write, Richard Henderson, 2022/04/30
- [PATCH 28/43] semihosting: Split out semihost_sys_remove, Richard Henderson, 2022/04/30
- [PATCH 29/43] semihosting: Split out semihost_sys_rename, Richard Henderson, 2022/04/30
- [PATCH 37/43] target/m68k: Do semihosting call as a normal helper, Richard Henderson, 2022/04/30
- [PATCH 32/43] semihosting: Create semihost_sys_gettimeofday, Richard Henderson, 2022/04/30
- [PATCH 08/43] semihosting: Generalize GuestFDFeatureFile, Richard Henderson, 2022/04/30
- [PATCH 18/43] semihosting: Use env more often in do_common_semihosting, Richard Henderson, 2022/04/30