Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 18 additions & 1 deletion llvm/lib/Target/BPF/BTFDebug.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,24 @@ void BTFTypeDerived::completeType(BTFDebug &BDebug) {
return;
IsCompleted = true;

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

if (NeedsFixup || !DTy)
return;
Expand Down
59 changes: 59 additions & 0 deletions llvm/test/CodeGen/BPF/BTF/ptr-named-2.ll
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
; RUN: llc -mtriple=bpfel -filetype=obj -o %t1 %s
; RUN: llvm-objcopy --dump-section='.BTF'=%t2 %t1
; RUN: %python %p/print_btf.py %t2 | FileCheck -check-prefixes=CHECK-BTF %s
; RUN: llc -mtriple=bpfeb -filetype=obj -o %t1 %s
; RUN: llvm-objcopy --dump-section='.BTF'=%t2 %t1
; RUN: %python %p/print_btf.py %t2 | FileCheck -check-prefixes=CHECK-BTF %s
;
; This IR is hand-written.

; ModuleID = 'ptr-named-2.ll'
source_filename = "ptr-named-2.ll"
target datalayout = "e-m:e-p:64:64-i64:64-i128:128-n32:64-S128"
target triple = "bpfel-unknown-none"

%struct.TypeExamples = type { i32*, i32, i32, i32* }

@type_examples = internal global %struct.TypeExamples zeroinitializer, align 8, !dbg !0

!llvm.dbg.cu = !{!1}
!llvm.module.flags = !{!2, !3, !4}
!llvm.ident = !{!21}

; CHECK-BTF: [1] STRUCT 'TypeExamples' size=32 vlen=4
; CHECK-BTF-NEXT: 'ptr' type_id=2 bits_offset=0
; CHECK-BTF-NEXT: 'volatile' type_id=4 bits_offset=64
; CHECK-BTF-NEXT: 'const' type_id=5 bits_offset=128
; CHECK-BTF-NEXT: 'restrict_ptr' type_id=6 bits_offset=192
; CHECK-BTF-NEXT: [2] PTR '(anon)' type_id=3
; CHECK-BTF-NEXT: [3] INT 'int' size=4 bits_offset=0 nr_bits=32 encoding=SIGNED
; CHECK-BTF-NEXT: [4] VOLATILE '(anon)' type_id=3
; CHECK-BTF-NEXT: [5] CONST '(anon)' type_id=3
; CHECK-BTF-NEXT: [6] RESTRICT '(anon)' type_id=7
; CHECK-BTF-NEXT: [7] PTR '(anon)' type_id=3
; CHECK-BTF-NEXT: [8] VAR 'type_examples' type_id=1, linkage=static
; CHECK-BTF-NEXT: [9] DATASEC '.bss' size=0 vlen=1
; CHECK-BTF-NEXT: type_id=8 offset=0 size=24

!0 = !DIGlobalVariableExpression(var: !5, expr: !DIExpression())
!1 = distinct !DICompileUnit(language: DW_LANG_C99, file: !6, isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, enums: !7, globals: !8, splitDebugInlining: false, nameTableKind: None)
!2 = !{i32 2, !"Dwarf Version", i32 4}
!3 = !{i32 2, !"Debug Info Version", i32 3}
!4 = !{i32 1, !"wchar_size", i32 4}
!5 = distinct !DIGlobalVariable(name: "type_examples", scope: !1, file: !6, line: 12, type: !9, isLocal: true, isDefinition: true)
!6 = !DIFile(filename: "ptr-named-2.ll", directory: "/tmp")
!7 = !{}
!8 = !{!0}
!9 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "TypeExamples", file: !6, line: 5, size: 256, elements: !10)
!10 = !{!11, !12, !13, !14}
!11 = !DIDerivedType(tag: DW_TAG_member, name: "ptr", scope: !9, file: !6, line: 6, baseType: !15, size: 64)
!12 = !DIDerivedType(tag: DW_TAG_member, name: "volatile", scope: !9, file: !6, line: 7, baseType: !17, size: 64, offset: 64)
!13 = !DIDerivedType(tag: DW_TAG_member, name: "const", scope: !9, file: !6, line: 8, baseType: !18, size: 64, offset: 128)
!14 = !DIDerivedType(tag: DW_TAG_member, name: "restrict_ptr", scope: !9, file: !6, line: 9, baseType: !19, size: 64, offset: 192)
!15 = !DIDerivedType(tag: DW_TAG_pointer_type, name: "*int", baseType: !16, size: 64)
!16 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed)
!17 = !DIDerivedType(tag: DW_TAG_volatile_type, name: "volatile int", baseType: !16)
!18 = !DIDerivedType(tag: DW_TAG_const_type, name: "const int", baseType: !16)
!19 = !DIDerivedType(tag: DW_TAG_restrict_type, name: "*int restrict", baseType: !20)
!20 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !16, size: 64)
!21 = !{!"my hand-written IR"}
75 changes: 75 additions & 0 deletions llvm/test/CodeGen/BPF/BTF/ptr-named.ll
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
; RUN: llc -mtriple=bpfel -filetype=obj -o %t1 %s
; RUN: llvm-objcopy --dump-section='.BTF'=%t2 %t1
; RUN: %python %p/print_btf.py %t2 | FileCheck -check-prefixes=CHECK-BTF %s
; RUN: llc -mtriple=bpfeb -filetype=obj -o %t1 %s
; RUN: llvm-objcopy --dump-section='.BTF'=%t2 %t1
; RUN: %python %p/print_btf.py %t2 | FileCheck -check-prefixes=CHECK-BTF %s
;
; Source:
; #![no_std]
; #![no_main]
;
; pub struct MyType {
; ptr: *const u32,
; }
;
; impl MyType {
; pub const fn new() -> Self {
; let ptr = core::ptr::null();
; Self { ptr }
; }
; }
;
; unsafe impl Sync for MyType {}
;
; #[unsafe(no_mangle)]
; pub static X: MyType = MyType::new();
;
; #[cfg(not(test))]
; #[panic_handler]
; fn panic(_info: &core::panic::PanicInfo) -> ! {
; loop {}
; }
; Compilation flag:
; cargo +nightly rustc -Zbuild-std=core --target=bpfel-unknown-none -- --emit=llvm-bc
; llvm-extract --glob=X $(find target/ -name "*.bc" | head -n 1) -o ptr-named.bc
; llvm-dis ptr-named.bc -o ptr-named.ll

