| ... | ... | @@ -20,6 +20,15 @@ |
| 20 | 20 | |
| 21 | 21 | #include <unwind.h> |
| 22 | 22 | |
| 23 | #if defined(__SEH__) && !defined(__USING_SJLJ_EXCEPTIONS__) |
| 24 | #include <windows.h> |
| 25 | #include <winnt.h> |
| 26 | |
| 27 | EXCEPTION_DISPOSITION _GCC_specific_handler(PEXCEPTION_RECORD, void *, PCONTEXT, |
| 28 | PDISPATCHER_CONTEXT, |
| 29 | _Unwind_Personality_Fn); |
| 30 | #endif |
| 31 | |
| 23 | 32 | // Pointer encodings documented at: |
| 24 | 33 | // http://refspecs.freestandards.org/LSB_1.3.0/gLSB/gLSB/ehframehdr.html |
| 25 | 34 | |
| ... | ... | @@ -43,9 +52,9 @@ |
| 43 | 52 | #define DW_EH_PE_indirect 0x80 // gcc extension |
| 44 | 53 | |
| 45 | 54 | // read a uleb128 encoded value and advance pointer |
| 46 | | static uintptr_t readULEB128(const uint8_t **data) { |
| 47 | | uintptr_t result = 0; |
| 48 | | uintptr_t shift = 0; |
| 55 | static size_t readULEB128(const uint8_t **data) { |
| 56 | size_t result = 0; |
| 57 | size_t shift = 0; |
| 49 | 58 | unsigned char byte; |
| 50 | 59 | const uint8_t *p = *data; |
| 51 | 60 | do { |
| ... | ... | @@ -133,7 +142,7 @@ static uintptr_t readEncodedPointer(const uint8_t **data, uint8_t encoding) { |
| 133 | 142 | } |
| 134 | 143 | |
| 135 | 144 | #if defined(__arm__) && !defined(__USING_SJLJ_EXCEPTIONS__) && \ |
| 136 | | !defined(__ARM_DWARF_EH__) |
| 145 | !defined(__ARM_DWARF_EH__) && !defined(__SEH__) |
| 137 | 146 | #define USING_ARM_EHABI 1 |
| 138 | 147 | _Unwind_Reason_Code __gnu_unwind_frame(struct _Unwind_Exception *, |
| 139 | 148 | struct _Unwind_Context *); |
| ... | ... | @@ -168,6 +177,10 @@ COMPILER_RT_ABI _Unwind_Reason_Code __gcc_personality_sj0( |
| 168 | 177 | COMPILER_RT_ABI _Unwind_Reason_Code __gcc_personality_v0( |
| 169 | 178 | _Unwind_State state, struct _Unwind_Exception *exceptionObject, |
| 170 | 179 | struct _Unwind_Context *context) |
| 180 | #elif defined(__SEH__) |
| 181 | static _Unwind_Reason_Code __gcc_personality_imp( |
| 182 | int version, _Unwind_Action actions, uint64_t exceptionClass, |
| 183 | struct _Unwind_Exception *exceptionObject, struct _Unwind_Context *context) |
| 171 | 184 | #else |
| 172 | 185 | COMPILER_RT_ABI _Unwind_Reason_Code __gcc_personality_v0( |
| 173 | 186 | int version, _Unwind_Action actions, uint64_t exceptionClass, |
| ... | ... | @@ -205,14 +218,14 @@ COMPILER_RT_ABI _Unwind_Reason_Code __gcc_personality_v0( |
| 205 | 218 | } |
| 206 | 219 | // Walk call-site table looking for range that includes current PC. |
| 207 | 220 | uint8_t callSiteEncoding = *lsda++; |
| 208 | | uint32_t callSiteTableLength = readULEB128(&lsda); |
| 221 | size_t callSiteTableLength = readULEB128(&lsda); |
| 209 | 222 | const uint8_t *callSiteTableStart = lsda; |
| 210 | 223 | const uint8_t *callSiteTableEnd = callSiteTableStart + callSiteTableLength; |
| 211 | 224 | const uint8_t *p = callSiteTableStart; |
| 212 | 225 | while (p < callSiteTableEnd) { |
| 213 | 226 | uintptr_t start = readEncodedPointer(&p, callSiteEncoding); |
| 214 | | uintptr_t length = readEncodedPointer(&p, callSiteEncoding); |
| 215 | | uintptr_t landingPad = readEncodedPointer(&p, callSiteEncoding); |
| 227 | size_t length = readEncodedPointer(&p, callSiteEncoding); |
| 228 | size_t landingPad = readEncodedPointer(&p, callSiteEncoding); |
| 216 | 229 | readULEB128(&p); // action value not used for C code |
| 217 | 230 | if (landingPad == 0) |
| 218 | 231 | continue; // no landing pad for this entry |
| ... | ... | @@ -232,3 +245,12 @@ COMPILER_RT_ABI _Unwind_Reason_Code __gcc_personality_v0( |
| 232 | 245 | // No landing pad found, continue unwinding. |
| 233 | 246 | return continueUnwind(exceptionObject, context); |
| 234 | 247 | } |
| 248 | |
| 249 | #if defined(__SEH__) && !defined(__USING_SJLJ_EXCEPTIONS__) |
| 250 | COMPILER_RT_ABI EXCEPTION_DISPOSITION |
| 251 | __gcc_personality_seh0(PEXCEPTION_RECORD ms_exc, void *this_frame, |
| 252 | PCONTEXT ms_orig_context, PDISPATCHER_CONTEXT ms_disp) { |
| 253 | return _GCC_specific_handler(ms_exc, this_frame, ms_orig_context, ms_disp, |
| 254 | __gcc_personality_imp); |
| 255 | } |
| 256 | #endif |