@@ -83,6 +83,19 @@ struct UNWIND_INFO {
83
83
uint16_t UnwindCodes[2 ];
84
84
};
85
85
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
+
86
99
extern " C" _Unwind_Reason_Code __libunwind_seh_personality (
87
100
int , _Unwind_Action, uint64_t , _Unwind_Exception *,
88
101
struct _Unwind_Context *);
@@ -2064,6 +2077,51 @@ bool UnwindCursor<A, R>::getInfoFromSEH(pint_t pc) {
2064
2077
}
2065
2078
}
2066
2079
}
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 (exceptionHandlerInfo[0 ])
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
+ }
2067
2125
#endif
2068
2126
setLastPC (pc);
2069
2127
return true ;
0 commit comments