[llvm] [RFC][BPF] Relax BTF_TYPE_ID_REMOTE_RELOC for unnamed types (PR #182370)
via llvm-commits
llvm-commits at lists.llvm.org
Thu Feb 19 12:54:42 PST 2026
https://github.com/yonghong-song created https://github.com/llvm/llvm-project/pull/182370
Currently, BTF_TYPE_ID_REMOTE_RELOC requires a named type e.g. named struct or union types.
But in [1], there are some use cases where unnamed types, e.g., 'void *', 'void **', 'const char *', etc. All these will fail compilation with error:
```
Empty type name for BTF_TYPE_ID_REMOTE reloc
```
This patch tried to relax this condition to allow unnamed types.
Currently, the libbpf does not support unamed types. E.g., I have
```
SEC("lsm/sb_eat_lsm_opts")
int BPF_PROG(sb_eat_lsm_opts_1,char *options, void **mnt_opts)
{
char** ppt = bpf_core_cast(mnt_opts, char*);
bpf_printk("%p\t", *ppt);
return 0;
}
```
The libbpf has the following failure:
```
libbpf: sec 'lsm/sb_eat_lsm_opts': found 1 CO-RE relocations
libbpf: prog 'sb_eat_lsm_opts_1': relo #0: target candidate search failed for [35] ptr : -22
libbpf: prog 'sb_eat_lsm_opts_1': relo #0: failed to relocate: -EINVAL
```
This commit is marked as RFC as it has dependency on libbpf.
[1] https://lore.kernel.org/bpf/bb4bf5fe648ac71c969c6228ac6e72ea85cbc64b.camel@gmail.com/T/#m5a7abf799b75199f6678eddd9c1ea4e31563b4dc
>From 1857d90e950a76e24f19a370ddd0c1272a36dd27 Mon Sep 17 00:00:00 2001
From: Yonghong Song <yonghong.song at linux.dev>
Date: Thu, 19 Feb 2026 09:05:36 -0800
Subject: [PATCH] [RFC][BPF] Relax BTF_TYPE_ID_REMOTE_RELOC for unnamed types
Currently, BTF_TYPE_ID_REMOTE_RELOC requires a named type e.g.
named struct or union types.
But in [1], there are some use cases where unnamed types, e.g.,
'void *', 'void **', 'const char *', etc. All these will fail
compilation with error:
Empty type name for BTF_TYPE_ID_REMOTE reloc
This patch tried to relax this condition to allow unnamed types.
Currently, the libbpf does not support unamed types. E.g., I have
SEC("lsm/sb_eat_lsm_opts")
int BPF_PROG(sb_eat_lsm_opts_1,char *options, void **mnt_opts)
{
char** ppt = bpf_core_cast(mnt_opts, char*);
bpf_printk("%p\t", *ppt);
return 0;
}
The libbpf has the following failure:
libbpf: sec 'lsm/sb_eat_lsm_opts': found 1 CO-RE relocations
libbpf: prog 'sb_eat_lsm_opts_1': relo #0: target candidate search failed for [35] ptr : -22
libbpf: prog 'sb_eat_lsm_opts_1': relo #0: failed to relocate: -EINVAL
This commit is marked as RFC as it has dependency on libbpf.
[1] https://lore.kernel.org/bpf/bb4bf5fe648ac71c969c6228ac6e72ea85cbc64b.camel@gmail.com/T/#m5a7abf799b75199f6678eddd9c1ea4e31563b4dc
---
llvm/lib/Target/BPF/BPFPreserveDIType.cpp | 2 -
.../BPF/BTF/builtin-btf-type-id-remote.ll | 100 ++++++++++++++++++
2 files changed, 100 insertions(+), 2 deletions(-)
create mode 100644 llvm/test/CodeGen/BPF/BTF/builtin-btf-type-id-remote.ll
diff --git a/llvm/lib/Target/BPF/BPFPreserveDIType.cpp b/llvm/lib/Target/BPF/BPFPreserveDIType.cpp
index 6a11ea6bf99d9..514390ffcaa0c 100644
--- a/llvm/lib/Target/BPF/BPFPreserveDIType.cpp
+++ b/llvm/lib/Target/BPF/BPFPreserveDIType.cpp
@@ -95,8 +95,6 @@ static bool BPFPreserveDITypeImpl(Function &F) {
if (isa<DISubroutineType>(Ty))
report_fatal_error(
"SubroutineType not supported for BTF_TYPE_ID_REMOTE reloc");
- else
- report_fatal_error("Empty type name for BTF_TYPE_ID_REMOTE reloc");
}
}
MD = Ty;
diff --git a/llvm/test/CodeGen/BPF/BTF/builtin-btf-type-id-remote.ll b/llvm/test/CodeGen/BPF/BTF/builtin-btf-type-id-remote.ll
new file mode 100644
index 0000000000000..b8c1408472f57
--- /dev/null
+++ b/llvm/test/CodeGen/BPF/BTF/builtin-btf-type-id-remote.ll
@@ -0,0 +1,100 @@
+; RUN: opt -O2 -mtriple=bpf-pc-linux -S %s -o %t1
+; RUN: llc -mcpu=v3 -filetype=obj %t1 -o %t2
+; RUN: llvm-objcopy --dump-section='.BTF'=%t3 %t2
+; RUN: %python %p/print_btf.py %t3 | FileCheck -check-prefixes=CHECK-BTF %s
+; RUN: llvm-objdump --no-print-imm-hex -dr --no-show-raw-insn %t2 | FileCheck --check-prefix=CHECK-DUMP %s
+
+; Source code:
+; int prog1(void) {
+; return __builtin_btf_type_id(*((char *) 0), 1);
+; }
+; int prog2(void) {
+; return __builtin_btf_type_id(*((typeof(const char *) *) 0), 1);
+; }
+; int prog3(void) {
+; return __builtin_btf_type_id(*((typeof(void *) *) 0), 1);
+; }
+; Compilation flag:
+; clang -target bpf -O2 -g -S -emit-llvm -Xclang -disable-llvm-passes test.c
+
+define dso_local i32 @prog1() #0 !dbg !13 {
+ %1 = call i64 @llvm.bpf.btf.type.id(i32 0, i64 1), !dbg !17, !llvm.preserve.access.index !3
+ %2 = trunc i64 %1 to i32, !dbg !18
+ ret i32 %2, !dbg !19
+}
+
+declare i64 @llvm.bpf.btf.type.id(i32, i64) #1
+
+define dso_local i32 @prog2() #0 !dbg !20 {
+ %1 = call i64 @llvm.bpf.btf.type.id(i32 1, i64 1), !dbg !21, !llvm.preserve.access.index !22
+ %2 = trunc i64 %1 to i32, !dbg !24
+ ret i32 %2, !dbg !25
+}
+
+define dso_local i32 @prog3() #0 !dbg !26 {
+ %1 = call i64 @llvm.bpf.btf.type.id(i32 2, i64 1), !dbg !27, !llvm.preserve.access.index !28
+ %2 = trunc i64 %1 to i32, !dbg !29
+ ret i32 %2, !dbg !30
+}
+
+; CHECK-BTF: [1] FUNC_PROTO '(anon)' ret_type_id=2 vlen=0
+; CHECK-BTF-NEXT: [2] INT 'int' size=4 bits_offset=0 nr_bits=32 encoding=SIGNED
+; CHECK-BTF-NEXT: [3] FUNC 'prog1' type_id=1 linkage=global
+; CHECK-BTF-NEXT: [4] INT 'char' size=1 bits_offset=0 nr_bits=8 encoding=SIGNED
+; CHECK-BTF-NEXT: [5] FUNC_PROTO '(anon)' ret_type_id=2 vlen=0
+; CHECK-BTF-NEXT: [6] FUNC 'prog2' type_id=5 linkage=global
+; CHECK-BTF-NEXT: [7] PTR '(anon)' type_id=8
+; CHECK-BTF-NEXT: [8] CONST '(anon)' type_id=4
+; CHECK-BTF-NEXT: [9] FUNC_PROTO '(anon)' ret_type_id=2 vlen=0
+; CHECK-BTF-NEXT: [10] FUNC 'prog3' type_id=9 linkage=global
+; CHECK-BTF-NEXT: [11] PTR '(anon)' type_id=0
+
+; CHECK-DUMP: prog1
+; CHECK-DUMP-NEXT: 0: r0 = 4 ll
+; CHECK-DUMP-NEXT: 0000000000000000: CO-RE <target_type_id> [4] char
+; CHECK-DUMP: prog2
+; CHECK-DUMP-NEXT: 3: r0 = 7 ll
+; CHECK-DUMP-NEXT: 0000000000000018: CO-RE <target_type_id> [7] <anon 7>
+; CHECK-DUMP: prog3
+; CHECK-DUMP-NEXT: 6: r0 = 11 ll
+; CHECK-DUMP-NEXT: 0000000000000030: CO-RE <target_type_id> [11] <anon 11>
+
+attributes #0 = { nounwind "frame-pointer"="all" "no-trapping-math"="true" "stack-protector-buffer-size"="8" }
+attributes #1 = { nounwind memory(none) }
+
+!llvm.dbg.cu = !{!0}
+!llvm.module.flags = !{!4, !5, !6, !7}
+!llvm.ident = !{!8}
+!llvm.errno.tbaa = !{!9}
+
+!0 = distinct !DICompileUnit(language: DW_LANG_C11, file: !1, producer: "clang version 23.0.0git (https://github.com/llvm/llvm-project.git ec6a219fc3627eebdbfbb934230aa843a823aee0)", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, retainedTypes: !2, splitDebugInlining: false, nameTableKind: None)
+!1 = !DIFile(filename: "test.c", directory: "/tmp/home/yhs/tmp/tmp3", checksumkind: CSK_MD5, checksum: "fa68707a49f823b3013ef8dab0a0c59b")
+!2 = !{!3}
+!3 = !DIBasicType(name: "char", size: 8, encoding: DW_ATE_signed_char)
+!4 = !{i32 7, !"Dwarf Version", i32 5}
+!5 = !{i32 2, !"Debug Info Version", i32 3}
+!6 = !{i32 1, !"wchar_size", i32 4}
+!7 = !{i32 7, !"frame-pointer", i32 2}
+!8 = !{!"clang version 23.0.0git (https://github.com/llvm/llvm-project.git ec6a219fc3627eebdbfbb934230aa843a823aee0)"}
+!9 = !{!10, !10, i64 0}
+!10 = !{!"int", !11, i64 0}
+!11 = !{!"omnipotent char", !12, i64 0}
+!12 = !{!"Simple C/C++ TBAA"}
+!13 = distinct !DISubprogram(name: "prog1", scope: !1, file: !1, line: 1, type: !14, scopeLine: 1, flags: DIFlagPrototyped | DIFlagAllCallsDescribed, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !0, keyInstructions: true)
+!14 = !DISubroutineType(types: !15)
+!15 = !{!16}
+!16 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed)
+!17 = !DILocation(line: 2, column: 10, scope: !13, atomGroup: 1, atomRank: 3)
+!18 = !DILocation(line: 2, column: 10, scope: !13, atomGroup: 1, atomRank: 2)
+!19 = !DILocation(line: 2, column: 3, scope: !13, atomGroup: 1, atomRank: 1)
+!20 = distinct !DISubprogram(name: "prog2", scope: !1, file: !1, line: 4, type: !14, scopeLine: 4, flags: DIFlagPrototyped | DIFlagAllCallsDescribed, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !0, keyInstructions: true)
+!21 = !DILocation(line: 5, column: 10, scope: !20, atomGroup: 1, atomRank: 3)
+!22 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !23, size: 64)
+!23 = !DIDerivedType(tag: DW_TAG_const_type, baseType: !3)
+!24 = !DILocation(line: 5, column: 10, scope: !20, atomGroup: 1, atomRank: 2)
+!25 = !DILocation(line: 5, column: 3, scope: !20, atomGroup: 1, atomRank: 1)
+!26 = distinct !DISubprogram(name: "prog3", scope: !1, file: !1, line: 7, type: !14, scopeLine: 7, flags: DIFlagPrototyped | DIFlagAllCallsDescribed, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !0, keyInstructions: true)
+!27 = !DILocation(line: 8, column: 10, scope: !26, atomGroup: 1, atomRank: 3)
+!28 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: null, size: 64)
+!29 = !DILocation(line: 8, column: 10, scope: !26, atomGroup: 1, atomRank: 2)
+!30 = !DILocation(line: 8, column: 3, scope: !26, atomGroup: 1, atomRank: 1)
More information about the llvm-commits
mailing list