cmake_policy(SET CMP0042 NEW) # Set MACOSX_RPATH=YES by default
endif()
+# Add path for custom modules
+set(CMAKE_MODULE_PATH
+ "${CMAKE_CURRENT_SOURCE_DIR}/cmake"
+ "${CMAKE_CURRENT_SOURCE_DIR}/cmake/Modules"
+ ${CMAKE_MODULE_PATH}
+ )
+
if (CMAKE_SOURCE_DIR STREQUAL CMAKE_CURRENT_SOURCE_DIR)
project(libunwind)
# Rely on llvm-config.
set(CONFIG_OUTPUT)
- find_program(LLVM_CONFIG "llvm-config")
+ if(NOT LLVM_CONFIG_PATH)
+ find_program(LLVM_CONFIG_PATH "llvm-config")
+ endif()
if (DEFINED LLVM_PATH)
set(LLVM_INCLUDE_DIR ${LLVM_INCLUDE_DIR} CACHE PATH "Path to llvm/include")
set(LLVM_PATH ${LLVM_PATH} CACHE PATH "Path to LLVM source tree")
set(LLVM_MAIN_SRC_DIR ${LLVM_PATH})
set(LLVM_CMAKE_PATH "${LLVM_PATH}/cmake/modules")
- elseif (LLVM_CONFIG)
- message(STATUS "Found LLVM_CONFIG as ${LLVM_CONFIG}")
- set(CONFIG_COMMAND ${LLVM_CONFIG} "--includedir" "--prefix" "--src-root")
+ elseif(LLVM_CONFIG_PATH)
+ message(STATUS "Found LLVM_CONFIG_PATH as ${LLVM_CONFIG_PATH}")
+ set(CONFIG_COMMAND ${LLVM_CONFIG_PATH} "--includedir" "--prefix" "--src-root")
execute_process(COMMAND ${CONFIG_COMMAND}
RESULT_VARIABLE HAD_ERROR
OUTPUT_VARIABLE CONFIG_OUTPUT)
set(LLVM_INCLUDE_DIR ${INCLUDE_DIR} CACHE PATH "Path to llvm/include")
set(LLVM_BINARY_DIR ${LLVM_OBJ_ROOT} CACHE PATH "Path to LLVM build tree")
set(LLVM_MAIN_SRC_DIR ${MAIN_SRC_DIR} CACHE PATH "Path to LLVM source tree")
- set(LLVM_CMAKE_PATH "${LLVM_BINARY_DIR}/lib${LLVM_LIBDIR_SUFFIX}/cmake/llvm")
set(LLVM_LIT_PATH "${LLVM_PATH}/utils/lit/lit.py")
+
+ # --cmakedir is supported since llvm r291218 (4.0 release)
+ execute_process(
+ COMMAND ${LLVM_CONFIG_PATH} --cmakedir
+ RESULT_VARIABLE HAD_ERROR
+ OUTPUT_VARIABLE CONFIG_OUTPUT
+ ERROR_QUIET)
+ if(NOT HAD_ERROR)
+ string(STRIP "${CONFIG_OUTPUT}" LLVM_CMAKE_PATH)
+ else()
+ set(LLVM_CMAKE_PATH
+ "${LLVM_BINARY_DIR}/lib${LLVM_LIBDIR_SUFFIX}/cmake/llvm")
+ endif()
else()
message(FATAL_ERROR "llvm-config not found and LLVM_MAIN_SRC_DIR not defined. "
"Reconfigure with -DLLVM_CONFIG=path/to/llvm-config "
endif()
set(PACKAGE_NAME libunwind)
- set(PACKAGE_VERSION 3.9.0)
+ set(PACKAGE_VERSION 6.0.0)
set(PACKAGE_STRING "${PACKAGE_NAME} ${PACKAGE_VERSION}")
set(PACKAGE_BUGREPORT "llvm-bugs@lists.llvm.org")
#===============================================================================
# Setup CMake Options
#===============================================================================
+include(HandleCompilerRT)
# Define options.
option(LIBUNWIND_BUILD_32_BITS "Build 32 bit libunwind" ${LLVM_BUILD_32_BITS})
option(LIBUNWIND_ENABLE_PEDANTIC "Compile with pedantic enabled." ON)
option(LIBUNWIND_ENABLE_WERROR "Fail and stop if a warning is triggered." OFF)
option(LIBUNWIND_ENABLE_SHARED "Build libunwind as a shared library." ON)
+option(LIBUNWIND_ENABLE_STATIC "Build libunwind as a static library." ON)
option(LIBUNWIND_ENABLE_CROSS_UNWINDING "Enable cross-platform unwinding support." OFF)
option(LIBUNWIND_ENABLE_ARM_WMMX "Enable unwinding support for ARM WMMX registers." OFF)
+option(LIBUNWIND_ENABLE_THREADS "Build libunwind with threading support." ON)
+option(LIBUNWIND_USE_COMPILER_RT "Use compiler-rt instead of libgcc" OFF)
+option(LIBUNWIND_INCLUDE_DOCS "Build the libunwind documentation." ${LLVM_INCLUDE_DOCS})
+set(LIBUNWIND_LIBDIR_SUFFIX "${LLVM_LIBDIR_SUFFIX}" CACHE STRING
+ "Define suffix of library directory name (32/64)")
+option(LIBUNWIND_INSTALL_LIBRARY "Install the libunwind library." ON)
set(LIBUNWIND_TARGET_TRIPLE "" CACHE STRING "Target triple for cross compiling.")
set(LIBUNWIND_GCC_TOOLCHAIN "" CACHE PATH "GCC toolchain for cross compiling.")
set(LIBUNWIND_SYSROOT "" CACHE PATH "Sysroot for cross compiling.")
+if (NOT LIBUNWIND_ENABLE_SHARED AND NOT LIBUNWIND_ENABLE_STATIC)
+ message(FATAL_ERROR "libunwind must be built as either a shared or static library.")
+endif()
+
# Check that we can build with 32 bits if requested.
if (CMAKE_SIZEOF_VOID_P EQUAL 8 AND NOT WIN32)
if (LIBUNWIND_BUILD_32_BITS AND NOT LLVM_BUILD_32_BITS) # Don't duplicate the output from LLVM
set(LIBUNWIND_COMPILER ${CMAKE_CXX_COMPILER})
set(LIBUNWIND_SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR})
set(LIBUNWIND_BINARY_DIR ${CMAKE_CURRENT_BINARY_DIR})
-set(LIBUNWIND_LIBRARY_DIR ${CMAKE_BINARY_DIR}/lib${LLVM_LIBDIR_SUFFIX})
+if (LLVM_LIBRARY_OUTPUT_INTDIR)
+ set(LIBUNWIND_LIBRARY_DIR ${LLVM_LIBRARY_OUTPUT_INTDIR})
+else()
+ set(LIBUNWIND_LIBRARY_DIR ${CMAKE_BINARY_DIR}/lib${LIBUNWIND_LIBDIR_SUFFIX})
+endif()
+
+set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${LIBUNWIND_LIBRARY_DIR})
+set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${LIBUNWIND_LIBRARY_DIR})
+set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${LIBUNWIND_LIBRARY_DIR})
+
+set(LIBUNWIND_INSTALL_PREFIX "" CACHE STRING
+ "Define libunwind destination prefix.")
+
+if (NOT LIBUNWIND_INSTALL_PREFIX MATCHES "^$|.*/")
+ message(FATAL_ERROR "LIBUNWIND_INSTALL_PREFIX has to end with \"/\".")
+endif()
set(LIBUNWIND_C_FLAGS "")
set(LIBUNWIND_CXX_FLAGS "")
if (${condition})
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${var}")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${var}")
- list(APPEND LINUNWIND_COMPILE_FLAGS ${var})
+ list(APPEND LIBUNWIND_COMPILE_FLAGS ${var})
list(APPEND LIBUNWIND_LINK_FLAGS ${var})
endif()
endmacro()
add_target_flags_if(LIBUNWIND_BUILD_32_BITS "-m32")
add_target_flags_if(LIBUNWIND_TARGET_TRIPLE
- "-target ${LIBUNWIND_TARGET_TRIPLE}")
+ "--target=${LIBUNWIND_TARGET_TRIPLE}")
add_target_flags_if(LIBUNWIND_GCC_TOOLCHAIN
- "-gcc-toolchain ${LIBUNWIND_GCC_TOOLCHAIN}")
+ "--gcc-toolchain=${LIBUNWIND_GCC_TOOLCHAIN}")
add_target_flags_if(LIBUNWIND_SYSROOT
"--sysroot=${LIBUNWIND_SYSROOT}")
+if (LIBUNWIND_TARGET_TRIPLE)
+ set(TARGET_TRIPLE "${LIBUNWIND_TARGET_TRIPLE}")
+endif()
+
# Configure compiler.
include(config-ix)
+if (LIBUNWIND_USE_COMPILER_RT)
+ list(APPEND LIBUNWIND_LINK_FLAGS "-rtlib=compiler-rt")
+endif()
+
#===============================================================================
# Setup Compiler Flags
#===============================================================================
list(APPEND LIBUNWIND_COMPILE_FLAGS -D_LIBUNWIND_IS_NATIVE_ONLY)
endif()
+# Threading-support
+if (NOT LIBUNWIND_ENABLE_THREADS)
+ list(APPEND LIBUNWIND_COMPILE_FLAGS -D_LIBUNWIND_HAS_NO_THREADS)
+endif()
+
# ARM WMMX register support
if (LIBUNWIND_ENABLE_ARM_WMMX)
# __ARM_WMMX is a compiler pre-define (as per the ACLE 2.0). Clang does not
add_definitions(-D_CRT_SECURE_NO_WARNINGS)
endif()
+# Disable DLL annotations on Windows for static builds.
+if (WIN32 AND LIBUNWIND_ENABLE_STATIC AND NOT LIBUNWIND_ENABLE_SHARED)
+ add_definitions(-D_LIBUNWIND_DISABLE_VISIBILITY_ANNOTATIONS)
+endif()
+
#===============================================================================
# Setup Source Code
#===============================================================================
include_directories(include)
+find_path(
+ LIBUNWIND_LIBCXX_INCLUDES_INTERNAL
+ __libcpp_version
+ PATHS ${LLVM_MAIN_SRC_DIR}/projects/libcxx/include
+ ${LLVM_MAIN_SRC_DIR}/runtimes/libcxx/include
+ NO_DEFAULT_PATH
+)
+if ((NOT LIBUNWIND_STANDALONE_BUILD OR HAVE_LIBCXX) AND
+ IS_DIRECTORY "${LIBUNWIND_LIBCXX_INCLUDES_INTERNAL}")
+ set(LIBUNWIND_CXX_INCLUDE_PATHS_DEFAULT "${LIBUNWIND_LIBCXX_INCLUDES_INTERNAL}")
+endif()
+
+set(LIBUNWIND_CXX_INCLUDE_PATHS "${LIBUNWIND_CXX_INCLUDE_PATHS_DEFAULT}" CACHE PATH
+ "Paths to C++ header directories separated by ';'.")
+
+if (NOT LIBUNWIND_CXX_INCLUDE_PATHS STREQUAL "")
+ list(APPEND LIBUNWIND_CXX_FLAGS -nostdinc++)
+ include_directories("${LIBUNWIND_CXX_INCLUDE_PATHS}")
+endif()
+
add_subdirectory(src)
+
+if (LIBUNWIND_INCLUDE_DOCS)
+ add_subdirectory(docs)
+endif()
+
+add_subdirectory(test)
--- /dev/null
+==============================================================================
+libunwind License
+==============================================================================
+
+The libunwind library is dual licensed under both the University of Illinois
+"BSD-Like" license and the MIT license. As a user of this code you may choose
+to use it under either license. As a contributor, you agree to allow your code
+to be used under both.
+
+Full text of the relevant licenses is included below.
+
+==============================================================================
+
+University of Illinois/NCSA
+Open Source License
+
+Copyright (c) 2009-2017 by the contributors listed in CREDITS.TXT
+
+All rights reserved.
+
+Developed by:
+
+ LLVM Team
+
+ University of Illinois at Urbana-Champaign
+
+ http://llvm.org
+
+Permission is hereby granted, free of charge, to any person obtaining a copy of
+this software and associated documentation files (the "Software"), to deal with
+the Software without restriction, including without limitation the rights to
+use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
+of the Software, and to permit persons to whom the Software is furnished to do
+so, subject to the following conditions:
+
+ * Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimers.
+
+ * Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimers in the
+ documentation and/or other materials provided with the distribution.
+
+ * Neither the names of the LLVM Team, University of Illinois at
+ Urbana-Champaign, nor the names of its contributors may be used to
+ endorse or promote products derived from this Software without specific
+ prior written permission.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
+FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS WITH THE
+SOFTWARE.
+
+==============================================================================
+
+Copyright (c) 2009-2014 by the contributors listed in CREDITS.TXT
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
--- /dev/null
+function(find_compiler_rt_library name dest)
+ if (NOT DEFINED LIBUNWIND_COMPILE_FLAGS)
+ message(FATAL_ERROR "LIBUNWIND_COMPILE_FLAGS must be defined when using this function")
+ endif()
+ set(dest "" PARENT_SCOPE)
+ set(CLANG_COMMAND ${CMAKE_CXX_COMPILER} ${LIBUNWIND_COMPILE_FLAGS}
+ "--rtlib=compiler-rt" "--print-libgcc-file-name")
+ if (CMAKE_CXX_COMPILER_ID MATCHES Clang AND CMAKE_CXX_COMPILER_TARGET)
+ list(APPEND CLANG_COMMAND "--target=${CMAKE_CXX_COMPILER_TARGET}")
+ endif()
+ execute_process(
+ COMMAND ${CLANG_COMMAND}
+ RESULT_VARIABLE HAD_ERROR
+ OUTPUT_VARIABLE LIBRARY_FILE
+ )
+ string(STRIP "${LIBRARY_FILE}" LIBRARY_FILE)
+ string(REPLACE "builtins" "${name}" LIBRARY_FILE "${LIBRARY_FILE}")
+ if (NOT HAD_ERROR AND EXISTS "${LIBRARY_FILE}")
+ message(STATUS "Found compiler-rt library: ${LIBRARY_FILE}")
+ set(${dest} "${LIBRARY_FILE}" PARENT_SCOPE)
+ else()
+ message(STATUS "Failed to find compiler-rt library")
+ endif()
+endfunction()
+
+function(find_compiler_rt_dir dest)
+ if (NOT DEFINED LIBUNWIND_COMPILE_FLAGS)
+ message(FATAL_ERROR "LIBUNWIND_COMPILE_FLAGS must be defined when using this function")
+ endif()
+ set(dest "" PARENT_SCOPE)
+ if (APPLE)
+ set(CLANG_COMMAND ${CMAKE_CXX_COMPILER} ${LIBUNWIND_COMPILE_FLAGS}
+ "-print-file-name=lib")
+ execute_process(
+ COMMAND ${CLANG_COMMAND}
+ RESULT_VARIABLE HAD_ERROR
+ OUTPUT_VARIABLE LIBRARY_DIR
+ )
+ string(STRIP "${LIBRARY_DIR}" LIBRARY_DIR)
+ set(LIBRARY_DIR "${LIBRARY_DIR}/darwin")
+ else()
+ set(CLANG_COMMAND ${CMAKE_CXX_COMPILER} ${LIBUNWIND_COMPILE_FLAGS}
+ "--rtlib=compiler-rt" "--print-libgcc-file-name")
+ execute_process(
+ COMMAND ${CLANG_COMMAND}
+ RESULT_VARIABLE HAD_ERROR
+ OUTPUT_VARIABLE LIBRARY_FILE
+ )
+ string(STRIP "${LIBRARY_FILE}" LIBRARY_FILE)
+ get_filename_component(LIBRARY_DIR "${LIBRARY_FILE}" DIRECTORY)
+ endif()
+ if (NOT HAD_ERROR AND EXISTS "${LIBRARY_DIR}")
+ message(STATUS "Found compiler-rt directory: ${LIBRARY_DIR}")
+ set(${dest} "${LIBRARY_DIR}" PARENT_SCOPE)
+ else()
+ message(STATUS "Failed to find compiler-rt directory")
+ endif()
+endfunction()
include(CheckCXXCompilerFlag)
include(CheckLibraryExists)
+check_library_exists(c fopen "" LIBUNWIND_HAS_C_LIB)
+
+if (NOT LIBUNWIND_USE_COMPILER_RT)
+ check_library_exists(gcc_s __gcc_personality_v0 "" LIBUNWIND_HAS_GCC_S_LIB)
+endif()
+
+# libunwind is built with -nodefaultlibs, so we want all our checks to also
+# use this option, otherwise we may end up with an inconsistency between
+# the flags we think we require during configuration (if the checks are
+# performed without -nodefaultlibs) and the flags that are actually
+# required during compilation (which has the -nodefaultlibs). libc is
+# required for the link to go through. We remove sanitizers from the
+# configuration checks to avoid spurious link errors.
+check_c_compiler_flag(-nodefaultlibs LIBUNWIND_HAS_NODEFAULTLIBS_FLAG)
+if (LIBUNWIND_HAS_NODEFAULTLIBS_FLAG)
+ set(CMAKE_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS} -nodefaultlibs")
+ if (LIBUNWIND_HAS_C_LIB)
+ list(APPEND CMAKE_REQUIRED_LIBRARIES c)
+ endif ()
+ if (LIBUNWIND_USE_COMPILER_RT)
+ list(APPEND CMAKE_REQUIRED_FLAGS -rtlib=compiler-rt)
+ find_compiler_rt_library(builtins LIBUNWIND_BUILTINS_LIBRARY)
+ list(APPEND CMAKE_REQUIRED_LIBRARIES "${LIBUNWIND_BUILTINS_LIBRARY}")
+ elseif (LIBUNWIND_HAS_GCC_S_LIB)
+ list(APPEND CMAKE_REQUIRED_LIBRARIES gcc_s)
+ endif ()
+ if (MINGW)
+ # Mingw64 requires quite a few "C" runtime libraries in order for basic
+ # programs to link successfully with -nodefaultlibs.
+ if (LIBUNWIND_USE_COMPILER_RT)
+ set(MINGW_RUNTIME ${LIBUNWIND_BUILTINS_LIBRARY})
+ else ()
+ set(MINGW_RUNTIME gcc_s gcc)
+ endif()
+ set(MINGW_LIBRARIES mingw32 ${MINGW_RUNTIME} moldname mingwex msvcrt advapi32
+ shell32 user32 kernel32 mingw32 ${MINGW_RUNTIME}
+ moldname mingwex msvcrt)
+ list(APPEND CMAKE_REQUIRED_LIBRARIES ${MINGW_LIBRARIES})
+ endif()
+ if (CMAKE_C_FLAGS MATCHES -fsanitize OR CMAKE_CXX_FLAGS MATCHES -fsanitize)
+ set(CMAKE_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS} -fno-sanitize=all")
+ endif ()
+ if (CMAKE_C_FLAGS MATCHES -fsanitize-coverage OR CMAKE_CXX_FLAGS MATCHES -fsanitize-coverage)
+ set(CMAKE_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS} -fno-sanitize-coverage=edge,trace-cmp,indirect-calls,8bit-counters")
+ endif ()
+endif ()
+
# Check compiler flags
check_c_compiler_flag(-funwind-tables LIBUNWIND_HAS_FUNWIND_TABLES)
-check_cxx_compiler_flag(-fPIC LIBUNWIND_HAS_FPIC_FLAG)
check_cxx_compiler_flag(-fno-exceptions LIBUNWIND_HAS_NO_EXCEPTIONS_FLAG)
check_cxx_compiler_flag(-fno-rtti LIBUNWIND_HAS_NO_RTTI_FLAG)
check_cxx_compiler_flag(-fstrict-aliasing LIBUNWIND_HAS_FSTRICT_ALIASING_FLAG)
-check_cxx_compiler_flag(-nodefaultlibs LIBUNWIND_HAS_NODEFAULTLIBS_FLAG)
check_cxx_compiler_flag(-nostdinc++ LIBUNWIND_HAS_NOSTDINCXX_FLAG)
check_cxx_compiler_flag(-Wall LIBUNWIND_HAS_WALL_FLAG)
check_cxx_compiler_flag(-W LIBUNWIND_HAS_W_FLAG)
check_cxx_compiler_flag(/EHs- LIBUNWIND_HAS_NO_EHS_FLAG)
check_cxx_compiler_flag(/EHa- LIBUNWIND_HAS_NO_EHA_FLAG)
check_cxx_compiler_flag(/GR- LIBUNWIND_HAS_NO_GR_FLAG)
+check_cxx_compiler_flag(-std=c++11 LIBUNWIND_HAS_STD_CXX11)
+
+if(LIBUNWIND_HAS_STD_CXX11)
+ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
+endif()
-check_library_exists(c fopen "" LIBUNWIND_HAS_C_LIB)
check_library_exists(dl dladdr "" LIBUNWIND_HAS_DL_LIB)
check_library_exists(pthread pthread_once "" LIBUNWIND_HAS_PTHREAD_LIB)
// Source Licenses. See LICENSE.TXT for details.
//
//
-// Darwin's alternative to dwarf based unwind encodings.
+// Darwin's alternative to DWARF based unwind encodings.
//
//===----------------------------------------------------------------------===//
#include <stdint.h>
//
-// Compilers can emit standard Dwarf FDEs in the __TEXT,__eh_frame section
+// Compilers can emit standard DWARF FDEs in the __TEXT,__eh_frame section
// of object files. Or compilers can emit compact unwind information in
// the __LD,__compact_unwind section.
//
// runtime to access unwind info for any given function. If the compiler
// emitted compact unwind info for the function, that compact unwind info will
// be encoded in the __TEXT,__unwind_info section. If the compiler emitted
-// dwarf unwind info, the __TEXT,__unwind_info section will contain the offset
+// DWARF unwind info, the __TEXT,__unwind_info section will contain the offset
// of the FDE in the __TEXT,__eh_frame section in the final linked image.
//
-// Note: Previously, the linker would transform some dwarf unwind infos into
+// Note: Previously, the linker would transform some DWARF unwind infos into
// compact unwind info. But that is fragile and no longer done.
// 1-bit: has lsda
// 2-bit: personality index
//
-// 4-bits: 0=old, 1=ebp based, 2=stack-imm, 3=stack-ind, 4=dwarf
+// 4-bits: 0=old, 1=ebp based, 2=stack-imm, 3=stack-ind, 4=DWARF
// ebp based:
// 15-bits (5*3-bits per reg) register permutation
// 8-bits for stack offset
// UNWIND_X86_FRAMELESS_STACK_SIZE.
// UNWIND_X86_MODE_DWARF:
// No compact unwind encoding is available. Instead the low 24-bits of the
-// compact encoding is the offset of the dwarf FDE in the __eh_frame section.
+// compact encoding is the offset of the DWARF FDE in the __eh_frame section.
// This mode is never used in object files. It is only generated by the
-// linker in final linked images which have only dwarf unwind info for a
+// linker in final linked images which have only DWARF unwind info for a
// function.
//
// The permutation encoding is a Lehmer code sequence encoded into a
// 1-bit: has lsda
// 2-bit: personality index
//
-// 4-bits: 0=old, 1=rbp based, 2=stack-imm, 3=stack-ind, 4=dwarf
+// 4-bits: 0=old, 1=rbp based, 2=stack-imm, 3=stack-ind, 4=DWARF
// rbp based:
// 15-bits (5*3-bits per reg) register permutation
// 8-bits for stack offset
// UNWIND_X86_64_FRAMELESS_STACK_SIZE.
// UNWIND_X86_64_MODE_DWARF:
// No compact unwind encoding is available. Instead the low 24-bits of the
-// compact encoding is the offset of the dwarf FDE in the __eh_frame section.
+// compact encoding is the offset of the DWARF FDE in the __eh_frame section.
// This mode is never used in object files. It is only generated by the
-// linker in final linked images which have only dwarf unwind info for a
+// linker in final linked images which have only DWARF unwind info for a
// function.
//
// 1-bit: has lsda
// 2-bit: personality index
//
-// 4-bits: 4=frame-based, 3=dwarf, 2=frameless
+// 4-bits: 4=frame-based, 3=DWARF, 2=frameless
// frameless:
// 12-bits of stack size
// frame-based:
// 4-bits D reg pairs saved
// 5-bits X reg pairs saved
-// dwarf:
-// 24-bits offset of dwarf FDE in __eh_frame section
+// DWARF:
+// 24-bits offset of DWARF FDE in __eh_frame section
//
enum {
UNWIND_ARM64_MODE_MASK = 0x0F000000,
// UNWIND_ARM64_FRAMELESS_STACK_SIZE_MASK.
// UNWIND_ARM64_MODE_DWARF:
// No compact unwind encoding is available. Instead the low 24-bits of the
-// compact encoding is the offset of the dwarf FDE in the __eh_frame section.
+// compact encoding is the offset of the DWARF FDE in the __eh_frame section.
// This mode is never used in object files. It is only generated by the
-// linker in final linked images which have only dwarf unwind info for a
+// linker in final linked images which have only DWARF unwind info for a
// function.
//
// saved at that range of the function.
//
// If a particular function is so wacky that there is no compact unwind way
-// to encode it, then the compiler can emit traditional dwarf unwind info.
+// to encode it, then the compiler can emit traditional DWARF unwind info.
// The runtime will use which ever is available.
//
// Runtime support for compact unwind encodings are only available on 10.6
_URC_HANDLER_FOUND = 6,
_URC_INSTALL_CONTEXT = 7,
_URC_CONTINUE_UNWIND = 8,
-#if _LIBUNWIND_ARM_EHABI
+#if defined(_LIBUNWIND_ARM_EHABI)
_URC_FAILURE = 9
#endif
} _Unwind_Reason_Code;
typedef struct _Unwind_Context _Unwind_Context; // opaque
-#if _LIBUNWIND_ARM_EHABI
+#if defined(_LIBUNWIND_ARM_EHABI)
typedef uint32_t _Unwind_State;
static const _Unwind_State _US_VIRTUAL_UNWIND_FRAME = 0;
static const _Unwind_State _US_UNWIND_FRAME_STARTING = 1;
static const _Unwind_State _US_UNWIND_FRAME_RESUME = 2;
+static const _Unwind_State _US_ACTION_MASK = 3;
/* Undocumented flag for force unwinding. */
static const _Unwind_State _US_FORCE_UNWIND = 8;
} pr_cache;
long long int :0; /* Enforce the 8-byte alignment */
-};
+} __attribute__((__aligned__(8)));
typedef _Unwind_Reason_Code (*_Unwind_Stop_Fn)
(_Unwind_State state,
_Unwind_Exception *exc);
uintptr_t private_1; // non-zero means forced unwind
uintptr_t private_2; // holds sp that phase1 found for phase2 to use
-#ifndef __LP64__
+#if __SIZEOF_POINTER__ == 4
// The implementation of _Unwind_Exception uses an attribute mode on the
// above fields which has the side effect of causing this whole struct to
// round up to 32 bytes in size. To be more explicit, we add pad fields
#endif
extern void _Unwind_DeleteException(_Unwind_Exception *exception_object);
-#if _LIBUNWIND_ARM_EHABI
+#if defined(_LIBUNWIND_ARM_EHABI)
typedef enum {
_UVRSC_CORE = 0, /* integer register */
_UVRSC_VFP = 1, /* vfp */
_Unwind_VRS_DataRepresentation representation);
#endif
-#if !_LIBUNWIND_ARM_EHABI
+#if !defined(_LIBUNWIND_ARM_EHABI)
extern uintptr_t _Unwind_GetGR(struct _Unwind_Context *context, int index);
extern void _Unwind_SetGR(struct _Unwind_Context *context, int index,
extern uintptr_t _Unwind_GetIP(struct _Unwind_Context *context);
extern void _Unwind_SetIP(struct _Unwind_Context *, uintptr_t new_value);
-#else // _LIBUNWIND_ARM_EHABI
+#else // defined(_LIBUNWIND_ARM_EHABI)
#if defined(_LIBUNWIND_UNWIND_LEVEL1_EXTERNAL_LINKAGE)
#define _LIBUNWIND_EXPORT_UNWIND_LEVEL1 extern
uintptr_t thumb_bit = _Unwind_GetGR(context, 15) & ((uintptr_t)0x1);
_Unwind_SetGR(context, 15, value | thumb_bit);
}
-#endif // _LIBUNWIND_ARM_EHABI
+#endif // defined(_LIBUNWIND_ARM_EHABI)
extern uintptr_t _Unwind_GetRegionStart(struct _Unwind_Context *context);
extern uintptr_t
// _Unwind_Find_FDE() will locate the FDE if the pc is in some function that has
// an associated FDE. Note, Mac OS X 10.6 and later, introduces "compact unwind
-// info" which the runtime uses in preference to dwarf unwind info. This
+// info" which the runtime uses in preference to DWARF unwind info. This
// function will only work if the target function has an FDE but no compact
// unwind info.
struct dwarf_eh_bases {
// This function attempts to find the start (address of first instruction) of
// a function given an address inside the function. It only works if the
-// function has an FDE (dwarf unwind info).
+// function has an FDE (DWARF unwind info).
// This function is unimplemented on Mac OS X 10.6 and later. Instead, use
// _Unwind_Find_FDE() and look at the dwarf_eh_bases.func result.
extern void *_Unwind_FindEnclosingFunction(void *pc);
DwarfParser.hpp
libunwind_ext.h
Registers.hpp
+ RWMutex.hpp
UnwindCursor.hpp
- unwind_ext.h
${CMAKE_CURRENT_SOURCE_DIR}/../include/libunwind.h
${CMAKE_CURRENT_SOURCE_DIR}/../include/unwind.h)
${LIBUNWIND_C_SOURCES}
${LIBUNWIND_ASM_SOURCES})
-if (LIBUNWIND_ENABLE_SHARED)
- add_library(unwind SHARED ${LIBUNWIND_SOURCES} ${LIBUNWIND_HEADERS})
-else()
- add_library(unwind STATIC ${LIBUNWIND_SOURCES} ${LIBUNWIND_HEADERS})
-endif ()
-
# Generate library list.
set(libraries ${LIBUNWINDCXX_ABI_LIBRARIES})
append_if(libraries LIBUNWIND_HAS_C_LIB c)
append_if(libraries LIBUNWIND_HAS_DL_LIB dl)
-append_if(libraries LIBUNWIND_HAS_PTHREAD_LIB pthread)
-
-target_link_libraries(unwind ${libraries})
+if (LIBUNWIND_ENABLE_THREADS)
+ append_if(libraries LIBUNWIND_HAS_PTHREAD_LIB pthread)
+endif()
# Setup flags.
-append_if(LIBUNWIND_COMPILE_FLAGS LIBUNWIND_HAS_FPIC_FLAG -fPIC)
append_if(LIBUNWIND_CXX_FLAGS LIBUNWIND_HAS_NO_RTTI_FLAG -fno-rtti)
append_if(LIBUNWIND_LINK_FLAGS LIBUNWIND_HAS_NODEFAULTLIBS_FLAG -nodefaultlibs)
string(REPLACE ";" " " LIBUNWIND_C_FLAGS "${LIBUNWIND_C_FLAGS}")
string(REPLACE ";" " " LIBUNWIND_LINK_FLAGS "${LIBUNWIND_LINK_FLAGS}")
-set_target_properties(unwind
- PROPERTIES
- COMPILE_FLAGS "${LIBUNWIND_COMPILE_FLAGS}"
- LINK_FLAGS "${LIBUNWIND_LINK_FLAGS}"
- OUTPUT_NAME "unwind"
- VERSION "1.0"
- SOVERSION "1")
set_property(SOURCE ${LIBUNWIND_CXX_SOURCES}
APPEND_STRING PROPERTY COMPILE_FLAGS " ${CMAKE_CXX_FLAGS} ${LIBUNWIND_CXX_FLAGS}")
set_property(SOURCE ${LIBUNWIND_C_SOURCES}
APPEND_STRING PROPERTY COMPILE_FLAGS " ${CMAKE_C_FLAGS} ${LIBUNWIND_C_FLAGS}")
-install(TARGETS unwind
- LIBRARY DESTINATION lib${LLVM_LIBDIR_SUFFIX}
- ARCHIVE DESTINATION lib${LLVM_LIBDIR_SUFFIX})
+# Add a object library that contains the compiled source files.
+add_library(unwind_objects OBJECT ${LIBUNWIND_SOURCES} ${LIBUNWIND_HEADERS})
+
+set_target_properties(unwind_objects
+ PROPERTIES
+ COMPILE_FLAGS "${LIBUNWIND_COMPILE_FLAGS}"
+ POSITION_INDEPENDENT_CODE ON)
+
+set(LIBUNWIND_TARGETS)
+
+# Build the shared library.
+if (LIBUNWIND_ENABLE_SHARED)
+ add_library(unwind_shared SHARED $<TARGET_OBJECTS:unwind_objects>)
+ target_link_libraries(unwind_shared ${libraries})
+ set_target_properties(unwind_shared
+ PROPERTIES
+ LINK_FLAGS "${LIBUNWIND_LINK_FLAGS}"
+ OUTPUT_NAME "unwind"
+ VERSION "1.0"
+ SOVERSION "1")
+ list(APPEND LIBUNWIND_TARGETS "unwind_shared")
+endif()
+
+# Build the static library.
+if (LIBUNWIND_ENABLE_STATIC)
+ add_library(unwind_static STATIC $<TARGET_OBJECTS:unwind_objects>)
+ target_link_libraries(unwind_static ${libraries})
+ set_target_properties(unwind_static
+ PROPERTIES
+ LINK_FLAGS "${LIBUNWIND_LINK_FLAGS}"
+ OUTPUT_NAME "unwind")
+ list(APPEND LIBUNWIND_TARGETS "unwind_static")
+endif()
+
+# Add a meta-target for both libraries.
+add_custom_target(unwind DEPENDS ${LIBUNWIND_TARGETS})
+if (LIBUNWIND_INSTALL_LIBRARY)
+ install(TARGETS ${LIBUNWIND_TARGETS}
+ LIBRARY DESTINATION ${LIBUNWIND_INSTALL_PREFIX}lib${LIBUNWIND_LIBDIR_SUFFIX} COMPONENT unwind
+ ARCHIVE DESTINATION ${LIBUNWIND_INSTALL_PREFIX}lib${LIBUNWIND_LIBDIR_SUFFIX} COMPONENT unwind)
+endif()
+
+if (NOT CMAKE_CONFIGURATION_TYPES AND LIBUNWIND_INSTALL_LIBRARY)
+ add_custom_target(install-unwind
+ DEPENDS unwind
+ COMMAND "${CMAKE_COMMAND}"
+ -DCMAKE_INSTALL_COMPONENT=unwind
+ -P "${LIBUNWIND_BINARY_DIR}/cmake_install.cmake")
+ add_custom_target(install-unwind-stripped
+ DEPENDS unwind
+ COMMAND "${CMAKE_COMMAND}"
+ -DCMAKE_INSTALL_COMPONENT=unwind
+ -DCMAKE_INSTALL_DO_STRIP=1
+ -P "${LIBUNWIND_BINARY_DIR}/cmake_install.cmake")
+endif()
#include <libunwind.h>
#include <mach-o/compact_unwind_encoding.h>
-#include "AddressSpace.hpp"
#include "Registers.hpp"
#define EXTRACT_BITS(value, mask) \
default:
(void)functionStart;
_LIBUNWIND_DEBUG_LOG("bad register for EBP frame, encoding=%08X for "
- "function starting at 0x%X\n",
+ "function starting at 0x%X",
compactEncoding, functionStart);
_LIBUNWIND_ABORT("invalid compact unwind encoding");
}
break;
default:
_LIBUNWIND_DEBUG_LOG("bad register for frameless, encoding=%08X for "
- "function starting at 0x%X\n",
+ "function starting at 0x%X",
encoding, functionStart);
_LIBUNWIND_ABORT("invalid compact unwind encoding");
}
default:
(void)functionStart;
_LIBUNWIND_DEBUG_LOG("bad register for RBP frame, encoding=%08X for "
- "function starting at 0x%llX\n",
+ "function starting at 0x%llX",
compactEncoding, functionStart);
_LIBUNWIND_ABORT("invalid compact unwind encoding");
}
break;
default:
_LIBUNWIND_DEBUG_LOG("bad register for frameless, encoding=%08X for "
- "function starting at 0x%llX\n",
+ "function starting at 0x%llX",
encoding, functionStart);
_LIBUNWIND_ABORT("invalid compact unwind encoding");
}
--- /dev/null
+//===----------------------------- Registers.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.
+//
+//
+// Abstract interface to shared reader/writer log, hiding platform and
+// configuration differences.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef __RWMUTEX_HPP__
+#define __RWMUTEX_HPP__
+
+#if defined(_WIN32)
+#include <windows.h>
+#elif !defined(_LIBUNWIND_HAS_NO_THREADS)
+#include <pthread.h>
+#endif
+
+namespace libunwind {
+
+#if defined(_LIBUNWIND_HAS_NO_THREADS)
+
+class _LIBUNWIND_HIDDEN RWMutex {
+public:
+ bool lock_shared() { return true; }
+ bool unlock_shared() { return true; }
+ bool lock() { return true; }
+ bool unlock() { return true; }
+};
+
+#elif defined(_WIN32)
+
+class _LIBUNWIND_HIDDEN RWMutex {
+public:
+ bool lock_shared() {
+ AcquireSRWLockShared(&_lock);
+ return true;
+ }
+ bool unlock_shared() {
+ ReleaseSRWLockShared(&_lock);
+ return true;
+ }
+ bool lock() {
+ AcquireSRWLockExclusive(&_lock);
+ return true;
+ }
+ bool unlock() {
+ ReleaseSRWLockExclusive(&_lock);
+ return true;
+ }
+
+private:
+ SRWLOCK _lock = SRWLOCK_INIT;
+};
+
+#else
+
+class _LIBUNWIND_HIDDEN RWMutex {
+public:
+ bool lock_shared() { return pthread_rwlock_rdlock(&_lock) == 0; }
+ bool unlock_shared() { return pthread_rwlock_unlock(&_lock) == 0; }
+ bool lock() { return pthread_rwlock_wrlock(&_lock) == 0; }
+ bool unlock() { return pthread_rwlock_unlock(&_lock) == 0; }
+
+private:
+ pthread_rwlock_t _lock = PTHREAD_RWLOCK_INITIALIZER;
+};
+
+#endif
+
+} // namespace libunwind
+
+#endif // __RWMUTEX_HPP__
#include "Unwind-EHABI.h"
-#if _LIBUNWIND_ARM_EHABI
+#if defined(_LIBUNWIND_ARM_EHABI)
+#include <inttypes.h>
#include <stdbool.h>
#include <stdint.h>
#include <stdio.h>
return data;
}
-_Unwind_Reason_Code _Unwind_VRS_Interpret(
- _Unwind_Context* context,
- const uint32_t* data,
- size_t offset,
- size_t len) {
+_LIBUNWIND_EXPORT _Unwind_Reason_Code
+_Unwind_VRS_Interpret(_Unwind_Context *context, const uint32_t *data,
+ size_t offset, size_t len) {
bool wrotePC = false;
bool finish = false;
while (offset < len && !finish) {
return _URC_CONTINUE_UNWIND;
}
-extern "C" _Unwind_Reason_Code __aeabi_unwind_cpp_pr0(
- _Unwind_State state,
- _Unwind_Control_Block *ucbp,
- _Unwind_Context *context) {
+extern "C" _LIBUNWIND_EXPORT _Unwind_Reason_Code
+__aeabi_unwind_cpp_pr0(_Unwind_State state, _Unwind_Control_Block *ucbp,
+ _Unwind_Context *context) {
return unwindOneFrame(state, ucbp, context);
}
-extern "C" _Unwind_Reason_Code __aeabi_unwind_cpp_pr1(
- _Unwind_State state,
- _Unwind_Control_Block *ucbp,
- _Unwind_Context *context) {
+extern "C" _LIBUNWIND_EXPORT _Unwind_Reason_Code
+__aeabi_unwind_cpp_pr1(_Unwind_State state, _Unwind_Control_Block *ucbp,
+ _Unwind_Context *context) {
return unwindOneFrame(state, ucbp, context);
}
-extern "C" _Unwind_Reason_Code __aeabi_unwind_cpp_pr2(
- _Unwind_State state,
- _Unwind_Control_Block *ucbp,
- _Unwind_Context *context) {
+extern "C" _LIBUNWIND_EXPORT _Unwind_Reason_Code
+__aeabi_unwind_cpp_pr2(_Unwind_State state, _Unwind_Control_Block *ucbp,
+ _Unwind_Context *context) {
return unwindOneFrame(state, ucbp, context);
}
unw_proc_info_t frameInfo;
if (unw_get_proc_info(cursor, &frameInfo) != UNW_ESUCCESS) {
_LIBUNWIND_TRACE_UNWINDING("unwind_phase1(ex_ojb=%p): unw_get_proc_info "
- "failed => _URC_FATAL_PHASE1_ERROR\n",
+ "failed => _URC_FATAL_PHASE1_ERROR",
static_cast<void *>(exception_object));
return _URC_FATAL_PHASE1_ERROR;
}
unw_word_t pc;
unw_get_reg(cursor, 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",
- static_cast<void *>(exception_object), (long long)pc,
- (long long)frameInfo.start_ip, functionName,
- (long long)frameInfo.lsda, (long long)frameInfo.handler);
+ "unwind_phase1(ex_ojb=%p): pc=0x%" PRIxPTR ", start_ip=0x%" PRIxPTR ", func=%s, "
+ "lsda=0x%" PRIxPTR ", personality=0x%" PRIxPTR,
+ static_cast<void *>(exception_object), pc,
+ frameInfo.start_ip, functionName,
+ frameInfo.lsda, frameInfo.handler);
}
// If there is a personality routine, ask it if it will want to stop at
__personality_routine p =
(__personality_routine)(long)(frameInfo.handler);
_LIBUNWIND_TRACE_UNWINDING(
- "unwind_phase1(ex_ojb=%p): calling personality function %p\n",
+ "unwind_phase1(ex_ojb=%p): calling personality function %p",
static_cast<void *>(exception_object),
reinterpret_cast<void *>(reinterpret_cast<uintptr_t>(p)));
struct _Unwind_Context *context = (struct _Unwind_Context *)(cursor);
(*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",
+ "additional %x",
static_cast<void *>(exception_object), personalityResult,
exception_object->pr_cache.fnstart,
static_cast<void *>(exception_object->pr_cache.ehtp),
handlerNotFound = false;
// p should have initialized barrier_cache. EHABI #7.3.5
_LIBUNWIND_TRACE_UNWINDING(
- "unwind_phase1(ex_ojb=%p): _URC_HANDLER_FOUND \n",
+ "unwind_phase1(ex_ojb=%p): _URC_HANDLER_FOUND",
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",
+ "unwind_phase1(ex_ojb=%p): _URC_CONTINUE_UNWIND",
static_cast<void *>(exception_object));
// continue unwinding
break;
default:
// something went wrong
_LIBUNWIND_TRACE_UNWINDING(
- "unwind_phase1(ex_ojb=%p): _URC_FATAL_PHASE1_ERROR\n",
+ "unwind_phase1(ex_ojb=%p): _URC_FATAL_PHASE1_ERROR",
static_cast<void *>(exception_object));
return _URC_FATAL_PHASE1_ERROR;
}
// See comment at the start of unwind_phase1 regarding VRS integrity.
unw_init_local(cursor, uc);
- _LIBUNWIND_TRACE_UNWINDING("unwind_phase2(ex_ojb=%p)\n",
+ _LIBUNWIND_TRACE_UNWINDING("unwind_phase2(ex_ojb=%p)",
static_cast<void *>(exception_object));
int frame_count = 0;
// Walk each frame until we reach where search phase said to stop.
while (true) {
- // Ask libuwind to get next frame (skip over first which is
+ // Ask libunwind to get next frame (skip over first which is
// _Unwind_RaiseException or _Unwind_Resume).
//
// Resume only ever makes sense for 1 frame.
unw_get_reg(cursor, UNW_REG_SP, &sp);
if (unw_get_proc_info(cursor, &frameInfo) != UNW_ESUCCESS) {
_LIBUNWIND_TRACE_UNWINDING("unwind_phase2(ex_ojb=%p): unw_get_proc_info "
- "failed => _URC_FATAL_PHASE1_ERROR\n",
+ "failed => _URC_FATAL_PHASE2_ERROR",
static_cast<void *>(exception_object));
return _URC_FATAL_PHASE2_ERROR;
}
(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",
- static_cast<void *>(exception_object), (long long)frameInfo.start_ip,
- functionName, (long long)sp, (long long)frameInfo.lsda,
- (long long)frameInfo.handler);
+ "unwind_phase2(ex_ojb=%p): start_ip=0x%" PRIxPTR ", func=%s, sp=0x%" PRIxPTR ", "
+ "lsda=0x%" PRIxPTR ", personality=0x%" PRIxPTR "",
+ static_cast<void *>(exception_object), frameInfo.start_ip,
+ functionName, sp, frameInfo.lsda,
+ frameInfo.handler);
}
// If there is a personality routine, tell it we are unwinding.
case _URC_CONTINUE_UNWIND:
// Continue unwinding
_LIBUNWIND_TRACE_UNWINDING(
- "unwind_phase2(ex_ojb=%p): _URC_CONTINUE_UNWIND\n",
+ "unwind_phase2(ex_ojb=%p): _URC_CONTINUE_UNWIND",
static_cast<void *>(exception_object));
// EHABI #7.2
if (sp == exception_object->barrier_cache.sp) {
break;
case _URC_INSTALL_CONTEXT:
_LIBUNWIND_TRACE_UNWINDING(
- "unwind_phase2(ex_ojb=%p): _URC_INSTALL_CONTEXT\n",
+ "unwind_phase2(ex_ojb=%p): _URC_INSTALL_CONTEXT",
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().
unw_get_reg(cursor, UNW_REG_IP, &pc);
unw_get_reg(cursor, UNW_REG_SP, &sp);
_LIBUNWIND_TRACE_UNWINDING("unwind_phase2(ex_ojb=%p): re-entering "
- "user code with ip=0x%llX, sp=0x%llX\n",
+ "user code with ip=0x%" PRIxPTR ", sp=0x%" PRIxPTR,
static_cast<void *>(exception_object),
- (long long)pc, (long long)sp);
+ pc, sp);
}
{
/// Called by __cxa_throw. Only returns if there is a fatal error.
_LIBUNWIND_EXPORT _Unwind_Reason_Code
_Unwind_RaiseException(_Unwind_Exception *exception_object) {
- _LIBUNWIND_TRACE_API("_Unwind_RaiseException(ex_obj=%p)\n",
+ _LIBUNWIND_TRACE_API("_Unwind_RaiseException(ex_obj=%p)",
static_cast<void *>(exception_object));
unw_context_t uc;
unw_cursor_t cursor;
/// 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",
+ _LIBUNWIND_TRACE_API("_Unwind_Resume(ex_obj=%p)",
static_cast<void *>(exception_object));
unw_context_t uc;
unw_cursor_t cursor;
if (unw_get_proc_info(cursor, &frameInfo) == UNW_ESUCCESS)
result = (uintptr_t)frameInfo.lsda;
_LIBUNWIND_TRACE_API(
- "_Unwind_GetLanguageSpecificData(context=%p) => 0x%llx\n",
+ "_Unwind_GetLanguageSpecificData(context=%p) => 0x%llx",
static_cast<void *>(context), (long long)result);
return result;
}
return value;
}
-_Unwind_VRS_Result
+_LIBUNWIND_EXPORT _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",
+ "rep=%d, value=0x%llX)",
static_cast<void *>(context), regclass, regno,
representation,
ValueAsBitPattern(representation, valuep));
*(unw_fpreg_t *)valuep) == UNW_ESUCCESS
? _UVRSR_OK
: _UVRSR_FAILED;
+#else
+ case _UVRSC_WMMXC:
+ case _UVRSC_WMMXD:
+ break;
#endif
}
_LIBUNWIND_ABORT("unsupported register class");
(unw_fpreg_t *)valuep) == UNW_ESUCCESS
? _UVRSR_OK
: _UVRSR_FAILED;
+#else
+ case _UVRSC_WMMXC:
+ case _UVRSC_WMMXD:
+ break;
#endif
}
_LIBUNWIND_ABORT("unsupported register class");
}
-_Unwind_VRS_Result _Unwind_VRS_Get(
- _Unwind_Context *context,
- _Unwind_VRS_RegClass regclass,
- uint32_t regno,
- _Unwind_VRS_DataRepresentation representation,
- void *valuep) {
+_LIBUNWIND_EXPORT _Unwind_VRS_Result
+_Unwind_VRS_Get(_Unwind_Context *context, _Unwind_VRS_RegClass regclass,
+ uint32_t regno, _Unwind_VRS_DataRepresentation representation,
+ void *valuep) {
_Unwind_VRS_Result result =
_Unwind_VRS_Get_Internal(context, regclass, regno, representation,
valuep);
_LIBUNWIND_TRACE_API("_Unwind_VRS_Get(context=%p, regclass=%d, reg=%d, "
- "rep=%d, value=0x%llX, result = %d)\n",
+ "rep=%d, value=0x%llX, result = %d)",
static_cast<void *>(context), regclass, regno,
representation,
ValueAsBitPattern(representation, valuep), result);
uint32_t discriminator,
_Unwind_VRS_DataRepresentation representation) {
_LIBUNWIND_TRACE_API("_Unwind_VRS_Pop(context=%p, regclass=%d, "
- "discriminator=%d, representation=%d)\n",
+ "discriminator=%d, representation=%d)",
static_cast<void *>(context), regclass, discriminator,
representation);
switch (regclass) {
- case _UVRSC_CORE:
- case _UVRSC_WMMXC: {
+ case _UVRSC_WMMXC:
+#if !defined(__ARM_WMMX)
+ break;
+#endif
+ case _UVRSC_CORE: {
if (representation != _UVRSD_UINT32)
return _UVRSR_FAILED;
// When popping SP from the stack, we don't want to override it from the
}
return _UVRSR_OK;
}
- case _UVRSC_VFP:
- case _UVRSC_WMMXD: {
+ case _UVRSC_WMMXD:
+#if !defined(__ARM_WMMX)
+ break;
+#endif
+ case _UVRSC_VFP: {
if (representation != _UVRSD_VFPX && representation != _UVRSD_DOUBLE)
return _UVRSR_FAILED;
uint32_t first = discriminator >> 16;
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%llX\n",
+ _LIBUNWIND_TRACE_API("_Unwind_GetRegionStart(context=%p) => 0x%llX",
static_cast<void *>(context), (long long)result);
return result;
}
// is caught.
_LIBUNWIND_EXPORT void
_Unwind_DeleteException(_Unwind_Exception *exception_object) {
- _LIBUNWIND_TRACE_API("_Unwind_DeleteException(ex_obj=%p)\n",
+ _LIBUNWIND_TRACE_API("_Unwind_DeleteException(ex_obj=%p)",
static_cast<void *>(exception_object));
if (exception_object->exception_cleanup != NULL)
(*exception_object->exception_cleanup)(_URC_FOREIGN_EXCEPTION_CAUGHT,
return _URC_OK;
}
-#endif // _LIBUNWIND_ARM_EHABI
+#endif // defined(_LIBUNWIND_ARM_EHABI)
#include <__libunwind_config.h>
-#if _LIBUNWIND_ARM_EHABI
+#if defined(_LIBUNWIND_ARM_EHABI)
#include <stdint.h>
#include <unwind.h>
} // extern "C"
#endif
-#endif // _LIBUNWIND_ARM_EHABI
+#endif // defined(_LIBUNWIND_ARM_EHABI)
#endif // __UNWIND_EHABI_H__
#include <stdlib.h>
#include "config.h"
-#include "unwind_ext.h"
-//
-// 32-bit iOS uses setjump/longjump based C++ exceptions.
-// Other architectures use "zero cost" exceptions.
-//
-// With SJLJ based exceptions, any function that has a catch clause or needs to
-// do any clean up when an exception propagates through it, needs to call
-// _Unwind_SjLj_Register() at the start of the function and
-// _Unwind_SjLj_Unregister() at the end. The register function is called with
-// the address of a block of memory in the function's stack frame. The runtime
-// keeps a linked list (stack) of these blocks - one per thread. The calling
-// function also sets the personality and lsda fields of the block.
-//
+/// With SJLJ based exceptions, any function that has a catch clause or needs to
+/// do any clean up when an exception propagates through it, needs to call
+/// \c _Unwind_SjLj_Register at the start of the function and
+/// \c _Unwind_SjLj_Unregister at the end. The register function is called with
+/// the address of a block of memory in the function's stack frame. The runtime
+/// keeps a linked list (stack) of these blocks - one per thread. The calling
+/// function also sets the personality and lsda fields of the block.
-#if _LIBUNWIND_BUILD_SJLJ_APIS
+#if defined(_LIBUNWIND_BUILD_SJLJ_APIS)
struct _Unwind_FunctionContext {
// next function in stack of handlers
struct _Unwind_FunctionContext *prev;
// set by calling function before registering to be the landing pad
- uintptr_t resumeLocation;
+ uint32_t resumeLocation;
// set by personality handler to be parameters passed to landing pad function
- uintptr_t resumeParameters[4];
+ uint32_t resumeParameters[4];
// set by calling function before registering
__personality_routine personality; // arm offset=24
void *jbuf[];
};
+#if defined(_LIBUNWIND_HAS_NO_THREADS)
+# define _LIBUNWIND_THREAD_LOCAL
+#else
+# if __STDC_VERSION__ >= 201112L
+# define _LIBUNWIND_THREAD_LOCAL _Thread_local
+# elif defined(_WIN32)
+# define _LIBUNWIND_THREAD_LOCAL __declspec(thread)
+# elif defined(__GNUC__) || defined(__clang__)
+# define _LIBUNWIND_THREAD_LOCAL __thread
+# else
+# error Unable to create thread local storage
+# endif
+#endif
+
+
+#if !defined(FOR_DYLD)
+
+#if defined(__APPLE__)
+#include <System/pthread_machdep.h>
+#else
+static _LIBUNWIND_THREAD_LOCAL struct _Unwind_FunctionContext *stack = NULL;
+#endif
+
+static struct _Unwind_FunctionContext *__Unwind_SjLj_GetTopOfFunctionStack() {
+#if defined(__APPLE__)
+ return _pthread_getspecific_direct(__PTK_LIBC_DYLD_Unwind_SjLj_Key);
+#else
+ return stack;
+#endif
+}
+
+static void
+__Unwind_SjLj_SetTopOfFunctionStack(struct _Unwind_FunctionContext *fc) {
+#if defined(__APPLE__)
+ _pthread_setspecific_direct(__PTK_LIBC_DYLD_Unwind_SjLj_Key, fc);
+#else
+ stack = fc;
+#endif
+}
+
+#endif
+
/// Called at start of each function that catches exceptions
_LIBUNWIND_EXPORT void
static _Unwind_Reason_Code
unwind_phase1(struct _Unwind_Exception *exception_object) {
_Unwind_FunctionContext_t c = __Unwind_SjLj_GetTopOfFunctionStack();
- _LIBUNWIND_TRACE_UNWINDING("unwind_phase1: initial function-context=%p\n", c);
+ _LIBUNWIND_TRACE_UNWINDING("unwind_phase1: initial function-context=%p", c);
// walk each frame looking for a place to stop
for (bool handlerNotFound = true; handlerNotFound; c = c->prev) {
// check for no more frames
if (c == NULL) {
_LIBUNWIND_TRACE_UNWINDING("unwind_phase1(ex_ojb=%p): reached "
- "bottom => _URC_END_OF_STACK\n",
+ "bottom => _URC_END_OF_STACK",
exception_object);
return _URC_END_OF_STACK;
}
- _LIBUNWIND_TRACE_UNWINDING("unwind_phase1: function-context=%p\n", c);
+ _LIBUNWIND_TRACE_UNWINDING("unwind_phase1: function-context=%p", c);
// if there is a personality routine, ask it if it will want to stop at this
// frame
if (c->personality != NULL) {
_LIBUNWIND_TRACE_UNWINDING("unwind_phase1(ex_ojb=%p): calling "
- "personality function %p\n",
+ "personality function %p",
exception_object, c->personality);
_Unwind_Reason_Code personalityResult = (*c->personality)(
1, _UA_SEARCH_PHASE, exception_object->exception_class,
handlerNotFound = false;
exception_object->private_2 = (uintptr_t) c;
_LIBUNWIND_TRACE_UNWINDING("unwind_phase1(ex_ojb=%p): "
- "_URC_HANDLER_FOUND\n", exception_object);
+ "_URC_HANDLER_FOUND", exception_object);
return _URC_NO_REASON;
case _URC_CONTINUE_UNWIND:
_LIBUNWIND_TRACE_UNWINDING("unwind_phase1(ex_ojb=%p): "
- "_URC_CONTINUE_UNWIND\n", exception_object);
+ "_URC_CONTINUE_UNWIND", exception_object);
// continue unwinding
break;
default:
// something went wrong
_LIBUNWIND_TRACE_UNWINDING(
- "unwind_phase1(ex_ojb=%p): _URC_FATAL_PHASE1_ERROR\n",
+ "unwind_phase1(ex_ojb=%p): _URC_FATAL_PHASE1_ERROR",
exception_object);
return _URC_FATAL_PHASE1_ERROR;
}
static _Unwind_Reason_Code
unwind_phase2(struct _Unwind_Exception *exception_object) {
- _LIBUNWIND_TRACE_UNWINDING("unwind_phase2(ex_ojb=%p)\n", exception_object);
+ _LIBUNWIND_TRACE_UNWINDING("unwind_phase2(ex_ojb=%p)", exception_object);
// walk each frame until we reach where search phase said to stop
_Unwind_FunctionContext_t c = __Unwind_SjLj_GetTopOfFunctionStack();
while (true) {
- _LIBUNWIND_TRACE_UNWINDING("unwind_phase2s(ex_ojb=%p): context=%p\n",
+ _LIBUNWIND_TRACE_UNWINDING("unwind_phase2s(ex_ojb=%p): context=%p",
exception_object, c);
// check for no more frames
if (c == NULL) {
_LIBUNWIND_TRACE_UNWINDING("unwind_phase2(ex_ojb=%p): unw_step() reached "
- "bottom => _URC_END_OF_STACK\n",
+ "bottom => _URC_END_OF_STACK",
exception_object);
return _URC_END_OF_STACK;
}
case _URC_CONTINUE_UNWIND:
// continue unwinding
_LIBUNWIND_TRACE_UNWINDING(
- "unwind_phase2(ex_ojb=%p): _URC_CONTINUE_UNWIND\n",
+ "unwind_phase2(ex_ojb=%p): _URC_CONTINUE_UNWIND",
exception_object);
if ((uintptr_t) c == exception_object->private_2) {
// phase 1 said we would stop at this frame, but we did not...
case _URC_INSTALL_CONTEXT:
_LIBUNWIND_TRACE_UNWINDING("unwind_phase2(ex_ojb=%p): "
"_URC_INSTALL_CONTEXT, will resume at "
- "landing pad %p\n",
+ "landing pad %p",
exception_object, c->jbuf[1]);
// personality routine says to transfer control to landing pad
// we may get control back if landing pad calls _Unwind_Resume()
// get next frame (skip over first which is _Unwind_RaiseException)
if (c == NULL) {
_LIBUNWIND_TRACE_UNWINDING("unwind_phase2(ex_ojb=%p): unw_step() reached "
- "bottom => _URC_END_OF_STACK\n",
+ "bottom => _URC_END_OF_STACK",
exception_object);
return _URC_END_OF_STACK;
}
(*stop)(1, action, exception_object->exception_class, exception_object,
(struct _Unwind_Context *)c, stop_parameter);
_LIBUNWIND_TRACE_UNWINDING("unwind_phase2_forced(ex_ojb=%p): "
- "stop function returned %d\n",
+ "stop function returned %d",
exception_object, stopResult);
if (stopResult != _URC_NO_REASON) {
_LIBUNWIND_TRACE_UNWINDING("unwind_phase2_forced(ex_ojb=%p): "
- "stopped by stop function\n",
+ "stopped by stop function",
exception_object);
return _URC_FATAL_PHASE2_ERROR;
}
if (c->personality != NULL) {
__personality_routine p = (__personality_routine) c->personality;
_LIBUNWIND_TRACE_UNWINDING("unwind_phase2_forced(ex_ojb=%p): "
- "calling personality function %p\n",
+ "calling personality function %p",
exception_object, p);
_Unwind_Reason_Code personalityResult =
(*p)(1, action, exception_object->exception_class, exception_object,
switch (personalityResult) {
case _URC_CONTINUE_UNWIND:
_LIBUNWIND_TRACE_UNWINDING("unwind_phase2_forced(ex_ojb=%p): "
- "personality returned _URC_CONTINUE_UNWIND\n",
+ "personality returned _URC_CONTINUE_UNWIND",
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",
+ "personality returned _URC_INSTALL_CONTEXT",
exception_object);
// we may get control back if landing pad calls _Unwind_Resume()
__Unwind_SjLj_SetTopOfFunctionStack(c);
// something went wrong
_LIBUNWIND_TRACE_UNWINDING("unwind_phase2_forced(ex_ojb=%p): "
"personality returned %d, "
- "_URC_FATAL_PHASE2_ERROR\n",
+ "_URC_FATAL_PHASE2_ERROR",
exception_object, personalityResult);
return _URC_FATAL_PHASE2_ERROR;
}
// 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",
+ "function with _UA_END_OF_STACK",
exception_object);
_Unwind_Action lastAction =
(_Unwind_Action)(_UA_FORCE_UNWIND | _UA_CLEANUP_PHASE | _UA_END_OF_STACK);
/// Called by __cxa_throw. Only returns if there is a fatal error
_LIBUNWIND_EXPORT _Unwind_Reason_Code
_Unwind_SjLj_RaiseException(struct _Unwind_Exception *exception_object) {
- _LIBUNWIND_TRACE_API("_Unwind_SjLj_RaiseException(ex_obj=%p)\n", exception_object);
+ _LIBUNWIND_TRACE_API("_Unwind_SjLj_RaiseException(ex_obj=%p)", exception_object);
// mark that this is a non-forced unwind, so _Unwind_Resume() can do the right
// thing
/// __cxa_rethrow() which in turn calls _Unwind_Resume_or_Rethrow()
_LIBUNWIND_EXPORT void
_Unwind_SjLj_Resume(struct _Unwind_Exception *exception_object) {
- _LIBUNWIND_TRACE_API("_Unwind_SjLj_Resume(ex_obj=%p)\n", exception_object);
+ _LIBUNWIND_TRACE_API("_Unwind_SjLj_Resume(ex_obj=%p)", exception_object);
if (exception_object->private_1 != 0)
unwind_phase2_forced(exception_object,
_LIBUNWIND_EXPORT _Unwind_Reason_Code
_Unwind_SjLj_Resume_or_Rethrow(struct _Unwind_Exception *exception_object) {
_LIBUNWIND_TRACE_API("__Unwind_SjLj_Resume_or_Rethrow(ex_obj=%p), "
- "private_1=%ld\n",
+ "private_1=%ld",
exception_object, exception_object->private_1);
// If this is non-forced and a stopping place was found, then this is a
// re-throw.
_Unwind_GetLanguageSpecificData(struct _Unwind_Context *context) {
_Unwind_FunctionContext_t ufc = (_Unwind_FunctionContext_t) context;
_LIBUNWIND_TRACE_API("_Unwind_GetLanguageSpecificData(context=%p) "
- "=> 0x%0lX\n", context, ufc->lsda);
+ "=> 0x%0lX", context, ufc->lsda);
return ufc->lsda;
}
/// Called by personality handler during phase 2 to get register values.
_LIBUNWIND_EXPORT uintptr_t _Unwind_GetGR(struct _Unwind_Context *context,
int index) {
- _LIBUNWIND_TRACE_API("_Unwind_GetGR(context=%p, reg=%d)\n",
+ _LIBUNWIND_TRACE_API("_Unwind_GetGR(context=%p, reg=%d)",
context, index);
_Unwind_FunctionContext_t ufc = (_Unwind_FunctionContext_t) context;
return ufc->resumeParameters[index];
/// 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%0lX)\n"
+ _LIBUNWIND_TRACE_API("_Unwind_SetGR(context=%p, reg=%d, value=0x%0lX)"
, context, index, new_value);
_Unwind_FunctionContext_t ufc = (_Unwind_FunctionContext_t) context;
ufc->resumeParameters[index] = new_value;
/// Called by personality handler during phase 2 to get instruction pointer.
_LIBUNWIND_EXPORT uintptr_t _Unwind_GetIP(struct _Unwind_Context *context) {
_Unwind_FunctionContext_t ufc = (_Unwind_FunctionContext_t) context;
- _LIBUNWIND_TRACE_API("_Unwind_GetIP(context=%p) => 0x%lX\n", context,
+ _LIBUNWIND_TRACE_API("_Unwind_GetIP(context=%p) => 0x%lX", context,
ufc->resumeLocation + 1);
return ufc->resumeLocation + 1;
}
int *ipBefore) {
_Unwind_FunctionContext_t ufc = (_Unwind_FunctionContext_t) context;
*ipBefore = 0;
- _LIBUNWIND_TRACE_API("_Unwind_GetIPInfo(context=%p, %p) => 0x%lX\n",
+ _LIBUNWIND_TRACE_API("_Unwind_GetIPInfo(context=%p, %p) => 0x%lX",
context, ipBefore, ufc->resumeLocation + 1);
return ufc->resumeLocation + 1;
}
/// Called by personality handler during phase 2 to alter instruction pointer.
_LIBUNWIND_EXPORT void _Unwind_SetIP(struct _Unwind_Context *context,
uintptr_t new_value) {
- _LIBUNWIND_TRACE_API("_Unwind_SetIP(context=%p, value=0x%0lX)\n",
+ _LIBUNWIND_TRACE_API("_Unwind_SetIP(context=%p, value=0x%0lX)",
context, new_value);
_Unwind_FunctionContext_t ufc = (_Unwind_FunctionContext_t) context;
ufc->resumeLocation = new_value - 1;
_Unwind_GetRegionStart(struct _Unwind_Context *context) {
// Not supported or needed for sjlj based unwinding
(void)context;
- _LIBUNWIND_TRACE_API("_Unwind_GetRegionStart(context=%p)\n", context);
+ _LIBUNWIND_TRACE_API("_Unwind_GetRegionStart(context=%p)", context);
return 0;
}
/// is caught.
_LIBUNWIND_EXPORT void
_Unwind_DeleteException(struct _Unwind_Exception *exception_object) {
- _LIBUNWIND_TRACE_API("_Unwind_DeleteException(ex_obj=%p)\n",
+ _LIBUNWIND_TRACE_API("_Unwind_DeleteException(ex_obj=%p)",
exception_object);
if (exception_object->exception_cleanup != NULL)
(*exception_object->exception_cleanup)(_URC_FOREIGN_EXCEPTION_CAUGHT,
_Unwind_GetDataRelBase(struct _Unwind_Context *context) {
// Not supported or needed for sjlj based unwinding
(void)context;
- _LIBUNWIND_TRACE_API("_Unwind_GetDataRelBase(context=%p)\n", context);
+ _LIBUNWIND_TRACE_API("_Unwind_GetDataRelBase(context=%p)", context);
_LIBUNWIND_ABORT("_Unwind_GetDataRelBase() not implemented");
}
_Unwind_GetTextRelBase(struct _Unwind_Context *context) {
// Not supported or needed for sjlj based unwinding
(void)context;
- _LIBUNWIND_TRACE_API("_Unwind_GetTextRelBase(context=%p)\n", context);
+ _LIBUNWIND_TRACE_API("_Unwind_GetTextRelBase(context=%p)", context);
_LIBUNWIND_ABORT("_Unwind_GetTextRelBase() not implemented");
}
/// Called by personality handler to get "Call Frame Area" for current frame.
_LIBUNWIND_EXPORT uintptr_t _Unwind_GetCFA(struct _Unwind_Context *context) {
- _LIBUNWIND_TRACE_API("_Unwind_GetCFA(context=%p)\n", context);
+ _LIBUNWIND_TRACE_API("_Unwind_GetCFA(context=%p)", context);
if (context != NULL) {
_Unwind_FunctionContext_t ufc = (_Unwind_FunctionContext_t) context;
// Setjmp/longjmp based exceptions don't have a true CFA.
return 0;
}
-#endif // _LIBUNWIND_BUILD_SJLJ_APIS
+#endif // defined(_LIBUNWIND_BUILD_SJLJ_APIS)
#include "Unwind-EHABI.h"
#include "unwind.h"
-#if _LIBUNWIND_BUILD_ZERO_COST_APIS
+#if defined(_LIBUNWIND_BUILD_ZERO_COST_APIS)
/// Called by __cxa_rethrow().
_LIBUNWIND_EXPORT _Unwind_Reason_Code
_Unwind_Resume_or_Rethrow(_Unwind_Exception *exception_object) {
-#if _LIBUNWIND_ARM_EHABI
- _LIBUNWIND_TRACE_API("_Unwind_Resume_or_Rethrow(ex_obj=%p), private_1=%ld\n",
+#if defined(_LIBUNWIND_ARM_EHABI)
+ _LIBUNWIND_TRACE_API("_Unwind_Resume_or_Rethrow(ex_obj=%p), private_1=%ld",
(void *)exception_object,
(long)exception_object->unwinder_cache.reserved1);
#else
- _LIBUNWIND_TRACE_API("_Unwind_Resume_or_Rethrow(ex_obj=%p), private_1=%ld\n",
+ _LIBUNWIND_TRACE_API("_Unwind_Resume_or_Rethrow(ex_obj=%p), private_1=%ld",
(void *)exception_object,
(long)exception_object->private_1);
#endif
-#if _LIBUNWIND_ARM_EHABI
+#if defined(_LIBUNWIND_ARM_EHABI)
// _Unwind_RaiseException on EHABI will always set the reserved1 field to 0,
// which is in the same position as private_1 below.
return _Unwind_RaiseException(exception_object);
_LIBUNWIND_EXPORT uintptr_t
_Unwind_GetDataRelBase(struct _Unwind_Context *context) {
(void)context;
- _LIBUNWIND_TRACE_API("_Unwind_GetDataRelBase(context=%p)\n", (void *)context);
+ _LIBUNWIND_TRACE_API("_Unwind_GetDataRelBase(context=%p)", (void *)context);
_LIBUNWIND_ABORT("_Unwind_GetDataRelBase() not implemented");
}
_LIBUNWIND_EXPORT uintptr_t
_Unwind_GetTextRelBase(struct _Unwind_Context *context) {
(void)context;
- _LIBUNWIND_TRACE_API("_Unwind_GetTextRelBase(context=%p)\n", (void *)context);
+ _LIBUNWIND_TRACE_API("_Unwind_GetTextRelBase(context=%p)", (void *)context);
_LIBUNWIND_ABORT("_Unwind_GetTextRelBase() not implemented");
}
/// Scans unwind information to find the function that contains the
/// specified code address "pc".
_LIBUNWIND_EXPORT void *_Unwind_FindEnclosingFunction(void *pc) {
- _LIBUNWIND_TRACE_API("_Unwind_FindEnclosingFunction(pc=%p)\n", pc);
+ _LIBUNWIND_TRACE_API("_Unwind_FindEnclosingFunction(pc=%p)", pc);
// This is slow, but works.
// We create an unwind cursor then alter the IP to be pc
unw_cursor_t cursor;
unw_getcontext(&uc);
unw_init_local(&cursor, &uc);
- _LIBUNWIND_TRACE_API("_Unwind_Backtrace(callback=%p)\n",
+ _LIBUNWIND_TRACE_API("_Unwind_Backtrace(callback=%p)",
(void *)(uintptr_t)callback);
-#if _LIBUNWIND_ARM_EHABI
+#if defined(_LIBUNWIND_ARM_EHABI)
// Create a mock exception object for force unwinding.
_Unwind_Exception ex;
memset(&ex, '\0', sizeof(ex));
while (true) {
_Unwind_Reason_Code result;
-#if !_LIBUNWIND_ARM_EHABI
- // ask libuwind to get next frame (skip over first frame which is
+#if !defined(_LIBUNWIND_ARM_EHABI)
+ // ask libunwind to get next frame (skip over first frame which is
// _Unwind_Backtrace())
if (unw_step(&cursor) <= 0) {
_LIBUNWIND_TRACE_UNWINDING(" _backtrace: ended because cursor reached "
- "bottom of stack, returning %d\n",
+ "bottom of stack, returning %d",
_URC_END_OF_STACK);
return _URC_END_OF_STACK;
}
_URC_CONTINUE_UNWIND) {
return _URC_END_OF_STACK;
}
-#endif // _LIBUNWIND_ARM_EHABI
+#endif // defined(_LIBUNWIND_ARM_EHABI)
// debugging
if (_LIBUNWIND_TRACING_UNWINDING) {
unw_get_proc_name(&cursor, functionName, 512, &offset);
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,
+ " _backtrace: start_ip=0x%" PRIxPTR ", func=%s, lsda=0x%" PRIxPTR ", context=%p",
+ frame.start_ip, functionName, frame.lsda,
(void *)&cursor);
}
result = (*callback)((struct _Unwind_Context *)(&cursor), ref);
if (result != _URC_NO_REASON) {
_LIBUNWIND_TRACE_UNWINDING(
- " _backtrace: ended because callback returned %d\n", result);
+ " _backtrace: ended because callback returned %d", result);
return result;
}
}
}
-/// Find dwarf unwind info for an address 'pc' in some function.
+/// Find DWARF unwind info for an address 'pc' in some function.
_LIBUNWIND_EXPORT const void *_Unwind_Find_FDE(const void *pc,
struct dwarf_eh_bases *bases) {
// This is slow, but works.
bases->tbase = (uintptr_t)info.extra;
bases->dbase = 0; // dbase not used on Mac OS X
bases->func = (uintptr_t)info.start_ip;
- _LIBUNWIND_TRACE_API("_Unwind_Find_FDE(pc=%p) => %p\n", pc,
+ _LIBUNWIND_TRACE_API("_Unwind_Find_FDE(pc=%p) => %p", pc,
(void *)(long) info.unwind_info);
return (void *)(long) info.unwind_info;
}
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",
- (void *)context, (uint64_t)result);
+ _LIBUNWIND_TRACE_API("_Unwind_GetCFA(context=%p) => 0x%" PRIxPTR,
+ (void *)context, result);
return (uintptr_t)result;
}
/// 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", (void *)context);
+ _LIBUNWIND_TRACE_API("_Unwind_GetIPInfo(context=%p)", (void *)context);
*ipBefore = 0;
return _Unwind_GetIP(context);
}
-#if _LIBUNWIND_SUPPORT_DWARF_UNWIND
+#if defined(_LIBUNWIND_SUPPORT_DWARF_UNWIND)
/// Called by programs with dynamic code generators that want
/// to register a dynamically generated FDE.
/// This function has existed on Mac OS X since 10.4, but
/// was broken until 10.6.
_LIBUNWIND_EXPORT void __register_frame(const void *fde) {
- _LIBUNWIND_TRACE_API("__register_frame(%p)\n", fde);
+ _LIBUNWIND_TRACE_API("__register_frame(%p)", fde);
_unw_add_dynamic_fde((unw_word_t)(uintptr_t) fde);
}
/// This function has existed on Mac OS X since 10.4, but
/// was broken until 10.6.
_LIBUNWIND_EXPORT void __deregister_frame(const void *fde) {
- _LIBUNWIND_TRACE_API("__deregister_frame(%p)\n", fde);
+ _LIBUNWIND_TRACE_API("__deregister_frame(%p)", fde);
_unw_remove_dynamic_fde((unw_word_t)(uintptr_t) fde);
}
// applications working. We also add the not in 10.6 symbol so that nwe
// application won't be able to use them.
-#if _LIBUNWIND_SUPPORT_FRAME_APIS
+#if defined(_LIBUNWIND_SUPPORT_FRAME_APIS)
_LIBUNWIND_EXPORT void __register_frame_info_bases(const void *fde, void *ob,
void *tb, void *db) {
(void)fde;
(void)ob;
(void)tb;
(void)db;
- _LIBUNWIND_TRACE_API("__register_frame_info_bases(%p,%p, %p, %p)\n",
+ _LIBUNWIND_TRACE_API("__register_frame_info_bases(%p,%p, %p, %p)",
fde, ob, tb, db);
// do nothing, this function never worked in Mac OS X
}
_LIBUNWIND_EXPORT void __register_frame_info(const void *fde, void *ob) {
(void)fde;
(void)ob;
- _LIBUNWIND_TRACE_API("__register_frame_info(%p, %p)\n", fde, ob);
+ _LIBUNWIND_TRACE_API("__register_frame_info(%p, %p)", fde, ob);
// do nothing, this function never worked in Mac OS X
}
(void)tb;
(void)db;
_LIBUNWIND_TRACE_API("__register_frame_info_table_bases"
- "(%p,%p, %p, %p)\n", fde, ob, tb, db);
+ "(%p,%p, %p, %p)", fde, ob, tb, db);
// do nothing, this function never worked in Mac OS X
}
_LIBUNWIND_EXPORT void __register_frame_info_table(const void *fde, void *ob) {
(void)fde;
(void)ob;
- _LIBUNWIND_TRACE_API("__register_frame_info_table(%p, %p)\n", fde, ob);
+ _LIBUNWIND_TRACE_API("__register_frame_info_table(%p, %p)", fde, ob);
// do nothing, this function never worked in Mac OS X
}
_LIBUNWIND_EXPORT void __register_frame_table(const void *fde) {
(void)fde;
- _LIBUNWIND_TRACE_API("__register_frame_table(%p)\n", fde);
+ _LIBUNWIND_TRACE_API("__register_frame_table(%p)", fde);
// do nothing, this function never worked in Mac OS X
}
_LIBUNWIND_EXPORT void *__deregister_frame_info(const void *fde) {
(void)fde;
- _LIBUNWIND_TRACE_API("__deregister_frame_info(%p)\n", fde);
+ _LIBUNWIND_TRACE_API("__deregister_frame_info(%p)", fde);
// do nothing, this function never worked in Mac OS X
return NULL;
}
_LIBUNWIND_EXPORT void *__deregister_frame_info_bases(const void *fde) {
(void)fde;
- _LIBUNWIND_TRACE_API("__deregister_frame_info_bases(%p)\n", fde);
+ _LIBUNWIND_TRACE_API("__deregister_frame_info_bases(%p)", fde);
// do nothing, this function never worked in Mac OS X
return NULL;
}
-#endif // _LIBUNWIND_SUPPORT_FRAME_APIS
+#endif // defined(_LIBUNWIND_SUPPORT_FRAME_APIS)
-#endif // _LIBUNWIND_SUPPORT_DWARF_UNWIND
+#endif // defined(_LIBUNWIND_SUPPORT_DWARF_UNWIND)
-#endif // _LIBUNWIND_BUILD_ZERO_COST_APIS
+#endif // defined(_LIBUNWIND_BUILD_ZERO_COST_APIS)
#include "unwind.h"
#include "config.h"
-#if !_LIBUNWIND_ARM_EHABI
+#if !defined(_LIBUNWIND_ARM_EHABI) && !defined(__USING_SJLJ_EXCEPTIONS__)
static _Unwind_Reason_Code
unwind_phase1(unw_context_t *uc, unw_cursor_t *cursor, _Unwind_Exception *exception_object) {
// Walk each frame looking for a place to stop.
bool handlerNotFound = true;
while (handlerNotFound) {
- // Ask libuwind to get next frame (skip over first which is
+ // Ask libunwind to get next frame (skip over first which is
// _Unwind_RaiseException).
int stepResult = unw_step(cursor);
if (stepResult == 0) {
_LIBUNWIND_TRACE_UNWINDING("unwind_phase1(ex_ojb=%p): unw_step() reached "
- "bottom => _URC_END_OF_STACK\n",
+ "bottom => _URC_END_OF_STACK",
(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",
+ "_URC_FATAL_PHASE1_ERROR",
(void *)exception_object);
return _URC_FATAL_PHASE1_ERROR;
}
unw_word_t sp;
if (unw_get_proc_info(cursor, &frameInfo) != UNW_ESUCCESS) {
_LIBUNWIND_TRACE_UNWINDING("unwind_phase1(ex_ojb=%p): unw_get_proc_info "
- "failed => _URC_FATAL_PHASE1_ERROR\n",
+ "failed => _URC_FATAL_PHASE1_ERROR",
(void *)exception_object);
return _URC_FATAL_PHASE1_ERROR;
}
unw_word_t pc;
unw_get_reg(cursor, 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",
+ "unwind_phase1(ex_ojb=%p): pc=0x%" PRIxPTR ", start_ip=0x%" PRIxPTR
+ ", func=%s, lsda=0x%" PRIxPTR ", personality=0x%" PRIxPTR "",
(void *)exception_object, pc, frameInfo.start_ip, functionName,
frameInfo.lsda, frameInfo.handler);
}
// this frame.
if (frameInfo.handler != 0) {
__personality_routine p =
- (__personality_routine)(long)(frameInfo.handler);
+ (__personality_routine)(uintptr_t)(frameInfo.handler);
_LIBUNWIND_TRACE_UNWINDING(
- "unwind_phase1(ex_ojb=%p): calling personality function %p\n",
+ "unwind_phase1(ex_ojb=%p): calling personality function %p",
(void *)exception_object, (void *)(uintptr_t)p);
_Unwind_Reason_Code personalityResult =
(*p)(1, _UA_SEARCH_PHASE, exception_object->exception_class,
unw_get_reg(cursor, UNW_REG_SP, &sp);
exception_object->private_2 = (uintptr_t)sp;
_LIBUNWIND_TRACE_UNWINDING(
- "unwind_phase1(ex_ojb=%p): _URC_HANDLER_FOUND \n",
+ "unwind_phase1(ex_ojb=%p): _URC_HANDLER_FOUND",
(void *)exception_object);
return _URC_NO_REASON;
case _URC_CONTINUE_UNWIND:
_LIBUNWIND_TRACE_UNWINDING(
- "unwind_phase1(ex_ojb=%p): _URC_CONTINUE_UNWIND\n",
+ "unwind_phase1(ex_ojb=%p): _URC_CONTINUE_UNWIND",
(void *)exception_object);
// continue unwinding
break;
default:
// something went wrong
_LIBUNWIND_TRACE_UNWINDING(
- "unwind_phase1(ex_ojb=%p): _URC_FATAL_PHASE1_ERROR\n",
+ "unwind_phase1(ex_ojb=%p): _URC_FATAL_PHASE1_ERROR",
(void *)exception_object);
return _URC_FATAL_PHASE1_ERROR;
}
unwind_phase2(unw_context_t *uc, unw_cursor_t *cursor, _Unwind_Exception *exception_object) {
unw_init_local(cursor, uc);
- _LIBUNWIND_TRACE_UNWINDING("unwind_phase2(ex_ojb=%p)\n",
+ _LIBUNWIND_TRACE_UNWINDING("unwind_phase2(ex_ojb=%p)",
(void *)exception_object);
// Walk each frame until we reach where search phase said to stop.
while (true) {
- // Ask libuwind to get next frame (skip over first which is
+ // Ask libunwind to get next frame (skip over first which is
// _Unwind_RaiseException).
int stepResult = unw_step(cursor);
if (stepResult == 0) {
_LIBUNWIND_TRACE_UNWINDING("unwind_phase2(ex_ojb=%p): unw_step() reached "
- "bottom => _URC_END_OF_STACK\n",
+ "bottom => _URC_END_OF_STACK",
(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",
+ "_URC_FATAL_PHASE1_ERROR",
(void *)exception_object);
return _URC_FATAL_PHASE2_ERROR;
}
unw_get_reg(cursor, UNW_REG_SP, &sp);
if (unw_get_proc_info(cursor, &frameInfo) != UNW_ESUCCESS) {
_LIBUNWIND_TRACE_UNWINDING("unwind_phase2(ex_ojb=%p): unw_get_proc_info "
- "failed => _URC_FATAL_PHASE1_ERROR\n",
+ "failed => _URC_FATAL_PHASE1_ERROR",
(void *)exception_object);
return _URC_FATAL_PHASE2_ERROR;
}
&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",
+ _LIBUNWIND_TRACE_UNWINDING("unwind_phase2(ex_ojb=%p): start_ip=0x%" PRIxPTR
+ ", func=%s, sp=0x%" PRIxPTR ", lsda=0x%" PRIxPTR
+ ", personality=0x%" PRIxPTR,
(void *)exception_object, frameInfo.start_ip,
functionName, sp, frameInfo.lsda,
frameInfo.handler);
// If there is a personality routine, tell it we are unwinding.
if (frameInfo.handler != 0) {
__personality_routine p =
- (__personality_routine)(long)(frameInfo.handler);
+ (__personality_routine)(uintptr_t)(frameInfo.handler);
_Unwind_Action action = _UA_CLEANUP_PHASE;
if (sp == exception_object->private_2) {
// Tell personality this was the frame it marked in phase 1.
case _URC_CONTINUE_UNWIND:
// Continue unwinding
_LIBUNWIND_TRACE_UNWINDING(
- "unwind_phase2(ex_ojb=%p): _URC_CONTINUE_UNWIND\n",
+ "unwind_phase2(ex_ojb=%p): _URC_CONTINUE_UNWIND",
(void *)exception_object);
if (sp == exception_object->private_2) {
// Phase 1 said we would stop at this frame, but we did not...
break;
case _URC_INSTALL_CONTEXT:
_LIBUNWIND_TRACE_UNWINDING(
- "unwind_phase2(ex_ojb=%p): _URC_INSTALL_CONTEXT\n",
+ "unwind_phase2(ex_ojb=%p): _URC_INSTALL_CONTEXT",
(void *)exception_object);
// Personality routine says to transfer control to landing pad.
// We may get control back if landing pad calls _Unwind_Resume().
unw_get_reg(cursor, UNW_REG_IP, &pc);
unw_get_reg(cursor, UNW_REG_SP, &sp);
_LIBUNWIND_TRACE_UNWINDING("unwind_phase2(ex_ojb=%p): re-entering "
- "user code with ip=0x%" PRIx64
- ", sp=0x%" PRIx64 "\n",
+ "user code with ip=0x%" PRIxPTR
+ ", sp=0x%" PRIxPTR,
(void *)exception_object, pc, sp);
}
unw_resume(cursor);
unw_proc_info_t frameInfo;
if (unw_get_proc_info(cursor, &frameInfo) != UNW_ESUCCESS) {
_LIBUNWIND_TRACE_UNWINDING("unwind_phase2_forced(ex_ojb=%p): unw_step "
- "failed => _URC_END_OF_STACK\n",
+ "failed => _URC_END_OF_STACK",
(void *)exception_object);
return _URC_FATAL_PHASE2_ERROR;
}
(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",
+ "unwind_phase2_forced(ex_ojb=%p): start_ip=0x%" PRIxPTR
+ ", func=%s, lsda=0x%" PRIxPTR ", personality=0x%" PRIxPTR,
(void *)exception_object, frameInfo.start_ip, functionName,
frameInfo.lsda, frameInfo.handler);
}
(*stop)(1, action, exception_object->exception_class, exception_object,
(struct _Unwind_Context *)(cursor), stop_parameter);
_LIBUNWIND_TRACE_UNWINDING(
- "unwind_phase2_forced(ex_ojb=%p): stop function returned %d\n",
+ "unwind_phase2_forced(ex_ojb=%p): stop function returned %d",
(void *)exception_object, stopResult);
if (stopResult != _URC_NO_REASON) {
_LIBUNWIND_TRACE_UNWINDING(
- "unwind_phase2_forced(ex_ojb=%p): stopped by stop function\n",
+ "unwind_phase2_forced(ex_ojb=%p): stopped by stop function",
(void *)exception_object);
return _URC_FATAL_PHASE2_ERROR;
}
__personality_routine p =
(__personality_routine)(long)(frameInfo.handler);
_LIBUNWIND_TRACE_UNWINDING(
- "unwind_phase2_forced(ex_ojb=%p): calling personality function %p\n",
+ "unwind_phase2_forced(ex_ojb=%p): calling personality function %p",
(void *)exception_object, (void *)(uintptr_t)p);
_Unwind_Reason_Code personalityResult =
(*p)(1, action, exception_object->exception_class, exception_object,
case _URC_CONTINUE_UNWIND:
_LIBUNWIND_TRACE_UNWINDING("unwind_phase2_forced(ex_ojb=%p): "
"personality returned "
- "_URC_CONTINUE_UNWIND\n",
+ "_URC_CONTINUE_UNWIND",
(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",
+ "_URC_INSTALL_CONTEXT",
(void *)exception_object);
// We may get control back if landing pad calls _Unwind_Resume().
unw_resume(cursor);
// Personality routine returned an unknown result code.
_LIBUNWIND_TRACE_UNWINDING("unwind_phase2_forced(ex_ojb=%p): "
"personality returned %d, "
- "_URC_FATAL_PHASE2_ERROR\n",
+ "_URC_FATAL_PHASE2_ERROR",
(void *)exception_object, personalityResult);
return _URC_FATAL_PHASE2_ERROR;
}
// 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",
+ "function with _UA_END_OF_STACK",
(void *)exception_object);
_Unwind_Action lastAction =
(_Unwind_Action)(_UA_FORCE_UNWIND | _UA_CLEANUP_PHASE | _UA_END_OF_STACK);
/// Called by __cxa_throw. Only returns if there is a fatal error.
_LIBUNWIND_EXPORT _Unwind_Reason_Code
_Unwind_RaiseException(_Unwind_Exception *exception_object) {
- _LIBUNWIND_TRACE_API("_Unwind_RaiseException(ex_obj=%p)\n",
+ _LIBUNWIND_TRACE_API("_Unwind_RaiseException(ex_obj=%p)",
(void *)exception_object);
unw_context_t uc;
unw_cursor_t cursor;
/// 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", (void *)exception_object);
+ _LIBUNWIND_TRACE_API("_Unwind_Resume(ex_obj=%p)", (void *)exception_object);
unw_context_t uc;
unw_cursor_t cursor;
unw_getcontext(&uc);
_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",
+ _LIBUNWIND_TRACE_API("_Unwind_ForcedUnwind(ex_obj=%p, stop=%p)",
(void *)exception_object, (void *)(uintptr_t)stop);
unw_context_t uc;
unw_cursor_t cursor;
if (unw_get_proc_info(cursor, &frameInfo) == UNW_ESUCCESS)
result = (uintptr_t)frameInfo.lsda;
_LIBUNWIND_TRACE_API(
- "_Unwind_GetLanguageSpecificData(context=%p) => 0x%" PRIxPTR "\n",
+ "_Unwind_GetLanguageSpecificData(context=%p) => 0x%" PRIxPTR,
(void *)context, result);
if (result != 0) {
if (*((uint8_t *)result) != 0xFF)
- _LIBUNWIND_DEBUG_LOG("lsda at 0x%" PRIxPTR " does not start with 0xFF\n",
+ _LIBUNWIND_DEBUG_LOG("lsda at 0x%" PRIxPTR " does not start with 0xFF",
result);
}
return result;
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",
+ _LIBUNWIND_TRACE_API("_Unwind_GetRegionStart(context=%p) => 0x%" PRIxPTR,
(void *)context, result);
return result;
}
// is caught.
_LIBUNWIND_EXPORT void
_Unwind_DeleteException(_Unwind_Exception *exception_object) {
- _LIBUNWIND_TRACE_API("_Unwind_DeleteException(ex_obj=%p)\n",
+ _LIBUNWIND_TRACE_API("_Unwind_DeleteException(ex_obj=%p)",
(void *)exception_object);
if (exception_object->exception_cleanup != NULL)
(*exception_object->exception_cleanup)(_URC_FOREIGN_EXCEPTION_CAUGHT,
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",
- (void *)context, index, (uint64_t)result);
+ _LIBUNWIND_TRACE_API("_Unwind_GetGR(context=%p, reg=%d) => 0x%" PRIxPTR,
+ (void *)context, index, 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 value) {
- _LIBUNWIND_TRACE_API("_Unwind_SetGR(context=%p, reg=%d, value=0x%0" PRIx64
- ")\n",
- (void *)context, index, (uint64_t)value);
+ _LIBUNWIND_TRACE_API("_Unwind_SetGR(context=%p, reg=%d, value=0x%0" PRIxPTR
+ ")",
+ (void *)context, index, value);
unw_cursor_t *cursor = (unw_cursor_t *)context;
unw_set_reg(cursor, index, value);
}
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",
- (void *)context, (uint64_t)result);
+ _LIBUNWIND_TRACE_API("_Unwind_GetIP(context=%p) => 0x%" PRIxPTR,
+ (void *)context, result);
return (uintptr_t)result;
}
/// start executing in the landing pad.
_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);
+ _LIBUNWIND_TRACE_API("_Unwind_SetIP(context=%p, value=0x%0" PRIxPTR ")",
+ (void *)context, value);
unw_cursor_t *cursor = (unw_cursor_t *)context;
unw_set_reg(cursor, UNW_REG_IP, value);
}
-#endif // !_LIBUNWIND_ARM_EHABI
+#endif // !defined(_LIBUNWIND_ARM_EHABI) && !defined(__USING_SJLJ_EXCEPTIONS__)
//===----------------------------------------------------------------------===//
#include "config.h"
+#include "AddressSpace.hpp"
#include "DwarfParser.hpp"
-#include "unwind_ext.h"
// private keymgr stuff
#endif
-#if _LIBUNWIND_BUILD_ZERO_COST_APIS
+#if defined(_LIBUNWIND_BUILD_ZERO_COST_APIS)
//
// symbols in libSystem.dylib in 10.6 and later, but are in libgcc_s.dylib in
NEVER_HERE(__deregister_frame_info)
NEVER_HERE(__deregister_frame_info_bases)
-#endif // _LIBUNWIND_BUILD_ZERO_COST_APIS
+#endif // defined(_LIBUNWIND_BUILD_ZERO_COST_APIS)
-#if _LIBUNWIND_BUILD_SJLJ_APIS
+#if defined(_LIBUNWIND_BUILD_SJLJ_APIS)
//
// symbols in libSystem.dylib in iOS 5.0 and later, but are in libgcc_s.dylib in
// earlier versions
NOT_HERE_BEFORE_5_0(_Unwind_SjLj_Resume_or_Rethrow)
NOT_HERE_BEFORE_5_0(_Unwind_SjLj_Unregister)
-#endif // _LIBUNWIND_BUILD_SJLJ_APIS
+#endif // defined(_LIBUNWIND_BUILD_SJLJ_APIS)
namespace libunwind {
}
-
-#if !defined(FOR_DYLD) && _LIBUNWIND_BUILD_SJLJ_APIS
-
-#include <System/pthread_machdep.h>
-
-// Accessors to get get/set linked list of frames for sjlj based execeptions.
-_LIBUNWIND_HIDDEN
-struct _Unwind_FunctionContext *__Unwind_SjLj_GetTopOfFunctionStack() {
- return (struct _Unwind_FunctionContext *)
- _pthread_getspecific_direct(__PTK_LIBC_DYLD_Unwind_SjLj_Key);
-}
-
-_LIBUNWIND_HIDDEN
-void __Unwind_SjLj_SetTopOfFunctionStack(struct _Unwind_FunctionContext *fc) {
- _pthread_setspecific_direct(__PTK_LIBC_DYLD_Unwind_SjLj_Key, fc);
-}
-#endif
-
-
-
-
#ifndef UNWIND_ASSEMBLY_H
#define UNWIND_ASSEMBLY_H
-#if defined(__POWERPC__) || defined(__powerpc__) || defined(__ppc__)
+#if defined(__powerpc64__)
+#define SEPARATOR ;
+#elif defined(__POWERPC__) || defined(__powerpc__) || defined(__ppc__)
#define SEPARATOR @
#elif defined(__arm64__)
#define SEPARATOR %%
#define SEPARATOR ;
#endif
-#if defined(__APPLE__)
-#define HIDDEN_DIRECTIVE .private_extern
-#else
-#define HIDDEN_DIRECTIVE .hidden
-#endif
-
#define GLUE2(a, b) a ## b
#define GLUE(a, b) GLUE2(a, b)
#define SYMBOL_NAME(name) GLUE(__USER_LABEL_PREFIX__, name)
#if defined(__APPLE__)
#define SYMBOL_IS_FUNC(name)
+#define HIDDEN_SYMBOL(name) .private_extern name
#define NO_EXEC_STACK_DIRECTIVE
#elif defined(__ELF__)
#else
#define SYMBOL_IS_FUNC(name) .type name,@function
#endif
+#define HIDDEN_SYMBOL(name) .hidden name
-#if defined(__GNU__) || defined(__ANDROID__) || defined(__FreeBSD__)
+#if defined(__GNU__) || defined(__FreeBSD__) || defined(__Fuchsia__) || \
+ defined(__linux__)
#define NO_EXEC_STACK_DIRECTIVE .section .note.GNU-stack,"",%progbits
#else
#define NO_EXEC_STACK_DIRECTIVE
#endif
-#else
+#elif defined(_WIN32)
#define SYMBOL_IS_FUNC(name) \
.def name SEPARATOR \
.scl 2 SEPARATOR \
.type 32 SEPARATOR \
.endef
+#define HIDDEN_SYMBOL(name)
#define NO_EXEC_STACK_DIRECTIVE
+#else
+
+#error Unsupported target
+
#endif
#define DEFINE_LIBUNWIND_FUNCTION(name) \
#define DEFINE_LIBUNWIND_PRIVATE_FUNCTION(name) \
.globl SYMBOL_NAME(name) SEPARATOR \
- HIDDEN_DIRECTIVE SYMBOL_NAME(name) SEPARATOR \
+ HIDDEN_SYMBOL(SYMBOL_NAME(name)) SEPARATOR \
SYMBOL_IS_FUNC(SYMBOL_NAME(name)) SEPARATOR \
SYMBOL_NAME(name):
// Source Licenses. See LICENSE.TXT for details.
//
//
-// Defines macros used within libuwind project.
+// Defines macros used within libunwind project.
//
//===----------------------------------------------------------------------===//
#include <assert.h>
#include <stdio.h>
+#include <stdint.h>
#include <stdlib.h>
// Define static_assert() unless already defined by compiler.
// Platform specific configuration defines.
#ifdef __APPLE__
#if defined(FOR_DYLD)
- #define _LIBUNWIND_SUPPORT_COMPACT_UNWIND 1
- #define _LIBUNWIND_SUPPORT_DWARF_UNWIND 0
- #define _LIBUNWIND_SUPPORT_DWARF_INDEX 0
+ #define _LIBUNWIND_SUPPORT_COMPACT_UNWIND
#else
- #define _LIBUNWIND_SUPPORT_COMPACT_UNWIND 1
+ #define _LIBUNWIND_SUPPORT_COMPACT_UNWIND
#define _LIBUNWIND_SUPPORT_DWARF_UNWIND 1
- #define _LIBUNWIND_SUPPORT_DWARF_INDEX 0
#endif
+#elif defined(_WIN32)
+ #define _LIBUNWIND_SUPPORT_DWARF_UNWIND 1
#else
#if defined(__ARM_DWARF_EH__) || !defined(__arm__)
- #define _LIBUNWIND_SUPPORT_COMPACT_UNWIND 0
#define _LIBUNWIND_SUPPORT_DWARF_UNWIND 1
#define _LIBUNWIND_SUPPORT_DWARF_INDEX 1
- #else
- #define _LIBUNWIND_SUPPORT_COMPACT_UNWIND 0
- #define _LIBUNWIND_SUPPORT_DWARF_UNWIND 0
- #define _LIBUNWIND_SUPPORT_DWARF_INDEX 0
#endif
#endif
-// FIXME: these macros are not correct for COFF targets
-#define _LIBUNWIND_EXPORT __attribute__((visibility("default")))
-#define _LIBUNWIND_HIDDEN __attribute__((visibility("hidden")))
+#if defined(_LIBUNWIND_DISABLE_VISIBILITY_ANNOTATIONS)
+ #define _LIBUNWIND_EXPORT
+ #define _LIBUNWIND_HIDDEN
+#else
+ #if !defined(__ELF__) && !defined(__MACH__)
+ #define _LIBUNWIND_EXPORT __declspec(dllexport)
+ #define _LIBUNWIND_HIDDEN
+ #else
+ #define _LIBUNWIND_EXPORT __attribute__((visibility("default")))
+ #define _LIBUNWIND_HIDDEN __attribute__((visibility("hidden")))
+ #endif
+#endif
#if (defined(__APPLE__) && defined(__arm__)) || defined(__USING_SJLJ_EXCEPTIONS__)
-#define _LIBUNWIND_BUILD_SJLJ_APIS 1
-#else
-#define _LIBUNWIND_BUILD_SJLJ_APIS 0
+#define _LIBUNWIND_BUILD_SJLJ_APIS
#endif
-#if defined(__i386__) || defined(__x86_64__)
-#define _LIBUNWIND_SUPPORT_FRAME_APIS 1
-#else
-#define _LIBUNWIND_SUPPORT_FRAME_APIS 0
+#if defined(__i386__) || defined(__x86_64__) || defined(__ppc__) || defined(__ppc64__) || defined(__powerpc64__)
+#define _LIBUNWIND_SUPPORT_FRAME_APIS
#endif
#if defined(__i386__) || defined(__x86_64__) || \
+ defined(__ppc__) || defined(__ppc64__) || defined(__powerpc64__) || \
(!defined(__APPLE__) && defined(__arm__)) || \
(defined(__arm64__) || defined(__aarch64__)) || \
- (defined(__APPLE__) && defined(__mips__))
-#define _LIBUNWIND_BUILD_ZERO_COST_APIS 1
-#else
-#define _LIBUNWIND_BUILD_ZERO_COST_APIS 0
+ defined(__mips__)
+#define _LIBUNWIND_BUILD_ZERO_COST_APIS
#endif
+#if defined(NDEBUG) && defined(_LIBUNWIND_IS_BAREMETAL)
+#define _LIBUNWIND_ABORT(msg) \
+ do { \
+ abort(); \
+ } while (0)
+#else
#define _LIBUNWIND_ABORT(msg) \
do { \
fprintf(stderr, "libunwind: %s %s:%d - %s\n", __func__, __FILE__, \
fflush(stderr); \
abort(); \
} while (0)
-#define _LIBUNWIND_LOG(msg, ...) fprintf(stderr, "libuwind: " msg, __VA_ARGS__)
+#endif
+
+#if defined(NDEBUG) && defined(_LIBUNWIND_IS_BAREMETAL)
+#define _LIBUNWIND_LOG0(msg)
+#define _LIBUNWIND_LOG(msg, ...)
+#else
+#define _LIBUNWIND_LOG0(msg) \
+ fprintf(stderr, "libunwind: " msg "\n")
+#define _LIBUNWIND_LOG(msg, ...) \
+ fprintf(stderr, "libunwind: " msg "\n", __VA_ARGS__)
+#endif
+
+#if defined(NDEBUG)
+ #define _LIBUNWIND_LOG_IF_FALSE(x) x
+#else
+ #define _LIBUNWIND_LOG_IF_FALSE(x) \
+ do { \
+ bool _ret = x; \
+ if (!_ret) \
+ _LIBUNWIND_LOG("" #x " failed in %s", __FUNCTION__); \
+ } while (0)
+#endif
// Macros that define away in non-Debug builds
#ifdef NDEBUG
#define _LIBUNWIND_DEBUG_LOG(msg, ...)
#define _LIBUNWIND_TRACE_API(msg, ...)
- #define _LIBUNWIND_TRACING_UNWINDING 0
+ #define _LIBUNWIND_TRACING_UNWINDING (0)
+ #define _LIBUNWIND_TRACING_DWARF (0)
#define _LIBUNWIND_TRACE_UNWINDING(msg, ...)
- #define _LIBUNWIND_LOG_NON_ZERO(x) x
+ #define _LIBUNWIND_TRACE_DWARF(...)
#else
#ifdef __cplusplus
extern "C" {
#endif
extern bool logAPIs();
extern bool logUnwinding();
+ extern bool logDWARF();
#ifdef __cplusplus
}
#endif
#define _LIBUNWIND_DEBUG_LOG(msg, ...) _LIBUNWIND_LOG(msg, __VA_ARGS__)
- #define _LIBUNWIND_LOG_NON_ZERO(x) \
- do { \
- int _err = x; \
- if ( _err != 0 ) \
- _LIBUNWIND_LOG("" #x "=%d in %s", _err, __FUNCTION__); \
- } while (0)
- #define _LIBUNWIND_TRACE_API(msg, ...) \
- do { \
- if ( logAPIs() ) _LIBUNWIND_LOG(msg, __VA_ARGS__); \
- } while(0)
- #define _LIBUNWIND_TRACE_UNWINDING(msg, ...) \
- do { \
- if ( logUnwinding() ) _LIBUNWIND_LOG(msg, __VA_ARGS__); \
- } while(0)
+ #define _LIBUNWIND_TRACE_API(msg, ...) \
+ do { \
+ if (logAPIs()) \
+ _LIBUNWIND_LOG(msg, __VA_ARGS__); \
+ } while (0)
#define _LIBUNWIND_TRACING_UNWINDING logUnwinding()
+ #define _LIBUNWIND_TRACING_DWARF logDWARF()
+ #define _LIBUNWIND_TRACE_UNWINDING(msg, ...) \
+ do { \
+ if (logUnwinding()) \
+ _LIBUNWIND_LOG(msg, __VA_ARGS__); \
+ } while (0)
+ #define _LIBUNWIND_TRACE_DWARF(...) \
+ do { \
+ if (logDWARF()) \
+ fprintf(stderr, __VA_ARGS__); \
+ } while (0)
#endif
#ifdef __cplusplus
#if defined(_LIBUNWIND_IS_NATIVE_ONLY)
# define COMP_OP ==
#else
-# define COMP_OP <
+# define COMP_OP <=
#endif
template <typename _Type, typename _Mem>
struct check_fit {
extern void _unw_add_dynamic_fde(unw_word_t fde);
extern void _unw_remove_dynamic_fde(unw_word_t fde);
-#if _LIBUNWIND_ARM_EHABI
+#if defined(_LIBUNWIND_ARM_EHABI)
extern const uint32_t* decode_eht_entry(const uint32_t*, size_t*, size_t*);
extern _Unwind_Reason_Code _Unwind_VRS_Interpret(_Unwind_Context *context,
const uint32_t *data,