Add initial support for Mac OS X 10.7 (Lion). Tracked by bug #275168.

* configure.in support

* new supp file darwin11.supp

* comment out many intercepts in mc_replace_strmem.c and
  vg_replace_malloc.c that are apparently unnecessary for Darwin

* add minimal handling for the following new syscalls and mach traps:
    mach_port_set_context
    task_get_exception_ports
    getaudit_addr
    psynch_mutexwait
    psynch_mutexdrop
    psynch_cvbroad
    psynch_cvsignal
    psynch_cvwait
    psynch_rw_rdlock
    psynch_rw_wrlock
    psynch_rw_unlock
    psynch_cvclrprepost

* wqthread_hijack on amd64-darwin: deal with
  tst->os_state.pthread having an apparently different offset,
  which caused an assertion failure

* m_debuginfo: for 32 bit processes on Lion, use the DebugInfoFSM
  cleanup added in r12041/12042 to handle apparently new dyld
  behaviour, which is to map text areas r-- first and only
  vm_protect them later to r-x.



The following cleanups remain to be done

* remove apparently pointless, commented out wrapper macro
  invokations in mc_replace_strmem.c, eg

  //MEMMOVE(VG_Z_DYLD,        memmove)

  (or determine that they are still necessary, and uncomment)


* ditto in vg_replace_malloc.c, plus general VGO_darwin cleanups
  there


* write proper syscall wrappers for
    mach_port_set_context
    task_get_exception_ports
    getaudit_addr
    psynch_mutexwait
    psynch_mutexdrop
    psynch_cvbroad
    psynch_cvsignal
    psynch_cvwait
    psynch_rw_rdlock
    psynch_rw_wrlock
    psynch_rw_unlock
    psynch_cvclrprepost
  These are currently just no-ops and may be causing Memcheck to
  report false undef-value errors


* figure out why it doesn't work properly unless built with gcc-4.2 on
  Lion.

  gcc-4.2 is the "normal" gcc (i686-apple-darwin11-gcc-4.2.1).  Plain
  gcc is the hybrid gcc-front-end clang-back-end thing
  (i686-apple-darwin11-llvm-gcc-4.2).  Whereas on Snow Leopard, plain
  gcc is the normal gcc.

  The symptoms of the failure are that wqthread_hijack in
  syswrap-amd64-linux.c hits this /*NOTREACHED*/ vg_assert(0); right
  at the end (you need a pretty complex threaded app to trigger this),
  which makes me think that either ML_(wqthread_continue_NORETURN) or
  call_on_new_stack_0_1 do return, which they are not expected to.


* figure out if some of the uninitialised value errors reported in
  system libraries on are caused by Memcheck being confused by LLVM
  generated code, as per bug #242137



git-svn-id: svn://svn.valgrind.org/valgrind/trunk@12043
This commit is contained in:
Julian Seward 2011-09-21 08:43:08 +00:00
parent ccaa4e370a
commit 8885c4e740
13 changed files with 725 additions and 207 deletions

View File

@ -53,6 +53,7 @@ SUPP_FILES = \
exp-sgcheck.supp \
darwin9.supp darwin9-drd.supp \
darwin10.supp darwin10-drd.supp \
darwin11.supp \
bionic.supp
DEFAULT_SUPP_FILES = @DEFAULT_SUPP@
@ -116,4 +117,5 @@ all-local: default.supp
clean-local:
rm -rf $(inplacedir)
# Need config.h in the installed tree, since some files depend on it
pkginclude_HEADERS = config.h

View File

@ -246,11 +246,19 @@ case "${host_os}" in
# 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])
@ -264,9 +272,16 @@ case "${host_os}" in
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
;;

View File

