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: Carl L. <ce...@us...> - 2022-06-16 16:54:54
|
On Thu, 2022-06-16 at 16:34 +0000, Christophe Leroy wrote:
> Hi Carl,
>
> Le 16/06/2022 à 18:04, Carl Love a écrit :
> > Christophe:
> >
> > On Thu, 2022-06-16 at 10:51 +0000, Christophe Leroy wrote:
> > > Hello
> > >
> > > Trying to build valgrind-3.19.0.
> > >
> > > ./configure --host=ppc-linux --prefix=/usr --enable-only32bit --
> > > disable-tls
> > >
> > > I'm using glibc-2.35
> > >
> > > I end up with following errors (many more of the same kind
> > > follows):
> > >
> > > /opt/cldk-1.5.1rc1b1/lib/gcc/ppc-linux/11.2.0/../../../../ppc-
> > > linux/bin/ld:
> > > memcheck_ppc32_linux-mc_main.o: in function `gcSecVBitTable':
> > > /home/chleroy/ldb_base/ofs/packages/valgrind-
> > > 3.19.0/memcheck/mc_main.c:993:
> > > undefined reference to `__floatsidf'
> > >
> >
> > Not sure why your using cldk-1.5.1.1rc1b1 in /opt? Not sure what
> > that
> > is?
>
> That's just the directory where sits my home built cross compiler.
>
> > When I tried the configure on a Power 10 64-bit system:
> >
> > ./configure --host=ppc-linux --prefix=/home/carll --enable-
> > only32bit
> > --disable-tls
> >
> > The configure went fine but the compile fails on
> > /usr/include/gnu/stubs.h:8:11: fatal error: gnu/stubs-32.h: No such
> > file or directory
> >
> > Not sure what system you are on and why you need the enable-
> > only32bit?
>
> I'm building on a x86_64 for running on a board which has a 32 bits
> powerpc CPU. That CPU has no FPU.
>
> > I normally build for 64-bit machines, so I tried:
> >
> > ./configure --host=ppc-linux --prefix=/home/carll --disable-tls
> >
> > I see at the end of the configure:
> >
> > Maximum build arch: ppc32
> > Primary build arch: ppc32
> >
> > and again get a ppc32 related build error.
> >
> > Since I am on a ppc64 LE system I did the following configure:
> >
> > ./configure --host=ppc64le-linux --prefix=/home/carll --disable-
> > tls
> >
> > Note, I am using the distro compiler /usr/bin/gcc and glibc. The
> > build
> > works fine with the distro gcc and glibc. Can you set your paths
> > to
> > use the default distro gcc and glib?
>
> I can't, I need a cross-build compiler with glibc support for my
> target.
>
> It is GCC 11 with Glibc 2.35
>
>
> > Note, the version of glibc that I am using, as given by the ldd
> > command, is:
> >
> > $ ldd --version ldd
> > ldd (GNU libc) 2.34
> >
>
> The point is:
> - libgcc doesn't include floating point functions on powerpc, they
> are
> in libc
> - valgrind is built statically against libgcc, without libc
OK, I understand better the environment of what you are trying to do.
Unfortunately, I have not played in that environment so don't have a
good feel for how to fix the issue. I believe the -msoft-float option
on the compiler and linker lines will force the compiler to not
generate FP instructions but I don't think that will help in this case.
Your issue is more of a library issue.
Carl
|
|
From: Christophe L. <chr...@cs...> - 2022-06-16 16:50:41
|
Hi Carl, Le 16/06/2022 à 18:04, Carl Love a écrit : > Christophe: > > On Thu, 2022-06-16 at 10:51 +0000, Christophe Leroy wrote: >> Hello >> >> Trying to build valgrind-3.19.0. >> >> ./configure --host=ppc-linux --prefix=/usr --enable-only32bit -- >> disable-tls >> >> I'm using glibc-2.35 >> >> I end up with following errors (many more of the same kind follows): >> >> /opt/cldk-1.5.1rc1b1/lib/gcc/ppc-linux/11.2.0/../../../../ppc- >> linux/bin/ld: >> memcheck_ppc32_linux-mc_main.o: in function `gcSecVBitTable': >> /home/chleroy/ldb_base/ofs/packages/valgrind- >> 3.19.0/memcheck/mc_main.c:993: >> undefined reference to `__floatsidf' >> > > Not sure why your using cldk-1.5.1.1rc1b1 in /opt? Not sure what that > is? That's just the directory where sits my home built cross compiler. > > When I tried the configure on a Power 10 64-bit system: > > ./configure --host=ppc-linux --prefix=/home/carll --enable-only32bit > --disable-tls > > The configure went fine but the compile fails on > /usr/include/gnu/stubs.h:8:11: fatal error: gnu/stubs-32.h: No such > file or directory > > Not sure what system you are on and why you need the enable-only32bit? I'm building on a x86_64 for running on a board which has a 32 bits powerpc CPU. That CPU has no FPU. > > I normally build for 64-bit machines, so I tried: > > ./configure --host=ppc-linux --prefix=/home/carll --disable-tls > > I see at the end of the configure: > > Maximum build arch: ppc32 > Primary build arch: ppc32 > > and again get a ppc32 related build error. > > Since I am on a ppc64 LE system I did the following configure: > > ./configure --host=ppc64le-linux --prefix=/home/carll --disable-tls > > Note, I am using the distro compiler /usr/bin/gcc and glibc. The build > works fine with the distro gcc and glibc. Can you set your paths to > use the default distro gcc and glib? I can't, I need a cross-build compiler with glibc support for my target. It is GCC 11 with Glibc 2.35 > > Note, the version of glibc that I am using, as given by the ldd > command, is: > > $ ldd --version ldd > ldd (GNU libc) 2.34 > The point is: - libgcc doesn't include floating point functions on powerpc, they are in libc - valgrind is built statically against libgcc, without libc Christophe |
|
From: Carl L. <ce...@us...> - 2022-06-16 16:47:16
|
Christophe:
On Thu, 2022-06-16 at 10:51 +0000, Christophe Leroy wrote:
> Hello
>
> Trying to build valgrind-3.19.0.
>
> ./configure --host=ppc-linux --prefix=/usr --enable-only32bit --
> disable-tls
>
> I'm using glibc-2.35
>
> I end up with following errors (many more of the same kind follows):
>
> /opt/cldk-1.5.1rc1b1/lib/gcc/ppc-linux/11.2.0/../../../../ppc-
> linux/bin/ld:
> memcheck_ppc32_linux-mc_main.o: in function `gcSecVBitTable':
> /home/chleroy/ldb_base/ofs/packages/valgrind-
> 3.19.0/memcheck/mc_main.c:993:
> undefined reference to `__floatsidf'
>
Not sure why your using cldk-1.5.1.1rc1b1 in /opt? Not sure what that
is?
When I tried the configure on a Power 10 64-bit system:
./configure --host=ppc-linux --prefix=/home/carll --enable-only32bit
--disable-tls
The configure went fine but the compile fails on
/usr/include/gnu/stubs.h:8:11: fatal error: gnu/stubs-32.h: No such
file or directory
Not sure what system you are on and why you need the enable-only32bit?
I normally build for 64-bit machines, so I tried:
./configure --host=ppc-linux --prefix=/home/carll --disable-tls
I see at the end of the configure:
Maximum build arch: ppc32
Primary build arch: ppc32
and again get a ppc32 related build error.
Since I am on a ppc64 LE system I did the following configure:
./configure --host=ppc64le-linux --prefix=/home/carll --disable-tls
Note, I am using the distro compiler /usr/bin/gcc and glibc. The build
works fine with the distro gcc and glibc. Can you set your paths to
use the default distro gcc and glib?
Note, the version of glibc that I am using, as given by the ldd
command, is:
$ ldd --version ldd
ldd (GNU libc) 2.34
Carl Love
|
|
From: Christophe L. <chr...@cs...> - 2022-06-16 11:06:15
|
Hello
Trying to build valgrind-3.19.0.
./configure --host=ppc-linux --prefix=/usr --enable-only32bit --disable-tls
I'm using glibc-2.35
I end up with following errors (many more of the same kind follows):
/opt/cldk-1.5.1rc1b1/lib/gcc/ppc-linux/11.2.0/../../../../ppc-linux/bin/ld:
memcheck_ppc32_linux-mc_main.o: in function `gcSecVBitTable':
/home/chleroy/ldb_base/ofs/packages/valgrind-3.19.0/memcheck/mc_main.c:993:
undefined reference to `__floatsidf'
/opt/cldk-1.5.1rc1b1/lib/gcc/ppc-linux/11.2.0/../../../../ppc-linux/bin/ld:
/home/chleroy/ldb_base/ofs/packages/valgrind-3.19.0/memcheck/mc_main.c:998:
undefined reference to `__floatsidf'
/opt/cldk-1.5.1rc1b1/lib/gcc/ppc-linux/11.2.0/../../../../ppc-linux/bin/ld:
/home/chleroy/ldb_base/ofs/packages/valgrind-3.19.0/memcheck/mc_main.c:998:
undefined reference to `__muldf3'
/opt/cldk-1.5.1rc1b1/lib/gcc/ppc-linux/11.2.0/../../../../ppc-linux/bin/ld:
/home/chleroy/ldb_base/ofs/packages/valgrind-3.19.0/memcheck/mc_main.c:997:
undefined reference to `__ltdf2'
/opt/cldk-1.5.1rc1b1/lib/gcc/ppc-linux/11.2.0/../../../../ppc-linux/bin/ld:
/home/chleroy/ldb_base/ofs/packages/valgrind-3.19.0/memcheck/mc_main.c:999:
undefined reference to `__muldf3'
/opt/cldk-1.5.1rc1b1/lib/gcc/ppc-linux/11.2.0/../../../../ppc-linux/bin/ld:
/home/chleroy/ldb_base/ofs/packages/valgrind-3.19.0/memcheck/mc_main.c:999:
undefined reference to `__fixdfsi'
/opt/cldk-1.5.1rc1b1/lib/gcc/ppc-linux/11.2.0/../../../../ppc-linux/bin/ld:
/home/chleroy/ldb_base/ofs/packages/valgrind-3.19.0/memcheck/mc_main.c:1008:
undefined reference to `__muldf3'
/opt/cldk-1.5.1rc1b1/lib/gcc/ppc-linux/11.2.0/../../../../ppc-linux/bin/ld:
/home/chleroy/ldb_base/ofs/packages/valgrind-3.19.0/memcheck/mc_main.c:1007:
undefined reference to `__ltdf2'
Looking at gcc history, I found:
commit e610393ca76b204d861177a9ec542e2b4b3956cb
Author: Joseph Myers <jo...@co...>
Date: Thu Oct 30 17:28:30 2014 +0000
Make soft-fp symbols into compat symbols for powerpc*-*-linux*.
Continuing preparations for implementing
TARGET_ATOMIC_ASSIGN_EXPAND_FENV for powerpc*-*-linux* soft-float and
e500, this patch makes soft-fp symbols used for those targets into
compat symbols when building with glibc >= 2.19, so that they are only
in shared libgcc for existing binaries requiring them, not in static
libgcc and not available for new links using shared libgcc. Instead,
new links will get the symbols from libc, which has exported all of
them since 2.19. ....
So I understand that libc is required to get those symbols. But I also
understand after reading comments in coregrind/m_main.c that valgrind is
intentionaly linked without libc but with libgcc only.
So how can I get the missing floating points symbols while linking
valgrind ?
Thanks
Christophe |
|
From: Reddy K <har...@gm...> - 2022-06-15 06:55:10
|
Hi Paul, Thank you very much for helping me. Sorry for the late reply. I thought of sharing the result of --trace-childern=yes but it has not crashed yet. So I will share those results once I get the crash report. Please find the details below. which Valgrind version : *valgrind-3.15.0-3.6.1.x86_64* which operating system : *"SUSE Linux Enterprise Server 12 SP5"* which compiler : *Linux version 4.12.14-122.103-default (geeko@buildhost) (gcc version 4.8.5 (SUSE Linux) ) #1 SMP Tue Nov 23 14:22:07 UTC 2021 (d263070*) earlier I was running the command like below and now I have added --trace-children=yes and will let you know the results. valgrind --tool=memcheck --num-callers=128 --log-file=./valgrind_2022may27_0128_bst.txt --error-limit=no --leak -check=full --show-reachable=yes /opt/novell/xad/sbin/start-xad-krb5kdc Thanks & Regards Haritha On Sat, May 28, 2022 at 12:35 AM Paul Floyd <pj...@wa...> wrote: > > On 5/27/22 14:55, Reddy K wrote: > > Hi Team, > > > > I am running valgrind for a process to check memory corruptions and I > > have installed all related debuginfo and debugsource for that process. > > > > Valgrind is stopping and the system is giving the below error on the > > terminal and there is no information related to this error in the > > messages file and also it is not giving the information about the > > memory allocation. > > > > -------------------- > > ** Error in `krb5kdc': free(): invalid next size (fast): > > 0x0000000001c8d8c0 *** > > -------------------------- > > > > I want to know why this is happening. So can you please me on this > > > > Hi > > You need to tell us more. The above message is not from Valgrind, it is > from libc. > > Could you tell us > > which Valgrind version > > which operating system > > which compiler > > you are using. > > > I also suggest that you run Valgrind with --trace-children=yes and send > the output if you do not understand it. > > > A+ > > Paul > > > > > _______________________________________________ > Valgrind-developers mailing list > Val...@li... > https://lists.sourceforge.net/lists/listinfo/valgrind-developers > |
|
From: Paul F. <pa...@so...> - 2022-06-15 05:08:34
|
https://sourceware.org/git/gitweb.cgi?p=valgrind.git;h=aaeb6f00c6969e559d9b7f033b198aae47e27e51 commit aaeb6f00c6969e559d9b7f033b198aae47e27e51 Author: Paul Floyd <pj...@wa...> Date: Wed Jun 15 07:06:25 2022 +0200 Add an expected for FreeBSD gdbserver_tests/nlcontrolc Diff: --- README.freebsd | 2 ++ gdbserver_tests/Makefile.am | 1 + gdbserver_tests/nlcontrolc.stdoutB.exp-freebsd | 22 ++++++++++++++++++++++ 3 files changed, 25 insertions(+) diff --git a/README.freebsd b/README.freebsd index f33ba2f9b6..6aab37b8d2 100644 --- a/README.freebsd +++ b/README.freebsd @@ -34,6 +34,8 @@ Known Limitations (June 2022) a) There may be missing source information concerning variables due to DWARF extensions ised by GCC. b) Code that uses OpenMP will generate spurious errors. +2. vgdb invoker, which uses ptrace, may cause system calls to be + interrupted. Notes for Developers ~~~~~~~~~~~~~~~~~~~~ diff --git a/gdbserver_tests/Makefile.am b/gdbserver_tests/Makefile.am index b47cfde10e..fbcb6596d4 100755 --- a/gdbserver_tests/Makefile.am +++ b/gdbserver_tests/Makefile.am @@ -113,6 +113,7 @@ EXTRA_DIST = \ nlcontrolc.stderr.exp \ nlcontrolc.stdinB.gdb \ nlcontrolc.stdoutB.exp \ + nlcontrolc.stdoutB.exp-freebsd \ nlcontrolc.vgtest \ nlfork_chain.stderr.exp \ nlfork_chain.stdout.exp \ diff --git a/gdbserver_tests/nlcontrolc.stdoutB.exp-freebsd b/gdbserver_tests/nlcontrolc.stdoutB.exp-freebsd new file mode 100644 index 0000000000..4de07a757f --- /dev/null +++ b/gdbserver_tests/nlcontrolc.stdoutB.exp-freebsd @@ -0,0 +1,22 @@ +Continuing. +Program received signal SIGTRAP, Trace/breakpoint trap. +do_burn () at sleepers.c:40 +40 for (i = 0; i < burn; i++) loopnr++; + > > > > > > 1 + 3 +$1 = 0 +$2 = 1000000 +changed burning parameters to sleeping parameters +Continuing. +Program received signal SIGTRAP, Trace/breakpoint trap. +0x........ in syscall ... +* 1 Thread .... (tid 1 VgTs_WaitSys) 0x........ in syscall ... +$3 = 0 +reset to sleeping parameters +Continuing. +Program received signal SIGTRAP, Trace/breakpoint trap. +sleeper_or_burner (v=0x........) at sleepers.c:81 +81 for (i = 0; i < loops; i++) { +* 1 Thread .... (tid 1 VgTs_Runnable) 0x........ in sleeper_or_burner (v=0x........) at sleepers.c:81 + > > > > 3 +Kill the program being debugged? (y or n) [answered Y; input not from terminal] |
|
From: Paul F. <pa...@so...> - 2022-06-14 20:47:36
|
https://sourceware.org/git/gitweb.cgi?p=valgrind.git;h=a108669a184a7bb93324c2a193b14245cad7365d commit a108669a184a7bb93324c2a193b14245cad7365d Author: Paul Floyd <pj...@wa...> Date: Tue Jun 14 22:39:31 2022 +0200 Implement vgdb invoker on FreeBSD This is a translation of the Linux vgdb-invoker-ptrace.c to the FreeBSD ptrace dialect. It seems to be basically functional (3 out of 4 of the regression tests pass, and for the 4th one it seems to be a limitation of ptrace on FreeBSD that it can cause syscalls to be interrupted). Diff: --- NEWS | 1 + coregrind/Makefile.am | 5 +- coregrind/vgdb-invoker-freebsd.c | 620 +++++++++++++++++++++++++++++++++++++++ include/vki/vki-freebsd.h | 49 ++-- 4 files changed, 639 insertions(+), 36 deletions(-) diff --git a/NEWS b/NEWS index 1f92c25e3d..eb098b1d07 100644 --- a/NEWS +++ b/NEWS @@ -42,6 +42,7 @@ are not entered into bugzilla tend to get forgotten about or ignored. 453055 shared_timed_mutex drd test fails with "Lock shared failed" message 453602 Missing command line option to enable/disable debuginfod 452802 Handle lld 9+ split RW PT_LOAD segments correctly +n-i-bz Implement vgdb invoker on FreeBSD To see details of a given bug, visit https://bugs.kde.org/show_bug.cgi?id=XXXXXX diff --git a/coregrind/Makefile.am b/coregrind/Makefile.am index 76c0aebc9d..151f5c2f00 100644 --- a/coregrind/Makefile.am +++ b/coregrind/Makefile.am @@ -98,10 +98,7 @@ if VGCONF_OS_IS_SOLARIS vgdb_SOURCES += vgdb-invoker-solaris.c endif if VGCONF_OS_IS_FREEBSD -# As with Darwin, we don't have ptrace PTRACE_PEEKTEXT -# so we can't use vgdb-invoker-ptrace.c -# Need to find an alternative, like Solaris -vgdb_SOURCES += vgdb-invoker-none.c +vgdb_SOURCES += vgdb-invoker-freebsd.c endif vgdb_CPPFLAGS = $(AM_CPPFLAGS_PRI) diff --git a/coregrind/vgdb-invoker-freebsd.c b/coregrind/vgdb-invoker-freebsd.c new file mode 100644 index 0000000000..2350de8caa --- /dev/null +++ b/coregrind/vgdb-invoker-freebsd.c @@ -0,0 +1,620 @@ +/*--------------------------------------------------------------------*/ +/*--- Implementation of vgdb invoker subsystem via ptrace() calls. ---*/ +/*--------------------------------------------------------------------*/ + +/* + This file is part of Valgrind, a dynamic binary instrumentation + framework. + + Copyright (C) 2011-2017 Philippe Waroquiers + Copyright (C) 2021-2022 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. +*/ + +#include "config.h" + +#include "vgdb.h" +#include "pub_core_threadstate.h" + +#include <assert.h> +#include <errno.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <signal.h> +#include <sys/ptrace.h> +#include <sys/time.h> +#include <sys/user.h> +#include <sys/wait.h> +#include <sys/uio.h> +#include <elf.h> +#include <sys/procfs.h> + +/* + * This file is largely a copy of vgdb-invoker-ptrace.c + * + * Sadly, though ptrace exists on most unix-like systems, + * no two versions are the same. + * + * The main two differences are that + * - FreeBSD ptrace works at the process level, not lwps + * so just attaching to the main pid stops everything + * (no need to read memory to get lwpids and stop all of the + * threads) + * - Reading registers is a lot simpler. + * + * Known limitations: + * gdbserver_tests/nlcontrolc has different behaviour + * becase attaching causes the select() syscall of main + * to be interrupted. This seems to be a "feature" of + * ptrace on FreeBSD so I doubt it can be fixed. + * + */ + +// 32-bit or 64-bit wide, depending on primary architecture. +typedef Addr CORE_ADDR; +typedef int PTRACE_XFER_TYPE; +typedef caddr_t PTRACE_ARG3_TYPE; + +// if > 0, pid for which registers have to be restored. +// if == 0, means we have not yet called setregs (or have already +// restored the registers). +static int pid_of_save_regs = 0; +/* True if we have continued pid_of_save_regs after PT_ATTACH. */ +static Bool pid_of_save_regs_continued = False; +// When setregs has been called to change the registers of pid_of_save_regs, +// vgdb cannot transmit the signals intercepted during ptrace. +// So, we queue them, and will deliver them when detaching. +// See function waitstopped for more info. +static int signal_queue_sz = 0; +static siginfo_t *signal_queue; + +/* True when loss of connection indicating that the Valgrind + process is dying. */ +static Bool dying = False; + +/* Copy LEN bytes of data from vgdb memory at MYADDR + to valgrind memory at MEMADDR. + On failure (cannot write the valgrind memory) + returns the value of errno. */ +__attribute__((unused)) /* not used on all platforms */ +static +int ptrace_write_memory (pid_t inferior_pid, CORE_ADDR memaddr, + const void *myaddr, size_t len) +{ + size_t i; + /* Round starting address down to longword boundary. */ + CORE_ADDR addr = memaddr & -(CORE_ADDR) sizeof (PTRACE_XFER_TYPE); + /* Round ending address up; get number of longwords that makes. */ + size_t count + = (((memaddr + len) - addr) + sizeof (PTRACE_XFER_TYPE) - 1) + / sizeof (PTRACE_XFER_TYPE); + /* Allocate buffer of that many longwords. */ + PTRACE_XFER_TYPE *buffer + = (PTRACE_XFER_TYPE *) alloca (count * sizeof (PTRACE_XFER_TYPE)); + + if (debuglevel >= 1) { + DEBUG (1, "Writing "); + for (i = 0; i < len; i++) + PDEBUG (1, "%02x", ((const unsigned char*)myaddr)[i]); + PDEBUG(1, " to %p\n", (void *) memaddr); + } + + /* Fill start and end extra bytes of buffer with existing memory data. */ + + buffer[0] = ptrace (PT_READ_I, inferior_pid, + (PTRACE_ARG3_TYPE) addr, 0); + + if (count > 1) { + buffer[count - 1] + = ptrace (PT_READ_I, inferior_pid, + (PTRACE_ARG3_TYPE) (addr + (count - 1) + * sizeof (PTRACE_XFER_TYPE)), + 0); + } + + /* Copy data to be written over corresponding part of buffer */ + + memcpy ((char *) buffer + (memaddr & (sizeof (PTRACE_XFER_TYPE) - 1)), + myaddr, len); + + /* Write the entire buffer. */ + + for (i = 0; i < count; i++, addr += sizeof (PTRACE_XFER_TYPE)) { + errno = 0; + ptrace (PT_WRITE_I, inferior_pid, + (PTRACE_ARG3_TYPE) addr, buffer[i]); + if (errno) + return errno; + } + + return 0; +} + +static +char *status_image (int status) +{ + static char result[256]; // large enough + int sz = 0; +#define APPEND(...) sz += snprintf (result+sz, 256 - sz - 1, __VA_ARGS__) + + result[0] = 0; + + if (WIFEXITED(status)) + APPEND ("WIFEXITED %d ", WEXITSTATUS(status)); + + if (WIFSIGNALED(status)) { + APPEND ("WIFSIGNALED %d ", WTERMSIG(status)); + if (WCOREDUMP(status)) APPEND ("WCOREDUMP "); + } + + if (WIFSTOPPED(status)) + APPEND ("WIFSTOPPED %d ", WSTOPSIG(status)); + +#ifdef WIFCONTINUED + if (WIFCONTINUED(status)) + APPEND ("WIFCONTINUED "); +#endif + + return result; +#undef APPEND +} + +/* Wait till the process pid is reported as stopped with signal_expected. + If other signal(s) than signal_expected are received, waitstopped + will pass them to pid, waiting for signal_expected to stop pid. + Returns True when process is in stopped state with signal_expected. + Returns False if a problem was encountered while waiting for pid + to be stopped. + + If pid is reported as being dead/exited, waitstopped will return False. +*/ +static +Bool waitstopped (pid_t pid, int signal_expected, const char *msg) +{ + pid_t p; + int status = 0; + int signal_received; + int res; + + while (1) { + DEBUG(1, "waitstopped %s before waitpid signal_expected %d\n", + msg, signal_expected); + p = waitpid(pid, &status, 0); /* PJF options was __WALL */ + DEBUG(1, "after waitpid pid %d p %d status 0x%x %s\n", pid, p, + status, status_image (status)); + if (p != pid) { + ERROR(errno, "%s waitpid pid %d in waitstopped %d status 0x%x %s\n", + msg, pid, p, status, status_image (status)); + return False; + } + + /* The process either exited or was terminated by a (fatal) signal. */ + if (WIFEXITED(status) || WIFSIGNALED(status)) { + shutting_down = True; + return False; + } + + assert (WIFSTOPPED(status)); + signal_received = WSTOPSIG(status); + if (signal_received == signal_expected) + break; + + /* pid received a signal which is not the signal we are waiting for. + If we have not (yet) changed the registers of the inferior + or we have (already) reset them, we can transmit the signal. + + If we have already set the registers of the inferior, we cannot + transmit the signal, as this signal would arrive when the + gdbserver code runs. And valgrind only expects signals to + arrive in a small code portion around + client syscall logic, where signal are unmasked (see e.g. + m_syswrap/syscall-x86-linux.S ML_(do_syscall_for_client_WRK). + + As ptrace is forcing a call to gdbserver by jumping + 'out of this region', signals are not masked, but + will arrive outside of the allowed/expected code region. + So, if we have changed the registers of the inferior, we + rather queue the signal to transmit them when detaching, + after having restored the registers to the initial values. */ + if (pid_of_save_regs) { + siginfo_t *newsiginfo; + struct ptrace_lwpinfo new_lwpinfo; + + // realloc a bigger queue, and store new signal at the end. + // This is not very efficient but we assume not many sigs are queued. + if (signal_queue_sz >= 64) { + DEBUG(0, "too many queued signals while waiting for SIGSTOP\n"); + return False; + } + signal_queue_sz++; + signal_queue = vrealloc(signal_queue, + sizeof(siginfo_t) * signal_queue_sz); + newsiginfo = signal_queue + (signal_queue_sz - 1); + + res = ptrace (PT_LWPINFO, pid, (caddr_t)&new_lwpinfo, sizeof(new_lwpinfo)); + *newsiginfo = new_lwpinfo.pl_siginfo; + if (res != 0) { + ERROR(errno, "PT_LWPINFO failed: signal lost !!!!\n"); + signal_queue_sz--; + } else + DEBUG(1, "waitstopped PTRACE_CONT, queuing signal %d" + " si_signo %d si_pid %d\n", + signal_received, newsiginfo->si_signo, newsiginfo->si_pid); + res = ptrace (PT_CONTINUE, pid, (caddr_t)1, 0); + } else { + DEBUG(1, "waitstopped PT_CONTINUE with signal %d\n", signal_received); + res = ptrace (PT_CONTINUE, pid, (caddr_t)1, signal_received); + } + if (res != 0) { + ERROR(errno, "waitstopped PTRACE_CONT\n"); + return False; + } + } + + return True; +} + +/* Stops the given pid, wait for the process to be stopped. + Returns True if successful, False otherwise. + msg is used in tracing and error reporting. */ +static +Bool stop (pid_t pid, const char *msg) +{ + long res; + + DEBUG(1, "%s SIGSTOP pid %d\n", msg, pid); + res = kill (pid, SIGSTOP); + if (res != 0) { + ERROR(errno, "%s SIGSTOP pid %d %ld\n", msg, pid, res); + return False; + } + + return waitstopped (pid, SIGSTOP, msg); + +} + +/* Attaches to given pid, wait for the process to be stopped. + Returns True if successful, False otherwise. + msg is used in tracing and error reporting. */ +static +Bool attach (pid_t pid, const char *msg) +{ + int res; + static Bool output_error = True; + static Bool initial_attach = True; + // For a ptrace_scope protected system, we do not want to output + // repetitively attach error. We will output once an error + // for the initial_attach. Once the 1st attach has succeeded, we + // again show all errors. + + DEBUG(1, "%s PT_ATTACH pid %d\n", msg, pid); + res = ptrace (PT_ATTACH, pid, 0, 0); + if (res != 0) { + if (output_error || debuglevel > 0) { + ERROR(errno, "%s PT_ATTACH pid %d %ld\n", msg, pid, res); + if (initial_attach) + output_error = False; + } + return False; + } + + initial_attach = False; + output_error = True; + return waitstopped(pid, SIGSTOP, msg); +} + +static +void detach_from_all_threads (pid_t pid) +{ + long res = ptrace (PT_DETACH, pid, NULL, 0); + + if (res != 0) { + ERROR(errno, "PT_DETACH pid %d res %ld\n", + pid, res); + } +} + +static struct reg reg_save; + +/* Get the registers from pid into regs. + Returns True if all ok, otherwise False. */ +static +Bool getregs (pid_t pid, struct reg *regs) +{ + if (ptrace(PT_GETREGS, pid, (caddr_t)regs, 0) < 0) { + return False; + } + return True; +} + +/* Set the registers of pid to regs. + Returns True if all ok, otherwise False. */ +static +Bool setregs (pid_t pid, struct reg *regs) +{ + if (ptrace(PT_SETREGS, pid, (caddr_t)regs, 0) < 0) { + return False; + } + return True; +} + +/* Restore the registers to the saved value, then detaches from all threads */ +static +void restore_and_detach (pid_t pid) +{ + int res; + + DEBUG(1, "restore_and_detach pid %d pid_of_save_regs %d\n", + pid, pid_of_save_regs); + + if (pid_of_save_regs) { + /* In case the 'main pid' has been continued, we need to stop it + before resetting the registers. */ + if (pid_of_save_regs_continued) { + pid_of_save_regs_continued = False; + if (!stop(pid_of_save_regs, "sigstop before reset regs")) + DEBUG(0, "Could not sigstop before reset"); + } + + DEBUG(1, "setregs restore registers pid %d\n", pid_of_save_regs); + if (!setregs(pid_of_save_regs, ®_save)) { + ERROR(errno, "setregs restore registers pid %d after cont\n", + pid_of_save_regs); + } + + /* Now, we transmit all the signals we have queued. */ + if (signal_queue_sz > 0) { + int i; + for (i = 0; i < signal_queue_sz; i++) { + DEBUG(1, "PTRACE_CONT to transmit queued signal %d\n", + signal_queue[i].si_signo); + res = ptrace (PT_CONTINUE, pid_of_save_regs, (caddr_t)1, + signal_queue[i].si_signo); + if (res != 0) + ERROR(errno, "PT_CONTINUE with signal %d\n", + signal_queue[i].si_signo); + if (!stop(pid_of_save_regs, "sigstop after transmit sig")) + DEBUG(0, "Could not sigstop after transmit sig"); + } + free (signal_queue); + signal_queue = NULL; + signal_queue_sz = 0; + } + pid_of_save_regs = 0; + } else { + DEBUG(1, "PTRACE_SETREGS restore registers: no pid\n"); + } + if (signal_queue) + ERROR (0, "One or more signals queued were not delivered. " + "First signal: %d\n", signal_queue[0].si_signo); + detach_from_all_threads(pid); +} + +Bool invoker_invoke_gdbserver (pid_t pid) +{ + long res; + Bool stopped; + struct reg reg_mod; + Addr sp __attribute__((unused)); // Not used on all platforms. + + /* A specific int value is passed to invoke_gdbserver, to check + everything goes according to the plan. */ + const int check = 0x8BADF00D; // ate bad food. + + const Addr bad_return = 0; + // A bad return address will be pushed on the stack. + // The function invoke_gdbserver cannot return. If ever it returns, a NULL + // address pushed on the stack should ensure this is detected. + + /* Not yet attached. If problem, vgdb can abort, + no cleanup needed. */ + + DEBUG(1, "attach to 'main' pid %d\n", pid); + if (!attach(pid, "attach main pid")) { + ERROR(0, "error attach main pid %d\n", pid); + return False; + } + + /* Now, we are attached. If problem, detach and return. */ + + DEBUG(1, "calling getregs\n"); + + if (!getregs(pid, ®_mod)) { + detach_from_all_threads(pid); + return False; + } + reg_save = reg_mod; + + DEBUG(1, "getregs call succeeded\n"); + +#if defined(VGA_x86) + sp = reg_mod.r_esp; +#elif defined(VGA_amd64) + sp = reg_mod.r_rsp; + if (shared32 != NULL) { + /* 64bit vgdb speaking with a 32bit executable. + To have system call restart properly, we need to sign extend rax. + For more info: + web search '[patch] Fix syscall restarts for amd64->i386 biarch' + e.g. http://sourceware.org/ml/gdb-patches/2009-11/msg00592.html */ + *(long *)®_save.r_rax = *(int*)®_save.r_rax; + DEBUG(1, "Sign extending %8.8lx to %8.8lx\n", + reg_mod.r_rax, reg_save.r_rax); + } +#else + I_die_here : (sp) architecture missing in vgdb-invoker-freebsd.c +#endif + + + // the magic below is derived from spying what gdb sends to + // the (classical) gdbserver when invoking a C function. + if (shared32 != NULL) { + // vgdb speaking with a 32bit executable. +#if defined(VGA_x86) || defined(VGA_amd64) + const int regsize = 4; + int rw; + /* push check arg on the stack */ + sp = sp - regsize; + DEBUG(1, "push check arg ptrace_write_memory\n"); + assert(regsize == sizeof(check)); + rw = ptrace_write_memory(pid, sp, + &check, + regsize); + if (rw != 0) { + ERROR(rw, "push check arg ptrace_write_memory"); + detach_from_all_threads(pid); + return False; + } + + sp = sp - regsize; + DEBUG(1, "push bad_return return address ptrace_write_memory\n"); + // Note that for a 64 bits vgdb, only 4 bytes of NULL bad_return + // are written. + rw = ptrace_write_memory(pid, sp, + &bad_return, + regsize); + if (rw != 0) { + ERROR(rw, "push bad_return return address ptrace_write_memory"); + detach_from_all_threads(pid); + return False; + } +#if defined(VGA_x86) + /* set ebp, esp, eip and orig_eax to invoke gdbserver */ + // compiled in 32bits, speaking with a 32bits exe + reg_mod.r_ebp = sp; // bp set to sp + reg_mod.r_esp = sp; + reg_mod.r_eip = shared32->invoke_gdbserver; +#elif defined(VGA_amd64) + /* set ebp, esp, eip and orig_eax to invoke gdbserver */ + // compiled in 64bits, speaking with a 32bits exe + reg_mod.r_rbp = sp; // bp set to sp + reg_mod.r_rsp = sp; + reg_mod.r_rip = shared32->invoke_gdbserver; +#else + I_die_here : not x86 or amd64 in x86/amd64 section/ +#endif + +#else + I_die_here : architecture missing in vgdb-invoker-freebsd.c +#endif + } + + else if (shared64 != NULL) { +#if defined(VGA_x86) + assert(0); // cannot vgdb a 64 bits executable with a 32 bits exe +#elif defined(VGA_amd64) + // vgdb speaking with a 64 bit executable. + const int regsize = 8; + int rw; + + /* give check arg in rdi */ + reg_mod.r_rdi = check; + + /* push return address on stack : return to breakaddr */ + sp &= ~0xf; // keep the stack aligned on 16 bytes ... + //sp = sp - 128; // do not touch the amd64 redzone + sp = sp - regsize; + DEBUG(1, "push bad_return return address ptrace_write_memory\n"); + rw = ptrace_write_memory(pid, sp, + &bad_return, + sizeof(bad_return)); + if (rw != 0) { + ERROR(rw, "push bad_return return address ptrace_write_memory"); + detach_from_all_threads(pid); + return False; + } + + /* set rbp, rsp, rip and orig_rax to invoke gdbserver */ + reg_mod.r_rbp = sp; // bp set to sp + reg_mod.r_rsp = sp; + reg_mod.r_rip = shared64->invoke_gdbserver; + +#else + I_die_here: architecture missing in vgdb-invoker-freebsd.c +#endif + } + else { + assert(0); + } + + DEBUG(1, "calling setregs\n"); + + if (!setregs(pid, ®_mod)) { + detach_from_all_threads(pid); + return False; + } + + DEBUG(1, "setregs succeeded\n"); + + /* Now that we have modified the registers, we set + pid_of_save_regs to indicate that restore_and_detach + must restore the registers in case of cleanup. */ + pid_of_save_regs = pid; + pid_of_save_regs_continued = False; + + + /* We PTRACE_CONT-inue pid. + Either gdbserver will be invoked directly (if all + threads are interruptible) or gdbserver will be + called soon by the scheduler. In the first case, + pid will stop on the break inserted above when + gdbserver returns. In the 2nd case, the break will + be encountered directly. */ + DEBUG(1, "PT_CONTINUE to invoke\n"); + /* an address of 1 means continue without modifying IP + since we already set IP above there is no need to set it here */ + res = ptrace (PT_CONTINUE, pid, (caddr_t)1, 0); + if (res != 0) { + ERROR(errno, "PT_CONTINUE\n"); + restore_and_detach(pid); + return False; + } + pid_of_save_regs_continued = True; + /* Wait for SIGSTOP generated by m_gdbserver.c give_control_back_to_vgdb */ + stopped = waitstopped (pid, SIGSTOP, + "waitpid status after PTRACE_CONT to invoke"); + if (stopped) { + /* Here pid has properly stopped on the break. */ + pid_of_save_regs_continued = False; + restore_and_detach(pid); + return True; + } else { + /* Whatever kind of problem happened. We shutdown. */ + shutting_down = True; + return False; + } +} + +void invoker_cleanup_restore_and_detach(void *v_pid) +{ + DEBUG(1, "invoker_cleanup_restore_and_detach dying: %d\n", dying); + if (!dying) + restore_and_detach(*(int*)v_pid); +} + +void invoker_restrictions_msg(void) +{ +} + +void invoker_valgrind_dying(void) +{ + /* Avoid messing up with registers of valgrind when it is dying. */ + pid_of_save_regs_continued = False; + dying = True; +} diff --git a/include/vki/vki-freebsd.h b/include/vki/vki-freebsd.h index a94fe9477f..ef5b27d6a7 100644 --- a/include/vki/vki-freebsd.h +++ b/include/vki/vki-freebsd.h @@ -40,21 +40,6 @@ is used. The files the code is taken from is indicated. - - Note especially that the types are not the glibc versions, many of which - are different to those in here. - - Also note that this file contains all the generic header info, ie. that - from linux/include/linux/ *.h. The arch-specific header info, eg. that - from linux/include/asm-i386/ *.h, is in vki-$PLATFORM.h and - vki_posixtypes-$PLATFORM.h. (Two files are required to avoid - circular dependencies between the generic VKI header and the - arch-specific VKI header. It's possible in the future, as more stuff - gets pulled in, that we might have to split files up some more to avoid - further circular dependencies.) - - Finally, note that it is assumed that __KERNEL__ is set for all these - definitions, which affects some of them. */ #ifndef VKI_FREEBSD_H @@ -1448,22 +1433,22 @@ union vki_semun { #define VKI_WNOHANG 0x00000001 typedef enum vki_idtype { - P_PID, - P_PPID, - P_PGID, - P_SID, - P_CID, - P_UID, - P_GID, - P_ALL, - P_LWPID, - P_TASKID, - P_PROJID, - P_POOLID, - P_JAILID, - P_CTID, - P_CPUID, - P_PSETID + VKI_P_PID, + VKI_P_PPID, + VKI_P_PGID, + VKI_P_SID, + VKI_P_CID, + VKI_P_UID, + VKI_P_GID, + VKI_P_ALL, + VKI_P_LWPID, + VKI_P_TASKID, + VKI_P_PROJID, + VLI_P_POOLID, + VKI_P_JAILID, + VKI_P_CTID, + VKI_P_CPUID, + VKI_P_PSETID } vki_idtype_t; //---------------------------------------------------------------------- @@ -1535,7 +1520,7 @@ struct vki_dirent { vki_uint16_t d_reclen; vki_uint8_t d_type; vki_uint8_t d_namelen; - char d_name[256]; /* We must not include limits.h! */ + char vki_d_name[256]; /* We must not include limits.h! */ }; //---------------------------------------------------------------------- |
|
From: Mark W. <ma...@so...> - 2022-06-14 19:24:58
|
https://sourceware.org/git/gitweb.cgi?p=valgrind.git;h=026cda6c8111ef6ff79bd5c6e083ab50ccf3ded6 commit 026cda6c8111ef6ff79bd5c6e083ab50ccf3ded6 Author: Luboš Luňák <l....@ce...> Date: Tue Apr 26 13:53:14 2022 +0200 support DW_FORM_addrx3 and DW_FORM_strx3 Apparently these may get used after all with large enough binaries, despite being somewhat tricky with regard to endianess. Diff: --- coregrind/m_debuginfo/readdwarf3.c | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/coregrind/m_debuginfo/readdwarf3.c b/coregrind/m_debuginfo/readdwarf3.c index 5a031a6043..96bd21f7f7 100644 --- a/coregrind/m_debuginfo/readdwarf3.c +++ b/coregrind/m_debuginfo/readdwarf3.c @@ -314,6 +314,25 @@ static Long get_SLEB128 ( Cursor* c ) { result |= -(1ULL << shift); return result; } +static UInt get_UInt3 ( Cursor* c ) { + UChar c1, c2, c3; + vg_assert(is_sane_Cursor(c)); + if (c->sli_next + 3 > c->sli.ioff + c->sli.szB) { + c->barf(c->barfstr); + /*NOTREACHED*/ + vg_assert(0); + } + c1 = ML_(img_get_UChar)(c->sli.img, c->sli_next); + c2 = ML_(img_get_UChar)(c->sli.img, c->sli_next+1); + c3 = ML_(img_get_UChar)(c->sli.img, c->sli_next+2); + c->sli_next += 3; +#if defined(VG_BIGENDIAN) + return c1 << 16 | c2 << 8 | c3; +#else + return c1 | c2 << 8 | c3 << 16; +#endif +} + /* Assume 'c' points to the start of a string. Return a DiCursor of whatever it points at, and advance it past the terminating zero. @@ -1846,6 +1865,12 @@ void get_Form_contents ( /*OUT*/FormContents* cts, get_Form_contents_addr(cts, form, index, cc, td3); break; } + case DW_FORM_addrx3: { + /* this is an offset into .debug_addr */ + ULong index = (ULong)get_UInt3(c); + get_Form_contents_addr(cts, form, index, cc, td3); + break; + } case DW_FORM_addrx4: { /* this is an offset into .debug_addr */ ULong index = (ULong)get_UInt(c); @@ -1870,6 +1895,12 @@ void get_Form_contents ( /*OUT*/FormContents* cts, get_Form_contents_str_offsets(cts, form, index, cc, td3); break; } + case DW_FORM_strx3: { + /* this is an offset into .debug_str_offsets */ + ULong index = (ULong)get_UInt3(c); + get_Form_contents_str_offsets(cts, form, index, cc, td3); + break; + } case DW_FORM_strx4: { /* this is an offset into .debug_str_offsets */ ULong index = (ULong)get_UInt(c); |
|
From: Mark W. <ma...@so...> - 2022-06-14 19:09:33
|
https://sourceware.org/git/gitweb.cgi?p=valgrind.git;h=4bb0164e6b2067376f085452a40137f13436384c commit 4bb0164e6b2067376f085452a40137f13436384c Author: Luboš Luňák <l....@ce...> Date: Mon Apr 25 22:11:27 2022 +0200 implement support for missing DW_LLE_* and DW_RLE_* values Diff: --- coregrind/m_debuginfo/d3basics.c | 31 ++++++++++++ coregrind/m_debuginfo/priv_d3basics.h | 2 + coregrind/m_debuginfo/readdwarf3.c | 93 ++++++++++++++++++++++++++++------- 3 files changed, 109 insertions(+), 17 deletions(-) diff --git a/coregrind/m_debuginfo/d3basics.c b/coregrind/m_debuginfo/d3basics.c index 555e1e00d0..d48589a30c 100644 --- a/coregrind/m_debuginfo/d3basics.c +++ b/coregrind/m_debuginfo/d3basics.c @@ -435,6 +435,37 @@ const HChar* ML_(pp_DW_AT) ( DW_AT attr ) return "DW_AT_???"; } +const HChar* ML_(pp_DW_LLE) ( DW_LLE entry ) +{ + switch (entry) { + case DW_LLE_end_of_list: return "DW_LLE_end_of_list"; + case DW_LLE_base_addressx: return "DW_LLE_base_addressx"; + case DW_LLE_startx_endx: return "DW_LLE_startx_endx"; + case DW_LLE_startx_length: return "DW_LLE_startx_length"; + case DW_LLE_offset_pair: return "DW_LLE_offset_pair"; + case DW_LLE_default_location: return "DW_LLE_default_location"; + case DW_LLE_base_address: return "DW_LLE_base_address"; + case DW_LLE_start_end: return "DW_LLE_start_end"; + case DW_LLE_start_length: return "DW_LLE_start_length"; + case DW_LLE_GNU_view_pair: return "DW_LLE_GNU_view_pair"; + } + return "DW_LLE_???"; +} + +const HChar* ML_(pp_DW_RLE) ( DW_RLE entry ) +{ + switch (entry) { + case DW_RLE_end_of_list: return "DW_RLE_end_of_list"; + case DW_RLE_base_addressx: return "DW_RLE_base_addressx"; + case DW_RLE_startx_endx: return "DW_RLE_startx_endx"; + case DW_RLE_startx_length: return "DW_RLE_startx_length"; + case DW_RLE_offset_pair: return "DW_RLE_offset_pair"; + case DW_RLE_base_address: return "DW_RLE_base_address"; + case DW_RLE_start_end: return "DW_RLE_start_end"; + case DW_RLE_start_length: return "DW_RLE_start_length"; + } + return "DW_RLE_???"; +} /* ------ To do with evaluation of Dwarf expressions ------ */ diff --git a/coregrind/m_debuginfo/priv_d3basics.h b/coregrind/m_debuginfo/priv_d3basics.h index 9d825e39ef..3f6e5c72c9 100644 --- a/coregrind/m_debuginfo/priv_d3basics.h +++ b/coregrind/m_debuginfo/priv_d3basics.h @@ -768,6 +768,8 @@ const HChar* ML_(pp_DW_children) ( DW_children hashch ); const HChar* ML_(pp_DW_TAG) ( DW_TAG tag ); const HChar* ML_(pp_DW_FORM) ( DW_FORM form ); const HChar* ML_(pp_DW_AT) ( DW_AT attr ); +const HChar* ML_(pp_DW_LLE) ( DW_LLE entry ); +const HChar* ML_(pp_DW_RLE) ( DW_RLE entry ); /* --- To do with evaluation of Dwarf expressions --- */ diff --git a/coregrind/m_debuginfo/readdwarf3.c b/coregrind/m_debuginfo/readdwarf3.c index 86af340ebc..5a031a6043 100644 --- a/coregrind/m_debuginfo/readdwarf3.c +++ b/coregrind/m_debuginfo/readdwarf3.c @@ -576,6 +576,55 @@ static UWord uncook_die( const CUConst *cc, UWord die, /*OUT*/Bool *type_flag, return die; } +/* Return an entry from .debug_addr with the given index. + Call one of the variants below that do error-checking. */ +static ULong get_debug_addr_entry_common( ULong index, const CUConst* cc ) +{ + vg_assert(cc->cu_has_addr_base); + /* We make the same word-size assumption as DW_FORM_addr. */ + UWord addr_pos = cc->cu_addr_base + index * sizeof(UWord); + Cursor cur; + init_Cursor( &cur, cc->escn_debug_addr, addr_pos, cc->barf, + "get_debug_addr_entry_common: index points outside .debug_addr" ); + return (ULong)(UWord)get_UWord(&cur); +} + +static ULong get_debug_addr_entry_form( ULong index, const CUConst* cc, + DW_FORM form ) +{ + if(!cc->cu_has_addr_base) { + VG_(printf)( + "get_debug_addr_entry_form: %u (%s) without DW_AT_addr_base\n", + form, ML_(pp_DW_FORM)(form)); + cc->barf("get_debug_addr_entry_form: DW_AT_addr_base not set"); + } + return get_debug_addr_entry_common( index, cc ); +} + +static ULong get_debug_addr_entry_lle( ULong index, const CUConst* cc, + DW_LLE entry ) +{ + if(!cc->cu_has_addr_base) { + VG_(printf)( + "get_debug_addr_entry_lle: %u (%s) without DW_AT_addr_base\n", + entry, ML_(pp_DW_LLE)(entry)); + cc->barf("get_debug_addr_entry_lle: DW_AT_addr_base not set"); + } + return get_debug_addr_entry_common( index, cc ); +} + +static ULong get_debug_addr_entry_rle( ULong index, const CUConst* cc, + DW_RLE entry ) +{ + if(!cc->cu_has_addr_base) { + VG_(printf)( + "get_debug_addr_entry_rle: %u (%s) without DW_AT_addr_base\n", + entry, ML_(pp_DW_RLE)(entry)); + cc->barf("get_debug_addr_entry_rle: DW_AT_addr_base not set"); + } + return get_debug_addr_entry_common( index, cc ); +} + /*------------------------------------------------------------*/ /*--- ---*/ /*--- Helper functions for Guarded Expressions ---*/ @@ -784,8 +833,22 @@ static GExpr* make_general_GX ( const CUConst* cc, get_ULEB128( &loc ); break; case DW_LLE_base_addressx: + base = get_debug_addr_entry_lle( get_ULEB128( &loc ), cc, + DW_LLE_base_addressx ); + break; case DW_LLE_startx_endx: + w1 = get_debug_addr_entry_lle( get_ULEB128( &loc ), cc, + DW_LLE_startx_endx ); + w2 = get_debug_addr_entry_lle( get_ULEB128( &loc ), cc, + DW_LLE_startx_endx ); + len = get_ULEB128( &loc ); + break; case DW_LLE_startx_length: + w1 = get_debug_addr_entry_lle( get_ULEB128( &loc ), cc, + DW_LLE_startx_length ); + w2 = w1 + get_ULEB128( &loc ); + len = get_ULEB128( &loc ); + break; case DW_LLE_default_location: default: cc->barf( "Unhandled or unknown loclists entry" ); @@ -1007,8 +1070,20 @@ get_range_list ( const CUConst* cc, w2 = get_UWord ( &ranges ); break; case DW_RLE_base_addressx: + base = get_debug_addr_entry_rle( get_ULEB128( &ranges ), cc, + DW_RLE_base_addressx ); + break; case DW_RLE_startx_endx: + w1 = get_debug_addr_entry_rle( get_ULEB128( &ranges ), cc, + DW_RLE_startx_endx ); + w2 = get_debug_addr_entry_rle( get_ULEB128( &ranges ), cc, + DW_RLE_startx_endx ); + break; case DW_RLE_startx_length: + w1 = get_debug_addr_entry_rle( get_ULEB128( &ranges ), cc, + DW_RLE_startx_length ); + w2 = w1 + get_ULEB128( &ranges ); + break; default: cc->barf( "Unhandled or unknown range list entry" ); done = True; @@ -1312,23 +1387,7 @@ typedef static void get_Form_contents_addr( /*OUT*/FormContents* cts, DW_FORM form, ULong index, const CUConst* cc, Bool td3 ) { - if(!cc->cu_has_addr_base) { - VG_(printf)( - "get_Form_contents_addr: %u (%s) without DW_AT_addr_base\n", - form, ML_(pp_DW_FORM)(form)); - cc->barf("get_Form_contents_addr: DW_AT_addr_base not set"); - } - /* We make the same word-size assumption as DW_FORM_addr. */ - UWord addr_pos = cc->cu_addr_base + index * sizeof(UWord); - Cursor cur; - init_Cursor( &cur, cc->escn_debug_addr, addr_pos, cc->barf, - "get_Form_contents_addr: index points outside .debug_addr" ); - if (TD3) { - HChar* tmp = ML_(cur_read_strdup)(get_DiCursor_from_Cursor(&cur), "di.getFC.1"); - TRACE_D3("(indirect address, offset: 0x%lx): %s", addr_pos, tmp); - ML_(dinfo_free)(tmp); - } - cts->u.val = (ULong)(UWord)get_UWord(&cur); + cts->u.val = get_debug_addr_entry_form( index, cc, form ); cts->szB = sizeof(UWord); TRACE_D3("0x%lx", (UWord)cts->u.val); } |
|
From: Paul F. <pj...@wa...> - 2022-06-13 22:04:37
|
On 6/13/22 19:33, Philippe Waroquiers wrote:
> Re-reading how the test works, the idea is that this test simulates a control-c
> typed in gdb by a user.
> The simulation is done by having the script simulate_control_c sending SIGUSR1
> to vgdb. Vgdb then sends \003 to the valgrind gdbserver.
> This char '003' is then read by valgrind gdbserver, that then stops the guest.
>
> If the guest is blocked in a syscall, vgdb will use ptrace to get the guest
> (and so the valgrind host) out of the syscall.
>
> Maybe the ptrace calls are causing the FreeBSD kernel to consider the
> syscall was interrupted ?
>
> It might be worth starting vgdb with -d -d -d -d
> and see if the EINTR is related to some ptrace calls ?
>
Hi Philippe
That's what I was beginning to think.
In the syscall traces I see
81891 none-amd64-freebsd CALL select(0,0,0,0,0x204e60)
81891 none-amd64-freebsd RET select -1 errno 4 Interrupted system call
81891 none-amd64-freebsd CALL write(0x72c98,0x40268dab8,0x2b)
81891 none-amd64-freebsd GIO fd 470168 wrote 43 bytes
"DEBUG: vgPlain_invoke_gdbserver wait/yield
That's a select that should be blocked being interrupted then my
VG_(printf) debug trace from VG_(invoke_gdbserver) caled via ptrace.
I need to dig more into ptrace. I did start looking at the lldb source
but there's a lot of abstraction with a load of "Plan" classes
corresponding to user commands.
A+
Paul
|
|
From: Mark W. <ma...@so...> - 2022-06-13 20:37:13
|
https://sourceware.org/git/gitweb.cgi?p=valgrind.git;h=e95904b99c87606eae1372ee4661e9db03833f08 commit e95904b99c87606eae1372ee4661e9db03833f08 Author: Luboš Luňák <l....@ce...> Date: Tue Apr 26 08:35:16 2022 +0200 treat DW_TAG_skeleton_unit like DW_TAG_compile_unit It's basically the same, except for being split-dwarf. Handling it is required e.g. for reading line info. Diff: --- coregrind/m_debuginfo/readdwarf.c | 6 ++++-- coregrind/m_debuginfo/readdwarf3.c | 9 ++++++--- 2 files changed, 10 insertions(+), 5 deletions(-) diff --git a/coregrind/m_debuginfo/readdwarf.c b/coregrind/m_debuginfo/readdwarf.c index e50d5d46d7..79d6764eaf 100644 --- a/coregrind/m_debuginfo/readdwarf.c +++ b/coregrind/m_debuginfo/readdwarf.c @@ -1136,7 +1136,8 @@ void read_unitinfo_dwarf2( /*OUT*/UnitInfo* ui, tag = step_leb128U( &abbrev_img ); - if ( tag != 0x0011 /*TAG_compile_unit*/ ) + if ( tag != 0x0011 /*TAG_compile_unit*/ + && tag != 0x004a /*TAG_skeleton_unit*/ ) return; /* Not a compile unit (might be partial) or broken DWARF. */ /* DW_CHILDREN_yes or DW_CHILDREN_no */ @@ -1330,7 +1331,8 @@ void read_unitinfo_dwarf2( /*OUT*/UnitInfo* ui, } /* Now store the members we need in the UnitInfo structure */ - if ( tag == 0x0011 /*TAG_compile_unit*/ ) { + if ( tag == 0x0011 /*TAG_compile_unit*/ + || tag == 0x004a /*TAG_skeleton_unit*/ ) { if ( name == 0x03 ) ui->name = sval; /* DW_AT_name */ else if ( name == 0x1b ) ui->compdir = sval; /* DW_AT_compdir */ else if ( name == 0x10 ) ui->stmt_list = cval; /* DW_AT_stmt_list */ diff --git a/coregrind/m_debuginfo/readdwarf3.c b/coregrind/m_debuginfo/readdwarf3.c index e9aab0dd52..86af340ebc 100644 --- a/coregrind/m_debuginfo/readdwarf3.c +++ b/coregrind/m_debuginfo/readdwarf3.c @@ -2826,7 +2826,8 @@ static void parse_var_DIE ( if (dtag == DW_TAG_compile_unit || dtag == DW_TAG_type_unit - || dtag == DW_TAG_partial_unit) { + || dtag == DW_TAG_partial_unit + || dtag == DW_TAG_skeleton_unit) { Bool have_lo = False; Bool have_hi1 = False; Bool hiIsRelative = False; @@ -3467,7 +3468,8 @@ static Bool parse_inl_DIE ( /* Get info about DW_TAG_compile_unit and DW_TAG_partial_unit which in theory could also contain inlined fn calls, if they cover an address range. */ Bool unit_has_addrs = False; - if (dtag == DW_TAG_compile_unit || dtag == DW_TAG_partial_unit) { + if (dtag == DW_TAG_compile_unit || dtag == DW_TAG_partial_unit + || dtag == DW_TAG_skeleton_unit) { Bool have_lo = False; Addr ip_lo = 0; const HChar *compdir = NULL; @@ -3859,7 +3861,8 @@ static void parse_type_DIE ( /*MOD*/XArray* /* of TyEnt */ tyents, if (dtag == DW_TAG_compile_unit || dtag == DW_TAG_type_unit - || dtag == DW_TAG_partial_unit) { + || dtag == DW_TAG_partial_unit + || dtag == DW_TAG_skeleton_unit) { if (level == 0) setup_cu_bases(cc, c_die, abbv); /* See if we can find DW_AT_language, since it is important for |
|
From: Mark W. <ma...@so...> - 2022-06-13 20:04:33
|
https://sourceware.org/git/gitweb.cgi?p=valgrind.git;h=69767ee522324836e9147154ac0c350662747007 commit 69767ee522324836e9147154ac0c350662747007 Author: Mark Wielaard <ma...@kl...> Date: Mon Jun 13 21:29:01 2022 +0200 Add cachegrind and callgrind post.{diff,out} to .gitignore Diff: --- .gitignore | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.gitignore b/.gitignore index c7202fab3a..1bce8a6287 100644 --- a/.gitignore +++ b/.gitignore @@ -92,6 +92,8 @@ # /cachegrind/tests/ /cachegrind/tests/*.dSYM /cachegrind/tests/*.so +/cachegrind/tests/*.post.diff* +/cachegrind/tests/*.post.out /cachegrind/tests/*.stderr.diff* /cachegrind/tests/*.stderr.out /cachegrind/tests/*.stdout.diff* @@ -137,6 +139,8 @@ # /callgrind/tests/ /callgrind/tests/*.dSYM +/callgrind/tests/*.post.diff* +/callgrind/tests/*.post.out /callgrind/tests/*.stderr.diff* /callgrind/tests/*.stderr.out /callgrind/tests/*.stdout.diff* |
|
From: Philippe W. <phi...@sk...> - 2022-06-13 19:49:37
|
On Sun, 2022-06-12 at 11:20 +0200, Paul Floyd wrote: > Hi > > This question is mostly for Philippe, but if anyone else feels fit to > comment please jump in. > > This weekend I have (mostly) finished adding gdb invoker support for > FreeBSD. Previously, like Darwin, the "none" invoker was being used. > > All but one of the gdb invoker regtests are passing, but I'm not sure > how serious the one failure is - gdbserver_tests/nlcontrolc is the one > failing, with a stdoutB diff. > > What is happening is that the first twp phases (burn and sleep) are > working OK. > > But for the final phase (set sleepms to 0 and continue, with the > expectation that all 4 threads be in the 16 minute timeout select calls). > > On FreeBSD I'm seeing the main thread select return and set EINTR. > However I don't see any signals with --trace-signals=yes. Re-reading how the test works, the idea is that this test simulates a control-c typed in gdb by a user. The simulation is done by having the script simulate_control_c sending SIGUSR1 to vgdb. Vgdb then sends \003 to the valgrind gdbserver. This char '003' is then read by valgrind gdbserver, that then stops the guest. If the guest is blocked in a syscall, vgdb will use ptrace to get the guest (and so the valgrind host) out of the syscall. Maybe the ptrace calls are causing the FreeBSD kernel to consider the syscall was interrupted ? It might be worth starting vgdb with -d -d -d -d and see if the EINTR is related to some ptrace calls ? Philippe > > It looks to me that this is an OS thing, with FreeBSD not resuming the > main thread select after the ptrace + signal timeout change. > > This is my only ptrace experience. Any ideas as to what else could be > causing select to be interrupted? > > A+ > Paul > > > _______________________________________________ > Valgrind-developers mailing list > Val...@li... > https://lists.sourceforge.net/lists/listinfo/valgrind-developers |
|
From: Mark W. <ma...@so...> - 2022-06-13 17:07:51
|
https://sourceware.org/git/gitweb.cgi?p=valgrind.git;h=d19bbdf1200685ddbb6976cf915fba25f2097162 commit d19bbdf1200685ddbb6976cf915fba25f2097162 Author: Luboš Luňák <l....@ce...> Date: Tue Apr 19 12:20:16 2022 +0200 read dwarf5 DW_FORM_rnglistx and DW_FORM_loclistx The .debug_rnglists/.debug_loclists sections first have a list of offsets and then a list of the actual data that those offsets point to. Diff: --- coregrind/m_debuginfo/readdwarf.c | 6 +++ coregrind/m_debuginfo/readdwarf3.c | 82 +++++++++++++++++++++++++++++++++++--- 2 files changed, 82 insertions(+), 6 deletions(-) diff --git a/coregrind/m_debuginfo/readdwarf.c b/coregrind/m_debuginfo/readdwarf.c index 7d71ff14fa..e50d5d46d7 100644 --- a/coregrind/m_debuginfo/readdwarf.c +++ b/coregrind/m_debuginfo/readdwarf.c @@ -1280,6 +1280,12 @@ void read_unitinfo_dwarf2( /*OUT*/UnitInfo* ui, case 0x20: /* FORM_ref_sig8 */ p = ML_(cur_plus)(p, 8); break; + case 0x22: /* FORM_loclistx */ + (void)step_leb128U(&p); + break; + case 0x23: /* FORM_rnglistx */ + (void)step_leb128U(&p); + break; case 0x25: /* FORM_strx1 */ p = ML_(cur_plus)(p, 1); break; diff --git a/coregrind/m_debuginfo/readdwarf3.c b/coregrind/m_debuginfo/readdwarf3.c index 85fc976634..e9aab0dd52 100644 --- a/coregrind/m_debuginfo/readdwarf3.c +++ b/coregrind/m_debuginfo/readdwarf3.c @@ -491,6 +491,12 @@ typedef /* DW_AT_str_offsets_base */ Addr cu_str_offsets_base; Bool cu_has_str_offsets_base; + /* DW_AT_rnglists_base */ + Addr cu_rnglists_base; + Bool cu_has_rnglists_base; + /* DW_AT_loclists_base */ + Addr cu_loclists_base; + Bool cu_has_loclists_base; /* --- Needed so we can add stuff to the string table. --- */ struct _DebugInfo* di; /* --- State of the hash table of g_abbv (i.e. parsed abbreviations) @@ -1435,6 +1441,40 @@ void get_Form_contents ( /*OUT*/FormContents* cts, cts->szB = cc->is_dw64 ? 8 : 4; TRACE_D3("%llu", cts->u.val); break; + case DW_FORM_rnglistx: { + if(!cc->cu_has_rnglists_base) { + cc->barf("get_Form_contents: DW_FORM_rnglistsx" + " without DW_AT_rnglists_base"); + } + /* Convert index to offset pointing to the offsets list. */ + ULong index = get_ULEB128(c); + ULong offset_to_offset = cc->cu_rnglists_base + index * sizeof_Dwarfish_UWord( cc->is_dw64 ); + /* And read the offset value from there. */ + Cursor cur; + init_Cursor( &cur, cc->escn_debug_rnglists, offset_to_offset, cc->barf, + "get_Form_contents: index points outside .debug_rnglists" ); + cts->u.val = cc->cu_rnglists_base + get_Dwarfish_UWord(&cur, cc->is_dw64); + cts->szB = 8; + TRACE_D3("%llu", cts->u.val); + break; + } + case DW_FORM_loclistx: { + if(!cc->cu_has_loclists_base) { + cc->barf("get_Form_contents: DW_FORM_loclistsx" + " without DW_AT_loclists_base"); + } + /* Convert index to offset pointing to the offsets list. */ + ULong index = get_ULEB128(c); + ULong offset_to_offset = cc->cu_loclists_base + index * sizeof_Dwarfish_UWord( cc->is_dw64 ); + /* And read the offset value from there. */ + Cursor cur; + init_Cursor( &cur, cc->escn_debug_loclists, offset_to_offset, cc->barf, + "get_Form_contents: index points outside .debug_loclists" ); + cts->u.val = cc->cu_loclists_base + get_Dwarfish_UWord(&cur, cc->is_dw64); + cts->szB = 8; + TRACE_D3("%llu", cts->u.val); + break; + } case DW_FORM_sdata: cts->u.val = (ULong)(Long)get_SLEB128(c); cts->szB = 8; @@ -1807,6 +1847,9 @@ UInt get_Form_szB (const CUConst* cc, DW_FORM form ) return 8; else return 4; + case DW_FORM_rnglistx: + case DW_FORM_loclistx: + return VARSZ_FORM; case DW_FORM_sdata: return VARSZ_FORM; case DW_FORM_udata: @@ -2571,27 +2614,32 @@ static void setup_cu_svma(CUConst* cc, Bool have_lo, Addr ip_lo, Bool td3) } } -/* Setup info from DW_AT_addr_base and DW_AT_str_offsets_base. This needs to be - done early, because other DW_AT_* info may depend on it. */ +/* Setup info from DW_AT_addr_base, DW_AT_str_offsets_base, DW_AT_rnglists_base + and DW_AT_loclists_base. This needs to be done early, because other DW_AT_* + info may depend on it. */ static void setup_cu_bases(CUConst* cc, Cursor* c_die, const g_abbv* abbv) { FormContents cts; UInt nf_i; ULong saved_c_pos; - if(cc->cu_has_addr_base && cc->cu_has_str_offsets_base) + if(cc->cu_has_addr_base && cc->cu_has_str_offsets_base + && cc->cu_has_rnglists_base && cc->cu_has_loclists_base) return; saved_c_pos = get_position_of_Cursor(c_die); nf_i = 0; - while (!cc->cu_has_addr_base || !cc->cu_has_str_offsets_base) { + while (!cc->cu_has_addr_base || !cc->cu_has_str_offsets_base + || !cc->cu_has_rnglists_base || !cc->cu_has_loclists_base) { DW_AT attr = (DW_AT) abbv->nf[nf_i].at_name; DW_FORM form = (DW_FORM)abbv->nf[nf_i].at_form; const name_form *nf = &abbv->nf[nf_i]; if (attr == 0 && form == 0) break; - if (attr != DW_AT_addr_base && attr != DW_AT_str_offsets_base ) { + if (attr != DW_AT_addr_base && attr != DW_AT_str_offsets_base + && attr != DW_AT_rnglists_base && attr != DW_AT_loclists_base) { const UInt form_szB = get_Form_szB (cc, form); if (form_szB == VARSZ_FORM) { - if(form == DW_FORM_addrx || form == DW_FORM_strx) { + if(form == DW_FORM_addrx || form == DW_FORM_strx + || form == DW_FORM_rnglistx || form == DW_FORM_loclistx) { /* Skip without interpreting them, they depend on *_base. */ (void) get_ULEB128(c_die); } else { @@ -2625,6 +2673,24 @@ static void setup_cu_bases(CUConst* cc, Cursor* c_die, const g_abbv* abbv) cc->cu_str_offsets_base = str_offsets_base; } } + if (attr == DW_AT_rnglists_base && cts.szB > 0) { + Addr rnglists_base = cts.u.val; + if (cc->cu_has_rnglists_base) + vg_assert (rnglists_base == cc->cu_rnglists_base); + else { + cc->cu_has_rnglists_base = True; + cc->cu_rnglists_base = rnglists_base; + } + } + if (attr == DW_AT_loclists_base && cts.szB > 0) { + Addr loclists_base = cts.u.val; + if (cc->cu_has_loclists_base) + vg_assert (loclists_base == cc->cu_loclists_base); + else { + cc->cu_has_loclists_base = True; + cc->cu_loclists_base = loclists_base; + } + } nf_i++; } set_position_of_Cursor(c_die, saved_c_pos); @@ -5564,6 +5630,10 @@ void new_dwarf3_reader_wrk ( cc.cu_has_addr_base = False; cc.cu_str_offsets_base = 0; cc.cu_has_str_offsets_base = False; + cc.cu_rnglists_base = 0; + cc.cu_has_rnglists_base = False; + cc.cu_loclists_base = 0; + cc.cu_has_loclists_base = False; cc.di = di; /* The CU's svma can be deduced by looking at the AT_low_pc value in the top level TAG_compile_unit, which is the topmost |
|
From: Mark W. <ma...@so...> - 2022-06-13 16:19:50
|
https://sourceware.org/git/gitweb.cgi?p=valgrind.git;h=383f36462fdc25a0e849391cf845e22703a95c08 commit 383f36462fdc25a0e849391cf845e22703a95c08 Author: Luboš Luňák <l....@ce...> Date: Mon Apr 25 22:11:27 2022 +0200 avoid warning about missing DW_AT_*_base in skip_DIE() Similarly to setup_cu_bases(), DW_FORM_addrx etc. may depend on DW_AT_addr_base etc. that have not been read yet. Diff: --- coregrind/m_debuginfo/readdwarf3.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/coregrind/m_debuginfo/readdwarf3.c b/coregrind/m_debuginfo/readdwarf3.c index 219cb6bbab..85fc976634 100644 --- a/coregrind/m_debuginfo/readdwarf3.c +++ b/coregrind/m_debuginfo/readdwarf3.c @@ -1899,8 +1899,15 @@ void skip_DIE (UWord *sibling, *sibling = cts.u.val; nf_i++; } else if (abbv->nf[nf_i].skip_szB == VARSZ_FORM) { - get_Form_contents( &cts, cc, c_die, False /*td3*/, - &abbv->nf[nf_i] ); + DW_FORM form = abbv->nf[nf_i].at_form; + if(form == DW_FORM_addrx || form == DW_FORM_strx + || form == DW_FORM_rnglistx || form == DW_FORM_loclistx) { + /* Skip without interpreting them, they may depend on e.g. + DW_AT_addr_base that has not been read yet. */ + (void) get_ULEB128(c_die); + } else + get_Form_contents( &cts, cc, c_die, False /*td3*/, + &abbv->nf[nf_i] ); nf_i++; } else { advance_position_of_Cursor (c_die, (ULong)abbv->nf[nf_i].skip_szB); |
|
From: Mark W. <ma...@so...> - 2022-06-13 14:48:16
|
https://sourceware.org/git/gitweb.cgi?p=valgrind.git;h=61dfba4232d795c00603c74e6d0573f2d16641e2 commit 61dfba4232d795c00603c74e6d0573f2d16641e2 Author: Luboš Luňák <l....@ce...> Date: Tue Apr 19 11:14:52 2022 +0200 read dwarf5 DW_FORM_addrx* and DW_FORM_strx* as generated by Clang14 DW_FORM_addrx* are offsets into .debug_addr containing addresses. DW_FORM_strx* are offsets into .debug_str_offsets, which contain offsets into .debug_str. Support for these also requires reading DW_AT_addr_base and DW_AT_str_offsets_base before any other field in the abbrev table entry, as those may use this form. Diff: --- coregrind/m_debuginfo/priv_readdwarf3.h | 3 +- coregrind/m_debuginfo/readdwarf.c | 30 ++++ coregrind/m_debuginfo/readdwarf3.c | 261 ++++++++++++++++++++++++++++---- coregrind/m_debuginfo/readelf.c | 21 ++- coregrind/m_debuginfo/readmacho.c | 8 +- 5 files changed, 293 insertions(+), 30 deletions(-) diff --git a/coregrind/m_debuginfo/priv_readdwarf3.h b/coregrind/m_debuginfo/priv_readdwarf3.h index f6d1dd1ee1..25e3cd50dc 100644 --- a/coregrind/m_debuginfo/priv_readdwarf3.h +++ b/coregrind/m_debuginfo/priv_readdwarf3.h @@ -48,7 +48,8 @@ ML_(new_dwarf3_reader) ( DiSlice escn_debug_rnglists, DiSlice escn_debug_loclists, DiSlice escn_debug_loc, DiSlice escn_debug_info_alt, DiSlice escn_debug_abbv_alt, DiSlice escn_debug_line_alt, - DiSlice escn_debug_str_alt, DiSlice escn_debug_line_str + DiSlice escn_debug_str_alt, DiSlice escn_debug_line_str, + DiSlice escn_debug_addr, DiSlice escn_debug_str_offsets ); #endif /* ndef __PRIV_READDWARF3_H */ diff --git a/coregrind/m_debuginfo/readdwarf.c b/coregrind/m_debuginfo/readdwarf.c index 56cef9a5f4..7d71ff14fa 100644 --- a/coregrind/m_debuginfo/readdwarf.c +++ b/coregrind/m_debuginfo/readdwarf.c @@ -1271,9 +1271,39 @@ void read_unitinfo_dwarf2( /*OUT*/UnitInfo* ui, break; case 0x19: /* FORM_flag_present */ break; + case 0x1a: /* FORM_strx */ + (void)step_leb128U(&p); + break; + case 0x1b: /* FORM_addrx */ + (void)step_leb128U(&p); + break; case 0x20: /* FORM_ref_sig8 */ p = ML_(cur_plus)(p, 8); break; + case 0x25: /* FORM_strx1 */ + p = ML_(cur_plus)(p, 1); + break; + case 0x26: /* FORM_strx2 */ + p = ML_(cur_plus)(p, 2); + break; + case 0x27: /* FORM_strx3 */ + p = ML_(cur_plus)(p, 3); + break; + case 0x28: /* FORM_strx4 */ + p = ML_(cur_plus)(p, 4); + break; + case 0x29: /* FORM_addrx1 */ + p = ML_(cur_plus)(p, 1); + break; + case 0x2a: /* FORM_addrx2 */ + p = ML_(cur_plus)(p, 2); + break; + case 0x2b: /* FORM_addrx3 */ + p = ML_(cur_plus)(p, 3); + break; + case 0x2c: /* FORM_addrx4 */ + p = ML_(cur_plus)(p, 4); + break; case 0x1f20: /* FORM_GNU_ref_alt */ p = ML_(cur_plus)(p, ui->dw64 ? 8 : 4); break; diff --git a/coregrind/m_debuginfo/readdwarf3.c b/coregrind/m_debuginfo/readdwarf3.c index 1453ebbdbc..219cb6bbab 100644 --- a/coregrind/m_debuginfo/readdwarf3.c +++ b/coregrind/m_debuginfo/readdwarf3.c @@ -479,10 +479,18 @@ typedef DiSlice escn_debug_info_alt; DiSlice escn_debug_str_alt; DiSlice escn_debug_line_str; + DiSlice escn_debug_addr; + DiSlice escn_debug_str_offsets; /* How much to add to .debug_types resp. alternate .debug_info offsets in cook_die*. */ UWord types_cuOff_bias; UWord alt_cuOff_bias; + /* DW_AT_addr_base */ + Addr cu_addr_base; + Bool cu_has_addr_base; + /* DW_AT_str_offsets_base */ + Addr cu_str_offsets_base; + Bool cu_has_str_offsets_base; /* --- Needed so we can add stuff to the string table. --- */ struct _DebugInfo* di; /* --- State of the hash table of g_abbv (i.e. parsed abbreviations) @@ -1294,6 +1302,87 @@ typedef } FormContents; +// Read data for get_Form_contents() from .debug_addr for the 'index' entry. +static void get_Form_contents_addr( /*OUT*/FormContents* cts, DW_FORM form, + ULong index, const CUConst* cc, Bool td3 ) +{ + if(!cc->cu_has_addr_base) { + VG_(printf)( + "get_Form_contents_addr: %u (%s) without DW_AT_addr_base\n", + form, ML_(pp_DW_FORM)(form)); + cc->barf("get_Form_contents_addr: DW_AT_addr_base not set"); + } + /* We make the same word-size assumption as DW_FORM_addr. */ + UWord addr_pos = cc->cu_addr_base + index * sizeof(UWord); + Cursor cur; + init_Cursor( &cur, cc->escn_debug_addr, addr_pos, cc->barf, + "get_Form_contents_addr: index points outside .debug_addr" ); + if (TD3) { + HChar* tmp = ML_(cur_read_strdup)(get_DiCursor_from_Cursor(&cur), "di.getFC.1"); + TRACE_D3("(indirect address, offset: 0x%lx): %s", addr_pos, tmp); + ML_(dinfo_free)(tmp); + } + cts->u.val = (ULong)(UWord)get_UWord(&cur); + cts->szB = sizeof(UWord); + TRACE_D3("0x%lx", (UWord)cts->u.val); +} + +// Read data for get_Form_contents() from .debug_str for the given offset. +static void get_Form_contents_str( /*OUT*/FormContents* cts, DW_FORM form, + UWord offset, const CUConst* cc, Bool td3 ) +{ + if (!ML_(sli_is_valid)(cc->escn_debug_str) + || offset >= cc->escn_debug_str.szB) { + VG_(printf)( + "get_Form_contents_str: %u (%s) points outside .debug_str\n", + form, ML_(pp_DW_FORM)(form)); + cc->barf("get_Form_contents_str: index points outside .debug_str"); + } + /* FIXME: check the entire string lies inside debug_str, + not just the first byte of it. */ + DiCursor str + = ML_(cur_plus)( ML_(cur_from_sli)(cc->escn_debug_str), offset ); + if (TD3) { + HChar* tmp = ML_(cur_read_strdup)(str, "di.getFC.1"); + TRACE_D3("(indirect string, offset: 0x%lx): %s", offset, tmp); + ML_(dinfo_free)(tmp); + } + cts->u.cur = str; + cts->szB = - (Long)(1 + (ULong)ML_(cur_strlen)(str)); +} + +static inline UInt sizeof_Dwarfish_UWord (Bool is_dw64) +{ + if (is_dw64) + return sizeof(ULong); + else + return sizeof(UInt); +} + +// Read data for get_Form_contents() from .debug_str_offsets for the 'index' entry. +static void get_Form_contents_str_offsets( /*OUT*/FormContents* cts, DW_FORM form, + ULong index, const CUConst* cc, Bool td3 ) +{ + if(!cc->cu_has_str_offsets_base) { + VG_(printf)( + "get_Form_contents_str_offsets: %u (%s) without DW_AT_str_offsets_base\n", + form, ML_(pp_DW_FORM)(form)); + cc->barf("get_Form_contents_str_offsets: DW_AT_str_offsets_base not set"); + } + UWord str_offsets_pos = cc->cu_str_offsets_base + + index * sizeof_Dwarfish_UWord (cc->is_dw64); + Cursor cur; + init_Cursor( &cur, cc->escn_debug_str_offsets, str_offsets_pos, cc->barf, + "get_Form_contents_str_offsets: index " + "points outside .debug_str_offsets" ); + if (TD3) { + HChar* tmp = ML_(cur_read_strdup)(get_DiCursor_from_Cursor(&cur), "di.getFC.1"); + TRACE_D3("(indirect string offset, offset: 0x%lx): %s", str_offsets_pos, tmp); + ML_(dinfo_free)(tmp); + } + get_Form_contents_str( cts, form, get_Dwarfish_UWord(&cur, cc->is_dw64), cc, td3 ); +} + /* From 'c', get the Form data into 'cts'. Either it gets a 1/2/4/8 byte scalar value, or (a reference to) zero or more bytes starting at a DiCursor.*/ @@ -1409,21 +1498,7 @@ void get_Form_contents ( /*OUT*/FormContents* cts, case DW_FORM_strp: { /* this is an offset into .debug_str */ UWord uw = (UWord)get_Dwarfish_UWord( c, cc->is_dw64 ); - if (!ML_(sli_is_valid)(cc->escn_debug_str) - || uw >= cc->escn_debug_str.szB) - cc->barf("get_Form_contents: DW_FORM_strp " - "points outside .debug_str"); - /* FIXME: check the entire string lies inside debug_str, - not just the first byte of it. */ - DiCursor str - = ML_(cur_plus)( ML_(cur_from_sli)(cc->escn_debug_str), uw ); - if (TD3) { - HChar* tmp = ML_(cur_read_strdup)(str, "di.getFC.1"); - TRACE_D3("(indirect string, offset: 0x%lx): %s", uw, tmp); - ML_(dinfo_free)(tmp); - } - cts->u.cur = str; - cts->szB = - (Long)(1 + (ULong)ML_(cur_strlen)(str)); + get_Form_contents_str( cts, form, uw, cc, td3 ); break; } case DW_FORM_line_strp: { @@ -1654,6 +1729,55 @@ void get_Form_contents ( /*OUT*/FormContents* cts, break; } + case DW_FORM_addrx: { + /* this is an offset into .debug_addr */ + ULong index = (ULong)(Long)get_ULEB128(c); + get_Form_contents_addr(cts, form, index, cc, td3); + break; + } + case DW_FORM_addrx1: { + /* this is an offset into .debug_addr */ + ULong index = (ULong)get_UChar(c); + get_Form_contents_addr(cts, form, index, cc, td3); + break; + } + case DW_FORM_addrx2: { + /* this is an offset into .debug_addr */ + ULong index = (ULong)get_UShort(c); + get_Form_contents_addr(cts, form, index, cc, td3); + break; + } + case DW_FORM_addrx4: { + /* this is an offset into .debug_addr */ + ULong index = (ULong)get_UInt(c); + get_Form_contents_addr(cts, form, index, cc, td3); + break; + } + case DW_FORM_strx: { + /* this is an offset into .debug_str_offsets */ + ULong index = (ULong)(Long)get_ULEB128(c); + get_Form_contents_str_offsets(cts, form, index, cc, td3); + break; + } + case DW_FORM_strx1: { + /* this is an offset into .debug_str_offsets */ + ULong index = get_UChar(c); + get_Form_contents_str_offsets(cts, form, index, cc, td3); + break; + } + case DW_FORM_strx2: { + /* this is an offset into .debug_str_offsets */ + ULong index = (ULong)get_UShort(c); + get_Form_contents_str_offsets(cts, form, index, cc, td3); + break; + } + case DW_FORM_strx4: { + /* this is an offset into .debug_str_offsets */ + ULong index = (ULong)get_UInt(c); + get_Form_contents_str_offsets(cts, form, index, cc, td3); + break; + } + default: VG_(printf)( "get_Form_contents: unhandled %u (%s) at <%llx>\n", @@ -1662,14 +1786,6 @@ void get_Form_contents ( /*OUT*/FormContents* cts, } } -static inline UInt sizeof_Dwarfish_UWord (Bool is_dw64) -{ - if (is_dw64) - return sizeof(ULong); - else - return sizeof(UInt); -} - #define VARSZ_FORM 0xffffffff /* If the form is a fixed length form, return the nr of bytes for this form. If the form is a variable length form, return VARSZ_FORM. */ @@ -1740,6 +1856,22 @@ UInt get_Form_szB (const CUConst* cc, DW_FORM form ) return sizeof_Dwarfish_UWord(cc->is_dw64); case DW_FORM_implicit_const: return 0; /* Value inside abbrev. */ + case DW_FORM_addrx: + return VARSZ_FORM; + case DW_FORM_strx: + return VARSZ_FORM; + case DW_FORM_addrx1: + case DW_FORM_strx1: + return 1; + case DW_FORM_addrx2: + case DW_FORM_strx2: + return 2; + case DW_FORM_addrx3: + case DW_FORM_strx3: + return 3; + case DW_FORM_addrx4: + case DW_FORM_strx4: + return 4; default: VG_(printf)( "get_Form_szB: unhandled %u (%s)\n", @@ -2432,6 +2564,65 @@ static void setup_cu_svma(CUConst* cc, Bool have_lo, Addr ip_lo, Bool td3) } } +/* Setup info from DW_AT_addr_base and DW_AT_str_offsets_base. This needs to be + done early, because other DW_AT_* info may depend on it. */ +static void setup_cu_bases(CUConst* cc, Cursor* c_die, const g_abbv* abbv) +{ + FormContents cts; + UInt nf_i; + ULong saved_c_pos; + if(cc->cu_has_addr_base && cc->cu_has_str_offsets_base) + return; + saved_c_pos = get_position_of_Cursor(c_die); + nf_i = 0; + while (!cc->cu_has_addr_base || !cc->cu_has_str_offsets_base) { + DW_AT attr = (DW_AT) abbv->nf[nf_i].at_name; + DW_FORM form = (DW_FORM)abbv->nf[nf_i].at_form; + const name_form *nf = &abbv->nf[nf_i]; + if (attr == 0 && form == 0) + break; + if (attr != DW_AT_addr_base && attr != DW_AT_str_offsets_base ) { + const UInt form_szB = get_Form_szB (cc, form); + if (form_szB == VARSZ_FORM) { + if(form == DW_FORM_addrx || form == DW_FORM_strx) { + /* Skip without interpreting them, they depend on *_base. */ + (void) get_ULEB128(c_die); + } else { + /* Need to read the contents of this one to skip it. */ + get_Form_contents( &cts, cc, c_die, False /*td3*/, + &abbv->nf[nf_i] ); + } + } else { + /* Skip without even reading it, as it may depend on *_base. */ + advance_position_of_Cursor (c_die, form_szB); + } + nf_i++; + continue; + } + get_Form_contents( &cts, cc, c_die, False/*td3*/, nf ); + if (attr == DW_AT_addr_base && cts.szB > 0) { + Addr addr_base = cts.u.val; + if (cc->cu_has_addr_base) + vg_assert (addr_base == cc->cu_addr_base); + else { + cc->cu_has_addr_base = True; + cc->cu_addr_base = addr_base; + } + } + if (attr == DW_AT_str_offsets_base && cts.szB > 0) { + Addr str_offsets_base = cts.u.val; + if (cc->cu_has_str_offsets_base) + vg_assert (str_offsets_base == cc->cu_str_offsets_base); + else { + cc->cu_has_str_offsets_base = True; + cc->cu_str_offsets_base = str_offsets_base; + } + } + nf_i++; + } + set_position_of_Cursor(c_die, saved_c_pos); +} + static void trace_DIE( DW_TAG dtag, UWord posn, @@ -2571,6 +2762,9 @@ static void parse_var_DIE ( Addr ip_hi1 = 0; Addr rangeoff = 0; const HChar *compdir = NULL; + + if (level == 0) + setup_cu_bases(cc, c_die, abbv); nf_i = 0; while (True) { DW_AT attr = (DW_AT) abbv->nf[nf_i].at_name; @@ -3207,6 +3401,8 @@ static Bool parse_inl_DIE ( Bool has_stmt_list = False; ULong cu_line_offset = 0; + if (level == 0) + setup_cu_bases(cc, c_die, abbv); nf_i = 0; while (True) { DW_AT attr = (DW_AT) abbv->nf[nf_i].at_name; @@ -3566,7 +3762,7 @@ static void parse_type_DIE ( /*MOD*/XArray* /* of TyEnt */ tyents, Int level, Cursor* c_die, const g_abbv *abbv, - const CUConst* cc, + CUConst* cc, Bool td3 ) { FormContents cts; @@ -3591,6 +3787,8 @@ static void parse_type_DIE ( /*MOD*/XArray* /* of TyEnt */ tyents, if (dtag == DW_TAG_compile_unit || dtag == DW_TAG_type_unit || dtag == DW_TAG_partial_unit) { + if (level == 0) + setup_cu_bases(cc, c_die, abbv); /* See if we can find DW_AT_language, since it is important for establishing array bounds (see DW_TAG_subrange_type below in this fn) */ @@ -5081,7 +5279,8 @@ void new_dwarf3_reader_wrk ( DiSlice escn_debug_rnglists, DiSlice escn_debug_loclists, DiSlice escn_debug_loc, DiSlice escn_debug_info_alt, DiSlice escn_debug_abbv_alt, DiSlice escn_debug_line_alt, - DiSlice escn_debug_str_alt, DiSlice escn_debug_line_str + DiSlice escn_debug_str_alt, DiSlice escn_debug_line_str, + DiSlice escn_debug_addr, DiSlice escn_debug_str_offsets ) { XArray* /* of TyEnt */ tyents = NULL; @@ -5349,9 +5548,15 @@ void new_dwarf3_reader_wrk ( cc.escn_debug_info_alt = escn_debug_info_alt; cc.escn_debug_str_alt = escn_debug_str_alt; cc.escn_debug_line_str = escn_debug_line_str; + cc.escn_debug_addr = escn_debug_addr; + cc.escn_debug_str_offsets = escn_debug_str_offsets; cc.types_cuOff_bias = escn_debug_info.szB; cc.alt_cuOff_bias = escn_debug_info.szB + escn_debug_types.szB; cc.cu_start_offset = cu_start_offset; + cc.cu_addr_base = 0; + cc.cu_has_addr_base = False; + cc.cu_str_offsets_base = 0; + cc.cu_has_str_offsets_base = False; cc.di = di; /* The CU's svma can be deduced by looking at the AT_low_pc value in the top level TAG_compile_unit, which is the topmost @@ -5795,7 +6000,8 @@ ML_(new_dwarf3_reader) ( DiSlice escn_debug_rnglists, DiSlice escn_debug_loclists, DiSlice escn_debug_loc, DiSlice escn_debug_info_alt, DiSlice escn_debug_abbv_alt, DiSlice escn_debug_line_alt, - DiSlice escn_debug_str_alt, DiSlice escn_debug_line_str + DiSlice escn_debug_str_alt, DiSlice escn_debug_line_str, + DiSlice escn_debug_addr, DiSlice escn_debug_str_offsets ) { volatile Int jumped; @@ -5819,7 +6025,8 @@ ML_(new_dwarf3_reader) ( escn_debug_rnglists, escn_debug_loclists, escn_debug_loc, escn_debug_info_alt, escn_debug_abbv_alt, escn_debug_line_alt, - escn_debug_str_alt, escn_debug_line_str ); + escn_debug_str_alt, escn_debug_line_str, + escn_debug_addr, escn_debug_str_offsets ); d3rd_jmpbuf_valid = False; TRACE_D3("\n------ .debug_info reading was successful ------\n"); } else { diff --git a/coregrind/m_debuginfo/readelf.c b/coregrind/m_debuginfo/readelf.c index b4edb4fe85..25d237b7de 100644 --- a/coregrind/m_debuginfo/readelf.c +++ b/coregrind/m_debuginfo/readelf.c @@ -2831,6 +2831,8 @@ Bool ML_(read_elf_debug_info) ( struct _DebugInfo* di ) DiSlice debug_ranges_escn = DiSlice_INVALID; // .debug_ranges (dwarf2) DiSlice debug_rnglists_escn = DiSlice_INVALID; // .debug_rnglists(dwarf5) DiSlice debug_loclists_escn = DiSlice_INVALID; // .debug_loclists(dwarf5) + DiSlice debug_addr_escn = DiSlice_INVALID; // .debug_addr (dwarf5) + DiSlice debug_str_offsets_escn = DiSlice_INVALID; // .debug_str_offsets (dwarf5) DiSlice debug_loc_escn = DiSlice_INVALID; // .debug_loc (dwarf2) DiSlice debug_frame_escn = DiSlice_INVALID; // .debug_frame (dwarf2) DiSlice debug_line_alt_escn = DiSlice_INVALID; // .debug_line (alt) @@ -2960,6 +2962,14 @@ Bool ML_(read_elf_debug_info) ( struct _DebugInfo* di ) if (!ML_(sli_is_valid)(debug_frame_escn)) FIND(".zdebug_frame", debug_frame_escn) + FIND( ".debug_addr", debug_addr_escn) + if (!ML_(sli_is_valid)(debug_addr_escn)) + FIND(".zdebug_addr", debug_addr_escn) + + FIND( ".debug_str_offsets", debug_str_offsets_escn) + if (!ML_(sli_is_valid)(debug_str_offsets_escn)) + FIND(".zdebug_str_offsets", debug_str_offsets_escn) + FIND( ".debug", dwarf1d_escn) FIND( ".line", dwarf1l_escn) @@ -3291,6 +3301,14 @@ Bool ML_(read_elf_debug_info) ( struct _DebugInfo* di ) if (!ML_(sli_is_valid)(debug_frame_escn)) FIND(need_dwarf2, ".zdebug_frame", debug_frame_escn) + FIND( need_dwarf2, ".debug_addr", debug_addr_escn) + if (!ML_(sli_is_valid)(debug_addr_escn)) + FIND(need_dwarf2, ".zdebug_addr", debug_addr_escn) + + FIND( need_dwarf2, ".debug_str_offsets", debug_str_offsets_escn) + if (!ML_(sli_is_valid)(debug_str_offsets_escn)) + FIND(need_dwarf2, ".zdebug_str_offsets", debug_str_offsets_escn) + if (!ML_(sli_is_valid)(debugaltlink_escn)) FIND( need_dwarf2, ".gnu_debugaltlink", debugaltlink_escn) @@ -3532,7 +3550,8 @@ Bool ML_(read_elf_debug_info) ( struct _DebugInfo* di ) debug_rnglists_escn, debug_loclists_escn, debug_loc_escn, debug_info_alt_escn, debug_abbv_alt_escn, debug_line_alt_escn, - debug_str_alt_escn, debug_line_str_escn + debug_str_alt_escn, debug_line_str_escn, + debug_addr_escn, debug_str_offsets_escn ); } } diff --git a/coregrind/m_debuginfo/readmacho.c b/coregrind/m_debuginfo/readmacho.c index d93e24ecf8..61a3fe9f5a 100644 --- a/coregrind/m_debuginfo/readmacho.c +++ b/coregrind/m_debuginfo/readmacho.c @@ -1113,6 +1113,10 @@ Bool ML_(read_macho_debug_info)( struct _DebugInfo* di ) = getsectdata(dsli, "__DWARF", "__debug_loclists", NULL); DiSlice debug_loc_mscn = getsectdata(dsli, "__DWARF", "__debug_loc", NULL); + DiSlice debug_addr_mscn + = getsectdata(dsli, "__DWARF", "__debug_addr", NULL); + DiSlice debug_str_offsets_mscn + = getsectdata(dsli, "__DWARF", "__debug_str_offsets", NULL); /* It appears (jrs, 2014-oct-19) that section "__eh_frame" in segment "__TEXT" appears in both the main and dsym files, but @@ -1174,7 +1178,9 @@ Bool ML_(read_macho_debug_info)( struct _DebugInfo* di ) DiSlice_INVALID, /* ALT .debug_abbv */ DiSlice_INVALID, /* ALT .debug_line */ DiSlice_INVALID, /* ALT .debug_str */ - debug_line_str_mscn /* .debug_line_str */ + debug_line_str_mscn, /* .debug_line_str */ + debug_addr_mscn, + debug_str_offsets_mscn ); } } |
|
From: Paul F. <pa...@so...> - 2022-06-12 13:49:30
|
https://sourceware.org/git/gitweb.cgi?p=valgrind.git;h=145fb72dbf627e69d9738b42390f3eb632afd901 commit 145fb72dbf627e69d9738b42390f3eb632afd901 Author: Paul Floyd <pj...@wa...> Date: Sun Jun 12 15:48:32 2022 +0200 Fix some compiler warnings on FreeBSD Includes one serious issue of a switch case fallthrough Diff: --- coregrind/m_syswrap/syswrap-freebsd.c | 1 + coregrind/m_syswrap/syswrap-x86-freebsd.c | 4 ++-- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/coregrind/m_syswrap/syswrap-freebsd.c b/coregrind/m_syswrap/syswrap-freebsd.c index 20718badd6..0481b1c512 100644 --- a/coregrind/m_syswrap/syswrap-freebsd.c +++ b/coregrind/m_syswrap/syswrap-freebsd.c @@ -1335,6 +1335,7 @@ PRE(sys_fcntl) 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); diff --git a/coregrind/m_syswrap/syswrap-x86-freebsd.c b/coregrind/m_syswrap/syswrap-x86-freebsd.c index fe46e1eabd..4a2c35d58c 100644 --- a/coregrind/m_syswrap/syswrap-x86-freebsd.c +++ b/coregrind/m_syswrap/syswrap-x86-freebsd.c @@ -704,7 +704,7 @@ PRE(sys_freebsd6_ftruncate) PRE(sys_clock_getcpuclockid2) { PRINT("sys_clock_getcpuclockid2( %lld, %" FMT_REGWORD "d, %#" FMT_REGWORD "x )", - MERGE64(ARG1,ARG2),SARG3,ARG4); + (vki_id_t)MERGE64(ARG1,ARG2),SARG3,ARG4); PRE_REG_READ4(int, "clock_getcpuclockid2", vki_uint32_t, MERGE64_FIRST(offset), vki_uint32_t, MERGE64_SECOND(offset), @@ -1290,7 +1290,7 @@ POST(sys_cpuset_getid) PRE(sys_cpuset_getaffinity) { PRINT("sys_cpuset_getaffinity ( %" FMT_REGWORD "u, %" FMT_REGWORD "u, %lld, %" FMT_REGWORD "u, %#" FMT_REGWORD "x )", - ARG1, ARG2, MERGE64(ARG3, ARG4), ARG5, ARG6); + ARG1, ARG2, (vki_id_t)MERGE64(ARG3, ARG4), ARG5, ARG6); PRE_REG_READ6(int, "cpuset_getaffinity", vki_cpulevel_t, level, vki_cpuwhich_t, which, vki_uint32_t, MERGE64_FIRST(id), |
|
From: Paul F. <pj...@wa...> - 2022-06-12 09:20:36
|
Hi This question is mostly for Philippe, but if anyone else feels fit to comment please jump in. This weekend I have (mostly) finished adding gdb invoker support for FreeBSD. Previously, like Darwin, the "none" invoker was being used. All but one of the gdb invoker regtests are passing, but I'm not sure how serious the one failure is - gdbserver_tests/nlcontrolc is the one failing, with a stdoutB diff. What is happening is that the first twp phases (burn and sleep) are working OK. But for the final phase (set sleepms to 0 and continue, with the expectation that all 4 threads be in the 16 minute timeout select calls). On FreeBSD I'm seeing the main thread select return and set EINTR. However I don't see any signals with --trace-signals=yes. It looks to me that this is an OS thing, with FreeBSD not resuming the main thread select after the ptrace + signal timeout change. This is my only ptrace experience. Any ideas as to what else could be causing select to be interrupted? A+ Paul |
|
From: John R. <jr...@bi...> - 2022-06-11 23:06:12
|
On 6/9/22 14:10, Mark Wielaard wrote: > https://sourceware.org/git/gitweb.cgi?p=valgrind.git;h=3aee8a29447ea14108eb5d4ab3c1f7677767296a > > commit 3aee8a29447ea14108eb5d4ab3c1f7677767296a > Author: Mark Wielaard <snipped> > Date: Thu Jun 9 23:06:36 2022 +0200 > > syswrap-linux.c (sys_execveat): Define path as const HChar * This change, announced in mailing lists [valgrind-developers] and [valgrind] on 2022-06-09, is superficial and ignores the hint of a larger, more serious problem. Valgrind's source code is sloppy with regard to "'const' correctness." The C language keyword 'const' is omitted willy-nilly, which increases the chances that bugs will be overlooked despite being detectable at compile time by a modern compiler. In two days of hacking I found 120 regions in 32 files where 'const' was omitted: git diff master --stat | wc -l; git diff master | grep -c '@@' and that was just by hunting near instances of "HChar *" which often should be "HChar const *". See the patch in https://bugs.kde.org/show_bug.cgi?id=455168 . The problems are exacerbated (or perhaps caused) by oversights (or errors) in the Standard for C language stdlib. For instance: int execve(const char *pathname, char *const argv[], char *const envp[]); should be int execve(const char *pathname, char const *const argv[], char const *const envp[]); Note the added 'const' in the declaration of the second and third parameters. When 'execve' fails, then control returns to the program (which often is a shell!) and the program is going to assume that the operating system has not scribbled on the characters in the argument or environment strings. But only the revised declaration states that property explicitly. A similar bug in the Standard is: long strtol(const char *nptr, char **endptr, int base); which should be long strtol(const char *nptr, char const **endptr, int base); If endptr is not NULL, then upon return from strtol *endptr designates a substring of nptr. The characters of nptr are const (both the application programmer and strtol are not allowed to write them), so therefore the characters of *endptr also must be 'const'. Confimation of this problem can be seen in the source code to strtol: ===== glibc-2.29-32-g6d8eaf4a25/stdlib/strtol_l.c INT INTERNAL (__strtol_l) (const STRING_TYPE *nptr, STRING_TYPE **endptr, int base, int group, locale_t loc) ----- /* Store in ENDPTR the address of one character past the last character we converted. */ if (endptr != NULL) *endptr = (STRING_TYPE *) s; ----- const STRING_TYPE *save, *end; ----- *endptr = (STRING_TYPE *) &save[-1]; ----- /* There was no number to convert. */ *endptr = (STRING_TYPE *) nptr; ===== where "gcc -Wcast-qual" will complain about 'const' being elided. |
|
From: Feiyang C. <chr...@gm...> - 2022-06-10 08:38:53
|
Hi, team, After fixing some decoding and stack backtracking bugs, Valgrind for loongarch64-linux successfully passed most of the tests. https://github.com/loongson/valgrind-loongarch64 I will try to get Valgrind to pass more tests. But now I have some doubts. Could you help me, please? There are more dubious and reachable blocks in some memcheck tests. I don't know what's wrong with it. $ valgrind --leak-check=full --leak-resolution=high memcheck/tests/leak-cases ==166906== Memcheck, a memory error detector ==166906== Copyright (C) 2002-2022, and GNU GPL'd, by Julian Seward et al. ==166906== Using Valgrind-3.20.0.GIT and LibVEX; rerun with -h for copyright info ==166906== Command: memcheck/tests/leak-cases ==166906== ==166906== All heap blocks were freed -- no leaks are possible ==166906== ==166906== LEAK SUMMARY: ==166906== definitely lost: 32 bytes in 2 blocks ==166906== indirectly lost: 16 bytes in 1 blocks ==166906== possibly lost: 112 bytes in 7 blocks ==166906== still reachable: 80 bytes in 5 blocks ==166906== suppressed: 0 bytes in 0 blocks ==166906== Rerun with --leak-check=full to see details of leaked memory ==166906== leaked: 48 bytes in 3 blocks dubious: 112 bytes in 7 blocks reachable: 80 bytes in 5 blocks suppressed: 0 bytes in 0 blocks ==166906== ==166906== HEAP SUMMARY: ==166906== in use at exit: 240 bytes in 15 blocks ==166906== total heap usage: 15 allocs, 0 frees, 240 bytes allocated ==166906== ==166906== 16 bytes in 1 blocks are possibly lost in loss record 7 of 17 ==166906== at 0x484704C: malloc (vg_replace_malloc.c:393) ==166906== by 0x120A27: mk (leak-cases.c:52) ==166906== by 0x120AC3: f (leak-cases.c:78) ==166906== by 0x120DE7: main (leak-cases.c:107) ==166906== ==166906== 16 bytes in 1 blocks are possibly lost in loss record 8 of 17 ==166906== at 0x484704C: malloc (vg_replace_malloc.c:393) ==166906== by 0x120A27: mk (leak-cases.c:52) ==166906== by 0x120AF7: f (leak-cases.c:81) ==166906== by 0x120DE7: main (leak-cases.c:107) ==166906== ==166906== 16 bytes in 1 blocks are possibly lost in loss record 9 of 17 ==166906== at 0x484704C: malloc (vg_replace_malloc.c:393) ==166906== by 0x120A27: mk (leak-cases.c:52) ==166906== by 0x120B33: f (leak-cases.c:84) ==166906== by 0x120DE7: main (leak-cases.c:107) ==166906== ==166906== 16 bytes in 1 blocks are possibly lost in loss record 10 of 17 ==166906== at 0x484704C: malloc (vg_replace_malloc.c:393) ==166906== by 0x120A27: mk (leak-cases.c:52) ==166906== by 0x120B3F: f (leak-cases.c:84) ==166906== by 0x120DE7: main (leak-cases.c:107) ==166906== ==166906== 16 bytes in 1 blocks are possibly lost in loss record 11 of 17 ==166906== at 0x484704C: malloc (vg_replace_malloc.c:393) ==166906== by 0x120A27: mk (leak-cases.c:52) ==166906== by 0x120B73: f (leak-cases.c:87) ==166906== by 0x120DE7: main (leak-cases.c:107) ==166906== ==166906== 16 bytes in 1 blocks are possibly lost in loss record 12 of 17 ==166906== at 0x484704C: malloc (vg_replace_malloc.c:393) ==166906== by 0x120A27: mk (leak-cases.c:52) ==166906== by 0x120B7F: f (leak-cases.c:87) ==166906== by 0x120DE7: main (leak-cases.c:107) ==166906== ==166906== 16 bytes in 1 blocks are definitely lost in loss record 15 of 17 ==166906== at 0x484704C: malloc (vg_replace_malloc.c:393) ==166906== by 0x120A27: mk (leak-cases.c:52) ==166906== by 0x120AA7: f (leak-cases.c:74) ==166906== by 0x120DE7: main (leak-cases.c:107) ==166906== ==166906== 32 (16 direct, 16 indirect) bytes in 1 blocks are definitely lost in loss record 16 of 17 ==166906== at 0x484704C: malloc (vg_replace_malloc.c:393) ==166906== by 0x120A27: mk (leak-cases.c:52) ==166906== by 0x120ABB: f (leak-cases.c:76) ==166906== by 0x120DE7: main (leak-cases.c:107) ==166906== ==166906== 32 (16 direct, 16 indirect) bytes in 1 blocks are definitely lost in loss record 17 of 17 ==166906== at 0x484704C: malloc (vg_replace_malloc.c:393) ==166906== by 0x120A27: mk (leak-cases.c:52) ==166906== by 0x120BD7: f (leak-cases.c:91) ==166906== by 0x120DE7: main (leak-cases.c:107) ==166906== ==166906== LEAK SUMMARY: ==166906== definitely lost: 48 bytes in 3 blocks ==166906== indirectly lost: 32 bytes in 2 blocks ==166906== possibly lost: 96 bytes in 6 blocks ==166906== still reachable: 64 bytes in 4 blocks ==166906== suppressed: 0 bytes in 0 blocks ==166906== Reachable blocks (those to which a pointer was found) are not shown. ==166906== To see them, rerun with: --leak-check=full --show-leak-kinds=all ==166906== ==166906== For lists of detected and suppressed errors, rerun with: -s ==166906== ERROR SUMMARY: 9 errors from 9 contexts (suppressed: 0 from 0) I add four functions in glibc-2.X-helgrind.supp.in: '_dl_lookup_symbol_x', '_dl_map_object_deps', '_dl_sort_maps_dfs' and '_dl_fini'. I don't know why they cause errors. $ valgrind --tool=helgrind helgrind/tests/bar_bad ==166897== Helgrind, a thread error detector ==166897== Copyright (C) 2007-2017, and GNU GPL'd, by OpenWorks LLP et al. ==166897== Using Valgrind-3.20.0.GIT and LibVEX; rerun with -h for copyright info ==166897== Command: helgrind/tests/bar_bad ==166897== initialise a barrier with zero count ==166897== ---Thread-Announcement------------------------------------------ ==166897== ==166897== Thread #1 is the program's root thread ==166897== ==166897== ---------------------------------------------------------------- ==166897== ==166897== Thread #1: pthread_barrier_init: 'count' argument is zero ==166897== at 0x4855184: pthread_barrier_init (hg_intercepts.c:1869) ==166897== by 0x120CEB: main (bar_bad.c:44) ==166897== ==166897== ---------------------------------------------------------------- ==166897== ==166897== Thread #1's call to pthread_barrier_init failed ==166897== with error code 22 (EINVAL: Invalid argument) ==166897== at 0x4855244: pthread_barrier_init (hg_intercepts.c:1877) ==166897== by 0x120CEB: main (bar_bad.c:44) ==166897== initialise a barrier twice ==166897== ---------------------------------------------------------------- ==166897== ==166897== Thread #1: pthread_barrier_init: barrier is already initialised ==166897== at 0x4855184: pthread_barrier_init (hg_intercepts.c:1869) ==166897== by 0x120D3F: main (bar_bad.c:50) ==166897== initialise a barrier which has threads waiting on it ==166897== ---Thread-Announcement------------------------------------------ ==166897== ==166897== Thread #2 was created ==166897== at 0x4978F68: clone (clone.S:56) ==166897== by 0x490F27B: create_thread (pthread_create.c:295) ==166897== by 0x490FC47: pthread_create@@GLIBC_2.36 (pthread_create.c:828) ==166897== by 0x4853883: pthread_create_WRK (hg_intercepts.c:445) ==166897== by 0x4854B2F: pthread_create@* (hg_intercepts.c:478) ==166897== by 0x120D9F: main (bar_bad.c:59) ==166897== ==166897== ---------------------------------------------------------------- ==166897== ==166897== Possible data race during read of size 8 at 0x4030B10 by thread #2 ==166897== Locks held: none ==166897== at 0x400B1A4: _dl_lookup_symbol_x (dl-lookup.c:824) ==166897== by 0x4010953: _dl_fixup (dl-runtime.c:95) ==166897== by 0x4012B27: _dl_runtime_resolve (dl-trampoline.S:62) ==166897== by 0xFFFFFFFFFFFFFFFF: ??? ==166897== ==166897== This conflicts with a previous write of size 8 by thread #1 ==166897== Locks held: none ==166897== at 0x400B1C0: _dl_lookup_symbol_x (dl-lookup.c:824) ==166897== by 0x4010953: _dl_fixup (dl-runtime.c:95) ==166897== by 0x4012B27: _dl_runtime_resolve (dl-trampoline.S:62) ==166897== by 0xFFFFFFFFFFFFFFFF: ??? ==166897== Address 0x4030b10 is 2712 bytes inside data symbol "_rtld_local" ==166897== ==166897== ---------------------------------------------------------------- ==166897== ==166897== Possible data race during write of size 8 at 0x4030B10 by thread #2 ==166897== Locks held: none ==166897== at 0x400B1C0: _dl_lookup_symbol_x (dl-lookup.c:824) ==166897== by 0x4010953: _dl_fixup (dl-runtime.c:95) ==166897== by 0x4012B27: _dl_runtime_resolve (dl-trampoline.S:62) ==166897== by 0xFFFFFFFFFFFFFFFF: ??? ==166897== ==166897== This conflicts with a previous write of size 8 by thread #1 ==166897== Locks held: none ==166897== at 0x400B1C0: _dl_lookup_symbol_x (dl-lookup.c:824) ==166897== by 0x4010953: _dl_fixup (dl-runtime.c:95) ==166897== by 0x4012B27: _dl_runtime_resolve (dl-trampoline.S:62) ==166897== by 0xFFFFFFFFFFFFFFFF: ??? ==166897== Address 0x4030b10 is 2712 bytes inside data symbol "_rtld_local" ==166897== ==166897== ---------------------------------------------------------------- ==166897== ==166897== Thread #1: pthread_barrier_init: barrier is already initialised ==166897== at 0x4855184: pthread_barrier_init (hg_intercepts.c:1869) ==166897== by 0x120DD3: main (bar_bad.c:65) ==166897== ==166897== ---------------------------------------------------------------- ==166897== ==166897== Thread #1: pthread_barrier_init: threads are waiting at barrier ==166897== at 0x4855184: pthread_barrier_init (hg_intercepts.c:1869) ==166897== by 0x120DD3: main (bar_bad.c:65) ==166897== destroy a barrier that has waiting threads ==166897== ---------------------------------------------------------------- ==166897== ==166897== Thread #1: pthread_barrier_destroy: threads are waiting at barrier ==166897== at 0x4855444: pthread_barrier_destroy (hg_intercepts.c:1944) ==166897== by 0x120E5F: main (bar_bad.c:83) ==166897== ==166897== ---Thread-Announcement------------------------------------------ ==166897== ==166897== Thread #4 was created ==166897== at 0x4978F68: clone (clone.S:56) ==166897== by 0x490F27B: create_thread (pthread_create.c:295) ==166897== by 0x490FC47: pthread_create@@GLIBC_2.36 (pthread_create.c:828) ==166897== by 0x4853883: pthread_create_WRK (hg_intercepts.c:445) ==166897== by 0x4854B2F: pthread_create@* (hg_intercepts.c:478) ==166897== by 0x120E33: main (bar_bad.c:77) ==166897== ==166897== ---------------------------------------------------------------- ==166897== ==166897== Thread #4: pthread_barrier_wait: barrier is uninitialised ==166897== at 0x48552E8: pthread_barrier_wait (hg_intercepts.c:1910) ==166897== by 0x120C5B: sleep1 (bar_bad.c:23) ==166897== by 0x4853A5F: mythread_wrapper (hg_intercepts.c:406) ==166897== by 0x490F4CB: start_thread (pthread_create.c:442) ==166897== by 0x4978F8B: __thread_start (clone.S:87) ==166897== ==166897== ---------------------------------------------------------------- ==166897== ==166897== Lock at 0x4030A80 was first observed ==166897== at 0x4850BEC: mutex_lock_WRK (hg_intercepts.c:942) ==166897== by 0x4854F63: pthread_mutex_lock (hg_intercepts.c:958) ==166897== by 0x400CD17: _dl_open (dl-open.c:830) ==166897== by 0x49B311F: do_dlopen (dl-libc.c:95) ==166897== by 0x49B2D2B: _dl_catch_exception (dl-error-skeleton.c:208) ==166897== by 0x49B2DEF: _dl_catch_error (dl-error-skeleton.c:227) ==166897== by 0x49B3073: dlerror_run (dl-libc.c:45) ==166897== by 0x49B326F: __libc_dlopen_mode (dl-libc.c:162) ==166897== by 0x4978BD3: __libc_unwind_link_get (unwind-link.c:50) ==166897== by 0x490D783: pthread_cancel@@GLIBC_2.36 (pthread_cancel.c:99) ==166897== by 0x120E6B: main (bar_bad.c:85) ==166897== Address 0x4030a80 is 2568 bytes inside data symbol "_rtld_local" ==166897== ==166897== Lock at 0x4030AD0 was first observed ==166897== at 0x4850BEC: mutex_lock_WRK (hg_intercepts.c:942) ==166897== by 0x4854F63: pthread_mutex_lock (hg_intercepts.c:958) ==166897== by 0x40120C3: _dl_allocate_tls_init (dl-tls.c:539) ==166897== by 0x4910127: allocate_stack (allocatestack.c:428) ==166897== by 0x4910127: pthread_create@@GLIBC_2.36 (pthread_create.c:647) ==166897== by 0x4853883: pthread_create_WRK (hg_intercepts.c:445) ==166897== by 0x4854B2F: pthread_create@* (hg_intercepts.c:478) ==166897== by 0x120D9F: main (bar_bad.c:59) ==166897== Address 0x4030ad0 is 2648 bytes inside data symbol "_rtld_local" ==166897== ==166897== Possible data race during write of size 2 at 0x4032774 by thread #1 ==166897== Locks held: 2, at addresses 0x4030A80 0x4030AD0 ==166897== at 0x40040F8: _dl_map_object_deps (dl-deps.c:259) ==166897== by 0x400D23F: dl_open_worker_begin (dl-open.c:592) ==166897== by 0x49B2D2B: _dl_catch_exception (dl-error-skeleton.c:208) ==166897== by 0x400C917: dl_open_worker (dl-open.c:782) ==166897== by 0x49B2D2B: _dl_catch_exception (dl-error-skeleton.c:208) ==166897== by 0x400CD5B: _dl_open (dl-open.c:883) ==166897== by 0x49B311F: do_dlopen (dl-libc.c:95) ==166897== by 0x49B2D2B: _dl_catch_exception (dl-error-skeleton.c:208) ==166897== by 0x49B2DEF: _dl_catch_error (dl-error-skeleton.c:227) ==166897== by 0x49B3073: dlerror_run (dl-libc.c:45) ==166897== by 0x49B326F: __libc_dlopen_mode (dl-libc.c:162) ==166897== by 0x4978BD3: __libc_unwind_link_get (unwind-link.c:50) ==166897== ==166897== This conflicts with a previous read of size 2 by thread #4 ==166897== Locks held: none ==166897== at 0x400B274: _dl_lookup_symbol_x (dl-lookup.c:907) ==166897== by 0x4010953: _dl_fixup (dl-runtime.c:95) ==166897== by 0x4012B27: _dl_runtime_resolve (dl-trampoline.S:62) ==166897== by 0xFFFFFFFFFFFFFFFF: ??? ==166897== Address 0x4032774 is in a rw- mapped file /usr/lib64/ld-linux-loongarch-lp64d.so.1 segment ==166897== ==166897== ---------------------------------------------------------------- ==166897== ==166897== Lock at 0x4030A80 was first observed ==166897== at 0x4850BEC: mutex_lock_WRK (hg_intercepts.c:942) ==166897== by 0x4854F63: pthread_mutex_lock (hg_intercepts.c:958) ==166897== by 0x400CD17: _dl_open (dl-open.c:830) ==166897== by 0x49B311F: do_dlopen (dl-libc.c:95) ==166897== by 0x49B2D2B: _dl_catch_exception (dl-error-skeleton.c:208) ==166897== by 0x49B2DEF: _dl_catch_error (dl-error-skeleton.c:227) ==166897== by 0x49B3073: dlerror_run (dl-libc.c:45) ==166897== by 0x49B326F: __libc_dlopen_mode (dl-libc.c:162) ==166897== by 0x4978BD3: __libc_unwind_link_get (unwind-link.c:50) ==166897== by 0x490D783: pthread_cancel@@GLIBC_2.36 (pthread_cancel.c:99) ==166897== by 0x120E6B: main (bar_bad.c:85) ==166897== Address 0x4030a80 is 2568 bytes inside data symbol "_rtld_local" ==166897== ==166897== Lock at 0x4030AD0 was first observed ==166897== at 0x4850BEC: mutex_lock_WRK (hg_intercepts.c:942) ==166897== by 0x4854F63: pthread_mutex_lock (hg_intercepts.c:958) ==166897== by 0x40120C3: _dl_allocate_tls_init (dl-tls.c:539) ==166897== by 0x4910127: allocate_stack (allocatestack.c:428) ==166897== by 0x4910127: pthread_create@@GLIBC_2.36 (pthread_create.c:647) ==166897== by 0x4853883: pthread_create_WRK (hg_intercepts.c:445) ==166897== by 0x4854B2F: pthread_create@* (hg_intercepts.c:478) ==166897== by 0x120D9F: main (bar_bad.c:59) ==166897== Address 0x4030ad0 is 2648 bytes inside data symbol "_rtld_local" ==166897== ==166897== Possible data race during read of size 8 at 0x4030B10 by thread #1 ==166897== Locks held: 2, at addresses 0x4030A80 0x4030AD0 ==166897== at 0x400B1A4: _dl_lookup_symbol_x (dl-lookup.c:824) ==166897== by 0x400F6BB: elf_machine_rela (dl-machine.h:186) ==166897== by 0x400F6BB: elf_dynamic_do_Rela (do-rel.h:147) ==166897== by 0x400F6BB: _dl_relocate_object (dl-reloc.c:288) ==166897== by 0x400D373: dl_open_worker_begin (dl-open.c:702) ==166897== by 0x49B2D2B: _dl_catch_exception (dl-error-skeleton.c:208) ==166897== by 0x400C917: dl_open_worker (dl-open.c:782) ==166897== by 0x49B2D2B: _dl_catch_exception (dl-error-skeleton.c:208) ==166897== by 0x400CD5B: _dl_open (dl-open.c:883) ==166897== by 0x49B311F: do_dlopen (dl-libc.c:95) ==166897== by 0x49B2D2B: _dl_catch_exception (dl-error-skeleton.c:208) ==166897== by 0x49B2DEF: _dl_catch_error (dl-error-skeleton.c:227) ==166897== by 0x49B3073: dlerror_run (dl-libc.c:45) ==166897== by 0x49B326F: __libc_dlopen_mode (dl-libc.c:162) ==166897== ==166897== This conflicts with a previous write of size 8 by thread #4 ==166897== Locks held: none ==166897== at 0x400B1C0: _dl_lookup_symbol_x (dl-lookup.c:824) ==166897== by 0x4010953: _dl_fixup (dl-runtime.c:95) ==166897== by 0x4012B27: _dl_runtime_resolve (dl-trampoline.S:62) ==166897== by 0xFFFFFFFFFFFFFFFF: ??? ==166897== Address 0x4030b10 is 2712 bytes inside data symbol "_rtld_local" ==166897== ==166897== ---------------------------------------------------------------- ==166897== ==166897== Lock at 0x4030A80 was first observed ==166897== at 0x4850BEC: mutex_lock_WRK (hg_intercepts.c:942) ==166897== by 0x4854F63: pthread_mutex_lock (hg_intercepts.c:958) ==166897== by 0x400CD17: _dl_open (dl-open.c:830) ==166897== by 0x49B311F: do_dlopen (dl-libc.c:95) ==166897== by 0x49B2D2B: _dl_catch_exception (dl-error-skeleton.c:208) ==166897== by 0x49B2DEF: _dl_catch_error (dl-error-skeleton.c:227) ==166897== by 0x49B3073: dlerror_run (dl-libc.c:45) ==166897== by 0x49B326F: __libc_dlopen_mode (dl-libc.c:162) ==166897== by 0x4978BD3: __libc_unwind_link_get (unwind-link.c:50) ==166897== by 0x490D783: pthread_cancel@@GLIBC_2.36 (pthread_cancel.c:99) ==166897== by 0x120E6B: main (bar_bad.c:85) ==166897== Address 0x4030a80 is 2568 bytes inside data symbol "_rtld_local" ==166897== ==166897== Lock at 0x4030AD0 was first observed ==166897== at 0x4850BEC: mutex_lock_WRK (hg_intercepts.c:942) ==166897== by 0x4854F63: pthread_mutex_lock (hg_intercepts.c:958) ==166897== by 0x40120C3: _dl_allocate_tls_init (dl-tls.c:539) ==166897== by 0x4910127: allocate_stack (allocatestack.c:428) ==166897== by 0x4910127: pthread_create@@GLIBC_2.36 (pthread_create.c:647) ==166897== by 0x4853883: pthread_create_WRK (hg_intercepts.c:445) ==166897== by 0x4854B2F: pthread_create@* (hg_intercepts.c:478) ==166897== by 0x120D9F: main (bar_bad.c:59) ==166897== Address 0x4030ad0 is 2648 bytes inside data symbol "_rtld_local" ==166897== ==166897== Possible data race during write of size 8 at 0x4030B10 by thread #1 ==166897== Locks held: 2, at addresses 0x4030A80 0x4030AD0 ==166897== at 0x400B1C0: _dl_lookup_symbol_x (dl-lookup.c:824) ==166897== by 0x400F6BB: elf_machine_rela (dl-machine.h:186) ==166897== by 0x400F6BB: elf_dynamic_do_Rela (do-rel.h:147) ==166897== by 0x400F6BB: _dl_relocate_object (dl-reloc.c:288) ==166897== by 0x400D373: dl_open_worker_begin (dl-open.c:702) ==166897== by 0x49B2D2B: _dl_catch_exception (dl-error-skeleton.c:208) ==166897== by 0x400C917: dl_open_worker (dl-open.c:782) ==166897== by 0x49B2D2B: _dl_catch_exception (dl-error-skeleton.c:208) ==166897== by 0x400CD5B: _dl_open (dl-open.c:883) ==166897== by 0x49B311F: do_dlopen (dl-libc.c:95) ==166897== by 0x49B2D2B: _dl_catch_exception (dl-error-skeleton.c:208) ==166897== by 0x49B2DEF: _dl_catch_error (dl-error-skeleton.c:227) ==166897== by 0x49B3073: dlerror_run (dl-libc.c:45) ==166897== by 0x49B326F: __libc_dlopen_mode (dl-libc.c:162) ==166897== ==166897== This conflicts with a previous write of size 8 by thread #4 ==166897== Locks held: none ==166897== at 0x400B1C0: _dl_lookup_symbol_x (dl-lookup.c:824) ==166897== by 0x4010953: _dl_fixup (dl-runtime.c:95) ==166897== by 0x4012B27: _dl_runtime_resolve (dl-trampoline.S:62) ==166897== by 0xFFFFFFFFFFFFFFFF: ??? ==166897== Address 0x4030b10 is 2712 bytes inside data symbol "_rtld_local" ==166897== ==166897== ---------------------------------------------------------------- ==166897== ==166897== Possible data race during read of size 8 at 0x4030B10 by thread #1 ==166897== Locks held: none ==166897== at 0x400B1A4: _dl_lookup_symbol_x (dl-lookup.c:824) ==166897== by 0x49B3177: do_dlsym (dl-libc.c:105) ==166897== by 0x49B2D2B: _dl_catch_exception (dl-error-skeleton.c:208) ==166897== by 0x49B2DEF: _dl_catch_error (dl-error-skeleton.c:227) ==166897== by 0x49B3073: dlerror_run (dl-libc.c:45) ==166897== by 0x49B32F7: __libc_dlsym (dl-libc.c:190) ==166897== by 0x4978BE7: __libc_unwind_link_get (unwind-link.c:59) ==166897== by 0x490D783: pthread_cancel@@GLIBC_2.36 (pthread_cancel.c:99) ==166897== by 0x120E6B: main (bar_bad.c:85) ==166897== ==166897== This conflicts with a previous write of size 8 by thread #4 ==166897== Locks held: none ==166897== at 0x400B1C0: _dl_lookup_symbol_x (dl-lookup.c:824) ==166897== by 0x4010953: _dl_fixup (dl-runtime.c:95) ==166897== by 0x4012B27: _dl_runtime_resolve (dl-trampoline.S:62) ==166897== by 0xFFFFFFFFFFFFFFFF: ??? ==166897== Address 0x4030b10 is 2712 bytes inside data symbol "_rtld_local" ==166897== ==166897== ---------------------------------------------------------------- ==166897== ==166897== Possible data race during write of size 8 at 0x4030B10 by thread #1 ==166897== Locks held: none ==166897== at 0x400B1C0: _dl_lookup_symbol_x (dl-lookup.c:824) ==166897== by 0x49B3177: do_dlsym (dl-libc.c:105) ==166897== by 0x49B2D2B: _dl_catch_exception (dl-error-skeleton.c:208) ==166897== by 0x49B2DEF: _dl_catch_error (dl-error-skeleton.c:227) ==166897== by 0x49B3073: dlerror_run (dl-libc.c:45) ==166897== by 0x49B32F7: __libc_dlsym (dl-libc.c:190) ==166897== by 0x4978BE7: __libc_unwind_link_get (unwind-link.c:59) ==166897== by 0x490D783: pthread_cancel@@GLIBC_2.36 (pthread_cancel.c:99) ==166897== by 0x120E6B: main (bar_bad.c:85) ==166897== ==166897== This conflicts with a previous write of size 8 by thread #4 ==166897== Locks held: none ==166897== at 0x400B1C0: _dl_lookup_symbol_x (dl-lookup.c:824) ==166897== by 0x4010953: _dl_fixup (dl-runtime.c:95) ==166897== by 0x4012B27: _dl_runtime_resolve (dl-trampoline.S:62) ==166897== by 0xFFFFFFFFFFFFFFFF: ??? ==166897== Address 0x4030b10 is 2712 bytes inside data symbol "_rtld_local" ==166897== destroy a barrier that was never initialised ==166897== ---------------------------------------------------------------- ==166897== ==166897== Thread #1: pthread_barrier_destroy: barrier was never initialised ==166897== at 0x4855444: pthread_barrier_destroy (hg_intercepts.c:1944) ==166897== by 0x120EFB: main (bar_bad.c:100) ==166897== ==166897== ---------------------------------------------------------------- ==166897== ==166897== Lock at 0x4030A80 was first observed ==166897== at 0x4850BEC: mutex_lock_WRK (hg_intercepts.c:942) ==166897== by 0x4854F63: pthread_mutex_lock (hg_intercepts.c:958) ==166897== by 0x400CD17: _dl_open (dl-open.c:830) ==166897== by 0x49B311F: do_dlopen (dl-libc.c:95) ==166897== by 0x49B2D2B: _dl_catch_exception (dl-error-skeleton.c:208) ==166897== by 0x49B2DEF: _dl_catch_error (dl-error-skeleton.c:227) ==166897== by 0x49B3073: dlerror_run (dl-libc.c:45) ==166897== by 0x49B326F: __libc_dlopen_mode (dl-libc.c:162) ==166897== by 0x4978BD3: __libc_unwind_link_get (unwind-link.c:50) ==166897== by 0x490D783: pthread_cancel@@GLIBC_2.36 (pthread_cancel.c:99) ==166897== by 0x120E6B: main (bar_bad.c:85) ==166897== Address 0x4030a80 is 2568 bytes inside data symbol "_rtld_local" ==166897== ==166897== Possible data race during write of size 2 at 0x4032774 by thread #1 ==166897== Locks held: 1, at address 0x4030A80 ==166897== at 0x4011470: _dl_sort_maps_dfs (dl-sort-maps.c:188) ==166897== by 0x4011470: _dl_sort_maps (dl-sort-maps.c:301) ==166897== by 0x4006133: _dl_fini (dl-fini.c:99) ==166897== by 0x48CDF63: __run_exit_handlers (exit.c:113) ==166897== by 0x48CE0D7: exit (exit.c:143) ==166897== by 0x120F2B: main (bar_bad.c:110) ==166897== ==166897== This conflicts with a previous read of size 2 by thread #4 ==166897== Locks held: none ==166897== at 0x400B274: _dl_lookup_symbol_x (dl-lookup.c:907) ==166897== by 0x4010953: _dl_fixup (dl-runtime.c:95) ==166897== by 0x4012B27: _dl_runtime_resolve (dl-trampoline.S:62) ==166897== by 0xFFFFFFFFFFFFFFFF: ??? ==166897== Address 0x4032774 is in a rw- mapped file /usr/lib64/ld-linux-loongarch-lp64d.so.1 segment ==166897== ==166897== ---------------------------------------------------------------- ==166897== ==166897== Possible data race during write of size 2 at 0x4032774 by thread #1 ==166897== Locks held: none ==166897== at 0x4006178: _dl_fini (dl-fini.c:120) ==166897== by 0x48CDF63: __run_exit_handlers (exit.c:113) ==166897== by 0x48CE0D7: exit (exit.c:143) ==166897== by 0x120F2B: main (bar_bad.c:110) ==166897== ==166897== This conflicts with a previous read of size 2 by thread #4 ==166897== Locks held: none ==166897== at 0x400B274: _dl_lookup_symbol_x (dl-lookup.c:907) ==166897== by 0x4010953: _dl_fixup (dl-runtime.c:95) ==166897== by 0x4012B27: _dl_runtime_resolve (dl-trampoline.S:62) ==166897== by 0xFFFFFFFFFFFFFFFF: ??? ==166897== Address 0x4032774 is in a rw- mapped file /usr/lib64/ld-linux-loongarch-lp64d.so.1 segment ==166897== ==166897== ==166897== Use --history-level=approx or =none to gain increased speed, at ==166897== the cost of reduced accuracy of conflicting-access information ==166897== For lists of detected and suppressed errors, rerun with: -s ==166897== ERROR SUMMARY: 37 errors from 17 contexts (suppressed: 8 from 7) Thanks, Feiyang |
|
From: Mark W. <ma...@so...> - 2022-06-09 21:11:02
|
https://sourceware.org/git/gitweb.cgi?p=valgrind.git;h=3aee8a29447ea14108eb5d4ab3c1f7677767296a commit 3aee8a29447ea14108eb5d4ab3c1f7677767296a Author: Mark Wielaard <ma...@kl...> Date: Thu Jun 9 23:06:36 2022 +0200 syswrap-linux.c (sys_execveat): Define path as const HChar * Like buf, path (ARG2) is a const HChar * Prevents a gcc warning: assignment discards 'const' qualifier from pointer target type [-Wdiscarded-qualifiers] 13328 | path = buf; | ^ Diff: --- coregrind/m_syswrap/syswrap-linux.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/coregrind/m_syswrap/syswrap-linux.c b/coregrind/m_syswrap/syswrap-linux.c index 04502f6257..adc3132118 100644 --- a/coregrind/m_syswrap/syswrap-linux.c +++ b/coregrind/m_syswrap/syswrap-linux.c @@ -13302,7 +13302,7 @@ PRE(sys_execveat) return; #endif - char *path = (char*) ARG2; + const HChar *path = (const HChar*) ARG2; Addr arg_2 = ARG3; Addr arg_3 = ARG4; const HChar *buf; |
|
From: Mark W. <ma...@so...> - 2022-06-09 21:10:57
|
https://sourceware.org/git/gitweb.cgi?p=valgrind.git;h=438d5e956dfa989184fcd4c18d7db534f65b75b6 commit 438d5e956dfa989184fcd4c18d7db534f65b75b6 Author: Mark Wielaard <ma...@kl...> Date: Thu Jun 9 22:51:56 2022 +0200 syswrap-linux.c (sys_bpf): Compare raw_tracepoint.name against 0, not NULL raw_tracepoint.name is a __vki_u64 (even on 32bit arches), so compare against zero, not NULL, to avoid a gcc warning. Diff: --- coregrind/m_syswrap/syswrap-linux.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/coregrind/m_syswrap/syswrap-linux.c b/coregrind/m_syswrap/syswrap-linux.c index 70aaec2f2d..04502f6257 100644 --- a/coregrind/m_syswrap/syswrap-linux.c +++ b/coregrind/m_syswrap/syswrap-linux.c @@ -12938,7 +12938,7 @@ PRE(sys_bpf) break; } /* Name is limited to 128 characters in kernel/bpf/syscall.c. */ - if (attr->raw_tracepoint.name != NULL) + if (attr->raw_tracepoint.name != 0) pre_asciiz_str(tid, attr->raw_tracepoint.name, 128, "bpf(attr->raw_tracepoint.name)"); } |
|
From: Mark W. <ma...@so...> - 2022-06-09 21:10:55
|
https://sourceware.org/git/gitweb.cgi?p=valgrind.git;h=61ddbc1fc395c787192e569d8f2238f713bdfd8e commit 61ddbc1fc395c787192e569d8f2238f713bdfd8e Author: Luboš Luňák <l....@ce...> Date: Tue Apr 19 10:58:44 2022 +0200 read properly unit headers depending on dwarf5 unit_type There may be additional fields that need to be skipped over, otherwise further reading will interpret these incorrectly. Diff: --- coregrind/m_debuginfo/readdwarf.c | 27 +++++++++++++++++++++++++-- coregrind/m_debuginfo/readdwarf3.c | 8 +++++++- 2 files changed, 32 insertions(+), 3 deletions(-) diff --git a/coregrind/m_debuginfo/readdwarf.c b/coregrind/m_debuginfo/readdwarf.c index 39a2946870..56cef9a5f4 100644 --- a/coregrind/m_debuginfo/readdwarf.c +++ b/coregrind/m_debuginfo/readdwarf.c @@ -1056,6 +1056,7 @@ void read_unitinfo_dwarf2( /*OUT*/UnitInfo* ui, UShort ver; UChar addr_size = 0; + UChar unit_type = 0; DiCursor p = unitblock_img; DiCursor end_img; DiCursor abbrev_img; @@ -1073,7 +1074,7 @@ void read_unitinfo_dwarf2( /*OUT*/UnitInfo* ui, if (ver >= 5) /* unit_type for DWARF5 */ - /* unit_type = */ ML_(cur_step_UChar)(&p); + unit_type = ML_(cur_step_UChar)(&p); else /* get offset in abbrev */ atoffs = ui->dw64 ? ML_(cur_step_ULong)(&p) @@ -1082,11 +1083,33 @@ void read_unitinfo_dwarf2( /*OUT*/UnitInfo* ui, /* Address size */ addr_size = ML_(cur_step_UChar)(&p); - if (ver >= 5) + if (ver >= 5) { /* get offset in abbrev */ atoffs = ui->dw64 ? ML_(cur_step_ULong)(&p) : (ULong)(ML_(cur_step_UInt)(&p)); + /* read any extra fields */ + switch(unit_type) { + case DW_UT_compile: + case DW_UT_partial: + break; + case DW_UT_skeleton: + case DW_UT_split_compile: + /* dwo_id = */ ML_(cur_step_ULong)(&p); + break; + case DW_UT_type: + case DW_UT_split_type: + /* type_signature = */ ML_(cur_step_ULong)(&p); + /* type_offset = */ ui->dw64 ? ML_(cur_step_ULong)(&p) + : (ULong)(ML_(cur_step_UInt)(&p)); + break; + default: + VG_(printf)( "### unhandled dwarf2 unit_type code 0x%x\n", + unit_type ); + break; + } + } + /* End of this block */ end_img = ML_(cur_plus)(unitblock_img, blklen + (ui->dw64 ? 12 : 4)); diff --git a/coregrind/m_debuginfo/readdwarf3.c b/coregrind/m_debuginfo/readdwarf3.c index 5489f8d135..1453ebbdbc 100644 --- a/coregrind/m_debuginfo/readdwarf3.c +++ b/coregrind/m_debuginfo/readdwarf3.c @@ -1200,11 +1200,17 @@ void parse_CU_Header ( /*OUT*/CUConst* cc, cc->is_type_unit = type_unit; cc->is_alt_info = alt_info; - if (type_unit || (cc->version >= 5 && unit_type == DW_UT_type)) { + if (type_unit || (cc->version >= 5 && (unit_type == DW_UT_type + || unit_type == DW_UT_split_type))) { cc->type_signature = get_ULong( c ); cc->type_offset = get_Dwarfish_UWord( c, cc->is_dw64 ); } + if (cc->version >= 5 && (unit_type == DW_UT_skeleton + || unit_type == DW_UT_split_compile)) { + /* dwo_id = */ get_ULong( c ); + } + /* Set up cc->debug_abbv to point to the relevant table for this CU. Set its .szB so that at least we can't read off the end of the debug_abbrev section -- potentially (and quite likely) too |
|
From: Paul F. <pa...@so...> - 2022-06-09 20:10:44
|
https://sourceware.org/git/gitweb.cgi?p=valgrind.git;h=7844752299b5472b21fc4df765d4cffdf92c6c3d commit 7844752299b5472b21fc4df765d4cffdf92c6c3d Author: Paul Floyd <pj...@wa...> Date: Thu Jun 9 22:03:04 2022 +0200 Bug 452802 Handle lld 9+ split RW PT_LOAD segments correctly Many changes mostly related to modifying VG_(di_notify_mmap)( Addr a, Bool allow_SkFileV, Int use_fd ) so that instead of triggering debuginfo reading after seeing one RX PT_LOAD and 1 RW PT_LOAD it can handle either 1 or 2 RW PT_LOADs. Diff: --- NEWS | 1 + coregrind/m_debuginfo/debuginfo.c | 135 ++++++++++++++++-- coregrind/m_debuginfo/image.c | 76 ++++++++-- coregrind/m_debuginfo/priv_image.h | 5 + coregrind/m_debuginfo/priv_readelf.h | 2 + coregrind/m_debuginfo/priv_storage.h | 2 +- coregrind/m_debuginfo/readelf.c | 215 ++++++++++++++++++++++------- coregrind/m_debuginfo/readpdb.c | 4 +- coregrind/m_debuginfo/storage.c | 6 +- memcheck/tests/Makefile.am | 1 + memcheck/tests/varinfo5.stderr.exp-freebsd | 191 +++++++++++++++++++++++++ 11 files changed, 556 insertions(+), 82 deletions(-) diff --git a/NEWS b/NEWS index a0cf73eaff..1f92c25e3d 100644 --- a/NEWS +++ b/NEWS @@ -41,6 +41,7 @@ are not entered into bugzilla tend to get forgotten about or ignored. 452779 Valgrind fails to build on FreeBSD 13.0 with llvm-devel (15.0.0) 453055 shared_timed_mutex drd test fails with "Lock shared failed" message 453602 Missing command line option to enable/disable debuginfod +452802 Handle lld 9+ split RW PT_LOAD segments correctly To see details of a given bug, visit https://bugs.kde.org/show_bug.cgi?id=XXXXXX diff --git a/coregrind/m_debuginfo/debuginfo.c b/coregrind/m_debuginfo/debuginfo.c index 60f9ea195d..34a2ea8ccb 100644 --- a/coregrind/m_debuginfo/debuginfo.c +++ b/coregrind/m_debuginfo/debuginfo.c @@ -665,7 +665,7 @@ static void check_CFSI_related_invariants ( const DebugInfo* di ) been successfully read. And that shouldn't happen until we have both a r-x and rw- mapping for the object. Hence: */ vg_assert(di->fsm.have_rx_map); - vg_assert(di->fsm.have_rw_map); + vg_assert(di->fsm.rw_map_count); for (i = 0; i < VG_(sizeXA)(di->fsm.maps); i++) { const DebugInfoMapping* map = VG_(indexXA)(di->fsm.maps, i); /* We are interested in r-x mappings only */ @@ -1024,16 +1024,96 @@ static ULong di_notify_ACHIEVE_ACCEPT_STATE ( struct _DebugInfo* di ) /* Notify the debuginfo system about a new mapping. This is the way - new debug information gets loaded. If allow_SkFileV is True, it - will try load debug info if the mapping at 'a' belongs to Valgrind; - whereas normally (False) it will not do that. This allows us to - carefully control when the thing will read symbols from the - Valgrind executable itself. + new debug information gets loaded. + + redelf -e will output something like + + readelf -e says + + Program Headers: + Type Offset VirtAddr PhysAddr + FileSiz MemSiz Flg Align + PHDR 0x0000000000000040 0x0000000000200040 0x0000000000200040 + 0x0000000000000268 0x0000000000000268 R 0x8 + INTERP 0x00000000000002a8 0x00000000002002a8 0x00000000002002a8 + 0x0000000000000015 0x0000000000000015 R 0x1 + [Requesting program interpreter: /libexec/ld-elf.so.1] + LOAD 0x0000000000000000 0x0000000000200000 0x0000000000200000 + 0x0000000000002acc 0x0000000000002acc R 0x1000 + LOAD 0x0000000000002ad0 0x0000000000203ad0 0x0000000000203ad0 + 0x0000000000004a70 0x0000000000004a70 R E 0x1000 + LOAD 0x0000000000007540 0x0000000000209540 0x0000000000209540 + 0x00000000000001d8 0x00000000000001d8 RW 0x1000 + LOAD 0x0000000000007720 0x000000000020a720 0x000000000020a720 + 0x00000000000002b8 0x00000000000005a0 RW 0x1000 + DYNAMIC 0x0000000000007570 0x0000000000209570 0x0000000000209570 + 0x00000000000001a0 0x00000000000001a0 RW 0x8 + GNU_RELRO 0x0000000000007540 0x0000000000209540 0x0000000000209540 + 0x00000000000001d8 0x00000000000001d8 R 0x1 + GNU_EH_FRAME 0x0000000000002334 0x0000000000202334 0x0000000000202334 + 0x000000000000012c 0x000000000000012c R 0x4 + GNU_STACK 0x0000000000000000 0x0000000000000000 0x0000000000000000 + 0x0000000000000000 0x0000000000000000 RW 0 + NOTE 0x00000000000002c0 0x00000000002002c0 0x00000000002002c0 + 0x0000000000000048 0x0000000000000048 R 0x4 + + This function will be called for the "LOAD" segments above. + + This function gets called from 2 contexts + + "HOST TRIGGERED" + + 1a. For the tool exe and tool/core shared libs. These are already + mmap'd when the host starts so we look at something like the + /proc filesystem to get the mapping after the event and build + up the NSegments from that. + + 1b. Then the host loads ld.so and the guest exe. This is done in + the sequence + load_client -> VG_(do_exec) -> VG_(do_exec_inner) -> + exe_handlers->load_fn ( == VG_(load_ELF) ). + + This does the mmap'ing and creats the associated NSegments. + + The NSegments may get merged, (see maybe_merge_nsegments) + so there could be more PT_LOADs than there are NSegments. + VG_(di_notify_mmap) is called by iterating over the + NSegments + + "GUEST TRIGGERED" + + 2. When the guest loads any further shared libs (libc, + other dependencies, dlopens) using mmap. + + There are a few variations for syswraps/platforms. + + In this case the NSegment could possibly be merged, + but that is irrelevant because di_notify_mmap is being + called directy on the mmap result. + + If allow_SkFileV is True, it will try load debug info if the + mapping at 'a' belongs to Valgrind; whereas normally (False) + it will not do that. This allows us to carefully control when + the thing will read symbols from the Valgrind executable itself. If use_fd is not -1, that is used instead of the filename; this avoids perturbing fcntl locks, which are released by simply re-opening and closing the same file (even via different fd!). + Read-only mappings will be ignored. + There may be 1 or 2 RW mappings. + There will also be 1 RX mapping. + + If there is no RX or no RW mapping then we will not attempt to + read debuginfo for the file. + + In order to know whether there are 1 or 2 RW mappings we + need to check the ELF headers. And in the case that we + detect 2 RW mappings we need to double check that they + aren't contiguous in memory resulting in merged NSegemnts. + + This does not apply to Darwin which just checks the Mach-O header + If a call to VG_(di_notify_mmap) causes debug info to be read, then the returned ULong is an abstract handle which can later be used to refer to the debuginfo read as a result of this specific mapping, @@ -1044,12 +1124,19 @@ static ULong di_notify_ACHIEVE_ACCEPT_STATE ( struct _DebugInfo* di ) ULong VG_(di_notify_mmap)( Addr a, Bool allow_SkFileV, Int use_fd ) { NSegment const * seg; + Int rw_load_count; const HChar* filename; Bool is_rx_map, is_rw_map, is_ro_map; + DebugInfo* di; Int actual_fd, oflags; +#if defined(VGO_darwin) SysRes preadres; HChar buf1k[1024]; +#else + Bool elf_ok; +#endif + const Bool debug = VG_(debugLog_getLevel)() >= 3; SysRes statres; struct vg_stat statbuf; @@ -1211,9 +1298,12 @@ ULong VG_(di_notify_mmap)( Addr a, Bool allow_SkFileV, Int use_fd ) return 0; #endif +#if defined(VGO_darwin) /* Peer at the first few bytes of the file, to see if it is an ELF */ /* object file. Ignore the file if we do not have read permission. */ VG_(memset)(buf1k, 0, sizeof(buf1k)); +#endif + oflags = VKI_O_RDONLY; # if defined(VKI_O_LARGEFILE) oflags |= VKI_O_LARGEFILE; @@ -1237,6 +1327,7 @@ ULong VG_(di_notify_mmap)( Addr a, Bool allow_SkFileV, Int use_fd ) actual_fd = use_fd; } +#if defined(VGO_darwin) preadres = VG_(pread)( actual_fd, buf1k, sizeof(buf1k), 0 ); if (use_fd == -1) { VG_(close)( actual_fd ); @@ -1246,20 +1337,33 @@ ULong VG_(di_notify_mmap)( Addr a, Bool allow_SkFileV, Int use_fd ) DebugInfo fake_di; VG_(memset)(&fake_di, 0, sizeof(fake_di)); fake_di.fsm.filename = ML_(dinfo_strdup)("di.debuginfo.nmm", filename); - ML_(symerr)(&fake_di, True, "can't read file to inspect ELF header"); + ML_(symerr)(&fake_di, True, "can't read file to inspect Mach-O headers"); return 0; } if (sr_Res(preadres) == 0) return 0; vg_assert(sr_Res(preadres) > 0 && sr_Res(preadres) <= sizeof(buf1k) ); +#endif /* We're only interested in mappings of object files. */ # if defined(VGO_linux) || defined(VGO_solaris) || defined(VGO_freebsd) - if (!ML_(is_elf_object_file)( buf1k, (SizeT)sr_Res(preadres), False )) + + rw_load_count = 0; + + elf_ok = ML_(check_elf_and_get_rw_loads) ( actual_fd, filename, &rw_load_count ); + + if (use_fd == -1) { + VG_(close)( actual_fd ); + } + + if (!elf_ok) { return 0; + } + # elif defined(VGO_darwin) if (!ML_(is_macho_object_file)( buf1k, (SizeT)sr_Res(preadres) )) return 0; + rw_load_count = 1; # else # error "unknown OS" # endif @@ -1311,15 +1415,20 @@ ULong VG_(di_notify_mmap)( Addr a, Bool allow_SkFileV, Int use_fd ) /* Update flags about what kind of mappings we've already seen. */ di->fsm.have_rx_map |= is_rx_map; - di->fsm.have_rw_map |= is_rw_map; + /* This is a bit of a hack, using a Bool as a counter */ + if (is_rw_map) + ++di->fsm.rw_map_count; di->fsm.have_ro_map |= is_ro_map; /* So, finally, are we in an accept state? */ vg_assert(!di->have_dinfo); - if (di->fsm.have_rx_map && di->fsm.have_rw_map) { + if (di->fsm.have_rx_map && + rw_load_count >= 1 && + di->fsm.rw_map_count == rw_load_count) { /* Ok, so, finally, we found what we need, and we haven't already read debuginfo for this object. So let's do so now. Yee-ha! */ + if (debug) VG_(dmsg)("di_notify_mmap-5: " "achieved accept state for %s\n", filename); @@ -1416,7 +1525,7 @@ void VG_(di_notify_vm_protect)( Addr a, SizeT len, UInt prot ) continue; /* need to have a r-- mapping for this object */ if (di->fsm.have_rx_map) continue; /* rx- mapping already exists */ - if (!di->fsm.have_rw_map) + if (!di->fsm.rw_map_count) continue; /* need to have a rw- mapping */ /* Try to find a mapping matching the memory area. */ for (i = 0; i < VG_(sizeXA)(di->fsm.maps); i++) { @@ -1454,7 +1563,7 @@ void VG_(di_notify_vm_protect)( Addr a, SizeT len, UInt prot ) } /* Check if we're now in an accept state and read debuginfo. Finally. */ - if (di->fsm.have_rx_map && di->fsm.have_rw_map && !di->have_dinfo) { + if (di->fsm.have_rx_map && di->fsm.rw_map_count && !di->have_dinfo) { if (debug) VG_(dmsg)("di_notify_vm_protect-5: " "achieved accept state for %s\n", di->fsm.filename); @@ -1669,7 +1778,7 @@ void VG_(di_notify_pdb_debuginfo)( Int fd_obj, Addr avma_obj, { DebugInfo* di = find_or_create_DebugInfo_for(exename); /* this di must be new, since we just nuked any old stuff in the range */ - vg_assert(di && !di->fsm.have_rx_map && !di->fsm.have_rw_map); + vg_assert(di && !di->fsm.have_rx_map && !di->fsm.rw_map_count); vg_assert(!di->have_dinfo); /* don't set up any of the di-> fields; let diff --git a/coregrind/m_debuginfo/image.c b/coregrind/m_debuginfo/image.c index ebe6dfcfe8..28dfd0b472 100644 --- a/coregrind/m_debuginfo/image.c +++ b/coregrind/m_debuginfo/image.c @@ -874,6 +874,49 @@ DiImage* ML_(img_from_local_file)(const HChar* fullpath) return img; } +/* As above, but uses fd rather than filename */ +DiImage* ML_(img_from_fd)(Int fd, const HChar* fullpath) +{ + struct vg_stat stat_buf; + DiOffT size; + + if (VG_(fstat)(fd, &stat_buf) != 0) { + return NULL; + } + + size = stat_buf.size; + if (size == 0 || size == DiOffT_INVALID + || /* size is unrepresentable as a SizeT */ + size != (DiOffT)(SizeT)(size)) { + return NULL; + } + + DiImage* img = ML_(dinfo_zalloc)("di.image.ML_iflf.1", sizeof(DiImage)); + img->source.is_local = True; + img->source.fd = fd; + img->size = size; + img->real_size = size; + img->ces_used = 0; + img->source.name = ML_(dinfo_strdup)("di.image.ML_iflf.2", fullpath); + img->cslc = NULL; + img->cslc_size = 0; + img->cslc_used = 0; + /* img->ces is already zeroed out */ + vg_assert(img->source.fd >= 0); + + /* Force the zeroth entry to be the first chunk of the file. + That's likely to be the first part that's requested anyway, and + loading it at this point forcing img->cent[0] to always be + non-empty, thereby saving us an is-it-empty check on the fast + path in get(). */ + UInt entNo = alloc_CEnt(img, CACHE_ENTRY_SIZE, False/*!fromC*/); + vg_assert(entNo == 0); + set_CEnt(img, 0, 0); + + return img; +} + + /* Create an image from a file on a remote debuginfo server. This is more complex. There are lots of ways in which it can fail. */ @@ -1007,20 +1050,9 @@ DiOffT ML_(img_mark_compressed_part)(DiImage* img, DiOffT offset, SizeT szC, return ret; } -void ML_(img_done)(DiImage* img) +void ML_(img_free)(DiImage* img) { vg_assert(img != NULL); - if (img->source.is_local) { - /* Close the file; nothing else to do. */ - vg_assert(img->source.session_id == 0); - VG_(close)(img->source.fd); - } else { - /* Close the socket. The server can detect this and will scrub - the connection when it happens, so there's no need to tell it - explicitly by sending it a "CLOSE" message, or any such. */ - vg_assert(img->source.session_id != 0); - VG_(close)(img->source.fd); - } /* Free up the cache entries, ultimately |img| itself. */ UInt i; @@ -1037,6 +1069,26 @@ void ML_(img_done)(DiImage* img) ML_(dinfo_free)(img); } +void ML_(img_done)(DiImage* img) +{ + vg_assert(img != NULL); + if (img->source.is_local) { + /* Close the file; nothing else to do. */ + vg_assert(img->source.session_id == 0); + VG_(close)(img->source.fd); + } else { + /* Close the socket. The server can detect this and will scrub + the connection when it happens, so there's no need to tell it + explicitly by sending it a "CLOSE" message, or any such. */ + vg_assert(img->source.session_id != 0); + VG_(close)(img->source.fd); + } + + ML_(img_free)(img); +} + + + DiOffT ML_(img_size)(const DiImage* img) { vg_assert(img != NULL); diff --git a/coregrind/m_debuginfo/priv_image.h b/coregrind/m_debuginfo/priv_image.h index f7413a9084..a49846f149 100644 --- a/coregrind/m_debuginfo/priv_image.h +++ b/coregrind/m_debuginfo/priv_image.h @@ -59,6 +59,8 @@ typedef ULong DiOffT; if it fails, for whatever reason. */ DiImage* ML_(img_from_local_file)(const HChar* fullpath); +DiImage* ML_(img_from_fd)(Int fd, const HChar* fullpath); + /* Create an image by connecting to a Valgrind debuginfo server (auxprogs/valgrind-di-server.c). |filename| contains the object name to ask for; it must be a plain filename, not absolute, not a @@ -69,6 +71,9 @@ DiImage* ML_(img_from_local_file)(const HChar* fullpath); DiImage* ML_(img_from_di_server)(const HChar* filename, const HChar* serverAddr); +/* Free memory allocated for image. */ +void ML_(img_free)(DiImage*); + /* Destroy an existing image. */ void ML_(img_done)(DiImage*); diff --git a/coregrind/m_debuginfo/priv_readelf.h b/coregrind/m_debuginfo/priv_readelf.h index 2bee615ab5..57aa0cc3f3 100644 --- a/coregrind/m_debuginfo/priv_readelf.h +++ b/coregrind/m_debuginfo/priv_readelf.h @@ -52,6 +52,8 @@ extern Bool ML_(is_elf_object_file)( const void* image, SizeT n_image, */ extern Bool ML_(read_elf_debug_info) ( DebugInfo* di ); +extern Bool ML_(check_elf_and_get_rw_loads) ( Int fd, const HChar* filename, Int * rw_load_count ); + #endif /* ndef __PRIV_READELF_H */ diff --git a/coregrind/m_debuginfo/priv_storage.h b/coregrind/m_debuginfo/priv_storage.h index ae44ca34e5..f44ab43ffe 100644 --- a/coregrind/m_debuginfo/priv_storage.h +++ b/coregrind/m_debuginfo/priv_storage.h @@ -585,7 +585,7 @@ struct _DebugInfoFSM HChar* dbgname; /* in mallocville (VG_AR_DINFO) */ XArray* maps; /* XArray of DebugInfoMapping structs */ Bool have_rx_map; /* did we see a r?x mapping yet for the file? */ - Bool have_rw_map; /* did we see a rw? mapping yet for the file? */ + Int rw_map_count; /* count of w? mappings seen (may be > 1 ) */ Bool have_ro_map; /* did we see a r-- mapping yet for the file? */ }; diff --git a/coregrind/m_debuginfo/readelf.c b/coregrind/m_debuginfo/readelf.c index ea9c80415b..b4edb4fe85 100644 --- a/coregrind/m_debuginfo/readelf.c +++ b/coregrind/m_debuginfo/readelf.c @@ -1182,10 +1182,10 @@ void read_and_set_osrel(DiImage* img) SizeT newlen = sizeof(osrel); Int error = VG_(sysctl)(name, 4, NULL, NULL, &osrel, newlen); if (error == -1) { - VG_(message)(Vg_DebugMsg, "Warning: failed to set osrel for current process with value %d\n", osrel); + VG_(message)(Vg_DebugMsg, "Warning: failed to set osrel for current process with value %u\n", osrel); } else { if (VG_(clo_verbosity) > 1) { - VG_(message)(Vg_DebugMsg, "Set osrel for current process with value %d\n", osrel); + VG_(message)(Vg_DebugMsg, "Set osrel for current process with value %u\n", osrel); } } } @@ -1924,7 +1924,7 @@ Bool ML_(read_elf_debug_info) ( struct _DebugInfo* di ) vg_assert(di); vg_assert(di->fsm.have_rx_map == True); - vg_assert(di->fsm.have_rw_map == True); + vg_assert(di->fsm.rw_map_count >= 1); vg_assert(di->have_dinfo == False); vg_assert(di->fsm.filename); vg_assert(!di->symtab); @@ -2120,11 +2120,6 @@ Bool ML_(read_elf_debug_info) ( struct _DebugInfo* di ) item.svma_limit = a_phdr.p_vaddr + a_phdr.p_memsz; item.bias = map->avma - map->foff + a_phdr.p_offset - a_phdr.p_vaddr; -#if (FREEBSD_VERS >= FREEBSD_12_2) - if ((long long int)item.bias < 0LL) { - item.bias = 0; - } -#endif if (map->rw && (a_phdr.p_flags & (PF_R | PF_W)) == (PF_R | PF_W)) { @@ -2264,9 +2259,10 @@ Bool ML_(read_elf_debug_info) ( struct _DebugInfo* di ) } for (i = 0; i < VG_(sizeXA)(di->fsm.maps); i++) { const DebugInfoMapping* map = VG_(indexXA)(di->fsm.maps, i); - if (map->rw) + if (map->rw) { TRACE_SYMTAB("rw: at %#lx are mapped foffsets %lld .. %lld\n", map->avma, (Long)map->foff, (Long)(map->foff + map->size - 1) ); + } } TRACE_SYMTAB("rw: contains these svma regions:\n"); for (i = 0; i < VG_(sizeXA)(svma_ranges); i++) { @@ -2290,28 +2286,34 @@ Bool ML_(read_elf_debug_info) ( struct _DebugInfo* di ) UInt alyn = a_shdr.sh_addralign; Bool nobits = a_shdr.sh_type == SHT_NOBITS; /* Look through our collection of info obtained from the PT_LOAD - headers, and make 'inrx' and 'inrw' point to the first entry + headers, and make 'inrx' and 'inrw1' point to the first entry in each that intersects 'avma'. If in each case none is found, leave the relevant pointer at NULL. */ RangeAndBias* inrx = NULL; - RangeAndBias* inrw = NULL; + RangeAndBias* inrw1 = NULL; + /* Depending on the link editro there may be two RW PT_LOAD headers + * If so this will point to the seond one */ + RangeAndBias* inrw2 = NULL; + /* used to switch between inrw1 and inrw2 */ + RangeAndBias* inrw; + for (j = 0; j < VG_(sizeXA)(svma_ranges); j++) { RangeAndBias* rng = VG_(indexXA)(svma_ranges, j); if (svma >= rng->svma_base && svma < rng->svma_limit) { if (!inrx && rng->exec) { inrx = rng; - } else if (!inrw && !rng->exec) { - inrw = rng; + } else if (!inrw1 && !rng->exec) { + inrw1 = rng; + } else if (!inrw2 && !rng->exec) { + inrw2 = rng; } - if (inrx && inrw) - break; } } - TRACE_SYMTAB(" [sec %2ld] %s %s al%4u foff %6lld .. %6lld " + TRACE_SYMTAB(" [sec %2ld] %s %s %s al%4u foff %6lld .. %6lld " " svma %p name \"%s\"\n", - i, inrx ? "rx" : " ", inrw ? "rw" : " ", alyn, - (Long) foff, (size == 0) ? (Long)foff : (Long)(foff+size-1), + i, inrx ? "rx" : " ", inrw1 ? "rw" : " ", inrw2 ? "rw" : " ", + alyn, (Long) foff, (size == 0) ? (Long)foff : (Long)(foff+size-1), (void *) svma, name); /* Check for sane-sized segments. SHT_NOBITS sections have zero @@ -2350,6 +2352,8 @@ Bool ML_(read_elf_debug_info) ( struct _DebugInfo* di ) /* Find avma-s for: .text .data .sdata .rodata .bss .sbss .plt .got .opd and .eh_frame */ + /* In inrw2 is non-NULL then it will be used for .data .got.plt .bss */ + /* Accept .text where mapped as rx (code), even if zero-sized */ if (0 == VG_(strcmp)(name, ".text")) { if (inrx && !di->text_present) { @@ -2380,6 +2384,13 @@ Bool ML_(read_elf_debug_info) ( struct _DebugInfo* di ) "%#lx .. %#lx\n", svma, svma + size - 1); } else # endif /* SOLARIS_PT_SUNDWTRACE_THRP */ + + if (inrw2) { + inrw = inrw2; + } else { + inrw = inrw1; + } + if (inrw && !di->data_present) { di->data_present = True; di->data_svma = svma; @@ -2402,14 +2413,14 @@ Bool ML_(read_elf_debug_info) ( struct _DebugInfo* di ) /* Accept .sdata where mapped as rw (data) */ if (0 == VG_(strcmp)(name, ".sdata")) { - if (inrw && !di->sdata_present) { + if (inrw1 && !di->sdata_present) { di->sdata_present = True; di->sdata_svma = svma; - di->sdata_avma = svma + inrw->bias; + di->sdata_avma = svma + inrw1->bias; di->sdata_size = size; - di->sdata_bias = inrw->bias; + di->sdata_bias = inrw1->bias; di->sdata_debug_svma = svma; - di->sdata_debug_bias = inrw->bias; + di->sdata_debug_bias = inrw1->bias; TRACE_SYMTAB("acquiring .sdata svma = %#lx .. %#lx\n", di->sdata_svma, di->sdata_svma + di->sdata_size - 1); @@ -2434,10 +2445,10 @@ Bool ML_(read_elf_debug_info) ( struct _DebugInfo* di ) di->rodata_avma += inrx->bias; di->rodata_bias = inrx->bias; di->rodata_debug_bias = inrx->bias; - } else if (inrw) { - di->rodata_avma += inrw->bias; - di->rodata_bias = inrw->bias; - di->rodata_debug_bias = inrw->bias; + } else if (inrw1) { + di->rodata_avma += inrw1->bias; + di->rodata_bias = inrw1->bias; + di->rodata_debug_bias = inrw1->bias; } else { BAD(".rodata"); } @@ -2456,15 +2467,15 @@ Bool ML_(read_elf_debug_info) ( struct _DebugInfo* di ) } if (0 == VG_(strcmp)(name, ".dynbss")) { - if (inrw && !di->bss_present) { + if (inrw1 && !di->bss_present) { dynbss_present = True; di->bss_present = True; di->bss_svma = svma; - di->bss_avma = svma + inrw->bias; + di->bss_avma = svma + inrw1->bias; di->bss_size = size; - di->bss_bias = inrw->bias; + di->bss_bias = inrw1->bias; di->bss_debug_svma = svma; - di->bss_debug_bias = inrw->bias; + di->bss_debug_bias = inrw1->bias; TRACE_SYMTAB("acquiring .dynbss svma = %#lx .. %#lx\n", di->bss_svma, di->bss_svma + di->bss_size - 1); @@ -2478,6 +2489,13 @@ Bool ML_(read_elf_debug_info) ( struct _DebugInfo* di ) /* Accept .bss where mapped as rw (data), even if zero-sized */ if (0 == VG_(strcmp)(name, ".bss")) { + + if (inrw2) { + inrw = inrw2; + } else { + inrw = inrw1; + } + if (inrw && dynbss_present) { vg_assert(di->bss_present); dynbss_present = False; @@ -2544,15 +2562,15 @@ Bool ML_(read_elf_debug_info) ( struct _DebugInfo* di ) } if (0 == VG_(strcmp)(name, ".sdynbss")) { - if (inrw && !di->sbss_present) { + if (inrw1 && !di->sbss_present) { sdynbss_present = True; di->sbss_present = True; di->sbss_svma = svma; - di->sbss_avma = svma + inrw->bias; + di->sbss_avma = svma + inrw1->bias; di->sbss_size = size; - di->sbss_bias = inrw->bias; + di->sbss_bias = inrw1->bias; di->sbss_debug_svma = svma; - di->sbss_debug_bias = inrw->bias; + di->sbss_debug_bias = inrw1->bias; TRACE_SYMTAB("acquiring .sdynbss svma = %#lx .. %#lx\n", di->sbss_svma, di->sbss_svma + di->sbss_size - 1); @@ -2566,7 +2584,7 @@ Bool ML_(read_elf_debug_info) ( struct _DebugInfo* di ) /* Accept .sbss where mapped as rw (data) */ if (0 == VG_(strcmp)(name, ".sbss")) { - if (inrw && sdynbss_present) { + if (inrw1 && sdynbss_present) { vg_assert(di->sbss_present); sdynbss_present = False; vg_assert(di->sbss_svma + di->sbss_size == svma); @@ -2574,18 +2592,18 @@ Bool ML_(read_elf_debug_info) ( struct _DebugInfo* di ) TRACE_SYMTAB("acquiring .sbss svma = %#lx .. %#lx\n", svma, svma + size - 1); TRACE_SYMTAB("acquiring .sbss avma = %#lx .. %#lx\n", - svma + inrw->bias, svma + inrw->bias + size - 1); + svma + inrw1->bias, svma + inrw1->bias + size - 1); TRACE_SYMTAB("acquiring .sbss bias = %#lx\n", (UWord)di->sbss_bias); } else - if (inrw && !di->sbss_present) { + if (inrw1 && !di->sbss_present) { di->sbss_present = True; di->sbss_svma = svma; - di->sbss_avma = svma + inrw->bias; + di->sbss_avma = svma + inrw1->bias; di->sbss_size = size; - di->sbss_bias = inrw->bias; + di->sbss_bias = inrw1->bias; di->sbss_debug_svma = svma; - di->sbss_debug_bias = inrw->bias; + di->sbss_debug_bias = inrw1->bias; TRACE_SYMTAB("acquiring .sbss svma = %#lx .. %#lx\n", di->sbss_svma, di->sbss_svma + di->sbss_size - 1); @@ -2600,9 +2618,9 @@ Bool ML_(read_elf_debug_info) ( struct _DebugInfo* di ) /* Accept .got where mapped as rw (data) */ if (0 == VG_(strcmp)(name, ".got")) { - if (inrw && !di->got_present) { + if (inrw1 && !di->got_present) { di->got_present = True; - di->got_avma = svma + inrw->bias; + di->got_avma = svma + inrw1->bias; di->got_size = size; TRACE_SYMTAB("acquiring .got avma = %#lx\n", di->got_avma); } else { @@ -2612,6 +2630,13 @@ Bool ML_(read_elf_debug_info) ( struct _DebugInfo* di ) /* Accept .got.plt where mapped as rw (data) */ if (0 == VG_(strcmp)(name, ".got.plt")) { + + if (inrw2) { + inrw = inrw2; + } else { + inrw = inrw1; + } + if (inrw && !di->gotplt_present) { di->gotplt_present = True; di->gotplt_avma = svma + inrw->bias; @@ -2643,9 +2668,9 @@ Bool ML_(read_elf_debug_info) ( struct _DebugInfo* di ) # elif defined(VGP_ppc32_linux) /* Accept .plt where mapped as rw (data) */ if (0 == VG_(strcmp)(name, ".plt")) { - if (inrw && !di->plt_present) { + if (inrw1 && !di->plt_present) { di->plt_present = True; - di->plt_avma = svma + inrw->bias; + di->plt_avma = svma + inrw1->bias; di->plt_size = size; TRACE_SYMTAB("acquiring .plt avma = %#lx\n", di->plt_avma); } else { @@ -2655,13 +2680,13 @@ Bool ML_(read_elf_debug_info) ( struct _DebugInfo* di ) # elif defined(VGP_ppc64be_linux) || defined(VGP_ppc64le_linux) /* Accept .plt where mapped as rw (data), or unmapped */ if (0 == VG_(strcmp)(name, ".plt")) { - if (inrw && !di->plt_present) { + if (inrw1 && !di->plt_present) { di->plt_present = True; - di->plt_avma = svma + inrw->bias; + di->plt_avma = svma + inrw1->bias; di->plt_size = size; TRACE_SYMTAB("acquiring .plt avma = %#lx\n", di->plt_avma); } else - if ((!inrw) && (!inrx) && size > 0 && !di->plt_present) { + if ((!inrw1) && (!inrx) && size > 0 && !di->plt_present) { /* File contains a .plt, but it didn't get mapped. Presumably it is not required on this platform. At least don't reject the situation as invalid. */ @@ -2678,9 +2703,9 @@ Bool ML_(read_elf_debug_info) ( struct _DebugInfo* di ) /* Accept .opd where mapped as rw (data) */ if (0 == VG_(strcmp)(name, ".opd")) { - if (inrw && !di->opd_present) { + if (inrw1 && !di->opd_present) { di->opd_present = True; - di->opd_avma = svma + inrw->bias; + di->opd_avma = svma + inrw1->bias; di->opd_size = size; TRACE_SYMTAB("acquiring .opd avma = %#lx\n", di->opd_avma); } else { @@ -2700,8 +2725,8 @@ Bool ML_(read_elf_debug_info) ( struct _DebugInfo* di ) di->ehframe_avma[di->n_ehframe]); di->n_ehframe++; } else - if (inrw && di->n_ehframe < N_EHFRAME_SECTS) { - di->ehframe_avma[di->n_ehframe] = svma + inrw->bias; + if (inrw1 && di->n_ehframe < N_EHFRAME_SECTS) { + di->ehframe_avma[di->n_ehframe] = svma + inrw1->bias; di->ehframe_size[di->n_ehframe] = size; TRACE_SYMTAB("acquiring .eh_frame avma = %#lx\n", di->ehframe_avma[di->n_ehframe]); @@ -3606,6 +3631,94 @@ Bool ML_(read_elf_debug_info) ( struct _DebugInfo* di ) /* NOTREACHED */ } +Bool ML_(check_elf_and_get_rw_loads) ( Int fd, const HChar* filename, Int * rw_load_count ) +{ + Bool res, ok; + UWord i; + DiImage* mimg = NULL; + DiOffT ehdr_mioff = 0; + DiOffT phdr_mioff = 0; + UWord phdr_mnent = 0U; + UWord phdr_ment_szB = 0U; + + res = False; + + mimg = ML_(img_from_fd)(fd, filename); + if (mimg == NULL) { + VG_(message)(Vg_UserMsg, "warning: connection to image %s failed\n", + filename ); + VG_(message)(Vg_UserMsg, " cannot read program headers \n" ); + return False; + } + + ok = is_elf_object_file_by_DiImage(mimg, False); + if (!ok) { + goto out; + } + + ElfXX_Ehdr ehdr_m; + Elf64_Word flag_x; +#if defined(VGA_amd64) || defined(VGA_ppc64be) || defined(VGA_ppc64le) || defined(VGA_arm) || defined(VGA_arm64) + flag_x = PF_X; +#else + flag_x = 0; +#endif + vg_assert(ehdr_mioff == 0); // ensured by its initialisation + ok = ML_(img_valid)(mimg, ehdr_mioff, sizeof(ehdr_m)); + vg_assert(ok); // ML_(is_elf_object_file) should ensure this + ML_(img_get)(&ehdr_m, mimg, ehdr_mioff, sizeof(ehdr_m)); + + phdr_mioff = ehdr_mioff + ehdr_m.e_phoff; + phdr_mnent = ehdr_m.e_phnum; + phdr_ment_szB = ehdr_m.e_phentsize; + + for (i = 0U; i < phdr_mnent; i++) { + ElfXX_Phdr a_phdr; + ML_(img_get)(&a_phdr, mimg, + INDEX_BIS(phdr_mioff, i, phdr_ment_szB), + sizeof(a_phdr)); + + if (a_phdr.p_type == PT_LOAD) { + if (a_phdr.p_memsz > 0) { + if (((a_phdr.p_flags & (PF_R | PF_W)) == (PF_R | PF_W)) && + ((a_phdr.p_flags & flag_x) == 0)) { + ++*rw_load_count; + } + + /* + * Hold your horses + * Just because The ELF file contains 2 RW PT_LOAD segments it + * doesn't mean that Valgrind will also make 2 calls to + * VG_(di_notify_mmap). If the stars are all aligned + * (which usually means that the ELF file is the client + * executable with the segment offset for the + * second PT_LOAD falls exactly on 0x1000) then the NSegements + * will get merged and VG_(di_notify_mmap) only gets called once. */ + if (*rw_load_count == 2 && + ehdr_m.e_type == ET_EXEC && + a_phdr.p_offset == VG_PGROUNDDN(a_phdr.p_offset) ) + { + *rw_load_count = 1; + } + } + } + } /* for (i = 0; i < phdr_Mnent; i++) ... */ + + res = True; + + out: + { + /* Last, but not least, detach from the image(s). */ + if (mimg) ML_(img_free)(mimg); + + return res; + } /* out: */ + + /* NOTREACHED */ +} + + + #endif // defined(VGO_linux) || defined(VGO_solaris) || defined(VGO_freebsd) /*--------------------------------------------------------------------*/ diff --git a/coregrind/m_debuginfo/readpdb.c b/coregrind/m_debuginfo/readpdb.c index a53cf48c44..f3a3817d89 100644 --- a/coregrind/m_debuginfo/readpdb.c +++ b/coregrind/m_debuginfo/readpdb.c @@ -2363,7 +2363,7 @@ Bool ML_(read_pdb_debug_info)( map.rx = False; map.rw = True; VG_(addToXA)(di->fsm.maps, &map); - di->fsm.have_rw_map = True; + di->fsm.rw_map_count = 1; di->data_present = True; if (di->data_avma == 0) { @@ -2385,7 +2385,7 @@ Bool ML_(read_pdb_debug_info)( } } - if (di->fsm.have_rx_map && di->fsm.have_rw_map && !di->have_dinfo) { + if (di->fsm.have_rx_map && di->fsm.rw_map_count && !di->have_dinfo) { vg_assert(di->fsm.filename); TRACE_SYMTAB("\n"); TRACE_SYMTAB("------ start PE OBJECT with PDB INFO " diff --git a/coregrind/m_debuginfo/storage.c b/coregrind/m_debuginfo/storage.c index 9ba74076c1..6eb932747f 100644 --- a/coregrind/m_debuginfo/storage.c +++ b/coregrind/m_debuginfo/storage.c @@ -616,7 +616,7 @@ void ML_(addLineInfo) ( struct _DebugInfo* di, /* Rule out ones which are completely outside the r-x mapped area. See "Comment_Regarding_Text_Range_Checks" elsewhere in this file for background and rationale. */ - vg_assert(di->fsm.have_rx_map && di->fsm.have_rw_map); + vg_assert(di->fsm.have_rx_map && di->fsm.rw_map_count); if (ML_(find_rx_mapping)(di, this, this + size - 1) == NULL) { if (0) VG_(message)(Vg_DebugMsg, @@ -798,7 +798,7 @@ void ML_(addDiCfSI) ( struct _DebugInfo* di, "warning: DiCfSI %#lx .. %#lx is huge; length = %u (%s)\n", base, base + len - 1, len, di->soname); - vg_assert(di->fsm.have_rx_map && di->fsm.have_rw_map); + vg_assert(di->fsm.have_rx_map && di->fsm.rw_map_count); /* Find mapping where at least one end of the CFSI falls into. */ map = ML_(find_rx_mapping)(di, base, base); map2 = ML_(find_rx_mapping)(di, base + len - 1, @@ -1304,7 +1304,7 @@ void ML_(addVar)( struct _DebugInfo* di, /* This is assured us by top level steering logic in debuginfo.c, and it is re-checked at the start of ML_(read_elf_debug_info). */ - vg_assert(di->fsm.have_rx_map && di->fsm.have_rw_map); + vg_assert(di->fsm.have_rx_map && di->fsm.rw_map_count); if (level > 0 && ML_(find_rx_mapping)(di, aMin, aMax) == NULL) { if (VG_(clo_verbosity) > 1) { VG_(message)(Vg_DebugMsg, diff --git a/memcheck/tests/Makefile.am b/memcheck/tests/Makefile.am index 474ef5c4c9..c8fa5b5cbf 100644 --- a/memcheck/tests/Makefile.am +++ b/memcheck/tests/Makefile.am @@ -342,6 +342,7 @@ EXTRA_DIST = \ varinfo4.stderr.exp-freebsd \ varinfo5.vgtest varinfo5.stdout.exp varinfo5.stderr.exp \ varinfo5.stderr.exp-ppc64 \ + varinfo5.stderr.exp-freebsd \ varinfo6.vgtest varinfo6.stdout.exp varinfo6.stderr.exp \ varinfo6.stderr.exp-ppc64 \ varinforestrict.vgtest varinforestrict.stderr.exp \ diff --git a/memcheck/tests/varinfo5.stderr.exp-freebsd b/memcheck/tests/varinfo5.stderr.exp-freebsd new file mode 100644 index 0000000000..df30c00d40 --- /dev/null +++ b/memcheck/tests/varinfo5.stderr.exp-freebsd @@ -0,0 +1,191 @@ +Uninitialised byte(s) found during client check request + at 0x........: croak (tests/varinfo5so.c:29) + by 0x........: varinfo1_main (tests/varinfo5so.c:52) + by 0x........: varinfo5_main (tests/varinfo5so.c:154) + by 0x........: main (tests/varinfo5.c:5) + Address 0x........ is 1 bytes inside a block of size 3 alloc'd + at 0x........: malloc (vg_replace_malloc.c:...) + by 0x........: varinfo1_main (tests/varinfo5so.c:50) + by 0x........: varinfo5_main (tests/varinfo5so.c:154) + by 0x........: main (tests/varinfo5.c:5) + +Uninitialised byte(s) found during client check request + at 0x........: croak (tests/varinfo5so.c:29) + by 0x........: varinfo1_main (tests/varinfo5so.c:55) + by 0x........: varinfo5_main (tests/varinfo5so.c:154) + by 0x........: main (tests/varinfo5.c:5) + Location 0x........ is 0 bytes inside global var "global_u1" + declared at varinfo5so.c:38 + +Uninitialised byte(s) found during client check request + at 0x........: croak (tests/varinfo5so.c:29) + by 0x........: varinfo1_main (tests/varinfo5so.c:56) + by 0x........: varinfo5_main (tests/varinfo5so.c:154) + by 0x........: main (tests/varinfo5.c:5) + Location 0x........ is 0 bytes inside global var "global_i1" + declared at varinfo5so.c:40 + +Uninitialised byte(s) found during client check request + at 0x........: croak (tests/varinfo5so.c:29) + by 0x........: varinfo1_main (tests/varinfo5so.c:57) + by 0x........: varinfo5_main (tests/varinfo5so.c:154) + by 0x........: main (tests/varinfo5.c:5) + Location 0x........ is 0 bytes inside global_u2[3], + a global variable declared at varinfo5so.c:42 + +Uninitialised byte(s) found during client check request + at 0x........: croak (tests/varinfo5so.c:29) + by 0x........: varinfo1_main (tests/varinfo5so.c:58) + by 0x........: varinfo5_main (tests/varinfo5so.c:154) + by 0x........: main (tests/varinfo5.c:5) + Location 0x........ is 0 bytes inside global_i2[7], + a global variable declared at varinfo5so.c:44 + +Uninitialised byte(s) found during client check request + at 0x........: croak (tests/varinfo5so.c:29) + by 0x........: varinfo1_main (tests/varinfo5so.c:59) + by 0x........: varinfo5_main (tests/varinfo5so.c:154) + by 0x........: main (tests/varinfo5.c:5) + Location 0x........ is 0 bytes inside local var "local" + declared at varinfo5so.c:49, in frame #X of thread 1 + +Uninitialised byte(s) found during client check request + at 0x........: croak (tests/varinfo5so.c:29) + by 0x........: foo2 (tests/varinfo5so.c:71) + by 0x........: varinfo2_main (tests/varinfo5so.c:81) + by 0x........: varinfo5_main (tests/varinfo5so.c:155) + by 0x........: main (tests/varinfo5.c:5) + Location 0x........ is 0 bytes inside var[7], + declared at varinfo5so.c:69, in frame #X of thread 1 + +Uninitialised byte(s) found during client check request + at 0x........: croak (tests/varinfo5so.c:29) + by 0x........: foo2 (tests/varinfo5so.c:73) + by 0x........: varinfo2_main (tests/varinfo5so.c:81) + by 0x........: varinfo5_main (tests/varinfo5so.c:155) + by 0x........: main (tests/varinfo5.c:5) + Location 0x........ is 2 bytes inside var.bar, + declared at varinfo5so.c:72, in frame #X of thread 1 + +Uninitialised byte(s) found during client check request + at 0x........: croak (tests/varinfo5so.c:29) + by 0x........: foo2 (tests/varinfo5so.c:76) + by 0x........: varinfo2_main (tests/varinfo5so.c:81) + by 0x........: varinfo5_main (tests/varinfo5so.c:155) + by 0x........: main (tests/varinfo5.c:5) + Address 0x........ is on thread 1's stack + in frame #X, created by foo2 (varinfo5so.c:66) + +Uninitialised byte(s) found during client check request + at 0x........: croak (tests/varinfo5so.c:29) + by 0x........: foo3 (tests/varinfo5so.c:106) + by 0x........: varinfo3_main (tests/varinfo5so.c:118) + by 0x........: varinfo5_main (tests/varinfo5so.c:156) + by 0x........: main (tests/varinfo5.c:5) + Location 0x........ is 0 bytes inside static_global_def[1], + a global variable declared at varinfo5so.c:87 + +Uninitialised byte(s) found during client check request + at 0x........: croak (tests/varinfo5so.c:29) + by 0x........: foo3 (tests/varinfo5so.c:107) + by 0x........: varinfo3_main (tests/varinfo5so.c:118) + by 0x........: varinfo5_main (tests/varinfo5so.c:156) + by 0x........: main (tests/varinfo5.c:5) + Location 0x........ is 0 bytes inside nonstatic_global_def[2], + a global variable declared at varinfo5so.c:88 + +Uninitialised byte(s) found during client check request + at 0x........: croak (tests/varinfo5so.c:29) + by 0x........: foo3 (tests/varinfo5so.c:108) + by 0x........: varinfo3_main (tests/varinfo5so.c:118) + by 0x........: varinfo5_main (tests/varinfo5so.c:156) + by 0x........: main (tests/varinfo5.c:5) + Location 0x........ is 0 bytes inside static_global_undef[3], + a global variable declared at varinfo5so.c:89 + +Uninitialised byte(s) found during client check request + at 0x........: croak (tests/varinfo5so.c:29) + by 0x........: foo3 (tests/varinfo5so.c:109) + by 0x........: varinfo3_main (tests/varinfo5so.c:118) + by 0x........: varinfo5_main (tests/varinfo5so.c:156) + by 0x........: main (tests/varinfo5.c:5) + Location 0x........ is 0 bytes inside nonstatic_global_undef[4], + a global variable declared at varinfo5so.c:90 + +Uninitialised byte(s) found during client check request + at 0x........: croak (tests/varinfo5so.c:29) + by 0x........: bar3 (tests/varinfo5so.c:94) + by 0x........: foo3 (tests/varinfo5so.c:110) + by 0x........: varinfo3_main (tests/varinfo5so.c:118) + by 0x........: varinfo5_main (tests/varinfo5so.c:156) + by 0x........: main (tests/varinfo5.c:5) + Address 0x........ is 5 bytes inside data symbol "foo3.static_local_def" + +Uninitialised byte(s) found during client check request + at 0x........: croak (tests/varinfo5so.c:29) + by 0x........: bar3 (tests/varinfo5so.c:95) + by 0x........: foo3 (tests/varinfo5so.c:110) + by 0x........: varinfo3_main (tests/varinfo5so.c:118) + by 0x........: varinfo5_main (tests/varinfo5so.c:156) + by 0x........: main (tests/varinfo5.c:5) + Address 0x........ is on thread 1's stack + in frame #X, created by foo3 (varinfo5so.c:101) + +Uninitialised byte(s) found during client check request + at 0x........: croak (tests/varinfo5so.c:29) + by 0x........: bar3 (tests/varinfo5so.c:96) + by 0x........: foo3 (tests/varinfo5so.c:110) + by 0x........: varinfo3_main (tests/varinfo5so.c:118) + by 0x........: varinfo5_main (tests/varinfo5so.c:156) + by 0x........: main (tests/varinfo5.c:5) + Address 0x........ is 7 bytes inside data symbol "foo3.static_local_undef" + +Uninitialised byte(s) found during client check request + at 0x........: croak (tests/varinfo5so.c:29) + by 0x........: bar3 (tests/varinfo5so.c:97) + by 0x........: foo3 (tests/varinfo5so.c:110) + by 0x........: varinfo3_main (tests/varinfo5so.c:118) + by 0x........: varinfo5_main (tests/varinfo5so.c:156) + by 0x........: main (tests/varinfo5.c:5) + Address 0x........ is on thread 1's stack + in frame #X, created by foo3 (varinfo5so.c:101) + +Uninitialised byte(s) found during client check request + at 0x........: croak (tests/varinfo5so.c:29) + by 0x........: blah4 (tests/varinfo5so.c:137) + by 0x........: varinfo4_main (tests/varinfo5so.c:146) + by 0x........: varinfo5_main (tests/varinfo5so.c:157) + by 0x........: main (tests/varinfo5.c:5) + Location 0x........ is 1 byte inside a[3].xyzzy[21].c1, + declared at varinfo5so.c:135, in frame #X of thread 1 + +Uninitialised byte(s) found during client check request + at 0x........: croak (tests/varinfo5so.c:29) + by 0x........: blah4 (tests/varinfo5so.c:138) + by 0x........: varinfo4_main (tests/varinfo5so.c:146) + by 0x........: varinfo5_main (tests/varinfo5so.c:157) + by 0x........: main (tests/varinfo5.c:5) + Location 0x........ is 0 bytes inside a[5].bong, + declared at varinfo5so.c:135, in frame #X of thread 1 + +Uninitialised byte(s) found during client check request + at 0x........: croak (tests/varinfo5so.c:29) + by 0x........: blah4 (tests/varinfo5so.c:139) + by 0x........: varinfo4_main (tests/varinfo5so.c:146) + by 0x........: varinfo5_main (tests/varinfo5so.c:157) + by 0x........: main (tests/varinfo5.c:5) + Location 0x........ is 1 byte inside a[3].xyzzy[21].c2[2], + declared at varinfo5so.c:135, in frame #X of thread 1 + +answer is 0 +Uninitialised byte(s) found during client check request + at 0x........: croak (tests/varinfo5so.c:29) + by 0x........: fun_c (tests/varinfo5so.c:164) + by 0x........: fun_b (./varinfo5so.c:168) + by 0x........: fun_a (./varinfo5so.c:172) + by 0x........: inlinetest (./varinfo5so.c:178) + by 0x........: varinfo5_main (tests/varinfo5so.c:158) + by 0x........: main (tests/varinfo5.c:5) + Address 0x........ is on thread 1's stack + in frame #X, created by inlinetest (varinfo5so.c:176) + |
|
From: Paul F. <pa...@so...> - 2022-06-08 21:18:21
|
https://sourceware.org/git/gitweb.cgi?p=valgrind.git;h=67b8fef50bfaed0ce5a1d8130836bcef0eafcd4b commit 67b8fef50bfaed0ce5a1d8130836bcef0eafcd4b Author: Paul Floyd <pj...@wa...> Date: Wed Jun 8 23:17:09 2022 +0200 Regtest memcheck/tests/amd64/shr_edx does not build on macOS Make it conditional Diff: --- memcheck/tests/amd64/Makefile.am | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/memcheck/tests/amd64/Makefile.am b/memcheck/tests/amd64/Makefile.am index 8b8785613c..a5a78aa310 100644 --- a/memcheck/tests/amd64/Makefile.am +++ b/memcheck/tests/amd64/Makefile.am @@ -46,8 +46,8 @@ check_PROGRAMS = \ insn-pmovmskb \ sh-mem-vec128 \ sse_memory \ - xor-undef-amd64 \ - shr_edx + xor-undef-amd64 + if BUILD_AVX_TESTS check_PROGRAMS += sh-mem-vec256 xsave-avx endif @@ -60,6 +60,13 @@ if !COMPILER_IS_CLANG more_x87_fp endif +# initially this was a "not clang" test +# but the problem is macOS, not clang +if !VGCONF_OS_IS_DARWIN + check_PROGRAMS += \ + shr_edx +endif + AM_CFLAGS += @FLAG_M64@ AM_CXXFLAGS += @FLAG_M64@ AM_CCASFLAGS += @FLAG_M64@ |