[llvm] [BPF] Support wrapping BPF map structs into nested, single field structs (PR #144097)

Michal Rostecki via llvm-commits llvm-commits at lists.llvm.org
Sat Jun 14 08:32:27 PDT 2025


================
@@ -0,0 +1,609 @@
+; RUN: llc -mtriple=bpfel -filetype=asm -o - %s | FileCheck -check-prefixes=CHECK-SHORT %s
+; RUN: llc -mtriple=bpfel -filetype=asm -o - %s | FileCheck -check-prefixes=CHECK %s
+
+; Source code:
+;   #![no_std]
+;   #![no_main]
+;   #![allow(dead_code)]
+;
+;   pub const BPF_MAP_TYPE_HASH: usize = 1;
+;
+;   // The real map definition.
+;   pub struct HashMapDef<K, V, const M: usize, const F: usize> {
+;       r#type: *const [i32; BPF_MAP_TYPE_HASH],
+;       key: *const K,
+;       value: *const V,
+;       max_entries: *const [i32; M],
+;       map_flags: *const [i32; F],
+;   }
+;   impl<K, V, const M: usize, const F: usize> HashMapDef<K, V, M, F> {
+;       pub const fn new() -> Self {
+;           Self {
+;               r#type: &[0i32; BPF_MAP_TYPE_HASH],
+;               key: ::core::ptr::null(),
+;               value: ::core::ptr::null(),
+;               max_entries: &[0i32; M],
+;               map_flags: &[0i32; F],
+;           }
+;       }
+;   }
+;   // Use `UnsafeCell` to allow mutability by multiple threads.
+;   pub struct HashMap<K, V, const M: usize, const F: usize = 0>(
+;       core::cell::UnsafeCell<HashMapDef<K, V, M, F>>,
+;   );
+;   impl<K, V, const M: usize, const F: usize> HashMap<K, V, M, F> {
+;       pub const fn new() -> Self {
+;           Self(core::cell::UnsafeCell::new(HashMapDef::new()))
+;       }
+;   }
+;   // Mark `HashMap` as thread-safe.
+;   unsafe impl<K: Sync, V: Sync, const M: usize, const F: usize> Sync for HashMap<K, V, M, F> {}
+;
+;   // Define custom structs for key and values.
+;   pub struct MyKey(u32);
+;   pub struct MyValue(u32);
+;
+;   #[link_section = ".maps"]
+;   #[export_name = "HASH_MAP"]
+;   pub static HASH_MAP: HashMap<MyKey, MyValue, 10> = HashMap::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-ir
+
+; ModuleID = 'map_def.b515d5aaa59f5dac-cgu.0'
+source_filename = "map_def.b515d5aaa59f5dac-cgu.0"
+target datalayout = "e-m:e-p:64:64-i64:64-i128:128-n32:64-S128"
+target triple = "bpfel"
+
+ at alloc_83ea17bf0c4f4a5a5a13d3ae7955acd0 = private unnamed_addr constant [4 x i8] zeroinitializer, align 4
+ at alloc_e225df0b9c7f20aa5692610f2f2527d2 = private unnamed_addr constant [40 x i8] zeroinitializer, align 4
+ at HASH_MAP = local_unnamed_addr global <{ ptr, [16 x i8], ptr, ptr }> <{ ptr @alloc_83ea17bf0c4f4a5a5a13d3ae7955acd0, [16 x i8] zeroinitializer, ptr @alloc_e225df0b9c7f20aa5692610f2f2527d2, ptr inttoptr (i64 4 to ptr) }>, section ".maps", align 8, !dbg !0
+
+; __rustc::rust_begin_unwind
+; Function Attrs: nofree norecurse noreturn nosync nounwind memory(none)
+define hidden void @_RNvCsksSW6QfmhpE_7___rustc17rust_begin_unwind(ptr noalias nocapture noundef readonly align 8 dereferenceable(24) %_info) unnamed_addr #0 !dbg !56 {
+start:
+    #dbg_value(ptr %_info, !220, !DIExpression(), !221)
+  br label %bb1, !dbg !222
+
+bb1:                                              ; preds = %bb1, %start
+  br label %bb1, !dbg !222
+}
+
+attributes #0 = { nofree norecurse noreturn nosync nounwind memory(none) "target-cpu"="generic" }
+
+; The resulting BTF should look like:
+;   #0: <VOID>
+;   #1: <PTR> --> [3]
+;   #2: <INT> 'i32' bits:32 off:0 enc:signed
+;   #3: <ARRAY> n:1 idx-->[4] val-->[2]
+;   #4: <INT> '__ARRAY_SIZE_TYPE__' bits:32 off:0
+;   #5: <PTR> --> [6]
+;   #6: <STRUCT> 'MyKey' sz:4 n:1
+;           #00 '__0' off:0 --> [7]
+;   #7: <INT> 'u32' bits:32 off:0
+;   #8: <PTR> --> [9]
+;   #9: <STRUCT> 'MyValue' sz:4 n:1
+;           #00 '__0' off:0 --> [7]
+;   #10: <PTR> --> [11]
+;   #11: <ARRAY> n:10 idx-->[4] val-->[2]
+;   #12: <PTR> --> [13]
+;   #13: <ARRAY> n:0 idx-->[4] val-->[2]
+;   #14: <STRUCT> 'HashMapDef<map_def::MyKey, map_def::MyValue, 10, 0>' sz:40 n:5
+;           #00 'type' off:0 --> [1]
+;           #01 'key' off:64 --> [5]
+;           #02 'value' off:128 --> [8]
+;           #03 'max_entries' off:192 --> [10]
+;           #04 'map_flags' off:256 --> [12]
+;   #15: <STRUCT> 'UnsafeCell<map_def::HashMapDef<map_def::MyKey, map_def::MyValue, 10, 0>>' sz:40 n:1
+;           #00 'value' off:0 --> [14]
+;   #16: <STRUCT> 'HashMap<map_def::MyKey, map_def::MyValue, 10, 0>' sz:40 n:1
+;           #00 '__0' off:0 --> [15]
+;   #17: <VAR> 'HASH_MAP' kind:global-alloc --> [16]
+;   #18: <PTR> --> [19]
+;   #19: <STRUCT> 'PanicInfo' sz:24 n:4
+;           #00 'message' off:0 --> [20]
+;           #01 'location' off:64 --> [21]
+;           #02 'can_unwind' off:128 --> [22]
+;           #03 'force_no_backtrace' off:136 --> [22]
+;   #20: <PTR> --> [27]
+;   #21: <PTR> --> [28]
+;   #22: <INT> 'bool' bits:8 off:0 enc:bool
+;   #23: <FUNC_PROTO> r-->[0] n:1
+;           #00 '_info' --> [18]
+;   #24: <FUNC> 'panic' --> static [23]
+;   #25: <DATASEC> '.maps' sz:0 n:1
+;           #00 off:0 sz:40 --> [17]
+;   #26: <DATASEC> '.rodata' sz:0 n:0
+;   #27: <FWD> 'Arguments' kind:struct
+;   #28: <FWD> 'Location' kind:struct
+;
+; Before bug https://github.com/llvm/llvm-project/issues/143361 was fixed, the
+; BTF kind of MyKey (#6) and MyValue (#9) would be <FWD> instead of <STRUCT>.
+; The main goal of this test is making sure that the full <STRUCT> BTF is
+; generated for these types.
+
+; We expect exactly 6 structs:
+; * MyKey
+; * MyValue
+; * HashMapDef<map_def::MyKey, map_def::MyValue, 10, 0>
+; * UnsafeCell<map_def::HashMapDef<map_def::MyKey, map_def::MyValue, 10, 0>>
+; * HashMap<map_def::MyKey, map_def::MyValue, 10, 0>
+; * PanicInfo (comes from the Rust core library)
+;
+; CHECK-SHORT-COUNT-6:        BTF_KIND_STRUCT
+; CHECK-SHORT-NOT:            BTF_KIND_STRUCT
+
+; We expect exactly 2 forward declarations:
+; * Arguments
+; * Location
+; Both of them come from Rust core library. These types are not used in fields
+; of any structs actually used by the program, so skipping them is absolutely
+; fine.
+;
+; CHECK-SHORT-COUNT-2:        BTF_KIND_FWD
+; CHECK-SHORT-NOT:            BTF_KIND_FWD
+
+; Assert the whole BTF section.
+;
+; CHECK:             .section	.BTF,"", at progbits
+; CHECK-NEXT:        .short	60319                           # 0xeb9f
+; CHECK-NEXT:        .byte	1
+; CHECK-NEXT:        .byte	0
+; CHECK-NEXT:        .long	24
+; CHECK-NEXT:        .long	0
+; CHECK-NEXT:        .long	568
+; CHECK-NEXT:        .long	568
+; CHECK-NEXT:        .long	639
+; CHECK-NEXT:        .long	1                               # BTF_KIND_PTR(id = 1)
+; CHECK-NEXT:        .long	33554432                        # 0x2000000
+; CHECK-NEXT:        .long	3
+; CHECK-NEXT:        .long	17                              # BTF_KIND_INT(id = 2)
+; CHECK-NEXT:        .long	16777216                        # 0x1000000
+; CHECK-NEXT:        .long	4
+; CHECK-NEXT:        .long	16777248                        # 0x1000020
+; CHECK-NEXT:        .long	0                               # BTF_KIND_ARRAY(id = 3)
+; CHECK-NEXT:        .long	50331648                        # 0x3000000
+; CHECK-NEXT:        .long	0
+; CHECK-NEXT:        .long	2
+; CHECK-NEXT:        .long	4
+; CHECK-NEXT:        .long	1
+; CHECK-NEXT:        .long	21                              # BTF_KIND_INT(id = 4)
+; CHECK-NEXT:        .long	16777216                        # 0x1000000
+; CHECK-NEXT:        .long	4
+; CHECK-NEXT:        .long	32                              # 0x20
+; CHECK-NEXT:        .long	41                              # BTF_KIND_PTR(id = 5)
+; CHECK-NEXT:        .long	33554432                        # 0x2000000
+; CHECK-NEXT:        .long	6
+; CHECK-NEXT:        .long	63                              # BTF_KIND_STRUCT(id = 6)
+; CHECK-NEXT:        .long	67108865                        # 0x4000001
+; CHECK-NEXT:        .long	4
+; CHECK-NEXT:        .long	69
+; CHECK-NEXT:        .long	7
+; CHECK-NEXT:        .long	0                               # 0x0
+; CHECK-NEXT:        .long	73                              # BTF_KIND_INT(id = 7)
+; CHECK-NEXT:        .long	16777216                        # 0x1000000
+; CHECK-NEXT:        .long	4
+; CHECK-NEXT:        .long	32                              # 0x20
+; CHECK-NEXT:        .long	77                              # BTF_KIND_PTR(id = 8)
+; CHECK-NEXT:        .long	33554432                        # 0x2000000
+; CHECK-NEXT:        .long	9
+; CHECK-NEXT:        .long	101                             # BTF_KIND_STRUCT(id = 9)
+; CHECK-NEXT:        .long	67108865                        # 0x4000001
+; CHECK-NEXT:        .long	4
+; CHECK-NEXT:        .long	69
+; CHECK-NEXT:        .long	7
+; CHECK-NEXT:        .long	0                               # 0x0
+; CHECK-NEXT:        .long	109                             # BTF_KIND_PTR(id = 10)
+; CHECK-NEXT:        .long	33554432                        # 0x2000000
+; CHECK-NEXT:        .long	11
+; CHECK-NEXT:        .long	0                               # BTF_KIND_ARRAY(id = 11)
+; CHECK-NEXT:        .long	50331648                        # 0x3000000
+; CHECK-NEXT:        .long	0
+; CHECK-NEXT:        .long	2
+; CHECK-NEXT:        .long	4
+; CHECK-NEXT:        .long	10
+; CHECK-NEXT:        .long	126                             # BTF_KIND_PTR(id = 12)
+; CHECK-NEXT:        .long	33554432                        # 0x2000000
+; CHECK-NEXT:        .long	13
+; CHECK-NEXT:        .long	0                               # BTF_KIND_ARRAY(id = 13)
+; CHECK-NEXT:        .long	50331648                        # 0x3000000
+; CHECK-NEXT:        .long	0
+; CHECK-NEXT:        .long	2
+; CHECK-NEXT:        .long	4
+; CHECK-NEXT:        .long	0
+; CHECK-NEXT:        .long	142                             # BTF_KIND_STRUCT(id = 14)
+; CHECK-NEXT:        .long	67108869                        # 0x4000005
+; CHECK-NEXT:        .long	40
+; CHECK-NEXT:        .long	194
+; CHECK-NEXT:        .long	1
+; CHECK-NEXT:        .long	0                               # 0x0
+; CHECK-NEXT:        .long	199
+; CHECK-NEXT:        .long	5
+; CHECK-NEXT:        .long	64                              # 0x40
+; CHECK-NEXT:        .long	203
+; CHECK-NEXT:        .long	8
+; CHECK-NEXT:        .long	128                             # 0x80
+; CHECK-NEXT:        .long	209
+; CHECK-NEXT:        .long	10
+; CHECK-NEXT:        .long	192                             # 0xc0
+; CHECK-NEXT:        .long	221
+; CHECK-NEXT:        .long	12
+; CHECK-NEXT:        .long	256                             # 0x100
+; CHECK-NEXT:        .long	231                             # BTF_KIND_STRUCT(id = 15)
+; CHECK-NEXT:        .long	67108865                        # 0x4000001
+; CHECK-NEXT:        .long	40
+; CHECK-NEXT:        .long	203
+; CHECK-NEXT:        .long	14
+; CHECK-NEXT:        .long	0                               # 0x0
+; CHECK-NEXT:        .long	304                             # BTF_KIND_STRUCT(id = 16)
+; CHECK-NEXT:        .long	67108865                        # 0x4000001
+; CHECK-NEXT:        .long	40
+; CHECK-NEXT:        .long	69
+; CHECK-NEXT:        .long	15
+; CHECK-NEXT:        .long	0                               # 0x0
+; CHECK-NEXT:        .long	353                             # BTF_KIND_VAR(id = 17)
+; CHECK-NEXT:        .long	234881024                       # 0xe000000
+; CHECK-NEXT:        .long	16
+; CHECK-NEXT:        .long	1
+; CHECK-NEXT:        .long	362                             # BTF_KIND_PTR(id = 18)
+; CHECK-NEXT:        .long	33554432                        # 0x2000000
+; CHECK-NEXT:        .long	19
+; CHECK-NEXT:        .long	398                             # BTF_KIND_STRUCT(id = 19)
+; CHECK-NEXT:        .long	67108868                        # 0x4000004
+; CHECK-NEXT:        .long	24
+; CHECK-NEXT:        .long	408
+; CHECK-NEXT:        .long	20
+; CHECK-NEXT:        .long	0                               # 0x0
+; CHECK-NEXT:        .long	416
+; CHECK-NEXT:        .long	21
+; CHECK-NEXT:        .long	64                              # 0x40
+; CHECK-NEXT:        .long	425
+; CHECK-NEXT:        .long	22
+; CHECK-NEXT:        .long	128                             # 0x80
+; CHECK-NEXT:        .long	436
+; CHECK-NEXT:        .long	22
+; CHECK-NEXT:        .long	136                             # 0x88
+; CHECK-NEXT:        .long	455                             # BTF_KIND_PTR(id = 20)
+; CHECK-NEXT:        .long	33554432                        # 0x2000000
+; CHECK-NEXT:        .long	27
+; CHECK-NEXT:        .long	477                             # BTF_KIND_PTR(id = 21)
+; CHECK-NEXT:        .long	33554432                        # 0x2000000
+; CHECK-NEXT:        .long	28
+; CHECK-NEXT:        .long	510                             # BTF_KIND_INT(id = 22)
+; CHECK-NEXT:        .long	16777216                        # 0x1000000
+; CHECK-NEXT:        .long	1
+; CHECK-NEXT:        .long	67108872                        # 0x4000008
+; CHECK-NEXT:        .long	0                               # BTF_KIND_FUNC_PROTO(id = 23)
+; CHECK-NEXT:        .long	218103809                       # 0xd000001
+; CHECK-NEXT:        .long	0
+; CHECK-NEXT:        .long	515
+; CHECK-NEXT:        .long	18
+; CHECK-NEXT:        .long	521                             # BTF_KIND_FUNC(id = 24)
+; CHECK-NEXT:        .long	201326592                       # 0xc000000
+; CHECK-NEXT:        .long	23
+; CHECK-NEXT:        .long	606                             # BTF_KIND_DATASEC(id = 25)
+; CHECK-NEXT:        .long	251658241                       # 0xf000001
+; CHECK-NEXT:        .long	0
+; CHECK-NEXT:        .long	17
+; CHECK-NEXT:        .long	HASH_MAP
+; CHECK-NEXT:        .long	40
+; CHECK-NEXT:        .long	612                             # BTF_KIND_DATASEC(id = 26)
+; CHECK-NEXT:        .long	251658240                       # 0xf000000
+; CHECK-NEXT:        .long	0
+; CHECK-NEXT:        .long	620                             # BTF_KIND_FWD(id = 27)
+; CHECK-NEXT:        .long	117440512                       # 0x7000000
+; CHECK-NEXT:        .long	0
+; CHECK-NEXT:        .long	630                             # BTF_KIND_FWD(id = 28)
+; CHECK-NEXT:        .long	117440512                       # 0x7000000
+; CHECK-NEXT:        .long	0
+; CHECK-NEXT:        .byte	0                               # string offset=0
+; CHECK-NEXT:        .ascii	"*const [i32; 1]"               # string offset=1
+; CHECK-NEXT:        .byte	0
+; CHECK-NEXT:        .ascii	"i32"                           # string offset=17
+; CHECK-NEXT:        .byte	0
+; CHECK-NEXT:        .ascii	"__ARRAY_SIZE_TYPE__"           # string offset=21
+; CHECK-NEXT:        .byte	0
+; CHECK-NEXT:        .ascii	"*const map_def::MyKey"         # string offset=41
+; CHECK-NEXT:        .byte	0
+; CHECK-NEXT:        .ascii	"MyKey"                         # string offset=63
+; CHECK-NEXT:        .byte	0
+; CHECK-NEXT:        .ascii	"__0"                           # string offset=69
+; CHECK-NEXT:        .byte	0
+; CHECK-NEXT:        .ascii	"u32"                           # string offset=73
+; CHECK-NEXT:        .byte	0
+; CHECK-NEXT:        .ascii	"*const map_def::MyValue"       # string offset=77
+; CHECK-NEXT:        .byte	0
+; CHECK-NEXT:        .ascii	"MyValue"                       # string offset=101
+; CHECK-NEXT:        .byte	0
+; CHECK-NEXT:        .ascii	"*const [i32; 10]"              # string offset=109
+; CHECK-NEXT:        .byte	0
+; CHECK-NEXT:        .ascii	"*const [i32; 0]"               # string offset=126
+; CHECK-NEXT:        .byte	0
+; CHECK-NEXT:        .ascii	"HashMapDef<map_def::MyKey, map_def::MyValue, 10, 0>" # string offset=142
+; CHECK-NEXT:        .byte	0
+; CHECK-NEXT:        .ascii	"type"                          # string offset=194
+; CHECK-NEXT:        .byte	0
+; CHECK-NEXT:        .ascii	"key"                           # string offset=199
+; CHECK-NEXT:        .byte	0
+; CHECK-NEXT:        .ascii	"value"                         # string offset=203
+; CHECK-NEXT:        .byte	0
+; CHECK-NEXT:        .ascii	"max_entries"                   # string offset=209
+; CHECK-NEXT:        .byte	0
+; CHECK-NEXT:        .ascii	"map_flags"                     # string offset=221
+; CHECK-NEXT:        .byte	0
+; CHECK-NEXT:        .ascii	"UnsafeCell<map_def::HashMapDef<map_def::MyKey, map_def::MyValue, 10, 0>>" # string offset=231
+; CHECK-NEXT:        .byte	0
+; CHECK-NEXT:        .ascii	"HashMap<map_def::MyKey, map_def::MyValue, 10, 0>" # string offset=304
+; CHECK-NEXT:        .byte	0
+; CHECK-NEXT:        .ascii	"HASH_MAP"                      # string offset=353
+; CHECK-NEXT:        .byte	0
+; CHECK-NEXT:        .ascii	"&core::panic::panic_info::PanicInfo" # string offset=362
+; CHECK-NEXT:        .byte	0
+; CHECK-NEXT:        .ascii	"PanicInfo"                     # string offset=398
+; CHECK-NEXT:        .byte	0
+; CHECK-NEXT:        .ascii	"message"                       # string offset=408
+; CHECK-NEXT:        .byte	0
+; CHECK-NEXT:        .ascii	"location"                      # string offset=416
+; CHECK-NEXT:        .byte	0
+; CHECK-NEXT:        .ascii	"can_unwind"                    # string offset=425
+; CHECK-NEXT:        .byte	0
+; CHECK-NEXT:        .ascii	"force_no_backtrace"            # string offset=436
+; CHECK-NEXT:        .byte	0
+; CHECK-NEXT:        .ascii	"&core::fmt::Arguments"         # string offset=455
+; CHECK-NEXT:        .byte	0
+; CHECK-NEXT:        .ascii	"&core::panic::location::Location" # string offset=477
+; CHECK-NEXT:        .byte	0
+; CHECK-NEXT:        .ascii	"bool"                          # string offset=510
+; CHECK-NEXT:        .byte	0
+; CHECK-NEXT:        .ascii	"_info"                         # string offset=515
+; CHECK-NEXT:        .byte	0
+; CHECK-NEXT:        .ascii	"panic"                         # string offset=521
+; CHECK-NEXT:        .byte	0
+; CHECK-NEXT:        .ascii	".text"                         # string offset=527
+; CHECK-NEXT:        .byte	0
+; CHECK-NEXT:        .ascii	"/home/vadorovsky/playground/map-def/map-def-ebpf/src/main.rs" # string offset=533
----------------
vadorovsky wrote:

Good point. In the most of `.ll` test files I see that `/tmp` is used as directory. I sanitized it to `/tmp/map-def/src`.

https://github.com/llvm/llvm-project/pull/144097


More information about the llvm-commits mailing list