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 <jo...@devlieghere.com> Date: Tue, 20 Feb 2024 10:57:54 -0800 Subject: [PATCH 01/10] 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 <dkova...@accesssoftek.com> Date: Thu, 7 Mar 2024 16:34:09 +0300 Subject: [PATCH 02/10] [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 <dkova...@accesssoftek.com> Date: Thu, 7 Mar 2024 16:41:51 +0300 Subject: [PATCH 03/10] [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 <dkova...@accesssoftek.com> Date: Thu, 7 Mar 2024 16:43:08 +0300 Subject: [PATCH 04/10] [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 8ef23c0c4bd0294fdf956f3db52fc305734e701a Mon Sep 17 00:00:00 2001 From: John McCall <rjmcc...@apple.com> Date: Mon, 16 Dec 2019 20:31:25 -0500 Subject: [PATCH 05/10] Abstract serialization fixes for the Apple Clang changes. --- clang/include/clang/AST/AbstractBasicReader.h | 4 ++-- clang/include/clang/AST/AbstractBasicWriter.h | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/clang/include/clang/AST/AbstractBasicReader.h b/clang/include/clang/AST/AbstractBasicReader.h index 1f2797cc701458..ab036f1d445acc 100644 --- a/clang/include/clang/AST/AbstractBasicReader.h +++ b/clang/include/clang/AST/AbstractBasicReader.h @@ -213,9 +213,9 @@ class DataStreamBasicReader : public BasicReaderBase<Impl> { } Qualifiers readQualifiers() { - static_assert(sizeof(Qualifiers().getAsOpaqueValue()) <= sizeof(uint32_t), + static_assert(sizeof(Qualifiers().getAsOpaqueValue()) <= sizeof(uint64_t), "update this if the value size changes"); - uint32_t value = asImpl().readUInt32(); + uint64_t value = asImpl().readUInt64(); return Qualifiers::fromOpaqueValue(value); } diff --git a/clang/include/clang/AST/AbstractBasicWriter.h b/clang/include/clang/AST/AbstractBasicWriter.h index 07afa388de2c17..8e42fcaad1d388 100644 --- a/clang/include/clang/AST/AbstractBasicWriter.h +++ b/clang/include/clang/AST/AbstractBasicWriter.h @@ -196,9 +196,9 @@ class DataStreamBasicWriter : public BasicWriterBase<Impl> { } void writeQualifiers(Qualifiers value) { - static_assert(sizeof(value.getAsOpaqueValue()) <= sizeof(uint32_t), + static_assert(sizeof(value.getAsOpaqueValue()) <= sizeof(uint64_t), "update this if the value size changes"); - asImpl().writeUInt32(value.getAsOpaqueValue()); + asImpl().writeUInt64(value.getAsOpaqueValue()); } void writeExceptionSpecInfo( >From f448a380dbc6710e4eb9447b6a562ff24e68386a Mon Sep 17 00:00:00 2001 From: Daniil Kovalev <dkova...@accesssoftek.com> Date: Thu, 7 Mar 2024 15:34:24 +0300 Subject: [PATCH 06/10] Define `PointerAuthenticationMode` enum --- clang/include/clang/Basic/LangOptions.h | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/clang/include/clang/Basic/LangOptions.h b/clang/include/clang/Basic/LangOptions.h index 24b109e32cdd3e..692b90dc9b9ec8 100644 --- a/clang/include/clang/Basic/LangOptions.h +++ b/clang/include/clang/Basic/LangOptions.h @@ -57,6 +57,13 @@ enum class ShaderStage { Invalid, }; +enum class PointerAuthenticationMode : unsigned { + None, + Strip, + SignAndStrip, + SignAndAuth +}; + /// Bitfields of LangOptions, split out from LangOptions in order to ensure that /// this large collection of bitfields is a trivial class type. class LangOptionsBase { >From 9f97ed4b0b90ffbc3422ced47966bb742bd743b6 Mon Sep 17 00:00:00 2001 From: Daniil Kovalev <dkova...@accesssoftek.com> Date: Thu, 7 Mar 2024 15:31:03 +0300 Subject: [PATCH 07/10] Define `PointerAuthQualifier` class Includes changes from the following commits from the branch https://github.com/ahmedbougacha/llvm-project/tree/eng/arm64e-upstream-llvmorg - Initial support https://github.com/ahmedbougacha/llvm-project/commit/cc7ba7eb1814e9b254c7d94aa0b78cb0e21acfc5 - ObjC isa signing https://github.com/ahmedbougacha/llvm-project/commit/c9ce0d408f1d9aeffc7b86256334220aec6de5a3 Also applies a fix from https://github.com/access-softek/llvm-project/pull/75 Co-authored-by: Ahmed Bougacha <ah...@bougacha.org> --- clang/include/clang/AST/Type.h | 215 +++++++++++++++++- .../include/clang/Basic/PointerAuthOptions.h | 23 ++ 2 files changed, 227 insertions(+), 11 deletions(-) create mode 100644 clang/include/clang/Basic/PointerAuthOptions.h diff --git a/clang/include/clang/AST/Type.h b/clang/include/clang/AST/Type.h index b3bf23227a47f2..df370146293cbc 100644 --- a/clang/include/clang/AST/Type.h +++ b/clang/include/clang/AST/Type.h @@ -25,8 +25,10 @@ #include "clang/Basic/Diagnostic.h" #include "clang/Basic/ExceptionSpecificationType.h" #include "clang/Basic/LLVM.h" +#include "clang/Basic/LangOptions.h" #include "clang/Basic/Linkage.h" #include "clang/Basic/PartialDiagnostic.h" +#include "clang/Basic/PointerAuthOptions.h" #include "clang/Basic/SourceLocation.h" #include "clang/Basic/Specifiers.h" #include "clang/Basic/Visibility.h" @@ -139,6 +141,165 @@ using CanQualType = CanQual<Type>; #define TYPE(Class, Base) class Class##Type; #include "clang/AST/TypeNodes.inc" +/// Pointer-authentication qualifiers. +class PointerAuthQualifier { + enum : uint32_t { + EnabledShift = 0, + EnabledBits = 1, + EnabledMask = 1 << EnabledShift, + AddressDiscriminatedShift = EnabledShift + EnabledBits, + AddressDiscriminatedBits = 1, + AddressDiscriminatedMask = 1 << AddressDiscriminatedShift, + AuthenticationModeShift = + AddressDiscriminatedShift + AddressDiscriminatedBits, + AuthenticationModeBits = 2, + AuthenticationModeMask = ((1 << AuthenticationModeBits) - 1) + << AuthenticationModeShift, + IsaPointerShift = AuthenticationModeShift + AuthenticationModeBits, + IsaPointerBits = 1, + IsaPointerMask = ((1 << IsaPointerBits) - 1) << IsaPointerShift, + AuthenticatesNullValuesShift = IsaPointerShift + IsaPointerBits, + AuthenticatesNullValuesBits = 1, + AuthenticatesNullValuesMask = ((1 << AuthenticatesNullValuesBits) - 1) + << AuthenticatesNullValuesShift, + KeyShift = AuthenticatesNullValuesShift + AuthenticatesNullValuesBits, + KeyBits = 10, + KeyMask = ((1 << KeyBits) - 1) << KeyShift, + DiscriminatorShift = KeyShift + KeyBits, + DiscriminatorBits = 16, + DiscriminatorMask = ((1u << DiscriminatorBits) - 1) << DiscriminatorShift, + }; + + // bits: |0 |1 |2..3 |4 | + // |Enabled|Address|AuthenticationMode|ISA pointer| + // bits: |5 |6..15| 16...31 | + // |AuthenticatesNull|Key |Discriminator| + uint32_t Data; + + static_assert((EnabledBits + AddressDiscriminatedBits + + AuthenticationModeBits + IsaPointerBits + + AuthenticatesNullValuesBits + KeyBits + DiscriminatorBits) == + 32, + "PointerAuthQualifier should be exactly 32 bits"); + static_assert((EnabledMask + AddressDiscriminatedMask + + AuthenticationModeMask + IsaPointerMask + + AuthenticatesNullValuesMask + KeyMask + DiscriminatorMask) == + 0xFFFFFFFF, + "All masks should cover the entire bits"); + static_assert((EnabledMask ^ AddressDiscriminatedMask ^ + AuthenticationModeMask ^ IsaPointerMask ^ + AuthenticatesNullValuesMask ^ KeyMask ^ DiscriminatorMask) == + 0xFFFFFFFF, + "All masks should cover the entire bits"); + + PointerAuthQualifier(unsigned key, bool isAddressDiscriminated, + unsigned extraDiscriminator, + PointerAuthenticationMode authenticationMode, + bool isIsaPointer, bool authenticatesNullValues) + : Data(EnabledMask | + (isAddressDiscriminated + ? static_cast<uint32_t>(AddressDiscriminatedMask) + : 0) | + (key << KeyShift) | + (unsigned(authenticationMode) << AuthenticationModeShift) | + (extraDiscriminator << DiscriminatorShift) | + (isIsaPointer << IsaPointerShift) | + (authenticatesNullValues << AuthenticatesNullValuesShift)) { + assert(key <= KeyNoneInternal); + assert(extraDiscriminator <= MaxDiscriminator); + } + +public: + enum { + KeyNoneInternal = (1u << KeyBits) - 1, + + /// The maximum supported pointer-authentication key. + MaxKey = KeyNoneInternal - 1, + + /// The maximum supported pointer-authentication discriminator. + MaxDiscriminator = (1u << DiscriminatorBits) - 1 + }; + +public: + PointerAuthQualifier() : Data(0) {} + + static PointerAuthQualifier + Create(int key, bool isAddressDiscriminated, unsigned extraDiscriminator, + PointerAuthenticationMode authenticationMode, bool isIsaPointer, + bool authenticatesNullValues) { + if (key == PointerAuthKeyNone) + key = KeyNoneInternal; + assert((key >= 0 && key <= KeyNoneInternal) && "out-of-range key value"); + return PointerAuthQualifier(key, isAddressDiscriminated, extraDiscriminator, + authenticationMode, isIsaPointer, + authenticatesNullValues); + } + + bool isPresent() const { + return getAuthenticationMode() != PointerAuthenticationMode::None; + } + + explicit operator bool() const { return isPresent(); } + + unsigned getKey() const { + assert(isPresent()); + return (Data & KeyMask) >> KeyShift; + } + + bool hasKeyNone() const { return isPresent() && getKey() == KeyNoneInternal; } + + bool isAddressDiscriminated() const { + assert(isPresent()); + return (Data & AddressDiscriminatedMask) >> AddressDiscriminatedShift; + } + + unsigned getExtraDiscriminator() const { + assert(isPresent()); + return (Data >> DiscriminatorShift); + } + + PointerAuthenticationMode getAuthenticationMode() const { + return PointerAuthenticationMode((Data & AuthenticationModeMask) >> + AuthenticationModeShift); + } + + bool isIsaPointer() const { + assert(isPresent()); + return (Data & IsaPointerMask) >> IsaPointerShift; + } + + bool authenticatesNullValues() const { + assert(isPresent()); + return (Data & AuthenticatesNullValuesMask) >> AuthenticatesNullValuesShift; + } + + PointerAuthQualifier withoutKeyNone() const { + return hasKeyNone() ? PointerAuthQualifier() : *this; + } + + friend bool operator==(PointerAuthQualifier Lhs, PointerAuthQualifier Rhs) { + return Lhs.Data == Rhs.Data; + } + friend bool operator!=(PointerAuthQualifier Lhs, PointerAuthQualifier Rhs) { + return Lhs.Data != Rhs.Data; + } + + bool isEquivalent(PointerAuthQualifier Other) const { + return withoutKeyNone() == Other.withoutKeyNone(); + } + + uint32_t getAsOpaqueValue() const { return Data; } + + // Deserialize pointer-auth qualifiers from an opaque representation. + static PointerAuthQualifier fromOpaqueValue(uint32_t opaque) { + PointerAuthQualifier result; + result.Data = opaque; + return result; + } + + void Profile(llvm::FoldingSetNodeID &ID) const { ID.AddInteger(Data); } +}; + /// The collection of all-type qualifiers we support. /// Clang supports five independent qualifiers: /// * C99: const, volatile, and restrict @@ -194,19 +355,27 @@ class Qualifiers { FastMask = (1 << FastWidth) - 1 }; + Qualifiers() : Mask(0), PtrAuth() {} + /// Returns the common set of qualifiers while removing them from /// the given sets. static Qualifiers removeCommonQualifiers(Qualifiers &L, Qualifiers &R) { + Qualifiers Q; + if (L.getPointerAuth().isEquivalent(R.getPointerAuth())) { + Q.setPointerAuth(L.getPointerAuth().withoutKeyNone()); + PointerAuthQualifier Empty; + L.setPointerAuth(Empty); + R.setPointerAuth(Empty); + } + // If both are only CVR-qualified, bit operations are sufficient. if (!(L.Mask & ~CVRMask) && !(R.Mask & ~CVRMask)) { - Qualifiers Q; Q.Mask = L.Mask & R.Mask; L.Mask &= ~Q.Mask; R.Mask &= ~Q.Mask; return Q; } - Qualifiers Q; unsigned CommonCRV = L.getCVRQualifiers() & R.getCVRQualifiers(); Q.addCVRQualifiers(CommonCRV); L.removeCVRQualifiers(CommonCRV); @@ -251,15 +420,16 @@ class Qualifiers { } // Deserialize qualifiers from an opaque representation. - static Qualifiers fromOpaqueValue(unsigned opaque) { + static Qualifiers fromOpaqueValue(uint64_t opaque) { Qualifiers Qs; - Qs.Mask = opaque; + Qs.Mask = uint32_t(opaque); + Qs.PtrAuth = PointerAuthQualifier::fromOpaqueValue(uint32_t(opaque >> 32)); return Qs; } // Serialize these qualifiers into an opaque representation. - unsigned getAsOpaqueValue() const { - return Mask; + uint64_t getAsOpaqueValue() const { + return uint64_t(Mask) | (uint64_t(PtrAuth.getAsOpaqueValue()) << 32); } bool hasConst() const { return Mask & Const; } @@ -407,6 +577,10 @@ class Qualifiers { setAddressSpace(space); } + PointerAuthQualifier getPointerAuth() const { return PtrAuth; } + void setPointerAuth(PointerAuthQualifier q) { PtrAuth = q; } + void removePtrAuth() { PtrAuth = PointerAuthQualifier(); } + // Fast qualifiers are those that can be allocated directly // on a QualType object. bool hasFastQualifiers() const { return getFastQualifiers(); } @@ -429,7 +603,7 @@ class Qualifiers { /// Return true if the set contains any qualifiers which require an ExtQuals /// node to be allocated. - bool hasNonFastQualifiers() const { return Mask & ~FastMask; } + bool hasNonFastQualifiers() const { return (Mask & ~FastMask) || PtrAuth; } Qualifiers getNonFastQualifiers() const { Qualifiers Quals = *this; Quals.setFastQualifiers(0); @@ -437,8 +611,8 @@ class Qualifiers { } /// Return true if the set contains any qualifiers. - bool hasQualifiers() const { return Mask; } - bool empty() const { return !Mask; } + bool hasQualifiers() const { return Mask || PtrAuth; } + bool empty() const { return !hasQualifiers(); } /// Add the qualifiers from the given set to this set. void addQualifiers(Qualifiers Q) { @@ -455,6 +629,9 @@ class Qualifiers { if (Q.hasObjCLifetime()) addObjCLifetime(Q.getObjCLifetime()); } + + if (Q.PtrAuth) + PtrAuth = Q.PtrAuth; } /// Remove the qualifiers from the given set from this set. @@ -472,6 +649,9 @@ class Qualifiers { if (getAddressSpace() == Q.getAddressSpace()) removeAddressSpace(); } + + if (PtrAuth == Q.PtrAuth) + PtrAuth = PointerAuthQualifier(); } /// Add the qualifiers from the given set to this set, given that @@ -483,7 +663,10 @@ class Qualifiers { !hasObjCGCAttr() || !qs.hasObjCGCAttr()); assert(getObjCLifetime() == qs.getObjCLifetime() || !hasObjCLifetime() || !qs.hasObjCLifetime()); + assert(!PtrAuth || !qs.PtrAuth || PtrAuth == qs.PtrAuth); Mask |= qs.Mask; + if (qs.PtrAuth) + PtrAuth = qs.PtrAuth; } /// Returns true if address space A is equal to or a superset of B. @@ -536,6 +719,8 @@ class Qualifiers { // be changed. (getObjCGCAttr() == other.getObjCGCAttr() || !hasObjCGCAttr() || !other.hasObjCGCAttr()) && + // Pointer-auth qualifiers must match exactly. + PtrAuth == other.PtrAuth && // ObjC lifetime qualifiers must match exactly. getObjCLifetime() == other.getObjCLifetime() && // CVR qualifiers may subset. @@ -568,8 +753,12 @@ class Qualifiers { /// another set of qualifiers, not considering qualifier compatibility. bool isStrictSupersetOf(Qualifiers Other) const; - bool operator==(Qualifiers Other) const { return Mask == Other.Mask; } - bool operator!=(Qualifiers Other) const { return Mask != Other.Mask; } + bool operator==(Qualifiers Other) const { + return Mask == Other.Mask && PtrAuth == Other.PtrAuth; + } + bool operator!=(Qualifiers Other) const { + return Mask != Other.Mask || PtrAuth != Other.PtrAuth; + } explicit operator bool() const { return hasQualifiers(); } @@ -607,6 +796,7 @@ class Qualifiers { void Profile(llvm::FoldingSetNodeID &ID) const { ID.AddInteger(Mask); + PtrAuth.Profile(ID); } private: @@ -614,6 +804,9 @@ class Qualifiers { // |C R V|U|GCAttr|Lifetime|AddressSpace| uint32_t Mask = 0; + PointerAuthQualifier PtrAuth; + static_assert(sizeof(PointerAuthQualifier) == sizeof(uint32_t), + "PointerAuthQualifier must be 32 bits"); static const uint32_t UMask = 0x8; static const uint32_t UShift = 3; static const uint32_t GCAttrMask = 0x30; diff --git a/clang/include/clang/Basic/PointerAuthOptions.h b/clang/include/clang/Basic/PointerAuthOptions.h new file mode 100644 index 00000000000000..c69847ac704a41 --- /dev/null +++ b/clang/include/clang/Basic/PointerAuthOptions.h @@ -0,0 +1,23 @@ +//===--- PointerAuthOptions.h -----------------------------------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// +// This file defines options for configuring pointer-auth technologies +// like ARMv8.3. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CLANG_BASIC_POINTERAUTHOPTIONS_H +#define LLVM_CLANG_BASIC_POINTERAUTHOPTIONS_H + +namespace clang { + +constexpr int PointerAuthKeyNone = -1; + +} // end namespace clang + +#endif >From f325fa9b8f57c78fe96ab84f62bf76848fc5c43c Mon Sep 17 00:00:00 2001 From: Daniil Kovalev <dkova...@accesssoftek.com> Date: Thu, 7 Mar 2024 17:54:20 +0300 Subject: [PATCH 08/10] Support `PointerAuthQualifier` in `QualType` --- clang/include/clang/AST/ASTContext.h | 10 ++++++++++ clang/include/clang/AST/Type.h | 4 ++++ 2 files changed, 14 insertions(+) diff --git a/clang/include/clang/AST/ASTContext.h b/clang/include/clang/AST/ASTContext.h index 002f36ecbbaa3f..4fe27f1b6fa270 100644 --- a/clang/include/clang/AST/ASTContext.h +++ b/clang/include/clang/AST/ASTContext.h @@ -2189,6 +2189,16 @@ class ASTContext : public RefCountedBase<ASTContext> { return getQualifiedType(type.getUnqualifiedType(), Qs); } + /// \brief Return a type with the given __ptrauth qualifier. + QualType getPointerAuthType(QualType type, PointerAuthQualifier pointerAuth) { + assert(!type.getPointerAuth()); + assert(pointerAuth); + + Qualifiers qs; + qs.setPointerAuth(pointerAuth); + return getQualifiedType(type, qs); + } + unsigned char getFixedPointScale(QualType Ty) const; unsigned char getFixedPointIBits(QualType Ty) const; llvm::FixedPointSemantics getFixedPointSemantics(QualType Ty) const; diff --git a/clang/include/clang/AST/Type.h b/clang/include/clang/AST/Type.h index df370146293cbc..fc666dd980e56c 100644 --- a/clang/include/clang/AST/Type.h +++ b/clang/include/clang/AST/Type.h @@ -1435,6 +1435,10 @@ class QualType { // true when Type is objc's weak and weak is enabled but ARC isn't. bool isNonWeakInMRRWithObjCWeak(const ASTContext &Context) const; + PointerAuthQualifier getPointerAuth() const { + return getQualifiers().getPointerAuth(); + } + enum PrimitiveDefaultInitializeKind { /// The type does not fall into any of the following categories. Note that /// this case is zero-valued so that values of this enum can be used as a >From dd77587e49a89af77a2821cfa9c69b81f9dc8a42 Mon Sep 17 00:00:00 2001 From: Daniil Kovalev <dkova...@accesssoftek.com> Date: Tue, 26 Mar 2024 22:34:52 +0300 Subject: [PATCH 09/10] 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 2db295c9f26c3bf5408b23b4cf71850600e97380 Mon Sep 17 00:00:00 2001 From: Daniil Kovalev <dkova...@accesssoftek.com> Date: Thu, 28 Mar 2024 12:52:24 +0300 Subject: [PATCH 10/10] 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(); } _______________________________________________ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits