[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
Thu Mar 7 13:49:18 PST 2024


https://github.com/kovdan01 created https://github.com/llvm/llvm-project/pull/84387

Depends on #84384 

This adds support for `DW_TAG_LLVM_ptrauth_type` entries corresponding
to explicitly signed types (e.g. free function pointers) in lldb user
expressions. Applies PR https://github.com/apple/llvm-project/pull/8239 from
Apple's downstream and also adds tests and related code.

Co-authored-by: Jonas Devlieghere <jonas at devlieghere.com>


>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/4] 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 f2a2cdc1ef3d4722a0b336ec484ef0200a0f1ee9 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/4] [PAC][lldb] Use `eEncodingIsLLVMPtrAuthUID` for
 `__ptrauth`-qualified types

---
 lldb/include/lldb/Symbol/Type.h                |  4 +++-
 .../SymbolFile/DWARF/DWARFASTParserClang.cpp   |  2 +-
 lldb/source/Symbol/Type.cpp                    | 18 ++++++++++++------
 3 files changed, 16 insertions(+), 8 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..6fa08236c1c272 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,12 +482,13 @@ 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: {
-      if (ArchSpec arch = m_symbol_file->GetObjectFile()->GetArchitecture()) {
-        m_byte_size = arch.GetAddressByteSize();
-        m_byte_size_has_value = true;
-        return static_cast<uint64_t>(m_byte_size);
-      }
+    case eEncodingIsRValueReferenceUID:
+    case eEncodingIsLLVMPtrAuthUID: {
+    if (ArchSpec arch = m_symbol_file->GetObjectFile()->GetArchitecture()) {
+      m_byte_size = arch.GetAddressByteSize();
+      m_byte_size_has_value = true;
+      return static_cast<uint64_t>(m_byte_size);
+    }
     } break;
   }
   return {};

>From e5513ed02c6cad2ce38db141ad14c23c36cd935b 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/4] [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 8d05d535a1c9f091e5c90af0a2e6969c57e26405 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/4] [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;



More information about the lldb-commits mailing list