diff --git a/libcxx/CMakeLists.txt b/libcxx/CMakeLists.txt index 3a87029b52980..bb179f8127d26 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 @@ -567,6 +575,17 @@ function(cxx_add_rtti_flags target) endif() endfunction() +function(cxx_add_pfp_flags target) + if (LIBCXX_PFP STREQUAL untagged) + target_add_compile_flags_if_supported(${target} PUBLIC + -fexperimental-pointer-field-protection) + elseif (LIBCXX_PFP STREQUAL tagged) + target_add_compile_flags_if_supported(${target} PUBLIC + -fexperimental-pointer-field-protection + -fexperimental-pointer-field-protection-tagged) + 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. @@ -823,6 +842,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/cmake/caches/Generic-pfp.cmake b/libcxx/cmake/caches/Generic-pfp.cmake new file mode 100644 index 0000000000000..1a25e6a8ac7fb --- /dev/null +++ b/libcxx/cmake/caches/Generic-pfp.cmake @@ -0,0 +1,7 @@ +set(LIBCXXABI_ENABLE_SHARED OFF CACHE BOOL "") +set(LIBCXX_USE_COMPILER_RT ON CACHE BOOL "") +set(LIBCXX_PFP "tagged" CACHE STRING "") +set(LIBCXX_ENABLE_SHARED OFF CACHE BOOL "") +set(LIBCXX_INCLUDE_BENCHMARKS OFF CACHE BOOL "") +set(LIBCXX_TEST_CONFIG "llvm-libc++-static.cfg.in" CACHE STRING "") +set(LIBUNWIND_ENABLE_SHARED OFF CACHE BOOL "") 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/test/libcxx/gdb/gdb_pretty_printer_test.sh.cpp b/libcxx/test/libcxx/gdb/gdb_pretty_printer_test.sh.cpp index f5a878582666b..592bacf071eb6 100644 --- a/libcxx/test/libcxx/gdb/gdb_pretty_printer_test.sh.cpp +++ b/libcxx/test/libcxx/gdb/gdb_pretty_printer_test.sh.cpp @@ -24,6 +24,9 @@ // This test doesn't work as such on Windows. // UNSUPPORTED: windows +// GDB doesn't know how to read PFP fields correctly yet. +// UNSUPPORTED: pfp + // RUN: %{cxx} %{flags} %s -o %t.exe %{compile_flags} -g %{link_flags} // Ensure locale-independence for unicode tests. // RUN: env LANG=en_US.UTF-8 %{gdb} -nx -batch -iex "set autoload off" -ex "source %S/../../../utils/gdb/libcxx/printers.py" -ex "python register_libcxx_printer_loader()" -ex "source %S/gdb_pretty_printer_test.py" %t.exe diff --git a/libcxx/test/libcxx/type_traits/is_trivially_relocatable.compile.pass.cpp b/libcxx/test/libcxx/type_traits/is_trivially_relocatable.compile.pass.cpp index 10889eb50870d..02e56e6bc6fa8 100644 --- a/libcxx/test/libcxx/type_traits/is_trivially_relocatable.compile.pass.cpp +++ b/libcxx/test/libcxx/type_traits/is_trivially_relocatable.compile.pass.cpp @@ -6,6 +6,9 @@ // //===----------------------------------------------------------------------===// +// With PFP we return different values for __libcpp_is_trivially_relocatable. +// UNSUPPORTED: pfp + #include <__type_traits/is_trivially_relocatable.h> #include #include diff --git a/libcxx/utils/ci/run-buildbot b/libcxx/utils/ci/run-buildbot index 57ecf1e49dbf2..4f7d4dd547e12 100755 --- a/libcxx/utils/ci/run-buildbot +++ b/libcxx/utils/ci/run-buildbot @@ -376,6 +376,11 @@ generic-ubsan) generate-cmake -C "${MONOREPO_ROOT}/libcxx/cmake/caches/Generic-ubsan.cmake" check-runtimes ;; +generic-pfp) + clean + generate-cmake -C "${MONOREPO_ROOT}/libcxx/cmake/caches/Generic-pfp.cmake" + check-runtimes +;; # # Various build configurations # diff --git a/libcxx/utils/libcxx/test/params.py b/libcxx/utils/libcxx/test/params.py index c02d6df1c47a4..dff826d02c393 100644 --- a/libcxx/utils/libcxx/test/params.py +++ b/libcxx/utils/libcxx/test/params.py @@ -343,6 +343,24 @@ 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("-fexperimental-pointer-field-protection"), + AddCompileFlag("-fexperimental-pointer-field-protection-tagged") if pfp == "tagged" else None, + # 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"), + AddFeature("pfp"), + ], + ), Parameter( name="enable_experimental", choices=[True, False], diff --git a/libcxxabi/test/CMakeLists.txt b/libcxxabi/test/CMakeLists.txt index 9eabfb08240b6..9a87a90b0b1dd 100644 --- a/libcxxabi/test/CMakeLists.txt +++ b/libcxxabi/test/CMakeLists.txt @@ -80,6 +80,10 @@ if (LLVM_USE_SANITIZER) serialize_lit_string_param(SERIALIZED_LIT_PARAMS use_sanitizer "${LLVM_USE_SANITIZER}") endif() +if (DEFINED LIBCXX_PFP) + serialize_lit_string_param(SERIALIZED_LIT_PARAMS pfp "${LIBCXX_PFP}") +endif() + if (CMAKE_CXX_COMPILER_TARGET) serialize_lit_string_param(SERIALIZED_LIT_PARAMS target_triple "${CMAKE_CXX_COMPILER_TARGET}") else()