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 a5019735-40e9-0310-863c-91ae7b9d1cf9
diff --git a/Makefile.am b/Makefile.am
index 1de4277..7d65a7f 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -43,7 +43,7 @@
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 cefb428..90f0ee8 100644
--- a/configure.in
+++ b/configure.in
@@ -134,7 +134,7 @@
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 @@
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 @@
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 f59301d..6e88124 100644
--- a/coregrind/m_debuginfo/debuginfo.c
+++ b/coregrind/m_debuginfo/debuginfo.c
@@ -956,7 +956,7 @@
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 3d7fc1c..261586f 100644
--- a/coregrind/m_main.c
+++ b/coregrind/m_main.c
@@ -1284,6 +1284,15 @@
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 @@
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 f811f29..41e9e17 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_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 b71b6d6..ef4cacd 100644
--- a/coregrind/m_syswrap/syswrap-amd64-darwin.c
+++ b/coregrind/m_syswrap/syswrap-amd64-darwin.c
@@ -448,7 +448,7 @@
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 dbafe47..fb4cb5f 100644
--- a/coregrind/m_syswrap/syswrap-darwin.c
+++ b/coregrind/m_syswrap/syswrap-darwin.c
@@ -1477,9 +1477,12 @@
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 @@
// 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 @@
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 @@
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 @@
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 @@
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 @@
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.
@@ -7811,16 +7829,74 @@
/* ---------------------------------------------------------------------
+ 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
------------------------------------------------------------------ */
/* 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 @@
_____(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 6096d4a..ff2b7d4 100644
--- a/coregrind/m_syswrap/syswrap-x86-darwin.c
+++ b/coregrind/m_syswrap/syswrap-x86-darwin.c
@@ -409,7 +409,7 @@
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 be37ca8..142a3f9 100644
--- a/coregrind/m_ume/macho.c
+++ b/coregrind/m_ume/macho.c
@@ -76,12 +76,21 @@
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 @@
}
+/* 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 @@
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 @@
}
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 @@
// 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 @@
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 0000000..e69de29
--- /dev/null
+++ b/darwin12.supp
diff --git a/include/pub_tool_redir.h b/include/pub_tool_redir.h
index 9311fd0..2df1fc3 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 dfc883d..70de0d9 100644
--- a/include/vki/vki-darwin.h
+++ b/include/vki/vki-darwin.h
@@ -829,9 +829,12 @@
// 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 <sys/ttycom.h>