@@ -83,6 +83,19 @@ struct UNWIND_INFO {
8383 uint16_t UnwindCodes[2 ];
8484};
8585
86+ union UNWIND_INFO_ARM {
87+ DWORD HeaderData;
88+ struct {
89+ DWORD FunctionLength : 18 ;
90+ DWORD Version : 2 ;
91+ DWORD ExceptionDataPresent : 1 ;
92+ DWORD EpilogInHeader : 1 ;
93+ DWORD FunctionFragment : 1 ;
94+ DWORD EpilogCount : 5 ;
95+ DWORD CodeWords : 4 ;
96+ } s;
97+ };
98+
8699extern " C" _Unwind_Reason_Code __libunwind_seh_personality (
87100 int , _Unwind_Action, uint64_t , _Unwind_Exception *,
88101 struct _Unwind_Context *);
@@ -2064,6 +2077,51 @@ bool UnwindCursor<A, R>::getInfoFromSEH(pint_t pc) {
20642077 }
20652078 }
20662079 }
2080+ #elif defined(_LIBUNWIND_TARGET_ARM)
2081+ if (unwindEntry->Flag != 0 ) { // Packed unwind info
2082+ _info.end_ip = _info.start_ip + unwindEntry->FunctionLength * 2 ;
2083+ // Only fill in the handler and LSDA if they're stale.
2084+ if (pc != getLastPC ()) {
2085+ // Packed unwind info doesn't have an exception handler.
2086+ _info.lsda = 0 ;
2087+ _info.handler = 0 ;
2088+ }
2089+ } else {
2090+ UNWIND_INFO_ARM *xdata =
2091+ reinterpret_cast <UNWIND_INFO_ARM *>(base + unwindEntry->UnwindData );
2092+ _info.end_ip = _info.start_ip + xdata->s .FunctionLength * 2 ;
2093+ // Only fill in the handler and LSDA if they're stale.
2094+ if (pc != getLastPC ()) {
2095+ if (xdata->s .ExceptionDataPresent ) {
2096+ uint32_t offset = 1 ; // The main xdata
2097+ uint32_t codeWords = xdata->s .CodeWords ;
2098+ uint32_t epilogScopes = xdata->s .EpilogCount ;
2099+ if (xdata->s .EpilogCount == 0 && xdata->s .CodeWords == 0 ) {
2100+ uint32_t extensionWord = reinterpret_cast <uint32_t *>(xdata)[1 ];
2101+ codeWords = (extensionWord >> 16 ) & 0xff ;
2102+ epilogScopes = extensionWord & 0xffff ;
2103+ offset++;
2104+ }
2105+ if (!xdata->s .EpilogInHeader )
2106+ offset += epilogScopes;
2107+ offset += codeWords;
2108+ uint32_t *exceptionHandlerInfo =
2109+ reinterpret_cast <uint32_t *>(xdata) + offset;
2110+ _dispContext.HandlerData = &exceptionHandlerInfo[1 ];
2111+ _dispContext.LanguageHandler = reinterpret_cast <EXCEPTION_ROUTINE *>(
2112+ base + exceptionHandlerInfo[0 ]);
2113+ _info.lsda = reinterpret_cast <unw_word_t >(_dispContext.HandlerData );
2114+ if (_dispContext.LanguageHandler )
2115+ _info.handler =
2116+ reinterpret_cast <unw_word_t >(__libunwind_seh_personality);
2117+ else
2118+ _info.handler = 0 ;
2119+ } else {
2120+ _info.lsda = 0 ;
2121+ _info.handler = 0 ;
2122+ }
2123+ }
2124+ }
20672125#endif
20682126 setLastPC (pc);
20692127 return true ;
0 commit comments