From: Julian Seward Date: Thu, 2 Aug 2012 18:25:04 +0000 (+0000) Subject: Add initial support for MacOSX 10.8. Note this is still very borked X-Git-Tag: svn/VALGRIND_3_8_0~54 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=f0c0f9f3cebcb7b287d8db05783587946cc9263f;p=thirdparty%2Fvalgrind.git Add initial support for MacOSX 10.8. Note this is still very borked and pretty much unusable for real work. git-svn-id: svn://svn.valgrind.org/valgrind/trunk@12814 --- diff --git a/Makefile.am b/Makefile.am index 1de4277ed0..7d65a7fe96 100644 --- a/Makefile.am +++ b/Makefile.am @@ -43,7 +43,7 @@ SUPP_FILES = \ exp-sgcheck.supp \ darwin9.supp darwin9-drd.supp \ darwin10.supp darwin10-drd.supp \ - darwin11.supp \ + darwin11.supp darwin12.supp \ bionic.supp DEFAULT_SUPP_FILES = @DEFAULT_SUPP@ diff --git a/configure.in b/configure.in index cefb428513..90f0ee8795 100644 --- a/configure.in +++ b/configure.in @@ -134,7 +134,7 @@ case "${is_clang}-${gcc_version}" in notclang-4.*) AC_MSG_RESULT([ok (${gcc_version})]) ;; - clang-2.9|clang-3.*) + clang-2.9|clang-3.*|clang-4.*) AC_MSG_RESULT([ok (clang-${gcc_version})]) ;; *) @@ -287,6 +287,7 @@ case "${host_os}" in AC_DEFINE([DARWIN_10_5], 100500, [DARWIN_VERS value for Mac OS X 10.5]) AC_DEFINE([DARWIN_10_6], 100600, [DARWIN_VERS value for Mac OS X 10.6]) AC_DEFINE([DARWIN_10_7], 100700, [DARWIN_VERS value for Mac OS X 10.7]) + AC_DEFINE([DARWIN_10_8], 100800, [DARWIN_VERS value for Mac OS X 10.8]) AC_MSG_CHECKING([for the kernel version]) kernel=`uname -r` @@ -323,10 +324,15 @@ case "${host_os}" in 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}" ;; + 12.*) + AC_MSG_RESULT([Darwin 12.x (${kernel}) / Mac OS X 10.8 Mountain Lion]) + AC_DEFINE([DARWIN_VERS], DARWIN_10_8, [Darwin / Mac OS X version]) + DEFAULT_SUPP="darwin12.supp ${DEFAULT_SUPP}" + DEFAULT_SUPP="darwin10-drd.supp ${DEFAULT_SUPP}" + ;; *) AC_MSG_RESULT([unsupported (${kernel})]) AC_MSG_ERROR([Valgrind works on Darwin 10.x and 11.x (Mac OS X 10.6/7)]) diff --git a/coregrind/m_debuginfo/debuginfo.c b/coregrind/m_debuginfo/debuginfo.c index f59301dfac..6e88124e26 100644 --- a/coregrind/m_debuginfo/debuginfo.c +++ b/coregrind/m_debuginfo/debuginfo.c @@ -956,7 +956,7 @@ void VG_(di_notify_mprotect)( Addr a, SizeT len, UInt prot ) 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 +# if defined(VGP_x86_darwin) && (DARWIN_VERS == DARWIN_10_7 || DARWIN_VERS == DARWIN_10_8) do_nothing = False; # endif if (do_nothing /* wrong platform */) diff --git a/coregrind/m_main.c b/coregrind/m_main.c index 3d7fc1c64d..261586f24e 100644 --- a/coregrind/m_main.c +++ b/coregrind/m_main.c @@ -1284,6 +1284,15 @@ static void print_preamble ( Bool logging_to_fd, else if (VG_(clo_verbosity) > 0) VG_(umsg)("\n"); +# if defined(VGO_darwin) && DARWIN_VERS == DARWIN_10_8 + /* Uh, this doesn't play nice with XML output. */ + umsg_or_xml( "WARNING: Support on MacOS 10.8 is experimental and mostly broken.\n"); + umsg_or_xml( "WARNING: Expect incorrect results, assertions and crashes.\n"); + umsg_or_xml( "WARNING: In particular, Memcheck on 32-bit programs will fail to\n"); + umsg_or_xml( "WARNING: detect any errors associated with heap-allocated data.\n"); + umsg_or_xml( "\n" ); +# endif + if (VG_(clo_verbosity) > 1) { SysRes fd; VexArch vex_arch; @@ -1602,7 +1611,12 @@ Int valgrind_main ( Int argc, HChar **argv, HChar **envp ) VG_(debugLog)(1, "main", "Checking current stack is plausible\n"); { HChar* limLo = (HChar*)(&VG_(interim_stack).bytes[0]); HChar* limHi = limLo + sizeof(VG_(interim_stack)); - HChar* aLocal = (HChar*)&zero; /* any auto local will do */ + HChar* aLocal = (HChar*)&limLo; /* any auto local will do */ + /* "Apple clang version 4.0 (tags/Apple/clang-421.0.57) (based on + LLVM 3.1svn)" appears to miscompile the following check, + causing run to abort at this point (in 64-bit mode) even + though aLocal is within limLo .. limHi. Try building with + gcc instead. */ if (aLocal < limLo || aLocal >= limHi) { /* something's wrong. Stop. */ VG_(debugLog)(0, "main", "Root stack %p to %p, a local %p\n", diff --git a/coregrind/m_syswrap/priv_syswrap-darwin.h b/coregrind/m_syswrap/priv_syswrap-darwin.h index f811f29db2..41e9e178fe 100644 --- a/coregrind/m_syswrap/priv_syswrap-darwin.h +++ b/coregrind/m_syswrap/priv_syswrap-darwin.h @@ -559,6 +559,16 @@ DECL_TEMPLATE(darwin, mach_msg_task); DECL_TEMPLATE(darwin, mach_msg_thread); // Mach traps +#if DARWIN_VERS == DARWIN_10_8 +DECL_TEMPLATE(darwin, mach__10); +DECL_TEMPLATE(darwin, mach__12); +DECL_TEMPLATE(darwin, mach__14); +DECL_TEMPLATE(darwin, mach__16); +DECL_TEMPLATE(darwin, mach__18); +DECL_TEMPLATE(darwin, mach__19); +DECL_TEMPLATE(darwin, mach__20); +DECL_TEMPLATE(darwin, mach__21); +#endif /* DARWIN_VERS == DARWIN_10_8 */ DECL_TEMPLATE(darwin, mach_msg_unhandled); DECL_TEMPLATE(darwin, mach_msg); DECL_TEMPLATE(darwin, mach_reply_port); diff --git a/coregrind/m_syswrap/syswrap-amd64-darwin.c b/coregrind/m_syswrap/syswrap-amd64-darwin.c index b71b6d682b..ef4cacd794 100644 --- a/coregrind/m_syswrap/syswrap-amd64-darwin.c +++ b/coregrind/m_syswrap/syswrap-amd64-darwin.c @@ -448,7 +448,7 @@ void wqthread_hijack(Addr self, Addr kport, Addr stackaddr, Addr workitem, idea why. */ # if DARWIN_VERS <= DARWIN_10_6 UWord magic_delta = 0; -# elif DARWIN_VERS == DARWIN_10_7 +# elif DARWIN_VERS >= DARWIN_10_7 UWord magic_delta = 0x60; # endif diff --git a/coregrind/m_syswrap/syswrap-darwin.c b/coregrind/m_syswrap/syswrap-darwin.c index dbafe47589..fb4cb5f764 100644 --- a/coregrind/m_syswrap/syswrap-darwin.c +++ b/coregrind/m_syswrap/syswrap-darwin.c @@ -1477,9 +1477,12 @@ PRE(workq_open) static const char *workqop_name(int op) { switch (op) { - case VKI_WQOPS_QUEUE_ADD: return "QUEUE_ADD"; - case VKI_WQOPS_QUEUE_REMOVE: return "QUEUE_REMOVE"; - case VKI_WQOPS_THREAD_RETURN: return "THREAD_RETURN"; + case VKI_WQOPS_QUEUE_ADD: return "QUEUE_ADD"; + case VKI_WQOPS_QUEUE_REMOVE: return "QUEUE_REMOVE"; + case VKI_WQOPS_THREAD_RETURN: return "THREAD_RETURN"; + case VKI_WQOPS_THREAD_SETCONC: return "THREAD_SETCONC"; + case VKI_WQOPS_QUEUE_NEWSPISUPP: return "QUEUE_NEWSPISUPP"; + case VKI_WQOPS_QUEUE_REQTHREADS: return "QUEUE_REQTHREADS"; default: return "?"; } } @@ -1498,6 +1501,8 @@ PRE(workq_ops) // GrP fixme need anything here? // GrP fixme may block? break; + case VKI_WQOPS_QUEUE_NEWSPISUPP: + break; // JRS don't think we need to do anything here case VKI_WQOPS_THREAD_RETURN: { // The interesting case. The kernel will do one of two things: @@ -3521,6 +3526,7 @@ POST(auditon) PRE(mmap) { // SysRes r; + if (0) VG_(am_do_sync_check)("(PRE_MMAP)",__FILE__,__LINE__); #if VG_WORDSIZE == 4 PRINT("mmap ( %#lx, %lu, %ld, %ld, %ld, %lld )", @@ -4986,6 +4992,8 @@ PRE(task_get_special_port) PRINT("task_get_special_port(%s, TASK_BOOTSTRAP_PORT)", name_for_port(MACH_REMOTE)); break; +#if DARWIN_VERS != DARWIN_10_8 + /* These disappeared in 10.8 */ case TASK_WIRED_LEDGER_PORT: PRINT("task_get_special_port(%s, TASK_WIRED_LEDGER_PORT)", name_for_port(MACH_REMOTE)); @@ -4994,6 +5002,7 @@ PRE(task_get_special_port) PRINT("task_get_special_port(%s, TASK_PAGED_LEDGER_PORT)", name_for_port(MACH_REMOTE)); break; +#endif default: PRINT("task_get_special_port(%s, %d)", name_for_port(MACH_REMOTE), req->which_port); @@ -5032,12 +5041,15 @@ POST(task_get_special_port) case TASK_HOST_PORT: assign_port_name(reply->special_port.name, "host"); break; +#if DARWIN_VERS != DARWIN_10_8 + /* These disappeared in 10.8 */ case TASK_WIRED_LEDGER_PORT: assign_port_name(reply->special_port.name, "wired-ledger"); break; case TASK_PAGED_LEDGER_PORT: assign_port_name(reply->special_port.name, "paged-ledger"); break; +#endif default: assign_port_name(reply->special_port.name, "special-%p"); break; @@ -6503,7 +6515,13 @@ PRE(bsdthread_terminate) if (ARG4) semaphore_signal((semaphore_t)ARG4); if (ARG1 && ARG2) { ML_(notify_core_and_tool_of_munmap)(ARG1, ARG2); +# if DARWIN_VERS == DARWIN_10_8 + /* JRS 2012 Aug 02: ugly hack: vm_deallocate disappeared from + the mig output. Work around it for the time being. */ + VG_(do_syscall2)(__NR_munmap, ARG1, ARG2); +# else vm_deallocate(mach_task_self(), (vm_address_t)ARG1, (vm_size_t)ARG2); +# endif } // Tell V to terminate the thread. @@ -7810,6 +7828,63 @@ POST(psynch_cvclrprepost) } +/* --------------------------------------------------------------------- + Added for OSX 10.8 (Mountain Lion) + ------------------------------------------------------------------ */ + +#if DARWIN_VERS == DARWIN_10_8 + +PRE(mach__10) +{ + PRINT("mach__10(ARGUMENTS_UNKNOWN)"); +} +POST(mach__10) +{ + ML_(sync_mappings)("after", "mach__10", 0); +} + +PRE(mach__12) +{ + PRINT("mach__12(ARGUMENTS_UNKNOWN)"); +} +POST(mach__12) +{ + ML_(sync_mappings)("after", "mach__12", 0); +} + +PRE(mach__14) +{ + PRINT("mach__14(ARGUMENTS_UNKNOWN)"); +} + +PRE(mach__16) +{ + PRINT("mach__16(ARGUMENTS_UNKNOWN)"); +} + +PRE(mach__18) +{ + PRINT("mach__18(ARGUMENTS_UNKNOWN)"); +} + +PRE(mach__19) +{ + PRINT("mach__19(ARGUMENTS_UNKNOWN)"); +} + +PRE(mach__20) +{ + PRINT("mach__20(ARGUMENTS_UNKNOWN)"); +} + +PRE(mach__21) +{ + PRINT("mach__21(ARGUMENTS_UNKNOWN)"); +} + +#endif /* DARWIN_VERS == DARWIN_10_8 */ + + /* --------------------------------------------------------------------- syscall tables ------------------------------------------------------------------ */ @@ -7817,10 +7892,11 @@ POST(psynch_cvclrprepost) /* Add a Darwin-specific, arch-independent wrapper to a syscall table. */ #define MACX_(sysno, name) WRAPPER_ENTRY_X_(darwin, VG_DARWIN_SYSNO_INDEX(sysno), name) #define MACXY(sysno, name) WRAPPER_ENTRY_XY(darwin, VG_DARWIN_SYSNO_INDEX(sysno), name) -#define _____(sysno) GENX_(sysno, sys_ni_syscall) +#define _____(sysno) GENX_(sysno, sys_ni_syscall) /* UNIX style only */ /* - _____ : unsupported by the kernel (sys_ni_syscall) + _____ : unsupported by the kernel (sys_ni_syscall) (UNIX-style only) + unfortunately misused for Mach too, causing assertion failures // _____ : unimplemented in valgrind GEN : handlers are in syswrap-generic.c MAC : handlers are in this file @@ -8315,18 +8391,51 @@ const SyscallTableEntry ML_(mach_trap_table)[] = { _____(VG_DARWIN_SYSCALL_CONSTRUCT_MACH(7)), _____(VG_DARWIN_SYSCALL_CONSTRUCT_MACH(8)), _____(VG_DARWIN_SYSCALL_CONSTRUCT_MACH(9)), - _____(VG_DARWIN_SYSCALL_CONSTRUCT_MACH(10)), + +# if DARWIN_VERS == DARWIN_10_8 + MACXY(VG_DARWIN_SYSCALL_CONSTRUCT_MACH(10), mach__10), +# else + _____(VG_DARWIN_SYSCALL_CONSTRUCT_MACH(10), +# endif + _____(VG_DARWIN_SYSCALL_CONSTRUCT_MACH(11)), + +# if DARWIN_VERS == DARWIN_10_8 + MACXY(VG_DARWIN_SYSCALL_CONSTRUCT_MACH(12), mach__12), +# else _____(VG_DARWIN_SYSCALL_CONSTRUCT_MACH(12)), +# endif + _____(VG_DARWIN_SYSCALL_CONSTRUCT_MACH(13)), + +# if DARWIN_VERS == DARWIN_10_8 + MACX_(VG_DARWIN_SYSCALL_CONSTRUCT_MACH(14), mach__14), +# else _____(VG_DARWIN_SYSCALL_CONSTRUCT_MACH(14)), +# endif + _____(VG_DARWIN_SYSCALL_CONSTRUCT_MACH(15)), + +# if DARWIN_VERS == DARWIN_10_8 + MACX_(VG_DARWIN_SYSCALL_CONSTRUCT_MACH(16), mach__16), +# else _____(VG_DARWIN_SYSCALL_CONSTRUCT_MACH(16)), +# endif + _____(VG_DARWIN_SYSCALL_CONSTRUCT_MACH(17)), + +# if DARWIN_VERS == DARWIN_10_8 + MACX_(VG_DARWIN_SYSCALL_CONSTRUCT_MACH(18), mach__18), + MACX_(VG_DARWIN_SYSCALL_CONSTRUCT_MACH(19), mach__19), + MACX_(VG_DARWIN_SYSCALL_CONSTRUCT_MACH(20), mach__20), + MACX_(VG_DARWIN_SYSCALL_CONSTRUCT_MACH(21), mach__21), +# else _____(VG_DARWIN_SYSCALL_CONSTRUCT_MACH(18)), _____(VG_DARWIN_SYSCALL_CONSTRUCT_MACH(19)), - _____(VG_DARWIN_SYSCALL_CONSTRUCT_MACH(20)), // -20 + _____(VG_DARWIN_SYSCALL_CONSTRUCT_MACH(20)), _____(VG_DARWIN_SYSCALL_CONSTRUCT_MACH(21)), +# endif + _____(VG_DARWIN_SYSCALL_CONSTRUCT_MACH(22)), _____(VG_DARWIN_SYSCALL_CONSTRUCT_MACH(23)), _____(VG_DARWIN_SYSCALL_CONSTRUCT_MACH(24)), diff --git a/coregrind/m_syswrap/syswrap-x86-darwin.c b/coregrind/m_syswrap/syswrap-x86-darwin.c index 6096d4ac7e..ff2b7d4883 100644 --- a/coregrind/m_syswrap/syswrap-x86-darwin.c +++ b/coregrind/m_syswrap/syswrap-x86-darwin.c @@ -409,7 +409,7 @@ void wqthread_hijack(Addr self, Addr kport, Addr stackaddr, Addr workitem, idea why. */ # if DARWIN_VERS <= DARWIN_10_6 UWord magic_delta = 0; -# elif DARWIN_VERS == DARWIN_10_7 +# elif DARWIN_VERS >= DARWIN_10_7 UWord magic_delta = 0x48; # endif diff --git a/coregrind/m_ume/macho.c b/coregrind/m_ume/macho.c index be37ca8b7e..142a3f9821 100644 --- a/coregrind/m_ume/macho.c +++ b/coregrind/m_ume/macho.c @@ -76,12 +76,21 @@ static void print(const char *str) static void check_mmap(SysRes res, Addr base, SizeT len, HChar* who) { if (sr_isError(res)) { - VG_(printf)("valgrind: mmap(0x%llx, %lld) failed in UME (%s).\n", + VG_(printf)("valgrind: mmap-FIXED(0x%llx, %lld) failed in UME (%s).\n", (ULong)base, (Long)len, who); VG_(exit)(1); } } +static void check_mmap_float(SysRes res, SizeT len, HChar* who) +{ + if (sr_isError(res)) { + VG_(printf)("valgrind: mmap-FLOAT(size=%lld) failed in UME (%s).\n", + (Long)len, who); + VG_(exit)(1); + } +} + static int load_thin_file(int fd, vki_off_t offset, vki_off_t size, unsigned long filetype, @@ -370,6 +379,45 @@ load_unixthread(vki_uint8_t **out_stack_start, vki_uint8_t **out_stack_end, } +/* Allocates a stack mapping at a V-chosen address. Pertains to + LC_MAIN commands, which seem to have appeared in OSX 10.8. + + This is a really nasty hack -- allocates 64M+stack size, then + deallocates the 64M, to guarantee that the stack is at least 64M + above zero. */ +static int +handle_lcmain ( vki_uint8_t **out_stack_start, + vki_uint8_t **out_stack_end, + vki_size_t requested_size ) +{ + if (requested_size == 0) { + requested_size = default_stack_size(); + } + requested_size = VG_PGROUNDUP(requested_size); + + const vki_size_t HACK = 64 * 1024 * 1024; + requested_size += HACK; + + SysRes res = VG_(am_mmap_anon_float_client)(requested_size, + VKI_PROT_READ|VKI_PROT_WRITE|VKI_PROT_EXEC); + check_mmap_float(res, requested_size, "handle_lcmain"); + vg_assert(!sr_isError(res)); + *out_stack_start = (vki_uint8_t*)sr_Res(res); + *out_stack_end = *out_stack_start + requested_size; + + Bool need_discard = False; + res = VG_(am_munmap_client)(&need_discard, (Addr)*out_stack_start, HACK); + if (sr_isError(res)) return -1; + vg_assert(!need_discard); // True == wtf? + + *out_stack_start += HACK; + + return 0; +} + + + + /* Processes an LC_LOAD_DYLINKER command. Returns 0 on success, -1 on any error. @@ -432,6 +480,7 @@ load_thin_file(int fd, vki_off_t offset, vki_off_t size, unsigned long filetype, vki_uint8_t **out_stack_start, vki_uint8_t **out_stack_end, vki_uint8_t **out_text, vki_uint8_t **out_entry, vki_uint8_t **out_linker_entry) { + VG_(debugLog)(1, "ume", "load_thin_file: begin: %s\n", filename); struct MACH_HEADER mh; vki_uint8_t *headers; vki_uint8_t *headers_end; @@ -506,6 +555,23 @@ load_thin_file(int fd, vki_off_t offset, vki_off_t size, unsigned long filetype, } switch (lc->cmd) { + +#if DARWIN_VERS == DARWIN_10_8 + case LC_MAIN: { /* New in 10.8 */ + struct entry_point_command* epcmd + = (struct entry_point_command*)lc; + if (stack_start || stack_end) { + print("bad executable (multiple indications of stack)"); + return -1; + } + err = handle_lcmain ( &stack_start, &stack_end, epcmd->stacksize ); + if (err) return -1; + VG_(debugLog)(2, "ume", "lc_main: created stack %p-%p\n", + stack_start, stack_end); + break; + } +# endif + case LC_SEGMENT_CMD: if (lc->cmdsize < sizeof(struct SEGMENT_COMMAND)) { print("bad executable (invalid load commands)\n"); @@ -582,7 +648,7 @@ load_thin_file(int fd, vki_off_t offset, vki_off_t size, unsigned long filetype, // a text segment // an entry point (static or linker) if (!stack_end || !stack_start) { - print("bad executable (no stack)\n"); + VG_(printf)("bad executable %s (no stack)\n", filename); return -1; } if (!text) { @@ -609,6 +675,7 @@ load_thin_file(int fd, vki_off_t offset, vki_off_t size, unsigned long filetype, if (out_entry) *out_entry = entry; if (out_linker_entry) *out_linker_entry = linker_entry; + VG_(debugLog)(1, "ume", "load_thin_file: success: %s\n", filename); return 0; } diff --git a/darwin12.supp b/darwin12.supp new file mode 100644 index 0000000000..e69de29bb2 diff --git a/include/pub_tool_redir.h b/include/pub_tool_redir.h index 9311fd0999..2df1fc3d3e 100644 --- a/include/pub_tool_redir.h +++ b/include/pub_tool_redir.h @@ -246,7 +246,7 @@ #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) +#elif defined(VGO_darwin) && (DARWIN_VERS >= DARWIN_10_7) # define VG_Z_LIBC_SONAME libsystemZucZaZddylib // libsystem_c*.dylib #else diff --git a/include/vki/vki-darwin.h b/include/vki/vki-darwin.h index dfc883dfe1..70de0d95ef 100644 --- a/include/vki/vki-darwin.h +++ b/include/vki/vki-darwin.h @@ -829,9 +829,12 @@ struct ByteRangeLockPB2 // Libc/pthreads/pthread.c -#define VKI_WQOPS_QUEUE_ADD 1 -#define VKI_WQOPS_QUEUE_REMOVE 2 -#define VKI_WQOPS_THREAD_RETURN 4 +#define VKI_WQOPS_QUEUE_ADD 1 +#define VKI_WQOPS_QUEUE_REMOVE 2 +#define VKI_WQOPS_THREAD_RETURN 4 +#define VKI_WQOPS_THREAD_SETCONC 8 +#define VKI_WQOPS_QUEUE_NEWSPISUPP 16 /* check for newer SPI support */ +#define VKI_WQOPS_QUEUE_REQTHREADS 32 /* request number of threads of a prio */ #include