-
Notifications
You must be signed in to change notification settings - Fork 15.4k
[BPF] Strip map struct names #164851
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[BPF] Strip map struct names #164851
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -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<BTFTypeStruct>(CTy, IsStruct, HasBitField, VLen); | ||
| std::make_unique<BTFTypeStruct>(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<uint32_t, StringRef>(), | ||
| TypeId); | ||
| else if (const auto *CTy = dyn_cast<DICompositeType>(Ty)) | ||
| visitCompositeType(CTy, TypeId); | ||
| visitCompositeType(CTy, TypeId, StripName); | ||
| else if (const auto *DTy = dyn_cast<DIDerivedType>(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<DICompositeType>(MemberBaseType); | ||
| if (MemberCTy) { | ||
| visitMapDefType(MemberBaseType, TmpId); | ||
| // Don't strip the name of the wrapper. | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Better to say why rather than what. |
||
| 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; | ||
| } | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -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 | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. does this (and the diffs in |
||
| ; 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 | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -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<K, V> { | ||
| ; key: *const K, | ||
| ; value: *const V, | ||
| ; } | ||
| ; | ||
| ; impl<K, V> HashMap<K, V> { | ||
| ; 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<u32, u32> = 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<u32, u32>", scope: !2, file: !5, size: 128, align: 64, flags: DIFlagPublic, elements: !6, templateParams: !11, identifier: "53d93ef1bb5578628ce008544cf10207") | ||
| !5 = !DIFile(filename: "<unknown>", 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} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
is it time to sprinkle some
/* argName = */ falsedecorations?here and everywhere