• Yonghong Song's avatar
    bpf: Add btf enum64 support · 6089fb32
    Yonghong Song authored
    Currently, BTF only supports upto 32bit enum value with BTF_KIND_ENUM.
    But in kernel, some enum indeed has 64bit values, e.g.,
    in uapi bpf.h, we have
      enum {
            BPF_F_INDEX_MASK                = 0xffffffffULL,
            BPF_F_CURRENT_CPU               = BPF_F_INDEX_MASK,
            BPF_F_CTXLEN_MASK               = (0xfffffULL << 32),
      };
    In this case, BTF_KIND_ENUM will encode the value of BPF_F_CTXLEN_MASK
    as 0, which certainly is incorrect.
    
    This patch added a new btf kind, BTF_KIND_ENUM64, which permits
    64bit value to cover the above use case. The BTF_KIND_ENUM64 has
    the following three fields followed by the common type:
      struct bpf_enum64 {
        __u32 nume_off;
        __u32 val_lo32;
        __u32 val_hi32;
      };
    Currently, btf type section has an alignment of 4 as all element types
    are u32. Representing the value with __u64 will introduce a pad
    for bpf_enum64 and may also introduce misalignment for the 64bit value.
    Hence, two members of val_hi32 and val_lo32 are chosen to avoid these issues.
    
    The kflag is also introduced for BTF_KIND_ENUM and BTF_KIND_ENUM64
    to indicate whether the value is signed or unsigned. The kflag intends
    to provide consistent output of BTF C fortmat with the original
    source code. For example, the original BTF_KIND_ENUM bit value is 0xffffffff.
    The format C has two choices, printing out 0xffffffff or -1 and current libbpf
    prints out as unsigned value. But if the signedness is preserved in btf,
    the value can be printed the same as the original source code.
    The kflag value 0 means unsigned values, which is consistent to the default
    by libbpf and should also cover most cases as well.
    
    The new BTF_KIND_ENUM64 is intended to support the enum value represented as
    64bit value. But it can represent all BTF_KIND_ENUM values as well.
    The compiler ([1]) and pahole will generate BTF_KIND_ENUM64 only if the value has
    to be represented with 64 bits.
    
    In addition, a static inline function btf_kind_core_compat() is introduced which
    will be used later when libbpf relo_core.c changed. Here the kernel shares the
    same relo_core.c with libbpf.
    
      [1] https://reviews.llvm.org/D124641Acked-by: default avatarAndrii Nakryiko <andrii@kernel.org>
    Signed-off-by: default avatarYonghong Song <yhs@fb.com>
    Link: https://lore.kernel.org/r/20220607062600.3716578-1-yhs@fb.comSigned-off-by: default avatarAlexei Starovoitov <ast@kernel.org>
    6089fb32
verifier.c 431 KB