diff options
Diffstat (limited to 'lib/gcc_personality_v0.c')
-rw-r--r-- | lib/gcc_personality_v0.c | 98 |
1 files changed, 52 insertions, 46 deletions
diff --git a/lib/gcc_personality_v0.c b/lib/gcc_personality_v0.c index 55d1166b8..249f0f0e8 100644 --- a/lib/gcc_personality_v0.c +++ b/lib/gcc_personality_v0.c @@ -1,20 +1,23 @@ -//===-- gcc_personality_v0.c - Implement __gcc_personality_v0 -------------===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// +/* ===-- gcc_personality_v0.c - Implement __gcc_personality_v0 -------------=== + * + * The LLVM Compiler Infrastructure + * + * This file is distributed under the University of Illinois Open Source + * License. See LICENSE.TXT for details. + * + * ===----------------------------------------------------------------------=== + * + */ #include <stdint.h> #include <stdio.h> #include <stdlib.h> -// -// _Unwind_* stuff based on C++ ABI public documentation -// http://refspecs.freestandards.org/abi-eh-1.21.html -// +/* + * _Unwind_* stuff based on C++ ABI public documentation + * http://refspecs.freestandards.org/abi-eh-1.21.html + */ + typedef enum { _URC_NO_REASON = 0, _URC_FOREIGN_EXCEPTION_CAUGHT = 1, @@ -52,11 +55,12 @@ extern uintptr_t _Unwind_GetIP(_Unwind_Context_t context); extern uintptr_t _Unwind_GetRegionStart(_Unwind_Context_t context); -// -// Pointer encodings documented at: -// http://refspecs.freestandards.org/LSB_1.3.0/gLSB/gLSB/ehframehdr.html -// -#define DW_EH_PE_omit 0xff // no data follows +/* + * Pointer encodings documented at: + * http://refspecs.freestandards.org/LSB_1.3.0/gLSB/gLSB/ehframehdr.html + */ + +#define DW_EH_PE_omit 0xff /* no data follows */ #define DW_EH_PE_absptr 0x00 #define DW_EH_PE_uleb128 0x01 @@ -73,11 +77,11 @@ extern uintptr_t _Unwind_GetRegionStart(_Unwind_Context_t context); #define DW_EH_PE_datarel 0x30 #define DW_EH_PE_funcrel 0x40 #define DW_EH_PE_aligned 0x50 -#define DW_EH_PE_indirect 0x80 // gcc extension +#define DW_EH_PE_indirect 0x80 /* gcc extension */ -// read a uleb128 encoded value and advance pointer +/* read a uleb128 encoded value and advance pointer */ static uintptr_t readULEB128(const uint8_t** data) { uintptr_t result = 0; @@ -93,7 +97,7 @@ static uintptr_t readULEB128(const uint8_t** data) return result; } -// read a pointer encoded value and advance pointer +/* read a pointer encoded value and advance pointer */ static uintptr_t readEncodedPointer(const uint8_t** data, uint8_t encoding) { const uint8_t* p = *data; @@ -102,7 +106,7 @@ static uintptr_t readEncodedPointer(const uint8_t** data, uint8_t encoding) if ( encoding == DW_EH_PE_omit ) return 0; - // first get value + /* first get value */ switch (encoding & 0x0F) { case DW_EH_PE_absptr: result = *((uintptr_t*)p); @@ -137,15 +141,15 @@ static uintptr_t readEncodedPointer(const uint8_t** data, uint8_t encoding) break; case DW_EH_PE_sleb128: default: - // not supported + /* not supported */ abort(); break; } - // then add relative offset + /* then add relative offset */ switch ( encoding & 0x70 ) { case DW_EH_PE_absptr: - // do nothing + /* do nothing */ break; case DW_EH_PE_pcrel: result += (uintptr_t)(*data); @@ -155,12 +159,12 @@ static uintptr_t readEncodedPointer(const uint8_t** data, uint8_t encoding) case DW_EH_PE_funcrel: case DW_EH_PE_aligned: default: - // not supported + /* not supported */ abort(); break; } - // then apply indirection + /* then apply indirection */ if (encoding & DW_EH_PE_indirect) { result = *((uintptr_t*)result); } @@ -170,24 +174,25 @@ static uintptr_t readEncodedPointer(const uint8_t** data, uint8_t encoding) } -// -// The C compiler makes references to __gcc_personality_v0 in -// the dwarf unwind information for translation units that use -// __attribute__((cleanup(xx))) on local variables. -// This personality routine is called by the system unwinder -// on each frame as the stack is unwound during a C++ exception -// throw through a C function compiled with -fexceptions. -// +/* + * The C compiler makes references to __gcc_personality_v0 in + * the dwarf unwind information for translation units that use + * __attribute__((cleanup(xx))) on local variables. + * This personality routine is called by the system unwinder + * on each frame as the stack is unwound during a C++ exception + * throw through a C function compiled with -fexceptions. + */ + _Unwind_Reason_Code __gcc_personality_v0(int version, _Unwind_Action actions, uint64_t exceptionClass, struct _Unwind_Exception* exceptionObject, _Unwind_Context_t context) { - // Since C does not have catch clauses, there is nothing to do during - // phase 1 (the search phase). + /* Since C does not have catch clauses, there is nothing to do during */ + /* phase 1 (the search phase). */ if ( actions & _UA_SEARCH_PHASE ) return _URC_CONTINUE_UNWIND; - // There is nothing to do if there is no LSDA for this frame. + /* There is nothing to do if there is no LSDA for this frame. */ const uint8_t* lsda = _Unwind_GetLanguageSpecificData(context); if ( lsda == NULL ) return _URC_CONTINUE_UNWIND; @@ -196,7 +201,7 @@ _Unwind_Reason_Code __gcc_personality_v0(int version, _Unwind_Action actions, uintptr_t funcStart = _Unwind_GetRegionStart(context); uintptr_t pcOffset = pc - funcStart; - // Parse LSDA header. + /* Parse LSDA header. */ uint8_t lpStartEncoding = *lsda++; if (lpStartEncoding != DW_EH_PE_omit) { readEncodedPointer(&lsda, lpStartEncoding); @@ -205,7 +210,7 @@ _Unwind_Reason_Code __gcc_personality_v0(int version, _Unwind_Action actions, if (ttypeEncoding != DW_EH_PE_omit) { readULEB128(&lsda); } - // Walk call-site table looking for range that includes current PC. + /* 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; @@ -215,14 +220,15 @@ _Unwind_Reason_Code __gcc_personality_v0(int version, _Unwind_Action actions, uintptr_t start = readEncodedPointer(&p, callSiteEncoding); uintptr_t length = readEncodedPointer(&p, callSiteEncoding); uintptr_t landingPad = readEncodedPointer(&p, callSiteEncoding); - readULEB128(&p); // action value not used for C code + readULEB128(&p); /* action value not used for C code */ if ( landingPad == 0 ) - continue; // no landing pad for this entry + continue; /* no landing pad for this entry */ if ( (start <= pcOffset) && (pcOffset < (start+length)) ) { - // 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. + /* 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); _Unwind_SetGR(context, __builtin_eh_return_data_regno(1), 0); @@ -231,7 +237,7 @@ _Unwind_Reason_Code __gcc_personality_v0(int version, _Unwind_Action actions, } } - // No landing pad found, continue unwinding. + /* No landing pad found, continue unwinding. */ return _URC_CONTINUE_UNWIND; } |