diff --git a/contrib/subrepo-cheri-libunwind/.gitrepo b/contrib/subrepo-cheri-libunwind/.gitrepo index 4806d7582818..db48ed03732b 100644 --- a/contrib/subrepo-cheri-libunwind/.gitrepo +++ b/contrib/subrepo-cheri-libunwind/.gitrepo @@ -6,7 +6,7 @@ [subrepo] remote = https://github.com/CTSRD-CHERI/libunwind.git branch = monorepo-mirror - commit = 1629fed8d5bf09a4070fcabf7197b697b057def6 - parent = 4fb798db6aed1502b7be28cc84a7bd78f261cb6c + commit = f35d76de2f37a7d7dd9448ddb9f31494898eb2dc + parent = c2ec382ceb2a4d744e34d42a296bb72c9a308963 method = rebase - cmdver = 0.4.1 + cmdver = 0.4.9 diff --git a/contrib/subrepo-cheri-libunwind/CMakeLists.txt b/contrib/subrepo-cheri-libunwind/CMakeLists.txt index cbc19cdaa6dc..2593f0e951f8 100644 --- a/contrib/subrepo-cheri-libunwind/CMakeLists.txt +++ b/contrib/subrepo-cheri-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" ) @@ -49,7 +50,7 @@ option(LIBUNWIND_INCLUDE_TESTS "Build the libunwind tests." ${LLVM_INCLUDE_TESTS 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." OFF) +option(LIBUNWIND_INSTALL_HEADERS "Install the libunwind headers." ON) set(LIBUNWIND_LIBDIR_SUFFIX "${LLVM_LIBDIR_SUFFIX}" CACHE STRING "Define suffix of library directory name (32/64)") @@ -60,10 +61,6 @@ cmake_dependent_option(LIBUNWIND_INSTALL_STATIC_LIBRARY cmake_dependent_option(LIBUNWIND_INSTALL_SHARED_LIBRARY "Install the shared libunwind library." ON "LIBUNWIND_ENABLE_SHARED;LIBUNWIND_INSTALL_LIBRARY" OFF) -set(LIBUNWIND_TEST_LINKER_FLAGS "" CACHE STRING - "Additional linker flags for test programs.") -set(LIBUNWIND_TEST_COMPILER_FLAGS "" CACHE STRING - "Additional compiler flags for test programs.") option(LIBUNWIND_TEST_ENABLE_EXCEPTIONS "Also include tests requiring C++ exceptions." ON) set(LIBUNWIND_TEST_CXX_ABI_LIB_PATH "" CACHE PATH "Path to the C++ ABI library to use for testing.") set(CXXABIS none default libcxxabi libcxxrt libstdc++ libsupc++ vcruntime) @@ -76,7 +73,9 @@ 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") @@ -125,6 +124,9 @@ set(LIBUNWIND_INSTALL_INCLUDE_DIR "${CMAKE_INSTALL_INCLUDEDIR}" CACHE PATH set(LIBUNWIND_INSTALL_RUNTIME_DIR "${CMAKE_INSTALL_BINDIR}" CACHE PATH "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.") +set(LIBUNWIND_STATIC_OUTPUT_NAME "unwind" CACHE STRING "Output name for the static libunwind runtime library.") + 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 @@ -151,6 +153,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) @@ -171,36 +177,14 @@ add_compile_flags_if_supported(-Werror=return-type) if (LIBUNWIND_ENABLE_CET) add_compile_flags_if_supported(-fcf-protection=full) add_compile_flags_if_supported(-mshstk) - if (NOT LIBUNWIND_SUPPORTS_FCF_PROTECTION_EQ_FULL_FLAG) + if (NOT CXX_SUPPORTS_FCF_PROTECTION_EQ_FULL_FLAG) message(SEND_ERROR "Compiler doesn't support CET -fcf-protection option!") endif() - if (NOT LIBUNWIND_SUPPORTS_MSHSTK_FLAG) + if (NOT CXX_SUPPORTS_MSHSTK_FLAG) message(SEND_ERROR "Compiler doesn't support CET -mshstk option!") 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 @@ -209,18 +193,6 @@ 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) -endif() - # Get feature flags. # Exceptions # Catches C++ exceptions only and tells the compiler to assume that extern C diff --git a/contrib/subrepo-cheri-libunwind/cmake/Modules/HandleLibunwindFlags.cmake b/contrib/subrepo-cheri-libunwind/cmake/Modules/HandleLibunwindFlags.cmake index c5d76034d870..94c676338821 100644 --- a/contrib/subrepo-cheri-libunwind/cmake/Modules/HandleLibunwindFlags.cmake +++ b/contrib/subrepo-cheri-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/contrib/subrepo-cheri-libunwind/cmake/config-ix.cmake b/contrib/subrepo-cheri-libunwind/cmake/config-ix.cmake index c2e17c6851f5..8170be0846d9 100644 --- a/contrib/subrepo-cheri-libunwind/cmake/config-ix.cmake +++ b/contrib/subrepo-cheri-libunwind/cmake/config-ix.cmake @@ -31,7 +31,7 @@ endif() # required for the link to go through. We remove sanitizers from the # configuration checks to avoid spurious link errors. -llvm_check_compiler_linker_flag(C "-nostdlib++" CXX_SUPPORTS_NOSTDLIBXX_FLAG) +llvm_check_compiler_linker_flag(CXX "-nostdlib++" CXX_SUPPORTS_NOSTDLIBXX_FLAG) if (CXX_SUPPORTS_NOSTDLIBXX_FLAG) set(CMAKE_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS} -nostdlib++") else() @@ -85,7 +85,7 @@ if(CMAKE_CXX_COMPILER_ID MATCHES "Clang") set(CMAKE_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS} -Werror=unknown-pragmas") check_c_source_compiles(" #pragma comment(lib, \"c\") -int main() { return 0; } +int main(void) { return 0; } " C_SUPPORTS_COMMENT_LIB_PRAGMA) cmake_pop_check_state() endif() diff --git a/contrib/subrepo-cheri-libunwind/docs/conf.py b/contrib/subrepo-cheri-libunwind/docs/conf.py index 21f1b011723b..29f9c24a7ee2 100644 --- a/contrib/subrepo-cheri-libunwind/docs/conf.py +++ b/contrib/subrepo-cheri-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 = '15.0' +version = "17.0" # The full version, including alpha/beta/rc tags. -release = '15.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,22 +221,28 @@ # (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 configration. +# FIXME: Define intersphinx configuration. intersphinx_mapping = {} diff --git a/contrib/subrepo-cheri-libunwind/docs/index.rst b/contrib/subrepo-cheri-libunwind/docs/index.rst index a8315299386d..7126d02abd29 100644 --- a/contrib/subrepo-cheri-libunwind/docs/index.rst +++ b/contrib/subrepo-cheri-libunwind/docs/index.rst @@ -96,7 +96,7 @@ Quick Links =========== * `LLVM Homepage `_ * `LLVM Bug Tracker `_ -* `cfe-dev Mailing List `_ +* `Clang Discourse Forums `_ * `cfe-commits Mailing List `_ * `Runtimes Forum `_ * `Browse libunwind Sources `_ diff --git a/contrib/subrepo-cheri-libunwind/include/CMakeLists.txt b/contrib/subrepo-cheri-libunwind/include/CMakeLists.txt index adf1766c44cb..51065d68afd4 100644 --- a/contrib/subrepo-cheri-libunwind/include/CMakeLists.txt +++ b/contrib/subrepo-cheri-libunwind/include/CMakeLists.txt @@ -1,7 +1,9 @@ set(files __libunwind_config.h libunwind.h + libunwind.modulemap mach-o/compact_unwind_encoding.h + mach-o/compact_unwind_encoding.modulemap unwind_arm_ehabi.h unwind_itanium.h unwind.h diff --git a/contrib/subrepo-cheri-libunwind/include/__libunwind_config.h b/contrib/subrepo-cheri-libunwind/include/__libunwind_config.h index cc14c084072c..0e7fe9899694 100644 --- a/contrib/subrepo-cheri-libunwind/include/__libunwind_config.h +++ b/contrib/subrepo-cheri-libunwind/include/__libunwind_config.h @@ -32,6 +32,7 @@ #define _LIBUNWIND_HIGHEST_DWARF_REGISTER_RISCV 64 #define _LIBUNWIND_HIGHEST_DWARF_REGISTER_VE 143 #define _LIBUNWIND_HIGHEST_DWARF_REGISTER_S390X 83 +#define _LIBUNWIND_HIGHEST_DWARF_REGISTER_LOONGARCH 64 #define _LIBUNWIND_MAX_CONTEXT_SIZE 200 #define _LIBUNWIND_MAX_CURSOR_SIZE 248 @@ -210,6 +211,16 @@ # define _LIBUNWIND_CONTEXT_SIZE 34 # define _LIBUNWIND_CURSOR_SIZE 46 # define _LIBUNWIND_HIGHEST_DWARF_REGISTER _LIBUNWIND_HIGHEST_DWARF_REGISTER_S390X +#elif defined(__loongarch__) +#define _LIBUNWIND_TARGET_LOONGARCH 1 +#if __loongarch_grlen == 64 +#define _LIBUNWIND_CONTEXT_SIZE 65 +#define _LIBUNWIND_CURSOR_SIZE 77 +#else +#error "Unsupported LoongArch ABI" +#endif +#define _LIBUNWIND_HIGHEST_DWARF_REGISTER \ + _LIBUNWIND_HIGHEST_DWARF_REGISTER_LOONGARCH # else # error "Unsupported architecture." # endif @@ -230,6 +241,7 @@ # define _LIBUNWIND_TARGET_RISCV 1 # define _LIBUNWIND_TARGET_VE 1 # define _LIBUNWIND_TARGET_S390X 1 + #define _LIBUNWIND_TARGET_LOONGARCH 1 # define _LIBUNWIND_CONTEXT_SIZE _LIBUNWIND_MAX_CONTEXT_SIZE # define _LIBUNWIND_CURSOR_SIZE _LIBUNWIND_MAX_CURSOR_SIZE # define _LIBUNWIND_HIGHEST_DWARF_REGISTER 287 diff --git a/contrib/subrepo-cheri-libunwind/include/libunwind.h b/contrib/subrepo-cheri-libunwind/include/libunwind.h index 951cf560ca0e..530596552637 100644 --- a/contrib/subrepo-cheri-libunwind/include/libunwind.h +++ b/contrib/subrepo-cheri-libunwind/include/libunwind.h @@ -1099,6 +1099,16 @@ enum { UNW_RISCV_F29 = 61, UNW_RISCV_F30 = 62, UNW_RISCV_F31 = 63, + // 65-95 -- Reserved for future standard extensions + // 96-127 -- v0-v31 (Vector registers) + // 128-3071 -- Reserved for future standard extensions + // 3072-4095 -- Reserved for custom extensions + // 4096-8191 -- CSRs + // + // VLENB CSR number: 0xC22 -- defined by section 3 of v-spec: + // https://github.com/riscv/riscv-v-spec/blob/master/v-spec.adoc#3-vector-extension-programmers-model + // VLENB DWARF number: 0x1000 + 0xC22 + UNW_RISCV_VLENB = 0x1C22, }; // VE register numbers @@ -1295,4 +1305,72 @@ enum { // 68-83 Vector Registers %v16-%v31 }; +// LoongArch registers. +enum { + UNW_LOONGARCH_R0 = 0, + UNW_LOONGARCH_R1 = 1, + UNW_LOONGARCH_R2 = 2, + UNW_LOONGARCH_R3 = 3, + UNW_LOONGARCH_R4 = 4, + UNW_LOONGARCH_R5 = 5, + UNW_LOONGARCH_R6 = 6, + UNW_LOONGARCH_R7 = 7, + UNW_LOONGARCH_R8 = 8, + UNW_LOONGARCH_R9 = 9, + UNW_LOONGARCH_R10 = 10, + UNW_LOONGARCH_R11 = 11, + UNW_LOONGARCH_R12 = 12, + UNW_LOONGARCH_R13 = 13, + UNW_LOONGARCH_R14 = 14, + UNW_LOONGARCH_R15 = 15, + UNW_LOONGARCH_R16 = 16, + UNW_LOONGARCH_R17 = 17, + UNW_LOONGARCH_R18 = 18, + UNW_LOONGARCH_R19 = 19, + UNW_LOONGARCH_R20 = 20, + UNW_LOONGARCH_R21 = 21, + UNW_LOONGARCH_R22 = 22, + UNW_LOONGARCH_R23 = 23, + UNW_LOONGARCH_R24 = 24, + UNW_LOONGARCH_R25 = 25, + UNW_LOONGARCH_R26 = 26, + UNW_LOONGARCH_R27 = 27, + UNW_LOONGARCH_R28 = 28, + UNW_LOONGARCH_R29 = 29, + UNW_LOONGARCH_R30 = 30, + UNW_LOONGARCH_R31 = 31, + UNW_LOONGARCH_F0 = 32, + UNW_LOONGARCH_F1 = 33, + UNW_LOONGARCH_F2 = 34, + UNW_LOONGARCH_F3 = 35, + UNW_LOONGARCH_F4 = 36, + UNW_LOONGARCH_F5 = 37, + UNW_LOONGARCH_F6 = 38, + UNW_LOONGARCH_F7 = 39, + UNW_LOONGARCH_F8 = 40, + UNW_LOONGARCH_F9 = 41, + UNW_LOONGARCH_F10 = 42, + UNW_LOONGARCH_F11 = 43, + UNW_LOONGARCH_F12 = 44, + UNW_LOONGARCH_F13 = 45, + UNW_LOONGARCH_F14 = 46, + UNW_LOONGARCH_F15 = 47, + UNW_LOONGARCH_F16 = 48, + UNW_LOONGARCH_F17 = 49, + UNW_LOONGARCH_F18 = 50, + UNW_LOONGARCH_F19 = 51, + UNW_LOONGARCH_F20 = 52, + UNW_LOONGARCH_F21 = 53, + UNW_LOONGARCH_F22 = 54, + UNW_LOONGARCH_F23 = 55, + UNW_LOONGARCH_F24 = 56, + UNW_LOONGARCH_F25 = 57, + UNW_LOONGARCH_F26 = 58, + UNW_LOONGARCH_F27 = 59, + UNW_LOONGARCH_F28 = 60, + UNW_LOONGARCH_F29 = 61, + UNW_LOONGARCH_F30 = 62, + UNW_LOONGARCH_F31 = 63, +}; + #endif diff --git a/contrib/subrepo-cheri-libunwind/include/libunwind.modulemap b/contrib/subrepo-cheri-libunwind/include/libunwind.modulemap new file mode 100644 index 000000000000..775841ecb5f1 --- /dev/null +++ b/contrib/subrepo-cheri-libunwind/include/libunwind.modulemap @@ -0,0 +1,13 @@ +module libunwind [system] { + header "libunwind.h" + export * +} + +module unwind [system] { + header "__libunwind_config.h" + header "unwind.h" + private textual header "unwind_arm_ehabi.h" + private textual header "unwind_itanium.h" + + export * +} diff --git a/contrib/subrepo-cheri-libunwind/include/mach-o/compact_unwind_encoding.h b/contrib/subrepo-cheri-libunwind/include/mach-o/compact_unwind_encoding.h index 68d562eec438..2dd857e45b49 100644 --- a/contrib/subrepo-cheri-libunwind/include/mach-o/compact_unwind_encoding.h +++ b/contrib/subrepo-cheri-libunwind/include/mach-o/compact_unwind_encoding.h @@ -33,7 +33,7 @@ // -// The compact unwind endoding is a 32-bit value which encoded in an +// The compact unwind encoding is a 32-bit value which encoded in an // architecture specific way, which registers to restore from where, and how // to unwind out of the function. // @@ -116,7 +116,7 @@ enum { // on the stack immediately after the return address. The stack_size/4 is // encoded in the UNWIND_X86_FRAMELESS_STACK_SIZE (max stack size is 1024). // The number of registers saved is encoded in UNWIND_X86_FRAMELESS_STACK_REG_COUNT. -// UNWIND_X86_FRAMELESS_STACK_REG_PERMUTATION constains which registers were +// UNWIND_X86_FRAMELESS_STACK_REG_PERMUTATION contains which registers were // saved and their order. // UNWIND_X86_MODE_STACK_IND: // A "frameless" (EBP not used as frame pointer) function large constant @@ -250,7 +250,7 @@ enum { // on the stack immediately after the return address. The stack_size/8 is // encoded in the UNWIND_X86_64_FRAMELESS_STACK_SIZE (max stack size is 2048). // The number of registers saved is encoded in UNWIND_X86_64_FRAMELESS_STACK_REG_COUNT. -// UNWIND_X86_64_FRAMELESS_STACK_REG_PERMUTATION constains which registers were +// UNWIND_X86_64_FRAMELESS_STACK_REG_PERMUTATION contains which registers were // saved and their order. // UNWIND_X86_64_MODE_STACK_IND: // A "frameless" (RBP not used as frame pointer) function large constant diff --git a/contrib/subrepo-cheri-libunwind/include/mach-o/compact_unwind_encoding.modulemap b/contrib/subrepo-cheri-libunwind/include/mach-o/compact_unwind_encoding.modulemap new file mode 100644 index 000000000000..6eae657d31b5 --- /dev/null +++ b/contrib/subrepo-cheri-libunwind/include/mach-o/compact_unwind_encoding.modulemap @@ -0,0 +1,4 @@ +module MachO.compact_unwind_encoding [system] { + header "compact_unwind_encoding.h" + export * +} diff --git a/contrib/subrepo-cheri-libunwind/include/unwind.h b/contrib/subrepo-cheri-libunwind/include/unwind.h index 6557374fa9d3..b1775d3a3dec 100644 --- a/contrib/subrepo-cheri-libunwind/include/unwind.h +++ b/contrib/subrepo-cheri-libunwind/include/unwind.h @@ -56,9 +56,9 @@ typedef enum { typedef struct _Unwind_Context _Unwind_Context; // opaque #if defined(_LIBUNWIND_ARM_EHABI) -#include "unwind_arm_ehabi.h" +#include #else -#include "unwind_itanium.h" +#include #endif typedef _Unwind_Reason_Code (*_Unwind_Stop_Fn) @@ -93,7 +93,7 @@ extern void _Unwind_SjLj_Unregister(_Unwind_FunctionContext_t fc); #endif // -// The following are semi-suppoted extensions to the C++ ABI +// The following are semi-supported extensions to the C++ ABI // // diff --git a/contrib/subrepo-cheri-libunwind/src/AddressSpace.hpp b/contrib/subrepo-cheri-libunwind/src/AddressSpace.hpp index 892c97f71873..55096ec40247 100644 --- a/contrib/subrepo-cheri-libunwind/src/AddressSpace.hpp +++ b/contrib/subrepo-cheri-libunwind/src/AddressSpace.hpp @@ -69,6 +69,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 @@ -438,7 +442,7 @@ inline uint64_t LocalAddressSpace::getULEB128(pint_t &addr, pint_t end) { inline int64_t LocalAddressSpace::getSLEB128(pint_t &addr, pint_t end) { const uint8_t *p = (uint8_t *)addr; const uint8_t *pend = (uint8_t *)end; - int64_t result = 0; + uint64_t result = 0; int bit = 0; uint8_t byte; do { @@ -452,7 +456,7 @@ inline int64_t LocalAddressSpace::getSLEB128(pint_t &addr, pint_t end) { if ((byte & 0x40) != 0 && bit < 64) result |= (-1ULL) << bit; addr = (pint_t) p; - return result; + return (int64_t)result; } template @@ -593,22 +597,6 @@ __attribute__((weak)) extern "C" Elf_Dyn _DYNAMIC[]; static uintptr_t calculateImageBase(struct dl_phdr_info *pinfo) { uintptr_t image_base = static_cast(pinfo->dlpi_addr); -#if defined(__ANDROID__) && __ANDROID_API__ < 18 - if (image_base == 0) { - // Normally, an image base of 0 indicates a non-PIE executable. On - // versions of Android prior to API 18, the dynamic linker reported a - // dlpi_addr of 0 for PIE executables. Compute the true image base - // using the PT_PHDR segment. - // See https://github.com/android/ndk/issues/505. - for (Elf_Half i = 0; i < pinfo->dlpi_phnum; i++) { - const Elf_Phdr *phdr = &pinfo->dlpi_phdr[i]; - if (phdr->p_type == PT_PHDR) { - image_base = static_cast(pinfo->dlpi_phdr) - phdr->p_vaddr; - break; - } - } - } -#endif #ifdef __CHERI_PURE_CAPABILITY__ // For statically linked pure-capability programs, it is generally not // possible to have a dlpi_addr capabibility with address zero but the bounds @@ -622,7 +610,6 @@ static uintptr_t calculateImageBase(struct dl_phdr_info *pinfo) { #endif return image_base; } - struct _LIBUNWIND_HIDDEN dl_iterate_cb_data { LocalAddressSpace *addressSpace; UnwindInfoSections *sects; @@ -849,6 +836,22 @@ inline bool LocalAddressSpace::findUnwindSections(pc_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) (void)targetAddr; info.dso_base = 0; @@ -932,6 +935,56 @@ inline bool LocalAddressSpace::findUnwindSections(pc_t targetAddr, if (info.arm_section && info.arm_section_length) return true; #elif defined(_LIBUNWIND_USE_DL_ITERATE_PHDR) + // Use DLFO_STRUCT_HAS_EH_DBASE to determine the existence of + // `_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 + // 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 + // so we only look it up once. Do manual lock to avoid _cxa_guard_acquire. + static decltype(_dl_find_object) *dlFindObject; + static bool dlFindObjectChecked = false; + if (!dlFindObjectChecked) { + dlFindObject = reinterpret_cast( + dlsym(RTLD_DEFAULT, "_dl_find_object")); + dlFindObjectChecked = true; + } + // Try to find the unwind info using `dl_find_object` + dl_find_object findResult; + if (dlFindObject && dlFindObject(targetAddr.get(), &findResult) == 0) { + if (findResult.dlfo_eh_frame == nullptr) { + // Found an entry for `targetAddr`, but there is no unwind info. + return false; + } + info.dso_base = reinterpret_cast(findResult.dlfo_map_start); + info.text_segment_length = static_cast( + (char *)findResult.dlfo_map_end - (char *)findResult.dlfo_map_start); + + // Record the start of PT_GNU_EH_FRAME. + info.set_dwarf_index_section( + reinterpret_cast(findResult.dlfo_eh_frame)); + // `_dl_find_object` does not give us the size of PT_GNU_EH_FRAME. + // Setting length to `SIZE_MAX` effectively disables all range checks. + info.dwarf_index_section_length = SIZE_MAX; + EHHeaderParser::EHHeaderInfo hdrInfo; + if (!EHHeaderParser::decodeEHHdr( + *this, info.dwarf_index_section(), info.dwarf_index_section_length, + hdrInfo)) { + return false; + } + // Record the start of the FDE and use SIZE_MAX to indicate that we do + // not know the end address. + info.set_dwarf_section(hdrInfo.eh_frame_ptr); + info.dwarf_section_length = SIZE_MAX; + return true; + } +#endif dl_iterate_cb_data cb_data = {this, &info, targetAddr}; CHERI_DBG("Calling dl_iterate_phdr(0x%jx)\n", (uintmax_t)targetAddr.address()); diff --git a/contrib/subrepo-cheri-libunwind/src/CMakeLists.txt b/contrib/subrepo-cheri-libunwind/src/CMakeLists.txt index fcb3054e038a..86c847de5829 100644 --- a/contrib/subrepo-cheri-libunwind/src/CMakeLists.txt +++ b/contrib/subrepo-cheri-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 @@ -31,14 +26,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() if (APPLE AND LLVM_USE_SANITIZER) if (("${LLVM_USE_SANITIZER}" STREQUAL "Address") OR @@ -160,14 +147,19 @@ 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 @@ -186,29 +178,33 @@ if (LIBUNWIND_ENABLE_SHARED) PROPERTIES LINK_FLAGS "${LIBUNWIND_LINK_FLAGS}" LINKER_LANGUAGE C - OUTPUT_NAME "unwind" + OUTPUT_NAME "${LIBUNWIND_SHARED_OUTPUT_NAME}" VERSION "1.0" SOVERSION "1" ) - # To allow testing exceptions with a shared libcxxrt.so - if (LIBUNWIND_USE_VERSION_SCRIPT) - target_link_libraries(unwind_shared PRIVATE "-Wl,--version-script=${LIBUNWIND_USE_VERSION_SCRIPT}") - endif() list(APPEND LIBUNWIND_BUILD_TARGETS "unwind_shared") if (LIBUNWIND_INSTALL_SHARED_LIBRARY) list(APPEND LIBUNWIND_INSTALL_TARGETS "unwind_shared") endif() endif() +# To allow testing exceptions with a shared libcxxrt.so +if (LIBUNWIND_USE_VERSION_SCRIPT AND TARGET unwind_shared) + target_link_libraries(unwind_shared PRIVATE "-Wl,--version-script=${LIBUNWIND_USE_VERSION_SCRIPT}") +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 @@ -230,7 +226,7 @@ if (LIBUNWIND_ENABLE_STATIC) PROPERTIES LINK_FLAGS "${LIBUNWIND_LINK_FLAGS}" LINKER_LANGUAGE C - OUTPUT_NAME "unwind" + OUTPUT_NAME "${LIBUNWIND_STATIC_OUTPUT_NAME}" ) list(APPEND LIBUNWIND_BUILD_TARGETS "unwind_static") diff --git a/contrib/subrepo-cheri-libunwind/src/CompactUnwinder.hpp b/contrib/subrepo-cheri-libunwind/src/CompactUnwinder.hpp index 0b2b5e111bfc..a7a8a153d86a 100644 --- a/contrib/subrepo-cheri-libunwind/src/CompactUnwinder.hpp +++ b/contrib/subrepo-cheri-libunwind/src/CompactUnwinder.hpp @@ -19,6 +19,7 @@ #include #include "Registers.hpp" +#include "libunwind_ext.h" #define EXTRACT_BITS(value, mask) \ ((value >> __builtin_ctz(mask)) & (((1 << __builtin_popcount(mask))) - 1)) diff --git a/contrib/subrepo-cheri-libunwind/src/CompartmentInfo.hpp b/contrib/subrepo-cheri-libunwind/src/CompartmentInfo.hpp index 39f3449c9292..2d050038acee 100644 --- a/contrib/subrepo-cheri-libunwind/src/CompartmentInfo.hpp +++ b/contrib/subrepo-cheri-libunwind/src/CompartmentInfo.hpp @@ -13,7 +13,9 @@ #ifndef __COMPARTMENT_INFO_HPP__ #define __COMPARTMENT_INFO_HPP__ +#ifdef _LIBUNWIND_HAS_CHERI_LIB_C18N #include +#endif namespace libunwind { diff --git a/contrib/subrepo-cheri-libunwind/src/DwarfInstructions.hpp b/contrib/subrepo-cheri-libunwind/src/DwarfInstructions.hpp index f47e3665a6f9..5a5ac95da26c 100644 --- a/contrib/subrepo-cheri-libunwind/src/DwarfInstructions.hpp +++ b/contrib/subrepo-cheri-libunwind/src/DwarfInstructions.hpp @@ -16,16 +16,17 @@ #include #include -#include "dwarf2.h" -#include "Registers.hpp" #include "DwarfParser.hpp" +#include "Registers.hpp" #include "config.h" +#include "dwarf2.h" +#include "libunwind_ext.h" namespace libunwind { -/// DwarfInstructions maps abtract DWARF unwind instructions to a particular +/// DwarfInstructions maps abstract DWARF unwind instructions to a particular /// architecture template class DwarfInstructions { @@ -37,7 +38,7 @@ class DwarfInstructions { typedef typename A::capability_t capability_t; static int stepWithDwarf(A &addressSpace, pc_t pc, pint_t fdeStart, - R ®isters, bool &isSignalFrame); + R ®isters, bool &isSignalFrame, bool stage2); private: @@ -249,7 +250,7 @@ bool DwarfInstructions::getRA_SIGN_STATE(A &addressSpace, R registers, template int DwarfInstructions::stepWithDwarf(A &addressSpace, pc_t pc, pint_t fdeStart, R ®isters, - bool &isSignalFrame) { + bool &isSignalFrame, bool stage2) { FDE_Info fdeInfo; CIE_Info cieInfo; if (CFI_Parser::decodeFDE(addressSpace, fdeStart, &fdeInfo, &cieInfo) == @@ -264,7 +265,39 @@ int DwarfInstructions::stepWithDwarf(A &addressSpace, pc_t pc, if (!cfa_valid) return UNW_EBADFRAME; - // restore registers that DWARF says were saved + (void)stage2; + // __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__) && !defined(__CHERI_PURE_CAPABILITY__) + if (stage2 && cieInfo.mteTaggedFrame) { + pint_t sp = registers.getSP(); + pint_t p = sp; + // AArch64 doesn't require the value of SP to be 16-byte aligned at + // all times, only at memory accesses and public interfaces [1]. Thus, + // a signal could arrive at a point where SP is not aligned properly. + // In that case, the kernel fixes up [2] the signal frame, but we + // still have a misaligned SP in the previous frame. If that signal + // handler caused stack unwinding, we would have an unaligned SP. + // We do not need to fix up the CFA, as that is the SP at a "public + // interface". + // [1]: + // https://github.com/ARM-software/abi-aa/blob/main/aapcs64/aapcs64.rst#622the-stack + // [2]: + // https://github.com/torvalds/linux/blob/1930a6e739c4b4a654a69164dbe39e554d228915/arch/arm64/kernel/signal.c#L718 + p &= ~0xfULL; + // CFA is the bottom of the current stack frame. + for (; p < cfa; p += 16) { + __asm__ __volatile__(".arch armv8.5-a\n" + ".arch_extension memtag\n" + "stg %[Ptr], [%[Ptr]]\n" + : + : [Ptr] "r"(p) + : "memory"); + } + } +#endif + // restore registers that DWARF says were saved R newRegisters = registers; // Typically, the CFA is the stack pointer at the call site in @@ -313,10 +346,10 @@ int DwarfInstructions::stepWithDwarf(A &addressSpace, pc_t pc, else return UNW_EBADREG; } else if (i == (int)cieInfo.returnAddressRegister) { - // Leaf function keeps the return address in register and there is no - // explicit intructions how to restore it. - returnAddress = registers.getRegister(cieInfo.returnAddressRegister); - CHERI_DBG("GETTING RETURN ADDRESS (leaf) %d (%s): %#p \n", i, + // Leaf function keeps the return address in register and there is no + // explicit instructions how to restore it. + returnAddress = registers.getRegister(cieInfo.returnAddressRegister); + CHERI_DBG("GETTING RETURN ADDRESS (leaf) %d (%s): %#p \n", i, registers.getRegisterName(i), (void *)returnAddress); } } @@ -406,7 +439,7 @@ int DwarfInstructions::stepWithDwarf(A &addressSpace, pc_t pc, #endif // Return address is address after call site instruction, so setting IP to - // that does simualates a return. + // that does simulates a return. newRegisters.setIP(returnAddress); CHERI_DBG("SETTING RETURN ADDRESS %#p\n", (void *)returnAddress); @@ -717,7 +750,7 @@ DwarfInstructions::evaluateExpression(pint_t expression, A &addressSpace, svalue = (sint_t)*sp; *sp = (pint_t)(svalue >> value); if (log) - fprintf(stderr, "shift left arithmetric\n"); + fprintf(stderr, "shift left arithmetic\n"); break; case DW_OP_xor: diff --git a/contrib/subrepo-cheri-libunwind/src/DwarfParser.hpp b/contrib/subrepo-cheri-libunwind/src/DwarfParser.hpp index 74de3f7e96f2..48d1459140a5 100644 --- a/contrib/subrepo-cheri-libunwind/src/DwarfParser.hpp +++ b/contrib/subrepo-cheri-libunwind/src/DwarfParser.hpp @@ -53,6 +53,7 @@ class CFI_Parser { uint8_t returnAddressRegister; #if defined(_LIBUNWIND_TARGET_AARCH64) bool addressesSignedWithBKey; + bool mteTaggedFrame; #endif }; @@ -399,6 +400,7 @@ const char *CFI_Parser::parseCIE(A &addressSpace, pint_t cie, cieInfo->fdesHaveAugmentationData = false; #if defined(_LIBUNWIND_TARGET_AARCH64) cieInfo->addressesSignedWithBKey = false; + cieInfo->mteTaggedFrame = false; #endif cieInfo->cieStart = assert_pointer_in_bounds(cie); pint_t p = cie; @@ -427,7 +429,7 @@ const char *CFI_Parser::parseCIE(A &addressSpace, pint_t cie, while (addressSpace.get8(p) != 0) ++p; ++p; - // parse code aligment factor + // parse code alignment factor cieInfo->codeAlignFactor = (uint32_t)addressSpace.getULEB128(p, cieContentEnd); // parse data alignment factor cieInfo->dataAlignFactor = (int)addressSpace.getSLEB128(p, cieContentEnd); @@ -477,6 +479,9 @@ const char *CFI_Parser::parseCIE(A &addressSpace, pint_t cie, case 'B': cieInfo->addressesSignedWithBKey = true; break; + case 'G': + cieInfo->mteTaggedFrame = true; + break; #endif default: // ignore unknown letters @@ -497,7 +502,7 @@ const char *CFI_Parser::parseCIE(A &addressSpace, pint_t cie, } -/// "run" the DWARF instructions and create the abstact PrologInfo for an FDE +/// "run" the DWARF instructions and create the abstract PrologInfo for an FDE template bool CFI_Parser::parseFDEInstructions(A &addressSpace, const FDE_Info &fdeInfo, diff --git a/contrib/subrepo-cheri-libunwind/src/FrameHeaderCache.hpp b/contrib/subrepo-cheri-libunwind/src/FrameHeaderCache.hpp index 54d5d33c3cd7..80a6a6bb020c 100644 --- a/contrib/subrepo-cheri-libunwind/src/FrameHeaderCache.hpp +++ b/contrib/subrepo-cheri-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; }; diff --git a/contrib/subrepo-cheri-libunwind/src/Registers.hpp b/contrib/subrepo-cheri-libunwind/src/Registers.hpp index 2b054f518bf8..af090fad643b 100644 --- a/contrib/subrepo-cheri-libunwind/src/Registers.hpp +++ b/contrib/subrepo-cheri-libunwind/src/Registers.hpp @@ -61,6 +61,7 @@ enum { REGISTERS_RISCV, REGISTERS_VE, REGISTERS_S390X, + REGISTERS_LOONGARCH, }; #if defined(_LIBUNWIND_TARGET_I386) @@ -4509,7 +4510,7 @@ typedef float fp_t; # error "Unsupported __riscv_flen" # endif # else -// This is just for supressing undeclared error of fp_t. +// This is just for suppressing undeclared error of fp_t. typedef double fp_t; # endif # else @@ -4600,6 +4601,8 @@ inline bool Registers_riscv::validRegister(int regNum) const { return true; if (regNum < 0) return false; + if (regNum == UNW_RISCV_VLENB) + return true; if (regNum > UNW_RISCV_F31) return false; return true; @@ -4614,6 +4617,11 @@ inline reg_t Registers_riscv::getRegister(int regNum) const { return 0; if ((regNum > 0) && (regNum < 32)) return _registers[regNum]; + if (regNum == UNW_RISCV_VLENB) { + size_t vlenb; + __asm__("csrr %0, 0xC22" : "=r"(vlenb)); + return vlenb; + } _LIBUNWIND_ABORT("unsupported riscv register"); } @@ -4789,6 +4797,8 @@ inline const char *Registers_riscv::getRegisterName(int regNum) { return "ft10"; case UNW_RISCV_F31: return "ft11"; + case UNW_RISCV_VLENB: + return "vlenb"; default: return "unknown register"; } @@ -5571,6 +5581,271 @@ inline const char *Registers_s390x::getRegisterName(int regNum) { } #endif // _LIBUNWIND_TARGET_S390X +#if defined(_LIBUNWIND_TARGET_LOONGARCH) +/// Registers_loongarch holds the register state of a thread in a 64-bit +/// LoongArch process. +class _LIBUNWIND_HIDDEN Registers_loongarch { +public: + Registers_loongarch(); + Registers_loongarch(const void *registers); + + bool validRegister(int num) const; + uint64_t getRegister(int num) const; + void setRegister(int num, uint64_t value); + bool validFloatRegister(int num) const; + double getFloatRegister(int num) const; + void setFloatRegister(int num, double value); + bool validVectorRegister(int num) const; + v128 getVectorRegister(int num) const; + void setVectorRegister(int num, v128 value); + static const char *getRegisterName(int num); + void jumpto(); + static constexpr int lastDwarfRegNum() { + return _LIBUNWIND_HIGHEST_DWARF_REGISTER_LOONGARCH; + } + static int getArch() { return REGISTERS_LOONGARCH; } + + uint64_t getSP() const { return _registers.__r[3]; } + void setSP(uint64_t value) { _registers.__r[3] = value; } + uint64_t getIP() const { return _registers.__pc; } + void setIP(uint64_t value) { _registers.__pc = value; } + +private: + struct loongarch_thread_state_t { + uint64_t __r[32]; + uint64_t __pc; + }; + + loongarch_thread_state_t _registers; +#if __loongarch_frlen == 64 + double _floats[32]; +#endif +}; + +inline Registers_loongarch::Registers_loongarch(const void *registers) { + static_assert((check_fit::does_fit), + "loongarch registers do not fit into unw_context_t"); + memcpy(&_registers, registers, sizeof(_registers)); + static_assert(sizeof(_registers) == 0x108, + "expected float registers to be at offset 264"); +#if __loongarch_frlen == 64 + memcpy(_floats, static_cast(registers) + sizeof(_registers), + sizeof(_floats)); +#endif +} + +inline Registers_loongarch::Registers_loongarch() { + memset(&_registers, 0, sizeof(_registers)); +#if __loongarch_frlen == 64 + memset(&_floats, 0, sizeof(_floats)); +#endif +} + +inline bool Registers_loongarch::validRegister(int regNum) const { + if (regNum == UNW_REG_IP || regNum == UNW_REG_SP) + return true; + if (regNum < 0 || regNum > UNW_LOONGARCH_F31) + return false; + return true; +} + +inline uint64_t Registers_loongarch::getRegister(int regNum) const { + if (regNum >= UNW_LOONGARCH_R0 && regNum <= UNW_LOONGARCH_R31) + return _registers.__r[regNum - UNW_LOONGARCH_R0]; + + if (regNum == UNW_REG_IP) + return _registers.__pc; + if (regNum == UNW_REG_SP) + return _registers.__r[3]; + _LIBUNWIND_ABORT("unsupported loongarch register"); +} + +inline void Registers_loongarch::setRegister(int regNum, uint64_t value) { + if (regNum >= UNW_LOONGARCH_R0 && regNum <= UNW_LOONGARCH_R31) + _registers.__r[regNum - UNW_LOONGARCH_R0] = value; + else if (regNum == UNW_REG_IP) + _registers.__pc = value; + else if (regNum == UNW_REG_SP) + _registers.__r[3] = value; + else + _LIBUNWIND_ABORT("unsupported loongarch register"); +} + +inline const char *Registers_loongarch::getRegisterName(int regNum) { + switch (regNum) { + case UNW_REG_IP: + return "$pc"; + case UNW_REG_SP: + return "$sp"; + case UNW_LOONGARCH_R0: + return "$r0"; + case UNW_LOONGARCH_R1: + return "$r1"; + case UNW_LOONGARCH_R2: + return "$r2"; + case UNW_LOONGARCH_R3: + return "$r3"; + case UNW_LOONGARCH_R4: + return "$r4"; + case UNW_LOONGARCH_R5: + return "$r5"; + case UNW_LOONGARCH_R6: + return "$r6"; + case UNW_LOONGARCH_R7: + return "$r7"; + case UNW_LOONGARCH_R8: + return "$r8"; + case UNW_LOONGARCH_R9: + return "$r9"; + case UNW_LOONGARCH_R10: + return "$r10"; + case UNW_LOONGARCH_R11: + return "$r11"; + case UNW_LOONGARCH_R12: + return "$r12"; + case UNW_LOONGARCH_R13: + return "$r13"; + case UNW_LOONGARCH_R14: + return "$r14"; + case UNW_LOONGARCH_R15: + return "$r15"; + case UNW_LOONGARCH_R16: + return "$r16"; + case UNW_LOONGARCH_R17: + return "$r17"; + case UNW_LOONGARCH_R18: + return "$r18"; + case UNW_LOONGARCH_R19: + return "$r19"; + case UNW_LOONGARCH_R20: + return "$r20"; + case UNW_LOONGARCH_R21: + return "$r21"; + case UNW_LOONGARCH_R22: + return "$r22"; + case UNW_LOONGARCH_R23: + return "$r23"; + case UNW_LOONGARCH_R24: + return "$r24"; + case UNW_LOONGARCH_R25: + return "$r25"; + case UNW_LOONGARCH_R26: + return "$r26"; + case UNW_LOONGARCH_R27: + return "$r27"; + case UNW_LOONGARCH_R28: + return "$r28"; + case UNW_LOONGARCH_R29: + return "$r29"; + case UNW_LOONGARCH_R30: + return "$r30"; + case UNW_LOONGARCH_R31: + return "$r31"; + case UNW_LOONGARCH_F0: + return "$f0"; + case UNW_LOONGARCH_F1: + return "$f1"; + case UNW_LOONGARCH_F2: + return "$f2"; + case UNW_LOONGARCH_F3: + return "$f3"; + case UNW_LOONGARCH_F4: + return "$f4"; + case UNW_LOONGARCH_F5: + return "$f5"; + case UNW_LOONGARCH_F6: + return "$f6"; + case UNW_LOONGARCH_F7: + return "$f7"; + case UNW_LOONGARCH_F8: + return "$f8"; + case UNW_LOONGARCH_F9: + return "$f9"; + case UNW_LOONGARCH_F10: + return "$f10"; + case UNW_LOONGARCH_F11: + return "$f11"; + case UNW_LOONGARCH_F12: + return "$f12"; + case UNW_LOONGARCH_F13: + return "$f13"; + case UNW_LOONGARCH_F14: + return "$f14"; + case UNW_LOONGARCH_F15: + return "$f15"; + case UNW_LOONGARCH_F16: + return "$f16"; + case UNW_LOONGARCH_F17: + return "$f17"; + case UNW_LOONGARCH_F18: + return "$f18"; + case UNW_LOONGARCH_F19: + return "$f19"; + case UNW_LOONGARCH_F20: + return "$f20"; + case UNW_LOONGARCH_F21: + return "$f21"; + case UNW_LOONGARCH_F22: + return "$f22"; + case UNW_LOONGARCH_F23: + return "$f23"; + case UNW_LOONGARCH_F24: + return "$f24"; + case UNW_LOONGARCH_F25: + return "$f25"; + case UNW_LOONGARCH_F26: + return "$f26"; + case UNW_LOONGARCH_F27: + return "$f27"; + case UNW_LOONGARCH_F28: + return "$f28"; + case UNW_LOONGARCH_F29: + return "$f29"; + case UNW_LOONGARCH_F30: + return "$f30"; + case UNW_LOONGARCH_F31: + return "$f31"; + default: + return "unknown register"; + } +} + +inline bool Registers_loongarch::validFloatRegister(int regNum) const { + if (regNum < UNW_LOONGARCH_F0 || regNum > UNW_LOONGARCH_F31) + return false; + return true; +} + +inline double Registers_loongarch::getFloatRegister(int regNum) const { +#if __loongarch_frlen == 64 + assert(validFloatRegister(regNum)); + return _floats[regNum - UNW_LOONGARCH_F0]; +#else + _LIBUNWIND_ABORT("libunwind not built with float support"); +#endif +} + +inline void Registers_loongarch::setFloatRegister(int regNum, double value) { +#if __loongarch_frlen == 64 + assert(validFloatRegister(regNum)); + _floats[regNum - UNW_LOONGARCH_F0] = value; +#else + _LIBUNWIND_ABORT("libunwind not built with float support"); +#endif +} + +inline bool Registers_loongarch::validVectorRegister(int) const { + return false; +} + +inline v128 Registers_loongarch::getVectorRegister(int) const { + _LIBUNWIND_ABORT("loongarch vector support not implemented"); +} + +inline void Registers_loongarch::setVectorRegister(int, v128) { + _LIBUNWIND_ABORT("loongarch vector support not implemented"); +} +#endif //_LIBUNWIND_TARGET_LOONGARCH } // namespace libunwind diff --git a/contrib/subrepo-cheri-libunwind/src/Unwind-EHABI.cpp b/contrib/subrepo-cheri-libunwind/src/Unwind-EHABI.cpp index 051a0cee6249..d093db24da2a 100644 --- a/contrib/subrepo-cheri-libunwind/src/Unwind-EHABI.cpp +++ b/contrib/subrepo-cheri-libunwind/src/Unwind-EHABI.cpp @@ -235,7 +235,7 @@ decode_eht_entry(const uint32_t* data, size_t* off, size_t* len) { } else { // 6.3: ARM Compact Model // - // EHT entries here correspond to the __aeabi_unwind_cpp_pr[012] PRs indeded + // EHT entries here correspond to the __aeabi_unwind_cpp_pr[012] PRs indeed // by format: Descriptor::Format format = static_cast((*data & 0x0f000000) >> 24); @@ -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; @@ -845,7 +845,7 @@ _LIBUNWIND_EXPORT void _Unwind_Complete(_Unwind_Exception* exception_object) { /// may force a jump to a landing pad in that function, the landing /// pad code may then call _Unwind_Resume() to continue with the /// unwinding. Note: the call to _Unwind_Resume() is from compiler -/// geneated user code. All other _Unwind_* routines are called +/// generated user code. All other _Unwind_* routines are called /// by the C++ runtime __cxa_* routines. /// /// Note: re-throwing an exception (as opposed to continuing the unwind) diff --git a/contrib/subrepo-cheri-libunwind/src/Unwind-seh.cpp b/contrib/subrepo-cheri-libunwind/src/Unwind-seh.cpp index d069c2778ea3..b973cce846a2 100644 --- a/contrib/subrepo-cheri-libunwind/src/Unwind-seh.cpp +++ b/contrib/subrepo-cheri-libunwind/src/Unwind-seh.cpp @@ -137,7 +137,7 @@ _GCC_specific_handler(PEXCEPTION_RECORD ms_exc, PVOID frame, PCONTEXT ms_ctx, // If we were called by __libunwind_seh_personality(), indicate that // a handler was found; otherwise, initiate phase 2 by unwinding. if (ours && ms_exc->NumberParameters > 1) - return 4 /* ExecptionExecuteHandler in mingw */; + return 4 /* ExceptionExecuteHandler in mingw */; // This should never happen in phase 2. if (IS_UNWINDING(ms_exc->ExceptionFlags)) _LIBUNWIND_ABORT("Personality indicated exception handler in phase 2!"); @@ -155,7 +155,7 @@ _GCC_specific_handler(PEXCEPTION_RECORD ms_exc, PVOID frame, PCONTEXT ms_ctx, // a handler was found; otherwise, it's time to initiate a collided // unwind to the target. if (ours && !IS_UNWINDING(ms_exc->ExceptionFlags) && ms_exc->NumberParameters > 1) - return 4 /* ExecptionExecuteHandler in mingw */; + return 4 /* ExceptionExecuteHandler in mingw */; // This should never happen in phase 1. if (!IS_UNWINDING(ms_exc->ExceptionFlags)) _LIBUNWIND_ABORT("Personality installed context during phase 1!"); @@ -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; } } @@ -354,7 +371,7 @@ _Unwind_RaiseException(_Unwind_Exception *exception_object) { /// may force a jump to a landing pad in that function; the landing /// pad code may then call \c _Unwind_Resume() to continue with the /// unwinding. Note: the call to \c _Unwind_Resume() is from compiler -/// geneated user code. All other \c _Unwind_* routines are called +/// generated user code. All other \c _Unwind_* routines are called /// by the C++ runtime \c __cxa_* routines. /// /// Note: re-throwing an exception (as opposed to continuing the unwind) diff --git a/contrib/subrepo-cheri-libunwind/src/Unwind-sjlj.c b/contrib/subrepo-cheri-libunwind/src/Unwind-sjlj.c index d487995bb78e..90a55fd29db1 100644 --- a/contrib/subrepo-cheri-libunwind/src/Unwind-sjlj.c +++ b/contrib/subrepo-cheri-libunwind/src/Unwind-sjlj.c @@ -33,7 +33,7 @@ struct _Unwind_FunctionContext { struct _Unwind_FunctionContext *prev; #if defined(__ve__) - // VE requires to store 64 bit pointers in the buffer for SjLj execption. + // VE requires to store 64 bit pointers in the buffer for SjLj exception. // We expand the size of values defined here. This size must be matched // to the size returned by TargetMachine::getSjLjDataSize(). @@ -357,7 +357,7 @@ _Unwind_SjLj_RaiseException(struct _Unwind_Exception *exception_object) { /// may force a jump to a landing pad in that function, the landing /// pad code may then call _Unwind_Resume() to continue with the /// unwinding. Note: the call to _Unwind_Resume() is from compiler -/// geneated user code. All other _Unwind_* routines are called +/// generated user code. All other _Unwind_* routines are called /// by the C++ runtime __cxa_* routines. /// /// Re-throwing an exception is implemented by having the code call @@ -394,7 +394,7 @@ _Unwind_SjLj_Resume_or_Rethrow(struct _Unwind_Exception *exception_object) { // std::terminate() } - // Call through to _Unwind_Resume() which distiguishes between forced and + // Call through to _Unwind_Resume() which distinguishes between forced and // regular exceptions. _Unwind_SjLj_Resume(exception_object); _LIBUNWIND_ABORT("__Unwind_SjLj_Resume_or_Rethrow() called " diff --git a/contrib/subrepo-cheri-libunwind/src/UnwindCursor.hpp b/contrib/subrepo-cheri-libunwind/src/UnwindCursor.hpp index dc4515c76700..3190505106af 100644 --- a/contrib/subrepo-cheri-libunwind/src/UnwindCursor.hpp +++ b/contrib/subrepo-cheri-libunwind/src/UnwindCursor.hpp @@ -31,13 +31,26 @@ #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 #define _LIBUNWIND_CHECK_LINUX_SIGRETURN 1 #endif +#include "AddressSpace.hpp" +#include "CompactUnwinder.hpp" +#include "config.h" +#include "DwarfInstructions.hpp" +#include "EHHeaderParser.hpp" +#include "libunwind.h" +#include "libunwind_ext.h" +#include "Registers.hpp" +#include "RWMutex.hpp" +#include "Unwind-EHABI.h" +#include "CompartmentInfo.hpp" + #if defined(_LIBUNWIND_SUPPORT_SEH_UNWIND) // Provide a definition for the DISPATCHER_CONTEXT struct for old (Win7 and // earlier) SDKs. @@ -75,19 +88,6 @@ extern "C" _Unwind_Reason_Code __libunwind_seh_personality( #endif -#include "config.h" - -#include "AddressSpace.hpp" -#include "CompactUnwinder.hpp" -#include "config.h" -#include "DwarfInstructions.hpp" -#include "EHHeaderParser.hpp" -#include "libunwind.h" -#include "Registers.hpp" -#include "RWMutex.hpp" -#include "Unwind-EHABI.h" -#include "CompartmentInfo.hpp" - namespace libunwind { #if defined(_LIBUNWIND_SUPPORT_DWARF_UNWIND) @@ -448,7 +448,7 @@ class _LIBUNWIND_HIDDEN AbstractUnwindCursor { virtual void setFloatReg(int, unw_fpreg_t) { _LIBUNWIND_ABORT("setFloatReg not implemented"); } - virtual int step() { _LIBUNWIND_ABORT("step not implemented"); } + virtual int step(bool = false) { _LIBUNWIND_ABORT("step not implemented"); } virtual void getInfo(unw_proc_info_t *) { _LIBUNWIND_ABORT("getInfo not implemented"); } @@ -500,7 +500,7 @@ class UnwindCursor : public AbstractUnwindCursor { virtual bool validFloatReg(int); virtual unw_fpreg_t getFloatReg(int); virtual void setFloatReg(int, unw_fpreg_t); - virtual int step(); + virtual int step(bool = false); virtual void getInfo(unw_proc_info_t *); virtual void jumpto(); virtual bool isSignalFrame(); @@ -512,10 +512,17 @@ 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 defition of inline placement new. + // need our own definition of inline placement new. static void *operator new(size_t, UnwindCursor *p) { return p; } private: @@ -574,10 +581,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); @@ -675,6 +684,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; @@ -685,7 +695,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) @@ -700,6 +710,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; @@ -750,6 +761,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; @@ -935,7 +947,7 @@ class UnwindCursor : public AbstractUnwindCursor{ virtual bool validFloatReg(int); virtual unw_fpreg_t getFloatReg(int); virtual void setFloatReg(int, unw_fpreg_t); - virtual int step(); + virtual int step(bool stage2 = false); virtual void getInfo(unw_proc_info_t *); virtual void jumpto(); virtual bool isSignalFrame(); @@ -955,7 +967,7 @@ class UnwindCursor : public AbstractUnwindCursor{ #endif // libunwind does not and should not depend on C++ library which means that we - // need our own defition of inline placement new. + // need our own definition of inline placement new. static void *operator new(size_t, UnwindCursor *p) { return p; } private: @@ -991,6 +1003,10 @@ class UnwindCursor : public AbstractUnwindCursor{ 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 &); @@ -1009,21 +1025,21 @@ class UnwindCursor : public AbstractUnwindCursor{ pc_t pc, uintptr_t dso_base); bool getInfoFromDwarfSection(pc_t pc, const UnwindInfoSections §s, uint32_t fdeSectionOffsetHint=0); - int stepWithDwarfFDE() { - return DwarfInstructions::stepWithDwarf(_addressSpace, this->getIP(), - (pint_t)_info.unwind_info, - _registers, _isSignalFrame); + int stepWithDwarfFDE(bool stage2) { + return DwarfInstructions::stepWithDwarf( + _addressSpace, this->getIP(), (pint_t)_info.unwind_info, _registers, + _isSignalFrame, stage2); } #endif #if defined(_LIBUNWIND_SUPPORT_COMPACT_UNWIND) bool getInfoFromCompactEncodingSection(pc_t pc, const UnwindInfoSections §s); - int stepWithCompactEncoding() { + int stepWithCompactEncoding(bool stage2 = false) { #if defined(_LIBUNWIND_SUPPORT_DWARF_UNWIND) if ( compactSaysUseDwarf() ) - return stepWithDwarfFDE(); - #endif + return stepWithDwarfFDE(stage2); +#endif R dummy; return stepWithCompactEncoding(dummy); } @@ -1074,6 +1090,10 @@ class UnwindCursor : public AbstractUnwindCursor{ } #endif +#if defined(_LIBUNWIND_TARGET_LOONGARCH) + int stepWithCompactEncoding(Registers_loongarch &) { return UNW_EINVAL; } +#endif + #if defined(_LIBUNWIND_TARGET_SPARC) int stepWithCompactEncoding(Registers_sparc &) { return UNW_EINVAL; } #endif @@ -1156,6 +1176,12 @@ class UnwindCursor : public AbstractUnwindCursor{ } #endif +#if defined(_LIBUNWIND_TARGET_LOONGARCH) + bool compactSaysUseDwarf(Registers_loongarch &, uint32_t *) const { + return true; + } +#endif + #if defined(_LIBUNWIND_TARGET_SPARC) bool compactSaysUseDwarf(Registers_sparc &, uint32_t *) const { return true; } #endif @@ -1246,6 +1272,12 @@ class UnwindCursor : public AbstractUnwindCursor{ } #endif +#if defined(_LIBUNWIND_TARGET_LOONGARCH) + compact_unwind_encoding_t dwarfEncoding(Registers_loongarch &) const { + return 0; + } +#endif + #if defined(_LIBUNWIND_TARGET_SPARC) compact_unwind_encoding_t dwarfEncoding(Registers_sparc &) const { return 0; } #endif @@ -1995,6 +2027,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 @@ -2137,6 +2172,11 @@ bool UnwindCursor::getInfoFromTBTable(pint_t pc, R ®isters) { // using dlopen(). const char libcxxabi[] = "libc++abi.a(libc++abi.so.1)"; void *libHandle; + // The AIX dlopen() sets errno to 0 when it is successful, which + // clobbers the value of errno from the user code. This is an AIX + // bug because according to POSIX it should not set errno to 0. To + // workaround before AIX fixes the bug, errno is saved and restored. + int saveErrno = errno; libHandle = dlopen(libcxxabi, RTLD_MEMBER | RTLD_NOW); if (libHandle == NULL) { _LIBUNWIND_TRACE_UNWINDING("dlopen() failed with errno=%d\n", @@ -2150,6 +2190,7 @@ bool UnwindCursor::getInfoFromTBTable(pint_t pc, R ®isters) { assert(0 && "dlsym() failed"); } dlclose(libHandle); + errno = saveErrno; } } xlcPersonalityV0InitLock.unlock(); @@ -2486,7 +2527,7 @@ int UnwindCursor::stepWithTBTable(pint_t pc, tbtable *TBTable, reinterpret_cast(pc)); // The return address is the address after call site instruction, so - // setting IP to that simualates a return. + // setting IP to that simulates a return. newRegisters.setIP(reinterpret_cast(returnAddress)); // Simulate the step by replacing the register set with the new ones. @@ -2733,6 +2774,60 @@ int UnwindCursor::stepThroughSigReturn(Registers_arm64 &) { #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)); + 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); + // Look for the two instructions used in the sigreturn trampoline + // __vdso_rt_sigreturn: + // + // 0x08b00893 li a7,0x8b + // 0x00000073 ecall + if (bytesRead != sizeof instructions || 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 @@ -2839,8 +2934,8 @@ int UnwindCursor::stepThroughSigReturn(Registers_s390x &) { #endif // defined(_LIBUNWIND_CHECK_LINUX_SIGRETURN) && // defined(_LIBUNWIND_TARGET_S390X) -template -int UnwindCursor::step() { +template int UnwindCursor::step(bool stage2) { + (void)stage2; // Bottom of stack is defined is when unwind info cannot be found. if (_unwindInfoMissing) { _LIBUNWIND_TRACE_UNWINDING("%s: _unwindInfoMissing -> UNW_STEP_END", __func__); @@ -2855,13 +2950,13 @@ int UnwindCursor::step() { #endif { #if defined(_LIBUNWIND_SUPPORT_COMPACT_UNWIND) - result = this->stepWithCompactEncoding(); + result = this->stepWithCompactEncoding(stage2); #elif defined(_LIBUNWIND_SUPPORT_SEH_UNWIND) result = this->stepWithSEHData(); #elif defined(_LIBUNWIND_SUPPORT_TBTAB_UNWIND) result = this->stepWithTBTableData(); #elif defined(_LIBUNWIND_SUPPORT_DWARF_UNWIND) - result = this->stepWithDwarfFDE(); + result = this->stepWithDwarfFDE(stage2); #elif defined(_LIBUNWIND_ARM_EHABI) result = this->stepWithEHABI(); #else diff --git a/contrib/subrepo-cheri-libunwind/src/UnwindLevel1-gcc-ext.c b/contrib/subrepo-cheri-libunwind/src/UnwindLevel1-gcc-ext.c index 0250664bbc7e..d343f4e6e9cc 100644 --- a/contrib/subrepo-cheri-libunwind/src/UnwindLevel1-gcc-ext.c +++ b/contrib/subrepo-cheri-libunwind/src/UnwindLevel1-gcc-ext.c @@ -22,6 +22,10 @@ #include "Unwind-EHABI.h" #include "unwind.h" +#if defined(_AIX) +#include +#endif + #if defined(_LIBUNWIND_BUILD_ZERO_COST_APIS) #if defined(_LIBUNWIND_SUPPORT_SEH_UNWIND) @@ -48,7 +52,7 @@ _Unwind_Resume_or_Rethrow(_Unwind_Exception *exception_object) { // std::terminate(). } - // Call through to _Unwind_Resume() which distiguishes between forced and + // Call through to _Unwind_Resume() which distinguishes between forced and // regular exceptions. _Unwind_Resume(exception_object); _LIBUNWIND_ABORT("_Unwind_Resume_or_Rethrow() called _Unwind_RaiseException()" @@ -82,6 +86,32 @@ _Unwind_GetTextRelBase(struct _Unwind_Context *context) { /// specified code address "pc". _LIBUNWIND_EXPORT void *_Unwind_FindEnclosingFunction(void *pc) { _LIBUNWIND_TRACE_API("_Unwind_FindEnclosingFunction(pc=%p)", pc); +#if defined(_AIX) + if (pc == NULL) + return NULL; + + // Get the start address of the enclosing function from the function's + // traceback table. + uint32_t *p = (uint32_t *)pc; + + // Keep looking forward until a word of 0 is found. The traceback + // table starts at the following word. + while (*p) + ++p; + struct tbtable *TBTable = (struct tbtable *)(p + 1); + + // Get the address of the traceback table extension. + p = (uint32_t *)&TBTable->tb_ext; + + // Skip field parminfo if it exists. + if (TBTable->tb.fixedparms || TBTable->tb.floatparms) + ++p; + + if (TBTable->tb.has_tboff) + // *p contains the offset from the function start to traceback table. + return (void *)((uintptr_t)TBTable - *p - sizeof(uint32_t)); + return NULL; +#else // This is slow, but works. // We create an unwind cursor then alter the IP to be pc unw_cursor_t cursor; @@ -94,6 +124,7 @@ _LIBUNWIND_EXPORT void *_Unwind_FindEnclosingFunction(void *pc) { return (void *)(intptr_t) info.start_ip; else return NULL; +#endif } /// Walk every frame and call trace function at each one. If trace function @@ -136,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/contrib/subrepo-cheri-libunwind/src/UnwindLevel1.c b/contrib/subrepo-cheri-libunwind/src/UnwindLevel1.c index 1f37a1f6624e..576eb11c8e1d 100644 --- a/contrib/subrepo-cheri-libunwind/src/UnwindLevel1.c +++ b/contrib/subrepo-cheri-libunwind/src/UnwindLevel1.c @@ -41,7 +41,7 @@ // In exception handing, some stack frames will be skipped before jumping to // landing pad and we must adjust CET shadow stack accordingly. // _LIBUNWIND_POP_CET_SSP is used to adjust CET shadow stack pointer and we -// directly jump to __libunwind_Registerts_x86/x86_64_jumpto instead of using +// directly jump to __libunwind_Registers_x86/x86_64_jumpto instead of using // a regular function call to avoid pushing to CET shadow stack again. #if !defined(_LIBUNWIND_USE_CET) #define __unw_phase2_resume(cursor, fn) \ @@ -50,6 +50,7 @@ __unw_resume((cursor)); \ } while (0) #elif defined(_LIBUNWIND_TARGET_I386) +#define __cet_ss_step_size 4 #define __unw_phase2_resume(cursor, fn) \ do { \ _LIBUNWIND_POP_CET_SSP((fn)); \ @@ -61,6 +62,7 @@ "d"(cetJumpAddress)); \ } while (0) #elif defined(_LIBUNWIND_TARGET_X86_64) +#define __cet_ss_step_size 8 #define __unw_phase2_resume(cursor, fn) \ do { \ _LIBUNWIND_POP_CET_SSP((fn)); \ @@ -82,13 +84,13 @@ unwind_phase1(unw_context_t *uc, unw_cursor_t *cursor, _Unwind_Exception *except int stepResult = __unw_step(cursor); if (stepResult == 0) { _LIBUNWIND_TRACE_UNWINDING( - "unwind_phase1(ex_ojb=%p): __unw_step() reached " + "unwind_phase1(ex_obj=%p): __unw_step() reached " "bottom => _URC_END_OF_STACK", (void *)exception_object); return _URC_END_OF_STACK; } else if (stepResult < 0) { _LIBUNWIND_TRACE_UNWINDING( - "unwind_phase1(ex_ojb=%p): __unw_step failed => " + "unwind_phase1(ex_obj=%p): __unw_step failed => " "_URC_FATAL_PHASE1_ERROR", (void *)exception_object); return _URC_FATAL_PHASE1_ERROR; @@ -99,7 +101,7 @@ unwind_phase1(unw_context_t *uc, unw_cursor_t *cursor, _Unwind_Exception *except unw_word_t sp; if (__unw_get_proc_info(cursor, &frameInfo) != UNW_ESUCCESS) { _LIBUNWIND_TRACE_UNWINDING( - "unwind_phase1(ex_ojb=%p): __unw_get_proc_info " + "unwind_phase1(ex_obj=%p): __unw_get_proc_info " "failed => _URC_FATAL_PHASE1_ERROR", (void *)exception_object); return _URC_FATAL_PHASE1_ERROR; @@ -118,7 +120,7 @@ unwind_phase1(unw_context_t *uc, unw_cursor_t *cursor, _Unwind_Exception *except unw_word_t pc; __unw_get_reg(cursor, UNW_REG_IP, &pc); _LIBUNWIND_TRACE_UNWINDING( - "unwind_phase1(ex_ojb=%p): pc=0x%" PRIxPTR ", start_ip=0x%" PRIxPTR + "unwind_phase1(ex_obj=%p): pc=0x%" PRIxPTR ", start_ip=0x%" PRIxPTR ", func=%s, lsda=0x%" PRIxPTR ", personality=0x%" PRIxPTR "", (void *)exception_object, pc, frameInfo.start_ip, functionName, frameInfo.lsda, frameInfo.handler); @@ -131,7 +133,7 @@ unwind_phase1(unw_context_t *uc, unw_cursor_t *cursor, _Unwind_Exception *except _Unwind_Personality_Fn p = (_Unwind_Personality_Fn)(uintptr_t)(frameInfo.handler); _LIBUNWIND_TRACE_UNWINDING( - "unwind_phase1(ex_ojb=%p): calling personality function %p", + "unwind_phase1(ex_obj=%p): calling personality function %p", (void *)exception_object, (void *)(uintptr_t)p); _Unwind_Reason_Code personalityResult = (*p)(1, _UA_SEARCH_PHASE, exception_object->exception_class, @@ -143,13 +145,13 @@ unwind_phase1(unw_context_t *uc, unw_cursor_t *cursor, _Unwind_Exception *except __unw_get_reg(cursor, UNW_REG_SP, &sp); exception_object->private_2 = (uintptr_t)sp; _LIBUNWIND_TRACE_UNWINDING( - "unwind_phase1(ex_ojb=%p): _URC_HANDLER_FOUND sp=%p", + "unwind_phase1(ex_obj=%p): _URC_HANDLER_FOUND sp=%p", (void *)exception_object, (void*)sp); return _URC_NO_REASON; case _URC_CONTINUE_UNWIND: _LIBUNWIND_TRACE_UNWINDING( - "unwind_phase1(ex_ojb=%p): _URC_CONTINUE_UNWIND", + "unwind_phase1(ex_obj=%p): _URC_CONTINUE_UNWIND", (void *)exception_object); // continue unwinding break; @@ -157,7 +159,7 @@ unwind_phase1(unw_context_t *uc, unw_cursor_t *cursor, _Unwind_Exception *except default: // something went wrong _LIBUNWIND_TRACE_UNWINDING( - "unwind_phase1(ex_ojb=%p): _URC_FATAL_PHASE1_ERROR", + "unwind_phase1(ex_obj=%p): _URC_FATAL_PHASE1_ERROR", (void *)exception_object); return _URC_FATAL_PHASE1_ERROR; } @@ -172,32 +174,36 @@ unwind_phase1(unw_context_t *uc, unw_cursor_t *cursor, _Unwind_Exception *except #endif #define PRINT_PTR "%p" +extern int __unw_step_stage2(unw_cursor_t *); static _Unwind_Reason_Code unwind_phase2(unw_context_t *uc, unw_cursor_t *cursor, _Unwind_Exception *exception_object) { __unw_init_local(cursor, uc); - _LIBUNWIND_TRACE_UNWINDING("unwind_phase2(ex_ojb=%p)", + _LIBUNWIND_TRACE_UNWINDING("unwind_phase2(ex_obj=%p)", (void *)exception_object); // uc is initialized by __unw_getcontext in the parent frame. The first stack // frame walked is unwind_phase2. unsigned framesWalked = 1; +#ifdef _LIBUNWIND_USE_CET + unsigned long shadowStackTop = _get_ssp(); +#endif // Walk each frame until we reach where search phase said to stop. while (true) { // Ask libunwind to get next frame (skip over first which is // _Unwind_RaiseException). - int stepResult = __unw_step(cursor); + int stepResult = __unw_step_stage2(cursor); if (stepResult == 0) { _LIBUNWIND_TRACE_UNWINDING( - "unwind_phase2(ex_ojb=%p): __unw_step() reached " + "unwind_phase2(ex_obj=%p): __unw_step_stage2() reached " "bottom => _URC_END_OF_STACK", (void *)exception_object); return _URC_END_OF_STACK; } else if (stepResult < 0) { _LIBUNWIND_TRACE_UNWINDING( - "unwind_phase2(ex_ojb=%p): __unw_step failed => " + "unwind_phase2(ex_obj=%p): __unw_step_stage2 failed => " "_URC_FATAL_PHASE1_ERROR", (void *)exception_object); return _URC_FATAL_PHASE2_ERROR; @@ -209,7 +215,7 @@ unwind_phase2(unw_context_t *uc, unw_cursor_t *cursor, _Unwind_Exception *except __unw_get_reg(cursor, UNW_REG_SP, &sp); if (__unw_get_proc_info(cursor, &frameInfo) != UNW_ESUCCESS) { _LIBUNWIND_TRACE_UNWINDING( - "unwind_phase2(ex_ojb=%p): __unw_get_proc_info " + "unwind_phase2(ex_obj=%p): __unw_get_proc_info " "failed => _URC_FATAL_PHASE1_ERROR", (void *)exception_object); return _URC_FATAL_PHASE2_ERROR; @@ -225,7 +231,7 @@ unwind_phase2(unw_context_t *uc, unw_cursor_t *cursor, _Unwind_Exception *except &offset) != UNW_ESUCCESS) || (frameInfo.start_ip + (size_t)offset > frameInfo.end_ip)) functionName = ".anonymous."; - _LIBUNWIND_TRACE_UNWINDING("unwind_phase2(ex_ojb=%p): start_ip=" PRINT_PTR + _LIBUNWIND_TRACE_UNWINDING("unwind_phase2(ex_obj=%p): start_ip=" PRINT_PTR ", func=%s, sp=" PRINT_PTR_V ", lsda=" PRINT_PTR ", personality=" PRINT_PTR, (void *)exception_object, (void *)frameInfo.start_ip, @@ -234,6 +240,20 @@ unwind_phase2(unw_context_t *uc, unw_cursor_t *cursor, _Unwind_Exception *except } #endif +// In CET enabled environment, we check return address stored in normal stack +// against return address stored in CET shadow stack, if the 2 addresses don't +// match, it means return address in normal stack has been corrupted, we return +// _URC_FATAL_PHASE2_ERROR. +#ifdef _LIBUNWIND_USE_CET + if (shadowStackTop != 0) { + unw_word_t retInNormalStack; + __unw_get_reg(cursor, UNW_REG_IP, &retInNormalStack); + unsigned long retInShadowStack = *( + unsigned long *)(shadowStackTop + __cet_ss_step_size * framesWalked); + if (retInNormalStack != retInShadowStack) + return _URC_FATAL_PHASE2_ERROR; + } +#endif ++framesWalked; // If there is a personality routine, tell it we are unwinding. if (frameInfo.handler != 0) { @@ -251,7 +271,7 @@ unwind_phase2(unw_context_t *uc, unw_cursor_t *cursor, _Unwind_Exception *except case _URC_CONTINUE_UNWIND: // Continue unwinding _LIBUNWIND_TRACE_UNWINDING( - "unwind_phase2(ex_ojb=%p): _URC_CONTINUE_UNWIND", + "unwind_phase2(ex_obj=%p): _URC_CONTINUE_UNWIND", (void *)exception_object); if (sp == exception_object->private_2) { // Phase 1 said we would stop at this frame, but we did not... @@ -261,7 +281,7 @@ unwind_phase2(unw_context_t *uc, unw_cursor_t *cursor, _Unwind_Exception *except break; case _URC_INSTALL_CONTEXT: _LIBUNWIND_TRACE_UNWINDING( - "unwind_phase2(ex_ojb=%p): _URC_INSTALL_CONTEXT", + "unwind_phase2(ex_obj=%p): _URC_INSTALL_CONTEXT", (void *)exception_object); // Personality routine says to transfer control to landing pad. // We may get control back if landing pad calls _Unwind_Resume(). @@ -269,7 +289,7 @@ unwind_phase2(unw_context_t *uc, unw_cursor_t *cursor, _Unwind_Exception *except unw_word_t pc; __unw_get_reg(cursor, UNW_REG_IP, &pc); __unw_get_reg(cursor, UNW_REG_SP, &sp); - _LIBUNWIND_TRACE_UNWINDING("unwind_phase2(ex_ojb=%p): re-entering " + _LIBUNWIND_TRACE_UNWINDING("unwind_phase2(ex_obj=%p): re-entering " "user code with ip=0x%" PRIxPTR ", sp=0x%" PRIxPTR, (void *)exception_object, pc, sp); @@ -302,14 +322,15 @@ unwind_phase2_forced(unw_context_t *uc, unw_cursor_t *cursor, // frame walked is unwind_phase2_forced. unsigned framesWalked = 1; // Walk each frame until we reach where search phase said to stop - while (__unw_step(cursor) > 0) { + while (__unw_step_stage2(cursor) > 0) { // Update info about this frame. unw_proc_info_t frameInfo; if (__unw_get_proc_info(cursor, &frameInfo) != UNW_ESUCCESS) { - _LIBUNWIND_TRACE_UNWINDING("unwind_phase2_forced(ex_ojb=%p): __unw_step " - "failed => _URC_END_OF_STACK", - (void *)exception_object); + _LIBUNWIND_TRACE_UNWINDING( + "unwind_phase2_forced(ex_obj=%p): __unw_get_proc_info " + "failed => _URC_END_OF_STACK", + (void *)exception_object); return _URC_FATAL_PHASE2_ERROR; } @@ -324,7 +345,7 @@ unwind_phase2_forced(unw_context_t *uc, unw_cursor_t *cursor, (frameInfo.start_ip + (size_t)offset > frameInfo.end_ip)) functionName = ".anonymous."; _LIBUNWIND_TRACE_UNWINDING( - "unwind_phase2_forced(ex_ojb=%p): start_ip=0x%" PRIxPTR + "unwind_phase2_forced(ex_obj=%p): start_ip=0x%" PRIxPTR ", func=%s, lsda=0x%" PRIxPTR ", personality=0x%" PRIxPTR, (void *)exception_object, frameInfo.start_ip, functionName, frameInfo.lsda, frameInfo.handler); @@ -338,11 +359,11 @@ unwind_phase2_forced(unw_context_t *uc, unw_cursor_t *cursor, (*stop)(1, action, exception_object->exception_class, exception_object, (struct _Unwind_Context *)(cursor), stop_parameter); _LIBUNWIND_TRACE_UNWINDING( - "unwind_phase2_forced(ex_ojb=%p): stop function returned %d", + "unwind_phase2_forced(ex_obj=%p): stop function returned %d", (void *)exception_object, stopResult); if (stopResult != _URC_NO_REASON) { _LIBUNWIND_TRACE_UNWINDING( - "unwind_phase2_forced(ex_ojb=%p): stopped by stop function", + "unwind_phase2_forced(ex_obj=%p): stopped by stop function", (void *)exception_object); return _URC_FATAL_PHASE2_ERROR; } @@ -353,21 +374,21 @@ unwind_phase2_forced(unw_context_t *uc, unw_cursor_t *cursor, _Unwind_Personality_Fn p = (_Unwind_Personality_Fn)(intptr_t)(frameInfo.handler); _LIBUNWIND_TRACE_UNWINDING( - "unwind_phase2_forced(ex_ojb=%p): calling personality function %p", + "unwind_phase2_forced(ex_obj=%p): calling personality function %p", (void *)exception_object, (void *)(uintptr_t)p); _Unwind_Reason_Code personalityResult = (*p)(1, action, exception_object->exception_class, exception_object, (struct _Unwind_Context *)(cursor)); switch (personalityResult) { case _URC_CONTINUE_UNWIND: - _LIBUNWIND_TRACE_UNWINDING("unwind_phase2_forced(ex_ojb=%p): " + _LIBUNWIND_TRACE_UNWINDING("unwind_phase2_forced(ex_obj=%p): " "personality returned " "_URC_CONTINUE_UNWIND", (void *)exception_object); // Destructors called, continue unwinding break; case _URC_INSTALL_CONTEXT: - _LIBUNWIND_TRACE_UNWINDING("unwind_phase2_forced(ex_ojb=%p): " + _LIBUNWIND_TRACE_UNWINDING("unwind_phase2_forced(ex_obj=%p): " "personality returned " "_URC_INSTALL_CONTEXT", (void *)exception_object); @@ -376,7 +397,7 @@ unwind_phase2_forced(unw_context_t *uc, unw_cursor_t *cursor, break; default: // Personality routine returned an unknown result code. - _LIBUNWIND_TRACE_UNWINDING("unwind_phase2_forced(ex_ojb=%p): " + _LIBUNWIND_TRACE_UNWINDING("unwind_phase2_forced(ex_obj=%p): " "personality returned %d, " "_URC_FATAL_PHASE2_ERROR", (void *)exception_object, personalityResult); @@ -387,7 +408,7 @@ unwind_phase2_forced(unw_context_t *uc, unw_cursor_t *cursor, // Call stop function one last time and tell it we've reached the end // of the stack. - _LIBUNWIND_TRACE_UNWINDING("unwind_phase2_forced(ex_ojb=%p): calling stop " + _LIBUNWIND_TRACE_UNWINDING("unwind_phase2_forced(ex_obj=%p): calling stop " "function with _UA_END_OF_STACK", (void *)exception_object); _Unwind_Action lastAction = @@ -434,7 +455,7 @@ _Unwind_RaiseException(_Unwind_Exception *exception_object) { /// may force a jump to a landing pad in that function, the landing /// pad code may then call _Unwind_Resume() to continue with the /// unwinding. Note: the call to _Unwind_Resume() is from compiler -/// geneated user code. All other _Unwind_* routines are called +/// generated user code. All other _Unwind_* routines are called /// by the C++ runtime __cxa_* routines. /// /// Note: re-throwing an exception (as opposed to continuing the unwind) diff --git a/contrib/subrepo-cheri-libunwind/src/UnwindRegistersRestore.S b/contrib/subrepo-cheri-libunwind/src/UnwindRegistersRestore.S index 88c76c887644..4b26183fa02f 100644 --- a/contrib/subrepo-cheri-libunwind/src/UnwindRegistersRestore.S +++ b/contrib/subrepo-cheri-libunwind/src/UnwindRegistersRestore.S @@ -9,6 +9,12 @@ #include "assembly.h" #include "__libunwind_config.h" +#define FROM_0_TO_15 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15 +#define FROM_16_TO_31 16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31 + +#define FROM_0_TO_31 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31 +#define FROM_32_TO_63 32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63 + #if defined(_AIX) .toc #else @@ -286,9 +292,20 @@ DEFINE_LIBUNWIND_FUNCTION(_ZN9libunwind15Registers_ppc646jumptoEv) addi 4, 3, PPC64_OFFS_FP // load VS register +#ifdef __LITTLE_ENDIAN__ +// For little-endian targets, we need a swap since lxvd2x will load the register +// in the incorrect doubleword order. +// FIXME: when supporting targets older than Power9 on LE is no longer required, +// this can be changed to simply `lxv n, (16 * n)(4)`. +#define PPC64_LVS(n) \ + lxvd2x n, 0, 4 ;\ + xxswapd n, n ;\ + addi 4, 4, 16 +#else #define PPC64_LVS(n) \ lxvd2x n, 0, 4 ;\ addi 4, 4, 16 +#endif // restore the first 32 VS regs (and also all floating point regs) PPC64_LVS(0) @@ -324,9 +341,16 @@ DEFINE_LIBUNWIND_FUNCTION(_ZN9libunwind15Registers_ppc646jumptoEv) PPC64_LVS(30) PPC64_LVS(31) +#ifdef __LITTLE_ENDIAN__ +#define PPC64_CLVS_RESTORE(n) \ + addi 4, 3, PPC64_OFFS_FP + n * 16 ;\ + lxvd2x n, 0, 4 ;\ + xxswapd n, n +#else #define PPC64_CLVS_RESTORE(n) \ addi 4, 3, PPC64_OFFS_FP + n * 16 ;\ lxvd2x n, 0, 4 +#endif #if !defined(_AIX) // use VRSAVE to conditionally restore the remaining VS regs, that are @@ -539,7 +563,7 @@ DEFINE_LIBUNWIND_FUNCTION(_ZN9libunwind13Registers_ppc6jumptoEv) // thread_state pointer is in r3 // - // restore integral registerrs + // restore integral registers // skip r0 for now // skip r1 for now lwz 2, 16(3) @@ -1187,38 +1211,9 @@ DEFINE_LIBUNWIND_FUNCTION(_ZN9libunwind21Registers_mips_newabi6jumptoEv) .set noreorder .set nomacro #ifdef __mips_hard_float - ldc1 $f0, (8 * 35)($4) - ldc1 $f1, (8 * 36)($4) - ldc1 $f2, (8 * 37)($4) - ldc1 $f3, (8 * 38)($4) - ldc1 $f4, (8 * 39)($4) - ldc1 $f5, (8 * 40)($4) - ldc1 $f6, (8 * 41)($4) - ldc1 $f7, (8 * 42)($4) - ldc1 $f8, (8 * 43)($4) - ldc1 $f9, (8 * 44)($4) - ldc1 $f10, (8 * 45)($4) - ldc1 $f11, (8 * 46)($4) - ldc1 $f12, (8 * 47)($4) - ldc1 $f13, (8 * 48)($4) - ldc1 $f14, (8 * 49)($4) - ldc1 $f15, (8 * 50)($4) - ldc1 $f16, (8 * 51)($4) - ldc1 $f17, (8 * 52)($4) - ldc1 $f18, (8 * 53)($4) - ldc1 $f19, (8 * 54)($4) - ldc1 $f20, (8 * 55)($4) - ldc1 $f21, (8 * 56)($4) - ldc1 $f22, (8 * 57)($4) - ldc1 $f23, (8 * 58)($4) - ldc1 $f24, (8 * 59)($4) - ldc1 $f25, (8 * 60)($4) - ldc1 $f26, (8 * 61)($4) - ldc1 $f27, (8 * 62)($4) - ldc1 $f28, (8 * 63)($4) - ldc1 $f29, (8 * 64)($4) - ldc1 $f30, (8 * 65)($4) - ldc1 $f31, (8 * 66)($4) + .irp i,FROM_0_TO_31 + ldc1 $f\i, (280+8*\i)($4) + .endr #endif // restore hi and lo ld $8, (8 * 33)($4) @@ -1230,32 +1225,9 @@ DEFINE_LIBUNWIND_FUNCTION(_ZN9libunwind21Registers_mips_newabi6jumptoEv) ld $2, (8 * 2)($4) ld $3, (8 * 3)($4) // skip a0 for now - ld $5, (8 * 5)($4) - ld $6, (8 * 6)($4) - ld $7, (8 * 7)($4) - ld $8, (8 * 8)($4) - ld $9, (8 * 9)($4) - ld $10, (8 * 10)($4) - ld $11, (8 * 11)($4) - ld $12, (8 * 12)($4) - ld $13, (8 * 13)($4) - ld $14, (8 * 14)($4) - ld $15, (8 * 15)($4) - ld $16, (8 * 16)($4) - ld $17, (8 * 17)($4) - ld $18, (8 * 18)($4) - ld $19, (8 * 19)($4) - ld $20, (8 * 20)($4) - ld $21, (8 * 21)($4) - ld $22, (8 * 22)($4) - ld $23, (8 * 23)($4) - ld $24, (8 * 24)($4) - ld $25, (8 * 25)($4) - ld $26, (8 * 26)($4) - ld $27, (8 * 27)($4) - ld $28, (8 * 28)($4) - ld $29, (8 * 29)($4) - ld $30, (8 * 30)($4) + .irp i,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30 + ld $\i, (8 * \i)($4) + .endr // load new pc into ra ld $31, (8 * 32)($4) // jump to ra, load a0 in the delay slot @@ -1334,19 +1306,19 @@ DEFINE_LIBUNWIND_FUNCTION(_ZN9libunwind15Registers_sparc6jumptoEv) #elif defined(__riscv) -.macro restore_fpr num +.macro restore_fpr num, ctxreg #ifdef __CHERI_PURE_CAPABILITY__ - cfld f\num, (__SIZEOF_CHERI_CAPABILITY__ * 32 + 8 * \num)(ca0) + cfld f\num, (RISCV_FOFFSET + RISCV_FSIZE * \num)(c\ctxreg) #else - FLOAD f\num, (8 * 32 + 8 * \num)(a0) + FLOAD f\num, (RISCV_FOFFSET + RISCV_FSIZE * \num)(\ctxreg) #endif .endm -.macro restore_gpr num +.macro restore_gpr num, ctxreg #ifdef __CHERI_PURE_CAPABILITY__ - clc c\num, (__SIZEOF_CHERI_CAPABILITY__ * \num)(ca0) + clc c\num, (__SIZEOF_CHERI_CAPABILITY__ * \num)(c\ctxreg) #else - ILOAD x\num, (8 * \num)(a0) + ILOAD x\num, (RISCV_ISIZE * \num)(\ctxreg) #endif .endm @@ -1358,78 +1330,26 @@ DEFINE_LIBUNWIND_FUNCTION(_ZN9libunwind15Registers_sparc6jumptoEv) // .p2align 2 DEFINE_LIBUNWIND_FUNCTION(_ZN9libunwind15Registers_riscv6jumptoEv) -#if defined(__riscv_flen) - restore_fpr 0 - restore_fpr 1 - restore_fpr 2 - restore_fpr 3 - restore_fpr 4 - restore_fpr 5 - restore_fpr 6 - restore_fpr 7 - restore_fpr 8 - restore_fpr 9 - restore_fpr 10 - restore_fpr 11 - restore_fpr 12 - restore_fpr 13 - restore_fpr 14 - restore_fpr 15 - restore_fpr 16 - restore_fpr 17 - restore_fpr 18 - restore_fpr 19 - restore_fpr 20 - restore_fpr 21 - restore_fpr 22 - restore_fpr 23 - restore_fpr 24 - restore_fpr 25 - restore_fpr 26 - restore_fpr 27 - restore_fpr 28 - restore_fpr 29 - restore_fpr 30 - restore_fpr 31 -#endif +# if defined(__riscv_flen) + .irp i,FROM_0_TO_31 + restore_fpr \i, a0 + .endr +# endif // x0 is zero #ifdef __CHERI_PURE_CAPABILITY__ clc c1, (__SIZEOF_CHERI_CAPABILITY__ * 0)(ca0) // restore pc into ra #else - ILOAD x1, (8 * 0)(a0) // restore pc into ra + ILOAD x1, (RISCV_ISIZE * 0)(a0) // restore pc into ra #endif - restore_gpr 2 - restore_gpr 3 - restore_gpr 4 - restore_gpr 5 - restore_gpr 6 - restore_gpr 7 - restore_gpr 8 - restore_gpr 9 + .irp i,2,3,4,5,6,7,8,9 + restore_gpr \i, a0 + .endr // skip a0 for now - restore_gpr 11 - restore_gpr 12 - restore_gpr 13 - restore_gpr 14 - restore_gpr 15 - restore_gpr 16 - restore_gpr 17 - restore_gpr 18 - restore_gpr 19 - restore_gpr 20 - restore_gpr 21 - restore_gpr 22 - restore_gpr 23 - restore_gpr 24 - restore_gpr 25 - restore_gpr 26 - restore_gpr 27 - restore_gpr 28 - restore_gpr 29 - restore_gpr 30 - restore_gpr 31 - restore_gpr 10 // restore a0 + .irp i,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31 + restore_gpr \i, a0 + .endr + restore_gpr 10, a0 // restore a0 #ifdef __CHERI_PURE_CAPABILITY__ cret // jump to cra @@ -1452,22 +1372,9 @@ DEFINE_LIBUNWIND_FUNCTION(_ZN9libunwind15Registers_s390x6jumptoEv) lg %r1, 8(%r2) // Restore FPRs - ld %f0, 144(%r2) - ld %f1, 152(%r2) - ld %f2, 160(%r2) - ld %f3, 168(%r2) - ld %f4, 176(%r2) - ld %f5, 184(%r2) - ld %f6, 192(%r2) - ld %f7, 200(%r2) - ld %f8, 208(%r2) - ld %f9, 216(%r2) - ld %f10, 224(%r2) - ld %f11, 232(%r2) - ld %f12, 240(%r2) - ld %f13, 248(%r2) - ld %f14, 256(%r2) - ld %f15, 264(%r2) + .irp i,FROM_0_TO_15 + ld %f\i, (144+8*\i)(%r2) + .endr // Restore GPRs - skipping %r0 and %r1 lmg %r2, %r15, 32(%r2) @@ -1475,6 +1382,36 @@ DEFINE_LIBUNWIND_FUNCTION(_ZN9libunwind15Registers_s390x6jumptoEv) // Return to PSWA (was loaded into %r1 above) br %r1 +#elif defined(__loongarch__) && __loongarch_grlen == 64 + +// +// void libunwind::Registers_loongarch::jumpto() +// +// On entry: +// thread_state pointer is in $a0($r4) +// + .p2align 2 +DEFINE_LIBUNWIND_FUNCTION(_ZN9libunwind19Registers_loongarch6jumptoEv) +# if __loongarch_frlen == 64 + .irp i,FROM_0_TO_31 + fld.d $f\i, $a0, (8 * 33 + 8 * \i) + .endr +# endif + + // $r0 is zero + .irp i,1,2,3 + ld.d $r\i, $a0, (8 * \i) + .endr + // skip $a0 for now + .irp i,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31 + ld.d $r\i, $a0, (8 * \i) + .endr + + ld.d $ra, $a0, (8 * 32) // load new pc into $ra + ld.d $a0, $a0, (8 * 4) // restore $a0 last + + jr $ra + #endif #endif /* !defined(__USING_SJLJ_EXCEPTIONS__) */ diff --git a/contrib/subrepo-cheri-libunwind/src/UnwindRegistersSave.S b/contrib/subrepo-cheri-libunwind/src/UnwindRegistersSave.S index 8ce6439fd915..3008dc125616 100644 --- a/contrib/subrepo-cheri-libunwind/src/UnwindRegistersSave.S +++ b/contrib/subrepo-cheri-libunwind/src/UnwindRegistersSave.S @@ -9,6 +9,12 @@ #include "assembly.h" #include "__libunwind_config.h" +#define FROM_0_TO_15 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15 +#define FROM_16_TO_31 16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31 + +#define FROM_0_TO_31 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31 +#define FROM_32_TO_63 32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63 + #if defined(_AIX) .toc #else @@ -359,37 +365,9 @@ DEFINE_LIBUNWIND_FUNCTION(__unw_getcontext) .set noat .set noreorder .set nomacro - sd $1, (8 * 1)($4) - sd $2, (8 * 2)($4) - sd $3, (8 * 3)($4) - sd $4, (8 * 4)($4) - sd $5, (8 * 5)($4) - sd $6, (8 * 6)($4) - sd $7, (8 * 7)($4) - sd $8, (8 * 8)($4) - sd $9, (8 * 9)($4) - sd $10, (8 * 10)($4) - sd $11, (8 * 11)($4) - sd $12, (8 * 12)($4) - sd $13, (8 * 13)($4) - sd $14, (8 * 14)($4) - sd $15, (8 * 15)($4) - sd $16, (8 * 16)($4) - sd $17, (8 * 17)($4) - sd $18, (8 * 18)($4) - sd $19, (8 * 19)($4) - sd $20, (8 * 20)($4) - sd $21, (8 * 21)($4) - sd $22, (8 * 22)($4) - sd $23, (8 * 23)($4) - sd $24, (8 * 24)($4) - sd $25, (8 * 25)($4) - sd $26, (8 * 26)($4) - sd $27, (8 * 27)($4) - sd $28, (8 * 28)($4) - sd $29, (8 * 29)($4) - sd $30, (8 * 30)($4) - sd $31, (8 * 31)($4) + .irp i,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31 + sd $\i, (8 * \i)($4) + .endr # Store return address to pc sd $31, (8 * 32)($4) # hi and lo @@ -398,38 +376,9 @@ DEFINE_LIBUNWIND_FUNCTION(__unw_getcontext) mflo $8 sd $8, (8 * 34)($4) #ifdef __mips_hard_float - sdc1 $f0, (8 * 35)($4) - sdc1 $f1, (8 * 36)($4) - sdc1 $f2, (8 * 37)($4) - sdc1 $f3, (8 * 38)($4) - sdc1 $f4, (8 * 39)($4) - sdc1 $f5, (8 * 40)($4) - sdc1 $f6, (8 * 41)($4) - sdc1 $f7, (8 * 42)($4) - sdc1 $f8, (8 * 43)($4) - sdc1 $f9, (8 * 44)($4) - sdc1 $f10, (8 * 45)($4) - sdc1 $f11, (8 * 46)($4) - sdc1 $f12, (8 * 47)($4) - sdc1 $f13, (8 * 48)($4) - sdc1 $f14, (8 * 49)($4) - sdc1 $f15, (8 * 50)($4) - sdc1 $f16, (8 * 51)($4) - sdc1 $f17, (8 * 52)($4) - sdc1 $f18, (8 * 53)($4) - sdc1 $f19, (8 * 54)($4) - sdc1 $f20, (8 * 55)($4) - sdc1 $f21, (8 * 56)($4) - sdc1 $f22, (8 * 57)($4) - sdc1 $f23, (8 * 58)($4) - sdc1 $f24, (8 * 59)($4) - sdc1 $f25, (8 * 60)($4) - sdc1 $f26, (8 * 61)($4) - sdc1 $f27, (8 * 62)($4) - sdc1 $f28, (8 * 63)($4) - sdc1 $f29, (8 * 64)($4) - sdc1 $f30, (8 * 65)($4) - sdc1 $f31, (8 * 66)($4) + .irp i,FROM_0_TO_31 + sdc1 $f\i, (280+8*\i)($4) + .endr #endif jr $31 # return UNW_ESUCCESS @@ -519,9 +468,20 @@ DEFINE_LIBUNWIND_FUNCTION(__unw_getcontext) addi 4, 3, PPC64_OFFS_FP // store VS register +#ifdef __LITTLE_ENDIAN__ +// For little-endian targets, we need a swap since stxvd2x will store the +// register in the incorrect doubleword order. +// FIXME: when supporting targets older than Power9 on LE is no longer required +// this can be changed to simply `stxv n, 16 * n(4)`. +#define PPC64_STVS(n) \ + xxswapd n, n ;\ + stxvd2x n, 0, 4 ;\ + addi 4, 4, 16 +#else #define PPC64_STVS(n) \ stxvd2x n, 0, 4 ;\ addi 4, 4, 16 +#endif PPC64_STVS(0) PPC64_STVS(1) @@ -1275,19 +1235,19 @@ DEFINE_LIBUNWIND_FUNCTION(__unw_getcontext) #elif defined(__riscv) -.macro save_fpr num +.macro save_fpr num, ctxreg #ifdef __CHERI_PURE_CAPABILITY__ - cfsd f\num, (__SIZEOF_CHERI_CAPABILITY__ * 32 + 8 * \num)(ca0) + cfsd f\num, (RISCV_FOFFSET + RISCV_FSIZE * \num)(c\ctxreg) #else - FSTORE f\num, (8 * 32 + 8 * \num)(a0) + FSTORE f\num, (RISCV_FOFFSET + RISCV_FSIZE * \num)(\ctxreg) #endif .endm -.macro save_gpr num +.macro save_gpr num, ctxreg #ifdef __CHERI_PURE_CAPABILITY__ - csc c\num, (__SIZEOF_CHERI_CAPABILITY__ * \num)(ca0) + csc c\num, (__SIZEOF_CHERI_CAPABILITY__ * \num)(c\ctxreg) #else - ISTORE x\num, (8 * \num)(a0) + ISTORE x\num, (RISCV_ISIZE * \num)(\ctxreg) #endif .endm @@ -1298,78 +1258,20 @@ DEFINE_LIBUNWIND_FUNCTION(__unw_getcontext) # thread_state pointer is in a0 # DEFINE_LIBUNWIND_FUNCTION(__unw_getcontext) - // x0 is zero (index 0 is used for PC) #ifdef __CHERI_PURE_CAPABILITY__ csc c1, (__SIZEOF_CHERI_CAPABILITY__ * 0)(ca0) // store ra as pc #else - ISTORE x1, (8 * 0)(a0) // store ra as pc + ISTORE x1, (RISCV_ISIZE * 0)(a0) // store ra as pc #endif - save_gpr 1 - save_gpr 2 - save_gpr 3 - save_gpr 4 - save_gpr 5 - save_gpr 6 - save_gpr 7 - save_gpr 8 - save_gpr 9 - save_gpr 10 - save_gpr 11 - save_gpr 12 - save_gpr 13 - save_gpr 14 - save_gpr 15 - save_gpr 16 - save_gpr 17 - save_gpr 18 - save_gpr 19 - save_gpr 20 - save_gpr 21 - save_gpr 22 - save_gpr 23 - save_gpr 24 - save_gpr 25 - save_gpr 26 - save_gpr 27 - save_gpr 28 - save_gpr 29 - save_gpr 30 - save_gpr 31 + .irp i,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31 + save_gpr \i, a0 + .endr # if defined(__riscv_flen) - save_fpr 0 - save_fpr 1 - save_fpr 2 - save_fpr 3 - save_fpr 4 - save_fpr 5 - save_fpr 6 - save_fpr 7 - save_fpr 8 - save_fpr 9 - save_fpr 10 - save_fpr 11 - save_fpr 12 - save_fpr 13 - save_fpr 14 - save_fpr 15 - save_fpr 16 - save_fpr 17 - save_fpr 18 - save_fpr 19 - save_fpr 20 - save_fpr 21 - save_fpr 22 - save_fpr 23 - save_fpr 24 - save_fpr 25 - save_fpr 26 - save_fpr 27 - save_fpr 28 - save_fpr 29 - save_fpr 30 - save_fpr 31 -#endif + .irp i,FROM_0_TO_31 + save_fpr \i, a0 + .endr +# endif li a0, 0 // return UNW_ESUCCESS #ifdef __CHERI_PURE_CAPABILITY__ @@ -1400,27 +1302,37 @@ DEFINE_LIBUNWIND_FUNCTION(__unw_getcontext) stg %r14, 8(%r2) // Save FPRs - std %f0, 144(%r2) - std %f1, 152(%r2) - std %f2, 160(%r2) - std %f3, 168(%r2) - std %f4, 176(%r2) - std %f5, 184(%r2) - std %f6, 192(%r2) - std %f7, 200(%r2) - std %f8, 208(%r2) - std %f9, 216(%r2) - std %f10, 224(%r2) - std %f11, 232(%r2) - std %f12, 240(%r2) - std %f13, 248(%r2) - std %f14, 256(%r2) - std %f15, 264(%r2) + .irp i,FROM_0_TO_15 + std %f\i, (144+8*\i)(%r2) + .endr // Return UNW_ESUCCESS lghi %r2, 0 br %r14 +#elif defined(__loongarch__) && __loongarch_grlen == 64 + +# +# extern int __unw_getcontext(unw_context_t* thread_state) +# +# On entry: +# thread_state pointer is in $a0($r4) +# +DEFINE_LIBUNWIND_FUNCTION(__unw_getcontext) + .irp i,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31 + st.d $r\i, $a0, (8*\i) + .endr + st.d $r1, $a0, (8 * 32) // store $ra to pc + +# if __loongarch_frlen == 64 + .irp i,FROM_0_TO_31 + fst.d $f\i, $a0, (8 * 33 + 8 * \i) + .endr +# endif + + move $a0, $zero // UNW_ESUCCESS + jr $ra + #endif WEAK_ALIAS(__unw_getcontext, unw_getcontext) diff --git a/contrib/subrepo-cheri-libunwind/src/Unwind_AIXExtras.cpp b/contrib/subrepo-cheri-libunwind/src/Unwind_AIXExtras.cpp index 7e47f70186e7..66194ab4a16b 100644 --- a/contrib/subrepo-cheri-libunwind/src/Unwind_AIXExtras.cpp +++ b/contrib/subrepo-cheri-libunwind/src/Unwind_AIXExtras.cpp @@ -38,7 +38,7 @@ char *getFuncNameFromTBTable(uintptr_t Pc, uint16_t &NameLen, if (TBTable->tb.fixedparms || TBTable->tb.floatparms) p++; - // If the tb_offset field exisits, get the offset from the start of + // If the tb_offset field exists, get the offset from the start of // the function to pc. Skip the field. if (TBTable->tb.has_tboff) { unw_word_t StartIp = diff --git a/contrib/subrepo-cheri-libunwind/src/Unwind_AppleExtras.cpp b/contrib/subrepo-cheri-libunwind/src/Unwind_AppleExtras.cpp deleted file mode 100644 index ffb49a89e54f..000000000000 --- a/contrib/subrepo-cheri-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/contrib/subrepo-cheri-libunwind/src/assembly.h b/contrib/subrepo-cheri-libunwind/src/assembly.h index 207b231770cf..8da72ce22c78 100644 --- a/contrib/subrepo-cheri-libunwind/src/assembly.h +++ b/contrib/subrepo-cheri-libunwind/src/assembly.h @@ -35,8 +35,12 @@ #elif defined(__APPLE__) && defined(__aarch64__) #define SEPARATOR %% #elif defined(__riscv) +#ifdef __CHERI_PURE_CAPABILITY__ +# define RISCV_FOFFSET (__SIZEOF_CHERI_CAPABILITY__ * 32) +#else # define RISCV_ISIZE (__riscv_xlen / 8) # define RISCV_FOFFSET (RISCV_ISIZE * 32) +#endif # if defined(__riscv_flen) # define RISCV_FSIZE (__riscv_flen / 8) # endif diff --git a/contrib/subrepo-cheri-libunwind/src/config.h b/contrib/subrepo-cheri-libunwind/src/config.h index a4b2f588aa25..deab4d9ab950 100644 --- a/contrib/subrepo-cheri-libunwind/src/config.h +++ b/contrib/subrepo-cheri-libunwind/src/config.h @@ -115,7 +115,7 @@ #if defined(__i386__) || defined(__x86_64__) || defined(__powerpc__) || \ (!defined(__APPLE__) && defined(__arm__)) || defined(__aarch64__) || \ defined(__mips__) || defined(__riscv) || defined(__hexagon__) || \ - defined(__sparc__) || defined(__s390x__) + defined(__sparc__) || defined(__s390x__) || defined(__loongarch__) #if !defined(_LIBUNWIND_BUILD_SJLJ_APIS) #define _LIBUNWIND_BUILD_ZERO_COST_APIS #endif @@ -176,10 +176,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/contrib/subrepo-cheri-libunwind/src/libunwind.cpp b/contrib/subrepo-cheri-libunwind/src/libunwind.cpp index 83648894a740..836ef5a9498d 100644 --- a/contrib/subrepo-cheri-libunwind/src/libunwind.cpp +++ b/contrib/subrepo-cheri-libunwind/src/libunwind.cpp @@ -98,6 +98,8 @@ _LIBUNWIND_HIDDEN int __unw_init_local(unw_cursor_t *cursor, # define REGISTER_KIND Registers_ve #elif defined(__s390x__) # define REGISTER_KIND Registers_s390x +#elif defined(__loongarch__) && __loongarch_grlen == 64 +#define REGISTER_KIND Registers_loongarch #else # error Architecture not supported #endif @@ -138,7 +140,7 @@ _LIBUNWIND_HIDDEN int __unw_set_reg(unw_cursor_t *cursor, unw_regnum_t regNum, AbstractUnwindCursor *co = (AbstractUnwindCursor *)cursor; if (co->validReg(regNum)) { co->setReg(regNum, (pint_t)value); - // specical case altering IP to re-find info (being called by personality + // special case altering IP to re-find info (being called by personality // function) if (regNum == UNW_REG_IP) { unw_proc_info_t info; @@ -202,6 +204,15 @@ _LIBUNWIND_HIDDEN int __unw_step(unw_cursor_t *cursor) { } _LIBUNWIND_WEAK_ALIAS(__unw_step, unw_step) +// Move cursor to next frame and for stage2 of unwinding. +// This resets MTE tags of tagged frames to zero. +extern "C" _LIBUNWIND_HIDDEN int __unw_step_stage2(unw_cursor_t *cursor) { + _LIBUNWIND_TRACE_API("__unw_step_stage2(cursor=%p)", + static_cast(cursor)); + AbstractUnwindCursor *co = (AbstractUnwindCursor *)cursor; + return co->step(true); +} + /// Get unwind info at cursor position in stack frame. _LIBUNWIND_HIDDEN int __unw_get_proc_info(unw_cursor_t *cursor, unw_proc_info_t *info) { @@ -359,7 +370,87 @@ void __unw_remove_dynamic_eh_frame_section(unw_word_t eh_frame_start) { #endif // defined(_LIBUNWIND_SUPPORT_DWARF_UNWIND) #endif // !defined(__USING_SJLJ_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/contrib/subrepo-cheri-libunwind/src/libunwind_ext.h b/contrib/subrepo-cheri-libunwind/src/libunwind_ext.h index 82d57af0a864..1a7b4a36e967 100644 --- a/contrib/subrepo-cheri-libunwind/src/libunwind_ext.h +++ b/contrib/subrepo-cheri-libunwind/src/libunwind_ext.h @@ -60,6 +60,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/contrib/subrepo-cheri-libunwind/test/CMakeLists.txt b/contrib/subrepo-cheri-libunwind/test/CMakeLists.txt index 66db183a9c60..fda3ccd72c7e 100644 --- a/contrib/subrepo-cheri-libunwind/test/CMakeLists.txt +++ b/contrib/subrepo-cheri-libunwind/test/CMakeLists.txt @@ -44,15 +44,15 @@ set(_LIBUNWIND_TEST_BINARIES) option(LIBUINWIND_BUILD_STATIC_TEST_BINARIES "build static test binaries" ON) foreach(_test_path ${_LIBUNWIND_TESTS}) get_filename_component(_test "${_test_path}" NAME_WE) - if ("${_test}" MATCHES ".*bad_unwind_info.*") + if ("${_test}" MATCHES ".*bad_unwind_info.*" OR "${_test}" MATCHES ".*scalable_vectors.*") continue() # Only works for a subset of architectures endif() string(REGEX MATCH ".*exceptions.*" _has_exceptions ${_test}) if (_has_exceptions) - set(_common_libs ${_cxx_abi_link_flag} -lpthread -lc -lpthread -ldl) + set(_common_libs unwind-headers ${_cxx_abi_link_flag} -lpthread -lc -lpthread -ldl) set(_common_flags -fexceptions) else() - set(_common_libs -lpthread -lc -lpthread -ldl) + set(_common_libs unwind-headers -lpthread -lc -lpthread -ldl) set(_common_flags -fno-exceptions) endif() foreach(_opt "" -O0 -O1 -O2 -O3) @@ -93,21 +93,11 @@ message(STATUS "TESTS: ${_LIBUNWIND_TEST_BINARIES}") add_custom_target(unwind-test-binaries DEPENDS ${_LIBUNWIND_TEST_BINARIES}) -if (NOT DEFINED LIBCXX_ENABLE_SHARED) - set(LIBCXX_ENABLE_SHARED ON) -endif() - pythonize_bool(LIBUNWIND_ENABLE_CET) -pythonize_bool(LIBCXX_ENABLE_SHARED) -pythonize_bool(LIBUNWIND_ENABLE_SHARED) pythonize_bool(LIBUNWIND_ENABLE_THREADS) pythonize_bool(LIBUNWIND_TEST_ENABLE_EXCEPTIONS) pythonize_bool(LIBUNWIND_USES_ARM_EHABI) -pythonize_bool(LIBUNWIND_USE_COMPILER_RT) -pythonize_bool(LIBUNWIND_BUILD_EXTERNAL_THREAD_LIBRARY) -set(LIBUNWIND_TARGET_INFO "libcxx.test.target_info.LocalTI" CACHE STRING - "TargetInfo to use when setting up test environment.") -set(LIBUNWIND_EXECUTOR "${Python3_EXECUTABLE} ${LIBUNWIND_LIBCXX_PATH}/utils/run.py" CACHE STRING +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!") diff --git a/contrib/subrepo-cheri-libunwind/test/bad_unwind_info.pass.cpp b/contrib/subrepo-cheri-libunwind/test/bad_unwind_info.pass.cpp index 06017d17ab57..b3284e8daed7 100644 --- a/contrib/subrepo-cheri-libunwind/test/bad_unwind_info.pass.cpp +++ b/contrib/subrepo-cheri-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/contrib/subrepo-cheri-libunwind/test/configs/apple-libunwind-backdeployment.cfg.in b/contrib/subrepo-cheri-libunwind/test/configs/apple-libunwind-backdeployment.cfg.in index d4777e2f6917..4484573801bd 100644 --- a/contrib/subrepo-cheri-libunwind/test/configs/apple-libunwind-backdeployment.cfg.in +++ b/contrib/subrepo-cheri-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/contrib/subrepo-cheri-libunwind/test/configs/cmake-bridge.cfg.in b/contrib/subrepo-cheri-libunwind/test/configs/cmake-bridge.cfg.in index 21768702f6d8..7860301c367f 100644 --- a/contrib/subrepo-cheri-libunwind/test/configs/cmake-bridge.cfg.in +++ b/contrib/subrepo-cheri-libunwind/test/configs/cmake-bridge.cfg.in @@ -20,8 +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.target_info = "@LIBUNWIND_TARGET_INFO@" +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@: diff --git a/contrib/subrepo-cheri-libunwind/test/configs/ibm-libunwind-shared.cfg.in b/contrib/subrepo-cheri-libunwind/test/configs/ibm-libunwind-shared.cfg.in index c3c0ddd5c726..c38d278ad2c9 100644 --- a/contrib/subrepo-cheri-libunwind/test/configs/ibm-libunwind-shared.cfg.in +++ b/contrib/subrepo-cheri-libunwind/test/configs/ibm-libunwind-shared.cfg.in @@ -5,7 +5,7 @@ lit_config.load_config(config, '@CMAKE_CURRENT_BINARY_DIR@/cmake-bridge.cfg') config.substitutions.append(('%{flags}', '')) config.substitutions.append(('%{compile_flags}', - '-nostdinc++ -I %{include} -I %{cxx-include}' + '-nostdinc++ -I %{include}' )) config.substitutions.append(('%{link_flags}', '-nostdlib++ -L %{lib} -lunwind -ldl -Wl,-bbigtoc' @@ -16,8 +16,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/contrib/subrepo-cheri-libunwind/test/configs/llvm-libunwind-merged.cfg.in b/contrib/subrepo-cheri-libunwind/test/configs/llvm-libunwind-merged.cfg.in index d01ee7470de7..218126073d40 100644 --- a/contrib/subrepo-cheri-libunwind/test/configs/llvm-libunwind-merged.cfg.in +++ b/contrib/subrepo-cheri-libunwind/test/configs/llvm-libunwind-merged.cfg.in @@ -33,8 +33,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/contrib/subrepo-cheri-libunwind/test/configs/llvm-libunwind-mingw.cfg.in b/contrib/subrepo-cheri-libunwind/test/configs/llvm-libunwind-mingw.cfg.in new file mode 100644 index 000000000000..33d061a3efc6 --- /dev/null +++ b/contrib/subrepo-cheri-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/contrib/subrepo-cheri-libunwind/test/configs/llvm-libunwind-shared.cfg.in b/contrib/subrepo-cheri-libunwind/test/configs/llvm-libunwind-shared.cfg.in index 72bf927407a7..0f91c2ec0222 100644 --- a/contrib/subrepo-cheri-libunwind/test/configs/llvm-libunwind-shared.cfg.in +++ b/contrib/subrepo-cheri-libunwind/test/configs/llvm-libunwind-shared.cfg.in @@ -33,8 +33,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/contrib/subrepo-cheri-libunwind/test/configs/llvm-libunwind-static.cfg.in b/contrib/subrepo-cheri-libunwind/test/configs/llvm-libunwind-static.cfg.in index d1003b9b55de..6ba2fbdaf8ac 100644 --- a/contrib/subrepo-cheri-libunwind/test/configs/llvm-libunwind-static.cfg.in +++ b/contrib/subrepo-cheri-libunwind/test/configs/llvm-libunwind-static.cfg.in @@ -36,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/contrib/subrepo-cheri-libunwind/test/forceunwind.pass.cpp b/contrib/subrepo-cheri-libunwind/test/forceunwind.pass.cpp index af5f234b8da6..8c26551b6d0b 100644 --- a/contrib/subrepo-cheri-libunwind/test/forceunwind.pass.cpp +++ b/contrib/subrepo-cheri-libunwind/test/forceunwind.pass.cpp @@ -15,6 +15,7 @@ // Basic test for _Unwind_ForcedUnwind. // See libcxxabi/test/forced_unwind* tests too. +#undef NDEBUG #include #include #include diff --git a/contrib/subrepo-cheri-libunwind/test/libunwind/__init__.py b/contrib/subrepo-cheri-libunwind/test/libunwind/__init__.py deleted file mode 100644 index e69de29bb2d1..000000000000 diff --git a/contrib/subrepo-cheri-libunwind/test/libunwind/test/__init__.py b/contrib/subrepo-cheri-libunwind/test/libunwind/test/__init__.py deleted file mode 100644 index e69de29bb2d1..000000000000 diff --git a/contrib/subrepo-cheri-libunwind/test/libunwind/test/config.py b/contrib/subrepo-cheri-libunwind/test/libunwind/test/config.py deleted file mode 100644 index 650e433a3da9..000000000000 --- a/contrib/subrepo-cheri-libunwind/test/libunwind/test/config.py +++ /dev/null @@ -1,111 +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 -# -#===----------------------------------------------------------------------===## -import os -import sys - -from libcxx.test.config import Configuration as LibcxxConfiguration - - -class Configuration(LibcxxConfiguration): - # pylint: disable=redefined-outer-name - def __init__(self, lit_config, config): - super(Configuration, self).__init__(lit_config, config) - self.libunwind_src_root = None - self.libunwind_obj_root = None - self.abi_library_root = None - self.libcxx_src_root = None - - def configure_src_root(self): - self.libunwind_src_root = (self.get_lit_conf('libunwind_src_root') - or os.path.dirname(self.config.test_source_root)) - self.libcxx_src_root = (self.get_lit_conf('libcxx_src_root') - or os.path.join(self.libunwind_src_root, '..', 'libcxx')) - - def configure_obj_root(self): - self.libunwind_obj_root = self.get_lit_conf('libunwind_obj_root') - super(Configuration, self).configure_obj_root() - - def has_cpp_feature(self, feature, required_value): - return int(self.cxx.dumpMacros().get('__cpp_' + feature, 0)) >= required_value - - def configure_features(self): - super(Configuration, self).configure_features() - if self.get_lit_bool('arm_ehabi', False): - self.config.available_features.add('libunwind-arm-ehabi') - - def configure_compile_flags(self): - # Stack unwinding tests need unwinding tables and these are not - # generated by default on all Targets. - self.cxx.compile_flags += ['-funwind-tables'] - # Make symbols available in the tests. - triple = self.get_lit_conf('target_triple', None) - if triple is not None and 'linux' in triple: - self.cxx.link_flags += ['-Wl,--export-dynamic'] - if not self.get_lit_bool('enable_threads', True): - self.cxx.compile_flags += ['-D_LIBUNWIND_HAS_NO_THREADS'] - self.config.available_features.add('libunwind-no-threads') - if self.get_lit_bool('x86_cet', False): - self.cxx.compile_flags += ['-fcf-protection=full'] - super(Configuration, self).configure_compile_flags() - - def configure_cxx_stdlib_under_test(self): - # We are always running libunwind against c++ library. Currently, - # all the tests only use the C++ ABI library so if possible we avoid - # linking against the full C++ standard library to avoid potentially - # pulling in another copy of libunwind. - self.cxx_stdlib_under_test = 'none' - - def configure_link_flags(self): - # Ensure that the currently built libunwind is be the first library - # in the search order. This is especially important for static linking. - if self.link_shared: - # dladdr needs libdl on Linux - self.cxx.link_flags += ['-L', os.path.join(self.libunwind_obj_root, "lib"), - '-lunwind', '-ldl'] - else: - libname = self.make_static_lib_name('unwind') - abs_path = os.path.join(self.libunwind_obj_root, "lib", libname) - assert os.path.exists(abs_path) and "static libunwind library does not exist", abs_path - self.cxx.link_flags += [abs_path] - - super(Configuration, self).configure_link_flags() - # Ensure that libunwind is always added to the linker flags - # This should be the case for most TargetInfo classes anyway but some - # of them don't add it. - self.cxx.link_flags += ['-nodefaultlibs', '-lc'] - # If we are building a static binary, we also need to add the compiler - # buitins library to the build since we are building with -nodefaultlibs. - if self.force_static_executable: - assert '-static' in self.cxx.link_flags # should be set by super() - rtlib = self.abi_library_root = self.get_lit_conf('runtime_library') - if not rtlib: - rtlib = self.cxx.getRtlibPath() - if not os.path.exists(rtlib): - self.lit_config.fatal("Cannot find compiler runtime library" + - " at expected path " + rtlib + ". Set" + - " -Druntime_library=.... to fix this.") - self.cxx.link_flags += [rtlib] - - print("LINKER FLAGS:", self.cxx.link_flags) - - def configure_compile_flags_header_includes(self): - libunwind_headers = self.get_lit_conf( - 'libunwind_headers', - os.path.join(self.libunwind_src_root, 'include')) - if not os.path.isdir(libunwind_headers): - self.lit_config.fatal("libunwind_headers='%s' is not a directory." - % libunwind_headers) - self.cxx.compile_flags += ['-I' + libunwind_headers] - - def configure_link_flags_cxx_library(self): - # libunwind tests should not link with libc++ - pass - - def configure_link_flags_abi_library(self): - # libunwind tests should not link with libc++abi - pass diff --git a/contrib/subrepo-cheri-libunwind/test/libunwind_01.pass.cpp b/contrib/subrepo-cheri-libunwind/test/libunwind_01.pass.cpp index 5f3a92cba5d3..82b94071ce86 100644 --- a/contrib/subrepo-cheri-libunwind/test/libunwind_01.pass.cpp +++ b/contrib/subrepo-cheri-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/contrib/subrepo-cheri-libunwind/test/libunwind_02.pass.cpp b/contrib/subrepo-cheri-libunwind/test/libunwind_02.pass.cpp index 37c571f22ed1..c4de36c0cdfe 100644 --- a/contrib/subrepo-cheri-libunwind/test/libunwind_02.pass.cpp +++ b/contrib/subrepo-cheri-libunwind/test/libunwind_02.pass.cpp @@ -10,6 +10,7 @@ // TODO: Figure out why this fails with Memory Sanitizer. // XFAIL: msan +#undef NDEBUG #include #include #include diff --git a/contrib/subrepo-cheri-libunwind/test/lit.cfg.py b/contrib/subrepo-cheri-libunwind/test/lit.cfg.py index 647464abe22d..ea4a9a75b4fd 100644 --- a/contrib/subrepo-cheri-libunwind/test/lit.cfg.py +++ b/contrib/subrepo-cheri-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/contrib/subrepo-cheri-libunwind/test/lit.site.cfg.in b/contrib/subrepo-cheri-libunwind/test/lit.site.cfg.in deleted file mode 100644 index 0d2575d4c9cf..000000000000 --- a/contrib/subrepo-cheri-libunwind/test/lit.site.cfg.in +++ /dev/null @@ -1,67 +0,0 @@ -@AUTO_GEN_COMMENT@ - -@SERIALIZED_LIT_PARAMS@ - -import os -import site - -config.cxx_under_test = "@CMAKE_CXX_COMPILER@" -config.project_obj_root = "@CMAKE_BINARY_DIR@" -config.install_root = "@CMAKE_BINARY_DIR@" -config.libunwind_src_root = "@LIBUNWIND_SOURCE_DIR@" -config.libunwind_obj_root = "@LIBUNWIND_BINARY_DIR@" -config.abi_library_root = "@LIBUNWIND_LIBRARY_DIR@" -config.cxx_abi = "@LIBUNWIND_CXX_ABI@" -config.cxx_abi_lib_path = "@LIBUNWIND_TEST_CXX_ABI_LIB_PATH@" -config.libcxx_src_root = "@LIBUNWIND_LIBCXX_PATH@" -config.libunwind_headers = "@LIBUNWIND_SOURCE_DIR@/include" -config.cxx_library_root = "@LIBUNWIND_LIBCXX_LIBRARY_PATH@" -config.llvm_unwinder = True -config.builtins_library = "@LIBUNWIND_BUILTINS_LIBRARY@" -config.enable_threads = @LIBUNWIND_ENABLE_THREADS@ -config.target_info = "@LIBUNWIND_TARGET_INFO@" -config.test_linker_flags = "@LIBUNWIND_TEST_LINKER_FLAGS@" -config.test_compiler_flags = "@LIBUNWIND_TEST_COMPILER_FLAGS@" -config.executor = "@LIBUNWIND_EXECUTOR@" -config.libunwind_shared = @LIBUNWIND_ENABLE_SHARED@ -config.enable_shared = @LIBCXX_ENABLE_SHARED@ -config.arm_ehabi = @LIBUNWIND_USES_ARM_EHABI@ -config.host_triple = "@LLVM_HOST_TRIPLE@" -config.sysroot = "@CMAKE_SYSROOT@" -config.gcc_toolchain = "@CMAKE_CXX_COMPILER_EXTERNAL_TOOLCHAIN@" -config.cxx_ext_threads = @LIBUNWIND_BUILD_EXTERNAL_THREAD_LIBRARY@ -# Avoid pulling in the C++ standard library and instead add -nodefaultlibs -config.cxx_stdlib_under_test = "cxx_default" -# Avoid the slow checks for locale support (we don't care about those features). -config.test_localization = False -config.x86_cet = @LIBUNWIND_ENABLE_CET@ - -site.addsitedir(os.path.join(config.libunwind_src_root, 'test')) -site.addsitedir(os.path.join(config.libcxx_src_root, 'utils')) - -# name: The name of this test suite. -config.name = 'libunwind' - -# suffixes: A list of file extensions to treat as test files. -config.suffixes = ['.cpp', '.s'] - -# test_source_root: The root path where tests are located. -config.test_source_root = os.path.join(config.libunwind_src_root, 'test') - -# Allow expanding substitutions that are based on other substitutions -config.recursiveExpansionLimit = 10 - -# Infer the test_exec_root from the build directory. -config.test_exec_root = os.path.join(config.libunwind_obj_root, 'test') - -import libcxx.test.format -config.test_format = libcxx.test.format.CxxStandardLibraryTest() - -lit_config.note('Using configuration variant: libunwind') -import libunwind.test.config -configuration = libunwind.test.config.Configuration(lit_config, config) -configuration.configure() -configuration.print_config_info() - -lit_config.warning("This is a legacy testing configuration which will be removed in LLVM 16. " - "Please use one of the configurations in libunwind/test/configs or define your own.") diff --git a/contrib/subrepo-cheri-libunwind/test/signal_frame.pass.cpp b/contrib/subrepo-cheri-libunwind/test/signal_frame.pass.cpp index b17804efa08c..e5409f6ce3d9 100644 --- a/contrib/subrepo-cheri-libunwind/test/signal_frame.pass.cpp +++ b/contrib/subrepo-cheri-libunwind/test/signal_frame.pass.cpp @@ -21,6 +21,11 @@ // are necessary to run this test. // UNSUPPORTED: target=powerpc{{(64)?}}-ibm-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 #include #include diff --git a/contrib/subrepo-cheri-libunwind/test/signal_unwind.pass.cpp b/contrib/subrepo-cheri-libunwind/test/signal_unwind.pass.cpp index 2ff50abbebb6..954a5d4ba3db 100644 --- a/contrib/subrepo-cheri-libunwind/test/signal_unwind.pass.cpp +++ b/contrib/subrepo-cheri-libunwind/test/signal_unwind.pass.cpp @@ -8,11 +8,12 @@ //===----------------------------------------------------------------------===// // 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 +#undef NDEBUG #include #include #include diff --git a/contrib/subrepo-cheri-libunwind/test/unw_getcontext.pass.cpp b/contrib/subrepo-cheri-libunwind/test/unw_getcontext.pass.cpp index 171ec933bfa7..74772f9e8dfb 100644 --- a/contrib/subrepo-cheri-libunwind/test/unw_getcontext.pass.cpp +++ b/contrib/subrepo-cheri-libunwind/test/unw_getcontext.pass.cpp @@ -7,6 +7,7 @@ // //===----------------------------------------------------------------------===// +#undef NDEBUG #include #include #include diff --git a/contrib/subrepo-cheri-libunwind/test/unw_resume.pass.cpp b/contrib/subrepo-cheri-libunwind/test/unw_resume.pass.cpp new file mode 100644 index 000000000000..76273e4a8ef0 --- /dev/null +++ b/contrib/subrepo-cheri-libunwind/test/unw_resume.pass.cpp @@ -0,0 +1,34 @@ +// -*- C++ -*- +//===----------------------------------------------------------------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +// 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() { + unw_context_t context; + unw_cursor_t cursor; + + unw_getcontext(&context); + unw_init_local(&cursor, &context); + unw_step(&cursor); + unw_resume(&cursor); +} + +int main() { + test_unw_resume(); + return 0; +} diff --git a/contrib/subrepo-cheri-libunwind/test/unwind_leaffunction.pass.cpp b/contrib/subrepo-cheri-libunwind/test/unwind_leaffunction.pass.cpp index f363dfe4a29d..8c9912e3c386 100644 --- a/contrib/subrepo-cheri-libunwind/test/unwind_leaffunction.pass.cpp +++ b/contrib/subrepo-cheri-libunwind/test/unwind_leaffunction.pass.cpp @@ -8,11 +8,12 @@ //===----------------------------------------------------------------------===// // 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 +#undef NDEBUG #include #include #include @@ -27,7 +28,8 @@ _Unwind_Reason_Code frame_handler(struct _Unwind_Context* ctx, void* arg) { (void)arg; Dl_info info = { 0, 0, 0, 0 }; - // Unwind util the main is reached, above frames deeped on the platfrom and architecture. + // Unwind until the main is reached, above frames deeped on the platform and + // architecture. if (dladdr(reinterpret_cast(_Unwind_GetIP(ctx)), &info) && info.dli_sname && !strcmp("main", info.dli_sname)) { _Exit(0); diff --git a/contrib/subrepo-cheri-libunwind/test/unwind_scalable_vectors.pass.cpp b/contrib/subrepo-cheri-libunwind/test/unwind_scalable_vectors.pass.cpp new file mode 100644 index 000000000000..a5c5947c870f --- /dev/null +++ b/contrib/subrepo-cheri-libunwind/test/unwind_scalable_vectors.pass.cpp @@ -0,0 +1,40 @@ +// -*- C++ -*- +//===----------------------------------------------------------------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +// REQUIRES: linux && target={{riscv64-.+}} + +#undef NDEBUG +#include +#include + +#ifdef __riscv_vector +__attribute__((noinline)) extern "C" void stepper() { + unw_cursor_t cursor; + unw_context_t uc; + unw_getcontext(&uc); + unw_init_local(&cursor, &uc); + // Stepping into foo() should succeed. + assert(unw_step(&cursor) > 0); + // Stepping past foo() should succeed, too. + 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