- Notifications
You must be signed in to change notification settings - Fork 14.9k
[libc++] Add build and CI support for pointer field protection #152414
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: users/pcc/spr/main.libc-add-build-and-ci-support-for-pointer-field-protection
Are you sure you want to change the base?
Conversation
Created using spr 1.3.6-beta.1
@llvm/pr-subscribers-libcxxabi @llvm/pr-subscribers-libcxx Author: Peter Collingbourne (pcc) ChangesAdd support for building the libc++ runtime with pointer field This implements the LLVM side of the CI support proposed in: Full diff: https://github.com/llvm/llvm-project/pull/152414.diff 5 Files Affected:
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() |
Created using spr 1.3.6-beta.1
libcxx/utils/ci/run-buildbot Outdated
| ||
ccache -s | ||
;; | ||
bootstrapping-build-pfp) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A bootstrapping build is incredibly heavy weight. Why is this required?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's required because the PFP support in the compiler is experimental, and brand new so it won't exist in compilers that are already installed on the target system. Once PFP becomes a stable feature that is supported in released compilers, we may convert this to a non-bootstrapping buid.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Then we should update the compiler instead. We have close-to-trunk compilers available.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Okay, I replaced this with a generic-pfp
build that assumes an up to date compiler.
Created using spr 1.3.6-beta.1
Created using spr 1.3.6-beta.1
Add support for building the libc++ runtime with pointer field
protection with a new CMake variable, LIBCXX_PFP. Add a new case to
libcxx/utils/ci/run-buildbot named generic-pfp that runs the libc++
and libc++abi tests.
This implements the LLVM side of the CI support proposed in:
https://discourse.llvm.org/t/rfc-libc-and-pointer-field-protection/87713