Skip to content

Commit

Permalink
[AArch64][PAC][lldb][Dwarf] Support __ptrauth-qualified types
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
kovdan01 committed Feb 12, 2024
1 parent d8bf5a0 commit 33e6446
Show file tree
Hide file tree
Showing 11 changed files with 308 additions and 7 deletions.
13 changes: 13 additions & 0 deletions lldb/include/lldb/Symbol/CompilerType.h
Original file line number Diff line number Diff line change
Expand Up @@ -215,6 +215,12 @@ class CompilerType {
size_t GetPointerByteSize() const;
/// \}

unsigned GetPtrAuthKey() const;

unsigned GetPtrAuthDiscriminator() const;

bool GetPtrAuthAddressDiversity() const;

/// Accessors.
/// \{

Expand Down Expand Up @@ -322,6 +328,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.
Expand Down
4 changes: 3 additions & 1 deletion lldb/include/lldb/Symbol/Type.h
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,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 {
Expand Down
17 changes: 17 additions & 0 deletions lldb/include/lldb/Symbol/TypeSystem.h
Original file line number Diff line number Diff line change
Expand Up @@ -215,6 +215,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,
Expand Down Expand Up @@ -279,6 +289,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,
Expand Down
31 changes: 31 additions & 0 deletions lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -504,6 +504,10 @@ TypeSP DWARFASTParserClang::ParseTypeFromDWARF(const SymbolContext &sc,
type_sp = ParsePointerToMemberType(die, attrs);
break;
}
case DW_TAG_LLVM_ptrauth_type: {
type_sp = ParsePtrAuthQualifiedType(die, attrs);
break;
}
default:
dwarf->GetObjectFile()->GetModule()->ReportError(
"[{0:x16}]: unhandled type tag {1:x4} ({2}), "
Expand Down Expand Up @@ -1375,6 +1379,33 @@ TypeSP DWARFASTParserClang::ParsePointerToMemberType(
return nullptr;
}

TypeSP DWARFASTParserClang::ParsePtrAuthQualifiedType(
const DWARFDIE &die, const ParsedDWARFTypeAttributes &attrs) {
SymbolFileDWARF *dwarf = die.GetDWARF();
Type *pointer_type = dwarf->ResolveTypeUID(attrs.type.Reference(), true);

if (pointer_type == nullptr)
return nullptr;

CompilerType pointer_clang_type = pointer_type->GetForwardCompilerType();

unsigned key = die.GetAttributeValueAsUnsigned(DW_AT_LLVM_ptrauth_key, 0);
bool has_addr_discr = die.GetAttributeValueAsUnsigned(
DW_AT_LLVM_ptrauth_address_discriminated, false);
unsigned extra_discr = die.GetAttributeValueAsUnsigned(
DW_AT_LLVM_ptrauth_extra_discriminator, 0);
CompilerType clang_type = m_ast.AddPtrAuthModifier(
pointer_clang_type.GetOpaqueQualType(), key, has_addr_discr, extra_discr);

TypeSP type_sp = dwarf->MakeType(
die.GetID(), attrs.name, pointer_type->GetByteSize(nullptr), nullptr,
attrs.type.Reference().GetID(), Type::eEncodingIsLLVMPtrAuthUID,
&attrs.decl, clang_type, Type::ResolveState::Forward);

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

void DWARFASTParserClang::ParseInheritance(
const DWARFDIE &die, const DWARFDIE &parent_die,
const CompilerType class_clang_type, const AccessType default_accessibility,
Expand Down
4 changes: 4 additions & 0 deletions lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.h
Original file line number Diff line number Diff line change
Expand Up @@ -296,6 +296,10 @@ class DWARFASTParserClang : public DWARFASTParser {
lldb::TypeSP ParsePointerToMemberType(const DWARFDIE &die,
const ParsedDWARFTypeAttributes &attrs);

lldb::TypeSP
ParsePtrAuthQualifiedType(const DWARFDIE &die,
const ParsedDWARFTypeAttributes &attrs);

/// Parses a DW_TAG_inheritance DIE into a base/super class.
///
/// \param die The DW_TAG_inheritance DIE to parse.
Expand Down
47 changes: 47 additions & 0 deletions lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3048,6 +3048,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();
Expand Down Expand Up @@ -4622,6 +4651,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) {
Expand Down
8 changes: 8 additions & 0 deletions lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.h
Original file line number Diff line number Diff line change
Expand Up @@ -642,6 +642,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,
Expand Down Expand Up @@ -782,6 +786,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;
Expand Down
32 changes: 32 additions & 0 deletions lldb/source/Symbol/CompilerType.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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::IsCStringType(uint32_t &length) const {
if (IsValid())
if (auto type_system_sp = GetTypeSystem())
Expand Down Expand Up @@ -485,6 +506,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())
Expand Down
18 changes: 12 additions & 6 deletions lldb/source/Symbol/Type.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -230,6 +230,9 @@ void Type::GetDescription(Stream *s, lldb::DescriptionLevel level,
case eEncodingIsSyntheticUID:
s->PutCString(" (synthetic type)");
break;
case eEncodingIsLLVMPtrAuthUID:
s->PutCString(" (ptrauth type)");
break;
}
}
}
Expand Down Expand Up @@ -291,6 +294,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)");
}
}

Expand Down Expand Up @@ -376,12 +381,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 {};
Expand Down
7 changes: 7 additions & 0 deletions lldb/source/Symbol/TypeSystem.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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();
Expand Down
Loading

0 comments on commit 33e6446

Please sign in to comment.