Skip to content

Commit 00a3c60

Browse files
author
Yonghong Song
committed
[RFC][BPF] Handle DW_TAG_atomic_type properly
Make change in BTFDebug.cpp to handle DW_TAG_atomic_type properly. Otherwise, a type like _Atomic int i; // global the dwarf type chain atomic->int Since DW_TAG_atomic_type is not processed BTF generation will stop at atomic modifier and BTF will encode 'i' as void type. Similar for type like volatile _Atomic int *p; the dwarf type chain ptr->volatile->atomic->int Since atomic type is not processed and BTF generation will stop at atomic type, the eventual BTF type will be ptr->volatile->void which is incorrect. This patch fixed the above two patterns by skipping DW_TAG_atomic_type. There could be more cases which I will try to fix those with more test cases. This is a RFC patch and the current implementation is good enough to run kernel selftests with _Atomic usage ([1]). In kernel selftest arena_atomics.c, the new bpf code looks like ``` _Atomic __u64 __arena_global and64_value = (0x110ull << 32); _Atomic __u32 __arena_global and32_value = 0x110; SEC("raw_tp/sys_enter") int and(const void *ctx) { ... __c11_atomic_fetch_and(&and64_value, 0x011ull << 32, memory_order_relaxed); __c11_atomic_fetch_and(&and32_value, 0x011, memory_order_relaxed); ... return 0; } ``` The skel file arena_atomics.skel.h has ``` struct arena_atomics__arena { ... __u64 and64_value; __u32 and32_value; ... } *arena; ``` [1] https://lore.kernel.org/bpf/[email protected]/
1 parent 1287680 commit 00a3c60

File tree

1 file changed

+19
-2
lines changed

1 file changed

+19
-2
lines changed

llvm/lib/Target/BPF/BTFDebug.cpp

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,12 @@ void BTFTypeDerived::completeType(BTFDebug &BDebug) {
9191

9292
// The base type for PTR/CONST/VOLATILE could be void.
9393
const DIType *ResolvedType = DTy->getBaseType();
94+
if (ResolvedType) {
95+
const auto *DerivedTy = dyn_cast<DIDerivedType>(ResolvedType);
96+
if (DerivedTy && DerivedTy->getTag() == dwarf::DW_TAG_atomic_type)
97+
ResolvedType = DerivedTy->getBaseType();
98+
}
99+
94100
if (!ResolvedType) {
95101
assert((Kind == BTF::BTF_KIND_PTR || Kind == BTF::BTF_KIND_CONST ||
96102
Kind == BTF::BTF_KIND_VOLATILE) &&
@@ -800,6 +806,10 @@ void BTFDebug::visitDerivedType(const DIDerivedType *DTy, uint32_t &TypeId,
800806
bool CheckPointer, bool SeenPointer) {
801807
unsigned Tag = DTy->getTag();
802808

809+
if (Tag == dwarf::DW_TAG_atomic_type)
810+
return visitTypeEntry(DTy->getBaseType(), TypeId, CheckPointer,
811+
SeenPointer);
812+
803813
/// Try to avoid chasing pointees, esp. structure pointees which may
804814
/// unnecessary bring in a lot of types.
805815
if (CheckPointer && !SeenPointer) {
@@ -1444,8 +1454,15 @@ void BTFDebug::processGlobals(bool ProcessingMapDef) {
14441454
DIGlobal = GVE->getVariable();
14451455
if (SecName.starts_with(".maps"))
14461456
visitMapDefType(DIGlobal->getType(), GVTypeId);
1447-
else
1448-
visitTypeEntry(DIGlobal->getType(), GVTypeId, false, false);
1457+
else {
1458+
const DIType *Ty = DIGlobal->getType();
1459+
if (Ty) {
1460+
auto *DTy = dyn_cast<DIDerivedType>(Ty);
1461+
if (DTy && DTy->getTag() == dwarf::DW_TAG_atomic_type)
1462+
Ty = DTy->getBaseType();
1463+
}
1464+
visitTypeEntry(Ty, GVTypeId, false, false);
1465+
}
14491466
break;
14501467
}
14511468

0 commit comments

Comments
 (0)