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
(19) |
Oct
|
Nov
|
Dec
|
|
From: Mark W. <ma...@kl...> - 2023-08-31 14:15:04
|
Hi Aaron, Hi Carl,
On Wed, Aug 30, 2023 at 03:48:20PM -0700, Carl Love via Valgrind-developers wrote:
> On Wed, 2023-08-30 at 15:09 -0400, Aaron Merey wrote:
> > Sorry for the delay. I'm currently away for the next couple
> > weeks, however I was able to take a look at these regressions.
Thanks. But don't feel you have to come back early just for this
technical issue. We might not be as quick as you, but we should be
able to figure it out :)
> > It looks like debuginfo is not always lazily loaded on ppc64le
> > since it's possible for neither describe_IP or find_DiCfSI to be
> > called before symtab lookups during stacktrace. describe_IP and
> > find_DiCfSI contain calls to lazily load debuginfo, so if they are
> > not called before stacktrace printing it results in missing
> > debuginfo and lower quality stacktraces.
> >
> > I've attached a patch that fixed the regressions for me when I
> > tested this on a ppc64le machine. It adds lazy debuginfo loading
> > during ppc get_StackTrace_wrk.
>
> Thanks for taking a look at the issue. I tested the patch an a variety
> of machines and get mixed results. Here is what I am seeing before the
> commit to add the lazy loading, with the current Valgrind mainline
> (includes the lazy commit) and with the patch to fix the lazy load on
> Power: [...]
It also doesn't seem to work for me on a power9 f38 system. Which is
surprising, since theoretically I think it should work. The
difference between ppc64le and other architectures is that all other
architectures use VG_(use_CF_info) for unwinding, which will
indirectly load the debuginfo for the pc. So explicitly loading it for
the pc in the ppc case should have worked, but it doesn't... :{
I'll keep poking if there is some other difference with the other
architectures.
Cheers,
Mark
|
|
From: Paul F. <pa...@so...> - 2023-08-31 11:44:46
|
https://sourceware.org/git/gitweb.cgi?p=valgrind.git;h=c934430d56c2add25002ea8e321bd8bdab80fc99 commit c934430d56c2add25002ea8e321bd8bdab80fc99 Author: Paul Floyd <pj...@wa...> Date: Thu Aug 31 15:32:21 2023 +0200 Bug 473870 - FreeBSD 14 applications fail early at startup FreeBSD recently started adding some functions using @gnu_indirect_function, specifically strpcmp which was causing this crash. When running and encountering this ifunc Valgrind looked for the ifunc_handler. But there wasn't one for FreeBSD so Valgrind asserted. Diff: --- NEWS | 1 + coregrind/vg_preloaded.c | 22 +++++++++++++++++++++- 2 files changed, 22 insertions(+), 1 deletion(-) diff --git a/NEWS b/NEWS index 96eb06af8a..519ed664c1 100644 --- a/NEWS +++ b/NEWS @@ -52,6 +52,7 @@ are not entered into bugzilla tend to get forgotten about or ignored. 472963 Broken regular expression in configure.ac 473604 Fix bug472219.c compile failure with Clang 16 473677 make check compile failure with Clang 16 based on GCC 13.x +473870 FreeBSD 14 applications fail early at startup n-i-bz Allow arguments with spaces in .valgrindrc files To see details of a given bug, visit diff --git a/coregrind/vg_preloaded.c b/coregrind/vg_preloaded.c index a792081b11..1c727966f3 100644 --- a/coregrind/vg_preloaded.c +++ b/coregrind/vg_preloaded.c @@ -238,7 +238,27 @@ void VG_REPLACE_FUNCTION_ZU(libSystemZdZaZddylib, arc4random_addrandom)(unsigned #elif defined(VGO_freebsd) -// nothing specific currently +#if (FREEBSD_VERS >= FREEBSD_14) + +void * VG_NOTIFY_ON_LOAD(ifunc_wrapper) (void); +void * VG_NOTIFY_ON_LOAD(ifunc_wrapper) (void) +{ + OrigFn fn; + Addr result = 0; + Addr fnentry; + + /* Call the original indirect function and get it's result */ + VALGRIND_GET_ORIG_FN(fn); + CALL_FN_W_v(result, fn); + + fnentry = result; + + VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ__ADD_IFUNC_TARGET, + fn.nraddr, fnentry, 0, 0, 0); + return (void*)result; +} + +#endif #elif defined(VGO_solaris) |
|
From: Carl L. <ce...@us...> - 2023-08-30 22:48:42
|
Aaron:
On Wed, 2023-08-30 at 15:09 -0400, Aaron Merey wrote:
> Hi Carl,
>
> Sorry for the delay. I'm currently away for the next couple weeks,
> however
> I was able to take a look at these regressions.
>
> It looks like debuginfo is not always lazily loaded on ppc64le since
> it's
> possible for neither describe_IP or find_DiCfSI to be called before
> symtab
> lookups during stacktrace. describe_IP and find_DiCfSI contain calls
> to lazily load debuginfo, so if they are not called before stacktrace
> printing
> it results in missing debuginfo and lower quality stacktraces.
>
> I've attached a patch that fixed the regressions for me when I tested
> this on
> a ppc64le machine. It adds lazy debuginfo loading during ppc
> get_StackTrace_wrk.
>
Thanks for taking a look at the issue. I tested the patch an a variety
of machines and get mixed results. Here is what I am seeing before the
commit to add the lazy loading, with the current Valgrind mainline
(includes the lazy commit) and with the patch to fix the lazy load on
Power:
machine pre-lazy-load current mainline with ppc debuginfo fix
Power 8 LE 707 tests, 708 tests, 708 tests
4 stderr failures, 280 stderr failures, 247 stderr failures,
0 stdout failures, 54 stdout failures, 54 stdout failures,
13 stderrB failures, 16 stderrB failures, 16 stderrB failures,
0 stdoutB failures, 11 stdoutB failures, 12 stdoutB failures
9 post failures 13 post failures 9 post failures
Power 8 BE 742 tests, 743 tests, 743 tests,
2 stderr failures, 671 stderr failures, 671 stderr failures,
0 stdout failures, 152 stdout failures, 152 stdout failures,
0 stderrB failures, 14 stderrB failures, 14 stderrB failures,
2 stdoutB failures, 20 stdoutB failures, 20 stdoutB failures,
9 post failures 43 post failures 43 post failures
Power 9 LE 711 tests, 712 tests, 712 tests,
4 stderr failures, 280 stderr failures, 247 stderr failures,
0 stdout failures, 54 stdout failures, 54 stdout failures,
13 stderrB failures, 16 stderrB failures, 16 stderrB failures,
0 stdoutB failures, 12 stdoutB failures, 12 stdoutB failures
9 post failures 13 post failures 9 post failures
Power 10 LE 719 tests 720 tests, 720 tests,
2 stderr failures, 42 stderr failures, 2 stderr failures,
0 stdout failures, 0 stdout failures, 0 stdout failures,
2 stderrB failures, 2 stderrB failures, 2 stderrB failures,
10 stdoutB failures, 10 stdoutB failures, 10 stdoutB failures,
0 post failures 3 post failures 0 post failures
So the patch has mixed results in fixing the issue. It feels like
there is still a timing issue to me. Perhaps there needs to be a check
to see if the lazy load has completed before the use? Just throwing
out ideas here.
Anyway, sounds like you are out of the office for awhile. I am fine
with waiting until you are back to work on this some more. No need to
mess up you time off. I don't think there is a release coming soon so
I think we have some time to get this fixed up.
Thanks for the help with the initial patch fix.
Carl
|
|
From: Aaron M. <am...@re...> - 2023-08-30 19:10:08
|
Hi Carl, Sorry for the delay. I'm currently away for the next couple weeks, however I was able to take a look at these regressions. It looks like debuginfo is not always lazily loaded on ppc64le since it's possible for neither describe_IP or find_DiCfSI to be called before symtab lookups during stacktrace. describe_IP and find_DiCfSI contain calls to lazily load debuginfo, so if they are not called before stacktrace printing it results in missing debuginfo and lower quality stacktraces. I've attached a patch that fixed the regressions for me when I tested this on a ppc64le machine. It adds lazy debuginfo loading during ppc get_StackTrace_wrk. Aaron On Tue, Aug 29, 2023 at 3:15 PM Carl Love <ce...@us...> wrote: > > Mark, Paul, Aaron: > > On Sun, 2023-08-27 at 17:36 +0200, Mark Wielaard wrote: > > Hi Paul, > > > > On Sat, Aug 26, 2023 at 06:26:29AM +0200, Paul Floyd wrote: > > > I was just looking at valgrind-testresults and there was a jump in > > > the number of failures on ppc64le on Aug 17th, just after the > > > deferred debuginfo reading change. > > > > > > One random example > > > > > > ================================================= > > > ./valgrind-old/drd/tests/tc16_byterace.stderr.diff > > > ================================================= > > > --- tc16_byterace.stderr.exp 2023-08-17 03:01:09.168107928 +0000 > > > +++ tc16_byterace.stderr.out 2023-08-17 03:28:20.030515805 +0000 > > > @@ -1,8 +1,7 @@ > > > > > > Conflicting load by thread 1 at 0x........ size 1 > > > at 0x........: main (tc16_byterace.c:34) > > > -Location 0x........ is 0 bytes inside bytes[4], > > > -a global variable declared at tc16_byterace.c:7 > > > +Allocation context: BSS section of tc16_byterace > > > > > > It does look to me like this is a debuginfo issue. > > > > You are correct, this was caused by: > > > > commit 60f7e89ba32b54d73b9e36d49e28d0f559ade0b9 > > Author: Aaron Merey <am...@re...> > > Date: Fri Jun 30 18:31:42 2023 -0400 > > > > Support lazy reading and downloading of DWARF debuginfo > > > > That commit shouldn't have been architecture specific, but it > > apparently was. I put some early analysis into the bug > > > > https://bugs.kde.org/show_bug.cgi?id=471807#c16 > > > > The patch depends on a call to find_DiCfSI triggering a full > > debuginfo load. > > find_DiCfSI is (indirectly called) when ML_(get_CFA) is called. > > It looks like ppc64le doesn't call ML_(get_CFA) because we have the > > following in > > coregrind/m_debuginfo/d3basics.c > > > > #if defined(VGP_ppc32_linux) || defined(VGP_ppc64be_linux) \ > > || defined(VGP_ppc64le_linux) > > /* Valgrind on ppc32/ppc64 currently doesn't use unwind > > info. */ > > uw1 = ML_(read_Addr)((UChar*)regs->sp); > > #else > > uw1 = ML_(get_CFA)(regs->ip, regs->sp, regs->fp, 0, > > ~(UWord) 0); > > #endif > > I verified that the patch from Aaron causes regression failures on > Power 9 and Power 10. Per the comment above, not sure why PowerPC does > not support the get_CFA call? Unfortunately, I don't know much about > callgrind or the debuginfo stuff. Not obvious to me at first glance > how to fix the issue. > > I would be happy to help test a patch or work on a patch if someone has > specific suggestions on how to fix the issue on PowerPC. > > Carl > |
|
From: Mark W. <ma...@kl...> - 2023-08-30 08:16:21
|
Sourceware infrastructure community updates for Q3 2023 - Sourceware 25 Roadmap - git source code integrity - inbox.sourceware.org vs HTML email - Continuous glibc src and manual snapshots - Conservancy BBB server for Sourceware projects - Working on individual tech sovereignty together - Sourceware Overseers Open Office hour = Sourceware 25 Roadmap Preparing Sourceware for the next 25 years. In the last couple of years we have started to diversify our hardware partners, setup new services using containers and isolated VMs, investigated secure supply chain issues, added redundant mirrors, created a non-profit home, collected funds, invested in open communication, open office hours and introduced community oversight by a Sourceware Project Leadership Committee with the help from the Software Freedom Conservancy. https://sourceware.org/sourceware-25-roadmap.html = git source code integrity. gitsigur for protecting git repo integrity. With comparisons, developer workflow examples and composition possibilities for gitsigur, b4 and sigstore. https://inbox.sourceware.org/ZJ3Tihvu6GbOb8%2F...@el.../ Sourceware now also allows signed git pushes (in addition to signed git commits). = inbox.sourceware.org vs HTML email HTML email. Most Sourceware projects allow it, if there is at least a text/plain alternative. But public-inbox is not so forgiving, it only allows plain-text emails, HTML is rejected by default. So the https://inbox.sourceware.org archive was incomplete. We now have a filter that removes redundant HTML parts before storing in public-inbox. And we re-imported missing emails to make the archive complete. But please don't sent HTML email. It will make DKIM verification of your email impossible. = Continuous glibc src and manual snapshots glibc is the latest Sourceware project that provides continuous snapshots from current git with both source archives and manuals. https://snapshots.sourceware.org This helps to make sure the release process always works and that manuals can be produced in various formats. Thanks to OSUOSL for hosting the snapshots server. = Conservancy BBB server for Sourceware projects The Software Freedom Conservancy is extending the use of their Big Blue Button instance https://bbb.sfconservancy.org/ to Sourceware projects that want to host video meetings. https://sfconservancy.org/news/2023/aug/15/exit-zoom/ Please contact ove...@so... for instructions on how to create an account for your project. Note: Anyone is able to join a meeting, accounts are only required to create new meetings. = Working on individual tech sovereignty together Valgrind was picked for a FUTO https://futo.org Microgrant, which has been donated to Sourceware through the Software Freedom Conservancy for maintaining and expanding the infrastructure for Valgrind and other core toolchain and developer tool projects. https://www.youtube.com/watch?v=aYzzOfQehPg If you want to donate to Sourceware please see https://sfconservancy.org/donate and become a Conservancy Sustainer or give directly by mentioning Sourceware as comment or on the memo line. = Sourceware Overseers Open Office hour Every second Friday of the month is the Sourceware Overseers Open Office hour in #overseers on irc.libera.chat from 18:00 till 19:00 UTC. The next one will be Friday September 4th. Please feel free to drop by with any Sourceware services and hosting questions. Feedback and questions about the Sourceware 25 Roadmap are also very appreciated. https://sourceware.org/sourceware-25-roadmap.html Of course you are welcome to drop into the #overseers channel at any time and we can also be reached through email and bugzilla: https://sourceware.org/mission.html#organization If you aren't already and want to keep up to date on Sourceware infrastructure services then please also subscribe to the overseers mailinglist. https://sourceware.org/mailman/listinfo/overseers We are also on the fediverse these days: https://fosstodon.org/@sourceware The Sourceware Project Leadership Committee also meets once a month to discuss all community input. The committee will set priorities and decide how to spend any funds, negotiate with hardware and service partners, create budgets together with the Conservancy, or decide when a new fundraising campaign is needed. Up till now we have been able to add new services without needing to use any of the collected funds. Our hardware partners have also been very generous with providing extra servers when requested. The current committee includes Frank Ch. Eigler, Christopher Faylor, Ian Kelling, Ian Lance Taylor, Tom Tromey, Jon Turney, Mark J. Wielaard and Elena Zannoni. |
|
From: Paul F. <pa...@so...> - 2023-08-30 06:06:32
|
https://sourceware.org/git/gitweb.cgi?p=valgrind.git;h=acf2c99ec39f3301e51152b1e78156616e8d6129 commit acf2c99ec39f3301e51152b1e78156616e8d6129 Author: Paul Floyd <pj...@wa...> Date: Wed Aug 30 08:06:00 2023 +0200 FreeBSD: a bit of cleanup of README.freebsd Diff: --- README.freebsd | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/README.freebsd b/README.freebsd index d197efcaf3..eb6a510ada 100644 --- a/README.freebsd +++ b/README.freebsd @@ -14,7 +14,7 @@ cd /usr/ports/devel/valgrind && make install clean Building Valgrind ~~~~~~~~~~~~~~~~~ -Install ports for autoconf, automake, libtool and gmake. +Install ports for autotools, gmake and python. $ sh autogen.sh $ ./configure --prefix=/where/ever @@ -137,13 +137,13 @@ the following packages gdb gsed -In addition to running "make" you will need to run -"make check" to build the regression test exectutables -and "make regtest". Again, more details can be seen in +In addition to running "gmake" you will need to run +"gmake check" to build the regression test exectutables +and "gmake regtest". Again, more details can be seen in README_DEVELOPERS. If you want to run the 'nightly' script (see nightly/README.txt) -you will need to install coreutils and modify the +you will need to install gcp and coreutils and modify the nightly/conf/freebsd.* files. The default configuration sends an e-mail to the valgrind-testresults mailing list. |
|
From: Carl L. <ce...@us...> - 2023-08-29 19:15:52
|
Mark, Paul, Aaron: On Sun, 2023-08-27 at 17:36 +0200, Mark Wielaard wrote: > Hi Paul, > > On Sat, Aug 26, 2023 at 06:26:29AM +0200, Paul Floyd wrote: > > I was just looking at valgrind-testresults and there was a jump in > > the number of failures on ppc64le on Aug 17th, just after the > > deferred debuginfo reading change. > > > > One random example > > > > ================================================= > > ./valgrind-old/drd/tests/tc16_byterace.stderr.diff > > ================================================= > > --- tc16_byterace.stderr.exp 2023-08-17 03:01:09.168107928 +0000 > > +++ tc16_byterace.stderr.out 2023-08-17 03:28:20.030515805 +0000 > > @@ -1,8 +1,7 @@ > > > > Conflicting load by thread 1 at 0x........ size 1 > > at 0x........: main (tc16_byterace.c:34) > > -Location 0x........ is 0 bytes inside bytes[4], > > -a global variable declared at tc16_byterace.c:7 > > +Allocation context: BSS section of tc16_byterace > > > > It does look to me like this is a debuginfo issue. > > You are correct, this was caused by: > > commit 60f7e89ba32b54d73b9e36d49e28d0f559ade0b9 > Author: Aaron Merey <am...@re...> > Date: Fri Jun 30 18:31:42 2023 -0400 > > Support lazy reading and downloading of DWARF debuginfo > > That commit shouldn't have been architecture specific, but it > apparently was. I put some early analysis into the bug > > https://bugs.kde.org/show_bug.cgi?id=471807#c16 > > The patch depends on a call to find_DiCfSI triggering a full > debuginfo load. > find_DiCfSI is (indirectly called) when ML_(get_CFA) is called. > It looks like ppc64le doesn't call ML_(get_CFA) because we have the > following in > coregrind/m_debuginfo/d3basics.c > > #if defined(VGP_ppc32_linux) || defined(VGP_ppc64be_linux) \ > || defined(VGP_ppc64le_linux) > /* Valgrind on ppc32/ppc64 currently doesn't use unwind > info. */ > uw1 = ML_(read_Addr)((UChar*)regs->sp); > #else > uw1 = ML_(get_CFA)(regs->ip, regs->sp, regs->fp, 0, > ~(UWord) 0); > #endif I verified that the patch from Aaron causes regression failures on Power 9 and Power 10. Per the comment above, not sure why PowerPC does not support the get_CFA call? Unfortunately, I don't know much about callgrind or the debuginfo stuff. Not obvious to me at first glance how to fix the issue. I would be happy to help test a patch or work on a patch if someone has specific suggestions on how to fix the issue on PowerPC. Carl |
|
From: Jojo R <rj...@gm...> - 2023-08-29 07:47:14
|
Hi, We are glad to open source RVV implementation here again: https://github.com/rjiejie/valgrind-riscv64 4 kinds extra ISAs were added in this repo: RV64Zfh : Half-precision floating-point RV64Xthead [1] : T-THEAD vendor extension for RV64G RV64V0p7 [2] : Vector 0.7.1 RV64V [3] : Vector 1.0 [1] https://github.com/T-head-Semi/thead-extension-spec [2] https://github.com/riscv/riscv-v-spec/releases/tag/0.7.1 [3] https://github.com/riscv/riscv-v-spec/releases/tag/v1.0 Regards --Jojo 在 2023/7/17 15:05, Jojo R 写道: > > Hi, > > Sorry for the late reply, > > i have been pushing the progress of valgrind RVV implementation 😄 > We finished the first version and tested with full RVV intrinsics spec. > > For real project and developers, we implement the first useable/ full > functionality's RVV valgrind with dirtycall method, > and we will make experiment or optimize RVV implementation on ideal > RVV design. > > Back to the RVV RFC, we are happy to share our thinking of design, see > attachment for more details :) > > Regards > > --Jojo > > 在 2023/4/21 17:25, Jojo R 写道: >> >> Hi, >> >> We consider to add RVV/Vector [1] feature in valgrind, there are some >> challenges. >> RVV like ARM's SVE [2] programming model, it's scalable/VLA, that >> means the vector length is agnostic. >> ARM's SVE is not supported in valgrind :( >> >> There are three major issues in implementing RVV instruction set in >> Valgrind as following: >> >> 1. Scalable vector register width VLENB >> 2. Runtime changing property of LMUL and SEW >> 3. Lack of proper VEX IR to represent all vector operations >> >> We propose applicable methods to solve 1 and 2. As for 3, we explore >> several possible but maybe imperfect approaches to handle different >> cases. >> >> We start from 1. As each guest register should be described in >> VEXGuestState struct, the vector registers with scalable width of >> VLENB can be added into VEXGuestState as arrays using an allowable >> maximum length like 2048/4096. >> >> The actual available access range can be determined at Valgrind >> startup time by querying the CPU for its vector capability or some >> suitable setup steps. >> >> >> To solve problem 2, we are inspired by already-proven techniques in >> QEMU, where translation blocks are broken up when certain critical >> CSRs are set. Because the guest code to IR translation relies on the >> precise value of LMUL/SEW and they may change within a basic block, >> we can break up the basic block each time encountering a vsetvl{i} >> instruction and return to the scheduler to execute the translated >> code and update LMUL/SEW. Accordingly, translation cache management >> should be refactored to detect the changing of LMUL/SEW to invalidate >> outdated code cache. Without losing the generality, the LMUL/SEW >> should be encoded into an ULong flag such that other architectures >> can leverage this flag to store their arch-dependent information. The >> TTentry struct should also take the flag into account no matter >> insertion or deletion. By doing this, the flag carries the newest >> LMUL/SEW throughout the simulation and can be passed to disassemble >> functions using the VEXArchInfo struct such that we can get the real >> and newest value of LMUL and SEW to facilitate our translation. >> >> Also, some architecture-related code should be taken care of. Like >> m_dispatch part, disp_cp_xindir function looks up code cache using >> hardcoded assembly by checking the requested guest state IP and >> translation cache entry address with no more constraints. Many other >> modules should be checked to ensure the in-time update of LMUL/SEW is >> instantly visible to essential parts in Valgrind. >> >> >> The last remaining big issue is 3, which we introduce some ad-hoc >> approaches to deal with. We summarize these approaches into three >> types as following: >> >> 1. Break down a vector instruction to scalar VEX IR ops. >> 2. Break down a vector instruction to fixed-length VEX IR ops. >> 3. Use dirty helpers to realize vector instructions. >> >> The very first method theoretically exists but is probably not >> applicable as the number of IR ops explodes when a large VLENB is >> adopted. Imaging a configuration of VLENB=512, SEW=8, LMUL=8, the VL >> is 512 * 8 / 8 = 512, meaning that a single vector instruction turns >> into 512 scalar instructions and each scalar instruction would be >> expanded to multiple IRs. To make things worse, the tool >> instrumentation will insert more IRs between adjacent scalar IR ops. >> As a result, the performance is likely to be slowed down thousand >> times during running a real-world application with lots of vector >> instructions. Therefore, the other two methods are more promising and >> we will discuss them below. >> >> 2 and 3 are not mutually exclusive as we may choose a suitable method >> from them to implement a vector instruction regarding its concrete >> behavior. To explain these methods in detail, we present some >> instances to illustrate their pros and cons. >> >> In terms of method 2, we have real values of VLENB/LMUL/SEW. The >> simple case is VLENB <= 256 and LMUL=1, where many SIMD IR ops are >> available and can be directly applied to represent vector operations. >> However, even when VLENB is restricted to 128, it still exceeds the >> maximum SIMD width of 256 supported by VEX IR if LMUL>2. Hence, here >> are two variants of method 2 to deal with long vectors: >> >> >> *2.1*Add more SIMD IR ops such as 1024/2048/4096, and translate >> vector instructions in the granularity of VLENB. Accordingly, >> VLENB=4096 with LMUL=2 is fulfilled by two 4096 SIMD VEX IR ops. >> >> * *pros*: it encourages VEX backend to generate more compact and >> efficient SIMD code (maybe). Particularly,it accommodatesmask and >> gather/scatter (indexed) instructions by delivering more >> information in IR itself. >> * *cons*: too many new IR ops need to be introduced in VEX as each >> op of different length should implement its add/sub/mul variants. >> New data types to denote long vectors are necessary too, causing >> difficulties in both VEX backend register allocation and tool >> instrumentation. >> >> *2.2*Break down long vectors to multiple repeated SIMD ops. For >> instance, a vadd.vv vector instruction with VLENB=256/LMUL=2/SEW=8 is >> composed of four operators of Iop_Add8x16 type. >> >> * *pros:*less efforts are required in register allocation and tool >> instrumentation. The VEX frontend is able to notify the backend >> to generate efficient vector instructions by existing Iops. It >> better trades off the complexity of adding many long vector IR >> ops and the benefit of generating high-efficiency host code. >> * *cons:*it is hard to describe a mask operation given that the >> mask is pretty flexible (the least significant bit of each >> segment of v0). Additionally, gather/scatter instructions may >> have similar problems in appropriately dividing index registers. >> There are various corner cases left here such as widening >> arithmetic operations (widening SIMD IR ops are currently not >> compatible) and vstart CSR register. When using fixed-length IR >> ops to comprise a vector instruction, we will inevitably tell >> each IR op which position encoded in vstart you can start to >> process the data. We can use vstart as a normal guest state >> virtual register to calculate each op's start position as a guard >> IRExpr or obtain the value of vstart like what we do in LMUL/SEW. >> Nevertheless, it is non-trivial to decompose a vector instruction >> concisely. >> >> In short, both 2.1 and 2.2 confront a dilemma in reducing engineering >> efforts of refactoring Valgrind elegantly as well as implementing the >> vector instruction set efficiently. Same obstacles exist in ARM SVE >> as they are scalable vector instructions and flexible in many ways. >> >> The final solution is the dirty helper. It is undoubtedly practical >> and requires possibly the least engineering efforts in dealing with >> so many details in Valgrind. In this design, each instruction is >> completed using an inline assembly running the same instruction on >> the host. Moreover, tool instrumentation already handles IRDirty >> except that new fields should be added in _IRDirty struct to indicate >> strided/indexed/masked memory accesses and arithmetic operations. >> >> * *pros:*it supports all instructions without bothering to build >> complicated IR expressions and statements. It executes vector >> instructions using host CPU to get acceleration to some extent. >> Besides, we do not need to add VEX backend to translate new IRs >> to vector instructions. >> * *cons:*the dirty helper always keeps its operations in a black >> box such that tools can never see what happens in a dirty helper. >> Like memcheck, the bit precision merit is missing once it meets a >> dirty helper as the V-bit propagation chain adopts a pretty >> coarse determination strategy. On the other hand, it is also not >> an elegant way to implement the entire ISA extension in dirty >> helpers. >> >> In summary, it is far to reach a truly applicable solution in adding >> vector extensions in Valgrind. We need to do detailed and >> comprehensive estimations on different vector instruction categories. >> >> Any feedback is welcome in github [3] also. >> >> >> [1] https://github.com/riscv/riscv-v-spec >> >> [2] >> https://community.arm.com/arm-research/b/articles/posts/the-arm-scalable-vector-extension-sve >> >> [3] https://github.com/petrpavlu/valgrind-riscv64/issues/17 >> >> >> Thanks. >> >> Jojo >> >> >> >> _______________________________________________ >> Valgrind-developers mailing list >> Val...@li... >> https://lists.sourceforge.net/lists/listinfo/valgrind-developers > > > _______________________________________________ > Valgrind-developers mailing list > Val...@li... > https://lists.sourceforge.net/lists/listinfo/valgrind-developers |
|
From: Paul F. <pa...@so...> - 2023-08-29 05:56:47
|
https://sourceware.org/git/gitweb.cgi?p=valgrind.git;h=69ac8e03a2e22175337acf999f8c8814143ba08a commit 69ac8e03a2e22175337acf999f8c8814143ba08a Author: Paul Floyd <pj...@wa...> Date: Tue Aug 29 07:55:31 2023 +0200 FreeBSD: add memcheck suppression for libc newlocale still reachable memory Diff: --- freebsd.supp | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/freebsd.supp b/freebsd.supp index 10d4a10454..471fbe6fd3 100644 --- a/freebsd.supp +++ b/freebsd.supp @@ -43,12 +43,21 @@ fun:posix_fallocate } { - MEMCHECK-LIBX-REACHABLE-2 + MEMCHECK-LIBC-REACHABLE-2 Memcheck:Leak match-leak-kinds: reachable fun:malloc - obj:/lib/libc.so.7 - obj:/lib/libc.so.7 - obj:/lib/libc.so.7 + obj:*/lib*/libc.so.7 + obj:*/lib*/libc.so.7 + obj:*/lib*/libc.so.7 fun:fwrite } +# when calling std::locale::facet::_S_create_c_locale +{ + MEMCHECK-LIBC-REACHABLE-3 + Memcheck:Leak + match-leak-kinds: reachable + fun:calloc + ... + fun:newlocale +} |
|
From: Paul F. <pa...@so...> - 2023-08-27 16:03:37
|
https://sourceware.org/git/gitweb.cgi?p=valgrind.git;h=5b43a08b64d2038e384bdcc229dfac3b826ae32a commit 5b43a08b64d2038e384bdcc229dfac3b826ae32a Author: Paul Floyd <pj...@wa...> Date: Sun Aug 27 18:03:07 2023 +0200 Linux: remove a couple of cpmpiler warnings Diff: --- massif/tests/Makefile.am | 2 +- memcheck/tests/realloc_size_zero.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/massif/tests/Makefile.am b/massif/tests/Makefile.am index cc79beceb4..f8deeb5766 100644 --- a/massif/tests/Makefile.am +++ b/massif/tests/Makefile.am @@ -91,7 +91,7 @@ AM_CXXFLAGS += $(AM_FLAG_M3264_PRI) bug469146_SOURCES = bug469146.cpp # -fno-optimize-sibling-calls because otherwise some platforms will have # tail call optimization which messes up --ignore-fn -bug469146_CXXFLAGS = $(AM_CXXFLAGS) -O2 -fno-optimize-sibling-calls +bug469146_CXXFLAGS = $(AM_CXXFLAGS) -O2 -fno-optimize-sibling-calls @FLAG_W_NO_USE_AFTER_FREE@ new_cpp_SOURCES = new-cpp.cpp overloaded_new_SOURCES = overloaded-new.cpp # pre C++11 compilers don't have exception specs diff --git a/memcheck/tests/realloc_size_zero.c b/memcheck/tests/realloc_size_zero.c index c9d8e74777..3e25d85a61 100644 --- a/memcheck/tests/realloc_size_zero.c +++ b/memcheck/tests/realloc_size_zero.c @@ -22,7 +22,7 @@ int main(void) } errno = 0; - volatile void *ptr = NULL; + void *ptr = NULL; volatile size_t size = 0U; char *p2 = realloc(ptr, size); if (p2) { |
|
From: Mark W. <ma...@kl...> - 2023-08-27 15:47:00
|
Hi Paul, On Tue, Aug 22, 2023 at 03:58:26PM +0200, Floyd, Paul wrote: > On 22/08/2023 15:16, Mark Wielaard wrote: > >There are a couple of larger features that could use more people to > >take a look: > > > >- AVX-512 support, incomplete and we lost contact with the original > > developer:https://bugs.kde.org/show_bug.cgi?id=383010 > >- Risc-V port, seems to have a dedicated developers: > > https://bugs.kde.org/show_bug.cgi?id=468575 > > There also is active development to extend it with > > Vector Register support > >https://sourceforge.net/p/valgrind/mailman/valgrind-developers/thread/20230526135944.1959407-5-fei2.wu%40intel.com/ > >- Loongarch64 port, seems pretty complete, split out in 40 commits: > > https://bugs.kde.org/show_bug.cgi?id=457504 > > > >Unfortunately I cannot promise to have time before October to look at > >all of these. So if others could take a look and report on status that > >would be great. > > Do we have any contacts at Intel (or AMD) for help with AVX512? I don't have any, but I'll ask around. > My wishlist for the October release of 3.22 includes all of the above plus > > * get at least one dev each for RISC-V and Loongson on board with > sourceware git write access in order to be able to support the > platforms directly And hopefully nightly test results and/or buildbot builders. > * the long running question of what to do with macOS Any testers/developers/volunteers? > * memcheck aligned and sized checks plus maybe c23 free_sized and > free_sized_aligned plus Linux aligned_alloc > > * detect whether a debug version of libstdc++ is being used and then > use that to automatically turn on or off mismatch detection That is an interesting idea. > And I expect the usual steady stream of smaller fixes. On irc we also discussed having a "rolling release branch" where we put small/essential bug fixes (some of which some distros now backport themselves). Cheers, Mark |
|
From: Mark W. <ma...@kl...> - 2023-08-27 15:36:24
|
Hi Paul,
On Sat, Aug 26, 2023 at 06:26:29AM +0200, Paul Floyd wrote:
> I was just looking at valgrind-testresults and there was a jump in
> the number of failures on ppc64le on Aug 17th, just after the
> deferred debuginfo reading change.
>
> One random example
>
> =================================================
> ./valgrind-old/drd/tests/tc16_byterace.stderr.diff
> =================================================
> --- tc16_byterace.stderr.exp 2023-08-17 03:01:09.168107928 +0000
> +++ tc16_byterace.stderr.out 2023-08-17 03:28:20.030515805 +0000
> @@ -1,8 +1,7 @@
>
> Conflicting load by thread 1 at 0x........ size 1
> at 0x........: main (tc16_byterace.c:34)
> -Location 0x........ is 0 bytes inside bytes[4],
> -a global variable declared at tc16_byterace.c:7
> +Allocation context: BSS section of tc16_byterace
>
> It does look to me like this is a debuginfo issue.
You are correct, this was caused by:
commit 60f7e89ba32b54d73b9e36d49e28d0f559ade0b9
Author: Aaron Merey <am...@re...>
Date: Fri Jun 30 18:31:42 2023 -0400
Support lazy reading and downloading of DWARF debuginfo
That commit shouldn't have been architecture specific, but it
apparently was. I put some early analysis into the bug
https://bugs.kde.org/show_bug.cgi?id=471807#c16
The patch depends on a call to find_DiCfSI triggering a full debuginfo load.
find_DiCfSI is (indirectly called) when ML_(get_CFA) is called.
It looks like ppc64le doesn't call ML_(get_CFA) because we have the following in
coregrind/m_debuginfo/d3basics.c
#if defined(VGP_ppc32_linux) || defined(VGP_ppc64be_linux) \
|| defined(VGP_ppc64le_linux)
/* Valgrind on ppc32/ppc64 currently doesn't use unwind info. */
uw1 = ML_(read_Addr)((UChar*)regs->sp);
#else
uw1 = ML_(get_CFA)(regs->ip, regs->sp, regs->fp, 0, ~(UWord) 0);
#endif
Cheers,
Mark
|
|
From: Paul F. <pa...@so...> - 2023-08-27 15:28:33
|
https://sourceware.org/git/gitweb.cgi?p=valgrind.git;h=5190d4110540bfb56623efac30a27f4c3f258f10 commit 5190d4110540bfb56623efac30a27f4c3f258f10 Author: Paul Floyd <pj...@wa...> Date: Sun Aug 27 17:27:57 2023 +0200 FreeBSD: remove testing code Diff: --- coregrind/m_syswrap/syswrap-freebsd.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/coregrind/m_syswrap/syswrap-freebsd.c b/coregrind/m_syswrap/syswrap-freebsd.c index 17abf132b6..a9a77c3f45 100644 --- a/coregrind/m_syswrap/syswrap-freebsd.c +++ b/coregrind/m_syswrap/syswrap-freebsd.c @@ -4695,7 +4695,7 @@ POST(sys__umtx_op) case VKI_UMTX_OP_SHM: case VKI_UMTX_OP_ROBUST_LISTS: break; -#if (FREEBSD_VERS >= FREEBSD_14 || 1) +#if (FREEBSD_VERS >= FREEBSD_14) case VKI_UMTX_OP_GET_MIN_TIMEOUT: POST_MEM_WRITE( ARG4, sizeof(long int) ); break; |
|
From: Paul F. <pa...@so...> - 2023-08-27 14:46:20
|
https://sourceware.org/git/gitweb.cgi?p=valgrind.git;h=6beec0455645e23f98f8c8c8237391bfc0cc4e46 commit 6beec0455645e23f98f8c8c8237391bfc0cc4e46 Author: Paul Floyd <pj...@wa...> Date: Sun Aug 27 18:45:03 2023 +0200 FreeBSD: add an extra libc filter for _start in massif deep-D test Diff: --- tests/filter_libc | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/filter_libc b/tests/filter_libc index 4f097903a3..bf035701c1 100755 --- a/tests/filter_libc +++ b/tests/filter_libc @@ -23,6 +23,7 @@ while (<>) # libc on x86 FreeBSD s#_start1 \(src/lib/csu/i386/crt1_c.c.*#(below main)#; + s#__libc_start1 \(in /...libc...\)#(below main)#; # filter out the exact libc-start.c:### line number. (ppc64*) s/\(libc-start.c:[0-9]*\)$/(in \/...libc...)/; |
|
From: Paul F. <pa...@so...> - 2023-08-27 14:33:29
|
https://sourceware.org/git/gitweb.cgi?p=valgrind.git;h=8ca6ecb1d9b26cea21cd3ed91f2277b860d3d572 commit 8ca6ecb1d9b26cea21cd3ed91f2277b860d3d572 Author: Paul Floyd <pj...@wa...> Date: Sun Aug 27 18:33:03 2023 +0200 Remove merge file added by mistake Diff: --- coregrind/m_syswrap/syswrap-freebsd.c.orig | 7418 ---------------------------- 1 file changed, 7418 deletions(-) diff --git a/coregrind/m_syswrap/syswrap-freebsd.c.orig b/coregrind/m_syswrap/syswrap-freebsd.c.orig deleted file mode 100644 index a59872b3c9..0000000000 --- a/coregrind/m_syswrap/syswrap-freebsd.c.orig +++ /dev/null @@ -1,7418 +0,0 @@ -/*--------------------------------------------------------------------*/ -/*--- FreeBSD-specific syscalls, etc. syswrap-freebsd.c ---*/ -/*--------------------------------------------------------------------*/ - -/* - This file is part of Valgrind, a dynamic binary instrumentation - framework. - - Copyright (C) 2000-2008 Nicholas Nethercote - nj...@va... - Copyright (C) 2018-2021 Paul Floyd - pj...@wa... - - This program is free software; you can redistribute it and/or - modify it under the terms of the GNU General Public License as - published by the Free Software Foundation; either version 2 of the - License, or (at your option) any later version. - - This program is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, see <http://www.gnu.org/licenses/>. - - The GNU General Public License is contained in the file COPYING. -*/ - -#if defined(VGO_freebsd) - -#include "pub_core_basics.h" -#include "pub_core_vki.h" -#include "pub_core_vkiscnums.h" -#include "pub_core_threadstate.h" -#include "pub_core_aspacemgr.h" -#include "pub_core_debuginfo.h" // VG_(di_notify_*) -#include "pub_core_transtab.h" // VG_(discard_translations) -#include "pub_core_xarray.h" -#include "pub_core_clientstate.h" -#include "pub_core_debuglog.h" -#include "pub_core_libcbase.h" -#include "pub_core_libcassert.h" -#include "pub_core_libcfile.h" -#include "pub_core_libcprint.h" -#include "pub_core_libcproc.h" -#include "pub_core_libcsignal.h" -#include "pub_core_machine.h" -#include "pub_core_mallocfree.h" -#include "pub_core_tooliface.h" -#include "pub_core_options.h" -#include "pub_core_scheduler.h" -#include "pub_core_signals.h" -#include "pub_core_stacks.h" -#include "pub_core_syscall.h" -#include "pub_core_syswrap.h" -#include "pub_core_inner.h" -#include "pub_core_pathscan.h" -#if defined(ENABLE_INNER_CLIENT_REQUEST) -#include "pub_core_clreq.h" -#endif - -#include "priv_types_n_macros.h" -#include "priv_syswrap-generic.h" -#include "priv_syswrap-main.h" -#include "priv_syswrap-freebsd.h" - -static Bool capabiltyMode = False; - -Bool VG_(get_capability_mode)(void) -{ - return capabiltyMode; -} - - -// Run a thread from beginning to end and return the thread's -// scheduler-return-code. -static VgSchedReturnCode thread_wrapper(Word /*ThreadId*/ tidW) -{ - VgSchedReturnCode ret; - ThreadId tid = (ThreadId)tidW; - Int lwpid = VG_(gettid)(); - ThreadState* tst = VG_(get_ThreadState)(tid); - - VG_(debugLog)(1, "syswrap-freebsd", - "thread_wrapper(tid=%u,lwpid=%d): entry\n", - tid, lwpid); - - vg_assert(tst->status == VgTs_Init); - - /* make sure we get the CPU lock before doing anything significant */ - VG_(acquire_BigLock)(tid, "thread_wrapper(starting new thread)"); - - if (0) { - VG_(printf)("thread tid %u started: stack = %p\n", - tid, (void*)&tid); - } - - /* Make sure error reporting is enabled in the new thread. */ - tst->err_disablement_level = 0; - - VG_TRACK(pre_thread_first_insn, tid); - - tst->os_state.lwpid = lwpid; - /* Set the threadgroup for real. This overwrites the provisional value set - in do_clone(). See comments in do_clone for background, also #226116. */ - tst->os_state.threadgroup = VG_(getpid)(); - - /* Thread created with all signals blocked; scheduler will set the - appropriate mask */ - - ret = VG_(scheduler)(tid); - - vg_assert(VG_(is_exiting)(tid)); - - vg_assert(tst->status == VgTs_Runnable); - vg_assert(VG_(is_running_thread)(tid)); - - VG_(debugLog)(1, "syswrap-freebsd", - "thread_wrapper(tid=%u,lwpid=%d): exit, schedreturncode %s\n", - tid, lwpid, VG_(name_of_VgSchedReturnCode)(ret)); - - /* Return to caller, still holding the lock. */ - return ret; -} - - -/* --------------------------------------------------------------------- - clone-related stuff - ------------------------------------------------------------------ */ - -/* Run a thread all the way to the end, then do appropriate exit actions - (this is the last-one-out-turn-off-the-lights bit). */ -__attribute__((noreturn)) -static void run_a_thread_NORETURN ( Word tidW ) -{ - ThreadId tid = (ThreadId)tidW; - VgSchedReturnCode src; - Int c; - ThreadState* tst; -#ifdef ENABLE_INNER_CLIENT_REQUEST - Int registered_vgstack_id; -#endif - - VG_(debugLog)(1, "syswrap-freebsd", - "run_a_thread_NORETURN(tid=%u): pre-thread_wrapper\n", - tid); - - tst = VG_(get_ThreadState)(tid); - vg_assert(tst); - - /* An thread has two stacks: - * the simulated stack (used by the synthetic cpu. Guest process - is using this stack). - * the valgrind stack (used by the real cpu. Valgrind code is running - on this stack). - When Valgrind runs as an inner, it must signals that its (real) stack - is the stack to use by the outer to e.g. do stacktraces. - */ - INNER_REQUEST - (registered_vgstack_id - = VALGRIND_STACK_REGISTER (tst->os_state.valgrind_stack_base, - tst->os_state.valgrind_stack_init_SP)); - - /* Run the thread all the way through. */ - src = thread_wrapper(tid); - - VG_(debugLog)(1, "syswrap-freebsd", - "run_a_thread_NORETURN(tid=%u): post-thread_wrapper\n", - tid); - - c = VG_(count_living_threads)(); - vg_assert(c >= 1); /* stay sane */ - - /* Deregister thread's stack. */ - if (tst->os_state.stk_id != NULL_STK_ID) { - VG_(deregister_stack)(tst->os_state.stk_id); - } - - // Tell the tool this thread is exiting - VG_TRACK( pre_thread_ll_exit, tid ); - - /* If the thread is exiting with errors disabled, complain loudly; - doing so is bad (does the user know this has happened?) Also, - in all cases, be paranoid and clear the flag anyway so that the - thread slot is safe in this respect if later reallocated. This - should be unnecessary since the flag should be cleared when the - slot is reallocated, in thread_wrapper(). */ - if (tst->err_disablement_level > 0) { - VG_(umsg)( - "WARNING: exiting thread has error reporting disabled.\n" - "WARNING: possibly as a result of some mistake in the use\n" - "WARNING: of the VALGRIND_DISABLE_ERROR_REPORTING macros.\n" - ); - VG_(debugLog)( - 1, "syswrap-freebsd", - "run_a_thread_NORETURN(tid=%u): " - "WARNING: exiting thread has err_disablement_level = %u\n", - tid, tst->err_disablement_level - ); - } - tst->err_disablement_level = 0; - - if (c == 1) { - - VG_(debugLog)(1, "syswrap-freebsd", - "run_a_thread_NORETURN(tid=%u): " - "last one standing\n", - tid); - - /* We are the last one standing. Keep hold of the lock and - carry on to show final tool results, then exit the entire system. - Use the continuation pointer set at startup in m_main. */ - ( * VG_(address_of_m_main_shutdown_actions_NORETURN) ) (tid, src); - } else { - - VG_(debugLog)(1, "syswrap-freebsd", - "run_a_thread_NORETURN(tid=%u): " - "not last one standing\n", - tid); - - /* OK, thread is dead, but others still exist. Just exit. */ - - /* This releases the run lock */ - VG_(exit_thread)(tid); - vg_assert(tst->status == VgTs_Zombie); - vg_assert(sizeof(tst->status) == 4); - vg_assert(sizeof(tst->os_state.exitcode) == sizeof(Word)); - - INNER_REQUEST (VALGRIND_STACK_DEREGISTER (registered_vgstack_id)); - - /* We have to use this sequence to terminate the thread to - prevent a subtle race. If VG_(exit_thread)() had left the - ThreadState as Empty, then it could have been reallocated, - reusing the stack while we're doing these last cleanups. - Instead, VG_(exit_thread) leaves it as Zombie to prevent - reallocation. We need to make sure we don't touch the stack - between marking it Empty and exiting. Hence the - assembler. */ -#if defined(VGP_x86_freebsd) /* FreeBSD has args on the stack */ - __asm__ volatile ( - "movl %1, %0\n" /* set tst->status = VgTs_Empty */ - "movl %2, %%eax\n" /* set %eax = __NR_thr_exit */ - "movl %3, %%ebx\n" /* set %ebx = tst->os_state.exitcode */ - "pushl %%ebx\n" /* arg on stack */ - "pushl %%ebx\n" /* fake return address */ - "int $0x80\n" /* thr_exit(tst->os_state.exitcode) */ - "popl %%ebx\n" /* fake return address */ - "popl %%ebx\n" /* arg off stack */ - : "=m" (tst->status) - : "n" (VgTs_Empty), "n" (__NR_thr_exit), "m" (tst->os_state.exitcode) - : "eax", "ebx" - ); -#elif defined(VGP_amd64_freebsd) - __asm__ volatile ( - "movl %1, %0\n" /* set tst->status = VgTs_Empty */ - "movq %2, %%rax\n" /* set %rax = __NR_thr_exit */ - "movq %3, %%rdi\n" /* set %rdi = tst->os_state.exitcode */ - "pushq %%rdi\n" /* fake return address */ - "syscall\n" /* thr_exit(tst->os_state.exitcode) */ - "popq %%rdi\n" /* fake return address */ - : "=m" (tst->status) - : "n" (VgTs_Empty), "n" (__NR_thr_exit), "m" (tst->os_state.exitcode) - : "rax", "rdi" - ); -#else -# error Unknown platform -#endif - - VG_(core_panic)("Thread exit failed?\n"); - } - - /*NOTREACHED*/ - vg_assert(0); -} - -Word ML_(start_thread_NORETURN) ( void* arg ) -{ - ThreadState* tst = (ThreadState*)arg; - ThreadId tid = tst->tid; - - run_a_thread_NORETURN ( (Word)tid ); - /*NOTREACHED*/ - vg_assert(0); -} - -/* Allocate a stack for this thread, if it doesn't already have one. - They're allocated lazily, and never freed. Returns the initial stack - pointer value to use, or 0 if allocation failed. */ -Addr ML_(allocstack)(ThreadId tid) -{ - ThreadState* tst = VG_(get_ThreadState)(tid); - VgStack* stack; - Addr initial_SP; - - /* Either the stack_base and stack_init_SP are both zero (in which - case a stack hasn't been allocated) or they are both non-zero, - in which case it has. */ - - if (tst->os_state.valgrind_stack_base == 0) { - vg_assert(tst->os_state.valgrind_stack_init_SP == 0); - } - - if (tst->os_state.valgrind_stack_base != 0) { - vg_assert(tst->os_state.valgrind_stack_init_SP != 0); - } - - /* If no stack is present, allocate one. */ - - if (tst->os_state.valgrind_stack_base == 0) { - stack = VG_(am_alloc_VgStack)( &initial_SP ); - if (stack) { - tst->os_state.valgrind_stack_base = (Addr)stack; - tst->os_state.valgrind_stack_init_SP = initial_SP; - } - } - - if (0) { - VG_(printf)( "stack for tid %u at %p; init_SP=%p\n", - tid, - (void*)tst->os_state.valgrind_stack_base, - (void*)tst->os_state.valgrind_stack_init_SP ); - } - - return tst->os_state.valgrind_stack_init_SP; -} - -/* Allocate a stack for the main thread, and run it all the way to the - end. Although we already have a working VgStack - (VG_(interim_stack)) it's better to allocate a new one, so that - overflow detection works uniformly for all threads. -*/ -__attribute__((noreturn)) -void VG_(main_thread_wrapper_NORETURN)(ThreadId tid) -{ - Addr sp; - VG_(debugLog)(1, "syswrap-freebsd", - "entering VG_(main_thread_wrapper_NORETURN)\n"); - - sp = ML_(allocstack)(tid); -#if defined(ENABLE_INNER_CLIENT_REQUEST) - { - // we must register the main thread stack before the call - // to ML_(call_on_new_stack_0_1), otherwise the outer valgrind - // reports 'write error' on the non registered stack. - ThreadState* tst = VG_(get_ThreadState)(tid); - INNER_REQUEST - ((void) - VALGRIND_STACK_REGISTER (tst->os_state.valgrind_stack_base, - tst->os_state.valgrind_stack_init_SP)); - } -#endif - - /* If we can't even allocate the first thread's stack, we're hosed. - Give up. */ - vg_assert2(sp != 0, "%s", "Cannot allocate main thread's stack."); - - /* shouldn't be any other threads around yet */ - vg_assert( VG_(count_living_threads)() == 1 ); - - ML_(call_on_new_stack_0_1)( - (Addr)sp, /* stack */ - 0, /* bogus return address */ - run_a_thread_NORETURN, /* fn to call */ - (Word)tid /* arg to give it */ - ); - - /*NOTREACHED*/ - vg_assert(0); -} - - -/* Do a fork() */ -SysRes ML_(do_fork) ( ThreadId tid ) -{ - vki_sigset_t fork_saved_mask; - vki_sigset_t mask; - SysRes res; - - /* Block all signals during fork, so that we can fix things up in - the child without being interrupted. */ - VG_(sigfillset)(&mask); - VG_(sigprocmask)(VKI_SIG_SETMASK, &mask, &fork_saved_mask); - - VG_(do_atfork_pre)(tid); - - res = VG_(do_syscall0)( __NR_fork ); - - if (!sr_isError(res)) { - if (sr_Res(res) == 0) { - /* child */ - VG_(do_atfork_child)(tid); - - /* restore signal mask */ - VG_(sigprocmask)(VKI_SIG_SETMASK, &fork_saved_mask, NULL); - - } else { - /* parent */ - VG_(do_atfork_parent)(tid); - - if (VG_(clo_trace_syscalls)) { - VG_(printf)(" clone(fork): process %d created child %lu\n", - VG_(getpid)(), sr_Res(res)); - } - - /* restore signal mask */ - VG_(sigprocmask)(VKI_SIG_SETMASK, &fork_saved_mask, NULL); - } - } - - return res; -} - -static Addr ML_(make_safe_mask) ( const HChar* malloc_message, Addr mask_pointer ) -{ - vki_sigset_t* new_mask; - const vki_sigset_t* old_mask = (vki_sigset_t *)mask_pointer; - - if (!ML_(safe_to_deref)(old_mask, sizeof(vki_sigset_t))) { - new_mask = (vki_sigset_t*)1; /* Something recognisable to POST() hook. */ - } else { - new_mask = VG_(malloc)(malloc_message, sizeof(vki_sigset_t)); - *new_mask = *old_mask; - VG_(sanitize_client_sigmask)(new_mask); - } - - return (Addr)new_mask; -} - -static void ML_(free_safe_mask) ( Addr mask_pointer ) -{ - if (mask_pointer != 0 && mask_pointer != 1) { - VG_(free)((vki_sigset_t *) mask_pointer); - } -} - - -/* --------------------------------------------------------------------- - PRE/POST wrappers for arch-generic, FreeBSD-specific syscalls - ------------------------------------------------------------------ */ - -// Nb: See the comment above the generic PRE/POST wrappers in -// m_syswrap/syswrap-generic.c for notes about how they work. - -#define PRE(name) DEFN_PRE_TEMPLATE(freebsd, name) -#define POST(name) DEFN_POST_TEMPLATE(freebsd, name) - -/* On FreeBSD, if any thread calls exit(2), then they are all shut down, pretty - * much like linux's exit_group(). - */ -// SYS_exit 1 -// void exit(int status); -PRE(sys_exit) -{ - ThreadId t; - - PRINT("exit( %" FMT_REGWORD "u )", ARG1); - PRE_REG_READ1(void, "exit", int, status); - - /* Mark all threads (including this one) to exit. */ - for (t = 1; t < VG_N_THREADS; t++) { - if ( /* not alive */ VG_(threads)[t].status == VgTs_Empty ) { - continue; - } - - //VG_(threads)[t].exitreason = VgSrc_ExitThread; - VG_(threads)[t].os_state.exitcode = ARG1; - - // if (t != tid) - // VG_(get_thread_out_of_syscall)(t); /* unblock it, if blocked */ - } - - VG_(nuke_all_threads_except)( tid, VgSrc_ExitProcess ); - VG_(reap_threads)(tid); - VG_(threads)[tid].exitreason = VgSrc_ExitThread; - - /* We have to claim the syscall already succeeded. */ - SET_STATUS_Success(0); -} - -// SYS_fork 2 -// pid_t fork(void); -PRE(sys_fork) -{ - PRINT("%s", "sys_fork ()"); - PRE_REG_READ0(pid_t, "fork"); - - SET_STATUS_from_SysRes( ML_(do_fork)(tid) ); - if (SUCCESS) { - /* Thread creation was successful; let the child have the chance - to run */ - *flags |= SfYieldAfter; - } -} - -// SYS_read 3 -// generic - -// SYS_write 4 -// generic - -// SYS_open 5 -// generic - -// SYS_close 6 -// generic - -// SYS_wait4 7 -// generic - -// SYS_link 9 -// generic - -// SYS_unlink 10 -// generic - -// SYS_chdir 12 - -// SYS_fchdir 13 -// generic - -// SYS_freebsd11_mknod 14 -// generic - -// SYS_chmod 15 -// generic - -// SYS_chown 16 -// generic - -// SYS_break 17 -// generic - -// SYS_getpid 20 -// generic - -// SYS_mount 21 -// int mount(const char *type, const char *dir, int flags, void *data); -PRE(sys_mount) -{ - // Nb: depending on 'flags', the 'type' and 'data' args may be ignored. - // We are conservative and check everything, except the memory pointed to - // by 'data'. - *flags |= SfMayBlock; - PRINT( "sys_mount( %#" FMT_REGWORD "x, %#" FMT_REGWORD "x, %" FMT_REGWORD "u, %#" FMT_REGWORD "x )",ARG1,ARG2,ARG3,ARG4); - PRE_REG_READ4(int, "mount", - const char *, type, char *, dir, int, flags, - void *, data); - PRE_MEM_RASCIIZ( "mount(type)", ARG1); - PRE_MEM_RASCIIZ( "mount(path)", ARG2); -} - -// SYS_unmount 22 -// int unmount(const char *dir, int flags); -PRE(sys_unmount) -{ - PRINT("sys_umount( %#" FMT_REGWORD "x, %" FMT_REGWORD "u )", ARG1, ARG2); - PRE_REG_READ2(int, "unmount", const char *, dir, int, flags); - PRE_MEM_RASCIIZ( "unmount(path)", ARG1); -} - -// SYS_setuid 23 -// generic - -// SYS_getuid 24 -// generic - -// SYS_geteuid 25 -// generic - -// SYS_ptrace 26 -// int ptrace(int request, pid_t pid, caddr_t addr, int data); -PRE(sys_ptrace) -{ - struct vki_ptrace_io_desc *io_desc; - PRINT("sys_ptrace ( %" FMT_REGWORD "u, %" FMT_REGWORD "u, 0x%" FMT_REGWORD "x, %" FMT_REGWORD "u)", ARG1, ARG2, ARG3, ARG4); - - PRE_REG_READ4(int, "ptrace", int, request, pid_t, pid, caddr_t, addr, int, data); - - switch (ARG1) { - case VKI_PTRACE_TRACEME: - case VKI_PTRACE_READ_I: - case VKI_PTRACE_READ_D: - case VKI_PTRACE_WRITE_I: - case VKI_PTRACE_WRITE_D: - break; - - case VKI_PTRACE_IO: - PRE_MEM_READ("ptrace", ARG3, sizeof(struct vki_ptrace_io_desc)); - io_desc = (struct vki_ptrace_io_desc *)ARG3; - switch (io_desc->piod_op) { - case VKI_PIOD_READ_D: - case VKI_PIOD_READ_I: - PRE_MEM_WRITE( "ptrace", (UWord)io_desc->piod_addr, io_desc->piod_len); - break; - case VKI_PIOD_WRITE_D: - case VKI_PIOD_WRITE_I: - PRE_MEM_READ( "ptrace", (UWord)io_desc->piod_addr, io_desc->piod_len); - break; - } - break; - - case VKI_PTRACE_CONTINUE: - case VKI_PTRACE_STEP: - case VKI_PTRACE_KILL: - case VKI_PTRACE_ATTACH: - case VKI_PTRACE_DETACH: - break; - - case VKI_PTRACE_GETREGS: - PRE_MEM_WRITE("ptrace", ARG3, sizeof(struct vki_user_regs_struct)); - break; - - case VKI_PTRACE_SETREGS: - PRE_MEM_READ("ptrace", ARG3, sizeof(struct vki_user_regs_struct)); - break; - - case VKI_PTRACE_GETFPREGS: - PRE_MEM_WRITE("ptrace", ARG3, sizeof(struct vki_fpreg)); - break; - - case VKI_PTRACE_SETFPREGS: - PRE_MEM_READ("ptrace", ARG3, sizeof(struct vki_fpreg)); - break; - - case VKI_PTRACE_GETDBREGS: - PRE_MEM_WRITE("ptrace", ARG3, sizeof(struct vki_dbreg)); - break; - - case VKI_PTRACE_SETDBREGS: - PRE_MEM_READ("ptrace", ARG3, sizeof(struct vki_dbreg)); - break; - - case VKI_PTRACE_LWPINFO: - PRE_MEM_WRITE("ptrace", ARG3, sizeof(struct vki_ptrace_lwpinfo)); - break; - - case VKI_PTRACE_GETNUMLWPS: - break; - - case VKI_PTRACE_GETLWPLIST: - PRE_MEM_WRITE( "ptrace", ARG3, sizeof(vki_lwpid_t) * ARG4); - break; - - case VKI_PTRACE_SETSTEP: - case VKI_PTRACE_CLEARSTEP: - case VKI_PTRACE_SUSPEND: - case VKI_PTRACE_RESUME: - case VKI_PTRACE_TO_SCE: - case VKI_PTRACE_TO_SCX: - case VKI_PTRACE_SYSCALL: - case VKI_PTRACE_VM_TIMESTAMP: - break; - case VKI_PTRACE_VM_ENTRY: - PRE_MEM_WRITE( "ptrace", ARG3, sizeof(struct vki_ptrace_vm_entry)); - break; - } -} - -POST(sys_ptrace) -{ - struct vki_ptrace_io_desc *io_desc; - - switch (ARG1) { - case VKI_PTRACE_TRACEME: - case VKI_PTRACE_READ_I: - case VKI_PTRACE_READ_D: - case VKI_PTRACE_WRITE_I: - case VKI_PTRACE_WRITE_D: - break; - - case VKI_PTRACE_IO: - io_desc = (struct vki_ptrace_io_desc *)ARG3; - switch (io_desc->piod_op) { - case VKI_PIOD_READ_D: - case VKI_PIOD_READ_I: - if ((Word)RES != -1) { - POST_MEM_WRITE((UWord)io_desc->piod_addr, io_desc->piod_len); - } - break; - case VKI_PIOD_WRITE_D: - case VKI_PIOD_WRITE_I: - break; - } - break; - - case VKI_PTRACE_CONTINUE: - case VKI_PTRACE_STEP: - case VKI_PTRACE_KILL: - case VKI_PTRACE_ATTACH: - case VKI_PTRACE_DETACH: - break; - - case VKI_PTRACE_GETREGS: - if ((Word)RES != -1) { - POST_MEM_WRITE(ARG3, sizeof(struct vki_user_regs_struct)); - } - break; - - case VKI_PTRACE_SETREGS: - break; - - case VKI_PTRACE_GETFPREGS: - if ((Word)RES != -1) { - POST_MEM_WRITE(ARG3, sizeof(struct vki_fpreg)); - } - break; - - case VKI_PTRACE_SETFPREGS: - break; - - case VKI_PTRACE_GETDBREGS: - if ((Word)RES != -1) { - POST_MEM_WRITE(ARG3, sizeof(struct vki_dbreg)); - } - break; - - case VKI_PTRACE_SETDBREGS: - break; - - case VKI_PTRACE_LWPINFO: - if ((Word)RES != -1) { - POST_MEM_WRITE(ARG3, sizeof(struct vki_ptrace_lwpinfo)); - } - break; - - case VKI_PTRACE_GETNUMLWPS: - break; - - case VKI_PTRACE_GETLWPLIST: - if ((Word)RES != -1) { - POST_MEM_WRITE(ARG3, sizeof(vki_lwpid_t) * RES); - } - break; - - case VKI_PTRACE_SETSTEP: - case VKI_PTRACE_CLEARSTEP: - case VKI_PTRACE_SUSPEND: - case VKI_PTRACE_RESUME: - case VKI_PTRACE_TO_SCE: - case VKI_PTRACE_TO_SCX: - case VKI_PTRACE_SYSCALL: - case VKI_PTRACE_VM_TIMESTAMP: - break; - - case VKI_PTRACE_VM_ENTRY: - if ((Word)RES != -1) { - POST_MEM_WRITE(ARG3, sizeof(struct vki_ptrace_vm_entry)); - } - break; - } -} - -// SYS_recvmsg 27 -// ssize_t recvmsg(int s, struct msghdr *msg, int flags); -PRE(sys_recvmsg) -{ - *flags |= SfMayBlock; - PRINT("sys_recvmsg ( %" FMT_REGWORD "d, %#" FMT_REGWORD "x, %" FMT_REGWORD "d )",SARG1,ARG2,SARG3); - PRE_REG_READ3(vki_ssize_t, "recvmsg", int, s, struct msghdr *, msg, int, flags); - ML_(generic_PRE_sys_recvmsg)(tid, "recvmsg", (struct vki_msghdr *)ARG2); -} - -POST(sys_recvmsg) -{ - - ML_(generic_POST_sys_recvmsg)(tid, "recvmsg", (struct vki_msghdr *)ARG2, RES); -} - -// SYS_sendmsg 28 -// ssize_t sendmsg(int s, const struct msghdr *msg, int flags); -PRE(sys_sendmsg) -{ - *flags |= SfMayBlock; - PRINT("sys_sendmsg ( %" FMT_REGWORD "u, %#" FMT_REGWORD "x, %" FMT_REGWORD "u )",ARG1,ARG2,ARG3); - PRE_REG_READ3(ssize_t, "sendmsg", - int, s, const struct msghdr *, msg, int, flags); - ML_(generic_PRE_sys_sendmsg)(tid, "sendmsg", (struct vki_msghdr *)ARG2); -} - -// SYS_recvfrom 29 -// ssize_t recvfrom(int s, void *buf, size_t len, int flags, -// struct sockaddr * restrict from, socklen_t * restrict fromlen); -PRE(sys_recvfrom) -{ - *flags |= SfMayBlock; - PRINT("sys_recvfrom ( %" FMT_REGWORD "d, %#" FMT_REGWORD "x, %" FMT_REGWORD "u, %" FMT_REGWORD "d, %#" FMT_REGWORD "x, %#" FMT_REGWORD "x )",SARG1,ARG2,ARG3,SARG4,ARG5,ARG6); - PRE_REG_READ6(ssize_t, "recvfrom", - int, s, void *, buf, size_t, len, int, flags, - struct sockaddr *, from, int *, fromlen); - ML_(generic_PRE_sys_recvfrom)(tid, ARG1,ARG2,ARG3,ARG4,ARG5,ARG6); -} - -POST(sys_recvfrom) -{ - vg_assert(SUCCESS); - ML_(generic_POST_sys_recvfrom)(tid, VG_(mk_SysRes_Success)(RES), - ARG1,ARG2,ARG3,ARG4,ARG5,ARG6); -} - -// SYS_accept 30 -// int accept(int s, struct sockaddr * restrict addr, -// socklen_t * restrict addrlen); -PRE(sys_accept) -{ - *flags |= SfMayBlock; - PRINT("sys_accept ( %" FMT_REGWORD "u, %#" FMT_REGWORD "x, %" FMT_REGWORD "u )",ARG1,ARG2,ARG3); - PRE_REG_READ3(int, "accept", - int, s, struct sockaddr *, addr, int, *addrlen); - ML_(generic_PRE_sys_accept)(tid, ARG1,ARG2,ARG3); -} - -POST(sys_accept) -{ - SysRes r; - vg_assert(SUCCESS); - r = ML_(generic_POST_sys_accept)(tid, VG_(mk_SysRes_Success)(RES), - ARG1,ARG2,ARG3); - SET_STATUS_from_SysRes(r); -} - -// SYS_getpeername 31 -// int getpeername(int s, struct sockaddr * restrict name, -// socklen_t * restrict namelen); -PRE(sys_getpeername) -{ - PRINT("sys_getpeername ( %" FMT_REGWORD "u, %#" FMT_REGWORD "x, %#" FMT_REGWORD "x )",ARG1,ARG2,ARG3); - PRE_REG_READ3(int, "getpeername", - int, s, struct sockaddr *, name, socklen_t *, namelen); - ML_(generic_PRE_sys_getpeername)(tid, ARG1,ARG2,ARG3); -} - -POST(sys_getpeername) -{ - vg_assert(SUCCESS); - ML_(generic_POST_sys_getpeername)(tid, VG_(mk_SysRes_Success)(RES), - ARG1,ARG2,ARG3); -} - -// SYS_getsockname 32 -// int getsockname(int s, struct sockaddr * restrict name, -// socklen_t * restrict namelen); -PRE(sys_getsockname) -{ - PRINT("sys_getsockname ( %" FMT_REGWORD "d, %#" FMT_REGWORD "x, %#" FMT_REGWORD "x )",SARG1,ARG2,ARG3); - PRE_REG_READ3(long, "getsockname", - int, s, struct sockaddr *, name, int *, namelen); - ML_(generic_PRE_sys_getsockname)(tid, ARG1,ARG2,ARG3); -} - -POST(sys_getsockname) -{ - vg_assert(SUCCESS); - ML_(generic_POST_sys_getsockname)(tid, VG_(mk_SysRes_Success)(RES), - ARG1,ARG2,ARG3); -} - -// SYS_access 33 -// generic - -// SYS_chflags 34 -// int chflags(const char *path, unsigned long flags) -PRE(sys_chflags) -{ - PRINT("sys_chflags ( %#" FMT_REGWORD "x(%s), 0x%" FMT_REGWORD "x )", ARG1,(char *)ARG1,ARG2); - PRE_REG_READ2(int, "chflags", - const char *, path, unsigned long, flags); - PRE_MEM_RASCIIZ( "chflags(path)", ARG1 ); -} - -// SYS_fchflags 35 -// int fchflags(int fd, unsigned long flags); -PRE(sys_fchflags) -{ - PRINT("sys_fchflags ( %" FMT_REGWORD "u, %" FMT_REGWORD "u )", ARG1,ARG2); - PRE_REG_READ2(int, "fchflags", int, fd, unsigned long, flags); -} - -// SYS_sync 36 -// generic - -// SYS_kill 37 -// generic - -// SYS_getppid 39 -// generic - -// SYS_dup 41 -// generic - -// Pipe on freebsd doesn't have args, and uses dual returns! -// SYS_freebsd10_pipe 42 -// int pipe(void); -PRE(sys_pipe) -{ - PRINT("%s", "sys_pipe ()"); -} - -POST(sys_pipe) -{ - if (!ML_(fd_allowed)(RES, "pipe", tid, True) || - !ML_(fd_allowed)(RESHI, "pipe", tid, True)) { - VG_(close)(RES); - VG_(close)(RESHI); - SET_STATUS_Failure( VKI_EMFILE ); - } else { - if (VG_(clo_track_fds)) { - ML_(record_fd_open_nameless)(tid, RES); - ML_(record_fd_open_nameless)(tid, RESHI); - } - } -} - -// SYS_getegid 43 -// generic - -// SYS_profil 44 -// generic - -// SYS_ktrace 45 -// generic - -// SYS_getgid 47 -// generic - -// SYS_getlogin 49 -// syscall.master refers to namelen and namebuf for the argument names -// man getlogin has just getlogin(void) but also -// int getlogin_r(char *name, int len); -// so let's go with those names -PRE(sys_getlogin) -{ - PRINT("sys_getlogin ( %#" FMT_REGWORD "x, %" FMT_REGWORD "u )",ARG1,ARG2); - PRE_REG_READ2(int, "getlogin", char *, buf, u_int, len); - PRE_MEM_WRITE( "getlogin(name)", ARG1, ARG2 ); -} - -POST(sys_getlogin) -{ - POST_MEM_WRITE(ARG1, ARG2 ); -} - -// SYS_setlogin 50 -// int setlogin(const char *name); -PRE(sys_setlogin) -{ - PRINT("sys_setlogin ( %#" FMT_REGWORD "x )",ARG1); - PRE_REG_READ1(long, "setlogin", char *, buf); - PRE_MEM_RASCIIZ( "setlogin(buf)", ARG1 ); -} - -// SYS_acct 51 -// generic - -// SYS_sigaltstack 53 -// generic - -// SYS_ioctl 54 -// int ioctl(int fd, unsigned long request, ...); -PRE(sys_ioctl) -{ - UInt dir = _VKI_IOC_DIR(ARG2); - UInt size = _VKI_IOC_SIZE(ARG2); - *flags |= SfMayBlock; - // @todo PJF presumably the presence of ARG3 depends on ARG2 - PRINT("sys_ioctl ( %" FMT_REGWORD "u, 0x%" FMT_REGWORD "x, %#" FMT_REGWORD "x )",ARG1,ARG2,ARG3); - PRE_REG_READ3(int, "ioctl", - int, fd, unsigned long, request, unsigned long, arg); - - /* On FreeBSD, ALL ioctl's are IOR/IOW encoded. Just use the default decoder */ - if (SimHintiS(SimHint_lax_ioctls, VG_(clo_sim_hints))) { - /* - * Be very lax about ioctl handling; the only - * assumption is that the size is correct. Doesn't - * require the full buffer to be initialized when - * writing. Without this, using some device - * drivers with a large number of strange ioctl - * commands becomes very tiresome. - */ - } else if (dir == _VKI_IOC_NONE && size > 0) { - static UWord unknown_ioctl[10]; - static Int moans = sizeof(unknown_ioctl) / sizeof(unknown_ioctl[0]); - if (moans > 0 && !VG_(clo_xml)) { - /* Check if have not already moaned for this request. */ - UInt i; - for (i = 0; i < sizeof(unknown_ioctl)/sizeof(unknown_ioctl[0]); i++) { - if (unknown_ioctl[i] == ARG2) { - break; - } - if (unknown_ioctl[i] == 0) { - unknown_ioctl[i] = ARG2; - moans--; - VG_(umsg)("Warning: noted but unhandled ioctl 0x%lx" - " with no direction hints.\n", ARG2); - VG_(umsg)(" This could cause spurious value errors to appear.\n"); - VG_(umsg)(" See README_MISSING_SYSCALL_OR_IOCTL for " - "guidance on writing a proper wrapper.\n" ); - return; - } - } - } - } else { - if ((dir & _VKI_IOC_WRITE) && size > 0) { - PRE_MEM_READ( "ioctl(generic)", ARG3, size); - } - if ((dir & _VKI_IOC_READ) && size > 0) { - PRE_MEM_WRITE( "ioctl(generic)", ARG3, size); - } - } - - // The block below is from Ryan Stone - // https://bitbucket.org/rysto32/valgrind-freebsd/commits/5323c22be9f6c71a00e842c3ddfa1fa8a7feb279 - // however it drags in hundreds of lines of headers into vki-freebsd.h. - // How stable are these structures? -> maintainability is a concern - // Also there are no testcases for this. - // Hence #if 0 -#if 0 - /* Handle specific ioctls which pass structures which may have pointers to other - buffers */ - switch (ARG2 /* request */) { - case VKI_SIOCGIFMEDIA: - if (ARG3) { - struct vki_ifmediareq* imr = (struct vki_ifmediareq*)ARG3; - if (imr->ifm_ulist) { - PRE_MEM_WRITE("ioctl(SIOCGIFMEDIA).ifm_ulist", - (Addr)(imr->ifm_ulist), imr->ifm_count * sizeof(int)); - } - } - break; - - case VKI_PCIOCGETCONF: - if (ARG3) { - struct vki_pci_conf_io* pci = (struct vki_pci_conf_io*)ARG3; - PRE_MEM_READ("ioctl(PCIOCGETCONF).patterns", - (Addr)(pci->patterns), pci->pat_buf_len); - PRE_MEM_WRITE("ioctl(PCIOCGETCONF).matches", - (Addr)(pci->matches), pci->match_buf_len); - } - break; - - case VKI_CAMIOCOMMAND: - if (ARG3) { - union vki_ccb* ccb = (union vki_ccb*)ARG3; - if (ccb->ccb_h.func_code == VKI_XPT_DEV_MATCH) { - PRE_MEM_WRITE("ioctl(CAMIOCOMMAND:XPT_DEV_MATCH).matches", - (Addr)(ccb->cdm.matches), ccb->cdm.match_buf_len); - } else if (ccb->ccb_h.func_code == VKI_XPT_SCSI_IO) { - struct vki_ccb_scsiio* scsiio = (struct vki_ccb_scsiio*)ccb; - if (scsiio->dxfer_len) { - if ((scsiio->ccb_h.flags & VKI_CAM_DIR_MASK) == VKI_CAM_DIR_IN) { - PRE_MEM_WRITE("ioctl(CAMIOCOMMAND:XPT_SCSI_IO).data_ptr", - (Addr)(scsiio->data_ptr), scsiio->dxfer_len); - } else if ((scsiio->ccb_h.flags & VKI_CAM_DIR_MASK) == VKI_CAM_DIR_OUT) { - PRE_MEM_READ("ioctl(CAMIOCOMMAND:XPT_SCSI_IO).data_ptr", - (Addr)(scsiio->data_ptr), scsiio->dxfer_len); - } - } - } else if (ccb->ccb_h.func_code == VKI_XPT_GDEV_TYPE || - ccb->ccb_h.func_code == VKI_XPT_PATH_INQ || - ccb->ccb_h.func_code == VKI_XPT_GET_TRAN_SETTINGS) { - // do nothing - } else { - VG_(message)(Vg_UserMsg, - "Warning: unhandled ioctl CAMIOCOMMAND function 0x%lx\n", - ccb->ccb_h.func_code); - } - } - break; - } -#endif -} - -POST(sys_ioctl) -{ - UInt dir = _VKI_IOC_DIR(ARG2); - UInt size = _VKI_IOC_SIZE(ARG2); - vg_assert(SUCCESS); - if (size > 0 && (dir & _VKI_IOC_READ) - && RES == 0 && ARG3 != (Addr)NULL) { - POST_MEM_WRITE(ARG3, size); - } - -#if 0 - /* Handle specific ioctls which pass structures which may have pointers to other - buffers */ - switch (ARG2 /* request */) { - case VKI_SIOCGIFMEDIA: - if (ARG3) { - struct vki_ifmediareq* imr = (struct vki_ifmediareq*)ARG3; - if (imr->ifm_ulist) { - POST_MEM_WRITE((Addr)(imr->ifm_ulist), imr->ifm_count * sizeof(int)); - } - } - break; - - case VKI_PCIOCGETCONF: - if (ARG3) { - struct vki_pci_conf_io* pci = (struct vki_pci_conf_io*)ARG3; - POST_MEM_WRITE((Addr)(pci->matches), pci->num_matches * sizeof(struct vki_pci_conf)); - } - break; - - case VKI_CAMIOCOMMAND: - if (ARG3) { - union vki_ccb* ccb = (union vki_ccb*)ARG3; - if (ccb->ccb_h.func_code == VKI_XPT_DEV_MATCH) { - POST_MEM_WRITE((Addr)(ccb->cdm.matches), ccb->cdm.num_matches*sizeof(struct vki_dev_match_result)); - } else if (ccb->ccb_h.func_code == VKI_XPT_SCSI_IO) { - struct vki_ccb_scsiio* scsiio = (struct vki_ccb_scsiio*)ccb; - if (scsiio->dxfer_len) { - if ((scsiio->ccb_h.flags & VKI_CAM_DIR_MASK) == VKI_CAM_DIR_IN) { - POST_MEM_WRITE((Addr)(scsiio->data_ptr), scsiio->dxfer_len); - } - } - } - } - break; - } -#endif -} - -// SYS_reboot 55 -// int reboot(int howto); -PRE(sys_reboot) -{ - PRINT("sys_reboot ( %" FMT_REGWORD "d )", SARG1); - PRE_REG_READ1(int, "reboot", int, howto); -} - -// SYS_revoke 56 -// int revoke(const char *path); -PRE(sys_revoke) -{ - PRINT("sys_revoke ( %#" FMT_REGWORD "x(%s) )", ARG1, (char*)ARG1); - PRE_REG_READ1(long, "revoke", const char *, path); - PRE_MEM_RASCIIZ( "revoke(path)", ARG1); -} - -// SYS_symlink 57 -// generic - -static void do_readlink(const HChar* path, HChar *buf, SizeT bufsize, SyscallStatus* status, Bool* curproc_file) -{ - HChar name[30]; - VG_(sprintf)(name, "/proc/%d/file", VG_(getpid)()); - if (ML_(safe_to_deref)(path, 1) - && (VG_(strcmp)(path, name) == 0 - || VG_(strcmp)(path, "/proc/curproc/file") == 0)) { - vg_assert(VG_(resolved_exename)); - Int len = VG_(snprintf)(buf, bufsize, "%s", VG_(resolved_exename)); - SET_STATUS_Success(len); - *curproc_file = True; - } -} - -// SYS_readlink 58 -// ssize_t readlink(const char *restrict path, char *restrict buf, size_t bufsiz); -PRE(sys_readlink) -{ - FUSE_COMPATIBLE_MAY_BLOCK(); - Word saved = SYSNO; - Bool curproc_file = False; - - PRINT("sys_readlink ( %#" FMT_REGWORD "x(%s), %#" FMT_REGWORD "x, %llu )", - ARG1, (char*)(Addr)ARG1, ARG2, (ULong)ARG3); - PRE_REG_READ3(long, "readlink", - const char *, path, char *, buf, int, bufsiz); - PRE_MEM_RASCIIZ( "readlink(path)", ARG1 ); - PRE_MEM_WRITE( "readlink(buf)", ARG2,ARG3 ); - - if (VG_(have_slash_proc) == True) - { - /* - * Handle the case where readlink is looking at /proc/curproc/file or - * /proc/<pid>/file - */ - do_readlink((const HChar *)ARG1, (HChar *)ARG2, (SizeT)ARG3, status, &curproc_file); - } - - if (!curproc_file) { - /* Normal case */ - SET_STATUS_from_SysRes( VG_(do_syscall3)(saved, ARG1, ARG2, ARG3)); - } - if (SUCCESS && RES > 0) { - POST_MEM_WRITE( ARG2, RES ); - } -} - -// SYS_execve 59 -// generic - -// SYS_umask 60 -// generic - -// SYS_chroot 61 -// generic - -// SYS_msync 65 -// generic - -// SYS_vfork 66 -// pid_t vfork(void); -PRE(sys_vfork) -{ - PRINT("%s", "sys_vfork ()"); - PRE_REG_READ0(pid_t, "vfork"); - - /* Pretend vfork == fork. Not true, but will have to do. */ - SET_STATUS_from_SysRes( ML_(do_fork)(tid) ); - if (SUCCESS) { - /* Thread creation was successful; let the child have the chance - to run */ - *flags |= SfYieldAfter; - } -} - -// SYS_sbrk 69 -// void * sbrk(intptr_t incr); -PRE(sys_sbrk) -{ - PRINT("sys_sbrk ( %#" FMT_REGWORD "x )",ARG1); - PRE_REG_READ1(void*, "sbrk", vki_intptr_t, incr); -} - -// SYS_freebsd11_vadvise 72 -// @todo maybe - -// SYS_munmap 73 -// generic - -// SYS_mprotect 74 -// generic - -// SYS_madvise 75 -// generic - -// SYS_mincore 78 -// generic - -// SYS_getgroups 79 -// generic - -// SYS_setgroups 80 -// generic - -// SYS_getpgrp 81 -// generic - -// SYS_setpgid 82 -// generic - -// SYS_setitimer 83 -// generic - -// SYS_swapon 85 -// int swapon(const char *special); -PRE(sys_swapon) -{ - PRINT("sys_swapon ( %#" FMT_REGWORD "x(%s) )", ARG1,(char*)ARG1); - PRE_REG_READ1(int, "swapon", const char*, special ); - PRE_MEM_RASCIIZ( "swapon(special)", ARG1 ); -} - -// SYS_getitimer 86 -// generic - -// SYS_getdtablesize 89 -// int getdtablesize(void); -PRE(sys_getdtablesize) -{ - PRINT("%s", "sys_getdtablesize ( )"); - PRE_REG_READ0(long, "getdtablesize"); -} - -// SYS_dup2 90 -// generic - -// SYS_fcntl 92 -// int fcntl(int fd, int cmd, ...); -PRE(sys_fcntl) -{ - switch (ARG2) { - // These ones ignore ARG3. - case VKI_F_GETFD: - case VKI_F_GETFL: - case VKI_F_GETOWN: - case VKI_F_GET_SEALS: - case VKI_F_ISUNIONSTACK: - PRINT("sys_fcntl ( %" FMT_REGWORD "d, %" FMT_REGWORD "d )", SARG1,SARG2); - PRE_REG_READ2(int, "fcntl", int, fd, int, cmd); - break; - - // These ones use ARG3 as "arg". - case VKI_F_DUPFD: - case VKI_F_DUPFD_CLOEXEC: - case VKI_F_SETFD: - case VKI_F_SETFL: - case VKI_F_SETOWN: - case VKI_F_READAHEAD: - case VKI_F_RDAHEAD: - case VKI_F_ADD_SEALS: - PRINT("sys_fcntl[ARG3=='arg'] ( %" FMT_REGWORD "d, %" FMT_REGWORD "d, %" FMT_REGWORD "d )", SARG1,SARG2,SARG3); - PRE_REG_READ3(int, "fcntl", - int, fd, int, cmd, int, arg); - break; - - // These ones use ARG3 as "lock" - obsolete. - case VKI_F_OSETLKW: - *flags |= SfMayBlock; - /* FALLTHROUGH */ - case VKI_F_OGETLK: - case VKI_F_OSETLK: - PRINT("sys_fcntl[ARG3=='lock'] ( %" FMT_REGWORD "u, %" FMT_REGWORD "u, %#" FMT_REGWORD "x )", ARG1,ARG2,ARG3); - PRE_REG_READ3(int, "fcntl", - int, fd, int, cmd, - struct oflock *, lock); - break; - - // This one uses ARG3 as "oldd" and ARG4 as "newd". - case VKI_F_DUP2FD: - case VKI_F_DUP2FD_CLOEXEC: - PRINT("sys_fcntl[ARG3=='oldd', ARG4=='newd'] ( %" FMT_REGWORD "u, %" FMT_REGWORD "u, %" FMT_REGWORD "u, %" FMT_REGWORD "u )", - ARG1,ARG2,ARG3,ARG4); - PRE_REG_READ4(int, "fcntl", - int, fd, int, cmd, - unsigned long, oldd, unsigned long, newd); - break; - - // These ones use ARG3 as "lock". - case VKI_F_SETLKW: - *flags |= SfMayBlock; - /* FALLTHROUGH */ - case VKI_F_GETLK: - case VKI_F_SETLK: - case VKI_F_SETLK_REMOTE: - PRINT("sys_fcntl[ARG3=='lock'] ( %" FMT_REGWORD "u, %" FMT_REGWORD "u, %#" FMT_REGWORD "x )", ARG1,ARG2,ARG3); - PRE_REG_READ3(int, "fcntl", - int, fd, int, cmd, - struct flock *, lock); - break; - case VKI_F_KINFO: - PRINT("sys_fcntl[ARG3=='kinfo_file'] ( %" FMT_REGWORD "u, %" FMT_REGWORD "u, %#" FMT_REGWORD "x )", ARG1,ARG2,ARG3); - PRE_REG_READ3(int, "fcntl", - int, fd, int, cmd, - struct vki_kinfo_file *, kinfo); - if (ARG3) { - struct vki_kinfo_file* p_kinfo_file = (struct vki_kinfo_file*)ARG3; - PRE_MEM_WRITE("fcntl(ARG3=='kinfo_file)", ARG3, p_kinfo_file->vki_kf_structsize); - } - break; - - default: - PRINT("sys_fcntl[UNKNOWN] ( %lu, %lu, %lu )", ARG1,ARG2,ARG3); - I_die_here; - } -} - -POST(sys_fcntl) -{ - vg_assert(SUCCESS); - if (ARG2 == VKI_F_DUPFD) { - if (!ML_(fd_allowed)(RES, "fcntl(DUPFD)", tid, True)) { - VG_(close)(RES); - SET_STATUS_Failure( VKI_EMFILE ); - } else { - if (VG_(clo_track_fds)) { - ML_(record_fd_open_named)(tid, RES); - } - } - } else if (ARG2 == VKI_F_DUPFD_CLOEXEC) { - if (!ML_(fd_allowed)(RES, "fcntl(DUPFD_CLOEXEC)", tid, True)) { - VG_(close)(RES); - SET_STATUS_Failure( VKI_EMFILE ); - } else { - if (VG_(clo_track_fds)) { - ML_(record_fd_open_named)(tid, RES); - } - } - } -} - -// SYS_select 93 -// generic - -// SYS_fsync 95 -// generic - -// SYS_setpriority 9 -// generic - -// SYS_socket 97 -// int socket(int domain, int type, int protocol); -PRE(sys_socket) -{ - PRINT("sys_socket ( %" FMT_REGWORD "d, %" FMT_REGWORD "d, %" FMT_REGWORD "d )",SARG1,SARG2,SARG3); - PRE_REG_READ3(int, "socket", int, domain, int, type, int, protocol); -} - -POST(sys_socket) -{ - SysRes r; - vg_assert(SUCCESS); - r = ML_(generic_POST_sys_socket)(tid, VG_(mk_SysRes_Success)(RES)); - SET_STATUS_from_SysRes(r); -} - -// SYS_connect 98 -// int connect(int s, const struct sockaddr *name, socklen_t namelen); -PRE(sys_connect) -{ - *flags |= SfMayBlock; - PRINT("sys_connect ( %" FMT_REGWORD "u, %#" FMT_REGWORD "x, %" FMT_REGWORD "u )",ARG1,ARG2,ARG3); - PRE_REG_READ3(int, "connect", - int, s, const struct sockaddr *, name, int, namelen); - ML_(generic_PRE_sys_connect)(tid, ARG1,ARG2,ARG3); -} - -// SYS_getpriority 100 -// generic - -// SYS_bind 104 -// int bind(int s, const struct sockaddr *addr, socklen_t addrlen); -PRE(sys_bind) -{ - PRINT("sys_bind ( %" FMT_REGWORD "u, %#" FMT_REGWORD "x, %" FMT_REGWORD "u )",ARG1,ARG2,ARG3); - PRE_REG_READ3(int, "bind", - int, s, struct sockaddr *, addr, int, addrlen); - ML_(generic_PRE_sys_bind)(tid, ARG1,ARG2,ARG3); -} - -// SYS_setsockopt 105 -// int setsockopt(int s, int level, int optname, const void *optval, -// socklen_t optlen); -PRE(sys_setsockopt) -{ - PRINT("sys_setsockopt ( %" FMT_REGWORD "d, %" FMT_REGWORD "d, %" FMT_REGWORD "d, %#" FMT_REGWORD "x, %" FMT_REGWORD "u )",SARG1,SARG2,SARG3,ARG4,ARG5); - PRE_REG_READ5(int, "setsockopt", - int, s, int, level, int, optname, - const void *, optval, vki_socklen_t, optlen); - ML_(generic_PRE_sys_setsockopt)(tid, ARG1,ARG2,ARG3,ARG4,ARG5); -} - -// SYS_listen 106 -// int listen(int s, int backlog); -PRE(sys_listen) -{ - PRINT("sys_listen ( %" FMT_REGWORD "d, %" FMT_REGWORD "d )",SARG1,SARG2); - PRE_REG_READ2(int, "listen", int, s, int, backlog); -} - -//SYS_gettimeofday 116 -// generic - -// SYS_getrusage 117 -// generic - -// SYS_getsockopt 118 -// int getsockopt(int s, int level, int optname, void * restrict optval, -// socklen_t * restrict optlen); -PRE(sys_getsockopt) -{ - Addr optval_p = ARG4; - Addr optlen_p = ARG5; - PRINT("sys_getsockopt ( %" FMT_REGWORD "u, %" FMT_REGWORD "u, %" FMT_REGWORD "u, %#" FMT_REGWORD "x, %#" FMT_REGWORD "x )",ARG1,ARG2,ARG3,ARG4,ARG5); - PRE_REG_READ5(int, "getsockopt", - int, s, int, level, int, optname, - void *, optval, int, *optlen); - if (optval_p != (Addr)NULL) { - ML_(buf_and_len_pre_check) ( tid, optval_p, optlen_p, - "getsockopt(optval)", - "getsockopt(optlen)" ); - } -} - -POST(sys_getsockopt) -{ - Addr optval_p = ARG4; - Addr optlen_p = ARG5; - vg_assert(SUCCESS); - if (optval_p != (Addr)NULL) { - ML_(buf_and_len_post_check) ( tid, VG_(mk_SysRes_Success)(RES), - optval_p, optlen_p, - "getsockopt(optlen_out)" ); - } -} - -// SYS_readv 120 -// generic - -// SYS_writev 121 -// generic - -// SYS_settimeofday 122 -// generic - -// SYS_fchown 123 -// generic - -// SYS_fchmod 124 -// generic - -// SYS_setreuid 126 -// generic - -// SYS_setregid 127 -// generic - -// SYS_rename 128 -// generic - -// SYS_flock 131 -// generic - -// SYS_mkfifo 132 -// int mkfifo(const char *path, mode_t mode); -PRE(sys_mkfifo) -{ - PRINT("sys_mkfifo ( %#" FMT_REGWORD "x(%s), 0x%" FMT_REGWORD "x, 0x%" FMT_REGWORD "x )", ARG1, (char *)ARG1, ARG2, ARG3 ); - PRE_REG_READ2(int, "mkfifo", const char *, path, int, mode); - PRE_MEM_RASCIIZ( "mkfifo(path)", ARG1 ); -} - -// SYS_sendto 133 -// ssize_t sendto(int s, const void *msg, size_t len, int flags, -// const struct sockaddr *to, socklen_t tolen); -PRE(sys_sendto) -{ - *flags |= SfMayBlock; - PRINT("sys_sendto ( %" FMT_REGWORD "u, %#" FMT_REGWORD "x, %" FMT_REGWORD "u, %" FMT_REGWORD "u, %#" FMT_REGWORD "x, %" FMT_REGWORD "u )",ARG1,ARG2,ARG3,ARG4,ARG5,ARG6); - PRE_REG_READ6(ssize_t, "sendto", - int, s, const void *, msg, int, len, - int, flags, - const struct sockaddr *, to, socklen_t, tolen); - ML_(generic_PRE_sys_sendto)(tid, ARG1,ARG2,ARG3,ARG4,ARG5,ARG6); -} - -// SYS_shutdown 134 -// int shutdown(int s, int how); -PRE(sys_shutdown) -{ - *flags |= SfMayBlock; - PRINT("sys_shutdown ( %" FMT_REGWORD "u, %" FMT_REGWORD "u )",ARG1,ARG2); - PRE_REG_READ2(int, "shutdown", int, s, int, how); -} - -// SYS_socketpair 135 -// int socketpair(int domain, int type, int protocol, int *sv); -PRE(sys_socketpair) -{ - PRINT("sys_socketpair ( %" FMT_REGWORD "u, %" FMT_REGWORD "u, %" FMT_REGWORD "u, %#" FMT_REGWORD "x )",ARG1,ARG2,ARG3,ARG4); - PRE_REG_READ4(int, "socketpair", - int, domain, int, type, int, protocol, int *, sv); - ML_(generic_PRE_sys_socketpair)(tid, ARG1,ARG2,ARG3,ARG4); -} - -POST(sys_socketpair) -{ - vg_assert(SUCCESS); - ML_(generic_POST_sys_socketpair)(tid, VG_(mk_SysRes_Success)(RES), - ARG1,ARG2,ARG3,ARG4); -} - -// SYS_mkdir 136 -// generic - -// SYS_rmdir 137 -// generic - -// SYS_utimes 138 -// generic - -// SYS_adjtime 140 -// int adjtime(const struct timeval *delta, struct timeval *olddelta); -PRE(sys_adjtime) -{ - PRINT("sys_adjtime ( %#" FMT_REGWORD "x, %#" FMT_REGWORD "x )",ARG1,ARG2); - PRE_REG_READ2(int, "adjtime", - const struct vki_timeval *, delta, struct vki_timeval *, olddelta); - PRE_MEM_READ("adjtime(delta)", ARG1, sizeof(struct vki_timeval)); - if (ARG2) { - PRE_MEM_WRITE("adjtime(olddelta)", ARG1, sizeof(struct vki_timeval)); - } -} - -POST(sys_adjtime) -{ - if (ARG2) { - POST_MEM_WRITE(ARG1, sizeof(struct vki_timeval)); - } -} - -// SYS_setsid 147 -// generic - -// SYS_quotactl 148 -/* int quotactl(const char *path, int cmd, int id, void *addr); */ -PRE(sys_quotactl) -{ - PRINT("sys_quotactl ( %#" FMT_REGWORD "x, %" FMT_REGWORD "u, %" FMT_REGWORD "u, %#" FMT_REGWORD "x )", ARG1,ARG2,ARG3, ARG4); - switch (ARG2) { - case VKI_Q_QUOTAON: - case VKI_Q_SETQUOTA: - case VKI_Q_SETUSE: - - case VKI_Q_GETQUOTASIZE: - PRE_REG_READ4(int, "quotactl", - const char *, path, int, cmd, int, id, - void *, addr); - PRE_MEM_RASCIIZ( "quotactl(path)", ARG1 ); - break; - case VKI_Q_GETQUOTA: - if (VG_(tdict).track_pre_reg_read) { - \ - PRRSN; - PRA1("quotactl",const char*,path); - PRA2("quotactl",int,cmd); - PRA4("quotactl",void*,addr); - } - break; - case VKI_Q_QUOTAOFF: - case VKI_Q_SYNC: - PRE_REG_READ2(int, "quotactl", - const char *, path, int, cmd); - break; - default: - break; - } -} - -// SYS_nlm_syscall 154 -// syscall.master says ; 154 is initialised by the NLM code, if present. -// @todo - -// SYS_nfssvc 155 -// int nfssvc(int flags, void *argstructp); -// lengthy manpage, at least 3 types of struct that argstructp can point to -// @todo - -// SYS_lgetfh 160 -// int lgetfh(const char *path, fhandle_t *fhp); -PRE(sys_lgetfh) -{ - PRINT("sys_lgetfh ( %#" FMT_REGWORD "x, %" FMT_REGWORD "x ", ARG1, ARG2); - PRE_REG_READ2(int, "lgetfh", const char*, path, vki_fhandle_t*, fhp); - PRE_MEM_RASCIIZ( "lgetfh(path)", ARG1 ); - PRE_MEM_WRITE("lgetfh(fhp)", ARG2, sizeof(vki_fhandle_t)); -} - -POST(sys_lgetfh) -{ - POST_MEM_WRITE(ARG2, sizeof(vki_fhandle_t)); -} - -// SYS_getfh 161 -// int getfh(const char *path, fhandle_t *fhp); -PRE(sys_getfh) -{ - PRINT("sys_getfh ( %#" FMT_REGWORD "x, %" FMT_REGWORD "x ", ARG1, ARG2); - PRE_REG_READ2(int, "getfh", const char*, path, vki_fhandle_t*, fhp); - PRE_MEM_RASCIIZ( "getfh(path)", ARG1 ); - PRE_MEM_WRITE("getfh(fhp)", ARG2, sizeof(vki_fhandle_t)); -} - -POST(sys_getfh) -{ - POST_MEM_WRITE(ARG2, sizeof(vki_fhandle_t)); -} - -#if (FREEBSD_VERS <= FREEBSD_10) -// 162 -// int getdomainname(char *domainname, int len); -PRE(sys_freebsd4_getdomainname) -{ - PRINT("sys_freebsd4_getdomainname ( %#" FMT_REGWORD "x, %" FMT_REGWORD "u )",ARG1,ARG2); - PRE_REG_READ2(int, "getdomainname", - char *, domainname, int, len); - PRE_MEM_WRITE( "getdomainname(domainname)", ARG1, ARG2 ); -} - -POST(sys_freebsd4_getdomainname) -{ - if (ARG1 != 0) { - POST_MEM_WRITE( ARG1, ARG2 ); - } -} - -// 163 -// int setdomainname(char *domainname, int len); -PRE(sys_freebsd4_setdomainname) -{ - PRINT("sys_freebsd4_setdomainname ( %#" FMT_REGWORD "x )",ARG1); - PRE_REG_READ2(int, "setdomainname", char *, domainname, int, len); - PRE_MEM_RASCIIZ( "setdomainname(domainname)", ARG1 ); -} - -// 164 -// int uname(struct utsname *name); -PRE(sys_freebsd4_uname) -{ - PRINT("sys_freebsd4_uname ( %#" FMT_REGWORD "x )", ARG1); - PRE_REG_READ1(int, "uname", struct utsname *, name); - PRE_MEM_WRITE( "uname(name)", ARG1, sizeof(struct vki_utsname) ); -} - -POST(sys_freebsd4_uname) -{ - if (ARG1 != 0) { - POST_MEM_WRITE( ARG1, sizeof(struct vki_utsname) ); - } -} -#endif - -// SYS_sysarch 165 -// x86/amd64 - -// SYS_rtprio 166 -PRE(sys_rtprio) -{ - PRINT( "sys_rtprio ( %" FMT_REGWORD "u, %" FMT_REGWORD "u, %#" FMT_REGWORD "x )", ARG1, ARG2, ARG3 ); - PRE_REG_READ3(int, "rtprio", - int, function, pid_t, pid, struct rtprio *, rtp); - if (ARG1 == VKI_RTP_SET) { - PRE_MEM_READ( "rtprio(rtp#set)", ARG3, sizeof(struct vki_rtprio)); - } else if (ARG1 == VKI_RTP_LOOKUP) { - PRE_MEM_WRITE( "rtprio(rtp#lookup)", ARG3, sizeof(struct vki_rtprio)); - } else { - /* PHK ?? */ - } -} - -POST(sys_rtprio) -{ - if (ARG1 == VKI_RTP_LOOKUP && RES == 0) { - POST_MEM_WRITE( ARG3, sizeof(struct vki_rtprio)); - } -} - -// freebsd6_pread 173 FREEBSD_VERS <= 10 -// x86/amd64 - -// freebsd6_pwrite 174 FREEBSD_VERS <= 10 -// x86/amd64 - -// SYS_setfib 175 -// int setfib(int fib); -PRE(sys_setfib) -{ - PRINT("sys_setfib ( %" FMT_REGWORD "d )", SARG1); - PRE_REG_READ1(int, "setfib", int, fib); -} - -// SYS_ntp_adjtime 176 -// int ntp_adjtime(struct timex *); -// @todo - -// SYS_setgid 181 -// generic - -// SYS_setegid 182 -// int setegid(gid_t egid); -PRE(sys_setegid) -{ - PRINT("sys_setegid ( %" FMT_REGWORD "u )", ARG1); - PRE_REG_READ1(int, "setegid", vki_gid_t, gid); -} - -// SYS_seteuid 183 -// int seteuid(uid_t euid); -PRE(sys_seteuid) -{ - PRINT("sys_seteuid ( %" FMT_REGWORD "u )", ARG1); - PRE_REG_READ1(long, "seteuid", vki_uid_t, uid); -} - - -#if (FREEBSD_VERS >= FREEBSD_12) - -// SYS_freebsd11_stat 188 -// int stat(char *path, struct freebsd11_stat *sb); -PRE(sys_freebsd11_stat) -{ - PRINT("sys_freebsd11_stat ( %#" FMT_REGWORD "x(%s), %#" FMT_REGWORD "x )",ARG1,(char *)ARG1,ARG2); - PRE_REG_READ2(int, "stat", char *, path, struct freebsd11_stat *, sb); - PRE_MEM_RASCIIZ( "stat(path)", ARG1 ); - PRE_MEM_WRITE( "stat(sb)", ARG2, sizeof(struct vki_freebsd11_stat) ); -} - -POST(sys_freebsd11_stat) -{ - POST_MEM_WRITE( ARG2, sizeof(struct vki_freebsd11_stat) ); -} - -// SYS_freebsd11_fstat 189 -// int fstat(int fd, struct stat *sb); -PRE(sys_freebsd11_fstat) -{ - PRINT("sys_freebsd11_fstat ( %" FMT_REGWORD "d, %#" FMT_REGWORD "x )",SARG1,ARG2); - PRE_REG_READ2(int, "fstat", int, fd, struct stat *, sb); - PRE_MEM_WRITE( "fstat(sb)", ARG2, sizeof(struct vki_freebsd11_stat) ); -} - -POST(sys_freebsd11_fstat) -{ - POST_MEM_WRITE( ARG2, sizeof(struct vki_freebsd11_stat) ); -} - -// SYS_freebsd11_lstat 190 -// int lstat(const char * restrict path, struct stat * restrict sb); -PRE(sys_freebsd11_lstat) -{ - PRINT("sys_freebsd11_lstat ( %#" FMT_REGWORD "x(%s), %#" FMT_REGWORD "x )",ARG1,(char *)ARG1,ARG2); - PRE_REG_READ2(sb, "lstat", const char *, path, struct freebsd11_stat *, sb); - PRE_MEM_RASCIIZ( "lstat(path)", ARG1 ); - PRE_MEM_WRITE( "lstat(sb)", ARG2, sizeof(struct vki_freebsd11_stat) ); -} - -POST(sys_freebsd11_lstat) -{ - vg_assert(SUCCESS); - if (RES == 0) { - POST_MEM_WRITE( ARG2, sizeof(struct vki_freebsd11_stat) ); - } -} - -#else - -PRE(sys_stat) -{ - PRINT("sys_stat ( %#" FMT_REGWORD "x(%s), %#" FMT_REGWORD "x )",ARG1,(char *)ARG1,ARG2); - PRE_REG_READ2(int, "stat", char *, path, struct stat *, sb); - PRE_MEM_RASCIIZ( "stat(path)", ARG1 ); - PRE_MEM_WRITE( "stat(sb)", ARG2, sizeof(struct vki_freebsd11_stat) ); -} - -POST(sys_stat) -{ - POST_MEM_WRITE( ARG2, sizeof(struct vki_freebsd11_stat) ); -} - - -PRE(sys_fstat) -{ - PRINT("sys_fstat ( %" FMT_REGWORD "d, %#" FMT_REGWORD "x )",SARG1,ARG2); - PRE_REG_READ2(int, "fstat", int, fd, struct stat *, sb); - PRE_MEM_WRITE( "fstat(sb)", ARG2, sizeof(struct vki_freebsd11_stat) ); -} - -POST(sys_fstat) -{ - POST_MEM_WRITE( ARG2, sizeof(struct vki_freebsd11_stat) ); -} - -PRE(sys_lstat) -{ - PRINT("sys_lstat ( %#" FMT_REGWORD "x(%s), %#" FMT_REGWORD "x )",ARG1,(char *)ARG1,ARG2); - PRE_REG_READ2(int, "lstat", const char *, path, struct stat *, sb); - PRE_MEM_RASCIIZ( "lstat(path)", ARG1 ); - PRE_MEM_WRITE( "lstat(sb)", ARG2, sizeof(struct vki_freebsd11_stat) ); -} - -POST(sys_lstat) -{ - vg_assert(SUCCESS); - if (RES == 0) { - POST_MEM_WRITE( ARG2, sizeof(struct vki_freebsd11_stat) ); - } -} - -#endif - -// SYS_pathconf 191 -// long pathconf(const char *path, int name); -PRE(sys_pathconf) -{ - PRINT("sys_pathconf ( %#" FMT_REGWORD "x(%s), %" FMT_REGWORD "u )",ARG1,(char *)ARG1,ARG2); - PRE_REG_READ2(long, "pathconf", char *, path, int, name); - PRE_MEM_RASCIIZ( "pathconf(path)", ARG1 ); -} - -// SYS_fpathconf 192 -// long fpathconf(int fd, int name); -PRE(sys_fpathconf) -{ - PRINT("sys_fpathconf ( %" FMT_REGWORD "u, %" FMT_REGWORD "u )",ARG1,ARG2); - PRE_REG_READ2(long, "fpathconf", int, fd, int, name); -} - -// SYS_getrlimit 194 -// generic - -// SYS_setrlimit 195 -// generic - - -// SYS_freebsd11_getdirentries 196 -// int getdirentries(int fd, char *buf, int nbytes, long *basep); -#if (FREEBSD_VERS >= FREEBSD_12) -PRE(sys_freebsd11_getdirentries) -{ - *flags |= SfMayBlock; - PRINT("sys_freebsd11_getdirentries ( %" FMT_REGWORD "u, %#" FMT_REGWORD "x, %" FMT_REGWORD "u )", ARG1,ARG2,ARG3); - PRE_REG_READ4(int, "getdirentries", - int, fd, char *, buf, - int, nbytes, - long *, basep); - PRE_MEM_WRITE( "getdirentries(buf)", ARG2, ARG3 ); - if (ARG4) { - PRE_MEM_WRITE( "getdirentries(basep)", ARG4, sizeof(long) ); - } -} - -POST(sys_freebsd11_getdirentries) -{ - vg_assert(SUCCESS); - if (RES > 0) { - POST_MEM_WRITE( ARG2, RES ); - if ( ARG4 != 0 ) { - POST_MEM_WRITE( ARG4, sizeof (long)); - } - } -} -#else -PRE(sys_getdirentries) -{ - *flags |= SfMayBlock; - PRINT("sys_getdirentries ( %" FMT_REGWORD "u, %#" FMT_REGWORD "x, %" FMT_REGWORD "u )", ARG1,ARG2,ARG3); - PRE_REG_READ4(int, "getdirentries", - int, fd, char *, buf, - int, nbytes, - long *, basep); - PRE_MEM_WRITE( "getdirentries(buf)", ARG2, ARG3 ); - if (ARG4) - PRE_MEM_WRITE( "getdirentries(basep)", ARG4, sizeof(long) ); -} - -POST(sys_getdirentries) -{ - vg_assert(SUCCESS); - if (RES > 0) { - POST_MEM_WRITE( ARG2, RES ); - if ( ARG4 != 0 ) - POST_MEM_WRITE( ARG4, sizeof (long)); - } -} -#endif - -// SYS_freebsd6_mmap 197 -// amd64 / x86 - - -// SYS___syscall 198 -// special handling - -// freebsd6_lseek 199 FREEBSD_VERS <= 10 -// x86/amd64 - -// freebsd6_truncate 200 FREEBSD_VERS <= 10 -// x86/amd64 - -// freebsd6_ftruncate 201 FREEBSD_VERS <= 10 -// x86/amd64 - -static Bool sysctl_kern_ps_strings(SizeT* out, SizeT* outlen) -{ - Word tmp = -1; - const struct auxv *cauxv; - - for (cauxv = (struct auxv*)VG_(client_auxv); cauxv->a_type != VKI_AT_NULL; cauxv++) { - if (cauxv->a_type == VKI_AT_PS_STRINGS) { - tmp = (Word)cauxv->u.a_ptr; - - *out = tmp; - *outlen = sizeof(size_t); - return True; - } - } - return False; -} - -static void sysctl_kern_usrstack(SizeT* out, SizeT* outlen) -{ - *out = VG_(get_usrstack)(); - *outlen = sizeof(ULong); -} - -static Bool sysctl_kern_proc_pathname(HChar *out, SizeT *len) -{ - const HChar *exe_name = VG_(resolved_exename); - - if (!len) { - return False; - } - - if (!out) { - HChar tmp[VKI_PATH_MAX]; - if (!VG_(realpath)(exe_name, tmp)) { - return False; - } - *len = VG_(strlen)(tmp)+1; - return True; - } - - if (!VG_(realpath)(exe_name, out)) { - return False; - } - - *len = VG_(strlen)(out)+1; - return True; -} - -// SYS___sysctl 202 -/* int __sysctl(int *name, u_int namelen, void *oldp, size_t *oldlenp, void *newp, size_t newlen); */ -/* ARG1 ARG2 ARG3 ARG4 ARG5 ARG6 */ -PRE(sys___sysctl) -{ - PRINT("sys_sysctl ( %#" FMT_REGWORD "x, %" FMT_REGWORD "d, %#" FMT_REGWORD "x, %#" FMT_REGWORD "x, %#" FMT_REGWORD "x, %" FMT_REGWORD "u )", ARG1,SARG2,ARG3,ARG4,ARG5,ARG6 ); - - int* name = (int*)ARG1; - if (ML_(safe_to_deref)(name, sizeof(int))) { - PRINT("\nmib[0]: "); - if (SARG2 >= 1) { - switch (name[0]) { - case 0: // CTL_UNSPEC - PRINT("unspec"); - break; - case 1: // CTL_KERN - PRINT("kern"); - break; - case 2: // CTL_VM - PRINT("vm"); - break; - case 3: // CTL_VFS - PRINT("vfs"); - break; - case 4: // CTL_NET - PRINT("net"); - break; - case 5: // CTL_DEBUG - PRINT("debug"); - break; - case 6: // CTL_HW - PRINT("hw"); - b... [truncated message content] |
|
From: Paul F. <pa...@so...> - 2023-08-27 14:32:11
|
https://sourceware.org/git/gitweb.cgi?p=valgrind.git;h=c5af71f5da178985c5bf42616134c6f083f689f1 commit c5af71f5da178985c5bf42616134c6f083f689f1 Author: Paul Floyd <pj...@wa...> Date: Sun Aug 27 18:29:30 2023 +0200 FreeBSD: Add a new testcase for FreeBSD 14 _umtx_op set timeout Uses an existing testcase with pthread APIs that use timeouts and sets LIBPTHREAD_UMTX_MIN_TIMEOUT to 100 (ns, so almost no effect other than exercising the syscall). Diff: --- coregrind/m_syswrap/syswrap-freebsd.c.orig | 7418 +++++++++++++++++++++++++ none/tests/freebsd/Makefile.am | 4 +- none/tests/freebsd/umtx_op_timeout.stderr.exp | 10 + none/tests/freebsd/umtx_op_timeout.vgtest | 7 + 4 files changed, 7438 insertions(+), 1 deletion(-) diff --git a/coregrind/m_syswrap/syswrap-freebsd.c.orig b/coregrind/m_syswrap/syswrap-freebsd.c.orig new file mode 100644 index 0000000000..a59872b3c9 --- /dev/null +++ b/coregrind/m_syswrap/syswrap-freebsd.c.orig @@ -0,0 +1,7418 @@ +/*--------------------------------------------------------------------*/ +/*--- FreeBSD-specific syscalls, etc. syswrap-freebsd.c ---*/ +/*--------------------------------------------------------------------*/ + +/* + This file is part of Valgrind, a dynamic binary instrumentation + framework. + + Copyright (C) 2000-2008 Nicholas Nethercote + nj...@va... + Copyright (C) 2018-2021 Paul Floyd + pj...@wa... + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, see <http://www.gnu.org/licenses/>. + + The GNU General Public License is contained in the file COPYING. +*/ + +#if defined(VGO_freebsd) + +#include "pub_core_basics.h" +#include "pub_core_vki.h" +#include "pub_core_vkiscnums.h" +#include "pub_core_threadstate.h" +#include "pub_core_aspacemgr.h" +#include "pub_core_debuginfo.h" // VG_(di_notify_*) +#include "pub_core_transtab.h" // VG_(discard_translations) +#include "pub_core_xarray.h" +#include "pub_core_clientstate.h" +#include "pub_core_debuglog.h" +#include "pub_core_libcbase.h" +#include "pub_core_libcassert.h" +#include "pub_core_libcfile.h" +#include "pub_core_libcprint.h" +#include "pub_core_libcproc.h" +#include "pub_core_libcsignal.h" +#include "pub_core_machine.h" +#include "pub_core_mallocfree.h" +#include "pub_core_tooliface.h" +#include "pub_core_options.h" +#include "pub_core_scheduler.h" +#include "pub_core_signals.h" +#include "pub_core_stacks.h" +#include "pub_core_syscall.h" +#include "pub_core_syswrap.h" +#include "pub_core_inner.h" +#include "pub_core_pathscan.h" +#if defined(ENABLE_INNER_CLIENT_REQUEST) +#include "pub_core_clreq.h" +#endif + +#include "priv_types_n_macros.h" +#include "priv_syswrap-generic.h" +#include "priv_syswrap-main.h" +#include "priv_syswrap-freebsd.h" + +static Bool capabiltyMode = False; + +Bool VG_(get_capability_mode)(void) +{ + return capabiltyMode; +} + + +// Run a thread from beginning to end and return the thread's +// scheduler-return-code. +static VgSchedReturnCode thread_wrapper(Word /*ThreadId*/ tidW) +{ + VgSchedReturnCode ret; + ThreadId tid = (ThreadId)tidW; + Int lwpid = VG_(gettid)(); + ThreadState* tst = VG_(get_ThreadState)(tid); + + VG_(debugLog)(1, "syswrap-freebsd", + "thread_wrapper(tid=%u,lwpid=%d): entry\n", + tid, lwpid); + + vg_assert(tst->status == VgTs_Init); + + /* make sure we get the CPU lock before doing anything significant */ + VG_(acquire_BigLock)(tid, "thread_wrapper(starting new thread)"); + + if (0) { + VG_(printf)("thread tid %u started: stack = %p\n", + tid, (void*)&tid); + } + + /* Make sure error reporting is enabled in the new thread. */ + tst->err_disablement_level = 0; + + VG_TRACK(pre_thread_first_insn, tid); + + tst->os_state.lwpid = lwpid; + /* Set the threadgroup for real. This overwrites the provisional value set + in do_clone(). See comments in do_clone for background, also #226116. */ + tst->os_state.threadgroup = VG_(getpid)(); + + /* Thread created with all signals blocked; scheduler will set the + appropriate mask */ + + ret = VG_(scheduler)(tid); + + vg_assert(VG_(is_exiting)(tid)); + + vg_assert(tst->status == VgTs_Runnable); + vg_assert(VG_(is_running_thread)(tid)); + + VG_(debugLog)(1, "syswrap-freebsd", + "thread_wrapper(tid=%u,lwpid=%d): exit, schedreturncode %s\n", + tid, lwpid, VG_(name_of_VgSchedReturnCode)(ret)); + + /* Return to caller, still holding the lock. */ + return ret; +} + + +/* --------------------------------------------------------------------- + clone-related stuff + ------------------------------------------------------------------ */ + +/* Run a thread all the way to the end, then do appropriate exit actions + (this is the last-one-out-turn-off-the-lights bit). */ +__attribute__((noreturn)) +static void run_a_thread_NORETURN ( Word tidW ) +{ + ThreadId tid = (ThreadId)tidW; + VgSchedReturnCode src; + Int c; + ThreadState* tst; +#ifdef ENABLE_INNER_CLIENT_REQUEST + Int registered_vgstack_id; +#endif + + VG_(debugLog)(1, "syswrap-freebsd", + "run_a_thread_NORETURN(tid=%u): pre-thread_wrapper\n", + tid); + + tst = VG_(get_ThreadState)(tid); + vg_assert(tst); + + /* An thread has two stacks: + * the simulated stack (used by the synthetic cpu. Guest process + is using this stack). + * the valgrind stack (used by the real cpu. Valgrind code is running + on this stack). + When Valgrind runs as an inner, it must signals that its (real) stack + is the stack to use by the outer to e.g. do stacktraces. + */ + INNER_REQUEST + (registered_vgstack_id + = VALGRIND_STACK_REGISTER (tst->os_state.valgrind_stack_base, + tst->os_state.valgrind_stack_init_SP)); + + /* Run the thread all the way through. */ + src = thread_wrapper(tid); + + VG_(debugLog)(1, "syswrap-freebsd", + "run_a_thread_NORETURN(tid=%u): post-thread_wrapper\n", + tid); + + c = VG_(count_living_threads)(); + vg_assert(c >= 1); /* stay sane */ + + /* Deregister thread's stack. */ + if (tst->os_state.stk_id != NULL_STK_ID) { + VG_(deregister_stack)(tst->os_state.stk_id); + } + + // Tell the tool this thread is exiting + VG_TRACK( pre_thread_ll_exit, tid ); + + /* If the thread is exiting with errors disabled, complain loudly; + doing so is bad (does the user know this has happened?) Also, + in all cases, be paranoid and clear the flag anyway so that the + thread slot is safe in this respect if later reallocated. This + should be unnecessary since the flag should be cleared when the + slot is reallocated, in thread_wrapper(). */ + if (tst->err_disablement_level > 0) { + VG_(umsg)( + "WARNING: exiting thread has error reporting disabled.\n" + "WARNING: possibly as a result of some mistake in the use\n" + "WARNING: of the VALGRIND_DISABLE_ERROR_REPORTING macros.\n" + ); + VG_(debugLog)( + 1, "syswrap-freebsd", + "run_a_thread_NORETURN(tid=%u): " + "WARNING: exiting thread has err_disablement_level = %u\n", + tid, tst->err_disablement_level + ); + } + tst->err_disablement_level = 0; + + if (c == 1) { + + VG_(debugLog)(1, "syswrap-freebsd", + "run_a_thread_NORETURN(tid=%u): " + "last one standing\n", + tid); + + /* We are the last one standing. Keep hold of the lock and + carry on to show final tool results, then exit the entire system. + Use the continuation pointer set at startup in m_main. */ + ( * VG_(address_of_m_main_shutdown_actions_NORETURN) ) (tid, src); + } else { + + VG_(debugLog)(1, "syswrap-freebsd", + "run_a_thread_NORETURN(tid=%u): " + "not last one standing\n", + tid); + + /* OK, thread is dead, but others still exist. Just exit. */ + + /* This releases the run lock */ + VG_(exit_thread)(tid); + vg_assert(tst->status == VgTs_Zombie); + vg_assert(sizeof(tst->status) == 4); + vg_assert(sizeof(tst->os_state.exitcode) == sizeof(Word)); + + INNER_REQUEST (VALGRIND_STACK_DEREGISTER (registered_vgstack_id)); + + /* We have to use this sequence to terminate the thread to + prevent a subtle race. If VG_(exit_thread)() had left the + ThreadState as Empty, then it could have been reallocated, + reusing the stack while we're doing these last cleanups. + Instead, VG_(exit_thread) leaves it as Zombie to prevent + reallocation. We need to make sure we don't touch the stack + between marking it Empty and exiting. Hence the + assembler. */ +#if defined(VGP_x86_freebsd) /* FreeBSD has args on the stack */ + __asm__ volatile ( + "movl %1, %0\n" /* set tst->status = VgTs_Empty */ + "movl %2, %%eax\n" /* set %eax = __NR_thr_exit */ + "movl %3, %%ebx\n" /* set %ebx = tst->os_state.exitcode */ + "pushl %%ebx\n" /* arg on stack */ + "pushl %%ebx\n" /* fake return address */ + "int $0x80\n" /* thr_exit(tst->os_state.exitcode) */ + "popl %%ebx\n" /* fake return address */ + "popl %%ebx\n" /* arg off stack */ + : "=m" (tst->status) + : "n" (VgTs_Empty), "n" (__NR_thr_exit), "m" (tst->os_state.exitcode) + : "eax", "ebx" + ); +#elif defined(VGP_amd64_freebsd) + __asm__ volatile ( + "movl %1, %0\n" /* set tst->status = VgTs_Empty */ + "movq %2, %%rax\n" /* set %rax = __NR_thr_exit */ + "movq %3, %%rdi\n" /* set %rdi = tst->os_state.exitcode */ + "pushq %%rdi\n" /* fake return address */ + "syscall\n" /* thr_exit(tst->os_state.exitcode) */ + "popq %%rdi\n" /* fake return address */ + : "=m" (tst->status) + : "n" (VgTs_Empty), "n" (__NR_thr_exit), "m" (tst->os_state.exitcode) + : "rax", "rdi" + ); +#else +# error Unknown platform +#endif + + VG_(core_panic)("Thread exit failed?\n"); + } + + /*NOTREACHED*/ + vg_assert(0); +} + +Word ML_(start_thread_NORETURN) ( void* arg ) +{ + ThreadState* tst = (ThreadState*)arg; + ThreadId tid = tst->tid; + + run_a_thread_NORETURN ( (Word)tid ); + /*NOTREACHED*/ + vg_assert(0); +} + +/* Allocate a stack for this thread, if it doesn't already have one. + They're allocated lazily, and never freed. Returns the initial stack + pointer value to use, or 0 if allocation failed. */ +Addr ML_(allocstack)(ThreadId tid) +{ + ThreadState* tst = VG_(get_ThreadState)(tid); + VgStack* stack; + Addr initial_SP; + + /* Either the stack_base and stack_init_SP are both zero (in which + case a stack hasn't been allocated) or they are both non-zero, + in which case it has. */ + + if (tst->os_state.valgrind_stack_base == 0) { + vg_assert(tst->os_state.valgrind_stack_init_SP == 0); + } + + if (tst->os_state.valgrind_stack_base != 0) { + vg_assert(tst->os_state.valgrind_stack_init_SP != 0); + } + + /* If no stack is present, allocate one. */ + + if (tst->os_state.valgrind_stack_base == 0) { + stack = VG_(am_alloc_VgStack)( &initial_SP ); + if (stack) { + tst->os_state.valgrind_stack_base = (Addr)stack; + tst->os_state.valgrind_stack_init_SP = initial_SP; + } + } + + if (0) { + VG_(printf)( "stack for tid %u at %p; init_SP=%p\n", + tid, + (void*)tst->os_state.valgrind_stack_base, + (void*)tst->os_state.valgrind_stack_init_SP ); + } + + return tst->os_state.valgrind_stack_init_SP; +} + +/* Allocate a stack for the main thread, and run it all the way to the + end. Although we already have a working VgStack + (VG_(interim_stack)) it's better to allocate a new one, so that + overflow detection works uniformly for all threads. +*/ +__attribute__((noreturn)) +void VG_(main_thread_wrapper_NORETURN)(ThreadId tid) +{ + Addr sp; + VG_(debugLog)(1, "syswrap-freebsd", + "entering VG_(main_thread_wrapper_NORETURN)\n"); + + sp = ML_(allocstack)(tid); +#if defined(ENABLE_INNER_CLIENT_REQUEST) + { + // we must register the main thread stack before the call + // to ML_(call_on_new_stack_0_1), otherwise the outer valgrind + // reports 'write error' on the non registered stack. + ThreadState* tst = VG_(get_ThreadState)(tid); + INNER_REQUEST + ((void) + VALGRIND_STACK_REGISTER (tst->os_state.valgrind_stack_base, + tst->os_state.valgrind_stack_init_SP)); + } +#endif + + /* If we can't even allocate the first thread's stack, we're hosed. + Give up. */ + vg_assert2(sp != 0, "%s", "Cannot allocate main thread's stack."); + + /* shouldn't be any other threads around yet */ + vg_assert( VG_(count_living_threads)() == 1 ); + + ML_(call_on_new_stack_0_1)( + (Addr)sp, /* stack */ + 0, /* bogus return address */ + run_a_thread_NORETURN, /* fn to call */ + (Word)tid /* arg to give it */ + ); + + /*NOTREACHED*/ + vg_assert(0); +} + + +/* Do a fork() */ +SysRes ML_(do_fork) ( ThreadId tid ) +{ + vki_sigset_t fork_saved_mask; + vki_sigset_t mask; + SysRes res; + + /* Block all signals during fork, so that we can fix things up in + the child without being interrupted. */ + VG_(sigfillset)(&mask); + VG_(sigprocmask)(VKI_SIG_SETMASK, &mask, &fork_saved_mask); + + VG_(do_atfork_pre)(tid); + + res = VG_(do_syscall0)( __NR_fork ); + + if (!sr_isError(res)) { + if (sr_Res(res) == 0) { + /* child */ + VG_(do_atfork_child)(tid); + + /* restore signal mask */ + VG_(sigprocmask)(VKI_SIG_SETMASK, &fork_saved_mask, NULL); + + } else { + /* parent */ + VG_(do_atfork_parent)(tid); + + if (VG_(clo_trace_syscalls)) { + VG_(printf)(" clone(fork): process %d created child %lu\n", + VG_(getpid)(), sr_Res(res)); + } + + /* restore signal mask */ + VG_(sigprocmask)(VKI_SIG_SETMASK, &fork_saved_mask, NULL); + } + } + + return res; +} + +static Addr ML_(make_safe_mask) ( const HChar* malloc_message, Addr mask_pointer ) +{ + vki_sigset_t* new_mask; + const vki_sigset_t* old_mask = (vki_sigset_t *)mask_pointer; + + if (!ML_(safe_to_deref)(old_mask, sizeof(vki_sigset_t))) { + new_mask = (vki_sigset_t*)1; /* Something recognisable to POST() hook. */ + } else { + new_mask = VG_(malloc)(malloc_message, sizeof(vki_sigset_t)); + *new_mask = *old_mask; + VG_(sanitize_client_sigmask)(new_mask); + } + + return (Addr)new_mask; +} + +static void ML_(free_safe_mask) ( Addr mask_pointer ) +{ + if (mask_pointer != 0 && mask_pointer != 1) { + VG_(free)((vki_sigset_t *) mask_pointer); + } +} + + +/* --------------------------------------------------------------------- + PRE/POST wrappers for arch-generic, FreeBSD-specific syscalls + ------------------------------------------------------------------ */ + +// Nb: See the comment above the generic PRE/POST wrappers in +// m_syswrap/syswrap-generic.c for notes about how they work. + +#define PRE(name) DEFN_PRE_TEMPLATE(freebsd, name) +#define POST(name) DEFN_POST_TEMPLATE(freebsd, name) + +/* On FreeBSD, if any thread calls exit(2), then they are all shut down, pretty + * much like linux's exit_group(). + */ +// SYS_exit 1 +// void exit(int status); +PRE(sys_exit) +{ + ThreadId t; + + PRINT("exit( %" FMT_REGWORD "u )", ARG1); + PRE_REG_READ1(void, "exit", int, status); + + /* Mark all threads (including this one) to exit. */ + for (t = 1; t < VG_N_THREADS; t++) { + if ( /* not alive */ VG_(threads)[t].status == VgTs_Empty ) { + continue; + } + + //VG_(threads)[t].exitreason = VgSrc_ExitThread; + VG_(threads)[t].os_state.exitcode = ARG1; + + // if (t != tid) + // VG_(get_thread_out_of_syscall)(t); /* unblock it, if blocked */ + } + + VG_(nuke_all_threads_except)( tid, VgSrc_ExitProcess ); + VG_(reap_threads)(tid); + VG_(threads)[tid].exitreason = VgSrc_ExitThread; + + /* We have to claim the syscall already succeeded. */ + SET_STATUS_Success(0); +} + +// SYS_fork 2 +// pid_t fork(void); +PRE(sys_fork) +{ + PRINT("%s", "sys_fork ()"); + PRE_REG_READ0(pid_t, "fork"); + + SET_STATUS_from_SysRes( ML_(do_fork)(tid) ); + if (SUCCESS) { + /* Thread creation was successful; let the child have the chance + to run */ + *flags |= SfYieldAfter; + } +} + +// SYS_read 3 +// generic + +// SYS_write 4 +// generic + +// SYS_open 5 +// generic + +// SYS_close 6 +// generic + +// SYS_wait4 7 +// generic + +// SYS_link 9 +// generic + +// SYS_unlink 10 +// generic + +// SYS_chdir 12 + +// SYS_fchdir 13 +// generic + +// SYS_freebsd11_mknod 14 +// generic + +// SYS_chmod 15 +// generic + +// SYS_chown 16 +// generic + +// SYS_break 17 +// generic + +// SYS_getpid 20 +// generic + +// SYS_mount 21 +// int mount(const char *type, const char *dir, int flags, void *data); +PRE(sys_mount) +{ + // Nb: depending on 'flags', the 'type' and 'data' args may be ignored. + // We are conservative and check everything, except the memory pointed to + // by 'data'. + *flags |= SfMayBlock; + PRINT( "sys_mount( %#" FMT_REGWORD "x, %#" FMT_REGWORD "x, %" FMT_REGWORD "u, %#" FMT_REGWORD "x )",ARG1,ARG2,ARG3,ARG4); + PRE_REG_READ4(int, "mount", + const char *, type, char *, dir, int, flags, + void *, data); + PRE_MEM_RASCIIZ( "mount(type)", ARG1); + PRE_MEM_RASCIIZ( "mount(path)", ARG2); +} + +// SYS_unmount 22 +// int unmount(const char *dir, int flags); +PRE(sys_unmount) +{ + PRINT("sys_umount( %#" FMT_REGWORD "x, %" FMT_REGWORD "u )", ARG1, ARG2); + PRE_REG_READ2(int, "unmount", const char *, dir, int, flags); + PRE_MEM_RASCIIZ( "unmount(path)", ARG1); +} + +// SYS_setuid 23 +// generic + +// SYS_getuid 24 +// generic + +// SYS_geteuid 25 +// generic + +// SYS_ptrace 26 +// int ptrace(int request, pid_t pid, caddr_t addr, int data); +PRE(sys_ptrace) +{ + struct vki_ptrace_io_desc *io_desc; + PRINT("sys_ptrace ( %" FMT_REGWORD "u, %" FMT_REGWORD "u, 0x%" FMT_REGWORD "x, %" FMT_REGWORD "u)", ARG1, ARG2, ARG3, ARG4); + + PRE_REG_READ4(int, "ptrace", int, request, pid_t, pid, caddr_t, addr, int, data); + + switch (ARG1) { + case VKI_PTRACE_TRACEME: + case VKI_PTRACE_READ_I: + case VKI_PTRACE_READ_D: + case VKI_PTRACE_WRITE_I: + case VKI_PTRACE_WRITE_D: + break; + + case VKI_PTRACE_IO: + PRE_MEM_READ("ptrace", ARG3, sizeof(struct vki_ptrace_io_desc)); + io_desc = (struct vki_ptrace_io_desc *)ARG3; + switch (io_desc->piod_op) { + case VKI_PIOD_READ_D: + case VKI_PIOD_READ_I: + PRE_MEM_WRITE( "ptrace", (UWord)io_desc->piod_addr, io_desc->piod_len); + break; + case VKI_PIOD_WRITE_D: + case VKI_PIOD_WRITE_I: + PRE_MEM_READ( "ptrace", (UWord)io_desc->piod_addr, io_desc->piod_len); + break; + } + break; + + case VKI_PTRACE_CONTINUE: + case VKI_PTRACE_STEP: + case VKI_PTRACE_KILL: + case VKI_PTRACE_ATTACH: + case VKI_PTRACE_DETACH: + break; + + case VKI_PTRACE_GETREGS: + PRE_MEM_WRITE("ptrace", ARG3, sizeof(struct vki_user_regs_struct)); + break; + + case VKI_PTRACE_SETREGS: + PRE_MEM_READ("ptrace", ARG3, sizeof(struct vki_user_regs_struct)); + break; + + case VKI_PTRACE_GETFPREGS: + PRE_MEM_WRITE("ptrace", ARG3, sizeof(struct vki_fpreg)); + break; + + case VKI_PTRACE_SETFPREGS: + PRE_MEM_READ("ptrace", ARG3, sizeof(struct vki_fpreg)); + break; + + case VKI_PTRACE_GETDBREGS: + PRE_MEM_WRITE("ptrace", ARG3, sizeof(struct vki_dbreg)); + break; + + case VKI_PTRACE_SETDBREGS: + PRE_MEM_READ("ptrace", ARG3, sizeof(struct vki_dbreg)); + break; + + case VKI_PTRACE_LWPINFO: + PRE_MEM_WRITE("ptrace", ARG3, sizeof(struct vki_ptrace_lwpinfo)); + break; + + case VKI_PTRACE_GETNUMLWPS: + break; + + case VKI_PTRACE_GETLWPLIST: + PRE_MEM_WRITE( "ptrace", ARG3, sizeof(vki_lwpid_t) * ARG4); + break; + + case VKI_PTRACE_SETSTEP: + case VKI_PTRACE_CLEARSTEP: + case VKI_PTRACE_SUSPEND: + case VKI_PTRACE_RESUME: + case VKI_PTRACE_TO_SCE: + case VKI_PTRACE_TO_SCX: + case VKI_PTRACE_SYSCALL: + case VKI_PTRACE_VM_TIMESTAMP: + break; + case VKI_PTRACE_VM_ENTRY: + PRE_MEM_WRITE( "ptrace", ARG3, sizeof(struct vki_ptrace_vm_entry)); + break; + } +} + +POST(sys_ptrace) +{ + struct vki_ptrace_io_desc *io_desc; + + switch (ARG1) { + case VKI_PTRACE_TRACEME: + case VKI_PTRACE_READ_I: + case VKI_PTRACE_READ_D: + case VKI_PTRACE_WRITE_I: + case VKI_PTRACE_WRITE_D: + break; + + case VKI_PTRACE_IO: + io_desc = (struct vki_ptrace_io_desc *)ARG3; + switch (io_desc->piod_op) { + case VKI_PIOD_READ_D: + case VKI_PIOD_READ_I: + if ((Word)RES != -1) { + POST_MEM_WRITE((UWord)io_desc->piod_addr, io_desc->piod_len); + } + break; + case VKI_PIOD_WRITE_D: + case VKI_PIOD_WRITE_I: + break; + } + break; + + case VKI_PTRACE_CONTINUE: + case VKI_PTRACE_STEP: + case VKI_PTRACE_KILL: + case VKI_PTRACE_ATTACH: + case VKI_PTRACE_DETACH: + break; + + case VKI_PTRACE_GETREGS: + if ((Word)RES != -1) { + POST_MEM_WRITE(ARG3, sizeof(struct vki_user_regs_struct)); + } + break; + + case VKI_PTRACE_SETREGS: + break; + + case VKI_PTRACE_GETFPREGS: + if ((Word)RES != -1) { + POST_MEM_WRITE(ARG3, sizeof(struct vki_fpreg)); + } + break; + + case VKI_PTRACE_SETFPREGS: + break; + + case VKI_PTRACE_GETDBREGS: + if ((Word)RES != -1) { + POST_MEM_WRITE(ARG3, sizeof(struct vki_dbreg)); + } + break; + + case VKI_PTRACE_SETDBREGS: + break; + + case VKI_PTRACE_LWPINFO: + if ((Word)RES != -1) { + POST_MEM_WRITE(ARG3, sizeof(struct vki_ptrace_lwpinfo)); + } + break; + + case VKI_PTRACE_GETNUMLWPS: + break; + + case VKI_PTRACE_GETLWPLIST: + if ((Word)RES != -1) { + POST_MEM_WRITE(ARG3, sizeof(vki_lwpid_t) * RES); + } + break; + + case VKI_PTRACE_SETSTEP: + case VKI_PTRACE_CLEARSTEP: + case VKI_PTRACE_SUSPEND: + case VKI_PTRACE_RESUME: + case VKI_PTRACE_TO_SCE: + case VKI_PTRACE_TO_SCX: + case VKI_PTRACE_SYSCALL: + case VKI_PTRACE_VM_TIMESTAMP: + break; + + case VKI_PTRACE_VM_ENTRY: + if ((Word)RES != -1) { + POST_MEM_WRITE(ARG3, sizeof(struct vki_ptrace_vm_entry)); + } + break; + } +} + +// SYS_recvmsg 27 +// ssize_t recvmsg(int s, struct msghdr *msg, int flags); +PRE(sys_recvmsg) +{ + *flags |= SfMayBlock; + PRINT("sys_recvmsg ( %" FMT_REGWORD "d, %#" FMT_REGWORD "x, %" FMT_REGWORD "d )",SARG1,ARG2,SARG3); + PRE_REG_READ3(vki_ssize_t, "recvmsg", int, s, struct msghdr *, msg, int, flags); + ML_(generic_PRE_sys_recvmsg)(tid, "recvmsg", (struct vki_msghdr *)ARG2); +} + +POST(sys_recvmsg) +{ + + ML_(generic_POST_sys_recvmsg)(tid, "recvmsg", (struct vki_msghdr *)ARG2, RES); +} + +// SYS_sendmsg 28 +// ssize_t sendmsg(int s, const struct msghdr *msg, int flags); +PRE(sys_sendmsg) +{ + *flags |= SfMayBlock; + PRINT("sys_sendmsg ( %" FMT_REGWORD "u, %#" FMT_REGWORD "x, %" FMT_REGWORD "u )",ARG1,ARG2,ARG3); + PRE_REG_READ3(ssize_t, "sendmsg", + int, s, const struct msghdr *, msg, int, flags); + ML_(generic_PRE_sys_sendmsg)(tid, "sendmsg", (struct vki_msghdr *)ARG2); +} + +// SYS_recvfrom 29 +// ssize_t recvfrom(int s, void *buf, size_t len, int flags, +// struct sockaddr * restrict from, socklen_t * restrict fromlen); +PRE(sys_recvfrom) +{ + *flags |= SfMayBlock; + PRINT("sys_recvfrom ( %" FMT_REGWORD "d, %#" FMT_REGWORD "x, %" FMT_REGWORD "u, %" FMT_REGWORD "d, %#" FMT_REGWORD "x, %#" FMT_REGWORD "x )",SARG1,ARG2,ARG3,SARG4,ARG5,ARG6); + PRE_REG_READ6(ssize_t, "recvfrom", + int, s, void *, buf, size_t, len, int, flags, + struct sockaddr *, from, int *, fromlen); + ML_(generic_PRE_sys_recvfrom)(tid, ARG1,ARG2,ARG3,ARG4,ARG5,ARG6); +} + +POST(sys_recvfrom) +{ + vg_assert(SUCCESS); + ML_(generic_POST_sys_recvfrom)(tid, VG_(mk_SysRes_Success)(RES), + ARG1,ARG2,ARG3,ARG4,ARG5,ARG6); +} + +// SYS_accept 30 +// int accept(int s, struct sockaddr * restrict addr, +// socklen_t * restrict addrlen); +PRE(sys_accept) +{ + *flags |= SfMayBlock; + PRINT("sys_accept ( %" FMT_REGWORD "u, %#" FMT_REGWORD "x, %" FMT_REGWORD "u )",ARG1,ARG2,ARG3); + PRE_REG_READ3(int, "accept", + int, s, struct sockaddr *, addr, int, *addrlen); + ML_(generic_PRE_sys_accept)(tid, ARG1,ARG2,ARG3); +} + +POST(sys_accept) +{ + SysRes r; + vg_assert(SUCCESS); + r = ML_(generic_POST_sys_accept)(tid, VG_(mk_SysRes_Success)(RES), + ARG1,ARG2,ARG3); + SET_STATUS_from_SysRes(r); +} + +// SYS_getpeername 31 +// int getpeername(int s, struct sockaddr * restrict name, +// socklen_t * restrict namelen); +PRE(sys_getpeername) +{ + PRINT("sys_getpeername ( %" FMT_REGWORD "u, %#" FMT_REGWORD "x, %#" FMT_REGWORD "x )",ARG1,ARG2,ARG3); + PRE_REG_READ3(int, "getpeername", + int, s, struct sockaddr *, name, socklen_t *, namelen); + ML_(generic_PRE_sys_getpeername)(tid, ARG1,ARG2,ARG3); +} + +POST(sys_getpeername) +{ + vg_assert(SUCCESS); + ML_(generic_POST_sys_getpeername)(tid, VG_(mk_SysRes_Success)(RES), + ARG1,ARG2,ARG3); +} + +// SYS_getsockname 32 +// int getsockname(int s, struct sockaddr * restrict name, +// socklen_t * restrict namelen); +PRE(sys_getsockname) +{ + PRINT("sys_getsockname ( %" FMT_REGWORD "d, %#" FMT_REGWORD "x, %#" FMT_REGWORD "x )",SARG1,ARG2,ARG3); + PRE_REG_READ3(long, "getsockname", + int, s, struct sockaddr *, name, int *, namelen); + ML_(generic_PRE_sys_getsockname)(tid, ARG1,ARG2,ARG3); +} + +POST(sys_getsockname) +{ + vg_assert(SUCCESS); + ML_(generic_POST_sys_getsockname)(tid, VG_(mk_SysRes_Success)(RES), + ARG1,ARG2,ARG3); +} + +// SYS_access 33 +// generic + +// SYS_chflags 34 +// int chflags(const char *path, unsigned long flags) +PRE(sys_chflags) +{ + PRINT("sys_chflags ( %#" FMT_REGWORD "x(%s), 0x%" FMT_REGWORD "x )", ARG1,(char *)ARG1,ARG2); + PRE_REG_READ2(int, "chflags", + const char *, path, unsigned long, flags); + PRE_MEM_RASCIIZ( "chflags(path)", ARG1 ); +} + +// SYS_fchflags 35 +// int fchflags(int fd, unsigned long flags); +PRE(sys_fchflags) +{ + PRINT("sys_fchflags ( %" FMT_REGWORD "u, %" FMT_REGWORD "u )", ARG1,ARG2); + PRE_REG_READ2(int, "fchflags", int, fd, unsigned long, flags); +} + +// SYS_sync 36 +// generic + +// SYS_kill 37 +// generic + +// SYS_getppid 39 +// generic + +// SYS_dup 41 +// generic + +// Pipe on freebsd doesn't have args, and uses dual returns! +// SYS_freebsd10_pipe 42 +// int pipe(void); +PRE(sys_pipe) +{ + PRINT("%s", "sys_pipe ()"); +} + +POST(sys_pipe) +{ + if (!ML_(fd_allowed)(RES, "pipe", tid, True) || + !ML_(fd_allowed)(RESHI, "pipe", tid, True)) { + VG_(close)(RES); + VG_(close)(RESHI); + SET_STATUS_Failure( VKI_EMFILE ); + } else { + if (VG_(clo_track_fds)) { + ML_(record_fd_open_nameless)(tid, RES); + ML_(record_fd_open_nameless)(tid, RESHI); + } + } +} + +// SYS_getegid 43 +// generic + +// SYS_profil 44 +// generic + +// SYS_ktrace 45 +// generic + +// SYS_getgid 47 +// generic + +// SYS_getlogin 49 +// syscall.master refers to namelen and namebuf for the argument names +// man getlogin has just getlogin(void) but also +// int getlogin_r(char *name, int len); +// so let's go with those names +PRE(sys_getlogin) +{ + PRINT("sys_getlogin ( %#" FMT_REGWORD "x, %" FMT_REGWORD "u )",ARG1,ARG2); + PRE_REG_READ2(int, "getlogin", char *, buf, u_int, len); + PRE_MEM_WRITE( "getlogin(name)", ARG1, ARG2 ); +} + +POST(sys_getlogin) +{ + POST_MEM_WRITE(ARG1, ARG2 ); +} + +// SYS_setlogin 50 +// int setlogin(const char *name); +PRE(sys_setlogin) +{ + PRINT("sys_setlogin ( %#" FMT_REGWORD "x )",ARG1); + PRE_REG_READ1(long, "setlogin", char *, buf); + PRE_MEM_RASCIIZ( "setlogin(buf)", ARG1 ); +} + +// SYS_acct 51 +// generic + +// SYS_sigaltstack 53 +// generic + +// SYS_ioctl 54 +// int ioctl(int fd, unsigned long request, ...); +PRE(sys_ioctl) +{ + UInt dir = _VKI_IOC_DIR(ARG2); + UInt size = _VKI_IOC_SIZE(ARG2); + *flags |= SfMayBlock; + // @todo PJF presumably the presence of ARG3 depends on ARG2 + PRINT("sys_ioctl ( %" FMT_REGWORD "u, 0x%" FMT_REGWORD "x, %#" FMT_REGWORD "x )",ARG1,ARG2,ARG3); + PRE_REG_READ3(int, "ioctl", + int, fd, unsigned long, request, unsigned long, arg); + + /* On FreeBSD, ALL ioctl's are IOR/IOW encoded. Just use the default decoder */ + if (SimHintiS(SimHint_lax_ioctls, VG_(clo_sim_hints))) { + /* + * Be very lax about ioctl handling; the only + * assumption is that the size is correct. Doesn't + * require the full buffer to be initialized when + * writing. Without this, using some device + * drivers with a large number of strange ioctl + * commands becomes very tiresome. + */ + } else if (dir == _VKI_IOC_NONE && size > 0) { + static UWord unknown_ioctl[10]; + static Int moans = sizeof(unknown_ioctl) / sizeof(unknown_ioctl[0]); + if (moans > 0 && !VG_(clo_xml)) { + /* Check if have not already moaned for this request. */ + UInt i; + for (i = 0; i < sizeof(unknown_ioctl)/sizeof(unknown_ioctl[0]); i++) { + if (unknown_ioctl[i] == ARG2) { + break; + } + if (unknown_ioctl[i] == 0) { + unknown_ioctl[i] = ARG2; + moans--; + VG_(umsg)("Warning: noted but unhandled ioctl 0x%lx" + " with no direction hints.\n", ARG2); + VG_(umsg)(" This could cause spurious value errors to appear.\n"); + VG_(umsg)(" See README_MISSING_SYSCALL_OR_IOCTL for " + "guidance on writing a proper wrapper.\n" ); + return; + } + } + } + } else { + if ((dir & _VKI_IOC_WRITE) && size > 0) { + PRE_MEM_READ( "ioctl(generic)", ARG3, size); + } + if ((dir & _VKI_IOC_READ) && size > 0) { + PRE_MEM_WRITE( "ioctl(generic)", ARG3, size); + } + } + + // The block below is from Ryan Stone + // https://bitbucket.org/rysto32/valgrind-freebsd/commits/5323c22be9f6c71a00e842c3ddfa1fa8a7feb279 + // however it drags in hundreds of lines of headers into vki-freebsd.h. + // How stable are these structures? -> maintainability is a concern + // Also there are no testcases for this. + // Hence #if 0 +#if 0 + /* Handle specific ioctls which pass structures which may have pointers to other + buffers */ + switch (ARG2 /* request */) { + case VKI_SIOCGIFMEDIA: + if (ARG3) { + struct vki_ifmediareq* imr = (struct vki_ifmediareq*)ARG3; + if (imr->ifm_ulist) { + PRE_MEM_WRITE("ioctl(SIOCGIFMEDIA).ifm_ulist", + (Addr)(imr->ifm_ulist), imr->ifm_count * sizeof(int)); + } + } + break; + + case VKI_PCIOCGETCONF: + if (ARG3) { + struct vki_pci_conf_io* pci = (struct vki_pci_conf_io*)ARG3; + PRE_MEM_READ("ioctl(PCIOCGETCONF).patterns", + (Addr)(pci->patterns), pci->pat_buf_len); + PRE_MEM_WRITE("ioctl(PCIOCGETCONF).matches", + (Addr)(pci->matches), pci->match_buf_len); + } + break; + + case VKI_CAMIOCOMMAND: + if (ARG3) { + union vki_ccb* ccb = (union vki_ccb*)ARG3; + if (ccb->ccb_h.func_code == VKI_XPT_DEV_MATCH) { + PRE_MEM_WRITE("ioctl(CAMIOCOMMAND:XPT_DEV_MATCH).matches", + (Addr)(ccb->cdm.matches), ccb->cdm.match_buf_len); + } else if (ccb->ccb_h.func_code == VKI_XPT_SCSI_IO) { + struct vki_ccb_scsiio* scsiio = (struct vki_ccb_scsiio*)ccb; + if (scsiio->dxfer_len) { + if ((scsiio->ccb_h.flags & VKI_CAM_DIR_MASK) == VKI_CAM_DIR_IN) { + PRE_MEM_WRITE("ioctl(CAMIOCOMMAND:XPT_SCSI_IO).data_ptr", + (Addr)(scsiio->data_ptr), scsiio->dxfer_len); + } else if ((scsiio->ccb_h.flags & VKI_CAM_DIR_MASK) == VKI_CAM_DIR_OUT) { + PRE_MEM_READ("ioctl(CAMIOCOMMAND:XPT_SCSI_IO).data_ptr", + (Addr)(scsiio->data_ptr), scsiio->dxfer_len); + } + } + } else if (ccb->ccb_h.func_code == VKI_XPT_GDEV_TYPE || + ccb->ccb_h.func_code == VKI_XPT_PATH_INQ || + ccb->ccb_h.func_code == VKI_XPT_GET_TRAN_SETTINGS) { + // do nothing + } else { + VG_(message)(Vg_UserMsg, + "Warning: unhandled ioctl CAMIOCOMMAND function 0x%lx\n", + ccb->ccb_h.func_code); + } + } + break; + } +#endif +} + +POST(sys_ioctl) +{ + UInt dir = _VKI_IOC_DIR(ARG2); + UInt size = _VKI_IOC_SIZE(ARG2); + vg_assert(SUCCESS); + if (size > 0 && (dir & _VKI_IOC_READ) + && RES == 0 && ARG3 != (Addr)NULL) { + POST_MEM_WRITE(ARG3, size); + } + +#if 0 + /* Handle specific ioctls which pass structures which may have pointers to other + buffers */ + switch (ARG2 /* request */) { + case VKI_SIOCGIFMEDIA: + if (ARG3) { + struct vki_ifmediareq* imr = (struct vki_ifmediareq*)ARG3; + if (imr->ifm_ulist) { + POST_MEM_WRITE((Addr)(imr->ifm_ulist), imr->ifm_count * sizeof(int)); + } + } + break; + + case VKI_PCIOCGETCONF: + if (ARG3) { + struct vki_pci_conf_io* pci = (struct vki_pci_conf_io*)ARG3; + POST_MEM_WRITE((Addr)(pci->matches), pci->num_matches * sizeof(struct vki_pci_conf)); + } + break; + + case VKI_CAMIOCOMMAND: + if (ARG3) { + union vki_ccb* ccb = (union vki_ccb*)ARG3; + if (ccb->ccb_h.func_code == VKI_XPT_DEV_MATCH) { + POST_MEM_WRITE((Addr)(ccb->cdm.matches), ccb->cdm.num_matches*sizeof(struct vki_dev_match_result)); + } else if (ccb->ccb_h.func_code == VKI_XPT_SCSI_IO) { + struct vki_ccb_scsiio* scsiio = (struct vki_ccb_scsiio*)ccb; + if (scsiio->dxfer_len) { + if ((scsiio->ccb_h.flags & VKI_CAM_DIR_MASK) == VKI_CAM_DIR_IN) { + POST_MEM_WRITE((Addr)(scsiio->data_ptr), scsiio->dxfer_len); + } + } + } + } + break; + } +#endif +} + +// SYS_reboot 55 +// int reboot(int howto); +PRE(sys_reboot) +{ + PRINT("sys_reboot ( %" FMT_REGWORD "d )", SARG1); + PRE_REG_READ1(int, "reboot", int, howto); +} + +// SYS_revoke 56 +// int revoke(const char *path); +PRE(sys_revoke) +{ + PRINT("sys_revoke ( %#" FMT_REGWORD "x(%s) )", ARG1, (char*)ARG1); + PRE_REG_READ1(long, "revoke", const char *, path); + PRE_MEM_RASCIIZ( "revoke(path)", ARG1); +} + +// SYS_symlink 57 +// generic + +static void do_readlink(const HChar* path, HChar *buf, SizeT bufsize, SyscallStatus* status, Bool* curproc_file) +{ + HChar name[30]; + VG_(sprintf)(name, "/proc/%d/file", VG_(getpid)()); + if (ML_(safe_to_deref)(path, 1) + && (VG_(strcmp)(path, name) == 0 + || VG_(strcmp)(path, "/proc/curproc/file") == 0)) { + vg_assert(VG_(resolved_exename)); + Int len = VG_(snprintf)(buf, bufsize, "%s", VG_(resolved_exename)); + SET_STATUS_Success(len); + *curproc_file = True; + } +} + +// SYS_readlink 58 +// ssize_t readlink(const char *restrict path, char *restrict buf, size_t bufsiz); +PRE(sys_readlink) +{ + FUSE_COMPATIBLE_MAY_BLOCK(); + Word saved = SYSNO; + Bool curproc_file = False; + + PRINT("sys_readlink ( %#" FMT_REGWORD "x(%s), %#" FMT_REGWORD "x, %llu )", + ARG1, (char*)(Addr)ARG1, ARG2, (ULong)ARG3); + PRE_REG_READ3(long, "readlink", + const char *, path, char *, buf, int, bufsiz); + PRE_MEM_RASCIIZ( "readlink(path)", ARG1 ); + PRE_MEM_WRITE( "readlink(buf)", ARG2,ARG3 ); + + if (VG_(have_slash_proc) == True) + { + /* + * Handle the case where readlink is looking at /proc/curproc/file or + * /proc/<pid>/file + */ + do_readlink((const HChar *)ARG1, (HChar *)ARG2, (SizeT)ARG3, status, &curproc_file); + } + + if (!curproc_file) { + /* Normal case */ + SET_STATUS_from_SysRes( VG_(do_syscall3)(saved, ARG1, ARG2, ARG3)); + } + if (SUCCESS && RES > 0) { + POST_MEM_WRITE( ARG2, RES ); + } +} + +// SYS_execve 59 +// generic + +// SYS_umask 60 +// generic + +// SYS_chroot 61 +// generic + +// SYS_msync 65 +// generic + +// SYS_vfork 66 +// pid_t vfork(void); +PRE(sys_vfork) +{ + PRINT("%s", "sys_vfork ()"); + PRE_REG_READ0(pid_t, "vfork"); + + /* Pretend vfork == fork. Not true, but will have to do. */ + SET_STATUS_from_SysRes( ML_(do_fork)(tid) ); + if (SUCCESS) { + /* Thread creation was successful; let the child have the chance + to run */ + *flags |= SfYieldAfter; + } +} + +// SYS_sbrk 69 +// void * sbrk(intptr_t incr); +PRE(sys_sbrk) +{ + PRINT("sys_sbrk ( %#" FMT_REGWORD "x )",ARG1); + PRE_REG_READ1(void*, "sbrk", vki_intptr_t, incr); +} + +// SYS_freebsd11_vadvise 72 +// @todo maybe + +// SYS_munmap 73 +// generic + +// SYS_mprotect 74 +// generic + +// SYS_madvise 75 +// generic + +// SYS_mincore 78 +// generic + +// SYS_getgroups 79 +// generic + +// SYS_setgroups 80 +// generic + +// SYS_getpgrp 81 +// generic + +// SYS_setpgid 82 +// generic + +// SYS_setitimer 83 +// generic + +// SYS_swapon 85 +// int swapon(const char *special); +PRE(sys_swapon) +{ + PRINT("sys_swapon ( %#" FMT_REGWORD "x(%s) )", ARG1,(char*)ARG1); + PRE_REG_READ1(int, "swapon", const char*, special ); + PRE_MEM_RASCIIZ( "swapon(special)", ARG1 ); +} + +// SYS_getitimer 86 +// generic + +// SYS_getdtablesize 89 +// int getdtablesize(void); +PRE(sys_getdtablesize) +{ + PRINT("%s", "sys_getdtablesize ( )"); + PRE_REG_READ0(long, "getdtablesize"); +} + +// SYS_dup2 90 +// generic + +// SYS_fcntl 92 +// int fcntl(int fd, int cmd, ...); +PRE(sys_fcntl) +{ + switch (ARG2) { + // These ones ignore ARG3. + case VKI_F_GETFD: + case VKI_F_GETFL: + case VKI_F_GETOWN: + case VKI_F_GET_SEALS: + case VKI_F_ISUNIONSTACK: + PRINT("sys_fcntl ( %" FMT_REGWORD "d, %" FMT_REGWORD "d )", SARG1,SARG2); + PRE_REG_READ2(int, "fcntl", int, fd, int, cmd); + break; + + // These ones use ARG3 as "arg". + case VKI_F_DUPFD: + case VKI_F_DUPFD_CLOEXEC: + case VKI_F_SETFD: + case VKI_F_SETFL: + case VKI_F_SETOWN: + case VKI_F_READAHEAD: + case VKI_F_RDAHEAD: + case VKI_F_ADD_SEALS: + PRINT("sys_fcntl[ARG3=='arg'] ( %" FMT_REGWORD "d, %" FMT_REGWORD "d, %" FMT_REGWORD "d )", SARG1,SARG2,SARG3); + PRE_REG_READ3(int, "fcntl", + int, fd, int, cmd, int, arg); + break; + + // These ones use ARG3 as "lock" - obsolete. + case VKI_F_OSETLKW: + *flags |= SfMayBlock; + /* FALLTHROUGH */ + case VKI_F_OGETLK: + case VKI_F_OSETLK: + PRINT("sys_fcntl[ARG3=='lock'] ( %" FMT_REGWORD "u, %" FMT_REGWORD "u, %#" FMT_REGWORD "x )", ARG1,ARG2,ARG3); + PRE_REG_READ3(int, "fcntl", + int, fd, int, cmd, + struct oflock *, lock); + break; + + // This one uses ARG3 as "oldd" and ARG4 as "newd". + case VKI_F_DUP2FD: + case VKI_F_DUP2FD_CLOEXEC: + PRINT("sys_fcntl[ARG3=='oldd', ARG4=='newd'] ( %" FMT_REGWORD "u, %" FMT_REGWORD "u, %" FMT_REGWORD "u, %" FMT_REGWORD "u )", + ARG1,ARG2,ARG3,ARG4); + PRE_REG_READ4(int, "fcntl", + int, fd, int, cmd, + unsigned long, oldd, unsigned long, newd); + break; + + // These ones use ARG3 as "lock". + case VKI_F_SETLKW: + *flags |= SfMayBlock; + /* FALLTHROUGH */ + case VKI_F_GETLK: + case VKI_F_SETLK: + case VKI_F_SETLK_REMOTE: + PRINT("sys_fcntl[ARG3=='lock'] ( %" FMT_REGWORD "u, %" FMT_REGWORD "u, %#" FMT_REGWORD "x )", ARG1,ARG2,ARG3); + PRE_REG_READ3(int, "fcntl", + int, fd, int, cmd, + struct flock *, lock); + break; + case VKI_F_KINFO: + PRINT("sys_fcntl[ARG3=='kinfo_file'] ( %" FMT_REGWORD "u, %" FMT_REGWORD "u, %#" FMT_REGWORD "x )", ARG1,ARG2,ARG3); + PRE_REG_READ3(int, "fcntl", + int, fd, int, cmd, + struct vki_kinfo_file *, kinfo); + if (ARG3) { + struct vki_kinfo_file* p_kinfo_file = (struct vki_kinfo_file*)ARG3; + PRE_MEM_WRITE("fcntl(ARG3=='kinfo_file)", ARG3, p_kinfo_file->vki_kf_structsize); + } + break; + + default: + PRINT("sys_fcntl[UNKNOWN] ( %lu, %lu, %lu )", ARG1,ARG2,ARG3); + I_die_here; + } +} + +POST(sys_fcntl) +{ + vg_assert(SUCCESS); + if (ARG2 == VKI_F_DUPFD) { + if (!ML_(fd_allowed)(RES, "fcntl(DUPFD)", tid, True)) { + VG_(close)(RES); + SET_STATUS_Failure( VKI_EMFILE ); + } else { + if (VG_(clo_track_fds)) { + ML_(record_fd_open_named)(tid, RES); + } + } + } else if (ARG2 == VKI_F_DUPFD_CLOEXEC) { + if (!ML_(fd_allowed)(RES, "fcntl(DUPFD_CLOEXEC)", tid, True)) { + VG_(close)(RES); + SET_STATUS_Failure( VKI_EMFILE ); + } else { + if (VG_(clo_track_fds)) { + ML_(record_fd_open_named)(tid, RES); + } + } + } +} + +// SYS_select 93 +// generic + +// SYS_fsync 95 +// generic + +// SYS_setpriority 9 +// generic + +// SYS_socket 97 +// int socket(int domain, int type, int protocol); +PRE(sys_socket) +{ + PRINT("sys_socket ( %" FMT_REGWORD "d, %" FMT_REGWORD "d, %" FMT_REGWORD "d )",SARG1,SARG2,SARG3); + PRE_REG_READ3(int, "socket", int, domain, int, type, int, protocol); +} + +POST(sys_socket) +{ + SysRes r; + vg_assert(SUCCESS); + r = ML_(generic_POST_sys_socket)(tid, VG_(mk_SysRes_Success)(RES)); + SET_STATUS_from_SysRes(r); +} + +// SYS_connect 98 +// int connect(int s, const struct sockaddr *name, socklen_t namelen); +PRE(sys_connect) +{ + *flags |= SfMayBlock; + PRINT("sys_connect ( %" FMT_REGWORD "u, %#" FMT_REGWORD "x, %" FMT_REGWORD "u )",ARG1,ARG2,ARG3); + PRE_REG_READ3(int, "connect", + int, s, const struct sockaddr *, name, int, namelen); + ML_(generic_PRE_sys_connect)(tid, ARG1,ARG2,ARG3); +} + +// SYS_getpriority 100 +// generic + +// SYS_bind 104 +// int bind(int s, const struct sockaddr *addr, socklen_t addrlen); +PRE(sys_bind) +{ + PRINT("sys_bind ( %" FMT_REGWORD "u, %#" FMT_REGWORD "x, %" FMT_REGWORD "u )",ARG1,ARG2,ARG3); + PRE_REG_READ3(int, "bind", + int, s, struct sockaddr *, addr, int, addrlen); + ML_(generic_PRE_sys_bind)(tid, ARG1,ARG2,ARG3); +} + +// SYS_setsockopt 105 +// int setsockopt(int s, int level, int optname, const void *optval, +// socklen_t optlen); +PRE(sys_setsockopt) +{ + PRINT("sys_setsockopt ( %" FMT_REGWORD "d, %" FMT_REGWORD "d, %" FMT_REGWORD "d, %#" FMT_REGWORD "x, %" FMT_REGWORD "u )",SARG1,SARG2,SARG3,ARG4,ARG5); + PRE_REG_READ5(int, "setsockopt", + int, s, int, level, int, optname, + const void *, optval, vki_socklen_t, optlen); + ML_(generic_PRE_sys_setsockopt)(tid, ARG1,ARG2,ARG3,ARG4,ARG5); +} + +// SYS_listen 106 +// int listen(int s, int backlog); +PRE(sys_listen) +{ + PRINT("sys_listen ( %" FMT_REGWORD "d, %" FMT_REGWORD "d )",SARG1,SARG2); + PRE_REG_READ2(int, "listen", int, s, int, backlog); +} + +//SYS_gettimeofday 116 +// generic + +// SYS_getrusage 117 +// generic + +// SYS_getsockopt 118 +// int getsockopt(int s, int level, int optname, void * restrict optval, +// socklen_t * restrict optlen); +PRE(sys_getsockopt) +{ + Addr optval_p = ARG4; + Addr optlen_p = ARG5; + PRINT("sys_getsockopt ( %" FMT_REGWORD "u, %" FMT_REGWORD "u, %" FMT_REGWORD "u, %#" FMT_REGWORD "x, %#" FMT_REGWORD "x )",ARG1,ARG2,ARG3,ARG4,ARG5); + PRE_REG_READ5(int, "getsockopt", + int, s, int, level, int, optname, + void *, optval, int, *optlen); + if (optval_p != (Addr)NULL) { + ML_(buf_and_len_pre_check) ( tid, optval_p, optlen_p, + "getsockopt(optval)", + "getsockopt(optlen)" ); + } +} + +POST(sys_getsockopt) +{ + Addr optval_p = ARG4; + Addr optlen_p = ARG5; + vg_assert(SUCCESS); + if (optval_p != (Addr)NULL) { + ML_(buf_and_len_post_check) ( tid, VG_(mk_SysRes_Success)(RES), + optval_p, optlen_p, + "getsockopt(optlen_out)" ); + } +} + +// SYS_readv 120 +// generic + +// SYS_writev 121 +// generic + +// SYS_settimeofday 122 +// generic + +// SYS_fchown 123 +// generic + +// SYS_fchmod 124 +// generic + +// SYS_setreuid 126 +// generic + +// SYS_setregid 127 +// generic + +// SYS_rename 128 +// generic + +// SYS_flock 131 +// generic + +// SYS_mkfifo 132 +// int mkfifo(const char *path, mode_t mode); +PRE(sys_mkfifo) +{ + PRINT("sys_mkfifo ( %#" FMT_REGWORD "x(%s), 0x%" FMT_REGWORD "x, 0x%" FMT_REGWORD "x )", ARG1, (char *)ARG1, ARG2, ARG3 ); + PRE_REG_READ2(int, "mkfifo", const char *, path, int, mode); + PRE_MEM_RASCIIZ( "mkfifo(path)", ARG1 ); +} + +// SYS_sendto 133 +// ssize_t sendto(int s, const void *msg, size_t len, int flags, +// const struct sockaddr *to, socklen_t tolen); +PRE(sys_sendto) +{ + *flags |= SfMayBlock; + PRINT("sys_sendto ( %" FMT_REGWORD "u, %#" FMT_REGWORD "x, %" FMT_REGWORD "u, %" FMT_REGWORD "u, %#" FMT_REGWORD "x, %" FMT_REGWORD "u )",ARG1,ARG2,ARG3,ARG4,ARG5,ARG6); + PRE_REG_READ6(ssize_t, "sendto", + int, s, const void *, msg, int, len, + int, flags, + const struct sockaddr *, to, socklen_t, tolen); + ML_(generic_PRE_sys_sendto)(tid, ARG1,ARG2,ARG3,ARG4,ARG5,ARG6); +} + +// SYS_shutdown 134 +// int shutdown(int s, int how); +PRE(sys_shutdown) +{ + *flags |= SfMayBlock; + PRINT("sys_shutdown ( %" FMT_REGWORD "u, %" FMT_REGWORD "u )",ARG1,ARG2); + PRE_REG_READ2(int, "shutdown", int, s, int, how); +} + +// SYS_socketpair 135 +// int socketpair(int domain, int type, int protocol, int *sv); +PRE(sys_socketpair) +{ + PRINT("sys_socketpair ( %" FMT_REGWORD "u, %" FMT_REGWORD "u, %" FMT_REGWORD "u, %#" FMT_REGWORD "x )",ARG1,ARG2,ARG3,ARG4); + PRE_REG_READ4(int, "socketpair", + int, domain, int, type, int, protocol, int *, sv); + ML_(generic_PRE_sys_socketpair)(tid, ARG1,ARG2,ARG3,ARG4); +} + +POST(sys_socketpair) +{ + vg_assert(SUCCESS); + ML_(generic_POST_sys_socketpair)(tid, VG_(mk_SysRes_Success)(RES), + ARG1,ARG2,ARG3,ARG4); +} + +// SYS_mkdir 136 +// generic + +// SYS_rmdir 137 +// generic + +// SYS_utimes 138 +// generic + +// SYS_adjtime 140 +// int adjtime(const struct timeval *delta, struct timeval *olddelta); +PRE(sys_adjtime) +{ + PRINT("sys_adjtime ( %#" FMT_REGWORD "x, %#" FMT_REGWORD "x )",ARG1,ARG2); + PRE_REG_READ2(int, "adjtime", + const struct vki_timeval *, delta, struct vki_timeval *, olddelta); + PRE_MEM_READ("adjtime(delta)", ARG1, sizeof(struct vki_timeval)); + if (ARG2) { + PRE_MEM_WRITE("adjtime(olddelta)", ARG1, sizeof(struct vki_timeval)); + } +} + +POST(sys_adjtime) +{ + if (ARG2) { + POST_MEM_WRITE(ARG1, sizeof(struct vki_timeval)); + } +} + +// SYS_setsid 147 +// generic + +// SYS_quotactl 148 +/* int quotactl(const char *path, int cmd, int id, void *addr); */ +PRE(sys_quotactl) +{ + PRINT("sys_quotactl ( %#" FMT_REGWORD "x, %" FMT_REGWORD "u, %" FMT_REGWORD "u, %#" FMT_REGWORD "x )", ARG1,ARG2,ARG3, ARG4); + switch (ARG2) { + case VKI_Q_QUOTAON: + case VKI_Q_SETQUOTA: + case VKI_Q_SETUSE: + + case VKI_Q_GETQUOTASIZE: + PRE_REG_READ4(int, "quotactl", + const char *, path, int, cmd, int, id, + void *, addr); + PRE_MEM_RASCIIZ( "quotactl(path)", ARG1 ); + break; + case VKI_Q_GETQUOTA: + if (VG_(tdict).track_pre_reg_read) { + \ + PRRSN; + PRA1("quotactl",const char*,path); + PRA2("quotactl",int,cmd); + PRA4("quotactl",void*,addr); + } + break; + case VKI_Q_QUOTAOFF: + case VKI_Q_SYNC: + PRE_REG_READ2(int, "quotactl", + const char *, path, int, cmd); + break; + default: + break; + } +} + +// SYS_nlm_syscall 154 +// syscall.master says ; 154 is initialised by the NLM code, if present. +// @todo + +// SYS_nfssvc 155 +// int nfssvc(int flags, void *argstructp); +// lengthy manpage, at least 3 types of struct that argstructp can point to +// @todo + +// SYS_lgetfh 160 +// int lgetfh(const char *path, fhandle_t *fhp); +PRE(sys_lgetfh) +{ + PRINT("sys_lgetfh ( %#" FMT_REGWORD "x, %" FMT_REGWORD "x ", ARG1, ARG2); + PRE_REG_READ2(int, "lgetfh", const char*, path, vki_fhandle_t*, fhp); + PRE_MEM_RASCIIZ( "lgetfh(path)", ARG1 ); + PRE_MEM_WRITE("lgetfh(fhp)", ARG2, sizeof(vki_fhandle_t)); +} + +POST(sys_lgetfh) +{ + POST_MEM_WRITE(ARG2, sizeof(vki_fhandle_t)); +} + +// SYS_getfh 161 +// int getfh(const char *path, fhandle_t *fhp); +PRE(sys_getfh) +{ + PRINT("sys_getfh ( %#" FMT_REGWORD "x, %" FMT_REGWORD "x ", ARG1, ARG2); + PRE_REG_READ2(int, "getfh", const char*, path, vki_fhandle_t*, fhp); + PRE_MEM_RASCIIZ( "getfh(path)", ARG1 ); + PRE_MEM_WRITE("getfh(fhp)", ARG2, sizeof(vki_fhandle_t)); +} + +POST(sys_getfh) +{ + POST_MEM_WRITE(ARG2, sizeof(vki_fhandle_t)); +} + +#if (FREEBSD_VERS <= FREEBSD_10) +// 162 +// int getdomainname(char *domainname, int len); +PRE(sys_freebsd4_getdomainname) +{ + PRINT("sys_freebsd4_getdomainname ( %#" FMT_REGWORD "x, %" FMT_REGWORD "u )",ARG1,ARG2); + PRE_REG_READ2(int, "getdomainname", + char *, domainname, int, len); + PRE_MEM_WRITE( "getdomainname(domainname)", ARG1, ARG2 ); +} + +POST(sys_freebsd4_getdomainname) +{ + if (ARG1 != 0) { + POST_MEM_WRITE( ARG1, ARG2 ); + } +} + +// 163 +// int setdomainname(char *domainname, int len); +PRE(sys_freebsd4_setdomainname) +{ + PRINT("sys_freebsd4_setdomainname ( %#" FMT_REGWORD "x )",ARG1); + PRE_REG_READ2(int, "setdomainname", char *, domainname, int, len); + PRE_MEM_RASCIIZ( "setdomainname(domainname)", ARG1 ); +} + +// 164 +// int uname(struct utsname *name); +PRE(sys_freebsd4_uname) +{ + PRINT("sys_freebsd4_uname ( %#" FMT_REGWORD "x )", ARG1); + PRE_REG_READ1(int, "uname", struct utsname *, name); + PRE_MEM_WRITE( "uname(name)", ARG1, sizeof(struct vki_utsname) ); +} + +POST(sys_freebsd4_uname) +{ + if (ARG1 != 0) { + POST_MEM_WRITE( ARG1, sizeof(struct vki_utsname) ); + } +} +#endif + +// SYS_sysarch 165 +// x86/amd64 + +// SYS_rtprio 166 +PRE(sys_rtprio) +{ + PRINT( "sys_rtprio ( %" FMT_REGWORD "u, %" FMT_REGWORD "u, %#" FMT_REGWORD "x )", ARG1, ARG2, ARG3 ); + PRE_REG_READ3(int, "rtprio", + int, function, pid_t, pid, struct rtprio *, rtp); + if (ARG1 == VKI_RTP_SET) { + PRE_MEM_READ( "rtprio(rtp#set)", ARG3, sizeof(struct vki_rtprio)); + } else if (ARG1 == VKI_RTP_LOOKUP) { + PRE_MEM_WRITE( "rtprio(rtp#lookup)", ARG3, sizeof(struct vki_rtprio)); + } else { + /* PHK ?? */ + } +} + +POST(sys_rtprio) +{ + if (ARG1 == VKI_RTP_LOOKUP && RES == 0) { + POST_MEM_WRITE( ARG3, sizeof(struct vki_rtprio)); + } +} + +// freebsd6_pread 173 FREEBSD_VERS <= 10 +// x86/amd64 + +// freebsd6_pwrite 174 FREEBSD_VERS <= 10 +// x86/amd64 + +// SYS_setfib 175 +// int setfib(int fib); +PRE(sys_setfib) +{ + PRINT("sys_setfib ( %" FMT_REGWORD "d )", SARG1); + PRE_REG_READ1(int, "setfib", int, fib); +} + +// SYS_ntp_adjtime 176 +// int ntp_adjtime(struct timex *); +// @todo + +// SYS_setgid 181 +// generic + +// SYS_setegid 182 +// int setegid(gid_t egid); +PRE(sys_setegid) +{ + PRINT("sys_setegid ( %" FMT_REGWORD "u )", ARG1); + PRE_REG_READ1(int, "setegid", vki_gid_t, gid); +} + +// SYS_seteuid 183 +// int seteuid(uid_t euid); +PRE(sys_seteuid) +{ + PRINT("sys_seteuid ( %" FMT_REGWORD "u )", ARG1); + PRE_REG_READ1(long, "seteuid", vki_uid_t, uid); +} + + +#if (FREEBSD_VERS >= FREEBSD_12) + +// SYS_freebsd11_stat 188 +// int stat(char *path, struct freebsd11_stat *sb); +PRE(sys_freebsd11_stat) +{ + PRINT("sys_freebsd11_stat ( %#" FMT_REGWORD "x(%s), %#" FMT_REGWORD "x )",ARG1,(char *)ARG1,ARG2); + PRE_REG_READ2(int, "stat", char *, path, struct freebsd11_stat *, sb); + PRE_MEM_RASCIIZ( "stat(path)", ARG1 ); + PRE_MEM_WRITE( "stat(sb)", ARG2, sizeof(struct vki_freebsd11_stat) ); +} + +POST(sys_freebsd11_stat) +{ + POST_MEM_WRITE( ARG2, sizeof(struct vki_freebsd11_stat) ); +} + +// SYS_freebsd11_fstat 189 +// int fstat(int fd, struct stat *sb); +PRE(sys_freebsd11_fstat) +{ + PRINT("sys_freebsd11_fstat ( %" FMT_REGWORD "d, %#" FMT_REGWORD "x )",SARG1,ARG2); + PRE_REG_READ2(int, "fstat", int, fd, struct stat *, sb); + PRE_MEM_WRITE( "fstat(sb)", ARG2, sizeof(struct vki_freebsd11_stat) ); +} + +POST(sys_freebsd11_fstat) +{ + POST_MEM_WRITE( ARG2, sizeof(struct vki_freebsd11_stat) ); +} + +// SYS_freebsd11_lstat 190 +// int lstat(const char * restrict path, struct stat * restrict sb); +PRE(sys_freebsd11_lstat) +{ + PRINT("sys_freebsd11_lstat ( %#" FMT_REGWORD "x(%s), %#" FMT_REGWORD "x )",ARG1,(char *)ARG1,ARG2); + PRE_REG_READ2(sb, "lstat", const char *, path, struct freebsd11_stat *, sb); + PRE_MEM_RASCIIZ( "lstat(path)", ARG1 ); + PRE_MEM_WRITE( "lstat(sb)", ARG2, sizeof(struct vki_freebsd11_stat) ); +} + +POST(sys_freebsd11_lstat) +{ + vg_assert(SUCCESS); + if (RES == 0) { + POST_MEM_WRITE( ARG2, sizeof(struct vki_freebsd11_stat) ); + } +} + +#else + +PRE(sys_stat) +{ + PRINT("sys_stat ( %#" FMT_REGWORD "x(%s), %#" FMT_REGWORD "x )",ARG1,(char *)ARG1,ARG2); + PRE_REG_READ2(int, "stat", char *, path, struct stat *, sb); + PRE_MEM_RASCIIZ( "stat(path)", ARG1 ); + PRE_MEM_WRITE( "stat(sb)", ARG2, sizeof(struct vki_freebsd11_stat) ); +} + +POST(sys_stat) +{ + POST_MEM_WRITE( ARG2, sizeof(struct vki_freebsd11_stat) ); +} + + +PRE(sys_fstat) +{ + PRINT("sys_fstat ( %" FMT_REGWORD "d, %#" FMT_REGWORD "x )",SARG1,ARG2); + PRE_REG_READ2(int, "fstat", int, fd, struct stat *, sb); + PRE_MEM_WRITE( "fstat(sb)", ARG2, sizeof(struct vki_freebsd11_stat) ); +} + +POST(sys_fstat) +{ + POST_MEM_WRITE( ARG2, sizeof(struct vki_freebsd11_stat) ); +} + +PRE(sys_lstat) +{ + PRINT("sys_lstat ( %#" FMT_REGWORD "x(%s), %#" FMT_REGWORD "x )",ARG1,(char *)ARG1,ARG2); + PRE_REG_READ2(int, "lstat", const char *, path, struct stat *, sb); + PRE_MEM_RASCIIZ( "lstat(path)", ARG1 ); + PRE_MEM_WRITE( "lstat(sb)", ARG2, sizeof(struct vki_freebsd11_stat) ); +} + +POST(sys_lstat) +{ + vg_assert(SUCCESS); + if (RES == 0) { + POST_MEM_WRITE( ARG2, sizeof(struct vki_freebsd11_stat) ); + } +} + +#endif + +// SYS_pathconf 191 +// long pathconf(const char *path, int name); +PRE(sys_pathconf) +{ + PRINT("sys_pathconf ( %#" FMT_REGWORD "x(%s), %" FMT_REGWORD "u )",ARG1,(char *)ARG1,ARG2); + PRE_REG_READ2(long, "pathconf", char *, path, int, name); + PRE_MEM_RASCIIZ( "pathconf(path)", ARG1 ); +} + +// SYS_fpathconf 192 +// long fpathconf(int fd, int name); +PRE(sys_fpathconf) +{ + PRINT("sys_fpathconf ( %" FMT_REGWORD "u, %" FMT_REGWORD "u )",ARG1,ARG2); + PRE_REG_READ2(long, "fpathconf", int, fd, int, name); +} + +// SYS_getrlimit 194 +// generic + +// SYS_setrlimit 195 +// generic + + +// SYS_freebsd11_getdirentries 196 +// int getdirentries(int fd, char *buf, int nbytes, long *basep); +#if (FREEBSD_VERS >= FREEBSD_12) +PRE(sys_freebsd11_getdirentries) +{ + *flags |= SfMayBlock; + PRINT("sys_freebsd11_getdirentries ( %" FMT_REGWORD "u, %#" FMT_REGWORD "x, %" FMT_REGWORD "u )", ARG1,ARG2,ARG3); + PRE_REG_READ4(int, "getdirentries", + int, fd, char *, buf, + int, nbytes, + long *, basep); + PRE_MEM_WRITE( "getdirentries(buf)", ARG2, ARG3 ); + if (ARG4) { + PRE_MEM_WRITE( "getdirentries(basep)", ARG4, sizeof(long) ); + } +} + +POST(sys_freebsd11_getdirentries) +{ + vg_assert(SUCCESS); + if (RES > 0) { + POST_MEM_WRITE( ARG2, RES ); + if ( ARG4 != 0 ) { + POST_MEM_WRITE( ARG4, sizeof (long)); + } + } +} +#else +PRE(sys_getdirentries) +{ + *flags |= SfMayBlock; + PRINT("sys_getdirentries ( %" FMT_REGWORD "u, %#" FMT_REGWORD "x, %" FMT_REGWORD "u )", ARG1,ARG2,ARG3); + PRE_REG_READ4(int, "getdirentries", + int, fd, char *, buf, + int, nbytes, + long *, basep); + PRE_MEM_WRITE( "getdirentries(buf)", ARG2, ARG3 ); + if (ARG4) + PRE_MEM_WRITE( "getdirentries(basep)", ARG4, sizeof(long) ); +} + +POST(sys_getdirentries) +{ + vg_assert(SUCCESS); + if (RES > 0) { + POST_MEM_WRITE( ARG2, RES ); + if ( ARG4 != 0 ) + POST_MEM_WRITE( ARG4, sizeof (long)); + } +} +#endif + +// SYS_freebsd6_mmap 197 +// amd64 / x86 + + +// SYS___syscall 198 +// special handling + +// freebsd6_lseek 199 FREEBSD_VERS <= 10 +// x86/amd64 + +// freebsd6_truncate 200 FREEBSD_VERS <= 10 +// x86/amd64 + +// freebsd6_ftruncate 201 FREEBSD_VERS <= 10 +// x86/amd64 + +static Bool sysctl_kern_ps_strings(SizeT* out, SizeT* outlen) +{ + Word tmp = -1; + const struct auxv *cauxv; + + for (cauxv = (struct auxv*)VG_(client_auxv); cauxv->a_type != VKI_AT_NULL; cauxv++) { + if (cauxv->a_type == VKI_AT_PS_STRINGS) { + tmp = (Word)cauxv->u.a_ptr; + + *out = tmp; + *outlen = sizeof(size_t); + return True; + } + } + return False; +} + +static void sysctl_kern_usrstack(SizeT* out, SizeT* outlen) +{ + *out = VG_(get_usrstack)(); + *outlen = sizeof(ULong); +} + +static Bool sysctl_kern_proc_pathname(HChar *out, SizeT *len) +{ + const HChar *exe_name = VG_(resolved_exename); + + if (!len) { + return False; + } + + if (!out) { + HChar tmp[VKI_PATH_MAX]; + if (!VG_(realpath)(exe_name, tmp)) { + return False; + } + *len = VG_(strlen)(tmp)+1; + return True; + } + + if (!VG_(realpath)(exe_name, out)) { + return False; + } + + *len = VG_(strlen)(out)+1; + return True; +} + +// SYS___sysctl 202 +/* int __sysctl(int *name, u_int namelen, void *oldp, size_t *oldlenp, void *newp, size_t newlen); */ +/* ARG1 ARG2 ARG3 ARG4 ARG5 ARG6 */ +PRE(sys___sysctl) +{ + PRINT("sys_sysctl ( %#" FMT_REGWORD "x, %" FMT_REGWORD "d, %#" FMT_REGWORD "x, %#" FMT_REGWORD "x, %#" FMT_REGWORD "x, %" FMT_REGWORD "u )", ARG1,SARG2,ARG3,ARG4,ARG5,ARG6 ); + + int* name = (int*)ARG1; + if (ML_(safe_to_deref)(name, sizeof(int))) { + PRINT("\nmib[0]: "); + if (SARG2 >= 1) { + switch (name[0]) { + case 0: // CTL_UNSPEC + PRINT("unspec"); + break; + case 1: // CTL_KERN + PRINT("kern");... [truncated message content] |
|
From: Paul F. <pa...@so...> - 2023-08-27 14:14:44
|
https://sourceware.org/git/gitweb.cgi?p=valgrind.git;h=e6ee535c1064663ce1f5c2a96388f239bfd575be commit e6ee535c1064663ce1f5c2a96388f239bfd575be Author: Paul Floyd <pj...@wa...> Date: Sun Aug 27 16:14:00 2023 +0200 FreeBSD: add 2 new _umtx_op op codes for FreeBSD 14 Diff: --- coregrind/m_syswrap/syswrap-freebsd.c | 31 ++++++++++++++++++++- include/vki/vki-freebsd.h | 51 ++++++++++++++++++----------------- 2 files changed, 57 insertions(+), 25 deletions(-) diff --git a/coregrind/m_syswrap/syswrap-freebsd.c b/coregrind/m_syswrap/syswrap-freebsd.c index a59872b3c9..17abf132b6 100644 --- a/coregrind/m_syswrap/syswrap-freebsd.c +++ b/coregrind/m_syswrap/syswrap-freebsd.c @@ -4607,6 +4607,27 @@ PRE(sys__umtx_op) struct umtx_robust_lists_params *, obj, int, op, unsigned long, flags); PRE_MEM_READ( "_umtx_op_robust_lists(mutex)", ARG3, sizeof(struct vki_umtx_robust_lists_params) ); break; +#if (FREEBSD_VERS >= FREEBSD_14) + case VKI_UMTX_OP_GET_MIN_TIMEOUT: + PRINT( "sys__umtx_op ( GET_MIN_TIMEOUT, %#" FMT_REGWORD "x)", ARG4); + // bit of a pain just reads args 2 and 4 + if (VG_(tdict).track_pre_reg_read) { + PRRSN; + PRA2("_umtx_op_get_min_timeout",int,op); + PRA4("_umtx_op_get_min_timeout",long int*,timeout); + } + PRE_MEM_WRITE( "_umtx_op_get_min_timout(uaddr)", ARG4, sizeof(long int) ); + break; + case VKI_UMTX_OP_SET_MIN_TIMEOUT: + PRINT( "sys__umtx_op ( SET_MIN_TIMEOUT, %" FMT_REGWORD "u)", ARG3); + // bit of a pain just reads args 2 and 3 + if (VG_(tdict).track_pre_reg_read) { + PRRSN; + PRA2("_umtx_op_set_min_timeout",int,op); + PRA3("_umtx_op_set_min_timeout",unsigned long,timeout); + } + break; +#endif default: VG_(umsg)("WARNING: _umtx_op unsupported value.\n"); PRINT( "sys__umtx_op ( %#" FMT_REGWORD "x, %" FMT_REGWORD "u(UNKNOWN), %" FMT_REGWORD "u, %#" FMT_REGWORD "x, %#" FMT_REGWORD "x )", ARG1, ARG2, ARG3, ARG4, ARG5); @@ -4673,6 +4694,14 @@ POST(sys__umtx_op) break; case VKI_UMTX_OP_SHM: case VKI_UMTX_OP_ROBUST_LISTS: + break; +#if (FREEBSD_VERS >= FREEBSD_14 || 1) + case VKI_UMTX_OP_GET_MIN_TIMEOUT: + POST_MEM_WRITE( ARG4, sizeof(long int) ); + break; + case VKI_UMTX_OP_SET_MIN_TIMEOUT: + break; +#endif default: break; } @@ -4957,7 +4986,7 @@ PRE(sys_sctp_generic_recvmsg) if (ARG4 != (Addr)NULL) { ML_(buf_and_len_pre_check) (tid, ARG4, ARG5, - "sctp_generic_recvmsg(from)", + "sctp_generic_recvmsg(from)", "sctp_generic_recvmsg(fromlen_in)"); } diff --git a/include/vki/vki-freebsd.h b/include/vki/vki-freebsd.h index f9ca51c036..92ca8a6878 100644 --- a/include/vki/vki-freebsd.h +++ b/include/vki/vki-freebsd.h @@ -2047,34 +2047,37 @@ struct vki_umtx_robust_lists_params { vki_uintptr_t robust_inact_offset; }; -#define VKI_UMTX_OP_LOCK 0 -#define VKI_UMTX_OP_UNLOCK 1 -#define VKI_UMTX_OP_WAIT 2 -#define VKI_UMTX_OP_WAKE 3 -#define VKI_UMTX_OP_MUTEX_TRYLOCK 4 -#define VKI_UMTX_OP_MUTEX_LOCK 5 -#define VKI_UMTX_OP_MUTEX_UNLOCK 6 -#define VKI_UMTX_OP_SET_CEILING 7 -#define VKI_UMTX_OP_CV_WAIT 8 -#define VKI_UMTX_OP_CV_SIGNAL 9 -#define VKI_UMTX_OP_CV_BROADCAST 10 -#define VKI_UMTX_OP_WAIT_UINT 11 -#define VKI_UMTX_OP_RW_RDLOCK 12 -#define VKI_UMTX_OP_RW_WRLOCK 13 -#define VKI_UMTX_OP_RW_UNLOCK 14 -#define VKI_UMTX_OP_WAIT_UINT_PRIVATE 15 -#define VKI_UMTX_OP_WAKE_PRIVATE 16 -#define VKI_UMTX_OP_MUTEX_WAIT 17 -#define VKI_UMTX_OP_MUTEX_WAKE 18 /* deprecated */ -#define VKI_UMTX_OP_SEM_WAIT 19 -#define VKI_UMTX_OP_SEM_WAKE 20 -#define VKI_UMTX_OP_NWAKE_PRIVATE 21 -#define VKI_UMTX_OP_MUTEX_WAKE2 22 +#define VKI_UMTX_OP_LOCK 0 +#define VKI_UMTX_OP_UNLOCK 1 +#define VKI_UMTX_OP_WAIT 2 +#define VKI_UMTX_OP_WAKE 3 +#define VKI_UMTX_OP_MUTEX_TRYLOCK 4 +#define VKI_UMTX_OP_MUTEX_LOCK 5 +#define VKI_UMTX_OP_MUTEX_UNLOCK 6 +#define VKI_UMTX_OP_SET_CEILING 7 +#define VKI_UMTX_OP_CV_WAIT 8 +#define VKI_UMTX_OP_CV_SIGNAL 9 +#define VKI_UMTX_OP_CV_BROADCAST 10 +#define VKI_UMTX_OP_WAIT_UINT 11 +#define VKI_UMTX_OP_RW_RDLOCK 12 +#define VKI_UMTX_OP_RW_WRLOCK 13 +#define VKI_UMTX_OP_RW_UNLOCK 14 +#define VKI_UMTX_OP_WAIT_UINT_PRIVATE 15 +#define VKI_UMTX_OP_WAKE_PRIVATE 16 +#define VKI_UMTX_OP_MUTEX_WAIT 17 +#define VKI_UMTX_OP_MUTEX_WAKE 18 /* deprecated */ +#define VKI_UMTX_OP_SEM_WAIT 19 +#define VKI_UMTX_OP_SEM_WAKE 20 +#define VKI_UMTX_OP_NWAKE_PRIVATE 21 +#define VKI_UMTX_OP_MUTEX_WAKE2 22 #define VKI_UMTX_OP_SEM2_WAIT 23 #define VKI_UMTX_OP_SEM2_WAKE 24 #define VKI_UMTX_OP_SHM 25 #define VKI_UMTX_OP_ROBUST_LISTS 26 -#define VKI_UMTX_OP_MAX 27 +#if (FREEBSD_VERS >= FREEBSD_14) +#define VKI_UMTX_OP_GET_MIN_TIMEOUT 27 +#define VKI_UMTX_OP_SET_MIN_TIMEOUT 28 +#endif //---------------------------------------------------------------------- |
|
From: Paul F. <pa...@so...> - 2023-08-27 12:58:59
|
https://sourceware.org/git/gitweb.cgi?p=valgrind.git;h=9f28b44348a0467b6026a099a224ef96f83181d7 commit 9f28b44348a0467b6026a099a224ef96f83181d7 Author: Paul Floyd <pj...@wa...> Date: Sun Aug 27 16:57:24 2023 +0200 regtest: fix compiler warnings with clang 16 Mostly warnings about deprecated use of K&R function definitions. Diff: --- drd/tests/dlopen_lib.c | 2 +- memcheck/tests/vcpu_fbench.c | 32 ++++++++++---------------------- none/tests/unit_debuglog.c | 4 +++- perf/fbench.c | 32 ++++++++++---------------------- perf/ffbench.c | 4 +--- 5 files changed, 25 insertions(+), 49 deletions(-) diff --git a/drd/tests/dlopen_lib.c b/drd/tests/dlopen_lib.c index ea18fc5439..34d6167614 100644 --- a/drd/tests/dlopen_lib.c +++ b/drd/tests/dlopen_lib.c @@ -18,7 +18,7 @@ void foo() int rc; uintptr_t t = 1; - printf("In main: creating thread %ld\n", t); + printf("In main: creating thread %u\n", (unsigned)t); rc = pthread_create(&thread, NULL, PrintHello, (void *)t); if (rc) printf("ERROR; return code from pthread_create() is %d\n", rc); diff --git a/memcheck/tests/vcpu_fbench.c b/memcheck/tests/vcpu_fbench.c index 6a7767d8cf..2f05eb86fd 100644 --- a/memcheck/tests/vcpu_fbench.c +++ b/memcheck/tests/vcpu_fbench.c @@ -380,8 +380,7 @@ static double atanc[] = { /* aint(x) Return integer part of number. Truncates towards 0 */ -double aint(x) -double x; +double aint(double x) { long l; @@ -398,8 +397,7 @@ double x; /* sin(x) Return sine, x in radians */ -static double sin(x) -double x; +static double sin(double x) { int sign; double y, r, z; @@ -437,8 +435,7 @@ double x; /* cos(x) Return cosine, x in radians, by identity */ -static double cos(x) -double x; +static double cos(double x) { x = (x < 0.0) ? -x : x; if (x > twopi) /* Do range reduction here to limit */ @@ -448,8 +445,7 @@ double x; /* tan(x) Return tangent, x in radians, by identity */ -static double tan(x) -double x; +static double tan(double x) { return sin(x) / cos(x); } @@ -457,8 +453,7 @@ double x; /* sqrt(x) Return square root. Initial guess, then Newton- Raphson refinement */ -double sqrt(x) -double x; +double sqrt(double x) { double c, cl, y; int n; @@ -490,8 +485,7 @@ double x; /* atan(x) Return arctangent in radians, range -pi/2 to pi/2 */ -static double atan(x) -double x; +static double atan(double x) { int sign, l, y; double a, b, z; @@ -530,8 +524,7 @@ atl: /* atan2(y,x) Return arctangent in radians of y/x, range -pi to pi */ -static double atan2(y, x) -double y, x; +static double atan2(double y, double x) { double temp; @@ -555,8 +548,7 @@ double y, x; /* asin(x) Return arcsine in radians of x */ -static double asin(x) -double x; +static double asin(double x) { if (fabs(x)>1.0) { fprintf(stderr, @@ -674,9 +666,7 @@ static void transit_surface() { /* Perform ray trace in specific spectral line */ -static void trace_line(line, ray_h) -int line; -double ray_h; +static void trace_line(int line, double ray_h) { int i; @@ -701,9 +691,7 @@ double ray_h; /* Initialise when called the first time */ -int main(argc, argv) -int argc; -char *argv[]; +int main(int argc, char* argv[]) { int i, j, k, errors; double od_fline, od_cline; diff --git a/none/tests/unit_debuglog.c b/none/tests/unit_debuglog.c index 7a71d04d27..fc1d59326f 100644 --- a/none/tests/unit_debuglog.c +++ b/none/tests/unit_debuglog.c @@ -16,7 +16,7 @@ #include "coregrind/m_debuglog.c" -void run(const char *format, ...) +int run(const char *format, ...) { int n, num_stars; const char *p; @@ -44,6 +44,8 @@ void run(const char *format, ...) emit(buf.buf, strlen(buf.buf)); fprintf(stderr, "\twrote %3d chars\n", n); + + return num_stars; } int main(int argc, char *argv[]) diff --git a/perf/fbench.c b/perf/fbench.c index 79bbb3ec5e..4a6090ee5f 100644 --- a/perf/fbench.c +++ b/perf/fbench.c @@ -376,8 +376,7 @@ static double atanc[] = { /* aint(x) Return integer part of number. Truncates towards 0 */ -double aint(x) -double x; +double aint(double x) { long l; @@ -394,8 +393,7 @@ double x; /* sin(x) Return sine, x in radians */ -static double sin(x) -double x; +static double sin(double x) { int sign; double y, r, z; @@ -433,8 +431,7 @@ double x; /* cos(x) Return cosine, x in radians, by identity */ -static double cos(x) -double x; +static double cos(double x) { x = (x < 0.0) ? -x : x; if (x > twopi) /* Do range reduction here to limit */ @@ -444,8 +441,7 @@ double x; /* tan(x) Return tangent, x in radians, by identity */ -static double tan(x) -double x; +static double tan(double x) { return sin(x) / cos(x); } @@ -453,8 +449,7 @@ double x; /* sqrt(x) Return square root. Initial guess, then Newton- Raphson refinement */ -double sqrt(x) -double x; +double sqrt(double x) { double c, cl, y; int n; @@ -486,8 +481,7 @@ double x; /* atan(x) Return arctangent in radians, range -pi/2 to pi/2 */ -static double atan(x) -double x; +static double atan(double x) { int sign, l, y; double a, b, z; @@ -526,8 +520,7 @@ atl: /* atan2(y,x) Return arctangent in radians of y/x, range -pi to pi */ -static double atan2(y, x) -double y, x; +static double atan2(double y, double x) { double temp; @@ -551,8 +544,7 @@ double y, x; /* asin(x) Return arcsine in radians of x */ -static double asin(x) -double x; +static double asin(double x) { if (fabs(x)>1.0) { fprintf(stderr, @@ -670,9 +662,7 @@ static void transit_surface() { /* Perform ray trace in specific spectral line */ -static void trace_line(line, ray_h) -int line; -double ray_h; +static void trace_line(int line, double ray_h) { int i; @@ -697,9 +687,7 @@ double ray_h; /* Initialise when called the first time */ -int main(argc, argv) -int argc; -char *argv[]; +int main(int argc, char* argv[]) { int i, j, k, errors; double od_fline, od_cline; diff --git a/perf/ffbench.c b/perf/ffbench.c index 7a02ce43ac..1fb21914bb 100644 --- a/perf/ffbench.c +++ b/perf/ffbench.c @@ -165,9 +165,7 @@ #define SWAP(a,b) tempr=(a); (a)=(b); (b)=tempr -static void fourn(data, nn, ndim, isign) - Float data[]; - int nn[], ndim, isign; +static void fourn(Float data[], int nn[], int ndim, int isign) { register int i1, i2, i3; int i2rev, i3rev, ip1, ip2, ip3, ifp1, ifp2; |
|
From: Paul F. <pa...@so...> - 2023-08-27 12:42:31
|
https://sourceware.org/git/gitweb.cgi?p=valgrind.git;h=aa37ab2d12e18cc5bb7eaec54a1b24c2b3bb6ee4 commit aa37ab2d12e18cc5bb7eaec54a1b24c2b3bb6ee4 Author: Paul Floyd <pj...@wa...> Date: Sun Aug 27 16:41:36 2023 +0200 FreeBSD regtest: add suppression to bug392331_supp for FreeBSD 14.0 Diff: --- helgrind/tests/bug392331.supp | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/helgrind/tests/bug392331.supp b/helgrind/tests/bug392331.supp index d19ab70b4a..d76ec469e0 100644 --- a/helgrind/tests/bug392331.supp +++ b/helgrind/tests/bug392331.supp @@ -4,3 +4,10 @@ fun:pthread_cond_signal_WRK fun:pthread_cond_signal* } + +{ + Variation for FreeBSD 14 + Helgrind:Dubious + fun:pthread_cond_signal_WRK + fun:_ZNSt3__118condition_variable10notify_oneEv +} |
|
From: Paul F. <pa...@so...> - 2023-08-27 07:42:47
|
https://sourceware.org/git/gitweb.cgi?p=valgrind.git;h=843fc19ccca36e08c8dc479dee59aedcbbc42e74 commit 843fc19ccca36e08c8dc479dee59aedcbbc42e74 Author: Paul Floyd <pj...@wa...> Date: Sun Aug 27 09:35:03 2023 +0200 Allow spaces in .valgrindrc files The patch for m_commandline.c comes from the Debian package files. Also add a regtest and allow --command-line-only=no to override --command-line-only=yes Diff: --- NEWS | 1 + coregrind/m_commandline.c | 21 +++++++++++++++++++-- none/tests/Makefile.am | 1 + none/tests/rc_option_with_spaces.stderr.exp | 0 none/tests/rc_option_with_spaces.vgtest | 5 +++++ 5 files changed, 26 insertions(+), 2 deletions(-) diff --git a/NEWS b/NEWS index 63d86bf51d..96eb06af8a 100644 --- a/NEWS +++ b/NEWS @@ -52,6 +52,7 @@ are not entered into bugzilla tend to get forgotten about or ignored. 472963 Broken regular expression in configure.ac 473604 Fix bug472219.c compile failure with Clang 16 473677 make check compile failure with Clang 16 based on GCC 13.x +n-i-bz Allow arguments with spaces in .valgrindrc files To see details of a given bug, visit https://bugs.kde.org/show_bug.cgi?id=XXXXXX diff --git a/coregrind/m_commandline.c b/coregrind/m_commandline.c index 27c53ba705..e9fdb9bb4c 100644 --- a/coregrind/m_commandline.c +++ b/coregrind/m_commandline.c @@ -98,14 +98,27 @@ static void add_args_from_string ( HChar* s ) { HChar* tmp; HChar* cp = s; + int quoted = '\0'; vg_assert(cp); while (True) { + HChar* out; // We have alternating sequences: blanks, non-blanks, blanks... // copy the non-blanks sequences, and add terminating '\0' + // deal with " or '-quoted strings properly. while (VG_(isspace)(*cp)) cp++; if (*cp == 0) break; - tmp = cp; - while ( !VG_(isspace)(*cp) && *cp != 0 ) cp++; + tmp = out = cp; + while ( (quoted || !VG_(isspace)(*cp)) && *cp) { + if (*cp == quoted) { + quoted = '\0'; + } else if (*cp == '\'' || *cp == '"') { + quoted = *cp; + } else { + *out++ = *cp; + } + cp++; + } + if (out < cp) *out++ = '\0'; if ( *cp != 0 ) *cp++ = '\0'; // terminate if not the last add_string( VG_(args_for_valgrind), tmp ); } @@ -188,6 +201,10 @@ void VG_(split_up_argv)( Int argc, HChar** argv ) } if (0 == VG_(strcmp)(argv[i], "--command-line-only=yes")) augment = False; + /* mainly to allow overriding the regtest default */ + if (0 == VG_(strcmp)(argv[i], "--command-line-only=no")) { + augment = True; + } if (argv[i][0] != '-') break; add_string( tmp_xarray, argv[i] ); diff --git a/none/tests/Makefile.am b/none/tests/Makefile.am index c0dd7c21db..253d4a140c 100644 --- a/none/tests/Makefile.am +++ b/none/tests/Makefile.am @@ -188,6 +188,7 @@ EXTRA_DIST = \ pth_stackalign.stdout.exp pth_stackalign.vgtest \ pth_2sig.stderr.exp-linux pth_2sig.stderr.exp-solaris pth_2sig.vgtest \ pth_term_signal.stderr.exp pth_term_signal.vgtest \ + rc_option_with_spaces.stderr.exp rc_option_with_spaces.vgtest \ rcrl.stderr.exp rcrl.stdout.exp rcrl.vgtest \ readline1.stderr.exp readline1.stdout.exp \ readline1.vgtest \ diff --git a/none/tests/rc_option_with_spaces.stderr.exp b/none/tests/rc_option_with_spaces.stderr.exp new file mode 100644 index 0000000000..e69de29bb2 diff --git a/none/tests/rc_option_with_spaces.vgtest b/none/tests/rc_option_with_spaces.vgtest new file mode 100644 index 0000000000..a64dcc99b0 --- /dev/null +++ b/none/tests/rc_option_with_spaces.vgtest @@ -0,0 +1,5 @@ +prereq: echo "--log-file='file with spaces.log'" > .valgrindrc +vgopts: --command-line-only=no +prog: ../../tests/true +post: test -f "./file with spaces.log" +cleanup: rm -f "./file with spaces.log" ./.valgrindrc |
|
From: Paul F. <pa...@so...> - 2023-08-26 10:58:37
|
https://sourceware.org/git/gitweb.cgi?p=valgrind.git;h=1377d1d58fb4912d86a1033c33f62a37b0af308b commit 1377d1d58fb4912d86a1033c33f62a37b0af308b Author: Paul Floyd <pj...@wa...> Date: Sat Aug 26 12:57:34 2023 +0200 FreeBSD regtest: use a filter to make eventfd2 consistent Diff: --- memcheck/tests/freebsd/Makefile.am | 4 ++-- memcheck/tests/freebsd/eventfd2.c | 21 +++++++-------------- memcheck/tests/freebsd/eventfd2.stderr.exp | 26 ++++++++++++++++++++++++++ memcheck/tests/freebsd/eventfd2.stdout.exp | 26 -------------------------- memcheck/tests/freebsd/eventfd2.vgtest | 1 + memcheck/tests/freebsd/filter_eventfd2 | 7 +++++++ 6 files changed, 43 insertions(+), 42 deletions(-) diff --git a/memcheck/tests/freebsd/Makefile.am b/memcheck/tests/freebsd/Makefile.am index 722cc5d51e..b936629b84 100644 --- a/memcheck/tests/freebsd/Makefile.am +++ b/memcheck/tests/freebsd/Makefile.am @@ -2,7 +2,7 @@ include $(top_srcdir)/Makefile.tool-tests.am dist_noinst_SCRIPTS = filter_stderr filter_pts dump_stdout filter_sigwait \ - filter_scalar filter_realpathat filter_fstat + filter_scalar filter_realpathat filter_fstat filter_eventfd2 EXTRA_DIST = \ scalar.h \ @@ -79,7 +79,7 @@ EXTRA_DIST = \ eventfd1.vgtest \ eventfd1.stderr.exp eventfd1.stdout.exp \ eventfd2.vgtest \ - eventfd2.stderr.exp eventfd2.stdout.exp \ + eventfd2.stderr.exp \ errno_aligned_allocs.vgtest \ errno_aligned_allocs.stderr.exp \ setproctitle.vgtest \ diff --git a/memcheck/tests/freebsd/eventfd2.c b/memcheck/tests/freebsd/eventfd2.c index d620907c9d..18dfff332f 100644 --- a/memcheck/tests/freebsd/eventfd2.c +++ b/memcheck/tests/freebsd/eventfd2.c @@ -16,9 +16,8 @@ static void xsem_wait(int fd) exit(1); } - fprintf(stdout, "wait completed on %d: count=%" PRIu64 "\n", + fprintf(stderr, "fd %d wait completed: count=%" PRIu64 "\n", fd, cntr); - fflush(stdout); } static void xsem_post(int fd, int count) @@ -38,28 +37,22 @@ static void sem_player(int fd1, int fd2) * not good for regresson tests * (also xsem_wait above) */ - fprintf(stdout, "posting 1 on %d\n", fd1); - fflush(stdout); + fprintf(stderr, "fd %d posting 1\n", fd1); xsem_post(fd1, 1); - fprintf(stdout, "waiting on %d\n", fd2); - fflush(stdout); + fprintf(stderr, "fd %d waiting\n", fd2); xsem_wait(fd2); - fprintf(stdout, "posting 1 on %d\n", fd1); - fflush(stdout); + fprintf(stderr, "fd %d posting 1\n", fd1); xsem_post(fd1, 1); - fprintf(stdout, "waiting on %d\n", fd2); - fflush(stdout); + fprintf(stderr, "fd %d waiting\n", fd2); xsem_wait(fd2); - fprintf(stdout, "posting 5 on %d\n", fd1); - fflush(stdout); + fprintf(stderr, "fd %d posting 5\n", fd1); xsem_post(fd1, 5); - fprintf(stdout, "waiting 5 times on %d\n", fd2); - fflush(stdout); + fprintf(stderr, "fd %d waiting 5 times\n", fd2); xsem_wait(fd2); xsem_wait(fd2); xsem_wait(fd2); diff --git a/memcheck/tests/freebsd/eventfd2.stderr.exp b/memcheck/tests/freebsd/eventfd2.stderr.exp index e69de29bb2..ce32ce5c92 100644 --- a/memcheck/tests/freebsd/eventfd2.stderr.exp +++ b/memcheck/tests/freebsd/eventfd2.stderr.exp @@ -0,0 +1,26 @@ +fd 3 posting 1 +fd 3 posting 1 +fd 3 posting 5 +fd 3 wait completed: count=1 +fd 3 wait completed: count=1 +fd 3 wait completed: count=1 +fd 3 wait completed: count=1 +fd 3 wait completed: count=1 +fd 3 wait completed: count=1 +fd 3 wait completed: count=1 +fd 3 waiting +fd 3 waiting +fd 3 waiting 5 times +fd 4 posting 1 +fd 4 posting 1 +fd 4 posting 5 +fd 4 wait completed: count=1 +fd 4 wait completed: count=1 +fd 4 wait completed: count=1 +fd 4 wait completed: count=1 +fd 4 wait completed: count=1 +fd 4 wait completed: count=1 +fd 4 wait completed: count=1 +fd 4 waiting +fd 4 waiting +fd 4 waiting 5 times diff --git a/memcheck/tests/freebsd/eventfd2.stdout.exp b/memcheck/tests/freebsd/eventfd2.stdout.exp deleted file mode 100644 index 00ecdcaca7..0000000000 --- a/memcheck/tests/freebsd/eventfd2.stdout.exp +++ /dev/null @@ -1,26 +0,0 @@ -posting 1 on 3 -waiting on 4 -posting 1 on 4 -wait completed on 4: count=1 -waiting on 3 -posting 1 on 3 -waiting on 4 -wait completed on 3: count=1 -posting 1 on 4 -wait completed on 4: count=1 -waiting on 3 -wait completed on 3: count=1 -posting 5 on 3 -posting 5 on 4 -waiting 5 times on 4 -wait completed on 4: count=1 -waiting 5 times on 3 -wait completed on 4: count=1 -wait completed on 3: count=1 -wait completed on 4: count=1 -wait completed on 3: count=1 -wait completed on 4: count=1 -wait completed on 3: count=1 -wait completed on 4: count=1 -wait completed on 3: count=1 -wait completed on 3: count=1 diff --git a/memcheck/tests/freebsd/eventfd2.vgtest b/memcheck/tests/freebsd/eventfd2.vgtest index 7dd3ad1ea8..f873b08f77 100644 --- a/memcheck/tests/freebsd/eventfd2.vgtest +++ b/memcheck/tests/freebsd/eventfd2.vgtest @@ -1,3 +1,4 @@ prog: eventfd2 prereq: test -e ./eventfd2 vgopts: -q +stderr_filter: filter_eventfd2 diff --git a/memcheck/tests/freebsd/filter_eventfd2 b/memcheck/tests/freebsd/filter_eventfd2 new file mode 100755 index 0000000000..05cd260dad --- /dev/null +++ b/memcheck/tests/freebsd/filter_eventfd2 @@ -0,0 +1,7 @@ +#! /bin/sh + +../filter_stderr "$@" | + +sort + +exit 0 |
|
From: Paul F. <pa...@so...> - 2023-08-26 06:05:17
|
https://sourceware.org/git/gitweb.cgi?p=valgrind.git;h=adbdbd740b72ffc80b68415d0b895a06fbafc4a9 commit adbdbd740b72ffc80b68415d0b895a06fbafc4a9 Author: Paul Floyd <pj...@wa...> Date: Sat Aug 26 07:58:10 2023 +0200 Solaris: remove cxx17_aligned_new expected No longer needed after last cleanup Diff: --- memcheck/tests/Makefile.am | 1 - .../tests/cxx17_aligned_new.stderr.exp-solaris | 34 ---------------------- 2 files changed, 35 deletions(-) diff --git a/memcheck/tests/Makefile.am b/memcheck/tests/Makefile.am index e7e0d78e45..687dc6995e 100644 --- a/memcheck/tests/Makefile.am +++ b/memcheck/tests/Makefile.am @@ -142,7 +142,6 @@ EXTRA_DIST = \ custom-overlap.stderr.exp custom-overlap.vgtest \ cxx17_aligned_new.stderr.exp cxx17_aligned_new.vgtest \ cxx17_aligned_new.stderr.exp_32 \ - cxx17_aligned_new.stderr.exp-solaris \ cxx17_aligned_new.stdout.exp \ sized_aligned_new_delete_args.stderr.exp \ sized_aligned_new_delete_args.vgtest \ diff --git a/memcheck/tests/cxx17_aligned_new.stderr.exp-solaris b/memcheck/tests/cxx17_aligned_new.stderr.exp-solaris deleted file mode 100644 index 275620856e..0000000000 --- a/memcheck/tests/cxx17_aligned_new.stderr.exp-solaris +++ /dev/null @@ -1,34 +0,0 @@ - -_ZnwjSt11align_val_t(size 64, al 64) = 0x........ -_ZdlPvSt11align_val_t(0x........) -_ZnajSt11align_val_t(size 320, al 64) = 0x........ -_ZdaPvSt11align_val_t(0x........) -_ZnwjSt11align_val_t(size 64, al 64) = 0x........ -_ZdlPvjSt11align_val_t(0x........) -_ZnajSt11align_val_t(size 320, al 64) = 0x........ -_ZdaPvjSt11align_val_t(0x........) -_ZnwjSt11align_val_t(size 64, al 64) = 0x........ -_ZdlPvSt11align_val_t(0x........) -_ZnajSt11align_val_tRKSt9nothrow_t(size 320, al 64) = 0x........ -_ZdaPvSt11align_val_t(0x........) -_ZnwjSt11align_val_t(size 64, al 64) = 0x........ -_ZdlPvjSt11align_val_t(0x........) -_ZnajSt11align_val_tRKSt9nothrow_t(size 320, al 64) = 0x........ -_ZdaPvjSt11align_val_t(0x........) -_Znwj(4) = 0x........ -_ZdlPvSt11align_val_t(0x........) -_ZnwjRKSt9nothrow_t(4) = 0x........ -_ZdlPv(0x........) -_Znaj(20) = 0x........ -_ZdaPv(0x........) -_ZnajRKSt9nothrow_t(20) = 0x........ -_ZdaPv(0x........) - -HEAP SUMMARY: - in use at exit: ... bytes in ... blocks - total heap usage: ... allocs, ... frees, ... bytes allocated - -For a detailed leak analysis, rerun with: --leak-check=full - -For lists of detected and suppressed errors, rerun with: -s -ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0) |
|
From: Paul F. <pj...@wa...> - 2023-08-26 05:53:33
|
Hi
I was just looking at valgrind-testresults and there was a jump in the
number of failures on ppc64le on Aug 17th, just after the deferred
debuginfo reading change.
One random example
=================================================
./valgrind-old/drd/tests/tc16_byterace.stderr.diff
=================================================
--- tc16_byterace.stderr.exp 2023-08-17 03:01:09.168107928 +0000
+++ tc16_byterace.stderr.out 2023-08-17 03:28:20.030515805 +0000
@@ -1,8 +1,7 @@
Conflicting load by thread 1 at 0x........ size 1
at 0x........: main (tc16_byterace.c:34)
-Location 0x........ is 0 bytes inside bytes[4],
-a global variable declared at tc16_byterace.c:7
+Allocation context: BSS section of tc16_byterace
It does look to me like this is a debuginfo issue.
Can anyone take a look?
A+
Paul
|
|
From: Paul F. <pa...@so...> - 2023-08-25 21:01:53
|
https://sourceware.org/git/gitweb.cgi?p=valgrind.git;h=75321f92b183c545e6690fd24f0725a24650bf50 commit 75321f92b183c545e6690fd24f0725a24650bf50 Author: Paul Floyd <pj...@wa...> Date: Fri Aug 25 23:00:58 2023 +0200 Fix various clang warnings Mostly missing 'void' in function prototypes. Diff: --- VEX/priv/guest_mips_helpers.c | 2 +- cachegrind/cg_arch.c | 2 +- callgrind/bb.c | 4 ++-- callgrind/bbcc.c | 2 +- callgrind/callstack.c | 2 +- callgrind/context.c | 2 +- callgrind/dump.c | 2 +- callgrind/fn.c | 4 ++-- callgrind/sim.c | 2 +- callgrind/threads.c | 8 ++++---- coregrind/m_debuginfo/readpdb.c | 1 - coregrind/m_gdbserver/target.c | 2 +- drd/drd_bitmap.c | 2 +- drd/drd_load_store.c | 4 ++-- drd/drd_thread.c | 2 +- drd/drd_vc.c | 6 +++--- drd/drd_vc.h | 2 +- 17 files changed, 24 insertions(+), 25 deletions(-) diff --git a/VEX/priv/guest_mips_helpers.c b/VEX/priv/guest_mips_helpers.c index 5845e483e4..74cfb9c34c 100644 --- a/VEX/priv/guest_mips_helpers.c +++ b/VEX/priv/guest_mips_helpers.c @@ -1274,7 +1274,7 @@ extern UInt mips_dirtyhelper_calculate_MSACSR ( void* gs, UInt ws, UInt wt, return ret; } -extern UInt mips_dirtyhelper_get_MSAIR() { +extern UInt mips_dirtyhelper_get_MSAIR(void) { UInt ret = 0; /* GCC 4.8 and later support MIPS MSA. */ #if defined(__mips__) && (defined(__clang__) || (GCC_VERSION >= 408)) diff --git a/cachegrind/cg_arch.c b/cachegrind/cg_arch.c index 6ff2247e84..8858b0ee6d 100644 --- a/cachegrind/cg_arch.c +++ b/cachegrind/cg_arch.c @@ -311,7 +311,7 @@ void VG_(post_clo_init_configure_caches)(cache_t* I1c, #undef DEFINED } -void VG_(print_cache_clo_opts)() +void VG_(print_cache_clo_opts)(void) { VG_(printf)( " --I1=<size>,<assoc>,<line_size> set I1 cache manually\n" diff --git a/callgrind/bb.c b/callgrind/bb.c index da64caa13e..a599c10a55 100644 --- a/callgrind/bb.c +++ b/callgrind/bb.c @@ -33,7 +33,7 @@ /* BB hash, resizable */ bb_hash bbs; -void CLG_(init_bb_hash)() +void CLG_(init_bb_hash)(void) { Int i; @@ -45,7 +45,7 @@ void CLG_(init_bb_hash)() for (i = 0; i < bbs.size; i++) bbs.table[i] = NULL; } -bb_hash* CLG_(get_bb_hash)() +bb_hash* CLG_(get_bb_hash)(void) { return &bbs; } diff --git a/callgrind/bbcc.c b/callgrind/bbcc.c index 619d400019..d197f3dee0 100644 --- a/callgrind/bbcc.c +++ b/callgrind/bbcc.c @@ -61,7 +61,7 @@ void CLG_(copy_current_bbcc_hash)(bbcc_hash* dst) dst->table = current_bbccs.table; } -bbcc_hash* CLG_(get_current_bbcc_hash)() +bbcc_hash* CLG_(get_current_bbcc_hash)(void) { return ¤t_bbccs; } diff --git a/callgrind/callstack.c b/callgrind/callstack.c index 96dfc995a5..fc1d6eeab1 100644 --- a/callgrind/callstack.c +++ b/callgrind/callstack.c @@ -309,7 +309,7 @@ void CLG_(push_call_stack)(BBCC* from, UInt jmp, BBCC* to, Addr sp, Bool skip) * * If the JCC becomes inactive, call entries are freed if possible */ -void CLG_(pop_call_stack)() +void CLG_(pop_call_stack)(void) { jCC* jcc; Int depth = 0; diff --git a/callgrind/context.c b/callgrind/context.c index 459c6e6ab1..81261bdf1c 100644 --- a/callgrind/context.c +++ b/callgrind/context.c @@ -67,7 +67,7 @@ void CLG_(set_current_fn_stack)(fn_stack* s) static cxt_hash cxts; -void CLG_(init_cxt_table)() +void CLG_(init_cxt_table)(void) { Int i; diff --git a/callgrind/dump.c b/callgrind/dump.c index 368a740b46..7f9f59f92a 100644 --- a/callgrind/dump.c +++ b/callgrind/dump.c @@ -1581,7 +1581,7 @@ void init_cmdbuf(void) * This function has to be called every time a profile dump is generated * to be able to react on PID changes. */ -void CLG_(init_dumps)() +void CLG_(init_dumps)(void) { SysRes res; diff --git a/callgrind/fn.c b/callgrind/fn.c index 45d26ed43f..27ad4988a0 100644 --- a/callgrind/fn.c +++ b/callgrind/fn.c @@ -300,7 +300,7 @@ static Bool search_runtime_resolve(obj_node* obj) /* Object hash table, fixed */ static obj_node* obj_table[N_OBJ_ENTRIES]; -void CLG_(init_obj_table)() +void CLG_(init_obj_table)(void) { Int i; for (i = 0; i < N_OBJ_ENTRIES; i++) @@ -741,7 +741,7 @@ void CLG_(copy_current_fn_array)(fn_array* dst) dst->array = current_fn_active.array; } -fn_array* CLG_(get_current_fn_array)() +fn_array* CLG_(get_current_fn_array)(void) { return ¤t_fn_active; } diff --git a/callgrind/sim.c b/callgrind/sim.c index 104c63492e..90e6134319 100644 --- a/callgrind/sim.c +++ b/callgrind/sim.c @@ -1593,7 +1593,7 @@ void cachesim_printstat(Int l1, Int l2, Int l3) struct event_sets CLG_(sets); -void CLG_(init_eventsets)() +void CLG_(init_eventsets)(void) { // Event groups from which the event sets are composed // the "Use" group only is used with "cacheuse" simulation diff --git a/callgrind/threads.c b/callgrind/threads.c index 20b23c1899..624588a269 100644 --- a/callgrind/threads.c +++ b/callgrind/threads.c @@ -61,17 +61,17 @@ ThreadId CLG_(current_tid); static thread_info** thread; -thread_info** CLG_(get_threads)() +thread_info** CLG_(get_threads)(void) { return thread; } -thread_info* CLG_(get_current_thread)() +thread_info* CLG_(get_current_thread)(void) { return thread[CLG_(current_tid)]; } -void CLG_(init_threads)() +void CLG_(init_threads)(void) { UInt i; @@ -224,7 +224,7 @@ void CLG_(pre_signal)(ThreadId tid, Int sigNum, Bool alt_stack) * * Called from CLG_(pop_call_stack) */ -void CLG_(run_post_signal_on_call_stack_bottom)() +void CLG_(run_post_signal_on_call_stack_bottom)(void) { exec_state* es = top_exec_state(); CLG_ASSERT(es != 0); diff --git a/coregrind/m_debuginfo/readpdb.c b/coregrind/m_debuginfo/readpdb.c index 7c5467d379..414c185ccd 100644 --- a/coregrind/m_debuginfo/readpdb.c +++ b/coregrind/m_debuginfo/readpdb.c @@ -1554,7 +1554,6 @@ static ULong DEBUG_SnarfLinetab( */ pnt.c = linetab; nfile = *pnt.s++; - nseg = *pnt.s++; filetab = pnt.ui; diff --git a/coregrind/m_gdbserver/target.c b/coregrind/m_gdbserver/target.c index 490276b6c4..f9f32f4aa5 100644 --- a/coregrind/m_gdbserver/target.c +++ b/coregrind/m_gdbserver/target.c @@ -190,7 +190,7 @@ Int valgrind_stopped_by_syscall (void) return sysno_to_report; } -Bool valgrind_stopped_before_syscall() +Bool valgrind_stopped_before_syscall(void) { vg_assert (sysno_to_report >= 0); return before_syscall; diff --git a/drd/drd_bitmap.c b/drd/drd_bitmap.c index 479c7f20e3..3bd7fa56bd 100644 --- a/drd/drd_bitmap.c +++ b/drd/drd_bitmap.c @@ -64,7 +64,7 @@ void DRD_(bm_module_cleanup)(void) s_bm2_set_template = NULL; } -struct bitmap* DRD_(bm_new)() +struct bitmap* DRD_(bm_new)(void) { struct bitmap* bm; diff --git a/drd/drd_load_store.c b/drd/drd_load_store.c index fba1dac713..80d326a0e2 100644 --- a/drd/drd_load_store.c +++ b/drd/drd_load_store.c @@ -66,7 +66,7 @@ static Bool s_first_race_only = False; /* Function definitions. */ -Bool DRD_(get_check_stack_accesses)() +Bool DRD_(get_check_stack_accesses)(void) { return s_check_stack_accesses; } @@ -77,7 +77,7 @@ void DRD_(set_check_stack_accesses)(const Bool c) s_check_stack_accesses = c; } -Bool DRD_(get_first_race_only)() +Bool DRD_(get_first_race_only)(void) { return s_first_race_only; } diff --git a/drd/drd_thread.c b/drd/drd_thread.c index 32064c3b15..891967b039 100644 --- a/drd/drd_thread.c +++ b/drd/drd_thread.c @@ -1681,7 +1681,7 @@ ULong DRD_(thread_get_discard_ordered_segments_count)(void) } /** Return how many times the conflict set has been updated entirely. */ -ULong DRD_(thread_get_compute_conflict_set_count)() +ULong DRD_(thread_get_compute_conflict_set_count)(void) { return s_compute_conflict_set_count; } diff --git a/drd/drd_vc.c b/drd/drd_vc.c index ee9fa52bea..5705391f27 100644 --- a/drd/drd_vc.c +++ b/drd/drd_vc.c @@ -67,10 +67,10 @@ void DRD_(vc_cleanup)(VectorClock* const vc) DRD_(vc_reserve)(vc, 0); } -/** Copy constructor -- initializes *new. */ -void DRD_(vc_copy)(VectorClock* const new, const VectorClock* const rhs) +/** Copy constructor -- initializes *obj. */ +void DRD_(vc_copy)(VectorClock* const obj, const VectorClock* const rhs) { - DRD_(vc_init)(new, rhs->vc, rhs->size); + DRD_(vc_init)(obj, rhs->vc, rhs->size); } /** Assignment operator -- *lhs is already a valid vector clock. */ diff --git a/drd/drd_vc.h b/drd/drd_vc.h index 47dd51baf6..0161be0f23 100644 --- a/drd/drd_vc.h +++ b/drd/drd_vc.h @@ -72,7 +72,7 @@ void DRD_(vc_init)(VectorClock* const vc, const VCElem* const vcelem, const unsigned size); void DRD_(vc_cleanup)(VectorClock* const vc); -void DRD_(vc_copy)(VectorClock* const new, const VectorClock* const rhs); +void DRD_(vc_copy)(VectorClock* const obj, const VectorClock* const rhs); void DRD_(vc_assign)(VectorClock* const lhs, const VectorClock* const rhs); void DRD_(vc_increment)(VectorClock* const vc, DrdThreadId const tid); static __inline__ |
|
From: Paul F. <pa...@so...> - 2023-08-25 20:13:09
|
https://sourceware.org/git/gitweb.cgi?p=valgrind.git;h=566b39a46f273710857938f66672213a4617beeb commit 566b39a46f273710857938f66672213a4617beeb Author: Paul Floyd <pj...@wa...> Date: Fri Aug 25 22:11:27 2023 +0200 Bug 473677 - make check compile failure with Clang 16 based on GCC 13.x Diff: --- NEWS | 1 + memcheck/tests/Makefile.am | 5 ++ memcheck/tests/cxx17_aligned_new.cpp | 82 +++++++++++++++++--------- memcheck/tests/cxx17_aligned_new.stderr.exp | 26 ++++---- memcheck/tests/cxx17_aligned_new.stderr.exp_32 | 34 +++++------ 5 files changed, 91 insertions(+), 57 deletions(-) diff --git a/NEWS b/NEWS index 2ce35472dd..63d86bf51d 100644 --- a/NEWS +++ b/NEWS @@ -51,6 +51,7 @@ are not entered into bugzilla tend to get forgotten about or ignored. 472219 Syscall param ppoll(ufds.events) points to uninitialised byte(s) 472963 Broken regular expression in configure.ac 473604 Fix bug472219.c compile failure with Clang 16 +473677 make check compile failure with Clang 16 based on GCC 13.x To see details of a given bug, visit https://bugs.kde.org/show_bug.cgi?id=XXXXXX diff --git a/memcheck/tests/Makefile.am b/memcheck/tests/Makefile.am index 307f47bd8e..e7e0d78e45 100644 --- a/memcheck/tests/Makefile.am +++ b/memcheck/tests/Makefile.am @@ -586,6 +586,11 @@ sized_aligned_new_delete_args_SOURCES = sized_aligned_new_delete_args.cpp sized_aligned_new_delete_args_CXXFLAGS = ${AM_CXXFLAGS} -std=c++17 sized_aligned_new_delete_misaligned_SOURCES = sized_aligned_new_delete_misaligned.cpp sized_aligned_new_delete_misaligned_CXXFLAGS = ${AM_CXXFLAGS} -std=c++17 +if COMPILER_IS_CLANG +cxx17_aligned_new_CXXFLAGS += -fsized-deallocation +sized_aligned_new_delete_args_CXXFLAGS += -fsized-deallocation +sized_aligned_new_delete_misaligned_CXXFLAGS += -fsized-deallocation +endif endif demangle_SOURCES = demangle.cpp diff --git a/memcheck/tests/cxx17_aligned_new.cpp b/memcheck/tests/cxx17_aligned_new.cpp index 1a7ac3c299..91d4d6535a 100644 --- a/memcheck/tests/cxx17_aligned_new.cpp +++ b/memcheck/tests/cxx17_aligned_new.cpp @@ -1,3 +1,12 @@ +// See +// https://en.cppreference.com/w/cpp/memory/new/operator_new +// and +// https://en.cppreference.com/w/cpp/memory/new/operator_delete + +// Some of these are only used in very special circumstances +// so rather then using new and delete expressions most calls +// here directly call the operators + #include <cstdlib> #include <new> #include <iostream> @@ -13,44 +22,63 @@ public: }; int main() { - // unsized versions - MyClass* myClass = new MyClass; + // THROWING + // plain versions + // cppreference new number 1 + OrdinaryClass* oClass = new OrdinaryClass(); + // cppreference delete number 1 + operator delete(oClass); + + // cppreference new number 2 + OrdinaryClass* oClass5 = new OrdinaryClass[5]; + // cppreference delete number 2 + operator delete[](oClass5); + + // aligned versions + // cppreference new number 3 + MyClass* myClass = new MyClass(); + // cppreference delete number 3 operator delete(myClass, std::align_val_t(64U)); + // cppreference new number 4 MyClass* myClass5 = new MyClass[5]; - operator delete [](myClass5, std::align_val_t(64U)); + // cppreference delete number 4 + operator delete[](myClass5, std::align_val_t(64U)); // sized versions + oClass = new OrdinaryClass(); + // cppreference delete number 5 + operator delete(oClass, sizeof(OrdinaryClass)); + + oClass5 = new OrdinaryClass[5]; + // cppreference delete number 6 + operator delete[](oClass5, sizeof(OrdinaryClass)*5); + + // sized aligned versions myClass = new MyClass(); - operator delete(myClass, 64U, std::align_val_t(64U)); + // cppreference delete number 7 + operator delete(myClass, sizeof(*myClass), std::align_val_t(64U)); myClass5 = new MyClass[5]; - operator delete [](myClass5, 320U, std::align_val_t(64U)); + // cppreference delete number 8 + operator delete [](myClass5, sizeof(*myClass)*5, std::align_val_t(64U)); - MyClass* myClassNt = new (std::nothrow) MyClass; - operator delete(myClassNt, std::align_val_t(64U)); + // NOTHROW - MyClass* myClass5Nt = new (std::nothrow) MyClass[5]; - operator delete [](myClass5Nt, std::align_val_t(64U)); + // cppreference new number 5 + oClass = new (std::nothrow) OrdinaryClass; + delete oClass; - myClassNt = new (std::nothrow) MyClass; - operator delete(myClassNt, sizeof(MyClass), std::align_val_t(64U)); + // cppreference new number 6 + oClass5 = new (std::nothrow) OrdinaryClass[5]; + delete [] oClass5; - myClass5Nt = new (std::nothrow) MyClass[5]; - operator delete [](myClass5Nt, sizeof(MyClass)*5, std::align_val_t(64U)); + // cppreference new number 7 + myClass = new (std::nothrow) MyClass; + delete myClass; - OrdinaryClass* oClass = new OrdinaryClass; - // this is a limitation, VG does not use enough bits - // to tell apart aligned and unaligned allocations - // so new/aligned delete is not a mismatch - operator delete(oClass, std::align_val_t(64U)); - oClass = new (std::nothrow) OrdinaryClass; - //delete oClass; - // changed the above delete because GCC generates - // a sized delete (???) whilst clang generates an ordinary delete - operator delete(oClass); - oClass = new OrdinaryClass[5]; - delete [] oClass; - oClass = new (std::nothrow) OrdinaryClass[5]; - delete [] oClass; + // cppreference new number 8 + myClass5 = new (std::nothrow) MyClass[5]; + delete [] myClass5; } + diff --git a/memcheck/tests/cxx17_aligned_new.stderr.exp b/memcheck/tests/cxx17_aligned_new.stderr.exp index cf52836c69..389bebf747 100644 --- a/memcheck/tests/cxx17_aligned_new.stderr.exp +++ b/memcheck/tests/cxx17_aligned_new.stderr.exp @@ -1,28 +1,28 @@ +_Znwm(4) = 0x........ +_ZdlPv(0x........) +_Znam(20) = 0x........ +_ZdaPv(0x........) _ZnwmSt11align_val_t(size 64, al 64) = 0x........ _ZdlPvSt11align_val_t(0x........) _ZnamSt11align_val_t(size 320, al 64) = 0x........ _ZdaPvSt11align_val_t(0x........) +_Znwm(4) = 0x........ +_ZdlPvm(0x........) +_Znam(20) = 0x........ +_ZdaPvm(0x........) _ZnwmSt11align_val_t(size 64, al 64) = 0x........ _ZdlPvmSt11align_val_t(0x........) _ZnamSt11align_val_t(size 320, al 64) = 0x........ _ZdaPvmSt11align_val_t(0x........) -_ZnwmSt11align_val_tRKSt9nothrow_t(size 64, al 64) = 0x........ -_ZdlPvSt11align_val_t(0x........) -_ZnamSt11align_val_tRKSt9nothrow_t(size 320, al 64) = 0x........ -_ZdaPvSt11align_val_t(0x........) -_ZnwmSt11align_val_tRKSt9nothrow_t(size 64, al 64) = 0x........ -_ZdlPvmSt11align_val_t(0x........) -_ZnamSt11align_val_tRKSt9nothrow_t(size 320, al 64) = 0x........ -_ZdaPvmSt11align_val_t(0x........) -_Znwm(4) = 0x........ -_ZdlPvSt11align_val_t(0x........) _ZnwmRKSt9nothrow_t(4) = 0x........ -_ZdlPv(0x........) -_Znam(20) = 0x........ -_ZdaPv(0x........) +_ZdlPvm(0x........) _ZnamRKSt9nothrow_t(20) = 0x........ _ZdaPv(0x........) +_ZnwmSt11align_val_tRKSt9nothrow_t(size 64, al 64) = 0x........ +_ZdlPvmSt11align_val_t(0x........) +_ZnamSt11align_val_tRKSt9nothrow_t(size 320, al 64) = 0x........ +_ZdaPvSt11align_val_t(0x........) HEAP SUMMARY: in use at exit: ... bytes in ... blocks diff --git a/memcheck/tests/cxx17_aligned_new.stderr.exp_32 b/memcheck/tests/cxx17_aligned_new.stderr.exp_32 index d40deebe81..c7239766b8 100644 --- a/memcheck/tests/cxx17_aligned_new.stderr.exp_32 +++ b/memcheck/tests/cxx17_aligned_new.stderr.exp_32 @@ -1,28 +1,28 @@ -_Znwj(64) = 0x........ -_ZdlPvSt11align_val_t(0x........) -_Znaj(320) = 0x........ -_ZdaPvSt11align_val_t(0x........) -_Znwj(64) = 0x........ -_ZdlPvjSt11align_val_t(0x........) -_Znaj(320) = 0x........ -_ZdaPvjSt11align_val_t(0x........) -_ZnwjRKSt9nothrow_t(64) = 0x........ +_Znwj(4) = 0x........ +_ZdlPv(0x........) +_Znaj(20) = 0x........ +_ZdaPv(0x........) +_ZnwjSt11align_val_t(size 64, al 64) = 0x........ _ZdlPvSt11align_val_t(0x........) -_ZnajRKSt9nothrow_t(320) = 0x........ +_ZnajSt11align_val_t(size 320, al 64) = 0x........ _ZdaPvSt11align_val_t(0x........) -_ZnwjRKSt9nothrow_t(64) = 0x........ +_Znwj(4) = 0x........ +_ZdlPvj(0x........) +_Znaj(20) = 0x........ +_ZdaPvj(0x........) +_ZnwjSt11align_val_t(size 64, al 64) = 0x........ _ZdlPvjSt11align_val_t(0x........) -_ZnajRKSt9nothrow_t(320) = 0x........ +_ZnajSt11align_val_t(size 320, al 64) = 0x........ _ZdaPvjSt11align_val_t(0x........) -_Znwj(4) = 0x........ -_ZdlPvSt11align_val_t(0x........) _ZnwjRKSt9nothrow_t(4) = 0x........ -_ZdlPv(0x........) -_Znaj(20) = 0x........ -_ZdaPv(0x........) +_ZdlPvj(0x........) _ZnajRKSt9nothrow_t(20) = 0x........ _ZdaPv(0x........) +_ZnwjSt11align_val_tRKSt9nothrow_t(size 64, al 64) = 0x........ +_ZdlPvjSt11align_val_t(0x........) +_ZnajSt11align_val_tRKSt9nothrow_t(size 320, al 64) = 0x........ +_ZdaPvSt11align_val_t(0x........) HEAP SUMMARY: in use at exit: ... bytes in ... blocks |