Skip to content

Commit 1cd3542

Browse files
committed
[AArch64][PAC][lldb][Dwarf] Support __ptrauth-qualified types
This adds support for `DW_TAG_LLVM_ptrauth_type` entries corresponding to explicitly signed free function pointers in lldb user expressions. In this patch, as a temporary solution pointer auth schema corresponding to `-mbranch-protection=pauthabi` is enabled unconditionally. This also brings support for all kinds of implicitly signed pointers, including member function pointers, virtual function pointers, etc.
1 parent 7232614 commit 1cd3542

File tree

11 files changed

+308
-7
lines changed

11 files changed

+308
-7
lines changed

lldb/include/lldb/Symbol/CompilerType.h

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -215,6 +215,12 @@ class CompilerType {
215215
size_t GetPointerByteSize() const;
216216
/// \}
217217

218+
unsigned GetPtrAuthKey() const;
219+
220+
unsigned GetPtrAuthDiscriminator() const;
221+
222+
bool GetPtrAuthAddressDiversity() const;
223+
218224
/// Accessors.
219225
/// \{
220226

@@ -322,6 +328,13 @@ class CompilerType {
322328

323329
/// Create related types using the current type's AST
324330
CompilerType GetBasicTypeFromAST(lldb::BasicType basic_type) const;
331+
332+
/// Return a new CompilerType adds a ptrauth modifier with given parameters to
333+
/// this type if this type is valid and the type system supports ptrauth
334+
/// modifiers, else return an invalid type. Note that this does not check if
335+
/// this type is a pointer.
336+
CompilerType AddPtrAuthModifier(unsigned key, bool isAddressDiscriminated,
337+
unsigned extraDiscriminator) const;
325338
/// \}
326339

327340
/// Exploring the type.

lldb/include/lldb/Symbol/Type.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,9 @@ class Type : public std::enable_shared_from_this<Type>, public UserID {
9292
/// This type is the type whose UID is m_encoding_uid as an atomic type.
9393
eEncodingIsAtomicUID,
9494
/// This type is the synthetic type whose UID is m_encoding_uid.
95-
eEncodingIsSyntheticUID
95+
eEncodingIsSyntheticUID,
96+
/// This type is a signed pointer.
97+
eEncodingIsLLVMPtrAuthUID
9698
};
9799

98100
enum class ResolveState : unsigned char {

lldb/include/lldb/Symbol/TypeSystem.h

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -215,6 +215,16 @@ class TypeSystem : public PluginInterface,
215215

216216
virtual uint32_t GetPointerByteSize() = 0;
217217

218+
// TODO: are we allowed to insert virtual functions in the middle of the class
219+
// interface and break ABI?
220+
virtual unsigned GetPtrAuthKey(lldb::opaque_compiler_type_t type) = 0;
221+
222+
virtual unsigned
223+
GetPtrAuthDiscriminator(lldb::opaque_compiler_type_t type) = 0;
224+
225+
virtual bool
226+
GetPtrAuthAddressDiversity(lldb::opaque_compiler_type_t type) = 0;
227+
218228
// Accessors
219229

220230
virtual ConstString GetTypeName(lldb::opaque_compiler_type_t type,
@@ -279,6 +289,13 @@ class TypeSystem : public PluginInterface,
279289

280290
virtual CompilerType AddRestrictModifier(lldb::opaque_compiler_type_t type);
281291

292+
// TODO: are we allowed to insert virtual functions in the middle of the class
293+
// interface and break ABI?
294+
virtual CompilerType AddPtrAuthModifier(lldb::opaque_compiler_type_t type,
295+
unsigned key,
296+
bool isAddressDiscriminated,
297+
unsigned extraDiscriminator);
298+
282299
/// \param opaque_payload The m_payload field of Type, which may
283300
/// carry TypeSystem-specific extra information.
284301
virtual CompilerType CreateTypedef(lldb::opaque_compiler_type_t type,

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

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -504,6 +504,10 @@ TypeSP DWARFASTParserClang::ParseTypeFromDWARF(const SymbolContext &sc,
504504
type_sp = ParsePointerToMemberType(die, attrs);
505505
break;
506506
}
507+
case DW_TAG_LLVM_ptrauth_type: {
508+
type_sp = ParsePtrAuthQualifiedType(die, attrs);
509+
break;
510+
}
507511
default:
508512
dwarf->GetObjectFile()->GetModule()->ReportError(
509513
"[{0:x16}]: unhandled type tag {1:x4} ({2}), "
@@ -1375,6 +1379,33 @@ TypeSP DWARFASTParserClang::ParsePointerToMemberType(
13751379
return nullptr;
13761380
}
13771381

1382+
TypeSP DWARFASTParserClang::ParsePtrAuthQualifiedType(
1383+
const DWARFDIE &die, const ParsedDWARFTypeAttributes &attrs) {
1384+
SymbolFileDWARF *dwarf = die.GetDWARF();
1385+
Type *pointer_type = dwarf->ResolveTypeUID(attrs.type.Reference(), true);
1386+
1387+
if (pointer_type == nullptr)
1388+
return nullptr;
1389+
1390+
CompilerType pointer_clang_type = pointer_type->GetForwardCompilerType();
1391+
1392+
unsigned key = die.GetAttributeValueAsUnsigned(DW_AT_LLVM_ptrauth_key, 0);
1393+
bool has_addr_discr = die.GetAttributeValueAsUnsigned(
1394+
DW_AT_LLVM_ptrauth_address_discriminated, false);
1395+
unsigned extra_discr = die.GetAttributeValueAsUnsigned(
1396+
DW_AT_LLVM_ptrauth_extra_discriminator, 0);
1397+
CompilerType clang_type = m_ast.AddPtrAuthModifier(
1398+
pointer_clang_type.GetOpaqueQualType(), key, has_addr_discr, extra_discr);
1399+
1400+
TypeSP type_sp = dwarf->MakeType(
1401+
die.GetID(), attrs.name, pointer_type->GetByteSize(nullptr), nullptr,
1402+
attrs.type.Reference().GetID(), Type::eEncodingIsLLVMPtrAuthUID,
1403+
&attrs.decl, clang_type, Type::ResolveState::Forward);
1404+
1405+
dwarf->GetDIEToType()[die.GetDIE()] = type_sp.get();
1406+
return type_sp;
1407+
}
1408+
13781409
void DWARFASTParserClang::ParseInheritance(
13791410
const DWARFDIE &die, const DWARFDIE &parent_die,
13801411
const CompilerType class_clang_type, const AccessType default_accessibility,

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

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -296,6 +296,10 @@ class DWARFASTParserClang : public DWARFASTParser {
296296
lldb::TypeSP ParsePointerToMemberType(const DWARFDIE &die,
297297
const ParsedDWARFTypeAttributes &attrs);
298298

299+
lldb::TypeSP
300+
ParsePtrAuthQualifiedType(const DWARFDIE &die,
301+
const ParsedDWARFTypeAttributes &attrs);
302+
299303
/// Parses a DW_TAG_inheritance DIE into a base/super class.
300304
///
301305
/// \param die The DW_TAG_inheritance DIE to parse.

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

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3048,6 +3048,35 @@ bool TypeSystemClang::IsCStringType(lldb::opaque_compiler_type_t type,
30483048
return false;
30493049
}
30503050

3051+
unsigned TypeSystemClang::GetPtrAuthKey(lldb::opaque_compiler_type_t type) {
3052+
if (type) {
3053+
clang::QualType qual_type(GetCanonicalQualType(type));
3054+
if (auto pointer_auth = qual_type.getPointerAuth())
3055+
return pointer_auth.getKey();
3056+
}
3057+
return 0;
3058+
}
3059+
3060+
unsigned
3061+
TypeSystemClang::GetPtrAuthDiscriminator(lldb::opaque_compiler_type_t type) {
3062+
if (type) {
3063+
clang::QualType qual_type(GetCanonicalQualType(type));
3064+
if (auto pointer_auth = qual_type.getPointerAuth())
3065+
return pointer_auth.getExtraDiscriminator();
3066+
}
3067+
return 0;
3068+
}
3069+
3070+
bool TypeSystemClang::GetPtrAuthAddressDiversity(
3071+
lldb::opaque_compiler_type_t type) {
3072+
if (type) {
3073+
clang::QualType qual_type(GetCanonicalQualType(type));
3074+
if (auto pointer_auth = qual_type.getPointerAuth())
3075+
return pointer_auth.isAddressDiscriminated();
3076+
}
3077+
return false;
3078+
}
3079+
30513080
bool TypeSystemClang::IsFunctionType(lldb::opaque_compiler_type_t type) {
30523081
auto isFunctionType = [&](clang::QualType qual_type) {
30533082
return qual_type->isFunctionType();
@@ -4622,6 +4651,24 @@ TypeSystemClang::AddConstModifier(lldb::opaque_compiler_type_t type) {
46224651
return CompilerType();
46234652
}
46244653

4654+
CompilerType
4655+
TypeSystemClang::AddPtrAuthModifier(lldb::opaque_compiler_type_t type,
4656+
unsigned key, bool isAddressDiscriminated,
4657+
unsigned extraDiscriminator) {
4658+
if (type) {
4659+
clang::ASTContext &clang_ast = getASTContext();
4660+
auto pauth = PointerAuthQualifier::Create(
4661+
key, isAddressDiscriminated, extraDiscriminator,
4662+
PointerAuthenticationMode::SignAndAuth,
4663+
/* isIsaPointer */ false,
4664+
/* authenticatesNullValues */ false);
4665+
clang::QualType result =
4666+
clang_ast.getPointerAuthType(GetQualType(type), pauth);
4667+
return GetType(result);
4668+
}
4669+
return CompilerType();
4670+
}
4671+
46254672
CompilerType
46264673
TypeSystemClang::AddVolatileModifier(lldb::opaque_compiler_type_t type) {
46274674
if (type) {

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

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -642,6 +642,10 @@ class TypeSystemClang : public TypeSystem {
642642
bool IsFloatingPointType(lldb::opaque_compiler_type_t type, uint32_t &count,
643643
bool &is_complex) override;
644644

645+
unsigned GetPtrAuthKey(lldb::opaque_compiler_type_t type) override;
646+
unsigned GetPtrAuthDiscriminator(lldb::opaque_compiler_type_t type) override;
647+
bool GetPtrAuthAddressDiversity(lldb::opaque_compiler_type_t type) override;
648+
645649
bool IsFunctionType(lldb::opaque_compiler_type_t type) override;
646650

647651
uint32_t IsHomogeneousAggregate(lldb::opaque_compiler_type_t type,
@@ -782,6 +786,10 @@ class TypeSystemClang : public TypeSystem {
782786

783787
CompilerType AddConstModifier(lldb::opaque_compiler_type_t type) override;
784788

789+
CompilerType AddPtrAuthModifier(lldb::opaque_compiler_type_t type,
790+
unsigned key, bool isAddressDiscriminated,
791+
unsigned extraDiscriminator) override;
792+
785793
CompilerType AddVolatileModifier(lldb::opaque_compiler_type_t type) override;
786794

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

lldb/source/Symbol/CompilerType.cpp

Lines changed: 32 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::IsCStringType(uint32_t &length) const {
112133
if (IsValid())
113134
if (auto type_system_sp = GetTypeSystem())
@@ -485,6 +506,17 @@ CompilerType CompilerType::GetPointerType() const {
485506
return CompilerType();
486507
}
487508

509+
CompilerType
510+
CompilerType::AddPtrAuthModifier(unsigned key, bool isAddressDiscriminated,
511+
unsigned extraDiscriminator) const {
512+
if (IsValid()) {
513+
if (auto type_system_sp = GetTypeSystem())
514+
return type_system_sp->AddPtrAuthModifier(
515+
m_type, key, isAddressDiscriminated, extraDiscriminator);
516+
}
517+
return CompilerType();
518+
}
519+
488520
CompilerType CompilerType::GetLValueReferenceType() const {
489521
if (IsValid())
490522
if (auto type_system_sp = GetTypeSystem())

lldb/source/Symbol/Type.cpp

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -230,6 +230,9 @@ void Type::GetDescription(Stream *s, lldb::DescriptionLevel level,
230230
case eEncodingIsSyntheticUID:
231231
s->PutCString(" (synthetic type)");
232232
break;
233+
case eEncodingIsLLVMPtrAuthUID:
234+
s->PutCString(" (ptrauth type)");
235+
break;
233236
}
234237
}
235238
}
@@ -291,6 +294,8 @@ void Type::Dump(Stream *s, bool show_context, lldb::DescriptionLevel level) {
291294
case eEncodingIsSyntheticUID:
292295
s->PutCString(" (synthetic type)");
293296
break;
297+
case eEncodingIsLLVMPtrAuthUID:
298+
s->PutCString(" (ptrauth type)");
294299
}
295300
}
296301

@@ -376,12 +381,13 @@ std::optional<uint64_t> Type::GetByteSize(ExecutionContextScope *exe_scope) {
376381
// If we are a pointer or reference, then this is just a pointer size;
377382
case eEncodingIsPointerUID:
378383
case eEncodingIsLValueReferenceUID:
379-
case eEncodingIsRValueReferenceUID: {
380-
if (ArchSpec arch = m_symbol_file->GetObjectFile()->GetArchitecture()) {
381-
m_byte_size = arch.GetAddressByteSize();
382-
m_byte_size_has_value = true;
383-
return static_cast<uint64_t>(m_byte_size);
384-
}
384+
case eEncodingIsRValueReferenceUID:
385+
case eEncodingIsLLVMPtrAuthUID: {
386+
if (ArchSpec arch = m_symbol_file->GetObjectFile()->GetArchitecture()) {
387+
m_byte_size = arch.GetAddressByteSize();
388+
m_byte_size_has_value = true;
389+
return static_cast<uint64_t>(m_byte_size);
390+
}
385391
} break;
386392
}
387393
return {};

lldb/source/Symbol/TypeSystem.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,13 @@ 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+
unsigned key,
98+
bool isAddressDiscriminated,
99+
unsigned extraDiscriminator) {
100+
return CompilerType();
101+
}
102+
96103
CompilerType
97104
TypeSystem::AddVolatileModifier(lldb::opaque_compiler_type_t type) {
98105
return CompilerType();

0 commit comments

Comments
 (0)