Skip to content

Commit

Permalink
i#1979 Mac64: Add 64-bit Mojave + XCode 10.1 build support (#3514)
Browse files Browse the repository at this point in the history
A series of small changes to build with XCode 10.1 64-bit:
+ Updates -max_supported_os_version on Mac to 18.
+ Updates 64-bit Mac frame field.
+ Removes , from runtime options in template defines.
+ Removes 32-bit-only tests from the OSX label list for 64-bit.
+ Increases the core's preferred base to 0x1'71000000 to stay above
  the default 0x1' _PAGEZERO.
+ Adds missing DECL_EXTERNs in mangle_suspend and mangle_asynch tests.
+ Adds missing GLOBAL_REFs in common.decode test.
+ Re-defines sigcontext_t and uc_mcontext in tools.h to match this toolchain.
+ Adds 64-bit libelftc.a and libdwarf.a Mach-O libraries along with
  instructions on how they were built.
+ Adds -mmacosx-version-min=10.9 to drcachesim to match core/.
+ Fixes a format string warning in drcachesim.

Includes a number of similar small changes from Shawn Denbow's first 2
commits on the project-mac64 branch in PR #2269 and PR #2273, updated for
clang-format:
+ Move -vm_base above 4GB since __PAGEZERO takes up first 4GB by default
+ Increase MEMQUERY_INTERNAL_DATA_LEN
+ Update Mach-O parsing to check for LC_SEGMENT_64
+ Change error notifications to warning to allow build to continue
+ Define SC_FIELD for 64-bit registers r8-r15 and update references
+ Update dynamorio_mach_dep_syscall to use syscall for 64-bit
+ Update dynamorio_mach_syscall to use syscall for 64-bit
+ Change code referencing eflags to xflags for cross platform compat
+ Misc code fix-ups

Issue: #1979
  • Loading branch information
derekbruening committed Apr 15, 2019
1 parent 09c690b commit 229ff65
Show file tree
Hide file tree
Showing 23 changed files with 145 additions and 70 deletions.
12 changes: 8 additions & 4 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -242,7 +242,7 @@ endif (CMAKE_C_SIZEOF_DATA_PTR EQUAL 8)

if (APPLE AND X64)
# XXX #1979: 64-bit OSX is not supported.
message(FATAL_ERROR "64-bit Mac OSX is not supported")
message(WARNING "64-bit Mac OSX is not supported")
endif ()

option(VMKERNEL "target VMkernel (not officially supported yet)")
Expand Down Expand Up @@ -334,9 +334,12 @@ option(SET_PREFERRED_BASE "set a preferred library base address")
if (WIN32 AND DEBUG)
# apparently no numeric type so we use STRING
set(preferred_base "0x15000000" CACHE STRING "Preferred library base address")
else (WIN32 AND DEBUG)
elseif (APPLE AND X64)
# Set to higher than _PAGEZERO which is [0..0x1'00000000).
set(preferred_base "0x171000000" CACHE STRING "Preferred library base address")
else ()
set(preferred_base "0x71000000" CACHE STRING "Preferred library base address")
endif (WIN32 AND DEBUG)
endif ()

# for x64: PR 253624: we need our library to be next to our heap
# for win32: not PIC so need a base
Expand Down Expand Up @@ -730,9 +733,10 @@ if (UNIX)
endif ()
if (APPLE AND CMAKE_COMPILER_IS_CLANG)
# Ensure our binaries can run on older OSX
# We're building our release package on 10.11, and that XCode does not
# We're building our release package on 10.14, and that XCode does not
# supply C++ libraries for below 10.9, causing drcachesim to fail to build.
# Thus we have abandoned support for below 10.9.
# If this is updated, update drcachesim's as well.
set(BASE_CFLAGS "${BASE_CFLAGS} -mmacosx-version-min=10.9")
endif ()
if (APPLE)
Expand Down
6 changes: 5 additions & 1 deletion clients/drcachesim/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# **********************************************************
# Copyright (c) 2015-2018 Google, Inc. All rights reserved.
# Copyright (c) 2015-2019 Google, Inc. All rights reserved.
# **********************************************************

