From: Julian Seward Date: Wed, 21 Sep 2011 08:43:08 +0000 (+0000) Subject: Add initial support for Mac OS X 10.7 (Lion). Tracked by bug #275168. X-Git-Tag: svn/VALGRIND_3_7_0~194 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=8885c4e740820578b148c49089f70c01da071902;p=thirdparty%2Fvalgrind.git 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 --- diff --git a/Makefile.am b/Makefile.am index 8526048a5a..5966e61234 100644 --- a/Makefile.am +++ b/Makefile.am @@ -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 diff --git a/configure.in b/configure.in index 334e3f469f..1c6560dac6 100644 --- a/configure.in +++ b/configure.in @@ -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 ;; diff --git a/coregrind/m_debuginfo/debuginfo.c b/coregrind/m_debuginfo/debuginfo.c index 6a9c177b02..97373e88a9 100644 --- a/coregrind/m_debuginfo/debuginfo.c +++ b/coregrind/m_debuginfo/debuginfo.c @@ -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); + 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; } @@ -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). */ diff --git a/coregrind/m_debuginfo/priv_storage.h b/coregrind/m_debuginfo/priv_storage.h index fa57d99ff7..740e6f762c 100644 --- a/coregrind/m_debuginfo/priv_storage.h +++ b/coregrind/m_debuginfo/priv_storage.h @@ -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; }; diff --git a/coregrind/m_replacemalloc/vg_replace_malloc.c b/coregrind/m_replacemalloc/vg_replace_malloc.c index f75bc7c661..0ee96d8867 100644 --- a/coregrind/m_replacemalloc/vg_replace_malloc.c +++ b/coregrind/m_replacemalloc/vg_replace_malloc.c @@ -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)) diff --git a/coregrind/m_syswrap/priv_syswrap-darwin.h b/coregrind/m_syswrap/priv_syswrap-darwin.h index ec99d8b65f..8d058b035b 100644 --- a/coregrind/m_syswrap/priv_syswrap-darwin.h +++ b/coregrind/m_syswrap/priv_syswrap-darwin.h @@ -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); diff --git a/coregrind/m_syswrap/syswrap-amd64-darwin.c b/coregrind/m_syswrap/syswrap-amd64-darwin.c index 03bad5e026..20ff97d1e3 100644 --- a/coregrind/m_syswrap/syswrap-amd64-darwin.c +++ b/coregrind/m_syswrap/syswrap-amd64-darwin.c @@ -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. diff --git a/coregrind/m_syswrap/syswrap-darwin.c b/coregrind/m_syswrap/syswrap-darwin.c index aa43e97784..5bb1a606f4 100644 --- a/coregrind/m_syswrap/syswrap-darwin.c +++ b/coregrind/m_syswrap/syswrap-darwin.c @@ -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 diff --git a/coregrind/pub_core_debuginfo.h b/coregrind/pub_core_debuginfo.h index 876eac172a..da9ec3e324 100644 --- a/coregrind/pub_core_debuginfo.h +++ b/coregrind/pub_core_debuginfo.h @@ -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 ); diff --git a/darwin11.supp b/darwin11.supp new file mode 100644 index 0000000000..8c5caef045 --- /dev/null +++ b/darwin11.supp @@ -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) +{ + + 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 +#} diff --git a/include/pub_tool_redir.h b/include/pub_tool_redir.h index 4ca8358350..1649f8c9fe 100644 --- a/include/pub_tool_redir.h +++ b/include/pub_tool_redir.h @@ -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. --- */ diff --git a/include/vki/vki-scnums-darwin.h b/include/vki/vki-scnums-darwin.h index f39f28ebb5..30a83801ff 100644 --- a/include/vki/vki-scnums-darwin.h +++ b/include/vki/vki-scnums-darwin.h @@ -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) diff --git a/memcheck/mc_replace_strmem.c b/memcheck/mc_replace_strmem.c index ddaf5121e8..1fdb7ebb39 100644 --- a/memcheck/mc_replace_strmem.c +++ b/memcheck/mc_replace_strmem.c @@ -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