Skip to content

Commit c346c16

Browse files
vadorovskyc-rhodes
authored andcommitted
[BPF] Do not emit names for PTR, CONST, VOLATILE and RESTRICT BTF types (#163174)
We currently raise a warning in `print_btf.py` when any of these types have a name. Linux kernel doesn't allow names in these types either.[0] However, there is nothing stopping frontends from giving names to these types. To make sure that they are always anonymous, explicitly skip the name emission. [0] https://elixir.bootlin.com/linux/v6.17.1/source/kernel/bpf/btf.c#L2586
1 parent 11ef752 commit c346c16

File tree

3 files changed

+152
-1
lines changed

3 files changed

+152
-1
lines changed

llvm/lib/Target/BPF/BTFDebug.cpp

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,24 @@ void BTFTypeDerived::completeType(BTFDebug &BDebug) {
9595
return;
9696
IsCompleted = true;
9797

98-
BTFType.NameOff = BDebug.addString(Name);
98+
switch (Kind) {
99+
case BTF::BTF_KIND_PTR:
100+
case BTF::BTF_KIND_CONST:
101+
case BTF::BTF_KIND_VOLATILE:
102+
case BTF::BTF_KIND_RESTRICT:
103+
// Debug info might contain names for these types, but given that we want
104+
// to keep BTF minimal and naming reference types doesn't bring any value
105+
// (what matters is the completeness of the base type), we don't emit them.
106+
//
107+
// Furthermore, the Linux kernel refuses to load BPF programs that contain
108+
// BTF with these types named:
109+
// https://elixir.bootlin.com/linux/v6.17.1/source/kernel/bpf/btf.c#L2586
110+
BTFType.NameOff = 0;
111+
break;
112+
default:
113+
BTFType.NameOff = BDebug.addString(Name);
114+
break;
115+
}
99116

100117
if (NeedsFixup || !DTy)
101118
return;
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
; RUN: llc -mtriple=bpfel -filetype=obj -o %t1 %s
2+
; RUN: llvm-objcopy --dump-section='.BTF'=%t2 %t1
3+
; RUN: %python %p/print_btf.py %t2 | FileCheck -check-prefixes=CHECK-BTF %s
4+
; RUN: llc -mtriple=bpfeb -filetype=obj -o %t1 %s
5+
; RUN: llvm-objcopy --dump-section='.BTF'=%t2 %t1
6+
; RUN: %python %p/print_btf.py %t2 | FileCheck -check-prefixes=CHECK-BTF %s
7+
;
8+
; This IR is hand-written.
9+
10+
; ModuleID = 'ptr-named-2.ll'
11+
source_filename = "ptr-named-2.ll"
12+
target datalayout = "e-m:e-p:64:64-i64:64-i128:128-n32:64-S128"
13+
target triple = "bpfel-unknown-none"
14+
15+
%struct.TypeExamples = type { i32*, i32, i32, i32* }
16+
17+
@type_examples = internal global %struct.TypeExamples zeroinitializer, align 8, !dbg !0
18+
19+
!llvm.dbg.cu = !{!1}
20+
!llvm.module.flags = !{!2, !3, !4}
21+
!llvm.ident = !{!21}
22+
23+
; CHECK-BTF: [1] STRUCT 'TypeExamples' size=32 vlen=4
24+
; CHECK-BTF-NEXT: 'ptr' type_id=2 bits_offset=0
25+
; CHECK-BTF-NEXT: 'volatile' type_id=4 bits_offset=64
26+
; CHECK-BTF-NEXT: 'const' type_id=5 bits_offset=128
27+
; CHECK-BTF-NEXT: 'restrict_ptr' type_id=6 bits_offset=192
28+
; CHECK-BTF-NEXT: [2] PTR '(anon)' type_id=3
29+
; CHECK-BTF-NEXT: [3] INT 'int' size=4 bits_offset=0 nr_bits=32 encoding=SIGNED
30+
; CHECK-BTF-NEXT: [4] VOLATILE '(anon)' type_id=3
31+
; CHECK-BTF-NEXT: [5] CONST '(anon)' type_id=3
32+
; CHECK-BTF-NEXT: [6] RESTRICT '(anon)' type_id=7
33+
; CHECK-BTF-NEXT: [7] PTR '(anon)' type_id=3
34+
; CHECK-BTF-NEXT: [8] VAR 'type_examples' type_id=1, linkage=static
35+
; CHECK-BTF-NEXT: [9] DATASEC '.bss' size=0 vlen=1
36+
; CHECK-BTF-NEXT: type_id=8 offset=0 size=24
37+
38+
!0 = !DIGlobalVariableExpression(var: !5, expr: !DIExpression())
39+
!1 = distinct !DICompileUnit(language: DW_LANG_C99, file: !6, isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, enums: !7, globals: !8, splitDebugInlining: false, nameTableKind: None)
40+
!2 = !{i32 2, !"Dwarf Version", i32 4}
41+
!3 = !{i32 2, !"Debug Info Version", i32 3}
42+
!4 = !{i32 1, !"wchar_size", i32 4}
43+
!5 = distinct !DIGlobalVariable(name: "type_examples", scope: !1, file: !6, line: 12, type: !9, isLocal: true, isDefinition: true)
44+
!6 = !DIFile(filename: "ptr-named-2.ll", directory: "/tmp")
45+
!7 = !{}
46+
!8 = !{!0}
47+
!9 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "TypeExamples", file: !6, line: 5, size: 256, elements: !10)
48+
!10 = !{!11, !12, !13, !14}
49+
!11 = !DIDerivedType(tag: DW_TAG_member, name: "ptr", scope: !9, file: !6, line: 6, baseType: !15, size: 64)
50+
!12 = !DIDerivedType(tag: DW_TAG_member, name: "volatile", scope: !9, file: !6, line: 7, baseType: !17, size: 64, offset: 64)
51+
!13 = !DIDerivedType(tag: DW_TAG_member, name: "const", scope: !9, file: !6, line: 8, baseType: !18, size: 64, offset: 128)
52+
!14 = !DIDerivedType(tag: DW_TAG_member, name: "restrict_ptr", scope: !9, file: !6, line: 9, baseType: !19, size: 64, offset: 192)
53+
!15 = !DIDerivedType(tag: DW_TAG_pointer_type, name: "*int", baseType: !16, size: 64)
54+
!16 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed)
55+
!17 = !DIDerivedType(tag: DW_TAG_volatile_type, name: "volatile int", baseType: !16)
56+
!18 = !DIDerivedType(tag: DW_TAG_const_type, name: "const int", baseType: !16)
57+
!19 = !DIDerivedType(tag: DW_TAG_restrict_type, name: "*int restrict", baseType: !20)
58+
!20 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !16, size: 64)
59+
!21 = !{!"my hand-written IR"}
Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
; RUN: llc -mtriple=bpfel -filetype=obj -o %t1 %s
2+
; RUN: llvm-objcopy --dump-section='.BTF'=%t2 %t1
3+
; RUN: %python %p/print_btf.py %t2 | FileCheck -check-prefixes=CHECK-BTF %s
4+
; RUN: llc -mtriple=bpfeb -filetype=obj -o %t1 %s
5+
; RUN: llvm-objcopy --dump-section='.BTF'=%t2 %t1
6+
; RUN: %python %p/print_btf.py %t2 | FileCheck -check-prefixes=CHECK-BTF %s
7+
;
8+
; Source:
9+
; #![no_std]
10+
; #![no_main]
11+
;
12+
; pub struct MyType {
13+
; ptr: *const u32,
14+
; }
15+
;
16+
; impl MyType {
17+
; pub const fn new() -> Self {
18+
; let ptr = core::ptr::null();
19+
; Self { ptr }
20+
; }
21+
; }
22+
;
23+
; unsafe impl Sync for MyType {}
24+
;
25+
; #[unsafe(no_mangle)]
26+
; pub static X: MyType = MyType::new();
27+
;
28+
; #[cfg(not(test))]
29+
; #[panic_handler]
30+
; fn panic(_info: &core::panic::PanicInfo) -> ! {
31+
; loop {}
32+
; }
33+
; Compilation flag:
34+
; cargo +nightly rustc -Zbuild-std=core --target=bpfel-unknown-none -- --emit=llvm-bc
35+
; llvm-extract --glob=X $(find target/ -name "*.bc" | head -n 1) -o ptr-named.bc
36+
; llvm-dis ptr-named.bc -o ptr-named.ll
37+
38+
; ModuleID = 'ptr-named.bc'
39+
source_filename = "1m2uqe50qkwxmo53ydydvou91"
40+
target datalayout = "e-m:e-p:64:64-i64:64-i128:128-n32:64-S128"
41+
target triple = "bpfel"
42+
43+
@X = constant [8 x i8] zeroinitializer, align 8, !dbg !0
44+
45+
!llvm.module.flags = !{!11, !12, !13, !14}
46+
!llvm.ident = !{!15}
47+
!llvm.dbg.cu = !{!16}
48+
49+
; CHECK-BTF: [1] STRUCT 'MyType' size=8 vlen=1
50+
; CHECK-BTF-NEXT: 'ptr' type_id=2 bits_offset=0
51+
; CHECK-BTF-NEXT: [2] PTR '(anon)' type_id=3
52+
; CHECK-BTF-NEXT: [3] INT 'u32' size=4 bits_offset=0 nr_bits=32 encoding=(none)
53+
; CHECK-BTF-NEXT: [4] VAR 'X' type_id=1, linkage=global
54+
; CHECK-BTF-NEXT: [5] DATASEC '.rodata' size=0 vlen=1
55+
; CHECK-BTF-NEXT: type_id=4 offset=0 size=8
56+
57+
!0 = !DIGlobalVariableExpression(var: !1, expr: !DIExpression())
58+
!1 = distinct !DIGlobalVariable(name: "X", scope: !2, file: !3, line: 19, type: !4, isLocal: false, isDefinition: true, align: 64)
59+
!2 = !DINamespace(name: "ptr_named", scope: null)
60+
!3 = !DIFile(filename: "ptr-named/src/main.rs", directory: "/tmp/ptr-named", checksumkind: CSK_MD5, checksum: "e37168304600b30cbb5ba168f0384932")
61+
!4 = !DICompositeType(tag: DW_TAG_structure_type, name: "MyType", scope: !2, file: !5, size: 64, align: 64, flags: DIFlagPublic, elements: !6, templateParams: !10, identifier: "7609fa40332dd486922f074276a171c3")
62+
!5 = !DIFile(filename: "<unknown>", directory: "")
63+
!6 = !{!7}
64+
!7 = !DIDerivedType(tag: DW_TAG_member, name: "ptr", scope: !4, file: !5, baseType: !8, size: 64, align: 64, flags: DIFlagPrivate)
65+
!8 = !DIDerivedType(tag: DW_TAG_pointer_type, name: "*const u32", baseType: !9, size: 64, align: 64, dwarfAddressSpace: 0)
66+
!9 = !DIBasicType(name: "u32", size: 32, encoding: DW_ATE_unsigned)
67+
!10 = !{}
68+
!11 = !{i32 8, !"PIC Level", i32 2}
69+
!12 = !{i32 7, !"PIE Level", i32 2}
70+
!13 = !{i32 7, !"Dwarf Version", i32 4}
71+
!14 = !{i32 2, !"Debug Info Version", i32 3}
72+
!15 = !{!"rustc version 1.92.0-nightly (c8905eaa6 2025-09-28)"}
73+
!16 = distinct !DICompileUnit(language: DW_LANG_Rust, file: !17, producer: "clang LLVM (rustc version 1.92.0-nightly (c8905eaa6 2025-09-28))", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, globals: !18, splitDebugInlining: false, nameTableKind: None)
74+
!17 = !DIFile(filename: "ptr-named/src/main.rs/@/1m2uqe50qkwxmo53ydydvou91", directory: "/tmp/ptr-named")
75+
!18 = !{!0}

0 commit comments

Comments
 (0)