Skip to content

Commit 4054e78

Browse files
igorpodgainoi-armgithub-cygwin
authored andcommitted
Cygwin: SEH: Fix crash and handle second unwind phase on AArch64
This patch adds the SEH_CODE macro (defined in cygtls.h) and refactors the TRY_HANDLER_DATA metadata, fixing code styling and allowing it to be used on both AArch64 and x86_64 architectures. It also makes modifications to the exception handler responsible for the __try and __except blocks. The first change to the handler fixes a bug where the existing exception context record is reused as an unwind context record, which fails with a crash on Windows on Arm (AArch64). The fix is to create a new record instead, while leaving the original one intact. The second change adds an additional condition for cases when the handler is called again in the second phase of unwinding on certain platforms such as Windows on Arm (AArch64). In this case, the value ExceptionContinueSearch is simply returned without making any changes. Tests fixed on AArch64: winsup.api/ltp/access03.exe winsup.api/ltp/access05.exe winsup.api/ltp/chdir04.exe winsup.api/ltp/mkdir01.exe winsup.api/ltp/rename08.exe winsup.api/ltp/rmdir05.exe winsup.api/ltp/stat03.exe winsup.api/ltp/stat06.exe winsup.api/ltp/symlink01.exe winsup.api/ltp/symlink03.exe winsup.api/ltp/times02.exe winsup.api/ltp/unlink07.exe Signed-off-by: Igor Podgainoi <igor.podgainoi@arm.com>
1 parent 9c2ea08 commit 4054e78

2 files changed

Lines changed: 23 additions & 14 deletions

File tree

winsup/cygwin/exceptions.cc

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -618,10 +618,14 @@ EXCEPTION_DISPOSITION
618618
exception::myfault (EXCEPTION_RECORD *e, exception_list *frame, CONTEXT *in,
619619
PDISPATCHER_CONTEXT dispatch)
620620
{
621+
if (IS_UNWINDING(e->ExceptionFlags))
622+
return ExceptionContinueSearch;
623+
621624
PSCOPE_TABLE table = (PSCOPE_TABLE) dispatch->HandlerData;
622-
RtlUnwindEx (frame,
623-
(char *) dispatch->ImageBase + table->ScopeRecord[0].JumpTarget,
624-
e, 0, in, dispatch->HistoryTable);
625+
void *jump_target = ((char *) dispatch->ImageBase) + table->ScopeRecord[0].JumpTarget;
626+
627+
CONTEXT c;
628+
RtlUnwindEx (frame, jump_target, e, 0, &c, dispatch->HistoryTable);
625629
/* NOTREACHED, make gcc happy. */
626630
return ExceptionContinueSearch;
627631
}

winsup/cygwin/local_includes/cygtls.h

Lines changed: 16 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -344,21 +344,26 @@ class san
344344
void leave () __attribute__ ((returns_twice));
345345
};
346346

347-
#if defined (__aarch64__)
347+
#if defined(__aarch64__)
348348
#define EXCEPTION_MYFAULT_REF "_ZN9exception7myfaultEP17_EXCEPTION_RECORDPvP8_CONTEXTP25_DISPATCHER_CONTEXT_ARM64"
349-
#define TRY_HANDLER_DATA (void) &&__l_try;
350-
#else
349+
/* An SEH directive that switches back to the code section. */
350+
#define SEH_CODE ".text"
351+
#elif defined(__x86_64__)
351352
#define EXCEPTION_MYFAULT_REF "_ZN9exception7myfaultEP17_EXCEPTION_RECORDPvP8_CONTEXTP19_DISPATCHER_CONTEXT"
352-
#define TRY_HANDLER_DATA \
353-
__asm__ goto ("\n" \
354-
" .seh_handler " EXCEPTION_MYFAULT_REF ", @except \n" \
355-
" .seh_handlerdata \n" \
356-
" .long 1 \n" \
357-
" .rva %l[__l_try],%l[__l_endtry],%l[__l_except],%l[__l_except] \n" \
358-
" .seh_code \n" \
359-
: : : : __l_try, __l_endtry, __l_except)
353+
#define SEH_CODE ".seh_code"
360354
#endif
361355

356+
#define TRY_HANDLER_DATA \
357+
__asm__ goto ("\n\
358+
.seh_handler " \
359+
EXCEPTION_MYFAULT_REF ", \
360+
@except \n\
361+
.seh_handlerdata \n\
362+
.long 1 \n\
363+
.rva %l[__l_try],%l[__l_endtry],%l[__l_except],%l[__l_except] \n"\
364+
SEH_CODE " \n"\
365+
: : : : __l_try, __l_endtry, __l_except)
366+
362367
/* Exception handling macros. This is a handmade SEH try/except. */
363368
#define __mem_barrier __asm__ __volatile__ ("" ::: "memory")
364369
#define __try \

0 commit comments

Comments
 (0)