@@ -83,6 +83,22 @@ struct UNWIND_INFO {
8383 uint16_t UnwindCodes[2 ];
8484};
8585
86+ #pragma clang diagnostic push
87+ #pragma clang diagnostic ignored "-Wgnu-anonymous-struct"
88+ union UNWIND_INFO_ARM {
89+ DWORD HeaderData;
90+ struct {
91+ DWORD FunctionLength : 18 ;
92+ DWORD Version : 2 ;
93+ DWORD ExceptionDataPresent : 1 ;
94+ DWORD EpilogInHeader : 1 ;
95+ DWORD FunctionFragment : 1 ;
96+ DWORD EpilogCount : 5 ;
97+ DWORD CodeWords : 4 ;
98+ };
99+ };
100+ #pragma clang diagnostic pop
101+
86102extern " C" _Unwind_Reason_Code __libunwind_seh_personality (
87103 int , _Unwind_Action, uint64_t , _Unwind_Exception *,
88104 struct _Unwind_Context *);
@@ -2018,27 +2034,36 @@ bool UnwindCursor<A, R>::getInfoFromSEH(pint_t pc) {
20182034 _info.handler = 0 ;
20192035 }
20202036 }
2021- #elif defined(_LIBUNWIND_TARGET_AARCH64)
2037+ #elif defined(_LIBUNWIND_TARGET_AARCH64) || defined(_LIBUNWIND_TARGET_ARM)
2038+
2039+ #if defined(_LIBUNWIND_TARGET_AARCH64)
2040+ #define FUNC_LENGTH_UNIT 4
2041+ #define XDATA_TYPE IMAGE_ARM64_RUNTIME_FUNCTION_ENTRY_XDATA
2042+ #else
2043+ #define FUNC_LENGTH_UNIT 2
2044+ #define XDATA_TYPE UNWIND_INFO_ARM
2045+ #endif
20222046 if (unwindEntry->Flag != 0 ) { // Packed unwind info
2023- _info.end_ip = _info.start_ip + unwindEntry->FunctionLength * 4 ;
2047+ _info.end_ip =
2048+ _info.start_ip + unwindEntry->FunctionLength * FUNC_LENGTH_UNIT;
20242049 // Only fill in the handler and LSDA if they're stale.
20252050 if (pc != getLastPC ()) {
20262051 // Packed unwind info doesn't have an exception handler.
20272052 _info.lsda = 0 ;
20282053 _info.handler = 0 ;
20292054 }
20302055 } else {
2031- IMAGE_ARM64_RUNTIME_FUNCTION_ENTRY_XDATA *xdata =
2032- reinterpret_cast <IMAGE_ARM64_RUNTIME_FUNCTION_ENTRY_XDATA *>(
2033- base + unwindEntry->UnwindData );
2034- _info.end_ip = _info.start_ip + xdata->FunctionLength * 4 ;
2056+ XDATA_TYPE *xdata =
2057+ reinterpret_cast <XDATA_TYPE *>(base + unwindEntry->UnwindData );
2058+ _info.end_ip = _info.start_ip + xdata->FunctionLength * FUNC_LENGTH_UNIT;
20352059 // Only fill in the handler and LSDA if they're stale.
20362060 if (pc != getLastPC ()) {
20372061 if (xdata->ExceptionDataPresent ) {
20382062 uint32_t offset = 1 ; // The main xdata
20392063 uint32_t codeWords = xdata->CodeWords ;
20402064 uint32_t epilogScopes = xdata->EpilogCount ;
20412065 if (xdata->EpilogCount == 0 && xdata->CodeWords == 0 ) {
2066+ // The extension word has got the same layout for both ARM and ARM64
20422067 uint32_t extensionWord = reinterpret_cast <uint32_t *>(xdata)[1 ];
20432068 codeWords = (extensionWord >> 16 ) & 0xff ;
20442069 epilogScopes = extensionWord & 0xffff ;
0 commit comments