Skip to content

Commit

Permalink
BPF: change btf_type_tag BTF output format
Browse files Browse the repository at this point in the history
For the declaration like below:
  int __tag1 * __tag1 __tag2 *g
Commit 41860e6 ("BPF: Support btf_type_tag attribute")
implemented the following encoding:
  VAR(g) -> __tag1 --> __tag2 -> pointer -> __tag1 -> pointer -> int

Some further experiments with linux btf_type_tag support, esp.
with generating attributes in vmlinux.h, and also some internal
discussion showed the following format is more desirable:
  VAR(g) -> pointer -> __tag2 -> __tag1 -> pointer -> __tag1 -> int

The format makes it similar to other modifier like 'const', e.g.,
  const int *g
which has encoding VAR(g) -> PTR -> CONST -> int

Differential Revision: https://reviews.llvm.org/D113496
  • Loading branch information
yonghong-song committed Nov 9, 2021
1 parent 791baf3 commit 8d499bd
Show file tree
Hide file tree
Showing 3 changed files with 60 additions and 29 deletions.
61 changes: 44 additions & 17 deletions llvm/lib/Target/BPF/BTFDebug.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ void BTFTypeBase::emitType(MCStreamer &OS) {

BTFTypeDerived::BTFTypeDerived(const DIDerivedType *DTy, unsigned Tag,
bool NeedsFixup)
: DTy(DTy), NeedsFixup(NeedsFixup) {
: DTy(DTy), NeedsFixup(NeedsFixup), Name(DTy->getName()) {
switch (Tag) {
case dwarf::DW_TAG_pointer_type:
Kind = BTF::BTF_KIND_PTR;
Expand All @@ -66,14 +66,23 @@ BTFTypeDerived::BTFTypeDerived(const DIDerivedType *DTy, unsigned Tag,
BTFType.Info = Kind << 24;
}

/// Used by DW_TAG_pointer_type only.
BTFTypeDerived::BTFTypeDerived(unsigned NextTypeId, unsigned Tag,
StringRef Name)
: DTy(nullptr), NeedsFixup(false), Name(Name) {
Kind = BTF::BTF_KIND_PTR;
BTFType.Info = Kind << 24;
BTFType.Type = NextTypeId;
}

void BTFTypeDerived::completeType(BTFDebug &BDebug) {
if (IsCompleted)
return;
IsCompleted = true;

BTFType.NameOff = BDebug.addString(DTy->getName());
BTFType.NameOff = BDebug.addString(Name);

if (NeedsFixup)
if (NeedsFixup || !DTy)
return;

// The base type for PTR/CONST/VOLATILE could be void.
Expand Down Expand Up @@ -408,17 +417,31 @@ void BTFTypeDeclTag::emitType(MCStreamer &OS) {
OS.emitInt32(Info);
}

BTFTypeTypeTag::BTFTypeTypeTag(uint32_t BaseTypeId, StringRef Tag) : Tag(Tag) {
BTFTypeTypeTag::BTFTypeTypeTag(uint32_t NextTypeId, StringRef Tag)
: DTy(nullptr), Tag(Tag) {
Kind = BTF::BTF_KIND_TYPE_TAG;
BTFType.Info = Kind << 24;
BTFType.Type = NextTypeId;
}

BTFTypeTypeTag::BTFTypeTypeTag(const DIDerivedType *DTy, StringRef Tag)
: DTy(DTy), Tag(Tag) {
Kind = BTF::BTF_KIND_TYPE_TAG;
BTFType.Info = Kind << 24;
BTFType.Type = BaseTypeId;
}

void BTFTypeTypeTag::completeType(BTFDebug &BDebug) {
if (IsCompleted)
return;
IsCompleted = true;
BTFType.NameOff = BDebug.addString(Tag);
if (DTy) {
const DIType *ResolvedType = DTy->getBaseType();
if (!ResolvedType)
BTFType.Type = 0;
else
BTFType.Type = BDebug.getTypeId(ResolvedType);
}
}

uint32_t BTFStringTable::addString(StringRef S) {
Expand Down Expand Up @@ -675,6 +698,8 @@ void BTFDebug::visitDerivedType(const DIDerivedType *DTy, uint32_t &TypeId,
SmallVector<const MDString *, 4> MDStrs;
DINodeArray Annots = DTy->getAnnotations();
if (Annots) {
// For type with "int __tag1 __tag2 *p", the MDStrs will have
// content: [__tag1, __tag2].
for (const Metadata *Annotations : Annots->operands()) {
const MDNode *MD = cast<MDNode>(Annotations);
const MDString *Name = cast<MDString>(MD->getOperand(0));
Expand All @@ -685,20 +710,22 @@ void BTFDebug::visitDerivedType(const DIDerivedType *DTy, uint32_t &TypeId,
}

if (MDStrs.size() > 0) {
auto TypeEntry = std::make_unique<BTFTypeDerived>(DTy, Tag, false);
// With MDStrs [__tag1, __tag2], the output type chain looks like
// PTR -> __tag2 -> __tag1 -> BaseType
// In the below, we construct BTF types with the order of __tag1, __tag2
// and PTR.
auto TypeEntry =
std::make_unique<BTFTypeTypeTag>(DTy, MDStrs[0]->getString());
unsigned TmpTypeId = addType(std::move(TypeEntry));
for (unsigned I = MDStrs.size(); I > 0; I--) {
const MDString *Value = MDStrs[I - 1];
if (I != 1) {
auto TypeEntry =
std::make_unique<BTFTypeTypeTag>(TmpTypeId, Value->getString());
TmpTypeId = addType(std::move(TypeEntry));
} else {
auto TypeEntry =
std::make_unique<BTFTypeTypeTag>(TmpTypeId, Value->getString());
TypeId = addType(std::move(TypeEntry), DTy);
}
for (unsigned I = 1; I < MDStrs.size(); I++) {
const MDString *Value = MDStrs[I];
TypeEntry =
std::make_unique<BTFTypeTypeTag>(TmpTypeId, Value->getString());
TmpTypeId = addType(std::move(TypeEntry));
}
auto TypeDEntry =
std::make_unique<BTFTypeDerived>(TmpTypeId, Tag, DTy->getName());
TypeId = addType(std::move(TypeDEntry), DTy);
} else {
auto TypeEntry = std::make_unique<BTFTypeDerived>(DTy, Tag, false);
TypeId = addType(std::move(TypeEntry), DTy);
Expand Down
6 changes: 5 additions & 1 deletion llvm/lib/Target/BPF/BTFDebug.h
Original file line number Diff line number Diff line change
Expand Up @@ -64,9 +64,11 @@ class BTFTypeBase {
class BTFTypeDerived : public BTFTypeBase {
const DIDerivedType *DTy;
bool NeedsFixup;
StringRef Name;

public:
BTFTypeDerived(const DIDerivedType *Ty, unsigned Tag, bool NeedsFixup);
BTFTypeDerived(unsigned NextTypeId, unsigned Tag, StringRef Name);
void completeType(BTFDebug &BDebug) override;
void emitType(MCStreamer &OS) override;
void setPointeeType(uint32_t PointeeType);
Expand Down Expand Up @@ -217,10 +219,12 @@ class BTFTypeDeclTag : public BTFTypeBase {
};

class BTFTypeTypeTag : public BTFTypeBase {
const DIDerivedType *DTy;
StringRef Tag;

public:
BTFTypeTypeTag(uint32_t BaseTypeId, StringRef Tag);
BTFTypeTypeTag(uint32_t NextTypeId, StringRef Tag);
BTFTypeTypeTag(const DIDerivedType *DTy, StringRef Tag);
void completeType(BTFDebug &BDebug) override;
};

Expand Down
22 changes: 11 additions & 11 deletions llvm/test/CodeGen/BPF/BTF/type-tag-var.ll
Original file line number Diff line number Diff line change
Expand Up @@ -27,20 +27,20 @@
!10 = !{!9, !11}
!11 = !{!"btf_type_tag", !"tag2"}

; CHECK: .long 0 # BTF_KIND_PTR(id = 1)
; CHECK-NEXT: .long 33554432 # 0x2000000
; CHECK: .long 1 # BTF_KIND_TYPE_TAG(id = 1)
; CHECK-NEXT: .long 301989888 # 0x12000000
; CHECK-NEXT: .long 5
; CHECK-NEXT: .long 1 # BTF_KIND_TYPE_TAG(id = 2)
; CHECK-NEXT: .long 6 # BTF_KIND_TYPE_TAG(id = 2)
; CHECK-NEXT: .long 301989888 # 0x12000000
; CHECK-NEXT: .long 1
; CHECK-NEXT: .long 6 # BTF_KIND_TYPE_TAG(id = 3)
; CHECK-NEXT: .long 301989888 # 0x12000000
; CHECK-NEXT: .long 2
; CHECK-NEXT: .long 0 # BTF_KIND_PTR(id = 4)
; CHECK-NEXT: .long 0 # BTF_KIND_PTR(id = 3)
; CHECK-NEXT: .long 33554432 # 0x2000000
; CHECK-NEXT: .long 6
; CHECK-NEXT: .long 6 # BTF_KIND_TYPE_TAG(id = 5)
; CHECK-NEXT: .long 2
; CHECK-NEXT: .long 1 # BTF_KIND_TYPE_TAG(id = 4)
; CHECK-NEXT: .long 301989888 # 0x12000000
; CHECK-NEXT: .long 6
; CHECK-NEXT: .long 0 # BTF_KIND_PTR(id = 5)
; CHECK-NEXT: .long 33554432 # 0x2000000
; CHECK-NEXT: .long 4
; CHECK-NEXT: .long 11 # BTF_KIND_INT(id = 6)
; CHECK-NEXT: .long 16777216 # 0x1000000
Expand All @@ -51,8 +51,8 @@
; CHECK-NEXT: .long 3
; CHECK-NEXT: .long 1

; CHECK: .ascii "tag2" # string offset=1
; CHECK: .ascii "tag1" # string offset=6
; CHECK: .ascii "tag1" # string offset=1
; CHECK: .ascii "tag2" # string offset=6
; CHECK: .ascii "int" # string offset=11
; CHECK: .byte 103 # string offset=15

Expand Down

0 comments on commit 8d499bd

Please sign in to comment.