Skip to content

Conversation

pcc
Copy link
Contributor

@pcc pcc commented Aug 7, 2025

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

Created using spr 1.3.6-beta.1
@pcc pcc requested review from a team as code owners August 7, 2025 00:12
@llvmbot llvmbot added libc++ libc++ C++ Standard Library. Not GNU libstdc++. Not libc++abi. libc++abi libc++abi C++ Runtime Library. Not libc++. labels Aug 7, 2025
@llvmbot
Copy link
Member

llvmbot commented Aug 7, 2025

@llvm/pr-subscribers-libcxxabi

@llvm/pr-subscribers-libcxx

Author: Peter Collingbourne (pcc)

Changes

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 bootstrapping-build-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


Full diff: https://github.com/llvm/llvm-project/pull/152414.diff

5 Files Affected:

  • (modified) libcxx/CMakeLists.txt (+15)
  • (modified) libcxx/test/CMakeLists.txt (+1)
  • (modified) libcxx/utils/ci/run-buildbot (+36)
  • (modified) libcxx/utils/libcxx/test/params.py (+16)
  • (modified) libcxxabi/test/CMakeLists.txt (+2)
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
Created using spr 1.3.6-beta.1

ccache -s
;;
bootstrapping-build-pfp)
Copy link
Contributor

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?

Copy link
Contributor Author

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.

Copy link
Contributor

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.

Copy link
Contributor Author

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.

pcc added 3 commits September 10, 2025 18:04
Created using spr 1.3.6-beta.1
Created using spr 1.3.6-beta.1
Created using spr 1.3.6-beta.1
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

libc++abi libc++abi C++ Runtime Library. Not libc++. libc++ libc++ C++ Standard Library. Not GNU libstdc++. Not libc++abi.

3 participants