Module: wine Branch: master Commit: 97bda9a05f50018d551776e0801c6604bde3f329 URL: http://source.winehq.org/git/wine.git/?a=commit;h=97bda9a05f50018d551776e080... Author: Charles Davis <cdavis5x(a)gmail.com> Date: Thu Feb 5 13:28:58 2015 -0700 ntdll: Support 64-bit Mac OS. --- dlls/ntdll/ntdll.spec | 2 +- dlls/ntdll/signal_x86_64.c | 62 ++++++++++++++++++++++++++++++++++++++++++++++ dlls/ntdll/thread.c | 20 ++++++++++++--- include/winnt.h | 2 +- 4 files changed, 81 insertions(+), 5 deletions(-) diff --git a/dlls/ntdll/ntdll.spec b/dlls/ntdll/ntdll.spec index 51de6e7..9355d04 100644 --- a/dlls/ntdll/ntdll.spec +++ b/dlls/ntdll/ntdll.spec @@ -146,7 +146,7 @@ @ stdcall NtCreateTimer(ptr long ptr long) @ stub NtCreateToken # @ stub NtCreateWaitablePort -@ stdcall -arch=win32,arm64 NtCurrentTeb() +@ stdcall NtCurrentTeb() # @ stub NtDebugActiveProcess # @ stub NtDebugContinue @ stdcall NtDelayExecution(long ptr) diff --git a/dlls/ntdll/signal_x86_64.c b/dlls/ntdll/signal_x86_64.c index 05581c2..c71069d 100644 --- a/dlls/ntdll/signal_x86_64.c +++ b/dlls/ntdll/signal_x86_64.c @@ -236,6 +236,39 @@ static inline int arch_prctl( int func, void *ptr ) { return syscall( __NR_arch_ #define ERROR_sig(context) ((context)->uc_mcontext.__gregs[_REG_ERR]) #define FPU_sig(context) ((XMM_SAVE_AREA32 *)((context)->uc_mcontext.__fpregs)) +#elif defined (__APPLE__) +static pthread_key_t teb_key; + +#define RAX_sig(context) ((context)->uc_mcontext->__ss.__rax) +#define RBX_sig(context) ((context)->uc_mcontext->__ss.__rbx) +#define RCX_sig(context) ((context)->uc_mcontext->__ss.__rcx) +#define RDX_sig(context) ((context)->uc_mcontext->__ss.__rdx) +#define RSI_sig(context) ((context)->uc_mcontext->__ss.__rsi) +#define RDI_sig(context) ((context)->uc_mcontext->__ss.__rdi) +#define RBP_sig(context) ((context)->uc_mcontext->__ss.__rbp) +#define R8_sig(context) ((context)->uc_mcontext->__ss.__r8) +#define R9_sig(context) ((context)->uc_mcontext->__ss.__r9) +#define R10_sig(context) ((context)->uc_mcontext->__ss.__r10) +#define R11_sig(context) ((context)->uc_mcontext->__ss.__r11) +#define R12_sig(context) ((context)->uc_mcontext->__ss.__r12) +#define R13_sig(context) ((context)->uc_mcontext->__ss.__r13) +#define R14_sig(context) ((context)->uc_mcontext->__ss.__r14) +#define R15_sig(context) ((context)->uc_mcontext->__ss.__r15) + +#define CS_sig(context) ((context)->uc_mcontext->__ss.__cs) +#define FS_sig(context) ((context)->uc_mcontext->__ss.__fs) +#define GS_sig(context) ((context)->uc_mcontext->__ss.__gs) + +#define EFL_sig(context) ((context)->uc_mcontext->__ss.__rflags) + +#define RIP_sig(context) (*((unsigned long*)&(context)->uc_mcontext->__ss.__rip)) +#define RSP_sig(context) (*((unsigned long*)&(context)->uc_mcontext->__ss.__rsp)) + +#define TRAP_sig(context) ((context)->uc_mcontext->__es.__trapno) +#define ERROR_sig(context) ((context)->uc_mcontext->__es.__err) + +#define FPU_sig(context) ((XMM_SAVE_AREA32 *)&(context)->uc_mcontext->__fs.__fpu_fcw) + #else #error You must define the signal context functions for your platform #endif @@ -2506,6 +2539,12 @@ void signal_free_thread( TEB *teb ) NtFreeVirtualMemory( NtCurrentProcess(), (void **)&teb, &size, MEM_RELEASE ); } +#ifdef __APPLE__ +static void init_teb_key(void) +{ + pthread_key_create( &teb_key, NULL ); +} +#endif /********************************************************************** * signal_init_thread @@ -2515,12 +2554,20 @@ void signal_init_thread( TEB *teb ) const WORD fpu_cw = 0x27f; stack_t ss; +#ifdef __APPLE__ + static pthread_once_t init_once = PTHREAD_ONCE_INIT; +#endif + #if defined __linux__ arch_prctl( ARCH_SET_GS, teb ); #elif defined (__FreeBSD__) || defined (__FreeBSD_kernel__) amd64_set_gsbase( teb ); #elif defined(__NetBSD__) sysarch( X86_64_SET_GSBASE, &teb ); +#elif defined (__APPLE__) + /* FIXME: Actually setting %gs needs support from the OS */ + pthread_once( &init_once, init_teb_key ); + pthread_setspecific( teb_key, teb ); #else # error Please define setting %gs for your architecture #endif @@ -3425,4 +3472,19 @@ __ASM_STDCALL_FUNC( DbgBreakPoint, 0, "int $3; ret") */ __ASM_STDCALL_FUNC( DbgUserBreakPoint, 0, "int $3; ret") +/********************************************************************** + * NtCurrentTeb (NTDLL.@) + * + * FIXME: This isn't exported from NTDLL on real NT. This should be + * removed if and when we can set the GSBASE MSR on Mac OS X. + */ +#ifdef __APPLE__ +TEB * WINAPI NtCurrentTeb(void) +{ + return pthread_getspecific( teb_key ); +} +#else +__ASM_STDCALL_FUNC( NtCurrentTeb, 0, ".byte 0x65\n\tmovq 0x30,%rax\n\tret" ) +#endif + #endif /* __x86_64__ */ diff --git a/dlls/ntdll/thread.c b/dlls/ntdll/thread.c index 7dd13f2..3696c8e 100644 --- a/dlls/ntdll/thread.c +++ b/dlls/ntdll/thread.c @@ -189,9 +189,9 @@ done: #include <mach/mach.h> #include <mach/mach_error.h> -static ULONG get_dyld_image_info_addr(void) +static ULONG64 get_dyld_image_info_addr(void) { - ULONG ret = 0; + ULONG64 ret = 0; #ifdef TASK_DYLD_INFO struct task_dyld_info dyld_info; mach_msg_type_number_t size = TASK_DYLD_INFO_COUNT; @@ -219,6 +219,9 @@ HANDLE thread_init(void) NTSTATUS status; struct ntdll_thread_data *thread_data; static struct debug_info debug_info; /* debug info for initial thread */ +#ifdef __APPLE__ + ULONG64 dyld_image_info; +#endif virtual_init(); @@ -263,7 +266,18 @@ HANDLE thread_init(void) InitializeListHead( &ldr.InMemoryOrderModuleList ); InitializeListHead( &ldr.InInitializationOrderModuleList ); #ifdef __APPLE__ - peb->Reserved[0] = get_dyld_image_info_addr(); + dyld_image_info = get_dyld_image_info_addr(); +#ifdef __LP64__ +#ifdef WORDS_BIGENDIAN + peb->Reserved[1] = dyld_image_info & 0xFFFFFFFF; + peb->Reserved[0] = dyld_image_info >> 32; +#else + peb->Reserved[0] = dyld_image_info & 0xFFFFFFFF; + peb->Reserved[1] = dyld_image_info >> 32; +#endif +#else + peb->Reserved[0] = dyld_image_info & 0xFFFFFFFF; +#endif #endif /* allocate and initialize the initial TEB */ diff --git a/include/winnt.h b/include/winnt.h index 709a93f..4b06b2c 100644 --- a/include/winnt.h +++ b/include/winnt.h @@ -2284,7 +2284,7 @@ static FORCEINLINE struct _TEB * WINAPI NtCurrentTeb(void) __asm mov teb, eax; return teb; } -#elif defined(__x86_64__) && defined(__GNUC__) +#elif defined(__x86_64__) && defined(__GNUC__) && !defined(__APPLE__) static FORCEINLINE struct _TEB * WINAPI NtCurrentTeb(void) { struct _TEB *teb;