@ -571,10 +571,87 @@ void VG_(di_initialise) ( void )
#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
@ -594,9 +671,8 @@ ULong VG_(di_notify_mmap)( Addr a, Bool allow_SkFileV )
{
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];
@ -707,6 +783,8 @@ ULong VG_(di_notify_mmap)( Addr a, Bool allow_SkFileV )
*/
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;
@ -720,12 +798,16 @@ ULong VG_(di_notify_mmap)( Addr a, Bool allow_SkFileV )
# 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 */
@ -799,71 +881,30 @@ ULong VG_(di_notify_mmap)( Addr a, Bool allow_SkFileV )
}
}
/* 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);
} 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 (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 */
}
}
TRACE_SYMTAB("\n");
TRACE_SYMTAB("------ name = %s\n", di->fsm.filename);
TRACE_SYMTAB("------ end ELF OBJECT "
"------------------------------\n");
TRACE_SYMTAB("\n");
return di_handle;
/* 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 {
/* 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;
}
}
@ -896,6 +937,72 @@ void VG_(di_notify_mprotect)( Addr a, SizeT len, UInt prot )
}
}
/* 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). */

View File

@ -402,7 +402,8 @@ ML_(cmp_for_DiAddrRange_range) ( const void* keyV, const void* elemV );
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
@ -411,9 +412,25 @@ ML_(cmp_for_DiAddrRange_range) ( const void* keyV, const void* elemV );
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? */
@ -426,6 +443,13 @@ struct _DebugInfoFSM
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;
};

View File

@ -263,7 +263,6 @@ static void init(void);
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);
@ -292,13 +291,13 @@ static void init(void);
#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
@ -321,13 +320,13 @@ static void init(void);
#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
@ -353,13 +352,13 @@ static void init(void);
#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
@ -382,13 +381,13 @@ static void init(void);
#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
@ -405,7 +404,7 @@ static void init(void);
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 ); \
@ -417,19 +416,17 @@ static void init(void);
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 );
@ -444,8 +441,8 @@ static void init(void);
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
@ -462,8 +459,8 @@ static void init(void);
#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
@ -477,8 +474,8 @@ static void init(void);
#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
@ -495,11 +492,11 @@ static void init(void);
#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
@ -513,8 +510,8 @@ static void init(void);
#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
@ -531,7 +528,7 @@ static void init(void);
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 ); \
@ -587,7 +584,7 @@ static void init(void);
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 \
@ -653,7 +650,7 @@ static void init(void);
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. */ \
@ -759,7 +756,7 @@ static void init(void);
MALLOPT(VG_Z_LIBC_SONAME, mallopt);
#elif defined(VGO_darwin)
MALLOPT(VG_Z_LIBC_SONAME, mallopt);
//MALLOPT(VG_Z_LIBC_SONAME, mallopt);
#endif
@ -801,7 +798,7 @@ static void init(void);
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
@ -838,7 +835,7 @@ static void init(void);
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
@ -868,7 +865,7 @@ static void init(void);
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
@ -918,7 +915,7 @@ static void panic(const char *str)
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
@ -944,34 +941,36 @@ static void panic(const char *str)
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 ); \
@ -980,23 +979,36 @@ static vki_malloc_zone_t vg_default_zone = {
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))

View File

@ -358,18 +358,18 @@ DECL_TEMPLATE(darwin, settid); // 285
// 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
@ -416,7 +416,9 @@ DECL_TEMPLATE(darwin, auditon); // 351
// 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
@ -491,6 +493,7 @@ DECL_TEMPLATE(darwin, audit_session_self); // 428
// 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);
@ -512,6 +515,7 @@ DECL_TEMPLATE(darwin, mach_port_get_attributes);
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);

View File