# Redistribution and use in source and binary forms, with or without
Expand Down Expand Up @@ -357,6 +357,10 @@ macro(add_win32_flags target)
if (NOT cur MATCHES "-std=")
append_property_string(TARGET ${target} COMPILE_FLAGS "-std=c++11")
endif ()
if (APPLE)
# Match the core/ flags.
append_property_string(TARGET ${target} COMPILE_FLAGS "-mmacosx-version-min=10.9")
endif ()
endif ()
endmacro ()

Expand Down
4 changes: 2 additions & 2 deletions clients/drcachesim/reader/file_reader.h
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/* **********************************************************
* Copyright (c) 2016-2018 Google, Inc. All rights reserved.
* Copyright (c) 2016-2019 Google, Inc. All rights reserved.
* **********************************************************/

/*
Expand Down Expand Up @@ -54,7 +54,7 @@
# ifdef WINDOWS
# define ZHEX64_FORMAT_STRING "%016I64x"
# else
# if defined(__i386__) || defined(__arm__)
# if defined(__i386__) || defined(__arm__) || defined(__APPLE__)
# define ZHEX64_FORMAT_STRING "%016llx"
# else
# define ZHEX64_FORMAT_STRING "%016lx"
Expand Down
1 change: 0 additions & 1 deletion core/arch/aarch64/codec.txt
Original file line number Diff line number Diff line change
Expand Up @@ -1193,4 +1193,3 @@ x101101011000000000101xxxxxxxxxx cls wx0 : wx5
01101110xx1xxxxx101000xxxxxxxxxx umlsl2 q0 : q5 q16 bhs_sz
00101110xx1xxxxx110000xxxxxxxxxx umull q0 : d5 d16 bhs_sz
01101110xx1xxxxx110000xxxxxxxxxx umull2 q0 : q5 q16 bhs_sz

2 changes: 1 addition & 1 deletion core/arch/x86/x86.asm
Original file line number Diff line number Diff line change
Expand Up @@ -1345,7 +1345,7 @@ GLOBAL_LABEL(dynamorio_condvar_wake_and_jmp:)
* so transparency should be ok so long as the app's stack is valid.
*/
mov REG_XDI, REG_XCX /* save across syscall */
mov REG_XAX, DWORD [REG_XAX] /* load mach_synch_t->sem */
mov REG_XAX, PTRSZ [REG_XAX] /* load mach_synch_t->sem */
# ifdef X64
mov ARG1, REG_XAX
mov eax, MACH_semaphore_signal_all_trap
Expand Down
16 changes: 8 additions & 8 deletions core/drlibc/drlibc_x86.asm
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,9 @@

#include "../asm_defines.asm"
#include "x86_asm_defines.asm" /* PUSHGPR, POPGPR, etc. */
#ifdef MACOS
# include "include/syscall_mach.h" /* SYSCALL_NUM_MARKER_MACH */
#endif
START_FILE