; ModuleID = 'ptr-named.bc'
source_filename = "1m2uqe50qkwxmo53ydydvou91"
target datalayout = "e-m:e-p:64:64-i64:64-i128:128-n32:64-S128"
target triple = "bpfel"

@X = constant [8 x i8] zeroinitializer, align 8, !dbg !0

!llvm.module.flags = !{!11, !12, !13, !14}
!llvm.ident = !{!15}
!llvm.dbg.cu = !{!16}

; CHECK-BTF: [1] STRUCT 'MyType' size=8 vlen=1
; CHECK-BTF-NEXT: 'ptr' type_id=2 bits_offset=0
; CHECK-BTF-NEXT: [2] PTR '(anon)' type_id=3
; CHECK-BTF-NEXT: [3] INT 'u32' size=4 bits_offset=0 nr_bits=32 encoding=(none)
; CHECK-BTF-NEXT: [4] VAR 'X' type_id=1, linkage=global
; CHECK-BTF-NEXT: [5] DATASEC '.rodata' size=0 vlen=1
; CHECK-BTF-NEXT: type_id=4 offset=0 size=8

!0 = !DIGlobalVariableExpression(var: !1, expr: !DIExpression())
!1 = distinct !DIGlobalVariable(name: "X", scope: !2, file: !3, line: 19, type: !4, isLocal: false, isDefinition: true, align: 64)
!2 = !DINamespace(name: "ptr_named", scope: null)
!3 = !DIFile(filename: "ptr-named/src/main.rs", directory: "/tmp/ptr-named", checksumkind: CSK_MD5, checksum: "e37168304600b30cbb5ba168f0384932")
!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")
!5 = !DIFile(filename: "<unknown>", directory: "")
!6 = !{!7}
!7 = !DIDerivedType(tag: DW_TAG_member, name: "ptr", scope: !4, file: !5, baseType: !8, size: 64, align: 64, flags: DIFlagPrivate)
!8 = !DIDerivedType(tag: DW_TAG_pointer_type, name: "*const u32", baseType: !9, size: 64, align: 64, dwarfAddressSpace: 0)
!9 = !DIBasicType(name: "u32", size: 32, encoding: DW_ATE_unsigned)
!10 = !{}
!11 = !{i32 8, !"PIC Level", i32 2}
!12 = !{i32 7, !"PIE Level", i32 2}
!13 = !{i32 7, !"Dwarf Version", i32 4}
!14 = !{i32 2, !"Debug Info Version", i32 3}
!15 = !{!"rustc version 1.92.0-nightly (c8905eaa6 2025-09-28)"}
!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)
!17 = !DIFile(filename: "ptr-named/src/main.rs/@/1m2uqe50qkwxmo53ydydvou91", directory: "/tmp/ptr-named")
!18 = !{!0}