diff --git a/libcxx/CMakeLists.txt b/libcxx/CMakeLists.txt index 85514cc7547a9..05f342d7002b3 100644 --- a/libcxx/CMakeLists.txt +++ b/libcxx/CMakeLists.txt @@ -66,6 +66,14 @@ if (NOT "${LIBCXX_HARDENING_MODE}" IN_LIST LIBCXX_SUPPORTED_HARDENING_MODES) message(FATAL_ERROR "Unsupported hardening mode: '${LIBCXX_HARDENING_MODE}'. Supported values are ${LIBCXX_SUPPORTED_HARDENING_MODES}.") endif() +set(LIBCXX_SUPPORTED_PFP none untagged tagged) +set(LIBCXX_PFP none CACHE STRING + "Specify whether to build with pointer field protection. + Supported values are ${LIBCXX_SUPPORTED_PFP}.") +if (NOT "${LIBCXX_PFP}" IN_LIST LIBCXX_SUPPORTED_PFP) + message(FATAL_ERROR + "Unsupported PFP mode: '${LIBCXX_PFP}'. Supported values are ${LIBCXX_SUPPORTED_PFP}.") +endif() set(LIBCXX_ASSERTION_HANDLER_FILE "vendor/llvm/default_assertion_handler.in" CACHE STRING @@ -564,6 +572,12 @@ function(cxx_add_rtti_flags target) endif() endfunction() +function(cxx_add_pfp_flags target) + if (NOT LIBCXX_PFP STREQUAL none) + target_add_compile_flags_if_supported(${target} PUBLIC -fexperimental-pointer-field-protection=${LIBCXX_PFP}) + endif() +endfunction() + # Modules flags =============================================================== # FIXME The libc++ sources are fundamentally non-modular. They need special # versions of the headers in order to provide C++03 and legacy ABI definitions. @@ -820,6 +834,7 @@ function(cxx_add_common_build_flags target) cxx_add_windows_flags(${target}) cxx_add_exception_flags(${target}) cxx_add_rtti_flags(${target}) + cxx_add_pfp_flags(${target}) cxx_add_module_flags(${target}) cxx_link_system_libraries(${target}) target_link_libraries(${target} PRIVATE cxx-sanitizer-flags) diff --git a/libcxx/test/CMakeLists.txt b/libcxx/test/CMakeLists.txt index f4e577aed57de..340f3d3c44101 100644 --- a/libcxx/test/CMakeLists.txt +++ b/libcxx/test/CMakeLists.txt @@ -79,6 +79,7 @@ if (NOT LIBCXX_ENABLE_RTTI) endif() serialize_lit_string_param(SERIALIZED_LIT_PARAMS hardening_mode "${LIBCXX_HARDENING_MODE}") +serialize_lit_string_param(SERIALIZED_LIT_PARAMS pfp "${LIBCXX_PFP}") if (CMAKE_CXX_COMPILER_TARGET) serialize_lit_string_param(SERIALIZED_LIT_PARAMS target_triple "${CMAKE_CXX_COMPILER_TARGET}") diff --git a/libcxx/utils/ci/run-buildbot b/libcxx/utils/ci/run-buildbot index 57ecf1e49dbf2..9965ebe78b497 100755 --- a/libcxx/utils/ci/run-buildbot +++ b/libcxx/utils/ci/run-buildbot @@ -411,6 +411,42 @@ bootstrapping-build) ccache -s ;; +bootstrapping-build-pfp) + clean + + triple="$(${CXX} --print-target-triple)" + + step "Generating CMake" + ${CMAKE} \ + -S "${MONOREPO_ROOT}/llvm" \ + -B "${BUILD_DIR}" \ + -GNinja -DCMAKE_MAKE_PROGRAM="${NINJA}" \ + -DCMAKE_BUILD_TYPE=Release \ + -DCMAKE_INSTALL_PREFIX="${INSTALL_DIR}" \ + -DLLVM_ENABLE_PROJECTS="clang;lld" \ + -DLLVM_ENABLE_RUNTIMES="compiler-rt;libcxx;libcxxabi;libunwind" \ + -DLLVM_RUNTIME_TARGETS="$triple" \ + -DLLVM_HOST_TRIPLE="$triple" \ + -DLLVM_TARGETS_TO_BUILD="host" \ + -DRUNTIMES_BUILD_ALLOW_DARWIN=ON \ + -DLLVM_ENABLE_ASSERTIONS=ON \ + "-DRUNTIMES_${triple}_LIBCXXABI_ENABLE_SHARED=OFF" \ + "-DRUNTIMES_${triple}_LIBCXX_USE_COMPILER_RT=ON" \ + "-DRUNTIMES_${triple}_LIBCXX_PFP=tagged" \ + "-DRUNTIMES_${triple}_LIBCXX_ENABLE_SHARED=OFF" \ + "-DRUNTIMES_${triple}_LIBCXX_TEST_CONFIG=llvm-libc++-static.cfg.in" \ + "-DRUNTIMES_${triple}_LIBUNWIND_ENABLE_SHARED=OFF" \ + -DLLVM_LIT_ARGS="-sv --xunit-xml-output test-results.xml --timeout=1500 --time-tests" + + # FIXME: Currently this also runs the sanitizer tests due to compiler-rt + # being in LLVM_ENABLE_RUNTIMES for the emulated PAC runtime. Ideally this + # would only run the libc++ and libc++abi tests. + step "Running the libc++ and libc++abi tests" + ${NINJA} -vC "${BUILD_DIR}" check-runtimes + + # FIXME: Debugging support for PFP is incomplete so don't run the LLDB tests + # as above for now. +;; generic-static) clean generate-cmake -C "${MONOREPO_ROOT}/libcxx/cmake/caches/Generic-static.cmake" diff --git a/libcxx/utils/libcxx/test/params.py b/libcxx/utils/libcxx/test/params.py index 81c613421a465..67201c719d1ab 100644 --- a/libcxx/utils/libcxx/test/params.py +++ b/libcxx/utils/libcxx/test/params.py @@ -340,6 +340,22 @@ def getSuitableClangTidy(cfg): ] ) ), + Parameter( + name="pfp", + choices=["none", "untagged", "tagged"], + type=str, + default="none", + help="Whether to build with pointer field protection.", + actions=lambda pfp: [] if pfp == "none" else [ + AddCompileFlag(f"-fexperimental-pointer-field-protection={pfp}"), + # Requires support for new relocations which are only implemented in lld for now. + AddLinkFlag("-fuse-ld=lld"), + # Requires emulated PAC support in compiler-rt. + AddCompileFlag("--rtlib=compiler-rt"), + AddLinkFlag("--rtlib=compiler-rt"), + AddLinkFlag("--unwindlib=libunwind"), + ], + ), Parameter( name="enable_experimental", choices=[True, False], diff --git a/libcxxabi/test/CMakeLists.txt b/libcxxabi/test/CMakeLists.txt index 9eabfb08240b6..447b0fc43b813 100644 --- a/libcxxabi/test/CMakeLists.txt +++ b/libcxxabi/test/CMakeLists.txt @@ -80,6 +80,8 @@ if (LLVM_USE_SANITIZER) serialize_lit_string_param(SERIALIZED_LIT_PARAMS use_sanitizer "${LLVM_USE_SANITIZER}") endif() +serialize_lit_string_param(SERIALIZED_LIT_PARAMS pfp "${LIBCXX_PFP}") + if (CMAKE_CXX_COMPILER_TARGET) serialize_lit_string_param(SERIALIZED_LIT_PARAMS target_triple "${CMAKE_CXX_COMPILER_TARGET}") else()