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
|
| S | M | T | W | T | F | S |
|---|---|---|---|---|---|---|
|
|
|
|
|
|
1
(4) |
2
(2) |
|
3
|
4
(3) |
5
(3) |
6
(5) |
7
(7) |
8
(1) |
9
(7) |
|
10
(7) |
11
(1) |
12
(13) |
13
(4) |
14
|
15
(5) |
16
|
|
17
(1) |
18
(2) |
19
(3) |
20
|
21
|
22
|
23
(1) |
|
24
|
25
|
26
|
27
(1) |
28
(3) |
29
|
30
|
|
31
|
|
|
|
|
|
|
|
From: Paul F. <pa...@so...> - 2021-10-09 21:04:00
|
https://sourceware.org/git/gitweb.cgi?p=valgrind.git;h=1c57706fbdc7f4ebd866aeade0900f437942f44c commit 1c57706fbdc7f4ebd866aeade0900f437942f44c Author: Paul Floyd <pj...@wa...> Date: Sat Oct 9 23:02:28 2021 +0200 Bug 443314 - In the latest GIT version, Valgrind with "--trace-flags" crashes at "al" register Diff: --- NEWS | 2 ++ VEX/priv/guest_amd64_toIR.c | 5 +++-- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/NEWS b/NEWS index d2455d4472..d8addbb203 100644 --- a/NEWS +++ b/NEWS @@ -84,6 +84,8 @@ are not entered into bugzilla tend to get forgotten about or ignored. 443179 Need new test for the lxvx and stxvx instructions on ISA 2.07 and ISA 3.0 systems. 443180 The subnormal test and the ISA 3.0 test generate compiler warnings. +443314 In the latest GIT version, Valgrind with "--trace-flags" crashes at + "al" register To see details of a given bug, visit https://bugs.kde.org/show_bug.cgi?id=XXXXXX diff --git a/VEX/priv/guest_amd64_toIR.c b/VEX/priv/guest_amd64_toIR.c index c7f94b15b5..86fe07fdc5 100644 --- a/VEX/priv/guest_amd64_toIR.c +++ b/VEX/priv/guest_amd64_toIR.c @@ -1188,8 +1188,9 @@ static const HChar* nameIRegRexB ( Int sz, Prefix pfx, UInt lo3bits ) vassert(lo3bits < 8); vassert(IS_VALID_PFX(pfx)); vassert(sz == 8 || sz == 4 || sz == 2 || sz == 1); - return nameIReg( sz, lo3bits | (getRexB(pfx) << 3), - toBool(sz==1 && !haveREX(pfx)) ); + UInt regNo = lo3bits | (getRexB(pfx) << 3); + return nameIReg( sz, regNo, + toBool(sz==1 && !haveREX(pfx) && regNo >= 4 && regNo < 8)); } static IRExpr* getIRegRexB ( Int sz, Prefix pfx, UInt lo3bits ) |
|
From: Paul F. <pa...@so...> - 2021-10-09 19:46:10
|
https://sourceware.org/git/gitweb.cgi?p=valgrind.git;h=c3002642d35b69f82fb1633ffc874e8ede370d32 commit c3002642d35b69f82fb1633ffc874e8ede370d32 Author: Paul Floyd <pj...@wa...> Date: Sat Oct 9 21:25:22 2021 +0200 Bug 439326 - Valgrind 3.17.0 won't compile with Intel 2021 oneAPI compilers Also reorder NEWS Diff: --- NEWS | 25 +++++++++++++------------ configure.ac | 2 +- 2 files changed, 14 insertions(+), 13 deletions(-) diff --git a/NEWS b/NEWS index e5414c02b4..d2455d4472 100644 --- a/NEWS +++ b/NEWS @@ -47,19 +47,7 @@ are not entered into bugzilla tend to get forgotten about or ignored. 429375 PPC ISA 3.1 support is missing, part 9 431157 PPC_FEATURE2_SCV needs to be masked in AT_HWCAP2 431306 Update demangler to support Rust v0 name mangling -433801 PPC ISA 3.1 support is missing, part 10 (ISA 3.1 support complete) -433863 s390x: memcheck/tests/s390x/{cds,cs,csg} failures -434840 PPC64 darn instruction not supported -434296 s390x: False-positive memcheck diagnostics from vector string - instructions -435665 PPC ISA 3.0 copy, paste, cpabort instructions are not supported -438871 unhandled instruction bytes: 0xF3 0x49 0xF 0x6F 0x9C 0x24 0x60 0x2 0x0 0x0 -435908 valgrind tries to fetch from deubginfod for files which already - have debug information -439590 glibc-2.34 breaks suppressions against obj:*/lib*/libc-2.*so* -440670 unhandled ppc64le-linux syscall: 252 (statfs64) and 253 (fstatfs64) 432387 s390x: z15 instructions support -439046 valgrind is unusably large when linked with lld 433437 FreeBSD support, part 1 433438 FreeBSD support, part 2 433439 FreeBSD support, part 3 @@ -72,6 +60,19 @@ are not entered into bugzilla tend to get forgotten about or ignored. 433507 FreeBSD support, part 10 433508 FreeBSD support, part 11 433510 FreeBSD support, part 12 +433801 PPC ISA 3.1 support is missing, part 10 (ISA 3.1 support complete) +433863 s390x: memcheck/tests/s390x/{cds,cs,csg} failures +434296 s390x: False-positive memcheck diagnostics from vector string + instructions +434840 PPC64 darn instruction not supported +435665 PPC ISA 3.0 copy, paste, cpabort instructions are not supported +435908 valgrind tries to fetch from deubginfod for files which already + have debug information +438871 unhandled instruction bytes: 0xF3 0x49 0xF 0x6F 0x9C 0x24 0x60 0x2 0x0 0x0 +439046 valgrind is unusably large when linked with lld +439326 Valgrind 3.17.0 won't compile with Intel 2021 oneAPI compilers +439590 glibc-2.34 breaks suppressions against obj:*/lib*/libc-2.*so* +440670 unhandled ppc64le-linux syscall: 252 (statfs64) and 253 (fstatfs64) 440906 Fix impossible constraint issue in P10 testcase. 441512 Remove a unneeded / unnecessary prefix check. 441534 Update the expected output for test_isa_3_1_VRT. diff --git a/configure.ac b/configure.ac index 275c0ca02c..3f51bc5c62 100755 --- a/configure.ac +++ b/configure.ac @@ -175,7 +175,7 @@ case "${is_clang}-${gcc_version}" in applellvm-5.1|applellvm-[[6-9]].*|applellvm-[[1-9][0-9]]*) AC_MSG_RESULT([ok (Apple LLVM version ${gcc_version})]) ;; - icc-1[[3-9]].*) + icc-1[[3-9]].*|icc-202[[0-9]].*) AC_MSG_RESULT([ok (ICC version ${gcc_version})]) ;; notclang-[[3-9]]|notclang-[[3-9]].*|notclang-[[1-9][0-9]]*) |
|
From: Paul F. <pa...@so...> - 2021-10-09 13:15:00
|
https://sourceware.org/git/gitweb.cgi?p=valgrind.git;h=80459895c4a89c4057cbfccba5c820f64e9dbe23 commit 80459895c4a89c4057cbfccba5c820f64e9dbe23 Author: Paul Floyd <pj...@wa...> Date: Sat Oct 9 15:13:50 2021 +0200 FreeBSD support, last loose ends One merge I missed and make a couple of changes to remove compiler warnings. Diff: --- coregrind/Makefile.am | 1 + coregrind/m_coredump/coredump-elf.c | 2 +- coregrind/m_mallocfree.c | 12 ++++++++++++ 3 files changed, 14 insertions(+), 1 deletion(-) diff --git a/coregrind/Makefile.am b/coregrind/Makefile.am index 1de685bb45..76c0aebc9d 100644 --- a/coregrind/Makefile.am +++ b/coregrind/Makefile.am @@ -51,6 +51,7 @@ valgrind_SOURCES = \ endif if VGCONF_OS_IS_FREEBSD valgrind_SOURCES = \ + launcher-freebsd.c \ m_debuglog.c endif diff --git a/coregrind/m_coredump/coredump-elf.c b/coregrind/m_coredump/coredump-elf.c index d0e8a03c94..0d22d01cbb 100644 --- a/coregrind/m_coredump/coredump-elf.c +++ b/coregrind/m_coredump/coredump-elf.c @@ -490,7 +490,7 @@ static void fill_prstatus(const ThreadState *tst, regs[VKI_MIPS32_EF_CP0_EPC] = arch->vex.guest_PC; # undef DO #elif defined(VGP_amd64_freebsd) - regs->rflags = LibVEX_GuestAMD64_get_rflags( &((ThreadArchState*)arch)->vex ); + regs->rflags = LibVEX_GuestAMD64_get_rflags( &arch->vex ); regs->rsp = arch->vex.guest_RSP; regs->rip = arch->vex.guest_RIP; regs->rbx = arch->vex.guest_RBX; diff --git a/coregrind/m_mallocfree.c b/coregrind/m_mallocfree.c index 4bc24f91e5..90c7d9aac9 100644 --- a/coregrind/m_mallocfree.c +++ b/coregrind/m_mallocfree.c @@ -1011,6 +1011,14 @@ Superblock* maybe_findSb ( Arena* a, Addr ad ) /*--- Functions for working with freelists. ---*/ /*------------------------------------------------------------*/ +#if defined(__clang__) +/* The nicely aligned 'returns' in the function below produce + * misleading indentation warnings. Rather than turn the + * warning off globally, just turn it off for the block of code. */ +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wmisleading-indentation" +#endif + // Nb: Determination of which freelist a block lives on is based on the // payload size, not block size. @@ -1120,6 +1128,10 @@ UInt pszB_to_listNo_SLOW ( SizeT pszB__divided_by__VG_MIN_MALLOC_SZB ) vg_assert(0); } +#if defined(__clang__) +#pragma clang diagnostic pop +#endif + static inline UInt pszB_to_listNo ( SizeT pszB ) { |
|
From: Paul F. <pa...@so...> - 2021-10-09 13:02:01
|
https://sourceware.org/git/gitweb.cgi?p=valgrind.git;h=68bb7c063f71631a4f207adca2235eb0f8d00d33 commit 68bb7c063f71631a4f207adca2235eb0f8d00d33 Author: Paul Floyd <pj...@wa...> Date: Sat Oct 9 15:01:08 2021 +0200 FreeBSD support, patch 12 coregrind modified files Diff: --- NEWS | 20 +- coregrind/m_aspacemgr/aspacemgr-common.c | 76 +++++- coregrind/m_aspacemgr/aspacemgr-linux.c | 195 ++++++++++++- coregrind/m_aspacemgr/priv_aspacemgr.h | 2 +- coregrind/m_coredump/coredump-elf.c | 79 +++++- coregrind/m_debuginfo/d3basics.c | 4 +- coregrind/m_debuginfo/debuginfo.c | 19 +- coregrind/m_debuginfo/priv_readpdb.h | 4 +- coregrind/m_debuginfo/readdwarf.c | 8 +- coregrind/m_debuginfo/readdwarf3.c | 4 +- coregrind/m_debuginfo/readelf.c | 116 +++++++- coregrind/m_debuginfo/readpdb.c | 4 +- coregrind/m_debuginfo/storage.c | 7 +- coregrind/m_debuglog.c | 83 ++++++ coregrind/m_gdbserver/gdb/signals.h | 3 + coregrind/m_gdbserver/remote-utils.c | 37 ++- coregrind/m_gdbserver/signals.c | 8 + coregrind/m_libcassert.c | 6 +- coregrind/m_libcfile.c | 141 ++++++++-- coregrind/m_libcprint.c | 2 +- coregrind/m_libcproc.c | 108 +++++++- coregrind/m_libcsetjmp.c | 22 +- coregrind/m_libcsignal.c | 39 ++- coregrind/m_machine.c | 17 +- coregrind/m_main.c | 148 +++++++++- coregrind/m_redir.c | 5 + coregrind/m_replacemalloc/vg_replace_malloc.c | 379 +++++++++++++++++++++++--- coregrind/m_scheduler/scheduler.c | 5 +- coregrind/m_scheduler/sema.c | 4 +- coregrind/m_sigframe/sigframe-common.c | 2 +- coregrind/m_signals.c | 99 ++++++- coregrind/m_stacktrace.c | 35 ++- coregrind/m_syscall.c | 130 +++++++++ coregrind/m_syswrap/priv_types_n_macros.h | 84 +++++- coregrind/m_syswrap/syswrap-generic.c | 73 ++++- coregrind/m_syswrap/syswrap-main.c | 357 +++++++++++++++++++++++- coregrind/m_trampoline.S | 68 +++++ coregrind/m_translate.c | 4 +- coregrind/m_ume/elf.c | 14 +- coregrind/m_ume/main.c | 2 +- coregrind/m_ume/priv_ume.h | 4 +- coregrind/m_vki.c | 4 +- coregrind/m_vkiscnums.c | 11 + coregrind/pub_core_aspacemgr.h | 4 + coregrind/pub_core_debuginfo.h | 2 +- coregrind/pub_core_gdbserver.h | 1 + coregrind/pub_core_initimg.h | 2 +- coregrind/pub_core_libcproc.h | 7 + coregrind/pub_core_machine.h | 4 +- coregrind/pub_core_mallocfree.h | 2 + coregrind/pub_core_sigframe.h | 6 +- coregrind/pub_core_syscall.h | 2 + coregrind/pub_core_syswrap.h | 4 + coregrind/pub_core_trampoline.h | 8 + coregrind/vg_preloaded.c | 6 +- coregrind/vgdb.c | 2 + include/pub_tool_libcproc.h | 2 +- 57 files changed, 2270 insertions(+), 214 deletions(-) diff --git a/NEWS b/NEWS index 68315a77ad..e5414c02b4 100644 --- a/NEWS +++ b/NEWS @@ -4,8 +4,9 @@ Release 3.??.? (?? 2021) This release supports X86/Linux, AMD64/Linux, ARM32/Linux, ARM64/Linux, PPC32/Linux, PPC64BE/Linux, PPC64LE/Linux, S390X/Linux, MIPS32/Linux, MIPS64/Linux, ARM/Android, ARM64/Android, MIPS32/Android, X86/Android, -X86/Solaris, AMD64/Solaris and AMD64/MacOSX 10.12. There is also preliminary -support for X86/macOS 10.13, AMD64/macOS 10.13 and nanoMIPS/Linux. +X86/Solaris, AMD64/Solaris, AMD64/MacOSX 10.12, X86/FreeBSD and +AMD64/FreeBSD. There is also preliminary support for X86/macOS 10.13, +AMD64/macOS 10.13 and nanoMIPS/Linux. * ==================== CORE CHANGES =================== @@ -25,6 +26,8 @@ support for X86/macOS 10.13, AMD64/macOS 10.13 and nanoMIPS/Linux. - ISA 3.0 support for the darn instruction added. - ISA 3.0 support for the vector system call instruction scv added. - ISA 3.0 support for the copy, paste and cpabort instructions added. + +* Support for X86/FreeBSD and AMD64/FreeBSD has been added. * ==================== TOOL CHANGES ==================== @@ -56,6 +59,19 @@ are not entered into bugzilla tend to get forgotten about or ignored. 439590 glibc-2.34 breaks suppressions against obj:*/lib*/libc-2.*so* 440670 unhandled ppc64le-linux syscall: 252 (statfs64) and 253 (fstatfs64) 432387 s390x: z15 instructions support +439046 valgrind is unusably large when linked with lld +433437 FreeBSD support, part 1 +433438 FreeBSD support, part 2 +433439 FreeBSD support, part 3 +433469 FreeBSD support, part 4 +433473 FreeBSD support, part 5 +433477 FreeBSD support, part 6 +433479 FreeBSD support, part 7 +433504 FreeBSD support, part 8 +433506 FreeBSD support, part 9 +433507 FreeBSD support, part 10 +433508 FreeBSD support, part 11 +433510 FreeBSD support, part 12 440906 Fix impossible constraint issue in P10 testcase. 441512 Remove a unneeded / unnecessary prefix check. 441534 Update the expected output for test_isa_3_1_VRT. diff --git a/coregrind/m_aspacemgr/aspacemgr-common.c b/coregrind/m_aspacemgr/aspacemgr-common.c index 214b54a35e..6814410c09 100644 --- a/coregrind/m_aspacemgr/aspacemgr-common.c +++ b/coregrind/m_aspacemgr/aspacemgr-common.c @@ -35,6 +35,7 @@ ************************************************************* */ #include "priv_aspacemgr.h" +#include "pub_core_libcassert.h" #include "config.h" @@ -171,6 +172,16 @@ SysRes VG_(am_do_mmap_NO_NOTIFY)( Addr start, SizeT length, UInt prot, } res = VG_(do_syscall6)(__NR_mmap, (UWord)start, length, prot, flags, (UInt)fd, offset); +# elif defined(VGP_x86_freebsd) + if (flags & VKI_MAP_ANONYMOUS && fd == 0) + fd = -1; + res = VG_(do_syscall7)(__NR_mmap, (UWord)start, length, + prot, flags, fd, offset, offset >> 32ul); +# elif defined(VGP_amd64_freebsd) + if ((flags & VKI_MAP_ANONYMOUS) && fd == 0) + fd = -1; + res = VG_(do_syscall6)(__NR_mmap, (UWord)start, length, + prot, flags, fd, offset); # elif defined(VGP_x86_solaris) /* MAP_ANON with fd==0 is EINVAL. */ if (fd == 0 && (flags & VKI_MAP_ANONYMOUS)) @@ -255,7 +266,7 @@ SysRes ML_(am_open) ( const HChar* pathname, Int flags, Int mode ) /* ARM64 wants to use __NR_openat rather than __NR_open. */ SysRes res = VG_(do_syscall4)(__NR_openat, VKI_AT_FDCWD, (UWord)pathname, flags, mode); -# elif defined(VGO_linux) || defined(VGO_darwin) +# elif defined(VGO_linux) || defined(VGO_darwin) || defined(VGO_freebsd) SysRes res = VG_(do_syscall3)(__NR_open, (UWord)pathname, flags, mode); # elif defined(VGO_solaris) SysRes res = VG_(do_syscall4)(__NR_openat, VKI_AT_FDCWD, (UWord)pathname, @@ -283,7 +294,7 @@ Int ML_(am_readlink)(const HChar* path, HChar* buf, UInt bufsiz) # if defined(VGP_arm64_linux) || defined(VGP_nanomips_linux) res = VG_(do_syscall4)(__NR_readlinkat, VKI_AT_FDCWD, (UWord)path, (UWord)buf, bufsiz); -# elif defined(VGO_linux) || defined(VGO_darwin) +# elif defined(VGO_linux) || defined(VGO_darwin) || defined(VGO_freebsd) res = VG_(do_syscall3)(__NR_readlink, (UWord)path, (UWord)buf, bufsiz); # elif defined(VGO_solaris) res = VG_(do_syscall4)(__NR_readlinkat, VKI_AT_FDCWD, (UWord)path, @@ -296,7 +307,7 @@ Int ML_(am_readlink)(const HChar* path, HChar* buf, UInt bufsiz) Int ML_(am_fcntl) ( Int fd, Int cmd, Addr arg ) { -# if defined(VGO_linux) || defined(VGO_solaris) +# if defined(VGO_linux) || defined(VGO_solaris) || defined(VGO_freebsd) # if defined(VGP_nanomips_linux) SysRes res = VG_(do_syscall3)(__NR_fcntl64, fd, cmd, arg); # else @@ -330,7 +341,8 @@ Bool ML_(am_get_fd_d_i_m)( Int fd, *mode = (UInt)bufx.stx_mode; return True; } -# endif +# endif // VGO_linux only + # if defined(VGO_linux) && defined(__NR_fstat64) /* fstat64 is second candidate as it can cope with minor and major device numbers outside the 0-255 range and it works properly for x86 @@ -343,7 +355,8 @@ Bool ML_(am_get_fd_d_i_m)( Int fd, *mode = (UInt) buf64.st_mode; return True; } -# endif +# endif // VGO_linux and defined __NR_fstat64 + # if defined(__NR_fstat) struct vki_stat buf; res = VG_(do_syscall2)(__NR_fstat, fd, (UWord)&buf); @@ -353,7 +366,7 @@ Bool ML_(am_get_fd_d_i_m)( Int fd, *mode = (UInt) buf.st_mode; return True; } -# endif +# endif // defined __NR_fstat return False; # elif defined(VGO_solaris) # if defined(VGP_x86_solaris) @@ -372,11 +385,30 @@ Bool ML_(am_get_fd_d_i_m)( Int fd, return True; } return False; +# elif defined(VGO_freebsd) + struct vki_freebsd11_stat buf; +#if (FREEBSD_VERS >= FREEBSD_12) + SysRes res = VG_(do_syscall2)(__NR_freebsd11_fstat, fd, (UWord)&buf); +#else + SysRes res = VG_(do_syscall2)(__NR_fstat, fd, (UWord)&buf); +#endif + if (!sr_isError(res)) { + *dev = (ULong)buf.st_dev; + *ino = (ULong)buf.st_ino; + *mode = (UInt) buf.st_mode; + return True; + } + return False; # else # error Unknown OS # endif } +#if defined(VGO_freebsd) +#define M_FILEDESC_BUF 1000000 +static Char filedesc_buf[M_FILEDESC_BUF]; +#endif + Bool ML_(am_resolve_filename) ( Int fd, /*OUT*/HChar* buf, Int nbuf ) { #if defined(VGO_linux) @@ -389,6 +421,38 @@ Bool ML_(am_resolve_filename) ( Int fd, /*OUT*/HChar* buf, Int nbuf ) else return False; +#elif defined(VGO_freebsd) + Int mib[4]; + SysRes sres; + vki_size_t len; + Char *bp, *eb; + struct vki_kinfo_file *kf; + + mib[0] = VKI_CTL_KERN; + mib[1] = VKI_KERN_PROC; + mib[2] = VKI_KERN_PROC_FILEDESC; + mib[3] = sr_Res(VG_(do_syscall0)(__NR_getpid)); + len = sizeof(filedesc_buf); + sres = VG_(do_syscall6)(__NR___sysctl, (UWord)mib, 4, (UWord)filedesc_buf, + (UWord)&len, 0, 0); + if (sr_isError(sres)) { + VG_(debugLog)(0, "sysctl(kern.proc.filedesc)", "%s\n", VG_(strerror)(sr_Err(sres))); + ML_(am_exit)(1); + } + /* Walk though the list. */ + bp = filedesc_buf; + eb = filedesc_buf + len; + while (bp < eb) { + kf = (struct vki_kinfo_file *)bp; + if (kf->kf_fd == fd) + break; + bp += kf->kf_structsize; + } + if (bp >= eb || *kf->kf_path == '\0') + VG_(strncpy)( buf, "[unknown]", nbuf ); + else + VG_(strncpy)( buf, kf->kf_path, nbuf ); + return True; #elif defined(VGO_darwin) HChar tmp[VKI_MAXPATHLEN+1]; if (0 == ML_(am_fcntl)(fd, VKI_F_GETPATH, (UWord)tmp)) { diff --git a/coregrind/m_aspacemgr/aspacemgr-linux.c b/coregrind/m_aspacemgr/aspacemgr-linux.c index 0eb3143161..9a69f3850f 100644 --- a/coregrind/m_aspacemgr/aspacemgr-linux.c +++ b/coregrind/m_aspacemgr/aspacemgr-linux.c @@ -4,7 +4,7 @@ /*--- The address space manager: segment initialisation and ---*/ /*--- tracking, stack operations ---*/ /*--- ---*/ -/*--- Implementation for Linux (and Darwin!) aspacemgr-linux.c ---*/ +/*--- Implementation for Linux, Darwin, Solaris and FreeBSD ---*/ /*--------------------------------------------------------------------*/ /* @@ -30,7 +30,7 @@ The GNU General Public License is contained in the file COPYING. */ -#if defined(VGO_linux) || defined(VGO_darwin) || defined(VGO_solaris) +#if defined(VGO_linux) || defined(VGO_darwin) || defined(VGO_solaris) || defined(VGO_freebsd) /* ************************************************************* DO NOT INCLUDE ANY OTHER FILES HERE. @@ -314,6 +314,8 @@ Addr VG_(clo_aspacem_minAddr) # endif #elif defined(VGO_solaris) = (Addr) 0x00100000; // 1MB +#elif defined(VGO_freebsd) + = (Addr) 0x04000000; // 64M #else #endif @@ -367,7 +369,12 @@ static void parse_procselfmaps ( # define ARM_LINUX_FAKE_COMMPAGE_END1 0xFFFF1000 #endif - +#if !defined(VKI_MAP_STACK) +/* this is only defined for FreeBSD + * for readability, define it to 0 + * for other platforms */ +#define VKI_MAP_STACK 0 +#endif /*-----------------------------------------------------------------*/ /*--- ---*/ @@ -871,7 +878,7 @@ static void sync_check_mapping_callback ( Addr addr, SizeT len, UInt prot, cmp_devino = False; #endif -#if defined(VGO_darwin) +#if defined(VGO_darwin) || defined(VGO_freebsd) // GrP fixme kernel info doesn't have dev/inode cmp_devino = False; @@ -1491,7 +1498,13 @@ static void init_nsegment ( /*OUT*/NSegment* seg ) seg->mode = 0; seg->offset = 0; seg->fnIdx = -1; - seg->hasR = seg->hasW = seg->hasX = seg->hasT = seg->isCH = False; + + seg->hasR = seg->hasW = seg->hasX = seg->hasT + = seg->isCH = False; +#if defined(VGO_freebsd) + seg->isFF = False; +#endif + } /* Make an NSegment which holds a reservation. */ @@ -1637,6 +1650,81 @@ Addr VG_(am_startup) ( Addr sp_at_startup ) suggested_clstack_end = -1; // ignored; Mach-O specifies its stack + // --- Freebsd ------------------------------------------ +#elif defined(VGO_freebsd) + + + VG_(debugLog)(2, "aspacem", + " sp_at_startup = 0x%010lx (supplied)\n", + sp_at_startup ); + +# if VG_WORDSIZE == 4 + + aspacem_maxAddr = VG_PGROUNDDN( sp_at_startup ) - 1; +# else + aspacem_maxAddr = (Addr) (Addr)0x800000000UL - 1; // 32G +# ifdef ENABLE_INNER + { Addr cse = VG_PGROUNDDN( sp_at_startup ) - 1; + if (aspacem_maxAddr > cse) + aspacem_maxAddr = cse; + } +# endif // ENABLE_INNER +# endif + + aspacem_cStart = aspacem_minAddr; + aspacem_vStart = VG_PGROUNDUP((aspacem_minAddr + aspacem_maxAddr + 1) / 2); + +# ifdef ENABLE_INNER + aspacem_vStart -= 0x10000000UL; // 512M +# endif // ENABLE_INNER + + // starting with FreeBSD 10.4, the stack is created with a zone + // that is marked MAP_GUARD. This zone is reserved but unmapped, + // and fills the space up to the end of the segment + // see man mmap + + // Version number from + // https://www.freebsd.org/doc/en_US.ISO8859-1/books/porters-handbook/versions-10.html + + // On x86 this is 0x3FE0000 + // And on amd64 it is 0x1FFE0000 (536739840) + // There is less of an issue on amd64 as we just choose some arbitrary address rather then trying + // to squeeze in just below the host stack + + // Some of this is in sys/vm/vm_map.c, for instance vm_map_stack and vm_map_stack_locked + // These refer to the kernel global sgrowsiz, which seems to be the initial size + // of the user stack, 128k on my system + // + // This seems to be in the sysctl kern.sgrowsiz + // Then there is kern.maxssiz which is the total stack size (grow size + guard area) + // In other words guard area = maxssiz - sgrowsiz + +#if (__FreeBSD_version >= 1003516) + +#if 0 + // this block implements what is described above + // this makes no changes to the regression tests + // I'm keeping it for a rainy day. + // note this needs + // #include "pub_core_libcproc.h" + SizeT kern_maxssiz; + SizeT kern_sgrowsiz; + SizeT sysctl_size = sizeof(SizeT); + VG_(sysctlbyname)("kern.maxssiz", &kern_maxssiz, &sysctl_size, NULL, 0); + VG_(sysctlbyname)("kern.sgrowsiz", &kern_sgrowsiz, &sysctl_size, NULL, 0); + + suggested_clstack_end = aspacem_maxAddr - (kern_maxssiz - kern_sgrowsiz) + VKI_PAGE_SIZE; +#endif + + suggested_clstack_end = aspacem_maxAddr - 64*1024*1024UL + + VKI_PAGE_SIZE; + +#else + suggested_clstack_end = aspacem_maxAddr - 16*1024*1024UL + + VKI_PAGE_SIZE; + +#endif + // --- Solaris ------------------------------------------ #elif defined(VGO_solaris) # if VG_WORDSIZE == 4 @@ -1759,7 +1847,7 @@ Addr VG_(am_startup) ( Addr sp_at_startup ) suggested_clstack_end = aspacem_maxAddr - 16*1024*1024ULL + VKI_PAGE_SIZE; -#endif +#endif /* #else of 'defined(VGO_solaris)' */ // --- (end) -------------------------------------------- aspacem_assert(VG_IS_PAGE_ALIGNED(aspacem_minAddr)); @@ -2165,13 +2253,13 @@ VG_(am_notify_client_mmap)( Addr a, SizeT len, UInt prot, UInt flags, needDiscard = any_Ts_in_range( a, len ); init_nsegment( &seg ); - seg.kind = (flags & VKI_MAP_ANONYMOUS) ? SkAnonC : SkFileC; + seg.kind = (flags & (VKI_MAP_ANONYMOUS | VKI_MAP_STACK)) ? SkAnonC : SkFileC; seg.start = a; seg.end = a + len - 1; seg.hasR = toBool(prot & VKI_PROT_READ); seg.hasW = toBool(prot & VKI_PROT_WRITE); seg.hasX = toBool(prot & VKI_PROT_EXEC); - if (!(flags & VKI_MAP_ANONYMOUS)) { + if (!(flags & (VKI_MAP_ANONYMOUS | VKI_MAP_STACK))) { // Nb: We ignore offset requests in anonymous mmaps (see bug #126722) seg.offset = offset; if (ML_(am_get_fd_d_i_m)(fd, &dev, &ino, &mode)) { @@ -2182,6 +2270,9 @@ VG_(am_notify_client_mmap)( Addr a, SizeT len, UInt prot, UInt flags, if (ML_(am_resolve_filename)(fd, buf, VKI_PATH_MAX)) { seg.fnIdx = ML_(am_allocate_segname)( buf ); } +#if defined(VGO_freebsd) + seg.isFF = (flags & VKI_MAP_FIXED); +#endif } add_segment( &seg ); AM_SANITY_CHECK; @@ -2423,6 +2514,9 @@ SysRes VG_(am_mmap_named_file_fixed_client_flags) } else if (ML_(am_resolve_filename)(fd, buf, VKI_PATH_MAX)) { seg.fnIdx = ML_(am_allocate_segname)( buf ); } +#if defined(VGO_freebsd) + seg.isFF = (flags & VKI_MAP_FIXED); +#endif add_segment( &seg ); AM_SANITY_CHECK; @@ -2733,6 +2827,9 @@ static SysRes VG_(am_mmap_file_float_valgrind_flags) ( SizeT length, UInt prot, if (ML_(am_resolve_filename)(fd, buf, VKI_PATH_MAX)) { seg.fnIdx = ML_(am_allocate_segname)( buf ); } +#if defined(VGO_freebsd) + seg.isFF = (flags & VKI_MAP_FIXED); +#endif add_segment( &seg ); AM_SANITY_CHECK; @@ -3796,13 +3893,89 @@ Bool VG_(get_changed_segments)( return !css_overflowed; } -#endif // defined(VGO_darwin) /*------END-procmaps-parser-for-Darwin---------------------------*/ +/*------BEGIN-procmaps-parser-for-Freebsd------------------------*/ +#elif defined(VGO_freebsd) + +/* Size of a smallish table used to read /proc/self/map entries. */ +#define M_PROCMAP_BUF 10485760 /* 10M */ + +/* static ... to keep it out of the stack frame. */ +static char procmap_buf[M_PROCMAP_BUF]; + +static void parse_procselfmaps ( + void (*record_mapping)( Addr addr, SizeT len, UInt prot, + ULong dev, ULong ino, Off64T offset, + const HChar* filename ), + void (*record_gap)( Addr addr, SizeT len ) + ) +{ + Addr start, endPlusOne, gapStart; + char* filename; + char *p; + UInt prot; + ULong foffset, dev, ino; + struct vki_kinfo_vmentry *kve; + vki_size_t len; + Int oid[4]; + SysRes sres; + + foffset = ino = 0; /* keep gcc-4.1.0 happy */ + + oid[0] = VKI_CTL_KERN; + oid[1] = VKI_KERN_PROC; + oid[2] = VKI_KERN_PROC_VMMAP; + oid[3] = sr_Res(VG_(do_syscall0)(__NR_getpid)); + len = sizeof(procmap_buf); + + sres = VG_(do_syscall6)(__NR___sysctl, (UWord)oid, 4, (UWord)procmap_buf, + (UWord)&len, 0, 0); + if (sr_isError(sres)) { + VG_(debugLog)(0, "procselfmaps", "sysctl %lu\n", sr_Err(sres)); + ML_(am_exit)(1); + } + gapStart = Addr_MIN; + p = procmap_buf; + while (p < (char *)procmap_buf + len) { + kve = (struct vki_kinfo_vmentry *)p; + start = (UWord)kve->kve_start; + endPlusOne = (UWord)kve->kve_end; + foffset = kve->kve_offset; + filename = kve->kve_path; + dev = kve->kve_fsid; + ino = kve->kve_fileid; + if (filename[0] != '/') { + filename = NULL; + foffset = 0; + } + + prot = 0; + if (kve->kve_protection & VKI_KVME_PROT_READ) prot |= VKI_PROT_READ; + if (kve->kve_protection & VKI_KVME_PROT_WRITE) prot |= VKI_PROT_WRITE; + if (kve->kve_protection & VKI_KVME_PROT_EXEC) prot |= VKI_PROT_EXEC; + + if (record_gap && gapStart < start) + (*record_gap) ( gapStart, start-gapStart ); + + if (record_mapping && start < endPlusOne) + (*record_mapping) ( start, endPlusOne-start, + prot, dev, ino, + foffset, filename ); + gapStart = endPlusOne; + p += kve->kve_structsize; + } + + if (record_gap && gapStart < Addr_MAX) + (*record_gap) ( gapStart, Addr_MAX - gapStart + 1 ); +} + +/*------END-procmaps-parser-for-Freebsd--------------------------*/ + /*------BEGIN-procmaps-parser-for-Solaris------------------------*/ -#if defined(VGO_solaris) +#elif defined(VGO_solaris) /* Note: /proc/self/xmap contains extended information about already materialized mappings whereas /proc/self/rmap contains information about @@ -4112,7 +4285,7 @@ Bool VG_(am_search_for_new_segment)(Addr *addr, SizeT *size, UInt *prot) /*------END-procmaps-parser-for-Solaris--------------------------*/ -#endif // defined(VGO_linux) || defined(VGO_darwin) || defined(VGO_solaris) +#endif // defined(VGO_linux) || defined(VGO_darwin) || defined(VGO_solaris) || defined(VGO_freebsd) /*--------------------------------------------------------------------*/ /*--- end ---*/ diff --git a/coregrind/m_aspacemgr/priv_aspacemgr.h b/coregrind/m_aspacemgr/priv_aspacemgr.h index fbc46aca7b..161c5c2954 100644 --- a/coregrind/m_aspacemgr/priv_aspacemgr.h +++ b/coregrind/m_aspacemgr/priv_aspacemgr.h @@ -77,7 +77,7 @@ extern void ML_(am_assert_fail) ( const HChar* expr, const HChar* fn ); #define aspacem_assert(expr) \ - ((void) (LIKELY(expr) ? 0 : \ + ((void) (LIKELY(expr) ? (void)0 : \ (ML_(am_assert_fail)(#expr, \ __FILE__, __LINE__, \ __PRETTY_FUNCTION__)))) diff --git a/coregrind/m_coredump/coredump-elf.c b/coregrind/m_coredump/coredump-elf.c index daf85e6479..d0e8a03c94 100644 --- a/coregrind/m_coredump/coredump-elf.c +++ b/coregrind/m_coredump/coredump-elf.c @@ -26,7 +26,7 @@ The GNU General Public License is contained in the file COPYING. */ -#if defined(VGO_linux) +#if defined(VGO_linux) || defined(VGO_freebsd) #include "pub_core_basics.h" #include "pub_core_vki.h" @@ -90,6 +90,9 @@ static void fill_ehdr(ESZ(Ehdr) *ehdr, Int num_phdrs) ehdr->e_ident[EI_CLASS] = VG_ELF_CLASS; ehdr->e_ident[EI_DATA] = VG_ELF_DATA2XXX; ehdr->e_ident[EI_VERSION] = EV_CURRENT; +#if defined(VGO_freebsd) + ehdr->e_ident[EI_OSABI] = ELFOSABI_FREEBSD; +#endif ehdr->e_type = ET_CORE; ehdr->e_machine = VG_ELF_MACHINE; @@ -193,6 +196,19 @@ static void write_note(Int fd, const struct note *n) VG_(write)(fd, &n->note, note_size(n)); } +#if defined(VGO_freebsd) +static void fill_prpsinfo(const ThreadState *tst, + struct vki_elf_prpsinfo *prpsinfo) +{ + VG_(memset)(prpsinfo, 0, sizeof(*prpsinfo)); + + prpsinfo->pr_version = VKI_PRPSINFO_VERSION; + prpsinfo->pr_psinfosz = sizeof(struct vki_elf_prpsinfo); + VG_(client_fname)(prpsinfo->pr_fname, sizeof(prpsinfo->pr_fname), False); + // why? + VG_(strncpy)(prpsinfo->pr_psargs, prpsinfo->pr_fname, sizeof(prpsinfo->pr_psargs) - 1); +} +#else static void fill_prpsinfo(const ThreadState *tst, struct vki_elf_prpsinfo *prpsinfo) { @@ -223,6 +239,7 @@ static void fill_prpsinfo(const ThreadState *tst, VG_(client_fname)(prpsinfo->pr_fname, sizeof(prpsinfo->pr_fname), False); } +#endif static void fill_prstatus(const ThreadState *tst, /*OUT*/struct vki_elf_prstatus *prs, @@ -238,6 +255,16 @@ static void fill_prstatus(const ThreadState *tst, VG_(memset)(prs, 0, sizeof(*prs)); +#if defined(VGO_freebsd) + prs->pr_version = VKI_PRSTATUS_VERSION; + prs->pr_statussz = sizeof(struct vki_elf_prstatus); + prs->pr_gregsetsz = sizeof(vki_elf_gregset_t); + prs->pr_fpregsetsz = sizeof(vki_elf_fpregset_t); + prs->pr_osreldate = VG_(getosreldate)(); + + prs->pr_cursig = si->si_signo; + prs->pr_pid = tst->os_state.lwpid; +#else prs->pr_info.si_signo = si->si_signo; prs->pr_info.si_code = si->si_code; prs->pr_info.si_errno = 0; @@ -248,6 +275,7 @@ static void fill_prstatus(const ThreadState *tst, prs->pr_ppid = 0; prs->pr_pgrp = VG_(getpgrp)(); prs->pr_sid = VG_(getpgrp)(); +#endif #if defined(VGP_s390x_linux) /* prs->pr_reg has struct type. Need to take address. */ @@ -461,6 +489,45 @@ static void fill_prstatus(const ThreadState *tst, regs[VKI_MIPS32_EF_CP0_STATUS] = arch->vex.guest_CP0_status; regs[VKI_MIPS32_EF_CP0_EPC] = arch->vex.guest_PC; # undef DO +#elif defined(VGP_amd64_freebsd) + regs->rflags = LibVEX_GuestAMD64_get_rflags( &((ThreadArchState*)arch)->vex ); + regs->rsp = arch->vex.guest_RSP; + regs->rip = arch->vex.guest_RIP; + regs->rbx = arch->vex.guest_RBX; + regs->rcx = arch->vex.guest_RCX; + regs->rdx = arch->vex.guest_RDX; + regs->rsi = arch->vex.guest_RSI; + regs->rdi = arch->vex.guest_RDI; + regs->rbp = arch->vex.guest_RBP; + regs->rax = arch->vex.guest_RAX; + regs->r8 = arch->vex.guest_R8; + regs->r9 = arch->vex.guest_R9; + regs->r10 = arch->vex.guest_R10; + regs->r11 = arch->vex.guest_R11; + regs->r12 = arch->vex.guest_R12; + regs->r13 = arch->vex.guest_R13; + regs->r14 = arch->vex.guest_R14; + regs->r15 = arch->vex.guest_R15; +#elif defined(VGP_x86_freebsd) + regs->eflags = LibVEX_GuestX86_get_eflags( &arch->vex ); + regs->esp = arch->vex.guest_ESP; + regs->eip = arch->vex.guest_EIP; + + regs->ebx = arch->vex.guest_EBX; + regs->ecx = arch->vex.guest_ECX; + regs->edx = arch->vex.guest_EDX; + regs->esi = arch->vex.guest_ESI; + regs->edi = arch->vex.guest_EDI; + regs->ebp = arch->vex.guest_EBP; + regs->eax = arch->vex.guest_EAX; + + regs->cs = arch->vex.guest_CS; + regs->ds = arch->vex.guest_DS; + regs->ss = arch->vex.guest_SS; + regs->es = arch->vex.guest_ES; + regs->fs = arch->vex.guest_FS; + regs->gs = arch->vex.guest_GS; + #else # error Unknown ELF platform #endif @@ -587,6 +654,16 @@ static void fill_fpu(const ThreadState *tst, vki_elf_fpregset_t *fpu) # undef DO #elif defined(VGP_nanomips_linux) +#elif defined(VGP_x86_freebsd) + +#elif defined(VGP_amd64_freebsd) + +# define DO(n) VG_(memcpy)(fpu->xmm_space + n * 4, \ + &arch->vex.guest_YMM##n[0], 16) + DO(0); DO(1); DO(2); DO(3); DO(4); DO(5); DO(6); DO(7); + DO(8); DO(9); DO(10); DO(11); DO(12); DO(13); DO(14); DO(15); +# undef DO + #else # error Unknown ELF platform #endif diff --git a/coregrind/m_debuginfo/d3basics.c b/coregrind/m_debuginfo/d3basics.c index 1bc5f8f052..555e1e00d0 100644 --- a/coregrind/m_debuginfo/d3basics.c +++ b/coregrind/m_debuginfo/d3basics.c @@ -498,11 +498,11 @@ static Bool get_Dwarf_Reg( /*OUT*/Addr* a, Word regno, const RegSummary* regs ) { vg_assert(regs); # if defined(VGP_x86_linux) || defined(VGP_x86_darwin) \ - || defined(VGP_x86_solaris) + || defined(VGP_x86_solaris) || defined(VGP_x86_freebsd) if (regno == 5/*EBP*/) { *a = regs->fp; return True; } if (regno == 4/*ESP*/) { *a = regs->sp; return True; } # elif defined(VGP_amd64_linux) || defined(VGP_amd64_darwin) \ - || defined(VGP_amd64_solaris) + || defined(VGP_amd64_solaris) || defined(VGP_amd64_freebsd) if (regno == 6/*RBP*/) { *a = regs->fp; return True; } if (regno == 7/*RSP*/) { *a = regs->sp; return True; } # elif defined(VGP_ppc32_linux) diff --git a/coregrind/m_debuginfo/debuginfo.c b/coregrind/m_debuginfo/debuginfo.c index e2218f2668..2e5b9b0192 100644 --- a/coregrind/m_debuginfo/debuginfo.c +++ b/coregrind/m_debuginfo/debuginfo.c @@ -57,7 +57,7 @@ #include "priv_tytypes.h" #include "priv_storage.h" #include "priv_readdwarf.h" -#if defined(VGO_linux) || defined(VGO_solaris) +#if defined(VGO_linux) || defined(VGO_solaris) || defined(VGO_freebsd) # include "priv_readelf.h" # include "priv_readdwarf3.h" # include "priv_readpdb.h" @@ -814,7 +814,7 @@ void VG_(di_initialise) ( void ) /*--- ---*/ /*--------------------------------------------------------------*/ -#if defined(VGO_linux) || defined(VGO_darwin) || defined(VGO_solaris) +#if defined(VGO_linux) || defined(VGO_darwin) || defined(VGO_solaris) || defined(VGO_freebsd) /* Helper (indirect) for di_notify_ACHIEVE_ACCEPT_STATE */ static Bool overlaps_DebugInfoMappings ( const DebugInfoMapping* map1, @@ -965,7 +965,7 @@ static ULong di_notify_ACHIEVE_ACCEPT_STATE ( struct _DebugInfo* di ) truncate_DebugInfoMapping_overlaps( di, di->fsm.maps ); /* And acquire new info. */ -# if defined(VGO_linux) || defined(VGO_solaris) +# if defined(VGO_linux) || defined(VGO_solaris) || defined(VGO_freebsd) ok = ML_(read_elf_debug_info)( di ); # elif defined(VGO_darwin) ok = ML_(read_macho_debug_info)( di ); @@ -1204,6 +1204,13 @@ ULong VG_(di_notify_mmap)( Addr a, Bool allow_SkFileV, Int use_fd ) if (!(is_rx_map || is_rw_map || is_ro_map)) return 0; +#if defined(VGO_freebsd) + /* Ignore non-fixed read-only mappings. The dynamic linker may be + * mapping something for its own transient purposes. */ + if (!seg->isFF && is_ro_map) + return 0; +#endif + /* 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)); @@ -1247,7 +1254,7 @@ ULong VG_(di_notify_mmap)( Addr a, Bool allow_SkFileV, Int use_fd ) vg_assert(sr_Res(preadres) > 0 && sr_Res(preadres) <= sizeof(buf1k) ); /* We're only interested in mappings of object files. */ -# if defined(VGO_linux) || defined(VGO_solaris) +# if defined(VGO_linux) || defined(VGO_solaris) || defined(VGO_freebsd) if (!ML_(is_elf_object_file)( buf1k, (SizeT)sr_Res(preadres), False )) return 0; # elif defined(VGO_darwin) @@ -1696,7 +1703,7 @@ void VG_(di_notify_pdb_debuginfo)( Int fd_obj, Addr avma_obj, if (pdbname) ML_(dinfo_free)(pdbname); } -#endif /* defined(VGO_linux) || defined(VGO_darwin) || defined(VGO_solaris) */ +#endif /* defined(VGO_linux) || defined(VGO_darwin) || defined(VGO_solaris) || defined(VGO_freebsd) */ /*------------------------------------------------------------*/ @@ -2290,6 +2297,8 @@ Vg_FnNameKind VG_(get_fnname_kind) ( const HChar* name ) VG_STREQ("generic_start_main", name) || // Yellow Dog doggedness VG_STREQN(19, "generic_start_main.", name) || // gcc optimization VG_STREQ("_start", name) || +# elif defined(VGO_freebsd) + VG_STREQ("_start", name) || // FreeBSD libc # elif defined(VGO_darwin) // See readmacho.c for an explanation of this. VG_STREQ("start_according_to_valgrind", name) || // Darwin, darling diff --git a/coregrind/m_debuginfo/priv_readpdb.h b/coregrind/m_debuginfo/priv_readpdb.h index b8f5958103..b9b8fb3a2c 100644 --- a/coregrind/m_debuginfo/priv_readpdb.h +++ b/coregrind/m_debuginfo/priv_readpdb.h @@ -30,7 +30,7 @@ The GNU General Public License is contained in the file COPYING. */ -#if defined(VGO_linux) || defined(VGO_darwin) || defined(VGO_solaris) +#if defined(VGO_linux) || defined(VGO_darwin) || defined(VGO_solaris) || defined(VGO_freebsd) #ifndef __PRIV_READPDB_H #define __PRIV_READPDB_H @@ -57,7 +57,7 @@ HChar* ML_(find_name_of_pdb_file)( const HChar* pename ); #endif /* ndef __PRIV_READPDB_H */ -#endif // defined(VGO_linux) || defined(VGO_darwin) || defined(VGO_solaris) +#endif // defined(VGO_linux) || defined(VGO_darwin) || defined(VGO_solaris) || defined(VGO_freebsd) /*--------------------------------------------------------------------*/ /*--- end ---*/ diff --git a/coregrind/m_debuginfo/readdwarf.c b/coregrind/m_debuginfo/readdwarf.c index bcacca4cb9..39a2946870 100644 --- a/coregrind/m_debuginfo/readdwarf.c +++ b/coregrind/m_debuginfo/readdwarf.c @@ -27,7 +27,7 @@ The GNU General Public License is contained in the file COPYING. */ -#if defined(VGO_linux) || defined(VGO_darwin) || defined(VGO_solaris) +#if defined(VGO_linux) || defined(VGO_darwin) || defined(VGO_solaris) || defined(VGO_freebsd) #include "pub_core_basics.h" #include "pub_core_debuginfo.h" @@ -1961,11 +1961,11 @@ void ML_(read_debuginfo_dwarf1) ( /* --------------- Decls --------------- */ -#if defined(VGP_x86_linux) || defined(VGP_x86_solaris) +#if defined(VGP_x86_linux) || defined(VGP_x86_solaris) || defined(VGP_x86_freebsd) # define FP_REG 5 # define SP_REG 4 # define RA_REG_DEFAULT 8 -#elif defined(VGP_amd64_linux) || defined(VGP_amd64_solaris) +#elif defined(VGP_amd64_linux) || defined(VGP_amd64_solaris) || defined(VGP_amd64_freebsd) # define FP_REG 6 # define SP_REG 7 # define RA_REG_DEFAULT 16 @@ -4522,7 +4522,7 @@ void ML_(read_callframe_info_dwarf3) return; } -#endif // defined(VGO_linux) || defined(VGO_darwin) || defined(VGO_solaris) +#endif // defined(VGO_linux) || defined(VGO_darwin) || defined(VGO_solaris) || defined(VGO_freebsd) /*--------------------------------------------------------------------*/ /*--- end ---*/ diff --git a/coregrind/m_debuginfo/readdwarf3.c b/coregrind/m_debuginfo/readdwarf3.c index 4ac23a3c4d..18eecea9f3 100644 --- a/coregrind/m_debuginfo/readdwarf3.c +++ b/coregrind/m_debuginfo/readdwarf3.c @@ -33,7 +33,7 @@ without prior written permission. */ -#if defined(VGO_linux) || defined(VGO_darwin) || defined(VGO_solaris) +#if defined(VGO_linux) || defined(VGO_darwin) || defined(VGO_solaris) || defined(VGO_freebsd) /* REFERENCE (without which this code will not make much sense): @@ -5879,7 +5879,7 @@ ML_(new_dwarf3_reader) ( TRACE_SYMTAB("\n"); #endif -#endif // defined(VGO_linux) || defined(VGO_darwin) || defined(VGO_solaris) +#endif // defined(VGO_linux) || defined(VGO_darwin) || defined(VGO_solaris) || defined(VGO_freebsd) /*--------------------------------------------------------------------*/ /*--- end ---*/ diff --git a/coregrind/m_debuginfo/readelf.c b/coregrind/m_debuginfo/readelf.c index e424e3e7e8..c586e3f332 100644 --- a/coregrind/m_debuginfo/readelf.c +++ b/coregrind/m_debuginfo/readelf.c @@ -27,7 +27,7 @@ The GNU General Public License is contained in the file COPYING. */ -#if defined(VGO_linux) || defined(VGO_solaris) +#if defined(VGO_linux) || defined(VGO_solaris) || defined(VGO_freebsd) #include "pub_core_basics.h" #include "pub_core_vki.h" @@ -45,6 +45,7 @@ #include "pub_core_syscall.h" #include "pub_core_tooliface.h" /* VG_(needs) */ #include "pub_core_xarray.h" +#include "pub_core_libcproc.h" #include "priv_misc.h" /* dinfo_zalloc/free/strdup */ #include "priv_image.h" #include "priv_d3basics.h" @@ -1118,6 +1119,80 @@ void read_elf_symtab__ppc64be_linux( VG_(OSetGen_Destroy)( oset ); } +#if defined(VGO_freebsd) + +/** + * read_and_set_osrel + * + * "osrel" is in an Elf note. It has values such as 1201000 for FreeBSD 12.1 + * Some of the behaviour related to SIGSEGV and SIGBUS signals depends on the + * kernel reading this value. + * + * However in the case of Valgrind, the host is strictly statically linked and + * does not contain the NT_FREEBSD_ABI_TAG note. And even if it did, we want to + * override the value with that of the guest. + * + * At some later date we might want to look at the value of "fctl0" (note with the + * NT_FREEBSD_FEATURE_CTL type). This seems to be related to Address Space Layout + * Randomization. No hurry at the moment. + * + * See /usr/src/sys/kern/imgact_elf.c for details on how the kernel reads these + * notes. + */ +static +void read_and_set_osrel(DiImage* img) +{ + if (is_elf_object_file_by_DiImage(img, False)) { + Word i; + + ElfXX_Ehdr ehdr; + ML_(img_get)(&ehdr, img, 0, sizeof(ehdr)); + /* Skip the phdrs when we have to search the shdrs. In separate + .debug files the phdrs might not be valid (they are a copy of + the main ELF file) and might trigger assertions when getting + image notes based on them. */ + for (i = 0; i < ehdr.e_phnum; i++) { + ElfXX_Phdr phdr; + ML_(img_get)(&phdr, img, + ehdr.e_phoff + i * ehdr.e_phentsize, sizeof(phdr)); + + if (phdr.p_type == PT_NOTE) { + ElfXX_Off note_ioff = phdr.p_offset; + + while (note_ioff < phdr.p_offset + phdr.p_filesz) { + ElfXX_Nhdr note[2]; + ML_(img_get)(note, img, (DiOffT)note_ioff, sizeof(note)); + DiOffT name_ioff = note_ioff + sizeof(ElfXX_Nhdr); + //DiOffT desc_ioff = name_ioff + ((note[0].n_namesz + 3) & ~3); + if (ML_(img_strcmp_c)(img, name_ioff, "FreeBSD") == 0 + && note[0].n_type == NT_FREEBSD_ABI_TAG) { + + u_int32_t osrel = note[1].n_type; + int name[4]; + name[0] = CTL_KERN; + name[1] = KERN_PROC; + name[2] = KERN_PROC_OSREL; + name[3] = VG_(getpid)(); + 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); + } else { + if (VG_(clo_verbosity) > 1) { + VG_(message)(Vg_DebugMsg, "Set osrel for current process with value %d\n", osrel); + } + } + } + note_ioff = note_ioff + sizeof(ElfXX_Nhdr) + + ((note[0].n_namesz + 3) & ~3) + + ((note[0].n_descsz + 3) & ~3); + } + } + } + } + +} +#endif /* * Look for a build-id in an ELF image. The build-id specification @@ -1701,7 +1776,7 @@ static HChar* readlink_path (const HChar *path) #if defined(VGP_arm64_linux) || defined(VGP_nanomips_linux) res = VG_(do_syscall4)(__NR_readlinkat, VKI_AT_FDCWD, (UWord)path, (UWord)buf, bufsiz); -#elif defined(VGO_linux) || defined(VGO_darwin) +#elif defined(VGO_linux) || defined(VGO_darwin) || defined(VGO_freebsd) res = VG_(do_syscall3)(__NR_readlink, (UWord)path, (UWord)buf, bufsiz); #elif defined(VGO_solaris) res = VG_(do_syscall4)(__NR_readlinkat, VKI_AT_FDCWD, (UWord)path, @@ -1939,14 +2014,14 @@ 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->rx) - TRACE_SYMTAB("rx_map: avma %#lx size %lu foff %ld\n", - map->avma, map->size, map->foff); + TRACE_SYMTAB("rx_map: avma %#lx size %lu foff %lld\n", + map->avma, map->size, (Long)map->foff); } for (i = 0; i < VG_(sizeXA)(di->fsm.maps); i++) { const DebugInfoMapping* map = VG_(indexXA)(di->fsm.maps, i); if (map->rw) - TRACE_SYMTAB("rw_map: avma %#lx size %lu foff %ld\n", - map->avma, map->size, map->foff); + TRACE_SYMTAB("rw_map: avma %#lx size %lu foff %lld\n", + map->avma, map->size, (Long)map->foff); } if (phdr_mnent == 0 @@ -2039,6 +2114,11 @@ 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)) { @@ -2166,8 +2246,8 @@ 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->rx) - TRACE_SYMTAB("rx: at %#lx are mapped foffsets %ld .. %lu\n", - map->avma, map->foff, map->foff + map->size - 1 ); + TRACE_SYMTAB("rx: at %#lx are mapped foffsets %lld .. %lld\n", + map->avma, (Long)map->foff, (Long)(map->foff + map->size - 1) ); } TRACE_SYMTAB("rx: contains these svma regions:\n"); for (i = 0; i < VG_(sizeXA)(svma_ranges); i++) { @@ -2179,8 +2259,8 @@ 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) - TRACE_SYMTAB("rw: at %#lx are mapped foffsets %ld .. %lu\n", - map->avma, map->foff, map->foff + map->size - 1 ); + 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++) { @@ -2222,10 +2302,11 @@ Bool ML_(read_elf_debug_info) ( struct _DebugInfo* di ) } } - TRACE_SYMTAB(" [sec %2ld] %s %s al%4u foff %6ld .. %6lu " + TRACE_SYMTAB(" [sec %2ld] %s %s al%4u foff %6lld .. %6lld " " svma %p name \"%s\"\n", i, inrx ? "rx" : " ", inrw ? "rw" : " ", alyn, - foff, (size == 0) ? foff : foff+size-1, (void *) svma, name); + (Long) foff, (size == 0) ? (Long)foff : (Long)(foff+size-1), + (void *) svma, name); /* Check for sane-sized segments. SHT_NOBITS sections have zero size in the file and their offsets are just conceptual. */ @@ -2540,7 +2621,8 @@ Bool ML_(read_elf_debug_info) ( struct _DebugInfo* di ) || defined(VGP_arm_linux) || defined (VGP_s390x_linux) \ || defined(VGP_mips32_linux) || defined(VGP_mips64_linux) \ || defined(VGP_arm64_linux) || defined(VGP_nanomips_linux) \ - || defined(VGP_x86_solaris) || defined(VGP_amd64_solaris) + || defined(VGP_x86_solaris) || defined(VGP_amd64_solaris) \ + || defined(VGP_x86_freebsd) || defined(VGP_amd64_freebsd) /* Accept .plt where mapped as rx (code) */ if (0 == VG_(strcmp)(name, ".plt")) { if (inrx && !di->plt_present) { @@ -2876,6 +2958,12 @@ Bool ML_(read_elf_debug_info) ( struct _DebugInfo* di ) |dimg| to it. */ vg_assert(dimg == NULL && aimg == NULL); +#if defined(VGO_freebsd) + /* */ + read_and_set_osrel(mimg); + +#endif + /* Look for a build-id */ HChar* buildid = find_buildid(mimg, False, False); @@ -3512,7 +3600,7 @@ Bool ML_(read_elf_debug_info) ( struct _DebugInfo* di ) /* NOTREACHED */ } -#endif // defined(VGO_linux) || defined(VGO_solaris) +#endif // defined(VGO_linux) || defined(VGO_solaris) || defined(VGO_freebsd) /*--------------------------------------------------------------------*/ /*--- end ---*/ diff --git a/coregrind/m_debuginfo/readpdb.c b/coregrind/m_debuginfo/readpdb.c index f9128e30cf..a53cf48c44 100644 --- a/coregrind/m_debuginfo/readpdb.c +++ b/coregrind/m_debuginfo/readpdb.c @@ -33,7 +33,7 @@ The GNU General Public License is contained in the file COPYING. */ -#if defined(VGO_linux) || defined(VGO_darwin) || defined(VGO_solaris) +#if defined(VGO_linux) || defined(VGO_darwin) || defined(VGO_solaris) || defined(VGO_freebsd) #include "pub_core_basics.h" #include "pub_core_debuginfo.h" @@ -2604,7 +2604,7 @@ HChar* ML_(find_name_of_pdb_file)( const HChar* pename ) return res; } -#endif // defined(VGO_linux) || defined(VGO_darwin) || defined(VGO_solaris) +#endif // defined(VGO_linux) || defined(VGO_darwin) || defined(VGO_solaris) || defined(VGO_freebsd) /*--------------------------------------------------------------------*/ /*--- end ---*/ diff --git a/coregrind/m_debuginfo/storage.c b/coregrind/m_debuginfo/storage.c index 48a92b4029..9ba74076c1 100644 --- a/coregrind/m_debuginfo/storage.c +++ b/coregrind/m_debuginfo/storage.c @@ -365,6 +365,11 @@ void ML_(addSym) ( struct _DebugInfo* di, DiSym* sym ) vg_assert(sym->pri_name != NULL); vg_assert(sym->sec_names == NULL); +#if defined(VGO_freebsd) + if (sym->size == 0) + sym->size = 1; +#endif + /* Ignore zero-sized syms. */ if (sym->size == 0) return; @@ -1534,7 +1539,7 @@ Bool preferName ( const DebugInfo* di, vlena = VG_(strlen)(a_name); vlenb = VG_(strlen)(b_name); -# if defined(VGO_linux) || defined(VGO_solaris) +# if defined(VGO_linux) || defined(VGO_solaris) || defined(VGO_freebsd) # define VERSION_CHAR '@' # elif defined(VGO_darwin) # define VERSION_CHAR '$' diff --git a/coregrind/m_debuglog.c b/coregrind/m_debuglog.c index ce4714d1bf..355c3caf5b 100644 --- a/coregrind/m_debuglog.c +++ b/coregrind/m_debuglog.c @@ -435,6 +435,89 @@ static UInt local_sys_getpid ( void ) return (UInt)(__res); } +#elif defined(VGP_x86_freebsd) +static UInt local_sys_write_stderr (const HChar* buf, Int n ) +{ + Int result; + + __asm__ volatile ( + "movl %2, %%eax\n" /* push n */ + "movl %1, %%edx\n" /* push buf */ + "pushl %%eax\n" + "pushl %%edx\n" + "movl $2, %%eax\n" /* push stderr */ + "pushl %%eax\n" + "movl $"VG_STRINGIFY(__NR_write)", %%eax\n" + "pushl %%eax\n" /* push write syscall id */ + "int $0x80\n" /* write(stderr, buf, n) */ + "jnc 1f\n" /* jump if no error */ + "movl $-1, %%eax\n" /* return -1 if error */ + "1: " + "movl %%eax, %0\n" /* __res = eax */ + "addl $16, %%esp\n" /* pop x4 */ + : /*wr*/ "=mr" (result) + : /*rd*/ "g" (buf), "g" (n) + : /*trash*/ "eax", "edx", "cc" + ); + return result >= 0 ? result : -1; +} + +static UInt local_sys_getpid ( void ) +{ + UInt __res; + __asm__ volatile ( + "movl $20, %%eax\n" /* set %eax = __NR_getpid */ + "int $0x80\n" /* getpid() */ + "movl %%eax, %0\n" /* set __res = eax */ + : "=mr" (__res) + : + : "eax" ); + return __res; +} + +#elif defined(VGP_amd64_freebsd) +__attribute__((noinline)) +static UInt local_sys_write_stderr (const HChar* buf, Int n ) +{ + volatile Long block[2]; + block[0] = (Long)buf; + block[1] = n; + __asm__ volatile ( + "subq $256, %%rsp\n" /* don't trash the stack redzone */ + "pushq %%r15\n" /* r15 is callee-save */ + "movq %0, %%r15\n" /* r15 = &block */ + "pushq %%r15\n" /* save &block */ + "movq $"VG_STRINGIFY(__NR_write)", %%rax\n" /* rax = __NR_write */ + "movq $2, %%rdi\n" /* rdi = stderr */ + "movq 0(%%r15), %%rsi\n" /* rsi = buf */ + "movq 8(%%r15), %%rdx\n" /* rdx = n */ + "syscall\n" /* write(stderr, buf, n) */ + "popq %%r15\n" /* reestablish &block */ + "movq %%rax, 0(%%r15)\n" /* block[0] = result */ + "popq %%r15\n" /* restore r15 */ + "addq $256, %%rsp\n" /* restore stack ptr */ + : /*wr*/ + : /*rd*/ "r" (block) + : /*trash*/ "rax", "rdi", "rsi", "rdx", "memory", "cc", "rcx", "r8", "r9", "r11" + ); + if (block[0] < 0) + block[0] = -1; + return (UInt)block[0]; +} + +static UInt local_sys_getpid ( void ) +{ + UInt __res; + __asm__ volatile ( + "movq $20, %%rax\n" /* set %rax = __NR_getpid */ + "syscall\n" /* getpid() */ + "movl %%eax, %0\n" /* set __res = %eax */ + : "=mr" (__res) + : + : "rax", "rcx");//, "r11" ); + return __res; +} + #elif defined(VGP_mips32_linux) || defined(VGP_mips64_linux) static UInt local_sys_write_stderr ( const HChar* buf, Int n ) diff --git a/coregrind/m_gdbserver/gdb/signals.h b/coregrind/m_gdbserver/gdb/signals.h index d04a574771..4857475fa3 100644 --- a/coregrind/m_gdbserver/gdb/signals.h +++ b/coregrind/m_gdbserver/gdb/signals.h @@ -137,6 +137,9 @@ enum target_signal /* Used internally by Solaris threads. See signal(5) on Solaris. */ TARGET_SIGNAL_CANCEL = 76, + /* Similar to the above, but for FreeBSD */ + TARGET_SIGNAL_THR = 77, + /* Yes, this pains me, too. But LynxOS didn't have SIG32, and now GNU/Linux does, and we can't disturb the numbering, since it's part of the remote protocol. Note that in some GDB's diff --git a/coregrind/m_gdbserver/remote-utils.c b/coregrind/m_gdbserver/remote-utils.c index 2d13b79f3d..559d8dd8e9 100644 --- a/coregrind/m_gdbserver/remote-utils.c +++ b/coregrind/m_gdbserver/remote-utils.c @@ -27,6 +27,7 @@ #include "pub_core_libcsignal.h" #include "pub_core_options.h" #include "pub_core_aspacemgr.h" +#include "pub_core_syswrap.h" #include "server.h" @@ -322,7 +323,11 @@ void remote_open (const HChar *name) (Addr) VG_(threads), VG_N_THREADS, sizeof(ThreadState), offsetof(ThreadState, status), offsetof(ThreadState, os_state) + offsetof(ThreadOSstate, lwpid), - 0}; + 0 +#if VEX_HOST_WORDSIZE == 8 + , 0 +#endif + }; user = VG_(getenv)("LOGNAME"); if (user == NULL) user = VG_(getenv)("USER"); @@ -519,12 +524,30 @@ void remote_close (void) from_gdb ? from_gdb : "NULL", to_gdb ? to_gdb : "NULL", shared_mem ? shared_mem : "NULL"); - if (pid == pid_from_to_creator && from_gdb && VG_(unlink) (from_gdb) == -1) - warning ("could not unlink %s\n", from_gdb); - if (pid == pid_from_to_creator && to_gdb && VG_(unlink) (to_gdb) == -1) - warning ("could not unlink %s\n", to_gdb); - if (pid == pid_from_to_creator && shared_mem && VG_(unlink) (shared_mem) == -1) - warning ("could not unlink %s\n", shared_mem); + + // PJF this is not ideal + // if the guest enters capability mode then the unlink calls will fail + // this may well also apply to Linux and seccomp + // I don't have any thoughts on how to fix it, other than forking early on + // having the child run the guest and the parent wait()ing and then + // the parent doing the cleanup + + Bool unlinkPossible = True; +#if defined(VGO_freebsd) + unlinkPossible = (VG_(get_capability_mode)() == False); +#endif + + if (unlinkPossible == True) { + if (pid == pid_from_to_creator && from_gdb && VG_(unlink) (from_gdb) == -1) + warning ("could not unlink %s\n", from_gdb); + if (pid == pid_from_to_creator && to_gdb && VG_(unlink) (to_gdb) == -1) + warning ("could not unlink %s\n", to_gdb); + if (pid == pid_from_to_creator && shared_mem && VG_(unlink) (shared_mem) == -1) + warning ("could not unlink %s\n", shared_mem); + } else { + VG_(debugLog)(1, "remote close", + "cannot unlink gdb pipes\n"); + } free (from_gdb); from_gdb = NULL; free (to_gdb); diff --git a/coregrind/m_gdbserver/signals.c b/coregrind/m_gdbserver/signals.c index 24948a19a4..9aee90fcba 100644 --- a/coregrind/m_gdbserver/signals.c +++ b/coregrind/m_gdbserver/signals.c @@ -404,6 +404,10 @@ enum target_signal target_signal_from_host (int hostsig) if (hostsig == VKI_SIGCANCEL) return TARGET_SIGNAL_CANCEL; #endif +#if defined(VKI_SIGTHR) + if (hostsig == VKI_SIGTHR) + return TARGET_SIGNAL_THR; +#endif #if defined (VKI_SIGLWP) if (hostsig == VKI_SIGLWP) return TARGET_SIGNAL_LWP; @@ -657,6 +661,10 @@ int do_target_signal_to_host (enum target_signal oursig, case TARGET_SIGNAL_CANCEL: return VKI_SIGCANCEL; #endif +#if defined (VKI_SIGTHR) + case TARGET_SIGNAL_THR: + return VKI_SIGTHR; +#endif #if defined (VKI_SIGLWP) case TARGET_SIGNAL_LWP: return VKI_SIGLWP; diff --git a/coregrind/m_libcassert.c b/coregrind/m_libcassert.c index ec63fccefb..35f37f88df 100644 --- a/coregrind/m_libcassert.c +++ b/coregrind/m_libcassert.c @@ -49,7 +49,7 @@ ------------------------------------------------------------------ */ #if defined(VGP_x86_linux) || defined(VGP_x86_darwin) \ - || defined(VGP_x86_solaris) + || defined(VGP_x86_solaris) || defined(VGP_x86_freebsd) # define GET_STARTREGS(srP) \ { UInt eip, esp, ebp; \ __asm__ __volatile__( \ @@ -66,7 +66,7 @@ (srP)->misc.X86.r_ebp = ebp; \ } #elif defined(VGP_amd64_linux) || defined(VGP_amd64_darwin) \ - || defined(VGP_amd64_solaris) + || defined(VGP_amd64_solaris) || defined(VGP_amd64_freebsd) # define GET_STARTREGS(srP) \ { ULong rip, rsp, rbp; \ __asm__ __volatile__( \ @@ -309,7 +309,7 @@ void VG_(exit_now)( Int status ) { #if defined(VGO_linux) (void)VG_(do_syscall1)(__NR_exit_group, status ); -#elif defined(VGO_darwin) || defined(VGO_solaris) +#elif defined(VGO_darwin) || defined(VGO_solaris) || defined(VGO_freebsd) (void)VG_(do_syscall1)(__NR_exit, status ); #else # error Unknown OS diff --git a/coregrind/m_libcfile.c b/coregrind/m_libcfile.c index 3a8fed85d9..598027c6d9 100644 --- a/coregrind/m_libcfile.c +++ b/coregrind/m_libcfile.c @@ -67,6 +67,11 @@ Int VG_(safe_fd)(Int oldfd) return newfd; } +#if defined(VGO_freebsd) +#define M_FILEDESC_BUF 1000000 +static Char filedesc_buf[M_FILEDESC_BUF]; +#endif + /* Given a file descriptor, attempt to deduce its filename. To do this, we use /proc/self/fd/<FD>. If this doesn't point to a file, or if it doesn't exist, we return False. @@ -113,6 +118,46 @@ Bool VG_(resolve_filename) ( Int fd, const HChar** result ) *result = NULL; return False; +#elif defined(VGO_freebsd) + Int mib[4]; + SysRes sres; + vki_size_t len; + Char *bp, *eb; + struct vki_kinfo_file *kf; + static HChar *buf = NULL; + static SizeT bufsiz = 0; + + if (buf == NULL) { // first time + bufsiz = 500; + buf = VG_(malloc)("resolve_filename", bufsiz); + } + + mib[0] = VKI_CTL_KERN; + mib[1] = VKI_KERN_PROC; + mib[2] = VKI_KERN_PROC_FILEDESC; + mib[3] = sr_Res(VG_(do_syscall0)(__NR_getpid)); + len = sizeof(filedesc_buf); + sres = VG_(do_syscall6)(__NR___sysctl, (UWord)mib, 4, (UWord)filedesc_buf, + (UWord)&len, 0, 0); + if (sr_isError(sres)) { + VG_(debugLog)(0, "sysctl(kern.proc.filedesc)", "%s\n", VG_(strerror)(sr_Err(sres))); + return False; + } + /* Walk though the list. */ + bp = filedesc_buf; + eb = filedesc_buf + len; + while (bp < eb) { + kf = (struct vki_kinfo_file *)bp; + if (kf->kf_fd == fd) + break; + bp += kf->kf_structsize; + } + if (bp >= eb || *kf->kf_path == '\0') + VG_(strncpy)( buf, "[unknown]", bufsiz ); + else + VG_(strncpy)( buf, kf->kf_path, bufsiz ); + *result = buf; + return True; # elif defined(VGO_darwin) HChar tmp[VKI_MAXPATHLEN+1]; if (0 == VG_(fcntl)(fd, VKI_F_GETPATH, (UWord)tmp)) { @@ -143,6 +188,9 @@ SysRes VG_(mknod) ( const HChar* pathname, Int mode, UWord dev ) # elif defined(VGO_linux) || defined(VGO_darwin) SysRes res = VG_(do_syscall3)(__NR_mknod, (UWord)pathname, mode, dev); +# elif defined(VGO_freebsd) + SysRes res = VG_(do_syscall3)(__NR_freebsd11_mknod, + (UWord)pathname, mode, dev); # elif defined(VGO_solaris) SysRes res = VG_(do_syscall4)(__NR_mknodat, VKI_AT_FDCWD, (UWord)pathname, mode, dev); @@ -158,7 +206,7 @@ SysRes VG_(open) ( const HChar* pathname, Int flags, Int mode ) /* ARM64 wants to use __NR_openat rather than __NR_open. */ SysRes res = VG_(do_syscall4)(__NR_openat, VKI_AT_FDCWD, (UWord)pathname, flags, mode); -# elif defined(VGO_linux) +# elif defined(VGO_linux) || defined(VGO_freebsd) SysRes res = VG_(do_syscall3)(__NR_open, (UWord)pathname, flags, mode); # elif defined(VGO_darwin) @@ -186,7 +234,7 @@ Int VG_(fd_open) (const HChar* pathname, Int flags, Int mode) void VG_(close) ( Int fd ) { /* Hmm. Return value is not checked. That's uncool. */ -# if defined(VGO_linux) || defined(VGO_solaris) +# if defined(VGO_linux) || defined(VGO_solaris) || defined(VGO_freebsd) (void)VG_(do_syscall1)(__NR_close, fd); # elif defined(VGO_darwin) (void)VG_(do_syscall1)(__NR_close_nocancel, fd); @@ -198,7 +246,7 @@ void VG_(close) ( Int fd ) Int VG_(read) ( Int fd, void* buf, Int count) { Int ret; -# if defined(VGO_linux) || defined(VGO_solaris) +# if defined(VGO_linux) || defined(VGO_solaris) || defined(VGO_freebsd) SysRes res = VG_(do_syscall3)(__NR_read, fd, (UWord)buf, count); # elif defined(VGO_darwin) SysRes res = VG_(do_syscall3)(__NR_read_nocancel, fd, (UWord)buf, count); @@ -218,7 +266,7 @@ Int VG_(read) ( Int fd, void* buf, Int count) Int VG_(write) ( Int fd, const void* buf, Int count) { Int ret; -# if defined(VGO_linux) || defined(VGO_solaris) +# if defined(VGO_linux) || defined(VGO_solaris) || defined(VGO_freebsd) SysRes res = VG_(do_syscall3)(__NR_write, fd, (UWord)buf, count); # elif defined(VGO_darwin) SysRes res = VG_(do_syscall3)(__NR_write_nocancel, fd, (UWord)buf, count); @@ -254,6 +302,13 @@ Int VG_(pipe) ( Int fd[2] ) # elif defined(VGO_linux) SysRes res = VG_(do_syscall1)(__NR_pipe, (UWord)fd); return sr_isError(res) ? -1 : 0; +# elif defined(VGO_freebsd) + SysRes res = VG_(do_syscall0)(__NR_freebsd10_pipe); + if (!sr_isError(res)) { + fd[0] = sr_Res(res); + fd[1] = sr_ResHI(res); + } + return sr_isError(res) ? -1 : 0; # elif defined(VGO_darwin) /* __NR_pipe is UX64, so produces a double-word result */ SysRes res = VG_(do_syscall0)(__NR_pipe); @@ -281,7 +336,7 @@ Int VG_(pipe) ( Int fd[2] ) Off64T VG_(lseek) ( Int fd, Off64T offset, Int whence ) { -# if defined(VGO_linux) || defined(VGP_amd64_darwin) +# if defined(VGO_linux) || defined(VGP_amd64_darwin) || defined(VGP_amd64_freebsd) # if defined(__NR__llseek) Off64T result; SysRes res = VG_(do_syscall5)(__NR__llseek, fd, @@ -293,7 +348,7 @@ Off64T VG_(lseek) ( Int fd, Off64T offset, Int whence ) vg_assert(sizeof(Off64T) == sizeof(sr_Res(res))); return sr_isError(res) ? (-1) : sr_Res(res); # endif -# elif defined(VGP_x86_darwin) +# elif defined(VGP_x86_darwin) || defined(VGP_x86_freebsd) SysRes res = VG_(do_syscall4)(__NR_lseek, fd, offset & 0xffffffff, offset >> 32, whence); return sr_isError(res) ? (-1) : sr_Res(res); @@ -424,6 +479,18 @@ SysRes VG_(stat) ( const HChar* file_n... [truncated message content] |
|
From: Paul F. <pa...@so...> - 2021-10-09 12:13:50
|
https://sourceware.org/git/gitweb.cgi?p=valgrind.git;h=e2e5d75f5cbc108d68142c4c56878df9abaed653 commit e2e5d75f5cbc108d68142c4c56878df9abaed653 Author: Paul Floyd <pj...@wa...> Date: Sat Oct 9 14:11:48 2021 +0200 FreeBSD support, patch 11 coregrind added files the key mechanics and the syscall wrappers Diff: --- configure.ac | 2 + coregrind/Makefile.am | 11 + coregrind/launcher-freebsd.c | 325 ++ coregrind/link_tool_exe_freebsd.in | 82 + coregrind/m_dispatch/dispatch-amd64-freebsd.S | 321 ++ coregrind/m_dispatch/dispatch-x86-freebsd.S | 251 + coregrind/m_initimg/initimg-freebsd.c | 979 ++++ coregrind/m_sigframe/sigframe-amd64-freebsd.c | 432 ++ coregrind/m_sigframe/sigframe-x86-freebsd.c | 457 ++ coregrind/m_syswrap/priv_syswrap-freebsd.h | 554 ++ coregrind/m_syswrap/syscall-amd64-freebsd.S | 207 + coregrind/m_syswrap/syscall-x86-freebsd.S | 201 + coregrind/m_syswrap/syswrap-amd64-freebsd.c | 1113 ++++ coregrind/m_syswrap/syswrap-freebsd.c | 6876 +++++++++++++++++++++++++ coregrind/m_syswrap/syswrap-x86-freebsd.c | 1517 ++++++ 15 files changed, 13328 insertions(+) diff --git a/configure.ac b/configure.ac index 39e619575e..275c0ca02c 100755 --- a/configure.ac +++ b/configure.ac @@ -5211,6 +5211,8 @@ AC_CONFIG_FILES([ ]) AC_CONFIG_FILES([coregrind/link_tool_exe_linux], [chmod +x coregrind/link_tool_exe_linux]) +AC_CONFIG_FILES([coregrind/link_tool_exe_freebsd], + [chmod +x coregrind/link_tool_exe_freebsd]) AC_CONFIG_FILES([coregrind/link_tool_exe_darwin], [chmod +x coregrind/link_tool_exe_darwin]) AC_CONFIG_FILES([coregrind/link_tool_exe_solaris], diff --git a/coregrind/Makefile.am b/coregrind/Makefile.am index 01b8783ee4..1de685bb45 100644 --- a/coregrind/Makefile.am +++ b/coregrind/Makefile.am @@ -286,6 +286,7 @@ noinst_HEADERS = \ m_syswrap/priv_syswrap-generic.h \ m_syswrap/priv_syswrap-linux.h \ m_syswrap/priv_syswrap-linux-variants.h \ + m_syswrap/priv_syswrap-freebsd.h \ m_syswrap/priv_syswrap-darwin.h \ m_syswrap/priv_syswrap-solaris.h \ m_syswrap/priv_syswrap-main.h \ @@ -388,6 +389,8 @@ COREGRIND_SOURCES_COMMON = \ m_dispatch/dispatch-mips32-linux.S \ m_dispatch/dispatch-mips64-linux.S \ m_dispatch/dispatch-nanomips-linux.S \ + m_dispatch/dispatch-x86-freebsd.S \ + m_dispatch/dispatch-amd64-freebsd.S \ m_dispatch/dispatch-x86-darwin.S \ m_dispatch/dispatch-amd64-darwin.S \ m_dispatch/dispatch-x86-solaris.S \ @@ -412,6 +415,7 @@ COREGRIND_SOURCES_COMMON = \ m_gdbserver/valgrind-low-nanomips.c \ m_gdbserver/version.c \ m_initimg/initimg-linux.c \ + m_initimg/initimg-freebsd.c \ m_initimg/initimg-darwin.c \ m_initimg/initimg-solaris.c \ m_mach/mach_basics.c \ @@ -426,6 +430,8 @@ COREGRIND_SOURCES_COMMON = \ m_sigframe/sigframe-common.c \ m_sigframe/sigframe-x86-linux.c \ m_sigframe/sigframe-amd64-linux.c \ + m_sigframe/sigframe-x86-freebsd.c \ + m_sigframe/sigframe-amd64-freebsd.c \ m_sigframe/sigframe-ppc32-linux.c \ m_sigframe/sigframe-ppc64-linux.c \ m_sigframe/sigframe-arm-linux.c \ @@ -448,6 +454,8 @@ COREGRIND_SOURCES_COMMON = \ m_syswrap/syscall-mips32-linux.S \ m_syswrap/syscall-mips64-linux.S \ m_syswrap/syscall-nanomips-linux.S \ + m_syswrap/syscall-x86-freebsd.S \ + m_syswrap/syscall-amd64-freebsd.S \ m_syswrap/syscall-x86-darwin.S \ m_syswrap/syscall-amd64-darwin.S \ m_syswrap/syscall-x86-solaris.S \ @@ -456,12 +464,15 @@ COREGRIND_SOURCES_COMMON = \ m_syswrap/syswrap-generic.c \ m_syswrap/syswrap-linux.c \ m_syswrap/syswrap-linux-variants.c \ + m_syswrap/syswrap-freebsd.c \ m_syswrap/syswrap-darwin.c \ m_syswrap/syswrap-solaris.c \ m_syswrap/syswrap-x86-linux.c \ m_syswrap/syswrap-amd64-linux.c \ m_syswrap/syswrap-ppc32-linux.c \ m_syswrap/syswrap-ppc64-linux.c \ + m_syswrap/syswrap-x86-freebsd.c \ + m_syswrap/syswrap-amd64-freebsd.c \ m_syswrap/syswrap-arm-linux.c \ m_syswrap/syswrap-arm64-linux.c \ m_syswrap/syswrap-s390x-linux.c \ diff --git a/coregrind/launcher-freebsd.c b/coregrind/launcher-freebsd.c new file mode 100644 index 0000000000..7d40ad6cce --- /dev/null +++ b/coregrind/launcher-freebsd.c @@ -0,0 +1,325 @@ + +/*--------------------------------------------------------------------*/ +/*--- Launching valgrind m_launcher.c ---*/ +/*--------------------------------------------------------------------*/ + +/* + This file is part of Valgrind, a dynamic binary instrumentation + framework. + + Copyright (C) 2000-2009 Julian Seward + js...@ac... + Copyright (C) 2018-2021 Paul Floyd + pj...@wa... + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, see <http://www.gnu.org/licenses/>. + + The GNU General Public License is contained in the file COPYING. +*/ + +/* Note: this is a "normal" program and not part of Valgrind proper, + and so it doesn't have to conform to Valgrind's arcane rules on + no-glibc-usage etc. */ + +#include <assert.h> +#include <ctype.h> +#include <elf.h> +#include <errno.h> +#include <fcntl.h> +#include <stdarg.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <sys/mman.h> +#include <sys/sysctl.h> +/* #include <sys/user.h> */ +#include <unistd.h> + +#include "pub_core_debuglog.h" +#include "pub_core_vki.h" // Avoids warnings from +// pub_core_libcfile.h +#include "pub_core_libcproc.h" // For VALGRIND_LIB, VALGRIND_LAUNCHER +#include "pub_core_ume.h" + + +#if !defined(PATH_MAX) +#define PATH_MAX 4096 /* POSIX refers to this a lot but I dunno + where it is defined */ +#endif + +#ifndef EM_X86_64 +#define EM_X86_64 62 // elf.h doesn't define this on some older systems +#endif + +/* Report fatal errors */ +__attribute__((noreturn)) +static void barf ( const char *format, ... ) +{ + va_list vargs; + + va_start(vargs, format); + fprintf(stderr, "valgrind: Cannot continue: "); + vfprintf(stderr, format, vargs); + fprintf(stderr, "\n"); + va_end(vargs); + + exit(1); + /*NOTREACHED*/ + assert(0); +} + +/* Search the path for the client program */ +static const char *find_client(const char *clientname) +{ + static char fullname[PATH_MAX]; + const char *path = getenv("PATH"); + const char *colon; + + while (path) { + if ((colon = strchr(path, ':')) == NULL) { + strcpy(fullname, path); + path = NULL; + } else { + memcpy(fullname, path, colon - path); + fullname[colon - path] = '\0'; + path = colon + 1; + } + + strcat(fullname, "/"); + strcat(fullname, clientname); + + if (access(fullname, R_OK|X_OK) == 0) + return fullname; + } + + return clientname; +} + +/* Examine the client and work out which platform it is for */ +static const char *select_platform(const char *clientname) +{ + int fd; + char header[4096]; + ssize_t n_bytes; + const char *platform = NULL; + + VG_(debugLog)(2, "launcher", "selecting platform for '%s'\n", clientname); + + if (strchr(clientname, '/') == NULL) + clientname = find_client(clientname); + + if ((fd = open(clientname, O_RDONLY)) < 0) + return NULL; + // barf("open(%s): %s", clientname, strerror(errno)); + + n_bytes = read(fd, header, sizeof(header)); + close(fd); + if (n_bytes < 2) { + return NULL; + } + + if (header[0] == '#' && header[1] == '!') { + int i = 2; + char *interp = (char *)header + 2; + + // Skip whitespace. + while (1) { + if (i == n_bytes) return NULL; + if (' ' != header[i] && '\t' == header[i]) break; + i++; + } + + // Get the interpreter name. + interp = &header[i]; + while (1) { + if (i == n_bytes) break; + if (isspace(header[i])) break; + i++; + } + if (i == n_bytes) return NULL; + header[i] = '\0'; + + platform = select_platform(interp); + + } else if (n_bytes >= SELFMAG && memcmp(header, ELFMAG, SELFMAG) == 0) { + + if ((size_t)n_bytes >= sizeof(Elf32_Ehdr) && header[EI_CLASS] == ELFCLASS32) { + const Elf32_Ehdr *ehdr = (Elf32_Ehdr *)header; + + if (header[EI_DATA] == ELFDATA2LSB) { + if (ehdr->e_machine == EM_386 && + ehdr->e_ident[EI_OSABI] == ELFOSABI_FREEBSD) { + platform = "x86-freebsd"; + } + } + } else if ((size_t)n_bytes >= sizeof(Elf64_Ehdr) && header[EI_CLASS] == ELFCLASS64) { + const Elf64_Ehdr *ehdr = (Elf64_Ehdr *)header; + + if (header[EI_DATA] == ELFDATA2LSB) { + if (ehdr->e_machine == EM_X86_64 && + ehdr->e_ident[EI_OSABI] == ELFOSABI_FREEBSD) { + platform = "amd64-freebsd"; + } + } + } + } + + VG_(debugLog)(2, "launcher", "selected platform '%s'\n", + platform ? platform : "unknown"); + + return platform; +} + +/* Where we expect to find all our aux files */ +static const char *valgrind_lib = VG_LIBDIR; + +int main(int argc, char** argv, char** envp) +{ + int i, j, loglevel, r; + const char *toolname = NULL; + const char *clientname = NULL; + const char *platform; + const char *default_platform; + const char *cp; + char *toolfile; + char launcher_name[PATH_MAX+1]; + char* new_line; + char** new_env; + int oid[4]; + vki_size_t len; + + /* Start the debugging-log system ASAP. First find out how many + "-d"s were specified. This is a pre-scan of the command line. + At the same time, look for the tool name. */ + loglevel = 0; + for (i = 1; i < argc; i++) { + if (argv[i][0] != '-') { + clientname = argv[i]; + break; + } + if (0 == strcmp(argv[i], "--")) { + if (i+1 < argc) + clientname = argv[i+1]; + break; + } + if (0 == strcmp(argv[i], "-d")) + loglevel++; + if (0 == strncmp(argv[i], "--tool=", 7)) + toolname = argv[i] + 7; + } + + /* ... and start the debug logger. Now we can safely emit logging + messages all through startup. */ + VG_(debugLog_startup)(loglevel, "Stage 1"); + + /* Make sure we know which tool we're using */ + if (toolname) { + VG_(debugLog)(1, "launcher", "tool '%s' requested\n", toolname); + } else { + VG_(debugLog)(1, "launcher", + "no tool requested, defaulting to 'memcheck'\n"); + toolname = "memcheck"; + } + + /* Select a platform to use if we can't decide that by looking at + the executable (eg because it's a shell script). Note that the + default_platform is not necessarily either the primary or + secondary build target. Instead it's chosen to maximise the + chances that /bin/sh will work on it. Hence for a primary + target of ppc64-linux we still choose ppc32-linux as the default + target, because on most ppc64-linux setups, the basic /bin, + /usr/bin, etc, stuff is built in 32-bit mode, not 64-bit + mode. */ + if (0==strcmp(VG_PLATFORM,"x86-freebsd")) + default_platform = "x86-freebsd"; + else if (0==strcmp(VG_PLATFORM,"amd64-freebsd")) + default_platform = "amd64-freebsd"; + else + barf("Unknown VG_PLATFORM '%s'", VG_PLATFORM); + + /* Work out what platform to use, or use the default platform if + not possible. */ + if (clientname == NULL) { + VG_(debugLog)(1, "launcher", + "no client specified, defaulting platform to '%s'\n", + default_platform); + platform = default_platform; + } else if ((platform = select_platform(clientname)) != NULL) { + VG_(debugLog)(1, "launcher", "selected platform '%s'\n", platform); + } else { + VG_(debugLog)(1, "launcher", + "no platform detected, defaulting platform to '%s'\n", + default_platform); + platform = default_platform; + } + + /* Figure out the name of this executable (viz, the launcher), so + we can tell stage2. stage2 will use the name for recursive + invocations of valgrind on child processes. */ + memset(launcher_name, 0, PATH_MAX+1); + + oid[0] = CTL_KERN; + oid[1] = KERN_PROC; + oid[2] = KERN_PROC_PATHNAME; + oid[3] = getpid(); + len = PATH_MAX; + r = sysctl(oid, 4, launcher_name, &len, 0, 0); + if (r != 0) { + fprintf(stderr, "valgrind: warning (non-fatal): " + "sysctl(\"kern.proc.pathname\") failed.\n"); + fprintf(stderr, "valgrind: continuing, however --trace-children=yes " + "will not work.\n"); + } + + /* tediously augment the env: VALGRIND_LAUNCHER=launcher_name */ + new_line = malloc(strlen(VALGRIND_LAUNCHER) + 1 + + strlen(launcher_name) + 1); + if (new_line == NULL) + barf("malloc of new_line failed."); + strcpy(new_line, VALGRIND_LAUNCHER); + strcat(new_line, "="); + strcat(new_line, launcher_name); + + for (j = 0; envp[j]; j++) + ; + new_env = malloc((j+2) * sizeof(char*)); + if (new_env == NULL) + barf("malloc of new_env failed."); + for (i = 0; i < j; i++) + new_env[i] = envp[i]; + new_env[i++] = new_line; + new_env[i++] = NULL; + assert(i == j+2); + + /* Establish the correct VALGRIND_LIB. */ + cp = getenv(VALGRIND_LIB); + + if (cp != NULL) + valgrind_lib = cp; + + /* Build the stage2 invocation, and execve it. Bye! */ + toolfile = malloc(strlen(valgrind_lib) + strlen(toolname) + strlen(platform) + 3); + if (toolfile == NULL) + barf("malloc of toolfile failed."); + sprintf(toolfile, "%s/%s-%s", valgrind_lib, toolname, platform); + + VG_(debugLog)(1, "launcher", "launching %s\n", toolfile); + + execve(toolfile, argv, new_env); + + fprintf(stderr, "valgrind: failed to start tool '%s' for platform '%s': %s\n", + toolname, platform, strerror(errno)); + + exit(1); +} diff --git a/coregrind/link_tool_exe_freebsd.in b/coregrind/link_tool_exe_freebsd.in new file mode 100755 index 0000000000..b4df4622c1 --- /dev/null +++ b/coregrind/link_tool_exe_freebsd.in @@ -0,0 +1,82 @@ +#! @PERL@ + +# This script handles linking the tool executables on FreeBSD, +# statically and at an alternative load address. +# +# Linking statically sidesteps all sorts of complications to do with +# having two copies of the dynamic linker (valgrind's and the +# client's) coexisting in the same process. The alternative load +# address is needed because Valgrind itself will load the client at +# whatever address it specifies, which is almost invariably the +# default load address. Hence we can't allow Valgrind itself (viz, +# the tool executable) to be loaded at that address. +# +# Unfortunately there's no standard way to do 'static link at +# alternative address', so these link_tool_exe_*.in scripts handle +# the per-platform hoop-jumping. +# +# What we get passed here is: +# first arg +# the alternative load address +# all the rest of the args +# the compiler invocation to do the final link, that +# the build system would have done, left to itself +# +# We just let the script 'die' if something is wrong, rather than do +# proper error reporting. We don't expect the users to run this +# directly. It is only run as part of the build process, with +# carefully constrained inputs. +# +# FreeBSD specific complications: +# +# - in the initial version of this file, the linker(s) it was targeted +# at supported only -Ttext to load the code at an alternative address, +# and did not require removing the build notes in order to function +# correctly, so the work done by configure to determine what should go +# into the FLAG_T_TEXT was ignored. +# +# - LLVM's ld.lld, for at least versions 8.0 (shipping with FreeBSD 12.1) +# and 9.0 support the -Ttext option and behave as desired. As of +# LLVM ld.lld version 10.0 a breaking change made -Ttext unusable, +# however the --image-base option has the desired semantics. +# It turns out that ld.lld has supported --image-base since at least +# as far back as version 8.0. +# +# So: what we actually do: +# +# pass the specified command to the linker as-is, except, add +# "-static" and the value of FLAG_T_TEXT as determined by configure. +# Previously we did this by adding these options after the first +# word of the rest of the arguments, which works in the common case +# when it's something like "gcc". But the linker invocation itself +# might be multiple words, say if it's "ccache gcc". So we now put +# the new options at the end instead. +# + +use warnings; +use strict; + +# expect at least: alt-load-address gcc -o foo bar.o +die "Not enough arguments" + if (($#ARGV + 1) < 5); + +my $ala = $ARGV[0]; +shift; # Remove $ala from @ARGV + +# check for plausible-ish alt load address +die "Bogus alt-load address" + if (length($ala) < 3 || index($ala, "0x") != 0); + +my $cmd = join(" ", @ARGV, "-static -Wl,@FLAG_T_TEXT@=$ala"); + +#print "link_tool_exe_freebsd: $cmd\n"; + + +# Execute the command: +my $r = system("$cmd"); + +if ($r == 0) { + exit 0; +} else { + exit 1; +} diff --git a/coregrind/m_dispatch/dispatch-amd64-freebsd.S b/coregrind/m_dispatch/dispatch-amd64-freebsd.S new file mode 100644 index 0000000000..db4dccac76 --- /dev/null +++ b/coregrind/m_dispatch/dispatch-amd64-freebsd.S @@ -0,0 +1,321 @@ + +/*--------------------------------------------------------------------*/ +/*--- The core dispatch loop, for jumping to a code address. ---*/ +/*--- dispatch-amd64-freebsd.S ---*/ +/*--------------------------------------------------------------------*/ + +/* + This file is part of Valgrind, a dynamic binary instrumentation + framework. + + Copyright (C) 2000-2017 Julian Seward + js...@ac... + Copyright (C) 2018-2021 Paul Floyd + pj...@wa... + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, see <http://www.gnu.org/licenses/>. + + The GNU General Public License is contained in the file COPYING. +*/ + +#include "pub_core_basics_asm.h" + +#if defined(VGP_amd64_freebsd) + +#include "pub_core_dispatch_asm.h" +#include "pub_core_transtab_asm.h" +#include "libvex_guest_offsets.h" /* for OFFSET_amd64_RIP */ + + +/*------------------------------------------------------------*/ +/*--- ---*/ +/*--- The dispatch loop. VG_(disp_run_translations) is ---*/ +/*--- used to run all translations, ---*/ +/*--- including no-redir ones. ---*/ +/*--- ---*/ +/*------------------------------------------------------------*/ + +/*----------------------------------------------------*/ +/*--- Entry and preamble (set everything up) ---*/ +/*----------------------------------------------------*/ + +/* signature: +void VG_(disp_run_translations)( UWord* two_words, + void* guest_state, + Addr host_addr ); +*/ +.text +.globl VG_(disp_run_translations) +.type VG_(disp_run_translations), @function +VG_(disp_run_translations): + /* %rdi holds two_words */ + /* %rsi holds guest_state */ + /* %rdx holds host_addr */ + + /* The preamble */ + + /* Save integer registers, since this is a pseudo-function. */ + pushq %rax + pushq %rbx + pushq %rcx + pushq %rdx + pushq %rsi + pushq %rbp + pushq %r8 + pushq %r9 + pushq %r10 + pushq %r11 + pushq %r12 + pushq %r13 + pushq %r14 + pushq %r15 + /* %rdi must be saved last */ + pushq %rdi + + /* Get the host CPU in the state expected by generated code. */ + + /* set host FPU control word to the default mode expected + by VEX-generated code. See comments in libvex.h for + more info. */ + finit + pushq $0x027F + fldcw (%rsp) + addq $8, %rsp + + /* set host SSE control word to the default mode expected + by VEX-generated code. */ + pushq $0x1F80 + ldmxcsr (%rsp) + addq $8, %rsp + + /* set dir flag to known value */ + cld + + /* Set up the guest state pointer */ + movq %rsi, %rbp + + /* and jump into the code cache. Chained translations in + the code cache run, until for whatever reason, they can't + continue. When that happens, the translation in question + will jump (or call) to one of the continuation points + VG_(cp_...) below. */ + jmpq *%rdx + /*NOTREACHED*/ + +/*----------------------------------------------------*/ +/*--- Postamble and exit. ---*/ +/*----------------------------------------------------*/ + +postamble: + /* At this point, %rax and %rdx contain two + words to be returned to the caller. %rax + holds a TRC value, and %rdx optionally may + hold another word (for CHAIN_ME exits, the + address of the place to patch.) */ + + /* We're leaving. Check that nobody messed with %mxcsr + or %fpucw. We can't mess with %rax or %rdx here as they + hold the tentative return values, but any others are OK. */ +#if !defined(ENABLE_INNER) + /* This check fails for self-hosting, so skip in that case */ + pushq $0 + fstcw (%rsp) + cmpl $0x027F, (%rsp) + popq %r15 /* get rid of the word without trashing %rflags */ + jnz invariant_violation +#endif + pushq $0 + stmxcsr (%rsp) + andl $0xFFFFFFC0, (%rsp) /* mask out status flags */ + cmpl $0x1F80, (%rsp) + popq %r15 + jnz invariant_violation + /* otherwise we're OK */ + jmp remove_frame +invariant_violation: + movq $VG_TRC_INVARIANT_FAILED, %rax + movq $0, %rdx + +remove_frame: + /* Pop %rdi, stash return values */ + popq %rdi + movq %rax, 0(%rdi) + movq %rdx, 8(%rdi) + /* Now pop everything else */ + popq %r15 + popq %r14 + popq %r13 + popq %r12 + popq %r11 + popq %r10 + popq %r9 + popq %r8 + popq %rbp + popq %rsi + popq %rdx + popq %rcx + popq %rbx + popq %rax + ret + +/*----------------------------------------------------*/ +/*--- Continuation points ---*/ +/*----------------------------------------------------*/ + +/* ------ Chain me to slow entry point ------ */ +.global VG_(disp_cp_chain_me_to_slowEP) +VG_(disp_cp_chain_me_to_slowEP): + /* We got called. The return address indicates + where the patching needs to happen. Collect + the return address and, exit back to C land, + handing the caller the pair (Chain_me_S, RA) */ + movq $VG_TRC_CHAIN_ME_TO_SLOW_EP, %rax + popq %rdx + /* 10 = movabsq $VG_(disp_chain_me_to_slowEP), %r11; + 3 = call *%r11 */ + subq $10+3, %rdx + jmp postamble + +/* ------ Chain me to fast entry point ------ */ +.global VG_(disp_cp_chain_me_to_fastEP) +VG_(disp_cp_chain_me_to_fastEP): + /* We got called. The return address indicates + where the patching needs to happen. Collect + the return address and, exit back to C land, + handing the caller the pair (Chain_me_F, RA) */ + movq $VG_TRC_CHAIN_ME_TO_FAST_EP, %rax + popq %rdx + /* 10 = movabsq $VG_(disp_chain_me_to_fastEP), %r11; + 3 = call *%r11 */ + subq $10+3, %rdx + jmp postamble + +/* ------ Indirect but boring jump ------ */ +.global VG_(disp_cp_xindir) +VG_(disp_cp_xindir): + /* Where are we going? */ + movq OFFSET_amd64_RIP(%rbp), %rax // "guest" + + /* stats only */ + addl $1, VG_(stats__n_xIndirs_32) + + // LIVE: %rbp (guest state ptr), %rax (guest address to go to). + // We use 4 temporaries: + // %r9 (to point at the relevant FastCacheSet), + // %r10, %r11 and %r12 (scratch). + + /* Try a fast lookup in the translation cache. This is pretty much + a handcoded version of VG_(lookupInFastCache). */ + + // Compute %r9 = VG_TT_FAST_HASH(guest) + movq %rax, %r9 // guest + shrq $VG_TT_FAST_BITS, %r9 // (guest >> VG_TT_FAST_BITS) + xorq %rax, %r9 // (guest >> VG_TT_FAST_BITS) ^ guest + andq $VG_TT_FAST_MASK, %r9 // setNo + + // Compute %r9 = &VG_(tt_fast)[%r9] + shlq $VG_FAST_CACHE_SET_BITS, %r9 // setNo * sizeof(FastCacheSet) + movabsq $VG_(tt_fast), %r10 // &VG_(tt_fast)[0] + leaq (%r10, %r9), %r9 // &VG_(tt_fast)[setNo] + + // LIVE: %rbp (guest state ptr), %rax (guest addr), %r9 (cache set) + // try way 0 + cmpq %rax, FCS_g0(%r9) // cmp against .guest0 + jnz 1f + // hit at way 0 + jmp *FCS_h0(%r9) // goto .host0 + ud2 + +1: // try way 1 + cmpq %rax, FCS_g1(%r9) // cmp against .guest1 + jnz 2f + // hit at way 1; swap upwards + /* stats only */ + addl $1, VG_(stats__n_xIndir_hits1_32) + movq FCS_g0(%r9), %r10 // r10 = old .guest0 + movq FCS_h0(%r9), %r11 // r11 = old .host0 + movq FCS_h1(%r9), %r12 // r12 = old .host1 + movq %rax, FCS_g0(%r9) // new .guest0 = guest + movq %r12, FCS_h0(%r9) // new .host0 = old .host1 + movq %r10, FCS_g1(%r9) // new .guest1 = old .guest0 + movq %r11, FCS_h1(%r9) // new .host1 = old .host0 + jmp *%r12 // goto old .host1 a.k.a. new .host0 + ud2 + +2: // try way 2 + cmpq %rax, FCS_g2(%r9) // cmp against .guest2 + jnz 3f + // hit at way 2; swap upwards + /* stats only */ + addl $1, VG_(stats__n_xIndir_hits2_32) + movq FCS_g1(%r9), %r10 + movq FCS_h1(%r9), %r11 + movq FCS_h2(%r9), %r12 + movq %rax, FCS_g1(%r9) + movq %r12, FCS_h1(%r9) + movq %r10, FCS_g2(%r9) + movq %r11, FCS_h2(%r9) + jmp *%r12 + ud2 + +3: // try way 3 + cmpq %rax, FCS_g3(%r9) // cmp against .guest3 + jnz 4f + // hit at way 3; swap upwards + /* stats only */ + addl $1, VG_(stats__n_xIndir_hits3_32) + movq FCS_g2(%r9), %r10 + movq FCS_h2(%r9), %r11 + movq FCS_h3(%r9), %r12 + movq %rax, FCS_g2(%r9) + movq %r12, FCS_h2(%r9) + movq %r10, FCS_g3(%r9) + movq %r11, FCS_h3(%r9) + jmp *%r12 + ud2 + +4: // fast lookup failed + /* stats only */ + addl $1, VG_(stats__n_xIndir_misses_32) + + movq $VG_TRC_INNER_FASTMISS, %rax + movq $0, %rdx + jmp postamble + +/* ------ Assisted jump ------ */ +.global VG_(disp_cp_xassisted) +VG_(disp_cp_xassisted): + /* %rbp contains the TRC */ + movq %rbp, %rax + movq $0, %rdx + jmp postamble + +/* ------ Event check failed ------ */ +.global VG_(disp_cp_evcheck_fail) +VG_(disp_cp_evcheck_fail): + movq $VG_TRC_INNER_COUNTERZERO, %rax + movq $0, %rdx + jmp postamble + + +.size VG_(disp_run_translations), .-VG_(disp_run_translations) + +#endif // defined(VGP_amd64_freebsd) + +/* Let the linker know we don't need an executable stack */ +MARK_STACK_NO_EXEC + +/*--------------------------------------------------------------------*/ +/*--- end ---*/ +/*--------------------------------------------------------------------*/ diff --git a/coregrind/m_dispatch/dispatch-x86-freebsd.S b/coregrind/m_dispatch/dispatch-x86-freebsd.S new file mode 100644 index 0000000000..667bfcd96a --- /dev/null +++ b/coregrind/m_dispatch/dispatch-x86-freebsd.S @@ -0,0 +1,251 @@ + +/*--------------------------------------------------------------------*/ +/*--- The core dispatch loop, for jumping to a code address. ---*/ +/*--- dispatch-x86-freebsd.S ---*/ +/*--------------------------------------------------------------------*/ + +/* + This file is part of Valgrind, a dynamic binary instrumentation + framework. + + Copyright (C) 2000-2012 Julian Seward + js...@ac... + Copyright (C) 2018-2021 Paul Floyd + pj...@wa... + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, see <http://www.gnu.org/licenses/>. + + The GNU General Public License is contained in the file COPYING. +*/ + +#include "pub_core_basics_asm.h" + +#if defined(VGP_x86_freebsd) + +#include "pub_core_dispatch_asm.h" +#include "pub_core_transtab_asm.h" +#include "libvex_guest_offsets.h" /* for OFFSET_x86_EIP */ + + +/*------------------------------------------------------------*/ +/*--- ---*/ +/*--- The dispatch loop. VG_(disp_run_translations) is ---*/ +/*--- used to run all translations, ---*/ +/*--- including no-redir ones. ---*/ +/*--- ---*/ +/*------------------------------------------------------------*/ + +/*----------------------------------------------------*/ +/*--- Entry and preamble (set everything up) ---*/ +/*----------------------------------------------------*/ + +/* signature: +void VG_(disp_run_translations)( UWord* two_words, + void* guest_state, + Addr host_addr ); +*/ +.text +.globl VG_(disp_run_translations) +.type VG_(disp_run_translations), @function +VG_(disp_run_translations): + /* 0(%esp) holds our return address. */ + /* 4(%esp) holds two_words */ + /* 8(%esp) holds guest_state */ + /* 12(%esp) holds host_addr */ + + /* The preamble */ + + /* Save integer registers, since this is a pseudo-function. */ + pushl %eax + pushl %ebx + pushl %ecx + pushl %edx + pushl %esi + pushl %edi + pushl %ebp + + /* 28+4(%esp) holds two_words */ + /* 28+8(%esp) holds guest_state */ + /* 28+12(%esp) holds host_addr */ + + /* Get the host CPU in the state expected by generated code. */ + + /* set host FPU control word to the default mode expected + by VEX-generated code. See comments in libvex.h for + more info. */ + finit + pushl $0x027F + fldcw (%esp) + addl $4, %esp + + /* set host SSE control word to the default mode expected + by VEX-generated code. */ + cmpl $0, VG_(machine_x86_have_mxcsr) + jz L1 + pushl $0x1F80 + ldmxcsr (%esp) + addl $4, %esp +L1: + /* set dir flag to known value */ + cld + + /* Set up the guest state pointer */ + movl 28+8(%esp), %ebp + + /* and jump into the code cache. Chained translations in + the code cache run, until for whatever reason, they can't + continue. When that happens, the translation in question + will jump (or call) to one of the continuation points + VG_(cp_...) below. */ + jmpl *28+12(%esp) + /*NOTREACHED*/ + +/*----------------------------------------------------*/ +/*--- Postamble and exit. ---*/ +/*----------------------------------------------------*/ + +postamble: + /* At this point, %eax and %edx contain two + words to be returned to the caller. %eax + holds a TRC value, and %edx optionally may + hold another word (for CHAIN_ME exits, the + address of the place to patch.) */ + + /* We're leaving. Check that nobody messed with %mxcsr + or %fpucw. We can't mess with %eax or %edx here as they + holds the tentative return value, but any others are OK. */ +#if !defined(ENABLE_INNER) + /* This check fails for self-hosting, so skip in that case */ + pushl $0 + fstcw (%esp) + cmpl $0x027F, (%esp) + popl %esi /* get rid of the word without trashing %eflags */ + jnz invariant_violation +#endif +# cmpl $0, VG_(machine_x86_have_mxcsr) + jz L2 + pushl $0 + stmxcsr (%esp) + andl $0xFFFFFFC0, (%esp) /* mask out status flags */ + cmpl $0x1F80, (%esp) + popl %esi + jnz invariant_violation +L2: /* otherwise we're OK */ + jmp remove_frame +invariant_violation: + movl $VG_TRC_INVARIANT_FAILED, %eax + movl $0, %edx + +remove_frame: + /* Stash return values */ + movl 28+4(%esp), %edi /* two_words */ + movl %eax, 0(%edi) + movl %edx, 4(%edi) + /* Restore int regs and return. */ + popl %ebp + popl %edi + popl %esi + popl %edx + popl %ecx + popl %ebx + popl %eax + ret + +/*----------------------------------------------------*/ +/*--- Continuation points ---*/ +/*----------------------------------------------------*/ + +/* ------ Chain me to slow entry point ------ */ +.global VG_(disp_cp_chain_me_to_slowEP) +VG_(disp_cp_chain_me_to_slowEP): + /* We got called. The return address indicates + where the patching needs to happen. Collect + the return address and, exit back to C land, + handing the caller the pair (Chain_me_S, RA) */ + movl $VG_TRC_CHAIN_ME_TO_SLOW_EP, %eax + popl %edx + /* 5 = movl $VG_(disp_chain_me_to_slowEP), %edx; + 2 = call *%edx */ + subl $5+2, %edx + jmp postamble + +/* ------ Chain me to fast entry point ------ */ +.global VG_(disp_cp_chain_me_to_fastEP) +VG_(disp_cp_chain_me_to_fastEP): + /* We got called. The return address indicates + where the patching needs to happen. Collect + the return address and, exit back to C land, + handing the caller the pair (Chain_me_F, RA) */ + movl $VG_TRC_CHAIN_ME_TO_FAST_EP, %eax + popl %edx + /* 5 = movl $VG_(disp_chain_me_to_fastEP), %edx; + 2 = call *%edx */ + subl $5+2, %edx + jmp postamble + +/* ------ Indirect but boring jump ------ */ +.global VG_(disp_cp_xindir) +VG_(disp_cp_xindir): + /* Where are we going? */ + movl OFFSET_x86_EIP(%ebp), %eax + + /* stats only */ + addl $1, VG_(stats__n_xIndirs_32) + + /* try a fast lookup in the translation cache */ + movl %eax, %ebx /* next guest addr */ + andl $VG_TT_FAST_MASK, %ebx /* entry# */ + movl 0+VG_(tt_fast)(,%ebx,8), %esi /* .guest */ + movl 4+VG_(tt_fast)(,%ebx,8), %edi /* .host */ + cmpl %eax, %esi + jnz fast_lookup_failed + + /* Found a match. Jump to .host. */ + jmp *%edi + ud2 /* persuade insn decoders not to speculate past here */ + +fast_lookup_failed: + /* stats only */ + addl $1, VG_(stats__n_xIndir_misses_32) + + movl $VG_TRC_INNER_FASTMISS, %eax + movl $0, %edx + jmp postamble + +/* ------ Assisted jump ------ */ +.global VG_(disp_cp_xassisted) +VG_(disp_cp_xassisted): + /* %ebp contains the TRC */ + movl %ebp, %eax + movl $0, %edx + jmp postamble + +/* ------ Event check failed ------ */ +.global VG_(disp_cp_evcheck_fail) +VG_(disp_cp_evcheck_fail): + movl $VG_TRC_INNER_COUNTERZERO, %eax + movl $0, %edx + jmp postamble + + +.size VG_(disp_run_translations), .-VG_(disp_run_translations) + +#endif // defined(VGP_x86_freebsd) + +/* Let the linker know we don't need an executable stack */ +MARK_STACK_NO_EXEC + +/*--------------------------------------------------------------------*/ +/*--- end ---*/ +/*--------------------------------------------------------------------*/ diff --git a/coregrind/m_initimg/initimg-freebsd.c b/coregrind/m_initimg/initimg-freebsd.c new file mode 100644 index 0000000000..d19186a42c --- /dev/null +++ b/coregrind/m_initimg/initimg-freebsd.c @@ -0,0 +1,979 @@ + +/*--------------------------------------------------------------------*/ +/*--- Startup: create initial process image on FreeBSD ---*/ +/*--- initimg-freebsd.c ---*/ +/*--------------------------------------------------------------------*/ + +/* + This file is part of Valgrind, a dynamic binary instrumentation + framework. + + Copyright (C) 2000-2009 Julian Seward + js...@ac... + Copyright (C) 2018-2021 Paul Floyd + pj...@wa... + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, see <http://www.gnu.org/licenses/>. + + The GNU General Public License is contained in the file COPYING. +*/ + +#if defined(VGO_freebsd) + +#include "pub_core_basics.h" +#include "pub_core_vki.h" +#include "pub_core_debuglog.h" +#include "pub_core_libcbase.h" +#include "pub_core_libcassert.h" +#include "pub_core_libcfile.h" +#include "pub_core_libcproc.h" +#include "pub_core_libcprint.h" +#include "pub_core_xarray.h" +#include "pub_core_clientstate.h" +#include "pub_core_aspacemgr.h" +#include "pub_core_mallocfree.h" +#include "pub_core_machine.h" +#include "pub_core_ume.h" +#include "pub_core_options.h" +#include "pub_core_syscall.h" +#include "pub_core_tooliface.h" /* VG_TRACK */ +#include "pub_core_threadstate.h" /* ThreadArchState */ +#include "pub_core_pathscan.h" +#include "pub_core_initimg.h" /* self */ + +/* --- !!! --- EXTERNAL HEADERS start --- !!! --- */ +/* This is for ELF types etc, and also the AT_ constants. */ +#include <elf.h> +/* --- !!! --- EXTERNAL HEADERS end --- !!! --- */ + + +/*====================================================================*/ +/*=== Loading the client ===*/ +/*====================================================================*/ + +/* Load the client whose name is VG_(argv_the_exename). */ + +static void load_client ( /*OUT*/ExeInfo* info, + /*OUT*/Addr* client_ip, + /*OUT*/Addr* client_toc) +{ + const HChar* exe_name; + Int ret; + SysRes res; + + vg_assert( VG_(args_the_exename) != NULL); + exe_name = VG_(find_executable)( VG_(args_the_exename) ); + + if (!exe_name) { + VG_(printf)("valgrind: %s: command not found\n", VG_(args_the_exename)); + VG_(exit)(127); // 127 is Posix NOTFOUND + } + + VG_(memset)(info, 0, sizeof(*info)); + ret = VG_(do_exec)(exe_name, info); + if (ret < 0) { + VG_(printf)("valgrind: could not execute '%s'\n", exe_name); + VG_(exit)(1); + } + + // The client was successfully loaded! Continue. + + /* Get hold of a file descriptor which refers to the client + executable. This is needed for attaching to GDB. */ + res = VG_(open)(exe_name, VKI_O_RDONLY, VKI_S_IRUSR); + if (!sr_isError(res)) + VG_(cl_exec_fd) = sr_Res(res); + + /* Copy necessary bits of 'info' that were filled in */ + *client_ip = info->init_ip; + *client_toc = info->init_toc; + VG_(brk_base) = VG_(brk_limit) = VG_PGROUNDUP(info->brkbase); +} + + +/*====================================================================*/ +/*=== Setting up the client's environment ===*/ +/*====================================================================*/ + +/* Prepare the client's environment. This is basically a copy of our + environment, except: + + LD_PRELOAD=$VALGRIND_LIB/vgpreload_core-PLATFORM.so: + ($VALGRIND_LIB/vgpreload_TOOL-PLATFORM.so:)? + $LD_PRELOAD + + If this is missing, then it is added. + + Also, remove any binding for VALGRIND_LAUNCHER=. The client should + not be able to see this. + + If this needs to handle any more variables it should be hacked + into something table driven. The copy is VG_(malloc)'d space. +*/ +static HChar** setup_client_env ( HChar** origenv, const HChar* toolname) +{ + vg_assert(origenv); + vg_assert(toolname); + + const HChar* preload_core = "vgpreload_core"; + const HChar* ld_preload = "LD_PRELOAD="; + const HChar* v_launcher = VALGRIND_LAUNCHER "="; + Int ld_preload_len = VG_(strlen)( ld_preload ); + Int v_launcher_len = VG_(strlen)( v_launcher ); + Bool ld_preload_done = False; +#if defined(VGP_x86_freebsd) + const HChar* ld_32_preload = "LD_32_PRELOAD="; + Int ld_32_preload_len = VG_(strlen)( ld_32_preload ); + Bool ld_32_preload_done = False; +#endif + Int vglib_len = VG_(strlen)(VG_(libdir)); + Bool debug = False; + + HChar** cpp; + HChar** ret; + HChar* preload_tool_path; + Int envc, i; + + /* Alloc space for the vgpreload_core.so path and vgpreload_<tool>.so + paths. We might not need the space for vgpreload_<tool>.so, but it + doesn't hurt to over-allocate briefly. The 16s are just cautious + slop. */ + Int preload_core_path_len = vglib_len + sizeof(preload_core) + + sizeof(VG_PLATFORM) + 16; + Int preload_tool_path_len = vglib_len + VG_(strlen)(toolname) + + sizeof(VG_PLATFORM) + 16; + Int preload_string_len = preload_core_path_len + preload_tool_path_len; + HChar* preload_string = VG_(malloc)("initimg-freebsd.sce.1", + preload_string_len); + /* Determine if there's a vgpreload_<tool>_<platform>.so file, and setup + preload_string. */ + preload_tool_path = VG_(malloc)("initimg-freebsd.sce.2", preload_tool_path_len); + VG_(snprintf)(preload_tool_path, preload_tool_path_len, + "%s/vgpreload_%s-%s.so", VG_(libdir), toolname, VG_PLATFORM); + if (VG_(access)(preload_tool_path, True/*r*/, False/*w*/, False/*x*/) == 0) { + VG_(snprintf)(preload_string, preload_string_len, "%s/%s-%s.so:%s", + VG_(libdir), preload_core, VG_PLATFORM, preload_tool_path); + } else { + VG_(snprintf)(preload_string, preload_string_len, "%s/%s-%s.so", + VG_(libdir), preload_core, VG_PLATFORM); + } + VG_(free)(preload_tool_path); + + VG_(debugLog)(2, "initimg", "preload_string:\n"); + VG_(debugLog)(2, "initimg", " \"%s\"\n", preload_string); + + /* Count the original size of the env */ + if (debug) VG_(printf)("\n\n"); + envc = 0; + for (cpp = origenv; cpp && *cpp; cpp++) { + envc++; + if (debug) VG_(printf)("XXXXXXXXX: BEFORE %s\n", *cpp); + } + + /* Allocate a new space */ + ret = VG_(malloc) ("initimg-freebsd.sce.3", + sizeof(HChar *) * (envc+2+1)); /* 2 new entries + NULL */ + + /* copy it over */ + for (cpp = ret; *origenv; ) { + if (debug) VG_(printf)("XXXXXXXXX: COPY %s\n", *origenv); + *cpp++ = *origenv++; + } + *cpp = NULL; + *(cpp + 1) = NULL; + + vg_assert(envc == (cpp - ret)); + + /* Walk over the new environment, mashing as we go */ + for (cpp = ret; cpp && *cpp; cpp++) { + if (VG_(memcmp)(*cpp, ld_preload, ld_preload_len) == 0) { + Int len = VG_(strlen)(*cpp) + preload_string_len; + HChar *cp = VG_(malloc)("initimg-freebsd.sce.4", len); + + VG_(snprintf)(cp, len, "%s%s:%s", + ld_preload, preload_string, (*cpp)+ld_preload_len); + + *cpp = cp; + + ld_preload_done = True; + } + if (debug) VG_(printf)("XXXXXXXXX: MASH %s\n", *cpp); + } + + /* Add the missing bits */ + if (!ld_preload_done) { + Int len = ld_preload_len + preload_string_len; + HChar *cp = VG_(malloc) ("initimg-freebsd.sce.5", len); + + VG_(snprintf)(cp, len, "%s%s", ld_preload, preload_string); + + ret[envc++] = cp; + if (debug) VG_(printf)("XXXXXXXXX: ADD %s\n", cp); + } + +#if defined(VGP_x86_freebsd) + /* If we're running a 32 bit binary, ld-elf32.so.1 may be looking for + * a different variable name. Or it might be a 32 bit ld-elf.so.1 in a + * chroot. Cover both cases. */ + if (VG_(is32on64)()) { + for (cpp = ret; cpp && *cpp; cpp++) { + if (VG_(memcmp)(*cpp, ld_32_preload, ld_32_preload_len) == 0) { + Int len = VG_(strlen)(*cpp) + preload_string_len; + HChar *cp = VG_(malloc)("initimg-freebsd.sce.4a", len); + vg_assert(cp); + + VG_(snprintf)(cp, len, "%s%s:%s", + ld_32_preload, preload_string, (*cpp)+ld_32_preload_len); + + *cpp = cp; + + ld_32_preload_done = True; + } + } + if (!ld_32_preload_done) { + Int len = ld_32_preload_len + preload_string_len; + HChar *cp = VG_(malloc) ("initimg-freebsd.sce.5a", len); + vg_assert(cp); + + VG_(snprintf)(cp, len, "%s%s", ld_32_preload, preload_string); + + ret[envc++] = cp; + } + } +#endif + + /* ret[0 .. envc-1] is live now. */ + /* Find and remove a binding for VALGRIND_LAUNCHER. */ + for (i = 0; i < envc; i++) + if (0 == VG_(memcmp)(ret[i], v_launcher, v_launcher_len)) + break; + + if (i < envc) { + for (; i < envc-1; i++) + ret[i] = ret[i+1]; + envc--; + } + + VG_(free)(preload_string); + ret[envc] = NULL; + + for (i = 0; i < envc; i++) { + if (debug) VG_(printf)("XXXXXXXXX: FINAL %s\n", ret[i]); + } + + return ret; +} + + +/*====================================================================*/ +/*=== Setting up the client's stack ===*/ +/*====================================================================*/ + +/* Add a string onto the string table, and return its address */ +static HChar *copy_str(HChar **tab, const HChar *str) +{ + HChar *cp = *tab; + HChar *orig = cp; + + while(*str) + *cp++ = *str++; + *cp++ = '\0'; + + if (0) + VG_(printf)("copied %p \"%s\" len %lld\n", (void*)orig, orig, (Long)(cp-orig)); + + *tab = cp; + + return orig; +} + + +/* ---------------------------------------------------------------- + + This sets up the client's initial stack, containing the args, + environment and aux vector. + + The format of the stack is: + + higher address +-----------------+ <- clstack_end + | | + : string table : + | | + +-----------------+ + | AT_NULL | + - - + | auxv | + +-----------------+ + | NULL | + - - + | envp | + +-----------------+ + | NULL | + - - + | argv | + +-----------------+ + | argc | + lower address +-----------------+ <- sp + | undefined | + : : + + Allocate and create the initial client stack. It is allocated down + from clstack_end, which was previously determined by the address + space manager. The returned value is the SP value for the client. + + The client's auxv is created by copying and modifying our own one. + + ---------------------------------------------------------------- */ + +struct auxv { + Word a_type; + union { + void *a_ptr; + Word a_val; + } u; +}; + +static +struct auxv *find_auxv(UWord* sp) +{ + sp++; // skip argc (Nb: is word-sized, not int-sized!) + + while (*sp != 0) // skip argv + sp++; + sp++; + + while (*sp != 0) // skip env + sp++; + sp++; + + return (struct auxv *)sp; +} + +static +Addr setup_client_stack( void* init_sp, + HChar** orig_envp, + const ExeInfo* info, + UInt** client_auxv, + Addr clstack_end, + SizeT clstack_max_size ) +{ + SysRes res; + HChar **cpp; + HChar *strtab; /* string table */ + HChar *stringbase; + Addr *ptr; + struct auxv *auxv; + const struct auxv *orig_auxv; + const struct auxv *cauxv; + unsigned stringsize; /* total size of strings in bytes */ + unsigned auxsize; /* total size of auxv in bytes */ + Int argc; /* total argc */ + Int envc; /* total number of env vars */ + unsigned stacksize; /* total client stack size */ + Addr client_SP; /* client stack base (initial SP) */ + Addr clstack_start; + Int i; + Bool have_exename; + + vg_assert(VG_IS_PAGE_ALIGNED(clstack_end+1)); + vg_assert( VG_(args_for_client) ); + + /* use our own auxv as a prototype */ + orig_auxv = find_auxv(init_sp); + + /* ==================== compute sizes ==================== */ + + /* first of all, work out how big the client stack will be */ + stringsize = 0; + have_exename = VG_(args_the_exename) != NULL; + + /* paste on the extra args if the loader needs them (ie, the #! + interpreter and its argument) */ + argc = 0; + if (info->interp_name != NULL) { + argc++; + stringsize += VG_(strlen)(info->interp_name) + 1; + } + if (info->interp_args != NULL) { + argc++; + stringsize += VG_(strlen)(info->interp_args) + 1; + } + + /* now scan the args we're given... */ + if (have_exename) + stringsize += VG_(strlen)( VG_(args_the_exename) ) + 1; + + for (i = 0; i < VG_(sizeXA)( VG_(args_for_client) ); i++) { + argc++; + stringsize += VG_(strlen)( * (HChar**) + VG_(indexXA)( VG_(args_for_client), i )) + + 1; + } + + /* ...and the environment */ + envc = 0; + for (cpp = orig_envp; cpp && *cpp; cpp++) { + envc++; + stringsize += VG_(strlen)(*cpp) + 1; + } + + /* now, how big is the auxv? */ + auxsize = sizeof(*auxv); /* there's always at least one entry: AT_NULL */ + for (cauxv = orig_auxv; cauxv->a_type != AT_NULL; cauxv++) { + auxsize += sizeof(*cauxv); + } + + /* OK, now we know how big the client stack is */ + stacksize = + sizeof(Word) + /* argc */ + (have_exename ? sizeof(HChar **) : 0) + /* argc[0] == exename */ + sizeof(HChar **)*argc + /* argv */ + sizeof(HChar **) + /* terminal NULL */ + sizeof(HChar **)*envc + /* envp */ + sizeof(HChar **) + /* terminal NULL */ + auxsize + /* auxv */ + VG_ROUNDUP(stringsize, sizeof(Word)); /* strings (aligned) */ + + if (0) VG_(printf)("stacksize = %u\n", stacksize); + + /* client_SP is the client's stack pointer */ + client_SP = clstack_end - stacksize; + client_SP = VG_ROUNDDN(client_SP, 16); /* make stack 16 byte aligned */ + + /* base of the string table (aligned) */ + stringbase = strtab = (HChar *)clstack_end + - VG_ROUNDUP(stringsize, sizeof(int)); + + clstack_start = VG_PGROUNDDN(client_SP); + + /* The max stack size */ + clstack_max_size = VG_PGROUNDUP(clstack_max_size); + + if (0) + VG_(printf)("stringsize=%u auxsize=%u stacksize=%u maxsize=0x%lx\n" + "clstack_start %p\n" + "clstack_end %p\n", + stringsize, auxsize, stacksize, clstack_max_size, + (void*)clstack_start, (void*)clstack_end); + + /* ==================== allocate space ==================== */ + + { + SizeT anon_size = clstack_end - clstack_start + 1; + SizeT resvn_size = clstack_max_size - anon_size; + Addr anon_start = clstack_start; + Addr resvn_start = anon_start - resvn_size; + SizeT inner_HACK = 0; + Bool ok; + + /* So far we've only accounted for space requirements down to the + stack pointer. If this target's ABI requires a redzone below + the stack pointer, we need to allocate an extra page, to + handle the worst case in which the stack pointer is almost at + the bottom of a page, and so there is insufficient room left + over to put the redzone in. In this case the simple thing to + do is allocate an extra page, by shrinking the reservation by + one page and growing the anonymous area by a corresponding + page. */ + vg_assert(VG_STACK_REDZONE_SZB >= 0); + vg_assert(VG_STACK_REDZONE_SZB < VKI_PAGE_SIZE); + if (VG_STACK_REDZONE_SZB > 0) { + vg_assert(resvn_size > VKI_PAGE_SIZE); + resvn_size -= VKI_PAGE_SIZE; + anon_start -= VKI_PAGE_SIZE; + anon_size += VKI_PAGE_SIZE; + } + + vg_assert(VG_IS_PAGE_ALIGNED(anon_size)); + vg_assert(VG_IS_PAGE_ALIGNED(resvn_size)); + vg_assert(VG_IS_PAGE_ALIGNED(anon_start)); + vg_assert(VG_IS_PAGE_ALIGNED(resvn_start)); + vg_assert(resvn_start == clstack_end + 1 - clstack_max_size); + +# ifdef ENABLE_INNER + inner_HACK = 1024*1024; // create 1M non-fault-extending stack +# endif + + if (0) + VG_(printf)("%#lx 0x%lx %#lx 0x%lx\n", + resvn_start, resvn_size, anon_start, anon_size); + + /* Create a shrinkable reservation followed by an anonymous + segment. Together these constitute a growdown stack. */ + res = VG_(mk_SysRes_Error)(0); + ok = VG_(am_create_reservation)( + resvn_start, + resvn_size -inner_HACK, + SmUpper, + anon_size +inner_HACK + ); + if (ok) { + /* allocate a stack - mmap enough space for the stack */ + res = VG_(am_mmap_anon_fixed_client)( + anon_start -inner_HACK, + anon_size +inner_HACK, + VKI_PROT_READ|VKI_PROT_WRITE|VKI_PROT_EXEC + ); + } + if ((!ok) || sr_isError(res)) { + /* Allocation of the stack failed. We have to stop. */ + VG_(printf)("valgrind: " + "I failed to allocate space for the application's stack.\n"); + VG_(printf)("valgrind: " + "This may be the result of a very large --main-stacksize=\n"); + VG_(printf)("valgrind: setting. Cannot continue. Sorry.\n\n"); + VG_(exit)(1); + } + + vg_assert(ok); + vg_assert(!sr_isError(res)); + + /* Record stack extent -- needed for stack-change code. */ + VG_(clstk_start_base) = anon_start -inner_HACK; + VG_(clstk_end) = VG_(clstk_start_base) + anon_size +inner_HACK -1; + + } + + /* ==================== create client stack ==================== */ + + ptr = (Addr*)client_SP; + + /* --- client argc --- */ + *ptr++ = argc + (have_exename ? 1 : 0); + + /* --- client argv --- */ + if (info->interp_name) + *ptr++ = (Addr)copy_str(&strtab, info->interp_name); + if (info->interp_args) + *ptr++ = (Addr)copy_str(&strtab, info->interp_args); + + if (have_exename) + *ptr++ = (Addr)copy_str(&strtab, VG_(args_the_exename)); + + for (i = 0; i < VG_(sizeXA)( VG_(args_for_client) ); i++) { + *ptr++ = (Addr)copy_str( + &strtab, + * (HChar**) VG_(indexXA)( VG_(args_for_client), i ) + ); + } + *ptr++ = 0; + + /* --- envp --- */ + VG_(client_envp) = (HChar **)ptr; + for (cpp = orig_envp; cpp && *cpp; ptr++, cpp++) + *ptr = (Addr)copy_str(&strtab, *cpp); + *ptr++ = 0; + + /* --- auxv --- */ + auxv = (struct auxv *)ptr; + *client_auxv = (UInt *)auxv; +#if defined(VGP_x86_freebsd) + int* pagesizes = NULL; +#endif + + /* + * The PAGESIZES hack - PJF + * + * Normally a standalone application has a full auxv which, among + * many other things contains a vector of integers (PAGESIZES) + * of a platform dependent length (PAGESIZESLEN). On x86 the + * length is 2, on amd64 the length is 3 (there are other lengths + * for architectures not supported on Valgrind). + * + * When the dynamic loader executes it will run a routine + * static void init_pagesizes(Elf_Auxinfo **aux_info) + * (see /usr/src/libexec/rtld-elf/rltd.c). If the PAGESIZES info is in + * auxv, init_pagesizes will use that. However, normally this loop + * does not copy 'pointered' elements (because that would generate + * 'Invalid reads' in the guest). This means that the auxv that + * Valgrind provides to ldrt *doesn't* normally contain + * PAGESIZES. + * + * So init_pagesizes falls back to using sysctlnametomib/sysctl + * to read "hw.pagesizes". Unfortunately there seems to be a bug + * in this for an x86 executable compiled and running on an amd64 + * kernel. + * + * The application sees MAXPAGESLEN as 3 (from the amd64 headers) + * but the x86 kernel sees MAXPAGESLEN as 2. The routine that + * copies out the data for a sysctl sees this discrepancy and + * sets an ENOMEM error. So guest execution doesn't even get past + * executing the dynamic linker. + */ + + for (; orig_auxv->a_type != AT_NULL; auxv++, orig_auxv++) { + + /* copy the entry... */ + *auxv = *orig_auxv; + + /* + * ...and fix up / examine the copy + * in general there are thee possibilities for these items + * 1. copy it, a common case for scalars + * 2. synthesize, if the value that the host gets isn't what we want + * 3. ignore, usually the case for pointers to memory for the host + * the ignored items are just left commented out + */ + switch(auxv->a_type) { + + case AT_IGNORE: + case AT_PHENT: + case AT_PAGESZ: + case AT_FLAGS: + case AT_NOTELF: + case AT_UID: + case AT_EUID: + case AT_GID: + case AT_EGID: + case AT_STACKPROT: + case AT_NCPUS: + case AT_OSRELDATE: +#if (FREEBSD_VERS >= FREEBSD_11) + // FreeBSD 11+ also have HWCAP and HWCAP2 + case AT_EHDRFLAGS: +#endif + /* All these are pointerless, so we don't need to do + anything about them. */ + break; + // case AT_CANARYLEN: + // case AT_EXECPATH: + // case AT_CANARY: +#if defined(VGP_x86_freebsd) + case AT_PAGESIZESLEN: + if (!VG_(is32on64)()) { + VG_(debugLog)(2, "initimg", + "stomping auxv entry %llu\n", + (ULong)auxv->a_type); + auxv->a_type = AT_IGNORE; + } + break; + case AT_PAGESIZES: + if (VG_(is32on64)()) { + pagesizes = VG_(malloc)("initimg-freebsd.cpauxv.1", 2*sizeof(int)); + ... [truncated message content] |
|
From: Paul F. <pa...@so...> - 2021-10-09 10:52:49
|
https://sourceware.org/git/gitweb.cgi?p=valgrind.git;h=1bbd829adb5a192593543d7b0fc2fab154317ece commit 1bbd829adb5a192593543d7b0fc2fab154317ece Author: Paul Floyd <pj...@wa...> Date: Sat Oct 9 12:51:41 2021 +0200 FreeBSD support, patch 10 Missing new expected file Diff: --- memcheck/tests/dw4.stderr.exp-freebsd | 49 +++++++++++++++++++++++++++++++++++ 1 file changed, 49 insertions(+) diff --git a/memcheck/tests/dw4.stderr.exp-freebsd b/memcheck/tests/dw4.stderr.exp-freebsd new file mode 100644 index 0000000000..e396a43b8a --- /dev/null +++ b/memcheck/tests/dw4.stderr.exp-freebsd @@ -0,0 +1,49 @@ +Uninitialised byte(s) found during client check request + at 0x........: croak (dw4.c:32) + by 0x........: main (dw4.c:59) + Address 0x........ is 4 bytes inside a block of size ... alloc'd + at 0x........: malloc (vg_replace_malloc.c:...) + by 0x........: main (dw4.c:52) + +Uninitialised byte(s) found during client check request + at 0x........: croak (dw4.c:32) + by 0x........: main (dw4.c:61) + Location 0x........ is 0 bytes inside S2[0].i, + a global variable declared at dw4.c:47 + +Uninitialised byte(s) found during client check request + at 0x........: croak (dw4.c:32) + by 0x........: main (dw4.c:62) + Location 0x........ is 0 bytes inside local.i, + declared at dw4.c:51, in frame #1 of thread 1 + +Uninitialised byte(s) found during client check request + at 0x........: croak (dw4.c:32) + by 0x........: main (dw4.c:68) + Address 0x........ is in a rw- anonymous segment + +Uninitialised byte(s) found during client check request + at 0x........: croak (dw4.c:32) + by 0x........: main (dw4.c:82) + Address 0x........ is in a rw- mapped file valgrind-dw4-test.PID segment + +Uninitialised byte(s) found during client check request + at 0x........: croak (dw4.c:32) + by 0x........: main (dw4.c:87) + Address 0x........ is 0 bytes after the brk data segment limit 0x........ + +Uninitialised byte(s) found during client check request + at 0x........: croak (dw4.c:32) + by 0x........: main (dw4.c:89) + Address 0x........ is in the brk data segment 0x........-0x........ + +Uninitialised byte(s) found during client check request + at 0x........: croak (dw4.c:32) + by 0x........: main (dw4.c:91) + Address 0x........ is in the brk data segment 0x........-0x........ + +Unaddressable byte(s) found during client check request + at 0x........: croak (dw4.c:25) + by 0x........: main (dw4.c:93) + Address 0x........ is 1024 bytes after the brk data segment limit 0x........ + |
|
From: Paul F. <pa...@so...> - 2021-10-09 10:39:51
|
https://sourceware.org/git/gitweb.cgi?p=valgrind.git;h=7c5d720a2b67b19cd06210d83434295ae838ea89 commit 7c5d720a2b67b19cd06210d83434295ae838ea89 Author: Paul Floyd <pj...@wa...> Date: Sat Oct 9 12:37:17 2021 +0200 FreeBSD support, patch 10 memcheck No code changes. A few modified tests. Adds new FreeBSD specific tests. Diff: --- configure.ac | 11 + memcheck/tests/Makefile.am | 28 +- memcheck/tests/addressable.c | 3 + memcheck/tests/addressable.stderr.exp | 24 +- memcheck/tests/amd64-freebsd/Makefile.am | 20 + memcheck/tests/amd64-freebsd/posix_fadvise.c | 27 + .../tests/amd64-freebsd/posix_fadvise.stderr.exp | 16 + memcheck/tests/amd64-freebsd/posix_fadvise.vgtest | 3 + memcheck/tests/amd64-freebsd/posix_fallocate.c | 19 + .../tests/amd64-freebsd/posix_fallocate.stderr.exp | 8 + .../tests/amd64-freebsd/posix_fallocate.vgtest | 3 + memcheck/tests/amd64/Makefile.am | 3 +- .../tests/amd64/insn-pmovmskb.stderr.exp-clang | 48 + .../tests/amd64/xor-undef-amd64.stderr.exp-freebsd | 26 + memcheck/tests/badjump2.c | 4 +- memcheck/tests/demangle.stderr.exp-freebsd | 0 memcheck/tests/err_disable4.c | 2 + memcheck/tests/filter_dw4 | 11 - memcheck/tests/filter_dw4.in | 13 + memcheck/tests/filter_malloc_free | 2 +- memcheck/tests/filter_overlaperror | 4 - memcheck/tests/filter_overlaperror.in | 6 + memcheck/tests/{filter_stderr => filter_stderr.in} | 6 +- memcheck/tests/filter_varinfo3 | 5 +- memcheck/tests/fprw.stderr.exp-freebsd | 35 + memcheck/tests/fprw.stderr.exp-freebsd-x86 | 41 + memcheck/tests/freebsd/Makefile.am | 93 + memcheck/tests/freebsd/access.c | 43 + memcheck/tests/freebsd/access.stderr.exp | 53 + memcheck/tests/freebsd/access.vgtest | 3 + memcheck/tests/freebsd/capsicum.c | 97 + memcheck/tests/freebsd/capsicum.stderr.exp | 41 + memcheck/tests/freebsd/capsicum.vgtest | 3 + memcheck/tests/freebsd/chflags.c | 43 + memcheck/tests/freebsd/chflags.stderr.exp | 57 + memcheck/tests/freebsd/chflags.stderr.exp-x86 | 58 + memcheck/tests/freebsd/chflags.vgtest | 4 + memcheck/tests/freebsd/chmod_chown.c | 65 + memcheck/tests/freebsd/chmod_chown.stderr.exp | 65 + memcheck/tests/freebsd/chmod_chown.vgtest | 3 + memcheck/tests/freebsd/dump_stdout | 2 + memcheck/tests/freebsd/extattr.c | 99 + memcheck/tests/freebsd/extattr.stderr.exp | 209 + memcheck/tests/freebsd/extattr.vgtest | 2 + memcheck/tests/freebsd/file_locking_wait6.c | 130 + .../tests/freebsd/file_locking_wait6.stderr.exp | 5 + memcheck/tests/freebsd/file_locking_wait6.vgtest | 2 + memcheck/tests/freebsd/filter_scalar | 12 + memcheck/tests/freebsd/filter_sigwait | 5 + memcheck/tests/freebsd/filter_stderr | 3 + memcheck/tests/freebsd/get_set_context.c | 50 + memcheck/tests/freebsd/get_set_context.stderr.exp | 40 + .../tests/freebsd/get_set_context.stderr.exp-x86 | 40 + memcheck/tests/freebsd/get_set_context.vgtest | 2 + memcheck/tests/freebsd/get_set_login.c | 15 + memcheck/tests/freebsd/get_set_login.stderr.exp | 11 + memcheck/tests/freebsd/get_set_login.vgtest | 2 + memcheck/tests/freebsd/getfh.c | 50 + memcheck/tests/freebsd/getfh.stderr.exp | 71 + memcheck/tests/freebsd/getfh.vgtest | 2 + memcheck/tests/freebsd/getfsstat.c | 33 + memcheck/tests/freebsd/getfsstat.stderr.exp | 18 + memcheck/tests/freebsd/getfsstat.stderr.exp-x86 | 21 + memcheck/tests/freebsd/getfsstat.supp | 38 + memcheck/tests/freebsd/getfsstat.vgtest | 4 + memcheck/tests/freebsd/inlinfo.c | 11 + memcheck/tests/freebsd/inlinfo_nested.c | 78 + memcheck/tests/freebsd/linkat.c | 85 + memcheck/tests/freebsd/linkat.stderr.exp | 94 + memcheck/tests/freebsd/linkat.vgtest | 2 + memcheck/tests/freebsd/misc.c | 63 + memcheck/tests/freebsd/misc.stderr.exp | 32 + memcheck/tests/freebsd/misc.vgtest | 3 + memcheck/tests/freebsd/pdfork_pdkill.c | 101 + memcheck/tests/freebsd/pdfork_pdkill.stderr.exp | 41 + memcheck/tests/freebsd/pdfork_pdkill.vgtest | 4 + memcheck/tests/freebsd/revoke.c | 21 + memcheck/tests/freebsd/revoke.stderr.exp | 11 + memcheck/tests/freebsd/revoke.vgtest | 3 + memcheck/tests/freebsd/scalar.c | 2042 ++++++++ memcheck/tests/freebsd/scalar.h | 39 + memcheck/tests/freebsd/scalar.stderr.exp | 5310 +++++++++++++++++++ .../tests/freebsd/scalar.stderr.exp-freebsd130 | 5313 +++++++++++++++++++ memcheck/tests/freebsd/scalar.stderr.exp-x86 | 5371 ++++++++++++++++++++ memcheck/tests/freebsd/scalar.vgtest | 11 + memcheck/tests/freebsd/scalar_abort2.c | 14 + memcheck/tests/freebsd/scalar_abort2.stderr.exp | 25 + memcheck/tests/freebsd/scalar_abort2.vgtest | 2 + memcheck/tests/freebsd/scalar_fork.c | 11 + memcheck/tests/freebsd/scalar_fork.stderr.exp | 3 + memcheck/tests/freebsd/scalar_fork.vgtest | 2 + memcheck/tests/freebsd/scalar_pdfork.c | 14 + memcheck/tests/freebsd/scalar_pdfork.stderr.exp | 11 + memcheck/tests/freebsd/scalar_pdfork.vgtest | 2 + memcheck/tests/freebsd/scalar_thr_exit.c | 14 + memcheck/tests/freebsd/scalar_thr_exit.stderr.exp | 12 + memcheck/tests/freebsd/scalar_thr_exit.vgtest | 2 + memcheck/tests/freebsd/scalar_vfork.c | 11 + memcheck/tests/freebsd/scalar_vfork.stderr.exp | 3 + memcheck/tests/freebsd/scalar_vfork.vgtest | 2 + memcheck/tests/freebsd/sigwait.c | 68 + memcheck/tests/freebsd/sigwait.stderr.exp | 22 + memcheck/tests/freebsd/sigwait.stderr.exp-x86 | 24 + memcheck/tests/freebsd/sigwait.stdout.exp | 3 + memcheck/tests/freebsd/sigwait.vgtest | 3 + memcheck/tests/freebsd/stat.c | 71 + memcheck/tests/freebsd/stat.stderr.exp | 49 + memcheck/tests/freebsd/stat.stderr.exp-x86 | 49 + memcheck/tests/freebsd/stat.vgtest | 3 + memcheck/tests/freebsd/statfs.c | 46 + memcheck/tests/freebsd/statfs.stderr.exp | 47 + memcheck/tests/freebsd/statfs.vgtest | 3 + memcheck/tests/freebsd/static_allocs.c | 39 + memcheck/tests/freebsd/static_allocs.stderr.exp | 5 + memcheck/tests/freebsd/static_allocs.vgtest | 2 + memcheck/tests/freebsd/supponlyobj.stderr.exp | 8 + memcheck/tests/freebsd/supponlyobj.supp | 16 + memcheck/tests/freebsd/supponlyobj.vgtest | 4 + memcheck/tests/freebsd/utimens.c | 57 + memcheck/tests/freebsd/utimens.stderr.exp | 36 + memcheck/tests/freebsd/utimens.vgtest | 3 + memcheck/tests/freebsd/utimes.c | 99 + memcheck/tests/freebsd/utimes.stderr.exp | 96 + memcheck/tests/freebsd/utimes.stderr.exp-x86 | 96 + memcheck/tests/freebsd/utimes.vgtest | 2 + .../tests/leak-autofreepool-5.stderr.exp-freebsd | 34 + memcheck/tests/leak-segv-jmp.c | 96 + memcheck/tests/leak-segv-jmp.stderr.exp | 20 +- .../tests/leak_cpp_interior.stderr.exp-freebsd | 131 + memcheck/tests/libstdc++.supp | 10 + memcheck/tests/manuel1.stderr.exp-freebsd-clang | 28 + memcheck/tests/memalign2.c | 2 + .../tests/memalign_test.stderr.exp-freebsd-clang | 10 + memcheck/tests/origin1-yes.stderr.exp-freebsd | 29 + .../tests/origin2-not-quite.stderr.exp-freebsd | 11 + memcheck/tests/origin3-no.stderr.exp-freebsd | 22 + memcheck/tests/origin4-many.c | 16 +- memcheck/tests/origin5-bz2.stderr.exp-freebsd | 158 + memcheck/tests/origin5-bz2.stderr.exp-freebsd-x86 | 158 + memcheck/tests/sendmsg.stderr.exp-freebsd | 20 + memcheck/tests/sendmsg.stderr.exp-freebsd-x86 | 20 + memcheck/tests/sigkill.stderr.exp-freebsd | 197 + memcheck/tests/str_tester.c | 26 +- memcheck/tests/supp_unknown.supp | 8 + memcheck/tests/supponlyobj.vgtest | 3 +- memcheck/tests/test-plo-no.stderr.exp-le32-freebsd | 18 + .../test-plo-no.stderr.exp-le32-freebsd-clang | 20 + memcheck/tests/test-plo-no.stderr.exp-le64-freebsd | 20 + memcheck/tests/thread_alloca.c | 2 + memcheck/tests/varinfo1.c | 4 +- memcheck/tests/varinfo1.stderr.exp | 2 +- memcheck/tests/varinfo1.stderr.exp-freebsd | 37 + memcheck/tests/varinfo1.vgtest | 1 + memcheck/tests/varinfo2.c | 4 +- memcheck/tests/varinfo2.stderr.exp | 6 +- memcheck/tests/varinfo2.stderr.exp-ppc64 | 6 +- memcheck/tests/varinfo2.vgtest | 1 + memcheck/tests/varinfo3.c | 4 +- memcheck/tests/varinfo3.stderr.exp | 4 +- memcheck/tests/varinfo3.stderr.exp-freebsd | 58 + memcheck/tests/varinfo4.c | 4 +- memcheck/tests/varinfo4.stderr.exp-freebsd | 21 + memcheck/tests/varinfo5.stderr.exp | 20 +- memcheck/tests/varinfo5.stderr.exp-ppc64 | 16 +- memcheck/tests/varinfo5so.c | 4 +- memcheck/tests/varinfo6.c | 4 +- memcheck/tests/vbit-test/util.c | 6 +- memcheck/tests/vbit-test/vbits.c | 6 +- memcheck/tests/wrap6.c | 19 + memcheck/tests/x86-freebsd/Makefile.am | 21 + memcheck/tests/x86-freebsd/posix_fadvise.c | 27 + .../tests/x86-freebsd/posix_fadvise.stderr.exp | 24 + memcheck/tests/x86-freebsd/posix_fadvise.vgtest | 3 + memcheck/tests/x86-freebsd/posix_fallocate.c | 19 + .../tests/x86-freebsd/posix_fallocate.stderr.exp | 16 + memcheck/tests/x86-freebsd/posix_fallocate.vgtest | 3 + memcheck/tests/x86/filter_pushfpopf | 5 - memcheck/tests/x86/filter_pushfpopf.in | 7 + memcheck/tests/x86/pushfpopf_s.S | 6 +- 179 files changed, 22775 insertions(+), 118 deletions(-) diff --git a/configure.ac b/configure.ac index 3f2a73ee27..39e619575e 100755 --- a/configure.ac +++ b/configure.ac @@ -5141,11 +5141,14 @@ AC_CONFIG_FILES([ memcheck/tests/linux/debuginfod-check.vgtest memcheck/tests/darwin/Makefile memcheck/tests/solaris/Makefile + memcheck/tests/freebsd/Makefile memcheck/tests/amd64-linux/Makefile memcheck/tests/arm64-linux/Makefile memcheck/tests/x86-linux/Makefile memcheck/tests/amd64-solaris/Makefile memcheck/tests/x86-solaris/Makefile + memcheck/tests/amd64-freebsd/Makefile + memcheck/tests/x86-freebsd/Makefile memcheck/tests/ppc32/Makefile memcheck/tests/ppc64/Makefile memcheck/tests/s390x/Makefile @@ -5216,6 +5219,14 @@ AC_CONFIG_FILES([tests/filter_stderr_basic], [chmod +x tests/filter_stderr_basic]) AC_CONFIG_FILES([tests/filter_discards], [chmod +x tests/filter_discards]) +AC_CONFIG_FILES([memcheck/tests/filter_stderr], + [chmod +x memcheck/tests/filter_stderr]) +AC_CONFIG_FILES([memcheck/tests/filter_dw4], + [chmod +x memcheck/tests/filter_dw4]) +AC_CONFIG_FILES([memcheck/tests/filter_overlaperror], + [chmod +x memcheck/tests/filter_overlaperror]) +AC_CONFIG_FILES([memcheck/tests/x86/filter_pushfpopf], + [chmod +x memcheck/tests/x86/filter_pushfpopf]) AC_CONFIG_FILES([gdbserver_tests/filter_gdb], [chmod +x gdbserver_tests/filter_gdb]) AC_CONFIG_FILES([gdbserver_tests/filter_memcheck_monitor], diff --git a/memcheck/tests/Makefile.am b/memcheck/tests/Makefile.am index 9fe8082b94..3ce33af181 100644 --- a/memcheck/tests/Makefile.am +++ b/memcheck/tests/Makefile.am @@ -66,6 +66,7 @@ endif DIST_SUBDIRS = x86 amd64 ppc32 ppc64 s390x linux \ darwin solaris x86-linux amd64-linux arm64-linux \ x86-solaris amd64-solaris mips32 mips64 \ + freebsd amd64-freebsd x86-freebsd \ common . dist_noinst_SCRIPTS = \ @@ -138,11 +139,13 @@ EXTRA_DIST = \ cxx17_aligned_new.stdout.exp \ deep-backtrace.vgtest deep-backtrace.stderr.exp \ demangle.stderr.exp demangle.vgtest \ + demangle.stderr.exp-freebsd \ big_debuginfo_symbol.stderr.exp big_debuginfo_symbol.vgtest \ describe-block.stderr.exp describe-block.vgtest \ descr_belowsp.vgtest descr_belowsp.stderr.exp \ doublefree.stderr.exp doublefree.vgtest \ dw4.vgtest dw4.stderr.exp dw4.stderr.exp-solaris dw4.stdout.exp \ + dw4.stderr.exp-freebsd \ err_disable1.vgtest err_disable1.stderr.exp \ err_disable2.vgtest err_disable2.stderr.exp \ err_disable3.vgtest err_disable3.stderr.exp \ @@ -155,8 +158,9 @@ EXTRA_DIST = \ execve1.stderr.exp execve1.vgtest execve1.stderr.exp-kfail \ execve2.stderr.exp execve2.vgtest execve2.stderr.exp-kfail \ file_locking.stderr.exp file_locking.vgtest \ - fprw.stderr.exp fprw.stderr.exp-mips32-be fprw.stderr.exp-mips32-le \ - fprw.vgtest \ + fprw.stderr.exp fprw.stderr.exp-freebsd fprw.stderr.exp-mips32-be \ + fprw.stderr.exp-mips32-le fprw.vgtest \ + fprw.stderr.exp-freebsd-x86 \ fwrite.stderr.exp fwrite.vgtest fwrite.stderr.exp-kfail \ gone_abrt_xml.vgtest gone_abrt_xml.stderr.exp gone_abrt_xml.stderr.exp-solaris \ holey_buffer_too_small.vgtest holey_buffer_too_small.stdout.exp \ @@ -186,6 +190,7 @@ EXTRA_DIST = \ leak-autofreepool-4.vgtest leak-autofreepool-4.stderr.exp \ leak-autofreepool-5.vgtest leak-autofreepool-5.stderr.exp \ leak-autofreepool-6.vgtest leak-autofreepool-6.stderr.exp \ + leak-autofreepool-5.stderr.exp-freebsd \ leak-tree.vgtest leak-tree.stderr.exp \ leak-segv-jmp.vgtest leak-segv-jmp.stderr.exp \ lks.vgtest lks.stdout.exp lks.supp lks.stderr.exp \ @@ -204,11 +209,13 @@ EXTRA_DIST = \ malloc2.stderr.exp malloc2.vgtest \ malloc3.stderr.exp malloc3.stdout.exp malloc3.vgtest \ manuel1.stderr.exp manuel1.stdout.exp manuel1.vgtest \ + manuel1.stderr.exp-freebsd-clang \ manuel2.stderr.exp manuel2.stderr.exp64 manuel2.stdout.exp \ manuel2.vgtest \ manuel3.stderr.exp manuel3.vgtest \ match-overrun.stderr.exp match-overrun.vgtest match-overrun.supp \ memalign_test.stderr.exp memalign_test.vgtest \ + memalign_test.stderr.exp-freebsd-clang \ memalign2.stderr.exp memalign2.vgtest \ memcmptest.stderr.exp memcmptest.stderr.exp2 \ memcmptest.stdout.exp memcmptest.vgtest \ @@ -225,9 +232,12 @@ EXTRA_DIST = \ noisy_child.vgtest noisy_child.stderr.exp noisy_child.stdout.exp \ null_socket.stderr.exp null_socket.vgtest \ origin1-yes.vgtest origin1-yes.stdout.exp origin1-yes.stderr.exp \ + origin1-yes.stderr.exp-freebsd \ origin2-not-quite.vgtest origin2-not-quite.stdout.exp \ origin2-not-quite.stderr.exp \ + origin2-not-quite.stderr.exp-freebsd \ origin3-no.vgtest origin3-no.stdout.exp \ + origin3-no.stderr.exp-freebsd \ origin3-no.stderr.exp \ origin4-many.vgtest origin4-many.stdout.exp \ origin4-many.stderr.exp \ @@ -238,6 +248,8 @@ EXTRA_DIST = \ origin5-bz2.stderr.exp-glibc27-ppc64 \ origin5-bz2.stderr.exp-glibc212-s390x \ origin5-bz2.stderr.exp-glibc234-s390x \ + origin5-bz2.stderr.exp-freebsd \ + origin5-bz2.stderr.exp-freebsd-x86 \ origin5-bz2.stderr.exp-glibc218-mips32 \ origin6-fp.vgtest origin6-fp.stdout.exp \ origin6-fp.stderr.exp-glibc25-amd64 \ @@ -272,11 +284,13 @@ EXTRA_DIST = \ sbfragment.stdout.exp sbfragment.stderr.exp sbfragment.vgtest \ sem.stderr.exp sem.vgtest \ sendmsg.stderr.exp sendmsg.stderr.exp-solaris sendmsg.vgtest \ + sendmsg.stderr.exp-freebsd \ + sendmsg.stderr.exp-freebsd-x86 \ sh-mem.stderr.exp sh-mem.vgtest \ sh-mem-random.stderr.exp sh-mem-random.stdout.exp64 \ sh-mem-random.stdout.exp sh-mem-random.vgtest \ sigaltstack.stderr.exp sigaltstack.vgtest \ - sigkill.stderr.exp sigkill.stderr.exp-darwin sigkill.stderr.exp-mips32 \ + sigkill.stderr.exp sigkill.stderr.exp-darwin sigkill.stderr.exp-freebsd sigkill.stderr.exp-mips32 \ sigkill.stderr.exp-solaris \ sigkill.stderr.exp-glibc-2.28 sigkill.vgtest \ signal2.stderr.exp signal2.stdout.exp signal2.vgtest \ @@ -302,6 +316,8 @@ EXTRA_DIST = \ suppvarinfo5.stderr.exp suppvarinfo5.supp suppvarinfo5.vgtest \ test-plo-no.vgtest test-plo-no.stdout.exp \ test-plo-no.stderr.exp-le64 test-plo-no.stderr.exp-le32 \ + test-plo-no.stderr.exp-le32-freebsd test-plo-no.stderr.exp-le64-freebsd \ + test-plo-no.stderr.exp-le32-freebsd-clang \ test-plo-yes.vgtest test-plo-yes.stdout.exp \ test-plo-yes.stderr.exp-le64 test-plo-yes.stderr.exp-le32 \ test-plo-no.stderr.exp-s390x-mvc \ @@ -314,12 +330,15 @@ EXTRA_DIST = \ unit_oset.stderr.exp unit_oset.stdout.exp unit_oset.vgtest \ varinfo1.vgtest varinfo1.stdout.exp varinfo1.stderr.exp \ varinfo1.stderr.exp-ppc64 \ + varinfo1.stderr.exp-freebsd \ varinfo2.vgtest varinfo2.stdout.exp varinfo2.stderr.exp \ varinfo2.stderr.exp-ppc64 \ varinfo3.vgtest varinfo3.stdout.exp varinfo3.stderr.exp \ varinfo3.stderr.exp-ppc64 \ + varinfo3.stderr.exp-freebsd \ varinfo4.vgtest varinfo4.stdout.exp varinfo4.stderr.exp \ varinfo4.stderr.exp-ppc64 \ + varinfo4.stderr.exp-freebsd \ varinfo5.vgtest varinfo5.stdout.exp varinfo5.stderr.exp \ varinfo5.stderr.exp-ppc64 \ varinfo6.vgtest varinfo6.stdout.exp varinfo6.stderr.exp \ @@ -344,7 +363,8 @@ EXTRA_DIST = \ wrapmallocstatic.vgtest wrapmallocstatic.stdout.exp \ wrapmallocstatic.stderr.exp \ writev1.stderr.exp writev1.stderr.exp-solaris writev1.vgtest \ - xml1.stderr.exp xml1.stdout.exp xml1.vgtest xml1.stderr.exp-s390x-mvc + xml1.stderr.exp xml1.stdout.exp xml1.vgtest xml1.stderr.exp-s390x-mvc \ + leak_cpp_interior.stderr.exp-freebsd check_PROGRAMS = \ accounting \ diff --git a/memcheck/tests/addressable.c b/memcheck/tests/addressable.c index 5f3c2e182e..568fbb45ed 100644 --- a/memcheck/tests/addressable.c +++ b/memcheck/tests/addressable.c @@ -9,6 +9,9 @@ #include <errno.h> #include <string.h> #include <stdlib.h> +#if defined(VGO_freebsd) +#include <signal.h> +#endif static int pgsz; diff --git a/memcheck/tests/addressable.stderr.exp b/memcheck/tests/addressable.stderr.exp index 4c121987d6..533d6e9bb1 100644 --- a/memcheck/tests/addressable.stderr.exp +++ b/memcheck/tests/addressable.stderr.exp @@ -9,20 +9,20 @@ For a detailed leak analysis, rerun with: --leak-check=full For lists of detected and suppressed errors, rerun with: -s ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0) Unaddressable byte(s) found during client check request - at 0x........: test2 (addressable.c:48) - by 0x........: main (addressable.c:125) + at 0x........: test2 (addressable.c:51) + by 0x........: main (addressable.c:128) Address 0x........ is not stack'd, malloc'd or (recently) free'd Invalid write of size 1 - at 0x........: test2 (addressable.c:51) - by 0x........: main (addressable.c:125) + at 0x........: test2 (addressable.c:54) + by 0x........: main (addressable.c:128) Address 0x........ is not stack'd, malloc'd or (recently) free'd Process terminating with default action of signal N (SIGSEGV or SIGBUS) Bad memory (SIGSEGV or SIGBUS) at address 0x........ - at 0x........: test2 (addressable.c:51) - by 0x........: main (addressable.c:125) + at 0x........: test2 (addressable.c:54) + by 0x........: main (addressable.c:128) If you believe this happened as a result of a stack overflow in your program's main thread (unlikely but possible), you can try to increase the size of the @@ -49,8 +49,8 @@ ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0) Process terminating with default action of signal N (SIGSEGV or SIGBUS) Bad memory (SIGSEGV or SIGBUS) at address 0x........ - at 0x........: test4 (addressable.c:74) - by 0x........: main (addressable.c:125) + at 0x........: test4 (addressable.c:77) + by 0x........: main (addressable.c:128) HEAP SUMMARY: in use at exit: ... bytes in ... blocks @@ -61,13 +61,13 @@ For a detailed leak analysis, rerun with: --leak-check=full For lists of detected and suppressed errors, rerun with: -s ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0) Uninitialised byte(s) found during client check request - at 0x........: test5 (addressable.c:85) - by 0x........: main (addressable.c:125) + at 0x........: test5 (addressable.c:88) + by 0x........: main (addressable.c:128) Address 0x........ is in a rw- anonymous segment Uninitialised byte(s) found during client check request - at 0x........: test5 (addressable.c:91) - by 0x........: main (addressable.c:125) + at 0x........: test5 (addressable.c:94) + by 0x........: main (addressable.c:128) Address 0x........ is in a r-- anonymous segment diff --git a/memcheck/tests/amd64-freebsd/Makefile.am b/memcheck/tests/amd64-freebsd/Makefile.am new file mode 100644 index 0000000000..80854419dd --- /dev/null +++ b/memcheck/tests/amd64-freebsd/Makefile.am @@ -0,0 +1,20 @@ + +include $(top_srcdir)/Makefile.tool-tests.am + +dist_noinst_SCRIPTS = filter_stderr + +EXTRA_DIST = \ + posix_fadvise.vgtest \ + posix_fallocate.vgtest \ + posix_fadvise.stderr.exp \ + posix_fallocate.stderr.exp + +check_PROGRAMS = \ + posix_fadvise posix_fallocate + +AM_CFLAGS += @FLAG_M64@ +AM_CXXFLAGS += @FLAG_M64@ +AM_CCASFLAGS += @FLAG_M64@ + +posix_fallocate_CFLAGS = $(AM_CFLAGS) @FLAG_W_NO_UNINITIALIZED@ +posix_fadvise_CFLAGS = $(AM_CFLAGS) @FLAG_W_NO_UNINITIALIZED@ diff --git a/memcheck/tests/amd64-freebsd/posix_fadvise.c b/memcheck/tests/amd64-freebsd/posix_fadvise.c new file mode 100644 index 0000000000..2ba2005ae6 --- /dev/null +++ b/memcheck/tests/amd64-freebsd/posix_fadvise.c @@ -0,0 +1,27 @@ +#include <fcntl.h> +#include <stdio.h> +#include <errno.h> + +int main(void) +{ + int fd = open("foo", O_RDWR|O_CREAT, 0666); + if (fd < 0) return 1; + posix_fadvise( fd, 0, 4096, POSIX_FADV_WILLNEED ); + posix_fadvise( fd, 0, 0, POSIX_FADV_NOREUSE ); + + int badfd = 42; + posix_fadvise( badfd, 0, 4096, POSIX_FADV_WILLNEED ); + + int x; + posix_fadvise(x, 1, 2, POSIX_FADV_NORMAL); + posix_fadvise(badfd, x, 2, POSIX_FADV_NORMAL); + posix_fadvise(badfd, 1, x, POSIX_FADV_NORMAL); + posix_fadvise(badfd, 1, 2, x); + + x = posix_fadvise(badfd + , 1, 2, POSIX_FADV_NORMAL); + + if (x != EBADF) + fprintf(stderr, "Unexpected return value: %d\n", x); +} + diff --git a/memcheck/tests/amd64-freebsd/posix_fadvise.stderr.exp b/memcheck/tests/amd64-freebsd/posix_fadvise.stderr.exp new file mode 100644 index 0000000000..3fb69d8413 --- /dev/null +++ b/memcheck/tests/amd64-freebsd/posix_fadvise.stderr.exp @@ -0,0 +1,16 @@ +Syscall param posix_fadvise(fd) contains uninitialised byte(s) + at 0x........: posix_fadvise (in /...libc...) + by 0x........: main (posix_fadvise.c:16) + +Syscall param posix_fadvise(offset) contains uninitialised byte(s) + at 0x........: posix_fadvise (in /...libc...) + by 0x........: main (posix_fadvise.c:17) + +Syscall param posix_fadvise(len) contains uninitialised byte(s) + at 0x........: posix_fadvise (in /...libc...) + by 0x........: main (posix_fadvise.c:18) + +Syscall param posix_fadvise(advice) contains uninitialised byte(s) + at 0x........: posix_fadvise (in /...libc...) + by 0x........: main (posix_fadvise.c:19) + diff --git a/memcheck/tests/amd64-freebsd/posix_fadvise.vgtest b/memcheck/tests/amd64-freebsd/posix_fadvise.vgtest new file mode 100644 index 0000000000..6353a958cb --- /dev/null +++ b/memcheck/tests/amd64-freebsd/posix_fadvise.vgtest @@ -0,0 +1,3 @@ +prog: posix_fadvise +vgopts: -q +cleanup: rm -f foo diff --git a/memcheck/tests/amd64-freebsd/posix_fallocate.c b/memcheck/tests/amd64-freebsd/posix_fallocate.c new file mode 100644 index 0000000000..8c04594379 --- /dev/null +++ b/memcheck/tests/amd64-freebsd/posix_fallocate.c @@ -0,0 +1,19 @@ +#include <fcntl.h> +#include <stdio.h> +#include <errno.h> + +int main(void) +{ + int fd = open("foo", O_RDWR|O_CREAT, 0666); + if (fd < 0) return 1; + posix_fallocate(fd, 0, 400000); + + int badfd = 42; + int x; + posix_fallocate(badfd, x, 20); + posix_fallocate(badfd, 0, x); + x = posix_fallocate(badfd, 0, 20); + if (x != EBADF) + fprintf(stderr, "Unexpected return value: %d\n", x); +} + diff --git a/memcheck/tests/amd64-freebsd/posix_fallocate.stderr.exp b/memcheck/tests/amd64-freebsd/posix_fallocate.stderr.exp new file mode 100644 index 0000000000..063b6d98ba --- /dev/null +++ b/memcheck/tests/amd64-freebsd/posix_fallocate.stderr.exp @@ -0,0 +1,8 @@ +Syscall param posix_fallocate(offset) contains uninitialised byte(s) + at 0x........: posix_fallocate (in /...libc...) + by 0x........: main (posix_fallocate.c:13) + +Syscall param posix_fallocate(len) contains uninitialised byte(s) + at 0x........: posix_fallocate (in /...libc...) + by 0x........: main (posix_fallocate.c:14) + diff --git a/memcheck/tests/amd64-freebsd/posix_fallocate.vgtest b/memcheck/tests/amd64-freebsd/posix_fallocate.vgtest new file mode 100644 index 0000000000..28954e87fe --- /dev/null +++ b/memcheck/tests/amd64-freebsd/posix_fallocate.vgtest @@ -0,0 +1,3 @@ +prog: posix_fallocate +vgopts: -q +cleanup: rm -f foo diff --git a/memcheck/tests/amd64/Makefile.am b/memcheck/tests/amd64/Makefile.am index da15cf797a..d5c94f68a0 100644 --- a/memcheck/tests/amd64/Makefile.am +++ b/memcheck/tests/amd64/Makefile.am @@ -17,6 +17,7 @@ EXTRA_DIST = \ insn-bsfl.vgtest insn-bsfl.stdout.exp insn-bsfl.stderr.exp \ insn-pcmpistri.vgtest insn-pcmpistri.stdout.exp insn-pcmpistri.stderr.exp \ insn-pmovmskb.vgtest insn-pmovmskb.stdout.exp insn-pmovmskb.stderr.exp \ + insn-pmovmskb.stderr.exp-clang \ more_x87_fp.stderr.exp more_x87_fp.stdout.exp more_x87_fp.vgtest \ sh-mem-vec128-plo-no.vgtest \ sh-mem-vec128-plo-no.stderr.exp \ @@ -33,7 +34,7 @@ EXTRA_DIST = \ shr_edx.stderr.exp shr_edx.stdout.exp shr_edx.vgtest \ sse_memory.stderr.exp sse_memory.stdout.exp sse_memory.vgtest \ xor-undef-amd64.stderr.exp xor-undef-amd64.stdout.exp \ - xor-undef-amd64.vgtest \ + xor-undef-amd64.stderr.exp-freebsd xor-undef-amd64.vgtest \ xsave-avx.vgtest xsave-avx.stdout.exp xsave-avx.stderr.exp check_PROGRAMS = \ diff --git a/memcheck/tests/amd64/insn-pmovmskb.stderr.exp-clang b/memcheck/tests/amd64/insn-pmovmskb.stderr.exp-clang new file mode 100644 index 0000000000..6d32a1f331 --- /dev/null +++ b/memcheck/tests/amd64/insn-pmovmskb.stderr.exp-clang @@ -0,0 +1,48 @@ +Conditional jump or move depends on uninitialised value(s) + ... + by 0x........: use (insn-pmovmskb.c:48) + by 0x........: doit (insn-pmovmskb.c:69) + by 0x........: main (insn-pmovmskb.c:140) + +Use of uninitialised value of size 8 + ... + by 0x........: use (insn-pmovmskb.c:48) + by 0x........: doit (insn-pmovmskb.c:69) + by 0x........: main (insn-pmovmskb.c:140) + +Use of uninitialised value of size 8 + ... + by 0x........: use (insn-pmovmskb.c:48) + by 0x........: doit (insn-pmovmskb.c:69) + by 0x........: main (insn-pmovmskb.c:140) + +Use of uninitialised value of size 8 + ... + by 0x........: use (insn-pmovmskb.c:48) + by 0x........: doit (insn-pmovmskb.c:69) + by 0x........: main (insn-pmovmskb.c:140) + +0: Invalid value is false +1: Invalid value is false +2: Invalid value is false +3: Invalid value is false +4: Invalid value is false +5: Invalid value is false +6: Invalid value is false +7: Invalid value is false +8: Invalid value is false +9: Invalid value is false +10: Invalid value is false +11: Invalid value is false +12: Invalid value is false +13: Invalid value is false +14: Invalid value is false +15: Invalid value is false +4: Invalid value is true +5: Invalid value is true +6: Invalid value is true +7: Invalid value is true +8: Invalid value is true +9: Invalid value is true +12: Invalid value is true +13: Invalid value is true diff --git a/memcheck/tests/amd64/xor-undef-amd64.stderr.exp-freebsd b/memcheck/tests/amd64/xor-undef-amd64.stderr.exp-freebsd new file mode 100755 index 0000000000..0bfff27098 --- /dev/null +++ b/memcheck/tests/amd64/xor-undef-amd64.stderr.exp-freebsd @@ -0,0 +1,26 @@ + +Conditional jump or move depends on uninitialised value(s) + at 0x........: main (xor-undef-amd64.c:17) + +Conditional jump or move depends on uninitialised value(s) + at 0x........: main (xor-undef-amd64.c:38) + +Conditional jump or move depends on uninitialised value(s) + at 0x........: main (xor-undef-amd64.c:65) + +Conditional jump or move depends on uninitialised value(s) + at 0x........: main (xor-undef-amd64.c:92) + +Conditional jump or move depends on uninitialised value(s) + at 0x........: main (xor-undef-amd64.c:117) + + +HEAP SUMMARY: + in use at exit: 4,096 bytes in 1 blocks + total heap usage: 2 allocs, 1 frees, 4,144 bytes allocated + +For a detailed leak analysis, rerun with: --leak-check=full + +For counts of detected and suppressed errors, rerun with: -v +Use --track-origins=yes to see where uninitialised values come from +ERROR SUMMARY: 5 errors from 5 contexts (suppressed: 0 from 0) diff --git a/memcheck/tests/badjump2.c b/memcheck/tests/badjump2.c index 2085a30d9e..ae858e7733 100644 --- a/memcheck/tests/badjump2.c +++ b/memcheck/tests/badjump2.c @@ -3,6 +3,7 @@ #include <signal.h> #include <stdio.h> #include <stdlib.h> +#include <string.h> // Regression test for bug 91162: if a client had a SEGV signal handler, // and jumped to a bogus address, Valgrind would abort. With the fix, @@ -22,9 +23,10 @@ int main(void) int res; /* Install own SIGSEGV handler */ + memset(&sigsegv_new, 0, sizeof(sigsegv_new)); sigsegv_new.sa_handler = SIGSEGV_handler; sigsegv_new.sa_flags = 0; -#if !defined(__APPLE__) && !defined(__sun) +#if !defined(__APPLE__) && !defined(__sun) && !defined(__FreeBSD__) sigsegv_new.sa_restorer = NULL; #endif res = sigemptyset( &sigsegv_new.sa_mask ); diff --git a/memcheck/tests/demangle.stderr.exp-freebsd b/memcheck/tests/demangle.stderr.exp-freebsd new file mode 100644 index 0000000000..e69de29bb2 diff --git a/memcheck/tests/err_disable4.c b/memcheck/tests/err_disable4.c index 44487afd2f..0692192ec8 100644 --- a/memcheck/tests/err_disable4.c +++ b/memcheck/tests/err_disable4.c @@ -94,7 +94,9 @@ int main ( void ) pthread_attr_t attr; r = pthread_attr_init(&attr); assert(!r); +#if !defined(VGO_freebsd) r = pthread_attr_setstacksize(&attr, PTHREAD_STACK_MIN); +#endif // create N threads to do child_fn_1 ... for (i = 0; i < NTHREADS; i++) { diff --git a/memcheck/tests/filter_dw4 b/memcheck/tests/filter_dw4 deleted file mode 100755 index b192bb91b7..0000000000 --- a/memcheck/tests/filter_dw4 +++ /dev/null @@ -1,11 +0,0 @@ -#! /bin/sh - -# Size of structure s1 differs between 32-bit and 64-bit programs. -sed "s/inside a block of size [0-9]* alloc'd/inside a block of size ... alloc'd/" | - -# remove directory name and pid from mapped filename -sed "s/file .*valgrind-dw4-test.[1-9][0-9]*/file valgrind-dw4-test.PID/" | - -./filter_stderr "$@" - -exit 0 diff --git a/memcheck/tests/filter_dw4.in b/memcheck/tests/filter_dw4.in new file mode 100755 index 0000000000..b217ad57ca --- /dev/null +++ b/memcheck/tests/filter_dw4.in @@ -0,0 +1,13 @@ +#! /bin/sh + +SED=@SED@ + +# Size of structure s1 differs between 32-bit and 64-bit programs. +$SED "s/inside a block of size [0-9]* alloc'd/inside a block of size ... alloc'd/" | + +# remove directory name and pid from mapped filename +$SED "s/file .*valgrind-dw4-test.[1-9][0-9]*/file valgrind-dw4-test.PID/" | + +./filter_stderr "$@" + +exit 0 diff --git a/memcheck/tests/filter_malloc_free b/memcheck/tests/filter_malloc_free index 0f43cf2e1d..9d4c52559c 100755 --- a/memcheck/tests/filter_malloc_free +++ b/memcheck/tests/filter_malloc_free @@ -2,5 +2,5 @@ ./filter_stderr "$@" | ./filter_allocs | -sed -e '/^malloc/d;/^free/d' +sed -e '/^malloc/d;/^free/d;/^calloc/d' diff --git a/memcheck/tests/filter_overlaperror b/memcheck/tests/filter_overlaperror deleted file mode 100755 index bd477b7351..0000000000 --- a/memcheck/tests/filter_overlaperror +++ /dev/null @@ -1,4 +0,0 @@ -#! /bin/sh - -./filter_allocs "$@" | -sed 's/\(Memcheck: mc_leakcheck.c:\)[0-9]*\(.*impossible.*happened.*\)/\1...\2/' diff --git a/memcheck/tests/filter_overlaperror.in b/memcheck/tests/filter_overlaperror.in new file mode 100755 index 0000000000..3c853c0480 --- /dev/null +++ b/memcheck/tests/filter_overlaperror.in @@ -0,0 +1,6 @@ +#! /bin/sh + +SED=@SED@ + +./filter_allocs "$@" | +$SED 's/\(Memcheck: mc_leakcheck.c:\)[0-9]*\(.*impossible.*happened.*\)/\1...\2/' diff --git a/memcheck/tests/filter_stderr b/memcheck/tests/filter_stderr.in similarity index 90% rename from memcheck/tests/filter_stderr rename to memcheck/tests/filter_stderr.in index c6f6cd439f..a410fa89e7 100755 --- a/memcheck/tests/filter_stderr +++ b/memcheck/tests/filter_stderr.in @@ -2,20 +2,22 @@ dir=`dirname $0` +SED=@SED@ + $dir/../../tests/filter_stderr_basic | # Anonymise addresses $dir/../../tests/filter_addresses | # Remove "Memcheck, ..." line and the following copyright line. -sed "/^Memcheck, a memory error detector/ , /./ d" | +$SED "/^Memcheck, a memory error detector/ , /./ d" | # Replace exit_group() with exit(), because you can get either on Linux # depending on the system. perl -p -e "s/param exit_group\(status\)/param exit(status)/" | # Leak check filtering. -sed "s/checked [0-9,]* bytes./checked ... bytes./" | +$SED "s/checked [0-9,]* bytes./checked ... bytes./" | # More leak check filtering. For systems that do extra libc allocations # (eg. Darwin) there may be extra (reachable, and thus not shown) loss diff --git a/memcheck/tests/filter_varinfo3 b/memcheck/tests/filter_varinfo3 index dbf25eee5b..9f0a31c091 100755 --- a/memcheck/tests/filter_varinfo3 +++ b/memcheck/tests/filter_varinfo3 @@ -4,4 +4,7 @@ ./filter_stderr "$@" | sed "s/static_local_def\.[0-9]*/static_local_def\.XXXX/g" | -sed "s/static_local_undef\.[0-9]*/static_local_undef\.XXXX/g" +sed "s/static_local_undef\.[0-9]*/static_local_undef\.XXXX/g" | +sed "s/foo.static_local_undef/static_local_undef.XXXX/g" | +sed "s/frame #./frame #X/g" + diff --git a/memcheck/tests/fprw.stderr.exp-freebsd b/memcheck/tests/fprw.stderr.exp-freebsd new file mode 100644 index 0000000000..1efbdcd91e --- /dev/null +++ b/memcheck/tests/fprw.stderr.exp-freebsd @@ -0,0 +1,35 @@ +Invalid read of size 8 + at 0x........: main (fprw.c:20) + Address 0x........ is 0 bytes inside a block of size 8 free'd + at 0x........: free (vg_replace_malloc.c:...) + by 0x........: main (fprw.c:18) + +Invalid write of size 8 + at 0x........: main (fprw.c:20) + Address 0x........ is 0 bytes inside a block of size 8 free'd + at 0x........: free (vg_replace_malloc.c:...) + by 0x........: main (fprw.c:18) + +Invalid read of size 4 + at 0x........: main (fprw.c:21) + Address 0x........ is 0 bytes inside a block of size 4 free'd + at 0x........: free (vg_replace_malloc.c:...) + by 0x........: main (fprw.c:19) + +Invalid write of size 4 + at 0x........: main (fprw.c:21) + Address 0x........ is 0 bytes inside a block of size 4 free'd + at 0x........: free (vg_replace_malloc.c:...) + by 0x........: main (fprw.c:19) + +Invalid free() / delete / delete[] / realloc() + at 0x........: free (vg_replace_malloc.c:...) + by 0x........: main (fprw.c:22) + Address 0x........ is not stack'd, malloc'd or (recently) free'd + +Invalid write of size 8 + at 0x........: main (fprw.c:24) + Address 0x........ is 0 bytes inside a block of size 4 alloc'd + at 0x........: malloc (vg_replace_malloc.c:...) + by 0x........: main (fprw.c:23) + diff --git a/memcheck/tests/fprw.stderr.exp-freebsd-x86 b/memcheck/tests/fprw.stderr.exp-freebsd-x86 new file mode 100644 index 0000000000..3b920e5922 --- /dev/null +++ b/memcheck/tests/fprw.stderr.exp-freebsd-x86 @@ -0,0 +1,41 @@ +Use of uninitialised value of size 4 + at 0x........: main (fprw.c:16) + +Use of uninitialised value of size 4 + at 0x........: main (fprw.c:17) + +Invalid read of size 8 + at 0x........: main (fprw.c:20) + Address 0x........ is 0 bytes inside a block of size 8 free'd + at 0x........: free (vg_replace_malloc.c:...) + by 0x........: main (fprw.c:18) + +Invalid write of size 8 + at 0x........: main (fprw.c:20) + Address 0x........ is 0 bytes inside a block of size 8 free'd + at 0x........: free (vg_replace_malloc.c:...) + by 0x........: main (fprw.c:18) + +Invalid read of size 4 + at 0x........: main (fprw.c:21) + Address 0x........ is 0 bytes inside a block of size 4 free'd + at 0x........: free (vg_replace_malloc.c:...) + by 0x........: main (fprw.c:19) + +Invalid write of size 4 + at 0x........: main (fprw.c:21) + Address 0x........ is 0 bytes inside a block of size 4 free'd + at 0x........: free (vg_replace_malloc.c:...) + by 0x........: main (fprw.c:19) + +Invalid free() / delete / delete[] / realloc() + at 0x........: free (vg_replace_malloc.c:...) + by 0x........: main (fprw.c:22) + Address 0x........ is not stack'd, malloc'd or (recently) free'd + +Invalid write of size 8 + at 0x........: main (fprw.c:24) + Address 0x........ is 0 bytes inside a block of size 4 alloc'd + at 0x........: malloc (vg_replace_malloc.c:...) + by 0x........: main (fprw.c:23) + diff --git a/memcheck/tests/freebsd/Makefile.am b/memcheck/tests/freebsd/Makefile.am new file mode 100644 index 0000000000..c1d675a7a3 --- /dev/null +++ b/memcheck/tests/freebsd/Makefile.am @@ -0,0 +1,93 @@ + +include $(top_srcdir)/Makefile.tool-tests.am + +dist_noinst_SCRIPTS = filter_stderr filter_pts dump_stdout filter_sigwait \ + filter_scalar + +EXTRA_DIST = \ + scalar.h \ + statfs.vgtest \ + statfs.stderr.exp \ + pdfork_pdkill.vgtest \ + pdfork_pdkill.stderr.exp \ + getfsstat.vgtest \ + getfsstat.stderr.exp \ + getfsstat.supp \ + getfsstat.stderr.exp-x86 \ + supponlyobj.vgtest \ + supponlyobj.stderr.exp \ + supponlyobj.supp \ + extattr.vgtest \ + extattr.stderr.exp \ + sigwait.vgtest \ + sigwait.stdout.exp \ + sigwait.stderr.exp \ + sigwait.stderr.exp-x86 \ + chflags.vgtest\ + chflags.stderr.exp \ + chflags.stderr.exp-x86 \ + get_set_login.vgtest \ + get_set_login.stderr.exp \ + revoke.vgtest \ + revoke.stderr.exp \ + scalar.vgtest \ + scalar.stderr.exp \ + scalar.stderr.exp-x86 \ + scalar.stderr.exp-freebsd130 \ + capsicum.vgtest \ + capsicum.stderr.exp \ + getfh.vgtest \ + getfh.stderr.exp \ + linkat.vgtest \ + linkat.stderr.exp \ + scalar_fork.vgtest \ + scalar_fork.stderr.exp \ + scalar_thr_exit.vgtest \ + scalar_thr_exit.stderr.exp \ + scalar_abort2.vgtest \ + scalar_abort2.stderr.exp \ + scalar_pdfork.vgtest \ + scalar_pdfork.stderr.exp \ + scalar_vfork.vgtest \ + scalar_vfork.stderr.exp \ + stat.vgtest \ + stat.stderr.exp \ + stat.stderr.exp-x86 \ + file_locking_wait6.vgtest \ + file_locking_wait6.stderr.exp \ + utimens.vgtest \ + utimens.stderr.exp \ + access.vgtest \ + access.stderr.exp \ + chmod_chown.vgtest \ + chmod_chown.stderr.exp \ + misc.vgtest \ + misc.stderr.exp \ + get_set_context.vgtest \ + get_set_context.stderr.exp \ + get_set_context.stderr.exp-x86 \ + utimes.vgtest \ + utimes.stderr.exp-x86 \ + utimes.stderr.exp \ + static_allocs.vgtest \ + static_allocs.stderr.exp + +check_PROGRAMS = \ + statfs pdfork_pdkill getfsstat inlinfo inlinfo_nested.so extattr \ + sigwait chflags get_set_login revoke scalar capsicum getfh \ + linkat scalar_fork scalar_thr_exit scalar_abort2 scalar_pdfork \ + scalar_vfork stat file_locking_wait6 utimens access chmod_chown \ + misc get_set_context utimes static_allocs + +AM_CFLAGS += $(AM_FLAG_M3264_PRI) +AM_CXXFLAGS += $(AM_FLAG_M3264_PRI) + +inlinfo_SOURCES = inlinfo.c +inlinfo_DEPENDENCIES = inlinfo_nested.so +inlinfo_LDFLAGS = -Wl,-rpath,$(top_builddir)/memcheck/tests/freebsd +inlinfo_LDADD = inlinfo_nested.so +inlinfo_nested_so_SOURCES = inlinfo_nested.c +inlinfo_nested_so_CFLAGS = $(AM_CFLAGS) -fPIC @FLAG_W_NO_UNINITIALIZED@ +inlinfo_nested_so_LDFLAGS = -Wl,-rpath,$(top_builddir)/memcheck/tests/freebsd -shared -fPIC + +scalar_CFLAGS = ${AM_CFLAGS} -g diff --git a/memcheck/tests/freebsd/access.c b/memcheck/tests/freebsd/access.c new file mode 100644 index 0000000000..69e5a36da5 --- /dev/null +++ b/memcheck/tests/freebsd/access.c @@ -0,0 +1,43 @@ +/* + * Tests for various access functions + * + * access + * eaccess + * accessat + */ + + +#include <unistd.h> +#include <stdio.h> +#include <fcntl.h> +#include <string.h> +#include <stdlib.h> + +int main() +{ + if (-1 == access("access.c", R_OK)) + { + perror("access failed:"); + } + + if (-1 == eaccess("access.c", F_OK)) + { + perror("eaccess failed:"); + } + + if (-1 == faccessat(AT_FDCWD, "access.c", R_OK, AT_EACCESS)) + { + perror("accessat failed:"); + } + + // error section + int badint; + char* badstring = strdup("foo"); + free(badstring); + access(badstring, badint); + eaccess(badstring, badint); + faccessat(badint, badstring, badint, badint); + + exit(badint); +} + diff --git a/memcheck/tests/freebsd/access.stderr.exp b/memcheck/tests/freebsd/access.stderr.exp new file mode 100644 index 0000000000..89166dcc31 --- /dev/null +++ b/memcheck/tests/freebsd/access.stderr.exp @@ -0,0 +1,53 @@ +Syscall param access(mode) contains uninitialised byte(s) + at 0x........: access (in /...libc...) + by 0x........: main (access.c:37) + +Syscall param access(pathname) points to unaddressable byte(s) + at 0x........: access (in /...libc...) + by 0x........: main (access.c:37) + Address 0x........ is 0 bytes inside a block of size 4 free'd + at 0x........: free (vg_replace_malloc.c:...) + by 0x........: main (access.c:36) + Block was alloc'd at + at 0x........: malloc (vg_replace_malloc.c:...) + ... + by 0x........: main (access.c:35) + +Syscall param eaccess(mode) contains uninitialised byte(s) + at 0x........: eaccess (in /...libc...) + by 0x........: main (access.c:38) + +Syscall param eaccess(path) points to unaddressable byte(s) + at 0x........: eaccess (in /...libc...) + by 0x........: main (access.c:38) + Address 0x........ is 0 bytes inside a block of size 4 free'd + at 0x........: free (vg_replace_malloc.c:...) + by 0x........: main (access.c:36) + Block was alloc'd at + at 0x........: malloc (vg_replace_malloc.c:...) + ... + by 0x........: main (access.c:35) + +Syscall param faccessat(fd) contains uninitialised byte(s) + at 0x........: faccessat (in /...libc...) + by 0x........: main (access.c:39) + +Syscall param faccessat(flag) contains uninitialised byte(s) + at 0x........: faccessat (in /...libc...) + by 0x........: main (access.c:39) + +Syscall param faccessat(path) points to unaddressable byte(s) + at 0x........: faccessat (in /...libc...) + by 0x........: main (access.c:39) + Address 0x........ is 0 bytes inside a block of size 4 free'd + at 0x........: free (vg_replace_malloc.c:...) + by 0x........: main (access.c:36) + Block was alloc'd at + at 0x........: malloc (vg_replace_malloc.c:...) + ... + by 0x........: main (access.c:35) + +Syscall param exit(status) contains uninitialised byte(s) + ... + by 0x........: main (access.c:41) + diff --git a/memcheck/tests/freebsd/access.vgtest b/memcheck/tests/freebsd/access.vgtest new file mode 100644 index 0000000000..28b90a030f --- /dev/null +++ b/memcheck/tests/freebsd/access.vgtest @@ -0,0 +1,3 @@ +prereq: test -e ./access +prog: access +vgopts: -q diff --git a/memcheck/tests/freebsd/capsicum.c b/memcheck/tests/freebsd/capsicum.c new file mode 100644 index 0000000000..c9cba9b588 --- /dev/null +++ b/memcheck/tests/freebsd/capsicum.c @@ -0,0 +1,97 @@ +#include <sys/capsicum.h> +#include <assert.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <errno.h> +#include <unistd.h> +#include <err.h> +#include <sys/ioccom.h> +#include <net/bpf.h> + +int main(void) +{ + u_int mode; + if (-1 == cap_getmode(&mode)) { + perror("cap_getmode() failed:"); + exit(1); + } else { + assert(mode == 0U); + } + + // example from man cap_rights_get + cap_rights_t setrights, getrights; + int fd; + + memset(&setrights, 0, sizeof(setrights)); + memset(&getrights, 0, sizeof(getrights)); + + fd = open("capsicum.c", O_RDONLY); + if (fd < 0) + err(1, "open() failed"); + + cap_rights_init(&setrights, CAP_IOCTL, CAP_FSTAT, CAP_READ); + if (cap_rights_limit(fd, &setrights) < 0 && errno != ENOSYS) + err(1, "cap_rights_limit() failed"); + + unsigned long cmds[] = { BIOCGSTATS, BIOCROTZBUF }; + if (cap_ioctls_limit(fd, cmds, sizeof(cmds) / sizeof(cmds[0])) < 0 && errno != ENOSYS) { + err(1, "cap_ioctls_limit() filed"); + } + + uint32_t fcntlrights = CAP_FCNTL_GETFL | CAP_FCNTL_SETFL; + if (cap_fcntls_limit(STDIN_FILENO, fcntlrights) < 0 && errno != ENOSYS) { + err(1, "cap_fcnls_limit() filed"); + } + + if (cap_rights_get(fd, &getrights) < 0 && errno != ENOSYS) + err(1, "cap_rights_get() failed"); + + assert(memcmp(&setrights, &getrights, sizeof(setrights)) == 0); + + unsigned long getcmds[2]; + if (cap_ioctls_get(fd, getcmds, 2) < 0 && errno != ENOSYS) + err(1, "cap_ioctls_get() failed"); + + assert(memcmp(cmds, getcmds, sizeof(cmds)) == 0); + + uint32_t getfcntlrights; + if (cap_fcntls_get(STDIN_FILENO, &getfcntlrights) < 0 && errno != ENOSYS) { + err(1, "cap_fcnls_limit() filed"); + } + + assert(fcntlrights == getfcntlrights); + + //close(fd); + + cap_enter(); + + if (-1 == cap_getmode(&mode)) { + perror("cap_getmode() failed:"); + exit(1); + } else { + assert(mode != 0U); + } + + // error section + + int *px = malloc(sizeof(int)); + int x = px[0]; + + cap_getmode(NULL); + + cap_rights_get(0, NULL); + cap_rights_get(x, &getrights); + cap_rights_t* badrights = malloc(sizeof(cap_rights_t)); + cap_rights_init(badrights, CAP_FSTAT, CAP_READ); + free(badrights); + cap_rights_get(0, badrights); + + cap_rights_limit(x, &setrights); + + cap_rights_limit(fd, badrights); + + int fd2 = open("foo", O_RDWR); + if (fd2 >= 0) + err(1, "open in write mode should have failed"); +} diff --git a/memcheck/tests/freebsd/capsicum.stderr.exp b/memcheck/tests/freebsd/capsicum.stderr.exp new file mode 100644 index 0000000000..3d70dbf821 --- /dev/null +++ b/memcheck/tests/freebsd/capsicum.stderr.exp @@ -0,0 +1,41 @@ +WARNING: Valgrind may not operate correctly in capability mode. + Please consider disabling capability by using the RUNNING_ON_VALGRIND mechanism. + See http://valgrind.org/docs/manual/manual-core-adv.html#manual-core-adv.clientreq +Syscall param cap_getmode(modep) points to unaddressable byte(s) + ... + by 0x........: main (capsicum.c:81) + Address 0x........ is not stack'd, malloc'd or (recently) free'd + +Syscall param cap_rights_get(rights) points to unaddressable byte(s) + ... + by 0x........: main (capsicum.c:83) + Address 0x........ is not stack'd, malloc'd or (recently) free'd + +Syscall param cap_rights_get(fd) contains uninitialised byte(s) + ... + by 0x........: main (capsicum.c:84) + +Syscall param cap_rights_get(rights) points to unaddressable byte(s) + ... + by 0x........: main (capsicum.c:88) + Address 0x........ is 0 bytes inside a block of size 16 free'd + at 0x........: free (vg_replace_malloc.c:...) + by 0x........: main (capsicum.c:87) + Block was alloc'd at + at 0x........: malloc (vg_replace_malloc.c:...) + by 0x........: main (capsicum.c:85) + +Syscall param cap_rights_limit(fd) contains uninitialised byte(s) + ... + by 0x........: main (capsicum.c:90) + +Syscall param cap_rights_limit(rights) points to unaddressable byte(s) + ... + by 0x........: main (capsicum.c:92) + Address 0x........ is 0 bytes inside a block of size 16 free'd + at 0x........: free (vg_replace_malloc.c:...) + by 0x........: main (capsicum.c:87) + Block was alloc'd at + at 0x........: malloc (vg_replace_malloc.c:...) + by 0x........: main (capsicum.c:85) + diff --git a/memcheck/tests/freebsd/capsicum.vgtest b/memcheck/tests/freebsd/capsicum.vgtest new file mode 100644 index 0000000000..f6ec3e12e7 --- /dev/null +++ b/memcheck/tests/freebsd/capsicum.vgtest @@ -0,0 +1,3 @@ +prereq: test -e ./capsicum +prog: capsicum +vgopts: -q diff --git a/memcheck/tests/freebsd/chflags.c b/memcheck/tests/freebsd/chflags.c new file mode 100644 index 0000000000..b32a44b4f4 --- /dev/null +++ b/memcheck/tests/freebsd/chflags.c @@ -0,0 +1,43 @@ +#include <sys/stat.h> +#include <unistd.h> +#include <fcntl.h> +#include <string.h> +#include <stdlib.h> +#include "../../memcheck.h" + + +int main() +{ + const char* filename = strdup("chflags.tst"); + int fd = open(filename, O_RDWR | O_CREAT, S_IRUSR | S_IWUSR); + + fchflags(fd, UF_APPEND); + + // a couple of errors while the file is open + int badfd = fd; + unsigned long badflags = UF_NODUMP; + VALGRIND_MAKE_MEM_UNDEFINED(&badfd, sizeof(int)); + VALGRIND_MAKE_MEM_UNDEFINED(&badflags, sizeof(unsigned long)); + + fchflags(badfd, UF_REPARSE); + fchflags(fd, badflags); + close(fd); + + chflags(filename, UF_SYSTEM); + lchflags(filename, UF_SYSTEM); + chflagsat(AT_FDCWD, filename, UF_SYSTEM, 0); + + chflags(filename, badflags); + lchflags(filename, badflags); + chflagsat(AT_FDCWD, filename, badflags, 0); + + int badatflag; + chflagsat(AT_FDCWD, filename, UF_SYSTEM, badatflag); + + free((void*)filename); + + chflags(filename, UF_SYSTEM); + lchflags(filename, UF_SYSTEM); + chflagsat(AT_FDCWD, filename, UF_SYSTEM, 0); +} + diff --git a/memcheck/tests/freebsd/chflags.stderr.exp b/memcheck/tests/freebsd/chflags.stderr.exp new file mode 100644 index 0000000000..82c11d13b2 --- /dev/null +++ b/memcheck/tests/freebsd/chflags.stderr.exp @@ -0,0 +1,57 @@ +Syscall param fchflags(fd) contains uninitialised byte(s) + at 0x........: fchflags (in /...libc...) + by 0x........: main (chflags.c:22) + +Syscall param fchflags(flags) contains uninitialised byte(s) + at 0x........: fchflags (in /...libc...) + by 0x........: main (chflags.c:23) + +Syscall param chflags(flags) contains uninitialised byte(s) + at 0x........: chflags (in /...libc...) + by 0x........: main (chflags.c:30) + +Syscall param lchflags(flags) contains uninitialised byte(s) + at 0x........: lchflags (in /...libc...) + by 0x........: main (chflags.c:31) + +Syscall param chflagsat(flags) contains uninitialised byte(s) + at 0x........: chflagsat (in /...libc...) + by 0x........: main (chflags.c:32) + +Syscall param chflagsat(atflag) contains uninitialised byte(s) + at 0x........: chflagsat (in /...libc...) + by 0x........: main (chflags.c:35) + +Syscall param chflags(path) points to unaddressable byte(s) + at 0x........: chflags (in /...libc...) + by 0x........: main (chflags.c:39) + Address 0x........ is 0 bytes inside a block of size 12 free'd + at 0x........: free (vg_replace_malloc.c:...) + by 0x........: main (chflags.c:37) + Block was alloc'd at + at 0x........: malloc (vg_replace_malloc.c:...) + ... + by 0x........: main (chflags.c:11) + +Syscall param lchflags(path) points to unaddressable byte(s) + at 0x........: lchflags (in /...libc...) + by 0x........: main (chflags.c:40) + Address 0x........ is 0 bytes inside a block of size 12 free'd + at 0x........: free (vg_replace_malloc.c:...) + by 0x........: main (chflags.c:37) + Block was alloc'd at + at 0x........: malloc (vg_replace_malloc.c:...) + ... + by 0x........: main (chflags.c:11) + +Syscall param chflagsat(path) points to unaddressable byte(s) + at 0x........: chflagsat (in /...libc...) + by 0x........: main (chflags.c:41) + Address 0x........ is 0 bytes inside a block of size 12 free'd + at 0x........: free (vg_replace_malloc.c:...) + by 0x........: main (chflags.c:37) + Block was alloc'd at + at 0x........: malloc (vg_replace_malloc.c:...) + ... + by 0x........: main (chflags.c:11) + diff --git a/memcheck/tests/freebsd/chflags.stderr.exp-x86 b/memcheck/tests/freebsd/chflags.stderr.exp-x86 new file mode 100644 index 0000000000..61e0aae414 --- /dev/null +++ b/memcheck/tests/freebsd/chflags.stderr.exp-x86 @@ -0,0 +1,58 @@ +Invalid read of size 4 + at 0x........: main (chflags.c:23) + Address 0x........ is 0 bytes inside a block of size 4 free'd + at 0x........: free (vg_replace_malloc.c:...) + by 0x........: main (chflags.c:21) + Block was alloc'd at + at 0x........: malloc (vg_replace_malloc.c:...) + by 0x........: main (chflags.c:15) + +Invalid read of size 4 + at 0x........: main (chflags.c:27) + Address 0x........ is 0 bytes inside a block of size 4 free'd + at 0x........: free (vg_replace_malloc.c:...) + by 0x........: main (chflags.c:25) + Block was alloc'd at + at 0x........: malloc (vg_replace_malloc.c:...) + by 0x........: main (chflags.c:16) + +Invalid read of size 4 + at 0x........: main (chflags.c:34) + Address 0x........ is 0 bytes inside a block of size 4 free'd + at 0x........: free (vg_replace_malloc.c:...) + by 0x........: main (chflags.c:25) + Block was alloc'd at + at 0x........: malloc (vg_replace_malloc.c:...) + by 0x........: main (chflags.c:16) + +Invalid read of size 4 + at 0x........: main (chflags.c:35) + Address 0x........ is 0 bytes inside a block of size 4 free'd + at 0x........: free (vg_replace_malloc.c:...) + by 0x........: main (chflags.c:25) + Block was alloc'd at + at 0x........: malloc (vg_replace_malloc.c:...) + by 0x........: main (chflags.c:16) + +Syscall param chflags(path) points to unaddressable byte(s) + at 0x........: chflags (in /...libc...) + by 0x........: main (chflags.c:39) + Address 0x........ is 0 bytes inside a block of size 12 free'd + at 0x........: free (vg_replace_malloc.c:...) + by 0x........: main (chflags.c:37) + Block was alloc'd at + at 0x........: malloc (vg_replace_malloc.c:...) + ... + by 0x........: main (chflags.c:9) + +Syscall param chflags(path) points to unaddressable byte(s) + at 0x........: lchflags (in /...libc...) + by 0x........: main (chflags.c:40) + Address 0x........ is 0 bytes inside a block of size 12 free'd + at 0x........: free (vg_replace_malloc.c:...) + by 0x........: main (chflags.c:37) + Block was alloc'd at + at 0x........: malloc (vg_replace_malloc.c:...) + ... + by 0x........: main (chflags.c:9) + diff --git a/memcheck/tests/freebsd/chflags.vgtest b/memcheck/tests/freebsd/chflags.vgtest new file mode 100644 index 0000000000..f9fa4b4d0e --- /dev/null +++ b/memcheck/tests/freebsd/chflags.vgtest @@ -0,0 +1,4 @@ +prog: chflags +vgopts: -q +cleanup: rm -f chflags.tst + diff --git a/memcheck/tests/freebsd/chmod_chown.c b/memcheck/tests/freebsd/chmod_chown.c new file mode 100644 index 0000000000..1fe40f4145 --- /dev/null +++ b/memcheck/tests/freebsd/chmod_chown.c @@ -0,0 +1,65 @@ +/* + * Test this family of functions + * lchmod chownat lchownat + */ + +#include <unistd.h> +#include <dirent.h> +#include <string.h> +#include <stdio.h> +#include <stdlib.h> +#include <sys/stat.h> + +int main(void) +{ + char buff[64]; + char tmpfile[] = "/tmp/test_chmod_chown.XXXXXX"; + char tmplink[] = "/tmp/test_chx_link.XXXXXX"; + int tmpfd = mkstemp(tmpfile); + mktemp(tmplink); + + memset(buff, 0, sizeof(buff)); + sprintf(buff, "some data"); + write(tmpfd, buff, strlen(buff)+1); + close (tmpfd); + + DIR* tmpdir = opendir("/tmp"); + if (tmpdir) { + int tmpdirfd = dirfd(tmpdir); + + if (-1 == symlinkat(tmpfile+5, tmpdirfd, tmplink+5)) { + perror("linkat failed"); + } + + if (-1 == lchmod(tmplink, S_IRWXU|S_IRWXG|S_IRWXO)) + { + perror("lchmod failed:"); + } + + if (fchmodat(tmpdirfd, tmpfile+5, S_IRWXU|S_IRWXG|S_IRWXO, 0)) + { + perror("fchmodat failed:"); + } + + // no test for failure as not everyone runnning this will be a member of group 921 + fchownat(tmpdirfd, tmpfile+5, getuid(), 920, 0); + + closedir(tmpdir); + } + + unlink(tmpfile); + unlink(tmplink); + + // error section + char* badstring = strdup("foo"); + free(badstring); + int badint1; + int badint2; + int badint3; + int badint4; + + lchmod(badstring, badint1); + fchmodat(badint1, badstring, badint2, badint3); + fchownat(badint1, badstring, badint2, badint3, badint4); +} + diff --git a/memcheck/tests/freebsd/chmod_chown.stderr.exp b/memcheck/tests/freebsd/chmod_chown.stderr.exp new file mode 100644 index 0000000000..87a76a1252 --- /dev/null +++ b/memcheck/tests/freebsd/chmod_chown.stderr.exp @@ -0,0 +1,65 @@ +Syscall param lchmod(mode) contains uninitialised byte(s) + ... + by 0x........: main (chmod_chown.c:61) + +Syscall param lchmod(path) points to unaddressable byte(s) + ... + by 0x........: main (chmod_chown.c:61) + Address 0x........ is 0 bytes inside a block of size 4 free'd + at 0x........: free (vg_replace_malloc.c:...) + by 0x........: main (chmod_chown.c:55) + Block was alloc'd at + at 0x........: malloc (vg_replace_malloc.c:...) + ... + by 0x........: main (chmod_chown.c:54) + +Syscall param fchmodat(fd) contains uninitialised byte(s) + ... + by 0x........: main (chmod_chown.c:62) + +Syscall param fchmodat(mode) contains uninitialised byte(s) + ... + by 0x........: main (chmod_chown.c:62) + +Syscall param fchmodat(flag) contains uninitialised byte(s) + ... + by 0x........: main (chmod_chown.c:62) + +Syscall param fchmodat(path) points to unaddressable byte(s) + ... + by 0x........: main (chmod_chown.c:62) + Address 0x........ is 0 bytes inside a block of size 4 free'd + at 0x........: free (vg_replace_malloc.c:...) + by 0x........: main (chmod_chown.c:55) + Block was alloc'd at + at 0x........: malloc (vg_replace_malloc.c:...) + ... + by 0x........: main (chmod_chown.c:54) + +Syscall param fchownat(fd) contains uninitialised byte(s) + ... + by 0x........: main (chmod_chown.c:63) + +Syscall param fchownat(owner) contains uninitialised byte(s) + ... + by 0x........: main (chmod_chown.c:63) + +Syscall param fchownat(group) contains uninitialised byte(s) + ... + by 0x........: main (chmod_chown.c:63) + +Syscall param fchownat(flag) contains uninitialised byte(s) + ... + by 0x........: main (chmod_chown.c:63) + +Syscall param fchownat(path) points to unaddressable byte(s) + ... + by 0x........: main (chmod_chown.c:63) + Address 0x........ is 0 bytes inside a block of size 4 free'd + at 0x........: free (vg_replace_malloc.c:...) + by 0x........: main (chmod_chown.c:55) + Block was alloc'd at + at 0x........: malloc (vg_replace_malloc.c:...) + ... + by 0x........: main (chmod_chown.c:54) + diff --git a/memcheck/tests/freebsd/chmod_chown.vgtest b/memcheck/tests/freebsd/chmod_chown.vgtest new file mode 100644 index 0000000000..db60bb886f --- /dev/null +++ b/memcheck/tests/freebsd/chmod_chown.vgtest @@ -0,0 +1,3 @@ +prereq: test -e ./chmod_chown +prog: chmod_chown +vgopts: -q diff --git a/memcheck/tests/freebsd/dump_stdout b/memcheck/tests/freebsd/dump_stdout new file mode 100755 index 0000000000..a8b7c3e935 --- /dev/null +++ b/memcheck/... [truncated message content] |