-
Notifications
You must be signed in to change notification settings - Fork 15k
[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
Conversation
Linux kernel rejects programs which use named structs as map definitions. BPF programs written in C usually follow that restriction by using anonymous structs. But some LLVM frontend (e.g. Rust) don't support defining anonymous structs. To make sure they work, strip the map struct name unconditionally.
You can test this locally with the following command:git-clang-format --diff origin/main HEAD --extensions cpp,h -- llvm/lib/Target/BPF/BTFDebug.cpp llvm/lib/Target/BPF/BTFDebug.h --diff_from_common_commit
View the diff from clang-format here.diff --git a/llvm/lib/Target/BPF/BTFDebug.cpp b/llvm/lib/Target/BPF/BTFDebug.cpp
index 7718e36f1..43ea28b1c 100644
--- a/llvm/lib/Target/BPF/BTFDebug.cpp
+++ b/llvm/lib/Target/BPF/BTFDebug.cpp
@@ -757,9 +757,8 @@ void BTFDebug::visitStructType(const DICompositeType *CTy, bool IsStruct,
}
}
- auto TypeEntry =
- std::make_unique<BTFTypeStruct>(CTy, IsStruct, HasBitField, VLen,
- StripName);
+ auto TypeEntry = std::make_unique<BTFTypeStruct>(CTy, IsStruct, HasBitField,
+ VLen, StripName);
StructTypes.push_back(TypeEntry.get());
TypeId = addType(std::move(TypeEntry), CTy);
@@ -864,8 +863,8 @@ void BTFDebug::visitFwdDeclType(const DICompositeType *CTy, bool IsUnion,
}
/// Handle structure, union, array and enumeration types.
-void BTFDebug::visitCompositeType(const DICompositeType *CTy,
- uint32_t &TypeId, bool StripName) {
+void BTFDebug::visitCompositeType(const DICompositeType *CTy, uint32_t &TypeId,
+ bool StripName) {
auto Tag = CTy->getTag();
switch (Tag) {
case dwarf::DW_TAG_structure_type:
@@ -875,7 +874,8 @@ 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, StripName);
+ visitStructType(CTy, Tag == dwarf::DW_TAG_structure_type, TypeId,
+ StripName);
break;
case dwarf::DW_TAG_array_type:
visitArrayType(CTy, TypeId);
@@ -905,8 +905,8 @@ void BTFDebug::visitDerivedType(const DIDerivedType *DTy, uint32_t &TypeId,
unsigned Tag = DTy->getTag();
if (Tag == dwarf::DW_TAG_atomic_type)
- return visitTypeEntry(DTy->getBaseType(), TypeId, CheckPointer,
- SeenPointer, false);
+ return visitTypeEntry(DTy->getBaseType(), TypeId, CheckPointer, SeenPointer,
+ false);
/// Try to avoid chasing pointees, esp. structure pointees which may
/// unnecessary bring in a lot of types.
|
| @@ -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); | |||
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
| @@ -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. | |||
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.
Better to say why rather than what.
| @@ -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 | |||
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.
does this (and the diffs in map-def-3.ll and map-def.ll) mean that this snippet would have been rejected by the kernel?
By map definition structs, you mean these things: struct {
__uint(type, BPF_MAP_TYPE_HASH);
__uint(max_entries, 1);
__type(key, long long);
__type(value, long long);
} map_hash_8b SEC(".maps");right? These are not processed by kernel, but by libbpf, so relaxing the requirement on the libbpf side is also an option. (See |
|
Actually, I don't see where libbpf enforces map type to be nameless. Could you please provide some detail on what fails w/o this change? |
|
I'm going to close this. We had a fixup for removing the map names in bpf-linker since forever and I made this PR without questioning it. But now I tested with different kernels down to 5.10 and I cannot reproduce the issue anymore. Perhaps the issues we were facing were just about the pointer types present in the map structs and we got too eager with these fixups. Sorry for the noise! |
Linux kernel rejects programs which use named structs as map definitions. BPF programs written in C usually follow that restriction by using anonymous structs. But some LLVM frontend (e.g. Rust) don't support defining anonymous structs. To make sure they work, strip the map struct name unconditionally.