bpf_core_type_id_kernel is not consistent with bpf_core_type_id_local

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hi,

I think that CO-RE has inconsistent behaviour wrt. BPF_TYPE_ID_LOCAL
and BPF_TYPE_ID_TARGET when dealing with qualifiers (modifiers?) Given
the following C:

enum bpf_type_id_kind {
    BPF_TYPE_ID_LOCAL = 0,        /* BTF type ID in local program */
    BPF_TYPE_ID_TARGET = 1,        /* BTF type ID in target kernel */
};

int foo(void) {
    return __builtin_btf_type_id(*(const int *)0, BPF_TYPE_ID_TARGET)
!= __builtin_btf_type_id(*(const int *)0, BPF_TYPE_ID_LOCAL);
}

That line with __builtin_btf_type_id is just the expansion of
bpf_core_type_id_kernel, etc. clang generates the following BPF:

foo:
 18 01 00 00 02 00 00 00 00 00 00 00 00 00 00 00    r1 = 0x2 ll
 79 11 00 00 00 00 00 00    r1 = *(u64 *)(r1 + 0x0)
 18 02 00 00 04 00 00 00 00 00 00 00 00 00 00 00    r2 = 0x4 ll
 79 22 00 00 00 00 00 00    r2 = *(u64 *)(r2 + 0x0)
 b7 03 00 00 00 00 00 00    r3 = 0x0
 7b 3a f0 ff 00 00 00 00    *(u64 *)(r10 - 0x10) = r3
 b7 03 00 00 01 00 00 00    r3 = 0x1
 7b 3a f8 ff 00 00 00 00    *(u64 *)(r10 - 0x8) = r3
 5d 21 02 00 00 00 00 00    if r1 != r2 goto +0x2 <LBB0_2>
 79 a1 f0 ff 00 00 00 00    r1 = *(u64 *)(r10 - 0x10)
 7b 1a f8 ff 00 00 00 00    *(u64 *)(r10 - 0x8) = r1
LBB0_2:
 79 a0 f8 ff 00 00 00 00    r0 = *(u64 *)(r10 - 0x8)
 95 00 00 00 00 00 00 00    exit

Link to godbolt: https://godbolt.org/z/jr63hKz9E (contains version info)

Note that the first two ldimm64 have distinct type IDs. I added some
debug logging to cilium/ebpf and found that the compiler indeed also
emits distinct CO-RE relocations:

foo {InsnOff:0 TypeID:2 AccessStrOff:69 Kind:local_type_id}
foo {InsnOff:2 TypeID:4 AccessStrOff:69 Kind:target_type_id}

It seems that for BPF_TYPE_ID_TARGET the outer const is peeled, while
this doesn't happen for the local variant.

CORERelocation(local_type_id, Const[0], local_id=4) local_type_id=4->4
CORERelocation(target_type_id, Int:"int"[0], local_id=2) target_type_id=2->2

Similar behaviour exists for BPF_TYPE_EXISTS, probably others.

The behaviour goes away if I drop the pointer casting magic:

__builtin_btf_type_id((const int)0, BPF_TYPE_ID_TARGET) !=
__builtin_btf_type_id((const int)0, BPF_TYPE_ID_LOCAL)

Intuitively I'd say that the root cause is that dereferencing the
pointer drops the constness of the type. Why does TARGET behave
differently than LOCAL though?

Cheers
Lorenz




[Index of Archives]     [Linux Samsung SoC]     [Linux Rockchip SoC]     [Linux Actions SoC]     [Linux for Synopsys ARC Processors]     [Linux NFS]     [Linux NILFS]     [Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]


  Powered by Linux