public inbox for bpf@vger.kernel.org
 help / color / mirror / Atom feed
From: Yonghong Song <yhs@meta.com>
To: Lorenz Bauer <lmb@isovalent.com>, bpf <bpf@vger.kernel.org>,
	Yonghong Song <yhs@fb.com>, Andrii Nakryiko <andrii@kernel.org>
Subject: Re: bpf_core_type_id_kernel is not consistent with bpf_core_type_id_local
Date: Wed, 5 Jul 2023 21:50:35 -0700	[thread overview]
Message-ID: <e9987f16-7328-627d-8c02-c42c130a61a8@meta.com> (raw)
In-Reply-To: <CAN+4W8h3yDjkOLJPiuKVKTpj_08pBz8ke6vN=Lf8gcA=iYBM-g@mail.gmail.com>



On 7/4/23 6:30 AM, Lorenz Bauer wrote:
> 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?

Thanks for reporting. The difference of type w.r.t. 'const' modifier
is a deliberate choice in llvm:

See 
https://github.com/llvm/llvm-project/blob/main/llvm/lib/Target/BPF/BPFPreserveDIType.cpp#L84-L103

     if (FlagValue == BPFCoreSharedInfo::BTF_TYPE_ID_LOCAL_RELOC) {
       Reloc = BPFCoreSharedInfo::BTF_TYPE_ID_LOCAL;
     } else {
       Reloc = BPFCoreSharedInfo::BTF_TYPE_ID_REMOTE;
       DIType *Ty = cast<DIType>(MD);
       while (auto *DTy = dyn_cast<DIDerivedType>(Ty)) {
         unsigned Tag = DTy->getTag();
         if (Tag != dwarf::DW_TAG_const_type &&
             Tag != dwarf::DW_TAG_volatile_type)
           break;
         Ty = DTy->getBaseType();
       }

       if (Ty->getName().empty()) {
         if (isa<DISubroutineType>(Ty))
           report_fatal_error(
               "SubroutineType not supported for BTF_TYPE_ID_REMOTE reloc");
         else
           report_fatal_error("Empty type name for BTF_TYPE_ID_REMOTE 
reloc");
       }
       MD = Ty;
     }

Basically, the BTF_TYPE_ID_REMOTE (the kernel term BPF_TYPE_ID_TARGET)
needs further checking to prevent some invalid cases.
Also for kernel type matching, it would be good to eliminate modifiers
otherwise, there could be many instances of 'const' which makes
kernel matching is more complicated.

But I see your point. Maybe we should preserve the original type
for BTF_TYPE_ID_TARGET as well. Will check what libbpf/kernel
will handle 'const int *' case and get back to this thread later.

> 
> Cheers
> Lorenz

  reply	other threads:[~2023-07-06  4:50 UTC|newest]

Thread overview: 12+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2023-07-04 13:30 bpf_core_type_id_kernel is not consistent with bpf_core_type_id_local Lorenz Bauer
2023-07-06  4:50 ` Yonghong Song [this message]
2023-07-06 21:06   ` Andrii Nakryiko
2023-07-11 16:20     ` Lorenz Bauer
2023-07-11 16:38       ` Andrii Nakryiko
2023-10-31 15:46   ` Lorenz Bauer
2023-10-31 18:24     ` Andrii Nakryiko
2023-11-01 14:17       ` Lorenz Bauer
2023-11-01 22:42         ` Andrii Nakryiko
2023-11-02  0:34           ` Yonghong Song
2023-11-02  2:16             ` Andrii Nakryiko
2023-11-03 19:58               ` Yonghong Song

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=e9987f16-7328-627d-8c02-c42c130a61a8@meta.com \
    --to=yhs@meta.com \
    --cc=andrii@kernel.org \
    --cc=bpf@vger.kernel.org \
    --cc=lmb@isovalent.com \
    --cc=yhs@fb.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox