mirror of
https://github.com/llvm/llvm-project.git
synced 2025-04-27 14:16:08 +00:00
[Dwarf] Support __ptrauth
qualifier in metadata nodes (#82363)
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) Co-authored-by: Ahmed Bougacha <ahmed@bougacha.org>
This commit is contained in:
parent
8fa33013de
commit
8f65e7b917
@ -262,6 +262,13 @@ namespace llvm {
|
||||
std::optional<unsigned> 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.
|
||||
|
@ -745,7 +745,7 @@ public:
|
||||
|
||||
unsigned getLine() const { return Line; }
|
||||
uint64_t getSizeInBits() const { return SizeInBits; }
|
||||
uint32_t getAlignInBits() const { return SubclassData32; }
|
||||
uint32_t getAlignInBits() const;
|
||||
uint32_t getAlignInBytes() const { return getAlignInBits() / CHAR_BIT; }
|
||||
uint64_t getOffsetInBits() const { return OffsetInBits; }
|
||||
DIFlags getFlags() const { return Flags; }
|
||||
@ -972,6 +972,40 @@ public:
|
||||
///
|
||||
/// 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 +1016,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<unsigned> DWARFAddressSpace, DIFlags Flags,
|
||||
std::optional<unsigned> DWARFAddressSpace,
|
||||
std::optional<PtrAuthData> PtrAuthData, DIFlags Flags,
|
||||
ArrayRef<Metadata *> 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<unsigned> DWARFAddressSpace, DIFlags Flags,
|
||||
std::optional<unsigned> DWARFAddressSpace,
|
||||
std::optional<PtrAuthData> 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<unsigned> DWARFAddressSpace, DIFlags Flags,
|
||||
std::optional<unsigned> DWARFAddressSpace,
|
||||
std::optional<PtrAuthData> 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<unsigned> 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<unsigned> DWARFAddressSpace,
|
||||
std::optional<PtrAuthData> 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<unsigned> DWARFAddressSpace, DIFlags Flags,
|
||||
std::optional<unsigned> DWARFAddressSpace,
|
||||
std::optional<PtrAuthData> 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 +1093,39 @@ public:
|
||||
return DWARFAddressSpace;
|
||||
}
|
||||
|
||||
std::optional<PtrAuthData> getPtrAuthData() const;
|
||||
|
||||
/// \returns The PointerAuth key.
|
||||
std::optional<unsigned> getPtrAuthKey() const {
|
||||
if (auto PtrAuthData = getPtrAuthData())
|
||||
return (unsigned)PtrAuthData->Payload.Data.Key;
|
||||
return std::nullopt;
|
||||
}
|
||||
/// \returns The PointerAuth address discrimination bit.
|
||||
std::optional<bool> isPtrAuthAddressDiscriminated() const {
|
||||
if (auto PtrAuthData = getPtrAuthData())
|
||||
return (bool)PtrAuthData->Payload.Data.IsAddressDiscriminated;
|
||||
return std::nullopt;
|
||||
}
|
||||
/// \returns The PointerAuth extra discriminator.
|
||||
std::optional<unsigned> getPtrAuthExtraDiscriminator() const {
|
||||
if (auto PtrAuthData = getPtrAuthData())
|
||||
return (unsigned)PtrAuthData->Payload.Data.ExtraDiscriminator;
|
||||
return std::nullopt;
|
||||
}
|
||||
/// \returns The PointerAuth IsaPointer bit.
|
||||
std::optional<bool> isPtrAuthIsaPointer() const {
|
||||
if (auto PtrAuthData = getPtrAuthData())
|
||||
return (bool)PtrAuthData->Payload.Data.IsaPointer;
|
||||
return std::nullopt;
|
||||
}
|
||||
/// \returns The PointerAuth authenticates null values bit.
|
||||
std::optional<bool> getPtrAuthAuthenticatesNullValues() const {
|
||||
if (auto PtrAuthData = getPtrAuthData())
|
||||
return (bool)PtrAuthData->Payload.Data.AuthenticatesNullValues;
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
/// Get extra data associated with this derived type.
|
||||
///
|
||||
/// Class type for pointer-to-members, objective-c property node for ivars,
|
||||
|
@ -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<unsigned> DWARFAddressSpace;
|
||||
if (dwarfAddressSpace.Val != UINT32_MAX)
|
||||
DWARFAddressSpace = dwarfAddressSpace.Val;
|
||||
std::optional<DIDerivedType::PtrAuthData> 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;
|
||||
}
|
||||
|
||||
|
@ -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<DIDerivedType::PtrAuthData> 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<DINode::DIFlags>(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++;
|
||||
|
@ -1804,6 +1804,11 @@ void ModuleBitcodeWriter::writeDIDerivedType(const DIDerivedType *N,
|
||||
|
||||
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();
|
||||
}
|
||||
|
@ -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) {
|
||||
|
@ -2135,6 +2135,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 << ")";
|
||||
}
|
||||
|
||||
|
@ -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<DIDerivedType::PtrAuthData>({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<unsigned> 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;
|
||||
}
|
||||
|
@ -1336,9 +1336,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<DIType>(PointeeTy),
|
||||
SizeInBits, AlignInBits,
|
||||
AddressSpace, {Name, NameLen}));
|
||||
return wrap(unwrap(Builder)->createPointerType(
|
||||
unwrapDI<DIType>(PointeeTy), SizeInBits, AlignInBits, AddressSpace,
|
||||
{Name, NameLen}));
|
||||
}
|
||||
|
||||
LLVMMetadataRef LLVMDIBuilderCreateStructType(
|
||||
|
@ -34,6 +34,10 @@ cl::opt<bool> 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<uint64_t>::max(), std::numeric_limits<uint64_t>::min()};
|
||||
|
||||
@ -731,26 +735,32 @@ 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<unsigned> 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<unsigned> DWARFAddressSpace,
|
||||
std::optional<PtrAuthData> 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);
|
||||
}
|
||||
|
||||
std::optional<DIDerivedType::PtrAuthData>
|
||||
DIDerivedType::getPtrAuthData() const {
|
||||
return getTag() == dwarf::DW_TAG_LLVM_ptrauth_type
|
||||
? std::optional<PtrAuthData>(PtrAuthData(SubclassData32))
|
||||
: std::nullopt;
|
||||
}
|
||||
|
||||
DICompositeType *DICompositeType::getImpl(
|
||||
LLVMContext &Context, unsigned Tag, MDString *Name, Metadata *File,
|
||||
unsigned Line, Metadata *Scope, Metadata *BaseType, uint64_t SizeInBits,
|
||||
|
@ -539,6 +539,7 @@ template <> struct MDNodeKeyImpl<DIDerivedType> {
|
||||
uint64_t OffsetInBits;
|
||||
uint32_t AlignInBits;
|
||||
std::optional<unsigned> DWARFAddressSpace;
|
||||
std::optional<DIDerivedType::PtrAuthData> PtrAuthData;
|
||||
unsigned Flags;
|
||||
Metadata *ExtraData;
|
||||
Metadata *Annotations;
|
||||
@ -546,18 +547,21 @@ template <> struct MDNodeKeyImpl<DIDerivedType> {
|
||||
MDNodeKeyImpl(unsigned Tag, MDString *Name, Metadata *File, unsigned Line,
|
||||
Metadata *Scope, Metadata *BaseType, uint64_t SizeInBits,
|
||||
uint32_t AlignInBits, uint64_t OffsetInBits,
|
||||
std::optional<unsigned> DWARFAddressSpace, unsigned Flags,
|
||||
Metadata *ExtraData, Metadata *Annotations)
|
||||
std::optional<unsigned> DWARFAddressSpace,
|
||||
std::optional<DIDerivedType::PtrAuthData> 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<DIDerivedType> {
|
||||
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();
|
||||
}
|
||||
|
||||
|
@ -1223,6 +1223,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 ||
|
||||
|
@ -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)
|
||||
|
70
llvm/test/DebugInfo/AArch64/ptrauth.ll
Normal file
70
llvm/test/DebugInfo/AArch64/ptrauth.ll
Normal file
@ -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)
|
@ -106,7 +106,7 @@ protected:
|
||||
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<DICompositeType>(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<DINode::DIFlags>(5);
|
||||
DINode::DIFlags Flags4 = static_cast<DINode::DIFlags>(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<DINode::DIFlags>(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");
|
||||
|
@ -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) {
|
||||
|
Loading…
x
Reference in New Issue
Block a user