diff --git a/llvm/lib/Target/BPF/BTFDebug.cpp b/llvm/lib/Target/BPF/BTFDebug.cpp index a652b7e9c537f..7718e36f1dc18 100644 --- a/llvm/lib/Target/BPF/BTFDebug.cpp +++ b/llvm/lib/Target/BPF/BTFDebug.cpp @@ -306,8 +306,8 @@ void BTFTypeArray::emitType(MCStreamer &OS) { /// Represent either a struct or a union. BTFTypeStruct::BTFTypeStruct(const DICompositeType *STy, bool IsStruct, - bool HasBitField, uint32_t Vlen) - : STy(STy), HasBitField(HasBitField) { + bool HasBitField, uint32_t Vlen, bool StripName) + : STy(STy), HasBitField(HasBitField), StripName(StripName) { Kind = IsStruct ? BTF::BTF_KIND_STRUCT : BTF::BTF_KIND_UNION; BTFType.Size = roundupToBytes(STy->getSizeInBits()); BTFType.Info = (HasBitField << 31) | (Kind << 24) | Vlen; @@ -318,7 +318,10 @@ void BTFTypeStruct::completeType(BTFDebug &BDebug) { return; IsCompleted = true; - BTFType.NameOff = BDebug.addString(STy->getName()); + if (StripName) + BTFType.NameOff = 0; + else + BTFType.NameOff = BDebug.addString(STy->getName()); if (STy->getTag() == dwarf::DW_TAG_variant_part) { // Variant parts might have a discriminator, which has its own memory @@ -726,7 +729,7 @@ int BTFDebug::genBTFTypeTags(const DIDerivedType *DTy, int BaseTypeId) { /// Handle structure/union types. void BTFDebug::visitStructType(const DICompositeType *CTy, bool IsStruct, - uint32_t &TypeId) { + uint32_t &TypeId, bool StripName) { const DINodeArray Elements = CTy->getElements(); uint32_t VLen = Elements.size(); // Variant parts might have a discriminator. LLVM DI doesn't consider it as @@ -755,7 +758,8 @@ void BTFDebug::visitStructType(const DICompositeType *CTy, bool IsStruct, } auto TypeEntry = - std::make_unique(CTy, IsStruct, HasBitField, VLen); + std::make_unique(CTy, IsStruct, HasBitField, VLen, + StripName); StructTypes.push_back(TypeEntry.get()); TypeId = addType(std::move(TypeEntry), CTy); @@ -789,7 +793,7 @@ void BTFDebug::visitArrayType(const DICompositeType *CTy, uint32_t &TypeId) { // Visit array element type. uint32_t ElemTypeId; const DIType *ElemType = CTy->getBaseType(); - visitTypeEntry(ElemType, ElemTypeId, false, false); + visitTypeEntry(ElemType, ElemTypeId, false, false, false); // Visit array dimensions. DINodeArray Elements = CTy->getElements(); @@ -861,7 +865,7 @@ void BTFDebug::visitFwdDeclType(const DICompositeType *CTy, bool IsUnion, /// Handle structure, union, array and enumeration types. void BTFDebug::visitCompositeType(const DICompositeType *CTy, - uint32_t &TypeId) { + uint32_t &TypeId, bool StripName) { auto Tag = CTy->getTag(); switch (Tag) { case dwarf::DW_TAG_structure_type: @@ -871,7 +875,7 @@ void BTFDebug::visitCompositeType(const DICompositeType *CTy, if (CTy->isForwardDecl()) visitFwdDeclType(CTy, Tag == dwarf::DW_TAG_union_type, TypeId); else - visitStructType(CTy, Tag == dwarf::DW_TAG_structure_type, TypeId); + visitStructType(CTy, Tag == dwarf::DW_TAG_structure_type, TypeId, StripName); break; case dwarf::DW_TAG_array_type: visitArrayType(CTy, TypeId); @@ -902,7 +906,7 @@ void BTFDebug::visitDerivedType(const DIDerivedType *DTy, uint32_t &TypeId, if (Tag == dwarf::DW_TAG_atomic_type) return visitTypeEntry(DTy->getBaseType(), TypeId, CheckPointer, - SeenPointer); + SeenPointer, false); /// Try to avoid chasing pointees, esp. structure pointees which may /// unnecessary bring in a lot of types. @@ -951,9 +955,10 @@ void BTFDebug::visitDerivedType(const DIDerivedType *DTy, uint32_t &TypeId, // struct/union member. uint32_t TempTypeId = 0; if (Tag == dwarf::DW_TAG_member) - visitTypeEntry(DTy->getBaseType(), TempTypeId, true, false); + visitTypeEntry(DTy->getBaseType(), TempTypeId, true, false, false); else - visitTypeEntry(DTy->getBaseType(), TempTypeId, CheckPointer, SeenPointer); + visitTypeEntry(DTy->getBaseType(), TempTypeId, CheckPointer, SeenPointer, + false); } /// Visit a type entry. CheckPointer is true if the type has @@ -964,7 +969,8 @@ void BTFDebug::visitDerivedType(const DIDerivedType *DTy, uint32_t &TypeId, /// will not be emitted in BTF and rather forward declarations /// will be generated. void BTFDebug::visitTypeEntry(const DIType *Ty, uint32_t &TypeId, - bool CheckPointer, bool SeenPointer) { + bool CheckPointer, bool SeenPointer, + bool StripName) { if (!Ty || DIToIdMap.find(Ty) != DIToIdMap.end()) { TypeId = DIToIdMap[Ty]; @@ -1014,7 +1020,8 @@ void BTFDebug::visitTypeEntry(const DIType *Ty, uint32_t &TypeId, break; } uint32_t TmpTypeId; - visitTypeEntry(BaseTy, TmpTypeId, CheckPointer, SeenPointer); + visitTypeEntry(BaseTy, TmpTypeId, CheckPointer, SeenPointer, + StripName); break; } } @@ -1030,7 +1037,7 @@ void BTFDebug::visitTypeEntry(const DIType *Ty, uint32_t &TypeId, visitSubroutineType(STy, false, std::unordered_map(), TypeId); else if (const auto *CTy = dyn_cast(Ty)) - visitCompositeType(CTy, TypeId); + visitCompositeType(CTy, TypeId, StripName); else if (const auto *DTy = dyn_cast(Ty)) visitDerivedType(DTy, TypeId, CheckPointer, SeenPointer); else @@ -1039,7 +1046,7 @@ void BTFDebug::visitTypeEntry(const DIType *Ty, uint32_t &TypeId, void BTFDebug::visitTypeEntry(const DIType *Ty) { uint32_t TypeId; - visitTypeEntry(Ty, TypeId, false, false); + visitTypeEntry(Ty, TypeId, false, false, false); } void BTFDebug::visitMapDefType(const DIType *Ty, uint32_t &TypeId) { @@ -1048,6 +1055,7 @@ void BTFDebug::visitMapDefType(const DIType *Ty, uint32_t &TypeId) { return; } + bool StripName = true; uint32_t TmpId; switch (Ty->getTag()) { case dwarf::DW_TAG_typedef: @@ -1077,6 +1085,8 @@ void BTFDebug::visitMapDefType(const DIType *Ty, uint32_t &TypeId) { const auto *MemberCTy = dyn_cast(MemberBaseType); if (MemberCTy) { visitMapDefType(MemberBaseType, TmpId); + // Don't strip the name of the wrapper. + StripName = false; } else { visitTypeEntry(MemberBaseType); } @@ -1088,7 +1098,7 @@ void BTFDebug::visitMapDefType(const DIType *Ty, uint32_t &TypeId) { } // Visit this type, struct or a const/typedef/volatile/restrict type - visitTypeEntry(Ty, TypeId, false, false); + visitTypeEntry(Ty, TypeId, false, false, StripName); } /// Read file contents from the actual file or from the source @@ -1364,7 +1374,7 @@ void BTFDebug::endFunctionImpl(const MachineFunction *MF) { /// accessing or preserve debuginfo type. unsigned BTFDebug::populateType(const DIType *Ty) { unsigned Id; - visitTypeEntry(Ty, Id, false, false); + visitTypeEntry(Ty, Id, false, false, false); for (const auto &TypeEntry : TypeEntries) TypeEntry->completeType(*this); return Id; @@ -1563,7 +1573,7 @@ void BTFDebug::processGlobals(bool ProcessingMapDef) { visitMapDefType(DIGlobal->getType(), GVTypeId); else { const DIType *Ty = tryRemoveAtomicType(DIGlobal->getType()); - visitTypeEntry(Ty, GVTypeId, false, false); + visitTypeEntry(Ty, GVTypeId, false, false, false); } break; } diff --git a/llvm/lib/Target/BPF/BTFDebug.h b/llvm/lib/Target/BPF/BTFDebug.h index 75858fcc8bfde..7e8250e5cb1f3 100644 --- a/llvm/lib/Target/BPF/BTFDebug.h +++ b/llvm/lib/Target/BPF/BTFDebug.h @@ -126,11 +126,12 @@ class BTFTypeArray : public BTFTypeBase { class BTFTypeStruct : public BTFTypeBase { const DICompositeType *STy; bool HasBitField; + bool StripName; std::vector Members; public: BTFTypeStruct(const DICompositeType *STy, bool IsStruct, bool HasBitField, - uint32_t NumMembers); + uint32_t NumMembers, bool StripName); uint32_t getSize() override { return BTFTypeBase::getSize() + Members.size() * BTF::BTFMemberSize; } @@ -321,7 +322,7 @@ class BTFDebug : public DebugHandlerBase { /// @{ void visitTypeEntry(const DIType *Ty); void visitTypeEntry(const DIType *Ty, uint32_t &TypeId, bool CheckPointer, - bool SeenPointer); + bool SeenPointer, bool StripName); void visitBasicType(const DIBasicType *BTy, uint32_t &TypeId); void visitSubroutineType( const DISubroutineType *STy, bool ForSubprog, @@ -329,9 +330,10 @@ class BTFDebug : public DebugHandlerBase { uint32_t &TypeId); void visitFwdDeclType(const DICompositeType *CTy, bool IsUnion, uint32_t &TypeId); - void visitCompositeType(const DICompositeType *CTy, uint32_t &TypeId); + void visitCompositeType(const DICompositeType *CTy, uint32_t &TypeId, + bool StripName); void visitStructType(const DICompositeType *STy, bool IsStruct, - uint32_t &TypeId); + uint32_t &TypeId, bool StripName); void visitArrayType(const DICompositeType *ATy, uint32_t &TypeId); void visitEnumType(const DICompositeType *ETy, uint32_t &TypeId); void visitDerivedType(const DIDerivedType *DTy, uint32_t &TypeId, diff --git a/llvm/test/CodeGen/BPF/BTF/map-def-2.ll b/llvm/test/CodeGen/BPF/BTF/map-def-2.ll index d4c836f7c479c..12770c5efdcf2 100644 --- a/llvm/test/CodeGen/BPF/BTF/map-def-2.ll +++ b/llvm/test/CodeGen/BPF/BTF/map-def-2.ll @@ -23,7 +23,7 @@ ; CHECK-BTF-NEXT: [2] STRUCT 'key_type' size=4 vlen=1 ; CHECK-BTF-NEXT: 'a1' type_id=3 bits_offset=0 ; CHECK-BTF-NEXT: [3] INT 'int' size=4 bits_offset=0 nr_bits=32 encoding=SIGNED -; CHECK-BTF-NEXT: [4] STRUCT 'map_type' size=8 vlen=1 +; CHECK-BTF-NEXT: [4] STRUCT '(anon)' size=8 vlen=1 ; CHECK-BTF-NEXT: 'key' type_id=1 bits_offset=0 ; CHECK-BTF-NEXT: [5] TYPEDEF '_map_type' type_id=4 ; CHECK-BTF-NEXT: [6] TYPEDEF '__map_type' type_id=5 diff --git a/llvm/test/CodeGen/BPF/BTF/map-def-3.ll b/llvm/test/CodeGen/BPF/BTF/map-def-3.ll index 1d95f03b0d5e8..7013d4e344fba 100644 --- a/llvm/test/CodeGen/BPF/BTF/map-def-3.ll +++ b/llvm/test/CodeGen/BPF/BTF/map-def-3.ll @@ -15,7 +15,7 @@ @hash_map = dso_local local_unnamed_addr constant %struct.key_type zeroinitializer, section ".maps", align 4, !dbg !0 ; CHECK-BTF: [1] INT 'int' size=4 bits_offset=0 nr_bits=32 encoding=SIGNED -; CHECK-BTF-NEXT: [2] STRUCT 'key_type' size=4 vlen=1 +; CHECK-BTF-NEXT: [2] STRUCT '(anon)' size=4 vlen=1 ; CHECK-BTF-NEXT: 'a1' type_id=1 bits_offset=0 ; CHECK-BTF-NEXT: [3] CONST '(anon)' type_id=2 ; CHECK-BTF-NEXT: [4] VAR 'hash_map' type_id=3, linkage=global diff --git a/llvm/test/CodeGen/BPF/BTF/map-def-4.ll b/llvm/test/CodeGen/BPF/BTF/map-def-4.ll new file mode 100644 index 0000000000000..807af6dafaf73 --- /dev/null +++ b/llvm/test/CodeGen/BPF/BTF/map-def-4.ll @@ -0,0 +1,84 @@ +; 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] +; +; use core::ptr; +; +; #[allow(dead_code)] +; pub struct HashMap { +; key: *const K, +; value: *const V, +; } +; +; impl HashMap { +; pub const fn new() -> Self { +; Self { +; key: ptr::null(), +; value: ptr::null(), +; } +; } +; } +; +; #[unsafe(link_section = ".maps")] +; #[unsafe(no_mangle)] +; pub static mut MY_MAP: HashMap = 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-bc +; llvm-extract --glob=MY_MAP $(find target/ -name "*.bc" | head -n 1) -o map-def-named-2.bc +; llvm-dis map-def-named-2.bc -o map-def-named-2.ll + +; ModuleID = 'map-def-named-2.bc' +source_filename = "9xlybfhcys3n1sozp3bnamiuu" +target datalayout = "e-m:e-p:64:64-i64:64-i128:128-n32:64-S128" +target triple = "bpfel" + +@MY_MAP = global [16 x i8] zeroinitializer, section ".maps", align 8, !dbg !0 + +!llvm.module.flags = !{!14, !15, !16, !17} +!llvm.ident = !{!18} +!llvm.dbg.cu = !{!19} + +; CHECK-BTF: [1] PTR '(anon)' type_id=2 +; CHECK-BTF-NEXT: [2] INT 'u32' size=4 bits_offset=0 nr_bits=32 encoding=(none) +; CHECK-BTF-NEXT: [3] STRUCT '(anon)' size=16 vlen=2 +; CHECK-BTF-NEXT: 'key' type_id=1 bits_offset=0 +; CHECK-BTF-NEXT: 'value' type_id=1 bits_offset=64 +; CHECK-BTF-NEXT: [4] VAR 'MY_MAP' type_id=3, linkage=global +; CHECK-BTF-NEXT: [5] DATASEC '.maps' size=0 vlen=1 +; CHECK-BTF-NEXT: type_id=4 offset=0 size=16 + +!0 = !DIGlobalVariableExpression(var: !1, expr: !DIExpression()) +!1 = distinct !DIGlobalVariable(name: "MY_MAP", scope: !2, file: !3, line: 23, type: !4, isLocal: false, isDefinition: true, align: 64) +!2 = !DINamespace(name: "btf_map", scope: null) +!3 = !DIFile(filename: "src/main.rs", directory: "/home/vad/playground/btf-map", checksumkind: CSK_MD5, checksum: "954834fe667cc8cedd8b47ffcd2b489f") +!4 = !DICompositeType(tag: DW_TAG_structure_type, name: "HashMap", scope: !2, file: !5, size: 128, align: 64, flags: DIFlagPublic, elements: !6, templateParams: !11, identifier: "53d93ef1bb5578628ce008544cf10207") +!5 = !DIFile(filename: "", directory: "") +!6 = !{!7, !10} +!7 = !DIDerivedType(tag: DW_TAG_member, name: "key", 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 = !DIDerivedType(tag: DW_TAG_member, name: "value", scope: !4, file: !5, baseType: !8, size: 64, align: 64, offset: 64, flags: DIFlagPrivate) +!11 = !{!12, !13} +!12 = !DITemplateTypeParameter(name: "K", type: !9) +!13 = !DITemplateTypeParameter(name: "V", type: !9) +!14 = !{i32 8, !"PIC Level", i32 2} +!15 = !{i32 7, !"PIE Level", i32 2} +!16 = !{i32 7, !"Dwarf Version", i32 4} +!17 = !{i32 2, !"Debug Info Version", i32 3} +!18 = !{!"rustc version 1.91.0-nightly (160e7623e 2025-08-26)"} +!19 = distinct !DICompileUnit(language: DW_LANG_Rust, file: !20, producer: "clang LLVM (rustc version 1.91.0-nightly (160e7623e 2025-08-26))", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, globals: !21, splitDebugInlining: false, nameTableKind: None) +!20 = !DIFile(filename: "src/main.rs/@/9xlybfhcys3n1sozp3bnamiuu", directory: "/home/vad/playground/btf-map") +!21 = !{!0} diff --git a/llvm/test/CodeGen/BPF/BTF/map-def.ll b/llvm/test/CodeGen/BPF/BTF/map-def.ll index a3835f1dae4b5..d97b75868e516 100644 --- a/llvm/test/CodeGen/BPF/BTF/map-def.ll +++ b/llvm/test/CodeGen/BPF/BTF/map-def.ll @@ -27,7 +27,7 @@ ; CHECK-NEXT: .long 0 ; CHECK-NEXT: .long 168 ; CHECK-NEXT: .long 168 -; CHECK-NEXT: .long 65 +; CHECK-NEXT: .long 56 ; CHECK-NEXT: .long 0 # BTF_KIND_PTR(id = 1) ; CHECK-NEXT: .long 33554432 # 0x2000000 ; CHECK-NEXT: .long 2 @@ -51,20 +51,20 @@ ; CHECK-NEXT: .long 16777216 # 0x1000000 ; CHECK-NEXT: .long 4 ; CHECK-NEXT: .long 32 # 0x20 -; CHECK-NEXT: .long 31 # BTF_KIND_STRUCT(id = 6) +; CHECK-NEXT: .long 0 # BTF_KIND_STRUCT(id = 6) ; CHECK-NEXT: .long 67108866 # 0x4000002 ; CHECK-NEXT: .long 16 -; CHECK-NEXT: .long 40 +; CHECK-NEXT: .long 31 ; CHECK-NEXT: .long 1 ; CHECK-NEXT: .long 0 # 0x0 -; CHECK-NEXT: .long 44 +; CHECK-NEXT: .long 35 ; CHECK-NEXT: .long 4 ; CHECK-NEXT: .long 64 # 0x40 -; CHECK-NEXT: .long 50 # BTF_KIND_VAR(id = 7) +; CHECK-NEXT: .long 41 # BTF_KIND_VAR(id = 7) ; CHECK-NEXT: .long 234881024 # 0xe000000 ; CHECK-NEXT: .long 6 ; CHECK-NEXT: .long 1 -; CHECK-NEXT: .long 59 # BTF_KIND_DATASEC(id = 8) +; CHECK-NEXT: .long 50 # BTF_KIND_DATASEC(id = 8) ; CHECK-NEXT: .long 251658241 # 0xf000001 ; CHECK-NEXT: .long 0 ; CHECK-NEXT: .long 7 @@ -81,15 +81,13 @@ ; CHECK-NEXT: .byte 0 ; CHECK-NEXT: .ascii "unsigned int" # string offset=18 ; CHECK-NEXT: .byte 0 -; CHECK-NEXT: .ascii "map_type" # string offset=31 +; CHECK-NEXT: .ascii "key" # string offset=31 ; CHECK-NEXT: .byte 0 -; CHECK-NEXT: .ascii "key" # string offset=40 +; CHECK-NEXT: .ascii "value" # string offset=35 ; CHECK-NEXT: .byte 0 -; CHECK-NEXT: .ascii "value" # string offset=44 +; CHECK-NEXT: .ascii "hash_map" # string offset=41 ; CHECK-NEXT: .byte 0 -; CHECK-NEXT: .ascii "hash_map" # string offset=50 -; CHECK-NEXT: .byte 0 -; CHECK-NEXT: .ascii ".maps" # string offset=59 +; CHECK-NEXT: .ascii ".maps" # string offset=50 ; CHECK-NEXT: .byte 0 !llvm.dbg.cu = !{!2}