summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorDan Albert <danalbert@google.com>2015-03-04 17:08:25 -0800
committerDan Albert <danalbert@google.com>2015-03-10 17:59:36 -0700
commit0a1ce9cae10bf7e2e6640e2a8f1efe7062c47292 (patch)
treecd4a0cb49f6717bc6659095706a376ad3a00436c /src
parentda0677d3172e235acc6a35a5d4fcf2b4dca86fea (diff)
downloadlibcxxabi-0a1ce9cae10bf7e2e6640e2a8f1efe7062c47292.tar.gz
Merge to upstream r231075.
Change-Id: If60a5707fa4299ce03b7bfd605b360486bcd9d2f
Diffstat (limited to 'src')
-rw-r--r--src/CMakeLists.txt68
-rw-r--r--src/Unwind/AddressSpace.hpp113
-rw-r--r--src/Unwind/CMakeLists.txt62
-rw-r--r--src/Unwind/CompactUnwinder.hpp2
-rw-r--r--src/Unwind/DwarfInstructions.hpp14
-rw-r--r--src/Unwind/DwarfParser.hpp2
-rw-r--r--src/Unwind/EHHeaderParser.hpp161
-rw-r--r--src/Unwind/Registers.hpp25
-rw-r--r--src/Unwind/Unwind-EHABI.cpp292
-rw-r--r--src/Unwind/Unwind-EHABI.h51
-rw-r--r--src/Unwind/UnwindCursor.hpp106
-rw-r--r--src/Unwind/UnwindLevel1-gcc-ext.c80
-rw-r--r--src/Unwind/UnwindLevel1.c264
-rw-r--r--src/Unwind/UnwindRegistersRestore.S35
-rw-r--r--src/Unwind/UnwindRegistersSave.S42
-rw-r--r--src/Unwind/Unwind_AppleExtras.cpp6
-rw-r--r--src/Unwind/assembly.h4
-rw-r--r--src/Unwind/config.h26
-rw-r--r--src/Unwind/libunwind.cpp63
-rw-r--r--src/abort_message.cpp10
-rw-r--r--src/cxa_exception.cpp14
-rw-r--r--src/cxa_exception.hpp26
-rw-r--r--src/cxa_guard.cpp2
-rw-r--r--src/cxa_personality.cpp101
-rw-r--r--src/private_typeinfo.cpp8
25 files changed, 980 insertions, 597 deletions
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index 5c9e38b..fda2d10 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -34,18 +34,6 @@ if (MSVC_IDE OR XCODE)
endif()
endif()
-if (LIBCXXABI_ENABLE_SHARED)
- add_library(cxxabi SHARED
- ${LIBCXXABI_SOURCES}
- ${LIBCXXABI_HEADERS}
- )
-else()
- add_library(cxxabi STATIC
- ${LIBCXXABI_SOURCES}
- ${LIBCXXABI_HEADERS}
- )
-endif()
-
include_directories("${LIBCXXABI_LIBCXX_INCLUDES}")
if (LIBCXXABI_HAS_CXA_THREAD_ATEXIT_IMPL)
@@ -65,22 +53,23 @@ else()
append_if(libraries LIBCXXABI_HAS_GCC_EH_LIB gcc_eh)
endif()
-target_link_libraries(cxxabi ${libraries})
-
# Setup flags.
append_if(LIBCXXABI_COMPILE_FLAGS LIBCXXABI_HAS_FPIC_FLAG -fPIC)
append_if(LIBCXXABI_LINK_FLAGS LIBCXXABI_HAS_NODEFAULTLIBS_FLAG -nodefaultlibs)
+set(LIBCXXABI_SHARED_LINK_FLAGS)
+
if ( APPLE )
if ( CMAKE_OSX_DEPLOYMENT_TARGET STREQUAL "10.6" )
list(APPEND LIBCXXABI_COMPILE_FLAGS "-U__STRICT_ANSI__")
- list(APPEND LIBCXXABI_LINK_FLAGS
+ list(APPEND LIBCXXABI_SHARED_LINK_FLAGS
"-compatibility_version 1"
"-current_version 1"
- "-install_name /usr/lib/libc++abi.1.dylib"
- "/usr/lib/libSystem.B.dylib")
- else()
+ "-install_name /usr/lib/libc++abi.1.dylib")
list(APPEND LIBCXXABI_LINK_FLAGS
+ "/usr/lib/libSystem.B.dylib")
+ else()
+ list(APPEND LIBCXXABI_SHARED_LINK_FLAGS
"-compatibility_version 1"
"-install_name /usr/lib/libc++abi.1.dylib")
endif()
@@ -88,17 +77,48 @@ endif()
string(REPLACE ";" " " LIBCXXABI_COMPILE_FLAGS "${LIBCXXABI_COMPILE_FLAGS}")
string(REPLACE ";" " " LIBCXXABI_LINK_FLAGS "${LIBCXXABI_LINK_FLAGS}")
+string(REPLACE ";" " " LIBCXXABI_SHARED_LINK_FLAGS "${LIBCXXABI_SHARED_LINK_FLAGS}")
+
+# Add a object library that contains the compiled source files.
+add_library(cxxabi_objects OBJECT ${LIBCXXABI_SOURCES} ${LIBCXXABI_HEADERS})
-set_target_properties(cxxabi
+set_target_properties(cxxabi_objects
PROPERTIES
COMPILE_FLAGS "${LIBCXXABI_COMPILE_FLAGS}"
- LINK_FLAGS "${LIBCXXABI_LINK_FLAGS}"
- OUTPUT_NAME "c++abi"
- VERSION "1.0"
- SOVERSION "1"
)
-install(TARGETS cxxabi
+set(LIBCXXABI_TARGETS)
+
+# Build the shared library.
+if (LIBCXXABI_ENABLE_SHARED)
+ add_library(cxxabi_shared SHARED $<TARGET_OBJECTS:cxxabi_objects>)
+ target_link_libraries(cxxabi_shared ${libraries})
+ set_target_properties(cxxabi_shared
+ PROPERTIES
+ LINK_FLAGS "${LIBCXXABI_LINK_FLAGS} ${LIBCXXABI_SHARED_LINK_FLAGS}"
+ OUTPUT_NAME "c++abi"
+ VERSION "1.0"
+ SOVERSION "1"
+ )
+ list(APPEND LIBCXXABI_TARGETS "cxxabi_shared")
+endif()
+
+# Build the static library.
+if (LIBCXXABI_ENABLE_STATIC)
+ add_library(cxxabi_static STATIC $<TARGET_OBJECTS:cxxabi_objects>)
+ target_link_libraries(cxxabi_static ${libraries})
+ set_target_properties(cxxabi_static
+ PROPERTIES
+ LINK_FLAGS "${LIBCXXABI_LINK_FLAGS}"
+ OUTPUT_NAME "c++abi"
+ )
+ list(APPEND LIBCXXABI_TARGETS "cxxabi_static")
+endif()
+
+# Add a meta-target for both libraries.
+add_custom_target(cxxabi DEPENDS ${LIBCXXABI_TARGETS})
+
+install(TARGETS ${LIBCXXABI_TARGETS}
LIBRARY DESTINATION lib${LIBCXXABI_LIBDIR_SUFFIX}
ARCHIVE DESTINATION lib${LIBCXXABI_LIBDIR_SUFFIX}
)
diff --git a/src/Unwind/AddressSpace.hpp b/src/Unwind/AddressSpace.hpp
index 4e94afc..abcac41 100644
--- a/src/Unwind/AddressSpace.hpp
+++ b/src/Unwind/AddressSpace.hpp
@@ -18,11 +18,11 @@
#include <stdlib.h>
#include <string.h>
-#if !_LIBUNWIND_IS_BAREMETAL
+#ifndef _LIBUNWIND_IS_BAREMETAL
#include <dlfcn.h>
#endif
-#if __APPLE__
+#ifdef __APPLE__
#include <mach-o/getsect.h>
namespace libunwind {
bool checkKeyMgrRegisteredFDEs(uintptr_t targetAddr, void *&fde);
@@ -35,7 +35,7 @@ namespace libunwind {
#include "Registers.hpp"
#if LIBCXXABI_ARM_EHABI
-#if __linux__
+#ifdef __linux__
typedef long unsigned int *_Unwind_Ptr;
extern "C" _Unwind_Ptr __gnu_Unwind_Find_exidx(_Unwind_Ptr addr, int *len);
@@ -43,9 +43,9 @@ extern "C" _Unwind_Ptr __gnu_Unwind_Find_exidx(_Unwind_Ptr addr, int *len);
// Emulate the BSD dl_unwind_find_exidx API when on a GNU libdl system.
#define dl_unwind_find_exidx __gnu_Unwind_Find_exidx
-#elif !_LIBUNWIND_IS_BAREMETAL
+#elif !defined(_LIBUNWIND_IS_BAREMETAL)
#include <link.h>
-#else // _LIBUNWIND_IS_BAREMETAL
+#else // !defined(_LIBUNWIND_IS_BAREMETAL)
// When statically linked on bare-metal, the symbols for the EH table are looked
// up without going through the dynamic loader.
struct EHTEntry {
@@ -54,10 +54,16 @@ struct EHTEntry {
};
extern EHTEntry __exidx_start;
extern EHTEntry __exidx_end;
-#endif // !_LIBUNWIND_IS_BAREMETAL
-
+#endif // !defined(_LIBUNWIND_IS_BAREMETAL)
#endif // LIBCXXABI_ARM_EHABI
+#if defined(__linux__)
+#if _LIBUNWIND_SUPPORT_DWARF_UNWIND && _LIBUNWIND_SUPPORT_DWARF_INDEX
+#include <link.h>
+#include "EHHeaderParser.hpp"
+#endif
+#endif
+
namespace libunwind {
/// Used by findUnwindSections() to return info about needed sections.
@@ -91,7 +97,7 @@ struct UnwindInfoSections {
/// making local unwinds fast.
class __attribute__((visibility("hidden"))) LocalAddressSpace {
public:
-#if __LP64__
+#ifdef __LP64__
typedef uint64_t pint_t;
typedef int64_t sint_t;
#else
@@ -132,7 +138,8 @@ public:
static uint64_t getULEB128(pint_t &addr, pint_t end);
static int64_t getSLEB128(pint_t &addr, pint_t end);
- pint_t getEncodedP(pint_t &addr, pint_t end, uint8_t encoding);
+ pint_t getEncodedP(pint_t &addr, pint_t end, uint8_t encoding,
+ pint_t datarelBase = 0);
bool findFunctionName(pint_t addr, char *buf, size_t bufLen,
unw_word_t *offset);
bool findUnwindSections(pint_t targetAddr, UnwindInfoSections &info);
@@ -142,7 +149,7 @@ public:
};
inline uintptr_t LocalAddressSpace::getP(pint_t addr) {
-#if __LP64__
+#ifdef __LP64__
return get64(addr);
#else
return get32(addr);
@@ -195,9 +202,9 @@ inline int64_t LocalAddressSpace::getSLEB128(pint_t &addr, pint_t end) {
return result;
}
-inline LocalAddressSpace::pint_t LocalAddressSpace::getEncodedP(pint_t &addr,
- pint_t end,
- uint8_t encoding) {
+inline LocalAddressSpace::pint_t
+LocalAddressSpace::getEncodedP(pint_t &addr, pint_t end, uint8_t encoding,
+ pint_t datarelBase) {
pint_t startAddr = addr;
const uint8_t *p = (uint8_t *)addr;
pint_t result;
@@ -263,7 +270,12 @@ inline LocalAddressSpace::pint_t LocalAddressSpace::getEncodedP(pint_t &addr,
_LIBUNWIND_ABORT("DW_EH_PE_textrel pointer encoding not supported");
break;
case DW_EH_PE_datarel:
- _LIBUNWIND_ABORT("DW_EH_PE_datarel pointer encoding not supported");
+ // DW_EH_PE_datarel is only valid in a few places, so the parameter has a
+ // default value of 0, and we abort in the event that someone calls this
+ // function with a datarelBase of 0 and DW_EH_PE_datarel encoding.
+ if (datarelBase == 0)
+ _LIBUNWIND_ABORT("DW_EH_PE_datarel is invalid with a datarelBase of 0");
+ result += datarelBase;
break;
case DW_EH_PE_funcrel:
_LIBUNWIND_ABORT("DW_EH_PE_funcrel pointer encoding not supported");
@@ -282,7 +294,7 @@ inline LocalAddressSpace::pint_t LocalAddressSpace::getEncodedP(pint_t &addr,
return result;
}
-#if __APPLE__
+#ifdef __APPLE__
struct dyld_unwind_sections
{
const struct mach_header* mh;
@@ -326,7 +338,7 @@ inline LocalAddressSpace::pint_t LocalAddressSpace::getEncodedP(pint_t &addr,
inline bool LocalAddressSpace::findUnwindSections(pint_t targetAddr,
UnwindInfoSections &info) {
-#if __APPLE__
+#ifdef __APPLE__
dyld_unwind_sections dyldInfo;
if (_dyld_find_unwind_sections((void *)targetAddr, &dyldInfo)) {
info.dso_base = (uintptr_t)dyldInfo.mh;
@@ -339,7 +351,7 @@ inline bool LocalAddressSpace::findUnwindSections(pint_t targetAddr,
return true;
}
#elif LIBCXXABI_ARM_EHABI
- #if _LIBUNWIND_IS_BAREMETAL
+ #ifdef _LIBUNWIND_IS_BAREMETAL
// Bare metal is statically linked, so no need to ask the dynamic loader
info.arm_section = (uintptr_t)(&__exidx_start);
info.arm_section_length = (uintptr_t)(&__exidx_end - &__exidx_start);
@@ -353,6 +365,64 @@ inline bool LocalAddressSpace::findUnwindSections(pint_t targetAddr,
info.arm_section, info.arm_section_length);
if (info.arm_section && info.arm_section_length)
return true;
+#elif _LIBUNWIND_SUPPORT_DWARF_UNWIND
+#if _LIBUNWIND_SUPPORT_DWARF_INDEX
+ struct dl_iterate_cb_data {
+ LocalAddressSpace *addressSpace;
+ UnwindInfoSections *sects;
+ uintptr_t targetAddr;
+ };
+
+ dl_iterate_cb_data cb_data = {this, &info, targetAddr};
+ int found = dl_iterate_phdr(
+ [](struct dl_phdr_info *pinfo, size_t, void *data) -> int {
+ auto cbdata = static_cast<dl_iterate_cb_data *>(data);
+ size_t object_length;
+ bool found_obj = false;
+ bool found_hdr = false;
+
+ assert(cbdata);
+ assert(cbdata->sects);
+
+ if (cbdata->targetAddr < pinfo->dlpi_addr) {
+ return false;
+ }
+
+ for (ElfW(Half) i = 0; i < pinfo->dlpi_phnum; i++) {
+ const ElfW(Phdr) *phdr = &pinfo->dlpi_phdr[i];
+ if (phdr->p_type == PT_LOAD) {
+ uintptr_t begin = pinfo->dlpi_addr + phdr->p_vaddr;
+ uintptr_t end = begin + phdr->p_memsz;
+ if (cbdata->targetAddr >= begin && cbdata->targetAddr < end) {
+ cbdata->sects->dso_base = begin;
+ object_length = phdr->p_memsz;
+ found_obj = true;
+ }
+ } else if (phdr->p_type == PT_GNU_EH_FRAME) {
+ EHHeaderParser<LocalAddressSpace>::EHHeaderInfo hdrInfo;
+ uintptr_t eh_frame_hdr_start = pinfo->dlpi_addr + phdr->p_vaddr;
+ cbdata->sects->dwarf_index_section = eh_frame_hdr_start;
+ cbdata->sects->dwarf_index_section_length = phdr->p_memsz;
+ EHHeaderParser<LocalAddressSpace>::decodeEHHdr(
+ *cbdata->addressSpace, eh_frame_hdr_start, phdr->p_memsz,
+ hdrInfo);
+ cbdata->sects->dwarf_section = hdrInfo.eh_frame_ptr;
+ found_hdr = true;
+ }
+ }
+
+ if (found_obj && found_hdr) {
+ cbdata->sects->dwarf_section_length = object_length;
+ return true;
+ } else {
+ return false;
+ }
+ },
+ &cb_data);
+ return static_cast<bool>(found);
+#else
+#error "_LIBUNWIND_SUPPORT_DWARF_UNWIND requires _LIBUNWIND_SUPPORT_DWARF_INDEX on this platform."
+#endif
#endif
return false;
@@ -360,7 +430,7 @@ inline bool LocalAddressSpace::findUnwindSections(pint_t targetAddr,
inline bool LocalAddressSpace::findOtherFDE(pint_t targetAddr, pint_t &fde) {
-#if __APPLE__
+#ifdef __APPLE__
return checkKeyMgrRegisteredFDEs(targetAddr, *((void**)&fde));
#else
// TO DO: if OS has way to dynamically register FDEs, check that.
@@ -373,7 +443,7 @@ inline bool LocalAddressSpace::findOtherFDE(pint_t targetAddr, pint_t &fde) {
inline bool LocalAddressSpace::findFunctionName(pint_t addr, char *buf,
size_t bufLen,
unw_word_t *offset) {
-#if !_LIBUNWIND_IS_BAREMETAL
+#ifndef _LIBUNWIND_IS_BAREMETAL
Dl_info dyldInfo;
if (dladdr((void *)addr, &dyldInfo)) {
if (dyldInfo.dli_sname != NULL) {
@@ -388,7 +458,7 @@ inline bool LocalAddressSpace::findFunctionName(pint_t addr, char *buf,
-#if UNW_REMOTE
+#ifdef UNW_REMOTE
/// OtherAddressSpace is used as a template parameter to UnwindCursor when
/// unwinding a thread in the another process. The other process can be a
@@ -408,7 +478,8 @@ public:
pint_t getP(pint_t addr);
uint64_t getULEB128(pint_t &addr, pint_t end);
int64_t getSLEB128(pint_t &addr, pint_t end);
- pint_t getEncodedP(pint_t &addr, pint_t end, uint8_t encoding);
+ pint_t getEncodedP(pint_t &addr, pint_t end, uint8_t encoding,
+ pint_t datarelBase = 0);
bool findFunctionName(pint_t addr, char *buf, size_t bufLen,
unw_word_t *offset);
bool findUnwindSections(pint_t targetAddr, UnwindInfoSections &info);
diff --git a/src/Unwind/CMakeLists.txt b/src/Unwind/CMakeLists.txt
index 598a081..2aa45dc 100644
--- a/src/Unwind/CMakeLists.txt
+++ b/src/Unwind/CMakeLists.txt
@@ -1,20 +1,24 @@
# Get sources
-set(LIBUNWIND_SOURCES
- libunwind.cpp
- Unwind-EHABI.cpp
- UnwindLevel1.c
- UnwindLevel1-gcc-ext.c
- Unwind-sjlj.c
-)
-append_if(LIBUNWIND_SOURCES APPLE Unwind_AppleExtras.cpp)
+set(LIBUNWIND_CXX_SOURCES
+ libunwind.cpp
+ Unwind-EHABI.cpp)
+append_if(LIBUNWIND_CXX_SOURCES APPLE Unwind_AppleExtras.cpp)
-set(LIBUNWIND_ASM_SOURCES
- UnwindRegistersRestore.S
- UnwindRegistersSave.S
-)
+set(LIBUNWIND_C_SOURCES
+ UnwindLevel1.c
+ UnwindLevel1-gcc-ext.c
+ Unwind-sjlj.c)
+set_source_files_properties(${LIBUNWIND_C_SOURCES}
+ PROPERTIES
+ COMPILE_FLAGS "-std=c99")
-set_source_files_properties(${LIBUNWIND_ASM_SOURCES} PROPERTIES LANGUAGE C)
+set(LIBUNWIND_ASM_SOURCES
+ UnwindRegistersRestore.S
+ UnwindRegistersSave.S)
+set_source_files_properties(${LIBUNWIND_ASM_SOURCES}
+ PROPERTIES
+ LANGUAGE C)
set(LIBUNWIND_HEADERS
AddressSpace.hpp
@@ -40,18 +44,15 @@ if (MSVC_IDE)
source_group("Header Files" FILES ${LIBUNWIND_HEADERS})
endif()
+set(LIBUNWIND_SOURCES
+ ${LIBUNWIND_CXX_SOURCES}
+ ${LIBUNWIND_C_SOURCES}
+ ${LIBUNWIND_ASM_SOURCES})
+
if (LIBUNWIND_ENABLE_SHARED)
- add_library(unwind SHARED
- ${LIBUNWIND_SOURCES}
- ${LIBUNWIND_ASM_SOURCES}
- ${LIBUNWIND_HEADERS}
- )
+ add_library(unwind SHARED ${LIBUNWIND_SOURCES} ${LIBUNWIND_HEADERS})
else()
- add_library(unwind STATIC
- ${LIBUNWIND_SOURCES}
- ${LIBUNWIND_ASM_SOURCES}
- ${LIBUNWIND_HEADERS}
- )
+ add_library(unwind STATIC ${LIBUNWIND_SOURCES} ${LIBUNWIND_HEADERS})
endif()
include_directories("${LIBCXXABI_LIBCXX_INCLUDES}")
@@ -68,6 +69,18 @@ target_link_libraries(unwind ${libraries})
append_if(LIBCXXABI_COMPILE_FLAGS LIBCXXABI_HAS_FPIC_FLAG -fPIC)
append_if(LIBCXXABI_LINK_FLAGS LIBCXXABI_HAS_NODEFAULTLIBS_FLAG -nodefaultlibs)
+set(LIBUNWIND_COMPILE_FLAGS)
+append_if(LIBUNWIND_COMPILE_FLAGS LIBCXXABI_HAS_NO_RTTI_FLAG -fno-rtti)
+if ( LIBCXXABI_HAS_NO_EXCEPTIONS_FLAG AND LIBCXXABI_HAS_FUNWIND_TABLES )
+ list(APPEND LIBUNWIND_COMPILE_FLAGS -fno-exceptions)
+ list(APPEND LIBUNWIND_COMPILE_FLAGS -funwind-tables)
+elseif( LIBUNWIND_ENABLE_SHARED )
+ message(FATAL_ERROR "Compiler doesn't support generation of unwind tables "
+ "if exception support is disabled. Building libunwind "
+ "DSO with runtime dependency on libcxxabi is not "
+ "supported.")
+endif()
+
set(LIBCXXABI_UNWINDER_NAME "unwind")
if ( APPLE )
@@ -86,11 +99,12 @@ if ( APPLE )
endif()
string(REPLACE ";" " " LIBCXXABI_COMPILE_FLAGS "${LIBCXXABI_COMPILE_FLAGS}")
+string(REPLACE ";" " " LIBUNWIND_COMPILE_FLAGS "${LIBUNWIND_COMPILE_FLAGS}")
string(REPLACE ";" " " LIBCXXABI_LINK_FLAGS "${LIBCXXABI_LINK_FLAGS}")
set_target_properties(unwind
PROPERTIES
- COMPILE_FLAGS "${LIBCXXABI_COMPILE_FLAGS}"
+ COMPILE_FLAGS "${LIBCXXABI_COMPILE_FLAGS} ${LIBUNWIND_COMPILE_FLAGS}"
LINK_FLAGS "${LIBCXXABI_LINK_FLAGS}"
OUTPUT_NAME "${LIBCXXABI_UNWINDER_NAME}"
VERSION "1.0"
diff --git a/src/Unwind/CompactUnwinder.hpp b/src/Unwind/CompactUnwinder.hpp
index 0dc187f..cd9ce3e 100644
--- a/src/Unwind/CompactUnwinder.hpp
+++ b/src/Unwind/CompactUnwinder.hpp
@@ -688,6 +688,6 @@ int CompactUnwinder_arm64<A>::stepWithCompactEncodingFrame(
}
-}; // namespace libunwind
+} // namespace libunwind
#endif // __COMPACT_UNWINDER_HPP__
diff --git a/src/Unwind/DwarfInstructions.hpp b/src/Unwind/DwarfInstructions.hpp
index 4fbd53c..99737e0 100644
--- a/src/Unwind/DwarfInstructions.hpp
+++ b/src/Unwind/DwarfInstructions.hpp
@@ -605,7 +605,7 @@ DwarfInstructions<A, R>::evaluateExpression(pint_t expression, A &addressSpace,
case DW_OP_lit29:
case DW_OP_lit30:
case DW_OP_lit31:
- value = opcode - DW_OP_lit0;
+ value = static_cast<pint_t>(opcode - DW_OP_lit0);
*(++sp) = value;
if (log)
fprintf(stderr, "push literal 0x%" PRIx64 "\n", (uint64_t)value);
@@ -643,14 +643,14 @@ DwarfInstructions<A, R>::evaluateExpression(pint_t expression, A &addressSpace,
case DW_OP_reg29:
case DW_OP_reg30:
case DW_OP_reg31:
- reg = opcode - DW_OP_reg0;
+ reg = static_cast<uint32_t>(opcode - DW_OP_reg0);
*(++sp) = registers.getRegister((int)reg);
if (log)
fprintf(stderr, "push reg %d\n", reg);
break;
case DW_OP_regx:
- reg = (uint32_t)addressSpace.getULEB128(p, expressionEnd);
+ reg = static_cast<uint32_t>(addressSpace.getULEB128(p, expressionEnd));
*(++sp) = registers.getRegister((int)reg);
if (log)
fprintf(stderr, "push reg %d + 0x%" PRIx64 "\n", reg, (uint64_t)svalue);
@@ -688,18 +688,18 @@ DwarfInstructions<A, R>::evaluateExpression(pint_t expression, A &addressSpace,
case DW_OP_breg29:
case DW_OP_breg30:
case DW_OP_breg31:
- reg = opcode - DW_OP_breg0;
+ reg = static_cast<uint32_t>(opcode - DW_OP_breg0);
svalue = (sint_t)addressSpace.getSLEB128(p, expressionEnd);
- svalue += registers.getRegister((int)reg);
+ svalue += static_cast<sint_t>(registers.getRegister((int)reg));
*(++sp) = (pint_t)(svalue);
if (log)
fprintf(stderr, "push reg %d + 0x%" PRIx64 "\n", reg, (uint64_t)svalue);
break;
case DW_OP_bregx:
- reg = (uint32_t)addressSpace.getULEB128(p, expressionEnd);
+ reg = static_cast<uint32_t>(addressSpace.getULEB128(p, expressionEnd));
svalue = (sint_t)addressSpace.getSLEB128(p, expressionEnd);
- svalue += registers.getRegister((int)reg);
+ svalue += static_cast<sint_t>(registers.getRegister((int)reg));
*(++sp) = (pint_t)(svalue);
if (log)
fprintf(stderr, "push reg %d + 0x%" PRIx64 "\n", reg, (uint64_t)svalue);
diff --git a/src/Unwind/DwarfParser.hpp b/src/Unwind/DwarfParser.hpp
index a9de345..f6ef738 100644
--- a/src/Unwind/DwarfParser.hpp
+++ b/src/Unwind/DwarfParser.hpp
@@ -347,7 +347,7 @@ bool CFI_Parser<A>::parseFDEInstructions(A &addressSpace,
const CIE_Info &cieInfo, pint_t upToPC,
PrologInfo *results) {
// clear results
- bzero(results, sizeof(PrologInfo));
+ memset(results, '\0', sizeof(PrologInfo));
PrologInfoStackEntry *rememberStack = NULL;
// parse CIE then FDE instructions
diff --git a/src/Unwind/EHHeaderParser.hpp b/src/Unwind/EHHeaderParser.hpp
new file mode 100644
index 0000000..7945c7b
--- /dev/null
+++ b/src/Unwind/EHHeaderParser.hpp
@@ -0,0 +1,161 @@
+//===------------------------- EHHeaderParser.hpp -------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//
+// Parses ELF .eh_frame_hdr sections.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef __EHHEADERPARSER_HPP__
+#define __EHHEADERPARSER_HPP__
+
+#include "libunwind.h"
+
+#include "AddressSpace.hpp"
+#include "DwarfParser.hpp"
+
+namespace libunwind {
+
+/// \brief EHHeaderParser does basic parsing of an ELF .eh_frame_hdr section.
+///
+/// See DWARF spec for details:
+/// http://refspecs.linuxbase.org/LSB_3.1.0/LSB-Core-generic/LSB-Core-generic/ehframechpt.html
+///
+template <typename A> class EHHeaderParser {
+public:
+ typedef typename A::pint_t pint_t;
+
+ /// Information encoded in the EH frame header.
+ struct EHHeaderInfo {
+ pint_t eh_frame_ptr;
+ size_t fde_count;
+ pint_t table;
+ uint8_t table_enc;
+ };
+
+ static void decodeEHHdr(A &addressSpace, pint_t ehHdrStart, pint_t ehHdrEnd,
+ EHHeaderInfo &ehHdrInfo);
+ static bool findFDE(A &addressSpace, pint_t pc, pint_t ehHdrStart,
+ uint32_t sectionLength,
+ typename CFI_Parser<A>::FDE_Info *fdeInfo,
+ typename CFI_Parser<A>::CIE_Info *cieInfo);
+
+private:
+ static bool decodeTableEntry(A &addressSpace, pint_t &tableEntry,
+ pint_t ehHdrStart, pint_t ehHdrEnd,
+ uint8_t tableEnc,
+ typename CFI_Parser<A>::FDE_Info *fdeInfo,
+ typename CFI_Parser<A>::CIE_Info *cieInfo);
+ static size_t getTableEntrySize(uint8_t tableEnc);
+};
+
+template <typename A>
+void EHHeaderParser<A>::decodeEHHdr(A &addressSpace, pint_t ehHdrStart,
+ pint_t ehHdrEnd, EHHeaderInfo &ehHdrInfo) {
+ pint_t p = ehHdrStart;
+ uint8_t version = addressSpace.get8(p++);
+ if (version != 1)
+ _LIBUNWIND_ABORT("Unsupported .eh_frame_hdr version");
+
+ uint8_t eh_frame_ptr_enc = addressSpace.get8(p++);
+ uint8_t fde_count_enc = addressSpace.get8(p++);
+ ehHdrInfo.table_enc = addressSpace.get8(p++);
+
+ ehHdrInfo.eh_frame_ptr =
+ addressSpace.getEncodedP(p, ehHdrEnd, eh_frame_ptr_enc, ehHdrStart);
+ ehHdrInfo.fde_count =
+ addressSpace.getEncodedP(p, ehHdrEnd, fde_count_enc, ehHdrStart);
+ ehHdrInfo.table = p;
+}
+
+template <typename A>
+bool EHHeaderParser<A>::decodeTableEntry(
+ A &addressSpace, pint_t &tableEntry, pint_t ehHdrStart, pint_t ehHdrEnd,
+ uint8_t tableEnc, typename CFI_Parser<A>::FDE_Info *fdeInfo,
+ typename CFI_Parser<A>::CIE_Info *cieInfo) {
+ // Have to decode the whole FDE for the PC range anyway, so just throw away
+ // the PC start.
+ addressSpace.getEncodedP(tableEntry, ehHdrEnd, tableEnc, ehHdrStart);
+ pint_t fde =
+ addressSpace.getEncodedP(tableEntry, ehHdrEnd, tableEnc, ehHdrStart);
+ const char *message =
+ CFI_Parser<A>::decodeFDE(addressSpace, fde, fdeInfo, cieInfo);
+ if (message != NULL) {
+ _LIBUNWIND_DEBUG_LOG("EHHeaderParser::decodeTableEntry: bad fde: %s\n",
+ message);
+ return false;
+ }
+
+ return true;
+}
+
+template <typename A>
+bool EHHeaderParser<A>::findFDE(A &addressSpace, pint_t pc, pint_t ehHdrStart,
+ uint32_t sectionLength,
+ typename CFI_Parser<A>::FDE_Info *fdeInfo,
+ typename CFI_Parser<A>::CIE_Info *cieInfo) {
+ pint_t ehHdrEnd = ehHdrStart + sectionLength;
+
+ EHHeaderParser<A>::EHHeaderInfo hdrInfo;
+ EHHeaderParser<A>::decodeEHHdr(addressSpace, ehHdrStart, ehHdrEnd, hdrInfo);
+
+ size_t tableEntrySize = getTableEntrySize(hdrInfo.table_enc);
+ pint_t tableEntry;
+
+ size_t low = 0;
+ for (size_t len = hdrInfo.fde_count; len > 1;) {
+ size_t mid = low + (len / 2);
+ tableEntry = hdrInfo.table + mid * tableEntrySize;
+ pint_t start = addressSpace.getEncodedP(tableEntry, ehHdrEnd,
+ hdrInfo.table_enc, ehHdrStart);
+
+ if (start == pc) {
+ low = mid;
+ break;
+ } else if (start < pc) {
+ low = mid;
+ len -= (len / 2);
+ } else {
+ len /= 2;
+ }
+ }
+
+ tableEntry = hdrInfo.table + low * tableEntrySize;
+ if (decodeTableEntry(addressSpace, tableEntry, ehHdrStart, ehHdrEnd,
+ hdrInfo.table_enc, fdeInfo, cieInfo)) {
+ if (pc >= fdeInfo->pcStart && pc < fdeInfo->pcEnd)
+ return true;
+ }
+
+ return false;
+}
+
+template <typename A>
+size_t EHHeaderParser<A>::getTableEntrySize(uint8_t tableEnc) {
+ switch (tableEnc & 0x0f) {
+ case DW_EH_PE_sdata2:
+ case DW_EH_PE_udata2:
+ return 4;
+ case DW_EH_PE_sdata4:
+ case DW_EH_PE_udata4:
+ return 8;
+ case DW_EH_PE_sdata8:
+ case DW_EH_PE_udata8:
+ return 16;
+ case DW_EH_PE_sleb128:
+ case DW_EH_PE_uleb128:
+ _LIBUNWIND_ABORT("Can't binary search on variable length encoded data.");
+ case DW_EH_PE_omit:
+ return 0;
+ default:
+ _LIBUNWIND_ABORT("Unknown DWARF encoding for search table.");
+ }
+}
+
+}
+
+#endif
diff --git a/src/Unwind/Registers.hpp b/src/Unwind/Registers.hpp
index 8c1acfc..4a441b7 100644
--- a/src/Unwind/Registers.hpp
+++ b/src/Unwind/Registers.hpp
@@ -89,7 +89,7 @@ private:
inline Registers_x86::Registers_x86(const void *registers) {
static_assert(sizeof(Registers_x86) < sizeof(unw_context_t),
"x86 registers do not fit into unw_context_t");
- _registers = *((GPRs *)registers);
+ memcpy(&_registers, registers, sizeof(_registers));
}
inline Registers_x86::Registers_x86() {
@@ -281,7 +281,7 @@ private:
inline Registers_x86_64::Registers_x86_64(const void *registers) {
static_assert(sizeof(Registers_x86_64) < sizeof(unw_context_t),
"x86_64 registers do not fit into unw_context_t");
- _registers = *((GPRs *)registers);
+ memcpy(&_registers, registers, sizeof(_registers));
}
inline Registers_x86_64::Registers_x86_64() {
@@ -546,9 +546,19 @@ private:
inline Registers_ppc::Registers_ppc(const void *registers) {
static_assert(sizeof(Registers_ppc) < sizeof(unw_context_t),
"ppc registers do not fit into unw_context_t");
- _registers = *((ppc_thread_state_t *)registers);
- _floatRegisters = *((ppc_float_state_t *)((char *)registers + 160));
- memcpy(_vectorRegisters, ((char *)registers + 424), sizeof(_vectorRegisters));
+ memcpy(&_registers, static_cast<const uint8_t *>(registers),
+ sizeof(_registers));
+ static_assert(sizeof(ppc_thread_state_t) == 160,
+ "expected float register offset to be 160");
+ memcpy(&_floatRegisters,
+ static_cast<const uint8_t *>(registers) + sizeof(ppc_thread_state_t),
+ sizeof(_floatRegisters));
+ static_assert(sizeof(ppc_thread_state_t) + sizeof(ppc_float_state_t) == 424,
+ "expected vector register offset to be 424 bytes");
+ memcpy(_vectorRegisters,
+ static_cast<const uint8_t *>(registers) + sizeof(ppc_thread_state_t) +
+ sizeof(ppc_float_state_t),
+ sizeof(_vectorRegisters));
}
inline Registers_ppc::Registers_ppc() {
@@ -1065,7 +1075,10 @@ inline Registers_arm64::Registers_arm64(const void *registers) {
static_assert(sizeof(Registers_arm64) < sizeof(unw_context_t),
"arm64 registers do not fit into unw_context_t");
memcpy(&_registers, registers, sizeof(_registers));
- memcpy(_vectorHalfRegisters, (((char *)registers) + 0x110),
+ static_assert(sizeof(GPRs) == 0x110,
+ "expected VFP registers to be at offset 272");
+ memcpy(_vectorHalfRegisters,
+ static_cast<const uint8_t *>(registers) + sizeof(GPRs),
sizeof(_vectorHalfRegisters));
}
diff --git a/src/Unwind/Unwind-EHABI.cpp b/src/Unwind/Unwind-EHABI.cpp
index 55bef5a..7ebba67 100644
--- a/src/Unwind/Unwind-EHABI.cpp
+++ b/src/Unwind/Unwind-EHABI.cpp
@@ -10,7 +10,9 @@
//
//===----------------------------------------------------------------------===//
-#include <unwind.h>
+#include "Unwind-EHABI.h"
+
+#if LIBCXXABI_ARM_EHABI
#include <stdbool.h>
#include <stdint.h>
@@ -18,13 +20,14 @@
#include <stdlib.h>
#include <string.h>
+#include <type_traits>
+
#include "config.h"
#include "libunwind.h"
#include "libunwind_ext.h"
#include "unwind.h"
#include "../private_typeinfo.h"
-#if LIBCXXABI_ARM_EHABI
namespace {
// Strange order: take words in order, but inside word, take from most to least
@@ -44,28 +47,24 @@ const char* getNextNibble(const char* data, uint32_t* out) {
return data + 2;
}
-static inline uint32_t signExtendPrel31(uint32_t data) {
- return data | ((data & 0x40000000u) << 1);
-}
-
struct Descriptor {
- // See # 9.2
- typedef enum {
- SU16 = 0, // Short descriptor, 16-bit entries
- LU16 = 1, // Long descriptor, 16-bit entries
- LU32 = 3, // Long descriptor, 32-bit entries
- RESERVED0 = 4, RESERVED1 = 5, RESERVED2 = 6, RESERVED3 = 7,
- RESERVED4 = 8, RESERVED5 = 9, RESERVED6 = 10, RESERVED7 = 11,
- RESERVED8 = 12, RESERVED9 = 13, RESERVED10 = 14, RESERVED11 = 15
- } Format;
-
- // See # 9.2
- typedef enum {
- CLEANUP = 0x0,
- FUNC = 0x1,
- CATCH = 0x2,
- INVALID = 0x4
- } Kind;
+ // See # 9.2
+ typedef enum {
+ SU16 = 0, // Short descriptor, 16-bit entries
+ LU16 = 1, // Long descriptor, 16-bit entries
+ LU32 = 3, // Long descriptor, 32-bit entries
+ RESERVED0 = 4, RESERVED1 = 5, RESERVED2 = 6, RESERVED3 = 7,
+ RESERVED4 = 8, RESERVED5 = 9, RESERVED6 = 10, RESERVED7 = 11,
+ RESERVED8 = 12, RESERVED9 = 13, RESERVED10 = 14, RESERVED11 = 15
+ } Format;
+
+ // See # 9.2
+ typedef enum {
+ CLEANUP = 0x0,
+ FUNC = 0x1,
+ CATCH = 0x2,
+ INVALID = 0x4
+ } Kind;
};
_Unwind_Reason_Code ProcessDescriptors(
@@ -135,7 +134,7 @@ _Unwind_Reason_Code ProcessDescriptors(
landing_pad = signExtendPrel31(landing_pad & ~0x80000000);
if (landing_pad == 0xffffffff) {
return _URC_HANDLER_FOUND;
- } else if (landing_pad == 0xfffffffe ) {
+ } else if (landing_pad == 0xfffffffe) {
return _URC_FAILURE;
} else {
/*
@@ -154,7 +153,7 @@ _Unwind_Reason_Code ProcessDescriptors(
}
default:
_LIBUNWIND_ABORT("Invalid descriptor kind found.");
- };
+ }
getNextWord(descriptor, &descriptorWord);
}
@@ -162,10 +161,9 @@ _Unwind_Reason_Code ProcessDescriptors(
return _URC_CONTINUE_UNWIND;
}
-_Unwind_Reason_Code unwindOneFrame(
- _Unwind_State state,
- _Unwind_Control_Block* ucbp,
- struct _Unwind_Context* context) {
+static _Unwind_Reason_Code unwindOneFrame(_Unwind_State state,
+ _Unwind_Control_Block* ucbp,
+ struct _Unwind_Context* context) {
// Read the compact model EHT entry's header # 6.3
const uint32_t* unwindingData = ucbp->pr_cache.ehtp;
assert((*unwindingData & 0xf0000000) == 0x80000000 && "Must be a compact entry");
@@ -206,28 +204,6 @@ uint32_t RegisterRange(uint8_t start, uint8_t count_minus_one) {
} // end anonymous namespace
-uintptr_t _Unwind_GetGR(struct _Unwind_Context* context, int index) {
- uintptr_t value = 0;
- _Unwind_VRS_Get(context, _UVRSC_CORE, (uint32_t)index, _UVRSD_UINT32, &value);
- return value;
-}
-
-void _Unwind_SetGR(struct _Unwind_Context* context, int index, uintptr_t
- new_value) {
- _Unwind_VRS_Set(context, _UVRSC_CORE, (uint32_t)index,
- _UVRSD_UINT32, &new_value);
-}
-
-uintptr_t _Unwind_GetIP(struct _Unwind_Context* context) {
- // remove the thumb-bit before returning
- return (_Unwind_GetGR(context, 15) & (~(uintptr_t)0x1));
-}
-
-void _Unwind_SetIP(struct _Unwind_Context* context, uintptr_t new_value) {
- uintptr_t thumb_bit = _Unwind_GetGR(context, 15) & ((uintptr_t)0x1);
- _Unwind_SetGR(context, 15, new_value | thumb_bit);
-}
-
/**
* Decodes an EHT entry.
*
@@ -238,44 +214,27 @@ void _Unwind_SetIP(struct _Unwind_Context* context, uintptr_t new_value) {
*/
extern "C" const uint32_t*
decode_eht_entry(const uint32_t* data, size_t* off, size_t* len) {
- if ((*data & 0x80000000) == 0) {
- // 6.2: Generic Model
- // EHT entry is a prel31 pointing to the PR, followed by data understood only
- // by the personality routine. Since EHABI doesn't guarantee the location or
- // availability of the unwind opcodes in the generic model, we have to check
- // for them on a case-by-case basis:
- _Unwind_Reason_Code __gxx_personality_v0(int version, _Unwind_Action actions,
- uint64_t exceptionClass,
- _Unwind_Exception* unwind_exception,
- _Unwind_Context* context);
- void *PR = (void*)signExtendPrel31(*data);
- if (PR == (void*)&__gxx_personality_v0) {
- *off = 1; // First byte is size data.
- *len = (((data[1] >> 24) & 0xff) + 1) * 4;
- } else
+ assert((*data & 0x80000000) != 0 &&
+ "decode_eht_entry() does not support user-defined personality");
+
+ // 6.3: ARM Compact Model
+ // EHT entries here correspond to the __aeabi_unwind_cpp_pr[012] PRs indeded
+ // by format:
+ Descriptor::Format format =
+ static_cast<Descriptor::Format>((*data & 0x0f000000) >> 24);
+ switch (format) {
+ case Descriptor::SU16:
+ *len = 4;
+ *off = 1;
+ break;
+ case Descriptor::LU16:
+ case Descriptor::LU32:
+ *len = 4 + 4 * ((*data & 0x00ff0000) >> 16);
+ *off = 2;
+ break;
+ default:
return nullptr;
- data++; // Skip the first word, which is the prel31 offset.
- } else {
- // 6.3: ARM Compact Model
- // EHT entries here correspond to the __aeabi_unwind_cpp_pr[012] PRs indeded
- // by format:
- Descriptor::Format format =
- static_cast<Descriptor::Format>((*data & 0x0f000000) >> 24);
- switch (format) {
- case Descriptor::SU16:
- *len = 4;
- *off = 1;
- break;
- case Descriptor::LU16:
- case Descriptor::LU32:
- *len = 4 + 4 * ((*data & 0x00ff0000) >> 16);
- *off = 2;
- break;
- default:
- return nullptr;
- }
}
-
return data;
}
@@ -367,7 +326,8 @@ _Unwind_Reason_Code _Unwind_VRS_Interpret(
case 0xb3: {
uint8_t v = getByte(data, offset++);
_Unwind_VRS_Pop(context, _UVRSC_VFP,
- RegisterRange(v >> 4, v & 0x0f), _UVRSD_VFPX);
+ RegisterRange(static_cast<uint8_t>(v >> 4),
+ v & 0x0f), _UVRSD_VFPX);
break;
}
case 0xb4:
@@ -395,7 +355,7 @@ _Unwind_Reason_Code _Unwind_VRS_Interpret(
break;
case 0xc6: {
uint8_t v = getByte(data, offset++);
- uint8_t start = v >> 4;
+ uint8_t start = static_cast<uint8_t>(v >> 4);
uint8_t count_minus_one = v & 0xf;
if (start + count_minus_one >= 16)
return _URC_FAILURE;
@@ -414,7 +374,8 @@ _Unwind_Reason_Code _Unwind_VRS_Interpret(
case 0xc8:
case 0xc9: {
uint8_t v = getByte(data, offset++);
- uint8_t start = ((byte == 0xc8) ? 16 : 0) + (v >> 4);
+ uint8_t start =
+ static_cast<uint8_t>(((byte == 0xc8) ? 16 : 0) + (v >> 4));
uint8_t count_minus_one = v & 0xf;
if (start + count_minus_one >= 32)
return _URC_FAILURE;
@@ -488,13 +449,13 @@ unwind_phase1(unw_context_t *uc, _Unwind_Exception *exception_object) {
int stepResult = unw_step(&cursor1);
if (stepResult == 0) {
_LIBUNWIND_TRACE_UNWINDING("unwind_phase1(ex_ojb=%p): unw_step() reached "
- "bottom => _URC_END_OF_STACK\n",
- exception_object);
+ "bottom => _URC_END_OF_STACK\n",
+ static_cast<void *>(exception_object));
return _URC_END_OF_STACK;
} else if (stepResult < 0) {
_LIBUNWIND_TRACE_UNWINDING("unwind_phase1(ex_ojb=%p): unw_step failed => "
- "_URC_FATAL_PHASE1_ERROR\n",
- exception_object);
+ "_URC_FATAL_PHASE1_ERROR\n",
+ static_cast<void *>(exception_object));
return _URC_FATAL_PHASE1_ERROR;
}
@@ -502,26 +463,28 @@ unwind_phase1(unw_context_t *uc, _Unwind_Exception *exception_object) {
unw_proc_info_t frameInfo;
if (unw_get_proc_info(&cursor1, &frameInfo) != UNW_ESUCCESS) {
_LIBUNWIND_TRACE_UNWINDING("unwind_phase1(ex_ojb=%p): unw_get_proc_info "
- "failed => _URC_FATAL_PHASE1_ERROR\n",
- exception_object);
+ "failed => _URC_FATAL_PHASE1_ERROR\n",
+ static_cast<void *>(exception_object));
return _URC_FATAL_PHASE1_ERROR;
}
// When tracing, print state information.
if (_LIBUNWIND_TRACING_UNWINDING) {
- char functionName[512];
+ char functionBuf[512];
+ const char *functionName = functionBuf;
unw_word_t offset;
- if ((unw_get_proc_name(&cursor1, functionName, 512, &offset) !=
- UNW_ESUCCESS) || (frameInfo.start_ip + offset > frameInfo.end_ip))
- strcpy(functionName, ".anonymous.");
+ if ((unw_get_proc_name(&cursor1, functionBuf, sizeof(functionBuf),
+ &offset) != UNW_ESUCCESS) ||
+ (frameInfo.start_ip + offset > frameInfo.end_ip))
+ functionName = ".anonymous.";
unw_word_t pc;
unw_get_reg(&cursor1, UNW_REG_IP, &pc);
_LIBUNWIND_TRACE_UNWINDING(
"unwind_phase1(ex_ojb=%p): pc=0x%llX, start_ip=0x%llX, func=%s, "
"lsda=0x%llX, personality=0x%llX\n",
- exception_object, (long long)pc, (long long)frameInfo.start_ip,
- functionName, (long long)frameInfo.lsda,
- (long long)frameInfo.handler);
+ static_cast<void *>(exception_object), (long long)pc,
+ (long long)frameInfo.start_ip, functionName,
+ (long long)frameInfo.lsda, (long long)frameInfo.handler);
}
// If there is a personality routine, ask it if it will want to stop at
@@ -531,7 +494,8 @@ unwind_phase1(unw_context_t *uc, _Unwind_Exception *exception_object) {
(__personality_routine)(long)(frameInfo.handler);
_LIBUNWIND_TRACE_UNWINDING(
"unwind_phase1(ex_ojb=%p): calling personality function %p\n",
- exception_object, p);
+ static_cast<void *>(exception_object),
+ reinterpret_cast<void *>(reinterpret_cast<uintptr_t>(p)));
struct _Unwind_Context *context = (struct _Unwind_Context *)(&cursor1);
exception_object->pr_cache.fnstart = frameInfo.start_ip;
exception_object->pr_cache.ehtp =
@@ -540,10 +504,11 @@ unwind_phase1(unw_context_t *uc, _Unwind_Exception *exception_object) {
_Unwind_Reason_Code personalityResult =
(*p)(_US_VIRTUAL_UNWIND_FRAME, exception_object, context);
_LIBUNWIND_TRACE_UNWINDING(
- "unwind_phase1(ex_ojb=%p): personality result %d "
- "start_ip %x ehtp %p additional %x\n",
- exception_object, personalityResult,
- exception_object->pr_cache.fnstart, exception_object->pr_cache.ehtp,
+ "unwind_phase1(ex_ojb=%p): personality result %d start_ip %x ehtp %p "
+ "additional %x\n",
+ static_cast<void *>(exception_object), personalityResult,
+ exception_object->pr_cache.fnstart,
+ static_cast<void *>(exception_object->pr_cache.ehtp),
exception_object->pr_cache.additional);
switch (personalityResult) {
case _URC_HANDLER_FOUND:
@@ -551,15 +516,15 @@ unwind_phase1(unw_context_t *uc, _Unwind_Exception *exception_object) {
// stop search and remember stack pointer at the frame
handlerNotFound = false;
// p should have initialized barrier_cache. EHABI #7.3.5
- _LIBUNWIND_TRACE_UNWINDING("unwind_phase1(ex_ojb=%p): "
- "_URC_HANDLER_FOUND \n",
- exception_object);
+ _LIBUNWIND_TRACE_UNWINDING(
+ "unwind_phase1(ex_ojb=%p): _URC_HANDLER_FOUND \n",
+ static_cast<void *>(exception_object));
return _URC_NO_REASON;
case _URC_CONTINUE_UNWIND:
_LIBUNWIND_TRACE_UNWINDING(
"unwind_phase1(ex_ojb=%p): _URC_CONTINUE_UNWIND\n",
- exception_object);
+ static_cast<void *>(exception_object));
// continue unwinding
break;
@@ -571,7 +536,7 @@ unwind_phase1(unw_context_t *uc, _Unwind_Exception *exception_object) {
// something went wrong
_LIBUNWIND_TRACE_UNWINDING(
"unwind_phase1(ex_ojb=%p): _URC_FATAL_PHASE1_ERROR\n",
- exception_object);
+ static_cast<void *>(exception_object));
return _URC_FATAL_PHASE1_ERROR;
}
}
@@ -586,7 +551,8 @@ static _Unwind_Reason_Code unwind_phase2(unw_context_t *uc,
unw_cursor_t cursor2;
unw_init_local(&cursor2, uc);
- _LIBUNWIND_TRACE_UNWINDING("unwind_phase2(ex_ojb=%p)\n", exception_object);
+ _LIBUNWIND_TRACE_UNWINDING("unwind_phase2(ex_ojb=%p)\n",
+ static_cast<void *>(exception_object));
int frame_count = 0;
// Walk each frame until we reach where search phase said to stop.
@@ -613,13 +579,13 @@ static _Unwind_Reason_Code unwind_phase2(unw_context_t *uc,
int stepResult = unw_step(&cursor2);
if (stepResult == 0) {
_LIBUNWIND_TRACE_UNWINDING("unwind_phase2(ex_ojb=%p): unw_step() reached "
- "bottom => _URC_END_OF_STACK\n",
- exception_object);
+ "bottom => _URC_END_OF_STACK\n",
+ static_cast<void *>(exception_object));
return _URC_END_OF_STACK;
} else if (stepResult < 0) {
_LIBUNWIND_TRACE_UNWINDING("unwind_phase2(ex_ojb=%p): unw_step failed => "
- "_URC_FATAL_PHASE1_ERROR\n",
- exception_object);
+ "_URC_FATAL_PHASE1_ERROR\n",
+ static_cast<void *>(exception_object));
return _URC_FATAL_PHASE2_ERROR;
}
@@ -629,23 +595,25 @@ static _Unwind_Reason_Code unwind_phase2(unw_context_t *uc,
unw_get_reg(&cursor2, UNW_REG_SP, &sp);
if (unw_get_proc_info(&cursor2, &frameInfo) != UNW_ESUCCESS) {
_LIBUNWIND_TRACE_UNWINDING("unwind_phase2(ex_ojb=%p): unw_get_proc_info "
- "failed => _URC_FATAL_PHASE1_ERROR\n",
- exception_object);
+ "failed => _URC_FATAL_PHASE1_ERROR\n",
+ static_cast<void *>(exception_object));
return _URC_FATAL_PHASE2_ERROR;
}
// When tracing, print state information.
if (_LIBUNWIND_TRACING_UNWINDING) {
- char functionName[512];
+ char functionBuf[512];
+ const char *functionName = functionBuf;
unw_word_t offset;
- if ((unw_get_proc_name(&cursor2, functionName, 512, &offset) !=
- UNW_ESUCCESS) || (frameInfo.start_ip + offset > frameInfo.end_ip))
- strcpy(functionName, ".anonymous.");
+ if ((unw_get_proc_name(&cursor2, functionBuf, sizeof(functionBuf),
+ &offset) != UNW_ESUCCESS) ||
+ (frameInfo.start_ip + offset > frameInfo.end_ip))
+ functionName = ".anonymous.";
_LIBUNWIND_TRACE_UNWINDING(
"unwind_phase2(ex_ojb=%p): start_ip=0x%llX, func=%s, sp=0x%llX, "
"lsda=0x%llX, personality=0x%llX\n",
- exception_object, (long long)frameInfo.start_ip, functionName,
- (long long)sp, (long long)frameInfo.lsda,
+ static_cast<void *>(exception_object), (long long)frameInfo.start_ip,
+ functionName, (long long)sp, (long long)frameInfo.lsda,
(long long)frameInfo.handler);
}
@@ -666,7 +634,7 @@ static _Unwind_Reason_Code unwind_phase2(unw_context_t *uc,
// Continue unwinding
_LIBUNWIND_TRACE_UNWINDING(
"unwind_phase2(ex_ojb=%p): _URC_CONTINUE_UNWIND\n",
- exception_object);
+ static_cast<void *>(exception_object));
// EHABI #7.2
if (sp == exception_object->barrier_cache.sp) {
// Phase 1 said we would stop at this frame, but we did not...
@@ -677,17 +645,17 @@ static _Unwind_Reason_Code unwind_phase2(unw_context_t *uc,
case _URC_INSTALL_CONTEXT:
_LIBUNWIND_TRACE_UNWINDING(
"unwind_phase2(ex_ojb=%p): _URC_INSTALL_CONTEXT\n",
- exception_object);
+ static_cast<void *>(exception_object));
// Personality routine says to transfer control to landing pad.
// We may get control back if landing pad calls _Unwind_Resume().
if (_LIBUNWIND_TRACING_UNWINDING) {
unw_word_t pc;
unw_get_reg(&cursor2, UNW_REG_IP, &pc);
unw_get_reg(&cursor2, UNW_REG_SP, &sp);
- _LIBUNWIND_TRACE_UNWINDING("unwind_phase2(ex_ojb=%p): re-entering "
+ _LIBUNWIND_TRACE_UNWINDING("unwind_phase2(ex_ojb=%p): re-entering "
"user code with ip=0x%llX, sp=0x%llX\n",
- exception_object, (long long)pc,
- (long long)sp);
+ static_cast<void *>(exception_object),
+ (long long)pc, (long long)sp);
}
{
@@ -724,7 +692,7 @@ static _Unwind_Reason_Code unwind_phase2(unw_context_t *uc,
_LIBUNWIND_EXPORT _Unwind_Reason_Code
_Unwind_RaiseException(_Unwind_Exception *exception_object) {
_LIBUNWIND_TRACE_API("_Unwind_RaiseException(ex_obj=%p)\n",
- exception_object);
+ static_cast<void *>(exception_object));
unw_context_t uc;
unw_getcontext(&uc);
@@ -760,7 +728,8 @@ _LIBUNWIND_EXPORT void _Unwind_Complete(_Unwind_Exception* exception_object) {
/// in turn calls _Unwind_Resume_or_Rethrow().
_LIBUNWIND_EXPORT void
_Unwind_Resume(_Unwind_Exception *exception_object) {
- _LIBUNWIND_TRACE_API("_Unwind_Resume(ex_obj=%p)\n", exception_object);
+ _LIBUNWIND_TRACE_API("_Unwind_Resume(ex_obj=%p)\n",
+ static_cast<void *>(exception_object));
unw_context_t uc;
unw_getcontext(&uc);
@@ -781,8 +750,9 @@ _Unwind_GetLanguageSpecificData(struct _Unwind_Context *context) {
uintptr_t result = 0;
if (unw_get_proc_info(cursor, &frameInfo) == UNW_ESUCCESS)
result = (uintptr_t)frameInfo.lsda;
- _LIBUNWIND_TRACE_API("_Unwind_GetLanguageSpecificData(context=%p)"
- "=> 0x%llx\n", context, (long long)result);
+ _LIBUNWIND_TRACE_API(
+ "_Unwind_GetLanguageSpecificData(context=%p) => 0x%llx\n",
+ static_cast<void *>(context), (long long)result);
if (result != 0) {
if (*((uint8_t *)result) != 0xFF)
_LIBUNWIND_DEBUG_LOG("lsda at 0x%llx does not start with 0xFF\n",
@@ -809,15 +779,14 @@ static uint64_t ValueAsBitPattern(_Unwind_VRS_DataRepresentation representation,
return value;
}
-_Unwind_VRS_Result _Unwind_VRS_Set(
- _Unwind_Context *context,
- _Unwind_VRS_RegClass regclass,
- uint32_t regno,
- _Unwind_VRS_DataRepresentation representation,
- void *valuep) {
+_Unwind_VRS_Result
+_Unwind_VRS_Set(_Unwind_Context *context, _Unwind_VRS_RegClass regclass,
+ uint32_t regno, _Unwind_VRS_DataRepresentation representation,
+ void *valuep) {
_LIBUNWIND_TRACE_API("_Unwind_VRS_Set(context=%p, regclass=%d, reg=%d, "
- "rep=%d, value=0x%llX)\n", context, regclass,
- regno, representation,
+ "rep=%d, value=0x%llX)\n",
+ static_cast<void *>(context), regclass, regno,
+ representation,
ValueAsBitPattern(representation, valuep));
unw_cursor_t *cursor = (unw_cursor_t *)context;
switch (regclass) {
@@ -859,14 +828,14 @@ _Unwind_VRS_Result _Unwind_VRS_Set(
? _UVRSR_OK
: _UVRSR_FAILED;
}
+ _LIBUNWIND_ABORT("unsupported register class");
}
-static _Unwind_VRS_Result _Unwind_VRS_Get_Internal(
- _Unwind_Context *context,
- _Unwind_VRS_RegClass regclass,
- uint32_t regno,
- _Unwind_VRS_DataRepresentation representation,
- void *valuep) {
+static _Unwind_VRS_Result
+_Unwind_VRS_Get_Internal(_Unwind_Context *context,
+ _Unwind_VRS_RegClass regclass, uint32_t regno,
+ _Unwind_VRS_DataRepresentation representation,
+ void *valuep) {
unw_cursor_t *cursor = (unw_cursor_t *)context;
switch (regclass) {
case _UVRSC_CORE:
@@ -907,6 +876,7 @@ static _Unwind_VRS_Result _Unwind_VRS_Get_Internal(
? _UVRSR_OK
: _UVRSR_FAILED;
}
+ _LIBUNWIND_ABORT("unsupported register class");
}
_Unwind_VRS_Result _Unwind_VRS_Get(
@@ -920,19 +890,20 @@ _Unwind_VRS_Result _Unwind_VRS_Get(
valuep);
_LIBUNWIND_TRACE_API("_Unwind_VRS_Get(context=%p, regclass=%d, reg=%d, "
"rep=%d, value=0x%llX, result = %d)\n",
- context, regclass, regno, representation,
+ static_cast<void *>(context), regclass, regno,
+ representation,
ValueAsBitPattern(representation, valuep), result);
return result;
}
-_Unwind_VRS_Result _Unwind_VRS_Pop(
- _Unwind_Context *context,
- _Unwind_VRS_RegClass regclass,
- uint32_t discriminator,
- _Unwind_VRS_DataRepresentation representation) {
+_Unwind_VRS_Result
+_Unwind_VRS_Pop(_Unwind_Context *context, _Unwind_VRS_RegClass regclass,
+ uint32_t discriminator,
+ _Unwind_VRS_DataRepresentation representation) {
_LIBUNWIND_TRACE_API("_Unwind_VRS_Pop(context=%p, regclass=%d, "
"discriminator=%d, representation=%d)\n",
- context, regclass, discriminator, representation);
+ static_cast<void *>(context), regclass, discriminator,
+ representation);
switch (regclass) {
case _UVRSC_CORE:
case _UVRSC_WMMXC: {
@@ -947,7 +918,7 @@ _Unwind_VRS_Result _Unwind_VRS_Pop(
return _UVRSR_FAILED;
}
for (uint32_t i = 0; i < 16; ++i) {
- if (!(discriminator & (1 << i)))
+ if (!(discriminator & static_cast<uint32_t>(1 << i)))
continue;
uint32_t value = *sp++;
if (regclass == _UVRSC_CORE && i == 13)
@@ -990,7 +961,8 @@ _Unwind_VRS_Result _Unwind_VRS_Pop(
return _Unwind_VRS_Set(context, _UVRSC_CORE, UNW_ARM_SP, _UVRSD_UINT32,
&sp);
}
- };
+ }
+ _LIBUNWIND_ABORT("unsupported register class");
}
/// Called by personality handler during phase 2 to find the start of the
@@ -1003,7 +975,7 @@ _Unwind_GetRegionStart(struct _Unwind_Context *context) {
if (unw_get_proc_info(cursor, &frameInfo) == UNW_ESUCCESS)
result = (uintptr_t)frameInfo.start_ip;
_LIBUNWIND_TRACE_API("_Unwind_GetRegionStart(context=%p) => 0x%llX\n",
- context, (long long)result);
+ static_cast<void *>(context), (long long)result);
return result;
}
@@ -1013,7 +985,7 @@ _Unwind_GetRegionStart(struct _Unwind_Context *context) {
_LIBUNWIND_EXPORT void
_Unwind_DeleteException(_Unwind_Exception *exception_object) {
_LIBUNWIND_TRACE_API("_Unwind_DeleteException(ex_obj=%p)\n",
- exception_object);
+ static_cast<void *>(exception_object));
if (exception_object->exception_cleanup != NULL)
(*exception_object->exception_cleanup)(_URC_FOREIGN_EXCEPTION_CAUGHT,
exception_object);
diff --git a/src/Unwind/Unwind-EHABI.h b/src/Unwind/Unwind-EHABI.h
new file mode 100644
index 0000000..ebd56a1
--- /dev/null
+++ b/src/Unwind/Unwind-EHABI.h
@@ -0,0 +1,51 @@
+//===------------------------- Unwind-EHABI.hpp ---------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef __UNWIND_EHABI_H__
+#define __UNWIND_EHABI_H__
+
+#include <__cxxabi_config.h>
+
+#if LIBCXXABI_ARM_EHABI
+
+#include <stdint.h>
+#include <unwind.h>
+
+// Unable to unwind in the ARM index table (section 5 EHABI).
+#define UNW_EXIDX_CANTUNWIND 0x1
+
+static inline uint32_t signExtendPrel31(uint32_t data) {
+ return data | ((data & 0x40000000u) << 1);
+}
+
+static inline uint32_t readPrel31(const uint32_t *data) {
+ return (((uint32_t)(uintptr_t)data) + signExtendPrel31(*data));
+}
+
+#if defined(__cplusplus)
+extern "C" {
+#endif
+
+extern _Unwind_Reason_Code __aeabi_unwind_cpp_pr0(
+ _Unwind_State state, _Unwind_Control_Block *ucbp, _Unwind_Context *context);
+
+extern _Unwind_Reason_Code __aeabi_unwind_cpp_pr1(
+ _Unwind_State state, _Unwind_Control_Block *ucbp, _Unwind_Context *context);
+
+extern _Unwind_Reason_Code __aeabi_unwind_cpp_pr2(
+ _Unwind_State state, _Unwind_Control_Block *ucbp, _Unwind_Context *context);
+
+#if defined(__cplusplus)
+} // extern "C"
+#endif
+
+#endif // LIBCXXABI_ARM_EHABI
+
+#endif // __UNWIND_EHABI_H__
diff --git a/src/Unwind/UnwindCursor.hpp b/src/Unwind/UnwindCursor.hpp
index 0350dfd..b4d413f 100644
--- a/src/Unwind/UnwindCursor.hpp
+++ b/src/Unwind/UnwindCursor.hpp
@@ -19,17 +19,20 @@
#include <pthread.h>
#include <unwind.h>
-#if __APPLE__
+#ifdef __APPLE__
#include <mach-o/dyld.h>
#endif
-#include "libunwind.h"
+#include "config.h"
#include "AddressSpace.hpp"
-#include "Registers.hpp"
-#include "DwarfInstructions.hpp"
#include "CompactUnwinder.hpp"
#include "config.h"
+#include "DwarfInstructions.hpp"
+#include "EHHeaderParser.hpp"
+#include "libunwind.h"
+#include "Registers.hpp"
+#include "Unwind-EHABI.h"
namespace libunwind {
@@ -58,7 +61,7 @@ private:
// These fields are all static to avoid needing an initializer.
// There is only one instance of this class per process.
static pthread_rwlock_t _lock;
-#if __APPLE__
+#ifdef __APPLE__
static void dyldUnloadHook(const struct mach_header *mh, intptr_t slide);
static bool _registeredForDyldUnloads;
#endif
@@ -87,7 +90,7 @@ typename DwarfFDECache<A>::entry DwarfFDECache<A>::_initialBuffer[64];
template <typename A>
pthread_rwlock_t DwarfFDECache<A>::_lock = PTHREAD_RWLOCK_INITIALIZER;
-#if __APPLE__
+#ifdef __APPLE__
template <typename A>
bool DwarfFDECache<A>::_registeredForDyldUnloads = false;
#endif
@@ -129,7 +132,7 @@ void DwarfFDECache<A>::add(pint_t mh, pint_t ip_start, pint_t ip_end,
_bufferUsed->ip_end = ip_end;
_bufferUsed->fde = fde;
++_bufferUsed;
-#if __APPLE__
+#ifdef __APPLE__
if (!_registeredForDyldUnloads) {
_dyld_register_func_for_remove_image(&dyldUnloadHook);
_registeredForDyldUnloads = true;
@@ -153,7 +156,7 @@ void DwarfFDECache<A>::removeAllIn(pint_t mh) {
_LIBUNWIND_LOG_NON_ZERO(::pthread_rwlock_unlock(&_lock));
}
-#if __APPLE__
+#ifdef __APPLE__
template <typename A>
void DwarfFDECache<A>::dyldUnloadHook(const struct mach_header *mh, intptr_t ) {
removeAllIn((pint_t) mh);
@@ -364,29 +367,49 @@ private:
};
#endif // _LIBUNWIND_SUPPORT_COMPACT_UNWIND
-
class _LIBUNWIND_HIDDEN AbstractUnwindCursor {
public:
- virtual ~AbstractUnwindCursor() {}
- virtual bool validReg(int) = 0;
- virtual unw_word_t getReg(int) = 0;
- virtual void setReg(int, unw_word_t) = 0;
- virtual bool validFloatReg(int) = 0;
- virtual unw_fpreg_t getFloatReg(int) = 0;
- virtual void setFloatReg(int, unw_fpreg_t) = 0;
- virtual int step() = 0;
- virtual void getInfo(unw_proc_info_t *) = 0;
- virtual void jumpto() = 0;
- virtual bool isSignalFrame() = 0;
- virtual bool getFunctionName(char *bf, size_t ln, unw_word_t *off) = 0;
- virtual void setInfoBasedOnIPRegister(bool isReturnAddr = false) = 0;
- virtual const char *getRegisterName(int num) = 0;
-#if __arm__
- virtual void saveVFPAsX() = 0;
+ // NOTE: provide a class specific placement deallocation function (S5.3.4 p20)
+ // This avoids an unnecessary dependency to libc++abi.
+ void operator delete(void *, size_t) {}
+
+ virtual ~AbstractUnwindCursor() {}
+ virtual bool validReg(int) { _LIBUNWIND_ABORT("validReg not implemented"); }
+ virtual unw_word_t getReg(int) { _LIBUNWIND_ABORT("getReg not implemented"); }
+ virtual void setReg(int, unw_word_t) {
+ _LIBUNWIND_ABORT("setReg not implemented");
+ }
+ virtual bool validFloatReg(int) {
+ _LIBUNWIND_ABORT("validFloatReg not implemented");
+ }
+ virtual unw_fpreg_t getFloatReg(int) {
+ _LIBUNWIND_ABORT("getFloatReg not implemented");
+ }
+ virtual void setFloatReg(int, unw_fpreg_t) {
+ _LIBUNWIND_ABORT("setFloatReg not implemented");
+ }
+ virtual int step() { _LIBUNWIND_ABORT("step not implemented"); }
+ virtual void getInfo(unw_proc_info_t *) {
+ _LIBUNWIND_ABORT("getInfo not implemented");
+ }
+ virtual void jumpto() { _LIBUNWIND_ABORT("jumpto not implemented"); }
+ virtual bool isSignalFrame() {
+ _LIBUNWIND_ABORT("isSignalFrame not implemented");
+ }
+ virtual bool getFunctionName(char *, size_t, unw_word_t *) {
+ _LIBUNWIND_ABORT("getFunctionName not implemented");
+ }
+ virtual void setInfoBasedOnIPRegister(bool = false) {
+ _LIBUNWIND_ABORT("setInfoBasedOnIPRegister not implemented");
+ }
+ virtual const char *getRegisterName(int) {
+ _LIBUNWIND_ABORT("getRegisterName not implemented");
+ }
+#ifdef __arm__
+ virtual void saveVFPAsX() { _LIBUNWIND_ABORT("saveVFPAsX not implemented"); }
#endif
};
-
/// UnwindCursor contains all state (including all register values) during
/// an unwind. This is normally stack allocated inside a unw_cursor_t.
template <typename A, typename R>
@@ -409,12 +432,10 @@ public:
virtual bool getFunctionName(char *buf, size_t len, unw_word_t *off);
virtual void setInfoBasedOnIPRegister(bool isReturnAddress = false);
virtual const char *getRegisterName(int num);
-#if __arm__
+#ifdef __arm__
virtual void saveVFPAsX();
#endif
- void operator delete(void *, size_t) {}
-
private:
#if LIBCXXABI_ARM_EHABI
@@ -584,7 +605,7 @@ template <typename A, typename R> void UnwindCursor<A, R>::jumpto() {
_registers.jumpto();
}
-#if __arm__
+#ifdef __arm__
template <typename A, typename R> void UnwindCursor<A, R>::saveVFPAsX() {
_registers.saveVFPAsX();
}
@@ -605,20 +626,6 @@ struct EHABIIndexEntry {
uint32_t data;
};
-// Unable to unwind in the ARM index table (section 5 EHABI).
-#define UNW_EXIDX_CANTUNWIND 0x1
-
-static inline uint32_t signExtendPrel31(uint32_t data) {
- return data | ((data & 0x40000000u) << 1);
-}
-
-extern "C" _Unwind_Reason_Code __aeabi_unwind_cpp_pr0(
- _Unwind_State state, _Unwind_Control_Block *ucbp, _Unwind_Context *context);
-extern "C" _Unwind_Reason_Code __aeabi_unwind_cpp_pr1(
- _Unwind_State state, _Unwind_Control_Block *ucbp, _Unwind_Context *context);
-extern "C" _Unwind_Reason_Code __aeabi_unwind_cpp_pr2(
- _Unwind_State state, _Unwind_Control_Block *ucbp, _Unwind_Context *context);
-
template<typename A>
struct EHABISectionIterator {
typedef EHABISectionIterator _Self;
@@ -730,8 +737,8 @@ bool UnwindCursor<A, R>::getInfoFromEHABISection(
// in compact form (section 6.3 EHABI).
if (exceptionTableData & 0x80000000) {
// Grab the index of the personality routine from the compact form.
- int choice = (exceptionTableData & 0x0f000000) >> 24;
- int extraWords = 0;
+ uint32_t choice = (exceptionTableData & 0x0f000000) >> 24;
+ uint32_t extraWords = 0;
switch (choice) {
case 0:
personalityRoutine = (unw_word_t) &__aeabi_unwind_cpp_pr0;
@@ -823,8 +830,9 @@ bool UnwindCursor<A, R>::getInfoFromDwarfSection(pint_t pc,
}
#if _LIBUNWIND_SUPPORT_DWARF_INDEX
if (!foundFDE && (sects.dwarf_index_section != 0)) {
- // Have eh_frame_hdr section which is index into dwarf section.
- // TO DO: implement index search
+ foundFDE = EHHeaderParser<A>::findFDE(
+ _addressSpace, pc, sects.dwarf_index_section,
+ (uint32_t)sects.dwarf_index_section_length, &fdeInfo, &cieInfo);
}
#endif
if (!foundFDE) {
@@ -1304,6 +1312,6 @@ bool UnwindCursor<A, R>::getFunctionName(char *buf, size_t bufLen,
buf, bufLen, offset);
}
-}; // namespace libunwind
+} // namespace libunwind
#endif // __UNWINDCURSOR_HPP__
diff --git a/src/Unwind/UnwindLevel1-gcc-ext.c b/src/Unwind/UnwindLevel1-gcc-ext.c
index c119d57..b1e3f77 100644
--- a/src/Unwind/UnwindLevel1-gcc-ext.c
+++ b/src/Unwind/UnwindLevel1-gcc-ext.c
@@ -16,10 +16,11 @@
#include <stdio.h>
#include <stdlib.h>
+#include "config.h"
+#include "libunwind_ext.h"
#include "libunwind.h"
+#include "Unwind-EHABI.h"
#include "unwind.h"
-#include "libunwind_ext.h"
-#include "config.h"
#if _LIBUNWIND_BUILD_ZERO_COST_APIS
@@ -27,14 +28,12 @@
_LIBUNWIND_EXPORT _Unwind_Reason_Code
_Unwind_Resume_or_Rethrow(_Unwind_Exception *exception_object) {
#if LIBCXXABI_ARM_EHABI
- _LIBUNWIND_TRACE_API("_Unwind_Resume_or_Rethrow(ex_obj=%p), "
- "private_1=%ld\n",
- exception_object,
+ _LIBUNWIND_TRACE_API("_Unwind_Resume_or_Rethrow(ex_obj=%p), private_1=%ld\n",
+ (void *)exception_object,
(long)exception_object->unwinder_cache.reserved1);
#else
- _LIBUNWIND_TRACE_API("_Unwind_Resume_or_Rethrow(ex_obj=%p), "
- "private_1=%ld\n",
- exception_object,
+ _LIBUNWIND_TRACE_API("_Unwind_Resume_or_Rethrow(ex_obj=%p), private_1=%ld\n",
+ (void *)exception_object,
(long)exception_object->private_1);
#endif
@@ -66,7 +65,7 @@ _Unwind_Resume_or_Rethrow(_Unwind_Exception *exception_object) {
_LIBUNWIND_EXPORT uintptr_t
_Unwind_GetDataRelBase(struct _Unwind_Context *context) {
(void)context;
- _LIBUNWIND_TRACE_API("_Unwind_GetDataRelBase(context=%p)\n", context);
+ _LIBUNWIND_TRACE_API("_Unwind_GetDataRelBase(context=%p)\n", (void *)context);
_LIBUNWIND_ABORT("_Unwind_GetDataRelBase() not implemented");
}
@@ -76,7 +75,7 @@ _Unwind_GetDataRelBase(struct _Unwind_Context *context) {
_LIBUNWIND_EXPORT uintptr_t
_Unwind_GetTextRelBase(struct _Unwind_Context *context) {
(void)context;
- _LIBUNWIND_TRACE_API("_Unwind_GetTextRelBase(context=%p)\n", context);
+ _LIBUNWIND_TRACE_API("_Unwind_GetTextRelBase(context=%p)\n", (void *)context);
_LIBUNWIND_ABORT("_Unwind_GetTextRelBase() not implemented");
}
@@ -99,7 +98,6 @@ _LIBUNWIND_EXPORT void *_Unwind_FindEnclosingFunction(void *pc) {
return NULL;
}
-
/// Walk every frame and call trace function at each one. If trace function
/// returns anything other than _URC_NO_REASON, then walk is terminated.
_LIBUNWIND_EXPORT _Unwind_Reason_Code
@@ -109,7 +107,8 @@ _Unwind_Backtrace(_Unwind_Trace_Fn callback, void *ref) {
unw_getcontext(&uc);
unw_init_local(&cursor, &uc);
- _LIBUNWIND_TRACE_API("_Unwind_Backtrace(callback=%p)\n", callback);
+ _LIBUNWIND_TRACE_API("_Unwind_Backtrace(callback=%p)\n",
+ (void *)(uintptr_t)callback);
// walk each frame
while (true) {
@@ -132,17 +131,39 @@ _Unwind_Backtrace(_Unwind_Trace_Fn callback, void *ref) {
}
struct _Unwind_Context *context = (struct _Unwind_Context *)&cursor;
- size_t off;
- size_t len;
const uint32_t* unwindInfo = (uint32_t *) frameInfo.unwind_info;
- unwindInfo = decode_eht_entry(unwindInfo, &off, &len);
- if (unwindInfo == NULL) {
- return _URC_FAILURE;
- }
-
- result = _Unwind_VRS_Interpret(context, unwindInfo, off, len);
- if (result != _URC_CONTINUE_UNWIND) {
- return _URC_END_OF_STACK;
+ if ((*unwindInfo & 0x80000000) == 0) {
+ // 6.2: Generic Model
+ // EHT entry is a prel31 pointing to the PR, followed by data understood
+ // only by the personality routine. Since EHABI doesn't guarantee the
+ // location or availability of the unwind opcodes in the generic model,
+ // we have to call personality functions with (_US_VIRTUAL_UNWIND_FRAME |
+ // _US_FORCE_UNWIND) state.
+
+ // Create a mock exception object for force unwinding.
+ _Unwind_Exception ex;
+ ex.exception_class = 0x434C4E47554E5700; // CLNGUNW\0
+ ex.pr_cache.fnstart = frameInfo.start_ip;
+ ex.pr_cache.ehtp = (_Unwind_EHT_Header *) unwindInfo;
+ ex.pr_cache.additional= frameInfo.flags;
+
+ // Get and call the personality function to unwind the frame.
+ __personality_routine pr = (__personality_routine) readPrel31(unwindInfo);
+ if (pr(_US_VIRTUAL_UNWIND_FRAME | _US_FORCE_UNWIND, &ex, context) !=
+ _URC_CONTINUE_UNWIND) {
+ return _URC_END_OF_STACK;
+ }
+ } else {
+ size_t off, len;
+ unwindInfo = decode_eht_entry(unwindInfo, &off, &len);
+ if (unwindInfo == NULL) {
+ return _URC_FAILURE;
+ }
+
+ result = _Unwind_VRS_Interpret(context, unwindInfo, off, len);
+ if (result != _URC_CONTINUE_UNWIND) {
+ return _URC_END_OF_STACK;
+ }
}
#endif // LIBCXXABI_ARM_EHABI
@@ -155,16 +176,15 @@ _Unwind_Backtrace(_Unwind_Trace_Fn callback, void *ref) {
unw_get_proc_info(&cursor, &frame);
_LIBUNWIND_TRACE_UNWINDING(
" _backtrace: start_ip=0x%llX, func=%s, lsda=0x%llX, context=%p\n",
- (long long)frame.start_ip, functionName,
- (long long)frame.lsda, &cursor);
+ (long long)frame.start_ip, functionName, (long long)frame.lsda,
+ (void *)&cursor);
}
// call trace function with this frame
result = (*callback)((struct _Unwind_Context *)(&cursor), ref);
if (result != _URC_NO_REASON) {
- _LIBUNWIND_TRACE_UNWINDING(" _backtrace: ended because callback "
- "returned %d\n",
- result);
+ _LIBUNWIND_TRACE_UNWINDING(
+ " _backtrace: ended because callback returned %d\n", result);
return result;
}
}
@@ -197,8 +217,8 @@ _LIBUNWIND_EXPORT uintptr_t _Unwind_GetCFA(struct _Unwind_Context *context) {
unw_cursor_t *cursor = (unw_cursor_t *)context;
unw_word_t result;
unw_get_reg(cursor, UNW_REG_SP, &result);
- _LIBUNWIND_TRACE_API("_Unwind_GetCFA(context=%p) => 0x%" PRIx64 "\n", context,
- (uint64_t)result);
+ _LIBUNWIND_TRACE_API("_Unwind_GetCFA(context=%p) => 0x%" PRIx64 "\n",
+ (void *)context, (uint64_t)result);
return (uintptr_t)result;
}
@@ -208,7 +228,7 @@ _LIBUNWIND_EXPORT uintptr_t _Unwind_GetCFA(struct _Unwind_Context *context) {
/// site address. Normally IP is the return address.
_LIBUNWIND_EXPORT uintptr_t _Unwind_GetIPInfo(struct _Unwind_Context *context,
int *ipBefore) {
- _LIBUNWIND_TRACE_API("_Unwind_GetIPInfo(context=%p)\n", context);
+ _LIBUNWIND_TRACE_API("_Unwind_GetIPInfo(context=%p)\n", (void *)context);
*ipBefore = 0;
return _Unwind_GetIP(context);
}
diff --git a/src/Unwind/UnwindLevel1.c b/src/Unwind/UnwindLevel1.c
index 9dde70d..5b911de 100644
--- a/src/Unwind/UnwindLevel1.c
+++ b/src/Unwind/UnwindLevel1.c
@@ -38,13 +38,13 @@ unwind_phase1(unw_context_t *uc, _Unwind_Exception *exception_object) {
int stepResult = unw_step(&cursor1);
if (stepResult == 0) {
_LIBUNWIND_TRACE_UNWINDING("unwind_phase1(ex_ojb=%p): unw_step() reached "
- "bottom => _URC_END_OF_STACK\n",
- exception_object);
+ "bottom => _URC_END_OF_STACK\n",
+ (void *)exception_object);
return _URC_END_OF_STACK;
} else if (stepResult < 0) {
_LIBUNWIND_TRACE_UNWINDING("unwind_phase1(ex_ojb=%p): unw_step failed => "
- "_URC_FATAL_PHASE1_ERROR\n",
- exception_object);
+ "_URC_FATAL_PHASE1_ERROR\n",
+ (void *)exception_object);
return _URC_FATAL_PHASE1_ERROR;
}
@@ -53,25 +53,26 @@ unwind_phase1(unw_context_t *uc, _Unwind_Exception *exception_object) {
unw_word_t sp;
if (unw_get_proc_info(&cursor1, &frameInfo) != UNW_ESUCCESS) {
_LIBUNWIND_TRACE_UNWINDING("unwind_phase1(ex_ojb=%p): unw_get_proc_info "
- "failed => _URC_FATAL_PHASE1_ERROR\n",
- exception_object);
+ "failed => _URC_FATAL_PHASE1_ERROR\n",
+ (void *)exception_object);
return _URC_FATAL_PHASE1_ERROR;
}
// When tracing, print state information.
if (_LIBUNWIND_TRACING_UNWINDING) {
- char functionName[512];
+ char functionBuf[512];
+ const char *functionName = functionBuf;
unw_word_t offset;
- if ((unw_get_proc_name(&cursor1, functionName, 512, &offset) !=
- UNW_ESUCCESS) || (frameInfo.start_ip + offset > frameInfo.end_ip))
- strcpy(functionName, ".anonymous.");
+ if ((unw_get_proc_name(&cursor1, functionBuf, sizeof(functionBuf),
+ &offset) != UNW_ESUCCESS) ||
+ (frameInfo.start_ip + offset > frameInfo.end_ip))
+ functionName = ".anonymous.";
unw_word_t pc;
unw_get_reg(&cursor1, UNW_REG_IP, &pc);
_LIBUNWIND_TRACE_UNWINDING(
"unwind_phase1(ex_ojb=%p): pc=0x%" PRIx64 ", start_ip=0x%" PRIx64
- ", func=%s, "
- "lsda=0x%" PRIx64 ", personality=0x%" PRIx64 "\n",
- exception_object, pc, frameInfo.start_ip, functionName,
+ ", func=%s, lsda=0x%" PRIx64 ", personality=0x%" PRIx64 "\n",
+ (void *)exception_object, pc, frameInfo.start_ip, functionName,
frameInfo.lsda, frameInfo.handler);
}
@@ -82,7 +83,7 @@ unwind_phase1(unw_context_t *uc, _Unwind_Exception *exception_object) {
(__personality_routine)(long)(frameInfo.handler);
_LIBUNWIND_TRACE_UNWINDING(
"unwind_phase1(ex_ojb=%p): calling personality function %p\n",
- exception_object, p);
+ (void *)exception_object, (void *)(uintptr_t)p);
_Unwind_Reason_Code personalityResult =
(*p)(1, _UA_SEARCH_PHASE, exception_object->exception_class,
exception_object, (struct _Unwind_Context *)(&cursor1));
@@ -93,15 +94,15 @@ unwind_phase1(unw_context_t *uc, _Unwind_Exception *exception_object) {
handlerNotFound = false;
unw_get_reg(&cursor1, UNW_REG_SP, &sp);
exception_object->private_2 = (uintptr_t)sp;
- _LIBUNWIND_TRACE_UNWINDING("unwind_phase1(ex_ojb=%p): "
- "_URC_HANDLER_FOUND \n",
- exception_object);
+ _LIBUNWIND_TRACE_UNWINDING(
+ "unwind_phase1(ex_ojb=%p): _URC_HANDLER_FOUND \n",
+ (void *)exception_object);
return _URC_NO_REASON;
case _URC_CONTINUE_UNWIND:
_LIBUNWIND_TRACE_UNWINDING(
"unwind_phase1(ex_ojb=%p): _URC_CONTINUE_UNWIND\n",
- exception_object);
+ (void *)exception_object);
// continue unwinding
break;
@@ -109,7 +110,7 @@ unwind_phase1(unw_context_t *uc, _Unwind_Exception *exception_object) {
// something went wrong
_LIBUNWIND_TRACE_UNWINDING(
"unwind_phase1(ex_ojb=%p): _URC_FATAL_PHASE1_ERROR\n",
- exception_object);
+ (void *)exception_object);
return _URC_FATAL_PHASE1_ERROR;
}
}
@@ -123,7 +124,8 @@ unwind_phase2(unw_context_t *uc, _Unwind_Exception *exception_object) {
unw_cursor_t cursor2;
unw_init_local(&cursor2, uc);
- _LIBUNWIND_TRACE_UNWINDING("unwind_phase2(ex_ojb=%p)\n", exception_object);
+ _LIBUNWIND_TRACE_UNWINDING("unwind_phase2(ex_ojb=%p)\n",
+ (void *)exception_object);
// Walk each frame until we reach where search phase said to stop.
while (true) {
@@ -133,13 +135,13 @@ unwind_phase2(unw_context_t *uc, _Unwind_Exception *exception_object) {
int stepResult = unw_step(&cursor2);
if (stepResult == 0) {
_LIBUNWIND_TRACE_UNWINDING("unwind_phase2(ex_ojb=%p): unw_step() reached "
- "bottom => _URC_END_OF_STACK\n",
- exception_object);
+ "bottom => _URC_END_OF_STACK\n",
+ (void *)exception_object);
return _URC_END_OF_STACK;
} else if (stepResult < 0) {
_LIBUNWIND_TRACE_UNWINDING("unwind_phase2(ex_ojb=%p): unw_step failed => "
- "_URC_FATAL_PHASE1_ERROR\n",
- exception_object);
+ "_URC_FATAL_PHASE1_ERROR\n",
+ (void *)exception_object);
return _URC_FATAL_PHASE2_ERROR;
}
@@ -149,24 +151,26 @@ unwind_phase2(unw_context_t *uc, _Unwind_Exception *exception_object) {
unw_get_reg(&cursor2, UNW_REG_SP, &sp);
if (unw_get_proc_info(&cursor2, &frameInfo) != UNW_ESUCCESS) {
_LIBUNWIND_TRACE_UNWINDING("unwind_phase2(ex_ojb=%p): unw_get_proc_info "
- "failed => _URC_FATAL_PHASE1_ERROR\n",
- exception_object);
+ "failed => _URC_FATAL_PHASE1_ERROR\n",
+ (void *)exception_object);
return _URC_FATAL_PHASE2_ERROR;
}
// When tracing, print state information.
if (_LIBUNWIND_TRACING_UNWINDING) {
- char functionName[512];
+ char functionBuf[512];
+ const char *functionName = functionBuf;
unw_word_t offset;
- if ((unw_get_proc_name(&cursor2, functionName, 512, &offset) !=
- UNW_ESUCCESS) || (frameInfo.start_ip + offset > frameInfo.end_ip))
- strcpy(functionName, ".anonymous.");
- _LIBUNWIND_TRACE_UNWINDING(
- "unwind_phase2(ex_ojb=%p): start_ip=0x%" PRIx64
- ", func=%s, sp=0x%" PRIx64 ", "
- "lsda=0x%" PRIx64 ", personality=0x%" PRIx64 "\n",
- exception_object, frameInfo.start_ip, functionName, sp,
- frameInfo.lsda, frameInfo.handler);
+ if ((unw_get_proc_name(&cursor2, functionBuf, sizeof(functionBuf),
+ &offset) != UNW_ESUCCESS) ||
+ (frameInfo.start_ip + offset > frameInfo.end_ip))
+ functionName = ".anonymous.";
+ _LIBUNWIND_TRACE_UNWINDING("unwind_phase2(ex_ojb=%p): start_ip=0x%" PRIx64
+ ", func=%s, sp=0x%" PRIx64 ", lsda=0x%" PRIx64
+ ", personality=0x%" PRIx64 "\n",
+ (void *)exception_object, frameInfo.start_ip,
+ functionName, sp, frameInfo.lsda,
+ frameInfo.handler);
}
// If there is a personality routine, tell it we are unwinding.
@@ -186,7 +190,7 @@ unwind_phase2(unw_context_t *uc, _Unwind_Exception *exception_object) {
// Continue unwinding
_LIBUNWIND_TRACE_UNWINDING(
"unwind_phase2(ex_ojb=%p): _URC_CONTINUE_UNWIND\n",
- exception_object);
+ (void *)exception_object);
if (sp == exception_object->private_2) {
// Phase 1 said we would stop at this frame, but we did not...
_LIBUNWIND_ABORT("during phase1 personality function said it would "
@@ -196,17 +200,17 @@ unwind_phase2(unw_context_t *uc, _Unwind_Exception *exception_object) {
case _URC_INSTALL_CONTEXT:
_LIBUNWIND_TRACE_UNWINDING(
"unwind_phase2(ex_ojb=%p): _URC_INSTALL_CONTEXT\n",
- exception_object);
+ (void *)exception_object);
// Personality routine says to transfer control to landing pad.
// We may get control back if landing pad calls _Unwind_Resume().
if (_LIBUNWIND_TRACING_UNWINDING) {
unw_word_t pc;
unw_get_reg(&cursor2, UNW_REG_IP, &pc);
unw_get_reg(&cursor2, UNW_REG_SP, &sp);
- _LIBUNWIND_TRACE_UNWINDING("unwind_phase2(ex_ojb=%p): re-entering "
+ _LIBUNWIND_TRACE_UNWINDING("unwind_phase2(ex_ojb=%p): re-entering "
"user code with ip=0x%" PRIx64
", sp=0x%" PRIx64 "\n",
- exception_object, pc, sp);
+ (void *)exception_object, pc, sp);
}
unw_resume(&cursor2);
// unw_resume() only returns if there was an error.
@@ -214,7 +218,7 @@ unwind_phase2(unw_context_t *uc, _Unwind_Exception *exception_object) {
default:
// Personality routine returned an unknown result code.
_LIBUNWIND_DEBUG_LOG("personality function returned unknown result %d",
- personalityResult);
+ personalityResult);
return _URC_FATAL_PHASE2_ERROR;
}
}
@@ -240,23 +244,24 @@ unwind_phase2_forced(unw_context_t *uc,
if (unw_get_proc_info(&cursor2, &frameInfo) != UNW_ESUCCESS) {
_LIBUNWIND_TRACE_UNWINDING("unwind_phase2_forced(ex_ojb=%p): unw_step "
"failed => _URC_END_OF_STACK\n",
- exception_object);
+ (void *)exception_object);
return _URC_FATAL_PHASE2_ERROR;
}
// When tracing, print state information.
if (_LIBUNWIND_TRACING_UNWINDING) {
- char functionName[512];
+ char functionBuf[512];
+ const char *functionName = functionBuf;
unw_word_t offset;
- if ((unw_get_proc_name(&cursor2, functionName, 512, &offset) !=
- UNW_ESUCCESS) || (frameInfo.start_ip + offset > frameInfo.end_ip))
- strcpy(functionName, ".anonymous.");
+ if ((unw_get_proc_name(&cursor2, functionBuf, sizeof(functionBuf),
+ &offset) != UNW_ESUCCESS) ||
+ (frameInfo.start_ip + offset > frameInfo.end_ip))
+ functionName = ".anonymous.";
_LIBUNWIND_TRACE_UNWINDING(
- "unwind_phase2_forced(ex_ojb=%p): "
- "start_ip=0x%" PRIx64 ", func=%s, lsda=0x%" PRIx64 ", "
- " personality=0x%" PRIx64 "\n",
- exception_object, frameInfo.start_ip, functionName, frameInfo.lsda,
- frameInfo.handler);
+ "unwind_phase2_forced(ex_ojb=%p): start_ip=0x%" PRIx64
+ ", func=%s, lsda=0x%" PRIx64 ", personality=0x%" PRIx64 "\n",
+ (void *)exception_object, frameInfo.start_ip, functionName,
+ frameInfo.lsda, frameInfo.handler);
}
// Call stop function at each frame.
@@ -267,11 +272,11 @@ unwind_phase2_forced(unw_context_t *uc,
(struct _Unwind_Context *)(&cursor2), stop_parameter);
_LIBUNWIND_TRACE_UNWINDING(
"unwind_phase2_forced(ex_ojb=%p): stop function returned %d\n",
- exception_object, stopResult);
+ (void *)exception_object, stopResult);
if (stopResult != _URC_NO_REASON) {
_LIBUNWIND_TRACE_UNWINDING(
"unwind_phase2_forced(ex_ojb=%p): stopped by stop function\n",
- exception_object);
+ (void *)exception_object);
return _URC_FATAL_PHASE2_ERROR;
}
@@ -281,21 +286,23 @@ unwind_phase2_forced(unw_context_t *uc,
(__personality_routine)(long)(frameInfo.handler);
_LIBUNWIND_TRACE_UNWINDING(
"unwind_phase2_forced(ex_ojb=%p): calling personality function %p\n",
- exception_object, p);
+ (void *)exception_object, (void *)(uintptr_t)p);
_Unwind_Reason_Code personalityResult =
(*p)(1, action, exception_object->exception_class, exception_object,
(struct _Unwind_Context *)(&cursor2));
switch (personalityResult) {
case _URC_CONTINUE_UNWIND:
_LIBUNWIND_TRACE_UNWINDING("unwind_phase2_forced(ex_ojb=%p): "
- "personality returned _URC_CONTINUE_UNWIND\n",
- exception_object);
+ "personality returned "
+ "_URC_CONTINUE_UNWIND\n",
+ (void *)exception_object);
// Destructors called, continue unwinding
break;
case _URC_INSTALL_CONTEXT:
_LIBUNWIND_TRACE_UNWINDING("unwind_phase2_forced(ex_ojb=%p): "
- "personality returned _URC_INSTALL_CONTEXT\n",
- exception_object);
+ "personality returned "
+ "_URC_INSTALL_CONTEXT\n",
+ (void *)exception_object);
// We may get control back if landing pad calls _Unwind_Resume().
unw_resume(&cursor2);
break;
@@ -304,7 +311,7 @@ unwind_phase2_forced(unw_context_t *uc,
_LIBUNWIND_TRACE_UNWINDING("unwind_phase2_forced(ex_ojb=%p): "
"personality returned %d, "
"_URC_FATAL_PHASE2_ERROR\n",
- exception_object, personalityResult);
+ (void *)exception_object, personalityResult);
return _URC_FATAL_PHASE2_ERROR;
}
}
@@ -313,8 +320,8 @@ unwind_phase2_forced(unw_context_t *uc,
// Call stop function one last time and tell it we've reached the end
// of the stack.
_LIBUNWIND_TRACE_UNWINDING("unwind_phase2_forced(ex_ojb=%p): calling stop "
- "function with _UA_END_OF_STACK\n",
- exception_object);
+ "function with _UA_END_OF_STACK\n",
+ (void *)exception_object);
_Unwind_Action lastAction =
(_Unwind_Action)(_UA_FORCE_UNWIND | _UA_CLEANUP_PHASE | _UA_END_OF_STACK);
(*stop)(1, lastAction, exception_object->exception_class, exception_object,
@@ -330,7 +337,7 @@ unwind_phase2_forced(unw_context_t *uc,
_LIBUNWIND_EXPORT _Unwind_Reason_Code
_Unwind_RaiseException(_Unwind_Exception *exception_object) {
_LIBUNWIND_TRACE_API("_Unwind_RaiseException(ex_obj=%p)\n",
- exception_object);
+ (void *)exception_object);
unw_context_t uc;
unw_getcontext(&uc);
@@ -363,7 +370,7 @@ _Unwind_RaiseException(_Unwind_Exception *exception_object) {
/// in turn calls _Unwind_Resume_or_Rethrow().
_LIBUNWIND_EXPORT void
_Unwind_Resume(_Unwind_Exception *exception_object) {
- _LIBUNWIND_TRACE_API("_Unwind_Resume(ex_obj=%p)\n", exception_object);
+ _LIBUNWIND_TRACE_API("_Unwind_Resume(ex_obj=%p)\n", (void *)exception_object);
unw_context_t uc;
unw_getcontext(&uc);
@@ -387,7 +394,7 @@ _LIBUNWIND_EXPORT _Unwind_Reason_Code
_Unwind_ForcedUnwind(_Unwind_Exception *exception_object,
_Unwind_Stop_Fn stop, void *stop_parameter) {
_LIBUNWIND_TRACE_API("_Unwind_ForcedUnwind(ex_obj=%p, stop=%p)\n",
- exception_object, stop);
+ (void *)exception_object, (void *)(uintptr_t)stop);
unw_context_t uc;
unw_getcontext(&uc);
@@ -409,9 +416,9 @@ _Unwind_GetLanguageSpecificData(struct _Unwind_Context *context) {
uintptr_t result = 0;
if (unw_get_proc_info(cursor, &frameInfo) == UNW_ESUCCESS)
result = (uintptr_t)frameInfo.lsda;
- _LIBUNWIND_TRACE_API("_Unwind_GetLanguageSpecificData(context=%p)"
- "=> 0x%" PRIxPTR "\n",
- context, result);
+ _LIBUNWIND_TRACE_API(
+ "_Unwind_GetLanguageSpecificData(context=%p) => 0x%" PRIxPTR "\n",
+ (void *)context, result);
if (result != 0) {
if (*((uint8_t *)result) != 0xFF)
_LIBUNWIND_DEBUG_LOG("lsda at 0x%" PRIxPTR " does not start with 0xFF\n",
@@ -421,80 +428,111 @@ _Unwind_GetLanguageSpecificData(struct _Unwind_Context *context) {
}
+/// Called by personality handler during phase 2 to find the start of the
+/// function.
+_LIBUNWIND_EXPORT uintptr_t
+_Unwind_GetRegionStart(struct _Unwind_Context *context) {
+ unw_cursor_t *cursor = (unw_cursor_t *)context;
+ unw_proc_info_t frameInfo;
+ uintptr_t result = 0;
+ if (unw_get_proc_info(cursor, &frameInfo) == UNW_ESUCCESS)
+ result = (uintptr_t)frameInfo.start_ip;
+ _LIBUNWIND_TRACE_API("_Unwind_GetRegionStart(context=%p) => 0x%" PRIxPTR "\n",
+ (void *)context, result);
+ return result;
+}
+
+
+/// Called by personality handler during phase 2 if a foreign exception
+// is caught.
+_LIBUNWIND_EXPORT void
+_Unwind_DeleteException(_Unwind_Exception *exception_object) {
+ _LIBUNWIND_TRACE_API("_Unwind_DeleteException(ex_obj=%p)\n",
+ (void *)exception_object);
+ if (exception_object->exception_cleanup != NULL)
+ (*exception_object->exception_cleanup)(_URC_FOREIGN_EXCEPTION_CAUGHT,
+ exception_object);
+}
+
+#endif // _LIBUNWIND_BUILD_ZERO_COST_APIS && !LIBCXXABI_ARM_EHABI
+
+#if LIBCXXABI_ARM_EHABI
+
+_LIBUNWIND_EXPORT uintptr_t
+_Unwind_GetGR(struct _Unwind_Context *context, int index) {
+ uintptr_t value = 0;
+ _Unwind_VRS_Get(context, _UVRSC_CORE, (uint32_t)index, _UVRSD_UINT32, &value);
+ _LIBUNWIND_TRACE_API("_Unwind_GetGR(context=%p, reg=%d) => 0x%" PRIx64 "\n",
+ (void *)context, index, (uint64_t)value);
+ return value;
+}
+
+_LIBUNWIND_EXPORT void _Unwind_SetGR(struct _Unwind_Context *context, int index,
+ uintptr_t value) {
+ _LIBUNWIND_TRACE_API("_Unwind_SetGR(context=%p, reg=%d, value=0x%0"PRIx64")\n",
+ (void *)context, index, (uint64_t)value);
+ _Unwind_VRS_Set(context, _UVRSC_CORE, (uint32_t)index, _UVRSD_UINT32, &value);
+}
+
+_LIBUNWIND_EXPORT uintptr_t _Unwind_GetIP(struct _Unwind_Context *context) {
+ // remove the thumb-bit before returning
+ uintptr_t value = _Unwind_GetGR(context, 15) & (~(uintptr_t)0x1);
+ _LIBUNWIND_TRACE_API("_Unwind_GetIP(context=%p) => 0x%" PRIx64 "\n",
+ (void *)context, (uint64_t)value);
+ return value;
+}
+
+_LIBUNWIND_EXPORT void _Unwind_SetIP(struct _Unwind_Context *context,
+ uintptr_t value) {
+ _LIBUNWIND_TRACE_API("_Unwind_SetIP(context=%p, value=0x%0" PRIx64 ")\n",
+ (void *)context, (uint64_t)value);
+ uintptr_t thumb_bit = _Unwind_GetGR(context, 15) & ((uintptr_t)0x1);
+ _Unwind_SetGR(context, 15, value | thumb_bit);
+}
+
+#else
/// Called by personality handler during phase 2 to get register values.
-_LIBUNWIND_EXPORT uintptr_t _Unwind_GetGR(struct _Unwind_Context *context,
- int index) {
+_LIBUNWIND_EXPORT uintptr_t
+_Unwind_GetGR(struct _Unwind_Context *context, int index) {
unw_cursor_t *cursor = (unw_cursor_t *)context;
unw_word_t result;
unw_get_reg(cursor, index, &result);
_LIBUNWIND_TRACE_API("_Unwind_GetGR(context=%p, reg=%d) => 0x%" PRIx64 "\n",
- context, index, (uint64_t)result);
+ (void *)context, index, (uint64_t)result);
return (uintptr_t)result;
}
-
-
/// Called by personality handler during phase 2 to alter register values.
_LIBUNWIND_EXPORT void _Unwind_SetGR(struct _Unwind_Context *context, int index,
- uintptr_t new_value) {
- _LIBUNWIND_TRACE_API("_Unwind_SetGR(context=%p, reg=%d, "
- "value=0x%0" PRIx64 ")\n",
- context, index, (uint64_t)new_value);
+ uintptr_t value) {
+ _LIBUNWIND_TRACE_API("_Unwind_SetGR(context=%p, reg=%d, value=0x%0" PRIx64
+ ")\n",
+ (void *)context, index, (uint64_t)value);
unw_cursor_t *cursor = (unw_cursor_t *)context;
- unw_set_reg(cursor, index, new_value);
+ unw_set_reg(cursor, index, value);
}
-
-
/// Called by personality handler during phase 2 to get instruction pointer.
_LIBUNWIND_EXPORT uintptr_t _Unwind_GetIP(struct _Unwind_Context *context) {
unw_cursor_t *cursor = (unw_cursor_t *)context;
unw_word_t result;
unw_get_reg(cursor, UNW_REG_IP, &result);
- _LIBUNWIND_TRACE_API("_Unwind_GetIP(context=%p) => 0x%" PRIx64 "\n", context,
- (uint64_t)result);
+ _LIBUNWIND_TRACE_API("_Unwind_GetIP(context=%p) => 0x%" PRIx64 "\n",
+ (void *)context, (uint64_t)result);
return (uintptr_t)result;
}
-
-
/// Called by personality handler during phase 2 to alter instruction pointer,
/// such as setting where the landing pad is, so _Unwind_Resume() will
/// start executing in the landing pad.
_LIBUNWIND_EXPORT void _Unwind_SetIP(struct _Unwind_Context *context,
- uintptr_t new_value) {
+ uintptr_t value) {
_LIBUNWIND_TRACE_API("_Unwind_SetIP(context=%p, value=0x%0" PRIx64 ")\n",
- context, (uint64_t)new_value);
- unw_cursor_t *cursor = (unw_cursor_t *)context;
- unw_set_reg(cursor, UNW_REG_IP, new_value);
-}
-
-
-/// Called by personality handler during phase 2 to find the start of the
-/// function.
-_LIBUNWIND_EXPORT uintptr_t
-_Unwind_GetRegionStart(struct _Unwind_Context *context) {
+ (void *)context, (uint64_t)value);
unw_cursor_t *cursor = (unw_cursor_t *)context;
- unw_proc_info_t frameInfo;
- uintptr_t result = 0;
- if (unw_get_proc_info(cursor, &frameInfo) == UNW_ESUCCESS)
- result = (uintptr_t)frameInfo.start_ip;
- _LIBUNWIND_TRACE_API("_Unwind_GetRegionStart(context=%p) => 0x%" PRIxPTR "\n",
- context, result);
- return result;
+ unw_set_reg(cursor, UNW_REG_IP, value);
}
+#endif
-/// Called by personality handler during phase 2 if a foreign exception
-// is caught.
-_LIBUNWIND_EXPORT void
-_Unwind_DeleteException(_Unwind_Exception *exception_object) {
- _LIBUNWIND_TRACE_API("_Unwind_DeleteException(ex_obj=%p)\n",
- exception_object);
- if (exception_object->exception_cleanup != NULL)
- (*exception_object->exception_cleanup)(_URC_FOREIGN_EXCEPTION_CAUGHT,
- exception_object);
-}
-
-#endif // _LIBUNWIND_BUILD_ZERO_COST_APIS && !LIBCXXABI_ARM_EHABI
diff --git a/src/Unwind/UnwindRegistersRestore.S b/src/Unwind/UnwindRegistersRestore.S
index 7dd3a11..00f2aeb 100644
--- a/src/Unwind/UnwindRegistersRestore.S
+++ b/src/Unwind/UnwindRegistersRestore.S
@@ -11,7 +11,7 @@
.text
-#if __i386__
+#if defined(__i386__)
DEFINE_LIBUNWIND_PRIVATE_FUNCTION(_ZN9libunwind13Registers_x866jumptoEv)
#
# void libunwind::Registers_x86::jumpto()
@@ -52,7 +52,7 @@ DEFINE_LIBUNWIND_PRIVATE_FUNCTION(_ZN9libunwind13Registers_x866jumptoEv)
# skip fs
# skip gs
-#elif __x86_64__
+#elif defined(__x86_64__)
DEFINE_LIBUNWIND_PRIVATE_FUNCTION(_ZN9libunwind16Registers_x86_646jumptoEv)
#
@@ -93,7 +93,7 @@ DEFINE_LIBUNWIND_PRIVATE_FUNCTION(_ZN9libunwind16Registers_x86_646jumptoEv)
ret # rip was saved here
-#elif __ppc__
+#elif defined(__ppc__)
DEFINE_LIBUNWIND_PRIVATE_FUNCTION(_ZN9libunwind13Registers_ppc6jumptoEv)
;
@@ -258,7 +258,7 @@ Lnovec:
lwz r3,20(r3) ; do r3 last
bctr
-#elif __arm64__
+#elif defined(__arm64__)
;
; void libunwind::Registers_arm64::jumpto()
@@ -308,7 +308,7 @@ DEFINE_LIBUNWIND_PRIVATE_FUNCTION(_ZN9libunwind15Registers_arm646jumptoEv)
ldp x0, x1, [x0, #0x000] ; restore x0,x1
ret lr ; jump to pc
-#elif __arm__ && !__APPLE__
+#elif defined(__arm__) && !defined(__APPLE__)
#if !defined(__ARM_ARCH_ISA_ARM)
.thumb
@@ -347,8 +347,8 @@ DEFINE_LIBUNWIND_PRIVATE_FUNCTION(_ZN9libunwind13Registers_arm20restoreCoreAndJu
@ values pointer is in r0
@
.p2align 2
+ .fpu vfpv3-d16
DEFINE_LIBUNWIND_PRIVATE_FUNCTION(_ZN9libunwind13Registers_arm19restoreVFPWithFLDMDEPy)
-#if defined(__ARM_FP)
@ VFP and iwMMX instructions are only available when compiling with the flags
@ that enable them. We do not want to do that in the library (because we do not
@ want the compiler to generate instructions that access those) but this is
@@ -356,12 +356,7 @@ DEFINE_LIBUNWIND_PRIVATE_FUNCTION(_ZN9libunwind13Registers_arm19restoreVFPWithFL
@ these registers implies they are, actually, available on the target, so
@ it's ok to execute.
@ So, generate the instruction using the corresponding coprocessor mnemonic.
-#if __ARM_ARCH < 7
- ldc p11, cr0, [r0], {0x20} @ fldmiad r0, {d0-d15}
-#else
vldmia r0, {d0-d15}
-#endif
-#endif
JMP(lr)
@
@@ -371,14 +366,9 @@ DEFINE_LIBUNWIND_PRIVATE_FUNCTION(_ZN9libunwind13Registers_arm19restoreVFPWithFL
@ values pointer is in r0
@
.p2align 2
+ .fpu vfpv3-d16
DEFINE_LIBUNWIND_PRIVATE_FUNCTION(_ZN9libunwind13Registers_arm19restoreVFPWithFLDMXEPy)
-#if defined(__ARM_FP)
-#if __ARM_ARCH < 7
- ldc p11, cr0, [r0], {0x21} @ fldmiax r0, {d0-d15}
-#else
vldmia r0, {d0-d15} @ fldmiax is deprecated in ARMv7+ and now behaves like vldmia
-#endif
-#endif
JMP(lr)
@
@@ -388,14 +378,9 @@ DEFINE_LIBUNWIND_PRIVATE_FUNCTION(_ZN9libunwind13Registers_arm19restoreVFPWithFL
@ values pointer is in r0
@
.p2align 2
+ .fpu vfpv3
DEFINE_LIBUNWIND_PRIVATE_FUNCTION(_ZN9libunwind13Registers_arm12restoreVFPv3EPy)
-#if defined(__ARM_FP)
-#ifndef __ARM_NEON
- ldcl p11, cr0, [r0], {0x20} @ vldm r0, {d16-d31}
-#else
vldmia r0, {d16-d31}
-#endif
-#endif
JMP(lr)
@
@@ -406,7 +391,7 @@ DEFINE_LIBUNWIND_PRIVATE_FUNCTION(_ZN9libunwind13Registers_arm12restoreVFPv3EPy)
@
.p2align 2
DEFINE_LIBUNWIND_PRIVATE_FUNCTION(_ZN9libunwind13Registers_arm12restoreiWMMXEPy)
-#if (!defined(__ARM_ARCH_6M__) && !defined(__ARM_ARCH_6SM__)) || __ARM_WMMX
+#if (!defined(__ARM_ARCH_6M__) && !defined(__ARM_ARCH_6SM__)) || defined(__ARM_WMMX)
ldcl p1, cr0, [r0], #8 @ wldrd wR0, [r0], #8
ldcl p1, cr1, [r0], #8 @ wldrd wR1, [r0], #8
ldcl p1, cr2, [r0], #8 @ wldrd wR2, [r0], #8
@@ -434,7 +419,7 @@ DEFINE_LIBUNWIND_PRIVATE_FUNCTION(_ZN9libunwind13Registers_arm12restoreiWMMXEPy)
@
.p2align 2
DEFINE_LIBUNWIND_PRIVATE_FUNCTION(_ZN9libunwind13Registers_arm19restoreiWMMXControlEPj)
-#if (!defined(__ARM_ARCH_6M__) && !defined(__ARM_ARCH_6SM__)) || __ARM_WMMX
+#if (!defined(__ARM_ARCH_6M__) && !defined(__ARM_ARCH_6SM__)) || defined(__ARM_WMMX)
ldc2 p1, cr8, [r0], #4 @ wldrw wCGR0, [r0], #4
ldc2 p1, cr9, [r0], #4 @ wldrw wCGR1, [r0], #4
ldc2 p1, cr10, [r0], #4 @ wldrw wCGR2, [r0], #4
diff --git a/src/Unwind/UnwindRegistersSave.S b/src/Unwind/UnwindRegistersSave.S
index d6b9a41..8c886a8 100644
--- a/src/Unwind/UnwindRegistersSave.S
+++ b/src/Unwind/UnwindRegistersSave.S
@@ -11,7 +11,7 @@
.text
-#if __i386__
+#if defined(__i386__)
#
# extern int unw_getcontext(unw_context_t* thread_state)
@@ -52,7 +52,7 @@ DEFINE_LIBUNWIND_FUNCTION(unw_getcontext)
xorl %eax, %eax # return UNW_ESUCCESS
ret
-#elif __x86_64__
+#elif defined(__x86_64__)
#
# extern int unw_getcontext(unw_context_t* thread_state)
@@ -87,7 +87,7 @@ DEFINE_LIBUNWIND_FUNCTION(unw_getcontext)
xorl %eax, %eax # return UNW_ESUCCESS
ret
-#elif __ppc__
+#elif defined(__ppc__)
;
; extern int unw_getcontext(unw_context_t* thread_state)
@@ -230,7 +230,7 @@ DEFINE_LIBUNWIND_FUNCTION(unw_getcontext)
blr
-#elif __arm64__
+#elif defined(__arm64__)
;
; extern int unw_getcontext(unw_context_t* thread_state)
@@ -280,7 +280,7 @@ DEFINE_LIBUNWIND_FUNCTION(unw_getcontext)
ldr x0, #0 ; return UNW_ESUCCESS
ret
-#elif __arm__ && !__APPLE__
+#elif defined(__arm__) && !defined(__APPLE__)
#if !defined(__ARM_ARCH_ISA_ARM)
.thumb
@@ -316,7 +316,14 @@ DEFINE_LIBUNWIND_FUNCTION(unw_getcontext)
str lr, [r0, #56]
str lr, [r0, #60] @ store return address as pc
#endif
+#if __ARM_ARCH_ISA_THUMB == 1
+ @ T1 does not have a non-cpsr-clobbering register-zeroing instruction.
+ @ It is safe to use here though because we are about to return, and cpsr is
+ @ not expected to be preserved.
+ movs r0, #0 @ return UNW_ESUCCESS
+#else
mov r0, #0 @ return UNW_ESUCCESS
+#endif
JMP(lr)
@
@@ -326,14 +333,9 @@ DEFINE_LIBUNWIND_FUNCTION(unw_getcontext)
@ values pointer is in r0
@
.p2align 2
+ .fpu vfpv3-d16
DEFINE_LIBUNWIND_PRIVATE_FUNCTION(_ZN9libunwind13Registers_arm16saveVFPWithFSTMDEPy)
-#if defined(__ARM_FP)
-#if __ARM_ARCH < 7
- stc p11, cr0, [r0], {0x20} @ fstmiad r0, {d0-d15}
-#else
vstmia r0, {d0-d15}
-#endif
-#endif
JMP(lr)
@
@@ -343,14 +345,9 @@ DEFINE_LIBUNWIND_PRIVATE_FUNCTION(_ZN9libunwind13Registers_arm16saveVFPWithFSTMD
@ values pointer is in r0
@
.p2align 2
+ .fpu vfpv3-d16
DEFINE_LIBUNWIND_PRIVATE_FUNCTION(_ZN9libunwind13Registers_arm16saveVFPWithFSTMXEPy)
-#if defined(__ARM_FP)
-#if __ARM_ARCH < 7
- stc p11, cr0, [r0], {0x21} @ fstmiax r0, {d0-d15}
-#else
vstmia r0, {d0-d15} @ fstmiax is deprecated in ARMv7+ and now behaves like vstmia
-#endif
-#endif
JMP(lr)
@
@@ -360,8 +357,8 @@ DEFINE_LIBUNWIND_PRIVATE_FUNCTION(_ZN9libunwind13Registers_arm16saveVFPWithFSTMX
@ values pointer is in r0
@
.p2align 2
+ .fpu vfpv3
DEFINE_LIBUNWIND_PRIVATE_FUNCTION(_ZN9libunwind13Registers_arm9saveVFPv3EPy)
-#if defined(__ARM_FP)
@ VFP and iwMMX instructions are only available when compiling with the flags
@ that enable them. We do not want to do that in the library (because we do not
@ want the compiler to generate instructions that access those) but this is
@@ -369,12 +366,7 @@ DEFINE_LIBUNWIND_PRIVATE_FUNCTION(_ZN9libunwind13Registers_arm9saveVFPv3EPy)
@ these registers implies they are, actually, available on the target, so
@ it's ok to execute.
@ So, generate the instructions using the corresponding coprocessor mnemonic.
-#ifndef __ARM_NEON
- stcl p11, cr0, [r0], {0x20} @ vstm r0, {d16-d31}
-#else
vstmia r0, {d16-d31}
-#endif
-#endif
JMP(lr)
@
@@ -385,7 +377,7 @@ DEFINE_LIBUNWIND_PRIVATE_FUNCTION(_ZN9libunwind13Registers_arm9saveVFPv3EPy)
@
.p2align 2
DEFINE_LIBUNWIND_PRIVATE_FUNCTION(_ZN9libunwind13Registers_arm9saveiWMMXEPy)
-#if (!defined(__ARM_ARCH_6M__) && !defined(__ARM_ARCH_6SM__)) || __ARM_WMMX
+#if (!defined(__ARM_ARCH_6M__) && !defined(__ARM_ARCH_6SM__)) || defined(__ARM_WMMX)
stcl p1, cr0, [r0], #8 @ wstrd wR0, [r0], #8
stcl p1, cr1, [r0], #8 @ wstrd wR1, [r0], #8
stcl p1, cr2, [r0], #8 @ wstrd wR2, [r0], #8
@@ -413,7 +405,7 @@ DEFINE_LIBUNWIND_PRIVATE_FUNCTION(_ZN9libunwind13Registers_arm9saveiWMMXEPy)
@
.p2align 2
DEFINE_LIBUNWIND_PRIVATE_FUNCTION(_ZN9libunwind13Registers_arm16saveiWMMXControlEPj)
-#if (!defined(__ARM_ARCH_6M__) && !defined(__ARM_ARCH_6SM__)) || __ARM_WMMX
+#if (!defined(__ARM_ARCH_6M__) && !defined(__ARM_ARCH_6SM__)) || defined(__ARM_WMMX)
stc2 p1, cr8, [r0], #4 @ wstrw wCGR0, [r0], #4
stc2 p1, cr9, [r0], #4 @ wstrw wCGR1, [r0], #4
stc2 p1, cr10, [r0], #4 @ wstrw wCGR2, [r0], #4
diff --git a/src/Unwind/Unwind_AppleExtras.cpp b/src/Unwind/Unwind_AppleExtras.cpp
index 6d02a66..b8baef5 100644
--- a/src/Unwind/Unwind_AppleExtras.cpp
+++ b/src/Unwind/Unwind_AppleExtras.cpp
@@ -41,7 +41,7 @@ struct libgcc_object_info {
// static linker symbols to prevent wrong two level namespace for _Unwind symbols
-#if __arm__
+#if defined(__arm__)
#define NOT_HERE_BEFORE_5_0(sym) \
extern const char sym##_tmp30 __asm("$ld$hide$os3.0$_" #sym ); \
__attribute__((visibility("default"))) const char sym##_tmp30 = 0; \
@@ -57,7 +57,7 @@ struct libgcc_object_info {
__attribute__((visibility("default"))) const char sym##_tmp42 = 0; \
extern const char sym##_tmp43 __asm("$ld$hide$os4.3$_" #sym ); \
__attribute__((visibility("default"))) const char sym##_tmp43 = 0;
-#elif __arm64__
+#elif defined(__arm64__)
#define NOT_HERE_BEFORE_10_6(sym)
#define NEVER_HERE(sym)
#else
@@ -183,7 +183,7 @@ bool checkKeyMgrRegisteredFDEs(uintptr_t pc, void *&fde) {
}
-#if !FOR_DYLD && _LIBUNWIND_BUILD_SJLJ_APIS
+#if !defined(FOR_DYLD) && _LIBUNWIND_BUILD_SJLJ_APIS
#include <System/pthread_machdep.h>
diff --git a/src/Unwind/assembly.h b/src/Unwind/assembly.h
index b749d67..f46a24d 100644
--- a/src/Unwind/assembly.h
+++ b/src/Unwind/assembly.h
@@ -62,6 +62,10 @@
SYMBOL_NAME(name):
#if defined(__arm__)
+#if !defined(__ARM_ARCH)
+#define __ARM_ARCH 4
+#endif
+
#if defined(__ARM_ARCH_4T__) || __ARM_ARCH >= 5
#define ARM_HAS_BX
#endif
diff --git a/src/Unwind/config.h b/src/Unwind/config.h
index 848d020..828b68e 100644
--- a/src/Unwind/config.h
+++ b/src/Unwind/config.h
@@ -28,7 +28,7 @@
#endif
// Platform specific configuration defines.
-#if __APPLE__
+#ifdef __APPLE__
#include <Availability.h>
#ifdef __cplusplus
extern "C" {
@@ -39,15 +39,18 @@
}
#endif
- #define _LIBUNWIND_BUILD_ZERO_COST_APIS (__i386__ || __x86_64__ || __arm64__)
- #define _LIBUNWIND_BUILD_SJLJ_APIS (__arm__)
- #define _LIBUNWIND_SUPPORT_FRAME_APIS (__i386__ || __x86_64__)
+ #define _LIBUNWIND_BUILD_ZERO_COST_APIS (defined(__i386__) || \
+ defined(__x86_64__) || \
+ defined(__arm64__))
+ #define _LIBUNWIND_BUILD_SJLJ_APIS defined(__arm__)
+ #define _LIBUNWIND_SUPPORT_FRAME_APIS (defined(__i386__) || \
+ defined(__x86_64__))
#define _LIBUNWIND_EXPORT __attribute__((visibility("default")))
#define _LIBUNWIND_HIDDEN __attribute__((visibility("hidden")))
#define _LIBUNWIND_LOG(msg, ...) fprintf(stderr, "libunwind: " msg, __VA_ARGS__)
#define _LIBUNWIND_ABORT(msg) __assert_rtn(__func__, __FILE__, __LINE__, msg)
- #if FOR_DYLD
+ #if defined(FOR_DYLD)
#define _LIBUNWIND_SUPPORT_COMPACT_UNWIND 1
#define _LIBUNWIND_SUPPORT_DWARF_UNWIND 0
#define _LIBUNWIND_SUPPORT_DWARF_INDEX 0
@@ -67,17 +70,22 @@
abort();
}
- #define _LIBUNWIND_BUILD_ZERO_COST_APIS (__i386__ || __x86_64__ || __arm64__ || __arm__)
+ #define _LIBUNWIND_BUILD_ZERO_COST_APIS (defined(__i386__) || \
+ defined(__x86_64__) || \
+ defined(__arm64__) || \
+ defined(__arm__))
#define _LIBUNWIND_BUILD_SJLJ_APIS 0
- #define _LIBUNWIND_SUPPORT_FRAME_APIS (__i386__ || __x86_64__)
+ #define _LIBUNWIND_SUPPORT_FRAME_APIS (defined(__i386__) || \
+ defined(__x86_64__))
#define _LIBUNWIND_EXPORT __attribute__((visibility("default")))
#define _LIBUNWIND_HIDDEN __attribute__((visibility("hidden")))
#define _LIBUNWIND_LOG(msg, ...) fprintf(stderr, "libuwind: " msg, __VA_ARGS__)
#define _LIBUNWIND_ABORT(msg) assert_rtn(__func__, __FILE__, __LINE__, msg)
#define _LIBUNWIND_SUPPORT_COMPACT_UNWIND 0
- #define _LIBUNWIND_SUPPORT_DWARF_UNWIND 0
- #define _LIBUNWIND_SUPPORT_DWARF_INDEX 0
+ #define _LIBUNWIND_SUPPORT_DWARF_UNWIND !defined(__arm__) || \
+ defined(__ARM_DWARF_EH__)
+ #define _LIBUNWIND_SUPPORT_DWARF_INDEX _LIBUNWIND_SUPPORT_DWARF_UNWIND
#endif
diff --git a/src/Unwind/libunwind.cpp b/src/Unwind/libunwind.cpp
index b80beaf..49f06cc 100644
--- a/src/Unwind/libunwind.cpp
+++ b/src/Unwind/libunwind.cpp
@@ -16,6 +16,9 @@
#include <cstdlib> // getenv
#endif
#include <new>
+#include <tuple>
+#include <memory>
+#include <vector>
#include "libunwind_ext.h"
#include "config.h"
@@ -32,6 +35,9 @@ using namespace libunwind;
/// internal object to represent this processes address space
LocalAddressSpace LocalAddressSpace::sThisAddressSpace;
+_LIBUNWIND_EXPORT unw_addr_space_t unw_local_addr_space =
+ (unw_addr_space_t)&LocalAddressSpace::sThisAddressSpace;
+
/// record the registers and stack position of the caller
extern int unw_getcontext(unw_context_t *);
// note: unw_getcontext() implemented in assembly
@@ -41,18 +47,19 @@ extern int unw_getcontext(unw_context_t *);
_LIBUNWIND_EXPORT int unw_init_local(unw_cursor_t *cursor,
unw_context_t *context) {
_LIBUNWIND_TRACE_API("unw_init_local(cursor=%p, context=%p)\n",
- cursor, context);
+ static_cast<void *>(cursor),
+ static_cast<void *>(context));
// Use "placement new" to allocate UnwindCursor in the cursor buffer.
-#if __i386__
+#if defined(__i386__)
new ((void *)cursor) UnwindCursor<LocalAddressSpace, Registers_x86>(
context, LocalAddressSpace::sThisAddressSpace);
-#elif __x86_64__
+#elif defined(__x86_64__)
new ((void *)cursor) UnwindCursor<LocalAddressSpace, Registers_x86_64>(
context, LocalAddressSpace::sThisAddressSpace);
-#elif __ppc__
+#elif defined(__ppc__)
new ((void *)cursor) UnwindCursor<LocalAddressSpace, Registers_ppc>(
context, LocalAddressSpace::sThisAddressSpace);
-#elif __arm64__
+#elif defined(__arm64__)
new ((void *)cursor) UnwindCursor<LocalAddressSpace, Registers_arm64>(
context, LocalAddressSpace::sThisAddressSpace);
#elif LIBCXXABI_ARM_EHABI
@@ -65,17 +72,13 @@ _LIBUNWIND_EXPORT int unw_init_local(unw_cursor_t *cursor,
return UNW_ESUCCESS;
}
-#if UNW_REMOTE
-
-_LIBUNWIND_EXPORT unw_addr_space_t unw_local_addr_space =
- (unw_addr_space_t) & sThisAddressSpace;
-
+#ifdef UNW_REMOTE
/// Create a cursor into a thread in another process.
_LIBUNWIND_EXPORT int unw_init_remote_thread(unw_cursor_t *cursor,
unw_addr_space_t as,
void *arg) {
// special case: unw_init_remote(xx, unw_local_addr_space, xx)
- if (as == (unw_addr_space_t) & sThisAddressSpace)
+ if (as == (unw_addr_space_t)&LocalAddressSpace::sThisAddressSpace)
return unw_init_local(cursor, NULL); //FIXME
// use "placement new" to allocate UnwindCursor in the cursor buffer
@@ -155,7 +158,8 @@ _LIBUNWIND_EXPORT void unw_destroy_addr_space(unw_addr_space_t asp) {
_LIBUNWIND_EXPORT int unw_get_reg(unw_cursor_t *cursor, unw_regnum_t regNum,
unw_word_t *value) {
_LIBUNWIND_TRACE_API("unw_get_reg(cursor=%p, regNum=%d, &value=%p)\n",
- cursor, regNum, value);
+ static_cast<void *>(cursor), regNum,
+ static_cast<void *>(value));
AbstractUnwindCursor *co = (AbstractUnwindCursor *)cursor;
if (co->validReg(regNum)) {
*value = co->getReg(regNum);
@@ -169,7 +173,7 @@ _LIBUNWIND_EXPORT int unw_get_reg(unw_cursor_t *cursor, unw_regnum_t regNum,
_LIBUNWIND_EXPORT int unw_set_reg(unw_cursor_t *cursor, unw_regnum_t regNum,
unw_word_t value) {
_LIBUNWIND_TRACE_API("unw_set_reg(cursor=%p, regNum=%d, value=0x%llX)\n",
- cursor, regNum, (long long)value);
+ static_cast<void *>(cursor), regNum, (long long)value);
typedef LocalAddressSpace::pint_t pint_t;
AbstractUnwindCursor *co = (AbstractUnwindCursor *)cursor;
if (co->validReg(regNum)) {
@@ -188,7 +192,8 @@ _LIBUNWIND_EXPORT int unw_set_reg(unw_cursor_t *cursor, unw_regnum_t regNum,
_LIBUNWIND_EXPORT int unw_get_fpreg(unw_cursor_t *cursor, unw_regnum_t regNum,
unw_fpreg_t *value) {
_LIBUNWIND_TRACE_API("unw_get_fpreg(cursor=%p, regNum=%d, &value=%p)\n",
- cursor, regNum, value);
+ static_cast<void *>(cursor), regNum,
+ static_cast<void *>(value));
AbstractUnwindCursor *co = (AbstractUnwindCursor *)cursor;
if (co->validFloatReg(regNum)) {
*value = co->getFloatReg(regNum);
@@ -203,10 +208,10 @@ _LIBUNWIND_EXPORT int unw_set_fpreg(unw_cursor_t *cursor, unw_regnum_t regNum,
unw_fpreg_t value) {
#if LIBCXXABI_ARM_EHABI
_LIBUNWIND_TRACE_API("unw_set_fpreg(cursor=%p, regNum=%d, value=%llX)\n",
- cursor, regNum, value);
+ static_cast<void *>(cursor), regNum, value);
#else
_LIBUNWIND_TRACE_API("unw_set_fpreg(cursor=%p, regNum=%d, value=%g)\n",
- cursor, regNum, value);
+ static_cast<void *>(cursor), regNum, value);
#endif
AbstractUnwindCursor *co = (AbstractUnwindCursor *)cursor;
if (co->validFloatReg(regNum)) {
@@ -219,7 +224,7 @@ _LIBUNWIND_EXPORT int unw_set_fpreg(unw_cursor_t *cursor, unw_regnum_t regNum,
/// Move cursor to next frame.
_LIBUNWIND_EXPORT int unw_step(unw_cursor_t *cursor) {
- _LIBUNWIND_TRACE_API("unw_step(cursor=%p)\n", cursor);
+ _LIBUNWIND_TRACE_API("unw_step(cursor=%p)\n", static_cast<void *>(cursor));
AbstractUnwindCursor *co = (AbstractUnwindCursor *)cursor;
return co->step();
}
@@ -229,7 +234,7 @@ _LIBUNWIND_EXPORT int unw_step(unw_cursor_t *cursor) {
_LIBUNWIND_EXPORT int unw_get_proc_info(unw_cursor_t *cursor,
unw_proc_info_t *info) {
_LIBUNWIND_TRACE_API("unw_get_proc_info(cursor=%p, &info=%p)\n",
- cursor, info);
+ static_cast<void *>(cursor), static_cast<void *>(info));
AbstractUnwindCursor *co = (AbstractUnwindCursor *)cursor;
co->getInfo(info);
if (info->end_ip == 0)
@@ -241,7 +246,7 @@ _LIBUNWIND_EXPORT int unw_get_proc_info(unw_cursor_t *cursor,
/// Resume execution at cursor position (aka longjump).
_LIBUNWIND_EXPORT int unw_resume(unw_cursor_t *cursor) {
- _LIBUNWIND_TRACE_API("unw_resume(cursor=%p)\n", cursor);
+ _LIBUNWIND_TRACE_API("unw_resume(cursor=%p)\n", static_cast<void *>(cursor));
AbstractUnwindCursor *co = (AbstractUnwindCursor *)cursor;
co->jumpto();
return UNW_EUNSPEC;
@@ -251,8 +256,9 @@ _LIBUNWIND_EXPORT int unw_resume(unw_cursor_t *cursor) {
/// Get name of function at cursor position in stack frame.
_LIBUNWIND_EXPORT int unw_get_proc_name(unw_cursor_t *cursor, char *buf,
size_t bufLen, unw_word_t *offset) {
- _LIBUNWIND_TRACE_API("unw_get_proc_name(cursor=%p, &buf=%p,"
- "bufLen=%zu)\n", cursor, buf, bufLen);
+ _LIBUNWIND_TRACE_API("unw_get_proc_name(cursor=%p, &buf=%p, bufLen=%lu)\n",
+ static_cast<void *>(cursor), static_cast<void *>(buf),
+ static_cast<unsigned long>(bufLen));
AbstractUnwindCursor *co = (AbstractUnwindCursor *)cursor;
if (co->getFunctionName(buf, bufLen, offset))
return UNW_ESUCCESS;
@@ -264,7 +270,7 @@ _LIBUNWIND_EXPORT int unw_get_proc_name(unw_cursor_t *cursor, char *buf,
/// Checks if a register is a floating-point register.
_LIBUNWIND_EXPORT int unw_is_fpreg(unw_cursor_t *cursor, unw_regnum_t regNum) {
_LIBUNWIND_TRACE_API("unw_is_fpreg(cursor=%p, regNum=%d)\n",
- cursor, regNum);
+ static_cast<void *>(cursor), regNum);
AbstractUnwindCursor *co = (AbstractUnwindCursor *)cursor;
return co->validFloatReg(regNum);
}
@@ -274,7 +280,7 @@ _LIBUNWIND_EXPORT int unw_is_fpreg(unw_cursor_t *cursor, unw_regnum_t regNum) {
_LIBUNWIND_EXPORT const char *unw_regname(unw_cursor_t *cursor,
unw_regnum_t regNum) {
_LIBUNWIND_TRACE_API("unw_regname(cursor=%p, regNum=%d)\n",
- cursor, regNum);
+ static_cast<void *>(cursor), regNum);
AbstractUnwindCursor *co = (AbstractUnwindCursor *)cursor;
return co->getRegisterName(regNum);
}
@@ -282,15 +288,17 @@ _LIBUNWIND_EXPORT const char *unw_regname(unw_cursor_t *cursor,
/// Checks if current frame is signal trampoline.
_LIBUNWIND_EXPORT int unw_is_signal_frame(unw_cursor_t *cursor) {
- _LIBUNWIND_TRACE_API("unw_is_signal_frame(cursor=%p)\n", cursor);
+ _LIBUNWIND_TRACE_API("unw_is_signal_frame(cursor=%p)\n",
+ static_cast<void *>(cursor));
AbstractUnwindCursor *co = (AbstractUnwindCursor *)cursor;
return co->isSignalFrame();
}
-#if __arm__
+#ifdef __arm__
// Save VFP registers d0-d15 using FSTMIADX instead of FSTMIADD
_LIBUNWIND_EXPORT void unw_save_vfp_as_X(unw_cursor_t *cursor) {
- _LIBUNWIND_TRACE_API("unw_fpreg_save_vfp_as_X(cursor=%p)\n", cursor);
+ _LIBUNWIND_TRACE_API("unw_fpreg_save_vfp_as_X(cursor=%p)\n",
+ static_cast<void *>(cursor));
AbstractUnwindCursor *co = (AbstractUnwindCursor *)cursor;
return co->saveVFPAsX();
}
@@ -301,7 +309,8 @@ _LIBUNWIND_EXPORT void unw_save_vfp_as_X(unw_cursor_t *cursor) {
/// SPI: walks cached dwarf entries
_LIBUNWIND_EXPORT void unw_iterate_dwarf_unwind_cache(void (*func)(
unw_word_t ip_start, unw_word_t ip_end, unw_word_t fde, unw_word_t mh)) {
- _LIBUNWIND_TRACE_API("unw_iterate_dwarf_unwind_cache(func=%p)\n", func);
+ _LIBUNWIND_TRACE_API("unw_iterate_dwarf_unwind_cache(func=%p)\n",
+ reinterpret_cast<void *>(func));
DwarfFDECache<LocalAddressSpace>::iterateCacheEntries(func);
}
diff --git a/src/abort_message.cpp b/src/abort_message.cpp
index 7702904..5e25c0f 100644
--- a/src/abort_message.cpp
+++ b/src/abort_message.cpp
@@ -24,9 +24,9 @@ extern "C" void android_set_abort_message(const char* msg);
#pragma GCC visibility push(hidden)
-#if __APPLE__
+#ifdef __APPLE__
# if defined(__has_include) && __has_include(<CrashReporterClient.h>)
-# define HAVE_CRASHREPORTERCLIENT_H 1
+# define HAVE_CRASHREPORTERCLIENT_H
# include <CrashReporterClient.h>
# endif
#endif
@@ -35,7 +35,7 @@ __attribute__((visibility("hidden"), noreturn))
void abort_message(const char* format, ...)
{
// write message to stderr
-#if __APPLE__
+#ifdef __APPLE__
fprintf(stderr, "libc++abi.dylib: ");
#endif
va_list list;
@@ -44,7 +44,7 @@ void abort_message(const char* format, ...)
va_end(list);
fprintf(stderr, "\n");
-#if __APPLE__ && HAVE_CRASHREPORTERCLIENT_H
+#if defined(__APPLE__) && defined(HAVE_CRASHREPORTERCLIENT_H)
// record message in crash report
char* buffer;
va_list list2;
@@ -52,7 +52,7 @@ void abort_message(const char* format, ...)
vasprintf(&buffer, format, list2);
va_end(list2);
CRSetCrashLogMessage(buffer);
-#elif __BIONIC__
+#elif defined(__BIONIC__)
char* buffer;
va_list list2;
va_start(list2, format);
diff --git a/src/cxa_exception.cpp b/src/cxa_exception.cpp
index e9f5e6e..b7a33d7 100644
--- a/src/cxa_exception.cpp
+++ b/src/cxa_exception.cpp
@@ -234,7 +234,7 @@ __cxa_throw(void* thrown_object, std::type_info* tinfo, void (*dest)(void*))
globals->uncaughtExceptions += 1; // Not atomically, since globals are thread-local
exception_header->unwindHeader.exception_cleanup = exception_cleanup_func;
-#if __USING_SJLJ_EXCEPTIONS__
+#ifdef __USING_SJLJ_EXCEPTIONS__
_Unwind_SjLj_RaiseException(&exception_header->unwindHeader);
#else
_Unwind_RaiseException(&exception_header->unwindHeader);
@@ -258,12 +258,10 @@ __cxa_get_exception_ptr(void* unwind_exception) throw()
{
#if LIBCXXABI_ARM_EHABI
return reinterpret_cast<void*>(
- static_cast<_Unwind_Control_Block*>(unwind_exception)->barrier_cache.bitpattern[0]);
+ static_cast<_Unwind_Control_Block*>(unwind_exception)->barrier_cache.bitpattern[0]);
#else
- return cxa_exception_from_exception_unwind_exception
- (
- static_cast<_Unwind_Exception*>(unwind_exception)
- )->adjustedPtr;
+ return cxa_exception_from_exception_unwind_exception(
+ static_cast<_Unwind_Exception*>(unwind_exception))->adjustedPtr;
#endif
}
@@ -571,7 +569,7 @@ __cxa_rethrow()
// nothing
globals->caughtExceptions = 0;
}
-#if __USING_SJLJ_EXCEPTIONS__
+#ifdef __USING_SJLJ_EXCEPTIONS__
_Unwind_SjLj_RaiseException(&exception_header->unwindHeader);
#else
_Unwind_RaiseException(&exception_header->unwindHeader);
@@ -700,7 +698,7 @@ __cxa_rethrow_primary_exception(void* thrown_object)
setDependentExceptionClass(&dep_exception_header->unwindHeader);
__cxa_get_globals()->uncaughtExceptions += 1;
dep_exception_header->unwindHeader.exception_cleanup = dependent_exception_cleanup;
-#if __USING_SJLJ_EXCEPTIONS__
+#ifdef __USING_SJLJ_EXCEPTIONS__
_Unwind_SjLj_RaiseException(&dep_exception_header->unwindHeader);
#else
_Unwind_RaiseException(&dep_exception_header->unwindHeader);
diff --git a/src/cxa_exception.hpp b/src/cxa_exception.hpp
index 9b22ce3..6e68f98 100644
--- a/src/cxa_exception.hpp
+++ b/src/cxa_exception.hpp
@@ -24,20 +24,20 @@ namespace __cxxabiv1 {
static const uint64_t kOurExceptionClass = 0x434C4E47432B2B00; // CLNGC++\0
static const uint64_t kOurDependentExceptionClass = 0x434C4E47432B2B01; // CLNGC++\1
-static const uint64_t get_vendor_and_language = 0xFFFFFFFFFFFFFF00; // mask for CLNGC++
-
-struct __cxa_exception {
-#if __LP64__ || LIBCXXABI_ARM_EHABI
+static const uint64_t get_vendor_and_language = 0xFFFFFFFFFFFFFF00; // mask for CLNGC++
+
+struct __cxa_exception {
+#if defined(__LP64__) || LIBCXXABI_ARM_EHABI
// This is a new field to support C++ 0x exception_ptr.
// For binary compatibility it is at the start of this
// struct which is prepended to the object thrown in
// __cxa_allocate_exception.
size_t referenceCount;
#endif
-
+
// Manage the exception object itself.
std::type_info *exceptionType;
- void (*exceptionDestructor)(void *);
+ void (*exceptionDestructor)(void *);
std::unexpected_handler unexpectedHandler;
std::terminate_handler terminateHandler;
@@ -56,7 +56,7 @@ struct __cxa_exception {
void *adjustedPtr;
#endif
-#if !__LP64__ && !LIBCXXABI_ARM_EHABI
+#if !defined(__LP64__) && !LIBCXXABI_ARM_EHABI
// This is a new field to support C++ 0x exception_ptr.
// For binary compatibility it is placed where the compiler
// previously adding padded to 64-bit align unwindHeader.
@@ -70,19 +70,19 @@ struct __cxa_exception {
// The layout of this structure MUST match the layout of __cxa_exception, with
// primaryException instead of referenceCount.
struct __cxa_dependent_exception {
-#if __LP64__ || LIBCXXABI_ARM_EHABI
+#if defined(__LP64__) || LIBCXXABI_ARM_EHABI
void* primaryException;
#endif
-
+
std::type_info *exceptionType;
- void (*exceptionDestructor)(void *);
+ void (*exceptionDestructor)(void *);
std::unexpected_handler unexpectedHandler;
std::terminate_handler terminateHandler;
__cxa_exception *nextException;
int handlerCount;
-
+
#if LIBCXXABI_ARM_EHABI
__cxa_exception* nextPropagatingException;
int propagationCount;
@@ -93,8 +93,8 @@ struct __cxa_dependent_exception {
void * catchTemp;
void *adjustedPtr;
#endif
-
-#if !__LP64__ && !LIBCXXABI_ARM_EHABI
+
+#if !defined(__LP64__) && !LIBCXXABI_ARM_EHABI
void* primaryException;
#endif
diff --git a/src/cxa_guard.cpp b/src/cxa_guard.cpp
index 5372a5c..1b41917 100644
--- a/src/cxa_guard.cpp
+++ b/src/cxa_guard.cpp
@@ -31,7 +31,7 @@ namespace __cxxabiv1
namespace
{
-#if __arm__
+#ifdef __arm__
// A 32-bit, 4-byte-aligned static data value. The least significant 2 bits must
// be statically initialized to 0.
diff --git a/src/cxa_personality.cpp b/src/cxa_personality.cpp
index 51f4a09..3ea8ca3 100644
--- a/src/cxa_personality.cpp
+++ b/src/cxa_personality.cpp
@@ -55,7 +55,7 @@
+------------------+--+-----+-----+------------------------+--------------------------+
| callSiteTableLength | (ULEB128) | Call Site Table length, used to find Action table |
+---------------------+-----------+---------------------------------------------------+
-#if !__USING_SJLJ_EXCEPTIONS__
+#ifndef __USING_SJLJ_EXCEPTIONS__
+---------------------+-----------+------------------------------------------------+
| Beginning of Call Site Table The current ip lies within the |
| ... (start, length) range of one of these |
@@ -595,7 +595,7 @@ static void scan_eh_tab(scan_results &results, _Unwind_Action actions,
// Get beginning current frame's code (as defined by the
// emitted dwarf code)
uintptr_t funcStart = _Unwind_GetRegionStart(context);
-#if __USING_SJLJ_EXCEPTIONS__
+#ifdef __USING_SJLJ_EXCEPTIONS__
if (ip == uintptr_t(-1))
{
// no action
@@ -628,7 +628,7 @@ static void scan_eh_tab(scan_results &results, _Unwind_Action actions,
// Walk call-site table looking for range that
// includes current PC.
uint8_t callSiteEncoding = *lsda++;
-#if __USING_SJLJ_EXCEPTIONS__
+#ifdef __USING_SJLJ_EXCEPTIONS__
(void)callSiteEncoding; // When using SjLj exceptions, callSiteEncoding is never used
#endif
uint32_t callSiteTableLength = static_cast<uint32_t>(readULEB128(&lsda));
@@ -639,7 +639,7 @@ static void scan_eh_tab(scan_results &results, _Unwind_Action actions,
while (callSitePtr < callSiteTableEnd)
{
// There is one entry per call site.
-#if !__USING_SJLJ_EXCEPTIONS__
+#ifndef __USING_SJLJ_EXCEPTIONS__
// 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);
@@ -655,7 +655,7 @@ static void scan_eh_tab(scan_results &results, _Unwind_Action actions,
#endif // __USING_SJLJ_EXCEPTIONS__
{
// Found the call site containing ip.
-#if !__USING_SJLJ_EXCEPTIONS__
+#ifndef __USING_SJLJ_EXCEPTIONS__
if (landingPad == 0)
{
// No handler here
@@ -857,7 +857,7 @@ static void scan_eh_tab(scan_results &results, _Unwind_Action actions,
action += actionOffset;
} // there is no break out of this loop, only return
}
-#if !__USING_SJLJ_EXCEPTIONS__
+#ifndef __USING_SJLJ_EXCEPTIONS__
else if (ipOffset < start)
{
// There is no call site for this ip
@@ -923,7 +923,7 @@ _UA_CLEANUP_PHASE
#if !LIBCXXABI_ARM_EHABI
_Unwind_Reason_Code
-#if __USING_SJLJ_EXCEPTIONS__
+#ifdef __USING_SJLJ_EXCEPTIONS__
__gxx_personality_sj0
#else
__gxx_personality_v0
@@ -1012,22 +1012,55 @@ __gxx_personality_v0
}
#else
+#if !LIBCXXABI_USE_LLVM_UNWINDER
+extern "C" _Unwind_Reason_Code __gnu_unwind_frame(_Unwind_Exception*, _Unwind_Context*);
+#endif
+
// Helper function to unwind one frame.
// ARM EHABI 7.3 and 7.4: If the personality function returns _URC_CONTINUE_UNWIND, the
// personality routine should update the virtual register set (VRS) according to the
// corresponding frame unwinding instructions (ARM EHABI 9.3.)
-static _Unwind_Reason_Code continue_unwind(_Unwind_Context* context,
- uint32_t* unwind_opcodes,
- size_t opcode_words)
+static _Unwind_Reason_Code continue_unwind(_Unwind_Exception* unwind_exception,
+ _Unwind_Context* context)
{
+#if LIBCXXABI_USE_LLVM_UNWINDER
+ // ARM EHABI # 6.2, # 9.2
+ //
+ // +---- ehtp
+ // v
+ // +--------------------------------------+
+ // | +--------+--------+--------+-------+ |
+ // | |0| prel31 to __gxx_personality_v0 | |
+ // | +--------+--------+--------+-------+ |
+ // | | N | unwind opcodes | | <-- unwind_opcodes
+ // | +--------+--------+--------+-------+ |
+ // | | Word 2 unwind opcodes | |
+ // | +--------+--------+--------+-------+ |
+ // | ... |
+ // | +--------+--------+--------+-------+ |
+ // | | Word N unwind opcodes | |
+ // | +--------+--------+--------+-------+ |
+ // | | LSDA | | <-- lsda
+ // | | ... | |
+ // | +--------+--------+--------+-------+ |
+ // +--------------------------------------+
+
+ uint32_t *unwind_opcodes = unwind_exception->pr_cache.ehtp + 1;
+ size_t opcode_words = ((*unwind_opcodes >> 24) & 0xff) + 1;
if (_Unwind_VRS_Interpret(context, unwind_opcodes, 1, opcode_words * 4) !=
_URC_CONTINUE_UNWIND)
return _URC_FAILURE;
+#else
+ if (__gnu_unwind_frame(unwind_exception, context) != _URC_OK)
+ return _URC_FAILURE;
+#endif
return _URC_CONTINUE_UNWIND;
}
// ARM register names
+#if !LIBCXXABI_USE_LLVM_UNWINDER
static const uint32_t REG_UCB = 12; // Register to save _Unwind_Control_Block
+#endif
static const uint32_t REG_SP = 13;
static void save_results_to_barrier_cache(_Unwind_Exception* unwind_exception,
@@ -1061,42 +1094,23 @@ __gxx_personality_v0(_Unwind_State state,
bool native_exception = (unwind_exception->exception_class & get_vendor_and_language) ==
(kOurExceptionClass & get_vendor_and_language);
-#if LIBCXXABI_ARM_EHABI
- // ARM EHABI # 6.2, # 9.2
- //
- // +---- ehtp
- // v
- // +--------------------------------------+
- // | +--------+--------+--------+-------+ |
- // | |0| prel31 to __gxx_personality_v0 | |
- // | +--------+--------+--------+-------+ |
- // | | N | unwind opcodes | | <-- UnwindData
- // | +--------+--------+--------+-------+ |
- // | | Word 2 unwind opcodes | |
- // | +--------+--------+--------+-------+ |
- // | ... |
- // | +--------+--------+--------+-------+ |
- // | | Word N unwind opcodes | |
- // | +--------+--------+--------+-------+ |
- // | | LSDA | | <-- lsda
- // | | ... | |
- // | +--------+--------+--------+-------+ |
- // +--------------------------------------+
-
- uint32_t *UnwindData = unwind_exception->pr_cache.ehtp + 1;
- uint32_t FirstDataWord = *UnwindData;
- size_t N = ((FirstDataWord >> 24) & 0xff);
- size_t NDataWords = N + 1;
-#endif
-
+#if !LIBCXXABI_USE_LLVM_UNWINDER
// Copy the address of _Unwind_Control_Block to r12 so that
// _Unwind_GetLanguageSpecificData() and _Unwind_GetRegionStart() can
// return correct address.
_Unwind_SetGR(context, REG_UCB, reinterpret_cast<uint32_t>(unwind_exception));
+#endif
+
+ // Check the undocumented force unwinding behavior
+ bool is_force_unwinding = state & _US_FORCE_UNWIND;
+ state &= ~_US_FORCE_UNWIND;
scan_results results;
switch (state) {
case _US_VIRTUAL_UNWIND_FRAME:
+ if (is_force_unwinding)
+ return continue_unwind(unwind_exception, context);
+
// Phase 1 search: All we're looking for in phase 1 is a handler that halts unwinding
scan_eh_tab(results, _UA_SEARCH_PHASE, native_exception, unwind_exception, context);
if (results.reason == _URC_HANDLER_FOUND)
@@ -1108,10 +1122,15 @@ __gxx_personality_v0(_Unwind_State state,
}
// Did not find the catch handler
if (results.reason == _URC_CONTINUE_UNWIND)
- return continue_unwind(context, UnwindData, NDataWords);
+ return continue_unwind(unwind_exception, context);
return results.reason;
case _US_UNWIND_FRAME_STARTING:
+ // TODO: Support force unwinding in the phase 2 search.
+ // NOTE: In order to call the cleanup functions, _Unwind_ForcedUnwind()
+ // will call this personality function with (_US_FORCE_UNWIND |
+ // _US_UNWIND_FRAME_STARTING).
+
// Phase 2 search
if (unwind_exception->barrier_cache.sp == _Unwind_GetGR(context, REG_SP))
{
@@ -1156,11 +1175,11 @@ __gxx_personality_v0(_Unwind_State state,
// Did not find any handler
if (results.reason == _URC_CONTINUE_UNWIND)
- return continue_unwind(context, UnwindData, NDataWords);
+ return continue_unwind(unwind_exception, context);
return results.reason;
case _US_UNWIND_FRAME_RESUME:
- return continue_unwind(context, UnwindData, NDataWords);
+ return continue_unwind(unwind_exception, context);
}
// We were called improperly: neither a phase 1 or phase 2 search
diff --git a/src/private_typeinfo.cpp b/src/private_typeinfo.cpp
index 38e70ab..821796f 100644
--- a/src/private_typeinfo.cpp
+++ b/src/private_typeinfo.cpp
@@ -34,7 +34,7 @@
//
// _LIBCXX_DYNAMIC_FALLBACK is currently off by default.
-#if _LIBCXX_DYNAMIC_FALLBACK
+#ifdef _LIBCXX_DYNAMIC_FALLBACK
#include "abort_message.h"
#include <string.h>
#include <sys/syslog.h>
@@ -57,7 +57,7 @@ namespace __cxxabiv1
#pragma GCC visibility push(hidden)
-#if _LIBCXX_DYNAMIC_FALLBACK
+#ifdef _LIBCXX_DYNAMIC_FALLBACK
inline
bool
@@ -515,7 +515,7 @@ __dynamic_cast(const void* static_ptr,
info.number_of_dst_type = 1;
// Do the search
dynamic_type->search_above_dst(&info, dynamic_ptr, dynamic_ptr, public_path, false);
-#if _LIBCXX_DYNAMIC_FALLBACK
+#ifdef _LIBCXX_DYNAMIC_FALLBACK
// The following if should always be false because we should definitely
// find (static_ptr, static_type), either on a public or private path
if (info.path_dst_ptr_to_static_ptr == unknown)
@@ -539,7 +539,7 @@ __dynamic_cast(const void* static_ptr,
{
// Not using giant short cut. Do the search
dynamic_type->search_below_dst(&info, dynamic_ptr, public_path, false);
- #if _LIBCXX_DYNAMIC_FALLBACK
+ #ifdef _LIBCXX_DYNAMIC_FALLBACK
// The following if should always be false because we should definitely
// find (static_ptr, static_type), either on a public or private path
if (info.path_dst_ptr_to_static_ptr == unknown &&