diff options
Diffstat (limited to 'chromium/buildtools')
87 files changed, 4 insertions, 28863 deletions
diff --git a/chromium/buildtools/android/doclava.tar.gz.sha1 b/chromium/buildtools/android/doclava.tar.gz.sha1 index bb86b788760..10ef37ea631 100644 --- a/chromium/buildtools/android/doclava.tar.gz.sha1 +++ b/chromium/buildtools/android/doclava.tar.gz.sha1 @@ -1 +1 @@ -86b0c87e7e73c923f6d3373fe7547f1770dd4758 +1931becb8a8e21685f39c62854e9e814d64ccf1a diff --git a/chromium/buildtools/linux64/gn.sha1 b/chromium/buildtools/linux64/gn.sha1 index 87d556346da..6940efd997b 100644 --- a/chromium/buildtools/linux64/gn.sha1 +++ b/chromium/buildtools/linux64/gn.sha1 @@ -1 +1 @@ -113f5b30a7cfae72015600a119590d45d64c0d0d +4e5f9299c4ae4d80dcd87b4ade0bbada23ccf866 diff --git a/chromium/buildtools/mac/gn.sha1 b/chromium/buildtools/mac/gn.sha1 index c7d13b67ab4..0001616dc06 100644 --- a/chromium/buildtools/mac/gn.sha1 +++ b/chromium/buildtools/mac/gn.sha1 @@ -1 +1 @@ -b33a6d33c2b2f42762f902672ffdf4837fa1c662 +fbba40a0900ae685f5822d03d160a413d549e056 diff --git a/chromium/buildtools/third_party/libc++abi/trunk/.arcconfig b/chromium/buildtools/third_party/libc++abi/trunk/.arcconfig deleted file mode 100644 index 0c5cf4e87ba..00000000000 --- a/chromium/buildtools/third_party/libc++abi/trunk/.arcconfig +++ /dev/null @@ -1,4 +0,0 @@ -{ - "project_id" : "libcxxabi", - "conduit_uri" : "https://reviews.llvm.org/" -} diff --git a/chromium/buildtools/third_party/libc++abi/trunk/.clang-format b/chromium/buildtools/third_party/libc++abi/trunk/.clang-format deleted file mode 100644 index 2d1d3bee68f..00000000000 --- a/chromium/buildtools/third_party/libc++abi/trunk/.clang-format +++ /dev/null @@ -1,12 +0,0 @@ -BasedOnStyle: LLVM - ---- -Language: Cpp - -AlwaysBreakTemplateDeclarations: true -PointerAlignment: Left - -# Disable formatting options which may break tests. -SortIncludes: false -ReflowComments: false ---- diff --git a/chromium/buildtools/third_party/libc++abi/trunk/CMakeLists.txt b/chromium/buildtools/third_party/libc++abi/trunk/CMakeLists.txt deleted file mode 100644 index 456250e6d89..00000000000 --- a/chromium/buildtools/third_party/libc++abi/trunk/CMakeLists.txt +++ /dev/null @@ -1,456 +0,0 @@ -# See www/CMake.html for instructions on how to build libcxxabi with CMake. - -#=============================================================================== -# Setup Project -#=============================================================================== - -cmake_minimum_required(VERSION 3.4.3) - -if(POLICY CMP0042) - 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(libcxxabi CXX C) - - set(PACKAGE_NAME libcxxabi) - set(PACKAGE_VERSION 6.0.0svn) - set(PACKAGE_STRING "${PACKAGE_NAME} ${PACKAGE_VERSION}") - set(PACKAGE_BUGREPORT "llvm-bugs@lists.llvm.org") - - # Find the LLVM sources and simulate LLVM CMake options. - include(HandleOutOfTreeLLVM) -endif() - -# Require out of source build. -include(MacroEnsureOutOfSourceBuild) -MACRO_ENSURE_OUT_OF_SOURCE_BUILD( - "${PROJECT_NAME} requires an out of source build. Please create a separate - build directory and run 'cmake /path/to/${PROJECT_NAME} [options]' there." - ) - -#=============================================================================== -# Setup CMake Options -#=============================================================================== -include(CMakeDependentOption) -include(HandleCompilerRT) - -# Define options. -option(LIBCXXABI_ENABLE_EXCEPTIONS "Use exceptions." ON) -option(LIBCXXABI_ENABLE_ASSERTIONS "Enable assertions independent of build mode." ON) -option(LIBCXXABI_ENABLE_PEDANTIC "Compile with pedantic enabled." ON) -option(LIBCXXABI_ENABLE_WERROR "Fail and stop if a warning is triggered." OFF) -option(LIBCXXABI_USE_LLVM_UNWINDER "Build and use the LLVM unwinder." OFF) -option(LIBCXXABI_ENABLE_STATIC_UNWINDER "Statically link the LLVM unwinder." OFF) -option(LIBCXXABI_USE_COMPILER_RT "Use compiler-rt instead of libgcc" OFF) -option(LIBCXXABI_ENABLE_THREADS "Build with threads enabled" ON) -option(LIBCXXABI_HAS_PTHREAD_API "Ignore auto-detection and force use of pthread API" OFF) -option(LIBCXXABI_HAS_EXTERNAL_THREAD_API - "Build libc++abi with an externalized threading API. - This option may only be set to ON when LIBCXXABI_ENABLE_THREADS=ON." OFF) -option(LIBCXXABI_BUILD_EXTERNAL_THREAD_LIBRARY - "Build libc++abi with an externalized threading library. - This option may only be set to ON when LIBCXXABI_ENABLE_THREADS=ON" OFF) - -# FIXME: This option should default to off. Unfortunatly GCC 4.9 fails to link -# programs to due undefined references to new/delete in libc++abi. Once this -# has been fixed or worked around the default value should be changed. -option(LIBCXXABI_ENABLE_NEW_DELETE_DEFINITIONS - "Build libc++abi with definitions for operator new/delete. Normally libc++ - provides these definitions" ON) -option(LIBCXXABI_BUILD_32_BITS "Build 32 bit libc++abi." ${LLVM_BUILD_32_BITS}) -option(LIBCXXABI_INCLUDE_TESTS "Generate build targets for the libc++abi unit tests." ${LLVM_INCLUDE_TESTS}) -set(LIBCXXABI_LIBDIR_SUFFIX "${LLVM_LIBDIR_SUFFIX}" CACHE STRING - "Define suffix of library directory name (32/64)") -set(LIBCXXABI_TARGET_TRIPLE "" CACHE STRING "Target triple for cross compiling.") -set(LIBCXXABI_GCC_TOOLCHAIN "" CACHE PATH "GCC toolchain for cross compiling.") -set(LIBCXXABI_SYSROOT "" CACHE PATH "Sysroot for cross compiling.") -set(LIBCXXABI_LIBCXX_LIBRARY_PATH "" CACHE PATH "The path to libc++ library.") - -# Default to building a shared library so that the default options still test -# the libc++abi that is being built. There are two problems with testing a -# static libc++abi. In the case of a standalone build, the tests will link the -# system's libc++, which might not have been built against our libc++abi. In the -# case of an in tree build, libc++ will prefer a dynamic libc++abi from the -# system over a static libc++abi from the output directory. -option(LIBCXXABI_ENABLE_SHARED "Build libc++abi as a shared library." ON) -option(LIBCXXABI_ENABLE_STATIC "Build libc++abi as a static library." ON) - -option(LIBCXXABI_BAREMETAL "Build libc++abi for baremetal targets." OFF) -# The default terminate handler attempts to demangle uncaught exceptions, which -# causes extra I/O and demangling code to be pulled in. -option(LIBCXXABI_SILENT_TERMINATE "Set this to make the terminate handler default to a silent alternative" OFF) - -if (NOT LIBCXXABI_ENABLE_SHARED AND NOT LIBCXXABI_ENABLE_STATIC) - message(FATAL_ERROR "libc++abi must be built as either a shared or static library.") -endif() - -if (LLVM_EXTERNAL_LIBCXX_SOURCE_DIR) - set(LIBCXXABI_LIBCXX_SRC_DIRS ${LLVM_EXTERNAL_LIBCXX_SOURCE_DIR}) -else() - set(LIBCXXABI_LIBCXX_SRC_DIRS - "${LLVM_MAIN_SRC_DIR}/projects/libcxx" - "${LLVM_MAIN_SRC_DIR}/runtimes/libcxx" - ) -endif() - -set(LIBCXXABI_LIBCXX_INCLUDE_DIRS "") -foreach(dir ${LIBCXXABI_LIBCXX_SRC_DIRS}) - list(APPEND LIBCXXABI_LIBCXX_INCLUDE_DIRS "${dir}/include") -endforeach() - -find_path( - LIBCXXABI_LIBCXX_INCLUDES - vector - PATHS ${LIBCXXABI_LIBCXX_INCLUDES} - ${LIBCXXABI_LIBCXX_PATH}/include - ${CMAKE_BINARY_DIR}/${LIBCXXABI_LIBCXX_INCLUDES} - ${LIBCXXABI_LIBCXX_INCLUDE_DIRS} - ${LLVM_INCLUDE_DIR}/c++/v1 - ) - -set(LIBCXXABI_LIBCXX_INCLUDES "${LIBCXXABI_LIBCXX_INCLUDES}" CACHE PATH - "Specify path to libc++ includes." FORCE) - -find_path( - LIBCXXABI_LIBCXX_PATH - utils/libcxx/test/__init__.py - PATHS ${LIBCXXABI_LIBCXX_PATH} - ${LIBCXXABI_LIBCXX_INCLUDES}/../ - ${LIBCXXABI_LIBCXX_SRC_DIRS} - NO_DEFAULT_PATH - ) - -if (LIBCXXABI_LIBCXX_PATH STREQUAL "LIBCXXABI_LIBCXX_PATH-NOTFOUND") - message(WARNING "LIBCXXABI_LIBCXX_PATH was not specified and couldn't be infered.") - set(LIBCXXABI_LIBCXX_PATH "") -endif() - -set(LIBCXXABI_LIBCXX_PATH "${LIBCXXABI_LIBCXX_PATH}" CACHE PATH - "Specify path to libc++ source." FORCE) - -#=============================================================================== -# Configure System -#=============================================================================== - -# Add path for custom modules -set(CMAKE_MODULE_PATH - "${CMAKE_CURRENT_SOURCE_DIR}/cmake" - "${CMAKE_CURRENT_SOURCE_DIR}/cmake/Modules" - ${CMAKE_MODULE_PATH} - ) - -set(LIBCXXABI_COMPILER ${CMAKE_CXX_COMPILER}) -set(LIBCXXABI_SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}) -set(LIBCXXABI_BINARY_DIR ${CMAKE_CURRENT_BINARY_DIR}) -if (LLVM_LIBRARY_OUTPUT_INTDIR) - set(LIBCXXABI_LIBRARY_DIR ${LLVM_LIBRARY_OUTPUT_INTDIR}) -else() - set(LIBCXXABI_LIBRARY_DIR ${CMAKE_BINARY_DIR}/lib${LIBCXXABI_LIBDIR_SUFFIX}) -endif() - -set(LIBCXXABI_INSTALL_PREFIX "" CACHE STRING - "Define libc++abi destination prefix.") - -if (NOT LIBCXXABI_INSTALL_PREFIX MATCHES "^$|.*/") - message(FATAL_ERROR "LIBCXXABI_INSTALL_PREFIX has to end with \"/\".") -endif() - -set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${LIBCXXABI_LIBRARY_DIR}) -set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${LIBCXXABI_LIBRARY_DIR}) -set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${LIBCXXABI_LIBRARY_DIR}) - -# By default, for non-standalone builds, libcxx and libcxxabi share a library -# directory. -if (NOT LIBCXXABI_LIBCXX_LIBRARY_PATH) - set(LIBCXXABI_LIBCXX_LIBRARY_PATH "${LIBCXXABI_LIBRARY_DIR}" CACHE PATH - "The path to libc++ library.") -endif() - -# Check that we can build with 32 bits if requested. -if (CMAKE_SIZEOF_VOID_P EQUAL 8 AND NOT WIN32) - if (LIBCXXABI_BUILD_32_BITS AND NOT LLVM_BUILD_32_BITS) # Don't duplicate the output from LLVM - message(STATUS "Building 32 bits executables and libraries.") - endif() -elseif(LIBCXXABI_BUILD_32_BITS) - message(FATAL_ERROR "LIBCXXABI_BUILD_32_BITS=ON is not supported on this platform.") -endif() - -# Declare libc++abi configuration variables. -# They are intended for use as follows: -# LIBCXXABI_C_FLAGS: General flags for both the c++ compiler and linker. -# LIBCXXABI_CXX_FLAGS: General flags for both the c++ compiler and linker. -# LIBCXXABI_COMPILE_FLAGS: Compile only flags. -# LIBCXXABI_LINK_FLAGS: Linker only flags. -# LIBCXXABI_LIBRARIES: libraries libc++abi is linked to. - -set(LIBCXXABI_C_FLAGS "") -set(LIBCXXABI_CXX_FLAGS "") -set(LIBCXXABI_COMPILE_FLAGS "") -set(LIBCXXABI_LINK_FLAGS "") -set(LIBCXXABI_LIBRARIES "") - -# Include macros for adding and removing libc++abi flags. -include(HandleLibcxxabiFlags) - -#=============================================================================== -# Setup Compiler Flags -#=============================================================================== - -# Configure target flags -add_target_flags_if(LIBCXXABI_BUILD_32_BITS "-m32") -add_target_flags_if(LIBCXXABI_TARGET_TRIPLE - "--target=${LIBCXXABI_TARGET_TRIPLE}") -add_target_flags_if(LIBCXXABI_GCC_TOOLCHAIN - "--gcc-toolchain=${LIBCXXABI_GCC_TOOLCHAIN}") -add_target_flags_if(LIBCXXABI_SYSROOT - "--sysroot=${LIBCXXABI_SYSROOT}") - -if (LIBCXXABI_TARGET_TRIPLE) - set(TARGET_TRIPLE "${LIBCXXABI_TARGET_TRIPLE}") -endif() - -# Configure compiler. Must happen after setting the target flags. -include(config-ix) - -if (LIBCXXABI_HAS_NOSTDINCXX_FLAG) - list(APPEND LIBCXXABI_COMPILE_FLAGS -nostdinc++) - # Remove -stdlib flags to prevent them from causing an unused flag warning. - string(REPLACE "-stdlib=libc++" "" CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}") - string(REPLACE "-stdlib=libstdc++" "" CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}") -endif() - -if (LIBCXXABI_USE_COMPILER_RT) - list(APPEND LIBCXXABI_LINK_FLAGS "-rtlib=compiler-rt") -endif() - -# Let the library headers know they are currently being used to build the -# library. -add_definitions(-D_LIBCXXABI_BUILDING_LIBRARY) - -# Disable DLL annotations on Windows for static builds. -if (WIN32 AND LIBCXXABI_ENABLE_STATIC AND NOT LIBCXXABI_ENABLE_SHARED) - add_definitions(-D_LIBCXXABI_DISABLE_VISIBILITY_ANNOTATIONS) -endif() - -add_compile_flags_if_supported(-Werror=return-type) - -# Get warning flags -add_compile_flags_if_supported(-W) -add_compile_flags_if_supported(-Wall) -add_compile_flags_if_supported(-Wchar-subscripts) -add_compile_flags_if_supported(-Wconversion) -add_compile_flags_if_supported(-Wmismatched-tags) -add_compile_flags_if_supported(-Wmissing-braces) -add_compile_flags_if_supported(-Wnewline-eof) -add_compile_flags_if_supported(-Wunused-function) -add_compile_flags_if_supported(-Wshadow) -add_compile_flags_if_supported(-Wshorten-64-to-32) -add_compile_flags_if_supported(-Wsign-compare) -add_compile_flags_if_supported(-Wsign-conversion) -add_compile_flags_if_supported(-Wstrict-aliasing=2) -add_compile_flags_if_supported(-Wstrict-overflow=4) -add_compile_flags_if_supported(-Wunused-parameter) -add_compile_flags_if_supported(-Wunused-variable) -add_compile_flags_if_supported(-Wwrite-strings) -add_compile_flags_if_supported(-Wundef) - -if (LIBCXXABI_ENABLE_WERROR) - add_compile_flags_if_supported(-Werror) - add_compile_flags_if_supported(-WX) -else() - add_compile_flags_if_supported(-Wno-error) - add_compile_flags_if_supported(-WX-) -endif() -if (LIBCXXABI_ENABLE_PEDANTIC) - add_compile_flags_if_supported(-pedantic) -endif() - -# Get feature flags. -add_compile_flags_if_supported(-fstrict-aliasing) - -# Exceptions -if (LIBCXXABI_ENABLE_EXCEPTIONS) - # Catches C++ exceptions only and tells the compiler to assume that extern C - # functions never throw a C++ exception. - add_compile_flags_if_supported(-EHsc) - # Do we really need to be run through the C compiler ? - add_c_compile_flags_if_supported(-funwind-tables) -else() - add_definitions(-D_LIBCXXABI_NO_EXCEPTIONS) - add_compile_flags_if_supported(-fno-exceptions) - add_compile_flags_if_supported(-EHs-) - add_compile_flags_if_supported(-EHa-) -endif() - -# Assert -string(TOUPPER "${CMAKE_BUILD_TYPE}" uppercase_CMAKE_BUILD_TYPE) -if (LIBCXXABI_ENABLE_ASSERTIONS) - # MSVC doesn't like _DEBUG on release builds. See PR 4379. - if (NOT MSVC) - list(APPEND LIBCXXABI_COMPILE_FLAGS -D_DEBUG) - endif() - # On Release builds cmake automatically defines NDEBUG, so we - # explicitly undefine it: - if (uppercase_CMAKE_BUILD_TYPE STREQUAL "RELEASE") - list(APPEND LIBCXXABI_COMPILE_FLAGS -UNDEBUG) - endif() -else() - if (NOT uppercase_CMAKE_BUILD_TYPE STREQUAL "RELEASE") - list(APPEND LIBCXXABI_COMPILE_FLAGS -DNDEBUG) - endif() -endif() -# Static library -if (NOT LIBCXXABI_ENABLE_SHARED) - list(APPEND LIBCXXABI_COMPILE_FLAGS -D_LIBCPP_BUILD_STATIC) -endif() - -# Threading -if (NOT LIBCXXABI_ENABLE_THREADS) - if (LIBCXXABI_HAS_PTHREAD_API) - message(FATAL_ERROR "LIBCXXABI_HAS_PTHREAD_API can only" - " be set to ON when LIBCXXABI_ENABLE_THREADS" - " is also set to ON.") - endif() - if (LIBCXXABI_HAS_EXTERNAL_THREAD_API) - message(FATAL_ERROR "LIBCXXABI_HAS_EXTERNAL_THREAD_API can only" - " be set to ON when LIBCXXABI_ENABLE_THREADS" - " is also set to ON.") - endif() - if (LIBCXXABI_BUILD_EXTERNAL_THREAD_LIBRARY) - message(FATAL_ERROR "LIBCXXABI_BUILD_EXTERNAL_THREAD_LIBRARY can only" - " be set to ON when LIBCXXABI_ENABLE_THREADS" - " is also set to ON.") - endif() - add_definitions(-D_LIBCXXABI_HAS_NO_THREADS) -endif() - -if (LIBCXXABI_HAS_EXTERNAL_THREAD_API) - if (LIBCXXABI_HAS_PTHREAD_API) - message(FATAL_ERROR "The options LIBCXXABI_HAS_EXTERNAL_THREAD_API" - " and LIBCXXABI_HAS_PTHREAD_API cannot be both" - " set to ON at the same time.") - endif() - if (LIBCXXABI_BUILD_EXTERNAL_THREAD_LIBRARY) - message(FATAL_ERROR "The options LIBCXXABI_BUILD_EXTERNAL_THREAD_LIBRARY" - " and LIBCXXABI_HAS_EXTERNAL_THREAD_API cannot be both" - " set to ON at the same time.") - endif() -endif() - -if (LLVM_ENABLE_MODULES) - # Ignore that the rest of the modules flags are now unused. - add_compile_flags_if_supported(-Wno-unused-command-line-argument) - add_compile_flags(-fno-modules) -endif() - -set(LIBCXXABI_HAS_UNDEFINED_SYMBOLS OFF) -if ((NOT LIBCXXABI_ENABLE_NEW_DELETE_DEFINITIONS) - OR (LIBCXXABI_BUILD_EXTERNAL_THREAD_LIBRARY AND LIBCXXABI_ENABLE_SHARED) - OR MINGW) - set(LIBCXXABI_HAS_UNDEFINED_SYMBOLS ON) -endif() - -if (LIBCXXABI_HAS_UNDEFINED_SYMBOLS) - # Need to allow unresolved symbols if this is to work with shared library builds - if (APPLE) - list(APPEND LIBCXXABI_LINK_FLAGS "-undefined dynamic_lookup") - else() - # Relax this restriction from HandleLLVMOptions - string(REPLACE "-Wl,-z,defs" "" CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS}") - endif() -endif() - -if (LIBCXXABI_HAS_PTHREAD_API) - add_definitions(-D_LIBCPP_HAS_THREAD_API_PTHREAD) -endif() - -if (LIBCXXABI_HAS_EXTERNAL_THREAD_API) - add_definitions(-D_LIBCPP_HAS_THREAD_API_EXTERNAL) -endif() - -if (LIBCXXABI_BUILD_EXTERNAL_THREAD_LIBRARY) - add_definitions(-D_LIBCPP_HAS_THREAD_LIBRARY_EXTERNAL) -endif() - -# Prevent libc++abi from having library dependencies on libc++ -add_definitions(-D_LIBCPP_DISABLE_EXTERN_TEMPLATE) - -if (MSVC) - add_definitions(-D_CRT_SECURE_NO_WARNINGS) -endif() - -# Define LIBCXXABI_USE_LLVM_UNWINDER for conditional compilation. -if (LIBCXXABI_USE_LLVM_UNWINDER) - add_definitions(-DLIBCXXABI_USE_LLVM_UNWINDER) -endif() - -if (LIBCXXABI_SILENT_TERMINATE) - add_definitions(-DLIBCXXABI_SILENT_TERMINATE) -endif() - -if (LIBCXXABI_BAREMETAL) - add_definitions(-DLIBCXXABI_BAREMETAL) -endif() - -string(REPLACE ";" " " LIBCXXABI_CXX_FLAGS "${LIBCXXABI_CXX_FLAGS}") -set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${LIBCXXABI_CXX_FLAGS}") -set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${LIBCXXABI_C_FLAGS}") - -#=============================================================================== -# Setup Source Code -#=============================================================================== - -set(LIBCXXABI_LIBUNWIND_INCLUDES "${LIBCXXABI_LIBUNWIND_INCLUDES}" CACHE PATH - "Specify path to libunwind includes." FORCE) -set(LIBCXXABI_LIBUNWIND_PATH "${LIBCXXABI_LIBUNWIND_PATH}" CACHE PATH - "Specify path to libunwind source." FORCE) - -include_directories(include) -if (LIBCXXABI_USE_LLVM_UNWINDER OR LLVM_NATIVE_ARCH MATCHES ARM) - find_path( - LIBCXXABI_LIBUNWIND_INCLUDES_INTERNAL - libunwind.h - PATHS ${LIBCXXABI_LIBUNWIND_INCLUDES} - ${LIBCXXABI_LIBUNWIND_PATH}/include - ${CMAKE_BINARY_DIR}/${LIBCXXABI_LIBUNWIND_INCLUDES} - ${LLVM_MAIN_SRC_DIR}/projects/libunwind/include - ${LLVM_MAIN_SRC_DIR}/runtimes/libunwind/include - NO_DEFAULT_PATH - ) - - if (LIBCXXABI_LIBUNWIND_INCLUDES_INTERNAL STREQUAL "LIBCXXABI_LIBUNWIND_INCLUDES_INTERNAL-NOTFOUND") - set(LIBCXXABI_LIBUNWIND_INCLUDES_INTERNAL "") - endif() - - if (NOT LIBCXXABI_LIBUNWIND_INCLUDES_INTERNAL STREQUAL "") - include_directories("${LIBCXXABI_LIBUNWIND_INCLUDES_INTERNAL}") - endif() -endif() - -# Add source code. This also contains all of the logic for deciding linker flags -# soname, etc... -add_subdirectory(src) - -if (NOT LIBCXXABI_INCLUDE_TESTS OR (LIBCXXABI_STANDALONE_BUILD AND NOT LIBCXXABI_ENABLE_SHARED)) - # We can't reasonably test the system C++ library with a static libc++abi. - # We either need to be able to replace libc++abi at run time (with a shared - # libc++abi), or we need to be able to replace the C++ runtime (with a non- - # standalone build). - message(WARNING "The libc++abi tests aren't valid when libc++abi is built " - "standalone (i.e. outside of llvm/projects/libcxxabi ) and " - "is built without a shared library. Either build a shared " - "library, build libc++abi at the same time as you build " - "libc++, or do without testing. No check target will be " - "available!") -else() - add_subdirectory(test) - add_subdirectory(fuzz) -endif() diff --git a/chromium/buildtools/third_party/libc++abi/trunk/CREDITS.TXT b/chromium/buildtools/third_party/libc++abi/trunk/CREDITS.TXT deleted file mode 100644 index 9c910fcfd0c..00000000000 --- a/chromium/buildtools/third_party/libc++abi/trunk/CREDITS.TXT +++ /dev/null @@ -1,71 +0,0 @@ -This file is a partial list of people who have contributed to the LLVM/libc++abi -project. If you have contributed a patch or made some other contribution to -LLVM/libc++abi, please submit a patch to this file to add yourself, and it will be -done! - -The list is sorted by surname and formatted to allow easy grepping and -beautification by scripts. The fields are: name (N), email (E), web-address -(W), PGP key ID and fingerprint (P), description (D), and snail-mail address -(S). - -N: Aaron Ballman -E: aaron@aaronballman.com -D: Minor patches - -N: Logan Chien -E: logan.chien@mediatek.com -D: ARM EHABI Unwind & Exception Handling - -N: Marshall Clow -E: mclow.lists@gmail.com -E: marshall@idio.com -D: Architect and primary coauthor of libc++abi - -N: Matthew Dempsky -E: matthew@dempsky.org -D: Minor patches and bug fixes. - -N: Nowar Gu -E: wenhan.gu@gmail.com -D: Minor patches and fixes - -N: Howard Hinnant -E: hhinnant@apple.com -D: Architect and primary coauthor of libc++abi - -N: Dana Jansens -E: danakj@chromium.org -D: ARM EHABI Unwind & Exception Handling - -N: Nick Kledzik -E: kledzik@apple.com - -N: Antoine Labour -E: piman@chromium.org -D: ARM EHABI Unwind & Exception Handling - -N: Bruce Mitchener, Jr. -E: bruce.mitchener@gmail.com -D: Minor typo fixes - -N: Andrew Morrow -E: andrew.c.morrow@gmail.com -D: Minor patches and fixes - -N: Erik Olofsson -E: erik.olofsson@hansoft.se -E: erik@olofsson.info -D: Minor patches and fixes - -N: Jon Roelofs -E: jonathan@codesourcery.com -D: ARM EHABI Unwind & Exception Handling, Bare-metal - -N: Nico Weber -E: thakis@chromium.org -D: ARM EHABI Unwind & Exception Handling - -N: Albert J. Wong -E: ajwong@google.com -D: ARM EHABI Unwind & Exception Handling - diff --git a/chromium/buildtools/third_party/libc++abi/trunk/LICENSE.TXT b/chromium/buildtools/third_party/libc++abi/trunk/LICENSE.TXT deleted file mode 100644 index f333f1fe48d..00000000000 --- a/chromium/buildtools/third_party/libc++abi/trunk/LICENSE.TXT +++ /dev/null @@ -1,76 +0,0 @@ -============================================================================== -libc++abi License -============================================================================== - -The libc++abi 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. diff --git a/chromium/buildtools/third_party/libc++abi/trunk/cmake/Modules/HandleCompilerRT.cmake b/chromium/buildtools/third_party/libc++abi/trunk/cmake/Modules/HandleCompilerRT.cmake deleted file mode 100644 index 395c21ace66..00000000000 --- a/chromium/buildtools/third_party/libc++abi/trunk/cmake/Modules/HandleCompilerRT.cmake +++ /dev/null @@ -1,58 +0,0 @@ -function(find_compiler_rt_library name dest) - if (NOT DEFINED LIBCXXABI_COMPILE_FLAGS) - message(FATAL_ERROR "LIBCXXABI_COMPILE_FLAGS must be defined when using this function") - endif() - set(dest "" PARENT_SCOPE) - set(CLANG_COMMAND ${CMAKE_CXX_COMPILER} ${LIBCXXABI_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 LIBCXXABI_COMPILE_FLAGS) - message(FATAL_ERROR "LIBCXXABI_COMPILE_FLAGS must be defined when using this function") - endif() - set(dest "" PARENT_SCOPE) - if (APPLE) - set(CLANG_COMMAND ${CMAKE_CXX_COMPILER} ${LIBCXXABI_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} ${LIBCXXABI_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() diff --git a/chromium/buildtools/third_party/libc++abi/trunk/cmake/Modules/HandleLibcxxabiFlags.cmake b/chromium/buildtools/third_party/libc++abi/trunk/cmake/Modules/HandleLibcxxabiFlags.cmake deleted file mode 100644 index 3eddd7bdc62..00000000000 --- a/chromium/buildtools/third_party/libc++abi/trunk/cmake/Modules/HandleLibcxxabiFlags.cmake +++ /dev/null @@ -1,208 +0,0 @@ -# HandleLibcxxFlags - A set of macros used to setup the flags used to compile -# and link libc++abi. These macros add flags to the following CMake variables. -# - LIBCXXABI_COMPILE_FLAGS: flags used to compile libc++abi -# - LIBCXXABI_LINK_FLAGS: flags used to link libc++abi -# - LIBCXXABI_LIBRARIES: libraries to link libc++abi to. - -include(CheckCXXCompilerFlag) - -unset(add_flag_if_supported) - -# Mangle the name of a compiler flag into a valid CMake identifier. -# Ex: --std=c++11 -> STD_EQ_CXX11 -macro(mangle_name str output) - string(STRIP "${str}" strippedStr) - string(REGEX REPLACE "^/" "" strippedStr "${strippedStr}") - string(REGEX REPLACE "^-+" "" strippedStr "${strippedStr}") - string(REGEX REPLACE "-+$" "" strippedStr "${strippedStr}") - string(REPLACE "-" "_" strippedStr "${strippedStr}") - string(REPLACE "=" "_EQ_" strippedStr "${strippedStr}") - string(REPLACE "+" "X" strippedStr "${strippedStr}") - string(TOUPPER "${strippedStr}" ${output}) -endmacro() - -# Remove a list of flags from all CMake variables that affect compile flags. -# This can be used to remove unwanted flags specified on the command line -# or added in other parts of LLVM's cmake configuration. -macro(remove_flags) - foreach(var ${ARGN}) - string(REPLACE "${var}" "" CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG}") - string(REPLACE "${var}" "" CMAKE_CXX_FLAGS_MINSIZEREL "${CMAKE_CXX_FLAGS_MINSIZEREL}") - string(REPLACE "${var}" "" CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE}") - string(REPLACE "${var}" "" CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_RELWITHDEBINFO}") - string(REPLACE "${var}" "" CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}") - string(REPLACE "${var}" "" CMAKE_C_FLAGS "${CMAKE_C_FLAGS}") - string(REPLACE "${var}" "" CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS}") - string(REPLACE "${var}" "" CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS}") - string(REPLACE "${var}" "" CMAKE_SHARED_MODULE_FLAGS "${CMAKE_SHARED_MODULE_FLAGS}") - remove_definitions(${var}) - endforeach() -endmacro(remove_flags) - -macro(check_flag_supported flag) - mangle_name("${flag}" flagname) - check_cxx_compiler_flag("${flag}" "LIBCXXABI_SUPPORTS_${flagname}_FLAG") -endmacro() - -# Add a macro definition if condition is true. -macro(define_if condition def) - if (${condition}) - add_definitions(${def}) - endif() -endmacro() - -# Add a macro definition if condition is not true. -macro(define_if_not condition def) - if (NOT ${condition}) - add_definitions(${def}) - endif() -endmacro() - -# Add a macro definition to the __config_site file if the specified condition -# is 'true'. Note that '-D${def}' is not added. Instead it is expected that -# the build include the '__config_site' header. -macro(config_define_if condition def) - if (${condition}) - set(${def} ON) - set(LIBCXXABI_NEEDS_SITE_CONFIG ON) - endif() -endmacro() - -macro(config_define_if_not condition def) - if (NOT ${condition}) - set(${def} ON) - set(LIBCXXABI_NEEDS_SITE_CONFIG ON) - endif() -endmacro() - -macro(config_define value def) - set(${def} ${value}) - set(LIBCXXABI_NEEDS_SITE_CONFIG ON) -endmacro() - -# Add a list of flags to all of 'CMAKE_CXX_FLAGS', 'CMAKE_C_FLAGS', -# 'LIBCXXABI_COMPILE_FLAGS' and 'LIBCXXABI_LINK_FLAGS'. -macro(add_target_flags) - foreach(value ${ARGN}) - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${value}") - set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${value}") - list(APPEND LIBCXXABI_COMPILE_FLAGS ${value}) - list(APPEND LIBCXXABI_LINK_FLAGS ${value}) - endforeach() -endmacro() - -# If the specified 'condition' is true then add a list of flags to -# all of 'CMAKE_CXX_FLAGS', 'CMAKE_C_FLAGS', 'LIBCXXABI_COMPILE_FLAGS' -# and 'LIBCXXABI_LINK_FLAGS'. -macro(add_target_flags_if condition) - if (${condition}) - add_target_flags(${ARGN}) - endif() -endmacro() - -# Add a specified list of flags to both 'LIBCXXABI_COMPILE_FLAGS' and -# 'LIBCXXABI_LINK_FLAGS'. -macro(add_flags) - foreach(value ${ARGN}) - list(APPEND LIBCXXABI_COMPILE_FLAGS ${value}) - list(APPEND LIBCXXABI_LINK_FLAGS ${value}) - endforeach() -endmacro() - -# If the specified 'condition' is true then add a list of flags to both -# 'LIBCXXABI_COMPILE_FLAGS' and 'LIBCXXABI_LINK_FLAGS'. -macro(add_flags_if condition) - if (${condition}) - add_flags(${ARGN}) - endif() -endmacro() - -# Add each flag in the list to LIBCXXABI_COMPILE_FLAGS and LIBCXXABI_LINK_FLAGS -# if that flag is supported by the current compiler. -macro(add_flags_if_supported) - foreach(flag ${ARGN}) - mangle_name("${flag}" flagname) - check_cxx_compiler_flag("${flag}" "LIBCXXABI_SUPPORTS_${flagname}_FLAG") - add_flags_if(LIBCXXABI_SUPPORTS_${flagname}_FLAG ${flag}) - endforeach() -endmacro() - -# Add a list of flags to 'LIBCXXABI_COMPILE_FLAGS'. -macro(add_compile_flags) - foreach(f ${ARGN}) - list(APPEND LIBCXXABI_COMPILE_FLAGS ${f}) - endforeach() -endmacro() - -# If 'condition' is true then add the specified list of flags to -# 'LIBCXXABI_COMPILE_FLAGS' -macro(add_compile_flags_if condition) - if (${condition}) - add_compile_flags(${ARGN}) - endif() -endmacro() - -# For each specified flag, add that flag to 'LIBCXXABI_COMPILE_FLAGS' if the -# flag is supported by the C++ compiler. -macro(add_compile_flags_if_supported) - foreach(flag ${ARGN}) - mangle_name("${flag}" flagname) - check_cxx_compiler_flag("${flag}" "LIBCXXABI_SUPPORTS_${flagname}_FLAG") - add_compile_flags_if(LIBCXXABI_SUPPORTS_${flagname}_FLAG ${flag}) - endforeach() -endmacro() - -# For each specified flag, add that flag to 'LIBCXXABI_COMPILE_FLAGS' if the -# flag is supported by the C compiler. -macro(add_c_compile_flags_if_supported) - foreach(flag ${ARGN}) - mangle_name("${flag}" flagname) - check_c_compiler_flag("${flag}" "LIBCXXABI_SUPPORTS_${flagname}_FLAG") - add_compile_flags_if(LIBCXXABI_SUPPORTS_${flagname}_FLAG ${flag}) - endforeach() -endmacro() - -# Add a list of flags to 'LIBCXXABI_LINK_FLAGS'. -macro(add_link_flags) - foreach(f ${ARGN}) - list(APPEND LIBCXXABI_LINK_FLAGS ${f}) - endforeach() -endmacro() - -# If 'condition' is true then add the specified list of flags to -# 'LIBCXXABI_LINK_FLAGS' -macro(add_link_flags_if condition) - if (${condition}) - add_link_flags(${ARGN}) - endif() -endmacro() - -# For each specified flag, add that flag to 'LIBCXXABI_LINK_FLAGS' if the -# flag is supported by the C++ compiler. -macro(add_link_flags_if_supported) - foreach(flag ${ARGN}) - mangle_name("${flag}" flagname) - check_cxx_compiler_flag("${flag}" "LIBCXXABI_SUPPORTS_${flagname}_FLAG") - add_link_flags_if(LIBCXXABI_SUPPORTS_${flagname}_FLAG ${flag}) - endforeach() -endmacro() - -# Add a list of libraries or link flags to 'LIBCXXABI_LIBRARIES'. -macro(add_library_flags) - foreach(lib ${ARGN}) - list(APPEND LIBCXXABI_LIBRARIES ${lib}) - endforeach() -endmacro() - -# if 'condition' is true then add the specified list of libraries and flags -# to 'LIBCXXABI_LIBRARIES'. -macro(add_library_flags_if condition) - if(${condition}) - add_library_flags(${ARGN}) - endif() -endmacro() - -# Turn a comma separated CMake list into a space separated string. -macro(split_list listname) - string(REPLACE ";" " " ${listname} "${${listname}}") -endmacro() diff --git a/chromium/buildtools/third_party/libc++abi/trunk/cmake/Modules/HandleOutOfTreeLLVM.cmake b/chromium/buildtools/third_party/libc++abi/trunk/cmake/Modules/HandleOutOfTreeLLVM.cmake deleted file mode 100644 index 8e742088978..00000000000 --- a/chromium/buildtools/third_party/libc++abi/trunk/cmake/Modules/HandleOutOfTreeLLVM.cmake +++ /dev/null @@ -1,131 +0,0 @@ -macro(find_llvm_parts) -# Rely on llvm-config. - set(CONFIG_OUTPUT) - 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_PATH) - message(STATUS "Found LLVM_CONFIG_PATH as ${LLVM_CONFIG_PATH}") - set(LIBCXXABI_USING_INSTALLED_LLVM 1) - set(CONFIG_COMMAND ${LLVM_CONFIG_PATH} - "--includedir" - "--prefix" - "--src-root") - execute_process( - COMMAND ${CONFIG_COMMAND} - RESULT_VARIABLE HAD_ERROR - OUTPUT_VARIABLE CONFIG_OUTPUT - ) - if(NOT HAD_ERROR) - string(REGEX REPLACE - "[ \t]*[\r\n]+[ \t]*" ";" - CONFIG_OUTPUT ${CONFIG_OUTPUT}) - else() - string(REPLACE ";" " " CONFIG_COMMAND_STR "${CONFIG_COMMAND}") - message(STATUS "${CONFIG_COMMAND_STR}") - message(FATAL_ERROR "llvm-config failed with status ${HAD_ERROR}") - endif() - - list(GET CONFIG_OUTPUT 0 INCLUDE_DIR) - list(GET CONFIG_OUTPUT 1 LLVM_OBJ_ROOT) - list(GET CONFIG_OUTPUT 2 MAIN_SRC_DIR) - - 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") - - # --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() - set(LLVM_FOUND OFF) - message(WARNING "UNSUPPORTED LIBCXXABI CONFIGURATION DETECTED: " - "llvm-config not found and LLVM_PATH not defined.\n" - "Reconfigure with -DLLVM_CONFIG_PATH=path/to/llvm-config " - "or -DLLVM_PATH=path/to/llvm-source-root.") - return() - endif() - - if (EXISTS "${LLVM_CMAKE_PATH}") - list(APPEND CMAKE_MODULE_PATH "${LLVM_CMAKE_PATH}") - elseif (EXISTS "${LLVM_MAIN_SRC_DIR}/cmake/modules") - list(APPEND CMAKE_MODULE_PATH "${LLVM_MAIN_SRC_DIR}/cmake/modules") - else() - set(LLVM_FOUND OFF) - message(WARNING "Neither ${LLVM_CMAKE_PATH} nor ${LLVM_MAIN_SRC_DIR}/cmake/modules found") - return() - endif() - - set(LLVM_FOUND ON) -endmacro(find_llvm_parts) - -macro(configure_out_of_tree_llvm) - message(STATUS "Configuring for standalone build.") - set(LIBCXXABI_STANDALONE_BUILD 1) - - find_llvm_parts() - - # Add LLVM Functions -------------------------------------------------------- - if (LLVM_FOUND AND LIBCXXABI_USING_INSTALLED_LLVM) - include(LLVMConfig) # For TARGET_TRIPLE - else() - if (WIN32) - set(LLVM_ON_UNIX 0) - set(LLVM_ON_WIN32 1) - else() - set(LLVM_ON_UNIX 1) - set(LLVM_ON_WIN32 0) - endif() - endif() - if (LLVM_FOUND) - include(AddLLVM OPTIONAL) - include(HandleLLVMOptions OPTIONAL) - endif() - - # LLVM Options -------------------------------------------------------------- - if (NOT DEFINED LLVM_INCLUDE_TESTS) - set(LLVM_INCLUDE_TESTS ${LLVM_FOUND}) - endif() - if (NOT DEFINED LLVM_INCLUDE_DOCS) - set(LLVM_INCLUDE_DOCS ${LLVM_FOUND}) - endif() - if (NOT DEFINED LLVM_ENABLE_SPHINX) - set(LLVM_ENABLE_SPHINX OFF) - endif() - - # Required LIT Configuration ------------------------------------------------ - # Define the default arguments to use with 'lit', and an option for the user - # to override. - set(LIT_ARGS_DEFAULT "-sv --show-xfail --show-unsupported") - if (MSVC OR XCODE) - set(LIT_ARGS_DEFAULT "${LIT_ARGS_DEFAULT} --no-progress-bar") - endif() - set(LLVM_LIT_ARGS "${LIT_ARGS_DEFAULT}" CACHE STRING "Default options for lit") - - # Required doc configuration - if (LLVM_ENABLE_SPHINX) - find_package(Sphinx REQUIRED) - endif() - - if (LLVM_ON_UNIX AND NOT APPLE) - set(LLVM_HAVE_LINK_VERSION_SCRIPT 1) - else() - set(LLVM_HAVE_LINK_VERSION_SCRIPT 0) - endif() -endmacro(configure_out_of_tree_llvm) - -configure_out_of_tree_llvm() diff --git a/chromium/buildtools/third_party/libc++abi/trunk/cmake/Modules/MacroEnsureOutOfSourceBuild.cmake b/chromium/buildtools/third_party/libc++abi/trunk/cmake/Modules/MacroEnsureOutOfSourceBuild.cmake deleted file mode 100644 index e75002bd8b7..00000000000 --- a/chromium/buildtools/third_party/libc++abi/trunk/cmake/Modules/MacroEnsureOutOfSourceBuild.cmake +++ /dev/null @@ -1,18 +0,0 @@ -# MACRO_ENSURE_OUT_OF_SOURCE_BUILD(<errorMessage>) - -macro( MACRO_ENSURE_OUT_OF_SOURCE_BUILD _errorMessage ) - -string( COMPARE EQUAL "${CMAKE_SOURCE_DIR}" "${CMAKE_BINARY_DIR}" _insource ) -if( _insource ) - message( SEND_ERROR "${_errorMessage}" ) - message( FATAL_ERROR - "In-source builds are not allowed. - CMake would overwrite the makefiles distributed with libcxxabi. - Please create a directory and run cmake from there, passing the path - to this source directory as the last argument. - This process created the file `CMakeCache.txt' and the directory `CMakeFiles'. - Please delete them." - ) -endif( _insource ) - -endmacro( MACRO_ENSURE_OUT_OF_SOURCE_BUILD ) diff --git a/chromium/buildtools/third_party/libc++abi/trunk/cmake/config-ix.cmake b/chromium/buildtools/third_party/libc++abi/trunk/cmake/config-ix.cmake deleted file mode 100644 index 379b5547749..00000000000 --- a/chromium/buildtools/third_party/libc++abi/trunk/cmake/config-ix.cmake +++ /dev/null @@ -1,89 +0,0 @@ -include(CheckLibraryExists) -include(CheckCCompilerFlag) -include(CheckCXXCompilerFlag) - -check_library_exists(c fopen "" LIBCXXABI_HAS_C_LIB) -if (NOT LIBCXXABI_USE_COMPILER_RT) - check_library_exists(gcc_s __gcc_personality_v0 "" LIBCXXABI_HAS_GCC_S_LIB) -endif () - -# libc++abi 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 LIBCXXABI_HAS_NODEFAULTLIBS_FLAG) -if (LIBCXXABI_HAS_NODEFAULTLIBS_FLAG) - set(CMAKE_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS} -nodefaultlibs") - if (LIBCXXABI_HAS_C_LIB) - list(APPEND CMAKE_REQUIRED_LIBRARIES c) - endif () - if (LIBCXXABI_USE_COMPILER_RT) - list(APPEND CMAKE_REQUIRED_FLAGS -rtlib=compiler-rt) - find_compiler_rt_library(builtins LIBCXXABI_BUILTINS_LIBRARY) - list(APPEND CMAKE_REQUIRED_LIBRARIES "${LIBCXXABI_BUILTINS_LIBRARY}") - elseif (LIBCXXABI_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 (LIBCXXABI_USE_COMPILER_RT) - set(MINGW_RUNTIME ${LIBCXXABI_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 LIBCXXABI_HAS_FUNWIND_TABLES) -check_cxx_compiler_flag(-fno-exceptions LIBCXXABI_HAS_NO_EXCEPTIONS_FLAG) -check_cxx_compiler_flag(-fno-rtti LIBCXXABI_HAS_NO_RTTI_FLAG) -check_cxx_compiler_flag(-fstrict-aliasing LIBCXXABI_HAS_FSTRICT_ALIASING_FLAG) -check_cxx_compiler_flag(-nostdinc++ LIBCXXABI_HAS_NOSTDINCXX_FLAG) -check_cxx_compiler_flag(-Wall LIBCXXABI_HAS_WALL_FLAG) -check_cxx_compiler_flag(-W LIBCXXABI_HAS_W_FLAG) -check_cxx_compiler_flag(-Wunused-function LIBCXXABI_HAS_WUNUSED_FUNCTION_FLAG) -check_cxx_compiler_flag(-Wunused-variable LIBCXXABI_HAS_WUNUSED_VARIABLE_FLAG) -check_cxx_compiler_flag(-Wunused-parameter LIBCXXABI_HAS_WUNUSED_PARAMETER_FLAG) -check_cxx_compiler_flag(-Wstrict-aliasing LIBCXXABI_HAS_WSTRICT_ALIASING_FLAG) -check_cxx_compiler_flag(-Wstrict-overflow LIBCXXABI_HAS_WSTRICT_OVERFLOW_FLAG) -check_cxx_compiler_flag(-Wwrite-strings LIBCXXABI_HAS_WWRITE_STRINGS_FLAG) -check_cxx_compiler_flag(-Wchar-subscripts LIBCXXABI_HAS_WCHAR_SUBSCRIPTS_FLAG) -check_cxx_compiler_flag(-Wmismatched-tags LIBCXXABI_HAS_WMISMATCHED_TAGS_FLAG) -check_cxx_compiler_flag(-Wmissing-braces LIBCXXABI_HAS_WMISSING_BRACES_FLAG) -check_cxx_compiler_flag(-Wshorten-64-to-32 LIBCXXABI_HAS_WSHORTEN_64_TO_32_FLAG) -check_cxx_compiler_flag(-Wsign-conversion LIBCXXABI_HAS_WSIGN_CONVERSION_FLAG) -check_cxx_compiler_flag(-Wsign-compare LIBCXXABI_HAS_WSIGN_COMPARE_FLAG) -check_cxx_compiler_flag(-Wshadow LIBCXXABI_HAS_WSHADOW_FLAG) -check_cxx_compiler_flag(-Wconversion LIBCXXABI_HAS_WCONVERSION_FLAG) -check_cxx_compiler_flag(-Wnewline-eof LIBCXXABI_HAS_WNEWLINE_EOF_FLAG) -check_cxx_compiler_flag(-Wundef LIBCXXABI_HAS_WUNDEF_FLAG) -check_cxx_compiler_flag(-pedantic LIBCXXABI_HAS_PEDANTIC_FLAG) -check_cxx_compiler_flag(-Werror LIBCXXABI_HAS_WERROR_FLAG) -check_cxx_compiler_flag(-Wno-error LIBCXXABI_HAS_WNO_ERROR_FLAG) -check_cxx_compiler_flag(/WX LIBCXXABI_HAS_WX_FLAG) -check_cxx_compiler_flag(/WX- LIBCXXABI_HAS_NO_WX_FLAG) -check_cxx_compiler_flag(/EHsc LIBCXXABI_HAS_EHSC_FLAG) -check_cxx_compiler_flag(/EHs- LIBCXXABI_HAS_NO_EHS_FLAG) -check_cxx_compiler_flag(/EHa- LIBCXXABI_HAS_NO_EHA_FLAG) -check_cxx_compiler_flag(/GR- LIBCXXABI_HAS_NO_GR_FLAG) - -# Check libraries -check_library_exists(dl dladdr "" LIBCXXABI_HAS_DL_LIB) -check_library_exists(pthread pthread_once "" LIBCXXABI_HAS_PTHREAD_LIB) -check_library_exists(c __cxa_thread_atexit_impl "" - LIBCXXABI_HAS_CXA_THREAD_ATEXIT_IMPL) diff --git a/chromium/buildtools/third_party/libc++abi/trunk/fuzz/CMakeLists.txt b/chromium/buildtools/third_party/libc++abi/trunk/fuzz/CMakeLists.txt deleted file mode 100644 index 017427e4631..00000000000 --- a/chromium/buildtools/third_party/libc++abi/trunk/fuzz/CMakeLists.txt +++ /dev/null @@ -1,11 +0,0 @@ -# See http://llvm.org/docs/LibFuzzer.html -if( LLVM_USE_SANITIZE_COVERAGE ) - add_executable(cxa_demangle_fuzzer - cxa_demangle_fuzzer.cpp - ../src/cxa_demangle.cpp - ) - - target_link_libraries(cxa_demangle_fuzzer - LLVMFuzzer - ) -endif() diff --git a/chromium/buildtools/third_party/libc++abi/trunk/fuzz/cxa_demangle_fuzzer.cpp b/chromium/buildtools/third_party/libc++abi/trunk/fuzz/cxa_demangle_fuzzer.cpp deleted file mode 100644 index cc9b193670d..00000000000 --- a/chromium/buildtools/third_party/libc++abi/trunk/fuzz/cxa_demangle_fuzzer.cpp +++ /dev/null @@ -1,15 +0,0 @@ -#include <stdint.h> -#include <stddef.h> -#include <string.h> -#include <stdlib.h> -extern "C" char * -__cxa_demangle(const char *mangled_name, char *buf, size_t *n, int *status); - -extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) { - char *str = new char[size+1]; - memcpy(str, data, size); - str[size] = 0; - free(__cxa_demangle(str, 0, 0, 0)); - delete [] str; - return 0; -} diff --git a/chromium/buildtools/third_party/libc++abi/trunk/include/__cxxabi_config.h b/chromium/buildtools/third_party/libc++abi/trunk/include/__cxxabi_config.h deleted file mode 100644 index 65b1961e68a..00000000000 --- a/chromium/buildtools/third_party/libc++abi/trunk/include/__cxxabi_config.h +++ /dev/null @@ -1,63 +0,0 @@ -//===-------------------------- __cxxabi_config.h -------------------------===// -// -// 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 ____CXXABI_CONFIG_H -#define ____CXXABI_CONFIG_H - -#if defined(__arm__) && !defined(__USING_SJLJ_EXCEPTIONS__) && \ - !defined(__ARM_DWARF_EH__) -#define _LIBCXXABI_ARM_EHABI -#endif - -#if !defined(__has_attribute) -#define __has_attribute(_attribute_) 0 -#endif - -#if defined(_WIN32) - #if defined(_LIBCXXABI_DISABLE_VISIBILITY_ANNOTATIONS) - #define _LIBCXXABI_HIDDEN - #define _LIBCXXABI_DATA_VIS - #define _LIBCXXABI_FUNC_VIS - #define _LIBCXXABI_TYPE_VIS - #elif defined(_LIBCXXABI_BUILDING_LIBRARY) - #define _LIBCXXABI_HIDDEN - #define _LIBCXXABI_DATA_VIS __declspec(dllexport) - #define _LIBCXXABI_FUNC_VIS __declspec(dllexport) - #define _LIBCXXABI_TYPE_VIS __declspec(dllexport) - #else - #define _LIBCXXABI_HIDDEN - #define _LIBCXXABI_DATA_VIS __declspec(dllimport) - #define _LIBCXXABI_FUNC_VIS __declspec(dllimport) - #define _LIBCXXABI_TYPE_VIS __declspec(dllimport) - #endif -#else - #if !defined(_LIBCXXABI_DISABLE_VISIBILITY_ANNOTATIONS) - #define _LIBCXXABI_HIDDEN __attribute__((__visibility__("hidden"))) - #define _LIBCXXABI_DATA_VIS __attribute__((__visibility__("default"))) - #define _LIBCXXABI_FUNC_VIS __attribute__((__visibility__("default"))) - #if __has_attribute(__type_visibility__) - #define _LIBCXXABI_TYPE_VIS __attribute__((__type_visibility__("default"))) - #else - #define _LIBCXXABI_TYPE_VIS __attribute__((__visibility__("default"))) - #endif - #else - #define _LIBCXXABI_HIDDEN - #define _LIBCXXABI_DATA_VIS - #define _LIBCXXABI_FUNC_VIS - #define _LIBCXXABI_TYPE_VIS - #endif -#endif - -#if defined(_WIN32) -#define _LIBCXXABI_WEAK -#else -#define _LIBCXXABI_WEAK __attribute__((__weak__)) -#endif - -#endif // ____CXXABI_CONFIG_H diff --git a/chromium/buildtools/third_party/libc++abi/trunk/include/cxxabi.h b/chromium/buildtools/third_party/libc++abi/trunk/include/cxxabi.h deleted file mode 100644 index 2596560d6e9..00000000000 --- a/chromium/buildtools/third_party/libc++abi/trunk/include/cxxabi.h +++ /dev/null @@ -1,177 +0,0 @@ -//===--------------------------- cxxabi.h ---------------------------------===// -// -// 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 __CXXABI_H -#define __CXXABI_H - -/* - * This header provides the interface to the C++ ABI as defined at: - * http://www.codesourcery.com/cxx-abi/ - */ - -#include <stddef.h> -#include <stdint.h> - -#include <__cxxabi_config.h> - -#define _LIBCPPABI_VERSION 1002 -#define _LIBCXXABI_NORETURN __attribute__((noreturn)) - -#ifdef __cplusplus - -namespace std { -#if defined(_WIN32) -class _LIBCXXABI_TYPE_VIS type_info; // forward declaration -#else -class type_info; // forward declaration -#endif -} - - -// runtime routines use C calling conventions, but are in __cxxabiv1 namespace -namespace __cxxabiv1 { -extern "C" { - -// 2.4.2 Allocating the Exception Object -extern _LIBCXXABI_FUNC_VIS void * -__cxa_allocate_exception(size_t thrown_size) throw(); -extern _LIBCXXABI_FUNC_VIS void -__cxa_free_exception(void *thrown_exception) throw(); - -// 2.4.3 Throwing the Exception Object -extern _LIBCXXABI_FUNC_VIS _LIBCXXABI_NORETURN void -__cxa_throw(void *thrown_exception, std::type_info *tinfo, - void (*dest)(void *)); - -// 2.5.3 Exception Handlers -extern _LIBCXXABI_FUNC_VIS void * -__cxa_get_exception_ptr(void *exceptionObject) throw(); -extern _LIBCXXABI_FUNC_VIS void * -__cxa_begin_catch(void *exceptionObject) throw(); -extern _LIBCXXABI_FUNC_VIS void __cxa_end_catch(); -#if defined(_LIBCXXABI_ARM_EHABI) -extern _LIBCXXABI_FUNC_VIS bool -__cxa_begin_cleanup(void *exceptionObject) throw(); -extern _LIBCXXABI_FUNC_VIS void __cxa_end_cleanup(); -#endif -extern _LIBCXXABI_FUNC_VIS std::type_info *__cxa_current_exception_type(); - -// 2.5.4 Rethrowing Exceptions -extern _LIBCXXABI_FUNC_VIS _LIBCXXABI_NORETURN void __cxa_rethrow(); - -// 2.6 Auxiliary Runtime APIs -extern _LIBCXXABI_FUNC_VIS _LIBCXXABI_NORETURN void __cxa_bad_cast(void); -extern _LIBCXXABI_FUNC_VIS _LIBCXXABI_NORETURN void __cxa_bad_typeid(void); -extern _LIBCXXABI_FUNC_VIS _LIBCXXABI_NORETURN void -__cxa_throw_bad_array_new_length(void); - -// 3.2.6 Pure Virtual Function API -extern _LIBCXXABI_FUNC_VIS _LIBCXXABI_NORETURN void __cxa_pure_virtual(void); - -// 3.2.7 Deleted Virtual Function API -extern _LIBCXXABI_FUNC_VIS _LIBCXXABI_NORETURN void __cxa_deleted_virtual(void); - -// 3.3.2 One-time Construction API -#ifdef __arm__ -extern _LIBCXXABI_FUNC_VIS int __cxa_guard_acquire(uint32_t *); -extern _LIBCXXABI_FUNC_VIS void __cxa_guard_release(uint32_t *); -extern _LIBCXXABI_FUNC_VIS void __cxa_guard_abort(uint32_t *); -#else -extern _LIBCXXABI_FUNC_VIS int __cxa_guard_acquire(uint64_t *); -extern _LIBCXXABI_FUNC_VIS void __cxa_guard_release(uint64_t *); -extern _LIBCXXABI_FUNC_VIS void __cxa_guard_abort(uint64_t *); -#endif - -// 3.3.3 Array Construction and Destruction API -extern _LIBCXXABI_FUNC_VIS void * -__cxa_vec_new(size_t element_count, size_t element_size, size_t padding_size, - void (*constructor)(void *), void (*destructor)(void *)); - -extern _LIBCXXABI_FUNC_VIS void * -__cxa_vec_new2(size_t element_count, size_t element_size, size_t padding_size, - void (*constructor)(void *), void (*destructor)(void *), - void *(*alloc)(size_t), void (*dealloc)(void *)); - -extern _LIBCXXABI_FUNC_VIS void * -__cxa_vec_new3(size_t element_count, size_t element_size, size_t padding_size, - void (*constructor)(void *), void (*destructor)(void *), - void *(*alloc)(size_t), void (*dealloc)(void *, size_t)); - -extern _LIBCXXABI_FUNC_VIS void -__cxa_vec_ctor(void *array_address, size_t element_count, size_t element_size, - void (*constructor)(void *), void (*destructor)(void *)); - -extern _LIBCXXABI_FUNC_VIS void __cxa_vec_dtor(void *array_address, - size_t element_count, - size_t element_size, - void (*destructor)(void *)); - -extern _LIBCXXABI_FUNC_VIS void __cxa_vec_cleanup(void *array_address, - size_t element_count, - size_t element_size, - void (*destructor)(void *)); - -extern _LIBCXXABI_FUNC_VIS void __cxa_vec_delete(void *array_address, - size_t element_size, - size_t padding_size, - void (*destructor)(void *)); - -extern _LIBCXXABI_FUNC_VIS void -__cxa_vec_delete2(void *array_address, size_t element_size, size_t padding_size, - void (*destructor)(void *), void (*dealloc)(void *)); - -extern _LIBCXXABI_FUNC_VIS void -__cxa_vec_delete3(void *__array_address, size_t element_size, - size_t padding_size, void (*destructor)(void *), - void (*dealloc)(void *, size_t)); - -extern _LIBCXXABI_FUNC_VIS void -__cxa_vec_cctor(void *dest_array, void *src_array, size_t element_count, - size_t element_size, void (*constructor)(void *, void *), - void (*destructor)(void *)); - -// 3.3.5.3 Runtime API -extern _LIBCXXABI_FUNC_VIS int __cxa_atexit(void (*f)(void *), void *p, - void *d); -extern _LIBCXXABI_FUNC_VIS int __cxa_finalize(void *); - -// 3.4 Demangler API -extern _LIBCXXABI_FUNC_VIS char *__cxa_demangle(const char *mangled_name, - char *output_buffer, - size_t *length, int *status); - -// Apple additions to support C++ 0x exception_ptr class -// These are primitives to wrap a smart pointer around an exception object -extern _LIBCXXABI_FUNC_VIS void *__cxa_current_primary_exception() throw(); -extern _LIBCXXABI_FUNC_VIS void -__cxa_rethrow_primary_exception(void *primary_exception); -extern _LIBCXXABI_FUNC_VIS void -__cxa_increment_exception_refcount(void *primary_exception) throw(); -extern _LIBCXXABI_FUNC_VIS void -__cxa_decrement_exception_refcount(void *primary_exception) throw(); - -// Apple extension to support std::uncaught_exception() -extern _LIBCXXABI_FUNC_VIS bool __cxa_uncaught_exception() throw(); -extern _LIBCXXABI_FUNC_VIS unsigned int __cxa_uncaught_exceptions() throw(); - -#ifdef __linux__ -// Linux TLS support. Not yet an official part of the Itanium ABI. -// https://sourceware.org/glibc/wiki/Destructor%20support%20for%20thread_local%20variables -extern _LIBCXXABI_FUNC_VIS int __cxa_thread_atexit(void (*)(void *), void *, - void *) throw(); -#endif - -} // extern "C" -} // namespace __cxxabiv1 - -namespace abi = __cxxabiv1; - -#endif // __cplusplus - -#endif // __CXXABI_H diff --git a/chromium/buildtools/third_party/libc++abi/trunk/lib/buildit b/chromium/buildtools/third_party/libc++abi/trunk/lib/buildit deleted file mode 100755 index 5a4a71090f7..00000000000 --- a/chromium/buildtools/third_party/libc++abi/trunk/lib/buildit +++ /dev/null @@ -1,99 +0,0 @@ -#! /bin/sh -# -# Set the $TRIPLE environment variable to your system's triple before -# running this script. If you set $CXX, that will be used to compile -# the library. Otherwise we'll use clang++. - -set -e - -if [ `basename $(pwd)` != "lib" ] -then - echo "current directory must be lib" - exit 1 -fi - -if [ -z "$CXX" ] -then - CXX=clang++ -fi - -if [ -z "$CC" ] -then - CC=clang -fi - -if [ -z $RC_ProjectSourceVersion ] -then - RC_ProjectSourceVersion=1 -fi - -EXTRA_FLAGS="-std=c++11 -stdlib=libc++ -fstrict-aliasing -Wstrict-aliasing=2 \ - -Wsign-conversion -Wshadow -Wconversion -Wunused-variable \ - -Wmissing-field-initializers -Wchar-subscripts -Wmismatched-tags \ - -Wmissing-braces -Wshorten-64-to-32 -Wsign-compare \ - -Wstrict-aliasing=2 -Wstrict-overflow=4 -Wunused-parameter \ - -Wnewline-eof" - -case $TRIPLE in - *-apple-*) - if [ -z $RC_XBS ] - then - RC_CFLAGS="-arch i386 -arch x86_64" - fi - SOEXT=dylib - if [ -n "$SDKROOT" ] - then - EXTRA_FLAGS+="-isysroot ${SDKROOT}" - CXX=`xcrun -sdk "${SDKROOT}" -find clang++` - CC=`xcrun -sdk "${SDKROOT}" -find clang` - fi - LDSHARED_FLAGS="-o libc++abi.dylib \ - -dynamiclib -nodefaultlibs \ - -current_version ${RC_ProjectSourceVersion} \ - -compatibility_version 1 \ - -install_name /usr/lib/libc++abi.dylib \ - -lSystem" - if [ -f "${SDKROOT}/usr/local/lib/libCrashReporterClient.a" ] - then - LDSHARED_FLAGS+=" -lCrashReporterClient" - fi - ;; - *-*-mingw*) - # FIXME: removing libgcc and libsupc++ dependencies means porting libcxxrt and LLVM/compiler-rt - SOEXT=dll - LDSHARED_FLAGS="-o libc++abi.dll \ - -shared -nodefaultlibs -Wl,--export-all-symbols -Wl,--allow-multiple-definition -Wl,--out-implib,libc++abi.dll.a \ - -lsupc++ -lpthread -lmingw32 -lgcc_s -lgcc -lmoldname -lmingwex -lmsvcr100 -ladvapi32 -lshell32 -luser32 -lkernel32 -lmingw32 -lgcc_s -lgcc -lmoldname -lmingwex -lmsvcrt" - ;; - *) - RC_CFLAGS="-fPIC" - SOEXT=so - LDSHARED_FLAGS="-o libc++abi.so.1.0 \ - -shared -nodefaultlibs -Wl,-soname,libc++abi.so.1 \ - -lpthread -lrt -lc -lstdc++" - ;; -esac - -if [ -z $RC_XBS ] -then - rm -f libc++abi.1.$SOEXT* -fi - -set -x - -for FILE in ../src/*.cpp; do - $CXX -c -g -O3 $RC_CFLAGS $EXTRA_FLAGS -I../include $OPTIONS $FILE -done -case $TRIPLE in - *-*-mingw*) - for FILE in ../src/support/win32/*.cpp; do - $CXX -c -g -Os $RC_CFLAGS $EXTRA_FLAGS -I../include $OPTIONS $FILE - done - ;; -esac -$CC *.o $RC_CFLAGS $LDSHARED_FLAGS $EXTRA_FLAGS - -if [ -z $RC_XBS ] -then - rm *.o -fi diff --git a/chromium/buildtools/third_party/libc++abi/trunk/src/CMakeLists.txt b/chromium/buildtools/third_party/libc++abi/trunk/src/CMakeLists.txt deleted file mode 100644 index adcc412880c..00000000000 --- a/chromium/buildtools/third_party/libc++abi/trunk/src/CMakeLists.txt +++ /dev/null @@ -1,190 +0,0 @@ -# Get sources -set(LIBCXXABI_SOURCES - # C++ABI files - cxa_aux_runtime.cpp - cxa_default_handlers.cpp - cxa_demangle.cpp - cxa_exception_storage.cpp - cxa_guard.cpp - cxa_handlers.cpp - cxa_unexpected.cpp - cxa_vector.cpp - cxa_virtual.cpp - # C++ STL files - stdlib_exception.cpp - stdlib_stdexcept.cpp - stdlib_typeinfo.cpp - # Internal files - abort_message.cpp - fallback_malloc.cpp - private_typeinfo.cpp -) - -if (LIBCXXABI_ENABLE_NEW_DELETE_DEFINITIONS) - list(APPEND LIBCXXABI_SOURCES stdlib_new_delete.cpp) -endif() - -if (LIBCXXABI_ENABLE_EXCEPTIONS) - list(APPEND LIBCXXABI_SOURCES cxa_exception.cpp) - list(APPEND LIBCXXABI_SOURCES cxa_personality.cpp) -else() - list(APPEND LIBCXXABI_SOURCES cxa_noexception.cpp) -endif() - -if (LIBCXXABI_ENABLE_THREADS AND UNIX AND NOT (APPLE OR CYGWIN)) - list(APPEND LIBCXXABI_SOURCES cxa_thread_atexit.cpp) -endif() - -set(LIBCXXABI_HEADERS ../include/cxxabi.h) - -# Add all the headers to the project for IDEs. -if (MSVC_IDE OR XCODE) - # Force them all into the headers dir on MSVC, otherwise they end up at - # project scope because they don't have extensions. - if (MSVC_IDE) - source_group("Header Files" FILES ${LIBCXXABI_HEADERS}) - endif() -endif() - -include_directories("${LIBCXXABI_LIBCXX_INCLUDES}") - -if (LIBCXXABI_HAS_CXA_THREAD_ATEXIT_IMPL) - add_definitions(-DHAVE___CXA_THREAD_ATEXIT_IMPL) -endif() - -if (LIBCXXABI_ENABLE_THREADS) - add_library_flags_if(LIBCXXABI_HAS_PTHREAD_LIB pthread) -endif() - -add_library_flags_if(LIBCXXABI_HAS_C_LIB c) -if (LIBCXXABI_USE_LLVM_UNWINDER) - # Prefer using the in-tree version of libunwind, either shared or static. If - # none are found fall back to using -lunwind. - # FIXME: Is it correct to prefer the static version of libunwind? - if (NOT LIBCXXABI_ENABLE_STATIC_UNWINDER AND (TARGET unwind_shared OR HAVE_LIBUNWIND)) - list(APPEND LIBCXXABI_LIBRARIES unwind_shared) - elseif (LIBCXXABI_ENABLE_STATIC_UNWINDER AND (TARGET unwind_static OR HAVE_LIBUNWIND)) - list(APPEND LIBCXXABI_LIBRARIES unwind_static) - else() - list(APPEND LIBCXXABI_LIBRARIES unwind) - endif() -else() - add_library_flags_if(LIBCXXABI_HAS_GCC_S_LIB gcc_s) -endif() -if (MINGW) - # MINGW_LIBRARIES is defined in config-ix.cmake - list(APPEND LIBCXXABI_LIBRARIES ${MINGW_LIBRARIES}) -endif() - -# Setup flags. -add_link_flags_if_supported(-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_SHARED_LINK_FLAGS - "-compatibility_version 1" - "-current_version 1" - "-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() -endif() - -split_list(LIBCXXABI_COMPILE_FLAGS) -split_list(LIBCXXABI_LINK_FLAGS) -split_list(LIBCXXABI_SHARED_LINK_FLAGS) - -# FIXME: libc++abi.so will not link when modules are enabled because it depends -# on symbols defined in libc++.so which has not yet been built. -if (LLVM_ENABLE_MODULES) - string(REPLACE "-Wl,-z,defs" "" CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS}") -endif() - -# Add a object library that contains the compiled source files. -add_library(cxxabi_objects OBJECT ${LIBCXXABI_SOURCES} ${LIBCXXABI_HEADERS}) -set_target_properties(cxxabi_objects - PROPERTIES - CXX_EXTENSIONS - OFF - CXX_STANDARD - 11 - CXX_STANDARD_REQUIRED - ON - COMPILE_FLAGS - "${LIBCXXABI_COMPILE_FLAGS}" - POSITION_INDEPENDENT_CODE - ON) - -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 ${LIBCXXABI_LIBRARIES}) - set_target_properties(cxxabi_shared - PROPERTIES - CXX_EXTENSIONS - OFF - CXX_STANDARD - 11 - CXX_STANDARD_REQUIRED - ON - LINK_FLAGS - "${LIBCXXABI_LINK_FLAGS} ${LIBCXXABI_SHARED_LINK_FLAGS}" - OUTPUT_NAME - "c++abi" - POSITION_INDEPENDENT_CODE - ON - SOVERSION - "1" - VERSION - "1.0") - 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 ${LIBCXXABI_LIBRARIES}) - set_target_properties(cxxabi_static - PROPERTIES - CXX_EXTENSIONS - OFF - CXX_STANDARD - 11 - CXX_STANDARD_REQUIRED - ON - LINK_FLAGS - "${LIBCXXABI_LINK_FLAGS}" - OUTPUT_NAME - "c++abi" - POSITION_INDEPENDENT_CODE - ON) - 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 ${LIBCXXABI_INSTALL_PREFIX}lib${LIBCXXABI_LIBDIR_SUFFIX} COMPONENT cxxabi - ARCHIVE DESTINATION ${LIBCXXABI_INSTALL_PREFIX}lib${LIBCXXABI_LIBDIR_SUFFIX} COMPONENT cxxabi - ) - -if (NOT CMAKE_CONFIGURATION_TYPES) - add_custom_target(install-cxxabi - DEPENDS cxxabi - COMMAND "${CMAKE_COMMAND}" - -DCMAKE_INSTALL_COMPONENT=cxxabi - -P "${LIBCXXABI_BINARY_DIR}/cmake_install.cmake") - - # TODO: This is a legacy target name and should be removed at some point. - add_custom_target(install-libcxxabi DEPENDS install-cxxabi) -endif() diff --git a/chromium/buildtools/third_party/libc++abi/trunk/src/abort_message.cpp b/chromium/buildtools/third_party/libc++abi/trunk/src/abort_message.cpp deleted file mode 100644 index 7a2a9f835bd..00000000000 --- a/chromium/buildtools/third_party/libc++abi/trunk/src/abort_message.cpp +++ /dev/null @@ -1,78 +0,0 @@ -//===------------------------- abort_message.cpp --------------------------===// -// -// 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. -// -//===----------------------------------------------------------------------===// - -#include <stdlib.h> -#include <stdio.h> -#include <stdarg.h> -#include "abort_message.h" - -#ifdef __BIONIC__ -#include <android/api-level.h> -#if __ANDROID_API__ >= 21 -#include <syslog.h> -extern "C" void android_set_abort_message(const char* msg); -#else -#include <assert.h> -#endif // __ANDROID_API__ >= 21 -#endif // __BIONIC__ - -#ifdef __APPLE__ -# if defined(__has_include) && __has_include(<CrashReporterClient.h>) -# define HAVE_CRASHREPORTERCLIENT_H -# include <CrashReporterClient.h> -# endif -#endif - -void abort_message(const char* format, ...) -{ - // write message to stderr -#if !defined(NDEBUG) || !defined(LIBCXXABI_BAREMETAL) -#ifdef __APPLE__ - fprintf(stderr, "libc++abi.dylib: "); -#endif - va_list list; - va_start(list, format); - vfprintf(stderr, format, list); - va_end(list); - fprintf(stderr, "\n"); -#endif - -#if defined(__APPLE__) && defined(HAVE_CRASHREPORTERCLIENT_H) - // record message in crash report - char* buffer; - va_list list2; - va_start(list2, format); - vasprintf(&buffer, format, list2); - va_end(list2); - CRSetCrashLogMessage(buffer); -#elif defined(__BIONIC__) - char* buffer; - va_list list2; - va_start(list2, format); - vasprintf(&buffer, format, list2); - va_end(list2); - -#if __ANDROID_API__ >= 21 - // Show error in tombstone. - android_set_abort_message(buffer); - - // Show error in logcat. - openlog("libc++abi", 0, 0); - syslog(LOG_CRIT, "%s", buffer); - closelog(); -#else - // The good error reporting wasn't available in Android until L. Since we're - // about to abort anyway, just call __assert2, which will log _somewhere_ - // (tombstone and/or logcat) in older releases. - __assert2(__FILE__, __LINE__, __func__, buffer); -#endif // __ANDROID_API__ >= 21 -#endif // __BIONIC__ - - abort(); -} diff --git a/chromium/buildtools/third_party/libc++abi/trunk/src/abort_message.h b/chromium/buildtools/third_party/libc++abi/trunk/src/abort_message.h deleted file mode 100644 index e8f9571cb56..00000000000 --- a/chromium/buildtools/third_party/libc++abi/trunk/src/abort_message.h +++ /dev/null @@ -1,27 +0,0 @@ -//===-------------------------- abort_message.h-----------------------------===// -// -// 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 __ABORT_MESSAGE_H_ -#define __ABORT_MESSAGE_H_ - -#include "cxxabi.h" - -#ifdef __cplusplus -extern "C" { -#endif - -_LIBCXXABI_HIDDEN _LIBCXXABI_NORETURN void -abort_message(const char *format, ...) __attribute__((format(printf, 1, 2))); - -#ifdef __cplusplus -} -#endif - -#endif - diff --git a/chromium/buildtools/third_party/libc++abi/trunk/src/cxa_aux_runtime.cpp b/chromium/buildtools/third_party/libc++abi/trunk/src/cxa_aux_runtime.cpp deleted file mode 100644 index 878d3bd034d..00000000000 --- a/chromium/buildtools/third_party/libc++abi/trunk/src/cxa_aux_runtime.cpp +++ /dev/null @@ -1,44 +0,0 @@ -//===------------------------ cxa_aux_runtime.cpp -------------------------===// -// -// 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. -// -// -// This file implements the "Auxiliary Runtime APIs" -// http://mentorembedded.github.io/cxx-abi/abi-eh.html#cxx-aux -//===----------------------------------------------------------------------===// - -#include "cxxabi.h" -#include <new> -#include <typeinfo> - -namespace __cxxabiv1 { -extern "C" { -_LIBCXXABI_FUNC_VIS _LIBCXXABI_NORETURN void __cxa_bad_cast(void) { -#ifndef _LIBCXXABI_NO_EXCEPTIONS - throw std::bad_cast(); -#else - std::terminate(); -#endif -} - -_LIBCXXABI_FUNC_VIS _LIBCXXABI_NORETURN void __cxa_bad_typeid(void) { -#ifndef _LIBCXXABI_NO_EXCEPTIONS - throw std::bad_typeid(); -#else - std::terminate(); -#endif -} - -_LIBCXXABI_FUNC_VIS _LIBCXXABI_NORETURN void -__cxa_throw_bad_array_new_length(void) { -#ifndef _LIBCXXABI_NO_EXCEPTIONS - throw std::bad_array_new_length(); -#else - std::terminate(); -#endif -} -} // extern "C" -} // abi diff --git a/chromium/buildtools/third_party/libc++abi/trunk/src/cxa_default_handlers.cpp b/chromium/buildtools/third_party/libc++abi/trunk/src/cxa_default_handlers.cpp deleted file mode 100644 index f2e36b4bc83..00000000000 --- a/chromium/buildtools/third_party/libc++abi/trunk/src/cxa_default_handlers.cpp +++ /dev/null @@ -1,133 +0,0 @@ -//===------------------------- cxa_default_handlers.cpp -------------------===// -// -// 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. -// -// -// This file implements the default terminate_handler and unexpected_handler. -//===----------------------------------------------------------------------===// - -#include <stdexcept> -#include <new> -#include <exception> -#include <cstdlib> -#include "abort_message.h" -#include "cxxabi.h" -#include "cxa_handlers.hpp" -#include "cxa_exception.hpp" -#include "private_typeinfo.h" - -static const char* cause = "uncaught"; - -__attribute__((noreturn)) -static void demangling_terminate_handler() -{ - // If there might be an uncaught exception - using namespace __cxxabiv1; - __cxa_eh_globals* globals = __cxa_get_globals_fast(); - if (globals) - { - __cxa_exception* exception_header = globals->caughtExceptions; - // If there is an uncaught exception - if (exception_header) - { - _Unwind_Exception* unwind_exception = - reinterpret_cast<_Unwind_Exception*>(exception_header + 1) - 1; - bool native_exception = - (unwind_exception->exception_class & get_vendor_and_language) == - (kOurExceptionClass & get_vendor_and_language); - if (native_exception) - { - void* thrown_object = - unwind_exception->exception_class == kOurDependentExceptionClass ? - ((__cxa_dependent_exception*)exception_header)->primaryException : - exception_header + 1; - const __shim_type_info* thrown_type = - static_cast<const __shim_type_info*>(exception_header->exceptionType); - // Try to get demangled name of thrown_type - int status; - char buf[1024]; - size_t len = sizeof(buf); - const char* name = __cxa_demangle(thrown_type->name(), buf, &len, &status); - if (status != 0) - name = thrown_type->name(); - // If the uncaught exception can be caught with std::exception& - const __shim_type_info* catch_type = - static_cast<const __shim_type_info*>(&typeid(std::exception)); - if (catch_type->can_catch(thrown_type, thrown_object)) - { - // Include the what() message from the exception - const std::exception* e = static_cast<const std::exception*>(thrown_object); - abort_message("terminating with %s exception of type %s: %s", - cause, name, e->what()); - } - else - // Else just note that we're terminating with an exception - abort_message("terminating with %s exception of type %s", - cause, name); - } - else - // Else we're terminating with a foreign exception - abort_message("terminating with %s foreign exception", cause); - } - } - // Else just note that we're terminating - abort_message("terminating"); -} - -__attribute__((noreturn)) -static void demangling_unexpected_handler() -{ - cause = "unexpected"; - std::terminate(); -} - -#if !defined(LIBCXXABI_SILENT_TERMINATE) -static std::terminate_handler default_terminate_handler = demangling_terminate_handler; -static std::terminate_handler default_unexpected_handler = demangling_unexpected_handler; -#else -static std::terminate_handler default_terminate_handler = std::abort; -static std::terminate_handler default_unexpected_handler = std::terminate; -#endif - -// -// Global variables that hold the pointers to the current handler -// -_LIBCXXABI_DATA_VIS -std::terminate_handler __cxa_terminate_handler = default_terminate_handler; - -_LIBCXXABI_DATA_VIS -std::unexpected_handler __cxa_unexpected_handler = default_unexpected_handler; - -// In the future these will become: -// std::atomic<std::terminate_handler> __cxa_terminate_handler(default_terminate_handler); -// std::atomic<std::unexpected_handler> __cxa_unexpected_handler(default_unexpected_handler); - -namespace std -{ - -unexpected_handler -set_unexpected(unexpected_handler func) _NOEXCEPT -{ - if (func == 0) - func = default_unexpected_handler; - return __atomic_exchange_n(&__cxa_unexpected_handler, func, - __ATOMIC_ACQ_REL); -// Using of C++11 atomics this should be rewritten -// return __cxa_unexpected_handler.exchange(func, memory_order_acq_rel); -} - -terminate_handler -set_terminate(terminate_handler func) _NOEXCEPT -{ - if (func == 0) - func = default_terminate_handler; - return __atomic_exchange_n(&__cxa_terminate_handler, func, - __ATOMIC_ACQ_REL); -// Using of C++11 atomics this should be rewritten -// return __cxa_terminate_handler.exchange(func, memory_order_acq_rel); -} - -} diff --git a/chromium/buildtools/third_party/libc++abi/trunk/src/cxa_demangle.cpp b/chromium/buildtools/third_party/libc++abi/trunk/src/cxa_demangle.cpp deleted file mode 100644 index 7d173189835..00000000000 --- a/chromium/buildtools/third_party/libc++abi/trunk/src/cxa_demangle.cpp +++ /dev/null @@ -1,6158 +0,0 @@ -//===-------------------------- cxa_demangle.cpp --------------------------===// -// -// 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. -// -//===----------------------------------------------------------------------===// - -#define _LIBCPP_NO_EXCEPTIONS - -#include "__cxxabi_config.h" - -#include <vector> -#include <algorithm> -#include <numeric> -#include <cstdio> -#include <cstdlib> -#include <cstring> -#include <cctype> - -#ifdef _MSC_VER -// snprintf is implemented in VS 2015 -#if _MSC_VER < 1900 -#define snprintf _snprintf_s -#endif -#endif - -namespace __cxxabiv1 -{ - -namespace -{ - -enum -{ - unknown_error = -4, - invalid_args = -3, - invalid_mangled_name, - memory_alloc_failure, - success -}; - -class StringView { - const char *First; - const char *Last; - -public: - template <size_t N> - StringView(const char (&Str)[N]) : First(Str), Last(Str + N - 1) {} - StringView(const char *First_, const char *Last_) : First(First_), Last(Last_) {} - StringView() : First(nullptr), Last(nullptr) {} - - StringView substr(size_t From, size_t To) { - if (To >= size()) - To = size() - 1; - if (From >= size()) - From = size() - 1; - return StringView(First + From, First + To); - } - - StringView dropFront(size_t N) const { - if (N >= size()) - N = size() - 1; - return StringView(First + N, Last); - } - - bool startsWith(StringView Str) const { - if (Str.size() > size()) - return false; - return std::equal(Str.begin(), Str.end(), begin()); - } - - const char &operator[](size_t Idx) const { return *(begin() + Idx); } - - const char *begin() const { return First; } - const char *end() const { return Last; } - size_t size() const { return static_cast<size_t>(Last - First); } -}; - -bool operator==(const StringView &LHS, const StringView &RHS) { - return LHS.size() == RHS.size() && - std::equal(LHS.begin(), LHS.end(), RHS.begin()); -} - -// Stream that AST nodes write their string representation into after the AST -// has been parsed. -class OutputStream { - char *Buffer; - size_t CurrentPosition; - size_t BufferCapacity; - - // Ensure there is at least n more positions in buffer. - void grow(size_t N) { - if (N + CurrentPosition >= BufferCapacity) { - BufferCapacity *= 2; - if (BufferCapacity < N + CurrentPosition) - BufferCapacity = N + CurrentPosition; - Buffer = static_cast<char *>(std::realloc(Buffer, BufferCapacity)); - } - } - -public: - OutputStream(char *StartBuf, size_t Size) - : Buffer(StartBuf), CurrentPosition(0), BufferCapacity(Size) {} - - OutputStream &operator+=(StringView R) { - size_t Size = R.size(); - if (Size == 0) - return *this; - grow(Size); - memmove(Buffer + CurrentPosition, R.begin(), Size); - CurrentPosition += Size; - return *this; - } - - OutputStream &operator+=(char C) { - grow(1); - Buffer[CurrentPosition++] = C; - return *this; - } - - // Offset of position in buffer, used for building stream_string_view. - typedef unsigned StreamPosition; - - // StringView into a stream, used for caching the ast nodes. - class StreamStringView { - StreamPosition First, Last; - - friend class OutputStream; - - public: - StreamStringView() : First(0), Last(0) {} - - StreamStringView(StreamPosition First_, StreamPosition Last_) - : First(First_), Last(Last_) {} - - bool empty() const { return First == Last; } - }; - - OutputStream &operator+=(StreamStringView &s) { - size_t Sz = static_cast<size_t>(s.Last - s.First); - if (Sz == 0) - return *this; - grow(Sz); - memmove(Buffer + CurrentPosition, Buffer + s.First, Sz); - CurrentPosition += Sz; - return *this; - } - - StreamPosition getCurrentPosition() const { - return static_cast<StreamPosition>(CurrentPosition); - } - - StreamStringView makeStringViewFromPastPosition(StreamPosition Pos) { - return StreamStringView(Pos, getCurrentPosition()); - } - - char back() const { - return CurrentPosition ? Buffer[CurrentPosition - 1] : '\0'; - } - - bool empty() const { return CurrentPosition == 0; } - - char *getBuffer() { return Buffer; } - char *getBufferEnd() { return Buffer + CurrentPosition - 1; } - size_t getBufferCapacity() { return BufferCapacity; } -}; - -// Base class of all AST nodes. The AST is built by the parser, then is -// traversed by the printLeft/Right functions to produce a demangled string. -class Node { -public: - enum Kind : unsigned char { - KDotSuffix, - KVendorExtQualType, - KQualType, - KConversionOperatorType, - KPostfixQualifiedType, - KNameType, - KObjCProtoName, - KPointerType, - KLValueReferenceType, - KRValueReferenceType, - KPointerToMemberType, - KArrayType, - KFunctionType, - KTopLevelFunctionDecl, - KFunctionQualType, - KFunctionRefQualType, - KLiteralOperator, - KSpecialName, - KCtorVtableSpecialName, - KQualifiedName, - KEmptyName, - KVectorType, - KTemplateParams, - KNameWithTemplateArgs, - KGlobalQualifiedName, - KStdQualifiedName, - KExpandedSpecialSubstitution, - KSpecialSubstitution, - KCtorDtorName, - KDtorName, - KUnnamedTypeName, - KLambdaTypeName, - KExpr, - }; - - const Kind K; - -private: - // If this Node has any RHS part, potentally many Nodes further down. - const unsigned HasRHSComponent : 1; - const unsigned HasFunction : 1; - const unsigned HasArray : 1; - -public: - Node(Kind K_, bool HasRHS_ = false, bool HasFunction_ = false, - bool HasArray_ = false) - : K(K_), HasRHSComponent(HasRHS_), HasFunction(HasFunction_), - HasArray(HasArray_) {} - - bool hasRHSComponent() const { return HasRHSComponent; } - bool hasArray() const { return HasArray; } - bool hasFunction() const { return HasFunction; } - - void print(OutputStream &s) const { - printLeft(s); - if (hasRHSComponent()) - printRight(s); - } - - // Print the "left" side of this Node into OutputStream. - virtual void printLeft(OutputStream &) const = 0; - - // Print the "right". This distinction is necessary to represent C++ types - // that appear on the RHS of their subtype, such as arrays or functions. - // Since most types don't have such a component, provide a default - // implemenation. - virtual void printRight(OutputStream &) const {} - - virtual StringView getBaseName() const { return StringView(); } - - // Silence compiler warnings, this dtor will never be called. - virtual ~Node() = default; -}; - -class NodeArray { - Node **Elements; - size_t NumElements; - -public: - NodeArray() : NumElements(0) {} - NodeArray(Node **Elements_, size_t NumElements_) - : Elements(Elements_), NumElements(NumElements_) {} - - bool empty() const { return NumElements == 0; } - size_t size() const { return NumElements; } - - void printWithSeperator(OutputStream &S, StringView Seperator) const { - for (size_t Idx = 0; Idx != NumElements; ++Idx) { - if (Idx) - S += Seperator; - Elements[Idx]->print(S); - } - } -}; - -class DotSuffix final : public Node { - const Node *Prefix; - const StringView Suffix; - -public: - DotSuffix(Node *Prefix_, StringView Suffix_) - : Node(KDotSuffix), Prefix(Prefix_), Suffix(Suffix_) {} - - void printLeft(OutputStream &s) const override { - Prefix->print(s); - s += " ("; - s += Suffix; - s += ")"; - } -}; - -class VendorExtQualType final : public Node { - const Node *Ext; - const Node *Ty; - -public: - VendorExtQualType(Node *Ext_, Node *Ty_) - : Node(KVendorExtQualType), Ext(Ext_), Ty(Ty_) {} - - void printLeft(OutputStream &S) const override { - Ext->print(S); - S += " "; - Ty->printLeft(S); - } - - void printRight(OutputStream &S) const override { Ty->printRight(S); } -}; - -enum Qualifiers { - QualNone = 0, - QualConst = 0x1, - QualVolatile = 0x2, - QualRestrict = 0x4, -}; - -void addQualifiers(Qualifiers &Q1, Qualifiers Q2) { - Q1 = static_cast<Qualifiers>(Q1 | Q2); -} - -class QualType : public Node { -protected: - const Qualifiers Quals; - const Node *Child; - - void printQuals(OutputStream &S) const { - if (Quals & QualConst) - S += " const"; - if (Quals & QualVolatile) - S += " volatile"; - if (Quals & QualRestrict) - S += " restrict"; - } - -public: - QualType(Node *Child_, Qualifiers Quals_) - : Node(KQualType, Child_->hasRHSComponent(), Child_->hasFunction(), - Child_->hasArray()), - Quals(Quals_), Child(Child_) {} - - QualType(Node::Kind ChildKind_, Node *Child_, Qualifiers Quals_) - : Node(ChildKind_, Child_->hasRHSComponent(), Child_->hasFunction(), - Child_->hasArray()), - Quals(Quals_), Child(Child_) {} - - void printLeft(OutputStream &S) const override { - Child->printLeft(S); - printQuals(S); - } - - void printRight(OutputStream &S) const override { Child->printRight(S); } -}; - -class ConversionOperatorType final : public Node { - const Node *Ty; - -public: - ConversionOperatorType(Node *Ty_) : Node(KConversionOperatorType), Ty(Ty_) {} - - void printLeft(OutputStream &S) const override { - S += "operator "; - Ty->print(S); - } -}; - -class PostfixQualifiedType final : public Node { - const Node *Ty; - const StringView Postfix; - -public: - PostfixQualifiedType(Node *Ty_, StringView Postfix_) - : Node(KPostfixQualifiedType), Ty(Ty_), Postfix(Postfix_) {} - - void printLeft(OutputStream &s) const override { - Ty->printLeft(s); - s += Postfix; - } - - void printRight(OutputStream &S) const override { Ty->printRight(S); } -}; - -class NameType final : public Node { - const StringView Name; - -public: - NameType(StringView Name_) : Node(KNameType), Name(Name_) {} - - StringView getName() const { return Name; } - StringView getBaseName() const override { return Name; } - - void printLeft(OutputStream &s) const override { s += Name; } -}; - -class ObjCProtoName : public Node { - Node *Ty; - Node *Protocol; - - friend class PointerType; - -public: - ObjCProtoName(Node *Ty_, Node *Protocol_) - : Node(KObjCProtoName), Ty(Ty_), Protocol(Protocol_) {} - - bool isObjCObject() const { - return Ty->K == KNameType && - static_cast<NameType *>(Ty)->getName() == "objc_object"; - } - - void printLeft(OutputStream &S) const override { - Ty->printLeft(S); - S += "<"; - Protocol->printLeft(S); - S += ">"; - } -}; - -class PointerType final : public Node { - const Node *Pointee; - -public: - PointerType(Node *Pointee_) - : Node(KPointerType, Pointee_->hasRHSComponent()), Pointee(Pointee_) {} - - void printLeft(OutputStream &s) const override { - // We rewrite objc_object<SomeProtocol>* into id<SomeProtocol>. - if (Pointee->K != KObjCProtoName || - !static_cast<const ObjCProtoName *>(Pointee)->isObjCObject()) { - Pointee->printLeft(s); - if (Pointee->hasArray()) - s += " "; - if (Pointee->hasArray() || Pointee->hasFunction()) - s += "("; - s += "*"; - } else { - const auto *objcProto = static_cast<const ObjCProtoName *>(Pointee); - s += "id<"; - objcProto->Protocol->print(s); - s += ">"; - } - } - - void printRight(OutputStream &s) const override { - if (Pointee->K != KObjCProtoName || - !static_cast<const ObjCProtoName *>(Pointee)->isObjCObject()) { - if (Pointee->hasArray() || Pointee->hasFunction()) - s += ")"; - Pointee->printRight(s); - } - } -}; - -class LValueReferenceType final : public Node { - const Node *Pointee; - -public: - LValueReferenceType(Node *Pointee_) - : Node(KLValueReferenceType, Pointee_->hasRHSComponent()), - Pointee(Pointee_) {} - - void printLeft(OutputStream &s) const override { - Pointee->printLeft(s); - if (Pointee->hasArray()) - s += " "; - if (Pointee->hasArray() || Pointee->hasFunction()) - s += "(&"; - else - s += "&"; - } - void printRight(OutputStream &s) const override { - if (Pointee->hasArray() || Pointee->hasFunction()) - s += ")"; - Pointee->printRight(s); - } -}; - -class RValueReferenceType final : public Node { - const Node *Pointee; - -public: - RValueReferenceType(Node *Pointee_) - : Node(KRValueReferenceType, Pointee_->hasRHSComponent()), - Pointee(Pointee_) {} - - void printLeft(OutputStream &s) const override { - Pointee->printLeft(s); - if (Pointee->hasArray()) - s += " "; - if (Pointee->hasArray() || Pointee->hasFunction()) - s += "(&&"; - else - s += "&&"; - } - - void printRight(OutputStream &s) const override { - if (Pointee->hasArray() || Pointee->hasFunction()) - s += ")"; - Pointee->printRight(s); - } -}; - -class PointerToMemberType final : public Node { - const Node *ClassType; - const Node *MemberType; - -public: - PointerToMemberType(Node *ClassType_, Node *MemberType_) - : Node(KPointerToMemberType, MemberType_->hasRHSComponent()), - ClassType(ClassType_), MemberType(MemberType_) {} - - void printLeft(OutputStream &s) const override { - MemberType->printLeft(s); - if (MemberType->hasArray() || MemberType->hasFunction()) - s += "("; - else - s += " "; - ClassType->print(s); - s += "::*"; - } - - void printRight(OutputStream &s) const override { - if (MemberType->hasArray() || MemberType->hasFunction()) - s += ")"; - MemberType->printRight(s); - } -}; - -class NodeOrString { - const void *First; - const void *Second; - -public: - /* implicit */ NodeOrString(StringView Str) { - const char *FirstChar = Str.begin(); - const char *SecondChar = Str.end(); - if (SecondChar == nullptr) { - assert(FirstChar == SecondChar); - ++FirstChar, ++SecondChar; - } - First = static_cast<const void *>(FirstChar); - Second = static_cast<const void *>(SecondChar); - } - - /* implicit */ NodeOrString(Node *N) - : First(static_cast<const void *>(N)), Second(nullptr) {} - NodeOrString() : First(nullptr), Second(nullptr) {} - - bool isString() const { return Second && First; } - bool isNode() const { return First && !Second; } - bool isEmpty() const { return !First && !Second; } - - StringView asString() const { - assert(isString()); - return StringView(static_cast<const char *>(First), - static_cast<const char *>(Second)); - } - - const Node *asNode() const { - assert(isNode()); - return static_cast<const Node *>(First); - } -}; - -class ArrayType final : public Node { - Node *Base; - NodeOrString Dimension; - -public: - ArrayType(Node *Base_, NodeOrString Dimension_) - : Node(KArrayType, true, false, true), Base(Base_), Dimension(Dimension_) {} - - // Incomplete array type. - ArrayType(Node *Base_) : Node(KArrayType, true, false, true), Base(Base_) {} - - void printLeft(OutputStream &S) const override { Base->printLeft(S); } - - void printRight(OutputStream &S) const override { - if (S.back() != ']') - S += " "; - S += "["; - if (Dimension.isString()) - S += Dimension.asString(); - else if (Dimension.isNode()) - Dimension.asNode()->print(S); - S += "]"; - Base->printRight(S); - } -}; - -class FunctionType final : public Node { - Node *Ret; - NodeArray Params; - -public: - FunctionType(Node *Ret_, NodeArray Params_) - : Node(KFunctionType, true, true), Ret(Ret_), Params(Params_) {} - - // Handle C++'s ... quirky decl grammer by using the left & right - // distinction. Consider: - // int (*f(float))(char) {} - // f is a function that takes a float and returns a pointer to a function - // that takes a char and returns an int. If we're trying to print f, start - // by printing out the return types's left, then print our parameters, then - // finally print right of the return type. - void printLeft(OutputStream &S) const override { - Ret->printLeft(S); - S += " "; - } - - void printRight(OutputStream &S) const override { - S += "("; - Params.printWithSeperator(S, ", "); - S += ")"; - Ret->printRight(S); - } -}; - -class TopLevelFunctionDecl final : public Node { - const Node *Ret; - const Node *Name; - NodeArray Params; - -public: - TopLevelFunctionDecl(Node *Ret_, Node *Name_, NodeArray Params_) - : Node(KTopLevelFunctionDecl, true, true), Ret(Ret_), Name(Name_), - Params(Params_) {} - - void printLeft(OutputStream &S) const override { - if (Ret) { - Ret->printLeft(S); - if (!Ret->hasRHSComponent()) - S += " "; - } - Name->print(S); - } - - void printRight(OutputStream &S) const override { - S += "("; - Params.printWithSeperator(S, ", "); - S += ")"; - if (Ret) - Ret->printRight(S); - } -}; - -enum FunctionRefQual : unsigned char { - FrefQualNone, - FrefQualLValue, - FrefQualRValue, -}; - -class FunctionRefQualType : public Node { - Node *Fn; - FunctionRefQual Quals; - - friend class FunctionQualType; - -public: - FunctionRefQualType(Node *Fn_, FunctionRefQual Quals_) - : Node(KFunctionRefQualType, true, true), Fn(Fn_), Quals(Quals_) {} - - void printQuals(OutputStream &S) const { - if (Quals == FrefQualLValue) - S += " &"; - else - S += " &&"; - } - - void printLeft(OutputStream &S) const override { Fn->printLeft(S); } - - void printRight(OutputStream &S) const override { - Fn->printRight(S); - printQuals(S); - } -}; - -class FunctionQualType final : public QualType { -public: - FunctionQualType(Node *Child_, Qualifiers Quals_) - : QualType(KFunctionQualType, Child_, Quals_) {} - - void printLeft(OutputStream &S) const override { Child->printLeft(S); } - - void printRight(OutputStream &S) const override { - if (Child->K == KFunctionRefQualType) { - auto *RefQuals = static_cast<const FunctionRefQualType *>(Child); - RefQuals->Fn->printRight(S); - printQuals(S); - RefQuals->printQuals(S); - } else { - Child->printRight(S); - printQuals(S); - } - } -}; - -class LiteralOperator : public Node { - const Node *OpName; - -public: - LiteralOperator(Node *OpName_) : Node(KLiteralOperator), OpName(OpName_) {} - - void printLeft(OutputStream &S) const override { - S += "operator\"\" "; - OpName->print(S); - } -}; - -class SpecialName final : public Node { - const StringView Special; - const Node *Child; - -public: - SpecialName(StringView Special_, Node *Child_) - : Node(KSpecialName), Special(Special_), Child(Child_) {} - - void printLeft(OutputStream &S) const override { - S += Special; - Child->print(S); - } -}; - -class CtorVtableSpecialName final : public Node { - const Node *FirstType; - const Node *SecondType; - -public: - CtorVtableSpecialName(Node *FirstType_, Node *SecondType_) - : Node(KCtorVtableSpecialName), FirstType(FirstType_), - SecondType(SecondType_) {} - - void printLeft(OutputStream &S) const override { - S += "construction vtable for "; - FirstType->print(S); - S += "-in-"; - SecondType->print(S); - } -}; - -class QualifiedName final : public Node { - // qualifier::name - const Node *Qualifier; - const Node *Name; - - mutable OutputStream::StreamStringView Cache; - -public: - QualifiedName(Node *Qualifier_, Node *Name_) - : Node(KQualifiedName), Qualifier(Qualifier_), Name(Name_) {} - - StringView getBaseName() const override { return Name->getBaseName(); } - - void printLeft(OutputStream &S) const override { - if (!Cache.empty()) { - S += Cache; - return; - } - - OutputStream::StreamPosition Start = S.getCurrentPosition(); - if (Qualifier->K != KEmptyName) { - Qualifier->print(S); - S += "::"; - } - Name->print(S); - Cache = S.makeStringViewFromPastPosition(Start); - } -}; - -class EmptyName : public Node { -public: - EmptyName() : Node(KEmptyName) {} - void printLeft(OutputStream &) const override {} -}; - -class VectorType final : public Node { - const Node *BaseType; - const NodeOrString Dimension; - const bool IsPixel; - -public: - VectorType(NodeOrString Dimension_) - : Node(KVectorType), BaseType(nullptr), Dimension(Dimension_), - IsPixel(true) {} - VectorType(Node *BaseType_, NodeOrString Dimension_) - : Node(KVectorType), BaseType(BaseType_), Dimension(Dimension_), - IsPixel(false) {} - - void printLeft(OutputStream &S) const override { - if (IsPixel) { - S += "pixel vector["; - S += Dimension.asString(); - S += "]"; - } else { - BaseType->print(S); - S += " vector["; - if (Dimension.isNode()) - Dimension.asNode()->print(S); - else if (Dimension.isString()) - S += Dimension.asString(); - S += "]"; - } - } -}; - -class TemplateParams final : public Node { - NodeArray Params; - - mutable OutputStream::StreamStringView Cache; - -public: - TemplateParams(NodeArray Params_) : Node(KTemplateParams), Params(Params_) {} - - void printLeft(OutputStream &S) const override { - if (!Cache.empty()) { - S += Cache; - return; - } - - OutputStream::StreamPosition Start = S.getCurrentPosition(); - - S += "<"; - Params.printWithSeperator(S, ", "); - if (S.back() == '>') - S += " "; - S += ">"; - - Cache = S.makeStringViewFromPastPosition(Start); - } -}; - -class NameWithTemplateArgs final : public Node { - // name<template_args> - Node *Name; - Node *TemplateArgs; - -public: - NameWithTemplateArgs(Node *Name_, Node *TemplateArgs_) - : Node(KNameWithTemplateArgs), Name(Name_), TemplateArgs(TemplateArgs_) {} - - StringView getBaseName() const override { return Name->getBaseName(); } - - void printLeft(OutputStream &S) const override { - Name->print(S); - TemplateArgs->print(S); - } -}; - -class GlobalQualifiedName final : public Node { - Node *Child; - -public: - GlobalQualifiedName(Node *Child_) : Node(KGlobalQualifiedName), Child(Child_) {} - - StringView getBaseName() const override { return Child->getBaseName(); } - - void printLeft(OutputStream &S) const override { - S += "::"; - Child->print(S); - } -}; - -class StdQualifiedName final : public Node { - Node *Child; - -public: - StdQualifiedName(Node *Child_) : Node(KStdQualifiedName), Child(Child_) {} - - StringView getBaseName() const override { return Child->getBaseName(); } - - void printLeft(OutputStream &S) const override { - S += "std::"; - Child->print(S); - } -}; - -enum class SpecialSubKind { - allocator, - basic_string, - string, - istream, - ostream, - iostream, -}; - -class ExpandedSpecialSubstitution final : public Node { - SpecialSubKind SSK; - -public: - ExpandedSpecialSubstitution(SpecialSubKind SSK_) - : Node(KExpandedSpecialSubstitution), SSK(SSK_) {} - - StringView getBaseName() const override { - switch (SSK) { - case SpecialSubKind::allocator: - return StringView("allocator"); - case SpecialSubKind::basic_string: - return StringView("basic_string"); - case SpecialSubKind::string: - return StringView("basic_string"); - case SpecialSubKind::istream: - return StringView("basic_istream"); - case SpecialSubKind::ostream: - return StringView("basic_ostream"); - case SpecialSubKind::iostream: - return StringView("basic_iostream"); - } - _LIBCPP_UNREACHABLE(); - } - - void printLeft(OutputStream &S) const override { - switch (SSK) { - case SpecialSubKind::allocator: - S += "std::basic_string<char, std::char_traits<char>, " - "std::allocator<char> >"; - break; - case SpecialSubKind::basic_string: - case SpecialSubKind::string: - S += "std::basic_string<char, std::char_traits<char>, " - "std::allocator<char> >"; - break; - case SpecialSubKind::istream: - S += "std::basic_istream<char, std::char_traits<char> >"; - break; - case SpecialSubKind::ostream: - S += "std::basic_ostream<char, std::char_traits<char> >"; - break; - case SpecialSubKind::iostream: - S += "std::basic_iostream<char, std::char_traits<char> >"; - break; - } - } -}; - -class SpecialSubstitution final : public Node { -public: - SpecialSubKind SSK; - - SpecialSubstitution(SpecialSubKind SSK_) - : Node(KSpecialSubstitution), SSK(SSK_) {} - - StringView getBaseName() const override { - switch (SSK) { - case SpecialSubKind::allocator: - return StringView("allocator"); - case SpecialSubKind::basic_string: - return StringView("basic_string"); - case SpecialSubKind::string: - return StringView("string"); - case SpecialSubKind::istream: - return StringView("istream"); - case SpecialSubKind::ostream: - return StringView("ostream"); - case SpecialSubKind::iostream: - return StringView("iostream"); - } - _LIBCPP_UNREACHABLE(); - } - - void printLeft(OutputStream &S) const override { - switch (SSK) { - case SpecialSubKind::allocator: - S += "std::allocator"; - break; - case SpecialSubKind::basic_string: - S += "std::basic_string"; - break; - case SpecialSubKind::string: - S += "std::string"; - break; - case SpecialSubKind::istream: - S += "std::istream"; - break; - case SpecialSubKind::ostream: - S += "std::ostream"; - break; - case SpecialSubKind::iostream: - S += "std::iostream"; - break; - } - } -}; - -class CtorDtorName final : public Node { - const Node *Basename; - const bool IsDtor; - -public: - CtorDtorName(Node *Basename_, bool IsDtor_) - : Node(KCtorDtorName), Basename(Basename_), IsDtor(IsDtor_) {} - - void printLeft(OutputStream &S) const override { - if (IsDtor) - S += "~"; - S += Basename->getBaseName(); - } -}; - -class DtorName : public Node { - const Node *Base; - -public: - DtorName(Node *Base_) : Node(KDtorName), Base(Base_) {} - - void printLeft(OutputStream &S) const override { - S += "~"; - Base->printLeft(S); - } -}; - -class UnnamedTypeName : public Node { - const StringView Count; - -public: - UnnamedTypeName(StringView Count_) : Node(KUnnamedTypeName), Count(Count_) {} - - void printLeft(OutputStream &S) const override { - S += "'unnamed"; - S += Count; - S += "\'"; - } -}; - -class LambdaTypeName : public Node { - NodeArray Params; - StringView Count; - -public: - LambdaTypeName(NodeArray Params_, StringView Count_) - : Node(KLambdaTypeName), Params(Params_), Count(Count_) {} - - void printLeft(OutputStream &S) const override { - S += "\'lambda"; - S += Count; - S += "\'("; - Params.printWithSeperator(S, ", "); - S += ")"; - } -}; - -// -- Expression Nodes -- - -struct Expr : public Node { - Expr() : Node(KExpr) {} -}; - -class BinaryExpr : public Expr { - const Node *LHS; - const StringView InfixOperator; - const Node *RHS; - -public: - BinaryExpr(Node *LHS_, StringView InfixOperator_, Node *RHS_) - : LHS(LHS_), InfixOperator(InfixOperator_), RHS(RHS_) {} - - void printLeft(OutputStream &S) const override { - // might be a template argument expression, then we need to disambiguate - // with parens. - if (InfixOperator == ">") - S += "("; - - S += "("; - LHS->print(S); - S += ") "; - S += InfixOperator; - S += " ("; - RHS->print(S); - S += ")"; - - if (InfixOperator == ">") - S += ")"; - } -}; - -class ArraySubscriptExpr : public Expr { - const Node *Op1; - const Node *Op2; - -public: - ArraySubscriptExpr(Node *Op1_, Node *Op2_) : Op1(Op1_), Op2(Op2_) {} - - void printLeft(OutputStream &S) const override { - S += "("; - Op1->print(S); - S += ")["; - Op2->print(S); - S += "]"; - } -}; - -class PostfixExpr : public Expr { - const Node *Child; - const StringView Operand; - -public: - PostfixExpr(Node *Child_, StringView Operand_) - : Child(Child_), Operand(Operand_) {} - - void printLeft(OutputStream &S) const override { - S += "("; - Child->print(S); - S += ")"; - S += Operand; - } -}; - -class ConditionalExpr : public Expr { - const Node *Cond; - const Node *Then; - const Node *Else; - -public: - ConditionalExpr(Node *Cond_, Node *Then_, Node *Else_) - : Cond(Cond_), Then(Then_), Else(Else_) {} - - void printLeft(OutputStream &S) const override { - S += "("; - Cond->print(S); - S += ") ? ("; - Then->print(S); - S += ") : ("; - Else->print(S); - S += ")"; - } -}; - -class MemberExpr : public Expr { - const Node *LHS; - const StringView Kind; - const Node *RHS; - -public: - MemberExpr(Node *LHS_, StringView Kind_, Node *RHS_) - : LHS(LHS_), Kind(Kind_), RHS(RHS_) {} - - void printLeft(OutputStream &S) const override { - LHS->print(S); - S += Kind; - RHS->print(S); - } -}; - -class EnclosingExpr : public Expr { - const StringView Prefix; - const Node *Infix; - const StringView Postfix; - -public: - EnclosingExpr(StringView Prefix_, Node *Infix_, StringView Postfix_) - : Prefix(Prefix_), Infix(Infix_), Postfix(Postfix_) {} - - void printLeft(OutputStream &S) const override { - S += Prefix; - Infix->print(S); - S += Postfix; - } -}; - -class CastExpr : public Expr { - // cast_kind<to>(from) - const StringView CastKind; - const Node *To; - const Node *From; - -public: - CastExpr(StringView CastKind_, Node *To_, Node *From_) - : CastKind(CastKind_), To(To_), From(From_) {} - - void printLeft(OutputStream &S) const override { - S += CastKind; - S += "<"; - To->printLeft(S); - S += ">("; - From->printLeft(S); - S += ")"; - } -}; - -class SizeofParamPackExpr : public Expr { - NodeArray Args; - -public: - SizeofParamPackExpr(NodeArray Args_) : Args(Args_) {} - - void printLeft(OutputStream &S) const override { - S += "sizeof...("; - Args.printWithSeperator(S, ", "); - S += ")"; - } -}; - -class CallExpr : public Expr { - const Node *Callee; - NodeArray Args; - -public: - CallExpr(Node *Callee_, NodeArray Args_) : Callee(Callee_), Args(Args_) {} - - void printLeft(OutputStream &S) const override { - Callee->print(S); - S += "("; - Args.printWithSeperator(S, ", "); - S += ")"; - } -}; - -class NewExpr : public Expr { - // new (expr_list) type(init_list) - NodeArray ExprList; - Node *Type; - NodeArray InitList; - bool IsGlobal; // ::operator new ? - bool IsArray; // new[] ? -public: - NewExpr(NodeArray ExprList_, Node *Type_, NodeArray InitList_, bool IsGlobal_, - bool IsArray_) - : ExprList(ExprList_), Type(Type_), InitList(InitList_), IsGlobal(IsGlobal_), - IsArray(IsArray_) {} - - void printLeft(OutputStream &S) const override { - if (IsGlobal) - S += "::operator "; - S += "new"; - if (IsArray) - S += "[]"; - if (!ExprList.empty()) { - S += "("; - ExprList.printWithSeperator(S, ", "); - S += ")"; - } - Type->print(S); - if (!InitList.empty()) { - S += "("; - InitList.printWithSeperator(S, ", "); - S += ")"; - } - } -}; - -class DeleteExpr : public Expr { - Node *Op; - bool IsGlobal; - bool IsArray; - -public: - DeleteExpr(Node *Op_, bool IsGlobal_, bool IsArray_) - : Op(Op_), IsGlobal(IsGlobal_), IsArray(IsArray_) {} - - void printLeft(OutputStream &S) const override { - if (IsGlobal) - S += "::"; - S += "delete"; - if (IsArray) - S += "[] "; - Op->print(S); - } -}; - -class PrefixExpr : public Expr { - StringView Prefix; - Node *Child; - -public: - PrefixExpr(StringView Prefix_, Node *Child_) : Prefix(Prefix_), Child(Child_) {} - - void printLeft(OutputStream &S) const override { - S += Prefix; - S += "("; - Child->print(S); - S += ")"; - } -}; - -class FunctionParam : public Expr { - StringView Number; - -public: - FunctionParam(StringView Number_) : Number(Number_) {} - - void printLeft(OutputStream &S) const override { - S += "fp"; - S += Number; - } -}; - -class ExprList : public Expr { - NodeArray SubExprs; - -public: - ExprList(NodeArray SubExprs_) : SubExprs(SubExprs_) {} - - void printLeft(OutputStream &S) const override { - S += "("; - SubExprs.printWithSeperator(S, ", "); - S += ")"; - } -}; - -class ConversionExpr : public Expr { - NodeArray Expressions; - NodeArray Types; - -public: - ConversionExpr(NodeArray Expressions_, NodeArray Types_) - : Expressions(Expressions_), Types(Types_) {} - - void printLeft(OutputStream &S) const override { - S += "("; - Expressions.printWithSeperator(S, ", "); - S += ")("; - Types.printWithSeperator(S, ", "); - S += ")"; - } -}; - -class ThrowExpr : public Expr { - const Node *Op; - -public: - ThrowExpr(Node *Op_) : Op(Op_) {} - - void printLeft(OutputStream &S) const override { - S += "throw "; - Op->print(S); - } -}; - -class BoolExpr : public Expr { - bool Value; - -public: - BoolExpr(bool Value_) : Value(Value_) {} - - void printLeft(OutputStream &S) const override { - S += Value ? StringView("true") : StringView("false"); - } -}; - -class IntegerCastExpr : public Expr { - // ty(integer) - Node *Ty; - StringView Integer; - -public: - IntegerCastExpr(Node *Ty_, StringView Integer_) : Ty(Ty_), Integer(Integer_) {} - - void printLeft(OutputStream &S) const override { - S += "("; - Ty->print(S); - S += ")"; - S += Integer; - } -}; - -class IntegerExpr : public Expr { - StringView Type; - StringView Value; - -public: - IntegerExpr(StringView Type_, StringView Value_) : Type(Type_), Value(Value_) {} - - void printLeft(OutputStream &S) const override { - if (Type.size() > 3) { - S += "("; - S += Type; - S += ")"; - } - - if (Value[0] == 'n') { - S += "-"; - S += Value.dropFront(1); - } else - S += Value; - - if (Type.size() <= 3) - S += Type; - } -}; - -template <class Float> struct FloatData; - -template <class Float> class FloatExpr : public Expr { - const StringView Contents; - -public: - FloatExpr(StringView Contents_) : Contents(Contents_) {} - - void printLeft(OutputStream &s) const override { - const char *first = Contents.begin(); - const char *last = Contents.end() + 1; - - const size_t N = FloatData<Float>::mangled_size; - if (static_cast<std::size_t>(last - first) > N) { - last = first + N; - union { - Float value; - char buf[sizeof(Float)]; - }; - const char *t = first; - char *e = buf; - for (; t != last; ++t, ++e) { - unsigned d1 = isdigit(*t) ? static_cast<unsigned>(*t - '0') - : static_cast<unsigned>(*t - 'a' + 10); - ++t; - unsigned d0 = isdigit(*t) ? static_cast<unsigned>(*t - '0') - : static_cast<unsigned>(*t - 'a' + 10); - *e = static_cast<char>((d1 << 4) + d0); - } -#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ - std::reverse(buf, e); -#endif - char num[FloatData<Float>::max_demangled_size] = {0}; - int n = snprintf(num, sizeof(num), FloatData<Float>::spec, value); - s += StringView(num, num + n); - } - } -}; - -class BumpPointerAllocator { - struct BlockMeta { - BlockMeta* Next; - size_t Current; - }; - - static constexpr size_t AllocSize = 4096; - static constexpr size_t UsableAllocSize = AllocSize - sizeof(BlockMeta); - - alignas(16) char InitialBuffer[AllocSize]; - BlockMeta* BlockList = nullptr; - - void grow() { - char* NewMeta = new char[AllocSize]; - BlockList = new (NewMeta) BlockMeta{BlockList, 0}; - } - - void* allocateMassive(size_t NBytes) { - NBytes += sizeof(BlockMeta); - BlockMeta* NewMeta = reinterpret_cast<BlockMeta*>(new char[NBytes]); - BlockList->Next = new (NewMeta) BlockMeta{BlockList->Next, 0}; - return static_cast<void*>(NewMeta + 1); - } - -public: - BumpPointerAllocator() - : BlockList(new (InitialBuffer) BlockMeta{nullptr, 0}) {} - - void* allocate(size_t N) { - N = (N + 15u) & ~15u; - if (N + BlockList->Current >= UsableAllocSize) { - if (N > UsableAllocSize) - return allocateMassive(N); - grow(); - } - BlockList->Current += N; - return static_cast<void*>(reinterpret_cast<char*>(BlockList + 1) + - BlockList->Current - N); - } - - ~BumpPointerAllocator() { - while (BlockList) { - BlockMeta* Tmp = BlockList; - BlockList = BlockList->Next; - if (reinterpret_cast<char*>(Tmp) != InitialBuffer) - delete[] reinterpret_cast<char*>(Tmp); - } - } -}; - -template <class T, size_t N> -class PODSmallVector { - static_assert(std::is_pod<T>::value, - "T is required to be a plain old data type"); - - T* First; - T* Last; - T* Cap; - T Inline[N]; - - bool isInline() const { return First == Inline; } - - void clearInline() { - First = Inline; - Last = Inline; - Cap = Inline + N; - } - - void reserve(size_t NewCap) { - size_t S = size(); - if (isInline()) { - auto* Tmp = static_cast<T*>(std::malloc(NewCap * sizeof(T))); - std::copy(First, Last, Tmp); - First = Tmp; - } else - First = static_cast<T*>(std::realloc(First, NewCap * sizeof(T))); - Last = First + S; - Cap = First + NewCap; - } - -public: - PODSmallVector() : First(Inline), Last(First), Cap(Inline + N) {} - - PODSmallVector(const PODSmallVector&) = delete; - PODSmallVector& operator=(const PODSmallVector&) = delete; - - PODSmallVector(PODSmallVector&& Other) : PODSmallVector() { - if (Other.isInline()) { - std::copy(Other.begin(), Other.end(), First); - Last = First + Other.size(); - Other.clear(); - return; - } - - First = Other.First; - Last = Other.Last; - Cap = Other.Cap; - Other.clearInline(); - } - - PODSmallVector& operator=(PODSmallVector&& Other) { - if (Other.isInline()) { - if (!isInline()) { - std::free(First); - clearInline(); - } - std::copy(Other.begin(), Other.end(), First); - Last = First + Other.size(); - Other.clear(); - return *this; - } - - if (isInline()) { - First = Other.First; - Last = Other.Last; - Cap = Other.Cap; - Other.clearInline(); - return *this; - } - - std::swap(First, Other.First); - std::swap(Last, Other.Last); - std::swap(Cap, Other.Cap); - Other.clear(); - return *this; - } - - void push_back(const T& Elem) { - if (Last == Cap) - reserve(size() * 2); - *Last++ = Elem; - } - - void pop_back() { - assert(Last != First && "Popping empty vector!"); - --Last; - } - - void dropBack(size_t Index) { - assert(Index <= size() && "dropBack() can't expand!"); - Last = First + Index; - } - - T* begin() { return First; } - T* end() { return Last; } - - bool empty() const { return First == Last; } - size_t size() const { return static_cast<size_t>(Last - First); } - T& back() { - assert(Last != First && "Calling back() on empty vector!"); - return *(Last - 1); - } - T& operator[](size_t Index) { - assert(Index < size() && "Invalid access!"); - return *(begin() + Index); - } - void clear() { Last = First; } - - ~PODSmallVector() { - if (!isInline()) - std::free(First); - } -}; - -// Substitution table. This type is used to track the substitutions that are -// known by the parser. -template <size_t Size> -class SubstitutionTable { - // Substitutions hold the actual entries in the table, and PackIndices tells - // us which entries are members of which pack. For example, if the - // substitutions we're tracking are: {int, {float, FooBar}, char}, with - // {float, FooBar} being a parameter pack, we represent the substitutions as: - // Substitutions: int, float, FooBar, char - // PackIndices: 0, 1, 3 - // So, PackIndicies[I] holds the offset of the begin of the Ith pack, and - // PackIndices[I + 1] holds the offset of the end. - PODSmallVector<Node*, Size> Substitutions; - PODSmallVector<unsigned, Size> PackIndices; - -public: - // Add a substitution that represents a single name to the table. This is - // modeled as a parameter pack with just one element. - void pushSubstitution(Node* Entry) { - pushPack(); - pushSubstitutionIntoPack(Entry); - } - - // Add a new empty pack to the table. Subsequent calls to - // pushSubstitutionIntoPack() will add to this pack. - void pushPack() { - PackIndices.push_back(static_cast<unsigned>(Substitutions.size())); - } - void pushSubstitutionIntoPack(Node* Entry) { - assert(!PackIndices.empty() && "No pack to push substitution into!"); - Substitutions.push_back(Entry); - } - - // Remove the last pack from the table. - void popPack() { - unsigned Last = PackIndices.back(); - PackIndices.pop_back(); - Substitutions.dropBack(Last); - } - - // For use in a range-for loop. - struct NodeRange { - Node** First; - Node** Last; - Node** begin() { return First; } - Node** end() { return Last; } - }; - - // Retrieve the Nth substitution. This is represented as a range, as the - // substitution could be referring to a parameter pack. - NodeRange nthSubstitution(size_t N) { - assert(PackIndices[N] <= Substitutions.size()); - // The Nth parameter pack starts at offset PackIndices[N], and ends at - // PackIndices[N + 1]. - Node** Begin = Substitutions.begin() + PackIndices[N]; - Node** End; - if (N + 1 != PackIndices.size()) { - assert(PackIndices[N + 1] <= Substitutions.size()); - End = Substitutions.begin() + PackIndices[N + 1]; - } else - End = Substitutions.end(); - assert(Begin <= End); - return NodeRange{Begin, End}; - } - - size_t size() const { return PackIndices.size(); } - bool empty() const { return PackIndices.empty(); } - void clear() { - Substitutions.clear(); - PackIndices.clear(); - } -}; - -struct Db -{ - // Name stack, this is used by the parser to hold temporary names that were - // parsed. The parser colapses multiple names into new nodes to construct - // the AST. Once the parser is finished, names.size() == 1. - PODSmallVector<Node*, 32> Names; - - // Substitution table. Itanium supports name substitutions as a means of - // compression. The string "S42_" refers to the 42nd entry in this table. - SubstitutionTable<32> Subs; - - // Template parameter table. Like the above, but referenced like "T42_". - // This has a smaller size compared to Subs and Names because it can be - // stored on the stack. - SubstitutionTable<4> TemplateParams; - - Qualifiers CV = QualNone; - FunctionRefQual RefQuals = FrefQualNone; - unsigned EncodingDepth = 0; - bool ParsedCtorDtorCV = false; - bool TagTemplates = true; - bool FixForwardReferences = false; - bool TryToParseTemplateArgs = true; - - BumpPointerAllocator ASTAllocator; - - template <class T, class... Args> T* make(Args&& ...args) - { - return new (ASTAllocator.allocate(sizeof(T))) - T(std::forward<Args>(args)...); - } - - template <class It> NodeArray makeNodeArray(It begin, It end) - { - size_t sz = static_cast<size_t>(end - begin); - void* mem = ASTAllocator.allocate(sizeof(Node*) * sz); - Node** data = new (mem) Node*[sz]; - std::copy(begin, end, data); - return NodeArray(data, sz); - } - - NodeArray popTrailingNodeArray(size_t FromPosition) - { - assert(FromPosition <= Names.size()); - NodeArray res = makeNodeArray( - Names.begin() + (long)FromPosition, Names.end()); - Names.dropBack(FromPosition); - return res; - } -}; - -const char* parse_type(const char* first, const char* last, Db& db); -const char* parse_encoding(const char* first, const char* last, Db& db); -const char* parse_name(const char* first, const char* last, Db& db, - bool* ends_with_template_args = 0); -const char* parse_expression(const char* first, const char* last, Db& db); -const char* parse_template_args(const char* first, const char* last, Db& db); -const char* parse_operator_name(const char* first, const char* last, Db& db); -const char* parse_unqualified_name(const char* first, const char* last, Db& db); -const char* parse_decltype(const char* first, const char* last, Db& db); - -// <number> ::= [n] <non-negative decimal integer> - -const char* -parse_number(const char* first, const char* last) -{ - if (first != last) - { - const char* t = first; - if (*t == 'n') - ++t; - if (t != last) - { - if (*t == '0') - { - first = t+1; - } - else if ('1' <= *t && *t <= '9') - { - first = t+1; - while (first != last && std::isdigit(*first)) - ++first; - } - } - } - return first; -} - -template <class Float> -struct FloatData; - -template <> -struct FloatData<float> -{ - static const size_t mangled_size = 8; - static const size_t max_demangled_size = 24; - static constexpr const char* spec = "%af"; -}; - -constexpr const char* FloatData<float>::spec; - -template <> -struct FloatData<double> -{ - static const size_t mangled_size = 16; - static const size_t max_demangled_size = 32; - static constexpr const char* spec = "%a"; -}; - -constexpr const char* FloatData<double>::spec; - -template <> -struct FloatData<long double> -{ -#if defined(__mips__) && defined(__mips_n64) || defined(__aarch64__) || \ - defined(__wasm__) - static const size_t mangled_size = 32; -#elif defined(__arm__) || defined(__mips__) || defined(__hexagon__) - static const size_t mangled_size = 16; -#else - static const size_t mangled_size = 20; // May need to be adjusted to 16 or 24 on other platforms -#endif - static const size_t max_demangled_size = 40; - static constexpr const char* spec = "%LaL"; -}; - -constexpr const char* FloatData<long double>::spec; - -template <class Float> -const char* -parse_floating_number(const char* first, const char* last, Db& db) -{ - const size_t N = FloatData<Float>::mangled_size; - if (static_cast<std::size_t>(last - first) <= N) - return first; - last = first + N; - const char* t = first; - for (; t != last; ++t) - { - if (!isxdigit(*t)) - return first; - } - if (*t == 'E') - { - db.Names.push_back( - db.make<FloatExpr<Float>>(StringView(first, t))); - first = t + 1; - } - return first; -} - -// <source-name> ::= <positive length number> <identifier> - -const char* -parse_source_name(const char* first, const char* last, Db& db) -{ - if (first != last) - { - char c = *first; - if (isdigit(c) && first+1 != last) - { - const char* t = first+1; - size_t n = static_cast<size_t>(c - '0'); - for (c = *t; isdigit(c); c = *t) - { - n = n * 10 + static_cast<size_t>(c - '0'); - if (++t == last) - return first; - } - if (static_cast<size_t>(last - t) >= n) - { - StringView r(t, t + n); - if (r.substr(0, 10) == "_GLOBAL__N") - db.Names.push_back(db.make<NameType>("(anonymous namespace)")); - else - db.Names.push_back(db.make<NameType>(r)); - first = t + n; - } - } - } - return first; -} - -// <substitution> ::= S <seq-id> _ -// ::= S_ -// <substitution> ::= Sa # ::std::allocator -// <substitution> ::= Sb # ::std::basic_string -// <substitution> ::= Ss # ::std::basic_string < char, -// ::std::char_traits<char>, -// ::std::allocator<char> > -// <substitution> ::= Si # ::std::basic_istream<char, std::char_traits<char> > -// <substitution> ::= So # ::std::basic_ostream<char, std::char_traits<char> > -// <substitution> ::= Sd # ::std::basic_iostream<char, std::char_traits<char> > - -const char* -parse_substitution(const char* first, const char* last, Db& db) -{ - if (last - first >= 2) - { - if (*first == 'S') - { - switch (first[1]) - { - case 'a': - db.Names.push_back( - db.make<SpecialSubstitution>( - SpecialSubKind::allocator)); - first += 2; - break; - case 'b': - db.Names.push_back( - db.make<SpecialSubstitution>(SpecialSubKind::basic_string)); - first += 2; - break; - case 's': - db.Names.push_back( - db.make<SpecialSubstitution>( - SpecialSubKind::string)); - first += 2; - break; - case 'i': - db.Names.push_back(db.make<SpecialSubstitution>(SpecialSubKind::istream)); - first += 2; - break; - case 'o': - db.Names.push_back(db.make<SpecialSubstitution>(SpecialSubKind::ostream)); - first += 2; - break; - case 'd': - db.Names.push_back(db.make<SpecialSubstitution>(SpecialSubKind::iostream)); - first += 2; - break; - case '_': - if (!db.Subs.empty()) - { - for (Node* n : db.Subs.nthSubstitution(0)) - db.Names.push_back(n); - first += 2; - } - break; - default: - if (std::isdigit(first[1]) || std::isupper(first[1])) - { - size_t sub = 0; - const char* t = first+1; - if (std::isdigit(*t)) - sub = static_cast<size_t>(*t - '0'); - else - sub = static_cast<size_t>(*t - 'A') + 10; - for (++t; t != last && (std::isdigit(*t) || std::isupper(*t)); ++t) - { - sub *= 36; - if (std::isdigit(*t)) - sub += static_cast<size_t>(*t - '0'); - else - sub += static_cast<size_t>(*t - 'A') + 10; - } - if (t == last || *t != '_') - return first; - ++sub; - if (sub < db.Subs.size()) - { - for (Node* n : db.Subs.nthSubstitution(sub)) - db.Names.push_back(n); - first = t+1; - } - } - break; - } - } - } - return first; -} - -// <builtin-type> ::= v # void -// ::= w # wchar_t -// ::= b # bool -// ::= c # char -// ::= a # signed char -// ::= h # unsigned char -// ::= s # short -// ::= t # unsigned short -// ::= i # int -// ::= j # unsigned int -// ::= l # long -// ::= m # unsigned long -// ::= x # long long, __int64 -// ::= y # unsigned long long, __int64 -// ::= n # __int128 -// ::= o # unsigned __int128 -// ::= f # float -// ::= d # double -// ::= e # long double, __float80 -// ::= g # __float128 -// ::= z # ellipsis -// ::= Dd # IEEE 754r decimal floating point (64 bits) -// ::= De # IEEE 754r decimal floating point (128 bits) -// ::= Df # IEEE 754r decimal floating point (32 bits) -// ::= Dh # IEEE 754r half-precision floating point (16 bits) -// ::= Di # char32_t -// ::= Ds # char16_t -// ::= Da # auto (in dependent new-expressions) -// ::= Dc # decltype(auto) -// ::= Dn # std::nullptr_t (i.e., decltype(nullptr)) -// ::= u <source-name> # vendor extended type - -const char* -parse_builtin_type(const char* first, const char* last, Db& db) -{ - if (first != last) - { - switch (*first) - { - case 'v': - db.Names.push_back(db.make<NameType>("void")); - ++first; - break; - case 'w': - db.Names.push_back(db.make<NameType>("wchar_t")); - ++first; - break; - case 'b': - db.Names.push_back(db.make<NameType>("bool")); - ++first; - break; - case 'c': - db.Names.push_back(db.make<NameType>("char")); - ++first; - break; - case 'a': - db.Names.push_back(db.make<NameType>("signed char")); - ++first; - break; - case 'h': - db.Names.push_back(db.make<NameType>("unsigned char")); - ++first; - break; - case 's': - db.Names.push_back(db.make<NameType>("short")); - ++first; - break; - case 't': - db.Names.push_back(db.make<NameType>("unsigned short")); - ++first; - break; - case 'i': - db.Names.push_back(db.make<NameType>("int")); - ++first; - break; - case 'j': - db.Names.push_back(db.make<NameType>("unsigned int")); - ++first; - break; - case 'l': - db.Names.push_back(db.make<NameType>("long")); - ++first; - break; - case 'm': - db.Names.push_back(db.make<NameType>("unsigned long")); - ++first; - break; - case 'x': - db.Names.push_back(db.make<NameType>("long long")); - ++first; - break; - case 'y': - db.Names.push_back(db.make<NameType>("unsigned long long")); - ++first; - break; - case 'n': - db.Names.push_back(db.make<NameType>("__int128")); - ++first; - break; - case 'o': - db.Names.push_back(db.make<NameType>("unsigned __int128")); - ++first; - break; - case 'f': - db.Names.push_back(db.make<NameType>("float")); - ++first; - break; - case 'd': - db.Names.push_back(db.make<NameType>("double")); - ++first; - break; - case 'e': - db.Names.push_back(db.make<NameType>("long double")); - ++first; - break; - case 'g': - db.Names.push_back(db.make<NameType>("__float128")); - ++first; - break; - case 'z': - db.Names.push_back(db.make<NameType>("...")); - ++first; - break; - case 'u': - { - const char*t = parse_source_name(first+1, last, db); - if (t != first+1) - first = t; - } - break; - case 'D': - if (first+1 != last) - { - switch (first[1]) - { - case 'd': - db.Names.push_back(db.make<NameType>("decimal64")); - first += 2; - break; - case 'e': - db.Names.push_back(db.make<NameType>("decimal128")); - first += 2; - break; - case 'f': - db.Names.push_back(db.make<NameType>("decimal32")); - first += 2; - break; - case 'h': - db.Names.push_back(db.make<NameType>("decimal16")); - first += 2; - break; - case 'i': - db.Names.push_back(db.make<NameType>("char32_t")); - first += 2; - break; - case 's': - db.Names.push_back(db.make<NameType>("char16_t")); - first += 2; - break; - case 'a': - db.Names.push_back(db.make<NameType>("auto")); - first += 2; - break; - case 'c': - db.Names.push_back(db.make<NameType>("decltype(auto)")); - first += 2; - break; - case 'n': - db.Names.push_back(db.make<NameType>("std::nullptr_t")); - first += 2; - break; - } - } - break; - } - } - return first; -} - -// <CV-Qualifiers> ::= [r] [V] [K] - -const char* -parse_cv_qualifiers(const char* first, const char* last, Qualifiers& cv) -{ - cv = QualNone; - if (first != last) - { - if (*first == 'r') - { - addQualifiers(cv, QualRestrict); - ++first; - } - if (*first == 'V') - { - addQualifiers(cv, QualVolatile); - ++first; - } - if (*first == 'K') - { - addQualifiers(cv, QualConst); - ++first; - } - } - return first; -} - -// <template-param> ::= T_ # first template parameter -// ::= T <parameter-2 non-negative number> _ - -const char* -parse_template_param(const char* first, const char* last, Db& db) -{ - if (last - first >= 2) - { - if (*first == 'T') - { - if (first[1] == '_') - { - if (!db.TemplateParams.empty()) - { - for (Node *t : db.TemplateParams.nthSubstitution(0)) - db.Names.push_back(t); - first += 2; - } - else - { - db.Names.push_back(db.make<NameType>("T_")); - first += 2; - db.FixForwardReferences = true; - } - } - else if (isdigit(first[1])) - { - const char* t = first+1; - size_t sub = static_cast<size_t>(*t - '0'); - for (++t; t != last && isdigit(*t); ++t) - { - sub *= 10; - sub += static_cast<size_t>(*t - '0'); - } - if (t == last || *t != '_') - return first; - ++sub; - if (sub < db.TemplateParams.size()) - { - for (Node *temp : db.TemplateParams.nthSubstitution(sub)) - db.Names.push_back(temp); - first = t+1; - } - else - { - db.Names.push_back( - db.make<NameType>(StringView(first, t + 1))); - first = t+1; - db.FixForwardReferences = true; - } - } - } - } - return first; -} - -// cc <type> <expression> # const_cast<type> (expression) - -const char* -parse_const_cast_expr(const char* first, const char* last, Db& db) -{ - if (last - first >= 3 && first[0] == 'c' && first[1] == 'c') - { - const char* t = parse_type(first+2, last, db); - if (t != first+2) - { - const char* t1 = parse_expression(t, last, db); - if (t1 != t) - { - if (db.Names.size() < 2) - return first; - auto from_expr = db.Names.back(); - db.Names.pop_back(); - if (db.Names.empty()) - return first; - db.Names.back() = db.make<CastExpr>( - "const_cast", db.Names.back(), from_expr); - first = t1; - } - } - } - return first; -} - -// dc <type> <expression> # dynamic_cast<type> (expression) - -const char* -parse_dynamic_cast_expr(const char* first, const char* last, Db& db) -{ - if (last - first >= 3 && first[0] == 'd' && first[1] == 'c') - { - const char* t = parse_type(first+2, last, db); - if (t != first+2) - { - const char* t1 = parse_expression(t, last, db); - if (t1 != t) - { - if (db.Names.size() < 2) - return first; - auto from_expr = db.Names.back(); - db.Names.pop_back(); - if (db.Names.empty()) - return first; - db.Names.back() = db.make<CastExpr>( - "dynamic_cast", db.Names.back(), from_expr); - first = t1; - } - } - } - return first; -} - -// rc <type> <expression> # reinterpret_cast<type> (expression) - -const char* -parse_reinterpret_cast_expr(const char* first, const char* last, Db& db) -{ - if (last - first >= 3 && first[0] == 'r' && first[1] == 'c') - { - const char* t = parse_type(first+2, last, db); - if (t != first+2) - { - const char* t1 = parse_expression(t, last, db); - if (t1 != t) - { - if (db.Names.size() < 2) - return first; - auto from_expr = db.Names.back(); - db.Names.pop_back(); - if (db.Names.empty()) - return first; - db.Names.back() = db.make<CastExpr>( - "reinterpret_cast", db.Names.back(), from_expr); - first = t1; - } - } - } - return first; -} - -// sc <type> <expression> # static_cast<type> (expression) - -const char* -parse_static_cast_expr(const char* first, const char* last, Db& db) -{ - if (last - first >= 3 && first[0] == 's' && first[1] == 'c') - { - const char* t = parse_type(first+2, last, db); - if (t != first+2) - { - const char* t1 = parse_expression(t, last, db); - if (t1 != t) - { - if (db.Names.size() < 2) - return first; - auto from_expr = db.Names.back(); - db.Names.pop_back(); - db.Names.back() = db.make<CastExpr>( - "static_cast", db.Names.back(), from_expr); - first = t1; - } - } - } - return first; -} - -// sp <expression> # pack expansion - -const char* -parse_pack_expansion(const char* first, const char* last, Db& db) -{ - if (last - first >= 3 && first[0] == 's' && first[1] == 'p') - { - const char* t = parse_expression(first+2, last, db); - if (t != first+2) - first = t; - } - return first; -} - -// st <type> # sizeof (a type) - -const char* -parse_sizeof_type_expr(const char* first, const char* last, Db& db) -{ - if (last - first >= 3 && first[0] == 's' && first[1] == 't') - { - const char* t = parse_type(first+2, last, db); - if (t != first+2) - { - if (db.Names.empty()) - return first; - db.Names.back() = db.make<EnclosingExpr>( - "sizeof (", db.Names.back(), ")"); - first = t; - } - } - return first; -} - -// sz <expr> # sizeof (a expression) - -const char* -parse_sizeof_expr_expr(const char* first, const char* last, Db& db) -{ - if (last - first >= 3 && first[0] == 's' && first[1] == 'z') - { - const char* t = parse_expression(first+2, last, db); - if (t != first+2) - { - if (db.Names.empty()) - return first; - db.Names.back() = db.make<EnclosingExpr>( - "sizeof (", db.Names.back(), ")"); - first = t; - } - } - return first; -} - -// sZ <template-param> # size of a parameter pack - -const char* -parse_sizeof_param_pack_expr(const char* first, const char* last, Db& db) -{ - if (last - first >= 3 && first[0] == 's' && first[1] == 'Z' && first[2] == 'T') - { - size_t k0 = db.Names.size(); - const char* t = parse_template_param(first+2, last, db); - size_t k1 = db.Names.size(); - if (t != first+2 && k0 <= k1) - { - Node* sizeof_expr = db.make<SizeofParamPackExpr>( - db.popTrailingNodeArray(k0)); - db.Names.push_back(sizeof_expr); - first = t; - } - } - return first; -} - -// <function-param> ::= fp <top-level CV-Qualifiers> _ # L == 0, first parameter -// ::= fp <top-level CV-Qualifiers> <parameter-2 non-negative number> _ # L == 0, second and later parameters -// ::= fL <L-1 non-negative number> p <top-level CV-Qualifiers> _ # L > 0, first parameter -// ::= fL <L-1 non-negative number> p <top-level CV-Qualifiers> <parameter-2 non-negative number> _ # L > 0, second and later parameters - -const char* -parse_function_param(const char* first, const char* last, Db& db) -{ - if (last - first >= 3 && *first == 'f') - { - if (first[1] == 'p') - { - Qualifiers cv; - const char* t = parse_cv_qualifiers(first+2, last, cv); - const char* t1 = parse_number(t, last); - if (t1 != last && *t1 == '_') - { - db.Names.push_back( - db.make<FunctionParam>(StringView(t, t1))); - first = t1+1; - } - } - else if (first[1] == 'L') - { - Qualifiers cv; - const char* t0 = parse_number(first+2, last); - if (t0 != last && *t0 == 'p') - { - ++t0; - const char* t = parse_cv_qualifiers(t0, last, cv); - const char* t1 = parse_number(t, last); - if (t1 != last && *t1 == '_') - { - db.Names.push_back( - db.make<FunctionParam>(StringView(t, t1))); - first = t1+1; - } - } - } - } - return first; -} - -// sZ <function-param> # size of a function parameter pack - -const char* -parse_sizeof_function_param_pack_expr(const char* first, const char* last, Db& db) -{ - if (last - first >= 3 && first[0] == 's' && first[1] == 'Z' && first[2] == 'f') - { - const char* t = parse_function_param(first+2, last, db); - if (t != first+2) - { - if (db.Names.empty()) - return first; - db.Names.back() = db.make<EnclosingExpr>( - "sizeof...(", db.Names.back(), ")"); - first = t; - } - } - return first; -} - -// te <expression> # typeid (expression) -// ti <type> # typeid (type) - -const char* -parse_typeid_expr(const char* first, const char* last, Db& db) -{ - if (last - first >= 3 && first[0] == 't' && (first[1] == 'e' || first[1] == 'i')) - { - const char* t; - if (first[1] == 'e') - t = parse_expression(first+2, last, db); - else - t = parse_type(first+2, last, db); - if (t != first+2) - { - if (db.Names.empty()) - return first; - db.Names.back() = db.make<EnclosingExpr>( - "typeid(", db.Names.back(), ")"); - first = t; - } - } - return first; -} - -// tw <expression> # throw expression - -const char* -parse_throw_expr(const char* first, const char* last, Db& db) -{ - if (last - first >= 3 && first[0] == 't' && first[1] == 'w') - { - const char* t = parse_expression(first+2, last, db); - if (t != first+2) - { - if (db.Names.empty()) - return first; - db.Names.back() = db.make<ThrowExpr>(db.Names.back()); - first = t; - } - } - return first; -} - -// ds <expression> <expression> # expr.*expr - -const char* -parse_dot_star_expr(const char* first, const char* last, Db& db) -{ - if (last - first >= 3 && first[0] == 'd' && first[1] == 's') - { - const char* t = parse_expression(first+2, last, db); - if (t != first+2) - { - const char* t1 = parse_expression(t, last, db); - if (t1 != t) - { - if (db.Names.size() < 2) - return first; - auto rhs_expr = db.Names.back(); - db.Names.pop_back(); - db.Names.back() = db.make<MemberExpr>( - db.Names.back(), ".*", rhs_expr); - first = t1; - } - } - } - return first; -} - -// <simple-id> ::= <source-name> [ <template-args> ] - -const char* -parse_simple_id(const char* first, const char* last, Db& db) -{ - if (first != last) - { - const char* t = parse_source_name(first, last, db); - if (t != first) - { - const char* t1 = parse_template_args(t, last, db); - if (t1 != t) - { - if (db.Names.size() < 2) - return first; - auto args = db.Names.back(); - db.Names.pop_back(); - db.Names.back() = - db.make<NameWithTemplateArgs>(db.Names.back(), args); - } - first = t1; - } - else - first = t; - } - return first; -} - -// <unresolved-type> ::= <template-param> -// ::= <decltype> -// ::= <substitution> - -const char* -parse_unresolved_type(const char* first, const char* last, Db& db) -{ - if (first != last) - { - const char* t = first; - switch (*first) - { - case 'T': - { - size_t k0 = db.Names.size(); - t = parse_template_param(first, last, db); - size_t k1 = db.Names.size(); - if (t != first && k1 == k0 + 1) - { - db.Subs.pushSubstitution(db.Names.back()); - first = t; - } - else - { - for (; k1 != k0; --k1) - db.Names.pop_back(); - } - break; - } - case 'D': - t = parse_decltype(first, last, db); - if (t != first) - { - if (db.Names.empty()) - return first; - db.Subs.pushSubstitution(db.Names.back()); - first = t; - } - break; - case 'S': - t = parse_substitution(first, last, db); - if (t != first) - first = t; - else - { - if (last - first > 2 && first[1] == 't') - { - t = parse_unqualified_name(first+2, last, db); - if (t != first+2) - { - if (db.Names.empty()) - return first; - db.Names.back() = - db.make<StdQualifiedName>(db.Names.back()); - db.Subs.pushSubstitution(db.Names.back()); - first = t; - } - } - } - break; - } - } - return first; -} - -// <destructor-name> ::= <unresolved-type> # e.g., ~T or ~decltype(f()) -// ::= <simple-id> # e.g., ~A<2*N> - -const char* -parse_destructor_name(const char* first, const char* last, Db& db) -{ - if (first != last) - { - const char* t = parse_unresolved_type(first, last, db); - if (t == first) - t = parse_simple_id(first, last, db); - if (t != first) - { - if (db.Names.empty()) - return first; - db.Names.back() = db.make<DtorName>(db.Names.back()); - first = t; - } - } - return first; -} - -// <base-unresolved-name> ::= <simple-id> # unresolved name -// extension ::= <operator-name> # unresolved operator-function-id -// extension ::= <operator-name> <template-args> # unresolved operator template-id -// ::= on <operator-name> # unresolved operator-function-id -// ::= on <operator-name> <template-args> # unresolved operator template-id -// ::= dn <destructor-name> # destructor or pseudo-destructor; -// # e.g. ~X or ~X<N-1> - -const char* -parse_base_unresolved_name(const char* first, const char* last, Db& db) -{ - if (last - first >= 2) - { - if ((first[0] == 'o' || first[0] == 'd') && first[1] == 'n') - { - if (first[0] == 'o') - { - const char* t = parse_operator_name(first+2, last, db); - if (t != first+2) - { - first = parse_template_args(t, last, db); - if (first != t) - { - if (db.Names.size() < 2) - return first; - auto args = db.Names.back(); - db.Names.pop_back(); - db.Names.back() = - db.make<NameWithTemplateArgs>( - db.Names.back(), args); - } - } - } - else - { - const char* t = parse_destructor_name(first+2, last, db); - if (t != first+2) - first = t; - } - } - else - { - const char* t = parse_simple_id(first, last, db); - if (t == first) - { - t = parse_operator_name(first, last, db); - if (t != first) - { - first = parse_template_args(t, last, db); - if (first != t) - { - if (db.Names.size() < 2) - return first; - auto args = db.Names.back(); - db.Names.pop_back(); - db.Names.back() = - db.make<NameWithTemplateArgs>( - db.Names.back(), args); - } - } - } - else - first = t; - } - } - return first; -} - -// <unresolved-qualifier-level> ::= <simple-id> - -const char* -parse_unresolved_qualifier_level(const char* first, const char* last, Db& db) -{ - return parse_simple_id(first, last, db); -} - -// <unresolved-name> -// extension ::= srN <unresolved-type> [<template-args>] <unresolved-qualifier-level>* E <base-unresolved-name> -// ::= [gs] <base-unresolved-name> # x or (with "gs") ::x -// ::= [gs] sr <unresolved-qualifier-level>+ E <base-unresolved-name> -// # A::x, N::y, A<T>::z; "gs" means leading "::" -// ::= sr <unresolved-type> <base-unresolved-name> # T::x / decltype(p)::x -// extension ::= sr <unresolved-type> <template-args> <base-unresolved-name> -// # T::N::x /decltype(p)::N::x -// (ignored) ::= srN <unresolved-type> <unresolved-qualifier-level>+ E <base-unresolved-name> - -const char* -parse_unresolved_name(const char* first, const char* last, Db& db) -{ - if (last - first > 2) - { - const char* t = first; - bool global = false; - if (t[0] == 'g' && t[1] == 's') - { - global = true; - t += 2; - } - const char* t2 = parse_base_unresolved_name(t, last, db); - if (t2 != t) - { - if (global) - { - if (db.Names.empty()) - return first; - db.Names.back() = - db.make<GlobalQualifiedName>(db.Names.back()); - } - first = t2; - } - else if (last - t > 2 && t[0] == 's' && t[1] == 'r') - { - if (t[2] == 'N') - { - t += 3; - const char* t1 = parse_unresolved_type(t, last, db); - if (t1 == t || t1 == last) - return first; - t = t1; - t1 = parse_template_args(t, last, db); - if (t1 != t) - { - if (db.Names.size() < 2) - return first; - auto args = db.Names.back(); - db.Names.pop_back(); - db.Names.back() = db.make<NameWithTemplateArgs>( - db.Names.back(), args); - t = t1; - if (t == last) - { - db.Names.pop_back(); - return first; - } - } - while (*t != 'E') - { - t1 = parse_unresolved_qualifier_level(t, last, db); - if (t1 == t || t1 == last || db.Names.size() < 2) - return first; - auto s = db.Names.back(); - db.Names.pop_back(); - db.Names.back() = - db.make<QualifiedName>(db.Names.back(), s); - t = t1; - } - ++t; - t1 = parse_base_unresolved_name(t, last, db); - if (t1 == t) - { - if (!db.Names.empty()) - db.Names.pop_back(); - return first; - } - if (db.Names.size() < 2) - return first; - auto s = db.Names.back(); - db.Names.pop_back(); - db.Names.back() = - db.make<QualifiedName>(db.Names.back(), s); - first = t1; - } - else - { - t += 2; - const char* t1 = parse_unresolved_type(t, last, db); - if (t1 != t) - { - t = t1; - t1 = parse_template_args(t, last, db); - if (t1 != t) - { - if (db.Names.size() < 2) - return first; - auto args = db.Names.back(); - db.Names.pop_back(); - db.Names.back() = - db.make<NameWithTemplateArgs>( - db.Names.back(), args); - t = t1; - } - t1 = parse_base_unresolved_name(t, last, db); - if (t1 == t) - { - if (!db.Names.empty()) - db.Names.pop_back(); - return first; - } - if (db.Names.size() < 2) - return first; - auto s = db.Names.back(); - db.Names.pop_back(); - db.Names.back() = - db.make<QualifiedName>(db.Names.back(), s); - first = t1; - } - else - { - t1 = parse_unresolved_qualifier_level(t, last, db); - if (t1 == t || t1 == last) - return first; - t = t1; - if (global) - { - if (db.Names.empty()) - return first; - db.Names.back() = - db.make<GlobalQualifiedName>( - db.Names.back()); - } - while (*t != 'E') - { - t1 = parse_unresolved_qualifier_level(t, last, db); - if (t1 == t || t1 == last || db.Names.size() < 2) - return first; - auto s = db.Names.back(); - db.Names.pop_back(); - db.Names.back() = db.make<QualifiedName>( - db.Names.back(), s); - t = t1; - } - ++t; - t1 = parse_base_unresolved_name(t, last, db); - if (t1 == t) - { - if (!db.Names.empty()) - db.Names.pop_back(); - return first; - } - if (db.Names.size() < 2) - return first; - auto s = db.Names.back(); - db.Names.pop_back(); - db.Names.back() = - db.make<QualifiedName>(db.Names.back(), s); - first = t1; - } - } - } - } - return first; -} - -// dt <expression> <unresolved-name> # expr.name - -const char* -parse_dot_expr(const char* first, const char* last, Db& db) -{ - if (last - first >= 3 && first[0] == 'd' && first[1] == 't') - { - const char* t = parse_expression(first+2, last, db); - if (t != first+2) - { - const char* t1 = parse_unresolved_name(t, last, db); - if (t1 != t) - { - if (db.Names.size() < 2) - return first; - auto name = db.Names.back(); - db.Names.pop_back(); - if (db.Names.empty()) - return first; - db.Names.back() = db.make<MemberExpr>(db.Names.back(), ".", name); - first = t1; - } - } - } - return first; -} - -// cl <expression>+ E # call - -const char* -parse_call_expr(const char* first, const char* last, Db& db) -{ - if (last - first >= 4 && first[0] == 'c' && first[1] == 'l') - { - const char* t = parse_expression(first+2, last, db); - if (t == last || t == first + 2 || db.Names.empty()) - return first; - Node* callee = db.Names.back(); - db.Names.pop_back(); - size_t args_begin = db.Names.size(); - while (*t != 'E') - { - const char* t1 = parse_expression(t, last, db); - if (t1 == last || t1 == t) - return first; - t = t1; - } - if (db.Names.size() < args_begin) - return first; - ++t; - CallExpr* the_call = db.make<CallExpr>( - callee, db.popTrailingNodeArray(args_begin)); - db.Names.push_back(the_call); - first = t; - } - return first; -} - -// [gs] nw <expression>* _ <type> E # new (expr-list) type -// [gs] nw <expression>* _ <type> <initializer> # new (expr-list) type (init) -// [gs] na <expression>* _ <type> E # new[] (expr-list) type -// [gs] na <expression>* _ <type> <initializer> # new[] (expr-list) type (init) -// <initializer> ::= pi <expression>* E # parenthesized initialization - -const char* -parse_new_expr(const char* first, const char* last, Db& db) -{ - if (last - first >= 4) - { - const char* t = first; - bool parsed_gs = false; - if (t[0] == 'g' && t[1] == 's') - { - t += 2; - parsed_gs = true; - } - if (t[0] == 'n' && (t[1] == 'w' || t[1] == 'a')) - { - bool is_array = t[1] == 'a'; - t += 2; - if (t == last) - return first; - size_t first_expr_in_list = db.Names.size(); - NodeArray ExprList, init_list; - while (*t != '_') - { - const char* t1 = parse_expression(t, last, db); - if (t1 == t || t1 == last) - return first; - t = t1; - } - if (first_expr_in_list > db.Names.size()) - return first; - ExprList = db.popTrailingNodeArray(first_expr_in_list); - ++t; - const char* t1 = parse_type(t, last, db); - if (t1 == t || t1 == last) - return first; - t = t1; - bool has_init = false; - if (last - t >= 3 && t[0] == 'p' && t[1] == 'i') - { - t += 2; - has_init = true; - size_t init_list_begin = db.Names.size(); - while (*t != 'E') - { - t1 = parse_expression(t, last, db); - if (t1 == t || t1 == last) - return first; - t = t1; - } - if (init_list_begin > db.Names.size()) - return first; - init_list = db.popTrailingNodeArray(init_list_begin); - } - if (*t != 'E' || db.Names.empty()) - return first; - auto type = db.Names.back(); - db.Names.pop_back(); - db.Names.push_back( - db.make<NewExpr>(ExprList, type, init_list, - parsed_gs, is_array)); - first = t+1; - } - } - return first; -} - -// cv <type> <expression> # conversion with one argument -// cv <type> _ <expression>* E # conversion with a different number of arguments - -const char* -parse_conversion_expr(const char* first, const char* last, Db& db) -{ - if (last - first >= 3 && first[0] == 'c' && first[1] == 'v') - { - bool TryToParseTemplateArgs = db.TryToParseTemplateArgs; - db.TryToParseTemplateArgs = false; - size_t type_begin = db.Names.size(); - const char* t = parse_type(first+2, last, db); - db.TryToParseTemplateArgs = TryToParseTemplateArgs; - if (t != first+2 && t != last) - { - size_t expr_list_begin = db.Names.size(); - if (*t != '_') - { - const char* t1 = parse_expression(t, last, db); - if (t1 == t) - return first; - t = t1; - } - else - { - ++t; - if (t == last) - return first; - if (*t != 'E') - { - while (*t != 'E') - { - const char* t1 = parse_expression(t, last, db); - if (t1 == t || t1 == last) - return first; - t = t1; - } - } - ++t; - } - if (db.Names.size() < expr_list_begin || - type_begin > expr_list_begin) - return first; - NodeArray expressions = db.makeNodeArray( - db.Names.begin() + (long)expr_list_begin, db.Names.end()); - NodeArray types = db.makeNodeArray( - db.Names.begin() + (long)type_begin, - db.Names.begin() + (long)expr_list_begin); - auto* conv_expr = db.make<ConversionExpr>( - types, expressions); - db.Names.dropBack(type_begin); - db.Names.push_back(conv_expr); - first = t; - } - } - return first; -} - -// pt <expression> <expression> # expr->name - -const char* -parse_arrow_expr(const char* first, const char* last, Db& db) -{ - if (last - first >= 3 && first[0] == 'p' && first[1] == 't') - { - const char* t = parse_expression(first+2, last, db); - if (t != first+2) - { - const char* t1 = parse_expression(t, last, db); - if (t1 != t) - { - if (db.Names.size() < 2) - return first; - auto tmp = db.Names.back(); - db.Names.pop_back(); - db.Names.back() = db.make<MemberExpr>( - db.Names.back(), "->", tmp); - first = t1; - } - } - } - return first; -} - -// <ref-qualifier> ::= R # & ref-qualifier -// <ref-qualifier> ::= O # && ref-qualifier - -// <function-type> ::= F [Y] <bare-function-type> [<ref-qualifier>] E - -const char* -parse_function_type(const char* first, const char* last, Db& db) -{ - if (first != last && *first == 'F') - { - const char* t = first+1; - if (t != last) - { - if (*t == 'Y') - { - /* extern "C" */ - if (++t == last) - return first; - } - const char* t1 = parse_type(t, last, db); - if (t1 != t && !db.Names.empty()) - { - Node* ret_type = db.Names.back(); - db.Names.pop_back(); - size_t params_begin = db.Names.size(); - t = t1; - FunctionRefQual RefQuals = FrefQualNone; - while (true) - { - if (t == last) - { - if (!db.Names.empty()) - db.Names.pop_back(); - return first; - } - if (*t == 'E') - { - ++t; - break; - } - if (*t == 'v') - { - ++t; - continue; - } - if (*t == 'R' && t+1 != last && t[1] == 'E') - { - RefQuals = FrefQualLValue; - ++t; - continue; - } - if (*t == 'O' && t+1 != last && t[1] == 'E') - { - RefQuals = FrefQualRValue; - ++t; - continue; - } - size_t k0 = db.Names.size(); - t1 = parse_type(t, last, db); - size_t k1 = db.Names.size(); - if (t1 == t || t1 == last || k1 < k0) - return first; - t = t1; - } - if (db.Names.empty() || params_begin > db.Names.size()) - return first; - Node* fty = db.make<FunctionType>( - ret_type, db.popTrailingNodeArray(params_begin)); - if (RefQuals) - fty = db.make<FunctionRefQualType>(fty, RefQuals); - db.Names.push_back(fty); - first = t; - } - } - } - return first; -} - -// <pointer-to-member-type> ::= M <class type> <member type> - -const char* -parse_pointer_to_member_type(const char* first, const char* last, Db& db) -{ - if (first != last && *first == 'M') - { - const char* t = parse_type(first+1, last, db); - if (t != first+1) - { - const char* t2 = parse_type(t, last, db); - if (t2 != t) - { - if (db.Names.size() < 2) - return first; - auto func = std::move(db.Names.back()); - db.Names.pop_back(); - auto ClassType = std::move(db.Names.back()); - db.Names.back() = - db.make<PointerToMemberType>(ClassType, func); - first = t2; - } - } - } - return first; -} - -// <array-type> ::= A <positive dimension number> _ <element type> -// ::= A [<dimension expression>] _ <element type> - -const char* -parse_array_type(const char* first, const char* last, Db& db) -{ - if (first != last && *first == 'A' && first+1 != last) - { - if (first[1] == '_') - { - const char* t = parse_type(first+2, last, db); - if (t != first+2) - { - if (db.Names.empty()) - return first; - db.Names.back() = db.make<ArrayType>(db.Names.back()); - first = t; - } - } - else if ('1' <= first[1] && first[1] <= '9') - { - const char* t = parse_number(first+1, last); - if (t != last && *t == '_') - { - const char* t2 = parse_type(t+1, last, db); - if (t2 != t+1) - { - if (db.Names.empty()) - return first; - db.Names.back() = - db.make<ArrayType>(db.Names.back(), - StringView(first + 1, t)); - first = t2; - } - } - } - else - { - const char* t = parse_expression(first+1, last, db); - if (t != first+1 && t != last && *t == '_') - { - const char* t2 = parse_type(++t, last, db); - if (t2 != t) - { - if (db.Names.size() < 2) - return first; - auto base_type = std::move(db.Names.back()); - db.Names.pop_back(); - auto dimension_expr = std::move(db.Names.back()); - db.Names.back() = - db.make<ArrayType>(base_type, dimension_expr); - first = t2; - } - } - } - } - return first; -} - -// <decltype> ::= Dt <expression> E # decltype of an id-expression or class member access (C++0x) -// ::= DT <expression> E # decltype of an expression (C++0x) - -const char* -parse_decltype(const char* first, const char* last, Db& db) -{ - if (last - first >= 4 && first[0] == 'D') - { - switch (first[1]) - { - case 't': - case 'T': - { - const char* t = parse_expression(first+2, last, db); - if (t != first+2 && t != last && *t == 'E') - { - if (db.Names.empty()) - return first; - db.Names.back() = db.make<EnclosingExpr>( - "decltype(", db.Names.back(), ")"); - first = t+1; - } - } - break; - } - } - return first; -} - -// extension: -// <vector-type> ::= Dv <positive dimension number> _ -// <extended element type> -// ::= Dv [<dimension expression>] _ <element type> -// <extended element type> ::= <element type> -// ::= p # AltiVec vector pixel - -const char* -parse_vector_type(const char* first, const char* last, Db& db) -{ - if (last - first > 3 && first[0] == 'D' && first[1] == 'v') - { - if ('1' <= first[2] && first[2] <= '9') - { - const char* t = parse_number(first+2, last); - if (t == last || *t != '_') - return first; - const char* num = first + 2; - size_t sz = static_cast<size_t>(t - num); - if (++t != last) - { - if (*t != 'p') - { - const char* t1 = parse_type(t, last, db); - if (t1 != t) - { - if (db.Names.empty()) - return first; - db.Names.back() = - db.make<VectorType>(db.Names.back(), - StringView(num, num + sz)); - first = t1; - } - } - else - { - ++t; - db.Names.push_back( - db.make<VectorType>(StringView(num, num + sz))); - first = t; - } - } - } - else - { - Node* num = nullptr; - const char* t1 = first+2; - if (*t1 != '_') - { - const char* t = parse_expression(t1, last, db); - if (t != t1) - { - if (db.Names.empty()) - return first; - num = db.Names.back(); - db.Names.pop_back(); - t1 = t; - } - } - if (t1 != last && *t1 == '_' && ++t1 != last) - { - const char* t = parse_type(t1, last, db); - if (t != t1) - { - if (db.Names.empty()) - return first; - if (num) - db.Names.back() = - db.make<VectorType>(db.Names.back(), num); - else - db.Names.back() = - db.make<VectorType>(db.Names.back(), StringView()); - first = t; - } else if (num) - db.Names.push_back(num); - } - } - } - return first; -} - -// <type> ::= <builtin-type> -// ::= <function-type> -// ::= <class-enum-type> -// ::= <array-type> -// ::= <pointer-to-member-type> -// ::= <template-param> -// ::= <template-template-param> <template-args> -// ::= <decltype> -// ::= <substitution> -// ::= <CV-Qualifiers> <type> -// ::= P <type> # pointer-to -// ::= R <type> # reference-to -// ::= O <type> # rvalue reference-to (C++0x) -// ::= C <type> # complex pair (C 2000) -// ::= G <type> # imaginary (C 2000) -// ::= Dp <type> # pack expansion (C++0x) -// ::= U <source-name> <type> # vendor extended type qualifier -// extension := U <objc-name> <objc-type> # objc-type<identifier> -// extension := <vector-type> # <vector-type> starts with Dv - -// <objc-name> ::= <k0 number> objcproto <k1 number> <identifier> # k0 = 9 + <number of digits in k1> + k1 -// <objc-type> := <source-name> # PU<11+>objcproto 11objc_object<source-name> 11objc_object -> id<source-name> - -const char* -parse_type(const char* first, const char* last, Db& db) -{ - if (first != last) - { - switch (*first) - { - case 'r': - case 'V': - case 'K': - { - Qualifiers cv = QualNone; - const char* t = parse_cv_qualifiers(first, last, cv); - if (t != first) - { - bool is_function = *t == 'F'; - size_t k0 = db.Names.size(); - const char* t1 = parse_type(t, last, db); - size_t k1 = db.Names.size(); - if (t1 != t) - { - if (is_function) - db.Subs.popPack(); - db.Subs.pushPack(); - for (size_t k = k0; k < k1; ++k) - { - if (cv) { - if (is_function) - db.Names[k] = db.make<FunctionQualType>( - db.Names[k], cv); - else - db.Names[k] = - db.make<QualType>(db.Names[k], cv); - } - db.Subs.pushSubstitutionIntoPack(db.Names[k]); - } - first = t1; - } - } - } - break; - default: - { - const char* t = parse_builtin_type(first, last, db); - if (t != first) - { - first = t; - } - else - { - switch (*first) - { - case 'A': - t = parse_array_type(first, last, db); - if (t != first) - { - if (db.Names.empty()) - return first; - first = t; - db.Subs.pushSubstitution(db.Names.back()); - } - break; - case 'C': - t = parse_type(first+1, last, db); - if (t != first+1) - { - if (db.Names.empty()) - return first; - db.Names.back() = db.make<PostfixQualifiedType>( - db.Names.back(), " complex"); - first = t; - db.Subs.pushSubstitution(db.Names.back()); - } - break; - case 'F': - t = parse_function_type(first, last, db); - if (t != first) - { - if (db.Names.empty()) - return first; - first = t; - db.Subs.pushSubstitution(db.Names.back()); - } - break; - case 'G': - t = parse_type(first+1, last, db); - if (t != first+1) - { - if (db.Names.empty()) - return first; - db.Names.back() = db.make<PostfixQualifiedType>( - db.Names.back(), " imaginary"); - first = t; - db.Subs.pushSubstitution(db.Names.back()); - } - break; - case 'M': - t = parse_pointer_to_member_type(first, last, db); - if (t != first) - { - if (db.Names.empty()) - return first; - first = t; - db.Subs.pushSubstitution(db.Names.back()); - } - break; - case 'O': - { - size_t k0 = db.Names.size(); - t = parse_type(first+1, last, db); - size_t k1 = db.Names.size(); - if (t != first+1) - { - db.Subs.pushPack(); - for (size_t k = k0; k < k1; ++k) - { - db.Names[k] = - db.make<RValueReferenceType>(db.Names[k]); - db.Subs.pushSubstitutionIntoPack(db.Names[k]); - } - first = t; - } - break; - } - case 'P': - { - size_t k0 = db.Names.size(); - t = parse_type(first+1, last, db); - size_t k1 = db.Names.size(); - if (t != first+1) - { - db.Subs.pushPack(); - for (size_t k = k0; k < k1; ++k) - { - db.Names[k] = db.make<PointerType>(db.Names[k]); - db.Subs.pushSubstitutionIntoPack(db.Names[k]); - } - first = t; - } - break; - } - case 'R': - { - size_t k0 = db.Names.size(); - t = parse_type(first+1, last, db); - size_t k1 = db.Names.size(); - if (t != first+1) - { - db.Subs.pushPack(); - for (size_t k = k0; k < k1; ++k) - { - db.Names[k] = - db.make<LValueReferenceType>(db.Names[k]); - db.Subs.pushSubstitutionIntoPack(db.Names[k]); - } - first = t; - } - break; - } - case 'T': - { - size_t k0 = db.Names.size(); - t = parse_template_param(first, last, db); - size_t k1 = db.Names.size(); - if (t != first) - { - db.Subs.pushPack(); - for (size_t k = k0; k < k1; ++k) - db.Subs.pushSubstitutionIntoPack(db.Names[k]); - if (db.TryToParseTemplateArgs && k1 == k0+1) - { - const char* t1 = parse_template_args(t, last, db); - if (t1 != t) - { - auto args = db.Names.back(); - db.Names.pop_back(); - db.Names.back() = db.make< - NameWithTemplateArgs>( - db.Names.back(), args); - db.Subs.pushSubstitution(db.Names.back()); - t = t1; - } - } - first = t; - } - break; - } - case 'U': - if (first+1 != last) - { - t = parse_source_name(first+1, last, db); - if (t != first+1) - { - const char* t2 = parse_type(t, last, db); - if (t2 != t) - { - if (db.Names.size() < 2) - return first; - auto type = db.Names.back(); - db.Names.pop_back(); - if (db.Names.back()->K != Node::KNameType || - !static_cast<NameType*>(db.Names.back())->getName().startsWith("objcproto")) - { - db.Names.back() = db.make<VendorExtQualType>(type, db.Names.back()); - } - else - { - auto* proto = static_cast<NameType*>(db.Names.back()); - db.Names.pop_back(); - t = parse_source_name(proto->getName().begin() + 9, proto->getName().end(), db); - if (t != proto->getName().begin() + 9) - { - db.Names.back() = db.make<ObjCProtoName>(type, db.Names.back()); - } - else - { - db.Names.push_back(db.make<VendorExtQualType>(type, proto)); - } - } - db.Subs.pushSubstitution(db.Names.back()); - first = t2; - } - } - } - break; - case 'S': - if (first+1 != last && first[1] == 't') - { - t = parse_name(first, last, db); - if (t != first) - { - if (db.Names.empty()) - return first; - db.Subs.pushSubstitution(db.Names.back()); - first = t; - } - } - else - { - t = parse_substitution(first, last, db); - if (t != first) - { - first = t; - // Parsed a substitution. If the substitution is a - // <template-param> it might be followed by <template-args>. - if (db.TryToParseTemplateArgs) - { - t = parse_template_args(first, last, db); - if (t != first) - { - if (db.Names.size() < 2) - return first; - auto template_args = db.Names.back(); - db.Names.pop_back(); - db.Names.back() = db.make< - NameWithTemplateArgs>( - db.Names.back(), template_args); - // Need to create substitution for <template-template-param> <template-args> - db.Subs.pushSubstitution(db.Names.back()); - first = t; - } - } - } - } - break; - case 'D': - if (first+1 != last) - { - switch (first[1]) - { - case 'p': - { - size_t k0 = db.Names.size(); - t = parse_type(first+2, last, db); - size_t k1 = db.Names.size(); - if (t != first+2) - { - db.Subs.pushPack(); - for (size_t k = k0; k < k1; ++k) - db.Subs.pushSubstitutionIntoPack(db.Names[k]); - first = t; - return first; - } - break; - } - case 't': - case 'T': - t = parse_decltype(first, last, db); - if (t != first) - { - if (db.Names.empty()) - return first; - db.Subs.pushSubstitution(db.Names.back()); - first = t; - return first; - } - break; - case 'v': - t = parse_vector_type(first, last, db); - if (t != first) - { - if (db.Names.empty()) - return first; - db.Subs.pushSubstitution(db.Names.back()); - first = t; - return first; - } - break; - } - } - _LIBCPP_FALLTHROUGH(); - default: - // must check for builtin-types before class-enum-types to avoid - // ambiguities with operator-names - t = parse_builtin_type(first, last, db); - if (t != first) - { - first = t; - } - else - { - t = parse_name(first, last, db); - if (t != first) - { - if (db.Names.empty()) - return first; - db.Subs.pushSubstitution(db.Names.back()); - first = t; - } - } - break; - } - } - break; - } - } - } - return first; -} - -// <operator-name> -// ::= aa # && -// ::= ad # & (unary) -// ::= an # & -// ::= aN # &= -// ::= aS # = -// ::= cl # () -// ::= cm # , -// ::= co # ~ -// ::= cv <type> # (cast) -// ::= da # delete[] -// ::= de # * (unary) -// ::= dl # delete -// ::= dv # / -// ::= dV # /= -// ::= eo # ^ -// ::= eO # ^= -// ::= eq # == -// ::= ge # >= -// ::= gt # > -// ::= ix # [] -// ::= le # <= -// ::= li <source-name> # operator "" -// ::= ls # << -// ::= lS # <<= -// ::= lt # < -// ::= mi # - -// ::= mI # -= -// ::= ml # * -// ::= mL # *= -// ::= mm # -- (postfix in <expression> context) -// ::= na # new[] -// ::= ne # != -// ::= ng # - (unary) -// ::= nt # ! -// ::= nw # new -// ::= oo # || -// ::= or # | -// ::= oR # |= -// ::= pm # ->* -// ::= pl # + -// ::= pL # += -// ::= pp # ++ (postfix in <expression> context) -// ::= ps # + (unary) -// ::= pt # -> -// ::= qu # ? -// ::= rm # % -// ::= rM # %= -// ::= rs # >> -// ::= rS # >>= -// ::= v <digit> <source-name> # vendor extended operator - -const char* -parse_operator_name(const char* first, const char* last, Db& db) -{ - if (last - first >= 2) - { - switch (first[0]) - { - case 'a': - switch (first[1]) - { - case 'a': - db.Names.push_back(db.make<NameType>("operator&&")); - first += 2; - break; - case 'd': - case 'n': - db.Names.push_back(db.make<NameType>("operator&")); - first += 2; - break; - case 'N': - db.Names.push_back(db.make<NameType>("operator&=")); - first += 2; - break; - case 'S': - db.Names.push_back(db.make<NameType>("operator=")); - first += 2; - break; - } - break; - case 'c': - switch (first[1]) - { - case 'l': - db.Names.push_back(db.make<NameType>("operator()")); - first += 2; - break; - case 'm': - db.Names.push_back(db.make<NameType>("operator,")); - first += 2; - break; - case 'o': - db.Names.push_back(db.make<NameType>("operator~")); - first += 2; - break; - case 'v': - { - bool TryToParseTemplateArgs = db.TryToParseTemplateArgs; - db.TryToParseTemplateArgs = false; - const char* t = parse_type(first+2, last, db); - db.TryToParseTemplateArgs = TryToParseTemplateArgs; - if (t != first+2) - { - if (db.Names.empty()) - return first; - db.Names.back() = - db.make<ConversionOperatorType>(db.Names.back()); - db.ParsedCtorDtorCV = true; - first = t; - } - } - break; - } - break; - case 'd': - switch (first[1]) - { - case 'a': - db.Names.push_back(db.make<NameType>("operator delete[]")); - first += 2; - break; - case 'e': - db.Names.push_back(db.make<NameType>("operator*")); - first += 2; - break; - case 'l': - db.Names.push_back(db.make<NameType>("operator delete")); - first += 2; - break; - case 'v': - db.Names.push_back(db.make<NameType>("operator/")); - first += 2; - break; - case 'V': - db.Names.push_back(db.make<NameType>("operator/=")); - first += 2; - break; - } - break; - case 'e': - switch (first[1]) - { - case 'o': - db.Names.push_back(db.make<NameType>("operator^")); - first += 2; - break; - case 'O': - db.Names.push_back(db.make<NameType>("operator^=")); - first += 2; - break; - case 'q': - db.Names.push_back(db.make<NameType>("operator==")); - first += 2; - break; - } - break; - case 'g': - switch (first[1]) - { - case 'e': - db.Names.push_back(db.make<NameType>("operator>=")); - first += 2; - break; - case 't': - db.Names.push_back(db.make<NameType>("operator>")); - first += 2; - break; - } - break; - case 'i': - if (first[1] == 'x') - { - db.Names.push_back(db.make<NameType>("operator[]")); - first += 2; - } - break; - case 'l': - switch (first[1]) - { - case 'e': - db.Names.push_back(db.make<NameType>("operator<=")); - first += 2; - break; - case 'i': - { - const char* t = parse_source_name(first+2, last, db); - if (t != first+2) - { - if (db.Names.empty()) - return first; - db.Names.back() = - db.make<LiteralOperator>(db.Names.back()); - first = t; - } - } - break; - case 's': - db.Names.push_back(db.make<NameType>("operator<<")); - first += 2; - break; - case 'S': - db.Names.push_back(db.make<NameType>("operator<<=")); - first += 2; - break; - case 't': - db.Names.push_back(db.make<NameType>("operator<")); - first += 2; - break; - } - break; - case 'm': - switch (first[1]) - { - case 'i': - db.Names.push_back(db.make<NameType>("operator-")); - first += 2; - break; - case 'I': - db.Names.push_back(db.make<NameType>("operator-=")); - first += 2; - break; - case 'l': - db.Names.push_back(db.make<NameType>("operator*")); - first += 2; - break; - case 'L': - db.Names.push_back(db.make<NameType>("operator*=")); - first += 2; - break; - case 'm': - db.Names.push_back(db.make<NameType>("operator--")); - first += 2; - break; - } - break; - case 'n': - switch (first[1]) - { - case 'a': - db.Names.push_back(db.make<NameType>("operator new[]")); - first += 2; - break; - case 'e': - db.Names.push_back(db.make<NameType>("operator!=")); - first += 2; - break; - case 'g': - db.Names.push_back(db.make<NameType>("operator-")); - first += 2; - break; - case 't': - db.Names.push_back(db.make<NameType>("operator!")); - first += 2; - break; - case 'w': - db.Names.push_back(db.make<NameType>("operator new")); - first += 2; - break; - } - break; - case 'o': - switch (first[1]) - { - case 'o': - db.Names.push_back(db.make<NameType>("operator||")); - first += 2; - break; - case 'r': - db.Names.push_back(db.make<NameType>("operator|")); - first += 2; - break; - case 'R': - db.Names.push_back(db.make<NameType>("operator|=")); - first += 2; - break; - } - break; - case 'p': - switch (first[1]) - { - case 'm': - db.Names.push_back(db.make<NameType>("operator->*")); - first += 2; - break; - case 'l': - db.Names.push_back(db.make<NameType>("operator+")); - first += 2; - break; - case 'L': - db.Names.push_back(db.make<NameType>("operator+=")); - first += 2; - break; - case 'p': - db.Names.push_back(db.make<NameType>("operator++")); - first += 2; - break; - case 's': - db.Names.push_back(db.make<NameType>("operator+")); - first += 2; - break; - case 't': - db.Names.push_back(db.make<NameType>("operator->")); - first += 2; - break; - } - break; - case 'q': - if (first[1] == 'u') - { - db.Names.push_back(db.make<NameType>("operator?")); - first += 2; - } - break; - case 'r': - switch (first[1]) - { - case 'm': - db.Names.push_back(db.make<NameType>("operator%")); - first += 2; - break; - case 'M': - db.Names.push_back(db.make<NameType>("operator%=")); - first += 2; - break; - case 's': - db.Names.push_back(db.make<NameType>("operator>>")); - first += 2; - break; - case 'S': - db.Names.push_back(db.make<NameType>("operator>>=")); - first += 2; - break; - } - break; - case 'v': - if (std::isdigit(first[1])) - { - const char* t = parse_source_name(first+2, last, db); - if (t != first+2) - { - if (db.Names.empty()) - return first; - db.Names.back() = - db.make<ConversionOperatorType>(db.Names.back()); - first = t; - } - } - break; - } - } - return first; -} - -const char* -parse_integer_literal(const char* first, const char* last, StringView lit, Db& db) -{ - const char* t = parse_number(first, last); - if (t != first && t != last && *t == 'E') - { - db.Names.push_back( - db.make<IntegerExpr>(lit, StringView(first, t))); - first = t+1; - } - return first; -} - -// <expr-primary> ::= L <type> <value number> E # integer literal -// ::= L <type> <value float> E # floating literal -// ::= L <string type> E # string literal -// ::= L <nullptr type> E # nullptr literal (i.e., "LDnE") -// ::= L <type> <real-part float> _ <imag-part float> E # complex floating point literal (C 2000) -// ::= L <mangled-name> E # external name - -const char* -parse_expr_primary(const char* first, const char* last, Db& db) -{ - if (last - first >= 4 && *first == 'L') - { - switch (first[1]) - { - case 'w': - { - const char* t = parse_integer_literal(first+2, last, "wchar_t", db); - if (t != first+2) - first = t; - } - break; - case 'b': - if (first[3] == 'E') - { - switch (first[2]) - { - case '0': - db.Names.push_back(db.make<BoolExpr>(0)); - first += 4; - break; - case '1': - db.Names.push_back(db.make<BoolExpr>(1)); - first += 4; - break; - } - } - break; - case 'c': - { - const char* t = parse_integer_literal(first+2, last, "char", db); - if (t != first+2) - first = t; - } - break; - case 'a': - { - const char* t = parse_integer_literal(first+2, last, "signed char", db); - if (t != first+2) - first = t; - } - break; - case 'h': - { - const char* t = parse_integer_literal(first+2, last, "unsigned char", db); - if (t != first+2) - first = t; - } - break; - case 's': - { - const char* t = parse_integer_literal(first+2, last, "short", db); - if (t != first+2) - first = t; - } - break; - case 't': - { - const char* t = parse_integer_literal(first+2, last, "unsigned short", db); - if (t != first+2) - first = t; - } - break; - case 'i': - { - const char* t = parse_integer_literal(first+2, last, "", db); - if (t != first+2) - first = t; - } - break; - case 'j': - { - const char* t = parse_integer_literal(first+2, last, "u", db); - if (t != first+2) - first = t; - } - break; - case 'l': - { - const char* t = parse_integer_literal(first+2, last, "l", db); - if (t != first+2) - first = t; - } - break; - case 'm': - { - const char* t = parse_integer_literal(first+2, last, "ul", db); - if (t != first+2) - first = t; - } - break; - case 'x': - { - const char* t = parse_integer_literal(first+2, last, "ll", db); - if (t != first+2) - first = t; - } - break; - case 'y': - { - const char* t = parse_integer_literal(first+2, last, "ull", db); - if (t != first+2) - first = t; - } - break; - case 'n': - { - const char* t = parse_integer_literal(first+2, last, "__int128", db); - if (t != first+2) - first = t; - } - break; - case 'o': - { - const char* t = parse_integer_literal(first+2, last, "unsigned __int128", db); - if (t != first+2) - first = t; - } - break; - case 'f': - { - const char* t = parse_floating_number<float>(first+2, last, db); - if (t != first+2) - first = t; - } - break; - case 'd': - { - const char* t = parse_floating_number<double>(first+2, last, db); - if (t != first+2) - first = t; - } - break; - case 'e': - { - const char* t = parse_floating_number<long double>(first+2, last, db); - if (t != first+2) - first = t; - } - break; - case '_': - if (first[2] == 'Z') - { - const char* t = parse_encoding(first+3, last, db); - if (t != first+3 && t != last && *t == 'E') - first = t+1; - } - break; - case 'T': - // Invalid mangled name per - // http://sourcerytools.com/pipermail/cxx-abi-dev/2011-August/002422.html - break; - default: - { - // might be named type - const char* t = parse_type(first+1, last, db); - if (t != first+1 && t != last) - { - if (*t != 'E') - { - const char* n = t; - for (; n != last && isdigit(*n); ++n) - ; - if (n != t && n != last && *n == 'E') - { - if (db.Names.empty()) - return first; - db.Names.back() = db.make<IntegerCastExpr>( - db.Names.back(), StringView(t, n)); - first = n+1; - break; - } - } - else - { - first = t+1; - break; - } - } - } - } - } - return first; -} - -Node* maybe_change_special_sub_name(Node* inp, Db& db) -{ - if (inp->K != Node::KSpecialSubstitution) - return inp; - auto Kind = static_cast<SpecialSubstitution*>(inp)->SSK; - switch (Kind) - { - case SpecialSubKind::string: - case SpecialSubKind::istream: - case SpecialSubKind::ostream: - case SpecialSubKind::iostream: - return db.make<ExpandedSpecialSubstitution>(Kind); - default: - break; - } - return inp; -} - -// <ctor-dtor-name> ::= C1 # complete object constructor -// ::= C2 # base object constructor -// ::= C3 # complete object allocating constructor -// extension ::= C5 # ? -// ::= D0 # deleting destructor -// ::= D1 # complete object destructor -// ::= D2 # base object destructor -// extension ::= D5 # ? - -const char* -parse_ctor_dtor_name(const char* first, const char* last, Db& db) -{ - if (last-first >= 2 && !db.Names.empty()) - { - switch (first[0]) - { - case 'C': - switch (first[1]) - { - case '1': - case '2': - case '3': - case '5': - if (db.Names.empty()) - return first; - db.Names.back() = - maybe_change_special_sub_name(db.Names.back(), db); - db.Names.push_back( - db.make<CtorDtorName>(db.Names.back(), false)); - first += 2; - db.ParsedCtorDtorCV = true; - break; - } - break; - case 'D': - switch (first[1]) - { - case '0': - case '1': - case '2': - case '5': - if (db.Names.empty()) - return first; - db.Names.push_back( - db.make<CtorDtorName>(db.Names.back(), true)); - first += 2; - db.ParsedCtorDtorCV = true; - break; - } - break; - } - } - return first; -} - -// <unnamed-type-name> ::= Ut [ <nonnegative number> ] _ -// ::= <closure-type-name> -// -// <closure-type-name> ::= Ul <lambda-sig> E [ <nonnegative number> ] _ -// -// <lambda-sig> ::= <parameter type>+ # Parameter types or "v" if the lambda has no parameters - -const char* -parse_unnamed_type_name(const char* first, const char* last, Db& db) -{ - if (last - first > 2 && first[0] == 'U') - { - char type = first[1]; - switch (type) - { - case 't': - { - const char* t0 = first+2; - if (t0 == last) - return first; - StringView count; - if (std::isdigit(*t0)) - { - const char* t1 = t0 + 1; - while (t1 != last && std::isdigit(*t1)) - ++t1; - count = StringView(t0, t1); - t0 = t1; - } - if (t0 == last || *t0 != '_') - return first; - db.Names.push_back(db.make<UnnamedTypeName>(count)); - first = t0 + 1; - } - break; - case 'l': - { - size_t begin_pos = db.Names.size(); - const char* t0 = first+2; - NodeArray lambda_params; - if (first[2] == 'v') - { - ++t0; - } - else - { - while (true) - { - const char* t1 = parse_type(t0, last, db); - if (t1 == t0) - break; - t0 = t1; - } - if (db.Names.size() < begin_pos) - return first; - lambda_params = db.popTrailingNodeArray(begin_pos); - } - if (t0 == last || *t0 != 'E') - return first; - ++t0; - if (t0 == last) - return first; - StringView count; - if (std::isdigit(*t0)) - { - const char* t1 = t0 + 1; - while (t1 != last && std::isdigit(*t1)) - ++t1; - count = StringView(t0, t1); - t0 = t1; - } - if (t0 == last || *t0 != '_') - return first; - db.Names.push_back(db.make<LambdaTypeName>(lambda_params, count)); - first = t0 + 1; - } - break; - } - } - return first; -} - -// <unqualified-name> ::= <operator-name> -// ::= <ctor-dtor-name> -// ::= <source-name> -// ::= <unnamed-type-name> - -const char* -parse_unqualified_name(const char* first, const char* last, Db& db) -{ - if (first != last) - { - const char* t; - switch (*first) - { - case 'C': - case 'D': - t = parse_ctor_dtor_name(first, last, db); - if (t != first) - first = t; - break; - case 'U': - t = parse_unnamed_type_name(first, last, db); - if (t != first) - first = t; - break; - case '1': - case '2': - case '3': - case '4': - case '5': - case '6': - case '7': - case '8': - case '9': - t = parse_source_name(first, last, db); - if (t != first) - first = t; - break; - default: - t = parse_operator_name(first, last, db); - if (t != first) - first = t; - break; - }; - } - return first; -} - -// <unscoped-name> ::= <unqualified-name> -// ::= St <unqualified-name> # ::std:: -// extension ::= StL<unqualified-name> - -const char* -parse_unscoped_name(const char* first, const char* last, Db& db) -{ - if (last - first >= 2) - { - const char* t0 = first; - bool St = false; - if (first[0] == 'S' && first[1] == 't') - { - t0 += 2; - St = true; - if (t0 != last && *t0 == 'L') - ++t0; - } - const char* t1 = parse_unqualified_name(t0, last, db); - if (t1 != t0) - { - if (St) - { - if (db.Names.empty()) - return first; - db.Names.back() = - db.make<StdQualifiedName>(db.Names.back()); - } - first = t1; - } - } - return first; -} - -// at <type> # alignof (a type) - -const char* -parse_alignof_type(const char* first, const char* last, Db& db) -{ - if (last - first >= 3 && first[0] == 'a' && first[1] == 't') - { - const char* t = parse_type(first+2, last, db); - if (t != first+2) - { - if (db.Names.empty()) - return first; - db.Names.back() = - db.make<EnclosingExpr>("alignof (", db.Names.back(), ")"); - first = t; - } - } - return first; -} - -// az <expression> # alignof (a expression) - -const char* -parse_alignof_expr(const char* first, const char* last, Db& db) -{ - if (last - first >= 3 && first[0] == 'a' && first[1] == 'z') - { - const char* t = parse_expression(first+2, last, db); - if (t != first+2) - { - if (db.Names.empty()) - return first; - db.Names.back() = - db.make<EnclosingExpr>("alignof (", db.Names.back(), ")"); - first = t; - } - } - return first; -} - -const char* -parse_noexcept_expression(const char* first, const char* last, Db& db) -{ - const char* t1 = parse_expression(first, last, db); - if (t1 != first) - { - if (db.Names.empty()) - return first; - db.Names.back() = - db.make<EnclosingExpr>("noexcept (", db.Names.back(), ")"); - first = t1; - } - return first; -} - -const char* -parse_prefix_expression(const char* first, const char* last, StringView op, Db& db) -{ - const char* t1 = parse_expression(first, last, db); - if (t1 != first) - { - if (db.Names.empty()) - return first; - db.Names.back() = db.make<PrefixExpr>(op, db.Names.back()); - first = t1; - } - return first; -} - -const char* -parse_binary_expression(const char* first, const char* last, StringView op, Db& db) -{ - const char* t1 = parse_expression(first, last, db); - if (t1 != first) - { - const char* t2 = parse_expression(t1, last, db); - if (t2 != t1) - { - if (db.Names.size() < 2) - return first; - auto op2 = db.Names.back(); - db.Names.pop_back(); - auto op1 = db.Names.back(); - db.Names.back() = db.make<BinaryExpr>(op1, op, op2); - first = t2; - } - } - return first; -} - -// <expression> ::= <unary operator-name> <expression> -// ::= <binary operator-name> <expression> <expression> -// ::= <ternary operator-name> <expression> <expression> <expression> -// ::= cl <expression>+ E # call -// ::= cv <type> <expression> # conversion with one argument -// ::= cv <type> _ <expression>* E # conversion with a different number of arguments -// ::= [gs] nw <expression>* _ <type> E # new (expr-list) type -// ::= [gs] nw <expression>* _ <type> <initializer> # new (expr-list) type (init) -// ::= [gs] na <expression>* _ <type> E # new[] (expr-list) type -// ::= [gs] na <expression>* _ <type> <initializer> # new[] (expr-list) type (init) -// ::= [gs] dl <expression> # delete expression -// ::= [gs] da <expression> # delete[] expression -// ::= pp_ <expression> # prefix ++ -// ::= mm_ <expression> # prefix -- -// ::= ti <type> # typeid (type) -// ::= te <expression> # typeid (expression) -// ::= dc <type> <expression> # dynamic_cast<type> (expression) -// ::= sc <type> <expression> # static_cast<type> (expression) -// ::= cc <type> <expression> # const_cast<type> (expression) -// ::= rc <type> <expression> # reinterpret_cast<type> (expression) -// ::= st <type> # sizeof (a type) -// ::= sz <expression> # sizeof (an expression) -// ::= at <type> # alignof (a type) -// ::= az <expression> # alignof (an expression) -// ::= nx <expression> # noexcept (expression) -// ::= <template-param> -// ::= <function-param> -// ::= dt <expression> <unresolved-name> # expr.name -// ::= pt <expression> <unresolved-name> # expr->name -// ::= ds <expression> <expression> # expr.*expr -// ::= sZ <template-param> # size of a parameter pack -// ::= sZ <function-param> # size of a function parameter pack -// ::= sp <expression> # pack expansion -// ::= tw <expression> # throw expression -// ::= tr # throw with no operand (rethrow) -// ::= <unresolved-name> # f(p), N::f(p), ::f(p), -// # freestanding dependent name (e.g., T::x), -// # objectless nonstatic member reference -// ::= <expr-primary> - -const char* -parse_expression(const char* first, const char* last, Db& db) -{ - if (last - first >= 2) - { - const char* t = first; - bool parsed_gs = false; - if (last - first >= 4 && t[0] == 'g' && t[1] == 's') - { - t += 2; - parsed_gs = true; - } - switch (*t) - { - case 'L': - first = parse_expr_primary(first, last, db); - break; - case 'T': - first = parse_template_param(first, last, db); - break; - case 'f': - first = parse_function_param(first, last, db); - break; - case 'a': - switch (t[1]) - { - case 'a': - t = parse_binary_expression(first+2, last, "&&", db); - if (t != first+2) - first = t; - break; - case 'd': - t = parse_prefix_expression(first+2, last, "&", db); - if (t != first+2) - first = t; - break; - case 'n': - t = parse_binary_expression(first+2, last, "&", db); - if (t != first+2) - first = t; - break; - case 'N': - t = parse_binary_expression(first+2, last, "&=", db); - if (t != first+2) - first = t; - break; - case 'S': - t = parse_binary_expression(first+2, last, "=", db); - if (t != first+2) - first = t; - break; - case 't': - first = parse_alignof_type(first, last, db); - break; - case 'z': - first = parse_alignof_expr(first, last, db); - break; - } - break; - case 'c': - switch (t[1]) - { - case 'c': - first = parse_const_cast_expr(first, last, db); - break; - case 'l': - first = parse_call_expr(first, last, db); - break; - case 'm': - t = parse_binary_expression(first+2, last, ",", db); - if (t != first+2) - first = t; - break; - case 'o': - t = parse_prefix_expression(first+2, last, "~", db); - if (t != first+2) - first = t; - break; - case 'v': - first = parse_conversion_expr(first, last, db); - break; - } - break; - case 'd': - switch (t[1]) - { - case 'a': - { - const char* t1 = parse_expression(t+2, last, db); - if (t1 != t+2) - { - if (db.Names.empty()) - return first; - db.Names.back() = db.make<DeleteExpr>( - db.Names.back(), parsed_gs, /*is_array=*/true); - first = t1; - } - } - break; - case 'c': - first = parse_dynamic_cast_expr(first, last, db); - break; - case 'e': - t = parse_prefix_expression(first+2, last, "*", db); - if (t != first+2) - first = t; - break; - case 'l': - { - const char* t1 = parse_expression(t+2, last, db); - if (t1 != t+2) - { - if (db.Names.empty()) - return first; - db.Names.back() = db.make<DeleteExpr>( - db.Names.back(), parsed_gs, /*is_array=*/false); - first = t1; - } - } - break; - case 'n': - return parse_unresolved_name(first, last, db); - case 's': - first = parse_dot_star_expr(first, last, db); - break; - case 't': - first = parse_dot_expr(first, last, db); - break; - case 'v': - t = parse_binary_expression(first+2, last, "/", db); - if (t != first+2) - first = t; - break; - case 'V': - t = parse_binary_expression(first+2, last, "/=", db); - if (t != first+2) - first = t; - break; - } - break; - case 'e': - switch (t[1]) - { - case 'o': - t = parse_binary_expression(first+2, last, "^", db); - if (t != first+2) - first = t; - break; - case 'O': - t = parse_binary_expression(first+2, last, "^=", db); - if (t != first+2) - first = t; - break; - case 'q': - t = parse_binary_expression(first+2, last, "==", db); - if (t != first+2) - first = t; - break; - } - break; - case 'g': - switch (t[1]) - { - case 'e': - t = parse_binary_expression(first+2, last, ">=", db); - if (t != first+2) - first = t; - break; - case 't': - t = parse_binary_expression(first+2, last, ">", db); - if (t != first+2) - first = t; - break; - } - break; - case 'i': - if (t[1] == 'x') - { - const char* t1 = parse_expression(first+2, last, db); - if (t1 != first+2) - { - const char* t2 = parse_expression(t1, last, db); - if (t2 != t1) - { - if (db.Names.size() < 2) - return first; - auto op2 = db.Names.back(); - db.Names.pop_back(); - auto op1 = db.Names.back(); - db.Names.back() = - db.make<ArraySubscriptExpr>(op1, op2); - first = t2; - } - else if (!db.Names.empty()) - db.Names.pop_back(); - } - } - break; - case 'l': - switch (t[1]) - { - case 'e': - t = parse_binary_expression(first+2, last, "<=", db); - if (t != first+2) - first = t; - break; - case 's': - t = parse_binary_expression(first+2, last, "<<", db); - if (t != first+2) - first = t; - break; - case 'S': - t = parse_binary_expression(first+2, last, "<<=", db); - if (t != first+2) - first = t; - break; - case 't': - t = parse_binary_expression(first+2, last, "<", db); - if (t != first+2) - first = t; - break; - } - break; - case 'm': - switch (t[1]) - { - case 'i': - t = parse_binary_expression(first+2, last, "-", db); - if (t != first+2) - first = t; - break; - case 'I': - t = parse_binary_expression(first+2, last, "-=", db); - if (t != first+2) - first = t; - break; - case 'l': - t = parse_binary_expression(first+2, last, "*", db); - if (t != first+2) - first = t; - break; - case 'L': - t = parse_binary_expression(first+2, last, "*=", db); - if (t != first+2) - first = t; - break; - case 'm': - if (first+2 != last && first[2] == '_') - { - t = parse_prefix_expression(first+3, last, "--", db); - if (t != first+3) - first = t; - } - else - { - const char* t1 = parse_expression(first+2, last, db); - if (t1 != first+2) - { - if (db.Names.empty()) - return first; - db.Names.back() = - db.make<PostfixExpr>(db.Names.back(), "--"); - first = t1; - } - } - break; - } - break; - case 'n': - switch (t[1]) - { - case 'a': - case 'w': - first = parse_new_expr(first, last, db); - break; - case 'e': - t = parse_binary_expression(first+2, last, "!=", db); - if (t != first+2) - first = t; - break; - case 'g': - t = parse_prefix_expression(first+2, last, "-", db); - if (t != first+2) - first = t; - break; - case 't': - t = parse_prefix_expression(first+2, last, "!", db); - if (t != first+2) - first = t; - break; - case 'x': - t = parse_noexcept_expression(first+2, last, db); - if (t != first+2) - first = t; - break; - } - break; - case 'o': - switch (t[1]) - { - case 'n': - return parse_unresolved_name(first, last, db); - case 'o': - t = parse_binary_expression(first+2, last, "||", db); - if (t != first+2) - first = t; - break; - case 'r': - t = parse_binary_expression(first+2, last, "|", db); - if (t != first+2) - first = t; - break; - case 'R': - t = parse_binary_expression(first+2, last, "|=", db); - if (t != first+2) - first = t; - break; - } - break; - case 'p': - switch (t[1]) - { - case 'm': - t = parse_binary_expression(first+2, last, "->*", db); - if (t != first+2) - first = t; - break; - case 'l': - t = parse_binary_expression(first+2, last, "+", db); - if (t != first+2) - first = t; - break; - case 'L': - t = parse_binary_expression(first+2, last, "+=", db); - if (t != first+2) - first = t; - break; - case 'p': - if (first+2 != last && first[2] == '_') - { - t = parse_prefix_expression(first+3, last, "++", db); - if (t != first+3) - first = t; - } - else - { - const char* t1 = parse_expression(first+2, last, db); - if (t1 != first+2) - { - if (db.Names.empty()) - return first; - db.Names.back() = - db.make<PostfixExpr>(db.Names.back(), "++"); - first = t1; - } - } - break; - case 's': - t = parse_prefix_expression(first+2, last, "+", db); - if (t != first+2) - first = t; - break; - case 't': - first = parse_arrow_expr(first, last, db); - break; - } - break; - case 'q': - if (t[1] == 'u') - { - const char* t1 = parse_expression(first+2, last, db); - if (t1 != first+2) - { - const char* t2 = parse_expression(t1, last, db); - if (t2 != t1) - { - const char* t3 = parse_expression(t2, last, db); - if (t3 != t2) - { - if (db.Names.size() < 3) - return first; - auto op3 = db.Names.back(); - db.Names.pop_back(); - auto op2 = db.Names.back(); - db.Names.pop_back(); - auto op1 = db.Names.back(); - db.Names.back() = - db.make<ConditionalExpr>(op1, op2, op3); - first = t3; - } - else - { - if (db.Names.size() < 2) - return first; - db.Names.pop_back(); - db.Names.pop_back(); - } - } - else if (!db.Names.empty()) - db.Names.pop_back(); - } - } - break; - case 'r': - switch (t[1]) - { - case 'c': - first = parse_reinterpret_cast_expr(first, last, db); - break; - case 'm': - t = parse_binary_expression(first+2, last, "%", db); - if (t != first+2) - first = t; - break; - case 'M': - t = parse_binary_expression(first+2, last, "%=", db); - if (t != first+2) - first = t; - break; - case 's': - t = parse_binary_expression(first+2, last, ">>", db); - if (t != first+2) - first = t; - break; - case 'S': - t = parse_binary_expression(first+2, last, ">>=", db); - if (t != first+2) - first = t; - break; - } - break; - case 's': - switch (t[1]) - { - case 'c': - first = parse_static_cast_expr(first, last, db); - break; - case 'p': - first = parse_pack_expansion(first, last, db); - break; - case 'r': - return parse_unresolved_name(first, last, db); - case 't': - first = parse_sizeof_type_expr(first, last, db); - break; - case 'z': - first = parse_sizeof_expr_expr(first, last, db); - break; - case 'Z': - if (last - t >= 3) - { - switch (t[2]) - { - case 'T': - first = parse_sizeof_param_pack_expr(first, last, db); - break; - case 'f': - first = parse_sizeof_function_param_pack_expr(first, last, db); - break; - } - } - break; - } - break; - case 't': - switch (t[1]) - { - case 'e': - case 'i': - first = parse_typeid_expr(first, last, db); - break; - case 'r': - db.Names.push_back(db.make<NameType>("throw")); - first += 2; - break; - case 'w': - first = parse_throw_expr(first, last, db); - break; - } - break; - case '1': - case '2': - case '3': - case '4': - case '5': - case '6': - case '7': - case '8': - case '9': - return parse_unresolved_name(first, last, db); - } - } - return first; -} - -// <template-arg> ::= <type> # type or template -// ::= X <expression> E # expression -// ::= <expr-primary> # simple expressions -// ::= J <template-arg>* E # argument pack -// ::= LZ <encoding> E # extension - -const char* -parse_template_arg(const char* first, const char* last, Db& db) -{ - if (first != last) - { - const char* t; - switch (*first) - { - case 'X': - t = parse_expression(first+1, last, db); - if (t != first+1) - { - if (t != last && *t == 'E') - first = t+1; - } - break; - case 'J': - t = first+1; - if (t == last) - return first; - while (*t != 'E') - { - const char* t1 = parse_template_arg(t, last, db); - if (t1 == t) - return first; - t = t1; - } - first = t+1; - break; - case 'L': - // <expr-primary> or LZ <encoding> E - if (first+1 != last && first[1] == 'Z') - { - t = parse_encoding(first+2, last, db); - if (t != first+2 && t != last && *t == 'E') - first = t+1; - } - else - first = parse_expr_primary(first, last, db); - break; - default: - // <type> - first = parse_type(first, last, db); - break; - } - } - return first; -} - -// <template-args> ::= I <template-arg>* E -// extension, the abi says <template-arg>+ - -const char* -parse_template_args(const char* first, const char* last, Db& db) -{ - if (last - first >= 2 && *first == 'I') - { - if (db.TagTemplates) - db.TemplateParams.clear(); - const char* t = first+1; - size_t begin_idx = db.Names.size(); - while (*t != 'E') - { - if (db.TagTemplates) - { - auto TmpParams = std::move(db.TemplateParams); - size_t k0 = db.Names.size(); - const char* t1 = parse_template_arg(t, last, db); - size_t k1 = db.Names.size(); - db.TemplateParams = std::move(TmpParams); - - if (t1 == t || t1 == last || k0 > k1) - return first; - db.TemplateParams.pushPack(); - for (size_t k = k0; k < k1; ++k) - db.TemplateParams.pushSubstitutionIntoPack(db.Names[k]); - t = t1; - continue; - } - size_t k0 = db.Names.size(); - const char* t1 = parse_template_arg(t, last, db); - size_t k1 = db.Names.size(); - if (t1 == t || t1 == last || k0 > k1) - return first; - t = t1; - } - if (begin_idx > db.Names.size()) - return first; - first = t + 1; - TemplateParams* tp = db.make<TemplateParams>( - db.popTrailingNodeArray(begin_idx)); - db.Names.push_back(tp); - } - return first; -} - -// <nested-name> ::= N [<CV-Qualifiers>] [<ref-qualifier>] <prefix> <unqualified-name> E -// ::= N [<CV-Qualifiers>] [<ref-qualifier>] <template-prefix> <template-args> E -// -// <prefix> ::= <prefix> <unqualified-name> -// ::= <template-prefix> <template-args> -// ::= <template-param> -// ::= <decltype> -// ::= # empty -// ::= <substitution> -// ::= <prefix> <data-member-prefix> -// extension ::= L -// -// <template-prefix> ::= <prefix> <template unqualified-name> -// ::= <template-param> -// ::= <substitution> - -const char* -parse_nested_name(const char* first, const char* last, Db& db, - bool* ends_with_template_args) -{ - if (first != last && *first == 'N') - { - Qualifiers cv; - const char* t0 = parse_cv_qualifiers(first+1, last, cv); - if (t0 == last) - return first; - db.RefQuals = FrefQualNone; - if (*t0 == 'R') - { - db.RefQuals = FrefQualLValue; - ++t0; - } - else if (*t0 == 'O') - { - db.RefQuals = FrefQualRValue; - ++t0; - } - db.Names.push_back(db.make<EmptyName>()); - if (last - t0 >= 2 && t0[0] == 'S' && t0[1] == 't') - { - t0 += 2; - db.Names.back() = db.make<NameType>("std"); - } - if (t0 == last) - return first; - bool pop_subs = false; - bool component_ends_with_template_args = false; - while (*t0 != 'E') - { - component_ends_with_template_args = false; - const char* t1; - switch (*t0) - { - case 'S': - if (t0 + 1 != last && t0[1] == 't') - goto do_parse_unqualified_name; - t1 = parse_substitution(t0, last, db); - if (t1 != t0 && t1 != last) - { - if (db.Names.size() < 2) - return first; - auto name = db.Names.back(); - db.Names.pop_back(); - if (db.Names.back()->K != Node::KEmptyName) - { - db.Names.back() = db.make<QualifiedName>( - db.Names.back(), name); - db.Subs.pushSubstitution(db.Names.back()); - } - else - db.Names.back() = name; - pop_subs = true; - t0 = t1; - } - else - return first; - break; - case 'T': - t1 = parse_template_param(t0, last, db); - if (t1 != t0 && t1 != last) - { - if (db.Names.size() < 2) - return first; - auto name = db.Names.back(); - db.Names.pop_back(); - if (db.Names.back()->K != Node::KEmptyName) - db.Names.back() = - db.make<QualifiedName>(db.Names.back(), name); - else - db.Names.back() = name; - db.Subs.pushSubstitution(db.Names.back()); - pop_subs = true; - t0 = t1; - } - else - return first; - break; - case 'D': - if (t0 + 1 != last && t0[1] != 't' && t0[1] != 'T') - goto do_parse_unqualified_name; - t1 = parse_decltype(t0, last, db); - if (t1 != t0 && t1 != last) - { - if (db.Names.size() < 2) - return first; - auto name = db.Names.back(); - db.Names.pop_back(); - if (db.Names.back()->K != Node::KEmptyName) - db.Names.back() = - db.make<QualifiedName>(db.Names.back(), name); - else - db.Names.back() = name; - db.Subs.pushSubstitution(db.Names.back()); - pop_subs = true; - t0 = t1; - } - else - return first; - break; - case 'I': - t1 = parse_template_args(t0, last, db); - if (t1 != t0 && t1 != last) - { - if (db.Names.size() < 2) - return first; - auto name = db.Names.back(); - db.Names.pop_back(); - db.Names.back() = db.make<NameWithTemplateArgs>( - db.Names.back(), name); - db.Subs.pushSubstitution(db.Names.back()); - t0 = t1; - component_ends_with_template_args = true; - } - else - return first; - break; - case 'L': - if (++t0 == last) - return first; - break; - default: - do_parse_unqualified_name: - t1 = parse_unqualified_name(t0, last, db); - if (t1 != t0 && t1 != last) - { - if (db.Names.size() < 2) - return first; - auto name = db.Names.back(); - db.Names.pop_back(); - if (db.Names.back()->K != Node::KEmptyName) - db.Names.back() = - db.make<QualifiedName>(db.Names.back(), name); - else - db.Names.back() = name; - db.Subs.pushSubstitution(db.Names.back()); - pop_subs = true; - t0 = t1; - } - else - return first; - } - } - first = t0 + 1; - db.CV = cv; - if (pop_subs && !db.Subs.empty()) - db.Subs.popPack(); - if (ends_with_template_args) - *ends_with_template_args = component_ends_with_template_args; - } - return first; -} - -// <discriminator> := _ <non-negative number> # when number < 10 -// := __ <non-negative number> _ # when number >= 10 -// extension := decimal-digit+ # at the end of string - -const char* -parse_discriminator(const char* first, const char* last) -{ - // parse but ignore discriminator - if (first != last) - { - if (*first == '_') - { - const char* t1 = first+1; - if (t1 != last) - { - if (std::isdigit(*t1)) - first = t1+1; - else if (*t1 == '_') - { - for (++t1; t1 != last && std::isdigit(*t1); ++t1) - ; - if (t1 != last && *t1 == '_') - first = t1 + 1; - } - } - } - else if (std::isdigit(*first)) - { - const char* t1 = first+1; - for (; t1 != last && std::isdigit(*t1); ++t1) - ; - if (t1 == last) - first = last; - } - } - return first; -} - -// <local-name> := Z <function encoding> E <entity name> [<discriminator>] -// := Z <function encoding> E s [<discriminator>] -// := Z <function encoding> Ed [ <parameter number> ] _ <entity name> - -const char* -parse_local_name(const char* first, const char* last, Db& db, - bool* ends_with_template_args) -{ - if (first != last && *first == 'Z') - { - const char* t = parse_encoding(first+1, last, db); - if (t != first+1 && t != last && *t == 'E' && ++t != last) - { - switch (*t) - { - case 's': - first = parse_discriminator(t+1, last); - if (db.Names.empty()) - return first; - db.Names.back() = db.make<QualifiedName>( - db.Names.back(), db.make<NameType>("string literal")); - break; - case 'd': - if (++t != last) - { - const char* t1 = parse_number(t, last); - if (t1 != last && *t1 == '_') - { - t = t1 + 1; - t1 = parse_name(t, last, db, - ends_with_template_args); - if (t1 != t) - { - if (db.Names.size() < 2) - return first; - auto name = db.Names.back(); - db.Names.pop_back(); - if (db.Names.empty()) - return first; - db.Names.back() = - db.make<QualifiedName>(db.Names.back(), name); - first = t1; - } - else if (!db.Names.empty()) - db.Names.pop_back(); - } - } - break; - default: - { - const char* t1 = parse_name(t, last, db, - ends_with_template_args); - if (t1 != t) - { - // parse but ignore discriminator - first = parse_discriminator(t1, last); - if (db.Names.size() < 2) - return first; - auto name = db.Names.back(); - db.Names.pop_back(); - if (db.Names.empty()) - return first; - db.Names.back() = - db.make<QualifiedName>(db.Names.back(), name); - } - else if (!db.Names.empty()) - db.Names.pop_back(); - } - break; - } - } - } - return first; -} - -// <name> ::= <nested-name> // N -// ::= <local-name> # See Scope Encoding below // Z -// ::= <unscoped-template-name> <template-args> -// ::= <unscoped-name> - -// <unscoped-template-name> ::= <unscoped-name> -// ::= <substitution> - -const char* -parse_name(const char* first, const char* last, Db& db, - bool* ends_with_template_args) -{ - if (last - first >= 2) - { - const char* t0 = first; - // extension: ignore L here - if (*t0 == 'L') - ++t0; - switch (*t0) - { - case 'N': - { - const char* t1 = parse_nested_name(t0, last, db, - ends_with_template_args); - if (t1 != t0) - first = t1; - break; - } - case 'Z': - { - const char* t1 = parse_local_name(t0, last, db, - ends_with_template_args); - if (t1 != t0) - first = t1; - break; - } - default: - { - const char* t1 = parse_unscoped_name(t0, last, db); - if (t1 != t0) - { - if (t1 != last && *t1 == 'I') // <unscoped-template-name> <template-args> - { - if (db.Names.empty()) - return first; - db.Subs.pushSubstitution(db.Names.back()); - t0 = t1; - t1 = parse_template_args(t0, last, db); - if (t1 != t0) - { - if (db.Names.size() < 2) - return first; - auto tmp = db.Names.back(); - db.Names.pop_back(); - if (db.Names.empty()) - return first; - db.Names.back() = - db.make<NameWithTemplateArgs>( - db.Names.back(), tmp); - first = t1; - if (ends_with_template_args) - *ends_with_template_args = true; - } - } - else // <unscoped-name> - first = t1; - } - else - { // try <substitution> <template-args> - t1 = parse_substitution(t0, last, db); - if (t1 != t0 && t1 != last && *t1 == 'I') - { - t0 = t1; - t1 = parse_template_args(t0, last, db); - if (t1 != t0) - { - if (db.Names.size() < 2) - return first; - auto tmp = db.Names.back(); - db.Names.pop_back(); - if (db.Names.empty()) - return first; - db.Names.back() = - db.make<NameWithTemplateArgs>( - db.Names.back(), tmp); - first = t1; - if (ends_with_template_args) - *ends_with_template_args = true; - } - } - } - break; - } - } - } - return first; -} - -// <call-offset> ::= h <nv-offset> _ -// ::= v <v-offset> _ -// -// <nv-offset> ::= <offset number> -// # non-virtual base override -// -// <v-offset> ::= <offset number> _ <virtual offset number> -// # virtual base override, with vcall offset - -const char* -parse_call_offset(const char* first, const char* last) -{ - if (first != last) - { - switch (*first) - { - case 'h': - { - const char* t = parse_number(first + 1, last); - if (t != first + 1 && t != last && *t == '_') - first = t + 1; - } - break; - case 'v': - { - const char* t = parse_number(first + 1, last); - if (t != first + 1 && t != last && *t == '_') - { - const char* t2 = parse_number(++t, last); - if (t2 != t && t2 != last && *t2 == '_') - first = t2 + 1; - } - } - break; - } - } - return first; -} - -// <special-name> ::= TV <type> # virtual table -// ::= TT <type> # VTT structure (construction vtable index) -// ::= TI <type> # typeinfo structure -// ::= TS <type> # typeinfo name (null-terminated byte string) -// ::= Tc <call-offset> <call-offset> <base encoding> -// # base is the nominal target function of thunk -// # first call-offset is 'this' adjustment -// # second call-offset is result adjustment -// ::= T <call-offset> <base encoding> -// # base is the nominal target function of thunk -// ::= GV <object name> # Guard variable for one-time initialization -// # No <type> -// ::= TW <object name> # Thread-local wrapper -// ::= TH <object name> # Thread-local initialization -// extension ::= TC <first type> <number> _ <second type> # construction vtable for second-in-first -// extension ::= GR <object name> # reference temporary for object - -const char* -parse_special_name(const char* first, const char* last, Db& db) -{ - if (last - first > 2) - { - const char* t; - switch (*first) - { - case 'T': - switch (first[1]) - { - case 'V': - // TV <type> # virtual table - t = parse_type(first+2, last, db); - if (t != first+2) - { - if (db.Names.empty()) - return first; - db.Names.back() = - db.make<SpecialName>("vtable for ", db.Names.back()); - first = t; - } - break; - case 'T': - // TT <type> # VTT structure (construction vtable index) - t = parse_type(first+2, last, db); - if (t != first+2) - { - if (db.Names.empty()) - return first; - db.Names.back() = - db.make<SpecialName>("VTT for ", db.Names.back()); - first = t; - } - break; - case 'I': - // TI <type> # typeinfo structure - t = parse_type(first+2, last, db); - if (t != first+2) - { - if (db.Names.empty()) - return first; - db.Names.back() = - db.make<SpecialName>("typeinfo for ", db.Names.back()); - first = t; - } - break; - case 'S': - // TS <type> # typeinfo name (null-terminated byte string) - t = parse_type(first+2, last, db); - if (t != first+2) - { - if (db.Names.empty()) - return first; - db.Names.back() = - db.make<SpecialName>("typeinfo name for ", db.Names.back()); - first = t; - } - break; - case 'c': - // Tc <call-offset> <call-offset> <base encoding> - { - const char* t0 = parse_call_offset(first+2, last); - if (t0 == first+2) - break; - const char* t1 = parse_call_offset(t0, last); - if (t1 == t0) - break; - t = parse_encoding(t1, last, db); - if (t != t1) - { - if (db.Names.empty()) - return first; - db.Names.back() = - db.make<SpecialName>("covariant return thunk to ", - db.Names.back()); - first = t; - } - } - break; - case 'C': - // extension ::= TC <first type> <number> _ <second type> # construction vtable for second-in-first - t = parse_type(first+2, last, db); - if (t != first+2) - { - const char* t0 = parse_number(t, last); - if (t0 != t && t0 != last && *t0 == '_') - { - const char* t1 = parse_type(++t0, last, db); - if (t1 != t0) - { - if (db.Names.size() < 2) - return first; - auto left = db.Names.back(); - db.Names.pop_back(); - if (db.Names.empty()) - return first; - db.Names.back() = db.make<CtorVtableSpecialName>( - left, db.Names.back()); - first = t1; - } - } - } - break; - case 'W': - // TW <object name> # Thread-local wrapper - t = parse_name(first + 2, last, db); - if (t != first + 2) - { - if (db.Names.empty()) - return first; - db.Names.back() = - db.make<SpecialName>("thread-local wrapper routine for ", - db.Names.back()); - first = t; - } - break; - case 'H': - //TH <object name> # Thread-local initialization - t = parse_name(first + 2, last, db); - if (t != first + 2) - { - if (db.Names.empty()) - return first; - db.Names.back() = db.make<SpecialName>( - "thread-local initialization routine for ", db.Names.back()); - first = t; - } - break; - default: - // T <call-offset> <base encoding> - { - const char* t0 = parse_call_offset(first+1, last); - if (t0 == first+1) - break; - t = parse_encoding(t0, last, db); - if (t != t0) - { - if (db.Names.empty()) - return first; - if (first[1] == 'v') - { - db.Names.back() = - db.make<SpecialName>("virtual thunk to ", - db.Names.back()); - first = t; - } - else - { - db.Names.back() = - db.make<SpecialName>("non-virtual thunk to ", - db.Names.back()); - first = t; - } - } - } - break; - } - break; - case 'G': - switch (first[1]) - { - case 'V': - // GV <object name> # Guard variable for one-time initialization - t = parse_name(first+2, last, db); - if (t != first+2) - { - if (db.Names.empty()) - return first; - db.Names.back() = - db.make<SpecialName>("guard variable for ", db.Names.back()); - first = t; - } - break; - case 'R': - // extension ::= GR <object name> # reference temporary for object - t = parse_name(first+2, last, db); - if (t != first+2) - { - if (db.Names.empty()) - return first; - db.Names.back() = - db.make<SpecialName>("reference temporary for ", - db.Names.back()); - first = t; - } - break; - } - break; - } - } - return first; -} - -template <class T> -class save_value -{ - T& restore_; - T original_value_; -public: - save_value(T& restore) - : restore_(restore), - original_value_(restore) - {} - - ~save_value() - { - restore_ = std::move(original_value_); - } - - save_value(const save_value&) = delete; - save_value& operator=(const save_value&) = delete; -}; - -// <encoding> ::= <function name> <bare-function-type> -// ::= <data name> -// ::= <special-name> - -const char* -parse_encoding(const char* first, const char* last, Db& db) -{ - if (first != last) - { - save_value<decltype(db.EncodingDepth)> su(db.EncodingDepth); - ++db.EncodingDepth; - save_value<decltype(db.TagTemplates)> sb(db.TagTemplates); - if (db.EncodingDepth > 1) - db.TagTemplates = true; - save_value<decltype(db.ParsedCtorDtorCV)> sp(db.ParsedCtorDtorCV); - db.ParsedCtorDtorCV = false; - switch (*first) - { - case 'G': - case 'T': - first = parse_special_name(first, last, db); - break; - default: - { - bool ends_with_template_args = false; - const char* t = parse_name(first, last, db, - &ends_with_template_args); - if (db.Names.empty()) - return first; - Qualifiers cv = db.CV; - FunctionRefQual ref = db.RefQuals; - if (t != first) - { - if (t != last && *t != 'E' && *t != '.') - { - save_value<bool> sb2(db.TagTemplates); - db.TagTemplates = false; - const char* t2; - if (db.Names.empty()) - return first; - if (!db.Names.back()) - return first; - Node* return_type = nullptr; - if (!db.ParsedCtorDtorCV && ends_with_template_args) - { - t2 = parse_type(t, last, db); - if (t2 == t) - return first; - if (db.Names.size() < 1) - return first; - return_type = db.Names.back(); - db.Names.pop_back(); - t = t2; - } - - Node* result = nullptr; - - if (t != last && *t == 'v') - { - ++t; - if (db.Names.empty()) - return first; - Node* name = db.Names.back(); - db.Names.pop_back(); - result = db.make<TopLevelFunctionDecl>( - return_type, name, NodeArray()); - } - else - { - size_t params_begin = db.Names.size(); - while (true) - { - t2 = parse_type(t, last, db); - if (t2 == t) - break; - t = t2; - } - if (db.Names.size() < params_begin) - return first; - NodeArray params = - db.popTrailingNodeArray(params_begin); - if (db.Names.empty()) - return first; - Node* name = db.Names.back(); - db.Names.pop_back(); - result = db.make<TopLevelFunctionDecl>( - return_type, name, params); - } - if (ref != FrefQualNone) - result = db.make<FunctionRefQualType>(result, ref); - if (cv != QualNone) - result = db.make<FunctionQualType>(result, cv); - db.Names.push_back(result); - first = t; - } - else - first = t; - } - break; - } - } - } - return first; -} - -// _block_invoke -// _block_invoke<decimal-digit>+ -// _block_invoke_<decimal-digit>+ - -const char* -parse_block_invoke(const char* first, const char* last, Db& db) -{ - if (last - first >= 13) - { - // FIXME: strcmp? - const char test[] = "_block_invoke"; - const char* t = first; - for (int i = 0; i < 13; ++i, ++t) - { - if (*t != test[i]) - return first; - } - if (t != last) - { - if (*t == '_') - { - // must have at least 1 decimal digit - if (++t == last || !std::isdigit(*t)) - return first; - ++t; - } - // parse zero or more digits - while (t != last && isdigit(*t)) - ++t; - } - if (db.Names.empty()) - return first; - db.Names.back() = - db.make<SpecialName>("invocation function for block in ", - db.Names.back()); - first = t; - } - return first; -} - -// extension -// <dot-suffix> := .<anything and everything> - -const char* -parse_dot_suffix(const char* first, const char* last, Db& db) -{ - if (first != last && *first == '.') - { - if (db.Names.empty()) - return first; - db.Names.back() = - db.make<DotSuffix>(db.Names.back(), StringView(first, last)); - first = last; - } - return first; -} - -// <block-involcaton-function> ___Z<encoding>_block_invoke -// <block-involcaton-function> ___Z<encoding>_block_invoke<decimal-digit>+ -// <block-involcaton-function> ___Z<encoding>_block_invoke_<decimal-digit>+ -// <mangled-name> ::= _Z<encoding> -// ::= <type> - -void -demangle(const char* first, const char* last, Db& db, int& status) -{ - if (first >= last) - { - status = invalid_mangled_name; - return; - } - if (*first == '_') - { - if (last - first >= 4) - { - if (first[1] == 'Z') - { - const char* t = parse_encoding(first+2, last, db); - if (t != first+2 && t != last && *t == '.') - t = parse_dot_suffix(t, last, db); - if (t != last) - status = invalid_mangled_name; - } - else if (first[1] == '_' && first[2] == '_' && first[3] == 'Z') - { - const char* t = parse_encoding(first+4, last, db); - if (t != first+4 && t != last) - { - const char* t1 = parse_block_invoke(t, last, db); - if (t1 != last) - status = invalid_mangled_name; - } - else - status = invalid_mangled_name; - } - else - status = invalid_mangled_name; - } - else - status = invalid_mangled_name; - } - else - { - const char* t = parse_type(first, last, db); - if (t != last) - status = invalid_mangled_name; - } - if (status == success && db.Names.empty()) - status = invalid_mangled_name; -} - -} // unnamed namespace - -extern "C" _LIBCXXABI_FUNC_VIS char * -__cxa_demangle(const char *mangled_name, char *buf, size_t *n, int *status) { - if (mangled_name == nullptr || (buf != nullptr && n == nullptr)) - { - if (status) - *status = invalid_args; - return nullptr; - } - - size_t internal_size = buf != nullptr ? *n : 0; - Db db; - int internal_status = success; - size_t len = std::strlen(mangled_name); - demangle(mangled_name, mangled_name + len, db, - internal_status); - - if (internal_status == success && db.FixForwardReferences && - !db.TemplateParams.empty()) - { - db.FixForwardReferences = false; - db.TagTemplates = false; - db.Names.clear(); - db.Subs.clear(); - demangle(mangled_name, mangled_name + len, db, internal_status); - if (db.FixForwardReferences) - internal_status = invalid_mangled_name; - } - - if (internal_status == success) - { - if (!buf) - { - internal_size = 1024; - buf = static_cast<char*>(std::malloc(internal_size)); - } - - if (buf) - { - OutputStream s(buf, internal_size); - db.Names.back()->print(s); - s += '\0'; - if (n) *n = s.getCurrentPosition(); - buf = s.getBuffer(); - } - else - internal_status = memory_alloc_failure; - } - else - buf = nullptr; - if (status) - *status = internal_status; - return buf; -} - -} // __cxxabiv1 diff --git a/chromium/buildtools/third_party/libc++abi/trunk/src/cxa_exception.cpp b/chromium/buildtools/third_party/libc++abi/trunk/src/cxa_exception.cpp deleted file mode 100644 index e6ed0931ceb..00000000000 --- a/chromium/buildtools/third_party/libc++abi/trunk/src/cxa_exception.cpp +++ /dev/null @@ -1,709 +0,0 @@ -//===------------------------- cxa_exception.cpp --------------------------===// -// -// 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. -// -// -// This file implements the "Exception Handling APIs" -// http://mentorembedded.github.io/cxx-abi/abi-eh.html -// -//===----------------------------------------------------------------------===// - -#include "cxxabi.h" - -#include <exception> // for std::terminate -#include <cstring> // for memset -#include "cxa_exception.hpp" -#include "cxa_handlers.hpp" -#include "fallback_malloc.h" - -#if __has_feature(address_sanitizer) -extern "C" void __asan_handle_no_return(void); -#endif - -// +---------------------------+-----------------------------+---------------+ -// | __cxa_exception | _Unwind_Exception CLNGC++\0 | thrown object | -// +---------------------------+-----------------------------+---------------+ -// ^ -// | -// +-------------------------------------------------------+ -// | -// +---------------------------+-----------------------------+ -// | __cxa_dependent_exception | _Unwind_Exception CLNGC++\1 | -// +---------------------------+-----------------------------+ - -namespace __cxxabiv1 { - -// Utility routines -static -inline -__cxa_exception* -cxa_exception_from_thrown_object(void* thrown_object) -{ - return static_cast<__cxa_exception*>(thrown_object) - 1; -} - -// Note: This is never called when exception_header is masquerading as a -// __cxa_dependent_exception. -static -inline -void* -thrown_object_from_cxa_exception(__cxa_exception* exception_header) -{ - return static_cast<void*>(exception_header + 1); -} - -// Get the exception object from the unwind pointer. -// Relies on the structure layout, where the unwind pointer is right in -// front of the user's exception object -static -inline -__cxa_exception* -cxa_exception_from_exception_unwind_exception(_Unwind_Exception* unwind_exception) -{ - return cxa_exception_from_thrown_object(unwind_exception + 1 ); -} - -// Round s up to next multiple of a. -static inline -size_t aligned_allocation_size(size_t s, size_t a) { - return (s + a - 1) & ~(a - 1); -} - -static inline -size_t cxa_exception_size_from_exception_thrown_size(size_t size) { - return aligned_allocation_size(size + sizeof (__cxa_exception), - alignof(__cxa_exception)); -} - -static void setExceptionClass(_Unwind_Exception* unwind_exception) { - unwind_exception->exception_class = kOurExceptionClass; -} - -static void setDependentExceptionClass(_Unwind_Exception* unwind_exception) { - unwind_exception->exception_class = kOurDependentExceptionClass; -} - -// Is it one of ours? -static bool isOurExceptionClass(const _Unwind_Exception* unwind_exception) { - return (unwind_exception->exception_class & get_vendor_and_language) == - (kOurExceptionClass & get_vendor_and_language); -} - -static bool isDependentException(_Unwind_Exception* unwind_exception) { - return (unwind_exception->exception_class & 0xFF) == 0x01; -} - -// This does not need to be atomic -static inline int incrementHandlerCount(__cxa_exception *exception) { - return ++exception->handlerCount; -} - -// This does not need to be atomic -static inline int decrementHandlerCount(__cxa_exception *exception) { - return --exception->handlerCount; -} - -/* - If reason isn't _URC_FOREIGN_EXCEPTION_CAUGHT, then the terminateHandler - stored in exc is called. Otherwise the exceptionDestructor stored in - exc is called, and then the memory for the exception is deallocated. - - This is never called for a __cxa_dependent_exception. -*/ -static -void -exception_cleanup_func(_Unwind_Reason_Code reason, _Unwind_Exception* unwind_exception) -{ - __cxa_exception* exception_header = cxa_exception_from_exception_unwind_exception(unwind_exception); - if (_URC_FOREIGN_EXCEPTION_CAUGHT != reason) - std::__terminate(exception_header->terminateHandler); - // Just in case there exists a dependent exception that is pointing to this, - // check the reference count and only destroy this if that count goes to zero. - __cxa_decrement_exception_refcount(unwind_exception + 1); -} - -static _LIBCXXABI_NORETURN void failed_throw(__cxa_exception* exception_header) { -// Section 2.5.3 says: -// * For purposes of this ABI, several things are considered exception handlers: -// ** A terminate() call due to a throw. -// and -// * Upon entry, Following initialization of the catch parameter, -// a handler must call: -// * void *__cxa_begin_catch(void *exceptionObject ); - (void) __cxa_begin_catch(&exception_header->unwindHeader); - std::__terminate(exception_header->terminateHandler); -} - -extern "C" { - -// Allocate a __cxa_exception object, and zero-fill it. -// Reserve "thrown_size" bytes on the end for the user's exception -// object. Zero-fill the object. If memory can't be allocated, call -// std::terminate. Return a pointer to the memory to be used for the -// user's exception object. -void *__cxa_allocate_exception(size_t thrown_size) throw() { - size_t actual_size = cxa_exception_size_from_exception_thrown_size(thrown_size); - __cxa_exception *exception_header = - static_cast<__cxa_exception *>(__aligned_malloc_with_fallback(actual_size)); - if (NULL == exception_header) - std::terminate(); - std::memset(exception_header, 0, actual_size); - return thrown_object_from_cxa_exception(exception_header); -} - - -// Free a __cxa_exception object allocated with __cxa_allocate_exception. -void __cxa_free_exception(void *thrown_object) throw() { - __aligned_free_with_fallback(cxa_exception_from_thrown_object(thrown_object)); -} - - -// This function shall allocate a __cxa_dependent_exception and -// return a pointer to it. (Really to the object, not past its' end). -// Otherwise, it will work like __cxa_allocate_exception. -void * __cxa_allocate_dependent_exception () { - size_t actual_size = sizeof(__cxa_dependent_exception); - void *ptr = __aligned_malloc_with_fallback(actual_size); - if (NULL == ptr) - std::terminate(); - std::memset(ptr, 0, actual_size); - return ptr; -} - - -// This function shall free a dependent_exception. -// It does not affect the reference count of the primary exception. -void __cxa_free_dependent_exception (void * dependent_exception) { - __aligned_free_with_fallback(dependent_exception); -} - - -// 2.4.3 Throwing the Exception Object -/* -After constructing the exception object with the throw argument value, -the generated code calls the __cxa_throw runtime library routine. This -routine never returns. - -The __cxa_throw routine will do the following: - -* Obtain the __cxa_exception header from the thrown exception object address, -which can be computed as follows: - __cxa_exception *header = ((__cxa_exception *) thrown_exception - 1); -* Save the current unexpected_handler and terminate_handler in the __cxa_exception header. -* Save the tinfo and dest arguments in the __cxa_exception header. -* Set the exception_class field in the unwind header. This is a 64-bit value -representing the ASCII string "XXXXC++\0", where "XXXX" is a -vendor-dependent string. That is, for implementations conforming to this -ABI, the low-order 4 bytes of this 64-bit value will be "C++\0". -* Increment the uncaught_exception flag. -* Call _Unwind_RaiseException in the system unwind library, Its argument is the -pointer to the thrown exception, which __cxa_throw itself received as an argument. -__Unwind_RaiseException begins the process of stack unwinding, described -in Section 2.5. In special cases, such as an inability to find a -handler, _Unwind_RaiseException may return. In that case, __cxa_throw -will call terminate, assuming that there was no handler for the -exception. -*/ -void -__cxa_throw(void *thrown_object, std::type_info *tinfo, void (*dest)(void *)) { - __cxa_eh_globals *globals = __cxa_get_globals(); - __cxa_exception* exception_header = cxa_exception_from_thrown_object(thrown_object); - - exception_header->unexpectedHandler = std::get_unexpected(); - exception_header->terminateHandler = std::get_terminate(); - exception_header->exceptionType = tinfo; - exception_header->exceptionDestructor = dest; - setExceptionClass(&exception_header->unwindHeader); - exception_header->referenceCount = 1; // This is a newly allocated exception, no need for thread safety. - globals->uncaughtExceptions += 1; // Not atomically, since globals are thread-local - - exception_header->unwindHeader.exception_cleanup = exception_cleanup_func; - -#if __has_feature(address_sanitizer) - // Inform the ASan runtime that now might be a good time to clean stuff up. - __asan_handle_no_return(); -#endif - -#ifdef __USING_SJLJ_EXCEPTIONS__ - _Unwind_SjLj_RaiseException(&exception_header->unwindHeader); -#else - _Unwind_RaiseException(&exception_header->unwindHeader); -#endif - // This only happens when there is no handler, or some unexpected unwinding - // error happens. - failed_throw(exception_header); -} - - -// 2.5.3 Exception Handlers -/* -The adjusted pointer is computed by the personality routine during phase 1 - and saved in the exception header (either __cxa_exception or - __cxa_dependent_exception). - - Requires: exception is native -*/ -void *__cxa_get_exception_ptr(void *unwind_exception) throw() { -#if defined(_LIBCXXABI_ARM_EHABI) - return reinterpret_cast<void*>( - 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; -#endif -} - -#if defined(_LIBCXXABI_ARM_EHABI) -/* -The routine to be called before the cleanup. This will save __cxa_exception in -__cxa_eh_globals, so that __cxa_end_cleanup() can recover later. -*/ -bool __cxa_begin_cleanup(void *unwind_arg) throw() { - _Unwind_Exception* unwind_exception = static_cast<_Unwind_Exception*>(unwind_arg); - __cxa_eh_globals* globals = __cxa_get_globals(); - __cxa_exception* exception_header = - cxa_exception_from_exception_unwind_exception(unwind_exception); - - if (isOurExceptionClass(unwind_exception)) - { - if (0 == exception_header->propagationCount) - { - exception_header->nextPropagatingException = globals->propagatingExceptions; - globals->propagatingExceptions = exception_header; - } - ++exception_header->propagationCount; - } - else - { - // If the propagatingExceptions stack is not empty, since we can't - // chain the foreign exception, terminate it. - if (NULL != globals->propagatingExceptions) - std::terminate(); - globals->propagatingExceptions = exception_header; - } - return true; -} - -/* -The routine to be called after the cleanup has been performed. It will get the -propagating __cxa_exception from __cxa_eh_globals, and continue the stack -unwinding with _Unwind_Resume. - -According to ARM EHABI 8.4.1, __cxa_end_cleanup() should not clobber any -register, thus we have to write this function in assembly so that we can save -{r1, r2, r3}. We don't have to save r0 because it is the return value and the -first argument to _Unwind_Resume(). In addition, we are saving r4 in order to -align the stack to 16 bytes, even though it is a callee-save register. -*/ -__attribute__((used)) static _Unwind_Exception * -__cxa_end_cleanup_impl() -{ - __cxa_eh_globals* globals = __cxa_get_globals(); - __cxa_exception* exception_header = globals->propagatingExceptions; - if (NULL == exception_header) - { - // It seems that __cxa_begin_cleanup() is not called properly. - // We have no choice but terminate the program now. - std::terminate(); - } - - if (isOurExceptionClass(&exception_header->unwindHeader)) - { - --exception_header->propagationCount; - if (0 == exception_header->propagationCount) - { - globals->propagatingExceptions = exception_header->nextPropagatingException; - exception_header->nextPropagatingException = NULL; - } - } - else - { - globals->propagatingExceptions = NULL; - } - return &exception_header->unwindHeader; -} - -asm ( - " .pushsection .text.__cxa_end_cleanup,\"ax\",%progbits\n" - " .globl __cxa_end_cleanup\n" - " .type __cxa_end_cleanup,%function\n" - "__cxa_end_cleanup:\n" - " push {r1, r2, r3, r4}\n" - " bl __cxa_end_cleanup_impl\n" - " pop {r1, r2, r3, r4}\n" - " bl _Unwind_Resume\n" - " bl abort\n" - " .popsection" -); -#endif // defined(_LIBCXXABI_ARM_EHABI) - -/* -This routine can catch foreign or native exceptions. If native, the exception -can be a primary or dependent variety. This routine may remain blissfully -ignorant of whether the native exception is primary or dependent. - -If the exception is native: -* Increment's the exception's handler count. -* Push the exception on the stack of currently-caught exceptions if it is not - already there (from a rethrow). -* Decrements the uncaught_exception count. -* Returns the adjusted pointer to the exception object, which is stored in - the __cxa_exception by the personality routine. - -If the exception is foreign, this means it did not originate from one of throw -routines. The foreign exception does not necessarily have a __cxa_exception -header. However we can catch it here with a catch (...), or with a call -to terminate or unexpected during unwinding. -* Do not try to increment the exception's handler count, we don't know where - it is. -* Push the exception on the stack of currently-caught exceptions only if the - stack is empty. The foreign exception has no way to link to the current - top of stack. If the stack is not empty, call terminate. Even with an - empty stack, this is hacked in by pushing a pointer to an imaginary - __cxa_exception block in front of the foreign exception. It would be better - if the __cxa_eh_globals structure had a stack of _Unwind_Exception, but it - doesn't. It has a stack of __cxa_exception (which has a next* in it). -* Do not decrement the uncaught_exception count because we didn't increment it - in __cxa_throw (or one of our rethrow functions). -* If we haven't terminated, assume the exception object is just past the - _Unwind_Exception and return a pointer to that. -*/ -void* -__cxa_begin_catch(void* unwind_arg) throw() -{ - _Unwind_Exception* unwind_exception = static_cast<_Unwind_Exception*>(unwind_arg); - bool native_exception = isOurExceptionClass(unwind_exception); - __cxa_eh_globals* globals = __cxa_get_globals(); - // exception_header is a hackish offset from a foreign exception, but it - // works as long as we're careful not to try to access any __cxa_exception - // parts. - __cxa_exception* exception_header = - cxa_exception_from_exception_unwind_exception - ( - static_cast<_Unwind_Exception*>(unwind_exception) - ); - if (native_exception) - { - // Increment the handler count, removing the flag about being rethrown - exception_header->handlerCount = exception_header->handlerCount < 0 ? - -exception_header->handlerCount + 1 : exception_header->handlerCount + 1; - // place the exception on the top of the stack if it's not already - // there by a previous rethrow - if (exception_header != globals->caughtExceptions) - { - exception_header->nextException = globals->caughtExceptions; - globals->caughtExceptions = exception_header; - } - globals->uncaughtExceptions -= 1; // Not atomically, since globals are thread-local -#if defined(_LIBCXXABI_ARM_EHABI) - return reinterpret_cast<void*>(exception_header->unwindHeader.barrier_cache.bitpattern[0]); -#else - return exception_header->adjustedPtr; -#endif - } - // Else this is a foreign exception - // If the caughtExceptions stack is not empty, terminate - if (globals->caughtExceptions != 0) - std::terminate(); - // Push the foreign exception on to the stack - globals->caughtExceptions = exception_header; - return unwind_exception + 1; -} - - -/* -Upon exit for any reason, a handler must call: - void __cxa_end_catch (); - -This routine can be called for either a native or foreign exception. -For a native exception: -* Locates the most recently caught exception and decrements its handler count. -* Removes the exception from the caught exception stack, if the handler count goes to zero. -* If the handler count goes down to zero, and the exception was not re-thrown - by throw, it locates the primary exception (which may be the same as the one - it's handling) and decrements its reference count. If that reference count - goes to zero, the function destroys the exception. In any case, if the current - exception is a dependent exception, it destroys that. - -For a foreign exception: -* If it has been rethrown, there is nothing to do. -* Otherwise delete the exception and pop the catch stack to empty. -*/ -void __cxa_end_catch() { - static_assert(sizeof(__cxa_exception) == sizeof(__cxa_dependent_exception), - "sizeof(__cxa_exception) must be equal to " - "sizeof(__cxa_dependent_exception)"); - static_assert(__builtin_offsetof(__cxa_exception, referenceCount) == - __builtin_offsetof(__cxa_dependent_exception, - primaryException), - "the layout of __cxa_exception must match the layout of " - "__cxa_dependent_exception"); - static_assert(__builtin_offsetof(__cxa_exception, handlerCount) == - __builtin_offsetof(__cxa_dependent_exception, handlerCount), - "the layout of __cxa_exception must match the layout of " - "__cxa_dependent_exception"); - __cxa_eh_globals* globals = __cxa_get_globals_fast(); // __cxa_get_globals called in __cxa_begin_catch - __cxa_exception* exception_header = globals->caughtExceptions; - // If we've rethrown a foreign exception, then globals->caughtExceptions - // will have been made an empty stack by __cxa_rethrow() and there is - // nothing more to be done. Do nothing! - if (NULL != exception_header) - { - bool native_exception = isOurExceptionClass(&exception_header->unwindHeader); - if (native_exception) - { - // This is a native exception - if (exception_header->handlerCount < 0) - { - // The exception has been rethrown by __cxa_rethrow, so don't delete it - if (0 == incrementHandlerCount(exception_header)) - { - // Remove from the chain of uncaught exceptions - globals->caughtExceptions = exception_header->nextException; - // but don't destroy - } - // Keep handlerCount negative in case there are nested catch's - // that need to be told that this exception is rethrown. Don't - // erase this rethrow flag until the exception is recaught. - } - else - { - // The native exception has not been rethrown - if (0 == decrementHandlerCount(exception_header)) - { - // Remove from the chain of uncaught exceptions - globals->caughtExceptions = exception_header->nextException; - // Destroy this exception, being careful to distinguish - // between dependent and primary exceptions - if (isDependentException(&exception_header->unwindHeader)) - { - // Reset exception_header to primaryException and deallocate the dependent exception - __cxa_dependent_exception* dep_exception_header = - reinterpret_cast<__cxa_dependent_exception*>(exception_header); - exception_header = - cxa_exception_from_thrown_object(dep_exception_header->primaryException); - __cxa_free_dependent_exception(dep_exception_header); - } - // Destroy the primary exception only if its referenceCount goes to 0 - // (this decrement must be atomic) - __cxa_decrement_exception_refcount(thrown_object_from_cxa_exception(exception_header)); - } - } - } - else - { - // The foreign exception has not been rethrown. Pop the stack - // and delete it. If there are nested catch's and they try - // to touch a foreign exception in any way, that is undefined - // behavior. They likely can't since the only way to catch - // a foreign exception is with catch (...)! - _Unwind_DeleteException(&globals->caughtExceptions->unwindHeader); - globals->caughtExceptions = 0; - } - } -} - -// Note: exception_header may be masquerading as a __cxa_dependent_exception -// and that's ok. exceptionType is there too. -// However watch out for foreign exceptions. Return null for them. -std::type_info *__cxa_current_exception_type() { -// get the current exception - __cxa_eh_globals *globals = __cxa_get_globals_fast(); - if (NULL == globals) - return NULL; // If there have never been any exceptions, there are none now. - __cxa_exception *exception_header = globals->caughtExceptions; - if (NULL == exception_header) - return NULL; // No current exception - if (!isOurExceptionClass(&exception_header->unwindHeader)) - return NULL; - return exception_header->exceptionType; -} - -// 2.5.4 Rethrowing Exceptions -/* This routine can rethrow native or foreign exceptions. -If the exception is native: -* marks the exception object on top of the caughtExceptions stack - (in an implementation-defined way) as being rethrown. -* If the caughtExceptions stack is empty, it calls terminate() - (see [C++FDIS] [except.throw], 15.1.8). -* It then calls _Unwind_RaiseException which should not return - (terminate if it does). - Note: exception_header may be masquerading as a __cxa_dependent_exception - and that's ok. -*/ -void __cxa_rethrow() { - __cxa_eh_globals* globals = __cxa_get_globals(); - __cxa_exception* exception_header = globals->caughtExceptions; - if (NULL == exception_header) - std::terminate(); // throw; called outside of a exception handler - bool native_exception = isOurExceptionClass(&exception_header->unwindHeader); - if (native_exception) - { - // Mark the exception as being rethrown (reverse the effects of __cxa_begin_catch) - exception_header->handlerCount = -exception_header->handlerCount; - globals->uncaughtExceptions += 1; - // __cxa_end_catch will remove this exception from the caughtExceptions stack if necessary - } - else // this is a foreign exception - { - // The only way to communicate to __cxa_end_catch that we've rethrown - // a foreign exception, so don't delete us, is to pop the stack here - // which must be empty afterwards. Then __cxa_end_catch will do - // nothing - globals->caughtExceptions = 0; - } -#ifdef __USING_SJLJ_EXCEPTIONS__ - _Unwind_SjLj_RaiseException(&exception_header->unwindHeader); -#else - _Unwind_RaiseException(&exception_header->unwindHeader); -#endif - - // If we get here, some kind of unwinding error has occurred. - // There is some weird code generation bug happening with - // Apple clang version 4.0 (tags/Apple/clang-418.0.2) (based on LLVM 3.1svn) - // If we call failed_throw here. Turns up with -O2 or higher, and -Os. - __cxa_begin_catch(&exception_header->unwindHeader); - if (native_exception) - std::__terminate(exception_header->terminateHandler); - // Foreign exception: can't get exception_header->terminateHandler - std::terminate(); -} - -/* - If thrown_object is not null, atomically increment the referenceCount field - of the __cxa_exception header associated with the thrown object referred to - by thrown_object. - - Requires: If thrown_object is not NULL, it is a native exception. -*/ -void -__cxa_increment_exception_refcount(void *thrown_object) throw() { - if (thrown_object != NULL ) - { - __cxa_exception* exception_header = cxa_exception_from_thrown_object(thrown_object); - __sync_add_and_fetch(&exception_header->referenceCount, 1); - } -} - -/* - If thrown_object is not null, atomically decrement the referenceCount field - of the __cxa_exception header associated with the thrown object referred to - by thrown_object. If the referenceCount drops to zero, destroy and - deallocate the exception. - - Requires: If thrown_object is not NULL, it is a native exception. -*/ -void -__cxa_decrement_exception_refcount(void *thrown_object) throw() { - if (thrown_object != NULL ) - { - __cxa_exception* exception_header = cxa_exception_from_thrown_object(thrown_object); - if (__sync_sub_and_fetch(&exception_header->referenceCount, size_t(1)) == 0) - { - if (NULL != exception_header->exceptionDestructor) - exception_header->exceptionDestructor(thrown_object); - __cxa_free_exception(thrown_object); - } - } -} - -/* - Returns a pointer to the thrown object (if any) at the top of the - caughtExceptions stack. Atomically increment the exception's referenceCount. - If there is no such thrown object or if the thrown object is foreign, - returns null. - - We can use __cxa_get_globals_fast here to get the globals because if there have - been no exceptions thrown, ever, on this thread, we can return NULL without - the need to allocate the exception-handling globals. -*/ -void *__cxa_current_primary_exception() throw() { -// get the current exception - __cxa_eh_globals* globals = __cxa_get_globals_fast(); - if (NULL == globals) - return NULL; // If there are no globals, there is no exception - __cxa_exception* exception_header = globals->caughtExceptions; - if (NULL == exception_header) - return NULL; // No current exception - if (!isOurExceptionClass(&exception_header->unwindHeader)) - return NULL; // Can't capture a foreign exception (no way to refcount it) - if (isDependentException(&exception_header->unwindHeader)) { - __cxa_dependent_exception* dep_exception_header = - reinterpret_cast<__cxa_dependent_exception*>(exception_header); - exception_header = cxa_exception_from_thrown_object(dep_exception_header->primaryException); - } - void* thrown_object = thrown_object_from_cxa_exception(exception_header); - __cxa_increment_exception_refcount(thrown_object); - return thrown_object; -} - -/* - If reason isn't _URC_FOREIGN_EXCEPTION_CAUGHT, then the terminateHandler - stored in exc is called. Otherwise the referenceCount stored in the - primary exception is decremented, destroying the primary if necessary. - Finally the dependent exception is destroyed. -*/ -static -void -dependent_exception_cleanup(_Unwind_Reason_Code reason, _Unwind_Exception* unwind_exception) -{ - __cxa_dependent_exception* dep_exception_header = - reinterpret_cast<__cxa_dependent_exception*>(unwind_exception + 1) - 1; - if (_URC_FOREIGN_EXCEPTION_CAUGHT != reason) - std::__terminate(dep_exception_header->terminateHandler); - __cxa_decrement_exception_refcount(dep_exception_header->primaryException); - __cxa_free_dependent_exception(dep_exception_header); -} - -/* - If thrown_object is not null, allocate, initialize and throw a dependent - exception. -*/ -void -__cxa_rethrow_primary_exception(void* thrown_object) -{ - if ( thrown_object != NULL ) - { - // thrown_object guaranteed to be native because - // __cxa_current_primary_exception returns NULL for foreign exceptions - __cxa_exception* exception_header = cxa_exception_from_thrown_object(thrown_object); - __cxa_dependent_exception* dep_exception_header = - static_cast<__cxa_dependent_exception*>(__cxa_allocate_dependent_exception()); - dep_exception_header->primaryException = thrown_object; - __cxa_increment_exception_refcount(thrown_object); - dep_exception_header->exceptionType = exception_header->exceptionType; - dep_exception_header->unexpectedHandler = std::get_unexpected(); - dep_exception_header->terminateHandler = std::get_terminate(); - setDependentExceptionClass(&dep_exception_header->unwindHeader); - __cxa_get_globals()->uncaughtExceptions += 1; - dep_exception_header->unwindHeader.exception_cleanup = dependent_exception_cleanup; -#ifdef __USING_SJLJ_EXCEPTIONS__ - _Unwind_SjLj_RaiseException(&dep_exception_header->unwindHeader); -#else - _Unwind_RaiseException(&dep_exception_header->unwindHeader); -#endif - // Some sort of unwinding error. Note that terminate is a handler. - __cxa_begin_catch(&dep_exception_header->unwindHeader); - } - // If we return client will call terminate() -} - -bool -__cxa_uncaught_exception() throw() { return __cxa_uncaught_exceptions() != 0; } - -unsigned int -__cxa_uncaught_exceptions() throw() -{ - // This does not report foreign exceptions in flight - __cxa_eh_globals* globals = __cxa_get_globals_fast(); - if (globals == 0) - return 0; - return globals->uncaughtExceptions; -} - -} // extern "C" - -} // abi diff --git a/chromium/buildtools/third_party/libc++abi/trunk/src/cxa_exception.hpp b/chromium/buildtools/third_party/libc++abi/trunk/src/cxa_exception.hpp deleted file mode 100644 index b9f74e3b0bb..00000000000 --- a/chromium/buildtools/third_party/libc++abi/trunk/src/cxa_exception.hpp +++ /dev/null @@ -1,138 +0,0 @@ -//===------------------------- cxa_exception.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. -// -// -// This file implements the "Exception Handling APIs" -// http://mentorembedded.github.io/cxx-abi/abi-eh.html -// -//===----------------------------------------------------------------------===// - -#ifndef _CXA_EXCEPTION_H -#define _CXA_EXCEPTION_H - -#include <exception> // for std::unexpected_handler and std::terminate_handler -#include "cxxabi.h" -#include "unwind.h" - -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 _LIBCXXABI_HIDDEN __cxa_exception { -#if defined(__LP64__) || defined(_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 *); - std::unexpected_handler unexpectedHandler; - std::terminate_handler terminateHandler; - - __cxa_exception *nextException; - - int handlerCount; - -#if defined(_LIBCXXABI_ARM_EHABI) - __cxa_exception* nextPropagatingException; - int propagationCount; -#else - int handlerSwitchValue; - const unsigned char *actionRecord; - const unsigned char *languageSpecificData; - void *catchTemp; - void *adjustedPtr; -#endif - -#if !defined(__LP64__) && !defined(_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. - size_t referenceCount; -#endif - - // This field is annotated with attribute aligned so that the exception - // object following the field is sufficiently aligned and there is no - // gap between the field and the exception object. r276215 made a change to - // annotate _Unwind_Exception in unwind.h with __attribute__((aligned)), but - // we cannot incorporate the fix on Darwin since it is an ABI-breaking - // change, which is why we need the attribute on this field. - // - // For ARM EHABI, we do not align this field since _Unwind_Exception is an - // alias of _Unwind_Control_Block, which is not annotated with - // __attribute__((aligned). -#if defined(_LIBCXXABI_ARM_EHABI) - _Unwind_Exception unwindHeader; -#else - _Unwind_Exception unwindHeader __attribute__((aligned)); -#endif -}; - -// http://sourcery.mentor.com/archives/cxx-abi-dev/msg01924.html -// The layout of this structure MUST match the layout of __cxa_exception, with -// primaryException instead of referenceCount. -struct _LIBCXXABI_HIDDEN __cxa_dependent_exception { -#if defined(__LP64__) || defined(_LIBCXXABI_ARM_EHABI) - void* primaryException; -#endif - - std::type_info *exceptionType; - void (*exceptionDestructor)(void *); - std::unexpected_handler unexpectedHandler; - std::terminate_handler terminateHandler; - - __cxa_exception *nextException; - - int handlerCount; - -#if defined(_LIBCXXABI_ARM_EHABI) - __cxa_exception* nextPropagatingException; - int propagationCount; -#else - int handlerSwitchValue; - const unsigned char *actionRecord; - const unsigned char *languageSpecificData; - void * catchTemp; - void *adjustedPtr; -#endif - -#if !defined(__LP64__) && !defined(_LIBCXXABI_ARM_EHABI) - void* primaryException; -#endif - - // See the comment in __cxa_exception as to why this field has attribute - // aligned. -#if defined(_LIBCXXABI_ARM_EHABI) - _Unwind_Exception unwindHeader; -#else - _Unwind_Exception unwindHeader __attribute__((aligned)); -#endif -}; - -struct _LIBCXXABI_HIDDEN __cxa_eh_globals { - __cxa_exception * caughtExceptions; - unsigned int uncaughtExceptions; -#if defined(_LIBCXXABI_ARM_EHABI) - __cxa_exception* propagatingExceptions; -#endif -}; - -extern "C" _LIBCXXABI_FUNC_VIS __cxa_eh_globals * __cxa_get_globals (); -extern "C" _LIBCXXABI_FUNC_VIS __cxa_eh_globals * __cxa_get_globals_fast (); - -extern "C" _LIBCXXABI_FUNC_VIS void * __cxa_allocate_dependent_exception (); -extern "C" _LIBCXXABI_FUNC_VIS void __cxa_free_dependent_exception (void * dependent_exception); - -} // namespace __cxxabiv1 - -#endif // _CXA_EXCEPTION_H diff --git a/chromium/buildtools/third_party/libc++abi/trunk/src/cxa_exception_storage.cpp b/chromium/buildtools/third_party/libc++abi/trunk/src/cxa_exception_storage.cpp deleted file mode 100644 index c641e0225f8..00000000000 --- a/chromium/buildtools/third_party/libc++abi/trunk/src/cxa_exception_storage.cpp +++ /dev/null @@ -1,102 +0,0 @@ -//===--------------------- cxa_exception_storage.cpp ----------------------===// -// -// 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. -// -// -// This file implements the storage for the "Caught Exception Stack" -// http://mentorembedded.github.io/cxx-abi/abi-eh.html (section 2.2.2) -// -//===----------------------------------------------------------------------===// - -#include "cxa_exception.hpp" - -#include <__threading_support> - -#if defined(_LIBCXXABI_HAS_NO_THREADS) - -namespace __cxxabiv1 { -extern "C" { - static __cxa_eh_globals eh_globals; - __cxa_eh_globals *__cxa_get_globals() { return &eh_globals; } - __cxa_eh_globals *__cxa_get_globals_fast() { return &eh_globals; } - } -} - -#elif defined(HAS_THREAD_LOCAL) - -namespace __cxxabiv1 { - -namespace { - __cxa_eh_globals * __globals () { - static thread_local __cxa_eh_globals eh_globals; - return &eh_globals; - } - } - -extern "C" { - __cxa_eh_globals * __cxa_get_globals () { return __globals (); } - __cxa_eh_globals * __cxa_get_globals_fast () { return __globals (); } - } -} - -#else - -#include "abort_message.h" -#include "fallback_malloc.h" - -// In general, we treat all threading errors as fatal. -// We cannot call std::terminate() because that will in turn -// call __cxa_get_globals() and cause infinite recursion. - -namespace __cxxabiv1 { -namespace { - std::__libcpp_tls_key key_; - std::__libcpp_exec_once_flag flag_ = _LIBCPP_EXEC_ONCE_INITIALIZER; - - void _LIBCPP_TLS_DESTRUCTOR_CC destruct_ (void *p) { - __free_with_fallback ( p ); - if ( 0 != std::__libcpp_tls_set ( key_, NULL ) ) - abort_message("cannot zero out thread value for __cxa_get_globals()"); - } - - void construct_ () { - if ( 0 != std::__libcpp_tls_create ( &key_, destruct_ ) ) - abort_message("cannot create thread specific key for __cxa_get_globals()"); - } -} - -extern "C" { - __cxa_eh_globals * __cxa_get_globals () { - // Try to get the globals for this thread - __cxa_eh_globals* retVal = __cxa_get_globals_fast (); - - // If this is the first time we've been asked for these globals, create them - if ( NULL == retVal ) { - retVal = static_cast<__cxa_eh_globals*> - (__calloc_with_fallback (1, sizeof (__cxa_eh_globals))); - if ( NULL == retVal ) - abort_message("cannot allocate __cxa_eh_globals"); - if ( 0 != std::__libcpp_tls_set ( key_, retVal ) ) - abort_message("std::__libcpp_tls_set failure in __cxa_get_globals()"); - } - return retVal; - } - - // Note that this implementation will reliably return NULL if not - // preceded by a call to __cxa_get_globals(). This is an extension - // to the Itanium ABI and is taken advantage of in several places in - // libc++abi. - __cxa_eh_globals * __cxa_get_globals_fast () { - // First time through, create the key. - if (0 != std::__libcpp_execute_once(&flag_, construct_)) - abort_message("execute once failure in __cxa_get_globals_fast()"); -// static int init = construct_(); - return static_cast<__cxa_eh_globals*>(std::__libcpp_tls_get(key_)); - } - -} -} -#endif diff --git a/chromium/buildtools/third_party/libc++abi/trunk/src/cxa_guard.cpp b/chromium/buildtools/third_party/libc++abi/trunk/src/cxa_guard.cpp deleted file mode 100644 index f4c2a184dc5..00000000000 --- a/chromium/buildtools/third_party/libc++abi/trunk/src/cxa_guard.cpp +++ /dev/null @@ -1,265 +0,0 @@ -//===---------------------------- cxa_guard.cpp ---------------------------===// -// -// 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. -// -//===----------------------------------------------------------------------===// - -#include "__cxxabi_config.h" - -#include "abort_message.h" -#include <__threading_support> - -#include <stdint.h> - -/* - This implementation must be careful to not call code external to this file - which will turn around and try to call __cxa_guard_acquire reentrantly. - For this reason, the headers of this file are as restricted as possible. - Previous implementations of this code for __APPLE__ have used - std::__libcpp_mutex_lock and the abort_message utility without problem. This - implementation also uses std::__libcpp_condvar_wait which has tested - to not be a problem. -*/ - -namespace __cxxabiv1 -{ - -namespace -{ - -#ifdef __arm__ -// A 32-bit, 4-byte-aligned static data value. The least significant 2 bits must -// be statically initialized to 0. -typedef uint32_t guard_type; - -inline void set_initialized(guard_type* guard_object) { - *guard_object |= 1; -} -#else -typedef uint64_t guard_type; - -void set_initialized(guard_type* guard_object) { - char* initialized = (char*)guard_object; - *initialized = 1; -} -#endif - -#if defined(_LIBCXXABI_HAS_NO_THREADS) || (defined(__APPLE__) && !defined(__arm__)) -#ifdef __arm__ - -// Test the lowest bit. -inline bool is_initialized(guard_type* guard_object) { - return (*guard_object) & 1; -} - -#else - -bool is_initialized(guard_type* guard_object) { - char* initialized = (char*)guard_object; - return *initialized; -} - -#endif -#endif - -#ifndef _LIBCXXABI_HAS_NO_THREADS -std::__libcpp_mutex_t guard_mut = _LIBCPP_MUTEX_INITIALIZER; -std::__libcpp_condvar_t guard_cv = _LIBCPP_CONDVAR_INITIALIZER; -#endif - -#if defined(__APPLE__) && !defined(__arm__) - -typedef uint32_t lock_type; - -#if __LITTLE_ENDIAN__ - -inline -lock_type -get_lock(uint64_t x) -{ - return static_cast<lock_type>(x >> 32); -} - -inline -void -set_lock(uint64_t& x, lock_type y) -{ - x = static_cast<uint64_t>(y) << 32; -} - -#else // __LITTLE_ENDIAN__ - -inline -lock_type -get_lock(uint64_t x) -{ - return static_cast<lock_type>(x); -} - -inline -void -set_lock(uint64_t& x, lock_type y) -{ - x = y; -} - -#endif // __LITTLE_ENDIAN__ - -#else // !__APPLE__ || __arm__ - -typedef bool lock_type; - -#if !defined(__arm__) -static_assert(std::is_same<guard_type, uint64_t>::value, ""); - -inline lock_type get_lock(uint64_t x) -{ - union - { - uint64_t guard; - uint8_t lock[2]; - } f = {x}; - return f.lock[1] != 0; -} - -inline void set_lock(uint64_t& x, lock_type y) -{ - union - { - uint64_t guard; - uint8_t lock[2]; - } f = {0}; - f.lock[1] = y; - x = f.guard; -} -#else // defined(__arm__) -static_assert(std::is_same<guard_type, uint32_t>::value, ""); - -inline lock_type get_lock(uint32_t x) -{ - union - { - uint32_t guard; - uint8_t lock[2]; - } f = {x}; - return f.lock[1] != 0; -} - -inline void set_lock(uint32_t& x, lock_type y) -{ - union - { - uint32_t guard; - uint8_t lock[2]; - } f = {0}; - f.lock[1] = y; - x = f.guard; -} - -#endif // !defined(__arm__) - -#endif // __APPLE__ && !__arm__ - -} // unnamed namespace - -extern "C" -{ - -#ifndef _LIBCXXABI_HAS_NO_THREADS -_LIBCXXABI_FUNC_VIS int __cxa_guard_acquire(guard_type *guard_object) { - char* initialized = (char*)guard_object; - if (std::__libcpp_mutex_lock(&guard_mut)) - abort_message("__cxa_guard_acquire failed to acquire mutex"); - int result = *initialized == 0; - if (result) - { -#if defined(__APPLE__) && !defined(__arm__) - // This is a special-case pthread dependency for Mac. We can't pull this - // out into libcxx's threading API (__threading_support) because not all - // supported Mac environments provide this function (in pthread.h). To - // make it possible to build/use libcxx in those environments, we have to - // keep this pthread dependency local to libcxxabi. If there is some - // convenient way to detect precisely when pthread_mach_thread_np is - // available in a given Mac environment, it might still be possible to - // bury this dependency in __threading_support. - #ifdef _LIBCPP_HAS_THREAD_API_PTHREAD - const lock_type id = pthread_mach_thread_np(std::__libcpp_thread_get_current_id()); - #else - #error "How do I pthread_mach_thread_np()?" - #endif - lock_type lock = get_lock(*guard_object); - if (lock) - { - // if this thread set lock for this same guard_object, abort - if (lock == id) - abort_message("__cxa_guard_acquire detected deadlock"); - do - { - if (std::__libcpp_condvar_wait(&guard_cv, &guard_mut)) - abort_message("__cxa_guard_acquire condition variable wait failed"); - lock = get_lock(*guard_object); - } while (lock); - result = !is_initialized(guard_object); - if (result) - set_lock(*guard_object, id); - } - else - set_lock(*guard_object, id); -#else // !__APPLE__ || __arm__ - while (get_lock(*guard_object)) - if (std::__libcpp_condvar_wait(&guard_cv, &guard_mut)) - abort_message("__cxa_guard_acquire condition variable wait failed"); - result = *initialized == 0; - if (result) - set_lock(*guard_object, true); -#endif // !__APPLE__ || __arm__ - } - if (std::__libcpp_mutex_unlock(&guard_mut)) - abort_message("__cxa_guard_acquire failed to release mutex"); - return result; -} - -_LIBCXXABI_FUNC_VIS void __cxa_guard_release(guard_type *guard_object) { - if (std::__libcpp_mutex_lock(&guard_mut)) - abort_message("__cxa_guard_release failed to acquire mutex"); - *guard_object = 0; - set_initialized(guard_object); - if (std::__libcpp_mutex_unlock(&guard_mut)) - abort_message("__cxa_guard_release failed to release mutex"); - if (std::__libcpp_condvar_broadcast(&guard_cv)) - abort_message("__cxa_guard_release failed to broadcast condition variable"); -} - -_LIBCXXABI_FUNC_VIS void __cxa_guard_abort(guard_type *guard_object) { - if (std::__libcpp_mutex_lock(&guard_mut)) - abort_message("__cxa_guard_abort failed to acquire mutex"); - *guard_object = 0; - if (std::__libcpp_mutex_unlock(&guard_mut)) - abort_message("__cxa_guard_abort failed to release mutex"); - if (std::__libcpp_condvar_broadcast(&guard_cv)) - abort_message("__cxa_guard_abort failed to broadcast condition variable"); -} - -#else // _LIBCXXABI_HAS_NO_THREADS - -_LIBCXXABI_FUNC_VIS int __cxa_guard_acquire(guard_type *guard_object) { - return !is_initialized(guard_object); -} - -_LIBCXXABI_FUNC_VIS void __cxa_guard_release(guard_type *guard_object) { - *guard_object = 0; - set_initialized(guard_object); -} - -_LIBCXXABI_FUNC_VIS void __cxa_guard_abort(guard_type *guard_object) { - *guard_object = 0; -} - -#endif // !_LIBCXXABI_HAS_NO_THREADS - -} // extern "C" - -} // __cxxabiv1 diff --git a/chromium/buildtools/third_party/libc++abi/trunk/src/cxa_handlers.cpp b/chromium/buildtools/third_party/libc++abi/trunk/src/cxa_handlers.cpp deleted file mode 100644 index 2881a2a65fe..00000000000 --- a/chromium/buildtools/third_party/libc++abi/trunk/src/cxa_handlers.cpp +++ /dev/null @@ -1,125 +0,0 @@ -//===------------------------- cxa_handlers.cpp ---------------------------===// -// -// 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. -// -// -// This file implements the functionality associated with the terminate_handler, -// unexpected_handler, and new_handler. -//===----------------------------------------------------------------------===// - -#include <stdexcept> -#include <new> -#include <exception> -#include "abort_message.h" -#include "cxxabi.h" -#include "cxa_handlers.hpp" -#include "cxa_exception.hpp" -#include "private_typeinfo.h" - -namespace std -{ - -unexpected_handler -get_unexpected() _NOEXCEPT -{ - return __sync_fetch_and_add(&__cxa_unexpected_handler, (unexpected_handler)0); -// The above is safe but overkill on x86 -// Using of C++11 atomics this should be rewritten -// return __cxa_unexpected_handler.load(memory_order_acq); -} - -void -__unexpected(unexpected_handler func) -{ - func(); - // unexpected handler should not return - abort_message("unexpected_handler unexpectedly returned"); -} - -__attribute__((noreturn)) -void -unexpected() -{ - __unexpected(get_unexpected()); -} - -terminate_handler -get_terminate() _NOEXCEPT -{ - return __sync_fetch_and_add(&__cxa_terminate_handler, (terminate_handler)0); -// The above is safe but overkill on x86 -// Using of C++11 atomics this should be rewritten -// return __cxa_terminate_handler.load(memory_order_acq); -} - -void -__terminate(terminate_handler func) _NOEXCEPT -{ -#ifndef _LIBCXXABI_NO_EXCEPTIONS - try - { -#endif // _LIBCXXABI_NO_EXCEPTIONS - func(); - // handler should not return - abort_message("terminate_handler unexpectedly returned"); -#ifndef _LIBCXXABI_NO_EXCEPTIONS - } - catch (...) - { - // handler should not throw exception - abort_message("terminate_handler unexpectedly threw an exception"); - } -#endif // _LIBCXXABI_NO_EXCEPTIONS -} - -__attribute__((noreturn)) -void -terminate() _NOEXCEPT -{ - // If there might be an uncaught exception - using namespace __cxxabiv1; - __cxa_eh_globals* globals = __cxa_get_globals_fast(); - if (globals) - { - __cxa_exception* exception_header = globals->caughtExceptions; - if (exception_header) - { - _Unwind_Exception* unwind_exception = - reinterpret_cast<_Unwind_Exception*>(exception_header + 1) - 1; - bool native_exception = - (unwind_exception->exception_class & get_vendor_and_language) == - (kOurExceptionClass & get_vendor_and_language); - if (native_exception) - __terminate(exception_header->terminateHandler); - } - } - __terminate(get_terminate()); -} - -// In the future this will become: -// std::atomic<std::new_handler> __cxa_new_handler(0); -extern "C" { -new_handler __cxa_new_handler = 0; -} - -new_handler -set_new_handler(new_handler handler) _NOEXCEPT -{ - return __atomic_exchange_n(&__cxa_new_handler, handler, __ATOMIC_ACQ_REL); -// Using of C++11 atomics this should be rewritten -// return __cxa_new_handler.exchange(handler, memory_order_acq_rel); -} - -new_handler -get_new_handler() _NOEXCEPT -{ - return __sync_fetch_and_add(&__cxa_new_handler, (new_handler)0); -// The above is safe but overkill on x86 -// Using of C++11 atomics this should be rewritten -// return __cxa_new_handler.load(memory_order_acq); -} - -} // std diff --git a/chromium/buildtools/third_party/libc++abi/trunk/src/cxa_handlers.hpp b/chromium/buildtools/third_party/libc++abi/trunk/src/cxa_handlers.hpp deleted file mode 100644 index 14c0e10119d..00000000000 --- a/chromium/buildtools/third_party/libc++abi/trunk/src/cxa_handlers.hpp +++ /dev/null @@ -1,56 +0,0 @@ -//===------------------------- cxa_handlers.cpp ---------------------------===// -// -// 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. -// -// -// This file implements the functionality associated with the terminate_handler, -// unexpected_handler, and new_handler. -//===----------------------------------------------------------------------===// - -#ifndef _CXA_HANDLERS_H -#define _CXA_HANDLERS_H - -#include <__cxxabi_config.h> - -#include <exception> - -namespace std -{ - -_LIBCXXABI_HIDDEN _LIBCXXABI_NORETURN -void -__unexpected(unexpected_handler func); - -_LIBCXXABI_HIDDEN _LIBCXXABI_NORETURN -void -__terminate(terminate_handler func) _NOEXCEPT; - -} // std - -extern "C" -{ - -_LIBCXXABI_DATA_VIS extern void (*__cxa_terminate_handler)(); -_LIBCXXABI_DATA_VIS extern void (*__cxa_unexpected_handler)(); -_LIBCXXABI_DATA_VIS extern void (*__cxa_new_handler)(); - -/* - - At some point in the future these three symbols will become - C++11 atomic variables: - - extern std::atomic<std::terminate_handler> __cxa_terminate_handler; - extern std::atomic<std::unexpected_handler> __cxa_unexpected_handler; - extern std::atomic<std::new_handler> __cxa_new_handler; - - This change will not impact their ABI. But it will allow for a - portable performance optimization. - -*/ - -} // extern "C" - -#endif // _CXA_HANDLERS_H diff --git a/chromium/buildtools/third_party/libc++abi/trunk/src/cxa_noexception.cpp b/chromium/buildtools/third_party/libc++abi/trunk/src/cxa_noexception.cpp deleted file mode 100644 index adda552b89f..00000000000 --- a/chromium/buildtools/third_party/libc++abi/trunk/src/cxa_noexception.cpp +++ /dev/null @@ -1,55 +0,0 @@ -//===------------------------- cxa_exception.cpp --------------------------===// -// -// 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. -// -// -// This file implements the "Exception Handling APIs" -// http://mentorembedded.github.io/cxx-abi/abi-eh.html -// -//===----------------------------------------------------------------------===// - -// Support functions for the no-exceptions libc++ library - -#include "cxxabi.h" - -#include <exception> // for std::terminate -#include "cxa_exception.hpp" -#include "cxa_handlers.hpp" - -namespace __cxxabiv1 { - -extern "C" { - -void -__cxa_increment_exception_refcount(void *thrown_object) throw() { - if (thrown_object != nullptr) - std::terminate(); -} - -void -__cxa_decrement_exception_refcount(void *thrown_object) throw() { - if (thrown_object != nullptr) - std::terminate(); -} - - -void *__cxa_current_primary_exception() throw() { return nullptr; } - -void -__cxa_rethrow_primary_exception(void* thrown_object) { - if (thrown_object != nullptr) - std::terminate(); -} - -bool -__cxa_uncaught_exception() throw() { return false; } - -unsigned int -__cxa_uncaught_exceptions() throw() { return 0; } - -} // extern "C" - -} // abi diff --git a/chromium/buildtools/third_party/libc++abi/trunk/src/cxa_personality.cpp b/chromium/buildtools/third_party/libc++abi/trunk/src/cxa_personality.cpp deleted file mode 100644 index 7f857faf78f..00000000000 --- a/chromium/buildtools/third_party/libc++abi/trunk/src/cxa_personality.cpp +++ /dev/null @@ -1,1305 +0,0 @@ -//===------------------------- cxa_exception.cpp --------------------------===// -// -// 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. -// -// -// This file implements the "Exception Handling APIs" -// http://mentorembedded.github.io/cxx-abi/abi-eh.html -// http://www.intel.com/design/itanium/downloads/245358.htm -// -//===----------------------------------------------------------------------===// - -#include <assert.h> -#include <stdlib.h> -#include <string.h> -#include <typeinfo> - -#include "__cxxabi_config.h" -#include "cxa_exception.hpp" -#include "cxa_handlers.hpp" -#include "private_typeinfo.h" -#include "unwind.h" - -/* - Exception Header Layout: - -+---------------------------+-----------------------------+---------------+ -| __cxa_exception | _Unwind_Exception CLNGC++\0 | thrown object | -+---------------------------+-----------------------------+---------------+ - ^ - | - +-------------------------------------------------------+ - | -+---------------------------+-----------------------------+ -| __cxa_dependent_exception | _Unwind_Exception CLNGC++\1 | -+---------------------------+-----------------------------+ - - Exception Handling Table Layout: - -+-----------------+--------+ -| lpStartEncoding | (char) | -+---------+-------+--------+---------------+-----------------------+ -| lpStart | (encoded with lpStartEncoding) | defaults to funcStart | -+---------+-----+--------+-----------------+---------------+-------+ -| ttypeEncoding | (char) | Encoding of the type_info table | -+---------------+-+------+----+----------------------------+----------------+ -| classInfoOffset | (ULEB128) | Offset to type_info table, defaults to null | -+-----------------++--------+-+----------------------------+----------------+ -| callSiteEncoding | (char) | Encoding for Call Site Table | -+------------------+--+-----+-----+------------------------+--------------------------+ -| callSiteTableLength | (ULEB128) | Call Site Table length, used to find Action table | -+---------------------+-----------+---------------------------------------------------+ -#ifndef __USING_SJLJ_EXCEPTIONS__ -+---------------------+-----------+------------------------------------------------+ -| Beginning of Call Site Table The current ip lies within the | -| ... (start, length) range of one of these | -| call sites. There may be action needed. | -| +-------------+---------------------------------+------------------------------+ | -| | start | (encoded with callSiteEncoding) | offset relative to funcStart | | -| | length | (encoded with callSiteEncoding) | length of code fragment | | -| | landingPad | (encoded with callSiteEncoding) | offset relative to lpStart | | -| | actionEntry | (ULEB128) | Action Table Index 1-based | | -| | | | actionEntry == 0 -> cleanup | | -| +-------------+---------------------------------+------------------------------+ | -| ... | -+----------------------------------------------------------------------------------+ -#else // __USING_SJLJ_EXCEPTIONS__ -+---------------------+-----------+------------------------------------------------+ -| Beginning of Call Site Table The current ip is a 1-based index into | -| ... this table. Or it is -1 meaning no | -| action is needed. Or it is 0 meaning | -| terminate. | -| +-------------+---------------------------------+------------------------------+ | -| | landingPad | (ULEB128) | offset relative to lpStart | | -| | actionEntry | (ULEB128) | Action Table Index 1-based | | -| | | | actionEntry == 0 -> cleanup | | -| +-------------+---------------------------------+------------------------------+ | -| ... | -+----------------------------------------------------------------------------------+ -#endif // __USING_SJLJ_EXCEPTIONS__ -+---------------------------------------------------------------------+ -| Beginning of Action Table ttypeIndex == 0 : cleanup | -| ... ttypeIndex > 0 : catch | -| ttypeIndex < 0 : exception spec | -| +--------------+-----------+--------------------------------------+ | -| | ttypeIndex | (SLEB128) | Index into type_info Table (1-based) | | -| | actionOffset | (SLEB128) | Offset into next Action Table entry | | -| +--------------+-----------+--------------------------------------+ | -| ... | -+---------------------------------------------------------------------+-----------------+ -| type_info Table, but classInfoOffset does *not* point here! | -| +----------------+------------------------------------------------+-----------------+ | -| | Nth type_info* | Encoded with ttypeEncoding, 0 means catch(...) | ttypeIndex == N | | -| +----------------+------------------------------------------------+-----------------+ | -| ... | -| +----------------+------------------------------------------------+-----------------+ | -| | 1st type_info* | Encoded with ttypeEncoding, 0 means catch(...) | ttypeIndex == 1 | | -| +----------------+------------------------------------------------+-----------------+ | -| +---------------------------------------+-----------+------------------------------+ | -| | 1st ttypeIndex for 1st exception spec | (ULEB128) | classInfoOffset points here! | | -| | ... | (ULEB128) | | | -| | Mth ttypeIndex for 1st exception spec | (ULEB128) | | | -| | 0 | (ULEB128) | | | -| +---------------------------------------+------------------------------------------+ | -| ... | -| +---------------------------------------+------------------------------------------+ | -| | 0 | (ULEB128) | throw() | | -| +---------------------------------------+------------------------------------------+ | -| ... | -| +---------------------------------------+------------------------------------------+ | -| | 1st ttypeIndex for Nth exception spec | (ULEB128) | | | -| | ... | (ULEB128) | | | -| | Mth ttypeIndex for Nth exception spec | (ULEB128) | | | -| | 0 | (ULEB128) | | | -| +---------------------------------------+------------------------------------------+ | -+---------------------------------------------------------------------------------------+ - -Notes: - -* ttypeIndex in the Action Table, and in the exception spec table, is an index, - not a byte count, if positive. It is a negative index offset of - classInfoOffset and the sizeof entry depends on ttypeEncoding. - But if ttypeIndex is negative, it is a positive 1-based byte offset into the - type_info Table. - And if ttypeIndex is zero, it refers to a catch (...). - -* landingPad can be 0, this implies there is nothing to be done. - -* landingPad != 0 and actionEntry == 0 implies a cleanup needs to be done - @landingPad. - -* A cleanup can also be found under landingPad != 0 and actionEntry != 0 in - the Action Table with ttypeIndex == 0. -*/ - -namespace __cxxabiv1 -{ - -namespace -{ - -template <class AsType> -uintptr_t readPointerHelper(const uint8_t*& p) { - AsType value; - memcpy(&value, p, sizeof(AsType)); - p += sizeof(AsType); - return static_cast<uintptr_t>(value); -} - -} // end namespace - -extern "C" -{ - -// private API - -// Heavily borrowed from llvm/examples/ExceptionDemo/ExceptionDemo.cpp - -// DWARF Constants -enum -{ - DW_EH_PE_absptr = 0x00, - DW_EH_PE_uleb128 = 0x01, - DW_EH_PE_udata2 = 0x02, - DW_EH_PE_udata4 = 0x03, - DW_EH_PE_udata8 = 0x04, - DW_EH_PE_sleb128 = 0x09, - DW_EH_PE_sdata2 = 0x0A, - DW_EH_PE_sdata4 = 0x0B, - DW_EH_PE_sdata8 = 0x0C, - DW_EH_PE_pcrel = 0x10, - DW_EH_PE_textrel = 0x20, - DW_EH_PE_datarel = 0x30, - DW_EH_PE_funcrel = 0x40, - DW_EH_PE_aligned = 0x50, - DW_EH_PE_indirect = 0x80, - DW_EH_PE_omit = 0xFF -}; - -/// Read a uleb128 encoded value and advance pointer -/// See Variable Length Data Appendix C in: -/// @link http://dwarfstd.org/Dwarf4.pdf @unlink -/// @param data reference variable holding memory pointer to decode from -/// @returns decoded value -static -uintptr_t -readULEB128(const uint8_t** data) -{ - uintptr_t result = 0; - uintptr_t shift = 0; - unsigned char byte; - const uint8_t *p = *data; - do - { - byte = *p++; - result |= static_cast<uintptr_t>(byte & 0x7F) << shift; - shift += 7; - } while (byte & 0x80); - *data = p; - return result; -} - -/// Read a sleb128 encoded value and advance pointer -/// See Variable Length Data Appendix C in: -/// @link http://dwarfstd.org/Dwarf4.pdf @unlink -/// @param data reference variable holding memory pointer to decode from -/// @returns decoded value -static -intptr_t -readSLEB128(const uint8_t** data) -{ - uintptr_t result = 0; - uintptr_t shift = 0; - unsigned char byte; - const uint8_t *p = *data; - do - { - byte = *p++; - result |= static_cast<uintptr_t>(byte & 0x7F) << shift; - shift += 7; - } while (byte & 0x80); - *data = p; - if ((byte & 0x40) && (shift < (sizeof(result) << 3))) - result |= static_cast<uintptr_t>(~0) << shift; - return static_cast<intptr_t>(result); -} - -/// Read a pointer encoded value and advance pointer -/// See Variable Length Data in: -/// @link http://dwarfstd.org/Dwarf3.pdf @unlink -/// @param data reference variable holding memory pointer to decode from -/// @param encoding dwarf encoding type -/// @returns decoded value -static -uintptr_t -readEncodedPointer(const uint8_t** data, uint8_t encoding) -{ - uintptr_t result = 0; - if (encoding == DW_EH_PE_omit) - return result; - const uint8_t* p = *data; - // first get value - switch (encoding & 0x0F) - { - case DW_EH_PE_absptr: - result = readPointerHelper<uintptr_t>(p); - break; - case DW_EH_PE_uleb128: - result = readULEB128(&p); - break; - case DW_EH_PE_sleb128: - result = static_cast<uintptr_t>(readSLEB128(&p)); - break; - case DW_EH_PE_udata2: - result = readPointerHelper<uint16_t>(p); - break; - case DW_EH_PE_udata4: - result = readPointerHelper<uint32_t>(p); - break; - case DW_EH_PE_udata8: - result = readPointerHelper<uint64_t>(p); - break; - case DW_EH_PE_sdata2: - result = readPointerHelper<int16_t>(p); - break; - case DW_EH_PE_sdata4: - result = readPointerHelper<int32_t>(p); - break; - case DW_EH_PE_sdata8: - result = readPointerHelper<int64_t>(p); - break; - default: - // not supported - abort(); - break; - } - // then add relative offset - switch (encoding & 0x70) - { - case DW_EH_PE_absptr: - // do nothing - break; - case DW_EH_PE_pcrel: - if (result) - result += (uintptr_t)(*data); - break; - case DW_EH_PE_textrel: - case DW_EH_PE_datarel: - case DW_EH_PE_funcrel: - case DW_EH_PE_aligned: - default: - // not supported - abort(); - break; - } - // then apply indirection - if (result && (encoding & DW_EH_PE_indirect)) - result = *((uintptr_t*)result); - *data = p; - return result; -} - -static -void -call_terminate(bool native_exception, _Unwind_Exception* unwind_exception) -{ - __cxa_begin_catch(unwind_exception); - if (native_exception) - { - // Use the stored terminate_handler if possible - __cxa_exception* exception_header = (__cxa_exception*)(unwind_exception+1) - 1; - std::__terminate(exception_header->terminateHandler); - } - std::terminate(); -} - -#if defined(_LIBCXXABI_ARM_EHABI) -static const void* read_target2_value(const void* ptr) -{ - uintptr_t offset = *reinterpret_cast<const uintptr_t*>(ptr); - if (!offset) - return 0; - // "ARM EABI provides a TARGET2 relocation to describe these typeinfo - // pointers. The reason being it allows their precise semantics to be - // deferred to the linker. For bare-metal they turn into absolute - // relocations. For linux they turn into GOT-REL relocations." - // https://gcc.gnu.org/ml/gcc-patches/2009-08/msg00264.html -#if defined(LIBCXXABI_BAREMETAL) - return reinterpret_cast<const void*>(reinterpret_cast<uintptr_t>(ptr) + - offset); -#else - return *reinterpret_cast<const void **>(reinterpret_cast<uintptr_t>(ptr) + - offset); -#endif -} - -static const __shim_type_info* -get_shim_type_info(uint64_t ttypeIndex, const uint8_t* classInfo, - uint8_t ttypeEncoding, bool native_exception, - _Unwind_Exception* unwind_exception) -{ - if (classInfo == 0) - { - // this should not happen. Indicates corrupted eh_table. - call_terminate(native_exception, unwind_exception); - } - - assert(((ttypeEncoding == DW_EH_PE_absptr) || // LLVM or GCC 4.6 - (ttypeEncoding == DW_EH_PE_pcrel) || // GCC 4.7 baremetal - (ttypeEncoding == (DW_EH_PE_pcrel | DW_EH_PE_indirect))) && // GCC 4.7 linux - "Unexpected TTypeEncoding"); - (void)ttypeEncoding; - - const uint8_t* ttypePtr = classInfo - ttypeIndex * sizeof(uintptr_t); - return reinterpret_cast<const __shim_type_info *>( - read_target2_value(ttypePtr)); -} -#else // !defined(_LIBCXXABI_ARM_EHABI) -static -const __shim_type_info* -get_shim_type_info(uint64_t ttypeIndex, const uint8_t* classInfo, - uint8_t ttypeEncoding, bool native_exception, - _Unwind_Exception* unwind_exception) -{ - if (classInfo == 0) - { - // this should not happen. Indicates corrupted eh_table. - call_terminate(native_exception, unwind_exception); - } - switch (ttypeEncoding & 0x0F) - { - case DW_EH_PE_absptr: - ttypeIndex *= sizeof(void*); - break; - case DW_EH_PE_udata2: - case DW_EH_PE_sdata2: - ttypeIndex *= 2; - break; - case DW_EH_PE_udata4: - case DW_EH_PE_sdata4: - ttypeIndex *= 4; - break; - case DW_EH_PE_udata8: - case DW_EH_PE_sdata8: - ttypeIndex *= 8; - break; - default: - // this should not happen. Indicates corrupted eh_table. - call_terminate(native_exception, unwind_exception); - } - classInfo -= ttypeIndex; - return (const __shim_type_info*)readEncodedPointer(&classInfo, ttypeEncoding); -} -#endif // !defined(_LIBCXXABI_ARM_EHABI) - -/* - This is checking a thrown exception type, excpType, against a possibly empty - list of catchType's which make up an exception spec. - - An exception spec acts like a catch handler, but in reverse. This "catch - handler" will catch an excpType if and only if none of the catchType's in - the list will catch a excpType. If any catchType in the list can catch an - excpType, then this exception spec does not catch the excpType. -*/ -#if defined(_LIBCXXABI_ARM_EHABI) -static -bool -exception_spec_can_catch(int64_t specIndex, const uint8_t* classInfo, - uint8_t ttypeEncoding, const __shim_type_info* excpType, - void* adjustedPtr, _Unwind_Exception* unwind_exception) -{ - if (classInfo == 0) - { - // this should not happen. Indicates corrupted eh_table. - call_terminate(false, unwind_exception); - } - - assert(((ttypeEncoding == DW_EH_PE_absptr) || // LLVM or GCC 4.6 - (ttypeEncoding == DW_EH_PE_pcrel) || // GCC 4.7 baremetal - (ttypeEncoding == (DW_EH_PE_pcrel | DW_EH_PE_indirect))) && // GCC 4.7 linux - "Unexpected TTypeEncoding"); - (void)ttypeEncoding; - - // specIndex is negative of 1-based byte offset into classInfo; - specIndex = -specIndex; - --specIndex; - const void** temp = reinterpret_cast<const void**>( - reinterpret_cast<uintptr_t>(classInfo) + - static_cast<uintptr_t>(specIndex) * sizeof(uintptr_t)); - // If any type in the spec list can catch excpType, return false, else return true - // adjustments to adjustedPtr are ignored. - while (true) - { - // ARM EHABI exception specification table (filter table) consists of - // several pointers which will directly point to the type info object - // (instead of ttypeIndex). The table will be terminated with 0. - const void** ttypePtr = temp++; - if (*ttypePtr == 0) - break; - // We can get the __shim_type_info simply by performing a - // R_ARM_TARGET2 relocation, and cast the result to __shim_type_info. - const __shim_type_info* catchType = - static_cast<const __shim_type_info*>(read_target2_value(ttypePtr)); - void* tempPtr = adjustedPtr; - if (catchType->can_catch(excpType, tempPtr)) - return false; - } - return true; -} -#else -static -bool -exception_spec_can_catch(int64_t specIndex, const uint8_t* classInfo, - uint8_t ttypeEncoding, const __shim_type_info* excpType, - void* adjustedPtr, _Unwind_Exception* unwind_exception) -{ - if (classInfo == 0) - { - // this should not happen. Indicates corrupted eh_table. - call_terminate(false, unwind_exception); - } - // specIndex is negative of 1-based byte offset into classInfo; - specIndex = -specIndex; - --specIndex; - const uint8_t* temp = classInfo + specIndex; - // If any type in the spec list can catch excpType, return false, else return true - // adjustments to adjustedPtr are ignored. - while (true) - { - uint64_t ttypeIndex = readULEB128(&temp); - if (ttypeIndex == 0) - break; - const __shim_type_info* catchType = get_shim_type_info(ttypeIndex, - classInfo, - ttypeEncoding, - true, - unwind_exception); - void* tempPtr = adjustedPtr; - if (catchType->can_catch(excpType, tempPtr)) - return false; - } - return true; -} -#endif - -static -void* -get_thrown_object_ptr(_Unwind_Exception* unwind_exception) -{ - // Even for foreign exceptions, the exception object is *probably* at unwind_exception + 1 - // Regardless, this library is prohibited from touching a foreign exception - void* adjustedPtr = unwind_exception + 1; - if (unwind_exception->exception_class == kOurDependentExceptionClass) - adjustedPtr = ((__cxa_dependent_exception*)adjustedPtr - 1)->primaryException; - return adjustedPtr; -} - -namespace -{ - -struct scan_results -{ - int64_t ttypeIndex; // > 0 catch handler, < 0 exception spec handler, == 0 a cleanup - const uint8_t* actionRecord; // Currently unused. Retained to ease future maintenance. - const uint8_t* languageSpecificData; // Needed only for __cxa_call_unexpected - uintptr_t landingPad; // null -> nothing found, else something found - void* adjustedPtr; // Used in cxa_exception.cpp - _Unwind_Reason_Code reason; // One of _URC_FATAL_PHASE1_ERROR, - // _URC_FATAL_PHASE2_ERROR, - // _URC_CONTINUE_UNWIND, - // _URC_HANDLER_FOUND -}; - -} // unnamed namespace - -static -void -set_registers(_Unwind_Exception* unwind_exception, _Unwind_Context* context, - const scan_results& results) -{ -#if defined(__USING_SJLJ_EXCEPTIONS__) -#define __builtin_eh_return_data_regno(regno) regno -#endif - _Unwind_SetGR(context, __builtin_eh_return_data_regno(0), - reinterpret_cast<uintptr_t>(unwind_exception)); - _Unwind_SetGR(context, __builtin_eh_return_data_regno(1), - static_cast<uintptr_t>(results.ttypeIndex)); - _Unwind_SetIP(context, results.landingPad); -} - -/* - There are 3 types of scans needed: - - 1. Scan for handler with native or foreign exception. If handler found, - save state and return _URC_HANDLER_FOUND, else return _URC_CONTINUE_UNWIND. - May also report an error on invalid input. - May terminate for invalid exception table. - _UA_SEARCH_PHASE - - 2. Scan for handler with foreign exception. Must return _URC_HANDLER_FOUND, - or call terminate. - _UA_CLEANUP_PHASE && _UA_HANDLER_FRAME && !native_exception - - 3. Scan for cleanups. If a handler is found and this isn't forced unwind, - then terminate, otherwise ignore the handler and keep looking for cleanup. - If a cleanup is found, return _URC_HANDLER_FOUND, else return _URC_CONTINUE_UNWIND. - May also report an error on invalid input. - May terminate for invalid exception table. - _UA_CLEANUP_PHASE && !_UA_HANDLER_FRAME -*/ - -static void scan_eh_tab(scan_results &results, _Unwind_Action actions, - bool native_exception, - _Unwind_Exception *unwind_exception, - _Unwind_Context *context) { - // Initialize results to found nothing but an error - results.ttypeIndex = 0; - results.actionRecord = 0; - results.languageSpecificData = 0; - results.landingPad = 0; - results.adjustedPtr = 0; - results.reason = _URC_FATAL_PHASE1_ERROR; - // Check for consistent actions - if (actions & _UA_SEARCH_PHASE) - { - // Do Phase 1 - if (actions & (_UA_CLEANUP_PHASE | _UA_HANDLER_FRAME | _UA_FORCE_UNWIND)) - { - // None of these flags should be set during Phase 1 - // Client error - results.reason = _URC_FATAL_PHASE1_ERROR; - return; - } - } - else if (actions & _UA_CLEANUP_PHASE) - { - if ((actions & _UA_HANDLER_FRAME) && (actions & _UA_FORCE_UNWIND)) - { - // _UA_HANDLER_FRAME should only be set if phase 1 found a handler. - // If _UA_FORCE_UNWIND is set, phase 1 shouldn't have happened. - // Client error - results.reason = _URC_FATAL_PHASE2_ERROR; - return; - } - } - else // Neither _UA_SEARCH_PHASE nor _UA_CLEANUP_PHASE is set - { - // One of these should be set. - // Client error - results.reason = _URC_FATAL_PHASE1_ERROR; - return; - } - // Start scan by getting exception table address - const uint8_t *lsda = (const uint8_t *)_Unwind_GetLanguageSpecificData(context); - if (lsda == 0) - { - // There is no exception table - results.reason = _URC_CONTINUE_UNWIND; - return; - } - results.languageSpecificData = lsda; - // Get the current instruction pointer and offset it before next - // instruction in the current frame which threw the exception. - uintptr_t ip = _Unwind_GetIP(context) - 1; - // Get beginning current frame's code (as defined by the - // emitted dwarf code) - uintptr_t funcStart = _Unwind_GetRegionStart(context); -#ifdef __USING_SJLJ_EXCEPTIONS__ - if (ip == uintptr_t(-1)) - { - // no action - results.reason = _URC_CONTINUE_UNWIND; - return; - } - else if (ip == 0) - call_terminate(native_exception, unwind_exception); - // ip is 1-based index into call site table -#else // !__USING_SJLJ_EXCEPTIONS__ - uintptr_t ipOffset = ip - funcStart; -#endif // !defined(_USING_SLJL_EXCEPTIONS__) - const uint8_t* classInfo = NULL; - // Note: See JITDwarfEmitter::EmitExceptionTable(...) for corresponding - // dwarf emission - // Parse LSDA header. - uint8_t lpStartEncoding = *lsda++; - const uint8_t* lpStart = (const uint8_t*)readEncodedPointer(&lsda, lpStartEncoding); - if (lpStart == 0) - lpStart = (const uint8_t*)funcStart; - uint8_t ttypeEncoding = *lsda++; - if (ttypeEncoding != DW_EH_PE_omit) - { - // Calculate type info locations in emitted dwarf code which - // were flagged by type info arguments to llvm.eh.selector - // intrinsic - uintptr_t classInfoOffset = readULEB128(&lsda); - classInfo = lsda + classInfoOffset; - } - // Walk call-site table looking for range that - // includes current PC. - uint8_t callSiteEncoding = *lsda++; -#ifdef __USING_SJLJ_EXCEPTIONS__ - (void)callSiteEncoding; // When using SjLj exceptions, callSiteEncoding is never used -#endif - uint32_t callSiteTableLength = static_cast<uint32_t>(readULEB128(&lsda)); - const uint8_t* callSiteTableStart = lsda; - const uint8_t* callSiteTableEnd = callSiteTableStart + callSiteTableLength; - const uint8_t* actionTableStart = callSiteTableEnd; - const uint8_t* callSitePtr = callSiteTableStart; - while (callSitePtr < callSiteTableEnd) - { - // There is one entry per call site. -#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); - uintptr_t length = readEncodedPointer(&callSitePtr, callSiteEncoding); - uintptr_t landingPad = readEncodedPointer(&callSitePtr, callSiteEncoding); - uintptr_t actionEntry = readULEB128(&callSitePtr); - if ((start <= ipOffset) && (ipOffset < (start + length))) -#else // __USING_SJLJ_EXCEPTIONS__ - // ip is 1-based index into this table - uintptr_t landingPad = readULEB128(&callSitePtr); - uintptr_t actionEntry = readULEB128(&callSitePtr); - if (--ip == 0) -#endif // __USING_SJLJ_EXCEPTIONS__ - { - // Found the call site containing ip. -#ifndef __USING_SJLJ_EXCEPTIONS__ - if (landingPad == 0) - { - // No handler here - results.reason = _URC_CONTINUE_UNWIND; - return; - } - landingPad = (uintptr_t)lpStart + landingPad; -#else // __USING_SJLJ_EXCEPTIONS__ - ++landingPad; -#endif // __USING_SJLJ_EXCEPTIONS__ - if (actionEntry == 0) - { - // Found a cleanup - // If this is a type 1 or type 2 search, there are no handlers - // If this is a type 3 search, you want to install the cleanup. - if ((actions & _UA_CLEANUP_PHASE) && !(actions & _UA_HANDLER_FRAME)) - { - results.ttypeIndex = 0; // Redundant but clarifying - results.landingPad = landingPad; - results.reason = _URC_HANDLER_FOUND; - return; - } - // No handler here - results.reason = _URC_CONTINUE_UNWIND; - return; - } - // Convert 1-based byte offset into - const uint8_t* action = actionTableStart + (actionEntry - 1); - // Scan action entries until you find a matching handler, cleanup, or the end of action list - while (true) - { - const uint8_t* actionRecord = action; - int64_t ttypeIndex = readSLEB128(&action); - if (ttypeIndex > 0) - { - // Found a catch, does it actually catch? - // First check for catch (...) - const __shim_type_info* catchType = - get_shim_type_info(static_cast<uint64_t>(ttypeIndex), - classInfo, ttypeEncoding, - native_exception, unwind_exception); - if (catchType == 0) - { - // Found catch (...) catches everything, including foreign exceptions - // If this is a type 1 search save state and return _URC_HANDLER_FOUND - // If this is a type 2 search save state and return _URC_HANDLER_FOUND - // If this is a type 3 search !_UA_FORCE_UNWIND, we should have found this in phase 1! - // If this is a type 3 search _UA_FORCE_UNWIND, ignore handler and continue scan - if ((actions & _UA_SEARCH_PHASE) || (actions & _UA_HANDLER_FRAME)) - { - // Save state and return _URC_HANDLER_FOUND - results.ttypeIndex = ttypeIndex; - results.actionRecord = actionRecord; - results.landingPad = landingPad; - results.adjustedPtr = get_thrown_object_ptr(unwind_exception); - results.reason = _URC_HANDLER_FOUND; - return; - } - else if (!(actions & _UA_FORCE_UNWIND)) - { - // It looks like the exception table has changed - // on us. Likely stack corruption! - call_terminate(native_exception, unwind_exception); - } - } - // Else this is a catch (T) clause and will never - // catch a foreign exception - else if (native_exception) - { - __cxa_exception* exception_header = (__cxa_exception*)(unwind_exception+1) - 1; - void* adjustedPtr = get_thrown_object_ptr(unwind_exception); - const __shim_type_info* excpType = - static_cast<const __shim_type_info*>(exception_header->exceptionType); - if (adjustedPtr == 0 || excpType == 0) - { - // Something very bad happened - call_terminate(native_exception, unwind_exception); - } - if (catchType->can_catch(excpType, adjustedPtr)) - { - // Found a matching handler - // If this is a type 1 search save state and return _URC_HANDLER_FOUND - // If this is a type 3 search and !_UA_FORCE_UNWIND, we should have found this in phase 1! - // If this is a type 3 search and _UA_FORCE_UNWIND, ignore handler and continue scan - if (actions & _UA_SEARCH_PHASE) - { - // Save state and return _URC_HANDLER_FOUND - results.ttypeIndex = ttypeIndex; - results.actionRecord = actionRecord; - results.landingPad = landingPad; - results.adjustedPtr = adjustedPtr; - results.reason = _URC_HANDLER_FOUND; - return; - } - else if (!(actions & _UA_FORCE_UNWIND)) - { - // It looks like the exception table has changed - // on us. Likely stack corruption! - call_terminate(native_exception, unwind_exception); - } - } - } - // Scan next action ... - } - else if (ttypeIndex < 0) - { - // Found an exception spec. If this is a foreign exception, - // it is always caught. - if (native_exception) - { - // Does the exception spec catch this native exception? - __cxa_exception* exception_header = (__cxa_exception*)(unwind_exception+1) - 1; - void* adjustedPtr = get_thrown_object_ptr(unwind_exception); - const __shim_type_info* excpType = - static_cast<const __shim_type_info*>(exception_header->exceptionType); - if (adjustedPtr == 0 || excpType == 0) - { - // Something very bad happened - call_terminate(native_exception, unwind_exception); - } - if (exception_spec_can_catch(ttypeIndex, classInfo, - ttypeEncoding, excpType, - adjustedPtr, unwind_exception)) - { - // native exception caught by exception spec - // If this is a type 1 search, save state and return _URC_HANDLER_FOUND - // If this is a type 3 search !_UA_FORCE_UNWIND, we should have found this in phase 1! - // If this is a type 3 search _UA_FORCE_UNWIND, ignore handler and continue scan - if (actions & _UA_SEARCH_PHASE) - { - // Save state and return _URC_HANDLER_FOUND - results.ttypeIndex = ttypeIndex; - results.actionRecord = actionRecord; - results.landingPad = landingPad; - results.adjustedPtr = adjustedPtr; - results.reason = _URC_HANDLER_FOUND; - return; - } - else if (!(actions & _UA_FORCE_UNWIND)) - { - // It looks like the exception table has changed - // on us. Likely stack corruption! - call_terminate(native_exception, unwind_exception); - } - } - } - else - { - // foreign exception caught by exception spec - // If this is a type 1 search, save state and return _URC_HANDLER_FOUND - // If this is a type 2 search, save state and return _URC_HANDLER_FOUND - // If this is a type 3 search !_UA_FORCE_UNWIND, we should have found this in phase 1! - // If this is a type 3 search _UA_FORCE_UNWIND, ignore handler and continue scan - if ((actions & _UA_SEARCH_PHASE) || (actions & _UA_HANDLER_FRAME)) - { - // Save state and return _URC_HANDLER_FOUND - results.ttypeIndex = ttypeIndex; - results.actionRecord = actionRecord; - results.landingPad = landingPad; - results.adjustedPtr = get_thrown_object_ptr(unwind_exception); - results.reason = _URC_HANDLER_FOUND; - return; - } - else if (!(actions & _UA_FORCE_UNWIND)) - { - // It looks like the exception table has changed - // on us. Likely stack corruption! - call_terminate(native_exception, unwind_exception); - } - } - // Scan next action ... - } - else // ttypeIndex == 0 - { - // Found a cleanup - // If this is a type 1 search, ignore it and continue scan - // If this is a type 2 search, ignore it and continue scan - // If this is a type 3 search, save state and return _URC_HANDLER_FOUND - if ((actions & _UA_CLEANUP_PHASE) && !(actions & _UA_HANDLER_FRAME)) - { - // Save state and return _URC_HANDLER_FOUND - results.ttypeIndex = ttypeIndex; - results.actionRecord = actionRecord; - results.landingPad = landingPad; - results.adjustedPtr = get_thrown_object_ptr(unwind_exception); - results.reason = _URC_HANDLER_FOUND; - return; - } - } - const uint8_t* temp = action; - int64_t actionOffset = readSLEB128(&temp); - if (actionOffset == 0) - { - // End of action list, no matching handler or cleanup found - results.reason = _URC_CONTINUE_UNWIND; - return; - } - // Go to next action - action += actionOffset; - } // there is no break out of this loop, only return - } -#ifndef __USING_SJLJ_EXCEPTIONS__ - else if (ipOffset < start) - { - // There is no call site for this ip - // Something bad has happened. We should never get here. - // Possible stack corruption. - call_terminate(native_exception, unwind_exception); - } -#endif // !__USING_SJLJ_EXCEPTIONS__ - } // there might be some tricky cases which break out of this loop - - // It is possible that no eh table entry specify how to handle - // this exception. By spec, terminate it immediately. - call_terminate(native_exception, unwind_exception); -} - -// public API - -/* -The personality function branches on actions like so: - -_UA_SEARCH_PHASE - - If _UA_CLEANUP_PHASE or _UA_HANDLER_FRAME or _UA_FORCE_UNWIND there's - an error from above, return _URC_FATAL_PHASE1_ERROR. - - Scan for anything that could stop unwinding: - - 1. A catch clause that will catch this exception - (will never catch foreign). - 2. A catch (...) (will always catch foreign). - 3. An exception spec that will catch this exception - (will always catch foreign). - If a handler is found - If not foreign - Save state in header - return _URC_HANDLER_FOUND - Else a handler not found - return _URC_CONTINUE_UNWIND - -_UA_CLEANUP_PHASE - - If _UA_HANDLER_FRAME - If _UA_FORCE_UNWIND - How did this happen? return _URC_FATAL_PHASE2_ERROR - If foreign - Do _UA_SEARCH_PHASE to recover state - else - Recover state from header - Transfer control to landing pad. return _URC_INSTALL_CONTEXT - - Else - - This branch handles both normal C++ non-catching handlers (cleanups) - and forced unwinding. - Scan for anything that can not stop unwinding: - - 1. A cleanup. - - If a cleanup is found - transfer control to it. return _URC_INSTALL_CONTEXT - Else a cleanup is not found: return _URC_CONTINUE_UNWIND -*/ - -#if !defined(_LIBCXXABI_ARM_EHABI) -_LIBCXXABI_FUNC_VIS _Unwind_Reason_Code -#ifdef __USING_SJLJ_EXCEPTIONS__ -__gxx_personality_sj0 -#else -__gxx_personality_v0 -#endif - (int version, _Unwind_Action actions, uint64_t exceptionClass, - _Unwind_Exception* unwind_exception, _Unwind_Context* context) -{ - if (version != 1 || unwind_exception == 0 || context == 0) - return _URC_FATAL_PHASE1_ERROR; - - bool native_exception = (exceptionClass & get_vendor_and_language) == - (kOurExceptionClass & get_vendor_and_language); - scan_results results; - if (actions & _UA_SEARCH_PHASE) - { - // Phase 1 search: All we're looking for in phase 1 is a handler that - // halts unwinding - scan_eh_tab(results, actions, native_exception, unwind_exception, context); - if (results.reason == _URC_HANDLER_FOUND) - { - // Found one. Can we cache the results somewhere to optimize phase 2? - if (native_exception) - { - __cxa_exception* exception_header = (__cxa_exception*)(unwind_exception+1) - 1; - exception_header->handlerSwitchValue = static_cast<int>(results.ttypeIndex); - exception_header->actionRecord = results.actionRecord; - exception_header->languageSpecificData = results.languageSpecificData; - exception_header->catchTemp = reinterpret_cast<void*>(results.landingPad); - exception_header->adjustedPtr = results.adjustedPtr; - } - return _URC_HANDLER_FOUND; - } - // Did not find a catching-handler. Return the results of the scan - // (normally _URC_CONTINUE_UNWIND, but could have been _URC_FATAL_PHASE1_ERROR - // if we were called improperly). - return results.reason; - } - if (actions & _UA_CLEANUP_PHASE) - { - // Phase 2 search: - // Did we find a catching handler in phase 1? - if (actions & _UA_HANDLER_FRAME) - { - // Yes, phase 1 said we have a catching handler here. - // Did we cache the results of the scan? - if (native_exception) - { - // Yes, reload the results from the cache. - __cxa_exception* exception_header = (__cxa_exception*)(unwind_exception+1) - 1; - results.ttypeIndex = exception_header->handlerSwitchValue; - results.actionRecord = exception_header->actionRecord; - results.languageSpecificData = exception_header->languageSpecificData; - results.landingPad = reinterpret_cast<uintptr_t>(exception_header->catchTemp); - results.adjustedPtr = exception_header->adjustedPtr; - } - else - { - // No, do the scan again to reload the results. - scan_eh_tab(results, actions, native_exception, unwind_exception, context); - // Phase 1 told us we would find a handler. Now in Phase 2 we - // didn't find a handler. The eh table should not be changing! - if (results.reason != _URC_HANDLER_FOUND) - call_terminate(native_exception, unwind_exception); - } - // Jump to the handler - set_registers(unwind_exception, context, results); - return _URC_INSTALL_CONTEXT; - } - // Either we didn't do a phase 1 search (due to forced unwinding), or - // phase 1 reported no catching-handlers. - // Search for a (non-catching) cleanup - scan_eh_tab(results, actions, native_exception, unwind_exception, context); - if (results.reason == _URC_HANDLER_FOUND) - { - // Found a non-catching handler. Jump to it: - set_registers(unwind_exception, context, results); - return _URC_INSTALL_CONTEXT; - } - // Did not find a cleanup. Return the results of the scan - // (normally _URC_CONTINUE_UNWIND, but could have been _URC_FATAL_PHASE2_ERROR - // if we were called improperly). - return results.reason; - } - // We were called improperly: neither a phase 1 or phase 2 search - return _URC_FATAL_PHASE1_ERROR; -} -#else - -extern "C" _Unwind_Reason_Code __gnu_unwind_frame(_Unwind_Exception*, - _Unwind_Context*); - -// 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_Exception* unwind_exception, - _Unwind_Context* context) -{ - if (__gnu_unwind_frame(unwind_exception, context) != _URC_OK) - return _URC_FAILURE; - return _URC_CONTINUE_UNWIND; -} - -// ARM register names -#if !defined(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, - const scan_results& results) -{ - unwind_exception->barrier_cache.bitpattern[0] = (uint32_t)results.adjustedPtr; - unwind_exception->barrier_cache.bitpattern[1] = (uint32_t)results.actionRecord; - unwind_exception->barrier_cache.bitpattern[2] = (uint32_t)results.languageSpecificData; - unwind_exception->barrier_cache.bitpattern[3] = (uint32_t)results.landingPad; - unwind_exception->barrier_cache.bitpattern[4] = (uint32_t)results.ttypeIndex; -} - -static void load_results_from_barrier_cache(scan_results& results, - const _Unwind_Exception* unwind_exception) -{ - results.adjustedPtr = (void*)unwind_exception->barrier_cache.bitpattern[0]; - results.actionRecord = (const uint8_t*)unwind_exception->barrier_cache.bitpattern[1]; - results.languageSpecificData = (const uint8_t*)unwind_exception->barrier_cache.bitpattern[2]; - results.landingPad = (uintptr_t)unwind_exception->barrier_cache.bitpattern[3]; - results.ttypeIndex = (int64_t)(int32_t)unwind_exception->barrier_cache.bitpattern[4]; -} - -extern "C" _LIBCXXABI_FUNC_VIS _Unwind_Reason_Code -__gxx_personality_v0(_Unwind_State state, - _Unwind_Exception* unwind_exception, - _Unwind_Context* context) -{ - if (unwind_exception == 0 || context == 0) - return _URC_FATAL_PHASE1_ERROR; - - bool native_exception = (unwind_exception->exception_class & get_vendor_and_language) == - (kOurExceptionClass & get_vendor_and_language); - -#if !defined(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) - { - unwind_exception->barrier_cache.sp = _Unwind_GetGR(context, REG_SP); - if (native_exception) - save_results_to_barrier_cache(unwind_exception, results); - return _URC_HANDLER_FOUND; - } - // Did not find the catch handler - if (results.reason == _URC_CONTINUE_UNWIND) - 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)) - { - // Found a catching handler in phase 1 - if (native_exception) - { - // Load the result from the native exception barrier cache. - load_results_from_barrier_cache(results, unwind_exception); - results.reason = _URC_HANDLER_FOUND; - } - else - { - // Search for the catching handler again for the foreign exception. - scan_eh_tab(results, static_cast<_Unwind_Action>(_UA_CLEANUP_PHASE | _UA_HANDLER_FRAME), - native_exception, unwind_exception, context); - if (results.reason != _URC_HANDLER_FOUND) // phase1 search should guarantee to find one - call_terminate(native_exception, unwind_exception); - } - - // Install the context for the catching handler - set_registers(unwind_exception, context, results); - return _URC_INSTALL_CONTEXT; - } - - // Either we didn't do a phase 1 search (due to forced unwinding), or - // phase 1 reported no catching-handlers. - // Search for a (non-catching) cleanup - scan_eh_tab(results, _UA_CLEANUP_PHASE, native_exception, unwind_exception, context); - if (results.reason == _URC_HANDLER_FOUND) - { - // Found a non-catching handler - - // ARM EHABI 8.4.2: Before we can jump to the cleanup handler, we have to setup some - // internal data structures, so that __cxa_end_cleanup() can get unwind_exception from - // __cxa_get_globals(). - __cxa_begin_cleanup(unwind_exception); - - // Install the context for the cleanup handler - set_registers(unwind_exception, context, results); - return _URC_INSTALL_CONTEXT; - } - - // Did not find any handler - if (results.reason == _URC_CONTINUE_UNWIND) - return continue_unwind(unwind_exception, context); - return results.reason; - - case _US_UNWIND_FRAME_RESUME: - return continue_unwind(unwind_exception, context); - } - - // We were called improperly: neither a phase 1 or phase 2 search - return _URC_FATAL_PHASE1_ERROR; -} -#endif - - -__attribute__((noreturn)) -_LIBCXXABI_FUNC_VIS void -__cxa_call_unexpected(void* arg) -{ - _Unwind_Exception* unwind_exception = static_cast<_Unwind_Exception*>(arg); - if (unwind_exception == 0) - call_terminate(false, unwind_exception); - __cxa_begin_catch(unwind_exception); - bool native_old_exception = - (unwind_exception->exception_class & get_vendor_and_language) == - (kOurExceptionClass & get_vendor_and_language); - std::unexpected_handler u_handler; - std::terminate_handler t_handler; - __cxa_exception* old_exception_header = 0; - int64_t ttypeIndex; - const uint8_t* lsda; - if (native_old_exception) - { - old_exception_header = (__cxa_exception*)(unwind_exception+1) - 1; - t_handler = old_exception_header->terminateHandler; - u_handler = old_exception_header->unexpectedHandler; - // If std::__unexpected(u_handler) rethrows the same exception, - // these values get overwritten by the rethrow. So save them now: -#if defined(_LIBCXXABI_ARM_EHABI) - ttypeIndex = (int64_t)(int32_t)unwind_exception->barrier_cache.bitpattern[4]; - lsda = (const uint8_t*)unwind_exception->barrier_cache.bitpattern[2]; -#else - ttypeIndex = old_exception_header->handlerSwitchValue; - lsda = old_exception_header->languageSpecificData; -#endif - } - else - { - t_handler = std::get_terminate(); - u_handler = std::get_unexpected(); - } - try - { - std::__unexpected(u_handler); - } - catch (...) - { - // If the old exception is foreign, then all we can do is terminate. - // We have no way to recover the needed old exception spec. There's - // no way to pass that information here. And the personality routine - // can't call us directly and do anything but terminate() if we throw - // from here. - if (native_old_exception) - { - // Have: - // old_exception_header->languageSpecificData - // old_exception_header->actionRecord - // Need - // const uint8_t* classInfo - // uint8_t ttypeEncoding - uint8_t lpStartEncoding = *lsda++; - const uint8_t* lpStart = (const uint8_t*)readEncodedPointer(&lsda, lpStartEncoding); - (void)lpStart; // purposefully unused. Just needed to increment lsda. - uint8_t ttypeEncoding = *lsda++; - if (ttypeEncoding == DW_EH_PE_omit) - std::__terminate(t_handler); - uintptr_t classInfoOffset = readULEB128(&lsda); - const uint8_t* classInfo = lsda + classInfoOffset; - // Is this new exception catchable by the exception spec at ttypeIndex? - // The answer is obviously yes if the new and old exceptions are the same exception - // If no - // throw; - __cxa_eh_globals* globals = __cxa_get_globals_fast(); - __cxa_exception* new_exception_header = globals->caughtExceptions; - if (new_exception_header == 0) - // This shouldn't be able to happen! - std::__terminate(t_handler); - bool native_new_exception = - (new_exception_header->unwindHeader.exception_class & get_vendor_and_language) == - (kOurExceptionClass & get_vendor_and_language); - void* adjustedPtr; - if (native_new_exception && (new_exception_header != old_exception_header)) - { - const __shim_type_info* excpType = - static_cast<const __shim_type_info*>(new_exception_header->exceptionType); - adjustedPtr = - new_exception_header->unwindHeader.exception_class == kOurDependentExceptionClass ? - ((__cxa_dependent_exception*)new_exception_header)->primaryException : - new_exception_header + 1; - if (!exception_spec_can_catch(ttypeIndex, classInfo, ttypeEncoding, - excpType, adjustedPtr, unwind_exception)) - { - // We need to __cxa_end_catch, but for the old exception, - // not the new one. This is a little tricky ... - // Disguise new_exception_header as a rethrown exception, but - // don't actually rethrow it. This means you can temporarily - // end the catch clause enclosing new_exception_header without - // __cxa_end_catch destroying new_exception_header. - new_exception_header->handlerCount = -new_exception_header->handlerCount; - globals->uncaughtExceptions += 1; - // Call __cxa_end_catch for new_exception_header - __cxa_end_catch(); - // Call __cxa_end_catch for old_exception_header - __cxa_end_catch(); - // Renter this catch clause with new_exception_header - __cxa_begin_catch(&new_exception_header->unwindHeader); - // Rethrow new_exception_header - throw; - } - } - // Will a std::bad_exception be catchable by the exception spec at - // ttypeIndex? - // If no - // throw std::bad_exception(); - const __shim_type_info* excpType = - static_cast<const __shim_type_info*>(&typeid(std::bad_exception)); - std::bad_exception be; - adjustedPtr = &be; - if (!exception_spec_can_catch(ttypeIndex, classInfo, ttypeEncoding, - excpType, adjustedPtr, unwind_exception)) - { - // We need to __cxa_end_catch for both the old exception and the - // new exception. Technically we should do it in that order. - // But it is expedient to do it in the opposite order: - // Call __cxa_end_catch for new_exception_header - __cxa_end_catch(); - // Throw std::bad_exception will __cxa_end_catch for - // old_exception_header - throw be; - } - } - } - std::__terminate(t_handler); -} - -} // extern "C" - -} // __cxxabiv1 diff --git a/chromium/buildtools/third_party/libc++abi/trunk/src/cxa_thread_atexit.cpp b/chromium/buildtools/third_party/libc++abi/trunk/src/cxa_thread_atexit.cpp deleted file mode 100644 index 49d15d6b145..00000000000 --- a/chromium/buildtools/third_party/libc++abi/trunk/src/cxa_thread_atexit.cpp +++ /dev/null @@ -1,140 +0,0 @@ -//===----------------------- cxa_thread_atexit.cpp ------------------------===// -// -// 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. -// -//===----------------------------------------------------------------------===// - -#include "abort_message.h" -#include "cxxabi.h" -#include <__threading_support> -#include <cstdlib> - -namespace __cxxabiv1 { - - using Dtor = void(*)(void*); - - extern "C" -#ifndef HAVE___CXA_THREAD_ATEXIT_IMPL - // A weak symbol is used to detect this function's presence in the C library - // at runtime, even if libc++ is built against an older libc - _LIBCXXABI_WEAK -#endif - int __cxa_thread_atexit_impl(Dtor, void*, void*); - -#ifndef HAVE___CXA_THREAD_ATEXIT_IMPL - -namespace { - // This implementation is used if the C library does not provide - // __cxa_thread_atexit_impl() for us. It has a number of limitations that are - // difficult to impossible to address without ..._impl(): - // - // - dso_symbol is ignored. This means that a shared library may be unloaded - // (via dlclose()) before its thread_local destructors have run. - // - // - thread_local destructors for the main thread are run by the destructor of - // a static object. This is later than expected; they should run before the - // destructors of any objects with static storage duration. - // - // - thread_local destructors on non-main threads run on the first iteration - // through the __libccpp_tls_key destructors. - // std::notify_all_at_thread_exit() and similar functions must be careful to - // wait until the second iteration to provide their intended ordering - // guarantees. - // - // Another limitation, though one shared with ..._impl(), is that any - // thread_locals that are first initialized after non-thread_local global - // destructors begin to run will not be destroyed. [basic.start.term] states - // that all thread_local destructors are sequenced before the destruction of - // objects with static storage duration, resulting in a contradiction if a - // thread_local is constructed after that point. Thus we consider such - // programs ill-formed, and don't bother to run those destructors. (If the - // program terminates abnormally after such a thread_local is constructed, - // the destructor is not expected to run and thus there is no contradiction. - // So construction still has to work.) - - struct DtorList { - Dtor dtor; - void* obj; - DtorList* next; - }; - - // The linked list of thread-local destructors to run - __thread DtorList* dtors = nullptr; - // True if the destructors are currently scheduled to run on this thread - __thread bool dtors_alive = false; - // Used to trigger destructors on thread exit; value is ignored - std::__libcpp_tls_key dtors_key; - - void run_dtors(void*) { - while (auto head = dtors) { - dtors = head->next; - head->dtor(head->obj); - std::free(head); - } - - dtors_alive = false; - } - - struct DtorsManager { - DtorsManager() { - // There is intentionally no matching std::__libcpp_tls_delete call, as - // __cxa_thread_atexit() may be called arbitrarily late (for example, from - // global destructors or atexit() handlers). - if (std::__libcpp_tls_create(&dtors_key, run_dtors) != 0) { - abort_message("std::__libcpp_tls_create() failed in __cxa_thread_atexit()"); - } - } - - ~DtorsManager() { - // std::__libcpp_tls_key destructors do not run on threads that call exit() - // (including when the main thread returns from main()), so we explicitly - // call the destructor here. This runs at exit time (potentially earlier - // if libc++abi is dlclose()'d). Any thread_locals initialized after this - // point will not be destroyed. - run_dtors(nullptr); - } - }; -} // namespace - -#endif // HAVE___CXA_THREAD_ATEXIT_IMPL - -extern "C" { - - _LIBCXXABI_FUNC_VIS int __cxa_thread_atexit(Dtor dtor, void* obj, void* dso_symbol) throw() { -#ifdef HAVE___CXA_THREAD_ATEXIT_IMPL - return __cxa_thread_atexit_impl(dtor, obj, dso_symbol); -#else - if (__cxa_thread_atexit_impl) { - return __cxa_thread_atexit_impl(dtor, obj, dso_symbol); - } else { - // Initialize the dtors std::__libcpp_tls_key (uses __cxa_guard_*() for - // one-time initialization and __cxa_atexit() for destruction) - static DtorsManager manager; - - if (!dtors_alive) { - if (std::__libcpp_tls_set(dtors_key, &dtors_key) != 0) { - return -1; - } - dtors_alive = true; - } - - auto head = static_cast<DtorList*>(std::malloc(sizeof(DtorList))); - if (!head) { - return -1; - } - - head->dtor = dtor; - head->obj = obj; - head->next = dtors; - dtors = head; - - return 0; - } -#endif // HAVE___CXA_THREAD_ATEXIT_IMPL - } - -} // extern "C" -} // namespace __cxxabiv1 diff --git a/chromium/buildtools/third_party/libc++abi/trunk/src/cxa_unexpected.cpp b/chromium/buildtools/third_party/libc++abi/trunk/src/cxa_unexpected.cpp deleted file mode 100644 index 7d4ef80c39e..00000000000 --- a/chromium/buildtools/third_party/libc++abi/trunk/src/cxa_unexpected.cpp +++ /dev/null @@ -1,23 +0,0 @@ -//===------------------------- cxa_unexpected.cpp -------------------------===// -// -// 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. -// -//===----------------------------------------------------------------------===// - -#include <exception> -#include "cxxabi.h" -#include "cxa_exception.hpp" - -namespace __cxxabiv1 -{ - -extern "C" -{ - -} - -} // namespace __cxxabiv1 - diff --git a/chromium/buildtools/third_party/libc++abi/trunk/src/cxa_vector.cpp b/chromium/buildtools/third_party/libc++abi/trunk/src/cxa_vector.cpp deleted file mode 100644 index c32a2119756..00000000000 --- a/chromium/buildtools/third_party/libc++abi/trunk/src/cxa_vector.cpp +++ /dev/null @@ -1,367 +0,0 @@ -//===-------------------------- cxa_vector.cpp ---------------------------===// -// -// 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. -// -// -// This file implements the "Array Construction and Destruction APIs" -// http://mentorembedded.github.io/cxx-abi/abi.html#array-ctor -// -//===----------------------------------------------------------------------===// - -#include "cxxabi.h" - -#include <exception> // for std::terminate - -namespace __cxxabiv1 { - -#if 0 -#pragma mark --Helper routines and classes -- -#endif - -namespace { - inline static size_t __get_element_count ( void *p ) { - return static_cast <size_t *> (p)[-1]; - } - - inline static void __set_element_count ( void *p, size_t element_count ) { - static_cast <size_t *> (p)[-1] = element_count; - } - - -// A pair of classes to simplify exception handling and control flow. -// They get passed a block of memory in the constructor, and unless the -// 'release' method is called, they deallocate the memory in the destructor. -// Preferred usage is to allocate some memory, attach it to one of these objects, -// and then, when all the operations to set up the memory block have succeeded, -// call 'release'. If any of the setup operations fail, or an exception is -// thrown, then the block is automatically deallocated. -// -// The only difference between these two classes is the signature for the -// deallocation function (to match new2/new3 and delete2/delete3. - class st_heap_block2 { - public: - typedef void (*dealloc_f)(void *); - - st_heap_block2 ( dealloc_f dealloc, void *ptr ) - : dealloc_ ( dealloc ), ptr_ ( ptr ), enabled_ ( true ) {} - ~st_heap_block2 () { if ( enabled_ ) dealloc_ ( ptr_ ) ; } - void release () { enabled_ = false; } - - private: - dealloc_f dealloc_; - void *ptr_; - bool enabled_; - }; - - class st_heap_block3 { - public: - typedef void (*dealloc_f)(void *, size_t); - - st_heap_block3 ( dealloc_f dealloc, void *ptr, size_t size ) - : dealloc_ ( dealloc ), ptr_ ( ptr ), size_ ( size ), enabled_ ( true ) {} - ~st_heap_block3 () { if ( enabled_ ) dealloc_ ( ptr_, size_ ) ; } - void release () { enabled_ = false; } - - private: - dealloc_f dealloc_; - void *ptr_; - size_t size_; - bool enabled_; - }; - - class st_cxa_cleanup { - public: - typedef void (*destruct_f)(void *); - - st_cxa_cleanup ( void *ptr, size_t &idx, size_t element_size, destruct_f destructor ) - : ptr_ ( ptr ), idx_ ( idx ), element_size_ ( element_size ), - destructor_ ( destructor ), enabled_ ( true ) {} - ~st_cxa_cleanup () { - if ( enabled_ ) - __cxa_vec_cleanup ( ptr_, idx_, element_size_, destructor_ ); - } - - void release () { enabled_ = false; } - - private: - void *ptr_; - size_t &idx_; - size_t element_size_; - destruct_f destructor_; - bool enabled_; - }; - - class st_terminate { - public: - st_terminate ( bool enabled = true ) : enabled_ ( enabled ) {} - ~st_terminate () { if ( enabled_ ) std::terminate (); } - void release () { enabled_ = false; } - private: - bool enabled_ ; - }; -} - -#if 0 -#pragma mark --Externally visible routines-- -#endif - -extern "C" { - -// Equivalent to -// -// __cxa_vec_new2(element_count, element_size, padding_size, constructor, -// destructor, &::operator new[], &::operator delete[]) -_LIBCXXABI_FUNC_VIS void * -__cxa_vec_new(size_t element_count, size_t element_size, size_t padding_size, - void (*constructor)(void *), void (*destructor)(void *)) { - return __cxa_vec_new2 ( element_count, element_size, padding_size, - constructor, destructor, &::operator new [], &::operator delete [] ); -} - - - -// Given the number and size of elements for an array and the non-negative -// size of prefix padding for a cookie, allocate space (using alloc) for -// the array preceded by the specified padding, initialize the cookie if -// the padding is non-zero, and call the given constructor on each element. -// Return the address of the array proper, after the padding. -// -// If alloc throws an exception, rethrow the exception. If alloc returns -// NULL, return NULL. If the constructor throws an exception, call -// destructor for any already constructed elements, and rethrow the -// exception. If the destructor throws an exception, call std::terminate. -// -// The constructor may be NULL, in which case it must not be called. If the -// padding_size is zero, the destructor may be NULL; in that case it must -// not be called. -// -// Neither alloc nor dealloc may be NULL. -_LIBCXXABI_FUNC_VIS void * -__cxa_vec_new2(size_t element_count, size_t element_size, size_t padding_size, - void (*constructor)(void *), void (*destructor)(void *), - void *(*alloc)(size_t), void (*dealloc)(void *)) { - const size_t heap_size = element_count * element_size + padding_size; - char * const heap_block = static_cast<char *> ( alloc ( heap_size )); - char *vec_base = heap_block; - - if ( NULL != vec_base ) { - st_heap_block2 heap ( dealloc, heap_block ); - - // put the padding before the array elements - if ( 0 != padding_size ) { - vec_base += padding_size; - __set_element_count ( vec_base, element_count ); - } - - // Construct the elements - __cxa_vec_ctor ( vec_base, element_count, element_size, constructor, destructor ); - heap.release (); // We're good! - } - - return vec_base; -} - - -// Same as __cxa_vec_new2 except that the deallocation function takes both -// the object address and its size. -_LIBCXXABI_FUNC_VIS void * -__cxa_vec_new3(size_t element_count, size_t element_size, size_t padding_size, - void (*constructor)(void *), void (*destructor)(void *), - void *(*alloc)(size_t), void (*dealloc)(void *, size_t)) { - const size_t heap_size = element_count * element_size + padding_size; - char * const heap_block = static_cast<char *> ( alloc ( heap_size )); - char *vec_base = heap_block; - - if ( NULL != vec_base ) { - st_heap_block3 heap ( dealloc, heap_block, heap_size ); - - // put the padding before the array elements - if ( 0 != padding_size ) { - vec_base += padding_size; - __set_element_count ( vec_base, element_count ); - } - - // Construct the elements - __cxa_vec_ctor ( vec_base, element_count, element_size, constructor, destructor ); - heap.release (); // We're good! - } - - return vec_base; -} - - -// Given the (data) addresses of a destination and a source array, an -// element count and an element size, call the given copy constructor to -// copy each element from the source array to the destination array. The -// copy constructor's arguments are the destination address and source -// address, respectively. If an exception occurs, call the given destructor -// (if non-NULL) on each copied element and rethrow. If the destructor -// throws an exception, call terminate(). The constructor and or destructor -// pointers may be NULL. If either is NULL, no action is taken when it -// would have been called. - -_LIBCXXABI_FUNC_VIS void __cxa_vec_cctor(void *dest_array, void *src_array, - size_t element_count, - size_t element_size, - void (*constructor)(void *, void *), - void (*destructor)(void *)) { - if ( NULL != constructor ) { - size_t idx = 0; - char *src_ptr = static_cast<char *>(src_array); - char *dest_ptr = static_cast<char *>(dest_array); - st_cxa_cleanup cleanup ( dest_array, idx, element_size, destructor ); - - for ( idx = 0; idx < element_count; - ++idx, src_ptr += element_size, dest_ptr += element_size ) - constructor ( dest_ptr, src_ptr ); - cleanup.release (); // We're good! - } -} - - -// Given the (data) address of an array, not including any cookie padding, -// and the number and size of its elements, call the given constructor on -// each element. If the constructor throws an exception, call the given -// destructor for any already-constructed elements, and rethrow the -// exception. If the destructor throws an exception, call terminate(). The -// constructor and/or destructor pointers may be NULL. If either is NULL, -// no action is taken when it would have been called. -_LIBCXXABI_FUNC_VIS void -__cxa_vec_ctor(void *array_address, size_t element_count, size_t element_size, - void (*constructor)(void *), void (*destructor)(void *)) { - if ( NULL != constructor ) { - size_t idx; - char *ptr = static_cast <char *> ( array_address ); - st_cxa_cleanup cleanup ( array_address, idx, element_size, destructor ); - - // Construct the elements - for ( idx = 0; idx < element_count; ++idx, ptr += element_size ) - constructor ( ptr ); - cleanup.release (); // We're good! - } -} - -// Given the (data) address of an array, the number of elements, and the -// size of its elements, call the given destructor on each element. If the -// destructor throws an exception, rethrow after destroying the remaining -// elements if possible. If the destructor throws a second exception, call -// terminate(). The destructor pointer may be NULL, in which case this -// routine does nothing. -_LIBCXXABI_FUNC_VIS void __cxa_vec_dtor(void *array_address, - size_t element_count, - size_t element_size, - void (*destructor)(void *)) { - if ( NULL != destructor ) { - char *ptr = static_cast <char *> (array_address); - size_t idx = element_count; - st_cxa_cleanup cleanup ( array_address, idx, element_size, destructor ); - { - st_terminate exception_guard (__cxa_uncaught_exception ()); - ptr += element_count * element_size; // one past the last element - - while ( idx-- > 0 ) { - ptr -= element_size; - destructor ( ptr ); - } - exception_guard.release (); // We're good ! - } - cleanup.release (); // We're still good! - } -} - -// Given the (data) address of an array, the number of elements, and the -// size of its elements, call the given destructor on each element. If the -// destructor throws an exception, call terminate(). The destructor pointer -// may be NULL, in which case this routine does nothing. -_LIBCXXABI_FUNC_VIS void __cxa_vec_cleanup(void *array_address, - size_t element_count, - size_t element_size, - void (*destructor)(void *)) { - if ( NULL != destructor ) { - char *ptr = static_cast <char *> (array_address); - size_t idx = element_count; - st_terminate exception_guard; - - ptr += element_count * element_size; // one past the last element - while ( idx-- > 0 ) { - ptr -= element_size; - destructor ( ptr ); - } - exception_guard.release (); // We're done! - } -} - - -// If the array_address is NULL, return immediately. Otherwise, given the -// (data) address of an array, the non-negative size of prefix padding for -// the cookie, and the size of its elements, call the given destructor on -// each element, using the cookie to determine the number of elements, and -// then delete the space by calling ::operator delete[](void *). If the -// destructor throws an exception, rethrow after (a) destroying the -// remaining elements, and (b) deallocating the storage. If the destructor -// throws a second exception, call terminate(). If padding_size is 0, the -// destructor pointer must be NULL. If the destructor pointer is NULL, no -// destructor call is to be made. -// -// The intent of this function is to permit an implementation to call this -// function when confronted with an expression of the form delete[] p in -// the source code, provided that the default deallocation function can be -// used. Therefore, the semantics of this function are consistent with -// those required by the standard. The requirement that the deallocation -// function be called even if the destructor throws an exception derives -// from the resolution to DR 353 to the C++ standard, which was adopted in -// April, 2003. -_LIBCXXABI_FUNC_VIS void __cxa_vec_delete(void *array_address, - size_t element_size, - size_t padding_size, - void (*destructor)(void *)) { - __cxa_vec_delete2 ( array_address, element_size, padding_size, - destructor, &::operator delete [] ); -} - -// Same as __cxa_vec_delete, except that the given function is used for -// deallocation instead of the default delete function. If dealloc throws -// an exception, the result is undefined. The dealloc pointer may not be -// NULL. -_LIBCXXABI_FUNC_VIS void -__cxa_vec_delete2(void *array_address, size_t element_size, size_t padding_size, - void (*destructor)(void *), void (*dealloc)(void *)) { - if ( NULL != array_address ) { - char *vec_base = static_cast <char *> (array_address); - char *heap_block = vec_base - padding_size; - st_heap_block2 heap ( dealloc, heap_block ); - - if ( 0 != padding_size && NULL != destructor ) // call the destructors - __cxa_vec_dtor ( array_address, __get_element_count ( vec_base ), - element_size, destructor ); - } -} - - -// Same as __cxa_vec_delete, except that the given function is used for -// deallocation instead of the default delete function. The deallocation -// function takes both the object address and its size. If dealloc throws -// an exception, the result is undefined. The dealloc pointer may not be -// NULL. -_LIBCXXABI_FUNC_VIS void -__cxa_vec_delete3(void *array_address, size_t element_size, size_t padding_size, - void (*destructor)(void *), void (*dealloc)(void *, size_t)) { - if ( NULL != array_address ) { - char *vec_base = static_cast <char *> (array_address); - char *heap_block = vec_base - padding_size; - const size_t element_count = padding_size ? __get_element_count ( vec_base ) : 0; - const size_t heap_block_size = element_size * element_count + padding_size; - st_heap_block3 heap ( dealloc, heap_block, heap_block_size ); - - if ( 0 != padding_size && NULL != destructor ) // call the destructors - __cxa_vec_dtor ( array_address, element_count, element_size, destructor ); - } -} - - -} // extern "C" - -} // abi diff --git a/chromium/buildtools/third_party/libc++abi/trunk/src/cxa_virtual.cpp b/chromium/buildtools/third_party/libc++abi/trunk/src/cxa_virtual.cpp deleted file mode 100644 index f59fa7ee2c6..00000000000 --- a/chromium/buildtools/third_party/libc++abi/trunk/src/cxa_virtual.cpp +++ /dev/null @@ -1,25 +0,0 @@ -//===-------------------------- cxa_virtual.cpp ---------------------------===// -// -// 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. -// -//===----------------------------------------------------------------------===// - -#include "cxxabi.h" -#include "abort_message.h" - -namespace __cxxabiv1 { -extern "C" { -_LIBCXXABI_FUNC_VIS _LIBCXXABI_NORETURN -void __cxa_pure_virtual(void) { - abort_message("Pure virtual function called!"); -} - -_LIBCXXABI_FUNC_VIS _LIBCXXABI_NORETURN -void __cxa_deleted_virtual(void) { - abort_message("Deleted virtual function called!"); -} -} // extern "C" -} // abi diff --git a/chromium/buildtools/third_party/libc++abi/trunk/src/fallback_malloc.cpp b/chromium/buildtools/third_party/libc++abi/trunk/src/fallback_malloc.cpp deleted file mode 100644 index 336ad31b017..00000000000 --- a/chromium/buildtools/third_party/libc++abi/trunk/src/fallback_malloc.cpp +++ /dev/null @@ -1,252 +0,0 @@ -//===------------------------ fallback_malloc.cpp -------------------------===// -// -// 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. -// -//===----------------------------------------------------------------------===// - -#include "fallback_malloc.h" - -#include <__threading_support> - -#include <cstdlib> // for malloc, calloc, free -#include <cstring> // for memset - -// A small, simple heap manager based (loosely) on -// the startup heap manager from FreeBSD, optimized for space. -// -// Manages a fixed-size memory pool, supports malloc and free only. -// No support for realloc. -// -// Allocates chunks in multiples of four bytes, with a four byte header -// for each chunk. The overhead of each chunk is kept low by keeping pointers -// as two byte offsets within the heap, rather than (4 or 8 byte) pointers. - -namespace { - -// When POSIX threads are not available, make the mutex operations a nop -#ifndef _LIBCXXABI_HAS_NO_THREADS -_LIBCPP_SAFE_STATIC -static std::__libcpp_mutex_t heap_mutex = _LIBCPP_MUTEX_INITIALIZER; -#else -static void* heap_mutex = 0; -#endif - -class mutexor { -public: -#ifndef _LIBCXXABI_HAS_NO_THREADS - mutexor(std::__libcpp_mutex_t* m) : mtx_(m) { - std::__libcpp_mutex_lock(mtx_); - } - ~mutexor() { std::__libcpp_mutex_unlock(mtx_); } -#else - mutexor(void*) {} - ~mutexor() {} -#endif -private: - mutexor(const mutexor& rhs); - mutexor& operator=(const mutexor& rhs); -#ifndef _LIBCXXABI_HAS_NO_THREADS - std::__libcpp_mutex_t* mtx_; -#endif -}; - -static const size_t HEAP_SIZE = 512; -char heap[HEAP_SIZE] __attribute__((aligned)); - -typedef unsigned short heap_offset; -typedef unsigned short heap_size; - -struct heap_node { - heap_offset next_node; // offset into heap - heap_size len; // size in units of "sizeof(heap_node)" -}; - -static const heap_node* list_end = - (heap_node*)(&heap[HEAP_SIZE]); // one past the end of the heap -static heap_node* freelist = NULL; - -heap_node* node_from_offset(const heap_offset offset) { - return (heap_node*)(heap + (offset * sizeof(heap_node))); -} - -heap_offset offset_from_node(const heap_node* ptr) { - return static_cast<heap_offset>( - static_cast<size_t>(reinterpret_cast<const char*>(ptr) - heap) / - sizeof(heap_node)); -} - -void init_heap() { - freelist = (heap_node*)heap; - freelist->next_node = offset_from_node(list_end); - freelist->len = HEAP_SIZE / sizeof(heap_node); -} - -// How big a chunk we allocate -size_t alloc_size(size_t len) { - return (len + sizeof(heap_node) - 1) / sizeof(heap_node) + 1; -} - -bool is_fallback_ptr(void* ptr) { - return ptr >= heap && ptr < (heap + HEAP_SIZE); -} - -void* fallback_malloc(size_t len) { - heap_node *p, *prev; - const size_t nelems = alloc_size(len); - mutexor mtx(&heap_mutex); - - if (NULL == freelist) - init_heap(); - - // Walk the free list, looking for a "big enough" chunk - for (p = freelist, prev = 0; p && p != list_end; - prev = p, p = node_from_offset(p->next_node)) { - - if (p->len > nelems) { // chunk is larger, shorten, and return the tail - heap_node* q; - - p->len = static_cast<heap_size>(p->len - nelems); - q = p + p->len; - q->next_node = 0; - q->len = static_cast<heap_size>(nelems); - return (void*)(q + 1); - } - - if (p->len == nelems) { // exact size match - if (prev == 0) - freelist = node_from_offset(p->next_node); - else - prev->next_node = p->next_node; - p->next_node = 0; - return (void*)(p + 1); - } - } - return NULL; // couldn't find a spot big enough -} - -// Return the start of the next block -heap_node* after(struct heap_node* p) { return p + p->len; } - -void fallback_free(void* ptr) { - struct heap_node* cp = ((struct heap_node*)ptr) - 1; // retrieve the chunk - struct heap_node *p, *prev; - - mutexor mtx(&heap_mutex); - -#ifdef DEBUG_FALLBACK_MALLOC - std::cout << "Freeing item at " << offset_from_node(cp) << " of size " - << cp->len << std::endl; -#endif - - for (p = freelist, prev = 0; p && p != list_end; - prev = p, p = node_from_offset(p->next_node)) { -#ifdef DEBUG_FALLBACK_MALLOC - std::cout << " p, cp, after (p), after(cp) " << offset_from_node(p) << ' ' - << offset_from_node(cp) << ' ' << offset_from_node(after(p)) - << ' ' << offset_from_node(after(cp)) << std::endl; -#endif - if (after(p) == cp) { -#ifdef DEBUG_FALLBACK_MALLOC - std::cout << " Appending onto chunk at " << offset_from_node(p) - << std::endl; -#endif - p->len = static_cast<heap_size>( - p->len + cp->len); // make the free heap_node larger - return; - } else if (after(cp) == p) { // there's a free heap_node right after -#ifdef DEBUG_FALLBACK_MALLOC - std::cout << " Appending free chunk at " << offset_from_node(p) - << std::endl; -#endif - cp->len = static_cast<heap_size>(cp->len + p->len); - if (prev == 0) { - freelist = cp; - cp->next_node = p->next_node; - } else - prev->next_node = offset_from_node(cp); - return; - } - } -// Nothing to merge with, add it to the start of the free list -#ifdef DEBUG_FALLBACK_MALLOC - std::cout << " Making new free list entry " << offset_from_node(cp) - << std::endl; -#endif - cp->next_node = offset_from_node(freelist); - freelist = cp; -} - -#ifdef INSTRUMENT_FALLBACK_MALLOC -size_t print_free_list() { - struct heap_node *p, *prev; - heap_size total_free = 0; - if (NULL == freelist) - init_heap(); - - for (p = freelist, prev = 0; p && p != list_end; - prev = p, p = node_from_offset(p->next_node)) { - std::cout << (prev == 0 ? "" : " ") << "Offset: " << offset_from_node(p) - << "\tsize: " << p->len << " Next: " << p->next_node << std::endl; - total_free += p->len; - } - std::cout << "Total Free space: " << total_free << std::endl; - return total_free; -} -#endif -} // end unnamed namespace - -namespace __cxxabiv1 { - -struct __attribute__((aligned)) __aligned_type {}; - -void* __aligned_malloc_with_fallback(size_t size) { -#if defined(_WIN32) - if (void* dest = _aligned_malloc(size, alignof(__aligned_type))) - return dest; -#elif defined(_LIBCPP_HAS_NO_ALIGNED_ALLOCATION) - if (void* dest = std::malloc(size)) - return dest; -#else - if (size == 0) - size = 1; - void* dest; - if (::posix_memalign(&dest, alignof(__aligned_type), size) == 0) - return dest; -#endif - return fallback_malloc(size); -} - -void* __calloc_with_fallback(size_t count, size_t size) { - void* ptr = std::calloc(count, size); - if (NULL != ptr) - return ptr; - // if calloc fails, fall back to emergency stash - ptr = fallback_malloc(size * count); - if (NULL != ptr) - std::memset(ptr, 0, size * count); - return ptr; -} - -void __aligned_free_with_fallback(void* ptr) { - if (is_fallback_ptr(ptr)) - fallback_free(ptr); - else { -#if defined(_WIN32) - ::_aligned_free(ptr); -#else - std::free(ptr); -#endif - } -} - -void __free_with_fallback(void* ptr) { - if (is_fallback_ptr(ptr)) - fallback_free(ptr); - else - std::free(ptr); -} - -} // namespace __cxxabiv1 diff --git a/chromium/buildtools/third_party/libc++abi/trunk/src/fallback_malloc.h b/chromium/buildtools/third_party/libc++abi/trunk/src/fallback_malloc.h deleted file mode 100644 index d6f471483a2..00000000000 --- a/chromium/buildtools/third_party/libc++abi/trunk/src/fallback_malloc.h +++ /dev/null @@ -1,29 +0,0 @@ -//===------------------------- fallback_malloc.h --------------------------===// -// -// 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 _FALLBACK_MALLOC_H -#define _FALLBACK_MALLOC_H - -#include "__cxxabi_config.h" -#include <cstddef> // for size_t - -namespace __cxxabiv1 { - -// Allocate some memory from _somewhere_ -_LIBCXXABI_HIDDEN void * __aligned_malloc_with_fallback(size_t size); - -// Allocate and zero-initialize memory from _somewhere_ -_LIBCXXABI_HIDDEN void * __calloc_with_fallback(size_t count, size_t size); - -_LIBCXXABI_HIDDEN void __aligned_free_with_fallback(void *ptr); -_LIBCXXABI_HIDDEN void __free_with_fallback(void *ptr); - -} // namespace __cxxabiv1 - -#endif diff --git a/chromium/buildtools/third_party/libc++abi/trunk/src/include/refstring.h b/chromium/buildtools/third_party/libc++abi/trunk/src/include/refstring.h deleted file mode 100644 index bc131aeb5ae..00000000000 --- a/chromium/buildtools/third_party/libc++abi/trunk/src/include/refstring.h +++ /dev/null @@ -1,131 +0,0 @@ -//===------------------------ __refstring ---------------------------------===// -// -// 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. -// -//===----------------------------------------------------------------------===// - -// FIXME: This file is copied from libcxx/src/include/refstring.h. Instead of -// duplicating the file in libc++abi we should require that the libc++ sources -// are available when building libc++abi. - -#ifndef _LIBCPPABI_REFSTRING_H -#define _LIBCPPABI_REFSTRING_H - -#include <__config> -#include <stdexcept> -#include <cstddef> -#include <cstring> -#ifdef __APPLE__ -#include <dlfcn.h> -#include <mach-o/dyld.h> -#endif - -_LIBCPP_BEGIN_NAMESPACE_STD - -namespace __refstring_imp { namespace { -typedef int count_t; - -struct _Rep_base { - std::size_t len; - std::size_t cap; - count_t count; -}; - -inline _Rep_base* rep_from_data(const char *data_) noexcept { - char *data = const_cast<char *>(data_); - return reinterpret_cast<_Rep_base *>(data - sizeof(_Rep_base)); -} - -inline char * data_from_rep(_Rep_base *rep) noexcept { - char *data = reinterpret_cast<char *>(rep); - return data + sizeof(*rep); -} - -#if defined(__APPLE__) -inline -const char* compute_gcc_empty_string_storage() _NOEXCEPT -{ - void* handle = dlopen("/usr/lib/libstdc++.6.dylib", RTLD_NOLOAD); - if (handle == nullptr) - return nullptr; - void* sym = dlsym(handle, "_ZNSs4_Rep20_S_empty_rep_storageE"); - if (sym == nullptr) - return nullptr; - return data_from_rep(reinterpret_cast<_Rep_base *>(sym)); -} - -inline -const char* -get_gcc_empty_string_storage() _NOEXCEPT -{ - static const char* p = compute_gcc_empty_string_storage(); - return p; -} -#endif - -}} // namespace __refstring_imp - -using namespace __refstring_imp; - -inline -__libcpp_refstring::__libcpp_refstring(const char* msg) { - std::size_t len = strlen(msg); - _Rep_base* rep = static_cast<_Rep_base *>(::operator new(sizeof(*rep) + len + 1)); - rep->len = len; - rep->cap = len; - rep->count = 0; - char *data = data_from_rep(rep); - std::memcpy(data, msg, len + 1); - __imp_ = data; -} - -inline -__libcpp_refstring::__libcpp_refstring(const __libcpp_refstring &s) _NOEXCEPT - : __imp_(s.__imp_) -{ - if (__uses_refcount()) - __sync_add_and_fetch(&rep_from_data(__imp_)->count, 1); -} - -inline -__libcpp_refstring& __libcpp_refstring::operator=(__libcpp_refstring const& s) _NOEXCEPT { - bool adjust_old_count = __uses_refcount(); - struct _Rep_base *old_rep = rep_from_data(__imp_); - __imp_ = s.__imp_; - if (__uses_refcount()) - __sync_add_and_fetch(&rep_from_data(__imp_)->count, 1); - if (adjust_old_count) - { - if (__sync_add_and_fetch(&old_rep->count, count_t(-1)) < 0) - { - ::operator delete(old_rep); - } - } - return *this; -} - -inline -__libcpp_refstring::~__libcpp_refstring() { - if (__uses_refcount()) { - _Rep_base* rep = rep_from_data(__imp_); - if (__sync_add_and_fetch(&rep->count, count_t(-1)) < 0) { - ::operator delete(rep); - } - } -} - -inline -bool __libcpp_refstring::__uses_refcount() const { -#ifdef __APPLE__ - return __imp_ != get_gcc_empty_string_storage(); -#else - return true; -#endif -} - -_LIBCPP_END_NAMESPACE_STD - -#endif //_LIBCPPABI_REFSTRING_H diff --git a/chromium/buildtools/third_party/libc++abi/trunk/src/private_typeinfo.cpp b/chromium/buildtools/third_party/libc++abi/trunk/src/private_typeinfo.cpp deleted file mode 100644 index 08e2b45fa86..00000000000 --- a/chromium/buildtools/third_party/libc++abi/trunk/src/private_typeinfo.cpp +++ /dev/null @@ -1,1294 +0,0 @@ -//===----------------------- private_typeinfo.cpp -------------------------===// -// -// 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. -// -//===----------------------------------------------------------------------===// - -#include "private_typeinfo.h" - -// The flag _LIBCXX_DYNAMIC_FALLBACK is used to make dynamic_cast more -// forgiving when type_info's mistakenly have hidden visibility and thus -// multiple type_infos can exist for a single type. -// -// When _LIBCXX_DYNAMIC_FALLBACK is defined, and only in the case where -// there is a detected inconsistency in the type_info hierarchy during a -// dynamic_cast, then the equality operation will fall back to using strcmp -// on type_info names to determine type_info equality. -// -// This change happens *only* under dynamic_cast, and only when -// dynamic_cast is faced with the choice: abort, or possibly give back the -// wrong answer. If when the dynamic_cast is done with this fallback -// algorithm and an inconsistency is still detected, dynamic_cast will call -// abort with an appropriate message. -// -// The current implementation of _LIBCXX_DYNAMIC_FALLBACK requires a -// printf-like function called syslog: -// -// void syslog(int facility_priority, const char* format, ...); -// -// If you want this functionality but your platform doesn't have syslog, -// just implement it in terms of fprintf(stderr, ...). -// -// _LIBCXX_DYNAMIC_FALLBACK is currently off by default. - - -#include <string.h> - - -#ifdef _LIBCXX_DYNAMIC_FALLBACK -#include "abort_message.h" -#include <sys/syslog.h> -#endif - -// On Windows, typeids are different between DLLs and EXEs, so comparing -// type_info* will work for typeids from the same compiled file but fail -// for typeids from a DLL and an executable. Among other things, exceptions -// are not caught by handlers since can_catch() returns false. -// -// Defining _LIBCXX_DYNAMIC_FALLBACK does not help since can_catch() calls -// is_equal() with use_strcmp=false so the string names are not compared. - -#ifdef _WIN32 -#include <string.h> -#endif - -static inline -bool -is_equal(const std::type_info* x, const std::type_info* y, bool use_strcmp) -{ -#ifndef _WIN32 - if (!use_strcmp) - return x == y; - return strcmp(x->name(), y->name()) == 0; -#else - return (x == y) || (strcmp(x->name(), y->name()) == 0); -#endif -} - -namespace __cxxabiv1 -{ - -// __shim_type_info - -__shim_type_info::~__shim_type_info() -{ -} - -void __shim_type_info::noop1() const {} -void __shim_type_info::noop2() const {} - -// __fundamental_type_info - -// This miraculously (compiler magic) emits the type_info's for: -// 1. all of the fundamental types -// 2. pointers to all of the fundamental types -// 3. pointers to all of the const fundamental types -__fundamental_type_info::~__fundamental_type_info() -{ -} - -// __array_type_info - -__array_type_info::~__array_type_info() -{ -} - -// __function_type_info - -__function_type_info::~__function_type_info() -{ -} - -// __enum_type_info - -__enum_type_info::~__enum_type_info() -{ -} - -// __class_type_info - -__class_type_info::~__class_type_info() -{ -} - -// __si_class_type_info - -__si_class_type_info::~__si_class_type_info() -{ -} - -// __vmi_class_type_info - -__vmi_class_type_info::~__vmi_class_type_info() -{ -} - -// __pbase_type_info - -__pbase_type_info::~__pbase_type_info() -{ -} - -// __pointer_type_info - -__pointer_type_info::~__pointer_type_info() -{ -} - -// __pointer_to_member_type_info - -__pointer_to_member_type_info::~__pointer_to_member_type_info() -{ -} - -// can_catch - -// A handler is a match for an exception object of type E if -// 1. The handler is of type cv T or cv T& and E and T are the same type -// (ignoring the top-level cv-qualifiers), or -// 2. the handler is of type cv T or cv T& and T is an unambiguous public -// base class of E, or -// 3. the handler is of type cv1 T* cv2 and E is a pointer type that can be -// converted to the type of the handler by either or both of -// A. a standard pointer conversion (4.10) not involving conversions to -// pointers to private or protected or ambiguous classes -// B. a qualification conversion -// 4. the handler is a pointer or pointer to member type and E is -// std::nullptr_t. - -// adjustedPtr: -// -// catch (A& a) : adjustedPtr == &a -// catch (A* a) : adjustedPtr == a -// catch (A** a) : adjustedPtr == a -// -// catch (D2& d2) : adjustedPtr == &d2 (d2 is base class of thrown object) -// catch (D2* d2) : adjustedPtr == d2 -// catch (D2*& d2) : adjustedPtr == d2 -// -// catch (...) : adjustedPtr == & of the exception -// -// If the thrown type is nullptr_t and the caught type is a pointer to -// member type, adjustedPtr points to a statically-allocated null pointer -// representation of that type. - -// Handles bullet 1 -bool -__fundamental_type_info::can_catch(const __shim_type_info* thrown_type, - void*&) const -{ - return is_equal(this, thrown_type, false); -} - -bool -__array_type_info::can_catch(const __shim_type_info*, void*&) const -{ - // We can get here if someone tries to catch an array by reference. - // However if someone tries to throw an array, it immediately gets - // converted to a pointer, which will not convert back to an array - // at the catch clause. So this can never catch anything. - return false; -} - -bool -__function_type_info::can_catch(const __shim_type_info*, void*&) const -{ - // We can get here if someone tries to catch a function by reference. - // However if someone tries to throw a function, it immediately gets - // converted to a pointer, which will not convert back to a function - // at the catch clause. So this can never catch anything. - return false; -} - -// Handles bullet 1 -bool -__enum_type_info::can_catch(const __shim_type_info* thrown_type, - void*&) const -{ - return is_equal(this, thrown_type, false); -} - -#ifdef __clang__ -#pragma clang diagnostic push -#pragma clang diagnostic ignored "-Wmissing-field-initializers" -#endif - -// Handles bullets 1 and 2 -bool -__class_type_info::can_catch(const __shim_type_info* thrown_type, - void*& adjustedPtr) const -{ - // bullet 1 - if (is_equal(this, thrown_type, false)) - return true; - const __class_type_info* thrown_class_type = - dynamic_cast<const __class_type_info*>(thrown_type); - if (thrown_class_type == 0) - return false; - // bullet 2 - __dynamic_cast_info info = {thrown_class_type, 0, this, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,}; - info.number_of_dst_type = 1; - thrown_class_type->has_unambiguous_public_base(&info, adjustedPtr, public_path); - if (info.path_dst_ptr_to_static_ptr == public_path) - { - adjustedPtr = const_cast<void*>(info.dst_ptr_leading_to_static_ptr); - return true; - } - return false; -} - -#ifdef __clang__ -#pragma clang diagnostic pop -#endif - -void -__class_type_info::process_found_base_class(__dynamic_cast_info* info, - void* adjustedPtr, - int path_below) const -{ - if (info->dst_ptr_leading_to_static_ptr == 0) - { - // First time here - info->dst_ptr_leading_to_static_ptr = adjustedPtr; - info->path_dst_ptr_to_static_ptr = path_below; - info->number_to_static_ptr = 1; - } - else if (info->dst_ptr_leading_to_static_ptr == adjustedPtr) - { - // We've been here before. Update path to "most public" - if (info->path_dst_ptr_to_static_ptr == not_public_path) - info->path_dst_ptr_to_static_ptr = path_below; - } - else - { - // We've detected an ambiguous cast from (thrown_class_type, adjustedPtr) - // to a static_type - info->number_to_static_ptr += 1; - info->path_dst_ptr_to_static_ptr = not_public_path; - info->search_done = true; - } -} - -void -__class_type_info::has_unambiguous_public_base(__dynamic_cast_info* info, - void* adjustedPtr, - int path_below) const -{ - if (is_equal(this, info->static_type, false)) - process_found_base_class(info, adjustedPtr, path_below); -} - -void -__si_class_type_info::has_unambiguous_public_base(__dynamic_cast_info* info, - void* adjustedPtr, - int path_below) const -{ - if (is_equal(this, info->static_type, false)) - process_found_base_class(info, adjustedPtr, path_below); - else - __base_type->has_unambiguous_public_base(info, adjustedPtr, path_below); -} - -void -__base_class_type_info::has_unambiguous_public_base(__dynamic_cast_info* info, - void* adjustedPtr, - int path_below) const -{ - ptrdiff_t offset_to_base = 0; - if (adjustedPtr != nullptr) - { - offset_to_base = __offset_flags >> __offset_shift; - if (__offset_flags & __virtual_mask) - { - const char* vtable = *static_cast<const char*const*>(adjustedPtr); - offset_to_base = *reinterpret_cast<const ptrdiff_t*>(vtable + offset_to_base); - } - } - __base_type->has_unambiguous_public_base( - info, - static_cast<char*>(adjustedPtr) + offset_to_base, - (__offset_flags & __public_mask) ? path_below : not_public_path); -} - -void -__vmi_class_type_info::has_unambiguous_public_base(__dynamic_cast_info* info, - void* adjustedPtr, - int path_below) const -{ - if (is_equal(this, info->static_type, false)) - process_found_base_class(info, adjustedPtr, path_below); - else - { - typedef const __base_class_type_info* Iter; - const Iter e = __base_info + __base_count; - Iter p = __base_info; - p->has_unambiguous_public_base(info, adjustedPtr, path_below); - if (++p < e) - { - do - { - p->has_unambiguous_public_base(info, adjustedPtr, path_below); - if (info->search_done) - break; - } while (++p < e); - } - } -} - -// Handles bullet 1 for both pointers and member pointers -bool -__pbase_type_info::can_catch(const __shim_type_info* thrown_type, - void*&) const -{ - bool use_strcmp = this->__flags & (__incomplete_class_mask | - __incomplete_mask); - if (!use_strcmp) { - const __pbase_type_info* thrown_pbase = dynamic_cast<const __pbase_type_info*>( - thrown_type); - if (!thrown_pbase) return false; - use_strcmp = thrown_pbase->__flags & (__incomplete_class_mask | - __incomplete_mask); - } - return is_equal(this, thrown_type, use_strcmp); -} - -#ifdef __clang__ -#pragma clang diagnostic push -#pragma clang diagnostic ignored "-Wmissing-field-initializers" -#endif - -// Handles bullets 1, 3 and 4 -// NOTE: It might not be safe to adjust the pointer if it is not not a pointer -// type. Only adjust the pointer after we know it is safe to do so. -bool -__pointer_type_info::can_catch(const __shim_type_info* thrown_type, - void*& adjustedPtr) const -{ - // bullet 4 - if (is_equal(thrown_type, &typeid(std::nullptr_t), false)) { - adjustedPtr = nullptr; - return true; - } - - // bullet 1 - if (__pbase_type_info::can_catch(thrown_type, adjustedPtr)) { - if (adjustedPtr != NULL) - adjustedPtr = *static_cast<void**>(adjustedPtr); - return true; - } - // bullet 3 - const __pointer_type_info* thrown_pointer_type = - dynamic_cast<const __pointer_type_info*>(thrown_type); - if (thrown_pointer_type == 0) - return false; - // Do the dereference adjustment - if (adjustedPtr != NULL) - adjustedPtr = *static_cast<void**>(adjustedPtr); - // bullet 3B and 3C - if (thrown_pointer_type->__flags & ~__flags & __no_remove_flags_mask) - return false; - if (__flags & ~thrown_pointer_type->__flags & __no_add_flags_mask) - return false; - if (is_equal(__pointee, thrown_pointer_type->__pointee, false)) - return true; - // bullet 3A - if (is_equal(__pointee, &typeid(void), false)) { - // pointers to functions cannot be converted to void*. - // pointers to member functions are not handled here. - const __function_type_info* thrown_function = - dynamic_cast<const __function_type_info*>(thrown_pointer_type->__pointee); - return (thrown_function == nullptr); - } - // Handle pointer to pointer - const __pointer_type_info* nested_pointer_type = - dynamic_cast<const __pointer_type_info*>(__pointee); - if (nested_pointer_type) { - if (~__flags & __const_mask) return false; - return nested_pointer_type->can_catch_nested(thrown_pointer_type->__pointee); - } - - // Handle pointer to pointer to member - const __pointer_to_member_type_info* member_ptr_type = - dynamic_cast<const __pointer_to_member_type_info*>(__pointee); - if (member_ptr_type) { - if (~__flags & __const_mask) return false; - return member_ptr_type->can_catch_nested(thrown_pointer_type->__pointee); - } - - // Handle pointer to class type - const __class_type_info* catch_class_type = - dynamic_cast<const __class_type_info*>(__pointee); - if (catch_class_type == 0) - return false; - const __class_type_info* thrown_class_type = - dynamic_cast<const __class_type_info*>(thrown_pointer_type->__pointee); - if (thrown_class_type == 0) - return false; - __dynamic_cast_info info = {thrown_class_type, 0, catch_class_type, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,}; - info.number_of_dst_type = 1; - thrown_class_type->has_unambiguous_public_base(&info, adjustedPtr, public_path); - if (info.path_dst_ptr_to_static_ptr == public_path) - { - if (adjustedPtr != NULL) - adjustedPtr = const_cast<void*>(info.dst_ptr_leading_to_static_ptr); - return true; - } - return false; -} - -bool __pointer_type_info::can_catch_nested( - const __shim_type_info* thrown_type) const -{ - const __pointer_type_info* thrown_pointer_type = - dynamic_cast<const __pointer_type_info*>(thrown_type); - if (thrown_pointer_type == 0) - return false; - // bullet 3B - if (thrown_pointer_type->__flags & ~__flags) - return false; - if (is_equal(__pointee, thrown_pointer_type->__pointee, false)) - return true; - // If the pointed to types differ then the catch type must be const - // qualified. - if (~__flags & __const_mask) - return false; - - // Handle pointer to pointer - const __pointer_type_info* nested_pointer_type = - dynamic_cast<const __pointer_type_info*>(__pointee); - if (nested_pointer_type) { - return nested_pointer_type->can_catch_nested( - thrown_pointer_type->__pointee); - } - - // Handle pointer to pointer to member - const __pointer_to_member_type_info* member_ptr_type = - dynamic_cast<const __pointer_to_member_type_info*>(__pointee); - if (member_ptr_type) { - return member_ptr_type->can_catch_nested(thrown_pointer_type->__pointee); - } - - return false; -} - -bool __pointer_to_member_type_info::can_catch( - const __shim_type_info* thrown_type, void*& adjustedPtr) const { - // bullet 4 - if (is_equal(thrown_type, &typeid(std::nullptr_t), false)) { - // We assume that the pointer to member representation is the same for - // all pointers to data members and for all pointers to member functions. - struct X {}; - if (dynamic_cast<const __function_type_info*>(__pointee)) { - static int (X::*const null_ptr_rep)() = nullptr; - adjustedPtr = const_cast<int (X::**)()>(&null_ptr_rep); - } else { - static int X::*const null_ptr_rep = nullptr; - adjustedPtr = const_cast<int X::**>(&null_ptr_rep); - } - return true; - } - - // bullet 1 - if (__pbase_type_info::can_catch(thrown_type, adjustedPtr)) - return true; - - const __pointer_to_member_type_info* thrown_pointer_type = - dynamic_cast<const __pointer_to_member_type_info*>(thrown_type); - if (thrown_pointer_type == 0) - return false; - if (thrown_pointer_type->__flags & ~__flags & __no_remove_flags_mask) - return false; - if (__flags & ~thrown_pointer_type->__flags & __no_add_flags_mask) - return false; - if (!is_equal(__pointee, thrown_pointer_type->__pointee, false)) - return false; - if (is_equal(__context, thrown_pointer_type->__context, false)) - return true; - - // [except.handle] does not allow the pointer-to-member conversions mentioned - // in [mem.conv] to take place. For this reason we don't check Derived->Base - // for Derived->Base conversions. - - return false; -} - -bool __pointer_to_member_type_info::can_catch_nested( - const __shim_type_info* thrown_type) const -{ - const __pointer_to_member_type_info* thrown_member_ptr_type = - dynamic_cast<const __pointer_to_member_type_info*>(thrown_type); - if (thrown_member_ptr_type == 0) - return false; - if (~__flags & thrown_member_ptr_type->__flags) - return false; - if (!is_equal(__pointee, thrown_member_ptr_type->__pointee, false)) - return false; - if (!is_equal(__context, thrown_member_ptr_type->__context, false)) - return false; - return true; -} - -#ifdef __clang__ -#pragma clang diagnostic pop -#endif - -#ifdef __clang__ -#pragma clang diagnostic push -#pragma clang diagnostic ignored "-Wmissing-field-initializers" -#endif - -// __dynamic_cast - -// static_ptr: pointer to an object of type static_type; nonnull, and since the -// object is polymorphic, *(void**)static_ptr is a virtual table pointer. -// static_ptr is &v in the expression dynamic_cast<T>(v). -// static_type: static type of the object pointed to by static_ptr. -// dst_type: destination type of the cast (the "T" in "dynamic_cast<T>(v)"). -// src2dst_offset: a static hint about the location of the -// source subobject with respect to the complete object; -// special negative values are: -// -1: no hint -// -2: static_type is not a public base of dst_type -// -3: static_type is a multiple public base type but never a -// virtual base type -// otherwise, the static_type type is a unique public nonvirtual -// base type of dst_type at offset src2dst_offset from the -// origin of dst_type. -// -// (dynamic_ptr, dynamic_type) are the run time type of the complete object -// referred to by static_ptr and a pointer to it. These can be found from -// static_ptr for polymorphic types. -// static_type is guaranteed to be a polymorphic type. -// -// (dynamic_ptr, dynamic_type) is the root of a DAG that grows upward. Each -// node of the tree represents a base class/object of its parent (or parents) below. -// Each node is uniquely represented by a pointer to the object, and a pointer -// to a type_info - its type. Different nodes may have the same pointer and -// different nodes may have the same type. But only one node has a specific -// (pointer-value, type) pair. In C++ two objects of the same type can not -// share the same address. -// -// There are two flavors of nodes which have the type dst_type: -// 1. Those that are derived from (below) (static_ptr, static_type). -// 2. Those that are not derived from (below) (static_ptr, static_type). -// -// Invariants of the DAG: -// -// There is at least one path from the root (dynamic_ptr, dynamic_type) to -// the node (static_ptr, static_type). This path may or may not be public. -// There may be more than one such path (some public some not). Such a path may -// or may not go through a node having type dst_type. -// -// No node of type T appears above a node of the same type. That means that -// there is only one node with dynamic_type. And if dynamic_type == dst_type, -// then there is only one dst_type in the DAG. -// -// No node of type dst_type appears above a node of type static_type. Such -// DAG's are possible in C++, but the compiler computes those dynamic_casts at -// compile time, and only calls __dynamic_cast when dst_type lies below -// static_type in the DAG. -// -// dst_type != static_type: The compiler computes the dynamic_cast in this case too. -// dynamic_type != static_type: The compiler computes the dynamic_cast in this case too. -// -// Returns: -// -// If there is exactly one dst_type of flavor 1, and -// If there is a public path from that dst_type to (static_ptr, static_type), or -// If there are 0 dst_types of flavor 2, and there is a public path from -// (dynamic_ptr, dynamic_type) to (static_ptr, static_type) and a public -// path from (dynamic_ptr, dynamic_type) to the one dst_type, then return -// a pointer to that dst_type. -// Else if there are 0 dst_types of flavor 1 and exactly 1 dst_type of flavor 2, and -// if there is a public path from (dynamic_ptr, dynamic_type) to -// (static_ptr, static_type) and a public path from (dynamic_ptr, dynamic_type) -// to the one dst_type, then return a pointer to that one dst_type. -// Else return nullptr. -// -// If dynamic_type == dst_type, then the above algorithm collapses to the -// following cheaper algorithm: -// -// If there is a public path from (dynamic_ptr, dynamic_type) to -// (static_ptr, static_type), then return dynamic_ptr. -// Else return nullptr. - -extern "C" _LIBCXXABI_FUNC_VIS void * -__dynamic_cast(const void *static_ptr, const __class_type_info *static_type, - const __class_type_info *dst_type, - std::ptrdiff_t src2dst_offset) { - // Possible future optimization: Take advantage of src2dst_offset - // Currently clang always sets src2dst_offset to -1 (no hint). - - // Get (dynamic_ptr, dynamic_type) from static_ptr - void **vtable = *static_cast<void ** const *>(static_ptr); - ptrdiff_t offset_to_derived = reinterpret_cast<ptrdiff_t>(vtable[-2]); - const void* dynamic_ptr = static_cast<const char*>(static_ptr) + offset_to_derived; - const __class_type_info* dynamic_type = static_cast<const __class_type_info*>(vtable[-1]); - - // Initialize answer to nullptr. This will be changed from the search - // results if a non-null answer is found. Regardless, this is what will - // be returned. - const void* dst_ptr = 0; - // Initialize info struct for this search. - __dynamic_cast_info info = {dst_type, static_ptr, static_type, src2dst_offset, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,}; - - // Find out if we can use a giant short cut in the search - if (is_equal(dynamic_type, dst_type, false)) - { - // Using giant short cut. Add that information to info. - info.number_of_dst_type = 1; - // Do the search - dynamic_type->search_above_dst(&info, dynamic_ptr, dynamic_ptr, public_path, false); -#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) - { - // We get here only if there is some kind of visibility problem - // in client code. - syslog(LOG_ERR, "dynamic_cast error 1: Both of the following type_info's " - "should have public visibility. At least one of them is hidden. %s" - ", %s.\n", static_type->name(), dynamic_type->name()); - // Redo the search comparing type_info's using strcmp - info = {dst_type, static_ptr, static_type, src2dst_offset, 0}; - info.number_of_dst_type = 1; - dynamic_type->search_above_dst(&info, dynamic_ptr, dynamic_ptr, public_path, true); - } -#endif // _LIBCXX_DYNAMIC_FALLBACK - // Query the search. - if (info.path_dst_ptr_to_static_ptr == public_path) - dst_ptr = dynamic_ptr; - } - else - { - // Not using giant short cut. Do the search - dynamic_type->search_below_dst(&info, dynamic_ptr, public_path, false); - #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 && - info.path_dynamic_ptr_to_static_ptr == unknown) - { - syslog(LOG_ERR, "dynamic_cast error 2: One or more of the following type_info's " - " has hidden visibility. They should all have public visibility. " - " %s, %s, %s.\n", static_type->name(), dynamic_type->name(), - dst_type->name()); - // Redo the search comparing type_info's using strcmp - info = {dst_type, static_ptr, static_type, src2dst_offset, 0}; - dynamic_type->search_below_dst(&info, dynamic_ptr, public_path, true); - } -#endif // _LIBCXX_DYNAMIC_FALLBACK - // Query the search. - switch (info.number_to_static_ptr) - { - case 0: - if (info.number_to_dst_ptr == 1 && - info.path_dynamic_ptr_to_static_ptr == public_path && - info.path_dynamic_ptr_to_dst_ptr == public_path) - dst_ptr = info.dst_ptr_not_leading_to_static_ptr; - break; - case 1: - if (info.path_dst_ptr_to_static_ptr == public_path || - ( - info.number_to_dst_ptr == 0 && - info.path_dynamic_ptr_to_static_ptr == public_path && - info.path_dynamic_ptr_to_dst_ptr == public_path - ) - ) - dst_ptr = info.dst_ptr_leading_to_static_ptr; - break; - } - } - return const_cast<void*>(dst_ptr); -} - -#ifdef __clang__ -#pragma clang diagnostic pop -#endif - -// Call this function when you hit a static_type which is a base (above) a dst_type. -// Let caller know you hit a static_type. But only start recording details if -// this is (static_ptr, static_type) -- the node we are casting from. -// If this is (static_ptr, static_type) -// Record the path (public or not) from the dst_type to here. There may be -// multiple paths from the same dst_type to here, record the "most public" one. -// Record the dst_ptr as pointing to (static_ptr, static_type). -// If more than one (dst_ptr, dst_type) points to (static_ptr, static_type), -// then mark this dyanmic_cast as ambiguous and stop the search. -void -__class_type_info::process_static_type_above_dst(__dynamic_cast_info* info, - const void* dst_ptr, - const void* current_ptr, - int path_below) const -{ - // Record that we found a static_type - info->found_any_static_type = true; - if (current_ptr == info->static_ptr) - { - // Record that we found (static_ptr, static_type) - info->found_our_static_ptr = true; - if (info->dst_ptr_leading_to_static_ptr == 0) - { - // First time here - info->dst_ptr_leading_to_static_ptr = dst_ptr; - info->path_dst_ptr_to_static_ptr = path_below; - info->number_to_static_ptr = 1; - // If there is only one dst_type in the entire tree and the path from - // there to here is public then we are done! - if (info->number_of_dst_type == 1 && info->path_dst_ptr_to_static_ptr == public_path) - info->search_done = true; - } - else if (info->dst_ptr_leading_to_static_ptr == dst_ptr) - { - // We've been here before. Update path to "most public" - if (info->path_dst_ptr_to_static_ptr == not_public_path) - info->path_dst_ptr_to_static_ptr = path_below; - // If there is only one dst_type in the entire tree and the path from - // there to here is public then we are done! - if (info->number_of_dst_type == 1 && info->path_dst_ptr_to_static_ptr == public_path) - info->search_done = true; - } - else - { - // We've detected an ambiguous cast from (static_ptr, static_type) - // to a dst_type - info->number_to_static_ptr += 1; - info->search_done = true; - } - } -} - -// Call this function when you hit a static_type which is not a base (above) a dst_type. -// If this is (static_ptr, static_type) -// Record the path (public or not) from (dynamic_ptr, dynamic_type) to here. There may be -// multiple paths from (dynamic_ptr, dynamic_type) to here, record the "most public" one. -void -__class_type_info::process_static_type_below_dst(__dynamic_cast_info* info, - const void* current_ptr, - int path_below) const -{ - if (current_ptr == info->static_ptr) - { - // Record the most public path from (dynamic_ptr, dynamic_type) to - // (static_ptr, static_type) - if (info->path_dynamic_ptr_to_static_ptr != public_path) - info->path_dynamic_ptr_to_static_ptr = path_below; - } -} - -// Call this function when searching below a dst_type node. This function searches -// for a path to (static_ptr, static_type) and for paths to one or more dst_type nodes. -// If it finds a static_type node, there is no need to further search base classes -// above. -// If it finds a dst_type node it should search base classes using search_above_dst -// to find out if this dst_type points to (static_ptr, static_type) or not. -// Either way, the dst_type is recorded as one of two "flavors": one that does -// or does not point to (static_ptr, static_type). -// If this is neither a static_type nor a dst_type node, continue searching -// base classes above. -// All the hoopla surrounding the search code is doing nothing but looking for -// excuses to stop the search prematurely (break out of the for-loop). That is, -// the algorithm below is simply an optimization of this: -// void -// __vmi_class_type_info::search_below_dst(__dynamic_cast_info* info, -// const void* current_ptr, -// int path_below) const -// { -// typedef const __base_class_type_info* Iter; -// if (this == info->static_type) -// process_static_type_below_dst(info, current_ptr, path_below); -// else if (this == info->dst_type) -// { -// // Record the most public access path that got us here -// if (info->path_dynamic_ptr_to_dst_ptr != public_path) -// info->path_dynamic_ptr_to_dst_ptr = path_below; -// bool does_dst_type_point_to_our_static_type = false; -// for (Iter p = __base_info, e= __base_info + __base_count; p < e; ++p) -// { -// p->search_above_dst(info, current_ptr, current_ptr, public_path); -// if (info->found_our_static_ptr) -// does_dst_type_point_to_our_static_type = true; -// // break out early here if you can detect it doesn't matter if you do -// } -// if (!does_dst_type_point_to_our_static_type) -// { -// // We found a dst_type that doesn't point to (static_ptr, static_type) -// // So record the address of this dst_ptr and increment the -// // count of the number of such dst_types found in the tree. -// info->dst_ptr_not_leading_to_static_ptr = current_ptr; -// info->number_to_dst_ptr += 1; -// } -// } -// else -// { -// // This is not a static_type and not a dst_type. -// for (Iter p = __base_info, e = __base_info + __base_count; p < e; ++p) -// { -// p->search_below_dst(info, current_ptr, public_path); -// // break out early here if you can detect it doesn't matter if you do -// } -// } -// } -void -__vmi_class_type_info::search_below_dst(__dynamic_cast_info* info, - const void* current_ptr, - int path_below, - bool use_strcmp) const -{ - typedef const __base_class_type_info* Iter; - if (is_equal(this, info->static_type, use_strcmp)) - process_static_type_below_dst(info, current_ptr, path_below); - else if (is_equal(this, info->dst_type, use_strcmp)) - { - // We've been here before if we've recorded current_ptr in one of these - // two places: - if (current_ptr == info->dst_ptr_leading_to_static_ptr || - current_ptr == info->dst_ptr_not_leading_to_static_ptr) - { - // We've seen this node before, and therefore have already searched - // its base classes above. - // Update path to here that is "most public". - if (path_below == public_path) - info->path_dynamic_ptr_to_dst_ptr = public_path; - } - else // We have haven't been here before - { - // Record the access path that got us here - // If there is more than one dst_type this path doesn't matter. - info->path_dynamic_ptr_to_dst_ptr = path_below; - // Only search above here if dst_type derives from static_type, or - // if it is unknown if dst_type derives from static_type. - if (info->is_dst_type_derived_from_static_type != no) - { - // Set up flags to record results from all base classes - bool is_dst_type_derived_from_static_type = false; - bool does_dst_type_point_to_our_static_type = false; - // We've found a dst_type with a potentially public path to here. - // We have to assume the path is public because it may become - // public later (if we get back to here with a public path). - // We can stop looking above if: - // 1. We've found a public path to (static_ptr, static_type). - // 2. We've found an ambiguous cast from (static_ptr, static_type) to a dst_type. - // This is detected at the (static_ptr, static_type). - // 3. We can prove that there is no public path to (static_ptr, static_type) - // above here. - const Iter e = __base_info + __base_count; - for (Iter p = __base_info; p < e; ++p) - { - // Zero out found flags - info->found_our_static_ptr = false; - info->found_any_static_type = false; - p->search_above_dst(info, current_ptr, current_ptr, public_path, use_strcmp); - if (info->search_done) - break; - if (info->found_any_static_type) - { - is_dst_type_derived_from_static_type = true; - if (info->found_our_static_ptr) - { - does_dst_type_point_to_our_static_type = true; - // If we found what we're looking for, stop looking above. - if (info->path_dst_ptr_to_static_ptr == public_path) - break; - // We found a private path to (static_ptr, static_type) - // If there is no diamond then there is only one path - // to (static_ptr, static_type) and we just found it. - if (!(__flags & __diamond_shaped_mask)) - break; - } - else - { - // If we found a static_type that isn't the one we're looking - // for, and if there are no repeated types above here, - // then stop looking. - if (!(__flags & __non_diamond_repeat_mask)) - break; - } - } - } - if (!does_dst_type_point_to_our_static_type) - { - // We found a dst_type that doesn't point to (static_ptr, static_type) - // So record the address of this dst_ptr and increment the - // count of the number of such dst_types found in the tree. - info->dst_ptr_not_leading_to_static_ptr = current_ptr; - info->number_to_dst_ptr += 1; - // If there exists another dst with a private path to - // (static_ptr, static_type), then the cast from - // (dynamic_ptr, dynamic_type) to dst_type is now ambiguous, - // so stop search. - if (info->number_to_static_ptr == 1 && - info->path_dst_ptr_to_static_ptr == not_public_path) - info->search_done = true; - } - // If we found no static_type,s then dst_type doesn't derive - // from static_type, else it does. Record this result so that - // next time we hit a dst_type we will know not to search above - // it if it doesn't derive from static_type. - if (is_dst_type_derived_from_static_type) - info->is_dst_type_derived_from_static_type = yes; - else - info->is_dst_type_derived_from_static_type = no; - } - } - } - else - { - // This is not a static_type and not a dst_type. - const Iter e = __base_info + __base_count; - Iter p = __base_info; - p->search_below_dst(info, current_ptr, path_below, use_strcmp); - if (++p < e) - { - if ((__flags & __diamond_shaped_mask) || info->number_to_static_ptr == 1) - { - // If there are multiple paths to a base above from here, or if - // a dst_type pointing to (static_ptr, static_type) has been found, - // then there is no way to break out of this loop early unless - // something below detects the search is done. - do - { - if (info->search_done) - break; - p->search_below_dst(info, current_ptr, path_below, use_strcmp); - } while (++p < e); - } - else if (__flags & __non_diamond_repeat_mask) - { - // There are not multiple paths to any base class from here and a - // dst_type pointing to (static_ptr, static_type) has not yet been - // found. - do - { - if (info->search_done) - break; - // If we just found a dst_type with a public path to (static_ptr, static_type), - // then the only reason to continue the search is to make sure - // no other dst_type points to (static_ptr, static_type). - // If !diamond, then we don't need to search here. - if (info->number_to_static_ptr == 1 && - info->path_dst_ptr_to_static_ptr == public_path) - break; - p->search_below_dst(info, current_ptr, path_below, use_strcmp); - } while (++p < e); - } - else - { - // There are no repeated types above this node. - // There are no nodes with multiple parents above this node. - // no dst_type has been found to (static_ptr, static_type) - do - { - if (info->search_done) - break; - // If we just found a dst_type with a public path to (static_ptr, static_type), - // then the only reason to continue the search is to make sure sure - // no other dst_type points to (static_ptr, static_type). - // If !diamond, then we don't need to search here. - // if we just found a dst_type with a private path to (static_ptr, static_type), - // then we're only looking for a public path to (static_ptr, static_type) - // and to check for other dst_types. - // If !diamond & !repeat, then there is not a pointer to (static_ptr, static_type) - // and not a dst_type under here. - if (info->number_to_static_ptr == 1) - break; - p->search_below_dst(info, current_ptr, path_below, use_strcmp); - } while (++p < e); - } - } - } -} - -// This is the same algorithm as __vmi_class_type_info::search_below_dst but -// simplified to the case that there is only a single base class. -void -__si_class_type_info::search_below_dst(__dynamic_cast_info* info, - const void* current_ptr, - int path_below, - bool use_strcmp) const -{ - if (is_equal(this, info->static_type, use_strcmp)) - process_static_type_below_dst(info, current_ptr, path_below); - else if (is_equal(this, info->dst_type, use_strcmp)) - { - // We've been here before if we've recorded current_ptr in one of these - // two places: - if (current_ptr == info->dst_ptr_leading_to_static_ptr || - current_ptr == info->dst_ptr_not_leading_to_static_ptr) - { - // We've seen this node before, and therefore have already searched - // its base classes above. - // Update path to here that is "most public". - if (path_below == public_path) - info->path_dynamic_ptr_to_dst_ptr = public_path; - } - else // We have haven't been here before - { - // Record the access path that got us here - // If there is more than one dst_type this path doesn't matter. - info->path_dynamic_ptr_to_dst_ptr = path_below; - // Only search above here if dst_type derives from static_type, or - // if it is unknown if dst_type derives from static_type. - if (info->is_dst_type_derived_from_static_type != no) - { - // Set up flags to record results from all base classes - bool is_dst_type_derived_from_static_type = false; - bool does_dst_type_point_to_our_static_type = false; - // Zero out found flags - info->found_our_static_ptr = false; - info->found_any_static_type = false; - __base_type->search_above_dst(info, current_ptr, current_ptr, public_path, use_strcmp); - if (info->found_any_static_type) - { - is_dst_type_derived_from_static_type = true; - if (info->found_our_static_ptr) - does_dst_type_point_to_our_static_type = true; - } - if (!does_dst_type_point_to_our_static_type) - { - // We found a dst_type that doesn't point to (static_ptr, static_type) - // So record the address of this dst_ptr and increment the - // count of the number of such dst_types found in the tree. - info->dst_ptr_not_leading_to_static_ptr = current_ptr; - info->number_to_dst_ptr += 1; - // If there exists another dst with a private path to - // (static_ptr, static_type), then the cast from - // (dynamic_ptr, dynamic_type) to dst_type is now ambiguous. - if (info->number_to_static_ptr == 1 && - info->path_dst_ptr_to_static_ptr == not_public_path) - info->search_done = true; - } - // If we found no static_type,s then dst_type doesn't derive - // from static_type, else it does. Record this result so that - // next time we hit a dst_type we will know not to search above - // it if it doesn't derive from static_type. - if (is_dst_type_derived_from_static_type) - info->is_dst_type_derived_from_static_type = yes; - else - info->is_dst_type_derived_from_static_type = no; - } - } - } - else - { - // This is not a static_type and not a dst_type - __base_type->search_below_dst(info, current_ptr, path_below, use_strcmp); - } -} - -// This is the same algorithm as __vmi_class_type_info::search_below_dst but -// simplified to the case that there is no base class. -void -__class_type_info::search_below_dst(__dynamic_cast_info* info, - const void* current_ptr, - int path_below, - bool use_strcmp) const -{ - if (is_equal(this, info->static_type, use_strcmp)) - process_static_type_below_dst(info, current_ptr, path_below); - else if (is_equal(this, info->dst_type, use_strcmp)) - { - // We've been here before if we've recorded current_ptr in one of these - // two places: - if (current_ptr == info->dst_ptr_leading_to_static_ptr || - current_ptr == info->dst_ptr_not_leading_to_static_ptr) - { - // We've seen this node before, and therefore have already searched - // its base classes above. - // Update path to here that is "most public". - if (path_below == public_path) - info->path_dynamic_ptr_to_dst_ptr = public_path; - } - else // We have haven't been here before - { - // Record the access path that got us here - // If there is more than one dst_type this path doesn't matter. - info->path_dynamic_ptr_to_dst_ptr = path_below; - // We found a dst_type that doesn't point to (static_ptr, static_type) - // So record the address of this dst_ptr and increment the - // count of the number of such dst_types found in the tree. - info->dst_ptr_not_leading_to_static_ptr = current_ptr; - info->number_to_dst_ptr += 1; - // If there exists another dst with a private path to - // (static_ptr, static_type), then the cast from - // (dynamic_ptr, dynamic_type) to dst_type is now ambiguous. - if (info->number_to_static_ptr == 1 && - info->path_dst_ptr_to_static_ptr == not_public_path) - info->search_done = true; - // We found that dst_type does not derive from static_type - info->is_dst_type_derived_from_static_type = no; - } - } -} - -// Call this function when searching above a dst_type node. This function searches -// for a public path to (static_ptr, static_type). -// This function is guaranteed not to find a node of type dst_type. -// Theoretically this is a very simple function which just stops if it finds a -// static_type node: All the hoopla surrounding the search code is doing -// nothing but looking for excuses to stop the search prematurely (break out of -// the for-loop). That is, the algorithm below is simply an optimization of this: -// void -// __vmi_class_type_info::search_above_dst(__dynamic_cast_info* info, -// const void* dst_ptr, -// const void* current_ptr, -// int path_below) const -// { -// if (this == info->static_type) -// process_static_type_above_dst(info, dst_ptr, current_ptr, path_below); -// else -// { -// typedef const __base_class_type_info* Iter; -// // This is not a static_type and not a dst_type -// for (Iter p = __base_info, e = __base_info + __base_count; p < e; ++p) -// { -// p->search_above_dst(info, dst_ptr, current_ptr, public_path); -// // break out early here if you can detect it doesn't matter if you do -// } -// } -// } -void -__vmi_class_type_info::search_above_dst(__dynamic_cast_info* info, - const void* dst_ptr, - const void* current_ptr, - int path_below, - bool use_strcmp) const -{ - if (is_equal(this, info->static_type, use_strcmp)) - process_static_type_above_dst(info, dst_ptr, current_ptr, path_below); - else - { - typedef const __base_class_type_info* Iter; - // This is not a static_type and not a dst_type - // Save flags so they can be restored when returning to nodes below. - bool found_our_static_ptr = info->found_our_static_ptr; - bool found_any_static_type = info->found_any_static_type; - // We've found a dst_type below with a path to here. If the path - // to here is not public, there may be another path to here that - // is public. So we have to assume that the path to here is public. - // We can stop looking above if: - // 1. We've found a public path to (static_ptr, static_type). - // 2. We've found an ambiguous cast from (static_ptr, static_type) to a dst_type. - // This is detected at the (static_ptr, static_type). - // 3. We can prove that there is no public path to (static_ptr, static_type) - // above here. - const Iter e = __base_info + __base_count; - Iter p = __base_info; - // Zero out found flags - info->found_our_static_ptr = false; - info->found_any_static_type = false; - p->search_above_dst(info, dst_ptr, current_ptr, path_below, use_strcmp); - if (++p < e) - { - do - { - if (info->search_done) - break; - if (info->found_our_static_ptr) - { - // If we found what we're looking for, stop looking above. - if (info->path_dst_ptr_to_static_ptr == public_path) - break; - // We found a private path to (static_ptr, static_type) - // If there is no diamond then there is only one path - // to (static_ptr, static_type) from here and we just found it. - if (!(__flags & __diamond_shaped_mask)) - break; - } - else if (info->found_any_static_type) - { - // If we found a static_type that isn't the one we're looking - // for, and if there are no repeated types above here, - // then stop looking. - if (!(__flags & __non_diamond_repeat_mask)) - break; - } - // Zero out found flags - info->found_our_static_ptr = false; - info->found_any_static_type = false; - p->search_above_dst(info, dst_ptr, current_ptr, path_below, use_strcmp); - } while (++p < e); - } - // Restore flags - info->found_our_static_ptr = found_our_static_ptr; - info->found_any_static_type = found_any_static_type; - } -} - -// This is the same algorithm as __vmi_class_type_info::search_above_dst but -// simplified to the case that there is only a single base class. -void -__si_class_type_info::search_above_dst(__dynamic_cast_info* info, - const void* dst_ptr, - const void* current_ptr, - int path_below, - bool use_strcmp) const -{ - if (is_equal(this, info->static_type, use_strcmp)) - process_static_type_above_dst(info, dst_ptr, current_ptr, path_below); - else - __base_type->search_above_dst(info, dst_ptr, current_ptr, path_below, use_strcmp); -} - -// This is the same algorithm as __vmi_class_type_info::search_above_dst but -// simplified to the case that there is no base class. -void -__class_type_info::search_above_dst(__dynamic_cast_info* info, - const void* dst_ptr, - const void* current_ptr, - int path_below, - bool use_strcmp) const -{ - if (is_equal(this, info->static_type, use_strcmp)) - process_static_type_above_dst(info, dst_ptr, current_ptr, path_below); -} - -// The search functions for __base_class_type_info are simply convenience -// functions for adjusting the current_ptr and path_below as the search is -// passed up to the base class node. - -void -__base_class_type_info::search_above_dst(__dynamic_cast_info* info, - const void* dst_ptr, - const void* current_ptr, - int path_below, - bool use_strcmp) const -{ - ptrdiff_t offset_to_base = __offset_flags >> __offset_shift; - if (__offset_flags & __virtual_mask) - { - const char* vtable = *static_cast<const char*const*>(current_ptr); - offset_to_base = *reinterpret_cast<const ptrdiff_t*>(vtable + offset_to_base); - } - __base_type->search_above_dst(info, dst_ptr, - static_cast<const char*>(current_ptr) + offset_to_base, - (__offset_flags & __public_mask) ? - path_below : - not_public_path, - use_strcmp); -} - -void -__base_class_type_info::search_below_dst(__dynamic_cast_info* info, - const void* current_ptr, - int path_below, - bool use_strcmp) const -{ - ptrdiff_t offset_to_base = __offset_flags >> __offset_shift; - if (__offset_flags & __virtual_mask) - { - const char* vtable = *static_cast<const char*const*>(current_ptr); - offset_to_base = *reinterpret_cast<const ptrdiff_t*>(vtable + offset_to_base); - } - __base_type->search_below_dst(info, - static_cast<const char*>(current_ptr) + offset_to_base, - (__offset_flags & __public_mask) ? - path_below : - not_public_path, - use_strcmp); -} - -} // __cxxabiv1 diff --git a/chromium/buildtools/third_party/libc++abi/trunk/src/private_typeinfo.h b/chromium/buildtools/third_party/libc++abi/trunk/src/private_typeinfo.h deleted file mode 100644 index 3922ae6ef56..00000000000 --- a/chromium/buildtools/third_party/libc++abi/trunk/src/private_typeinfo.h +++ /dev/null @@ -1,252 +0,0 @@ -//===------------------------ private_typeinfo.h --------------------------===// -// -// 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 __PRIVATE_TYPEINFO_H_ -#define __PRIVATE_TYPEINFO_H_ - -#include "__cxxabi_config.h" - -#include <typeinfo> -#include <cstddef> - -namespace __cxxabiv1 { - -class _LIBCXXABI_TYPE_VIS __shim_type_info : public std::type_info { -public: - _LIBCXXABI_HIDDEN virtual ~__shim_type_info(); - - _LIBCXXABI_HIDDEN virtual void noop1() const; - _LIBCXXABI_HIDDEN virtual void noop2() const; - _LIBCXXABI_HIDDEN virtual bool can_catch(const __shim_type_info *thrown_type, - void *&adjustedPtr) const = 0; -}; - -class _LIBCXXABI_TYPE_VIS __fundamental_type_info : public __shim_type_info { -public: - _LIBCXXABI_HIDDEN virtual ~__fundamental_type_info(); - _LIBCXXABI_HIDDEN virtual bool can_catch(const __shim_type_info *, - void *&) const; -}; - -class _LIBCXXABI_TYPE_VIS __array_type_info : public __shim_type_info { -public: - _LIBCXXABI_HIDDEN virtual ~__array_type_info(); - _LIBCXXABI_HIDDEN virtual bool can_catch(const __shim_type_info *, - void *&) const; -}; - -class _LIBCXXABI_TYPE_VIS __function_type_info : public __shim_type_info { -public: - _LIBCXXABI_HIDDEN virtual ~__function_type_info(); - _LIBCXXABI_HIDDEN virtual bool can_catch(const __shim_type_info *, - void *&) const; -}; - -class _LIBCXXABI_TYPE_VIS __enum_type_info : public __shim_type_info { -public: - _LIBCXXABI_HIDDEN virtual ~__enum_type_info(); - _LIBCXXABI_HIDDEN virtual bool can_catch(const __shim_type_info *, - void *&) const; -}; - -enum -{ - unknown = 0, - public_path, - not_public_path, - yes, - no -}; - -class _LIBCXXABI_TYPE_VIS __class_type_info; - -struct _LIBCXXABI_HIDDEN __dynamic_cast_info -{ -// const data supplied to the search: - - const __class_type_info* dst_type; - const void* static_ptr; - const __class_type_info* static_type; - std::ptrdiff_t src2dst_offset; - -// Data that represents the answer: - - // pointer to a dst_type which has (static_ptr, static_type) above it - const void* dst_ptr_leading_to_static_ptr; - // pointer to a dst_type which does not have (static_ptr, static_type) above it - const void* dst_ptr_not_leading_to_static_ptr; - - // The following three paths are either unknown, public_path or not_public_path. - // access of path from dst_ptr_leading_to_static_ptr to (static_ptr, static_type) - int path_dst_ptr_to_static_ptr; - // access of path from (dynamic_ptr, dynamic_type) to (static_ptr, static_type) - // when there is no dst_type along the path - int path_dynamic_ptr_to_static_ptr; - // access of path from (dynamic_ptr, dynamic_type) to dst_type - // (not used if there is a (static_ptr, static_type) above a dst_type). - int path_dynamic_ptr_to_dst_ptr; - - // Number of dst_types below (static_ptr, static_type) - int number_to_static_ptr; - // Number of dst_types not below (static_ptr, static_type) - int number_to_dst_ptr; - -// Data that helps stop the search before the entire tree is searched: - - // is_dst_type_derived_from_static_type is either unknown, yes or no. - int is_dst_type_derived_from_static_type; - // Number of dst_type in tree. If 0, then that means unknown. - int number_of_dst_type; - // communicates to a dst_type node that (static_ptr, static_type) was found - // above it. - bool found_our_static_ptr; - // communicates to a dst_type node that a static_type was found - // above it, but it wasn't (static_ptr, static_type) - bool found_any_static_type; - // Set whenever a search can be stopped - bool search_done; -}; - -// Has no base class -class _LIBCXXABI_TYPE_VIS __class_type_info : public __shim_type_info { -public: - _LIBCXXABI_HIDDEN virtual ~__class_type_info(); - - _LIBCXXABI_HIDDEN void process_static_type_above_dst(__dynamic_cast_info *, - const void *, - const void *, int) const; - _LIBCXXABI_HIDDEN void process_static_type_below_dst(__dynamic_cast_info *, - const void *, int) const; - _LIBCXXABI_HIDDEN void process_found_base_class(__dynamic_cast_info *, void *, - int) const; - _LIBCXXABI_HIDDEN virtual void search_above_dst(__dynamic_cast_info *, - const void *, const void *, - int, bool) const; - _LIBCXXABI_HIDDEN virtual void - search_below_dst(__dynamic_cast_info *, const void *, int, bool) const; - _LIBCXXABI_HIDDEN virtual bool can_catch(const __shim_type_info *, - void *&) const; - _LIBCXXABI_HIDDEN virtual void - has_unambiguous_public_base(__dynamic_cast_info *, void *, int) const; -}; - -// Has one non-virtual public base class at offset zero -class _LIBCXXABI_TYPE_VIS __si_class_type_info : public __class_type_info { -public: - const __class_type_info *__base_type; - - _LIBCXXABI_HIDDEN virtual ~__si_class_type_info(); - - _LIBCXXABI_HIDDEN virtual void search_above_dst(__dynamic_cast_info *, - const void *, const void *, - int, bool) const; - _LIBCXXABI_HIDDEN virtual void - search_below_dst(__dynamic_cast_info *, const void *, int, bool) const; - _LIBCXXABI_HIDDEN virtual void - has_unambiguous_public_base(__dynamic_cast_info *, void *, int) const; -}; - -struct _LIBCXXABI_HIDDEN __base_class_type_info -{ -public: - const __class_type_info* __base_type; - long __offset_flags; - - enum __offset_flags_masks - { - __virtual_mask = 0x1, - __public_mask = 0x2, // base is public - __offset_shift = 8 - }; - - void search_above_dst(__dynamic_cast_info*, const void*, const void*, int, bool) const; - void search_below_dst(__dynamic_cast_info*, const void*, int, bool) const; - void has_unambiguous_public_base(__dynamic_cast_info*, void*, int) const; -}; - -// Has one or more base classes -class _LIBCXXABI_TYPE_VIS __vmi_class_type_info : public __class_type_info { -public: - unsigned int __flags; - unsigned int __base_count; - __base_class_type_info __base_info[1]; - - enum __flags_masks { - __non_diamond_repeat_mask = 0x1, // has two or more distinct base class - // objects of the same type - __diamond_shaped_mask = 0x2 // has base class object with two or - // more derived objects - }; - - _LIBCXXABI_HIDDEN virtual ~__vmi_class_type_info(); - - _LIBCXXABI_HIDDEN virtual void search_above_dst(__dynamic_cast_info *, - const void *, const void *, - int, bool) const; - _LIBCXXABI_HIDDEN virtual void - search_below_dst(__dynamic_cast_info *, const void *, int, bool) const; - _LIBCXXABI_HIDDEN virtual void - has_unambiguous_public_base(__dynamic_cast_info *, void *, int) const; -}; - -class _LIBCXXABI_TYPE_VIS __pbase_type_info : public __shim_type_info { -public: - unsigned int __flags; - const __shim_type_info *__pointee; - - enum __masks { - __const_mask = 0x1, - __volatile_mask = 0x2, - __restrict_mask = 0x4, - __incomplete_mask = 0x8, - __incomplete_class_mask = 0x10, - __transaction_safe_mask = 0x20, - // This implements the following proposal from cxx-abi-dev (not yet part of - // the ABI document): - // - // http://sourcerytools.com/pipermail/cxx-abi-dev/2016-October/002986.html - // - // This is necessary for support of http://wg21.link/p0012, which permits - // throwing noexcept function and member function pointers and catching - // them as non-noexcept pointers. - __noexcept_mask = 0x40, - - // Flags that cannot be removed by a standard conversion. - __no_remove_flags_mask = __const_mask | __volatile_mask | __restrict_mask, - // Flags that cannot be added by a standard conversion. - __no_add_flags_mask = __transaction_safe_mask | __noexcept_mask - }; - - _LIBCXXABI_HIDDEN virtual ~__pbase_type_info(); - _LIBCXXABI_HIDDEN virtual bool can_catch(const __shim_type_info *, - void *&) const; -}; - -class _LIBCXXABI_TYPE_VIS __pointer_type_info : public __pbase_type_info { -public: - _LIBCXXABI_HIDDEN virtual ~__pointer_type_info(); - _LIBCXXABI_HIDDEN virtual bool can_catch(const __shim_type_info *, - void *&) const; - _LIBCXXABI_HIDDEN bool can_catch_nested(const __shim_type_info *) const; -}; - -class _LIBCXXABI_TYPE_VIS __pointer_to_member_type_info - : public __pbase_type_info { -public: - const __class_type_info *__context; - - _LIBCXXABI_HIDDEN virtual ~__pointer_to_member_type_info(); - _LIBCXXABI_HIDDEN virtual bool can_catch(const __shim_type_info *, - void *&) const; - _LIBCXXABI_HIDDEN bool can_catch_nested(const __shim_type_info *) const; -}; - -} // __cxxabiv1 - -#endif // __PRIVATE_TYPEINFO_H_ diff --git a/chromium/buildtools/third_party/libc++abi/trunk/src/stdlib_exception.cpp b/chromium/buildtools/third_party/libc++abi/trunk/src/stdlib_exception.cpp deleted file mode 100644 index a8f71ab0ecc..00000000000 --- a/chromium/buildtools/third_party/libc++abi/trunk/src/stdlib_exception.cpp +++ /dev/null @@ -1,103 +0,0 @@ -//===---------------------------- exception.cpp ---------------------------===// -// -// 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. -// -//===----------------------------------------------------------------------===// - -#define _LIBCPP_BUILDING_LIBRARY -#define _LIBCPP_BUILDING_NEW -#include <new> -#include <exception> - -namespace std -{ - -// exception - -exception::~exception() _NOEXCEPT -{ -} - -const char* exception::what() const _NOEXCEPT -{ - return "std::exception"; -} - -// bad_exception - -bad_exception::~bad_exception() _NOEXCEPT -{ -} - -const char* bad_exception::what() const _NOEXCEPT -{ - return "std::bad_exception"; -} - - -// bad_alloc - -bad_alloc::bad_alloc() _NOEXCEPT -{ -} - -bad_alloc::~bad_alloc() _NOEXCEPT -{ -} - -const char* -bad_alloc::what() const _NOEXCEPT -{ - return "std::bad_alloc"; -} - -// bad_array_new_length - -bad_array_new_length::bad_array_new_length() _NOEXCEPT -{ -} - -bad_array_new_length::~bad_array_new_length() _NOEXCEPT -{ -} - -const char* -bad_array_new_length::what() const _NOEXCEPT -{ - return "bad_array_new_length"; -} - -// bad_array_length - -#ifndef _LIBCPP_BAD_ARRAY_LENGTH_DEFINED - -class _LIBCPP_EXCEPTION_ABI bad_array_length - : public bad_alloc -{ -public: - bad_array_length() _NOEXCEPT; - virtual ~bad_array_length() _NOEXCEPT; - virtual const char* what() const _NOEXCEPT; -}; - -#endif // _LIBCPP_BAD_ARRAY_LENGTH_DEFINED - -bad_array_length::bad_array_length() _NOEXCEPT -{ -} - -bad_array_length::~bad_array_length() _NOEXCEPT -{ -} - -const char* -bad_array_length::what() const _NOEXCEPT -{ - return "bad_array_length"; -} - - -} // std diff --git a/chromium/buildtools/third_party/libc++abi/trunk/src/stdlib_new_delete.cpp b/chromium/buildtools/third_party/libc++abi/trunk/src/stdlib_new_delete.cpp deleted file mode 100644 index 0e85f6ad299..00000000000 --- a/chromium/buildtools/third_party/libc++abi/trunk/src/stdlib_new_delete.cpp +++ /dev/null @@ -1,264 +0,0 @@ -//===--------------------- stdlib_new_delete.cpp --------------------------===// -// -// 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. -// -// -// This file implements the new and delete operators. -//===----------------------------------------------------------------------===// - -#define _LIBCPP_BUILDING_NEW -#define _LIBCPP_BUILDING_LIBRARY -#include "__cxxabi_config.h" -#include <new> -#include <cstdlib> - -#if !defined(_THROW_BAD_ALLOC) || !defined(_NOEXCEPT) || !defined(_LIBCXXABI_WEAK) -#error The _THROW_BAD_ALLOC, _NOEXCEPT, and _LIBCXXABI_WEAK libc++ macros must \ - already be defined by libc++. -#endif -// Implement all new and delete operators as weak definitions -// in this shared library, so that they can be overridden by programs -// that define non-weak copies of the functions. - -_LIBCXXABI_WEAK -void * -operator new(std::size_t size) _THROW_BAD_ALLOC -{ - if (size == 0) - size = 1; - void* p; - while ((p = ::malloc(size)) == 0) - { - // If malloc fails and there is a new_handler, - // call it to try free up memory. - std::new_handler nh = std::get_new_handler(); - if (nh) - nh(); - else -#ifndef _LIBCXXABI_NO_EXCEPTIONS - throw std::bad_alloc(); -#else - break; -#endif - } - return p; -} - -_LIBCXXABI_WEAK -void* -operator new(size_t size, const std::nothrow_t&) _NOEXCEPT -{ - void* p = 0; -#ifndef _LIBCXXABI_NO_EXCEPTIONS - try - { -#endif // _LIBCXXABI_NO_EXCEPTIONS - p = ::operator new(size); -#ifndef _LIBCXXABI_NO_EXCEPTIONS - } - catch (...) - { - } -#endif // _LIBCXXABI_NO_EXCEPTIONS - return p; -} - -_LIBCXXABI_WEAK -void* -operator new[](size_t size) _THROW_BAD_ALLOC -{ - return ::operator new(size); -} - -_LIBCXXABI_WEAK -void* -operator new[](size_t size, const std::nothrow_t&) _NOEXCEPT -{ - void* p = 0; -#ifndef _LIBCXXABI_NO_EXCEPTIONS - try - { -#endif // _LIBCXXABI_NO_EXCEPTIONS - p = ::operator new[](size); -#ifndef _LIBCXXABI_NO_EXCEPTIONS - } - catch (...) - { - } -#endif // _LIBCXXABI_NO_EXCEPTIONS - return p; -} - -_LIBCXXABI_WEAK -void -operator delete(void* ptr) _NOEXCEPT -{ - if (ptr) - ::free(ptr); -} - -_LIBCXXABI_WEAK -void -operator delete(void* ptr, const std::nothrow_t&) _NOEXCEPT -{ - ::operator delete(ptr); -} - -_LIBCXXABI_WEAK -void -operator delete(void* ptr, size_t) _NOEXCEPT -{ - ::operator delete(ptr); -} - -_LIBCXXABI_WEAK -void -operator delete[] (void* ptr) _NOEXCEPT -{ - ::operator delete(ptr); -} - -_LIBCXXABI_WEAK -void -operator delete[] (void* ptr, const std::nothrow_t&) _NOEXCEPT -{ - ::operator delete[](ptr); -} - -_LIBCXXABI_WEAK -void -operator delete[] (void* ptr, size_t) _NOEXCEPT -{ - ::operator delete[](ptr); -} - -#if !defined(_LIBCPP_HAS_NO_ALIGNED_ALLOCATION) - -_LIBCXXABI_WEAK -void * -operator new(std::size_t size, std::align_val_t alignment) _THROW_BAD_ALLOC -{ - if (size == 0) - size = 1; - if (static_cast<size_t>(alignment) < sizeof(void*)) - alignment = std::align_val_t(sizeof(void*)); - void* p; -#if defined(_LIBCPP_WIN32API) - while ((p = _aligned_malloc(size, static_cast<size_t>(alignment))) == nullptr) -#else - while (::posix_memalign(&p, static_cast<size_t>(alignment), size) != 0) -#endif - { - // If posix_memalign fails and there is a new_handler, - // call it to try free up memory. - std::new_handler nh = std::get_new_handler(); - if (nh) - nh(); - else { -#ifndef _LIBCXXABI_NO_EXCEPTIONS - throw std::bad_alloc(); -#else - p = nullptr; // posix_memalign doesn't initialize 'p' on failure - break; -#endif - } - } - return p; -} - -_LIBCXXABI_WEAK -void* -operator new(size_t size, std::align_val_t alignment, const std::nothrow_t&) _NOEXCEPT -{ - void* p = 0; -#ifndef _LIBCXXABI_NO_EXCEPTIONS - try - { -#endif // _LIBCXXABI_NO_EXCEPTIONS - p = ::operator new(size, alignment); -#ifndef _LIBCXXABI_NO_EXCEPTIONS - } - catch (...) - { - } -#endif // _LIBCXXABI_NO_EXCEPTIONS - return p; -} - -_LIBCXXABI_WEAK -void* -operator new[](size_t size, std::align_val_t alignment) _THROW_BAD_ALLOC -{ - return ::operator new(size, alignment); -} - -_LIBCXXABI_WEAK -void* -operator new[](size_t size, std::align_val_t alignment, const std::nothrow_t&) _NOEXCEPT -{ - void* p = 0; -#ifndef _LIBCXXABI_NO_EXCEPTIONS - try - { -#endif // _LIBCXXABI_NO_EXCEPTIONS - p = ::operator new[](size, alignment); -#ifndef _LIBCXXABI_NO_EXCEPTIONS - } - catch (...) - { - } -#endif // _LIBCXXABI_NO_EXCEPTIONS - return p; -} - -_LIBCXXABI_WEAK -void -operator delete(void* ptr, std::align_val_t) _NOEXCEPT -{ - if (ptr) -#if defined(_LIBCPP_WIN32API) - ::_aligned_free(ptr); -#else - ::free(ptr); -#endif -} - -_LIBCXXABI_WEAK -void -operator delete(void* ptr, std::align_val_t alignment, const std::nothrow_t&) _NOEXCEPT -{ - ::operator delete(ptr, alignment); -} - -_LIBCXXABI_WEAK -void -operator delete(void* ptr, size_t, std::align_val_t alignment) _NOEXCEPT -{ - ::operator delete(ptr, alignment); -} - -_LIBCXXABI_WEAK -void -operator delete[] (void* ptr, std::align_val_t alignment) _NOEXCEPT -{ - ::operator delete(ptr, alignment); -} - -_LIBCXXABI_WEAK -void -operator delete[] (void* ptr, std::align_val_t alignment, const std::nothrow_t&) _NOEXCEPT -{ - ::operator delete[](ptr, alignment); -} - -_LIBCXXABI_WEAK -void -operator delete[] (void* ptr, size_t, std::align_val_t alignment) _NOEXCEPT -{ - ::operator delete[](ptr, alignment); -} - -#endif // !_LIBCPP_HAS_NO_ALIGNED_ALLOCATION diff --git a/chromium/buildtools/third_party/libc++abi/trunk/src/stdlib_stdexcept.cpp b/chromium/buildtools/third_party/libc++abi/trunk/src/stdlib_stdexcept.cpp deleted file mode 100644 index e3b7cd40658..00000000000 --- a/chromium/buildtools/third_party/libc++abi/trunk/src/stdlib_stdexcept.cpp +++ /dev/null @@ -1,48 +0,0 @@ -//===------------------------ stdexcept.cpp -------------------------------===// -// -// 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. -// -//===----------------------------------------------------------------------===// - -#include "include/refstring.h" -#include "stdexcept" -#include "new" -#include <cstdlib> -#include <cstring> -#include <cstdint> -#include <cstddef> - -static_assert(sizeof(std::__libcpp_refstring) == sizeof(const char *), ""); - -namespace std // purposefully not using versioning namespace -{ - -logic_error::~logic_error() _NOEXCEPT {} - -const char* -logic_error::what() const _NOEXCEPT -{ - return __imp_.c_str(); -} - -runtime_error::~runtime_error() _NOEXCEPT {} - -const char* -runtime_error::what() const _NOEXCEPT -{ - return __imp_.c_str(); -} - -domain_error::~domain_error() _NOEXCEPT {} -invalid_argument::~invalid_argument() _NOEXCEPT {} -length_error::~length_error() _NOEXCEPT {} -out_of_range::~out_of_range() _NOEXCEPT {} - -range_error::~range_error() _NOEXCEPT {} -overflow_error::~overflow_error() _NOEXCEPT {} -underflow_error::~underflow_error() _NOEXCEPT {} - -} // std diff --git a/chromium/buildtools/third_party/libc++abi/trunk/src/stdlib_typeinfo.cpp b/chromium/buildtools/third_party/libc++abi/trunk/src/stdlib_typeinfo.cpp deleted file mode 100644 index 9313be04a39..00000000000 --- a/chromium/buildtools/third_party/libc++abi/trunk/src/stdlib_typeinfo.cpp +++ /dev/null @@ -1,53 +0,0 @@ -//===----------------------------- typeinfo.cpp ---------------------------===// -// -// 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. -// -//===----------------------------------------------------------------------===// - -#include <typeinfo> - -namespace std -{ - -// type_info - -type_info::~type_info() -{ -} - -// bad_cast - -bad_cast::bad_cast() _NOEXCEPT -{ -} - -bad_cast::~bad_cast() _NOEXCEPT -{ -} - -const char* -bad_cast::what() const _NOEXCEPT -{ - return "std::bad_cast"; -} - -// bad_typeid - -bad_typeid::bad_typeid() _NOEXCEPT -{ -} - -bad_typeid::~bad_typeid() _NOEXCEPT -{ -} - -const char* -bad_typeid::what() const _NOEXCEPT -{ - return "std::bad_typeid"; -} - -} // std diff --git a/chromium/buildtools/third_party/libc++abi/trunk/www/content.css b/chromium/buildtools/third_party/libc++abi/trunk/www/content.css deleted file mode 100644 index dca6a329143..00000000000 --- a/chromium/buildtools/third_party/libc++abi/trunk/www/content.css +++ /dev/null @@ -1,27 +0,0 @@ -html { margin: 0px; } body { margin: 8px; } - -html, body { - padding:0px; - font-size:small; font-family:"Lucida Grande", "Lucida Sans Unicode", Arial, Verdana, Helvetica, sans-serif; background-color: #fff; color: #222; - line-height:1.5; -} - -h1, h2, h3, tt { color: #000 } - -h1 { padding-top:0px; margin-top:0px;} -h2 { color:#333333; padding-top:0.5em; } -h3 { padding-top: 0.5em; margin-bottom: -0.25em; color:#2d58b7} -li { padding-bottom: 0.5em; } -ul { padding-left:1.5em; } - -/* Slides */ -IMG.img_slide { - display: block; - margin-left: auto; - margin-right: auto -} - -.itemTitle { color:#2d58b7 } - -/* Tables */ -tr { vertical-align:top } diff --git a/chromium/buildtools/third_party/libc++abi/trunk/www/index.html b/chromium/buildtools/third_party/libc++abi/trunk/www/index.html deleted file mode 100644 index 66bbb64824e..00000000000 --- a/chromium/buildtools/third_party/libc++abi/trunk/www/index.html +++ /dev/null @@ -1,143 +0,0 @@ -<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" - "http://www.w3.org/TR/html4/strict.dtd"> -<!-- Material used from: HTML 4.01 specs: http://www.w3.org/TR/html401/ --> -<html> -<head> - <META http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"> - <title>"libc++abi" C++ Standard Library Support</title> - <link type="text/css" rel="stylesheet" href="menu.css"> - <link type="text/css" rel="stylesheet" href="content.css"> -</head> - -<body> -<div id="menu"> - <div> - <a href="http://llvm.org/">LLVM Home</a> - </div> - - <div class="submenu"> - <label>libc++abi Info</label> - <a href="/index.html">About</a> - </div> - - <div class="submenu"> - <label>Quick Links</label> - <a href="http://lists.llvm.org/mailman/listinfo/cfe-dev">cfe-dev</a> - <a href="http://lists.llvm.org/mailman/listinfo/cfe-commits">cfe-commits</a> - <a href="http://llvm.org/bugs/">Bug Reports</a> - <a href="http://llvm.org/svn/llvm-project/libcxxabi/trunk/">Browse SVN</a> - <a href="http://llvm.org/viewvc/llvm-project/libcxxabi/trunk/">Browse ViewVC</a> - </div> -</div> - -<div id="content"> - <!--*********************************************************************--> - <h1>"libc++abi" C++ Standard Library Support</h1> - <!--*********************************************************************--> - - <p>libc++abi is a new implementation of low level support for a standard - C++ library.</p> - - <p>All of the code in libc++abi is <a - href="http://llvm.org/docs/DeveloperPolicy.html#license">dual licensed</a> - under the MIT license and the UIUC License (a BSD-like license).</p> - - <!--=====================================================================--> - <h2 id="goals">Features and Goals</h2> - <!--=====================================================================--> - - <ul> - <li>Correctness as defined by the C++11 standard.</li> - <li>Provide a portable sublayer to ease the porting of <a href="http://libcxx.llvm.org/">libc++</a></li> - <li>On Mac OS X, be ABI compatible with the existing low-level support.</li> - </ul> - - <!--=====================================================================--> - <h2 id="requirements">Platform Support</h2> - <!--=====================================================================--> - - <p>libc++abi is known to work on the following platforms, using clang.</p> - - <ul> - <li>Darwin</li> - </ul> - - <!--=====================================================================--> - <h2 id="dir-structure">Current Status</h2> - <!--=====================================================================--> - - <p>libc++abi is complete. <a href="spec.html">Here</a> is a - list of functionality.</p> - - <!--=====================================================================--> - <h2>Get it and get involved!</h2> - <!--=====================================================================--> - - <p>To check out the code, use:</p> - - <ul> - <li><code>svn co http://llvm.org/svn/llvm-project/libcxxabi/trunk libcxxabi</code></li> - </ul> - - <p>To build:</p> - <ul> - <li>Check out libcxxabi into <code>llvm/projects</code></li> - <li><code>cd llvm</code></li> - <li><code>mkdir build && cd build</code></li> - <li><code>cmake .. # on linux you may need to prefix with CC=clang CXX=clang++</code></li> - <li><code>make</code></li> - </ul> - - <p>To do a standalone build:</p> - <ul> - <li> - Check out the <a href="http://libcxx.llvm.org">libcxx source</a> tree. - </li> - <li><code>cd libcxxabi</code></li> - <li><code>mkdir build && cd build</code></li> - <li><code>cmake -DLIBCXXABI_LIBCXX_PATH=path/to/libcxx .. # on - linux you may need -DCMAKE_C_COMPILER=clang -DCMAKE_CXX_COMPILER=clang++</code></li> - <li><code>make</code></li> - </ul> - <p> By default CMake uses <code>llvm-config</code> to locate the required - LLVM sources. If CMake cannot find <code>llvm-config</code> then you must - configure CMake using either of the following options. - </p> - <ul> - <li><code>-DLLVM_CONFIG_PATH=path/to/llvm-config</code></li> - <li><code>-DLLVM_PATH=path/to/llvm-source-root</code></li> - </ul> - - </p> - - <p>To run the tests:</p> - <ul> - <li><code>make check-cxxabi</code></li> - </ul> - <p>Note: in a standalone build, the system's libc++ will be used for tests. If - the system's libc++ was statically linked against libc++abi (or linked against - a different ABI library), this may interfere with test results.</p> - - <p>Send discussions to the - (<a href="http://lists.llvm.org/mailman/listinfo/cfe-dev">clang mailing list</a>).</p> - - <!--=====================================================================--> - <h2>Frequently asked questions</h2> - <!--=====================================================================--> - - <p>Q: Why are the destructors for the standard exception classes defined in libc++abi? - They're just empty, can't they be defined inline?</p> - <p>A: The destructors for them live in libc++abi because they are "key" functions. - The Itanium ABI describes a "key" function as the first virtual declared. - And wherever the key function is defined, that is where the <code>type_info</code> gets defined. - And in libc++ types are the same type if and only if they have the same <code>type_info</code> - (as in there must be only one type info per type in the entire application). - And on OS X, libstdc++ and libc++ share these exception types. - So to be able to throw in one dylib and catch in another (a <code>std::exception</code> for example), - there must be only one <code>std::exception type_info</code> in the entire app. - That typeinfo gets laid down beside <code>~exception()</code> in libc++abi (for both libstdc++ and libc++).</p> - <p>--Howard Hinnant</p> - -</div> -</body> -</html> diff --git a/chromium/buildtools/third_party/libc++abi/trunk/www/menu.css b/chromium/buildtools/third_party/libc++abi/trunk/www/menu.css deleted file mode 100644 index 4a887b1907a..00000000000 --- a/chromium/buildtools/third_party/libc++abi/trunk/www/menu.css +++ /dev/null @@ -1,39 +0,0 @@ -/***************/ -/* page layout */ -/***************/ - -[id=menu] { - position:fixed; - width:25ex; -} -[id=content] { - /* ***** EDIT THIS VALUE IF CONTENT OVERLAPS MENU ***** */ - position:absolute; - left:29ex; - padding-right:4ex; -} - -/**************/ -/* menu style */ -/**************/ - -#menu .submenu { - padding-top:1em; - display:block; -} - -#menu label { - display:block; - font-weight: bold; - text-align: center; - background-color: rgb(192,192,192); -} -#menu a { - padding:0 .2em; - display:block; - text-align: center; - background-color: rgb(235,235,235); -} -#menu a:visited { - color:rgb(100,50,100); -} diff --git a/chromium/buildtools/third_party/libc++abi/trunk/www/spec.html b/chromium/buildtools/third_party/libc++abi/trunk/www/spec.html deleted file mode 100644 index 2bb9ad959ca..00000000000 --- a/chromium/buildtools/third_party/libc++abi/trunk/www/spec.html +++ /dev/null @@ -1,1016 +0,0 @@ -<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" - "http://www.w3.org/TR/html4/strict.dtd"> -<html> -<head> - <title>libc++abi spec</title> -</head> -<body> - -<table border=1> -<tr> -<th rowspan=2>libc++abi Specification</th> -<th colspan=3>Completed ?</th> -</tr> - -<tr> -<th>darwin</th><th>linux</th><th>arm</th> -</tr> - -<tr> -<td colspan=4 align="center">Memory management</td> -</tr> - -<tr> -<td> -<p> -<code>void* __cxa_allocate_exception(size_t thrown_size) throw();</code> -</p> -<blockquote> -<p> -<i>Effects:</i> Allocates memory to hold the exception to be thrown. -<tt>thrown_size</tt> is the size of the exception object. Can allocate -additional memory to hold private data. If memory can not be allocated, call -<tt>std::terminate()</tt>. -</p> -<p> -<i>Returns:</i> A pointer to the memory allocated for the exception object. -</p> -</blockquote> -</td> -<td>✓</td> -<td>✓</td> -<td>✓</td> -</tr> - -<tr> -<td> -<p> -<code>void __cxa_free_exception(void * thrown_exception) throw();</code> -</p> -<blockquote> -<p> -<i>Effects:</i> Frees memory allocated by <tt>__cxa_allocate_exception</tt>. -</p> -</blockquote> -</td> -<td>✓</td> -<td>✓</td> -<td>✓</td> -</tr> - -<tr> -<td> -<p> -<code>void* __cxa_allocate_dependent_exception() throw();</code> -</p> -<blockquote> -<p> -<i>Effects:</i> Allocates memory to hold a "dependent" exception to be thrown. -<tt>thrown_size</tt> is the size of the exception object. Can allocate -additional memory to hold private data. If memory can not be allocated, call -<tt>std::terminate()</tt>. -</p> -<p> -<i>Returns:</i> A pointer to the memory allocated for the exception object. -</p> -</blockquote> -</td> -<td>✓</td> -<td>✓</td> -<td>✓</td> -</tr> - -<tr> -<td> -<p> -<code>void __cxa_free_dependent_exception (void* dependent_exception) throw();</code> -</p> -<blockquote> -<p> -<i>Effects:</i> Frees memory allocated by <tt>__cxa_allocate_dependent_exception</tt>. -</p> -</blockquote> -</td> -<td>✓</td> -<td>✓</td> -<td>✓</td> -</tr> - -<tr> -<td colspan=4 align="center">Exception Handling</td> -</tr> - -<tr> -<td> -<p> -<code>void __cxa_throw(void* thrown_exception, struct std::type_info * tinfo, - void (*dest)(void*));</code> -</p> -<blockquote> -<p> -<i>Effects:</i> -</p> -</blockquote> -</td> -<td>✓</td> -<td>✓</td> -<td>✓</td> -</tr> - -<tr> -<td> -<p> -<code>void* __cxa_get_exception_ptr(void* exceptionObject) throw();</code> -</p> -<blockquote> -<p> -<i>Returns:</i> The adjusted pointer to the exception object. (The adjusted -pointer is typically computed by the personality routine during phase 1 and -saved in the exception object.) -</p> -</blockquote> -</td> -<td>✓</td> -<td>✓</td> -<td>✓</td> -</tr> - -<tr> -<td> -<p> -<code>void* __cxa_begin_catch(void* exceptionObject) throw();</code> -</p> -<blockquote> -<p> -<i>Effects:</i> -</p> -<ul> -<li>Increment's the exception's handler count.</li> -<li>Places the exception on the stack of currently-caught exceptions if it is -not already there, linking the exception to the previous top of the stack.</li> -<li>Decrements the uncaught_exception count.</li> -</ul> -<p> -If the initialization of the catch parameter is trivial (e,g., there is no -formal catch parameter, or the parameter has no copy constructor), the calls to -<tt>__cxa_get_exception_ptr()</tt> and <tt>__cxa_begin_catch()</tt> may be -combined into a single call to <tt>__cxa_begin_catch()</tt>. -</p> -<p> -When the personality routine encounters a termination condition, it will call -<tt>__cxa_begin_catch()</tt> to mark the exception as handled and then call -<tt>terminate()</tt>, which shall not return to its caller. -</p> -<p> -<i>Returns:</i> The adjusted pointer to the exception object. -</p> -</blockquote> -</td> -<td>✓</td> -<td>✓</td> -<td>✓</td> -</tr> - -<tr> -<td> -<p> -<code>void __cxa_end_catch();</code> -</p> -<blockquote> -<p> -<i>Effects:</i> Locates the most recently caught exception and decrements its -handler count. Removes the exception from the caughtÓexception stack, if the -handler count goes to zero. Destroys the exception if the handler count goes to -zero, and the exception was not re-thrown by throw. Collaboration between -__cxa_rethrow() and __cxa_end_catch() is necessary to handle the last point. -Though implementation-defined, one possibility is for __cxa_rethrow() to set a -flag in the handlerCount member of the exception header to mark an exception -being rethrown. -</p> -</blockquote> -</td> -<td>✓</td> -<td>✓</td> -<td>✓</td> -</tr> - -<tr> -<td> -<p> -<code>std::type_info* __cxa_current_exception_type();</code> -</p> -<blockquote> -<p> -<i>Returns:</i> the type of the currently handled exception, or null if there -are no caught exceptions. -</p> -</blockquote> -</td> -<td>✓</td> -<td>✓</td> -<td>✓</td> -</tr> - -<tr> -<td> -<p> -<code>void __cxa_rethrow();</code> -</p> -<blockquote> -<p> -<i>Effects:</i> Marks the exception object on top of the caughtExceptions stack -(in an implementation-defined way) as being rethrown. If the caughtExceptions -stack is empty, it calls terminate() (see [C++FDIS] [except.throw], 15.1.8). It -then returns to the handler that called it, which must call __cxa_end_catch(), -perform any necessary cleanup, and finally call _Unwind_Resume() to continue -unwinding. -</p> -</blockquote> -</td> -<td>✓</td> -<td>✓</td> -<td>✓</td> -</tr> - -<tr> -<td> -<p> -<code>void* __cxa_current_primary_exception() throw();</code> -</p> -<blockquote> -<p> -<i>Effects:</i> Increments the ownership count of the currently handled -exception (if any) by one. -</p> -<p> -<i>Returns:</i> the type of the currently handled exception, or null if there -are no caught exceptions. -</p> -</blockquote> -</td> -<td>✓</td> -<td>✓</td> -<td>✓</td> -</tr> - -<tr> -<td> -<p> -<code>void __cxa_decrement_exception_refcount(void* primary_exception) throw();</code> -</p> -<blockquote> -<p> -<i>Effects:</i> Decrements the ownership count of the exception by 1, and on -zero calls <tt>_Unwind_DeleteException</tt> with the exception object. -</p> -</blockquote> -</td> -<td>✓</td> -<td>✓</td> -<td>✓</td> -</tr> - -<tr> -<td> -<p> -<code>__cxa_eh_globals* __cxa_get_globals() throw();</code> -</p> -<blockquote> -<p> -<i>Returns:</i> A pointer to the __cxa_eh_globals structure for the current -thread, initializing it if necessary. -</p> -</blockquote> -</td> -<td>✓</td> -<td>✓</td> -<td>✓</td> -</tr> - -<tr> -<td> -<p> -<code>__cxa_eh_globals* __cxa_get_globals_fast() throw();</code> -</p> -<blockquote> -<p> -<i>Requires:</i> At least one prior call to __cxa_get_globals has been made from -the current thread. -</p> -<p> -<i>Returns:</i> A pointer to the __cxa_eh_globals structure for the current -thread. -</p> -</blockquote> -</td> -<td>✓</td> -<td>✓</td> -<td>✓</td> -</tr> - -<tr> -<td> -<p> -<code>void __cxa_increment_exception_refcount(void* primary_exception) throw();</code> -</p> -<blockquote> -<p> -<i>Effects:</i> Increments the ownership count of the referenced exception. -</p> -</blockquote> -</td> -<td>✓</td> -<td>✓</td> -<td>✓</td> -</tr> - -<tr> -<td> -<p> -<code>void __cxa_rethrow_primary_exception(void* primary_exception);</code> -</p> -<blockquote> -<p> -<i>Effects:</i> Implements <tt>std::rethrow_exception(exception_ptr p)</tt>. -</p> -</blockquote> -</td> -<td>✓</td> -<td>✓</td> -<td>✓</td> -</tr> - -<tr> -<td> -<p> -<code>bool __cxa_uncaught_exception() throw();</code> -</p> -<blockquote> -<p> -<i>Effects:</i> -</p> -<p> -<i>Returns:</i> -</p> -</blockquote> -</td> -<td>✓</td> -<td>✓</td> -<td>✓</td> -</tr> - -<tr> -<td> -<p> -<code>_Unwind_Reason_Code __gxx_personality_v0 - (int, _Unwind_Action, _Unwind_Exception_Class, - struct _Unwind_Exception *, struct _Unwind_Context *);</code> -</p> -<blockquote> -<p> -<i>Effects:</i> -</p> -<p> -<i>Returns:</i> -</p> -</blockquote> -</td> -<td>✓</td> -<td>✓</td> -<td>✓</td> -</tr> - -<tr> -<td colspan=4 align="center">Guard objects</td> -</tr> - -<tr> -<td> -<p> -<code>int __cxa_guard_acquire(uint64_t* guard_object);</code> -</p> -<blockquote> -<p> -<i>Effects:</i> This function is called before initialization takes place. If -this function returns 1, either <code>__cxa_guard_release</code> or -<code>__cxa_guard_abort</code> must be called with the same argument. The first -byte of the <code>guard_object</code> is not modified by this function. -</p> -<p> -On Darwin the implementation checks for deadlock. -</p> -<p> -<i>Returns:</i> 1 if the initialization is not yet complete, otherwise 0. -</p> -</blockquote> -</td> -<td>✓</td> -<td>✓</td> -<td>✓</td> -</tr> - -<tr> -<td> -<p> -<code>void __cxa_guard_release(uint64_t*);</code> -</p> -<blockquote> -<p> -<i>Effects:</i> Sets the first byte of the guard object to a non-zero value. -This function is called after initialization is complete. A thread-safe -implementation will release the mutex acquired by __cxa_guard_acquire after -setting the first byte of the guard object. -</p> -</blockquote> -</td> -<td>✓</td> -<td>✓</td> -<td>✓</td> -</tr> - -<tr> -<td> -<p> -<code>void __cxa_guard_abort(uint64_t*);</code> -</p> -<blockquote> -<p> -<i>Effects:</i> This function is called if the initialization terminates by -throwing an exception. -</p> -</blockquote> -</td> -<td>✓</td> -<td>✓</td> -<td>✓</td> -</tr> - -<tr> -<td colspan=4 align="center">Vector construction and destruction</td> -</tr> - -<tr> -<td> -<p> -<code>void* __cxa_vec_new(size_t element_count, - size_t element_size, - size_t padding_size, - void (*constructor)(void*), - void (*destructor)(void*) );</code> -</p> -<blockquote> -<p> -<i>Effects:</i> -</p> -<p> -<i>Returns:</i> -</p> -</blockquote> -</td> -<td>✓</td> -<td>✓</td> -<td>✓</td> -</tr> - -<tr> -<td> -<p> -<code>void* __cxa_vec_new2(size_t element_count, - size_t element_size, - size_t padding_size, - void (*constructor)(void*), - void (*destructor)(void*), - void* (*alloc)(size_t), - void (*dealloc)(void*) );</code> -</p> -<blockquote> -<p> -<i>Effects:</i> -</p> -<p> -<i>Returns:</i> -</p> -</blockquote> -</td> -<td>✓</td> -<td>✓</td> -<td>✓</td> -</tr> - -<tr> -<td> -<p> -<code>void* __cxa_vec_new3(size_t element_count, - size_t element_size, - size_t padding_size, - void (*constructor)(void*), - void (*destructor)(void*), - void* (*alloc)(size_t), - void (*dealloc)(void*, size_t) );</code> -</p> -<blockquote> -<p> -<i>Effects:</i> -</p> -<p> -<i>Returns:</i> -</p> -</blockquote> -</td> -<td>✓</td> -<td>✓</td> -<td>✓</td> -</tr> - -<tr> -<td> -<p> -<code>void __cxa_vec_ctor(void* array_address, - size_t element_count, - size_t element_size, - void (*constructor)(void*), - void (*destructor)(void*) );</code> -</p> -<blockquote> -<p> -<i>Effects:</i> -</p> -</blockquote> -</td> -<td>✓</td> -<td>✓</td> -<td>✓</td> -</tr> - -<tr> -<td> -<p> -<code>void __cxa_vec_dtor(void* array_address, - size_t element_count, - size_t element_size, - void (*destructor)(void*) );</code> -</p> -<blockquote> -<p> -<i>Effects:</i> -</p> -</blockquote> -</td> -<td>✓</td> -<td>✓</td> -<td>✓</td> -</tr> - -<tr> -<td> -<p> -<code>void __cxa_vec_cleanup(void* array_address, - size_t element_count, - size_t element_size, - void (*destructor)(void*) );</code> -</p> -<blockquote> -<p> -<i>Effects:</i> -</p> -</blockquote> -</td> -<td>✓</td> -<td>✓</td> -<td>✓</td> -</tr> - -<tr> -<td> -<p> -<code>void __cxa_vec_delete(void* array_address, - size_t element_size, - size_t padding_size, - void (*destructor)(void*) );</code> -</p> -<blockquote> -<p> -<i>Effects:</i> -</p> -</blockquote> -</td> -<td>✓</td> -<td>✓</td> -<td>✓</td> -</tr> - -<tr> -<td> -<p> -<code>void __cxa_vec_delete2(void* array_address, - size_t element_size, - size_t padding_size, - void (*destructor)(void*), - void (*dealloc)(void*) );</code> -</p> -<blockquote> -<p> -<i>Effects:</i> -</p> -</blockquote> -</td> -<td>✓</td> -<td>✓</td> -<td>✓</td> -</tr> - -<tr> -<td> -<p> -<code>void __cxa_vec_delete3(void* __array_address, - size_t element_size, - size_t padding_size, - void (*destructor)(void*), - void (*dealloc) (void*, size_t));</code> -</p> -<blockquote> -<p> -<i>Effects:</i> -</p> -</blockquote> -</td> -<td>✓</td> -<td>✓</td> -<td>✓</td> -</tr> - -<tr> -<td> -<p> -<code>void __cxa_vec_cctor(void* dest_array, - void* src_array, - size_t element_count, - size_t element_size, - void (*constructor) (void*, void*), - void (*destructor)(void*) );</code> -</p> -<blockquote> -<p> -<i>Effects:</i> -</p> -</blockquote> -</td> -<td>✓</td> -<td>✓</td> -<td>✓</td> -</tr> - -<tr> -<td colspan=4 align="center">Handlers</td> -</tr> - -<tr> -<td> -<p> -<code>void (*__cxa_new_handler)();</code> -</p> -<blockquote> -<p> -The currently installed new handler. -</p> -</blockquote> -</td> -<td>✓</td> -<td>✓</td> -<td>✓</td> -</tr> - -<tr> -<td> -<p> -<code>void (*__cxa_terminate_handler)();</code> -</p> -<blockquote> -<p> -The currently installed terminate handler. -</p> -</blockquote> -</td> -<td>✓</td> -<td>✓</td> -<td>✓</td> -</tr> - -<tr> -<td> -<p> -<code>void (*__cxa_unexpected_handler)();</code> -</p> -<blockquote> -<p> -<i>Effects:</i> -</p> -</blockquote> -</td> -<td>✓</td> -<td>✓</td> -<td>✓</td> -</tr> - - - -<tr> -<td colspan=4 align="center">Utilities</td> -</tr> - -<tr> -<td> -<p> -<code>[[noreturn]] void __cxa_bad_cast()</code> -</p> -<blockquote> -<p> -<i>Effects:</i> Throws an exception of type <tt>bad_cast</tt>. -</p> -</blockquote> -</td> -<td>✓</td> -<td>✓</td> -<td>✓</td> -</tr> - -<tr> -<td> -<p> -<code>[[noreturn]] void __cxa_bad_typeid();</code> -</p> -<blockquote> -<p> -<i>Effects:</i> Throws an exception of type <tt>bad_typeid</tt>. -</p> -</blockquote> -</td> -<td>✓</td> -<td>✓</td> -<td>✓</td> -</tr> - -<tr> -<td> -<p> -<code>void __cxa_pure_virtual(void);</code> -</p> -<blockquote> -<p> -<i>Effects:</i> Called if the user calls a non-overridden pure virtual function, -which has undefined behavior according to the C++ Standard. Ends the program. -</p> -</blockquote> -</td> -<td>✓</td> -<td>✓</td> -<td>✓</td> -</tr> - -<tr> -<td> -<p> -<code>void __cxa_call_unexpected (void*) __attribute__((noreturn));</code> -</p> -<blockquote> -<p> -<i>Effects:</i> Handles re-checking the exception specification if -unexpectedHandler throws, and if <tt>bad_exception</tt> needs to be thrown. -Called from the compiler. -</p> -</blockquote> -</td> -<td>✓</td> -<td>✓</td> -<td>✓</td> -</tr> - -<tr> -<td> -<p> -<code>char* __cxa_demangle(const char* mangled_name, - char* output_buffer, - size_t* length, - int* status);</code> -</p> -<blockquote> -<p> -<i>Effects:</i> -</p> -<p> -<i>Returns:</i> -</p> -</blockquote> -</td> -<td>✓</td> -<td>✓</td> -<td>✓</td> -</tr> - -<tr> -<td> -<p> -<code>void* - __dynamic_cast(const void* __src_ptr, - const __class_type_info* __src_type, - const __class_type_info* __dst_type, - ptrdiff_t __src2dst);</code> -</p> -<blockquote> -<p> -<i>Effects:</i> -</p> -<p> -<i>Returns:</i> -</p> -</blockquote> -</td> -<td>✓</td> -<td>✓</td> -<td>✓</td> -</tr> - -</table> - -<!-- -000000000000d570 (__DATA,__const) external typeinfo for char32_t -000000000000cfd0 (__DATA,__const) external typeinfo for std::nullptr_t -000000000000d520 (__DATA,__const) external typeinfo for char16_t -000000000000d580 (__DATA,__const) external typeinfo for char32_t* -000000000000cfe0 (__DATA,__const) external typeinfo for std::nullptr_t* -000000000000d530 (__DATA,__const) external typeinfo for char16_t* -000000000000d5a0 (__DATA,__const) external typeinfo for char32_t const* -000000000000d000 (__DATA,__const) external typeinfo for std::nullptr_t const* -000000000000d550 (__DATA,__const) external typeinfo for char16_t const* -000000000000d190 (__DATA,__const) external typeinfo for signed char const* -000000000000d050 (__DATA,__const) external typeinfo for bool const* -000000000000d0f0 (__DATA,__const) external typeinfo for char const* -000000000000d4b0 (__DATA,__const) external typeinfo for double const* -000000000000d500 (__DATA,__const) external typeinfo for long double const* -000000000000d460 (__DATA,__const) external typeinfo for float const* -000000000000d140 (__DATA,__const) external typeinfo for unsigned char const* -000000000000d280 (__DATA,__const) external typeinfo for int const* -000000000000d2d0 (__DATA,__const) external typeinfo for unsigned int const* -000000000000d320 (__DATA,__const) external typeinfo for long const* -000000000000d370 (__DATA,__const) external typeinfo for unsigned long const* -000000000000d1e0 (__DATA,__const) external typeinfo for short const* -000000000000d230 (__DATA,__const) external typeinfo for unsigned short const* -000000000000cfb0 (__DATA,__const) external typeinfo for void const* -000000000000d0a0 (__DATA,__const) external typeinfo for wchar_t const* -000000000000d3c0 (__DATA,__const) external typeinfo for long long const* -000000000000d410 (__DATA,__const) external typeinfo for unsigned long long const* -000000000000d170 (__DATA,__const) external typeinfo for signed char* -000000000000d030 (__DATA,__const) external typeinfo for bool* -000000000000d0d0 (__DATA,__const) external typeinfo for char* -000000000000d490 (__DATA,__const) external typeinfo for double* -000000000000d4e0 (__DATA,__const) external typeinfo for long double* -000000000000d440 (__DATA,__const) external typeinfo for float* -000000000000d120 (__DATA,__const) external typeinfo for unsigned char* -000000000000d260 (__DATA,__const) external typeinfo for int* -000000000000d2b0 (__DATA,__const) external typeinfo for unsigned int* -000000000000d300 (__DATA,__const) external typeinfo for long* -000000000000d350 (__DATA,__const) external typeinfo for unsigned long* -000000000000d1c0 (__DATA,__const) external typeinfo for short* -000000000000d210 (__DATA,__const) external typeinfo for unsigned short* -000000000000cf90 (__DATA,__const) external typeinfo for void* -000000000000d080 (__DATA,__const) external typeinfo for wchar_t* -000000000000d3a0 (__DATA,__const) external typeinfo for long long* -000000000000d3f0 (__DATA,__const) external typeinfo for unsigned long long* -000000000000d160 (__DATA,__const) external typeinfo for signed char -000000000000d020 (__DATA,__const) external typeinfo for bool -000000000000d0c0 (__DATA,__const) external typeinfo for char -000000000000d480 (__DATA,__const) external typeinfo for double -000000000000d4d0 (__DATA,__const) external typeinfo for long double -000000000000d430 (__DATA,__const) external typeinfo for float -000000000000d110 (__DATA,__const) external typeinfo for unsigned char -000000000000d250 (__DATA,__const) external typeinfo for int -000000000000d2a0 (__DATA,__const) external typeinfo for unsigned int -000000000000d2f0 (__DATA,__const) external typeinfo for long -000000000000d340 (__DATA,__const) external typeinfo for unsigned long -000000000000d1b0 (__DATA,__const) external typeinfo for short -000000000000d200 (__DATA,__const) external typeinfo for unsigned short -000000000000cf78 (__DATA,__const) external typeinfo for void -000000000000d070 (__DATA,__const) external typeinfo for wchar_t -000000000000d390 (__DATA,__const) external typeinfo for long long -000000000000d3e0 (__DATA,__const) external typeinfo for unsigned long long -00000000000093f9 (__TEXT,__cstring) external typeinfo name for char32_t -0000000000009351 (__TEXT,__cstring) external typeinfo name for std::nullptr_t -00000000000093ed (__TEXT,__cstring) external typeinfo name for char16_t -0000000000009470 (__TEXT,__cstring) external typeinfo name for __cxxabiv1::__enum_type_info -0000000000009410 (__TEXT,__cstring) external typeinfo name for __cxxabiv1::__array_type_info -0000000000009290 (__TEXT,__cstring) external typeinfo name for __cxxabiv1::__class_type_info -00000000000094a0 (__TEXT,__cstring) external typeinfo name for __cxxabiv1::__pbase_type_info -00000000000094d0 (__TEXT,__cstring) external typeinfo name for __cxxabiv1::__pointer_type_info -0000000000009440 (__TEXT,__cstring) external typeinfo name for __cxxabiv1::__function_type_info -00000000000092c0 (__TEXT,__cstring) external typeinfo name for __cxxabiv1::__si_class_type_info -00000000000092f0 (__TEXT,__cstring) external typeinfo name for __cxxabiv1::__vmi_class_type_info -0000000000009320 (__TEXT,__cstring) external typeinfo name for __cxxabiv1::__fundamental_type_info -0000000000009500 (__TEXT,__cstring) external typeinfo name for __cxxabiv1::__pointer_to_member_type_info -00000000000093fc (__TEXT,__cstring) external typeinfo name for char32_t* -0000000000009354 (__TEXT,__cstring) external typeinfo name for std::nullptr_t* -00000000000093f0 (__TEXT,__cstring) external typeinfo name for char16_t* -0000000000009400 (__TEXT,__cstring) external typeinfo name for char32_t const* -0000000000009358 (__TEXT,__cstring) external typeinfo name for std::nullptr_t const* -00000000000093f4 (__TEXT,__cstring) external typeinfo name for char16_t const* -0000000000009386 (__TEXT,__cstring) external typeinfo name for signed char const* -0000000000009362 (__TEXT,__cstring) external typeinfo name for bool const* -0000000000009374 (__TEXT,__cstring) external typeinfo name for char const* -00000000000093e0 (__TEXT,__cstring) external typeinfo name for double const* -00000000000093e9 (__TEXT,__cstring) external typeinfo name for long double const* -00000000000093d7 (__TEXT,__cstring) external typeinfo name for float const* -000000000000937d (__TEXT,__cstring) external typeinfo name for unsigned char const* -00000000000093a1 (__TEXT,__cstring) external typeinfo name for int const* -00000000000093aa (__TEXT,__cstring) external typeinfo name for unsigned int const* -00000000000093b3 (__TEXT,__cstring) external typeinfo name for long const* -00000000000093bc (__TEXT,__cstring) external typeinfo name for unsigned long const* -000000000000938f (__TEXT,__cstring) external typeinfo name for short const* -0000000000009398 (__TEXT,__cstring) external typeinfo name for unsigned short const* -000000000000934d (__TEXT,__cstring) external typeinfo name for void const* -000000000000936b (__TEXT,__cstring) external typeinfo name for wchar_t const* -00000000000093c5 (__TEXT,__cstring) external typeinfo name for long long const* -00000000000093ce (__TEXT,__cstring) external typeinfo name for unsigned long long const* -0000000000009383 (__TEXT,__cstring) external typeinfo name for signed char* -000000000000935f (__TEXT,__cstring) external typeinfo name for bool* -0000000000009371 (__TEXT,__cstring) external typeinfo name for char* -00000000000093dd (__TEXT,__cstring) external typeinfo name for double* -00000000000093e6 (__TEXT,__cstring) external typeinfo name for long double* -00000000000093d4 (__TEXT,__cstring) external typeinfo name for float* -000000000000937a (__TEXT,__cstring) external typeinfo name for unsigned char* -000000000000939e (__TEXT,__cstring) external typeinfo name for int* -00000000000093a7 (__TEXT,__cstring) external typeinfo name for unsigned int* -00000000000093b0 (__TEXT,__cstring) external typeinfo name for long* -00000000000093b9 (__TEXT,__cstring) external typeinfo name for unsigned long* -000000000000938c (__TEXT,__cstring) external typeinfo name for short* -0000000000009395 (__TEXT,__cstring) external typeinfo name for unsigned short* -000000000000934a (__TEXT,__cstring) external typeinfo name for void* -0000000000009368 (__TEXT,__cstring) external typeinfo name for wchar_t* -00000000000093c2 (__TEXT,__cstring) external typeinfo name for long long* -00000000000093cb (__TEXT,__cstring) external typeinfo name for unsigned long long* -0000000000009381 (__TEXT,__cstring) external typeinfo name for signed char -000000000000935d (__TEXT,__cstring) external typeinfo name for bool -000000000000936f (__TEXT,__cstring) external typeinfo name for char -00000000000093db (__TEXT,__cstring) external typeinfo name for double -00000000000093e4 (__TEXT,__cstring) external typeinfo name for long double -00000000000093d2 (__TEXT,__cstring) external typeinfo name for float -0000000000009378 (__TEXT,__cstring) external typeinfo name for unsigned char -000000000000939c (__TEXT,__cstring) external typeinfo name for int -00000000000093a5 (__TEXT,__cstring) external typeinfo name for unsigned int -00000000000093ae (__TEXT,__cstring) external typeinfo name for long -00000000000093b7 (__TEXT,__cstring) external typeinfo name for unsigned long -000000000000938a (__TEXT,__cstring) external typeinfo name for short -0000000000009393 (__TEXT,__cstring) external typeinfo name for unsigned short -0000000000009348 (__TEXT,__cstring) external typeinfo name for void -0000000000009366 (__TEXT,__cstring) external typeinfo name for wchar_t -00000000000093c0 (__TEXT,__cstring) external typeinfo name for long long -00000000000093c9 (__TEXT,__cstring) external typeinfo name for unsigned long long -000000000000ce30 (__DATA,__const) external vtable for __cxxabiv1::__enum_type_info -000000000000cdb0 (__DATA,__const) external vtable for __cxxabiv1::__array_type_info -000000000000cbe0 (__DATA,__const) external vtable for __cxxabiv1::__class_type_info -000000000000ce70 (__DATA,__const) external vtable for __cxxabiv1::__pbase_type_info -000000000000cec0 (__DATA,__const) external vtable for __cxxabiv1::__pointer_type_info -000000000000cdf0 (__DATA,__const) external vtable for __cxxabiv1::__function_type_info -000000000000cc40 (__DATA,__const) external vtable for __cxxabiv1::__si_class_type_info -000000000000cca0 (__DATA,__const) external vtable for __cxxabiv1::__vmi_class_type_info -000000000000cd70 (__DATA,__const) external vtable for __cxxabiv1::__fundamental_type_info -000000000000cf10 (__DATA,__const) external vtable for __cxxabiv1::__pointer_to_member_type_info - - (undefined) external ___stack_chk_fail (from libSystem) - (undefined) external ___stack_chk_guard (from libSystem) - (undefined) external ___stderrp (from libSystem) - (undefined) external ___strcat_chk (from libSystem) - (undefined) external _abort (from libSystem) - (undefined) external _calloc (from libSystem) - (undefined) external _dlsym (from libSystem) - (undefined) external _free (from libSystem) - (undefined) external _malloc (from libSystem) - (undefined) external _memcpy (from libSystem) - (undefined) external _pthread_getspecific (from libSystem) - (undefined) external _pthread_key_create (from libSystem) - (undefined) external _pthread_mutex_init (from libSystem) - (undefined) external _pthread_mutex_lock (from libSystem) - (undefined) external _pthread_mutex_unlock (from libSystem) - (undefined) external _pthread_mutexattr_init (from libSystem) - (undefined) external _pthread_mutexattr_settype (from libSystem) - (undefined) external _pthread_once (from libSystem) - (undefined) external _pthread_setspecific (from libSystem) - (undefined) external _realloc (from libSystem) - (undefined) external _strcmp (from libSystem) - (undefined) external _strcpy (from libSystem) - (undefined) external _strlen (from libSystem) - (undefined) external _strncmp (from libSystem) - (undefined) external _vasprintf (from libSystem) - (undefined) external _vfprintf (from libSystem) - (undefined) external dyld_stub_binder (from libSystem) - (undefined) external __Unwind_DeleteException (from libSystem) - (undefined) external __Unwind_GetIP (from libSystem) - (undefined) external __Unwind_GetLanguageSpecificData (from libSystem) - (undefined) external __Unwind_GetRegionStart (from libSystem) - (undefined) external __Unwind_RaiseException (from libSystem) - (undefined) external __Unwind_Resume_or_Rethrow (from libSystem) - (undefined) external __Unwind_SetGR (from libSystem) - (undefined) external __Unwind_SetIP (from libSystem) - (undefined) external ___bzero (from libSystem) - --> - -</body> -</html> diff --git a/chromium/buildtools/third_party/libunwind/trunk/.arcconfig b/chromium/buildtools/third_party/libunwind/trunk/.arcconfig deleted file mode 100644 index 97a4bf1b29d..00000000000 --- a/chromium/buildtools/third_party/libunwind/trunk/.arcconfig +++ /dev/null @@ -1,4 +0,0 @@ -{ - "project_id" : "libunwind", - "conduit_uri" : "https://reviews.llvm.org/" -} diff --git a/chromium/buildtools/third_party/libunwind/trunk/.clang-format b/chromium/buildtools/third_party/libunwind/trunk/.clang-format deleted file mode 100644 index 5bead5f39dd..00000000000 --- a/chromium/buildtools/third_party/libunwind/trunk/.clang-format +++ /dev/null @@ -1,2 +0,0 @@ -BasedOnStyle: LLVM - diff --git a/chromium/buildtools/third_party/libunwind/trunk/CMakeLists.txt b/chromium/buildtools/third_party/libunwind/trunk/CMakeLists.txt deleted file mode 100644 index eef7479dfdf..00000000000 --- a/chromium/buildtools/third_party/libunwind/trunk/CMakeLists.txt +++ /dev/null @@ -1,342 +0,0 @@ -#=============================================================================== -# Setup Project -#=============================================================================== - -cmake_minimum_required(VERSION 3.4.3) - -if (POLICY CMP0042) - 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) - 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_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) - if (NOT HAD_ERROR) - string(REGEX REPLACE "[ \t]*[\r\n]+[ \t]*" ";" - CONFIG_OUTPUT ${CONFIG_OUTPUT}) - else() - string(REPLACE ";" " " CONFIG_COMMAND_STR "${CONFIG_COMMAND}") - message(STATUS "${CONFIG_COMMAND_STR}") - message(FATAL_ERROR "llvm-config failed with status ${HAD_ERROR}") - endif() - - list(GET CONFIG_OUTPUT 0 INCLUDE_DIR) - list(GET CONFIG_OUTPUT 1 LLVM_OBJ_ROOT) - list(GET CONFIG_OUTPUT 2 MAIN_SRC_DIR) - - 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_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 " - "or -DLLVM_PATH=path/to/llvm-source-root.") - endif() - - if (EXISTS ${LLVM_CMAKE_PATH}) - list(APPEND CMAKE_MODULE_PATH "${LLVM_CMAKE_PATH}") - include("${LLVM_CMAKE_PATH}/AddLLVM.cmake") - include("${LLVM_CMAKE_PATH}/HandleLLVMOptions.cmake") - else() - message(FATAL_ERROR "Not found: ${LLVM_CMAKE_PATH}") - endif() - - set(PACKAGE_NAME libunwind) - set(PACKAGE_VERSION 5.0.0svn) - set(PACKAGE_STRING "${PACKAGE_NAME} ${PACKAGE_VERSION}") - set(PACKAGE_BUGREPORT "llvm-bugs@lists.llvm.org") - - if (EXISTS ${LLVM_MAIN_SRC_DIR}/utils/lit/lit.py) - set(LLVM_LIT ${LLVM_MAIN_SRC_DIR}/utils/lit/lit.py) - else() - # Seek installed Lit. - find_program(LLVM_LIT "lit.py" ${LLVM_MAIN_SRC_DIR}/utils/lit - DOC "Path to lit.py") - endif() - - if (LLVM_LIT) - # Define the default arguments to use with 'lit', and an option for the user - # to override. - set(LIT_ARGS_DEFAULT "-sv") - if (MSVC OR XCODE) - set(LIT_ARGS_DEFAULT "${LIT_ARGS_DEFAULT} --no-progress-bar") - endif() - set(LLVM_LIT_ARGS "${LIT_ARGS_DEFAULT}" CACHE STRING "Default options for lit") - - # On Win32 hosts, provide an option to specify the path to the GnuWin32 tools. - if (WIN32 AND NOT CYGWIN) - set(LLVM_LIT_TOOLS_DIR "" CACHE PATH "Path to GnuWin32 tools") - endif() - else() - set(LLVM_INCLUDE_TESTS OFF) - endif() - - set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib${LLVM_LIBDIR_SUFFIX}) - set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib${LLVM_LIBDIR_SUFFIX}) -else() - set(LLVM_MAIN_SRC_DIR "${CMAKE_SOURCE_DIR}" CACHE PATH "Path to LLVM source tree") - set(LLVM_LIT "${CMAKE_SOURCE_DIR}/utils/lit/lit.py") -endif() - -#=============================================================================== -# Setup CMake Options -#=============================================================================== -include(HandleCompilerRT) - -# Define options. -option(LIBUNWIND_BUILD_32_BITS "Build 32 bit libunwind" ${LLVM_BUILD_32_BITS}) -option(LIBUNWIND_ENABLE_ASSERTIONS "Enable assertions independent of build mode." ON) -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)") -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 - message(STATUS "Building 32 bits executables and libraries.") - endif() -elseif(LIBUNWIND_BUILD_32_BITS) - message(FATAL_ERROR "LIBUNWIND_BUILD_32_BITS=ON is not supported on this platform.") -endif() - -#=============================================================================== -# Configure System -#=============================================================================== - -# Add path for custom modules -set(CMAKE_MODULE_PATH - "${CMAKE_CURRENT_SOURCE_DIR}/cmake" - ${CMAKE_MODULE_PATH}) - -set(LIBUNWIND_COMPILER ${CMAKE_CXX_COMPILER}) -set(LIBUNWIND_SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}) -set(LIBUNWIND_BINARY_DIR ${CMAKE_CURRENT_BINARY_DIR}) -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 "") -set(LIBUNWIND_COMPILE_FLAGS "") -set(LIBUNWIND_LINK_FLAGS "") - -# Get required flags. -macro(append_if list condition var) - if (${condition}) - list(APPEND ${list} ${var}) - endif() -endmacro() - -macro(add_target_flags_if condition var) - if (${condition}) - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${var}") - set(CMAKE_C_FLAGS "${CMAKE_C_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}") -add_target_flags_if(LIBUNWIND_GCC_TOOLCHAIN - "--gcc-toolchain=${LIBUNWIND_GCC_TOOLCHAIN}") -add_target_flags_if(LIBUNWIND_SYSROOT - "--sysroot=${LIBUNWIND_SYSROOT}") - -# Configure compiler. -include(config-ix) - -if (LIBUNWIND_USE_COMPILER_RT) - list(APPEND LIBUNWIND_LINK_FLAGS "-rtlib=compiler-rt") -endif() - -#=============================================================================== -# Setup Compiler Flags -#=============================================================================== - -append_if(LIBUNWIND_COMPILE_FLAGS LIBUNWIND_HAS_WERROR_FLAG -Werror=return-type) - -# Get warning flags -append_if(LIBUNWIND_COMPILE_FLAGS LIBUNWIND_HAS_W_FLAG -W) -append_if(LIBUNWIND_COMPILE_FLAGS LIBUNWIND_HAS_WALL_FLAG -Wall) -append_if(LIBUNWIND_COMPILE_FLAGS LIBUNWIND_HAS_WCHAR_SUBSCRIPTS_FLAG -Wchar-subscripts) -append_if(LIBUNWIND_COMPILE_FLAGS LIBUNWIND_HAS_WCONVERSION_FLAG -Wconversion) -append_if(LIBUNWIND_COMPILE_FLAGS LIBUNWIND_HAS_WMISMATCHED_TAGS_FLAG -Wmismatched-tags) -append_if(LIBUNWIND_COMPILE_FLAGS LIBUNWIND_HAS_WMISSING_BRACES_FLAG -Wmissing-braces) -append_if(LIBUNWIND_COMPILE_FLAGS LIBUNWIND_HAS_WNEWLINE_EOF_FLAG -Wnewline-eof) -append_if(LIBUNWIND_COMPILE_FLAGS LIBUNWIND_HAS_WNO_UNUSED_FUNCTION_FLAG -Wno-unused-function) -append_if(LIBUNWIND_COMPILE_FLAGS LIBUNWIND_HAS_WSHADOW_FLAG -Wshadow) -append_if(LIBUNWIND_COMPILE_FLAGS LIBUNWIND_HAS_WSHORTEN_64_TO_32_FLAG -Wshorten-64-to-32) -append_if(LIBUNWIND_COMPILE_FLAGS LIBUNWIND_HAS_WSIGN_COMPARE_FLAG -Wsign-compare) -append_if(LIBUNWIND_COMPILE_FLAGS LIBUNWIND_HAS_WSIGN_CONVERSION_FLAG -Wsign-conversion) -append_if(LIBUNWIND_COMPILE_FLAGS LIBUNWIND_HAS_WSTRICT_ALIASING_FLAG -Wstrict-aliasing=2) -append_if(LIBUNWIND_COMPILE_FLAGS LIBUNWIND_HAS_WSTRICT_OVERFLOW_FLAG -Wstrict-overflow=4) -append_if(LIBUNWIND_COMPILE_FLAGS LIBUNWIND_HAS_WUNUSED_PARAMETER_FLAG -Wunused-parameter) -append_if(LIBUNWIND_COMPILE_FLAGS LIBUNWIND_HAS_WUNUSED_VARIABLE_FLAG -Wunused-variable) -append_if(LIBUNWIND_COMPILE_FLAGS LIBUNWIND_HAS_WWRITE_STRINGS_FLAG -Wwrite-strings) -append_if(LIBUNWIND_COMPILE_FLAGS LIBUNWIND_HAS_WUNDEF_FLAG -Wundef) - -if (LIBUNWIND_ENABLE_WERROR) - append_if(LIBUNWIND_COMPILE_FLAGS LIBUNWIND_HAS_WERROR_FLAG -Werror) - append_if(LIBUNWIND_COMPILE_FLAGS LIBUNWIND_HAS_WX_FLAG -WX) -else() - append_if(LIBUNWIND_COMPILE_FLAGS LIBUNWIND_HAS_WNO_ERROR_FLAG -Wno-error) - append_if(LIBUNWIND_COMPILE_FLAGS LIBUNWIND_HAS_NO_WX_FLAG -WX-) -endif() - -if (LIBUNWIND_ENABLE_PEDANTIC) - append_if(LIBUNWIND_COMPILE_FLAGS LIBUNWIND_HAS_PEDANTIC_FLAG -pedantic) -endif() - -# Get feature flags. -# Exceptions -# Catches C++ exceptions only and tells the compiler to assume that extern C -# functions never throw a C++ exception. -append_if(LIBUNWIND_CXX_FLAGS LIBUNWIND_HAS_FSTRICT_ALIASING_FLAG -fstrict-aliasing) -append_if(LIBUNWIND_CXX_FLAGS LIBUNWIND_HAS_EHSC_FLAG -EHsc) - -append_if(LIBUNWIND_C_FLAGS LIBUNWIND_HAS_FUNWIND_TABLES -funwind-tables) - -# Assert -string(TOUPPER "${CMAKE_BUILD_TYPE}" uppercase_CMAKE_BUILD_TYPE) -if (LIBUNWIND_ENABLE_ASSERTIONS) - # MSVC doesn't like _DEBUG on release builds. See PR 4379. - if (NOT MSVC) - list(APPEND LIBUNWIND_COMPILE_FLAGS -D_DEBUG) - endif() - - # On Release builds cmake automatically defines NDEBUG, so we - # explicitly undefine it: - if (uppercase_CMAKE_BUILD_TYPE STREQUAL "RELEASE") - list(APPEND LIBUNWIND_COMPILE_FLAGS -UNDEBUG) - endif() -else() - if (NOT uppercase_CMAKE_BUILD_TYPE STREQUAL "RELEASE") - list(APPEND LIBUNWIND_COMPILE_FLAGS -DNDEBUG) - endif() -endif() - -# Cross-unwinding -if (NOT LIBUNWIND_ENABLE_CROSS_UNWINDING) - 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 - # define this macro for any supported target at present. Therefore, here we - # provide the option to explicitly enable support for WMMX registers in the - # unwinder. - list(APPEND LIBUNWIND_COMPILE_FLAGS -D__ARM_WMMX) -endif() - -# This is the _ONLY_ place where add_definitions is called. -if (MSVC) - add_definitions(-D_CRT_SECURE_NO_WARNINGS) -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) diff --git a/chromium/buildtools/third_party/libunwind/trunk/LICENSE.TXT b/chromium/buildtools/third_party/libunwind/trunk/LICENSE.TXT deleted file mode 100644 index fb77e1b74a0..00000000000 --- a/chromium/buildtools/third_party/libunwind/trunk/LICENSE.TXT +++ /dev/null @@ -1,76 +0,0 @@ -============================================================================== -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. diff --git a/chromium/buildtools/third_party/libunwind/trunk/cmake/Modules/HandleCompilerRT.cmake b/chromium/buildtools/third_party/libunwind/trunk/cmake/Modules/HandleCompilerRT.cmake deleted file mode 100644 index 9bf88bb4c27..00000000000 --- a/chromium/buildtools/third_party/libunwind/trunk/cmake/Modules/HandleCompilerRT.cmake +++ /dev/null @@ -1,58 +0,0 @@ -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() diff --git a/chromium/buildtools/third_party/libunwind/trunk/cmake/config-ix.cmake b/chromium/buildtools/third_party/libunwind/trunk/cmake/config-ix.cmake deleted file mode 100644 index 2d4da649f6d..00000000000 --- a/chromium/buildtools/third_party/libunwind/trunk/cmake/config-ix.cmake +++ /dev/null @@ -1,94 +0,0 @@ - -include(CheckCCompilerFlag) -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(-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(-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(-Wno-unused-function LIBUNWIND_HAS_WNO_UNUSED_FUNCTION_FLAG) -check_cxx_compiler_flag(-Wunused-variable LIBUNWIND_HAS_WUNUSED_VARIABLE_FLAG) -check_cxx_compiler_flag(-Wunused-parameter LIBUNWIND_HAS_WUNUSED_PARAMETER_FLAG) -check_cxx_compiler_flag(-Wstrict-aliasing LIBUNWIND_HAS_WSTRICT_ALIASING_FLAG) -check_cxx_compiler_flag(-Wstrict-overflow LIBUNWIND_HAS_WSTRICT_OVERFLOW_FLAG) -check_cxx_compiler_flag(-Wwrite-strings LIBUNWIND_HAS_WWRITE_STRINGS_FLAG) -check_cxx_compiler_flag(-Wchar-subscripts LIBUNWIND_HAS_WCHAR_SUBSCRIPTS_FLAG) -check_cxx_compiler_flag(-Wmismatched-tags LIBUNWIND_HAS_WMISMATCHED_TAGS_FLAG) -check_cxx_compiler_flag(-Wmissing-braces LIBUNWIND_HAS_WMISSING_BRACES_FLAG) -check_cxx_compiler_flag(-Wshorten-64-to-32 LIBUNWIND_HAS_WSHORTEN_64_TO_32_FLAG) -check_cxx_compiler_flag(-Wsign-conversion LIBUNWIND_HAS_WSIGN_CONVERSION_FLAG) -check_cxx_compiler_flag(-Wsign-compare LIBUNWIND_HAS_WSIGN_COMPARE_FLAG) -check_cxx_compiler_flag(-Wshadow LIBUNWIND_HAS_WSHADOW_FLAG) -check_cxx_compiler_flag(-Wconversion LIBUNWIND_HAS_WCONVERSION_FLAG) -check_cxx_compiler_flag(-Wnewline-eof LIBUNWIND_HAS_WNEWLINE_EOF_FLAG) -check_cxx_compiler_flag(-Wundef LIBUNWIND_HAS_WUNDEF_FLAG) -check_cxx_compiler_flag(-pedantic LIBUNWIND_HAS_PEDANTIC_FLAG) -check_cxx_compiler_flag(-Werror LIBUNWIND_HAS_WERROR_FLAG) -check_cxx_compiler_flag(-Wno-error LIBUNWIND_HAS_WNO_ERROR_FLAG) -check_cxx_compiler_flag(/WX LIBUNWIND_HAS_WX_FLAG) -check_cxx_compiler_flag(/WX- LIBUNWIND_HAS_NO_WX_FLAG) -check_cxx_compiler_flag(/EHsc LIBUNWIND_HAS_EHSC_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(dl dladdr "" LIBUNWIND_HAS_DL_LIB) -check_library_exists(pthread pthread_once "" LIBUNWIND_HAS_PTHREAD_LIB) - diff --git a/chromium/buildtools/third_party/libunwind/trunk/docs/BuildingLibunwind.rst b/chromium/buildtools/third_party/libunwind/trunk/docs/BuildingLibunwind.rst deleted file mode 100644 index 6aa45561bc9..00000000000 --- a/chromium/buildtools/third_party/libunwind/trunk/docs/BuildingLibunwind.rst +++ /dev/null @@ -1,167 +0,0 @@ -.. _BuildingLibunwind: - -================== -Building libunwind -================== - -.. contents:: - :local: - -.. _build instructions: - -Getting Started -=============== - -On Mac OS, the easiest way to get this library is to link with -lSystem. -However if you want to build tip-of-trunk from here (getting the bleeding -edge), read on. - -The basic steps needed to build libc++ are: - -#. Checkout LLVM: - - * ``cd where-you-want-llvm-to-live`` - * ``svn co http://llvm.org/svn/llvm-project/llvm/trunk llvm`` - -#. Checkout libunwind: - - * ``cd where-you-want-llvm-to-live`` - * ``cd llvm/runtimes`` - * ``svn co http://llvm.org/svn/llvm-project/libunwind/trunk libunwind`` - -#. Configure and build libunwind: - - CMake is the only supported configuration system. - - Clang is the preferred compiler when building and using libunwind. - - * ``cd where you want to build llvm`` - * ``mkdir build`` - * ``cd build`` - * ``cmake -G <generator> [options] <path to llvm sources>`` - - For more information about configuring libunwind see :ref:`CMake Options`. - - * ``make unwind`` --- will build libunwind. - * ``make check-unwind`` --- will run the test suite. - - Shared and static libraries for libunwind should now be present in llvm/build/lib. - -#. **Optional**: Install libunwind - - If your system already provides an unwinder, it is important to be careful - not to replace it. Remember Use the CMake option ``CMAKE_INSTALL_PREFIX`` to - select a safe place to install libunwind. - - * ``make install-unwind`` --- Will install the libraries and the headers - - -It is sometimes beneficial to build outside of the LLVM tree. An out-of-tree -build would look like this: - -.. code-block:: bash - - $ cd where-you-want-libunwind-to-live - $ # Check out llvm, and libunwind - $ ``svn co http://llvm.org/svn/llvm-project/llvm/trunk llvm`` - $ ``svn co http://llvm.org/svn/llvm-project/libunwind/trunk libunwind`` - $ cd where-you-want-to-build - $ mkdir build && cd build - $ export CC=clang CXX=clang++ - $ cmake -DLLVM_PATH=path/to/llvm \ - path/to/libunwind - $ make - - -.. _CMake Options: - -CMake Options -============= - -Here are some of the CMake variables that are used often, along with a -brief explanation and LLVM-specific notes. For full documentation, check the -CMake docs or execute ``cmake --help-variable VARIABLE_NAME``. - -**CMAKE_BUILD_TYPE**:STRING - Sets the build type for ``make`` based generators. Possible values are - Release, Debug, RelWithDebInfo and MinSizeRel. On systems like Visual Studio - the user sets the build type with the IDE settings. - -**CMAKE_INSTALL_PREFIX**:PATH - Path where LLVM will be installed if "make install" is invoked or the - "INSTALL" target is built. - -**CMAKE_CXX_COMPILER**:STRING - The C++ compiler to use when building and testing libunwind. - - -.. _libunwind-specific options: - -libunwind specific options --------------------------- - -.. option:: LIBUNWIND_BUILD_32_BITS:BOOL - - **Default**: Same as LLVM_BUILD_32_BITS - - Toggle whether libunwind should be built with -m32. - -.. option:: LIBUNWIND_ENABLE_ASSERTIONS:BOOL - - **Default**: ``ON`` - - Toggle assertions independent of the build mode. - -.. option:: LIBUNWIND_ENABLE_PEDANTIC:BOOL - - **Default**: ``ON`` - - Compile with -Wpedantic. - -.. option:: LIBUNWIND_ENABLE_WERROR:BOOL - - **Default**: ``ON`` - - Compile with -Werror - -.. option:: LIBUNWIND_ENABLE_SHARED:BOOL - - **Default**: ``ON`` - - Build libunwind as a shared library. - -.. option:: LIBUNWIND_ENABLE_STATIC:BOOL - - **Default**: ``ON`` - - Build libunwind as a static archive. - -.. option:: LIBUNWIND_ENABLE_CROSS_UNWINDING:BOOL - - **Default**: ``OFF`` - - Enable cross-platform unwinding support. - -.. option:: LIBUNWIND_ENABLE_ARM_WMMX:BOOL - - **Default**: ``OFF`` - - Enable unwinding support for ARM WMMX registers. - -.. option:: LIBUNWIND_ENABLE_THREADS:BOOL - - **Default**: ``ON`` - - Build libunwind with threading support. - -.. option:: LIBUNWIND_TARGET_TRIPLE:STRING - - Target triple for cross compiling - -.. option:: LIBUNWIND_GCC_TOOLCHAIN:PATH - - GCC toolchain for cross compiling - -.. option:: LIBUNWIND_SYSROOT - - Sysroot for cross compiling diff --git a/chromium/buildtools/third_party/libunwind/trunk/docs/CMakeLists.txt b/chromium/buildtools/third_party/libunwind/trunk/docs/CMakeLists.txt deleted file mode 100644 index c226f2f5b8e..00000000000 --- a/chromium/buildtools/third_party/libunwind/trunk/docs/CMakeLists.txt +++ /dev/null @@ -1,7 +0,0 @@ -include(FindSphinx) -if (SPHINX_FOUND) - include(AddSphinxTarget) - if (${SPHINX_OUTPUT_HTML}) - add_sphinx_target(html libunwind) - endif() -endif() diff --git a/chromium/buildtools/third_party/libunwind/trunk/docs/README.txt b/chromium/buildtools/third_party/libunwind/trunk/docs/README.txt deleted file mode 100644 index 968982fce5e..00000000000 --- a/chromium/buildtools/third_party/libunwind/trunk/docs/README.txt +++ /dev/null @@ -1,13 +0,0 @@ -libunwind Documentation -==================== - -The libunwind documentation is written using the Sphinx documentation generator. It is -currently tested with Sphinx 1.1.3. - -To build the documents into html configure libunwind with the following cmake options: - - * -DLLVM_ENABLE_SPHINX=ON - * -DLIBUNWIND_INCLUDE_DOCS=ON - -After configuring libunwind with these options the make rule `docs-libunwind-html` -should be available. diff --git a/chromium/buildtools/third_party/libunwind/trunk/docs/conf.py b/chromium/buildtools/third_party/libunwind/trunk/docs/conf.py deleted file mode 100644 index 29c95f37b3c..00000000000 --- a/chromium/buildtools/third_party/libunwind/trunk/docs/conf.py +++ /dev/null @@ -1,251 +0,0 @@ -# -*- coding: utf-8 -*- -# -# libunwind documentation build configuration file. -# -# This file is execfile()d with the current directory set to its containing dir. -# -# Note that not all possible configuration values are present in this -# autogenerated file. -# -# All configuration values have a default; values that are commented out -# serve to show the default. - -import sys, os - -# If extensions (or modules to document with autodoc) are in another directory, -# add these directories to sys.path here. If the directory is relative to the -# documentation root, use os.path.abspath to make it absolute, like shown here. -#sys.path.insert(0, os.path.abspath('.')) - -# -- General configuration ----------------------------------------------------- - -# If your documentation needs a minimal Sphinx version, state it here. -#needs_sphinx = '1.0' - -# Add any Sphinx extension module names here, as strings. They can be extensions -# coming with Sphinx (named 'sphinx.ext.*') or your custom ones. -extensions = ['sphinx.ext.intersphinx', 'sphinx.ext.todo'] - -# Add any paths that contain templates here, relative to this directory. -templates_path = ['_templates'] - -# The suffix of source filenames. -source_suffix = '.rst' - -# The encoding of source files. -#source_encoding = 'utf-8-sig' - -# The master toctree document. -master_doc = 'index' - -# General information about the project. -project = u'libunwind' -copyright = u'2011-2017, LLVM Project' - -# The version info for the project you're documenting, acts as replacement for -# |version| and |release|, also used in various other places throughout the -# built documents. -# -# The short X.Y version. -version = '6.0' -# The full version, including alpha/beta/rc tags. -release = '6.0' - -# The language for content autogenerated by Sphinx. Refer to documentation -# for a list of supported languages. -#language = None - -# There are two options for replacing |today|: either, you set today to some -# non-false value, then it is used: -#today = '' -# Else, today_fmt is used as the format for a strftime call. -today_fmt = '%Y-%m-%d' - -# List of patterns, relative to source directory, that match files and -# directories to ignore when looking for source files. -exclude_patterns = ['_build'] - -# The reST default role (used for this markup: `text`) to use for all documents. -#default_role = None - -# If true, '()' will be appended to :func: etc. cross-reference text. -#add_function_parentheses = True - -# If true, the current module name will be prepended to all description -# unit titles (such as .. function::). -#add_module_names = True - -# If true, sectionauthor and moduleauthor directives will be shown in the -# output. They are ignored by default. -show_authors = True - -# The name of the Pygments (syntax highlighting) style to use. -pygments_style = 'friendly' - -# A list of ignored prefixes for module index sorting. -#modindex_common_prefix = [] - - -# -- Options for HTML output --------------------------------------------------- - -# The theme to use for HTML and HTML Help pages. See the documentation for -# a list of builtin themes. -html_theme = 'haiku' - -# Theme options are theme-specific and customize the look and feel of a theme -# further. For a list of options available for each theme, see the -# documentation. -#html_theme_options = {} - -# Add any paths that contain custom themes here, relative to this directory. -#html_theme_path = [] - -# The name for this set of Sphinx documents. If None, it defaults to -# "<project> v<release> documentation". -#html_title = None - -# A shorter title for the navigation bar. Default is the same as html_title. -#html_short_title = None - -# The name of an image file (relative to this directory) to place at the top -# of the sidebar. -#html_logo = None - -# The name of an image file (within the static path) to use as favicon of the -# docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32 -# pixels large. -#html_favicon = None - -# Add any paths that contain custom static files (such as style sheets) here, -# relative to this directory. They are copied after the builtin static files, -# so a file named "default.css" will overwrite the builtin "default.css". -html_static_path = [] - -# If not '', a 'Last updated on:' timestamp is inserted at every page bottom, -# using the given strftime format. -#html_last_updated_fmt = '%b %d, %Y' - -# If true, SmartyPants will be used to convert quotes and dashes to -# typographically correct entities. -#html_use_smartypants = True - -# Custom sidebar templates, maps document names to template names. -#html_sidebars = {} - -# Additional templates that should be rendered to pages, maps page names to -# template names. -#html_additional_pages = {} - -# If false, no module index is generated. -#html_domain_indices = True - -# If false, no index is generated. -#html_use_index = True - -# If true, the index is split into individual pages for each letter. -#html_split_index = False - -# If true, links to the reST sources are added to the pages. -#html_show_sourcelink = True - -# If true, "Created using Sphinx" is shown in the HTML footer. Default is True. -#html_show_sphinx = True - -# If true, "(C) Copyright ..." is shown in the HTML footer. Default is True. -#html_show_copyright = True - -# If true, an OpenSearch description file will be output, and all pages will -# contain a <link> tag referring to it. The value of this option must be the -# base URL from which the finished HTML is served. -#html_use_opensearch = '' - -# This is the file name suffix for HTML files (e.g. ".xhtml"). -#html_file_suffix = None - -# Output file base name for HTML help builder. -htmlhelp_basename = 'libunwinddoc' - - -# -- Options for LaTeX output -------------------------------------------------- - -latex_elements = { -# The paper size ('letterpaper' or 'a4paper'). -#'papersize': 'letterpaper', - -# The font size ('10pt', '11pt' or '12pt'). -#'pointsize': '10pt', - -# Additional stuff for the LaTeX preamble. -#'preamble': '', -} - -# Grouping the document tree into LaTeX files. List of tuples -# (source start file, target name, title, author, documentclass [howto/manual]). -latex_documents = [ - ('contents', 'libunwind.tex', u'libunwind Documentation', - u'LLVM project', 'manual'), -] - -# The name of an image file (relative to this directory) to place at the top of -# the title page. -#latex_logo = None - -# For "manual" documents, if this is true, then toplevel headings are parts, -# not chapters. -#latex_use_parts = False - -# If true, show page references after internal links. -#latex_show_pagerefs = False - -# If true, show URL addresses after external links. -#latex_show_urls = False - -# Documents to append as an appendix to all manuals. -#latex_appendices = [] - -# If false, no module index is generated. -#latex_domain_indices = True - - -# -- Options for manual page output -------------------------------------------- - -# One entry per manual page. List of tuples -# (source start file, name, description, authors, manual section). -man_pages = [ - ('contents', 'libunwind', u'libunwind Documentation', - [u'LLVM project'], 1) -] - -# If true, show URL addresses after external links. -#man_show_urls = False - - -# -- Options for Texinfo output ------------------------------------------------ - -# Grouping the document tree into Texinfo files. List of tuples -# (source start file, target name, title, author, -# dir menu entry, description, category) -texinfo_documents = [ - ('contents', 'libunwind', u'libunwind Documentation', - u'LLVM project', 'libunwind', 'LLVM Unwinder', - 'Miscellaneous'), -] - -# Documents to append as an appendix to all manuals. -#texinfo_appendices = [] - -# If false, no module index is generated. -#texinfo_domain_indices = True - -# How to display URL addresses: 'footnote', 'no', or 'inline'. -#texinfo_show_urls = 'footnote' - - -# FIXME: Define intersphinx configration. -intersphinx_mapping = {} - - -# -- Options for extensions ---------------------------------------------------- - -# Enable this if you want TODOs to show up in the generated documentation. -todo_include_todos = True diff --git a/chromium/buildtools/third_party/libunwind/trunk/docs/index.rst b/chromium/buildtools/third_party/libunwind/trunk/docs/index.rst deleted file mode 100644 index 831bd0e1f58..00000000000 --- a/chromium/buildtools/third_party/libunwind/trunk/docs/index.rst +++ /dev/null @@ -1,105 +0,0 @@ -.. _index: - -======================= -libunwind LLVM Unwinder -======================= - -Overview -======== - -libunwind is an implementation of the interface defined by the HP libunwind -project. It was contributed by Apple as a way to enable clang++ to port to -platforms that do not have a system unwinder. It is intended to be a small and -fast implementation of the ABI, leaving off some features of HP's libunwind -that never materialized (e.g. remote unwinding). - -The unwinder has two levels of API. The high level APIs are the `_Unwind_*` -functions which implement functionality required by `__cxa_*` exception -functions. The low level APIs are the `unw_*` functions which are an interface -defined by the old HP libunwind project. - -Getting Started with libunwind ------------------------------- - -.. toctree:: - :maxdepth: 2 - - BuildingLibunwind - -Current Status --------------- - -libunwind is a production-quality unwinder, with platform support for DWARF -unwind info, SjLj, and ARM EHABI. - -The low level libunwind API was designed to work either in-process (aka local) -or to operate on another process (aka remote), but only the local path has been -implemented. Remote unwinding remains as future work. - -Platform and Compiler Support ------------------------------ - -libunwind is known to work on the following platforms: - -============ ==================== ============ ======================== -OS Arch Compilers Unwind Info -============ ==================== ============ ======================== -Any i386, x86_64, ARM Clang SjLj -Bare Metal ARM Clang, GCC EHABI -FreeBSD i386, x86_64, ARM64 Clang DWARF CFI -iOS ARM Clang SjLj -Linux ARM Clang, GCC EHABI -Linux i386, x86_64, ARM64 Clang, GCC DWARF CFI -Mac OS X i386, x86_64 Clang, GCC DWARF CFI -NetBSD x86_64 Clang, GCC DWARF CFI -Windows i386, x86_64 Clang DWARF CFI -============ ==================== ============ ======================== - -The following minimum compiler versions are strongly recommended. - -* Clang 3.5 and above -* GCC 4.7 and above. - -Anything older *may* work. - -Notes and Known Issues ----------------------- - -* TODO - - -Getting Involved -================ - -First please review our `Developer's Policy <http://llvm.org/docs/DeveloperPolicy.html>`__ -and `Getting started with LLVM <http://llvm.org/docs/GettingStarted.html>`__. - -**Bug Reports** - -If you think you've found a bug in libunwind, please report it using -the `LLVM Bugzilla`_. If you're not sure, you -can post a message to the `cfe-dev mailing list`_ or on IRC. -Please include "libunwind" in your subject. - -**Patches** - -If you want to contribute a patch to libunwind, the best place for that is -`Phabricator <http://llvm.org/docs/Phabricator.html>`_. Please include [libunwind] in the subject and -add `cfe-commits` as a subscriber. Also make sure you are subscribed to the -`cfe-commits mailing list <http://lists.llvm.org/mailman/listinfo/cfe-commits>`_. - -**Discussion and Questions** - -Send discussions and questions to the -`cfe-dev mailing list <http://lists.llvm.org/mailman/listinfo/cfe-dev>`_. -Please include [libunwind] in the subject. - - -Quick Links -=========== -* `LLVM Homepage <http://llvm.org/>`_ -* `LLVM Bugzilla <https://bugs.llvm.org/>`_ -* `cfe-commits Mailing List`_ -* `cfe-dev Mailing List`_ -* `Browse libunwind -- SVN <http://llvm.org/svn/llvm-project/libunwind/trunk/>`_ -* `Browse libunwind -- ViewVC <http://llvm.org/viewvc/llvm-project/libunwind/trunk/>`_ diff --git a/chromium/buildtools/third_party/libunwind/trunk/include/__libunwind_config.h b/chromium/buildtools/third_party/libunwind/trunk/include/__libunwind_config.h deleted file mode 100644 index 6d69085d83a..00000000000 --- a/chromium/buildtools/third_party/libunwind/trunk/include/__libunwind_config.h +++ /dev/null @@ -1,81 +0,0 @@ -//===------------------------- __libunwind_config.h -----------------------===// -// -// 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 ____LIBUNWIND_CONFIG_H__ -#define ____LIBUNWIND_CONFIG_H__ - -#if defined(__arm__) && !defined(__USING_SJLJ_EXCEPTIONS__) && \ - !defined(__ARM_DWARF_EH__) -#define _LIBUNWIND_ARM_EHABI -#endif - -#define _LIBUNWIND_HIGHEST_DWARF_REGISTER_X86 8 -#define _LIBUNWIND_HIGHEST_DWARF_REGISTER_X86_64 32 -#define _LIBUNWIND_HIGHEST_DWARF_REGISTER_PPC 112 -#define _LIBUNWIND_HIGHEST_DWARF_REGISTER_ARM64 95 -#define _LIBUNWIND_HIGHEST_DWARF_REGISTER_ARM 95 -#define _LIBUNWIND_HIGHEST_DWARF_REGISTER_OR1K 31 - -#if defined(_LIBUNWIND_IS_NATIVE_ONLY) -# if defined(__i386__) -# define _LIBUNWIND_TARGET_I386 -# define _LIBUNWIND_CONTEXT_SIZE 8 -# define _LIBUNWIND_CURSOR_SIZE 15 -# define _LIBUNWIND_HIGHEST_DWARF_REGISTER _LIBUNWIND_HIGHEST_DWARF_REGISTER_X86 -# elif defined(__x86_64__) -# define _LIBUNWIND_TARGET_X86_64 1 -# if defined(_WIN64) -# define _LIBUNWIND_CONTEXT_SIZE 54 -# define _LIBUNWIND_CURSOR_SIZE 66 -# else -# define _LIBUNWIND_CONTEXT_SIZE 21 -# define _LIBUNWIND_CURSOR_SIZE 33 -# endif -# define _LIBUNWIND_HIGHEST_DWARF_REGISTER _LIBUNWIND_HIGHEST_DWARF_REGISTER_X86_64 -# elif defined(__ppc__) -# define _LIBUNWIND_TARGET_PPC 1 -# define _LIBUNWIND_CONTEXT_SIZE 117 -# define _LIBUNWIND_CURSOR_SIZE 124 -# define _LIBUNWIND_HIGHEST_DWARF_REGISTER _LIBUNWIND_HIGHEST_DWARF_REGISTER_PPC -# elif defined(__aarch64__) -# define _LIBUNWIND_TARGET_AARCH64 1 -# define _LIBUNWIND_CONTEXT_SIZE 66 -# define _LIBUNWIND_CURSOR_SIZE 78 -# define _LIBUNWIND_HIGHEST_DWARF_REGISTER _LIBUNWIND_HIGHEST_DWARF_REGISTER_ARM64 -# elif defined(__arm__) -# define _LIBUNWIND_TARGET_ARM 1 -# if defined(__ARM_WMMX) -# define _LIBUNWIND_CONTEXT_SIZE 61 -# define _LIBUNWIND_CURSOR_SIZE 68 -# else -# define _LIBUNWIND_CONTEXT_SIZE 42 -# define _LIBUNWIND_CURSOR_SIZE 49 -# endif -# define _LIBUNWIND_HIGHEST_DWARF_REGISTER _LIBUNWIND_HIGHEST_DWARF_REGISTER_ARM -# elif defined(__or1k__) -# define _LIBUNWIND_TARGET_OR1K 1 -# define _LIBUNWIND_CONTEXT_SIZE 16 -# define _LIBUNWIND_CURSOR_SIZE 24 -# define _LIBUNWIND_HIGHEST_DWARF_REGISTER _LIBUNWIND_HIGHEST_DWARF_REGISTER_OR1K -# else -# error "Unsupported architecture." -# endif -#else // !_LIBUNWIND_IS_NATIVE_ONLY -# define _LIBUNWIND_TARGET_I386 -# define _LIBUNWIND_TARGET_X86_64 1 -# define _LIBUNWIND_TARGET_PPC 1 -# define _LIBUNWIND_TARGET_AARCH64 1 -# define _LIBUNWIND_TARGET_ARM 1 -# define _LIBUNWIND_TARGET_OR1K 1 -# define _LIBUNWIND_CONTEXT_SIZE 128 -# define _LIBUNWIND_CURSOR_SIZE 140 -# define _LIBUNWIND_HIGHEST_DWARF_REGISTER 119 -#endif // _LIBUNWIND_IS_NATIVE_ONLY - -#endif // ____LIBUNWIND_CONFIG_H__ diff --git a/chromium/buildtools/third_party/libunwind/trunk/include/libunwind.h b/chromium/buildtools/third_party/libunwind/trunk/include/libunwind.h deleted file mode 100644 index 04840440d88..00000000000 --- a/chromium/buildtools/third_party/libunwind/trunk/include/libunwind.h +++ /dev/null @@ -1,566 +0,0 @@ -//===---------------------------- libunwind.h -----------------------------===// -// -// 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. -// -// -// Compatible with libunwind API documented at: -// http://www.nongnu.org/libunwind/man/libunwind(3).html -// -//===----------------------------------------------------------------------===// - -#ifndef __LIBUNWIND__ -#define __LIBUNWIND__ - -#include <__libunwind_config.h> - -#include <stdint.h> -#include <stddef.h> - -#ifdef __APPLE__ - #if __clang__ - #if __has_include(<Availability.h>) - #include <Availability.h> - #endif - #elif __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ >= 1050 - #include <Availability.h> - #endif - - #ifdef __arm__ - #define LIBUNWIND_AVAIL __attribute__((unavailable)) - #elif defined(__OSX_AVAILABLE_STARTING) - #define LIBUNWIND_AVAIL __OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_5_0) - #else - #include <AvailabilityMacros.h> - #ifdef AVAILABLE_MAC_OS_X_VERSION_10_6_AND_LATER - #define LIBUNWIND_AVAIL AVAILABLE_MAC_OS_X_VERSION_10_6_AND_LATER - #else - #define LIBUNWIND_AVAIL __attribute__((unavailable)) - #endif - #endif -#else - #define LIBUNWIND_AVAIL -#endif - -/* error codes */ -enum { - UNW_ESUCCESS = 0, /* no error */ - UNW_EUNSPEC = -6540, /* unspecified (general) error */ - UNW_ENOMEM = -6541, /* out of memory */ - UNW_EBADREG = -6542, /* bad register number */ - UNW_EREADONLYREG = -6543, /* attempt to write read-only register */ - UNW_ESTOPUNWIND = -6544, /* stop unwinding */ - UNW_EINVALIDIP = -6545, /* invalid IP */ - UNW_EBADFRAME = -6546, /* bad frame */ - UNW_EINVAL = -6547, /* unsupported operation or bad value */ - UNW_EBADVERSION = -6548, /* unwind info has unsupported version */ - UNW_ENOINFO = -6549 /* no unwind info found */ -}; - -struct unw_context_t { - uint64_t data[_LIBUNWIND_CONTEXT_SIZE]; -}; -typedef struct unw_context_t unw_context_t; - -struct unw_cursor_t { - uint64_t data[_LIBUNWIND_CURSOR_SIZE]; -}; -typedef struct unw_cursor_t unw_cursor_t; - -typedef struct unw_addr_space *unw_addr_space_t; - -typedef int unw_regnum_t; -typedef uintptr_t unw_word_t; -#if defined(_LIBUNWIND_ARM_EHABI) -typedef uint64_t unw_fpreg_t; -#else -typedef double unw_fpreg_t; -#endif - -struct unw_proc_info_t { - unw_word_t start_ip; /* start address of function */ - unw_word_t end_ip; /* address after end of function */ - unw_word_t lsda; /* address of language specific data area, */ - /* or zero if not used */ - unw_word_t handler; /* personality routine, or zero if not used */ - unw_word_t gp; /* not used */ - unw_word_t flags; /* not used */ - uint32_t format; /* compact unwind encoding, or zero if none */ - uint32_t unwind_info_size; /* size of DWARF unwind info, or zero if none */ - unw_word_t unwind_info; /* address of DWARF unwind info, or zero */ - unw_word_t extra; /* mach_header of mach-o image containing func */ -}; -typedef struct unw_proc_info_t unw_proc_info_t; - -#ifdef __cplusplus -extern "C" { -#endif - -extern int unw_getcontext(unw_context_t *) LIBUNWIND_AVAIL; -extern int unw_init_local(unw_cursor_t *, unw_context_t *) LIBUNWIND_AVAIL; -extern int unw_step(unw_cursor_t *) LIBUNWIND_AVAIL; -extern int unw_get_reg(unw_cursor_t *, unw_regnum_t, unw_word_t *) LIBUNWIND_AVAIL; -extern int unw_get_fpreg(unw_cursor_t *, unw_regnum_t, unw_fpreg_t *) LIBUNWIND_AVAIL; -extern int unw_set_reg(unw_cursor_t *, unw_regnum_t, unw_word_t) LIBUNWIND_AVAIL; -extern int unw_set_fpreg(unw_cursor_t *, unw_regnum_t, unw_fpreg_t) LIBUNWIND_AVAIL; -extern int unw_resume(unw_cursor_t *) LIBUNWIND_AVAIL; - -#ifdef __arm__ -/* Save VFP registers in FSTMX format (instead of FSTMD). */ -extern void unw_save_vfp_as_X(unw_cursor_t *) LIBUNWIND_AVAIL; -#endif - - -extern const char *unw_regname(unw_cursor_t *, unw_regnum_t) LIBUNWIND_AVAIL; -extern int unw_get_proc_info(unw_cursor_t *, unw_proc_info_t *) LIBUNWIND_AVAIL; -extern int unw_is_fpreg(unw_cursor_t *, unw_regnum_t) LIBUNWIND_AVAIL; -extern int unw_is_signal_frame(unw_cursor_t *) LIBUNWIND_AVAIL; -extern int unw_get_proc_name(unw_cursor_t *, char *, size_t, unw_word_t *) LIBUNWIND_AVAIL; -//extern int unw_get_save_loc(unw_cursor_t*, int, unw_save_loc_t*); - -extern unw_addr_space_t unw_local_addr_space; - -#ifdef UNW_REMOTE -/* - * Mac OS X "remote" API for unwinding other processes on same machine - * - */ -extern unw_addr_space_t unw_create_addr_space_for_task(task_t); -extern void unw_destroy_addr_space(unw_addr_space_t); -extern int unw_init_remote_thread(unw_cursor_t *, unw_addr_space_t, thread_t *); -#endif /* UNW_REMOTE */ - -/* - * traditional libunwind "remote" API - * NOT IMPLEMENTED on Mac OS X - * - * extern int unw_init_remote(unw_cursor_t*, unw_addr_space_t, - * thread_t*); - * extern unw_accessors_t unw_get_accessors(unw_addr_space_t); - * extern unw_addr_space_t unw_create_addr_space(unw_accessors_t, int); - * extern void unw_flush_cache(unw_addr_space_t, unw_word_t, - * unw_word_t); - * extern int unw_set_caching_policy(unw_addr_space_t, - * unw_caching_policy_t); - * extern void _U_dyn_register(unw_dyn_info_t*); - * extern void _U_dyn_cancel(unw_dyn_info_t*); - */ - -#ifdef __cplusplus -} -#endif - -// architecture independent register numbers -enum { - UNW_REG_IP = -1, // instruction pointer - UNW_REG_SP = -2, // stack pointer -}; - -// 32-bit x86 registers -enum { - UNW_X86_EAX = 0, - UNW_X86_ECX = 1, - UNW_X86_EDX = 2, - UNW_X86_EBX = 3, - UNW_X86_EBP = 4, - UNW_X86_ESP = 5, - UNW_X86_ESI = 6, - UNW_X86_EDI = 7 -}; - -// 64-bit x86_64 registers -enum { - UNW_X86_64_RAX = 0, - UNW_X86_64_RDX = 1, - UNW_X86_64_RCX = 2, - UNW_X86_64_RBX = 3, - UNW_X86_64_RSI = 4, - UNW_X86_64_RDI = 5, - UNW_X86_64_RBP = 6, - UNW_X86_64_RSP = 7, - UNW_X86_64_R8 = 8, - UNW_X86_64_R9 = 9, - UNW_X86_64_R10 = 10, - UNW_X86_64_R11 = 11, - UNW_X86_64_R12 = 12, - UNW_X86_64_R13 = 13, - UNW_X86_64_R14 = 14, - UNW_X86_64_R15 = 15, - UNW_X86_64_RIP = 16, - UNW_X86_64_XMM0 = 17, - UNW_X86_64_XMM1 = 18, - UNW_X86_64_XMM2 = 19, - UNW_X86_64_XMM3 = 20, - UNW_X86_64_XMM4 = 21, - UNW_X86_64_XMM5 = 22, - UNW_X86_64_XMM6 = 23, - UNW_X86_64_XMM7 = 24, - UNW_X86_64_XMM8 = 25, - UNW_X86_64_XMM9 = 26, - UNW_X86_64_XMM10 = 27, - UNW_X86_64_XMM11 = 28, - UNW_X86_64_XMM12 = 29, - UNW_X86_64_XMM13 = 30, - UNW_X86_64_XMM14 = 31, - UNW_X86_64_XMM15 = 32, -}; - - -// 32-bit ppc register numbers -enum { - UNW_PPC_R0 = 0, - UNW_PPC_R1 = 1, - UNW_PPC_R2 = 2, - UNW_PPC_R3 = 3, - UNW_PPC_R4 = 4, - UNW_PPC_R5 = 5, - UNW_PPC_R6 = 6, - UNW_PPC_R7 = 7, - UNW_PPC_R8 = 8, - UNW_PPC_R9 = 9, - UNW_PPC_R10 = 10, - UNW_PPC_R11 = 11, - UNW_PPC_R12 = 12, - UNW_PPC_R13 = 13, - UNW_PPC_R14 = 14, - UNW_PPC_R15 = 15, - UNW_PPC_R16 = 16, - UNW_PPC_R17 = 17, - UNW_PPC_R18 = 18, - UNW_PPC_R19 = 19, - UNW_PPC_R20 = 20, - UNW_PPC_R21 = 21, - UNW_PPC_R22 = 22, - UNW_PPC_R23 = 23, - UNW_PPC_R24 = 24, - UNW_PPC_R25 = 25, - UNW_PPC_R26 = 26, - UNW_PPC_R27 = 27, - UNW_PPC_R28 = 28, - UNW_PPC_R29 = 29, - UNW_PPC_R30 = 30, - UNW_PPC_R31 = 31, - UNW_PPC_F0 = 32, - UNW_PPC_F1 = 33, - UNW_PPC_F2 = 34, - UNW_PPC_F3 = 35, - UNW_PPC_F4 = 36, - UNW_PPC_F5 = 37, - UNW_PPC_F6 = 38, - UNW_PPC_F7 = 39, - UNW_PPC_F8 = 40, - UNW_PPC_F9 = 41, - UNW_PPC_F10 = 42, - UNW_PPC_F11 = 43, - UNW_PPC_F12 = 44, - UNW_PPC_F13 = 45, - UNW_PPC_F14 = 46, - UNW_PPC_F15 = 47, - UNW_PPC_F16 = 48, - UNW_PPC_F17 = 49, - UNW_PPC_F18 = 50, - UNW_PPC_F19 = 51, - UNW_PPC_F20 = 52, - UNW_PPC_F21 = 53, - UNW_PPC_F22 = 54, - UNW_PPC_F23 = 55, - UNW_PPC_F24 = 56, - UNW_PPC_F25 = 57, - UNW_PPC_F26 = 58, - UNW_PPC_F27 = 59, - UNW_PPC_F28 = 60, - UNW_PPC_F29 = 61, - UNW_PPC_F30 = 62, - UNW_PPC_F31 = 63, - UNW_PPC_MQ = 64, - UNW_PPC_LR = 65, - UNW_PPC_CTR = 66, - UNW_PPC_AP = 67, - UNW_PPC_CR0 = 68, - UNW_PPC_CR1 = 69, - UNW_PPC_CR2 = 70, - UNW_PPC_CR3 = 71, - UNW_PPC_CR4 = 72, - UNW_PPC_CR5 = 73, - UNW_PPC_CR6 = 74, - UNW_PPC_CR7 = 75, - UNW_PPC_XER = 76, - UNW_PPC_V0 = 77, - UNW_PPC_V1 = 78, - UNW_PPC_V2 = 79, - UNW_PPC_V3 = 80, - UNW_PPC_V4 = 81, - UNW_PPC_V5 = 82, - UNW_PPC_V6 = 83, - UNW_PPC_V7 = 84, - UNW_PPC_V8 = 85, - UNW_PPC_V9 = 86, - UNW_PPC_V10 = 87, - UNW_PPC_V11 = 88, - UNW_PPC_V12 = 89, - UNW_PPC_V13 = 90, - UNW_PPC_V14 = 91, - UNW_PPC_V15 = 92, - UNW_PPC_V16 = 93, - UNW_PPC_V17 = 94, - UNW_PPC_V18 = 95, - UNW_PPC_V19 = 96, - UNW_PPC_V20 = 97, - UNW_PPC_V21 = 98, - UNW_PPC_V22 = 99, - UNW_PPC_V23 = 100, - UNW_PPC_V24 = 101, - UNW_PPC_V25 = 102, - UNW_PPC_V26 = 103, - UNW_PPC_V27 = 104, - UNW_PPC_V28 = 105, - UNW_PPC_V29 = 106, - UNW_PPC_V30 = 107, - UNW_PPC_V31 = 108, - UNW_PPC_VRSAVE = 109, - UNW_PPC_VSCR = 110, - UNW_PPC_SPE_ACC = 111, - UNW_PPC_SPEFSCR = 112 -}; - -// 64-bit ARM64 registers -enum { - UNW_ARM64_X0 = 0, - UNW_ARM64_X1 = 1, - UNW_ARM64_X2 = 2, - UNW_ARM64_X3 = 3, - UNW_ARM64_X4 = 4, - UNW_ARM64_X5 = 5, - UNW_ARM64_X6 = 6, - UNW_ARM64_X7 = 7, - UNW_ARM64_X8 = 8, - UNW_ARM64_X9 = 9, - UNW_ARM64_X10 = 10, - UNW_ARM64_X11 = 11, - UNW_ARM64_X12 = 12, - UNW_ARM64_X13 = 13, - UNW_ARM64_X14 = 14, - UNW_ARM64_X15 = 15, - UNW_ARM64_X16 = 16, - UNW_ARM64_X17 = 17, - UNW_ARM64_X18 = 18, - UNW_ARM64_X19 = 19, - UNW_ARM64_X20 = 20, - UNW_ARM64_X21 = 21, - UNW_ARM64_X22 = 22, - UNW_ARM64_X23 = 23, - UNW_ARM64_X24 = 24, - UNW_ARM64_X25 = 25, - UNW_ARM64_X26 = 26, - UNW_ARM64_X27 = 27, - UNW_ARM64_X28 = 28, - UNW_ARM64_X29 = 29, - UNW_ARM64_FP = 29, - UNW_ARM64_X30 = 30, - UNW_ARM64_LR = 30, - UNW_ARM64_X31 = 31, - UNW_ARM64_SP = 31, - // reserved block - UNW_ARM64_D0 = 64, - UNW_ARM64_D1 = 65, - UNW_ARM64_D2 = 66, - UNW_ARM64_D3 = 67, - UNW_ARM64_D4 = 68, - UNW_ARM64_D5 = 69, - UNW_ARM64_D6 = 70, - UNW_ARM64_D7 = 71, - UNW_ARM64_D8 = 72, - UNW_ARM64_D9 = 73, - UNW_ARM64_D10 = 74, - UNW_ARM64_D11 = 75, - UNW_ARM64_D12 = 76, - UNW_ARM64_D13 = 77, - UNW_ARM64_D14 = 78, - UNW_ARM64_D15 = 79, - UNW_ARM64_D16 = 80, - UNW_ARM64_D17 = 81, - UNW_ARM64_D18 = 82, - UNW_ARM64_D19 = 83, - UNW_ARM64_D20 = 84, - UNW_ARM64_D21 = 85, - UNW_ARM64_D22 = 86, - UNW_ARM64_D23 = 87, - UNW_ARM64_D24 = 88, - UNW_ARM64_D25 = 89, - UNW_ARM64_D26 = 90, - UNW_ARM64_D27 = 91, - UNW_ARM64_D28 = 92, - UNW_ARM64_D29 = 93, - UNW_ARM64_D30 = 94, - UNW_ARM64_D31 = 95, -}; - -// 32-bit ARM registers. Numbers match DWARF for ARM spec #3.1 Table 1. -// Naming scheme uses recommendations given in Note 4 for VFP-v2 and VFP-v3. -// In this scheme, even though the 64-bit floating point registers D0-D31 -// overlap physically with the 32-bit floating pointer registers S0-S31, -// they are given a non-overlapping range of register numbers. -// -// Commented out ranges are not preserved during unwinding. -enum { - UNW_ARM_R0 = 0, - UNW_ARM_R1 = 1, - UNW_ARM_R2 = 2, - UNW_ARM_R3 = 3, - UNW_ARM_R4 = 4, - UNW_ARM_R5 = 5, - UNW_ARM_R6 = 6, - UNW_ARM_R7 = 7, - UNW_ARM_R8 = 8, - UNW_ARM_R9 = 9, - UNW_ARM_R10 = 10, - UNW_ARM_R11 = 11, - UNW_ARM_R12 = 12, - UNW_ARM_SP = 13, // Logical alias for UNW_REG_SP - UNW_ARM_R13 = 13, - UNW_ARM_LR = 14, - UNW_ARM_R14 = 14, - UNW_ARM_IP = 15, // Logical alias for UNW_REG_IP - UNW_ARM_R15 = 15, - // 16-63 -- OBSOLETE. Used in VFP1 to represent both S0-S31 and D0-D31. - UNW_ARM_S0 = 64, - UNW_ARM_S1 = 65, - UNW_ARM_S2 = 66, - UNW_ARM_S3 = 67, - UNW_ARM_S4 = 68, - UNW_ARM_S5 = 69, - UNW_ARM_S6 = 70, - UNW_ARM_S7 = 71, - UNW_ARM_S8 = 72, - UNW_ARM_S9 = 73, - UNW_ARM_S10 = 74, - UNW_ARM_S11 = 75, - UNW_ARM_S12 = 76, - UNW_ARM_S13 = 77, - UNW_ARM_S14 = 78, - UNW_ARM_S15 = 79, - UNW_ARM_S16 = 80, - UNW_ARM_S17 = 81, - UNW_ARM_S18 = 82, - UNW_ARM_S19 = 83, - UNW_ARM_S20 = 84, - UNW_ARM_S21 = 85, - UNW_ARM_S22 = 86, - UNW_ARM_S23 = 87, - UNW_ARM_S24 = 88, - UNW_ARM_S25 = 89, - UNW_ARM_S26 = 90, - UNW_ARM_S27 = 91, - UNW_ARM_S28 = 92, - UNW_ARM_S29 = 93, - UNW_ARM_S30 = 94, - UNW_ARM_S31 = 95, - // 96-103 -- OBSOLETE. F0-F7. Used by the FPA system. Superseded by VFP. - // 104-111 -- wCGR0-wCGR7, ACC0-ACC7 (Intel wireless MMX) - UNW_ARM_WR0 = 112, - UNW_ARM_WR1 = 113, - UNW_ARM_WR2 = 114, - UNW_ARM_WR3 = 115, - UNW_ARM_WR4 = 116, - UNW_ARM_WR5 = 117, - UNW_ARM_WR6 = 118, - UNW_ARM_WR7 = 119, - UNW_ARM_WR8 = 120, - UNW_ARM_WR9 = 121, - UNW_ARM_WR10 = 122, - UNW_ARM_WR11 = 123, - UNW_ARM_WR12 = 124, - UNW_ARM_WR13 = 125, - UNW_ARM_WR14 = 126, - UNW_ARM_WR15 = 127, - // 128-133 -- SPSR, SPSR_{FIQ|IRQ|ABT|UND|SVC} - // 134-143 -- Reserved - // 144-150 -- R8_USR-R14_USR - // 151-157 -- R8_FIQ-R14_FIQ - // 158-159 -- R13_IRQ-R14_IRQ - // 160-161 -- R13_ABT-R14_ABT - // 162-163 -- R13_UND-R14_UND - // 164-165 -- R13_SVC-R14_SVC - // 166-191 -- Reserved - UNW_ARM_WC0 = 192, - UNW_ARM_WC1 = 193, - UNW_ARM_WC2 = 194, - UNW_ARM_WC3 = 195, - // 196-199 -- wC4-wC7 (Intel wireless MMX control) - // 200-255 -- Reserved - UNW_ARM_D0 = 256, - UNW_ARM_D1 = 257, - UNW_ARM_D2 = 258, - UNW_ARM_D3 = 259, - UNW_ARM_D4 = 260, - UNW_ARM_D5 = 261, - UNW_ARM_D6 = 262, - UNW_ARM_D7 = 263, - UNW_ARM_D8 = 264, - UNW_ARM_D9 = 265, - UNW_ARM_D10 = 266, - UNW_ARM_D11 = 267, - UNW_ARM_D12 = 268, - UNW_ARM_D13 = 269, - UNW_ARM_D14 = 270, - UNW_ARM_D15 = 271, - UNW_ARM_D16 = 272, - UNW_ARM_D17 = 273, - UNW_ARM_D18 = 274, - UNW_ARM_D19 = 275, - UNW_ARM_D20 = 276, - UNW_ARM_D21 = 277, - UNW_ARM_D22 = 278, - UNW_ARM_D23 = 279, - UNW_ARM_D24 = 280, - UNW_ARM_D25 = 281, - UNW_ARM_D26 = 282, - UNW_ARM_D27 = 283, - UNW_ARM_D28 = 284, - UNW_ARM_D29 = 285, - UNW_ARM_D30 = 286, - UNW_ARM_D31 = 287, - // 288-319 -- Reserved for VFP/Neon - // 320-8191 -- Reserved - // 8192-16383 -- Unspecified vendor co-processor register. -}; - -// OpenRISC1000 register numbers -enum { - UNW_OR1K_R0 = 0, - UNW_OR1K_R1 = 1, - UNW_OR1K_R2 = 2, - UNW_OR1K_R3 = 3, - UNW_OR1K_R4 = 4, - UNW_OR1K_R5 = 5, - UNW_OR1K_R6 = 6, - UNW_OR1K_R7 = 7, - UNW_OR1K_R8 = 8, - UNW_OR1K_R9 = 9, - UNW_OR1K_R10 = 10, - UNW_OR1K_R11 = 11, - UNW_OR1K_R12 = 12, - UNW_OR1K_R13 = 13, - UNW_OR1K_R14 = 14, - UNW_OR1K_R15 = 15, - UNW_OR1K_R16 = 16, - UNW_OR1K_R17 = 17, - UNW_OR1K_R18 = 18, - UNW_OR1K_R19 = 19, - UNW_OR1K_R20 = 20, - UNW_OR1K_R21 = 21, - UNW_OR1K_R22 = 22, - UNW_OR1K_R23 = 23, - UNW_OR1K_R24 = 24, - UNW_OR1K_R25 = 25, - UNW_OR1K_R26 = 26, - UNW_OR1K_R27 = 27, - UNW_OR1K_R28 = 28, - UNW_OR1K_R29 = 29, - UNW_OR1K_R30 = 30, - UNW_OR1K_R31 = 31, -}; - -#endif diff --git a/chromium/buildtools/third_party/libunwind/trunk/include/mach-o/compact_unwind_encoding.h b/chromium/buildtools/third_party/libunwind/trunk/include/mach-o/compact_unwind_encoding.h deleted file mode 100644 index de14fd51e53..00000000000 --- a/chromium/buildtools/third_party/libunwind/trunk/include/mach-o/compact_unwind_encoding.h +++ /dev/null @@ -1,478 +0,0 @@ -//===------------------ mach-o/compact_unwind_encoding.h ------------------===// -// -// 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. -// -// -// Darwin's alternative to DWARF based unwind encodings. -// -//===----------------------------------------------------------------------===// - - -#ifndef __COMPACT_UNWIND_ENCODING__ -#define __COMPACT_UNWIND_ENCODING__ - -#include <stdint.h> - -// -// 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. -// -// When the linker creates a final linked image, it will create a -// __TEXT,__unwind_info section. This section is a small and fast way for the -// 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 -// 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 -// compact unwind info. But that is fragile and no longer done. - - -// -// The compact unwind endoding is a 32-bit value which encoded in an -// architecture specific way, which registers to restore from where, and how -// to unwind out of the function. -// -typedef uint32_t compact_unwind_encoding_t; - - -// architecture independent bits -enum { - UNWIND_IS_NOT_FUNCTION_START = 0x80000000, - UNWIND_HAS_LSDA = 0x40000000, - UNWIND_PERSONALITY_MASK = 0x30000000, -}; - - - - -// -// x86 -// -// 1-bit: start -// 1-bit: has lsda -// 2-bit: personality index -// -// 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 -// frameless: -// 8-bits stack size -// 3-bits stack adjust -// 3-bits register count -// 10-bits register permutation -// -enum { - UNWIND_X86_MODE_MASK = 0x0F000000, - UNWIND_X86_MODE_EBP_FRAME = 0x01000000, - UNWIND_X86_MODE_STACK_IMMD = 0x02000000, - UNWIND_X86_MODE_STACK_IND = 0x03000000, - UNWIND_X86_MODE_DWARF = 0x04000000, - - UNWIND_X86_EBP_FRAME_REGISTERS = 0x00007FFF, - UNWIND_X86_EBP_FRAME_OFFSET = 0x00FF0000, - - UNWIND_X86_FRAMELESS_STACK_SIZE = 0x00FF0000, - UNWIND_X86_FRAMELESS_STACK_ADJUST = 0x0000E000, - UNWIND_X86_FRAMELESS_STACK_REG_COUNT = 0x00001C00, - UNWIND_X86_FRAMELESS_STACK_REG_PERMUTATION = 0x000003FF, - - UNWIND_X86_DWARF_SECTION_OFFSET = 0x00FFFFFF, -}; - -enum { - UNWIND_X86_REG_NONE = 0, - UNWIND_X86_REG_EBX = 1, - UNWIND_X86_REG_ECX = 2, - UNWIND_X86_REG_EDX = 3, - UNWIND_X86_REG_EDI = 4, - UNWIND_X86_REG_ESI = 5, - UNWIND_X86_REG_EBP = 6, -}; - -// -// For x86 there are four modes for the compact unwind encoding: -// UNWIND_X86_MODE_EBP_FRAME: -// EBP based frame where EBP is push on stack immediately after return address, -// then ESP is moved to EBP. Thus, to unwind ESP is restored with the current -// EPB value, then EBP is restored by popping off the stack, and the return -// is done by popping the stack once more into the pc. -// All non-volatile registers that need to be restored must have been saved -// in a small range in the stack that starts EBP-4 to EBP-1020. The offset/4 -// is encoded in the UNWIND_X86_EBP_FRAME_OFFSET bits. The registers saved -// are encoded in the UNWIND_X86_EBP_FRAME_REGISTERS bits as five 3-bit entries. -// Each entry contains which register to restore. -// UNWIND_X86_MODE_STACK_IMMD: -// A "frameless" (EBP not used as frame pointer) function with a small -// constant stack size. To return, a constant (encoded in the compact -// unwind encoding) is added to the ESP. Then the return is done by -// popping the stack into the pc. -// All non-volatile registers that need to be restored must have been saved -// on the stack immediately after the return address. The stack_size/4 is -// encoded in the UNWIND_X86_FRAMELESS_STACK_SIZE (max stack size is 1024). -// The number of registers saved is encoded in UNWIND_X86_FRAMELESS_STACK_REG_COUNT. -// UNWIND_X86_FRAMELESS_STACK_REG_PERMUTATION constains which registers were -// saved and their order. -// UNWIND_X86_MODE_STACK_IND: -// A "frameless" (EBP not used as frame pointer) function large constant -// stack size. This case is like the previous, except the stack size is too -// large to encode in the compact unwind encoding. Instead it requires that -// the function contains "subl $nnnnnnnn,ESP" in its prolog. The compact -// encoding contains the offset to the nnnnnnnn value in the function in -// 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. -// 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 -// function. -// -// The permutation encoding is a Lehmer code sequence encoded into a -// single variable-base number so we can encode the ordering of up to -// six registers in a 10-bit space. -// -// The following is the algorithm used to create the permutation encoding used -// with frameless stacks. It is passed the number of registers to be saved and -// an array of the register numbers saved. -// -//uint32_t permute_encode(uint32_t registerCount, const uint32_t registers[6]) -//{ -// uint32_t renumregs[6]; -// for (int i=6-registerCount; i < 6; ++i) { -// int countless = 0; -// for (int j=6-registerCount; j < i; ++j) { -// if ( registers[j] < registers[i] ) -// ++countless; -// } -// renumregs[i] = registers[i] - countless -1; -// } -// uint32_t permutationEncoding = 0; -// switch ( registerCount ) { -// case 6: -// permutationEncoding |= (120*renumregs[0] + 24*renumregs[1] -// + 6*renumregs[2] + 2*renumregs[3] -// + renumregs[4]); -// break; -// case 5: -// permutationEncoding |= (120*renumregs[1] + 24*renumregs[2] -// + 6*renumregs[3] + 2*renumregs[4] -// + renumregs[5]); -// break; -// case 4: -// permutationEncoding |= (60*renumregs[2] + 12*renumregs[3] -// + 3*renumregs[4] + renumregs[5]); -// break; -// case 3: -// permutationEncoding |= (20*renumregs[3] + 4*renumregs[4] -// + renumregs[5]); -// break; -// case 2: -// permutationEncoding |= (5*renumregs[4] + renumregs[5]); -// break; -// case 1: -// permutationEncoding |= (renumregs[5]); -// break; -// } -// return permutationEncoding; -//} -// - - - - -// -// x86_64 -// -// 1-bit: start -// 1-bit: has lsda -// 2-bit: personality index -// -// 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 -// frameless: -// 8-bits stack size -// 3-bits stack adjust -// 3-bits register count -// 10-bits register permutation -// -enum { - UNWIND_X86_64_MODE_MASK = 0x0F000000, - UNWIND_X86_64_MODE_RBP_FRAME = 0x01000000, - UNWIND_X86_64_MODE_STACK_IMMD = 0x02000000, - UNWIND_X86_64_MODE_STACK_IND = 0x03000000, - UNWIND_X86_64_MODE_DWARF = 0x04000000, - - UNWIND_X86_64_RBP_FRAME_REGISTERS = 0x00007FFF, - UNWIND_X86_64_RBP_FRAME_OFFSET = 0x00FF0000, - - UNWIND_X86_64_FRAMELESS_STACK_SIZE = 0x00FF0000, - UNWIND_X86_64_FRAMELESS_STACK_ADJUST = 0x0000E000, - UNWIND_X86_64_FRAMELESS_STACK_REG_COUNT = 0x00001C00, - UNWIND_X86_64_FRAMELESS_STACK_REG_PERMUTATION = 0x000003FF, - - UNWIND_X86_64_DWARF_SECTION_OFFSET = 0x00FFFFFF, -}; - -enum { - UNWIND_X86_64_REG_NONE = 0, - UNWIND_X86_64_REG_RBX = 1, - UNWIND_X86_64_REG_R12 = 2, - UNWIND_X86_64_REG_R13 = 3, - UNWIND_X86_64_REG_R14 = 4, - UNWIND_X86_64_REG_R15 = 5, - UNWIND_X86_64_REG_RBP = 6, -}; -// -// For x86_64 there are four modes for the compact unwind encoding: -// UNWIND_X86_64_MODE_RBP_FRAME: -// RBP based frame where RBP is push on stack immediately after return address, -// then RSP is moved to RBP. Thus, to unwind RSP is restored with the current -// EPB value, then RBP is restored by popping off the stack, and the return -// is done by popping the stack once more into the pc. -// All non-volatile registers that need to be restored must have been saved -// in a small range in the stack that starts RBP-8 to RBP-2040. The offset/8 -// is encoded in the UNWIND_X86_64_RBP_FRAME_OFFSET bits. The registers saved -// are encoded in the UNWIND_X86_64_RBP_FRAME_REGISTERS bits as five 3-bit entries. -// Each entry contains which register to restore. -// UNWIND_X86_64_MODE_STACK_IMMD: -// A "frameless" (RBP not used as frame pointer) function with a small -// constant stack size. To return, a constant (encoded in the compact -// unwind encoding) is added to the RSP. Then the return is done by -// popping the stack into the pc. -// All non-volatile registers that need to be restored must have been saved -// on the stack immediately after the return address. The stack_size/8 is -// encoded in the UNWIND_X86_64_FRAMELESS_STACK_SIZE (max stack size is 2048). -// The number of registers saved is encoded in UNWIND_X86_64_FRAMELESS_STACK_REG_COUNT. -// UNWIND_X86_64_FRAMELESS_STACK_REG_PERMUTATION constains which registers were -// saved and their order. -// UNWIND_X86_64_MODE_STACK_IND: -// A "frameless" (RBP not used as frame pointer) function large constant -// stack size. This case is like the previous, except the stack size is too -// large to encode in the compact unwind encoding. Instead it requires that -// the function contains "subq $nnnnnnnn,RSP" in its prolog. The compact -// encoding contains the offset to the nnnnnnnn value in the function in -// 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. -// 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 -// function. -// - - -// ARM64 -// -// 1-bit: start -// 1-bit: has lsda -// 2-bit: personality index -// -// 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 -// -enum { - UNWIND_ARM64_MODE_MASK = 0x0F000000, - UNWIND_ARM64_MODE_FRAMELESS = 0x02000000, - UNWIND_ARM64_MODE_DWARF = 0x03000000, - UNWIND_ARM64_MODE_FRAME = 0x04000000, - - UNWIND_ARM64_FRAME_X19_X20_PAIR = 0x00000001, - UNWIND_ARM64_FRAME_X21_X22_PAIR = 0x00000002, - UNWIND_ARM64_FRAME_X23_X24_PAIR = 0x00000004, - UNWIND_ARM64_FRAME_X25_X26_PAIR = 0x00000008, - UNWIND_ARM64_FRAME_X27_X28_PAIR = 0x00000010, - UNWIND_ARM64_FRAME_D8_D9_PAIR = 0x00000100, - UNWIND_ARM64_FRAME_D10_D11_PAIR = 0x00000200, - UNWIND_ARM64_FRAME_D12_D13_PAIR = 0x00000400, - UNWIND_ARM64_FRAME_D14_D15_PAIR = 0x00000800, - - UNWIND_ARM64_FRAMELESS_STACK_SIZE_MASK = 0x00FFF000, - UNWIND_ARM64_DWARF_SECTION_OFFSET = 0x00FFFFFF, -}; -// For arm64 there are three modes for the compact unwind encoding: -// UNWIND_ARM64_MODE_FRAME: -// This is a standard arm64 prolog where FP/LR are immediately pushed on the -// stack, then SP is copied to FP. If there are any non-volatile registers -// saved, then are copied into the stack frame in pairs in a contiguous -// range right below the saved FP/LR pair. Any subset of the five X pairs -// and four D pairs can be saved, but the memory layout must be in register -// number order. -// UNWIND_ARM64_MODE_FRAMELESS: -// A "frameless" leaf function, where FP/LR are not saved. The return address -// remains in LR throughout the function. If any non-volatile registers -// are saved, they must be pushed onto the stack before any stack space is -// allocated for local variables. The stack sized (including any saved -// non-volatile registers) divided by 16 is encoded in the bits -// 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. -// 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 -// function. -// - - - - - -//////////////////////////////////////////////////////////////////////////////// -// -// Relocatable Object Files: __LD,__compact_unwind -// -//////////////////////////////////////////////////////////////////////////////// - -// -// A compiler can generated compact unwind information for a function by adding -// a "row" to the __LD,__compact_unwind section. This section has the -// S_ATTR_DEBUG bit set, so the section will be ignored by older linkers. -// It is removed by the new linker, so never ends up in final executables. -// This section is a table, initially with one row per function (that needs -// unwind info). The table columns and some conceptual entries are: -// -// range-start pointer to start of function/range -// range-length -// compact-unwind-encoding 32-bit encoding -// personality-function or zero if no personality function -// lsda or zero if no LSDA data -// -// The length and encoding fields are 32-bits. The other are all pointer sized. -// -// In x86_64 assembly, these entry would look like: -// -// .section __LD,__compact_unwind,regular,debug -// -// #compact unwind for _foo -// .quad _foo -// .set L1,LfooEnd-_foo -// .long L1 -// .long 0x01010001 -// .quad 0 -// .quad 0 -// -// #compact unwind for _bar -// .quad _bar -// .set L2,LbarEnd-_bar -// .long L2 -// .long 0x01020011 -// .quad __gxx_personality -// .quad except_tab1 -// -// -// Notes: There is no need for any labels in the the __compact_unwind section. -// The use of the .set directive is to force the evaluation of the -// range-length at assembly time, instead of generating relocations. -// -// To support future compiler optimizations where which non-volatile registers -// are saved changes within a function (e.g. delay saving non-volatiles until -// necessary), there can by multiple lines in the __compact_unwind table for one -// function, each with a different (non-overlapping) range and each with -// different compact unwind encodings that correspond to the non-volatiles -// 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. -// The runtime will use which ever is available. -// -// Runtime support for compact unwind encodings are only available on 10.6 -// and later. So, the compiler should not generate it when targeting pre-10.6. - - - - -//////////////////////////////////////////////////////////////////////////////// -// -// Final Linked Images: __TEXT,__unwind_info -// -//////////////////////////////////////////////////////////////////////////////// - -// -// The __TEXT,__unwind_info section is laid out for an efficient two level lookup. -// The header of the section contains a coarse index that maps function address -// to the page (4096 byte block) containing the unwind info for that function. -// - -#define UNWIND_SECTION_VERSION 1 -struct unwind_info_section_header -{ - uint32_t version; // UNWIND_SECTION_VERSION - uint32_t commonEncodingsArraySectionOffset; - uint32_t commonEncodingsArrayCount; - uint32_t personalityArraySectionOffset; - uint32_t personalityArrayCount; - uint32_t indexSectionOffset; - uint32_t indexCount; - // compact_unwind_encoding_t[] - // uint32_t personalities[] - // unwind_info_section_header_index_entry[] - // unwind_info_section_header_lsda_index_entry[] -}; - -struct unwind_info_section_header_index_entry -{ - uint32_t functionOffset; - uint32_t secondLevelPagesSectionOffset; // section offset to start of regular or compress page - uint32_t lsdaIndexArraySectionOffset; // section offset to start of lsda_index array for this range -}; - -struct unwind_info_section_header_lsda_index_entry -{ - uint32_t functionOffset; - uint32_t lsdaOffset; -}; - -// -// There are two kinds of second level index pages: regular and compressed. -// A compressed page can hold up to 1021 entries, but it cannot be used -// if too many different encoding types are used. The regular page holds -// 511 entries. -// - -struct unwind_info_regular_second_level_entry -{ - uint32_t functionOffset; - compact_unwind_encoding_t encoding; -}; - -#define UNWIND_SECOND_LEVEL_REGULAR 2 -struct unwind_info_regular_second_level_page_header -{ - uint32_t kind; // UNWIND_SECOND_LEVEL_REGULAR - uint16_t entryPageOffset; - uint16_t entryCount; - // entry array -}; - -#define UNWIND_SECOND_LEVEL_COMPRESSED 3 -struct unwind_info_compressed_second_level_page_header -{ - uint32_t kind; // UNWIND_SECOND_LEVEL_COMPRESSED - uint16_t entryPageOffset; - uint16_t entryCount; - uint16_t encodingsPageOffset; - uint16_t encodingsCount; - // 32-bit entry array - // encodings array -}; - -#define UNWIND_INFO_COMPRESSED_ENTRY_FUNC_OFFSET(entry) (entry & 0x00FFFFFF) -#define UNWIND_INFO_COMPRESSED_ENTRY_ENCODING_INDEX(entry) ((entry >> 24) & 0xFF) - - - -#endif - diff --git a/chromium/buildtools/third_party/libunwind/trunk/include/unwind.h b/chromium/buildtools/third_party/libunwind/trunk/include/unwind.h deleted file mode 100644 index 0ab87dd615b..00000000000 --- a/chromium/buildtools/third_party/libunwind/trunk/include/unwind.h +++ /dev/null @@ -1,376 +0,0 @@ -//===------------------------------- unwind.h -----------------------------===// -// -// 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. -// -// -// C++ ABI Level 1 ABI documented at: -// http://mentorembedded.github.io/cxx-abi/abi-eh.html -// -//===----------------------------------------------------------------------===// - -#ifndef __UNWIND_H__ -#define __UNWIND_H__ - -#include <__libunwind_config.h> - -#include <stdint.h> -#include <stddef.h> - -#if defined(__APPLE__) -#define LIBUNWIND_UNAVAIL __attribute__ (( unavailable )) -#else -#define LIBUNWIND_UNAVAIL -#endif - -typedef enum { - _URC_NO_REASON = 0, - _URC_OK = 0, - _URC_FOREIGN_EXCEPTION_CAUGHT = 1, - _URC_FATAL_PHASE2_ERROR = 2, - _URC_FATAL_PHASE1_ERROR = 3, - _URC_NORMAL_STOP = 4, - _URC_END_OF_STACK = 5, - _URC_HANDLER_FOUND = 6, - _URC_INSTALL_CONTEXT = 7, - _URC_CONTINUE_UNWIND = 8, -#if defined(_LIBUNWIND_ARM_EHABI) - _URC_FAILURE = 9 -#endif -} _Unwind_Reason_Code; - -typedef enum { - _UA_SEARCH_PHASE = 1, - _UA_CLEANUP_PHASE = 2, - _UA_HANDLER_FRAME = 4, - _UA_FORCE_UNWIND = 8, - _UA_END_OF_STACK = 16 // gcc extension to C++ ABI -} _Unwind_Action; - -typedef struct _Unwind_Context _Unwind_Context; // opaque - -#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; - -typedef uint32_t _Unwind_EHT_Header; - -struct _Unwind_Control_Block; -typedef struct _Unwind_Control_Block _Unwind_Control_Block; -typedef struct _Unwind_Control_Block _Unwind_Exception; /* Alias */ - -struct _Unwind_Control_Block { - uint64_t exception_class; - void (*exception_cleanup)(_Unwind_Reason_Code, _Unwind_Control_Block*); - - /* Unwinder cache, private fields for the unwinder's use */ - struct { - uint32_t reserved1; /* init reserved1 to 0, then don't touch */ - uint32_t reserved2; - uint32_t reserved3; - uint32_t reserved4; - uint32_t reserved5; - } unwinder_cache; - - /* Propagation barrier cache (valid after phase 1): */ - struct { - uint32_t sp; - uint32_t bitpattern[5]; - } barrier_cache; - - /* Cleanup cache (preserved over cleanup): */ - struct { - uint32_t bitpattern[4]; - } cleanup_cache; - - /* Pr cache (for pr's benefit): */ - struct { - uint32_t fnstart; /* function start address */ - _Unwind_EHT_Header* ehtp; /* pointer to EHT entry header word */ - uint32_t additional; - uint32_t reserved1; - } 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* exceptionObject, - struct _Unwind_Context* context); - -typedef _Unwind_Reason_Code (*__personality_routine) - (_Unwind_State state, - _Unwind_Exception* exceptionObject, - struct _Unwind_Context* context); -#else -struct _Unwind_Context; // opaque -struct _Unwind_Exception; // forward declaration -typedef struct _Unwind_Exception _Unwind_Exception; - -struct _Unwind_Exception { - uint64_t exception_class; - void (*exception_cleanup)(_Unwind_Reason_Code reason, - _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 -#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 - // added for binary compatibility. - uint32_t reserved[3]; -#endif - // The Itanium ABI requires that _Unwind_Exception objects are "double-word - // aligned". GCC has interpreted this to mean "use the maximum useful - // alignment for the target"; so do we. -} __attribute__((__aligned__)); - -typedef _Unwind_Reason_Code (*_Unwind_Stop_Fn) - (int version, - _Unwind_Action actions, - uint64_t exceptionClass, - _Unwind_Exception* exceptionObject, - struct _Unwind_Context* context, - void* stop_parameter ); - -typedef _Unwind_Reason_Code (*__personality_routine) - (int version, - _Unwind_Action actions, - uint64_t exceptionClass, - _Unwind_Exception* exceptionObject, - struct _Unwind_Context* context); -#endif - -#ifdef __cplusplus -extern "C" { -#endif - -// -// The following are the base functions documented by the C++ ABI -// -#ifdef __USING_SJLJ_EXCEPTIONS__ -extern _Unwind_Reason_Code - _Unwind_SjLj_RaiseException(_Unwind_Exception *exception_object); -extern void _Unwind_SjLj_Resume(_Unwind_Exception *exception_object); -#else -extern _Unwind_Reason_Code - _Unwind_RaiseException(_Unwind_Exception *exception_object); -extern void _Unwind_Resume(_Unwind_Exception *exception_object); -#endif -extern void _Unwind_DeleteException(_Unwind_Exception *exception_object); - -#if defined(_LIBUNWIND_ARM_EHABI) -typedef enum { - _UVRSC_CORE = 0, /* integer register */ - _UVRSC_VFP = 1, /* vfp */ - _UVRSC_WMMXD = 3, /* Intel WMMX data register */ - _UVRSC_WMMXC = 4 /* Intel WMMX control register */ -} _Unwind_VRS_RegClass; - -typedef enum { - _UVRSD_UINT32 = 0, - _UVRSD_VFPX = 1, - _UVRSD_UINT64 = 3, - _UVRSD_FLOAT = 4, - _UVRSD_DOUBLE = 5 -} _Unwind_VRS_DataRepresentation; - -typedef enum { - _UVRSR_OK = 0, - _UVRSR_NOT_IMPLEMENTED = 1, - _UVRSR_FAILED = 2 -} _Unwind_VRS_Result; - -extern void _Unwind_Complete(_Unwind_Exception* exception_object); - -extern _Unwind_VRS_Result -_Unwind_VRS_Get(_Unwind_Context *context, _Unwind_VRS_RegClass regclass, - uint32_t regno, _Unwind_VRS_DataRepresentation representation, - void *valuep); - -extern _Unwind_VRS_Result -_Unwind_VRS_Set(_Unwind_Context *context, _Unwind_VRS_RegClass regclass, - uint32_t regno, _Unwind_VRS_DataRepresentation representation, - void *valuep); - -extern _Unwind_VRS_Result -_Unwind_VRS_Pop(_Unwind_Context *context, _Unwind_VRS_RegClass regclass, - uint32_t discriminator, - _Unwind_VRS_DataRepresentation representation); -#endif - -#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, - uintptr_t new_value); -extern uintptr_t _Unwind_GetIP(struct _Unwind_Context *context); -extern void _Unwind_SetIP(struct _Unwind_Context *, uintptr_t new_value); - -#else // defined(_LIBUNWIND_ARM_EHABI) - -#if defined(_LIBUNWIND_UNWIND_LEVEL1_EXTERNAL_LINKAGE) -#define _LIBUNWIND_EXPORT_UNWIND_LEVEL1 extern -#else -#define _LIBUNWIND_EXPORT_UNWIND_LEVEL1 static __inline__ -#endif - -// These are de facto helper functions for ARM, which delegate the function -// calls to _Unwind_VRS_Get/Set(). These are not a part of ARM EHABI -// specification, thus these function MUST be inlined. Please don't replace -// these with the "extern" function declaration; otherwise, the program -// including this <unwind.h> header won't be ABI compatible and will result in -// link error when we are linking the program with libgcc. - -_LIBUNWIND_EXPORT_UNWIND_LEVEL1 -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; -} - -_LIBUNWIND_EXPORT_UNWIND_LEVEL1 -void _Unwind_SetGR(struct _Unwind_Context *context, int index, - uintptr_t value) { - _Unwind_VRS_Set(context, _UVRSC_CORE, (uint32_t)index, _UVRSD_UINT32, &value); -} - -_LIBUNWIND_EXPORT_UNWIND_LEVEL1 -uintptr_t _Unwind_GetIP(struct _Unwind_Context *context) { - // remove the thumb-bit before returning - return _Unwind_GetGR(context, 15) & (~(uintptr_t)0x1); -} - -_LIBUNWIND_EXPORT_UNWIND_LEVEL1 -void _Unwind_SetIP(struct _Unwind_Context *context, uintptr_t value) { - uintptr_t thumb_bit = _Unwind_GetGR(context, 15) & ((uintptr_t)0x1); - _Unwind_SetGR(context, 15, value | thumb_bit); -} -#endif // defined(_LIBUNWIND_ARM_EHABI) - -extern uintptr_t _Unwind_GetRegionStart(struct _Unwind_Context *context); -extern uintptr_t - _Unwind_GetLanguageSpecificData(struct _Unwind_Context *context); -#ifdef __USING_SJLJ_EXCEPTIONS__ -extern _Unwind_Reason_Code - _Unwind_SjLj_ForcedUnwind(_Unwind_Exception *exception_object, - _Unwind_Stop_Fn stop, void *stop_parameter); -#else -extern _Unwind_Reason_Code - _Unwind_ForcedUnwind(_Unwind_Exception *exception_object, - _Unwind_Stop_Fn stop, void *stop_parameter); -#endif - -#ifdef __USING_SJLJ_EXCEPTIONS__ -typedef struct _Unwind_FunctionContext *_Unwind_FunctionContext_t; -extern void _Unwind_SjLj_Register(_Unwind_FunctionContext_t fc); -extern void _Unwind_SjLj_Unregister(_Unwind_FunctionContext_t fc); -#endif - -// -// The following are semi-suppoted extensions to the C++ ABI -// - -// -// called by __cxa_rethrow(). -// -#ifdef __USING_SJLJ_EXCEPTIONS__ -extern _Unwind_Reason_Code - _Unwind_SjLj_Resume_or_Rethrow(_Unwind_Exception *exception_object); -#else -extern _Unwind_Reason_Code - _Unwind_Resume_or_Rethrow(_Unwind_Exception *exception_object); -#endif - -// _Unwind_Backtrace() is a gcc extension that walks the stack and calls the -// _Unwind_Trace_Fn once per frame until it reaches the bottom of the stack -// or the _Unwind_Trace_Fn function returns something other than _URC_NO_REASON. -typedef _Unwind_Reason_Code (*_Unwind_Trace_Fn)(struct _Unwind_Context *, - void *); -extern _Unwind_Reason_Code _Unwind_Backtrace(_Unwind_Trace_Fn, void *); - -// _Unwind_GetCFA is a gcc extension that can be called from within a -// personality handler to get the CFA (stack pointer before call) of -// current frame. -extern uintptr_t _Unwind_GetCFA(struct _Unwind_Context *); - - -// _Unwind_GetIPInfo is a gcc extension that can be called from within a -// personality handler. Similar to _Unwind_GetIP() but also returns in -// *ipBefore a non-zero value if the instruction pointer is at or before the -// instruction causing the unwind. Normally, in a function call, the IP returned -// is the return address which is after the call instruction and may be past the -// end of the function containing the call instruction. -extern uintptr_t _Unwind_GetIPInfo(struct _Unwind_Context *context, - int *ipBefore); - - -// __register_frame() is used with dynamically generated code to register the -// FDE for a generated (JIT) code. The FDE must use pc-rel addressing to point -// to its function and optional LSDA. -// __register_frame() has existed in all versions of Mac OS X, but in 10.4 and -// 10.5 it was buggy and did not actually register the FDE with the unwinder. -// In 10.6 and later it does register properly. -extern void __register_frame(const void *fde); -extern void __deregister_frame(const void *fde); - -// _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 -// function will only work if the target function has an FDE but no compact -// unwind info. -struct dwarf_eh_bases { - uintptr_t tbase; - uintptr_t dbase; - uintptr_t func; -}; -extern const void *_Unwind_Find_FDE(const void *pc, 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). -// 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); - -// Mac OS X does not support text-rel and data-rel addressing so these functions -// are unimplemented -extern uintptr_t _Unwind_GetDataRelBase(struct _Unwind_Context *context) - LIBUNWIND_UNAVAIL; -extern uintptr_t _Unwind_GetTextRelBase(struct _Unwind_Context *context) - LIBUNWIND_UNAVAIL; - -// Mac OS X 10.4 and 10.5 had implementations of these functions in -// libgcc_s.dylib, but they never worked. -/// These functions are no longer available on Mac OS X. -extern void __register_frame_info_bases(const void *fde, void *ob, void *tb, - void *db) LIBUNWIND_UNAVAIL; -extern void __register_frame_info(const void *fde, void *ob) - LIBUNWIND_UNAVAIL; -extern void __register_frame_info_table_bases(const void *fde, void *ob, - void *tb, void *db) - LIBUNWIND_UNAVAIL; -extern void __register_frame_info_table(const void *fde, void *ob) - LIBUNWIND_UNAVAIL; -extern void __register_frame_table(const void *fde) - LIBUNWIND_UNAVAIL; -extern void *__deregister_frame_info(const void *fde) - LIBUNWIND_UNAVAIL; -extern void *__deregister_frame_info_bases(const void *fde) - LIBUNWIND_UNAVAIL; - -#ifdef __cplusplus -} -#endif - -#endif // __UNWIND_H__ diff --git a/chromium/buildtools/third_party/libunwind/trunk/src/AddressSpace.hpp b/chromium/buildtools/third_party/libunwind/trunk/src/AddressSpace.hpp deleted file mode 100644 index 32428400526..00000000000 --- a/chromium/buildtools/third_party/libunwind/trunk/src/AddressSpace.hpp +++ /dev/null @@ -1,660 +0,0 @@ -//===------------------------- AddressSpace.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. -// -// -// Abstracts accessing local vs remote address spaces. -// -//===----------------------------------------------------------------------===// - -#ifndef __ADDRESSSPACE_HPP__ -#define __ADDRESSSPACE_HPP__ - -#include <stdint.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> - -#if !defined(_LIBUNWIND_IS_BAREMETAL) && !defined(_WIN32) -#include <dlfcn.h> -#endif - -#ifdef __APPLE__ -#include <mach-o/getsect.h> -namespace libunwind { - bool checkKeyMgrRegisteredFDEs(uintptr_t targetAddr, void *&fde); -} -#endif - -#include "libunwind.h" -#include "config.h" -#include "dwarf2.h" -#include "EHHeaderParser.hpp" -#include "Registers.hpp" - -#ifdef __APPLE__ - - struct dyld_unwind_sections - { - const struct mach_header* mh; - const void* dwarf_section; - uintptr_t dwarf_section_length; - const void* compact_unwind_section; - uintptr_t compact_unwind_section_length; - }; - #if (defined(__MAC_OS_X_VERSION_MIN_REQUIRED) \ - && (__MAC_OS_X_VERSION_MIN_REQUIRED >= 1070)) \ - || defined(__IPHONE_OS_VERSION_MIN_REQUIRED) - // In 10.7.0 or later, libSystem.dylib implements this function. - extern "C" bool _dyld_find_unwind_sections(void *, dyld_unwind_sections *); - #else - // In 10.6.x and earlier, we need to implement this functionality. Note - // that this requires a newer version of libmacho (from cctools) than is - // present in libSystem on 10.6.x (for getsectiondata). - static inline bool _dyld_find_unwind_sections(void* addr, - dyld_unwind_sections* info) { - // Find mach-o image containing address. - Dl_info dlinfo; - if (!dladdr(addr, &dlinfo)) - return false; -#if __LP64__ - const struct mach_header_64 *mh = (const struct mach_header_64 *)dlinfo.dli_fbase; -#else - const struct mach_header *mh = (const struct mach_header *)dlinfo.dli_fbase; -#endif - - // Initialize the return struct - info->mh = (const struct mach_header *)mh; - info->dwarf_section = getsectiondata(mh, "__TEXT", "__eh_frame", &info->dwarf_section_length); - info->compact_unwind_section = getsectiondata(mh, "__TEXT", "__unwind_info", &info->compact_unwind_section_length); - - if (!info->dwarf_section) { - info->dwarf_section_length = 0; - } - - if (!info->compact_unwind_section) { - info->compact_unwind_section_length = 0; - } - - return true; - } - #endif - -#elif defined(_LIBUNWIND_ARM_EHABI) && 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. -extern char __exidx_start; -extern char __exidx_end; - -#elif defined(_LIBUNWIND_ARM_EHABI) || defined(_LIBUNWIND_SUPPORT_DWARF_UNWIND) - -// ELF-based systems may use dl_iterate_phdr() to access sections -// containing unwinding information. The ElfW() macro for pointer-size -// independent ELF header traversal is not provided by <link.h> on some -// systems (e.g., FreeBSD). On these systems the data structures are -// just called Elf_XXX. Define ElfW() locally. -#ifndef _WIN32 -#include <link.h> -#else -#include <windows.h> -#include <psapi.h> -#endif -#if !defined(ElfW) -#define ElfW(type) Elf_##type -#endif - -#endif - -namespace libunwind { - -/// Used by findUnwindSections() to return info about needed sections. -struct UnwindInfoSections { -#if defined(_LIBUNWIND_SUPPORT_DWARF_UNWIND) || defined(_LIBUNWIND_SUPPORT_DWARF_INDEX) || \ - defined(_LIBUNWIND_SUPPORT_COMPACT_UNWIND) - // No dso_base for ARM EHABI. - uintptr_t dso_base; -#endif -#if defined(_LIBUNWIND_SUPPORT_DWARF_UNWIND) - uintptr_t dwarf_section; - uintptr_t dwarf_section_length; -#endif -#if defined(_LIBUNWIND_SUPPORT_DWARF_INDEX) - uintptr_t dwarf_index_section; - uintptr_t dwarf_index_section_length; -#endif -#if defined(_LIBUNWIND_SUPPORT_COMPACT_UNWIND) - uintptr_t compact_unwind_section; - uintptr_t compact_unwind_section_length; -#endif -#if defined(_LIBUNWIND_ARM_EHABI) - uintptr_t arm_section; - uintptr_t arm_section_length; -#endif -}; - - -/// LocalAddressSpace is used as a template parameter to UnwindCursor when -/// unwinding a thread in the same process. The wrappers compile away, -/// making local unwinds fast. -class __attribute__((visibility("hidden"))) LocalAddressSpace { -public: - typedef uintptr_t pint_t; - typedef intptr_t sint_t; - uint8_t get8(pint_t addr) { - uint8_t val; - memcpy(&val, (void *)addr, sizeof(val)); - return val; - } - uint16_t get16(pint_t addr) { - uint16_t val; - memcpy(&val, (void *)addr, sizeof(val)); - return val; - } - uint32_t get32(pint_t addr) { - uint32_t val; - memcpy(&val, (void *)addr, sizeof(val)); - return val; - } - uint64_t get64(pint_t addr) { - uint64_t val; - memcpy(&val, (void *)addr, sizeof(val)); - return val; - } - double getDouble(pint_t addr) { - double val; - memcpy(&val, (void *)addr, sizeof(val)); - return val; - } - v128 getVector(pint_t addr) { - v128 val; - memcpy(&val, (void *)addr, sizeof(val)); - return val; - } - uintptr_t getP(pint_t addr); - 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 datarelBase = 0); - bool findFunctionName(pint_t addr, char *buf, size_t bufLen, - unw_word_t *offset); - bool findUnwindSections(pint_t targetAddr, UnwindInfoSections &info); - bool findOtherFDE(pint_t targetAddr, pint_t &fde); - - static LocalAddressSpace sThisAddressSpace; -}; - -inline uintptr_t LocalAddressSpace::getP(pint_t addr) { -#if __SIZEOF_POINTER__ == 8 - return get64(addr); -#else - return get32(addr); -#endif -} - -/// Read a ULEB128 into a 64-bit word. -inline uint64_t LocalAddressSpace::getULEB128(pint_t &addr, pint_t end) { - const uint8_t *p = (uint8_t *)addr; - const uint8_t *pend = (uint8_t *)end; - uint64_t result = 0; - int bit = 0; - do { - uint64_t b; - - if (p == pend) - _LIBUNWIND_ABORT("truncated uleb128 expression"); - - b = *p & 0x7f; - - if (bit >= 64 || b << bit >> bit != b) { - _LIBUNWIND_ABORT("malformed uleb128 expression"); - } else { - result |= b << bit; - bit += 7; - } - } while (*p++ >= 0x80); - addr = (pint_t) p; - return result; -} - -/// Read a SLEB128 into a 64-bit word. -inline int64_t LocalAddressSpace::getSLEB128(pint_t &addr, pint_t end) { - const uint8_t *p = (uint8_t *)addr; - const uint8_t *pend = (uint8_t *)end; - int64_t result = 0; - int bit = 0; - uint8_t byte; - do { - if (p == pend) - _LIBUNWIND_ABORT("truncated sleb128 expression"); - byte = *p++; - result |= ((byte & 0x7f) << bit); - bit += 7; - } while (byte & 0x80); - // sign extend negative numbers - if ((byte & 0x40) != 0) - result |= (-1ULL) << bit; - addr = (pint_t) p; - return result; -} - -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; - - // first get value - switch (encoding & 0x0F) { - case DW_EH_PE_ptr: - result = getP(addr); - p += sizeof(pint_t); - addr = (pint_t) p; - break; - case DW_EH_PE_uleb128: - result = (pint_t)getULEB128(addr, end); - break; - case DW_EH_PE_udata2: - result = get16(addr); - p += 2; - addr = (pint_t) p; - break; - case DW_EH_PE_udata4: - result = get32(addr); - p += 4; - addr = (pint_t) p; - break; - case DW_EH_PE_udata8: - result = (pint_t)get64(addr); - p += 8; - addr = (pint_t) p; - break; - case DW_EH_PE_sleb128: - result = (pint_t)getSLEB128(addr, end); - break; - case DW_EH_PE_sdata2: - // Sign extend from signed 16-bit value. - result = (pint_t)(int16_t)get16(addr); - p += 2; - addr = (pint_t) p; - break; - case DW_EH_PE_sdata4: - // Sign extend from signed 32-bit value. - result = (pint_t)(int32_t)get32(addr); - p += 4; - addr = (pint_t) p; - break; - case DW_EH_PE_sdata8: - result = (pint_t)get64(addr); - p += 8; - addr = (pint_t) p; - break; - default: - _LIBUNWIND_ABORT("unknown pointer encoding"); - } - - // then add relative offset - switch (encoding & 0x70) { - case DW_EH_PE_absptr: - // do nothing - break; - case DW_EH_PE_pcrel: - result += startAddr; - break; - case DW_EH_PE_textrel: - _LIBUNWIND_ABORT("DW_EH_PE_textrel pointer encoding not supported"); - break; - case DW_EH_PE_datarel: - // 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"); - break; - case DW_EH_PE_aligned: - _LIBUNWIND_ABORT("DW_EH_PE_aligned pointer encoding not supported"); - break; - default: - _LIBUNWIND_ABORT("unknown pointer encoding"); - break; - } - - if (encoding & DW_EH_PE_indirect) - result = getP(result); - - return result; -} - -inline bool LocalAddressSpace::findUnwindSections(pint_t targetAddr, - UnwindInfoSections &info) { -#ifdef __APPLE__ - dyld_unwind_sections dyldInfo; - if (_dyld_find_unwind_sections((void *)targetAddr, &dyldInfo)) { - info.dso_base = (uintptr_t)dyldInfo.mh; - #if defined(_LIBUNWIND_SUPPORT_DWARF_UNWIND) - info.dwarf_section = (uintptr_t)dyldInfo.dwarf_section; - info.dwarf_section_length = dyldInfo.dwarf_section_length; - #endif - info.compact_unwind_section = (uintptr_t)dyldInfo.compact_unwind_section; - info.compact_unwind_section_length = dyldInfo.compact_unwind_section_length; - return true; - } -#elif defined(_LIBUNWIND_ARM_EHABI) && defined(_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); - _LIBUNWIND_TRACE_UNWINDING("findUnwindSections: section %X length %x", - info.arm_section, info.arm_section_length); - if (info.arm_section && info.arm_section_length) - return true; -#elif defined(_LIBUNWIND_SUPPORT_DWARF_UNWIND) && defined(_WIN32) - HMODULE mods[1024]; - HANDLE process = GetCurrentProcess(); - DWORD needed; - - if (!EnumProcessModules(process, mods, sizeof(mods), &needed)) - return false; - - for (unsigned i = 0; i < (needed / sizeof(HMODULE)); i++) { - PIMAGE_DOS_HEADER pidh = (PIMAGE_DOS_HEADER)mods[i]; - PIMAGE_NT_HEADERS pinh = (PIMAGE_NT_HEADERS)((BYTE *)pidh + pidh->e_lfanew); - PIMAGE_FILE_HEADER pifh = (PIMAGE_FILE_HEADER)&pinh->FileHeader; - PIMAGE_SECTION_HEADER pish = IMAGE_FIRST_SECTION(pinh); - bool found_obj = false; - bool found_hdr = false; - - info.dso_base = (uintptr_t)mods[i]; - for (unsigned j = 0; j < pifh->NumberOfSections; j++, pish++) { - uintptr_t begin = pish->VirtualAddress + (uintptr_t)mods[i]; - uintptr_t end = begin + pish->Misc.VirtualSize; - if (!strncmp((const char *)pish->Name, ".text", - IMAGE_SIZEOF_SHORT_NAME)) { - if (targetAddr >= begin && targetAddr < end) - found_obj = true; - } else if (!strncmp((const char *)pish->Name, ".eh_frame", - IMAGE_SIZEOF_SHORT_NAME)) { - // FIXME: This section name actually is truncated, ideally we - // should locate and check the full long name instead. - info.dwarf_section = begin; - info.dwarf_section_length = pish->Misc.VirtualSize; - found_hdr = true; - } - if (found_obj && found_hdr) - return true; - } - } - return false; -#elif defined(_LIBUNWIND_ARM_EHABI) && defined(__BIONIC__) && \ - (__ANDROID_API__ < 21) - int length = 0; - info.arm_section = - (uintptr_t)dl_unwind_find_exidx((_Unwind_Ptr)targetAddr, &length); - info.arm_section_length = (uintptr_t)length; - if (info.arm_section && info.arm_section_length) - return true; -#elif defined(_LIBUNWIND_ARM_EHABI) || defined(_LIBUNWIND_SUPPORT_DWARF_UNWIND) - 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); - bool found_obj = false; - bool found_hdr = false; - - assert(cbdata); - assert(cbdata->sects); - - if (cbdata->targetAddr < pinfo->dlpi_addr) { - return false; - } - -#if !defined(Elf_Half) - typedef ElfW(Half) Elf_Half; -#endif -#if !defined(Elf_Phdr) - typedef ElfW(Phdr) Elf_Phdr; -#endif -#if !defined(Elf_Addr) && defined(__ANDROID__) - typedef ElfW(Addr) Elf_Addr; -#endif - - #if defined(_LIBUNWIND_SUPPORT_DWARF_UNWIND) - #if !defined(_LIBUNWIND_SUPPORT_DWARF_INDEX) - #error "_LIBUNWIND_SUPPORT_DWARF_UNWIND requires _LIBUNWIND_SUPPORT_DWARF_INDEX on this platform." - #endif - size_t object_length; -#if defined(__ANDROID__) - Elf_Addr image_base = - pinfo->dlpi_phnum - ? reinterpret_cast<Elf_Addr>(pinfo->dlpi_phdr) - - reinterpret_cast<const Elf_Phdr *>(pinfo->dlpi_phdr) - ->p_offset - : 0; -#endif - - for (Elf_Half i = 0; i < pinfo->dlpi_phnum; i++) { - const Elf_Phdr *phdr = &pinfo->dlpi_phdr[i]; - if (phdr->p_type == PT_LOAD) { - uintptr_t begin = pinfo->dlpi_addr + phdr->p_vaddr; -#if defined(__ANDROID__) - if (pinfo->dlpi_addr == 0 && phdr->p_vaddr < image_base) - begin = begin + image_base; -#endif - 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; -#if defined(__ANDROID__) - if (pinfo->dlpi_addr == 0 && phdr->p_vaddr < image_base) - eh_frame_hdr_start = eh_frame_hdr_start + image_base; -#endif - 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; - } - #else // defined(_LIBUNWIND_ARM_EHABI) - for (Elf_Half i = 0; i < pinfo->dlpi_phnum; i++) { - const Elf_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) - found_obj = true; - } else if (phdr->p_type == PT_ARM_EXIDX) { - uintptr_t exidx_start = pinfo->dlpi_addr + phdr->p_vaddr; - cbdata->sects->arm_section = exidx_start; - cbdata->sects->arm_section_length = phdr->p_memsz; - found_hdr = true; - } - } - return found_obj && found_hdr; - #endif - }, - &cb_data); - return static_cast<bool>(found); -#endif - - return false; -} - - -inline bool LocalAddressSpace::findOtherFDE(pint_t targetAddr, pint_t &fde) { -#ifdef __APPLE__ - return checkKeyMgrRegisteredFDEs(targetAddr, *((void**)&fde)); -#else - // TO DO: if OS has way to dynamically register FDEs, check that. - (void)targetAddr; - (void)fde; - return false; -#endif -} - -inline bool LocalAddressSpace::findFunctionName(pint_t addr, char *buf, - size_t bufLen, - unw_word_t *offset) { -#if !defined(_LIBUNWIND_IS_BAREMETAL) && !defined(_WIN32) - Dl_info dyldInfo; - if (dladdr((void *)addr, &dyldInfo)) { - if (dyldInfo.dli_sname != NULL) { - snprintf(buf, bufLen, "%s", dyldInfo.dli_sname); - *offset = (addr - (pint_t) dyldInfo.dli_saddr); - return true; - } - } -#endif - return false; -} - - - -#ifdef UNW_REMOTE - -/// RemoteAddressSpace is used as a template parameter to UnwindCursor when -/// unwinding a thread in the another process. The other process can be a -/// different endianness and a different pointer size which is handled by -/// the P template parameter. -template <typename P> -class RemoteAddressSpace { -public: - RemoteAddressSpace(task_t task) : fTask(task) {} - - typedef typename P::uint_t pint_t; - - uint8_t get8(pint_t addr); - uint16_t get16(pint_t addr); - uint32_t get32(pint_t addr); - uint64_t get64(pint_t addr); - 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 datarelBase = 0); - bool findFunctionName(pint_t addr, char *buf, size_t bufLen, - unw_word_t *offset); - bool findUnwindSections(pint_t targetAddr, UnwindInfoSections &info); - bool findOtherFDE(pint_t targetAddr, pint_t &fde); -private: - void *localCopy(pint_t addr); - - task_t fTask; -}; - -template <typename P> uint8_t RemoteAddressSpace<P>::get8(pint_t addr) { - return *((uint8_t *)localCopy(addr)); -} - -template <typename P> uint16_t RemoteAddressSpace<P>::get16(pint_t addr) { - return P::E::get16(*(uint16_t *)localCopy(addr)); -} - -template <typename P> uint32_t RemoteAddressSpace<P>::get32(pint_t addr) { - return P::E::get32(*(uint32_t *)localCopy(addr)); -} - -template <typename P> uint64_t RemoteAddressSpace<P>::get64(pint_t addr) { - return P::E::get64(*(uint64_t *)localCopy(addr)); -} - -template <typename P> -typename P::uint_t RemoteAddressSpace<P>::getP(pint_t addr) { - return P::getP(*(uint64_t *)localCopy(addr)); -} - -template <typename P> -uint64_t RemoteAddressSpace<P>::getULEB128(pint_t &addr, pint_t end) { - uintptr_t size = (end - addr); - LocalAddressSpace::pint_t laddr = (LocalAddressSpace::pint_t) localCopy(addr); - LocalAddressSpace::pint_t sladdr = laddr; - uint64_t result = LocalAddressSpace::getULEB128(laddr, laddr + size); - addr += (laddr - sladdr); - return result; -} - -template <typename P> -int64_t RemoteAddressSpace<P>::getSLEB128(pint_t &addr, pint_t end) { - uintptr_t size = (end - addr); - LocalAddressSpace::pint_t laddr = (LocalAddressSpace::pint_t) localCopy(addr); - LocalAddressSpace::pint_t sladdr = laddr; - uint64_t result = LocalAddressSpace::getSLEB128(laddr, laddr + size); - addr += (laddr - sladdr); - return result; -} - -template <typename P> void *RemoteAddressSpace<P>::localCopy(pint_t addr) { - // FIX ME -} - -template <typename P> -bool RemoteAddressSpace<P>::findFunctionName(pint_t addr, char *buf, - size_t bufLen, - unw_word_t *offset) { - // FIX ME -} - -/// unw_addr_space is the base class that abstract unw_addr_space_t type in -/// libunwind.h points to. -struct unw_addr_space { - cpu_type_t cpuType; - task_t taskPort; -}; - -/// unw_addr_space_i386 is the concrete instance that a unw_addr_space_t points -/// to when examining -/// a 32-bit intel process. -struct unw_addr_space_i386 : public unw_addr_space { - unw_addr_space_i386(task_t task) : oas(task) {} - RemoteAddressSpace<Pointer32<LittleEndian>> oas; -}; - -/// unw_addr_space_x86_64 is the concrete instance that a unw_addr_space_t -/// points to when examining -/// a 64-bit intel process. -struct unw_addr_space_x86_64 : public unw_addr_space { - unw_addr_space_x86_64(task_t task) : oas(task) {} - RemoteAddressSpace<Pointer64<LittleEndian>> oas; -}; - -/// unw_addr_space_ppc is the concrete instance that a unw_addr_space_t points -/// to when examining -/// a 32-bit PowerPC process. -struct unw_addr_space_ppc : public unw_addr_space { - unw_addr_space_ppc(task_t task) : oas(task) {} - RemoteAddressSpace<Pointer32<BigEndian>> oas; -}; - -#endif // UNW_REMOTE - -} // namespace libunwind - -#endif // __ADDRESSSPACE_HPP__ diff --git a/chromium/buildtools/third_party/libunwind/trunk/src/CMakeLists.txt b/chromium/buildtools/third_party/libunwind/trunk/src/CMakeLists.txt deleted file mode 100644 index 17550d9ef8a..00000000000 --- a/chromium/buildtools/third_party/libunwind/trunk/src/CMakeLists.txt +++ /dev/null @@ -1,138 +0,0 @@ -# Get sources - -set(LIBUNWIND_CXX_SOURCES - libunwind.cpp - Unwind-EHABI.cpp) -append_if(LIBUNWIND_CXX_SOURCES APPLE Unwind_AppleExtras.cpp) - -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(LIBUNWIND_ASM_SOURCES - UnwindRegistersRestore.S - UnwindRegistersSave.S) -set_source_files_properties(${LIBUNWIND_ASM_SOURCES} - PROPERTIES - LANGUAGE C) - -set(LIBUNWIND_HEADERS - AddressSpace.hpp - assembly.h - CompactUnwinder.hpp - config.h - dwarf2.h - DwarfInstructions.hpp - DwarfParser.hpp - libunwind_ext.h - Registers.hpp - RWMutex.hpp - UnwindCursor.hpp - ${CMAKE_CURRENT_SOURCE_DIR}/../include/libunwind.h - ${CMAKE_CURRENT_SOURCE_DIR}/../include/unwind.h) - -append_if(LIBUNWIND_HEADERS APPLE - "${CMAKE_CURRENT_SOURCE_DIR}/../include/mach-o/compact_unwind_encoding.h") - -if (MSVC_IDE) - # Force them all into the headers dir on MSVC, otherwise they end up at - # project scope because they don't have extensions. - source_group("Header Files" FILES ${LIBUNWIND_HEADERS}) -endif() - -set(LIBUNWIND_SOURCES - ${LIBUNWIND_CXX_SOURCES} - ${LIBUNWIND_C_SOURCES} - ${LIBUNWIND_ASM_SOURCES}) - -# Generate library list. -set(libraries ${LIBUNWINDCXX_ABI_LIBRARIES}) -append_if(libraries LIBUNWIND_HAS_C_LIB c) -append_if(libraries LIBUNWIND_HAS_DL_LIB dl) -if (LIBUNWIND_ENABLE_THREADS) - append_if(libraries LIBUNWIND_HAS_PTHREAD_LIB pthread) -endif() - -# Setup flags. -append_if(LIBUNWIND_CXX_FLAGS LIBUNWIND_HAS_NO_RTTI_FLAG -fno-rtti) - -append_if(LIBUNWIND_LINK_FLAGS LIBUNWIND_HAS_NODEFAULTLIBS_FLAG -nodefaultlibs) - -if (LIBUNWIND_HAS_NO_EXCEPTIONS_FLAG AND LIBUNWIND_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 C++ ABI library is not supported.") -endif() - -if (APPLE) - list(APPEND LIBUNWIND_COMPILE_FLAGS "-U__STRICT_ANSI__") - list(APPEND LIBUNWIND_LINK_FLAGS - "-compatibility_version 1" - "-install_name /usr/lib/libunwind.1.dylib") - - if (CMAKE_OSX_DEPLOYMENT_TARGET STREQUAL "10.6") - list(APPEND LIBUNWIND_LINK_FLAGS - "-current_version ${LIBUNWIND_VERSION}" - "/usr/lib/libSystem.B.dylib") - endif () -endif () - -string(REPLACE ";" " " LIBUNWIND_COMPILE_FLAGS "${LIBUNWIND_COMPILE_FLAGS}") -string(REPLACE ";" " " LIBUNWIND_CXX_FLAGS "${LIBUNWIND_CXX_FLAGS}") -string(REPLACE ";" " " LIBUNWIND_C_FLAGS "${LIBUNWIND_C_FLAGS}") -string(REPLACE ";" " " LIBUNWIND_LINK_FLAGS "${LIBUNWIND_LINK_FLAGS}") - -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}") - -# 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}) - -install(TARGETS ${LIBUNWIND_TARGETS} - LIBRARY DESTINATION ${LIBUNWIND_INSTALL_PREFIX}lib${LIBUNWIND_LIBDIR_SUFFIX} - ARCHIVE DESTINATION ${LIBUNWIND_INSTALL_PREFIX}lib${LIBUNWIND_LIBDIR_SUFFIX}) - diff --git a/chromium/buildtools/third_party/libunwind/trunk/src/CompactUnwinder.hpp b/chromium/buildtools/third_party/libunwind/trunk/src/CompactUnwinder.hpp deleted file mode 100644 index 7b97bf84ceb..00000000000 --- a/chromium/buildtools/third_party/libunwind/trunk/src/CompactUnwinder.hpp +++ /dev/null @@ -1,698 +0,0 @@ -//===-------------------------- CompactUnwinder.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. -// -// -// Does runtime stack unwinding using compact unwind encodings. -// -//===----------------------------------------------------------------------===// - -#ifndef __COMPACT_UNWINDER_HPP__ -#define __COMPACT_UNWINDER_HPP__ - -#include <stdint.h> -#include <stdlib.h> - -#include <libunwind.h> -#include <mach-o/compact_unwind_encoding.h> - -#include "Registers.hpp" - -#define EXTRACT_BITS(value, mask) \ - ((value >> __builtin_ctz(mask)) & (((1 << __builtin_popcount(mask))) - 1)) - -namespace libunwind { - -#if defined(_LIBUNWIND_TARGET_I386) -/// CompactUnwinder_x86 uses a compact unwind info to virtually "step" (aka -/// unwind) by modifying a Registers_x86 register set -template <typename A> -class CompactUnwinder_x86 { -public: - - static int stepWithCompactEncoding(compact_unwind_encoding_t info, - uint32_t functionStart, A &addressSpace, - Registers_x86 ®isters); - -private: - typename A::pint_t pint_t; - - static void frameUnwind(A &addressSpace, Registers_x86 ®isters); - static void framelessUnwind(A &addressSpace, - typename A::pint_t returnAddressLocation, - Registers_x86 ®isters); - static int - stepWithCompactEncodingEBPFrame(compact_unwind_encoding_t compactEncoding, - uint32_t functionStart, A &addressSpace, - Registers_x86 ®isters); - static int stepWithCompactEncodingFrameless( - compact_unwind_encoding_t compactEncoding, uint32_t functionStart, - A &addressSpace, Registers_x86 ®isters, bool indirectStackSize); -}; - -template <typename A> -int CompactUnwinder_x86<A>::stepWithCompactEncoding( - compact_unwind_encoding_t compactEncoding, uint32_t functionStart, - A &addressSpace, Registers_x86 ®isters) { - switch (compactEncoding & UNWIND_X86_MODE_MASK) { - case UNWIND_X86_MODE_EBP_FRAME: - return stepWithCompactEncodingEBPFrame(compactEncoding, functionStart, - addressSpace, registers); - case UNWIND_X86_MODE_STACK_IMMD: - return stepWithCompactEncodingFrameless(compactEncoding, functionStart, - addressSpace, registers, false); - case UNWIND_X86_MODE_STACK_IND: - return stepWithCompactEncodingFrameless(compactEncoding, functionStart, - addressSpace, registers, true); - } - _LIBUNWIND_ABORT("invalid compact unwind encoding"); -} - -template <typename A> -int CompactUnwinder_x86<A>::stepWithCompactEncodingEBPFrame( - compact_unwind_encoding_t compactEncoding, uint32_t functionStart, - A &addressSpace, Registers_x86 ®isters) { - uint32_t savedRegistersOffset = - EXTRACT_BITS(compactEncoding, UNWIND_X86_EBP_FRAME_OFFSET); - uint32_t savedRegistersLocations = - EXTRACT_BITS(compactEncoding, UNWIND_X86_EBP_FRAME_REGISTERS); - - uint32_t savedRegisters = registers.getEBP() - 4 * savedRegistersOffset; - for (int i = 0; i < 5; ++i) { - switch (savedRegistersLocations & 0x7) { - case UNWIND_X86_REG_NONE: - // no register saved in this slot - break; - case UNWIND_X86_REG_EBX: - registers.setEBX(addressSpace.get32(savedRegisters)); - break; - case UNWIND_X86_REG_ECX: - registers.setECX(addressSpace.get32(savedRegisters)); - break; - case UNWIND_X86_REG_EDX: - registers.setEDX(addressSpace.get32(savedRegisters)); - break; - case UNWIND_X86_REG_EDI: - registers.setEDI(addressSpace.get32(savedRegisters)); - break; - case UNWIND_X86_REG_ESI: - registers.setESI(addressSpace.get32(savedRegisters)); - break; - default: - (void)functionStart; - _LIBUNWIND_DEBUG_LOG("bad register for EBP frame, encoding=%08X for " - "function starting at 0x%X", - compactEncoding, functionStart); - _LIBUNWIND_ABORT("invalid compact unwind encoding"); - } - savedRegisters += 4; - savedRegistersLocations = (savedRegistersLocations >> 3); - } - frameUnwind(addressSpace, registers); - return UNW_STEP_SUCCESS; -} - -template <typename A> -int CompactUnwinder_x86<A>::stepWithCompactEncodingFrameless( - compact_unwind_encoding_t encoding, uint32_t functionStart, - A &addressSpace, Registers_x86 ®isters, bool indirectStackSize) { - uint32_t stackSizeEncoded = - EXTRACT_BITS(encoding, UNWIND_X86_FRAMELESS_STACK_SIZE); - uint32_t stackAdjust = - EXTRACT_BITS(encoding, UNWIND_X86_FRAMELESS_STACK_ADJUST); - uint32_t regCount = - EXTRACT_BITS(encoding, UNWIND_X86_FRAMELESS_STACK_REG_COUNT); - uint32_t permutation = - EXTRACT_BITS(encoding, UNWIND_X86_FRAMELESS_STACK_REG_PERMUTATION); - uint32_t stackSize = stackSizeEncoded * 4; - if (indirectStackSize) { - // stack size is encoded in subl $xxx,%esp instruction - uint32_t subl = addressSpace.get32(functionStart + stackSizeEncoded); - stackSize = subl + 4 * stackAdjust; - } - // decompress permutation - uint32_t permunreg[6]; - switch (regCount) { - case 6: - permunreg[0] = permutation / 120; - permutation -= (permunreg[0] * 120); - permunreg[1] = permutation / 24; - permutation -= (permunreg[1] * 24); - permunreg[2] = permutation / 6; - permutation -= (permunreg[2] * 6); - permunreg[3] = permutation / 2; - permutation -= (permunreg[3] * 2); - permunreg[4] = permutation; - permunreg[5] = 0; - break; - case 5: - permunreg[0] = permutation / 120; - permutation -= (permunreg[0] * 120); - permunreg[1] = permutation / 24; - permutation -= (permunreg[1] * 24); - permunreg[2] = permutation / 6; - permutation -= (permunreg[2] * 6); - permunreg[3] = permutation / 2; - permutation -= (permunreg[3] * 2); - permunreg[4] = permutation; - break; - case 4: - permunreg[0] = permutation / 60; - permutation -= (permunreg[0] * 60); - permunreg[1] = permutation / 12; - permutation -= (permunreg[1] * 12); - permunreg[2] = permutation / 3; - permutation -= (permunreg[2] * 3); - permunreg[3] = permutation; - break; - case 3: - permunreg[0] = permutation / 20; - permutation -= (permunreg[0] * 20); - permunreg[1] = permutation / 4; - permutation -= (permunreg[1] * 4); - permunreg[2] = permutation; - break; - case 2: - permunreg[0] = permutation / 5; - permutation -= (permunreg[0] * 5); - permunreg[1] = permutation; - break; - case 1: - permunreg[0] = permutation; - break; - } - // re-number registers back to standard numbers - int registersSaved[6]; - bool used[7] = { false, false, false, false, false, false, false }; - for (uint32_t i = 0; i < regCount; ++i) { - uint32_t renum = 0; - for (int u = 1; u < 7; ++u) { - if (!used[u]) { - if (renum == permunreg[i]) { - registersSaved[i] = u; - used[u] = true; - break; - } - ++renum; - } - } - } - uint32_t savedRegisters = registers.getSP() + stackSize - 4 - 4 * regCount; - for (uint32_t i = 0; i < regCount; ++i) { - switch (registersSaved[i]) { - case UNWIND_X86_REG_EBX: - registers.setEBX(addressSpace.get32(savedRegisters)); - break; - case UNWIND_X86_REG_ECX: - registers.setECX(addressSpace.get32(savedRegisters)); - break; - case UNWIND_X86_REG_EDX: - registers.setEDX(addressSpace.get32(savedRegisters)); - break; - case UNWIND_X86_REG_EDI: - registers.setEDI(addressSpace.get32(savedRegisters)); - break; - case UNWIND_X86_REG_ESI: - registers.setESI(addressSpace.get32(savedRegisters)); - break; - case UNWIND_X86_REG_EBP: - registers.setEBP(addressSpace.get32(savedRegisters)); - break; - default: - _LIBUNWIND_DEBUG_LOG("bad register for frameless, encoding=%08X for " - "function starting at 0x%X", - encoding, functionStart); - _LIBUNWIND_ABORT("invalid compact unwind encoding"); - } - savedRegisters += 4; - } - framelessUnwind(addressSpace, savedRegisters, registers); - return UNW_STEP_SUCCESS; -} - - -template <typename A> -void CompactUnwinder_x86<A>::frameUnwind(A &addressSpace, - Registers_x86 ®isters) { - typename A::pint_t bp = registers.getEBP(); - // ebp points to old ebp - registers.setEBP(addressSpace.get32(bp)); - // old esp is ebp less saved ebp and return address - registers.setSP((uint32_t)bp + 8); - // pop return address into eip - registers.setIP(addressSpace.get32(bp + 4)); -} - -template <typename A> -void CompactUnwinder_x86<A>::framelessUnwind( - A &addressSpace, typename A::pint_t returnAddressLocation, - Registers_x86 ®isters) { - // return address is on stack after last saved register - registers.setIP(addressSpace.get32(returnAddressLocation)); - // old esp is before return address - registers.setSP((uint32_t)returnAddressLocation + 4); -} -#endif // _LIBUNWIND_TARGET_I386 - - -#if defined(_LIBUNWIND_TARGET_X86_64) -/// CompactUnwinder_x86_64 uses a compact unwind info to virtually "step" (aka -/// unwind) by modifying a Registers_x86_64 register set -template <typename A> -class CompactUnwinder_x86_64 { -public: - - static int stepWithCompactEncoding(compact_unwind_encoding_t compactEncoding, - uint64_t functionStart, A &addressSpace, - Registers_x86_64 ®isters); - -private: - typename A::pint_t pint_t; - - static void frameUnwind(A &addressSpace, Registers_x86_64 ®isters); - static void framelessUnwind(A &addressSpace, uint64_t returnAddressLocation, - Registers_x86_64 ®isters); - static int - stepWithCompactEncodingRBPFrame(compact_unwind_encoding_t compactEncoding, - uint64_t functionStart, A &addressSpace, - Registers_x86_64 ®isters); - static int stepWithCompactEncodingFrameless( - compact_unwind_encoding_t compactEncoding, uint64_t functionStart, - A &addressSpace, Registers_x86_64 ®isters, bool indirectStackSize); -}; - -template <typename A> -int CompactUnwinder_x86_64<A>::stepWithCompactEncoding( - compact_unwind_encoding_t compactEncoding, uint64_t functionStart, - A &addressSpace, Registers_x86_64 ®isters) { - switch (compactEncoding & UNWIND_X86_64_MODE_MASK) { - case UNWIND_X86_64_MODE_RBP_FRAME: - return stepWithCompactEncodingRBPFrame(compactEncoding, functionStart, - addressSpace, registers); - case UNWIND_X86_64_MODE_STACK_IMMD: - return stepWithCompactEncodingFrameless(compactEncoding, functionStart, - addressSpace, registers, false); - case UNWIND_X86_64_MODE_STACK_IND: - return stepWithCompactEncodingFrameless(compactEncoding, functionStart, - addressSpace, registers, true); - } - _LIBUNWIND_ABORT("invalid compact unwind encoding"); -} - -template <typename A> -int CompactUnwinder_x86_64<A>::stepWithCompactEncodingRBPFrame( - compact_unwind_encoding_t compactEncoding, uint64_t functionStart, - A &addressSpace, Registers_x86_64 ®isters) { - uint32_t savedRegistersOffset = - EXTRACT_BITS(compactEncoding, UNWIND_X86_64_RBP_FRAME_OFFSET); - uint32_t savedRegistersLocations = - EXTRACT_BITS(compactEncoding, UNWIND_X86_64_RBP_FRAME_REGISTERS); - - uint64_t savedRegisters = registers.getRBP() - 8 * savedRegistersOffset; - for (int i = 0; i < 5; ++i) { - switch (savedRegistersLocations & 0x7) { - case UNWIND_X86_64_REG_NONE: - // no register saved in this slot - break; - case UNWIND_X86_64_REG_RBX: - registers.setRBX(addressSpace.get64(savedRegisters)); - break; - case UNWIND_X86_64_REG_R12: - registers.setR12(addressSpace.get64(savedRegisters)); - break; - case UNWIND_X86_64_REG_R13: - registers.setR13(addressSpace.get64(savedRegisters)); - break; - case UNWIND_X86_64_REG_R14: - registers.setR14(addressSpace.get64(savedRegisters)); - break; - case UNWIND_X86_64_REG_R15: - registers.setR15(addressSpace.get64(savedRegisters)); - break; - default: - (void)functionStart; - _LIBUNWIND_DEBUG_LOG("bad register for RBP frame, encoding=%08X for " - "function starting at 0x%llX", - compactEncoding, functionStart); - _LIBUNWIND_ABORT("invalid compact unwind encoding"); - } - savedRegisters += 8; - savedRegistersLocations = (savedRegistersLocations >> 3); - } - frameUnwind(addressSpace, registers); - return UNW_STEP_SUCCESS; -} - -template <typename A> -int CompactUnwinder_x86_64<A>::stepWithCompactEncodingFrameless( - compact_unwind_encoding_t encoding, uint64_t functionStart, A &addressSpace, - Registers_x86_64 ®isters, bool indirectStackSize) { - uint32_t stackSizeEncoded = - EXTRACT_BITS(encoding, UNWIND_X86_64_FRAMELESS_STACK_SIZE); - uint32_t stackAdjust = - EXTRACT_BITS(encoding, UNWIND_X86_64_FRAMELESS_STACK_ADJUST); - uint32_t regCount = - EXTRACT_BITS(encoding, UNWIND_X86_64_FRAMELESS_STACK_REG_COUNT); - uint32_t permutation = - EXTRACT_BITS(encoding, UNWIND_X86_64_FRAMELESS_STACK_REG_PERMUTATION); - uint32_t stackSize = stackSizeEncoded * 8; - if (indirectStackSize) { - // stack size is encoded in subl $xxx,%esp instruction - uint32_t subl = addressSpace.get32(functionStart + stackSizeEncoded); - stackSize = subl + 8 * stackAdjust; - } - // decompress permutation - uint32_t permunreg[6]; - switch (regCount) { - case 6: - permunreg[0] = permutation / 120; - permutation -= (permunreg[0] * 120); - permunreg[1] = permutation / 24; - permutation -= (permunreg[1] * 24); - permunreg[2] = permutation / 6; - permutation -= (permunreg[2] * 6); - permunreg[3] = permutation / 2; - permutation -= (permunreg[3] * 2); - permunreg[4] = permutation; - permunreg[5] = 0; - break; - case 5: - permunreg[0] = permutation / 120; - permutation -= (permunreg[0] * 120); - permunreg[1] = permutation / 24; - permutation -= (permunreg[1] * 24); - permunreg[2] = permutation / 6; - permutation -= (permunreg[2] * 6); - permunreg[3] = permutation / 2; - permutation -= (permunreg[3] * 2); - permunreg[4] = permutation; - break; - case 4: - permunreg[0] = permutation / 60; - permutation -= (permunreg[0] * 60); - permunreg[1] = permutation / 12; - permutation -= (permunreg[1] * 12); - permunreg[2] = permutation / 3; - permutation -= (permunreg[2] * 3); - permunreg[3] = permutation; - break; - case 3: - permunreg[0] = permutation / 20; - permutation -= (permunreg[0] * 20); - permunreg[1] = permutation / 4; - permutation -= (permunreg[1] * 4); - permunreg[2] = permutation; - break; - case 2: - permunreg[0] = permutation / 5; - permutation -= (permunreg[0] * 5); - permunreg[1] = permutation; - break; - case 1: - permunreg[0] = permutation; - break; - } - // re-number registers back to standard numbers - int registersSaved[6]; - bool used[7] = { false, false, false, false, false, false, false }; - for (uint32_t i = 0; i < regCount; ++i) { - uint32_t renum = 0; - for (int u = 1; u < 7; ++u) { - if (!used[u]) { - if (renum == permunreg[i]) { - registersSaved[i] = u; - used[u] = true; - break; - } - ++renum; - } - } - } - uint64_t savedRegisters = registers.getSP() + stackSize - 8 - 8 * regCount; - for (uint32_t i = 0; i < regCount; ++i) { - switch (registersSaved[i]) { - case UNWIND_X86_64_REG_RBX: - registers.setRBX(addressSpace.get64(savedRegisters)); - break; - case UNWIND_X86_64_REG_R12: - registers.setR12(addressSpace.get64(savedRegisters)); - break; - case UNWIND_X86_64_REG_R13: - registers.setR13(addressSpace.get64(savedRegisters)); - break; - case UNWIND_X86_64_REG_R14: - registers.setR14(addressSpace.get64(savedRegisters)); - break; - case UNWIND_X86_64_REG_R15: - registers.setR15(addressSpace.get64(savedRegisters)); - break; - case UNWIND_X86_64_REG_RBP: - registers.setRBP(addressSpace.get64(savedRegisters)); - break; - default: - _LIBUNWIND_DEBUG_LOG("bad register for frameless, encoding=%08X for " - "function starting at 0x%llX", - encoding, functionStart); - _LIBUNWIND_ABORT("invalid compact unwind encoding"); - } - savedRegisters += 8; - } - framelessUnwind(addressSpace, savedRegisters, registers); - return UNW_STEP_SUCCESS; -} - - -template <typename A> -void CompactUnwinder_x86_64<A>::frameUnwind(A &addressSpace, - Registers_x86_64 ®isters) { - uint64_t rbp = registers.getRBP(); - // ebp points to old ebp - registers.setRBP(addressSpace.get64(rbp)); - // old esp is ebp less saved ebp and return address - registers.setSP(rbp + 16); - // pop return address into eip - registers.setIP(addressSpace.get64(rbp + 8)); -} - -template <typename A> -void CompactUnwinder_x86_64<A>::framelessUnwind(A &addressSpace, - uint64_t returnAddressLocation, - Registers_x86_64 ®isters) { - // return address is on stack after last saved register - registers.setIP(addressSpace.get64(returnAddressLocation)); - // old esp is before return address - registers.setSP(returnAddressLocation + 8); -} -#endif // _LIBUNWIND_TARGET_X86_64 - - - -#if defined(_LIBUNWIND_TARGET_AARCH64) -/// CompactUnwinder_arm64 uses a compact unwind info to virtually "step" (aka -/// unwind) by modifying a Registers_arm64 register set -template <typename A> -class CompactUnwinder_arm64 { -public: - - static int stepWithCompactEncoding(compact_unwind_encoding_t compactEncoding, - uint64_t functionStart, A &addressSpace, - Registers_arm64 ®isters); - -private: - typename A::pint_t pint_t; - - static int - stepWithCompactEncodingFrame(compact_unwind_encoding_t compactEncoding, - uint64_t functionStart, A &addressSpace, - Registers_arm64 ®isters); - static int stepWithCompactEncodingFrameless( - compact_unwind_encoding_t compactEncoding, uint64_t functionStart, - A &addressSpace, Registers_arm64 ®isters); -}; - -template <typename A> -int CompactUnwinder_arm64<A>::stepWithCompactEncoding( - compact_unwind_encoding_t compactEncoding, uint64_t functionStart, - A &addressSpace, Registers_arm64 ®isters) { - switch (compactEncoding & UNWIND_ARM64_MODE_MASK) { - case UNWIND_ARM64_MODE_FRAME: - return stepWithCompactEncodingFrame(compactEncoding, functionStart, - addressSpace, registers); - case UNWIND_ARM64_MODE_FRAMELESS: - return stepWithCompactEncodingFrameless(compactEncoding, functionStart, - addressSpace, registers); - } - _LIBUNWIND_ABORT("invalid compact unwind encoding"); -} - -template <typename A> -int CompactUnwinder_arm64<A>::stepWithCompactEncodingFrameless( - compact_unwind_encoding_t encoding, uint64_t, A &addressSpace, - Registers_arm64 ®isters) { - uint32_t stackSize = - 16 * EXTRACT_BITS(encoding, UNWIND_ARM64_FRAMELESS_STACK_SIZE_MASK); - - uint64_t savedRegisterLoc = registers.getSP() + stackSize; - - if (encoding & UNWIND_ARM64_FRAME_X19_X20_PAIR) { - registers.setRegister(UNW_ARM64_X19, addressSpace.get64(savedRegisterLoc)); - savedRegisterLoc -= 8; - registers.setRegister(UNW_ARM64_X20, addressSpace.get64(savedRegisterLoc)); - savedRegisterLoc -= 8; - } - if (encoding & UNWIND_ARM64_FRAME_X21_X22_PAIR) { - registers.setRegister(UNW_ARM64_X21, addressSpace.get64(savedRegisterLoc)); - savedRegisterLoc -= 8; - registers.setRegister(UNW_ARM64_X22, addressSpace.get64(savedRegisterLoc)); - savedRegisterLoc -= 8; - } - if (encoding & UNWIND_ARM64_FRAME_X23_X24_PAIR) { - registers.setRegister(UNW_ARM64_X23, addressSpace.get64(savedRegisterLoc)); - savedRegisterLoc -= 8; - registers.setRegister(UNW_ARM64_X24, addressSpace.get64(savedRegisterLoc)); - savedRegisterLoc -= 8; - } - if (encoding & UNWIND_ARM64_FRAME_X25_X26_PAIR) { - registers.setRegister(UNW_ARM64_X25, addressSpace.get64(savedRegisterLoc)); - savedRegisterLoc -= 8; - registers.setRegister(UNW_ARM64_X26, addressSpace.get64(savedRegisterLoc)); - savedRegisterLoc -= 8; - } - if (encoding & UNWIND_ARM64_FRAME_X27_X28_PAIR) { - registers.setRegister(UNW_ARM64_X27, addressSpace.get64(savedRegisterLoc)); - savedRegisterLoc -= 8; - registers.setRegister(UNW_ARM64_X28, addressSpace.get64(savedRegisterLoc)); - savedRegisterLoc -= 8; - } - - if (encoding & UNWIND_ARM64_FRAME_D8_D9_PAIR) { - registers.setFloatRegister(UNW_ARM64_D8, - addressSpace.getDouble(savedRegisterLoc)); - savedRegisterLoc -= 8; - registers.setFloatRegister(UNW_ARM64_D9, - addressSpace.getDouble(savedRegisterLoc)); - savedRegisterLoc -= 8; - } - if (encoding & UNWIND_ARM64_FRAME_D10_D11_PAIR) { - registers.setFloatRegister(UNW_ARM64_D10, - addressSpace.getDouble(savedRegisterLoc)); - savedRegisterLoc -= 8; - registers.setFloatRegister(UNW_ARM64_D11, - addressSpace.getDouble(savedRegisterLoc)); - savedRegisterLoc -= 8; - } - if (encoding & UNWIND_ARM64_FRAME_D12_D13_PAIR) { - registers.setFloatRegister(UNW_ARM64_D12, - addressSpace.getDouble(savedRegisterLoc)); - savedRegisterLoc -= 8; - registers.setFloatRegister(UNW_ARM64_D13, - addressSpace.getDouble(savedRegisterLoc)); - savedRegisterLoc -= 8; - } - if (encoding & UNWIND_ARM64_FRAME_D14_D15_PAIR) { - registers.setFloatRegister(UNW_ARM64_D14, - addressSpace.getDouble(savedRegisterLoc)); - savedRegisterLoc -= 8; - registers.setFloatRegister(UNW_ARM64_D15, - addressSpace.getDouble(savedRegisterLoc)); - savedRegisterLoc -= 8; - } - - // subtract stack size off of sp - registers.setSP(savedRegisterLoc); - - // set pc to be value in lr - registers.setIP(registers.getRegister(UNW_ARM64_LR)); - - return UNW_STEP_SUCCESS; -} - -template <typename A> -int CompactUnwinder_arm64<A>::stepWithCompactEncodingFrame( - compact_unwind_encoding_t encoding, uint64_t, A &addressSpace, - Registers_arm64 ®isters) { - uint64_t savedRegisterLoc = registers.getFP() - 8; - - if (encoding & UNWIND_ARM64_FRAME_X19_X20_PAIR) { - registers.setRegister(UNW_ARM64_X19, addressSpace.get64(savedRegisterLoc)); - savedRegisterLoc -= 8; - registers.setRegister(UNW_ARM64_X20, addressSpace.get64(savedRegisterLoc)); - savedRegisterLoc -= 8; - } - if (encoding & UNWIND_ARM64_FRAME_X21_X22_PAIR) { - registers.setRegister(UNW_ARM64_X21, addressSpace.get64(savedRegisterLoc)); - savedRegisterLoc -= 8; - registers.setRegister(UNW_ARM64_X22, addressSpace.get64(savedRegisterLoc)); - savedRegisterLoc -= 8; - } - if (encoding & UNWIND_ARM64_FRAME_X23_X24_PAIR) { - registers.setRegister(UNW_ARM64_X23, addressSpace.get64(savedRegisterLoc)); - savedRegisterLoc -= 8; - registers.setRegister(UNW_ARM64_X24, addressSpace.get64(savedRegisterLoc)); - savedRegisterLoc -= 8; - } - if (encoding & UNWIND_ARM64_FRAME_X25_X26_PAIR) { - registers.setRegister(UNW_ARM64_X25, addressSpace.get64(savedRegisterLoc)); - savedRegisterLoc -= 8; - registers.setRegister(UNW_ARM64_X26, addressSpace.get64(savedRegisterLoc)); - savedRegisterLoc -= 8; - } - if (encoding & UNWIND_ARM64_FRAME_X27_X28_PAIR) { - registers.setRegister(UNW_ARM64_X27, addressSpace.get64(savedRegisterLoc)); - savedRegisterLoc -= 8; - registers.setRegister(UNW_ARM64_X28, addressSpace.get64(savedRegisterLoc)); - savedRegisterLoc -= 8; - } - - if (encoding & UNWIND_ARM64_FRAME_D8_D9_PAIR) { - registers.setFloatRegister(UNW_ARM64_D8, - addressSpace.getDouble(savedRegisterLoc)); - savedRegisterLoc -= 8; - registers.setFloatRegister(UNW_ARM64_D9, - addressSpace.getDouble(savedRegisterLoc)); - savedRegisterLoc -= 8; - } - if (encoding & UNWIND_ARM64_FRAME_D10_D11_PAIR) { - registers.setFloatRegister(UNW_ARM64_D10, - addressSpace.getDouble(savedRegisterLoc)); - savedRegisterLoc -= 8; - registers.setFloatRegister(UNW_ARM64_D11, - addressSpace.getDouble(savedRegisterLoc)); - savedRegisterLoc -= 8; - } - if (encoding & UNWIND_ARM64_FRAME_D12_D13_PAIR) { - registers.setFloatRegister(UNW_ARM64_D12, - addressSpace.getDouble(savedRegisterLoc)); - savedRegisterLoc -= 8; - registers.setFloatRegister(UNW_ARM64_D13, - addressSpace.getDouble(savedRegisterLoc)); - savedRegisterLoc -= 8; - } - if (encoding & UNWIND_ARM64_FRAME_D14_D15_PAIR) { - registers.setFloatRegister(UNW_ARM64_D14, - addressSpace.getDouble(savedRegisterLoc)); - savedRegisterLoc -= 8; - registers.setFloatRegister(UNW_ARM64_D15, - addressSpace.getDouble(savedRegisterLoc)); - savedRegisterLoc -= 8; - } - - uint64_t fp = registers.getFP(); - // fp points to old fp - registers.setFP(addressSpace.get64(fp)); - // old sp is fp less saved fp and lr - registers.setSP(fp + 16); - // pop return address into pc - registers.setIP(addressSpace.get64(fp + 8)); - - return UNW_STEP_SUCCESS; -} -#endif // _LIBUNWIND_TARGET_AARCH64 - - -} // namespace libunwind - -#endif // __COMPACT_UNWINDER_HPP__ diff --git a/chromium/buildtools/third_party/libunwind/trunk/src/DwarfInstructions.hpp b/chromium/buildtools/third_party/libunwind/trunk/src/DwarfInstructions.hpp deleted file mode 100644 index bd1448b2842..00000000000 --- a/chromium/buildtools/third_party/libunwind/trunk/src/DwarfInstructions.hpp +++ /dev/null @@ -1,759 +0,0 @@ -//===-------------------------- DwarfInstructions.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. -// -// -// Processor specific interpretation of DWARF unwind info. -// -//===----------------------------------------------------------------------===// - -#ifndef __DWARF_INSTRUCTIONS_HPP__ -#define __DWARF_INSTRUCTIONS_HPP__ - -#include <stdint.h> -#include <stdio.h> -#include <stdlib.h> - -#include "dwarf2.h" -#include "Registers.hpp" -#include "DwarfParser.hpp" -#include "config.h" - - -namespace libunwind { - - -/// DwarfInstructions maps abtract DWARF unwind instructions to a particular -/// architecture -template <typename A, typename R> -class DwarfInstructions { -public: - typedef typename A::pint_t pint_t; - typedef typename A::sint_t sint_t; - - static int stepWithDwarf(A &addressSpace, pint_t pc, pint_t fdeStart, - R ®isters); - -private: - - enum { - DW_X86_64_RET_ADDR = 16 - }; - - enum { - DW_X86_RET_ADDR = 8 - }; - - typedef typename CFI_Parser<A>::RegisterLocation RegisterLocation; - typedef typename CFI_Parser<A>::PrologInfo PrologInfo; - typedef typename CFI_Parser<A>::FDE_Info FDE_Info; - typedef typename CFI_Parser<A>::CIE_Info CIE_Info; - - static pint_t evaluateExpression(pint_t expression, A &addressSpace, - const R ®isters, - pint_t initialStackValue); - static pint_t getSavedRegister(A &addressSpace, const R ®isters, - pint_t cfa, const RegisterLocation &savedReg); - static double getSavedFloatRegister(A &addressSpace, const R ®isters, - pint_t cfa, const RegisterLocation &savedReg); - static v128 getSavedVectorRegister(A &addressSpace, const R ®isters, - pint_t cfa, const RegisterLocation &savedReg); - - static pint_t getCFA(A &addressSpace, const PrologInfo &prolog, - const R ®isters) { - if (prolog.cfaRegister != 0) - return (pint_t)((sint_t)registers.getRegister((int)prolog.cfaRegister) + - prolog.cfaRegisterOffset); - if (prolog.cfaExpression != 0) - return evaluateExpression((pint_t)prolog.cfaExpression, addressSpace, - registers, 0); - assert(0 && "getCFA(): unknown location"); - __builtin_unreachable(); - } -}; - - -template <typename A, typename R> -typename A::pint_t DwarfInstructions<A, R>::getSavedRegister( - A &addressSpace, const R ®isters, pint_t cfa, - const RegisterLocation &savedReg) { - switch (savedReg.location) { - case CFI_Parser<A>::kRegisterInCFA: - return addressSpace.getP(cfa + (pint_t)savedReg.value); - - case CFI_Parser<A>::kRegisterAtExpression: - return addressSpace.getP( - evaluateExpression((pint_t)savedReg.value, addressSpace, - registers, cfa)); - - case CFI_Parser<A>::kRegisterIsExpression: - return evaluateExpression((pint_t)savedReg.value, addressSpace, - registers, cfa); - - case CFI_Parser<A>::kRegisterInRegister: - return registers.getRegister((int)savedReg.value); - - case CFI_Parser<A>::kRegisterUnused: - case CFI_Parser<A>::kRegisterOffsetFromCFA: - // FIX ME - break; - } - _LIBUNWIND_ABORT("unsupported restore location for register"); -} - -template <typename A, typename R> -double DwarfInstructions<A, R>::getSavedFloatRegister( - A &addressSpace, const R ®isters, pint_t cfa, - const RegisterLocation &savedReg) { - switch (savedReg.location) { - case CFI_Parser<A>::kRegisterInCFA: - return addressSpace.getDouble(cfa + (pint_t)savedReg.value); - - case CFI_Parser<A>::kRegisterAtExpression: - return addressSpace.getDouble( - evaluateExpression((pint_t)savedReg.value, addressSpace, - registers, cfa)); - - case CFI_Parser<A>::kRegisterIsExpression: - case CFI_Parser<A>::kRegisterUnused: - case CFI_Parser<A>::kRegisterOffsetFromCFA: - case CFI_Parser<A>::kRegisterInRegister: - // FIX ME - break; - } - _LIBUNWIND_ABORT("unsupported restore location for float register"); -} - -template <typename A, typename R> -v128 DwarfInstructions<A, R>::getSavedVectorRegister( - A &addressSpace, const R ®isters, pint_t cfa, - const RegisterLocation &savedReg) { - switch (savedReg.location) { - case CFI_Parser<A>::kRegisterInCFA: - return addressSpace.getVector(cfa + (pint_t)savedReg.value); - - case CFI_Parser<A>::kRegisterAtExpression: - return addressSpace.getVector( - evaluateExpression((pint_t)savedReg.value, addressSpace, - registers, cfa)); - - case CFI_Parser<A>::kRegisterIsExpression: - case CFI_Parser<A>::kRegisterUnused: - case CFI_Parser<A>::kRegisterOffsetFromCFA: - case CFI_Parser<A>::kRegisterInRegister: - // FIX ME - break; - } - _LIBUNWIND_ABORT("unsupported restore location for vector register"); -} - -template <typename A, typename R> -int DwarfInstructions<A, R>::stepWithDwarf(A &addressSpace, pint_t pc, - pint_t fdeStart, R ®isters) { - FDE_Info fdeInfo; - CIE_Info cieInfo; - if (CFI_Parser<A>::decodeFDE(addressSpace, fdeStart, &fdeInfo, - &cieInfo) == NULL) { - PrologInfo prolog; - if (CFI_Parser<A>::parseFDEInstructions(addressSpace, fdeInfo, cieInfo, pc, - &prolog)) { - // get pointer to cfa (architecture specific) - pint_t cfa = getCFA(addressSpace, prolog, registers); - - // restore registers that DWARF says were saved - R newRegisters = registers; - pint_t returnAddress = 0; - const int lastReg = R::lastDwarfRegNum(); - assert(static_cast<int>(CFI_Parser<A>::kMaxRegisterNumber) >= lastReg && - "register range too large"); - assert(lastReg >= (int)cieInfo.returnAddressRegister && - "register range does not contain return address register"); - for (int i = 0; i <= lastReg; ++i) { - if (prolog.savedRegisters[i].location != - CFI_Parser<A>::kRegisterUnused) { - if (registers.validFloatRegister(i)) - newRegisters.setFloatRegister( - i, getSavedFloatRegister(addressSpace, registers, cfa, - prolog.savedRegisters[i])); - else if (registers.validVectorRegister(i)) - newRegisters.setVectorRegister( - i, getSavedVectorRegister(addressSpace, registers, cfa, - prolog.savedRegisters[i])); - else if (i == (int)cieInfo.returnAddressRegister) - returnAddress = getSavedRegister(addressSpace, registers, cfa, - prolog.savedRegisters[i]); - else if (registers.validRegister(i)) - newRegisters.setRegister( - i, getSavedRegister(addressSpace, registers, cfa, - prolog.savedRegisters[i])); - else - return UNW_EBADREG; - } - } - - // By definition, the CFA is the stack pointer at the call site, so - // restoring SP means setting it to CFA. - newRegisters.setSP(cfa); - - // Return address is address after call site instruction, so setting IP to - // that does simualates a return. - newRegisters.setIP(returnAddress); - - // Simulate the step by replacing the register set with the new ones. - registers = newRegisters; - - return UNW_STEP_SUCCESS; - } - } - return UNW_EBADFRAME; -} - -template <typename A, typename R> -typename A::pint_t -DwarfInstructions<A, R>::evaluateExpression(pint_t expression, A &addressSpace, - const R ®isters, - pint_t initialStackValue) { - const bool log = false; - pint_t p = expression; - pint_t expressionEnd = expression + 20; // temp, until len read - pint_t length = (pint_t)addressSpace.getULEB128(p, expressionEnd); - expressionEnd = p + length; - if (log) - fprintf(stderr, "evaluateExpression(): length=%" PRIu64 "\n", - (uint64_t)length); - pint_t stack[100]; - pint_t *sp = stack; - *(++sp) = initialStackValue; - - while (p < expressionEnd) { - if (log) { - for (pint_t *t = sp; t > stack; --t) { - fprintf(stderr, "sp[] = 0x%" PRIx64 "\n", (uint64_t)(*t)); - } - } - uint8_t opcode = addressSpace.get8(p++); - sint_t svalue, svalue2; - pint_t value; - uint32_t reg; - switch (opcode) { - case DW_OP_addr: - // push immediate address sized value - value = addressSpace.getP(p); - p += sizeof(pint_t); - *(++sp) = value; - if (log) - fprintf(stderr, "push 0x%" PRIx64 "\n", (uint64_t)value); - break; - - case DW_OP_deref: - // pop stack, dereference, push result - value = *sp--; - *(++sp) = addressSpace.getP(value); - if (log) - fprintf(stderr, "dereference 0x%" PRIx64 "\n", (uint64_t)value); - break; - - case DW_OP_const1u: - // push immediate 1 byte value - value = addressSpace.get8(p); - p += 1; - *(++sp) = value; - if (log) - fprintf(stderr, "push 0x%" PRIx64 "\n", (uint64_t)value); - break; - - case DW_OP_const1s: - // push immediate 1 byte signed value - svalue = (int8_t) addressSpace.get8(p); - p += 1; - *(++sp) = (pint_t)svalue; - if (log) - fprintf(stderr, "push 0x%" PRIx64 "\n", (uint64_t)svalue); - break; - - case DW_OP_const2u: - // push immediate 2 byte value - value = addressSpace.get16(p); - p += 2; - *(++sp) = value; - if (log) - fprintf(stderr, "push 0x%" PRIx64 "\n", (uint64_t)value); - break; - - case DW_OP_const2s: - // push immediate 2 byte signed value - svalue = (int16_t) addressSpace.get16(p); - p += 2; - *(++sp) = (pint_t)svalue; - if (log) - fprintf(stderr, "push 0x%" PRIx64 "\n", (uint64_t)svalue); - break; - - case DW_OP_const4u: - // push immediate 4 byte value - value = addressSpace.get32(p); - p += 4; - *(++sp) = value; - if (log) - fprintf(stderr, "push 0x%" PRIx64 "\n", (uint64_t)value); - break; - - case DW_OP_const4s: - // push immediate 4 byte signed value - svalue = (int32_t)addressSpace.get32(p); - p += 4; - *(++sp) = (pint_t)svalue; - if (log) - fprintf(stderr, "push 0x%" PRIx64 "\n", (uint64_t)svalue); - break; - - case DW_OP_const8u: - // push immediate 8 byte value - value = (pint_t)addressSpace.get64(p); - p += 8; - *(++sp) = value; - if (log) - fprintf(stderr, "push 0x%" PRIx64 "\n", (uint64_t)value); - break; - - case DW_OP_const8s: - // push immediate 8 byte signed value - value = (pint_t)addressSpace.get64(p); - p += 8; - *(++sp) = value; - if (log) - fprintf(stderr, "push 0x%" PRIx64 "\n", (uint64_t)value); - break; - - case DW_OP_constu: - // push immediate ULEB128 value - value = (pint_t)addressSpace.getULEB128(p, expressionEnd); - *(++sp) = value; - if (log) - fprintf(stderr, "push 0x%" PRIx64 "\n", (uint64_t)value); - break; - - case DW_OP_consts: - // push immediate SLEB128 value - svalue = (sint_t)addressSpace.getSLEB128(p, expressionEnd); - *(++sp) = (pint_t)svalue; - if (log) - fprintf(stderr, "push 0x%" PRIx64 "\n", (uint64_t)svalue); - break; - - case DW_OP_dup: - // push top of stack - value = *sp; - *(++sp) = value; - if (log) - fprintf(stderr, "duplicate top of stack\n"); - break; - - case DW_OP_drop: - // pop - --sp; - if (log) - fprintf(stderr, "pop top of stack\n"); - break; - - case DW_OP_over: - // dup second - value = sp[-1]; - *(++sp) = value; - if (log) - fprintf(stderr, "duplicate second in stack\n"); - break; - - case DW_OP_pick: - // pick from - reg = addressSpace.get8(p); - p += 1; - value = sp[-reg]; - *(++sp) = value; - if (log) - fprintf(stderr, "duplicate %d in stack\n", reg); - break; - - case DW_OP_swap: - // swap top two - value = sp[0]; - sp[0] = sp[-1]; - sp[-1] = value; - if (log) - fprintf(stderr, "swap top of stack\n"); - break; - - case DW_OP_rot: - // rotate top three - value = sp[0]; - sp[0] = sp[-1]; - sp[-1] = sp[-2]; - sp[-2] = value; - if (log) - fprintf(stderr, "rotate top three of stack\n"); - break; - - case DW_OP_xderef: - // pop stack, dereference, push result - value = *sp--; - *sp = *((pint_t*)value); - if (log) - fprintf(stderr, "x-dereference 0x%" PRIx64 "\n", (uint64_t)value); - break; - - case DW_OP_abs: - svalue = (sint_t)*sp; - if (svalue < 0) - *sp = (pint_t)(-svalue); - if (log) - fprintf(stderr, "abs\n"); - break; - - case DW_OP_and: - value = *sp--; - *sp &= value; - if (log) - fprintf(stderr, "and\n"); - break; - - case DW_OP_div: - svalue = (sint_t)(*sp--); - svalue2 = (sint_t)*sp; - *sp = (pint_t)(svalue2 / svalue); - if (log) - fprintf(stderr, "div\n"); - break; - - case DW_OP_minus: - value = *sp--; - *sp = *sp - value; - if (log) - fprintf(stderr, "minus\n"); - break; - - case DW_OP_mod: - svalue = (sint_t)(*sp--); - svalue2 = (sint_t)*sp; - *sp = (pint_t)(svalue2 % svalue); - if (log) - fprintf(stderr, "module\n"); - break; - - case DW_OP_mul: - svalue = (sint_t)(*sp--); - svalue2 = (sint_t)*sp; - *sp = (pint_t)(svalue2 * svalue); - if (log) - fprintf(stderr, "mul\n"); - break; - - case DW_OP_neg: - *sp = 0 - *sp; - if (log) - fprintf(stderr, "neg\n"); - break; - - case DW_OP_not: - svalue = (sint_t)(*sp); - *sp = (pint_t)(~svalue); - if (log) - fprintf(stderr, "not\n"); - break; - - case DW_OP_or: - value = *sp--; - *sp |= value; - if (log) - fprintf(stderr, "or\n"); - break; - - case DW_OP_plus: - value = *sp--; - *sp += value; - if (log) - fprintf(stderr, "plus\n"); - break; - - case DW_OP_plus_uconst: - // pop stack, add uelb128 constant, push result - *sp += static_cast<pint_t>(addressSpace.getULEB128(p, expressionEnd)); - if (log) - fprintf(stderr, "add constant\n"); - break; - - case DW_OP_shl: - value = *sp--; - *sp = *sp << value; - if (log) - fprintf(stderr, "shift left\n"); - break; - - case DW_OP_shr: - value = *sp--; - *sp = *sp >> value; - if (log) - fprintf(stderr, "shift left\n"); - break; - - case DW_OP_shra: - value = *sp--; - svalue = (sint_t)*sp; - *sp = (pint_t)(svalue >> value); - if (log) - fprintf(stderr, "shift left arithmetric\n"); - break; - - case DW_OP_xor: - value = *sp--; - *sp ^= value; - if (log) - fprintf(stderr, "xor\n"); - break; - - case DW_OP_skip: - svalue = (int16_t) addressSpace.get16(p); - p += 2; - p = (pint_t)((sint_t)p + svalue); - if (log) - fprintf(stderr, "skip %" PRIu64 "\n", (uint64_t)svalue); - break; - - case DW_OP_bra: - svalue = (int16_t) addressSpace.get16(p); - p += 2; - if (*sp--) - p = (pint_t)((sint_t)p + svalue); - if (log) - fprintf(stderr, "bra %" PRIu64 "\n", (uint64_t)svalue); - break; - - case DW_OP_eq: - value = *sp--; - *sp = (*sp == value); - if (log) - fprintf(stderr, "eq\n"); - break; - - case DW_OP_ge: - value = *sp--; - *sp = (*sp >= value); - if (log) - fprintf(stderr, "ge\n"); - break; - - case DW_OP_gt: - value = *sp--; - *sp = (*sp > value); - if (log) - fprintf(stderr, "gt\n"); - break; - - case DW_OP_le: - value = *sp--; - *sp = (*sp <= value); - if (log) - fprintf(stderr, "le\n"); - break; - - case DW_OP_lt: - value = *sp--; - *sp = (*sp < value); - if (log) - fprintf(stderr, "lt\n"); - break; - - case DW_OP_ne: - value = *sp--; - *sp = (*sp != value); - if (log) - fprintf(stderr, "ne\n"); - break; - - case DW_OP_lit0: - case DW_OP_lit1: - case DW_OP_lit2: - case DW_OP_lit3: - case DW_OP_lit4: - case DW_OP_lit5: - case DW_OP_lit6: - case DW_OP_lit7: - case DW_OP_lit8: - case DW_OP_lit9: - case DW_OP_lit10: - case DW_OP_lit11: - case DW_OP_lit12: - case DW_OP_lit13: - case DW_OP_lit14: - case DW_OP_lit15: - case DW_OP_lit16: - case DW_OP_lit17: - case DW_OP_lit18: - case DW_OP_lit19: - case DW_OP_lit20: - case DW_OP_lit21: - case DW_OP_lit22: - case DW_OP_lit23: - case DW_OP_lit24: - case DW_OP_lit25: - case DW_OP_lit26: - case DW_OP_lit27: - case DW_OP_lit28: - case DW_OP_lit29: - case DW_OP_lit30: - case DW_OP_lit31: - value = static_cast<pint_t>(opcode - DW_OP_lit0); - *(++sp) = value; - if (log) - fprintf(stderr, "push literal 0x%" PRIx64 "\n", (uint64_t)value); - break; - - case DW_OP_reg0: - case DW_OP_reg1: - case DW_OP_reg2: - case DW_OP_reg3: - case DW_OP_reg4: - case DW_OP_reg5: - case DW_OP_reg6: - case DW_OP_reg7: - case DW_OP_reg8: - case DW_OP_reg9: - case DW_OP_reg10: - case DW_OP_reg11: - case DW_OP_reg12: - case DW_OP_reg13: - case DW_OP_reg14: - case DW_OP_reg15: - case DW_OP_reg16: - case DW_OP_reg17: - case DW_OP_reg18: - case DW_OP_reg19: - case DW_OP_reg20: - case DW_OP_reg21: - case DW_OP_reg22: - case DW_OP_reg23: - case DW_OP_reg24: - case DW_OP_reg25: - case DW_OP_reg26: - case DW_OP_reg27: - case DW_OP_reg28: - case DW_OP_reg29: - case DW_OP_reg30: - case DW_OP_reg31: - 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 = 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); - break; - - case DW_OP_breg0: - case DW_OP_breg1: - case DW_OP_breg2: - case DW_OP_breg3: - case DW_OP_breg4: - case DW_OP_breg5: - case DW_OP_breg6: - case DW_OP_breg7: - case DW_OP_breg8: - case DW_OP_breg9: - case DW_OP_breg10: - case DW_OP_breg11: - case DW_OP_breg12: - case DW_OP_breg13: - case DW_OP_breg14: - case DW_OP_breg15: - case DW_OP_breg16: - case DW_OP_breg17: - case DW_OP_breg18: - case DW_OP_breg19: - case DW_OP_breg20: - case DW_OP_breg21: - case DW_OP_breg22: - case DW_OP_breg23: - case DW_OP_breg24: - case DW_OP_breg25: - case DW_OP_breg26: - case DW_OP_breg27: - case DW_OP_breg28: - case DW_OP_breg29: - case DW_OP_breg30: - case DW_OP_breg31: - reg = static_cast<uint32_t>(opcode - DW_OP_breg0); - svalue = (sint_t)addressSpace.getSLEB128(p, expressionEnd); - 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 = static_cast<uint32_t>(addressSpace.getULEB128(p, expressionEnd)); - svalue = (sint_t)addressSpace.getSLEB128(p, expressionEnd); - 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_fbreg: - _LIBUNWIND_ABORT("DW_OP_fbreg not implemented"); - break; - - case DW_OP_piece: - _LIBUNWIND_ABORT("DW_OP_piece not implemented"); - break; - - case DW_OP_deref_size: - // pop stack, dereference, push result - value = *sp--; - switch (addressSpace.get8(p++)) { - case 1: - value = addressSpace.get8(value); - break; - case 2: - value = addressSpace.get16(value); - break; - case 4: - value = addressSpace.get32(value); - break; - case 8: - value = (pint_t)addressSpace.get64(value); - break; - default: - _LIBUNWIND_ABORT("DW_OP_deref_size with bad size"); - } - *(++sp) = value; - if (log) - fprintf(stderr, "sized dereference 0x%" PRIx64 "\n", (uint64_t)value); - break; - - case DW_OP_xderef_size: - case DW_OP_nop: - case DW_OP_push_object_addres: - case DW_OP_call2: - case DW_OP_call4: - case DW_OP_call_ref: - default: - _LIBUNWIND_ABORT("DWARF opcode not implemented"); - } - - } - if (log) - fprintf(stderr, "expression evaluates to 0x%" PRIx64 "\n", (uint64_t)*sp); - return *sp; -} - - - -} // namespace libunwind - -#endif // __DWARF_INSTRUCTIONS_HPP__ diff --git a/chromium/buildtools/third_party/libunwind/trunk/src/DwarfParser.hpp b/chromium/buildtools/third_party/libunwind/trunk/src/DwarfParser.hpp deleted file mode 100644 index 95af7a6ffa0..00000000000 --- a/chromium/buildtools/third_party/libunwind/trunk/src/DwarfParser.hpp +++ /dev/null @@ -1,720 +0,0 @@ -//===--------------------------- DwarfParser.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 DWARF CFIs (FDEs and CIEs). -// -//===----------------------------------------------------------------------===// - -#ifndef __DWARF_PARSER_HPP__ -#define __DWARF_PARSER_HPP__ - -#include <inttypes.h> -#include <stdint.h> -#include <stdio.h> -#include <stdlib.h> -#include <limits> - -#include "libunwind.h" -#include "dwarf2.h" - -#include "config.h" - -namespace libunwind { - -/// CFI_Parser does basic parsing of a CFI (Call Frame Information) records. -/// 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 CFI_Parser { -public: - typedef typename A::pint_t pint_t; - - /// Information encoded in a CIE (Common Information Entry) - struct CIE_Info { - pint_t cieStart; - pint_t cieLength; - pint_t cieInstructions; - uint8_t pointerEncoding; - uint8_t lsdaEncoding; - uint8_t personalityEncoding; - uint8_t personalityOffsetInCIE; - pint_t personality; - uint32_t codeAlignFactor; - int dataAlignFactor; - bool isSignalFrame; - bool fdesHaveAugmentationData; - uint8_t returnAddressRegister; - }; - - /// Information about an FDE (Frame Description Entry) - struct FDE_Info { - pint_t fdeStart; - pint_t fdeLength; - pint_t fdeInstructions; - pint_t pcStart; - pint_t pcEnd; - pint_t lsda; - }; - - enum { - kMaxRegisterNumber = _LIBUNWIND_HIGHEST_DWARF_REGISTER - }; - enum RegisterSavedWhere { - kRegisterUnused, - kRegisterInCFA, - kRegisterOffsetFromCFA, - kRegisterInRegister, - kRegisterAtExpression, - kRegisterIsExpression - }; - struct RegisterLocation { - RegisterSavedWhere location; - int64_t value; - }; - /// Information about a frame layout and registers saved determined - /// by "running" the DWARF FDE "instructions" - struct PrologInfo { - uint32_t cfaRegister; - int32_t cfaRegisterOffset; // CFA = (cfaRegister)+cfaRegisterOffset - int64_t cfaExpression; // CFA = expression - uint32_t spExtraArgSize; - uint32_t codeOffsetAtStackDecrement; - bool registersInOtherRegisters; - bool sameValueUsed; - RegisterLocation savedRegisters[kMaxRegisterNumber + 1]; - }; - - struct PrologInfoStackEntry { - PrologInfoStackEntry(PrologInfoStackEntry *n, const PrologInfo &i) - : next(n), info(i) {} - PrologInfoStackEntry *next; - PrologInfo info; - }; - - static bool findFDE(A &addressSpace, pint_t pc, pint_t ehSectionStart, - uint32_t sectionLength, pint_t fdeHint, FDE_Info *fdeInfo, - CIE_Info *cieInfo); - static const char *decodeFDE(A &addressSpace, pint_t fdeStart, - FDE_Info *fdeInfo, CIE_Info *cieInfo); - static bool parseFDEInstructions(A &addressSpace, const FDE_Info &fdeInfo, - const CIE_Info &cieInfo, pint_t upToPC, - PrologInfo *results); - - static const char *parseCIE(A &addressSpace, pint_t cie, CIE_Info *cieInfo); - -private: - static bool parseInstructions(A &addressSpace, pint_t instructions, - pint_t instructionsEnd, const CIE_Info &cieInfo, - pint_t pcoffset, - PrologInfoStackEntry *&rememberStack, - PrologInfo *results); -}; - -/// Parse a FDE into a CIE_Info and an FDE_Info -template <typename A> -const char *CFI_Parser<A>::decodeFDE(A &addressSpace, pint_t fdeStart, - FDE_Info *fdeInfo, CIE_Info *cieInfo) { - pint_t p = fdeStart; - pint_t cfiLength = (pint_t)addressSpace.get32(p); - p += 4; - if (cfiLength == 0xffffffff) { - // 0xffffffff means length is really next 8 bytes - cfiLength = (pint_t)addressSpace.get64(p); - p += 8; - } - if (cfiLength == 0) - return "FDE has zero length"; // end marker - uint32_t ciePointer = addressSpace.get32(p); - if (ciePointer == 0) - return "FDE is really a CIE"; // this is a CIE not an FDE - pint_t nextCFI = p + cfiLength; - pint_t cieStart = p - ciePointer; - const char *err = parseCIE(addressSpace, cieStart, cieInfo); - if (err != NULL) - return err; - p += 4; - // Parse pc begin and range. - pint_t pcStart = - addressSpace.getEncodedP(p, nextCFI, cieInfo->pointerEncoding); - pint_t pcRange = - addressSpace.getEncodedP(p, nextCFI, cieInfo->pointerEncoding & 0x0F); - // Parse rest of info. - fdeInfo->lsda = 0; - // Check for augmentation length. - if (cieInfo->fdesHaveAugmentationData) { - pint_t augLen = (pint_t)addressSpace.getULEB128(p, nextCFI); - pint_t endOfAug = p + augLen; - if (cieInfo->lsdaEncoding != DW_EH_PE_omit) { - // Peek at value (without indirection). Zero means no LSDA. - pint_t lsdaStart = p; - if (addressSpace.getEncodedP(p, nextCFI, cieInfo->lsdaEncoding & 0x0F) != - 0) { - // Reset pointer and re-parse LSDA address. - p = lsdaStart; - fdeInfo->lsda = - addressSpace.getEncodedP(p, nextCFI, cieInfo->lsdaEncoding); - } - } - p = endOfAug; - } - fdeInfo->fdeStart = fdeStart; - fdeInfo->fdeLength = nextCFI - fdeStart; - fdeInfo->fdeInstructions = p; - fdeInfo->pcStart = pcStart; - fdeInfo->pcEnd = pcStart + pcRange; - return NULL; // success -} - -/// Scan an eh_frame section to find an FDE for a pc -template <typename A> -bool CFI_Parser<A>::findFDE(A &addressSpace, pint_t pc, pint_t ehSectionStart, - uint32_t sectionLength, pint_t fdeHint, - FDE_Info *fdeInfo, CIE_Info *cieInfo) { - //fprintf(stderr, "findFDE(0x%llX)\n", (long long)pc); - pint_t p = (fdeHint != 0) ? fdeHint : ehSectionStart; - const pint_t ehSectionEnd = p + sectionLength; - while (p < ehSectionEnd) { - pint_t currentCFI = p; - //fprintf(stderr, "findFDE() CFI at 0x%llX\n", (long long)p); - pint_t cfiLength = addressSpace.get32(p); - p += 4; - if (cfiLength == 0xffffffff) { - // 0xffffffff means length is really next 8 bytes - cfiLength = (pint_t)addressSpace.get64(p); - p += 8; - } - if (cfiLength == 0) - return false; // end marker - uint32_t id = addressSpace.get32(p); - if (id == 0) { - // Skip over CIEs. - p += cfiLength; - } else { - // Process FDE to see if it covers pc. - pint_t nextCFI = p + cfiLength; - uint32_t ciePointer = addressSpace.get32(p); - pint_t cieStart = p - ciePointer; - // Validate pointer to CIE is within section. - if ((ehSectionStart <= cieStart) && (cieStart < ehSectionEnd)) { - if (parseCIE(addressSpace, cieStart, cieInfo) == NULL) { - p += 4; - // Parse pc begin and range. - pint_t pcStart = - addressSpace.getEncodedP(p, nextCFI, cieInfo->pointerEncoding); - pint_t pcRange = addressSpace.getEncodedP( - p, nextCFI, cieInfo->pointerEncoding & 0x0F); - // Test if pc is within the function this FDE covers. - if ((pcStart < pc) && (pc <= pcStart + pcRange)) { - // parse rest of info - fdeInfo->lsda = 0; - // check for augmentation length - if (cieInfo->fdesHaveAugmentationData) { - pint_t augLen = (pint_t)addressSpace.getULEB128(p, nextCFI); - pint_t endOfAug = p + augLen; - if (cieInfo->lsdaEncoding != DW_EH_PE_omit) { - // Peek at value (without indirection). Zero means no LSDA. - pint_t lsdaStart = p; - if (addressSpace.getEncodedP( - p, nextCFI, cieInfo->lsdaEncoding & 0x0F) != 0) { - // Reset pointer and re-parse LSDA address. - p = lsdaStart; - fdeInfo->lsda = addressSpace - .getEncodedP(p, nextCFI, cieInfo->lsdaEncoding); - } - } - p = endOfAug; - } - fdeInfo->fdeStart = currentCFI; - fdeInfo->fdeLength = nextCFI - currentCFI; - fdeInfo->fdeInstructions = p; - fdeInfo->pcStart = pcStart; - fdeInfo->pcEnd = pcStart + pcRange; - return true; - } else { - // pc is not in begin/range, skip this FDE - } - } else { - // Malformed CIE, now augmentation describing pc range encoding. - } - } else { - // malformed FDE. CIE is bad - } - p = nextCFI; - } - } - return false; -} - -/// Extract info from a CIE -template <typename A> -const char *CFI_Parser<A>::parseCIE(A &addressSpace, pint_t cie, - CIE_Info *cieInfo) { - cieInfo->pointerEncoding = 0; - cieInfo->lsdaEncoding = DW_EH_PE_omit; - cieInfo->personalityEncoding = 0; - cieInfo->personalityOffsetInCIE = 0; - cieInfo->personality = 0; - cieInfo->codeAlignFactor = 0; - cieInfo->dataAlignFactor = 0; - cieInfo->isSignalFrame = false; - cieInfo->fdesHaveAugmentationData = false; - cieInfo->cieStart = cie; - pint_t p = cie; - pint_t cieLength = (pint_t)addressSpace.get32(p); - p += 4; - pint_t cieContentEnd = p + cieLength; - if (cieLength == 0xffffffff) { - // 0xffffffff means length is really next 8 bytes - cieLength = (pint_t)addressSpace.get64(p); - p += 8; - cieContentEnd = p + cieLength; - } - if (cieLength == 0) - return NULL; - // CIE ID is always 0 - if (addressSpace.get32(p) != 0) - return "CIE ID is not zero"; - p += 4; - // Version is always 1 or 3 - uint8_t version = addressSpace.get8(p); - if ((version != 1) && (version != 3)) - return "CIE version is not 1 or 3"; - ++p; - // save start of augmentation string and find end - pint_t strStart = p; - while (addressSpace.get8(p) != 0) - ++p; - ++p; - // parse code aligment factor - cieInfo->codeAlignFactor = (uint32_t)addressSpace.getULEB128(p, cieContentEnd); - // parse data alignment factor - cieInfo->dataAlignFactor = (int)addressSpace.getSLEB128(p, cieContentEnd); - // parse return address register - uint64_t raReg = addressSpace.getULEB128(p, cieContentEnd); - assert(raReg < 255 && "return address register too large"); - cieInfo->returnAddressRegister = (uint8_t)raReg; - // parse augmentation data based on augmentation string - const char *result = NULL; - if (addressSpace.get8(strStart) == 'z') { - // parse augmentation data length - addressSpace.getULEB128(p, cieContentEnd); - for (pint_t s = strStart; addressSpace.get8(s) != '\0'; ++s) { - switch (addressSpace.get8(s)) { - case 'z': - cieInfo->fdesHaveAugmentationData = true; - break; - case 'P': - cieInfo->personalityEncoding = addressSpace.get8(p); - ++p; - cieInfo->personalityOffsetInCIE = (uint8_t)(p - cie); - cieInfo->personality = addressSpace - .getEncodedP(p, cieContentEnd, cieInfo->personalityEncoding); - break; - case 'L': - cieInfo->lsdaEncoding = addressSpace.get8(p); - ++p; - break; - case 'R': - cieInfo->pointerEncoding = addressSpace.get8(p); - ++p; - break; - case 'S': - cieInfo->isSignalFrame = true; - break; - default: - // ignore unknown letters - break; - } - } - } - cieInfo->cieLength = cieContentEnd - cieInfo->cieStart; - cieInfo->cieInstructions = p; - return result; -} - - -/// "run" the DWARF instructions and create the abstact PrologInfo for an FDE -template <typename A> -bool CFI_Parser<A>::parseFDEInstructions(A &addressSpace, - const FDE_Info &fdeInfo, - const CIE_Info &cieInfo, pint_t upToPC, - PrologInfo *results) { - // clear results - memset(results, '\0', sizeof(PrologInfo)); - PrologInfoStackEntry *rememberStack = NULL; - - // parse CIE then FDE instructions - return parseInstructions(addressSpace, cieInfo.cieInstructions, - cieInfo.cieStart + cieInfo.cieLength, cieInfo, - (pint_t)(-1), rememberStack, results) && - parseInstructions(addressSpace, fdeInfo.fdeInstructions, - fdeInfo.fdeStart + fdeInfo.fdeLength, cieInfo, - upToPC - fdeInfo.pcStart, rememberStack, results); -} - -/// "run" the DWARF instructions -template <typename A> -bool CFI_Parser<A>::parseInstructions(A &addressSpace, pint_t instructions, - pint_t instructionsEnd, - const CIE_Info &cieInfo, pint_t pcoffset, - PrologInfoStackEntry *&rememberStack, - PrologInfo *results) { - pint_t p = instructions; - pint_t codeOffset = 0; - PrologInfo initialState = *results; - - _LIBUNWIND_TRACE_DWARF("parseInstructions(instructions=0x%0" PRIx64 ")\n", - static_cast<uint64_t>(instructionsEnd)); - - // see DWARF Spec, section 6.4.2 for details on unwind opcodes - while ((p < instructionsEnd) && (codeOffset < pcoffset)) { - uint64_t reg; - uint64_t reg2; - int64_t offset; - uint64_t length; - uint8_t opcode = addressSpace.get8(p); - uint8_t operand; -#if !defined(_LIBUNWIND_NO_HEAP) - PrologInfoStackEntry *entry; -#endif - ++p; - switch (opcode) { - case DW_CFA_nop: - _LIBUNWIND_TRACE_DWARF("DW_CFA_nop\n"); - break; - case DW_CFA_set_loc: - codeOffset = - addressSpace.getEncodedP(p, instructionsEnd, cieInfo.pointerEncoding); - _LIBUNWIND_TRACE_DWARF("DW_CFA_set_loc\n"); - break; - case DW_CFA_advance_loc1: - codeOffset += (addressSpace.get8(p) * cieInfo.codeAlignFactor); - p += 1; - _LIBUNWIND_TRACE_DWARF("DW_CFA_advance_loc1: new offset=%" PRIu64 "\n", - static_cast<uint64_t>(codeOffset)); - break; - case DW_CFA_advance_loc2: - codeOffset += (addressSpace.get16(p) * cieInfo.codeAlignFactor); - p += 2; - _LIBUNWIND_TRACE_DWARF("DW_CFA_advance_loc2: new offset=%" PRIu64 "\n", - static_cast<uint64_t>(codeOffset)); - break; - case DW_CFA_advance_loc4: - codeOffset += (addressSpace.get32(p) * cieInfo.codeAlignFactor); - p += 4; - _LIBUNWIND_TRACE_DWARF("DW_CFA_advance_loc4: new offset=%" PRIu64 "\n", - static_cast<uint64_t>(codeOffset)); - break; - case DW_CFA_offset_extended: - reg = addressSpace.getULEB128(p, instructionsEnd); - offset = (int64_t)addressSpace.getULEB128(p, instructionsEnd) - * cieInfo.dataAlignFactor; - if (reg > kMaxRegisterNumber) { - fprintf(stderr, - "malformed DW_CFA_offset_extended DWARF unwind, reg too big\n"); - return false; - } - results->savedRegisters[reg].location = kRegisterInCFA; - results->savedRegisters[reg].value = offset; - _LIBUNWIND_TRACE_DWARF("DW_CFA_offset_extended(reg=%" PRIu64 ", " - "offset=%" PRId64 ")\n", - reg, offset); - break; - case DW_CFA_restore_extended: - reg = addressSpace.getULEB128(p, instructionsEnd); - if (reg > kMaxRegisterNumber) { - fprintf( - stderr, - "malformed DW_CFA_restore_extended DWARF unwind, reg too big\n"); - return false; - } - results->savedRegisters[reg] = initialState.savedRegisters[reg]; - _LIBUNWIND_TRACE_DWARF("DW_CFA_restore_extended(reg=%" PRIu64 ")\n", reg); - break; - case DW_CFA_undefined: - reg = addressSpace.getULEB128(p, instructionsEnd); - if (reg > kMaxRegisterNumber) { - fprintf(stderr, - "malformed DW_CFA_undefined DWARF unwind, reg too big\n"); - return false; - } - results->savedRegisters[reg].location = kRegisterUnused; - _LIBUNWIND_TRACE_DWARF("DW_CFA_undefined(reg=%" PRIu64 ")\n", reg); - break; - case DW_CFA_same_value: - reg = addressSpace.getULEB128(p, instructionsEnd); - if (reg > kMaxRegisterNumber) { - fprintf(stderr, - "malformed DW_CFA_same_value DWARF unwind, reg too big\n"); - return false; - } - // <rdar://problem/8456377> DW_CFA_same_value unsupported - // "same value" means register was stored in frame, but its current - // value has not changed, so no need to restore from frame. - // We model this as if the register was never saved. - results->savedRegisters[reg].location = kRegisterUnused; - // set flag to disable conversion to compact unwind - results->sameValueUsed = true; - _LIBUNWIND_TRACE_DWARF("DW_CFA_same_value(reg=%" PRIu64 ")\n", reg); - break; - case DW_CFA_register: - reg = addressSpace.getULEB128(p, instructionsEnd); - reg2 = addressSpace.getULEB128(p, instructionsEnd); - if (reg > kMaxRegisterNumber) { - fprintf(stderr, - "malformed DW_CFA_register DWARF unwind, reg too big\n"); - return false; - } - if (reg2 > kMaxRegisterNumber) { - fprintf(stderr, - "malformed DW_CFA_register DWARF unwind, reg2 too big\n"); - return false; - } - results->savedRegisters[reg].location = kRegisterInRegister; - results->savedRegisters[reg].value = (int64_t)reg2; - // set flag to disable conversion to compact unwind - results->registersInOtherRegisters = true; - _LIBUNWIND_TRACE_DWARF( - "DW_CFA_register(reg=%" PRIu64 ", reg2=%" PRIu64 ")\n", reg, reg2); - break; -#if !defined(_LIBUNWIND_NO_HEAP) - case DW_CFA_remember_state: - // avoid operator new, because that would be an upward dependency - entry = (PrologInfoStackEntry *)malloc(sizeof(PrologInfoStackEntry)); - if (entry != NULL) { - entry->next = rememberStack; - entry->info = *results; - rememberStack = entry; - } else { - return false; - } - _LIBUNWIND_TRACE_DWARF("DW_CFA_remember_state\n"); - break; - case DW_CFA_restore_state: - if (rememberStack != NULL) { - PrologInfoStackEntry *top = rememberStack; - *results = top->info; - rememberStack = top->next; - free((char *)top); - } else { - return false; - } - _LIBUNWIND_TRACE_DWARF("DW_CFA_restore_state\n"); - break; -#endif - case DW_CFA_def_cfa: - reg = addressSpace.getULEB128(p, instructionsEnd); - offset = (int64_t)addressSpace.getULEB128(p, instructionsEnd); - if (reg > kMaxRegisterNumber) { - fprintf(stderr, "malformed DW_CFA_def_cfa DWARF unwind, reg too big\n"); - return false; - } - results->cfaRegister = (uint32_t)reg; - results->cfaRegisterOffset = (int32_t)offset; - _LIBUNWIND_TRACE_DWARF( - "DW_CFA_def_cfa(reg=%" PRIu64 ", offset=%" PRIu64 ")\n", reg, offset); - break; - case DW_CFA_def_cfa_register: - reg = addressSpace.getULEB128(p, instructionsEnd); - if (reg > kMaxRegisterNumber) { - fprintf( - stderr, - "malformed DW_CFA_def_cfa_register DWARF unwind, reg too big\n"); - return false; - } - results->cfaRegister = (uint32_t)reg; - _LIBUNWIND_TRACE_DWARF("DW_CFA_def_cfa_register(%" PRIu64 ")\n", reg); - break; - case DW_CFA_def_cfa_offset: - results->cfaRegisterOffset = (int32_t) - addressSpace.getULEB128(p, instructionsEnd); - results->codeOffsetAtStackDecrement = (uint32_t)codeOffset; - _LIBUNWIND_TRACE_DWARF("DW_CFA_def_cfa_offset(%d)\n", - results->cfaRegisterOffset); - break; - case DW_CFA_def_cfa_expression: - results->cfaRegister = 0; - results->cfaExpression = (int64_t)p; - length = addressSpace.getULEB128(p, instructionsEnd); - assert(length < std::numeric_limits<pint_t>::max() && "pointer overflow"); - p += static_cast<pint_t>(length); - _LIBUNWIND_TRACE_DWARF("DW_CFA_def_cfa_expression(expression=0x%" PRIx64 - ", length=%" PRIu64 ")\n", - results->cfaExpression, length); - break; - case DW_CFA_expression: - reg = addressSpace.getULEB128(p, instructionsEnd); - if (reg > kMaxRegisterNumber) { - fprintf(stderr, - "malformed DW_CFA_expression DWARF unwind, reg too big\n"); - return false; - } - results->savedRegisters[reg].location = kRegisterAtExpression; - results->savedRegisters[reg].value = (int64_t)p; - length = addressSpace.getULEB128(p, instructionsEnd); - assert(length < std::numeric_limits<pint_t>::max() && "pointer overflow"); - p += static_cast<pint_t>(length); - _LIBUNWIND_TRACE_DWARF("DW_CFA_expression(reg=%" PRIu64 ", " - "expression=0x%" PRIx64 ", " - "length=%" PRIu64 ")\n", - reg, results->savedRegisters[reg].value, length); - break; - case DW_CFA_offset_extended_sf: - reg = addressSpace.getULEB128(p, instructionsEnd); - if (reg > kMaxRegisterNumber) { - fprintf( - stderr, - "malformed DW_CFA_offset_extended_sf DWARF unwind, reg too big\n"); - return false; - } - offset = - addressSpace.getSLEB128(p, instructionsEnd) * cieInfo.dataAlignFactor; - results->savedRegisters[reg].location = kRegisterInCFA; - results->savedRegisters[reg].value = offset; - _LIBUNWIND_TRACE_DWARF("DW_CFA_offset_extended_sf(reg=%" PRIu64 ", " - "offset=%" PRId64 ")\n", - reg, offset); - break; - case DW_CFA_def_cfa_sf: - reg = addressSpace.getULEB128(p, instructionsEnd); - offset = - addressSpace.getSLEB128(p, instructionsEnd) * cieInfo.dataAlignFactor; - if (reg > kMaxRegisterNumber) { - fprintf(stderr, - "malformed DW_CFA_def_cfa_sf DWARF unwind, reg too big\n"); - return false; - } - results->cfaRegister = (uint32_t)reg; - results->cfaRegisterOffset = (int32_t)offset; - _LIBUNWIND_TRACE_DWARF("DW_CFA_def_cfa_sf(reg=%" PRIu64 ", " - "offset=%" PRId64 ")\n", - reg, offset); - break; - case DW_CFA_def_cfa_offset_sf: - results->cfaRegisterOffset = (int32_t) - (addressSpace.getSLEB128(p, instructionsEnd) * cieInfo.dataAlignFactor); - results->codeOffsetAtStackDecrement = (uint32_t)codeOffset; - _LIBUNWIND_TRACE_DWARF("DW_CFA_def_cfa_offset_sf(%d)\n", - results->cfaRegisterOffset); - break; - case DW_CFA_val_offset: - reg = addressSpace.getULEB128(p, instructionsEnd); - if (reg > kMaxRegisterNumber) { - fprintf(stderr, - "malformed DW_CFA_val_offset DWARF unwind, reg (%" PRIu64 - ") out of range\n", - reg); - return false; - } - offset = (int64_t)addressSpace.getULEB128(p, instructionsEnd) - * cieInfo.dataAlignFactor; - results->savedRegisters[reg].location = kRegisterOffsetFromCFA; - results->savedRegisters[reg].value = offset; - _LIBUNWIND_TRACE_DWARF("DW_CFA_val_offset(reg=%" PRIu64 ", " - "offset=%" PRId64 "\n", - reg, offset); - break; - case DW_CFA_val_offset_sf: - reg = addressSpace.getULEB128(p, instructionsEnd); - if (reg > kMaxRegisterNumber) { - fprintf(stderr, - "malformed DW_CFA_val_offset_sf DWARF unwind, reg too big\n"); - return false; - } - offset = - addressSpace.getSLEB128(p, instructionsEnd) * cieInfo.dataAlignFactor; - results->savedRegisters[reg].location = kRegisterOffsetFromCFA; - results->savedRegisters[reg].value = offset; - _LIBUNWIND_TRACE_DWARF("DW_CFA_val_offset_sf(reg=%" PRIu64 ", " - "offset=%" PRId64 "\n", - reg, offset); - break; - case DW_CFA_val_expression: - reg = addressSpace.getULEB128(p, instructionsEnd); - if (reg > kMaxRegisterNumber) { - fprintf(stderr, - "malformed DW_CFA_val_expression DWARF unwind, reg too big\n"); - return false; - } - results->savedRegisters[reg].location = kRegisterIsExpression; - results->savedRegisters[reg].value = (int64_t)p; - length = addressSpace.getULEB128(p, instructionsEnd); - assert(length < std::numeric_limits<pint_t>::max() && "pointer overflow"); - p += static_cast<pint_t>(length); - _LIBUNWIND_TRACE_DWARF("DW_CFA_val_expression(reg=%" PRIu64 ", " - "expression=0x%" PRIx64 ", length=%" PRIu64 ")\n", - reg, results->savedRegisters[reg].value, length); - break; - case DW_CFA_GNU_args_size: - length = addressSpace.getULEB128(p, instructionsEnd); - results->spExtraArgSize = (uint32_t)length; - _LIBUNWIND_TRACE_DWARF("DW_CFA_GNU_args_size(%" PRIu64 ")\n", length); - break; - case DW_CFA_GNU_negative_offset_extended: - reg = addressSpace.getULEB128(p, instructionsEnd); - if (reg > kMaxRegisterNumber) { - fprintf(stderr, "malformed DW_CFA_GNU_negative_offset_extended DWARF " - "unwind, reg too big\n"); - return false; - } - offset = (int64_t)addressSpace.getULEB128(p, instructionsEnd) - * cieInfo.dataAlignFactor; - results->savedRegisters[reg].location = kRegisterInCFA; - results->savedRegisters[reg].value = -offset; - _LIBUNWIND_TRACE_DWARF( - "DW_CFA_GNU_negative_offset_extended(%" PRId64 ")\n", offset); - break; - default: - operand = opcode & 0x3F; - switch (opcode & 0xC0) { - case DW_CFA_offset: - reg = operand; - if (reg > kMaxRegisterNumber) { - fprintf(stderr, "malformed DW_CFA_offset DWARF unwind, reg (%" PRIu64 - ") out of range\n", - reg); - return false; - } - offset = (int64_t)addressSpace.getULEB128(p, instructionsEnd) - * cieInfo.dataAlignFactor; - results->savedRegisters[reg].location = kRegisterInCFA; - results->savedRegisters[reg].value = offset; - _LIBUNWIND_TRACE_DWARF("DW_CFA_offset(reg=%d, offset=%" PRId64 ")\n", - operand, offset); - break; - case DW_CFA_advance_loc: - codeOffset += operand * cieInfo.codeAlignFactor; - _LIBUNWIND_TRACE_DWARF("DW_CFA_advance_loc: new offset=%" PRIu64 "\n", - static_cast<uint64_t>(codeOffset)); - break; - case DW_CFA_restore: - reg = operand; - if (reg > kMaxRegisterNumber) { - fprintf(stderr, "malformed DW_CFA_restore DWARF unwind, reg (%" PRIu64 - ") out of range\n", - reg); - return false; - } - results->savedRegisters[reg] = initialState.savedRegisters[reg]; - _LIBUNWIND_TRACE_DWARF("DW_CFA_restore(reg=%" PRIu64 ")\n", - static_cast<uint64_t>(operand)); - break; - default: - _LIBUNWIND_TRACE_DWARF("unknown CFA opcode 0x%02X\n", opcode); - return false; - } - } - } - - return true; -} - -} // namespace libunwind - -#endif // __DWARF_PARSER_HPP__ diff --git a/chromium/buildtools/third_party/libunwind/trunk/src/EHHeaderParser.hpp b/chromium/buildtools/third_party/libunwind/trunk/src/EHHeaderParser.hpp deleted file mode 100644 index 9bdaf5505ff..00000000000 --- a/chromium/buildtools/third_party/libunwind/trunk/src/EHHeaderParser.hpp +++ /dev/null @@ -1,162 +0,0 @@ -//===------------------------- 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 "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 = - fde_count_enc == DW_EH_PE_omit - ? 0 - : 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", - 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/chromium/buildtools/third_party/libunwind/trunk/src/RWMutex.hpp b/chromium/buildtools/third_party/libunwind/trunk/src/RWMutex.hpp deleted file mode 100644 index 50a78a57b08..00000000000 --- a/chromium/buildtools/third_party/libunwind/trunk/src/RWMutex.hpp +++ /dev/null @@ -1,77 +0,0 @@ -//===----------------------------- 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__ diff --git a/chromium/buildtools/third_party/libunwind/trunk/src/Registers.hpp b/chromium/buildtools/third_party/libunwind/trunk/src/Registers.hpp deleted file mode 100644 index 0c4fecb8ab7..00000000000 --- a/chromium/buildtools/third_party/libunwind/trunk/src/Registers.hpp +++ /dev/null @@ -1,2045 +0,0 @@ -//===----------------------------- 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. -// -// -// Models register sets for supported processors. -// -//===----------------------------------------------------------------------===// - -#ifndef __REGISTERS_HPP__ -#define __REGISTERS_HPP__ - -#include <stdint.h> -#include <string.h> - -#include "libunwind.h" -#include "config.h" - -namespace libunwind { - -// For emulating 128-bit registers -struct v128 { uint32_t vec[4]; }; - - -#if defined(_LIBUNWIND_TARGET_I386) -/// Registers_x86 holds the register state of a thread in a 32-bit intel -/// process. -class _LIBUNWIND_HIDDEN Registers_x86 { -public: - Registers_x86(); - Registers_x86(const void *registers); - - bool validRegister(int num) const; - uint32_t getRegister(int num) const; - void setRegister(int num, uint32_t value); - bool validFloatRegister(int) const { return false; } - double getFloatRegister(int num) const; - void setFloatRegister(int num, double value); - bool validVectorRegister(int) const { return false; } - v128 getVectorRegister(int num) const; - void setVectorRegister(int num, v128 value); - const char *getRegisterName(int num); - void jumpto(); - static int lastDwarfRegNum() { return _LIBUNWIND_HIGHEST_DWARF_REGISTER_X86; } - - uint32_t getSP() const { return _registers.__esp; } - void setSP(uint32_t value) { _registers.__esp = value; } - uint32_t getIP() const { return _registers.__eip; } - void setIP(uint32_t value) { _registers.__eip = value; } - uint32_t getEBP() const { return _registers.__ebp; } - void setEBP(uint32_t value) { _registers.__ebp = value; } - uint32_t getEBX() const { return _registers.__ebx; } - void setEBX(uint32_t value) { _registers.__ebx = value; } - uint32_t getECX() const { return _registers.__ecx; } - void setECX(uint32_t value) { _registers.__ecx = value; } - uint32_t getEDX() const { return _registers.__edx; } - void setEDX(uint32_t value) { _registers.__edx = value; } - uint32_t getESI() const { return _registers.__esi; } - void setESI(uint32_t value) { _registers.__esi = value; } - uint32_t getEDI() const { return _registers.__edi; } - void setEDI(uint32_t value) { _registers.__edi = value; } - -private: - struct GPRs { - unsigned int __eax; - unsigned int __ebx; - unsigned int __ecx; - unsigned int __edx; - unsigned int __edi; - unsigned int __esi; - unsigned int __ebp; - unsigned int __esp; - unsigned int __ss; - unsigned int __eflags; - unsigned int __eip; - unsigned int __cs; - unsigned int __ds; - unsigned int __es; - unsigned int __fs; - unsigned int __gs; - }; - - GPRs _registers; -}; - -inline Registers_x86::Registers_x86(const void *registers) { - static_assert((check_fit<Registers_x86, unw_context_t>::does_fit), - "x86 registers do not fit into unw_context_t"); - memcpy(&_registers, registers, sizeof(_registers)); -} - -inline Registers_x86::Registers_x86() { - memset(&_registers, 0, sizeof(_registers)); -} - -inline bool Registers_x86::validRegister(int regNum) const { - if (regNum == UNW_REG_IP) - return true; - if (regNum == UNW_REG_SP) - return true; - if (regNum < 0) - return false; - if (regNum > 7) - return false; - return true; -} - -inline uint32_t Registers_x86::getRegister(int regNum) const { - switch (regNum) { - case UNW_REG_IP: - return _registers.__eip; - case UNW_REG_SP: - return _registers.__esp; - case UNW_X86_EAX: - return _registers.__eax; - case UNW_X86_ECX: - return _registers.__ecx; - case UNW_X86_EDX: - return _registers.__edx; - case UNW_X86_EBX: - return _registers.__ebx; -#if !defined(__APPLE__) - case UNW_X86_ESP: -#else - case UNW_X86_EBP: -#endif - return _registers.__ebp; -#if !defined(__APPLE__) - case UNW_X86_EBP: -#else - case UNW_X86_ESP: -#endif - return _registers.__esp; - case UNW_X86_ESI: - return _registers.__esi; - case UNW_X86_EDI: - return _registers.__edi; - } - _LIBUNWIND_ABORT("unsupported x86 register"); -} - -inline void Registers_x86::setRegister(int regNum, uint32_t value) { - switch (regNum) { - case UNW_REG_IP: - _registers.__eip = value; - return; - case UNW_REG_SP: - _registers.__esp = value; - return; - case UNW_X86_EAX: - _registers.__eax = value; - return; - case UNW_X86_ECX: - _registers.__ecx = value; - return; - case UNW_X86_EDX: - _registers.__edx = value; - return; - case UNW_X86_EBX: - _registers.__ebx = value; - return; -#if !defined(__APPLE__) - case UNW_X86_ESP: -#else - case UNW_X86_EBP: -#endif - _registers.__ebp = value; - return; -#if !defined(__APPLE__) - case UNW_X86_EBP: -#else - case UNW_X86_ESP: -#endif - _registers.__esp = value; - return; - case UNW_X86_ESI: - _registers.__esi = value; - return; - case UNW_X86_EDI: - _registers.__edi = value; - return; - } - _LIBUNWIND_ABORT("unsupported x86 register"); -} - -inline const char *Registers_x86::getRegisterName(int regNum) { - switch (regNum) { - case UNW_REG_IP: - return "ip"; - case UNW_REG_SP: - return "esp"; - case UNW_X86_EAX: - return "eax"; - case UNW_X86_ECX: - return "ecx"; - case UNW_X86_EDX: - return "edx"; - case UNW_X86_EBX: - return "ebx"; - case UNW_X86_EBP: - return "ebp"; - case UNW_X86_ESP: - return "esp"; - case UNW_X86_ESI: - return "esi"; - case UNW_X86_EDI: - return "edi"; - default: - return "unknown register"; - } -} - -inline double Registers_x86::getFloatRegister(int) const { - _LIBUNWIND_ABORT("no x86 float registers"); -} - -inline void Registers_x86::setFloatRegister(int, double) { - _LIBUNWIND_ABORT("no x86 float registers"); -} - -inline v128 Registers_x86::getVectorRegister(int) const { - _LIBUNWIND_ABORT("no x86 vector registers"); -} - -inline void Registers_x86::setVectorRegister(int, v128) { - _LIBUNWIND_ABORT("no x86 vector registers"); -} -#endif // _LIBUNWIND_TARGET_I386 - - -#if defined(_LIBUNWIND_TARGET_X86_64) -/// Registers_x86_64 holds the register state of a thread in a 64-bit intel -/// process. -class _LIBUNWIND_HIDDEN Registers_x86_64 { -public: - Registers_x86_64(); - Registers_x86_64(const void *registers); - - bool validRegister(int num) const; - uint64_t getRegister(int num) const; - void setRegister(int num, uint64_t value); - bool validFloatRegister(int) const { return false; } - double getFloatRegister(int num) const; - void setFloatRegister(int num, double value); - bool validVectorRegister(int) const; - v128 getVectorRegister(int num) const; - void setVectorRegister(int num, v128 value); - const char *getRegisterName(int num); - void jumpto(); - static int lastDwarfRegNum() { return _LIBUNWIND_HIGHEST_DWARF_REGISTER_X86_64; } - - uint64_t getSP() const { return _registers.__rsp; } - void setSP(uint64_t value) { _registers.__rsp = value; } - uint64_t getIP() const { return _registers.__rip; } - void setIP(uint64_t value) { _registers.__rip = value; } - uint64_t getRBP() const { return _registers.__rbp; } - void setRBP(uint64_t value) { _registers.__rbp = value; } - uint64_t getRBX() const { return _registers.__rbx; } - void setRBX(uint64_t value) { _registers.__rbx = value; } - uint64_t getR12() const { return _registers.__r12; } - void setR12(uint64_t value) { _registers.__r12 = value; } - uint64_t getR13() const { return _registers.__r13; } - void setR13(uint64_t value) { _registers.__r13 = value; } - uint64_t getR14() const { return _registers.__r14; } - void setR14(uint64_t value) { _registers.__r14 = value; } - uint64_t getR15() const { return _registers.__r15; } - void setR15(uint64_t value) { _registers.__r15 = value; } - -private: - struct GPRs { - uint64_t __rax; - uint64_t __rbx; - uint64_t __rcx; - uint64_t __rdx; - uint64_t __rdi; - uint64_t __rsi; - uint64_t __rbp; - uint64_t __rsp; - uint64_t __r8; - uint64_t __r9; - uint64_t __r10; - uint64_t __r11; - uint64_t __r12; - uint64_t __r13; - uint64_t __r14; - uint64_t __r15; - uint64_t __rip; - uint64_t __rflags; - uint64_t __cs; - uint64_t __fs; - uint64_t __gs; -#if defined(_WIN64) - uint64_t __padding; // 16-byte align -#endif - }; - GPRs _registers; -#if defined(_WIN64) - v128 _xmm[16]; -#endif -}; - -inline Registers_x86_64::Registers_x86_64(const void *registers) { - static_assert((check_fit<Registers_x86_64, unw_context_t>::does_fit), - "x86_64 registers do not fit into unw_context_t"); - memcpy(&_registers, registers, sizeof(_registers)); -} - -inline Registers_x86_64::Registers_x86_64() { - memset(&_registers, 0, sizeof(_registers)); -} - -inline bool Registers_x86_64::validRegister(int regNum) const { - if (regNum == UNW_REG_IP) - return true; - if (regNum == UNW_REG_SP) - return true; - if (regNum < 0) - return false; - if (regNum > 15) - return false; - return true; -} - -inline uint64_t Registers_x86_64::getRegister(int regNum) const { - switch (regNum) { - case UNW_REG_IP: - return _registers.__rip; - case UNW_REG_SP: - return _registers.__rsp; - case UNW_X86_64_RAX: - return _registers.__rax; - case UNW_X86_64_RDX: - return _registers.__rdx; - case UNW_X86_64_RCX: - return _registers.__rcx; - case UNW_X86_64_RBX: - return _registers.__rbx; - case UNW_X86_64_RSI: - return _registers.__rsi; - case UNW_X86_64_RDI: - return _registers.__rdi; - case UNW_X86_64_RBP: - return _registers.__rbp; - case UNW_X86_64_RSP: - return _registers.__rsp; - case UNW_X86_64_R8: - return _registers.__r8; - case UNW_X86_64_R9: - return _registers.__r9; - case UNW_X86_64_R10: - return _registers.__r10; - case UNW_X86_64_R11: - return _registers.__r11; - case UNW_X86_64_R12: - return _registers.__r12; - case UNW_X86_64_R13: - return _registers.__r13; - case UNW_X86_64_R14: - return _registers.__r14; - case UNW_X86_64_R15: - return _registers.__r15; - } - _LIBUNWIND_ABORT("unsupported x86_64 register"); -} - -inline void Registers_x86_64::setRegister(int regNum, uint64_t value) { - switch (regNum) { - case UNW_REG_IP: - _registers.__rip = value; - return; - case UNW_REG_SP: - _registers.__rsp = value; - return; - case UNW_X86_64_RAX: - _registers.__rax = value; - return; - case UNW_X86_64_RDX: - _registers.__rdx = value; - return; - case UNW_X86_64_RCX: - _registers.__rcx = value; - return; - case UNW_X86_64_RBX: - _registers.__rbx = value; - return; - case UNW_X86_64_RSI: - _registers.__rsi = value; - return; - case UNW_X86_64_RDI: - _registers.__rdi = value; - return; - case UNW_X86_64_RBP: - _registers.__rbp = value; - return; - case UNW_X86_64_RSP: - _registers.__rsp = value; - return; - case UNW_X86_64_R8: - _registers.__r8 = value; - return; - case UNW_X86_64_R9: - _registers.__r9 = value; - return; - case UNW_X86_64_R10: - _registers.__r10 = value; - return; - case UNW_X86_64_R11: - _registers.__r11 = value; - return; - case UNW_X86_64_R12: - _registers.__r12 = value; - return; - case UNW_X86_64_R13: - _registers.__r13 = value; - return; - case UNW_X86_64_R14: - _registers.__r14 = value; - return; - case UNW_X86_64_R15: - _registers.__r15 = value; - return; - } - _LIBUNWIND_ABORT("unsupported x86_64 register"); -} - -inline const char *Registers_x86_64::getRegisterName(int regNum) { - switch (regNum) { - case UNW_REG_IP: - return "rip"; - case UNW_REG_SP: - return "rsp"; - case UNW_X86_64_RAX: - return "rax"; - case UNW_X86_64_RDX: - return "rdx"; - case UNW_X86_64_RCX: - return "rcx"; - case UNW_X86_64_RBX: - return "rbx"; - case UNW_X86_64_RSI: - return "rsi"; - case UNW_X86_64_RDI: - return "rdi"; - case UNW_X86_64_RBP: - return "rbp"; - case UNW_X86_64_RSP: - return "rsp"; - case UNW_X86_64_R8: - return "r8"; - case UNW_X86_64_R9: - return "r9"; - case UNW_X86_64_R10: - return "r10"; - case UNW_X86_64_R11: - return "r11"; - case UNW_X86_64_R12: - return "r12"; - case UNW_X86_64_R13: - return "r13"; - case UNW_X86_64_R14: - return "r14"; - case UNW_X86_64_R15: - return "r15"; - case UNW_X86_64_XMM0: - return "xmm0"; - case UNW_X86_64_XMM1: - return "xmm1"; - case UNW_X86_64_XMM2: - return "xmm2"; - case UNW_X86_64_XMM3: - return "xmm3"; - case UNW_X86_64_XMM4: - return "xmm4"; - case UNW_X86_64_XMM5: - return "xmm5"; - case UNW_X86_64_XMM6: - return "xmm6"; - case UNW_X86_64_XMM7: - return "xmm7"; - case UNW_X86_64_XMM8: - return "xmm8"; - case UNW_X86_64_XMM9: - return "xmm9"; - case UNW_X86_64_XMM10: - return "xmm10"; - case UNW_X86_64_XMM11: - return "xmm11"; - case UNW_X86_64_XMM12: - return "xmm12"; - case UNW_X86_64_XMM13: - return "xmm13"; - case UNW_X86_64_XMM14: - return "xmm14"; - case UNW_X86_64_XMM15: - return "xmm15"; - default: - return "unknown register"; - } -} - -inline double Registers_x86_64::getFloatRegister(int) const { - _LIBUNWIND_ABORT("no x86_64 float registers"); -} - -inline void Registers_x86_64::setFloatRegister(int, double) { - _LIBUNWIND_ABORT("no x86_64 float registers"); -} - -inline bool Registers_x86_64::validVectorRegister(int regNum) const { -#if defined(_WIN64) - if (regNum < UNW_X86_64_XMM0) - return false; - if (regNum > UNW_X86_64_XMM15) - return false; - return true; -#else - return false; -#endif -} - -inline v128 Registers_x86_64::getVectorRegister(int regNum) const { -#if defined(_WIN64) - assert(validVectorRegister(regNum)); - return _xmm[regNum - UNW_X86_64_XMM0]; -#else - _LIBUNWIND_ABORT("no x86_64 vector registers"); -#endif -} - -inline void Registers_x86_64::setVectorRegister(int regNum, v128 value) { -#if defined(_WIN64) - assert(validVectorRegister(regNum)); - _xmm[regNum - UNW_X86_64_XMM0] = value; -#else - _LIBUNWIND_ABORT("no x86_64 vector registers"); -#endif -} -#endif // _LIBUNWIND_TARGET_X86_64 - - -#if defined(_LIBUNWIND_TARGET_PPC) -/// Registers_ppc holds the register state of a thread in a 32-bit PowerPC -/// process. -class _LIBUNWIND_HIDDEN Registers_ppc { -public: - Registers_ppc(); - Registers_ppc(const void *registers); - - bool validRegister(int num) const; - uint32_t getRegister(int num) const; - void setRegister(int num, uint32_t value); - bool validFloatRegister(int num) const; - double getFloatRegister(int num) const; - void setFloatRegister(int num, double value); - bool validVectorRegister(int num) const; - v128 getVectorRegister(int num) const; - void setVectorRegister(int num, v128 value); - const char *getRegisterName(int num); - void jumpto(); - static int lastDwarfRegNum() { return _LIBUNWIND_HIGHEST_DWARF_REGISTER_PPC; } - - uint64_t getSP() const { return _registers.__r1; } - void setSP(uint32_t value) { _registers.__r1 = value; } - uint64_t getIP() const { return _registers.__srr0; } - void setIP(uint32_t value) { _registers.__srr0 = value; } - -private: - struct ppc_thread_state_t { - unsigned int __srr0; /* Instruction address register (PC) */ - unsigned int __srr1; /* Machine state register (supervisor) */ - unsigned int __r0; - unsigned int __r1; - unsigned int __r2; - unsigned int __r3; - unsigned int __r4; - unsigned int __r5; - unsigned int __r6; - unsigned int __r7; - unsigned int __r8; - unsigned int __r9; - unsigned int __r10; - unsigned int __r11; - unsigned int __r12; - unsigned int __r13; - unsigned int __r14; - unsigned int __r15; - unsigned int __r16; - unsigned int __r17; - unsigned int __r18; - unsigned int __r19; - unsigned int __r20; - unsigned int __r21; - unsigned int __r22; - unsigned int __r23; - unsigned int __r24; - unsigned int __r25; - unsigned int __r26; - unsigned int __r27; - unsigned int __r28; - unsigned int __r29; - unsigned int __r30; - unsigned int __r31; - unsigned int __cr; /* Condition register */ - unsigned int __xer; /* User's integer exception register */ - unsigned int __lr; /* Link register */ - unsigned int __ctr; /* Count register */ - unsigned int __mq; /* MQ register (601 only) */ - unsigned int __vrsave; /* Vector Save Register */ - }; - - struct ppc_float_state_t { - double __fpregs[32]; - - unsigned int __fpscr_pad; /* fpscr is 64 bits, 32 bits of rubbish */ - unsigned int __fpscr; /* floating point status register */ - }; - - ppc_thread_state_t _registers; - ppc_float_state_t _floatRegisters; - v128 _vectorRegisters[32]; // offset 424 -}; - -inline Registers_ppc::Registers_ppc(const void *registers) { - static_assert((check_fit<Registers_ppc, unw_context_t>::does_fit), - "ppc registers do not fit into unw_context_t"); - 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() { - memset(&_registers, 0, sizeof(_registers)); - memset(&_floatRegisters, 0, sizeof(_floatRegisters)); - memset(&_vectorRegisters, 0, sizeof(_vectorRegisters)); -} - -inline bool Registers_ppc::validRegister(int regNum) const { - if (regNum == UNW_REG_IP) - return true; - if (regNum == UNW_REG_SP) - return true; - if (regNum == UNW_PPC_VRSAVE) - return true; - if (regNum < 0) - return false; - if (regNum <= UNW_PPC_R31) - return true; - if (regNum == UNW_PPC_MQ) - return true; - if (regNum == UNW_PPC_LR) - return true; - if (regNum == UNW_PPC_CTR) - return true; - if ((UNW_PPC_CR0 <= regNum) && (regNum <= UNW_PPC_CR7)) - return true; - return false; -} - -inline uint32_t Registers_ppc::getRegister(int regNum) const { - switch (regNum) { - case UNW_REG_IP: - return _registers.__srr0; - case UNW_REG_SP: - return _registers.__r1; - case UNW_PPC_R0: - return _registers.__r0; - case UNW_PPC_R1: - return _registers.__r1; - case UNW_PPC_R2: - return _registers.__r2; - case UNW_PPC_R3: - return _registers.__r3; - case UNW_PPC_R4: - return _registers.__r4; - case UNW_PPC_R5: - return _registers.__r5; - case UNW_PPC_R6: - return _registers.__r6; - case UNW_PPC_R7: - return _registers.__r7; - case UNW_PPC_R8: - return _registers.__r8; - case UNW_PPC_R9: - return _registers.__r9; - case UNW_PPC_R10: - return _registers.__r10; - case UNW_PPC_R11: - return _registers.__r11; - case UNW_PPC_R12: - return _registers.__r12; - case UNW_PPC_R13: - return _registers.__r13; - case UNW_PPC_R14: - return _registers.__r14; - case UNW_PPC_R15: - return _registers.__r15; - case UNW_PPC_R16: - return _registers.__r16; - case UNW_PPC_R17: - return _registers.__r17; - case UNW_PPC_R18: - return _registers.__r18; - case UNW_PPC_R19: - return _registers.__r19; - case UNW_PPC_R20: - return _registers.__r20; - case UNW_PPC_R21: - return _registers.__r21; - case UNW_PPC_R22: - return _registers.__r22; - case UNW_PPC_R23: - return _registers.__r23; - case UNW_PPC_R24: - return _registers.__r24; - case UNW_PPC_R25: - return _registers.__r25; - case UNW_PPC_R26: - return _registers.__r26; - case UNW_PPC_R27: - return _registers.__r27; - case UNW_PPC_R28: - return _registers.__r28; - case UNW_PPC_R29: - return _registers.__r29; - case UNW_PPC_R30: - return _registers.__r30; - case UNW_PPC_R31: - return _registers.__r31; - case UNW_PPC_LR: - return _registers.__lr; - case UNW_PPC_CR0: - return (_registers.__cr & 0xF0000000); - case UNW_PPC_CR1: - return (_registers.__cr & 0x0F000000); - case UNW_PPC_CR2: - return (_registers.__cr & 0x00F00000); - case UNW_PPC_CR3: - return (_registers.__cr & 0x000F0000); - case UNW_PPC_CR4: - return (_registers.__cr & 0x0000F000); - case UNW_PPC_CR5: - return (_registers.__cr & 0x00000F00); - case UNW_PPC_CR6: - return (_registers.__cr & 0x000000F0); - case UNW_PPC_CR7: - return (_registers.__cr & 0x0000000F); - case UNW_PPC_VRSAVE: - return _registers.__vrsave; - } - _LIBUNWIND_ABORT("unsupported ppc register"); -} - -inline void Registers_ppc::setRegister(int regNum, uint32_t value) { - //fprintf(stderr, "Registers_ppc::setRegister(%d, 0x%08X)\n", regNum, value); - switch (regNum) { - case UNW_REG_IP: - _registers.__srr0 = value; - return; - case UNW_REG_SP: - _registers.__r1 = value; - return; - case UNW_PPC_R0: - _registers.__r0 = value; - return; - case UNW_PPC_R1: - _registers.__r1 = value; - return; - case UNW_PPC_R2: - _registers.__r2 = value; - return; - case UNW_PPC_R3: - _registers.__r3 = value; - return; - case UNW_PPC_R4: - _registers.__r4 = value; - return; - case UNW_PPC_R5: - _registers.__r5 = value; - return; - case UNW_PPC_R6: - _registers.__r6 = value; - return; - case UNW_PPC_R7: - _registers.__r7 = value; - return; - case UNW_PPC_R8: - _registers.__r8 = value; - return; - case UNW_PPC_R9: - _registers.__r9 = value; - return; - case UNW_PPC_R10: - _registers.__r10 = value; - return; - case UNW_PPC_R11: - _registers.__r11 = value; - return; - case UNW_PPC_R12: - _registers.__r12 = value; - return; - case UNW_PPC_R13: - _registers.__r13 = value; - return; - case UNW_PPC_R14: - _registers.__r14 = value; - return; - case UNW_PPC_R15: - _registers.__r15 = value; - return; - case UNW_PPC_R16: - _registers.__r16 = value; - return; - case UNW_PPC_R17: - _registers.__r17 = value; - return; - case UNW_PPC_R18: - _registers.__r18 = value; - return; - case UNW_PPC_R19: - _registers.__r19 = value; - return; - case UNW_PPC_R20: - _registers.__r20 = value; - return; - case UNW_PPC_R21: - _registers.__r21 = value; - return; - case UNW_PPC_R22: - _registers.__r22 = value; - return; - case UNW_PPC_R23: - _registers.__r23 = value; - return; - case UNW_PPC_R24: - _registers.__r24 = value; - return; - case UNW_PPC_R25: - _registers.__r25 = value; - return; - case UNW_PPC_R26: - _registers.__r26 = value; - return; - case UNW_PPC_R27: - _registers.__r27 = value; - return; - case UNW_PPC_R28: - _registers.__r28 = value; - return; - case UNW_PPC_R29: - _registers.__r29 = value; - return; - case UNW_PPC_R30: - _registers.__r30 = value; - return; - case UNW_PPC_R31: - _registers.__r31 = value; - return; - case UNW_PPC_MQ: - _registers.__mq = value; - return; - case UNW_PPC_LR: - _registers.__lr = value; - return; - case UNW_PPC_CTR: - _registers.__ctr = value; - return; - case UNW_PPC_CR0: - _registers.__cr &= 0x0FFFFFFF; - _registers.__cr |= (value & 0xF0000000); - return; - case UNW_PPC_CR1: - _registers.__cr &= 0xF0FFFFFF; - _registers.__cr |= (value & 0x0F000000); - return; - case UNW_PPC_CR2: - _registers.__cr &= 0xFF0FFFFF; - _registers.__cr |= (value & 0x00F00000); - return; - case UNW_PPC_CR3: - _registers.__cr &= 0xFFF0FFFF; - _registers.__cr |= (value & 0x000F0000); - return; - case UNW_PPC_CR4: - _registers.__cr &= 0xFFFF0FFF; - _registers.__cr |= (value & 0x0000F000); - return; - case UNW_PPC_CR5: - _registers.__cr &= 0xFFFFF0FF; - _registers.__cr |= (value & 0x00000F00); - return; - case UNW_PPC_CR6: - _registers.__cr &= 0xFFFFFF0F; - _registers.__cr |= (value & 0x000000F0); - return; - case UNW_PPC_CR7: - _registers.__cr &= 0xFFFFFFF0; - _registers.__cr |= (value & 0x0000000F); - return; - case UNW_PPC_VRSAVE: - _registers.__vrsave = value; - return; - // not saved - return; - case UNW_PPC_XER: - _registers.__xer = value; - return; - case UNW_PPC_AP: - case UNW_PPC_VSCR: - case UNW_PPC_SPEFSCR: - // not saved - return; - } - _LIBUNWIND_ABORT("unsupported ppc register"); -} - -inline bool Registers_ppc::validFloatRegister(int regNum) const { - if (regNum < UNW_PPC_F0) - return false; - if (regNum > UNW_PPC_F31) - return false; - return true; -} - -inline double Registers_ppc::getFloatRegister(int regNum) const { - assert(validFloatRegister(regNum)); - return _floatRegisters.__fpregs[regNum - UNW_PPC_F0]; -} - -inline void Registers_ppc::setFloatRegister(int regNum, double value) { - assert(validFloatRegister(regNum)); - _floatRegisters.__fpregs[regNum - UNW_PPC_F0] = value; -} - -inline bool Registers_ppc::validVectorRegister(int regNum) const { - if (regNum < UNW_PPC_V0) - return false; - if (regNum > UNW_PPC_V31) - return false; - return true; -} - -inline v128 Registers_ppc::getVectorRegister(int regNum) const { - assert(validVectorRegister(regNum)); - v128 result = _vectorRegisters[regNum - UNW_PPC_V0]; - return result; -} - -inline void Registers_ppc::setVectorRegister(int regNum, v128 value) { - assert(validVectorRegister(regNum)); - _vectorRegisters[regNum - UNW_PPC_V0] = value; -} - -inline const char *Registers_ppc::getRegisterName(int regNum) { - switch (regNum) { - case UNW_REG_IP: - return "ip"; - case UNW_REG_SP: - return "sp"; - case UNW_PPC_R0: - return "r0"; - case UNW_PPC_R1: - return "r1"; - case UNW_PPC_R2: - return "r2"; - case UNW_PPC_R3: - return "r3"; - case UNW_PPC_R4: - return "r4"; - case UNW_PPC_R5: - return "r5"; - case UNW_PPC_R6: - return "r6"; - case UNW_PPC_R7: - return "r7"; - case UNW_PPC_R8: - return "r8"; - case UNW_PPC_R9: - return "r9"; - case UNW_PPC_R10: - return "r10"; - case UNW_PPC_R11: - return "r11"; - case UNW_PPC_R12: - return "r12"; - case UNW_PPC_R13: - return "r13"; - case UNW_PPC_R14: - return "r14"; - case UNW_PPC_R15: - return "r15"; - case UNW_PPC_R16: - return "r16"; - case UNW_PPC_R17: - return "r17"; - case UNW_PPC_R18: - return "r18"; - case UNW_PPC_R19: - return "r19"; - case UNW_PPC_R20: - return "r20"; - case UNW_PPC_R21: - return "r21"; - case UNW_PPC_R22: - return "r22"; - case UNW_PPC_R23: - return "r23"; - case UNW_PPC_R24: - return "r24"; - case UNW_PPC_R25: - return "r25"; - case UNW_PPC_R26: - return "r26"; - case UNW_PPC_R27: - return "r27"; - case UNW_PPC_R28: - return "r28"; - case UNW_PPC_R29: - return "r29"; - case UNW_PPC_R30: - return "r30"; - case UNW_PPC_R31: - return "r31"; - case UNW_PPC_F0: - return "fp0"; - case UNW_PPC_F1: - return "fp1"; - case UNW_PPC_F2: - return "fp2"; - case UNW_PPC_F3: - return "fp3"; - case UNW_PPC_F4: - return "fp4"; - case UNW_PPC_F5: - return "fp5"; - case UNW_PPC_F6: - return "fp6"; - case UNW_PPC_F7: - return "fp7"; - case UNW_PPC_F8: - return "fp8"; - case UNW_PPC_F9: - return "fp9"; - case UNW_PPC_F10: - return "fp10"; - case UNW_PPC_F11: - return "fp11"; - case UNW_PPC_F12: - return "fp12"; - case UNW_PPC_F13: - return "fp13"; - case UNW_PPC_F14: - return "fp14"; - case UNW_PPC_F15: - return "fp15"; - case UNW_PPC_F16: - return "fp16"; - case UNW_PPC_F17: - return "fp17"; - case UNW_PPC_F18: - return "fp18"; - case UNW_PPC_F19: - return "fp19"; - case UNW_PPC_F20: - return "fp20"; - case UNW_PPC_F21: - return "fp21"; - case UNW_PPC_F22: - return "fp22"; - case UNW_PPC_F23: - return "fp23"; - case UNW_PPC_F24: - return "fp24"; - case UNW_PPC_F25: - return "fp25"; - case UNW_PPC_F26: - return "fp26"; - case UNW_PPC_F27: - return "fp27"; - case UNW_PPC_F28: - return "fp28"; - case UNW_PPC_F29: - return "fp29"; - case UNW_PPC_F30: - return "fp30"; - case UNW_PPC_F31: - return "fp31"; - case UNW_PPC_LR: - return "lr"; - default: - return "unknown register"; - } - -} -#endif // _LIBUNWIND_TARGET_PPC - - -#if defined(_LIBUNWIND_TARGET_AARCH64) -/// Registers_arm64 holds the register state of a thread in a 64-bit arm -/// process. -class _LIBUNWIND_HIDDEN Registers_arm64 { -public: - Registers_arm64(); - Registers_arm64(const void *registers); - - bool validRegister(int num) const; - uint64_t getRegister(int num) const; - void setRegister(int num, uint64_t value); - bool validFloatRegister(int num) const; - double getFloatRegister(int num) const; - void setFloatRegister(int num, double value); - bool validVectorRegister(int num) const; - v128 getVectorRegister(int num) const; - void setVectorRegister(int num, v128 value); - const char *getRegisterName(int num); - void jumpto(); - static int lastDwarfRegNum() { return _LIBUNWIND_HIGHEST_DWARF_REGISTER_ARM64; } - - uint64_t getSP() const { return _registers.__sp; } - void setSP(uint64_t value) { _registers.__sp = value; } - uint64_t getIP() const { return _registers.__pc; } - void setIP(uint64_t value) { _registers.__pc = value; } - uint64_t getFP() const { return _registers.__fp; } - void setFP(uint64_t value) { _registers.__fp = value; } - -private: - struct GPRs { - uint64_t __x[29]; // x0-x28 - uint64_t __fp; // Frame pointer x29 - uint64_t __lr; // Link register x30 - uint64_t __sp; // Stack pointer x31 - uint64_t __pc; // Program counter - uint64_t padding; // 16-byte align - }; - - GPRs _registers; - double _vectorHalfRegisters[32]; - // Currently only the lower double in 128-bit vectore registers - // is perserved during unwinding. We could define new register - // numbers (> 96) which mean whole vector registers, then this - // struct would need to change to contain whole vector registers. -}; - -inline Registers_arm64::Registers_arm64(const void *registers) { - static_assert((check_fit<Registers_arm64, unw_context_t>::does_fit), - "arm64 registers do not fit into unw_context_t"); - memcpy(&_registers, registers, sizeof(_registers)); - 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)); -} - -inline Registers_arm64::Registers_arm64() { - memset(&_registers, 0, sizeof(_registers)); - memset(&_vectorHalfRegisters, 0, sizeof(_vectorHalfRegisters)); -} - -inline bool Registers_arm64::validRegister(int regNum) const { - if (regNum == UNW_REG_IP) - return true; - if (regNum == UNW_REG_SP) - return true; - if (regNum < 0) - return false; - if (regNum > 95) - return false; - if ((regNum > 31) && (regNum < 64)) - return false; - return true; -} - -inline uint64_t Registers_arm64::getRegister(int regNum) const { - if (regNum == UNW_REG_IP) - return _registers.__pc; - if (regNum == UNW_REG_SP) - return _registers.__sp; - if ((regNum >= 0) && (regNum < 32)) - return _registers.__x[regNum]; - _LIBUNWIND_ABORT("unsupported arm64 register"); -} - -inline void Registers_arm64::setRegister(int regNum, uint64_t value) { - if (regNum == UNW_REG_IP) - _registers.__pc = value; - else if (regNum == UNW_REG_SP) - _registers.__sp = value; - else if ((regNum >= 0) && (regNum < 32)) - _registers.__x[regNum] = value; - else - _LIBUNWIND_ABORT("unsupported arm64 register"); -} - -inline const char *Registers_arm64::getRegisterName(int regNum) { - switch (regNum) { - case UNW_REG_IP: - return "pc"; - case UNW_REG_SP: - return "sp"; - case UNW_ARM64_X0: - return "x0"; - case UNW_ARM64_X1: - return "x1"; - case UNW_ARM64_X2: - return "x2"; - case UNW_ARM64_X3: - return "x3"; - case UNW_ARM64_X4: - return "x4"; - case UNW_ARM64_X5: - return "x5"; - case UNW_ARM64_X6: - return "x6"; - case UNW_ARM64_X7: - return "x7"; - case UNW_ARM64_X8: - return "x8"; - case UNW_ARM64_X9: - return "x9"; - case UNW_ARM64_X10: - return "x10"; - case UNW_ARM64_X11: - return "x11"; - case UNW_ARM64_X12: - return "x12"; - case UNW_ARM64_X13: - return "x13"; - case UNW_ARM64_X14: - return "x14"; - case UNW_ARM64_X15: - return "x15"; - case UNW_ARM64_X16: - return "x16"; - case UNW_ARM64_X17: - return "x17"; - case UNW_ARM64_X18: - return "x18"; - case UNW_ARM64_X19: - return "x19"; - case UNW_ARM64_X20: - return "x20"; - case UNW_ARM64_X21: - return "x21"; - case UNW_ARM64_X22: - return "x22"; - case UNW_ARM64_X23: - return "x23"; - case UNW_ARM64_X24: - return "x24"; - case UNW_ARM64_X25: - return "x25"; - case UNW_ARM64_X26: - return "x26"; - case UNW_ARM64_X27: - return "x27"; - case UNW_ARM64_X28: - return "x28"; - case UNW_ARM64_X29: - return "fp"; - case UNW_ARM64_X30: - return "lr"; - case UNW_ARM64_X31: - return "sp"; - case UNW_ARM64_D0: - return "d0"; - case UNW_ARM64_D1: - return "d1"; - case UNW_ARM64_D2: - return "d2"; - case UNW_ARM64_D3: - return "d3"; - case UNW_ARM64_D4: - return "d4"; - case UNW_ARM64_D5: - return "d5"; - case UNW_ARM64_D6: - return "d6"; - case UNW_ARM64_D7: - return "d7"; - case UNW_ARM64_D8: - return "d8"; - case UNW_ARM64_D9: - return "d9"; - case UNW_ARM64_D10: - return "d10"; - case UNW_ARM64_D11: - return "d11"; - case UNW_ARM64_D12: - return "d12"; - case UNW_ARM64_D13: - return "d13"; - case UNW_ARM64_D14: - return "d14"; - case UNW_ARM64_D15: - return "d15"; - case UNW_ARM64_D16: - return "d16"; - case UNW_ARM64_D17: - return "d17"; - case UNW_ARM64_D18: - return "d18"; - case UNW_ARM64_D19: - return "d19"; - case UNW_ARM64_D20: - return "d20"; - case UNW_ARM64_D21: - return "d21"; - case UNW_ARM64_D22: - return "d22"; - case UNW_ARM64_D23: - return "d23"; - case UNW_ARM64_D24: - return "d24"; - case UNW_ARM64_D25: - return "d25"; - case UNW_ARM64_D26: - return "d26"; - case UNW_ARM64_D27: - return "d27"; - case UNW_ARM64_D28: - return "d28"; - case UNW_ARM64_D29: - return "d29"; - case UNW_ARM64_D30: - return "d30"; - case UNW_ARM64_D31: - return "d31"; - default: - return "unknown register"; - } -} - -inline bool Registers_arm64::validFloatRegister(int regNum) const { - if (regNum < UNW_ARM64_D0) - return false; - if (regNum > UNW_ARM64_D31) - return false; - return true; -} - -inline double Registers_arm64::getFloatRegister(int regNum) const { - assert(validFloatRegister(regNum)); - return _vectorHalfRegisters[regNum - UNW_ARM64_D0]; -} - -inline void Registers_arm64::setFloatRegister(int regNum, double value) { - assert(validFloatRegister(regNum)); - _vectorHalfRegisters[regNum - UNW_ARM64_D0] = value; -} - -inline bool Registers_arm64::validVectorRegister(int) const { - return false; -} - -inline v128 Registers_arm64::getVectorRegister(int) const { - _LIBUNWIND_ABORT("no arm64 vector register support yet"); -} - -inline void Registers_arm64::setVectorRegister(int, v128) { - _LIBUNWIND_ABORT("no arm64 vector register support yet"); -} -#endif // _LIBUNWIND_TARGET_AARCH64 - -#if defined(_LIBUNWIND_TARGET_ARM) -/// Registers_arm holds the register state of a thread in a 32-bit arm -/// process. -/// -/// NOTE: Assumes VFPv3. On ARM processors without a floating point unit, -/// this uses more memory than required. -class _LIBUNWIND_HIDDEN Registers_arm { -public: - Registers_arm(); - Registers_arm(const void *registers); - - bool validRegister(int num) const; - uint32_t getRegister(int num); - void setRegister(int num, uint32_t value); - bool validFloatRegister(int num) const; - unw_fpreg_t getFloatRegister(int num); - void setFloatRegister(int num, unw_fpreg_t value); - bool validVectorRegister(int num) const; - v128 getVectorRegister(int num) const; - void setVectorRegister(int num, v128 value); - const char *getRegisterName(int num); - void jumpto() { - restoreSavedFloatRegisters(); - restoreCoreAndJumpTo(); - } - - uint32_t getSP() const { return _registers.__sp; } - void setSP(uint32_t value) { _registers.__sp = value; } - uint32_t getIP() const { return _registers.__pc; } - void setIP(uint32_t value) { _registers.__pc = value; } - - void saveVFPAsX() { - assert(_use_X_for_vfp_save || !_saved_vfp_d0_d15); - _use_X_for_vfp_save = true; - } - - void restoreSavedFloatRegisters() { - if (_saved_vfp_d0_d15) { - if (_use_X_for_vfp_save) - restoreVFPWithFLDMX(_vfp_d0_d15_pad); - else - restoreVFPWithFLDMD(_vfp_d0_d15_pad); - } - if (_saved_vfp_d16_d31) - restoreVFPv3(_vfp_d16_d31); -#if defined(__ARM_WMMX) - if (_saved_iwmmx) - restoreiWMMX(_iwmmx); - if (_saved_iwmmx_control) - restoreiWMMXControl(_iwmmx_control); -#endif - } - -private: - struct GPRs { - uint32_t __r[13]; // r0-r12 - uint32_t __sp; // Stack pointer r13 - uint32_t __lr; // Link register r14 - uint32_t __pc; // Program counter r15 - }; - - static void saveVFPWithFSTMD(unw_fpreg_t*); - static void saveVFPWithFSTMX(unw_fpreg_t*); - static void saveVFPv3(unw_fpreg_t*); - static void restoreVFPWithFLDMD(unw_fpreg_t*); - static void restoreVFPWithFLDMX(unw_fpreg_t*); - static void restoreVFPv3(unw_fpreg_t*); -#if defined(__ARM_WMMX) - static void saveiWMMX(unw_fpreg_t*); - static void saveiWMMXControl(uint32_t*); - static void restoreiWMMX(unw_fpreg_t*); - static void restoreiWMMXControl(uint32_t*); -#endif - void restoreCoreAndJumpTo(); - - // ARM registers - GPRs _registers; - - // We save floating point registers lazily because we can't know ahead of - // time which ones are used. See EHABI #4.7. - - // Whether D0-D15 are saved in the FTSMX instead of FSTMD format. - // - // See EHABI #7.5 that explains how matching instruction sequences for load - // and store need to be used to correctly restore the exact register bits. - bool _use_X_for_vfp_save; - // Whether VFP D0-D15 are saved. - bool _saved_vfp_d0_d15; - // Whether VFPv3 D16-D31 are saved. - bool _saved_vfp_d16_d31; - // VFP registers D0-D15, + padding if saved using FSTMX - unw_fpreg_t _vfp_d0_d15_pad[17]; - // VFPv3 registers D16-D31, always saved using FSTMD - unw_fpreg_t _vfp_d16_d31[16]; -#if defined(__ARM_WMMX) - // Whether iWMMX data registers are saved. - bool _saved_iwmmx; - // Whether iWMMX control registers are saved. - bool _saved_iwmmx_control; - // iWMMX registers - unw_fpreg_t _iwmmx[16]; - // iWMMX control registers - uint32_t _iwmmx_control[4]; -#endif -}; - -inline Registers_arm::Registers_arm(const void *registers) - : _use_X_for_vfp_save(false), - _saved_vfp_d0_d15(false), - _saved_vfp_d16_d31(false) { - static_assert((check_fit<Registers_arm, unw_context_t>::does_fit), - "arm registers do not fit into unw_context_t"); - // See unw_getcontext() note about data. - memcpy(&_registers, registers, sizeof(_registers)); - memset(&_vfp_d0_d15_pad, 0, sizeof(_vfp_d0_d15_pad)); - memset(&_vfp_d16_d31, 0, sizeof(_vfp_d16_d31)); -#if defined(__ARM_WMMX) - _saved_iwmmx = false; - _saved_iwmmx_control = false; - memset(&_iwmmx, 0, sizeof(_iwmmx)); - memset(&_iwmmx_control, 0, sizeof(_iwmmx_control)); -#endif -} - -inline Registers_arm::Registers_arm() - : _use_X_for_vfp_save(false), - _saved_vfp_d0_d15(false), - _saved_vfp_d16_d31(false) { - memset(&_registers, 0, sizeof(_registers)); - memset(&_vfp_d0_d15_pad, 0, sizeof(_vfp_d0_d15_pad)); - memset(&_vfp_d16_d31, 0, sizeof(_vfp_d16_d31)); -#if defined(__ARM_WMMX) - _saved_iwmmx = false; - _saved_iwmmx_control = false; - memset(&_iwmmx, 0, sizeof(_iwmmx)); - memset(&_iwmmx_control, 0, sizeof(_iwmmx_control)); -#endif -} - -inline bool Registers_arm::validRegister(int regNum) const { - // Returns true for all non-VFP registers supported by the EHABI - // virtual register set (VRS). - if (regNum == UNW_REG_IP) - return true; - - if (regNum == UNW_REG_SP) - return true; - - if (regNum >= UNW_ARM_R0 && regNum <= UNW_ARM_R15) - return true; - -#if defined(__ARM_WMMX) - if (regNum >= UNW_ARM_WC0 && regNum <= UNW_ARM_WC3) - return true; -#endif - - return false; -} - -inline uint32_t Registers_arm::getRegister(int regNum) { - if (regNum == UNW_REG_SP || regNum == UNW_ARM_SP) - return _registers.__sp; - - if (regNum == UNW_ARM_LR) - return _registers.__lr; - - if (regNum == UNW_REG_IP || regNum == UNW_ARM_IP) - return _registers.__pc; - - if (regNum >= UNW_ARM_R0 && regNum <= UNW_ARM_R12) - return _registers.__r[regNum]; - -#if defined(__ARM_WMMX) - if (regNum >= UNW_ARM_WC0 && regNum <= UNW_ARM_WC3) { - if (!_saved_iwmmx_control) { - _saved_iwmmx_control = true; - saveiWMMXControl(_iwmmx_control); - } - return _iwmmx_control[regNum - UNW_ARM_WC0]; - } -#endif - - _LIBUNWIND_ABORT("unsupported arm register"); -} - -inline void Registers_arm::setRegister(int regNum, uint32_t value) { - if (regNum == UNW_REG_SP || regNum == UNW_ARM_SP) { - _registers.__sp = value; - return; - } - - if (regNum == UNW_ARM_LR) { - _registers.__lr = value; - return; - } - - if (regNum == UNW_REG_IP || regNum == UNW_ARM_IP) { - _registers.__pc = value; - return; - } - - if (regNum >= UNW_ARM_R0 && regNum <= UNW_ARM_R12) { - _registers.__r[regNum] = value; - return; - } - -#if defined(__ARM_WMMX) - if (regNum >= UNW_ARM_WC0 && regNum <= UNW_ARM_WC3) { - if (!_saved_iwmmx_control) { - _saved_iwmmx_control = true; - saveiWMMXControl(_iwmmx_control); - } - _iwmmx_control[regNum - UNW_ARM_WC0] = value; - return; - } -#endif - - _LIBUNWIND_ABORT("unsupported arm register"); -} - -inline const char *Registers_arm::getRegisterName(int regNum) { - switch (regNum) { - case UNW_REG_IP: - case UNW_ARM_IP: // UNW_ARM_R15 is alias - return "pc"; - case UNW_ARM_LR: // UNW_ARM_R14 is alias - return "lr"; - case UNW_REG_SP: - case UNW_ARM_SP: // UNW_ARM_R13 is alias - return "sp"; - case UNW_ARM_R0: - return "r0"; - case UNW_ARM_R1: - return "r1"; - case UNW_ARM_R2: - return "r2"; - case UNW_ARM_R3: - return "r3"; - case UNW_ARM_R4: - return "r4"; - case UNW_ARM_R5: - return "r5"; - case UNW_ARM_R6: - return "r6"; - case UNW_ARM_R7: - return "r7"; - case UNW_ARM_R8: - return "r8"; - case UNW_ARM_R9: - return "r9"; - case UNW_ARM_R10: - return "r10"; - case UNW_ARM_R11: - return "r11"; - case UNW_ARM_R12: - return "r12"; - case UNW_ARM_S0: - return "s0"; - case UNW_ARM_S1: - return "s1"; - case UNW_ARM_S2: - return "s2"; - case UNW_ARM_S3: - return "s3"; - case UNW_ARM_S4: - return "s4"; - case UNW_ARM_S5: - return "s5"; - case UNW_ARM_S6: - return "s6"; - case UNW_ARM_S7: - return "s7"; - case UNW_ARM_S8: - return "s8"; - case UNW_ARM_S9: - return "s9"; - case UNW_ARM_S10: - return "s10"; - case UNW_ARM_S11: - return "s11"; - case UNW_ARM_S12: - return "s12"; - case UNW_ARM_S13: - return "s13"; - case UNW_ARM_S14: - return "s14"; - case UNW_ARM_S15: - return "s15"; - case UNW_ARM_S16: - return "s16"; - case UNW_ARM_S17: - return "s17"; - case UNW_ARM_S18: - return "s18"; - case UNW_ARM_S19: - return "s19"; - case UNW_ARM_S20: - return "s20"; - case UNW_ARM_S21: - return "s21"; - case UNW_ARM_S22: - return "s22"; - case UNW_ARM_S23: - return "s23"; - case UNW_ARM_S24: - return "s24"; - case UNW_ARM_S25: - return "s25"; - case UNW_ARM_S26: - return "s26"; - case UNW_ARM_S27: - return "s27"; - case UNW_ARM_S28: - return "s28"; - case UNW_ARM_S29: - return "s29"; - case UNW_ARM_S30: - return "s30"; - case UNW_ARM_S31: - return "s31"; - case UNW_ARM_D0: - return "d0"; - case UNW_ARM_D1: - return "d1"; - case UNW_ARM_D2: - return "d2"; - case UNW_ARM_D3: - return "d3"; - case UNW_ARM_D4: - return "d4"; - case UNW_ARM_D5: - return "d5"; - case UNW_ARM_D6: - return "d6"; - case UNW_ARM_D7: - return "d7"; - case UNW_ARM_D8: - return "d8"; - case UNW_ARM_D9: - return "d9"; - case UNW_ARM_D10: - return "d10"; - case UNW_ARM_D11: - return "d11"; - case UNW_ARM_D12: - return "d12"; - case UNW_ARM_D13: - return "d13"; - case UNW_ARM_D14: - return "d14"; - case UNW_ARM_D15: - return "d15"; - case UNW_ARM_D16: - return "d16"; - case UNW_ARM_D17: - return "d17"; - case UNW_ARM_D18: - return "d18"; - case UNW_ARM_D19: - return "d19"; - case UNW_ARM_D20: - return "d20"; - case UNW_ARM_D21: - return "d21"; - case UNW_ARM_D22: - return "d22"; - case UNW_ARM_D23: - return "d23"; - case UNW_ARM_D24: - return "d24"; - case UNW_ARM_D25: - return "d25"; - case UNW_ARM_D26: - return "d26"; - case UNW_ARM_D27: - return "d27"; - case UNW_ARM_D28: - return "d28"; - case UNW_ARM_D29: - return "d29"; - case UNW_ARM_D30: - return "d30"; - case UNW_ARM_D31: - return "d31"; - default: - return "unknown register"; - } -} - -inline bool Registers_arm::validFloatRegister(int regNum) const { - // NOTE: Consider the intel MMX registers floating points so the - // unw_get_fpreg can be used to transmit the 64-bit data back. - return ((regNum >= UNW_ARM_D0) && (regNum <= UNW_ARM_D31)) -#if defined(__ARM_WMMX) - || ((regNum >= UNW_ARM_WR0) && (regNum <= UNW_ARM_WR15)) -#endif - ; -} - -inline unw_fpreg_t Registers_arm::getFloatRegister(int regNum) { - if (regNum >= UNW_ARM_D0 && regNum <= UNW_ARM_D15) { - if (!_saved_vfp_d0_d15) { - _saved_vfp_d0_d15 = true; - if (_use_X_for_vfp_save) - saveVFPWithFSTMX(_vfp_d0_d15_pad); - else - saveVFPWithFSTMD(_vfp_d0_d15_pad); - } - return _vfp_d0_d15_pad[regNum - UNW_ARM_D0]; - } - - if (regNum >= UNW_ARM_D16 && regNum <= UNW_ARM_D31) { - if (!_saved_vfp_d16_d31) { - _saved_vfp_d16_d31 = true; - saveVFPv3(_vfp_d16_d31); - } - return _vfp_d16_d31[regNum - UNW_ARM_D16]; - } - -#if defined(__ARM_WMMX) - if (regNum >= UNW_ARM_WR0 && regNum <= UNW_ARM_WR15) { - if (!_saved_iwmmx) { - _saved_iwmmx = true; - saveiWMMX(_iwmmx); - } - return _iwmmx[regNum - UNW_ARM_WR0]; - } -#endif - - _LIBUNWIND_ABORT("Unknown ARM float register"); -} - -inline void Registers_arm::setFloatRegister(int regNum, unw_fpreg_t value) { - if (regNum >= UNW_ARM_D0 && regNum <= UNW_ARM_D15) { - if (!_saved_vfp_d0_d15) { - _saved_vfp_d0_d15 = true; - if (_use_X_for_vfp_save) - saveVFPWithFSTMX(_vfp_d0_d15_pad); - else - saveVFPWithFSTMD(_vfp_d0_d15_pad); - } - _vfp_d0_d15_pad[regNum - UNW_ARM_D0] = value; - return; - } - - if (regNum >= UNW_ARM_D16 && regNum <= UNW_ARM_D31) { - if (!_saved_vfp_d16_d31) { - _saved_vfp_d16_d31 = true; - saveVFPv3(_vfp_d16_d31); - } - _vfp_d16_d31[regNum - UNW_ARM_D16] = value; - return; - } - -#if defined(__ARM_WMMX) - if (regNum >= UNW_ARM_WR0 && regNum <= UNW_ARM_WR15) { - if (!_saved_iwmmx) { - _saved_iwmmx = true; - saveiWMMX(_iwmmx); - } - _iwmmx[regNum - UNW_ARM_WR0] = value; - return; - } -#endif - - _LIBUNWIND_ABORT("Unknown ARM float register"); -} - -inline bool Registers_arm::validVectorRegister(int) const { - return false; -} - -inline v128 Registers_arm::getVectorRegister(int) const { - _LIBUNWIND_ABORT("ARM vector support not implemented"); -} - -inline void Registers_arm::setVectorRegister(int, v128) { - _LIBUNWIND_ABORT("ARM vector support not implemented"); -} -#endif // _LIBUNWIND_TARGET_ARM - - -#if defined(_LIBUNWIND_TARGET_OR1K) -/// Registers_or1k holds the register state of a thread in an OpenRISC1000 -/// process. -class _LIBUNWIND_HIDDEN Registers_or1k { -public: - Registers_or1k(); - Registers_or1k(const void *registers); - - bool validRegister(int num) const; - uint32_t getRegister(int num) const; - void setRegister(int num, uint32_t value); - bool validFloatRegister(int num) const; - double getFloatRegister(int num) const; - void setFloatRegister(int num, double value); - bool validVectorRegister(int num) const; - v128 getVectorRegister(int num) const; - void setVectorRegister(int num, v128 value); - const char *getRegisterName(int num); - void jumpto(); - static int lastDwarfRegNum() { return _LIBUNWIND_HIGHEST_DWARF_REGISTER_OR1K; } - - uint64_t getSP() const { return _registers.__r[1]; } - void setSP(uint32_t value) { _registers.__r[1] = value; } - uint64_t getIP() const { return _registers.__r[9]; } - void setIP(uint32_t value) { _registers.__r[9] = value; } - -private: - struct or1k_thread_state_t { - unsigned int __r[32]; - }; - - or1k_thread_state_t _registers; -}; - -inline Registers_or1k::Registers_or1k(const void *registers) { - static_assert((check_fit<Registers_or1k, unw_context_t>::does_fit), - "or1k registers do not fit into unw_context_t"); - memcpy(&_registers, static_cast<const uint8_t *>(registers), - sizeof(_registers)); -} - -inline Registers_or1k::Registers_or1k() { - memset(&_registers, 0, sizeof(_registers)); -} - -inline bool Registers_or1k::validRegister(int regNum) const { - if (regNum == UNW_REG_IP) - return true; - if (regNum == UNW_REG_SP) - return true; - if (regNum < 0) - return false; - if (regNum <= UNW_OR1K_R31) - return true; - return false; -} - -inline uint32_t Registers_or1k::getRegister(int regNum) const { - if (regNum >= UNW_OR1K_R0 && regNum <= UNW_OR1K_R31) - return _registers.__r[regNum - UNW_OR1K_R0]; - - switch (regNum) { - case UNW_REG_IP: - return _registers.__r[9]; - case UNW_REG_SP: - return _registers.__r[1]; - } - _LIBUNWIND_ABORT("unsupported or1k register"); -} - -inline void Registers_or1k::setRegister(int regNum, uint32_t value) { - if (regNum >= UNW_OR1K_R0 && regNum <= UNW_OR1K_R31) { - _registers.__r[regNum - UNW_OR1K_R0] = value; - return; - } - - switch (regNum) { - case UNW_REG_IP: - _registers.__r[9] = value; - return; - case UNW_REG_SP: - _registers.__r[1] = value; - return; - } - _LIBUNWIND_ABORT("unsupported or1k register"); -} - -inline bool Registers_or1k::validFloatRegister(int /* regNum */) const { - return false; -} - -inline double Registers_or1k::getFloatRegister(int /* regNum */) const { - _LIBUNWIND_ABORT("or1k float support not implemented"); -} - -inline void Registers_or1k::setFloatRegister(int /* regNum */, - double /* value */) { - _LIBUNWIND_ABORT("or1k float support not implemented"); -} - -inline bool Registers_or1k::validVectorRegister(int /* regNum */) const { - return false; -} - -inline v128 Registers_or1k::getVectorRegister(int /* regNum */) const { - _LIBUNWIND_ABORT("or1k vector support not implemented"); -} - -inline void Registers_or1k::setVectorRegister(int /* regNum */, v128 /* value */) { - _LIBUNWIND_ABORT("or1k vector support not implemented"); -} - -inline const char *Registers_or1k::getRegisterName(int regNum) { - switch (regNum) { - case UNW_OR1K_R0: - return "r0"; - case UNW_OR1K_R1: - return "r1"; - case UNW_OR1K_R2: - return "r2"; - case UNW_OR1K_R3: - return "r3"; - case UNW_OR1K_R4: - return "r4"; - case UNW_OR1K_R5: - return "r5"; - case UNW_OR1K_R6: - return "r6"; - case UNW_OR1K_R7: - return "r7"; - case UNW_OR1K_R8: - return "r8"; - case UNW_OR1K_R9: - return "r9"; - case UNW_OR1K_R10: - return "r10"; - case UNW_OR1K_R11: - return "r11"; - case UNW_OR1K_R12: - return "r12"; - case UNW_OR1K_R13: - return "r13"; - case UNW_OR1K_R14: - return "r14"; - case UNW_OR1K_R15: - return "r15"; - case UNW_OR1K_R16: - return "r16"; - case UNW_OR1K_R17: - return "r17"; - case UNW_OR1K_R18: - return "r18"; - case UNW_OR1K_R19: - return "r19"; - case UNW_OR1K_R20: - return "r20"; - case UNW_OR1K_R21: - return "r21"; - case UNW_OR1K_R22: - return "r22"; - case UNW_OR1K_R23: - return "r23"; - case UNW_OR1K_R24: - return "r24"; - case UNW_OR1K_R25: - return "r25"; - case UNW_OR1K_R26: - return "r26"; - case UNW_OR1K_R27: - return "r27"; - case UNW_OR1K_R28: - return "r28"; - case UNW_OR1K_R29: - return "r29"; - case UNW_OR1K_R30: - return "r30"; - case UNW_OR1K_R31: - return "r31"; - default: - return "unknown register"; - } - -} -#endif // _LIBUNWIND_TARGET_OR1K -} // namespace libunwind - -#endif // __REGISTERS_HPP__ diff --git a/chromium/buildtools/third_party/libunwind/trunk/src/Unwind-EHABI.cpp b/chromium/buildtools/third_party/libunwind/trunk/src/Unwind-EHABI.cpp deleted file mode 100644 index f37732c6ac8..00000000000 --- a/chromium/buildtools/third_party/libunwind/trunk/src/Unwind-EHABI.cpp +++ /dev/null @@ -1,991 +0,0 @@ -//===--------------------------- Unwind-EHABI.cpp -------------------------===// -// -// 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. -// -// -// Implements ARM zero-cost C++ exceptions -// -//===----------------------------------------------------------------------===// - -#include "Unwind-EHABI.h" - -#if defined(_LIBUNWIND_ARM_EHABI) - -#include <inttypes.h> -#include <stdbool.h> -#include <stdint.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> - -#include <type_traits> - -#include "config.h" -#include "libunwind.h" -#include "libunwind_ext.h" -#include "unwind.h" - -namespace { - -// Strange order: take words in order, but inside word, take from most to least -// signinficant byte. -uint8_t getByte(const uint32_t* data, size_t offset) { - const uint8_t* byteData = reinterpret_cast<const uint8_t*>(data); - return byteData[(offset & ~(size_t)0x03) + (3 - (offset & (size_t)0x03))]; -} - -const char* getNextWord(const char* data, uint32_t* out) { - *out = *reinterpret_cast<const uint32_t*>(data); - return data + 4; -} - -const char* getNextNibble(const char* data, uint32_t* out) { - *out = *reinterpret_cast<const uint16_t*>(data); - return data + 2; -} - -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; -}; - -_Unwind_Reason_Code ProcessDescriptors( - _Unwind_State state, - _Unwind_Control_Block* ucbp, - struct _Unwind_Context* context, - Descriptor::Format format, - const char* descriptorStart, - uint32_t flags) { - - // EHT is inlined in the index using compact form. No descriptors. #5 - if (flags & 0x1) - return _URC_CONTINUE_UNWIND; - - // TODO: We should check the state here, and determine whether we need to - // perform phase1 or phase2 unwinding. - (void)state; - - const char* descriptor = descriptorStart; - uint32_t descriptorWord; - getNextWord(descriptor, &descriptorWord); - while (descriptorWord) { - // Read descriptor based on # 9.2. - uint32_t length; - uint32_t offset; - switch (format) { - case Descriptor::LU32: - descriptor = getNextWord(descriptor, &length); - descriptor = getNextWord(descriptor, &offset); - case Descriptor::LU16: - descriptor = getNextNibble(descriptor, &length); - descriptor = getNextNibble(descriptor, &offset); - default: - assert(false); - return _URC_FAILURE; - } - - // See # 9.2 table for decoding the kind of descriptor. It's a 2-bit value. - Descriptor::Kind kind = - static_cast<Descriptor::Kind>((length & 0x1) | ((offset & 0x1) << 1)); - - // Clear off flag from last bit. - length &= ~1u; - offset &= ~1u; - uintptr_t scopeStart = ucbp->pr_cache.fnstart + offset; - uintptr_t scopeEnd = scopeStart + length; - uintptr_t pc = _Unwind_GetIP(context); - bool isInScope = (scopeStart <= pc) && (pc < scopeEnd); - - switch (kind) { - case Descriptor::CLEANUP: { - // TODO(ajwong): Handle cleanup descriptors. - break; - } - case Descriptor::FUNC: { - // TODO(ajwong): Handle function descriptors. - break; - } - case Descriptor::CATCH: { - // Catch descriptors require gobbling one more word. - uint32_t landing_pad; - descriptor = getNextWord(descriptor, &landing_pad); - - if (isInScope) { - // TODO(ajwong): This is only phase1 compatible logic. Implement - // phase2. - landing_pad = signExtendPrel31(landing_pad & ~0x80000000); - if (landing_pad == 0xffffffff) { - return _URC_HANDLER_FOUND; - } else if (landing_pad == 0xfffffffe) { - return _URC_FAILURE; - } else { - /* - bool is_reference_type = landing_pad & 0x80000000; - void* matched_object; - if (__cxxabiv1::__cxa_type_match( - ucbp, reinterpret_cast<const std::type_info *>(landing_pad), - is_reference_type, - &matched_object) != __cxxabiv1::ctm_failed) - return _URC_HANDLER_FOUND; - */ - _LIBUNWIND_ABORT("Type matching not implemented"); - } - } - break; - } - default: - _LIBUNWIND_ABORT("Invalid descriptor kind found."); - } - - getNextWord(descriptor, &descriptorWord); - } - - return _URC_CONTINUE_UNWIND; -} - -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"); - Descriptor::Format format = - static_cast<Descriptor::Format>((*unwindingData & 0x0f000000) >> 24); - - const char *lsda = - reinterpret_cast<const char *>(_Unwind_GetLanguageSpecificData(context)); - - // Handle descriptors before unwinding so they are processed in the context - // of the correct stack frame. - _Unwind_Reason_Code result = - ProcessDescriptors(state, ucbp, context, format, lsda, - ucbp->pr_cache.additional); - - if (result != _URC_CONTINUE_UNWIND) - return result; - - if (unw_step(reinterpret_cast<unw_cursor_t*>(context)) != UNW_STEP_SUCCESS) - return _URC_FAILURE; - return _URC_CONTINUE_UNWIND; -} - -// Generates mask discriminator for _Unwind_VRS_Pop, e.g. for _UVRSC_CORE / -// _UVRSD_UINT32. -uint32_t RegisterMask(uint8_t start, uint8_t count_minus_one) { - return ((1U << (count_minus_one + 1)) - 1) << start; -} - -// Generates mask discriminator for _Unwind_VRS_Pop, e.g. for _UVRSC_VFP / -// _UVRSD_DOUBLE. -uint32_t RegisterRange(uint8_t start, uint8_t count_minus_one) { - return ((uint32_t)start << 16) | ((uint32_t)count_minus_one + 1); -} - -} // end anonymous namespace - -/** - * Decodes an EHT entry. - * - * @param data Pointer to EHT. - * @param[out] off Offset from return value (in bytes) to begin interpretation. - * @param[out] len Number of bytes in unwind code. - * @return Pointer to beginning of unwind code. - */ -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. Fortunately, all existing assembler - // implementations, including GNU assembler, LLVM integrated assembler, - // and ARM assembler, assume that the unwind opcodes come after the - // personality rountine address. - *off = 1; // First byte is size data. - *len = (((data[1] >> 24) & 0xff) + 1) * 4; - 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; -} - -_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) { - uint8_t byte = getByte(data, offset++); - if ((byte & 0x80) == 0) { - uint32_t sp; - _Unwind_VRS_Get(context, _UVRSC_CORE, UNW_ARM_SP, _UVRSD_UINT32, &sp); - if (byte & 0x40) - sp -= (((uint32_t)byte & 0x3f) << 2) + 4; - else - sp += ((uint32_t)byte << 2) + 4; - _Unwind_VRS_Set(context, _UVRSC_CORE, UNW_ARM_SP, _UVRSD_UINT32, &sp); - } else { - switch (byte & 0xf0) { - case 0x80: { - if (offset >= len) - return _URC_FAILURE; - uint32_t registers = - (((uint32_t)byte & 0x0f) << 12) | - (((uint32_t)getByte(data, offset++)) << 4); - if (!registers) - return _URC_FAILURE; - if (registers & (1 << 15)) - wrotePC = true; - _Unwind_VRS_Pop(context, _UVRSC_CORE, registers, _UVRSD_UINT32); - break; - } - case 0x90: { - uint8_t reg = byte & 0x0f; - if (reg == 13 || reg == 15) - return _URC_FAILURE; - uint32_t sp; - _Unwind_VRS_Get(context, _UVRSC_CORE, UNW_ARM_R0 + reg, - _UVRSD_UINT32, &sp); - _Unwind_VRS_Set(context, _UVRSC_CORE, UNW_ARM_SP, _UVRSD_UINT32, - &sp); - break; - } - case 0xa0: { - uint32_t registers = RegisterMask(4, byte & 0x07); - if (byte & 0x08) - registers |= 1 << 14; - _Unwind_VRS_Pop(context, _UVRSC_CORE, registers, _UVRSD_UINT32); - break; - } - case 0xb0: { - switch (byte) { - case 0xb0: - finish = true; - break; - case 0xb1: { - if (offset >= len) - return _URC_FAILURE; - uint8_t registers = getByte(data, offset++); - if (registers & 0xf0 || !registers) - return _URC_FAILURE; - _Unwind_VRS_Pop(context, _UVRSC_CORE, registers, _UVRSD_UINT32); - break; - } - case 0xb2: { - uint32_t addend = 0; - uint32_t shift = 0; - // This decodes a uleb128 value. - while (true) { - if (offset >= len) - return _URC_FAILURE; - uint32_t v = getByte(data, offset++); - addend |= (v & 0x7f) << shift; - if ((v & 0x80) == 0) - break; - shift += 7; - } - uint32_t sp; - _Unwind_VRS_Get(context, _UVRSC_CORE, UNW_ARM_SP, _UVRSD_UINT32, - &sp); - sp += 0x204 + (addend << 2); - _Unwind_VRS_Set(context, _UVRSC_CORE, UNW_ARM_SP, _UVRSD_UINT32, - &sp); - break; - } - case 0xb3: { - uint8_t v = getByte(data, offset++); - _Unwind_VRS_Pop(context, _UVRSC_VFP, - RegisterRange(static_cast<uint8_t>(v >> 4), - v & 0x0f), _UVRSD_VFPX); - break; - } - case 0xb4: - case 0xb5: - case 0xb6: - case 0xb7: - return _URC_FAILURE; - default: - _Unwind_VRS_Pop(context, _UVRSC_VFP, - RegisterRange(8, byte & 0x07), _UVRSD_VFPX); - break; - } - break; - } - case 0xc0: { - switch (byte) { -#if defined(__ARM_WMMX) - case 0xc0: - case 0xc1: - case 0xc2: - case 0xc3: - case 0xc4: - case 0xc5: - _Unwind_VRS_Pop(context, _UVRSC_WMMXD, - RegisterRange(10, byte & 0x7), _UVRSD_DOUBLE); - break; - case 0xc6: { - uint8_t v = getByte(data, offset++); - 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; - _Unwind_VRS_Pop(context, _UVRSC_WMMXD, - RegisterRange(start, count_minus_one), - _UVRSD_DOUBLE); - break; - } - case 0xc7: { - uint8_t v = getByte(data, offset++); - if (!v || v & 0xf0) - return _URC_FAILURE; - _Unwind_VRS_Pop(context, _UVRSC_WMMXC, v, _UVRSD_DOUBLE); - break; - } -#endif - case 0xc8: - case 0xc9: { - uint8_t v = getByte(data, offset++); - 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; - _Unwind_VRS_Pop(context, _UVRSC_VFP, - RegisterRange(start, count_minus_one), - _UVRSD_DOUBLE); - break; - } - default: - return _URC_FAILURE; - } - break; - } - case 0xd0: { - if (byte & 0x08) - return _URC_FAILURE; - _Unwind_VRS_Pop(context, _UVRSC_VFP, RegisterRange(8, byte & 0x7), - _UVRSD_DOUBLE); - break; - } - default: - return _URC_FAILURE; - } - } - } - if (!wrotePC) { - uint32_t lr; - _Unwind_VRS_Get(context, _UVRSC_CORE, UNW_ARM_LR, _UVRSD_UINT32, &lr); - _Unwind_VRS_Set(context, _UVRSC_CORE, UNW_ARM_IP, _UVRSD_UINT32, &lr); - } - return _URC_CONTINUE_UNWIND; -} - -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" _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" _LIBUNWIND_EXPORT _Unwind_Reason_Code -__aeabi_unwind_cpp_pr2(_Unwind_State state, _Unwind_Control_Block *ucbp, - _Unwind_Context *context) { - return unwindOneFrame(state, ucbp, context); -} - -static _Unwind_Reason_Code -unwind_phase1(unw_context_t *uc, unw_cursor_t *cursor, _Unwind_Exception *exception_object) { - // EHABI #7.3 discusses preserving the VRS in a "temporary VRS" during - // phase 1 and then restoring it to the "primary VRS" for phase 2. The - // effect is phase 2 doesn't see any of the VRS manipulations from phase 1. - // In this implementation, the phases don't share the VRS backing store. - // Instead, they are passed the original |uc| and they create a new VRS - // from scratch thus achieving the same effect. - unw_init_local(cursor, uc); - - // Walk each frame looking for a place to stop. - for (bool handlerNotFound = true; handlerNotFound;) { - - // See if frame has code to run (has personality routine). - 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", - static_cast<void *>(exception_object)); - return _URC_FATAL_PHASE1_ERROR; - } - - // When tracing, print state information. - if (_LIBUNWIND_TRACING_UNWINDING) { - char functionBuf[512]; - const char *functionName = functionBuf; - unw_word_t offset; - if ((unw_get_proc_name(cursor, functionBuf, sizeof(functionBuf), - &offset) != UNW_ESUCCESS) || - (frameInfo.start_ip + offset > frameInfo.end_ip)) - functionName = ".anonymous."; - unw_word_t pc; - unw_get_reg(cursor, UNW_REG_IP, &pc); - _LIBUNWIND_TRACE_UNWINDING( - "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 - // this frame. - if (frameInfo.handler != 0) { - __personality_routine p = - (__personality_routine)(long)(frameInfo.handler); - _LIBUNWIND_TRACE_UNWINDING( - "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); - exception_object->pr_cache.fnstart = frameInfo.start_ip; - exception_object->pr_cache.ehtp = - (_Unwind_EHT_Header *)frameInfo.unwind_info; - exception_object->pr_cache.additional = frameInfo.flags; - _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", - 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: - // found a catch clause or locals that need destructing in this frame - // 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", - static_cast<void *>(exception_object)); - return _URC_NO_REASON; - - case _URC_CONTINUE_UNWIND: - _LIBUNWIND_TRACE_UNWINDING( - "unwind_phase1(ex_ojb=%p): _URC_CONTINUE_UNWIND", - static_cast<void *>(exception_object)); - // continue unwinding - break; - - // EHABI #7.3.3 - case _URC_FAILURE: - return _URC_FAILURE; - - default: - // something went wrong - _LIBUNWIND_TRACE_UNWINDING( - "unwind_phase1(ex_ojb=%p): _URC_FATAL_PHASE1_ERROR", - static_cast<void *>(exception_object)); - return _URC_FATAL_PHASE1_ERROR; - } - } - } - return _URC_NO_REASON; -} - -static _Unwind_Reason_Code unwind_phase2(unw_context_t *uc, unw_cursor_t *cursor, - _Unwind_Exception *exception_object, - bool resume) { - // See comment at the start of unwind_phase1 regarding VRS integrity. - unw_init_local(cursor, uc); - - _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 libunwind to get next frame (skip over first which is - // _Unwind_RaiseException or _Unwind_Resume). - // - // Resume only ever makes sense for 1 frame. - _Unwind_State state = - resume ? _US_UNWIND_FRAME_RESUME : _US_UNWIND_FRAME_STARTING; - if (resume && frame_count == 1) { - // On a resume, first unwind the _Unwind_Resume() frame. The next frame - // is now the landing pad for the cleanup from a previous execution of - // phase2. To continue unwindingly correctly, replace VRS[15] with the - // IP of the frame that the previous run of phase2 installed the context - // for. After this, continue unwinding as if normal. - // - // See #7.4.6 for details. - unw_set_reg(cursor, UNW_REG_IP, - exception_object->unwinder_cache.reserved2); - resume = false; - } - - // Get info about this frame. - unw_word_t sp; - unw_proc_info_t frameInfo; - 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_PHASE2_ERROR", - static_cast<void *>(exception_object)); - return _URC_FATAL_PHASE2_ERROR; - } - - // When tracing, print state information. - if (_LIBUNWIND_TRACING_UNWINDING) { - char functionBuf[512]; - const char *functionName = functionBuf; - unw_word_t offset; - if ((unw_get_proc_name(cursor, 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%" 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. - if (frameInfo.handler != 0) { - __personality_routine p = - (__personality_routine)(long)(frameInfo.handler); - struct _Unwind_Context *context = (struct _Unwind_Context *)(cursor); - // EHABI #7.2 - exception_object->pr_cache.fnstart = frameInfo.start_ip; - exception_object->pr_cache.ehtp = - (_Unwind_EHT_Header *)frameInfo.unwind_info; - exception_object->pr_cache.additional = frameInfo.flags; - _Unwind_Reason_Code personalityResult = - (*p)(state, exception_object, context); - switch (personalityResult) { - case _URC_CONTINUE_UNWIND: - // Continue unwinding - _LIBUNWIND_TRACE_UNWINDING( - "unwind_phase2(ex_ojb=%p): _URC_CONTINUE_UNWIND", - 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... - _LIBUNWIND_ABORT("during phase1 personality function said it would " - "stop here, but now in phase2 it did not stop here"); - } - break; - case _URC_INSTALL_CONTEXT: - _LIBUNWIND_TRACE_UNWINDING( - "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(). - if (_LIBUNWIND_TRACING_UNWINDING) { - unw_word_t pc; - 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%" PRIxPTR ", sp=0x%" PRIxPTR, - static_cast<void *>(exception_object), - pc, sp); - } - - { - // EHABI #7.4.1 says we need to preserve pc for when _Unwind_Resume - // is called back, to find this same frame. - unw_word_t pc; - unw_get_reg(cursor, UNW_REG_IP, &pc); - exception_object->unwinder_cache.reserved2 = (uint32_t)pc; - } - unw_resume(cursor); - // unw_resume() only returns if there was an error. - return _URC_FATAL_PHASE2_ERROR; - - // # EHABI #7.4.3 - case _URC_FAILURE: - abort(); - - default: - // Personality routine returned an unknown result code. - _LIBUNWIND_DEBUG_LOG("personality function returned unknown result %d", - personalityResult); - return _URC_FATAL_PHASE2_ERROR; - } - } - frame_count++; - } - - // Clean up phase did not resume at the frame that the search phase - // said it would... - return _URC_FATAL_PHASE2_ERROR; -} - -/// 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)", - static_cast<void *>(exception_object)); - unw_context_t uc; - unw_cursor_t cursor; - unw_getcontext(&uc); - - // This field for is for compatibility with GCC to say this isn't a forced - // unwind. EHABI #7.2 - exception_object->unwinder_cache.reserved1 = 0; - - // phase 1: the search phase - _Unwind_Reason_Code phase1 = unwind_phase1(&uc, &cursor, exception_object); - if (phase1 != _URC_NO_REASON) - return phase1; - - // phase 2: the clean up phase - return unwind_phase2(&uc, &cursor, exception_object, false); -} - -_LIBUNWIND_EXPORT void _Unwind_Complete(_Unwind_Exception* exception_object) { - // This is to be called when exception handling completes to give us a chance - // to perform any housekeeping. EHABI #7.2. But we have nothing to do here. - (void)exception_object; -} - -/// When _Unwind_RaiseException() is in phase2, it hands control -/// to the personality function at each frame. The personality -/// may force a jump to a landing pad in that function, the landing -/// pad code may then call _Unwind_Resume() to continue with the -/// unwinding. Note: the call to _Unwind_Resume() is from compiler -/// geneated user code. All other _Unwind_* routines are called -/// by the C++ runtime __cxa_* routines. -/// -/// Note: re-throwing an exception (as opposed to continuing the unwind) -/// is implemented by having the code call __cxa_rethrow() which -/// in turn calls _Unwind_Resume_or_Rethrow(). -_LIBUNWIND_EXPORT void -_Unwind_Resume(_Unwind_Exception *exception_object) { - _LIBUNWIND_TRACE_API("_Unwind_Resume(ex_obj=%p)", - static_cast<void *>(exception_object)); - unw_context_t uc; - unw_cursor_t cursor; - unw_getcontext(&uc); - - // _Unwind_RaiseException on EHABI will always set the reserved1 field to 0, - // which is in the same position as private_1 below. - // TODO(ajwong): Who wronte the above? Why is it true? - unwind_phase2(&uc, &cursor, exception_object, true); - - // Clients assume _Unwind_Resume() does not return, so all we can do is abort. - _LIBUNWIND_ABORT("_Unwind_Resume() can't return"); -} - -/// Called by personality handler during phase 2 to get LSDA for current frame. -_LIBUNWIND_EXPORT uintptr_t -_Unwind_GetLanguageSpecificData(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.lsda; - _LIBUNWIND_TRACE_API( - "_Unwind_GetLanguageSpecificData(context=%p) => 0x%llx", - static_cast<void *>(context), (long long)result); - return result; -} - -static uint64_t ValueAsBitPattern(_Unwind_VRS_DataRepresentation representation, - void* valuep) { - uint64_t value = 0; - switch (representation) { - case _UVRSD_UINT32: - case _UVRSD_FLOAT: - memcpy(&value, valuep, sizeof(uint32_t)); - break; - - case _UVRSD_VFPX: - case _UVRSD_UINT64: - case _UVRSD_DOUBLE: - memcpy(&value, valuep, sizeof(uint64_t)); - break; - } - return value; -} - -_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)", - static_cast<void *>(context), regclass, regno, - representation, - ValueAsBitPattern(representation, valuep)); - unw_cursor_t *cursor = (unw_cursor_t *)context; - switch (regclass) { - case _UVRSC_CORE: - if (representation != _UVRSD_UINT32 || regno > 15) - return _UVRSR_FAILED; - return unw_set_reg(cursor, (unw_regnum_t)(UNW_ARM_R0 + regno), - *(unw_word_t *)valuep) == UNW_ESUCCESS - ? _UVRSR_OK - : _UVRSR_FAILED; - case _UVRSC_VFP: - if (representation != _UVRSD_VFPX && representation != _UVRSD_DOUBLE) - return _UVRSR_FAILED; - if (representation == _UVRSD_VFPX) { - // Can only touch d0-15 with FSTMFDX. - if (regno > 15) - return _UVRSR_FAILED; - unw_save_vfp_as_X(cursor); - } else { - if (regno > 31) - return _UVRSR_FAILED; - } - return unw_set_fpreg(cursor, (unw_regnum_t)(UNW_ARM_D0 + regno), - *(unw_fpreg_t *)valuep) == UNW_ESUCCESS - ? _UVRSR_OK - : _UVRSR_FAILED; -#if defined(__ARM_WMMX) - case _UVRSC_WMMXC: - if (representation != _UVRSD_UINT32 || regno > 3) - return _UVRSR_FAILED; - return unw_set_reg(cursor, (unw_regnum_t)(UNW_ARM_WC0 + regno), - *(unw_word_t *)valuep) == UNW_ESUCCESS - ? _UVRSR_OK - : _UVRSR_FAILED; - case _UVRSC_WMMXD: - if (representation != _UVRSD_DOUBLE || regno > 31) - return _UVRSR_FAILED; - return unw_set_fpreg(cursor, (unw_regnum_t)(UNW_ARM_WR0 + regno), - *(unw_fpreg_t *)valuep) == UNW_ESUCCESS - ? _UVRSR_OK - : _UVRSR_FAILED; -#else - case _UVRSC_WMMXC: - case _UVRSC_WMMXD: - break; -#endif - } - _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) { - unw_cursor_t *cursor = (unw_cursor_t *)context; - switch (regclass) { - case _UVRSC_CORE: - if (representation != _UVRSD_UINT32 || regno > 15) - return _UVRSR_FAILED; - return unw_get_reg(cursor, (unw_regnum_t)(UNW_ARM_R0 + regno), - (unw_word_t *)valuep) == UNW_ESUCCESS - ? _UVRSR_OK - : _UVRSR_FAILED; - case _UVRSC_VFP: - if (representation != _UVRSD_VFPX && representation != _UVRSD_DOUBLE) - return _UVRSR_FAILED; - if (representation == _UVRSD_VFPX) { - // Can only touch d0-15 with FSTMFDX. - if (regno > 15) - return _UVRSR_FAILED; - unw_save_vfp_as_X(cursor); - } else { - if (regno > 31) - return _UVRSR_FAILED; - } - return unw_get_fpreg(cursor, (unw_regnum_t)(UNW_ARM_D0 + regno), - (unw_fpreg_t *)valuep) == UNW_ESUCCESS - ? _UVRSR_OK - : _UVRSR_FAILED; -#if defined(__ARM_WMMX) - case _UVRSC_WMMXC: - if (representation != _UVRSD_UINT32 || regno > 3) - return _UVRSR_FAILED; - return unw_get_reg(cursor, (unw_regnum_t)(UNW_ARM_WC0 + regno), - (unw_word_t *)valuep) == UNW_ESUCCESS - ? _UVRSR_OK - : _UVRSR_FAILED; - case _UVRSC_WMMXD: - if (representation != _UVRSD_DOUBLE || regno > 31) - return _UVRSR_FAILED; - return unw_get_fpreg(cursor, (unw_regnum_t)(UNW_ARM_WR0 + regno), - (unw_fpreg_t *)valuep) == UNW_ESUCCESS - ? _UVRSR_OK - : _UVRSR_FAILED; -#else - case _UVRSC_WMMXC: - case _UVRSC_WMMXD: - break; -#endif - } - _LIBUNWIND_ABORT("unsupported register class"); -} - -_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)", - 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) { - _LIBUNWIND_TRACE_API("_Unwind_VRS_Pop(context=%p, regclass=%d, " - "discriminator=%d, representation=%d)", - static_cast<void *>(context), regclass, discriminator, - representation); - switch (regclass) { - 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 - // computed new stack location. See EHABI #7.5.4 table 3. - bool poppedSP = false; - uint32_t* sp; - if (_Unwind_VRS_Get(context, _UVRSC_CORE, UNW_ARM_SP, - _UVRSD_UINT32, &sp) != _UVRSR_OK) { - return _UVRSR_FAILED; - } - for (uint32_t i = 0; i < 16; ++i) { - if (!(discriminator & static_cast<uint32_t>(1 << i))) - continue; - uint32_t value = *sp++; - if (regclass == _UVRSC_CORE && i == 13) - poppedSP = true; - if (_Unwind_VRS_Set(context, regclass, i, - _UVRSD_UINT32, &value) != _UVRSR_OK) { - return _UVRSR_FAILED; - } - } - if (!poppedSP) { - return _Unwind_VRS_Set(context, _UVRSC_CORE, UNW_ARM_SP, - _UVRSD_UINT32, &sp); - } - return _UVRSR_OK; - } - 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; - uint32_t count = discriminator & 0xffff; - uint32_t end = first+count; - uint32_t* sp; - if (_Unwind_VRS_Get(context, _UVRSC_CORE, UNW_ARM_SP, - _UVRSD_UINT32, &sp) != _UVRSR_OK) { - return _UVRSR_FAILED; - } - // For _UVRSD_VFPX, we're assuming the data is stored in FSTMX "standard - // format 1", which is equivalent to FSTMD + a padding word. - for (uint32_t i = first; i < end; ++i) { - // SP is only 32-bit aligned so don't copy 64-bit at a time. - uint64_t value = *sp++; - value |= ((uint64_t)(*sp++)) << 32; - if (_Unwind_VRS_Set(context, regclass, i, representation, &value) != - _UVRSR_OK) - return _UVRSR_FAILED; - } - if (representation == _UVRSD_VFPX) - ++sp; - 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 -/// 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%llX", - static_cast<void *>(context), (long long)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)", - static_cast<void *>(exception_object)); - if (exception_object->exception_cleanup != NULL) - (*exception_object->exception_cleanup)(_URC_FOREIGN_EXCEPTION_CAUGHT, - exception_object); -} - -extern "C" _LIBUNWIND_EXPORT _Unwind_Reason_Code -__gnu_unwind_frame(_Unwind_Exception *exception_object, - struct _Unwind_Context *context) { - unw_cursor_t *cursor = (unw_cursor_t *)context; - if (unw_step(cursor) != UNW_STEP_SUCCESS) - return _URC_FAILURE; - return _URC_OK; -} - -#endif // defined(_LIBUNWIND_ARM_EHABI) diff --git a/chromium/buildtools/third_party/libunwind/trunk/src/Unwind-EHABI.h b/chromium/buildtools/third_party/libunwind/trunk/src/Unwind-EHABI.h deleted file mode 100644 index fe164ff7be1..00000000000 --- a/chromium/buildtools/third_party/libunwind/trunk/src/Unwind-EHABI.h +++ /dev/null @@ -1,51 +0,0 @@ -//===------------------------- 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 <__libunwind_config.h> - -#if defined(_LIBUNWIND_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 // defined(_LIBUNWIND_ARM_EHABI) - -#endif // __UNWIND_EHABI_H__ diff --git a/chromium/buildtools/third_party/libunwind/trunk/src/Unwind-sjlj.c b/chromium/buildtools/third_party/libunwind/trunk/src/Unwind-sjlj.c deleted file mode 100644 index 90cac3f8c76..00000000000 --- a/chromium/buildtools/third_party/libunwind/trunk/src/Unwind-sjlj.c +++ /dev/null @@ -1,504 +0,0 @@ -//===--------------------------- Unwind-sjlj.c ----------------------------===// -// -// 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. -// -// -// Implements setjump-longjump based C++ exceptions -// -//===----------------------------------------------------------------------===// - -#include <unwind.h> - -#include <stdint.h> -#include <stdbool.h> -#include <stdlib.h> - -#include "config.h" - -/// 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 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 - uint32_t resumeLocation; - - // set by personality handler to be parameters passed to landing pad function - uint32_t resumeParameters[4]; - - // set by calling function before registering - __personality_routine personality; // arm offset=24 - uintptr_t lsda; // arm offset=28 - - // variable length array, contains registers to restore - // 0 = r7, 1 = pc, 2 = sp - 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 -_Unwind_SjLj_Register(struct _Unwind_FunctionContext *fc) { - fc->prev = __Unwind_SjLj_GetTopOfFunctionStack(); - __Unwind_SjLj_SetTopOfFunctionStack(fc); -} - - -/// Called at end of each function that catches exceptions -_LIBUNWIND_EXPORT void -_Unwind_SjLj_Unregister(struct _Unwind_FunctionContext *fc) { - __Unwind_SjLj_SetTopOfFunctionStack(fc->prev); -} - - -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", 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", - exception_object); - return _URC_END_OF_STACK; - } - - _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", - exception_object, c->personality); - _Unwind_Reason_Code personalityResult = (*c->personality)( - 1, _UA_SEARCH_PHASE, exception_object->exception_class, - exception_object, (struct _Unwind_Context *)c); - switch (personalityResult) { - case _URC_HANDLER_FOUND: - // found a catch clause or locals that need destructing in this frame - // stop search and remember function context - handlerNotFound = false; - exception_object->private_2 = (uintptr_t) c; - _LIBUNWIND_TRACE_UNWINDING("unwind_phase1(ex_ojb=%p): " - "_URC_HANDLER_FOUND", exception_object); - return _URC_NO_REASON; - - case _URC_CONTINUE_UNWIND: - _LIBUNWIND_TRACE_UNWINDING("unwind_phase1(ex_ojb=%p): " - "_URC_CONTINUE_UNWIND", exception_object); - // continue unwinding - break; - - default: - // something went wrong - _LIBUNWIND_TRACE_UNWINDING( - "unwind_phase1(ex_ojb=%p): _URC_FATAL_PHASE1_ERROR", - exception_object); - return _URC_FATAL_PHASE1_ERROR; - } - } - } - return _URC_NO_REASON; -} - - -static _Unwind_Reason_Code -unwind_phase2(struct _Unwind_Exception *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", - 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", - exception_object); - return _URC_END_OF_STACK; - } - - // if there is a personality routine, tell it we are unwinding - if (c->personality != NULL) { - _Unwind_Action action = _UA_CLEANUP_PHASE; - if ((uintptr_t) c == exception_object->private_2) - action = (_Unwind_Action)( - _UA_CLEANUP_PHASE | - _UA_HANDLER_FRAME); // tell personality this was the frame it marked - // in phase 1 - _Unwind_Reason_Code personalityResult = - (*c->personality)(1, action, exception_object->exception_class, - exception_object, (struct _Unwind_Context *)c); - switch (personalityResult) { - case _URC_CONTINUE_UNWIND: - // continue unwinding - _LIBUNWIND_TRACE_UNWINDING( - "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... - _LIBUNWIND_ABORT("during phase1 personality function said it would " - "stop here, but now if phase2 it did not stop here"); - } - break; - case _URC_INSTALL_CONTEXT: - _LIBUNWIND_TRACE_UNWINDING("unwind_phase2(ex_ojb=%p): " - "_URC_INSTALL_CONTEXT, will resume at " - "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() - __Unwind_SjLj_SetTopOfFunctionStack(c); - __builtin_longjmp(c->jbuf, 1); - // unw_resume() only returns if there was an error - return _URC_FATAL_PHASE2_ERROR; - default: - // something went wrong - _LIBUNWIND_DEBUG_LOG("personality function returned unknown result %d", - personalityResult); - return _URC_FATAL_PHASE2_ERROR; - } - } - c = c->prev; - } - - // clean up phase did not resume at the frame that the search phase said it - // would - return _URC_FATAL_PHASE2_ERROR; -} - - -static _Unwind_Reason_Code -unwind_phase2_forced(struct _Unwind_Exception *exception_object, - _Unwind_Stop_Fn stop, void *stop_parameter) { - // walk each frame until we reach where search phase said to stop - _Unwind_FunctionContext_t c = __Unwind_SjLj_GetTopOfFunctionStack(); - while (true) { - - // 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", - exception_object); - return _URC_END_OF_STACK; - } - - // call stop function at each frame - _Unwind_Action action = - (_Unwind_Action)(_UA_FORCE_UNWIND | _UA_CLEANUP_PHASE); - _Unwind_Reason_Code stopResult = - (*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", - exception_object, stopResult); - if (stopResult != _URC_NO_REASON) { - _LIBUNWIND_TRACE_UNWINDING("unwind_phase2_forced(ex_ojb=%p): " - "stopped by stop function", - exception_object); - return _URC_FATAL_PHASE2_ERROR; - } - - // if there is a personality routine, tell it we are unwinding - if (c->personality != NULL) { - __personality_routine p = (__personality_routine) c->personality; - _LIBUNWIND_TRACE_UNWINDING("unwind_phase2_forced(ex_ojb=%p): " - "calling personality function %p", - exception_object, p); - _Unwind_Reason_Code personalityResult = - (*p)(1, action, exception_object->exception_class, exception_object, - (struct _Unwind_Context *)c); - switch (personalityResult) { - case _URC_CONTINUE_UNWIND: - _LIBUNWIND_TRACE_UNWINDING("unwind_phase2_forced(ex_ojb=%p): " - "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", - exception_object); - // we may get control back if landing pad calls _Unwind_Resume() - __Unwind_SjLj_SetTopOfFunctionStack(c); - __builtin_longjmp(c->jbuf, 1); - break; - default: - // something went wrong - _LIBUNWIND_TRACE_UNWINDING("unwind_phase2_forced(ex_ojb=%p): " - "personality returned %d, " - "_URC_FATAL_PHASE2_ERROR", - exception_object, personalityResult); - return _URC_FATAL_PHASE2_ERROR; - } - } - c = c->prev; - } - - // 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", - 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, - (struct _Unwind_Context *)c, stop_parameter); - - // clean up phase did not resume at the frame that the search phase said it - // would - return _URC_FATAL_PHASE2_ERROR; -} - - -/// 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)", exception_object); - - // mark that this is a non-forced unwind, so _Unwind_Resume() can do the right - // thing - exception_object->private_1 = 0; - exception_object->private_2 = 0; - - // phase 1: the search phase - _Unwind_Reason_Code phase1 = unwind_phase1(exception_object); - if (phase1 != _URC_NO_REASON) - return phase1; - - // phase 2: the clean up phase - return unwind_phase2(exception_object); -} - - - -/// When _Unwind_RaiseException() is in phase2, it hands control -/// to the personality function at each frame. The personality -/// may force a jump to a landing pad in that function, the landing -/// pad code may then call _Unwind_Resume() to continue with the -/// unwinding. Note: the call to _Unwind_Resume() is from compiler -/// geneated user code. All other _Unwind_* routines are called -/// by the C++ runtime __cxa_* routines. -/// -/// Re-throwing an exception is implemented by having the code call -/// __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)", exception_object); - - if (exception_object->private_1 != 0) - unwind_phase2_forced(exception_object, - (_Unwind_Stop_Fn) exception_object->private_1, - (void *)exception_object->private_2); - else - unwind_phase2(exception_object); - - // clients assume _Unwind_Resume() does not return, so all we can do is abort. - _LIBUNWIND_ABORT("_Unwind_SjLj_Resume() can't return"); -} - - -/// Called by __cxa_rethrow(). -_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", - exception_object, exception_object->private_1); - // If this is non-forced and a stopping place was found, then this is a - // re-throw. - // Call _Unwind_RaiseException() as if this was a new exception. - if (exception_object->private_1 == 0) { - return _Unwind_SjLj_RaiseException(exception_object); - // should return if there is no catch clause, so that __cxa_rethrow can call - // std::terminate() - } - - // Call through to _Unwind_Resume() which distiguishes between forced and - // regular exceptions. - _Unwind_SjLj_Resume(exception_object); - _LIBUNWIND_ABORT("__Unwind_SjLj_Resume_or_Rethrow() called " - "_Unwind_SjLj_Resume() which unexpectedly returned"); -} - - -/// Called by personality handler during phase 2 to get LSDA for current frame. -_LIBUNWIND_EXPORT uintptr_t -_Unwind_GetLanguageSpecificData(struct _Unwind_Context *context) { - _Unwind_FunctionContext_t ufc = (_Unwind_FunctionContext_t) context; - _LIBUNWIND_TRACE_API("_Unwind_GetLanguageSpecificData(context=%p) " - "=> 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)", - 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)" - , 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", context, - ufc->resumeLocation + 1); - return ufc->resumeLocation + 1; -} - - -/// Called by personality handler during phase 2 to get instruction pointer. -/// ipBefore is a boolean that says if IP is already adjusted to be the call -/// site address. Normally IP is the return address. -_LIBUNWIND_EXPORT uintptr_t _Unwind_GetIPInfo(struct _Unwind_Context *context, - int *ipBefore) { - _Unwind_FunctionContext_t ufc = (_Unwind_FunctionContext_t) context; - *ipBefore = 0; - _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)", - context, new_value); - _Unwind_FunctionContext_t ufc = (_Unwind_FunctionContext_t) context; - ufc->resumeLocation = new_value - 1; -} - - -/// Called by personality handler during phase 2 to find the start of the -/// function. -_LIBUNWIND_EXPORT uintptr_t -_Unwind_GetRegionStart(struct _Unwind_Context *context) { - // Not supported or needed for sjlj based unwinding - (void)context; - _LIBUNWIND_TRACE_API("_Unwind_GetRegionStart(context=%p)", context); - return 0; -} - - -/// Called by personality handler during phase 2 if a foreign exception -/// is caught. -_LIBUNWIND_EXPORT void -_Unwind_DeleteException(struct _Unwind_Exception *exception_object) { - _LIBUNWIND_TRACE_API("_Unwind_DeleteException(ex_obj=%p)", - exception_object); - if (exception_object->exception_cleanup != NULL) - (*exception_object->exception_cleanup)(_URC_FOREIGN_EXCEPTION_CAUGHT, - exception_object); -} - - - -/// Called by personality handler during phase 2 to get base address for data -/// relative encodings. -_LIBUNWIND_EXPORT uintptr_t -_Unwind_GetDataRelBase(struct _Unwind_Context *context) { - // Not supported or needed for sjlj based unwinding - (void)context; - _LIBUNWIND_TRACE_API("_Unwind_GetDataRelBase(context=%p)", context); - _LIBUNWIND_ABORT("_Unwind_GetDataRelBase() not implemented"); -} - - -/// Called by personality handler during phase 2 to get base address for text -/// relative encodings. -_LIBUNWIND_EXPORT uintptr_t -_Unwind_GetTextRelBase(struct _Unwind_Context *context) { - // Not supported or needed for sjlj based unwinding - (void)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)", context); - if (context != NULL) { - _Unwind_FunctionContext_t ufc = (_Unwind_FunctionContext_t) context; - // Setjmp/longjmp based exceptions don't have a true CFA. - // Instead, the SP in the jmpbuf is the closest approximation. - return (uintptr_t) ufc->jbuf[2]; - } - return 0; -} - -#endif // defined(_LIBUNWIND_BUILD_SJLJ_APIS) diff --git a/chromium/buildtools/third_party/libunwind/trunk/src/UnwindCursor.hpp b/chromium/buildtools/third_party/libunwind/trunk/src/UnwindCursor.hpp deleted file mode 100644 index ab2f542dbdf..00000000000 --- a/chromium/buildtools/third_party/libunwind/trunk/src/UnwindCursor.hpp +++ /dev/null @@ -1,1374 +0,0 @@ -//===------------------------- UnwindCursor.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. -// -// -// C++ interface to lower levels of libunwind -//===----------------------------------------------------------------------===// - -#ifndef __UNWINDCURSOR_HPP__ -#define __UNWINDCURSOR_HPP__ - -#include <algorithm> -#include <stdint.h> -#include <stdio.h> -#include <stdlib.h> -#include <unwind.h> - -#ifdef __APPLE__ - #include <mach-o/dyld.h> -#endif - -#include "config.h" - -#include "AddressSpace.hpp" -#include "CompactUnwinder.hpp" -#include "config.h" -#include "DwarfInstructions.hpp" -#include "EHHeaderParser.hpp" -#include "libunwind.h" -#include "Registers.hpp" -#include "RWMutex.hpp" -#include "Unwind-EHABI.h" - -namespace libunwind { - -#if defined(_LIBUNWIND_SUPPORT_DWARF_UNWIND) -/// Cache of recently found FDEs. -template <typename A> -class _LIBUNWIND_HIDDEN DwarfFDECache { - typedef typename A::pint_t pint_t; -public: - static pint_t findFDE(pint_t mh, pint_t pc); - static void add(pint_t mh, pint_t ip_start, pint_t ip_end, pint_t fde); - static void removeAllIn(pint_t mh); - static void iterateCacheEntries(void (*func)(unw_word_t ip_start, - unw_word_t ip_end, - unw_word_t fde, unw_word_t mh)); - -private: - - struct entry { - pint_t mh; - pint_t ip_start; - pint_t ip_end; - pint_t fde; - }; - - // These fields are all static to avoid needing an initializer. - // There is only one instance of this class per process. - static RWMutex _lock; -#ifdef __APPLE__ - static void dyldUnloadHook(const struct mach_header *mh, intptr_t slide); - static bool _registeredForDyldUnloads; -#endif - // Can't use std::vector<> here because this code is below libc++. - static entry *_buffer; - static entry *_bufferUsed; - static entry *_bufferEnd; - static entry _initialBuffer[64]; -}; - -template <typename A> -typename DwarfFDECache<A>::entry * -DwarfFDECache<A>::_buffer = _initialBuffer; - -template <typename A> -typename DwarfFDECache<A>::entry * -DwarfFDECache<A>::_bufferUsed = _initialBuffer; - -template <typename A> -typename DwarfFDECache<A>::entry * -DwarfFDECache<A>::_bufferEnd = &_initialBuffer[64]; - -template <typename A> -typename DwarfFDECache<A>::entry DwarfFDECache<A>::_initialBuffer[64]; - -template <typename A> -RWMutex DwarfFDECache<A>::_lock; - -#ifdef __APPLE__ -template <typename A> -bool DwarfFDECache<A>::_registeredForDyldUnloads = false; -#endif - -template <typename A> -typename A::pint_t DwarfFDECache<A>::findFDE(pint_t mh, pint_t pc) { - pint_t result = 0; - _LIBUNWIND_LOG_IF_FALSE(_lock.lock_shared()); - for (entry *p = _buffer; p < _bufferUsed; ++p) { - if ((mh == p->mh) || (mh == 0)) { - if ((p->ip_start <= pc) && (pc < p->ip_end)) { - result = p->fde; - break; - } - } - } - _LIBUNWIND_LOG_IF_FALSE(_lock.unlock_shared()); - return result; -} - -template <typename A> -void DwarfFDECache<A>::add(pint_t mh, pint_t ip_start, pint_t ip_end, - pint_t fde) { -#if !defined(_LIBUNWIND_NO_HEAP) - _LIBUNWIND_LOG_IF_FALSE(_lock.lock()); - if (_bufferUsed >= _bufferEnd) { - size_t oldSize = (size_t)(_bufferEnd - _buffer); - size_t newSize = oldSize * 4; - // Can't use operator new (we are below it). - entry *newBuffer = (entry *)malloc(newSize * sizeof(entry)); - memcpy(newBuffer, _buffer, oldSize * sizeof(entry)); - if (_buffer != _initialBuffer) - free(_buffer); - _buffer = newBuffer; - _bufferUsed = &newBuffer[oldSize]; - _bufferEnd = &newBuffer[newSize]; - } - _bufferUsed->mh = mh; - _bufferUsed->ip_start = ip_start; - _bufferUsed->ip_end = ip_end; - _bufferUsed->fde = fde; - ++_bufferUsed; -#ifdef __APPLE__ - if (!_registeredForDyldUnloads) { - _dyld_register_func_for_remove_image(&dyldUnloadHook); - _registeredForDyldUnloads = true; - } -#endif - _LIBUNWIND_LOG_IF_FALSE(_lock.unlock()); -#endif -} - -template <typename A> -void DwarfFDECache<A>::removeAllIn(pint_t mh) { - _LIBUNWIND_LOG_IF_FALSE(_lock.lock()); - entry *d = _buffer; - for (const entry *s = _buffer; s < _bufferUsed; ++s) { - if (s->mh != mh) { - if (d != s) - *d = *s; - ++d; - } - } - _bufferUsed = d; - _LIBUNWIND_LOG_IF_FALSE(_lock.unlock()); -} - -#ifdef __APPLE__ -template <typename A> -void DwarfFDECache<A>::dyldUnloadHook(const struct mach_header *mh, intptr_t ) { - removeAllIn((pint_t) mh); -} -#endif - -template <typename A> -void DwarfFDECache<A>::iterateCacheEntries(void (*func)( - unw_word_t ip_start, unw_word_t ip_end, unw_word_t fde, unw_word_t mh)) { - _LIBUNWIND_LOG_IF_FALSE(_lock.lock()); - for (entry *p = _buffer; p < _bufferUsed; ++p) { - (*func)(p->ip_start, p->ip_end, p->fde, p->mh); - } - _LIBUNWIND_LOG_IF_FALSE(_lock.unlock()); -} -#endif // defined(_LIBUNWIND_SUPPORT_DWARF_UNWIND) - - -#define arrayoffsetof(type, index, field) ((size_t)(&((type *)0)[index].field)) - -#if defined(_LIBUNWIND_SUPPORT_COMPACT_UNWIND) -template <typename A> class UnwindSectionHeader { -public: - UnwindSectionHeader(A &addressSpace, typename A::pint_t addr) - : _addressSpace(addressSpace), _addr(addr) {} - - uint32_t version() const { - return _addressSpace.get32(_addr + - offsetof(unwind_info_section_header, version)); - } - uint32_t commonEncodingsArraySectionOffset() const { - return _addressSpace.get32(_addr + - offsetof(unwind_info_section_header, - commonEncodingsArraySectionOffset)); - } - uint32_t commonEncodingsArrayCount() const { - return _addressSpace.get32(_addr + offsetof(unwind_info_section_header, - commonEncodingsArrayCount)); - } - uint32_t personalityArraySectionOffset() const { - return _addressSpace.get32(_addr + offsetof(unwind_info_section_header, - personalityArraySectionOffset)); - } - uint32_t personalityArrayCount() const { - return _addressSpace.get32( - _addr + offsetof(unwind_info_section_header, personalityArrayCount)); - } - uint32_t indexSectionOffset() const { - return _addressSpace.get32( - _addr + offsetof(unwind_info_section_header, indexSectionOffset)); - } - uint32_t indexCount() const { - return _addressSpace.get32( - _addr + offsetof(unwind_info_section_header, indexCount)); - } - -private: - A &_addressSpace; - typename A::pint_t _addr; -}; - -template <typename A> class UnwindSectionIndexArray { -public: - UnwindSectionIndexArray(A &addressSpace, typename A::pint_t addr) - : _addressSpace(addressSpace), _addr(addr) {} - - uint32_t functionOffset(uint32_t index) const { - return _addressSpace.get32( - _addr + arrayoffsetof(unwind_info_section_header_index_entry, index, - functionOffset)); - } - uint32_t secondLevelPagesSectionOffset(uint32_t index) const { - return _addressSpace.get32( - _addr + arrayoffsetof(unwind_info_section_header_index_entry, index, - secondLevelPagesSectionOffset)); - } - uint32_t lsdaIndexArraySectionOffset(uint32_t index) const { - return _addressSpace.get32( - _addr + arrayoffsetof(unwind_info_section_header_index_entry, index, - lsdaIndexArraySectionOffset)); - } - -private: - A &_addressSpace; - typename A::pint_t _addr; -}; - -template <typename A> class UnwindSectionRegularPageHeader { -public: - UnwindSectionRegularPageHeader(A &addressSpace, typename A::pint_t addr) - : _addressSpace(addressSpace), _addr(addr) {} - - uint32_t kind() const { - return _addressSpace.get32( - _addr + offsetof(unwind_info_regular_second_level_page_header, kind)); - } - uint16_t entryPageOffset() const { - return _addressSpace.get16( - _addr + offsetof(unwind_info_regular_second_level_page_header, - entryPageOffset)); - } - uint16_t entryCount() const { - return _addressSpace.get16( - _addr + - offsetof(unwind_info_regular_second_level_page_header, entryCount)); - } - -private: - A &_addressSpace; - typename A::pint_t _addr; -}; - -template <typename A> class UnwindSectionRegularArray { -public: - UnwindSectionRegularArray(A &addressSpace, typename A::pint_t addr) - : _addressSpace(addressSpace), _addr(addr) {} - - uint32_t functionOffset(uint32_t index) const { - return _addressSpace.get32( - _addr + arrayoffsetof(unwind_info_regular_second_level_entry, index, - functionOffset)); - } - uint32_t encoding(uint32_t index) const { - return _addressSpace.get32( - _addr + - arrayoffsetof(unwind_info_regular_second_level_entry, index, encoding)); - } - -private: - A &_addressSpace; - typename A::pint_t _addr; -}; - -template <typename A> class UnwindSectionCompressedPageHeader { -public: - UnwindSectionCompressedPageHeader(A &addressSpace, typename A::pint_t addr) - : _addressSpace(addressSpace), _addr(addr) {} - - uint32_t kind() const { - return _addressSpace.get32( - _addr + - offsetof(unwind_info_compressed_second_level_page_header, kind)); - } - uint16_t entryPageOffset() const { - return _addressSpace.get16( - _addr + offsetof(unwind_info_compressed_second_level_page_header, - entryPageOffset)); - } - uint16_t entryCount() const { - return _addressSpace.get16( - _addr + - offsetof(unwind_info_compressed_second_level_page_header, entryCount)); - } - uint16_t encodingsPageOffset() const { - return _addressSpace.get16( - _addr + offsetof(unwind_info_compressed_second_level_page_header, - encodingsPageOffset)); - } - uint16_t encodingsCount() const { - return _addressSpace.get16( - _addr + offsetof(unwind_info_compressed_second_level_page_header, - encodingsCount)); - } - -private: - A &_addressSpace; - typename A::pint_t _addr; -}; - -template <typename A> class UnwindSectionCompressedArray { -public: - UnwindSectionCompressedArray(A &addressSpace, typename A::pint_t addr) - : _addressSpace(addressSpace), _addr(addr) {} - - uint32_t functionOffset(uint32_t index) const { - return UNWIND_INFO_COMPRESSED_ENTRY_FUNC_OFFSET( - _addressSpace.get32(_addr + index * sizeof(uint32_t))); - } - uint16_t encodingIndex(uint32_t index) const { - return UNWIND_INFO_COMPRESSED_ENTRY_ENCODING_INDEX( - _addressSpace.get32(_addr + index * sizeof(uint32_t))); - } - -private: - A &_addressSpace; - typename A::pint_t _addr; -}; - -template <typename A> class UnwindSectionLsdaArray { -public: - UnwindSectionLsdaArray(A &addressSpace, typename A::pint_t addr) - : _addressSpace(addressSpace), _addr(addr) {} - - uint32_t functionOffset(uint32_t index) const { - return _addressSpace.get32( - _addr + arrayoffsetof(unwind_info_section_header_lsda_index_entry, - index, functionOffset)); - } - uint32_t lsdaOffset(uint32_t index) const { - return _addressSpace.get32( - _addr + arrayoffsetof(unwind_info_section_header_lsda_index_entry, - index, lsdaOffset)); - } - -private: - A &_addressSpace; - typename A::pint_t _addr; -}; -#endif // defined(_LIBUNWIND_SUPPORT_COMPACT_UNWIND) - -class _LIBUNWIND_HIDDEN AbstractUnwindCursor { -public: - // 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> -class UnwindCursor : public AbstractUnwindCursor{ - typedef typename A::pint_t pint_t; -public: - UnwindCursor(unw_context_t *context, A &as); - UnwindCursor(A &as, void *threadArg); - virtual ~UnwindCursor() {} - virtual bool validReg(int); - virtual unw_word_t getReg(int); - virtual void setReg(int, unw_word_t); - virtual bool validFloatReg(int); - virtual unw_fpreg_t getFloatReg(int); - virtual void setFloatReg(int, unw_fpreg_t); - virtual int step(); - virtual void getInfo(unw_proc_info_t *); - virtual void jumpto(); - virtual bool isSignalFrame(); - virtual bool getFunctionName(char *buf, size_t len, unw_word_t *off); - virtual void setInfoBasedOnIPRegister(bool isReturnAddress = false); - virtual const char *getRegisterName(int num); -#ifdef __arm__ - virtual void saveVFPAsX(); -#endif - -private: - -#if defined(_LIBUNWIND_ARM_EHABI) - bool getInfoFromEHABISection(pint_t pc, const UnwindInfoSections §s); - - int stepWithEHABI() { - size_t len = 0; - size_t off = 0; - // FIXME: Calling decode_eht_entry() here is violating the libunwind - // abstraction layer. - const uint32_t *ehtp = - decode_eht_entry(reinterpret_cast<const uint32_t *>(_info.unwind_info), - &off, &len); - if (_Unwind_VRS_Interpret((_Unwind_Context *)this, ehtp, off, len) != - _URC_CONTINUE_UNWIND) - return UNW_STEP_END; - return UNW_STEP_SUCCESS; - } -#endif - -#if defined(_LIBUNWIND_SUPPORT_DWARF_UNWIND) - bool getInfoFromDwarfSection(pint_t pc, const UnwindInfoSections §s, - uint32_t fdeSectionOffsetHint=0); - int stepWithDwarfFDE() { - return DwarfInstructions<A, R>::stepWithDwarf(_addressSpace, - (pint_t)this->getReg(UNW_REG_IP), - (pint_t)_info.unwind_info, - _registers); - } -#endif - -#if defined(_LIBUNWIND_SUPPORT_COMPACT_UNWIND) - bool getInfoFromCompactEncodingSection(pint_t pc, - const UnwindInfoSections §s); - int stepWithCompactEncoding() { - #if defined(_LIBUNWIND_SUPPORT_DWARF_UNWIND) - if ( compactSaysUseDwarf() ) - return stepWithDwarfFDE(); - #endif - R dummy; - return stepWithCompactEncoding(dummy); - } - -#if defined(_LIBUNWIND_TARGET_X86_64) - int stepWithCompactEncoding(Registers_x86_64 &) { - return CompactUnwinder_x86_64<A>::stepWithCompactEncoding( - _info.format, _info.start_ip, _addressSpace, _registers); - } -#endif - -#if defined(_LIBUNWIND_TARGET_I386) - int stepWithCompactEncoding(Registers_x86 &) { - return CompactUnwinder_x86<A>::stepWithCompactEncoding( - _info.format, (uint32_t)_info.start_ip, _addressSpace, _registers); - } -#endif - -#if defined(_LIBUNWIND_TARGET_PPC) - int stepWithCompactEncoding(Registers_ppc &) { - return UNW_EINVAL; - } -#endif - -#if defined(_LIBUNWIND_TARGET_AARCH64) - int stepWithCompactEncoding(Registers_arm64 &) { - return CompactUnwinder_arm64<A>::stepWithCompactEncoding( - _info.format, _info.start_ip, _addressSpace, _registers); - } -#endif - - bool compactSaysUseDwarf(uint32_t *offset=NULL) const { - R dummy; - return compactSaysUseDwarf(dummy, offset); - } - -#if defined(_LIBUNWIND_TARGET_X86_64) - bool compactSaysUseDwarf(Registers_x86_64 &, uint32_t *offset) const { - if ((_info.format & UNWIND_X86_64_MODE_MASK) == UNWIND_X86_64_MODE_DWARF) { - if (offset) - *offset = (_info.format & UNWIND_X86_64_DWARF_SECTION_OFFSET); - return true; - } - return false; - } -#endif - -#if defined(_LIBUNWIND_TARGET_I386) - bool compactSaysUseDwarf(Registers_x86 &, uint32_t *offset) const { - if ((_info.format & UNWIND_X86_MODE_MASK) == UNWIND_X86_MODE_DWARF) { - if (offset) - *offset = (_info.format & UNWIND_X86_DWARF_SECTION_OFFSET); - return true; - } - return false; - } -#endif - -#if defined(_LIBUNWIND_TARGET_PPC) - bool compactSaysUseDwarf(Registers_ppc &, uint32_t *) const { - return true; - } -#endif - -#if defined(_LIBUNWIND_TARGET_AARCH64) - bool compactSaysUseDwarf(Registers_arm64 &, uint32_t *offset) const { - if ((_info.format & UNWIND_ARM64_MODE_MASK) == UNWIND_ARM64_MODE_DWARF) { - if (offset) - *offset = (_info.format & UNWIND_ARM64_DWARF_SECTION_OFFSET); - return true; - } - return false; - } -#endif -#endif // defined(_LIBUNWIND_SUPPORT_COMPACT_UNWIND) - -#if defined(_LIBUNWIND_SUPPORT_DWARF_UNWIND) - compact_unwind_encoding_t dwarfEncoding() const { - R dummy; - return dwarfEncoding(dummy); - } - -#if defined(_LIBUNWIND_TARGET_X86_64) - compact_unwind_encoding_t dwarfEncoding(Registers_x86_64 &) const { - return UNWIND_X86_64_MODE_DWARF; - } -#endif - -#if defined(_LIBUNWIND_TARGET_I386) - compact_unwind_encoding_t dwarfEncoding(Registers_x86 &) const { - return UNWIND_X86_MODE_DWARF; - } -#endif - -#if defined(_LIBUNWIND_TARGET_PPC) - compact_unwind_encoding_t dwarfEncoding(Registers_ppc &) const { - return 0; - } -#endif - -#if defined(_LIBUNWIND_TARGET_AARCH64) - compact_unwind_encoding_t dwarfEncoding(Registers_arm64 &) const { - return UNWIND_ARM64_MODE_DWARF; - } -#endif - -#if defined (_LIBUNWIND_TARGET_OR1K) - compact_unwind_encoding_t dwarfEncoding(Registers_or1k &) const { - return 0; - } -#endif -#endif // defined(_LIBUNWIND_SUPPORT_DWARF_UNWIND) - - - A &_addressSpace; - R _registers; - unw_proc_info_t _info; - bool _unwindInfoMissing; - bool _isSignalFrame; -}; - - -template <typename A, typename R> -UnwindCursor<A, R>::UnwindCursor(unw_context_t *context, A &as) - : _addressSpace(as), _registers(context), _unwindInfoMissing(false), - _isSignalFrame(false) { - static_assert((check_fit<UnwindCursor<A, R>, unw_cursor_t>::does_fit), - "UnwindCursor<> does not fit in unw_cursor_t"); - memset(&_info, 0, sizeof(_info)); -} - -template <typename A, typename R> -UnwindCursor<A, R>::UnwindCursor(A &as, void *) - : _addressSpace(as), _unwindInfoMissing(false), _isSignalFrame(false) { - memset(&_info, 0, sizeof(_info)); - // FIXME - // fill in _registers from thread arg -} - - -template <typename A, typename R> -bool UnwindCursor<A, R>::validReg(int regNum) { - return _registers.validRegister(regNum); -} - -template <typename A, typename R> -unw_word_t UnwindCursor<A, R>::getReg(int regNum) { - return _registers.getRegister(regNum); -} - -template <typename A, typename R> -void UnwindCursor<A, R>::setReg(int regNum, unw_word_t value) { - _registers.setRegister(regNum, (typename A::pint_t)value); -} - -template <typename A, typename R> -bool UnwindCursor<A, R>::validFloatReg(int regNum) { - return _registers.validFloatRegister(regNum); -} - -template <typename A, typename R> -unw_fpreg_t UnwindCursor<A, R>::getFloatReg(int regNum) { - return _registers.getFloatRegister(regNum); -} - -template <typename A, typename R> -void UnwindCursor<A, R>::setFloatReg(int regNum, unw_fpreg_t value) { - _registers.setFloatRegister(regNum, value); -} - -template <typename A, typename R> void UnwindCursor<A, R>::jumpto() { - _registers.jumpto(); -} - -#ifdef __arm__ -template <typename A, typename R> void UnwindCursor<A, R>::saveVFPAsX() { - _registers.saveVFPAsX(); -} -#endif - -template <typename A, typename R> -const char *UnwindCursor<A, R>::getRegisterName(int regNum) { - return _registers.getRegisterName(regNum); -} - -template <typename A, typename R> bool UnwindCursor<A, R>::isSignalFrame() { - return _isSignalFrame; -} - -#if defined(_LIBUNWIND_ARM_EHABI) -struct EHABIIndexEntry { - uint32_t functionOffset; - uint32_t data; -}; - -template<typename A> -struct EHABISectionIterator { - typedef EHABISectionIterator _Self; - - typedef std::random_access_iterator_tag iterator_category; - typedef typename A::pint_t value_type; - typedef typename A::pint_t* pointer; - typedef typename A::pint_t& reference; - typedef size_t size_type; - typedef size_t difference_type; - - static _Self begin(A& addressSpace, const UnwindInfoSections& sects) { - return _Self(addressSpace, sects, 0); - } - static _Self end(A& addressSpace, const UnwindInfoSections& sects) { - return _Self(addressSpace, sects, - sects.arm_section_length / sizeof(EHABIIndexEntry)); - } - - EHABISectionIterator(A& addressSpace, const UnwindInfoSections& sects, size_t i) - : _i(i), _addressSpace(&addressSpace), _sects(§s) {} - - _Self& operator++() { ++_i; return *this; } - _Self& operator+=(size_t a) { _i += a; return *this; } - _Self& operator--() { assert(_i > 0); --_i; return *this; } - _Self& operator-=(size_t a) { assert(_i >= a); _i -= a; return *this; } - - _Self operator+(size_t a) { _Self out = *this; out._i += a; return out; } - _Self operator-(size_t a) { assert(_i >= a); _Self out = *this; out._i -= a; return out; } - - size_t operator-(const _Self& other) { return _i - other._i; } - - bool operator==(const _Self& other) const { - assert(_addressSpace == other._addressSpace); - assert(_sects == other._sects); - return _i == other._i; - } - - typename A::pint_t operator*() const { return functionAddress(); } - - typename A::pint_t functionAddress() const { - typename A::pint_t indexAddr = _sects->arm_section + arrayoffsetof( - EHABIIndexEntry, _i, functionOffset); - return indexAddr + signExtendPrel31(_addressSpace->get32(indexAddr)); - } - - typename A::pint_t dataAddress() { - typename A::pint_t indexAddr = _sects->arm_section + arrayoffsetof( - EHABIIndexEntry, _i, data); - return indexAddr; - } - - private: - size_t _i; - A* _addressSpace; - const UnwindInfoSections* _sects; -}; - -template <typename A, typename R> -bool UnwindCursor<A, R>::getInfoFromEHABISection( - pint_t pc, - const UnwindInfoSections §s) { - EHABISectionIterator<A> begin = - EHABISectionIterator<A>::begin(_addressSpace, sects); - EHABISectionIterator<A> end = - EHABISectionIterator<A>::end(_addressSpace, sects); - if (begin == end) - return false; - - EHABISectionIterator<A> itNextPC = std::upper_bound(begin, end, pc); - if (itNextPC == begin) - return false; - EHABISectionIterator<A> itThisPC = itNextPC - 1; - - pint_t thisPC = itThisPC.functionAddress(); - // If an exception is thrown from a function, corresponding to the last entry - // in the table, we don't really know the function extent and have to choose a - // value for nextPC. Choosing max() will allow the range check during trace to - // succeed. - pint_t nextPC = (itNextPC == end) ? std::numeric_limits<pint_t>::max() - : itNextPC.functionAddress(); - pint_t indexDataAddr = itThisPC.dataAddress(); - - if (indexDataAddr == 0) - return false; - - uint32_t indexData = _addressSpace.get32(indexDataAddr); - if (indexData == UNW_EXIDX_CANTUNWIND) - return false; - - // If the high bit is set, the exception handling table entry is inline inside - // the index table entry on the second word (aka |indexDataAddr|). Otherwise, - // the table points at an offset in the exception handling table (section 5 EHABI). - pint_t exceptionTableAddr; - uint32_t exceptionTableData; - bool isSingleWordEHT; - if (indexData & 0x80000000) { - exceptionTableAddr = indexDataAddr; - // TODO(ajwong): Should this data be 0? - exceptionTableData = indexData; - isSingleWordEHT = true; - } else { - exceptionTableAddr = indexDataAddr + signExtendPrel31(indexData); - exceptionTableData = _addressSpace.get32(exceptionTableAddr); - isSingleWordEHT = false; - } - - // Now we know the 3 things: - // exceptionTableAddr -- exception handler table entry. - // exceptionTableData -- the data inside the first word of the eht entry. - // isSingleWordEHT -- whether the entry is in the index. - unw_word_t personalityRoutine = 0xbadf00d; - bool scope32 = false; - uintptr_t lsda; - - // If the high bit in the exception handling table entry is set, the entry is - // in compact form (section 6.3 EHABI). - if (exceptionTableData & 0x80000000) { - // Grab the index of the personality routine from the compact form. - uint32_t choice = (exceptionTableData & 0x0f000000) >> 24; - uint32_t extraWords = 0; - switch (choice) { - case 0: - personalityRoutine = (unw_word_t) &__aeabi_unwind_cpp_pr0; - extraWords = 0; - scope32 = false; - lsda = isSingleWordEHT ? 0 : (exceptionTableAddr + 4); - break; - case 1: - personalityRoutine = (unw_word_t) &__aeabi_unwind_cpp_pr1; - extraWords = (exceptionTableData & 0x00ff0000) >> 16; - scope32 = false; - lsda = exceptionTableAddr + (extraWords + 1) * 4; - break; - case 2: - personalityRoutine = (unw_word_t) &__aeabi_unwind_cpp_pr2; - extraWords = (exceptionTableData & 0x00ff0000) >> 16; - scope32 = true; - lsda = exceptionTableAddr + (extraWords + 1) * 4; - break; - default: - _LIBUNWIND_ABORT("unknown personality routine"); - return false; - } - - if (isSingleWordEHT) { - if (extraWords != 0) { - _LIBUNWIND_ABORT("index inlined table detected but pr function " - "requires extra words"); - return false; - } - } - } else { - pint_t personalityAddr = - exceptionTableAddr + signExtendPrel31(exceptionTableData); - personalityRoutine = personalityAddr; - - // ARM EHABI # 6.2, # 9.2 - // - // +---- ehtp - // v - // +--------------------------------------+ - // | +--------+--------+--------+-------+ | - // | |0| prel31 to personalityRoutine | | - // | +--------+--------+--------+-------+ | - // | | N | unwind opcodes | | <-- UnwindData - // | +--------+--------+--------+-------+ | - // | | Word 2 unwind opcodes | | - // | +--------+--------+--------+-------+ | - // | ... | - // | +--------+--------+--------+-------+ | - // | | Word N unwind opcodes | | - // | +--------+--------+--------+-------+ | - // | | LSDA | | <-- lsda - // | | ... | | - // | +--------+--------+--------+-------+ | - // +--------------------------------------+ - - uint32_t *UnwindData = reinterpret_cast<uint32_t*>(exceptionTableAddr) + 1; - uint32_t FirstDataWord = *UnwindData; - size_t N = ((FirstDataWord >> 24) & 0xff); - size_t NDataWords = N + 1; - lsda = reinterpret_cast<uintptr_t>(UnwindData + NDataWords); - } - - _info.start_ip = thisPC; - _info.end_ip = nextPC; - _info.handler = personalityRoutine; - _info.unwind_info = exceptionTableAddr; - _info.lsda = lsda; - // flags is pr_cache.additional. See EHABI #7.2 for definition of bit 0. - _info.flags = isSingleWordEHT ? 1 : 0 | scope32 ? 0x2 : 0; // Use enum? - - return true; -} -#endif - -#if defined(_LIBUNWIND_SUPPORT_DWARF_UNWIND) -template <typename A, typename R> -bool UnwindCursor<A, R>::getInfoFromDwarfSection(pint_t pc, - const UnwindInfoSections §s, - uint32_t fdeSectionOffsetHint) { - typename CFI_Parser<A>::FDE_Info fdeInfo; - typename CFI_Parser<A>::CIE_Info cieInfo; - bool foundFDE = false; - bool foundInCache = false; - // If compact encoding table gave offset into dwarf section, go directly there - if (fdeSectionOffsetHint != 0) { - foundFDE = CFI_Parser<A>::findFDE(_addressSpace, pc, sects.dwarf_section, - (uint32_t)sects.dwarf_section_length, - sects.dwarf_section + fdeSectionOffsetHint, - &fdeInfo, &cieInfo); - } -#if defined(_LIBUNWIND_SUPPORT_DWARF_INDEX) - if (!foundFDE && (sects.dwarf_index_section != 0)) { - foundFDE = EHHeaderParser<A>::findFDE( - _addressSpace, pc, sects.dwarf_index_section, - (uint32_t)sects.dwarf_index_section_length, &fdeInfo, &cieInfo); - } -#endif - if (!foundFDE) { - // otherwise, search cache of previously found FDEs. - pint_t cachedFDE = DwarfFDECache<A>::findFDE(sects.dso_base, pc); - if (cachedFDE != 0) { - foundFDE = - CFI_Parser<A>::findFDE(_addressSpace, pc, sects.dwarf_section, - (uint32_t)sects.dwarf_section_length, - cachedFDE, &fdeInfo, &cieInfo); - foundInCache = foundFDE; - } - } - if (!foundFDE) { - // Still not found, do full scan of __eh_frame section. - foundFDE = CFI_Parser<A>::findFDE(_addressSpace, pc, sects.dwarf_section, - (uint32_t)sects.dwarf_section_length, 0, - &fdeInfo, &cieInfo); - } - if (foundFDE) { - typename CFI_Parser<A>::PrologInfo prolog; - if (CFI_Parser<A>::parseFDEInstructions(_addressSpace, fdeInfo, cieInfo, pc, - &prolog)) { - // Save off parsed FDE info - _info.start_ip = fdeInfo.pcStart; - _info.end_ip = fdeInfo.pcEnd; - _info.lsda = fdeInfo.lsda; - _info.handler = cieInfo.personality; - _info.gp = prolog.spExtraArgSize; - _info.flags = 0; - _info.format = dwarfEncoding(); - _info.unwind_info = fdeInfo.fdeStart; - _info.unwind_info_size = (uint32_t)fdeInfo.fdeLength; - _info.extra = (unw_word_t) sects.dso_base; - - // Add to cache (to make next lookup faster) if we had no hint - // and there was no index. - if (!foundInCache && (fdeSectionOffsetHint == 0)) { - #if defined(_LIBUNWIND_SUPPORT_DWARF_INDEX) - if (sects.dwarf_index_section == 0) - #endif - DwarfFDECache<A>::add(sects.dso_base, fdeInfo.pcStart, fdeInfo.pcEnd, - fdeInfo.fdeStart); - } - return true; - } - } - //_LIBUNWIND_DEBUG_LOG("can't find/use FDE for pc=0x%llX", (uint64_t)pc); - return false; -} -#endif // defined(_LIBUNWIND_SUPPORT_DWARF_UNWIND) - - -#if defined(_LIBUNWIND_SUPPORT_COMPACT_UNWIND) -template <typename A, typename R> -bool UnwindCursor<A, R>::getInfoFromCompactEncodingSection(pint_t pc, - const UnwindInfoSections §s) { - const bool log = false; - if (log) - fprintf(stderr, "getInfoFromCompactEncodingSection(pc=0x%llX, mh=0x%llX)\n", - (uint64_t)pc, (uint64_t)sects.dso_base); - - const UnwindSectionHeader<A> sectionHeader(_addressSpace, - sects.compact_unwind_section); - if (sectionHeader.version() != UNWIND_SECTION_VERSION) - return false; - - // do a binary search of top level index to find page with unwind info - pint_t targetFunctionOffset = pc - sects.dso_base; - const UnwindSectionIndexArray<A> topIndex(_addressSpace, - sects.compact_unwind_section - + sectionHeader.indexSectionOffset()); - uint32_t low = 0; - uint32_t high = sectionHeader.indexCount(); - uint32_t last = high - 1; - while (low < high) { - uint32_t mid = (low + high) / 2; - //if ( log ) fprintf(stderr, "\tmid=%d, low=%d, high=%d, *mid=0x%08X\n", - //mid, low, high, topIndex.functionOffset(mid)); - if (topIndex.functionOffset(mid) <= targetFunctionOffset) { - if ((mid == last) || - (topIndex.functionOffset(mid + 1) > targetFunctionOffset)) { - low = mid; - break; - } else { - low = mid + 1; - } - } else { - high = mid; - } - } - const uint32_t firstLevelFunctionOffset = topIndex.functionOffset(low); - const uint32_t firstLevelNextPageFunctionOffset = - topIndex.functionOffset(low + 1); - const pint_t secondLevelAddr = - sects.compact_unwind_section + topIndex.secondLevelPagesSectionOffset(low); - const pint_t lsdaArrayStartAddr = - sects.compact_unwind_section + topIndex.lsdaIndexArraySectionOffset(low); - const pint_t lsdaArrayEndAddr = - sects.compact_unwind_section + topIndex.lsdaIndexArraySectionOffset(low+1); - if (log) - fprintf(stderr, "\tfirst level search for result index=%d " - "to secondLevelAddr=0x%llX\n", - low, (uint64_t) secondLevelAddr); - // do a binary search of second level page index - uint32_t encoding = 0; - pint_t funcStart = 0; - pint_t funcEnd = 0; - pint_t lsda = 0; - pint_t personality = 0; - uint32_t pageKind = _addressSpace.get32(secondLevelAddr); - if (pageKind == UNWIND_SECOND_LEVEL_REGULAR) { - // regular page - UnwindSectionRegularPageHeader<A> pageHeader(_addressSpace, - secondLevelAddr); - UnwindSectionRegularArray<A> pageIndex( - _addressSpace, secondLevelAddr + pageHeader.entryPageOffset()); - // binary search looks for entry with e where index[e].offset <= pc < - // index[e+1].offset - if (log) - fprintf(stderr, "\tbinary search for targetFunctionOffset=0x%08llX in " - "regular page starting at secondLevelAddr=0x%llX\n", - (uint64_t) targetFunctionOffset, (uint64_t) secondLevelAddr); - low = 0; - high = pageHeader.entryCount(); - while (low < high) { - uint32_t mid = (low + high) / 2; - if (pageIndex.functionOffset(mid) <= targetFunctionOffset) { - if (mid == (uint32_t)(pageHeader.entryCount() - 1)) { - // at end of table - low = mid; - funcEnd = firstLevelNextPageFunctionOffset + sects.dso_base; - break; - } else if (pageIndex.functionOffset(mid + 1) > targetFunctionOffset) { - // next is too big, so we found it - low = mid; - funcEnd = pageIndex.functionOffset(low + 1) + sects.dso_base; - break; - } else { - low = mid + 1; - } - } else { - high = mid; - } - } - encoding = pageIndex.encoding(low); - funcStart = pageIndex.functionOffset(low) + sects.dso_base; - if (pc < funcStart) { - if (log) - fprintf( - stderr, - "\tpc not in table, pc=0x%llX, funcStart=0x%llX, funcEnd=0x%llX\n", - (uint64_t) pc, (uint64_t) funcStart, (uint64_t) funcEnd); - return false; - } - if (pc > funcEnd) { - if (log) - fprintf( - stderr, - "\tpc not in table, pc=0x%llX, funcStart=0x%llX, funcEnd=0x%llX\n", - (uint64_t) pc, (uint64_t) funcStart, (uint64_t) funcEnd); - return false; - } - } else if (pageKind == UNWIND_SECOND_LEVEL_COMPRESSED) { - // compressed page - UnwindSectionCompressedPageHeader<A> pageHeader(_addressSpace, - secondLevelAddr); - UnwindSectionCompressedArray<A> pageIndex( - _addressSpace, secondLevelAddr + pageHeader.entryPageOffset()); - const uint32_t targetFunctionPageOffset = - (uint32_t)(targetFunctionOffset - firstLevelFunctionOffset); - // binary search looks for entry with e where index[e].offset <= pc < - // index[e+1].offset - if (log) - fprintf(stderr, "\tbinary search of compressed page starting at " - "secondLevelAddr=0x%llX\n", - (uint64_t) secondLevelAddr); - low = 0; - last = pageHeader.entryCount() - 1; - high = pageHeader.entryCount(); - while (low < high) { - uint32_t mid = (low + high) / 2; - if (pageIndex.functionOffset(mid) <= targetFunctionPageOffset) { - if ((mid == last) || - (pageIndex.functionOffset(mid + 1) > targetFunctionPageOffset)) { - low = mid; - break; - } else { - low = mid + 1; - } - } else { - high = mid; - } - } - funcStart = pageIndex.functionOffset(low) + firstLevelFunctionOffset - + sects.dso_base; - if (low < last) - funcEnd = - pageIndex.functionOffset(low + 1) + firstLevelFunctionOffset - + sects.dso_base; - else - funcEnd = firstLevelNextPageFunctionOffset + sects.dso_base; - if (pc < funcStart) { - _LIBUNWIND_DEBUG_LOG("malformed __unwind_info, pc=0x%llX not in second " - "level compressed unwind table. funcStart=0x%llX", - (uint64_t) pc, (uint64_t) funcStart); - return false; - } - if (pc > funcEnd) { - _LIBUNWIND_DEBUG_LOG("malformed __unwind_info, pc=0x%llX not in second " - "level compressed unwind table. funcEnd=0x%llX", - (uint64_t) pc, (uint64_t) funcEnd); - return false; - } - uint16_t encodingIndex = pageIndex.encodingIndex(low); - if (encodingIndex < sectionHeader.commonEncodingsArrayCount()) { - // encoding is in common table in section header - encoding = _addressSpace.get32( - sects.compact_unwind_section + - sectionHeader.commonEncodingsArraySectionOffset() + - encodingIndex * sizeof(uint32_t)); - } else { - // encoding is in page specific table - uint16_t pageEncodingIndex = - encodingIndex - (uint16_t)sectionHeader.commonEncodingsArrayCount(); - encoding = _addressSpace.get32(secondLevelAddr + - pageHeader.encodingsPageOffset() + - pageEncodingIndex * sizeof(uint32_t)); - } - } else { - _LIBUNWIND_DEBUG_LOG("malformed __unwind_info at 0x%0llX bad second " - "level page", - (uint64_t) sects.compact_unwind_section); - return false; - } - - // look up LSDA, if encoding says function has one - if (encoding & UNWIND_HAS_LSDA) { - UnwindSectionLsdaArray<A> lsdaIndex(_addressSpace, lsdaArrayStartAddr); - uint32_t funcStartOffset = (uint32_t)(funcStart - sects.dso_base); - low = 0; - high = (uint32_t)(lsdaArrayEndAddr - lsdaArrayStartAddr) / - sizeof(unwind_info_section_header_lsda_index_entry); - // binary search looks for entry with exact match for functionOffset - if (log) - fprintf(stderr, - "\tbinary search of lsda table for targetFunctionOffset=0x%08X\n", - funcStartOffset); - while (low < high) { - uint32_t mid = (low + high) / 2; - if (lsdaIndex.functionOffset(mid) == funcStartOffset) { - lsda = lsdaIndex.lsdaOffset(mid) + sects.dso_base; - break; - } else if (lsdaIndex.functionOffset(mid) < funcStartOffset) { - low = mid + 1; - } else { - high = mid; - } - } - if (lsda == 0) { - _LIBUNWIND_DEBUG_LOG("found encoding 0x%08X with HAS_LSDA bit set for " - "pc=0x%0llX, but lsda table has no entry", - encoding, (uint64_t) pc); - return false; - } - } - - // extact personality routine, if encoding says function has one - uint32_t personalityIndex = (encoding & UNWIND_PERSONALITY_MASK) >> - (__builtin_ctz(UNWIND_PERSONALITY_MASK)); - if (personalityIndex != 0) { - --personalityIndex; // change 1-based to zero-based index - if (personalityIndex > sectionHeader.personalityArrayCount()) { - _LIBUNWIND_DEBUG_LOG("found encoding 0x%08X with personality index %d, " - "but personality table has only %d entires", - encoding, personalityIndex, - sectionHeader.personalityArrayCount()); - return false; - } - int32_t personalityDelta = (int32_t)_addressSpace.get32( - sects.compact_unwind_section + - sectionHeader.personalityArraySectionOffset() + - personalityIndex * sizeof(uint32_t)); - pint_t personalityPointer = sects.dso_base + (pint_t)personalityDelta; - personality = _addressSpace.getP(personalityPointer); - if (log) - fprintf(stderr, "getInfoFromCompactEncodingSection(pc=0x%llX), " - "personalityDelta=0x%08X, personality=0x%08llX\n", - (uint64_t) pc, personalityDelta, (uint64_t) personality); - } - - if (log) - fprintf(stderr, "getInfoFromCompactEncodingSection(pc=0x%llX), " - "encoding=0x%08X, lsda=0x%08llX for funcStart=0x%llX\n", - (uint64_t) pc, encoding, (uint64_t) lsda, (uint64_t) funcStart); - _info.start_ip = funcStart; - _info.end_ip = funcEnd; - _info.lsda = lsda; - _info.handler = personality; - _info.gp = 0; - _info.flags = 0; - _info.format = encoding; - _info.unwind_info = 0; - _info.unwind_info_size = 0; - _info.extra = sects.dso_base; - return true; -} -#endif // defined(_LIBUNWIND_SUPPORT_COMPACT_UNWIND) - - -template <typename A, typename R> -void UnwindCursor<A, R>::setInfoBasedOnIPRegister(bool isReturnAddress) { - pint_t pc = (pint_t)this->getReg(UNW_REG_IP); -#if defined(_LIBUNWIND_ARM_EHABI) - // Remove the thumb bit so the IP represents the actual instruction address. - // This matches the behaviour of _Unwind_GetIP on arm. - pc &= (pint_t)~0x1; -#endif - - // If the last line of a function is a "throw" the compiler sometimes - // emits no instructions after the call to __cxa_throw. This means - // the return address is actually the start of the next function. - // To disambiguate this, back up the pc when we know it is a return - // address. - if (isReturnAddress) - --pc; - - // Ask address space object to find unwind sections for this pc. - UnwindInfoSections sects; - if (_addressSpace.findUnwindSections(pc, sects)) { -#if defined(_LIBUNWIND_SUPPORT_COMPACT_UNWIND) - // If there is a compact unwind encoding table, look there first. - if (sects.compact_unwind_section != 0) { - if (this->getInfoFromCompactEncodingSection(pc, sects)) { - #if defined(_LIBUNWIND_SUPPORT_DWARF_UNWIND) - // Found info in table, done unless encoding says to use dwarf. - uint32_t dwarfOffset; - if ((sects.dwarf_section != 0) && compactSaysUseDwarf(&dwarfOffset)) { - if (this->getInfoFromDwarfSection(pc, sects, dwarfOffset)) { - // found info in dwarf, done - return; - } - } - #endif - // If unwind table has entry, but entry says there is no unwind info, - // record that we have no unwind info. - if (_info.format == 0) - _unwindInfoMissing = true; - return; - } - } -#endif // defined(_LIBUNWIND_SUPPORT_COMPACT_UNWIND) - -#if defined(_LIBUNWIND_SUPPORT_DWARF_UNWIND) - // If there is dwarf unwind info, look there next. - if (sects.dwarf_section != 0) { - if (this->getInfoFromDwarfSection(pc, sects)) { - // found info in dwarf, done - return; - } - } -#endif - -#if defined(_LIBUNWIND_ARM_EHABI) - // If there is ARM EHABI unwind info, look there next. - if (sects.arm_section != 0 && this->getInfoFromEHABISection(pc, sects)) - return; -#endif - } - -#if defined(_LIBUNWIND_SUPPORT_DWARF_UNWIND) - // There is no static unwind info for this pc. Look to see if an FDE was - // dynamically registered for it. - pint_t cachedFDE = DwarfFDECache<A>::findFDE(0, pc); - if (cachedFDE != 0) { - CFI_Parser<LocalAddressSpace>::FDE_Info fdeInfo; - CFI_Parser<LocalAddressSpace>::CIE_Info cieInfo; - const char *msg = CFI_Parser<A>::decodeFDE(_addressSpace, - cachedFDE, &fdeInfo, &cieInfo); - if (msg == NULL) { - typename CFI_Parser<A>::PrologInfo prolog; - if (CFI_Parser<A>::parseFDEInstructions(_addressSpace, fdeInfo, cieInfo, - pc, &prolog)) { - // save off parsed FDE info - _info.start_ip = fdeInfo.pcStart; - _info.end_ip = fdeInfo.pcEnd; - _info.lsda = fdeInfo.lsda; - _info.handler = cieInfo.personality; - _info.gp = prolog.spExtraArgSize; - // Some frameless functions need SP - // altered when resuming in function. - _info.flags = 0; - _info.format = dwarfEncoding(); - _info.unwind_info = fdeInfo.fdeStart; - _info.unwind_info_size = (uint32_t)fdeInfo.fdeLength; - _info.extra = 0; - return; - } - } - } - - // Lastly, ask AddressSpace object about platform specific ways to locate - // other FDEs. - pint_t fde; - if (_addressSpace.findOtherFDE(pc, fde)) { - CFI_Parser<LocalAddressSpace>::FDE_Info fdeInfo; - CFI_Parser<LocalAddressSpace>::CIE_Info cieInfo; - if (!CFI_Parser<A>::decodeFDE(_addressSpace, fde, &fdeInfo, &cieInfo)) { - // Double check this FDE is for a function that includes the pc. - if ((fdeInfo.pcStart <= pc) && (pc < fdeInfo.pcEnd)) { - typename CFI_Parser<A>::PrologInfo prolog; - if (CFI_Parser<A>::parseFDEInstructions(_addressSpace, fdeInfo, - cieInfo, pc, &prolog)) { - // save off parsed FDE info - _info.start_ip = fdeInfo.pcStart; - _info.end_ip = fdeInfo.pcEnd; - _info.lsda = fdeInfo.lsda; - _info.handler = cieInfo.personality; - _info.gp = prolog.spExtraArgSize; - _info.flags = 0; - _info.format = dwarfEncoding(); - _info.unwind_info = fdeInfo.fdeStart; - _info.unwind_info_size = (uint32_t)fdeInfo.fdeLength; - _info.extra = 0; - return; - } - } - } - } -#endif // #if defined(_LIBUNWIND_SUPPORT_DWARF_UNWIND) - - // no unwind info, flag that we can't reliably unwind - _unwindInfoMissing = true; -} - -template <typename A, typename R> -int UnwindCursor<A, R>::step() { - // Bottom of stack is defined is when unwind info cannot be found. - if (_unwindInfoMissing) - return UNW_STEP_END; - - // Use unwinding info to modify register set as if function returned. - int result; -#if defined(_LIBUNWIND_SUPPORT_COMPACT_UNWIND) - result = this->stepWithCompactEncoding(); -#elif defined(_LIBUNWIND_SUPPORT_DWARF_UNWIND) - result = this->stepWithDwarfFDE(); -#elif defined(_LIBUNWIND_ARM_EHABI) - result = this->stepWithEHABI(); -#else - #error Need _LIBUNWIND_SUPPORT_COMPACT_UNWIND or \ - _LIBUNWIND_SUPPORT_DWARF_UNWIND or \ - _LIBUNWIND_ARM_EHABI -#endif - - // update info based on new PC - if (result == UNW_STEP_SUCCESS) { - this->setInfoBasedOnIPRegister(true); - if (_unwindInfoMissing) - return UNW_STEP_END; - if (_info.gp) - setReg(UNW_REG_SP, getReg(UNW_REG_SP) + _info.gp); - } - - return result; -} - -template <typename A, typename R> -void UnwindCursor<A, R>::getInfo(unw_proc_info_t *info) { - *info = _info; -} - -template <typename A, typename R> -bool UnwindCursor<A, R>::getFunctionName(char *buf, size_t bufLen, - unw_word_t *offset) { - return _addressSpace.findFunctionName((pint_t)this->getReg(UNW_REG_IP), - buf, bufLen, offset); -} - -} // namespace libunwind - -#endif // __UNWINDCURSOR_HPP__ diff --git a/chromium/buildtools/third_party/libunwind/trunk/src/UnwindLevel1-gcc-ext.c b/chromium/buildtools/third_party/libunwind/trunk/src/UnwindLevel1-gcc-ext.c deleted file mode 100644 index 10619ba431d..00000000000 --- a/chromium/buildtools/third_party/libunwind/trunk/src/UnwindLevel1-gcc-ext.c +++ /dev/null @@ -1,316 +0,0 @@ -//===--------------------- UnwindLevel1-gcc-ext.c -------------------------===// -// -// 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. -// -// -// Implements gcc extensions to the C++ ABI Exception Handling Level 1. -// -//===----------------------------------------------------------------------===// - -#include <inttypes.h> -#include <stdbool.h> -#include <stdint.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> - -#include "config.h" -#include "libunwind_ext.h" -#include "libunwind.h" -#include "Unwind-EHABI.h" -#include "unwind.h" - -#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 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", - (void *)exception_object, - (long)exception_object->private_1); -#endif - -#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); -#else - // If this is non-forced and a stopping place was found, then this is a - // re-throw. - // Call _Unwind_RaiseException() as if this was a new exception - if (exception_object->private_1 == 0) { - return _Unwind_RaiseException(exception_object); - // Will return if there is no catch clause, so that __cxa_rethrow can call - // std::terminate(). - } - - // Call through to _Unwind_Resume() which distiguishes between forced and - // regular exceptions. - _Unwind_Resume(exception_object); - _LIBUNWIND_ABORT("_Unwind_Resume_or_Rethrow() called _Unwind_RaiseException()" - " which unexpectedly returned"); -#endif -} - - -/// Called by personality handler during phase 2 to get base address for data -/// relative encodings. -_LIBUNWIND_EXPORT uintptr_t -_Unwind_GetDataRelBase(struct _Unwind_Context *context) { - (void)context; - _LIBUNWIND_TRACE_API("_Unwind_GetDataRelBase(context=%p)", (void *)context); - _LIBUNWIND_ABORT("_Unwind_GetDataRelBase() not implemented"); -} - - -/// Called by personality handler during phase 2 to get base address for text -/// relative encodings. -_LIBUNWIND_EXPORT uintptr_t -_Unwind_GetTextRelBase(struct _Unwind_Context *context) { - (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)", pc); - // This is slow, but works. - // We create an unwind cursor then alter the IP to be pc - unw_cursor_t cursor; - unw_context_t uc; - unw_proc_info_t info; - unw_getcontext(&uc); - unw_init_local(&cursor, &uc); - unw_set_reg(&cursor, UNW_REG_IP, (unw_word_t)(long) pc); - if (unw_get_proc_info(&cursor, &info) == UNW_ESUCCESS) - return (void *)(long) info.start_ip; - else - 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 -_Unwind_Backtrace(_Unwind_Trace_Fn callback, void *ref) { - unw_cursor_t cursor; - unw_context_t uc; - unw_getcontext(&uc); - unw_init_local(&cursor, &uc); - - _LIBUNWIND_TRACE_API("_Unwind_Backtrace(callback=%p)", - (void *)(uintptr_t)callback); - -#if defined(_LIBUNWIND_ARM_EHABI) - // Create a mock exception object for force unwinding. - _Unwind_Exception ex; - memset(&ex, '\0', sizeof(ex)); - ex.exception_class = 0x434C4E47554E5700; // CLNGUNW\0 -#endif - - // walk each frame - while (true) { - _Unwind_Reason_Code result; - -#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", - _URC_END_OF_STACK); - return _URC_END_OF_STACK; - } -#else - // Get the information for this frame. - unw_proc_info_t frameInfo; - if (unw_get_proc_info(&cursor, &frameInfo) != UNW_ESUCCESS) { - return _URC_END_OF_STACK; - } - - // Update the pr_cache in the mock exception object. - const uint32_t* unwindInfo = (uint32_t *) frameInfo.unwind_info; - ex.pr_cache.fnstart = frameInfo.start_ip; - ex.pr_cache.ehtp = (_Unwind_EHT_Header *) unwindInfo; - ex.pr_cache.additional= frameInfo.flags; - - struct _Unwind_Context *context = (struct _Unwind_Context *)&cursor; - // Get and call the personality function to unwind the frame. - __personality_routine handler = (__personality_routine) frameInfo.handler; - if (handler == NULL) { - return _URC_END_OF_STACK; - } - if (handler(_US_VIRTUAL_UNWIND_FRAME | _US_FORCE_UNWIND, &ex, context) != - _URC_CONTINUE_UNWIND) { - return _URC_END_OF_STACK; - } -#endif // defined(_LIBUNWIND_ARM_EHABI) - - // debugging - if (_LIBUNWIND_TRACING_UNWINDING) { - char functionName[512]; - unw_proc_info_t frame; - unw_word_t offset; - unw_get_proc_name(&cursor, functionName, 512, &offset); - unw_get_proc_info(&cursor, &frame); - _LIBUNWIND_TRACE_UNWINDING( - " _backtrace: start_ip=0x%" PRIxPTR ", func=%s, lsda=0x%" PRIxPTR ", context=%p", - frame.start_ip, functionName, 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", result); - return result; - } - } -} - - -/// 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. - // We create an unwind cursor then alter the IP to be pc - unw_cursor_t cursor; - unw_context_t uc; - unw_proc_info_t info; - unw_getcontext(&uc); - unw_init_local(&cursor, &uc); - unw_set_reg(&cursor, UNW_REG_IP, (unw_word_t)(long) pc); - unw_get_proc_info(&cursor, &info); - 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", pc, - (void *)(long) info.unwind_info); - return (void *)(long) info.unwind_info; -} - -/// Returns the CFA (call frame area, or stack pointer at start of function) -/// for the current context. -_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%" PRIxPTR, - (void *)context, result); - return (uintptr_t)result; -} - - -/// Called by personality handler during phase 2 to get instruction pointer. -/// ipBefore is a boolean that says if IP is already adjusted to be the call -/// 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)", (void *)context); - *ipBefore = 0; - return _Unwind_GetIP(context); -} - -#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)", fde); - _unw_add_dynamic_fde((unw_word_t)(uintptr_t) fde); -} - - -/// Called by programs with dynamic code generators that want -/// to unregister a dynamically generated 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)", fde); - _unw_remove_dynamic_fde((unw_word_t)(uintptr_t) fde); -} - - -// The following register/deregister functions are gcc extensions. -// They have existed on Mac OS X, but have never worked because Mac OS X -// before 10.6 used keymgr to track known FDEs, but these functions -// never got updated to use keymgr. -// For now, we implement these as do-nothing functions to keep any existing -// applications working. We also add the not in 10.6 symbol so that nwe -// application won't be able to use them. - -#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)", - 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)", fde, ob); - // do nothing, this function never worked in Mac OS X -} - -_LIBUNWIND_EXPORT void __register_frame_info_table_bases(const void *fde, - void *ob, void *tb, - void *db) { - (void)fde; - (void)ob; - (void)tb; - (void)db; - _LIBUNWIND_TRACE_API("__register_frame_info_table_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_table(const void *fde, void *ob) { - (void)fde; - (void)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)", 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)", 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)", fde); - // do nothing, this function never worked in Mac OS X - return NULL; -} -#endif // defined(_LIBUNWIND_SUPPORT_FRAME_APIS) - -#endif // defined(_LIBUNWIND_SUPPORT_DWARF_UNWIND) - -#endif // defined(_LIBUNWIND_BUILD_ZERO_COST_APIS) diff --git a/chromium/buildtools/third_party/libunwind/trunk/src/UnwindLevel1.c b/chromium/buildtools/third_party/libunwind/trunk/src/UnwindLevel1.c deleted file mode 100644 index 518577b1d50..00000000000 --- a/chromium/buildtools/third_party/libunwind/trunk/src/UnwindLevel1.c +++ /dev/null @@ -1,506 +0,0 @@ -//===------------------------- UnwindLevel1.c -----------------------------===// -// -// 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. -// -// -// Implements C++ ABI Exception Handling Level 1 as documented at: -// http://mentorembedded.github.io/cxx-abi/abi-eh.html -// using libunwind -// -//===----------------------------------------------------------------------===// - -// ARM EHABI does not specify _Unwind_{Get,Set}{GR,IP}(). Thus, we are -// defining inline functions to delegate the function calls to -// _Unwind_VRS_{Get,Set}(). However, some applications might declare the -// function protetype directly (instead of including <unwind.h>), thus we need -// to export these functions from libunwind.so as well. -#define _LIBUNWIND_UNWIND_LEVEL1_EXTERNAL_LINKAGE 1 - -#include <inttypes.h> -#include <stdint.h> -#include <stdbool.h> -#include <stdlib.h> -#include <stdio.h> -#include <string.h> - -#include "libunwind.h" -#include "unwind.h" -#include "config.h" - -#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) { - unw_init_local(cursor, uc); - - // Walk each frame looking for a place to stop. - bool handlerNotFound = true; - while (handlerNotFound) { - // 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", - (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", - (void *)exception_object); - return _URC_FATAL_PHASE1_ERROR; - } - - // See if frame has code to run (has personality routine). - unw_proc_info_t frameInfo; - 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", - (void *)exception_object); - return _URC_FATAL_PHASE1_ERROR; - } - - // When tracing, print state information. - if (_LIBUNWIND_TRACING_UNWINDING) { - char functionBuf[512]; - const char *functionName = functionBuf; - unw_word_t offset; - if ((unw_get_proc_name(cursor, functionBuf, sizeof(functionBuf), - &offset) != UNW_ESUCCESS) || - (frameInfo.start_ip + offset > frameInfo.end_ip)) - functionName = ".anonymous."; - unw_word_t pc; - unw_get_reg(cursor, UNW_REG_IP, &pc); - _LIBUNWIND_TRACE_UNWINDING( - "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); - } - - // If there is a personality routine, ask it if it will want to stop at - // this frame. - if (frameInfo.handler != 0) { - __personality_routine p = - (__personality_routine)(uintptr_t)(frameInfo.handler); - _LIBUNWIND_TRACE_UNWINDING( - "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, - exception_object, (struct _Unwind_Context *)(cursor)); - switch (personalityResult) { - case _URC_HANDLER_FOUND: - // found a catch clause or locals that need destructing in this frame - // stop search and remember stack pointer at the frame - handlerNotFound = false; - 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", - (void *)exception_object); - return _URC_NO_REASON; - - case _URC_CONTINUE_UNWIND: - _LIBUNWIND_TRACE_UNWINDING( - "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", - (void *)exception_object); - return _URC_FATAL_PHASE1_ERROR; - } - } - } - return _URC_NO_REASON; -} - - -static _Unwind_Reason_Code -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)", - (void *)exception_object); - - // Walk each frame until we reach where search phase said to stop. - while (true) { - - // 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", - (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", - (void *)exception_object); - return _URC_FATAL_PHASE2_ERROR; - } - - // Get info about this frame. - unw_word_t sp; - unw_proc_info_t frameInfo; - 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", - (void *)exception_object); - return _URC_FATAL_PHASE2_ERROR; - } - - // When tracing, print state information. - if (_LIBUNWIND_TRACING_UNWINDING) { - char functionBuf[512]; - const char *functionName = functionBuf; - unw_word_t offset; - if ((unw_get_proc_name(cursor, 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%" 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)(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. - action = (_Unwind_Action)(_UA_CLEANUP_PHASE | _UA_HANDLER_FRAME); - } - _Unwind_Reason_Code personalityResult = - (*p)(1, action, exception_object->exception_class, exception_object, - (struct _Unwind_Context *)(cursor)); - switch (personalityResult) { - case _URC_CONTINUE_UNWIND: - // Continue unwinding - _LIBUNWIND_TRACE_UNWINDING( - "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... - _LIBUNWIND_ABORT("during phase1 personality function said it would " - "stop here, but now in phase2 it did not stop here"); - } - break; - case _URC_INSTALL_CONTEXT: - _LIBUNWIND_TRACE_UNWINDING( - "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(). - if (_LIBUNWIND_TRACING_UNWINDING) { - unw_word_t pc; - 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%" PRIxPTR - ", sp=0x%" PRIxPTR, - (void *)exception_object, pc, sp); - } - unw_resume(cursor); - // unw_resume() only returns if there was an error. - return _URC_FATAL_PHASE2_ERROR; - default: - // Personality routine returned an unknown result code. - _LIBUNWIND_DEBUG_LOG("personality function returned unknown result %d", - personalityResult); - return _URC_FATAL_PHASE2_ERROR; - } - } - } - - // Clean up phase did not resume at the frame that the search phase - // said it would... - return _URC_FATAL_PHASE2_ERROR; -} - -static _Unwind_Reason_Code -unwind_phase2_forced(unw_context_t *uc, unw_cursor_t *cursor, - _Unwind_Exception *exception_object, - _Unwind_Stop_Fn stop, void *stop_parameter) { - unw_init_local(cursor, uc); - - // Walk each frame until we reach where search phase said to stop - while (unw_step(cursor) > 0) { - - // Update info about this frame. - 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", - (void *)exception_object); - return _URC_FATAL_PHASE2_ERROR; - } - - // When tracing, print state information. - if (_LIBUNWIND_TRACING_UNWINDING) { - char functionBuf[512]; - const char *functionName = functionBuf; - unw_word_t offset; - if ((unw_get_proc_name(cursor, 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%" PRIxPTR - ", func=%s, lsda=0x%" PRIxPTR ", personality=0x%" PRIxPTR, - (void *)exception_object, frameInfo.start_ip, functionName, - frameInfo.lsda, frameInfo.handler); - } - - // Call stop function at each frame. - _Unwind_Action action = - (_Unwind_Action)(_UA_FORCE_UNWIND | _UA_CLEANUP_PHASE); - _Unwind_Reason_Code stopResult = - (*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", - (void *)exception_object, stopResult); - if (stopResult != _URC_NO_REASON) { - _LIBUNWIND_TRACE_UNWINDING( - "unwind_phase2_forced(ex_ojb=%p): stopped by stop function", - (void *)exception_object); - return _URC_FATAL_PHASE2_ERROR; - } - - // If there is a personality routine, tell it we are unwinding. - if (frameInfo.handler != 0) { - __personality_routine p = - (__personality_routine)(long)(frameInfo.handler); - _LIBUNWIND_TRACE_UNWINDING( - "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, - (struct _Unwind_Context *)(cursor)); - switch (personalityResult) { - case _URC_CONTINUE_UNWIND: - _LIBUNWIND_TRACE_UNWINDING("unwind_phase2_forced(ex_ojb=%p): " - "personality returned " - "_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", - (void *)exception_object); - // We may get control back if landing pad calls _Unwind_Resume(). - unw_resume(cursor); - break; - default: - // Personality routine returned an unknown result code. - _LIBUNWIND_TRACE_UNWINDING("unwind_phase2_forced(ex_ojb=%p): " - "personality returned %d, " - "_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", - (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, - (struct _Unwind_Context *)(cursor), stop_parameter); - - // Clean up phase did not resume at the frame that the search phase said it - // would. - return _URC_FATAL_PHASE2_ERROR; -} - - -/// 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)", - (void *)exception_object); - unw_context_t uc; - unw_cursor_t cursor; - unw_getcontext(&uc); - - // Mark that this is a non-forced unwind, so _Unwind_Resume() - // can do the right thing. - exception_object->private_1 = 0; - exception_object->private_2 = 0; - - // phase 1: the search phase - _Unwind_Reason_Code phase1 = unwind_phase1(&uc, &cursor, exception_object); - if (phase1 != _URC_NO_REASON) - return phase1; - - // phase 2: the clean up phase - return unwind_phase2(&uc, &cursor, exception_object); -} - - - -/// When _Unwind_RaiseException() is in phase2, it hands control -/// to the personality function at each frame. The personality -/// may force a jump to a landing pad in that function, the landing -/// pad code may then call _Unwind_Resume() to continue with the -/// unwinding. Note: the call to _Unwind_Resume() is from compiler -/// geneated user code. All other _Unwind_* routines are called -/// by the C++ runtime __cxa_* routines. -/// -/// Note: re-throwing an exception (as opposed to continuing the unwind) -/// is implemented by having the code call __cxa_rethrow() which -/// in turn calls _Unwind_Resume_or_Rethrow(). -_LIBUNWIND_EXPORT void -_Unwind_Resume(_Unwind_Exception *exception_object) { - _LIBUNWIND_TRACE_API("_Unwind_Resume(ex_obj=%p)", (void *)exception_object); - unw_context_t uc; - unw_cursor_t cursor; - unw_getcontext(&uc); - - if (exception_object->private_1 != 0) - unwind_phase2_forced(&uc, &cursor, exception_object, - (_Unwind_Stop_Fn) exception_object->private_1, - (void *)exception_object->private_2); - else - unwind_phase2(&uc, &cursor, exception_object); - - // Clients assume _Unwind_Resume() does not return, so all we can do is abort. - _LIBUNWIND_ABORT("_Unwind_Resume() can't return"); -} - - - -/// Not used by C++. -/// Unwinds stack, calling "stop" function at each frame. -/// Could be used to implement longjmp(). -_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)", - (void *)exception_object, (void *)(uintptr_t)stop); - unw_context_t uc; - unw_cursor_t cursor; - unw_getcontext(&uc); - - // Mark that this is a forced unwind, so _Unwind_Resume() can do - // the right thing. - exception_object->private_1 = (uintptr_t) stop; - exception_object->private_2 = (uintptr_t) stop_parameter; - - // do it - return unwind_phase2_forced(&uc, &cursor, exception_object, stop, stop_parameter); -} - - -/// Called by personality handler during phase 2 to get LSDA for current frame. -_LIBUNWIND_EXPORT uintptr_t -_Unwind_GetLanguageSpecificData(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.lsda; - _LIBUNWIND_TRACE_API( - "_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", - result); - } - return result; -} - - -/// 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, - (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)", - (void *)exception_object); - if (exception_object->exception_cleanup != NULL) - (*exception_object->exception_cleanup)(_URC_FOREIGN_EXCEPTION_CAUGHT, - exception_object); -} - -/// Called by personality handler during phase 2 to get register values. -_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%" 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" PRIxPTR - ")", - (void *)context, index, value); - unw_cursor_t *cursor = (unw_cursor_t *)context; - 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%" PRIxPTR, - (void *)context, 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 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 // !defined(_LIBUNWIND_ARM_EHABI) && !defined(__USING_SJLJ_EXCEPTIONS__) diff --git a/chromium/buildtools/third_party/libunwind/trunk/src/UnwindRegistersRestore.S b/chromium/buildtools/third_party/libunwind/trunk/src/UnwindRegistersRestore.S deleted file mode 100644 index 96106de8941..00000000000 --- a/chromium/buildtools/third_party/libunwind/trunk/src/UnwindRegistersRestore.S +++ /dev/null @@ -1,532 +0,0 @@ -//===-------------------- UnwindRegistersRestore.S ------------------------===// -// -// 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. -// -//===----------------------------------------------------------------------===// - -#include "assembly.h" - - .text - -#if !defined(__USING_SJLJ_EXCEPTIONS__) - -#if defined(__i386__) -DEFINE_LIBUNWIND_PRIVATE_FUNCTION(_ZN9libunwind13Registers_x866jumptoEv) -# -# void libunwind::Registers_x86::jumpto() -# -#if defined(_WIN32) -# On windows, the 'this' pointer is passed in ecx instead of on the stack - movl %ecx, %eax -#else -# On entry: -# + + -# +-----------------------+ -# + thread_state pointer + -# +-----------------------+ -# + return address + -# +-----------------------+ <-- SP -# + + - movl 4(%esp), %eax -#endif - # set up eax and ret on new stack location - movl 28(%eax), %edx # edx holds new stack pointer - subl $8,%edx - movl %edx, 28(%eax) - movl 0(%eax), %ebx - movl %ebx, 0(%edx) - movl 40(%eax), %ebx - movl %ebx, 4(%edx) - # we now have ret and eax pushed onto where new stack will be - # restore all registers - movl 4(%eax), %ebx - movl 8(%eax), %ecx - movl 12(%eax), %edx - movl 16(%eax), %edi - movl 20(%eax), %esi - movl 24(%eax), %ebp - movl 28(%eax), %esp - # skip ss - # skip eflags - pop %eax # eax was already pushed on new stack - ret # eip was already pushed on new stack - # skip cs - # skip ds - # skip es - # skip fs - # skip gs - -#elif defined(__x86_64__) - -DEFINE_LIBUNWIND_PRIVATE_FUNCTION(_ZN9libunwind16Registers_x86_646jumptoEv) -# -# void libunwind::Registers_x86_64::jumpto() -# -#if defined(_WIN64) -# On entry, thread_state pointer is in rcx; move it into rdi -# to share restore code below. Since this routine restores and -# overwrites all registers, we can use the same registers for -# pointers and temporaries as on unix even though win64 normally -# mustn't clobber some of them. - movq %rcx, %rdi -#else -# On entry, thread_state pointer is in rdi -#endif - - movq 56(%rdi), %rax # rax holds new stack pointer - subq $16, %rax - movq %rax, 56(%rdi) - movq 32(%rdi), %rbx # store new rdi on new stack - movq %rbx, 0(%rax) - movq 128(%rdi), %rbx # store new rip on new stack - movq %rbx, 8(%rax) - # restore all registers - movq 0(%rdi), %rax - movq 8(%rdi), %rbx - movq 16(%rdi), %rcx - movq 24(%rdi), %rdx - # restore rdi later - movq 40(%rdi), %rsi - movq 48(%rdi), %rbp - # restore rsp later - movq 64(%rdi), %r8 - movq 72(%rdi), %r9 - movq 80(%rdi), %r10 - movq 88(%rdi), %r11 - movq 96(%rdi), %r12 - movq 104(%rdi), %r13 - movq 112(%rdi), %r14 - movq 120(%rdi), %r15 - # skip rflags - # skip cs - # skip fs - # skip gs - -#if defined(_WIN64) - movdqu 176(%rdi),%xmm0 - movdqu 192(%rdi),%xmm1 - movdqu 208(%rdi),%xmm2 - movdqu 224(%rdi),%xmm3 - movdqu 240(%rdi),%xmm4 - movdqu 256(%rdi),%xmm5 - movdqu 272(%rdi),%xmm6 - movdqu 288(%rdi),%xmm7 - movdqu 304(%rdi),%xmm8 - movdqu 320(%rdi),%xmm9 - movdqu 336(%rdi),%xmm10 - movdqu 352(%rdi),%xmm11 - movdqu 368(%rdi),%xmm12 - movdqu 384(%rdi),%xmm13 - movdqu 400(%rdi),%xmm14 - movdqu 416(%rdi),%xmm15 -#endif - movq 56(%rdi), %rsp # cut back rsp to new location - pop %rdi # rdi was saved here earlier - ret # rip was saved here - - -#elif defined(__ppc__) - -DEFINE_LIBUNWIND_PRIVATE_FUNCTION(_ZN9libunwind13Registers_ppc6jumptoEv) -; -; void libunwind::Registers_ppc::jumpto() -; -; On entry: -; thread_state pointer is in r3 -; - - ; restore integral registerrs - ; skip r0 for now - ; skip r1 for now - lwz r2, 16(r3) - ; skip r3 for now - ; skip r4 for now - ; skip r5 for now - lwz r6, 32(r3) - lwz r7, 36(r3) - lwz r8, 40(r3) - lwz r9, 44(r3) - lwz r10, 48(r3) - lwz r11, 52(r3) - lwz r12, 56(r3) - lwz r13, 60(r3) - lwz r14, 64(r3) - lwz r15, 68(r3) - lwz r16, 72(r3) - lwz r17, 76(r3) - lwz r18, 80(r3) - lwz r19, 84(r3) - lwz r20, 88(r3) - lwz r21, 92(r3) - lwz r22, 96(r3) - lwz r23,100(r3) - lwz r24,104(r3) - lwz r25,108(r3) - lwz r26,112(r3) - lwz r27,116(r3) - lwz r28,120(r3) - lwz r29,124(r3) - lwz r30,128(r3) - lwz r31,132(r3) - - ; restore float registers - lfd f0, 160(r3) - lfd f1, 168(r3) - lfd f2, 176(r3) - lfd f3, 184(r3) - lfd f4, 192(r3) - lfd f5, 200(r3) - lfd f6, 208(r3) - lfd f7, 216(r3) - lfd f8, 224(r3) - lfd f9, 232(r3) - lfd f10,240(r3) - lfd f11,248(r3) - lfd f12,256(r3) - lfd f13,264(r3) - lfd f14,272(r3) - lfd f15,280(r3) - lfd f16,288(r3) - lfd f17,296(r3) - lfd f18,304(r3) - lfd f19,312(r3) - lfd f20,320(r3) - lfd f21,328(r3) - lfd f22,336(r3) - lfd f23,344(r3) - lfd f24,352(r3) - lfd f25,360(r3) - lfd f26,368(r3) - lfd f27,376(r3) - lfd f28,384(r3) - lfd f29,392(r3) - lfd f30,400(r3) - lfd f31,408(r3) - - ; restore vector registers if any are in use - lwz r5,156(r3) ; test VRsave - cmpwi r5,0 - beq Lnovec - - subi r4,r1,16 - rlwinm r4,r4,0,0,27 ; mask low 4-bits - ; r4 is now a 16-byte aligned pointer into the red zone - ; the _vectorRegisters may not be 16-byte aligned so copy via red zone temp buffer - - -#define LOAD_VECTOR_UNALIGNEDl(_index) \ - andis. r0,r5,(1<<(15-_index)) @\ - beq Ldone ## _index @\ - lwz r0, 424+_index*16(r3) @\ - stw r0, 0(r4) @\ - lwz r0, 424+_index*16+4(r3) @\ - stw r0, 4(r4) @\ - lwz r0, 424+_index*16+8(r3) @\ - stw r0, 8(r4) @\ - lwz r0, 424+_index*16+12(r3)@\ - stw r0, 12(r4) @\ - lvx v ## _index,0,r4 @\ -Ldone ## _index: - -#define LOAD_VECTOR_UNALIGNEDh(_index) \ - andi. r0,r5,(1<<(31-_index)) @\ - beq Ldone ## _index @\ - lwz r0, 424+_index*16(r3) @\ - stw r0, 0(r4) @\ - lwz r0, 424+_index*16+4(r3) @\ - stw r0, 4(r4) @\ - lwz r0, 424+_index*16+8(r3) @\ - stw r0, 8(r4) @\ - lwz r0, 424+_index*16+12(r3)@\ - stw r0, 12(r4) @\ - lvx v ## _index,0,r4 @\ - Ldone ## _index: - - - LOAD_VECTOR_UNALIGNEDl(0) - LOAD_VECTOR_UNALIGNEDl(1) - LOAD_VECTOR_UNALIGNEDl(2) - LOAD_VECTOR_UNALIGNEDl(3) - LOAD_VECTOR_UNALIGNEDl(4) - LOAD_VECTOR_UNALIGNEDl(5) - LOAD_VECTOR_UNALIGNEDl(6) - LOAD_VECTOR_UNALIGNEDl(7) - LOAD_VECTOR_UNALIGNEDl(8) - LOAD_VECTOR_UNALIGNEDl(9) - LOAD_VECTOR_UNALIGNEDl(10) - LOAD_VECTOR_UNALIGNEDl(11) - LOAD_VECTOR_UNALIGNEDl(12) - LOAD_VECTOR_UNALIGNEDl(13) - LOAD_VECTOR_UNALIGNEDl(14) - LOAD_VECTOR_UNALIGNEDl(15) - LOAD_VECTOR_UNALIGNEDh(16) - LOAD_VECTOR_UNALIGNEDh(17) - LOAD_VECTOR_UNALIGNEDh(18) - LOAD_VECTOR_UNALIGNEDh(19) - LOAD_VECTOR_UNALIGNEDh(20) - LOAD_VECTOR_UNALIGNEDh(21) - LOAD_VECTOR_UNALIGNEDh(22) - LOAD_VECTOR_UNALIGNEDh(23) - LOAD_VECTOR_UNALIGNEDh(24) - LOAD_VECTOR_UNALIGNEDh(25) - LOAD_VECTOR_UNALIGNEDh(26) - LOAD_VECTOR_UNALIGNEDh(27) - LOAD_VECTOR_UNALIGNEDh(28) - LOAD_VECTOR_UNALIGNEDh(29) - LOAD_VECTOR_UNALIGNEDh(30) - LOAD_VECTOR_UNALIGNEDh(31) - -Lnovec: - lwz r0, 136(r3) ; __cr - mtocrf 255,r0 - lwz r0, 148(r3) ; __ctr - mtctr r0 - lwz r0, 0(r3) ; __ssr0 - mtctr r0 - lwz r0, 8(r3) ; do r0 now - lwz r5,28(r3) ; do r5 now - lwz r4,24(r3) ; do r4 now - lwz r1,12(r3) ; do sp now - lwz r3,20(r3) ; do r3 last - bctr - -#elif defined(__arm64__) || defined(__aarch64__) - -// -// void libunwind::Registers_arm64::jumpto() -// -// On entry: -// thread_state pointer is in x0 -// - .p2align 2 -DEFINE_LIBUNWIND_PRIVATE_FUNCTION(_ZN9libunwind15Registers_arm646jumptoEv) - // skip restore of x0,x1 for now - ldp x2, x3, [x0, #0x010] - ldp x4, x5, [x0, #0x020] - ldp x6, x7, [x0, #0x030] - ldp x8, x9, [x0, #0x040] - ldp x10,x11, [x0, #0x050] - ldp x12,x13, [x0, #0x060] - ldp x14,x15, [x0, #0x070] - ldp x16,x17, [x0, #0x080] - ldp x18,x19, [x0, #0x090] - ldp x20,x21, [x0, #0x0A0] - ldp x22,x23, [x0, #0x0B0] - ldp x24,x25, [x0, #0x0C0] - ldp x26,x27, [x0, #0x0D0] - ldp x28,x29, [x0, #0x0E0] - ldr x30, [x0, #0x100] // restore pc into lr - ldr x1, [x0, #0x0F8] - mov sp,x1 // restore sp - - ldp d0, d1, [x0, #0x110] - ldp d2, d3, [x0, #0x120] - ldp d4, d5, [x0, #0x130] - ldp d6, d7, [x0, #0x140] - ldp d8, d9, [x0, #0x150] - ldp d10,d11, [x0, #0x160] - ldp d12,d13, [x0, #0x170] - ldp d14,d15, [x0, #0x180] - ldp d16,d17, [x0, #0x190] - ldp d18,d19, [x0, #0x1A0] - ldp d20,d21, [x0, #0x1B0] - ldp d22,d23, [x0, #0x1C0] - ldp d24,d25, [x0, #0x1D0] - ldp d26,d27, [x0, #0x1E0] - ldp d28,d29, [x0, #0x1F0] - ldr d30, [x0, #0x200] - ldr d31, [x0, #0x208] - - ldp x0, x1, [x0, #0x000] // restore x0,x1 - ret x30 // jump to pc - -#elif defined(__arm__) && !defined(__APPLE__) - -#if !defined(__ARM_ARCH_ISA_ARM) - .thumb -#endif - -@ -@ void libunwind::Registers_arm::restoreCoreAndJumpTo() -@ -@ On entry: -@ thread_state pointer is in r0 -@ - .p2align 2 -DEFINE_LIBUNWIND_PRIVATE_FUNCTION(_ZN9libunwind13Registers_arm20restoreCoreAndJumpToEv) -#if !defined(__ARM_ARCH_ISA_ARM) && __ARM_ARCH_ISA_THUMB == 1 - @ r8-r11: ldm into r1-r4, then mov to r8-r11 - adds r0, #0x20 - ldm r0!, {r1-r4} - subs r0, #0x30 - mov r8, r1 - mov r9, r2 - mov r10, r3 - mov r11, r4 - @ r12 does not need loading, it it the intra-procedure-call scratch register - ldr r2, [r0, #0x34] - ldr r3, [r0, #0x3c] - mov sp, r2 - mov lr, r3 @ restore pc into lr - ldm r0, {r0-r7} -#else - @ Use lr as base so that r0 can be restored. - mov lr, r0 - @ 32bit thumb-2 restrictions for ldm: - @ . the sp (r13) cannot be in the list - @ . the pc (r15) and lr (r14) cannot both be in the list in an LDM instruction - ldm lr, {r0-r12} - ldr sp, [lr, #52] - ldr lr, [lr, #60] @ restore pc into lr -#endif - JMP(lr) - -@ -@ static void libunwind::Registers_arm::restoreVFPWithFLDMD(unw_fpreg_t* values) -@ -@ On entry: -@ values pointer is in r0 -@ - .p2align 2 - .fpu vfpv3-d16 -DEFINE_LIBUNWIND_PRIVATE_FUNCTION(_ZN9libunwind13Registers_arm19restoreVFPWithFLDMDEPy) - @ 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 - @ only accessed if the personality routine needs these registers. Use of - @ 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. - vldmia r0, {d0-d15} - JMP(lr) - -@ -@ static void libunwind::Registers_arm::restoreVFPWithFLDMX(unw_fpreg_t* values) -@ -@ On entry: -@ values pointer is in r0 -@ - .p2align 2 - .fpu vfpv3-d16 -DEFINE_LIBUNWIND_PRIVATE_FUNCTION(_ZN9libunwind13Registers_arm19restoreVFPWithFLDMXEPy) - vldmia r0, {d0-d15} @ fldmiax is deprecated in ARMv7+ and now behaves like vldmia - JMP(lr) - -@ -@ static void libunwind::Registers_arm::restoreVFPv3(unw_fpreg_t* values) -@ -@ On entry: -@ values pointer is in r0 -@ - .p2align 2 - .fpu vfpv3 -DEFINE_LIBUNWIND_PRIVATE_FUNCTION(_ZN9libunwind13Registers_arm12restoreVFPv3EPy) - vldmia r0, {d16-d31} - JMP(lr) - -#if defined(__ARM_WMMX) - -@ -@ static void libunwind::Registers_arm::restoreiWMMX(unw_fpreg_t* values) -@ -@ On entry: -@ values pointer is in r0 -@ - .p2align 2 - .arch armv5te -DEFINE_LIBUNWIND_PRIVATE_FUNCTION(_ZN9libunwind13Registers_arm12restoreiWMMXEPy) - 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 - ldcl p1, cr3, [r0], #8 @ wldrd wR3, [r0], #8 - ldcl p1, cr4, [r0], #8 @ wldrd wR4, [r0], #8 - ldcl p1, cr5, [r0], #8 @ wldrd wR5, [r0], #8 - ldcl p1, cr6, [r0], #8 @ wldrd wR6, [r0], #8 - ldcl p1, cr7, [r0], #8 @ wldrd wR7, [r0], #8 - ldcl p1, cr8, [r0], #8 @ wldrd wR8, [r0], #8 - ldcl p1, cr9, [r0], #8 @ wldrd wR9, [r0], #8 - ldcl p1, cr10, [r0], #8 @ wldrd wR10, [r0], #8 - ldcl p1, cr11, [r0], #8 @ wldrd wR11, [r0], #8 - ldcl p1, cr12, [r0], #8 @ wldrd wR12, [r0], #8 - ldcl p1, cr13, [r0], #8 @ wldrd wR13, [r0], #8 - ldcl p1, cr14, [r0], #8 @ wldrd wR14, [r0], #8 - ldcl p1, cr15, [r0], #8 @ wldrd wR15, [r0], #8 - JMP(lr) - -@ -@ static void libunwind::Registers_arm::restoreiWMMXControl(unw_uint32_t* values) -@ -@ On entry: -@ values pointer is in r0 -@ - .p2align 2 - .arch armv5te -DEFINE_LIBUNWIND_PRIVATE_FUNCTION(_ZN9libunwind13Registers_arm19restoreiWMMXControlEPj) - 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 - ldc2 p1, cr11, [r0], #4 @ wldrw wCGR3, [r0], #4 - JMP(lr) - -#endif - -#elif defined(__or1k__) - -DEFINE_LIBUNWIND_PRIVATE_FUNCTION(_ZN9libunwind14Registers_or1k6jumptoEv) -# -# void libunwind::Registers_or1k::jumpto() -# -# On entry: -# thread_state pointer is in r3 -# - - # restore integral registerrs - l.lwz r0, 0(r3) - l.lwz r1, 4(r3) - l.lwz r2, 8(r3) - # skip r3 for now - l.lwz r4, 16(r3) - l.lwz r5, 20(r3) - l.lwz r6, 24(r3) - l.lwz r7, 28(r3) - l.lwz r8, 32(r3) - l.lwz r9, 36(r3) - l.lwz r10, 40(r3) - l.lwz r11, 44(r3) - l.lwz r12, 48(r3) - l.lwz r13, 52(r3) - l.lwz r14, 56(r3) - l.lwz r15, 60(r3) - l.lwz r16, 64(r3) - l.lwz r17, 68(r3) - l.lwz r18, 72(r3) - l.lwz r19, 76(r3) - l.lwz r20, 80(r3) - l.lwz r21, 84(r3) - l.lwz r22, 88(r3) - l.lwz r23, 92(r3) - l.lwz r24, 96(r3) - l.lwz r25,100(r3) - l.lwz r26,104(r3) - l.lwz r27,108(r3) - l.lwz r28,112(r3) - l.lwz r29,116(r3) - l.lwz r30,120(r3) - l.lwz r31,124(r3) - - # at last, restore r3 - l.lwz r3, 12(r3) - - # jump to pc - l.jr r9 - l.nop - -#endif - -#endif /* !defined(__USING_SJLJ_EXCEPTIONS__) */ - -NO_EXEC_STACK_DIRECTIVE - diff --git a/chromium/buildtools/third_party/libunwind/trunk/src/UnwindRegistersSave.S b/chromium/buildtools/third_party/libunwind/trunk/src/UnwindRegistersSave.S deleted file mode 100644 index 873a16e41a2..00000000000 --- a/chromium/buildtools/third_party/libunwind/trunk/src/UnwindRegistersSave.S +++ /dev/null @@ -1,506 +0,0 @@ -//===------------------------ UnwindRegistersSave.S -----------------------===// -// -// 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. -// -//===----------------------------------------------------------------------===// - -#include "assembly.h" - - .text - -#if !defined(__USING_SJLJ_EXCEPTIONS__) - -#if defined(__i386__) - -# -# extern int unw_getcontext(unw_context_t* thread_state) -# -# On entry: -# + + -# +-----------------------+ -# + thread_state pointer + -# +-----------------------+ -# + return address + -# +-----------------------+ <-- SP -# + + -# -DEFINE_LIBUNWIND_FUNCTION(unw_getcontext) - push %eax - movl 8(%esp), %eax - movl %ebx, 4(%eax) - movl %ecx, 8(%eax) - movl %edx, 12(%eax) - movl %edi, 16(%eax) - movl %esi, 20(%eax) - movl %ebp, 24(%eax) - movl %esp, %edx - addl $8, %edx - movl %edx, 28(%eax) # store what sp was at call site as esp - # skip ss - # skip eflags - movl 4(%esp), %edx - movl %edx, 40(%eax) # store return address as eip - # skip cs - # skip ds - # skip es - # skip fs - # skip gs - movl (%esp), %edx - movl %edx, (%eax) # store original eax - popl %eax - xorl %eax, %eax # return UNW_ESUCCESS - ret - -#elif defined(__x86_64__) - -# -# extern int unw_getcontext(unw_context_t* thread_state) -# -# On entry: -# thread_state pointer is in rdi -# -DEFINE_LIBUNWIND_FUNCTION(unw_getcontext) -#if defined(_WIN64) -#define PTR %rcx -#define TMP %rdx -#else -#define PTR %rdi -#define TMP %rsi -#endif - - movq %rax, (PTR) - movq %rbx, 8(PTR) - movq %rcx, 16(PTR) - movq %rdx, 24(PTR) - movq %rdi, 32(PTR) - movq %rsi, 40(PTR) - movq %rbp, 48(PTR) - movq %rsp, 56(PTR) - addq $8, 56(PTR) - movq %r8, 64(PTR) - movq %r9, 72(PTR) - movq %r10, 80(PTR) - movq %r11, 88(PTR) - movq %r12, 96(PTR) - movq %r13,104(PTR) - movq %r14,112(PTR) - movq %r15,120(PTR) - movq (%rsp),TMP - movq TMP,128(PTR) # store return address as rip - # skip rflags - # skip cs - # skip fs - # skip gs - -#if defined(_WIN64) - movdqu %xmm0,176(PTR) - movdqu %xmm1,192(PTR) - movdqu %xmm2,208(PTR) - movdqu %xmm3,224(PTR) - movdqu %xmm4,240(PTR) - movdqu %xmm5,256(PTR) - movdqu %xmm6,272(PTR) - movdqu %xmm7,288(PTR) - movdqu %xmm8,304(PTR) - movdqu %xmm9,320(PTR) - movdqu %xmm10,336(PTR) - movdqu %xmm11,352(PTR) - movdqu %xmm12,368(PTR) - movdqu %xmm13,384(PTR) - movdqu %xmm14,400(PTR) - movdqu %xmm15,416(PTR) -#endif - xorl %eax, %eax # return UNW_ESUCCESS - ret - -# elif defined(__mips__) - -# -# extern int unw_getcontext(unw_context_t* thread_state) -# -# Just trap for the time being. -DEFINE_LIBUNWIND_FUNCTION(unw_getcontext) - teq $0, $0 - -#elif defined(__ppc__) - -; -; extern int unw_getcontext(unw_context_t* thread_state) -; -; On entry: -; thread_state pointer is in r3 -; -DEFINE_LIBUNWIND_FUNCTION(unw_getcontext) - stw r0, 8(r3) - mflr r0 - stw r0, 0(r3) ; store lr as ssr0 - stw r1, 12(r3) - stw r2, 16(r3) - stw r3, 20(r3) - stw r4, 24(r3) - stw r5, 28(r3) - stw r6, 32(r3) - stw r7, 36(r3) - stw r8, 40(r3) - stw r9, 44(r3) - stw r10, 48(r3) - stw r11, 52(r3) - stw r12, 56(r3) - stw r13, 60(r3) - stw r14, 64(r3) - stw r15, 68(r3) - stw r16, 72(r3) - stw r17, 76(r3) - stw r18, 80(r3) - stw r19, 84(r3) - stw r20, 88(r3) - stw r21, 92(r3) - stw r22, 96(r3) - stw r23,100(r3) - stw r24,104(r3) - stw r25,108(r3) - stw r26,112(r3) - stw r27,116(r3) - stw r28,120(r3) - stw r29,124(r3) - stw r30,128(r3) - stw r31,132(r3) - - ; save VRSave register - mfspr r0,256 - stw r0,156(r3) - ; save CR registers - mfcr r0 - stw r0,136(r3) - ; save CTR register - mfctr r0 - stw r0,148(r3) - - ; save float registers - stfd f0, 160(r3) - stfd f1, 168(r3) - stfd f2, 176(r3) - stfd f3, 184(r3) - stfd f4, 192(r3) - stfd f5, 200(r3) - stfd f6, 208(r3) - stfd f7, 216(r3) - stfd f8, 224(r3) - stfd f9, 232(r3) - stfd f10,240(r3) - stfd f11,248(r3) - stfd f12,256(r3) - stfd f13,264(r3) - stfd f14,272(r3) - stfd f15,280(r3) - stfd f16,288(r3) - stfd f17,296(r3) - stfd f18,304(r3) - stfd f19,312(r3) - stfd f20,320(r3) - stfd f21,328(r3) - stfd f22,336(r3) - stfd f23,344(r3) - stfd f24,352(r3) - stfd f25,360(r3) - stfd f26,368(r3) - stfd f27,376(r3) - stfd f28,384(r3) - stfd f29,392(r3) - stfd f30,400(r3) - stfd f31,408(r3) - - - ; save vector registers - - subi r4,r1,16 - rlwinm r4,r4,0,0,27 ; mask low 4-bits - ; r4 is now a 16-byte aligned pointer into the red zone - -#define SAVE_VECTOR_UNALIGNED(_vec, _offset) \ - stvx _vec,0,r4 @\ - lwz r5, 0(r4) @\ - stw r5, _offset(r3) @\ - lwz r5, 4(r4) @\ - stw r5, _offset+4(r3) @\ - lwz r5, 8(r4) @\ - stw r5, _offset+8(r3) @\ - lwz r5, 12(r4) @\ - stw r5, _offset+12(r3) - - SAVE_VECTOR_UNALIGNED( v0, 424+0x000) - SAVE_VECTOR_UNALIGNED( v1, 424+0x010) - SAVE_VECTOR_UNALIGNED( v2, 424+0x020) - SAVE_VECTOR_UNALIGNED( v3, 424+0x030) - SAVE_VECTOR_UNALIGNED( v4, 424+0x040) - SAVE_VECTOR_UNALIGNED( v5, 424+0x050) - SAVE_VECTOR_UNALIGNED( v6, 424+0x060) - SAVE_VECTOR_UNALIGNED( v7, 424+0x070) - SAVE_VECTOR_UNALIGNED( v8, 424+0x080) - SAVE_VECTOR_UNALIGNED( v9, 424+0x090) - SAVE_VECTOR_UNALIGNED(v10, 424+0x0A0) - SAVE_VECTOR_UNALIGNED(v11, 424+0x0B0) - SAVE_VECTOR_UNALIGNED(v12, 424+0x0C0) - SAVE_VECTOR_UNALIGNED(v13, 424+0x0D0) - SAVE_VECTOR_UNALIGNED(v14, 424+0x0E0) - SAVE_VECTOR_UNALIGNED(v15, 424+0x0F0) - SAVE_VECTOR_UNALIGNED(v16, 424+0x100) - SAVE_VECTOR_UNALIGNED(v17, 424+0x110) - SAVE_VECTOR_UNALIGNED(v18, 424+0x120) - SAVE_VECTOR_UNALIGNED(v19, 424+0x130) - SAVE_VECTOR_UNALIGNED(v20, 424+0x140) - SAVE_VECTOR_UNALIGNED(v21, 424+0x150) - SAVE_VECTOR_UNALIGNED(v22, 424+0x160) - SAVE_VECTOR_UNALIGNED(v23, 424+0x170) - SAVE_VECTOR_UNALIGNED(v24, 424+0x180) - SAVE_VECTOR_UNALIGNED(v25, 424+0x190) - SAVE_VECTOR_UNALIGNED(v26, 424+0x1A0) - SAVE_VECTOR_UNALIGNED(v27, 424+0x1B0) - SAVE_VECTOR_UNALIGNED(v28, 424+0x1C0) - SAVE_VECTOR_UNALIGNED(v29, 424+0x1D0) - SAVE_VECTOR_UNALIGNED(v30, 424+0x1E0) - SAVE_VECTOR_UNALIGNED(v31, 424+0x1F0) - - li r3, 0 ; return UNW_ESUCCESS - blr - - -#elif defined(__arm64__) || defined(__aarch64__) - -// -// extern int unw_getcontext(unw_context_t* thread_state) -// -// On entry: -// thread_state pointer is in x0 -// - .p2align 2 -DEFINE_LIBUNWIND_FUNCTION(unw_getcontext) - stp x0, x1, [x0, #0x000] - stp x2, x3, [x0, #0x010] - stp x4, x5, [x0, #0x020] - stp x6, x7, [x0, #0x030] - stp x8, x9, [x0, #0x040] - stp x10,x11, [x0, #0x050] - stp x12,x13, [x0, #0x060] - stp x14,x15, [x0, #0x070] - stp x16,x17, [x0, #0x080] - stp x18,x19, [x0, #0x090] - stp x20,x21, [x0, #0x0A0] - stp x22,x23, [x0, #0x0B0] - stp x24,x25, [x0, #0x0C0] - stp x26,x27, [x0, #0x0D0] - stp x28,x29, [x0, #0x0E0] - str x30, [x0, #0x0F0] - mov x1,sp - str x1, [x0, #0x0F8] - str x30, [x0, #0x100] // store return address as pc - // skip cpsr - stp d0, d1, [x0, #0x110] - stp d2, d3, [x0, #0x120] - stp d4, d5, [x0, #0x130] - stp d6, d7, [x0, #0x140] - stp d8, d9, [x0, #0x150] - stp d10,d11, [x0, #0x160] - stp d12,d13, [x0, #0x170] - stp d14,d15, [x0, #0x180] - stp d16,d17, [x0, #0x190] - stp d18,d19, [x0, #0x1A0] - stp d20,d21, [x0, #0x1B0] - stp d22,d23, [x0, #0x1C0] - stp d24,d25, [x0, #0x1D0] - stp d26,d27, [x0, #0x1E0] - stp d28,d29, [x0, #0x1F0] - str d30, [x0, #0x200] - str d31, [x0, #0x208] - mov x0, #0 // return UNW_ESUCCESS - ret - -#elif defined(__arm__) && !defined(__APPLE__) - -#if !defined(__ARM_ARCH_ISA_ARM) - .thumb -#endif - -@ -@ extern int unw_getcontext(unw_context_t* thread_state) -@ -@ On entry: -@ thread_state pointer is in r0 -@ -@ Per EHABI #4.7 this only saves the core integer registers. -@ EHABI #7.4.5 notes that in general all VRS registers should be restored -@ however this is very hard to do for VFP registers because it is unknown -@ to the library how many registers are implemented by the architecture. -@ Instead, VFP registers are demand saved by logic external to unw_getcontext. -@ - .p2align 2 -DEFINE_LIBUNWIND_FUNCTION(unw_getcontext) -#if !defined(__ARM_ARCH_ISA_ARM) && __ARM_ARCH_ISA_THUMB == 1 - stm r0!, {r0-r7} - mov r1, r8 - mov r2, r9 - mov r3, r10 - stm r0!, {r1-r3} - mov r1, r11 - mov r2, sp - mov r3, lr - str r1, [r0, #0] @ r11 - @ r12 does not need storing, it it the intra-procedure-call scratch register - str r2, [r0, #8] @ sp - str r3, [r0, #12] @ lr - str r3, [r0, #16] @ store return address as pc - @ 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 - @ 32bit thumb-2 restrictions for stm: - @ . the sp (r13) cannot be in the list - @ . the pc (r15) cannot be in the list in an STM instruction - stm r0, {r0-r12} - str sp, [r0, #52] - str lr, [r0, #56] - str lr, [r0, #60] @ store return address as pc - mov r0, #0 @ return UNW_ESUCCESS -#endif - JMP(lr) - -@ -@ static void libunwind::Registers_arm::saveVFPWithFSTMD(unw_fpreg_t* values) -@ -@ On entry: -@ values pointer is in r0 -@ - .p2align 2 - .fpu vfpv3-d16 -DEFINE_LIBUNWIND_PRIVATE_FUNCTION(_ZN9libunwind13Registers_arm16saveVFPWithFSTMDEPy) - vstmia r0, {d0-d15} - JMP(lr) - -@ -@ static void libunwind::Registers_arm::saveVFPWithFSTMX(unw_fpreg_t* values) -@ -@ On entry: -@ values pointer is in r0 -@ - .p2align 2 - .fpu vfpv3-d16 -DEFINE_LIBUNWIND_PRIVATE_FUNCTION(_ZN9libunwind13Registers_arm16saveVFPWithFSTMXEPy) - vstmia r0, {d0-d15} @ fstmiax is deprecated in ARMv7+ and now behaves like vstmia - JMP(lr) - -@ -@ static void libunwind::Registers_arm::saveVFPv3(unw_fpreg_t* values) -@ -@ On entry: -@ values pointer is in r0 -@ - .p2align 2 - .fpu vfpv3 -DEFINE_LIBUNWIND_PRIVATE_FUNCTION(_ZN9libunwind13Registers_arm9saveVFPv3EPy) - @ 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 - @ only accessed if the personality routine needs these registers. Use of - @ 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. - vstmia r0, {d16-d31} - JMP(lr) - -#if defined(_LIBUNWIND_ARM_WMMX) - -@ -@ static void libunwind::Registers_arm::saveiWMMX(unw_fpreg_t* values) -@ -@ On entry: -@ values pointer is in r0 -@ - .p2align 2 - .arch armv5te -DEFINE_LIBUNWIND_PRIVATE_FUNCTION(_ZN9libunwind13Registers_arm9saveiWMMXEPy) - 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 - stcl p1, cr3, [r0], #8 @ wstrd wR3, [r0], #8 - stcl p1, cr4, [r0], #8 @ wstrd wR4, [r0], #8 - stcl p1, cr5, [r0], #8 @ wstrd wR5, [r0], #8 - stcl p1, cr6, [r0], #8 @ wstrd wR6, [r0], #8 - stcl p1, cr7, [r0], #8 @ wstrd wR7, [r0], #8 - stcl p1, cr8, [r0], #8 @ wstrd wR8, [r0], #8 - stcl p1, cr9, [r0], #8 @ wstrd wR9, [r0], #8 - stcl p1, cr10, [r0], #8 @ wstrd wR10, [r0], #8 - stcl p1, cr11, [r0], #8 @ wstrd wR11, [r0], #8 - stcl p1, cr12, [r0], #8 @ wstrd wR12, [r0], #8 - stcl p1, cr13, [r0], #8 @ wstrd wR13, [r0], #8 - stcl p1, cr14, [r0], #8 @ wstrd wR14, [r0], #8 - stcl p1, cr15, [r0], #8 @ wstrd wR15, [r0], #8 - JMP(lr) - -@ -@ static void libunwind::Registers_arm::saveiWMMXControl(unw_uint32_t* values) -@ -@ On entry: -@ values pointer is in r0 -@ - .p2align 2 - .arch armv5te -DEFINE_LIBUNWIND_PRIVATE_FUNCTION(_ZN9libunwind13Registers_arm16saveiWMMXControlEPj) - 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 - stc2 p1, cr11, [r0], #4 @ wstrw wCGR3, [r0], #4 - JMP(lr) - -#endif - -#elif defined(__or1k__) - -# -# extern int unw_getcontext(unw_context_t* thread_state) -# -# On entry: -# thread_state pointer is in r3 -# -DEFINE_LIBUNWIND_FUNCTION(unw_getcontext) - l.sw 0(r3), r0 - l.sw 4(r3), r1 - l.sw 8(r3), r2 - l.sw 12(r3), r3 - l.sw 16(r3), r4 - l.sw 20(r3), r5 - l.sw 24(r3), r6 - l.sw 28(r3), r7 - l.sw 32(r3), r8 - l.sw 36(r3), r9 - l.sw 40(r3), r10 - l.sw 44(r3), r11 - l.sw 48(r3), r12 - l.sw 52(r3), r13 - l.sw 56(r3), r14 - l.sw 60(r3), r15 - l.sw 64(r3), r16 - l.sw 68(r3), r17 - l.sw 72(r3), r18 - l.sw 76(r3), r19 - l.sw 80(r3), r20 - l.sw 84(r3), r21 - l.sw 88(r3), r22 - l.sw 92(r3), r23 - l.sw 96(r3), r24 - l.sw 100(r3), r25 - l.sw 104(r3), r26 - l.sw 108(r3), r27 - l.sw 112(r3), r28 - l.sw 116(r3), r29 - l.sw 120(r3), r30 - l.sw 124(r3), r31 -#endif - -#endif /* !defined(__USING_SJLJ_EXCEPTIONS__) */ - -NO_EXEC_STACK_DIRECTIVE - diff --git a/chromium/buildtools/third_party/libunwind/trunk/src/Unwind_AppleExtras.cpp b/chromium/buildtools/third_party/libunwind/trunk/src/Unwind_AppleExtras.cpp deleted file mode 100644 index 39f379c5298..00000000000 --- a/chromium/buildtools/third_party/libunwind/trunk/src/Unwind_AppleExtras.cpp +++ /dev/null @@ -1,184 +0,0 @@ -//===--------------------- Unwind_AppleExtras.cpp -------------------------===// -// -// 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. -// -// -//===----------------------------------------------------------------------===// - -#include "config.h" -#include "AddressSpace.hpp" -#include "DwarfParser.hpp" - - -// private keymgr stuff -#define KEYMGR_GCC3_DW2_OBJ_LIST 302 -extern "C" { - extern void _keymgr_set_and_unlock_processwide_ptr(int key, void *ptr); - extern void *_keymgr_get_and_lock_processwide_ptr(int key); -} - -// undocumented libgcc "struct object" -struct libgcc_object { - void *start; - void *unused1; - void *unused2; - void *fde; - unsigned long encoding; - void *fde_end; - libgcc_object *next; -}; - -// undocumented libgcc "struct km_object_info" referenced by -// KEYMGR_GCC3_DW2_OBJ_LIST -struct libgcc_object_info { - libgcc_object *seen_objects; - libgcc_object *unseen_objects; - unsigned spare[2]; -}; - - -// static linker symbols to prevent wrong two level namespace for _Unwind symbols -#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; \ - extern const char sym##_tmp31 __asm("$ld$hide$os3.1$_" #sym ); \ - __attribute__((visibility("default"))) const char sym##_tmp31 = 0; \ - extern const char sym##_tmp32 __asm("$ld$hide$os3.2$_" #sym );\ - __attribute__((visibility("default"))) const char sym##_tmp32 = 0; \ - extern const char sym##_tmp40 __asm("$ld$hide$os4.0$_" #sym ); \ - __attribute__((visibility("default"))) const char sym##_tmp40 = 0; \ - extern const char sym##_tmp41 __asm("$ld$hide$os4.1$_" #sym ); \ - __attribute__((visibility("default"))) const char sym##_tmp41 = 0; \ - extern const char sym##_tmp42 __asm("$ld$hide$os4.2$_" #sym ); \ - __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 defined(__arm64__) - #define NOT_HERE_BEFORE_10_6(sym) - #define NEVER_HERE(sym) -#else - #define NOT_HERE_BEFORE_10_6(sym) \ - extern const char sym##_tmp4 __asm("$ld$hide$os10.4$_" #sym ); \ - __attribute__((visibility("default"))) const char sym##_tmp4 = 0; \ - extern const char sym##_tmp5 __asm("$ld$hide$os10.5$_" #sym ); \ - __attribute__((visibility("default"))) const char sym##_tmp5 = 0; - #define NEVER_HERE(sym) \ - extern const char sym##_tmp4 __asm("$ld$hide$os10.4$_" #sym ); \ - __attribute__((visibility("default"))) const char sym##_tmp4 = 0; \ - extern const char sym##_tmp5 __asm("$ld$hide$os10.5$_" #sym ); \ - __attribute__((visibility("default"))) const char sym##_tmp5 = 0; \ - extern const char sym##_tmp6 __asm("$ld$hide$os10.6$_" #sym ); \ - __attribute__((visibility("default"))) const char sym##_tmp6 = 0; -#endif - - -#if defined(_LIBUNWIND_BUILD_ZERO_COST_APIS) - -// -// symbols in libSystem.dylib in 10.6 and later, but are in libgcc_s.dylib in -// earlier versions -// -NOT_HERE_BEFORE_10_6(_Unwind_DeleteException) -NOT_HERE_BEFORE_10_6(_Unwind_Find_FDE) -NOT_HERE_BEFORE_10_6(_Unwind_ForcedUnwind) -NOT_HERE_BEFORE_10_6(_Unwind_GetGR) -NOT_HERE_BEFORE_10_6(_Unwind_GetIP) -NOT_HERE_BEFORE_10_6(_Unwind_GetLanguageSpecificData) -NOT_HERE_BEFORE_10_6(_Unwind_GetRegionStart) -NOT_HERE_BEFORE_10_6(_Unwind_RaiseException) -NOT_HERE_BEFORE_10_6(_Unwind_Resume) -NOT_HERE_BEFORE_10_6(_Unwind_SetGR) -NOT_HERE_BEFORE_10_6(_Unwind_SetIP) -NOT_HERE_BEFORE_10_6(_Unwind_Backtrace) -NOT_HERE_BEFORE_10_6(_Unwind_FindEnclosingFunction) -NOT_HERE_BEFORE_10_6(_Unwind_GetCFA) -NOT_HERE_BEFORE_10_6(_Unwind_GetDataRelBase) -NOT_HERE_BEFORE_10_6(_Unwind_GetTextRelBase) -NOT_HERE_BEFORE_10_6(_Unwind_Resume_or_Rethrow) -NOT_HERE_BEFORE_10_6(_Unwind_GetIPInfo) -NOT_HERE_BEFORE_10_6(__register_frame) -NOT_HERE_BEFORE_10_6(__deregister_frame) - -// -// symbols in libSystem.dylib for compatibility, but we don't want any new code -// using them -// -NEVER_HERE(__register_frame_info_bases) -NEVER_HERE(__register_frame_info) -NEVER_HERE(__register_frame_info_table_bases) -NEVER_HERE(__register_frame_info_table) -NEVER_HERE(__register_frame_table) -NEVER_HERE(__deregister_frame_info) -NEVER_HERE(__deregister_frame_info_bases) - -#endif // defined(_LIBUNWIND_BUILD_ZERO_COST_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_GetLanguageSpecificData) -NOT_HERE_BEFORE_5_0(_Unwind_GetRegionStart) -NOT_HERE_BEFORE_5_0(_Unwind_GetIP) -NOT_HERE_BEFORE_5_0(_Unwind_SetGR) -NOT_HERE_BEFORE_5_0(_Unwind_SetIP) -NOT_HERE_BEFORE_5_0(_Unwind_DeleteException) -NOT_HERE_BEFORE_5_0(_Unwind_SjLj_Register) -NOT_HERE_BEFORE_5_0(_Unwind_GetGR) -NOT_HERE_BEFORE_5_0(_Unwind_GetIPInfo) -NOT_HERE_BEFORE_5_0(_Unwind_GetCFA) -NOT_HERE_BEFORE_5_0(_Unwind_SjLj_Resume) -NOT_HERE_BEFORE_5_0(_Unwind_SjLj_RaiseException) -NOT_HERE_BEFORE_5_0(_Unwind_SjLj_Resume_or_Rethrow) -NOT_HERE_BEFORE_5_0(_Unwind_SjLj_Unregister) - -#endif // defined(_LIBUNWIND_BUILD_SJLJ_APIS) - - -namespace libunwind { - -_LIBUNWIND_HIDDEN -bool checkKeyMgrRegisteredFDEs(uintptr_t pc, void *&fde) { -#if __MAC_OS_X_VERSION_MIN_REQUIRED - // lastly check for old style keymgr registration of dynamically generated - // FDEs acquire exclusive access to libgcc_object_info - libgcc_object_info *head = (libgcc_object_info *) - _keymgr_get_and_lock_processwide_ptr(KEYMGR_GCC3_DW2_OBJ_LIST); - if (head != NULL) { - // look at each FDE in keymgr - for (libgcc_object *ob = head->unseen_objects; ob != NULL; ob = ob->next) { - CFI_Parser<LocalAddressSpace>::FDE_Info fdeInfo; - CFI_Parser<LocalAddressSpace>::CIE_Info cieInfo; - const char *msg = CFI_Parser<LocalAddressSpace>::decodeFDE( - LocalAddressSpace::sThisAddressSpace, - (uintptr_t)ob->fde, &fdeInfo, &cieInfo); - if (msg == NULL) { - // Check if this FDE is for a function that includes the pc - if ((fdeInfo.pcStart <= pc) && (pc < fdeInfo.pcEnd)) { - fde = (void*)fdeInfo.pcStart; - _keymgr_set_and_unlock_processwide_ptr(KEYMGR_GCC3_DW2_OBJ_LIST, - head); - return true; - } - } - } - } - // release libgcc_object_info - _keymgr_set_and_unlock_processwide_ptr(KEYMGR_GCC3_DW2_OBJ_LIST, head); -#else - (void)pc; - (void)fde; -#endif - return false; -} - -} - diff --git a/chromium/buildtools/third_party/libunwind/trunk/src/assembly.h b/chromium/buildtools/third_party/libunwind/trunk/src/assembly.h deleted file mode 100644 index 2b2269cc05f..00000000000 --- a/chromium/buildtools/third_party/libunwind/trunk/src/assembly.h +++ /dev/null @@ -1,97 +0,0 @@ -/* ===-- assembly.h - libUnwind assembler support macros -------------------=== - * - * 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. - * - * ===----------------------------------------------------------------------=== - * - * This file defines macros for use in libUnwind assembler source. - * This file is not part of the interface of this library. - * - * ===----------------------------------------------------------------------=== - */ - -#ifndef UNWIND_ASSEMBLY_H -#define UNWIND_ASSEMBLY_H - -#if defined(__POWERPC__) || defined(__powerpc__) || defined(__ppc__) -#define SEPARATOR @ -#elif defined(__arm64__) -#define SEPARATOR %% -#else -#define SEPARATOR ; -#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__) - -#if defined(__arm__) -#define SYMBOL_IS_FUNC(name) .type name,%function -#else -#define SYMBOL_IS_FUNC(name) .type name,@function -#endif -#define HIDDEN_SYMBOL(name) .hidden name - -#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 - -#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) \ - .globl SYMBOL_NAME(name) SEPARATOR \ - SYMBOL_IS_FUNC(SYMBOL_NAME(name)) SEPARATOR \ - SYMBOL_NAME(name): - -#define DEFINE_LIBUNWIND_PRIVATE_FUNCTION(name) \ - .globl SYMBOL_NAME(name) SEPARATOR \ - HIDDEN_SYMBOL(SYMBOL_NAME(name)) SEPARATOR \ - SYMBOL_IS_FUNC(SYMBOL_NAME(name)) SEPARATOR \ - 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 - -#ifdef ARM_HAS_BX -#define JMP(r) bx r -#else -#define JMP(r) mov pc, r -#endif -#endif /* __arm__ */ - -#endif /* UNWIND_ASSEMBLY_H */ diff --git a/chromium/buildtools/third_party/libunwind/trunk/src/config.h b/chromium/buildtools/third_party/libunwind/trunk/src/config.h deleted file mode 100644 index 6706e5a3acc..00000000000 --- a/chromium/buildtools/third_party/libunwind/trunk/src/config.h +++ /dev/null @@ -1,166 +0,0 @@ -//===----------------------------- config.h -------------------------------===// -// -// 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. -// -// -// Defines macros used within libunwind project. -// -//===----------------------------------------------------------------------===// - - -#ifndef LIBUNWIND_CONFIG_H -#define LIBUNWIND_CONFIG_H - -#include <assert.h> -#include <stdio.h> -#include <stdint.h> -#include <stdlib.h> - -// Define static_assert() unless already defined by compiler. -#ifndef __has_feature - #define __has_feature(__x) 0 -#endif -#if !(__has_feature(cxx_static_assert)) && !defined(static_assert) - #define static_assert(__b, __m) \ - extern int compile_time_assert_failed[ ( __b ) ? 1 : -1 ] \ - __attribute__( ( unused ) ); -#endif - -// Platform specific configuration defines. -#ifdef __APPLE__ - #if defined(FOR_DYLD) - #define _LIBUNWIND_SUPPORT_COMPACT_UNWIND - #else - #define _LIBUNWIND_SUPPORT_COMPACT_UNWIND - #define _LIBUNWIND_SUPPORT_DWARF_UNWIND 1 - #endif -#elif defined(_WIN32) - #define _LIBUNWIND_SUPPORT_DWARF_UNWIND 1 -#else - #if defined(__ARM_DWARF_EH__) || !defined(__arm__) - #define _LIBUNWIND_SUPPORT_DWARF_UNWIND 1 - #define _LIBUNWIND_SUPPORT_DWARF_INDEX 1 - #endif -#endif - -#if defined(_LIBUNWIND_DISABLE_VISIBILITY_ANNOTATIONS) - #define _LIBUNWIND_EXPORT - #define _LIBUNWIND_HIDDEN -#else - // FIXME: these macros are not correct for COFF targets - #define _LIBUNWIND_EXPORT __attribute__((visibility("default"))) - #define _LIBUNWIND_HIDDEN __attribute__((visibility("hidden"))) -#endif - -#if (defined(__APPLE__) && defined(__arm__)) || defined(__USING_SJLJ_EXCEPTIONS__) -#define _LIBUNWIND_BUILD_SJLJ_APIS -#endif - -#if defined(__i386__) || defined(__x86_64__) || defined(__ppc__) || defined(__ppc64__) -#define _LIBUNWIND_SUPPORT_FRAME_APIS -#endif - -#if defined(__i386__) || defined(__x86_64__) || \ - defined(__ppc__) || defined(__ppc64__) || \ - (!defined(__APPLE__) && defined(__arm__)) || \ - (defined(__arm64__) || defined(__aarch64__)) || \ - (defined(__APPLE__) && 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__, \ - __LINE__, msg); \ - fflush(stderr); \ - abort(); \ - } while (0) -#endif - -#if defined(NDEBUG) && defined(_LIBUNWIND_IS_BAREMETAL) -#define _LIBUNWIND_LOG(msg, ...) -#else -#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_DWARF (0) - #define _LIBUNWIND_TRACE_UNWINDING(msg, ...) - #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_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 -// Used to fit UnwindCursor and Registers_xxx types against unw_context_t / -// unw_cursor_t sized memory blocks. -#if defined(_LIBUNWIND_IS_NATIVE_ONLY) -# define COMP_OP == -#else -# define COMP_OP < -#endif -template <typename _Type, typename _Mem> -struct check_fit { - template <typename T> - struct blk_count { - static const size_t count = - (sizeof(T) + sizeof(uint64_t) - 1) / sizeof(uint64_t); - }; - static const bool does_fit = - (blk_count<_Type>::count COMP_OP blk_count<_Mem>::count); -}; -#undef COMP_OP -#endif // __cplusplus - -#endif // LIBUNWIND_CONFIG_H diff --git a/chromium/buildtools/third_party/libunwind/trunk/src/dwarf2.h b/chromium/buildtools/third_party/libunwind/trunk/src/dwarf2.h deleted file mode 100644 index 0dcd2ca99ba..00000000000 --- a/chromium/buildtools/third_party/libunwind/trunk/src/dwarf2.h +++ /dev/null @@ -1,237 +0,0 @@ -//===------------------------------- dwarf2.h -----------------------------===// -// -// 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. -// -//===----------------------------------------------------------------------===// - - -/* - These constants were taken from version 3 of the DWARF standard, - which is Copyright (c) 2005 Free Standards Group, and - Copyright (c) 1992, 1993 UNIX International, Inc. -*/ - -#ifndef __DWARF2__ -#define __DWARF2__ - -// DWARF unwind instructions -enum { - DW_CFA_nop = 0x0, - DW_CFA_set_loc = 0x1, - DW_CFA_advance_loc1 = 0x2, - DW_CFA_advance_loc2 = 0x3, - DW_CFA_advance_loc4 = 0x4, - DW_CFA_offset_extended = 0x5, - DW_CFA_restore_extended = 0x6, - DW_CFA_undefined = 0x7, - DW_CFA_same_value = 0x8, - DW_CFA_register = 0x9, - DW_CFA_remember_state = 0xA, - DW_CFA_restore_state = 0xB, - DW_CFA_def_cfa = 0xC, - DW_CFA_def_cfa_register = 0xD, - DW_CFA_def_cfa_offset = 0xE, - DW_CFA_def_cfa_expression = 0xF, - DW_CFA_expression = 0x10, - DW_CFA_offset_extended_sf = 0x11, - DW_CFA_def_cfa_sf = 0x12, - DW_CFA_def_cfa_offset_sf = 0x13, - DW_CFA_val_offset = 0x14, - DW_CFA_val_offset_sf = 0x15, - DW_CFA_val_expression = 0x16, - DW_CFA_advance_loc = 0x40, // high 2 bits are 0x1, lower 6 bits are delta - DW_CFA_offset = 0x80, // high 2 bits are 0x2, lower 6 bits are register - DW_CFA_restore = 0xC0, // high 2 bits are 0x3, lower 6 bits are register - - // GNU extensions - DW_CFA_GNU_window_save = 0x2D, - DW_CFA_GNU_args_size = 0x2E, - DW_CFA_GNU_negative_offset_extended = 0x2F -}; - - -// FSF exception handling Pointer-Encoding constants -// Used in CFI augmentation by GCC -enum { - DW_EH_PE_ptr = 0x00, - DW_EH_PE_uleb128 = 0x01, - DW_EH_PE_udata2 = 0x02, - DW_EH_PE_udata4 = 0x03, - DW_EH_PE_udata8 = 0x04, - DW_EH_PE_signed = 0x08, - DW_EH_PE_sleb128 = 0x09, - DW_EH_PE_sdata2 = 0x0A, - DW_EH_PE_sdata4 = 0x0B, - DW_EH_PE_sdata8 = 0x0C, - DW_EH_PE_absptr = 0x00, - DW_EH_PE_pcrel = 0x10, - DW_EH_PE_textrel = 0x20, - DW_EH_PE_datarel = 0x30, - DW_EH_PE_funcrel = 0x40, - DW_EH_PE_aligned = 0x50, - DW_EH_PE_indirect = 0x80, - DW_EH_PE_omit = 0xFF -}; - - -// DWARF expressions -enum { - DW_OP_addr = 0x03, // constant address (size target specific) - DW_OP_deref = 0x06, - DW_OP_const1u = 0x08, // 1-byte constant - DW_OP_const1s = 0x09, // 1-byte constant - DW_OP_const2u = 0x0A, // 2-byte constant - DW_OP_const2s = 0x0B, // 2-byte constant - DW_OP_const4u = 0x0C, // 4-byte constant - DW_OP_const4s = 0x0D, // 4-byte constant - DW_OP_const8u = 0x0E, // 8-byte constant - DW_OP_const8s = 0x0F, // 8-byte constant - DW_OP_constu = 0x10, // ULEB128 constant - DW_OP_consts = 0x11, // SLEB128 constant - DW_OP_dup = 0x12, - DW_OP_drop = 0x13, - DW_OP_over = 0x14, - DW_OP_pick = 0x15, // 1-byte stack index - DW_OP_swap = 0x16, - DW_OP_rot = 0x17, - DW_OP_xderef = 0x18, - DW_OP_abs = 0x19, - DW_OP_and = 0x1A, - DW_OP_div = 0x1B, - DW_OP_minus = 0x1C, - DW_OP_mod = 0x1D, - DW_OP_mul = 0x1E, - DW_OP_neg = 0x1F, - DW_OP_not = 0x20, - DW_OP_or = 0x21, - DW_OP_plus = 0x22, - DW_OP_plus_uconst = 0x23, // ULEB128 addend - DW_OP_shl = 0x24, - DW_OP_shr = 0x25, - DW_OP_shra = 0x26, - DW_OP_xor = 0x27, - DW_OP_skip = 0x2F, // signed 2-byte constant - DW_OP_bra = 0x28, // signed 2-byte constant - DW_OP_eq = 0x29, - DW_OP_ge = 0x2A, - DW_OP_gt = 0x2B, - DW_OP_le = 0x2C, - DW_OP_lt = 0x2D, - DW_OP_ne = 0x2E, - DW_OP_lit0 = 0x30, // Literal 0 - DW_OP_lit1 = 0x31, // Literal 1 - DW_OP_lit2 = 0x32, // Literal 2 - DW_OP_lit3 = 0x33, // Literal 3 - DW_OP_lit4 = 0x34, // Literal 4 - DW_OP_lit5 = 0x35, // Literal 5 - DW_OP_lit6 = 0x36, // Literal 6 - DW_OP_lit7 = 0x37, // Literal 7 - DW_OP_lit8 = 0x38, // Literal 8 - DW_OP_lit9 = 0x39, // Literal 9 - DW_OP_lit10 = 0x3A, // Literal 10 - DW_OP_lit11 = 0x3B, // Literal 11 - DW_OP_lit12 = 0x3C, // Literal 12 - DW_OP_lit13 = 0x3D, // Literal 13 - DW_OP_lit14 = 0x3E, // Literal 14 - DW_OP_lit15 = 0x3F, // Literal 15 - DW_OP_lit16 = 0x40, // Literal 16 - DW_OP_lit17 = 0x41, // Literal 17 - DW_OP_lit18 = 0x42, // Literal 18 - DW_OP_lit19 = 0x43, // Literal 19 - DW_OP_lit20 = 0x44, // Literal 20 - DW_OP_lit21 = 0x45, // Literal 21 - DW_OP_lit22 = 0x46, // Literal 22 - DW_OP_lit23 = 0x47, // Literal 23 - DW_OP_lit24 = 0x48, // Literal 24 - DW_OP_lit25 = 0x49, // Literal 25 - DW_OP_lit26 = 0x4A, // Literal 26 - DW_OP_lit27 = 0x4B, // Literal 27 - DW_OP_lit28 = 0x4C, // Literal 28 - DW_OP_lit29 = 0x4D, // Literal 29 - DW_OP_lit30 = 0x4E, // Literal 30 - DW_OP_lit31 = 0x4F, // Literal 31 - DW_OP_reg0 = 0x50, // Contents of reg0 - DW_OP_reg1 = 0x51, // Contents of reg1 - DW_OP_reg2 = 0x52, // Contents of reg2 - DW_OP_reg3 = 0x53, // Contents of reg3 - DW_OP_reg4 = 0x54, // Contents of reg4 - DW_OP_reg5 = 0x55, // Contents of reg5 - DW_OP_reg6 = 0x56, // Contents of reg6 - DW_OP_reg7 = 0x57, // Contents of reg7 - DW_OP_reg8 = 0x58, // Contents of reg8 - DW_OP_reg9 = 0x59, // Contents of reg9 - DW_OP_reg10 = 0x5A, // Contents of reg10 - DW_OP_reg11 = 0x5B, // Contents of reg11 - DW_OP_reg12 = 0x5C, // Contents of reg12 - DW_OP_reg13 = 0x5D, // Contents of reg13 - DW_OP_reg14 = 0x5E, // Contents of reg14 - DW_OP_reg15 = 0x5F, // Contents of reg15 - DW_OP_reg16 = 0x60, // Contents of reg16 - DW_OP_reg17 = 0x61, // Contents of reg17 - DW_OP_reg18 = 0x62, // Contents of reg18 - DW_OP_reg19 = 0x63, // Contents of reg19 - DW_OP_reg20 = 0x64, // Contents of reg20 - DW_OP_reg21 = 0x65, // Contents of reg21 - DW_OP_reg22 = 0x66, // Contents of reg22 - DW_OP_reg23 = 0x67, // Contents of reg23 - DW_OP_reg24 = 0x68, // Contents of reg24 - DW_OP_reg25 = 0x69, // Contents of reg25 - DW_OP_reg26 = 0x6A, // Contents of reg26 - DW_OP_reg27 = 0x6B, // Contents of reg27 - DW_OP_reg28 = 0x6C, // Contents of reg28 - DW_OP_reg29 = 0x6D, // Contents of reg29 - DW_OP_reg30 = 0x6E, // Contents of reg30 - DW_OP_reg31 = 0x6F, // Contents of reg31 - DW_OP_breg0 = 0x70, // base register 0 + SLEB128 offset - DW_OP_breg1 = 0x71, // base register 1 + SLEB128 offset - DW_OP_breg2 = 0x72, // base register 2 + SLEB128 offset - DW_OP_breg3 = 0x73, // base register 3 + SLEB128 offset - DW_OP_breg4 = 0x74, // base register 4 + SLEB128 offset - DW_OP_breg5 = 0x75, // base register 5 + SLEB128 offset - DW_OP_breg6 = 0x76, // base register 6 + SLEB128 offset - DW_OP_breg7 = 0x77, // base register 7 + SLEB128 offset - DW_OP_breg8 = 0x78, // base register 8 + SLEB128 offset - DW_OP_breg9 = 0x79, // base register 9 + SLEB128 offset - DW_OP_breg10 = 0x7A, // base register 10 + SLEB128 offset - DW_OP_breg11 = 0x7B, // base register 11 + SLEB128 offset - DW_OP_breg12 = 0x7C, // base register 12 + SLEB128 offset - DW_OP_breg13 = 0x7D, // base register 13 + SLEB128 offset - DW_OP_breg14 = 0x7E, // base register 14 + SLEB128 offset - DW_OP_breg15 = 0x7F, // base register 15 + SLEB128 offset - DW_OP_breg16 = 0x80, // base register 16 + SLEB128 offset - DW_OP_breg17 = 0x81, // base register 17 + SLEB128 offset - DW_OP_breg18 = 0x82, // base register 18 + SLEB128 offset - DW_OP_breg19 = 0x83, // base register 19 + SLEB128 offset - DW_OP_breg20 = 0x84, // base register 20 + SLEB128 offset - DW_OP_breg21 = 0x85, // base register 21 + SLEB128 offset - DW_OP_breg22 = 0x86, // base register 22 + SLEB128 offset - DW_OP_breg23 = 0x87, // base register 23 + SLEB128 offset - DW_OP_breg24 = 0x88, // base register 24 + SLEB128 offset - DW_OP_breg25 = 0x89, // base register 25 + SLEB128 offset - DW_OP_breg26 = 0x8A, // base register 26 + SLEB128 offset - DW_OP_breg27 = 0x8B, // base register 27 + SLEB128 offset - DW_OP_breg28 = 0x8C, // base register 28 + SLEB128 offset - DW_OP_breg29 = 0x8D, // base register 29 + SLEB128 offset - DW_OP_breg30 = 0x8E, // base register 30 + SLEB128 offset - DW_OP_breg31 = 0x8F, // base register 31 + SLEB128 offset - DW_OP_regx = 0x90, // ULEB128 register - DW_OP_fbreg = 0x91, // SLEB128 offset - DW_OP_bregx = 0x92, // ULEB128 register followed by SLEB128 offset - DW_OP_piece = 0x93, // ULEB128 size of piece addressed - DW_OP_deref_size = 0x94, // 1-byte size of data retrieved - DW_OP_xderef_size = 0x95, // 1-byte size of data retrieved - DW_OP_nop = 0x96, - DW_OP_push_object_addres = 0x97, - DW_OP_call2 = 0x98, // 2-byte offset of DIE - DW_OP_call4 = 0x99, // 4-byte offset of DIE - DW_OP_call_ref = 0x9A, // 4- or 8-byte offset of DIE - DW_OP_lo_user = 0xE0, - DW_OP_APPLE_uninit = 0xF0, - DW_OP_hi_user = 0xFF -}; - - -#endif diff --git a/chromium/buildtools/third_party/libunwind/trunk/src/libunwind.cpp b/chromium/buildtools/third_party/libunwind/trunk/src/libunwind.cpp deleted file mode 100644 index c4308170ab6..00000000000 --- a/chromium/buildtools/third_party/libunwind/trunk/src/libunwind.cpp +++ /dev/null @@ -1,390 +0,0 @@ -//===--------------------------- libunwind.cpp ----------------------------===// -// -// 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. -// -// -// Implements unw_* functions from <libunwind.h> -// -//===----------------------------------------------------------------------===// - -#include <libunwind.h> - -#ifndef NDEBUG -#include <cstdlib> // getenv -#endif -#include <new> -#include <algorithm> - -#include "libunwind_ext.h" -#include "config.h" - -#include <stdlib.h> - - -#if !defined(__USING_SJLJ_EXCEPTIONS__) -#include "AddressSpace.hpp" -#include "UnwindCursor.hpp" - -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 - -/// Create a cursor of a thread in this process given 'context' recorded by -/// unw_getcontext(). -_LIBUNWIND_EXPORT int unw_init_local(unw_cursor_t *cursor, - unw_context_t *context) { - _LIBUNWIND_TRACE_API("unw_init_local(cursor=%p, context=%p)", - static_cast<void *>(cursor), - static_cast<void *>(context)); -#if defined(__i386__) -# define REGISTER_KIND Registers_x86 -#elif defined(__x86_64__) -# define REGISTER_KIND Registers_x86_64 -#elif defined(__ppc__) -# define REGISTER_KIND Registers_ppc -#elif defined(__aarch64__) -# define REGISTER_KIND Registers_arm64 -#elif defined(_LIBUNWIND_ARM_EHABI) -# define REGISTER_KIND Registers_arm -#elif defined(__or1k__) -# define REGISTER_KIND Registers_or1k -#elif defined(__mips__) -# warning The MIPS architecture is not supported. -#else -# error Architecture not supported -#endif - // Use "placement new" to allocate UnwindCursor in the cursor buffer. - new ((void *)cursor) UnwindCursor<LocalAddressSpace, REGISTER_KIND>( - context, LocalAddressSpace::sThisAddressSpace); -#undef REGISTER_KIND - AbstractUnwindCursor *co = (AbstractUnwindCursor *)cursor; - co->setInfoBasedOnIPRegister(); - - return UNW_ESUCCESS; -} - -#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)&LocalAddressSpace::sThisAddressSpace) - return unw_init_local(cursor, NULL); //FIXME - - // use "placement new" to allocate UnwindCursor in the cursor buffer - switch (as->cpuType) { - case CPU_TYPE_I386: - new ((void *)cursor) - UnwindCursor<RemoteAddressSpace<Pointer32<LittleEndian>>, - Registers_x86>(((unw_addr_space_i386 *)as)->oas, arg); - break; - case CPU_TYPE_X86_64: - new ((void *)cursor) - UnwindCursor<RemoteAddressSpace<Pointer64<LittleEndian>>, - Registers_x86_64>(((unw_addr_space_x86_64 *)as)->oas, arg); - break; - case CPU_TYPE_POWERPC: - new ((void *)cursor) - UnwindCursor<RemoteAddressSpace<Pointer32<BigEndian>>, - Registers_ppc>(((unw_addr_space_ppc *)as)->oas, arg); - break; - default: - return UNW_EUNSPEC; - } - return UNW_ESUCCESS; -} - - -static bool is64bit(task_t task) { - return false; // FIXME -} - -/// Create an address_space object for use in examining another task. -_LIBUNWIND_EXPORT unw_addr_space_t unw_create_addr_space_for_task(task_t task) { -#if __i386__ - if (is64bit(task)) { - unw_addr_space_x86_64 *as = new unw_addr_space_x86_64(task); - as->taskPort = task; - as->cpuType = CPU_TYPE_X86_64; - //as->oas - } else { - unw_addr_space_i386 *as = new unw_addr_space_i386(task); - as->taskPort = task; - as->cpuType = CPU_TYPE_I386; - //as->oas - } -#else -// FIXME -#endif -} - - -/// Delete an address_space object. -_LIBUNWIND_EXPORT void unw_destroy_addr_space(unw_addr_space_t asp) { - switch (asp->cpuType) { -#if __i386__ || __x86_64__ - case CPU_TYPE_I386: { - unw_addr_space_i386 *as = (unw_addr_space_i386 *)asp; - delete as; - } - break; - case CPU_TYPE_X86_64: { - unw_addr_space_x86_64 *as = (unw_addr_space_x86_64 *)asp; - delete as; - } - break; -#endif - case CPU_TYPE_POWERPC: { - unw_addr_space_ppc *as = (unw_addr_space_ppc *)asp; - delete as; - } - break; - } -} -#endif // UNW_REMOTE - - -/// Get value of specified register at cursor position in stack frame. -_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)", - static_cast<void *>(cursor), regNum, - static_cast<void *>(value)); - AbstractUnwindCursor *co = (AbstractUnwindCursor *)cursor; - if (co->validReg(regNum)) { - *value = co->getReg(regNum); - return UNW_ESUCCESS; - } - return UNW_EBADREG; -} - - -/// Set value of specified register at cursor position in stack frame. -_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%" PRIxPTR ")", - static_cast<void *>(cursor), regNum, value); - typedef LocalAddressSpace::pint_t pint_t; - AbstractUnwindCursor *co = (AbstractUnwindCursor *)cursor; - if (co->validReg(regNum)) { - co->setReg(regNum, (pint_t)value); - // specical case altering IP to re-find info (being called by personality - // function) - if (regNum == UNW_REG_IP) - co->setInfoBasedOnIPRegister(false); - return UNW_ESUCCESS; - } - return UNW_EBADREG; -} - - -/// Get value of specified float register at cursor position in stack frame. -_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)", - static_cast<void *>(cursor), regNum, - static_cast<void *>(value)); - AbstractUnwindCursor *co = (AbstractUnwindCursor *)cursor; - if (co->validFloatReg(regNum)) { - *value = co->getFloatReg(regNum); - return UNW_ESUCCESS; - } - return UNW_EBADREG; -} - - -/// Set value of specified float register at cursor position in stack frame. -_LIBUNWIND_EXPORT int unw_set_fpreg(unw_cursor_t *cursor, unw_regnum_t regNum, - unw_fpreg_t value) { -#if defined(_LIBUNWIND_ARM_EHABI) - _LIBUNWIND_TRACE_API("unw_set_fpreg(cursor=%p, regNum=%d, value=%llX)", - static_cast<void *>(cursor), regNum, value); -#else - _LIBUNWIND_TRACE_API("unw_set_fpreg(cursor=%p, regNum=%d, value=%g)", - static_cast<void *>(cursor), regNum, value); -#endif - AbstractUnwindCursor *co = (AbstractUnwindCursor *)cursor; - if (co->validFloatReg(regNum)) { - co->setFloatReg(regNum, value); - return UNW_ESUCCESS; - } - return UNW_EBADREG; -} - - -/// Move cursor to next frame. -_LIBUNWIND_EXPORT int unw_step(unw_cursor_t *cursor) { - _LIBUNWIND_TRACE_API("unw_step(cursor=%p)", static_cast<void *>(cursor)); - AbstractUnwindCursor *co = (AbstractUnwindCursor *)cursor; - return co->step(); -} - - -/// Get unwind info at cursor position in stack frame. -_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)", - static_cast<void *>(cursor), static_cast<void *>(info)); - AbstractUnwindCursor *co = (AbstractUnwindCursor *)cursor; - co->getInfo(info); - if (info->end_ip == 0) - return UNW_ENOINFO; - else - return UNW_ESUCCESS; -} - - -/// Resume execution at cursor position (aka longjump). -_LIBUNWIND_EXPORT int unw_resume(unw_cursor_t *cursor) { - _LIBUNWIND_TRACE_API("unw_resume(cursor=%p)", static_cast<void *>(cursor)); - AbstractUnwindCursor *co = (AbstractUnwindCursor *)cursor; - co->jumpto(); - return UNW_EUNSPEC; -} - - -/// 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=%lu)", - 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; - else - return UNW_EUNSPEC; -} - - -/// 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)", - static_cast<void *>(cursor), regNum); - AbstractUnwindCursor *co = (AbstractUnwindCursor *)cursor; - return co->validFloatReg(regNum); -} - - -/// Checks if a register is a floating-point register. -_LIBUNWIND_EXPORT const char *unw_regname(unw_cursor_t *cursor, - unw_regnum_t regNum) { - _LIBUNWIND_TRACE_API("unw_regname(cursor=%p, regNum=%d)", - static_cast<void *>(cursor), regNum); - AbstractUnwindCursor *co = (AbstractUnwindCursor *)cursor; - return co->getRegisterName(regNum); -} - - -/// 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)", - static_cast<void *>(cursor)); - AbstractUnwindCursor *co = (AbstractUnwindCursor *)cursor; - return co->isSignalFrame(); -} - -#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)", - static_cast<void *>(cursor)); - AbstractUnwindCursor *co = (AbstractUnwindCursor *)cursor; - return co->saveVFPAsX(); -} -#endif - - -#if defined(_LIBUNWIND_SUPPORT_DWARF_UNWIND) -/// 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)", - reinterpret_cast<void *>(func)); - DwarfFDECache<LocalAddressSpace>::iterateCacheEntries(func); -} - - -/// IPI: for __register_frame() -void _unw_add_dynamic_fde(unw_word_t fde) { - CFI_Parser<LocalAddressSpace>::FDE_Info fdeInfo; - CFI_Parser<LocalAddressSpace>::CIE_Info cieInfo; - const char *message = CFI_Parser<LocalAddressSpace>::decodeFDE( - LocalAddressSpace::sThisAddressSpace, - (LocalAddressSpace::pint_t) fde, &fdeInfo, &cieInfo); - if (message == NULL) { - // dynamically registered FDEs don't have a mach_header group they are in. - // Use fde as mh_group - unw_word_t mh_group = fdeInfo.fdeStart; - DwarfFDECache<LocalAddressSpace>::add((LocalAddressSpace::pint_t)mh_group, - fdeInfo.pcStart, fdeInfo.pcEnd, - fdeInfo.fdeStart); - } else { - _LIBUNWIND_DEBUG_LOG("_unw_add_dynamic_fde: bad fde: %s", message); - } -} - -/// IPI: for __deregister_frame() -void _unw_remove_dynamic_fde(unw_word_t fde) { - // fde is own mh_group - DwarfFDECache<LocalAddressSpace>::removeAllIn((LocalAddressSpace::pint_t)fde); -} -#endif // defined(_LIBUNWIND_SUPPORT_DWARF_UNWIND) -#endif // !defined(__USING_SJLJ_EXCEPTIONS__) - - - -// Add logging hooks in Debug builds only -#ifndef NDEBUG -#include <stdlib.h> - -_LIBUNWIND_HIDDEN -bool logAPIs() { - // do manual lock to avoid use of _cxa_guard_acquire or initializers - static bool checked = false; - static bool log = false; - if (!checked) { - log = (getenv("LIBUNWIND_PRINT_APIS") != NULL); - checked = true; - } - return log; -} - -_LIBUNWIND_HIDDEN -bool logUnwinding() { - // do manual lock to avoid use of _cxa_guard_acquire or initializers - static bool checked = false; - static bool log = false; - if (!checked) { - log = (getenv("LIBUNWIND_PRINT_UNWINDING") != NULL); - checked = true; - } - return log; -} - -_LIBUNWIND_HIDDEN -bool logDWARF() { - // do manual lock to avoid use of _cxa_guard_acquire or initializers - static bool checked = false; - static bool log = false; - if (!checked) { - log = (getenv("LIBUNWIND_PRINT_DWARF") != NULL); - checked = true; - } - return log; -} - -#endif // NDEBUG - diff --git a/chromium/buildtools/third_party/libunwind/trunk/src/libunwind_ext.h b/chromium/buildtools/third_party/libunwind/trunk/src/libunwind_ext.h deleted file mode 100644 index ec645a84673..00000000000 --- a/chromium/buildtools/third_party/libunwind/trunk/src/libunwind_ext.h +++ /dev/null @@ -1,47 +0,0 @@ -//===------------------------ libunwind_ext.h -----------------------------===// -// -// 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. -// -// -// Extensions to libunwind API. -// -//===----------------------------------------------------------------------===// - -#ifndef __LIBUNWIND_EXT__ -#define __LIBUNWIND_EXT__ - -#include "config.h" -#include <libunwind.h> -#include <unwind.h> - -#define UNW_STEP_SUCCESS 1 -#define UNW_STEP_END 0 - -#ifdef __cplusplus -extern "C" { -#endif -// SPI -extern 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)); - -// IPI -extern void _unw_add_dynamic_fde(unw_word_t fde); -extern void _unw_remove_dynamic_fde(unw_word_t fde); - -#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, - size_t offset, size_t len); -#endif - -#ifdef __cplusplus -} -#endif - -#endif // __LIBUNWIND_EXT__ diff --git a/chromium/buildtools/win/gn.exe.sha1 b/chromium/buildtools/win/gn.exe.sha1 index 3b11723605e..47e5e1e590e 100644 --- a/chromium/buildtools/win/gn.exe.sha1 +++ b/chromium/buildtools/win/gn.exe.sha1 @@ -1 +1 @@ -b1981c189f40c3ae42b965277ad1bc3449d26d2a +c0d03f78af494365ff38c663297a20fe61da29ea |