[llvm] [BPF] Support for `DW_TAG_variant_part` in BTF generation (PR #155783)

via llvm-commits llvm-commits at lists.llvm.org
Tue Oct 7 10:22:21 PDT 2025


================
@@ -301,21 +303,61 @@ void BTFTypeStruct::completeType(BTFDebug &BDebug) {
 
   BTFType.NameOff = BDebug.addString(STy->getName());
 
+  uint64_t InitialOffset = 0;
+  if (STy->getTag() == dwarf::DW_TAG_variant_part) {
+    // Variant parts have a discriminator, which has its own memory location at
+    // the beginning, and variants, which share the memory location afterwards.
+    // LLVM DI doesn't consider discriminator as an element and instead keeps
+    // it as a separate reference.
+    // To keep BTF simple, let's represent the structure as an union with
+    // discriminator as the first element and apply offsets to the other
+    // elements.
+    struct BTF::BTFMember Discriminator;
+    const auto *DDTy = STy->getDiscriminator();
+
+    InitialOffset += DDTy->getOffsetInBits() + DDTy->getSizeInBits();
----------------
eddyz87 wrote:

> Regarding stability - I think the variant parts annotated with #[repr(C)] are guaranteed to be stable. #[repr(Rust)] could change the layout any time, but I think it's fair to require the usage of #[repr(C)] in BPF programs. We could sort of enforce that by adding a custom Clippy lint and push Aya users to adhere to it.

I'm not worried about binary stability, but about generated DWARF stability. I don't think rustc gives any guarantees regarding DWARF representation of enums. Specifically, for the example at hand DWARF describes an equivalent of C structure below:

```c
// repr A
union Adt {
  u32 discriminant;
  struct First First;
  struct Second Second;
};
struct First {
  u32 :32;
  u32 a;
  u32 b;
};
...
```

But an alternative representation would be correct as well: 

```c
// repr B
struct Adt {
  u32 discriminant;
  union {
    struct First First;
    struct Second Second;
  }
};
struct First {
  u32 a;
  u32 b;
};
...
```

What you are trying to do with `InitialOffset` is to convert repr A into repr B, which is recursive operation closely tied to the specifics of DWARF generation by rustc. Should rustc decide to use different DWARF representation the logic will need adjustment.

> My worry is that we don't do the offset computation correctly, the BTF relocations done on variant parts won't work. 

DWARF produced by rustc already contains correct offsets for data structure fields, what is it exactly that you suspect won't work?

> Hypocritical of me given that I didn't get it right here (I'm very sorry, I'm still new to LLVM and compilers), but I really want to do it right.

Nothing to be sorry about, compilers are complicated.


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


More information about the llvm-commits mailing list