summaryrefslogtreecommitdiffstats
path: root/libcxxabi/src/cxa_personality.cpp
diff options
context:
space:
mode:
authorHoward Hinnant <hhinnant@apple.com>2012-01-30 20:16:21 +0000
committerHoward Hinnant <hhinnant@apple.com>2012-01-30 20:16:21 +0000
commitc9204f6bedada8dadd7183b7aac2ebbff0860ba6 (patch)
treec0ddecd02963fe29523b020266f1ac1fc07190d5 /libcxxabi/src/cxa_personality.cpp
parent2c50972c32c21f89897d6198360b989f9859cd11 (diff)
downloadbcm5719-llvm-c9204f6bedada8dadd7183b7aac2ebbff0860ba6.tar.gz
bcm5719-llvm-c9204f6bedada8dadd7183b7aac2ebbff0860ba6.zip
Refactored personality function. Found one bug in scanning exception spec lists.
llvm-svn: 149272
Diffstat (limited to 'libcxxabi/src/cxa_personality.cpp')
-rw-r--r--libcxxabi/src/cxa_personality.cpp1140
1 files changed, 361 insertions, 779 deletions
diff --git a/libcxxabi/src/cxa_personality.cpp b/libcxxabi/src/cxa_personality.cpp
index 8d5b05b1c78..fdf86792045 100644
--- a/libcxxabi/src/cxa_personality.cpp
+++ b/libcxxabi/src/cxa_personality.cpp
@@ -20,8 +20,6 @@
#include <stdlib.h>
#include <assert.h>
-#include <stdio.h>
-
/*
Exception Header Layout:
@@ -206,10 +204,6 @@ static
uintptr_t
readEncodedPointer(const uint8_t** data, uint8_t encoding)
{
-// TODO: Not quite rgiht. This should be able to read a 0 from the TType table
-// and not dereference it. Pasted in temporayr workaround
-// TODO: Sometimes this is clearly not always reading an encoded pointer, for
-// example a length in the call site table. Needs new name?
uintptr_t result = 0;
if (encoding == DW_EH_PE_omit)
return result;
@@ -346,7 +340,8 @@ exception_spec_can_catch(int64_t specIndex, const uint8_t* classInfo,
// this should not happen
call_terminate(false, unwind_exception);
}
- // specIndex is 1-based byte offset into classInfo;
+ // specIndex is negative of 1-based byte offset into classInfo;
+ specIndex = -specIndex;
--specIndex;
const uint8_t* temp = classInfo + specIndex;
// If any type in the spec list can catch excpType, return false, else return true
@@ -369,222 +364,360 @@ exception_spec_can_catch(int64_t specIndex, const uint8_t* classInfo,
}
static
-const uint8_t*
-getTTypeEntry(int64_t ttypeIndex, const uint8_t* classInfo, uint8_t ttypeEncoding)
+void*
+get_thrown_object_ptr(_Unwind_Exception* unwind_exception)
{
- switch (ttypeEncoding & 0x0F)
- {
- case DW_EH_PE_absptr:
- ttypeIndex *= sizeof(void*);
- break;
- case DW_EH_PE_udata2:
- case DW_EH_PE_sdata2:
- ttypeIndex *= 2;
- break;
- case DW_EH_PE_udata4:
- case DW_EH_PE_sdata4:
- ttypeIndex *= 4;
- break;
- case DW_EH_PE_udata8:
- case DW_EH_PE_sdata8:
- ttypeIndex *= 8;
- break;
- }
- return classInfo - ttypeIndex;
+ // Even for foreign exceptions, the exception object is *probably* at unwind_exception + 1
+ // Regardless, this library is prohibited from touching a foreign exception
+ void* adjustedPtr = unwind_exception + 1;
+ if (unwind_exception->exception_class == kOurDependentExceptionClass)
+ adjustedPtr = ((__cxa_dependent_exception*)adjustedPtr - 1)->primaryException;
+ return adjustedPtr;
}
-static
-void
-save_state(__cxa_exception* exception_header, int handlerSwitchValue,
- const uint8_t* actionRecord, const uint8_t* languageSpecificData,
- void* landingPad, void* adjustedPtr)
+/*
+ There are 3 types of scans needed:
+
+ 1. Scan for handler with native or foreign exception. If handler found,
+ save state and return _URC_HANDLER_FOUND, else return _URC_CONTINUE_UNWIND.
+ May also report an error on invalid input.
+ May terminate for invalid exception table.
+ _UA_SEARCH_PHASE
+
+ 2. Scan for handler with foreign exception. Must return _URC_HANDLER_FOUND,
+ or call terminate.
+ _UA_CLEANUP_PHASE && _UA_HANDLER_FRAME && !native_exception
+
+ 3. Scan for cleanups. If a handler is found and this isn't forced unwind,
+ then terminate, otherwise ignore the handler and keep looking for cleanup.
+ If a cleanup is found, return _URC_HANDLER_FOUND, else return _URC_CONTINUE_UNWIND.
+ May also report an error on invalid input.
+ May terminate for invalid exception table.
+ _UA_CLEANUP_PHASE && !_UA_HANDLER_FRAME
+*/
+
+namespace
{
- exception_header->handlerSwitchValue = handlerSwitchValue;
- exception_header->actionRecord = actionRecord;
- exception_header->languageSpecificData = languageSpecificData;
- exception_header->catchTemp = landingPad;
- exception_header->adjustedPtr = adjustedPtr;
-}
-static
-void
-save_state_for_exception_spec(__cxa_exception* exception_header,
- int handlerSwitchValue,
- const void* classInfo,
- uint8_t ttypeEncoding,
- void* adjustedPtr)
+struct scan_results
{
- exception_header->handlerSwitchValue = handlerSwitchValue;
- exception_header->languageSpecificData = static_cast<const uint8_t*>(classInfo);
- exception_header->catchTemp = (void*)(uintptr_t)ttypeEncoding;
- exception_header->adjustedPtr = adjustedPtr;
-}
+ int64_t ttypeIndex; // > 0 catch handler, < 0 exception spec handler, == 0 a cleanup
+ const uint8_t* actionRecord; // Currently unused. TODO: Remove?
+ const uint8_t* languageSpecificData; // Needed only for __cxa_call_unexpected
+ uintptr_t landingPad; // null -> nothing found, else something found
+ void* adjustedPtr; // Used in cxa_exception.cpp
+ _Unwind_Reason_Code reason; // One of _URC_FATAL_PHASE1_ERROR,
+ // _URC_FATAL_PHASE2_ERROR,
+ // _URC_CONTINUE_UNWIND,
+ // _URC_HANDLER_FOUND
+};
+
+} // unnamed namespace
-/// Deals with Dwarf actions matching our type infos
-/// (OurExceptionType_t instances). Returns whether or not a dwarf emitted
-/// action matches the supplied exception type. If such a match succeeds,
-/// the handlerSwitchValue will be set with > 0 index value. Only
-/// corresponding llvm.eh.selector type info arguments, cleanup arguments
-/// are supported. Filters are not supported.
-/// See Variable Length Data in:
-/// @link http://dwarfstd.org/Dwarf3.pdf @unlink
-/// Also see @link http://refspecs.freestandards.org/abi-eh-1.21.html @unlink
-/// @param classInfo our array of type info pointers (to globals)
-/// @param actionEntry index into above type info array or 0 (cleanup).
-/// We do not support filters.
-/// @param unwind_exception thrown _Unwind_Exception instance.
-/// @returns whether or not a type info was found. False is returned if only
-/// a cleanup was found
static
-bool
-handleActionValue(const uint8_t* classInfo, uintptr_t actionEntry,
- _Unwind_Exception* unwind_exception, uint8_t ttypeEncoding)
+void
+scan_eh_tab(scan_results& results, _Unwind_Action actions, bool native_exception,
+ _Unwind_Exception* unwind_exception, _Unwind_Context* context)
{
- __cxa_exception* exception_header = (__cxa_exception*)(unwind_exception+1) - 1;
- void* thrown_object =
- unwind_exception->exception_class == kOurDependentExceptionClass ?
- ((__cxa_dependent_exception*)exception_header)->primaryException :
- exception_header + 1;
- const __shim_type_info* excpType =
- static_cast<const __shim_type_info*>(exception_header->exceptionType);
- const uint8_t* actionPos = (uint8_t*)actionEntry;
- while (true)
+ // Initialize results to found nothing but an error
+ results.ttypeIndex = 0;
+ results.actionRecord = 0;
+ results.languageSpecificData = 0;
+ results.landingPad = 0;
+ results.adjustedPtr = 0;
+ results.reason = _URC_FATAL_PHASE1_ERROR;
+ // Check for consistent actions
+ if (actions & _UA_SEARCH_PHASE)
{
- // Each emitted dwarf action corresponds to a 2 tuple of
- // type info address offset, and action offset to the next
- // emitted action.
- const uint8_t* SactionPos = actionPos;
- int64_t ttypeIndex = readSLEB128(&actionPos);
- const uint8_t* tempActionPos = actionPos;
- int64_t actionOffset = readSLEB128(&tempActionPos);
- if (ttypeIndex > 0) // a catch handler
- {
- const uint8_t* TTypeEntry = getTTypeEntry(ttypeIndex, classInfo,
- ttypeEncoding);
- const __shim_type_info* catchType =
- (const __shim_type_info*)readEncodedPointer(&TTypeEntry,
- ttypeEncoding);
- void* adjustedPtr = thrown_object;
- // catchType == 0 -> catch (...)
- if (catchType == 0 || catchType->can_catch(excpType, adjustedPtr))
- {
- exception_header->handlerSwitchValue = ttypeIndex;
- exception_header->actionRecord = SactionPos; // unnecessary?
- // used by __cxa_get_exception_ptr and __cxa_begin_catch
- exception_header->adjustedPtr = adjustedPtr;
- return true;
- }
- }
- else if (ttypeIndex < 0) // an exception spec
+ // Do Phase 1
+ if (actions & (_UA_CLEANUP_PHASE | _UA_HANDLER_FRAME | _UA_FORCE_UNWIND))
{
+ // None of these flags should be set during Phase 1
+ // Client error
+ results.reason = _URC_FATAL_PHASE1_ERROR;
+ return;
}
- else // ttypeIndex == 0 // a cleanup
+ }
+ else if (actions & _UA_CLEANUP_PHASE)
+ {
+ if ((actions & _UA_HANDLER_FRAME) && (actions & _UA_FORCE_UNWIND))
{
+ // _UA_HANDLER_FRAME should only be set if phase 1 found a handler.
+ // If _UA_FORCE_UNWIND is set, phase 1 shouldn't have happened.
+ // Client error
+ results.reason = _URC_FATAL_PHASE2_ERROR;
+ return;
}
- if (actionOffset == 0)
- break;
- actionPos += actionOffset;
}
- return false;
-}
-
-// Return true if there is a handler and false otherwise
-// cache handlerSwitchValue, actionRecord, languageSpecificData,
-// catchTemp and adjustedPtr here.
-static
-bool
-contains_handler(_Unwind_Exception* unwind_exception, _Unwind_Context* context)
-{
- __cxa_exception* exception_header = (__cxa_exception*)(unwind_exception+1) - 1;
+ else // Niether _UA_SEARCH_PHASE nor _UA_CLEANUP_PHASE is set
+ {
+ // One of these should be set.
+ // Client error
+ results.reason = _URC_FATAL_PHASE1_ERROR;
+ return;
+ }
+ // Start scan by getting exception table address
const uint8_t* lsda = (const uint8_t*)_Unwind_GetLanguageSpecificData(context);
- exception_header->languageSpecificData = lsda;
- if (lsda)
+ if (lsda == 0)
{
- // Get the current instruction pointer and offset it before next
- // instruction in the current frame which threw the exception.
- uintptr_t ip = _Unwind_GetIP(context) - 1;
- // Get beginning current frame's code (as defined by the
- // emitted dwarf code)
- uintptr_t funcStart = _Unwind_GetRegionStart(context);
- uintptr_t ipOffset = ip - funcStart;
- const uint8_t* classInfo = NULL;
- // Note: See JITDwarfEmitter::EmitExceptionTable(...) for corresponding
- // dwarf emission
- // Parse LSDA header.
- uint8_t lpStartEncoding = *lsda++;
- const uint8_t* lpStart = (const uint8_t*)readEncodedPointer(&lsda, lpStartEncoding);
- if (lpStart == 0)
- lpStart = (const uint8_t*)funcStart;
- uint8_t ttypeEncoding = *lsda++;
- // TODO: preflight ttypeEncoding here and return error if there's a problem
- if (ttypeEncoding != DW_EH_PE_omit)
- {
- // Calculate type info locations in emitted dwarf code which
- // were flagged by type info arguments to llvm.eh.selector
- // intrinsic
- uintptr_t classInfoOffset = readULEB128(&lsda);
- classInfo = lsda + classInfoOffset;
- }
- // Walk call-site table looking for range that
- // includes current PC.
- uint8_t callSiteEncoding = *lsda++;
- uint32_t callSiteTableLength = readULEB128(&lsda);
- const uint8_t* callSiteTableStart = lsda;
- const uint8_t* callSiteTableEnd = callSiteTableStart + callSiteTableLength;
- const uint8_t* actionTableStart = callSiteTableEnd;
- const uint8_t* callSitePtr = callSiteTableStart;
- while (callSitePtr < callSiteTableEnd)
+ // There is no exception table
+ results.reason = _URC_CONTINUE_UNWIND;
+ return;
+ }
+ results.languageSpecificData = lsda;
+ // Get the current instruction pointer and offset it before next
+ // instruction in the current frame which threw the exception.
+ uintptr_t ip = _Unwind_GetIP(context) - 1;
+ // Get beginning current frame's code (as defined by the
+ // emitted dwarf code)
+ uintptr_t funcStart = _Unwind_GetRegionStart(context);
+ uintptr_t ipOffset = ip - funcStart;
+ const uint8_t* classInfo = NULL;
+ // Note: See JITDwarfEmitter::EmitExceptionTable(...) for corresponding
+ // dwarf emission
+ // Parse LSDA header.
+ uint8_t lpStartEncoding = *lsda++;
+ const uint8_t* lpStart = (const uint8_t*)readEncodedPointer(&lsda, lpStartEncoding);
+ if (lpStart == 0)
+ lpStart = (const uint8_t*)funcStart;
+ uint8_t ttypeEncoding = *lsda++;
+ if (ttypeEncoding != DW_EH_PE_omit)
+ {
+ // Calculate type info locations in emitted dwarf code which
+ // were flagged by type info arguments to llvm.eh.selector
+ // intrinsic
+ uintptr_t classInfoOffset = readULEB128(&lsda);
+ classInfo = lsda + classInfoOffset;
+ }
+ // Walk call-site table looking for range that
+ // includes current PC.
+ uint8_t callSiteEncoding = *lsda++;
+ uint32_t callSiteTableLength = readULEB128(&lsda);
+ const uint8_t* callSiteTableStart = lsda;
+ const uint8_t* callSiteTableEnd = callSiteTableStart + callSiteTableLength;
+ const uint8_t* actionTableStart = callSiteTableEnd;
+ const uint8_t* callSitePtr = callSiteTableStart;
+ while (true)
+ {
+ // There is one entry per call site.
+ // The call sites are non-overlapping in [start, start+length)
+ // The call sites are ordered in increasing value of start
+ uintptr_t start = readEncodedPointer(&callSitePtr, callSiteEncoding);
+ uintptr_t length = readEncodedPointer(&callSitePtr, callSiteEncoding);
+ uintptr_t landingPad = readEncodedPointer(&callSitePtr, callSiteEncoding);
+ uintptr_t actionEntry = readULEB128(&callSitePtr);
+ if ((start <= ipOffset) && (ipOffset < (start + length)))
{
- uintptr_t start = readEncodedPointer(&callSitePtr, callSiteEncoding);
- uintptr_t length = readEncodedPointer(&callSitePtr, callSiteEncoding);
- uintptr_t landingPad = readEncodedPointer(&callSitePtr, callSiteEncoding);
- // Note: Action value
- uintptr_t actionEntry = readULEB128(&callSitePtr);
+ // Found the call site containing ip.
if (landingPad == 0)
- continue; // no landing pad for this entry
- if (actionEntry)
- actionEntry += ((uintptr_t)actionTableStart) - 1;
- if ((start <= ipOffset) && (ipOffset < (start + length)))
{
- exception_header->catchTemp = (void*)(lpStart + landingPad);
- if (actionEntry)
- return handleActionValue(classInfo,
- actionEntry,
- unwind_exception,
- ttypeEncoding);
- // Note: Only non-cleanup handlers are marked as
- // found. Otherwise the cleanup handlers will be
- // re-found and executed during the cleanup
- // phase.
- return false; // Won't find another call site in range of ipOffset
+ // No handler here
+ results.reason = _URC_CONTINUE_UNWIND;
+ return;
+ }
+ landingPad = (uintptr_t)lpStart + landingPad;
+ if (actionEntry == 0)
+ {
+ // Found a cleanup
+ // If this is a type 1 or type 2 search, ignore the clean up
+ // and continue to scan for a handler.
+ // If this is a type 3 search, you want to install the cleanup.
+ if ((actions & _UA_CLEANUP_PHASE) && !(actions & _UA_HANDLER_FRAME))
+ {
+ results.ttypeIndex = 0; // Redundant but clarifying
+ results.landingPad = landingPad;
+ results.reason = _URC_HANDLER_FOUND;
+ return;
+ }
}
+ // Convert 1-based byte offset into
+ const uint8_t* action = actionTableStart + (actionEntry - 1);
+ // Scan action entries until you find a matching handler, cleanup, or the end of action list
+ while (true)
+ {
+ const uint8_t* actionRecord = action;
+ int64_t ttypeIndex = readSLEB128(&action);
+ if (ttypeIndex > 0)
+ {
+ // Found a catch, does it actually catch?
+ // First check for catch (...)
+ const __shim_type_info* catchType =
+ get_shim_type_info(ttypeIndex, classInfo,
+ ttypeEncoding, native_exception,
+ unwind_exception);
+ if (catchType == 0)
+ {
+ // Found catch (...) catches everything, including foreign exceptions
+ // If this is a type 1 search save state and return _URC_HANDLER_FOUND
+ // If this is a type 2 search save state and return _URC_HANDLER_FOUND
+ // If this is a type 3 search !_UA_FORCE_UNWIND, we should have found this in phase 1!
+ // If this is a type 3 search _UA_FORCE_UNWIND, ignore handler and continue scan
+ if ((actions & _UA_SEARCH_PHASE) || (actions & _UA_HANDLER_FRAME))
+ {
+ // Save state and return _URC_HANDLER_FOUND
+ results.ttypeIndex = ttypeIndex;
+ results.actionRecord = actionRecord;
+ results.landingPad = landingPad;
+ results.adjustedPtr = get_thrown_object_ptr(unwind_exception);
+ results.reason = _URC_HANDLER_FOUND;
+ return;
+ }
+ else if (!(actions & _UA_FORCE_UNWIND))
+ {
+ // It looks like the exception table has changed
+ // on us. Likely stack corruption!
+ call_terminate(native_exception, unwind_exception);
+ }
+ }
+ // Else this is a catch (T) clause and will never
+ // catch a foreign exception
+ else if (native_exception)
+ {
+ __cxa_exception* exception_header = (__cxa_exception*)(unwind_exception+1) - 1;
+ void* adjustedPtr = get_thrown_object_ptr(unwind_exception);
+ const __shim_type_info* excpType =
+ static_cast<const __shim_type_info*>(exception_header->exceptionType);
+ if (adjustedPtr == 0 || excpType == 0)
+ {
+ // Something very bad happened
+ call_terminate(native_exception, unwind_exception);
+ }
+ if (catchType->can_catch(excpType, adjustedPtr))
+ {
+ // Found a matching handler
+ // If this is a type 1 search save state and return _URC_HANDLER_FOUND
+ // If this is a type 3 search and !_UA_FORCE_UNWIND, we should have found this in phase 1!
+ // If this is a type 3 search and _UA_FORCE_UNWIND, ignore handler and continue scan
+ if (actions & _UA_SEARCH_PHASE)
+ {
+ // Save state and return _URC_HANDLER_FOUND
+ results.ttypeIndex = ttypeIndex;
+ results.actionRecord = actionRecord;
+ results.landingPad = landingPad;
+ results.adjustedPtr = adjustedPtr;
+ results.reason = _URC_HANDLER_FOUND;
+ return;
+ }
+ else if (!(actions & _UA_FORCE_UNWIND))
+ {
+ // It looks like the exception table has changed
+ // on us. Likely stack corruption!
+ call_terminate(native_exception, unwind_exception);
+ }
+ }
+ }
+ // Scan next action ...
+ }
+ else if (ttypeIndex < 0)
+ {
+ // Found an exception spec. If this is a foreign exception,
+ // it is always caught.
+ if (native_exception)
+ {
+ // Does the exception spec catch this native exception?
+ __cxa_exception* exception_header = (__cxa_exception*)(unwind_exception+1) - 1;
+ void* adjustedPtr = get_thrown_object_ptr(unwind_exception);
+ const __shim_type_info* excpType =
+ static_cast<const __shim_type_info*>(exception_header->exceptionType);
+ if (adjustedPtr == 0 || excpType == 0)
+ {
+ // Something very bad happened
+ call_terminate(native_exception, unwind_exception);
+ }
+ if (exception_spec_can_catch(ttypeIndex, classInfo,
+ ttypeEncoding, excpType,
+ adjustedPtr, unwind_exception))
+ {
+ // native exception caught by exception spec
+ // If this is a type 1 search, save state and return _URC_HANDLER_FOUND
+ // If this is a type 3 search !_UA_FORCE_UNWIND, we should have found this in phase 1!
+ // If this is a type 3 search _UA_FORCE_UNWIND, ignore handler and continue scan
+ if (actions & _UA_SEARCH_PHASE)
+ {
+ // Save state and return _URC_HANDLER_FOUND
+ results.ttypeIndex = ttypeIndex;
+ results.actionRecord = actionRecord;
+ results.landingPad = landingPad;
+ results.adjustedPtr = adjustedPtr;
+ results.reason = _URC_HANDLER_FOUND;
+ return;
+ }
+ else if (!(actions & _UA_FORCE_UNWIND))
+ {
+ // It looks like the exception table has changed
+ // on us. Likely stack corruption!
+ call_terminate(native_exception, unwind_exception);
+ }
+ }
+ }
+ else
+ {
+ // foreign exception caught by exception spec
+ // If this is a type 1 search, save state and return _URC_HANDLER_FOUND
+ // If this is a type 2 search, save state and return _URC_HANDLER_FOUND
+ // If this is a type 3 search !_UA_FORCE_UNWIND, we should have found this in phase 1!
+ // If this is a type 3 search _UA_FORCE_UNWIND, ignore handler and continue scan
+ if ((actions & _UA_SEARCH_PHASE) || (actions & _UA_HANDLER_FRAME))
+ {
+ // Save state and return _URC_HANDLER_FOUND
+ results.ttypeIndex = ttypeIndex;
+ results.actionRecord = actionRecord;
+ results.landingPad = landingPad;
+ results.adjustedPtr = get_thrown_object_ptr(unwind_exception);
+ results.reason = _URC_HANDLER_FOUND;
+ return;
+ }
+ else if (!(actions & _UA_FORCE_UNWIND))
+ {
+ // It looks like the exception table has changed
+ // on us. Likely stack corruption!
+ call_terminate(native_exception, unwind_exception);
+ }
+ }
+ // Scan next action ...
+ }
+ else // ttypeIndex == 0
+ {
+ // Found a cleanup
+ // If this is a type 1 search, ignore it and continue scan
+ // If this is a type 2 search, ignore it and continue scan
+ // If this is a type 3 search, save state and return _URC_HANDLER_FOUND
+ if ((actions & _UA_CLEANUP_PHASE) && !(actions & _UA_HANDLER_FRAME))
+ {
+ // Save state and return _URC_HANDLER_FOUND
+ results.ttypeIndex = ttypeIndex;
+ results.actionRecord = actionRecord;
+ results.landingPad = landingPad;
+ results.adjustedPtr = get_thrown_object_ptr(unwind_exception);
+ results.reason = _URC_HANDLER_FOUND;
+ return;
+ }
+ }
+ const uint8_t* temp = action;
+ int64_t actionOffset = readSLEB128(&temp);
+ if (actionOffset == 0)
+ {
+ // End of action list, no matching handler or cleanup found
+ // If this is a type 2 search, phase 1 told us we would find
+ // a handler and we didn't. Something has gone terribly wrong.
+ // Searches type 1 and 3 should return _URC_CONTINUE_UNWIND
+ if (actions & _UA_HANDLER_FRAME)
+ call_terminate(native_exception, unwind_exception);
+ results.reason = _URC_CONTINUE_UNWIND;
+ return;
+ }
+ // Go to next action
+ action += actionOffset;
+ } // there is no break out of this loop, only return
}
- // Not found, need to properly terminate
- }
- return false;
-}
-
-static
-_Unwind_Reason_Code
-transfer_control_to_landing_pad(_Unwind_Exception* unwind_exception,
- _Unwind_Context* context)
-{
- __cxa_exception* exception_header = (__cxa_exception*)(unwind_exception+1) - 1;
- _Unwind_SetGR(context, __builtin_eh_return_data_regno(0), (uintptr_t)unwind_exception);
- _Unwind_SetGR(context, __builtin_eh_return_data_regno(1), exception_header->handlerSwitchValue);
- _Unwind_SetIP(context, (uintptr_t)exception_header->catchTemp);
- return _URC_INSTALL_CONTEXT;
-}
-
-static
-_Unwind_Reason_Code
-perform_cleanup(_Unwind_Exception* unwind_exception, _Unwind_Context* context)
-{
- __cxa_exception* exception_header = (__cxa_exception*)(unwind_exception+1) - 1;
- _Unwind_SetGR(context, __builtin_eh_return_data_regno(0), (uintptr_t)unwind_exception);
- _Unwind_SetGR(context, __builtin_eh_return_data_regno(1), 0);
- _Unwind_SetIP(context, (uintptr_t)exception_header->catchTemp);
- return _URC_INSTALL_CONTEXT;
+ else if (ipOffset < start)
+ {
+ // There is no call site for this ip
+ // Something bad has happened. We should never get here.
+ // Possible stack corruption.
+ call_terminate(native_exception, unwind_exception);
+ }
+ } // there is no break out of this loop, only return
}
// public API
@@ -644,558 +777,58 @@ _Unwind_Reason_Code
__gxx_personality_v0(int version, _Unwind_Action actions, uint64_t exceptionClass,
_Unwind_Exception* unwind_exception, _Unwind_Context* context)
{
-printf("__gxx_personality_v0 start with unwind_exception = %p\n", unwind_exception);
if (version != 1 || unwind_exception == 0 || context == 0)
return _URC_FATAL_PHASE1_ERROR;
bool native_exception = (exceptionClass & get_language) ==
(kOurExceptionClass & get_language);
+ scan_results results;
if (actions & _UA_SEARCH_PHASE)
{
-printf("__gxx_personality_v0 start phase 1\n");
- // Do Phase 1
- if (actions & (_UA_CLEANUP_PHASE | _UA_HANDLER_FRAME | _UA_FORCE_UNWIND))
- {
- // None of these flags should be set during Phase 1
- return _URC_FATAL_PHASE1_ERROR;
- }
- // Scan for handlers
- // If a handler is found return _URC_HANDLER_FOUND else return _URC_CONTINUE_UNWIND
- const uint8_t* lsda = (const uint8_t*)_Unwind_GetLanguageSpecificData(context);
- if (lsda == 0)
+ scan_eh_tab(results, actions, native_exception, unwind_exception, context);
+ if (results.reason == _URC_HANDLER_FOUND)
{
- // No LanguageSpecificData means no handlers
-printf("__gxx_personality_v0 phase 1 no lsda, returning _URC_CONTINUE_UNWIND\n");
- return _URC_CONTINUE_UNWIND;
- }
- const uint8_t* languageSpecificData = lsda;
- // Get the current instruction pointer and offset it before next
- // instruction in the current frame which threw the exception.
- uintptr_t ip = _Unwind_GetIP(context) - 1;
- // Get beginning current frame's code (as defined by the
- // emitted dwarf code)
- uintptr_t funcStart = _Unwind_GetRegionStart(context);
- uintptr_t ipOffset = ip - funcStart;
- const uint8_t* classInfo = NULL;
- // Note: See JITDwarfEmitter::EmitExceptionTable(...) for corresponding
- // dwarf emission
- // Parse LSDA header.
- uint8_t lpStartEncoding = *lsda++;
- const uint8_t* lpStart = (const uint8_t*)readEncodedPointer(&lsda, lpStartEncoding);
- if (lpStart == 0)
- lpStart = (const uint8_t*)funcStart;
- uint8_t ttypeEncoding = *lsda++;
- if (ttypeEncoding != DW_EH_PE_omit)
- {
- // Calculate type info locations in emitted dwarf code which
- // were flagged by type info arguments to llvm.eh.selector
- // intrinsic
- uintptr_t classInfoOffset = readULEB128(&lsda);
- classInfo = lsda + classInfoOffset;
- }
- // Walk call-site table looking for range that
- // includes current PC.
- uint8_t callSiteEncoding = *lsda++;
- uint32_t callSiteTableLength = readULEB128(&lsda);
- const uint8_t* callSiteTableStart = lsda;
- const uint8_t* callSiteTableEnd = callSiteTableStart + callSiteTableLength;
- const uint8_t* actionTableStart = callSiteTableEnd;
- const uint8_t* callSitePtr = callSiteTableStart;
- while (true)
- {
- // There is one entry per call site.
- // The call sites are non-overlapping in [start, start+length)
- // The call sites are ordered in increasing value of start
- uintptr_t start = readEncodedPointer(&callSitePtr, callSiteEncoding);
- uintptr_t length = readEncodedPointer(&callSitePtr, callSiteEncoding);
- uintptr_t landingPad = readEncodedPointer(&callSitePtr, callSiteEncoding);
- uintptr_t actionEntry = readULEB128(&callSitePtr);
- if ((start <= ipOffset) && (ipOffset < (start + length)))
- {
- // Found the call site containing ip.
- if (landingPad == 0 || actionEntry == 0)
- {
- // No handler here
- printf("__gxx_personality_v0 phase 1 no landingPad or no actionEntry, returning _URC_CONTINUE_UNWIND\n");
- return _URC_CONTINUE_UNWIND;
- }
- // Convert 1-based byte offset into
- const uint8_t* action = actionTableStart + (actionEntry - 1);
- // Scan action entries until you find a matching handler, or they end
- while (true)
- {
- const uint8_t* actionRecord = action;
- int64_t ttypeIndex = readSLEB128(&action);
- const uint8_t* temp = action;
- int64_t actionOffset = readSLEB128(&temp);
- if (ttypeIndex > 0)
- {
- // Does this handler match?
- // First check for catch (...)
- const __shim_type_info* catchType =
- get_shim_type_info(ttypeIndex, classInfo,
- ttypeEncoding, native_exception,
- unwind_exception);
- if (catchType == 0)
- {
- // catch (...) catches everything, including foreign exceptions
- // If not foreign, safe state before returning
- if (native_exception)
- {
- __cxa_exception* exception_header = (__cxa_exception*)(unwind_exception+1) - 1;
- void* adjustedPtr =
- unwind_exception->exception_class == kOurDependentExceptionClass ?
- ((__cxa_dependent_exception*)exception_header)->primaryException :
- exception_header + 1;
- save_state(exception_header, static_cast<int>(ttypeIndex),
- actionRecord, languageSpecificData,
- const_cast<uint8_t*>(lpStart + landingPad),
- adjustedPtr);
- }
- printf("__gxx_personality_v0 phase 1 catch (...), returning _URC_HANDLER_FOUND\n");
- return _URC_HANDLER_FOUND;
- }
- // Else this is a catch (T) clause and will never
- // catch a foreign exception
- if (native_exception)
- {
- __cxa_exception* exception_header = (__cxa_exception*)(unwind_exception+1) - 1;
- void* adjustedPtr =
- unwind_exception->exception_class == kOurDependentExceptionClass ?
- ((__cxa_dependent_exception*)exception_header)->primaryException :
- exception_header + 1;
- const __shim_type_info* excpType =
- static_cast<const __shim_type_info*>(exception_header->exceptionType);
- if (adjustedPtr == 0 || excpType == 0)
- {
- // Something very bad happened
- call_terminate(native_exception, unwind_exception);
- }
- if (catchType->can_catch(excpType, adjustedPtr))
- {
- // Found a matching handler
- save_state(exception_header, static_cast<int>(ttypeIndex),
- actionRecord, languageSpecificData,
- const_cast<uint8_t*>(lpStart + landingPad),
- adjustedPtr);
- printf("__gxx_personality_v0 phase 1 catch (T), returning _URC_HANDLER_FOUND\n");
- return _URC_HANDLER_FOUND;
- }
- }
- // Scan next action ...
- }
- else if (ttypeIndex < 0)
- {
- // Found an exception spec. If this is a foreign exception,
- // it is always caught.
- if (!native_exception)
- {
- printf("__gxx_personality_v0 phase 1 exception spec for foreign, returning _URC_HANDLER_FOUND\n");
- return _URC_HANDLER_FOUND;
- }
- __cxa_exception* exception_header = (__cxa_exception*)(unwind_exception+1) - 1;
- void* adjustedPtr =
- unwind_exception->exception_class == kOurDependentExceptionClass ?
- ((__cxa_dependent_exception*)exception_header)->primaryException :
- exception_header + 1;
- const __shim_type_info* excpType =
- static_cast<const __shim_type_info*>(exception_header->exceptionType);
- if (adjustedPtr == 0 || excpType == 0)
- {
- // Something very bad happened
- call_terminate(native_exception, unwind_exception);
- }
- if (exception_spec_can_catch(ttypeIndex, classInfo,
- ttypeEncoding, excpType,
- adjustedPtr, unwind_exception))
- {
- // The state saved is a little different for exception specs
- save_state(exception_header,
- ttypeIndex,
- actionRecord,
- languageSpecificData,
- const_cast<uint8_t*>(lpStart + landingPad),
- adjustedPtr);
- printf("__gxx_personality_v0 phase 1 exception spec for native, returning _URC_HANDLER_FOUND\n");
- return _URC_HANDLER_FOUND;
- }
- // Scan next action ...
- }
- if (actionOffset == 0)
- {
- // End of action list, no matching handler found
- printf("__gxx_personality_v0 phase 1 no handler found, returning _URC_CONTINUE_UNWIND\n");
- return _URC_CONTINUE_UNWIND;
- }
- // Go to next action
- action += actionOffset;
- }
- }
- else if (ipOffset < start)
+ if (native_exception)
{
- // There is no call site for this ip
- // Something bad has happened. We should never get here.
- // Possible stack corruption.
- call_terminate(native_exception, unwind_exception);
+ __cxa_exception* exception_header = (__cxa_exception*)(unwind_exception+1) - 1;
+ exception_header->handlerSwitchValue = static_cast<int>(results.ttypeIndex);
+ exception_header->actionRecord = results.actionRecord;
+ exception_header->languageSpecificData = results.languageSpecificData;
+ exception_header->catchTemp = reinterpret_cast<void*>(results.landingPad);
+ exception_header->adjustedPtr = results.adjustedPtr;
}
+ return _URC_HANDLER_FOUND;
}
+ return results.reason;
}
if (actions & _UA_CLEANUP_PHASE)
{
if (actions & _UA_HANDLER_FRAME)
{
-printf("__gxx_personality_v0 start phase 2 handling\n");
- // Search phase found a handler, now install it
- if (actions & _UA_FORCE_UNWIND)
- {
- // This should never happen. The search phase isn't executed
- // for forced unwinding, so no handler could have been found.
- call_terminate(native_exception, unwind_exception);
- }
- // This is the state we need:
- uintptr_t handlerSwitchValue;
- uintptr_t landingPad;
if (native_exception)
{
- // Just retrieve it from the exception_header
__cxa_exception* exception_header = (__cxa_exception*)(unwind_exception+1) - 1;
- handlerSwitchValue = static_cast<uintptr_t>(static_cast<intptr_t>(exception_header->handlerSwitchValue));
- landingPad = reinterpret_cast<uintptr_t>(exception_header->catchTemp);
+ results.ttypeIndex = exception_header->handlerSwitchValue;
+ results.actionRecord = exception_header->actionRecord;
+ results.languageSpecificData = exception_header->languageSpecificData;
+ results.landingPad = reinterpret_cast<uintptr_t>(exception_header->catchTemp);
+ results.adjustedPtr = exception_header->adjustedPtr;
}
else
- {
- // Else a foreign exception, we need to find the handler that caught it
- const uint8_t* lsda = (const uint8_t*)_Unwind_GetLanguageSpecificData(context);
- if (lsda == 0)
- {
- // If we don't find a handler, something bad happened
- call_terminate(native_exception, unwind_exception);
- }
- // Get the current instruction pointer and offset it before next
- // instruction in the current frame which threw the exception.
- uintptr_t ip = _Unwind_GetIP(context) - 1;
- // Get beginning current frame's code (as defined by the
- // emitted dwarf code)
- uintptr_t funcStart = _Unwind_GetRegionStart(context);
- uintptr_t ipOffset = ip - funcStart;
- const uint8_t* classInfo = NULL;
- // Note: See JITDwarfEmitter::EmitExceptionTable(...) for corresponding
- // dwarf emission
- // Parse LSDA header.
- uint8_t lpStartEncoding = *lsda++;
- const uint8_t* lpStart = (const uint8_t*)readEncodedPointer(&lsda, lpStartEncoding);
- if (lpStart == 0)
- lpStart = (const uint8_t*)funcStart;
- uint8_t ttypeEncoding = *lsda++;
- if (ttypeEncoding != DW_EH_PE_omit)
- {
- // Calculate type info locations in emitted dwarf code which
- // were flagged by type info arguments to llvm.eh.selector
- // intrinsic
- uintptr_t classInfoOffset = readULEB128(&lsda);
- classInfo = lsda + classInfoOffset;
- }
- // Walk call-site table looking for range that
- // includes current PC.
- uint8_t callSiteEncoding = *lsda++;
- uint32_t callSiteTableLength = readULEB128(&lsda);
- const uint8_t* callSiteTableStart = lsda;
- const uint8_t* callSiteTableEnd = callSiteTableStart + callSiteTableLength;
- const uint8_t* actionTableStart = callSiteTableEnd;
- const uint8_t* callSitePtr = callSiteTableStart;
- while (true)
- {
- // There is one entry per call site.
- // The call sites are non-overlapping in [start, start+length)
- // The call sites are ordered in increasing value of start
- uintptr_t start = readEncodedPointer(&callSitePtr, callSiteEncoding);
- uintptr_t length = readEncodedPointer(&callSitePtr, callSiteEncoding);
- landingPad = readEncodedPointer(&callSitePtr, callSiteEncoding);
- uintptr_t actionEntry = readULEB128(&callSitePtr);
- if ((start <= ipOffset) && (ipOffset < (start + length)))
- {
- // Found the call site containing ip.
- if (landingPad == 0 || actionEntry == 0)
- {
- // No handler here
- // If we don't find a handler, something bad happened
- call_terminate(native_exception, unwind_exception);
- }
- landingPad = (uintptr_t)lpStart + landingPad;
- // Convert 1-based byte offset into
- const uint8_t* action = actionTableStart + (actionEntry - 1);
- // Scan action entries until you find a matching handler, or they end
- while (true)
- {
- int64_t ttypeIndex = readSLEB128(&action);
- const uint8_t* temp = action;
- int64_t actionOffset = readSLEB128(&temp);
- if (ttypeIndex > 0)
- {
- // Does this handler match?
- // First check for catch (...)
- const __shim_type_info* catchType =
- get_shim_type_info(ttypeIndex, classInfo,
- ttypeEncoding, native_exception,
- unwind_exception);
- if (catchType == 0)
- {
- // catch (...) catches everything, including foreign exceptions
- handlerSwitchValue = ttypeIndex;
- goto install_handler;
- }
- // Else this is a catch (T) clause and will never
- // catch a foreign exception
- // Scan next action ...
- }
- else if (ttypeIndex < 0)
- {
- // Found an exception spec. This is a foreign exception,
- // and thus is always caught.
- // However the landing pad is going to call either
- // __cxa_call_unexpected (for a throw spec) or
- // std::terminate (for noexcept). We
- // don't know which. And __cxa_call_unexpected
- // lacks the API to recover ttypeIndex. However
- // if we were to call a variant of __cxa_call_unexpected
- // from here, and if it throws an exception,
- // that won't work either. We can't propagate
- // an exception out of here. So just call
- // the landing pad and let __cxa_call_unexpected
- // force terminate. There's nothing else we
- // can do.
- handlerSwitchValue = ttypeIndex;
- goto install_handler;
- }
- if (actionOffset == 0)
- {
- // End of action list, no matching handler found
- // If we don't find a handler, something bad happened
- call_terminate(native_exception, unwind_exception);
- }
- // Go to next action
- action += actionOffset;
- }
- }
- else if (ipOffset < start)
- {
- // There is no call site for this ip
- // Something bad has happened. We should never get here.
- // Possible stack corruption.
- call_terminate(native_exception, unwind_exception);
- }
- }
- }
- install_handler:
+ scan_eh_tab(results, actions, native_exception, unwind_exception, context);
_Unwind_SetGR(context, __builtin_eh_return_data_regno(0), (uintptr_t)unwind_exception);
- _Unwind_SetGR(context, __builtin_eh_return_data_regno(1), handlerSwitchValue);
- _Unwind_SetIP(context, landingPad);
- printf("__gxx_personality_v0 phase 2 handler found, returning _URC_INSTALL_CONTEXT\n");
+ _Unwind_SetGR(context, __builtin_eh_return_data_regno(1), results.ttypeIndex);
+ _Unwind_SetIP(context, results.landingPad);
return _URC_INSTALL_CONTEXT;
}
-printf("__gxx_personality_v0 start phase 2 cleanup\n");
- // Else scan for a cleanup.
- // If handler found and !_UA_FORCE_UNWIND, terminate.
- // If cleanup found, install it.
- // If nothing found return _URC_CONTINUE_UNWIND
- const uint8_t* lsda = (const uint8_t*)_Unwind_GetLanguageSpecificData(context);
- if (lsda == 0)
+ scan_eh_tab(results, actions, native_exception, unwind_exception, context);
+ if (results.reason == _URC_HANDLER_FOUND)
{
- // No LanguageSpecificData means no handlers
- printf("__gxx_personality_v0 phase 2 no lsda, returning _URC_CONTINUE_UNWIND\n");
- return _URC_CONTINUE_UNWIND;
- }
- // Get the current instruction pointer and offset it before next
- // instruction in the current frame which threw the exception.
- uintptr_t ip = _Unwind_GetIP(context) - 1;
- // Get beginning current frame's code (as defined by the
- // emitted dwarf code)
- uintptr_t funcStart = _Unwind_GetRegionStart(context);
- uintptr_t ipOffset = ip - funcStart;
- const uint8_t* classInfo = NULL;
- // Note: See JITDwarfEmitter::EmitExceptionTable(...) for corresponding
- // dwarf emission
- // Parse LSDA header.
- uint8_t lpStartEncoding = *lsda++;
- const uint8_t* lpStart = (const uint8_t*)readEncodedPointer(&lsda, lpStartEncoding);
- if (lpStart == 0)
- lpStart = (const uint8_t*)funcStart;
- uint8_t ttypeEncoding = *lsda++;
- if (ttypeEncoding != DW_EH_PE_omit)
- {
- // Calculate type info locations in emitted dwarf code which
- // were flagged by type info arguments to llvm.eh.selector
- // intrinsic
- uintptr_t classInfoOffset = readULEB128(&lsda);
- classInfo = lsda + classInfoOffset;
- }
- // Walk call-site table looking for range that
- // includes current PC.
- uint8_t callSiteEncoding = *lsda++;
- uint32_t callSiteTableLength = readULEB128(&lsda);
- const uint8_t* callSiteTableStart = lsda;
- const uint8_t* callSiteTableEnd = callSiteTableStart + callSiteTableLength;
- const uint8_t* actionTableStart = callSiteTableEnd;
- const uint8_t* callSitePtr = callSiteTableStart;
- while (true)
- {
- // There is one entry per call site.
- // The call sites are non-overlapping in [start, start+length)
- // The call sites are ordered in increasing value of start
- uintptr_t start = readEncodedPointer(&callSitePtr, callSiteEncoding);
- uintptr_t length = readEncodedPointer(&callSitePtr, callSiteEncoding);
- uintptr_t landingPad = readEncodedPointer(&callSitePtr, callSiteEncoding);
- uintptr_t actionEntry = readULEB128(&callSitePtr);
- if ((start <= ipOffset) && (ipOffset < (start + length)))
- {
- // Found the call site containing ip.
- if (landingPad == 0)
- {
- // No handler here
- printf("__gxx_personality_v0 phase 2 no landingPad, returning _URC_CONTINUE_UNWIND\n");
- return _URC_CONTINUE_UNWIND;
- }
- landingPad = (uintptr_t)lpStart + landingPad;
- if (actionEntry == 0)
- {
- // Found a cleanup, install it:
- _Unwind_SetGR(context, __builtin_eh_return_data_regno(0), (uintptr_t)unwind_exception);
- _Unwind_SetGR(context, __builtin_eh_return_data_regno(1), 0);
- _Unwind_SetIP(context, landingPad);
- printf("__gxx_personality_v0 phase 2 found cleanup 1, returning _URC_INSTALL_CONTEXT\n");
- return _URC_INSTALL_CONTEXT;
- }
- // Convert 1-based byte offset into
- const uint8_t* action = actionTableStart + (actionEntry - 1);
- // Scan action entries until you find a matching handler, or they end
- while (true)
- {
- int64_t ttypeIndex = readSLEB128(&action);
- const uint8_t* temp = action;
- int64_t actionOffset = readSLEB128(&temp);
- if (ttypeIndex > 0)
- {
- // Does this handler match?
- // First check for catch (...)
- const __shim_type_info* catchType =
- get_shim_type_info(ttypeIndex, classInfo,
- ttypeEncoding, native_exception,
- unwind_exception);
- if (catchType == 0)
- {
- // catch (...) catches everything, including foreign exceptions
- if (!(actions & _UA_FORCE_UNWIND))
- {
- // Something bad has happened. We should never get here.
- // We should have found this handler in phase 1
- // Possible stack corruption.
- call_terminate(native_exception, unwind_exception);
- }
- // Ignoring this handler because we are forced
- }
- else
- {
- // Else this is a catch (T) clause and will never
- // catch a foreign exception
- if (native_exception)
- {
- __cxa_exception* exception_header = (__cxa_exception*)(unwind_exception+1) - 1;
- void* adjustedPtr =
- unwind_exception->exception_class == kOurDependentExceptionClass ?
- ((__cxa_dependent_exception*)exception_header)->primaryException :
- exception_header + 1;
- const __shim_type_info* excpType =
- static_cast<const __shim_type_info*>(exception_header->exceptionType);
- if (adjustedPtr == 0 || excpType == 0)
- {
- // Something very bad happened
- call_terminate(native_exception, unwind_exception);
- }
- if (catchType->can_catch(excpType, adjustedPtr))
- {
- // Found a matching handler
- if (!(actions & _UA_FORCE_UNWIND))
- {
- // Something bad has happened. We should never get here.
- // We should have found this handler in phase 1
- // Possible stack corruption.
- call_terminate(native_exception, unwind_exception);
- }
- // Ignoring this handler because we are forced
- }
- }
- }
- // Scan next action ...
- }
- else if (ttypeIndex < 0)
- {
- // Found an exception spec. If this is a foreign exception,
- // it is always caught.
- if (!native_exception)
- {
- if (!(actions & _UA_FORCE_UNWIND))
- {
- // Something bad has happened. We should never get here.
- // We should have found this handler in phase 1
- // Possible stack corruption.
- call_terminate(native_exception, unwind_exception);
- }
- }
- else
- {
- __cxa_exception* exception_header = (__cxa_exception*)(unwind_exception+1) - 1;
- void* adjustedPtr =
- unwind_exception->exception_class == kOurDependentExceptionClass ?
- ((__cxa_dependent_exception*)exception_header)->primaryException :
- exception_header + 1;
- const __shim_type_info* excpType =
- static_cast<const __shim_type_info*>(exception_header->exceptionType);
- if (adjustedPtr == 0 || excpType == 0)
- {
- // Something very bad happened
- call_terminate(native_exception, unwind_exception);
- }
- if (exception_spec_can_catch(ttypeIndex, classInfo,
- ttypeEncoding, excpType,
- adjustedPtr, unwind_exception))
- {
- if (!(actions & _UA_FORCE_UNWIND))
- {
- // Something bad has happened. We should never get here.
- // We should have found this handler in phase 1
- // Possible stack corruption.
- call_terminate(native_exception, unwind_exception);
- }
- }
- }
- // Scan next action ...
- }
- else // ttypeIndex == 0
- {
- // Found a cleanup, install it:
- _Unwind_SetGR(context, __builtin_eh_return_data_regno(0), (uintptr_t)unwind_exception);
- _Unwind_SetGR(context, __builtin_eh_return_data_regno(1), 0);
- _Unwind_SetIP(context, landingPad);
- printf("__gxx_personality_v0 phase 2 found cleanup 2, returning _URC_INSTALL_CONTEXT\n");
- return _URC_INSTALL_CONTEXT;
- }
- if (actionOffset == 0)
- {
- // End of action list, no matching handler or cleanup found
- printf("__gxx_personality_v0 phase 2 found no cleanups, returning _URC_CONTINUE_UNWIND\n");
- return _URC_CONTINUE_UNWIND;
- }
- // Go to next action
- action += actionOffset;
- }
- }
- else if (ipOffset < start)
- {
- // There is no call site for this ip
- // Something bad has happened. We should never get here.
- // Possible stack corruption.
- call_terminate(native_exception, unwind_exception);
- }
+ _Unwind_SetGR(context, __builtin_eh_return_data_regno(0), (uintptr_t)unwind_exception);
+ _Unwind_SetGR(context, __builtin_eh_return_data_regno(1), results.ttypeIndex);
+ _Unwind_SetIP(context, results.landingPad);
+ return _URC_INSTALL_CONTEXT;
}
+ return results.reason;
}
// Neither _UA_SEARCH_PHASE nor _UA_CLEANUP_PHASE
return _URC_FATAL_PHASE1_ERROR;
@@ -1205,7 +838,6 @@ __attribute__((noreturn))
void
__cxa_call_unexpected(void* arg)
{
-printf("__cxa_call_unexpected A\n");
_Unwind_Exception* unwind_exception = static_cast<_Unwind_Exception*>(arg);
if (unwind_exception == 0)
call_terminate(true, unwind_exception);
@@ -1321,56 +953,6 @@ printf("__cxa_call_unexpected A\n");
std::__terminate(t_handler);
}
-/*
-_Unwind_Reason_Code
-__gxx_personality_v0(int version, _Unwind_Action actions, uint64_t exceptionClass,
- _Unwind_Exception* unwind_exception, _Unwind_Context* context)
-{
- if (version == 1 && unwind_exception != 0 && context != 0)
- {
- bool native_exception = (exceptionClass & 0xFFFFFF00) == 0x432B2B00;
- bool force_unwind = actions & _UA_FORCE_UNWIND;
- if (native_exception && !force_unwind)
- {
- if (actions & _UA_SEARCH_PHASE)
- {
- if (actions & _UA_CLEANUP_PHASE)
- return _URC_FATAL_PHASE1_ERROR;
- if (contains_handler(unwind_exception, context))
- return _URC_HANDLER_FOUND;
- return _URC_CONTINUE_UNWIND;
- }
- if (actions & _UA_CLEANUP_PHASE)
- {
- if (actions & _UA_HANDLER_FRAME)
- {
- // return _URC_INSTALL_CONTEXT or _URC_FATAL_PHASE2_ERROR
- return transfer_control_to_landing_pad(unwind_exception, context);
- }
- // return _URC_CONTINUE_UNWIND or _URC_FATAL_PHASE2_ERROR
- return perform_cleanup(unwind_exception, context);
- }
- }
- else // foreign exception or force_unwind
- {
- if (actions & _UA_SEARCH_PHASE)
- {
- if (actions & _UA_CLEANUP_PHASE)
- return _URC_FATAL_PHASE1_ERROR;
- return _URC_CONTINUE_UNWIND;
- }
- if (actions & _UA_CLEANUP_PHASE)
- {
- if (actions & _UA_HANDLER_FRAME)
- return _URC_FATAL_PHASE2_ERROR;
- // return _URC_CONTINUE_UNWIND or _URC_FATAL_PHASE2_ERROR
- return perform_cleanup(unwind_exception, context);
- }
- }
- }
- return _URC_FATAL_PHASE1_ERROR;
-}
-*/
} // extern "C"
} // __cxxabiv1
OpenPOWER on IntegriCloud