[𝘀𝗽𝗿] changes introduced through rebase
Created using spr 1.3.6-beta.1
[skip ci]
diff --git a/libcxx/docs/CodingGuidelines.rst b/libcxx/docs/CodingGuidelines.rst
index ff312d1..0a1ab13 100644
--- a/libcxx/docs/CodingGuidelines.rst
+++ b/libcxx/docs/CodingGuidelines.rst
@@ -195,3 +195,16 @@
should be annotated for the same reason.
This is enforced by the clang-tidy check ``libcpp-nodebug-on-aliases``.
+
+Pointer field protection
+========================
+
+To improve the effectiveness of Clang's `pointer field protection
+<https://clang.llvm.org/docs/StructureProtection.html>`_ feature,
+commonly used vocabulary types with pointer fields are marked with the
+``_LIBCPP_PFP`` attribute, to give Clang permission to use PFP to protect
+their pointer fields. Newly added vocabulary types should be marked with
+this attribute if they contain pointer fields.
+
+For the time being, PFP is an experimental feature, so our criteria for
+marking types with ``_LIBCPP_PFP`` may change.
diff --git a/libcxx/include/__config b/libcxx/include/__config
index 5f6dc79..a54eba27 100644
--- a/libcxx/include/__config
+++ b/libcxx/include/__config
@@ -1275,12 +1275,16 @@
# define _LIBCPP_HAS_EXPLICIT_THIS_PARAMETER 0
# endif
+# if __has_cpp_attribute(_Clang::__no_field_protection__)
+# define _LIBCPP_NO_PFP [[_Clang::__no_field_protection__]]
+# else
+# define _LIBCPP_NO_PFP
+# endif
+
# if defined(__POINTER_FIELD_PROTECTION__)
-# define _LIBCPP_PFP [[clang::pointer_field_protection]]
-# define _LIBCPP_NO_PFP [[clang::no_field_protection]]
+# define _LIBCPP_PFP [[_Clang::__pointer_field_protection__]]
# else
# define _LIBCPP_PFP
-# define _LIBCPP_NO_PFP
# endif
#endif // __cplusplus
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 a7db822..f5a8785 100644
--- a/libcxx/test/libcxx/gdb/gdb_pretty_printer_test.sh.cpp
+++ b/libcxx/test/libcxx/gdb/gdb_pretty_printer_test.sh.cpp
@@ -256,12 +256,9 @@
ComparePrettyPrintToRegex(std::move(forty_two),
R"(std::unique_ptr<int> containing = {__ptr_ = 0x[a-f0-9]+})");
-#if !defined(__POINTER_FIELD_PROTECTION__)
- // GDB doesn't know how to read PFP fields correctly yet.
std::unique_ptr<int> this_is_null;
ComparePrettyPrintToChars(std::move(this_is_null),
R"(std::unique_ptr is nullptr)");
-#endif
}
void bitset_test() {
@@ -357,8 +354,6 @@
}
void multimap_test() {
-#if !defined(__POINTER_FIELD_PROTECTION__)
- // GDB doesn't know how to read PFP fields correctly yet.
std::multimap<int, int> i_am_empty{};
ComparePrettyPrintToChars(i_am_empty, "std::multimap is empty");
@@ -374,7 +369,6 @@
"std::multimap with 6 elements = "
R"({[1] = "one", [1] = "ein", [1] = "bir", )"
R"([2] = "two", [2] = "zwei", [3] = "three"})");
-#endif
}
void queue_test() {
@@ -447,8 +441,6 @@
}
void multiset_test() {
-#if !defined(__POINTER_FIELD_PROTECTION__)
- // GDB doesn't know how to read PFP fields correctly yet.
std::multiset<int> i_am_empty;
ComparePrettyPrintToChars(i_am_empty, "std::multiset is empty");
@@ -456,7 +448,6 @@
ComparePrettyPrintToChars(one_two_three,
"std::multiset with 4 elements = {"
R"("1:one", "1:one", "2:two", "3:three"})");
-#endif
}
void vector_test() {
@@ -490,13 +481,10 @@
"std::vector of length "
"3, capacity 3 = {5, 6, 7}");
-#if !defined(__POINTER_FIELD_PROTECTION__)
- // GDB doesn't know how to read PFP fields correctly yet.
std::vector<int, UncompressibleAllocator<int>> test3({7, 8});
ComparePrettyPrintToChars(std::move(test3),
"std::vector of length "
"2, capacity 2 = {7, 8}");
-#endif
}
void set_iterator_test() {
@@ -667,11 +655,8 @@
test0,
R"(std::shared_ptr<int> count [3\?], weak [0\?]( \(libc\+\+ missing debug info\))? containing = {__ptr_ = 0x[a-f0-9]+})");
-#if !defined(__POINTER_FIELD_PROTECTION__)
- // GDB doesn't know how to read PFP fields correctly yet.
std::shared_ptr<const int> test3;
ComparePrettyPrintToChars(test3, "std::shared_ptr is nullptr");
-#endif
}
void streampos_test() {
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 847ef6f..c462672 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
@@ -26,12 +26,6 @@
# include <locale>
#endif
-#if defined(__POINTER_FIELD_PROTECTION__)
-constexpr bool pfp_disabled = false;
-#else
-constexpr bool pfp_disabled = true;
-#endif
-
static_assert(std::__libcpp_is_trivially_relocatable<char>::value, "");
static_assert(std::__libcpp_is_trivially_relocatable<int>::value, "");
static_assert(std::__libcpp_is_trivially_relocatable<double>::value, "");
@@ -74,8 +68,8 @@
// ----------------------
// __split_buffer
-static_assert(std::__libcpp_is_trivially_relocatable<std::__split_buffer<int> >::value == pfp_disabled, "");
-static_assert(std::__libcpp_is_trivially_relocatable<std::__split_buffer<NotTriviallyCopyable> >::value == pfp_disabled, "");
+static_assert(std::__libcpp_is_trivially_relocatable<std::__split_buffer<int> >::value, "");
+static_assert(std::__libcpp_is_trivially_relocatable<std::__split_buffer<NotTriviallyCopyable> >::value, "");
static_assert(!std::__libcpp_is_trivially_relocatable<std::__split_buffer<int, test_allocator<int> > >::value, "");
// standard library types
@@ -88,7 +82,7 @@
static_assert(std::__libcpp_is_trivially_relocatable<std::array<int, 1> >::value, "");
static_assert(!std::__libcpp_is_trivially_relocatable<std::array<NotTriviallyCopyable, 1> >::value, "");
-static_assert(std::__libcpp_is_trivially_relocatable<std::array<std::unique_ptr<int>, 1> >::value == pfp_disabled, "");
+static_assert(std::__libcpp_is_trivially_relocatable<std::array<std::unique_ptr<int>, 1> >::value, "");
// basic_string
#if !__has_feature(address_sanitizer) || !_LIBCPP_INSTRUMENTED_WITH_ASAN
@@ -103,17 +97,17 @@
};
static_assert(std::__libcpp_is_trivially_relocatable<
- std::basic_string<char, std::char_traits<char>, std::allocator<char> > >::value == pfp_disabled,
+ std::basic_string<char, std::char_traits<char>, std::allocator<char> > >::value,
"");
static_assert(std::__libcpp_is_trivially_relocatable<
- std::basic_string<char, NotTriviallyRelocatableCharTraits<char>, std::allocator<char> > >::value == pfp_disabled,
+ std::basic_string<char, NotTriviallyRelocatableCharTraits<char>, std::allocator<char> > >::value,
"");
static_assert(std::__libcpp_is_trivially_relocatable<
- std::basic_string<MyChar, constexpr_char_traits<MyChar>, std::allocator<MyChar> > >::value == pfp_disabled,
+ std::basic_string<MyChar, constexpr_char_traits<MyChar>, std::allocator<MyChar> > >::value,
"");
static_assert(
std::__libcpp_is_trivially_relocatable<
- std::basic_string<MyChar, NotTriviallyRelocatableCharTraits<MyChar>, std::allocator<MyChar> > >::value == pfp_disabled,
+ std::basic_string<MyChar, NotTriviallyRelocatableCharTraits<MyChar>, std::allocator<MyChar> > >::value,
"");
static_assert(!std::__libcpp_is_trivially_relocatable<
std::basic_string<char, std::char_traits<char>, test_allocator<char> > >::value,
@@ -125,21 +119,21 @@
#endif
// deque
-static_assert(std::__libcpp_is_trivially_relocatable<std::deque<int> >::value == pfp_disabled, "");
-static_assert(std::__libcpp_is_trivially_relocatable<std::deque<NotTriviallyCopyable> >::value == pfp_disabled, "");
+static_assert(std::__libcpp_is_trivially_relocatable<std::deque<int> >::value, "");
+static_assert(std::__libcpp_is_trivially_relocatable<std::deque<NotTriviallyCopyable> >::value, "");
static_assert(!std::__libcpp_is_trivially_relocatable<std::deque<int, test_allocator<int> > >::value, "");
// exception_ptr
#ifndef _LIBCPP_ABI_MICROSOFT // FIXME: Is this also the case on windows?
-static_assert(std::__libcpp_is_trivially_relocatable<std::exception_ptr>::value == pfp_disabled, "");
+static_assert(std::__libcpp_is_trivially_relocatable<std::exception_ptr>::value, "");
#endif
// expected
#if TEST_STD_VER >= 23
-static_assert(std::__libcpp_is_trivially_relocatable<std::expected<int, int> >::value == pfp_disabled);
-static_assert(std::__libcpp_is_trivially_relocatable<std::expected<std::unique_ptr<int>, int>>::value == pfp_disabled);
-static_assert(std::__libcpp_is_trivially_relocatable<std::expected<int, std::unique_ptr<int>>>::value == pfp_disabled);
-static_assert(std::__libcpp_is_trivially_relocatable<std::expected<std::unique_ptr<int>, std::unique_ptr<int>>>::value == pfp_disabled);
+static_assert(std::__libcpp_is_trivially_relocatable<std::expected<int, int> >::value);
+static_assert(std::__libcpp_is_trivially_relocatable<std::expected<std::unique_ptr<int>, int>>::value);
+static_assert(std::__libcpp_is_trivially_relocatable<std::expected<int, std::unique_ptr<int>>>::value);
+static_assert(std::__libcpp_is_trivially_relocatable<std::expected<std::unique_ptr<int>, std::unique_ptr<int>>>::value);
static_assert(!std::__libcpp_is_trivially_relocatable<std::expected<int, NotTriviallyCopyable>>::value);
static_assert(!std::__libcpp_is_trivially_relocatable<std::expected<NotTriviallyCopyable, int>>::value);
@@ -149,42 +143,42 @@
// locale
#ifndef TEST_HAS_NO_LOCALIZATION
-static_assert(std::__libcpp_is_trivially_relocatable<std::locale>::value == pfp_disabled, "");
+static_assert(std::__libcpp_is_trivially_relocatable<std::locale>::value, "");
#endif
// optional
#if TEST_STD_VER >= 17
static_assert(std::__libcpp_is_trivially_relocatable<std::optional<int>>::value, "");
static_assert(!std::__libcpp_is_trivially_relocatable<std::optional<NotTriviallyCopyable>>::value, "");
-static_assert(std::__libcpp_is_trivially_relocatable<std::optional<std::unique_ptr<int>>>::value == pfp_disabled, "");
+static_assert(std::__libcpp_is_trivially_relocatable<std::optional<std::unique_ptr<int>>>::value, "");
#endif // TEST_STD_VER >= 17
// pair
-static_assert(std::__libcpp_is_trivially_relocatable<std::pair<int, int> >::value == pfp_disabled, "");
+static_assert(std::__libcpp_is_trivially_relocatable<std::pair<int, int> >::value, "");
static_assert(!std::__libcpp_is_trivially_relocatable<std::pair<NotTriviallyCopyable, int> >::value, "");
static_assert(!std::__libcpp_is_trivially_relocatable<std::pair<int, NotTriviallyCopyable> >::value, "");
static_assert(!std::__libcpp_is_trivially_relocatable<std::pair<NotTriviallyCopyable, NotTriviallyCopyable> >::value,
"");
-static_assert(std::__libcpp_is_trivially_relocatable<std::pair<std::unique_ptr<int>, std::unique_ptr<int> > >::value == pfp_disabled,
+static_assert(std::__libcpp_is_trivially_relocatable<std::pair<std::unique_ptr<int>, std::unique_ptr<int> > >::value,
"");
// shared_ptr
-static_assert(std::__libcpp_is_trivially_relocatable<std::shared_ptr<NotTriviallyCopyable> >::value == pfp_disabled, "");
+static_assert(std::__libcpp_is_trivially_relocatable<std::shared_ptr<NotTriviallyCopyable> >::value, "");
// tuple
#if TEST_STD_VER >= 11
static_assert(std::__libcpp_is_trivially_relocatable<std::tuple<> >::value, "");
-static_assert(std::__libcpp_is_trivially_relocatable<std::tuple<int> >::value == pfp_disabled, "");
+static_assert(std::__libcpp_is_trivially_relocatable<std::tuple<int> >::value, "");
static_assert(!std::__libcpp_is_trivially_relocatable<std::tuple<NotTriviallyCopyable> >::value, "");
-static_assert(std::__libcpp_is_trivially_relocatable<std::tuple<std::unique_ptr<int> > >::value == pfp_disabled, "");
+static_assert(std::__libcpp_is_trivially_relocatable<std::tuple<std::unique_ptr<int> > >::value, "");
-static_assert(std::__libcpp_is_trivially_relocatable<std::tuple<int, int> >::value == pfp_disabled, "");
+static_assert(std::__libcpp_is_trivially_relocatable<std::tuple<int, int> >::value, "");
static_assert(!std::__libcpp_is_trivially_relocatable<std::tuple<NotTriviallyCopyable, int> >::value, "");
static_assert(!std::__libcpp_is_trivially_relocatable<std::tuple<int, NotTriviallyCopyable> >::value, "");
static_assert(!std::__libcpp_is_trivially_relocatable<std::tuple<NotTriviallyCopyable, NotTriviallyCopyable> >::value,
"");
-static_assert(std::__libcpp_is_trivially_relocatable<std::tuple<std::unique_ptr<int>, std::unique_ptr<int> > >::value == pfp_disabled,
+static_assert(std::__libcpp_is_trivially_relocatable<std::tuple<std::unique_ptr<int>, std::unique_ptr<int> > >::value,
"");
#endif // TEST_STD_VER >= 11
@@ -209,9 +203,9 @@
void operator()(T*);
};
-static_assert(std::__libcpp_is_trivially_relocatable<std::unique_ptr<int> >::value == pfp_disabled, "");
-static_assert(std::__libcpp_is_trivially_relocatable<std::unique_ptr<NotTriviallyCopyable> >::value == pfp_disabled, "");
-static_assert(std::__libcpp_is_trivially_relocatable<std::unique_ptr<int[]> >::value == pfp_disabled, "");
+static_assert(std::__libcpp_is_trivially_relocatable<std::unique_ptr<int> >::value, "");
+static_assert(std::__libcpp_is_trivially_relocatable<std::unique_ptr<NotTriviallyCopyable> >::value, "");
+static_assert(std::__libcpp_is_trivially_relocatable<std::unique_ptr<int[]> >::value, "");
static_assert(!std::__libcpp_is_trivially_relocatable<std::unique_ptr<int, NotTriviallyRelocatableDeleter> >::value,
"");
static_assert(!std::__libcpp_is_trivially_relocatable<std::unique_ptr<int[], NotTriviallyRelocatableDeleter> >::value,
@@ -225,23 +219,23 @@
#if TEST_STD_VER >= 17
static_assert(std::__libcpp_is_trivially_relocatable<std::variant<int> >::value, "");
static_assert(!std::__libcpp_is_trivially_relocatable<std::variant<NotTriviallyCopyable> >::value, "");
-static_assert(std::__libcpp_is_trivially_relocatable<std::variant<std::unique_ptr<int> > >::value == pfp_disabled, "");
+static_assert(std::__libcpp_is_trivially_relocatable<std::variant<std::unique_ptr<int> > >::value, "");
static_assert(std::__libcpp_is_trivially_relocatable<std::variant<int, int> >::value, "");
static_assert(!std::__libcpp_is_trivially_relocatable<std::variant<NotTriviallyCopyable, int> >::value, "");
static_assert(!std::__libcpp_is_trivially_relocatable<std::variant<int, NotTriviallyCopyable> >::value, "");
static_assert(!std::__libcpp_is_trivially_relocatable<std::variant<NotTriviallyCopyable, NotTriviallyCopyable> >::value,
"");
-static_assert(std::__libcpp_is_trivially_relocatable<std::variant<std::unique_ptr<int>, std::unique_ptr<int> > >::value == pfp_disabled,
+static_assert(std::__libcpp_is_trivially_relocatable<std::variant<std::unique_ptr<int>, std::unique_ptr<int> > >::value,
"");
#endif // TEST_STD_VER >= 17
// vector
-static_assert(std::__libcpp_is_trivially_relocatable<std::vector<int> >::value == pfp_disabled, "");
-static_assert(std::__libcpp_is_trivially_relocatable<std::vector<NotTriviallyCopyable> >::value == pfp_disabled, "");
+static_assert(std::__libcpp_is_trivially_relocatable<std::vector<int> >::value, "");
+static_assert(std::__libcpp_is_trivially_relocatable<std::vector<NotTriviallyCopyable> >::value, "");
static_assert(!std::__libcpp_is_trivially_relocatable<std::vector<int, test_allocator<int> > >::value, "");
// weak_ptr
-static_assert(std::__libcpp_is_trivially_relocatable<std::weak_ptr<NotTriviallyCopyable> >::value == pfp_disabled, "");
+static_assert(std::__libcpp_is_trivially_relocatable<std::weak_ptr<NotTriviallyCopyable> >::value, "");
// TODO: Mark all the trivially relocatable STL types as such
diff --git a/libcxxabi/include/__cxxabi_config.h b/libcxxabi/include/__cxxabi_config.h
index 925cc41..c8c3b18 100644
--- a/libcxxabi/include/__cxxabi_config.h
+++ b/libcxxabi/include/__cxxabi_config.h
@@ -109,12 +109,8 @@
# define _LIBCXXABI_NOEXCEPT noexcept
#endif
-#if defined(_LIBCXXABI_COMPILER_CLANG)
-# if defined(__POINTER_FIELD_PROTECTION__)
-# define _LIBCXXABI_NO_PFP [[clang::no_field_protection]]
-# else
-# define _LIBCXXABI_NO_PFP
-# endif
+#if defined(__POINTER_FIELD_PROTECTION__)
+# define _LIBCXXABI_NO_PFP [[_Clang::__no_field_protection__]]
#else
# define _LIBCXXABI_NO_PFP
#endif
diff --git a/llvm/docs/LangRef.rst b/llvm/docs/LangRef.rst
index 094e5f0..e49d7bb 100644
--- a/llvm/docs/LangRef.rst
+++ b/llvm/docs/LangRef.rst
@@ -3092,13 +3092,16 @@
When present, the operand bundle must contain exactly one value of token type.
See the :doc:`ConvergentOperations` document for details.
+.. _deactivationsymbol:
+
Deactivation Symbol Operand Bundles
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
A ``"deactivation-symbol"`` operand bundle is valid on the following
instructions (AArch64 only):
-- Call to a normal function with ``notail`` attribute.
+- Call to a normal function with ``notail`` attribute and a first argument and
+ return value of type ``ptr``.
- Call to ``llvm.ptrauth.sign`` or ``llvm.ptrauth.auth`` intrinsics.
This operand bundle specifies that if the deactivation symbol is defined
@@ -5148,7 +5151,7 @@
Pointer Authentication Constants
--------------------------------
-``ptrauth (ptr CST, i32 KEY[, i64 DISC[, ptr ADDRDISC]?]?)``
+``ptrauth (ptr CST, i32 KEY[, i64 DISC[, ptr ADDRDISC[, ptr DS]?]?]?)``
A '``ptrauth``' constant represents a pointer with a cryptographic
authentication signature embedded into some bits, as described in the
@@ -5177,6 +5180,11 @@
%tmp2 = call i64 @llvm.ptrauth.sign(i64 ptrtoint (ptr CST to i64), i32 KEY, i64 %tmp1)
%val = inttoptr i64 %tmp2 to ptr
+If the deactivation symbol operand ``DS`` has a non-null value,
+the semantics are as if a :ref:`deactivation-symbol operand bundle
+<deactivationsymbol>` were added to the ``llvm.ptrauth.sign`` intrinsic
+calls above, with ``DS`` as the only operand.
+
.. _constantexprs:
Constant Expressions
diff --git a/llvm/lib/Bitcode/Reader/BitcodeReader.cpp b/llvm/lib/Bitcode/Reader/BitcodeReader.cpp
index 045ed20..a7fce4f 100644
--- a/llvm/lib/Bitcode/Reader/BitcodeReader.cpp
+++ b/llvm/lib/Bitcode/Reader/BitcodeReader.cpp
@@ -1613,6 +1613,9 @@
ConstOps.size() > 4 ? ConstOps[4]
: ConstantPointerNull::get(cast<PointerType>(
ConstOps[3]->getType()));
+ if (!DeactivationSymbol->getType()->isPointerTy())
+ return error(
+ "ptrauth deactivation symbol operand must be a pointer");
C = ConstantPtrAuth::get(ConstOps[0], Key, Disc, ConstOps[3],
DeactivationSymbol);
diff --git a/llvm/lib/IR/Constants.cpp b/llvm/lib/IR/Constants.cpp
index 5eacc7a..53b292f 100644
--- a/llvm/lib/IR/Constants.cpp
+++ b/llvm/lib/IR/Constants.cpp
@@ -2082,6 +2082,7 @@
assert(Key->getBitWidth() == 32);
assert(Disc->getBitWidth() == 64);
assert(AddrDisc->getType()->isPointerTy());
+ assert(DeactivationSymbol->getType()->isPointerTy());
setOperand(0, Ptr);
setOperand(1, Key);
setOperand(2, Disc);
diff --git a/llvm/lib/IR/Verifier.cpp b/llvm/lib/IR/Verifier.cpp
index 9e44dfb..a53ba17 100644
--- a/llvm/lib/IR/Verifier.cpp
+++ b/llvm/lib/IR/Verifier.cpp
@@ -2632,6 +2632,9 @@
Check(CPA->getDiscriminator()->getBitWidth() == 64,
"signed ptrauth constant discriminator must be i64 constant integer");
+ Check(CPA->getDeactivationSymbol()->getType()->isPointerTy(),
+ "signed ptrauth constant deactivation symbol must be a pointer");
+
Check(isa<GlobalValue>(CPA->getDeactivationSymbol()) ||
CPA->getDeactivationSymbol()->isNullValue(),
"signed ptrauth constant deactivation symbol must be a global value "
diff --git a/llvm/test/Assembler/invalid-ptrauth-const6.ll b/llvm/test/Assembler/invalid-ptrauth-const6.ll
new file mode 100644
index 0000000..6e8e1d3
--- /dev/null
+++ b/llvm/test/Assembler/invalid-ptrauth-const6.ll
@@ -0,0 +1,6 @@
+; RUN: not llvm-as < %s 2>&1 | FileCheck %s
+
+@var = global i32 0
+
+; CHECK: error: constant ptrauth deactivation symbol must be a pointer
+@ptr = global ptr ptrauth (ptr @var, i32 0, i64 65535, ptr null, i64 0)
diff --git a/llvm/test/Transforms/Util/phi-protected-field-ptr.ll b/llvm/test/Transforms/PhaseOrdering/phi-protected-field-ptr.ll
similarity index 100%
rename from llvm/test/Transforms/Util/phi-protected-field-ptr.ll
rename to llvm/test/Transforms/PhaseOrdering/phi-protected-field-ptr.ll