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
(18) |
Sep
|
Oct
|
Nov
|
Dec
|
From: Florian K. <fk...@so...> - 2025-06-30 19:32:26
|
https://sourceware.org/cgit/valgrind/commit/?id=c56fbcb7c6e8c821be67c7e8d317116f5deff274 commit c56fbcb7c6e8c821be67c7e8d317116f5deff274 Author: Florian Krohm <fl...@ei...> Date: Mon Jun 30 19:31:33 2025 +0000 s390x: Fix diagnostic for S390_DECODE_UNKNOWN_SPECIAL_INSN When decoding fails the insn bytes (at most 6) are shown. However, "special insns" are 10 bytes with the last 2 bytes being the interesting ones. Print them all. Diff: --- VEX/priv/guest_s390_toIR.c | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/VEX/priv/guest_s390_toIR.c b/VEX/priv/guest_s390_toIR.c index b3ee122c5a..f40cd15e85 100644 --- a/VEX/priv/guest_s390_toIR.c +++ b/VEX/priv/guest_s390_toIR.c @@ -23881,12 +23881,10 @@ s390_decode_and_irgen(const UChar *bytes, UInt insn_length, DisResult *dres) vpanic("s390_decode_and_irgen"); } - vex_printf("%02x%02x", bytes[0], bytes[1]); - if (insn_length > 2) { - vex_printf(" %02x%02x", bytes[2], bytes[3]); - } - if (insn_length > 4) { - vex_printf(" %02x%02x", bytes[4], bytes[5]); + for (unsigned i = 0; i < insn_length; i += 2) { + if (i != 0) + vex_printf(" "); + vex_printf("%02x%02x", bytes[i], bytes[i + 1]); } vex_printf("\n"); } |
From: John R. <jr...@bi...> - 2025-06-30 18:30:01
|
> https://sourceware.org/cgit/valgrind/commit/?id=56d870ba62c775ac5a97f95fc6efb49610cdf96e > commit 56d870ba62c775ac5a97f95fc6efb49610cdf96e > s390x: Add script s390-runone to help debugging small code snippet Four lines suffice: ===== iefbr14.S ## old timers will remember the name from 60 years ago // build+run: gcc -nostartfiles -nostdlib iefbr14.S; valgrind ./a.out _start: .globl _start << insert code snippet here >> br %r14 ===== |
From: Florian K. <fk...@so...> - 2025-06-30 08:28:39
|
https://sourceware.org/cgit/valgrind/commit/?id=56d870ba62c775ac5a97f95fc6efb49610cdf96e commit 56d870ba62c775ac5a97f95fc6efb49610cdf96e Author: Florian Krohm <fl...@ei...> Date: Mon Jun 30 08:27:18 2025 +0000 s390x: Add script s390-runone to help debugging small code snippets Diff: --- auxprogs/s390-runone | 85 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 85 insertions(+) diff --git a/auxprogs/s390-runone b/auxprogs/s390-runone new file mode 100755 index 0000000000..2079a5e460 --- /dev/null +++ b/auxprogs/s390-runone @@ -0,0 +1,85 @@ +#!/bin/sh +# +#----------------------------------------------------------------------- +# Compile a small C program containing a sequence of assembler +# instructions into an executable that does not need a dynamic linker. +# Very handy for debugging new insns or small snippets without going +# through the multi-pass process of figuring out which SB contains the +# code we're interested in. +# +# Here is a template: +# +# int main(void) +# { +# //FIXME: insert test code here: +# asm volatile ("lghi %r1,1"); // __NR_exit +# asm volatile ("lghi %r2,0"); // return code = 0 +# asm volatile ("svc 0"); +# return 0; // shuts up GCC +# } +# +# When running the executable created by this script under valgrind +# there will be only a single super block! Which is exactly what we want +# for debugging. +# +# objdump -d: +# +# 00000000010000b0 <_start>: +# 10000b0: b3 c1 00 0b ldgr %f0,%r11 +# 10000b4: b9 04 00 bf lgr %r11,%r15 +# 10000b8: a7 19 00 01 lghi %r1,1 <--- +# 10000bc: a7 29 00 09 lghi %r2,9 <--- +# 10000c0: 0a 00 svc 0 <--- +# 10000c2: a7 18 00 00 lhi %r1,0 +# 10000c6: b9 14 00 11 lgfr %r1,%r1 +# 10000ca: b9 04 00 21 lgr %r2,%r1 +# 10000ce: b3 cd 00 b0 lgdr %r11,%f0 +# 10000d2: 07 fe br %r14 +# 10000d4: 07 07 nopr %r7 +# 10000d6: 07 07 nopr %r7 +# +# There are only 2 extra insns ahead of our asm code sequence. +# Everything after the svc insn is not reachable. +#----------------------------------------------------------------------- +# + +if [ "x$1" = "x" ]; then + echo "Usage: s390-runone C-file" 1>&2 + echo " or: s390-runone -t" 1>&2 + exit 1 +fi + +if [ "x$1" = "x-t" ]; then + echo 'int main(void)' + echo '{' + echo ' //FIXME: insert test code here:' + echo ' asm volatile ("lghi %r1,1"); // __NR_exit' + echo ' asm volatile ("lghi %r2,0"); // return code = 0' + echo ' asm volatile ("svc 0");' + echo ' return 0; // shuts up GCC' + echo '}' + exit 0 +fi + +file="$1" +base=`basename "$file" .c` +asm="$base.s" +exe="$base" + +if [ "$base" = "$file" ]; then + echo "$file is not a C file" 1>&2 + exit 1 +fi + +# Compile the testprogram to assembler +gcc -S -fno-ident -march=arch14 $file +mv "$asm" "$asm.orig" # save the result + +# Rename main with _start, remove cfi stuff and comment lines +sed 's/main/_start/g' "$asm.orig" | grep -v \.cfi_ | grep -v ^# > "$asm" + +# Link to executable +gcc -static -Wl,--build-id=none -nodefaultlibs -nostartfiles "$asm" -o "$exe" + +echo "$exe created" +exit 0 |
From: Mark W. <ma...@kl...> - 2025-06-28 16:40:41
|
Hi Matthias, On Sat, Jun 28, 2025 at 04:22:21PM +0200, Matthias Schwarzott wrote: > I have one observation to that change. see below. > [...] > diff --git a/coregrind/m_syswrap/syswrap-mips32-linux.c > b/coregrind/m_syswrap/syswrap-mips32-linux.c > >index 5edae82c31..734f129c87 100644 > >--- a/coregrind/m_syswrap/syswrap-mips32-linux.c > >+++ b/coregrind/m_syswrap/syswrap-mips32-linux.c > >@@ -1182,6 +1182,8 @@ static SyscallTableEntry syscall_main_table[] = { > > LINXY(__NR_cachestat, sys_cachestat), // 451 > > LINX_(__NR_fchmodat2, sys_fchmodat2), // 452 > >+ LINX_(__NR_statmount, sys_statmount), // 457 > >+ LINX_(__NR_listmount, sys_listmount), // 458 > > LINX_(__NR_mseal, sys_mseal), // 462 > > }; > This hunk adds LINX_-entries for mips32. > In contrast all other archs use the macro LINXY. Oops. Sharp eyes. And we don't have any mips32 nightly testers or builders. So nobody else noticed. Fixed in commit 6adb4391cb20 "mips32: Use LINXY for statmount and listmount" Thanks, Mark |
From: Mark W. <ma...@so...> - 2025-06-28 16:37:53
|
https://sourceware.org/cgit/valgrind/commit/?id=6adb4391cb202805cbf60edd5769a207af6fe300 commit 6adb4391cb202805cbf60edd5769a207af6fe300 Author: Mark Wielaard <ma...@kl...> Date: Sat Jun 28 18:33:29 2025 +0200 mips32: Use LINXY for statmount and listmount commit 57152acfc6a8 "Wrap linux specific syscalls 457 (listmount) and 458 (statmount)" added LINXY wrappers for all arches, except for mips32 where it used LINX_. This was a typo/mistake. Make sure mips32 also uses LINXY wrappers. Suggested-by: Matthias Schwarzott <zz...@ge...> Diff: --- coregrind/m_syswrap/syswrap-mips32-linux.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/coregrind/m_syswrap/syswrap-mips32-linux.c b/coregrind/m_syswrap/syswrap-mips32-linux.c index 734f129c87..4e5e91e15b 100644 --- a/coregrind/m_syswrap/syswrap-mips32-linux.c +++ b/coregrind/m_syswrap/syswrap-mips32-linux.c @@ -1182,8 +1182,8 @@ static SyscallTableEntry syscall_main_table[] = { LINXY(__NR_cachestat, sys_cachestat), // 451 LINX_(__NR_fchmodat2, sys_fchmodat2), // 452 - LINX_(__NR_statmount, sys_statmount), // 457 - LINX_(__NR_listmount, sys_listmount), // 458 + LINXY(__NR_statmount, sys_statmount), // 457 + LINXY(__NR_listmount, sys_listmount), // 458 LINX_(__NR_mseal, sys_mseal), // 462 }; |
From: Mark W. <ma...@so...> - 2025-06-28 16:30:25
|
https://sourceware.org/cgit/valgrind/commit/?id=763dd003ad5d8a02180ec542b7366700c161299f commit 763dd003ad5d8a02180ec542b7366700c161299f Author: Mark Wielaard <ma...@kl...> Date: Sat Jun 28 18:29:45 2025 +0200 Update commit-url to use cgit instead of gitweb Diff: --- project.config | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/project.config b/project.config index 2983a2e719..1a3b003edb 100644 --- a/project.config +++ b/project.config @@ -26,7 +26,7 @@ # - on Valgrind release branches: There is a high risk that a merge # commit is a merge from master into the branch, which would # bring a lot more than what the user probably meant to push. - # Request that the user cherry-pick his changes. + # Request that the user cherry-pick their changes. reject-merge-commits = refs/heads/master,refs/heads/VALGRIND_.* # The style checker, applied to the contents of each file being @@ -35,7 +35,7 @@ # The URL where we can inspect the commit, inserted in the commit # notification email, and also copy sent to the file-commit-cmd. - commit-url = "https://sourceware.org/git/gitweb.cgi?p=valgrind.git;h=%(rev)s" + commit-url = "https://sourceware.org/cgit/valgrind/commit/?id=%(rev)s" # Do not send emails for the following branches (unofficial # private branches). |
From: Matthias S. <zz...@ge...> - 2025-06-28 14:22:12
|
I have one observation to that change. see below. Am 27.06.25 um 23:20 schrieb Mark Wielaard: > https://sourceware.org/git/gitweb.cgi?p=valgrind.git;h=57152acfc6a82baa58f0d2fa0409290278bafde7 > > commit 57152acfc6a82baa58f0d2fa0409290278bafde7 > Author: Martin Cermak <mc...@re...> > Date: Fri Jun 27 22:36:03 2025 +0200 > > Wrap linux specific syscalls 457 (listmount) and 458 (statmount) > > The listmount syscall returns a list of mount IDs under the req.mnt_id. > This is meant to be used in conjunction with statmount(2) in order to > provide a way to iterate and discover mounted file systems. > > The statmount syscall returns information about a mount, storing it in > the buffer pointed to by smbuf. The returned buffer is a struct > statmount which is of size bufsize. > > Declare a sys_{lis,sta}tmount 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 > > Both syscalls need CAP_SYS_ADMIN, to successfully test. > > Resolves: https://bugs.kde.org/show_bug.cgi?id=502968 > > Diff: > --- > NEWS | 1 + > coregrind/m_syswrap/priv_syswrap-linux.h | 4 +++ > coregrind/m_syswrap/syswrap-amd64-linux.c | 2 ++ > coregrind/m_syswrap/syswrap-arm-linux.c | 2 ++ > coregrind/m_syswrap/syswrap-arm64-linux.c | 2 ++ > coregrind/m_syswrap/syswrap-linux.c | 53 ++++++++++++++++++++++++++++ > coregrind/m_syswrap/syswrap-mips32-linux.c | 2 ++ > coregrind/m_syswrap/syswrap-mips64-linux.c | 2 ++ > coregrind/m_syswrap/syswrap-nanomips-linux.c | 2 ++ > coregrind/m_syswrap/syswrap-ppc32-linux.c | 2 ++ > coregrind/m_syswrap/syswrap-ppc64-linux.c | 2 ++ > coregrind/m_syswrap/syswrap-riscv64-linux.c | 2 ++ > coregrind/m_syswrap/syswrap-s390x-linux.c | 2 ++ > coregrind/m_syswrap/syswrap-x86-linux.c | 2 ++ > include/vki/vki-linux.h | 37 +++++++++++++++++++ > include/vki/vki-scnums-shared-linux.h | 2 ++ > 16 files changed, 119 insertions(+) > > diff --git a/NEWS b/NEWS > index 0d9cc798ec..c1940b56ce 100644 > --- a/NEWS > +++ b/NEWS > @@ -44,6 +44,7 @@ are not entered into bugzilla tend to get forgotten about or ignored. > 504936 Add FreeBSD amd64 sysarch subcommands AMD64_SET_TLSBASE and > AMD64_GET_TLSBASE > 505228 Wrap linux specific mseal syscall > +502968 Wrap linux specific syscalls 457 (listmount) and 458 (statmount) > > To see details of a given bug, visit > https://bugs.kde.org/show_bug.cgi?id=XXXXXX > diff --git a/coregrind/m_syswrap/priv_syswrap-linux.h b/coregrind/m_syswrap/priv_syswrap-linux.h > index ed8cb4ed50..9e6cb89811 100644 > --- a/coregrind/m_syswrap/priv_syswrap-linux.h > +++ b/coregrind/m_syswrap/priv_syswrap-linux.h > @@ -355,6 +355,10 @@ DECL_TEMPLATE(linux, sys_pidfd_getfd); > // Since Linux 6.6 > DECL_TEMPLATE(linux, sys_fchmodat2); > > +// Since Linux 6.8 > +DECL_TEMPLATE(linux, sys_listmount); > +DECL_TEMPLATE(linux, sys_statmount); > + > // Since Linux 6.10 > DECL_TEMPLATE(linux, sys_mseal); > > diff --git a/coregrind/m_syswrap/syswrap-amd64-linux.c b/coregrind/m_syswrap/syswrap-amd64-linux.c > index 292e969fc1..22989f9fa5 100644 > --- a/coregrind/m_syswrap/syswrap-amd64-linux.c > +++ b/coregrind/m_syswrap/syswrap-amd64-linux.c > @@ -904,6 +904,8 @@ static SyscallTableEntry syscall_table[] = { > > LINXY(__NR_cachestat, sys_cachestat), // 451 > LINX_(__NR_fchmodat2, sys_fchmodat2), // 452 > + LINXY(__NR_statmount, sys_statmount), // 457 > + LINXY(__NR_listmount, sys_listmount), // 458 > LINX_(__NR_mseal, sys_mseal), // 462 > }; > > diff --git a/coregrind/m_syswrap/syswrap-arm-linux.c b/coregrind/m_syswrap/syswrap-arm-linux.c > index 6d7db0425b..7bd69b6817 100644 > --- a/coregrind/m_syswrap/syswrap-arm-linux.c > +++ b/coregrind/m_syswrap/syswrap-arm-linux.c > @@ -1075,6 +1075,8 @@ static SyscallTableEntry syscall_main_table[] = { > > LINXY(__NR_cachestat, sys_cachestat), // 451 > LINX_(__NR_fchmodat2, sys_fchmodat2), // 452 > + LINXY(__NR_statmount, sys_statmount), // 457 > + LINXY(__NR_listmount, sys_listmount), // 458 > LINX_(__NR_mseal, sys_mseal), // 462 > }; > > diff --git a/coregrind/m_syswrap/syswrap-arm64-linux.c b/coregrind/m_syswrap/syswrap-arm64-linux.c > index 2d6b45f916..40eb654324 100644 > --- a/coregrind/m_syswrap/syswrap-arm64-linux.c > +++ b/coregrind/m_syswrap/syswrap-arm64-linux.c > @@ -855,6 +855,8 @@ static SyscallTableEntry syscall_main_table[] = { > > LINXY(__NR_cachestat, sys_cachestat), // 451 > LINX_(__NR_fchmodat2, sys_fchmodat2), // 452 > + LINXY(__NR_statmount, sys_statmount), // 457 > + LINXY(__NR_listmount, sys_listmount), // 458 > LINX_(__NR_mseal, sys_mseal), // 462 > }; > [...]> diff --git a/coregrind/m_syswrap/syswrap-mips32-linux.c b/coregrind/m_syswrap/syswrap-mips32-linux.c > index 5edae82c31..734f129c87 100644 > --- a/coregrind/m_syswrap/syswrap-mips32-linux.c > +++ b/coregrind/m_syswrap/syswrap-mips32-linux.c > @@ -1182,6 +1182,8 @@ static SyscallTableEntry syscall_main_table[] = { > > LINXY(__NR_cachestat, sys_cachestat), // 451 > LINX_(__NR_fchmodat2, sys_fchmodat2), // 452 > + LINX_(__NR_statmount, sys_statmount), // 457 > + LINX_(__NR_listmount, sys_listmount), // 458 > LINX_(__NR_mseal, sys_mseal), // 462 > }; > This hunk adds LINX_-entries for mips32. In contrast all other archs use the macro LINXY. Regards Matthias |
From: Paul F. <pa...@so...> - 2025-06-28 07:01:20
|
https://sourceware.org/git/gitweb.cgi?p=valgrind.git;h=5f832cccbdd28b173deae1056048ed12a67bbfd1 commit 5f832cccbdd28b173deae1056048ed12a67bbfd1 Author: Paul Floyd <pj...@wa...> Date: Sat Jun 28 09:00:13 2025 +0200 Non-Linux regtest: update none cmdline2 stdout expected Diff: --- none/tests/cmdline2.stdout.exp-non-linux | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/none/tests/cmdline2.stdout.exp-non-linux b/none/tests/cmdline2.stdout.exp-non-linux index 767f1cb9c0..56a92dbf1f 100644 --- a/none/tests/cmdline2.stdout.exp-non-linux +++ b/none/tests/cmdline2.stdout.exp-non-linux @@ -29,7 +29,11 @@ usage: valgrind [options] prog-and-args where event is one of: startup exit abexit valgrindabexit all none --track-fds=no|yes|all|bad track open file descriptors? [no] - all includes reporting inherited file descriptors + all also reports on open inherited file + descriptors at exit (e.g. stdin/out/err) + bad only reports on file descriptor usage + errors and doesn't list open file descriptors + at exit --modify-fds=no|yes|high modify newly open file descriptors? [no] --time-stamp=no|yes add timestamps to log messages? [no] --log-fd=<number> log messages to file descriptor [2=stderr] |
From: Mark W. <ma...@so...> - 2025-06-27 21:21:01
|
https://sourceware.org/git/gitweb.cgi?p=valgrind.git;h=57152acfc6a82baa58f0d2fa0409290278bafde7 commit 57152acfc6a82baa58f0d2fa0409290278bafde7 Author: Martin Cermak <mc...@re...> Date: Fri Jun 27 22:36:03 2025 +0200 Wrap linux specific syscalls 457 (listmount) and 458 (statmount) The listmount syscall returns a list of mount IDs under the req.mnt_id. This is meant to be used in conjunction with statmount(2) in order to provide a way to iterate and discover mounted file systems. The statmount syscall returns information about a mount, storing it in the buffer pointed to by smbuf. The returned buffer is a struct statmount which is of size bufsize. Declare a sys_{lis,sta}tmount 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 Both syscalls need CAP_SYS_ADMIN, to successfully test. Resolves: https://bugs.kde.org/show_bug.cgi?id=502968 Diff: --- NEWS | 1 + coregrind/m_syswrap/priv_syswrap-linux.h | 4 +++ coregrind/m_syswrap/syswrap-amd64-linux.c | 2 ++ coregrind/m_syswrap/syswrap-arm-linux.c | 2 ++ coregrind/m_syswrap/syswrap-arm64-linux.c | 2 ++ coregrind/m_syswrap/syswrap-linux.c | 53 ++++++++++++++++++++++++++++ coregrind/m_syswrap/syswrap-mips32-linux.c | 2 ++ coregrind/m_syswrap/syswrap-mips64-linux.c | 2 ++ coregrind/m_syswrap/syswrap-nanomips-linux.c | 2 ++ coregrind/m_syswrap/syswrap-ppc32-linux.c | 2 ++ coregrind/m_syswrap/syswrap-ppc64-linux.c | 2 ++ coregrind/m_syswrap/syswrap-riscv64-linux.c | 2 ++ coregrind/m_syswrap/syswrap-s390x-linux.c | 2 ++ coregrind/m_syswrap/syswrap-x86-linux.c | 2 ++ include/vki/vki-linux.h | 37 +++++++++++++++++++ include/vki/vki-scnums-shared-linux.h | 2 ++ 16 files changed, 119 insertions(+) diff --git a/NEWS b/NEWS index 0d9cc798ec..c1940b56ce 100644 --- a/NEWS +++ b/NEWS @@ -44,6 +44,7 @@ are not entered into bugzilla tend to get forgotten about or ignored. 504936 Add FreeBSD amd64 sysarch subcommands AMD64_SET_TLSBASE and AMD64_GET_TLSBASE 505228 Wrap linux specific mseal syscall +502968 Wrap linux specific syscalls 457 (listmount) and 458 (statmount) To see details of a given bug, visit https://bugs.kde.org/show_bug.cgi?id=XXXXXX diff --git a/coregrind/m_syswrap/priv_syswrap-linux.h b/coregrind/m_syswrap/priv_syswrap-linux.h index ed8cb4ed50..9e6cb89811 100644 --- a/coregrind/m_syswrap/priv_syswrap-linux.h +++ b/coregrind/m_syswrap/priv_syswrap-linux.h @@ -355,6 +355,10 @@ DECL_TEMPLATE(linux, sys_pidfd_getfd); // Since Linux 6.6 DECL_TEMPLATE(linux, sys_fchmodat2); +// Since Linux 6.8 +DECL_TEMPLATE(linux, sys_listmount); +DECL_TEMPLATE(linux, sys_statmount); + // Since Linux 6.10 DECL_TEMPLATE(linux, sys_mseal); diff --git a/coregrind/m_syswrap/syswrap-amd64-linux.c b/coregrind/m_syswrap/syswrap-amd64-linux.c index 292e969fc1..22989f9fa5 100644 --- a/coregrind/m_syswrap/syswrap-amd64-linux.c +++ b/coregrind/m_syswrap/syswrap-amd64-linux.c @@ -904,6 +904,8 @@ static SyscallTableEntry syscall_table[] = { LINXY(__NR_cachestat, sys_cachestat), // 451 LINX_(__NR_fchmodat2, sys_fchmodat2), // 452 + LINXY(__NR_statmount, sys_statmount), // 457 + LINXY(__NR_listmount, sys_listmount), // 458 LINX_(__NR_mseal, sys_mseal), // 462 }; diff --git a/coregrind/m_syswrap/syswrap-arm-linux.c b/coregrind/m_syswrap/syswrap-arm-linux.c index 6d7db0425b..7bd69b6817 100644 --- a/coregrind/m_syswrap/syswrap-arm-linux.c +++ b/coregrind/m_syswrap/syswrap-arm-linux.c @@ -1075,6 +1075,8 @@ static SyscallTableEntry syscall_main_table[] = { LINXY(__NR_cachestat, sys_cachestat), // 451 LINX_(__NR_fchmodat2, sys_fchmodat2), // 452 + LINXY(__NR_statmount, sys_statmount), // 457 + LINXY(__NR_listmount, sys_listmount), // 458 LINX_(__NR_mseal, sys_mseal), // 462 }; diff --git a/coregrind/m_syswrap/syswrap-arm64-linux.c b/coregrind/m_syswrap/syswrap-arm64-linux.c index 2d6b45f916..40eb654324 100644 --- a/coregrind/m_syswrap/syswrap-arm64-linux.c +++ b/coregrind/m_syswrap/syswrap-arm64-linux.c @@ -855,6 +855,8 @@ static SyscallTableEntry syscall_main_table[] = { LINXY(__NR_cachestat, sys_cachestat), // 451 LINX_(__NR_fchmodat2, sys_fchmodat2), // 452 + LINXY(__NR_statmount, sys_statmount), // 457 + LINXY(__NR_listmount, sys_listmount), // 458 LINX_(__NR_mseal, sys_mseal), // 462 }; diff --git a/coregrind/m_syswrap/syswrap-linux.c b/coregrind/m_syswrap/syswrap-linux.c index 0db8717786..97d3862902 100644 --- a/coregrind/m_syswrap/syswrap-linux.c +++ b/coregrind/m_syswrap/syswrap-linux.c @@ -4305,6 +4305,59 @@ PRE(sys_mseal) SET_STATUS_Failure(VKI_ENOMEM); } +PRE(sys_statmount) +{ + // int syscall(SYS_statmount, struct mnt_id_req *req, + // struct statmount *smbuf, size_t bufsize, + // unsigned long flags); + FUSE_COMPATIBLE_MAY_BLOCK(); + PRINT("sys_statmount ( %#" FMT_REGWORD "x, %#" FMT_REGWORD "x, %lu, %#" FMT_REGWORD "x)", ARG1, ARG2, ARG3, ARG4); + PRE_REG_READ4(long, "statmount", struct vki_mnt_id_req *, req, struct vki_statmount *, smbuf, vki_size_t, bufsize, unsigned long, flags); + + struct vki_mnt_id_req *req = (struct vki_mnt_id_req *)(Addr)ARG1; + if (!ML_(safe_to_deref) ((void *)&req->size, sizeof(vki_size_t))) + PRE_MEM_READ("statmount(req)", ARG1, sizeof(struct vki_mnt_id_req)); + else + PRE_MEM_READ("statmount(req)", ARG1, req->size); + + struct vki_statmount *smbuf = (struct vki_statmount *)(Addr)ARG2; + if (!ML_(safe_to_deref) ((void *)&smbuf->size, sizeof(struct vki_statmount))) + PRE_MEM_WRITE("statmount(smbuf)", ARG2, sizeof(struct vki_statmount)); + else + PRE_MEM_WRITE("statmount(smbuf)", ARG2, ARG3); +} + +POST(sys_statmount) +{ + struct vki_statmount *smbuf = (struct vki_statmount *)(Addr)ARG2; + POST_MEM_WRITE((Addr)smbuf, smbuf->size); +} + +PRE(sys_listmount) +{ + // int syscall(SYS_listmount, struct mnt_id_req *req, + // uint64_t *mnt_ids, size_t nr_mnt_ids, + // unsigned long flags); + FUSE_COMPATIBLE_MAY_BLOCK(); + PRINT("sys_listmount ( %#" FMT_REGWORD "x, %#" FMT_REGWORD "x, %lu, %#" FMT_REGWORD "x)", ARG1, ARG2, ARG3, ARG4); + PRE_REG_READ4(long, "listmount", struct vki_mnt_id_req *, req, vki_uint64_t *, mnt_ids, vki_size_t, nr_mnt_ids, unsigned long, flags); + + struct vki_mnt_id_req *req = (struct vki_mnt_id_req *)(Addr)ARG1; + if (!ML_(safe_to_deref) ((void *)&req->size, sizeof(vki_size_t))) + PRE_MEM_READ("listmount(req)", ARG1, sizeof(struct vki_mnt_id_req)); + else + PRE_MEM_READ("listmount(req)", ARG1, req->size); + + PRE_MEM_WRITE("listmount(mnt_ids)", ARG2, ARG3 * sizeof(vki_uint64_t)); +} + +POST(sys_listmount) +{ + if (RES > 0) { + POST_MEM_WRITE(ARG2, RES * sizeof(vki_uint64_t)); + } +} + PRE(sys_syncfs) { *flags |= SfMayBlock; diff --git a/coregrind/m_syswrap/syswrap-mips32-linux.c b/coregrind/m_syswrap/syswrap-mips32-linux.c index 5edae82c31..734f129c87 100644 --- a/coregrind/m_syswrap/syswrap-mips32-linux.c +++ b/coregrind/m_syswrap/syswrap-mips32-linux.c @@ -1182,6 +1182,8 @@ static SyscallTableEntry syscall_main_table[] = { LINXY(__NR_cachestat, sys_cachestat), // 451 LINX_(__NR_fchmodat2, sys_fchmodat2), // 452 + LINX_(__NR_statmount, sys_statmount), // 457 + LINX_(__NR_listmount, sys_listmount), // 458 LINX_(__NR_mseal, sys_mseal), // 462 }; diff --git a/coregrind/m_syswrap/syswrap-mips64-linux.c b/coregrind/m_syswrap/syswrap-mips64-linux.c index 63e4b111ec..67e5c0b37d 100644 --- a/coregrind/m_syswrap/syswrap-mips64-linux.c +++ b/coregrind/m_syswrap/syswrap-mips64-linux.c @@ -838,6 +838,8 @@ static SyscallTableEntry syscall_main_table[] = { LINXY (__NR_cachestat, sys_cachestat), LINX_ (__NR_fchmodat2, sys_fchmodat2), LINXY (__NR_userfaultfd, sys_userfaultfd), + LINXY (__NR_statmount, sys_statmount), + LINXY (__NR_listmount, sys_listmount), LINX_ (__NR_mseal, sys_mseal), }; diff --git a/coregrind/m_syswrap/syswrap-nanomips-linux.c b/coregrind/m_syswrap/syswrap-nanomips-linux.c index b392ad1ade..a4da2be9ba 100644 --- a/coregrind/m_syswrap/syswrap-nanomips-linux.c +++ b/coregrind/m_syswrap/syswrap-nanomips-linux.c @@ -842,6 +842,8 @@ static SyscallTableEntry syscall_main_table[] = { LINX_ (__NR_landlock_restrict_self, sys_landlock_restrict_self), LINXY (__NR_cachestat, sys_cachestat), LINX_ (__NR_fchmodat2, sys_fchmodat2), + LINXY (__NR_statmount, sys_statmount), + LINXY (__NR_listmount, sys_listmount), LINX_ (__NR_mseal, sys_mseal), }; diff --git a/coregrind/m_syswrap/syswrap-ppc32-linux.c b/coregrind/m_syswrap/syswrap-ppc32-linux.c index 9d02a02580..b5d45e1094 100644 --- a/coregrind/m_syswrap/syswrap-ppc32-linux.c +++ b/coregrind/m_syswrap/syswrap-ppc32-linux.c @@ -1081,6 +1081,8 @@ static SyscallTableEntry syscall_table[] = { LINXY(__NR_cachestat, sys_cachestat), // 451 LINX_ (__NR_fchmodat2, sys_fchmodat2), // 452 + LINXY (__NR_statmount, sys_statmount), // 457 + LINXY (__NR_listmount, sys_listmount), // 458 LINX_ (__NR_mseal, sys_mseal), // 462 }; diff --git a/coregrind/m_syswrap/syswrap-ppc64-linux.c b/coregrind/m_syswrap/syswrap-ppc64-linux.c index 94385a4fa1..764fb557ec 100644 --- a/coregrind/m_syswrap/syswrap-ppc64-linux.c +++ b/coregrind/m_syswrap/syswrap-ppc64-linux.c @@ -1048,6 +1048,8 @@ static SyscallTableEntry syscall_table[] = { LINXY (__NR_cachestat, sys_cachestat), // 451 LINX_ (__NR_fchmodat2, sys_fchmodat2), // 452 + LINXY (__NR_statmount, sys_statmount), // 457 + LINXY (__NR_listmount, sys_listmount), // 458 LINX_ (__NR_mseal, sys_mseal), // 462 }; diff --git a/coregrind/m_syswrap/syswrap-riscv64-linux.c b/coregrind/m_syswrap/syswrap-riscv64-linux.c index 68ccd0ea49..d572672f85 100644 --- a/coregrind/m_syswrap/syswrap-riscv64-linux.c +++ b/coregrind/m_syswrap/syswrap-riscv64-linux.c @@ -599,6 +599,8 @@ static SyscallTableEntry syscall_main_table[] = { LINXY(__NR_memfd_secret, sys_memfd_secret), /* 447 */ LINXY(__NR_cachestat, sys_cachestat), /* 451 */ LINX_(__NR_fchmodat2, sys_fchmodat2), /* 452 */ + LINXY(__NR_statmount, sys_statmount), /* 457 */ + LINXY(__NR_listmount, sys_listmount), /* 458 */ LINX_(__NR_mseal, sys_mseal), /* 462 */ }; diff --git a/coregrind/m_syswrap/syswrap-s390x-linux.c b/coregrind/m_syswrap/syswrap-s390x-linux.c index a6770399dd..8202c1922d 100644 --- a/coregrind/m_syswrap/syswrap-s390x-linux.c +++ b/coregrind/m_syswrap/syswrap-s390x-linux.c @@ -890,6 +890,8 @@ static SyscallTableEntry syscall_table[] = { LINXY (__NR_cachestat, sys_cachestat), // 451 LINX_ (__NR_fchmodat2, sys_fchmodat2), // 452 + LINXY (__NR_statmount, sys_statmount), // 457 + LINXY (__NR_listmount, sys_listmount), // 458 LINX_ (__NR_mseal, sys_mseal), // 462 }; diff --git a/coregrind/m_syswrap/syswrap-x86-linux.c b/coregrind/m_syswrap/syswrap-x86-linux.c index 4b5b5fb15f..45216b45f4 100644 --- a/coregrind/m_syswrap/syswrap-x86-linux.c +++ b/coregrind/m_syswrap/syswrap-x86-linux.c @@ -1676,6 +1676,8 @@ static SyscallTableEntry syscall_table[] = { LINXY(__NR_cachestat, sys_cachestat), // 451 LINX_(__NR_fchmodat2, sys_fchmodat2), // 452 + LINXY(__NR_statmount, sys_statmount), // 457 + LINXY(__NR_listmount, sys_listmount), // 458 LINX_(__NR_mseal, sys_mseal), // 462 }; diff --git a/include/vki/vki-linux.h b/include/vki/vki-linux.h index 0d2bed6dc6..65406fffe9 100644 --- a/include/vki/vki-linux.h +++ b/include/vki/vki-linux.h @@ -5502,6 +5502,43 @@ struct vki__aio_sigset { vki_size_t sigsetsize; }; +//---------------------------------------------------------------------- +// From uapi/linux/mount.h +//---------------------------------------------------------------------- + +struct vki_mnt_id_req { + __vki_u32 size; + __vki_u32 spare; + __vki_u64 mnt_id; + __vki_u64 param; + __vki_u64 mnt_ns_id; +}; + +struct vki_statmount { + __vki_u32 size; /* Total size, including strings */ + __vki_u32 mnt_opts; /* [str] Mount options of the mount */ + __vki_u64 mask; /* What results were written */ + __vki_u32 sb_dev_major; /* Device ID */ + __vki_u32 sb_dev_minor; + __vki_u64 sb_magic; /* ..._SUPER_MAGIC */ + __vki_u32 sb_flags; /* SB_{RDONLY,SYNCHRONOUS,DIRSYNC,LAZYTIME} */ + __vki_u32 fs_type; /* [str] Filesystem type */ + __vki_u64 mnt_id; /* Unique ID of mount */ + __vki_u64 mnt_parent_id; /* Unique ID of parent (for root == mnt_id) */ + __vki_u32 mnt_id_old; /* Reused IDs used in proc/.../mountinfo */ + __vki_u32 mnt_parent_id_old; + __vki_u64 mnt_attr; /* MOUNT_ATTR_... */ + __vki_u64 mnt_propagation; /* MS_{SHARED,SLAVE,PRIVATE,UNBINDABLE} */ + __vki_u64 mnt_peer_group; /* ID of shared peer group */ + __vki_u64 mnt_master; /* Mount receives propagation from this ID */ + __vki_u64 propagate_from; /* Propagation from in current namespace */ + __vki_u32 mnt_root; /* [str] Root of mount relative to root of fs */ + __vki_u32 mnt_point; /* [str] Mountpoint relative to current root */ + __vki_u64 mnt_ns_id; /* ID of the mount namespace */ + __vki_u64 __spare2[49]; + char str[]; /* Variable size part containing strings */ +}; + /*--------------------------------------------------------------------*/ /*--- end ---*/ /*--------------------------------------------------------------------*/ diff --git a/include/vki/vki-scnums-shared-linux.h b/include/vki/vki-scnums-shared-linux.h index 32ef8ac133..9c20964c51 100644 --- a/include/vki/vki-scnums-shared-linux.h +++ b/include/vki/vki-scnums-shared-linux.h @@ -56,6 +56,8 @@ #define __NR_cachestat 451 #define __NR_fchmodat2 452 +#define __NR_statmount 457 +#define __NR_listmount 458 #define __NR_mseal 462 #endif |
From: Alexandra H. <aha...@so...> - 2025-06-27 11:16:55
|
https://sourceware.org/git/gitweb.cgi?p=valgrind.git;h=2942c04c485076d84a2df8ee6bb901bb0f014c51 commit 2942c04c485076d84a2df8ee6bb901bb0f014c51 Author: Alexandra Hájková <aha...@re...> Date: Fri Jun 20 03:21:41 2025 -0400 Add "bad" option for --track-fds. When --track-fds=bad is specified, do not warn about leaked file descriptors and only warn about file decriptors which was not opened or already closed. Update the documentation in docs/xml/manual-core.xml. Add none/tests/track_bad test to test the new option. Adjust none/tests/cmdline1 and none/tests/cmdline2 expected outputs. https://bugs.kde.org/show_bug.cgi?id=493434 Diff: --- .gitignore | 1 + NEWS | 1 + coregrind/m_main.c | 12 ++++++++--- docs/xml/manual-core.xml | 35 ++++++++++++++++++++++---------- none/tests/Makefile.am | 6 ++++-- none/tests/cmdline1.stdout.exp | 8 ++++++-- none/tests/cmdline1.stdout.exp-non-linux | 8 ++++++-- none/tests/cmdline2.stdout.exp | 8 ++++++-- none/tests/cmdline2.stdout.exp-non-linux | 2 +- none/tests/track_bad.c | 34 +++++++++++++++++++++++++++++++ none/tests/track_bad.stderr.exp | 28 +++++++++++++++++++++++++ none/tests/track_bad.vgtest | 3 +++ 12 files changed, 123 insertions(+), 23 deletions(-) diff --git a/.gitignore b/.gitignore index 8cabb96df4..32cedb0d7c 100644 --- a/.gitignore +++ b/.gitignore @@ -1676,6 +1676,7 @@ /none/tests/track-fds-exec-children /none/tests/track_new /none/tests/track_std +/none/tests/track_bad /none/tests/unit_debuglog /none/tests/use_after_close /none/tests/valgrind_cpp_test diff --git a/NEWS b/NEWS index 0e01182651..0d9cc798ec 100644 --- a/NEWS +++ b/NEWS @@ -24,6 +24,7 @@ than mailing the developers (or mailing lists) directly -- bugs that are not entered into bugzilla tend to get forgotten about or ignored. 338803 Handling of dwz debug alt files or cross-CU is broken +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 503677 duplicated-cond compiler warning in dis_RV64M diff --git a/coregrind/m_main.c b/coregrind/m_main.c index 128e4298c1..f7fd20dbae 100644 --- a/coregrind/m_main.c +++ b/coregrind/m_main.c @@ -113,8 +113,12 @@ static void usage_NORETURN ( int need_help ) " --vgdb-stop-at=event1,event2,... invoke gdbserver for given events [none]\n" " where event is one of:\n" " startup exit abexit valgrindabexit all none\n" -" --track-fds=no|yes|all track open file descriptors? [no]\n" -" all includes reporting inherited file descriptors\n" +" --track-fds=no|yes|all|bad track open file descriptors? [no]\n" +" all also reports on open inherited file\n" +" descriptors at exit (e.g. stdin/out/err)\n" +" bad only reports on file descriptor usage\n" +" errors and doesn't list open file descriptors\n" +" at exit\n" " --modify-fds=no|yes|high modify newly open file descriptors? [no]\n" " --time-stamp=no|yes add timestamps to log messages? [no]\n" " --log-fd=<number> log messages to file descriptor [2=stderr]\n" @@ -643,6 +647,8 @@ static void process_option (Clo_Mode mode, VG_(clo_track_fds) = 2; else if (VG_(strcmp)(tmp_str, "no") == 0) VG_(clo_track_fds) = 0; + else if (VG_(strcmp)(tmp_str, "bad") == 0) + VG_(clo_track_fds) = 3; else VG_(fmsg_bad_option)(arg, "Bad argument, should be 'yes', 'all' or 'no'\n"); @@ -2324,7 +2330,7 @@ void shutdown_actions_NORETURN( ThreadId tid, } /* Print out file descriptor summary and stats. */ - if (VG_(clo_track_fds)) + if (VG_(clo_track_fds) && VG_(clo_track_fds) < 3) VG_(show_open_fds)("at exit"); /* Call the tool's finalisation function. This makes Memcheck's diff --git a/docs/xml/manual-core.xml b/docs/xml/manual-core.xml index 7d18d46f39..9ab09b51bf 100644 --- a/docs/xml/manual-core.xml +++ b/docs/xml/manual-core.xml @@ -886,18 +886,31 @@ in most cases. We group the available options by rough categories.</para> <varlistentry id="opt.track-fds" xreflabel="--track-fds"> <term> - <option><![CDATA[--track-fds=<yes|no|all> [default: no] ]]></option> - </term> - <listitem> - <para>When enabled, Valgrind will print out a list of open file - descriptors on exit or on request, via the gdbserver monitor - command <varname>v.info open_fds</varname>. Along with each - file descriptor is printed a stack backtrace of where the file - was opened and any details relating to the file descriptor such - as the file name or socket details. Use <option>all</option> to - include reporting on <computeroutput>stdin</computeroutput>, + <option><![CDATA[--track-fds=<yes|no|all|bad> [default: no] ]]></option> + </term> + <listitem> + <para>When enabled, Valgrind will track all file descriptor + usage. It will produce errors for bad file descriptor usage like + closing a file descriptor twice, using a file descriptor + (number) that was never created, or passing an already closed + file descriptor to a system call. It will also print out a list + of open file descriptors on exit. Or on request, via the + gdbserver monitor command <varname>v.info open_fds</varname>.</para> + + <para>When an error is generated, or when listing the still open + file descriptors at exit, a stack backtrace of where the file + was opened is printed. If the file descriptor has already been + closed, it will also include a backtrace of where it was + previously closed. Any error will include details relating to + the file descriptor such as the file name or socket details.</para> + + <para>Use <option>all</option> to also include reporting + on <computeroutput>stdin</computeroutput>, <computeroutput>stdout</computeroutput> and - <computeroutput>stderr</computeroutput>.</para> + <computeroutput>stderr</computeroutput> (or other inherited file + descriptors) at exit. If <option>bad</option> option is used, + then exclude reporting on leaked file descriptors at exit and + only produce errors about bad file decriptors usage.</para> </listitem> </varlistentry> diff --git a/none/tests/Makefile.am b/none/tests/Makefile.am index ca01f9e42d..716ce000d3 100644 --- a/none/tests/Makefile.am +++ b/none/tests/Makefile.am @@ -275,7 +275,8 @@ EXTRA_DIST = \ track_new.stderr.exp track_new.stdout.exp \ track_new.vgtest track_new.stderr.exp-illumos \ track_yes.vgtest track_high.vgtest \ - track_yes.stderr.exp track_high.stderr.exp + track_yes.stderr.exp track_high.stderr.exp \ + track_bad.vgtest track_bad.stderr.exp check_PROGRAMS = \ args \ @@ -334,7 +335,8 @@ check_PROGRAMS = \ fdbaduse \ use_after_close \ track_new \ - track_std + track_std \ + track_bad if HAVE_STATIC_LIBC if ! VGCONF_OS_IS_LINUX diff --git a/none/tests/cmdline1.stdout.exp b/none/tests/cmdline1.stdout.exp index 06a679a111..5d3ea05697 100644 --- a/none/tests/cmdline1.stdout.exp +++ b/none/tests/cmdline1.stdout.exp @@ -28,8 +28,12 @@ usage: valgrind [options] prog-and-args --vgdb-stop-at=event1,event2,... invoke gdbserver for given events [none] where event is one of: startup exit abexit valgrindabexit all none - --track-fds=no|yes|all track open file descriptors? [no] - all includes reporting inherited file descriptors + --track-fds=no|yes|all|bad track open file descriptors? [no] + all also reports on open inherited file + descriptors at exit (e.g. stdin/out/err) + bad only reports on file descriptor usage + errors and doesn't list open file descriptors + at exit --modify-fds=no|yes|high modify newly open file descriptors? [no] --time-stamp=no|yes add timestamps to log messages? [no] --log-fd=<number> log messages to file descriptor [2=stderr] diff --git a/none/tests/cmdline1.stdout.exp-non-linux b/none/tests/cmdline1.stdout.exp-non-linux index 4049d5ab2f..9b044e78a1 100644 --- a/none/tests/cmdline1.stdout.exp-non-linux +++ b/none/tests/cmdline1.stdout.exp-non-linux @@ -28,8 +28,12 @@ usage: valgrind [options] prog-and-args --vgdb-stop-at=event1,event2,... invoke gdbserver for given events [none] where event is one of: startup exit abexit valgrindabexit all none - --track-fds=no|yes|all track open file descriptors? [no] - all includes reporting inherited file descriptors + --track-fds=no|yes|all|bad track open file descriptors? [no] + all also reports on open inherited file + descriptors at exit (e.g. stdin/out/err) + bad only reports on file descriptor usage + errors and doesn't list open file descriptors + at exit --modify-fds=no|yes|high modify newly open file descriptors? [no] --time-stamp=no|yes add timestamps to log messages? [no] --log-fd=<number> log messages to file descriptor [2=stderr] diff --git a/none/tests/cmdline2.stdout.exp b/none/tests/cmdline2.stdout.exp index d7914ae010..618c43acbc 100644 --- a/none/tests/cmdline2.stdout.exp +++ b/none/tests/cmdline2.stdout.exp @@ -28,8 +28,12 @@ usage: valgrind [options] prog-and-args --vgdb-stop-at=event1,event2,... invoke gdbserver for given events [none] where event is one of: startup exit abexit valgrindabexit all none - --track-fds=no|yes|all track open file descriptors? [no] - all includes reporting inherited file descriptors + --track-fds=no|yes|all|bad track open file descriptors? [no] + all also reports on open inherited file + descriptors at exit (e.g. stdin/out/err) + bad only reports on file descriptor usage + errors and doesn't list open file descriptors + at exit --modify-fds=no|yes|high modify newly open file descriptors? [no] --time-stamp=no|yes add timestamps to log messages? [no] --log-fd=<number> log messages to file descriptor [2=stderr] diff --git a/none/tests/cmdline2.stdout.exp-non-linux b/none/tests/cmdline2.stdout.exp-non-linux index d709ea365d..767f1cb9c0 100644 --- a/none/tests/cmdline2.stdout.exp-non-linux +++ b/none/tests/cmdline2.stdout.exp-non-linux @@ -28,7 +28,7 @@ usage: valgrind [options] prog-and-args --vgdb-stop-at=event1,event2,... invoke gdbserver for given events [none] where event is one of: startup exit abexit valgrindabexit all none - --track-fds=no|yes|all track open file descriptors? [no] + --track-fds=no|yes|all|bad track open file descriptors? [no] all includes reporting inherited file descriptors --modify-fds=no|yes|high modify newly open file descriptors? [no] --time-stamp=no|yes add timestamps to log messages? [no] diff --git a/none/tests/track_bad.c b/none/tests/track_bad.c new file mode 100644 index 0000000000..b1674d6484 --- /dev/null +++ b/none/tests/track_bad.c @@ -0,0 +1,34 @@ +#include<stdio.h> +#include <stdlib.h> +#include <unistd.h> +#include <fcntl.h> +#include "fdleak.h" + +int main(void) +{ + char *string = "bad\n"; + int fd = dup(2); + + /* OK. */ + write(fd, string, 4); + close(fd); + + /* Already closed. */ + write(fd, string, 4); + + /* Never created. */ + write(7, string, 4); + + /* Invalid. */ + write(-7, string, 4); + + /* Double double close. */ + close(fd); + + /* Invalid close. */ + close (-7); + + (void) DO( open("/dev/null", O_RDONLY) ); + + return 0; +} diff --git a/none/tests/track_bad.stderr.exp b/none/tests/track_bad.stderr.exp new file mode 100644 index 0000000000..620a6b8d29 --- /dev/null +++ b/none/tests/track_bad.stderr.exp @@ -0,0 +1,28 @@ +bad +File descriptor was closed already + at 0x........: write (in /...libc...) + by 0x........: main + Previously closed + at 0x........: close (in /...libc...) + by 0x........: main + Originally opened + at 0x........: dup (in /...libc...) + by 0x........: main +File descriptor 7 was never created + at 0x........: write (in /...libc...) + by 0x........: main +File descriptor -7 Invalid file descriptor + at 0x........: write (in /...libc...) + by 0x........: main +File descriptor ...: ... is already closed + at 0x........: close (in /...libc...) + by 0x........: main + Previously closed + at 0x........: close (in /...libc...) + by 0x........: main + Originally opened + at 0x........: dup (in /...libc...) + by 0x........: main +File descriptor -7 Invalid file descriptor + at 0x........: close (in /...libc...) + by 0x........: main diff --git a/none/tests/track_bad.vgtest b/none/tests/track_bad.vgtest new file mode 100644 index 0000000000..77daf8f44a --- /dev/null +++ b/none/tests/track_bad.vgtest @@ -0,0 +1,3 @@ +prog: track_bad +vgopts: -q --track-fds=bad +stderr_filter: filter_fdleak |
From: Florian K. <fl...@ei...> - 2025-06-26 12:40:33
|
On 20.06.25 22:31, Florian Krohm wrote: > > There is no bug that I could find and I don't have a list either. But it would > be worthwhile to fill in the gaps. Constant folding is a cheap and easy thing to > do and effective. Algebraic identities are a different story as they need to > recurse the subtrees (sameIRexprs). > > Anyhow, I'll bite and make a pass and see what is missing for operations of > integer type except Ity_I128. I opened https://bugs.kde.org/show_bug.cgi?id=506211 to track this issue. |
From: Andreas A. <ar...@so...> - 2025-06-25 14:36:00
|
https://sourceware.org/git/gitweb.cgi?p=valgrind.git;h=24b634e8ce04de70d4aa6c61a12149df223f9c68 commit 24b634e8ce04de70d4aa6c61a12149df223f9c68 Author: Andreas Arnez <ar...@li...> Date: Wed Jun 25 16:35:04 2025 +0200 Bug 503241 - s390x: Support z17 changes to the NNPA instruction This adds support for the NNPA enhancements that are implemented with z17. Diff: --- coregrind/m_extension/extension-s390x.c | 346 +++++++++++++++++++------------- 1 file changed, 207 insertions(+), 139 deletions(-) diff --git a/coregrind/m_extension/extension-s390x.c b/coregrind/m_extension/extension-s390x.c index 85b99ad086..98b825d9b5 100644 --- a/coregrind/m_extension/extension-s390x.c +++ b/coregrind/m_extension/extension-s390x.c @@ -301,11 +301,17 @@ typedef enum { S390_NNPA_MAX = 0x15, S390_NNPA_LOG = 0x20, S390_NNPA_EXP = 0x21, + S390_NNPA_SQRT = 0x22, + S390_NNPA_INVSQRT = 0x23, S390_NNPA_RELU = 0x31, S390_NNPA_TANH = 0x32, S390_NNPA_SIGMOID = 0x33, S390_NNPA_SOFTMAX = 0x34, + S390_NNPA_GELU = 0x35, S390_NNPA_BATCHNORM = 0x40, + S390_NNPA_MOMENTS = 0x41, + S390_NNPA_LAYERNORM = 0x42, + S390_NNPA_NORM = 0x43, S390_NNPA_MAXPOOL2D = 0x50, S390_NNPA_AVGPOOL2D = 0x51, S390_NNPA_LSTMACT = 0x60, @@ -313,6 +319,9 @@ typedef enum { S390_NNPA_CONVOLUTION = 0x70, S390_NNPA_MATMUL_OP = 0x71, S390_NNPA_MATMUL_OP_BCAST23 = 0x72, + S390_NNPA_MATMUL_OP_BCAST1 = 0x73, + S390_NNPA_TRANSFORM = 0xf0, + S390_NNPA_REDUCE = 0xf1, } s390_nnpa_function_t; /* Suported NNPA functions */ @@ -321,30 +330,51 @@ static const ULong NNPA_functions[] = { S390_SETBIT(S390_NNPA_SUB) | S390_SETBIT(S390_NNPA_MUL) | S390_SETBIT(S390_NNPA_DIV) | S390_SETBIT(S390_NNPA_MIN) | S390_SETBIT(S390_NNPA_MAX) | S390_SETBIT(S390_NNPA_LOG) | - S390_SETBIT(S390_NNPA_EXP) | S390_SETBIT(S390_NNPA_RELU) | + S390_SETBIT(S390_NNPA_EXP) | S390_SETBIT(S390_NNPA_SQRT) | + S390_SETBIT(S390_NNPA_INVSQRT) | S390_SETBIT(S390_NNPA_RELU) | S390_SETBIT(S390_NNPA_TANH) | S390_SETBIT(S390_NNPA_SIGMOID) | - S390_SETBIT(S390_NNPA_SOFTMAX)), - (S390_SETBIT(S390_NNPA_BATCHNORM) | S390_SETBIT(S390_NNPA_MAXPOOL2D) | - S390_SETBIT(S390_NNPA_AVGPOOL2D) | S390_SETBIT(S390_NNPA_LSTMACT) | - S390_SETBIT(S390_NNPA_GRUACT) | S390_SETBIT(S390_NNPA_CONVOLUTION) | - S390_SETBIT(S390_NNPA_MATMUL_OP) | - S390_SETBIT(S390_NNPA_MATMUL_OP_BCAST23)), + S390_SETBIT(S390_NNPA_SOFTMAX) | S390_SETBIT(S390_NNPA_GELU)), + (S390_SETBIT(S390_NNPA_BATCHNORM) | S390_SETBIT(S390_NNPA_MOMENTS) | + S390_SETBIT(S390_NNPA_LAYERNORM) | S390_SETBIT(S390_NNPA_NORM) | + S390_SETBIT(S390_NNPA_MAXPOOL2D) | S390_SETBIT(S390_NNPA_AVGPOOL2D) | + S390_SETBIT(S390_NNPA_LSTMACT) | S390_SETBIT(S390_NNPA_GRUACT) | + S390_SETBIT(S390_NNPA_CONVOLUTION) | S390_SETBIT(S390_NNPA_MATMUL_OP) | + S390_SETBIT(S390_NNPA_MATMUL_OP_BCAST23) | + S390_SETBIT(S390_NNPA_MATMUL_OP_BCAST1)), + 0, + (S390_SETBIT(S390_NNPA_TRANSFORM) | S390_SETBIT(S390_NNPA_REDUCE)), }; /* Supported parameter block formats */ static const ULong NNPA_ipbf[] = { - (S390_SETBIT(0)), + (S390_SETBIT(0) | S390_SETBIT(1)), }; /* Supported data types and data layout formats */ +enum { + S390_NNPA_TYPE_1 = 0, // data type 1 (16 bit) + S390_NNPA_TYPE_BFP32 = 6, + S390_NNPA_TYPE_INT8 = 8, + S390_NNPA_TYPE_INT32 = 10, +}; + +enum { + S390_NNPA_4D_FEATURE_TENSOR = 0, + S390_NNPA_4D_KERNEL_TENSOR = 1, + S390_NNPA_4D_WEIGHTS_TENSOR = 2, + S390_NNPA_4D_GENERIC_TENSOR = 31, +}; + static const ULong NNPA_dtypes_layouts[] = { /* Data types */ - (S390_SETBIT(0) | // data type 1 (16 bit) + (S390_SETBIT(S390_NNPA_TYPE_1) | S390_SETBIT(S390_NNPA_TYPE_BFP32) | + S390_SETBIT(S390_NNPA_TYPE_INT8) | S390_SETBIT(S390_NNPA_TYPE_INT32) | /* Data layout formats */ - S390_SETBIT(32 + 0) | // 4D-feature tensor - S390_SETBIT(32 + 1) // 4D-kernel tensor - ), + S390_SETBIT(32 + S390_NNPA_4D_FEATURE_TENSOR) | + S390_SETBIT(32 + S390_NNPA_4D_KERNEL_TENSOR) | + S390_SETBIT(32 + S390_NNPA_4D_WEIGHTS_TENSOR) | + S390_SETBIT(32 + S390_NNPA_4D_GENERIC_TENSOR)), }; static const ULong NNPA_conversions[] = { @@ -360,10 +390,15 @@ struct s390_NNPA_parms_qaf { UInt mdis; ULong mts; ULong conversions; - ULong reserved2[22]; + ULong reserved2; + UInt mdnis[4]; + struct { + ULong reserved[19]; + } reserved3; }; -struct s390_NNPA_tensor0 { +/* Tensor descriptor, common for all data-layout formats */ +struct s390_NNPA_tensor { UChar layout; UChar dtype; UShort reserved1; @@ -372,21 +407,21 @@ struct s390_NNPA_tensor0 { ULong address; }; -struct s390_NNPA_parms0 { - ULong pbvn : 16; - ULong mvn : 8; - ULong ribm : 24; - ULong reserved0 : 15; - ULong cf : 1; - ULong reserved1[6]; - ULong save_area_address; - struct s390_NNPA_tensor0 out[2]; - struct s390_NNPA_tensor0 reserved2[2]; - struct s390_NNPA_tensor0 in[3]; - ULong reserved3[12]; - UInt param[5]; - UInt reserved4; - ULong reserved5[13]; +/* Parameter block format 0 or 1 */ +struct s390_NNPA_parms { + ULong pbvn : 16; + ULong mvn : 8; + ULong ribm : 24; + ULong reserved0 : 15; + ULong cf : 1; + ULong reserved1[6]; + ULong save_area_address; + struct s390_NNPA_tensor out[2]; + struct s390_NNPA_tensor reserved2[2]; + struct s390_NNPA_tensor in[3]; + ULong reserved3[12]; + UInt param[16]; + ULong reserved4[8]; }; enum { @@ -418,135 +453,145 @@ static const char* const s390_NNPA_errmsg_access[s390_NNPA_message_n] = { struct s390_NNPA_mem_dimensions { UChar layout; - ULong dim[5]; // total dimensions - ULong used[4]; // used dimensions, without padding - ULong step[5]; - ULong last_dim4_size; + ULong dim[4]; + ULong total_size; + ULong used_sticks; // occupied sticks per next-higher dimension + ULong stick_fill; + ULong last_stick_fill; }; -/* Determine the 5 dimensions used to represent the tensor data in memory */ +/* Determine the dimensions used to represent the tensor data in memory */ static enum ExtensionError -NNPA_tensor0_size(const struct s390_NNPA_tensor0* t, - UInt msg_idx, - struct s390_NNPA_mem_dimensions* out_md) +NNPA_tensor_size(const struct s390_NNPA_tensor* t, + UInt msg_idx, + struct s390_NNPA_mem_dimensions* out_md) { struct s390_NNPA_mem_dimensions md; ULong elem_size; + ULong eps; - md.layout = t->layout; - if (t->dtype == 0) + switch (t->dtype) { + case S390_NNPA_TYPE_INT8: + elem_size = 1; + break; + case S390_NNPA_TYPE_1: elem_size = 2; - else + break; + case S390_NNPA_TYPE_BFP32: + case S390_NNPA_TYPE_INT32: + elem_size = 4; + break; + default: return INSN_ERR(s390_NNPA_errmsg_dtype[msg_idx]); + } + eps = 128 / elem_size; + md.layout = t->layout; switch (t->layout) { - case 0: // 4D-feature tensor - md.dim[0] = md.used[0] = t->dim4; - md.dim[1] = md.used[1] = (t->dim1 + 63) / 64; - md.dim[2] = md.used[2] = t->dim3; - md.dim[3] = (t->dim2 + 31) / 32 * 32; - md.used[3] = t->dim2; - md.dim[4] = 64; - md.last_dim4_size = elem_size * (t->dim1 % 64); + case S390_NNPA_4D_FEATURE_TENSOR: + md.dim[0] = t->dim4; + md.dim[1] = (t->dim1 + eps - 1) / eps; + md.used_sticks = t->dim2; + goto common_tensor_dimensions; + case S390_NNPA_4D_KERNEL_TENSOR: + md.dim[0] = (t->dim1 + eps - 1) / eps; + md.dim[1] = t->dim4; + md.used_sticks = t->dim2; + goto common_tensor_dimensions; + case S390_NNPA_4D_WEIGHTS_TENSOR: + elem_size *= 2; + eps /= 2; + md.dim[0] = t->dim4; + md.dim[1] = (t->dim1 + eps - 1) / eps; + md.used_sticks = (t->dim2 + 1) / 2; + common_tensor_dimensions: + md.dim[2] = t->dim3; + md.dim[3] = (md.used_sticks + 31) / 32 * 32; + md.stick_fill = elem_size * (t->dim1 >= eps ? eps : t->dim1); + md.last_stick_fill = elem_size * ((t->dim1 - 1) % eps + 1); break; - case 1: // 4D-kernel tensor - md.dim[0] = md.used[0] = (t->dim1 + 63) / 64; - md.dim[1] = md.used[1] = t->dim4; - md.dim[2] = md.used[2] = t->dim3; - md.dim[3] = (t->dim2 + 31) / 32 * 32; - md.used[3] = t->dim2; - md.dim[4] = 64; - md.last_dim4_size = elem_size * (t->dim1 % 64); + case S390_NNPA_4D_GENERIC_TENSOR: + md.dim[0] = t->dim4; + md.dim[1] = t->dim3; + md.dim[2] = t->dim2; + md.dim[3] = t->dim1; + eps = 1; break; default: return INSN_ERR(s390_NNPA_errmsg_layout[msg_idx]); } - md.step[4] = elem_size * md.dim[4]; - md.step[3] = md.step[4] * md.dim[3]; - md.step[2] = md.step[3] * md.dim[2]; - md.step[1] = md.step[2] * md.dim[1]; - md.step[0] = md.step[1] * md.dim[0]; // total size - *out_md = md; + md.total_size = + elem_size * eps * md.dim[3] * md.dim[2] * md.dim[1] * md.dim[0]; + *out_md = md; return ExtErr_OK; } -/* Determine the size of the non-pad elements in the last dimension */ -static ULong NNPA_mem_dim4_size(const struct s390_NNPA_mem_dimensions* md, - ULong d0, - ULong d1) -{ - switch (md->layout) { - case 0: // 4D-feature tensor - return d1 + 1 == md->dim[1] ? md->last_dim4_size : md->step[4]; - case 1: // 4D-kernel tensor - return d0 + 1 == md->dim[0] ? md->last_dim4_size : md->step[4]; - } - return 0; -} - -static enum ExtensionError NNPA_pre_read_tensor0( - ThreadState* tst, UInt msg_idx, const struct s390_NNPA_tensor0* t) +/* Track a tensor's memory regions with PRE_MEM_READ or POST_MEM_WRITE */ +static enum ExtensionError NNPA_track_tensor(ThreadState* tst, + UInt msg_idx, + const struct s390_NNPA_tensor* t, + Bool do_write) { struct s390_NNPA_mem_dimensions md; enum ExtensionError ret; + ULong addr = t->address; - ret = NNPA_tensor0_size(t, msg_idx, &md); + ret = NNPA_tensor_size(t, msg_idx, &md); if (ret != ExtErr_OK) return ret; - for (ULong d0 = 0; d0 < md.used[0]; d0++) { - for (ULong d1 = 0; d1 < md.used[1]; d1++) { - for (ULong d2 = 0; d2 < md.used[2]; d2++) { - for (ULong d3 = 0; d3 < md.used[3]; d3++) { - ULong addr = t->address + d0 * md.step[1] + d1 * md.step[2] + - d2 * md.step[3] + d3 * md.step[4]; - ULong len = NNPA_mem_dim4_size(&md, d0, d1); - PRE_MEM_READ(tst, s390_NNPA_errmsg_access[msg_idx], addr, len); + switch (md.layout) { + case S390_NNPA_4D_FEATURE_TENSOR: + case S390_NNPA_4D_KERNEL_TENSOR: + case S390_NNPA_4D_WEIGHTS_TENSOR: + for (ULong d0 = 0; d0 < md.dim[0]; d0++) { + for (ULong d1 = 0; d1 < md.dim[1]; d1++) { + ULong len; + switch (md.layout) { + case S390_NNPA_4D_FEATURE_TENSOR: + case S390_NNPA_4D_WEIGHTS_TENSOR: + len = d1 + 1 == md.dim[1] ? md.last_stick_fill : md.stick_fill; + break; + case S390_NNPA_4D_KERNEL_TENSOR: + len = d0 + 1 == md.dim[0] ? md.last_stick_fill : md.stick_fill; + break; } - } - } - } - return ExtErr_OK; -} - -static UWord NNPA_pre_write_tensor0(ThreadState* tst, - UInt msg_idx, - const struct s390_NNPA_tensor0* t) -{ - struct s390_NNPA_mem_dimensions md; - enum ExtensionError ret; - - ret = NNPA_tensor0_size(t, msg_idx, &md); - if (ret != ExtErr_OK) - return ret; - - PRE_MEM_WRITE(tst, "NNPA(out_tensor)", t->address, md.step[0]); - return ExtErr_OK; -} - -static void NNPA_post_write_tensor0(ThreadState* tst, - UInt msg_idx, - const struct s390_NNPA_tensor0* t) -{ - struct s390_NNPA_mem_dimensions md; - enum ExtensionError ret; - - ret = NNPA_tensor0_size(t, msg_idx, &md); - if (ret != ExtErr_OK) - return; - - for (ULong d0 = 0; d0 < md.used[0]; d0++) { - for (ULong d1 = 0; d1 < md.used[1]; d1++) { - for (ULong d2 = 0; d2 < md.used[2]; d2++) { - for (ULong d3 = 0; d3 < md.used[3]; d3++) { - ULong addr = t->address + d0 * md.step[1] + d1 * md.step[2] + - d2 * md.step[3] + d3 * md.step[4]; - ULong len = NNPA_mem_dim4_size(&md, d0, d1); - POST_MEM_WRITE(tst, addr, len); + for (ULong d2 = 0; d2 < md.dim[2]; d2++) { + for (ULong d3 = 0; d3 < md.used_sticks; d3++) { + if (md.layout == S390_NNPA_4D_WEIGHTS_TENSOR && + d3 == md.used_sticks - 1 && t->dim2 % 2 != 0) { + // even elements only + for (ULong i = 0; i < len - 1; i += 2) { + if (do_write) { + POST_MEM_WRITE(tst, addr + i, 1); + } else { + PRE_MEM_READ(tst, s390_NNPA_errmsg_access[msg_idx], + addr + i, 1); + } + } + } else if (do_write) { + POST_MEM_WRITE(tst, addr, len); + } else { + PRE_MEM_READ(tst, s390_NNPA_errmsg_access[msg_idx], addr, + len); + } + addr += 128; + } + addr += 128 * (md.dim[3] - md.used_sticks); } } } + break; + case S390_NNPA_4D_GENERIC_TENSOR: + if (do_write) { + POST_MEM_WRITE(tst, t->address, md.total_size); + } else { + PRE_MEM_READ(tst, s390_NNPA_errmsg_access[msg_idx], t->address, + md.total_size); + } + break; } + return ExtErr_OK; } static enum ExtensionError do_extension_NNPA(ThreadState* tst, ULong variant) @@ -571,16 +616,21 @@ static enum ExtensionError do_extension_NNPA(ThreadState* tst, ULong variant) NNPA_dtypes_layouts, sizeof(NNPA_dtypes_layouts)); s390_filter_functions(&parms->conversions, sizeof(ULong), NNPA_conversions, sizeof(NNPA_conversions)); + // Clear reserved fields + parms->reserved1 = 0; + parms->reserved2 = 0; + parms->reserved3 = (__typeof__(parms->reserved3)){0}; } else { - struct s390_NNPA_parms0* parms = (void*)parms_addr; - const struct s390_NNPA_parms0 orig_parms = *parms; - ULong save_area_size = 0; - UInt in_tensors; - UInt out_tensors; + struct s390_NNPA_parms* parms = (void*)parms_addr; + const struct s390_NNPA_parms orig_parms = *parms; + ULong save_area_size = 0; + UInt in_tensors; + UInt out_tensors; + enum ExtensionError retval; parms_len = 4096; PRE_MEM_READ(tst, "NNPA(parms)", parms_addr, - sizeof(struct s390_NNPA_parms0)); + sizeof(struct s390_NNPA_parms)); if (parms->cf) { PRE_MEM_READ(tst, "NNPA(parms.csb)", parms_addr + 512, parms_len - 512); @@ -594,28 +644,39 @@ static enum ExtensionError do_extension_NNPA(ThreadState* tst, ULong variant) case S390_NNPA_DIV: case S390_NNPA_MIN: case S390_NNPA_MAX: + case S390_NNPA_NORM: in_tensors = 2; out_tensors = 1; break; case S390_NNPA_LOG: case S390_NNPA_EXP: + case S390_NNPA_SQRT: + case S390_NNPA_INVSQRT: case S390_NNPA_RELU: case S390_NNPA_TANH: case S390_NNPA_SIGMOID: + case S390_NNPA_GELU: in_tensors = 1; out_tensors = 1; break; case S390_NNPA_SOFTMAX: + case S390_NNPA_REDUCE: in_tensors = 1; out_tensors = 1; save_area_size = 8192; break; case S390_NNPA_BATCHNORM: + case S390_NNPA_LAYERNORM: in_tensors = 3; out_tensors = 1; break; + case S390_NNPA_MOMENTS: + in_tensors = 1; + out_tensors = 2; + break; case S390_NNPA_MAXPOOL2D: case S390_NNPA_AVGPOOL2D: + case S390_NNPA_TRANSFORM: in_tensors = 1; out_tensors = 1; break; @@ -627,6 +688,7 @@ static enum ExtensionError do_extension_NNPA(ThreadState* tst, ULong variant) case S390_NNPA_CONVOLUTION: case S390_NNPA_MATMUL_OP: case S390_NNPA_MATMUL_OP_BCAST23: + case S390_NNPA_MATMUL_OP_BCAST1: in_tensors = 3; out_tensors = 1; break; @@ -635,16 +697,20 @@ static enum ExtensionError do_extension_NNPA(ThreadState* tst, ULong variant) } for (UInt i = 0; i < in_tensors; i++) { - enum ExtensionError retval = - NNPA_pre_read_tensor0(tst, s390_NNPA_message_in + i, &parms->in[i]); + retval = NNPA_track_tensor(tst, s390_NNPA_message_in + i, + &parms->in[i], False); if (retval != ExtErr_OK) return retval; } for (UInt i = 0; i < out_tensors; i++) { - enum ExtensionError retval = NNPA_pre_write_tensor0( - tst, s390_NNPA_message_out + i, &parms->out[i]); + UInt msg_idx = s390_NNPA_message_out + i; + struct s390_NNPA_mem_dimensions md; + + retval = NNPA_tensor_size(&parms->out[i], msg_idx, &md); if (retval != ExtErr_OK) return retval; + PRE_MEM_WRITE(tst, s390_NNPA_errmsg_access[msg_idx], + parms->out[i].address, md.total_size); } if (save_area_size != 0) { PRE_MEM_WRITE(tst, "NNPA(save_area)", parms->save_area_address, @@ -653,8 +719,10 @@ static enum ExtensionError do_extension_NNPA(ThreadState* tst, ULong variant) cc = do_NNPA_insn(&gpr0, parms_addr); if (cc == 0) { for (UInt i = 0; i < out_tensors; i++) { - NNPA_post_write_tensor0(tst, s390_NNPA_message_out + i, - &orig_parms.out[i]); + retval = NNPA_track_tensor(tst, s390_NNPA_message_out + i, + &orig_parms.out[i], True); + if (retval != ExtErr_OK) + return retval; } } } |
From: Paul F. <pj...@wa...> - 2025-06-22 10:34:09
|
Hi Mark On 6/22/25 00:15, Mark Wielaard wrote: > Hopefully that gets rid of all the Warnings. > Yes, all back to normal this morning. Thanks! Paul |
From: Mark W. <ma...@so...> - 2025-06-21 23:41:15
|
https://sourceware.org/git/gitweb.cgi?p=valgrind.git;h=116a1c8242891b5ddcd1ce9704b0ab90143cc968 commit 116a1c8242891b5ddcd1ce9704b0ab90143cc968 Author: Mark Wielaard <ma...@kl...> Date: Sat Jun 21 23:04:04 2025 +0200 Update DW_TAG_subprogram parsing for clang Clang doesn't give a name for some artificial subprograms. In that case just use "<artificial>" as the name of the DW_TAG_subprogram. Clang also sometimes generates a DW_TAG_subprogram without any attributes. These aren't really useful for us. So just silently skip them. If we warn about subprograms without a name, specification or abstract origin, also emit the index in the .debug_info section to make it easier to look them up. Diff: --- coregrind/m_debuginfo/readdwarf3.c | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/coregrind/m_debuginfo/readdwarf3.c b/coregrind/m_debuginfo/readdwarf3.c index 745f2c43a6..49c5abb68d 100644 --- a/coregrind/m_debuginfo/readdwarf3.c +++ b/coregrind/m_debuginfo/readdwarf3.c @@ -3617,18 +3617,27 @@ static Bool parse_inl_DIE ( sub.isSubprogRef = False; } } + /* Clang doesn't give a name for some artificial subprograms. + Just use "<artificial>" as the name. */ + if (!name_or_spec && sub.isArtificial) { + name_or_spec = True; + fn = ML_(addStr)(cc->di, "<artificial>", -1); + sub.ref.fn = fn; + sub.isSubprogRef = False; + } if (name_or_spec) ML_(addSubprogram) (cc->di, &sub); - else { + else if (nf_i > 1 /* Clang produces empty subprograms, no attrs. */ + && VG_(clo_verbosity) >= 1) { /* Only warn once per debug file. */ static HChar *last_dbgname; HChar *dbgname = cc->di->fsm.dbgname ? cc->di->fsm.dbgname : cc->di->fsm.filename; if (last_dbgname != dbgname) { - if (VG_(clo_verbosity) >= 1) - VG_(message)(Vg_DebugMsg, "Warning: DW_TAG_subprogram with" - " no DW_AT_name and no DW_AT_specification or" - " DW_AT_abstract_origin in %s\n", dbgname); + VG_(message)(Vg_DebugMsg, + "Warning: <%lx> DW_TAG_subprogram with no" + " DW_AT_name and no DW_AT_specification or" + " DW_AT_abstract_origin in %s\n", posn, dbgname); last_dbgname = dbgname; } } |
From: Florian K. <fk...@so...> - 2025-06-21 22:32:27
|
https://sourceware.org/git/gitweb.cgi?p=valgrind.git;h=c38e9220c3efb2b11c94e744fe679851a4c63957 commit c38e9220c3efb2b11c94e744fe679851a4c63957 Author: Florian Krohm <fl...@ei...> Date: Sat Jun 21 19:49:02 2025 +0000 ir_opt.c bug fix: folloup to 4b8dcbb146 x <= x is True, you silly. Diff: --- VEX/priv/ir_opt.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/VEX/priv/ir_opt.c b/VEX/priv/ir_opt.c index 6b75119ab7..ee2c5a4a71 100644 --- a/VEX/priv/ir_opt.c +++ b/VEX/priv/ir_opt.c @@ -2464,12 +2464,8 @@ static IRExpr* fold_Expr_WRK ( IRExpr** env, IRExpr* e ) case Iop_ExpCmpNE64: case Iop_CmpLT32S: case Iop_CmpLT64S: - case Iop_CmpLE32S: - case Iop_CmpLE64S: case Iop_CmpLT32U: case Iop_CmpLT64U: - case Iop_CmpLE32U: - case Iop_CmpLE64U: case Iop_CmpNE8: case Iop_CmpNE16: case Iop_CmpNE32: @@ -2492,11 +2488,16 @@ static IRExpr* fold_Expr_WRK ( IRExpr** env, IRExpr* e ) } break; + case Iop_CmpLE32U: + case Iop_CmpLE64U: + case Iop_CmpLE32S: + case Iop_CmpLE64S: case Iop_CmpEQ8: case Iop_CmpEQ16: case Iop_CmpEQ32: case Iop_CmpEQ64: /* CmpEQ8/16/32/64(t,t) ==> 1, for some IRTemp t */ + /* CmpLE32U/64U/32S/64S(t,t) ==> 1, for some IRTemp t */ if (sameIRExprs(env, e->Iex.Binop.arg1, e->Iex.Binop.arg2)) { e2 = mkTrue(); } |
From: Mark W. <ma...@kl...> - 2025-06-21 22:15:37
|
Hi Paul, On Sat, Jun 21, 2025 at 05:27:43PM +0200, Paul Floyd via Valgrind-developers wrote: > On 21/06/2025 00:12, Mark Wielaard wrote: > >>Compiler is the system compiler, based on LLVM 18 > >> > >> > >>paulf> clang++ --version > >>FreeBSD clang version 18.1.6 > >>(https://github.com/llvm/llvm-project.git llvmorg-18.1.6-0-g1118c > >>2e05e67) > >>Target: x86_64-unknown-freebsd14.2 > >>Thread model: posix > >>InstalledDir: /usr/bin > >I'll try to get a freebsd 14.2 setup. It looks like the cfarm only has > >freebsd 15, do you happen to know if the issue also occurs on that > >version? > > I hadn't seen that cfarm how has some FreeBSD machines. I'll see if > I can setup a crontab for regtest on one of them. > > Two seem to be unreachable at the moment. The reachable one is > running CheriBSD. That's hardware with enhanced security built in to > all pointers. I doubt that Valgrind will work on that (and in any > case it is already doing much of the checks that Memcheck does but > in hardware). > > However, you shouldn't need to to that far. I can reproduce an > example on Fedora 42 amd64. > > In the drd/tests directory, compile std_list.cpp with everything LLVM: > > clang++ -g -o std_list std_list.cpp -fuse-ld=/usr/bin/ld.lld -stdlib=libc++ > > That is > > clang++ --version > clang version 20.1.6 (Fedora 20.1.6-1.fc42) > > Then I can reproduce the problem: > > ../../vg-in-place --tool=drd --check-stack-var=yes --show-confl-seg > =no ./std_list Thanks. I did eventually install FreeBSD 14.3 in a VM. That and the above showed me what was going on. There are two issues with the clang produced DWARF. First for some artificial (DW_AT_artificial) subprograms it doesn't produce a DW_AT_name. In that case we just call it "<artificial>". In some other cases like: static void func (int i) { static int count = 1; count += i; } void inc (void) { func (1); } $ clang -g -O2 -c t.c It produces: <1><23>: Abbrev Number: 2 (DW_TAG_subprogram) <2><24>: Abbrev Number: 3 (DW_TAG_variable) <25> DW_AT_name : (indexed string: 0x3): count <26> DW_AT_type : <0x30> <2a> DW_AT_decl_file : 0 <2b> DW_AT_decl_line : 3 <2c> DW_AT_location : (DW_OP_addrx <0>) <2><2f>: Abbrev Number: 0 So it "invents" a no-attribute DW_TAG_subprogram to put the static count variable in. Which is odd, since there is a real DW_TAG_subprogram with a DW_AT_name for func. We just ignore these subprograms without attributes since they are useless. commit 116a1c8242891b5ddcd1ce9704b0ab90143cc968 Author: Mark Wielaard <ma...@kl...> Date: Sat Jun 21 23:04:04 2025 +0200 Update DW_TAG_subprogram parsing for clang Clang doesn't give a name for some artificial subprograms. In that case just use "<artificial>" as the name of the DW_TAG_subprogram. Clang also sometimes generates a DW_TAG_subprogram without any attributes. These aren't really useful for us. So just silently skip them. If we warn about subprograms without a name, specification or abstract origin, also emit the index in the .debug_info section to make it easier to look them up. Hopefully that gets rid of all the Warnings. Cheers, Mark |
From: Paul F. <pj...@wa...> - 2025-06-21 15:27:53
|
Hi Mark On 21/06/2025 00:12, Mark Wielaard wrote: >> Compiler is the system compiler, based on LLVM 18 >> >> >> paulf> clang++ --version >> FreeBSD clang version 18.1.6 >> (https://github.com/llvm/llvm-project.git llvmorg-18.1.6-0-g1118c >> 2e05e67) >> Target: x86_64-unknown-freebsd14.2 >> Thread model: posix >> InstalledDir: /usr/bin > I'll try to get a freebsd 14.2 setup. It looks like the cfarm only has > freebsd 15, do you happen to know if the issue also occurs on that > version? I hadn't seen that cfarm how has some FreeBSD machines. I'll see if I can setup a crontab for regtest on one of them. Two seem to be unreachable at the moment. The reachable one is running CheriBSD. That's hardware with enhanced security built in to all pointers. I doubt that Valgrind will work on that (and in any case it is already doing much of the checks that Memcheck does but in hardware). However, you shouldn't need to to that far. I can reproduce an example on Fedora 42 amd64. In the drd/tests directory, compile std_list.cpp with everything LLVM: clang++ -g -o std_list std_list.cpp -fuse-ld=/usr/bin/ld.lld -stdlib=libc++ That is clang++ --version clang version 20.1.6 (Fedora 20.1.6-1.fc42) Then I can reproduce the problem: ../../vg-in-place --tool=drd --check-stack-var=yes --show-confl-seg =no ./std_list ==4383== drd, a thread error detector ==4383== Copyright (C) 2006-2024, and GNU GPL'd, by Bart Van Assche et al. ==4383== Using Valgrind-3.26.0.GIT and LibVEX; rerun with -h for copyright info ==4383== Command: ./std_list ==4383== --4383-- Warning: DW_TAG_subprogram with no DW_AT_name and no DW_AT_specification or DW_AT_abstract_origin in /home/paulf/.cache/debuginfod_client/5da32e666245ff34dff556bfbe8dce95f10684f5/debuginfo --4383-- Warning: DW_TAG_subprogram with no DW_AT_name and no DW_AT_specification or DW_AT_abstract_origin in /home/paulf/.cache/debuginfod_client/930a216263bfe4ab5026826ea37a54a16f37cf40/debuginfo ==4383== ==4383== For lists of detected and suppressed errors, rerun with: -s ==4383== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 21 from 17) A+ Paul |
From: Florian K. <fk...@so...> - 2025-06-21 14:25:10
|
https://sourceware.org/git/gitweb.cgi?p=valgrind.git;h=3bae961d3fc5c506bbf2e1210ec2fb366eb46f30 commit 3bae961d3fc5c506bbf2e1210ec2fb366eb46f30 Author: Florian Krohm <fl...@ei...> Date: Sat Jun 21 14:11:47 2025 +0000 libvex_ir.h: Fix comment for Iop_DivModU128to64 This IROp uses an I128 dividend and produces an I128 result. Cf. function typeOfPrimop and IR generation for amd64 and s390. Diff: --- VEX/pub/libvex_ir.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/VEX/pub/libvex_ir.h b/VEX/pub/libvex_ir.h index 80ef8f27a4..803a1317ed 100644 --- a/VEX/pub/libvex_ir.h +++ b/VEX/pub/libvex_ir.h @@ -521,7 +521,7 @@ typedef // of which lo half is div and hi half is mod Iop_DivModS64to32, // ditto, signed - Iop_DivModU128to64, // :: V128,I64 -> V128 + Iop_DivModU128to64, // :: I128,I64 -> I128 // of which lo half is div and hi half is mod Iop_DivModS128to64, // ditto, signed |
From: Mark W. <ma...@kl...> - 2025-06-20 22:13:02
|
Hi Paul, On Fri, Jun 20, 2025 at 08:20:16PM +0200, Paul Floyd via Valgrind-developers wrote: > > On 6/20/25 11:54, Mark Wielaard wrote: > >Which failures are those? Are they all about std_list or also other > >objects? Which compiler version was used? > > The failures are > > memcheck/tests/leak-autofreepool-5 (stderr) > memcheck/tests/leak_cpp_interior (stderr) > helgrind/tests/shared_timed_mutex (stderr) > drd/tests/annotate_static (stderr) > drd/tests/monitor_example (stderr) > drd/tests/shared_timed_mutex (stderr) > drd/tests/std_list (stderr) > drd/tests/timed_mutex (stderr) > > They are all C++ tests apart from the first. Could you sent me the log or diff files of the above tests? > Compiler is the system compiler, based on LLVM 18 > > > paulf> clang++ --version > FreeBSD clang version 18.1.6 > (https://github.com/llvm/llvm-project.git llvmorg-18.1.6-0-g1118c > 2e05e67) > Target: x86_64-unknown-freebsd14.2 > Thread model: posix > InstalledDir: /usr/bin I'll try to get a freebsd 14.2 setup. It looks like the cfarm only has freebsd 15, do you happen to know if the issue also occurs on that version? > >Could you upload/sent the readelf --debug-dump=info drd/tests/std_list > >output somewhere? Probably gzipped. > > I'll e-mail them to you directly. Thanks, I looked them over but I don't see where the issue is. I will have to try to replicate myself on a freebsd system. > >The Warning says there is a DW_TAG_subprogram that has no name and no > >reference to another subprogram that could describe it. Which means the > >subprogram is not very useful. I wonder why. Maybe a bug in the > >compiler? Or an artificial function without a name? > > Pass. > > >Were those tests run with -q? The Warning shouldn't show up then. > >Maybe we should filter out those Warning messages in some stderr > >filter? > > None of the tests use -q. With -q there's no warning. OK. Maybe we can run these tests with -q. I'll look. > >Or maybe the Warning should be behind -v since there isn't really > >something the user can do about it, except recompile their program with > >another compiler? > > We could filter, but I think that making the warning verbose only > would be better (if there's no other fix). Yeah, if we cannot figure it out then hiding behind -v might be best. Thanks, Mark |
From: Florian K. <fk...@so...> - 2025-06-20 20:31:38
|
https://sourceware.org/git/gitweb.cgi?p=valgrind.git;h=4b8dcbb14601cf2bad02e370be825dcb7169bc16 commit 4b8dcbb14601cf2bad02e370be825dcb7169bc16 Author: Florian Krohm <fl...@ei...> Date: Fri Jun 20 20:28:22 2025 +0000 Constant folding tweaks. Add constant folding for Iop_8Sto64, Iop_32HIto16, Iop_Or1 and various integer comparison operators. New functions mkFalse and mkTrue. Diff: --- VEX/priv/ir_opt.c | 68 +++++++++++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 59 insertions(+), 9 deletions(-) diff --git a/VEX/priv/ir_opt.c b/VEX/priv/ir_opt.c index 6565378654..6b75119ab7 100644 --- a/VEX/priv/ir_opt.c +++ b/VEX/priv/ir_opt.c @@ -1262,7 +1262,6 @@ static Bool notBool ( Bool b ) static IRExpr* mkZeroOfPrimopResultType ( IROp op ) { switch (op) { - case Iop_CmpNE32: return IRExpr_Const(IRConst_U1(toBool(0))); case Iop_Xor8: return IRExpr_Const(IRConst_U8(0)); case Iop_Xor16: return IRExpr_Const(IRConst_U16(0)); case Iop_Sub32: @@ -1278,14 +1277,23 @@ static IRExpr* mkZeroOfPrimopResultType ( IROp op ) } } +/* Make a Boolean False value */ +static inline IRExpr* mkFalse(void) +{ + return IRExpr_Const(IRConst_U1(toBool(0))); +} + +/* Make a Boolean True value */ +static inline IRExpr* mkTrue(void) +{ + return IRExpr_Const(IRConst_U1(toBool(1))); +} + /* Make a value containing all 1-bits, which has the same type as the result of the given primop. */ static IRExpr* mkOnesOfPrimopResultType ( IROp op ) { switch (op) { - case Iop_CmpEQ32: - case Iop_CmpEQ64: - return IRExpr_Const(IRConst_U1(toBool(1))); case Iop_Or8: return IRExpr_Const(IRConst_U8(0xFF)); case Iop_Or16: @@ -1440,6 +1448,13 @@ static IRExpr* fold_Expr_WRK ( IRExpr** env, IRExpr* e ) e2 = IRExpr_Const(IRConst_U32(u32)); break; } + case Iop_8Sto64: { + ULong u64 = e->Iex.Unop.arg->Iex.Const.con->Ico.U8; + u64 <<= 56; + u64 = (Long)u64 >> 56; /* signed shift */ + e2 = IRExpr_Const(IRConst_U64(u64)); + break; + } case Iop_16Sto32: { UInt u32 = e->Iex.Unop.arg->Iex.Const.con->Ico.U16; u32 <<= 16; @@ -1474,6 +1489,12 @@ static IRExpr* fold_Expr_WRK ( IRExpr** env, IRExpr* e ) e2 = IRExpr_Const(IRConst_U32( 0xFFFF & e->Iex.Unop.arg->Iex.Const.con->Ico.U16)); break; + case Iop_32HIto16: { + UInt w32 = e->Iex.Unop.arg->Iex.Const.con->Ico.U32; + w32 >>= 16; + e2 = IRExpr_Const(IRConst_U16(toUShort(w32))); + break; + } case Iop_32to16: e2 = IRExpr_Const(IRConst_U16(toUShort( 0xFFFF & e->Iex.Unop.arg->Iex.Const.con->Ico.U32))); @@ -1779,6 +1800,11 @@ static IRExpr* fold_Expr_WRK ( IRExpr** env, IRExpr* e ) switch (e->Iex.Binop.op) { /* -- Or -- */ + case Iop_Or1: + e2 = IRExpr_Const(IRConst_U1(toBool( + (e->Iex.Binop.arg1->Iex.Const.con->Ico.U1 + | e->Iex.Binop.arg2->Iex.Const.con->Ico.U1)))); + break; case Iop_Or8: e2 = IRExpr_Const(IRConst_U8(toUChar( (e->Iex.Binop.arg1->Iex.Const.con->Ico.U8 @@ -2432,14 +2458,31 @@ static IRExpr* fold_Expr_WRK ( IRExpr** env, IRExpr* e ) } break; + case Iop_ExpCmpNE8: + case Iop_ExpCmpNE16: + case Iop_ExpCmpNE32: + case Iop_ExpCmpNE64: + case Iop_CmpLT32S: + case Iop_CmpLT64S: + case Iop_CmpLE32S: + case Iop_CmpLE64S: + case Iop_CmpLT32U: + case Iop_CmpLT64U: + case Iop_CmpLE32U: + case Iop_CmpLE64U: + case Iop_CmpNE8: + case Iop_CmpNE16: case Iop_CmpNE32: - /* CmpNE32(t,t) ==> 0, for some IRTemp t */ + case Iop_CmpNE64: + /* Integer comparisons for some kind of inequality yield + 'False' when both operands are identical. */ if (sameIRExprs(env, e->Iex.Binop.arg1, e->Iex.Binop.arg2)) { - e2 = mkZeroOfPrimopResultType(e->Iex.Binop.op); + e2 = mkFalse(); break; } /* CmpNE32(1Uto32(b), 0) ==> b */ - if (isZeroU32(e->Iex.Binop.arg2)) { + if (e->Iex.Binop.op == Iop_CmpNE32 && + isZeroU32(e->Iex.Binop.arg2)) { IRExpr* a1 = chase(env, e->Iex.Binop.arg1); if (a1 && a1->tag == Iex_Unop && a1->Iex.Unop.op == Iop_1Uto32) { @@ -2449,10 +2492,17 @@ static IRExpr* fold_Expr_WRK ( IRExpr** env, IRExpr* e ) } break; - // in total 32 bits + case Iop_CmpEQ8: + case Iop_CmpEQ16: case Iop_CmpEQ32: - // in total 64 bits case Iop_CmpEQ64: + /* CmpEQ8/16/32/64(t,t) ==> 1, for some IRTemp t */ + if (sameIRExprs(env, e->Iex.Binop.arg1, e->Iex.Binop.arg2)) { + e2 = mkTrue(); + } + break; + + // in total 64 bits case Iop_CmpEQ8x8: case Iop_CmpEQ16x4: case Iop_CmpEQ32x2: |
From: Florian K. <fl...@ei...> - 2025-06-20 20:31:35
|
Hi Mark, thanks for the review. Checked in as 4b8dcbb146. On 19.06.25 23:54, Mark Wielaard wrote: > > Do you happen to have a list or is there a bug for "missing constant > folding oppertunities" that someone could try? > There is no bug that I could find and I don't have a list either. But it would be worthwhile to fill in the gaps. Constant folding is a cheap and easy thing to do and effective. Algebraic identities are a different story as they need to recurse the subtrees (sameIRexprs). Anyhow, I'll bite and make a pass and see what is missing for operations of integer type except Ity_I128. I got quite puzzled to see that an U128 constant is represented by an UShort rather than a __uint128_t. Florian |
From: Paul F. <pj...@wa...> - 2025-06-20 18:20:24
|
On 6/20/25 11:54, Mark Wielaard wrote: > Which failures are those? Are they all about std_list or also other > objects? Which compiler version was used? The failures are memcheck/tests/leak-autofreepool-5 (stderr) memcheck/tests/leak_cpp_interior (stderr) helgrind/tests/shared_timed_mutex (stderr) drd/tests/annotate_static (stderr) drd/tests/monitor_example (stderr) drd/tests/shared_timed_mutex (stderr) drd/tests/std_list (stderr) drd/tests/timed_mutex (stderr) They are all C++ tests apart from the first. Compiler is the system compiler, based on LLVM 18 paulf> clang++ --version FreeBSD clang version 18.1.6 (https://github.com/llvm/llvm-project.git llvmorg-18.1.6-0-g1118c 2e05e67) Target: x86_64-unknown-freebsd14.2 Thread model: posix InstalledDir: /usr/bin > Could you upload/sent the readelf --debug-dump=info drd/tests/std_list > output somewhere? Probably gzipped. I'll e-mail them to you directly. > The Warning says there is a DW_TAG_subprogram that has no name and no > reference to another subprogram that could describe it. Which means the > subprogram is not very useful. I wonder why. Maybe a bug in the > compiler? Or an artificial function without a name? Pass. > Were those tests run with -q? The Warning shouldn't show up then. > Maybe we should filter out those Warning messages in some stderr > filter? None of the tests use -q. With -q there's no warning. > Or maybe the Warning should be behind -v since there isn't really > something the user can do about it, except recompile their program with > another compiler? We could filter, but I think that making the warning verbose only would be better (if there's no other fix). A+ Paul |
From: Mark W. <ma...@kl...> - 2025-06-20 09:54:27
|
Hi Paul, On Fri, 2025-06-20 at 07:49 +0200, Paul Floyd via Valgrind-developers wrote: > On 6/19/25 23:59, Mark Wielaard wrote: > > https://sourceware.org/git/gitweb.cgi?p=valgrind.git;h=f7dccaab11b8dc1af2bbcd31dea5bb7a50c6f811 > > > > commit f7dccaab11b8dc1af2bbcd31dea5bb7a50c6f811 > > Author: Mark Wielaard <ma...@kl...> > > Date: Thu May 29 23:41:52 2025 +0200 > > > > Rewrite DWARF inlined subroutine handling to work cross CU > > On FreeBSD 14.2 amd64 I'm getting 8 new failures. They all have > something like > > +Warning: DW_TAG_subprogram with no DW_AT_name and no > DW_AT_specification or DW_AT_abstract_or > igin in /home/paulf/z400/paulf/scratch/valgrind/drd/tests/std_list Which failures are those? Are they all about std_list or also other objects? Which compiler version was used? Could you upload/sent the readelf --debug-dump=info drd/tests/std_list output somewhere? Probably gzipped. The Warning says there is a DW_TAG_subprogram that has no name and no reference to another subprogram that could describe it. Which means the subprogram is not very useful. I wonder why. Maybe a bug in the compiler? Or an artificial function without a name? Were those tests run with -q? The Warning shouldn't show up then. Maybe we should filter out those Warning messages in some stderr filter? Or maybe the Warning should be behind -v since there isn't really something the user can do about it, except recompile their program with another compiler? Cheers, Mark |
From: Paul F. <pj...@wa...> - 2025-06-20 05:49:19
|
On 6/19/25 23:59, Mark Wielaard wrote: > https://sourceware.org/git/gitweb.cgi?p=valgrind.git;h=f7dccaab11b8dc1af2bbcd31dea5bb7a50c6f811 > > commit f7dccaab11b8dc1af2bbcd31dea5bb7a50c6f811 > Author: Mark Wielaard <ma...@kl...> > Date: Thu May 29 23:41:52 2025 +0200 > > Rewrite DWARF inlined subroutine handling to work cross CU > Hi Mark On FreeBSD 14.2 amd64 I'm getting 8 new failures. They all have something like +Warning: DW_TAG_subprogram with no DW_AT_name and no DW_AT_specification or DW_AT_abstract_or igin in /home/paulf/z400/paulf/scratch/valgrind/drd/tests/std_list A+ Paul |
From: Mark W. <ma...@so...> - 2025-06-19 21:59:22
|
https://sourceware.org/git/gitweb.cgi?p=valgrind.git;h=f7dccaab11b8dc1af2bbcd31dea5bb7a50c6f811 commit f7dccaab11b8dc1af2bbcd31dea5bb7a50c6f811 Author: Mark Wielaard <ma...@kl...> Date: Thu May 29 23:41:52 2025 +0200 Rewrite DWARF inlined subroutine handling to work cross CU The readdwarf3 parsers cannot read DIEs across CUs. An inlined subroutine refers to an subprogram which has a name (or refers to a declaration of a subprogram that has a name). These subprograms can be (and often are when dwz has been used to compress the DWARF) in a different CU. So a lot of inlined subroutines in backtraces are just called "UnknownInlinedFun". To work around not being able to read DIEs across CUs directly we don't try to immediately resolve the name of the inlined subroutine by following the abstract origin reference to the subprogram, but just record it in the DiInlLoc. We also record all subprogram indexes while parsing in a new DiSubprogram structure and whether the subprogram had a name or had a reference to another subprogram (specification). We have to look under a couple more DIEs. We normally want to skip any DIE that doesn't have an address range when looking for inlined subroutines, but there are various other DIEs that can contain a subprogram (specification). We also want to walk the DIEs from low to high (cooked DIE) index, so we first pass over the main .debug_info, then the .debug_types, and finally the alt .debug_info. That way we can store the DiSubprograms in an array from low to high index and use a binary search to connect the inlined subroutines to the subprogram that contains the name. The code also tracks whether the subprogram is artificial, but this isn't used yet. But should make it possible for a followup patch to remove artificial inlined subroutines from a backtrace. Tested against emacs and libreoffice as packaged in Fedora where the programs and all shared libraries used are processed with dwz. The new code gives a name to every inlined subroutine. Except when the DWARF produced is bad and the DW_AT_subroutine didn't contain an DW_AT_abstract_origin and so no DW_AT_subprogram can be found. https://bugs.kde.org/show_bug.cgi?id=338803 Diff: --- NEWS | 1 + coregrind/m_debuginfo/debuginfo.c | 6 +- coregrind/m_debuginfo/priv_storage.h | 29 ++- coregrind/m_debuginfo/readdwarf3.c | 379 +++++++++++++++++++---------------- coregrind/m_debuginfo/storage.c | 33 ++- 5 files changed, 264 insertions(+), 184 deletions(-) diff --git a/NEWS b/NEWS index 97e4b3b413..0e01182651 100644 --- a/NEWS +++ b/NEWS @@ -23,6 +23,7 @@ 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. +338803 Handling of dwz debug alt files or cross-CU is broken 503098 Incorrect NAN-boxing for float registers in RISC-V 503641 close_range syscalls started failing with 3.25.0 503677 duplicated-cond compiler warning in dis_RV64M diff --git a/coregrind/m_debuginfo/debuginfo.c b/coregrind/m_debuginfo/debuginfo.c index cd04720902..4ce976a6d4 100644 --- a/coregrind/m_debuginfo/debuginfo.c +++ b/coregrind/m_debuginfo/debuginfo.c @@ -2354,7 +2354,7 @@ Bool VG_(get_fnname_inl) ( DiEpoch ep, Addr a, const HChar** buf, ? & iipc->di->inltab[iipc->next_inltab] : NULL; vg_assert (next_inl); - *buf = next_inl->inlinedfn; + *buf = next_inl->inlined.fn; return True; } } @@ -2444,7 +2444,7 @@ Bool VG_(get_fnname_no_cxx_demangle) ( DiEpoch ep, Addr a, const HChar** buf, : NULL; vg_assert (next_inl); // The function we are in is called by next_inl. - *buf = next_inl->inlinedfn; + *buf = next_inl->inlined.fn; return True; } } @@ -2806,7 +2806,7 @@ const HChar* VG_(describe_IP)(DiEpoch ep, Addr eip, const InlIPCursor *iipc) : NULL; vg_assert (next_inl); // The function we are in is called by next_inl. - buf_fn = next_inl->inlinedfn; + buf_fn = next_inl->inlined.fn; know_fnname = True; // INLINED???? diff --git a/coregrind/m_debuginfo/priv_storage.h b/coregrind/m_debuginfo/priv_storage.h index d8cba81c48..868ce27727 100644 --- a/coregrind/m_debuginfo/priv_storage.h +++ b/coregrind/m_debuginfo/priv_storage.h @@ -11,6 +11,8 @@ Copyright (C) 2000-2017 Julian Seward js...@ac... + Copyright (C) 2025 Mark J. Wielaard + ma...@kl... This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as @@ -142,7 +144,10 @@ typedef /* Word 2 */ Addr addr_hi; /* highest address following the inlined fn */ /* Word 3 */ - const HChar* inlinedfn; /* inlined function name */ + union { + UWord subprog; /* subprogram DIE (cooked) reference. */ + const HChar* fn; /* inlined function name (after resolving) */ + } inlined; /* Word 4 and 5 */ UInt fndn_ix; /* index in di->fndnpool of caller source dirname/filename */ @@ -151,6 +156,18 @@ typedef } DiInlLoc; +typedef + struct { + UWord index; /* cooked DIE index. */ + union { + const HChar *fn; /* Name of subprogram. */ + UWord subprog; /* DW_AT_specification of another subprogram. */ + } ref; + Bool isSubprogRef; /* True is ref is a subprog reference. */ + Bool isArtificial; /* True is the subprogram has DW_AT_artificial. */ + } + DiSubprogram; + /* --------------------- CF INFO --------------------- */ /* DiCfSI: a structure to summarise DWARF2/3 CFA info for the code @@ -949,6 +966,12 @@ struct _DebugInfo { UWord inltab_size; SizeT maxinl_codesz; + /* Storage for subprogram attributes. To use in inltab after pass over + all debuginfo to resolve names. */ + DiSubprogram* subtab; + UWord subtab_used; + UWord subtab_size; + /* A set of expandable arrays to store CFI summary info records. The machine specific information (i.e. the DiCfSI_m struct) are stored in cfsi_m_pool, as these are highly duplicated. @@ -1125,10 +1148,12 @@ void ML_(addLineInfo) ( struct _DebugInfo* di, extern void ML_(addInlInfo) ( struct _DebugInfo* di, Addr addr_lo, Addr addr_hi, - const HChar* inlinedfn, + UWord subprog, UInt fndn_ix, Int lineno, UShort level); +extern void ML_(addSubprogram) ( struct _DebugInfo* di, DiSubprogram* sub ); + /* Add a CFI summary record. The supplied DiCfSI_m is copied. */ extern void ML_(addDiCfSI) ( struct _DebugInfo* di, Addr base, UInt len, DiCfSI_m* cfsi_m ); diff --git a/coregrind/m_debuginfo/readdwarf3.c b/coregrind/m_debuginfo/readdwarf3.c index 735896f7c0..745f2c43a6 100644 --- a/coregrind/m_debuginfo/readdwarf3.c +++ b/coregrind/m_debuginfo/readdwarf3.c @@ -11,6 +11,8 @@ Copyright (C) 2008-2017 OpenWorks LLP in...@op... + Copyright (C) 2025 Mark J. Wielaard + ma...@kl... This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as @@ -3388,147 +3390,6 @@ typedef } D3InlParser; -/* Return the function name corresponding to absori. - - absori is a 'cooked' reference to a DIE, i.e. absori can be either - in cc->escn_debug_info or in cc->escn_debug_info_alt. - get_inlFnName will uncook absori. - - The returned value is a (permanent) string in DebugInfo's .strchunks. - - LIMITATION: absori must point in the CU of cc. If absori points - in another CU, returns "UnknownInlinedFun". - - Here are the problems to retrieve the fun name if absori is in - another CU: the DIE reading code cannot properly extract data from - another CU, as the abbv code retrieved in the other CU cannot be - translated in an abbreviation. Reading data from the alternate debug - info also gives problems as the string reference is also in the alternate - file, but when reading the alt DIE, the string form is a 'local' string, - but cannot be read in the current CU, but must be read in the alt CU. - See bug 338803 comment#3 and attachment for a failed attempt to handle - these problems (failed because with the patch, only one alt abbrev hash - table is kept, while we must handle all abbreviations in all CUs - referenced by an absori (being a reference to an alt CU, or a previous - or following CU). */ -static const HChar* get_inlFnName (Int absori, CUConst* cc, Bool td3) -{ - Cursor c; - const g_abbv *abbv; - ULong atag, abbv_code; - UInt has_children; - UWord posn; - Bool type_flag, alt_flag; - const HChar *ret = NULL; - FormContents cts; - UInt nf_i; - - /* Some inlined subroutine call dwarf entries do not have the abstract - origin attribute, resulting in absori being 0 (see callers of - get_inlFnName). This is observed at least with gcc 6.3.0 when compiling - valgrind with lto. So, in case we have a 0 absori, do not report an - error, instead, rather return an unknown inlined function. */ - if (absori == 0) { - static Bool absori0_reported = False; - if (!absori0_reported && VG_(clo_verbosity) > 1) { - VG_(message)(Vg_DebugMsg, - "Warning: inlined fn name without absori\n" - "is shown as UnknownInlinedFun\n"); - absori0_reported = True; - } - TRACE_D3(" <get_inlFnName>: absori is not set"); - return ML_(addStr)(cc->di, "UnknownInlinedFun", -1); - } - - posn = uncook_die( cc, absori, &type_flag, &alt_flag); - if (type_flag) - cc->barf("get_inlFnName: uncooked absori in type debug info"); - - /* LIMITATION: check we are in the same CU. - If not, return unknown inlined function name. */ - /* if crossing between alt debug info<>normal info - or posn not in the cu range, - then it is in another CU. */ - if (alt_flag != cc->is_alt_info - || posn < cc->cu_start_offset - || posn >= cc->cu_start_offset + cc->unit_length) { - static Bool reported = False; - if (!reported && VG_(clo_verbosity) > 1) { - VG_(message)(Vg_DebugMsg, - "Warning: cross-CU LIMITATION: some inlined fn names\n" - "might be shown as UnknownInlinedFun\n"); - reported = True; - } - TRACE_D3(" <get_inlFnName><%lx>: cross-CU LIMITATION", posn); - return ML_(addStr)(cc->di, "UnknownInlinedFun", -1); - } - - init_Cursor (&c, cc->escn_debug_info, posn, cc->barf, - "Overrun get_inlFnName absori"); - - abbv_code = get_ULEB128( &c ); - abbv = get_abbv ( cc, abbv_code, td3); - atag = abbv->atag; - TRACE_D3(" <get_inlFnName><%lx>: Abbrev Number: %llu (%s)\n", - posn, abbv_code, ML_(pp_DW_TAG)( atag ) ); - - if (atag == 0) - cc->barf("get_inlFnName: invalid zero tag on DIE"); - - has_children = abbv->has_children; - if (has_children != DW_children_no && has_children != DW_children_yes) - cc->barf("get_inlFnName: invalid has_children value"); - - if (atag != DW_TAG_subprogram) - cc->barf("get_inlFnName: absori not a subprogram"); - - nf_i = 0; - while (True) { - DW_AT attr = (DW_AT) abbv->nf[nf_i].at_name; - DW_FORM form = (DW_FORM)abbv->nf[nf_i].at_form; - const name_form *nf = &abbv->nf[nf_i]; - nf_i++; - if (attr == 0 && form == 0) break; - get_Form_contents( &cts, cc, &c, False/*td3*/, nf ); - if (attr == DW_AT_name) { - HChar *fnname; - if (cts.szB >= 0) - cc->barf("get_inlFnName: expecting indirect string"); - fnname = ML_(cur_read_strdup)( cts.u.cur, - "get_inlFnName.1" ); - ret = ML_(addStr)(cc->di, fnname, -1); - ML_(dinfo_free) (fnname); - break; /* Name found, get out of the loop, as this has priority over - DW_AT_specification. */ - } - if (attr == DW_AT_specification) { - UWord cdie; - - if (cts.szB == 0) - cc->barf("get_inlFnName: AT specification missing"); - - /* The recursive call to get_inlFnName will uncook its arg. - So, we need to cook it here, so as to reference the - correct section (e.g. the alt info). */ - cdie = cook_die_using_form(cc, (UWord)cts.u.val, form); - - /* hoping that there is no loop */ - ret = get_inlFnName (cdie, cc, td3); - /* Unclear if having both DW_AT_specification and DW_AT_name is - possible but in any case, we do not break here. - If we find later on a DW_AT_name, it will override the name found - in the DW_AT_specification.*/ - } - } - - if (ret) - return ret; - else { - TRACE_D3("AbsOriFnNameNotFound"); - return ML_(addStr)(cc->di, "AbsOriFnNameNotFound", -1); - } -} - /* Returns True if the (possibly) childrens of the current DIE are interesting to parse. Returns False otherwise. If the current DIE has a sibling, the non interesting children can @@ -3618,8 +3479,8 @@ static Bool parse_inl_DIE ( Addr rangeoff = 0; UInt caller_fndn_ix = 0; Int caller_lineno = 0; - Int inlinedfn_abstract_origin = 0; - // 0 will be interpreted as no abstract origin by get_inlFnName + UWord inlinedfn_abstract_origin = 0; + // 0 will be interpreted as no abstract origin nf_i = 0; while (True) { @@ -3683,7 +3544,7 @@ static Bool parse_inl_DIE ( ip_hi1 += cc->di->text_debug_bias; ML_(addInlInfo) (cc->di, ip_lo, ip_hi1, - get_inlFnName (inlinedfn_abstract_origin, cc, td3), + inlinedfn_abstract_origin, caller_fndn_ix, caller_lineno, level); } @@ -3691,8 +3552,6 @@ static Bool parse_inl_DIE ( /* This inlined call is several address ranges. */ XArray *ranges; Word j; - const HChar *inlfnname = - get_inlFnName (inlinedfn_abstract_origin, cc, td3); /* Ranges are biased for the inline info using the same logic as what is used for biasing ranges for the var info, for which @@ -3709,7 +3568,7 @@ static Bool parse_inl_DIE ( // aMax+1 as range has its last bound included // while ML_(addInlInfo) expects last bound not // included. - inlfnname, + inlinedfn_abstract_origin, caller_fndn_ix, caller_lineno, level); } @@ -3718,11 +3577,82 @@ static Bool parse_inl_DIE ( goto_bad_DIE; } + if (dtag == DW_TAG_subprogram) { + DiSubprogram sub; + sub.index = posn; /* Note posn is already cooked. */ + sub.isArtificial = False; + UWord cdie = 0; + const HChar *fn = NULL; + Bool name_or_spec = False; + nf_i = 0; + while (True) { + DW_AT attr = (DW_AT) abbv->nf[nf_i].at_name; + DW_FORM form = (DW_FORM)abbv->nf[nf_i].at_form; + const name_form *nf = &abbv->nf[nf_i]; + nf_i++; + if (attr == 0 && form == 0) break; + get_Form_contents( &cts, cc, c_die, False/*td3*/, nf ); + if (attr == DW_AT_sibling && cts.szB > 0) { + parser->sibling = cts.u.val; + } + if (attr == DW_AT_artificial && cts.u.val == 1) { + sub.isArtificial = True; + } + if ((attr == DW_AT_specification + || attr == DW_AT_abstract_origin) + && cts.szB > 0 && cts.u.val > 0) { + name_or_spec = True; + cdie = cook_die_using_form(cc, (UWord)cts.u.val, form); + sub.ref.subprog = cdie; + sub.isSubprogRef = True; + } + if (attr == DW_AT_name && cts.szB < 0) { + HChar *fnname; + name_or_spec = True; + fnname = ML_(cur_read_strdup)( cts.u.cur, + ".1" ); + fn = ML_(addStr)(cc->di, fnname, -1); + ML_(dinfo_free) (fnname); + sub.ref.fn = fn; + sub.isSubprogRef = False; + } + } + if (name_or_spec) + ML_(addSubprogram) (cc->di, &sub); + else { + /* Only warn once per debug file. */ + static HChar *last_dbgname; + HChar *dbgname = cc->di->fsm.dbgname + ? cc->di->fsm.dbgname : cc->di->fsm.filename; + if (last_dbgname != dbgname) { + if (VG_(clo_verbosity) >= 1) + VG_(message)(Vg_DebugMsg, "Warning: DW_TAG_subprogram with" + " no DW_AT_name and no DW_AT_specification or" + " DW_AT_abstract_origin in %s\n", dbgname); + last_dbgname = dbgname; + } + } + } + // Only recursively parse the (possible) children for the DIE which - // might maybe contain a DW_TAG_inlined_subroutine: + // might maybe contain a DW_TAG_inlined_subroutine or DW_TAG_subprogram. + // subprograms can also appear without addresses. Bool ret = (unit_has_addrs - || dtag == DW_TAG_lexical_block || dtag == DW_TAG_subprogram - || dtag == DW_TAG_inlined_subroutine || dtag == DW_TAG_namespace); + || dtag == DW_TAG_compile_unit + || dtag == DW_TAG_partial_unit + || dtag == DW_TAG_lexical_block + || dtag == DW_TAG_subprogram + || dtag == DW_TAG_inlined_subroutine + || dtag == DW_TAG_namespace + || dtag == DW_TAG_enumeration_type + || dtag == DW_TAG_class_type + || dtag == DW_TAG_structure_type + || dtag == DW_TAG_union_type + || dtag == DW_TAG_module + || dtag == DW_TAG_with_stmt + || dtag == DW_TAG_catch_block + || dtag == DW_TAG_try_block + || dtag == DW_TAG_entry_point); return ret; bad_DIE: @@ -5609,8 +5539,10 @@ void new_dwarf3_reader_wrk ( } /* Perform three DIE-reading passes. The first pass reads DIEs from - alternate .debug_info (if any), the second pass reads DIEs from - .debug_info, and the third pass reads DIEs from .debug_types. + .debug_info, the second pass reads DIEs from .debug_types (if any), + and the third pass reads DIEs from the alternate .debug_info (if any). + This is in the order that cook_die numbers the DIEs, so the inlined + parser can add subprograms in order. Moving the body of this loop into a separate function would require a large number of arguments to be passed in, so it is kept inline instead. */ @@ -5618,23 +5550,6 @@ void new_dwarf3_reader_wrk ( ULong section_size; if (pass == 0) { - if (!ML_(sli_is_valid)(escn_debug_info_alt)) - continue; - /* Now loop over the Compilation Units listed in the alternate - .debug_info section (see D3SPEC sec 7.5) paras 1 and 2. - Each compilation unit contains a Compilation Unit Header - followed by precisely one DW_TAG_compile_unit or - DW_TAG_partial_unit DIE. */ - init_Cursor( &info, escn_debug_info_alt, 0, barf, - "Overrun whilst reading alternate .debug_info section" ); - section_size = escn_debug_info_alt.szB; - - /* Keep track of the last line table we have seen, - it might turn up again. */ - reset_fndn_ix_table(&fndn_ix_Table, &debug_line_offset, (ULong) -1); - - TRACE_D3("\n------ Parsing alternate .debug_info section ------\n"); - } else if (pass == 1) { /* Now loop over the Compilation Units listed in the .debug_info section (see D3SPEC sec 7.5) paras 1 and 2. Each compilation unit contains a Compilation Unit Header followed by precisely @@ -5648,7 +5563,7 @@ void new_dwarf3_reader_wrk ( reset_fndn_ix_table(&fndn_ix_Table, &debug_line_offset, (ULong) -1); TRACE_D3("\n------ Parsing .debug_info section ------\n"); - } else { + } else if (pass == 1) { if (!ML_(sli_is_valid)(escn_debug_types)) continue; if (!VG_(clo_read_var_info)) @@ -5662,6 +5577,23 @@ void new_dwarf3_reader_wrk ( reset_fndn_ix_table(&fndn_ix_Table, &debug_line_offset, (ULong) -1); TRACE_D3("\n------ Parsing .debug_types section ------\n"); + } else { + if (!ML_(sli_is_valid)(escn_debug_info_alt)) + continue; + /* Now loop over the Compilation Units listed in the alternate + .debug_info section (see D3SPEC sec 7.5) paras 1 and 2. + Each compilation unit contains a Compilation Unit Header + followed by precisely one DW_TAG_compile_unit or + DW_TAG_partial_unit DIE. */ + init_Cursor( &info, escn_debug_info_alt, 0, barf, + "Overrun whilst reading alternate .debug_info section" ); + section_size = escn_debug_info_alt.szB; + + /* Keep track of the last line table we have seen, + it might turn up again. */ + reset_fndn_ix_table(&fndn_ix_Table, &debug_line_offset, (ULong) -1); + + TRACE_D3("\n------ Parsing alternate .debug_info section ------\n"); } abbv_state last_abbv; @@ -5713,22 +5645,22 @@ void new_dwarf3_reader_wrk ( TRACE_D3("\n"); TRACE_D3(" Compilation Unit @ offset 0x%llx:\n", cu_start_offset); /* parse_CU_header initialises the CU's hashtable of abbvs ht_abbvs */ - if (pass == 0) { + if (pass == 2) { parse_CU_Header( &cc, td3, &info, escn_debug_abbv_alt, last_abbv, False, True ); } else { parse_CU_Header( &cc, td3, &info, escn_debug_abbv, - last_abbv, pass == 2, False ); + last_abbv, pass == 1, False ); } - cc.escn_debug_str = pass == 0 ? escn_debug_str_alt + cc.escn_debug_str = pass == 2 ? escn_debug_str_alt : escn_debug_str; cc.escn_debug_ranges = escn_debug_ranges; cc.escn_debug_rnglists = escn_debug_rnglists; cc.escn_debug_loclists = escn_debug_loclists; cc.escn_debug_loc = escn_debug_loc; - cc.escn_debug_line = pass == 0 ? escn_debug_line_alt + cc.escn_debug_line = pass == 2 ? escn_debug_line_alt : escn_debug_line; - cc.escn_debug_info = pass == 0 ? escn_debug_info_alt + cc.escn_debug_info = pass == 2 ? escn_debug_info_alt : escn_debug_info; cc.escn_debug_types = escn_debug_types; cc.escn_debug_info_alt = escn_debug_info_alt; @@ -6161,6 +6093,99 @@ void new_dwarf3_reader_wrk ( } } +static Word search_one_subtab ( DebugInfo* di, UWord index ) +{ + Word mid, + lo = 0, + hi = di->subtab_used-1; + UWord mid_index; + while (True) { + /* current unsearched space is from lo to hi, inclusive. */ + if (lo > hi) return -1; /* not found */ + mid = (lo + hi) / 2; + mid_index = di->subtab[mid].index; + + if (mid_index > index) { hi = mid-1; continue; } + if (mid_index < index) { lo = mid+1; continue; } + vg_assert(index == mid_index); + return mid; + } +} + +/* Report an issue only once, we cannot really give too good an error + message since we don't know the exact DIE that was broken. + So only report once per DebugInfo file. */ +static void report_resolve_subprogram_issue (DebugInfo *di, const HChar *msg) +{ + static HChar *last_dbgname; + HChar *dbgname = di->fsm.dbgname ? di->fsm.dbgname : di->fsm.filename; + if (last_dbgname != dbgname) { + if (VG_(clo_verbosity) >= 1) + VG_(message)(Vg_DebugMsg, "Warning: %s in %s\n", msg, dbgname); + last_dbgname = dbgname; + } +} + +static void resolve_subprograms ( DebugInfo* di ) +{ + for (UWord i = 0; i < di->inltab_used; i++) { + Word s = di->inltab[i].inlined.subprog; + if (s == 0) { + report_resolve_subprogram_issue + (di, "zero subprog, missing DW_AT_abstract_origin in" + " DW_TAG_inlined_subroutine"); + di->inltab[i].inlined.fn = ML_(addStr)(di, "UnknownInlinedFun", -1); + continue; + } + s = search_one_subtab (di, di->inltab[i].inlined.subprog); + if (s == -1) { + report_resolve_subprogram_issue + (di, "subprog not found, DW_TAG_inlined_subroutine points to" + " unknown DW_TAG_subprogram"); + di->inltab[i].inlined.fn = ML_(addStr)(di, "UnknownInlinedFun", -1); + continue; + } + /* We allow two indirections, subprograms with abstract origins. */ + if (di->subtab[s].isSubprogRef) { + s = search_one_subtab (di, di->subtab[s].ref.subprog); + if (s == -1) { + report_resolve_subprogram_issue + (di, "subprog ref not found, DW_TAG_subprogram has an" + " unknown DW_AT_abstract_origin or DW_AT_specification"); + di->inltab[i].inlined.fn = ML_(addStr)(di, + "UnknownInlinedFun", -1); + continue; + } + } + if (di->subtab[s].isSubprogRef) { + s = search_one_subtab (di, di->subtab[s].ref.subprog); + if (s == -1) { + report_resolve_subprogram_issue + (di, "subprog ref to ref not found, DW_TAG_subprogram has an" + " unknown DW_AT_abstract_origin or DW_AT_specification"); + di->inltab[i].inlined.fn = ML_(addStr)(di, + "UnknownInlinedFun", -1); + continue; + } + } + if (di->subtab[s].isSubprogRef) + { + report_resolve_subprogram_issue + (di, "too many subprog indirections for DW_TAG_subprogram" + " with DW_AT_abstract_origin or DW_AT_specification refs"); + di->inltab[i].inlined.fn = ML_(addStr)(di, + "UnknownInlinedFun", -1); + continue; + } + di->inltab[i].inlined.fn = di->subtab[s].ref.fn; + } + + /* We don't need the SubPrograms anymore. */ + ML_(dinfo_free)(di->subtab); + di->subtab = NULL; + di->subtab_used = 0; + di->subtab_size = 0; +} /*------------------------------------------------------------*/ /*--- ---*/ @@ -6232,6 +6257,10 @@ ML_(new_dwarf3_reader) ( d3rd_jmpbuf_valid = False; d3rd_jmpbuf_reason = NULL; + + /* Always call this even after .debug_info reading failed, to make sure + any known inlined subroutine names are resolved and memory freed. */ + resolve_subprograms (di); } diff --git a/coregrind/m_debuginfo/storage.c b/coregrind/m_debuginfo/storage.c index 12ad681304..22fed6d4f0 100644 --- a/coregrind/m_debuginfo/storage.c +++ b/coregrind/m_debuginfo/storage.c @@ -11,6 +11,8 @@ Copyright (C) 2000-2017 Julian Seward js...@ac... + Copyright (C) 2025 Mark J. Wielaard + ma...@kl... This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as @@ -697,7 +699,7 @@ static void shrinkInlTab ( struct _DebugInfo* di ) /* Top-level place to call to add a addr-to-inlined fn info. */ void ML_(addInlInfo) ( struct _DebugInfo* di, Addr addr_lo, Addr addr_hi, - const HChar* inlinedfn, + UWord subprog, UInt fndn_ix, Int lineno, UShort level) { @@ -705,9 +707,9 @@ void ML_(addInlInfo) ( struct _DebugInfo* di, # define SHOWLINEINFO \ VG_(message) (Vg_DebugMsg, \ - "addInlInfo: fn %s inlined as addr_lo %#lx,addr_hi %#lx," \ + "addInlInfo: fn %lx inlined as addr_lo %#lx,addr_hi %#lx," \ "caller fndn_ix %u %s:%d\n", \ - inlinedfn, addr_lo, addr_hi, fndn_ix, \ + subprog, addr_lo, addr_hi, fndn_ix, \ ML_(fndn_ix2filename) (di, fndn_ix), lineno) /* Similar paranoia as in ML_(addLineInfo). Unclear if needed. */ @@ -737,7 +739,7 @@ void ML_(addInlInfo) ( struct _DebugInfo* di, // code resulting from inlining of inlinedfn: inl.addr_lo = addr_lo; inl.addr_hi = addr_hi; - inl.inlinedfn = inlinedfn; + inl.inlined.subprog = subprog; // caller: inl.fndn_ix = fndn_ix; inl.lineno = lineno; @@ -749,6 +751,29 @@ void ML_(addInlInfo) ( struct _DebugInfo* di, # undef SHOWLINEINFO } +void ML_(addSubprogram) ( struct _DebugInfo* di, DiSubprogram* sub ) +{ + UInt new_sz, i; + DiSubprogram* new_tab; + + if (di->subtab_used == di->subtab_size) { + new_sz = 2 * di->subtab_size; + if (new_sz == 0) new_sz = 2560; + new_tab = ML_(dinfo_zalloc)( "di.storage.addSubprogram.1", + new_sz * sizeof(DiSubprogram) ); + if (di->subtab != NULL) { + for (i = 0; i < di->subtab_used; i++) + new_tab[i] = di->subtab[i]; + ML_(dinfo_free)(di->subtab); + } + di->subtab = new_tab; + di->subtab_size = new_sz; + } + + di->subtab[di->subtab_used] = *sub; + di->subtab_used++; +} + DiCfSI_m* ML_(get_cfsi_m) (const DebugInfo* di, UInt pos) { UInt cfsi_m_ix; |