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
This commit is contained in:
Julian Seward 2012-08-02 18:25:04 +00:00
parent 0b3c2d6642
commit f0c0f9f3ce
12 changed files with 229 additions and 20 deletions

View File

@ -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@

View File

@ -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)])

View File

@ -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 */)

View File

@ -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",

View File

@ -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);

View File

@ -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

View File

@ -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)),

View File

@ -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

View File

@ -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;
}

0
darwin12.supp Normal file
View File

View File

@ -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

View File

@ -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 <sys/ttycom.h>