[Lldb-commits] [lldb] [PAC][lldb][Dwarf] Support `__ptrauth`-qualified types in user expressions (PR #84387)
Daniil Kovalev via lldb-commits
lldb-commits at lists.llvm.org
Fri Apr 26 14:17:07 PDT 2024
https://github.com/kovdan01 updated https://github.com/llvm/llvm-project/pull/84387
>From 728f5644aebfafd2114e7e47a9b83ef057423997 Mon Sep 17 00:00:00 2001
From: Jonas Devlieghere <jonas at devlieghere.com>
Date: Tue, 20 Feb 2024 10:57:54 -0800
Subject: [PATCH 1/6] Upstream ptrauth changes to DWARFASTParserClang
---
.../SymbolFile/DWARF/DWARFASTParserClang.cpp | 57 +++++++++++++++++++
1 file changed, 57 insertions(+)
diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp b/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
index 54d06b1115a229..67fe830e1aa70d 100644
--- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
+++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
@@ -495,6 +495,7 @@ TypeSP DWARFASTParserClang::ParseTypeFromDWARF(const SymbolContext &sc,
case DW_TAG_const_type:
case DW_TAG_restrict_type:
case DW_TAG_volatile_type:
+ case DW_TAG_LLVM_ptrauth_type:
case DW_TAG_atomic_type:
case DW_TAG_unspecified_type: {
type_sp = ParseTypeModifier(sc, die, attrs);
@@ -676,6 +677,62 @@ DWARFASTParserClang::ParseTypeModifier(const SymbolContext &sc,
case DW_TAG_volatile_type:
encoding_data_type = Type::eEncodingIsVolatileUID;
break;
+ case DW_TAG_LLVM_ptrauth_type: {
+ DWARFDIE ptr_die = die.GetReferencedDIE(DW_AT_type);
+ // FIXME: Fully resolving the type here may affect performance.
+ Type *res_type = dwarf->ResolveType(ptr_die);
+ if (!res_type)
+ break;
+ attrs.type.Clear();
+ encoding_data_type = Type::eEncodingIsUID;
+ resolve_state = Type::ResolveState::Full;
+
+ // Apply the ptrauth qualifier to the resolved type.
+ auto *ptr_type =
+ (clang::Type *)res_type->GetForwardCompilerType().GetOpaqueQualType();
+ auto getAttr = [&](llvm::dwarf::Attribute Attr, unsigned defaultValue = 0) {
+ return die.GetAttributeValueAsUnsigned(Attr, defaultValue);
+ };
+ const unsigned key = getAttr(DW_AT_LLVM_ptrauth_key);
+ const bool addr_disc = getAttr(DW_AT_LLVM_ptrauth_address_discriminated);
+ const unsigned extra = getAttr(DW_AT_LLVM_ptrauth_extra_discriminator);
+ const bool isapointer = getAttr(DW_AT_LLVM_ptrauth_isa_pointer);
+ const bool authenticates_null_values =
+ getAttr(DW_AT_LLVM_ptrauth_authenticates_null_values, 0);
+ const bool is_restricted_integral = !ptr_type->isPointerType();
+ const unsigned authentication_mode_int = getAttr(
+ DW_AT_LLVM_ptrauth_authentication_mode,
+ static_cast<unsigned>(clang::PointerAuthenticationMode::SignAndAuth));
+ clang::PointerAuthenticationMode authentication_mode =
+ clang::PointerAuthenticationMode::SignAndAuth;
+ if (authentication_mode_int >=
+ static_cast<unsigned>(clang::PointerAuthenticationMode::None) &&
+ authentication_mode_int <=
+ static_cast<unsigned>(
+ clang::PointerAuthenticationMode::SignAndAuth)) {
+ authentication_mode = static_cast<clang::PointerAuthenticationMode>(
+ authentication_mode_int);
+ } else {
+ dwarf->GetObjectFile()->GetModule()->ReportError(
+ "[{0:x16}]: invalid pointer authentication mode method {1:x4}",
+ die.GetOffset(), authentication_mode_int);
+ }
+
+ // FIXME: Use these variables when PointerAuthQualifier is more complete
+ // upstream.
+ (void)is_restricted_integral;
+
+ clang::Qualifiers qualifiers;
+ auto ptr_auth = clang::PointerAuthQualifier::Create(
+ key, addr_disc, extra, authentication_mode, isapointer,
+ authenticates_null_values);
+ qualifiers.setPointerAuth(ptr_auth);
+ auto &ctx = m_ast.getASTContext();
+ auto qual_type = ctx.getQualifiedType(ptr_type, qualifiers);
+ clang_type =
+ CompilerType(m_ast.weak_from_this(), qual_type.getAsOpaquePtr());
+ break;
+ }
case DW_TAG_atomic_type:
encoding_data_type = Type::eEncodingIsAtomicUID;
break;
>From 8aa1ba0b05362b8960faac1945bb25c68ecb4b98 Mon Sep 17 00:00:00 2001
From: Daniil Kovalev <dkovalev at accesssoftek.com>
Date: Thu, 7 Mar 2024 16:34:09 +0300
Subject: [PATCH 2/6] [PAC][lldb] Use `eEncodingIsLLVMPtrAuthUID` for
`__ptrauth`-qualified types
---
lldb/include/lldb/Symbol/Type.h | 4 +++-
.../Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp | 2 +-
lldb/source/Symbol/Type.cpp | 8 +++++++-
3 files changed, 11 insertions(+), 3 deletions(-)
diff --git a/lldb/include/lldb/Symbol/Type.h b/lldb/include/lldb/Symbol/Type.h
index acd1a769f13cd6..d55280b58bc4f7 100644
--- a/lldb/include/lldb/Symbol/Type.h
+++ b/lldb/include/lldb/Symbol/Type.h
@@ -401,7 +401,9 @@ class Type : public std::enable_shared_from_this<Type>, public UserID {
/// This type is the type whose UID is m_encoding_uid as an atomic type.
eEncodingIsAtomicUID,
/// This type is the synthetic type whose UID is m_encoding_uid.
- eEncodingIsSyntheticUID
+ eEncodingIsSyntheticUID,
+ /// This type is a signed pointer.
+ eEncodingIsLLVMPtrAuthUID
};
enum class ResolveState : unsigned char {
diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp b/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
index 67fe830e1aa70d..1e13962aadd43e 100644
--- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
+++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
@@ -684,7 +684,7 @@ DWARFASTParserClang::ParseTypeModifier(const SymbolContext &sc,
if (!res_type)
break;
attrs.type.Clear();
- encoding_data_type = Type::eEncodingIsUID;
+ encoding_data_type = Type::eEncodingIsLLVMPtrAuthUID;
resolve_state = Type::ResolveState::Full;
// Apply the ptrauth qualifier to the resolved type.
diff --git a/lldb/source/Symbol/Type.cpp b/lldb/source/Symbol/Type.cpp
index 6069d066eaf66b..60ad7bc029eb17 100644
--- a/lldb/source/Symbol/Type.cpp
+++ b/lldb/source/Symbol/Type.cpp
@@ -355,6 +355,9 @@ void Type::GetDescription(Stream *s, lldb::DescriptionLevel level,
case eEncodingIsSyntheticUID:
s->PutCString(" (synthetic type)");
break;
+ case eEncodingIsLLVMPtrAuthUID:
+ s->PutCString(" (ptrauth type)");
+ break;
}
}
}
@@ -416,6 +419,8 @@ void Type::Dump(Stream *s, bool show_context, lldb::DescriptionLevel level) {
case eEncodingIsSyntheticUID:
s->PutCString(" (synthetic type)");
break;
+ case eEncodingIsLLVMPtrAuthUID:
+ s->PutCString(" (ptrauth type)");
}
}
@@ -477,7 +482,8 @@ std::optional<uint64_t> Type::GetByteSize(ExecutionContextScope *exe_scope) {
// If we are a pointer or reference, then this is just a pointer size;
case eEncodingIsPointerUID:
case eEncodingIsLValueReferenceUID:
- case eEncodingIsRValueReferenceUID: {
+ case eEncodingIsRValueReferenceUID:
+ case eEncodingIsLLVMPtrAuthUID: {
if (ArchSpec arch = m_symbol_file->GetObjectFile()->GetArchitecture()) {
m_byte_size = arch.GetAddressByteSize();
m_byte_size_has_value = true;
>From 013a85a11493057b632d4492dacb22d53dae4481 Mon Sep 17 00:00:00 2001
From: Daniil Kovalev <dkovalev at accesssoftek.com>
Date: Thu, 7 Mar 2024 16:41:51 +0300
Subject: [PATCH 3/6] [PAC][lldb] Support `__ptrauth` types in `CompilerType`
and `TypeSystemClang`
---
lldb/include/lldb/Symbol/CompilerType.h | 13 +++++
lldb/include/lldb/Symbol/TypeSystem.h | 17 +++++++
.../TypeSystem/Clang/TypeSystemClang.cpp | 47 +++++++++++++++++++
.../TypeSystem/Clang/TypeSystemClang.h | 8 ++++
lldb/source/Symbol/CompilerType.cpp | 32 +++++++++++++
lldb/source/Symbol/TypeSystem.cpp | 7 +++
6 files changed, 124 insertions(+)
diff --git a/lldb/include/lldb/Symbol/CompilerType.h b/lldb/include/lldb/Symbol/CompilerType.h
index 414c44275aaafc..a0ed6999548f87 100644
--- a/lldb/include/lldb/Symbol/CompilerType.h
+++ b/lldb/include/lldb/Symbol/CompilerType.h
@@ -262,6 +262,12 @@ class CompilerType {
size_t GetPointerByteSize() const;
/// \}
+ unsigned GetPtrAuthKey() const;
+
+ unsigned GetPtrAuthDiscriminator() const;
+
+ bool GetPtrAuthAddressDiversity() const;
+
/// Accessors.
/// \{
@@ -369,6 +375,13 @@ class CompilerType {
/// Create related types using the current type's AST
CompilerType GetBasicTypeFromAST(lldb::BasicType basic_type) const;
+
+ /// Return a new CompilerType adds a ptrauth modifier with given parameters to
+ /// this type if this type is valid and the type system supports ptrauth
+ /// modifiers, else return an invalid type. Note that this does not check if
+ /// this type is a pointer.
+ CompilerType AddPtrAuthModifier(unsigned key, bool isAddressDiscriminated,
+ unsigned extraDiscriminator) const;
/// \}
/// Exploring the type.
diff --git a/lldb/include/lldb/Symbol/TypeSystem.h b/lldb/include/lldb/Symbol/TypeSystem.h
index 63829131556e87..ecb92c62821dcd 100644
--- a/lldb/include/lldb/Symbol/TypeSystem.h
+++ b/lldb/include/lldb/Symbol/TypeSystem.h
@@ -216,6 +216,16 @@ class TypeSystem : public PluginInterface,
virtual uint32_t GetPointerByteSize() = 0;
+ // TODO: are we allowed to insert virtual functions in the middle of the class
+ // interface and break ABI?
+ virtual unsigned GetPtrAuthKey(lldb::opaque_compiler_type_t type) = 0;
+
+ virtual unsigned
+ GetPtrAuthDiscriminator(lldb::opaque_compiler_type_t type) = 0;
+
+ virtual bool
+ GetPtrAuthAddressDiversity(lldb::opaque_compiler_type_t type) = 0;
+
// Accessors
virtual ConstString GetTypeName(lldb::opaque_compiler_type_t type,
@@ -280,6 +290,13 @@ class TypeSystem : public PluginInterface,
virtual CompilerType AddRestrictModifier(lldb::opaque_compiler_type_t type);
+ // TODO: are we allowed to insert virtual functions in the middle of the class
+ // interface and break ABI?
+ virtual CompilerType AddPtrAuthModifier(lldb::opaque_compiler_type_t type,
+ unsigned key,
+ bool isAddressDiscriminated,
+ unsigned extraDiscriminator);
+
/// \param opaque_payload The m_payload field of Type, which may
/// carry TypeSystem-specific extra information.
virtual CompilerType CreateTypedef(lldb::opaque_compiler_type_t type,
diff --git a/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp b/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp
index 51ab13108feb3a..3e8da08a915982 100644
--- a/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp
+++ b/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp
@@ -2975,6 +2975,35 @@ bool TypeSystemClang::IsCStringType(lldb::opaque_compiler_type_t type,
return false;
}
+unsigned TypeSystemClang::GetPtrAuthKey(lldb::opaque_compiler_type_t type) {
+ if (type) {
+ clang::QualType qual_type(GetCanonicalQualType(type));
+ if (auto pointer_auth = qual_type.getPointerAuth())
+ return pointer_auth.getKey();
+ }
+ return 0;
+}
+
+unsigned
+TypeSystemClang::GetPtrAuthDiscriminator(lldb::opaque_compiler_type_t type) {
+ if (type) {
+ clang::QualType qual_type(GetCanonicalQualType(type));
+ if (auto pointer_auth = qual_type.getPointerAuth())
+ return pointer_auth.getExtraDiscriminator();
+ }
+ return 0;
+}
+
+bool TypeSystemClang::GetPtrAuthAddressDiversity(
+ lldb::opaque_compiler_type_t type) {
+ if (type) {
+ clang::QualType qual_type(GetCanonicalQualType(type));
+ if (auto pointer_auth = qual_type.getPointerAuth())
+ return pointer_auth.isAddressDiscriminated();
+ }
+ return false;
+}
+
bool TypeSystemClang::IsFunctionType(lldb::opaque_compiler_type_t type) {
auto isFunctionType = [&](clang::QualType qual_type) {
return qual_type->isFunctionType();
@@ -4560,6 +4589,24 @@ TypeSystemClang::AddConstModifier(lldb::opaque_compiler_type_t type) {
return CompilerType();
}
+CompilerType
+TypeSystemClang::AddPtrAuthModifier(lldb::opaque_compiler_type_t type,
+ unsigned key, bool isAddressDiscriminated,
+ unsigned extraDiscriminator) {
+ if (type) {
+ clang::ASTContext &clang_ast = getASTContext();
+ auto pauth = PointerAuthQualifier::Create(
+ key, isAddressDiscriminated, extraDiscriminator,
+ PointerAuthenticationMode::SignAndAuth,
+ /* isIsaPointer */ false,
+ /* authenticatesNullValues */ false);
+ clang::QualType result =
+ clang_ast.getPointerAuthType(GetQualType(type), pauth);
+ return GetType(result);
+ }
+ return CompilerType();
+}
+
CompilerType
TypeSystemClang::AddVolatileModifier(lldb::opaque_compiler_type_t type) {
if (type) {
diff --git a/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.h b/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.h
index a73164895baa80..f3598d0cb181c6 100644
--- a/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.h
+++ b/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.h
@@ -648,6 +648,10 @@ class TypeSystemClang : public TypeSystem {
bool IsFloatingPointType(lldb::opaque_compiler_type_t type, uint32_t &count,
bool &is_complex) override;
+ unsigned GetPtrAuthKey(lldb::opaque_compiler_type_t type) override;
+ unsigned GetPtrAuthDiscriminator(lldb::opaque_compiler_type_t type) override;
+ bool GetPtrAuthAddressDiversity(lldb::opaque_compiler_type_t type) override;
+
bool IsFunctionType(lldb::opaque_compiler_type_t type) override;
uint32_t IsHomogeneousAggregate(lldb::opaque_compiler_type_t type,
@@ -788,6 +792,10 @@ class TypeSystemClang : public TypeSystem {
CompilerType AddConstModifier(lldb::opaque_compiler_type_t type) override;
+ CompilerType AddPtrAuthModifier(lldb::opaque_compiler_type_t type,
+ unsigned key, bool isAddressDiscriminated,
+ unsigned extraDiscriminator) override;
+
CompilerType AddVolatileModifier(lldb::opaque_compiler_type_t type) override;
CompilerType AddRestrictModifier(lldb::opaque_compiler_type_t type) override;
diff --git a/lldb/source/Symbol/CompilerType.cpp b/lldb/source/Symbol/CompilerType.cpp
index 76b79daa6ac154..b8fc6b1946a1a4 100644
--- a/lldb/source/Symbol/CompilerType.cpp
+++ b/lldb/source/Symbol/CompilerType.cpp
@@ -108,6 +108,27 @@ bool CompilerType::IsConst() const {
return false;
}
+unsigned CompilerType::GetPtrAuthKey() const {
+ if (IsValid())
+ if (auto type_system_sp = GetTypeSystem())
+ return type_system_sp->GetPtrAuthKey(m_type);
+ return 0;
+}
+
+unsigned CompilerType::GetPtrAuthDiscriminator() const {
+ if (IsValid())
+ if (auto type_system_sp = GetTypeSystem())
+ return type_system_sp->GetPtrAuthDiscriminator(m_type);
+ return 0;
+}
+
+bool CompilerType::GetPtrAuthAddressDiversity() const {
+ if (IsValid())
+ if (auto type_system_sp = GetTypeSystem())
+ return type_system_sp->GetPtrAuthAddressDiversity(m_type);
+ return false;
+}
+
bool CompilerType::IsFunctionType() const {
if (IsValid())
if (auto type_system_sp = GetTypeSystem())
@@ -664,6 +685,17 @@ CompilerType CompilerType::GetPointerType() const {
return CompilerType();
}
+CompilerType
+CompilerType::AddPtrAuthModifier(unsigned key, bool isAddressDiscriminated,
+ unsigned extraDiscriminator) const {
+ if (IsValid()) {
+ if (auto type_system_sp = GetTypeSystem())
+ return type_system_sp->AddPtrAuthModifier(
+ m_type, key, isAddressDiscriminated, extraDiscriminator);
+ }
+ return CompilerType();
+}
+
CompilerType CompilerType::GetLValueReferenceType() const {
if (IsValid())
if (auto type_system_sp = GetTypeSystem())
diff --git a/lldb/source/Symbol/TypeSystem.cpp b/lldb/source/Symbol/TypeSystem.cpp
index 59b1b39e635ac5..80e3d62320278a 100644
--- a/lldb/source/Symbol/TypeSystem.cpp
+++ b/lldb/source/Symbol/TypeSystem.cpp
@@ -93,6 +93,13 @@ CompilerType TypeSystem::AddConstModifier(lldb::opaque_compiler_type_t type) {
return CompilerType();
}
+CompilerType TypeSystem::AddPtrAuthModifier(lldb::opaque_compiler_type_t type,
+ unsigned key,
+ bool isAddressDiscriminated,
+ unsigned extraDiscriminator) {
+ return CompilerType();
+}
+
CompilerType
TypeSystem::AddVolatileModifier(lldb::opaque_compiler_type_t type) {
return CompilerType();
>From 4164b7e60c5f5feffce5b8d4c24937a28fbbe010 Mon Sep 17 00:00:00 2001
From: Daniil Kovalev <dkovalev at accesssoftek.com>
Date: Thu, 7 Mar 2024 16:43:08 +0300
Subject: [PATCH 4/6] [PAC][lldb] Test parsing `__ptrauth`-qalified types in
`DWARFASTParserClang`
---
.../DWARF/DWARFASTParserClangTests.cpp | 135 ++++++++++++++++++
1 file changed, 135 insertions(+)
diff --git a/lldb/unittests/SymbolFile/DWARF/DWARFASTParserClangTests.cpp b/lldb/unittests/SymbolFile/DWARF/DWARFASTParserClangTests.cpp
index 0c2a0d735dc837..f7a4b8f1ac59be 100644
--- a/lldb/unittests/SymbolFile/DWARF/DWARFASTParserClangTests.cpp
+++ b/lldb/unittests/SymbolFile/DWARF/DWARFASTParserClangTests.cpp
@@ -287,6 +287,141 @@ TEST_F(DWARFASTParserClangTests, TestCallingConventionParsing) {
ASSERT_EQ(found_function_types, expected_function_types);
}
+TEST_F(DWARFASTParserClangTests, TestPtrAuthParsing) {
+ // Tests parsing values with type DW_TAG_LLVM_ptrauth_type corresponding to
+ // explicitly signed raw function pointers
+
+ // This is Dwarf for the following C code:
+ // ```
+ // void (*__ptrauth(0, 0, 42) a)();
+ // ```
+
+ const char *yamldata = R"(
+--- !ELF
+FileHeader:
+ Class: ELFCLASS64
+ Data: ELFDATA2LSB
+ Type: ET_EXEC
+ Machine: EM_AARCH64
+DWARF:
+ debug_str:
+ - a
+ debug_abbrev:
+ - ID: 0
+ Table:
+ - Code: 0x01
+ Tag: DW_TAG_compile_unit
+ Children: DW_CHILDREN_yes
+ Attributes:
+ - Attribute: DW_AT_language
+ Form: DW_FORM_data2
+ - Code: 0x02
+ Tag: DW_TAG_variable
+ Children: DW_CHILDREN_no
+ Attributes:
+ - Attribute: DW_AT_name
+ Form: DW_FORM_strp
+ - Attribute: DW_AT_type
+ Form: DW_FORM_ref4
+ - Attribute: DW_AT_external
+ Form: DW_FORM_flag_present
+ - Code: 0x03
+ Tag: DW_TAG_LLVM_ptrauth_type
+ Children: DW_CHILDREN_no
+ Attributes:
+ - Attribute: DW_AT_type
+ Form: DW_FORM_ref4
+ - Attribute: DW_AT_LLVM_ptrauth_key
+ Form: DW_FORM_data1
+ - Attribute: DW_AT_LLVM_ptrauth_extra_discriminator
+ Form: DW_FORM_data2
+ - Code: 0x04
+ Tag: DW_TAG_pointer_type
+ Children: DW_CHILDREN_no
+ Attributes:
+ - Attribute: DW_AT_type
+ Form: DW_FORM_ref4
+ - Code: 0x05
+ Tag: DW_TAG_subroutine_type
+ Children: DW_CHILDREN_yes
+ - Code: 0x06
+ Tag: DW_TAG_unspecified_parameters
+ Children: DW_CHILDREN_no
+
+ debug_info:
+ - Version: 5
+ UnitType: DW_UT_compile
+ AddrSize: 8
+ Entries:
+# 0x0c: DW_TAG_compile_unit
+# DW_AT_language [DW_FORM_data2] (DW_LANG_C99)
+ - AbbrCode: 0x01
+ Values:
+ - Value: 0x0c
+
+# 0x0f: DW_TAG_variable
+# DW_AT_name [DW_FORM_strp] (\"a\")
+# DW_AT_type [DW_FORM_ref4] (0x00000018 \"void (*__ptrauth(0, 0, 0x02a)\")
+# DW_AT_external [DW_FORM_flag_present] (true)
+ - AbbrCode: 0x02
+ Values:
+ - Value: 0x00
+ - Value: 0x18
+
+# 0x18: DW_TAG_LLVM_ptrauth_type
+# DW_AT_type [DW_FORM_ref4] (0x00000020 \"void (*)(...)\")
+# DW_AT_LLVM_ptrauth_key [DW_FORM_data1] (0x00)
+# DW_AT_LLVM_ptrauth_extra_discriminator [DW_FORM_data2] (0x002a)
+ - AbbrCode: 0x03
+ Values:
+ - Value: 0x20
+ - Value: 0x00
+ - Value: 0x2a
+
+# 0x20: DW_TAG_pointer_type
+# DW_AT_type [DW_AT_type [DW_FORM_ref4] (0x00000025 \"void (...)\")
+ - AbbrCode: 0x04
+ Values:
+ - Value: 0x25
+
+# 0x25: DW_TAG_subroutine_type
+ - AbbrCode: 0x05
+
+# 0x26: DW_TAG_unspecified_parameters
+ - AbbrCode: 0x06
+
+ - AbbrCode: 0x00 # end of child tags of 0x25
+ - AbbrCode: 0x00 # end of child tags of 0x0c
+...
+)";
+ YAMLModuleTester t(yamldata);
+
+ DWARFUnit *unit = t.GetDwarfUnit();
+ ASSERT_NE(unit, nullptr);
+ const DWARFDebugInfoEntry *cu_entry = unit->DIE().GetDIE();
+ ASSERT_EQ(cu_entry->Tag(), DW_TAG_compile_unit);
+ DWARFDIE cu_die(unit, cu_entry);
+
+ auto holder = std::make_unique<clang_utils::TypeSystemClangHolder>("ast");
+ auto &ast_ctx = *holder->GetAST();
+ DWARFASTParserClangStub ast_parser(ast_ctx);
+
+ DWARFDIE ptrauth_variable = cu_die.GetFirstChild();
+ ASSERT_EQ(ptrauth_variable.Tag(), DW_TAG_variable);
+ DWARFDIE ptrauth_type =
+ ptrauth_variable.GetAttributeValueAsReferenceDIE(DW_AT_type);
+ ASSERT_EQ(ptrauth_type.Tag(), DW_TAG_LLVM_ptrauth_type);
+
+ SymbolContext sc;
+ bool new_type = false;
+ lldb::TypeSP type_sp =
+ ast_parser.ParseTypeFromDWARF(sc, ptrauth_type, &new_type);
+ CompilerType compiler_type = type_sp->GetForwardCompilerType();
+ ASSERT_EQ(compiler_type.GetPtrAuthKey(), 0);
+ ASSERT_EQ(compiler_type.GetPtrAuthAddressDiversity(), false);
+ ASSERT_EQ(compiler_type.GetPtrAuthDiscriminator(), 42);
+}
+
struct ExtractIntFromFormValueTest : public testing::Test {
SubsystemRAII<FileSystem, HostInfo> subsystems;
clang_utils::TypeSystemClangHolder holder;
>From ced59fd6d4fcaa1a4158708fde3a4b0e9af2e5c2 Mon Sep 17 00:00:00 2001
From: Daniil Kovalev <dkovalev at accesssoftek.com>
Date: Tue, 26 Mar 2024 22:34:52 +0300
Subject: [PATCH 5/6] Delete TODOs
---
lldb/include/lldb/Symbol/TypeSystem.h | 4 ----
1 file changed, 4 deletions(-)
diff --git a/lldb/include/lldb/Symbol/TypeSystem.h b/lldb/include/lldb/Symbol/TypeSystem.h
index 085ac4a37feab7..ca92fa790d2614 100644
--- a/lldb/include/lldb/Symbol/TypeSystem.h
+++ b/lldb/include/lldb/Symbol/TypeSystem.h
@@ -216,8 +216,6 @@ class TypeSystem : public PluginInterface,
virtual uint32_t GetPointerByteSize() = 0;
- // TODO: are we allowed to insert virtual functions in the middle of the class
- // interface and break ABI?
virtual unsigned GetPtrAuthKey(lldb::opaque_compiler_type_t type) = 0;
virtual unsigned
@@ -290,8 +288,6 @@ class TypeSystem : public PluginInterface,
virtual CompilerType AddRestrictModifier(lldb::opaque_compiler_type_t type);
- // TODO: are we allowed to insert virtual functions in the middle of the class
- // interface and break ABI?
virtual CompilerType AddPtrAuthModifier(lldb::opaque_compiler_type_t type,
unsigned key,
bool isAddressDiscriminated,
>From eecbb370d3d0257a5a4ffb644448219d41aa5426 Mon Sep 17 00:00:00 2001
From: Daniil Kovalev <dkovalev at accesssoftek.com>
Date: Thu, 28 Mar 2024 12:52:24 +0300
Subject: [PATCH 6/6] Implement lazy resolve of ptrauth types
---
lldb/include/lldb/Symbol/CompilerType.h | 11 +--
lldb/include/lldb/Symbol/TypeSystem.h | 4 +-
.../SymbolFile/DWARF/DWARFASTParserClang.cpp | 93 ++++++++-----------
.../TypeSystem/Clang/TypeSystemClang.cpp | 9 +-
.../TypeSystem/Clang/TypeSystemClang.h | 7 +-
lldb/source/Symbol/CompilerType.cpp | 10 +-
lldb/source/Symbol/Type.cpp | 10 ++
lldb/source/Symbol/TypeSystem.cpp | 4 +-
8 files changed, 63 insertions(+), 85 deletions(-)
diff --git a/lldb/include/lldb/Symbol/CompilerType.h b/lldb/include/lldb/Symbol/CompilerType.h
index f9d3da5704454c..872066b8c73207 100644
--- a/lldb/include/lldb/Symbol/CompilerType.h
+++ b/lldb/include/lldb/Symbol/CompilerType.h
@@ -376,12 +376,11 @@ class CompilerType {
/// Create related types using the current type's AST
CompilerType GetBasicTypeFromAST(lldb::BasicType basic_type) const;
- /// Return a new CompilerType adds a ptrauth modifier with given parameters to
- /// this type if this type is valid and the type system supports ptrauth
- /// modifiers, else return an invalid type. Note that this does not check if
- /// this type is a pointer.
- CompilerType AddPtrAuthModifier(unsigned key, bool isAddressDiscriminated,
- unsigned extraDiscriminator) const;
+ /// Return a new CompilerType adds a ptrauth modifier from the given 32-bit
+ /// opaque payload to this type if this type is valid and the type system
+ /// supports ptrauth modifiers, else return an invalid type. Note that this
+ /// does not check if this type is a pointer.
+ CompilerType AddPtrAuthModifier(uint32_t payload) const;
/// \}
/// Exploring the type.
diff --git a/lldb/include/lldb/Symbol/TypeSystem.h b/lldb/include/lldb/Symbol/TypeSystem.h
index ca92fa790d2614..03aa939ba6c7e0 100644
--- a/lldb/include/lldb/Symbol/TypeSystem.h
+++ b/lldb/include/lldb/Symbol/TypeSystem.h
@@ -289,9 +289,7 @@ class TypeSystem : public PluginInterface,
virtual CompilerType AddRestrictModifier(lldb::opaque_compiler_type_t type);
virtual CompilerType AddPtrAuthModifier(lldb::opaque_compiler_type_t type,
- unsigned key,
- bool isAddressDiscriminated,
- unsigned extraDiscriminator);
+ uint32_t payload);
/// \param opaque_payload The m_payload field of Type, which may
/// carry TypeSystem-specific extra information.
diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp b/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
index 1e13962aadd43e..5ff3f0d614e6e3 100644
--- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
+++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
@@ -570,6 +570,39 @@ ExtractDataMemberLocation(DWARFDIE const &die, DWARFFormValue const &form_value,
return memberOffset.ResolveValue(nullptr).UInt();
}
+static TypePayloadClang GetPtrAuthMofidierPayload(const DWARFDIE &die) {
+ auto getAttr = [&](llvm::dwarf::Attribute Attr, unsigned defaultValue = 0) {
+ return die.GetAttributeValueAsUnsigned(Attr, defaultValue);
+ };
+ const unsigned key = getAttr(DW_AT_LLVM_ptrauth_key);
+ const bool addr_disc = getAttr(DW_AT_LLVM_ptrauth_address_discriminated);
+ const unsigned extra = getAttr(DW_AT_LLVM_ptrauth_extra_discriminator);
+ const bool isapointer = getAttr(DW_AT_LLVM_ptrauth_isa_pointer);
+ const bool authenticates_null_values =
+ getAttr(DW_AT_LLVM_ptrauth_authenticates_null_values);
+ const unsigned authentication_mode_int = getAttr(
+ DW_AT_LLVM_ptrauth_authentication_mode,
+ static_cast<unsigned>(clang::PointerAuthenticationMode::SignAndAuth));
+ clang::PointerAuthenticationMode authentication_mode =
+ clang::PointerAuthenticationMode::SignAndAuth;
+ if (authentication_mode_int >=
+ static_cast<unsigned>(clang::PointerAuthenticationMode::None) &&
+ authentication_mode_int <=
+ static_cast<unsigned>(
+ clang::PointerAuthenticationMode::SignAndAuth)) {
+ authentication_mode =
+ static_cast<clang::PointerAuthenticationMode>(authentication_mode_int);
+ } else {
+ die.GetDWARF()->GetObjectFile()->GetModule()->ReportError(
+ "[{0:x16}]: invalid pointer authentication mode method {1:x4}",
+ die.GetOffset(), authentication_mode_int);
+ }
+ auto ptr_auth = clang::PointerAuthQualifier::Create(
+ key, addr_disc, extra, authentication_mode, isapointer,
+ authenticates_null_values);
+ return TypePayloadClang(ptr_auth.getAsOpaqueValue());
+}
+
lldb::TypeSP
DWARFASTParserClang::ParseTypeModifier(const SymbolContext &sc,
const DWARFDIE &die,
@@ -580,6 +613,7 @@ DWARFASTParserClang::ParseTypeModifier(const SymbolContext &sc,
LanguageType cu_language = SymbolFileDWARF::GetLanguage(*die.GetCU());
Type::ResolveState resolve_state = Type::ResolveState::Unresolved;
Type::EncodingDataType encoding_data_type = Type::eEncodingIsUID;
+ TypePayloadClang payload(GetOwningClangModule(die));
TypeSP type_sp;
CompilerType clang_type;
@@ -677,62 +711,10 @@ DWARFASTParserClang::ParseTypeModifier(const SymbolContext &sc,
case DW_TAG_volatile_type:
encoding_data_type = Type::eEncodingIsVolatileUID;
break;
- case DW_TAG_LLVM_ptrauth_type: {
- DWARFDIE ptr_die = die.GetReferencedDIE(DW_AT_type);
- // FIXME: Fully resolving the type here may affect performance.
- Type *res_type = dwarf->ResolveType(ptr_die);
- if (!res_type)
- break;
- attrs.type.Clear();
+ case DW_TAG_LLVM_ptrauth_type:
encoding_data_type = Type::eEncodingIsLLVMPtrAuthUID;
- resolve_state = Type::ResolveState::Full;
-
- // Apply the ptrauth qualifier to the resolved type.
- auto *ptr_type =
- (clang::Type *)res_type->GetForwardCompilerType().GetOpaqueQualType();
- auto getAttr = [&](llvm::dwarf::Attribute Attr, unsigned defaultValue = 0) {
- return die.GetAttributeValueAsUnsigned(Attr, defaultValue);
- };
- const unsigned key = getAttr(DW_AT_LLVM_ptrauth_key);
- const bool addr_disc = getAttr(DW_AT_LLVM_ptrauth_address_discriminated);
- const unsigned extra = getAttr(DW_AT_LLVM_ptrauth_extra_discriminator);
- const bool isapointer = getAttr(DW_AT_LLVM_ptrauth_isa_pointer);
- const bool authenticates_null_values =
- getAttr(DW_AT_LLVM_ptrauth_authenticates_null_values, 0);
- const bool is_restricted_integral = !ptr_type->isPointerType();
- const unsigned authentication_mode_int = getAttr(
- DW_AT_LLVM_ptrauth_authentication_mode,
- static_cast<unsigned>(clang::PointerAuthenticationMode::SignAndAuth));
- clang::PointerAuthenticationMode authentication_mode =
- clang::PointerAuthenticationMode::SignAndAuth;
- if (authentication_mode_int >=
- static_cast<unsigned>(clang::PointerAuthenticationMode::None) &&
- authentication_mode_int <=
- static_cast<unsigned>(
- clang::PointerAuthenticationMode::SignAndAuth)) {
- authentication_mode = static_cast<clang::PointerAuthenticationMode>(
- authentication_mode_int);
- } else {
- dwarf->GetObjectFile()->GetModule()->ReportError(
- "[{0:x16}]: invalid pointer authentication mode method {1:x4}",
- die.GetOffset(), authentication_mode_int);
- }
-
- // FIXME: Use these variables when PointerAuthQualifier is more complete
- // upstream.
- (void)is_restricted_integral;
-
- clang::Qualifiers qualifiers;
- auto ptr_auth = clang::PointerAuthQualifier::Create(
- key, addr_disc, extra, authentication_mode, isapointer,
- authenticates_null_values);
- qualifiers.setPointerAuth(ptr_auth);
- auto &ctx = m_ast.getASTContext();
- auto qual_type = ctx.getQualifiedType(ptr_type, qualifiers);
- clang_type =
- CompilerType(m_ast.weak_from_this(), qual_type.getAsOpaquePtr());
+ payload = GetPtrAuthMofidierPayload(die);
break;
- }
case DW_TAG_atomic_type:
encoding_data_type = Type::eEncodingIsAtomicUID;
break;
@@ -842,8 +824,7 @@ DWARFASTParserClang::ParseTypeModifier(const SymbolContext &sc,
type_sp = dwarf->MakeType(die.GetID(), attrs.name, attrs.byte_size, nullptr,
attrs.type.Reference().GetID(), encoding_data_type,
- &attrs.decl, clang_type, resolve_state,
- TypePayloadClang(GetOwningClangModule(die)));
+ &attrs.decl, clang_type, resolve_state, payload);
dwarf->GetDIEToType()[die.GetDIE()] = type_sp.get();
return type_sp;
diff --git a/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp b/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp
index 45d9e67c59a0b5..bcab4fbd0e7859 100644
--- a/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp
+++ b/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp
@@ -4593,15 +4593,10 @@ TypeSystemClang::AddConstModifier(lldb::opaque_compiler_type_t type) {
CompilerType
TypeSystemClang::AddPtrAuthModifier(lldb::opaque_compiler_type_t type,
- unsigned key, bool isAddressDiscriminated,
- unsigned extraDiscriminator) {
+ uint32_t payload) {
if (type) {
clang::ASTContext &clang_ast = getASTContext();
- auto pauth = PointerAuthQualifier::Create(
- key, isAddressDiscriminated, extraDiscriminator,
- PointerAuthenticationMode::SignAndAuth,
- /* isIsaPointer */ false,
- /* authenticatesNullValues */ false);
+ auto pauth = PointerAuthQualifier::fromOpaqueValue(payload);
clang::QualType result =
clang_ast.getPointerAuthType(GetQualType(type), pauth);
return GetType(result);
diff --git a/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.h b/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.h
index 667c62bd263ea5..cf8b9f54ed5598 100644
--- a/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.h
+++ b/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.h
@@ -66,11 +66,13 @@ class OptionalClangModuleID {
/// The implementation of lldb::Type's m_payload field for TypeSystemClang.
class TypePayloadClang {
- /// The Layout is as follows:
+ /// The payload is used for typedefs and ptrauth types.
+ /// For typedefs, the Layout is as follows:
/// \verbatim
/// bit 0..30 ... Owning Module ID.
/// bit 31 ...... IsCompleteObjCClass.
/// \endverbatim
+ /// For ptrauth types, we store the PointerAuthQualifier as an opaque value.
Type::Payload m_payload = 0;
public:
@@ -793,8 +795,7 @@ class TypeSystemClang : public TypeSystem {
CompilerType AddConstModifier(lldb::opaque_compiler_type_t type) override;
CompilerType AddPtrAuthModifier(lldb::opaque_compiler_type_t type,
- unsigned key, bool isAddressDiscriminated,
- unsigned extraDiscriminator) override;
+ uint32_t payload) override;
CompilerType AddVolatileModifier(lldb::opaque_compiler_type_t type) override;
diff --git a/lldb/source/Symbol/CompilerType.cpp b/lldb/source/Symbol/CompilerType.cpp
index 88cd65bfaa6a45..af66856479223f 100644
--- a/lldb/source/Symbol/CompilerType.cpp
+++ b/lldb/source/Symbol/CompilerType.cpp
@@ -685,14 +685,10 @@ CompilerType CompilerType::GetPointerType() const {
return CompilerType();
}
-CompilerType
-CompilerType::AddPtrAuthModifier(unsigned key, bool isAddressDiscriminated,
- unsigned extraDiscriminator) const {
- if (IsValid()) {
+CompilerType CompilerType::AddPtrAuthModifier(uint32_t payload) const {
+ if (IsValid())
if (auto type_system_sp = GetTypeSystem())
- return type_system_sp->AddPtrAuthModifier(
- m_type, key, isAddressDiscriminated, extraDiscriminator);
- }
+ return type_system_sp->AddPtrAuthModifier(m_type, payload);
return CompilerType();
}
diff --git a/lldb/source/Symbol/Type.cpp b/lldb/source/Symbol/Type.cpp
index 89e9a7a256e1bb..ca505981002f4b 100644
--- a/lldb/source/Symbol/Type.cpp
+++ b/lldb/source/Symbol/Type.cpp
@@ -627,6 +627,12 @@ bool Type::ResolveCompilerType(ResolveState compiler_type_resolve_state) {
encoding_type->GetForwardCompilerType().GetRValueReferenceType();
break;
+ case eEncodingIsLLVMPtrAuthUID:
+ m_compiler_type =
+ encoding_type->GetForwardCompilerType().AddPtrAuthModifier(
+ m_payload);
+ break;
+
default:
llvm_unreachable("Unhandled encoding_data_type.");
}
@@ -682,6 +688,10 @@ bool Type::ResolveCompilerType(ResolveState compiler_type_resolve_state) {
m_compiler_type = void_compiler_type.GetRValueReferenceType();
break;
+ case eEncodingIsLLVMPtrAuthUID:
+ llvm_unreachable("Cannot handle eEncodingIsLLVMPtrAuthUID without "
+ "valid encoding_type");
+
default:
llvm_unreachable("Unhandled encoding_data_type.");
}
diff --git a/lldb/source/Symbol/TypeSystem.cpp b/lldb/source/Symbol/TypeSystem.cpp
index 80e3d62320278a..3665771b188906 100644
--- a/lldb/source/Symbol/TypeSystem.cpp
+++ b/lldb/source/Symbol/TypeSystem.cpp
@@ -94,9 +94,7 @@ CompilerType TypeSystem::AddConstModifier(lldb::opaque_compiler_type_t type) {
}
CompilerType TypeSystem::AddPtrAuthModifier(lldb::opaque_compiler_type_t type,
- unsigned key,
- bool isAddressDiscriminated,
- unsigned extraDiscriminator) {
+ uint32_t payload) {
return CompilerType();
}
More information about the lldb-commits
mailing list