-
Notifications
You must be signed in to change notification settings - Fork 11k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[DebugInfo][BPF] Add 'btf:type_tag' annotation in DWARF
This commit is a follow-up for BPF mailing list discussion at [1]. It changes the way `__attribute__((btf_type_tag("...")))`s are represented in DWARF. Prior to this commit type tags could only be attached to pointers. Such attachments associated the tags with a pointee type. E.g. for the following C code: int __attribute__((btf_type_tag("tag1"))) *g; Generated DWARF looked as follows: 0x0000001e: DW_TAG_variable DW_AT_name ("g") DW_AT_type (0x00000029 "int *") 0x00000029: DW_TAG_pointer_type DW_AT_type (0x00000032 "int") 0x0000002e: DW_TAG_LLVM_annotation DW_AT_name ("btf_type_tag") DW_AT_const_value ("tag1") 0x00000032: DW_TAG_base_type DW_AT_name ("int") The goal of this commit is to allow attachment of type tags to the tagged types instead. E.g. for the same example DWARF should look as follows: 0x0000001e: DW_TAG_variable DW_AT_name ("g") DW_AT_type (0x00000029 "int *") 0x00000029: DW_TAG_pointer_type DW_AT_type (0x00000032 "int") 0x00000032: DW_TAG_base_type DW_AT_name ("int") 0x00000036: DW_TAG_LLVM_annotation DW_AT_name ("btf:type_tag") DW_AT_const_value ("tag1") A new tag name, `btf:type_tag`, is used so that DWARF consumers could distinguish between old and new attachment semantics. In order to preserve backwards compatibility both `btf_type_tag` and `btf:type_tag` are generated. `btf_type_tag` might be deprecated in the future. The commit includes the following changes: - Changes in debug info generation: - New method `DIBuilder::createAnnotationsPlaceholder()` is added, it creates a temporary `DIDerivedType` that plays as annotations placeholder while debug info metadata is being constructed; - New overload for `CGDebugInfo::CreateType` method is added: llvm::DIType *CGDebugInfo::CreateType(const BTFTagAttributedType *Ty, llvm::DIFile *Unit); This overload collects BTF type tags in `Ty`, creates annotations placeholder pointing to the base type of `Ty`, registers the placeholder in the `CGDebugInfo::AnnotationsPlaceholder` vector. - `CGDebugInfo::finalize()` is updated to do the following for each annotation placeholder: - clone underlying base type; - attach annotations the clone using `replaceAnnotations()` call; - replace all placeholder usages by a clone. Such scheme allows to deal with type cycles. - Changes in AST construction: - `ASTContext::getBTFTagAttributedType()` is updated to ensure that `BTFTagAttributedType` always wraps `QualType` w/o local constant/volatile/restricted qualifiers. This simplifies debug info generation. [1] https://lore.kernel.org/bpf/87r0w9jjoq.fsf@oracle.com/ Depends on D143966 Differential Revision: https://reviews.llvm.org/D143967
- Loading branch information
Showing
14 changed files
with
385 additions
and
92 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
// RUN: %clang_cc1 -triple %itanium_abi_triple -debug-info-kind=limited -S -emit-llvm -o - %s | FileCheck %s | ||
|
||
#define __tag1 __attribute__((btf_type_tag("tag1"))) | ||
|
||
struct st { | ||
struct st __tag1 *self; | ||
} g; | ||
|
||
// CHECK: distinct !DIGlobalVariable(name: "g", scope: ![[#]], file: ![[#]], line: [[#]], type: ![[L1:[0-9]+]], isLocal: false, isDefinition: true) | ||
// CHECK: ![[L1]] = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "st", file: ![[#]], line: [[#]], size: [[#]], elements: ![[L2:[0-9]+]]) | ||
// CHECK: ![[L2]] = !{![[L3:[0-9]+]]} | ||
// CHECK: ![[L3]] = !DIDerivedType(tag: DW_TAG_member, name: "self", scope: ![[L1]], file: ![[#]], line: [[#]], baseType: ![[L4:[0-9]+]], size: [[#]]) | ||
// CHECK: ![[L4]] = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: ![[L5:[0-9]+]], size: [[#]], annotations: ![[L6:[0-9]+]]) | ||
// CHECK: ![[L5]] = !DICompositeType(tag: DW_TAG_structure_type, name: "st", file: ![[#]], line: [[#]], size: [[#]], elements: ![[L2]], annotations: ![[L7:[0-9]+]]) | ||
// CHECK: ![[L7]] = !{![[L8:[0-9]+]]} | ||
// CHECK: ![[L8]] = !{!"btf:type_tag", !"tag1"} | ||
// CHECK: ![[L6]] = !{![[L9:[0-9]+]]} | ||
// CHECK: ![[L9]] = !{!"btf_type_tag", !"tag1"} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,43 @@ | ||
// RUN: %clang_cc1 \ | ||
// RUN: -triple %itanium_abi_triple -debug-info-kind=limited \ | ||
// RUN: -S -emit-llvm -o - %s | FileCheck %s | ||
|
||
// Check that BTF type tags are not attached to DW_TAG_const_type DIEs | ||
// in presence of "sugar" expressions that are transparent for | ||
// CGDebugInfo.cpp:UnwrapTypeForDebugInfo(), but are not transparent | ||
// for local qualifiers. | ||
// | ||
// For details see: | ||
// CGDebugInfo::CreateType(const BTFTagAttributedType, llvm::DIFile) | ||
|
||
#define __tag1 __attribute__((btf_type_tag("tag1"))) | ||
#define __tag2 __attribute__((btf_type_tag("tag2"))) | ||
#define __tag3 __attribute__((btf_type_tag("tag3"))) | ||
|
||
const int *foo; | ||
typeof(*foo) __tag1 bar; | ||
|
||
// CHECK: distinct !DIGlobalVariable(name: "bar", {{.*}}, type: ![[L01:[0-9]+]], {{.*}}) | ||
// CHECK: ![[L01]] = !DIDerivedType(tag: DW_TAG_const_type, baseType: ![[L02:[0-9]+]]) | ||
// CHECK: ![[L02]] = !DIBasicType(name: "int", {{.*}}, annotations: ![[L03:[0-9]+]]) | ||
// CHECK: ![[L03]] = !{![[L04:[0-9]+]]} | ||
// CHECK: ![[L04]] = !{!"btf:type_tag", !"tag1"} | ||
|
||
const int __tag2 *buz; | ||
|
||
// CHECK: distinct !DIGlobalVariable(name: "buz", {{.*}}, type: ![[L05:[0-9]+]], {{.*}}) | ||
// CHECK: ![[L05]] = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: ![[L06:[0-9]+]], {{.*}}, annotations: ![[L07:[0-9]+]]) | ||
// CHECK: ![[L06]] = !DIDerivedType(tag: DW_TAG_const_type, baseType: ![[L08:[0-9]+]]) | ||
// CHECK: ![[L08]] = !DIBasicType(name: "int", size: [[#]], {{.*}}, annotations: ![[L09:[0-9]+]]) | ||
// CHECK: ![[L09]] = !{![[L10:[0-9]+]]} | ||
// CHECK: ![[L10]] = !{!"btf:type_tag", !"tag2"} | ||
// CHECK: ![[L07]] = !{![[L11:[0-9]+]]} | ||
// CHECK: ![[L11]] = !{!"btf_type_tag", !"tag2"} | ||
|
||
typeof(*buz) __tag3 quux; | ||
|
||
// CHECK: distinct !DIGlobalVariable(name: "quux", {{.*}}, type: ![[L12:[0-9]+]], {{.*}}) | ||
// CHECK: ![[L12]] = !DIDerivedType(tag: DW_TAG_const_type, baseType: ![[L13:[0-9]+]]) | ||
// CHECK: ![[L13]] = !DIBasicType(name: "int", {{.*}}, annotations: ![[L14:[0-9]+]]) | ||
// CHECK: ![[L14]] = !{![[L15:[0-9]+]], ![[L10]]} | ||
// CHECK: ![[L15]] = !{!"btf:type_tag", !"tag3"} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
// RUN: %clang_cc1 \ | ||
// RUN: -triple %itanium_abi_triple -debug-info-kind=limited \ | ||
// RUN: -S -emit-llvm -o - %s | FileCheck %s | ||
|
||
// See attr-btf_type_tag-const.c for reasoning behind this test. | ||
// Alternatively, see the following method: | ||
// CGDebugInfo::CreateType(const BTFTagAttributedType, llvm::DIFile) | ||
|
||
#define __tag1 __attribute__((btf_type_tag("tag1"))) | ||
|
||
void foo(int * restrict bar, typeof(bar) __tag1 buz) {} | ||
|
||
// CHECK: ![[#]] = !DISubroutineType(types: ![[L1:[0-9]+]]) | ||
// CHECK: ![[L1]] = !{null, ![[L2:[0-9]+]], ![[L3:[0-9]+]]} | ||
// CHECK: ![[L2]] = !DIDerivedType(tag: DW_TAG_restrict_type, baseType: ![[L4:[0-9]+]]) | ||
// CHECK: ![[L4]] = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: ![[L5:[0-9]+]], {{.*}}) | ||
// CHECK: ![[L5]] = !DIBasicType(name: "int", {{.*}}, encoding: DW_ATE_signed) | ||
// CHECK: ![[L3]] = !DIDerivedType(tag: DW_TAG_restrict_type, baseType: ![[L6:[0-9]+]]) | ||
// CHECK: ![[L6]] = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: ![[L5]], {{.*}}, annotations: ![[L7:[0-9]+]]) | ||
// CHECK: ![[L7]] = !{![[L8:[0-9]+]]} | ||
// CHECK: ![[L8]] = !{!"btf:type_tag", !"tag1"} |
Oops, something went wrong.