@ -30,6 +30,7 @@
#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
@ -282,7 +283,7 @@ asm(
// other values stay where they are in registers
" push $0\n" // fake return address
" jmp _pthread_hijack\n"
);
);
@ -372,7 +373,7 @@ asm(
// 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
@ -401,12 +402,26 @@ void wqthread_hijack(Addr self, Addr kport, Addr stackaddr, Addr workitem,
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.
@ -416,8 +431,14 @@ void wqthread_hijack(Addr self, Addr kport, Addr stackaddr, Addr workitem,
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.

View File

@ -4316,6 +4316,79 @@ PRE(host_request_notification)
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)
{
@ -5332,6 +5405,7 @@ POST(vm_protect)
//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 {
@ -6752,6 +6826,9 @@ PRE(mach_msg_host)
}
}
// 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
@ -6804,7 +6881,11 @@ PRE(mach_msg_task)
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;
@ -6828,6 +6909,10 @@ PRE(mach_msg_task)
case 3412:
CALL_PRE(thread_create_running);
return;
case 3414:
CALL_PRE(task_get_exception_ports);
return;
case 3418:
CALL_PRE(semaphore_create);
@ -7629,6 +7714,103 @@ PRE(thread_fast_set_cthread_self)
}
/* ---------------------------------------------------------------------
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
------------------------------------------------------------------ */
@ -7970,18 +8152,18 @@ const SyscallTableEntry ML_(syscall_table)[] = {
_____(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),
@ -8028,7 +8210,9 @@ const SyscallTableEntry ML_(syscall_table)[] = {
// _____(__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

View File

@ -67,6 +67,9 @@ extern void VG_(di_notify_mprotect)( Addr a, SizeT len, UInt prot );
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 );

122
darwin11.supp Normal file
View File

@ -0,0 +1,122 @@
# 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
#}

View File

@ -31,6 +31,8 @@
#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
@ -240,10 +242,16 @@
#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. --- */

View File

@ -515,18 +515,18 @@
/* 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)

View File

@ -178,10 +178,11 @@ static inline void my_exit ( int x )
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
@ -214,10 +215,11 @@ static inline void my_exit ( int x )
# 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
@ -252,7 +254,7 @@ static inline void my_exit ( int x )
STRCAT(VG_Z_LIBC_SONAME, __GI_strcat)
#elif defined(VGO_darwin)
STRCAT(VG_Z_LIBC_SONAME, strcat)
//STRCAT(VG_Z_LIBC_SONAME, strcat)
#endif
@ -288,8 +290,8 @@ static inline void my_exit ( int x )
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
@ -335,8 +337,9 @@ static inline void my_exit ( int x )
#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
@ -359,7 +362,7 @@ static inline void my_exit ( int x )
STRNLEN(VG_Z_LIBC_SONAME, __GI_strnlen)
#elif defined(VGO_darwin)
STRNLEN(VG_Z_LIBC_SONAME, strnlen)
//STRNLEN(VG_Z_LIBC_SONAME, strnlen)
#endif
@ -387,7 +390,8 @@ static inline void my_exit ( int x )
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
@ -422,8 +426,9 @@ static inline void my_exit ( int x )
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
@ -455,8 +460,9 @@ static inline void my_exit ( int x )
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
@ -491,8 +497,9 @@ static inline void my_exit ( int x )
#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
@ -524,8 +531,9 @@ static inline void my_exit ( int x )
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
@ -560,7 +568,7 @@ static inline void my_exit ( int x )
# endif
#elif defined(VGO_darwin)
STRCASECMP(VG_Z_LIBC_SONAME, strcasecmp)
//STRCASECMP(VG_Z_LIBC_SONAME, strcasecmp)
#endif
@ -597,8 +605,8 @@ static inline void my_exit ( int x )
# 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
@ -632,7 +640,7 @@ static inline void my_exit ( int x )
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
@ -667,8 +675,8 @@ static inline void my_exit ( int x )
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
@ -702,7 +710,8 @@ static inline void my_exit ( int x )
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
@ -727,8 +736,8 @@ static inline void my_exit ( int x )
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
@ -833,8 +842,10 @@ static inline void my_exit ( int x )
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
@ -872,10 +883,10 @@ static inline void my_exit ( int x )
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
@ -914,8 +925,8 @@ static inline void my_exit ( int x )
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
@ -924,6 +935,7 @@ static inline void my_exit ( int x )
/* 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); \
@ -947,8 +959,9 @@ static inline void my_exit ( int x )
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
@ -956,12 +969,15 @@ static inline void my_exit ( int x )
/*---------------------- 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
@ -991,8 +1007,8 @@ static inline void my_exit ( int x )
#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
@ -1198,7 +1214,7 @@ static inline void my_exit ( int x )
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