From 948516a3fac0bdd47eb127fe1a86148ed86d5c65 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mika=C3=ABl=20Urankar?= Date: Sat, 8 Jul 2017 13:13:31 +0200 Subject: [PATCH 01/23] bsd-user/mmap.c: Always zero MAP_ANONYMOUS memory in mmap_frag() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Similar to the equivalent linux-user commit e6deac9cf99 When mapping MAP_ANONYMOUS memory fragments, still need notice about to set it zero, or it will cause issues. Signed-off-by: Mikaël Urankar Signed-off-by: Warner Losh Reviewed-by: Richard Henderson Reviewed-by: Kyle Evans --- bsd-user/mmap.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/bsd-user/mmap.c b/bsd-user/mmap.c index b40ab9045f..fc3c1480f5 100644 --- a/bsd-user/mmap.c +++ b/bsd-user/mmap.c @@ -180,10 +180,12 @@ static int mmap_frag(abi_ulong real_start, if (prot_new != (prot1 | PROT_WRITE)) mprotect(host_start, qemu_host_page_size, prot_new); } else { - /* just update the protection */ if (prot_new != prot1) { mprotect(host_start, qemu_host_page_size, prot_new); } + if (prot_new & PROT_WRITE) { + memset(g2h_untagged(start), 0, end - start); + } } return 0; } From 26778ac3da794f29c2c7c7d473f0a8d77b874392 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mika=C3=ABl=20Urankar?= Date: Thu, 16 Sep 2021 17:45:05 -0600 Subject: [PATCH 02/23] bsd-user/mmap.c: check pread's return value to fix warnings with _FORTIFY_SOURCE MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Simmilar to the equivalent linux-user: commit fb7e378cf9c, which added checking to pread's return value. Update to current qemu standards with {} around the if statement. Signed-off-by: Mikaël Urankar Signed-off-by: Warner Losh Reviewed-by: Richard Henderson Reviewed-by: Philippe Mathieu-Daudé Reviewed-by: Kyle Evans --- bsd-user/mmap.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/bsd-user/mmap.c b/bsd-user/mmap.c index fc3c1480f5..4f4fa3ab46 100644 --- a/bsd-user/mmap.c +++ b/bsd-user/mmap.c @@ -174,7 +174,9 @@ static int mmap_frag(abi_ulong real_start, mprotect(host_start, qemu_host_page_size, prot1 | PROT_WRITE); /* read the corresponding file data */ - pread(fd, g2h_untagged(start), end - start, offset); + if (pread(fd, g2h_untagged(start), end - start, offset) == -1) { + return -1; + } /* put final protection */ if (prot_new != (prot1 | PROT_WRITE)) @@ -593,7 +595,9 @@ abi_long target_mmap(abi_ulong start, abi_ulong len, int prot, -1, 0); if (retaddr == -1) goto fail; - pread(fd, g2h_untagged(start), len, offset); + if (pread(fd, g2h_untagged(start), len, offset) == -1) { + goto fail; + } if (!(prot & PROT_WRITE)) { ret = target_mprotect(start, len, prot); if (ret != 0) { From 36d5d891559f6b9f0bae4907669de9bfdf5d4d94 Mon Sep 17 00:00:00 2001 From: Warner Losh Date: Thu, 16 Sep 2021 18:37:21 -0600 Subject: [PATCH 03/23] bsd-user/mmap.c: MAP_ symbols are defined, so no need for ifdefs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit All these MAP_ symbols are always defined on supported FreeBSD versions (12.2 and newer), so remove the #ifdefs since they aren't needed. Signed-off-by: Warner Losh Reviewed-by: Philippe Mathieu-Daudé Acked-by: Richard Henderson Reviewed-by: Kyle Evans --- bsd-user/mmap.c | 14 -------------- 1 file changed, 14 deletions(-) diff --git a/bsd-user/mmap.c b/bsd-user/mmap.c index 4f4fa3ab46..6f33aec58b 100644 --- a/bsd-user/mmap.c +++ b/bsd-user/mmap.c @@ -286,13 +286,9 @@ static abi_ulong mmap_find_vma_aligned(abi_ulong start, abi_ulong size, wrapped = repeat = 0; prev = 0; flags = MAP_ANONYMOUS | MAP_PRIVATE; -#ifdef MAP_ALIGNED if (alignment != 0) { flags |= MAP_ALIGNED(alignment); } -#else - /* XXX TODO */ -#endif for (;; prev = ptr) { /* @@ -407,22 +403,18 @@ abi_long target_mmap(abi_ulong start, abi_ulong len, int prot, printf("MAP_ALIGNED(%u) ", (flags & MAP_ALIGNMENT_MASK) >> MAP_ALIGNMENT_SHIFT); } -#if MAP_GUARD if (flags & MAP_GUARD) { printf("MAP_GUARD "); } -#endif if (flags & MAP_FIXED) { printf("MAP_FIXED "); } if (flags & MAP_ANONYMOUS) { printf("MAP_ANON "); } -#ifdef MAP_EXCL if (flags & MAP_EXCL) { printf("MAP_EXCL "); } -#endif if (flags & MAP_PRIVATE) { printf("MAP_PRIVATE "); } @@ -432,11 +424,9 @@ abi_long target_mmap(abi_ulong start, abi_ulong len, int prot, if (flags & MAP_NOCORE) { printf("MAP_NOCORE "); } -#ifdef MAP_STACK if (flags & MAP_STACK) { printf("MAP_STACK "); } -#endif printf("fd=%d offset=0x%llx\n", fd, offset); } #endif @@ -445,7 +435,6 @@ abi_long target_mmap(abi_ulong start, abi_ulong len, int prot, errno = EINVAL; goto fail; } -#ifdef MAP_STACK if (flags & MAP_STACK) { if ((fd != -1) || ((prot & (PROT_READ | PROT_WRITE)) != (PROT_READ | PROT_WRITE))) { @@ -453,8 +442,6 @@ abi_long target_mmap(abi_ulong start, abi_ulong len, int prot, goto fail; } } -#endif /* MAP_STACK */ -#ifdef MAP_GUARD if ((flags & MAP_GUARD) && (prot != PROT_NONE || fd != -1 || offset != 0 || (flags & (MAP_SHARED | MAP_PRIVATE | /* MAP_PREFAULT | */ /* MAP_PREFAULT not in mman.h */ @@ -462,7 +449,6 @@ abi_long target_mmap(abi_ulong start, abi_ulong len, int prot, errno = EINVAL; goto fail; } -#endif if (offset & ~TARGET_PAGE_MASK) { errno = EINVAL; From 14837a3f7540f38ba78261238da3914a6529d882 Mon Sep 17 00:00:00 2001 From: Warner Losh Date: Thu, 16 Sep 2021 18:43:01 -0600 Subject: [PATCH 04/23] bsd-user/mmap.c: mmap return ENOMEM on overflow MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit mmap should return ENOMEM on len overflow rather than EINVAL. Return EINVAL when len == 0 and ENOMEM when the rounded to a page length is 0. Found by make check-tcg. Signed-off-by: Warner Losh Reviewed-by: Richard Henderson Reviewed-by: Philippe Mathieu-Daudé Reviewed-by: Kyle Evans --- bsd-user/mmap.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/bsd-user/mmap.c b/bsd-user/mmap.c index 6f33aec58b..f0be3b12cf 100644 --- a/bsd-user/mmap.c +++ b/bsd-user/mmap.c @@ -455,11 +455,18 @@ abi_long target_mmap(abi_ulong start, abi_ulong len, int prot, goto fail; } - len = TARGET_PAGE_ALIGN(len); if (len == 0) { errno = EINVAL; goto fail; } + + /* Check for overflows */ + len = TARGET_PAGE_ALIGN(len); + if (len == 0) { + errno = ENOMEM; + goto fail; + } + real_start = start & qemu_host_page_mask; host_offset = offset & qemu_host_page_mask; From 953b69cc06fe3ae5fa1c157f17f054fa95620f38 Mon Sep 17 00:00:00 2001 From: Warner Losh Date: Thu, 16 Sep 2021 18:45:28 -0600 Subject: [PATCH 05/23] bsd-user/mmap.c: mmap prefer MAP_ANON for BSD MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit MAP_ANON and MAP_ANONYMOUS are identical. Prefer MAP_ANON for BSD since the file is now a confusing mix of the two. Signed-off-by: Warner Losh Reviewed-by: Philippe Mathieu-Daudé Reviewed-by: Richard Henderson Reviewed-by: Kyle Evans --- bsd-user/mmap.c | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/bsd-user/mmap.c b/bsd-user/mmap.c index f0be3b12cf..301108ed25 100644 --- a/bsd-user/mmap.c +++ b/bsd-user/mmap.c @@ -285,7 +285,7 @@ static abi_ulong mmap_find_vma_aligned(abi_ulong start, abi_ulong size, addr = start; wrapped = repeat = 0; prev = 0; - flags = MAP_ANONYMOUS | MAP_PRIVATE; + flags = MAP_ANON | MAP_PRIVATE; if (alignment != 0) { flags |= MAP_ALIGNED(alignment); } @@ -409,7 +409,7 @@ abi_long target_mmap(abi_ulong start, abi_ulong len, int prot, if (flags & MAP_FIXED) { printf("MAP_FIXED "); } - if (flags & MAP_ANONYMOUS) { + if (flags & MAP_ANON) { printf("MAP_ANON "); } if (flags & MAP_EXCL) { @@ -431,7 +431,7 @@ abi_long target_mmap(abi_ulong start, abi_ulong len, int prot, } #endif - if ((flags & MAP_ANONYMOUS) && fd != -1) { + if ((flags & MAP_ANON) && fd != -1) { errno = EINVAL; goto fail; } @@ -533,7 +533,7 @@ abi_long target_mmap(abi_ulong start, abi_ulong len, int prot, * qemu_real_host_page_size */ p = mmap(g2h_untagged(start), host_len, prot, - flags | MAP_FIXED | ((fd != -1) ? MAP_ANONYMOUS : 0), -1, 0); + flags | MAP_FIXED | ((fd != -1) ? MAP_ANON : 0), -1, 0); if (p == MAP_FAILED) goto fail; /* update start so that it points to the file position at 'offset' */ @@ -696,8 +696,7 @@ static void mmap_reserve(abi_ulong start, abi_ulong size) } if (real_start != real_end) { mmap(g2h_untagged(real_start), real_end - real_start, PROT_NONE, - MAP_FIXED | MAP_ANONYMOUS | MAP_PRIVATE, - -1, 0); + MAP_FIXED | MAP_ANON | MAP_PRIVATE, -1, 0); } } From 45b8765e8f3001436c09cebcd9b8b281e6c55804 Mon Sep 17 00:00:00 2001 From: Warner Losh Date: Thu, 16 Sep 2021 18:47:19 -0600 Subject: [PATCH 06/23] bsd-user/mmap.c: Convert to qemu_log logging for mmap debugging MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Convert DEBUG_MMAP to qemu_log CPU_LOG_PAGE. Signed-off-by: Warner Losh Reviewed-by: Richard Henderson Reviewed-by: Philippe Mathieu-Daudé Reviewed-by: Kyle Evans --- bsd-user/mmap.c | 53 +++++++++++++++++++++---------------------------- 1 file changed, 23 insertions(+), 30 deletions(-) diff --git a/bsd-user/mmap.c b/bsd-user/mmap.c index 301108ed25..face98573f 100644 --- a/bsd-user/mmap.c +++ b/bsd-user/mmap.c @@ -21,8 +21,6 @@ #include "qemu.h" #include "qemu-common.h" -//#define DEBUG_MMAP - static pthread_mutex_t mmap_mutex = PTHREAD_MUTEX_INITIALIZER; static __thread int mmap_lock_count; @@ -67,14 +65,11 @@ int target_mprotect(abi_ulong start, abi_ulong len, int prot) abi_ulong end, host_start, host_end, addr; int prot1, ret; -#ifdef DEBUG_MMAP - printf("mprotect: start=0x" TARGET_ABI_FMT_lx - "len=0x" TARGET_ABI_FMT_lx " prot=%c%c%c\n", start, len, - prot & PROT_READ ? 'r' : '-', - prot & PROT_WRITE ? 'w' : '-', - prot & PROT_EXEC ? 'x' : '-'); -#endif - + qemu_log_mask(CPU_LOG_PAGE, "mprotect: start=0x" TARGET_ABI_FMT_lx + " len=0x" TARGET_ABI_FMT_lx " prot=%c%c%c\n", start, len, + prot & PROT_READ ? 'r' : '-', + prot & PROT_WRITE ? 'w' : '-', + prot & PROT_EXEC ? 'x' : '-'); if ((start & ~TARGET_PAGE_MASK) != 0) return -EINVAL; len = TARGET_PAGE_ALIGN(len); @@ -391,45 +386,43 @@ abi_long target_mmap(abi_ulong start, abi_ulong len, int prot, abi_ulong ret, end, real_start, real_end, retaddr, host_offset, host_len; mmap_lock(); -#ifdef DEBUG_MMAP - { - printf("mmap: start=0x" TARGET_ABI_FMT_lx - " len=0x" TARGET_ABI_FMT_lx " prot=%c%c%c flags=", - start, len, - prot & PROT_READ ? 'r' : '-', - prot & PROT_WRITE ? 'w' : '-', - prot & PROT_EXEC ? 'x' : '-'); + if (qemu_loglevel_mask(CPU_LOG_PAGE)) { + qemu_log("mmap: start=0x" TARGET_ABI_FMT_lx + " len=0x" TARGET_ABI_FMT_lx " prot=%c%c%c flags=", + start, len, + prot & PROT_READ ? 'r' : '-', + prot & PROT_WRITE ? 'w' : '-', + prot & PROT_EXEC ? 'x' : '-'); if (flags & MAP_ALIGNMENT_MASK) { - printf("MAP_ALIGNED(%u) ", (flags & MAP_ALIGNMENT_MASK) - >> MAP_ALIGNMENT_SHIFT); + qemu_log("MAP_ALIGNED(%u) ", + (flags & MAP_ALIGNMENT_MASK) >> MAP_ALIGNMENT_SHIFT); } if (flags & MAP_GUARD) { - printf("MAP_GUARD "); + qemu_log("MAP_GUARD "); } if (flags & MAP_FIXED) { - printf("MAP_FIXED "); + qemu_log("MAP_FIXED "); } if (flags & MAP_ANON) { - printf("MAP_ANON "); + qemu_log("MAP_ANON "); } if (flags & MAP_EXCL) { - printf("MAP_EXCL "); + qemu_log("MAP_EXCL "); } if (flags & MAP_PRIVATE) { - printf("MAP_PRIVATE "); + qemu_log("MAP_PRIVATE "); } if (flags & MAP_SHARED) { - printf("MAP_SHARED "); + qemu_log("MAP_SHARED "); } if (flags & MAP_NOCORE) { - printf("MAP_NOCORE "); + qemu_log("MAP_NOCORE "); } if (flags & MAP_STACK) { - printf("MAP_STACK "); + qemu_log("MAP_STACK "); } - printf("fd=%d offset=0x%llx\n", fd, offset); + qemu_log("fd=%d offset=0x%lx\n", fd, offset); } -#endif if ((flags & MAP_ANON) && fd != -1) { errno = EINVAL; From a6b2d060667422d54e077c0a8e4c55bd083ef489 Mon Sep 17 00:00:00 2001 From: Warner Losh Date: Mon, 18 Oct 2021 12:51:17 -0600 Subject: [PATCH 07/23] bsd-user/mmap.c: Don't mmap fd == -1 independently from MAP_ANON flag Switch checks for !(flags & MAP_ANONYMOUS) with checks for fd != -1. MAP_STACK and MAP_GUARD both require fd == -1 and don't require mapping the fd either. Add analysis from Guy Yur detailing the different cases for MAP_GUARD and MAP_STACK. Signed-off-by: Guy Yur [ partially merged before, finishing the job and documenting origin] Signed-off-by: Warner Losh Reviewed-by: Richard Henderson Reviewed-by: Kyle Evans --- bsd-user/mmap.c | 30 +++++++++++++++++++++++++----- 1 file changed, 25 insertions(+), 5 deletions(-) diff --git a/bsd-user/mmap.c b/bsd-user/mmap.c index face98573f..4ecd949a10 100644 --- a/bsd-user/mmap.c +++ b/bsd-user/mmap.c @@ -127,7 +127,27 @@ error: return ret; } -/* map an incomplete host page */ +/* + * map an incomplete host page + * + * mmap_frag can be called with a valid fd, if flags doesn't contain one of + * MAP_ANON, MAP_STACK, MAP_GUARD. If we need to map a page in those cases, we + * pass fd == -1. However, if flags contains MAP_GUARD then MAP_ANON cannot be + * added. + * + * * If fd is valid (not -1) we want to map the pages with MAP_ANON. + * * If flags contains MAP_GUARD we don't want to add MAP_ANON because it + * will be rejected. See kern_mmap's enforcing of constraints for MAP_GUARD + * in sys/vm/vm_mmap.c. + * * If flags contains MAP_ANON it doesn't matter if we add it or not. + * * If flags contains MAP_STACK, mmap adds MAP_ANON when called so doesn't + * matter if we add it or not either. See enforcing of constraints for + * MAP_STACK in kern_mmap. + * + * Don't add MAP_ANON for the flags that use fd == -1 without specifying the + * flags directly, with the assumption that future flags that require fd == -1 + * will also not require MAP_ANON. + */ static int mmap_frag(abi_ulong real_start, abi_ulong start, abi_ulong end, int prot, int flags, int fd, abi_ulong offset) @@ -147,9 +167,9 @@ static int mmap_frag(abi_ulong real_start, } if (prot1 == 0) { - /* no page was there, so we allocate one */ + /* no page was there, so we allocate one. See also above. */ void *p = mmap(host_start, qemu_host_page_size, prot, - flags | MAP_ANON, -1, 0); + flags | ((fd != -1) ? MAP_ANON : 0), -1, 0); if (p == MAP_FAILED) return -1; prot1 = prot; @@ -157,7 +177,7 @@ static int mmap_frag(abi_ulong real_start, prot1 &= PAGE_BITS; prot_new = prot | prot1; - if (!(flags & MAP_ANON)) { + if (fd != -1) { /* msync() won't work here, so we return an error if write is possible while it is a shared mapping */ if ((flags & TARGET_BSD_MAP_FLAGMASK) == MAP_SHARED && @@ -565,7 +585,7 @@ abi_long target_mmap(abi_ulong start, abi_ulong len, int prot, * worst case: we cannot map the file because the offset is not * aligned, so we read it */ - if (!(flags & MAP_ANON) && + if (fd != -1 && (offset & ~qemu_host_page_mask) != (start & ~qemu_host_page_mask)) { /* * msync() won't work here, so we return an error if write is From 0fc76b685989d30a32316b17a9c43ba017e114a1 Mon Sep 17 00:00:00 2001 From: Kyle Evans Date: Thu, 8 Nov 2018 14:39:47 -0600 Subject: [PATCH 08/23] bsd-user/mmap.c: Implement MAP_EXCL, required by jemalloc in head jemalloc requires a working MAP_EXCL. Ensure that no page is double mapped when specified. In addition, use guest_range_valid_untagged to test for valid ranges of pages rather than an incomplete inlined version of the test that might be wrong. Signed-off-by: Kyle Evans Signed-off-by: Warner Losh Reviewed-by: Richard Henderson --- bsd-user/mmap.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/bsd-user/mmap.c b/bsd-user/mmap.c index 4ecd949a10..5b6ed5eed1 100644 --- a/bsd-user/mmap.c +++ b/bsd-user/mmap.c @@ -574,12 +574,10 @@ abi_long target_mmap(abi_ulong start, abi_ulong len, int prot, * It can fail only on 64-bit host with 32-bit target. * On any other target/host host mmap() handles this error correctly. */ -#if TARGET_ABI_BITS == 32 && HOST_LONG_BITS == 64 - if ((unsigned long)start + len - 1 > (abi_ulong) -1) { + if (!guest_range_valid_untagged(start, len)) { errno = EINVAL; goto fail; } -#endif /* * worst case: we cannot map the file because the offset is not @@ -614,6 +612,12 @@ abi_long target_mmap(abi_ulong start, abi_ulong len, int prot, goto the_end; } + /* Reject the mapping if any page within the range is mapped */ + if ((flags & MAP_EXCL) && page_check_range(start, len, 0) < 0) { + errno = EINVAL; + goto fail; + } + /* handle the start of the mapping */ if (start > real_start) { if (real_end == real_start + qemu_host_page_size) { From 91a5adda1583fa8a3166bc16d79c67f3c87e958b Mon Sep 17 00:00:00 2001 From: Warner Losh Date: Fri, 17 Sep 2021 09:16:54 -0600 Subject: [PATCH 09/23] bsd-user/mmap.c: assert that target_mprotect cannot fail MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Similar to the equivalent linux-user change 86abac06c14. All error conditions that target_mprotect checks are also checked by target_mmap. EACCESS cannot happen because we are just removing PROT_WRITE. ENOMEM should not happen because we are modifying a whole VMA (and we have bigger problems anyway if it happens). Fixes a Coverity false positive, where Coverity complains about target_mprotect's return value being passed to tb_invalidate_phys_range. Signed-off-by: Mikaël Urankar Signed-off-by: Warner Losh Reviewed-by: Richard Henderson Reviewed-by: Philippe Mathieu-Daudé Reviewed-by: Kyle Evans --- bsd-user/mmap.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/bsd-user/mmap.c b/bsd-user/mmap.c index 5b6ed5eed1..13cb32dba1 100644 --- a/bsd-user/mmap.c +++ b/bsd-user/mmap.c @@ -604,10 +604,7 @@ abi_long target_mmap(abi_ulong start, abi_ulong len, int prot, } if (!(prot & PROT_WRITE)) { ret = target_mprotect(start, len, prot); - if (ret != 0) { - start = ret; - goto the_end; - } + assert(ret == 0); } goto the_end; } From dda2da6c94484b85d28fe7c29f7fee562deaf177 Mon Sep 17 00:00:00 2001 From: Warner Losh Date: Fri, 8 Oct 2021 16:47:37 -0600 Subject: [PATCH 10/23] meson: *-user: only descend into *-user when configured MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit To increase flexibility, only descend into *-user when that is configured. This allows *-user to selectively include directories based on the host OS which may not exist on all hosts. Adopt Paolo's suggestion of checking the configuration in the directories that know about the configuration. Message-Id: <20210926220103.1721355-2-f4bug@amsat.org> Message-Id: <20210926220103.1721355-3-f4bug@amsat.org> Signed-off-by: Philippe Mathieu-Daudé Signed-off-by: Warner Losh Acked-by: Paolo Bonzini Reviewed-by: Kyle Evans --- bsd-user/meson.build | 4 ++++ linux-user/meson.build | 4 ++++ meson.build | 12 ++++++++---- 3 files changed, 16 insertions(+), 4 deletions(-) diff --git a/bsd-user/meson.build b/bsd-user/meson.build index 0369549340..5378f56f71 100644 --- a/bsd-user/meson.build +++ b/bsd-user/meson.build @@ -1,3 +1,7 @@ +if not have_bsd_user + subdir_done() +endif + bsd_user_ss.add(files( 'bsdload.c', 'elfload.c', diff --git a/linux-user/meson.build b/linux-user/meson.build index 9549f81682..bf62c13e37 100644 --- a/linux-user/meson.build +++ b/linux-user/meson.build @@ -1,3 +1,7 @@ +if not have_linux_user + subdir_done() +endif + linux_user_ss.add(files( 'elfload.c', 'exit.c', diff --git a/meson.build b/meson.build index 6b7487b725..5e7946776d 100644 --- a/meson.build +++ b/meson.build @@ -40,12 +40,15 @@ config_host_data = configuration_data() genh = [] target_dirs = config_host['TARGET_DIRS'].split() -have_user = false +have_linux_user = false +have_bsd_user = false have_system = false foreach target : target_dirs - have_user = have_user or target.endswith('-user') + have_linux_user = have_linux_user or target.endswith('linux-user') + have_bsd_user = have_bsd_user or target.endswith('bsd-user') have_system = have_system or target.endswith('-softmmu') endforeach +have_user = have_linux_user or have_bsd_user have_tools = 'CONFIG_TOOLS' in config_host have_block = have_system or have_tools @@ -2595,10 +2598,11 @@ subdir('bsd-user') subdir('linux-user') subdir('ebpf') -bsd_user_ss.add(files('gdbstub.c')) +common_ss.add(libbpf) + specific_ss.add_all(when: 'CONFIG_BSD_USER', if_true: bsd_user_ss) -linux_user_ss.add(files('gdbstub.c', 'thunk.c')) +linux_user_ss.add(files('thunk.c')) specific_ss.add_all(when: 'CONFIG_LINUX_USER', if_true: linux_user_ss) # needed for fuzzing binaries From 1fecb605f83f4a5db315cd183b6f4e30fc72518d Mon Sep 17 00:00:00 2001 From: Warner Losh Date: Sun, 19 Sep 2021 00:17:40 -0600 Subject: [PATCH 11/23] bsd-user/target_os-user.h: Remove support for FreeBSD older than 12.0 Signed-off-by: Warner Losh Reviewed-by: Richard Henderson Reviewed-by: Kyle Evans --- bsd-user/freebsd/target_os_user.h | 100 +----------------------------- 1 file changed, 1 insertion(+), 99 deletions(-) diff --git a/bsd-user/freebsd/target_os_user.h b/bsd-user/freebsd/target_os_user.h index 95b1fa9f99..19892c5071 100644 --- a/bsd-user/freebsd/target_os_user.h +++ b/bsd-user/freebsd/target_os_user.h @@ -61,15 +61,7 @@ struct target_sockaddr_storage { /* * from sys/user.h */ -#if defined(__FreeBSD_version) && __FreeBSD_version >= 1200031 #define TARGET_KI_NSPARE_INT 2 -#elif defined(__FreeBSD_version) && __FreeBSD_version >= 1100000 -#define TARGET_KI_NSPARE_INT 4 -#elif defined(__FreeBSD_version) && __FreeBSD_version >= 1000000 -#define TARGET_KI_NSPARE_INT 7 -#else -#define TARGET_KI_NSPARE_INT 9 -#endif /* ! __FreeBSD_version >= 1000000 */ #define TARGET_KI_NSPARE_LONG 12 #define TARGET_KI_NSPARE_PTR 6 @@ -116,11 +108,7 @@ struct target_kinfo_proc { int32_t ki_tsid; /* Terminal session ID */ int16_t ki_jobc; /* job control counter */ int16_t ki_spare_short1; /* unused (just here for alignment) */ -#if defined(__FreeBSD_version) && __FreeBSD_version >= 1200031 int32_t ki_tdev__freebsd11; /* controlling tty dev */ -#else - int32_t ki_tdev; /* controlling tty dev */ -#endif target_sigset_t ki_siglist; /* Signals arrived but not delivered */ target_sigset_t ki_sigmask; /* Current signal mask */ target_sigset_t ki_sigignore; /* Signals being ignored */ @@ -164,45 +152,24 @@ struct target_kinfo_proc { int8_t ki_nice; /* Process "nice" value */ char ki_lock; /* Process lock (prevent swap) count */ char ki_rqindex; /* Run queue index */ -#if defined(__FreeBSD_version) && __FreeBSD_version >= 1100000 u_char ki_oncpu_old; /* Which cpu we are on (legacy) */ u_char ki_lastcpu_old; /* Last cpu we were on (legacy) */ -#else - u_char ki_oncpu; /* Which cpu we are on */ - u_char ki_lastcpu; /* Last cpu we were on */ -#endif /* ! __FreeBSD_version >= 1100000 */ -#if defined(__FreeBSD_version) && __FreeBSD_version >= 900000 char ki_tdname[TARGET_TDNAMLEN + 1]; /* thread name */ -#else - char ki_ocomm[TARGET_TDNAMLEN + 1]; /* thread name */ -#endif /* ! __FreeBSD_version >= 900000 */ char ki_wmesg[TARGET_WMESGLEN + 1]; /* wchan message */ char ki_login[TARGET_LOGNAMELEN + 1]; /* setlogin name */ char ki_lockname[TARGET_LOCKNAMELEN + 1]; /* lock name */ char ki_comm[TARGET_COMMLEN + 1]; /* command name */ char ki_emul[TARGET_KI_EMULNAMELEN + 1]; /* emulation name */ -#if defined(__FreeBSD_version) && __FreeBSD_version >= 900000 char ki_loginclass[TARGET_LOGINCLASSLEN + 1]; /* login class */ -#endif /* ! __FreeBSD_version >= 900000 */ -#if defined(__FreeBSD_version) && __FreeBSD_version >= 900000 char ki_sparestrings[50]; /* spare string space */ -#else - char ki_sparestrings[68]; /* spare string space */ -#endif /* ! __FreeBSD_version >= 900000 */ int32_t ki_spareints[TARGET_KI_NSPARE_INT]; /* spare room for growth */ -#if defined(__FreeBSD_version) && __FreeBSD_version >= 1200031 - uint64_t ki_tdev; /* controlling tty dev */ -#endif -#if defined(__FreeBSD_version) && __FreeBSD_version >= 1100000 + uint64_t ki_tdev; /* controlling tty dev */ int32_t ki_oncpu; /* Which cpu we are on */ int32_t ki_lastcpu; /* Last cpu we were on */ int32_t ki_tracer; /* Pid of tracing process */ -#endif /* __FreeBSD_version >= 1100000 */ -#if defined(__FreeBSD_version) && __FreeBSD_version >= 900000 int32_t ki_flag2; /* P2_* flags */ int32_t ki_fibnum; /* Default FIB number */ -#endif /* ! __FreeBSD_version >= 900000 */ uint32_t ki_cr_flags; /* Credential flags */ int32_t ki_jid; /* Process jail ID */ int32_t ki_numthreads; /* XXXKSE number of threads in total */ @@ -234,18 +201,8 @@ struct target_kinfo_file { int32_t kf_flags; /* Flags. */ int32_t kf_pad0; /* Round to 64 bit alignment. */ int64_t kf_offset; /* Seek location. */ -#if defined(__FreeBSD_version) && __FreeBSD_version < 1200031 - int32_t kf_vnode_type; /* Vnode type. */ - int32_t kf_sock_domain; /* Socket domain. */ - int32_t kf_sock_type; /* Socket type. */ - int32_t kf_sock_protocol; /* Socket protocol. */ - struct target_sockaddr_storage kf_sa_local; /* Socket address. */ - struct target_sockaddr_storage kf_sa_peer; /* Peer address. */ -#endif -#if defined(__FreeBSD_version) && __FreeBSD_version >= 900000 union { struct { -#if defined(__FreeBSD_version) && __FreeBSD_version >= 1200031 uint32_t kf_spareint; /* Socket domain. */ int kf_sock_domain0; @@ -257,7 +214,6 @@ struct target_kinfo_file { struct sockaddr_storage kf_sa_local; /* Peer address. */ struct sockaddr_storage kf_sa_peer; -#endif /* Address of so_pcb. */ uint64_t kf_sock_pcb; /* Address of inp_ppcb. */ @@ -272,7 +228,6 @@ struct target_kinfo_file { uint32_t kf_sock_pad0; } kf_sock; struct { -#if defined(__FreeBSD_version) && __FreeBSD_version >= 1200031 /* Vnode type. */ int kf_file_type; /* Space for future use */ @@ -290,16 +245,6 @@ struct target_kinfo_file { uint32_t kf_file_fsid_freebsd11; /* File device, FreeBSD 11 compat. */ uint32_t kf_file_rdev_freebsd11; -#else - /* Global file id. */ - uint64_t kf_file_fileid; - /* File size. */ - uint64_t kf_file_size; - /* Vnode filesystem id. */ - uint32_t kf_file_fsid; - /* File device. */ - uint32_t kf_file_rdev; -#endif /* File mode. */ uint16_t kf_file_mode; /* Round to 64 bit alignment. */ @@ -307,18 +252,14 @@ struct target_kinfo_file { uint32_t kf_file_pad1; } kf_file; struct { -#if defined(__FreeBSD_version) && __FreeBSD_version >= 1200031 uint32_t kf_spareint[4]; uint64_t kf_spareint64[32]; -#endif uint32_t kf_sem_value; uint16_t kf_sem_mode; } kf_sem; struct { -#if defined(__FreeBSD_version) && __FreeBSD_version >= 1200031 uint32_t kf_spareint[4]; uint64_t kf_spareint64[32]; -#endif uint64_t kf_pipe_addr; uint64_t kf_pipe_peer; uint32_t kf_pipe_buffer_cnt; @@ -326,7 +267,6 @@ struct target_kinfo_file { uint32_t kf_pipe_pad0[3]; } kf_pipe; struct { -#if defined(__FreeBSD_version) && __FreeBSD_version >= 1200031 uint32_t kf_spareint[4]; uint64_t kf_spareint64[32]; uint32_t kf_pts_dev_freebsd11; @@ -334,34 +274,18 @@ struct target_kinfo_file { uint64_t kf_pts_dev; /* Round to 64 bit alignment. */ uint32_t kf_pts_pad1[4]; -#else - uint32_t kf_pts_dev; - /* Round to 64 bit alignment. */ - uint32_t kf_pts_pad0[7]; -#endif } kf_pts; struct { -#if defined(__FreeBSD_version) && __FreeBSD_version >= 1200031 uint32_t kf_spareint[4]; uint64_t kf_spareint64[32]; -#endif int32_t kf_pid; } kf_proc; } kf_un; uint16_t kf_status; /* Status flags. */ uint16_t kf_pad1; /* Round to 32 bit alignment. */ int32_t _kf_ispare0; /* Space for more stuff. */ -#if defined(__FreeBSD_version) && __FreeBSD_version >= 1000000 target_cap_rights_t kf_cap_rights; /* Capability rights. */ uint64_t _kf_cap_spare; /* Space for future cap_rights_t. */ -#else /* ! __FreeBSD_version >= 1000000 */ - uint64_t kf_cap_rights; - int _kf_ispare[4]; -#endif /* ! __FreeBSD_version >= 1000000 */ - -#else /* ! __FreeBSD_version >= 900000 */ - int _kf_ispare[16]; -#endif /* ! __FreeBSD_version >= 900000 */ /* Truncated before copyout in sysctl */ char kf_path[PATH_MAX]; /* Path to file, if any. */ }; @@ -372,34 +296,19 @@ struct target_kinfo_vmentry { uint64_t kve_start; /* Starting address. */ uint64_t kve_end; /* Finishing address. */ uint64_t kve_offset; /* Mapping offset in object */ -#if defined(__FreeBSD_version) && __FreeBSD_version >= 900000 uint64_t kve_vn_fileid; /* inode number if vnode */ -#if defined(__FreeBSD_version) && __FreeBSD_version >= 1200031 uint32_t kve_vn_fsid_freebsd11; /* dev_t of vnode location */ -#else - uint32_t kve_vn_fsid; /* dev_t of vnode location */ -#endif -#else /* ! __FreeBSD_version >= 900000 */ - uint64_t kve_fileid; /* inode number if vnode */ - uint32_t kve_fsid; /* dev_t of vnode location */ -#endif /* ! __FreeBSD_version >= 900000 */ int32_t kve_flags; /* Flags on map entry. */ int32_t kve_resident; /* Number of resident pages. */ int32_t kve_private_resident; /* Number of private pages. */ int32_t kve_protection; /* Protection bitmask. */ int32_t kve_ref_count; /* VM obj ref count. */ int32_t kve_shadow_count; /* VM obj shadow count. */ -#if defined(__FreeBSD_version) && __FreeBSD_version >= 900000 int32_t kve_vn_type; /* Vnode type. */ uint64_t kve_vn_size; /* File size. */ -#if defined(__FreeBSD_version) && __FreeBSD_version >= 1200031 uint32_t kve_vn_rdev_freebsd11; /* Device id if device. */ -#else - uint32_t kve_vn_rdev; /* Device id if device. */ -#endif uint16_t kve_vn_mode; /* File mode. */ uint16_t kve_status; /* Status flags. */ -#if defined(__FreeBSD_version) && __FreeBSD_version >= 1200031 #if (__FreeBSD_version >= 1300501 && __FreeBSD_version < 1400000) || \ __FreeBSD_version >= 1400009 union { @@ -413,13 +322,6 @@ struct target_kinfo_vmentry { #endif uint64_t kve_vn_rdev; /* Device id if device. */ int _kve_ispare[8]; /* Space for more stuff. */ -#else - int32_t _kve_ispare[12]; /* Space for more stuff. */ -#endif -#else /* ! __FreeBSD_version >= 900000 */ - int _kve_pad0; - int32_t _kve_ispare[16]; /* Space for more stuff. */ -#endif /* ! __FreeBSD_version >= 900000 */ /* Truncated before copyout in sysctl */ char kve_path[PATH_MAX]; /* Path to VM obj, if any. */ }; From b03c0bb27aa513869fbdbff941b92e5aa3604bd0 Mon Sep 17 00:00:00 2001 From: Warner Losh Date: Sun, 19 Sep 2021 00:15:37 -0600 Subject: [PATCH 12/23] bsd-user/strace.list: Remove support for FreeBSD versions older than 12.0 Signed-off-by: Warner Losh Reviewed-by: Richard Henderson Reviewed-by: Kyle Evans --- bsd-user/freebsd/strace.list | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/bsd-user/freebsd/strace.list b/bsd-user/freebsd/strace.list index b01b5f36e8..275d2dbe27 100644 --- a/bsd-user/freebsd/strace.list +++ b/bsd-user/freebsd/strace.list @@ -33,10 +33,6 @@ { TARGET_FREEBSD_NR___syscall, "__syscall", NULL, NULL, NULL }, { TARGET_FREEBSD_NR___sysctl, "__sysctl", NULL, print_sysctl, NULL }, { TARGET_FREEBSD_NR__umtx_op, "_umtx_op", "%s(%#x, %d, %d, %#x, %#x)", NULL, NULL }, -#if defined(__FreeBSD_version) && __FreeBSD_version < 1000000 -{ TARGET_FREEBSD_NR__umtx_lock, "__umtx_lock", NULL, NULL, NULL }, -{ TARGET_FREEBSD_NR__umtx_unlock, "__umtx_unlock", NULL, NULL, NULL }, -#endif { TARGET_FREEBSD_NR_accept, "accept", "%s(%d,%#x,%#x)", NULL, NULL }, { TARGET_FREEBSD_NR_accept4, "accept4", "%s(%d,%d,%#x,%#x)", NULL, NULL }, { TARGET_FREEBSD_NR_access, "access", "%s(\"%s\",%#o)", NULL, NULL }, @@ -49,10 +45,6 @@ { TARGET_FREEBSD_NR_cap_fcntls_get, "cap_fcntls_get", NULL, NULL, NULL }, { TARGET_FREEBSD_NR_cap_fcntls_limit, "cap_fcntls_limit", NULL, NULL, NULL }, { TARGET_FREEBSD_NR_cap_getmode, "cap_getmode", NULL, NULL, NULL }, -#if defined(__FreeBSD_version) && __FreeBSD_version < 1000000 -{ TARGET_FREEBSD_NR_cap_getrights, "cap_getrights", NULL, NULL, NULL }, -{ TARGET_FREEBSD_NR_cap_new, "cap_new", NULL, NULL, NULL }, -#endif { TARGET_FREEBSD_NR_cap_ioctls_get, "cap_ioctls_get", NULL, NULL, NULL }, { TARGET_FREEBSD_NR_cap_ioctls_limit, "cap_ioctls_limit", NULL, NULL, NULL }, { TARGET_FREEBSD_NR_cap_rights_limit, "cap_rights_limit", NULL, NULL, NULL }, @@ -146,9 +138,6 @@ { TARGET_FREEBSD_NR_freebsd11_kevent, "freebsd11_kevent", NULL, NULL, NULL }, { TARGET_FREEBSD_NR_kevent, "kevent", NULL, NULL, NULL }, { TARGET_FREEBSD_NR_kill, "kill", NULL, NULL, NULL }, -#if defined(__FreeBSD_version) && __FreeBSD_version < 1000000 -{ TARGET_FREEBSD_NR_killpg, "killpg", NULL, NULL, NULL }, -#endif { TARGET_FREEBSD_NR_kqueue, "kqueue", NULL, NULL, NULL }, { TARGET_FREEBSD_NR_ktrace, "ktrace", NULL, NULL, NULL }, { TARGET_FREEBSD_NR_lchown, "lchown", NULL, NULL, NULL }, From fbbacc99821781f4d0faa0e714c4885d9570faf4 Mon Sep 17 00:00:00 2001 From: Warner Losh Date: Tue, 21 Sep 2021 18:59:05 -0600 Subject: [PATCH 13/23] bsd-user: TARGET_RESET define is unused, remove it MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Warner Losh Reviewed-by: Richard Henderson Reviewed-by: Philippe Mathieu-Daudé Reviewed-by: Kyle Evans --- bsd-user/i386/target_arch_cpu.h | 2 -- bsd-user/x86_64/target_arch_cpu.h | 2 -- 2 files changed, 4 deletions(-) diff --git a/bsd-user/i386/target_arch_cpu.h b/bsd-user/i386/target_arch_cpu.h index 978e8066af..b28602adbb 100644 --- a/bsd-user/i386/target_arch_cpu.h +++ b/bsd-user/i386/target_arch_cpu.h @@ -23,8 +23,6 @@ #define TARGET_DEFAULT_CPU_MODEL "qemu32" -#define TARGET_CPU_RESET(cpu) - static inline void target_cpu_init(CPUX86State *env, struct target_pt_regs *regs) { diff --git a/bsd-user/x86_64/target_arch_cpu.h b/bsd-user/x86_64/target_arch_cpu.h index 5f5ee602f9..5172b230f0 100644 --- a/bsd-user/x86_64/target_arch_cpu.h +++ b/bsd-user/x86_64/target_arch_cpu.h @@ -23,8 +23,6 @@ #define TARGET_DEFAULT_CPU_MODEL "qemu64" -#define TARGET_CPU_RESET(cpu) - static inline void target_cpu_init(CPUX86State *env, struct target_pt_regs *regs) { From e5f674f01cdfbb7b98374a947aed84412f4c763f Mon Sep 17 00:00:00 2001 From: Warner Losh Date: Sat, 18 Sep 2021 00:26:49 -0600 Subject: [PATCH 14/23] bsd-user: export get_errno and is_error from syscall.c MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Make get_errno and is_error global so files other than syscall.c can use them. Signed-off-by: Warner Losh Reviewed-by: Richard Henderson Reviewed-by: Philippe Mathieu-Daudé Reviewed-by: Kyle Evans --- bsd-user/qemu.h | 4 ++++ bsd-user/syscall.c | 10 +++++----- 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/bsd-user/qemu.h b/bsd-user/qemu.h index 522d6c4031..3b8475394c 100644 --- a/bsd-user/qemu.h +++ b/bsd-user/qemu.h @@ -235,6 +235,10 @@ extern unsigned long target_dflssiz; extern unsigned long target_maxssiz; extern unsigned long target_sgrowsiz; +/* syscall.c */ +abi_long get_errno(abi_long ret); +bool is_error(abi_long ret); + /* user access */ #define VERIFY_READ PAGE_READ diff --git a/bsd-user/syscall.c b/bsd-user/syscall.c index 372836d44d..2fd2ba8330 100644 --- a/bsd-user/syscall.c +++ b/bsd-user/syscall.c @@ -33,18 +33,18 @@ static abi_ulong target_brk; static abi_ulong target_original_brk; -static inline abi_long get_errno(abi_long ret) +abi_long get_errno(abi_long ret) { - if (ret == -1) + if (ret == -1) { /* XXX need to translate host -> target errnos here */ return -(errno); - else - return ret; + } + return ret; } #define target_to_host_bitmask(x, tbl) (x) -static inline int is_error(abi_long ret) +bool is_error(abi_long ret) { return (abi_ulong)ret >= (abi_ulong)(-4096); } From 7cb4d7c917c2718f9fd5a075c2e4b4fca3be482a Mon Sep 17 00:00:00 2001 From: Stacey Son Date: Sat, 18 Sep 2021 09:27:47 -0600 Subject: [PATCH 15/23] bsd-user/errno_defs.h: Add internal error numbers To emulate signals and interrupted system calls, we need to have the same mechanisms we have in the kernel, including these errno values. Signed-off-by: Stacey Son Signed-off-by: Warner Losh Reviewed-by: Richard Henderson Reviewed-by: Kyle Evans --- bsd-user/errno_defs.h | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/bsd-user/errno_defs.h b/bsd-user/errno_defs.h index 1efa502a12..832671354f 100644 --- a/bsd-user/errno_defs.h +++ b/bsd-user/errno_defs.h @@ -1,6 +1,3 @@ -/* $OpenBSD: errno.h,v 1.20 2007/09/03 14:37:52 millert Exp $ */ -/* $NetBSD: errno.h,v 1.10 1996/01/20 01:33:53 jtc Exp $ */ - /* * Copyright (c) 1982, 1986, 1989, 1993 * The Regents of the University of California. All rights reserved. @@ -37,6 +34,9 @@ * @(#)errno.h 8.5 (Berkeley) 1/21/94 */ +#ifndef _ERRNO_DEFS_H_ +#define _ERRNO_DEFS_H_ + #define TARGET_EPERM 1 /* Operation not permitted */ #define TARGET_ENOENT 2 /* No such file or directory */ #define TARGET_ESRCH 3 /* No such process */ @@ -147,3 +147,10 @@ #define TARGET_EIDRM 89 /* Identifier removed */ #define TARGET_ENOMSG 90 /* No message of desired type */ #define TARGET_ELAST 90 /* Must be equal largest errno */ + +/* Internal errors: */ +#define TARGET_EJUSTRETURN 254 /* Just return without modifing regs */ +#define TARGET_ERESTART 255 /* Restart syscall */ +#define TARGET_ERESTARTSYS TARGET_ERESTART /* Linux compat */ + +#endif /* ! _ERRNO_DEFS_H_ */ From f4a29b6ed29360cf556851c82875a2b782adb5ed Mon Sep 17 00:00:00 2001 From: Warner Losh Date: Tue, 21 Sep 2021 17:40:23 -0600 Subject: [PATCH 16/23] bsd-user: move TARGET_MC_GET_CLEAR_RET to target_os_signal.h MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Move TARGET_MC_GET_CLEAR_RET to freebsd/target_os_signal.h since it's architecture agnostic on FreeBSD. Signed-off-by: Warner Losh Reviewed-by: Richard Henderson Reviewed-by: Philippe Mathieu-Daudé Reviewed-by: Kyle Evans --- bsd-user/freebsd/target_os_signal.h | 3 +++ bsd-user/i386/target_arch_signal.h | 2 -- bsd-user/x86_64/target_arch_signal.h | 2 -- 3 files changed, 3 insertions(+), 4 deletions(-) diff --git a/bsd-user/freebsd/target_os_signal.h b/bsd-user/freebsd/target_os_signal.h index 3ed454e086..1a4c5faf19 100644 --- a/bsd-user/freebsd/target_os_signal.h +++ b/bsd-user/freebsd/target_os_signal.h @@ -1,6 +1,9 @@ #ifndef _TARGET_OS_SIGNAL_H_ #define _TARGET_OS_SIGNAL_H_ +/* FreeBSD's sys/ucontext.h defines this */ +#define TARGET_MC_GET_CLEAR_RET 0x0001 + #include "target_os_siginfo.h" #include "target_arch_signal.h" diff --git a/bsd-user/i386/target_arch_signal.h b/bsd-user/i386/target_arch_signal.h index 9812c6b034..a90750d602 100644 --- a/bsd-user/i386/target_arch_signal.h +++ b/bsd-user/i386/target_arch_signal.h @@ -27,8 +27,6 @@ #define TARGET_MINSIGSTKSZ (512 * 4) /* min sig stack size */ #define TARGET_SIGSTKSZ (MINSIGSTKSZ + 32768) /* recommended size */ -#define TARGET_MC_GET_CLEAR_RET 0x0001 - struct target_sigcontext { /* to be added */ }; diff --git a/bsd-user/x86_64/target_arch_signal.h b/bsd-user/x86_64/target_arch_signal.h index 4c1ff0e5ba..4bb753b08b 100644 --- a/bsd-user/x86_64/target_arch_signal.h +++ b/bsd-user/x86_64/target_arch_signal.h @@ -27,8 +27,6 @@ #define TARGET_MINSIGSTKSZ (512 * 4) /* min sig stack size */ #define TARGET_SIGSTKSZ (MINSIGSTKSZ + 32768) /* recommended size */ -#define TARGET_MC_GET_CLEAR_RET 0x0001 - struct target_sigcontext { /* to be added */ }; From 11170cbdcc64e4207850eb886baeb6db436aaf46 Mon Sep 17 00:00:00 2001 From: Warner Losh Date: Sat, 18 Sep 2021 09:35:43 -0600 Subject: [PATCH 17/23] bsd-user/target_os_elf.h: Remove fallback ELF_HWCAP and reorder MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit All architectures have a ELF_HWCAP, so remove the fallback ifdef. Place ELF_HWCAP in the same order as on native FreeBSD. Signed-off-by: Warner Losh Reviewed-by: Richard Henderson Reviewed-by: Philippe Mathieu-Daudé Reviewed-by: Kyle Evans --- bsd-user/freebsd/target_os_elf.h | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/bsd-user/freebsd/target_os_elf.h b/bsd-user/freebsd/target_os_elf.h index 2d03a883aa..adcffd1ddb 100644 --- a/bsd-user/freebsd/target_os_elf.h +++ b/bsd-user/freebsd/target_os_elf.h @@ -38,10 +38,6 @@ #define ELF_PLATFORM (NULL) #endif -#ifndef ELF_HWCAP -#define ELF_HWCAP 0 -#endif - /* XXX Look at the other conflicting AT_* values. */ #define FREEBSD_AT_NCPUS 19 #define FREEBSD_AT_HWCAP 25 @@ -114,12 +110,12 @@ static abi_ulong target_create_elf_tables(abi_ulong p, int argc, int envc, NEW_AUX_ENT(AT_FLAGS, (abi_ulong)0); NEW_AUX_ENT(FREEBSD_AT_NCPUS, (abi_ulong)bsd_get_ncpu()); NEW_AUX_ENT(AT_ENTRY, load_bias + exec->e_entry); + features = ELF_HWCAP; + NEW_AUX_ENT(FREEBSD_AT_HWCAP, features); NEW_AUX_ENT(AT_UID, (abi_ulong)getuid()); NEW_AUX_ENT(AT_EUID, (abi_ulong)geteuid()); NEW_AUX_ENT(AT_GID, (abi_ulong)getgid()); NEW_AUX_ENT(AT_EGID, (abi_ulong)getegid()); - features = ELF_HWCAP; - NEW_AUX_ENT(FREEBSD_AT_HWCAP, features); target_auxents = sp; /* Note where the aux entries are in the target */ #ifdef ARCH_DLINFO /* From f6f0706cc2081ebaf786603aaaf204ae5a39dda7 Mon Sep 17 00:00:00 2001 From: Warner Losh Date: Sat, 18 Sep 2021 09:38:11 -0600 Subject: [PATCH 18/23] bsd-user/target_os_elf: If ELF_HWCAP2 is defined, publish it MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Some architectures publish AT_HWCAP2 as well as AT_HWCAP. Those architectures will define ELF_HWCAP2 in their target_arch_elf.h files for the value for this process. If it is defined, then publish it. Signed-off-by: Warner Losh Reviewed-by: Richard Henderson Reviewed-by: Philippe Mathieu-Daudé Reviewed-by: Kyle Evans --- bsd-user/freebsd/target_os_elf.h | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/bsd-user/freebsd/target_os_elf.h b/bsd-user/freebsd/target_os_elf.h index adcffd1ddb..e5ac8e8e50 100644 --- a/bsd-user/freebsd/target_os_elf.h +++ b/bsd-user/freebsd/target_os_elf.h @@ -112,6 +112,10 @@ static abi_ulong target_create_elf_tables(abi_ulong p, int argc, int envc, NEW_AUX_ENT(AT_ENTRY, load_bias + exec->e_entry); features = ELF_HWCAP; NEW_AUX_ENT(FREEBSD_AT_HWCAP, features); +#ifdef ELF_HWCAP2 + features = ELF_HWCAP2; + NEW_AUX_ENT(FREEBSD_AT_HWCAP2, features); +#endif NEW_AUX_ENT(AT_UID, (abi_ulong)getuid()); NEW_AUX_ENT(AT_EUID, (abi_ulong)geteuid()); NEW_AUX_ENT(AT_GID, (abi_ulong)getgid()); From 7aac7392346d1f5bb9fc31cb7e4f3f1f3fc2be05 Mon Sep 17 00:00:00 2001 From: Warner Losh Date: Sat, 18 Sep 2021 22:03:43 -0600 Subject: [PATCH 19/23] bsd-user: Remove used from TaskState MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The 'used' field in TaskState is write only. Remove it from TaskState. Signed-off-by: Warner Losh Reviewed-by: Richard Henderson Reviewed-by: Philippe Mathieu-Daudé Reviewed-by: Kyle Evans --- bsd-user/main.c | 1 - bsd-user/qemu.h | 1 - 2 files changed, 2 deletions(-) diff --git a/bsd-user/main.c b/bsd-user/main.c index 48643eeabc..ee84554854 100644 --- a/bsd-user/main.c +++ b/bsd-user/main.c @@ -210,7 +210,6 @@ void init_task_state(TaskState *ts) { int i; - ts->used = 1; ts->first_free = ts->sigqueue_table; for (i = 0; i < MAX_SIGQUEUE_SIZE - 1; i++) { ts->sigqueue_table[i].next = &ts->sigqueue_table[i + 1]; diff --git a/bsd-user/qemu.h b/bsd-user/qemu.h index 3b8475394c..c1170f14d9 100644 --- a/bsd-user/qemu.h +++ b/bsd-user/qemu.h @@ -92,7 +92,6 @@ typedef struct TaskState { struct TaskState *next; struct bsd_binprm *bprm; - int used; /* non zero if used */ struct image_info *info; struct emulated_sigtable sigtab[TARGET_NSIG]; From 653ccec26dd3f9942ac258c43be0edb93e16dfba Mon Sep 17 00:00:00 2001 From: Warner Losh Date: Sun, 19 Sep 2021 01:11:43 -0600 Subject: [PATCH 20/23] bsd-user: Add stop_all_tasks Similar to the same function in linux-user: this stops all the current tasks. Signed-off-by: Stacey Son Signed-off-by: Warner Losh Reviewed-by: Richard Henderson Reviewed-by: Kyle Evans --- bsd-user/main.c | 9 +++++++++ bsd-user/qemu.h | 1 + 2 files changed, 10 insertions(+) diff --git a/bsd-user/main.c b/bsd-user/main.c index ee84554854..cb5ea40236 100644 --- a/bsd-user/main.c +++ b/bsd-user/main.c @@ -195,6 +195,15 @@ static void usage(void) __thread CPUState *thread_cpu; +void stop_all_tasks(void) +{ + /* + * We trust when using NPTL (pthreads) start_exclusive() handles thread + * stopping correctly. + */ + start_exclusive(); +} + bool qemu_cpu_is_self(CPUState *cpu) { return thread_cpu == cpu; diff --git a/bsd-user/qemu.h b/bsd-user/qemu.h index c1170f14d9..cdb85140f4 100644 --- a/bsd-user/qemu.h +++ b/bsd-user/qemu.h @@ -103,6 +103,7 @@ typedef struct TaskState { } __attribute__((aligned(16))) TaskState; void init_task_state(TaskState *ts); +void stop_all_tasks(void); extern const char *qemu_uname_release; /* From da07e6944fb0f1fe162246cbf31271f31ec9a5c0 Mon Sep 17 00:00:00 2001 From: Warner Losh Date: Mon, 20 Sep 2021 13:41:38 -0600 Subject: [PATCH 21/23] bsd-user/sysarch: Move to using do_freebsd_arch_sysarch interface do_freebsd_arch_sysarch() exists in $ARCH/target_arch_sysarch.h for x86. Call it from do_freebsd_sysarch() and remove the mostly duplicate version in syscall.c. Future changes will move it to os-sys.c and support other architectures. Signed-off-by: Warner Losh Reviewed-by: Richard Henderson Reviewed-by: Kyle Evans --- bsd-user/freebsd/meson.build | 3 +++ bsd-user/freebsd/os-sys.c | 27 +++++++++++++++++++ bsd-user/meson.build | 3 +++ bsd-user/qemu.h | 3 +++ bsd-user/syscall.c | 50 ------------------------------------ 5 files changed, 36 insertions(+), 50 deletions(-) create mode 100644 bsd-user/freebsd/meson.build create mode 100644 bsd-user/freebsd/os-sys.c diff --git a/bsd-user/freebsd/meson.build b/bsd-user/freebsd/meson.build new file mode 100644 index 0000000000..4b69cca7b9 --- /dev/null +++ b/bsd-user/freebsd/meson.build @@ -0,0 +1,3 @@ +bsd_user_ss.add(files( + 'os-sys.c', +)) diff --git a/bsd-user/freebsd/os-sys.c b/bsd-user/freebsd/os-sys.c new file mode 100644 index 0000000000..309e27b9d6 --- /dev/null +++ b/bsd-user/freebsd/os-sys.c @@ -0,0 +1,27 @@ +/* + * FreeBSD sysctl() and sysarch() system call emulation + * + * Copyright (c) 2013-15 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.h" +#include "target_arch_sysarch.h" + +/* sysarch() is architecture dependent. */ +abi_long do_freebsd_sysarch(void *cpu_env, abi_long arg1, abi_long arg2) +{ + return do_freebsd_arch_sysarch(cpu_env, arg1, arg2); +} diff --git a/bsd-user/meson.build b/bsd-user/meson.build index 5378f56f71..87885d91ed 100644 --- a/bsd-user/meson.build +++ b/bsd-user/meson.build @@ -12,3 +12,6 @@ bsd_user_ss.add(files( 'syscall.c', 'uaccess.c', )) + +# Pull in the OS-specific build glue, if any +subdir(targetos) diff --git a/bsd-user/qemu.h b/bsd-user/qemu.h index cdb85140f4..e65e41d53d 100644 --- a/bsd-user/qemu.h +++ b/bsd-user/qemu.h @@ -239,6 +239,9 @@ extern unsigned long target_sgrowsiz; abi_long get_errno(abi_long ret); bool is_error(abi_long ret); +/* os-sys.c */ +abi_long do_freebsd_sysarch(void *cpu_env, abi_long arg1, abi_long arg2); + /* user access */ #define VERIFY_READ PAGE_READ diff --git a/bsd-user/syscall.c b/bsd-user/syscall.c index 2fd2ba8330..d3322760f4 100644 --- a/bsd-user/syscall.c +++ b/bsd-user/syscall.c @@ -88,56 +88,6 @@ static abi_long do_obreak(abi_ulong new_brk) return 0; } -#if defined(TARGET_I386) -static abi_long do_freebsd_sysarch(CPUX86State *env, int op, abi_ulong parms) -{ - abi_long ret = 0; - abi_ulong val; - int idx; - - switch (op) { -#ifdef TARGET_ABI32 - case TARGET_FREEBSD_I386_SET_GSBASE: - case TARGET_FREEBSD_I386_SET_FSBASE: - if (op == TARGET_FREEBSD_I386_SET_GSBASE) -#else - case TARGET_FREEBSD_AMD64_SET_GSBASE: - case TARGET_FREEBSD_AMD64_SET_FSBASE: - if (op == TARGET_FREEBSD_AMD64_SET_GSBASE) -#endif - idx = R_GS; - else - idx = R_FS; - if (get_user(val, parms, abi_ulong)) - return -TARGET_EFAULT; - cpu_x86_load_seg(env, idx, 0); - env->segs[idx].base = val; - break; -#ifdef TARGET_ABI32 - case TARGET_FREEBSD_I386_GET_GSBASE: - case TARGET_FREEBSD_I386_GET_FSBASE: - if (op == TARGET_FREEBSD_I386_GET_GSBASE) -#else - case TARGET_FREEBSD_AMD64_GET_GSBASE: - case TARGET_FREEBSD_AMD64_GET_FSBASE: - if (op == TARGET_FREEBSD_AMD64_GET_GSBASE) -#endif - idx = R_GS; - else - idx = R_FS; - val = env->segs[idx].base; - if (put_user(val, parms, abi_ulong)) - return -TARGET_EFAULT; - break; - /* XXX handle the others... */ - default: - ret = -TARGET_EINVAL; - break; - } - return ret; -} -#endif - #ifdef __FreeBSD__ /* * XXX this uses the undocumented oidfmt interface to find the kind of From 11c7b43faa1d19c94524984c878479d14a7194f6 Mon Sep 17 00:00:00 2001 From: Warner Losh Date: Mon, 20 Sep 2021 13:56:06 -0600 Subject: [PATCH 22/23] bsd-user: Rename sigqueue to qemu_sigqueue MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit To avoid a name clash with FreeBSD's sigqueue data structure in signalvar.h, rename sigqueue to qemu_sigqueue. This structure is currently defined, but unused. Signed-off-by: Warner Losh Reviewed-by: Richard Henderson Reviewed-by: Philippe Mathieu-Daudé Reviewed-by: Kyle Evans --- bsd-user/qemu.h | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/bsd-user/qemu.h b/bsd-user/qemu.h index e65e41d53d..ba15b1b56f 100644 --- a/bsd-user/qemu.h +++ b/bsd-user/qemu.h @@ -73,15 +73,15 @@ struct image_info { #define MAX_SIGQUEUE_SIZE 1024 -struct sigqueue { - struct sigqueue *next; +struct qemu_sigqueue { + struct qemu_sigqueue *next; + target_siginfo_t info; }; struct emulated_sigtable { int pending; /* true if signal is pending */ - struct sigqueue *first; - /* in order to always have memory for the first signal, we put it here */ - struct sigqueue info; + struct qemu_sigqueue *first; + struct qemu_sigqueue info; /* Put first signal info here */ }; /* @@ -95,8 +95,8 @@ typedef struct TaskState { struct image_info *info; struct emulated_sigtable sigtab[TARGET_NSIG]; - struct sigqueue sigqueue_table[MAX_SIGQUEUE_SIZE]; /* siginfo queue */ - struct sigqueue *first_free; /* first free siginfo queue entry */ + struct qemu_sigqueue sigqueue_table[MAX_SIGQUEUE_SIZE]; /* siginfo queue */ + struct qemu_sigqueue *first_free; /* first free siginfo queue entry */ int signal_pending; /* non zero if a signal may be pending */ uint8_t stack[]; From 5abfac277d25feb5f12332422c03ea1cb21c6aa1 Mon Sep 17 00:00:00 2001 From: Warner Losh Date: Tue, 21 Sep 2021 16:20:52 -0600 Subject: [PATCH 23/23] bsd-user/signal: Create a dummy signal queueing function Create dummy signal queueing function so we can start to integrate other architectures (at the cost of signals remaining broken) to tame the dependency graph a bit and to bring in signals in a more controlled fashion. Log unimplemented events to it in the mean time. Signed-off-by: Warner Losh Reviewed-by: Richard Henderson Reviewed-by: Kyle Evans --- bsd-user/qemu.h | 2 +- bsd-user/signal.c | 11 ++++++++++- 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/bsd-user/qemu.h b/bsd-user/qemu.h index ba15b1b56f..1b3b974afe 100644 --- a/bsd-user/qemu.h +++ b/bsd-user/qemu.h @@ -17,7 +17,6 @@ #ifndef QEMU_H #define QEMU_H - #include "qemu/osdep.h" #include "cpu.h" #include "qemu/units.h" @@ -209,6 +208,7 @@ void process_pending_signals(CPUArchState *cpu_env); void signal_init(void); long do_sigreturn(CPUArchState *env); long do_rt_sigreturn(CPUArchState *env); +void queue_signal(CPUArchState *env, int sig, target_siginfo_t *info); abi_long do_sigaltstack(abi_ulong uss_addr, abi_ulong uoss_addr, abi_ulong sp); /* mmap.c */ diff --git a/bsd-user/signal.c b/bsd-user/signal.c index ad6d935569..0c1093deb1 100644 --- a/bsd-user/signal.c +++ b/bsd-user/signal.c @@ -16,10 +16,19 @@ * 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/osdep.h" #include "qemu.h" +/* + * Queue a signal so that it will be send to the virtual CPU as soon as + * possible. + */ +void queue_signal(CPUArchState *env, int sig, target_siginfo_t *info) +{ + qemu_log_mask(LOG_UNIMP, "No signal queueing, dropping signal %d\n", sig); +} + void signal_init(void) { }