You can subscribe to this list here.
2002 |
Jan
|
Feb
|
Mar
|
Apr
|
May
|
Jun
|
Jul
|
Aug
|
Sep
(1) |
Oct
(122) |
Nov
(152) |
Dec
(69) |
---|---|---|---|---|---|---|---|---|---|---|---|---|
2003 |
Jan
(6) |
Feb
(25) |
Mar
(73) |
Apr
(82) |
May
(24) |
Jun
(25) |
Jul
(10) |
Aug
(11) |
Sep
(10) |
Oct
(54) |
Nov
(203) |
Dec
(182) |
2004 |
Jan
(307) |
Feb
(305) |
Mar
(430) |
Apr
(312) |
May
(187) |
Jun
(342) |
Jul
(487) |
Aug
(637) |
Sep
(336) |
Oct
(373) |
Nov
(441) |
Dec
(210) |
2005 |
Jan
(385) |
Feb
(480) |
Mar
(636) |
Apr
(544) |
May
(679) |
Jun
(625) |
Jul
(810) |
Aug
(838) |
Sep
(634) |
Oct
(521) |
Nov
(965) |
Dec
(543) |
2006 |
Jan
(494) |
Feb
(431) |
Mar
(546) |
Apr
(411) |
May
(406) |
Jun
(322) |
Jul
(256) |
Aug
(401) |
Sep
(345) |
Oct
(542) |
Nov
(308) |
Dec
(481) |
2007 |
Jan
(427) |
Feb
(326) |
Mar
(367) |
Apr
(255) |
May
(244) |
Jun
(204) |
Jul
(223) |
Aug
(231) |
Sep
(354) |
Oct
(374) |
Nov
(497) |
Dec
(362) |
2008 |
Jan
(322) |
Feb
(482) |
Mar
(658) |
Apr
(422) |
May
(476) |
Jun
(396) |
Jul
(455) |
Aug
(267) |
Sep
(280) |
Oct
(253) |
Nov
(232) |
Dec
(304) |
2009 |
Jan
(486) |
Feb
(470) |
Mar
(458) |
Apr
(423) |
May
(696) |
Jun
(461) |
Jul
(551) |
Aug
(575) |
Sep
(134) |
Oct
(110) |
Nov
(157) |
Dec
(102) |
2010 |
Jan
(226) |
Feb
(86) |
Mar
(147) |
Apr
(117) |
May
(107) |
Jun
(203) |
Jul
(193) |
Aug
(238) |
Sep
(300) |
Oct
(246) |
Nov
(23) |
Dec
(75) |
2011 |
Jan
(133) |
Feb
(195) |
Mar
(315) |
Apr
(200) |
May
(267) |
Jun
(293) |
Jul
(353) |
Aug
(237) |
Sep
(278) |
Oct
(611) |
Nov
(274) |
Dec
(260) |
2012 |
Jan
(303) |
Feb
(391) |
Mar
(417) |
Apr
(441) |
May
(488) |
Jun
(655) |
Jul
(590) |
Aug
(610) |
Sep
(526) |
Oct
(478) |
Nov
(359) |
Dec
(372) |
2013 |
Jan
(467) |
Feb
(226) |
Mar
(391) |
Apr
(281) |
May
(299) |
Jun
(252) |
Jul
(311) |
Aug
(352) |
Sep
(481) |
Oct
(571) |
Nov
(222) |
Dec
(231) |
2014 |
Jan
(185) |
Feb
(329) |
Mar
(245) |
Apr
(238) |
May
(281) |
Jun
(399) |
Jul
(382) |
Aug
(500) |
Sep
(579) |
Oct
(435) |
Nov
(487) |
Dec
(256) |
2015 |
Jan
(338) |
Feb
(357) |
Mar
(330) |
Apr
(294) |
May
(191) |
Jun
(108) |
Jul
(142) |
Aug
(261) |
Sep
(190) |
Oct
(54) |
Nov
(83) |
Dec
(22) |
2016 |
Jan
(49) |
Feb
(89) |
Mar
(33) |
Apr
(50) |
May
(27) |
Jun
(34) |
Jul
(53) |
Aug
(53) |
Sep
(98) |
Oct
(206) |
Nov
(93) |
Dec
(53) |
2017 |
Jan
(65) |
Feb
(82) |
Mar
(102) |
Apr
(86) |
May
(187) |
Jun
(67) |
Jul
(23) |
Aug
(93) |
Sep
(65) |
Oct
(45) |
Nov
(35) |
Dec
(17) |
2018 |
Jan
(26) |
Feb
(35) |
Mar
(38) |
Apr
(32) |
May
(8) |
Jun
(43) |
Jul
(27) |
Aug
(30) |
Sep
(43) |
Oct
(42) |
Nov
(38) |
Dec
(67) |
2019 |
Jan
(32) |
Feb
(37) |
Mar
(53) |
Apr
(64) |
May
(49) |
Jun
(18) |
Jul
(14) |
Aug
(53) |
Sep
(25) |
Oct
(30) |
Nov
(49) |
Dec
(31) |
2020 |
Jan
(87) |
Feb
(45) |
Mar
(37) |
Apr
(51) |
May
(99) |
Jun
(36) |
Jul
(11) |
Aug
(14) |
Sep
(20) |
Oct
(24) |
Nov
(40) |
Dec
(23) |
2021 |
Jan
(14) |
Feb
(53) |
Mar
(85) |
Apr
(15) |
May
(19) |
Jun
(3) |
Jul
(14) |
Aug
(1) |
Sep
(57) |
Oct
(73) |
Nov
(56) |
Dec
(22) |
2022 |
Jan
(3) |
Feb
(22) |
Mar
(6) |
Apr
(55) |
May
(46) |
Jun
(39) |
Jul
(15) |
Aug
(9) |
Sep
(11) |
Oct
(34) |
Nov
(20) |
Dec
(36) |
2023 |
Jan
(79) |
Feb
(41) |
Mar
(99) |
Apr
(169) |
May
(48) |
Jun
(16) |
Jul
(16) |
Aug
(57) |
Sep
(83) |
Oct
(89) |
Nov
(97) |
Dec
(30) |
2024 |
Jan
(25) |
Feb
(73) |
Mar
(76) |
Apr
(122) |
May
(46) |
Jun
(44) |
Jul
(27) |
Aug
(30) |
Sep
(33) |
Oct
(67) |
Nov
(91) |
Dec
(70) |
2025 |
Jan
(44) |
Feb
(36) |
Mar
(85) |
Apr
(100) |
May
(138) |
Jun
(55) |
Jul
(107) |
Aug
(9) |
Sep
|
Oct
|
Nov
|
Dec
|
From: Florian K. <fk...@so...> - 2025-07-20 09:01:26
|
https://sourceware.org/cgit/valgrind/commit/?id=1c9d639ecedbb98c01d1bbf30c43d119487ab0b4 commit 1c9d639ecedbb98c01d1bbf30c43d119487ab0b4 Author: Florian Krohm <fl...@ei...> Date: Sun Jul 20 08:58:46 2025 +0000 s390x: Fix crash when constant folding is disabled (BZ 507173) Followup to 942a48c1d which fixed the register usage of conditional moves for s390_insn_get_reg_usage. A similar fix is needed for s390_insn_map_regs considering the case when the condition is S390_CC_NEVER. Fixes https://bugs.kde.org/show_bug.cgi?id=507173 Diff: --- NEWS | 1 + VEX/priv/host_s390_defs.c | 6 ++++-- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/NEWS b/NEWS index 29e2274eae..d52bba0c2f 100644 --- a/NEWS +++ b/NEWS @@ -61,6 +61,7 @@ are not entered into bugzilla tend to get forgotten about or ignored. 506910 openat2 with RESOLVE_NO_MAGICLINKS succeeds on /proc/self/exe 506930 valgrind allows SIGKILL being reset to SIG_DFL 506970 mmap needs an EBADF fd_allowed check +507173 s390x: Crash when constant folding is disabled To see details of a given bug, visit https://bugs.kde.org/show_bug.cgi?id=XXXXXX diff --git a/VEX/priv/host_s390_defs.c b/VEX/priv/host_s390_defs.c index 08a34a5fa9..1ee1696b30 100644 --- a/VEX/priv/host_s390_defs.c +++ b/VEX/priv/host_s390_defs.c @@ -1118,8 +1118,10 @@ s390_insn_map_regs(HRegRemap *m, s390_insn *insn) break; case S390_INSN_COND_MOVE: - insn->variant.cond_move.dst = lookupHRegRemap(m, insn->variant.cond_move.dst); - s390_opnd_RMI_map_regs(m, &insn->variant.cond_move.src); + if (insn->variant.cond_move.cond != S390_CC_NEVER) { + insn->variant.cond_move.dst = lookupHRegRemap(m, insn->variant.cond_move.dst); + s390_opnd_RMI_map_regs(m, &insn->variant.cond_move.src); + } break; case S390_INSN_LOAD_IMMEDIATE: |
From: Florian K. <fk...@so...> - 2025-07-20 08:41:42
|
https://sourceware.org/cgit/valgrind/commit/?id=42a1a2e601dd2860405a3475aeefbdfea144bd58 commit 42a1a2e601dd2860405a3475aeefbdfea144bd58 Author: Florian Krohm <fl...@ei...> Date: Sun Jul 20 08:39:40 2025 +0000 fdleak.h: Mark close_inherited as possible unused because it is. Avoids compiler warning for track_bad.c Diff: --- none/tests/fdleak.h | 1 + 1 file changed, 1 insertion(+) diff --git a/none/tests/fdleak.h b/none/tests/fdleak.h index f0a6eac493..54c4895dba 100644 --- a/none/tests/fdleak.h +++ b/none/tests/fdleak.h @@ -26,6 +26,7 @@ * - For Ubuntu 8.04, see also * https://bugs.launchpad.net/ubuntu/+source/seahorse/+bug/235184 */ +__attribute__((unused)) static void close_inherited (void) { struct stat sb; int i; int max_fds = sysconf (_SC_OPEN_MAX); |
From: Paul F. <pa...@so...> - 2025-07-20 08:20:24
|
https://sourceware.org/cgit/valgrind/commit/?id=282fd0d3eb2b8d0b289b35311b05db4acddfdc14 commit 282fd0d3eb2b8d0b289b35311b05db4acddfdc14 Author: Paul Floyd <pj...@wa...> Date: Sun Jul 20 10:19:00 2025 +0200 FreeBSD regtest: make memcheck/tests/freebsd/setcred consistent on arm64 and amd64 Was getting different errors due to the contents of junk pointers. Diff: --- memcheck/tests/freebsd/setcred.cpp | 9 +++++++-- memcheck/tests/freebsd/setcred.stderr.exp | 19 +++++++++---------- 2 files changed, 16 insertions(+), 12 deletions(-) diff --git a/memcheck/tests/freebsd/setcred.cpp b/memcheck/tests/freebsd/setcred.cpp index 7553599dfc..464de08efe 100644 --- a/memcheck/tests/freebsd/setcred.cpp +++ b/memcheck/tests/freebsd/setcred.cpp @@ -1,14 +1,18 @@ #include <sys/ucred.h> #include <cstring> +#include <cstdlib> + +static long x0; int main() { + long *px{static_cast<long*>(malloc(2*sizeof(long)))}; + x0 = px[0]; struct setcred cred1; struct setcred* cred2; int flags1{0}; int flags2; size_t size1{sizeof(cred1)}; - size_t size2; std::memset(&cred1, 250, sizeof(cred1)); @@ -19,7 +23,7 @@ int main() setcred(flags1, nullptr, size1); // uninit - setcred(flags2, cred2, size2); + setcred(flags2, (struct setcred*)x0, size1+x0); cred2 = new struct setcred; @@ -27,5 +31,6 @@ int main() setcred(flags1, cred2, size1); delete cred2; + free(px); } diff --git a/memcheck/tests/freebsd/setcred.stderr.exp b/memcheck/tests/freebsd/setcred.stderr.exp index 1d9cecf8e3..629ceacf84 100644 --- a/memcheck/tests/freebsd/setcred.stderr.exp +++ b/memcheck/tests/freebsd/setcred.stderr.exp @@ -1,30 +1,29 @@ Syscall param setcred(wcred) points to unaddressable byte(s) at 0x........: setcred (in /...libc...) - by 0x........: main (setcred.cpp:19) + by 0x........: main (setcred.cpp:23) Address 0x........ is not stack'd, malloc'd or (recently) free'd Syscall param setcred(flags) contains uninitialised byte(s) at 0x........: setcred (in /...libc...) - by 0x........: main (setcred.cpp:22) + by 0x........: main (setcred.cpp:26) Syscall param setcred(wcred) contains uninitialised byte(s) at 0x........: setcred (in /...libc...) - by 0x........: main (setcred.cpp:22) + by 0x........: main (setcred.cpp:26) Syscall param setcred(size) contains uninitialised byte(s) at 0x........: setcred (in /...libc...) - by 0x........: main (setcred.cpp:22) + by 0x........: main (setcred.cpp:26) -Syscall param setcred(wcred) points to uninitialised byte(s) +Syscall param setcred(wcred) points to unaddressable byte(s) at 0x........: setcred (in /...libc...) - by 0x........: main (setcred.cpp:22) - Address 0x........ is on thread 1's stack - in frame #2, created by __libc_start1 (???:) + by 0x........: main (setcred.cpp:26) + Address 0x........ is not stack'd, malloc'd or (recently) free'd Syscall param setcred(wcred) points to uninitialised byte(s) at 0x........: setcred (in /...libc...) - by 0x........: main (setcred.cpp:27) + by 0x........: main (setcred.cpp:31) Address 0x........ is 0 bytes inside a block of size 48 alloc'd at 0x........: ...operator new... (vg_replace_malloc.c:...) - by 0x........: main (setcred.cpp:24) + by 0x........: main (setcred.cpp:28) |
From: Paul F. <pa...@so...> - 2025-07-20 08:01:28
|
https://sourceware.org/cgit/valgrind/commit/?id=5ae51164205ea47d20c3c7c215d563daf43b7ca1 commit 5ae51164205ea47d20c3c7c215d563daf43b7ca1 Author: Paul Floyd <pj...@wa...> Date: Sun Jul 20 09:59:51 2025 +0200 FreeBSD regtest: filter leak from memcheck/tests/gone_abrt_xml On amd64 there is a suppressed reachable that shows up in the leak summary. On arm64 there is no leak. So add a filter for leaks in xml files. Diff: --- memcheck/tests/Makefile.am | 1 + memcheck/tests/filter_xml_leak | 5 +++++ memcheck/tests/gone_abrt_xml.stderr.exp-freebsd | 2 -- memcheck/tests/gone_abrt_xml.vgtest | 2 +- 4 files changed, 7 insertions(+), 3 deletions(-) diff --git a/memcheck/tests/Makefile.am b/memcheck/tests/Makefile.am index 860cb2076f..aceed97b27 100644 --- a/memcheck/tests/Makefile.am +++ b/memcheck/tests/Makefile.am @@ -82,6 +82,7 @@ dist_noinst_SCRIPTS = \ filter_leak_cpp_interior \ filter_libc_variants \ filter_xml \ + filter_xml_leak \ filter_strchr \ filter_varinfo3 \ filter_memcheck \ diff --git a/memcheck/tests/filter_xml_leak b/memcheck/tests/filter_xml_leak new file mode 100755 index 0000000000..31418f48d6 --- /dev/null +++ b/memcheck/tests/filter_xml_leak @@ -0,0 +1,5 @@ +#!/bin/sh + +./filter_xml "$@" | + +sed -e '/<leak_summary>...<\/leak_summary>/,+1d' diff --git a/memcheck/tests/gone_abrt_xml.stderr.exp-freebsd b/memcheck/tests/gone_abrt_xml.stderr.exp-freebsd index 04643bbffa..6f8d7ec922 100644 --- a/memcheck/tests/gone_abrt_xml.stderr.exp-freebsd +++ b/memcheck/tests/gone_abrt_xml.stderr.exp-freebsd @@ -55,8 +55,6 @@ aborting ... <heap_summary>...</heap_summary> -<leak_summary>...</leak_summary> - <errorcounts> </errorcounts> diff --git a/memcheck/tests/gone_abrt_xml.vgtest b/memcheck/tests/gone_abrt_xml.vgtest index dc18192d19..6e2c5d504b 100644 --- a/memcheck/tests/gone_abrt_xml.vgtest +++ b/memcheck/tests/gone_abrt_xml.vgtest @@ -1,5 +1,5 @@ prog: ../../gdbserver_tests/gone args: abort vgopts: --xml=yes --xml-fd=2 --log-file=/dev/null -stderr_filter: filter_xml +stderr_filter: filter_xml_leak cleanup: rm -f vgcore.* |
From: Paul F. <pa...@so...> - 2025-07-20 05:47:43
|
https://sourceware.org/cgit/valgrind/commit/?id=c9f166b67728202906ff8f52a9e5c90ff25543fc commit c9f166b67728202906ff8f52a9e5c90ff25543fc Author: Paul Floyd <pj...@wa...> Date: Sun Jul 20 07:46:47 2025 +0200 Linux regtest: fix build of tests on old systems without openat2 Diff: --- none/tests/linux/Makefile.am | 10 +++++++--- none/tests/linux/bug506910.vgtest | 1 + none/tests/linux/open_client.vgtest | 1 + 3 files changed, 9 insertions(+), 3 deletions(-) diff --git a/none/tests/linux/Makefile.am b/none/tests/linux/Makefile.am index c20b2d2d01..7bfcedc862 100644 --- a/none/tests/linux/Makefile.am +++ b/none/tests/linux/Makefile.am @@ -27,7 +27,6 @@ check_PROGRAMS = \ brk-overflow1 \ brk-overflow2 \ bug498317 \ - bug506910 \ clonev \ mremap \ mremap2 \ @@ -35,10 +34,13 @@ check_PROGRAMS = \ mremap4 \ mremap5 \ mremap6 \ - open_client \ pthread-stack \ stack-overflow +if HAVE_OPENAT2 + check_PROGRAMS += bug506910 open_client +endif + if HAVE_NR_MEMBARRIER check_PROGRAMS += membarrier endif @@ -48,9 +50,11 @@ AM_CFLAGS += $(AM_FLAG_M3264_PRI) AM_CXXFLAGS += $(AM_FLAG_M3264_PRI) # Special needs +if HAVE_OPENAT2 bug506910_SOURCES = bug506910.cpp -clonev_LDADD = -lpthread open_client_SOURCES = open_client.cpp +endif +clonev_LDADD = -lpthread pthread_stack_LDADD = -lpthread stack_overflow_CFLAGS = $(AM_CFLAGS) @FLAG_W_NO_UNINITIALIZED@ \ diff --git a/none/tests/linux/bug506910.vgtest b/none/tests/linux/bug506910.vgtest index 28e3f29751..b23362548e 100644 --- a/none/tests/linux/bug506910.vgtest +++ b/none/tests/linux/bug506910.vgtest @@ -1 +1,2 @@ +prereq: test -x bug506910 prog: bug506910 diff --git a/none/tests/linux/open_client.vgtest b/none/tests/linux/open_client.vgtest index 6b930efe6c..05eba98bb5 100644 --- a/none/tests/linux/open_client.vgtest +++ b/none/tests/linux/open_client.vgtest @@ -1,2 +1,3 @@ +prereq: test -x open_client prog: open_client vgopts: -q |
From: Mark W. <ma...@so...> - 2025-07-19 21:08:58
|
https://sourceware.org/cgit/valgrind/commit/?id=769ca880912f26f3b6033bfe08e7417580b02c25 commit 769ca880912f26f3b6033bfe08e7417580b02c25 Author: Mark Wielaard <ma...@kl...> Date: Sat Jul 19 22:19:08 2025 +0200 Just set filename ARG to handle /proc/self/exe in open, openat and openat2 This simplifies the logic a little and makes reasoning about how the PRE handler works slightly simpler. Diff: --- coregrind/m_syswrap/syswrap-generic.c | 3 +-- coregrind/m_syswrap/syswrap-linux.c | 6 ++---- 2 files changed, 3 insertions(+), 6 deletions(-) diff --git a/coregrind/m_syswrap/syswrap-generic.c b/coregrind/m_syswrap/syswrap-generic.c index 280b1ccb6a..7ac86fbbc0 100644 --- a/coregrind/m_syswrap/syswrap-generic.c +++ b/coregrind/m_syswrap/syswrap-generic.c @@ -4692,8 +4692,7 @@ PRE(sys_open) if (proc_self_exe) { // do the syscall with VG_(resolved_exename) - SET_STATUS_from_SysRes(VG_(do_syscall3)(SYSNO, (Word)VG_(resolved_exename), ARG2, ARG3)); - return; + ARG1 = (Word)VG_(resolved_exename); } #endif // defined(VGO_linux) diff --git a/coregrind/m_syswrap/syswrap-linux.c b/coregrind/m_syswrap/syswrap-linux.c index d1cfdad69a..552fceee8d 100644 --- a/coregrind/m_syswrap/syswrap-linux.c +++ b/coregrind/m_syswrap/syswrap-linux.c @@ -6094,8 +6094,7 @@ no_client_write: if (proc_self_exe) { // do the syscall with VG_(resolved_exename) - SET_STATUS_from_SysRes(VG_(do_syscall4)(SYSNO, ARG1, (Word)VG_(resolved_exename), ARG3, ARG4)); - return; + ARG2 = (Word)VG_(resolved_exename); } /* Otherwise handle normally */ @@ -14095,8 +14094,7 @@ PRE(sys_openat2) if (proc_self_exe) { // do the syscall with VG_(resolved_exename) - SET_STATUS_from_SysRes(VG_(do_syscall4)(SYSNO, ARG1, (Word)VG_(resolved_exename), ARG3, ARG4)); - return; + ARG2 = (Word)VG_(resolved_exename); } /* Otherwise handle normally */ |
From: Paul F. <pa...@so...> - 2025-07-19 20:19:12
|
https://sourceware.org/cgit/valgrind/commit/?id=3c78edc2da61abfdbb494ec0437ca7ecafc3f278 commit 3c78edc2da61abfdbb494ec0437ca7ecafc3f278 Author: Paul Floyd <pj...@wa...> Date: Sat Jul 19 22:13:15 2025 +0200 Linux arm64 and riscv64: for build for VG_(lstat) These 'new' architectures don't have 'old' syscalls like __NR_lstat so use __NR_newfstatat instead. Also modify the oen_client testcase so that it checks for the 'old' open syscall. Diff: --- coregrind/m_libcfile.c | 25 +++++++++++++++++++++---- none/tests/linux/open_client.cpp | 4 ++++ 2 files changed, 25 insertions(+), 4 deletions(-) diff --git a/coregrind/m_libcfile.c b/coregrind/m_libcfile.c index ff1ead4e71..6addb87610 100644 --- a/coregrind/m_libcfile.c +++ b/coregrind/m_libcfile.c @@ -680,17 +680,34 @@ SysRes VG_(lstat) ( const HChar* file_name, struct vg_stat* vgbuf ) SysRes res; VG_(memset)(vgbuf, 0, sizeof(*vgbuf)); -#if !defined(VGO_freebsd) || (__FreeBSD_version < 1200031) -#if defined(VGO_freebsd) - struct vki_freebsd11_stat buf; +#if defined(VGO_linux) + +struct vki_stat buf; + +#if defined(__NR_newfstatat) + res = VG_(do_syscall4)(__NR_newfstatat, VKI_AT_FDCWD, (UWord)file_name, (UWord)&buf, VKI_AT_SYMLINK_NOFOLLOW); #else - struct vki_stat buf; + res = VG_(do_syscall2)(__NR_lstat, (UWord)file_name, (UWord)&buf); #endif + +#elif defined(VGO_freebsd) + +#if (__FreeBSD_version < 1200031) + struct vki_freebsd11_stat buf; res = VG_(do_syscall2)(__NR_lstat, (UWord)file_name, (UWord)&buf); #else struct vki_stat buf; res = VG_(do_syscall4)(__NR_fstatat, VKI_AT_FDCWD, (UWord)file_name, (UWord)&buf, VKI_AT_SYMLINK_NOFOLLOW); #endif + +#else + + /* check this on illumos and Darwin */ + struct vki_stat buf; + res = VG_(do_syscall2)(__NR_lstat, (UWord)file_name, (UWord)&buf); + +#endif + if (!sr_isError(res)) { TRANSLATE_TO_vg_stat(vgbuf, &buf); } diff --git a/none/tests/linux/open_client.cpp b/none/tests/linux/open_client.cpp index 4b336e7f02..2052286d49 100644 --- a/none/tests/linux/open_client.cpp +++ b/none/tests/linux/open_client.cpp @@ -36,6 +36,7 @@ int main(int argc, char** argv) } } +#if defined(SYS_open) for (auto f : flags) { int res = syscall(SYS_open, n.c_str(), f, 0666); @@ -52,6 +53,7 @@ int main(int argc, char** argv) } } } +#endif } if ((dotdot = open("..", O_DIRECTORY | O_RDONLY)) == -1) @@ -154,6 +156,7 @@ int main(int argc, char** argv) } } +#if defined(SYS_open) for (auto f : flags) { int res = syscall(SYS_open, "linux/open_client", f, 0666); @@ -169,6 +172,7 @@ int main(int argc, char** argv) } } } +#endif #if defined(SYS_openat2) for (auto f : flags) |
From: Paul F. <pa...@so...> - 2025-07-19 16:21:59
|
https://sourceware.org/cgit/valgrind/commit/?id=088ac305a2f27b4d8d5822bace59742719cc84d5 commit 088ac305a2f27b4d8d5822bace59742719cc84d5 Author: Paul Floyd <pj...@wa...> Date: Sat Jul 19 18:17:35 2025 +0200 Bug 506910 - openat2 with RESOLVE_NO_MAGICLINKS succeeds on /proc/self/exe Previous change did most of the work but need to return without setting SfMayBlock. Add a testcase covering /proc/self/exe and /proc/PID/exe. Diff: --- .gitignore | 1 + NEWS | 1 + coregrind/m_syswrap/syswrap-generic.c | 1 + coregrind/m_syswrap/syswrap-linux.c | 3 ++- none/tests/linux/Makefile.am | 3 +++ none/tests/linux/bug506910.cpp | 44 +++++++++++++++++++++++++++++++++++ none/tests/linux/bug506910.stderr.exp | 2 ++ none/tests/linux/bug506910.vgtest | 1 + 8 files changed, 55 insertions(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index 44454d08bb..0da54a7ebf 100644 --- a/.gitignore +++ b/.gitignore @@ -1885,6 +1885,7 @@ /none/tests/linux/brk-overflow1 /none/tests/linux/brk-overflow2 /none/tests/linux/bug498317 +/none/tests/linux/bug506910 /none/tests/linux/clonev /none/tests/linux/Makefile /none/tests/linux/Makefile.in diff --git a/NEWS b/NEWS index af88103641..29e2274eae 100644 --- a/NEWS +++ b/NEWS @@ -58,6 +58,7 @@ are not entered into bugzilla tend to get forgotten about or ignored. 506499 Unhandled syscall 592 (exterrctl - FreeBSD 506795 Better report which clone flags are problematic 506928 Wrap (deprecated) linux specific ustat syscall +506910 openat2 with RESOLVE_NO_MAGICLINKS succeeds on /proc/self/exe 506930 valgrind allows SIGKILL being reset to SIG_DFL 506970 mmap needs an EBADF fd_allowed check diff --git a/coregrind/m_syswrap/syswrap-generic.c b/coregrind/m_syswrap/syswrap-generic.c index 727766869f..280b1ccb6a 100644 --- a/coregrind/m_syswrap/syswrap-generic.c +++ b/coregrind/m_syswrap/syswrap-generic.c @@ -4693,6 +4693,7 @@ PRE(sys_open) if (proc_self_exe) { // do the syscall with VG_(resolved_exename) SET_STATUS_from_SysRes(VG_(do_syscall3)(SYSNO, (Word)VG_(resolved_exename), ARG2, ARG3)); + return; } #endif // defined(VGO_linux) diff --git a/coregrind/m_syswrap/syswrap-linux.c b/coregrind/m_syswrap/syswrap-linux.c index e16d293cd0..d1cfdad69a 100644 --- a/coregrind/m_syswrap/syswrap-linux.c +++ b/coregrind/m_syswrap/syswrap-linux.c @@ -6095,6 +6095,7 @@ no_client_write: // do the syscall with VG_(resolved_exename) SET_STATUS_from_SysRes(VG_(do_syscall4)(SYSNO, ARG1, (Word)VG_(resolved_exename), ARG3, ARG4)); + return; } /* Otherwise handle normally */ @@ -14093,9 +14094,9 @@ PRE(sys_openat2) } if (proc_self_exe) { - // do the syscall with VG_(resolved_exename) SET_STATUS_from_SysRes(VG_(do_syscall4)(SYSNO, ARG1, (Word)VG_(resolved_exename), ARG3, ARG4)); + return; } /* Otherwise handle normally */ diff --git a/none/tests/linux/Makefile.am b/none/tests/linux/Makefile.am index c81ffff548..c20b2d2d01 100644 --- a/none/tests/linux/Makefile.am +++ b/none/tests/linux/Makefile.am @@ -8,6 +8,7 @@ EXTRA_DIST = \ brk-overflow1.stderr.exp brk-overflow1.vgtest \ brk-overflow2.stderr.exp brk-overflow2.vgtest \ bug498317.stderr.exp bug498317.supp bug498317.vgtest \ + bug506910.stderr.exp bug506910.vgtest \ clonev.stdout.exp clonev.stderr.exp clonev.vgtest \ membarrier.stderr.exp membarrier.vgtest \ mremap.stderr.exp mremap.stderr.exp-glibc27 mremap.stdout.exp \ @@ -26,6 +27,7 @@ check_PROGRAMS = \ brk-overflow1 \ brk-overflow2 \ bug498317 \ + bug506910 \ clonev \ mremap \ mremap2 \ @@ -46,6 +48,7 @@ AM_CFLAGS += $(AM_FLAG_M3264_PRI) AM_CXXFLAGS += $(AM_FLAG_M3264_PRI) # Special needs +bug506910_SOURCES = bug506910.cpp clonev_LDADD = -lpthread open_client_SOURCES = open_client.cpp pthread_stack_LDADD = -lpthread diff --git a/none/tests/linux/bug506910.cpp b/none/tests/linux/bug506910.cpp new file mode 100644 index 0000000000..2dbadf56a2 --- /dev/null +++ b/none/tests/linux/bug506910.cpp @@ -0,0 +1,44 @@ +// For Bug 5056910 +// openat2 with RESOLVE_NO_MAGICLINKS succeeds on /proc/self/exe +#include <fcntl.h> +#include <cerrno> +#include <stdexcept> +#include <string> +#include <unistd.h> +#include <sys/syscall.h> +#include <unistd.h> +#include <linux/openat2.h> + +int main(int argc, char** argv) +{ + auto pid = getpid(); + auto ppe = std::string("/proc/") + std::to_string(pid) + "/exe"; +#if defined(SYS_openat2) + struct open_how oh = { .flags=O_RDONLY, .mode=0UL, .resolve=RESOLVE_NO_MAGICLINKS }; + int res = syscall(SYS_openat2, AT_FDCWD, "/proc/self/exe", &oh, sizeof(oh)); + if (-1 != res) + { + throw std::runtime_error("openat2 should have failed"); + } + else + { + if (errno != ELOOP) + { + throw std::runtime_error("errno should be ELOOP"); + } + } + + res = syscall(SYS_openat2, AT_FDCWD, ppe.c_str(), &oh, sizeof(oh)); + if (-1 != res) + { + throw std::runtime_error("openat2 should have failed"); + } + else + { + if (errno != ELOOP) + { + throw std::runtime_error("errno should be ELOOP"); + } + } +#endif +} diff --git a/none/tests/linux/bug506910.stderr.exp b/none/tests/linux/bug506910.stderr.exp new file mode 100644 index 0000000000..139597f9cb --- /dev/null +++ b/none/tests/linux/bug506910.stderr.exp @@ -0,0 +1,2 @@ + + diff --git a/none/tests/linux/bug506910.vgtest b/none/tests/linux/bug506910.vgtest new file mode 100644 index 0000000000..28e3f29751 --- /dev/null +++ b/none/tests/linux/bug506910.vgtest @@ -0,0 +1 @@ +prog: bug506910 |
From: Paul F. <pa...@so...> - 2025-07-19 15:10:49
|
https://sourceware.org/cgit/valgrind/commit/?id=7fb17b67f40eb8197c45b5f575daf4fa77d16faa commit 7fb17b67f40eb8197c45b5f575daf4fa77d16faa Author: Paul Floyd <pj...@wa...> Date: Sat Jul 19 15:10:31 2025 +0200 Bug 505673 - Valgrind crashes with an internal error and SIGBUS when the guest tries to open its own file with O_WRONLY|O_CREAT|O_TRUNC This is all quite messy. It affects open() openat() and openat2() (the last of which is Linux only). On Linux we also need to check for /proc/self/exe and /proc/PID/exe. On Linux there are also a couple of RESOLVE flags for openat2() that mean _don't_ check /proc magic links. In the general case we need to have some reference to check whether the filename matches the guest filename. So I've added that as VG_(resolved_exename) (which I was already using on FreeBSD). The pathname also needs to be canonicalised. It may be a relative path, symlink or use RESOLVE_IN_ROOT. That uses VG_(realpath) (again which was already present for FreBSD). On illumos the man page says that opening running binaries for writing failes with errno set to ETXTBSY but that's not what the open functions do - they just open the file. So I've done nothing for illumos or Solaris. Maybe I'll open an illumos ticket. I haven't tried on Darwin. The Linux open functions with /proc/self/exe and /proc/PID/exe were just calling dup on the fd that we hold for the client exe. That means that we were ignoring any other flags. That has now changed. If the open doesn't fail because the WRONLY/RDWR flags are set then the syscall gets called from the PRE wrapper using VG_(resolved_exename) instewad of the /proc pathname. I haven't tried to handle all of the Linux openat2 RESOLVE* flags. RESOLVE_NO_MAGICLINKS is handled and I see the LTS test openat202 now passing, so this should also fix Bug 506910. I'm not sure that VG_(realpath) handles all forms of weird path resolution on Linux (on FreeBSD it uses a syscall so that should work OK). Diff: --- .gitignore | 2 + NEWS | 2 + coregrind/m_initimg/initimg-freebsd.c | 3 + coregrind/m_initimg/initimg-linux.c | 63 +++++- coregrind/m_libcfile.c | 20 +- coregrind/m_syswrap/syswrap-freebsd.c | 33 +++ coregrind/m_syswrap/syswrap-generic.c | 48 ++++- coregrind/m_syswrap/syswrap-linux.c | 222 +++++++++++++++------ coregrind/pub_core_libcfile.h | 3 +- include/pub_tool_libcfile.h | 2 - memcheck/tests/x86-linux/scalar_openat2.stderr.exp | 6 +- none/tests/freebsd/Makefile.am | 6 +- none/tests/freebsd/open_client.cpp | 108 ++++++++++ none/tests/freebsd/open_client.stderr.exp | 0 none/tests/freebsd/open_client.vgtest | 3 + none/tests/linux/Makefile.am | 3 + none/tests/linux/open_client.cpp | 191 ++++++++++++++++++ none/tests/linux/open_client.stderr.exp | 0 none/tests/linux/open_client.vgtest | 2 + 19 files changed, 643 insertions(+), 74 deletions(-) diff --git a/.gitignore b/.gitignore index 69e182f757..44454d08bb 100644 --- a/.gitignore +++ b/.gitignore @@ -1895,6 +1895,7 @@ /none/tests/linux/mremap4 /none/tests/linux/mremap5 /none/tests/linux/mremap6 +/none/tests/linux/open_client /none/tests/linux/pthread-stack /none/tests/linux/stack-overflow @@ -2328,6 +2329,7 @@ none/tests/freebsd/bug499212 /none/tests/freebsd/swapcontext /none/tests/freebsd/fexecve /none/tests/freebsd/hello_world +/none/tests/freebsd/open_client /none/tests/freebsd/proc_pid_file /none/tests/freebsd/sanity_level_thread /none/tests/freebsd/usrstack diff --git a/NEWS b/NEWS index e61b56baf9..af88103641 100644 --- a/NEWS +++ b/NEWS @@ -52,6 +52,8 @@ are not entered into bugzilla tend to get forgotten about or ignored. AMD64_GET_TLSBASE 505228 Wrap linux specific mseal syscall 502968 Wrap linux specific syscalls 457 (listmount) and 458 (statmount) +505673 Valgrind crashes with an internal error and SIGBUS when + the guest tries to open its own file with O_WRONLY|O_CREAT|O_TRUNC 506076 unimplemented fcntl command: 1028 (F_CREATED_QUERY) 506499 Unhandled syscall 592 (exterrctl - FreeBSD 506795 Better report which clone flags are problematic diff --git a/coregrind/m_initimg/initimg-freebsd.c b/coregrind/m_initimg/initimg-freebsd.c index cb98eb9144..5c167e3fb1 100644 --- a/coregrind/m_initimg/initimg-freebsd.c +++ b/coregrind/m_initimg/initimg-freebsd.c @@ -334,6 +334,9 @@ static const struct auxv *find_auxv(const UWord* sp) return (const struct auxv *)sp; } +/* + * @todo PJF Make this multi-platform + */ static Bool try_get_interp(const HChar* args_exe, HChar* interp_out) { HChar hdr[4096]; diff --git a/coregrind/m_initimg/initimg-linux.c b/coregrind/m_initimg/initimg-linux.c index 483b7a3ddd..bcca59da74 100644 --- a/coregrind/m_initimg/initimg-linux.c +++ b/coregrind/m_initimg/initimg-linux.c @@ -385,9 +385,59 @@ struct auxv *find_auxv(UWord* sp) return (struct auxv *)sp; } +/* + * @todo PJF Make this multi-platform + */ +static Bool try_get_interp(const HChar* args_exe, HChar* interp_out) +{ + HChar hdr[4096]; + Int len = sizeof hdr; + SysRes res; + Int fd; + HChar* end; + HChar* cp; + HChar* interp; + + res = VG_(open)(args_exe, VKI_O_RDONLY, 0); + if (sr_isError(res)) { + return False; + } else { + fd = sr_Res(res); + } + + res = VG_(pread)(fd, hdr, len, 0); + + if (sr_isError(res)) { + VG_(close)(fd); + return False; + } else { + len = sr_Res(res); + } + + if (0 != VG_(memcmp)(hdr, "#!", 2)) { + VG_(close)(fd); + return False; + } + + end = hdr + len; + interp = hdr + 2; + while (interp < end && (*interp == ' ' || *interp == '\t')) + interp++; + + for (cp = interp; cp < end && !VG_(isspace)(*cp); cp++) + ; + + *cp = '\0'; + + VG_(sprintf)(interp_out, "%s", interp); + + VG_(close)(fd); + return True; +} + static Addr setup_client_stack( void* init_sp, - HChar** orig_envp, + HChar** orig_envp, const ExeInfo* info, UInt** client_auxv, Addr clstack_end, @@ -953,6 +1003,17 @@ Addr setup_client_stack( void* init_sp, vg_assert((strtab-stringbase) == stringsize); + if (VG_(resolved_exename) == NULL) { + const HChar *exe_name = VG_(find_executable)(VG_(args_the_exename)); + HChar interp_name[VKI_PATH_MAX]; + if (try_get_interp(exe_name, interp_name)) { + exe_name = interp_name; + } + HChar resolved_name[VKI_PATH_MAX]; + VG_(realpath)(exe_name, resolved_name); + VG_(resolved_exename) = VG_(strdup)("initimg-linux.sre.1", resolved_name); + } + /* client_SP is pointing at client's argc/argv */ if (0) VG_(printf)("startup SP = %#lx\n", client_SP); diff --git a/coregrind/m_libcfile.c b/coregrind/m_libcfile.c index 767f34522c..ff1ead4e71 100644 --- a/coregrind/m_libcfile.c +++ b/coregrind/m_libcfile.c @@ -674,15 +674,18 @@ Int VG_(fstat) ( Int fd, struct vg_stat* vgbuf ) # endif } -#if defined(VGO_freebsd) /* extend this to other OSes as and when needed */ SysRes VG_(lstat) ( const HChar* file_name, struct vg_stat* vgbuf ) { SysRes res; VG_(memset)(vgbuf, 0, sizeof(*vgbuf)); -#if (__FreeBSD_version < 1200031) +#if !defined(VGO_freebsd) || (__FreeBSD_version < 1200031) +#if defined(VGO_freebsd) struct vki_freebsd11_stat buf; +#else + struct vki_stat buf; +#endif res = VG_(do_syscall2)(__NR_lstat, (UWord)file_name, (UWord)&buf); #else struct vki_stat buf; @@ -693,7 +696,6 @@ SysRes VG_(lstat) ( const HChar* file_name, struct vg_stat* vgbuf ) } return res; } -#endif #undef TRANSLATE_TO_vg_stat #undef TRANSLATE_statx_TO_vg_stat @@ -1803,7 +1805,6 @@ const HChar *VG_(dirname)(const HChar *path) return buf; } -#if defined(VGO_freebsd) /* * I did look at nicking this from FreeBSD, it's fairly easy to port * but I was put off by the copyright and 3-clause licence @@ -1819,7 +1820,7 @@ Bool VG_(realpath)(const HChar *path, HChar *resolved) { vg_assert(path); vg_assert(resolved); -#if (__FreeBSD_version >= 1300080) +#if defined(VGO_freebsd) && (__FreeBSD_version >= 1300080) return !sr_isError(VG_(do_syscall5)(__NR___realpathat, VKI_AT_FDCWD, (RegWord)path, (RegWord)resolved, VKI_PATH_MAX, 0)); #else // poor man's realpath @@ -1847,7 +1848,13 @@ Bool VG_(realpath)(const HChar *path, HChar *resolved) if (resolved_name[0] == '.' && resolved_name[1] == '/') { resolved_name += 2; } - VG_(snprintf)(resolved, VKI_PATH_MAX, "%s/%s", VG_(get_startup_wd)(), resolved_name); + HChar wd[VKI_PATH_MAX]; +#if defined(VGO_linux) || defined(VGO_solaris) + res = VG_(do_syscall2)(__NR_getcwd, (UWord)wd, VKI_PATH_MAX); +#elif defined(VGO_freebsd) + res = VG_(do_syscall2)(__NR___getcwd, (UWord)wd, VKI_PATH_MAX); +#endif + VG_(snprintf)(resolved, VKI_PATH_MAX, "%s/%s", wd, resolved_name); } else { VG_(snprintf)(resolved, VKI_PATH_MAX, "%s", resolved_name); } @@ -1855,7 +1862,6 @@ Bool VG_(realpath)(const HChar *path, HChar *resolved) return True; #endif } -#endif /*--------------------------------------------------------------------*/ diff --git a/coregrind/m_syswrap/syswrap-freebsd.c b/coregrind/m_syswrap/syswrap-freebsd.c index 79e30f7d37..df223a2a05 100644 --- a/coregrind/m_syswrap/syswrap-freebsd.c +++ b/coregrind/m_syswrap/syswrap-freebsd.c @@ -5347,6 +5347,39 @@ PRE(sys_freebsd11_mknodat) // int openat(int fd, const char *path, int flags, ...); PRE(sys_openat) { + // check that we are not trying to open the client exe for writing + if ((ARG3 & VKI_O_WRONLY) || + (ARG3 & VKI_O_RDWR)) { + vg_assert(VG_(resolved_exename) && VG_(resolved_exename)[0] == '/'); + Int fd = ARG1; + const HChar* path = (const HChar*)ARG2; + if (ML_(safe_to_deref)(path, 1)) { // we need something like a "ML_(safe_to_deref_path)" that does a binary search for the addressable length, and maybe nul + if (fd == VKI_AT_FDCWD) { + HChar tmp[VKI_PATH_MAX]; + if (VG_(realpath)(path, tmp)) { + if (!VG_(strcmp)(tmp, VG_(resolved_exename))) { + SET_STATUS_Failure( VKI_ETXTBSY ); + } + } + } else { + const HChar* dirname; + if (VG_(resolve_filename)(fd, &dirname) == False) { + goto no_client_write; // let the OS do the error handling + } + HChar tmp1[VKI_PATH_MAX]; + VG_(snprintf)(tmp1, VKI_PATH_MAX, "%s/%s", dirname, path); + tmp1[VKI_PATH_MAX - 1] = '\0'; + //VG_(free)((void*)dirname); + HChar tmp2[VKI_PATH_MAX]; + if (VG_(realpath)(tmp1, tmp2)) { + if (!VG_(strcmp)(tmp2, VG_(resolved_exename))) { + SET_STATUS_Failure( VKI_ETXTBSY ); + } + } + } + } + } +no_client_write: if (ARG3 & VKI_O_CREAT) { // 4-arg version PRINT("sys_openat ( %" FMT_REGWORD "u, %#" FMT_REGWORD "x(%s), %" FMT_REGWORD "u, %" FMT_REGWORD "u )",ARG1,ARG2,(char*)ARG2,ARG3,ARG4); diff --git a/coregrind/m_syswrap/syswrap-generic.c b/coregrind/m_syswrap/syswrap-generic.c index 1b3b5e80d6..727766869f 100644 --- a/coregrind/m_syswrap/syswrap-generic.c +++ b/coregrind/m_syswrap/syswrap-generic.c @@ -4602,8 +4602,23 @@ Bool ML_(handle_self_exe_open)(SyscallStatus *status, const HChar *filename, } #endif // defined(VGO_linux) +// int open(const char *path, int flags, mode_t mode); PRE(sys_open) { +#if defined(VGO_linux) + HChar name[30]; // large enough + Bool proc_self_exe = False; + + /* Check for /proc/self/exe or /proc/<pid>/exe case + * first so that we can then use the later checks. */ + VG_(sprintf)(name, "/proc/%d/exe", VG_(getpid)()); + if (ML_(safe_to_deref)( (void*)(Addr)ARG1, 1 ) + && (VG_(strcmp)((HChar *)(Addr)ARG1, name) == 0 + || VG_(strcmp)((HChar *)(Addr)ARG1, "/proc/self/exe") == 0)) { + proc_self_exe = True; + } +#endif + if (ARG2 & VKI_O_CREAT) { // 3-arg version PRINT("sys_open ( %#" FMT_REGWORD "x(%s), %ld, %ld )",ARG1, @@ -4619,13 +4634,39 @@ PRE(sys_open) } PRE_MEM_RASCIIZ( "open(filename)", ARG1 ); + // check that we are not trying to open the client exe for writing + if ((ARG2 & VKI_O_WRONLY) || + (ARG2 & VKI_O_RDWR)) { +#if defined(VGO_linux) + if (proc_self_exe) { + + SET_STATUS_Failure( VKI_ETXTBSY ); + return; + } else { +#endif + vg_assert(VG_(resolved_exename)); + const HChar* path = (const HChar*)ARG1; + if (ML_(safe_to_deref)(path, 1)) { + // we need something like a "ML_(safe_to_deref_path)" that does a binary search for the addressable length, and maybe nul + HChar tmp[VKI_PATH_MAX]; + if (VG_(realpath)(path, tmp)) { + if (!VG_(strcmp)(tmp, VG_(resolved_exename))) { + SET_STATUS_Failure( VKI_ETXTBSY ); + return; + } + } + } +#if defined(VGO_linux) + } +#endif + } + #if defined(VGO_linux) /* Handle the case where the open is of /proc/self/cmdline or /proc/<pid>/cmdline, and just give it a copy of the fd for the fake file we cooked up at startup (in m_main). Also, seek the cloned fd back to the start. */ { - HChar name[30]; // large enough HChar* arg1s = (HChar*) (Addr)ARG1; SysRes sres; @@ -4648,6 +4689,11 @@ PRE(sys_open) if (ML_(handle_auxv_open)(status, (const HChar *)(Addr)ARG1, ARG2) || ML_(handle_self_exe_open)(status, (const HChar *)(Addr)ARG1, ARG2)) return; + + if (proc_self_exe) { + // do the syscall with VG_(resolved_exename) + SET_STATUS_from_SysRes(VG_(do_syscall3)(SYSNO, (Word)VG_(resolved_exename), ARG2, ARG3)); + } #endif // defined(VGO_linux) /* Otherwise handle normally */ diff --git a/coregrind/m_syswrap/syswrap-linux.c b/coregrind/m_syswrap/syswrap-linux.c index bd563d9894..e16d293cd0 100644 --- a/coregrind/m_syswrap/syswrap-linux.c +++ b/coregrind/m_syswrap/syswrap-linux.c @@ -5966,25 +5966,89 @@ PRE(sys_openat) { HChar name[30]; // large enough SysRes sres; + Bool proc_self_exe = False; + + /* Check for /proc/self/exe or /proc/<pid>/exe case + * first so that we can then use the later checks. */ + VG_(sprintf)(name, "/proc/%d/exe", VG_(getpid)()); + if (ML_(safe_to_deref)( (void*)(Addr)ARG2, 1 ) + && (VG_(strcmp)((HChar *)(Addr)ARG2, name) == 0 + || VG_(strcmp)((HChar *)(Addr)ARG2, "/proc/self/exe") == 0)) { + proc_self_exe = True; + } if (ARG3 & VKI_O_CREAT) { // 4-arg version PRINT("sys_openat ( %ld, %#" FMT_REGWORD "x(%s), %ld, %ld )", SARG1, ARG2, (HChar*)(Addr)ARG2, SARG3, SARG4); PRE_REG_READ4(long, "openat", - int, dfd, const char *, filename, int, flags, int, mode); + int, dirfd, const char *, pathname, int, flags, int, mode); } else { // 3-arg version PRINT("sys_openat ( %ld, %#" FMT_REGWORD "x(%s), %ld )", SARG1, ARG2, (HChar*)(Addr)ARG2, SARG3); PRE_REG_READ3(long, "openat", - int, dfd, const char *, filename, int, flags); + int, dirfd, const char *, pathname, int, flags); } - PRE_MEM_RASCIIZ( "openat(filename)", ARG2 ); + PRE_MEM_RASCIIZ( "openat(pathname)", ARG2 ); - /* For absolute filenames, dfd is ignored. If dfd is AT_FDCWD, - filename is relative to cwd. When comparing dfd against AT_FDCWD, + // check that we are not trying to open the client exe for writing + if ((ARG3 & VKI_O_WRONLY) || + (ARG3 & VKI_O_RDWR)) { + if (proc_self_exe) { + SET_STATUS_Failure( VKI_ETXTBSY ); + return; + } else { + vg_assert(VG_(resolved_exename)); + if (!VG_(strncmp)(VG_(resolved_exename), "#!", 2)) { + goto no_client_write; + } + Int fd = ARG1; + const HChar* path = (const HChar*)ARG2; + if (ML_(safe_to_deref)(path, 1)) { + // we need something like a "ML_(safe_to_deref_path)" that does a binary search for the addressable length, and maybe nul + if (path[0] == '/') { + // ignore fd + HChar tmp[VKI_PATH_MAX]; + if (VG_(realpath)(path, tmp)) { + if (!VG_(strcmp)(tmp, VG_(resolved_exename))) { + SET_STATUS_Failure( VKI_ETXTBSY ); + return; + } + } + } else { + if (fd == VKI_AT_FDCWD) { + HChar tmp[VKI_PATH_MAX]; + if (VG_(realpath)(path, tmp)) { + if (!VG_(strcmp)(tmp, VG_(resolved_exename))) { + SET_STATUS_Failure( VKI_ETXTBSY ); + } + } + } else { + const HChar* dirname; + if (VG_(resolve_filename)(fd, &dirname) == False) { + goto no_client_write; // let the OS do the error handling + } + HChar tmp1[VKI_PATH_MAX]; + VG_(snprintf)(tmp1, VKI_PATH_MAX, "%s/%s", dirname, path); + tmp1[VKI_PATH_MAX - 1] = '\0'; + HChar tmp2[VKI_PATH_MAX]; + if (VG_(realpath)(tmp1, tmp2)) { + if (!VG_(strcmp)(tmp2, VG_(resolved_exename))) { + SET_STATUS_Failure( VKI_ETXTBSY ); + return; + } + } + } + } + } + } + } +no_client_write: + + /* For absolute filenames, dirfd is ignored. If dirfd is AT_FDCWD, + filename is relative to cwd. When comparing dirfd against AT_FDCWD, be sure only to compare the bottom 32 bits. */ if (ML_(safe_to_deref)( (void*)(Addr)ARG2, 1 ) && *(Char *)(Addr)ARG2 != '/' @@ -6027,20 +6091,10 @@ PRE(sys_openat) return; } - /* And for /proc/self/exe or /proc/<pid>/exe case. */ + if (proc_self_exe) { - VG_(sprintf)(name, "/proc/%d/exe", VG_(getpid)()); - if (ML_(safe_to_deref)( (void*)(Addr)ARG2, 1 ) - && (VG_(strcmp)((HChar *)(Addr)ARG2, name) == 0 - || VG_(strcmp)((HChar *)(Addr)ARG2, "/proc/self/exe") == 0)) { - sres = VG_(dup)( VG_(cl_exec_fd) ); - SET_STATUS_from_SysRes( sres ); - if (!sr_isError(sres)) { - OffT off = VG_(lseek)( sr_Res(sres), 0, VKI_SEEK_SET ); - if (off < 0) - SET_STATUS_Failure( VKI_EMFILE ); - } - return; + // do the syscall with VG_(resolved_exename) + SET_STATUS_from_SysRes(VG_(do_syscall4)(SYSNO, ARG1, (Word)VG_(resolved_exename), ARG3, ARG4)); } /* Otherwise handle normally */ @@ -13900,43 +13954,109 @@ PRE(sys_openat2) { HChar name[30]; // large enough SysRes sres; - struct vki_open_how * how; + struct vki_open_how* how = (struct vki_open_how *)ARG3; + Bool proc_self_exe = False; + Bool can_deref_how = how && ML_(safe_to_deref)(how, sizeof(*how)); + + // ARG4 is supposed to be sizeof(struct vki_open_how) + // but we can't trust it + if (can_deref_how) { + // check that we are not trying to open the client exe for writing + // this doesn't handle all of the RESOLVE options, there may be cases + // like RESOLVE_NO_XDEV and RESOLVE_BENEATH where the path is + // invalid and we might return the wrong errno + if (how->vki_resolve != VKI_RESOLVE_IN_ROOT && + how->vki_resolve != VKI_RESOLVE_NO_MAGICLINKS) { + /* Check for /proc/self/exe or /proc/<pid>/exe case + * first so that we can then use the later checks. */ + VG_(sprintf)(name, "/proc/%d/exe", VG_(getpid)()); + if (ML_(safe_to_deref)( (void*)(Addr)ARG2, 1 ) + && (VG_(strcmp)((HChar *)(Addr)ARG2, name) == 0 + || VG_(strcmp)((HChar *)(Addr)ARG2, "/proc/self/exe") == 0)) { + proc_self_exe = True; + } + } + } PRINT("sys_openat2 ( %ld, %#" FMT_REGWORD "x(%s), %#" FMT_REGWORD "x, %ld )", SARG1, ARG2, (HChar*)(Addr)ARG2, ARG3, SARG4); PRE_REG_READ4(long, "openat2", - int, dfd, const char *, filename, struct vki_open_how *, how, vki_size_t, size); + int, dirfd, const char *, pathname, struct vki_open_how *, how, vki_size_t, size); - PRE_MEM_RASCIIZ( "openat2(filename)", ARG2 ); + PRE_MEM_RASCIIZ( "openat2(pathname)", ARG2 ); PRE_MEM_READ( "openat2(how)", ARG3, sizeof(struct vki_open_how)); - /* For absolute filenames, dfd is ignored. If dfd is AT_FDCWD, - filename is relative to cwd. When comparing dfd against AT_FDCWD, + if (can_deref_how && + ((how->vki_flags & VKI_O_WRONLY) || + (how->vki_flags & VKI_O_RDWR))) { + if (proc_self_exe) { + SET_STATUS_Failure( VKI_ETXTBSY ); + return; + } else { + vg_assert(VG_(resolved_exename)); + if (!VG_(strncmp)(VG_(resolved_exename), "#!", 2)) { + goto no_client_write; + } + Int fd = ARG1; + const HChar* path = (const HChar*)ARG2; + if (ML_(safe_to_deref)(path, 1)) { + // we need something like a "ML_(safe_to_deref_path)" that does a binary search for the addressable length, and maybe nul + if (path[0] == '/' && how->vki_resolve != VKI_RESOLVE_IN_ROOT) { + // absolute path, ignore fd + HChar tmp[VKI_PATH_MAX]; + if (VG_(realpath)(path, tmp)) { + if (!VG_(strcmp)(tmp, VG_(resolved_exename))) { + SET_STATUS_Failure( VKI_ETXTBSY ); + return; + } + } + } else { + // relative or rooted path + // or RESOLVE_IN_ROOT + if (how->vki_resolve == VKI_RESOLVE_IN_ROOT) { + while (*path == '/' && *path != '\0') { + ++path; + } + } + if (fd == VKI_AT_FDCWD) { + HChar tmp[VKI_PATH_MAX]; + if (VG_(realpath)(path, tmp)) { + if (!VG_(strcmp)(tmp, VG_(resolved_exename))) { + SET_STATUS_Failure( VKI_ETXTBSY ); + return; + } + } + } else { + // build absolute path from fd and path + const HChar* dirname; + if (VG_(resolve_filename)(fd, &dirname) == False) { + goto no_client_write; // let the OS do the error handling + } + HChar tmp1[VKI_PATH_MAX]; + VG_(snprintf)(tmp1, VKI_PATH_MAX, "%s/%s", dirname, path); + tmp1[VKI_PATH_MAX - 1] = '\0'; + HChar tmp2[VKI_PATH_MAX]; + if (VG_(realpath)(tmp1, tmp2)) { + if (!VG_(strcmp)(tmp2, VG_(resolved_exename))) { + SET_STATUS_Failure( VKI_ETXTBSY ); + return; + } + } + } + } + } + } + } + no_client_write: + + /* For absolute filenames, dirfd is ignored. If dirfd is AT_FDCWD, + filename is relative to cwd. When comparing dirfd against AT_FDCWD, be sure only to compare the bottom 32 bits. */ if (ML_(safe_to_deref)( (void*)(Addr)ARG2, 1 ) && *(Char *)(Addr)ARG2 != '/' && ((Int)ARG1) != ((Int)VKI_AT_FDCWD) - && !ML_(fd_allowed)(ARG1, "openat2", tid, False)) + && !ML_(fd_allowed)(ARG1, "openat", tid, False)) SET_STATUS_Failure( VKI_EBADF ); - - how = (struct vki_open_how *)ARG3; - - if (how && ML_(safe_to_deref) (how, sizeof(struct vki_open_how))) { - if (how->vki_mode) { - if (!(how->vki_flags & ((vki_uint64_t)VKI_O_CREAT | VKI_O_TMPFILE))) { - SET_STATUS_Failure( VKI_EINVAL ); - } - } - if (how->vki_resolve & ~((vki_uint64_t)VKI_RESOLVE_NO_XDEV | - VKI_RESOLVE_NO_MAGICLINKS | - VKI_RESOLVE_NO_SYMLINKS | - VKI_RESOLVE_BENEATH | - VKI_RESOLVE_IN_ROOT | - VKI_RESOLVE_CACHED)) { - SET_STATUS_Failure( VKI_EINVAL ); - } - } - /* Handle the case where the open is of /proc/self/cmdline or /proc/<pid>/cmdline, and just give it a copy of the fd for the fake file we cooked up at startup (in m_main). Also, seek the @@ -13972,20 +14092,10 @@ PRE(sys_openat2) return; } - /* And for /proc/self/exe or /proc/<pid>/exe case. */ + if (proc_self_exe) { - VG_(sprintf)(name, "/proc/%d/exe", VG_(getpid)()); - if (ML_(safe_to_deref)( (void*)(Addr)ARG2, 1 ) - && (VG_(strcmp)((HChar *)(Addr)ARG2, name) == 0 - || VG_(strcmp)((HChar *)(Addr)ARG2, "/proc/self/exe") == 0)) { - sres = VG_(dup)( VG_(cl_exec_fd) ); - SET_STATUS_from_SysRes( sres ); - if (!sr_isError(sres)) { - OffT off = VG_(lseek)( sr_Res(sres), 0, VKI_SEEK_SET ); - if (off < 0) - SET_STATUS_Failure( VKI_EMFILE ); - } - return; + // do the syscall with VG_(resolved_exename) + SET_STATUS_from_SysRes(VG_(do_syscall4)(SYSNO, ARG1, (Word)VG_(resolved_exename), ARG3, ARG4)); } /* Otherwise handle normally */ diff --git a/coregrind/pub_core_libcfile.h b/coregrind/pub_core_libcfile.h index dc243bf7fe..8411ad3687 100644 --- a/coregrind/pub_core_libcfile.h +++ b/coregrind/pub_core_libcfile.h @@ -110,9 +110,8 @@ extern Int VG_(mkstemp) ( const HChar* part_of_name, /*OUT*/HChar* fullname ); return if the working directory couldn't be found. */ extern void VG_(record_startup_wd) ( void ); -#if defined(VGO_freebsd) +/* Resolves a path to a canonical absolute path */ extern Bool VG_(realpath)(const HChar *path, HChar *resolved); -#endif #endif // __PUB_CORE_LIBCFILE_H diff --git a/include/pub_tool_libcfile.h b/include/pub_tool_libcfile.h index ff4c0d3a57..5b912d31c1 100644 --- a/include/pub_tool_libcfile.h +++ b/include/pub_tool_libcfile.h @@ -81,9 +81,7 @@ extern Int VG_(pipe) ( Int fd[2] ); extern Off64T VG_(lseek) ( Int fd, Off64T offset, Int whence ); extern SysRes VG_(stat) ( const HChar* file_name, struct vg_stat* buf ); -#if defined(VGO_freebsd) extern SysRes VG_(lstat) ( const HChar* file_name, struct vg_stat* buf ); -#endif extern Int VG_(fstat) ( Int fd, struct vg_stat* buf ); extern SysRes VG_(dup) ( Int oldfd ); extern SysRes VG_(dup2) ( Int oldfd, Int newfd ); diff --git a/memcheck/tests/x86-linux/scalar_openat2.stderr.exp b/memcheck/tests/x86-linux/scalar_openat2.stderr.exp index 367da9dbf2..c666f9fb48 100644 --- a/memcheck/tests/x86-linux/scalar_openat2.stderr.exp +++ b/memcheck/tests/x86-linux/scalar_openat2.stderr.exp @@ -1,11 +1,11 @@ ----------------------------------------------------- 437: __NR_openat2 4s 2m ----------------------------------------------------- -Syscall param openat2(dfd) contains uninitialised byte(s) +Syscall param openat2(dirfd) contains uninitialised byte(s) ... by 0x........: main (scalar_openat2.c:15) -Syscall param openat2(filename) contains uninitialised byte(s) +Syscall param openat2(pathname) contains uninitialised byte(s) ... by 0x........: main (scalar_openat2.c:15) @@ -17,7 +17,7 @@ Syscall param openat2(size) contains uninitialised byte(s) ... by 0x........: main (scalar_openat2.c:15) -Syscall param openat2(filename) points to unaddressable byte(s) +Syscall param openat2(pathname) points to unaddressable byte(s) ... by 0x........: main (scalar_openat2.c:15) Address 0x........ is not stack'd, malloc'd or (recently) free'd diff --git a/none/tests/freebsd/Makefile.am b/none/tests/freebsd/Makefile.am index 5d209c6d27..0bbbffdad6 100644 --- a/none/tests/freebsd/Makefile.am +++ b/none/tests/freebsd/Makefile.am @@ -53,6 +53,8 @@ EXTRA_DIST = \ ksh_test.ksh \ ksh_test.stderr.exp \ ksh_test.stdout.exp \ + open_client.vgtest \ + open_client.stderr.exp \ sanity_level_thread.vgtest \ sanity_level_thread.stderr.exp \ swapcontext.vgtest \ @@ -69,7 +71,7 @@ EXTRA_DIST = \ usrstack.stdout.exp check_PROGRAMS = \ - auxv bug452274 bug498317 bug499212 fexecve hello_world osrel \ + auxv bug452274 bug498317 bug499212 fexecve hello_world open_client osrel \ proc_pid_file sanity_level_thread swapcontext umtx_shm_creat usrstack AM_CFLAGS += $(AM_FLAG_M3264_PRI) @@ -80,7 +82,7 @@ osrel_CFLAGS = ${AM_CFLAGS} swapcontext_CFLAGS = ${AM_CFLAGS} hello_world_SOURCES = hello_world.cpp - +open_client_SOURCES = open_client.cpp proc_pid_file_SOURCES = proc_pid_file.cpp sanity_level_thread_SOURCES = sanity_level_thread.cpp diff --git a/none/tests/freebsd/open_client.cpp b/none/tests/freebsd/open_client.cpp new file mode 100644 index 0000000000..454c0a3dc7 --- /dev/null +++ b/none/tests/freebsd/open_client.cpp @@ -0,0 +1,108 @@ +// For Bug 505673 +// Valgrind crashes with an internal error and SIGBUS when the guest tries to open its own file with O_WRONLY|O_CREAT|O_TRUNC +#include <fcntl.h> +#include <cerrno> +#include <stdexcept> +#include <vector> +#include <unistd.h> +#include <sys/syscall.h> +#include <unistd.h> + +int main(int argc, char** argv) +{ + std::vector<int> flags{O_WRONLY|O_CREAT|O_TRUNC, O_WRONLY, O_RDWR}; + + // On FreeBSD libc open uses syscall openat (at least on 14.2) + for (auto f : flags) + { + int res = open(argv[0], f, 0666); + if (-1 != res) + { + throw std::runtime_error("open should have failed"); + } + else + { + if (errno != ETXTBSY) + { + throw std::runtime_error("errno should be ETXTBSY"); + } + } + } + + // repeat the above, but with syscall SYS_open + for (auto f : flags) + { + int res = syscall(SYS_open, argv[0], f, 0666); + if (-1 != res) + { + throw std::runtime_error("open should have failed"); + } + else + { + if (errno != ETXTBSY) + { + throw std::runtime_error("errno should be ETXTBSY"); + } + } + } + + int dotdot; + if ((dotdot = open("..", O_DIRECTORY | O_RDONLY)) == -1) + { + throw std::runtime_error("failed to open ,."); + } + else + { + for (auto f : flags) + { + int res = openat(dotdot, "freebsd/open_client", f, 0666); + if (-1 != res) + { + throw std::runtime_error("open should have failed"); + } + else + { + if (errno != ETXTBSY) + { + throw std::runtime_error("errno should be ETXTBSY"); + } + } + } + } + close(dotdot); + + chdir(".."); + + // check that relative paths work + for (auto f : flags) + { + int res = open("freebsd/open_client", f, 0666); + if (-1 != res) + { + throw std::runtime_error("open should have failed"); + } + else + { + if (errno != ETXTBSY) + { + throw std::runtime_error("errno should be ETXTBSY"); + } + } + } + + for (auto f : flags) + { + int res = syscall(SYS_open, "freebsd/open_client", f, 0666); + if (-1 != res) + { + throw std::runtime_error("open should have failed"); + } + else + { + if (errno != ETXTBSY) + { + throw std::runtime_error("errno should be ETXTBSY"); + } + } + } +} diff --git a/none/tests/freebsd/open_client.stderr.exp b/none/tests/freebsd/open_client.stderr.exp new file mode 100644 index 0000000000..e69de29bb2 diff --git a/none/tests/freebsd/open_client.vgtest b/none/tests/freebsd/open_client.vgtest new file mode 100644 index 0000000000..12b148de4e --- /dev/null +++ b/none/tests/freebsd/open_client.vgtest @@ -0,0 +1,3 @@ +prog: open_client +vgopts: -q + diff --git a/none/tests/linux/Makefile.am b/none/tests/linux/Makefile.am index dbb535902e..c81ffff548 100644 --- a/none/tests/linux/Makefile.am +++ b/none/tests/linux/Makefile.am @@ -17,6 +17,7 @@ EXTRA_DIST = \ mremap4.stderr.exp mremap4.vgtest \ mremap5.stderr.exp mremap5.vgtest \ mremap6.stderr.exp mremap6.vgtest \ + open_client.stderr.exp open_client.vgtest \ pthread-stack.stderr.exp pthread-stack.vgtest \ stack-overflow.stderr.exp stack-overflow.vgtest @@ -32,6 +33,7 @@ check_PROGRAMS = \ mremap4 \ mremap5 \ mremap6 \ + open_client \ pthread-stack \ stack-overflow @@ -45,6 +47,7 @@ AM_CXXFLAGS += $(AM_FLAG_M3264_PRI) # Special needs clonev_LDADD = -lpthread +open_client_SOURCES = open_client.cpp pthread_stack_LDADD = -lpthread stack_overflow_CFLAGS = $(AM_CFLAGS) @FLAG_W_NO_UNINITIALIZED@ \ diff --git a/none/tests/linux/open_client.cpp b/none/tests/linux/open_client.cpp new file mode 100644 index 0000000000..4b336e7f02 --- /dev/null +++ b/none/tests/linux/open_client.cpp @@ -0,0 +1,191 @@ +// For Bug 505673 +// Valgrind crashes with an internal error and SIGBUS when the guest tries to open its own file with O_WRONLY|O_CREAT|O_TRUNC +#include <fcntl.h> +#include <cerrno> +#include <stdexcept> +#include <string> +#include <vector> +#include <unistd.h> +#include <sys/syscall.h> +#include <unistd.h> +#include <linux/openat2.h> + +int main(int argc, char** argv) +{ + std::vector<__u64> flags{O_WRONLY|O_CREAT|O_TRUNC, O_WRONLY, O_RDWR}; + auto pid = getpid(); + auto ppe = std::string("/proc/") + std::to_string(pid) + "/exe"; + std::vector<std::string> names{argv[0], "/proc/self/exe", ppe}; + int dotdot; + + for (const auto& n : names) + { + for (auto f : flags) + { + int res = open(n.c_str(), f, 0666); + if (-1 != res) + { + throw std::runtime_error("open should have failed"); + } + else + { + if (errno != ETXTBSY) + { + throw std::runtime_error("errno should be ETXTBSY"); + } + } + } + + for (auto f : flags) + { + int res = syscall(SYS_open, n.c_str(), f, 0666); + + if (-1 != res) + { + throw std::runtime_error("open should have failed"); + } + else + { + if (errno != ETXTBSY) + { + throw std::runtime_error("errno should be ETXTBSY"); + } + } + } + } + + if ((dotdot = open("..", O_DIRECTORY | O_RDONLY)) == -1) + { + throw std::runtime_error("failed to open ,."); + } + else + { + for (auto f : flags) + { + int res = openat(dotdot, "linux/open_client", f, 0666); + if (-1 != res) + { + throw std::runtime_error("open should have failed"); + } + else + { + if (errno != ETXTBSY) + { + throw std::runtime_error("errno should be ETXTBSY"); + } + } + } + } + +#if defined(SYS_openat2) + for (const auto& n : names) + { + for (auto f : flags) + { + struct open_how oh = { .flags=f, .mode=((f&static_cast<__u64>(O_CREAT))?0666UL:0UL), .resolve=0 }; + int res = syscall(SYS_openat2, AT_FDCWD, n.c_str(), &oh, sizeof(oh)); + if (-1 != res) + { + throw std::runtime_error("openat2 should have failed"); + } + else + { + if (errno != ETXTBSY) + { + throw std::runtime_error("errno should be ETXTBSY"); + } + } + } + } + + for (auto f : flags) + { + struct open_how oh = { .flags=f, .mode=((f&static_cast<__u64>(O_CREAT))?0666UL:0UL), .resolve=0 }; + int res = syscall(SYS_openat2, dotdot, "linux/open_client", &oh, sizeof(oh)); + if (-1 != res) + { + throw std::runtime_error("openat2 should have failed"); + } + else + { + if (errno != ETXTBSY) + { + throw std::runtime_error("errno should be ETXTBSY"); + } + } + } + + for (auto f : flags) + { + struct open_how oh = { .flags=f, .mode=((f&static_cast<__u64>(O_CREAT))?0666UL:0UL), .resolve=RESOLVE_IN_ROOT }; + int res = syscall(SYS_openat2, dotdot, "/linux/open_client", &oh, sizeof(oh)); + if (-1 != res) + { + throw std::runtime_error("openat2 should have failed"); + } + else + { + if (errno != ETXTBSY) + { + throw std::runtime_error("errno should be ETXTBSY"); + } + } + } +#endif + + close(dotdot); + + chdir(".."); + + // check that relative paths work + for (auto f : flags) + { + int res = open("linux/open_client", f, 0666); + if (-1 != res) + { + throw std::runtime_error("open should have failed"); + } + else + { + if (errno != ETXTBSY) + { + throw std::runtime_error("errno should be ETXTBSY"); + } + } + } + + for (auto f : flags) + { + int res = syscall(SYS_open, "linux/open_client", f, 0666); + if (-1 != res) + { + throw std::runtime_error("open should have failed"); + } + else + { + if (errno != ETXTBSY) + { + throw std::runtime_error("errno should be ETXTBSY"); + } + } + } + +#if defined(SYS_openat2) + for (auto f : flags) + { + struct open_how oh = { .flags=f, .mode=((f&static_cast<__u64>(O_CREAT))?0666UL:0UL), .resolve=0 }; + int res = syscall(SYS_openat2, AT_FDCWD, "linux/open_client", &oh, sizeof(oh)); + if (-1 != res) + { + throw std::runtime_error("openat2 should have failed"); + } + else + { + if (errno != ETXTBSY) + { + throw std::runtime_error("errno should be ETXTBSY"); + } + } + } +#endif +} diff --git a/none/tests/linux/open_client.stderr.exp b/none/tests/linux/open_client.stderr.exp new file mode 100644 index 0000000000..e69de29bb2 diff --git a/none/tests/linux/open_client.vgtest b/none/tests/linux/open_client.vgtest new file mode 100644 index 0000000000..6b930efe6c --- /dev/null +++ b/none/tests/linux/open_client.vgtest @@ -0,0 +1,2 @@ +prog: open_client +vgopts: -q |
From: Paul F. <pa...@so...> - 2025-07-18 11:29:45
|
https://sourceware.org/cgit/valgrind/commit/?id=baac076edfde2870ee6cc69390f3bca9d4f7d974 commit baac076edfde2870ee6cc69390f3bca9d4f7d974 Author: Paul Floyd <pj...@wa...> Date: Fri Jul 18 13:21:26 2025 +0200 FreeBSD: fix check for mmap flags On FreeBSD, mmap also has MAP_STACK and MAP_GUARD that can be mapped without a backing file referred to by fd. As a result during ld.so startup and thread creation mmap for stacks was failing. So no guest could be load and execute, with errors like ld-elf.so.1: /home/paulf/scratch/valgrind_nightly/nightly/valgrind-new/.in_place/vgpreload_core-amd64-freebsd.so: mmap of entire address space failed: Bad file descriptor Diff: --- coregrind/m_syswrap/syswrap-generic.c | 18 ++++++++++++++++-- include/vki/vki-freebsd.h | 1 + 2 files changed, 17 insertions(+), 2 deletions(-) diff --git a/coregrind/m_syswrap/syswrap-generic.c b/coregrind/m_syswrap/syswrap-generic.c index 7ad2809807..1b3b5e80d6 100644 --- a/coregrind/m_syswrap/syswrap-generic.c +++ b/coregrind/m_syswrap/syswrap-generic.c @@ -2653,12 +2653,26 @@ ML_(generic_PRE_sys_mmap) ( ThreadId tid, VG_(core_panic)("can't use ML_(generic_PRE_sys_mmap) on Darwin"); # endif - /* fd (arg4) is only used when flags (arg4) does not contain - MAP_ANONYMOUS. ML_(fd_allowed) might just warn (with --track-fds) +#if !defined(VKI_MAP_GUARD) +// on platforms without MAP_GUARD the compiler should optimise away +// the term using it below as it will always be true +#define VKI_MAP_GUARD 0 +#endif + +#if !defined(VKI_MAP_STACK) +// as above +#define VKI_MAP_STACK 0 +#endif + + /* fd (arg5) is only used when flags (arg4) does not contain + MAP_ANONYMOUS (or, on FreeBSD, MAP_GUARD and MAP_STACK). + ML_(fd_allowed) might just warn (with --track-fds) and not fail, unless it is a Valgrind owned file descriptor. So also check with fcntl (F_GETFD) to know if it really is a bad fd. Fail early in that case with EBADF. */ if (!(arg4 & VKI_MAP_ANONYMOUS) + && !(arg4 & VKI_MAP_GUARD) + && !(arg4 & VKI_MAP_STACK) && (!ML_(fd_allowed)(arg5, "mmap", tid, False) || VG_(fcntl) (arg5, VKI_F_GETFD, 0) < 0)) { return VG_(mk_SysRes_Error)( VKI_EBADF ); diff --git a/include/vki/vki-freebsd.h b/include/vki/vki-freebsd.h index 63ffbe7e5e..1a371245f6 100644 --- a/include/vki/vki-freebsd.h +++ b/include/vki/vki-freebsd.h @@ -1526,6 +1526,7 @@ typedef enum vki_idtype { #define VKI_MAP_STACK 0x400 #define VKI_MAP_ANON 0x1000 /* don't use a file */ #define VKI_MAP_ANONYMOUS VKI_MAP_ANON +#define VKI_MAP_GUARD 0x00002000 #define VKI_MAP_ALIGNED(n) ((n) << VKI_MAP_ALIGNMENT_SHIFT) #define VKI_MAP_ALIGNMENT_SHIFT 24 |
From: Florian K. <fk...@so...> - 2025-07-17 20:39:37
|
https://sourceware.org/cgit/valgrind/commit/?id=4ecf8d2832530de0904803c772126aabcf8fb075 commit 4ecf8d2832530de0904803c772126aabcf8fb075 Author: Florian Krohm <fl...@ei...> Date: Thu Jul 17 20:39:12 2025 +0000 Constant folding for various division IROps. (BZ 506211) Part of fixing https://bugs.kde.org/show_bug.cgi?id=506211 Diff: --- VEX/priv/ir_opt.c | 48 +++++++++++++++++++++++++++++++++++++++++ none/tests/iropt-test/binary.c | 41 +++++++++++++++++++++++++++++++++++ none/tests/iropt-test/irops.tab | 16 +++++++------- 3 files changed, 97 insertions(+), 8 deletions(-) diff --git a/VEX/priv/ir_opt.c b/VEX/priv/ir_opt.c index fa0b76a961..ebea8ba0e3 100644 --- a/VEX/priv/ir_opt.c +++ b/VEX/priv/ir_opt.c @@ -2149,6 +2149,54 @@ static IRExpr* fold_Expr_WRK ( IRExpr** env, IRExpr* e ) break; } + /* -- Div -- */ + case Iop_DivS32: { + Int s32a = e->Iex.Binop.arg1->Iex.Const.con->Ico.U32; + Int s32b = e->Iex.Binop.arg2->Iex.Const.con->Ico.U32; + if (s32b != 0) + e2 = IRExpr_Const(IRConst_U32(s32a / s32b)); + break; + } + case Iop_DivS64: { + Long s64a = e->Iex.Binop.arg1->Iex.Const.con->Ico.U64; + Long s64b = e->Iex.Binop.arg2->Iex.Const.con->Ico.U64; + if (s64b != 0) + e2 = IRExpr_Const(IRConst_U64(s64a / s64b)); + break; + } + case Iop_DivU32: { + UInt u32a = e->Iex.Binop.arg1->Iex.Const.con->Ico.U32; + UInt u32b = e->Iex.Binop.arg2->Iex.Const.con->Ico.U32; + if (u32b != 0) + e2 = IRExpr_Const(IRConst_U32(u32a / u32b)); + break; + } + case Iop_DivU64: { + ULong u64a = e->Iex.Binop.arg1->Iex.Const.con->Ico.U64; + ULong u64b = e->Iex.Binop.arg2->Iex.Const.con->Ico.U64; + if (u64b != 0) + e2 = IRExpr_Const(IRConst_U64(u64a / u64b)); + break; + } + case Iop_DivS32E: { + Int s32a = e->Iex.Binop.arg1->Iex.Const.con->Ico.U32; + Int s32b = e->Iex.Binop.arg2->Iex.Const.con->Ico.U32; + if (s32b != 0) { + Long s64a = (Long)s32a << 32; + e2 = IRExpr_Const(IRConst_U32(toUInt(s64a / s32b))); + } + break; + } + case Iop_DivU32E: { + UInt u32a = e->Iex.Binop.arg1->Iex.Const.con->Ico.U32; + UInt u32b = e->Iex.Binop.arg2->Iex.Const.con->Ico.U32; + if (u32b != 0) { + ULong u64a = (ULong)u32a << 32; + e2 = IRExpr_Const(IRConst_U32(toUInt(u64a / u32b))); + } + break; + } + /* -- Shl -- */ case Iop_Shl8: vassert(e->Iex.Binop.arg2->Iex.Const.con->tag == Ico_U8); diff --git a/none/tests/iropt-test/binary.c b/none/tests/iropt-test/binary.c index 96e71a068e..62c9faeb35 100644 --- a/none/tests/iropt-test/binary.c +++ b/none/tests/iropt-test/binary.c @@ -30,6 +30,7 @@ static void check_result(const irop_t *, const test_data_t *); static void run_tests(const irop_t *, test_data_t *); static void run_shift_tests(const irop_t *, test_data_t *); static int is_shift_op(IROp); +static int is_division_op(IROp); void @@ -56,6 +57,8 @@ run_selected_tests(const irop_t *op, test_data_t *data) for (unsigned j = 0; j < num_val_r; ++j) { opnd_r->value = values_r[j]; + if (is_division_op(op->op) && opnd_r->value == 0) continue; + valgrind_execute_test(op, data); check_result(op, data); } @@ -74,6 +77,8 @@ run_random_tests(const irop_t *op, test_data_t *data) opnd_l->value = get_random_value(opnd_l->type); opnd_r->value = get_random_value(opnd_r->type); + if (is_division_op(op->op) && opnd_r->value == 0) continue; + valgrind_execute_test(op, data); check_result(op, data); } @@ -190,6 +195,27 @@ check_result(const irop_t *op, const test_data_t *data) expected = (int64_t)(int32_t)opnd_l * (int64_t)(int32_t)opnd_r; break; + case Iop_DivU32: + case Iop_DivU64: + expected = opnd_l / opnd_r; + break; + + case Iop_DivS32: + expected = (int32_t)opnd_l / (int32_t)opnd_r; + break; + + case Iop_DivS64: + expected = (int64_t)opnd_l / (int64_t)opnd_r; + break; + + case Iop_DivU32E: + expected = (opnd_l << 32) / opnd_r; + break; + + case Iop_DivS32E: + expected = (int64_t)(opnd_l << 32) / (int32_t)opnd_r; + break; + case Iop_Shl8: case Iop_Shl16: case Iop_Shl32: @@ -392,3 +418,18 @@ is_shift_op(IROp op) return 0; } } + + +static int +is_division_op(IROp op) +{ + switch (op) { + case Iop_DivU32: case Iop_DivU64: + case Iop_DivS32: case Iop_DivS64: + case Iop_DivU32E: + case Iop_DivS32E: + return 1; + default: + return 0; + } +} diff --git a/none/tests/iropt-test/irops.tab b/none/tests/iropt-test/irops.tab index 5fb2016634..f2ffd007c6 100644 --- a/none/tests/iropt-test/irops.tab +++ b/none/tests/iropt-test/irops.tab @@ -135,20 +135,20 @@ { OPNAME(MullS32), Ity_I64, 2, Ity_I32, Ity_I32 }, // { OPNAME(MullS64), Ity_I128, 2, Ity_I64, Ity_I64 }, // 128 bit -// { OPNAME(DivU32), Ity_I32, 2, Ity_I32, Ity_I32 }, // no folding yet -// { OPNAME(DivU64), Ity_I64, 2, Ity_I64, Ity_I64 }, // no folding yet + { OPNAME(DivU32), Ity_I32, 2, Ity_I32, Ity_I32 }, + { OPNAME(DivU64), Ity_I64, 2, Ity_I64, Ity_I64 }, // { OPNAME(DivU128), Ity_I128, 2, Ity_I128, Ity_I128 }, // 128 bit -// { OPNAME(DivS32), Ity_I32, 2, Ity_I32, Ity_I32 }, // no folding yet -// { OPNAME(DivS64), Ity_I64, 2, Ity_I64, Ity_I64 }, // no folding yet + { OPNAME(DivS32), Ity_I32, 2, Ity_I32, Ity_I32 }, + { OPNAME(DivS64), Ity_I64, 2, Ity_I64, Ity_I64 }, // { OPNAME(DivS128), Ity_I128, 2, Ity_I128, Ity_I128 }, // 128 bit -// { OPNAME(DivU32E), Ity_I32, 2, Ity_I32, Ity_I32 }, // semantics ? -// { OPNAME(DivU64E), Ity_I32, 2, Ity_I32, Ity_I32 }, // semantics ? + { OPNAME(DivU32E), Ity_I32, 2, Ity_I32, Ity_I32 }, +// { OPNAME(DivU64E), Ity_I64, 2, Ity_I64, Ity_I64 }, // 128 bit // { OPNAME(DivU128E), Ity_I128, 2, Ity_I128, Ity_I128 }, // 128 bit -// { OPNAME(DivS32E), Ity_I32, 2, Ity_I32, Ity_I32 }, // semantics ? -// { OPNAME(DivS64E), Ity_I32, 2, Ity_I32, Ity_I32 }, // semantics ? + { OPNAME(DivS32E), Ity_I32, 2, Ity_I32, Ity_I32 }, +// { OPNAME(DivS64E), Ity_I32, 2, Ity_I32, Ity_I32 }, // 128 bit // { OPNAME(DivS128E), Ity_I128, 2, Ity_I128, Ity_I128 }, // 128 bit // { OPNAME(DivModU32to32), Ity_I64, 2, Ity_I32, Ity_I64 }, // no folding yet |
From: Paul F. <pa...@so...> - 2025-07-17 18:41:36
|
https://sourceware.org/cgit/valgrind/commit/?id=c322bf33df88d1e8813434f7beeba909831a6a79 commit c322bf33df88d1e8813434f7beeba909831a6a79 Author: Paul Floyd <pj...@wa...> Date: Thu Jul 17 20:38:54 2025 +0200 iropt regtest: use mrand32() instead of rand() On illumos rand() has a RAND_MAX of 32k only. That's not enough to generate 64bit values easily. So use mrand48() which genrerates the full range of 32bit int values. Diff: --- none/tests/iropt-test/main.c | 2 +- none/tests/iropt-test/util.c | 9 +++------ 2 files changed, 4 insertions(+), 7 deletions(-) diff --git a/none/tests/iropt-test/main.c b/none/tests/iropt-test/main.c index 2622515e55..9f1cc5083a 100644 --- a/none/tests/iropt-test/main.c +++ b/none/tests/iropt-test/main.c @@ -45,7 +45,7 @@ int main(int argc, char *argv[]) { assert(sizeof(long long) == 8); - assert(RAND_MAX == INT32_MAX); + srand48(42L); for (int i = 1; i < argc; ++i) { if (strcmp(argv[i], "-v") == 0) diff --git a/none/tests/iropt-test/util.c b/none/tests/iropt-test/util.c index 072ff90c36..18b671114c 100644 --- a/none/tests/iropt-test/util.c +++ b/none/tests/iropt-test/util.c @@ -109,7 +109,7 @@ bitsof_irtype(IRType ty) uint64_t get_random_value(IRType type) { - uint64_t val = rand(); + uint64_t val = mrand48(); switch (type) { case Ity_I1: return val & 0x1; @@ -117,11 +117,8 @@ get_random_value(IRType type) case Ity_I16: return val & UINT16_MAX; case Ity_I32: return val & UINT32_MAX; case Ity_I64: - /* Note, that RAND_MAX == INT32_MAX. Therefore, simply concatenating - two rand() values would never produce a value with MSB == 1 */ - val <<= (32 + 1); - val |= rand() << 1; - val |= rand() & 0x1; + val <<= 32; + val |= mrand48(); return val; default: |
From: Florian K. <fk...@so...> - 2025-07-17 15:07:11
|
https://sourceware.org/cgit/valgrind/commit/?id=a3b172bd1235f9b74736a7f12a4a4072037b7900 commit a3b172bd1235f9b74736a7f12a4a4072037b7900 Author: Florian Krohm <fl...@ei...> Date: Thu Jul 17 14:04:50 2025 +0000 Constant folding for various multiplication IROps. (BZ 506211) Part of fixing https://bugs.kde.org/show_bug.cgi?id=506211 Diff: --- VEX/priv/ir_opt.c | 57 +++++++++++++++++++++++++++++++++++++++++ none/tests/iropt-test/binary.c | 42 ++++++++++++++++++++++++++++++ none/tests/iropt-test/irops.tab | 20 +++++++-------- 3 files changed, 109 insertions(+), 10 deletions(-) diff --git a/VEX/priv/ir_opt.c b/VEX/priv/ir_opt.c index 8e4d95692d..fa0b76a961 100644 --- a/VEX/priv/ir_opt.c +++ b/VEX/priv/ir_opt.c @@ -2067,6 +2067,16 @@ static IRExpr* fold_Expr_WRK ( IRExpr** env, IRExpr* e ) } /* -- Mul -- */ + case Iop_Mul8: + e2 = IRExpr_Const(IRConst_U8(toUChar( + (e->Iex.Binop.arg1->Iex.Const.con->Ico.U8 + * e->Iex.Binop.arg2->Iex.Const.con->Ico.U8)))); + break; + case Iop_Mul16: + e2 = IRExpr_Const(IRConst_U16(toUShort( + (e->Iex.Binop.arg1->Iex.Const.con->Ico.U16 + * e->Iex.Binop.arg2->Iex.Const.con->Ico.U16)))); + break; case Iop_Mul32: e2 = IRExpr_Const(IRConst_U32( (e->Iex.Binop.arg1->Iex.Const.con->Ico.U32 @@ -2078,6 +2088,53 @@ static IRExpr* fold_Expr_WRK ( IRExpr** env, IRExpr* e ) * e->Iex.Binop.arg2->Iex.Const.con->Ico.U64))); break; + case Iop_MullU8: { + UChar u8a = e->Iex.Binop.arg1->Iex.Const.con->Ico.U8; + UChar u8b = e->Iex.Binop.arg2->Iex.Const.con->Ico.U8; + Int res = u8a * u8b; /* Compiler will promote to int */ + e2 = IRExpr_Const(IRConst_U16(toUShort(res))); + break; + } + case Iop_MullU16: { + UShort u16a = e->Iex.Binop.arg1->Iex.Const.con->Ico.U16; + UShort u16b = e->Iex.Binop.arg2->Iex.Const.con->Ico.U16; + Int res = u16a * u16b; /* Compiler will promote to int */ + e2 = IRExpr_Const(IRConst_U32(res)); + break; + } + case Iop_MullU32: { + UInt u32a = e->Iex.Binop.arg1->Iex.Const.con->Ico.U32; + UInt u32b = e->Iex.Binop.arg2->Iex.Const.con->Ico.U32; + ULong res = (ULong)u32a * (ULong)u32b; + e2 = IRExpr_Const(IRConst_U64(res)); + break; + } + case Iop_MullS8: { + /* very paranoid */ + UChar u8a = e->Iex.Binop.arg1->Iex.Const.con->Ico.U8; + UChar u8b = e->Iex.Binop.arg2->Iex.Const.con->Ico.U8; + Char s8a = (Char)u8a; + Char s8b = (Char)u8b; + Short s16a = (Short)s8a; + Short s16b = (Short)s8b; + Int sres = s16a * s16b; + UShort ures = toUShort(sres); + e2 = IRExpr_Const(IRConst_U16(ures)); + break; + } + case Iop_MullS16: { + /* very paranoid */ + UShort u16a = e->Iex.Binop.arg1->Iex.Const.con->Ico.U16; + UShort u16b = e->Iex.Binop.arg2->Iex.Const.con->Ico.U16; + Short s16a = (Short)u16a; + Short s16b = (Short)u16b; + Int s32a = (Int)s16a; + Int s32b = (Int)s16b; + Int sres = s32a * s32b; + UInt ures = (UInt)sres; + e2 = IRExpr_Const(IRConst_U32(ures)); + break; + } case Iop_MullS32: { /* very paranoid */ UInt u32a = e->Iex.Binop.arg1->Iex.Const.con->Ico.U32; diff --git a/none/tests/iropt-test/binary.c b/none/tests/iropt-test/binary.c index 1ec2d77e3d..96e71a068e 100644 --- a/none/tests/iropt-test/binary.c +++ b/none/tests/iropt-test/binary.c @@ -144,6 +144,48 @@ check_result(const irop_t *op, const test_data_t *data) expected = opnd_l - opnd_r; break; + case Iop_Mul8: + case Iop_MullU8: { + uint8_t u8l = opnd_l; + uint8_t u8r = opnd_r; + expected = u8l * u8r; + break; + } + case Iop_Mul16: + case Iop_MullU16: { + uint16_t u16l = opnd_l; + uint16_t u16r = opnd_r; + expected = u16l * u16r; + break; + } + case Iop_Mul32: + case Iop_MullU32: { + uint32_t u32l = opnd_l; + uint32_t u32r = opnd_r; + expected = (uint64_t)u32l * (uint64_t)u32r; + break; + } + + case Iop_Mul64: + expected = opnd_l * opnd_r; + break; + + case Iop_MullS8: { + uint8_t u8l = opnd_l; + uint8_t u8r = opnd_r; + int8_t s8l = (int8_t)u8l; + int8_t s8r = (int8_t)u8r; + expected = (int16_t)s8l * (int16_t)s8r; + break; + } + case Iop_MullS16: { + uint16_t u16l = opnd_l; + uint16_t u16r = opnd_r; + int16_t s16l = (int16_t)u16l; + int16_t s16r = (int16_t)u16r; + expected = (int32_t)s16l * (int32_t)s16r; + break; + } case Iop_MullS32: expected = (int64_t)(int32_t)opnd_l * (int64_t)(int32_t)opnd_r; break; diff --git a/none/tests/iropt-test/irops.tab b/none/tests/iropt-test/irops.tab index 68f8cc8860..5fb2016634 100644 --- a/none/tests/iropt-test/irops.tab +++ b/none/tests/iropt-test/irops.tab @@ -120,18 +120,18 @@ { OPNAME(Sub32), Ity_I32, 2, Ity_I32, Ity_I32 }, { OPNAME(Sub64), Ity_I64, 2, Ity_I64, Ity_I64 }, -// { OPNAME(Mul8), Ity_I8, 2, Ity_I8, Ity_I8 }, -// { OPNAME(Mul16), Ity_I16, 2, Ity_I16, Ity_I16 }, -// { OPNAME(Mul32), Ity_I32, 2, Ity_I32, Ity_I32 }, -// { OPNAME(Mul64), Ity_I64, 2, Ity_I64, Ity_I64 }, - -// { OPNAME(MullU8), Ity_I16, 2, Ity_I8, Ity_I8 }, // no folding yet -// { OPNAME(MullU16), Ity_I32, 2, Ity_I16, Ity_I16 }, // no folding yet -// { OPNAME(MullU32), Ity_I64, 2, Ity_I32, Ity_I32 }, // no folding yet + { OPNAME(Mul8), Ity_I8, 2, Ity_I8, Ity_I8 }, + { OPNAME(Mul16), Ity_I16, 2, Ity_I16, Ity_I16 }, + { OPNAME(Mul32), Ity_I32, 2, Ity_I32, Ity_I32 }, + { OPNAME(Mul64), Ity_I64, 2, Ity_I64, Ity_I64 }, + + { OPNAME(MullU8), Ity_I16, 2, Ity_I8, Ity_I8 }, + { OPNAME(MullU16), Ity_I32, 2, Ity_I16, Ity_I16 }, + { OPNAME(MullU32), Ity_I64, 2, Ity_I32, Ity_I32 }, // { OPNAME(MullU64), Ity_I128, 2, Ity_I64, Ity_I64 }, // 128 bit -// { OPNAME(MullS8), Ity_I16, 2, Ity_I8, Ity_I8 }, // no folding yet -// { OPNAME(MullS16), Ity_I32, 2, Ity_I16, Ity_I16 }, // no folding yet + { OPNAME(MullS8), Ity_I16, 2, Ity_I8, Ity_I8 }, + { OPNAME(MullS16), Ity_I32, 2, Ity_I16, Ity_I16 }, { OPNAME(MullS32), Ity_I64, 2, Ity_I32, Ity_I32 }, // { OPNAME(MullS64), Ity_I128, 2, Ity_I64, Ity_I64 }, // 128 bit |
From: Florian K. <fk...@so...> - 2025-07-17 15:07:06
|
https://sourceware.org/cgit/valgrind/commit/?id=c84404c4f8ba52edd9bd3c68fae316510adc1a90 commit c84404c4f8ba52edd9bd3c68fae316510adc1a90 Author: Florian Krohm <fl...@ei...> Date: Thu Jul 17 12:23:22 2025 +0000 Constant folding for Iop_CmpORD.. and Iop_8HLto16, Iop16HLto32. (BZ 506211) Part of fixing https://bugs.kde.org/show_bug.cgi?id=506211 Diff: --- VEX/priv/ir_opt.c | 56 +++++++++++++++++++++++++++++++++++++++++ none/tests/iropt-test/binary.c | 41 ++++++++++++++++++++++++------ none/tests/iropt-test/irops.tab | 10 ++++---- 3 files changed, 94 insertions(+), 13 deletions(-) diff --git a/VEX/priv/ir_opt.c b/VEX/priv/ir_opt.c index 4653704d3e..8e4d95692d 100644 --- a/VEX/priv/ir_opt.c +++ b/VEX/priv/ir_opt.c @@ -2339,8 +2339,64 @@ static IRExpr* fold_Expr_WRK ( IRExpr** env, IRExpr* e ) e2 = IRExpr_Const(IRConst_U32(r)); break; } + case Iop_CmpORD64S: { + /* very paranoid */ + ULong u64a = e->Iex.Binop.arg1->Iex.Const.con->Ico.U64; + ULong u64b = e->Iex.Binop.arg2->Iex.Const.con->Ico.U64; + Long s64a = (Long)u64a; + Long s64b = (Long)u64b; + Int r = 0x2; /* EQ */ + if (s64a < s64b) { + r = 0x8; /* LT */ + } + else if (s64a > s64b) { + r = 0x4; /* GT */ + } + e2 = IRExpr_Const(IRConst_U64(r)); + break; + } + case Iop_CmpORD32U: { + UInt u32a = e->Iex.Binop.arg1->Iex.Const.con->Ico.U32; + UInt u32b = e->Iex.Binop.arg2->Iex.Const.con->Ico.U32; + Int r = 0x2; /* EQ */ + if (u32a < u32b) { + r = 0x8; /* LT */ + } + else if (u32a > u32b) { + r = 0x4; /* GT */ + } + e2 = IRExpr_Const(IRConst_U32(r)); + break; + } + case Iop_CmpORD64U: { + ULong u64a = e->Iex.Binop.arg1->Iex.Const.con->Ico.U64; + ULong u64b = e->Iex.Binop.arg2->Iex.Const.con->Ico.U64; + Int r = 0x2; /* EQ */ + if (u64a < u64b) { + r = 0x8; /* LT */ + } + else if (u64a > u64b) { + r = 0x4; /* GT */ + } + e2 = IRExpr_Const(IRConst_U64(r)); + break; + } /* -- nHLto2n -- */ + case Iop_8HLto16: + e2 = IRExpr_Const(IRConst_U16(toUShort( + (((UInt)(e->Iex.Binop.arg1 + ->Iex.Const.con->Ico.U8)) << 8) + | ((UInt)(e->Iex.Binop.arg2->Iex.Const.con->Ico.U8))) + )); + break; + case Iop_16HLto32: + e2 = IRExpr_Const(IRConst_U32( + (((UInt)(e->Iex.Binop.arg1 + ->Iex.Const.con->Ico.U16)) << 16) + | ((UInt)(e->Iex.Binop.arg2->Iex.Const.con->Ico.U16)) + )); + break; case Iop_32HLto64: e2 = IRExpr_Const(IRConst_U64( (((ULong)(e->Iex.Binop.arg1 diff --git a/none/tests/iropt-test/binary.c b/none/tests/iropt-test/binary.c index 2c815c8136..1ec2d77e3d 100644 --- a/none/tests/iropt-test/binary.c +++ b/none/tests/iropt-test/binary.c @@ -233,9 +233,11 @@ check_result(const irop_t *op, const test_data_t *data) break; case Iop_CmpLT32S: { - int32_t opnd_ls = (int32_t)(opnd_l & UINT32_MAX); - int32_t opnd_rs = (int32_t)(opnd_r & UINT32_MAX); - expected = opnd_ls < opnd_rs; + uint32_t u32l = opnd_l & UINT32_MAX; + uint32_t u32r = opnd_r & UINT32_MAX; + int32_t s32l = (int32_t)u32l; + int32_t s32r = (int32_t)u32r; + expected = s32l < s32r; break; } @@ -249,9 +251,11 @@ check_result(const irop_t *op, const test_data_t *data) break; case Iop_CmpLE32S: { - int32_t opnd_ls = (int32_t)(opnd_l & UINT32_MAX); - int32_t opnd_rs = (int32_t)(opnd_r & UINT32_MAX); - expected = opnd_ls <= opnd_rs; + uint32_t u32l = opnd_l & UINT32_MAX; + uint32_t u32r = opnd_r & UINT32_MAX; + int32_t s32l = (int32_t)u32l; + int32_t s32r = (int32_t)u32r; + expected = s32l <= s32r; break; } @@ -259,9 +263,22 @@ check_result(const irop_t *op, const test_data_t *data) expected = (int64_t)opnd_l <= (int64_t)opnd_r; break; + case Iop_CmpORD32U: + case Iop_CmpORD64U: + expected = (opnd_l < opnd_r) ? 8 : (opnd_l > opnd_r) ? 4 : 2; + break; + case Iop_CmpORD32S: { - int32_t opnd_ls = (int32_t)(opnd_l & UINT32_MAX); - int32_t opnd_rs = (int32_t)(opnd_r & UINT32_MAX); + uint32_t u32l = opnd_l & UINT32_MAX; + uint32_t u32r = opnd_r & UINT32_MAX; + int32_t s32l = (int32_t)u32l; + int32_t s32r = (int32_t)u32r; + expected = (s32l < s32r) ? 8 : (s32l > s32r) ? 4 : 2; + break; + } + case Iop_CmpORD64S: { + int64_t opnd_ls = (int64_t)opnd_l; + int64_t opnd_rs = (int64_t)opnd_r; expected = (opnd_ls < opnd_rs) ? 8 : (opnd_ls > opnd_rs) ? 4 : 2; break; } @@ -272,6 +289,14 @@ check_result(const irop_t *op, const test_data_t *data) expected = opnd_l > opnd_r ? opnd_l : opnd_r; break; + case Iop_8HLto16: + expected = (opnd_l << 8) | opnd_r; + break; + + case Iop_16HLto32: + expected = (opnd_l << 16) | opnd_r; + break; + case Iop_32HLto64: expected = (opnd_l << 32) | opnd_r; break; diff --git a/none/tests/iropt-test/irops.tab b/none/tests/iropt-test/irops.tab index efae871fbf..68f8cc8860 100644 --- a/none/tests/iropt-test/irops.tab +++ b/none/tests/iropt-test/irops.tab @@ -234,15 +234,15 @@ { OPNAME(ExpCmpNE32), Ity_I1, 2, Ity_I32, Ity_I32 }, { OPNAME(ExpCmpNE64), Ity_I1, 2, Ity_I64, Ity_I64 }, -// { OPNAME(CmpORD32U), Ity_I32, 2, Ity_I32, Ity_I32 }, // no folding yet -// { OPNAME(CmpORD64U), Ity_I64, 2, Ity_I64, Ity_I64 }, // no folding yet + { OPNAME(CmpORD32U), Ity_I32, 2, Ity_I32, Ity_I32 }, + { OPNAME(CmpORD64U), Ity_I64, 2, Ity_I64, Ity_I64 }, { OPNAME(CmpORD32S), Ity_I32, 2, Ity_I32, Ity_I32 }, -// { OPNAME(CmpORD64S), Ity_I64, 2, Ity_I64, Ity_I64 }, // no folding yet + { OPNAME(CmpORD64S), Ity_I64, 2, Ity_I64, Ity_I64 }, { OPNAME(Max32U), Ity_I32, 2, Ity_I32, Ity_I32 }, -// { OPNAME(8HLto16), Ity_I16, 2, Ity_I8, Ity_I8 }, // no folding yet -// { OPNAME(16HLto32), Ity_I32, 2, Ity_I16, Ity_I16 }, // no folding yet + { OPNAME(8HLto16), Ity_I16, 2, Ity_I8, Ity_I8 }, + { OPNAME(16HLto32), Ity_I32, 2, Ity_I16, Ity_I16 }, { OPNAME(32HLto64), Ity_I64, 2, Ity_I32, Ity_I32 }, // { OPNAME(64HLto128), Ity_I128, 2, Ity_I64, Ity_I64 }, // 128 bit |
From: Mark W. <ma...@so...> - 2025-07-17 11:19:29
|
https://sourceware.org/cgit/valgrind/commit/?id=a4d893c6ef133fdf8255860aa8ca0a8460e105b1 commit a4d893c6ef133fdf8255860aa8ca0a8460e105b1 Author: Martin Cermak <mc...@re...> Date: Thu Jul 17 09:16:53 2025 +0200 Wrap linux specific syscall 22 (ustat) The ustat syscall comes from pre-git linux history. It is deprecated in favor of statfs. But in some cases it may still be used. int ustat(dev_t dev, struct ustat *ubuf); returns information about a mounted filesystem. dev is a device number identifying a device containing a mounted filesystem. ubuf is a pointer to a ustat structure. Declare a sys_ustat wrapper in priv_syswrap-linux.h and hook it for {amd64,arm,arm64,mips64,nanomips,ppc32,ppc64,riscv64,\ s390x,x86}-linux using LINXY with PRE and POST handler in syswrap-linux.c https://bugs.kde.org/show_bug.cgi?id=506928 Diff: --- NEWS | 1 + coregrind/m_syswrap/priv_syswrap-linux.h | 1 + coregrind/m_syswrap/syswrap-amd64-linux.c | 2 +- coregrind/m_syswrap/syswrap-arm-linux.c | 2 +- coregrind/m_syswrap/syswrap-linux.c | 13 +++++++++++++ coregrind/m_syswrap/syswrap-mips32-linux.c | 2 +- coregrind/m_syswrap/syswrap-mips64-linux.c | 9 +-------- coregrind/m_syswrap/syswrap-ppc32-linux.c | 2 +- coregrind/m_syswrap/syswrap-ppc64-linux.c | 2 +- coregrind/m_syswrap/syswrap-s390x-linux.c | 2 +- coregrind/m_syswrap/syswrap-x86-linux.c | 2 +- include/vki/vki-linux.h | 19 +++++++++++++++++++ 12 files changed, 42 insertions(+), 15 deletions(-) diff --git a/NEWS b/NEWS index 868d4218fe..e61b56baf9 100644 --- a/NEWS +++ b/NEWS @@ -55,6 +55,7 @@ are not entered into bugzilla tend to get forgotten about or ignored. 506076 unimplemented fcntl command: 1028 (F_CREATED_QUERY) 506499 Unhandled syscall 592 (exterrctl - FreeBSD 506795 Better report which clone flags are problematic +506928 Wrap (deprecated) linux specific ustat syscall 506930 valgrind allows SIGKILL being reset to SIG_DFL 506970 mmap needs an EBADF fd_allowed check diff --git a/coregrind/m_syswrap/priv_syswrap-linux.h b/coregrind/m_syswrap/priv_syswrap-linux.h index 9e6cb89811..ce10a35f6a 100644 --- a/coregrind/m_syswrap/priv_syswrap-linux.h +++ b/coregrind/m_syswrap/priv_syswrap-linux.h @@ -40,6 +40,7 @@ extern void ML_(call_on_new_stack_0_1) ( Addr stack, Addr retaddr, // Linux-specific (but non-arch-specific) syscalls +DECL_TEMPLATE(linux, sys_ustat); DECL_TEMPLATE(linux, sys_clone) DECL_TEMPLATE(linux, sys_mount); DECL_TEMPLATE(linux, sys_oldumount); diff --git a/coregrind/m_syswrap/syswrap-amd64-linux.c b/coregrind/m_syswrap/syswrap-amd64-linux.c index 22989f9fa5..c80286f00b 100644 --- a/coregrind/m_syswrap/syswrap-amd64-linux.c +++ b/coregrind/m_syswrap/syswrap-amd64-linux.c @@ -633,7 +633,7 @@ static SyscallTableEntry syscall_table[] = { // (__NR_uselib, sys_uselib), // 134 LINX_(__NR_personality, sys_personality), // 135 - // (__NR_ustat, sys_ustat), // 136 + LINXY(__NR_ustat, sys_ustat), // 136 GENXY(__NR_statfs, sys_statfs), // 137 GENXY(__NR_fstatfs, sys_fstatfs), // 138 // (__NR_sysfs, sys_sysfs), // 139 diff --git a/coregrind/m_syswrap/syswrap-arm-linux.c b/coregrind/m_syswrap/syswrap-arm-linux.c index 7bd69b6817..c5fb08dcc6 100644 --- a/coregrind/m_syswrap/syswrap-arm-linux.c +++ b/coregrind/m_syswrap/syswrap-arm-linux.c @@ -621,7 +621,7 @@ static SyscallTableEntry syscall_main_table[] = { //zz GENX_(__NR_umask, sys_umask), // 60 GENX_(__NR_chroot, sys_chroot), // 61 -//zz // (__NR_ustat, sys_ustat) // 62 SVr4 -- deprecated + LINXY(__NR_ustat, sys_ustat), // 62 SVr4 -- deprecated GENXY(__NR_dup2, sys_dup2), // 63 GENX_(__NR_getppid, sys_getppid), // 64 diff --git a/coregrind/m_syswrap/syswrap-linux.c b/coregrind/m_syswrap/syswrap-linux.c index 306c3a2f8b..bd563d9894 100644 --- a/coregrind/m_syswrap/syswrap-linux.c +++ b/coregrind/m_syswrap/syswrap-linux.c @@ -14204,6 +14204,19 @@ POST(sys_userfaultfd) } } +PRE(sys_ustat) +{ + FUSE_COMPATIBLE_MAY_BLOCK(); + PRINT("sys_ustat ( %#" FMT_REGWORD "x, %#" FMT_REGWORD "x)", ARG1, ARG2); + PRE_REG_READ2(long, "ustat", __vki_u32, dev, struct vki_ustat *, ubuf); + PRE_MEM_WRITE( "ustat(ubuf)", ARG2, sizeof(struct vki_ustat) ); +} + +POST(sys_ustat) +{ + POST_MEM_WRITE( ARG2, sizeof(struct vki_ustat) ); +} + #undef PRE #undef POST diff --git a/coregrind/m_syswrap/syswrap-mips32-linux.c b/coregrind/m_syswrap/syswrap-mips32-linux.c index 4e5e91e15b..684bda4b9a 100644 --- a/coregrind/m_syswrap/syswrap-mips32-linux.c +++ b/coregrind/m_syswrap/syswrap-mips32-linux.c @@ -826,7 +826,7 @@ static SyscallTableEntry syscall_main_table[] = { //.. // (__NR_oldolduname, sys_olduname), // 59 GENX_ (__NR_umask, sys_umask), // 60 GENX_ (__NR_chroot, sys_chroot), // 61 - //.. // (__NR_ustat, sys_ustat) // 62 + LINXY (__NR_ustat, sys_ustat), // 62 GENXY (__NR_dup2, sys_dup2), // 63 GENX_ (__NR_getppid, sys_getppid), // 64 GENX_ (__NR_getpgrp, sys_getpgrp), // 65 diff --git a/coregrind/m_syswrap/syswrap-mips64-linux.c b/coregrind/m_syswrap/syswrap-mips64-linux.c index 67e5c0b37d..8e2dcbe93c 100644 --- a/coregrind/m_syswrap/syswrap-mips64-linux.c +++ b/coregrind/m_syswrap/syswrap-mips64-linux.c @@ -216,7 +216,6 @@ SysRes sys_set_tls ( ThreadId tid, Addr tlsptr ) DECL_TEMPLATE (mips_linux, sys_set_thread_area); DECL_TEMPLATE (mips_linux, sys_vmsplice); -DECL_TEMPLATE (mips_linux, sys_ustat); DECL_TEMPLATE (mips_linux, sys_sysfs); DECL_TEMPLATE (mips_linux, sys_swapon); DECL_TEMPLATE (mips_linux, sys_swapoff); @@ -248,12 +247,6 @@ PRE(sys_sched_rr_get_interval) *flags |= SfMayBlock; } -PRE(sys_ustat) -{ - PRINT("sys_ustat ( %#" FMT_REGWORD "x, %#" FMT_REGWORD "x)", ARG1, ARG2); - PRE_REG_READ2(long, "ustat", int, flags, const void *, path); -} - PRE(sys_swapon) { PRINT("sys_swapon ( %#" FMT_REGWORD "x, %#" FMT_REGWORD "x )", ARG1, ARG2); @@ -649,7 +642,7 @@ static SyscallTableEntry syscall_main_table[] = { LINX_ (__NR_utime, sys_utime), GENX_ (__NR_mknod, sys_mknod), LINX_ (__NR_personality, sys_personality), - PLAX_ (__NR_ustat, sys_ustat), + LINXY (__NR_ustat, sys_ustat), GENXY (__NR_statfs, sys_statfs), GENXY (__NR_fstatfs, sys_fstatfs), PLAX_ (__NR_sysfs, sys_sysfs), diff --git a/coregrind/m_syswrap/syswrap-ppc32-linux.c b/coregrind/m_syswrap/syswrap-ppc32-linux.c index b5d45e1094..d2b59786c4 100644 --- a/coregrind/m_syswrap/syswrap-ppc32-linux.c +++ b/coregrind/m_syswrap/syswrap-ppc32-linux.c @@ -685,7 +685,7 @@ static SyscallTableEntry syscall_table[] = { GENX_(__NR_umask, sys_umask), // 60 GENX_(__NR_chroot, sys_chroot), // 61 -//.. // (__NR_ustat, sys_ustat) // 62 SVr4 -- deprecated + LINXY(__NR_ustat, sys_ustat), // 62 SVr4 -- deprecated GENXY(__NR_dup2, sys_dup2), // 63 GENX_(__NR_getppid, sys_getppid), // 64 diff --git a/coregrind/m_syswrap/syswrap-ppc64-linux.c b/coregrind/m_syswrap/syswrap-ppc64-linux.c index 764fb557ec..3d6c2e4eda 100644 --- a/coregrind/m_syswrap/syswrap-ppc64-linux.c +++ b/coregrind/m_syswrap/syswrap-ppc64-linux.c @@ -674,7 +674,7 @@ static SyscallTableEntry syscall_table[] = { GENX_(__NR_umask, sys_umask), // 60 GENX_(__NR_chroot, sys_chroot), // 61 -// _____(__NR_ustat, sys_ustat), // 62 + LINXY(__NR_ustat, sys_ustat), // 62 GENXY(__NR_dup2, sys_dup2), // 63 GENX_(__NR_getppid, sys_getppid), // 64 diff --git a/coregrind/m_syswrap/syswrap-s390x-linux.c b/coregrind/m_syswrap/syswrap-s390x-linux.c index 8202c1922d..65a26a02da 100644 --- a/coregrind/m_syswrap/syswrap-s390x-linux.c +++ b/coregrind/m_syswrap/syswrap-s390x-linux.c @@ -485,7 +485,7 @@ static SyscallTableEntry syscall_table[] = { GENX_(__NR_umask, sys_umask), // 60 GENX_(__NR_chroot, sys_chroot), // 61 -// ?????(__NR_ustat, sys_ustat), /* deprecated in favor of statfs */ // 62 + LINXY(__NR_ustat, sys_ustat), /* deprecated in favor of statfs */ // 62 GENXY(__NR_dup2, sys_dup2), // 63 GENX_(__NR_getppid, sys_getppid), // 64 diff --git a/coregrind/m_syswrap/syswrap-x86-linux.c b/coregrind/m_syswrap/syswrap-x86-linux.c index 45216b45f4..0b8373ffa8 100644 --- a/coregrind/m_syswrap/syswrap-x86-linux.c +++ b/coregrind/m_syswrap/syswrap-x86-linux.c @@ -1230,7 +1230,7 @@ static SyscallTableEntry syscall_table[] = { //zz GENX_(__NR_umask, sys_umask), // 60 GENX_(__NR_chroot, sys_chroot), // 61 -//zz // (__NR_ustat, sys_ustat) // 62 SVr4 -- deprecated + LINXY(__NR_ustat, sys_ustat), // 62 SVr4 -- deprecated GENXY(__NR_dup2, sys_dup2), // 63 GENX_(__NR_getppid, sys_getppid), // 64 diff --git a/include/vki/vki-linux.h b/include/vki/vki-linux.h index 8c919845bc..c31035cbbe 100644 --- a/include/vki/vki-linux.h +++ b/include/vki/vki-linux.h @@ -171,6 +171,25 @@ typedef struct { typedef int __vki_kernel_key_t; typedef int __vki_kernel_mqd_t; +//---------------------------------------------------------------------- +// From pre-git history /include/linux/types.h +//---------------------------------------------------------------------- + +struct vki_ustat { +#if defined(VGA_mips32) || defined(VGA_mips64) || defined(VGA_nanomips) + long f_tfree; +#else + int f_tfree; +#endif +#if defined(VGA_s390x) + unsigned int f_tinode; +#else + unsigned long f_tinode; +#endif + char f_fname[6]; + char f_fpack[6]; +}; + //---------------------------------------------------------------------- // From linux-2.6.8.1/include/linux/types.h //---------------------------------------------------------------------- |
From: Mark W. <ma...@so...> - 2025-07-17 10:40:10
|
https://sourceware.org/cgit/valgrind/commit/?id=bd1e857cd493f4d1e64c3f5ae1061650644c666b commit bd1e857cd493f4d1e64c3f5ae1061650644c666b Author: Mark Wielaard <ma...@kl...> Date: Wed Jul 16 02:45:39 2025 +0200 Check mmap fd is valid, if used, and fail early with EBADF if not mmap should fail with EBADF if the given fd is bad (or used by valgrind itself) when used (flags does not contain MAP_ANONYMOUS). Check both with ML_(fd_allowed) (which might only warn) and fcntl (VKI_F_GETFD) to see if the file descriptor is valid. Fail early so the address space manager and the actual mmap call don't do unnecessary work (and might fail with a different error code). This fixes the LTP mmap08 testcase. https://bugs.kde.org/show_bug.cgi?id=506970 Diff: --- NEWS | 1 + coregrind/m_syswrap/syswrap-generic.c | 11 +++++++++++ 2 files changed, 12 insertions(+) diff --git a/NEWS b/NEWS index 796d9716e5..868d4218fe 100644 --- a/NEWS +++ b/NEWS @@ -56,6 +56,7 @@ are not entered into bugzilla tend to get forgotten about or ignored. 506499 Unhandled syscall 592 (exterrctl - FreeBSD 506795 Better report which clone flags are problematic 506930 valgrind allows SIGKILL being reset to SIG_DFL +506970 mmap needs an EBADF fd_allowed check To see details of a given bug, visit https://bugs.kde.org/show_bug.cgi?id=XXXXXX diff --git a/coregrind/m_syswrap/syswrap-generic.c b/coregrind/m_syswrap/syswrap-generic.c index 50415a2faa..7ad2809807 100644 --- a/coregrind/m_syswrap/syswrap-generic.c +++ b/coregrind/m_syswrap/syswrap-generic.c @@ -2653,6 +2653,17 @@ ML_(generic_PRE_sys_mmap) ( ThreadId tid, VG_(core_panic)("can't use ML_(generic_PRE_sys_mmap) on Darwin"); # endif + /* fd (arg4) is only used when flags (arg4) does not contain + MAP_ANONYMOUS. ML_(fd_allowed) might just warn (with --track-fds) + and not fail, unless it is a Valgrind owned file descriptor. + So also check with fcntl (F_GETFD) to know if it really is a bad + fd. Fail early in that case with EBADF. */ + if (!(arg4 & VKI_MAP_ANONYMOUS) + && (!ML_(fd_allowed)(arg5, "mmap", tid, False) + || VG_(fcntl) (arg5, VKI_F_GETFD, 0) < 0)) { + return VG_(mk_SysRes_Error)( VKI_EBADF ); + } + if (arg2 == 0) { /* SuSV3 says: If len is zero, mmap() shall fail and no mapping shall be established. */ |
From: Florian K. <fk...@so...> - 2025-07-17 07:04:34
|
https://sourceware.org/cgit/valgrind/commit/?id=92b886de45265ca15e87f67d4245d77f292de80e commit 92b886de45265ca15e87f67d4245d77f292de80e Author: Florian Krohm <fl...@ei...> Date: Thu Jul 17 07:04:03 2025 +0000 Constant folding for Iop_Shl8/16, Iop_Shr8/16 and Iop_Sar8/16. (BZ 506211) Part of fixing https://bugs.kde.org/show_bug.cgi?id=506211 Diff: --- VEX/priv/ir_opt.c | 56 +++++++++++++++++++++++++++++++++++++++++ none/tests/iropt-test/binary.c | 16 ++++++++---- none/tests/iropt-test/irops.tab | 12 ++++----- 3 files changed, 73 insertions(+), 11 deletions(-) diff --git a/VEX/priv/ir_opt.c b/VEX/priv/ir_opt.c index 91b266aa1d..4653704d3e 100644 --- a/VEX/priv/ir_opt.c +++ b/VEX/priv/ir_opt.c @@ -2093,6 +2093,22 @@ static IRExpr* fold_Expr_WRK ( IRExpr** env, IRExpr* e ) } /* -- Shl -- */ + case Iop_Shl8: + vassert(e->Iex.Binop.arg2->Iex.Const.con->tag == Ico_U8); + shift = e->Iex.Binop.arg2->Iex.Const.con->Ico.U8; + if (shift >= 0 && shift <= 7) + e2 = IRExpr_Const(IRConst_U8(toUChar( + (e->Iex.Binop.arg1->Iex.Const.con->Ico.U8 + << shift)))); + break; + case Iop_Shl16: + vassert(e->Iex.Binop.arg2->Iex.Const.con->tag == Ico_U8); + shift = e->Iex.Binop.arg2->Iex.Const.con->Ico.U8; + if (shift >= 0 && shift <= 15) + e2 = IRExpr_Const(IRConst_U16(toUShort( + (e->Iex.Binop.arg1->Iex.Const.con->Ico.U16 + << shift)))); + break; case Iop_Shl32: vassert(e->Iex.Binop.arg2->Iex.Const.con->tag == Ico_U8); shift = (Int)(e->Iex.Binop.arg2->Iex.Const.con->Ico.U8); @@ -2111,6 +2127,28 @@ static IRExpr* fold_Expr_WRK ( IRExpr** env, IRExpr* e ) break; /* -- Sar -- */ + case Iop_Sar8: { + Int s8; + vassert(e->Iex.Binop.arg2->Iex.Const.con->tag == Ico_U8); + s8 = (Char)(e->Iex.Binop.arg1->Iex.Const.con->Ico.U8); + shift = e->Iex.Binop.arg2->Iex.Const.con->Ico.U8; + if (shift >= 0 && shift <= 7) { + s8 >>=/*signed*/ shift; + e2 = IRExpr_Const(IRConst_U8(toUChar(s8))); + } + break; + } + case Iop_Sar16: { + Int s16; + vassert(e->Iex.Binop.arg2->Iex.Const.con->tag == Ico_U8); + s16 = (Short)(e->Iex.Binop.arg1->Iex.Const.con->Ico.U16); + shift = e->Iex.Binop.arg2->Iex.Const.con->Ico.U8; + if (shift >= 0 && shift <= 15) { + s16 >>=/*signed*/ shift; + e2 = IRExpr_Const(IRConst_U16(toUShort(s16))); + } + break; + } case Iop_Sar32: { /* paranoid ... */ /*signed*/ Int s32; @@ -2137,6 +2175,24 @@ static IRExpr* fold_Expr_WRK ( IRExpr** env, IRExpr* e ) } /* -- Shr -- */ + case Iop_Shr8: { + vassert(e->Iex.Binop.arg2->Iex.Const.con->tag == Ico_U8); + shift = e->Iex.Binop.arg2->Iex.Const.con->Ico.U8; + if (shift >= 0 && shift <= 7) + e2 = IRExpr_Const(IRConst_U8(toUChar( + (e->Iex.Binop.arg1->Iex.Const.con->Ico.U8 + >> shift)))); + break; + } + case Iop_Shr16: { + vassert(e->Iex.Binop.arg2->Iex.Const.con->tag == Ico_U8); + shift = e->Iex.Binop.arg2->Iex.Const.con->Ico.U8; + if (shift >= 0 && shift <= 15) + e2 = IRExpr_Const(IRConst_U16(toUShort( + (e->Iex.Binop.arg1->Iex.Const.con->Ico.U16 + >> shift)))); + break; + } case Iop_Shr32: { /* paranoid ... */ /*unsigned*/ UInt u32; diff --git a/none/tests/iropt-test/binary.c b/none/tests/iropt-test/binary.c index 894213a569..2c815c8136 100644 --- a/none/tests/iropt-test/binary.c +++ b/none/tests/iropt-test/binary.c @@ -148,20 +148,26 @@ check_result(const irop_t *op, const test_data_t *data) expected = (int64_t)(int32_t)opnd_l * (int64_t)(int32_t)opnd_r; break; + case Iop_Shl8: + case Iop_Shl16: case Iop_Shl32: - expected = opnd_l << opnd_r; - break; - case Iop_Shl64: expected = opnd_l << opnd_r; break; + case Iop_Shr8: + case Iop_Shr16: case Iop_Shr32: + case Iop_Shr64: expected = opnd_l >> opnd_r; break; - case Iop_Shr64: - expected = opnd_l >> opnd_r; + case Iop_Sar8: + expected = ((int64_t)(opnd_l << 56) >> 56) >> opnd_r; + break; + + case Iop_Sar16: + expected = ((int64_t)(opnd_l << 48) >> 48) >> opnd_r; break; case Iop_Sar32: diff --git a/none/tests/iropt-test/irops.tab b/none/tests/iropt-test/irops.tab index a9f57a4ce1..efae871fbf 100644 --- a/none/tests/iropt-test/irops.tab +++ b/none/tests/iropt-test/irops.tab @@ -164,18 +164,18 @@ // { OPNAME(ModU128), Ity_I128, 2, Ity_I128, Ity_I128 }, // 128 bit // { OPNAME(ModS128), Ity_I128, 2, Ity_I128, Ity_I128 }, // 128 bit -// { OPNAME(Shl8), Ity_I8, 2, Ity_I8, Ity_I8 }, // no folding yet -// { OPNAME(Shl16), Ity_I16, 2, Ity_I16, Ity_I8 }, // no folding yet + { OPNAME(Shl8), Ity_I8, 2, Ity_I8, Ity_I8 }, + { OPNAME(Shl16), Ity_I16, 2, Ity_I16, Ity_I8 }, { OPNAME(Shl32), Ity_I32, 2, Ity_I32, Ity_I8 }, { OPNAME(Shl64), Ity_I64, 2, Ity_I64, Ity_I8 }, -// { OPNAME(Shr8), Ity_I8, 2, Ity_I8, Ity_I8 }, // no folding yet -// { OPNAME(Shr16), Ity_I16, 2, Ity_I16, Ity_I8 }, // no folding yet + { OPNAME(Shr8), Ity_I8, 2, Ity_I8, Ity_I8 }, + { OPNAME(Shr16), Ity_I16, 2, Ity_I16, Ity_I8 }, { OPNAME(Shr32), Ity_I32, 2, Ity_I32, Ity_I8 }, { OPNAME(Shr64), Ity_I64, 2, Ity_I64, Ity_I8 }, -// { OPNAME(Sar8), Ity_I8, 2, Ity_I8, Ity_I8 }, // no folding yet -// { OPNAME(Sar16), Ity_I16, 2, Ity_I16, Ity_I8 }, // no folding yet + { OPNAME(Sar8), Ity_I8, 2, Ity_I8, Ity_I8 }, + { OPNAME(Sar16), Ity_I16, 2, Ity_I16, Ity_I8 }, { OPNAME(Sar32), Ity_I32, 2, Ity_I32, Ity_I8 }, { OPNAME(Sar64), Ity_I64, 2, Ity_I64, Ity_I8 }, |
From: Florian K. <fk...@so...> - 2025-07-16 20:02:20
|
https://sourceware.org/cgit/valgrind/commit/?id=943e7070f3b8dd6f903779640f4f75db6b972e83 commit 943e7070f3b8dd6f903779640f4f75db6b972e83 Author: Florian Krohm <fl...@ei...> Date: Wed Jul 16 20:01:54 2025 +0000 Constant folding for various binary IRops. (BZ 506211) Iop_Add16, Iop_Sub16, Iop_CmpEQ8/16, Iop_CasCmpEQ8/16/32/64, Iop_CmpNE16, Iop_CasCmpNE16, Iop_ExpCmpNE16 Part of fixing https://bugs.kde.org/show_bug.cgi?id=506211 Diff: --- VEX/priv/ir_opt.c | 31 +++++++++++++++++++++++++++++++ none/tests/iropt-test/binary.c | 14 +++++++------- none/tests/iropt-test/irops.tab | 22 +++++++++++----------- 3 files changed, 49 insertions(+), 18 deletions(-) diff --git a/VEX/priv/ir_opt.c b/VEX/priv/ir_opt.c index c37ff08a77..91b266aa1d 100644 --- a/VEX/priv/ir_opt.c +++ b/VEX/priv/ir_opt.c @@ -2019,6 +2019,11 @@ static IRExpr* fold_Expr_WRK ( IRExpr** env, IRExpr* e ) (e->Iex.Binop.arg1->Iex.Const.con->Ico.U8 + e->Iex.Binop.arg2->Iex.Const.con->Ico.U8)))); break; + case Iop_Add16: + e2 = IRExpr_Const(IRConst_U16(toUShort( + (e->Iex.Binop.arg1->Iex.Const.con->Ico.U16 + + e->Iex.Binop.arg2->Iex.Const.con->Ico.U16)))); + break; case Iop_Add32: e2 = IRExpr_Const(IRConst_U32( (e->Iex.Binop.arg1->Iex.Const.con->Ico.U32 @@ -2036,6 +2041,11 @@ static IRExpr* fold_Expr_WRK ( IRExpr** env, IRExpr* e ) (e->Iex.Binop.arg1->Iex.Const.con->Ico.U8 - e->Iex.Binop.arg2->Iex.Const.con->Ico.U8)))); break; + case Iop_Sub16: + e2 = IRExpr_Const(IRConst_U16(toUShort( + (e->Iex.Binop.arg1->Iex.Const.con->Ico.U16 + - e->Iex.Binop.arg2->Iex.Const.con->Ico.U16)))); + break; case Iop_Sub32: e2 = IRExpr_Const(IRConst_U32( (e->Iex.Binop.arg1->Iex.Const.con->Ico.U32 @@ -2153,12 +2163,26 @@ static IRExpr* fold_Expr_WRK ( IRExpr** env, IRExpr* e ) } /* -- CmpEQ -- */ + case Iop_CmpEQ8: + case Iop_CasCmpEQ8: + e2 = IRExpr_Const(IRConst_U1(toBool( + (e->Iex.Binop.arg1->Iex.Const.con->Ico.U8 + == e->Iex.Binop.arg2->Iex.Const.con->Ico.U8)))); + break; + case Iop_CmpEQ16: + case Iop_CasCmpEQ16: + e2 = IRExpr_Const(IRConst_U1(toBool( + (e->Iex.Binop.arg1->Iex.Const.con->Ico.U16 + == e->Iex.Binop.arg2->Iex.Const.con->Ico.U16)))); + break; case Iop_CmpEQ32: + case Iop_CasCmpEQ32: e2 = IRExpr_Const(IRConst_U1(toBool( (e->Iex.Binop.arg1->Iex.Const.con->Ico.U32 == e->Iex.Binop.arg2->Iex.Const.con->Ico.U32)))); break; case Iop_CmpEQ64: + case Iop_CasCmpEQ64: e2 = IRExpr_Const(IRConst_U1(toBool( (e->Iex.Binop.arg1->Iex.Const.con->Ico.U64 == e->Iex.Binop.arg2->Iex.Const.con->Ico.U64)))); @@ -2172,6 +2196,13 @@ static IRExpr* fold_Expr_WRK ( IRExpr** env, IRExpr* e ) ((0xFF & e->Iex.Binop.arg1->Iex.Const.con->Ico.U8) != (0xFF & e->Iex.Binop.arg2->Iex.Const.con->Ico.U8))))); break; + case Iop_CmpNE16: + case Iop_CasCmpNE16: + case Iop_ExpCmpNE16: + e2 = IRExpr_Const(IRConst_U1(toBool( + (e->Iex.Binop.arg1->Iex.Const.con->Ico.U16 + != e->Iex.Binop.arg2->Iex.Const.con->Ico.U16)))); + break; case Iop_CmpNE32: case Iop_CasCmpNE32: case Iop_ExpCmpNE32: diff --git a/none/tests/iropt-test/binary.c b/none/tests/iropt-test/binary.c index ec4fa21d1c..894213a569 100644 --- a/none/tests/iropt-test/binary.c +++ b/none/tests/iropt-test/binary.c @@ -199,23 +199,23 @@ check_result(const irop_t *op, const test_data_t *data) case Iop_CmpEQ16: case Iop_CmpEQ32: case Iop_CmpEQ64: -// case Iop_CasCmpEQ8: -// case Iop_CasCmpEQ16: -// case Iop_CasCmpEQ32: -// case Iop_CasCmpEQ64: + case Iop_CasCmpEQ8: + case Iop_CasCmpEQ16: + case Iop_CasCmpEQ32: + case Iop_CasCmpEQ64: expected = opnd_l == opnd_r; break; case Iop_CmpNE8: -// case Iop_CmpNE16: + case Iop_CmpNE16: case Iop_CmpNE32: case Iop_CmpNE64: case Iop_CasCmpNE8: -// case Iop_CasCmpNE16: + case Iop_CasCmpNE16: case Iop_CasCmpNE32: case Iop_CasCmpNE64: case Iop_ExpCmpNE8: -// case Iop_ExpCmpNE16: + case Iop_ExpCmpNE16: case Iop_ExpCmpNE32: case Iop_ExpCmpNE64: expected = opnd_l != opnd_r; diff --git a/none/tests/iropt-test/irops.tab b/none/tests/iropt-test/irops.tab index 02afa6423a..a9f57a4ce1 100644 --- a/none/tests/iropt-test/irops.tab +++ b/none/tests/iropt-test/irops.tab @@ -111,12 +111,12 @@ // BINARY { OPNAME(Add8), Ity_I8, 2, Ity_I8, Ity_I8 }, -// { OPNAME(Add16), Ity_I16, 2, Ity_I16, Ity_I16 }, // no folding yet + { OPNAME(Add16), Ity_I16, 2, Ity_I16, Ity_I16 }, { OPNAME(Add32), Ity_I32, 2, Ity_I32, Ity_I32 }, { OPNAME(Add64), Ity_I64, 2, Ity_I64, Ity_I64 }, { OPNAME(Sub8), Ity_I8, 2, Ity_I8, Ity_I8 }, -// { OPNAME(Sub16), Ity_I16, 2, Ity_I16, Ity_I16 }, // no folding yet + { OPNAME(Sub16), Ity_I16, 2, Ity_I16, Ity_I16 }, { OPNAME(Sub32), Ity_I32, 2, Ity_I32, Ity_I32 }, { OPNAME(Sub64), Ity_I64, 2, Ity_I64, Ity_I64 }, @@ -197,13 +197,13 @@ { OPNAME(Xor32), Ity_I32, 2, Ity_I32, Ity_I32 }, { OPNAME(Xor64), Ity_I64, 2, Ity_I64, Ity_I64 }, -// { OPNAME(CmpEQ8), Ity_I1, 2, Ity_I8, Ity_I8 }, // no folding yet -// { OPNAME(CmpEQ16), Ity_I1, 2, Ity_I16, Ity_I16 }, // no folding yet + { OPNAME(CmpEQ8), Ity_I1, 2, Ity_I8, Ity_I8 }, + { OPNAME(CmpEQ16), Ity_I1, 2, Ity_I16, Ity_I16 }, { OPNAME(CmpEQ32), Ity_I1, 2, Ity_I32, Ity_I32 }, { OPNAME(CmpEQ64), Ity_I1, 2, Ity_I64, Ity_I64 }, { OPNAME(CmpNE8), Ity_I1, 2, Ity_I8, Ity_I8 }, -// { OPNAME(CmpNE16), Ity_I1, 2, Ity_I16, Ity_I16 }, // no folding yet + { OPNAME(CmpNE16), Ity_I1, 2, Ity_I16, Ity_I16 }, { OPNAME(CmpNE32), Ity_I1, 2, Ity_I32, Ity_I32 }, { OPNAME(CmpNE64), Ity_I1, 2, Ity_I64, Ity_I64 }, @@ -219,18 +219,18 @@ { OPNAME(CmpLE32S), Ity_I1, 2, Ity_I32, Ity_I32 }, { OPNAME(CmpLE64S), Ity_I1, 2, Ity_I64, Ity_I64 }, -// { OPNAME(CasCmpEQ8), Ity_I1, 2, Ity_I8, Ity_I8 }, // no folding yet -// { OPNAME(CasCmpEQ16), Ity_I1, 2, Ity_I16, Ity_I16 }, // no folding yet -// { OPNAME(CasCmpEQ32), Ity_I1, 2, Ity_I32, Ity_I32 }, // no folding yet -// { OPNAME(CasCmpEQ64), Ity_I1, 2, Ity_I64, Ity_I64 }, // no folding yet + { OPNAME(CasCmpEQ8), Ity_I1, 2, Ity_I8, Ity_I8 }, + { OPNAME(CasCmpEQ16), Ity_I1, 2, Ity_I16, Ity_I16 }, + { OPNAME(CasCmpEQ32), Ity_I1, 2, Ity_I32, Ity_I32 }, + { OPNAME(CasCmpEQ64), Ity_I1, 2, Ity_I64, Ity_I64 }, { OPNAME(CasCmpNE8), Ity_I1, 2, Ity_I8, Ity_I8 }, -// { OPNAME(CasCmpNE16), Ity_I1, 2, Ity_I16, Ity_I16 }, // no folding yet + { OPNAME(CasCmpNE16), Ity_I1, 2, Ity_I16, Ity_I16 }, { OPNAME(CasCmpNE32), Ity_I1, 2, Ity_I32, Ity_I32 }, { OPNAME(CasCmpNE64), Ity_I1, 2, Ity_I64, Ity_I64 }, { OPNAME(ExpCmpNE8), Ity_I1, 2, Ity_I8, Ity_I8 }, -// { OPNAME(ExpCmpNE16), Ity_I1, 2, Ity_I16, Ity_I16 }, // no folding yet + { OPNAME(ExpCmpNE16), Ity_I1, 2, Ity_I16, Ity_I16 }, { OPNAME(ExpCmpNE32), Ity_I1, 2, Ity_I32, Ity_I32 }, { OPNAME(ExpCmpNE64), Ity_I1, 2, Ity_I64, Ity_I64 }, |
From: Florian K. <fk...@so...> - 2025-07-16 17:44:08
|
https://sourceware.org/cgit/valgrind/commit/?id=0593738843903c7c2d6299bf2a47f63ebc08e947 commit 0593738843903c7c2d6299bf2a47f63ebc08e947 Author: Florian Krohm <fl...@ei...> Date: Wed Jul 16 17:43:34 2025 +0000 Constant folding for Iop_CtzNat32/64. (BZ 506211) Part of fixing https://bugs.kde.org/show_bug.cgi?id=506211 Diff: --- VEX/priv/ir_opt.c | 35 +++++++++++++++++++++++++++++++++++ none/tests/iropt-test/irops.tab | 4 ++-- none/tests/iropt-test/unary.c | 23 +++++++++++++++++++++++ 3 files changed, 60 insertions(+), 2 deletions(-) diff --git a/VEX/priv/ir_opt.c b/VEX/priv/ir_opt.c index 140899480f..c37ff08a77 100644 --- a/VEX/priv/ir_opt.c +++ b/VEX/priv/ir_opt.c @@ -1365,6 +1365,30 @@ static UInt fold_ClzNat32 ( UInt value ) return 32; } +/* Helpers for folding CtzNat32/64. */ +static UInt fold_CtzNat_WRK ( ULong value, UInt num_bits ) +{ + UInt count = 0; + + for (UInt i = 1; i <= num_bits; ++i) { + if (value & 0x1) + return count; + value >>= 1; + ++count; + } + return count; +} + +static UInt fold_CtzNat64 ( ULong value ) +{ + return fold_CtzNat_WRK(value, 64); +} + +static UInt fold_CtzNat32 ( UInt value ) +{ + return fold_CtzNat_WRK(value, 32); +} + /* Helpers for folding PopCount32/64. https://graphics.stanford.edu/~seander/bithacks.html#CountBitsSetKernighan As many iterations as 1-bits present. @@ -1739,6 +1763,17 @@ static IRExpr* fold_Expr_WRK ( IRExpr** env, IRExpr* e ) break; } + case Iop_CtzNat32: { + UInt u32 = e->Iex.Unop.arg->Iex.Const.con->Ico.U32; + e2 = IRExpr_Const(IRConst_U32(fold_CtzNat32(u32))); + break; + } + case Iop_CtzNat64: { + ULong u64 = e->Iex.Unop.arg->Iex.Const.con->Ico.U64; + e2 = IRExpr_Const(IRConst_U64(fold_CtzNat64(u64))); + break; + } + case Iop_PopCount32: { UInt u32 = e->Iex.Unop.arg->Iex.Const.con->Ico.U32; e2 = IRExpr_Const(IRConst_U32(fold_PopCount32(u32))); diff --git a/none/tests/iropt-test/irops.tab b/none/tests/iropt-test/irops.tab index 1d06919d16..02afa6423a 100644 --- a/none/tests/iropt-test/irops.tab +++ b/none/tests/iropt-test/irops.tab @@ -101,8 +101,8 @@ { OPNAME(ClzNat32), Ity_I32, 1, Ity_I32 }, { OPNAME(ClzNat64), Ity_I64, 1, Ity_I64 }, -// { OPNAME(CtzNat32), Ity_I32, 1, Ity_I32 }, // no folding yet -// { OPNAME(CtzNat64), Ity_I64, 1, Ity_I64 }, // no folding yet + { OPNAME(CtzNat32), Ity_I32, 1, Ity_I32 }, + { OPNAME(CtzNat64), Ity_I64, 1, Ity_I64 }, { OPNAME(PopCount32), Ity_I32, 1, Ity_I32 }, { OPNAME(PopCount64), Ity_I64, 1, Ity_I64 }, diff --git a/none/tests/iropt-test/unary.c b/none/tests/iropt-test/unary.c index 6d664a1b84..e6554cef60 100644 --- a/none/tests/iropt-test/unary.c +++ b/none/tests/iropt-test/unary.c @@ -33,6 +33,7 @@ static void run_random_tests(const irop_t *, test_data_t *); static uint64_t left(uint64_t, unsigned); static uint32_t popcount(uint64_t); static uint32_t clz(uint64_t, unsigned); +static uint32_t ctz(uint64_t, unsigned); void @@ -201,6 +202,9 @@ check_result(const irop_t *op, const test_data_t *data) case Iop_ClzNat32: expected = clz(opnd, 32); break; case Iop_ClzNat64: expected = clz(opnd, 64); break; + case Iop_CtzNat32: expected = ctz(opnd, 32); break; + case Iop_CtzNat64: expected = ctz(opnd, 64); break; + default: panic("%s: operator %s not handled\n", __func__, op->name); } @@ -283,3 +287,22 @@ clz(uint64_t value, unsigned num_bits) } return num_bits - last_seen_1bit; } + + +static uint32_t +ctz(uint64_t value, unsigned num_bits ) +{ + unsigned count = 0; + unsigned num_nibbles = num_bits / 4; + + for (unsigned i = 0; i < num_nibbles; ++i) { + UInt nibble = value & 0xF; + if ((nibble & 0x1) == 0x1) return count; + if ((nibble & 0x2) == 0x2) return count + 1; + if ((nibble & 0x4) == 0x4) return count + 2; + if ((nibble & 0x8) == 0x8) return count + 3; + count += 4; + value >>= 4; + } + return count; +} |
From: Florian K. <fk...@so...> - 2025-07-16 14:55:15
|
https://sourceware.org/cgit/valgrind/commit/?id=c164cf37aca7661f76440e14d817dcfeb4c4fc82 commit c164cf37aca7661f76440e14d817dcfeb4c4fc82 Author: Florian Krohm <fl...@ei...> Date: Wed Jul 16 14:54:44 2025 +0000 Constant folding for Iop_ClzNat32/64. (BZ 506211) Part of fixing https://bugs.kde.org/show_bug.cgi?id=506211 Diff: --- VEX/priv/ir_opt.c | 30 ++++++++++++++++++++++++++++++ none/tests/iropt-test/irops.tab | 4 ++-- none/tests/iropt-test/unary.c | 18 ++++++++++++++++++ 3 files changed, 50 insertions(+), 2 deletions(-) diff --git a/VEX/priv/ir_opt.c b/VEX/priv/ir_opt.c index f0458cb285..140899480f 100644 --- a/VEX/priv/ir_opt.c +++ b/VEX/priv/ir_opt.c @@ -1346,6 +1346,25 @@ static UInt fold_Clz32 ( UInt value ) return 0; } +/* Helpers for folding ClzNat32/64. */ +static UInt fold_ClzNat64 ( ULong value ) +{ + UInt i; + for (i = 0; i < 64; ++i) { + if (0ULL != (value & (((ULong)1) << (63 - i)))) return i; + } + return 64; +} + +static UInt fold_ClzNat32 ( UInt value ) +{ + UInt i; + for (i = 0; i < 32; ++i) { + if (0 != (value & (((UInt)1) << (31 - i)))) return i; + } + return 32; +} + /* Helpers for folding PopCount32/64. https://graphics.stanford.edu/~seander/bithacks.html#CountBitsSetKernighan As many iterations as 1-bits present. @@ -1709,6 +1728,17 @@ static IRExpr* fold_Expr_WRK ( IRExpr** env, IRExpr* e ) break; } + case Iop_ClzNat32: { + UInt u32 = e->Iex.Unop.arg->Iex.Const.con->Ico.U32; + e2 = IRExpr_Const(IRConst_U32(fold_ClzNat32(u32))); + break; + } + case Iop_ClzNat64: { + ULong u64 = e->Iex.Unop.arg->Iex.Const.con->Ico.U64; + e2 = IRExpr_Const(IRConst_U64(fold_ClzNat64(u64))); + break; + } + case Iop_PopCount32: { UInt u32 = e->Iex.Unop.arg->Iex.Const.con->Ico.U32; e2 = IRExpr_Const(IRConst_U32(fold_PopCount32(u32))); diff --git a/none/tests/iropt-test/irops.tab b/none/tests/iropt-test/irops.tab index e73ec46a87..1d06919d16 100644 --- a/none/tests/iropt-test/irops.tab +++ b/none/tests/iropt-test/irops.tab @@ -98,8 +98,8 @@ // { OPNAME(Ctz32), Ity_I32, 1, Ity_I32 }, // deprecated, undefined behaviour // { OPNAME(Ctz64), Ity_I64, 1, Ity_I64 }, // deprecated, undefined behaviour -// { OPNAME(ClzNat32), Ity_I32, 1, Ity_I32 }, // no folding yet -// { OPNAME(ClzNat64), Ity_I64, 1, Ity_I64 }, // no folding yet + { OPNAME(ClzNat32), Ity_I32, 1, Ity_I32 }, + { OPNAME(ClzNat64), Ity_I64, 1, Ity_I64 }, // { OPNAME(CtzNat32), Ity_I32, 1, Ity_I32 }, // no folding yet // { OPNAME(CtzNat64), Ity_I64, 1, Ity_I64 }, // no folding yet diff --git a/none/tests/iropt-test/unary.c b/none/tests/iropt-test/unary.c index bb26138487..6d664a1b84 100644 --- a/none/tests/iropt-test/unary.c +++ b/none/tests/iropt-test/unary.c @@ -32,6 +32,7 @@ static void run_selected_tests(const irop_t *, test_data_t *); static void run_random_tests(const irop_t *, test_data_t *); static uint64_t left(uint64_t, unsigned); static uint32_t popcount(uint64_t); +static uint32_t clz(uint64_t, unsigned); void @@ -197,6 +198,9 @@ check_result(const irop_t *op, const test_data_t *data) expected = popcount(opnd); break; + case Iop_ClzNat32: expected = clz(opnd, 32); break; + case Iop_ClzNat64: expected = clz(opnd, 64); break; + default: panic("%s: operator %s not handled\n", __func__, op->name); } @@ -265,3 +269,17 @@ popcount(uint64_t value) } return count; } + + +static uint32_t +clz(uint64_t value, unsigned num_bits) +{ + unsigned last_seen_1bit = 0; + + for (int i = 1; i <= num_bits; ++i) { + if (value & 0x1) + last_seen_1bit = i; + value >>= 1; + } + return num_bits - last_seen_1bit; +} |
From: Florian K. <fk...@so...> - 2025-07-16 11:52:07
|
https://sourceware.org/cgit/valgrind/commit/?id=21bc095a32ad715a5857d11111703a34eca62b79 commit 21bc095a32ad715a5857d11111703a34eca62b79 Author: Florian Krohm <fl...@ei...> Date: Wed Jul 16 11:51:15 2025 +0000 iropt-test: Also test with random inputs; reorg the code a bit New utility functions: get_random_value and get_selected_values Add command line option -rNUM to specify the number of random tests per operator. Diff: --- none/tests/iropt-test/binary.c | 116 +++++++++++++++++--------------- none/tests/iropt-test/iropt-test.vgtest | 3 +- none/tests/iropt-test/main.c | 9 ++- none/tests/iropt-test/unary.c | 74 ++++++++++---------- none/tests/iropt-test/util.c | 55 +++++++++++++++ none/tests/iropt-test/vtest.h | 3 + 6 files changed, 163 insertions(+), 97 deletions(-) diff --git a/none/tests/iropt-test/binary.c b/none/tests/iropt-test/binary.c index c3f36c1884..ec4fa21d1c 100644 --- a/none/tests/iropt-test/binary.c +++ b/none/tests/iropt-test/binary.c @@ -27,90 +27,96 @@ #include "vtest.h" static void check_result(const irop_t *, const test_data_t *); -static void run_tests(const irop_t *, test_data_t *, unsigned, uint64_t *, - unsigned, uint64_t *); +static void run_tests(const irop_t *, test_data_t *); +static void run_shift_tests(const irop_t *, test_data_t *); static int is_shift_op(IROp); void test_binary_op(const irop_t *op, test_data_t *data) { - opnd_t *opnd_l = &data->opnds[0]; - - switch (opnd_l->type) { - case Ity_I1: { - uint64_t values[] = { 0, 1 }; - - run_tests(op, data, NUM_EL(values), values, NUM_EL(values), values); - break; - } + if (is_shift_op(op->op)) + run_shift_tests(op, data); + else + run_tests(op, data); +} - case Ity_I8: { - uint64_t values[] = { 0, 1, 2, UINT8_MAX - 1, UINT8_MAX }; - uint64_t shifts[] = { 0, 1, 2, 6, 7 }; - if (is_shift_op(op->op)) - run_tests(op, data, NUM_EL(values), values, NUM_EL(shifts), shifts); - else - run_tests(op, data, NUM_EL(values), values, NUM_EL(values), values); - break; - } +static void +run_selected_tests(const irop_t *op, test_data_t *data) +{ + opnd_t *opnd_l = &data->opnds[0]; + opnd_t *opnd_r = &data->opnds[1]; + unsigned num_val_l, num_val_r; + const uint64_t *values_l = get_selected_values(opnd_l->type, &num_val_l); + const uint64_t *values_r = get_selected_values(opnd_r->type, &num_val_r); - case Ity_I16: { - uint64_t values[] = { 0, 1, 2, UINT16_MAX - 1, UINT16_MAX }; - uint64_t shifts[] = { 0, 1, 2, 14, 15 }; + for (unsigned i = 0; i < num_val_l; ++i) { + opnd_l->value = values_l[i]; + for (unsigned j = 0; j < num_val_r; ++j) { + opnd_r->value = values_r[j]; - if (is_shift_op(op->op)) - run_tests(op, data, NUM_EL(values), values, NUM_EL(shifts), shifts); - else - run_tests(op, data, NUM_EL(values), values, NUM_EL(values), values); - break; + valgrind_execute_test(op, data); + check_result(op, data); + } } +} - case Ity_I32: { - uint64_t values[] = { 0, 1, 2, UINT32_MAX - 1, UINT32_MAX }; - uint64_t shifts[] = { 0, 1, 2, 30, 31 }; - - if (is_shift_op(op->op)) - run_tests(op, data, NUM_EL(values), values, NUM_EL(shifts), shifts); - else - run_tests(op, data, NUM_EL(values), values, NUM_EL(values), values); - break; - } - case Ity_I64: { - uint64_t values[] = { 0, 1, 2, UINT64_MAX - 1, UINT64_MAX }; - uint64_t shifts[] = { 0, 1, 2, 62, 63 }; +/* Test with pseudo-random numbers */ +static void +run_random_tests(const irop_t *op, test_data_t *data) +{ + opnd_t *opnd_l = &data->opnds[0]; + opnd_t *opnd_r = &data->opnds[1]; - if (is_shift_op(op->op)) - run_tests(op, data, NUM_EL(values), values, NUM_EL(shifts), shifts); - else - run_tests(op, data, NUM_EL(values), values, NUM_EL(values), values); - break; - } + for (unsigned i = 0; i < num_random_tests; ++i) { + opnd_l->value = get_random_value(opnd_l->type); + opnd_r->value = get_random_value(opnd_r->type); - default: - panic(__func__); + valgrind_execute_test(op, data); + check_result(op, data); } } +/* OP is a shift operator. */ static void -run_tests(const irop_t *op, test_data_t *data, unsigned num_val_l, - uint64_t *values_l, unsigned num_val_r, uint64_t *values_r) +run_shift_tests(const irop_t *op, test_data_t *data) { opnd_t *opnd_l = &data->opnds[0]; opnd_t *opnd_r = &data->opnds[1]; + unsigned num_shiftee; + const uint64_t *shiftee = get_selected_values(opnd_l->type, &num_shiftee); + unsigned max_shift_amount = bitsof_irtype(opnd_r->type) - 1; - for (unsigned i = 0; i < num_val_l; ++i) { - opnd_l->value = values_l[i]; - for (unsigned j = 0; j < num_val_r; ++j) { - opnd_r->value = values_r[j]; + /* Shift selected values with all possible shift amounts */ + for (unsigned i = 0; i < num_shiftee; ++i) { + opnd_l->value = shiftee[i]; + for (unsigned j = 0; j < max_shift_amount; ++j) { + opnd_r->value = j; valgrind_execute_test(op, data); check_result(op, data); } } + + /* Shift random values with random shift amounts */ + for (unsigned i = 0; i < num_random_tests; ++i) { + opnd_l->value = get_random_value(opnd_l->type); + opnd_r->value = get_random_value(opnd_r->type) & max_shift_amount; + + valgrind_execute_test(op, data); + check_result(op, data); + } +} + + +static void +run_tests(const irop_t *op, test_data_t *data) +{ + run_selected_tests(op, data); + run_random_tests(op, data); } diff --git a/none/tests/iropt-test/iropt-test.vgtest b/none/tests/iropt-test/iropt-test.vgtest index 8becafdf8c..de31de6046 100644 --- a/none/tests/iropt-test/iropt-test.vgtest +++ b/none/tests/iropt-test/iropt-test.vgtest @@ -1,4 +1,5 @@ prog: iropt-test -#args: -v -v +#args: -v -v -r10 +args: -r100 vgopts: -q --vex-guest-chase=no diff --git a/none/tests/iropt-test/main.c b/none/tests/iropt-test/main.c index 28b8d23e4b..2622515e55 100644 --- a/none/tests/iropt-test/main.c +++ b/none/tests/iropt-test/main.c @@ -38,18 +38,23 @@ static void check_irops_table(void); static test_data_t *new_test_data(const irop_t *); int verbose = 0; +unsigned num_random_tests; int main(int argc, char *argv[]) { assert(sizeof(long long) == 8); + assert(RAND_MAX == INT32_MAX); for (int i = 1; i < argc; ++i) { if (strcmp(argv[i], "-v") == 0) ++verbose; - else if (strcmp(argv[i], "--help") == 0) { + else if (strncmp(argv[i], "-r", 2) == 0) { + num_random_tests = atoi(argv[i] + 2); + } else if (strcmp(argv[i], "--help") == 0) { printf("\niropt-test [ -v | --help ]\n"); + printf("\n\t -rNUM number of random tests per IRop\n"); printf("\n\t -v verbose mode; shows IROps being tested\n"); printf("\n\t -v -v verbose mode, extreme edition\n\n"); return 0; @@ -72,7 +77,7 @@ main(int argc, char *argv[]) const irop_t *op = irops +i; if (verbose) - printf("\nTesting operator %s\n", op->name); + printf("Testing operator %s\n", op->name); test_data_t *data = new_test_data(op); diff --git a/none/tests/iropt-test/unary.c b/none/tests/iropt-test/unary.c index 44af3203dd..bb26138487 100644 --- a/none/tests/iropt-test/unary.c +++ b/none/tests/iropt-test/unary.c @@ -23,11 +23,13 @@ */ #include <stdio.h> // printf +#include <stdlib.h> // rand #include <stdint.h> // UINT64_MAX #include "vtest.h" static void check_result(const irop_t *, const test_data_t *); -static void run_tests(const irop_t *, test_data_t *, unsigned, uint64_t *); +static void run_selected_tests(const irop_t *, test_data_t *); +static void run_random_tests(const irop_t *, test_data_t *); static uint64_t left(uint64_t, unsigned); static uint32_t popcount(uint64_t); @@ -38,47 +40,25 @@ test_unary_op(const irop_t *op, test_data_t *data) opnd_t *opnd = &data->opnds[0]; switch (opnd->type) { - case Ity_I1: { - uint64_t values[] = { 0, 1 }; - - run_tests(op, data, NUM_EL(values), values); - break; - } - + case Ity_I1: case Ity_I8: { - uint64_t values[] = { 0, 1, 2, UINT8_MAX - 1, UINT8_MAX }; - - run_tests(op, data, NUM_EL(values), values); - break; - } - - case Ity_I16: { - uint64_t values[] = { 0, 1, 2, UINT16_MAX - 1, UINT16_MAX, - /* and for the benefit of Iop_16HIto8: */ - 1 << 8, 2 << 8, UINT8_MAX << 8 - }; - - run_tests(op, data, NUM_EL(values), values); - break; - } - - case Ity_I32: { - uint64_t values[] = { 0, 1, 2, UINT32_MAX - 1, UINT32_MAX, - /* and for the benefit of Iop_32HIto16: */ - 1 << 16, 2 << 16, (uint64_t)UINT16_MAX << 16 - }; - run_tests(op, data, NUM_EL(values), values); + /* Exhaustive */ + unsigned max = (1 << bitsof_irtype(opnd->type)) - 1; + for (unsigned i = 0; i <= max; ++i) { + opnd->value = i; + + valgrind_execute_test(op, data); + check_result(op, data); + } break; } - case Ity_I64: { - uint64_t values[] = { 0, 1, 2, UINT64_MAX - 1, UINT64_MAX, - /* and for the benefit of Iop_64HIto32: */ - (uint64_t)1 << 32, (uint64_t)2 << 32, (uint64_t)UINT32_MAX << 32 - }; - run_tests(op, data, NUM_EL(values), values); + case Ity_I16: + case Ity_I32: + case Ity_I64: + run_selected_tests(op, data); + run_random_tests(op, data); break; - } default: panic(__func__); @@ -87,10 +67,11 @@ test_unary_op(const irop_t *op, test_data_t *data) static void -run_tests(const irop_t *op, test_data_t *data, unsigned num_val, - uint64_t *values) +run_selected_tests(const irop_t *op, test_data_t *data) { opnd_t *opnd = &data->opnds[0]; + unsigned num_val; + const uint64_t *values = get_selected_values(opnd->type, &num_val); for (unsigned i = 0; i < num_val; ++i) { opnd->value = values[i]; @@ -101,6 +82,21 @@ run_tests(const irop_t *op, test_data_t *data, unsigned num_val, } +/* Test with pseudo-random numbers */ +static void +run_random_tests(const irop_t *op, test_data_t *data) +{ + opnd_t *opnd = &data->opnds[0]; + + for (unsigned i = 0; i < num_random_tests; ++i) { + opnd->value = get_random_value(opnd->type); + + valgrind_execute_test(op, data); + check_result(op, data); + } +} + + /* Check the result of a unary operation. */ static void check_result(const irop_t *op, const test_data_t *data) diff --git a/none/tests/iropt-test/util.c b/none/tests/iropt-test/util.c index 80e58570fe..072ff90c36 100644 --- a/none/tests/iropt-test/util.c +++ b/none/tests/iropt-test/util.c @@ -104,3 +104,58 @@ bitsof_irtype(IRType ty) panic(__func__); } } + + +uint64_t +get_random_value(IRType type) +{ + uint64_t val = rand(); + + switch (type) { + case Ity_I1: return val & 0x1; + case Ity_I8: return val & UINT8_MAX; + case Ity_I16: return val & UINT16_MAX; + case Ity_I32: return val & UINT32_MAX; + case Ity_I64: + /* Note, that RAND_MAX == INT32_MAX. Therefore, simply concatenating + two rand() values would never produce a value with MSB == 1 */ + val <<= (32 + 1); + val |= rand() << 1; + val |= rand() & 0x1; + return val; + + default: + panic(__func__); + } +} + + +const uint64_t * +get_selected_values(IRType type, unsigned *num_val) +{ + static const uint64_t values_1bit[] = { 0, 1 }; + static const uint64_t values_8bit[] = { 0, 1, 2, + UINT8_MAX - 1, UINT8_MAX }; + static const uint64_t values_16bit[] = { 0, 1, 2, + UINT8_MAX - 1, UINT8_MAX, UINT8_MAX + 1, + UINT16_MAX - 1, UINT16_MAX }; + static const uint64_t values_32bit[] = { 0, 1, 2, + UINT8_MAX - 1, UINT8_MAX, UINT8_MAX + 1, + UINT16_MAX - 1, UINT16_MAX, UINT16_MAX + 1, + UINT32_MAX - 1, UINT32_MAX }; + static const uint64_t values_64bit[] = { 0, 1, 2, + UINT8_MAX - 1, UINT8_MAX, UINT8_MAX + 1, + UINT16_MAX - 1, UINT16_MAX, UINT16_MAX + 1, + UINT32_MAX - 1, UINT32_MAX, UINT32_MAX + 1, + UINT64_MAX - 1, UINT64_MAX }; + + switch (type) { + case Ity_I1: *num_val = NUM_EL(values_1bit); return values_1bit; + case Ity_I8: *num_val = NUM_EL(values_8bit); return values_8bit; + case Ity_I16: *num_val = NUM_EL(values_16bit); return values_16bit; + case Ity_I32: *num_val = NUM_EL(values_32bit); return values_32bit; + case Ity_I64: *num_val = NUM_EL(values_64bit); return values_64bit; + default: + panic(__func__); + } +} diff --git a/none/tests/iropt-test/vtest.h b/none/tests/iropt-test/vtest.h index d9c1ddaae5..47b397f681 100644 --- a/none/tests/iropt-test/vtest.h +++ b/none/tests/iropt-test/vtest.h @@ -84,8 +84,11 @@ void panic(const char *, ...) __attribute__((noreturn)); void complain(const irop_t *, const test_data_t *, uint64_t expected); unsigned bitsof_irtype(IRType); +uint64_t get_random_value(IRType); +const uint64_t *get_selected_values(IRType, unsigned *); /* Exported variables */ extern int verbose; +extern unsigned num_random_tests; #endif // VTEST_H |
From: Paul F. <pa...@so...> - 2025-07-16 05:11:08
|
https://sourceware.org/cgit/valgrind/commit/?id=9000b0e5540c98f80cceb341423d24b1f5200722 commit 9000b0e5540c98f80cceb341423d24b1f5200722 Author: Paul Floyd <pj...@wa...> Date: Wed Jul 16 07:09:37 2025 +0200 Change [a]sync_sighandler to [a]sync_signalhandler in comments and in one "if (0)" VG_(printf). Diff: --- coregrind/m_signals.c | 4 ++-- coregrind/m_syswrap/syswrap-main.c | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/coregrind/m_signals.c b/coregrind/m_signals.c index 523f4d7fcb..a51840c0a0 100644 --- a/coregrind/m_signals.c +++ b/coregrind/m_signals.c @@ -178,7 +178,7 @@ else if thread is blocked in a syscall marked SfMayBlock - then signals may be delivered to async_sighandler, since we + then signals may be delivered to async_signalhandler, since we temporarily unblocked them for the duration of the syscall, by using the real (SCSS) mask for this thread @@ -2999,7 +2999,7 @@ void sync_signalhandler ( Int sigNo, Bool from_user; if (0) - VG_(printf)("sync_sighandler(%d, %p, %p)\n", sigNo, info, uc); + VG_(printf)("sync_signalhandler(%d, %p, %p)\n", sigNo, info, uc); vg_assert(info != NULL); vg_assert(info->si_signo == sigNo); diff --git a/coregrind/m_syswrap/syswrap-main.c b/coregrind/m_syswrap/syswrap-main.c index 1a7f038d48..5919698f0e 100644 --- a/coregrind/m_syswrap/syswrap-main.c +++ b/coregrind/m_syswrap/syswrap-main.c @@ -2512,7 +2512,7 @@ void VG_(client_syscall) ( ThreadId tid, UInt trc ) /* do_syscall_for_client may not return if the syscall was interrupted by a signal. In that case, flow of control is - first to m_signals.async_sighandler, which calls + first to m_signals.async_signalhandler, which calls VG_(fixup_guest_state_after_syscall_interrupted), which fixes up the guest state, and possibly calls VG_(post_syscall). Once that's done, control drops back @@ -2723,9 +2723,9 @@ void VG_(post_syscall) (ThreadId tid) However, the syscall may get interrupted by an async-signal. In that case do_syscall_for_client/VG_(do_syscall6) do not - return. Instead we wind up in m_signals.async_sighandler. We need + return. Instead we wind up in m_signals.async_signalhandler. We need to fix up the guest state to make it look like the syscall was - interrupted for guest. So async_sighandler calls here, and this + interrupted for guest. So async_signalhandler calls here, and this does the fixup. Note that from here we wind up calling VG_(post_syscall) too. */ |
From: Mark W. <ma...@so...> - 2025-07-15 22:02:53
|
https://sourceware.org/cgit/valgrind/commit/?id=cad20f3e7d42e6371896e2492f0fc3a081314238 commit cad20f3e7d42e6371896e2492f0fc3a081314238 Author: Mark Wielaard <ma...@kl...> Date: Tue Jul 15 23:49:36 2025 +0200 Support mmap MAP_FIXED_NOREPLACE if defined Define VKI_MAP_FIXED_NOREPLACE for amd64-linux, arm-linux, arm64-linux, mips32-linux, mips64-linux, riscv64-linux and x86-linux. If it is defined then ML_(generic_PRE_sys_mmap) will also interpret VKI_MAP_FIXED_NOREPLACE as an MFixed hint. If the aspace manager doesn't find a MAP_FIXED_NOREPLACE ok, then fail with EEXIST. If the actual kernel mmap request fails and MAP_FIXED_NOREPLACE is set also immediately fail with EEXIST without retrying. This fixes the LTP mmap17 testcase. https://bugs.kde.org/show_bug.cgi?id=418756 Diff: --- NEWS | 3 ++- coregrind/m_syswrap/syswrap-generic.c | 19 ++++++++++++++++++- include/vki/vki-amd64-linux.h | 1 + include/vki/vki-arm-linux.h | 1 + include/vki/vki-arm64-linux.h | 1 + include/vki/vki-mips32-linux.h | 1 + include/vki/vki-mips64-linux.h | 1 + include/vki/vki-riscv64-linux.h | 1 + include/vki/vki-x86-linux.h | 1 + 9 files changed, 27 insertions(+), 2 deletions(-) diff --git a/NEWS b/NEWS index 49403da013..796d9716e5 100644 --- a/NEWS +++ b/NEWS @@ -29,8 +29,8 @@ bugzilla (https://bugs.kde.org/enter_bug.cgi?product=valgrind) rather than mailing the developers (or mailing lists) directly -- bugs that are not entered into bugzilla tend to get forgotten about or ignored. -506076 unimplemented fcntl command: 1028 (F_CREATED_QUERY) 338803 Handling of dwz debug alt files or cross-CU is broken +418756 MAP_FIXED_NOREPLACE mmap flag unsupported 493434 Add --track-fds=bad mode (no "leak" tracking) 503098 Incorrect NAN-boxing for float registers in RISC-V 503641 close_range syscalls started failing with 3.25.0 @@ -52,6 +52,7 @@ are not entered into bugzilla tend to get forgotten about or ignored. AMD64_GET_TLSBASE 505228 Wrap linux specific mseal syscall 502968 Wrap linux specific syscalls 457 (listmount) and 458 (statmount) +506076 unimplemented fcntl command: 1028 (F_CREATED_QUERY) 506499 Unhandled syscall 592 (exterrctl - FreeBSD 506795 Better report which clone flags are problematic 506930 valgrind allows SIGKILL being reset to SIG_DFL diff --git a/coregrind/m_syswrap/syswrap-generic.c b/coregrind/m_syswrap/syswrap-generic.c index 50deb1e764..50415a2faa 100644 --- a/coregrind/m_syswrap/syswrap-generic.c +++ b/coregrind/m_syswrap/syswrap-generic.c @@ -2678,7 +2678,12 @@ ML_(generic_PRE_sys_mmap) ( ThreadId tid, (fixed/hint/any), and ask aspacem what we should do. */ mreq.start = arg1; mreq.len = arg2; - if (arg4 & VKI_MAP_FIXED) { + if ((arg4 & VKI_MAP_FIXED) +#if defined(VKI_MAP_FIXED_NOREPLACE) + || (arg4 & VKI_MAP_FIXED_NOREPLACE) +#endif + ) + { mreq.rkind = MFixed; } else #if defined(VGO_solaris) && defined(VKI_MAP_ALIGN) @@ -2710,6 +2715,11 @@ ML_(generic_PRE_sys_mmap) ( ThreadId tid, advised = VG_(am_get_advisory)( &mreq, True/*client*/, &mreq_ok ); if (!mreq_ok) { /* Our request was bounced, so we'd better fail. */ +#if defined(VKI_MAP_FIXED_NOREPLACE) + if (arg4 & VKI_MAP_FIXED_NOREPLACE) { + return VG_(mk_SysRes_Error)( VKI_EEXIST ); + } +#endif return VG_(mk_SysRes_Error)( VKI_EINVAL ); } @@ -2744,6 +2754,13 @@ ML_(generic_PRE_sys_mmap) ( ThreadId tid, } # endif +# if defined(VKI_MAP_FIXED_NOREPLACE) + /* FIXED_NOREPLACE is fatal, no retries. */ + if ((arg4 & VKI_MAP_FIXED_NOREPLACE) && sr_isError(sres)) { + return VG_(mk_SysRes_Error)( VKI_EEXIST ); + } +# endif + /* A refinement: it may be that the kernel refused aspacem's choice of address. If we were originally asked for a hinted mapping, there is still a last chance: try again at any address. diff --git a/include/vki/vki-amd64-linux.h b/include/vki/vki-amd64-linux.h index 12cd65ac7c..bbcf4ab4e9 100644 --- a/include/vki/vki-amd64-linux.h +++ b/include/vki/vki-amd64-linux.h @@ -236,6 +236,7 @@ struct vki_sigcontext { #define VKI_MAP_ANONYMOUS 0x20 /* don't use a file */ #define VKI_MAP_32BIT 0x40 /* only give out 32bit addresses */ #define VKI_MAP_NORESERVE 0x4000 /* don't check for reservations */ +#define VKI_MAP_FIXED_NOREPLACE 0x100000 /* fail EEXIST if fixed map fails */ //---------------------------------------------------------------------- // From linux-2.6.9/include/asm-x86_64/fcntl.h diff --git a/include/vki/vki-arm-linux.h b/include/vki/vki-arm-linux.h index 7e0001c0cf..a72268ca43 100644 --- a/include/vki/vki-arm-linux.h +++ b/include/vki/vki-arm-linux.h @@ -233,6 +233,7 @@ struct vki_sigcontext { #define VKI_MAP_FIXED 0x10 /* Interpret addr exactly */ #define VKI_MAP_ANONYMOUS 0x20 /* don't use a file */ #define VKI_MAP_NORESERVE 0x4000 /* don't check for reservations */ +#define VKI_MAP_FIXED_NOREPLACE 0x100000 /* fail EEXIST if fixed map fails */ //---------------------------------------------------------------------- // From linux-2.6.8.1/include/asm-i386/fcntl.h diff --git a/include/vki/vki-arm64-linux.h b/include/vki/vki-arm64-linux.h index 2fc97e614f..1b005c7750 100644 --- a/include/vki/vki-arm64-linux.h +++ b/include/vki/vki-arm64-linux.h @@ -215,6 +215,7 @@ struct vki_sigcontext { #define VKI_MAP_FIXED 0x10 /* Interpret addr exactly */ #define VKI_MAP_ANONYMOUS 0x20 /* don't use a file */ #define VKI_MAP_NORESERVE 0x4000 /* don't check for reservations */ +#define VKI_MAP_FIXED_NOREPLACE 0x100000 /* fail EEXIST if fixed map fails */ //---------------------------------------------------------------------- // From linux-3.10.5/uapi/include/asm-generic/fcntl.h diff --git a/include/vki/vki-mips32-linux.h b/include/vki/vki-mips32-linux.h index 2d752e2ccb..584b5dd727 100644 --- a/include/vki/vki-mips32-linux.h +++ b/include/vki/vki-mips32-linux.h @@ -300,6 +300,7 @@ struct vki_sigcontext { #define VKI_MAP_LOCKED 0x8000 /* pages are locked */ #define VKI_MAP_POPULATE 0x10000 /* populate (prefault) pagetables */ #define VKI_MAP_NONBLOCK 0x20000 /* do not block on IO */ +#define VKI_MAP_FIXED_NOREPLACE 0x100000 /* fail EEXIST if fixed map fails */ //---------------------------------------------------------------------- diff --git a/include/vki/vki-mips64-linux.h b/include/vki/vki-mips64-linux.h index 527b0dae63..9171b6fb0e 100644 --- a/include/vki/vki-mips64-linux.h +++ b/include/vki/vki-mips64-linux.h @@ -306,6 +306,7 @@ struct vki_sigcontext { #define VKI_MAP_LOCKED 0x8000 /* pages are locked */ #define VKI_MAP_POPULATE 0x10000 /* populate (prefault) pagetables */ #define VKI_MAP_NONBLOCK 0x20000 /* do not block on IO */ +#define VKI_MAP_FIXED_NOREPLACE 0x100000 /* fail EEXIST if fixed map fails */ //---------------------------------------------------------------------- // From linux-2.6.35.9/include/asm-mips/fcntl.h diff --git a/include/vki/vki-riscv64-linux.h b/include/vki/vki-riscv64-linux.h index 5cc98b6ab1..0ad826c02f 100644 --- a/include/vki/vki-riscv64-linux.h +++ b/include/vki/vki-riscv64-linux.h @@ -186,6 +186,7 @@ typedef struct vki_sigaltstack { //---------------------------------------------------------------------- #define VKI_MAP_NORESERVE 0x4000 /* don't check for reservations */ +#define VKI_MAP_FIXED_NOREPLACE 0x100000 /* fail EEXIST if fixed map fails */ //---------------------------------------------------------------------- // From linux-6.0/include/uapi/linux/mman.h diff --git a/include/vki/vki-x86-linux.h b/include/vki/vki-x86-linux.h index 5a5f9e5d82..d00de22b41 100644 --- a/include/vki/vki-x86-linux.h +++ b/include/vki/vki-x86-linux.h @@ -271,6 +271,7 @@ struct vki_sigcontext { #define VKI_MAP_FIXED 0x10 /* Interpret addr exactly */ #define VKI_MAP_ANONYMOUS 0x20 /* don't use a file */ #define VKI_MAP_NORESERVE 0x4000 /* don't check for reservations */ +#define VKI_MAP_FIXED_NOREPLACE 0x100000 /* fail EEXIST if fixed map fails */ //---------------------------------------------------------------------- // From linux-2.6.8.1/include/asm-i386/fcntl.h |
From: Mark W. <ma...@so...> - 2025-07-14 22:26:26
|
https://sourceware.org/cgit/valgrind/commit/?id=969bccaaca7aab2614def013ac1f37de37fbce86 commit 969bccaaca7aab2614def013ac1f37de37fbce86 Author: Mark Wielaard <ma...@kl...> Date: Tue Jul 15 00:00:44 2025 +0200 Handle SIGSYS and SIGSTKFLT when defined Both signals were already partially handled. But calculate_SKSS_from_SCSS only handled SIGSYS on freebsd. default_action didn't handle SIGSTKFLT. And sync_signalhandler didn't expect to have to handle SIGSYS. This fixes LTP tests kill11 and waitpid01. https://bugs.kde.org/show_bug.cgi?id=506890 Diff: --- coregrind/m_signals.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/coregrind/m_signals.c b/coregrind/m_signals.c index cccbb56832..523f4d7fcb 100644 --- a/coregrind/m_signals.c +++ b/coregrind/m_signals.c @@ -855,7 +855,7 @@ void calculate_SKSS_from_SCSS ( SKSS* dst ) case VKI_SIGFPE: case VKI_SIGILL: case VKI_SIGTRAP: -#if defined(VGO_freebsd) +#if defined(VKI_SIGSYS) case VKI_SIGSYS: #endif /* For these, we always want to catch them and report, even @@ -1832,6 +1832,9 @@ static void default_action(const vki_siginfo_t *info, ThreadId tid) case VKI_SIGPIPE: /* term */ case VKI_SIGALRM: /* term */ case VKI_SIGTERM: /* term */ +# if defined(VKI_SIGSTKFLT) + case VKI_SIGSTKFLT: /* term */ +# endif case VKI_SIGUSR1: /* term */ case VKI_SIGUSR2: /* term */ case VKI_SIGIO: /* term */ @@ -3004,6 +3007,9 @@ void sync_signalhandler ( Int sigNo, || sigNo == VKI_SIGBUS || sigNo == VKI_SIGFPE || sigNo == VKI_SIGILL +#if defined(VKI_SIGSYS) + || sigNo == VKI_SIGSYS +#endif || sigNo == VKI_SIGTRAP); info->si_code = sanitize_si_code(info->si_code); |
From: Mark W. <ma...@so...> - 2025-07-14 21:37:02
|
https://sourceware.org/cgit/valgrind/commit/?id=806abab0557a53546d9498926f699fd679b9f0f1 commit 806abab0557a53546d9498926f699fd679b9f0f1 Author: Mark Wielaard <ma...@kl...> Date: Mon Jul 14 23:23:23 2025 +0200 Reject any attempt to set the handler for SIGKILL/STOP Even though resetting SIGKILL or SIGSTOP to SIG_DFL would be a noop it isn't allowed. Just always return EINVAL if an attempt is made to set the signal handler for SIGKILL or SIGSTOP. There is an LTP test for this signal01. https://bugs.kde.org/show_bug.cgi?id=506930 Diff: --- NEWS | 1 + coregrind/m_signals.c | 6 ++---- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/NEWS b/NEWS index 73488cbc17..49403da013 100644 --- a/NEWS +++ b/NEWS @@ -54,6 +54,7 @@ are not entered into bugzilla tend to get forgotten about or ignored. 502968 Wrap linux specific syscalls 457 (listmount) and 458 (statmount) 506499 Unhandled syscall 592 (exterrctl - FreeBSD 506795 Better report which clone flags are problematic +506930 valgrind allows SIGKILL being reset to SIG_DFL To see details of a given bug, visit https://bugs.kde.org/show_bug.cgi?id=XXXXXX diff --git a/coregrind/m_signals.c b/coregrind/m_signals.c index f0e6b8e7cf..cccbb56832 100644 --- a/coregrind/m_signals.c +++ b/coregrind/m_signals.c @@ -1317,10 +1317,8 @@ SysRes VG_(do_sys_sigaction) ( Int signo, || new_act->ksa_handler == VKI_SIG_IGN) ) goto bad_signo_reserved; - /* Reject attempts to set a handler (or set ignore) for SIGKILL. */ - if ( (signo == VKI_SIGKILL || signo == VKI_SIGSTOP) - && new_act - && new_act->ksa_handler != VKI_SIG_DFL) + /* Reject any attempt to set the handler for SIGKILL/STOP. */ + if ( (signo == VKI_SIGKILL || signo == VKI_SIGSTOP) && new_act ) goto bad_sigkill_or_sigstop; /* If the client supplied non-NULL old_act, copy the relevant SCSS |