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