diff options
author | Chris Lattner <sabre@nondot.org> | 2011-04-08 18:02:51 +0000 |
---|---|---|
committer | Chris Lattner <sabre@nondot.org> | 2011-04-08 18:02:51 +0000 |
commit | 626ab1ccad703deefd386fc732d875f8e1319edb (patch) | |
tree | 5bf12e8b80c18df06023865071d6982ea28164dc /examples | |
parent | cad3f77fa8618ac940aa519cd40c403800977273 (diff) |
reindent this whole file and do a variety of stylistic cleanups.
This code is still a long way from following best practices.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@129140 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'examples')
-rw-r--r-- | examples/ExceptionDemo/ExceptionDemo.cpp | 2822 |
1 files changed, 1400 insertions, 1422 deletions
diff --git a/examples/ExceptionDemo/ExceptionDemo.cpp b/examples/ExceptionDemo/ExceptionDemo.cpp index e4fd0dbe49..f2203a72b6 100644 --- a/examples/ExceptionDemo/ExceptionDemo.cpp +++ b/examples/ExceptionDemo/ExceptionDemo.cpp @@ -1,12 +1,11 @@ -//===-- examples/ExceptionDemo/ExceptionDemo.cpp - -// An example use of the llvm Exception mechanism --===// +//===-- ExceptionDemo.cpp - An example using llvm Exceptions --------------===// // // The LLVM Compiler Infrastructure // // This file is distributed under the University of Illinois Open Source // License. See LICENSE.TXT for details. // -//===--------------------------------------------------------------------===// +//===----------------------------------------------------------------------===// // // Demo program which implements an example LLVM exception implementation, and // shows several test cases including the handling of foreign exceptions. @@ -46,8 +45,7 @@ // This code uses code from the llvm compiler-rt project and the llvm // Kaleidoscope project. // -//===--------------------------------------------------------------------===// - +//===----------------------------------------------------------------------===// #include "llvm/LLVMContext.h" #include "llvm/DerivedTypes.h" @@ -64,11 +62,7 @@ #include "llvm/Support/IRBuilder.h" #include "llvm/Support/Dwarf.h" -#include <cstdio> -#include <string> #include <sstream> -#include <map> -#include <vector> #include <stdexcept> @@ -80,8 +74,8 @@ // http://refspecs.freestandards.org/abi-eh-1.21.html extern "C" { - -typedef enum { + + typedef enum { _URC_NO_REASON = 0, _URC_FOREIGN_EXCEPTION_CAUGHT = 1, _URC_FATAL_PHASE2_ERROR = 2, @@ -91,43 +85,43 @@ typedef enum { _URC_HANDLER_FOUND = 6, _URC_INSTALL_CONTEXT = 7, _URC_CONTINUE_UNWIND = 8 -} _Unwind_Reason_Code; - -typedef enum { + } _Unwind_Reason_Code; + + typedef enum { _UA_SEARCH_PHASE = 1, _UA_CLEANUP_PHASE = 2, _UA_HANDLER_FRAME = 4, _UA_FORCE_UNWIND = 8, _UA_END_OF_STACK = 16 -} _Unwind_Action; - -struct _Unwind_Exception; - -typedef void (*_Unwind_Exception_Cleanup_Fn) (_Unwind_Reason_Code, - struct _Unwind_Exception *); - -struct _Unwind_Exception { + } _Unwind_Action; + + struct _Unwind_Exception; + + typedef void (*_Unwind_Exception_Cleanup_Fn) (_Unwind_Reason_Code, + struct _Unwind_Exception *); + + struct _Unwind_Exception { uint64_t exception_class; _Unwind_Exception_Cleanup_Fn exception_cleanup; - + uintptr_t private_1; uintptr_t private_2; - + // @@@ The IA-64 ABI says that this structure must be double-word aligned. // Taking that literally does not make much sense generically. Instead // we provide the maximum alignment required by any type for the machine. -} __attribute__((__aligned__)); - -struct _Unwind_Context; -typedef struct _Unwind_Context* _Unwind_Context_t; - -extern const uint8_t* _Unwind_GetLanguageSpecificData (_Unwind_Context_t c); -extern uintptr_t _Unwind_GetGR (_Unwind_Context_t c, int i); -extern void _Unwind_SetGR (_Unwind_Context_t c, int i, uintptr_t n); -extern void _Unwind_SetIP (_Unwind_Context_t, uintptr_t new_value); -extern uintptr_t _Unwind_GetIP (_Unwind_Context_t context); -extern uintptr_t _Unwind_GetRegionStart (_Unwind_Context_t context); - + } __attribute__((__aligned__)); + + struct _Unwind_Context; + typedef struct _Unwind_Context* _Unwind_Context_t; + + extern const uint8_t* _Unwind_GetLanguageSpecificData (_Unwind_Context_t c); + extern uintptr_t _Unwind_GetGR (_Unwind_Context_t c, int i); + extern void _Unwind_SetGR (_Unwind_Context_t c, int i, uintptr_t n); + extern void _Unwind_SetIP (_Unwind_Context_t, uintptr_t new_value); + extern uintptr_t _Unwind_GetIP (_Unwind_Context_t context); + extern uintptr_t _Unwind_GetRegionStart (_Unwind_Context_t context); + } // extern "C" // @@ -136,8 +130,8 @@ extern uintptr_t _Unwind_GetRegionStart (_Unwind_Context_t context); /// This is our simplistic type info struct OurExceptionType_t { - /// type info type - int type; + /// type info type + int type; }; @@ -148,10 +142,10 @@ struct OurExceptionType_t { /// on a double word boundary. This is necessary to match the standard: /// http://refspecs.freestandards.org/abi-eh-1.21.html struct OurBaseException_t { - struct OurExceptionType_t type; - - // Note: This is properly aligned in unwind.h - struct _Unwind_Exception unwindException; + struct OurExceptionType_t type; + + // Note: This is properly aligned in unwind.h + struct _Unwind_Exception unwindException; }; @@ -169,7 +163,7 @@ static std::map<std::string, llvm::Value*> namedValues; int64_t ourBaseFromUnwindOffset; const unsigned char ourBaseExcpClassChars[] = - {'o', 'b', 'j', '\0', 'b', 'a', 's', '\0'}; +{'o', 'b', 'j', '\0', 'b', 'a', 's', '\0'}; static uint64_t ourBaseExceptionClass = 0; @@ -212,27 +206,24 @@ llvm::Function *createFunction(llvm::Module& module, llvm::GlobalValue::LinkageTypes linkage, bool declarationOnly, bool isVarArg) { - llvm::FunctionType* functType = llvm::FunctionType::get(retType, - theArgTypes, - isVarArg); - llvm::Function* ret = llvm::Function::Create(functType, - linkage, - functName, - &module); - if (!ret || declarationOnly) - return(ret); - - namedValues.clear(); - unsigned i = 0; - for (llvm::Function::arg_iterator argIndex = ret->arg_begin(); - i != theArgNames.size(); - ++argIndex, ++i) { - - argIndex->setName(theArgNames[i]); - namedValues[theArgNames[i]] = argIndex; - } - + llvm::FunctionType *functType = + llvm::FunctionType::get(retType, theArgTypes, isVarArg); + llvm::Function *ret = + llvm::Function::Create(functType, linkage, functName, &module); + if (!ret || declarationOnly) return(ret); + + namedValues.clear(); + unsigned i = 0; + for (llvm::Function::arg_iterator argIndex = ret->arg_begin(); + i != theArgNames.size(); + ++argIndex, ++i) { + + argIndex->setName(theArgNames[i]); + namedValues[theArgNames[i]] = argIndex; + } + + return(ret); } @@ -244,17 +235,17 @@ llvm::Function *createFunction(llvm::Module& module, /// @param initWith optional constant initialization value /// @returns AllocaInst instance static llvm::AllocaInst *createEntryBlockAlloca(llvm::Function& function, - const std::string &varName, - const llvm::Type* type, - llvm::Constant* initWith = NULL) { - llvm::BasicBlock& block = function.getEntryBlock(); - llvm::IRBuilder<> tmp(&block, block.begin()); - llvm::AllocaInst* ret = tmp.CreateAlloca(type, 0, varName.c_str()); - - if (initWith) - tmp.CreateStore(initWith, ret); - - return(ret); + const std::string &varName, + const llvm::Type* type, + llvm::Constant* initWith = 0) { + llvm::BasicBlock& block = function.getEntryBlock(); + llvm::IRBuilder<> tmp(&block, block.begin()); + llvm::AllocaInst* ret = tmp.CreateAlloca(type, 0, varName.c_str()); + + if (initWith) + tmp.CreateStore(initWith, ret); + + return(ret); } @@ -275,14 +266,14 @@ extern "C" { /// @param intToPrint integer to print /// @param format printf like format to use when printing void print32Int(int intToPrint, const char* format) { - if (format) { - // Note: No NULL check - fprintf(stderr, format, intToPrint); - } - else { - // Note: No NULL check - fprintf(stderr, "::print32Int(...):NULL arg.\n"); - } + if (format) { + // Note: No NULL check + fprintf(stderr, format, intToPrint); + } + else { + // Note: No NULL check + fprintf(stderr, "::print32Int(...):NULL arg.\n"); + } } @@ -292,26 +283,26 @@ void print32Int(int intToPrint, const char* format) { /// @param intToPrint integer to print /// @param format printf like format to use when printing void print64Int(long int intToPrint, const char* format) { - if (format) { - // Note: No NULL check - fprintf(stderr, format, intToPrint); - } - else { - // Note: No NULL check - fprintf(stderr, "::print64Int(...):NULL arg.\n"); - } + if (format) { + // Note: No NULL check + fprintf(stderr, format, intToPrint); + } + else { + // Note: No NULL check + fprintf(stderr, "::print64Int(...):NULL arg.\n"); + } } /// Prints a C string to stderr /// @param toPrint string to print void printStr(char* toPrint) { - if (toPrint) { - fprintf(stderr, "%s", toPrint); - } - else { - fprintf(stderr, "::printStr(...):NULL arg.\n"); - } + if (toPrint) { + fprintf(stderr, "%s", toPrint); + } + else { + fprintf(stderr, "::printStr(...):NULL arg.\n"); + } } @@ -321,15 +312,15 @@ void printStr(char* toPrint) { /// @param expToDelete exception to delete void deleteOurException(OurUnwindException* expToDelete) { #ifdef DEBUG - fprintf(stderr, - "deleteOurException(...).\n"); + fprintf(stderr, + "deleteOurException(...).\n"); #endif - - if (expToDelete && - (expToDelete->exception_class == ourBaseExceptionClass)) { - - free(((char*) expToDelete) + ourBaseFromUnwindOffset); - } + + if (expToDelete && + (expToDelete->exception_class == ourBaseExceptionClass)) { + + free(((char*) expToDelete) + ourBaseFromUnwindOffset); + } } @@ -342,11 +333,11 @@ void deleteOurException(OurUnwindException* expToDelete) { void deleteFromUnwindOurException(_Unwind_Reason_Code reason, OurUnwindException* expToDelete) { #ifdef DEBUG - fprintf(stderr, - "deleteFromUnwindOurException(...).\n"); + fprintf(stderr, + "deleteFromUnwindOurException(...).\n"); #endif - - deleteOurException(expToDelete); + + deleteOurException(expToDelete); } @@ -354,13 +345,13 @@ void deleteFromUnwindOurException(_Unwind_Reason_Code reason, /// of the supplied type info type. /// @param type type info type OurUnwindException* createOurException(int type) { - size_t size = sizeof(OurException); - OurException* ret = (OurException*) memset(malloc(size), 0, size); - (ret->type).type = type; - (ret->unwindException).exception_class = ourBaseExceptionClass; - (ret->unwindException).exception_cleanup = deleteFromUnwindOurException; - - return(&(ret->unwindException)); + size_t size = sizeof(OurException); + OurException* ret = (OurException*) memset(malloc(size), 0, size); + (ret->type).type = type; + (ret->unwindException).exception_class = ourBaseExceptionClass; + (ret->unwindException).exception_cleanup = deleteFromUnwindOurException; + + return(&(ret->unwindException)); } @@ -370,21 +361,21 @@ OurUnwindException* createOurException(int type) { /// @param data reference variable holding memory pointer to decode from /// @returns decoded value static uintptr_t readULEB128(const uint8_t** data) { - uintptr_t result = 0; - uintptr_t shift = 0; - unsigned char byte; - const uint8_t* p = *data; - - do { - byte = *p++; - result |= (byte & 0x7f) << shift; - shift += 7; - } - while (byte & 0x80); - - *data = p; - - return result; + uintptr_t result = 0; + uintptr_t shift = 0; + unsigned char byte; + const uint8_t* p = *data; + + do { + byte = *p++; + result |= (byte & 0x7f) << shift; + shift += 7; + } + while (byte & 0x80); + + *data = p; + + return result; } @@ -394,25 +385,25 @@ static uintptr_t readULEB128(const uint8_t** data) { /// @param data reference variable holding memory pointer to decode from /// @returns decoded value static uintptr_t readSLEB128(const uint8_t** data) { - uintptr_t result = 0; - uintptr_t shift = 0; - unsigned char byte; - const uint8_t* p = *data; - - do { - byte = *p++; - result |= (byte & 0x7f) << shift; - shift += 7; - } - while (byte & 0x80); - - *data = p; - - if ((byte & 0x40) && (shift < (sizeof(result) << 3))) { - result |= (~0 << shift); - } - - return result; + uintptr_t result = 0; + uintptr_t shift = 0; + unsigned char byte; + const uint8_t* p = *data; + + do { + byte = *p++; + result |= (byte & 0x7f) << shift; + shift += 7; + } + while (byte & 0x80); + + *data = p; + + if ((byte & 0x40) && (shift < (sizeof(result) << 3))) { + result |= (~0 << shift); + } + + return result; } @@ -423,81 +414,81 @@ static uintptr_t readSLEB128(const uint8_t** data) { /// @param encoding dwarf encoding type /// @returns decoded value static uintptr_t readEncodedPointer(const uint8_t** data, uint8_t encoding) { - uintptr_t result = 0; - const uint8_t* p = *data; - - if (encoding == llvm::dwarf::DW_EH_PE_omit) - return(result); - - // first get value - switch (encoding & 0x0F) { - case llvm::dwarf::DW_EH_PE_absptr: - result = *((uintptr_t*)p); - p += sizeof(uintptr_t); - break; - case llvm::dwarf::DW_EH_PE_uleb128: - result = readULEB128(&p); - break; - // Note: This case has not been tested - case llvm::dwarf::DW_EH_PE_sleb128: - result = readSLEB128(&p); - break; - case llvm::dwarf::DW_EH_PE_udata2: - result = *((uint16_t*)p); - p += sizeof(uint16_t); - break; - case llvm::dwarf::DW_EH_PE_udata4: - result = *((uint32_t*)p); - p += sizeof(uint32_t); - break; - case llvm::dwarf::DW_EH_PE_udata8: - result = *((uint64_t*)p); - p += sizeof(uint64_t); - break; - case llvm::dwarf::DW_EH_PE_sdata2: - result = *((int16_t*)p); - p += sizeof(int16_t); - break; - case llvm::dwarf::DW_EH_PE_sdata4: - result = *((int32_t*)p); - p += sizeof(int32_t); - break; - case llvm::dwarf::DW_EH_PE_sdata8: - result = *((int64_t*)p); - p += sizeof(int64_t); - break; - default: - // not supported - abort(); - break; - } - - // then add relative offset - switch (encoding & 0x70) { - case llvm::dwarf::DW_EH_PE_absptr: - // do nothing - break; - case llvm::dwarf::DW_EH_PE_pcrel: - result += (uintptr_t)(*data); - break; - case llvm::dwarf::DW_EH_PE_textrel: - case llvm::dwarf::DW_EH_PE_datarel: - case llvm::dwarf::DW_EH_PE_funcrel: - case llvm::dwarf::DW_EH_PE_aligned: - default: - // not supported - abort(); - break; - } - - // then apply indirection - if (encoding & llvm::dwarf::DW_EH_PE_indirect) { - result = *((uintptr_t*)result); - } - - *data = p; - - return result; + uintptr_t result = 0; + const uint8_t* p = *data; + + if (encoding == llvm::dwarf::DW_EH_PE_omit) + return(result); + + // first get value + switch (encoding & 0x0F) { + case llvm::dwarf::DW_EH_PE_absptr: + result = *((uintptr_t*)p); + p += sizeof(uintptr_t); + break; + case llvm::dwarf::DW_EH_PE_uleb128: + result = readULEB128(&p); + break; + // Note: This case has not been tested + case llvm::dwarf::DW_EH_PE_sleb128: + result = readSLEB128(&p); + break; + case llvm::dwarf::DW_EH_PE_udata2: + result = *((uint16_t*)p); + p += sizeof(uint16_t); + break; + case llvm::dwarf::DW_EH_PE_udata4: + result = *((uint32_t*)p); + p += sizeof(uint32_t); + break; + case llvm::dwarf::DW_EH_PE_udata8: + result = *((uint64_t*)p); + p += sizeof(uint64_t); + break; + case llvm::dwarf::DW_EH_PE_sdata2: + result = *((int16_t*)p); + p += sizeof(int16_t); + break; + case llvm::dwarf::DW_EH_PE_sdata4: + result = *((int32_t*)p); + p += sizeof(int32_t); + break; + case llvm::dwarf::DW_EH_PE_sdata8: + result = *((int64_t*)p); + p += sizeof(int64_t); + break; + default: + // not supported + abort(); + break; + } + + // then add relative offset + switch (encoding & 0x70) { + case llvm::dwarf::DW_EH_PE_absptr: + // do nothing + break; + case llvm::dwarf::DW_EH_PE_pcrel: + result += (uintptr_t)(*data); + break; + case llvm::dwarf::DW_EH_PE_textrel: + case llvm::dwarf::DW_EH_PE_datarel: + case llvm::dwarf::DW_EH_PE_funcrel: + case llvm::dwarf::DW_EH_PE_aligned: + default: + // not supported + abort(); + break; + } + + // then apply indirection + if (encoding & llvm::dwarf::DW_EH_PE_indirect) { + result = *((uintptr_t*)result); + } + + *data = p; + + return result; } @@ -524,74 +515,74 @@ static bool handleActionValue(int64_t *resultAction, uintptr_t actionEntry, uint64_t exceptionClass, struct _Unwind_Exception *exceptionObject) { - bool ret = false; - - if (!resultAction || - !exceptionObject || - (exceptionClass != ourBaseExceptionClass)) - return(ret); - - struct OurBaseException_t* excp = (struct OurBaseException_t*) - (((char*) exceptionObject) + ourBaseFromUnwindOffset); - struct OurExceptionType_t *excpType = &(excp->type); - int type = excpType->type; - + bool ret = false; + + if (!resultAction || + !exceptionObject || + (exceptionClass != ourBaseExceptionClass)) + return(ret); + + struct OurBaseException_t* excp = (struct OurBaseException_t*) + (((char*) exceptionObject) + ourBaseFromUnwindOffset); + struct OurExceptionType_t *excpType = &(excp->type); + int type = excpType->type; + #ifdef DEBUG - fprintf(stderr, - "handleActionValue(...): exceptionObject = <%p>, " - "excp = <%p>.\n", - exceptionObject, - excp); + fprintf(stderr, + "handleActionValue(...): exceptionObject = <%p>, " + "excp = <%p>.\n", + exceptionObject, + excp); #endif - - const uint8_t *actionPos = (uint8_t*) actionEntry, - *tempActionPos; - int64_t typeOffset = 0, - actionOffset; - - for (int i = 0; true; ++i) { - // Each emitted dwarf action corresponds to a 2 tuple of - // type info address offset, and action offset to the next - // emitted action. - typeOffset = readSLEB128(&actionPos); - tempActionPos = actionPos; - actionOffset = readSLEB128(&tempActionPos); - + + const uint8_t *actionPos = (uint8_t*) actionEntry, + *tempActionPos; + int64_t typeOffset = 0, + actionOffset; + + for (int i = 0; true; ++i) { + // Each emitted dwarf action corresponds to a 2 tuple of + // type info address offset, and action offset to the next + // emitted action. + typeOffset = readSLEB128(&actionPos); + tempActionPos = actionPos; + actionOffset = readSLEB128(&tempActionPos); + #ifdef DEBUG - fprintf(stderr, - "handleActionValue(...):typeOffset: <%lld>, " - "actionOffset: <%lld>.\n", - typeOffset, - actionOffset); + fprintf(stderr, + "handleActionValue(...):typeOffset: <%lld>, " + "actionOffset: <%lld>.\n", + typeOffset, + actionOffset); #endif - assert((typeOffset >= 0) && - "handleActionValue(...):filters are not supported."); - - // Note: A typeOffset == 0 implies that a cleanup llvm.eh.selector - // argument has been matched. - if ((typeOffset > 0) && - (type == (classInfo[-typeOffset])->type)) { + assert((typeOffset >= 0) && + "handleActionValue(...):filters are not supported."); + + // Note: A typeOffset == 0 implies that a cleanup llvm.eh.selector + // argument has been matched. + if ((typeOffset > 0) && + (type == (classInfo[-typeOffset])->type)) { #ifdef DEBUG - fprintf(stderr, - "handleActionValue(...):actionValue <%d> found.\n", - i); + fprintf(stderr, + "handleActionValue(...):actionValue <%d> found.\n", + i); #endif - *resultAction = i + 1; - ret = true; - break; - } - + *resultAction = i + 1; + ret = true; + break; + } + #ifdef DEBUG - fprintf(stderr, - "handleActionValue(...):actionValue not found.\n"); + fprintf(stderr, + "handleActionValue(...):actionValue not found.\n"); #endif - if (!actionOffset) - break; - - actionPos += actionOffset; - } - - return(ret); + if (!actionOffset) + break; + + actionPos += actionOffset; + } + + return(ret); } @@ -607,180 +598,180 @@ static bool handleActionValue(int64_t *resultAction, /// @param context unwind system context /// @returns minimally supported unwinding control indicator static _Unwind_Reason_Code handleLsda(int version, - const uint8_t* lsda, - _Unwind_Action actions, - uint64_t exceptionClass, - struct _Unwind_Exception* exceptionObject, - _Unwind_Context_t context) { - _Unwind_Reason_Code ret = _URC_CONTINUE_UNWIND; - - if (!lsda) - return(ret); - + const uint8_t* lsda, + _Unwind_Action actions, + uint64_t exceptionClass, + struct _Unwind_Exception* exceptionObject, + _Unwind_Context_t context) { + _Unwind_Reason_Code ret = _URC_CONTINUE_UNWIND; + + if (!lsda) + return(ret); + #ifdef DEBUG - fprintf(stderr, - "handleLsda(...):lsda is non-zero.\n"); + fprintf(stderr, + "handleLsda(...):lsda is non-zero.\n"); #endif - - // Get the current instruction pointer and offset it before next - // instruction in the current frame which threw the exception. - uintptr_t pc = _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 pcOffset = pc - funcStart; - struct OurExceptionType_t** classInfo = NULL; - - // Note: See JITDwarfEmitter::EmitExceptionTable(...) for corresponding - // dwarf emission - - // Parse LSDA header. - uint8_t lpStartEncoding = *lsda++; - - if (lpStartEncoding != llvm::dwarf::DW_EH_PE_omit) { - readEncodedPointer(&lsda, lpStartEncoding); - } - - uint8_t ttypeEncoding = *lsda++; - uintptr_t classInfoOffset; - - if (ttypeEncoding != llvm::dwarf::DW_EH_PE_omit) { - // Calculate type info locations in emitted dwarf code which - // were flagged by type info arguments to llvm.eh.selector - // intrinsic - classInfoOffset = readULEB128(&lsda); - classInfo = (struct OurExceptionType_t**) (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; - - bool foreignException = false; - - while (callSitePtr < callSiteTableEnd) { - uintptr_t start = readEncodedPointer(&callSitePtr, - callSiteEncoding); - uintptr_t length = readEncodedPointer(&callSitePtr, + + // Get the current instruction pointer and offset it before next + // instruction in the current frame which threw the exception. + uintptr_t pc = _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 pcOffset = pc - funcStart; + struct OurExceptionType_t** classInfo = NULL; + + // Note: See JITDwarfEmitter::EmitExceptionTable(...) for corresponding + // dwarf emission + + // Parse LSDA header. + uint8_t lpStartEncoding = *lsda++; + + if (lpStartEncoding != llvm::dwarf::DW_EH_PE_omit) { + readEncodedPointer(&lsda, lpStartEncoding); + } + + uint8_t ttypeEncoding = *lsda++; + uintptr_t classInfoOffset; + + if (ttypeEncoding != llvm::dwarf::DW_EH_PE_omit) { + // Calculate type info locations in emitted dwarf code which + // were flagged by type info arguments to llvm.eh.selector + // intrinsic + classInfoOffset = readULEB128(&lsda); + classInfo = (struct OurExceptionType_t**) (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; + + bool foreignException = false; + + while (callSitePtr < callSiteTableEnd) { + uintptr_t start = readEncodedPointer(&callSitePtr, + callSiteEncoding); + uintptr_t length = readEncodedPointer(&callSitePtr, + callSiteEncoding); + uintptr_t landingPad = readEncodedPointer(&callSitePtr, callSiteEncoding); - uintptr_t landingPad = readEncodedPointer(&callSitePtr, - callSiteEncoding); - - // Note: Action value - uintptr_t actionEntry = readULEB128(&callSitePtr); - - if (exceptionClass != ourBaseExceptionClass) { - // We have been notified of a foreign exception being thrown, - // and we therefore need to execute cleanup landing pads - actionEntry = 0; - foreignException = true; - } - - if (landingPad == 0) { + + // Note: Action value + uintptr_t actionEntry = readULEB128(&callSitePtr); + + if (exceptionClass != ourBaseExceptionClass) { + // We have been notified of a foreign exception being thrown, + // and we therefore need to execute cleanup landing pads + actionEntry = 0; + foreignException = true; + } + + if (landingPad == 0) { #ifdef DEBUG - fprintf(stderr, - "handleLsda(...): No landing pad found.\n"); + fprintf(stderr, + "handleLsda(...): No landing pad found.\n"); #endif - - continue; // no landing pad for this entry - } - - if (actionEntry) { - actionEntry += ((uintptr_t) actionTableStart) - 1; - } - else { + + continue; // no landing pad for this entry + } + + if (actionEntry) { + actionEntry += ((uintptr_t) actionTableStart) - 1; + } + else { #ifdef DEBUG - fprintf(stderr, - "handleLsda(...):No action table found.\n"); + fprintf(stderr, + "handleLsda(...):No action table found.\n"); #endif - } - - bool exceptionMatched = false; - - if ((start <= pcOffset) && (pcOffset < (start + length))) { + } + + bool exceptionMatched = false; + + if ((start <= pcOffset) && (pcOffset < (start + length))) { #ifdef DEBUG - fprintf(stderr, - "handleLsda(...): Landing pad found.\n"); + fprintf(stderr, + "handleLsda(...): Landing pad found.\n"); #endif - int64_t actionValue = 0; - - if (actionEntry) { - exceptionMatched = handleActionValue - ( - &actionValue, - classInfo, - actionEntry, - exceptionClass, - exceptionObject - ); - } - - if (!(actions & _UA_SEARCH_PHASE)) { + int64_t actionValue = 0; + + if (actionEntry) { + exceptionMatched = handleActionValue + ( + &actionValue, + classInfo, + actionEntry, + exceptionClass, + exceptionObject + ); + } + + if (!(actions & _UA_SEARCH_PHASE)) { #ifdef DEBUG - fprintf(stderr, - "handleLsda(...): installed landing pad " - "context.\n"); + fprintf(stderr, + "handleLsda(...): installed landing pad " + "context.\n"); #endif - - // Found landing pad for the PC. - // Set Instruction Pointer to so we re-enter function - // at landing pad. The landing pad is created by the - // compiler to take two parameters in registers. - _Unwind_SetGR(context, - __builtin_eh_return_data_regno(0), - (uintptr_t)exceptionObject); - - // Note: this virtual register directly corresponds - // to the return of the llvm.eh.selector intrinsic - if (!actionEntry || !exceptionMatched) { - // We indicate cleanup only - _Unwind_SetGR(context, - __builtin_eh_return_data_regno(1), - 0); - } - else { - // Matched type info index of llvm.eh.selector intrinsic - // passed here. - _Unwind_SetGR(context, - __builtin_eh_return_data_regno(1), - actionValue); - } - - // To execute landing pad set here - _Unwind_SetIP(context, funcStart + landingPad); - ret = _URC_INSTALL_CONTEXT; - } - else if (exceptionMatched) { + + // Found landing pad for the PC. + // Set Instruction Pointer to so we re-enter function + // at landing pad. The landing pad is created by the + // compiler to take two parameters in registers. + _Unwind_SetGR(context, + __builtin_eh_return_data_regno(0), + (uintptr_t)exceptionObject); + + // Note: this virtual register directly corresponds + // to the return of the llvm.eh.selector intrinsic + if (!actionEntry || !exceptionMatched) { + // We indicate cleanup only + _Unwind_SetGR(context, + __builtin_eh_return_data_regno(1), + 0); + } + else { + // Matched type info index of llvm.eh.selector intrinsic + // passed here. + _Unwind_SetGR(context, + __builtin_eh_return_data_regno(1), + actionValue); + } + + // To execute landing pad set here + _Unwind_SetIP(context, funcStart + landingPad); + ret = _URC_INSTALL_CONTEXT; + } + else if (exceptionMatched) { #ifdef DEBUG - fprintf(stderr, - "handleLsda(...): setting handler found.\n"); + fprintf(stderr, + "handleLsda(...): setting handler found.\n"); #endif - ret = _URC_HANDLER_FOUND; - } - else { - // Note: Only non-clean up handlers are marked as - // found. Otherwise the clean up handlers will be - // re-found and executed during the clean up - // phase. + ret = _URC_HANDLER_FOUND; + } + else { + // Note: Only non-clean up handlers are marked as + // found. Otherwise the clean up handlers will be + // re-found and executed during the clean up + // phase. #ifdef DEBUG - fprintf(stderr, - "handleLsda(...): cleanup handler found.\n"); + fprintf(stderr, + "handleLsda(...): cleanup handler found.\n"); #endif - } - - break; - } + } + + break; } - - return(ret); + } + + return(ret); } @@ -796,38 +787,38 @@ static _Unwind_Reason_Code handleLsda(int version, /// @param context unwind system context /// @returns minimally supported unwinding control indicator _Unwind_Reason_Code ourPersonality(int version, - _Unwind_Action actions, - uint64_t exceptionClass, - struct _Unwind_Exception* exceptionObje |