20
20
#include " llvm/ADT/SmallVector.h"
21
21
#include " llvm/ADT/StringRef.h"
22
22
#include " llvm/ADT/iterator_range.h"
23
+ #include " llvm/BinaryFormat/Dwarf.h"
23
24
#include " llvm/IR/Constants.h"
24
25
#include " llvm/IR/Metadata.h"
25
26
#include " llvm/IR/PseudoProbe.h"
@@ -745,7 +746,9 @@ class DIType : public DIScope {
745
746
746
747
unsigned getLine () const { return Line; }
747
748
uint64_t getSizeInBits () const { return SizeInBits; }
748
- uint32_t getAlignInBits () const { return SubclassData32; }
749
+ uint32_t getAlignInBits () const {
750
+ return (getTag () == dwarf::DW_TAG_LLVM_ptrauth_type ? 0 : SubclassData32);
751
+ }
749
752
uint32_t getAlignInBytes () const { return getAlignInBits () / CHAR_BIT; }
750
753
uint64_t getOffsetInBits () const { return OffsetInBits; }
751
754
DIFlags getFlags () const { return Flags; }
@@ -972,6 +975,40 @@ class DIStringType : public DIType {
972
975
// /
973
976
// / TODO: Split out members (inheritance, fields, methods, etc.).
974
977
class DIDerivedType : public DIType {
978
+ public:
979
+ // / Pointer authentication (__ptrauth) metadata.
980
+ struct PtrAuthData {
981
+ union {
982
+ struct {
983
+ unsigned Key : 4 ;
984
+ unsigned IsAddressDiscriminated : 1 ;
985
+ unsigned ExtraDiscriminator : 16 ;
986
+ unsigned IsaPointer : 1 ;
987
+ unsigned AuthenticatesNullValues : 1 ;
988
+ } Data;
989
+ unsigned RawData;
990
+ } Payload;
991
+
992
+ PtrAuthData (unsigned FromRawData) { Payload.RawData = FromRawData; }
993
+ PtrAuthData (unsigned Key, bool IsDiscr, unsigned Discriminator,
994
+ bool IsaPointer, bool AuthenticatesNullValues) {
995
+ assert (Key < 16 );
996
+ assert (Discriminator <= 0xffff );
997
+ Payload.Data .Key = Key;
998
+ Payload.Data .IsAddressDiscriminated = IsDiscr;
999
+ Payload.Data .ExtraDiscriminator = Discriminator;
1000
+ Payload.Data .IsaPointer = IsaPointer;
1001
+ Payload.Data .AuthenticatesNullValues = AuthenticatesNullValues;
1002
+ }
1003
+ bool operator ==(struct PtrAuthData Other) const {
1004
+ return Payload.RawData == Other.Payload .RawData ;
1005
+ }
1006
+ bool operator !=(struct PtrAuthData Other) const {
1007
+ return !(*this == Other);
1008
+ }
1009
+ };
1010
+
1011
+ private:
975
1012
friend class LLVMContextImpl ;
976
1013
friend class MDNode ;
977
1014
@@ -982,59 +1019,70 @@ class DIDerivedType : public DIType {
982
1019
DIDerivedType (LLVMContext &C, StorageType Storage, unsigned Tag,
983
1020
unsigned Line, uint64_t SizeInBits, uint32_t AlignInBits,
984
1021
uint64_t OffsetInBits,
985
- std::optional<unsigned > DWARFAddressSpace, DIFlags Flags,
1022
+ std::optional<unsigned > DWARFAddressSpace,
1023
+ std::optional<PtrAuthData> PtrAuthData, DIFlags Flags,
986
1024
ArrayRef<Metadata *> Ops)
987
1025
: DIType(C, DIDerivedTypeKind, Storage, Tag, Line, SizeInBits,
988
1026
AlignInBits, OffsetInBits, Flags, Ops),
989
- DWARFAddressSpace (DWARFAddressSpace) {}
1027
+ DWARFAddressSpace (DWARFAddressSpace) {
1028
+ if (PtrAuthData)
1029
+ SubclassData32 = PtrAuthData->Payload .RawData ;
1030
+ }
990
1031
~DIDerivedType () = default ;
991
1032
static DIDerivedType *
992
1033
getImpl (LLVMContext &Context, unsigned Tag, StringRef Name, DIFile *File,
993
1034
unsigned Line, DIScope *Scope, DIType *BaseType, uint64_t SizeInBits,
994
1035
uint32_t AlignInBits, uint64_t OffsetInBits,
995
- std::optional<unsigned > DWARFAddressSpace, DIFlags Flags,
1036
+ std::optional<unsigned > DWARFAddressSpace,
1037
+ std::optional<PtrAuthData> PtrAuthData, DIFlags Flags,
996
1038
Metadata *ExtraData, DINodeArray Annotations, StorageType Storage,
997
1039
bool ShouldCreate = true ) {
998
1040
return getImpl (Context, Tag, getCanonicalMDString (Context, Name), File,
999
1041
Line, Scope, BaseType, SizeInBits, AlignInBits, OffsetInBits,
1000
- DWARFAddressSpace, Flags, ExtraData, Annotations. get () ,
1001
- Storage, ShouldCreate);
1042
+ DWARFAddressSpace, PtrAuthData, Flags, ExtraData ,
1043
+ Annotations. get (), Storage, ShouldCreate);
1002
1044
}
1003
1045
static DIDerivedType *
1004
1046
getImpl (LLVMContext &Context, unsigned Tag, MDString *Name, Metadata *File,
1005
1047
unsigned Line, Metadata *Scope, Metadata *BaseType,
1006
1048
uint64_t SizeInBits, uint32_t AlignInBits, uint64_t OffsetInBits,
1007
- std::optional<unsigned > DWARFAddressSpace, DIFlags Flags,
1049
+ std::optional<unsigned > DWARFAddressSpace,
1050
+ std::optional<PtrAuthData> PtrAuthData, DIFlags Flags,
1008
1051
Metadata *ExtraData, Metadata *Annotations, StorageType Storage,
1009
1052
bool ShouldCreate = true );
1010
1053
1011
1054
TempDIDerivedType cloneImpl () const {
1012
- return getTemporary (
1013
- getContext (), getTag (), getName (), getFile (), getLine (), getScope (),
1014
- getBaseType (), getSizeInBits (), getAlignInBits (), getOffsetInBits (),
1015
- getDWARFAddressSpace (), getFlags (), getExtraData (), getAnnotations ());
1055
+ return getTemporary (getContext (), getTag (), getName (), getFile (), getLine (),
1056
+ getScope (), getBaseType (), getSizeInBits (),
1057
+ getAlignInBits (), getOffsetInBits (),
1058
+ getDWARFAddressSpace (), getPtrAuthData (), getFlags (),
1059
+ getExtraData (), getAnnotations ());
1016
1060
}
1017
1061
1018
1062
public:
1019
- DEFINE_MDNODE_GET (
1020
- DIDerivedType,
1021
- (unsigned Tag, MDString *Name, Metadata *File, unsigned Line,
1022
- Metadata *Scope, Metadata *BaseType, uint64_t SizeInBits,
1023
- uint32_t AlignInBits, uint64_t OffsetInBits,
1024
- std::optional<unsigned > DWARFAddressSpace, DIFlags Flags,
1025
- Metadata *ExtraData = nullptr , Metadata *Annotations = nullptr ),
1026
- (Tag, Name, File, Line, Scope, BaseType, SizeInBits, AlignInBits,
1027
- OffsetInBits, DWARFAddressSpace, Flags, ExtraData, Annotations))
1063
+ DEFINE_MDNODE_GET (DIDerivedType,
1064
+ (unsigned Tag, MDString *Name, Metadata *File,
1065
+ unsigned Line, Metadata *Scope, Metadata *BaseType,
1066
+ uint64_t SizeInBits, uint32_t AlignInBits,
1067
+ uint64_t OffsetInBits,
1068
+ std::optional<unsigned > DWARFAddressSpace,
1069
+ std::optional<PtrAuthData> PtrAuthData, DIFlags Flags,
1070
+ Metadata *ExtraData = nullptr ,
1071
+ Metadata *Annotations = nullptr ),
1072
+ (Tag, Name, File, Line, Scope, BaseType, SizeInBits,
1073
+ AlignInBits, OffsetInBits, DWARFAddressSpace, PtrAuthData,
1074
+ Flags, ExtraData, Annotations))
1028
1075
DEFINE_MDNODE_GET(DIDerivedType,
1029
1076
(unsigned Tag, StringRef Name, DIFile *File, unsigned Line,
1030
1077
DIScope *Scope, DIType *BaseType, uint64_t SizeInBits,
1031
1078
uint32_t AlignInBits, uint64_t OffsetInBits,
1032
- std::optional<unsigned > DWARFAddressSpace, DIFlags Flags,
1079
+ std::optional<unsigned > DWARFAddressSpace,
1080
+ std::optional<PtrAuthData> PtrAuthData, DIFlags Flags,
1033
1081
Metadata *ExtraData = nullptr ,
1034
1082
DINodeArray Annotations = nullptr ),
1035
1083
(Tag, Name, File, Line, Scope, BaseType, SizeInBits,
1036
- AlignInBits, OffsetInBits, DWARFAddressSpace, Flags ,
1037
- ExtraData, Annotations))
1084
+ AlignInBits, OffsetInBits, DWARFAddressSpace, PtrAuthData ,
1085
+ Flags, ExtraData, Annotations))
1038
1086
1039
1087
TempDIDerivedType clone() const { return cloneImpl (); }
1040
1088
@@ -1048,6 +1096,48 @@ class DIDerivedType : public DIType {
1048
1096
return DWARFAddressSpace;
1049
1097
}
1050
1098
1099
+ std::optional<PtrAuthData> getPtrAuthData () const {
1100
+ return getTag () == dwarf::DW_TAG_LLVM_ptrauth_type
1101
+ ? std::optional<PtrAuthData>(PtrAuthData (SubclassData32))
1102
+ : std::nullopt;
1103
+ }
1104
+
1105
+ // / \returns The PointerAuth key.
1106
+ std::optional<unsigned > getPtrAuthKey () const {
1107
+ if (auto PtrAuthData = getPtrAuthData ())
1108
+ return (unsigned )PtrAuthData->Payload .Data .Key ;
1109
+ else
1110
+ return std::nullopt;
1111
+ }
1112
+ // / \returns The PointerAuth address discrimination bit.
1113
+ std::optional<bool > isPtrAuthAddressDiscriminated () const {
1114
+ if (auto PtrAuthData = getPtrAuthData ())
1115
+ return (bool )PtrAuthData->Payload .Data .IsAddressDiscriminated ;
1116
+ else
1117
+ return std::nullopt;
1118
+ }
1119
+ // / \returns The PointerAuth extra discriminator.
1120
+ std::optional<unsigned > getPtrAuthExtraDiscriminator () const {
1121
+ if (auto PtrAuthData = getPtrAuthData ())
1122
+ return (unsigned )PtrAuthData->Payload .Data .ExtraDiscriminator ;
1123
+ else
1124
+ return std::nullopt;
1125
+ }
1126
+ // / \returns The PointerAuth IsaPointer bit.
1127
+ std::optional<bool > isPtrAuthIsaPointer () const {
1128
+ if (auto PtrAuthData = getPtrAuthData ())
1129
+ return (bool )PtrAuthData->Payload .Data .IsaPointer ;
1130
+ else
1131
+ return std::nullopt;
1132
+ }
1133
+ // / \returns The PointerAuth authenticates null values bit.
1134
+ std::optional<bool > getPtrAuthAuthenticatesNullValues () const {
1135
+ if (auto PtrAuthData = getPtrAuthData ())
1136
+ return (bool )PtrAuthData->Payload .Data .AuthenticatesNullValues ;
1137
+ else
1138
+ return std::nullopt;
1139
+ }
1140
+
1051
1141
// / Get extra data associated with this derived type.
1052
1142
// /
1053
1143
// / Class type for pointer-to-members, objective-c property node for ivars,
0 commit comments