exp-sgcheck.supp \
darwin9.supp darwin9-drd.supp \
darwin10.supp darwin10-drd.supp \
+ darwin11.supp \
bionic.supp
DEFAULT_SUPP_FILES = @DEFAULT_SUPP@
clean-local:
rm -rf $(inplacedir)
-
+# Need config.h in the installed tree, since some files depend on it
+pkginclude_HEADERS = config.h
# Nb: for Darwin we set DEFAULT_SUPP here. That's because Darwin
# has only one relevant version, the OS version. The `uname` check
# is a good way to get that version (i.e. "Darwin 9.6.0" is Mac OS
- # X 10.5.6, and "Darwin 10.x" is Mac OS X 10.6.x Snow Leopard),
+ # X 10.5.6, and "Darwin 10.x" is Mac OS X 10.6.x Snow Leopard,
+ # and possibly "Darwin 11.x" is Mac OS X 10.7.x Lion),
# and we don't know of an macros similar to __GLIBC__ to get that info.
#
# XXX: `uname -r` won't do the right thing for cross-compiles, but
# that's not a problem yet.
+ #
+ # jseward 21 Sept 2011: I seriously doubt whether V 3.7.0 will work
+ # on OS X 10.5.x; I haven't tested yet, and only plan to test 3.7.0
+ # on 10.6.8 and 10.7.1. Although tempted to delete the configure
+ # time support for 10.5 (the 9.* pattern just below), I'll leave it
+ # in for now, just in case anybody wants to give it a try. But I'm
+ # assuming that 3.7.0 is a Snow Leopard and Lion-only release.
case "${kernel}" in
9.*)
AC_MSG_RESULT([Darwin 9.x (${kernel}) / Mac OS X 10.5 Leopard])
DEFAULT_SUPP="darwin10.supp ${DEFAULT_SUPP}"
DEFAULT_SUPP="darwin10-drd.supp ${DEFAULT_SUPP}"
;;
- *)
+ 11.*)
+ AC_MSG_RESULT([Darwin 11.x (${kernel}) / Mac OS X 10.7 Lion])
+ AC_DEFINE([DARWIN_VERS], DARWIN_10_7, [Darwin / Mac OS X version])
+ # FIXME: change these to xx11.supp
+ DEFAULT_SUPP="darwin11.supp ${DEFAULT_SUPP}"
+ DEFAULT_SUPP="darwin10-drd.supp ${DEFAULT_SUPP}"
+ ;;
+ *)
AC_MSG_RESULT([unsupported (${kernel})])
- AC_MSG_ERROR([Valgrind works on Darwin 9.x and 10.x (Mac OS X 10.5 and 10.6)])
+ AC_MSG_ERROR([Valgrind works on Darwin 10.x and 11.x (Mac OS X 10.6/7)])
;;
esac
;;
#if defined(VGO_linux) || defined(VGO_darwin)
/* The debug info system is driven by notifications that a text
- segment has been mapped in, or unmapped. When that happens it
- tries to acquire/discard whatever info is available for the
- corresponding object. This section contains the notification
- handlers. */
+ segment has been mapped in, or unmapped, or when sections change
+ permission. It's all a bit kludgey and basically means watching
+ syscalls, trying to second-guess when the system's dynamic linker
+ is done with mapping in a new object for execution. This is all
+ tracked using the DebugInfoFSM struct for the object. Anyway, once
+ we finally decide we've got to an accept state, this section then
+ will acquire whatever info is available for the corresponding
+ object. This section contains the notification handlers, which
+ update the FSM and determine when an accept state has been reached.
+*/
+
+/* When the sequence of observations causes a DebugInfoFSM to move
+ into the accept state, call here to actually get the debuginfo read
+ in. Returns a ULong whose purpose is described in comments
+ preceding VG_(di_notify_mmap) just below.
+*/
+static ULong di_notify_ACHIEVE_ACCEPT_STATE ( struct _DebugInfo* di )
+{
+ ULong di_handle;
+ Bool ok;
+
+ vg_assert(di->fsm.filename);
+ TRACE_SYMTAB("\n");
+ TRACE_SYMTAB("------ start ELF OBJECT "
+ "------------------------------\n");
+ TRACE_SYMTAB("------ name = %s\n", di->fsm.filename);
+ TRACE_SYMTAB("\n");
+
+ /* We're going to read symbols and debug info for the avma
+ ranges [rx_map_avma, +rx_map_size) and [rw_map_avma,
+ +rw_map_size). First get rid of any other DebugInfos which
+ overlap either of those ranges (to avoid total confusion). */
+ discard_DebugInfos_which_overlap_with( di );
+
+ /* .. and acquire new info. */
+# if defined(VGO_linux)
+ ok = ML_(read_elf_debug_info)( di );
+# elif defined(VGO_darwin)
+ ok = ML_(read_macho_debug_info)( di );
+# else
+# error "unknown OS"
+# endif
+
+ if (ok) {
+
+ TRACE_SYMTAB("\n------ Canonicalising the "
+ "acquired info ------\n");
+ /* invalidate the CFI unwind cache. */
+ cfsi_cache__invalidate();
+ /* prepare read data for use */
+ ML_(canonicaliseTables)( di );
+ /* notify m_redir about it */
+ TRACE_SYMTAB("\n------ Notifying m_redir ------\n");
+ VG_(redir_notify_new_DebugInfo)( di );
+ /* Note that we succeeded */
+ di->have_dinfo = True;
+ tl_assert(di->handle > 0);
+ di_handle = di->handle;
+ /* Check invariants listed in
+ Comment_on_IMPORTANT_REPRESENTATIONAL_INVARIANTS in
+ priv_storage.h. */
+ check_CFSI_related_invariants(di);
+
+ } else {
+ TRACE_SYMTAB("\n------ ELF reading failed ------\n");
+ /* Something went wrong (eg. bad ELF file). Should we delete
+ this DebugInfo? No - it contains info on the rw/rx
+ mappings, at least. */
+ di_handle = 0;
+ vg_assert(di->have_dinfo == False);
+ }
+
+ TRACE_SYMTAB("\n");
+ TRACE_SYMTAB("------ name = %s\n", di->fsm.filename);
+ TRACE_SYMTAB("------ end ELF OBJECT "
+ "------------------------------\n");
+ TRACE_SYMTAB("\n");
+
+ return di_handle;
+}
+
/* Notify the debuginfo system about a new mapping. This is the way
new debug information gets loaded. If allow_SkFileV is True, it
{
NSegment const * seg;
HChar* filename;
- Bool ok, is_rx_map, is_rw_map;
+ Bool is_rx_map, is_rw_map, is_ro_map;
DebugInfo* di;
- ULong di_handle;
SysRes fd;
Int nread, oflags;
HChar buf1k[1024];
*/
is_rx_map = False;
is_rw_map = False;
+ is_ro_map = False;
+
# if defined(VGA_x86) || defined(VGA_ppc32)
is_rx_map = seg->hasR && seg->hasX;
is_rw_map = seg->hasR && seg->hasW;
# error "Unknown platform"
# endif
+# if defined(VGP_x86_darwin) && DARWIN_VERS == DARWIN_10_7
+ is_ro_map = seg->hasR && !seg->hasW && !seg->hasX;
+# endif
+
if (debug)
VG_(printf)("di_notify_mmap-3: is_rx_map %d, is_rw_map %d\n",
(Int)is_rx_map, (Int)is_rw_map);
- /* If it is neither text-ish nor data-ish, we're not interested. */
- if (!(is_rx_map || is_rw_map))
+ /* Ignore mappings with permissions we can't possibly be interested in. */
+ if (!(is_rx_map || is_rw_map || is_ro_map))
return 0;
/* Peer at the first few bytes of the file, to see if it is an ELF */
}
}
- /* If we don't have an rx and rw mapping, or if we already have
- debuginfo for this mapping for whatever reason, go no
- further. */
- if ( ! (di->fsm.have_rx_map && di->fsm.have_rw_map && !di->have_dinfo) )
- return 0;
-
- /* Ok, so, finally, let's try to read the debuginfo. */
- vg_assert(di->fsm.filename);
- TRACE_SYMTAB("\n");
- TRACE_SYMTAB("------ start ELF OBJECT "
- "------------------------------\n");
- TRACE_SYMTAB("------ name = %s\n", di->fsm.filename);
- TRACE_SYMTAB("\n");
-
- /* We're going to read symbols and debug info for the avma
- ranges [rx_map_avma, +rx_map_size) and [rw_map_avma,
- +rw_map_size). First get rid of any other DebugInfos which
- overlap either of those ranges (to avoid total confusion). */
- discard_DebugInfos_which_overlap_with( di );
-
- /* .. and acquire new info. */
-# if defined(VGO_linux)
- ok = ML_(read_elf_debug_info)( di );
-# elif defined(VGO_darwin)
- ok = ML_(read_macho_debug_info)( di );
-# else
-# error "unknown OS"
-# endif
-
- if (ok) {
-
- TRACE_SYMTAB("\n------ Canonicalising the "
- "acquired info ------\n");
- /* invalidate the CFI unwind cache. */
- cfsi_cache__invalidate();
- /* prepare read data for use */
- ML_(canonicaliseTables)( di );
- /* notify m_redir about it */
- TRACE_SYMTAB("\n------ Notifying m_redir ------\n");
- VG_(redir_notify_new_DebugInfo)( di );
- /* Note that we succeeded */
- di->have_dinfo = True;
- tl_assert(di->handle > 0);
- di_handle = di->handle;
- /* Check invariants listed in
- Comment_on_IMPORTANT_REPRESENTATIONAL_INVARIANTS in
- priv_storage.h. */
- check_CFSI_related_invariants(di);
+ if (is_ro_map) {
+ /* We have a r-- mapping. Note the details (OSX 10.7, 32-bit only) */
+ if (!di->fsm.have_ro_map) {
+ di->fsm.have_ro_map = True;
+ di->fsm.ro_map_avma = a;
+ di->fsm.ro_map_size = seg->end + 1 - seg->start;
+ di->fsm.ro_map_foff = seg->offset;
+ } else {
+ /* FIXME: complain about a second r-- mapping */
+ }
+ }
+ /* So, finally, are we in an accept state? */
+ if (di->fsm.have_rx_map && di->fsm.have_rw_map && !di->have_dinfo) {
+ /* Ok, so, finally, we found what we need, and we haven't
+ already read debuginfo for this object. So let's do so now.
+ Yee-ha! */
+ return di_notify_ACHIEVE_ACCEPT_STATE ( di );
} else {
- TRACE_SYMTAB("\n------ ELF reading failed ------\n");
- /* Something went wrong (eg. bad ELF file). Should we delete
- this DebugInfo? No - it contains info on the rw/rx
- mappings, at least. */
- di_handle = 0;
- vg_assert(di->have_dinfo == False);
+ /* If we don't have an rx and rw mapping, or if we already have
+ debuginfo for this mapping for whatever reason, go no
+ further. */
+ return 0;
}
-
- TRACE_SYMTAB("\n");
- TRACE_SYMTAB("------ name = %s\n", di->fsm.filename);
- TRACE_SYMTAB("------ end ELF OBJECT "
- "------------------------------\n");
- TRACE_SYMTAB("\n");
-
- return di_handle;
}
}
}
+
+/* This is a MacOSX 10.7 32-bit only special. See comments on the
+ declaration of struct _DebugInfoFSM for details. */
+void VG_(di_notify_vm_protect)( Addr a, SizeT len, UInt prot )
+{
+ Bool do_nothing = True;
+# if defined(VGP_x86_darwin) && DARWIN_VERS == DARWIN_10_7
+ do_nothing = False;
+# endif
+ if (do_nothing /* wrong platform */)
+ return;
+
+ Bool r_ok = toBool(prot & VKI_PROT_READ);
+ Bool w_ok = toBool(prot & VKI_PROT_WRITE);
+ Bool x_ok = toBool(prot & VKI_PROT_EXEC);
+ if (! (r_ok && !w_ok && x_ok))
+ return; /* not an upgrade to r-x */
+
+ /* Find a DebugInfo containing a FSM that has [a, +len) previously
+ observed as a r-- mapping, plus some other rw- mapping. If such
+ is found, conclude we're in an accept state and read debuginfo
+ accordingly. */
+ DebugInfo* di;
+ for (di = debugInfo_list; di; di = di->next) {
+ vg_assert(di->fsm.filename);
+ if (di->have_dinfo)
+ continue; /* already have debuginfo for this object */
+ if (!di->fsm.have_ro_map)
+ continue; /* need to have a r-- mapping for this object */
+ if (di->fsm.have_rx_map)
+ continue; /* rx- mapping already exists */
+ if (!di->fsm.have_rw_map)
+ continue; /* need to have a rw- mapping */
+ if (di->fsm.ro_map_avma != a || di->fsm.ro_map_size != len)
+ continue; /* this isn't an upgrade of the r-- mapping */
+ /* looks like we're in luck! */
+ break;
+ }
+ if (di == NULL)
+ return; /* didn't find anything */
+
+ /* Do the upgrade. Copy the RO map info into the RX map info and
+ pretend we never saw the RO map at all. */
+ vg_assert(di->fsm.have_rw_map);
+ vg_assert(di->fsm.have_ro_map);
+ vg_assert(!di->fsm.have_rx_map);
+
+ di->fsm.have_rx_map = True;
+ di->fsm.rx_map_avma = di->fsm.ro_map_avma;
+ di->fsm.rx_map_size = di->fsm.ro_map_size;
+ di->fsm.rx_map_foff = di->fsm.ro_map_foff;
+
+ di->fsm.have_ro_map = False;
+ di->fsm.ro_map_avma = 0;
+ di->fsm.ro_map_size = 0;
+ di->fsm.ro_map_foff = 0;
+
+ /* And since we're now in an accept state, read debuginfo. Finally. */
+ ULong di_handle __attribute__((unused))
+ = di_notify_ACHIEVE_ACCEPT_STATE( di );
+ /* di_handle is ignored. That's not a problem per se -- it just
+ means nobody will ever be able to refer to this debuginfo by
+ handle since nobody will know what the handle value is. */
+}
+
+
/*--------- PDB (windows debug info) reading --------- */
/* this should really return ULong, as per VG_(di_notify_mmap). */
reaches an accept state, signals that we should now read debug info
from the object into the associated struct _DebugInfo. The accept
state is arrived at when have_rx_map and have_rw_map both become
- true.
+ true. The initial state is one in which we have no observations,
+ so have_rx_map and have_rw_map are both false.
This is all rather ad-hoc; for example it has no way to record more
than one rw or rx mapping for a given object, not because such
read debug info. It may be that in future we need to track more
state in order to make the decision, so this struct would then get
expanded.
+
+ The normal sequence of events is one of
+
+ start --> r-x mapping --> rw- mapping --> accept
+ start --> rw- mapping --> r-x mapping --> accept
+
+ that is, take the first r-x and rw- mapping we see, and we're done.
+
+ On MacOSX 10.7, 32-bit, there appears to be a new variant:
+
+ start --> r-- mapping --> rw- mapping
+ --> upgrade r-- mapping to r-x mapping --> accept
+
+ where the upgrade is done by a call to vm_protect. Hence we
+ need to also track this possibility.
*/
struct _DebugInfoFSM
{
+ /* --- all targets --- */
UChar* filename; /* in mallocville (VG_AR_DINFO) */
Bool have_rx_map; /* did we see a r?x mapping yet for the file? */
Addr rw_map_avma; /* ditto, for the rw? mapping we believe is the */
SizeT rw_map_size; /* .data segment mapping */
OffT rw_map_foff;
+
+ /* --- OSX 10.7, 32-bit only --- */
+ Bool have_ro_map; /* did we see a r-- mapping yet for the file? */
+
+ Addr ro_map_avma; /* file offset, length, avma for said mapping */
+ SizeT ro_map_size;
+ OffT ro_map_foff;
};
ALLOC_or_NULL(VG_Z_LIBC_SONAME, malloc, malloc);
#elif defined(VGO_darwin)
- ALLOC_or_NULL(VG_Z_LIBSTDCXX_SONAME, malloc, malloc);
ALLOC_or_NULL(VG_Z_LIBC_SONAME, malloc, malloc);
ZONEALLOC_or_NULL(VG_Z_LIBC_SONAME, malloc_zone_malloc, malloc);
#elif defined(VGO_darwin)
// operator new(unsigned int), GNU mangling
#if VG_WORDSIZE == 4
- ALLOC_or_BOMB(VG_Z_LIBSTDCXX_SONAME, _Znwj, __builtin_new);
- ALLOC_or_BOMB(VG_Z_LIBC_SONAME, _Znwj, __builtin_new);
+ //ALLOC_or_BOMB(VG_Z_LIBSTDCXX_SONAME, _Znwj, __builtin_new);
+ //ALLOC_or_BOMB(VG_Z_LIBC_SONAME, _Znwj, __builtin_new);
#endif
// operator new(unsigned long), GNU mangling
#if 1 // FIXME: is this right?
- ALLOC_or_BOMB(VG_Z_LIBSTDCXX_SONAME, _Znwm, __builtin_new);
- ALLOC_or_BOMB(VG_Z_LIBC_SONAME, _Znwm, __builtin_new);
+ //ALLOC_or_BOMB(VG_Z_LIBSTDCXX_SONAME, _Znwm, __builtin_new);
+ //ALLOC_or_BOMB(VG_Z_LIBC_SONAME, _Znwm, __builtin_new);
#endif
#endif
#elif defined(VGO_darwin)
// operator new(unsigned, std::nothrow_t const&), GNU mangling
#if VG_WORDSIZE == 4
- ALLOC_or_NULL(VG_Z_LIBSTDCXX_SONAME, _ZnwjRKSt9nothrow_t, __builtin_new);
- ALLOC_or_NULL(VG_Z_LIBC_SONAME, _ZnwjRKSt9nothrow_t, __builtin_new);
+ //ALLOC_or_NULL(VG_Z_LIBSTDCXX_SONAME, _ZnwjRKSt9nothrow_t, __builtin_new);
+ //ALLOC_or_NULL(VG_Z_LIBC_SONAME, _ZnwjRKSt9nothrow_t, __builtin_new);
#endif
// operator new(unsigned long, std::nothrow_t const&), GNU mangling
#if 1 // FIXME: is this right?
- ALLOC_or_NULL(VG_Z_LIBSTDCXX_SONAME, _ZnwmRKSt9nothrow_t, __builtin_new);
- ALLOC_or_NULL(VG_Z_LIBC_SONAME, _ZnwmRKSt9nothrow_t, __builtin_new);
+ //ALLOC_or_NULL(VG_Z_LIBSTDCXX_SONAME, _ZnwmRKSt9nothrow_t, __builtin_new);
+ //ALLOC_or_NULL(VG_Z_LIBC_SONAME, _ZnwmRKSt9nothrow_t, __builtin_new);
#endif
#endif
#elif defined(VGO_darwin)
// operator new[](unsigned int), GNU mangling
#if VG_WORDSIZE == 4
- ALLOC_or_BOMB(VG_Z_LIBSTDCXX_SONAME, _Znaj, __builtin_vec_new );
- ALLOC_or_BOMB(VG_Z_LIBC_SONAME, _Znaj, __builtin_vec_new );
+ //ALLOC_or_BOMB(VG_Z_LIBSTDCXX_SONAME, _Znaj, __builtin_vec_new );
+ //ALLOC_or_BOMB(VG_Z_LIBC_SONAME, _Znaj, __builtin_vec_new );
#endif
// operator new[](unsigned long), GNU mangling
#if 1 // FIXME: is this right?
- ALLOC_or_BOMB(VG_Z_LIBSTDCXX_SONAME, _Znam, __builtin_vec_new );
- ALLOC_or_BOMB(VG_Z_LIBC_SONAME, _Znam, __builtin_vec_new );
+ //ALLOC_or_BOMB(VG_Z_LIBSTDCXX_SONAME, _Znam, __builtin_vec_new );
+ //ALLOC_or_BOMB(VG_Z_LIBC_SONAME, _Znam, __builtin_vec_new );
#endif
#endif
#elif defined(VGO_darwin)
// operator new[](unsigned, std::nothrow_t const&), GNU mangling
#if VG_WORDSIZE == 4
- ALLOC_or_NULL(VG_Z_LIBSTDCXX_SONAME, _ZnajRKSt9nothrow_t, __builtin_vec_new );
- ALLOC_or_NULL(VG_Z_LIBC_SONAME, _ZnajRKSt9nothrow_t, __builtin_vec_new );
+ //ALLOC_or_NULL(VG_Z_LIBSTDCXX_SONAME, _ZnajRKSt9nothrow_t, __builtin_vec_new );
+ //ALLOC_or_NULL(VG_Z_LIBC_SONAME, _ZnajRKSt9nothrow_t, __builtin_vec_new );
#endif
// operator new[](unsigned long, std::nothrow_t const&), GNU mangling
#if 1 // FIXME: is this right?
- ALLOC_or_NULL(VG_Z_LIBSTDCXX_SONAME, _ZnamRKSt9nothrow_t, __builtin_vec_new );
- ALLOC_or_NULL(VG_Z_LIBC_SONAME, _ZnamRKSt9nothrow_t, __builtin_vec_new );
+ //ALLOC_or_NULL(VG_Z_LIBSTDCXX_SONAME, _ZnamRKSt9nothrow_t, __builtin_vec_new );
+ //ALLOC_or_NULL(VG_Z_LIBC_SONAME, _ZnamRKSt9nothrow_t, __builtin_vec_new );
#endif
#endif
void VG_REPLACE_FUNCTION_EZU(10040,soname,fnname) (void *zone, void *p) \
{ \
if (!init_done) init(); \
- MALLOC_TRACE(#vg_replacement "(%p, %p)\n", zone, p ); \
+ MALLOC_TRACE(#fnname "(%p, %p)\n", zone, p ); \
if (p == NULL) \
return; \
(void)VALGRIND_NON_SIMD_CALL1( info.tl_##vg_replacement, p ); \
void VG_REPLACE_FUNCTION_EZU(10050,soname,fnname) (void *p) \
{ \
if (!init_done) init(); \
- MALLOC_TRACE(#vg_replacement "(%p)\n", p ); \
+ MALLOC_TRACE(#fnname "(%p)\n", p ); \
if (p == NULL) \
return; \
(void)VALGRIND_NON_SIMD_CALL1( info.tl_##vg_replacement, p ); \
}
-// free
#if defined(VGO_linux)
FREE(VG_Z_LIBSTDCXX_SONAME, free, free );
FREE(VG_Z_LIBC_SONAME, free, free );
#elif defined(VGO_darwin)
- FREE(VG_Z_LIBSTDCXX_SONAME, free, free );
FREE(VG_Z_LIBC_SONAME, free, free );
ZONEFREE(VG_Z_LIBC_SONAME, malloc_zone_free, free );
FREE(VG_Z_LIBC_SONAME, cfree, free );
#elif defined(VGO_darwin)
- FREE(VG_Z_LIBSTDCXX_SONAME, cfree, free );
- FREE(VG_Z_LIBC_SONAME, cfree, free );
+ //FREE(VG_Z_LIBSTDCXX_SONAME, cfree, free );
+ //FREE(VG_Z_LIBC_SONAME, cfree, free );
#endif
#elif defined(VGO_darwin)
// operator delete(void*), GNU mangling
- FREE(VG_Z_LIBSTDCXX_SONAME, _ZdlPv, __builtin_delete );
- FREE(VG_Z_LIBC_SONAME, _ZdlPv, __builtin_delete );
+ //FREE(VG_Z_LIBSTDCXX_SONAME, _ZdlPv, __builtin_delete );
+ //FREE(VG_Z_LIBC_SONAME, _ZdlPv, __builtin_delete );
#endif
#elif defined(VGO_darwin)
// operator delete(void*, std::nothrow_t const&), GNU mangling
- FREE(VG_Z_LIBSTDCXX_SONAME, _ZdlPvRKSt9nothrow_t, __builtin_delete );
- FREE(VG_Z_LIBC_SONAME, _ZdlPvRKSt9nothrow_t, __builtin_delete );
+ //FREE(VG_Z_LIBSTDCXX_SONAME, _ZdlPvRKSt9nothrow_t, __builtin_delete );
+ //FREE(VG_Z_LIBC_SONAME, _ZdlPvRKSt9nothrow_t, __builtin_delete );
#endif
#elif defined(VGO_darwin)
// operator delete[](void*), not mangled (for gcc 2.96)
- FREE(VG_Z_LIBSTDCXX_SONAME, __builtin_vec_delete, __builtin_vec_delete );
- FREE(VG_Z_LIBC_SONAME, __builtin_vec_delete, __builtin_vec_delete );
+ //FREE(VG_Z_LIBSTDCXX_SONAME, __builtin_vec_delete, __builtin_vec_delete );
+ //FREE(VG_Z_LIBC_SONAME, __builtin_vec_delete, __builtin_vec_delete );
// operator delete[](void*), GNU mangling
- FREE(VG_Z_LIBSTDCXX_SONAME, _ZdaPv, __builtin_vec_delete );
- FREE(VG_Z_LIBC_SONAME, _ZdaPv, __builtin_vec_delete );
+ //FREE(VG_Z_LIBSTDCXX_SONAME, _ZdaPv, __builtin_vec_delete );
+ //FREE(VG_Z_LIBC_SONAME, _ZdaPv, __builtin_vec_delete );
#endif
#elif defined(VGO_darwin)
// operator delete[](void*, std::nothrow_t const&), GNU mangling
- FREE(VG_Z_LIBSTDCXX_SONAME, _ZdaPvRKSt9nothrow_t, __builtin_vec_delete );
- FREE(VG_Z_LIBC_SONAME, _ZdaPvRKSt9nothrow_t, __builtin_vec_delete );
+ //FREE(VG_Z_LIBSTDCXX_SONAME, _ZdaPvRKSt9nothrow_t, __builtin_vec_delete );
+ //FREE(VG_Z_LIBC_SONAME, _ZdaPvRKSt9nothrow_t, __builtin_vec_delete );
#endif
void* v; \
\
if (!init_done) init(); \
- MALLOC_TRACE("calloc(%p, %llu,%llu)", zone, (ULong)nmemb, (ULong)size ); \
+ MALLOC_TRACE("zone_calloc(%p, %llu,%llu)", zone, (ULong)nmemb, (ULong)size ); \
\
v = (void*)VALGRIND_NON_SIMD_CALL2( info.tl_calloc, nmemb, size ); \
MALLOC_TRACE(" = %p\n", v ); \
void* v; \
\
if (!init_done) init(); \
- MALLOC_TRACE("realloc(%p,%p,%llu)", zone, ptrV, (ULong)new_size ); \
+ MALLOC_TRACE("zone_realloc(%p,%p,%llu)", zone, ptrV, (ULong)new_size ); \
\
if (ptrV == NULL) \
/* We need to call a malloc-like function; so let's use \
void* v; \
\
if (!init_done) init(); \
- MALLOC_TRACE("memalign(%p, al %llu, size %llu)", \
+ MALLOC_TRACE("zone_memalign(%p, al %llu, size %llu)", \
zone, (ULong)alignment, (ULong)n ); \
\
/* Round up to minimum alignment if necessary. */ \
MALLOPT(VG_Z_LIBC_SONAME, mallopt);
#elif defined(VGO_darwin)
- MALLOPT(VG_Z_LIBC_SONAME, mallopt);
+ //MALLOPT(VG_Z_LIBC_SONAME, mallopt);
#endif
MALLOC_TRIM(VG_Z_LIBC_SONAME, malloc_trim);
#elif defined(VGO_darwin)
- MALLOC_TRIM(VG_Z_LIBC_SONAME, malloc_trim);
+ //MALLOC_TRIM(VG_Z_LIBC_SONAME, malloc_trim);
#endif
POSIX_MEMALIGN(VG_Z_LIBC_SONAME, posix_memalign);
#elif defined(VGO_darwin)
- POSIX_MEMALIGN(VG_Z_LIBC_SONAME, posix_memalign);
+ //POSIX_MEMALIGN(VG_Z_LIBC_SONAME, posix_memalign);
#endif
MALLOC_USABLE_SIZE(VG_Z_LIBC_SONAME, malloc_size);
#elif defined(VGO_darwin)
- MALLOC_USABLE_SIZE(VG_Z_LIBC_SONAME, malloc_usable_size);
+ //MALLOC_USABLE_SIZE(VG_Z_LIBC_SONAME, malloc_usable_size);
MALLOC_USABLE_SIZE(VG_Z_LIBC_SONAME, malloc_size);
#endif
MALLOC_STATS(VG_Z_LIBC_SONAME, malloc_stats);
#elif defined(VGO_darwin)
- MALLOC_STATS(VG_Z_LIBC_SONAME, malloc_stats);
+ //MALLOC_STATS(VG_Z_LIBC_SONAME, malloc_stats);
#endif
MALLINFO(VG_Z_LIBC_SONAME, mallinfo);
#elif defined(VGO_darwin)
- MALLINFO(VG_Z_LIBC_SONAME, mallinfo);
+ //MALLINFO(VG_Z_LIBC_SONAME, mallinfo);
#endif
+/*------------------ Darwin zone stuff ------------------*/
+
#if defined(VGO_darwin)
static vki_malloc_zone_t vg_default_zone = {
- NULL, // reserved
- NULL, // reserved
- NULL, // GrP fixme malloc_size
+ NULL, // reserved1
+ NULL, // reserved2
+ NULL, // GrP fixme: malloc_size
(void*)VG_REPLACE_FUNCTION_EZU(10020,VG_Z_LIBC_SONAME,malloc_zone_malloc),
(void*)VG_REPLACE_FUNCTION_EZU(10060,VG_Z_LIBC_SONAME,malloc_zone_calloc),
(void*)VG_REPLACE_FUNCTION_EZU(10130,VG_Z_LIBC_SONAME,malloc_zone_valloc),
(void*)VG_REPLACE_FUNCTION_EZU(10040,VG_Z_LIBC_SONAME,malloc_zone_free),
(void*)VG_REPLACE_FUNCTION_EZU(10080,VG_Z_LIBC_SONAME,malloc_zone_realloc),
- NULL, // GrP fixme destroy
+ NULL, // GrP fixme: destroy
"ValgrindMallocZone",
NULL, // batch_malloc
NULL, // batch_free
- NULL, // GrP fixme introspect
+ NULL, // GrP fixme: introspect
2, // version (GrP fixme 3?)
- // DDD: this field exists in Mac OS 10.6, but not 10.5.
- #if 0
- (void*)VG_REPLACE_FUNCTION_ZU(VG_Z_LIBC_SONAME, malloc_zone_memalign)
- #endif
+ NULL, /* memalign */ // DDD: this field exists in Mac OS 10.6, but not 10.5.
+ NULL, /* free_definite_size */
+ NULL, /* pressure_relief */
};
+
#define DEFAULT_ZONE(soname, fnname) \
\
void *VG_REPLACE_FUNCTION_EZU(10210,soname,fnname) ( void ); \
return &vg_default_zone; \
}
-DEFAULT_ZONE(VG_Z_LIBC_SONAME, malloc_zone_from_ptr);
DEFAULT_ZONE(VG_Z_LIBC_SONAME, malloc_default_zone);
+
+#define ZONE_FROM_PTR(soname, fnname) \
+ \
+ void *VG_REPLACE_FUNCTION_EZU(10220,soname,fnname) ( void* ptr ); \
+ void *VG_REPLACE_FUNCTION_EZU(10220,soname,fnname) ( void* ptr ) \
+ { \
+ return &vg_default_zone; \
+ }
+
+ZONE_FROM_PTR(VG_Z_LIBC_SONAME, malloc_zone_from_ptr);
+
+
// GrP fixme bypass libc's use of zone->introspect->check
#define ZONE_CHECK(soname, fnname) \
\
- int VG_REPLACE_FUNCTION_EZU(10220,soname,fnname)(void* zone); \
- int VG_REPLACE_FUNCTION_EZU(10220,soname,fnname)(void* zone) \
+ int VG_REPLACE_FUNCTION_EZU(10230,soname,fnname)(void* zone); \
+ int VG_REPLACE_FUNCTION_EZU(10230,soname,fnname)(void* zone) \
{ \
return 1; \
}
-ZONE_CHECK(VG_Z_LIBC_SONAME, malloc_zone_check);
+//ZONE_CHECK(VG_Z_LIBC_SONAME, malloc_zone_check);
#endif /* defined(VGO_darwin) */
+/*------------------ (startup related) ------------------*/
+
/* All the code in here is unused until this function is called */
__attribute__((constructor))
// old new_system_shared_regions
// old shared_region_map_file_np
// old shared_region_make_private_np
-// NYI __pthread_mutex_destroy 301
-// NYI __pthread_mutex_init 302
-// NYI __pthread_mutex_lock 303
-// NYI __pthread_mutex_trylock 304
-// NYI __pthread_mutex_unlock 305
-// NYI __pthread_cond_init 306
-// NYI __pthread_cond_destroy 307
-// NYI __pthread_cond_broadcast 308
+DECL_TEMPLATE(darwin, psynch_mutexwait); // 301 // new in 10.7 ?
+DECL_TEMPLATE(darwin, psynch_mutexdrop); // 302 // new in 10.7 ?
+DECL_TEMPLATE(darwin, psynch_cvbroad); // 303 // new in 10.7 ?
+DECL_TEMPLATE(darwin, psynch_cvsignal); // 304 // new in 10.7 ?
+DECL_TEMPLATE(darwin, psynch_cvwait); // 305 // new in 10.7 ?
+DECL_TEMPLATE(darwin, psynch_rw_rdlock); // 306 // new in 10.7 ?
+DECL_TEMPLATE(darwin, psynch_rw_wrlock); // 307 // new in 10.7 ?
+DECL_TEMPLATE(darwin, psynch_rw_unlock); // 308 // new in 10.7 ?
// NYI __pthread_cond_signal 309
// NYI getsid 310
// NYI settid_with_pid 311
-// NYI __pthread_cond_timedwait 312
+DECL_TEMPLATE(darwin, psynch_cvclrprepost); // 312 // new in 10.7 ?
// NYI aio_fsync 313
DECL_TEMPLATE(darwin, aio_return); // 314
DECL_TEMPLATE(darwin, aio_suspend); // 315
// NYI setauid 354
// NYI getaudit 355
// NYI setaudit 356
-// NYI getaudit_addr 357
+#if DARWIN_VERS >= DARWIN_10_7
+DECL_TEMPLATE(darwin, getaudit_addr) // 357
+#endif
// NYI setaudit_addr 358
// NYI auditctl 359
DECL_TEMPLATE(darwin, bsdthread_create); // 360
// NYI audit_session_join 429
// Mach message helpers
+DECL_TEMPLATE(darwin, mach_port_set_context);
DECL_TEMPLATE(darwin, host_info);
DECL_TEMPLATE(darwin, host_page_size);
DECL_TEMPLATE(darwin, host_get_io_master);
DECL_TEMPLATE(darwin, mach_port_set_attributes);
DECL_TEMPLATE(darwin, mach_port_insert_member);
DECL_TEMPLATE(darwin, task_get_special_port);
+DECL_TEMPLATE(darwin, task_get_exception_ports);
DECL_TEMPLATE(darwin, semaphore_create);
DECL_TEMPLATE(darwin, semaphore_destroy);
DECL_TEMPLATE(darwin, mach_ports_lookup);
#if defined(VGP_amd64_darwin)
+#include "config.h" // DARWIN_VERS
#include "pub_core_basics.h"
#include "pub_core_vki.h"
#include "pub_core_libcsetjmp.h" // to keep _threadstate.h happy
// other values stay where they are in registers
" push $0\n" // fake return address
" jmp _pthread_hijack\n"
- );
+);
// other values stay where they are in registers
" push $0\n" // fake return address
" jmp _wqthread_hijack\n"
- );
+);
/* wqthread note: The kernel may create or destroy pthreads in the
lock. */
VG_(acquire_BigLock_LL)("wqthread_hijack");
+ if (0) VG_(printf)("wqthread_hijack: self %#lx, kport %#lx, "
+ "stackaddr %#lx, workitem %#lx, reuse %d, sp %#lx\n",
+ self, kport, stackaddr, workitem, reuse, sp);
+
/* Start the thread with all signals blocked. VG_(scheduler) will
set the mask correctly when we finally get there. */
VG_(sigfillset)(&blockall);
VG_(sigprocmask)(VKI_SIG_SETMASK, &blockall, NULL);
if (reuse) {
+
+ /* For whatever reason, tst->os_state.pthread appear to have a
+ constant offset of 96 on 10.7, but zero on 10.6 and 10.5. No
+ idea why. */
+# if DARWIN_VERS <= DARWIN_10_6
+ UWord magic_delta = 0;
+# elif DARWIN_VERS == DARWIN_10_7
+ UWord magic_delta = 0x60;
+# endif
+
// This thread already exists; we're merely re-entering
// after leaving via workq_ops(WQOPS_THREAD_RETURN).
// Don't allocate any V thread resources.
vg_assert(mach_thread_self() == kport);
tst = VG_(get_ThreadState)(tid);
+
+ if (0) VG_(printf)("wqthread_hijack reuse %s: tid %d, tst %p, "
+ "tst->os_state.pthread %#lx\n",
+ tst->os_state.pthread == self ? "SAME" : "DIFF",
+ tid, tst, tst->os_state.pthread);
+
vex = &tst->arch.vex;
- vg_assert(tst->os_state.pthread == self);
+ vg_assert(tst->os_state.pthread - magic_delta == self);
}
else {
// This is a new thread.
mach_msg: messages to a task
------------------------------------------------------------------ */
+// JRS 2011-Aug-25: just guessing here. I have no clear idea how
+// these structs are derived. They obviously relate to the various
+// .def files in the xnu sources, and can also be found in some
+// form in /usr/include/mach/*.h, but not sure how these all
+// relate to each other.
+
+PRE(mach_port_set_context)
+{
+#pragma pack(4)
+ typedef struct {
+ mach_msg_header_t Head;
+ NDR_record_t NDR;
+ mach_port_name_t name;
+ mach_vm_address_t context;
+ } Request;
+#pragma pack()
+
+ Request *req = (Request *)ARG1;
+
+ PRINT("mach_port_set_context(%s, %s, 0x%llx)",
+ name_for_port(MACH_REMOTE),
+ name_for_port(req->name), req->context);
+
+ AFTER = POST_FN(mach_port_set_context);
+}
+
+POST(mach_port_set_context)
+{
+#pragma pack(4)
+ typedef struct {
+ mach_msg_header_t Head;
+ NDR_record_t NDR;
+ kern_return_t RetCode;
+ } Reply;
+#pragma pack()
+}
+
+
+// JRS 2011-Aug-25 FIXME completely bogus
+PRE(task_get_exception_ports)
+{
+#pragma pack(4)
+ typedef struct {
+ mach_msg_header_t Head;
+ NDR_record_t NDR;
+ exception_mask_t exception_mask;
+ } Request;
+#pragma pack()
+
+ PRINT("task_get_exception_ports(BOGUS)");
+ AFTER = POST_FN(task_get_exception_ports);
+}
+
+POST(task_get_exception_ports)
+{
+#pragma pack(4)
+ typedef struct {
+ mach_msg_header_t Head;
+ /* start of the kernel processed data */
+ mach_msg_body_t msgh_body;
+ mach_msg_port_descriptor_t old_handlers[32];
+ /* end of the kernel processed data */
+ NDR_record_t NDR;
+ mach_msg_type_number_t masksCnt;
+ exception_mask_t masks[32];
+ exception_behavior_t old_behaviors[32];
+ thread_state_flavor_t old_flavors[32];
+ } Reply;
+#pragma pack()
+}
+
+
+///////////////////////////////////////////////////
PRE(mach_port_type)
{
//VG_(mprotect_max_range)(start, end-start, prot);
} else {
ML_(notify_core_and_tool_of_mprotect)(start, end-start, prot);
+ VG_(di_notify_vm_protect)(start, end-start, prot);
}
}
} else {
}
}
+// JRS 2011-Aug-25: these magic numbers (3201 etc) come from
+// /usr/include/mach/mach_port.h et al (grep in /usr/include
+// for them)
PRE(mach_msg_task)
{
// message to a task port
case 3227:
CALL_PRE(mach_port_extract_member);
return;
-
+
+ case 3229:
+ CALL_PRE(mach_port_set_context);
+ return;
+
case 3402:
CALL_PRE(task_threads);
return;
case 3412:
CALL_PRE(thread_create_running);
return;
+
+ case 3414:
+ CALL_PRE(task_get_exception_ports);
+ return;
case 3418:
CALL_PRE(semaphore_create);
}
+/* ---------------------------------------------------------------------
+ Added for OSX 10.7 (Lion)
+ ------------------------------------------------------------------ */
+
+PRE(getaudit_addr)
+{
+ PRINT("getaudit_addr(%#lx, %lu)", ARG1, ARG2);
+ PRE_REG_READ1(void*, "auditinfo_addr", int, "length");
+ PRE_MEM_WRITE("getaudit_addr(auditinfo_addr)", ARG1, ARG2);
+}
+POST(getaudit_addr)
+{
+ POST_MEM_WRITE(ARG1, ARG2);
+}
+
+PRE(psynch_mutexwait)
+{
+ PRINT("psynch_mutexwait(BOGUS)\n");
+ *flags |= SfMayBlock;
+}
+POST(psynch_mutexwait)
+{
+}
+
+PRE(psynch_mutexdrop)
+{
+ PRINT("psynch_mutexdrop(BOGUS)\n");
+ *flags |= SfMayBlock;
+}
+POST(psynch_mutexdrop)
+{
+}
+
+PRE(psynch_cvbroad)
+{
+ PRINT("psynch_cvbroad(BOGUS)\n");
+ *flags |= SfMayBlock;
+}
+POST(psynch_cvbroad)
+{
+}
+
+PRE(psynch_cvsignal)
+{
+ PRINT("psynch_cvsignal(BOGUS)\n");
+ *flags |= SfMayBlock;
+}
+POST(psynch_cvsignal)
+{
+}
+
+PRE(psynch_cvwait)
+{
+ PRINT("psynch_cvwait(BOGUS)\n");
+ *flags |= SfMayBlock;
+}
+POST(psynch_cvwait)
+{
+}
+
+PRE(psynch_rw_rdlock)
+{
+ PRINT("psynch_rw_rdlock(BOGUS)\n");
+ *flags |= SfMayBlock;
+}
+POST(psynch_rw_rdlock)
+{
+}
+
+PRE(psynch_rw_wrlock)
+{
+ PRINT("psynch_rw_wrlock(BOGUS)\n");
+ *flags |= SfMayBlock;
+}
+POST(psynch_rw_wrlock)
+{
+}
+
+PRE(psynch_rw_unlock)
+{
+ PRINT("psynch_rw_unlock(BOGUS)\n");
+ *flags |= SfMayBlock;
+}
+POST(psynch_rw_unlock)
+{
+}
+
+PRE(psynch_cvclrprepost)
+{
+ PRINT("psynch_cvclrprepost(BOGUS)\n");
+ *flags |= SfMayBlock;
+}
+POST(psynch_cvclrprepost)
+{
+}
+
+
/* ---------------------------------------------------------------------
syscall tables
------------------------------------------------------------------ */
_____(VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(298)), // old new_system_shared_regions
_____(VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(299)), // old shared_region_map_file_np
_____(VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(300)), // old shared_region_make_private_np
- _____(VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(301)), // ???
- _____(VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(302)), // ???
- _____(VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(303)), // ???
- _____(VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(304)), // ???
- _____(VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(305)), // ???
- _____(VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(306)), // ???
- _____(VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(307)), // ???
- _____(VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(308)), // ???
+ MACXY(__NR_psynch_mutexwait, psynch_mutexwait), // 301
+ MACXY(__NR_psynch_mutexdrop, psynch_mutexdrop), // 302
+ MACXY(__NR_psynch_cvbroad, psynch_cvbroad), // 303
+ MACXY(__NR_psynch_cvsignal, psynch_cvsignal), // 304
+ MACXY(__NR_psynch_cvwait, psynch_cvwait), // 305
+ MACXY(__NR_psynch_rw_rdlock, psynch_rw_rdlock), // 306
+ MACXY(__NR_psynch_rw_wrlock, psynch_rw_wrlock), // 307
+ MACXY(__NR_psynch_rw_unlock, psynch_rw_unlock), // 308
_____(VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(309)), // ???
// _____(__NR_getsid),
// _____(__NR_settid_with_pid),
- _____(VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(312)), // ???
+ MACXY(__NR_psynch_cvclrprepost, psynch_cvclrprepost), // 312
// _____(__NR_aio_fsync),
MACXY(__NR_aio_return, aio_return),
MACX_(__NR_aio_suspend, aio_suspend),
// _____(__NR_setauid),
// _____(__NR_getaudit),
// _____(__NR_setaudit),
-// _____(__NR_getaudit_addr),
+#if DARWIN_VERS >= DARWIN_10_7
+ MACXY(__NR_getaudit_addr, getaudit_addr),
+#endif
// _____(__NR_setaudit_addr),
// _____(__NR_auditctl),
MACXY(__NR_bsdthread_create, bsdthread_create), // 360
extern void VG_(di_notify_pdb_debuginfo)( Int fd, Addr avma,
SizeT total_size,
PtrdiffT unknown_purpose__reloc );
+
+/* this should also really return ULong */
+extern void VG_(di_notify_vm_protect)( Addr a, SizeT len, UInt prot );
#endif
extern void VG_(di_discard_ALL_debuginfo)( void );
--- /dev/null
+
+# Suppressions for Darwin 11.x / Mac OS X 10.7 Lion
+
+##----------------------------------------------------------------------##
+# Memcheck
+##----------------------------------------------------------------------##
+
+# Dunno where this is a real bug, or due to borked 10.7-specific syscall
+# wrappers. 64-bit mode; not sure if occurs in 32-bit mode.
+# Anyway, for the tine being:
+#
+# Conditional jump or move depends on uninitialised value(s)
+# at 0x1973E6: __mtx_droplock (in /usr/lib/system/libsystem_c.dylib)
+# by 0x1976AA: pthread_mutex_unlock (in /usr/lib/system/libsystem_c.dylib)
+# by 0x100B3D: unlock_node (in /usr/lib/system/libkeymgr.dylib)
+{
+ OSX107:__mtx_droplock
+ Memcheck:Cond
+ fun:__mtx_droplock
+ fun:pthread_mutex_unlock
+ fun:unlock_node
+}
+
+# Conditional jump or move depends on uninitialised value(s)
+# at 0x2EB883: ??? (in /usr/lib/system/libxpc.dylib)
+# by 0x237C6: ??? (in /usr/lib/libSystem.B.dylib)
+# by 0x8FE1115A: ImageLoaderMachO::doModInitFunctions(ImageLoader::LinkContext const&) (in /usr/lib/dyld)
+{
+ <insert_a_suppression_name_here>
+ Memcheck:Cond
+ obj:/usr/lib/system/libxpc.dylib
+ obj:/usr/lib/libSystem.B.dylib
+ fun:_ZN16ImageLoaderMachO18doModInitFunctionsERKN11ImageLoader11LinkContextE
+}
+
+# ZLib stuff. How come this wasn't necessary in 10.6 ?
+{
+ OSX107:zlib-C
+ Memcheck:Cond
+ obj:/usr/lib/libz.*dylib
+ obj:/usr/lib/libz.*dylib
+}
+{
+ OSX107:zlib-8
+ Memcheck:Value8
+ obj:/usr/lib/libz.*dylib
+ obj:/usr/lib/libz.*dylib
+}
+
+# Really a bug? I don't know.
+# Conditional jump or move depends on uninitialised value(s)
+# at 0x3A322FE: __mtx_droplock (in /usr/lib/system/libsystem_c.dylib)
+# by 0x3A326AA: pthread_mutex_unlock (in /usr/lib/system/libsystem_c.dylib)
+# by 0x26382: load_images (in /usr/lib/libobjc.A.dylib)
+{
+ OSX107:blah
+ Memcheck:Cond
+ fun:__mtx_droplock
+ fun:pthread_mutex_unlock
+}
+
+{
+ OSX107:blah
+ Memcheck:Cond
+ fun:pthread_mutex_lock
+}
+
+
+
+##########################################################################
+### The ones below are from darwin10.supp (for Snow Leopard). I don't
+### know whether they are still necessary.
+
+# afaict this is legit. Might be caused by setenv("VAR=")
+# where the value string is empty (not sure)
+{
+ macos-Cond-7
+ Memcheck:Cond
+ fun:__setenv
+}
+
+# From Jesse Ruderman.
+#{
+# Mac OS X 10.6.4. rdar://8145289. "new[]" paired with "delete" in the DesktopServicesPriv framework.
+# Memcheck:Free
+# fun:_ZdlPv
+# fun:_ZN5TChar18RemovePtrReferenceEv
+# }
+
+# From Jesse Ruderman.
+#{
+# Mac OS X 10.6.4. rdar://8145318. Uninitialized memory from HIMenuBarView::MeasureAppMenus is used in HIMenuBarView::SetAdjustTextTitleBoundsAtIndex.
+# Memcheck:Cond
+# fun:_ZN13HIMenuBarView31SetAdjustTextTitleBoundsAtIndexEih
+# fun:_ZN13HIMenuBarView15MeasureAppMenusEv
+#}
+
+#{
+# TFontFeatures::TFontFeatures(CGFont*) (in CoreText.framework)
+# Memcheck:Cond
+# fun:_ZN13TFontFeaturesC2EP6CGFont
+# fun:_ZNK9TBaseFont12CopyFeaturesEv
+#}
+
+# See https://bugs.kde.org/show_bug.cgi?id=188572 about this; it's
+# unavoidable due to BSD setenv() semantics.
+#{
+# macos-__setenv-leak-see-our-bug-188572
+# Memcheck:Leak
+# fun:malloc_zone_malloc
+# fun:__setenv
+#}
+
+#{
+# libSystem-keymgr-leak-at-exit
+# Memcheck:Leak
+# fun:malloc
+# fun:get_or_create_key_element
+# fun:_keymgr_get_and_lock_processwide_ptr_2
+# fun:__keymgr_initializer
+# fun:libSystem_initializer
+#}
#ifndef __PUB_TOOL_REDIR_H
#define __PUB_TOOL_REDIR_H
+#include "config.h" /* DARWIN_VERS */
+
/* The following macros facilitate function replacement and wrapping.
Function wrapping and function replacement are similar but not
#if defined(VGO_linux)
# define VG_Z_LIBC_SONAME libcZdsoZa // libc.so*
-#elif defined(VGO_darwin)
+
+#elif defined(VGO_darwin) && (DARWIN_VERS <= DARWIN_10_6)
# define VG_Z_LIBC_SONAME libSystemZdZaZddylib // libSystem.*.dylib
+
+#elif defined(VGO_darwin) && (DARWIN_VERS == DARWIN_10_7)
+# define VG_Z_LIBC_SONAME libsystemZucZaZddylib // libsystem_c*.dylib
+
#else
# error "Unknown platform"
+
#endif
/* --- Soname of the GNU C++ library. --- */
/* 298 old new_system_shared_regions */
/* 299 old shared_region_map_file_np */
/* 300 old shared_region_make_private_np */
- /* 301 */
- /* 302 */
- /* 303 */
- /* 304 */
- /* 305 */
- /* 306 */
- /* 307 */
- /* 308 */
+#define __NR_psynch_mutexwait VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(301)
+#define __NR_psynch_mutexdrop VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(302)
+#define __NR_psynch_cvbroad VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(303)
+#define __NR_psynch_cvsignal VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(304)
+#define __NR_psynch_cvwait VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(305)
+#define __NR_psynch_rw_rdlock VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(306)
+#define __NR_psynch_rw_wrlock VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(307)
+#define __NR_psynch_rw_unlock VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(308)
/* 309 */
#define __NR_getsid VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(310)
#define __NR_settid_with_pid VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(311)
- /* 312 */
+#define __NR_psynch_cvclrprepost VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(312)
#define __NR_aio_fsync VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(313)
#define __NR_aio_return VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(314)
#define __NR_aio_suspend VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(315)
STRRCHR(VG_Z_LD_LINUX_SO_2, rindex)
#elif defined(VGO_darwin)
- STRRCHR(VG_Z_LIBC_SONAME, strrchr)
- STRRCHR(VG_Z_LIBC_SONAME, rindex)
- STRRCHR(VG_Z_DYLD, strrchr)
- STRRCHR(VG_Z_DYLD, rindex)
+ //STRRCHR(VG_Z_LIBC_SONAME, strrchr)
+ //STRRCHR(VG_Z_LIBC_SONAME, rindex)
+ //STRRCHR(VG_Z_DYLD, strrchr)
+ //STRRCHR(VG_Z_DYLD, rindex)
+ STRRCHR(VG_Z_LIBC_SONAME, strrchr)
#endif
# endif
#elif defined(VGO_darwin)
- STRCHR(VG_Z_LIBC_SONAME, strchr)
- STRCHR(VG_Z_LIBC_SONAME, index)
- STRCHR(VG_Z_DYLD, strchr)
- STRCHR(VG_Z_DYLD, index)
+ //STRCHR(VG_Z_LIBC_SONAME, strchr)
+ //STRCHR(VG_Z_LIBC_SONAME, index)
+ //STRCHR(VG_Z_DYLD, strchr)
+ //STRCHR(VG_Z_DYLD, index)
+ STRCHR(VG_Z_LIBC_SONAME, strchr)
#endif
STRCAT(VG_Z_LIBC_SONAME, __GI_strcat)
#elif defined(VGO_darwin)
- STRCAT(VG_Z_LIBC_SONAME, strcat)
+ //STRCAT(VG_Z_LIBC_SONAME, strcat)
#endif
STRNCAT(VG_Z_LIBC_SONAME, strncat)
#elif defined(VGO_darwin)
- STRNCAT(VG_Z_LIBC_SONAME, strncat)
- STRNCAT(VG_Z_DYLD, strncat)
+ //STRNCAT(VG_Z_LIBC_SONAME, strncat)
+ //STRNCAT(VG_Z_DYLD, strncat)
#endif
#if defined(VGO_linux)
#elif defined(VGO_darwin)
+ //STRLCAT(VG_Z_LIBC_SONAME, strlcat)
+ //STRLCAT(VG_Z_DYLD, strlcat)
STRLCAT(VG_Z_LIBC_SONAME, strlcat)
- STRLCAT(VG_Z_DYLD, strlcat)
#endif
STRNLEN(VG_Z_LIBC_SONAME, __GI_strnlen)
#elif defined(VGO_darwin)
- STRNLEN(VG_Z_LIBC_SONAME, strnlen)
+ //STRNLEN(VG_Z_LIBC_SONAME, strnlen)
#endif
STRLEN(VG_Z_LIBC_SONAME, __GI_strlen)
#elif defined(VGO_darwin)
- STRLEN(VG_Z_LIBC_SONAME, strlen)
+ //STRLEN(VG_Z_LIBC_SONAME, strlen)
+ STRLEN(VG_Z_LIBC_SONAME, strlen)
#endif
STRCPY(VG_Z_LIBC_SONAME, __GI_strcpy)
#elif defined(VGO_darwin)
+ //STRCPY(VG_Z_LIBC_SONAME, strcpy)
+ //STRCPY(VG_Z_DYLD, strcpy)
STRCPY(VG_Z_LIBC_SONAME, strcpy)
- STRCPY(VG_Z_DYLD, strcpy)
#endif
STRNCPY(VG_Z_LIBC_SONAME, __GI_strncpy)
#elif defined(VGO_darwin)
+ //STRNCPY(VG_Z_LIBC_SONAME, strncpy)
+ //STRNCPY(VG_Z_DYLD, strncpy)
STRNCPY(VG_Z_LIBC_SONAME, strncpy)
- STRNCPY(VG_Z_DYLD, strncpy)
#endif
#if defined(VGO_linux)
#elif defined(VGO_darwin)
+ //STRLCPY(VG_Z_LIBC_SONAME, strlcpy)
+ //STRLCPY(VG_Z_DYLD, strlcpy)
STRLCPY(VG_Z_LIBC_SONAME, strlcpy)
- STRLCPY(VG_Z_DYLD, strlcpy)
#endif
STRNCMP(VG_Z_LIBC_SONAME, __GI_strncmp)
#elif defined(VGO_darwin)
- STRNCMP(VG_Z_LIBC_SONAME, strncmp)
- STRNCMP(VG_Z_DYLD, strncmp)
+ //STRNCMP(VG_Z_LIBC_SONAME, strncmp)
+ //STRNCMP(VG_Z_DYLD, strncmp)
+ STRNCMP(VG_Z_LIBC_SONAME, strncmp)
#endif
# endif
#elif defined(VGO_darwin)
- STRCASECMP(VG_Z_LIBC_SONAME, strcasecmp)
+ //STRCASECMP(VG_Z_LIBC_SONAME, strcasecmp)
#endif
# endif
#elif defined(VGO_darwin)
- STRNCASECMP(VG_Z_LIBC_SONAME, strncasecmp)
- STRNCASECMP(VG_Z_DYLD, strncasecmp)
+ //STRNCASECMP(VG_Z_LIBC_SONAME, strncasecmp)
+ //STRNCASECMP(VG_Z_DYLD, strncasecmp)
#endif
STRCASECMP_L(VG_Z_LIBC_SONAME, __GI___strcasecmp_l)
#elif defined(VGO_darwin)
- STRCASECMP_L(VG_Z_LIBC_SONAME, strcasecmp_l)
+ //STRCASECMP_L(VG_Z_LIBC_SONAME, strcasecmp_l)
#endif
STRNCASECMP_L(VG_Z_LIBC_SONAME, __GI_strncasecmp_l)
#elif defined(VGO_darwin)
- STRNCASECMP_L(VG_Z_LIBC_SONAME, strncasecmp_l)
- STRNCASECMP_L(VG_Z_DYLD, strncasecmp_l)
+ //STRNCASECMP_L(VG_Z_LIBC_SONAME, strncasecmp_l)
+ //STRNCASECMP_L(VG_Z_DYLD, strncasecmp_l)
#endif
STRCMP(VG_Z_LD64_SO_1, strcmp)
#elif defined(VGO_darwin)
- STRCMP(VG_Z_LIBC_SONAME, strcmp)
+ //STRCMP(VG_Z_LIBC_SONAME, strcmp)
+ STRCMP(VG_Z_LIBC_SONAME, strcmp)
#endif
MEMCHR(VG_Z_LIBC_SONAME, memchr)
#elif defined(VGO_darwin)
- MEMCHR(VG_Z_LIBC_SONAME, memchr)
- MEMCHR(VG_Z_DYLD, memchr)
+ //MEMCHR(VG_Z_LIBC_SONAME, memchr)
+ //MEMCHR(VG_Z_DYLD, memchr)
#endif
MEMCPY(NONE, ZuintelZufastZumemcpy)
#elif defined(VGO_darwin)
- MEMCPY(VG_Z_LIBC_SONAME, memcpy)
- MEMCPY(VG_Z_DYLD, memcpy)
+ //MEMCPY(VG_Z_LIBC_SONAME, memcpy)
+ //MEMCPY(VG_Z_DYLD, memcpy)
+ MEMCPY(VG_Z_LIBC_SONAME, memcpyZDVARIANTZDsse3x) /* memcpy$VARIANT$sse3x */
+ MEMCPY(VG_Z_LIBC_SONAME, memcpyZDVARIANTZDsse42) /* memcpy$VARIANT$sse42 */
#endif
MEMCMP(VG_Z_LD_SO_1, bcmp)
#elif defined(VGO_darwin)
- MEMCMP(VG_Z_LIBC_SONAME, memcmp)
- MEMCMP(VG_Z_LIBC_SONAME, bcmp)
- MEMCMP(VG_Z_DYLD, memcmp)
- MEMCMP(VG_Z_DYLD, bcmp)
+ //MEMCMP(VG_Z_LIBC_SONAME, memcmp)
+ //MEMCMP(VG_Z_LIBC_SONAME, bcmp)
+ //MEMCMP(VG_Z_DYLD, memcmp)
+ //MEMCMP(VG_Z_DYLD, bcmp)
#endif
STPCPY(VG_Z_LD_LINUX_X86_64_SO_2, stpcpy)
#elif defined(VGO_darwin)
- STPCPY(VG_Z_LIBC_SONAME, stpcpy)
- STPCPY(VG_Z_DYLD, stpcpy)
+ //STPCPY(VG_Z_LIBC_SONAME, stpcpy)
+ //STPCPY(VG_Z_DYLD, stpcpy)
#endif
/* Why are we bothering to intercept this? It seems entirely
pointless. */
+
#define MEMSET(soname, fnname) \
void* VG_REPLACE_FUNCTION_EZU(20210,soname,fnname) \
(void *s, Int c, SizeT n); \
MEMSET(VG_Z_LIBC_SONAME, memset)
#elif defined(VGO_darwin)
+ //MEMSET(VG_Z_LIBC_SONAME, memset)
+ //MEMSET(VG_Z_DYLD, memset)
MEMSET(VG_Z_LIBC_SONAME, memset)
- MEMSET(VG_Z_DYLD, memset)
#endif
/*---------------------- memmove ----------------------*/
/* memmove -- use the MEMMOVE defn above. */
+
#if defined(VGO_linux)
MEMMOVE(VG_Z_LIBC_SONAME, memmove)
#elif defined(VGO_darwin)
- MEMMOVE(VG_Z_LIBC_SONAME, memmove)
- MEMMOVE(VG_Z_DYLD, memmove)
+ //MEMMOVE(VG_Z_LIBC_SONAME, memmove)
+ //MEMMOVE(VG_Z_DYLD, memmove)#
+ MEMMOVE(VG_Z_LIBC_SONAME, memmoveZDVARIANTZDsse3x) /* memmove$VARIANT$sse3x */
+ MEMMOVE(VG_Z_LIBC_SONAME, memmoveZDVARIANTZDsse42) /* memmove$VARIANT$sse42 */
#endif
#if defined(VGO_linux)
#elif defined(VGO_darwin)
- BCOPY(VG_Z_LIBC_SONAME, bcopy)
- BCOPY(VG_Z_DYLD, bcopy)
+ //BCOPY(VG_Z_LIBC_SONAME, bcopy)
+ //BCOPY(VG_Z_DYLD, bcopy)
#endif
GLIBC25_MEMPCPY(VG_Z_LD_SO_1, mempcpy) /* ld.so.1 */
#elif defined(VGO_darwin)
- GLIBC25_MEMPCPY(VG_Z_LIBC_SONAME, mempcpy)
+ //GLIBC25_MEMPCPY(VG_Z_LIBC_SONAME, mempcpy)
#endif