From 935f1dd8181b757e6eff83522d85b0a2b84c27c5 Mon Sep 17 00:00:00 2001 From: Richard Henderson Date: Fri, 18 Aug 2023 10:57:34 -0700 Subject: [PATCH 01/36] bsd-user: Remove ELF_START_MMAP and image_info.start_mmap MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The start_mmap value is write-only. Remove the field and the defines that populated it. Signed-off-by: Richard Henderson Reviewed-by: Philippe Mathieu-Daudé Message-Id: <20230818175736.144194-2-richard.henderson@linaro.org> Reviewed-by: Warner Losh Signed-off-by: Warner Losh --- bsd-user/arm/target_arch_elf.h | 1 - bsd-user/elfload.c | 1 - bsd-user/i386/target_arch_elf.h | 1 - bsd-user/qemu.h | 1 - bsd-user/x86_64/target_arch_elf.h | 1 - 5 files changed, 5 deletions(-) diff --git a/bsd-user/arm/target_arch_elf.h b/bsd-user/arm/target_arch_elf.h index 935bce347f..b1c0fd2b32 100644 --- a/bsd-user/arm/target_arch_elf.h +++ b/bsd-user/arm/target_arch_elf.h @@ -20,7 +20,6 @@ #ifndef TARGET_ARCH_ELF_H #define TARGET_ARCH_ELF_H -#define ELF_START_MMAP 0x80000000 #define ELF_ET_DYN_LOAD_ADDR 0x500000 #define elf_check_arch(x) ((x) == EM_ARM) diff --git a/bsd-user/elfload.c b/bsd-user/elfload.c index 1f650bdde8..38a3439d2c 100644 --- a/bsd-user/elfload.c +++ b/bsd-user/elfload.c @@ -738,7 +738,6 @@ int load_elf_binary(struct bsd_binprm *bprm, struct target_pt_regs *regs, /* OK, This is the point of no return */ info->end_data = 0; info->end_code = 0; - info->start_mmap = (abi_ulong)ELF_START_MMAP; info->mmap = 0; elf_entry = (abi_ulong) elf_ex.e_entry; diff --git a/bsd-user/i386/target_arch_elf.h b/bsd-user/i386/target_arch_elf.h index cbcd1f08e2..4ac27b02e7 100644 --- a/bsd-user/i386/target_arch_elf.h +++ b/bsd-user/i386/target_arch_elf.h @@ -20,7 +20,6 @@ #ifndef TARGET_ARCH_ELF_H #define TARGET_ARCH_ELF_H -#define ELF_START_MMAP 0x80000000 #define ELF_ET_DYN_LOAD_ADDR 0x01001000 #define elf_check_arch(x) (((x) == EM_386) || ((x) == EM_486)) diff --git a/bsd-user/qemu.h b/bsd-user/qemu.h index 8f2d6a3c78..178114b423 100644 --- a/bsd-user/qemu.h +++ b/bsd-user/qemu.h @@ -52,7 +52,6 @@ struct image_info { abi_ulong end_data; abi_ulong start_brk; abi_ulong brk; - abi_ulong start_mmap; abi_ulong mmap; abi_ulong rss; abi_ulong start_stack; diff --git a/bsd-user/x86_64/target_arch_elf.h b/bsd-user/x86_64/target_arch_elf.h index b244711888..e51c2faf08 100644 --- a/bsd-user/x86_64/target_arch_elf.h +++ b/bsd-user/x86_64/target_arch_elf.h @@ -20,7 +20,6 @@ #ifndef TARGET_ARCH_ELF_H #define TARGET_ARCH_ELF_H -#define ELF_START_MMAP 0x2aaaaab000ULL #define ELF_ET_DYN_LOAD_ADDR 0x01021000 #define elf_check_arch(x) (((x) == ELF_ARCH)) From 7db1873664dcba22820981ad105b0d30bcd509b8 Mon Sep 17 00:00:00 2001 From: Richard Henderson Date: Fri, 18 Aug 2023 10:57:35 -0700 Subject: [PATCH 02/36] bsd-user: Remove image_info.mmap MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This value is unused. Signed-off-by: Richard Henderson Reviewed-by: Philippe Mathieu-Daudé Message-Id: <20230818175736.144194-3-richard.henderson@linaro.org> Reviewed-by: Warner Losh Signed-off-by: Warner Losh --- bsd-user/elfload.c | 1 - bsd-user/qemu.h | 1 - 2 files changed, 2 deletions(-) diff --git a/bsd-user/elfload.c b/bsd-user/elfload.c index 38a3439d2c..2d39e59258 100644 --- a/bsd-user/elfload.c +++ b/bsd-user/elfload.c @@ -738,7 +738,6 @@ int load_elf_binary(struct bsd_binprm *bprm, struct target_pt_regs *regs, /* OK, This is the point of no return */ info->end_data = 0; info->end_code = 0; - info->mmap = 0; elf_entry = (abi_ulong) elf_ex.e_entry; /* XXX Join this with PT_INTERP search? */ diff --git a/bsd-user/qemu.h b/bsd-user/qemu.h index 178114b423..898fe3e8b3 100644 --- a/bsd-user/qemu.h +++ b/bsd-user/qemu.h @@ -52,7 +52,6 @@ struct image_info { abi_ulong end_data; abi_ulong start_brk; abi_ulong brk; - abi_ulong mmap; abi_ulong rss; abi_ulong start_stack; abi_ulong entry; From 4436e2ff6cae585f4863fa59a3ad77dd3c54ac63 Mon Sep 17 00:00:00 2001 From: Richard Henderson Date: Fri, 18 Aug 2023 10:57:36 -0700 Subject: [PATCH 03/36] bsd-user: Remove image_info.start_brk MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This has the same value is image_info.brk, which is also logged, and is otherwise unused. Signed-off-by: Richard Henderson Reviewed-by: Philippe Mathieu-Daudé Message-Id: <20230818175736.144194-4-richard.henderson@linaro.org> Reviewed-by: Warner Losh Signed-off-by: Warner Losh --- bsd-user/elfload.c | 2 +- bsd-user/main.c | 2 -- bsd-user/qemu.h | 1 - 3 files changed, 1 insertion(+), 4 deletions(-) diff --git a/bsd-user/elfload.c b/bsd-user/elfload.c index 2d39e59258..baf2f63d2f 100644 --- a/bsd-user/elfload.c +++ b/bsd-user/elfload.c @@ -811,7 +811,7 @@ int load_elf_binary(struct bsd_binprm *bprm, struct target_pt_regs *regs, bprm->stringp, &elf_ex, load_addr, et_dyn_addr, interp_load_addr, info); info->load_addr = reloc_func_desc; - info->start_brk = info->brk = elf_brk; + info->brk = elf_brk; info->start_stack = bprm->p; info->load_bias = 0; diff --git a/bsd-user/main.c b/bsd-user/main.c index 381bb18df8..f913cb55a7 100644 --- a/bsd-user/main.c +++ b/bsd-user/main.c @@ -553,8 +553,6 @@ int main(int argc, char **argv) fprintf(f, "page layout changed following binary load\n"); page_dump(f); - fprintf(f, "start_brk 0x" TARGET_ABI_FMT_lx "\n", - info->start_brk); fprintf(f, "end_code 0x" TARGET_ABI_FMT_lx "\n", info->end_code); fprintf(f, "start_code 0x" TARGET_ABI_FMT_lx "\n", diff --git a/bsd-user/qemu.h b/bsd-user/qemu.h index 898fe3e8b3..61501c321b 100644 --- a/bsd-user/qemu.h +++ b/bsd-user/qemu.h @@ -50,7 +50,6 @@ struct image_info { abi_ulong end_code; abi_ulong start_data; abi_ulong end_data; - abi_ulong start_brk; abi_ulong brk; abi_ulong rss; abi_ulong start_stack; From 25e2cfbb8e621a4a726040427f14dca68f78bd1b Mon Sep 17 00:00:00 2001 From: Warner Losh Date: Sun, 13 Aug 2023 10:41:22 +0200 Subject: [PATCH 04/36] bsd-user: Move _WANT_FREEBSD macros to include/qemu/osdep.h move _WANT_FREEBSD macros from bsd-user/freebsd/os-syscall.c to include/qemu/osdep.h in order to pull some struct defintions needed later in the build. Signed-off-by: Warner Losh Signed-off-by: Karim Taha Acked-by: Richard Henderson --- bsd-user/freebsd/os-syscall.c | 11 ----------- include/qemu/osdep.h | 13 +++++++++++++ 2 files changed, 13 insertions(+), 11 deletions(-) diff --git a/bsd-user/freebsd/os-syscall.c b/bsd-user/freebsd/os-syscall.c index de36c4b71c..2224a280ea 100644 --- a/bsd-user/freebsd/os-syscall.c +++ b/bsd-user/freebsd/os-syscall.c @@ -17,17 +17,6 @@ * You should have received a copy of the GNU General Public License * along with this program; if not, see . */ - -/* - * We need the FreeBSD "legacy" definitions. Rust needs the FreeBSD 11 system - * calls since it doesn't use libc at all, so we have to emulate that despite - * FreeBSD 11 being EOL'd. - */ -#define _WANT_FREEBSD11_STAT -#define _WANT_FREEBSD11_STATFS -#define _WANT_FREEBSD11_DIRENT -#define _WANT_KERNEL_ERRNO -#define _WANT_SEMUN #include "qemu/osdep.h" #include "qemu/cutils.h" #include "qemu/path.h" diff --git a/include/qemu/osdep.h b/include/qemu/osdep.h index 21ef8f1699..2cae135280 100644 --- a/include/qemu/osdep.h +++ b/include/qemu/osdep.h @@ -88,6 +88,19 @@ QEMU_EXTERN_C int daemon(int, int); #define __USE_MINGW_ANSI_STDIO 1 #endif +/* + * We need the FreeBSD "legacy" definitions. Rust needs the FreeBSD 11 system + * calls since it doesn't use libc at all, so we have to emulate that despite + * FreeBSD 11 being EOL'd. + */ +#ifdef __FreeBSD__ +#define _WANT_FREEBSD11_STAT +#define _WANT_FREEBSD11_STATFS +#define _WANT_FREEBSD11_DIRENT +#define _WANT_KERNEL_ERRNO +#define _WANT_SEMUN +#endif + #include #include #include From 15b950ecd16ecc6e9a1f21e1f9f185ee61a5a1d5 Mon Sep 17 00:00:00 2001 From: Kyle Evans Date: Sun, 13 Aug 2023 10:41:23 +0200 Subject: [PATCH 05/36] bsd-user: Disable clang warnings Implement PRAGMA_DISABLE_PACKED_WARNING and PRAGMA_REENABLE_PACKED_WARNING macros in include/qemu/compiler.h. Signed-off-by: Kyle Evans Signed-off-by: Karim Taha Reviewed-by: Richard Henderson Signed-off-by: Warner Losh --- include/qemu/compiler.h | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/include/qemu/compiler.h b/include/qemu/compiler.h index a309f90c76..b037442518 100644 --- a/include/qemu/compiler.h +++ b/include/qemu/compiler.h @@ -22,6 +22,36 @@ #define QEMU_EXTERN_C extern #endif +/* + * Tricky points: + * - Use __builtin_choose_expr to avoid type promotion from ?:, + * - Invalid sizes result in a compile time error stemming from + * the fact that abort has no parameters. + * - It's easier to use the endian-specific unaligned load/store + * functions than host-endian unaligned load/store plus tswapN. + * - The pragmas are necessary only to silence a clang false-positive + * warning: see https://bugs.llvm.org/show_bug.cgi?id=39113 . + * - We have to disable -Wpragmas warnings to avoid a complaint about + * an unknown warning type from older compilers that don't know about + * -Waddress-of-packed-member. + * - gcc has bugs in its _Pragma() support in some versions, eg + * https://gcc.gnu.org/bugzilla/show_bug.cgi?id=83256 -- so we only + * include the warning-suppression pragmas for clang + */ +#ifdef __clang__ +#define PRAGMA_DISABLE_PACKED_WARNING \ + _Pragma("GCC diagnostic push"); \ + _Pragma("GCC diagnostic ignored \"-Wpragmas\""); \ + _Pragma("GCC diagnostic ignored \"-Waddress-of-packed-member\"") + +#define PRAGMA_REENABLE_PACKED_WARNING \ + _Pragma("GCC diagnostic pop") + +#else +#define PRAGMA_DISABLE_PACKED_WARNING +#define PRAGMA_REENABLE_PACKED_WARNING +#endif + #if defined(_WIN32) && (defined(__x86_64__) || defined(__i386__)) # define QEMU_PACKED __attribute__((gcc_struct, packed)) #else From 6538c682db9c2b34fbffc22e111a4bcd8f4b02de Mon Sep 17 00:00:00 2001 From: Warner Losh Date: Sun, 13 Aug 2023 10:41:24 +0200 Subject: [PATCH 06/36] bsd-user; Update the definitions of __put_user and __get_user macros Use __builtin_choose_expr to avoid type promotion from ?: in __put_user_e and __get_user_e macros. Copied from linux-user/qemu.h, originally by Blue Swirl. Signed-off-by: Warner Losh Signed-off-by: Karim Taha Reviewed-by: Richard Henderson --- bsd-user/qemu.h | 81 ++++++++++++++++++++--------------------------- bsd-user/signal.c | 5 +-- 2 files changed, 35 insertions(+), 51 deletions(-) diff --git a/bsd-user/qemu.h b/bsd-user/qemu.h index 61501c321b..ca791e18b2 100644 --- a/bsd-user/qemu.h +++ b/bsd-user/qemu.h @@ -272,50 +272,37 @@ static inline bool access_ok(int type, abi_ulong addr, abi_ulong size) * These are usually used to access struct data members once the struct has been * locked - usually with lock_user_struct(). */ -#define __put_user(x, hptr)\ -({\ - int size = sizeof(*hptr);\ - switch (size) {\ - case 1:\ - *(uint8_t *)(hptr) = (uint8_t)(typeof(*hptr))(x);\ - break;\ - case 2:\ - *(uint16_t *)(hptr) = tswap16((typeof(*hptr))(x));\ - break;\ - case 4:\ - *(uint32_t *)(hptr) = tswap32((typeof(*hptr))(x));\ - break;\ - case 8:\ - *(uint64_t *)(hptr) = tswap64((typeof(*hptr))(x));\ - break;\ - default:\ - abort();\ - } \ - 0;\ -}) +#define __put_user_e(x, hptr, e) \ + do { \ + PRAGMA_DISABLE_PACKED_WARNING; \ + (__builtin_choose_expr(sizeof(*(hptr)) == 1, stb_p, \ + __builtin_choose_expr(sizeof(*(hptr)) == 2, stw_##e##_p, \ + __builtin_choose_expr(sizeof(*(hptr)) == 4, stl_##e##_p, \ + __builtin_choose_expr(sizeof(*(hptr)) == 8, stq_##e##_p, abort)))) \ + ((hptr), (x)), (void)0); \ + PRAGMA_REENABLE_PACKED_WARNING; \ + } while (0) -#define __get_user(x, hptr) \ -({\ - int size = sizeof(*hptr);\ - switch (size) {\ - case 1:\ - x = (typeof(*hptr))*(uint8_t *)(hptr);\ - break;\ - case 2:\ - x = (typeof(*hptr))tswap16(*(uint16_t *)(hptr));\ - break;\ - case 4:\ - x = (typeof(*hptr))tswap32(*(uint32_t *)(hptr));\ - break;\ - case 8:\ - x = (typeof(*hptr))tswap64(*(uint64_t *)(hptr));\ - break;\ - default:\ - x = 0;\ - abort();\ - } \ - 0;\ -}) +#define __get_user_e(x, hptr, e) \ + do { \ + PRAGMA_DISABLE_PACKED_WARNING; \ + ((x) = (typeof(*hptr))( \ + __builtin_choose_expr(sizeof(*(hptr)) == 1, ldub_p, \ + __builtin_choose_expr(sizeof(*(hptr)) == 2, lduw_##e##_p, \ + __builtin_choose_expr(sizeof(*(hptr)) == 4, ldl_##e##_p, \ + __builtin_choose_expr(sizeof(*(hptr)) == 8, ldq_##e##_p, abort)))) \ + (hptr)), (void)0); \ + PRAGMA_REENABLE_PACKED_WARNING; \ + } while (0) + + +#if TARGET_BIG_ENDIAN +# define __put_user(x, hptr) __put_user_e(x, hptr, be) +# define __get_user(x, hptr) __get_user_e(x, hptr, be) +#else +# define __put_user(x, hptr) __put_user_e(x, hptr, le) +# define __get_user(x, hptr) __get_user_e(x, hptr, le) +#endif /* * put_user()/get_user() take a guest address and check access @@ -328,10 +315,10 @@ static inline bool access_ok(int type, abi_ulong addr, abi_ulong size) ({ \ abi_ulong __gaddr = (gaddr); \ target_type *__hptr; \ - abi_long __ret; \ + abi_long __ret = 0; \ __hptr = lock_user(VERIFY_WRITE, __gaddr, sizeof(target_type), 0); \ if (__hptr) { \ - __ret = __put_user((x), __hptr); \ + __put_user((x), __hptr); \ unlock_user(__hptr, __gaddr, sizeof(target_type)); \ } else \ __ret = -TARGET_EFAULT; \ @@ -342,10 +329,10 @@ static inline bool access_ok(int type, abi_ulong addr, abi_ulong size) ({ \ abi_ulong __gaddr = (gaddr); \ target_type *__hptr; \ - abi_long __ret; \ + abi_long __ret = 0; \ __hptr = lock_user(VERIFY_READ, __gaddr, sizeof(target_type), 1); \ if (__hptr) { \ - __ret = __get_user((x), __hptr); \ + __get_user((x), __hptr); \ unlock_user(__hptr, __gaddr, 0); \ } else { \ (x) = 0; \ diff --git a/bsd-user/signal.c b/bsd-user/signal.c index f4e078ee1d..4db85a3485 100644 --- a/bsd-user/signal.c +++ b/bsd-user/signal.c @@ -787,10 +787,7 @@ static int reset_signal_mask(target_ucontext_t *ucontext) TaskState *ts = (TaskState *)thread_cpu->opaque; for (i = 0; i < TARGET_NSIG_WORDS; i++) { - if (__get_user(target_set.__bits[i], - &ucontext->uc_sigmask.__bits[i])) { - return -TARGET_EFAULT; - } + __get_user(target_set.__bits[i], &ucontext->uc_sigmask.__bits[i]); } target_to_host_sigset_internal(&blocked, &target_set); ts->signal_mask = blocked; From 9b4a902d3164b60ea732cca7405fcd2d083b784e Mon Sep 17 00:00:00 2001 From: Stacey Son Date: Sun, 13 Aug 2023 10:41:25 +0200 Subject: [PATCH 07/36] bsd-user: Declarations of h2t and t2h conversion functions. Declarations of functions that convert between host and target structs. Co-authored-by: Michal Meloun Signed-off-by: Stacey Son Signed-off-by: Karim Taha Reviewed-by: Richard Henderson Signed-off-by: Warner Losh --- bsd-user/freebsd/qemu-os.h | 50 ++++++++++++++++++++++++++++++++++++++ bsd-user/qemu.h | 1 + 2 files changed, 51 insertions(+) create mode 100644 bsd-user/freebsd/qemu-os.h diff --git a/bsd-user/freebsd/qemu-os.h b/bsd-user/freebsd/qemu-os.h new file mode 100644 index 0000000000..12adc50928 --- /dev/null +++ b/bsd-user/freebsd/qemu-os.h @@ -0,0 +1,50 @@ +/* + * FreeBSD conversion extern declarations + * + * Copyright (c) 2013 Stacey D. Son + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see . + */ + +#ifndef QEMU_OS_H +#define QEMU_OS_H + +/* qemu/osdep.h pulls in the rest */ + +#include +#include +#include +#include +#include +#include +#include + +struct freebsd11_stat; + +/* os-stat.c */ +abi_long h2t_freebsd11_stat(abi_ulong target_addr, + struct freebsd11_stat *host_st); +abi_long h2t_freebsd11_nstat(abi_ulong target_addr, + struct freebsd11_stat *host_st); +abi_long t2h_freebsd_fhandle(fhandle_t *host_fh, abi_ulong target_addr); +abi_long h2t_freebsd_fhandle(abi_ulong target_addr, fhandle_t *host_fh); +abi_long h2t_freebsd11_statfs(abi_ulong target_addr, + struct freebsd11_statfs *host_statfs); +abi_long target_to_host_fcntl_cmd(int cmd); +abi_long h2t_freebsd_stat(abi_ulong target_addr, + struct stat *host_st); +abi_long h2t_freebsd_statfs(abi_ulong target_addr, + struct statfs *host_statfs); + +#endif /* QEMU_OS_H */ diff --git a/bsd-user/qemu.h b/bsd-user/qemu.h index ca791e18b2..4cfd5c6337 100644 --- a/bsd-user/qemu.h +++ b/bsd-user/qemu.h @@ -38,6 +38,7 @@ extern char **environ; #include "exec/gdbstub.h" #include "qemu/clang-tsa.h" +#include "qemu-os.h" /* * This struct is used to hold certain information about the image. Basically, * it replicates in user space what would be certain task_struct fields in the From 40f5e2983407e51e00e0fc82ff59c1ed55001530 Mon Sep 17 00:00:00 2001 From: Stacey Son Date: Sun, 13 Aug 2023 10:41:26 +0200 Subject: [PATCH 08/36] bsd-user: Add struct target_freebsd11_stat to bsd-user/syscall_defs Signed-off-by: Stacey Son Signed-off-by: Karim Taha Acked-by: Richard Henderson Singed-off-by: Warner Losh --- bsd-user/syscall_defs.h | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/bsd-user/syscall_defs.h b/bsd-user/syscall_defs.h index aedfbf2d7d..56198cc6a0 100644 --- a/bsd-user/syscall_defs.h +++ b/bsd-user/syscall_defs.h @@ -179,6 +179,39 @@ struct target_freebsd__wrusage { struct target_freebsd_rusage wru_children; }; +/* + * sys/stat.h + */ +struct target_freebsd11_stat { + uint32_t st_dev; /* inode's device */ + uint32_t st_ino; /* inode's number */ + int16_t st_mode; /* inode protection mode */ + int16_t st_nlink; /* number of hard links */ + uint32_t st_uid; /* user ID of the file's owner */ + uint32_t st_gid; /* group ID of the file's group */ + uint32_t st_rdev; /* device type */ + struct target_freebsd_timespec st_atim; /* time last accessed */ + struct target_freebsd_timespec st_mtim; /* time last data modification */ + struct target_freebsd_timespec st_ctim; /* time last file status change */ + int64_t st_size; /* file size, in bytes */ + int64_t st_blocks; /* blocks allocated for file */ + uint32_t st_blksize; /* optimal blocksize for I/O */ + uint32_t st_flags; /* user defined flags for file */ + uint32_t st_gen; /* file generation number */ + int32_t st_lspare; + struct target_freebsd_timespec st_birthtim; /* time of file creation */ + /* + * Explicitly pad st_birthtim to 16 bytes so that the size of + * struct stat is backwards compatible. We use bitfields instead + * of an array of chars so that this doesn't require a C99 compiler + * to compile if the size of the padding is 0. We use 2 bitfields + * to cover up to 64 bits on 32-bit machines. We assume that + * CHAR_BIT is 8... + */ + unsigned int:(8 / 2) * (16 - (int)sizeof(struct target_freebsd_timespec)); + unsigned int:(8 / 2) * (16 - (int)sizeof(struct target_freebsd_timespec)); +} __packed; + #define safe_syscall0(type, name) \ type safe_##name(void) \ { \ From ad805a77592a1765515c70be225ec3097c954e5c Mon Sep 17 00:00:00 2001 From: Michal Meloun Date: Sun, 13 Aug 2023 10:41:27 +0200 Subject: [PATCH 09/36] bsd-user: Add struct target_stat to bsd-user/syscall_defs.h Signed-off-by: Michal Meloun Signed-off-by: Karim Taha Acked-by: Richard Henderson Signed-off-by: Warner Losh --- bsd-user/syscall_defs.h | 38 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) diff --git a/bsd-user/syscall_defs.h b/bsd-user/syscall_defs.h index 56198cc6a0..bd04b30a56 100644 --- a/bsd-user/syscall_defs.h +++ b/bsd-user/syscall_defs.h @@ -212,6 +212,44 @@ struct target_freebsd11_stat { unsigned int:(8 / 2) * (16 - (int)sizeof(struct target_freebsd_timespec)); } __packed; +#if defined(__i386__) +#define TARGET_HAS_STAT_TIME_T_EXT 1 +#endif + +struct target_stat { + uint64_t st_dev; /* inode's device */ + uint64_t st_ino; /* inode's number */ + uint64_t st_nlink; /* number of hard links */ + int16_t st_mode; /* inode protection mode */ + int16_t st_padding0; + uint32_t st_uid; /* user ID of the file's owner */ + uint32_t st_gid; /* group ID of the file's group */ + int32_t st_padding1; + uint64_t st_rdev; /* device type */ +#ifdef TARGET_HAS_STAT_TIME_T_EXT + int32_t st_atim_ext; +#endif + struct target_freebsd_timespec st_atim; /* time of last access */ +#ifdef TARGET_HAS_STAT_TIME_T_EXT + int32_t st_mtim_ext; +#endif + struct target_freebsd_timespec st_mtim; /* time of last data modification */ +#ifdef TARGET_HAS_STAT_TIME_T_EXT + int32_t st_ctim_ext; +#endif + struct target_freebsd_timespec st_ctim;/* time of last file status change */ +#ifdef TARGET_HAS_STAT_TIME_T_EXT + int32_t st_btim_ext; +#endif + struct target_freebsd_timespec st_birthtim; /* time of file creation */ + int64_t st_size; /* file size, in bytes */ + int64_t st_blocks; /* blocks allocated for file */ + uint32_t st_blksize; /* optimal blocksize for I/O */ + uint32_t st_flags; /* user defined flags for file */ + uint64_t st_gen; /* file generation number */ + uint64_t st_spare[10]; +}; + #define safe_syscall0(type, name) \ type safe_##name(void) \ { \ From 1de075a0f6c6aa0ab54cef4fae902d4c0e95effa Mon Sep 17 00:00:00 2001 From: Stacey Son Date: Sun, 13 Aug 2023 10:41:28 +0200 Subject: [PATCH 10/36] bsd-user: Add structs target_freebsd11_{nstat,statfs} Add structs target_freebsd11_nstat and target_freebsd11_statfs to bsd-user/syscall_defs.h Signed-off-by: Stacey Son Signed-off-by: Karim Taha Acked-by: Richard Henderson --- bsd-user/syscall_defs.h | 64 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 64 insertions(+) diff --git a/bsd-user/syscall_defs.h b/bsd-user/syscall_defs.h index bd04b30a56..51d8ff0dd8 100644 --- a/bsd-user/syscall_defs.h +++ b/bsd-user/syscall_defs.h @@ -250,6 +250,70 @@ struct target_stat { uint64_t st_spare[10]; }; + +/* struct nstat is the same as stat above but without the st_lspare field */ +struct target_freebsd11_nstat { + uint32_t st_dev; /* inode's device */ + uint32_t st_ino; /* inode's number */ + int16_t st_mode; /* inode protection mode */ + int16_t st_nlink; /* number of hard links */ + uint32_t st_uid; /* user ID of the file's owner */ + uint32_t st_gid; /* group ID of the file's group */ + uint32_t st_rdev; /* device type */ + struct target_freebsd_timespec st_atim; /* time last accessed */ + struct target_freebsd_timespec st_mtim; /* time last data modification */ + struct target_freebsd_timespec st_ctim; /* time last file status change */ + int64_t st_size; /* file size, in bytes */ + int64_t st_blocks; /* blocks allocated for file */ + uint32_t st_blksize; /* optimal blocksize for I/O */ + uint32_t st_flags; /* user defined flags for file */ + uint32_t st_gen; /* file generation number */ + struct target_freebsd_timespec st_birthtim; /* time of file creation */ + /* + * Explicitly pad st_birthtim to 16 bytes so that the size of + * struct stat is backwards compatible. We use bitfields instead + * of an array of chars so that this doesn't require a C99 compiler + * to compile if the size of the padding is 0. We use 2 bitfields + * to cover up to 64 bits on 32-bit machines. We assume that + * CHAR_BIT is 8... + */ + unsigned int:(8 / 2) * (16 - (int)sizeof(struct target_freebsd_timespec)); + unsigned int:(8 / 2) * (16 - (int)sizeof(struct target_freebsd_timespec)); +} __packed; + +/* + * sys/mount.h + */ + +/* filesystem id type */ +typedef struct target_freebsd_fsid { int32_t val[2]; } target_freebsd_fsid_t; + +/* filesystem statistics */ +struct target_freebsd11_statfs { + uint32_t f_version; /* structure version number */ + uint32_t f_type; /* type of filesystem */ + uint64_t f_flags; /* copy of mount exported flags */ + uint64_t f_bsize; /* filesystem fragment size */ + uint64_t f_iosize; /* optimal transfer block size */ + uint64_t f_blocks; /* total data blocks in filesystem */ + uint64_t f_bfree; /* free blocks in filesystem */ + int64_t f_bavail; /* free blocks avail to non-superuser */ + uint64_t f_files; /* total file nodes in filesystem */ + int64_t f_ffree; /* free nodes avail to non-superuser */ + uint64_t f_syncwrites; /* count of sync writes since mount */ + uint64_t f_asyncwrites; /* count of async writes since mount */ + uint64_t f_syncreads; /* count of sync reads since mount */ + uint64_t f_asyncreads; /* count of async reads since mount */ + uint64_t f_spare[10]; /* unused spare */ + uint32_t f_namemax; /* maximum filename length */ + uint32_t f_owner; /* user that mounted the filesystem */ + target_freebsd_fsid_t f_fsid; /* filesystem id */ + char f_charspare[80]; /* spare string space */ + char f_fstypename[16]; /* filesys type name */ + char f_mntfromname[88]; /* mount filesystem */ + char f_mntonname[88]; /* dir on which mounted*/ +}; + #define safe_syscall0(type, name) \ type safe_##name(void) \ { \ From 25efcda41f107f124019f338ae929a694ec6191e Mon Sep 17 00:00:00 2001 From: Michal Meloun Date: Sun, 13 Aug 2023 10:41:29 +0200 Subject: [PATCH 11/36] bsd-user: Add struct target_statfs Add struct target_statfs to bsd-user/syscall_defs.h Signed-off-by: Michal Meloun Signed-off-by: Karim Taha Acked-by: Richard Henderson Signed-off-by: Warner Losh --- bsd-user/syscall_defs.h | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/bsd-user/syscall_defs.h b/bsd-user/syscall_defs.h index 51d8ff0dd8..499a80f8bf 100644 --- a/bsd-user/syscall_defs.h +++ b/bsd-user/syscall_defs.h @@ -314,6 +314,31 @@ struct target_freebsd11_statfs { char f_mntonname[88]; /* dir on which mounted*/ }; +struct target_statfs { + uint32_t f_version; /* structure version number */ + uint32_t f_type; /* type of filesystem */ + uint64_t f_flags; /* copy of mount exported flags */ + uint64_t f_bsize; /* filesystem fragment size */ + uint64_t f_iosize; /* optimal transfer block size */ + uint64_t f_blocks; /* total data blocks in filesystem */ + uint64_t f_bfree; /* free blocks in filesystem */ + int64_t f_bavail; /* free blocks avail to non-superuser */ + uint64_t f_files; /* total file nodes in filesystem */ + int64_t f_ffree; /* free nodes avail to non-superuser */ + uint64_t f_syncwrites; /* count of sync writes since mount */ + uint64_t f_asyncwrites; /* count of async writes since mount */ + uint64_t f_syncreads; /* count of sync reads since mount */ + uint64_t f_asyncreads; /* count of async reads since mount */ + uint64_t f_spare[10]; /* unused spare */ + uint32_t f_namemax; /* maximum filename length */ + uint32_t f_owner; /* user that mounted the filesystem */ + target_freebsd_fsid_t f_fsid; /* filesystem id */ + char f_charspare[80]; /* spare string space */ + char f_fstypename[16]; /* filesystem type name */ + char f_mntfromname[1024]; /* mounted filesystem */ + char f_mntonname[1024]; /* directory on which mounted */ +}; + #define safe_syscall0(type, name) \ type safe_##name(void) \ { \ From 54d07b44aa534277d72fa570498bd379c06d9a40 Mon Sep 17 00:00:00 2001 From: Stacey Son Date: Sun, 13 Aug 2023 10:41:30 +0200 Subject: [PATCH 12/36] bsd-user: Add struct target_freebsd_fhandle and fcntl flags Add struct target_freebsd_fhandle and fcntl flags to bsd-user/syscall_defs.h Signed-off-by: Stacey Son Signed-off-by: Karim Taha Acked-by: Richard Henderson Reviewed-by: Warner Losh Signed-off-by: Warner Losh --- bsd-user/syscall_defs.h | 51 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 51 insertions(+) diff --git a/bsd-user/syscall_defs.h b/bsd-user/syscall_defs.h index 499a80f8bf..96ae90b063 100644 --- a/bsd-user/syscall_defs.h +++ b/bsd-user/syscall_defs.h @@ -339,6 +339,57 @@ struct target_statfs { char f_mntonname[1024]; /* directory on which mounted */ }; +/* File identifier. These are unique per filesystem on a single machine. */ +#define TARGET_MAXFIDSZ 16 + +struct target_freebsd_fid { + uint16_t fid_len; /* len of data in bytes */ + uint16_t fid_data0; /* force longword align */ + char fid_data[TARGET_MAXFIDSZ]; /* data (variable len) */ +}; + +/* Generic file handle */ +struct target_freebsd_fhandle { + target_freebsd_fsid_t fh_fsid; /* Filesystem id of mount point */ + struct target_freebsd_fid fh_fid; /* Filesys specific id */ +}; +typedef struct target_freebsd_fhandle target_freebsd_fhandle_t; + +/* + * sys/fcntl.h + */ +#define TARGET_F_DUPFD 0 +#define TARGET_F_GETFD 1 +#define TARGET_F_SETFD 2 +#define TARGET_F_GETFL 3 +#define TARGET_F_SETFL 4 +#define TARGET_F_GETOWN 5 +#define TARGET_F_SETOWN 6 +#define TARGET_F_OGETLK 7 +#define TARGET_F_OSETLK 8 +#define TARGET_F_OSETLKW 9 +#define TARGET_F_DUP2FD 10 +#define TARGET_F_GETLK 11 +#define TARGET_F_SETLK 12 +#define TARGET_F_SETLKW 13 +#define TARGET_F_SETLK_REMOTE 14 +#define TARGET_F_READAHEAD 15 +#define TARGET_F_RDAHEAD 16 +#define TARGET_F_DUPFD_CLOEXEC 17 +#define TARGET_F_DUP2FD_CLOEXEC 18 +/* FreeBSD-specific */ +#define TARGET_F_ADD_SEALS 19 +#define TARGET_F_GET_SEALS 20 + +struct target_freebsd_flock { + int64_t l_start; + int64_t l_len; + int32_t l_pid; + int16_t l_type; + int16_t l_whence; + int32_t l_sysid; +} QEMU_PACKED; + #define safe_syscall0(type, name) \ type safe_##name(void) \ { \ From 243c725fe7489b15aa441a20b0298035481da2f9 Mon Sep 17 00:00:00 2001 From: Kyle Evans Date: Sat, 19 Aug 2023 20:23:27 -0600 Subject: [PATCH 13/36] bsd-user: Define safe_fcntl macro in bsd-user/syscall_defs.h Signed-off-by: Kyle Evans Signed-off-by: Karim Taha Reviewed-by: Richard Henderson Signed-off-by: Warner Losh --- bsd-user/syscall_defs.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/bsd-user/syscall_defs.h b/bsd-user/syscall_defs.h index 96ae90b063..c6699c9943 100644 --- a/bsd-user/syscall_defs.h +++ b/bsd-user/syscall_defs.h @@ -437,6 +437,8 @@ type safe_##name(type1 arg1, type2 arg2, type3 arg3, type4 arg4, \ return safe_syscall(SYS_##name, arg1, arg2, arg3, arg4, arg5, arg6); \ } +#define safe_fcntl(...) safe_syscall(SYS_fcntl, __VA_ARGS__) + /* So far all target and host bitmasks are the same */ #undef target_to_host_bitmask #define target_to_host_bitmask(x, tbl) (x) From a0c20b1b36576042d1c2789f92b42043f48409c4 Mon Sep 17 00:00:00 2001 From: Warner Losh Date: Sun, 13 Aug 2023 10:41:32 +0200 Subject: [PATCH 14/36] bsd-user: Rename target_freebsd_time_t to target_time_t This is necessary for future code using target_time_t, in bsd-user/syscall_defs. Signed-off-by: Warner Losh Signed-off-by: Karim Taha Reviewed-by: Richard Henderson --- bsd-user/syscall_defs.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/bsd-user/syscall_defs.h b/bsd-user/syscall_defs.h index c6699c9943..9c90616baa 100644 --- a/bsd-user/syscall_defs.h +++ b/bsd-user/syscall_defs.h @@ -45,9 +45,9 @@ * */ #if (!defined(TARGET_I386)) -typedef int64_t target_freebsd_time_t; +typedef int64_t target_time_t; #else -typedef int32_t target_freebsd_time_t; +typedef int32_t target_time_t; #endif struct target_iovec { @@ -102,7 +102,7 @@ typedef abi_long target_freebsd_suseconds_t; /* compare to sys/timespec.h */ struct target_freebsd_timespec { - target_freebsd_time_t tv_sec; /* seconds */ + target_time_t tv_sec; /* seconds */ abi_long tv_nsec; /* and nanoseconds */ #if !defined(TARGET_I386) && TARGET_ABI_BITS == 32 abi_long _pad; @@ -120,7 +120,7 @@ struct target_freebsd__umtx_time { }; struct target_freebsd_timeval { - target_freebsd_time_t tv_sec; /* seconds */ + target_time_t tv_sec; /* seconds */ target_freebsd_suseconds_t tv_usec;/* and microseconds */ #if !defined(TARGET_I386) && TARGET_ABI_BITS == 32 abi_long _pad; From 86547e577bdfe55f32778a052b82227599233067 Mon Sep 17 00:00:00 2001 From: Stacey Son Date: Sun, 13 Aug 2023 10:41:33 +0200 Subject: [PATCH 15/36] bsd-user: Implement h2t_freebsd11_stat h2t_freebsd_nstat Implement the stat conversion functions: h2t_freebsd11_stat h2t_freebsd_nstat Signed-off-by: Stacey Son Signed-off-by: Karim Taha Reviewed-by: Richard Henderson Signed-off-by: Warner Losh --- bsd-user/freebsd/os-stat.c | 94 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 94 insertions(+) create mode 100644 bsd-user/freebsd/os-stat.c diff --git a/bsd-user/freebsd/os-stat.c b/bsd-user/freebsd/os-stat.c new file mode 100644 index 0000000000..8c73f7402c --- /dev/null +++ b/bsd-user/freebsd/os-stat.c @@ -0,0 +1,94 @@ +/* + * FreeBSD stat related conversion routines + * + * Copyright (c) 2013 Stacey D. Son + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see . + */ +#include "qemu/osdep.h" + +#include "qemu.h" + +/* + * stat conversion + */ +abi_long h2t_freebsd11_stat(abi_ulong target_addr, + struct freebsd11_stat *host_st) +{ + struct target_freebsd11_stat *target_st; + + if (!lock_user_struct(VERIFY_WRITE, target_st, target_addr, 0)) { + return -TARGET_EFAULT; + } + memset(target_st, 0, sizeof(*target_st)); + __put_user(host_st->st_dev, &target_st->st_dev); + __put_user(host_st->st_ino, &target_st->st_ino); + __put_user(host_st->st_mode, &target_st->st_mode); + __put_user(host_st->st_nlink, &target_st->st_nlink); + __put_user(host_st->st_uid, &target_st->st_uid); + __put_user(host_st->st_gid, &target_st->st_gid); + __put_user(host_st->st_rdev, &target_st->st_rdev); + __put_user(host_st->st_atim.tv_sec, &target_st->st_atim.tv_sec); + __put_user(host_st->st_atim.tv_nsec, &target_st->st_atim.tv_nsec); + __put_user(host_st->st_mtim.tv_sec, &target_st->st_mtim.tv_sec); + __put_user(host_st->st_mtim.tv_nsec, &target_st->st_mtim.tv_nsec); + __put_user(host_st->st_ctim.tv_sec, &target_st->st_ctim.tv_sec); + __put_user(host_st->st_ctim.tv_nsec, &target_st->st_ctim.tv_nsec); + __put_user(host_st->st_size, &target_st->st_size); + __put_user(host_st->st_blocks, &target_st->st_blocks); + __put_user(host_st->st_blksize, &target_st->st_blksize); + __put_user(host_st->st_flags, &target_st->st_flags); + __put_user(host_st->st_gen, &target_st->st_gen); + /* st_lspare not used */ + __put_user(host_st->st_birthtim.tv_sec, &target_st->st_birthtim.tv_sec); + __put_user(host_st->st_birthtim.tv_nsec, &target_st->st_birthtim.tv_nsec); + unlock_user_struct(target_st, target_addr, 1); + + return 0; +} + +abi_long h2t_freebsd11_nstat(abi_ulong target_addr, + struct freebsd11_stat *host_st) +{ + struct target_freebsd11_nstat *target_st; + + if (!lock_user_struct(VERIFY_WRITE, target_st, target_addr, 0)) { + return -TARGET_EFAULT; + } + memset(target_st, 0, sizeof(*target_st)); + __put_user(host_st->st_dev, &target_st->st_dev); + __put_user(host_st->st_ino, &target_st->st_ino); + __put_user(host_st->st_mode, &target_st->st_mode); + __put_user(host_st->st_nlink, &target_st->st_nlink); + __put_user(host_st->st_uid, &target_st->st_uid); + __put_user(host_st->st_gid, &target_st->st_gid); + __put_user(host_st->st_rdev, &target_st->st_rdev); + __put_user(host_st->st_atim.tv_sec, &target_st->st_atim.tv_sec); + __put_user(host_st->st_atim.tv_nsec, &target_st->st_atim.tv_nsec); + __put_user(host_st->st_mtim.tv_sec, &target_st->st_mtim.tv_sec); + __put_user(host_st->st_mtim.tv_nsec, &target_st->st_mtim.tv_nsec); + __put_user(host_st->st_ctim.tv_sec, &target_st->st_ctim.tv_sec); + __put_user(host_st->st_ctim.tv_nsec, &target_st->st_ctim.tv_nsec); + __put_user(host_st->st_size, &target_st->st_size); + __put_user(host_st->st_blocks, &target_st->st_blocks); + __put_user(host_st->st_blksize, &target_st->st_blksize); + __put_user(host_st->st_flags, &target_st->st_flags); + __put_user(host_st->st_gen, &target_st->st_gen); + __put_user(host_st->st_birthtim.tv_sec, &target_st->st_birthtim.tv_sec); + __put_user(host_st->st_birthtim.tv_nsec, &target_st->st_birthtim.tv_nsec); + unlock_user_struct(target_st, target_addr, 1); + + return 0; +} + From f2bc92aaf3d2944fd41073ed3bfb5addf9ee96e7 Mon Sep 17 00:00:00 2001 From: Stacey Son Date: Sun, 13 Aug 2023 10:41:34 +0200 Subject: [PATCH 16/36] bsd-user: Implement h2t_freebsd_fhandle t2h_freebsd_fhandle Implement the stat conversion functions: h2t_freebsd_fhandle t2h_freebsd_fhandle Signed-off-by: Stacey Son Signed-off-by: Karim Taha Reviewed-by: Richard Henderson Signed-off-by: Warner Losh --- bsd-user/freebsd/os-stat.c | 37 +++++++++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) diff --git a/bsd-user/freebsd/os-stat.c b/bsd-user/freebsd/os-stat.c index 8c73f7402c..6716cee3e2 100644 --- a/bsd-user/freebsd/os-stat.c +++ b/bsd-user/freebsd/os-stat.c @@ -92,3 +92,40 @@ abi_long h2t_freebsd11_nstat(abi_ulong target_addr, return 0; } +/* + * file handle conversion + */ +abi_long t2h_freebsd_fhandle(fhandle_t *host_fh, abi_ulong target_addr) +{ + target_freebsd_fhandle_t *target_fh; + + if (!lock_user_struct(VERIFY_READ, target_fh, target_addr, 1)) { + return -TARGET_EFAULT; + } + __get_user(host_fh->fh_fsid.val[0], &target_fh->fh_fsid.val[0]); + __get_user(host_fh->fh_fsid.val[1], &target_fh->fh_fsid.val[0]); + __get_user(host_fh->fh_fid.fid_len, &target_fh->fh_fid.fid_len); + /* u_short fid_data0; */ + memcpy(host_fh->fh_fid.fid_data, target_fh->fh_fid.fid_data, + TARGET_MAXFIDSZ); + unlock_user_struct(target_fh, target_addr, 0); + return 0; +} + +abi_long h2t_freebsd_fhandle(abi_ulong target_addr, fhandle_t *host_fh) +{ + target_freebsd_fhandle_t *target_fh; + + if (!lock_user_struct(VERIFY_WRITE, target_fh, target_addr, 0)) { + return -TARGET_EFAULT; + } + __put_user(host_fh->fh_fsid.val[0], &target_fh->fh_fsid.val[0]); + __put_user(host_fh->fh_fsid.val[1], &target_fh->fh_fsid.val[0]); + __put_user(host_fh->fh_fid.fid_len, &target_fh->fh_fid.fid_len); + /* u_short fid_data0; */ + memcpy(target_fh->fh_fid.fid_data, host_fh->fh_fid.fid_data, + TARGET_MAXFIDSZ); + unlock_user_struct(target_fh, target_addr, 1); + return 0; +} + From 5aa88f962cac2e93f222c48c92a14d685aaf00e7 Mon Sep 17 00:00:00 2001 From: Stacey Son Date: Sun, 13 Aug 2023 10:41:35 +0200 Subject: [PATCH 17/36] bsd-user: Implement h2t_freebds11_statfs Implement the stat conversion functions: h2t_freebds11_statfs Signed-off-by: Stacey Son Signed-off-by: Karim Taha Reviewed-by: Richard Henderson Signed-off-by: Warner Losh --- bsd-user/freebsd/os-stat.c | 41 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) diff --git a/bsd-user/freebsd/os-stat.c b/bsd-user/freebsd/os-stat.c index 6716cee3e2..9eb01bf664 100644 --- a/bsd-user/freebsd/os-stat.c +++ b/bsd-user/freebsd/os-stat.c @@ -129,3 +129,44 @@ abi_long h2t_freebsd_fhandle(abi_ulong target_addr, fhandle_t *host_fh) return 0; } +/* + * file system stat + */ +abi_long h2t_freebsd11_statfs(abi_ulong target_addr, + struct freebsd11_statfs *host_statfs) +{ + struct target_freebsd11_statfs *target_statfs; + + if (!lock_user_struct(VERIFY_WRITE, target_statfs, target_addr, 0)) { + return -TARGET_EFAULT; + } + __put_user(host_statfs->f_version, &target_statfs->f_version); + __put_user(host_statfs->f_type, &target_statfs->f_type); + __put_user(host_statfs->f_flags, &target_statfs->f_flags); + __put_user(host_statfs->f_bsize, &target_statfs->f_bsize); + __put_user(host_statfs->f_iosize, &target_statfs->f_iosize); + __put_user(host_statfs->f_blocks, &target_statfs->f_blocks); + __put_user(host_statfs->f_bfree, &target_statfs->f_bfree); + __put_user(host_statfs->f_bavail, &target_statfs->f_bavail); + __put_user(host_statfs->f_files, &target_statfs->f_files); + __put_user(host_statfs->f_ffree, &target_statfs->f_ffree); + __put_user(host_statfs->f_syncwrites, &target_statfs->f_syncwrites); + __put_user(host_statfs->f_asyncwrites, &target_statfs->f_asyncwrites); + __put_user(host_statfs->f_syncreads, &target_statfs->f_syncreads); + __put_user(host_statfs->f_asyncreads, &target_statfs->f_asyncreads); + /* uint64_t f_spare[10]; */ + __put_user(host_statfs->f_namemax, &target_statfs->f_namemax); + __put_user(host_statfs->f_owner, &target_statfs->f_owner); + __put_user(host_statfs->f_fsid.val[0], &target_statfs->f_fsid.val[0]); + __put_user(host_statfs->f_fsid.val[1], &target_statfs->f_fsid.val[1]); + /* char f_charspace[80]; */ + strncpy(target_statfs->f_fstypename, host_statfs->f_fstypename, + sizeof(target_statfs->f_fstypename)); + strncpy(target_statfs->f_mntfromname, host_statfs->f_mntfromname, + sizeof(target_statfs->f_mntfromname)); + strncpy(target_statfs->f_mntonname, host_statfs->f_mntonname, + sizeof(target_statfs->f_mntonname)); + unlock_user_struct(target_statfs, target_addr, 1); + return 0; +} + From 584d6fce65bd80335795d80c0e9bf1062ef3c4f6 Mon Sep 17 00:00:00 2001 From: Stacey Son Date: Sun, 13 Aug 2023 10:41:36 +0200 Subject: [PATCH 18/36] bsd-user: Implement target_to_host_fcntl_cmd Implement the stat conversion functions: target_to_host_fcntl_cmd Signed-off-by: Stacey Son Signed-off-by: Karim Taha Reviewed-by: Richard Henderson Signed-off-by: Warner Losh --- bsd-user/freebsd/os-stat.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/bsd-user/freebsd/os-stat.c b/bsd-user/freebsd/os-stat.c index 9eb01bf664..2ce235d5da 100644 --- a/bsd-user/freebsd/os-stat.c +++ b/bsd-user/freebsd/os-stat.c @@ -170,3 +170,11 @@ abi_long h2t_freebsd11_statfs(abi_ulong target_addr, return 0; } +/* + * fcntl cmd conversion + */ +abi_long target_to_host_fcntl_cmd(int cmd) +{ + return cmd; +} + From f9d5a35fbbfeb534e748fc79df7f3f85b83c695a Mon Sep 17 00:00:00 2001 From: Michal Meloun Date: Sun, 13 Aug 2023 10:41:37 +0200 Subject: [PATCH 19/36] bsd-uesr: Implement h2t_freebsd_stat and h2t_freebsd_statfs functions They are the 64-bit variants of h2t_freebsd11_stat and h2t_freebsd11_statfs, respectively Signed-off-by: Michal Meloun Signed-off-by: Karim Taha Reviewed-by: Richard Henderson Signed-off-by: Warner Losh --- bsd-user/freebsd/os-stat.c | 82 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 82 insertions(+) diff --git a/bsd-user/freebsd/os-stat.c b/bsd-user/freebsd/os-stat.c index 2ce235d5da..f0f9e609c3 100644 --- a/bsd-user/freebsd/os-stat.c +++ b/bsd-user/freebsd/os-stat.c @@ -58,6 +58,50 @@ abi_long h2t_freebsd11_stat(abi_ulong target_addr, return 0; } +abi_long h2t_freebsd_stat(abi_ulong target_addr, + struct stat *host_st) +{ + struct target_stat *target_st; + + if (!lock_user_struct(VERIFY_WRITE, target_st, target_addr, 0)) { + return -TARGET_EFAULT; + } + memset(target_st, 0, sizeof(*target_st)); + __put_user(host_st->st_dev, &target_st->st_dev); + __put_user(host_st->st_ino, &target_st->st_ino); + __put_user(host_st->st_nlink, &target_st->st_nlink); + __put_user(host_st->st_mode, &target_st->st_mode); + __put_user(host_st->st_uid, &target_st->st_uid); + __put_user(host_st->st_gid, &target_st->st_gid); + __put_user(host_st->st_rdev, &target_st->st_rdev); + __put_user(host_st->st_atim.tv_sec, &target_st->st_atim.tv_sec); + __put_user(host_st->st_atim.tv_nsec, &target_st->st_atim.tv_nsec); +#ifdef TARGET_HAS_STAT_TIME_T_EXT +/* __put_user(host_st->st_mtim_ext, &target_st->st_mtim_ext); XXX */ +#endif + __put_user(host_st->st_mtim.tv_sec, &target_st->st_mtim.tv_sec); + __put_user(host_st->st_mtim.tv_nsec, &target_st->st_mtim.tv_nsec); +#ifdef TARGET_HAS_STAT_TIME_T_EXT +/* __put_user(host_st->st_ctim_ext, &target_st->st_ctim_ext); XXX */ +#endif + __put_user(host_st->st_ctim.tv_sec, &target_st->st_ctim.tv_sec); + __put_user(host_st->st_ctim.tv_nsec, &target_st->st_ctim.tv_nsec); +#ifdef TARGET_HAS_STAT_TIME_T_EXT +/* __put_user(host_st->st_birthtim_ext, &target_st->st_birthtim_ext); XXX */ +#endif + __put_user(host_st->st_birthtim.tv_sec, &target_st->st_birthtim.tv_sec); + __put_user(host_st->st_birthtim.tv_nsec, &target_st->st_birthtim.tv_nsec); + + __put_user(host_st->st_size, &target_st->st_size); + __put_user(host_st->st_blocks, &target_st->st_blocks); + __put_user(host_st->st_blksize, &target_st->st_blksize); + __put_user(host_st->st_flags, &target_st->st_flags); + __put_user(host_st->st_gen, &target_st->st_gen); + unlock_user_struct(target_st, target_addr, 1); + + return 0; +} + abi_long h2t_freebsd11_nstat(abi_ulong target_addr, struct freebsd11_stat *host_st) { @@ -170,6 +214,44 @@ abi_long h2t_freebsd11_statfs(abi_ulong target_addr, return 0; } +abi_long h2t_freebsd_statfs(abi_ulong target_addr, + struct statfs *host_statfs) +{ + struct target_statfs *target_statfs; + + if (!lock_user_struct(VERIFY_WRITE, target_statfs, target_addr, 0)) { + return -TARGET_EFAULT; + } + __put_user(host_statfs->f_version, &target_statfs->f_version); + __put_user(host_statfs->f_type, &target_statfs->f_type); + __put_user(host_statfs->f_flags, &target_statfs->f_flags); + __put_user(host_statfs->f_bsize, &target_statfs->f_bsize); + __put_user(host_statfs->f_iosize, &target_statfs->f_iosize); + __put_user(host_statfs->f_blocks, &target_statfs->f_blocks); + __put_user(host_statfs->f_bfree, &target_statfs->f_bfree); + __put_user(host_statfs->f_bavail, &target_statfs->f_bavail); + __put_user(host_statfs->f_files, &target_statfs->f_files); + __put_user(host_statfs->f_ffree, &target_statfs->f_ffree); + __put_user(host_statfs->f_syncwrites, &target_statfs->f_syncwrites); + __put_user(host_statfs->f_asyncwrites, &target_statfs->f_asyncwrites); + __put_user(host_statfs->f_syncreads, &target_statfs->f_syncreads); + __put_user(host_statfs->f_asyncreads, &target_statfs->f_asyncreads); + /* uint64_t f_spare[10]; */ + __put_user(host_statfs->f_namemax, &target_statfs->f_namemax); + __put_user(host_statfs->f_owner, &target_statfs->f_owner); + __put_user(host_statfs->f_fsid.val[0], &target_statfs->f_fsid.val[0]); + __put_user(host_statfs->f_fsid.val[1], &target_statfs->f_fsid.val[1]); + /* char f_charspace[80]; */ + strncpy(target_statfs->f_fstypename, host_statfs->f_fstypename, + sizeof(target_statfs->f_fstypename)); + strncpy(target_statfs->f_mntfromname, host_statfs->f_mntfromname, + sizeof(target_statfs->f_mntfromname)); + strncpy(target_statfs->f_mntonname, host_statfs->f_mntonname, + sizeof(target_statfs->f_mntonname)); + unlock_user_struct(target_statfs, target_addr, 1); + return 0; +} + /* * fcntl cmd conversion */ From bf14f13d8be8f572fa169a866d3244fa4a1988ac Mon Sep 17 00:00:00 2001 From: Stacey Son Date: Sun, 13 Aug 2023 10:41:38 +0200 Subject: [PATCH 20/36] bsd-user: Implement stat related syscalls Implement the following syscalls: stat(2) lstat(2) fstat(2) fstatat(2) nstat nfstat nlstat Signed-off-by: Stacey Son Signed-off-by: Karim Taha Reviewed-by: Richard Henderson Signed-off-by: Warner Losh --- bsd-user/freebsd/os-stat.h | 130 +++++++++++++++++++++++++++++++++++++ 1 file changed, 130 insertions(+) create mode 100644 bsd-user/freebsd/os-stat.h diff --git a/bsd-user/freebsd/os-stat.h b/bsd-user/freebsd/os-stat.h new file mode 100644 index 0000000000..f8f99b4a72 --- /dev/null +++ b/bsd-user/freebsd/os-stat.h @@ -0,0 +1,130 @@ +/* + * stat related system call shims and definitions + * + * Copyright (c) 2013 Stacey D. Son + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see . + */ + +#ifndef BSD_USER_FREEBSD_OS_STAT_H +#define BSD_USER_FREEBSD_OS_STAT_H + +/* stat(2) */ +static inline abi_long do_freebsd11_stat(abi_long arg1, abi_long arg2) +{ + abi_long ret; + void *p; + struct freebsd11_stat st; + + LOCK_PATH(p, arg1); + ret = get_errno(freebsd11_stat(path(p), &st)); + UNLOCK_PATH(p, arg1); + if (!is_error(ret)) { + ret = h2t_freebsd11_stat(arg2, &st); + } + return ret; +} + +/* lstat(2) */ +static inline abi_long do_freebsd11_lstat(abi_long arg1, abi_long arg2) +{ + abi_long ret; + void *p; + struct freebsd11_stat st; + + LOCK_PATH(p, arg1); + ret = get_errno(freebsd11_lstat(path(p), &st)); + UNLOCK_PATH(p, arg1); + if (!is_error(ret)) { + ret = h2t_freebsd11_stat(arg2, &st); + } + return ret; +} + +/* fstat(2) */ +static inline abi_long do_freebsd_fstat(abi_long arg1, abi_long arg2) +{ + abi_long ret; + struct stat st; + + ret = get_errno(fstat(arg1, &st)); + if (!is_error(ret)) { + ret = h2t_freebsd_stat(arg2, &st); + } + return ret; +} + +/* fstatat(2) */ +static inline abi_long do_freebsd_fstatat(abi_long arg1, abi_long arg2, + abi_long arg3, abi_long arg4) +{ + abi_long ret; + void *p; + struct stat st; + + LOCK_PATH(p, arg2); + ret = get_errno(fstatat(arg1, p, &st, arg4)); + UNLOCK_PATH(p, arg2); + if (!is_error(ret) && arg3) { + ret = h2t_freebsd_stat(arg3, &st); + } + return ret; +} + +/* undocummented nstat(char *path, struct nstat *ub) syscall */ +static abi_long do_freebsd11_nstat(abi_long arg1, abi_long arg2) +{ + abi_long ret; + void *p; + struct freebsd11_stat st; + + LOCK_PATH(p, arg1); + ret = get_errno(freebsd11_nstat(path(p), &st)); + UNLOCK_PATH(p, arg1); + if (!is_error(ret)) { + ret = h2t_freebsd11_nstat(arg2, &st); + } + return ret; +} + +/* undocummented nfstat(int fd, struct nstat *sb) syscall */ +static abi_long do_freebsd11_nfstat(abi_long arg1, abi_long arg2) +{ + abi_long ret; + struct freebsd11_stat st; + + ret = get_errno(freebsd11_nfstat(arg1, &st)); + if (!is_error(ret)) { + ret = h2t_freebsd11_nstat(arg2, &st); + } + return ret; +} + +/* undocummented nlstat(char *path, struct nstat *ub) syscall */ +static abi_long do_freebsd11_nlstat(abi_long arg1, abi_long arg2) +{ + abi_long ret; + void *p; + struct freebsd11_stat st; + + LOCK_PATH(p, arg1); + ret = get_errno(freebsd11_nlstat(path(p), &st)); + UNLOCK_PATH(p, arg1); + if (!is_error(ret)) { + ret = h2t_freebsd11_nstat(arg2, &st); + } + return ret; +} + +#endif /* BSD_USER_FREEBSD_OS_STAT_H */ From db8ee08f0a88ae04ee6b684690a3d53f862e7ea3 Mon Sep 17 00:00:00 2001 From: Stacey Son Date: Sun, 13 Aug 2023 10:41:39 +0200 Subject: [PATCH 21/36] bsd-user: Implement statfh related syscalls Implement the following syscalls: getfh(2) lgetfh(2) fhopen(2) fhstat(2) fhstatfs(2) Signed-off-by: Stacey Son Signed-off-by: Karim Taha Reviewed-by: Richard Henderson Signed-off-by: Warner Losh --- bsd-user/freebsd/os-stat.h | 83 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 83 insertions(+) diff --git a/bsd-user/freebsd/os-stat.h b/bsd-user/freebsd/os-stat.h index f8f99b4a72..935663c071 100644 --- a/bsd-user/freebsd/os-stat.h +++ b/bsd-user/freebsd/os-stat.h @@ -127,4 +127,87 @@ static abi_long do_freebsd11_nlstat(abi_long arg1, abi_long arg2) return ret; } +/* getfh(2) */ +static abi_long do_freebsd_getfh(abi_long arg1, abi_long arg2) +{ + abi_long ret; + void *p; + fhandle_t host_fh; + + LOCK_PATH(p, arg1); + ret = get_errno(getfh(path(p), &host_fh)); + UNLOCK_PATH(p, arg1); + if (is_error(ret)) { + return ret; + } + return h2t_freebsd_fhandle(arg2, &host_fh); +} + +/* lgetfh(2) */ +static inline abi_long do_freebsd_lgetfh(abi_long arg1, abi_long arg2) +{ + abi_long ret; + void *p; + fhandle_t host_fh; + + LOCK_PATH(p, arg1); + ret = get_errno(lgetfh(path(p), &host_fh)); + UNLOCK_PATH(p, arg1); + if (is_error(ret)) { + return ret; + } + return h2t_freebsd_fhandle(arg2, &host_fh); +} + +/* fhopen(2) */ +static inline abi_long do_freebsd_fhopen(abi_long arg1, abi_long arg2) +{ + abi_long ret; + fhandle_t host_fh; + + ret = t2h_freebsd_fhandle(&host_fh, arg1); + if (is_error(ret)) { + return ret; + } + + return get_errno(fhopen(&host_fh, arg2)); +} + +/* fhstat(2) */ +static inline abi_long do_freebsd_fhstat(abi_long arg1, abi_long arg2) +{ + abi_long ret; + fhandle_t host_fh; + struct stat host_sb; + + ret = t2h_freebsd_fhandle(&host_fh, arg1); + if (is_error(ret)) { + return ret; + } + ret = get_errno(fhstat(&host_fh, &host_sb)); + if (is_error(ret)) { + return ret; + } + return h2t_freebsd_stat(arg2, &host_sb); +} + +/* fhstatfs(2) */ +static inline abi_long do_freebsd_fhstatfs(abi_ulong target_fhp_addr, + abi_ulong target_stfs_addr) +{ + abi_long ret; + fhandle_t host_fh; + struct statfs host_stfs; + + ret = t2h_freebsd_fhandle(&host_fh, target_fhp_addr); + if (is_error(ret)) { + return ret; + } + ret = get_errno(fhstatfs(&host_fh, &host_stfs)); + if (is_error(ret)) { + return ret; + } + return h2t_freebsd_statfs(target_stfs_addr, &host_stfs); +} + #endif /* BSD_USER_FREEBSD_OS_STAT_H */ From 191fe50d5dc8f26e0049d62e92d192d410520fab Mon Sep 17 00:00:00 2001 From: Stacey Son Date: Sun, 13 Aug 2023 10:41:40 +0200 Subject: [PATCH 22/36] bsd-user: Implement statfs related syscalls Implement the following syscalls: statfs(2) fstatfs(2) getfsstat(2) Signed-off-by: Stacey Son Signed-off-by: Karim Taha Reviewed-by: Richard Henderson Signed-off-by: Warner Losh --- bsd-user/freebsd/os-stat.h | 69 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 69 insertions(+) diff --git a/bsd-user/freebsd/os-stat.h b/bsd-user/freebsd/os-stat.h index 935663c071..9492c93c55 100644 --- a/bsd-user/freebsd/os-stat.h +++ b/bsd-user/freebsd/os-stat.h @@ -210,4 +210,73 @@ static inline abi_long do_freebsd_fhstatfs(abi_ulong target_fhp_addr, return h2t_freebsd_statfs(target_stfs_addr, &host_stfs); } +/* statfs(2) */ +static inline abi_long do_freebsd_statfs(abi_long arg1, abi_long arg2) +{ + abi_long ret; + void *p; + struct statfs host_stfs; + + LOCK_PATH(p, arg1); + ret = get_errno(statfs(path(p), &host_stfs)); + UNLOCK_PATH(p, arg1); + if (is_error(ret)) { + return ret; + } + + return h2t_freebsd_statfs(arg2, &host_stfs); +} + +/* fstatfs(2) */ +static inline abi_long do_freebsd_fstatfs(abi_long fd, abi_ulong target_addr) +{ + abi_long ret; + struct statfs host_stfs; + + ret = get_errno(fstatfs(fd, &host_stfs)); + if (is_error(ret)) { + return ret; + } + + return h2t_freebsd_statfs(target_addr, &host_stfs); +} + +/* getfsstat(2) */ +static inline abi_long do_freebsd_getfsstat(abi_ulong target_addr, + abi_long bufsize, abi_long flags) +{ + abi_long ret; + struct statfs *host_stfs; + int count; + long host_bufsize; + + count = bufsize / sizeof(struct target_statfs); + + /* if user buffer is NULL then return number of mounted FS's */ + if (target_addr == 0 || count == 0) { + return get_errno(freebsd11_getfsstat(NULL, 0, flags)); + } + + /* XXX check count to be reasonable */ + host_bufsize = sizeof(struct statfs) * count; + host_stfs = alloca(host_bufsize); + if (!host_stfs) { + return -TARGET_EINVAL; + } + + ret = count = get_errno(getfsstat(host_stfs, host_bufsize, flags)); + if (is_error(ret)) { + return ret; + } + + while (count--) { + if (h2t_freebsd_statfs((target_addr + + (count * sizeof(struct target_statfs))), + &host_stfs[count])) { + return -TARGET_EFAULT; + } + } + return ret; +} + #endif /* BSD_USER_FREEBSD_OS_STAT_H */ From 213444529de083d1cbd1ef2391a1323207182f93 Mon Sep 17 00:00:00 2001 From: Stacey Son Date: Sun, 13 Aug 2023 10:41:41 +0200 Subject: [PATCH 23/36] bsd-user: Implement getdents related syscalls Implement the following syscalls: getdents(2) getdirecentries(2) Signed-off-by: Stacey Son Signed-off-by: Karim Taha Reviewed-by: Richard Henderson Signed-off-by: Warner Losh --- bsd-user/freebsd/os-stat.h | 72 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 72 insertions(+) diff --git a/bsd-user/freebsd/os-stat.h b/bsd-user/freebsd/os-stat.h index 9492c93c55..7dc41cd0bf 100644 --- a/bsd-user/freebsd/os-stat.h +++ b/bsd-user/freebsd/os-stat.h @@ -279,4 +279,76 @@ static inline abi_long do_freebsd_getfsstat(abi_ulong target_addr, return ret; } +/* getdents(2) */ +static inline abi_long do_freebsd11_getdents(abi_long arg1, + abi_ulong arg2, abi_long nbytes) +{ + abi_long ret; + struct freebsd11_dirent *dirp; + + dirp = lock_user(VERIFY_WRITE, arg2, nbytes, 0); + if (dirp == NULL) { + return -TARGET_EFAULT; + } + ret = get_errno(freebsd11_getdents(arg1, (char *)dirp, nbytes)); + if (!is_error(ret)) { + struct freebsd11_dirent *de; + int len = ret; + int reclen; + + de = dirp; + while (len > 0) { + reclen = de->d_reclen; + if (reclen > len) { + return -TARGET_EFAULT; + } + de->d_reclen = tswap16(reclen); + de->d_fileno = tswap32(de->d_fileno); + len -= reclen; + } + } + return ret; +} + +/* getdirecentries(2) */ +static inline abi_long do_freebsd_getdirentries(abi_long arg1, + abi_ulong arg2, abi_long nbytes, abi_ulong arg4) +{ + abi_long ret; + struct dirent *dirp; + long basep; + + dirp = lock_user(VERIFY_WRITE, arg2, nbytes, 0); + if (dirp == NULL) { + return -TARGET_EFAULT; + } + ret = get_errno(getdirentries(arg1, (char *)dirp, nbytes, &basep)); + if (!is_error(ret)) { + struct dirent *de; + int len = ret; + int reclen; + + de = dirp; + while (len > 0) { + reclen = de->d_reclen; + if (reclen > len) { + return -TARGET_EFAULT; + } + de->d_fileno = tswap64(de->d_fileno); + de->d_off = tswap64(de->d_off); + de->d_reclen = tswap16(de->d_reclen); + de->d_namlen = tswap16(de->d_namlen); + len -= reclen; + de = (struct dirent *)((void *)de + reclen); + } + } + unlock_user(dirp, arg2, ret); + if (arg4) { + if (put_user(basep, arg4, abi_ulong)) { + return -TARGET_EFAULT; + } + } + return ret; +} + #endif /* BSD_USER_FREEBSD_OS_STAT_H */ From c0023204cb05f330c51432fdcae8929413ff6d73 Mon Sep 17 00:00:00 2001 From: Stacey Son Date: Sun, 13 Aug 2023 10:41:42 +0200 Subject: [PATCH 24/36] bsd-user: Implement stat related syscalls Implement the following syscalls: fcntl(2) Signed-off-by: Stacey Son Signed-off-by: Karim Taha Reviewed-by: Richard Henderson Signed-off-by: Warner Losh --- bsd-user/freebsd/os-stat.h | 74 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 74 insertions(+) diff --git a/bsd-user/freebsd/os-stat.h b/bsd-user/freebsd/os-stat.h index 7dc41cd0bf..5d9323c7d1 100644 --- a/bsd-user/freebsd/os-stat.h +++ b/bsd-user/freebsd/os-stat.h @@ -351,4 +351,78 @@ static inline abi_long do_freebsd_getdirentries(abi_long arg1, return ret; } +/* fcntl(2) */ +static inline abi_long do_freebsd_fcntl(abi_long arg1, abi_long arg2, + abi_ulong arg3) +{ + abi_long ret; + int host_cmd; + struct flock fl; + struct target_freebsd_flock *target_fl; + + host_cmd = target_to_host_fcntl_cmd(arg2); + if (host_cmd < 0) { + return host_cmd; + } + switch (arg2) { + case TARGET_F_GETLK: + if (!lock_user_struct(VERIFY_READ, target_fl, arg3, 1)) { + return -TARGET_EFAULT; + } + __get_user(fl.l_type, &target_fl->l_type); + __get_user(fl.l_whence, &target_fl->l_whence); + __get_user(fl.l_start, &target_fl->l_start); + __get_user(fl.l_len, &target_fl->l_len); + __get_user(fl.l_pid, &target_fl->l_pid); + __get_user(fl.l_sysid, &target_fl->l_sysid); + unlock_user_struct(target_fl, arg3, 0); + ret = get_errno(safe_fcntl(arg1, host_cmd, &fl)); + if (!is_error(ret)) { + if (!lock_user_struct(VERIFY_WRITE, target_fl, arg3, 0)) { + return -TARGET_EFAULT; + } + __put_user(fl.l_type, &target_fl->l_type); + __put_user(fl.l_whence, &target_fl->l_whence); + __put_user(fl.l_start, &target_fl->l_start); + __put_user(fl.l_len, &target_fl->l_len); + __put_user(fl.l_pid, &target_fl->l_pid); + __put_user(fl.l_sysid, &target_fl->l_sysid); + unlock_user_struct(target_fl, arg3, 1); + } + break; + + case TARGET_F_SETLK: + case TARGET_F_SETLKW: + if (!lock_user_struct(VERIFY_READ, target_fl, arg3, 1)) { + return -TARGET_EFAULT; + } + __get_user(fl.l_type, &target_fl->l_type); + __get_user(fl.l_whence, &target_fl->l_whence); + __get_user(fl.l_start, &target_fl->l_start); + __get_user(fl.l_len, &target_fl->l_len); + __get_user(fl.l_pid, &target_fl->l_pid); + __get_user(fl.l_sysid, &target_fl->l_sysid); + unlock_user_struct(target_fl, arg3, 0); + ret = get_errno(safe_fcntl(arg1, host_cmd, &fl)); + break; + + case TARGET_F_DUPFD: + case TARGET_F_DUP2FD: + case TARGET_F_GETOWN: + case TARGET_F_SETOWN: + case TARGET_F_GETFD: + case TARGET_F_SETFD: + case TARGET_F_GETFL: + case TARGET_F_SETFL: + case TARGET_F_READAHEAD: + case TARGET_F_RDAHEAD: + case TARGET_F_ADD_SEALS: + case TARGET_F_GET_SEALS: + default: + ret = get_errno(safe_fcntl(arg1, host_cmd, arg3)); + break; + } + return ret; +} + #endif /* BSD_USER_FREEBSD_OS_STAT_H */ From b443297793ef696f282e470775dc89815758fb24 Mon Sep 17 00:00:00 2001 From: Michal Meloun Date: Sun, 13 Aug 2023 10:41:43 +0200 Subject: [PATCH 25/36] bsd-user: Implement freebsd11 stat related syscalls Rename the following syscalls to the freebsd11 variant: do_freebsd_lstat -> do_freebsd11_lstat do_freebsd_stat -> do_freebsd11_stat Co-authored-by: Stacey Son Signed-off-by: Stacey Son Signed-off-by: Michal Meloun Signed-off-by: Karim Taha Reviewed-by: Richard Henderson Signed-off-by: Warner Losh --- bsd-user/freebsd/os-stat.h | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/bsd-user/freebsd/os-stat.h b/bsd-user/freebsd/os-stat.h index 5d9323c7d1..aef55c8bb5 100644 --- a/bsd-user/freebsd/os-stat.h +++ b/bsd-user/freebsd/os-stat.h @@ -20,6 +20,11 @@ #ifndef BSD_USER_FREEBSD_OS_STAT_H #define BSD_USER_FREEBSD_OS_STAT_H +int freebsd11_stat(const char *path, struct freebsd11_stat *stat); +__sym_compat(stat, freebsd11_stat, FBSD_1.0); +int freebsd11_lstat(const char *path, struct freebsd11_stat *stat); +__sym_compat(lstat, freebsd11_lstat, FBSD_1.0); + /* stat(2) */ static inline abi_long do_freebsd11_stat(abi_long arg1, abi_long arg2) { From 33d730684efbe9f9343a07a6f4259e322d22f63e Mon Sep 17 00:00:00 2001 From: Michal Meloun Date: Sun, 13 Aug 2023 10:41:44 +0200 Subject: [PATCH 26/36] bsd-user: Implement freebsd11 fstat and fhstat related syscalls Implement the freebsd11 variant of the following syscalls: fstat(2) fstatat(2) fhstat(2) fhstatfs(2) Co-authored-by: Stacey Son Signed-off-by: Stacey Son Signed-off-by: Michal Meloun Signed-off-by: Karim Taha Reviewed-by: Richard Henderson Signed-off-by: Warner Losh --- bsd-user/freebsd/os-stat.h | 78 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 78 insertions(+) diff --git a/bsd-user/freebsd/os-stat.h b/bsd-user/freebsd/os-stat.h index aef55c8bb5..2e0c7245df 100644 --- a/bsd-user/freebsd/os-stat.h +++ b/bsd-user/freebsd/os-stat.h @@ -24,6 +24,17 @@ int freebsd11_stat(const char *path, struct freebsd11_stat *stat); __sym_compat(stat, freebsd11_stat, FBSD_1.0); int freebsd11_lstat(const char *path, struct freebsd11_stat *stat); __sym_compat(lstat, freebsd11_lstat, FBSD_1.0); +int freebsd11_fstat(int fd, struct freebsd11_stat *stat); +__sym_compat(fstat, freebsd11_fstat, FBSD_1.0); +int freebsd11_fstatat(int fd, const char *path, struct freebsd11_stat *stat, + int flag); +__sym_compat(fstatat, freebsd11_fstatat, FBSD_1.1); + +int freebsd11_fhstat(const fhandle_t *fhandle, struct freebsd11_stat *stat); +__sym_compat(fhstat, freebsd11_fhstat, FBSD_1.0); +int freebsd11_fhstatfs(const fhandle_t *fhandle, struct freebsd11_statfs * buf); +__sym_compat(fhstatfs, freebsd11_fhstatfs, FBSD_1.0); +int freebsd11_statfs(const char *path, struct freebsd11_statfs *buf); /* stat(2) */ static inline abi_long do_freebsd11_stat(abi_long arg1, abi_long arg2) @@ -57,6 +68,19 @@ static inline abi_long do_freebsd11_lstat(abi_long arg1, abi_long arg2) return ret; } +/* fstat(2) */ +static inline abi_long do_freebsd11_fstat(abi_long arg1, abi_long arg2) +{ + abi_long ret; + struct freebsd11_stat st; + + ret = get_errno(freebsd11_fstat(arg1, &st)); + if (!is_error(ret)) { + ret = h2t_freebsd11_stat(arg2, &st); + } + return ret; +} + /* fstat(2) */ static inline abi_long do_freebsd_fstat(abi_long arg1, abi_long arg2) { @@ -70,6 +94,23 @@ static inline abi_long do_freebsd_fstat(abi_long arg1, abi_long arg2) return ret; } +/* fstatat(2) */ +static inline abi_long do_freebsd11_fstatat(abi_long arg1, abi_long arg2, + abi_long arg3, abi_long arg4) +{ + abi_long ret; + void *p; + struct freebsd11_stat st; + + LOCK_PATH(p, arg2); + ret = get_errno(freebsd11_fstatat(arg1, p, &st, arg4)); + UNLOCK_PATH(p, arg2); + if (!is_error(ret) && arg3) { + ret = h2t_freebsd11_stat(arg3, &st); + } + return ret; +} + /* fstatat(2) */ static inline abi_long do_freebsd_fstatat(abi_long arg1, abi_long arg2, abi_long arg3, abi_long arg4) @@ -178,6 +219,24 @@ static inline abi_long do_freebsd_fhopen(abi_long arg1, abi_long arg2) return get_errno(fhopen(&host_fh, arg2)); } +/* fhstat(2) */ +static inline abi_long do_freebsd11_fhstat(abi_long arg1, abi_long arg2) +{ + abi_long ret; + fhandle_t host_fh; + struct freebsd11_stat host_sb; + + ret = t2h_freebsd_fhandle(&host_fh, arg1); + if (is_error(ret)) { + return ret; + } + ret = get_errno(freebsd11_fhstat(&host_fh, &host_sb)); + if (is_error(ret)) { + return ret; + } + return h2t_freebsd11_stat(arg2, &host_sb); +} + /* fhstat(2) */ static inline abi_long do_freebsd_fhstat(abi_long arg1, abi_long arg2) { @@ -196,6 +255,25 @@ static inline abi_long do_freebsd_fhstat(abi_long arg1, abi_long arg2) return h2t_freebsd_stat(arg2, &host_sb); } +/* fhstatfs(2) */ +static inline abi_long do_freebsd11_fhstatfs(abi_ulong target_fhp_addr, + abi_ulong target_stfs_addr) +{ + abi_long ret; + fhandle_t host_fh; + struct freebsd11_statfs host_stfs; + + ret = t2h_freebsd_fhandle(&host_fh, target_fhp_addr); + if (is_error(ret)) { + return ret; + } + ret = get_errno(freebsd11_fhstatfs(&host_fh, &host_stfs)); + if (is_error(ret)) { + return ret; + } + return h2t_freebsd11_statfs(target_stfs_addr, &host_stfs); +} + /* fhstatfs(2) */ static inline abi_long do_freebsd_fhstatfs(abi_ulong target_fhp_addr, abi_ulong target_stfs_addr) From 196da9d3d3f1ab142473a6b2f714720ba1b29a33 Mon Sep 17 00:00:00 2001 From: Michal Meloun Date: Sun, 13 Aug 2023 10:41:45 +0200 Subject: [PATCH 27/36] bsd-user: Implement freebsd11 statfs related syscalls Implement the freebsd11 variant of the following syscalls: statfs(2) fstatfs(2) getfsstat(2) Co-authored-by: Stacey Son Signed-off-by: Stacey Son Signed-off-by: Michal Meloun Signed-off-by: Karim Taha Reviewed-by: Richard Henderson Signed-off-by: Warner Losh --- bsd-user/freebsd/os-stat.h | 75 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 75 insertions(+) diff --git a/bsd-user/freebsd/os-stat.h b/bsd-user/freebsd/os-stat.h index 2e0c7245df..04a61fabd1 100644 --- a/bsd-user/freebsd/os-stat.h +++ b/bsd-user/freebsd/os-stat.h @@ -32,9 +32,15 @@ __sym_compat(fstatat, freebsd11_fstatat, FBSD_1.1); int freebsd11_fhstat(const fhandle_t *fhandle, struct freebsd11_stat *stat); __sym_compat(fhstat, freebsd11_fhstat, FBSD_1.0); +int freebsd11_getfsstat(struct freebsd11_statfs *buf, long bufsize, int mode); +__sym_compat(getfsstat, freebsd11_getfsstat, FBSD_1.0); int freebsd11_fhstatfs(const fhandle_t *fhandle, struct freebsd11_statfs * buf); __sym_compat(fhstatfs, freebsd11_fhstatfs, FBSD_1.0); int freebsd11_statfs(const char *path, struct freebsd11_statfs *buf); +__sym_compat(statfs, freebsd11_statfs, FBSD_1.0); +int freebsd11_fstatfs(int fd, struct freebsd11_statfs *buf); +__sym_compat(fstatfs, freebsd11_fstatfs, FBSD_1.0); + /* stat(2) */ static inline abi_long do_freebsd11_stat(abi_long arg1, abi_long arg2) @@ -293,6 +299,23 @@ static inline abi_long do_freebsd_fhstatfs(abi_ulong target_fhp_addr, return h2t_freebsd_statfs(target_stfs_addr, &host_stfs); } +/* statfs(2) */ +static inline abi_long do_freebsd11_statfs(abi_long arg1, abi_long arg2) +{ + abi_long ret; + void *p; + struct freebsd11_statfs host_stfs; + + LOCK_PATH(p, arg1); + ret = get_errno(freebsd11_statfs(path(p), &host_stfs)); + UNLOCK_PATH(p, arg1); + if (is_error(ret)) { + return ret; + } + + return h2t_freebsd11_statfs(arg2, &host_stfs); +} + /* statfs(2) */ static inline abi_long do_freebsd_statfs(abi_long arg1, abi_long arg2) { @@ -310,6 +333,20 @@ static inline abi_long do_freebsd_statfs(abi_long arg1, abi_long arg2) return h2t_freebsd_statfs(arg2, &host_stfs); } +/* fstatfs(2) */ +static inline abi_long do_freebsd11_fstatfs(abi_long fd, abi_ulong target_addr) +{ + abi_long ret; + struct freebsd11_statfs host_stfs; + + ret = get_errno(freebsd11_fstatfs(fd, &host_stfs)); + if (is_error(ret)) { + return ret; + } + + return h2t_freebsd11_statfs(target_addr, &host_stfs); +} + /* fstatfs(2) */ static inline abi_long do_freebsd_fstatfs(abi_long fd, abi_ulong target_addr) { @@ -324,6 +361,44 @@ static inline abi_long do_freebsd_fstatfs(abi_long fd, abi_ulong target_addr) return h2t_freebsd_statfs(target_addr, &host_stfs); } +/* getfsstat(2) */ +static inline abi_long do_freebsd11_getfsstat(abi_ulong target_addr, + abi_long bufsize, abi_long flags) +{ + abi_long ret; + struct freebsd11_statfs *host_stfs; + int count; + long host_bufsize; + + count = bufsize / sizeof(struct target_freebsd11_statfs); + + /* if user buffer is NULL then return number of mounted FS's */ + if (target_addr == 0 || count == 0) { + return get_errno(freebsd11_getfsstat(NULL, 0, flags)); + } + + /* XXX check count to be reasonable */ + host_bufsize = sizeof(struct freebsd11_statfs) * count; + host_stfs = alloca(host_bufsize); + if (!host_stfs) { + return -TARGET_EINVAL; + } + + ret = count = get_errno(freebsd11_getfsstat(host_stfs, host_bufsize, flags)); + if (is_error(ret)) { + return ret; + } + + while (count--) { + if (h2t_freebsd11_statfs((target_addr + + (count * sizeof(struct target_freebsd11_statfs))), + &host_stfs[count])) { + return -TARGET_EFAULT; + } + } + return ret; +} + /* getfsstat(2) */ static inline abi_long do_freebsd_getfsstat(abi_ulong target_addr, abi_long bufsize, abi_long flags) From 91a98c9bbcfba2a9f278a0811676cd2f8000481c Mon Sep 17 00:00:00 2001 From: Michal Meloun Date: Sun, 13 Aug 2023 10:41:46 +0200 Subject: [PATCH 28/36] bsd-user: Implement freebsd11 getdirents related syscalls Implement the freebsd11 variant of the following syscalls: getdirentries(2) Co-authored-by: Stacey Son Signed-off-by: Stacey Son Signed-off-by: Michal Meloun Signed-off-by: Karim Taha Reviewed-by: Richard Henderson Signed-off-by: Warner Losh --- bsd-user/freebsd/os-stat.h | 44 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 44 insertions(+) diff --git a/bsd-user/freebsd/os-stat.h b/bsd-user/freebsd/os-stat.h index 04a61fabd1..26909af455 100644 --- a/bsd-user/freebsd/os-stat.h +++ b/bsd-user/freebsd/os-stat.h @@ -41,6 +41,11 @@ __sym_compat(statfs, freebsd11_statfs, FBSD_1.0); int freebsd11_fstatfs(int fd, struct freebsd11_statfs *buf); __sym_compat(fstatfs, freebsd11_fstatfs, FBSD_1.0); +ssize_t freebsd11_getdirentries(int fd, char *buf, size_t nbytes, off_t *basep); +__sym_compat(getdirentries, freebsd11_getdirentries, FBSD_1.0); +ssize_t freebsd11_getdents(int fd, char *buf, size_t nbytes); +__sym_compat(getdents, freebsd11_getdents, FBSD_1.0); + /* stat(2) */ static inline abi_long do_freebsd11_stat(abi_long arg1, abi_long arg2) @@ -468,6 +473,45 @@ static inline abi_long do_freebsd11_getdents(abi_long arg1, return ret; } +/* getdirecentries(2) */ +static inline abi_long do_freebsd11_getdirentries(abi_long arg1, + abi_ulong arg2, abi_long nbytes, abi_ulong arg4) +{ + abi_long ret; + struct freebsd11_dirent *dirp; + long basep; + + dirp = lock_user(VERIFY_WRITE, arg2, nbytes, 0); + if (dirp == NULL) { + return -TARGET_EFAULT; + } + ret = get_errno(freebsd11_getdirentries(arg1, (char *)dirp, nbytes, &basep)); + if (!is_error(ret)) { + struct freebsd11_dirent *de; + int len = ret; + int reclen; + + de = dirp; + while (len > 0) { + reclen = de->d_reclen; + if (reclen > len) { + return -TARGET_EFAULT; + } + de->d_reclen = tswap16(reclen); + de->d_fileno = tswap32(de->d_fileno); + len -= reclen; + de = (struct freebsd11_dirent *)((void *)de + reclen); + } + } + unlock_user(dirp, arg2, ret); + if (arg4) { + if (put_user(basep, arg4, abi_ulong)) { + return -TARGET_EFAULT; + } + } + return ret; +} + /* getdirecentries(2) */ static inline abi_long do_freebsd_getdirentries(abi_long arg1, abi_ulong arg2, abi_long nbytes, abi_ulong arg4) From 292f00c05bfa62a020eee5eb1d8c0983e8483b33 Mon Sep 17 00:00:00 2001 From: Michal Meloun Date: Sun, 13 Aug 2023 10:41:47 +0200 Subject: [PATCH 29/36] bsd-user: Implement freebsd11 netbsd stat related syscalls Forward declaration of the nstat syscalls: nstat nlstat nfstat Co-authored-by: Stacey Son Signed-off-by: Stacey Son Signed-off-by: Michal Meloun Signed-off-by: Karim Taha Reviewed-by: Richard Henderson Signed-off-by: Warner Losh --- bsd-user/freebsd/os-stat.h | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/bsd-user/freebsd/os-stat.h b/bsd-user/freebsd/os-stat.h index 26909af455..e31b2aab9e 100644 --- a/bsd-user/freebsd/os-stat.h +++ b/bsd-user/freebsd/os-stat.h @@ -46,6 +46,13 @@ __sym_compat(getdirentries, freebsd11_getdirentries, FBSD_1.0); ssize_t freebsd11_getdents(int fd, char *buf, size_t nbytes); __sym_compat(getdents, freebsd11_getdents, FBSD_1.0); +/* undocumented nstat system calls */ +int freebsd11_nstat(const char *path, struct freebsd11_stat *sb); +__sym_compat(nstat, freebsd11_nstat, FBSD_1.0); +int freebsd11_nlstat(const char *path, struct freebsd11_stat *sb); +__sym_compat(nlstat, freebsd11_nlstat, FBSD_1.0); +int freebsd11_nfstat(int fd, struct freebsd11_stat *sb); +__sym_compat(nfstat, freebsd11_nfstat, FBSD_1.0); /* stat(2) */ static inline abi_long do_freebsd11_stat(abi_long arg1, abi_long arg2) From 292bfd0f512aa71fcc8f7e2f6ce2aa40a5a825ef Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mika=C3=ABl=20Urankar?= Date: Sun, 13 Aug 2023 10:41:48 +0200 Subject: [PATCH 30/36] bsd-user: Implement do_freebsd_realpathat syscall MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Mikaël Urankar Signed-off-by: Karim Taha Reviewed-by: Richard Henderson Signed-off-by: Warner Losh --- bsd-user/freebsd/os-stat.h | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/bsd-user/freebsd/os-stat.h b/bsd-user/freebsd/os-stat.h index e31b2aab9e..b20e270774 100644 --- a/bsd-user/freebsd/os-stat.h +++ b/bsd-user/freebsd/os-stat.h @@ -634,4 +634,30 @@ static inline abi_long do_freebsd_fcntl(abi_long arg1, abi_long arg2, return ret; } +#if defined(__FreeBSD_version) && __FreeBSD_version >= 1300080 +extern int __realpathat(int fd, const char *path, char *buf, size_t size, + int flags); +/* https://svnweb.freebsd.org/base?view=revision&revision=358172 */ +/* no man page */ +static inline abi_long do_freebsd_realpathat(abi_long arg1, abi_long arg2, + abi_long arg3, abi_long arg4, abi_long arg5) +{ + abi_long ret; + void *p, *b; + + LOCK_PATH(p, arg2); + b = lock_user(VERIFY_WRITE, arg3, arg4, 0); + if (b == NULL) { + UNLOCK_PATH(p, arg2); + return -TARGET_EFAULT; + } + + ret = get_errno(__realpathat(arg1, p, b, arg4, arg5)); + UNLOCK_PATH(p, arg2); + unlock_user(b, arg3, ret); + + return ret; +} +#endif + #endif /* BSD_USER_FREEBSD_OS_STAT_H */ From c97c1f3a9f4d4a5bebf88c844b9b3fc07c4296e3 Mon Sep 17 00:00:00 2001 From: Karim Taha Date: Sun, 13 Aug 2023 10:41:49 +0200 Subject: [PATCH 31/36] bsd-user: Add os-stat.c to the build Signed-off-by: Karim Taha Reviewed-by: Richard Henderson Signed-off-by: Warner Losh --- bsd-user/freebsd/meson.build | 1 + 1 file changed, 1 insertion(+) diff --git a/bsd-user/freebsd/meson.build b/bsd-user/freebsd/meson.build index f87c788e84..f2f047cca3 100644 --- a/bsd-user/freebsd/meson.build +++ b/bsd-user/freebsd/meson.build @@ -1,4 +1,5 @@ bsd_user_ss.add(files( + 'os-stat.c', 'os-sys.c', 'os-syscall.c', )) From e800e6c541b4088a52f4c0129eb4cbbf8a0ea9fb Mon Sep 17 00:00:00 2001 From: Warner Losh Date: Sun, 13 Aug 2023 10:41:50 +0200 Subject: [PATCH 32/36] bsd-user: Add glue for the freebsd11_stat syscalls Add glue to call the freebsd11_stat syscalls to the freebsd_syscall: freebsd11_stat freebsd11_lstat freebsd11_fstat freebsd11_fstatat freebsd11_nstat, freebsd11_nfstat, freebsd11_nlstat fstatat fstat Signed-off-by: Warner Losh Signed-off-by: Karim Taha Reviewed-by: Richard Henderson Signed-off-by: Warner Losh --- bsd-user/freebsd/os-syscall.c | 42 +++++++++++++++++++++++++++++++++++ 1 file changed, 42 insertions(+) diff --git a/bsd-user/freebsd/os-syscall.c b/bsd-user/freebsd/os-syscall.c index 2224a280ea..ade47a0d2f 100644 --- a/bsd-user/freebsd/os-syscall.c +++ b/bsd-user/freebsd/os-syscall.c @@ -36,6 +36,9 @@ #include "bsd-file.h" #include "bsd-proc.h" +/* *BSD dependent syscall shims */ +#include "os-stat.h" + /* I/O */ safe_syscall3(int, open, const char *, path, int, flags, mode_t, mode); safe_syscall4(int, openat, int, fd, const char *, path, int, flags, mode_t, @@ -482,6 +485,45 @@ static abi_long freebsd_syscall(void *cpu_env, int num, abi_long arg1, ret = do_bsd_undelete(arg1); break; + /* + * stat system calls + */ + case TARGET_FREEBSD_NR_freebsd11_stat: /* stat(2) */ + ret = do_freebsd11_stat(arg1, arg2); + break; + + case TARGET_FREEBSD_NR_freebsd11_lstat: /* lstat(2) */ + ret = do_freebsd11_lstat(arg1, arg2); + break; + + case TARGET_FREEBSD_NR_freebsd11_fstat: /* fstat(2) */ + ret = do_freebsd11_fstat(arg1, arg2); + break; + + case TARGET_FREEBSD_NR_fstat: /* fstat(2) */ + ret = do_freebsd_fstat(arg1, arg2); + break; + + case TARGET_FREEBSD_NR_freebsd11_fstatat: /* fstatat(2) */ + ret = do_freebsd11_fstatat(arg1, arg2, arg3, arg4); + break; + + case TARGET_FREEBSD_NR_fstatat: /* fstatat(2) */ + ret = do_freebsd_fstatat(arg1, arg2, arg3, arg4); + break; + + case TARGET_FREEBSD_NR_freebsd11_nstat: /* undocumented */ + ret = do_freebsd11_nstat(arg1, arg2); + break; + + case TARGET_FREEBSD_NR_freebsd11_nfstat: /* undocumented */ + ret = do_freebsd11_nfstat(arg1, arg2); + break; + + case TARGET_FREEBSD_NR_freebsd11_nlstat: /* undocumented */ + ret = do_freebsd11_nlstat(arg1, arg2); + break; + /* * sys{ctl, arch, call} */ From 6fe97c6cf7969bcf809a89ecabc30acf10b77735 Mon Sep 17 00:00:00 2001 From: Warner Losh Date: Sun, 13 Aug 2023 10:41:51 +0200 Subject: [PATCH 33/36] bsd-user: Add glue for getfh and related syscalls Add glue to call the following syscalls to the freebsd_syscall: getfh lgetfh fhopen freebsd11_fhstat freebsd11_fhstatfs fhstat fhstatfs Signed-off-by: Warner Losh Signed-off-by: Karim Taha Reviewed-by: Richard Henderson --- bsd-user/freebsd/os-syscall.c | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/bsd-user/freebsd/os-syscall.c b/bsd-user/freebsd/os-syscall.c index ade47a0d2f..73616a5be0 100644 --- a/bsd-user/freebsd/os-syscall.c +++ b/bsd-user/freebsd/os-syscall.c @@ -524,6 +524,34 @@ static abi_long freebsd_syscall(void *cpu_env, int num, abi_long arg1, ret = do_freebsd11_nlstat(arg1, arg2); break; + case TARGET_FREEBSD_NR_getfh: /* getfh(2) */ + ret = do_freebsd_getfh(arg1, arg2); + break; + + case TARGET_FREEBSD_NR_lgetfh: /* lgetfh(2) */ + ret = do_freebsd_lgetfh(arg1, arg2); + break; + + case TARGET_FREEBSD_NR_fhopen: /* fhopen(2) */ + ret = do_freebsd_fhopen(arg1, arg2); + break; + + case TARGET_FREEBSD_NR_freebsd11_fhstat: /* fhstat(2) */ + ret = do_freebsd11_fhstat(arg1, arg2); + break; + + case TARGET_FREEBSD_NR_fhstat: /* fhstat(2) */ + ret = do_freebsd_fhstat(arg1, arg2); + break; + + case TARGET_FREEBSD_NR_freebsd11_fhstatfs: /* fhstatfs(2) */ + ret = do_freebsd11_fhstatfs(arg1, arg2); + break; + + case TARGET_FREEBSD_NR_fhstatfs: /* fhstatfs(2) */ + ret = do_freebsd_fhstatfs(arg1, arg2); + break; + /* * sys{ctl, arch, call} */ From d7e9a545084ba1ded8fe864697db174cc3e6ebe2 Mon Sep 17 00:00:00 2001 From: Warner Losh Date: Sun, 13 Aug 2023 10:41:52 +0200 Subject: [PATCH 34/36] bsd-user: Add glue for statfs related system calls Add glue to call the following syscalls to the freebsd_syscall: freebsd11_statfs statfs freebsd11_fstatfs fstatfs freebsd11_getfsstat getfsstat Signed-off-by: Warner Losh Signed-off-by: Karim Taha Reviewed-by: Richard Henderson --- bsd-user/freebsd/os-syscall.c | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/bsd-user/freebsd/os-syscall.c b/bsd-user/freebsd/os-syscall.c index 73616a5be0..916a754bf8 100644 --- a/bsd-user/freebsd/os-syscall.c +++ b/bsd-user/freebsd/os-syscall.c @@ -552,6 +552,30 @@ static abi_long freebsd_syscall(void *cpu_env, int num, abi_long arg1, ret = do_freebsd_fhstatfs(arg1, arg2); break; + case TARGET_FREEBSD_NR_freebsd11_statfs: /* statfs(2) */ + ret = do_freebsd11_statfs(arg1, arg2); + break; + + case TARGET_FREEBSD_NR_statfs: /* statfs(2) */ + ret = do_freebsd_statfs(arg1, arg2); + break; + + case TARGET_FREEBSD_NR_freebsd11_fstatfs: /* fstatfs(2) */ + ret = do_freebsd11_fstatfs(arg1, arg2); + break; + + case TARGET_FREEBSD_NR_fstatfs: /* fstatfs(2) */ + ret = do_freebsd_fstatfs(arg1, arg2); + break; + + case TARGET_FREEBSD_NR_freebsd11_getfsstat: /* getfsstat(2) */ + ret = do_freebsd11_getfsstat(arg1, arg2, arg3); + break; + + case TARGET_FREEBSD_NR_getfsstat: /* getfsstat(2) */ + ret = do_freebsd_getfsstat(arg1, arg2, arg3); + break; + /* * sys{ctl, arch, call} */ From 97a3c571147c3b62a79a994ebd85769419e630c2 Mon Sep 17 00:00:00 2001 From: Warner Losh Date: Sun, 13 Aug 2023 10:41:53 +0200 Subject: [PATCH 35/36] bsd-user: Add getdents and fcntl related system calls Add glue to call the following syscalls to the freebsd_syscall: freebsd11_getdents getdirentries freebsd11_getdirentries fcntl Signed-off-by: Warner Losh Signed-off-by: Karim Taha Reviewed-by: Richard Henderson Signed-off-by: Warner Losh --- bsd-user/freebsd/os-syscall.c | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/bsd-user/freebsd/os-syscall.c b/bsd-user/freebsd/os-syscall.c index 916a754bf8..e9b1b663af 100644 --- a/bsd-user/freebsd/os-syscall.c +++ b/bsd-user/freebsd/os-syscall.c @@ -576,6 +576,22 @@ static abi_long freebsd_syscall(void *cpu_env, int num, abi_long arg1, ret = do_freebsd_getfsstat(arg1, arg2, arg3); break; + case TARGET_FREEBSD_NR_freebsd11_getdents: /* getdents(2) */ + ret = do_freebsd11_getdents(arg1, arg2, arg3); + break; + + case TARGET_FREEBSD_NR_getdirentries: /* getdirentries(2) */ + ret = do_freebsd_getdirentries(arg1, arg2, arg3, arg4); + break; + + case TARGET_FREEBSD_NR_freebsd11_getdirentries: /* getdirentries(2) */ + ret = do_freebsd11_getdirentries(arg1, arg2, arg3, arg4); + break; + case TARGET_FREEBSD_NR_fcntl: /* fcntl(2) */ + ret = do_freebsd_fcntl(arg1, arg2, arg3); + break; + + /* * sys{ctl, arch, call} */ From f51e7c41acb4b17d28fc74f9f10df50a4a65fbcc Mon Sep 17 00:00:00 2001 From: Warner Losh Date: Sat, 19 Aug 2023 22:54:19 -0600 Subject: [PATCH 36/36] bsd-user: Add missing break after do_bsd_preadv MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Without it, we'd call preadv, then write with weird parameters, which is clearly not ideal... Signed-off-by: Warner Losh Reviewed-by: Philippe Mathieu-Daudé Fixes: 770d8abae7 ("bsd-user/bsd-file.h: Meat of the write system calls") Reviewed-by: Richard Henderson Message-Id: <20230820045419.89691-1-imp@bsdimp.com> --- bsd-user/freebsd/os-syscall.c | 1 + 1 file changed, 1 insertion(+) diff --git a/bsd-user/freebsd/os-syscall.c b/bsd-user/freebsd/os-syscall.c index e9b1b663af..fa60df529e 100644 --- a/bsd-user/freebsd/os-syscall.c +++ b/bsd-user/freebsd/os-syscall.c @@ -240,6 +240,7 @@ static abi_long freebsd_syscall(void *cpu_env, int num, abi_long arg1, case TARGET_FREEBSD_NR_preadv: /* preadv(2) */ ret = do_bsd_preadv(cpu_env, arg1, arg2, arg3, arg4, arg5, arg6); + break; case TARGET_FREEBSD_NR_write: /* write(2) */ ret = do_bsd_write(arg1, arg2, arg3);