With latest bcc v0.29.1 and LLVM 17.0.6. bcc will produce a BPF program with incorrect offset for struct my_struct.ptr in the following (incomplete) snipped:
struct my_struct
{
long: 64;
long: 64;
long: 64;
void* ptr;
};
int kprobe__netif_rx(struct pt_regs *ctx)
{
struct event_t event = {};
void* p1 = (void*)ctx->di;
void* p2 = NULL;
event.offset1 = ((long)&((struct my_struct*)p1)->ptr) - (long)p1;
event.offset2 = ((long)&((struct my_struct*)p2)->ptr) - (long)p2;
events.perf_submit(ctx, &event, sizeof(event));
return 0;
}
where the produced BPF program is
Disassembly of function kprobe__netif_rx
; { // Line 34
0: b7 02 00 00 18 00 00 00 r2 = 24
; event.offset2 = (long)&((struct my_struct*)p2)->ptr - (long)p2; // Line 41
1: 7b 2a f8 ff 00 00 00 00 *(u64 *)(r10 - 8) = r2
2: b7 02 00 00 20 00 00 00 r2 = 32
; event.offset1 = (long)&((struct my_struct*)p1)->ptr - (long)p1; // Line 40
3: 7b 2a f0 ff 00 00 00 00 *(u64 *)(r10 - 16) = r2
; bpf_perf_event_output(ctx, (void *)bpf_pseudo_fd(1, -1), CUR_CPU_IDENTIFIER, &event, sizeof(event)); // Line 42
...
In the above we can see offset1 == 32 while offset2 == 24 despite both are calculating the offset of ptr.
Bisect landed me on f35dae07 (merged in #2863) which was meant to address #2827 by introducing i128 type to the BPF layout spec (supported since LLVM 11); but I don't know what's the proper fix here.
To my best knowledge this has to do with the consecutive bitfields merging together and become a singe i192 type, which will use the alignment of the largest defined type (i64:64/8 bytes before and i128:128/16 bytes after f35dae07).
%struct.my_struct = type { i192, ptr }
Note: LLVM release 18.1.0-rc1 has llvm/llvm-project@a21abc7 that made the issue go away for me. However, I cannot judge whether it is the proper fix in this case.
(CC @yonghong-song)
With latest bcc v0.29.1 and LLVM 17.0.6. bcc will produce a BPF program with incorrect offset for
struct my_struct.ptrin the following (incomplete) snipped:where the produced BPF program is
In the above we can see
offset1 == 32whileoffset2 == 24despite both are calculating the offset ofptr.Bisect landed me on f35dae07 (merged in #2863) which was meant to address #2827 by introducing i128 type to the BPF layout spec (supported since LLVM 11); but I don't know what's the proper fix here.
To my best knowledge this has to do with the consecutive bitfields merging together and become a singe
i192type, which will use the alignment of the largest defined type (i64:64/8 bytes before andi128:128/16 bytes after f35dae07).Note: LLVM release 18.1.0-rc1 has llvm/llvm-project@a21abc7 that made the issue go away for me. However, I cannot judge whether it is the proper fix in this case.
(CC @yonghong-song)