ntdll: Implement __C_specific_handler and __jump_unwind for arm.
Signed-off-by: Martin Storsjö <martin@martin.st> Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
bdb3608811
commit
3ef9a04f91
|
@ -14,7 +14,7 @@
|
||||||
@ cdecl __AdjustPointer(ptr ptr) ucrtbase.__AdjustPointer
|
@ cdecl __AdjustPointer(ptr ptr) ucrtbase.__AdjustPointer
|
||||||
@ stub __BuildCatchObject
|
@ stub __BuildCatchObject
|
||||||
@ stub __BuildCatchObjectHelper
|
@ stub __BuildCatchObjectHelper
|
||||||
@ stdcall -arch=x86_64,arm64 __C_specific_handler(ptr long ptr ptr) ucrtbase.__C_specific_handler
|
@ stdcall -arch=x86_64,arm,arm64 __C_specific_handler(ptr long ptr ptr) ucrtbase.__C_specific_handler
|
||||||
@ stub __C_specific_handler_noexcept
|
@ stub __C_specific_handler_noexcept
|
||||||
@ cdecl -arch=i386,x86_64,arm,arm64 __CxxDetectRethrow(ptr) ucrtbase.__CxxDetectRethrow
|
@ cdecl -arch=i386,x86_64,arm,arm64 __CxxDetectRethrow(ptr) ucrtbase.__CxxDetectRethrow
|
||||||
@ cdecl -arch=i386,x86_64,arm,arm64 __CxxExceptionFilter(ptr ptr long ptr) ucrtbase.__CxxExceptionFilter
|
@ cdecl -arch=i386,x86_64,arm,arm64 __CxxExceptionFilter(ptr ptr long ptr) ucrtbase.__CxxExceptionFilter
|
||||||
|
@ -41,6 +41,7 @@
|
||||||
@ cdecl __intrinsic_abnormal_termination() ucrtbase.__intrinsic_abnormal_termination
|
@ cdecl __intrinsic_abnormal_termination() ucrtbase.__intrinsic_abnormal_termination
|
||||||
@ cdecl -arch=i386,x86_64,arm,arm64 -norelay __intrinsic_setjmp(ptr) ucrtbase.__intrinsic_setjmp
|
@ cdecl -arch=i386,x86_64,arm,arm64 -norelay __intrinsic_setjmp(ptr) ucrtbase.__intrinsic_setjmp
|
||||||
@ cdecl -arch=x86_64,arm64 -norelay __intrinsic_setjmpex(ptr ptr) ucrtbase.__intrinsic_setjmpex
|
@ cdecl -arch=x86_64,arm64 -norelay __intrinsic_setjmpex(ptr ptr) ucrtbase.__intrinsic_setjmpex
|
||||||
|
@ stdcall -arch=arm __jump_unwind(ptr ptr) ucrtbase.__jump_unwind
|
||||||
@ cdecl __processing_throw() ucrtbase.__processing_throw
|
@ cdecl __processing_throw() ucrtbase.__processing_throw
|
||||||
@ stub __report_gsfailure
|
@ stub __report_gsfailure
|
||||||
@ cdecl __std_exception_copy(ptr ptr) ucrtbase.__std_exception_copy
|
@ cdecl __std_exception_copy(ptr ptr) ucrtbase.__std_exception_copy
|
||||||
|
|
|
@ -1464,11 +1464,12 @@
|
||||||
@ cdecl -private -arch=i386 _CIpow()
|
@ cdecl -private -arch=i386 _CIpow()
|
||||||
@ cdecl -private -arch=i386 _CIsin()
|
@ cdecl -private -arch=i386 _CIsin()
|
||||||
@ cdecl -private -arch=i386 _CIsqrt()
|
@ cdecl -private -arch=i386 _CIsqrt()
|
||||||
@ stdcall -arch=x86_64,arm64 __C_specific_handler(ptr long ptr ptr)
|
@ stdcall -arch=x86_64,arm,arm64 __C_specific_handler(ptr long ptr ptr)
|
||||||
@ cdecl -arch=arm,arm64,x86_64 -norelay __chkstk()
|
@ cdecl -arch=arm,arm64,x86_64 -norelay __chkstk()
|
||||||
@ cdecl __isascii(long)
|
@ cdecl __isascii(long)
|
||||||
@ cdecl __iscsym(long)
|
@ cdecl __iscsym(long)
|
||||||
@ cdecl __iscsymf(long)
|
@ cdecl __iscsymf(long)
|
||||||
|
@ stdcall -arch=arm __jump_unwind(ptr ptr)
|
||||||
@ cdecl __toascii(long)
|
@ cdecl __toascii(long)
|
||||||
@ cdecl -norelay -arch=i386 -ret64 _alldiv(int64 int64)
|
@ cdecl -norelay -arch=i386 -ret64 _alldiv(int64 int64)
|
||||||
@ cdecl -arch=i386 -norelay _alldvrm(int64 int64)
|
@ cdecl -arch=i386 -norelay _alldvrm(int64 int64)
|
||||||
|
|
|
@ -37,6 +37,18 @@
|
||||||
|
|
||||||
WINE_DEFAULT_DEBUG_CHANNEL(seh);
|
WINE_DEFAULT_DEBUG_CHANNEL(seh);
|
||||||
|
|
||||||
|
typedef struct _SCOPE_TABLE
|
||||||
|
{
|
||||||
|
ULONG Count;
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
ULONG BeginAddress;
|
||||||
|
ULONG EndAddress;
|
||||||
|
ULONG HandlerAddress;
|
||||||
|
ULONG JumpTarget;
|
||||||
|
} ScopeRecord[1];
|
||||||
|
} SCOPE_TABLE, *PSCOPE_TABLE;
|
||||||
|
|
||||||
|
|
||||||
/* layering violation: the setjmp buffer is defined in msvcrt, but used by RtlUnwindEx */
|
/* layering violation: the setjmp buffer is defined in msvcrt, but used by RtlUnwindEx */
|
||||||
struct MSVCRT_JUMP_BUFFER
|
struct MSVCRT_JUMP_BUFFER
|
||||||
|
@ -56,6 +68,20 @@ struct MSVCRT_JUMP_BUFFER
|
||||||
unsigned long long D[8];
|
unsigned long long D[8];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
static void dump_scope_table( ULONG64 base, const SCOPE_TABLE *table )
|
||||||
|
{
|
||||||
|
unsigned int i;
|
||||||
|
|
||||||
|
TRACE( "scope table at %p\n", table );
|
||||||
|
for (i = 0; i < table->Count; i++)
|
||||||
|
TRACE( " %u: %lx-%lx handler %lx target %lx\n", i,
|
||||||
|
base + table->ScopeRecord[i].BeginAddress,
|
||||||
|
base + table->ScopeRecord[i].EndAddress,
|
||||||
|
base + table->ScopeRecord[i].HandlerAddress,
|
||||||
|
base + table->ScopeRecord[i].JumpTarget );
|
||||||
|
}
|
||||||
|
|
||||||
/*******************************************************************
|
/*******************************************************************
|
||||||
* is_valid_frame
|
* is_valid_frame
|
||||||
*/
|
*/
|
||||||
|
@ -1260,6 +1286,125 @@ void WINAPI RtlUnwind( void *frame, void *target_ip, EXCEPTION_RECORD *rec, void
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************
|
||||||
|
* __jump_unwind (NTDLL.@)
|
||||||
|
*/
|
||||||
|
void WINAPI __jump_unwind( void *frame, void *target_ip )
|
||||||
|
{
|
||||||
|
CONTEXT context;
|
||||||
|
RtlUnwindEx( frame, target_ip, NULL, NULL, &context, NULL );
|
||||||
|
}
|
||||||
|
|
||||||
|
extern LONG __C_ExecuteExceptionFilter(PEXCEPTION_POINTERS ptrs, PVOID frame,
|
||||||
|
PEXCEPTION_FILTER filter,
|
||||||
|
PUCHAR nonvolatile);
|
||||||
|
__ASM_GLOBAL_FUNC( __C_ExecuteExceptionFilter,
|
||||||
|
"push {r4-r11,lr}\n\t"
|
||||||
|
|
||||||
|
__ASM_CFI(".cfi_def_cfa 13, 36\n\t")
|
||||||
|
__ASM_CFI(".cfi_offset r4, -36\n\t")
|
||||||
|
__ASM_CFI(".cfi_offset r5, -32\n\t")
|
||||||
|
__ASM_CFI(".cfi_offset r6, -28\n\t")
|
||||||
|
__ASM_CFI(".cfi_offset r7, -24\n\t")
|
||||||
|
__ASM_CFI(".cfi_offset r8, -20\n\t")
|
||||||
|
__ASM_CFI(".cfi_offset r9, -16\n\t")
|
||||||
|
__ASM_CFI(".cfi_offset r10, -12\n\t")
|
||||||
|
__ASM_CFI(".cfi_offset r11, -8\n\t")
|
||||||
|
__ASM_CFI(".cfi_offset lr, -4\n\t")
|
||||||
|
|
||||||
|
"ldm r3, {r4-r11,lr}\n\t"
|
||||||
|
"blx r2\n\t"
|
||||||
|
"pop {r4-r11,pc}\n\t" )
|
||||||
|
|
||||||
|
extern void __C_ExecuteTerminationHandler(BOOL abnormal, PVOID frame,
|
||||||
|
PTERMINATION_HANDLER handler,
|
||||||
|
PUCHAR nonvolatile);
|
||||||
|
/* This is, implementation wise, identical to __C_ExecuteExceptionFilter. */
|
||||||
|
__ASM_GLOBAL_FUNC( __C_ExecuteTerminationHandler,
|
||||||
|
"b " __ASM_NAME("__C_ExecuteExceptionFilter") "\n\t");
|
||||||
|
|
||||||
|
/*******************************************************************
|
||||||
|
* __C_specific_handler (NTDLL.@)
|
||||||
|
*/
|
||||||
|
EXCEPTION_DISPOSITION WINAPI __C_specific_handler( EXCEPTION_RECORD *rec,
|
||||||
|
void *frame,
|
||||||
|
CONTEXT *context,
|
||||||
|
struct _DISPATCHER_CONTEXT *dispatch )
|
||||||
|
{
|
||||||
|
SCOPE_TABLE *table = dispatch->HandlerData;
|
||||||
|
ULONG i;
|
||||||
|
DWORD64 ControlPc = dispatch->ControlPc;
|
||||||
|
|
||||||
|
TRACE( "%p %p %p %p\n", rec, frame, context, dispatch );
|
||||||
|
if (TRACE_ON(seh)) dump_scope_table( dispatch->ImageBase, table );
|
||||||
|
|
||||||
|
if (dispatch->ControlPcIsUnwound)
|
||||||
|
ControlPc -= 2;
|
||||||
|
|
||||||
|
if (rec->ExceptionFlags & (EH_UNWINDING | EH_EXIT_UNWIND))
|
||||||
|
{
|
||||||
|
for (i = dispatch->ScopeIndex; i < table->Count; i++)
|
||||||
|
{
|
||||||
|
if (ControlPc >= dispatch->ImageBase + table->ScopeRecord[i].BeginAddress &&
|
||||||
|
ControlPc < dispatch->ImageBase + table->ScopeRecord[i].EndAddress)
|
||||||
|
{
|
||||||
|
PTERMINATION_HANDLER handler;
|
||||||
|
|
||||||
|
if (table->ScopeRecord[i].JumpTarget) continue;
|
||||||
|
|
||||||
|
if (rec->ExceptionFlags & EH_TARGET_UNWIND &&
|
||||||
|
dispatch->TargetPc >= dispatch->ImageBase + table->ScopeRecord[i].BeginAddress &&
|
||||||
|
dispatch->TargetPc < dispatch->ImageBase + table->ScopeRecord[i].EndAddress)
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
handler = (PTERMINATION_HANDLER)(dispatch->ImageBase + table->ScopeRecord[i].HandlerAddress);
|
||||||
|
dispatch->ScopeIndex = i+1;
|
||||||
|
|
||||||
|
TRACE( "calling __finally %p frame %p\n", handler, frame );
|
||||||
|
__C_ExecuteTerminationHandler( TRUE, frame, handler,
|
||||||
|
dispatch->NonVolatileRegisters );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ExceptionContinueSearch;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = dispatch->ScopeIndex; i < table->Count; i++)
|
||||||
|
{
|
||||||
|
if (ControlPc >= dispatch->ImageBase + table->ScopeRecord[i].BeginAddress &&
|
||||||
|
ControlPc < dispatch->ImageBase + table->ScopeRecord[i].EndAddress)
|
||||||
|
{
|
||||||
|
if (!table->ScopeRecord[i].JumpTarget) continue;
|
||||||
|
if (table->ScopeRecord[i].HandlerAddress != EXCEPTION_EXECUTE_HANDLER)
|
||||||
|
{
|
||||||
|
EXCEPTION_POINTERS ptrs;
|
||||||
|
PEXCEPTION_FILTER filter;
|
||||||
|
|
||||||
|
filter = (PEXCEPTION_FILTER)(dispatch->ImageBase + table->ScopeRecord[i].HandlerAddress);
|
||||||
|
ptrs.ExceptionRecord = rec;
|
||||||
|
ptrs.ContextRecord = context;
|
||||||
|
TRACE( "calling filter %p ptrs %p frame %p\n", filter, &ptrs, frame );
|
||||||
|
switch (__C_ExecuteExceptionFilter( &ptrs, frame, filter,
|
||||||
|
dispatch->NonVolatileRegisters ))
|
||||||
|
{
|
||||||
|
case EXCEPTION_EXECUTE_HANDLER:
|
||||||
|
break;
|
||||||
|
case EXCEPTION_CONTINUE_SEARCH:
|
||||||
|
continue;
|
||||||
|
case EXCEPTION_CONTINUE_EXECUTION:
|
||||||
|
return ExceptionContinueExecution;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
TRACE( "unwinding to target %lx\n", dispatch->ImageBase + table->ScopeRecord[i].JumpTarget );
|
||||||
|
RtlUnwindEx( frame, (char *)dispatch->ImageBase + table->ScopeRecord[i].JumpTarget,
|
||||||
|
rec, 0, dispatch->ContextRecord, dispatch->HistoryTable );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ExceptionContinueSearch;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/***********************************************************************
|
/***********************************************************************
|
||||||
* RtlRaiseException (NTDLL.@)
|
* RtlRaiseException (NTDLL.@)
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -48,7 +48,7 @@
|
||||||
@ cdecl __AdjustPointer(ptr ptr)
|
@ cdecl __AdjustPointer(ptr ptr)
|
||||||
@ stub __BuildCatchObject
|
@ stub __BuildCatchObject
|
||||||
@ stub __BuildCatchObjectHelper
|
@ stub __BuildCatchObjectHelper
|
||||||
@ stdcall -arch=x86_64,arm64 __C_specific_handler(ptr long ptr ptr) ntdll.__C_specific_handler
|
@ stdcall -arch=x86_64,arm,arm64 __C_specific_handler(ptr long ptr ptr) ntdll.__C_specific_handler
|
||||||
@ cdecl -arch=i386,x86_64,arm,arm64 __CxxDetectRethrow(ptr)
|
@ cdecl -arch=i386,x86_64,arm,arm64 __CxxDetectRethrow(ptr)
|
||||||
@ cdecl -arch=i386,x86_64,arm,arm64 __CxxExceptionFilter(ptr ptr long ptr)
|
@ cdecl -arch=i386,x86_64,arm,arm64 __CxxExceptionFilter(ptr ptr long ptr)
|
||||||
@ cdecl -arch=i386,x86_64,arm,arm64 -norelay __CxxFrameHandler(ptr ptr ptr ptr)
|
@ cdecl -arch=i386,x86_64,arm,arm64 -norelay __CxxFrameHandler(ptr ptr ptr ptr)
|
||||||
|
@ -100,6 +100,7 @@
|
||||||
@ cdecl __iscsymf(long)
|
@ cdecl __iscsymf(long)
|
||||||
@ stub __iswcsym
|
@ stub __iswcsym
|
||||||
@ stub __iswcsymf
|
@ stub __iswcsymf
|
||||||
|
@ stdcall -arch=arm __jump_unwind(ptr ptr) ntdll.__jump_unwind
|
||||||
@ cdecl -arch=i386 -norelay __libm_sse2_acos()
|
@ cdecl -arch=i386 -norelay __libm_sse2_acos()
|
||||||
@ cdecl -arch=i386 -norelay __libm_sse2_acosf()
|
@ cdecl -arch=i386 -norelay __libm_sse2_acosf()
|
||||||
@ cdecl -arch=i386 -norelay __libm_sse2_asin()
|
@ cdecl -arch=i386 -norelay __libm_sse2_asin()
|
||||||
|
|
|
@ -10,7 +10,7 @@
|
||||||
@ cdecl __AdjustPointer(ptr ptr) ucrtbase.__AdjustPointer
|
@ cdecl __AdjustPointer(ptr ptr) ucrtbase.__AdjustPointer
|
||||||
@ stub __BuildCatchObject
|
@ stub __BuildCatchObject
|
||||||
@ stub __BuildCatchObjectHelper
|
@ stub __BuildCatchObjectHelper
|
||||||
@ stdcall -arch=x86_64,arm64 __C_specific_handler(ptr long ptr ptr) ucrtbase.__C_specific_handler
|
@ stdcall -arch=x86_64,arm,arm64 __C_specific_handler(ptr long ptr ptr) ucrtbase.__C_specific_handler
|
||||||
@ stub __C_specific_handler_noexcept
|
@ stub __C_specific_handler_noexcept
|
||||||
@ cdecl -arch=i386,x86_64,arm,arm64 __CxxDetectRethrow(ptr) ucrtbase.__CxxDetectRethrow
|
@ cdecl -arch=i386,x86_64,arm,arm64 __CxxDetectRethrow(ptr) ucrtbase.__CxxDetectRethrow
|
||||||
@ cdecl -arch=i386,x86_64,arm,arm64 __CxxExceptionFilter(ptr ptr long ptr) ucrtbase.__CxxExceptionFilter
|
@ cdecl -arch=i386,x86_64,arm,arm64 __CxxExceptionFilter(ptr ptr long ptr) ucrtbase.__CxxExceptionFilter
|
||||||
|
@ -34,6 +34,7 @@
|
||||||
@ cdecl __current_exception_context() ucrtbase.__current_exception_context
|
@ cdecl __current_exception_context() ucrtbase.__current_exception_context
|
||||||
@ cdecl -arch=i386,x86_64,arm,arm64 -norelay __intrinsic_setjmp(ptr) ucrtbase.__intrinsic_setjmp
|
@ cdecl -arch=i386,x86_64,arm,arm64 -norelay __intrinsic_setjmp(ptr) ucrtbase.__intrinsic_setjmp
|
||||||
@ cdecl -arch=x86_64,arm64 -norelay __intrinsic_setjmpex(ptr ptr) ucrtbase.__intrinsic_setjmpex
|
@ cdecl -arch=x86_64,arm64 -norelay __intrinsic_setjmpex(ptr ptr) ucrtbase.__intrinsic_setjmpex
|
||||||
|
@ stdcall -arch=arm __jump_unwind(ptr ptr) ucrtbase.__jump_unwind
|
||||||
@ cdecl __processing_throw() ucrtbase.__processing_throw
|
@ cdecl __processing_throw() ucrtbase.__processing_throw
|
||||||
@ stub __report_gsfailure
|
@ stub __report_gsfailure
|
||||||
@ cdecl __std_exception_copy(ptr ptr) ucrtbase.__std_exception_copy
|
@ cdecl __std_exception_copy(ptr ptr) ucrtbase.__std_exception_copy
|
||||||
|
|
Loading…
Reference in New Issue