mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-08-21 08:19:28 +00:00
![Yonghong Song](/assets/img/avatar_default.png)
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/D124641 Acked-by: Andrii Nakryiko <andrii@kernel.org> Signed-off-by: Yonghong Song <yhs@fb.com> Link: https://lore.kernel.org/r/20220607062600.3716578-1-yhs@fb.com Signed-off-by: Alexei Starovoitov <ast@kernel.org>
200 lines
5.5 KiB
C
200 lines
5.5 KiB
C
/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
|
|
/* Copyright (c) 2018 Facebook */
|
|
#ifndef _UAPI__LINUX_BTF_H__
|
|
#define _UAPI__LINUX_BTF_H__
|
|
|
|
#include <linux/types.h>
|
|
|
|
#define BTF_MAGIC 0xeB9F
|
|
#define BTF_VERSION 1
|
|
|
|
struct btf_header {
|
|
__u16 magic;
|
|
__u8 version;
|
|
__u8 flags;
|
|
__u32 hdr_len;
|
|
|
|
/* All offsets are in bytes relative to the end of this header */
|
|
__u32 type_off; /* offset of type section */
|
|
__u32 type_len; /* length of type section */
|
|
__u32 str_off; /* offset of string section */
|
|
__u32 str_len; /* length of string section */
|
|
};
|
|
|
|
/* Max # of type identifier */
|
|
#define BTF_MAX_TYPE 0x000fffff
|
|
/* Max offset into the string section */
|
|
#define BTF_MAX_NAME_OFFSET 0x00ffffff
|
|
/* Max # of struct/union/enum members or func args */
|
|
#define BTF_MAX_VLEN 0xffff
|
|
|
|
struct btf_type {
|
|
__u32 name_off;
|
|
/* "info" bits arrangement
|
|
* bits 0-15: vlen (e.g. # of struct's members)
|
|
* bits 16-23: unused
|
|
* bits 24-28: kind (e.g. int, ptr, array...etc)
|
|
* bits 29-30: unused
|
|
* bit 31: kind_flag, currently used by
|
|
* struct, union, enum, fwd and enum64
|
|
*/
|
|
__u32 info;
|
|
/* "size" is used by INT, ENUM, STRUCT, UNION, DATASEC and ENUM64.
|
|
* "size" tells the size of the type it is describing.
|
|
*
|
|
* "type" is used by PTR, TYPEDEF, VOLATILE, CONST, RESTRICT,
|
|
* FUNC, FUNC_PROTO, VAR, DECL_TAG and TYPE_TAG.
|
|
* "type" is a type_id referring to another type.
|
|
*/
|
|
union {
|
|
__u32 size;
|
|
__u32 type;
|
|
};
|
|
};
|
|
|
|
#define BTF_INFO_KIND(info) (((info) >> 24) & 0x1f)
|
|
#define BTF_INFO_VLEN(info) ((info) & 0xffff)
|
|
#define BTF_INFO_KFLAG(info) ((info) >> 31)
|
|
|
|
enum {
|
|
BTF_KIND_UNKN = 0, /* Unknown */
|
|
BTF_KIND_INT = 1, /* Integer */
|
|
BTF_KIND_PTR = 2, /* Pointer */
|
|
BTF_KIND_ARRAY = 3, /* Array */
|
|
BTF_KIND_STRUCT = 4, /* Struct */
|
|
BTF_KIND_UNION = 5, /* Union */
|
|
BTF_KIND_ENUM = 6, /* Enumeration up to 32-bit values */
|
|
BTF_KIND_FWD = 7, /* Forward */
|
|
BTF_KIND_TYPEDEF = 8, /* Typedef */
|
|
BTF_KIND_VOLATILE = 9, /* Volatile */
|
|
BTF_KIND_CONST = 10, /* Const */
|
|
BTF_KIND_RESTRICT = 11, /* Restrict */
|
|
BTF_KIND_FUNC = 12, /* Function */
|
|
BTF_KIND_FUNC_PROTO = 13, /* Function Proto */
|
|
BTF_KIND_VAR = 14, /* Variable */
|
|
BTF_KIND_DATASEC = 15, /* Section */
|
|
BTF_KIND_FLOAT = 16, /* Floating point */
|
|
BTF_KIND_DECL_TAG = 17, /* Decl Tag */
|
|
BTF_KIND_TYPE_TAG = 18, /* Type Tag */
|
|
BTF_KIND_ENUM64 = 19, /* Enumeration up to 64-bit values */
|
|
|
|
NR_BTF_KINDS,
|
|
BTF_KIND_MAX = NR_BTF_KINDS - 1,
|
|
};
|
|
|
|
/* For some specific BTF_KIND, "struct btf_type" is immediately
|
|
* followed by extra data.
|
|
*/
|
|
|
|
/* BTF_KIND_INT is followed by a u32 and the following
|
|
* is the 32 bits arrangement:
|
|
*/
|
|
#define BTF_INT_ENCODING(VAL) (((VAL) & 0x0f000000) >> 24)
|
|
#define BTF_INT_OFFSET(VAL) (((VAL) & 0x00ff0000) >> 16)
|
|
#define BTF_INT_BITS(VAL) ((VAL) & 0x000000ff)
|
|
|
|
/* Attributes stored in the BTF_INT_ENCODING */
|
|
#define BTF_INT_SIGNED (1 << 0)
|
|
#define BTF_INT_CHAR (1 << 1)
|
|
#define BTF_INT_BOOL (1 << 2)
|
|
|
|
/* BTF_KIND_ENUM is followed by multiple "struct btf_enum".
|
|
* The exact number of btf_enum is stored in the vlen (of the
|
|
* info in "struct btf_type").
|
|
*/
|
|
struct btf_enum {
|
|
__u32 name_off;
|
|
__s32 val;
|
|
};
|
|
|
|
/* BTF_KIND_ARRAY is followed by one "struct btf_array" */
|
|
struct btf_array {
|
|
__u32 type;
|
|
__u32 index_type;
|
|
__u32 nelems;
|
|
};
|
|
|
|
/* BTF_KIND_STRUCT and BTF_KIND_UNION are followed
|
|
* by multiple "struct btf_member". The exact number
|
|
* of btf_member is stored in the vlen (of the info in
|
|
* "struct btf_type").
|
|
*/
|
|
struct btf_member {
|
|
__u32 name_off;
|
|
__u32 type;
|
|
/* If the type info kind_flag is set, the btf_member offset
|
|
* contains both member bitfield size and bit offset. The
|
|
* bitfield size is set for bitfield members. If the type
|
|
* info kind_flag is not set, the offset contains only bit
|
|
* offset.
|
|
*/
|
|
__u32 offset;
|
|
};
|
|
|
|
/* If the struct/union type info kind_flag is set, the
|
|
* following two macros are used to access bitfield_size
|
|
* and bit_offset from btf_member.offset.
|
|
*/
|
|
#define BTF_MEMBER_BITFIELD_SIZE(val) ((val) >> 24)
|
|
#define BTF_MEMBER_BIT_OFFSET(val) ((val) & 0xffffff)
|
|
|
|
/* BTF_KIND_FUNC_PROTO is followed by multiple "struct btf_param".
|
|
* The exact number of btf_param is stored in the vlen (of the
|
|
* info in "struct btf_type").
|
|
*/
|
|
struct btf_param {
|
|
__u32 name_off;
|
|
__u32 type;
|
|
};
|
|
|
|
enum {
|
|
BTF_VAR_STATIC = 0,
|
|
BTF_VAR_GLOBAL_ALLOCATED = 1,
|
|
BTF_VAR_GLOBAL_EXTERN = 2,
|
|
};
|
|
|
|
enum btf_func_linkage {
|
|
BTF_FUNC_STATIC = 0,
|
|
BTF_FUNC_GLOBAL = 1,
|
|
BTF_FUNC_EXTERN = 2,
|
|
};
|
|
|
|
/* BTF_KIND_VAR is followed by a single "struct btf_var" to describe
|
|
* additional information related to the variable such as its linkage.
|
|
*/
|
|
struct btf_var {
|
|
__u32 linkage;
|
|
};
|
|
|
|
/* BTF_KIND_DATASEC is followed by multiple "struct btf_var_secinfo"
|
|
* to describe all BTF_KIND_VAR types it contains along with it's
|
|
* in-section offset as well as size.
|
|
*/
|
|
struct btf_var_secinfo {
|
|
__u32 type;
|
|
__u32 offset;
|
|
__u32 size;
|
|
};
|
|
|
|
/* BTF_KIND_DECL_TAG is followed by a single "struct btf_decl_tag" to describe
|
|
* additional information related to the tag applied location.
|
|
* If component_idx == -1, the tag is applied to a struct, union,
|
|
* variable or function. Otherwise, it is applied to a struct/union
|
|
* member or a func argument, and component_idx indicates which member
|
|
* or argument (0 ... vlen-1).
|
|
*/
|
|
struct btf_decl_tag {
|
|
__s32 component_idx;
|
|
};
|
|
|
|
/* BTF_KIND_ENUM64 is followed by multiple "struct btf_enum64".
|
|
* The exact number of btf_enum64 is stored in the vlen (of the
|
|
* info in "struct btf_type").
|
|
*/
|
|
struct btf_enum64 {
|
|
__u32 name_off;
|
|
__u32 val_lo32;
|
|
__u32 val_hi32;
|
|
};
|
|
|
|
#endif /* _UAPI__LINUX_BTF_H__ */
|