]> git.ipfire.org Git - thirdparty/valgrind.git/commitdiff
Darwin: updates to macho loading and turn off hanging regtests
authorPaul Floyd <pjfloyd@wanadoo.fr>
Sat, 29 Nov 2025 20:14:44 +0000 (21:14 +0100)
committerPaul Floyd <pjfloyd@wanadoo.fr>
Sat, 29 Nov 2025 20:14:44 +0000 (21:14 +0100)
Code merges from Louis Brunner.
Turn off 7 tests that are hanging.
Updates to filtering.

12 files changed:
configure.ac
coregrind/m_debuginfo/debuginfo.c
coregrind/m_debuginfo/readmacho.c
drd/tests/annotate_sem.vgtest
drd/tests/pth_cond_destroy_busy.vgtest
drd/tests/swapcontext.vgtest
helgrind/tests/bug392331.vgtest
helgrind/tests/bug392331_supp.vgtest
helgrind/tests/filter_stderr.in
helgrind/tests/shared_timed_mutex.vgtest
helgrind/tests/tc22_exit_w_lock.vgtest
helgrind/tests/tc24_nonzero_sem.c

index 09a352a707e8e97d3a475a6645ecd762d82a733e..54df9c1e19668d38a33014a0d9cff66a45df9daa 100644 (file)
@@ -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`
index 18152b9e25e4cde23b4ab793b8dc223b82baf808..bb208925d47f062383cd865aa65d7671302fde78 100644 (file)
 #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;
index 31f56134d67e737966e9de964aa78484fd6ebb2e..dc2023bc77f8b150568117f0cb5ac6ecfd39a35d 100644 (file)
 /*---                                                      ---*/
 /*------------------------------------------------------------*/
 
+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
        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;
 }
 
 
index 3c5071ca14510bbab494f99c4426f0db1f1705d8..4cec9ee3714c79b7dd322d5d3a625c2eb45ade75 100644 (file)
@@ -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
index f3cf778252ae71e0c0b7c9a46bc2659bb65a1d57..a5895f3520389d5e456c2e4633e0931181310b31 100644 (file)
@@ -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
index 98e3712c401cb128bbb64e513a0f9873ef6072a1..0c05ab7021161cc1b8c3f6f4002be952128ee8cd 100644 (file)
@@ -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
index f300c5cc13b58a04c0338a81ded5371f4d86d6c7..3484935de77c476f634450075b67caa1dd26631d 100644 (file)
@@ -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
index 64fc729607db4d41f052db28f5eac22b554a58b0..5b4c526bf949d905c0c29ac95517489773cbc6bb 100644 (file)
@@ -1,3 +1,3 @@
-prereq: test -e bug392331
+prereq: test -e bug392331 && ! ../../tests/os_test darwin
 vgopts: -q --suppressions=bug392331.supp
 prog: bug392331
index 03a7d9e3b6bab5a52dfaea66af516a4202c52cae..3a89f54bd3a48fe0e6a16df6f5c6d21b00e5ef52 100644 (file)
@@ -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
index d3a044379c860e7a76ecbe094dd5d83da2cb38ac..8903894e6aad5ac63daab65ad1fa07ed051e7b00 100644 (file)
@@ -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
index 2e6190a727c2c7f8cbb98377f3d633a58b211a3a..8dd7531ec5fb85ecb48bc328fa366485377281f5 100644 (file)
@@ -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.*
index 541fa7ddb8816a1a77aa98b00d046aa656c64b71..2fe408191337e275fba98929a44b8cda84954c76 100644 (file)
@@ -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;
 }