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

Tamir Duberstein via llvm-commits llvm-commits at lists.llvm.org
Fri Jun 13 09:28:45 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
----------------
tamird wrote:

various strings with paths from your machine have snuck in here. i'm not sure what the convention is for these tests, but in case it is to sanitize these, please do so.

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


More information about the llvm-commits mailing list