167 lines
4.1 KiB
C
167 lines
4.1 KiB
C
|
/*
|
||
|
* ARM64 signal handling routines
|
||
|
*
|
||
|
* Copyright 2010-2013 André Hentschel
|
||
|
*
|
||
|
* This library is free software; you can redistribute it and/or
|
||
|
* modify it under the terms of the GNU Lesser General Public
|
||
|
* License as published by the Free Software Foundation; either
|
||
|
* version 2.1 of the License, or (at your option) any later version.
|
||
|
*
|
||
|
* This library is distributed in the hope that it will be useful,
|
||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||
|
* Lesser General Public License for more details.
|
||
|
*
|
||
|
* You should have received a copy of the GNU Lesser General Public
|
||
|
* License along with this library; if not, write to the Free Software
|
||
|
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
||
|
*/
|
||
|
|
||
|
#if 0
|
||
|
#pragma makedep unix
|
||
|
#endif
|
||
|
|
||
|
#ifdef __aarch64__
|
||
|
|
||
|
#include "config.h"
|
||
|
#include "wine/port.h"
|
||
|
|
||
|
#include <assert.h>
|
||
|
#include <pthread.h>
|
||
|
#include <signal.h>
|
||
|
#include <stdlib.h>
|
||
|
#include <stdarg.h>
|
||
|
#include <stdio.h>
|
||
|
#ifdef HAVE_UNISTD_H
|
||
|
# include <unistd.h>
|
||
|
#endif
|
||
|
#ifdef HAVE_SYS_PARAM_H
|
||
|
# include <sys/param.h>
|
||
|
#endif
|
||
|
#ifdef HAVE_SYSCALL_H
|
||
|
# include <syscall.h>
|
||
|
#else
|
||
|
# ifdef HAVE_SYS_SYSCALL_H
|
||
|
# include <sys/syscall.h>
|
||
|
# endif
|
||
|
#endif
|
||
|
#ifdef HAVE_SYS_SIGNAL_H
|
||
|
# include <sys/signal.h>
|
||
|
#endif
|
||
|
#ifdef HAVE_SYS_UCONTEXT_H
|
||
|
# include <sys/ucontext.h>
|
||
|
#endif
|
||
|
#ifdef HAVE_LIBUNWIND
|
||
|
# define UNW_LOCAL_ONLY
|
||
|
# include <libunwind.h>
|
||
|
#endif
|
||
|
|
||
|
#define NONAMELESSUNION
|
||
|
#define NONAMELESSSTRUCT
|
||
|
#include "ntstatus.h"
|
||
|
#define WIN32_NO_STATUS
|
||
|
#include "windef.h"
|
||
|
#include "winnt.h"
|
||
|
#include "winternl.h"
|
||
|
#include "wine/exception.h"
|
||
|
#include "wine/asm.h"
|
||
|
#include "unix_private.h"
|
||
|
#include "wine/debug.h"
|
||
|
|
||
|
static pthread_key_t teb_key;
|
||
|
|
||
|
static const size_t teb_size = 0x2000; /* we reserve two pages for the TEB */
|
||
|
|
||
|
|
||
|
/**********************************************************************
|
||
|
* get_thread_ldt_entry
|
||
|
*/
|
||
|
NTSTATUS CDECL get_thread_ldt_entry( HANDLE handle, void *data, ULONG len, ULONG *ret_len )
|
||
|
{
|
||
|
return STATUS_NOT_IMPLEMENTED;
|
||
|
}
|
||
|
|
||
|
|
||
|
/******************************************************************************
|
||
|
* NtSetLdtEntries (NTDLL.@)
|
||
|
* ZwSetLdtEntries (NTDLL.@)
|
||
|
*/
|
||
|
NTSTATUS WINAPI NtSetLdtEntries( ULONG sel1, LDT_ENTRY entry1, ULONG sel2, LDT_ENTRY entry2 )
|
||
|
{
|
||
|
return STATUS_NOT_IMPLEMENTED;
|
||
|
}
|
||
|
|
||
|
|
||
|
/**********************************************************************
|
||
|
* signal_init_threading
|
||
|
*/
|
||
|
void signal_init_threading(void)
|
||
|
{
|
||
|
pthread_key_create( &teb_key, NULL );
|
||
|
}
|
||
|
|
||
|
|
||
|
/**********************************************************************
|
||
|
* signal_alloc_thread
|
||
|
*/
|
||
|
NTSTATUS signal_alloc_thread( TEB *teb )
|
||
|
{
|
||
|
return STATUS_SUCCESS;
|
||
|
}
|
||
|
|
||
|
|
||
|
/**********************************************************************
|
||
|
* signal_free_thread
|
||
|
*/
|
||
|
void signal_free_thread( TEB *teb )
|
||
|
{
|
||
|
}
|
||
|
|
||
|
|
||
|
/**********************************************************************
|
||
|
* signal_init_thread
|
||
|
*/
|
||
|
void signal_init_thread( TEB *teb )
|
||
|
{
|
||
|
stack_t ss;
|
||
|
|
||
|
ss.ss_sp = (char *)teb + teb_size;
|
||
|
ss.ss_size = signal_stack_size;
|
||
|
ss.ss_flags = 0;
|
||
|
if (sigaltstack( &ss, NULL ) == -1) perror( "sigaltstack" );
|
||
|
|
||
|
/* Win64/ARM applications expect the TEB pointer to be in the x18 platform register. */
|
||
|
__asm__ __volatile__( "mov x18, %0" : : "r" (teb) );
|
||
|
|
||
|
pthread_setspecific( teb_key, teb );
|
||
|
}
|
||
|
|
||
|
|
||
|
extern void DECLSPEC_NORETURN call_thread_exit_func( int status, void (*func)(int), TEB *teb );
|
||
|
__ASM_GLOBAL_FUNC( call_thread_exit_func,
|
||
|
"ldr x3, [x2, #0x300]\n\t" /* arm64_thread_data()->exit_frame */
|
||
|
"str xzr, [x2, #0x300]\n\t"
|
||
|
"cbz x3, 1f\n\t"
|
||
|
"mov sp, x3\n"
|
||
|
"1:\tblr x1" )
|
||
|
|
||
|
/***********************************************************************
|
||
|
* signal_exit_thread
|
||
|
*/
|
||
|
void signal_exit_thread( int status, void (*func)(int) )
|
||
|
{
|
||
|
call_thread_exit_func( status, func, NtCurrentTeb() );
|
||
|
}
|
||
|
|
||
|
|
||
|
/**********************************************************************
|
||
|
* NtCurrentTeb (NTDLL.@)
|
||
|
*/
|
||
|
TEB * WINAPI NtCurrentTeb(void)
|
||
|
{
|
||
|
return pthread_getspecific( teb_key );
|
||
|
}
|
||
|
|
||
|
#endif /* __aarch64__ */
|