@@ -495,6 +495,7 @@ TypeSP DWARFASTParserClang::ParseTypeFromDWARF(const SymbolContext &sc,
495
495
case DW_TAG_const_type:
496
496
case DW_TAG_restrict_type:
497
497
case DW_TAG_volatile_type:
498
+ case DW_TAG_LLVM_ptrauth_type:
498
499
case DW_TAG_atomic_type:
499
500
case DW_TAG_unspecified_type: {
500
501
type_sp = ParseTypeModifier (sc, die, attrs);
@@ -676,6 +677,63 @@ DWARFASTParserClang::ParseTypeModifier(const SymbolContext &sc,
676
677
case DW_TAG_volatile_type:
677
678
encoding_data_type = Type::eEncodingIsVolatileUID;
678
679
break ;
680
+ case DW_TAG_LLVM_ptrauth_type: {
681
+ DWARFDIE ptr_die = die.GetReferencedDIE (DW_AT_type);
682
+ // FIXME: Fully resolving the type here may affect performance.
683
+ Type *res_type = dwarf->ResolveType (ptr_die);
684
+ if (!res_type)
685
+ break ;
686
+ attrs.type .Clear ();
687
+ encoding_data_type = Type::eEncodingIsUID;
688
+ resolve_state = Type::ResolveState::Full;
689
+
690
+ // Apply the ptrauth qualifier to the resolved type.
691
+ auto *ptr_type =
692
+ (clang::Type *)res_type->GetForwardCompilerType ().GetOpaqueQualType ();
693
+ auto getAttr = [&](llvm::dwarf::Attribute Attr, unsigned defaultValue = 0 ) {
694
+ return die.GetAttributeValueAsUnsigned (Attr, defaultValue);
695
+ };
696
+ const unsigned key = getAttr (DW_AT_LLVM_ptrauth_key);
697
+ const bool addr_disc = getAttr (DW_AT_LLVM_ptrauth_address_discriminated);
698
+ const unsigned extra = getAttr (DW_AT_LLVM_ptrauth_extra_discriminator);
699
+ const bool isapointer = getAttr (DW_AT_LLVM_ptrauth_isa_pointer);
700
+ const bool authenticates_null_values =
701
+ getAttr (DW_AT_LLVM_ptrauth_authenticates_null_values, 0 );
702
+ const bool is_restricted_integral = !ptr_type->isPointerType ();
703
+ const unsigned authentication_mode_int = getAttr (
704
+ DW_AT_LLVM_ptrauth_authentication_mode,
705
+ static_cast <unsigned >(clang::PointerAuthenticationMode::SignAndAuth));
706
+ clang::PointerAuthenticationMode authentication_mode =
707
+ clang::PointerAuthenticationMode::SignAndAuth;
708
+ if (authentication_mode_int >=
709
+ static_cast <unsigned >(clang::PointerAuthenticationMode::None) &&
710
+ authentication_mode_int <=
711
+ static_cast <unsigned >(
712
+ clang::PointerAuthenticationMode::SignAndAuth)) {
713
+ authentication_mode = static_cast <clang::PointerAuthenticationMode>(
714
+ authentication_mode_int);
715
+ } else {
716
+ dwarf->GetObjectFile ()->GetModule ()->ReportError (
717
+ " [{0:x16}]: invalid pointer authentication mode method {1:x4}" ,
718
+ die.GetOffset (), authentication_mode_int);
719
+ }
720
+
721
+ // FIXME: Use these variables when PointerAuthQualifier is more complete
722
+ // upstream.
723
+ (void )isapointer;
724
+ (void )authenticates_null_values;
725
+ (void )is_restricted_integral;
726
+ (void )authentication_mode;
727
+
728
+ clang::Qualifiers qualifiers;
729
+ clang::PointerAuthQualifier ptr_auth (key, addr_disc, extra);
730
+ qualifiers.setPointerAuth (ptr_auth);
731
+ auto &ctx = m_ast.getASTContext ();
732
+ auto qual_type = ctx.getQualifiedType (ptr_type, qualifiers);
733
+ clang_type =
734
+ CompilerType (m_ast.weak_from_this (), qual_type.getAsOpaquePtr ());
735
+ break ;
736
+ }
679
737
case DW_TAG_atomic_type:
680
738
encoding_data_type = Type::eEncodingIsAtomicUID;
681
739
break ;
0 commit comments