From cd46bc16093bd326719a063f1ca6ac7feb7b9665 Mon Sep 17 00:00:00 2001 From: Adeel <3840695+am11@users.noreply.github.com> Date: Wed, 15 May 2024 01:31:56 +0300 Subject: [PATCH 1/3] Update llvm-libunwind to v18 --- .../external/llvm-libunwind/CMakeLists.txt | 79 +++-- .../cmake/Modules/HandleLibunwindFlags.cmake | 181 +---------- .../llvm-libunwind/cmake/config-ix.cmake | 20 +- .../external/llvm-libunwind/docs/conf.py | 134 ++++---- .../include/__libunwind_config.h | 30 +- .../llvm-libunwind/include/libunwind.h | 27 +- .../llvm-libunwind/include/unwind_arm_ehabi.h | 8 +- .../llvm-libunwind/include/unwind_itanium.h | 2 +- .../llvm-libunwind/src/AddressSpace.hpp | 33 +- .../llvm-libunwind/src/CMakeLists.txt | 72 +++-- .../llvm-libunwind/src/CompactUnwinder.hpp | 226 +++++++------- .../llvm-libunwind/src/DwarfInstructions.hpp | 60 ++-- .../llvm-libunwind/src/DwarfParser.hpp | 4 +- .../llvm-libunwind/src/EHHeaderParser.hpp | 13 + .../llvm-libunwind/src/FrameHeaderCache.hpp | 6 +- .../external/llvm-libunwind/src/Registers.hpp | 293 ++++-------------- .../llvm-libunwind/src/Unwind-EHABI.cpp | 41 +-- .../llvm-libunwind/src/Unwind-seh.cpp | 19 +- .../external/llvm-libunwind/src/Unwind-sjlj.c | 11 +- .../external/llvm-libunwind/src/Unwind-wasm.c | 123 ++++++++ .../llvm-libunwind/src/UnwindCursor.hpp | 282 +++++++++++------ .../llvm-libunwind/src/UnwindLevel1-gcc-ext.c | 4 +- .../llvm-libunwind/src/UnwindLevel1.c | 2 +- .../src/UnwindRegistersRestore.S | 15 +- .../llvm-libunwind/src/UnwindRegistersSave.S | 44 ++- .../llvm-libunwind/src/Unwind_AppleExtras.cpp | 113 ------- .../external/llvm-libunwind/src/config.h | 26 +- .../external/llvm-libunwind/src/libunwind.cpp | 108 +++++-- .../llvm-libunwind/src/libunwind_ext.h | 68 +++- .../external/llvm-libunwind/src/unwind_ext.h | 37 --- .../llvm-libunwind/test/CMakeLists.txt | 24 +- .../test/aix_signal_unwind.pass.sh.S | 245 +++++++++++++++ .../test/bad_unwind_info.pass.cpp | 2 +- .../apple-libunwind-backdeployment.cfg.in | 8 +- .../configs/armv7m-picolibc-libunwind.cfg.in | 39 +++ .../test/configs/cmake-bridge.cfg.in | 3 +- .../test/configs/ibm-libunwind-shared.cfg.in | 10 +- .../test/configs/llvm-libunwind-merged.cfg.in | 14 +- .../test/configs/llvm-libunwind-mingw.cfg.in | 25 ++ .../test/configs/llvm-libunwind-shared.cfg.in | 14 +- .../test/configs/llvm-libunwind-static.cfg.in | 14 +- .../llvm-libunwind/test/forceunwind.pass.cpp | 2 +- .../llvm-libunwind/test/libunwind_01.pass.cpp | 2 +- .../llvm-libunwind/test/libunwind_02.pass.cpp | 31 +- .../external/llvm-libunwind/test/lit.cfg.py | 3 +- .../llvm-libunwind/test/signal_frame.pass.cpp | 6 +- .../test/signal_unwind.pass.cpp | 2 +- .../llvm-libunwind/test/unw_resume.pass.cpp | 5 +- .../test/unwind_leaffunction.pass.cpp | 22 +- .../test/unwind_scalable_vectors.pass.cpp | 38 +-- 50 files changed, 1436 insertions(+), 1154 deletions(-) create mode 100644 src/native/external/llvm-libunwind/src/Unwind-wasm.c delete mode 100644 src/native/external/llvm-libunwind/src/Unwind_AppleExtras.cpp delete mode 100644 src/native/external/llvm-libunwind/src/unwind_ext.h create mode 100644 src/native/external/llvm-libunwind/test/aix_signal_unwind.pass.sh.S create mode 100644 src/native/external/llvm-libunwind/test/configs/armv7m-picolibc-libunwind.cfg.in create mode 100644 src/native/external/llvm-libunwind/test/configs/llvm-libunwind-mingw.cfg.in diff --git a/src/native/external/llvm-libunwind/CMakeLists.txt b/src/native/external/llvm-libunwind/CMakeLists.txt index 5c547883f9927..806d5a783ec39 100644 --- a/src/native/external/llvm-libunwind/CMakeLists.txt +++ b/src/native/external/llvm-libunwind/CMakeLists.txt @@ -2,7 +2,7 @@ # Setup Project #=============================================================================== -cmake_minimum_required(VERSION 3.13.4) +cmake_minimum_required(VERSION 3.20.0) set(LLVM_COMMON_CMAKE_UTILS "${CMAKE_CURRENT_SOURCE_DIR}/../cmake") @@ -10,6 +10,7 @@ set(LLVM_COMMON_CMAKE_UTILS "${CMAKE_CURRENT_SOURCE_DIR}/../cmake") list(INSERT CMAKE_MODULE_PATH 0 "${CMAKE_CURRENT_SOURCE_DIR}/cmake" "${CMAKE_CURRENT_SOURCE_DIR}/cmake/Modules" + "${CMAKE_CURRENT_SOURCE_DIR}/../runtimes/cmake/Modules" "${LLVM_COMMON_CMAKE_UTILS}" "${LLVM_COMMON_CMAKE_UTILS}/Modules" ) @@ -20,6 +21,7 @@ set(LIBUNWIND_LIBCXX_PATH "${CMAKE_CURRENT_LIST_DIR}/../libcxx" CACHE PATH "Specify path to libc++ source.") include(GNUInstallDirs) +include(CheckSymbolExists) #=============================================================================== # Setup CMake Options @@ -50,6 +52,7 @@ option(LIBUNWIND_IS_BAREMETAL "Build libunwind for baremetal targets." OFF) option(LIBUNWIND_USE_FRAME_HEADER_CACHE "Cache frame headers for unwinding. Requires locking dl_iterate_phdr." OFF) option(LIBUNWIND_REMEMBER_HEAP_ALLOC "Use heap instead of the stack for .cfi_remember_state." OFF) option(LIBUNWIND_INSTALL_HEADERS "Install the libunwind headers." ON) +option(LIBUNWIND_ENABLE_FRAME_APIS "Include libgcc-compatible frame apis." OFF) set(LIBUNWIND_LIBDIR_SUFFIX "${LLVM_LIBDIR_SUFFIX}" CACHE STRING "Define suffix of library directory name (32/64)") @@ -61,12 +64,9 @@ cmake_dependent_option(LIBUNWIND_INSTALL_SHARED_LIBRARY "Install the shared libunwind library." ON "LIBUNWIND_ENABLE_SHARED;LIBUNWIND_INSTALL_LIBRARY" OFF) -# TODO: Remove this after branching for LLVM 15 -if(LIBUNWIND_SYSROOT OR LIBUNWIND_TARGET_TRIPLE OR LIBUNWIND_GCC_TOOLCHAIN) - message(WARNING "LIBUNWIND_SYSROOT, LIBUNWIND_TARGET_TRIPLE and LIBUNWIND_GCC_TOOLCHAIN are not supported anymore, please use the native CMake equivalents instead") -endif() - -if (LIBUNWIND_ENABLE_SHARED) +if(MINGW) + set(LIBUNWIND_DEFAULT_TEST_CONFIG "llvm-libunwind-mingw.cfg.in") +elseif (LIBUNWIND_ENABLE_SHARED) set(LIBUNWIND_DEFAULT_TEST_CONFIG "llvm-libunwind-shared.cfg.in") else() set(LIBUNWIND_DEFAULT_TEST_CONFIG "llvm-libunwind-static.cfg.in") @@ -97,6 +97,20 @@ endif() option(LIBUNWIND_HIDE_SYMBOLS "Do not export any symbols from the static library." ${LIBUNWIND_DEFAULT_HIDE_SYMBOLS}) +# If toolchain is FPXX, we switch to FP64 to save the full FPRs. See: +# https://web.archive.org/web/20180828210612/https://dmz-portal.mips.com/wiki/MIPS_O32_ABI_-_FR0_and_FR1_Interlinking +check_symbol_exists(__mips_hard_float "" __MIPSHF) +check_symbol_exists(_ABIO32 "" __MIPS_O32) +if (__MIPSHF AND __MIPS_O32) + file(WRITE ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/mips_is_fpxx.c + "#if __mips_fpr != 0\n" + "# error\n" + "#endif\n") + try_compile(MIPS_FPABI_FPXX ${CMAKE_BINARY_DIR} + ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/mips_is_fpxx.c + CMAKE_FLAGS -DCMAKE_C_LINK_EXECUTABLE='echo') +endif() + #=============================================================================== # Configure System #=============================================================================== @@ -106,9 +120,9 @@ set(CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake" ${CMAKE_MODULE_PATH}) -set(LIBUNWIND_INSTALL_INCLUDE_DIR "${CMAKE_INSTALL_INCLUDEDIR}" CACHE PATH +set(LIBUNWIND_INSTALL_INCLUDE_DIR "${CMAKE_INSTALL_INCLUDEDIR}" CACHE STRING "Path where built libunwind headers should be installed.") -set(LIBUNWIND_INSTALL_RUNTIME_DIR "${CMAKE_INSTALL_BINDIR}" CACHE PATH +set(LIBUNWIND_INSTALL_RUNTIME_DIR "${CMAKE_INSTALL_BINDIR}" CACHE STRING "Path where built libunwind runtime libraries should be installed.") set(LIBUNWIND_SHARED_OUTPUT_NAME "unwind" CACHE STRING "Output name for the shared libunwind runtime library.") @@ -116,7 +130,7 @@ set(LIBUNWIND_STATIC_OUTPUT_NAME "unwind" CACHE STRING "Output name for the stat if(LLVM_ENABLE_PER_TARGET_RUNTIME_DIR AND NOT APPLE) set(LIBUNWIND_LIBRARY_DIR ${LLVM_LIBRARY_OUTPUT_INTDIR}/${LLVM_DEFAULT_TARGET_TRIPLE}) - set(LIBUNWIND_INSTALL_LIBRARY_DIR lib${LLVM_LIBDIR_SUFFIX}/${LLVM_DEFAULT_TARGET_TRIPLE} CACHE PATH + set(LIBUNWIND_INSTALL_LIBRARY_DIR lib${LLVM_LIBDIR_SUFFIX}/${LLVM_DEFAULT_TARGET_TRIPLE} CACHE STRING "Path where built libunwind libraries should be installed.") if(LIBCXX_LIBDIR_SUBDIR) string(APPEND LIBUNWIND_LIBRARY_DIR /${LIBUNWIND_LIBDIR_SUBDIR}) @@ -128,7 +142,7 @@ else() else() set(LIBUNWIND_LIBRARY_DIR ${CMAKE_BINARY_DIR}/lib${LIBUNWIND_LIBDIR_SUFFIX}) endif() - set(LIBUNWIND_INSTALL_LIBRARY_DIR lib${LIBUNWIND_LIBDIR_SUFFIX} CACHE PATH + set(LIBUNWIND_INSTALL_LIBRARY_DIR lib${LIBUNWIND_LIBDIR_SUFFIX} CACHE STRING "Path where built libunwind libraries should be installed.") endif() @@ -140,6 +154,10 @@ set(LIBUNWIND_C_FLAGS "") set(LIBUNWIND_CXX_FLAGS "") set(LIBUNWIND_COMPILE_FLAGS "") set(LIBUNWIND_LINK_FLAGS "") +set(LIBUNWIND_ADDITIONAL_COMPILE_FLAGS "" CACHE STRING + "Additional Compile only flags which can be provided in cache") +set(LIBUNWIND_ADDITIONAL_LIBRARIES "" CACHE STRING + "Additional libraries libunwind is linked to which can be provided in cache") # Include macros for adding and removing libunwind flags. include(HandleLibunwindFlags) @@ -168,28 +186,6 @@ if (LIBUNWIND_ENABLE_CET) endif() endif() -# 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(-Wno-unused-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) - -add_compile_flags_if_supported(-Wno-suggest-override) - if (WIN32) # The headers lack matching dllexport attributes (_LIBUNWIND_EXPORT); # silence the warning instead of cluttering the headers (which aren't @@ -198,16 +194,8 @@ if (WIN32) add_compile_flags_if_supported(-Wno-dll-attribute-on-redeclaration) endif() -if (LIBUNWIND_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 (LIBUNWIND_ENABLE_PEDANTIC) - add_compile_flags_if_supported(-pedantic) +if (MIPS_FPABI_FPXX) + add_compile_flags(-mfp64) endif() # Get feature flags. @@ -277,6 +265,11 @@ if (NOT LIBUNWIND_ENABLE_CROSS_UNWINDING) add_compile_flags(-D_LIBUNWIND_IS_NATIVE_ONLY) endif() +# Include stubs for __register_frame_info_bases and related +if (LIBUNWIND_ENABLE_FRAME_APIS) + add_compile_flags(-D_LIBUNWIND_SUPPORT_FRAME_APIS) +endif() + # Threading-support if (NOT LIBUNWIND_ENABLE_THREADS) add_compile_flags(-D_LIBUNWIND_HAS_NO_THREADS) diff --git a/src/native/external/llvm-libunwind/cmake/Modules/HandleLibunwindFlags.cmake b/src/native/external/llvm-libunwind/cmake/Modules/HandleLibunwindFlags.cmake index c5d76034d8709..94c676338821c 100644 --- a/src/native/external/llvm-libunwind/cmake/Modules/HandleLibunwindFlags.cmake +++ b/src/native/external/llvm-libunwind/cmake/Modules/HandleLibunwindFlags.cmake @@ -6,162 +6,10 @@ include(CheckCCompilerFlag) include(CheckCXXCompilerFlag) +include(HandleFlags) 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}" "CXX_SUPPORTS_${flagname}_FLAG") -endmacro() - -macro(append_flags DEST) - foreach(value ${ARGN}) - list(APPEND ${DEST} ${value}) - list(APPEND ${DEST} ${value}) - endforeach() -endmacro() - -# If the specified 'condition' is true then append the specified list of flags to DEST -macro(append_flags_if condition DEST) - if (${condition}) - list(APPEND ${DEST} ${ARGN}) - endif() -endmacro() - -# Add each flag in the list specified by DEST if that flag is supported by the current compiler. -macro(append_flags_if_supported DEST) - foreach(flag ${ARGN}) - mangle_name("${flag}" flagname) - check_cxx_compiler_flag("${flag}" "CXX_SUPPORTS_${flagname}_FLAG") - append_flags_if(CXX_SUPPORTS_${flagname}_FLAG ${DEST} ${flag}) - endforeach() -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(LIBUNWIND_NEEDS_SITE_CONFIG ON) - endif() -endmacro() - -macro(config_define_if_not condition def) - if (NOT ${condition}) - set(${def} ON) - set(LIBUNWIND_NEEDS_SITE_CONFIG ON) - endif() -endmacro() - -macro(config_define value def) - set(${def} ${value}) - set(LIBUNWIND_NEEDS_SITE_CONFIG ON) -endmacro() - -# Add a list of flags to all of 'CMAKE_CXX_FLAGS', 'CMAKE_C_FLAGS', -# 'LIBUNWIND_COMPILE_FLAGS' and 'LIBUNWIND_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 LIBUNWIND_COMPILE_FLAGS ${value}) - list(APPEND LIBUNWIND_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', 'LIBUNWIND_COMPILE_FLAGS' -# and 'LIBUNWIND_LINK_FLAGS'. -macro(add_target_flags_if condition) - if (${condition}) - add_target_flags(${ARGN}) - endif() -endmacro() - -# Add all the flags supported by the compiler to all of -# 'CMAKE_CXX_FLAGS', 'CMAKE_C_FLAGS', 'LIBUNWIND_COMPILE_FLAGS' -# and 'LIBUNWIND_LINK_FLAGS'. -macro(add_target_flags_if_supported) - foreach(flag ${ARGN}) - mangle_name("${flag}" flagname) - check_cxx_compiler_flag("${flag}" "CXX_SUPPORTS_${flagname}_FLAG") - add_target_flags_if(CXX_SUPPORTS_${flagname}_FLAG ${flag}) - endforeach() -endmacro() - -# Add a specified list of flags to both 'LIBUNWIND_COMPILE_FLAGS' and -# 'LIBUNWIND_LINK_FLAGS'. -macro(add_flags) - foreach(value ${ARGN}) - list(APPEND LIBUNWIND_COMPILE_FLAGS ${value}) - list(APPEND LIBUNWIND_LINK_FLAGS ${value}) - endforeach() -endmacro() - -# If the specified 'condition' is true then add a list of flags to both -# 'LIBUNWIND_COMPILE_FLAGS' and 'LIBUNWIND_LINK_FLAGS'. -macro(add_flags_if condition) - if (${condition}) - add_flags(${ARGN}) - endif() -endmacro() - -# Add each flag in the list to LIBUNWIND_COMPILE_FLAGS and LIBUNWIND_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}" "CXX_SUPPORTS_${flagname}_FLAG") - add_flags_if(CXX_SUPPORTS_${flagname}_FLAG ${flag}) - endforeach() -endmacro() - # Add a list of flags to 'LIBUNWIND_COMPILE_FLAGS'. macro(add_compile_flags) foreach(f ${ARGN}) @@ -202,16 +50,6 @@ macro(add_c_flags_if condition) endif() endmacro() -# For each specified flag, add that flag to 'LIBUNWIND_C_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}" "C_SUPPORTS_${flagname}_FLAG") - add_c_flags_if(C_SUPPORTS_${flagname}_FLAG ${flag}) - endforeach() -endmacro() - # Add a list of flags to 'LIBUNWIND_CXX_FLAGS'. macro(add_cxx_flags) foreach(f ${ARGN}) @@ -276,20 +114,3 @@ macro(add_library_flags_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() - -# For each specified flag, add that compile flag to the provided target. -# The flags are added with the given visibility, i.e. PUBLIC|PRIVATE|INTERFACE. -function(target_add_compile_flags_if_supported target visibility) - foreach(flag ${ARGN}) - mangle_name("${flag}" flagname) - check_cxx_compiler_flag("${flag}" "CXX_SUPPORTS_${flagname}_FLAG") - if (CXX_SUPPORTS_${flagname}_FLAG) - target_compile_options(${target} ${visibility} ${flag}) - endif() - endforeach() -endfunction() diff --git a/src/native/external/llvm-libunwind/cmake/config-ix.cmake b/src/native/external/llvm-libunwind/cmake/config-ix.cmake index d311477f02c69..126c872f0d489 100644 --- a/src/native/external/llvm-libunwind/cmake/config-ix.cmake +++ b/src/native/external/llvm-libunwind/cmake/config-ix.cmake @@ -11,7 +11,11 @@ include(CheckCSourceCompiles) # --unwindlib=none is supported, and use that if possible. llvm_check_compiler_linker_flag(C "--unwindlib=none" CXX_SUPPORTS_UNWINDLIB_EQ_NONE_FLAG) -check_library_exists(c fopen "" LIBUNWIND_HAS_C_LIB) +if (HAIKU) + check_library_exists(root fopen "" LIBUNWIND_HAS_ROOT_LIB) +else() + check_library_exists(c fopen "" LIBUNWIND_HAS_C_LIB) +endif() if (NOT LIBUNWIND_USE_COMPILER_RT) if (ANDROID) @@ -41,10 +45,15 @@ else() endif() endif() -if (CXX_SUPPORTS_NOSTDLIBXX_FLAG OR C_SUPPORTS_NODEFAULTLIBS_FLAG) +# Only link against compiler-rt manually if we use -nodefaultlibs, since +# otherwise the compiler will do the right thing on its own. +if (NOT CXX_SUPPORTS_NOSTDLIBXX_FLAG AND C_SUPPORTS_NODEFAULTLIBS_FLAG) if (LIBUNWIND_HAS_C_LIB) list(APPEND CMAKE_REQUIRED_LIBRARIES c) endif () + if (LIBUNWIND_HAS_ROOT_LIB) + list(APPEND CMAKE_REQUIRED_LIBRARIES root) + endif () if (LIBUNWIND_USE_COMPILER_RT) include(HandleCompilerRT) find_compiler_rt_library(builtins LIBUNWIND_BUILTINS_LIBRARY @@ -71,6 +80,9 @@ if (CXX_SUPPORTS_NOSTDLIBXX_FLAG OR C_SUPPORTS_NODEFAULTLIBS_FLAG) moldname mingwex msvcrt) list(APPEND CMAKE_REQUIRED_LIBRARIES ${MINGW_LIBRARIES}) endif() +endif() + +if (CXX_SUPPORTS_NOSTDLIBXX_FLAG OR C_SUPPORTS_NODEFAULTLIBS_FLAG) if (CMAKE_C_FLAGS MATCHES -fsanitize OR CMAKE_CXX_FLAGS MATCHES -fsanitize) set(CMAKE_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS} -fno-sanitize=all") endif () @@ -111,3 +123,7 @@ else() check_library_exists(dl dladdr "" LIBUNWIND_HAS_DL_LIB) check_library_exists(pthread pthread_once "" LIBUNWIND_HAS_PTHREAD_LIB) endif() + +if(HAIKU) + check_library_exists(bsd dl_iterate_phdr "" LIBUNWIND_HAS_BSD_LIB) +endif() diff --git a/src/native/external/llvm-libunwind/docs/conf.py b/src/native/external/llvm-libunwind/docs/conf.py index 404bcb0685759..29f9c24a7ee26 100644 --- a/src/native/external/llvm-libunwind/docs/conf.py +++ b/src/native/external/llvm-libunwind/docs/conf.py @@ -16,106 +16,106 @@ # 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('.')) +# sys.path.insert(0, os.path.abspath('.')) # -- General configuration ----------------------------------------------------- # If your documentation needs a minimal Sphinx version, state it here. -#needs_sphinx = '1.0' +# 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'] +extensions = ["sphinx.ext.intersphinx", "sphinx.ext.todo"] # Add any paths that contain templates here, relative to this directory. -templates_path = ['_templates'] +templates_path = ["_templates"] # The suffix of source filenames. -source_suffix = '.rst' +source_suffix = ".rst" # The encoding of source files. -#source_encoding = 'utf-8-sig' +# source_encoding = 'utf-8-sig' # The master toctree document. -master_doc = 'index' +master_doc = "index" # General information about the project. -project = u'libunwind' -copyright = u'2011-%d, LLVM Project' % date.today().year +project = "libunwind" +copyright = "2011-%d, LLVM Project" % date.today().year # 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 = '16.0' +version = "17.0" # The full version, including alpha/beta/rc tags. -release = '16.0' +release = "17.0" # The language for content autogenerated by Sphinx. Refer to documentation # for a list of supported languages. -#language = None +# language = None # There are two options for replacing |today|: either, you set today to some # non-false value, then it is used: -#today = '' +# today = '' # Else, today_fmt is used as the format for a strftime call. -today_fmt = '%Y-%m-%d' +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'] +exclude_patterns = ["_build"] # The reST default role (used for this markup: `text`) to use for all documents. -#default_role = None +# default_role = None # If true, '()' will be appended to :func: etc. cross-reference text. -#add_function_parentheses = True +# 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 +# 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' +pygments_style = "friendly" # A list of ignored prefixes for module index sorting. -#modindex_common_prefix = [] +# 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' +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 = {} +# html_theme_options = {} # Add any paths that contain custom themes here, relative to this directory. -#html_theme_path = [] +# html_theme_path = [] # The name for this set of Sphinx documents. If None, it defaults to # " v documentation". -#html_title = None +# html_title = None # A shorter title for the navigation bar. Default is the same as html_title. -#html_short_title = None +# 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 +# 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 +# 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, @@ -124,101 +124,95 @@ # 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' +# 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 +# html_use_smartypants = True # Custom sidebar templates, maps document names to template names. -#html_sidebars = {} +# html_sidebars = {} # Additional templates that should be rendered to pages, maps page names to # template names. -#html_additional_pages = {} +# html_additional_pages = {} # If false, no module index is generated. -#html_domain_indices = True +# html_domain_indices = True # If false, no index is generated. -#html_use_index = True +# html_use_index = True # If true, the index is split into individual pages for each letter. -#html_split_index = False +# html_split_index = False # If true, links to the reST sources are added to the pages. -#html_show_sourcelink = True +# html_show_sourcelink = True # If true, "Created using Sphinx" is shown in the HTML footer. Default is True. -#html_show_sphinx = True +# html_show_sphinx = True # If true, "(C) Copyright ..." is shown in the HTML footer. Default is True. -#html_show_copyright = True +# html_show_copyright = True # If true, an OpenSearch description file will be output, and all pages will # contain a tag referring to it. The value of this option must be the # base URL from which the finished HTML is served. -#html_use_opensearch = '' +# html_use_opensearch = '' # This is the file name suffix for HTML files (e.g. ".xhtml"). -#html_file_suffix = None +# html_file_suffix = None # Output file base name for HTML help builder. -htmlhelp_basename = 'libunwinddoc' +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': '', + # 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'), + ("contents", "libunwind.tex", "libunwind Documentation", "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 +# latex_logo = None # For "manual" documents, if this is true, then toplevel headings are parts, # not chapters. -#latex_use_parts = False +# latex_use_parts = False # If true, show page references after internal links. -#latex_show_pagerefs = False +# latex_show_pagerefs = False # If true, show URL addresses after external links. -#latex_show_urls = False +# latex_show_urls = False # Documents to append as an appendix to all manuals. -#latex_appendices = [] +# latex_appendices = [] # If false, no module index is generated. -#latex_domain_indices = True +# 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) -] +man_pages = [("contents", "libunwind", "libunwind Documentation", ["LLVM project"], 1)] # If true, show URL addresses after external links. -#man_show_urls = False +# man_show_urls = False # -- Options for Texinfo output ------------------------------------------------ @@ -227,19 +221,25 @@ # (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'), + ( + "contents", + "libunwind", + "libunwind Documentation", + "LLVM project", + "libunwind", + "LLVM Unwinder", + "Miscellaneous", + ), ] # Documents to append as an appendix to all manuals. -#texinfo_appendices = [] +# texinfo_appendices = [] # If false, no module index is generated. -#texinfo_domain_indices = True +# texinfo_domain_indices = True # How to display URL addresses: 'footnote', 'no', or 'inline'. -#texinfo_show_urls = 'footnote' +# texinfo_show_urls = 'footnote' # FIXME: Define intersphinx configuration. diff --git a/src/native/external/llvm-libunwind/include/__libunwind_config.h b/src/native/external/llvm-libunwind/include/__libunwind_config.h index b925489e3e7fe..8db336b2d727c 100644 --- a/src/native/external/llvm-libunwind/include/__libunwind_config.h +++ b/src/native/external/llvm-libunwind/include/__libunwind_config.h @@ -36,10 +36,13 @@ # if defined(__linux__) # define _LIBUNWIND_TARGET_LINUX 1 # endif +# if defined(__HAIKU__) +# define _LIBUNWIND_TARGET_HAIKU 1 +# endif # if defined(__i386__) # define _LIBUNWIND_TARGET_I386 -# define _LIBUNWIND_CONTEXT_SIZE 13 -# define _LIBUNWIND_CURSOR_SIZE 19 +# 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 @@ -51,8 +54,8 @@ # define _LIBUNWIND_CURSOR_SIZE 66 # endif # else -# define _LIBUNWIND_CONTEXT_SIZE 38 -# define _LIBUNWIND_CURSOR_SIZE 50 +# define _LIBUNWIND_CONTEXT_SIZE 21 +# define _LIBUNWIND_CURSOR_SIZE 33 # endif # define _LIBUNWIND_HIGHEST_DWARF_REGISTER _LIBUNWIND_HIGHEST_DWARF_REGISTER_X86_64 # elif defined(__powerpc64__) @@ -67,11 +70,11 @@ # define _LIBUNWIND_HIGHEST_DWARF_REGISTER _LIBUNWIND_HIGHEST_DWARF_REGISTER_PPC # elif defined(__aarch64__) # define _LIBUNWIND_TARGET_AARCH64 1 -# define _LIBUNWIND_CONTEXT_SIZE 100 +# define _LIBUNWIND_CONTEXT_SIZE 66 # if defined(__SEH__) -# define _LIBUNWIND_CURSOR_SIZE 198 +# define _LIBUNWIND_CURSOR_SIZE 164 # else -# define _LIBUNWIND_CURSOR_SIZE 112 +# define _LIBUNWIND_CURSOR_SIZE 78 # endif # define _LIBUNWIND_HIGHEST_DWARF_REGISTER _LIBUNWIND_HIGHEST_DWARF_REGISTER_ARM64 # elif defined(__arm__) @@ -83,8 +86,8 @@ # define _LIBUNWIND_CONTEXT_SIZE 61 # define _LIBUNWIND_CURSOR_SIZE 68 # else -# define _LIBUNWIND_CONTEXT_SIZE 50 -# define _LIBUNWIND_CURSOR_SIZE 57 +# define _LIBUNWIND_CONTEXT_SIZE 42 +# define _LIBUNWIND_CURSOR_SIZE 49 # endif # define _LIBUNWIND_HIGHEST_DWARF_REGISTER _LIBUNWIND_HIGHEST_DWARF_REGISTER_ARM # elif defined(__or1k__) @@ -172,11 +175,6 @@ #if __loongarch_grlen == 64 #define _LIBUNWIND_CONTEXT_SIZE 65 #define _LIBUNWIND_CURSOR_SIZE 77 -#elif defined(HOST_WASM) -#define _LIBUNWIND_TARGET_WASM 1 -// TODO: Determine the right values -#define _LIBUNWIND_CONTEXT_SIZE 0xbadf00d -#define _LIBUNWIND_CURSOR_SIZE 0xbadf00d #else #error "Unsupported LoongArch ABI" #endif @@ -201,9 +199,9 @@ # define _LIBUNWIND_TARGET_RISCV 1 # define _LIBUNWIND_TARGET_VE 1 # define _LIBUNWIND_TARGET_S390X 1 -#define _LIBUNWIND_TARGET_LOONGARCH 1 +# define _LIBUNWIND_TARGET_LOONGARCH 1 # define _LIBUNWIND_CONTEXT_SIZE 167 -# define _LIBUNWIND_CURSOR_SIZE 179 +# define _LIBUNWIND_CURSOR_SIZE 204 # define _LIBUNWIND_HIGHEST_DWARF_REGISTER 287 #endif // _LIBUNWIND_IS_NATIVE_ONLY diff --git a/src/native/external/llvm-libunwind/include/libunwind.h b/src/native/external/llvm-libunwind/include/libunwind.h index 1c5320c1aea8b..b2dae8feed9a3 100644 --- a/src/native/external/llvm-libunwind/include/libunwind.h +++ b/src/native/external/llvm-libunwind/include/libunwind.h @@ -102,26 +102,6 @@ struct unw_proc_info_t { }; typedef struct unw_proc_info_t unw_proc_info_t; -enum unw_save_loc_type_t -{ - UNW_SLT_NONE, /* register is not saved ("not an l-value") */ - UNW_SLT_MEMORY, /* register has been saved in memory */ - UNW_SLT_REG /* register has been saved in (another) register */ -}; -typedef enum unw_save_loc_type_t unw_save_loc_type_t; - -struct unw_save_loc_t -{ - unw_save_loc_type_t type; - union - { - unw_word_t addr; /* valid if type==UNW_SLT_MEMORY */ - unw_regnum_t regnum; /* valid if type==UNW_SLT_REG */ - } - u; -}; -typedef struct unw_save_loc_t unw_save_loc_t; - #ifdef __cplusplus extern "C" { #endif @@ -131,7 +111,7 @@ 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, unw_word_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; @@ -149,7 +129,7 @@ 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*) 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; @@ -896,6 +876,9 @@ enum { UNW_MIPS_F29 = 61, UNW_MIPS_F30 = 62, UNW_MIPS_F31 = 63, + // HI,LO have been dropped since r6, we keep them here. + // So, when we add DSP/MSA etc, we can use the same register indexes + // for r6 and pre-r6. UNW_MIPS_HI = 64, UNW_MIPS_LO = 65, }; diff --git a/src/native/external/llvm-libunwind/include/unwind_arm_ehabi.h b/src/native/external/llvm-libunwind/include/unwind_arm_ehabi.h index 5fa94a167ff10..6277a1457f896 100644 --- a/src/native/external/llvm-libunwind/include/unwind_arm_ehabi.h +++ b/src/native/external/llvm-libunwind/include/unwind_arm_ehabi.h @@ -118,7 +118,7 @@ _Unwind_VRS_Get(_Unwind_Context *context, _Unwind_VRS_RegClass regclass, extern _Unwind_VRS_Result _Unwind_VRS_Set(_Unwind_Context *context, _Unwind_VRS_RegClass regclass, uint32_t regno, _Unwind_VRS_DataRepresentation representation, - void *valuep, uintptr_t *pos); + void *valuep); extern _Unwind_VRS_Result _Unwind_VRS_Pop(_Unwind_Context *context, _Unwind_VRS_RegClass regclass, @@ -147,8 +147,8 @@ uintptr_t _Unwind_GetGR(struct _Unwind_Context *context, int index) { _LIBUNWIND_EXPORT_UNWIND_LEVEL1 void _Unwind_SetGR(struct _Unwind_Context *context, int index, - uintptr_t value, uintptr_t *pos) { - _Unwind_VRS_Set(context, _UVRSC_CORE, (uint32_t)index, _UVRSD_UINT32, &value, pos); + uintptr_t value) { + _Unwind_VRS_Set(context, _UVRSC_CORE, (uint32_t)index, _UVRSD_UINT32, &value); } _LIBUNWIND_EXPORT_UNWIND_LEVEL1 @@ -160,7 +160,7 @@ uintptr_t _Unwind_GetIP(struct _Unwind_Context *context) { _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, NULL); + _Unwind_SetGR(context, 15, value | thumb_bit); } #ifdef __cplusplus diff --git a/src/native/external/llvm-libunwind/include/unwind_itanium.h b/src/native/external/llvm-libunwind/include/unwind_itanium.h index 7e813c7c2b07a..d94a6183be290 100644 --- a/src/native/external/llvm-libunwind/include/unwind_itanium.h +++ b/src/native/external/llvm-libunwind/include/unwind_itanium.h @@ -65,7 +65,7 @@ extern void _Unwind_DeleteException(_Unwind_Exception *exception_object); 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, uintptr_t *pos); + uintptr_t new_value); extern uintptr_t _Unwind_GetIP(struct _Unwind_Context *context); extern void _Unwind_SetIP(struct _Unwind_Context *, uintptr_t new_value); diff --git a/src/native/external/llvm-libunwind/src/AddressSpace.hpp b/src/native/external/llvm-libunwind/src/AddressSpace.hpp index dff3249bf9bfc..5551c7d4bef1c 100644 --- a/src/native/external/llvm-libunwind/src/AddressSpace.hpp +++ b/src/native/external/llvm-libunwind/src/AddressSpace.hpp @@ -66,6 +66,10 @@ char *getFuncNameFromTBTable(uintptr_t pc, uint16_t &NameLen, // In 10.7.0 or later, libSystem.dylib implements this function. extern "C" bool _dyld_find_unwind_sections(void *, dyld_unwind_sections *); +namespace libunwind { + bool findDynamicUnwindSections(void *, unw_dynamic_unwind_sections *); +} + #elif defined(_LIBUNWIND_SUPPORT_DWARF_UNWIND) && defined(_LIBUNWIND_IS_BAREMETAL) // When statically linked on bare-metal, the symbols for the EH table are looked @@ -410,8 +414,8 @@ static bool checkForUnwindInfoSegment(const Elf_Phdr *phdr, size_t image_base, cbdata->sects->dwarf_index_section = eh_frame_hdr_start; cbdata->sects->dwarf_index_section_length = phdr->p_memsz; if (EHHeaderParser::decodeEHHdr( - *cbdata->addressSpace, eh_frame_hdr_start, phdr->p_memsz, - hdrInfo)) { + *cbdata->addressSpace, eh_frame_hdr_start, + eh_frame_hdr_start + phdr->p_memsz, hdrInfo)) { // .eh_frame_hdr records the start of .eh_frame, but not its size. // Rely on a zero terminator to find the end of the section. cbdata->sects->dwarf_section = hdrInfo.eh_frame_ptr; @@ -497,6 +501,22 @@ inline bool LocalAddressSpace::findUnwindSections(pint_t targetAddr, info.compact_unwind_section_length = (size_t)dyldInfo.compact_unwind_section_length; return true; } + + unw_dynamic_unwind_sections dynamicUnwindSectionInfo; + if (findDynamicUnwindSections((void *)targetAddr, + &dynamicUnwindSectionInfo)) { + info.dso_base = dynamicUnwindSectionInfo.dso_base; +#if defined(_LIBUNWIND_SUPPORT_DWARF_UNWIND) + info.dwarf_section = (uintptr_t)dynamicUnwindSectionInfo.dwarf_section; + info.dwarf_section_length = dynamicUnwindSectionInfo.dwarf_section_length; +#endif + info.compact_unwind_section = + (uintptr_t)dynamicUnwindSectionInfo.compact_unwind_section; + info.compact_unwind_section_length = + dynamicUnwindSectionInfo.compact_unwind_section_length; + return true; + } + #elif defined(_LIBUNWIND_SUPPORT_DWARF_UNWIND) && defined(_LIBUNWIND_IS_BAREMETAL) info.dso_base = 0; // Bare metal is statically linked, so no need to ask the dynamic loader @@ -583,7 +603,11 @@ inline bool LocalAddressSpace::findUnwindSections(pint_t targetAddr, // `_dl_find_object`. Use _LIBUNWIND_SUPPORT_DWARF_INDEX, because libunwind // support for _dl_find_object on other unwind formats is not implemented, // yet. -#if defined(DLFO_STRUCT_HAS_EH_DBASE) && defined(_LIBUNWIND_SUPPORT_DWARF_INDEX) && DLFO_EH_SEGMENT_TYPE == PT_GNU_EH_FRAME +#if defined(DLFO_STRUCT_HAS_EH_DBASE) & defined(_LIBUNWIND_SUPPORT_DWARF_INDEX) + // We expect `_dl_find_object` to return PT_GNU_EH_FRAME. +#if DLFO_EH_SEGMENT_TYPE != PT_GNU_EH_FRAME +#error _dl_find_object retrieves an unexpected section type +#endif // We look-up `dl_find_object` dynamically at runtime to ensure backwards // compatibility with earlier version of glibc not yet providing it. On older // systems, we gracefully fallback to `dl_iterate_phdr`. Cache the pointer @@ -614,7 +638,8 @@ inline bool LocalAddressSpace::findUnwindSections(pint_t targetAddr, info.dwarf_index_section_length = SIZE_MAX; EHHeaderParser::EHHeaderInfo hdrInfo; if (!EHHeaderParser::decodeEHHdr( - *this, info.dwarf_index_section, info.dwarf_index_section_length, + *this, info.dwarf_index_section, + info.dwarf_index_section + info.dwarf_index_section_length, hdrInfo)) { return false; } diff --git a/src/native/external/llvm-libunwind/src/CMakeLists.txt b/src/native/external/llvm-libunwind/src/CMakeLists.txt index df32e53d69e6e..780430ba70ba6 100644 --- a/src/native/external/llvm-libunwind/src/CMakeLists.txt +++ b/src/native/external/llvm-libunwind/src/CMakeLists.txt @@ -5,11 +5,6 @@ set(LIBUNWIND_CXX_SOURCES Unwind-EHABI.cpp Unwind-seh.cpp ) -if(APPLE) - list(APPEND LIBUNWIND_CXX_SOURCES - Unwind_AppleExtras.cpp - ) -endif() if(${CMAKE_SYSTEM_NAME} MATCHES "AIX") list(APPEND LIBUNWIND_CXX_SOURCES @@ -21,6 +16,7 @@ set(LIBUNWIND_C_SOURCES UnwindLevel1.c UnwindLevel1-gcc-ext.c Unwind-sjlj.c + Unwind-wasm.c ) set_source_files_properties(${LIBUNWIND_C_SOURCES} PROPERTIES @@ -31,15 +27,6 @@ set(LIBUNWIND_ASM_SOURCES UnwindRegistersSave.S ) -# See add_asm_sources() in compiler-rt for explanation of this workaround. -# CMake doesn't work correctly with assembly on AIX. Workaround by compiling -# as C files as well. -if((APPLE AND CMAKE_VERSION VERSION_LESS 3.19) OR - (MINGW AND CMAKE_VERSION VERSION_LESS 3.17) OR - (${CMAKE_SYSTEM_NAME} MATCHES "AIX")) - set_source_files_properties(${LIBUNWIND_ASM_SOURCES} PROPERTIES LANGUAGE C) -endif() - set(LIBUNWIND_HEADERS AddressSpace.hpp assembly.h @@ -79,26 +66,32 @@ set(LIBUNWIND_SOURCES ${LIBUNWIND_ASM_SOURCES}) # Generate library list. -add_library_flags_if(LIBUNWIND_HAS_C_LIB c) -if (LIBUNWIND_USE_COMPILER_RT) - add_library_flags("${LIBUNWIND_BUILTINS_LIBRARY}") +if (CXX_SUPPORTS_NOSTDLIBXX_FLAG) + add_link_flags_if_supported(-nostdlib++) else() - add_library_flags_if(LIBUNWIND_HAS_GCC_S_LIB gcc_s) - add_library_flags_if(LIBUNWIND_HAS_GCC_LIB gcc) + if (LIBUNWIND_USE_COMPILER_RT) + add_library_flags("${LIBUNWIND_BUILTINS_LIBRARY}") + else() + add_library_flags_if(LIBUNWIND_HAS_GCC_S_LIB gcc_s) + add_library_flags_if(LIBUNWIND_HAS_GCC_LIB gcc) + endif() + add_library_flags_if(LIBUNWIND_HAS_C_LIB c) +endif() + +if (NOT APPLE) + add_library_flags_if(LIBUNWIND_HAS_DL_LIB dl) +endif() + +if (LIBUNWIND_ENABLE_THREADS AND NOT APPLE) + add_library_flags_if(LIBUNWIND_HAS_PTHREAD_LIB pthread) endif() -add_library_flags_if(LIBUNWIND_HAS_DL_LIB dl) + if (LIBUNWIND_ENABLE_THREADS) - add_library_flags_if(LIBUNWIND_HAS_PTHREAD_LIB pthread) add_compile_flags_if(LIBUNWIND_WEAK_PTHREAD_LIB -DLIBUNWIND_USE_WEAK_PTHREAD=1) endif() # Setup flags. add_link_flags_if(CXX_SUPPORTS_UNWINDLIB_EQ_NONE_FLAG --unwindlib=none) -if (CXX_SUPPORTS_NOSTDLIBXX_FLAG) - add_link_flags_if_supported(-nostdlib++) -else() - add_link_flags_if_supported(-nodefaultlibs) -endif() # MINGW_LIBRARIES is defined in config-ix.cmake add_library_flags_if(MINGW "${MINGW_LIBRARIES}") @@ -121,6 +114,16 @@ if (APPLE) endif () endif () +if (HAIKU) + add_library_flags_if(LIBUNWIND_HAS_ROOT_LIB root) + + add_library_flags_if(LIBUNWIND_HAS_BSD_LIB bsd) + add_compile_flags_if(LIBUNWIND_HAS_BSD_LIB -D_LIBUNWIND_USE_HAIKU_BSD_LIB=1) + + add_compile_flags("-D_DEFAULT_SOURCE") + add_compile_flags("-DPT_GNU_EH_FRAME=PT_EH_FRAME") +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}") @@ -135,18 +138,23 @@ set_property(SOURCE ${LIBUNWIND_C_SOURCES} # ease, but does not rely on C++ at runtime. set(CMAKE_CXX_IMPLICIT_LINK_LIBRARIES "") +include(WarningFlags) + # Build the shared library. add_library(unwind_shared_objects OBJECT EXCLUDE_FROM_ALL ${LIBUNWIND_SOURCES} ${LIBUNWIND_HEADERS}) +cxx_add_warning_flags(unwind_shared_objects ${LIBUNWIND_ENABLE_WERROR} ${LIBUNWIND_ENABLE_PEDANTIC}) if(CMAKE_C_COMPILER_ID STREQUAL MSVC) target_compile_options(unwind_shared_objects PRIVATE /GR-) else() target_compile_options(unwind_shared_objects PRIVATE -fno-rtti) endif() target_link_libraries(unwind_shared_objects PRIVATE unwind-headers ${LIBUNWIND_LIBRARIES}) +target_compile_options(unwind_shared_objects PUBLIC "${LIBUNWIND_ADDITIONAL_COMPILE_FLAGS}") +target_link_libraries(unwind_shared_objects PUBLIC "${LIBUNWIND_ADDITIONAL_LIBRARIES}") set_target_properties(unwind_shared_objects PROPERTIES CXX_EXTENSIONS OFF - CXX_STANDARD 11 + CXX_STANDARD 17 CXX_STANDARD_REQUIRED ON COMPILE_FLAGS "${LIBUNWIND_COMPILE_FLAGS}" ) @@ -174,23 +182,29 @@ endif() # Build the static library. add_library(unwind_static_objects OBJECT EXCLUDE_FROM_ALL ${LIBUNWIND_SOURCES} ${LIBUNWIND_HEADERS}) +cxx_add_warning_flags(unwind_static_objects ${LIBUNWIND_ENABLE_WERROR} ${LIBUNWIND_ENABLE_PEDANTIC}) if(CMAKE_C_COMPILER_ID STREQUAL MSVC) target_compile_options(unwind_static_objects PRIVATE /GR-) else() target_compile_options(unwind_static_objects PRIVATE -fno-rtti) endif() target_link_libraries(unwind_static_objects PRIVATE unwind-headers ${LIBUNWIND_LIBRARIES}) +target_compile_options(unwind_static_objects PUBLIC "${LIBUNWIND_ADDITIONAL_COMPILE_FLAGS}") +target_link_libraries(unwind_static_objects PUBLIC "${LIBUNWIND_ADDITIONAL_LIBRARIES}") set_target_properties(unwind_static_objects PROPERTIES CXX_EXTENSIONS OFF - CXX_STANDARD 11 + CXX_STANDARD 17 CXX_STANDARD_REQUIRED ON COMPILE_FLAGS "${LIBUNWIND_COMPILE_FLAGS}" ) if(LIBUNWIND_HIDE_SYMBOLS) target_add_compile_flags_if_supported(unwind_static_objects PRIVATE -fvisibility=hidden) - target_add_compile_flags_if_supported(unwind_static_objects PRIVATE -fvisibility-global-new-delete-hidden) + target_add_compile_flags_if_supported(unwind_static_objects PRIVATE -fvisibility-global-new-delete=force-hidden) + if (NOT CXX_SUPPORTS_FVISIBILITY_GLOBAL_NEW_DELETE_EQ_FORCE_HIDDEN_FLAG) + target_add_compile_flags_if_supported(unwind_static_objects PRIVATE -fvisibility-global-new-delete-hidden) + endif() target_compile_definitions(unwind_static_objects PRIVATE _LIBUNWIND_HIDE_SYMBOLS) endif() diff --git a/src/native/external/llvm-libunwind/src/CompactUnwinder.hpp b/src/native/external/llvm-libunwind/src/CompactUnwinder.hpp index 5cb825e2fd3e9..a7a8a153d86a4 100644 --- a/src/native/external/llvm-libunwind/src/CompactUnwinder.hpp +++ b/src/native/external/llvm-libunwind/src/CompactUnwinder.hpp @@ -29,34 +29,34 @@ 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 +template class CompactUnwinder_x86 { public: static int stepWithCompactEncoding(compact_unwind_encoding_t info, uint32_t functionStart, A &addressSpace, - R ®isters); + Registers_x86 ®isters); private: typename A::pint_t pint_t; - static void frameUnwind(A &addressSpace, R ®isters); + static void frameUnwind(A &addressSpace, Registers_x86 ®isters); static void framelessUnwind(A &addressSpace, typename A::pint_t returnAddressLocation, - R ®isters); + Registers_x86 ®isters); static int stepWithCompactEncodingEBPFrame(compact_unwind_encoding_t compactEncoding, uint32_t functionStart, A &addressSpace, - R ®isters); + Registers_x86 ®isters); static int stepWithCompactEncodingFrameless( compact_unwind_encoding_t compactEncoding, uint32_t functionStart, - A &addressSpace, R ®isters, bool indirectStackSize); + A &addressSpace, Registers_x86 ®isters, bool indirectStackSize); }; -template -int CompactUnwinder_x86::stepWithCompactEncoding( +template +int CompactUnwinder_x86::stepWithCompactEncoding( compact_unwind_encoding_t compactEncoding, uint32_t functionStart, - A &addressSpace, R ®isters) { + A &addressSpace, Registers_x86 ®isters) { switch (compactEncoding & UNWIND_X86_MODE_MASK) { case UNWIND_X86_MODE_EBP_FRAME: return stepWithCompactEncodingEBPFrame(compactEncoding, functionStart, @@ -71,10 +71,10 @@ int CompactUnwinder_x86::stepWithCompactEncoding( _LIBUNWIND_ABORT("invalid compact unwind encoding"); } -template -int CompactUnwinder_x86::stepWithCompactEncodingEBPFrame( +template +int CompactUnwinder_x86::stepWithCompactEncodingEBPFrame( compact_unwind_encoding_t compactEncoding, uint32_t functionStart, - A &addressSpace, R ®isters) { + A &addressSpace, Registers_x86 ®isters) { uint32_t savedRegistersOffset = EXTRACT_BITS(compactEncoding, UNWIND_X86_EBP_FRAME_OFFSET); uint32_t savedRegistersLocations = @@ -87,19 +87,19 @@ int CompactUnwinder_x86::stepWithCompactEncodingEBPFrame( // no register saved in this slot break; case UNWIND_X86_REG_EBX: - registers.setEBX(addressSpace.get32(savedRegisters), savedRegisters); + registers.setEBX(addressSpace.get32(savedRegisters)); break; case UNWIND_X86_REG_ECX: - registers.setECX(addressSpace.get32(savedRegisters), savedRegisters); + registers.setECX(addressSpace.get32(savedRegisters)); break; case UNWIND_X86_REG_EDX: - registers.setEDX(addressSpace.get32(savedRegisters), savedRegisters); + registers.setEDX(addressSpace.get32(savedRegisters)); break; case UNWIND_X86_REG_EDI: - registers.setEDI(addressSpace.get32(savedRegisters), savedRegisters); + registers.setEDI(addressSpace.get32(savedRegisters)); break; case UNWIND_X86_REG_ESI: - registers.setESI(addressSpace.get32(savedRegisters), savedRegisters); + registers.setESI(addressSpace.get32(savedRegisters)); break; default: (void)functionStart; @@ -115,10 +115,10 @@ int CompactUnwinder_x86::stepWithCompactEncodingEBPFrame( return UNW_STEP_SUCCESS; } -template -int CompactUnwinder_x86::stepWithCompactEncodingFrameless( +template +int CompactUnwinder_x86::stepWithCompactEncodingFrameless( compact_unwind_encoding_t encoding, uint32_t functionStart, - A &addressSpace, R ®isters, bool indirectStackSize) { + A &addressSpace, Registers_x86 ®isters, bool indirectStackSize) { uint32_t stackSizeEncoded = EXTRACT_BITS(encoding, UNWIND_X86_FRAMELESS_STACK_SIZE); uint32_t stackAdjust = @@ -204,22 +204,22 @@ int CompactUnwinder_x86::stepWithCompactEncodingFrameless( for (uint32_t i = 0; i < regCount; ++i) { switch (registersSaved[i]) { case UNWIND_X86_REG_EBX: - registers.setEBX(addressSpace.get32(savedRegisters), savedRegisters); + registers.setEBX(addressSpace.get32(savedRegisters)); break; case UNWIND_X86_REG_ECX: - registers.setECX(addressSpace.get32(savedRegisters), savedRegisters); + registers.setECX(addressSpace.get32(savedRegisters)); break; case UNWIND_X86_REG_EDX: - registers.setEDX(addressSpace.get32(savedRegisters), savedRegisters); + registers.setEDX(addressSpace.get32(savedRegisters)); break; case UNWIND_X86_REG_EDI: - registers.setEDI(addressSpace.get32(savedRegisters), savedRegisters); + registers.setEDI(addressSpace.get32(savedRegisters)); break; case UNWIND_X86_REG_ESI: - registers.setESI(addressSpace.get32(savedRegisters), savedRegisters); + registers.setESI(addressSpace.get32(savedRegisters)); break; case UNWIND_X86_REG_EBP: - registers.setEBP(addressSpace.get32(savedRegisters), savedRegisters); + registers.setEBP(addressSpace.get32(savedRegisters)); break; default: _LIBUNWIND_DEBUG_LOG("bad register for frameless, encoding=%08X for " @@ -234,26 +234,26 @@ int CompactUnwinder_x86::stepWithCompactEncodingFrameless( } -template -void CompactUnwinder_x86::frameUnwind(A &addressSpace, - R ®isters) { +template +void CompactUnwinder_x86::frameUnwind(A &addressSpace, + Registers_x86 ®isters) { typename A::pint_t bp = registers.getEBP(); // ebp points to old ebp - registers.setEBP(addressSpace.get32(bp), bp); + registers.setEBP(addressSpace.get32(bp)); // old esp is ebp less saved ebp and return address - registers.setSP((uint32_t)bp + 8, 0); + registers.setSP((uint32_t)bp + 8); // pop return address into eip - registers.setIP(addressSpace.get32(bp + 4), bp + 4); + registers.setIP(addressSpace.get32(bp + 4)); } -template -void CompactUnwinder_x86::framelessUnwind( +template +void CompactUnwinder_x86::framelessUnwind( A &addressSpace, typename A::pint_t returnAddressLocation, - R ®isters) { + Registers_x86 ®isters) { // return address is on stack after last saved register - registers.setIP(addressSpace.get32(returnAddressLocation), returnAddressLocation); + registers.setIP(addressSpace.get32(returnAddressLocation)); // old esp is before return address - registers.setSP((uint32_t)returnAddressLocation + 4, 0); + registers.setSP((uint32_t)returnAddressLocation + 4); } #endif // _LIBUNWIND_TARGET_I386 @@ -261,33 +261,33 @@ void CompactUnwinder_x86::framelessUnwind( #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 +template class CompactUnwinder_x86_64 { public: static int stepWithCompactEncoding(compact_unwind_encoding_t compactEncoding, uint64_t functionStart, A &addressSpace, - R ®isters); + Registers_x86_64 ®isters); private: typename A::pint_t pint_t; - static void frameUnwind(A &addressSpace, R ®isters); + static void frameUnwind(A &addressSpace, Registers_x86_64 ®isters); static void framelessUnwind(A &addressSpace, uint64_t returnAddressLocation, - R ®isters); + Registers_x86_64 ®isters); static int stepWithCompactEncodingRBPFrame(compact_unwind_encoding_t compactEncoding, uint64_t functionStart, A &addressSpace, - R ®isters); + Registers_x86_64 ®isters); static int stepWithCompactEncodingFrameless( compact_unwind_encoding_t compactEncoding, uint64_t functionStart, - A &addressSpace, R ®isters, bool indirectStackSize); + A &addressSpace, Registers_x86_64 ®isters, bool indirectStackSize); }; -template -int CompactUnwinder_x86_64::stepWithCompactEncoding( +template +int CompactUnwinder_x86_64::stepWithCompactEncoding( compact_unwind_encoding_t compactEncoding, uint64_t functionStart, - A &addressSpace, R ®isters) { + A &addressSpace, Registers_x86_64 ®isters) { switch (compactEncoding & UNWIND_X86_64_MODE_MASK) { case UNWIND_X86_64_MODE_RBP_FRAME: return stepWithCompactEncodingRBPFrame(compactEncoding, functionStart, @@ -302,10 +302,10 @@ int CompactUnwinder_x86_64::stepWithCompactEncoding( _LIBUNWIND_ABORT("invalid compact unwind encoding"); } -template -int CompactUnwinder_x86_64::stepWithCompactEncodingRBPFrame( +template +int CompactUnwinder_x86_64::stepWithCompactEncodingRBPFrame( compact_unwind_encoding_t compactEncoding, uint64_t functionStart, - A &addressSpace, R ®isters) { + A &addressSpace, Registers_x86_64 ®isters) { uint32_t savedRegistersOffset = EXTRACT_BITS(compactEncoding, UNWIND_X86_64_RBP_FRAME_OFFSET); uint32_t savedRegistersLocations = @@ -318,19 +318,19 @@ int CompactUnwinder_x86_64::stepWithCompactEncodingRBPFrame( // no register saved in this slot break; case UNWIND_X86_64_REG_RBX: - registers.setRBX(addressSpace.get64(savedRegisters), savedRegisters); + registers.setRBX(addressSpace.get64(savedRegisters)); break; case UNWIND_X86_64_REG_R12: - registers.setR12(addressSpace.get64(savedRegisters), savedRegisters); + registers.setR12(addressSpace.get64(savedRegisters)); break; case UNWIND_X86_64_REG_R13: - registers.setR13(addressSpace.get64(savedRegisters), savedRegisters); + registers.setR13(addressSpace.get64(savedRegisters)); break; case UNWIND_X86_64_REG_R14: - registers.setR14(addressSpace.get64(savedRegisters), savedRegisters); + registers.setR14(addressSpace.get64(savedRegisters)); break; case UNWIND_X86_64_REG_R15: - registers.setR15(addressSpace.get64(savedRegisters), savedRegisters); + registers.setR15(addressSpace.get64(savedRegisters)); break; default: (void)functionStart; @@ -346,10 +346,10 @@ int CompactUnwinder_x86_64::stepWithCompactEncodingRBPFrame( return UNW_STEP_SUCCESS; } -template -int CompactUnwinder_x86_64::stepWithCompactEncodingFrameless( +template +int CompactUnwinder_x86_64::stepWithCompactEncodingFrameless( compact_unwind_encoding_t encoding, uint64_t functionStart, A &addressSpace, - R ®isters, bool indirectStackSize) { + Registers_x86_64 ®isters, bool indirectStackSize) { uint32_t stackSizeEncoded = EXTRACT_BITS(encoding, UNWIND_X86_64_FRAMELESS_STACK_SIZE); uint32_t stackAdjust = @@ -435,22 +435,22 @@ int CompactUnwinder_x86_64::stepWithCompactEncodingFrameless( for (uint32_t i = 0; i < regCount; ++i) { switch (registersSaved[i]) { case UNWIND_X86_64_REG_RBX: - registers.setRBX(addressSpace.get64(savedRegisters), savedRegisters); + registers.setRBX(addressSpace.get64(savedRegisters)); break; case UNWIND_X86_64_REG_R12: - registers.setR12(addressSpace.get64(savedRegisters), savedRegisters); + registers.setR12(addressSpace.get64(savedRegisters)); break; case UNWIND_X86_64_REG_R13: - registers.setR13(addressSpace.get64(savedRegisters), savedRegisters); + registers.setR13(addressSpace.get64(savedRegisters)); break; case UNWIND_X86_64_REG_R14: - registers.setR14(addressSpace.get64(savedRegisters), savedRegisters); + registers.setR14(addressSpace.get64(savedRegisters)); break; case UNWIND_X86_64_REG_R15: - registers.setR15(addressSpace.get64(savedRegisters), savedRegisters); + registers.setR15(addressSpace.get64(savedRegisters)); break; case UNWIND_X86_64_REG_RBP: - registers.setRBP(addressSpace.get64(savedRegisters), savedRegisters); + registers.setRBP(addressSpace.get64(savedRegisters)); break; default: _LIBUNWIND_DEBUG_LOG("bad register for frameless, encoding=%08X for " @@ -465,26 +465,26 @@ int CompactUnwinder_x86_64::stepWithCompactEncodingFrameless( } -template -void CompactUnwinder_x86_64::frameUnwind(A &addressSpace, - R ®isters) { +template +void CompactUnwinder_x86_64::frameUnwind(A &addressSpace, + Registers_x86_64 ®isters) { uint64_t rbp = registers.getRBP(); // ebp points to old ebp - registers.setRBP(addressSpace.get64(rbp), rbp); + registers.setRBP(addressSpace.get64(rbp)); // old esp is ebp less saved ebp and return address - registers.setSP(rbp + 16, 0); + registers.setSP(rbp + 16); // pop return address into eip - registers.setIP(addressSpace.get64(rbp + 8), rbp + 8); + registers.setIP(addressSpace.get64(rbp + 8)); } -template -void CompactUnwinder_x86_64::framelessUnwind(A &addressSpace, - uint64_t returnAddressLocation, - R ®isters) { +template +void CompactUnwinder_x86_64::framelessUnwind(A &addressSpace, + uint64_t returnAddressLocation, + Registers_x86_64 ®isters) { // return address is on stack after last saved register - registers.setIP(addressSpace.get64(returnAddressLocation), returnAddressLocation); + registers.setIP(addressSpace.get64(returnAddressLocation)); // old esp is before return address - registers.setSP(returnAddressLocation + 8, 0); + registers.setSP(returnAddressLocation + 8); } #endif // _LIBUNWIND_TARGET_X86_64 @@ -493,13 +493,13 @@ void CompactUnwinder_x86_64::framelessUnwind(A &addressSpace, #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 +template class CompactUnwinder_arm64 { public: static int stepWithCompactEncoding(compact_unwind_encoding_t compactEncoding, uint64_t functionStart, A &addressSpace, - R ®isters); + Registers_arm64 ®isters); private: typename A::pint_t pint_t; @@ -507,16 +507,16 @@ class CompactUnwinder_arm64 { static int stepWithCompactEncodingFrame(compact_unwind_encoding_t compactEncoding, uint64_t functionStart, A &addressSpace, - R ®isters); + Registers_arm64 ®isters); static int stepWithCompactEncodingFrameless( compact_unwind_encoding_t compactEncoding, uint64_t functionStart, - A &addressSpace, R ®isters); + A &addressSpace, Registers_arm64 ®isters); }; -template -int CompactUnwinder_arm64::stepWithCompactEncoding( +template +int CompactUnwinder_arm64::stepWithCompactEncoding( compact_unwind_encoding_t compactEncoding, uint64_t functionStart, - A &addressSpace, R ®isters) { + A &addressSpace, Registers_arm64 ®isters) { switch (compactEncoding & UNWIND_ARM64_MODE_MASK) { case UNWIND_ARM64_MODE_FRAME: return stepWithCompactEncodingFrame(compactEncoding, functionStart, @@ -528,43 +528,43 @@ int CompactUnwinder_arm64::stepWithCompactEncoding( _LIBUNWIND_ABORT("invalid compact unwind encoding"); } -template -int CompactUnwinder_arm64::stepWithCompactEncodingFrameless( +template +int CompactUnwinder_arm64::stepWithCompactEncodingFrameless( compact_unwind_encoding_t encoding, uint64_t, A &addressSpace, - R ®isters) { + 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_AARCH64_X19, addressSpace.get64(savedRegisterLoc), savedRegisterLoc); + registers.setRegister(UNW_AARCH64_X19, addressSpace.get64(savedRegisterLoc)); savedRegisterLoc -= 8; - registers.setRegister(UNW_AARCH64_X20, addressSpace.get64(savedRegisterLoc), savedRegisterLoc); + registers.setRegister(UNW_AARCH64_X20, addressSpace.get64(savedRegisterLoc)); savedRegisterLoc -= 8; } if (encoding & UNWIND_ARM64_FRAME_X21_X22_PAIR) { - registers.setRegister(UNW_AARCH64_X21, addressSpace.get64(savedRegisterLoc), savedRegisterLoc); + registers.setRegister(UNW_AARCH64_X21, addressSpace.get64(savedRegisterLoc)); savedRegisterLoc -= 8; - registers.setRegister(UNW_AARCH64_X22, addressSpace.get64(savedRegisterLoc), savedRegisterLoc); + registers.setRegister(UNW_AARCH64_X22, addressSpace.get64(savedRegisterLoc)); savedRegisterLoc -= 8; } if (encoding & UNWIND_ARM64_FRAME_X23_X24_PAIR) { - registers.setRegister(UNW_AARCH64_X23, addressSpace.get64(savedRegisterLoc), savedRegisterLoc); + registers.setRegister(UNW_AARCH64_X23, addressSpace.get64(savedRegisterLoc)); savedRegisterLoc -= 8; - registers.setRegister(UNW_AARCH64_X24, addressSpace.get64(savedRegisterLoc), savedRegisterLoc); + registers.setRegister(UNW_AARCH64_X24, addressSpace.get64(savedRegisterLoc)); savedRegisterLoc -= 8; } if (encoding & UNWIND_ARM64_FRAME_X25_X26_PAIR) { - registers.setRegister(UNW_AARCH64_X25, addressSpace.get64(savedRegisterLoc), savedRegisterLoc); + registers.setRegister(UNW_AARCH64_X25, addressSpace.get64(savedRegisterLoc)); savedRegisterLoc -= 8; - registers.setRegister(UNW_AARCH64_X26, addressSpace.get64(savedRegisterLoc), savedRegisterLoc); + registers.setRegister(UNW_AARCH64_X26, addressSpace.get64(savedRegisterLoc)); savedRegisterLoc -= 8; } if (encoding & UNWIND_ARM64_FRAME_X27_X28_PAIR) { - registers.setRegister(UNW_AARCH64_X27, addressSpace.get64(savedRegisterLoc), savedRegisterLoc); + registers.setRegister(UNW_AARCH64_X27, addressSpace.get64(savedRegisterLoc)); savedRegisterLoc -= 8; - registers.setRegister(UNW_AARCH64_X28, addressSpace.get64(savedRegisterLoc), savedRegisterLoc); + registers.setRegister(UNW_AARCH64_X28, addressSpace.get64(savedRegisterLoc)); savedRegisterLoc -= 8; } @@ -602,48 +602,48 @@ int CompactUnwinder_arm64::stepWithCompactEncodingFrameless( } // subtract stack size off of sp - registers.setSP(savedRegisterLoc, 0); + registers.setSP(savedRegisterLoc); // set pc to be value in lr - registers.setIP(registers.getRegister(UNW_AARCH64_LR), 0); + registers.setIP(registers.getRegister(UNW_AARCH64_LR)); return UNW_STEP_SUCCESS; } -template -int CompactUnwinder_arm64::stepWithCompactEncodingFrame( +template +int CompactUnwinder_arm64::stepWithCompactEncodingFrame( compact_unwind_encoding_t encoding, uint64_t, A &addressSpace, - R ®isters) { + Registers_arm64 ®isters) { uint64_t savedRegisterLoc = registers.getFP() - 8; if (encoding & UNWIND_ARM64_FRAME_X19_X20_PAIR) { - registers.setRegister(UNW_AARCH64_X19, addressSpace.get64(savedRegisterLoc), savedRegisterLoc); + registers.setRegister(UNW_AARCH64_X19, addressSpace.get64(savedRegisterLoc)); savedRegisterLoc -= 8; - registers.setRegister(UNW_AARCH64_X20, addressSpace.get64(savedRegisterLoc), savedRegisterLoc); + registers.setRegister(UNW_AARCH64_X20, addressSpace.get64(savedRegisterLoc)); savedRegisterLoc -= 8; } if (encoding & UNWIND_ARM64_FRAME_X21_X22_PAIR) { - registers.setRegister(UNW_AARCH64_X21, addressSpace.get64(savedRegisterLoc), savedRegisterLoc); + registers.setRegister(UNW_AARCH64_X21, addressSpace.get64(savedRegisterLoc)); savedRegisterLoc -= 8; - registers.setRegister(UNW_AARCH64_X22, addressSpace.get64(savedRegisterLoc), savedRegisterLoc); + registers.setRegister(UNW_AARCH64_X22, addressSpace.get64(savedRegisterLoc)); savedRegisterLoc -= 8; } if (encoding & UNWIND_ARM64_FRAME_X23_X24_PAIR) { - registers.setRegister(UNW_AARCH64_X23, addressSpace.get64(savedRegisterLoc), savedRegisterLoc); + registers.setRegister(UNW_AARCH64_X23, addressSpace.get64(savedRegisterLoc)); savedRegisterLoc -= 8; - registers.setRegister(UNW_AARCH64_X24, addressSpace.get64(savedRegisterLoc), savedRegisterLoc); + registers.setRegister(UNW_AARCH64_X24, addressSpace.get64(savedRegisterLoc)); savedRegisterLoc -= 8; } if (encoding & UNWIND_ARM64_FRAME_X25_X26_PAIR) { - registers.setRegister(UNW_AARCH64_X25, addressSpace.get64(savedRegisterLoc), savedRegisterLoc); + registers.setRegister(UNW_AARCH64_X25, addressSpace.get64(savedRegisterLoc)); savedRegisterLoc -= 8; - registers.setRegister(UNW_AARCH64_X26, addressSpace.get64(savedRegisterLoc), savedRegisterLoc); + registers.setRegister(UNW_AARCH64_X26, addressSpace.get64(savedRegisterLoc)); savedRegisterLoc -= 8; } if (encoding & UNWIND_ARM64_FRAME_X27_X28_PAIR) { - registers.setRegister(UNW_AARCH64_X27, addressSpace.get64(savedRegisterLoc), savedRegisterLoc); + registers.setRegister(UNW_AARCH64_X27, addressSpace.get64(savedRegisterLoc)); savedRegisterLoc -= 8; - registers.setRegister(UNW_AARCH64_X28, addressSpace.get64(savedRegisterLoc), savedRegisterLoc); + registers.setRegister(UNW_AARCH64_X28, addressSpace.get64(savedRegisterLoc)); savedRegisterLoc -= 8; } @@ -682,11 +682,11 @@ int CompactUnwinder_arm64::stepWithCompactEncodingFrame( uint64_t fp = registers.getFP(); // fp points to old fp - registers.setFP(addressSpace.get64(fp), fp); + registers.setFP(addressSpace.get64(fp)); // old sp is fp less saved fp and lr - registers.setSP(fp + 16, 0); + registers.setSP(fp + 16); // pop return address into pc - registers.setIP(addressSpace.get64(fp + 8), fp + 8); + registers.setIP(addressSpace.get64(fp + 8)); return UNW_STEP_SUCCESS; } diff --git a/src/native/external/llvm-libunwind/src/DwarfInstructions.hpp b/src/native/external/llvm-libunwind/src/DwarfInstructions.hpp index d242a549e5b47..bd9ece60ee588 100644 --- a/src/native/external/llvm-libunwind/src/DwarfInstructions.hpp +++ b/src/native/external/llvm-libunwind/src/DwarfInstructions.hpp @@ -56,8 +56,7 @@ class DwarfInstructions { const R ®isters, pint_t initialStackValue); static pint_t getSavedRegister(A &addressSpace, const R ®isters, - pint_t cfa, const RegisterLocation &savedReg, - pint_t& location); + 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, @@ -69,7 +68,7 @@ class DwarfInstructions { return (pint_t)((sint_t)registers.getRegister((int)prolog.cfaRegister) + prolog.cfaRegisterOffset); if (prolog.cfaExpression != 0) - return evaluateExpression((pint_t)prolog.cfaExpression, addressSpace, + return evaluateExpression((pint_t)prolog.cfaExpression, addressSpace, registers, 0); assert(0 && "getCFA(): unknown location"); __builtin_unreachable(); @@ -91,28 +90,24 @@ template uint64_t getSparcWCookie(const R &, long) { template typename A::pint_t DwarfInstructions::getSavedRegister( A &addressSpace, const R ®isters, pint_t cfa, - const RegisterLocation &savedReg, - typename A::pint_t& location) { + const RegisterLocation &savedReg) { switch (savedReg.location) { case CFI_Parser::kRegisterInCFA: - location = cfa + (pint_t)savedReg.value; - return (pint_t)addressSpace.getP(location); + return (pint_t)addressSpace.getRegister(cfa + (pint_t)savedReg.value); case CFI_Parser::kRegisterInCFADecrypt: // sparc64 specific return (pint_t)(addressSpace.getP(cfa + (pint_t)savedReg.value) ^ getSparcWCookie(registers, 0)); case CFI_Parser::kRegisterAtExpression: - location = evaluateExpression((pint_t)savedReg.value, addressSpace, - registers, cfa); - return (pint_t)addressSpace.getP(location); + return (pint_t)addressSpace.getRegister(evaluateExpression( + (pint_t)savedReg.value, addressSpace, registers, cfa)); case CFI_Parser::kRegisterIsExpression: - location = 0; return evaluateExpression((pint_t)savedReg.value, addressSpace, registers, cfa); + case CFI_Parser::kRegisterInRegister: - location = 0; return registers.getRegister((int)savedReg.value); case CFI_Parser::kRegisterUndefined: return 0; @@ -181,12 +176,11 @@ template bool DwarfInstructions::getRA_SIGN_STATE(A &addressSpace, R registers, pint_t cfa, PrologInfo &prolog) { pint_t raSignState; - pint_t location; auto regloc = prolog.savedRegisters[UNW_AARCH64_RA_SIGN_STATE]; if (regloc.location == CFI_Parser::kRegisterUnused) raSignState = static_cast(regloc.value); else - raSignState = getSavedRegister(addressSpace, registers, cfa, regloc, location); + raSignState = getSavedRegister(addressSpace, registers, cfa, regloc); // Only bit[0] is meaningful. return raSignState & 0x01; @@ -211,7 +205,7 @@ int DwarfInstructions::stepWithDwarf(A &addressSpace, pint_t pc, // __unw_step_stage2 is not used for cross unwinding, so we use // __aarch64__ rather than LIBUNWIND_TARGET_AARCH64 to make sure we are // building for AArch64 natively. -#if 0 // defined(__aarch64__) +#if defined(__aarch64__) if (stage2 && cieInfo.mteTaggedFrame) { pint_t sp = registers.getSP(); pint_t p = sp; @@ -249,13 +243,13 @@ int DwarfInstructions::stepWithDwarf(A &addressSpace, pint_t pc, // // We set the SP here to the CFA, allowing for it to be overridden // by a CFI directive later on. - newRegisters.setSP(cfa, 0); + newRegisters.setSP(cfa); pint_t returnAddress = 0; - pint_t returnAddressLocation = 0; - const int lastReg = R::lastDwarfRegNum(); - assert(static_cast(CFI_Parser::kMaxRegisterNumber) >= lastReg && - "register range too large"); + constexpr int lastReg = R::lastDwarfRegNum(); + static_assert(static_cast(CFI_Parser::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) { @@ -269,23 +263,13 @@ int DwarfInstructions::stepWithDwarf(A &addressSpace, pint_t pc, newRegisters.setVectorRegister( i, getSavedVectorRegister(addressSpace, registers, cfa, prolog.savedRegisters[i])); - else if (i == (int)cieInfo.returnAddressRegister) { + else if (i == (int)cieInfo.returnAddressRegister) returnAddress = getSavedRegister(addressSpace, registers, cfa, - prolog.savedRegisters[i], - returnAddressLocation); - if (registers.validRegister(i)) { - newRegisters.setRegister(i, returnAddress, returnAddressLocation); - } - } - else if (registers.validRegister(i)) { - pint_t value; - pint_t location; - value = getSavedRegister(addressSpace, registers, cfa, - prolog.savedRegisters[i], - location); - - newRegisters.setRegister(i, value, location); - } + prolog.savedRegisters[i]); + else if (registers.validRegister(i)) + newRegisters.setRegister( + i, getSavedRegister(addressSpace, registers, cfa, + prolog.savedRegisters[i])); else return UNW_EBADREG; } else if (i == (int)cieInfo.returnAddressRegister) { @@ -380,8 +364,8 @@ int DwarfInstructions::stepWithDwarf(A &addressSpace, pint_t pc, #endif // Return address is address after call site instruction, so setting IP to - // that does simualates a return. - newRegisters.setIP(returnAddress, returnAddressLocation); + // that does simulates a return. + newRegisters.setIP(returnAddress); // Simulate the step by replacing the register set with the new ones. registers = newRegisters; diff --git a/src/native/external/llvm-libunwind/src/DwarfParser.hpp b/src/native/external/llvm-libunwind/src/DwarfParser.hpp index 0407a3dc8615e..0682942ce1379 100644 --- a/src/native/external/llvm-libunwind/src/DwarfParser.hpp +++ b/src/native/external/llvm-libunwind/src/DwarfParser.hpp @@ -270,7 +270,7 @@ bool CFI_Parser::findFDE(A &addressSpace, pint_t pc, pint_t ehSectionStart, 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)) { + if ((pcStart < pc) && (pc <= pcStart + pcRange)) { // parse rest of info fdeInfo->lsda = 0; // check for augmentation length @@ -451,7 +451,7 @@ bool CFI_Parser::parseFDEInstructions(A &addressSpace, static_cast(instructionsEnd)); // see DWARF Spec, section 6.4.2 for details on unwind opcodes - while ((p < instructionsEnd) && (codeOffset <= pcoffset)) { + while ((p < instructionsEnd) && (codeOffset < pcoffset)) { uint64_t reg; uint64_t reg2; int64_t offset; diff --git a/src/native/external/llvm-libunwind/src/EHHeaderParser.hpp b/src/native/external/llvm-libunwind/src/EHHeaderParser.hpp index ed4317c89055c..0662a1321e2c7 100644 --- a/src/native/external/llvm-libunwind/src/EHHeaderParser.hpp +++ b/src/native/external/llvm-libunwind/src/EHHeaderParser.hpp @@ -55,6 +55,19 @@ template bool EHHeaderParser::decodeEHHdr(A &addressSpace, pint_t ehHdrStart, pint_t ehHdrEnd, EHHeaderInfo &ehHdrInfo) { pint_t p = ehHdrStart; + + // Ensure that we don't read data beyond the end of .eh_frame_hdr + if (ehHdrEnd - ehHdrStart < 4) { + // Don't print a message for an empty .eh_frame_hdr (this can happen if + // the linker script defines symbols for it even in the empty case). + if (ehHdrEnd == ehHdrStart) + return false; + _LIBUNWIND_LOG("unsupported .eh_frame_hdr at %" PRIx64 + ": need at least 4 bytes of data but only got %zd", + static_cast(ehHdrStart), + static_cast(ehHdrEnd - ehHdrStart)); + return false; + } uint8_t version = addressSpace.get8(p++); if (version != 1) { _LIBUNWIND_LOG("unsupported .eh_frame_hdr version: %" PRIu8 " at %" PRIx64, diff --git a/src/native/external/llvm-libunwind/src/FrameHeaderCache.hpp b/src/native/external/llvm-libunwind/src/FrameHeaderCache.hpp index 54d5d33c3cd7e..296064d8e2e67 100644 --- a/src/native/external/llvm-libunwind/src/FrameHeaderCache.hpp +++ b/src/native/external/llvm-libunwind/src/FrameHeaderCache.hpp @@ -31,8 +31,8 @@ class _LIBUNWIND_HIDDEN FrameHeaderCache { struct CacheEntry { - uintptr_t LowPC() { return Info.dso_base; }; - uintptr_t HighPC() { return Info.dso_base + Info.text_segment_length; }; + uintptr_t LowPC() { return Info.dso_base; } + uintptr_t HighPC() { return Info.dso_base + Info.text_segment_length; } UnwindInfoSections Info; CacheEntry *Next; }; @@ -41,7 +41,7 @@ class _LIBUNWIND_HIDDEN FrameHeaderCache { // Can't depend on the C++ standard library in libunwind, so use an array to // allocate the entries, and two linked lists for ordering unused and recently - // used entries. FIXME: Would the the extra memory for a doubly-linked list + // used entries. FIXME: Would the extra memory for a doubly-linked list // be better than the runtime cost of traversing a very short singly-linked // list on a cache miss? The entries themselves are all small and consecutive, // so unlikely to cause page faults when following the pointers. The memory diff --git a/src/native/external/llvm-libunwind/src/Registers.hpp b/src/native/external/llvm-libunwind/src/Registers.hpp index 4a0c8d83bb40c..d11ddb3426d52 100644 --- a/src/native/external/llvm-libunwind/src/Registers.hpp +++ b/src/native/external/llvm-libunwind/src/Registers.hpp @@ -62,8 +62,7 @@ class _LIBUNWIND_HIDDEN Registers_x86 { bool validRegister(int num) const; uint32_t getRegister(int num) const; - void setRegister(int num, uint32_t value, uint32_t location); - uint32_t getRegisterLocation(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); @@ -78,21 +77,21 @@ class _LIBUNWIND_HIDDEN Registers_x86 { static int getArch() { return REGISTERS_X86; } uint32_t getSP() const { return _registers.__esp; } - void setSP(uint32_t value, uint32_t location) { _registers.__esp = value; _registerLocations.__esp = location; } + void setSP(uint32_t value) { _registers.__esp = value; } uint32_t getIP() const { return _registers.__eip; } - void setIP(uint32_t value, uint32_t location) { _registers.__eip = value; _registerLocations.__eip = location; } + void setIP(uint32_t value) { _registers.__eip = value; } uint32_t getEBP() const { return _registers.__ebp; } - void setEBP(uint32_t value, uint32_t location) { _registers.__ebp = value; _registerLocations.__ebp = location; } + void setEBP(uint32_t value) { _registers.__ebp = value; } uint32_t getEBX() const { return _registers.__ebx; } - void setEBX(uint32_t value, uint32_t location) { _registers.__ebx = value; _registerLocations.__ebx = location; } + void setEBX(uint32_t value) { _registers.__ebx = value; } uint32_t getECX() const { return _registers.__ecx; } - void setECX(uint32_t value, uint32_t location) { _registers.__ecx = value; _registerLocations.__ecx = location; } + void setECX(uint32_t value) { _registers.__ecx = value; } uint32_t getEDX() const { return _registers.__edx; } - void setEDX(uint32_t value, uint32_t location) { _registers.__edx = value; _registerLocations.__edx = location; } + void setEDX(uint32_t value) { _registers.__edx = value; } uint32_t getESI() const { return _registers.__esi; } - void setESI(uint32_t value, uint32_t location) { _registers.__esi = value; _registerLocations.__esi = location; } + void setESI(uint32_t value) { _registers.__esi = value; } uint32_t getEDI() const { return _registers.__edi; } - void setEDI(uint32_t value, uint32_t location) { _registers.__edi = value; _registerLocations.__edi = location; } + void setEDI(uint32_t value) { _registers.__edi = value; } private: struct GPRs { @@ -113,32 +112,18 @@ class _LIBUNWIND_HIDDEN Registers_x86 { unsigned int __fs; unsigned int __gs; }; - struct GPRLocations { - 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 __eip; - }; GPRs _registers; - GPRLocations _registerLocations; }; inline Registers_x86::Registers_x86(const void *registers) { static_assert((check_fit::does_fit), "x86 registers do not fit into unw_context_t"); memcpy(&_registers, registers, sizeof(_registers)); - memset(&_registerLocations, 0, sizeof(_registerLocations)); } inline Registers_x86::Registers_x86() { memset(&_registers, 0, sizeof(_registers)); - memset(&_registerLocations, 0, sizeof(_registerLocations)); } inline bool Registers_x86::validRegister(int regNum) const { @@ -187,31 +172,25 @@ inline uint32_t Registers_x86::getRegister(int regNum) const { _LIBUNWIND_ABORT("unsupported x86 register"); } -inline void Registers_x86::setRegister(int regNum, uint32_t value, uint32_t location) { +inline void Registers_x86::setRegister(int regNum, uint32_t value) { switch (regNum) { case UNW_REG_IP: _registers.__eip = value; - _registerLocations.__eip = location; return; case UNW_REG_SP: _registers.__esp = value; - _registerLocations.__esp = location; return; case UNW_X86_EAX: _registers.__eax = value; - _registerLocations.__eax = location; return; case UNW_X86_ECX: _registers.__ecx = value; - _registerLocations.__ecx = location; return; case UNW_X86_EDX: _registers.__edx = value; - _registerLocations.__edx = location; return; case UNW_X86_EBX: _registers.__ebx = value; - _registerLocations.__ebx = location; return; #if !defined(__APPLE__) case UNW_X86_ESP: @@ -219,7 +198,6 @@ inline void Registers_x86::setRegister(int regNum, uint32_t value, uint32_t loca case UNW_X86_EBP: #endif _registers.__ebp = value; - _registerLocations.__ebp = location; return; #if !defined(__APPLE__) case UNW_X86_EBP: @@ -227,46 +205,17 @@ inline void Registers_x86::setRegister(int regNum, uint32_t value, uint32_t loca case UNW_X86_ESP: #endif _registers.__esp = value; - _registerLocations.__esp = location; return; case UNW_X86_ESI: _registers.__esi = value; - _registerLocations.__esi = location; return; case UNW_X86_EDI: _registers.__edi = value; - _registerLocations.__edi = location; return; } _LIBUNWIND_ABORT("unsupported x86 register"); } -inline uint32_t Registers_x86::getRegisterLocation(int regNum) const { - switch (regNum) { - case UNW_REG_IP: - return _registerLocations.__eip; - case UNW_REG_SP: - return _registerLocations.__esp; - case UNW_X86_EAX: - return _registerLocations.__eax; - case UNW_X86_ECX: - return _registerLocations.__ecx; - case UNW_X86_EDX: - return _registerLocations.__edx; - case UNW_X86_EBX: - return _registerLocations.__ebx; - case UNW_X86_EBP: - return _registerLocations.__ebp; - case UNW_X86_ESP: - return _registerLocations.__esp; - case UNW_X86_ESI: - return _registerLocations.__esi; - case UNW_X86_EDI: - return _registerLocations.__edi; - } - _LIBUNWIND_ABORT("unsupported x86 register"); -} - inline const char *Registers_x86::getRegisterName(int regNum) { switch (regNum) { case UNW_REG_IP: @@ -331,8 +280,7 @@ class _LIBUNWIND_HIDDEN Registers_x86_64 { bool validRegister(int num) const; uint64_t getRegister(int num) const; - void setRegister(int num, uint64_t value, uint64_t location); - uint64_t getRegisterLocation(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); @@ -347,21 +295,21 @@ class _LIBUNWIND_HIDDEN Registers_x86_64 { static int getArch() { return REGISTERS_X86_64; } uint64_t getSP() const { return _registers.__rsp; } - void setSP(uint64_t value, uint64_t location) { _registers.__rsp = value; _registerLocations.__rsp = location;} + void setSP(uint64_t value) { _registers.__rsp = value; } uint64_t getIP() const { return _registers.__rip; } - void setIP(uint64_t value, uint64_t location) { _registers.__rip = value; _registerLocations.__rip = location; } + void setIP(uint64_t value) { _registers.__rip = value; } uint64_t getRBP() const { return _registers.__rbp; } - void setRBP(uint64_t value, uint64_t location) { _registers.__rbp = value; _registerLocations.__rbp = location; } + void setRBP(uint64_t value) { _registers.__rbp = value; } uint64_t getRBX() const { return _registers.__rbx; } - void setRBX(uint64_t value, uint64_t location) { _registers.__rbx = value; _registerLocations.__rbx = location; } + void setRBX(uint64_t value) { _registers.__rbx = value; } uint64_t getR12() const { return _registers.__r12; } - void setR12(uint64_t value, uint64_t location) { _registers.__r12 = value; _registerLocations.__r12 = location; } + void setR12(uint64_t value) { _registers.__r12 = value; } uint64_t getR13() const { return _registers.__r13; } - void setR13(uint64_t value, uint64_t location) { _registers.__r13 = value; _registerLocations.__r13 = location; } + void setR13(uint64_t value) { _registers.__r13 = value; } uint64_t getR14() const { return _registers.__r14; } - void setR14(uint64_t value, uint64_t location) { _registers.__r14 = value; _registerLocations.__r14 = location; } + void setR14(uint64_t value) { _registers.__r14 = value; } uint64_t getR15() const { return _registers.__r15; } - void setR15(uint64_t value, uint64_t location) { _registers.__r15 = value; _registerLocations.__r15 = location; } + void setR15(uint64_t value) { _registers.__r15 = value; } private: struct GPRs { @@ -390,27 +338,7 @@ class _LIBUNWIND_HIDDEN Registers_x86_64 { uint64_t __padding; // 16-byte align #endif }; - struct GPRLocations { - 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; - }; GPRs _registers; - GPRLocations _registerLocations; #if defined(_WIN64) v128 _xmm[16]; #endif @@ -420,12 +348,10 @@ inline Registers_x86_64::Registers_x86_64(const void *registers) { static_assert((check_fit::does_fit), "x86_64 registers do not fit into unw_context_t"); memcpy(&_registers, registers, sizeof(_registers)); - memset(&_registerLocations, 0, sizeof(_registerLocations)); } inline Registers_x86_64::Registers_x86_64() { memset(&_registers, 0, sizeof(_registers)); - memset(&_registerLocations, 0, sizeof(_registerLocations)); } inline bool Registers_x86_64::validRegister(int regNum) const { @@ -483,122 +409,62 @@ inline uint64_t Registers_x86_64::getRegister(int regNum) const { _LIBUNWIND_ABORT("unsupported x86_64 register"); } -inline uint64_t Registers_x86_64::getRegisterLocation(int regNum) const { - switch (regNum) { - case UNW_REG_IP: - return _registerLocations.__rip; - case UNW_REG_SP: - return _registerLocations.__rsp; - case UNW_X86_64_RAX: - return _registerLocations.__rax; - case UNW_X86_64_RDX: - return _registerLocations.__rdx; - case UNW_X86_64_RCX: - return _registerLocations.__rcx; - case UNW_X86_64_RBX: - return _registerLocations.__rbx; - case UNW_X86_64_RSI: - return _registerLocations.__rsi; - case UNW_X86_64_RDI: - return _registerLocations.__rdi; - case UNW_X86_64_RBP: - return _registerLocations.__rbp; - case UNW_X86_64_RSP: - return _registerLocations.__rsp; - case UNW_X86_64_R8: - return _registerLocations.__r8; - case UNW_X86_64_R9: - return _registerLocations.__r9; - case UNW_X86_64_R10: - return _registerLocations.__r10; - case UNW_X86_64_R11: - return _registerLocations.__r11; - case UNW_X86_64_R12: - return _registerLocations.__r12; - case UNW_X86_64_R13: - return _registerLocations.__r13; - case UNW_X86_64_R14: - return _registerLocations.__r14; - case UNW_X86_64_R15: - return _registerLocations.__r15; - } - _LIBUNWIND_ABORT("unsupported x86_64 register"); -} - -inline void Registers_x86_64::setRegister(int regNum, uint64_t value, uint64_t location) { +inline void Registers_x86_64::setRegister(int regNum, uint64_t value) { switch (regNum) { case UNW_REG_IP: case UNW_X86_64_RIP: _registers.__rip = value; - _registerLocations.__rip = location; return; case UNW_REG_SP: _registers.__rsp = value; - _registerLocations.__rsp = location; return; case UNW_X86_64_RAX: _registers.__rax = value; - _registerLocations.__rax = location; return; case UNW_X86_64_RDX: _registers.__rdx = value; - _registerLocations.__rdx = location; return; case UNW_X86_64_RCX: _registers.__rcx = value; - _registerLocations.__rcx = location; return; case UNW_X86_64_RBX: _registers.__rbx = value; - _registerLocations.__rbx = location; return; case UNW_X86_64_RSI: _registers.__rsi = value; - _registerLocations.__rsi = location; return; case UNW_X86_64_RDI: _registers.__rdi = value; - _registerLocations.__rdi = location; return; case UNW_X86_64_RBP: _registers.__rbp = value; - _registerLocations.__rbp = location; return; case UNW_X86_64_RSP: _registers.__rsp = value; - _registerLocations.__rsp = location; return; case UNW_X86_64_R8: _registers.__r8 = value; - _registerLocations.__r8 = location; return; case UNW_X86_64_R9: _registers.__r9 = value; - _registerLocations.__r9 = location; return; case UNW_X86_64_R10: _registers.__r10 = value; - _registerLocations.__r10 = location; return; case UNW_X86_64_R11: _registers.__r11 = value; - _registerLocations.__r11 = location; return; case UNW_X86_64_R12: _registers.__r12 = value; - _registerLocations.__r12 = location; return; case UNW_X86_64_R13: _registers.__r13 = value; - _registerLocations.__r13 = location; return; case UNW_X86_64_R14: _registers.__r14 = value; - _registerLocations.__r14 = location; return; case UNW_X86_64_R15: _registers.__r15 = value; - _registerLocations.__r15 = location; return; } _LIBUNWIND_ABORT("unsupported x86_64 register"); @@ -753,6 +619,8 @@ class _LIBUNWIND_HIDDEN Registers_ppc { void setIP(uint32_t value) { _registers.__srr0 = value; } uint64_t getCR() const { return _registers.__cr; } void setCR(uint32_t value) { _registers.__cr = value; } + uint64_t getLR() const { return _registers.__lr; } + void setLR(uint32_t value) { _registers.__lr = value; } private: struct ppc_thread_state_t { @@ -1303,8 +1171,7 @@ class _LIBUNWIND_HIDDEN Registers_ppc64 { bool validRegister(int num) const; uint64_t getRegister(int num) const; - void setRegister(int num, uint64_t value, uint64_t location); - uint64_t getRegisterLocation(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); @@ -1324,6 +1191,8 @@ class _LIBUNWIND_HIDDEN Registers_ppc64 { void setIP(uint64_t value) { _registers.__srr0 = value; } uint64_t getCR() const { return _registers.__cr; } void setCR(uint64_t value) { _registers.__cr = value; } + uint64_t getLR() const { return _registers.__lr; } + void setLR(uint64_t value) { _registers.__lr = value; } private: struct ppc64_thread_state_t { @@ -1953,14 +1822,13 @@ class _LIBUNWIND_HIDDEN Registers_arm64 { bool validRegister(int num) const; uint64_t getRegister(int num) const; - void setRegister(int num, uint64_t value, uint64_t location); + 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); - uint64_t getRegisterLocation(int regNum) const; static const char *getRegisterName(int num); void jumpto() { __libunwind_Registers_arm64_jumpto(this); } static constexpr int lastDwarfRegNum() { @@ -1969,11 +1837,11 @@ class _LIBUNWIND_HIDDEN Registers_arm64 { static int getArch() { return REGISTERS_ARM64; } uint64_t getSP() const { return _registers.__sp; } - void setSP(uint64_t value, uint64_t location) { _registers.__sp = value; } + void setSP(uint64_t value) { _registers.__sp = value; } uint64_t getIP() const { return _registers.__pc; } - void setIP(uint64_t value, uint64_t location) { _registers.__pc = value; } + void setIP(uint64_t value) { _registers.__pc = value; } uint64_t getFP() const { return _registers.__fp; } - void setFP(uint64_t value, uint64_t location) { _registers.__fp = value; } + void setFP(uint64_t value) { _registers.__fp = value; } private: struct GPRs { @@ -1985,17 +1853,7 @@ class _LIBUNWIND_HIDDEN Registers_arm64 { uint64_t __ra_sign_state; // RA sign state register }; - struct GPRLocations { - 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; - GPRLocations _registerLocations; double _vectorHalfRegisters[32]; // Currently only the lower double in 128-bit vectore registers // is perserved during unwinding. We could define new register @@ -2007,9 +1865,7 @@ inline Registers_arm64::Registers_arm64(const void *registers) { static_assert((check_fit::does_fit), "arm64 registers do not fit into unw_context_t"); memcpy(&_registers, registers, sizeof(_registers)); - memset(&_registerLocations, 0, sizeof(_registerLocations)); - static_assert( - sizeof(GPRs) == 0x110, + static_assert(sizeof(GPRs) == 0x110, "expected VFP registers to be at offset 272"); memcpy(_vectorHalfRegisters, static_cast(registers) + sizeof(GPRs), @@ -2018,7 +1874,6 @@ inline Registers_arm64::Registers_arm64(const void *registers) { inline Registers_arm64::Registers_arm64() { memset(&_registers, 0, sizeof(_registers)); - memset(&_registerLocations, 0, sizeof(_registerLocations)); memset(&_vectorHalfRegisters, 0, sizeof(_vectorHalfRegisters)); } @@ -2054,43 +1909,23 @@ inline uint64_t Registers_arm64::getRegister(int regNum) const { _LIBUNWIND_ABORT("unsupported arm64 register"); } -inline void Registers_arm64::setRegister(int regNum, uint64_t value, uint64_t location) { - if (regNum == UNW_REG_IP || regNum == UNW_AARCH64_PC) { +inline void Registers_arm64::setRegister(int regNum, uint64_t value) { + if (regNum == UNW_REG_IP || regNum == UNW_AARCH64_PC) _registers.__pc = value; - _registerLocations.__pc = location; - } - else if (regNum == UNW_REG_SP || regNum == UNW_AARCH64_SP) { + else if (regNum == UNW_REG_SP || regNum == UNW_AARCH64_SP) _registers.__sp = value; - _registerLocations.__sp = location; - } else if (regNum == UNW_AARCH64_RA_SIGN_STATE) _registers.__ra_sign_state = value; - else if (regNum == UNW_AARCH64_FP) { + else if (regNum == UNW_AARCH64_FP) _registers.__fp = value; - _registerLocations.__fp = location; - } - else if (regNum == UNW_AARCH64_LR) { + else if (regNum == UNW_AARCH64_LR) _registers.__lr = value; - _registerLocations.__lr = location; - } - else if ((regNum >= 0) && (regNum < 29)) { + else if ((regNum >= 0) && (regNum < 29)) _registers.__x[regNum] = value; - _registerLocations.__x[regNum] = location; - } else _LIBUNWIND_ABORT("unsupported arm64 register"); } -inline uint64_t Registers_arm64::getRegisterLocation(int regNum) const { - if (regNum == UNW_REG_IP) - return _registerLocations.__pc; - if (regNum == UNW_REG_SP) - return _registerLocations.__sp; - if ((regNum >= 0) && (regNum < 32)) - return _registerLocations.__x[regNum]; - _LIBUNWIND_ABORT("unsupported arm64 register"); -} - inline const char *Registers_arm64::getRegisterName(int regNum) { switch (regNum) { case UNW_REG_IP: @@ -2276,8 +2111,7 @@ class _LIBUNWIND_HIDDEN Registers_arm { bool validRegister(int num) const; uint32_t getRegister(int num) const; - void setRegister(int num, uint32_t value, uint32_t location); - uint32_t getRegisterLocation(int num) const; + 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); @@ -2295,9 +2129,9 @@ class _LIBUNWIND_HIDDEN Registers_arm { static int getArch() { return REGISTERS_ARM; } uint32_t getSP() const { return _registers.__sp; } - void setSP(uint32_t value, uint32_t location) { _registers.__sp = value; _registerLocations.__sp = location; } + void setSP(uint32_t value) { _registers.__sp = value; } uint32_t getIP() const { return _registers.__pc; } - void setIP(uint32_t value, uint32_t location) { _registers.__pc = value; _registerLocations.__pc = location; } + void setIP(uint32_t value) { _registers.__pc = value; } void saveVFPAsX() { assert(_use_X_for_vfp_save || !_saved_vfp_d0_d15); @@ -2334,14 +2168,6 @@ class _LIBUNWIND_HIDDEN Registers_arm { }; static void saveVFPWithFSTMD(void*); - - struct GPRLocations { - 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 saveVFPWithFSTMX(void*); static void saveVFPv3(void*); static void restoreVFPWithFLDMD(void*); @@ -2358,7 +2184,6 @@ class _LIBUNWIND_HIDDEN Registers_arm { // ARM registers GPRs _registers; PseudoRegisters _pseudo_registers; - GPRLocations _registerLocations; // We save floating point registers lazily because we can't know ahead of // time which ones are used. See EHABI #4.7. @@ -2397,7 +2222,6 @@ inline Registers_arm::Registers_arm(const void *registers) // See __unw_getcontext() note about data. memcpy(&_registers, registers, sizeof(_registers)); memset(&_pseudo_registers, 0, sizeof(_pseudo_registers)); - memset(&_registerLocations, 0, sizeof(_registerLocations)); memset(&_vfp_d0_d15_pad, 0, sizeof(_vfp_d0_d15_pad)); memset(&_vfp_d16_d31, 0, sizeof(_vfp_d16_d31)); #if defined(__ARM_WMMX) @@ -2414,7 +2238,6 @@ inline Registers_arm::Registers_arm() _saved_vfp_d16_d31(false) { memset(&_registers, 0, sizeof(_registers)); memset(&_pseudo_registers, 0, sizeof(_pseudo_registers)); - memset(&_registerLocations, 0, sizeof(_registerLocations)); memset(&_vfp_d0_d15_pad, 0, sizeof(_vfp_d0_d15_pad)); memset(&_vfp_d16_d31, 0, sizeof(_vfp_d16_d31)); #if defined(__ARM_WMMX) @@ -2481,28 +2304,24 @@ inline uint32_t Registers_arm::getRegister(int regNum) const { _LIBUNWIND_ABORT("unsupported arm register"); } -inline void Registers_arm::setRegister(int regNum, uint32_t value, uint32_t location) { +inline void Registers_arm::setRegister(int regNum, uint32_t value) { if (regNum == UNW_REG_SP || regNum == UNW_ARM_SP) { _registers.__sp = value; - _registerLocations.__sp = location; return; } if (regNum == UNW_ARM_LR) { _registers.__lr = value; - _registerLocations.__lr = location; return; } if (regNum == UNW_REG_IP || regNum == UNW_ARM_IP) { _registers.__pc = value; - _registerLocations.__pc = location; return; } if (regNum >= UNW_ARM_R0 && regNum <= UNW_ARM_R12) { _registers.__r[regNum] = value; - _registerLocations.__r[regNum] = location; return; } @@ -2525,22 +2344,6 @@ inline void Registers_arm::setRegister(int regNum, uint32_t value, uint32_t loca _LIBUNWIND_ABORT("unsupported arm register"); } -inline uint32_t Registers_arm::getRegisterLocation(int regNum) const { - if (regNum == UNW_REG_SP || regNum == UNW_ARM_SP) - return _registerLocations.__sp; - - if (regNum == UNW_ARM_LR) - return _registerLocations.__lr; - - if (regNum == UNW_REG_IP || regNum == UNW_ARM_IP) - return _registerLocations.__pc; - - if (regNum >= UNW_ARM_R0 && regNum <= UNW_ARM_R12) - return _registerLocations.__r[regNum]; - - _LIBUNWIND_ABORT("unsupported arm register"); -} - inline const char *Registers_arm::getRegisterName(int regNum) { switch (regNum) { case UNW_REG_IP: @@ -3070,7 +2873,7 @@ inline bool Registers_mips_o32::validRegister(int regNum) const { return false; if (regNum <= UNW_MIPS_R31) return true; -#if __mips_isa_rev != 6 +#if __mips_isa_rev < 6 if (regNum == UNW_MIPS_HI) return true; if (regNum == UNW_MIPS_LO) @@ -3104,10 +2907,12 @@ inline uint32_t Registers_mips_o32::getRegister(int regNum) const { return _registers.__pc; case UNW_REG_SP: return _registers.__r[29]; +#if __mips_isa_rev < 6 case UNW_MIPS_HI: return _registers.__hi; case UNW_MIPS_LO: return _registers.__lo; +#endif } _LIBUNWIND_ABORT("unsupported mips_o32 register"); } @@ -3137,11 +2942,13 @@ inline void Registers_mips_o32::setRegister(int regNum, uint32_t value) { case UNW_REG_SP: _registers.__r[29] = value; return; +#if __mips_isa_rev < 6 case UNW_MIPS_HI: _registers.__hi = value; return; case UNW_MIPS_LO: _registers.__lo = value; +#endif return; } _LIBUNWIND_ABORT("unsupported mips_o32 register"); @@ -3321,10 +3128,12 @@ inline const char *Registers_mips_o32::getRegisterName(int regNum) { return "$f30"; case UNW_MIPS_F31: return "$f31"; +#if __mips_isa_rev < 6 case UNW_MIPS_HI: return "$hi"; case UNW_MIPS_LO: return "$lo"; +#endif default: return "unknown register"; } @@ -3394,7 +3203,7 @@ inline bool Registers_mips_newabi::validRegister(int regNum) const { return false; if (regNum <= UNW_MIPS_R31) return true; -#if __mips_isa_rev != 6 +#if __mips_isa_rev < 6 if (regNum == UNW_MIPS_HI) return true; if (regNum == UNW_MIPS_LO) @@ -3413,10 +3222,12 @@ inline uint64_t Registers_mips_newabi::getRegister(int regNum) const { return _registers.__pc; case UNW_REG_SP: return _registers.__r[29]; +#if __mips_isa_rev < 6 case UNW_MIPS_HI: return _registers.__hi; case UNW_MIPS_LO: return _registers.__lo; +#endif } _LIBUNWIND_ABORT("unsupported mips_newabi register"); } @@ -3434,12 +3245,14 @@ inline void Registers_mips_newabi::setRegister(int regNum, uint64_t value) { case UNW_REG_SP: _registers.__r[29] = value; return; +#if __mips_isa_rev < 6 case UNW_MIPS_HI: _registers.__hi = value; return; case UNW_MIPS_LO: _registers.__lo = value; return; +#endif } _LIBUNWIND_ABORT("unsupported mips_newabi register"); } @@ -3618,10 +3431,12 @@ inline const char *Registers_mips_newabi::getRegisterName(int regNum) { return "$f30"; case UNW_MIPS_F31: return "$f31"; +#if __mips_isa_rev < 6 case UNW_MIPS_HI: return "$hi"; case UNW_MIPS_LO: return "$lo"; +#endif default: return "unknown register"; } diff --git a/src/native/external/llvm-libunwind/src/Unwind-EHABI.cpp b/src/native/external/llvm-libunwind/src/Unwind-EHABI.cpp index 63d01aaf9cef4..05475c6ac1e2f 100644 --- a/src/native/external/llvm-libunwind/src/Unwind-EHABI.cpp +++ b/src/native/external/llvm-libunwind/src/Unwind-EHABI.cpp @@ -228,7 +228,7 @@ decode_eht_entry(const uint32_t* data, size_t* off, size_t* len) { // 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 routine address. + // 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. @@ -271,7 +271,7 @@ _Unwind_VRS_Interpret(_Unwind_Context *context, const uint32_t *data, 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, NULL); + _Unwind_VRS_Set(context, _UVRSC_CORE, UNW_ARM_SP, _UVRSD_UINT32, &sp); } else { switch (byte & 0xf0) { case 0x80: { @@ -295,7 +295,7 @@ _Unwind_VRS_Interpret(_Unwind_Context *context, const uint32_t *data, _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, NULL); + &sp); break; } case 0xa0: { @@ -337,7 +337,7 @@ _Unwind_VRS_Interpret(_Unwind_Context *context, const uint32_t *data, &sp); sp += 0x204 + (addend << 2); _Unwind_VRS_Set(context, _UVRSC_CORE, UNW_ARM_SP, _UVRSD_UINT32, - &sp, NULL); + &sp); break; } case 0xb3: { @@ -438,7 +438,7 @@ _Unwind_VRS_Interpret(_Unwind_Context *context, const uint32_t *data, #else (void)hasReturnAddrAuthCode; #endif - _Unwind_VRS_Set(context, _UVRSC_CORE, UNW_ARM_IP, _UVRSD_UINT32, &lr, NULL); + _Unwind_VRS_Set(context, _UVRSC_CORE, UNW_ARM_IP, _UVRSD_UINT32, &lr); } return _URC_CONTINUE_UNWIND; } @@ -589,7 +589,7 @@ static _Unwind_Reason_Code unwind_phase2(unw_context_t *uc, unw_cursor_t *cursor // // See #7.4.6 for details. __unw_set_reg(cursor, UNW_REG_IP, - exception_object->unwinder_cache.reserved2, NULL); + exception_object->unwinder_cache.reserved2); resume = false; } @@ -709,7 +709,7 @@ unwind_phase2_forced(unw_context_t *uc, unw_cursor_t *cursor, // 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 " + _LIBUNWIND_TRACE_UNWINDING("unwind_phase2_forced(ex_ojb=%p): __unw_get_proc_info " "failed => _URC_END_OF_STACK", (void *)exception_object); return _URC_FATAL_PHASE2_ERROR; @@ -885,8 +885,11 @@ _Unwind_GetLanguageSpecificData(struct _Unwind_Context *context) { return result; } -static uint64_t ValueAsBitPattern(_Unwind_VRS_DataRepresentation representation, - void* valuep) { +// Only used in _LIBUNWIND_TRACE_API, which is a no-op when assertions are +// disabled. +[[gnu::unused]] static uint64_t +ValueAsBitPattern(_Unwind_VRS_DataRepresentation representation, + const void *valuep) { uint64_t value = 0; switch (representation) { case _UVRSD_UINT32: @@ -906,7 +909,7 @@ static uint64_t ValueAsBitPattern(_Unwind_VRS_DataRepresentation representation, _LIBUNWIND_EXPORT _Unwind_VRS_Result _Unwind_VRS_Set(_Unwind_Context *context, _Unwind_VRS_RegClass regclass, uint32_t regno, _Unwind_VRS_DataRepresentation representation, - void *valuep, unw_word_t *pos) { + void *valuep) { _LIBUNWIND_TRACE_API("_Unwind_VRS_Set(context=%p, regclass=%d, reg=%d, " "rep=%d, value=0x%llX)", static_cast(context), regclass, regno, @@ -918,7 +921,7 @@ _Unwind_VRS_Set(_Unwind_Context *context, _Unwind_VRS_RegClass regclass, 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_word_t *)pos) == UNW_ESUCCESS + *(unw_word_t *)valuep) == UNW_ESUCCESS ? _UVRSR_OK : _UVRSR_FAILED; case _UVRSC_VFP: @@ -962,7 +965,7 @@ _Unwind_VRS_Set(_Unwind_Context *context, _Unwind_VRS_RegClass regclass, if (representation != _UVRSD_UINT32 || regno != 0) return _UVRSR_FAILED; return __unw_set_reg(cursor, (unw_regnum_t)(UNW_ARM_RA_AUTH_CODE), - *(unw_word_t *)valuep, NULL) == UNW_ESUCCESS + *(unw_word_t *)valuep) == UNW_ESUCCESS ? _UVRSR_OK : _UVRSR_FAILED; break; @@ -1068,7 +1071,6 @@ _Unwind_VRS_Pop(_Unwind_Context *context, _Unwind_VRS_RegClass regclass, // computed new stack location. See EHABI #7.5.4 table 3. bool poppedSP = false; uint32_t* sp; - uint32_t* pos; if (_Unwind_VRS_Get(context, _UVRSC_CORE, UNW_ARM_SP, _UVRSD_UINT32, &sp) != _UVRSR_OK) { return _UVRSR_FAILED; @@ -1076,18 +1078,17 @@ _Unwind_VRS_Pop(_Unwind_Context *context, _Unwind_VRS_RegClass regclass, for (uint32_t i = 0; i < 16; ++i) { if (!(discriminator & static_cast(1 << i))) continue; - pos = sp; uint32_t value = *sp++; if (regclass == _UVRSC_CORE && i == 13) poppedSP = true; if (_Unwind_VRS_Set(context, regclass, i, - _UVRSD_UINT32, &value, pos) != _UVRSR_OK) { + _UVRSD_UINT32, &value) != _UVRSR_OK) { return _UVRSR_FAILED; } } if (!poppedSP) { return _Unwind_VRS_Set(context, _UVRSC_CORE, UNW_ARM_SP, - _UVRSD_UINT32, &sp, NULL); + _UVRSD_UINT32, &sp); } return _UVRSR_OK; } @@ -1119,14 +1120,14 @@ _Unwind_VRS_Pop(_Unwind_Context *context, _Unwind_VRS_RegClass regclass, #else #error "Unable to determine endianess" #endif - if (_Unwind_VRS_Set(context, regclass, i, representation, &value, NULL) != + 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, NULL); + &sp); } case _UVRSC_PSEUDO: { if (representation != _UVRSD_UINT32 || discriminator != 0) @@ -1138,8 +1139,8 @@ _Unwind_VRS_Pop(_Unwind_Context *context, _Unwind_VRS_RegClass regclass, return _UVRSR_FAILED; } uint32_t pac = *sp++; - _Unwind_VRS_Set(context, _UVRSC_CORE, UNW_ARM_SP, _UVRSD_UINT32, &sp, NULL); - return _Unwind_VRS_Set(context, _UVRSC_PSEUDO, 0, _UVRSD_UINT32, &pac, NULL); + _Unwind_VRS_Set(context, _UVRSC_CORE, UNW_ARM_SP, _UVRSD_UINT32, &sp); + return _Unwind_VRS_Set(context, _UVRSC_PSEUDO, 0, _UVRSD_UINT32, &pac); } } _LIBUNWIND_ABORT("unsupported register class"); diff --git a/src/native/external/llvm-libunwind/src/Unwind-seh.cpp b/src/native/external/llvm-libunwind/src/Unwind-seh.cpp index d08c29c21383b..b2bb119ed6d29 100644 --- a/src/native/external/llvm-libunwind/src/Unwind-seh.cpp +++ b/src/native/external/llvm-libunwind/src/Unwind-seh.cpp @@ -212,11 +212,20 @@ __libunwind_seh_personality(int version, _Unwind_Action state, ms_exc.ExceptionInformation[2] = state; DISPATCHER_CONTEXT *disp_ctx = __unw_seh_get_disp_ctx((unw_cursor_t *)context); + _LIBUNWIND_TRACE_UNWINDING("__libunwind_seh_personality() calling " + "LanguageHandler %p(%p, %p, %p, %p)", + (void *)disp_ctx->LanguageHandler, (void *)&ms_exc, + (void *)disp_ctx->EstablisherFrame, + (void *)disp_ctx->ContextRecord, (void *)disp_ctx); EXCEPTION_DISPOSITION ms_act = disp_ctx->LanguageHandler(&ms_exc, (PVOID)disp_ctx->EstablisherFrame, disp_ctx->ContextRecord, disp_ctx); + _LIBUNWIND_TRACE_UNWINDING("__libunwind_seh_personality() LanguageHandler " + "returned %d", + (int)ms_act); switch (ms_act) { + case ExceptionContinueExecution: return _URC_END_OF_STACK; case ExceptionContinueSearch: return _URC_CONTINUE_UNWIND; case 4 /*ExceptionExecuteHandler*/: return phase2 ? _URC_INSTALL_CONTEXT : _URC_HANDLER_FOUND; @@ -238,7 +247,7 @@ unwind_phase2_forced(unw_context_t *uc, // Update info about this frame. unw_proc_info_t frameInfo; if (__unw_get_proc_info(&cursor2, &frameInfo) != UNW_ESUCCESS) { - _LIBUNWIND_TRACE_UNWINDING("unwind_phase2_forced(ex_ojb=%p): __unw_step " + _LIBUNWIND_TRACE_UNWINDING("unwind_phase2_forced(ex_ojb=%p): __unw_get_proc_info " "failed => _URC_END_OF_STACK", (void *)exception_object); return _URC_FATAL_PHASE2_ERROR; @@ -304,6 +313,12 @@ unwind_phase2_forced(unw_context_t *uc, // We may get control back if landing pad calls _Unwind_Resume(). __unw_resume(&cursor2); break; + case _URC_END_OF_STACK: + _LIBUNWIND_TRACE_UNWINDING("unwind_phase2_forced(ex_ojb=%p): " + "personality returned " + "_URC_END_OF_STACK", + (void *)exception_object); + break; default: // Personality routine returned an unknown result code. _LIBUNWIND_TRACE_UNWINDING("unwind_phase2_forced(ex_ojb=%p): " @@ -312,6 +327,8 @@ unwind_phase2_forced(unw_context_t *uc, (void *)exception_object, personalityResult); return _URC_FATAL_PHASE2_ERROR; } + if (personalityResult == _URC_END_OF_STACK) + break; } } diff --git a/src/native/external/llvm-libunwind/src/Unwind-sjlj.c b/src/native/external/llvm-libunwind/src/Unwind-sjlj.c index 90a55fd29db1f..7e8faf098fe14 100644 --- a/src/native/external/llvm-libunwind/src/Unwind-sjlj.c +++ b/src/native/external/llvm-libunwind/src/Unwind-sjlj.c @@ -82,7 +82,8 @@ struct _Unwind_FunctionContext { static _LIBUNWIND_THREAD_LOCAL struct _Unwind_FunctionContext *stack = NULL; #endif -static struct _Unwind_FunctionContext *__Unwind_SjLj_GetTopOfFunctionStack() { +static struct _Unwind_FunctionContext * +__Unwind_SjLj_GetTopOfFunctionStack(void) { #if defined(__APPLE__) return _pthread_getspecific_direct(__PTK_LIBC_DYLD_Unwind_SjLj_Key); #else @@ -426,7 +427,7 @@ _LIBUNWIND_EXPORT uintptr_t _Unwind_GetGR(struct _Unwind_Context *context, /// 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%" PRIuPTR + _LIBUNWIND_TRACE_API("_Unwind_SetGR(context=%p, reg=%d, value=0x%" PRIxPTR ")", (void *)context, index, new_value); _Unwind_FunctionContext_t ufc = (_Unwind_FunctionContext_t) context; @@ -437,7 +438,7 @@ _LIBUNWIND_EXPORT void _Unwind_SetGR(struct _Unwind_Context *context, int index, /// 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%" PRIu32, + _LIBUNWIND_TRACE_API("_Unwind_GetIP(context=%p) => 0x%" PRIxPTR, (void *)context, ufc->resumeLocation + 1); return ufc->resumeLocation + 1; } @@ -450,7 +451,7 @@ _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%" PRIu32, + _LIBUNWIND_TRACE_API("_Unwind_GetIPInfo(context=%p, %p) => 0x%" PRIxPTR, (void *)context, (void *)ipBefore, ufc->resumeLocation + 1); return ufc->resumeLocation + 1; @@ -460,7 +461,7 @@ _LIBUNWIND_EXPORT uintptr_t _Unwind_GetIPInfo(struct _Unwind_Context *context, /// 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%" PRIuPTR ")", + _LIBUNWIND_TRACE_API("_Unwind_SetIP(context=%p, value=0x%" PRIxPTR ")", (void *)context, new_value); _Unwind_FunctionContext_t ufc = (_Unwind_FunctionContext_t) context; ufc->resumeLocation = new_value - 1; diff --git a/src/native/external/llvm-libunwind/src/Unwind-wasm.c b/src/native/external/llvm-libunwind/src/Unwind-wasm.c new file mode 100644 index 0000000000000..f7f39d38b59c1 --- /dev/null +++ b/src/native/external/llvm-libunwind/src/Unwind-wasm.c @@ -0,0 +1,123 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +// +// Implements Wasm exception handling proposal +// (https://github.com/WebAssembly/exception-handling) based C++ exceptions +// +//===----------------------------------------------------------------------===// + +#include + +#include "config.h" + +#ifdef __USING_WASM_EXCEPTIONS__ + +#include "unwind.h" +#include + +_Unwind_Reason_Code __gxx_personality_wasm0(int version, _Unwind_Action actions, + uint64_t exceptionClass, + _Unwind_Exception *unwind_exception, + _Unwind_Context *context); + +struct _Unwind_LandingPadContext { + // Input information to personality function + uintptr_t lpad_index; // landing pad index + uintptr_t lsda; // LSDA address + + // Output information computed by personality function + uintptr_t selector; // selector value +}; + +// Communication channel between compiler-generated user code and personality +// function +thread_local struct _Unwind_LandingPadContext __wasm_lpad_context; + +/// Calls to this function is in landing pads in compiler-generated user code. +/// In other EH schemes, stack unwinding is done by libunwind library, which +/// calls the personality function for each each frame it lands. On the other +/// hand, WebAssembly stack unwinding process is performed by a VM, and the +/// personality function cannot be called from there. So the compiler inserts +/// a call to this function in landing pads in the user code, which in turn +/// calls the personality function. +_Unwind_Reason_Code _Unwind_CallPersonality(void *exception_ptr) { + struct _Unwind_Exception *exception_object = + (struct _Unwind_Exception *)exception_ptr; + _LIBUNWIND_TRACE_API("_Unwind_CallPersonality(exception_object=%p)", + (void *)exception_object); + + // Reset the selector. + __wasm_lpad_context.selector = 0; + + // Call personality function. Wasm does not have two-phase unwinding, so we + // only do the cleanup phase. + return __gxx_personality_wasm0( + 1, _UA_SEARCH_PHASE, exception_object->exception_class, exception_object, + (struct _Unwind_Context *)&__wasm_lpad_context); +} + +/// Called by __cxa_throw. +_LIBUNWIND_EXPORT _Unwind_Reason_Code +_Unwind_RaiseException(_Unwind_Exception *exception_object) { + _LIBUNWIND_TRACE_API("_Unwind_RaiseException(exception_object=%p)", + (void *)exception_object); + // Use Wasm EH's 'throw' instruction. + __builtin_wasm_throw(0, exception_object); +} + +/// Called by __cxa_end_catch. +_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 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, index=%d, value=%lu)", + (void *)context, index, value); + // We only use this function to set __wasm_lpad_context.selector field, which + // is index 1 in the personality function. + if (index == 1) + ((struct _Unwind_LandingPadContext *)context)->selector = value; +} + +/// Called by personality handler to get instruction pointer. +_LIBUNWIND_EXPORT uintptr_t _Unwind_GetIP(struct _Unwind_Context *context) { + // The result will be used as an 1-based index after decrementing 1, so we + // increment 2 here + uintptr_t result = + ((struct _Unwind_LandingPadContext *)context)->lpad_index + 2; + _LIBUNWIND_TRACE_API("_Unwind_GetIP(context=%p) => %lu", (void *)context, + result); + return result; +} + +/// Not used in Wasm. +_LIBUNWIND_EXPORT void _Unwind_SetIP(struct _Unwind_Context *context, + uintptr_t value) {} + +/// Called by personality handler to get LSDA for current frame. +_LIBUNWIND_EXPORT uintptr_t +_Unwind_GetLanguageSpecificData(struct _Unwind_Context *context) { + uintptr_t result = ((struct _Unwind_LandingPadContext *)context)->lsda; + _LIBUNWIND_TRACE_API("_Unwind_GetLanguageSpecificData(context=%p) => 0x%lx", + (void *)context, result); + return result; +} + +/// Not used in Wasm. +_LIBUNWIND_EXPORT uintptr_t +_Unwind_GetRegionStart(struct _Unwind_Context *context) { + return 0; +} + +#endif // defined(__USING_WASM_EXCEPTIONS__) diff --git a/src/native/external/llvm-libunwind/src/UnwindCursor.hpp b/src/native/external/llvm-libunwind/src/UnwindCursor.hpp index 67f4d16ef14d3..7753936a5894a 100644 --- a/src/native/external/llvm-libunwind/src/UnwindCursor.hpp +++ b/src/native/external/llvm-libunwind/src/UnwindCursor.hpp @@ -31,7 +31,10 @@ #endif #if defined(_LIBUNWIND_TARGET_LINUX) && \ - (defined(_LIBUNWIND_TARGET_AARCH64) || defined(_LIBUNWIND_TARGET_S390X)) + (defined(_LIBUNWIND_TARGET_AARCH64) || defined(_LIBUNWIND_TARGET_RISCV) || \ + defined(_LIBUNWIND_TARGET_S390X)) +#include +#include #include #include #include @@ -430,12 +433,9 @@ class _LIBUNWIND_HIDDEN AbstractUnwindCursor { 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, unw_word_t) { + virtual void setReg(int, unw_word_t) { _LIBUNWIND_ABORT("setReg not implemented"); } - virtual unw_word_t getRegLocation(int) { - _LIBUNWIND_ABORT("getRegLocation not implemented"); - } virtual bool validFloatReg(int) { _LIBUNWIND_ABORT("validFloatReg not implemented"); } @@ -509,7 +509,14 @@ class UnwindCursor : public AbstractUnwindCursor { #endif DISPATCHER_CONTEXT *getDispatcherContext() { return &_dispContext; } - void setDispatcherContext(DISPATCHER_CONTEXT *disp) { _dispContext = *disp; } + void setDispatcherContext(DISPATCHER_CONTEXT *disp) { + _dispContext = *disp; + _info.lsda = reinterpret_cast(_dispContext.HandlerData); + if (_dispContext.LanguageHandler) { + _info.handler = reinterpret_cast(__libunwind_seh_personality); + } else + _info.handler = 0; + } // libunwind does not and should not depend on C++ library which means that we // need our own definition of inline placement new. @@ -571,10 +578,12 @@ UnwindCursor::UnwindCursor(unw_context_t *context, A &as) "UnwindCursor<> requires more alignment than unw_cursor_t"); memset(&_info, 0, sizeof(_info)); memset(&_histTable, 0, sizeof(_histTable)); + memset(&_dispContext, 0, sizeof(_dispContext)); _dispContext.ContextRecord = &_msContext; _dispContext.HistoryTable = &_histTable; // Initialize MS context from ours. R r(context); + RtlCaptureContext(&_msContext); _msContext.ContextFlags = CONTEXT_CONTROL|CONTEXT_INTEGER|CONTEXT_FLOATING_POINT; #if defined(_LIBUNWIND_TARGET_X86_64) _msContext.Rax = r.getRegister(UNW_X86_64_RAX); @@ -672,6 +681,7 @@ UnwindCursor::UnwindCursor(CONTEXT *context, A &as) "UnwindCursor<> does not fit in unw_cursor_t"); memset(&_info, 0, sizeof(_info)); memset(&_histTable, 0, sizeof(_histTable)); + memset(&_dispContext, 0, sizeof(_dispContext)); _dispContext.ContextRecord = &_msContext; _dispContext.HistoryTable = &_histTable; _msContext = *context; @@ -682,7 +692,7 @@ template bool UnwindCursor::validReg(int regNum) { if (regNum == UNW_REG_IP || regNum == UNW_REG_SP) return true; #if defined(_LIBUNWIND_TARGET_X86_64) - if (regNum >= UNW_X86_64_RAX && regNum <= UNW_X86_64_R15) return true; + if (regNum >= UNW_X86_64_RAX && regNum <= UNW_X86_64_RIP) return true; #elif defined(_LIBUNWIND_TARGET_ARM) if ((regNum >= UNW_ARM_R0 && regNum <= UNW_ARM_R15) || regNum == UNW_ARM_RA_AUTH_CODE) @@ -697,6 +707,7 @@ template unw_word_t UnwindCursor::getReg(int regNum) { switch (regNum) { #if defined(_LIBUNWIND_TARGET_X86_64) + case UNW_X86_64_RIP: case UNW_REG_IP: return _msContext.Rip; case UNW_X86_64_RAX: return _msContext.Rax; case UNW_X86_64_RDX: return _msContext.Rdx; @@ -747,6 +758,7 @@ template void UnwindCursor::setReg(int regNum, unw_word_t value) { switch (regNum) { #if defined(_LIBUNWIND_TARGET_X86_64) + case UNW_X86_64_RIP: case UNW_REG_IP: _msContext.Rip = value; break; case UNW_X86_64_RAX: _msContext.Rax = value; break; case UNW_X86_64_RDX: _msContext.Rdx = value; break; @@ -919,14 +931,12 @@ template class UnwindCursor : public AbstractUnwindCursor{ typedef typename A::pint_t pint_t; public: - UnwindCursor(A &as); 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, unw_word_t); - virtual unw_word_t getRegLocation(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); @@ -956,7 +966,6 @@ class UnwindCursor : public AbstractUnwindCursor{ private: #if defined(_LIBUNWIND_ARM_EHABI) -public: bool getInfoFromEHABISection(pint_t pc, const UnwindInfoSections §s); int stepWithEHABI() { @@ -983,10 +992,15 @@ class UnwindCursor : public AbstractUnwindCursor{ R dummy; return stepThroughSigReturn(dummy); } + bool isReadableAddr(const pint_t addr) const; #if defined(_LIBUNWIND_TARGET_AARCH64) bool setInfoForSigReturn(Registers_arm64 &); int stepThroughSigReturn(Registers_arm64 &); #endif +#if defined(_LIBUNWIND_TARGET_RISCV) + bool setInfoForSigReturn(Registers_riscv &); + int stepThroughSigReturn(Registers_riscv &); +#endif #if defined(_LIBUNWIND_TARGET_S390X) bool setInfoForSigReturn(Registers_s390x &); int stepThroughSigReturn(Registers_s390x &); @@ -1003,8 +1017,6 @@ class UnwindCursor : public AbstractUnwindCursor{ bool getInfoFromFdeCie(const typename CFI_Parser::FDE_Info &fdeInfo, const typename CFI_Parser::CIE_Info &cieInfo, pint_t pc, uintptr_t dso_base); - -public: bool getInfoFromDwarfSection(pint_t pc, const UnwindInfoSections §s, uint32_t fdeSectionOffsetHint=0); int stepWithDwarfFDE(bool stage2) { @@ -1307,13 +1319,6 @@ class UnwindCursor : public AbstractUnwindCursor{ #endif }; -template -UnwindCursor::UnwindCursor(A &as) - : _addressSpace(as) - , _unwindInfoMissing(false) - , _isSignalFrame(false) { - memset(&_info, 0, sizeof(_info)); -} template UnwindCursor::UnwindCursor(unw_context_t *context, A &as) @@ -1327,11 +1332,9 @@ UnwindCursor::UnwindCursor(unw_context_t *context, A &as) } template -UnwindCursor::UnwindCursor(A &as, void *arg) - : _addressSpace(as),_registers(arg), _unwindInfoMissing(false), - _isSignalFrame(false) { +UnwindCursor::UnwindCursor(A &as, void *) + : _addressSpace(as), _unwindInfoMissing(false), _isSignalFrame(false) { memset(&_info, 0, sizeof(_info)); - // FIXME // fill in _registers from thread arg } @@ -1348,13 +1351,8 @@ unw_word_t UnwindCursor::getReg(int regNum) { } template -void UnwindCursor::setReg(int regNum, unw_word_t value, unw_word_t location) { - _registers.setRegister(regNum, (typename A::pint_t)value, (typename A::pint_t)location); -} - -template -unw_word_t UnwindCursor::getRegLocation(int regNum) { - return _registers.getRegisterLocation(regNum); +void UnwindCursor::setReg(int regNum, unw_word_t value) { + _registers.setRegister(regNum, (typename A::pint_t)value); } template @@ -1661,7 +1659,6 @@ bool UnwindCursor::getInfoFromDwarfSection(pint_t pc, typename CFI_Parser::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::findFDE(_addressSpace, pc, sects.dwarf_section, @@ -1669,7 +1666,6 @@ bool UnwindCursor::getInfoFromDwarfSection(pint_t pc, sects.dwarf_section + fdeSectionOffsetHint, &fdeInfo, &cieInfo); } - #if defined(_LIBUNWIND_SUPPORT_DWARF_INDEX) if (!foundFDE && (sects.dwarf_index_section != 0)) { foundFDE = EHHeaderParser::findFDE( @@ -1677,7 +1673,6 @@ bool UnwindCursor::getInfoFromDwarfSection(pint_t pc, (uint32_t)sects.dwarf_index_section_length, &fdeInfo, &cieInfo); } #endif - if (!foundFDE) { // otherwise, search cache of previously found FDEs. pint_t cachedFDE = DwarfFDECache::findFDE(sects.dso_base, pc); @@ -2003,6 +1998,9 @@ bool UnwindCursor::getInfoFromSEH(pint_t pc) { uint32_t lastcode = (xdata->CountOfCodes + 1) & ~1; const uint32_t *handler = reinterpret_cast(&xdata->UnwindCodes[lastcode]); _info.lsda = reinterpret_cast(handler+1); + _dispContext.HandlerData = reinterpret_cast(_info.lsda); + _dispContext.LanguageHandler = + reinterpret_cast(base + *handler); if (*handler) { _info.handler = reinterpret_cast(__libunwind_seh_personality); } else @@ -2306,27 +2304,39 @@ int UnwindCursor::stepWithTBTable(pint_t pc, tbtable *TBTable, if (!getFunctionName(functionBuf, sizeof(functionBuf), &offset)) { functionName = ".anonymous."; } - _LIBUNWIND_TRACE_UNWINDING("%s: Look up traceback table of func=%s at %p", - __func__, functionName, - reinterpret_cast(TBTable)); + _LIBUNWIND_TRACE_UNWINDING( + "%s: Look up traceback table of func=%s at %p, pc=%p, " + "SP=%p, saves_lr=%d, stores_bc=%d", + __func__, functionName, reinterpret_cast(TBTable), + reinterpret_cast(pc), + reinterpret_cast(registers.getSP()), TBTable->tb.saves_lr, + TBTable->tb.stores_bc); } #if defined(__powerpc64__) - // Instruction to reload TOC register "l r2,40(r1)" + // Instruction to reload TOC register "ld r2,40(r1)" const uint32_t loadTOCRegInst = 0xe8410028; const int32_t unwPPCF0Index = UNW_PPC64_F0; const int32_t unwPPCV0Index = UNW_PPC64_V0; #else - // Instruction to reload TOC register "l r2,20(r1)" + // Instruction to reload TOC register "lwz r2,20(r1)" const uint32_t loadTOCRegInst = 0x80410014; const int32_t unwPPCF0Index = UNW_PPC_F0; const int32_t unwPPCV0Index = UNW_PPC_V0; #endif + // lastStack points to the stack frame of the next routine up. + pint_t curStack = static_cast(registers.getSP()); + pint_t lastStack = *reinterpret_cast(curStack); + + if (lastStack == 0) + return UNW_STEP_END; + R newRegisters = registers; - // lastStack points to the stack frame of the next routine up. - pint_t lastStack = *(reinterpret_cast(registers.getSP())); + // If backchain is not stored, use the current stack frame. + if (!TBTable->tb.stores_bc) + lastStack = curStack; // Return address is the address after call site instruction. pint_t returnAddress; @@ -2336,33 +2346,41 @@ int UnwindCursor::stepWithTBTable(pint_t pc, tbtable *TBTable, reinterpret_cast(lastStack)); sigcontext *sigContext = reinterpret_cast( - reinterpret_cast(lastStack) + STKMIN); + reinterpret_cast(lastStack) + STKMINALIGN); returnAddress = sigContext->sc_jmpbuf.jmp_context.iar; - _LIBUNWIND_TRACE_UNWINDING("From sigContext=%p, returnAddress=%p\n", - reinterpret_cast(sigContext), - reinterpret_cast(returnAddress)); - + bool useSTKMIN = false; if (returnAddress < 0x10000000) { - // Try again using STKMINALIGN + // Try again using STKMIN. sigContext = reinterpret_cast( - reinterpret_cast(lastStack) + STKMINALIGN); + reinterpret_cast(lastStack) + STKMIN); returnAddress = sigContext->sc_jmpbuf.jmp_context.iar; if (returnAddress < 0x10000000) { - _LIBUNWIND_TRACE_UNWINDING("Bad returnAddress=%p\n", - reinterpret_cast(returnAddress)); + _LIBUNWIND_TRACE_UNWINDING("Bad returnAddress=%p from sigcontext=%p", + reinterpret_cast(returnAddress), + reinterpret_cast(sigContext)); return UNW_EBADFRAME; - } else { - _LIBUNWIND_TRACE_UNWINDING("Tried again using STKMINALIGN: " - "sigContext=%p, returnAddress=%p. " - "Seems to be a valid address\n", - reinterpret_cast(sigContext), - reinterpret_cast(returnAddress)); } + useSTKMIN = true; } + _LIBUNWIND_TRACE_UNWINDING("Returning from a signal handler %s: " + "sigContext=%p, returnAddress=%p. " + "Seems to be a valid address", + useSTKMIN ? "STKMIN" : "STKMINALIGN", + reinterpret_cast(sigContext), + reinterpret_cast(returnAddress)); + // Restore the condition register from sigcontext. newRegisters.setCR(sigContext->sc_jmpbuf.jmp_context.cr); + // Save the LR in sigcontext for stepping up when the function that + // raised the signal is a leaf function. This LR has the return address + // to the caller of the leaf function. + newRegisters.setLR(sigContext->sc_jmpbuf.jmp_context.lr); + _LIBUNWIND_TRACE_UNWINDING( + "Save LR=%p from sigcontext", + reinterpret_cast(sigContext->sc_jmpbuf.jmp_context.lr)); + // Restore GPRs from sigcontext. for (int i = 0; i < 32; ++i) newRegisters.setRegister(i, sigContext->sc_jmpbuf.jmp_context.gpr[i]); @@ -2385,13 +2403,26 @@ int UnwindCursor::stepWithTBTable(pint_t pc, tbtable *TBTable, } } else { // Step up a normal frame. - returnAddress = reinterpret_cast(lastStack)[2]; - _LIBUNWIND_TRACE_UNWINDING("Extract info from lastStack=%p, " - "returnAddress=%p\n", - reinterpret_cast(lastStack), - reinterpret_cast(returnAddress)); - _LIBUNWIND_TRACE_UNWINDING("fpr_regs=%d, gpr_regs=%d, saves_cr=%d\n", + if (!TBTable->tb.saves_lr && registers.getLR()) { + // This case should only occur if we were called from a signal handler + // and the signal occurred in a function that doesn't save the LR. + returnAddress = static_cast(registers.getLR()); + _LIBUNWIND_TRACE_UNWINDING("Use saved LR=%p", + reinterpret_cast(returnAddress)); + } else { + // Otherwise, use the LR value in the stack link area. + returnAddress = reinterpret_cast(lastStack)[2]; + } + + // Reset LR in the current context. + newRegisters.setLR(NULL); + + _LIBUNWIND_TRACE_UNWINDING( + "Extract info from lastStack=%p, returnAddress=%p", + reinterpret_cast(lastStack), + reinterpret_cast(returnAddress)); + _LIBUNWIND_TRACE_UNWINDING("fpr_regs=%d, gpr_regs=%d, saves_cr=%d", TBTable->tb.fpr_saved, TBTable->tb.gpr_saved, TBTable->tb.saves_cr); @@ -2455,7 +2486,7 @@ int UnwindCursor::stepWithTBTable(pint_t pc, tbtable *TBTable, struct vec_ext *vec_ext = reinterpret_cast(charPtr); - _LIBUNWIND_TRACE_UNWINDING("vr_saved=%d\n", vec_ext->vr_saved); + _LIBUNWIND_TRACE_UNWINDING("vr_saved=%d", vec_ext->vr_saved); // Restore vector register(s) if saved on the stack. if (vec_ext->vr_saved) { @@ -2485,11 +2516,11 @@ int UnwindCursor::stepWithTBTable(pint_t pc, tbtable *TBTable, // Do we need to set the TOC register? _LIBUNWIND_TRACE_UNWINDING( - "Current gpr2=%p\n", + "Current gpr2=%p", reinterpret_cast(newRegisters.getRegister(2))); if (firstInstruction == loadTOCRegInst) { _LIBUNWIND_TRACE_UNWINDING( - "Set gpr2=%p from frame\n", + "Set gpr2=%p from frame", reinterpret_cast(reinterpret_cast(lastStack)[5])); newRegisters.setRegister(2, reinterpret_cast(lastStack)[5]); } @@ -2521,7 +2552,6 @@ int UnwindCursor::stepWithTBTable(pint_t pc, tbtable *TBTable, } else { isSignalFrame = false; } - return UNW_STEP_SUCCESS; } #endif // defined(_LIBUNWIND_SUPPORT_TBTAB_UNWIND) @@ -2673,20 +2703,12 @@ bool UnwindCursor::setInfoForSigReturn(Registers_arm64 &) { // [1] https://github.com/torvalds/linux/blob/master/arch/arm64/kernel/vdso/sigreturn.S const pint_t pc = static_cast(this->getReg(UNW_REG_IP)); // The PC might contain an invalid address if the unwind info is bad, so - // directly accessing it could cause a segfault. Use process_vm_readv to read - // the memory safely instead. process_vm_readv was added in Linux 3.2, and - // AArch64 supported was added in Linux 3.7, so the syscall is guaranteed to - // be present. Unfortunately, there are Linux AArch64 environments where the - // libc wrapper for the syscall might not be present (e.g. Android 5), so call - // the syscall directly instead. - uint32_t instructions[2]; - struct iovec local_iov = {&instructions, sizeof instructions}; - struct iovec remote_iov = {reinterpret_cast(pc), sizeof instructions}; - long bytesRead = - syscall(SYS_process_vm_readv, getpid(), &local_iov, 1, &remote_iov, 1, 0); + // directly accessing it could cause a SIGSEGV. + if (!isReadableAddr(pc)) + return false; + auto *instructions = reinterpret_cast(pc); // Look for instructions: mov x8, #0x8b; svc #0x0 - if (bytesRead != sizeof instructions || instructions[0] != 0xd2801168 || - instructions[1] != 0xd4000001) + if (instructions[0] != 0xd2801168 || instructions[1] != 0xd4000001) return false; _info = {}; @@ -2720,16 +2742,69 @@ int UnwindCursor::stepThroughSigReturn(Registers_arm64 &) { for (int i = 0; i <= 30; ++i) { uint64_t value = _addressSpace.get64(sigctx + kOffsetGprs + static_cast(i * 8)); - _registers.setRegister(UNW_AARCH64_X0 + i, value, 0); + _registers.setRegister(UNW_AARCH64_X0 + i, value); } - _registers.setSP(_addressSpace.get64(sigctx + kOffsetSp), 0); - _registers.setIP(_addressSpace.get64(sigctx + kOffsetPc), 0); + _registers.setSP(_addressSpace.get64(sigctx + kOffsetSp)); + _registers.setIP(_addressSpace.get64(sigctx + kOffsetPc)); _isSignalFrame = true; return UNW_STEP_SUCCESS; } #endif // defined(_LIBUNWIND_CHECK_LINUX_SIGRETURN) && // defined(_LIBUNWIND_TARGET_AARCH64) +#if defined(_LIBUNWIND_CHECK_LINUX_SIGRETURN) && \ + defined(_LIBUNWIND_TARGET_RISCV) +template +bool UnwindCursor::setInfoForSigReturn(Registers_riscv &) { + const pint_t pc = static_cast(getReg(UNW_REG_IP)); + // The PC might contain an invalid address if the unwind info is bad, so + // directly accessing it could cause a SIGSEGV. + if (!isReadableAddr(pc)) + return false; + const auto *instructions = reinterpret_cast(pc); + // Look for the two instructions used in the sigreturn trampoline + // __vdso_rt_sigreturn: + // + // 0x08b00893 li a7,0x8b + // 0x00000073 ecall + if (instructions[0] != 0x08b00893 || instructions[1] != 0x00000073) + return false; + + _info = {}; + _info.start_ip = pc; + _info.end_ip = pc + 4; + _isSigReturn = true; + return true; +} + +template +int UnwindCursor::stepThroughSigReturn(Registers_riscv &) { + // In the signal trampoline frame, sp points to an rt_sigframe[1], which is: + // - 128-byte siginfo struct + // - ucontext_t struct: + // - 8-byte long (__uc_flags) + // - 8-byte pointer (*uc_link) + // - 24-byte uc_stack + // - 8-byte uc_sigmask + // - 120-byte of padding to allow sigset_t to be expanded in the future + // - 8 bytes of padding because sigcontext has 16-byte alignment + // - struct sigcontext uc_mcontext + // [1] + // https://github.com/torvalds/linux/blob/master/arch/riscv/kernel/signal.c + const pint_t kOffsetSpToSigcontext = 128 + 8 + 8 + 24 + 8 + 128; + + const pint_t sigctx = _registers.getSP() + kOffsetSpToSigcontext; + _registers.setIP(_addressSpace.get64(sigctx)); + for (int i = UNW_RISCV_X1; i <= UNW_RISCV_X31; ++i) { + uint64_t value = _addressSpace.get64(sigctx + static_cast(i * 8)); + _registers.setRegister(i, value); + } + _isSignalFrame = true; + return UNW_STEP_SUCCESS; +} +#endif // defined(_LIBUNWIND_CHECK_LINUX_SIGRETURN) && + // defined(_LIBUNWIND_TARGET_RISCV) + #if defined(_LIBUNWIND_CHECK_LINUX_SIGRETURN) && \ defined(_LIBUNWIND_TARGET_S390X) template @@ -2741,13 +2816,11 @@ bool UnwindCursor::setInfoForSigReturn(Registers_s390x &) { // onto the stack. const pint_t pc = static_cast(this->getReg(UNW_REG_IP)); // The PC might contain an invalid address if the unwind info is bad, so - // directly accessing it could cause a segfault. Use process_vm_readv to - // read the memory safely instead. - uint16_t inst; - struct iovec local_iov = {&inst, sizeof inst}; - struct iovec remote_iov = {reinterpret_cast(pc), sizeof inst}; - long bytesRead = process_vm_readv(getpid(), &local_iov, 1, &remote_iov, 1, 0); - if (bytesRead == sizeof inst && (inst == 0x0a77 || inst == 0x0aad)) { + // directly accessing it could cause a SIGSEGV. + if (!isReadableAddr(pc)) + return false; + const auto inst = *reinterpret_cast(pc); + if (inst == 0x0a77 || inst == 0x0aad) { _info = {}; _info.start_ip = pc; _info.end_ip = pc + 2; @@ -2893,6 +2966,37 @@ bool UnwindCursor::getFunctionName(char *buf, size_t bufLen, buf, bufLen, offset); } +#if defined(_LIBUNWIND_CHECK_LINUX_SIGRETURN) +template +bool UnwindCursor::isReadableAddr(const pint_t addr) const { + // We use SYS_rt_sigprocmask, inspired by Abseil's AddressIsReadable. + + const auto sigsetAddr = reinterpret_cast(addr); + // We have to check that addr is nullptr because sigprocmask allows that + // as an argument without failure. + if (!sigsetAddr) + return false; + const auto saveErrno = errno; + // We MUST use a raw syscall here, as wrappers may try to access + // sigsetAddr which may cause a SIGSEGV. A raw syscall however is + // safe. Additionally, we need to pass the kernel_sigset_size, which is + // different from libc sizeof(sigset_t). For the majority of architectures, + // it's 64 bits (_NSIG), and libc NSIG is _NSIG + 1. + const auto kernelSigsetSize = NSIG / 8; + [[maybe_unused]] const int Result = syscall( + SYS_rt_sigprocmask, /*how=*/~0, sigsetAddr, nullptr, kernelSigsetSize); + // Because our "how" is invalid, this syscall should always fail, and our + // errno should always be EINVAL or an EFAULT. This relies on the Linux + // kernel to check copy_from_user before checking if the "how" argument is + // invalid. + assert(Result == -1); + assert(errno == EFAULT || errno == EINVAL); + const auto readable = errno != EFAULT; + errno = saveErrno; + return readable; +} +#endif + #if defined(_LIBUNWIND_USE_CET) extern "C" void *__libunwind_cet_get_registers(unw_cursor_t *cursor) { AbstractUnwindCursor *co = (AbstractUnwindCursor *)cursor; diff --git a/src/native/external/llvm-libunwind/src/UnwindLevel1-gcc-ext.c b/src/native/external/llvm-libunwind/src/UnwindLevel1-gcc-ext.c index efb872bbe59eb..32c872ffade1f 100644 --- a/src/native/external/llvm-libunwind/src/UnwindLevel1-gcc-ext.c +++ b/src/native/external/llvm-libunwind/src/UnwindLevel1-gcc-ext.c @@ -143,7 +143,7 @@ _Unwind_Backtrace(_Unwind_Trace_Fn callback, void *ref) { // Create a mock exception object for force unwinding. _Unwind_Exception ex; memset(&ex, '\0', sizeof(ex)); - strcpy((char *)&ex.exception_class, "CLNGUNW"); + memcpy(&ex.exception_class, "CLNGUNW", sizeof(ex.exception_class)); #endif // walk each frame @@ -167,7 +167,7 @@ _Unwind_Backtrace(_Unwind_Trace_Fn callback, void *ref) { } // Update the pr_cache in the mock exception object. - const uint32_t* unwindInfo = (uint32_t *) frameInfo.unwind_info; + 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; diff --git a/src/native/external/llvm-libunwind/src/UnwindLevel1.c b/src/native/external/llvm-libunwind/src/UnwindLevel1.c index 7e9adf64246df..05d0f2cb0a0a7 100644 --- a/src/native/external/llvm-libunwind/src/UnwindLevel1.c +++ b/src/native/external/llvm-libunwind/src/UnwindLevel1.c @@ -321,7 +321,7 @@ unwind_phase2_forced(unw_context_t *uc, unw_cursor_t *cursor, unw_proc_info_t frameInfo; if (__unw_get_proc_info(cursor, &frameInfo) != UNW_ESUCCESS) { _LIBUNWIND_TRACE_UNWINDING( - "unwind_phase2_forced(ex_obj=%p): __unw_step_stage2 " + "unwind_phase2_forced(ex_obj=%p): __unw_get_proc_info " "failed => _URC_END_OF_STACK", (void *)exception_object); return _URC_FATAL_PHASE2_ERROR; diff --git a/src/native/external/llvm-libunwind/src/UnwindRegistersRestore.S b/src/native/external/llvm-libunwind/src/UnwindRegistersRestore.S index 5d9607ad798dd..42c2488fc7cf7 100644 --- a/src/native/external/llvm-libunwind/src/UnwindRegistersRestore.S +++ b/src/native/external/llvm-libunwind/src/UnwindRegistersRestore.S @@ -645,7 +645,8 @@ DEFINE_LIBUNWIND_FUNCTION(__libunwind_Registers_arm64_jumpto) ldp x10,x11, [x0, #0x050] ldp x12,x13, [x0, #0x060] ldp x14,x15, [x0, #0x070] - ldp x16,x17, [x0, #0x080] + // x16 and x17 were clobbered by the call into the unwinder, so no point in + // restoring them. ldp x18,x19, [x0, #0x090] ldp x20,x21, [x0, #0x0A0] ldp x22,x23, [x0, #0x0B0] @@ -653,8 +654,6 @@ DEFINE_LIBUNWIND_FUNCTION(__libunwind_Registers_arm64_jumpto) 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] @@ -674,7 +673,13 @@ DEFINE_LIBUNWIND_FUNCTION(__libunwind_Registers_arm64_jumpto) ldr d30, [x0, #0x200] ldr d31, [x0, #0x208] + // Finally, restore sp. This must be done after the last read from the + // context struct, because it is allocated on the stack, and an exception + // could clobber the de-allocated portion of the stack after sp has been + // restored. + ldr x16, [x0, #0x0F8] ldp x0, x1, [x0, #0x000] // restore x0,x1 + mov sp,x16 // restore sp ret x30 // jump to pc #elif defined(__arm__) && !defined(__APPLE__) @@ -988,11 +993,13 @@ DEFINE_LIBUNWIND_FUNCTION(_ZN9libunwind18Registers_mips_o326jumptoEv) ldc1 $f31, (4 * 36 + 8 * 31)($4) #endif #endif +#if __mips_isa_rev < 6 // restore hi and lo lw $8, (4 * 33)($4) mthi $8 lw $8, (4 * 34)($4) mtlo $8 +#endif // r0 is zero lw $1, (4 * 1)($4) lw $2, (4 * 2)($4) @@ -1049,11 +1056,13 @@ DEFINE_LIBUNWIND_FUNCTION(_ZN9libunwind21Registers_mips_newabi6jumptoEv) ldc1 $f\i, (280+8*\i)($4) .endr #endif +#if __mips_isa_rev < 6 // restore hi and lo ld $8, (8 * 33)($4) mthi $8 ld $8, (8 * 34)($4) mtlo $8 +#endif // r0 is zero ld $1, (8 * 1)($4) ld $2, (8 * 2)($4) diff --git a/src/native/external/llvm-libunwind/src/UnwindRegistersSave.S b/src/native/external/llvm-libunwind/src/UnwindRegistersSave.S index 79f5696a9888f..19a0e87d683ce 100644 --- a/src/native/external/llvm-libunwind/src/UnwindRegistersSave.S +++ b/src/native/external/llvm-libunwind/src/UnwindRegistersSave.S @@ -174,11 +174,13 @@ DEFINE_LIBUNWIND_FUNCTION(__unw_getcontext) sw $31, (4 * 31)($4) # Store return address to pc sw $31, (4 * 32)($4) +#if __mips_isa_rev < 6 # hi and lo mfhi $8 sw $8, (4 * 33)($4) mflo $8 sw $8, (4 * 34)($4) +#endif #ifdef __mips_hard_float #if __mips_fpr != 64 sdc1 $f0, (4 * 36 + 8 * 0)($4) @@ -255,11 +257,13 @@ DEFINE_LIBUNWIND_FUNCTION(__unw_getcontext) .endr # Store return address to pc sd $31, (8 * 32)($4) +#if __mips_isa_rev < 6 # hi and lo mfhi $8 sd $8, (8 * 33)($4) mflo $8 sd $8, (8 * 34)($4) +#endif #ifdef __mips_hard_float .irp i,FROM_0_TO_31 sdc1 $f\i, (280+8*\i)($4) @@ -301,9 +305,21 @@ DEFINE_LIBUNWIND_FUNCTION(__unw_getcontext) mflr 0 std 0, PPC64_OFFS_SRR0(3) // store lr as ssr0 PPC64_STR(1) + PPC64_STR(4) // Save r4 first since it will be used for fixing r2. +#if defined(_AIX) + // The TOC register (r2) was changed by the glue code if unw_getcontext + // is called from a different module. Save the original TOC register + // in the context if this is the case. + mflr 4 + lwz 4, 0(4) // Get the first instruction at the return address. + xoris 0, 4, 0xe841 // Is it reloading the TOC register "ld 2,40(1)"? + cmplwi 0, 0x28 + bne 0, LnoR2Fix // No need to fix up r2 if it is not. + ld 2, 40(1) // Use the saved TOC register in the stack. +LnoR2Fix: +#endif PPC64_STR(2) PPC64_STR(3) - PPC64_STR(4) PPC64_STR(5) PPC64_STR(6) PPC64_STR(7) @@ -336,7 +352,12 @@ DEFINE_LIBUNWIND_FUNCTION(__unw_getcontext) std 0, PPC64_OFFS_CR(3) mfxer 0 std 0, PPC64_OFFS_XER(3) +#if defined(_AIX) + // LR value saved from the register is not used, initialize it to 0. + li 0, 0 +#else mflr 0 +#endif std 0, PPC64_OFFS_LR(3) mfctr 0 std 0, PPC64_OFFS_CTR(3) @@ -543,9 +564,21 @@ DEFINE_LIBUNWIND_FUNCTION(__unw_getcontext) mflr 0 stw 0, 0(3) // store lr as ssr0 stw 1, 12(3) + stw 4, 24(3) // Save r4 first since it will be used for fixing r2. +#if defined(_AIX) + // The TOC register (r2) was changed by the glue code if unw_getcontext + // is called from a different module. Save the original TOC register + // in the context if this is the case. + mflr 4 + lwz 4, 0(4) // Get the instruction at the return address. + xoris 0, 4, 0x8041 // Is it reloading the TOC register "lwz 2,20(1)"? + cmplwi 0, 0x14 + bne 0, LnoR2Fix // No need to fix up r2 if it is not. + lwz 2, 20(1) // Use the saved TOC register in the stack. +LnoR2Fix: +#endif stw 2, 16(3) stw 3, 20(3) - stw 4, 24(3) stw 5, 28(3) stw 6, 32(3) stw 7, 36(3) @@ -582,6 +615,11 @@ DEFINE_LIBUNWIND_FUNCTION(__unw_getcontext) // save CR registers mfcr 0 stw 0, 136(3) +#if defined(_AIX) + // LR value from the register is not used, initialize it to 0. + li 0, 0 + stw 0, 144(3) +#endif // save CTR register mfctr 0 stw 0, 148(3) @@ -742,7 +780,7 @@ DEFINE_LIBUNWIND_FUNCTION(__unw_getcontext) @ @ 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 diff --git a/src/native/external/llvm-libunwind/src/Unwind_AppleExtras.cpp b/src/native/external/llvm-libunwind/src/Unwind_AppleExtras.cpp deleted file mode 100644 index ffb49a89e54f3..0000000000000 --- a/src/native/external/llvm-libunwind/src/Unwind_AppleExtras.cpp +++ /dev/null @@ -1,113 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -// See https://llvm.org/LICENSE.txt for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -// -//===----------------------------------------------------------------------===// - -#include "config.h" - - -// 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(__aarch64__) - #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) diff --git a/src/native/external/llvm-libunwind/src/config.h b/src/native/external/llvm-libunwind/src/config.h index 4bbac951624f9..deb5a4d4d73d4 100644 --- a/src/native/external/llvm-libunwind/src/config.h +++ b/src/native/external/llvm-libunwind/src/config.h @@ -46,6 +46,12 @@ #elif defined(_AIX) // The traceback table at the end of each function is used for unwinding. #define _LIBUNWIND_SUPPORT_TBTAB_UNWIND 1 +#elif defined(__HAIKU__) + #if defined(_LIBUNWIND_USE_HAIKU_BSD_LIB) + #define _LIBUNWIND_USE_DL_ITERATE_PHDR 1 + #endif + #define _LIBUNWIND_SUPPORT_DWARF_UNWIND 1 + #define _LIBUNWIND_SUPPORT_DWARF_INDEX 1 #else // Assume an ELF system with a dl_iterate_phdr function. #define _LIBUNWIND_USE_DL_ITERATE_PHDR 1 @@ -83,7 +89,7 @@ __asm__(".globl " SYMBOL_NAME(aliasname)); \ __asm__(SYMBOL_NAME(aliasname) " = " SYMBOL_NAME(name)); \ _LIBUNWIND_ALIAS_VISIBILITY(SYMBOL_NAME(aliasname)) -#elif defined(__ELF__) || defined(_AIX) +#elif defined(__ELF__) || defined(_AIX) || defined(__wasm__) #define _LIBUNWIND_WEAK_ALIAS(name, aliasname) \ extern "C" _LIBUNWIND_EXPORT __typeof(name) aliasname \ __attribute__((weak, alias(#name))); @@ -108,10 +114,6 @@ #define _LIBUNWIND_BUILD_SJLJ_APIS #endif -#if defined(__i386__) || defined(__x86_64__) || defined(__powerpc__) -#define _LIBUNWIND_SUPPORT_FRAME_APIS -#endif - #if defined(__i386__) || defined(__x86_64__) || defined(__powerpc__) || \ (!defined(__APPLE__) && defined(__arm__)) || defined(__aarch64__) || \ defined(__mips__) || defined(__riscv) || defined(__hexagon__) || \ @@ -125,7 +127,7 @@ #if defined(_LIBUNWIND_REMEMBER_STACK_ALLOC) || defined(__APPLE__) || \ defined(__linux__) || defined(__ANDROID__) || defined(__MINGW32__) || \ defined(_LIBUNWIND_IS_BAREMETAL) -#define _LIBUNWIND_REMEMBER_ALLOC(_size) alloca(_size) +#define _LIBUNWIND_REMEMBER_ALLOC(_size) __builtin_alloca(_size) #define _LIBUNWIND_REMEMBER_FREE(_ptr) \ do { \ } while (0) @@ -162,10 +164,14 @@ #define _LIBUNWIND_LOG0(msg) #define _LIBUNWIND_LOG(msg, ...) #else -#define _LIBUNWIND_LOG0(msg) \ - fprintf(stderr, "libunwind: " msg "\n") -#define _LIBUNWIND_LOG(msg, ...) \ - fprintf(stderr, "libunwind: " msg "\n", __VA_ARGS__) +#define _LIBUNWIND_LOG0(msg) do { \ + fprintf(stderr, "libunwind: " msg "\n"); \ + fflush(stderr); \ + } while (0) +#define _LIBUNWIND_LOG(msg, ...) do { \ + fprintf(stderr, "libunwind: " msg "\n", __VA_ARGS__); \ + fflush(stderr); \ + } while (0) #endif #if defined(NDEBUG) diff --git a/src/native/external/llvm-libunwind/src/libunwind.cpp b/src/native/external/llvm-libunwind/src/libunwind.cpp index f350655b869fe..217dde9098637 100644 --- a/src/native/external/llvm-libunwind/src/libunwind.cpp +++ b/src/native/external/llvm-libunwind/src/libunwind.cpp @@ -26,7 +26,7 @@ #include #endif -#if !defined(__USING_SJLJ_EXCEPTIONS__) +#if !defined(__USING_SJLJ_EXCEPTIONS__) && !defined(__USING_WASM_EXCEPTIONS__) #include "AddressSpace.hpp" #include "UnwindCursor.hpp" @@ -111,14 +111,14 @@ _LIBUNWIND_WEAK_ALIAS(__unw_get_reg, unw_get_reg) /// Set value of specified register at cursor position in stack frame. _LIBUNWIND_HIDDEN int __unw_set_reg(unw_cursor_t *cursor, unw_regnum_t regNum, - unw_word_t value, unw_word_t *pos) { + unw_word_t value) { _LIBUNWIND_TRACE_API("__unw_set_reg(cursor=%p, regNum=%d, value=0x%" PRIxPTR ")", static_cast(cursor), regNum, value); typedef LocalAddressSpace::pint_t pint_t; AbstractUnwindCursor *co = (AbstractUnwindCursor *)cursor; if (co->validReg(regNum)) { - co->setReg(regNum, (pint_t)value, (pint_t)pos); + co->setReg(regNum, (pint_t)value); // special case altering IP to re-find info (being called by personality // function) if (regNum == UNW_REG_IP) { @@ -133,7 +133,7 @@ _LIBUNWIND_HIDDEN int __unw_set_reg(unw_cursor_t *cursor, unw_regnum_t regNum, // this should actually be - info.gp. LLVM doesn't currently support // any such platforms and Clang doesn't export a macro for them. if (info.gp) - co->setReg(UNW_REG_SP, co->getReg(UNW_REG_SP) + info.gp, 0); + co->setReg(UNW_REG_SP, co->getReg(UNW_REG_SP) + info.gp); } return UNW_ESUCCESS; } @@ -175,21 +175,6 @@ _LIBUNWIND_HIDDEN int __unw_set_fpreg(unw_cursor_t *cursor, unw_regnum_t regNum, } _LIBUNWIND_WEAK_ALIAS(__unw_set_fpreg, unw_set_fpreg) -/// Get location of specified register at cursor position in stack frame. -_LIBUNWIND_HIDDEN int __unw_get_save_loc(unw_cursor_t *cursor, int regNum, - unw_save_loc_t* location) -{ - AbstractUnwindCursor *co = (AbstractUnwindCursor *)cursor; - if (co->validReg(regNum)) { - // We only support memory locations, not register locations - location->u.addr = co->getRegLocation(regNum); - location->type = (location->u.addr == 0) ? UNW_SLT_NONE : UNW_SLT_MEMORY; - return UNW_ESUCCESS; - } - return UNW_EBADREG; -} -_LIBUNWIND_WEAK_ALIAS(__unw_get_save_loc, unw_get_save_loc) - /// Move cursor to next frame. _LIBUNWIND_HIDDEN int __unw_step(unw_cursor_t *cursor) { _LIBUNWIND_TRACE_API("__unw_step(cursor=%p)", static_cast(cursor)); @@ -339,7 +324,7 @@ void __unw_add_dynamic_eh_frame_section(unw_word_t eh_frame_start) { CFI_Parser::CIE_Info cieInfo; CFI_Parser::FDE_Info fdeInfo; auto p = (LocalAddressSpace::pint_t)eh_frame_start; - while (true) { + while (LocalAddressSpace::sThisAddressSpace.get32(p)) { if (CFI_Parser::decodeFDE( LocalAddressSpace::sThisAddressSpace, p, &fdeInfo, &cieInfo, true) == NULL) { @@ -362,9 +347,90 @@ void __unw_remove_dynamic_eh_frame_section(unw_word_t eh_frame_start) { } #endif // defined(_LIBUNWIND_SUPPORT_DWARF_UNWIND) -#endif // !defined(__USING_SJLJ_EXCEPTIONS__) +#endif // !defined(__USING_SJLJ_EXCEPTIONS__) && + // !defined(__USING_WASM_EXCEPTIONS__) + +#ifdef __APPLE__ + +namespace libunwind { +static constexpr size_t MAX_DYNAMIC_UNWIND_SECTIONS_FINDERS = 8; + +static RWMutex findDynamicUnwindSectionsLock; +static size_t numDynamicUnwindSectionsFinders = 0; +static unw_find_dynamic_unwind_sections + dynamicUnwindSectionsFinders[MAX_DYNAMIC_UNWIND_SECTIONS_FINDERS] = {0}; + +bool findDynamicUnwindSections(void *addr, unw_dynamic_unwind_sections *info) { + bool found = false; + findDynamicUnwindSectionsLock.lock_shared(); + for (size_t i = 0; i != numDynamicUnwindSectionsFinders; ++i) { + if (dynamicUnwindSectionsFinders[i]((unw_word_t)addr, info)) { + found = true; + break; + } + } + findDynamicUnwindSectionsLock.unlock_shared(); + return found; +} + +} // namespace libunwind + +int __unw_add_find_dynamic_unwind_sections( + unw_find_dynamic_unwind_sections find_dynamic_unwind_sections) { + findDynamicUnwindSectionsLock.lock(); + + // Check that we have enough space... + if (numDynamicUnwindSectionsFinders == MAX_DYNAMIC_UNWIND_SECTIONS_FINDERS) { + findDynamicUnwindSectionsLock.unlock(); + return UNW_ENOMEM; + } + + // Check for value already present... + for (size_t i = 0; i != numDynamicUnwindSectionsFinders; ++i) { + if (dynamicUnwindSectionsFinders[i] == find_dynamic_unwind_sections) { + findDynamicUnwindSectionsLock.unlock(); + return UNW_EINVAL; + } + } + + // Success -- add callback entry. + dynamicUnwindSectionsFinders[numDynamicUnwindSectionsFinders++] = + find_dynamic_unwind_sections; + findDynamicUnwindSectionsLock.unlock(); + + return UNW_ESUCCESS; +} + +int __unw_remove_find_dynamic_unwind_sections( + unw_find_dynamic_unwind_sections find_dynamic_unwind_sections) { + findDynamicUnwindSectionsLock.lock(); + + // Find index to remove. + size_t finderIdx = numDynamicUnwindSectionsFinders; + for (size_t i = 0; i != numDynamicUnwindSectionsFinders; ++i) { + if (dynamicUnwindSectionsFinders[i] == find_dynamic_unwind_sections) { + finderIdx = i; + break; + } + } + + // If no such registration is present then error out. + if (finderIdx == numDynamicUnwindSectionsFinders) { + findDynamicUnwindSectionsLock.unlock(); + return UNW_EINVAL; + } + + // Remove entry. + for (size_t i = finderIdx; i != numDynamicUnwindSectionsFinders - 1; ++i) + dynamicUnwindSectionsFinders[i] = dynamicUnwindSectionsFinders[i + 1]; + dynamicUnwindSectionsFinders[--numDynamicUnwindSectionsFinders] = nullptr; + + findDynamicUnwindSectionsLock.unlock(); + return UNW_ESUCCESS; +} +#endif // __APPLE__ // Add logging hooks in Debug builds only #ifndef NDEBUG diff --git a/src/native/external/llvm-libunwind/src/libunwind_ext.h b/src/native/external/llvm-libunwind/src/libunwind_ext.h index 5385821ce2c12..28db43a4f6eef 100644 --- a/src/native/external/llvm-libunwind/src/libunwind_ext.h +++ b/src/native/external/llvm-libunwind/src/libunwind_ext.h @@ -28,7 +28,7 @@ extern int __unw_init_local(unw_cursor_t *, unw_context_t *); extern int __unw_step(unw_cursor_t *); extern int __unw_get_reg(unw_cursor_t *, unw_regnum_t, unw_word_t *); extern int __unw_get_fpreg(unw_cursor_t *, unw_regnum_t, unw_fpreg_t *); -extern int __unw_set_reg(unw_cursor_t *, unw_regnum_t, unw_word_t, unw_word_t *); +extern int __unw_set_reg(unw_cursor_t *, unw_regnum_t, unw_word_t); extern int __unw_set_fpreg(unw_cursor_t *, unw_regnum_t, unw_fpreg_t); extern int __unw_resume(unw_cursor_t *); @@ -42,7 +42,6 @@ extern int __unw_get_proc_info(unw_cursor_t *, unw_proc_info_t *); extern int __unw_is_fpreg(unw_cursor_t *, unw_regnum_t); extern int __unw_is_signal_frame(unw_cursor_t *); extern int __unw_get_proc_name(unw_cursor_t *, char *, size_t, unw_word_t *); -extern int __unw_get_save_loc(unw_cursor_t *, int, unw_save_loc_t *); #if defined(_AIX) extern uintptr_t __unw_get_data_rel_base(unw_cursor_t *); @@ -59,6 +58,71 @@ extern void __unw_remove_dynamic_fde(unw_word_t fde); extern void __unw_add_dynamic_eh_frame_section(unw_word_t eh_frame_start); extern void __unw_remove_dynamic_eh_frame_section(unw_word_t eh_frame_start); +#ifdef __APPLE__ + +// Holds a description of the object-format-header (if any) and unwind info +// sections for a given address: +// +// * dso_base should point to a header for the JIT'd object containing the +// given address. The header's type should match the format type that +// libunwind was compiled for (so a mach_header or mach_header_64 on Darwin). +// A value of zero indicates that no such header exists. +// +// * dwarf_section and dwarf_section_length hold the address range of a DWARF +// eh-frame section associated with the given address, if any. If the +// dwarf_section_length field is zero it indicates that no such section +// exists (and in this case dwarf_section should also be set to zero). +// +// * compact_unwind_section and compact_unwind_section_length hold the address +// range of a compact-unwind info section associated with the given address, +// if any. If the compact_unwind_section_length field is zero it indicates +// that no such section exists (and in this case compact_unwind_section +// should also be set to zero). +// +// See the unw_find_dynamic_unwind_sections type below for more details. +struct unw_dynamic_unwind_sections { + unw_word_t dso_base; + unw_word_t dwarf_section; + size_t dwarf_section_length; + unw_word_t compact_unwind_section; + size_t compact_unwind_section_length; +}; + +// Typedef for unwind-info lookup callbacks. Functions of this type can be +// registered and deregistered using __unw_add_find_dynamic_unwind_sections +// and __unw_remove_find_dynamic_unwind_sections respectively. +// +// An unwind-info lookup callback should return 1 to indicate that it found +// unwind-info for the given address, or 0 to indicate that it did not find +// unwind-info for the given address. If found, the callback should populate +// some or all of the fields of the info argument (which is guaranteed to be +// non-null with all fields zero-initialized): +typedef int (*unw_find_dynamic_unwind_sections)( + unw_word_t addr, struct unw_dynamic_unwind_sections *info); + +// Register a dynamic unwind-info lookup callback. If libunwind does not find +// unwind info for a given frame in the executable program or normal dynamic +// shared objects then it will call all registered dynamic lookup functions +// in registration order until either one of them returns true, or the end +// of the list is reached. This lookup will happen before libunwind searches +// any eh-frames registered via __register_frame or +// __unw_add_dynamic_eh_frame_section. +// +// Returns UNW_ESUCCESS for successful registrations. If the given callback +// has already been registered then UNW_EINVAL will be returned. If all +// available callback entries are in use then UNW_ENOMEM will be returned. +extern int __unw_add_find_dynamic_unwind_sections( + unw_find_dynamic_unwind_sections find_dynamic_unwind_sections); + +// Deregister a dynacim unwind-info lookup callback. +// +// Returns UNW_ESUCCESS for successful deregistrations. If the given callback +// has already been registered then UNW_EINVAL will be returned. +extern int __unw_remove_find_dynamic_unwind_sections( + unw_find_dynamic_unwind_sections find_dynamic_unwind_sections); + +#endif + #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, diff --git a/src/native/external/llvm-libunwind/src/unwind_ext.h b/src/native/external/llvm-libunwind/src/unwind_ext.h deleted file mode 100644 index c40ce6a1610f4..0000000000000 --- a/src/native/external/llvm-libunwind/src/unwind_ext.h +++ /dev/null @@ -1,37 +0,0 @@ -//===-------------------------- unwind_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 unwind API. -// -//===----------------------------------------------------------------------===// - -#ifndef __UNWIND_EXT__ -#define __UNWIND_EXT__ - -#include "unwind.h" - -#ifdef __cplusplus -extern "C" { -#endif - -// These platform specific functions to get and set the top context are -// implemented elsewhere. - -extern struct _Unwind_FunctionContext * -__Unwind_SjLj_GetTopOfFunctionStack(); - -extern void -__Unwind_SjLj_SetTopOfFunctionStack(struct _Unwind_FunctionContext *fc); - -#ifdef __cplusplus -} -#endif - -#endif // __UNWIND_EXT__ - - diff --git a/src/native/external/llvm-libunwind/test/CMakeLists.txt b/src/native/external/llvm-libunwind/test/CMakeLists.txt index 0a09553e692da..21dfbb0a84f0a 100644 --- a/src/native/external/llvm-libunwind/test/CMakeLists.txt +++ b/src/native/external/llvm-libunwind/test/CMakeLists.txt @@ -1,4 +1,5 @@ include(AddLLVM) # for add_lit_testsuite +include(HandleLitArguments) macro(pythonize_bool var) if (${var}) set(${var} True) @@ -10,33 +11,28 @@ endmacro() pythonize_bool(LIBUNWIND_ENABLE_CET) pythonize_bool(LIBUNWIND_ENABLE_THREADS) pythonize_bool(LIBUNWIND_USES_ARM_EHABI) -set(LIBUNWIND_EXECUTOR "${Python3_EXECUTABLE} ${LIBUNWIND_LIBCXX_PATH}/utils/run.py" CACHE STRING - "Executor to use when running tests.") set(AUTO_GEN_COMMENT "## Autogenerated by libunwind configuration.\n# Do not edit!") set(SERIALIZED_LIT_PARAMS "# Lit parameters serialized here for llvm-lit to pick them up\n") -macro(serialize_lit_param param value) - string(APPEND SERIALIZED_LIT_PARAMS "config.${param} = ${value}\n") -endmacro() +if (LIBUNWIND_EXECUTOR) + message(DEPRECATION "LIBUNWIND_EXECUTOR is deprecated, please add executor=... to LIBUNWIND_TEST_PARAMS") + serialize_lit_string_param(SERIALIZED_LIT_PARAMS executor "${LIBUNWIND_EXECUTOR}") +endif() -serialize_lit_param(enable_experimental False) +serialize_lit_param(SERIALIZED_LIT_PARAMS enable_experimental False) if (LLVM_USE_SANITIZER) - serialize_lit_param(use_sanitizer "\"${LLVM_USE_SANITIZER}\"") + serialize_lit_string_param(SERIALIZED_LIT_PARAMS use_sanitizer "${LLVM_USE_SANITIZER}") endif() if (CMAKE_CXX_COMPILER_TARGET) - serialize_lit_param(target_triple "\"${CMAKE_CXX_COMPILER_TARGET}\"") + serialize_lit_string_param(SERIALIZED_LIT_PARAMS target_triple "${CMAKE_CXX_COMPILER_TARGET}") else() - serialize_lit_param(target_triple "\"${LLVM_DEFAULT_TARGET_TRIPLE}\"") + serialize_lit_string_param(SERIALIZED_LIT_PARAMS target_triple "${LLVM_DEFAULT_TARGET_TRIPLE}") endif() -foreach(param IN LISTS LIBUNWIND_TEST_PARAMS) - string(REGEX REPLACE "(.+)=(.+)" "\\1" name "${param}") - string(REGEX REPLACE "(.+)=(.+)" "\\2" value "${param}") - serialize_lit_param("${name}" "\"${value}\"") -endforeach() +serialize_lit_params_list(SERIALIZED_LIT_PARAMS LIBUNWIND_TEST_PARAMS) configure_file("${CMAKE_CURRENT_SOURCE_DIR}/configs/cmake-bridge.cfg.in" "${CMAKE_CURRENT_BINARY_DIR}/cmake-bridge.cfg" diff --git a/src/native/external/llvm-libunwind/test/aix_signal_unwind.pass.sh.S b/src/native/external/llvm-libunwind/test/aix_signal_unwind.pass.sh.S new file mode 100644 index 0000000000000..9ca18e9481f4f --- /dev/null +++ b/src/native/external/llvm-libunwind/test/aix_signal_unwind.pass.sh.S @@ -0,0 +1,245 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +// Test that _Unwind_Backtrace() walks up from a signal handler and produces +// a correct traceback when the function raising the signal does not save +// the link register or does not store the stack back chain. + +// REQUIRES: target=powerpc{{(64)?}}-ibm-aix + +// Test when the function raising the signal does not save the link register +// RUN: %{cxx} -x c++ %s -o %t.exe -DCXX_CODE %{flags} %{compile_flags} +// RUN: %{exec} %t.exe + +// Test when the function raising the signal does not store stack back chain. +// RUN: %{cxx} -x c++ -c %s -o %t1.o -DCXX_CODE -DNOBACKCHAIN %{flags} \ +// RUN: %{compile_flags} +// RUN: %{cxx} -c %s -o %t2.o %{flags} %{compile_flags} +// RUN: %{cxx} -o %t1.exe %t1.o %t2.o %{flags} %{link_flags} +// RUN: %{exec} %t1.exe + +#ifdef CXX_CODE + +#undef NDEBUG +#include +#include +#include +#include +#include +#include +#include + +#define NAME_ARRAY_SIZE 10 +#define NAMES_EXPECTED 6 + +const char* namesExpected[] = {"handler", "abc", "bar", "foo", "main", + "__start"}; +char *namesObtained[NAME_ARRAY_SIZE] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; + +int funcIndex = 0; + +// Get the function name from traceback table. +char *getFuncName(uintptr_t pc, uint16_t *nameLen) { + uint32_t *p = reinterpret_cast(pc); + + // Keep looking forward until a word of 0 is found. The traceback + // table starts at the following word. + while (*p) + ++p; + tbtable *TBTable = reinterpret_cast(p + 1); + + if (!TBTable->tb.name_present) + return NULL; + + // Get to the optional portion of the traceback table. + p = reinterpret_cast(&TBTable->tb_ext); + + // Skip field parminfo if it exists. + if (TBTable->tb.fixedparms || TBTable->tb.floatparms) + ++p; + + // Skip field tb_offset if it exists. + if (TBTable->tb.has_tboff) + ++p; + + // Skip field hand_mask if it exists. + if (TBTable->tb.int_hndl) + ++p; + + // Skip fields ctl_info and ctl_info_disp if they exist. + if (TBTable->tb.has_ctl) + p += 1 + *p; + + *nameLen = *reinterpret_cast(p); + return reinterpret_cast(p) + sizeof(uint16_t); +} + +_Unwind_Reason_Code callBack(struct _Unwind_Context *uc, void *arg) { + (void)arg; + uint16_t nameLen; + uintptr_t ip = _Unwind_GetIP(uc); + if (funcIndex < NAME_ARRAY_SIZE) + namesObtained[funcIndex++] = strndup(getFuncName(ip, &nameLen), nameLen); + return _URC_NO_REASON; +} + +extern "C" void handler(int signum) { + (void)signum; + // Walk stack frames for traceback. + _Unwind_Backtrace(callBack, NULL); + + // Verify the traceback. + assert(funcIndex <= NAMES_EXPECTED && "Obtained names more than expected"); + for (int i = 0; i < funcIndex; ++i) { + assert(!strcmp(namesExpected[i], namesObtained[i]) && + "Function names do not match"); + free(namesObtained[i]); + } + exit(0); +} + +#ifdef NOBACKCHAIN +// abc() is in assembly. It raises signal SIGSEGV and does not store +// the stack back chain. +extern "C" void abc(); + +#else +volatile int *null = 0; + +// abc() raises signal SIGSEGV and does not save the link register. +extern "C" __attribute__((noinline)) void abc() { + // Produce a SIGSEGV. + *null = 0; +} +#endif + +extern "C" __attribute__((noinline)) void bar() { + abc(); +} + +extern "C" __attribute__((noinline)) void foo() { + bar(); +} + +int main() { + // Set signal handler for SIGSEGV. + signal(SIGSEGV, handler); + foo(); +} + +#else // Assembly code for abc(). +// This assembly code is similar to the following C code but it saves the +// link register. +// +// int *badp = 0; +// void abc() { +// *badp = 0; +// } + +#ifdef __64BIT__ + .csect [PR],5 + .file "abc.c" + .globl abc[DS] # -- Begin function abc + .globl .abc + .align 4 + .csect abc[DS],3 + .vbyte 8, .abc # @abc + .vbyte 8, TOC[TC0] + .vbyte 8, 0 + .csect [PR],5 +.abc: +# %bb.0: # %entry + mflr 0 + std 0, 16(1) + ld 3, L..C0(2) # @badp + bl $+4 + ld 4, 0(3) + li 3, 0 + stw 3, 0(4) + ld 0, 16(1) + mtlr 0 + blr +L..abc0: + .vbyte 4, 0x00000000 # Traceback table begin + .byte 0x00 # Version = 0 + .byte 0x09 # Language = CPlusPlus + .byte 0x20 # -IsGlobaLinkage, -IsOutOfLineEpilogOrPrologue + # +HasTraceBackTableOffset, -IsInternalProcedure + # -HasControlledStorage, -IsTOCless + # -IsFloatingPointPresent + # -IsFloatingPointOperationLogOrAbortEnabled + .byte 0x61 # -IsInterruptHandler, +IsFunctionNamePresent, +IsAllocaUsed + # OnConditionDirective = 0, -IsCRSaved, +IsLRSaved + .byte 0x00 # -IsBackChainStored, -IsFixup, NumOfFPRsSaved = 0 + .byte 0x01 # -HasExtensionTable, -HasVectorInfo, NumOfGPRsSaved = 1 + .byte 0x00 # NumberOfFixedParms = 0 + .byte 0x01 # NumberOfFPParms = 0, +HasParmsOnStack + .vbyte 4, L..abc0-.abc # Function size + .vbyte 2, 0x0003 # Function name len = 3 + .byte "abc" # Function Name + .byte 0x1f # AllocaUsed + # -- End function + .csect badp[RW],3 + .globl badp[RW] # @badp + .align 3 + .vbyte 8, 0 + .toc +L..C0: + .tc badp[TC],badp[RW] +#else + .csect [PR],5 + .file "abc.c" + .globl abc[DS] # -- Begin function abc + .globl .abc + .align 4 + .csect abc[DS],2 + .vbyte 4, .abc # @abc + .vbyte 4, TOC[TC0] + .vbyte 4, 0 + .csect [PR],5 +.abc: +# %bb.0: # %entry + mflr 0 + stw 0, 8(1) + lwz 3, L..C0(2) # @badp + bl $+4 + lwz 4, 0(3) + li 3, 0 + stw 3, 0(4) + lwz 0, 8(1) + mtlr 0 + blr +L..abc0: + .vbyte 4, 0x00000000 # Traceback table begin + .byte 0x00 # Version = 0 + .byte 0x09 # Language = CPlusPlus + .byte 0x20 # -IsGlobaLinkage, -IsOutOfLineEpilogOrPrologue + # +HasTraceBackTableOffset, -IsInternalProcedure + # -HasControlledStorage, -IsTOCless + # -IsFloatingPointPresent + # -IsFloatingPointOperationLogOrAbortEnabled + .byte 0x61 # -IsInterruptHandler, +IsFunctionNamePresent, +IsAllocaUsed + # OnConditionDirective = 0, -IsCRSaved, +IsLRSaved + .byte 0x00 # -IsBackChainStored, -IsFixup, NumOfFPRsSaved = 0 + .byte 0x01 # -HasExtensionTable, -HasVectorInfo, NumOfGPRsSaved = 1 + .byte 0x00 # NumberOfFixedParms = 0 + .byte 0x01 # NumberOfFPParms = 0, +HasParmsOnStack + .vbyte 4, L..abc0-.abc # Function size + .vbyte 2, 0x0003 # Function name len = 3 + .byte "abc" # Function Name + .byte 0x1f # AllocaUsed + # -- End function + .csect badp[RW],2 + .globl badp[RW] # @badp + .align 2 + .vbyte 4, 0 + .toc +L..C0: + .tc badp[TC],badp[RW] +#endif // __64BIT__ +#endif // CXX_CODE diff --git a/src/native/external/llvm-libunwind/test/bad_unwind_info.pass.cpp b/src/native/external/llvm-libunwind/test/bad_unwind_info.pass.cpp index 06017d17ab574..b3284e8daed71 100644 --- a/src/native/external/llvm-libunwind/test/bad_unwind_info.pass.cpp +++ b/src/native/external/llvm-libunwind/test/bad_unwind_info.pass.cpp @@ -10,7 +10,7 @@ // Ensure that libunwind doesn't crash on invalid info; the Linux aarch64 // sigreturn frame check would previously attempt to access invalid memory in // this scenario. -// REQUIRES: linux && (target={{aarch64-.+}} || target={{s390x-.+}} || target={{x86_64-.+}}) +// REQUIRES: target={{(aarch64|s390x|x86_64)-.+linux.*}} // GCC doesn't support __attribute__((naked)) on AArch64. // UNSUPPORTED: gcc diff --git a/src/native/external/llvm-libunwind/test/configs/apple-libunwind-backdeployment.cfg.in b/src/native/external/llvm-libunwind/test/configs/apple-libunwind-backdeployment.cfg.in index d4777e2f6917a..4484573801bd2 100644 --- a/src/native/external/llvm-libunwind/test/configs/apple-libunwind-backdeployment.cfg.in +++ b/src/native/external/llvm-libunwind/test/configs/apple-libunwind-backdeployment.cfg.in @@ -7,7 +7,7 @@ import os, site site.addsitedir(os.path.join('@LIBUNWIND_LIBCXX_PATH@', 'utils')) -import libcxx.test.params, libcxx.test.newconfig, libcxx.test.dsl +import libcxx.test.params, libcxx.test.config, libcxx.test.dsl lit_config.load_config(config, '@CMAKE_CURRENT_BINARY_DIR@/cmake-bridge.cfg') @@ -54,9 +54,11 @@ config.substitutions.append(('%{exec}', '%{executor} --execdir %T --env DYLD_LIBRARY_PATH="%{cxx-runtime-root}:%{abi-runtime-root}:%{unwind-runtime-root}" -- ' )) +config.stdlib = 'apple-libc++' + import os, site -import libcxx.test.params, libcxx.test.newconfig, libcxx.test.newconfig -libcxx.test.newconfig.configure( +import libcxx.test.params, libcxx.test.config +libcxx.test.config.configure( libcxx.test.params.DEFAULT_PARAMETERS + BACKDEPLOYMENT_PARAMETERS, libcxx.test.features.DEFAULT_FEATURES, config, diff --git a/src/native/external/llvm-libunwind/test/configs/armv7m-picolibc-libunwind.cfg.in b/src/native/external/llvm-libunwind/test/configs/armv7m-picolibc-libunwind.cfg.in new file mode 100644 index 0000000000000..e8f68a51fc53f --- /dev/null +++ b/src/native/external/llvm-libunwind/test/configs/armv7m-picolibc-libunwind.cfg.in @@ -0,0 +1,39 @@ +lit_config.load_config(config, '@CMAKE_CURRENT_BINARY_DIR@/cmake-bridge.cfg') + +libc_linker_script = '@CMAKE_INSTALL_PREFIX@/lib/picolibcpp.ld' + +config.substitutions.append(('%{flags}', '--sysroot=@CMAKE_INSTALL_PREFIX@')) + +config.substitutions.append(('%{compile_flags}', + '-nostdinc++ -I %{include}' +)) +config.substitutions.append(('%{link_flags}', + '-nostdlib -nostdlib++ -L %{lib} -lunwind' + ' -lc -lm -lclang_rt.builtins -lsemihost -lcrt0-semihost' + + ' -T {}'.format(libc_linker_script) + + ' -Wl,--defsym=__flash=0x0' + ' -Wl,--defsym=__flash_size=0x400000' + ' -Wl,--defsym=__ram=0x21000000' + ' -Wl,--defsym=__ram_size=0x1000000' + ' -Wl,--defsym=__stack_size=0x1000' +)) + +config.executor = ( + '@LIBUNWIND_LIBCXX_PATH@/utils/qemu_baremetal.py' + ' --qemu @QEMU_SYSTEM_ARM@' + ' --machine mps2-an385' + ' --cpu cortex-m3') +config.substitutions.append(('%{exec}', + '%{executor}' + ' --execdir %T' +)) + +import os, site +site.addsitedir(os.path.join('@LIBUNWIND_LIBCXX_PATH@', 'utils')) +import libcxx.test.params, libcxx.test.config +libcxx.test.config.configure( + libcxx.test.params.DEFAULT_PARAMETERS, + libcxx.test.features.DEFAULT_FEATURES, + config, + lit_config +) diff --git a/src/native/external/llvm-libunwind/test/configs/cmake-bridge.cfg.in b/src/native/external/llvm-libunwind/test/configs/cmake-bridge.cfg.in index 109602db8a0fb..c5f34c87abb92 100644 --- a/src/native/external/llvm-libunwind/test/configs/cmake-bridge.cfg.in +++ b/src/native/external/llvm-libunwind/test/configs/cmake-bridge.cfg.in @@ -20,7 +20,7 @@ config.name = os.path.basename('@LIBUNWIND_TEST_CONFIG@') config.test_source_root = os.path.join('@LIBUNWIND_SOURCE_DIR@', 'test') config.test_format = libcxx.test.format.CxxStandardLibraryTest() config.recursiveExpansionLimit = 10 -config.test_exec_root = '@CMAKE_BINARY_DIR@' +config.test_exec_root = os.path.join('@CMAKE_BINARY_DIR@', 'test') # Add a few features that are common to all the configurations if @LIBUNWIND_USES_ARM_EHABI@: @@ -31,6 +31,5 @@ if not @LIBUNWIND_ENABLE_THREADS@: # Add substitutions for bootstrapping the test suite configuration import shlex config.substitutions.append(('%{cxx}', shlex.quote('@CMAKE_CXX_COMPILER@'))) -config.substitutions.append(('%{executor}', '@LIBUNWIND_EXECUTOR@')) config.substitutions.append(('%{include}', '@LIBUNWIND_SOURCE_DIR@/include')) config.substitutions.append(('%{lib}', '@LIBUNWIND_LIBRARY_DIR@')) diff --git a/src/native/external/llvm-libunwind/test/configs/ibm-libunwind-shared.cfg.in b/src/native/external/llvm-libunwind/test/configs/ibm-libunwind-shared.cfg.in index 599de72b1399d..2221e0cf499ff 100644 --- a/src/native/external/llvm-libunwind/test/configs/ibm-libunwind-shared.cfg.in +++ b/src/native/external/llvm-libunwind/test/configs/ibm-libunwind-shared.cfg.in @@ -3,6 +3,12 @@ lit_config.load_config(config, '@CMAKE_CURRENT_BINARY_DIR@/cmake-bridge.cfg') +import lit.util +if lit.util.isAIXTriple(config.target_triple): + # Add the AIX version to the triple here because there currently isn't a good + # way to retrieve the AIX version in the driver. + config.target_triple = lit.util.addAIXVersion(config.target_triple) + config.substitutions.append(('%{flags}', '')) config.substitutions.append(('%{compile_flags}', '-nostdinc++ -I %{include}' @@ -16,8 +22,8 @@ config.substitutions.append(('%{exec}', import os, site site.addsitedir(os.path.join('@LIBUNWIND_LIBCXX_PATH@', 'utils')) -import libcxx.test.params, libcxx.test.newconfig, libcxx.test.newconfig -libcxx.test.newconfig.configure( +import libcxx.test.params, libcxx.test.config +libcxx.test.config.configure( libcxx.test.params.DEFAULT_PARAMETERS, libcxx.test.features.DEFAULT_FEATURES, config, diff --git a/src/native/external/llvm-libunwind/test/configs/llvm-libunwind-merged.cfg.in b/src/native/external/llvm-libunwind/test/configs/llvm-libunwind-merged.cfg.in index d01ee7470de7b..38b79840c9fe2 100644 --- a/src/native/external/llvm-libunwind/test/configs/llvm-libunwind-merged.cfg.in +++ b/src/native/external/llvm-libunwind/test/configs/llvm-libunwind-merged.cfg.in @@ -11,8 +11,12 @@ link_flags = [] if @LIBUNWIND_ENABLE_CET@: compile_flags.append('-fcf-protection=full') -if '@CMAKE_SYSTEM_NAME@' == 'Linux': - link_flags.append('-Wl,--export-dynamic') +# On ELF platforms, link tests with -Wl,--export-dynamic if supported by the linker. +if len('@CMAKE_EXE_EXPORTS_CXX_FLAG@'): + link_flags.append('@CMAKE_EXE_EXPORTS_CXX_FLAG@') + +if '@CMAKE_DL_LIBS@': + link_flags.append('-l@CMAKE_DL_LIBS@') # Stack unwinding tests need unwinding tables and these are not generated by default on all targets. compile_flags.append('-funwind-tables') @@ -25,7 +29,7 @@ config.substitutions.append(('%{compile_flags}', '-nostdinc++ -I %{{include}} {}'.format(' '.join(compile_flags)) )) config.substitutions.append(('%{link_flags}', - '-L %{{lib}} -Wl,-rpath,%{{lib}} -lc++ -ldl {}'.format(' '.join(link_flags)) + '-L %{{lib}} -Wl,-rpath,%{{lib}} -lc++ {}'.format(' '.join(link_flags)) )) config.substitutions.append(('%{exec}', '%{executor} --execdir %T -- ' @@ -33,8 +37,8 @@ config.substitutions.append(('%{exec}', import os, site site.addsitedir(os.path.join('@LIBUNWIND_LIBCXX_PATH@', 'utils')) -import libcxx.test.params, libcxx.test.newconfig, libcxx.test.newconfig -libcxx.test.newconfig.configure( +import libcxx.test.params, libcxx.test.config +libcxx.test.config.configure( libcxx.test.params.DEFAULT_PARAMETERS, libcxx.test.features.DEFAULT_FEATURES, config, diff --git a/src/native/external/llvm-libunwind/test/configs/llvm-libunwind-mingw.cfg.in b/src/native/external/llvm-libunwind/test/configs/llvm-libunwind-mingw.cfg.in new file mode 100644 index 0000000000000..33d061a3efc6f --- /dev/null +++ b/src/native/external/llvm-libunwind/test/configs/llvm-libunwind-mingw.cfg.in @@ -0,0 +1,25 @@ +# This testing configuration handles running the test suite against LLVM's libunwind +# using either a DLL or a static library, with MinGW/Clang on Windows. + +lit_config.load_config(config, '@CMAKE_CURRENT_BINARY_DIR@/cmake-bridge.cfg') + +config.substitutions.append(('%{flags}', '')) +config.substitutions.append(('%{compile_flags}', + '-nostdinc++ -I %{include} -funwind-tables' +)) +config.substitutions.append(('%{link_flags}', + '-L %{lib} -lunwind' +)) +config.substitutions.append(('%{exec}', + '%{executor} --execdir %T --prepend_env PATH=%{lib} -- ' +)) + +import os, site +site.addsitedir(os.path.join('@LIBUNWIND_LIBCXX_PATH@', 'utils')) +import libcxx.test.params, libcxx.test.config +libcxx.test.config.configure( + libcxx.test.params.DEFAULT_PARAMETERS, + libcxx.test.features.DEFAULT_FEATURES, + config, + lit_config +) diff --git a/src/native/external/llvm-libunwind/test/configs/llvm-libunwind-shared.cfg.in b/src/native/external/llvm-libunwind/test/configs/llvm-libunwind-shared.cfg.in index b82eec71b02ff..13896aeb13bc4 100644 --- a/src/native/external/llvm-libunwind/test/configs/llvm-libunwind-shared.cfg.in +++ b/src/native/external/llvm-libunwind/test/configs/llvm-libunwind-shared.cfg.in @@ -10,8 +10,12 @@ link_flags = [] if @LIBUNWIND_ENABLE_CET@: compile_flags.append('-fcf-protection=full') -if '@CMAKE_SYSTEM_NAME@' == 'Linux': - link_flags.append('-Wl,--export-dynamic') +# On ELF platforms, link tests with -Wl,--export-dynamic if supported by the linker. +if len('@CMAKE_EXE_EXPORTS_CXX_FLAG@'): + link_flags.append('@CMAKE_EXE_EXPORTS_CXX_FLAG@') + +if '@CMAKE_DL_LIBS@': + link_flags.append('-l@CMAKE_DL_LIBS@') # Stack unwinding tests need unwinding tables and these are not generated by default on all targets. compile_flags.append('-funwind-tables') @@ -24,7 +28,7 @@ config.substitutions.append(('%{compile_flags}', '-nostdinc++ -I %{{include}} {}'.format(' '.join(compile_flags)) )) config.substitutions.append(('%{link_flags}', - '-L %{{lib}} -Wl,-rpath,%{{lib}} -lunwind -ldl {}'.format(' '.join(link_flags)) + '-L %{{lib}} -Wl,-rpath,%{{lib}} -lunwind {}'.format(' '.join(link_flags)) )) config.substitutions.append(('%{exec}', '%{executor} --execdir %T -- ' @@ -32,8 +36,8 @@ config.substitutions.append(('%{exec}', import os, site site.addsitedir(os.path.join('@LIBUNWIND_LIBCXX_PATH@', 'utils')) -import libcxx.test.params, libcxx.test.newconfig, libcxx.test.newconfig -libcxx.test.newconfig.configure( +import libcxx.test.params, libcxx.test.config +libcxx.test.config.configure( libcxx.test.params.DEFAULT_PARAMETERS, libcxx.test.features.DEFAULT_FEATURES, config, diff --git a/src/native/external/llvm-libunwind/test/configs/llvm-libunwind-static.cfg.in b/src/native/external/llvm-libunwind/test/configs/llvm-libunwind-static.cfg.in index a947a5d08f58b..50b64dc665a5a 100644 --- a/src/native/external/llvm-libunwind/test/configs/llvm-libunwind-static.cfg.in +++ b/src/native/external/llvm-libunwind/test/configs/llvm-libunwind-static.cfg.in @@ -13,8 +13,12 @@ if @LIBUNWIND_ENABLE_THREADS@: if @LIBUNWIND_ENABLE_CET@: compile_flags.append('-fcf-protection=full') -if '@CMAKE_SYSTEM_NAME@' == 'Linux': - link_flags.append('-Wl,--export-dynamic') +# On ELF platforms, link tests with -Wl,--export-dynamic if supported by the linker. +if len('@CMAKE_EXE_EXPORTS_CXX_FLAG@'): + link_flags.append('@CMAKE_EXE_EXPORTS_CXX_FLAG@') + +if '@CMAKE_DL_LIBS@': + link_flags.append('-l@CMAKE_DL_LIBS@') # Stack unwinding tests need unwinding tables and these are not generated by default on all targets. compile_flags.append('-funwind-tables') @@ -27,7 +31,7 @@ config.substitutions.append(('%{compile_flags}', '-nostdinc++ -I %{{include}} {}'.format(' '.join(compile_flags)) )) config.substitutions.append(('%{link_flags}', - '%{{lib}}/libunwind.a -ldl {}'.format(' '.join(link_flags)) + '%{{lib}}/libunwind.a {}'.format(' '.join(link_flags)) )) config.substitutions.append(('%{exec}', '%{executor} --execdir %T -- ' @@ -35,8 +39,8 @@ config.substitutions.append(('%{exec}', import os, site site.addsitedir(os.path.join('@LIBUNWIND_LIBCXX_PATH@', 'utils')) -import libcxx.test.params, libcxx.test.newconfig, libcxx.test.newconfig -libcxx.test.newconfig.configure( +import libcxx.test.params, libcxx.test.config +libcxx.test.config.configure( libcxx.test.params.DEFAULT_PARAMETERS, libcxx.test.features.DEFAULT_FEATURES, config, diff --git a/src/native/external/llvm-libunwind/test/forceunwind.pass.cpp b/src/native/external/llvm-libunwind/test/forceunwind.pass.cpp index 8c26551b6d0b6..db499d8bc3089 100644 --- a/src/native/external/llvm-libunwind/test/forceunwind.pass.cpp +++ b/src/native/external/llvm-libunwind/test/forceunwind.pass.cpp @@ -61,7 +61,7 @@ __attribute__((noinline)) void foo() { #if defined(_LIBUNWIND_ARM_EHABI) // Create a mock exception object. memset(e, '\0', sizeof(*e)); - strcpy(reinterpret_cast(&e->exception_class), "CLNGUNW"); + memcpy(&e->exception_class, "CLNGUNW", sizeof(e->exception_class)); #endif _Unwind_ForcedUnwind(e, stop, (void *)&foo); } diff --git a/src/native/external/llvm-libunwind/test/libunwind_01.pass.cpp b/src/native/external/llvm-libunwind/test/libunwind_01.pass.cpp index 4661ac9df8219..96f12d1fc3937 100644 --- a/src/native/external/llvm-libunwind/test/libunwind_01.pass.cpp +++ b/src/native/external/llvm-libunwind/test/libunwind_01.pass.cpp @@ -8,7 +8,7 @@ //===----------------------------------------------------------------------===// // TODO: Investigate this failure on x86_64 macOS back deployment -// XFAIL: use_system_cxx_lib && target=x86_64-apple-macosx{{10.9|10.10|10.11|10.12|10.13|10.14|10.15|11.0|12.0}} +// XFAIL: stdlib=apple-libc++ && target=x86_64-apple-macosx{{10.9|10.10|10.11|10.12|10.13|10.14|10.15|11.0|12.0}} // TODO: Figure out why this fails with Memory Sanitizer. // XFAIL: msan diff --git a/src/native/external/llvm-libunwind/test/libunwind_02.pass.cpp b/src/native/external/llvm-libunwind/test/libunwind_02.pass.cpp index fc034378781a2..9fd8e5d7159c9 100644 --- a/src/native/external/llvm-libunwind/test/libunwind_02.pass.cpp +++ b/src/native/external/llvm-libunwind/test/libunwind_02.pass.cpp @@ -10,6 +10,9 @@ // TODO: Figure out why this fails with Memory Sanitizer. // XFAIL: msan +// This test fails on older llvm, when built with picolibc. +// XFAIL: clang-16 && LIBCXX-PICOLIBC-FIXME + #undef NDEBUG #include #include @@ -18,7 +21,8 @@ #define EXPECTED_NUM_FRAMES 50 #define NUM_FRAMES_UPPER_BOUND 100 -_Unwind_Reason_Code callback(_Unwind_Context *context, void *cnt) { +__attribute__((noinline)) _Unwind_Reason_Code callback(_Unwind_Context *context, + void *cnt) { (void)context; int *i = (int *)cnt; ++*i; @@ -28,7 +32,7 @@ _Unwind_Reason_Code callback(_Unwind_Context *context, void *cnt) { return _URC_NO_REASON; } -void test_backtrace() { +__attribute__((noinline)) void test_backtrace() { int n = 0; _Unwind_Backtrace(&callback, &n); if (n < EXPECTED_NUM_FRAMES) { @@ -36,17 +40,34 @@ void test_backtrace() { } } -int test(int i) { +// These functions are effectively the same, but we have to be careful to avoid +// unwanted optimizations that would mess with the number of frames we expect. +// Surprisingly, slapping `noinline` is not sufficient -- we also have to avoid +// writing the function in a way that the compiler can easily spot tail +// recursion. +__attribute__((noinline)) int test1(int i); +__attribute__((noinline)) int test2(int i); + +__attribute__((noinline)) int test1(int i) { + if (i == 0) { + test_backtrace(); + return 0; + } else { + return i + test2(i - 1); + } +} + +__attribute__((noinline)) int test2(int i) { if (i == 0) { test_backtrace(); return 0; } else { - return i + test(i - 1); + return i + test1(i - 1); } } int main(int, char**) { - int total = test(50); + int total = test1(50); assert(total == 1275); return 0; } diff --git a/src/native/external/llvm-libunwind/test/lit.cfg.py b/src/native/external/llvm-libunwind/test/lit.cfg.py index 647464abe22d9..ea4a9a75b4fdb 100644 --- a/src/native/external/llvm-libunwind/test/lit.cfg.py +++ b/src/native/external/llvm-libunwind/test/lit.cfg.py @@ -7,4 +7,5 @@ lit_config.fatal( "You seem to be running Lit directly -- you should be running Lit through " "/bin/llvm-lit, which will ensure that the right Lit configuration " - "file is used.") + "file is used." +) diff --git a/src/native/external/llvm-libunwind/test/signal_frame.pass.cpp b/src/native/external/llvm-libunwind/test/signal_frame.pass.cpp index 482481d9d96ba..004029cfe1e90 100644 --- a/src/native/external/llvm-libunwind/test/signal_frame.pass.cpp +++ b/src/native/external/llvm-libunwind/test/signal_frame.pass.cpp @@ -19,7 +19,11 @@ // The AIX assembler does not support CFI directives, which // are necessary to run this test. -// UNSUPPORTED: target=powerpc{{(64)?}}-ibm-aix +// UNSUPPORTED: target={{.*}}-aix{{.*}} + +// Windows doesn't generally use CFI directives. However, i686 +// mingw targets do use DWARF (where CFI directives are supported). +// UNSUPPORTED: target={{x86_64|arm.*|aarch64}}-{{.*}}-windows-{{.*}} #undef NDEBUG #include diff --git a/src/native/external/llvm-libunwind/test/signal_unwind.pass.cpp b/src/native/external/llvm-libunwind/test/signal_unwind.pass.cpp index e6a53ab9ff952..954a5d4ba3db1 100644 --- a/src/native/external/llvm-libunwind/test/signal_unwind.pass.cpp +++ b/src/native/external/llvm-libunwind/test/signal_unwind.pass.cpp @@ -8,7 +8,7 @@ //===----------------------------------------------------------------------===// // Ensure that the unwinder can cope with the signal handler. -// REQUIRES: linux && (target={{aarch64-.+}} || target={{s390x-.+}} || target={{x86_64-.+}}) +// REQUIRES: target={{(aarch64|riscv64|s390x|x86_64)-.+linux.*}} // TODO: Figure out why this fails with Memory Sanitizer. // XFAIL: msan diff --git a/src/native/external/llvm-libunwind/test/unw_resume.pass.cpp b/src/native/external/llvm-libunwind/test/unw_resume.pass.cpp index 76273e4a8ef0a..2b7470b5cad0e 100644 --- a/src/native/external/llvm-libunwind/test/unw_resume.pass.cpp +++ b/src/native/external/llvm-libunwind/test/unw_resume.pass.cpp @@ -10,15 +10,12 @@ // Ensure that unw_resume() resumes execution at the stack frame identified by // cursor. -// TODO: Investigate this failure on AIX system. -// XFAIL: target={{.*}}-aix{{.*}} - // TODO: Figure out why this fails with Memory Sanitizer. // XFAIL: msan #include -void test_unw_resume() { +__attribute__((noinline)) void test_unw_resume() { unw_context_t context; unw_cursor_t cursor; diff --git a/src/native/external/llvm-libunwind/test/unwind_leaffunction.pass.cpp b/src/native/external/llvm-libunwind/test/unwind_leaffunction.pass.cpp index bdeb44ab62ae8..112a5968247a4 100644 --- a/src/native/external/llvm-libunwind/test/unwind_leaffunction.pass.cpp +++ b/src/native/external/llvm-libunwind/test/unwind_leaffunction.pass.cpp @@ -8,7 +8,7 @@ //===----------------------------------------------------------------------===// // Ensure that leaf function can be unwund. -// REQUIRES: linux && (target={{aarch64-.+}} || target={{s390x-.+}} || target={{x86_64-.+}}) +// REQUIRES: target={{(aarch64|riscv64|s390x|x86_64)-.+linux.*}} // TODO: Figure out why this fails with Memory Sanitizer. // XFAIL: msan @@ -28,7 +28,7 @@ _Unwind_Reason_Code frame_handler(struct _Unwind_Context* ctx, void* arg) { (void)arg; Dl_info info = { 0, 0, 0, 0 }; - // Unwind until the main is reached, above frames deeped on the platform and + // Unwind until the main is reached, above frames depend on the platform and // architecture. if (dladdr(reinterpret_cast(_Unwind_GetIP(ctx)), &info) && info.dli_sname && !strcmp("main", info.dli_sname)) { @@ -43,18 +43,22 @@ void signal_handler(int signum) { _Exit(-1); } -__attribute__((noinline)) void crashing_leaf_func(void) { +__attribute__((noinline)) void crashing_leaf_func(int do_trap) { // libunwind searches for the address before the return address which points - // to the trap instruction. NOP guarantees the trap instruction is not the - // first instruction of the function. - // We should keep this here for other unwinders that also decrement pc. - __asm__ __volatile__("nop"); - __builtin_trap(); + // to the trap instruction. We make the trap conditional and prevent inlining + // of the function to ensure that the compiler doesn't remove the `ret` + // instruction altogether. + // + // It's also important that the trap instruction isn't the first instruction + // in the function (which it isn't because of the branch) for other unwinders + // that also decrement pc. + if (do_trap) + __builtin_trap(); } int main(int, char**) { signal(SIGTRAP, signal_handler); signal(SIGILL, signal_handler); - crashing_leaf_func(); + crashing_leaf_func(1); return -2; } diff --git a/src/native/external/llvm-libunwind/test/unwind_scalable_vectors.pass.cpp b/src/native/external/llvm-libunwind/test/unwind_scalable_vectors.pass.cpp index 250e2c8fc7b1e..a5c5947c870fd 100644 --- a/src/native/external/llvm-libunwind/test/unwind_scalable_vectors.pass.cpp +++ b/src/native/external/llvm-libunwind/test/unwind_scalable_vectors.pass.cpp @@ -13,30 +13,8 @@ #include #include -// Check correct unwinding of frame with VLENB-sized objects (vector registers): -// 1. Save return address (ra) in temporary register. -// 2. Load VLENB (vector length in bytes) and substract it from current stack -// pointer (sp) - equivalent to one vector register on stack frame. -// 3. Set DWARF cannonical frame address (CFA) to "sp + vlenb" expresssion so it -// can be correctly unwinded. -// 4. Call stepper() function and check that 2 unwind steps are successful - -// from stepper() into foo() and from foo() into main(). -// 5. Restore stack pointer and return address. -__attribute__((naked)) static void foo() { - __asm__(".cfi_startproc\n" - "mv s0, ra\n" - "csrr s1, vlenb\n" - "sub sp, sp, s1\n" - "# .cfi_def_cfa_expression sp + vlenb\n" - ".cfi_escape 0x0f, 0x07, 0x72, 0x00, 0x92, 0xa2, 0x38, 0x00, 0x22\n" - "call stepper\n" - "add sp, sp, s1\n" - "mv ra, s0\n" - "ret\n" - ".cfi_endproc\n"); -} - -extern "C" void stepper() { +#ifdef __riscv_vector +__attribute__((noinline)) extern "C" void stepper() { unw_cursor_t cursor; unw_context_t uc; unw_getcontext(&uc); @@ -47,4 +25,16 @@ extern "C" void stepper() { assert(unw_step(&cursor) > 0); } +// Check correct unwinding of frame with VLENB-sized objects (vector registers). +__attribute__((noinline)) static void foo() { + __rvv_int32m1_t v; + asm volatile("" : "=vr"(v)); // Dummy inline asm to def v. + stepper(); // def-use of v has cross the function, so that + // will triger spill/reload to/from the stack. + asm volatile("" ::"vr"(v)); // Dummy inline asm to use v. +} + int main() { foo(); } +#else +int main() { return 0; } +#endif From a53805790a49f5bf52776dc81c1c83ec7f21ebce Mon Sep 17 00:00:00 2001 From: Adeel <3840695+am11@users.noreply.github.com> Date: Wed, 15 May 2024 01:44:33 +0300 Subject: [PATCH 2/3] Apply all patches --- src/native/external/llvm-libunwind.cmake | 7 - .../include/__libunwind_config.h | 23 +- .../llvm-libunwind/include/libunwind.h | 24 +- .../llvm-libunwind/include/unwind_arm_ehabi.h | 8 +- .../llvm-libunwind/include/unwind_itanium.h | 2 +- .../llvm-libunwind/src/AddressSpace.hpp | 7 +- .../llvm-libunwind/src/CompactUnwinder.hpp | 226 +++++++-------- .../llvm-libunwind/src/DwarfInstructions.hpp | 58 ++-- .../llvm-libunwind/src/DwarfParser.hpp | 4 +- .../external/llvm-libunwind/src/Registers.hpp | 273 +++++++++++++++--- .../llvm-libunwind/src/Unwind-EHABI.cpp | 32 +- .../llvm-libunwind/src/UnwindCursor.hpp | 43 ++- .../src/UnwindRegistersRestore.S | 11 +- .../external/llvm-libunwind/src/libunwind.cpp | 21 +- .../llvm-libunwind/src/libunwind_ext.h | 3 +- 15 files changed, 506 insertions(+), 236 deletions(-) diff --git a/src/native/external/llvm-libunwind.cmake b/src/native/external/llvm-libunwind.cmake index 72cecd2a14980..720dc5ae6f890 100644 --- a/src/native/external/llvm-libunwind.cmake +++ b/src/native/external/llvm-libunwind.cmake @@ -9,13 +9,6 @@ set (LLVM_LIBUNWIND_SOURCES_BASE src/libunwind.cpp ) -if(CLR_CMAKE_TARGET_APPLE) - set(LLVM_LIBUNWIND_SOURCES_BASE - ${LLVM_LIBUNWIND_SOURCES_BASE} - src/Unwind_AppleExtras.cpp - ) -endif() - set(LLVM_LIBUNWIND_ASM_SOURCES_BASE src/UnwindRegistersRestore.S src/UnwindRegistersSave.S diff --git a/src/native/external/llvm-libunwind/include/__libunwind_config.h b/src/native/external/llvm-libunwind/include/__libunwind_config.h index 8db336b2d727c..ecfe7be0d12f6 100644 --- a/src/native/external/llvm-libunwind/include/__libunwind_config.h +++ b/src/native/external/llvm-libunwind/include/__libunwind_config.h @@ -41,8 +41,8 @@ # endif # if defined(__i386__) # define _LIBUNWIND_TARGET_I386 -# define _LIBUNWIND_CONTEXT_SIZE 8 -# define _LIBUNWIND_CURSOR_SIZE 15 +# define _LIBUNWIND_CONTEXT_SIZE 13 +# define _LIBUNWIND_CURSOR_SIZE 19 # define _LIBUNWIND_HIGHEST_DWARF_REGISTER _LIBUNWIND_HIGHEST_DWARF_REGISTER_X86 # elif defined(__x86_64__) # define _LIBUNWIND_TARGET_X86_64 1 @@ -54,8 +54,8 @@ # define _LIBUNWIND_CURSOR_SIZE 66 # endif # else -# define _LIBUNWIND_CONTEXT_SIZE 21 -# define _LIBUNWIND_CURSOR_SIZE 33 +# define _LIBUNWIND_CONTEXT_SIZE 38 +# define _LIBUNWIND_CURSOR_SIZE 50 # endif # define _LIBUNWIND_HIGHEST_DWARF_REGISTER _LIBUNWIND_HIGHEST_DWARF_REGISTER_X86_64 # elif defined(__powerpc64__) @@ -70,11 +70,11 @@ # 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_CONTEXT_SIZE 100 # if defined(__SEH__) -# define _LIBUNWIND_CURSOR_SIZE 164 +# define _LIBUNWIND_CURSOR_SIZE 198 # else -# define _LIBUNWIND_CURSOR_SIZE 78 +# define _LIBUNWIND_CURSOR_SIZE 112 # endif # define _LIBUNWIND_HIGHEST_DWARF_REGISTER _LIBUNWIND_HIGHEST_DWARF_REGISTER_ARM64 # elif defined(__arm__) @@ -86,8 +86,8 @@ # define _LIBUNWIND_CONTEXT_SIZE 61 # define _LIBUNWIND_CURSOR_SIZE 68 # else -# define _LIBUNWIND_CONTEXT_SIZE 42 -# define _LIBUNWIND_CURSOR_SIZE 49 +# define _LIBUNWIND_CONTEXT_SIZE 50 +# define _LIBUNWIND_CURSOR_SIZE 57 # endif # define _LIBUNWIND_HIGHEST_DWARF_REGISTER _LIBUNWIND_HIGHEST_DWARF_REGISTER_ARM # elif defined(__or1k__) @@ -175,6 +175,11 @@ #if __loongarch_grlen == 64 #define _LIBUNWIND_CONTEXT_SIZE 65 #define _LIBUNWIND_CURSOR_SIZE 77 +#elif defined(HOST_WASM) +#define _LIBUNWIND_TARGET_WASM 1 +// TODO: Determine the right values +#define _LIBUNWIND_CONTEXT_SIZE 0xbadf00d +#define _LIBUNWIND_CURSOR_SIZE 0xbadf00d #else #error "Unsupported LoongArch ABI" #endif diff --git a/src/native/external/llvm-libunwind/include/libunwind.h b/src/native/external/llvm-libunwind/include/libunwind.h index b2dae8feed9a3..7a8fcbcb26745 100644 --- a/src/native/external/llvm-libunwind/include/libunwind.h +++ b/src/native/external/llvm-libunwind/include/libunwind.h @@ -102,6 +102,26 @@ struct unw_proc_info_t { }; typedef struct unw_proc_info_t unw_proc_info_t; +enum unw_save_loc_type_t +{ + UNW_SLT_NONE, /* register is not saved ("not an l-value") */ + UNW_SLT_MEMORY, /* register has been saved in memory */ + UNW_SLT_REG /* register has been saved in (another) register */ +}; +typedef enum unw_save_loc_type_t unw_save_loc_type_t; + +struct unw_save_loc_t +{ + unw_save_loc_type_t type; + union + { + unw_word_t addr; /* valid if type==UNW_SLT_MEMORY */ + unw_regnum_t regnum; /* valid if type==UNW_SLT_REG */ + } + u; +}; +typedef struct unw_save_loc_t unw_save_loc_t; + #ifdef __cplusplus extern "C" { #endif @@ -111,7 +131,7 @@ 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_reg(unw_cursor_t *, unw_regnum_t, unw_word_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; @@ -129,7 +149,7 @@ 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 int unw_get_save_loc(unw_cursor_t*, int, unw_save_loc_t*) LIBUNWIND_AVAIL; extern unw_addr_space_t unw_local_addr_space; diff --git a/src/native/external/llvm-libunwind/include/unwind_arm_ehabi.h b/src/native/external/llvm-libunwind/include/unwind_arm_ehabi.h index 6277a1457f896..5fa94a167ff10 100644 --- a/src/native/external/llvm-libunwind/include/unwind_arm_ehabi.h +++ b/src/native/external/llvm-libunwind/include/unwind_arm_ehabi.h @@ -118,7 +118,7 @@ _Unwind_VRS_Get(_Unwind_Context *context, _Unwind_VRS_RegClass regclass, extern _Unwind_VRS_Result _Unwind_VRS_Set(_Unwind_Context *context, _Unwind_VRS_RegClass regclass, uint32_t regno, _Unwind_VRS_DataRepresentation representation, - void *valuep); + void *valuep, uintptr_t *pos); extern _Unwind_VRS_Result _Unwind_VRS_Pop(_Unwind_Context *context, _Unwind_VRS_RegClass regclass, @@ -147,8 +147,8 @@ uintptr_t _Unwind_GetGR(struct _Unwind_Context *context, int index) { _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); + uintptr_t value, uintptr_t *pos) { + _Unwind_VRS_Set(context, _UVRSC_CORE, (uint32_t)index, _UVRSD_UINT32, &value, pos); } _LIBUNWIND_EXPORT_UNWIND_LEVEL1 @@ -160,7 +160,7 @@ uintptr_t _Unwind_GetIP(struct _Unwind_Context *context) { _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); + _Unwind_SetGR(context, 15, value | thumb_bit, NULL); } #ifdef __cplusplus diff --git a/src/native/external/llvm-libunwind/include/unwind_itanium.h b/src/native/external/llvm-libunwind/include/unwind_itanium.h index d94a6183be290..7e813c7c2b07a 100644 --- a/src/native/external/llvm-libunwind/include/unwind_itanium.h +++ b/src/native/external/llvm-libunwind/include/unwind_itanium.h @@ -65,7 +65,7 @@ extern void _Unwind_DeleteException(_Unwind_Exception *exception_object); 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); + uintptr_t new_value, uintptr_t *pos); extern uintptr_t _Unwind_GetIP(struct _Unwind_Context *context); extern void _Unwind_SetIP(struct _Unwind_Context *, uintptr_t new_value); diff --git a/src/native/external/llvm-libunwind/src/AddressSpace.hpp b/src/native/external/llvm-libunwind/src/AddressSpace.hpp index 5551c7d4bef1c..33f6441529826 100644 --- a/src/native/external/llvm-libunwind/src/AddressSpace.hpp +++ b/src/native/external/llvm-libunwind/src/AddressSpace.hpp @@ -22,6 +22,7 @@ #include "dwarf2.h" #include "EHHeaderParser.hpp" #include "Registers.hpp" +#include "libunwind_ext.h" #ifndef _LIBUNWIND_USE_DLADDR #if !(defined(_LIBUNWIND_IS_BAREMETAL) || defined(_WIN32) || defined(_AIX)) @@ -603,11 +604,7 @@ inline bool LocalAddressSpace::findUnwindSections(pint_t targetAddr, // `_dl_find_object`. Use _LIBUNWIND_SUPPORT_DWARF_INDEX, because libunwind // support for _dl_find_object on other unwind formats is not implemented, // yet. -#if defined(DLFO_STRUCT_HAS_EH_DBASE) & defined(_LIBUNWIND_SUPPORT_DWARF_INDEX) - // We expect `_dl_find_object` to return PT_GNU_EH_FRAME. -#if DLFO_EH_SEGMENT_TYPE != PT_GNU_EH_FRAME -#error _dl_find_object retrieves an unexpected section type -#endif +#if defined(DLFO_STRUCT_HAS_EH_DBASE) && defined(_LIBUNWIND_SUPPORT_DWARF_INDEX) && DLFO_EH_SEGMENT_TYPE == PT_GNU_EH_FRAME // We look-up `dl_find_object` dynamically at runtime to ensure backwards // compatibility with earlier version of glibc not yet providing it. On older // systems, we gracefully fallback to `dl_iterate_phdr`. Cache the pointer diff --git a/src/native/external/llvm-libunwind/src/CompactUnwinder.hpp b/src/native/external/llvm-libunwind/src/CompactUnwinder.hpp index a7a8a153d86a4..5cb825e2fd3e9 100644 --- a/src/native/external/llvm-libunwind/src/CompactUnwinder.hpp +++ b/src/native/external/llvm-libunwind/src/CompactUnwinder.hpp @@ -29,34 +29,34 @@ 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 +template class CompactUnwinder_x86 { public: static int stepWithCompactEncoding(compact_unwind_encoding_t info, uint32_t functionStart, A &addressSpace, - Registers_x86 ®isters); + R ®isters); private: typename A::pint_t pint_t; - static void frameUnwind(A &addressSpace, Registers_x86 ®isters); + static void frameUnwind(A &addressSpace, R ®isters); static void framelessUnwind(A &addressSpace, typename A::pint_t returnAddressLocation, - Registers_x86 ®isters); + R ®isters); static int stepWithCompactEncodingEBPFrame(compact_unwind_encoding_t compactEncoding, uint32_t functionStart, A &addressSpace, - Registers_x86 ®isters); + R ®isters); static int stepWithCompactEncodingFrameless( compact_unwind_encoding_t compactEncoding, uint32_t functionStart, - A &addressSpace, Registers_x86 ®isters, bool indirectStackSize); + A &addressSpace, R ®isters, bool indirectStackSize); }; -template -int CompactUnwinder_x86::stepWithCompactEncoding( +template +int CompactUnwinder_x86::stepWithCompactEncoding( compact_unwind_encoding_t compactEncoding, uint32_t functionStart, - A &addressSpace, Registers_x86 ®isters) { + A &addressSpace, R ®isters) { switch (compactEncoding & UNWIND_X86_MODE_MASK) { case UNWIND_X86_MODE_EBP_FRAME: return stepWithCompactEncodingEBPFrame(compactEncoding, functionStart, @@ -71,10 +71,10 @@ int CompactUnwinder_x86::stepWithCompactEncoding( _LIBUNWIND_ABORT("invalid compact unwind encoding"); } -template -int CompactUnwinder_x86::stepWithCompactEncodingEBPFrame( +template +int CompactUnwinder_x86::stepWithCompactEncodingEBPFrame( compact_unwind_encoding_t compactEncoding, uint32_t functionStart, - A &addressSpace, Registers_x86 ®isters) { + A &addressSpace, R ®isters) { uint32_t savedRegistersOffset = EXTRACT_BITS(compactEncoding, UNWIND_X86_EBP_FRAME_OFFSET); uint32_t savedRegistersLocations = @@ -87,19 +87,19 @@ int CompactUnwinder_x86::stepWithCompactEncodingEBPFrame( // no register saved in this slot break; case UNWIND_X86_REG_EBX: - registers.setEBX(addressSpace.get32(savedRegisters)); + registers.setEBX(addressSpace.get32(savedRegisters), savedRegisters); break; case UNWIND_X86_REG_ECX: - registers.setECX(addressSpace.get32(savedRegisters)); + registers.setECX(addressSpace.get32(savedRegisters), savedRegisters); break; case UNWIND_X86_REG_EDX: - registers.setEDX(addressSpace.get32(savedRegisters)); + registers.setEDX(addressSpace.get32(savedRegisters), savedRegisters); break; case UNWIND_X86_REG_EDI: - registers.setEDI(addressSpace.get32(savedRegisters)); + registers.setEDI(addressSpace.get32(savedRegisters), savedRegisters); break; case UNWIND_X86_REG_ESI: - registers.setESI(addressSpace.get32(savedRegisters)); + registers.setESI(addressSpace.get32(savedRegisters), savedRegisters); break; default: (void)functionStart; @@ -115,10 +115,10 @@ int CompactUnwinder_x86::stepWithCompactEncodingEBPFrame( return UNW_STEP_SUCCESS; } -template -int CompactUnwinder_x86::stepWithCompactEncodingFrameless( +template +int CompactUnwinder_x86::stepWithCompactEncodingFrameless( compact_unwind_encoding_t encoding, uint32_t functionStart, - A &addressSpace, Registers_x86 ®isters, bool indirectStackSize) { + A &addressSpace, R ®isters, bool indirectStackSize) { uint32_t stackSizeEncoded = EXTRACT_BITS(encoding, UNWIND_X86_FRAMELESS_STACK_SIZE); uint32_t stackAdjust = @@ -204,22 +204,22 @@ int CompactUnwinder_x86::stepWithCompactEncodingFrameless( for (uint32_t i = 0; i < regCount; ++i) { switch (registersSaved[i]) { case UNWIND_X86_REG_EBX: - registers.setEBX(addressSpace.get32(savedRegisters)); + registers.setEBX(addressSpace.get32(savedRegisters), savedRegisters); break; case UNWIND_X86_REG_ECX: - registers.setECX(addressSpace.get32(savedRegisters)); + registers.setECX(addressSpace.get32(savedRegisters), savedRegisters); break; case UNWIND_X86_REG_EDX: - registers.setEDX(addressSpace.get32(savedRegisters)); + registers.setEDX(addressSpace.get32(savedRegisters), savedRegisters); break; case UNWIND_X86_REG_EDI: - registers.setEDI(addressSpace.get32(savedRegisters)); + registers.setEDI(addressSpace.get32(savedRegisters), savedRegisters); break; case UNWIND_X86_REG_ESI: - registers.setESI(addressSpace.get32(savedRegisters)); + registers.setESI(addressSpace.get32(savedRegisters), savedRegisters); break; case UNWIND_X86_REG_EBP: - registers.setEBP(addressSpace.get32(savedRegisters)); + registers.setEBP(addressSpace.get32(savedRegisters), savedRegisters); break; default: _LIBUNWIND_DEBUG_LOG("bad register for frameless, encoding=%08X for " @@ -234,26 +234,26 @@ int CompactUnwinder_x86::stepWithCompactEncodingFrameless( } -template -void CompactUnwinder_x86::frameUnwind(A &addressSpace, - Registers_x86 ®isters) { +template +void CompactUnwinder_x86::frameUnwind(A &addressSpace, + R ®isters) { typename A::pint_t bp = registers.getEBP(); // ebp points to old ebp - registers.setEBP(addressSpace.get32(bp)); + registers.setEBP(addressSpace.get32(bp), bp); // old esp is ebp less saved ebp and return address - registers.setSP((uint32_t)bp + 8); + registers.setSP((uint32_t)bp + 8, 0); // pop return address into eip - registers.setIP(addressSpace.get32(bp + 4)); + registers.setIP(addressSpace.get32(bp + 4), bp + 4); } -template -void CompactUnwinder_x86::framelessUnwind( +template +void CompactUnwinder_x86::framelessUnwind( A &addressSpace, typename A::pint_t returnAddressLocation, - Registers_x86 ®isters) { + R ®isters) { // return address is on stack after last saved register - registers.setIP(addressSpace.get32(returnAddressLocation)); + registers.setIP(addressSpace.get32(returnAddressLocation), returnAddressLocation); // old esp is before return address - registers.setSP((uint32_t)returnAddressLocation + 4); + registers.setSP((uint32_t)returnAddressLocation + 4, 0); } #endif // _LIBUNWIND_TARGET_I386 @@ -261,33 +261,33 @@ void CompactUnwinder_x86::framelessUnwind( #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 +template class CompactUnwinder_x86_64 { public: static int stepWithCompactEncoding(compact_unwind_encoding_t compactEncoding, uint64_t functionStart, A &addressSpace, - Registers_x86_64 ®isters); + R ®isters); private: typename A::pint_t pint_t; - static void frameUnwind(A &addressSpace, Registers_x86_64 ®isters); + static void frameUnwind(A &addressSpace, R ®isters); static void framelessUnwind(A &addressSpace, uint64_t returnAddressLocation, - Registers_x86_64 ®isters); + R ®isters); static int stepWithCompactEncodingRBPFrame(compact_unwind_encoding_t compactEncoding, uint64_t functionStart, A &addressSpace, - Registers_x86_64 ®isters); + R ®isters); static int stepWithCompactEncodingFrameless( compact_unwind_encoding_t compactEncoding, uint64_t functionStart, - A &addressSpace, Registers_x86_64 ®isters, bool indirectStackSize); + A &addressSpace, R ®isters, bool indirectStackSize); }; -template -int CompactUnwinder_x86_64::stepWithCompactEncoding( +template +int CompactUnwinder_x86_64::stepWithCompactEncoding( compact_unwind_encoding_t compactEncoding, uint64_t functionStart, - A &addressSpace, Registers_x86_64 ®isters) { + A &addressSpace, R ®isters) { switch (compactEncoding & UNWIND_X86_64_MODE_MASK) { case UNWIND_X86_64_MODE_RBP_FRAME: return stepWithCompactEncodingRBPFrame(compactEncoding, functionStart, @@ -302,10 +302,10 @@ int CompactUnwinder_x86_64::stepWithCompactEncoding( _LIBUNWIND_ABORT("invalid compact unwind encoding"); } -template -int CompactUnwinder_x86_64::stepWithCompactEncodingRBPFrame( +template +int CompactUnwinder_x86_64::stepWithCompactEncodingRBPFrame( compact_unwind_encoding_t compactEncoding, uint64_t functionStart, - A &addressSpace, Registers_x86_64 ®isters) { + A &addressSpace, R ®isters) { uint32_t savedRegistersOffset = EXTRACT_BITS(compactEncoding, UNWIND_X86_64_RBP_FRAME_OFFSET); uint32_t savedRegistersLocations = @@ -318,19 +318,19 @@ int CompactUnwinder_x86_64::stepWithCompactEncodingRBPFrame( // no register saved in this slot break; case UNWIND_X86_64_REG_RBX: - registers.setRBX(addressSpace.get64(savedRegisters)); + registers.setRBX(addressSpace.get64(savedRegisters), savedRegisters); break; case UNWIND_X86_64_REG_R12: - registers.setR12(addressSpace.get64(savedRegisters)); + registers.setR12(addressSpace.get64(savedRegisters), savedRegisters); break; case UNWIND_X86_64_REG_R13: - registers.setR13(addressSpace.get64(savedRegisters)); + registers.setR13(addressSpace.get64(savedRegisters), savedRegisters); break; case UNWIND_X86_64_REG_R14: - registers.setR14(addressSpace.get64(savedRegisters)); + registers.setR14(addressSpace.get64(savedRegisters), savedRegisters); break; case UNWIND_X86_64_REG_R15: - registers.setR15(addressSpace.get64(savedRegisters)); + registers.setR15(addressSpace.get64(savedRegisters), savedRegisters); break; default: (void)functionStart; @@ -346,10 +346,10 @@ int CompactUnwinder_x86_64::stepWithCompactEncodingRBPFrame( return UNW_STEP_SUCCESS; } -template -int CompactUnwinder_x86_64::stepWithCompactEncodingFrameless( +template +int CompactUnwinder_x86_64::stepWithCompactEncodingFrameless( compact_unwind_encoding_t encoding, uint64_t functionStart, A &addressSpace, - Registers_x86_64 ®isters, bool indirectStackSize) { + R ®isters, bool indirectStackSize) { uint32_t stackSizeEncoded = EXTRACT_BITS(encoding, UNWIND_X86_64_FRAMELESS_STACK_SIZE); uint32_t stackAdjust = @@ -435,22 +435,22 @@ int CompactUnwinder_x86_64::stepWithCompactEncodingFrameless( for (uint32_t i = 0; i < regCount; ++i) { switch (registersSaved[i]) { case UNWIND_X86_64_REG_RBX: - registers.setRBX(addressSpace.get64(savedRegisters)); + registers.setRBX(addressSpace.get64(savedRegisters), savedRegisters); break; case UNWIND_X86_64_REG_R12: - registers.setR12(addressSpace.get64(savedRegisters)); + registers.setR12(addressSpace.get64(savedRegisters), savedRegisters); break; case UNWIND_X86_64_REG_R13: - registers.setR13(addressSpace.get64(savedRegisters)); + registers.setR13(addressSpace.get64(savedRegisters), savedRegisters); break; case UNWIND_X86_64_REG_R14: - registers.setR14(addressSpace.get64(savedRegisters)); + registers.setR14(addressSpace.get64(savedRegisters), savedRegisters); break; case UNWIND_X86_64_REG_R15: - registers.setR15(addressSpace.get64(savedRegisters)); + registers.setR15(addressSpace.get64(savedRegisters), savedRegisters); break; case UNWIND_X86_64_REG_RBP: - registers.setRBP(addressSpace.get64(savedRegisters)); + registers.setRBP(addressSpace.get64(savedRegisters), savedRegisters); break; default: _LIBUNWIND_DEBUG_LOG("bad register for frameless, encoding=%08X for " @@ -465,26 +465,26 @@ int CompactUnwinder_x86_64::stepWithCompactEncodingFrameless( } -template -void CompactUnwinder_x86_64::frameUnwind(A &addressSpace, - Registers_x86_64 ®isters) { +template +void CompactUnwinder_x86_64::frameUnwind(A &addressSpace, + R ®isters) { uint64_t rbp = registers.getRBP(); // ebp points to old ebp - registers.setRBP(addressSpace.get64(rbp)); + registers.setRBP(addressSpace.get64(rbp), rbp); // old esp is ebp less saved ebp and return address - registers.setSP(rbp + 16); + registers.setSP(rbp + 16, 0); // pop return address into eip - registers.setIP(addressSpace.get64(rbp + 8)); + registers.setIP(addressSpace.get64(rbp + 8), rbp + 8); } -template -void CompactUnwinder_x86_64::framelessUnwind(A &addressSpace, - uint64_t returnAddressLocation, - Registers_x86_64 ®isters) { +template +void CompactUnwinder_x86_64::framelessUnwind(A &addressSpace, + uint64_t returnAddressLocation, + R ®isters) { // return address is on stack after last saved register - registers.setIP(addressSpace.get64(returnAddressLocation)); + registers.setIP(addressSpace.get64(returnAddressLocation), returnAddressLocation); // old esp is before return address - registers.setSP(returnAddressLocation + 8); + registers.setSP(returnAddressLocation + 8, 0); } #endif // _LIBUNWIND_TARGET_X86_64 @@ -493,13 +493,13 @@ void CompactUnwinder_x86_64::framelessUnwind(A &addressSpace, #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 +template class CompactUnwinder_arm64 { public: static int stepWithCompactEncoding(compact_unwind_encoding_t compactEncoding, uint64_t functionStart, A &addressSpace, - Registers_arm64 ®isters); + R ®isters); private: typename A::pint_t pint_t; @@ -507,16 +507,16 @@ class CompactUnwinder_arm64 { static int stepWithCompactEncodingFrame(compact_unwind_encoding_t compactEncoding, uint64_t functionStart, A &addressSpace, - Registers_arm64 ®isters); + R ®isters); static int stepWithCompactEncodingFrameless( compact_unwind_encoding_t compactEncoding, uint64_t functionStart, - A &addressSpace, Registers_arm64 ®isters); + A &addressSpace, R ®isters); }; -template -int CompactUnwinder_arm64::stepWithCompactEncoding( +template +int CompactUnwinder_arm64::stepWithCompactEncoding( compact_unwind_encoding_t compactEncoding, uint64_t functionStart, - A &addressSpace, Registers_arm64 ®isters) { + A &addressSpace, R ®isters) { switch (compactEncoding & UNWIND_ARM64_MODE_MASK) { case UNWIND_ARM64_MODE_FRAME: return stepWithCompactEncodingFrame(compactEncoding, functionStart, @@ -528,43 +528,43 @@ int CompactUnwinder_arm64::stepWithCompactEncoding( _LIBUNWIND_ABORT("invalid compact unwind encoding"); } -template -int CompactUnwinder_arm64::stepWithCompactEncodingFrameless( +template +int CompactUnwinder_arm64::stepWithCompactEncodingFrameless( compact_unwind_encoding_t encoding, uint64_t, A &addressSpace, - Registers_arm64 ®isters) { + R ®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_AARCH64_X19, addressSpace.get64(savedRegisterLoc)); + registers.setRegister(UNW_AARCH64_X19, addressSpace.get64(savedRegisterLoc), savedRegisterLoc); savedRegisterLoc -= 8; - registers.setRegister(UNW_AARCH64_X20, addressSpace.get64(savedRegisterLoc)); + registers.setRegister(UNW_AARCH64_X20, addressSpace.get64(savedRegisterLoc), savedRegisterLoc); savedRegisterLoc -= 8; } if (encoding & UNWIND_ARM64_FRAME_X21_X22_PAIR) { - registers.setRegister(UNW_AARCH64_X21, addressSpace.get64(savedRegisterLoc)); + registers.setRegister(UNW_AARCH64_X21, addressSpace.get64(savedRegisterLoc), savedRegisterLoc); savedRegisterLoc -= 8; - registers.setRegister(UNW_AARCH64_X22, addressSpace.get64(savedRegisterLoc)); + registers.setRegister(UNW_AARCH64_X22, addressSpace.get64(savedRegisterLoc), savedRegisterLoc); savedRegisterLoc -= 8; } if (encoding & UNWIND_ARM64_FRAME_X23_X24_PAIR) { - registers.setRegister(UNW_AARCH64_X23, addressSpace.get64(savedRegisterLoc)); + registers.setRegister(UNW_AARCH64_X23, addressSpace.get64(savedRegisterLoc), savedRegisterLoc); savedRegisterLoc -= 8; - registers.setRegister(UNW_AARCH64_X24, addressSpace.get64(savedRegisterLoc)); + registers.setRegister(UNW_AARCH64_X24, addressSpace.get64(savedRegisterLoc), savedRegisterLoc); savedRegisterLoc -= 8; } if (encoding & UNWIND_ARM64_FRAME_X25_X26_PAIR) { - registers.setRegister(UNW_AARCH64_X25, addressSpace.get64(savedRegisterLoc)); + registers.setRegister(UNW_AARCH64_X25, addressSpace.get64(savedRegisterLoc), savedRegisterLoc); savedRegisterLoc -= 8; - registers.setRegister(UNW_AARCH64_X26, addressSpace.get64(savedRegisterLoc)); + registers.setRegister(UNW_AARCH64_X26, addressSpace.get64(savedRegisterLoc), savedRegisterLoc); savedRegisterLoc -= 8; } if (encoding & UNWIND_ARM64_FRAME_X27_X28_PAIR) { - registers.setRegister(UNW_AARCH64_X27, addressSpace.get64(savedRegisterLoc)); + registers.setRegister(UNW_AARCH64_X27, addressSpace.get64(savedRegisterLoc), savedRegisterLoc); savedRegisterLoc -= 8; - registers.setRegister(UNW_AARCH64_X28, addressSpace.get64(savedRegisterLoc)); + registers.setRegister(UNW_AARCH64_X28, addressSpace.get64(savedRegisterLoc), savedRegisterLoc); savedRegisterLoc -= 8; } @@ -602,48 +602,48 @@ int CompactUnwinder_arm64::stepWithCompactEncodingFrameless( } // subtract stack size off of sp - registers.setSP(savedRegisterLoc); + registers.setSP(savedRegisterLoc, 0); // set pc to be value in lr - registers.setIP(registers.getRegister(UNW_AARCH64_LR)); + registers.setIP(registers.getRegister(UNW_AARCH64_LR), 0); return UNW_STEP_SUCCESS; } -template -int CompactUnwinder_arm64::stepWithCompactEncodingFrame( +template +int CompactUnwinder_arm64::stepWithCompactEncodingFrame( compact_unwind_encoding_t encoding, uint64_t, A &addressSpace, - Registers_arm64 ®isters) { + R ®isters) { uint64_t savedRegisterLoc = registers.getFP() - 8; if (encoding & UNWIND_ARM64_FRAME_X19_X20_PAIR) { - registers.setRegister(UNW_AARCH64_X19, addressSpace.get64(savedRegisterLoc)); + registers.setRegister(UNW_AARCH64_X19, addressSpace.get64(savedRegisterLoc), savedRegisterLoc); savedRegisterLoc -= 8; - registers.setRegister(UNW_AARCH64_X20, addressSpace.get64(savedRegisterLoc)); + registers.setRegister(UNW_AARCH64_X20, addressSpace.get64(savedRegisterLoc), savedRegisterLoc); savedRegisterLoc -= 8; } if (encoding & UNWIND_ARM64_FRAME_X21_X22_PAIR) { - registers.setRegister(UNW_AARCH64_X21, addressSpace.get64(savedRegisterLoc)); + registers.setRegister(UNW_AARCH64_X21, addressSpace.get64(savedRegisterLoc), savedRegisterLoc); savedRegisterLoc -= 8; - registers.setRegister(UNW_AARCH64_X22, addressSpace.get64(savedRegisterLoc)); + registers.setRegister(UNW_AARCH64_X22, addressSpace.get64(savedRegisterLoc), savedRegisterLoc); savedRegisterLoc -= 8; } if (encoding & UNWIND_ARM64_FRAME_X23_X24_PAIR) { - registers.setRegister(UNW_AARCH64_X23, addressSpace.get64(savedRegisterLoc)); + registers.setRegister(UNW_AARCH64_X23, addressSpace.get64(savedRegisterLoc), savedRegisterLoc); savedRegisterLoc -= 8; - registers.setRegister(UNW_AARCH64_X24, addressSpace.get64(savedRegisterLoc)); + registers.setRegister(UNW_AARCH64_X24, addressSpace.get64(savedRegisterLoc), savedRegisterLoc); savedRegisterLoc -= 8; } if (encoding & UNWIND_ARM64_FRAME_X25_X26_PAIR) { - registers.setRegister(UNW_AARCH64_X25, addressSpace.get64(savedRegisterLoc)); + registers.setRegister(UNW_AARCH64_X25, addressSpace.get64(savedRegisterLoc), savedRegisterLoc); savedRegisterLoc -= 8; - registers.setRegister(UNW_AARCH64_X26, addressSpace.get64(savedRegisterLoc)); + registers.setRegister(UNW_AARCH64_X26, addressSpace.get64(savedRegisterLoc), savedRegisterLoc); savedRegisterLoc -= 8; } if (encoding & UNWIND_ARM64_FRAME_X27_X28_PAIR) { - registers.setRegister(UNW_AARCH64_X27, addressSpace.get64(savedRegisterLoc)); + registers.setRegister(UNW_AARCH64_X27, addressSpace.get64(savedRegisterLoc), savedRegisterLoc); savedRegisterLoc -= 8; - registers.setRegister(UNW_AARCH64_X28, addressSpace.get64(savedRegisterLoc)); + registers.setRegister(UNW_AARCH64_X28, addressSpace.get64(savedRegisterLoc), savedRegisterLoc); savedRegisterLoc -= 8; } @@ -682,11 +682,11 @@ int CompactUnwinder_arm64::stepWithCompactEncodingFrame( uint64_t fp = registers.getFP(); // fp points to old fp - registers.setFP(addressSpace.get64(fp)); + registers.setFP(addressSpace.get64(fp), fp); // old sp is fp less saved fp and lr - registers.setSP(fp + 16); + registers.setSP(fp + 16, 0); // pop return address into pc - registers.setIP(addressSpace.get64(fp + 8)); + registers.setIP(addressSpace.get64(fp + 8), fp + 8); return UNW_STEP_SUCCESS; } diff --git a/src/native/external/llvm-libunwind/src/DwarfInstructions.hpp b/src/native/external/llvm-libunwind/src/DwarfInstructions.hpp index bd9ece60ee588..a4e75755e5b4d 100644 --- a/src/native/external/llvm-libunwind/src/DwarfInstructions.hpp +++ b/src/native/external/llvm-libunwind/src/DwarfInstructions.hpp @@ -56,7 +56,8 @@ class DwarfInstructions { const R ®isters, pint_t initialStackValue); static pint_t getSavedRegister(A &addressSpace, const R ®isters, - pint_t cfa, const RegisterLocation &savedReg); + pint_t cfa, const RegisterLocation &savedReg, + pint_t& location); static double getSavedFloatRegister(A &addressSpace, const R ®isters, pint_t cfa, const RegisterLocation &savedReg); static v128 getSavedVectorRegister(A &addressSpace, const R ®isters, @@ -90,24 +91,28 @@ template uint64_t getSparcWCookie(const R &, long) { template typename A::pint_t DwarfInstructions::getSavedRegister( A &addressSpace, const R ®isters, pint_t cfa, - const RegisterLocation &savedReg) { + const RegisterLocation &savedReg, + typename A::pint_t& location) { switch (savedReg.location) { case CFI_Parser::kRegisterInCFA: - return (pint_t)addressSpace.getRegister(cfa + (pint_t)savedReg.value); + location = cfa + (pint_t)savedReg.value; + return (pint_t)addressSpace.getP(location); case CFI_Parser::kRegisterInCFADecrypt: // sparc64 specific return (pint_t)(addressSpace.getP(cfa + (pint_t)savedReg.value) ^ getSparcWCookie(registers, 0)); case CFI_Parser::kRegisterAtExpression: - return (pint_t)addressSpace.getRegister(evaluateExpression( - (pint_t)savedReg.value, addressSpace, registers, cfa)); + location = evaluateExpression((pint_t)savedReg.value, addressSpace, + registers, cfa); + return (pint_t)addressSpace.getP(location); case CFI_Parser::kRegisterIsExpression: + location = 0; return evaluateExpression((pint_t)savedReg.value, addressSpace, registers, cfa); - case CFI_Parser::kRegisterInRegister: + location = 0; return registers.getRegister((int)savedReg.value); case CFI_Parser::kRegisterUndefined: return 0; @@ -176,11 +181,12 @@ template bool DwarfInstructions::getRA_SIGN_STATE(A &addressSpace, R registers, pint_t cfa, PrologInfo &prolog) { pint_t raSignState; + pint_t location; auto regloc = prolog.savedRegisters[UNW_AARCH64_RA_SIGN_STATE]; if (regloc.location == CFI_Parser::kRegisterUnused) raSignState = static_cast(regloc.value); else - raSignState = getSavedRegister(addressSpace, registers, cfa, regloc); + raSignState = getSavedRegister(addressSpace, registers, cfa, regloc, location); // Only bit[0] is meaningful. return raSignState & 0x01; @@ -205,7 +211,7 @@ int DwarfInstructions::stepWithDwarf(A &addressSpace, pint_t pc, // __unw_step_stage2 is not used for cross unwinding, so we use // __aarch64__ rather than LIBUNWIND_TARGET_AARCH64 to make sure we are // building for AArch64 natively. -#if defined(__aarch64__) +#if 0 // defined(__aarch64__) if (stage2 && cieInfo.mteTaggedFrame) { pint_t sp = registers.getSP(); pint_t p = sp; @@ -243,13 +249,13 @@ int DwarfInstructions::stepWithDwarf(A &addressSpace, pint_t pc, // // We set the SP here to the CFA, allowing for it to be overridden // by a CFI directive later on. - newRegisters.setSP(cfa); + newRegisters.setSP(cfa, 0); pint_t returnAddress = 0; - constexpr int lastReg = R::lastDwarfRegNum(); - static_assert(static_cast(CFI_Parser::kMaxRegisterNumber) >= - lastReg, - "register range too large"); + pint_t returnAddressLocation = 0; + const int lastReg = R::lastDwarfRegNum(); + assert(static_cast(CFI_Parser::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) { @@ -263,13 +269,23 @@ int DwarfInstructions::stepWithDwarf(A &addressSpace, pint_t pc, newRegisters.setVectorRegister( i, getSavedVectorRegister(addressSpace, registers, cfa, prolog.savedRegisters[i])); - else if (i == (int)cieInfo.returnAddressRegister) + 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])); + prolog.savedRegisters[i], + returnAddressLocation); + if (registers.validRegister(i)) { + newRegisters.setRegister(i, returnAddress, returnAddressLocation); + } + } + else if (registers.validRegister(i)) { + pint_t value; + pint_t location; + value = getSavedRegister(addressSpace, registers, cfa, + prolog.savedRegisters[i], + location); + + newRegisters.setRegister(i, value, location); + } else return UNW_EBADREG; } else if (i == (int)cieInfo.returnAddressRegister) { @@ -364,8 +380,8 @@ int DwarfInstructions::stepWithDwarf(A &addressSpace, pint_t pc, #endif // Return address is address after call site instruction, so setting IP to - // that does simulates a return. - newRegisters.setIP(returnAddress); + // that does simualates a return. + newRegisters.setIP(returnAddress, returnAddressLocation); // Simulate the step by replacing the register set with the new ones. registers = newRegisters; diff --git a/src/native/external/llvm-libunwind/src/DwarfParser.hpp b/src/native/external/llvm-libunwind/src/DwarfParser.hpp index 0682942ce1379..0407a3dc8615e 100644 --- a/src/native/external/llvm-libunwind/src/DwarfParser.hpp +++ b/src/native/external/llvm-libunwind/src/DwarfParser.hpp @@ -270,7 +270,7 @@ bool CFI_Parser::findFDE(A &addressSpace, pint_t pc, pint_t ehSectionStart, 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)) { + if ((pcStart <= pc) && (pc < pcStart + pcRange)) { // parse rest of info fdeInfo->lsda = 0; // check for augmentation length @@ -451,7 +451,7 @@ bool CFI_Parser::parseFDEInstructions(A &addressSpace, static_cast(instructionsEnd)); // see DWARF Spec, section 6.4.2 for details on unwind opcodes - while ((p < instructionsEnd) && (codeOffset < pcoffset)) { + while ((p < instructionsEnd) && (codeOffset <= pcoffset)) { uint64_t reg; uint64_t reg2; int64_t offset; diff --git a/src/native/external/llvm-libunwind/src/Registers.hpp b/src/native/external/llvm-libunwind/src/Registers.hpp index d11ddb3426d52..4e1d75519ef35 100644 --- a/src/native/external/llvm-libunwind/src/Registers.hpp +++ b/src/native/external/llvm-libunwind/src/Registers.hpp @@ -62,7 +62,8 @@ class _LIBUNWIND_HIDDEN Registers_x86 { bool validRegister(int num) const; uint32_t getRegister(int num) const; - void setRegister(int num, uint32_t value); + void setRegister(int num, uint32_t value, uint32_t location); + uint32_t getRegisterLocation(int num) const; bool validFloatRegister(int) const { return false; } double getFloatRegister(int num) const; void setFloatRegister(int num, double value); @@ -77,21 +78,21 @@ class _LIBUNWIND_HIDDEN Registers_x86 { static int getArch() { return REGISTERS_X86; } uint32_t getSP() const { return _registers.__esp; } - void setSP(uint32_t value) { _registers.__esp = value; } + void setSP(uint32_t value, uint32_t location) { _registers.__esp = value; _registerLocations.__esp = location; } uint32_t getIP() const { return _registers.__eip; } - void setIP(uint32_t value) { _registers.__eip = value; } + void setIP(uint32_t value, uint32_t location) { _registers.__eip = value; _registerLocations.__eip = location; } uint32_t getEBP() const { return _registers.__ebp; } - void setEBP(uint32_t value) { _registers.__ebp = value; } + void setEBP(uint32_t value, uint32_t location) { _registers.__ebp = value; _registerLocations.__ebp = location; } uint32_t getEBX() const { return _registers.__ebx; } - void setEBX(uint32_t value) { _registers.__ebx = value; } + void setEBX(uint32_t value, uint32_t location) { _registers.__ebx = value; _registerLocations.__ebx = location; } uint32_t getECX() const { return _registers.__ecx; } - void setECX(uint32_t value) { _registers.__ecx = value; } + void setECX(uint32_t value, uint32_t location) { _registers.__ecx = value; _registerLocations.__ecx = location; } uint32_t getEDX() const { return _registers.__edx; } - void setEDX(uint32_t value) { _registers.__edx = value; } + void setEDX(uint32_t value, uint32_t location) { _registers.__edx = value; _registerLocations.__edx = location; } uint32_t getESI() const { return _registers.__esi; } - void setESI(uint32_t value) { _registers.__esi = value; } + void setESI(uint32_t value, uint32_t location) { _registers.__esi = value; _registerLocations.__esi = location; } uint32_t getEDI() const { return _registers.__edi; } - void setEDI(uint32_t value) { _registers.__edi = value; } + void setEDI(uint32_t value, uint32_t location) { _registers.__edi = value; _registerLocations.__edi = location; } private: struct GPRs { @@ -112,18 +113,32 @@ class _LIBUNWIND_HIDDEN Registers_x86 { unsigned int __fs; unsigned int __gs; }; + struct GPRLocations { + 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 __eip; + }; GPRs _registers; + GPRLocations _registerLocations; }; inline Registers_x86::Registers_x86(const void *registers) { static_assert((check_fit::does_fit), "x86 registers do not fit into unw_context_t"); memcpy(&_registers, registers, sizeof(_registers)); + memset(&_registerLocations, 0, sizeof(_registerLocations)); } inline Registers_x86::Registers_x86() { memset(&_registers, 0, sizeof(_registers)); + memset(&_registerLocations, 0, sizeof(_registerLocations)); } inline bool Registers_x86::validRegister(int regNum) const { @@ -172,25 +187,31 @@ inline uint32_t Registers_x86::getRegister(int regNum) const { _LIBUNWIND_ABORT("unsupported x86 register"); } -inline void Registers_x86::setRegister(int regNum, uint32_t value) { +inline void Registers_x86::setRegister(int regNum, uint32_t value, uint32_t location) { switch (regNum) { case UNW_REG_IP: _registers.__eip = value; + _registerLocations.__eip = location; return; case UNW_REG_SP: _registers.__esp = value; + _registerLocations.__esp = location; return; case UNW_X86_EAX: _registers.__eax = value; + _registerLocations.__eax = location; return; case UNW_X86_ECX: _registers.__ecx = value; + _registerLocations.__ecx = location; return; case UNW_X86_EDX: _registers.__edx = value; + _registerLocations.__edx = location; return; case UNW_X86_EBX: _registers.__ebx = value; + _registerLocations.__ebx = location; return; #if !defined(__APPLE__) case UNW_X86_ESP: @@ -198,6 +219,7 @@ inline void Registers_x86::setRegister(int regNum, uint32_t value) { case UNW_X86_EBP: #endif _registers.__ebp = value; + _registerLocations.__ebp = location; return; #if !defined(__APPLE__) case UNW_X86_EBP: @@ -205,17 +227,46 @@ inline void Registers_x86::setRegister(int regNum, uint32_t value) { case UNW_X86_ESP: #endif _registers.__esp = value; + _registerLocations.__esp = location; return; case UNW_X86_ESI: _registers.__esi = value; + _registerLocations.__esi = location; return; case UNW_X86_EDI: _registers.__edi = value; + _registerLocations.__edi = location; return; } _LIBUNWIND_ABORT("unsupported x86 register"); } +inline uint32_t Registers_x86::getRegisterLocation(int regNum) const { + switch (regNum) { + case UNW_REG_IP: + return _registerLocations.__eip; + case UNW_REG_SP: + return _registerLocations.__esp; + case UNW_X86_EAX: + return _registerLocations.__eax; + case UNW_X86_ECX: + return _registerLocations.__ecx; + case UNW_X86_EDX: + return _registerLocations.__edx; + case UNW_X86_EBX: + return _registerLocations.__ebx; + case UNW_X86_EBP: + return _registerLocations.__ebp; + case UNW_X86_ESP: + return _registerLocations.__esp; + case UNW_X86_ESI: + return _registerLocations.__esi; + case UNW_X86_EDI: + return _registerLocations.__edi; + } + _LIBUNWIND_ABORT("unsupported x86 register"); +} + inline const char *Registers_x86::getRegisterName(int regNum) { switch (regNum) { case UNW_REG_IP: @@ -280,7 +331,8 @@ class _LIBUNWIND_HIDDEN Registers_x86_64 { bool validRegister(int num) const; uint64_t getRegister(int num) const; - void setRegister(int num, uint64_t value); + void setRegister(int num, uint64_t value, uint64_t location); + uint64_t getRegisterLocation(int num) const; bool validFloatRegister(int) const { return false; } double getFloatRegister(int num) const; void setFloatRegister(int num, double value); @@ -295,21 +347,21 @@ class _LIBUNWIND_HIDDEN Registers_x86_64 { static int getArch() { return REGISTERS_X86_64; } uint64_t getSP() const { return _registers.__rsp; } - void setSP(uint64_t value) { _registers.__rsp = value; } + void setSP(uint64_t value, uint64_t location) { _registers.__rsp = value; _registerLocations.__rsp = location;} uint64_t getIP() const { return _registers.__rip; } - void setIP(uint64_t value) { _registers.__rip = value; } + void setIP(uint64_t value, uint64_t location) { _registers.__rip = value; _registerLocations.__rip = location; } uint64_t getRBP() const { return _registers.__rbp; } - void setRBP(uint64_t value) { _registers.__rbp = value; } + void setRBP(uint64_t value, uint64_t location) { _registers.__rbp = value; _registerLocations.__rbp = location; } uint64_t getRBX() const { return _registers.__rbx; } - void setRBX(uint64_t value) { _registers.__rbx = value; } + void setRBX(uint64_t value, uint64_t location) { _registers.__rbx = value; _registerLocations.__rbx = location; } uint64_t getR12() const { return _registers.__r12; } - void setR12(uint64_t value) { _registers.__r12 = value; } + void setR12(uint64_t value, uint64_t location) { _registers.__r12 = value; _registerLocations.__r12 = location; } uint64_t getR13() const { return _registers.__r13; } - void setR13(uint64_t value) { _registers.__r13 = value; } + void setR13(uint64_t value, uint64_t location) { _registers.__r13 = value; _registerLocations.__r13 = location; } uint64_t getR14() const { return _registers.__r14; } - void setR14(uint64_t value) { _registers.__r14 = value; } + void setR14(uint64_t value, uint64_t location) { _registers.__r14 = value; _registerLocations.__r14 = location; } uint64_t getR15() const { return _registers.__r15; } - void setR15(uint64_t value) { _registers.__r15 = value; } + void setR15(uint64_t value, uint64_t location) { _registers.__r15 = value; _registerLocations.__r15 = location; } private: struct GPRs { @@ -338,7 +390,27 @@ class _LIBUNWIND_HIDDEN Registers_x86_64 { uint64_t __padding; // 16-byte align #endif }; + struct GPRLocations { + 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; + }; GPRs _registers; + GPRLocations _registerLocations; #if defined(_WIN64) v128 _xmm[16]; #endif @@ -348,10 +420,12 @@ inline Registers_x86_64::Registers_x86_64(const void *registers) { static_assert((check_fit::does_fit), "x86_64 registers do not fit into unw_context_t"); memcpy(&_registers, registers, sizeof(_registers)); + memset(&_registerLocations, 0, sizeof(_registerLocations)); } inline Registers_x86_64::Registers_x86_64() { memset(&_registers, 0, sizeof(_registers)); + memset(&_registerLocations, 0, sizeof(_registerLocations)); } inline bool Registers_x86_64::validRegister(int regNum) const { @@ -409,62 +483,122 @@ inline uint64_t Registers_x86_64::getRegister(int regNum) const { _LIBUNWIND_ABORT("unsupported x86_64 register"); } -inline void Registers_x86_64::setRegister(int regNum, uint64_t value) { +inline uint64_t Registers_x86_64::getRegisterLocation(int regNum) const { + switch (regNum) { + case UNW_REG_IP: + return _registerLocations.__rip; + case UNW_REG_SP: + return _registerLocations.__rsp; + case UNW_X86_64_RAX: + return _registerLocations.__rax; + case UNW_X86_64_RDX: + return _registerLocations.__rdx; + case UNW_X86_64_RCX: + return _registerLocations.__rcx; + case UNW_X86_64_RBX: + return _registerLocations.__rbx; + case UNW_X86_64_RSI: + return _registerLocations.__rsi; + case UNW_X86_64_RDI: + return _registerLocations.__rdi; + case UNW_X86_64_RBP: + return _registerLocations.__rbp; + case UNW_X86_64_RSP: + return _registerLocations.__rsp; + case UNW_X86_64_R8: + return _registerLocations.__r8; + case UNW_X86_64_R9: + return _registerLocations.__r9; + case UNW_X86_64_R10: + return _registerLocations.__r10; + case UNW_X86_64_R11: + return _registerLocations.__r11; + case UNW_X86_64_R12: + return _registerLocations.__r12; + case UNW_X86_64_R13: + return _registerLocations.__r13; + case UNW_X86_64_R14: + return _registerLocations.__r14; + case UNW_X86_64_R15: + return _registerLocations.__r15; + } + _LIBUNWIND_ABORT("unsupported x86_64 register"); +} + +inline void Registers_x86_64::setRegister(int regNum, uint64_t value, uint64_t location) { switch (regNum) { case UNW_REG_IP: case UNW_X86_64_RIP: _registers.__rip = value; + _registerLocations.__rip = location; return; case UNW_REG_SP: _registers.__rsp = value; + _registerLocations.__rsp = location; return; case UNW_X86_64_RAX: _registers.__rax = value; + _registerLocations.__rax = location; return; case UNW_X86_64_RDX: _registers.__rdx = value; + _registerLocations.__rdx = location; return; case UNW_X86_64_RCX: _registers.__rcx = value; + _registerLocations.__rcx = location; return; case UNW_X86_64_RBX: _registers.__rbx = value; + _registerLocations.__rbx = location; return; case UNW_X86_64_RSI: _registers.__rsi = value; + _registerLocations.__rsi = location; return; case UNW_X86_64_RDI: _registers.__rdi = value; + _registerLocations.__rdi = location; return; case UNW_X86_64_RBP: _registers.__rbp = value; + _registerLocations.__rbp = location; return; case UNW_X86_64_RSP: _registers.__rsp = value; + _registerLocations.__rsp = location; return; case UNW_X86_64_R8: _registers.__r8 = value; + _registerLocations.__r8 = location; return; case UNW_X86_64_R9: _registers.__r9 = value; + _registerLocations.__r9 = location; return; case UNW_X86_64_R10: _registers.__r10 = value; + _registerLocations.__r10 = location; return; case UNW_X86_64_R11: _registers.__r11 = value; + _registerLocations.__r11 = location; return; case UNW_X86_64_R12: _registers.__r12 = value; + _registerLocations.__r12 = location; return; case UNW_X86_64_R13: _registers.__r13 = value; + _registerLocations.__r13 = location; return; case UNW_X86_64_R14: _registers.__r14 = value; + _registerLocations.__r14 = location; return; case UNW_X86_64_R15: _registers.__r15 = value; + _registerLocations.__r15 = location; return; } _LIBUNWIND_ABORT("unsupported x86_64 register"); @@ -1171,7 +1305,8 @@ class _LIBUNWIND_HIDDEN Registers_ppc64 { bool validRegister(int num) const; uint64_t getRegister(int num) const; - void setRegister(int num, uint64_t value); + void setRegister(int num, uint64_t value, uint64_t location); + uint64_t getRegisterLocation(int num) const; bool validFloatRegister(int num) const; double getFloatRegister(int num) const; void setFloatRegister(int num, double value); @@ -1822,13 +1957,14 @@ class _LIBUNWIND_HIDDEN Registers_arm64 { bool validRegister(int num) const; uint64_t getRegister(int num) const; - void setRegister(int num, uint64_t value); + void setRegister(int num, uint64_t value, uint64_t location); 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); + uint64_t getRegisterLocation(int regNum) const; static const char *getRegisterName(int num); void jumpto() { __libunwind_Registers_arm64_jumpto(this); } static constexpr int lastDwarfRegNum() { @@ -1837,11 +1973,11 @@ class _LIBUNWIND_HIDDEN Registers_arm64 { static int getArch() { return REGISTERS_ARM64; } uint64_t getSP() const { return _registers.__sp; } - void setSP(uint64_t value) { _registers.__sp = value; } + void setSP(uint64_t value, uint64_t location) { _registers.__sp = value; } uint64_t getIP() const { return _registers.__pc; } - void setIP(uint64_t value) { _registers.__pc = value; } + void setIP(uint64_t value, uint64_t location) { _registers.__pc = value; } uint64_t getFP() const { return _registers.__fp; } - void setFP(uint64_t value) { _registers.__fp = value; } + void setFP(uint64_t value, uint64_t location) { _registers.__fp = value; } private: struct GPRs { @@ -1853,7 +1989,17 @@ class _LIBUNWIND_HIDDEN Registers_arm64 { uint64_t __ra_sign_state; // RA sign state register }; + struct GPRLocations { + 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; + GPRLocations _registerLocations; double _vectorHalfRegisters[32]; // Currently only the lower double in 128-bit vectore registers // is perserved during unwinding. We could define new register @@ -1865,7 +2011,9 @@ inline Registers_arm64::Registers_arm64(const void *registers) { static_assert((check_fit::does_fit), "arm64 registers do not fit into unw_context_t"); memcpy(&_registers, registers, sizeof(_registers)); - static_assert(sizeof(GPRs) == 0x110, + memset(&_registerLocations, 0, sizeof(_registerLocations)); + static_assert( + sizeof(GPRs) == 0x110, "expected VFP registers to be at offset 272"); memcpy(_vectorHalfRegisters, static_cast(registers) + sizeof(GPRs), @@ -1874,6 +2022,7 @@ inline Registers_arm64::Registers_arm64(const void *registers) { inline Registers_arm64::Registers_arm64() { memset(&_registers, 0, sizeof(_registers)); + memset(&_registerLocations, 0, sizeof(_registerLocations)); memset(&_vectorHalfRegisters, 0, sizeof(_vectorHalfRegisters)); } @@ -1909,23 +2058,43 @@ inline uint64_t Registers_arm64::getRegister(int regNum) const { _LIBUNWIND_ABORT("unsupported arm64 register"); } -inline void Registers_arm64::setRegister(int regNum, uint64_t value) { - if (regNum == UNW_REG_IP || regNum == UNW_AARCH64_PC) +inline void Registers_arm64::setRegister(int regNum, uint64_t value, uint64_t location) { + if (regNum == UNW_REG_IP || regNum == UNW_AARCH64_PC) { _registers.__pc = value; - else if (regNum == UNW_REG_SP || regNum == UNW_AARCH64_SP) + _registerLocations.__pc = location; + } + else if (regNum == UNW_REG_SP || regNum == UNW_AARCH64_SP) { _registers.__sp = value; + _registerLocations.__sp = location; + } else if (regNum == UNW_AARCH64_RA_SIGN_STATE) _registers.__ra_sign_state = value; - else if (regNum == UNW_AARCH64_FP) + else if (regNum == UNW_AARCH64_FP) { _registers.__fp = value; - else if (regNum == UNW_AARCH64_LR) + _registerLocations.__fp = location; + } + else if (regNum == UNW_AARCH64_LR) { _registers.__lr = value; - else if ((regNum >= 0) && (regNum < 29)) + _registerLocations.__lr = location; + } + else if ((regNum >= 0) && (regNum < 29)) { _registers.__x[regNum] = value; + _registerLocations.__x[regNum] = location; + } else _LIBUNWIND_ABORT("unsupported arm64 register"); } +inline uint64_t Registers_arm64::getRegisterLocation(int regNum) const { + if (regNum == UNW_REG_IP) + return _registerLocations.__pc; + if (regNum == UNW_REG_SP) + return _registerLocations.__sp; + if ((regNum >= 0) && (regNum < 32)) + return _registerLocations.__x[regNum]; + _LIBUNWIND_ABORT("unsupported arm64 register"); +} + inline const char *Registers_arm64::getRegisterName(int regNum) { switch (regNum) { case UNW_REG_IP: @@ -2111,7 +2280,8 @@ class _LIBUNWIND_HIDDEN Registers_arm { bool validRegister(int num) const; uint32_t getRegister(int num) const; - void setRegister(int num, uint32_t value); + void setRegister(int num, uint32_t value, uint32_t location); + uint32_t getRegisterLocation(int num) const; bool validFloatRegister(int num) const; unw_fpreg_t getFloatRegister(int num); void setFloatRegister(int num, unw_fpreg_t value); @@ -2129,9 +2299,9 @@ class _LIBUNWIND_HIDDEN Registers_arm { static int getArch() { return REGISTERS_ARM; } uint32_t getSP() const { return _registers.__sp; } - void setSP(uint32_t value) { _registers.__sp = value; } + void setSP(uint32_t value, uint32_t location) { _registers.__sp = value; _registerLocations.__sp = location; } uint32_t getIP() const { return _registers.__pc; } - void setIP(uint32_t value) { _registers.__pc = value; } + void setIP(uint32_t value, uint32_t location) { _registers.__pc = value; _registerLocations.__pc = location; } void saveVFPAsX() { assert(_use_X_for_vfp_save || !_saved_vfp_d0_d15); @@ -2168,6 +2338,14 @@ class _LIBUNWIND_HIDDEN Registers_arm { }; static void saveVFPWithFSTMD(void*); + + struct GPRLocations { + 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 saveVFPWithFSTMX(void*); static void saveVFPv3(void*); static void restoreVFPWithFLDMD(void*); @@ -2184,6 +2362,7 @@ class _LIBUNWIND_HIDDEN Registers_arm { // ARM registers GPRs _registers; PseudoRegisters _pseudo_registers; + GPRLocations _registerLocations; // We save floating point registers lazily because we can't know ahead of // time which ones are used. See EHABI #4.7. @@ -2222,6 +2401,7 @@ inline Registers_arm::Registers_arm(const void *registers) // See __unw_getcontext() note about data. memcpy(&_registers, registers, sizeof(_registers)); memset(&_pseudo_registers, 0, sizeof(_pseudo_registers)); + memset(&_registerLocations, 0, sizeof(_registerLocations)); memset(&_vfp_d0_d15_pad, 0, sizeof(_vfp_d0_d15_pad)); memset(&_vfp_d16_d31, 0, sizeof(_vfp_d16_d31)); #if defined(__ARM_WMMX) @@ -2238,6 +2418,7 @@ inline Registers_arm::Registers_arm() _saved_vfp_d16_d31(false) { memset(&_registers, 0, sizeof(_registers)); memset(&_pseudo_registers, 0, sizeof(_pseudo_registers)); + memset(&_registerLocations, 0, sizeof(_registerLocations)); memset(&_vfp_d0_d15_pad, 0, sizeof(_vfp_d0_d15_pad)); memset(&_vfp_d16_d31, 0, sizeof(_vfp_d16_d31)); #if defined(__ARM_WMMX) @@ -2304,24 +2485,28 @@ inline uint32_t Registers_arm::getRegister(int regNum) const { _LIBUNWIND_ABORT("unsupported arm register"); } -inline void Registers_arm::setRegister(int regNum, uint32_t value) { +inline void Registers_arm::setRegister(int regNum, uint32_t value, uint32_t location) { if (regNum == UNW_REG_SP || regNum == UNW_ARM_SP) { _registers.__sp = value; + _registerLocations.__sp = location; return; } if (regNum == UNW_ARM_LR) { _registers.__lr = value; + _registerLocations.__lr = location; return; } if (regNum == UNW_REG_IP || regNum == UNW_ARM_IP) { _registers.__pc = value; + _registerLocations.__pc = location; return; } if (regNum >= UNW_ARM_R0 && regNum <= UNW_ARM_R12) { _registers.__r[regNum] = value; + _registerLocations.__r[regNum] = location; return; } @@ -2344,6 +2529,22 @@ inline void Registers_arm::setRegister(int regNum, uint32_t value) { _LIBUNWIND_ABORT("unsupported arm register"); } +inline uint32_t Registers_arm::getRegisterLocation(int regNum) const { + if (regNum == UNW_REG_SP || regNum == UNW_ARM_SP) + return _registerLocations.__sp; + + if (regNum == UNW_ARM_LR) + return _registerLocations.__lr; + + if (regNum == UNW_REG_IP || regNum == UNW_ARM_IP) + return _registerLocations.__pc; + + if (regNum >= UNW_ARM_R0 && regNum <= UNW_ARM_R12) + return _registerLocations.__r[regNum]; + + _LIBUNWIND_ABORT("unsupported arm register"); +} + inline const char *Registers_arm::getRegisterName(int regNum) { switch (regNum) { case UNW_REG_IP: diff --git a/src/native/external/llvm-libunwind/src/Unwind-EHABI.cpp b/src/native/external/llvm-libunwind/src/Unwind-EHABI.cpp index 05475c6ac1e2f..338c853bca780 100644 --- a/src/native/external/llvm-libunwind/src/Unwind-EHABI.cpp +++ b/src/native/external/llvm-libunwind/src/Unwind-EHABI.cpp @@ -228,7 +228,7 @@ decode_eht_entry(const uint32_t* data, size_t* off, size_t* len) { // 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. + // personality routine 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. @@ -271,7 +271,7 @@ _Unwind_VRS_Interpret(_Unwind_Context *context, const uint32_t *data, 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); + _Unwind_VRS_Set(context, _UVRSC_CORE, UNW_ARM_SP, _UVRSD_UINT32, &sp, NULL); } else { switch (byte & 0xf0) { case 0x80: { @@ -295,7 +295,7 @@ _Unwind_VRS_Interpret(_Unwind_Context *context, const uint32_t *data, _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); + &sp, NULL); break; } case 0xa0: { @@ -337,7 +337,7 @@ _Unwind_VRS_Interpret(_Unwind_Context *context, const uint32_t *data, &sp); sp += 0x204 + (addend << 2); _Unwind_VRS_Set(context, _UVRSC_CORE, UNW_ARM_SP, _UVRSD_UINT32, - &sp); + &sp, NULL); break; } case 0xb3: { @@ -438,7 +438,7 @@ _Unwind_VRS_Interpret(_Unwind_Context *context, const uint32_t *data, #else (void)hasReturnAddrAuthCode; #endif - _Unwind_VRS_Set(context, _UVRSC_CORE, UNW_ARM_IP, _UVRSD_UINT32, &lr); + _Unwind_VRS_Set(context, _UVRSC_CORE, UNW_ARM_IP, _UVRSD_UINT32, &lr, NULL); } return _URC_CONTINUE_UNWIND; } @@ -589,7 +589,7 @@ static _Unwind_Reason_Code unwind_phase2(unw_context_t *uc, unw_cursor_t *cursor // // See #7.4.6 for details. __unw_set_reg(cursor, UNW_REG_IP, - exception_object->unwinder_cache.reserved2); + exception_object->unwinder_cache.reserved2, NULL); resume = false; } @@ -909,7 +909,7 @@ ValueAsBitPattern(_Unwind_VRS_DataRepresentation representation, _LIBUNWIND_EXPORT _Unwind_VRS_Result _Unwind_VRS_Set(_Unwind_Context *context, _Unwind_VRS_RegClass regclass, uint32_t regno, _Unwind_VRS_DataRepresentation representation, - void *valuep) { + void *valuep, unw_word_t *pos) { _LIBUNWIND_TRACE_API("_Unwind_VRS_Set(context=%p, regclass=%d, reg=%d, " "rep=%d, value=0x%llX)", static_cast(context), regclass, regno, @@ -921,7 +921,7 @@ _Unwind_VRS_Set(_Unwind_Context *context, _Unwind_VRS_RegClass regclass, 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 + *(unw_word_t *)valuep,(unw_word_t *)pos) == UNW_ESUCCESS ? _UVRSR_OK : _UVRSR_FAILED; case _UVRSC_VFP: @@ -965,7 +965,7 @@ _Unwind_VRS_Set(_Unwind_Context *context, _Unwind_VRS_RegClass regclass, if (representation != _UVRSD_UINT32 || regno != 0) return _UVRSR_FAILED; return __unw_set_reg(cursor, (unw_regnum_t)(UNW_ARM_RA_AUTH_CODE), - *(unw_word_t *)valuep) == UNW_ESUCCESS + *(unw_word_t *)valuep, NULL) == UNW_ESUCCESS ? _UVRSR_OK : _UVRSR_FAILED; break; @@ -1071,6 +1071,7 @@ _Unwind_VRS_Pop(_Unwind_Context *context, _Unwind_VRS_RegClass regclass, // computed new stack location. See EHABI #7.5.4 table 3. bool poppedSP = false; uint32_t* sp; + uint32_t* pos; if (_Unwind_VRS_Get(context, _UVRSC_CORE, UNW_ARM_SP, _UVRSD_UINT32, &sp) != _UVRSR_OK) { return _UVRSR_FAILED; @@ -1078,17 +1079,18 @@ _Unwind_VRS_Pop(_Unwind_Context *context, _Unwind_VRS_RegClass regclass, for (uint32_t i = 0; i < 16; ++i) { if (!(discriminator & static_cast(1 << i))) continue; + pos = sp; uint32_t value = *sp++; if (regclass == _UVRSC_CORE && i == 13) poppedSP = true; if (_Unwind_VRS_Set(context, regclass, i, - _UVRSD_UINT32, &value) != _UVRSR_OK) { + _UVRSD_UINT32, &value, pos) != _UVRSR_OK) { return _UVRSR_FAILED; } } if (!poppedSP) { return _Unwind_VRS_Set(context, _UVRSC_CORE, UNW_ARM_SP, - _UVRSD_UINT32, &sp); + _UVRSD_UINT32, &sp, NULL); } return _UVRSR_OK; } @@ -1120,14 +1122,14 @@ _Unwind_VRS_Pop(_Unwind_Context *context, _Unwind_VRS_RegClass regclass, #else #error "Unable to determine endianess" #endif - if (_Unwind_VRS_Set(context, regclass, i, representation, &value) != + if (_Unwind_VRS_Set(context, regclass, i, representation, &value, NULL) != _UVRSR_OK) return _UVRSR_FAILED; } if (representation == _UVRSD_VFPX) ++sp; return _Unwind_VRS_Set(context, _UVRSC_CORE, UNW_ARM_SP, _UVRSD_UINT32, - &sp); + &sp, NULL); } case _UVRSC_PSEUDO: { if (representation != _UVRSD_UINT32 || discriminator != 0) @@ -1139,8 +1141,8 @@ _Unwind_VRS_Pop(_Unwind_Context *context, _Unwind_VRS_RegClass regclass, return _UVRSR_FAILED; } uint32_t pac = *sp++; - _Unwind_VRS_Set(context, _UVRSC_CORE, UNW_ARM_SP, _UVRSD_UINT32, &sp); - return _Unwind_VRS_Set(context, _UVRSC_PSEUDO, 0, _UVRSD_UINT32, &pac); + _Unwind_VRS_Set(context, _UVRSC_CORE, UNW_ARM_SP, _UVRSD_UINT32, &sp, NULL); + return _Unwind_VRS_Set(context, _UVRSC_PSEUDO, 0, _UVRSD_UINT32, &pac, NULL); } } _LIBUNWIND_ABORT("unsupported register class"); diff --git a/src/native/external/llvm-libunwind/src/UnwindCursor.hpp b/src/native/external/llvm-libunwind/src/UnwindCursor.hpp index 7753936a5894a..606ba0b0a8d31 100644 --- a/src/native/external/llvm-libunwind/src/UnwindCursor.hpp +++ b/src/native/external/llvm-libunwind/src/UnwindCursor.hpp @@ -433,9 +433,12 @@ class _LIBUNWIND_HIDDEN AbstractUnwindCursor { 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) { + virtual void setReg(int, unw_word_t, unw_word_t) { _LIBUNWIND_ABORT("setReg not implemented"); } + virtual unw_word_t getRegLocation(int) { + _LIBUNWIND_ABORT("getRegLocation not implemented"); + } virtual bool validFloatReg(int) { _LIBUNWIND_ABORT("validFloatReg not implemented"); } @@ -931,12 +934,14 @@ template class UnwindCursor : public AbstractUnwindCursor{ typedef typename A::pint_t pint_t; public: + UnwindCursor(A &as); 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 void setReg(int, unw_word_t, unw_word_t); + virtual unw_word_t getRegLocation(int); virtual bool validFloatReg(int); virtual unw_fpreg_t getFloatReg(int); virtual void setFloatReg(int, unw_fpreg_t); @@ -966,6 +971,7 @@ class UnwindCursor : public AbstractUnwindCursor{ private: #if defined(_LIBUNWIND_ARM_EHABI) +public: bool getInfoFromEHABISection(pint_t pc, const UnwindInfoSections §s); int stepWithEHABI() { @@ -1017,6 +1023,8 @@ class UnwindCursor : public AbstractUnwindCursor{ bool getInfoFromFdeCie(const typename CFI_Parser::FDE_Info &fdeInfo, const typename CFI_Parser::CIE_Info &cieInfo, pint_t pc, uintptr_t dso_base); + +public: bool getInfoFromDwarfSection(pint_t pc, const UnwindInfoSections §s, uint32_t fdeSectionOffsetHint=0); int stepWithDwarfFDE(bool stage2) { @@ -1319,6 +1327,13 @@ class UnwindCursor : public AbstractUnwindCursor{ #endif }; +template +UnwindCursor::UnwindCursor(A &as) + : _addressSpace(as) + , _unwindInfoMissing(false) + , _isSignalFrame(false) { + memset(&_info, 0, sizeof(_info)); +} template UnwindCursor::UnwindCursor(unw_context_t *context, A &as) @@ -1332,9 +1347,11 @@ UnwindCursor::UnwindCursor(unw_context_t *context, A &as) } template -UnwindCursor::UnwindCursor(A &as, void *) - : _addressSpace(as), _unwindInfoMissing(false), _isSignalFrame(false) { +UnwindCursor::UnwindCursor(A &as, void *arg) + : _addressSpace(as),_registers(arg), _unwindInfoMissing(false), + _isSignalFrame(false) { memset(&_info, 0, sizeof(_info)); + // FIXME // fill in _registers from thread arg } @@ -1351,8 +1368,13 @@ unw_word_t UnwindCursor::getReg(int regNum) { } template -void UnwindCursor::setReg(int regNum, unw_word_t value) { - _registers.setRegister(regNum, (typename A::pint_t)value); +void UnwindCursor::setReg(int regNum, unw_word_t value, unw_word_t location) { + _registers.setRegister(regNum, (typename A::pint_t)value, (typename A::pint_t)location); +} + +template +unw_word_t UnwindCursor::getRegLocation(int regNum) { + return _registers.getRegisterLocation(regNum); } template @@ -1659,6 +1681,7 @@ bool UnwindCursor::getInfoFromDwarfSection(pint_t pc, typename CFI_Parser::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::findFDE(_addressSpace, pc, sects.dwarf_section, @@ -1666,6 +1689,7 @@ bool UnwindCursor::getInfoFromDwarfSection(pint_t pc, sects.dwarf_section + fdeSectionOffsetHint, &fdeInfo, &cieInfo); } + #if defined(_LIBUNWIND_SUPPORT_DWARF_INDEX) if (!foundFDE && (sects.dwarf_index_section != 0)) { foundFDE = EHHeaderParser::findFDE( @@ -1673,6 +1697,7 @@ bool UnwindCursor::getInfoFromDwarfSection(pint_t pc, (uint32_t)sects.dwarf_index_section_length, &fdeInfo, &cieInfo); } #endif + if (!foundFDE) { // otherwise, search cache of previously found FDEs. pint_t cachedFDE = DwarfFDECache::findFDE(sects.dso_base, pc); @@ -2742,10 +2767,10 @@ int UnwindCursor::stepThroughSigReturn(Registers_arm64 &) { for (int i = 0; i <= 30; ++i) { uint64_t value = _addressSpace.get64(sigctx + kOffsetGprs + static_cast(i * 8)); - _registers.setRegister(UNW_AARCH64_X0 + i, value); + _registers.setRegister(UNW_AARCH64_X0 + i, value, 0); } - _registers.setSP(_addressSpace.get64(sigctx + kOffsetSp)); - _registers.setIP(_addressSpace.get64(sigctx + kOffsetPc)); + _registers.setSP(_addressSpace.get64(sigctx + kOffsetSp), 0); + _registers.setIP(_addressSpace.get64(sigctx + kOffsetPc), 0); _isSignalFrame = true; return UNW_STEP_SUCCESS; } diff --git a/src/native/external/llvm-libunwind/src/UnwindRegistersRestore.S b/src/native/external/llvm-libunwind/src/UnwindRegistersRestore.S index 42c2488fc7cf7..60cb3bfbba082 100644 --- a/src/native/external/llvm-libunwind/src/UnwindRegistersRestore.S +++ b/src/native/external/llvm-libunwind/src/UnwindRegistersRestore.S @@ -645,8 +645,7 @@ DEFINE_LIBUNWIND_FUNCTION(__libunwind_Registers_arm64_jumpto) ldp x10,x11, [x0, #0x050] ldp x12,x13, [x0, #0x060] ldp x14,x15, [x0, #0x070] - // x16 and x17 were clobbered by the call into the unwinder, so no point in - // restoring them. + ldp x16,x17, [x0, #0x080] ldp x18,x19, [x0, #0x090] ldp x20,x21, [x0, #0x0A0] ldp x22,x23, [x0, #0x0B0] @@ -654,6 +653,8 @@ DEFINE_LIBUNWIND_FUNCTION(__libunwind_Registers_arm64_jumpto) 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] @@ -673,13 +674,7 @@ DEFINE_LIBUNWIND_FUNCTION(__libunwind_Registers_arm64_jumpto) ldr d30, [x0, #0x200] ldr d31, [x0, #0x208] - // Finally, restore sp. This must be done after the last read from the - // context struct, because it is allocated on the stack, and an exception - // could clobber the de-allocated portion of the stack after sp has been - // restored. - ldr x16, [x0, #0x0F8] ldp x0, x1, [x0, #0x000] // restore x0,x1 - mov sp,x16 // restore sp ret x30 // jump to pc #elif defined(__arm__) && !defined(__APPLE__) diff --git a/src/native/external/llvm-libunwind/src/libunwind.cpp b/src/native/external/llvm-libunwind/src/libunwind.cpp index 217dde9098637..96e4343a2cc67 100644 --- a/src/native/external/llvm-libunwind/src/libunwind.cpp +++ b/src/native/external/llvm-libunwind/src/libunwind.cpp @@ -111,14 +111,14 @@ _LIBUNWIND_WEAK_ALIAS(__unw_get_reg, unw_get_reg) /// Set value of specified register at cursor position in stack frame. _LIBUNWIND_HIDDEN int __unw_set_reg(unw_cursor_t *cursor, unw_regnum_t regNum, - unw_word_t value) { + unw_word_t value, unw_word_t *pos) { _LIBUNWIND_TRACE_API("__unw_set_reg(cursor=%p, regNum=%d, value=0x%" PRIxPTR ")", static_cast(cursor), regNum, value); typedef LocalAddressSpace::pint_t pint_t; AbstractUnwindCursor *co = (AbstractUnwindCursor *)cursor; if (co->validReg(regNum)) { - co->setReg(regNum, (pint_t)value); + co->setReg(regNum, (pint_t)value, (pint_t)pos); // special case altering IP to re-find info (being called by personality // function) if (regNum == UNW_REG_IP) { @@ -133,7 +133,7 @@ _LIBUNWIND_HIDDEN int __unw_set_reg(unw_cursor_t *cursor, unw_regnum_t regNum, // this should actually be - info.gp. LLVM doesn't currently support // any such platforms and Clang doesn't export a macro for them. if (info.gp) - co->setReg(UNW_REG_SP, co->getReg(UNW_REG_SP) + info.gp); + co->setReg(UNW_REG_SP, co->getReg(UNW_REG_SP) + info.gp, 0); } return UNW_ESUCCESS; } @@ -175,6 +175,21 @@ _LIBUNWIND_HIDDEN int __unw_set_fpreg(unw_cursor_t *cursor, unw_regnum_t regNum, } _LIBUNWIND_WEAK_ALIAS(__unw_set_fpreg, unw_set_fpreg) +/// Get location of specified register at cursor position in stack frame. +_LIBUNWIND_HIDDEN int __unw_get_save_loc(unw_cursor_t *cursor, int regNum, + unw_save_loc_t* location) +{ + AbstractUnwindCursor *co = (AbstractUnwindCursor *)cursor; + if (co->validReg(regNum)) { + // We only support memory locations, not register locations + location->u.addr = co->getRegLocation(regNum); + location->type = (location->u.addr == 0) ? UNW_SLT_NONE : UNW_SLT_MEMORY; + return UNW_ESUCCESS; + } + return UNW_EBADREG; +} +_LIBUNWIND_WEAK_ALIAS(__unw_get_save_loc, unw_get_save_loc) + /// Move cursor to next frame. _LIBUNWIND_HIDDEN int __unw_step(unw_cursor_t *cursor) { _LIBUNWIND_TRACE_API("__unw_step(cursor=%p)", static_cast(cursor)); diff --git a/src/native/external/llvm-libunwind/src/libunwind_ext.h b/src/native/external/llvm-libunwind/src/libunwind_ext.h index 28db43a4f6eef..db55939971264 100644 --- a/src/native/external/llvm-libunwind/src/libunwind_ext.h +++ b/src/native/external/llvm-libunwind/src/libunwind_ext.h @@ -28,7 +28,7 @@ extern int __unw_init_local(unw_cursor_t *, unw_context_t *); extern int __unw_step(unw_cursor_t *); extern int __unw_get_reg(unw_cursor_t *, unw_regnum_t, unw_word_t *); extern int __unw_get_fpreg(unw_cursor_t *, unw_regnum_t, unw_fpreg_t *); -extern int __unw_set_reg(unw_cursor_t *, unw_regnum_t, unw_word_t); +extern int __unw_set_reg(unw_cursor_t *, unw_regnum_t, unw_word_t, unw_word_t *); extern int __unw_set_fpreg(unw_cursor_t *, unw_regnum_t, unw_fpreg_t); extern int __unw_resume(unw_cursor_t *); @@ -42,6 +42,7 @@ extern int __unw_get_proc_info(unw_cursor_t *, unw_proc_info_t *); extern int __unw_is_fpreg(unw_cursor_t *, unw_regnum_t); extern int __unw_is_signal_frame(unw_cursor_t *); extern int __unw_get_proc_name(unw_cursor_t *, char *, size_t, unw_word_t *); +extern int __unw_get_save_loc(unw_cursor_t *, int, unw_save_loc_t *); #if defined(_AIX) extern uintptr_t __unw_get_data_rel_base(unw_cursor_t *); From 74033b9b5ce25b39128d2977aaab7121133cf8f4 Mon Sep 17 00:00:00 2001 From: Adeel <3840695+am11@users.noreply.github.com> Date: Wed, 15 May 2024 02:16:24 +0300 Subject: [PATCH 3/3] Update version file --- src/native/external/llvm-libunwind-version.txt | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/native/external/llvm-libunwind-version.txt b/src/native/external/llvm-libunwind-version.txt index d23999cc45368..f833dd0c83fb5 100644 --- a/src/native/external/llvm-libunwind-version.txt +++ b/src/native/external/llvm-libunwind-version.txt @@ -1,6 +1,5 @@ -v16.0.2 -https://github.com/llvm/llvm-project/releases/tag/llvmorg-16.0.2 +v18.1.5 +https://github.com/llvm/llvm-project/releases/tag/llvmorg-18.1.5 -Apply https://github.com/dotnet/runtime/commit/1bafb60792b91747d9c2a9dd38461cf090a987a4 -Apply https://github.com/dotnet/runtime/commit/0ee8827547405408b37d1aae2a83629c1632eea8 +Apply https://github.com/dotnet/runtime/commit/a53805790a49f5bf52776dc81c1c83ec7f21ebce