DECL_EXTERN(unexpected_return)
Expand Down Expand Up @@ -214,6 +217,8 @@ GLOBAL_LABEL(dynamorio_mach_dep_syscall:)
cmp REG_XBX, 3
je mach_dep_syscall_ready
mov ARG4, ARG6
mach_dep_syscall_ready:
syscall
# else
push REG_XBP
push REG_XSI
Expand Down Expand Up @@ -246,10 +251,8 @@ mach_dep_syscall_0args:
push 0 /* extra slot */
/* clear the top half so we can always consider the result 64-bit */
mov edx, 0
# endif
/* mach dep syscalls use interrupt 0x82 */
int HEX(82)
# ifndef X64
lea esp, [7*ARG_SZ + esp] /* must not change flags */
pop REG_XDI
pop REG_XSI
Expand Down Expand Up @@ -279,6 +282,7 @@ GLOBAL_LABEL(dynamorio_mach_syscall:)
/* reverse order so we don't clobber earlier args */
mov REG_XBX, ARG2 /* put num_args where we can reference it longer */
mov rax, ARG1 /* sysnum: only need eax, but need rax to use ARG1 (or movzx) */
or eax, SYSCALL_NUM_MARKER_MACH
cmp REG_XBX, 0
je dynamorio_mach_syscall_ready
mov ARG1, ARG3
Expand All @@ -291,6 +295,8 @@ GLOBAL_LABEL(dynamorio_mach_syscall:)
cmp REG_XBX, 3
je dynamorio_mach_syscall_ready
mov ARG4, ARG6
dynamorio_mach_syscall_ready:
syscall
# else
push REG_XBP
push REG_XSI
Expand All @@ -314,12 +320,8 @@ dynamorio_mach_syscall_1args:
mov ebx, [16+12 + esp] /* arg1 */
dynamorio_mach_syscall_0args:
mov eax, [16+ 4 + esp] /* sysnum */
# ifdef X64
or eax, SYSCALL_NUM_MARKER_MACH
# else
/* The sysnum is passed as a negative number */
neg eax
# endif
/* args are on stack, w/ an extra slot (retaddr of syscall wrapper) */
lea REG_XSP, [-2*ARG_SZ + REG_XSP] /* maintain align-16: retaddr-5th below */
/* args are on stack, w/ an extra slot (retaddr of syscall wrapper) */
Expand All @@ -328,7 +330,6 @@ dynamorio_mach_syscall_0args:
push ecx
push ebx
push 0 /* extra slot */
# endif
/* If we use ADDRTAKEN_LABEL and GLOBAL_REF we get text relocation
* complaints so we instead do this hack:
*/
Expand All @@ -341,7 +342,6 @@ dynamorio_mach_syscall_next:
* This implies that we can't return 64-bit in 32-bit mode.
*/
sysenter
# ifndef X64
lea esp, [7*ARG_SZ + esp] /* must not change flags */
pop REG_XDI
pop REG_XSI
Expand Down
6 changes: 4 additions & 2 deletions core/optionsx.h
Original file line number Diff line number Diff line change
Expand Up @@ -687,7 +687,7 @@ DYNAMIC_OPTION(bool, pause_via_loop,

/* For MacOS, set to 0 to disable the check */
OPTION_DEFAULT(uint, max_supported_os_version,
IF_WINDOWS_ELSE(105, IF_MACOS_ELSE(17, 0)),
IF_WINDOWS_ELSE(105, IF_MACOS_ELSE(18, 0)),
/* case 447, defaults to supporting NT, 2000, XP, 2003, and Vista.
* Windows 7 added with i#218
* Windows 8 added with i#565
Expand Down Expand Up @@ -1430,11 +1430,13 @@ DYNAMIC_OPTION(bool, pause_via_loop,
* new default -vm_size of 0x20000000 we want to stay below our various
* preferred addresses of 0x7xxx0000 so we keep the base plus offset plus
* size below that.
* For a 64-bit process on MacOS __PAGEZERO takes up the first 4GB by default.
* We ignore this for x64 if -vm_base_near_app and the app is far away.
*/
OPTION_DEFAULT(uint_addr, vm_base,
IF_VMX86_ELSE(IF_X64_ELSE(0x40000000,0x10800000),
IF_WINDOWS_ELSE(0x16000000, 0x3f000000)),
IF_WINDOWS_ELSE(0x16000000, IF_MACOS_ELSE(
IF_X64_ELSE(0x120000000,0x3f000000),0x3f000000))),
"preferred base address hint")
/* FIXME: we need to find a good location with no conflict with DLLs or apps allocations */
OPTION_DEFAULT(uint_addr, vm_max_offset,
Expand Down
2 changes: 1 addition & 1 deletion core/unix/memquery.h
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ typedef struct _memquery_iter_t {
* without using static data and limiting to one iterator (and having
* to unprotect and reprotect if in .data).
*/
#define MEMQUERY_INTERNAL_DATA_LEN 96 /* 84 bytes needed for Mac 10.9.1 */
#define MEMQUERY_INTERNAL_DATA_LEN 116 /* 104 bytes needed for MacOS 64-bit */
char internal[MEMQUERY_INTERNAL_DATA_LEN];
} memquery_iter_t;

Expand Down
10 changes: 5 additions & 5 deletions core/unix/module_macho.c
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ module_walk_program_headers(app_pc base, size_t view_size, bool at_map, bool dyn
cmd = (struct load_command *)(hdr + 1);
cmd_stop = (struct load_command *)((byte *)cmd + hdr->sizeofcmds);
while (cmd < cmd_stop) {
if (cmd->cmd == LC_SEGMENT) {
if (cmd->cmd == LC_SEGMENT || cmd->cmd == LC_SEGMENT_64) {
segment_command_t *seg = (segment_command_t *)cmd;
found_seg = true;
LOG(GLOBAL, LOG_VMAREAS, 4, "%s: segment %s addr=0x%x sz=0x%x file=0x%x\n",
Expand Down Expand Up @@ -171,7 +171,7 @@ module_walk_program_headers(app_pc base, size_t view_size, bool at_map, bool dyn
/* Now that we have the load delta, we can add the abs addr segments */
cmd = (struct load_command *)(hdr + 1);
while (cmd < cmd_stop) {
if (cmd->cmd == LC_SEGMENT) {
if (cmd->cmd == LC_SEGMENT || cmd->cmd == LC_SEGMENT_64) {
segment_command_t *seg = (segment_command_t *)cmd;
if (strcmp(seg->segname, "__PAGEZERO") == 0 && seg->initprot == 0) {
/* skip */
Expand Down Expand Up @@ -210,10 +210,10 @@ module_walk_program_headers(app_pc base, size_t view_size, bool at_map, bool dyn
/* even if stripped, dynamic symbols are in this table */
struct symtab_command *symtab = (struct symtab_command *)cmd;
out_data->symtab =
(app_pc)symtab->symoff + load_delta + linkedit_delta;
(app_pc)(symtab->symoff + load_delta + linkedit_delta);
out_data->num_syms = symtab->nsyms;
out_data->strtab =
(app_pc)symtab->stroff + load_delta + linkedit_delta;
(app_pc)(symtab->stroff + load_delta + linkedit_delta);
out_data->strtab_sz = symtab->strsize;
} else if (cmd->cmd == LC_UUID) {
memcpy(out_data->uuid, ((struct uuid_command *)cmd)->uuid,
Expand Down Expand Up @@ -268,7 +268,7 @@ module_entry_point(app_pc base, ptr_int_t load_delta)
#ifdef X64
const x86_thread_state64_t *reg =
(const x86_thread_state64_t *)((char *)cmd + LC_UNIXTHREAD_REGS_OFFS);
return (app_pc)reg->__rip + load_delta
return (app_pc)reg->__rip + load_delta;
#else
const i386_thread_state_t *reg =
(const i386_thread_state_t *)((byte *)cmd + LC_UNIXTHREAD_REGS_OFFS);
Expand Down
12 changes: 7 additions & 5 deletions core/unix/os.c
Original file line number Diff line number Diff line change
Expand Up @@ -2858,10 +2858,12 @@ replace_thread_id(thread_id_t old, thread_id_t new)
ASSERT(is_thread_tls_initialized());
DOCHECK(1, {
thread_id_t old_tid;
READ_TLS_INT_SLOT_IMM(TLS_THREAD_ID_OFFSET, old_tid);
IF_LINUX_ELSE(READ_TLS_INT_SLOT_IMM(TLS_THREAD_ID_OFFSET, old_tid),
READ_TLS_SLOT_IMM(TLS_THREAD_ID_OFFSET, old_tid));
ASSERT(old_tid == old);
});
WRITE_TLS_INT_SLOT_IMM(TLS_THREAD_ID_OFFSET, new_tid);
IF_LINUX_ELSE(WRITE_TLS_INT_SLOT_IMM(TLS_THREAD_ID_OFFSET, new_tid),
WRITE_TLS_SLOT_IMM(TLS_THREAD_ID_OFFSET, new_tid));
#else
int i;
d_r_mutex_lock(&tls_lock);
Expand Down Expand Up @@ -4865,7 +4867,7 @@ syscall_successful(priv_mcontext_t *mc, int normalized_sysnum)
*/
return ((ptr_int_t)MCXT_SYSCALL_RES(mc) >= 0);
} else
return !TEST(EFLAGS_CF, mc->eflags);
return !TEST(EFLAGS_CF, mc->xflags);
#else
if (normalized_sysnum == IF_X64_ELSE(SYS_mmap, SYS_mmap2) ||
# if !defined(ARM) && !defined(X64)
Expand All @@ -4891,7 +4893,7 @@ set_success_return_val(dcontext_t *dcontext, reg_t val)
/* On MacOS, success is determined by CF, except for Mach syscalls, but
* there it doesn't hurt to set CF.
*/
mc->eflags &= ~(EFLAGS_CF);
mc->xflags &= ~(EFLAGS_CF);
#endif
MCXT_SYSCALL_RES(mc) = val;
}
Expand All @@ -4903,7 +4905,7 @@ set_failure_return_val(dcontext_t *dcontext, uint errno_val)
priv_mcontext_t *mc = get_mcontext(dcontext);
#ifdef MACOS
/* On MacOS, success is determined by CF, and errno is positive */
mc->eflags |= EFLAGS_CF;
mc->xflags |= EFLAGS_CF;
MCXT_SYSCALL_RES(mc) = errno_val;
#else
MCXT_SYSCALL_RES(mc) = -(int)errno_val;
Expand Down
1 change: 0 additions & 1 deletion core/unix/os_public.h
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,6 @@ typedef kernel_sigcontext_t sigcontext_t;
# define SC_R13 SC_FIELD(r13)
# define SC_R14 SC_FIELD(r14)
# define SC_R15 SC_FIELD(r15)

# ifdef MACOS
# define SC_XFLAGS SC_FIELD(rflags)
# else
Expand Down
28 changes: 17 additions & 11 deletions core/unix/signal.c
Original file line number Diff line number Diff line change
Expand Up @@ -2603,14 +2603,14 @@ thread_set_self_context(void *cxt)
buf.xsp = sc->SC_XSP - XSP_SZ; /* extra slot for retaddr */
buf.xip = sc->SC_XIP;
# ifdef X64
buf.r8 = sc->r8;
buf.r9 = sc->r9;
buf.r10 = sc->r10;
buf.r11 = sc->r11;
buf.r12 = sc->r12;
buf.r13 = sc->r13;
buf.r14 = sc->r14;
buf.r15 = sc->r15;
buf.r8 = sc->SC_R8;
buf.r9 = sc->SC_R9;
buf.r10 = sc->SC_R10;
buf.r11 = sc->SC_R11;
buf.r12 = sc->SC_R12;
buf.r13 = sc->SC_R13;
buf.r14 = sc->SC_R14;
buf.r15 = sc->SC_R15;
# endif
dr_longjmp(&buf, sc->SC_XAX);
return;
Expand Down Expand Up @@ -3066,15 +3066,17 @@ fixup_rtframe_pointers(dcontext_t *dcontext, int sig, sigframe_rt_t *f_old,
/* 32-bit kernel copies to aligned buf first */
IF_X64(ASSERT(ALIGNED(f_new->uc.uc_mcontext.fpstate, 16)));
#elif defined(MACOS)
# ifndef X64
# ifdef X64
ASSERT_NOT_IMPLEMENTED(false);
# else
f_new->pinfo = &(f_new->info);
f_new->puc = &(f_new->uc);
# endif
f_new->puc->uc_mcontext =
(IF_X64_ELSE(_STRUCT_MCONTEXT64, _STRUCT_MCONTEXT32) *)&f_new->mc;
LOG(THREAD, LOG_ASYNCH, 3, "\tf_new=" PFX ", &handler=" PFX "\n", f_new,
&f_new->handler);
ASSERT(!for_app || ALIGNED(&f_new->handler, 16));
# endif
#endif /* X86 && LINUX */
}

Expand Down Expand Up @@ -3262,9 +3264,13 @@ copy_frame_to_stack(dcontext_t *dcontext, int sig, sigframe_rt_t *frame, byte *s
}

#ifdef MACOS
# ifdef X64
ASSERT_NOT_IMPLEMENTED(false);
# else
/* Update handler field, which is passed to the libc trampoline, to app */
ASSERT(info->app_sigaction[sig] != NULL);
((sigframe_rt_t *)sp)->handler = (app_pc)info->app_sigaction[sig]->handler;
# endif
#endif
}

Expand Down Expand Up @@ -4741,7 +4747,7 @@ is_safe_read_ucxt(kernel_ucontext_t *ucxt)
/* stub in x86.asm passes our xsp to us */
# ifdef MACOS
void
master_signal_handler_C(handler_t handler, int style, int sig, kernel_siginfo_t *info,
master_signal_handler_C(handler_t handler, int style, int sig, kernel_siginfo_t *siginfo,
kernel_ucontext_t *ucxt, byte *xsp)
# else
void
Expand Down
16 changes: 8 additions & 8 deletions core/unix/signal_macos.c
Original file line number Diff line number Diff line change
Expand Up @@ -241,14 +241,14 @@ dump_sigcontext(dcontext_t *dcontext, sigcontext_t *sc)
LOG(THREAD, LOG_ASYNCH, 1, "\txcx=" PFX "\n", sc->SC_XCX);
LOG(THREAD, LOG_ASYNCH, 1, "\txax=" PFX "\n", sc->SC_XAX);
#ifdef X64
LOG(THREAD, LOG_ASYNCH, 1, "\t r8=" PFX "\n", sc->r8);
LOG(THREAD, LOG_ASYNCH, 1, "\t r9=" PFX "\n", sc->r8);
LOG(THREAD, LOG_ASYNCH, 1, "\tr10=" PFX "\n", sc->r10);
LOG(THREAD, LOG_ASYNCH, 1, "\tr11=" PFX "\n", sc->r11);
LOG(THREAD, LOG_ASYNCH, 1, "\tr12=" PFX "\n", sc->r12);
LOG(THREAD, LOG_ASYNCH, 1, "\tr13=" PFX "\n", sc->r13);
LOG(THREAD, LOG_ASYNCH, 1, "\tr14=" PFX "\n", sc->r14);
LOG(THREAD, LOG_ASYNCH, 1, "\tr15=" PFX "\n", sc->r15);
LOG(THREAD, LOG_ASYNCH, 1, "\t r8=" PFX "\n", sc->SC_R8);
LOG(THREAD, LOG_ASYNCH, 1, "\t r9=" PFX "\n", sc->SC_R8);
LOG(THREAD, LOG_ASYNCH, 1, "\tr10=" PFX "\n", sc->SC_R10);
LOG(THREAD, LOG_ASYNCH, 1, "\tr11=" PFX "\n", sc->SC_R11);
LOG(THREAD, LOG_ASYNCH, 1, "\tr12=" PFX "\n", sc->SC_R12);
LOG(THREAD, LOG_ASYNCH, 1, "\tr13=" PFX "\n", sc->SC_R13);
LOG(THREAD, LOG_ASYNCH, 1, "\tr14=" PFX "\n", sc->SC_R14);
LOG(THREAD, LOG_ASYNCH, 1, "\tr15=" PFX "\n", sc->SC_R15);
#endif

LOG(THREAD, LOG_ASYNCH, 1, "\txip=" PFX "\n", sc->SC_XIP);
Expand Down
5 changes: 4 additions & 1 deletion core/unix/signal_private.h
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,9 @@
#elif defined(MACOS)
# include "../globals.h" /* this defines _XOPEN_SOURCE for Mac */
# include <signal.h> /* after globals.h, for _XOPEN_SOURCE from os_exports.h */
# ifdef X64
# include <sys/_types/_ucontext64.h> /* for _STRUCT_UCONTEXT64 */
# endif
#endif

#include "os_private.h"
Expand Down Expand Up @@ -187,7 +190,7 @@ typedef _STRUCT_UCONTEXT /* == __darwin_ucontext */ kernel_ucontext_t;
# define SIGMASK_FROM_UCXT(ucxt) ((kernel_sigset_t *)&((ucxt)->uc_sigmask))
#endif

#ifdef LINUX
#if defined(LINUX) || defined(X64)
# define SIGINFO_FROM_RT_FRAME(frame) (&(frame)->info)
#elif defined(MACOS)
/* Make sure to access through pinfo rather than info as on Mac the info
Expand Down
Loading

0 comments on commit 229ff65

Please sign in to comment.