|
From: Paul F. <pa...@so...> - 2025-11-29 20:17:43
|
https://sourceware.org/cgit/valgrind/commit/?id=dde5c22436e7b8c8f73b8366ed8e5ec967a132c4 commit dde5c22436e7b8c8f73b8366ed8e5ec967a132c4 Author: Paul Floyd <pj...@wa...> Date: Sat Nov 29 21:14:44 2025 +0100 Darwin: updates to macho loading and turn off hanging regtests Code merges from Louis Brunner. Turn off 7 tests that are hanging. Updates to filtering. Diff: --- configure.ac | 9 ++++ coregrind/m_debuginfo/debuginfo.c | 7 ++- coregrind/m_debuginfo/readmacho.c | 93 +++++++++++++++++--------------- drd/tests/annotate_sem.vgtest | 2 +- drd/tests/pth_cond_destroy_busy.vgtest | 2 +- drd/tests/swapcontext.vgtest | 2 +- helgrind/tests/bug392331.vgtest | 2 +- helgrind/tests/bug392331_supp.vgtest | 2 +- helgrind/tests/filter_stderr.in | 9 +++- helgrind/tests/shared_timed_mutex.vgtest | 2 +- helgrind/tests/tc22_exit_w_lock.vgtest | 2 +- helgrind/tests/tc24_nonzero_sem.c | 5 +- 12 files changed, 84 insertions(+), 53 deletions(-) diff --git a/configure.ac b/configure.ac index 09a352a707..54df9c1e19 100644 --- a/configure.ac +++ b/configure.ac @@ -396,6 +396,15 @@ case "${host_os}" in AC_DEFINE([DARWIN_10_11], 101100, [DARWIN_VERS value for Mac OS X 10.11]) AC_DEFINE([DARWIN_10_12], 101200, [DARWIN_VERS value for macOS 10.12]) AC_DEFINE([DARWIN_10_13], 101300, [DARWIN_VERS value for macOS 10.13]) + AC_DEFINE([DARWIN_10_14], 101400, [DARWIN_VERS value for macOS 10.14 / iOS 12]) + AC_DEFINE([DARWIN_10_15], 101500, [DARWIN_VERS value for macOS 10.15 / iOS 13]) + AC_DEFINE([DARWIN_11_00], 110000, [DARWIN_VERS value for macOS 11.0 / iOS 14]) + AC_DEFINE([DARWIN_12_00], 120000, [DARWIN_VERS value for macOS 12.0 / iOS 15]) + AC_DEFINE([DARWIN_13_00], 130000, [DARWIN_VERS value for macOS 13.0 / iOS 16]) + AC_DEFINE([DARWIN_14_00], 140000, [DARWIN_VERS value for macOS 14.0 / iOS 17]) + AC_DEFINE([DARWIN_15_00], 150000, [DARWIN_VERS value for macOS 15.0 / iOS 18]) + AC_DEFINE([DARWIN_15_04], 150400, [DARWIN_VERS value for macOS 15.4]) + AC_DEFINE([DARWIN_26_00], 260000, [DARWIN_VERS value for macOS / iOS 26]) AC_MSG_CHECKING([for the kernel version]) kernel=`uname -r` diff --git a/coregrind/m_debuginfo/debuginfo.c b/coregrind/m_debuginfo/debuginfo.c index 18152b9e25..bb208925d4 100644 --- a/coregrind/m_debuginfo/debuginfo.c +++ b/coregrind/m_debuginfo/debuginfo.c @@ -60,11 +60,11 @@ #if defined(VGO_linux) || defined(VGO_solaris) || defined(VGO_freebsd) # include "priv_readelf.h" # include "priv_readdwarf3.h" -# include "priv_readpdb.h" #elif defined(VGO_darwin) # include "priv_readmacho.h" -# include "priv_readpdb.h" +# include "pub_core_mach.h" #endif +# include "priv_readpdb.h" #if defined(VGO_freebsd) #include "pub_core_clientstate.h" #endif @@ -1196,6 +1196,9 @@ ULong VG_(di_notify_mmap)( Addr a, Bool allow_SkFileV, Int use_fd ) if (sr_isError(statres)) { DebugInfo fake_di; Bool quiet = VG_(strstr)(filename, "/var/run/nscd/") != NULL +#if defined(VGO_darwin) + || VG_(strstr)(filename, DARWIN_FAKE_MEMORY_PATH) != NULL +#endif || VG_(strstr)(filename, "/dev/shm/") != NULL || VG_(strncmp)("/memfd:", filename, VG_(strlen)("/memfd:")) == 0; diff --git a/coregrind/m_debuginfo/readmacho.c b/coregrind/m_debuginfo/readmacho.c index 31f56134d6..dc2023bc77 100644 --- a/coregrind/m_debuginfo/readmacho.c +++ b/coregrind/m_debuginfo/readmacho.c @@ -83,6 +83,41 @@ /*--- ---*/ /*------------------------------------------------------------*/ +static Int count_rw_loads(const struct load_command* macho_load_commands, unsigned int ncmds) +{ + Int rw_loads = 0; + const struct load_command* lc = (const struct load_command*)macho_load_commands; + for (unsigned int i = 0U; i < ncmds; ++i) { + if (lc->cmd == LC_SEGMENT_CMD) { + const struct SEGMENT_COMMAND* sc = (const struct SEGMENT_COMMAND*)lc; + if (sc->initprot == 3 && sc->filesize +#if DARWIN_VERS >= DARWIN_13_00 +// FIXME: somehow __DATA_CONST appears as rw- in most binaries in macOS 13 and later (not sure when that started) +// so we ignore it otherwise some binaries don't get symbols + && VG_(strcmp)(sc->segname, "__DATA_CONST") != 0 +#endif + ) { + rw_loads += 1; + } + } + const char* tmp = (const char*)lc + lc->cmdsize; + lc = (const struct load_command*)tmp; + } + return rw_loads; +} + +static Bool check_fat_macho_and_get_rw_loads(const void* macho_header, Int* rw_loads) +{ + const struct fat_header* fh_be = (const struct fat_header*)macho_header; + vg_assert(fh_be); + if (VG_(ntohl)(fh_be->magic) == FAT_MAGIC) { + // @todo PJF not yet handled, previous behaviour was to assume that the count is 1 + *rw_loads = 1; + return True; + } + return False; +} + /* A DiSlice is used to handle the thin/fat distinction for MachO images. (1) the entire mapped-in ("primary") image, fat headers, kitchen sink, whatnot: the entire file. This is the DiImage* that is the backing @@ -93,20 +128,11 @@ memory that falls entirely inside the primary image. */ +STATIC_ASSERT(sizeof(struct fat_header) <= sizeof(struct MACH_HEADER)); + Bool ML_(check_macho_and_get_rw_loads)( Int fd, Int* rw_loads ) { - /* (JRS: the Mach-O headers might not be in this mapped data, - because we only mapped a page for this initial check, - or at least not very much, and what's at the start of the file - is in general a so-called fat header. The Mach-O object we're - interested in could be arbitrarily far along the image, and so - we can't assume its header will fall within this page.) */ - - /* But we can say that either it's a fat object, in which case it - begins with a fat header, or it's unadorned Mach-O, in which - case it starts with a normal header. At least do what checks we - can to establish whether or not we're looking at something - sane. */ + vg_assert(rw_loads); HChar macho_header[sizeof(struct MACH_HEADER)]; SysRes preadres = VG_(pread)( fd, macho_header, sizeof(struct MACH_HEADER), 0 ); @@ -115,43 +141,26 @@ Bool ML_(check_macho_and_get_rw_loads)( Int fd, Int* rw_loads ) return False; } - const struct fat_header* fh_be = (const struct fat_header*)macho_header; - const struct MACH_HEADER* mh = (const struct MACH_HEADER*)macho_header; - - vg_assert(fh_be); - vg_assert(mh); - vg_assert(rw_loads); - STATIC_ASSERT(sizeof(struct fat_header) <= sizeof(struct MACH_HEADER)); - if (VG_(ntohl)(fh_be->magic) == FAT_MAGIC) { - // @todo PJF not yet handled, previous behaviour was to assume that the count is 1 - *rw_loads = 1; + if (check_fat_macho_and_get_rw_loads(macho_header, rw_loads)) { return True; } - if (mh->magic == MAGIC) { - HChar* macho_load_commands = ML_(dinfo_zalloc)("di.readmacho.macho_load_commands", mh->sizeofcmds); - preadres = VG_(pread)( fd, macho_load_commands, mh->sizeofcmds, sizeof(struct MACH_HEADER) ); - if (sr_isError(preadres) || sr_Res(preadres) < mh->sizeofcmds) { - ML_(dinfo_free)(macho_load_commands); - return False; - } + const struct MACH_HEADER* mh = (const struct MACH_HEADER*)macho_header; + vg_assert(mh); + if (mh->magic != MAGIC) { + return False; + } - const struct load_command* lc = (const struct load_command*)macho_load_commands; - for (unsigned int i = 0U; i < mh->ncmds; ++i) { - if (lc->cmd == LC_SEGMENT_CMD) { - const struct SEGMENT_COMMAND* sc = (const struct SEGMENT_COMMAND*)lc; - if (sc->initprot == 3 && sc->filesize) { - ++*rw_loads; - } - } - const char* tmp = (const char*)lc + lc->cmdsize; - lc = (const struct load_command*)tmp; - } + HChar* macho_load_commands = ML_(dinfo_zalloc)("di.readmacho.macho_load_commands", mh->sizeofcmds); + preadres = VG_(pread)( fd, macho_load_commands, mh->sizeofcmds, sizeof(struct MACH_HEADER) ); + if (sr_isError(preadres) || sr_Res(preadres) < mh->sizeofcmds) { ML_(dinfo_free)(macho_load_commands); - return True; + return False; } - return False; + *rw_loads = count_rw_loads((const struct load_command*)macho_load_commands, mh->ncmds); + ML_(dinfo_free)(macho_load_commands); + return True; } diff --git a/drd/tests/annotate_sem.vgtest b/drd/tests/annotate_sem.vgtest index 3c5071ca14..4cec9ee371 100644 --- a/drd/tests/annotate_sem.vgtest +++ b/drd/tests/annotate_sem.vgtest @@ -1,4 +1,4 @@ -prereq: test -e annotate_sem && ./supported_libpthread +prereq: test -e annotate_sem && ./supported_libpthread && ! ../../tests/os_test darwin vgopts: --fair-sched=try --read-var-info=yes --check-stack-var=yes --show-confl-seg=no prog: annotate_sem stderr_filter: filter_stderr_and_thread_no diff --git a/drd/tests/pth_cond_destroy_busy.vgtest b/drd/tests/pth_cond_destroy_busy.vgtest index f3cf778252..a5895f3520 100644 --- a/drd/tests/pth_cond_destroy_busy.vgtest +++ b/drd/tests/pth_cond_destroy_busy.vgtest @@ -1,2 +1,2 @@ -prereq: ./supported_libpthread && ! ../../tests/libc_test glibc 2.24.90 +prereq: ./supported_libpthread && ! ../../tests/libc_test glibc 2.24.90 && ! ../../tests/os_test darwin prog: pth_cond_destroy_busy diff --git a/drd/tests/swapcontext.vgtest b/drd/tests/swapcontext.vgtest index 98e3712c40..0c05ab7021 100644 --- a/drd/tests/swapcontext.vgtest +++ b/drd/tests/swapcontext.vgtest @@ -1,4 +1,4 @@ -prereq: test -e swapcontext && ./supported_libpthread +prereq: test -e swapcontext && ./supported_libpthread && ! ../../tests/os_test darwin vgopts: --read-var-info=yes --check-stack-var=yes --show-confl-seg=no --num-callers=2 prog: swapcontext stderr_filter: filter_stderr diff --git a/helgrind/tests/bug392331.vgtest b/helgrind/tests/bug392331.vgtest index f300c5cc13..3484935de7 100644 --- a/helgrind/tests/bug392331.vgtest +++ b/helgrind/tests/bug392331.vgtest @@ -1,4 +1,4 @@ -prereq: test -e bug392331 +prereq: test -e bug392331 && ! ../../tests/os_test darwin vgopts: -q --check-cond-signal-mutex=yes prog: bug392331 stderr_filter: filter_bug392331 diff --git a/helgrind/tests/bug392331_supp.vgtest b/helgrind/tests/bug392331_supp.vgtest index 64fc729607..5b4c526bf9 100644 --- a/helgrind/tests/bug392331_supp.vgtest +++ b/helgrind/tests/bug392331_supp.vgtest @@ -1,3 +1,3 @@ -prereq: test -e bug392331 +prereq: test -e bug392331 && ! ../../tests/os_test darwin vgopts: -q --suppressions=bug392331.supp prog: bug392331 diff --git a/helgrind/tests/filter_stderr.in b/helgrind/tests/filter_stderr.in index 03a7d9e3b6..3a89f54bd3 100644 --- a/helgrind/tests/filter_stderr.in +++ b/helgrind/tests/filter_stderr.in @@ -19,7 +19,14 @@ fi | # And FreeBSD if $dir/../../tests/os_test freebsd; then - #perl -p $dir/filter_stderr_freebsd + awk -f $dir/filter_freebsd.awk +else + cat +fi | + +# And Darwin +if $dir/../../tests/os_test darwin; then + # reuse the FreeBSD filter to start with awk -f $dir/filter_freebsd.awk else cat diff --git a/helgrind/tests/shared_timed_mutex.vgtest b/helgrind/tests/shared_timed_mutex.vgtest index d3a044379c..8903894e6a 100644 --- a/helgrind/tests/shared_timed_mutex.vgtest +++ b/helgrind/tests/shared_timed_mutex.vgtest @@ -1,3 +1,3 @@ -prereq: test -e ../../drd/tests/shared_timed_mutex +prereq: test -e ../../drd/tests/shared_timed_mutex && ! ../../tests/os_test darwin vgopts: --read-var-info=yes prog: ../../drd/tests/shared_timed_mutex diff --git a/helgrind/tests/tc22_exit_w_lock.vgtest b/helgrind/tests/tc22_exit_w_lock.vgtest index 2e6190a727..8dd7531ec5 100644 --- a/helgrind/tests/tc22_exit_w_lock.vgtest +++ b/helgrind/tests/tc22_exit_w_lock.vgtest @@ -1,3 +1,3 @@ -prereq: test -e tc22_exit_w_lock +prereq: test -e tc22_exit_w_lock && ! ../../tests/os_test darwin prog: tc22_exit_w_lock cleanup: rm -f vgcore.* diff --git a/helgrind/tests/tc24_nonzero_sem.c b/helgrind/tests/tc24_nonzero_sem.c index 541fa7ddb8..2fe4081913 100644 --- a/helgrind/tests/tc24_nonzero_sem.c +++ b/helgrind/tests/tc24_nonzero_sem.c @@ -44,7 +44,10 @@ int main ( void ) assert(!r); } - r= my_sem_destroy(sem); assert(!r); + r= my_sem_destroy(sem); +#if !defined(VGO_darwin) + assert(!r); +#endif return 0; } |