From 448c90801db6ca11e09a76bc9b8487289e3e506c Mon Sep 17 00:00:00 2001 From: Daniil Kovalev Date: Tue, 20 Feb 2024 17:47:29 +0300 Subject: [PATCH 1/5] [Dwarf] Support `__ptrauth` qualifier in metadata nodes Emit `__ptrauth`-qualified types as `DIDerivedType` metadata nodes in IR with tag `DW_TAG_LLVM_ptrauth_type`, baseType referring to the type which has the qualifier applied, and the following parameters representing the signing schema: - `ptrAuthKey` (integer) - `ptrAuthIsAddressDiscriminated` (boolean) - `ptrAuthExtraDiscriminator` (integer) - `ptrAuthIsaPointer` (boolean) - `ptrAuthAuthenticatesNullValues` (boolean) --- llvm/include/llvm/IR/DIBuilder.h | 7 ++ llvm/include/llvm/IR/DebugInfoMetadata.h | 136 +++++++++++++++++---- llvm/lib/AsmParser/LLParser.cpp | 23 +++- llvm/lib/Bitcode/Reader/MetadataLoader.cpp | 18 ++- llvm/lib/Bitcode/Writer/BitcodeWriter.cpp | 6 +- llvm/lib/CodeGen/AsmPrinter/DwarfUnit.cpp | 14 +++ llvm/lib/IR/AsmWriter.cpp | 11 ++ llvm/lib/IR/DIBuilder.cpp | 58 +++++---- llvm/lib/IR/DebugInfo.cpp | 6 +- llvm/lib/IR/DebugInfoMetadata.cpp | 21 ++-- llvm/lib/IR/LLVMContextImpl.h | 15 ++- llvm/lib/IR/Verifier.cpp | 1 + llvm/test/Assembler/debug-info.ll | 16 ++- llvm/test/DebugInfo/AArch64/ptrauth.ll | 70 +++++++++++ llvm/unittests/IR/MetadataTest.cpp | 85 +++++++++---- 15 files changed, 387 insertions(+), 100 deletions(-) create mode 100644 llvm/test/DebugInfo/AArch64/ptrauth.ll diff --git a/llvm/include/llvm/IR/DIBuilder.h b/llvm/include/llvm/IR/DIBuilder.h index edec161b39715..010dcbfdadcac 100644 --- a/llvm/include/llvm/IR/DIBuilder.h +++ b/llvm/include/llvm/IR/DIBuilder.h @@ -262,6 +262,13 @@ namespace llvm { std::optional DWARFAddressSpace = std::nullopt, StringRef Name = "", DINodeArray Annotations = nullptr); + /// Create a __ptrauth qualifier. + DIDerivedType *createPtrAuthQualifiedType(DIType *FromTy, unsigned Key, + bool IsAddressDiscriminated, + unsigned ExtraDiscriminator, + bool IsaPointer, + bool authenticatesNullValues); + /// Create debugging information entry for a pointer to member. /// \param PointeeTy Type pointed to by this pointer. /// \param SizeInBits Size. diff --git a/llvm/include/llvm/IR/DebugInfoMetadata.h b/llvm/include/llvm/IR/DebugInfoMetadata.h index 156f6eb49253d..eec150636fff7 100644 --- a/llvm/include/llvm/IR/DebugInfoMetadata.h +++ b/llvm/include/llvm/IR/DebugInfoMetadata.h @@ -20,6 +20,7 @@ #include "llvm/ADT/SmallVector.h" #include "llvm/ADT/StringRef.h" #include "llvm/ADT/iterator_range.h" +#include "llvm/BinaryFormat/Dwarf.h" #include "llvm/IR/Constants.h" #include "llvm/IR/Metadata.h" #include "llvm/IR/PseudoProbe.h" @@ -745,7 +746,9 @@ class DIType : public DIScope { unsigned getLine() const { return Line; } uint64_t getSizeInBits() const { return SizeInBits; } - uint32_t getAlignInBits() const { return SubclassData32; } + uint32_t getAlignInBits() const { + return (getTag() == dwarf::DW_TAG_LLVM_ptrauth_type ? 0 : SubclassData32); + } uint32_t getAlignInBytes() const { return getAlignInBits() / CHAR_BIT; } uint64_t getOffsetInBits() const { return OffsetInBits; } DIFlags getFlags() const { return Flags; } @@ -972,6 +975,40 @@ class DIStringType : public DIType { /// /// TODO: Split out members (inheritance, fields, methods, etc.). class DIDerivedType : public DIType { +public: + /// Pointer authentication (__ptrauth) metadata. + struct PtrAuthData { + union { + struct { + unsigned Key : 4; + unsigned IsAddressDiscriminated : 1; + unsigned ExtraDiscriminator : 16; + unsigned IsaPointer : 1; + unsigned AuthenticatesNullValues : 1; + } Data; + unsigned RawData; + } Payload; + + PtrAuthData(unsigned FromRawData) { Payload.RawData = FromRawData; } + PtrAuthData(unsigned Key, bool IsDiscr, unsigned Discriminator, + bool IsaPointer, bool AuthenticatesNullValues) { + assert(Key < 16); + assert(Discriminator <= 0xffff); + Payload.Data.Key = Key; + Payload.Data.IsAddressDiscriminated = IsDiscr; + Payload.Data.ExtraDiscriminator = Discriminator; + Payload.Data.IsaPointer = IsaPointer; + Payload.Data.AuthenticatesNullValues = AuthenticatesNullValues; + } + bool operator==(struct PtrAuthData Other) const { + return Payload.RawData == Other.Payload.RawData; + } + bool operator!=(struct PtrAuthData Other) const { + return !(*this == Other); + } + }; + +private: friend class LLVMContextImpl; friend class MDNode; @@ -982,59 +1019,70 @@ class DIDerivedType : public DIType { DIDerivedType(LLVMContext &C, StorageType Storage, unsigned Tag, unsigned Line, uint64_t SizeInBits, uint32_t AlignInBits, uint64_t OffsetInBits, - std::optional DWARFAddressSpace, DIFlags Flags, + std::optional DWARFAddressSpace, + std::optional PtrAuthData, DIFlags Flags, ArrayRef Ops) : DIType(C, DIDerivedTypeKind, Storage, Tag, Line, SizeInBits, AlignInBits, OffsetInBits, Flags, Ops), - DWARFAddressSpace(DWARFAddressSpace) {} + DWARFAddressSpace(DWARFAddressSpace) { + if (PtrAuthData) + SubclassData32 = PtrAuthData->Payload.RawData; + } ~DIDerivedType() = default; static DIDerivedType * getImpl(LLVMContext &Context, unsigned Tag, StringRef Name, DIFile *File, unsigned Line, DIScope *Scope, DIType *BaseType, uint64_t SizeInBits, uint32_t AlignInBits, uint64_t OffsetInBits, - std::optional DWARFAddressSpace, DIFlags Flags, + std::optional DWARFAddressSpace, + std::optional PtrAuthData, DIFlags Flags, Metadata *ExtraData, DINodeArray Annotations, StorageType Storage, bool ShouldCreate = true) { return getImpl(Context, Tag, getCanonicalMDString(Context, Name), File, Line, Scope, BaseType, SizeInBits, AlignInBits, OffsetInBits, - DWARFAddressSpace, Flags, ExtraData, Annotations.get(), - Storage, ShouldCreate); + DWARFAddressSpace, PtrAuthData, Flags, ExtraData, + Annotations.get(), Storage, ShouldCreate); } static DIDerivedType * getImpl(LLVMContext &Context, unsigned Tag, MDString *Name, Metadata *File, unsigned Line, Metadata *Scope, Metadata *BaseType, uint64_t SizeInBits, uint32_t AlignInBits, uint64_t OffsetInBits, - std::optional DWARFAddressSpace, DIFlags Flags, + std::optional DWARFAddressSpace, + std::optional PtrAuthData, DIFlags Flags, Metadata *ExtraData, Metadata *Annotations, StorageType Storage, bool ShouldCreate = true); TempDIDerivedType cloneImpl() const { - return getTemporary( - getContext(), getTag(), getName(), getFile(), getLine(), getScope(), - getBaseType(), getSizeInBits(), getAlignInBits(), getOffsetInBits(), - getDWARFAddressSpace(), getFlags(), getExtraData(), getAnnotations()); + return getTemporary(getContext(), getTag(), getName(), getFile(), getLine(), + getScope(), getBaseType(), getSizeInBits(), + getAlignInBits(), getOffsetInBits(), + getDWARFAddressSpace(), getPtrAuthData(), getFlags(), + getExtraData(), getAnnotations()); } public: - DEFINE_MDNODE_GET( - DIDerivedType, - (unsigned Tag, MDString *Name, Metadata *File, unsigned Line, - Metadata *Scope, Metadata *BaseType, uint64_t SizeInBits, - uint32_t AlignInBits, uint64_t OffsetInBits, - std::optional DWARFAddressSpace, DIFlags Flags, - Metadata *ExtraData = nullptr, Metadata *Annotations = nullptr), - (Tag, Name, File, Line, Scope, BaseType, SizeInBits, AlignInBits, - OffsetInBits, DWARFAddressSpace, Flags, ExtraData, Annotations)) + DEFINE_MDNODE_GET(DIDerivedType, + (unsigned Tag, MDString *Name, Metadata *File, + unsigned Line, Metadata *Scope, Metadata *BaseType, + uint64_t SizeInBits, uint32_t AlignInBits, + uint64_t OffsetInBits, + std::optional DWARFAddressSpace, + std::optional PtrAuthData, DIFlags Flags, + Metadata *ExtraData = nullptr, + Metadata *Annotations = nullptr), + (Tag, Name, File, Line, Scope, BaseType, SizeInBits, + AlignInBits, OffsetInBits, DWARFAddressSpace, PtrAuthData, + Flags, ExtraData, Annotations)) DEFINE_MDNODE_GET(DIDerivedType, (unsigned Tag, StringRef Name, DIFile *File, unsigned Line, DIScope *Scope, DIType *BaseType, uint64_t SizeInBits, uint32_t AlignInBits, uint64_t OffsetInBits, - std::optional DWARFAddressSpace, DIFlags Flags, + std::optional DWARFAddressSpace, + std::optional PtrAuthData, DIFlags Flags, Metadata *ExtraData = nullptr, DINodeArray Annotations = nullptr), (Tag, Name, File, Line, Scope, BaseType, SizeInBits, - AlignInBits, OffsetInBits, DWARFAddressSpace, Flags, - ExtraData, Annotations)) + AlignInBits, OffsetInBits, DWARFAddressSpace, PtrAuthData, + Flags, ExtraData, Annotations)) TempDIDerivedType clone() const { return cloneImpl(); } @@ -1048,6 +1096,48 @@ class DIDerivedType : public DIType { return DWARFAddressSpace; } + std::optional getPtrAuthData() const { + return getTag() == dwarf::DW_TAG_LLVM_ptrauth_type + ? std::optional(PtrAuthData(SubclassData32)) + : std::nullopt; + } + + /// \returns The PointerAuth key. + std::optional getPtrAuthKey() const { + if (auto PtrAuthData = getPtrAuthData()) + return (unsigned)PtrAuthData->Payload.Data.Key; + else + return std::nullopt; + } + /// \returns The PointerAuth address discrimination bit. + std::optional isPtrAuthAddressDiscriminated() const { + if (auto PtrAuthData = getPtrAuthData()) + return (bool)PtrAuthData->Payload.Data.IsAddressDiscriminated; + else + return std::nullopt; + } + /// \returns The PointerAuth extra discriminator. + std::optional getPtrAuthExtraDiscriminator() const { + if (auto PtrAuthData = getPtrAuthData()) + return (unsigned)PtrAuthData->Payload.Data.ExtraDiscriminator; + else + return std::nullopt; + } + /// \returns The PointerAuth IsaPointer bit. + std::optional isPtrAuthIsaPointer() const { + if (auto PtrAuthData = getPtrAuthData()) + return (bool)PtrAuthData->Payload.Data.IsaPointer; + else + return std::nullopt; + } + /// \returns The PointerAuth authenticates null values bit. + std::optional getPtrAuthAuthenticatesNullValues() const { + if (auto PtrAuthData = getPtrAuthData()) + return (bool)PtrAuthData->Payload.Data.AuthenticatesNullValues; + else + return std::nullopt; + } + /// Get extra data associated with this derived type. /// /// Class type for pointer-to-members, objective-c property node for ivars, diff --git a/llvm/lib/AsmParser/LLParser.cpp b/llvm/lib/AsmParser/LLParser.cpp index a91e2f690999e..e91abaf0780a3 100644 --- a/llvm/lib/AsmParser/LLParser.cpp +++ b/llvm/lib/AsmParser/LLParser.cpp @@ -5130,7 +5130,11 @@ bool LLParser::parseDIStringType(MDNode *&Result, bool IsDistinct) { /// ::= !DIDerivedType(tag: DW_TAG_pointer_type, name: "int", file: !0, /// line: 7, scope: !1, baseType: !2, size: 32, /// align: 32, offset: 0, flags: 0, extraData: !3, -/// dwarfAddressSpace: 3) +/// dwarfAddressSpace: 3, ptrAuthKey: 1, +/// ptrAuthIsAddressDiscriminated: true, +/// ptrAuthExtraDiscriminator: 0x1234, +/// ptrAuthIsaPointer: 1, ptrAuthAuthenticatesNullValues:1 +/// ) bool LLParser::parseDIDerivedType(MDNode *&Result, bool IsDistinct) { #define VISIT_MD_FIELDS(OPTIONAL, REQUIRED) \ REQUIRED(tag, DwarfTagField, ); \ @@ -5145,19 +5149,30 @@ bool LLParser::parseDIDerivedType(MDNode *&Result, bool IsDistinct) { OPTIONAL(flags, DIFlagField, ); \ OPTIONAL(extraData, MDField, ); \ OPTIONAL(dwarfAddressSpace, MDUnsignedField, (UINT32_MAX, UINT32_MAX)); \ - OPTIONAL(annotations, MDField, ); + OPTIONAL(annotations, MDField, ); \ + OPTIONAL(ptrAuthKey, MDUnsignedField, (0, 7)); \ + OPTIONAL(ptrAuthIsAddressDiscriminated, MDBoolField, ); \ + OPTIONAL(ptrAuthExtraDiscriminator, MDUnsignedField, (0, 0xffff)); \ + OPTIONAL(ptrAuthIsaPointer, MDBoolField, ); \ + OPTIONAL(ptrAuthAuthenticatesNullValues, MDBoolField, ); PARSE_MD_FIELDS(); #undef VISIT_MD_FIELDS std::optional DWARFAddressSpace; if (dwarfAddressSpace.Val != UINT32_MAX) DWARFAddressSpace = dwarfAddressSpace.Val; + std::optional PtrAuthData; + if (ptrAuthKey.Val) + PtrAuthData = DIDerivedType::PtrAuthData( + (unsigned)ptrAuthKey.Val, ptrAuthIsAddressDiscriminated.Val, + (unsigned)ptrAuthExtraDiscriminator.Val, ptrAuthIsaPointer.Val, + ptrAuthAuthenticatesNullValues.Val); Result = GET_OR_DISTINCT(DIDerivedType, (Context, tag.Val, name.Val, file.Val, line.Val, scope.Val, baseType.Val, size.Val, align.Val, - offset.Val, DWARFAddressSpace, flags.Val, - extraData.Val, annotations.Val)); + offset.Val, DWARFAddressSpace, PtrAuthData, + flags.Val, extraData.Val, annotations.Val)); return false; } diff --git a/llvm/lib/Bitcode/Reader/MetadataLoader.cpp b/llvm/lib/Bitcode/Reader/MetadataLoader.cpp index 770eb83af17f9..bdc2db82dfbe0 100644 --- a/llvm/lib/Bitcode/Reader/MetadataLoader.cpp +++ b/llvm/lib/Bitcode/Reader/MetadataLoader.cpp @@ -1556,7 +1556,7 @@ Error MetadataLoader::MetadataLoaderImpl::parseOneMetadata( break; } case bitc::METADATA_DERIVED_TYPE: { - if (Record.size() < 12 || Record.size() > 14) + if (Record.size() < 12 || Record.size() > 15) return error("Invalid record"); // DWARF address space is encoded as N->getDWARFAddressSpace() + 1. 0 means @@ -1566,8 +1566,18 @@ Error MetadataLoader::MetadataLoaderImpl::parseOneMetadata( DWARFAddressSpace = Record[12] - 1; Metadata *Annotations = nullptr; - if (Record.size() > 13 && Record[13]) - Annotations = getMDOrNull(Record[13]); + std::optional PtrAuthData; + + // Only look for annotations/ptrauth if both are allocated. + // If not, we can't tell which was intended to be embedded, as both ptrauth + // and annotations have been expected at Record[13] at various times. + if (Record.size() > 14) { + if (Record[13]) + Annotations = getMDOrNull(Record[13]); + + if (Record[14]) + PtrAuthData = DIDerivedType::PtrAuthData(Record[14]); + } IsDistinct = Record[0]; DINode::DIFlags Flags = static_cast(Record[10]); @@ -1577,7 +1587,7 @@ Error MetadataLoader::MetadataLoaderImpl::parseOneMetadata( getMDOrNull(Record[3]), Record[4], getDITypeRefOrNull(Record[5]), getDITypeRefOrNull(Record[6]), Record[7], Record[8], - Record[9], DWARFAddressSpace, Flags, + Record[9], DWARFAddressSpace, PtrAuthData, Flags, getDITypeRefOrNull(Record[11]), Annotations)), NextMetadataNo); NextMetadataNo++; diff --git a/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp b/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp index 13be0b0c3307f..16963e408ed4d 100644 --- a/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp +++ b/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp @@ -1801,9 +1801,13 @@ void ModuleBitcodeWriter::writeDIDerivedType(const DIDerivedType *N, Record.push_back(*DWARFAddressSpace + 1); else Record.push_back(0); - Record.push_back(VE.getMetadataOrNullID(N->getAnnotations().get())); + if (auto PtrAuthData = N->getPtrAuthData()) + Record.push_back(PtrAuthData->Payload.RawData); + else + Record.push_back(0); + Stream.EmitRecord(bitc::METADATA_DERIVED_TYPE, Record, Abbrev); Record.clear(); } diff --git a/llvm/lib/CodeGen/AsmPrinter/DwarfUnit.cpp b/llvm/lib/CodeGen/AsmPrinter/DwarfUnit.cpp index d462859e48946..ae0226934804f 100644 --- a/llvm/lib/CodeGen/AsmPrinter/DwarfUnit.cpp +++ b/llvm/lib/CodeGen/AsmPrinter/DwarfUnit.cpp @@ -803,6 +803,20 @@ void DwarfUnit::constructTypeDIE(DIE &Buffer, const DIDerivedType *DTy) { if (DTy->getDWARFAddressSpace()) addUInt(Buffer, dwarf::DW_AT_address_class, dwarf::DW_FORM_data4, *DTy->getDWARFAddressSpace()); + if (auto Key = DTy->getPtrAuthKey()) + addUInt(Buffer, dwarf::DW_AT_LLVM_ptrauth_key, dwarf::DW_FORM_data1, *Key); + if (auto AddrDisc = DTy->isPtrAuthAddressDiscriminated()) + if (AddrDisc.value()) + addFlag(Buffer, dwarf::DW_AT_LLVM_ptrauth_address_discriminated); + if (auto Disc = DTy->getPtrAuthExtraDiscriminator()) + addUInt(Buffer, dwarf::DW_AT_LLVM_ptrauth_extra_discriminator, + dwarf::DW_FORM_data2, *Disc); + if (auto IsaPointer = DTy->isPtrAuthIsaPointer()) + if (*IsaPointer) + addFlag(Buffer, dwarf::DW_AT_LLVM_ptrauth_isa_pointer); + if (auto AuthenticatesNullValues = DTy->getPtrAuthAuthenticatesNullValues()) + if (*AuthenticatesNullValues) + addFlag(Buffer, dwarf::DW_AT_LLVM_ptrauth_authenticates_null_values); } void DwarfUnit::constructSubprogramArguments(DIE &Buffer, DITypeRefArray Args) { diff --git a/llvm/lib/IR/AsmWriter.cpp b/llvm/lib/IR/AsmWriter.cpp index d3c64a57f7fdf..4b5709ba8173a 100644 --- a/llvm/lib/IR/AsmWriter.cpp +++ b/llvm/lib/IR/AsmWriter.cpp @@ -2104,6 +2104,17 @@ static void writeDIDerivedType(raw_ostream &Out, const DIDerivedType *N, Printer.printInt("dwarfAddressSpace", *DWARFAddressSpace, /* ShouldSkipZero */ false); Printer.printMetadata("annotations", N->getRawAnnotations()); + if (auto Key = N->getPtrAuthKey()) + Printer.printInt("ptrAuthKey", *Key); + if (auto AddrDisc = N->isPtrAuthAddressDiscriminated()) + Printer.printBool("ptrAuthIsAddressDiscriminated", *AddrDisc); + if (auto Disc = N->getPtrAuthExtraDiscriminator()) + Printer.printInt("ptrAuthExtraDiscriminator", *Disc); + if (auto IsaPointer = N->isPtrAuthIsaPointer()) + Printer.printBool("ptrAuthIsaPointer", *IsaPointer); + if (auto AuthenticatesNullValues = N->getPtrAuthAuthenticatesNullValues()) + Printer.printBool("ptrAuthAuthenticatesNullValues", + *AuthenticatesNullValues); Out << ")"; } diff --git a/llvm/lib/IR/DIBuilder.cpp b/llvm/lib/IR/DIBuilder.cpp index 62efaba025344..2842cb15e78fb 100644 --- a/llvm/lib/IR/DIBuilder.cpp +++ b/llvm/lib/IR/DIBuilder.cpp @@ -296,7 +296,20 @@ DIStringType *DIBuilder::createStringType(StringRef Name, DIDerivedType *DIBuilder::createQualifiedType(unsigned Tag, DIType *FromTy) { return DIDerivedType::get(VMContext, Tag, "", nullptr, 0, nullptr, FromTy, 0, - 0, 0, std::nullopt, DINode::FlagZero); + 0, 0, std::nullopt, std::nullopt, DINode::FlagZero); +} + +DIDerivedType *DIBuilder::createPtrAuthQualifiedType( + DIType *FromTy, unsigned Key, bool IsAddressDiscriminated, + unsigned ExtraDiscriminator, bool IsaPointer, + bool AuthenticatesNullValues) { + return DIDerivedType::get( + VMContext, dwarf::DW_TAG_LLVM_ptrauth_type, "", nullptr, 0, nullptr, + FromTy, 0, 0, 0, std::nullopt, + std::optional({Key, IsAddressDiscriminated, + ExtraDiscriminator, IsaPointer, + AuthenticatesNullValues}), + DINode::FlagZero); } DIDerivedType * @@ -307,8 +320,8 @@ DIBuilder::createPointerType(DIType *PointeeTy, uint64_t SizeInBits, // FIXME: Why is there a name here? return DIDerivedType::get(VMContext, dwarf::DW_TAG_pointer_type, Name, nullptr, 0, nullptr, PointeeTy, SizeInBits, - AlignInBits, 0, DWARFAddressSpace, DINode::FlagZero, - nullptr, Annotations); + AlignInBits, 0, DWARFAddressSpace, std::nullopt, + DINode::FlagZero, nullptr, Annotations); } DIDerivedType *DIBuilder::createMemberPointerType(DIType *PointeeTy, @@ -318,7 +331,8 @@ DIDerivedType *DIBuilder::createMemberPointerType(DIType *PointeeTy, DINode::DIFlags Flags) { return DIDerivedType::get(VMContext, dwarf::DW_TAG_ptr_to_member_type, "", nullptr, 0, nullptr, PointeeTy, SizeInBits, - AlignInBits, 0, std::nullopt, Flags, Base); + AlignInBits, 0, std::nullopt, std::nullopt, Flags, + Base); } DIDerivedType * @@ -327,7 +341,7 @@ DIBuilder::createReferenceType(unsigned Tag, DIType *RTy, uint64_t SizeInBits, std::optional DWARFAddressSpace) { assert(RTy && "Unable to create reference type"); return DIDerivedType::get(VMContext, Tag, "", nullptr, 0, nullptr, RTy, - SizeInBits, AlignInBits, 0, DWARFAddressSpace, + SizeInBits, AlignInBits, 0, DWARFAddressSpace, {}, DINode::FlagZero); } @@ -338,15 +352,16 @@ DIDerivedType *DIBuilder::createTypedef(DIType *Ty, StringRef Name, DINodeArray Annotations) { return DIDerivedType::get(VMContext, dwarf::DW_TAG_typedef, Name, File, LineNo, getNonCompileUnitScope(Context), Ty, 0, - AlignInBits, 0, std::nullopt, Flags, nullptr, - Annotations); + AlignInBits, 0, std::nullopt, std::nullopt, Flags, + nullptr, Annotations); } DIDerivedType *DIBuilder::createFriend(DIType *Ty, DIType *FriendTy) { assert(Ty && "Invalid type!"); assert(FriendTy && "Invalid friend type!"); return DIDerivedType::get(VMContext, dwarf::DW_TAG_friend, "", nullptr, 0, Ty, - FriendTy, 0, 0, 0, std::nullopt, DINode::FlagZero); + FriendTy, 0, 0, 0, std::nullopt, std::nullopt, + DINode::FlagZero); } DIDerivedType *DIBuilder::createInheritance(DIType *Ty, DIType *BaseTy, @@ -358,7 +373,7 @@ DIDerivedType *DIBuilder::createInheritance(DIType *Ty, DIType *BaseTy, ConstantInt::get(IntegerType::get(VMContext, 32), VBPtrOffset)); return DIDerivedType::get(VMContext, dwarf::DW_TAG_inheritance, "", nullptr, 0, Ty, BaseTy, 0, 0, BaseOffset, std::nullopt, - Flags, ExtraData); + std::nullopt, Flags, ExtraData); } DIDerivedType *DIBuilder::createMemberType( @@ -368,7 +383,7 @@ DIDerivedType *DIBuilder::createMemberType( return DIDerivedType::get(VMContext, dwarf::DW_TAG_member, Name, File, LineNumber, getNonCompileUnitScope(Scope), Ty, SizeInBits, AlignInBits, OffsetInBits, std::nullopt, - Flags, nullptr, Annotations); + std::nullopt, Flags, nullptr, Annotations); } static ConstantAsMetadata *getConstantOrNull(Constant *C) { @@ -381,10 +396,10 @@ DIDerivedType *DIBuilder::createVariantMemberType( DIScope *Scope, StringRef Name, DIFile *File, unsigned LineNumber, uint64_t SizeInBits, uint32_t AlignInBits, uint64_t OffsetInBits, Constant *Discriminant, DINode::DIFlags Flags, DIType *Ty) { - return DIDerivedType::get(VMContext, dwarf::DW_TAG_member, Name, File, - LineNumber, getNonCompileUnitScope(Scope), Ty, - SizeInBits, AlignInBits, OffsetInBits, std::nullopt, - Flags, getConstantOrNull(Discriminant)); + return DIDerivedType::get( + VMContext, dwarf::DW_TAG_member, Name, File, LineNumber, + getNonCompileUnitScope(Scope), Ty, SizeInBits, AlignInBits, OffsetInBits, + std::nullopt, std::nullopt, Flags, getConstantOrNull(Discriminant)); } DIDerivedType *DIBuilder::createBitFieldMemberType( @@ -395,7 +410,7 @@ DIDerivedType *DIBuilder::createBitFieldMemberType( return DIDerivedType::get( VMContext, dwarf::DW_TAG_member, Name, File, LineNumber, getNonCompileUnitScope(Scope), Ty, SizeInBits, /*AlignInBits=*/0, - OffsetInBits, std::nullopt, Flags, + OffsetInBits, std::nullopt, std::nullopt, Flags, ConstantAsMetadata::get(ConstantInt::get(IntegerType::get(VMContext, 64), StorageOffsetInBits)), Annotations); @@ -409,7 +424,8 @@ DIBuilder::createStaticMemberType(DIScope *Scope, StringRef Name, DIFile *File, Flags |= DINode::FlagStaticMember; return DIDerivedType::get(VMContext, Tag, Name, File, LineNumber, getNonCompileUnitScope(Scope), Ty, 0, AlignInBits, - 0, std::nullopt, Flags, getConstantOrNull(Val)); + 0, std::nullopt, std::nullopt, Flags, + getConstantOrNull(Val)); } DIDerivedType * @@ -420,7 +436,7 @@ DIBuilder::createObjCIVar(StringRef Name, DIFile *File, unsigned LineNumber, return DIDerivedType::get(VMContext, dwarf::DW_TAG_member, Name, File, LineNumber, getNonCompileUnitScope(File), Ty, SizeInBits, AlignInBits, OffsetInBits, std::nullopt, - Flags, PropertyNode); + std::nullopt, Flags, PropertyNode); } DIObjCProperty * @@ -555,10 +571,10 @@ DIDerivedType *DIBuilder::createSetType(DIScope *Scope, StringRef Name, DIFile *File, unsigned LineNo, uint64_t SizeInBits, uint32_t AlignInBits, DIType *Ty) { - auto *R = - DIDerivedType::get(VMContext, dwarf::DW_TAG_set_type, Name, File, LineNo, - getNonCompileUnitScope(Scope), Ty, SizeInBits, - AlignInBits, 0, std::nullopt, DINode::FlagZero); + auto *R = DIDerivedType::get(VMContext, dwarf::DW_TAG_set_type, Name, File, + LineNo, getNonCompileUnitScope(Scope), Ty, + SizeInBits, AlignInBits, 0, std::nullopt, + std::nullopt, DINode::FlagZero); trackIfUnresolved(R); return R; } diff --git a/llvm/lib/IR/DebugInfo.cpp b/llvm/lib/IR/DebugInfo.cpp index eaa5cb36a49c1..81e8d48eef66e 100644 --- a/llvm/lib/IR/DebugInfo.cpp +++ b/llvm/lib/IR/DebugInfo.cpp @@ -1334,9 +1334,9 @@ LLVMMetadataRef LLVMDIBuilderCreatePointerType( LLVMDIBuilderRef Builder, LLVMMetadataRef PointeeTy, uint64_t SizeInBits, uint32_t AlignInBits, unsigned AddressSpace, const char *Name, size_t NameLen) { - return wrap(unwrap(Builder)->createPointerType(unwrapDI(PointeeTy), - SizeInBits, AlignInBits, - AddressSpace, {Name, NameLen})); + return wrap(unwrap(Builder)->createPointerType( + unwrapDI(PointeeTy), SizeInBits, AlignInBits, AddressSpace, + {Name, NameLen})); } LLVMMetadataRef LLVMDIBuilderCreateStructType( diff --git a/llvm/lib/IR/DebugInfoMetadata.cpp b/llvm/lib/IR/DebugInfoMetadata.cpp index 28f96653d815b..2b799eea7d56f 100644 --- a/llvm/lib/IR/DebugInfoMetadata.cpp +++ b/llvm/lib/IR/DebugInfoMetadata.cpp @@ -731,23 +731,22 @@ Constant *DIDerivedType::getDiscriminantValue() const { return nullptr; } -DIDerivedType * -DIDerivedType::getImpl(LLVMContext &Context, unsigned Tag, MDString *Name, - Metadata *File, unsigned Line, Metadata *Scope, - Metadata *BaseType, uint64_t SizeInBits, - uint32_t AlignInBits, uint64_t OffsetInBits, - std::optional DWARFAddressSpace, DIFlags Flags, - Metadata *ExtraData, Metadata *Annotations, - StorageType Storage, bool ShouldCreate) { +DIDerivedType *DIDerivedType::getImpl( + LLVMContext &Context, unsigned Tag, MDString *Name, Metadata *File, + unsigned Line, Metadata *Scope, Metadata *BaseType, uint64_t SizeInBits, + uint32_t AlignInBits, uint64_t OffsetInBits, + std::optional DWARFAddressSpace, + std::optional PtrAuthData, DIFlags Flags, Metadata *ExtraData, + Metadata *Annotations, StorageType Storage, bool ShouldCreate) { assert(isCanonical(Name) && "Expected canonical MDString"); DEFINE_GETIMPL_LOOKUP(DIDerivedType, (Tag, Name, File, Line, Scope, BaseType, SizeInBits, - AlignInBits, OffsetInBits, DWARFAddressSpace, Flags, - ExtraData, Annotations)); + AlignInBits, OffsetInBits, DWARFAddressSpace, + PtrAuthData, Flags, ExtraData, Annotations)); Metadata *Ops[] = {File, Scope, Name, BaseType, ExtraData, Annotations}; DEFINE_GETIMPL_STORE(DIDerivedType, (Tag, Line, SizeInBits, AlignInBits, OffsetInBits, - DWARFAddressSpace, Flags), + DWARFAddressSpace, PtrAuthData, Flags), Ops); } diff --git a/llvm/lib/IR/LLVMContextImpl.h b/llvm/lib/IR/LLVMContextImpl.h index 6a20291344989..3a6d48c03a366 100644 --- a/llvm/lib/IR/LLVMContextImpl.h +++ b/llvm/lib/IR/LLVMContextImpl.h @@ -539,6 +539,7 @@ template <> struct MDNodeKeyImpl { uint64_t OffsetInBits; uint32_t AlignInBits; std::optional DWARFAddressSpace; + std::optional PtrAuthData; unsigned Flags; Metadata *ExtraData; Metadata *Annotations; @@ -546,18 +547,21 @@ template <> struct MDNodeKeyImpl { MDNodeKeyImpl(unsigned Tag, MDString *Name, Metadata *File, unsigned Line, Metadata *Scope, Metadata *BaseType, uint64_t SizeInBits, uint32_t AlignInBits, uint64_t OffsetInBits, - std::optional DWARFAddressSpace, unsigned Flags, - Metadata *ExtraData, Metadata *Annotations) + std::optional DWARFAddressSpace, + std::optional PtrAuthData, + unsigned Flags, Metadata *ExtraData, Metadata *Annotations) : Tag(Tag), Name(Name), File(File), Line(Line), Scope(Scope), BaseType(BaseType), SizeInBits(SizeInBits), OffsetInBits(OffsetInBits), AlignInBits(AlignInBits), DWARFAddressSpace(DWARFAddressSpace), - Flags(Flags), ExtraData(ExtraData), Annotations(Annotations) {} + PtrAuthData(PtrAuthData), Flags(Flags), ExtraData(ExtraData), + Annotations(Annotations) {} MDNodeKeyImpl(const DIDerivedType *N) : Tag(N->getTag()), Name(N->getRawName()), File(N->getRawFile()), Line(N->getLine()), Scope(N->getRawScope()), BaseType(N->getRawBaseType()), SizeInBits(N->getSizeInBits()), OffsetInBits(N->getOffsetInBits()), AlignInBits(N->getAlignInBits()), - DWARFAddressSpace(N->getDWARFAddressSpace()), Flags(N->getFlags()), + DWARFAddressSpace(N->getDWARFAddressSpace()), + PtrAuthData(N->getPtrAuthData()), Flags(N->getFlags()), ExtraData(N->getRawExtraData()), Annotations(N->getRawAnnotations()) {} bool isKeyOf(const DIDerivedType *RHS) const { @@ -568,7 +572,8 @@ template <> struct MDNodeKeyImpl { AlignInBits == RHS->getAlignInBits() && OffsetInBits == RHS->getOffsetInBits() && DWARFAddressSpace == RHS->getDWARFAddressSpace() && - Flags == RHS->getFlags() && ExtraData == RHS->getRawExtraData() && + PtrAuthData == RHS->getPtrAuthData() && Flags == RHS->getFlags() && + ExtraData == RHS->getRawExtraData() && Annotations == RHS->getRawAnnotations(); } diff --git a/llvm/lib/IR/Verifier.cpp b/llvm/lib/IR/Verifier.cpp index b04d39c700a8f..fa0d27f5aa178 100644 --- a/llvm/lib/IR/Verifier.cpp +++ b/llvm/lib/IR/Verifier.cpp @@ -1181,6 +1181,7 @@ void Verifier::visitDIDerivedType(const DIDerivedType &N) { N.getTag() == dwarf::DW_TAG_volatile_type || N.getTag() == dwarf::DW_TAG_restrict_type || N.getTag() == dwarf::DW_TAG_atomic_type || + N.getTag() == dwarf::DW_TAG_LLVM_ptrauth_type || N.getTag() == dwarf::DW_TAG_member || (N.getTag() == dwarf::DW_TAG_variable && N.isStaticMember()) || N.getTag() == dwarf::DW_TAG_inheritance || diff --git a/llvm/test/Assembler/debug-info.ll b/llvm/test/Assembler/debug-info.ll index 419623a2cb7d1..06144b261373f 100644 --- a/llvm/test/Assembler/debug-info.ll +++ b/llvm/test/Assembler/debug-info.ll @@ -1,8 +1,8 @@ ; RUN: llvm-as < %s | llvm-dis | llvm-as | llvm-dis | FileCheck %s ; RUN: verify-uselistorder %s -; CHECK: !named = !{!0, !0, !1, !2, !3, !4, !5, !6, !7, !8, !8, !9, !10, !11, !12, !13, !14, !15, !16, !17, !18, !19, !20, !21, !22, !23, !24, !25, !26, !27, !27, !28, !29, !30, !31, !32, !33, !34, !35, !36, !37, !38, !39} -!named = !{!0, !1, !2, !3, !4, !5, !6, !7, !8, !9, !10, !11, !12, !13, !14, !15, !16, !17, !18, !19, !20, !21, !22, !23, !24, !25, !26, !27, !28, !29, !30, !31, !32, !33, !34, !35, !36, !37, !38, !39, !40, !41, !42} +; CHECK: !named = !{!0, !0, !1, !2, !3, !4, !5, !6, !7, !8, !8, !9, !10, !11, !12, !13, !14, !15, !16, !17, !18, !19, !20, !21, !22, !23, !24, !25, !26, !27, !27, !28, !29, !30, !31, !32, !33, !34, !35, !36, !37, !38, !39, !40, !41, !42, !43} +!named = !{!0, !1, !2, !3, !4, !5, !6, !7, !8, !9, !10, !11, !12, !13, !14, !15, !16, !17, !18, !19, !20, !21, !22, !23, !24, !25, !26, !27, !28, !29, !30, !31, !32, !33, !34, !35, !36, !37, !38, !39, !40, !41, !42, !43, !44, !45, !46} ; CHECK: !0 = !DISubrange(count: 3, lowerBound: 0) ; CHECK-NEXT: !1 = !DISubrange(count: 3, lowerBound: 4) @@ -99,3 +99,15 @@ ; CHECK-NEXT: !39 = !DIBasicType(name: "u64.le", size: 64, align: 1, encoding: DW_ATE_unsigned, flags: DIFlagLittleEndian) !41 = !DIBasicType(name: "u64.be", size: 64, align: 1, encoding: DW_ATE_unsigned, flags: DIFlagBigEndian) !42 = !DIBasicType(name: "u64.le", size: 64, align: 1, encoding: DW_ATE_unsigned, flags: DIFlagLittleEndian) + +; CHECK: !DIDerivedType(tag: DW_TAG_LLVM_ptrauth_type, baseType: !13, ptrAuthKey: 2, ptrAuthIsAddressDiscriminated: true, ptrAuthExtraDiscriminator: 1234, ptrAuthIsaPointer: false, ptrAuthAuthenticatesNullValues: false) +!43 = !DIDerivedType(tag: DW_TAG_LLVM_ptrauth_type, baseType: !15, ptrAuthKey: 2, ptrAuthIsAddressDiscriminated: true, ptrAuthExtraDiscriminator: 1234) + +; CHECK: !DIDerivedType(tag: DW_TAG_LLVM_ptrauth_type, baseType: !13, ptrAuthKey: 2, ptrAuthIsAddressDiscriminated: true, ptrAuthExtraDiscriminator: 1234, ptrAuthIsaPointer: true, ptrAuthAuthenticatesNullValues: false) +!44 = !DIDerivedType(tag: DW_TAG_LLVM_ptrauth_type, baseType: !15, ptrAuthKey: 2, ptrAuthIsAddressDiscriminated: true, ptrAuthExtraDiscriminator: 1234, ptrAuthIsaPointer: true) + +; CHECK: !DIDerivedType(tag: DW_TAG_LLVM_ptrauth_type, baseType: !13, ptrAuthKey: 2, ptrAuthIsAddressDiscriminated: true, ptrAuthExtraDiscriminator: 1234, ptrAuthIsaPointer: false, ptrAuthAuthenticatesNullValues: true) +!45 = !DIDerivedType(tag: DW_TAG_LLVM_ptrauth_type, baseType: !15, ptrAuthKey: 2, ptrAuthIsAddressDiscriminated: true, ptrAuthExtraDiscriminator: 1234, ptrAuthAuthenticatesNullValues: true) + +; CHECK: !DIDerivedType(tag: DW_TAG_LLVM_ptrauth_type, baseType: !13, ptrAuthKey: 2, ptrAuthIsAddressDiscriminated: true, ptrAuthExtraDiscriminator: 1234, ptrAuthIsaPointer: true, ptrAuthAuthenticatesNullValues: true) +!46 = !DIDerivedType(tag: DW_TAG_LLVM_ptrauth_type, baseType: !15, ptrAuthKey: 2, ptrAuthIsAddressDiscriminated: true, ptrAuthExtraDiscriminator: 1234, ptrAuthIsaPointer: true, ptrAuthAuthenticatesNullValues: true) diff --git a/llvm/test/DebugInfo/AArch64/ptrauth.ll b/llvm/test/DebugInfo/AArch64/ptrauth.ll new file mode 100644 index 0000000000000..4f84fe4f96297 --- /dev/null +++ b/llvm/test/DebugInfo/AArch64/ptrauth.ll @@ -0,0 +1,70 @@ +; RUN: llc %s -filetype=obj -mtriple arm64e-apple-darwin -o - \ +; RUN: | llvm-dwarfdump - | FileCheck %s + +; CHECK: DW_AT_type (0x{{0+}}[[TY:.*]] "void *__ptrauth(4, 0, 0x04d2)") +; CHECK: 0x{{0+}}[[TY]]: DW_TAG_LLVM_ptrauth_type +; CHECK-NEXT: DW_AT_type {{.*}}"void *" +; CHECK-NEXT: DW_AT_LLVM_ptrauth_key (0x04) +; CHECK-NEXT: DW_AT_LLVM_ptrauth_extra_discriminator (0x04d2) + +; CHECK: DW_AT_type (0x{{0+}}[[TY:.*]] "void *__ptrauth(4, 1, 0x04d3)") +; CHECK: 0x{{0+}}[[TY]]: DW_TAG_LLVM_ptrauth_type +; CHECK-NEXT: DW_AT_type {{.*}}"void *" +; CHECK-NEXT: DW_AT_LLVM_ptrauth_key (0x04) +; CHECK-NEXT: DW_AT_LLVM_ptrauth_address_discriminated (true) +; CHECK-NEXT: DW_AT_LLVM_ptrauth_extra_discriminator (0x04d3) + +; CHECK: DW_AT_type (0x{{0+}}[[TY:.*]] "void *__ptrauth(4, 1, 0x04d4, "isa-pointer")") +; CHECK: 0x{{0+}}[[TY]]: DW_TAG_LLVM_ptrauth_type +; CHECK-NEXT: DW_AT_type {{.*}}"void *" +; CHECK-NEXT: DW_AT_LLVM_ptrauth_key (0x04) +; CHECK-NEXT: DW_AT_LLVM_ptrauth_address_discriminated (true) +; CHECK-NEXT: DW_AT_LLVM_ptrauth_extra_discriminator (0x04d4) +; CHECK-NEXT: DW_AT_LLVM_ptrauth_isa_pointer (true) + +; CHECK: DW_AT_type (0x{{0+}}[[TY:.*]] "void *__ptrauth(4, 1, 0x04d5, "authenticates-null-values")") +; CHECK: 0x{{0+}}[[TY]]: DW_TAG_LLVM_ptrauth_type +; CHECK-NEXT: DW_AT_type {{.*}}"void *" +; CHECK-NEXT: DW_AT_LLVM_ptrauth_key (0x04) +; CHECK-NEXT: DW_AT_LLVM_ptrauth_address_discriminated (true) +; CHECK-NEXT: DW_AT_LLVM_ptrauth_extra_discriminator (0x04d5) +; CHECK-NEXT: DW_AT_LLVM_ptrauth_authenticates_null_values (true) + +; CHECK: DW_AT_type (0x{{0+}}[[TY:.*]] "void *__ptrauth(4, 1, 0x04d6, "isa-pointer,authenticates-null-values")") +; CHECK: 0x{{0+}}[[TY]]: DW_TAG_LLVM_ptrauth_type +; CHECK-NEXT: DW_AT_type {{.*}}"void *" +; CHECK-NEXT: DW_AT_LLVM_ptrauth_key (0x04) +; CHECK-NEXT: DW_AT_LLVM_ptrauth_address_discriminated (true) +; CHECK-NEXT: DW_AT_LLVM_ptrauth_extra_discriminator (0x04d6) +; CHECK-NEXT: DW_AT_LLVM_ptrauth_isa_pointer (true) +; CHECK-NEXT: DW_AT_LLVM_ptrauth_authenticates_null_values (true) + +target datalayout = "e-m:o-i64:64-i128:128-n32:64-S128" + +@p = common global i8* null, align 8, !dbg !0 + +!llvm.dbg.cu = !{!10} +!llvm.module.flags = !{!19, !20} + +!0 = !DIGlobalVariableExpression(var: !5, expr: !DIExpression()) +!1 = !DIGlobalVariableExpression(var: !6, expr: !DIExpression()) +!2 = !DIGlobalVariableExpression(var: !7, expr: !DIExpression()) +!3 = !DIGlobalVariableExpression(var: !8, expr: !DIExpression()) +!4 = !DIGlobalVariableExpression(var: !9, expr: !DIExpression()) +!5 = distinct !DIGlobalVariable(name: "p1", scope: !10, file: !11, line: 1, type: !14, isLocal: false, isDefinition: true) +!6 = distinct !DIGlobalVariable(name: "p2", scope: !10, file: !11, line: 1, type: !15, isLocal: false, isDefinition: true) +!7 = distinct !DIGlobalVariable(name: "p3", scope: !10, file: !11, line: 1, type: !16, isLocal: false, isDefinition: true) +!8 = distinct !DIGlobalVariable(name: "p4", scope: !10, file: !11, line: 1, type: !17, isLocal: false, isDefinition: true) +!9 = distinct !DIGlobalVariable(name: "p5", scope: !10, file: !11, line: 1, type: !18, isLocal: false, isDefinition: true) +!10 = distinct !DICompileUnit(language: DW_LANG_C99, file: !11, emissionKind: FullDebug, globals: !13) +!11 = !DIFile(filename: "/tmp/p.c", directory: "/") +!12 = !{} +!13 = !{!0,!1,!2,!3,!4} +!14 = !DIDerivedType(tag: DW_TAG_LLVM_ptrauth_type, baseType: !21, ptrAuthKey: 4, ptrAuthIsAddressDiscriminated: false, ptrAuthExtraDiscriminator: 1234) +!15 = !DIDerivedType(tag: DW_TAG_LLVM_ptrauth_type, baseType: !21, ptrAuthKey: 4, ptrAuthIsAddressDiscriminated: true, ptrAuthExtraDiscriminator: 1235) +!16 = !DIDerivedType(tag: DW_TAG_LLVM_ptrauth_type, baseType: !21, ptrAuthKey: 4, ptrAuthIsAddressDiscriminated: true, ptrAuthExtraDiscriminator: 1236, ptrAuthIsaPointer: true) +!17 = !DIDerivedType(tag: DW_TAG_LLVM_ptrauth_type, baseType: !21, ptrAuthKey: 4, ptrAuthIsAddressDiscriminated: true, ptrAuthExtraDiscriminator: 1237, ptrAuthAuthenticatesNullValues: true) +!18 = !DIDerivedType(tag: DW_TAG_LLVM_ptrauth_type, baseType: !21, ptrAuthKey: 4, ptrAuthIsAddressDiscriminated: true, ptrAuthExtraDiscriminator: 1238, ptrAuthIsaPointer: true, ptrAuthAuthenticatesNullValues: true) +!19 = !{i32 2, !"Dwarf Version", i32 4} +!20 = !{i32 2, !"Debug Info Version", i32 3} +!21 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: null) diff --git a/llvm/unittests/IR/MetadataTest.cpp b/llvm/unittests/IR/MetadataTest.cpp index 767dd1a59d2b9..20d4090135dd4 100644 --- a/llvm/unittests/IR/MetadataTest.cpp +++ b/llvm/unittests/IR/MetadataTest.cpp @@ -106,7 +106,7 @@ class MetadataTest : public testing::Test { DIType *getDerivedType() { return DIDerivedType::getDistinct( Context, dwarf::DW_TAG_pointer_type, "", nullptr, 0, nullptr, - getBasicType("basictype"), 1, 2, 0, std::nullopt, DINode::FlagZero); + getBasicType("basictype"), 1, 2, 0, std::nullopt, {}, DINode::FlagZero); } Constant *getConstant() { return ConstantInt::get(Type::getInt32Ty(Context), Counter++); @@ -461,7 +461,7 @@ TEST_F(MDNodeTest, PrintTree) { auto *StructTy = cast(getCompositeType()); DIType *PointerTy = DIDerivedType::getDistinct( Context, dwarf::DW_TAG_pointer_type, "", nullptr, 0, nullptr, StructTy, - 1, 2, 0, std::nullopt, DINode::FlagZero); + 1, 2, 0, std::nullopt, {}, DINode::FlagZero); StructTy->replaceElements(MDTuple::get(Context, PointerTy)); auto *Var = DILocalVariable::get(Context, Scope, "foo", File, @@ -1864,13 +1864,17 @@ TEST_F(DIDerivedTypeTest, get) { DIType *BaseType = getBasicType("basic"); MDTuple *ExtraData = getTuple(); unsigned DWARFAddressSpace = 8; + DIDerivedType::PtrAuthData PtrAuthData(1, false, 1234, true, true); + DIDerivedType::PtrAuthData PtrAuthData2(1, false, 1234, true, false); DINode::DIFlags Flags5 = static_cast(5); DINode::DIFlags Flags4 = static_cast(4); - auto *N = - DIDerivedType::get(Context, dwarf::DW_TAG_pointer_type, "something", File, - 1, Scope, BaseType, 2, 3, 4, DWARFAddressSpace, Flags5, - ExtraData); + auto *N = DIDerivedType::get( + Context, dwarf::DW_TAG_pointer_type, "something", File, 1, Scope, + BaseType, 2, 3, 4, DWARFAddressSpace, std::nullopt, Flags5, ExtraData); + auto *N1 = DIDerivedType::get(Context, dwarf::DW_TAG_LLVM_ptrauth_type, "", + File, 1, Scope, N, 2, 3, 4, DWARFAddressSpace, + PtrAuthData, Flags5, ExtraData); EXPECT_EQ(dwarf::DW_TAG_pointer_type, N->getTag()); EXPECT_EQ("something", N->getName()); EXPECT_EQ(File, N->getFile()); @@ -1881,53 +1885,73 @@ TEST_F(DIDerivedTypeTest, get) { EXPECT_EQ(3u, N->getAlignInBits()); EXPECT_EQ(4u, N->getOffsetInBits()); EXPECT_EQ(DWARFAddressSpace, *N->getDWARFAddressSpace()); + EXPECT_EQ(std::nullopt, N->getPtrAuthData()); + EXPECT_EQ(PtrAuthData, N1->getPtrAuthData()); + EXPECT_NE(PtrAuthData2, N1->getPtrAuthData()); EXPECT_EQ(5u, N->getFlags()); EXPECT_EQ(ExtraData, N->getExtraData()); EXPECT_EQ(N, DIDerivedType::get(Context, dwarf::DW_TAG_pointer_type, "something", File, 1, Scope, BaseType, 2, 3, - 4, DWARFAddressSpace, Flags5, ExtraData)); + 4, DWARFAddressSpace, std::nullopt, Flags5, + ExtraData)); EXPECT_NE(N, DIDerivedType::get(Context, dwarf::DW_TAG_reference_type, "something", File, 1, Scope, BaseType, 2, 3, - 4, DWARFAddressSpace, Flags5, ExtraData)); + 4, DWARFAddressSpace, std::nullopt, Flags5, + ExtraData)); EXPECT_NE(N, DIDerivedType::get(Context, dwarf::DW_TAG_pointer_type, "else", - File, 1, Scope, BaseType, 2, 3, - 4, DWARFAddressSpace, Flags5, ExtraData)); + File, 1, Scope, BaseType, 2, 3, 4, + DWARFAddressSpace, std::nullopt, Flags5, + ExtraData)); EXPECT_NE(N, DIDerivedType::get(Context, dwarf::DW_TAG_pointer_type, "something", getFile(), 1, Scope, BaseType, 2, - 3, 4, DWARFAddressSpace, Flags5, ExtraData)); + 3, 4, DWARFAddressSpace, std::nullopt, Flags5, + ExtraData)); EXPECT_NE(N, DIDerivedType::get(Context, dwarf::DW_TAG_pointer_type, "something", File, 2, Scope, BaseType, 2, 3, - 4, DWARFAddressSpace, Flags5, ExtraData)); + 4, DWARFAddressSpace, std::nullopt, Flags5, + ExtraData)); EXPECT_NE(N, DIDerivedType::get(Context, dwarf::DW_TAG_pointer_type, "something", File, 1, getSubprogram(), - BaseType, 2, 3, 4, DWARFAddressSpace, Flags5, - ExtraData)); + BaseType, 2, 3, 4, DWARFAddressSpace, + std::nullopt, Flags5, ExtraData)); EXPECT_NE(N, DIDerivedType::get( Context, dwarf::DW_TAG_pointer_type, "something", File, 1, Scope, getBasicType("basic2"), 2, 3, 4, DWARFAddressSpace, - Flags5, ExtraData)); + std::nullopt, Flags5, ExtraData)); EXPECT_NE(N, DIDerivedType::get(Context, dwarf::DW_TAG_pointer_type, "something", File, 1, Scope, BaseType, 3, 3, - 4, DWARFAddressSpace, Flags5, ExtraData)); + 4, DWARFAddressSpace, std::nullopt, Flags5, + ExtraData)); EXPECT_NE(N, DIDerivedType::get(Context, dwarf::DW_TAG_pointer_type, "something", File, 1, Scope, BaseType, 2, 2, - 4, DWARFAddressSpace, Flags5, ExtraData)); + 4, DWARFAddressSpace, std::nullopt, Flags5, + ExtraData)); EXPECT_NE(N, DIDerivedType::get(Context, dwarf::DW_TAG_pointer_type, "something", File, 1, Scope, BaseType, 2, 3, - 5, DWARFAddressSpace, Flags5, ExtraData)); + 5, DWARFAddressSpace, std::nullopt, Flags5, + ExtraData)); EXPECT_NE(N, DIDerivedType::get(Context, dwarf::DW_TAG_pointer_type, "something", File, 1, Scope, BaseType, 2, 3, - 4, DWARFAddressSpace + 1, Flags5, ExtraData)); + 4, DWARFAddressSpace + 1, std::nullopt, + Flags5, ExtraData)); + EXPECT_NE(N1, + DIDerivedType::get(Context, dwarf::DW_TAG_LLVM_ptrauth_type, "", + File, 1, Scope, N, 2, 3, 4, DWARFAddressSpace, + std::nullopt, Flags5, ExtraData)); EXPECT_NE(N, DIDerivedType::get(Context, dwarf::DW_TAG_pointer_type, "something", File, 1, Scope, BaseType, 2, 3, - 4, DWARFAddressSpace, Flags4, ExtraData)); + 4, DWARFAddressSpace, std::nullopt, Flags4, + ExtraData)); EXPECT_NE(N, DIDerivedType::get(Context, dwarf::DW_TAG_pointer_type, "something", File, 1, Scope, BaseType, 2, 3, - 4, DWARFAddressSpace, Flags5, getTuple())); + 4, DWARFAddressSpace, std::nullopt, Flags5, + getTuple())); TempDIDerivedType Temp = N->clone(); EXPECT_EQ(N, MDNode::replaceWithUniqued(std::move(Temp))); + TempDIDerivedType Temp1 = N1->clone(); + EXPECT_EQ(N1, MDNode::replaceWithUniqued(std::move(Temp1))); } TEST_F(DIDerivedTypeTest, getWithLargeValues) { @@ -1937,14 +1961,23 @@ TEST_F(DIDerivedTypeTest, getWithLargeValues) { MDTuple *ExtraData = getTuple(); DINode::DIFlags Flags = static_cast(5); - auto *N = DIDerivedType::get( - Context, dwarf::DW_TAG_pointer_type, "something", File, 1, Scope, - BaseType, UINT64_MAX, UINT32_MAX - 1, UINT64_MAX - 2, UINT32_MAX - 3, - Flags, ExtraData); + auto *N = DIDerivedType::get(Context, dwarf::DW_TAG_pointer_type, "something", + File, 1, Scope, BaseType, UINT64_MAX, + UINT32_MAX - 1, UINT64_MAX - 2, UINT32_MAX - 3, + std::nullopt, Flags, ExtraData); EXPECT_EQ(UINT64_MAX, N->getSizeInBits()); EXPECT_EQ(UINT32_MAX - 1, N->getAlignInBits()); EXPECT_EQ(UINT64_MAX - 2, N->getOffsetInBits()); EXPECT_EQ(UINT32_MAX - 3, *N->getDWARFAddressSpace()); + + auto *N1 = DIDerivedType::get( + Context, dwarf::DW_TAG_LLVM_ptrauth_type, "", File, 1, Scope, N, + UINT64_MAX, UINT32_MAX - 1, UINT64_MAX - 2, UINT32_MAX - 3, + DIDerivedType::PtrAuthData(7, true, 0xffff, true, false), Flags, + ExtraData); + EXPECT_EQ(7U, *N1->getPtrAuthKey()); + EXPECT_EQ(true, *N1->isPtrAuthAddressDiscriminated()); + EXPECT_EQ(0xffffU, *N1->getPtrAuthExtraDiscriminator()); } typedef MetadataTest DICompositeTypeTest; @@ -4268,7 +4301,7 @@ TEST_F(MDTupleAllocationTest, Tracking2) { #if defined(GTEST_HAS_DEATH_TEST) && !defined(NDEBUG) && !defined(GTEST_HAS_SEH) typedef MetadataTest MDTupleAllocationDeathTest; TEST_F(MDTupleAllocationDeathTest, ResizeRejected) { - MDTuple *A = MDTuple::get(Context, None); + MDTuple *A = MDTuple::get(Context, std::nullopt); auto *Value1 = getConstantAsMetadata(); EXPECT_DEATH(A->push_back(Value1), "Resizing is not supported for uniqued nodes"); From ff2494bd18966527c92e3a6c62413c1ae3e84e38 Mon Sep 17 00:00:00 2001 From: Daniil Kovalev Date: Wed, 21 Feb 2024 01:19:47 +0300 Subject: [PATCH 2/5] Restore accidentally removed line --- llvm/lib/Bitcode/Writer/BitcodeWriter.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp b/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp index 16963e408ed4d..3126b880cc008 100644 --- a/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp +++ b/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp @@ -1801,6 +1801,7 @@ void ModuleBitcodeWriter::writeDIDerivedType(const DIDerivedType *N, Record.push_back(*DWARFAddressSpace + 1); else Record.push_back(0); + Record.push_back(VE.getMetadataOrNullID(N->getAnnotations().get())); if (auto PtrAuthData = N->getPtrAuthData()) From 57e86f68e3a83165efa521138b1646ad6a463317 Mon Sep 17 00:00:00 2001 From: Daniil Kovalev Date: Wed, 21 Feb 2024 01:20:01 +0300 Subject: [PATCH 3/5] Do not use else after return --- llvm/include/llvm/IR/DebugInfoMetadata.h | 15 +++++---------- 1 file changed, 5 insertions(+), 10 deletions(-) diff --git a/llvm/include/llvm/IR/DebugInfoMetadata.h b/llvm/include/llvm/IR/DebugInfoMetadata.h index eec150636fff7..6a13b7f4b5e11 100644 --- a/llvm/include/llvm/IR/DebugInfoMetadata.h +++ b/llvm/include/llvm/IR/DebugInfoMetadata.h @@ -1106,36 +1106,31 @@ class DIDerivedType : public DIType { std::optional getPtrAuthKey() const { if (auto PtrAuthData = getPtrAuthData()) return (unsigned)PtrAuthData->Payload.Data.Key; - else - return std::nullopt; + return std::nullopt; } /// \returns The PointerAuth address discrimination bit. std::optional isPtrAuthAddressDiscriminated() const { if (auto PtrAuthData = getPtrAuthData()) return (bool)PtrAuthData->Payload.Data.IsAddressDiscriminated; - else - return std::nullopt; + return std::nullopt; } /// \returns The PointerAuth extra discriminator. std::optional getPtrAuthExtraDiscriminator() const { if (auto PtrAuthData = getPtrAuthData()) return (unsigned)PtrAuthData->Payload.Data.ExtraDiscriminator; - else - return std::nullopt; + return std::nullopt; } /// \returns The PointerAuth IsaPointer bit. std::optional isPtrAuthIsaPointer() const { if (auto PtrAuthData = getPtrAuthData()) return (bool)PtrAuthData->Payload.Data.IsaPointer; - else - return std::nullopt; + return std::nullopt; } /// \returns The PointerAuth authenticates null values bit. std::optional getPtrAuthAuthenticatesNullValues() const { if (auto PtrAuthData = getPtrAuthData()) return (bool)PtrAuthData->Payload.Data.AuthenticatesNullValues; - else - return std::nullopt; + return std::nullopt; } /// Get extra data associated with this derived type. From 32e43df2d656e0e52adc3e1df9d98f65acf1af01 Mon Sep 17 00:00:00 2001 From: Daniil Kovalev Date: Wed, 21 Feb 2024 01:25:31 +0300 Subject: [PATCH 4/5] Do not include llvm/BinaryFormat/Dwarf.h in llvm/IR/DebugInfoMetadata.h --- llvm/include/llvm/IR/DebugInfoMetadata.h | 11 ++--------- llvm/lib/IR/DebugInfoMetadata.cpp | 11 +++++++++++ 2 files changed, 13 insertions(+), 9 deletions(-) diff --git a/llvm/include/llvm/IR/DebugInfoMetadata.h b/llvm/include/llvm/IR/DebugInfoMetadata.h index 6a13b7f4b5e11..1a953c53c17a1 100644 --- a/llvm/include/llvm/IR/DebugInfoMetadata.h +++ b/llvm/include/llvm/IR/DebugInfoMetadata.h @@ -20,7 +20,6 @@ #include "llvm/ADT/SmallVector.h" #include "llvm/ADT/StringRef.h" #include "llvm/ADT/iterator_range.h" -#include "llvm/BinaryFormat/Dwarf.h" #include "llvm/IR/Constants.h" #include "llvm/IR/Metadata.h" #include "llvm/IR/PseudoProbe.h" @@ -746,9 +745,7 @@ class DIType : public DIScope { unsigned getLine() const { return Line; } uint64_t getSizeInBits() const { return SizeInBits; } - uint32_t getAlignInBits() const { - return (getTag() == dwarf::DW_TAG_LLVM_ptrauth_type ? 0 : SubclassData32); - } + uint32_t getAlignInBits() const; uint32_t getAlignInBytes() const { return getAlignInBits() / CHAR_BIT; } uint64_t getOffsetInBits() const { return OffsetInBits; } DIFlags getFlags() const { return Flags; } @@ -1096,11 +1093,7 @@ class DIDerivedType : public DIType { return DWARFAddressSpace; } - std::optional getPtrAuthData() const { - return getTag() == dwarf::DW_TAG_LLVM_ptrauth_type - ? std::optional(PtrAuthData(SubclassData32)) - : std::nullopt; - } + std::optional getPtrAuthData() const; /// \returns The PointerAuth key. std::optional getPtrAuthKey() const { diff --git a/llvm/lib/IR/DebugInfoMetadata.cpp b/llvm/lib/IR/DebugInfoMetadata.cpp index 2b799eea7d56f..36c13e79a6492 100644 --- a/llvm/lib/IR/DebugInfoMetadata.cpp +++ b/llvm/lib/IR/DebugInfoMetadata.cpp @@ -34,6 +34,10 @@ cl::opt EnableFSDiscriminator( cl::desc("Enable adding flow sensitive discriminators")); } // namespace llvm +uint32_t DIType::getAlignInBits() const { + return (getTag() == dwarf::DW_TAG_LLVM_ptrauth_type ? 0 : SubclassData32); +} + const DIExpression::FragmentInfo DebugVariable::DefaultFragment = { std::numeric_limits::max(), std::numeric_limits::min()}; @@ -750,6 +754,13 @@ DIDerivedType *DIDerivedType::getImpl( Ops); } +std::optional +DIDerivedType::getPtrAuthData() const { + return getTag() == dwarf::DW_TAG_LLVM_ptrauth_type + ? std::optional(PtrAuthData(SubclassData32)) + : std::nullopt; +} + DICompositeType *DICompositeType::getImpl( LLVMContext &Context, unsigned Tag, MDString *Name, Metadata *File, unsigned Line, Metadata *Scope, Metadata *BaseType, uint64_t SizeInBits, From 06a0bc43553100ba5a0eaa31d1be0f49dd89e50b Mon Sep 17 00:00:00 2001 From: Daniil Kovalev Date: Thu, 29 Feb 2024 01:48:34 +0300 Subject: [PATCH 5/5] [MLIR] Fix `llvm::DIDerivedType::get` call (new argument PtrAuthData proposed) --- mlir/lib/Target/LLVMIR/DebugTranslation.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/mlir/lib/Target/LLVMIR/DebugTranslation.cpp b/mlir/lib/Target/LLVMIR/DebugTranslation.cpp index 16918aab54978..420bb8d8274ec 100644 --- a/mlir/lib/Target/LLVMIR/DebugTranslation.cpp +++ b/mlir/lib/Target/LLVMIR/DebugTranslation.cpp @@ -150,7 +150,8 @@ llvm::DIDerivedType *DebugTranslation::translateImpl(DIDerivedTypeAttr attr) { /*File=*/nullptr, /*Line=*/0, /*Scope=*/nullptr, translate(attr.getBaseType()), attr.getSizeInBits(), attr.getAlignInBits(), attr.getOffsetInBits(), - /*DWARFAddressSpace=*/std::nullopt, /*Flags=*/llvm::DINode::FlagZero); + /*DWARFAddressSpace=*/std::nullopt, /*PtrAuthData=*/std::nullopt, + /*Flags=*/llvm::DINode::FlagZero); } llvm::DIFile *DebugTranslation::translateImpl(DIFileAttr attr) {