Skip to content

Commit 64248d7

Browse files
[PAC][lldb][Dwarf] Support __ptrauth-qualified types in user expressions (#84387)
Depends on #84384 and #90329 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 swiftlang#8239 from Apple's downstream and also adds tests and related code. --------- Co-authored-by: Jonas Devlieghere <[email protected]>
1 parent a413c56 commit 64248d7

File tree

10 files changed

+302
-5
lines changed

10 files changed

+302
-5
lines changed

lldb/include/lldb/Symbol/CompilerType.h

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -262,6 +262,12 @@ class CompilerType {
262262
size_t GetPointerByteSize() const;
263263
/// \}
264264

265+
unsigned GetPtrAuthKey() const;
266+
267+
unsigned GetPtrAuthDiscriminator() const;
268+
269+
bool GetPtrAuthAddressDiversity() const;
270+
265271
/// Accessors.
266272
/// \{
267273

@@ -369,6 +375,12 @@ class CompilerType {
369375

370376
/// Create related types using the current type's AST
371377
CompilerType GetBasicTypeFromAST(lldb::BasicType basic_type) const;
378+
379+
/// Return a new CompilerType adds a ptrauth modifier from the given 32-bit
380+
/// opaque payload to this type if this type is valid and the type system
381+
/// supports ptrauth modifiers, else return an invalid type. Note that this
382+
/// does not check if this type is a pointer.
383+
CompilerType AddPtrAuthModifier(uint32_t payload) const;
372384
/// \}
373385

374386
/// Exploring the type.

lldb/include/lldb/Symbol/Type.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -401,7 +401,9 @@ class Type : public std::enable_shared_from_this<Type>, public UserID {
401401
/// This type is the type whose UID is m_encoding_uid as an atomic type.
402402
eEncodingIsAtomicUID,
403403
/// This type is the synthetic type whose UID is m_encoding_uid.
404-
eEncodingIsSyntheticUID
404+
eEncodingIsSyntheticUID,
405+
/// This type is a signed pointer.
406+
eEncodingIsLLVMPtrAuthUID
405407
};
406408

407409
enum class ResolveState : unsigned char {

lldb/include/lldb/Symbol/TypeSystem.h

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -221,6 +221,14 @@ class TypeSystem : public PluginInterface,
221221

222222
virtual uint32_t GetPointerByteSize() = 0;
223223

224+
virtual unsigned GetPtrAuthKey(lldb::opaque_compiler_type_t type) = 0;
225+
226+
virtual unsigned
227+
GetPtrAuthDiscriminator(lldb::opaque_compiler_type_t type) = 0;
228+
229+
virtual bool
230+
GetPtrAuthAddressDiversity(lldb::opaque_compiler_type_t type) = 0;
231+
224232
// Accessors
225233

226234
virtual ConstString GetTypeName(lldb::opaque_compiler_type_t type,
@@ -285,6 +293,9 @@ class TypeSystem : public PluginInterface,
285293

286294
virtual CompilerType AddRestrictModifier(lldb::opaque_compiler_type_t type);
287295

296+
virtual CompilerType AddPtrAuthModifier(lldb::opaque_compiler_type_t type,
297+
uint32_t payload);
298+
288299
/// \param opaque_payload The m_payload field of Type, which may
289300
/// carry TypeSystem-specific extra information.
290301
virtual CompilerType CreateTypedef(lldb::opaque_compiler_type_t type,

lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp

Lines changed: 39 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -570,6 +570,39 @@ ExtractDataMemberLocation(DWARFDIE const &die, DWARFFormValue const &form_value,
570570
return memberOffset.ResolveValue(nullptr).UInt();
571571
}
572572

573+
static TypePayloadClang GetPtrAuthMofidierPayload(const DWARFDIE &die) {
574+
auto getAttr = [&](llvm::dwarf::Attribute Attr, unsigned defaultValue = 0) {
575+
return die.GetAttributeValueAsUnsigned(Attr, defaultValue);
576+
};
577+
const unsigned key = getAttr(DW_AT_LLVM_ptrauth_key);
578+
const bool addr_disc = getAttr(DW_AT_LLVM_ptrauth_address_discriminated);
579+
const unsigned extra = getAttr(DW_AT_LLVM_ptrauth_extra_discriminator);
580+
const bool isapointer = getAttr(DW_AT_LLVM_ptrauth_isa_pointer);
581+
const bool authenticates_null_values =
582+
getAttr(DW_AT_LLVM_ptrauth_authenticates_null_values);
583+
const unsigned authentication_mode_int = getAttr(
584+
DW_AT_LLVM_ptrauth_authentication_mode,
585+
static_cast<unsigned>(clang::PointerAuthenticationMode::SignAndAuth));
586+
clang::PointerAuthenticationMode authentication_mode =
587+
clang::PointerAuthenticationMode::SignAndAuth;
588+
if (authentication_mode_int >=
589+
static_cast<unsigned>(clang::PointerAuthenticationMode::None) &&
590+
authentication_mode_int <=
591+
static_cast<unsigned>(
592+
clang::PointerAuthenticationMode::SignAndAuth)) {
593+
authentication_mode =
594+
static_cast<clang::PointerAuthenticationMode>(authentication_mode_int);
595+
} else {
596+
die.GetDWARF()->GetObjectFile()->GetModule()->ReportError(
597+
"[{0:x16}]: invalid pointer authentication mode method {1:x4}",
598+
die.GetOffset(), authentication_mode_int);
599+
}
600+
auto ptr_auth = clang::PointerAuthQualifier::Create(
601+
key, addr_disc, extra, authentication_mode, isapointer,
602+
authenticates_null_values);
603+
return TypePayloadClang(ptr_auth.getAsOpaqueValue());
604+
}
605+
573606
lldb::TypeSP
574607
DWARFASTParserClang::ParseTypeModifier(const SymbolContext &sc,
575608
const DWARFDIE &die,
@@ -580,6 +613,7 @@ DWARFASTParserClang::ParseTypeModifier(const SymbolContext &sc,
580613
LanguageType cu_language = SymbolFileDWARF::GetLanguage(*die.GetCU());
581614
Type::ResolveState resolve_state = Type::ResolveState::Unresolved;
582615
Type::EncodingDataType encoding_data_type = Type::eEncodingIsUID;
616+
TypePayloadClang payload(GetOwningClangModule(die));
583617
TypeSP type_sp;
584618
CompilerType clang_type;
585619

@@ -677,6 +711,10 @@ DWARFASTParserClang::ParseTypeModifier(const SymbolContext &sc,
677711
case DW_TAG_volatile_type:
678712
encoding_data_type = Type::eEncodingIsVolatileUID;
679713
break;
714+
case DW_TAG_LLVM_ptrauth_type:
715+
encoding_data_type = Type::eEncodingIsLLVMPtrAuthUID;
716+
payload = GetPtrAuthMofidierPayload(die);
717+
break;
680718
case DW_TAG_atomic_type:
681719
encoding_data_type = Type::eEncodingIsAtomicUID;
682720
break;
@@ -786,8 +824,7 @@ DWARFASTParserClang::ParseTypeModifier(const SymbolContext &sc,
786824

787825
type_sp = dwarf->MakeType(die.GetID(), attrs.name, attrs.byte_size, nullptr,
788826
attrs.type.Reference().GetID(), encoding_data_type,
789-
&attrs.decl, clang_type, resolve_state,
790-
TypePayloadClang(GetOwningClangModule(die)));
827+
&attrs.decl, clang_type, resolve_state, payload);
791828

792829
dwarf->GetDIEToType()[die.GetDIE()] = type_sp.get();
793830
return type_sp;

lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2923,6 +2923,35 @@ bool TypeSystemClang::IsCStringType(lldb::opaque_compiler_type_t type,
29232923
return false;
29242924
}
29252925

2926+
unsigned TypeSystemClang::GetPtrAuthKey(lldb::opaque_compiler_type_t type) {
2927+
if (type) {
2928+
clang::QualType qual_type(GetCanonicalQualType(type));
2929+
if (auto pointer_auth = qual_type.getPointerAuth())
2930+
return pointer_auth.getKey();
2931+
}
2932+
return 0;
2933+
}
2934+
2935+
unsigned
2936+
TypeSystemClang::GetPtrAuthDiscriminator(lldb::opaque_compiler_type_t type) {
2937+
if (type) {
2938+
clang::QualType qual_type(GetCanonicalQualType(type));
2939+
if (auto pointer_auth = qual_type.getPointerAuth())
2940+
return pointer_auth.getExtraDiscriminator();
2941+
}
2942+
return 0;
2943+
}
2944+
2945+
bool TypeSystemClang::GetPtrAuthAddressDiversity(
2946+
lldb::opaque_compiler_type_t type) {
2947+
if (type) {
2948+
clang::QualType qual_type(GetCanonicalQualType(type));
2949+
if (auto pointer_auth = qual_type.getPointerAuth())
2950+
return pointer_auth.isAddressDiscriminated();
2951+
}
2952+
return false;
2953+
}
2954+
29262955
bool TypeSystemClang::IsFunctionType(lldb::opaque_compiler_type_t type) {
29272956
auto isFunctionType = [&](clang::QualType qual_type) {
29282957
return qual_type->isFunctionType();
@@ -4511,6 +4540,19 @@ TypeSystemClang::AddConstModifier(lldb::opaque_compiler_type_t type) {
45114540
return CompilerType();
45124541
}
45134542

4543+
CompilerType
4544+
TypeSystemClang::AddPtrAuthModifier(lldb::opaque_compiler_type_t type,
4545+
uint32_t payload) {
4546+
if (type) {
4547+
clang::ASTContext &clang_ast = getASTContext();
4548+
auto pauth = PointerAuthQualifier::fromOpaqueValue(payload);
4549+
clang::QualType result =
4550+
clang_ast.getPointerAuthType(GetQualType(type), pauth);
4551+
return GetType(result);
4552+
}
4553+
return CompilerType();
4554+
}
4555+
45144556
CompilerType
45154557
TypeSystemClang::AddVolatileModifier(lldb::opaque_compiler_type_t type) {
45164558
if (type) {

lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.h

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,11 +67,13 @@ class OptionalClangModuleID {
6767

6868
/// The implementation of lldb::Type's m_payload field for TypeSystemClang.
6969
class TypePayloadClang {
70-
/// The Layout is as follows:
70+
/// The payload is used for typedefs and ptrauth types.
71+
/// For typedefs, the Layout is as follows:
7172
/// \verbatim
7273
/// bit 0..30 ... Owning Module ID.
7374
/// bit 31 ...... IsCompleteObjCClass.
7475
/// \endverbatim
76+
/// For ptrauth types, we store the PointerAuthQualifier as an opaque value.
7577
Type::Payload m_payload = 0;
7678

7779
public:
@@ -653,6 +655,10 @@ class TypeSystemClang : public TypeSystem {
653655
bool IsFloatingPointType(lldb::opaque_compiler_type_t type, uint32_t &count,
654656
bool &is_complex) override;
655657

658+
unsigned GetPtrAuthKey(lldb::opaque_compiler_type_t type) override;
659+
unsigned GetPtrAuthDiscriminator(lldb::opaque_compiler_type_t type) override;
660+
bool GetPtrAuthAddressDiversity(lldb::opaque_compiler_type_t type) override;
661+
656662
bool IsFunctionType(lldb::opaque_compiler_type_t type) override;
657663

658664
uint32_t IsHomogeneousAggregate(lldb::opaque_compiler_type_t type,
@@ -793,6 +799,9 @@ class TypeSystemClang : public TypeSystem {
793799

794800
CompilerType AddConstModifier(lldb::opaque_compiler_type_t type) override;
795801

802+
CompilerType AddPtrAuthModifier(lldb::opaque_compiler_type_t type,
803+
uint32_t payload) override;
804+
796805
CompilerType AddVolatileModifier(lldb::opaque_compiler_type_t type) override;
797806

798807
CompilerType AddRestrictModifier(lldb::opaque_compiler_type_t type) override;

lldb/source/Symbol/CompilerType.cpp

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,27 @@ bool CompilerType::IsConst() const {
108108
return false;
109109
}
110110

111+
unsigned CompilerType::GetPtrAuthKey() const {
112+
if (IsValid())
113+
if (auto type_system_sp = GetTypeSystem())
114+
return type_system_sp->GetPtrAuthKey(m_type);
115+
return 0;
116+
}
117+
118+
unsigned CompilerType::GetPtrAuthDiscriminator() const {
119+
if (IsValid())
120+
if (auto type_system_sp = GetTypeSystem())
121+
return type_system_sp->GetPtrAuthDiscriminator(m_type);
122+
return 0;
123+
}
124+
125+
bool CompilerType::GetPtrAuthAddressDiversity() const {
126+
if (IsValid())
127+
if (auto type_system_sp = GetTypeSystem())
128+
return type_system_sp->GetPtrAuthAddressDiversity(m_type);
129+
return false;
130+
}
131+
111132
bool CompilerType::IsFunctionType() const {
112133
if (IsValid())
113134
if (auto type_system_sp = GetTypeSystem())
@@ -664,6 +685,13 @@ CompilerType CompilerType::GetPointerType() const {
664685
return CompilerType();
665686
}
666687

688+
CompilerType CompilerType::AddPtrAuthModifier(uint32_t payload) const {
689+
if (IsValid())
690+
if (auto type_system_sp = GetTypeSystem())
691+
return type_system_sp->AddPtrAuthModifier(m_type, payload);
692+
return CompilerType();
693+
}
694+
667695
CompilerType CompilerType::GetLValueReferenceType() const {
668696
if (IsValid())
669697
if (auto type_system_sp = GetTypeSystem())

lldb/source/Symbol/Type.cpp

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -355,6 +355,9 @@ void Type::GetDescription(Stream *s, lldb::DescriptionLevel level,
355355
case eEncodingIsSyntheticUID:
356356
s->PutCString(" (synthetic type)");
357357
break;
358+
case eEncodingIsLLVMPtrAuthUID:
359+
s->PutCString(" (ptrauth type)");
360+
break;
358361
}
359362
}
360363
}
@@ -416,6 +419,8 @@ void Type::Dump(Stream *s, bool show_context, lldb::DescriptionLevel level) {
416419
case eEncodingIsSyntheticUID:
417420
s->PutCString(" (synthetic type)");
418421
break;
422+
case eEncodingIsLLVMPtrAuthUID:
423+
s->PutCString(" (ptrauth type)");
419424
}
420425
}
421426

@@ -477,7 +482,8 @@ std::optional<uint64_t> Type::GetByteSize(ExecutionContextScope *exe_scope) {
477482
// If we are a pointer or reference, then this is just a pointer size;
478483
case eEncodingIsPointerUID:
479484
case eEncodingIsLValueReferenceUID:
480-
case eEncodingIsRValueReferenceUID: {
485+
case eEncodingIsRValueReferenceUID:
486+
case eEncodingIsLLVMPtrAuthUID: {
481487
if (ArchSpec arch = m_symbol_file->GetObjectFile()->GetArchitecture()) {
482488
m_byte_size = arch.GetAddressByteSize();
483489
m_byte_size_has_value = true;
@@ -621,6 +627,12 @@ bool Type::ResolveCompilerType(ResolveState compiler_type_resolve_state) {
621627
encoding_type->GetForwardCompilerType().GetRValueReferenceType();
622628
break;
623629

630+
case eEncodingIsLLVMPtrAuthUID:
631+
m_compiler_type =
632+
encoding_type->GetForwardCompilerType().AddPtrAuthModifier(
633+
m_payload);
634+
break;
635+
624636
default:
625637
llvm_unreachable("Unhandled encoding_data_type.");
626638
}
@@ -676,6 +688,10 @@ bool Type::ResolveCompilerType(ResolveState compiler_type_resolve_state) {
676688
m_compiler_type = void_compiler_type.GetRValueReferenceType();
677689
break;
678690

691+
case eEncodingIsLLVMPtrAuthUID:
692+
llvm_unreachable("Cannot handle eEncodingIsLLVMPtrAuthUID without "
693+
"valid encoding_type");
694+
679695
default:
680696
llvm_unreachable("Unhandled encoding_data_type.");
681697
}

lldb/source/Symbol/TypeSystem.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,11 @@ CompilerType TypeSystem::AddConstModifier(lldb::opaque_compiler_type_t type) {
9393
return CompilerType();
9494
}
9595

96+
CompilerType TypeSystem::AddPtrAuthModifier(lldb::opaque_compiler_type_t type,
97+
uint32_t payload) {
98+
return CompilerType();
99+
}
100+
96101
CompilerType
97102
TypeSystem::AddVolatileModifier(lldb::opaque_compiler_type_t type) {
98103
return CompilerType();

0 commit comments

Comments
 (0)