1119 lines
		
	
	
		
			37 KiB
		
	
	
	
		
			ReStructuredText
		
	
	
	
	
	
			
		
		
	
	
			1119 lines
		
	
	
		
			37 KiB
		
	
	
	
		
			ReStructuredText
		
	
	
	
	
	
| =====================
 | |
| BPF Type Format (BTF)
 | |
| =====================
 | |
| 
 | |
| 1. Introduction
 | |
| ===============
 | |
| 
 | |
| BTF (BPF Type Format) is the metadata format which encodes the debug info
 | |
| related to BPF program/map. The name BTF was used initially to describe data
 | |
| types. The BTF was later extended to include function info for defined
 | |
| subroutines, and line info for source/line information.
 | |
| 
 | |
| The debug info is used for map pretty print, function signature, etc. The
 | |
| function signature enables better bpf program/function kernel symbol. The line
 | |
| info helps generate source annotated translated byte code, jited code and
 | |
| verifier log.
 | |
| 
 | |
| The BTF specification contains two parts,
 | |
|   * BTF kernel API
 | |
|   * BTF ELF file format
 | |
| 
 | |
| The kernel API is the contract between user space and kernel. The kernel
 | |
| verifies the BTF info before using it. The ELF file format is a user space
 | |
| contract between ELF file and libbpf loader.
 | |
| 
 | |
| The type and string sections are part of the BTF kernel API, describing the
 | |
| debug info (mostly types related) referenced by the bpf program. These two
 | |
| sections are discussed in details in :ref:`BTF_Type_String`.
 | |
| 
 | |
| .. _BTF_Type_String:
 | |
| 
 | |
| 2. BTF Type and String Encoding
 | |
| ===============================
 | |
| 
 | |
| The file ``include/uapi/linux/btf.h`` provides high-level definition of how
 | |
| types/strings are encoded.
 | |
| 
 | |
| The beginning of data blob must be::
 | |
| 
 | |
|     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     */
 | |
|     };
 | |
| 
 | |
| The magic is ``0xeB9F``, which has different encoding for big and little
 | |
| endian systems, and can be used to test whether BTF is generated for big- or
 | |
| little-endian target. The ``btf_header`` is designed to be extensible with
 | |
| ``hdr_len`` equal to ``sizeof(struct btf_header)`` when a data blob is
 | |
| generated.
 | |
| 
 | |
| 2.1 String Encoding
 | |
| -------------------
 | |
| 
 | |
| The first string in the string section must be a null string. The rest of
 | |
| string table is a concatenation of other null-terminated strings.
 | |
| 
 | |
| 2.2 Type Encoding
 | |
| -----------------
 | |
| 
 | |
| The type id ``0`` is reserved for ``void`` type. The type section is parsed
 | |
| sequentially and type id is assigned to each recognized type starting from id
 | |
| ``1``. Currently, the following types are supported::
 | |
| 
 | |
|     #define BTF_KIND_INT            1       /* Integer      */
 | |
|     #define BTF_KIND_PTR            2       /* Pointer      */
 | |
|     #define BTF_KIND_ARRAY          3       /* Array        */
 | |
|     #define BTF_KIND_STRUCT         4       /* Struct       */
 | |
|     #define BTF_KIND_UNION          5       /* Union        */
 | |
|     #define BTF_KIND_ENUM           6       /* Enumeration up to 32-bit values */
 | |
|     #define BTF_KIND_FWD            7       /* Forward      */
 | |
|     #define BTF_KIND_TYPEDEF        8       /* Typedef      */
 | |
|     #define BTF_KIND_VOLATILE       9       /* Volatile     */
 | |
|     #define BTF_KIND_CONST          10      /* Const        */
 | |
|     #define BTF_KIND_RESTRICT       11      /* Restrict     */
 | |
|     #define BTF_KIND_FUNC           12      /* Function     */
 | |
|     #define BTF_KIND_FUNC_PROTO     13      /* Function Proto       */
 | |
|     #define BTF_KIND_VAR            14      /* Variable     */
 | |
|     #define BTF_KIND_DATASEC        15      /* Section      */
 | |
|     #define BTF_KIND_FLOAT          16      /* Floating point       */
 | |
|     #define BTF_KIND_DECL_TAG       17      /* Decl Tag     */
 | |
|     #define BTF_KIND_TYPE_TAG       18      /* Type Tag     */
 | |
|     #define BTF_KIND_ENUM64         19      /* Enumeration up to 64-bit values */
 | |
| 
 | |
| Note that the type section encodes debug info, not just pure types.
 | |
| ``BTF_KIND_FUNC`` is not a type, and it represents a defined subprogram.
 | |
| 
 | |
| Each type contains the following common data::
 | |
| 
 | |
|     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, fwd, enum and enum64.
 | |
|          */
 | |
|         __u32 info;
 | |
|         /* "size" is used by INT, ENUM, STRUCT, UNION and ENUM64.
 | |
|          * "size" tells the size of the type it is describing.
 | |
|          *
 | |
|          * "type" is used by PTR, TYPEDEF, VOLATILE, CONST, RESTRICT,
 | |
|          * FUNC, FUNC_PROTO, DECL_TAG and TYPE_TAG.
 | |
|          * "type" is a type_id referring to another type.
 | |
|          */
 | |
|         union {
 | |
|                 __u32 size;
 | |
|                 __u32 type;
 | |
|         };
 | |
|     };
 | |
| 
 | |
| For certain kinds, the common data are followed by kind-specific data. The
 | |
| ``name_off`` in ``struct btf_type`` specifies the offset in the string table.
 | |
| The following sections detail encoding of each kind.
 | |
| 
 | |
| 2.2.1 BTF_KIND_INT
 | |
| ~~~~~~~~~~~~~~~~~~
 | |
| 
 | |
| ``struct btf_type`` encoding requirement:
 | |
|  * ``name_off``: any valid offset
 | |
|  * ``info.kind_flag``: 0
 | |
|  * ``info.kind``: BTF_KIND_INT
 | |
|  * ``info.vlen``: 0
 | |
|  * ``size``: the size of the int type in bytes.
 | |
| 
 | |
| ``btf_type`` is followed by a ``u32`` with the following 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)
 | |
| 
 | |
| The ``BTF_INT_ENCODING`` has the following attributes::
 | |
| 
 | |
|   #define BTF_INT_SIGNED  (1 << 0)
 | |
|   #define BTF_INT_CHAR    (1 << 1)
 | |
|   #define BTF_INT_BOOL    (1 << 2)
 | |
| 
 | |
| The ``BTF_INT_ENCODING()`` provides extra information: signedness, char, or
 | |
| bool, for the int type. The char and bool encoding are mostly useful for
 | |
| pretty print. At most one encoding can be specified for the int type.
 | |
| 
 | |
| The ``BTF_INT_BITS()`` specifies the number of actual bits held by this int
 | |
| type. For example, a 4-bit bitfield encodes ``BTF_INT_BITS()`` equals to 4.
 | |
| The ``btf_type.size * 8`` must be equal to or greater than ``BTF_INT_BITS()``
 | |
| for the type. The maximum value of ``BTF_INT_BITS()`` is 128.
 | |
| 
 | |
| The ``BTF_INT_OFFSET()`` specifies the starting bit offset to calculate values
 | |
| for this int. For example, a bitfield struct member has:
 | |
| 
 | |
|  * btf member bit offset 100 from the start of the structure,
 | |
|  * btf member pointing to an int type,
 | |
|  * the int type has ``BTF_INT_OFFSET() = 2`` and ``BTF_INT_BITS() = 4``
 | |
| 
 | |
| Then in the struct memory layout, this member will occupy ``4`` bits starting
 | |
| from bits ``100 + 2 = 102``.
 | |
| 
 | |
| Alternatively, the bitfield struct member can be the following to access the
 | |
| same bits as the above:
 | |
| 
 | |
|  * btf member bit offset 102,
 | |
|  * btf member pointing to an int type,
 | |
|  * the int type has ``BTF_INT_OFFSET() = 0`` and ``BTF_INT_BITS() = 4``
 | |
| 
 | |
| The original intention of ``BTF_INT_OFFSET()`` is to provide flexibility of
 | |
| bitfield encoding. Currently, both llvm and pahole generate
 | |
| ``BTF_INT_OFFSET() = 0`` for all int types.
 | |
| 
 | |
| 2.2.2 BTF_KIND_PTR
 | |
| ~~~~~~~~~~~~~~~~~~
 | |
| 
 | |
| ``struct btf_type`` encoding requirement:
 | |
|   * ``name_off``: 0
 | |
|   * ``info.kind_flag``: 0
 | |
|   * ``info.kind``: BTF_KIND_PTR
 | |
|   * ``info.vlen``: 0
 | |
|   * ``type``: the pointee type of the pointer
 | |
| 
 | |
| No additional type data follow ``btf_type``.
 | |
| 
 | |
| 2.2.3 BTF_KIND_ARRAY
 | |
| ~~~~~~~~~~~~~~~~~~~~
 | |
| 
 | |
| ``struct btf_type`` encoding requirement:
 | |
|   * ``name_off``: 0
 | |
|   * ``info.kind_flag``: 0
 | |
|   * ``info.kind``: BTF_KIND_ARRAY
 | |
|   * ``info.vlen``: 0
 | |
|   * ``size/type``: 0, not used
 | |
| 
 | |
| ``btf_type`` is followed by one ``struct btf_array``::
 | |
| 
 | |
|     struct btf_array {
 | |
|         __u32   type;
 | |
|         __u32   index_type;
 | |
|         __u32   nelems;
 | |
|     };
 | |
| 
 | |
| The ``struct btf_array`` encoding:
 | |
|   * ``type``: the element type
 | |
|   * ``index_type``: the index type
 | |
|   * ``nelems``: the number of elements for this array (``0`` is also allowed).
 | |
| 
 | |
| The ``index_type`` can be any regular int type (``u8``, ``u16``, ``u32``,
 | |
| ``u64``, ``unsigned __int128``). The original design of including
 | |
| ``index_type`` follows DWARF, which has an ``index_type`` for its array type.
 | |
| Currently in BTF, beyond type verification, the ``index_type`` is not used.
 | |
| 
 | |
| The ``struct btf_array`` allows chaining through element type to represent
 | |
| multidimensional arrays. For example, for ``int a[5][6]``, the following type
 | |
| information illustrates the chaining:
 | |
| 
 | |
|   * [1]: int
 | |
|   * [2]: array, ``btf_array.type = [1]``, ``btf_array.nelems = 6``
 | |
|   * [3]: array, ``btf_array.type = [2]``, ``btf_array.nelems = 5``
 | |
| 
 | |
| Currently, both pahole and llvm collapse multidimensional array into
 | |
| one-dimensional array, e.g., for ``a[5][6]``, the ``btf_array.nelems`` is
 | |
| equal to ``30``. This is because the original use case is map pretty print
 | |
| where the whole array is dumped out so one-dimensional array is enough. As
 | |
| more BTF usage is explored, pahole and llvm can be changed to generate proper
 | |
| chained representation for multidimensional arrays.
 | |
| 
 | |
| 2.2.4 BTF_KIND_STRUCT
 | |
| ~~~~~~~~~~~~~~~~~~~~~
 | |
| 2.2.5 BTF_KIND_UNION
 | |
| ~~~~~~~~~~~~~~~~~~~~
 | |
| 
 | |
| ``struct btf_type`` encoding requirement:
 | |
|   * ``name_off``: 0 or offset to a valid C identifier
 | |
|   * ``info.kind_flag``: 0 or 1
 | |
|   * ``info.kind``: BTF_KIND_STRUCT or BTF_KIND_UNION
 | |
|   * ``info.vlen``: the number of struct/union members
 | |
|   * ``info.size``: the size of the struct/union in bytes
 | |
| 
 | |
| ``btf_type`` is followed by ``info.vlen`` number of ``struct btf_member``.::
 | |
| 
 | |
|     struct btf_member {
 | |
|         __u32   name_off;
 | |
|         __u32   type;
 | |
|         __u32   offset;
 | |
|     };
 | |
| 
 | |
| ``struct btf_member`` encoding:
 | |
|   * ``name_off``: offset to a valid C identifier
 | |
|   * ``type``: the member type
 | |
|   * ``offset``: <see below>
 | |
| 
 | |
| If the type info ``kind_flag`` is not set, the offset contains only bit offset
 | |
| of the member. Note that the base type of the bitfield can only be int or enum
 | |
| type. If the bitfield size is 32, the base type can be either int or enum
 | |
| type. If the bitfield size is not 32, the base type must be int, and int type
 | |
| ``BTF_INT_BITS()`` encodes the bitfield size.
 | |
| 
 | |
| If the ``kind_flag`` is set, the ``btf_member.offset`` contains both member
 | |
| bitfield size and bit offset. The bitfield size and bit offset are calculated
 | |
| as below.::
 | |
| 
 | |
|   #define BTF_MEMBER_BITFIELD_SIZE(val)   ((val) >> 24)
 | |
|   #define BTF_MEMBER_BIT_OFFSET(val)      ((val) & 0xffffff)
 | |
| 
 | |
| In this case, if the base type is an int type, it must be a regular int type:
 | |
| 
 | |
|   * ``BTF_INT_OFFSET()`` must be 0.
 | |
|   * ``BTF_INT_BITS()`` must be equal to ``{1,2,4,8,16} * 8``.
 | |
| 
 | |
| Commit 9d5f9f701b18 introduced ``kind_flag`` and explains why both modes
 | |
| exist.
 | |
| 
 | |
| 2.2.6 BTF_KIND_ENUM
 | |
| ~~~~~~~~~~~~~~~~~~~
 | |
| 
 | |
| ``struct btf_type`` encoding requirement:
 | |
|   * ``name_off``: 0 or offset to a valid C identifier
 | |
|   * ``info.kind_flag``: 0 for unsigned, 1 for signed
 | |
|   * ``info.kind``: BTF_KIND_ENUM
 | |
|   * ``info.vlen``: number of enum values
 | |
|   * ``size``: 1/2/4/8
 | |
| 
 | |
| ``btf_type`` is followed by ``info.vlen`` number of ``struct btf_enum``.::
 | |
| 
 | |
|     struct btf_enum {
 | |
|         __u32   name_off;
 | |
|         __s32   val;
 | |
|     };
 | |
| 
 | |
| The ``btf_enum`` encoding:
 | |
|   * ``name_off``: offset to a valid C identifier
 | |
|   * ``val``: any value
 | |
| 
 | |
| If the original enum value is signed and the size is less than 4,
 | |
| that value will be sign extended into 4 bytes. If the size is 8,
 | |
| the value will be truncated into 4 bytes.
 | |
| 
 | |
| 2.2.7 BTF_KIND_FWD
 | |
| ~~~~~~~~~~~~~~~~~~
 | |
| 
 | |
| ``struct btf_type`` encoding requirement:
 | |
|   * ``name_off``: offset to a valid C identifier
 | |
|   * ``info.kind_flag``: 0 for struct, 1 for union
 | |
|   * ``info.kind``: BTF_KIND_FWD
 | |
|   * ``info.vlen``: 0
 | |
|   * ``type``: 0
 | |
| 
 | |
| No additional type data follow ``btf_type``.
 | |
| 
 | |
| 2.2.8 BTF_KIND_TYPEDEF
 | |
| ~~~~~~~~~~~~~~~~~~~~~~
 | |
| 
 | |
| ``struct btf_type`` encoding requirement:
 | |
|   * ``name_off``: offset to a valid C identifier
 | |
|   * ``info.kind_flag``: 0
 | |
|   * ``info.kind``: BTF_KIND_TYPEDEF
 | |
|   * ``info.vlen``: 0
 | |
|   * ``type``: the type which can be referred by name at ``name_off``
 | |
| 
 | |
| No additional type data follow ``btf_type``.
 | |
| 
 | |
| 2.2.9 BTF_KIND_VOLATILE
 | |
| ~~~~~~~~~~~~~~~~~~~~~~~
 | |
| 
 | |
| ``struct btf_type`` encoding requirement:
 | |
|   * ``name_off``: 0
 | |
|   * ``info.kind_flag``: 0
 | |
|   * ``info.kind``: BTF_KIND_VOLATILE
 | |
|   * ``info.vlen``: 0
 | |
|   * ``type``: the type with ``volatile`` qualifier
 | |
| 
 | |
| No additional type data follow ``btf_type``.
 | |
| 
 | |
| 2.2.10 BTF_KIND_CONST
 | |
| ~~~~~~~~~~~~~~~~~~~~~
 | |
| 
 | |
| ``struct btf_type`` encoding requirement:
 | |
|   * ``name_off``: 0
 | |
|   * ``info.kind_flag``: 0
 | |
|   * ``info.kind``: BTF_KIND_CONST
 | |
|   * ``info.vlen``: 0
 | |
|   * ``type``: the type with ``const`` qualifier
 | |
| 
 | |
| No additional type data follow ``btf_type``.
 | |
| 
 | |
| 2.2.11 BTF_KIND_RESTRICT
 | |
| ~~~~~~~~~~~~~~~~~~~~~~~~
 | |
| 
 | |
| ``struct btf_type`` encoding requirement:
 | |
|   * ``name_off``: 0
 | |
|   * ``info.kind_flag``: 0
 | |
|   * ``info.kind``: BTF_KIND_RESTRICT
 | |
|   * ``info.vlen``: 0
 | |
|   * ``type``: the type with ``restrict`` qualifier
 | |
| 
 | |
| No additional type data follow ``btf_type``.
 | |
| 
 | |
| 2.2.12 BTF_KIND_FUNC
 | |
| ~~~~~~~~~~~~~~~~~~~~
 | |
| 
 | |
| ``struct btf_type`` encoding requirement:
 | |
|   * ``name_off``: offset to a valid C identifier
 | |
|   * ``info.kind_flag``: 0
 | |
|   * ``info.kind``: BTF_KIND_FUNC
 | |
|   * ``info.vlen``: linkage information (BTF_FUNC_STATIC, BTF_FUNC_GLOBAL
 | |
|                    or BTF_FUNC_EXTERN - see :ref:`BTF_Function_Linkage_Constants`)
 | |
|   * ``type``: a BTF_KIND_FUNC_PROTO type
 | |
| 
 | |
| No additional type data follow ``btf_type``.
 | |
| 
 | |
| A BTF_KIND_FUNC defines not a type, but a subprogram (function) whose
 | |
| signature is defined by ``type``. The subprogram is thus an instance of that
 | |
| type. The BTF_KIND_FUNC may in turn be referenced by a func_info in the
 | |
| :ref:`BTF_Ext_Section` (ELF) or in the arguments to :ref:`BPF_Prog_Load`
 | |
| (ABI).
 | |
| 
 | |
| Currently, only linkage values of BTF_FUNC_STATIC and BTF_FUNC_GLOBAL are
 | |
| supported in the kernel.
 | |
| 
 | |
| 2.2.13 BTF_KIND_FUNC_PROTO
 | |
| ~~~~~~~~~~~~~~~~~~~~~~~~~~
 | |
| 
 | |
| ``struct btf_type`` encoding requirement:
 | |
|   * ``name_off``: 0
 | |
|   * ``info.kind_flag``: 0
 | |
|   * ``info.kind``: BTF_KIND_FUNC_PROTO
 | |
|   * ``info.vlen``: # of parameters
 | |
|   * ``type``: the return type
 | |
| 
 | |
| ``btf_type`` is followed by ``info.vlen`` number of ``struct btf_param``.::
 | |
| 
 | |
|     struct btf_param {
 | |
|         __u32   name_off;
 | |
|         __u32   type;
 | |
|     };
 | |
| 
 | |
| If a BTF_KIND_FUNC_PROTO type is referred by a BTF_KIND_FUNC type, then
 | |
| ``btf_param.name_off`` must point to a valid C identifier except for the
 | |
| possible last argument representing the variable argument. The btf_param.type
 | |
| refers to parameter type.
 | |
| 
 | |
| If the function has variable arguments, the last parameter is encoded with
 | |
| ``name_off = 0`` and ``type = 0``.
 | |
| 
 | |
| 2.2.14 BTF_KIND_VAR
 | |
| ~~~~~~~~~~~~~~~~~~~
 | |
| 
 | |
| ``struct btf_type`` encoding requirement:
 | |
|   * ``name_off``: offset to a valid C identifier
 | |
|   * ``info.kind_flag``: 0
 | |
|   * ``info.kind``: BTF_KIND_VAR
 | |
|   * ``info.vlen``: 0
 | |
|   * ``type``: the type of the variable
 | |
| 
 | |
| ``btf_type`` is followed by a single ``struct btf_variable`` with the
 | |
| following data::
 | |
| 
 | |
|     struct btf_var {
 | |
|         __u32   linkage;
 | |
|     };
 | |
| 
 | |
| ``btf_var.linkage`` may take the values: BTF_VAR_STATIC, BTF_VAR_GLOBAL_ALLOCATED or BTF_VAR_GLOBAL_EXTERN -
 | |
| see :ref:`BTF_Var_Linkage_Constants`.
 | |
| 
 | |
| Not all type of global variables are supported by LLVM at this point.
 | |
| The following is currently available:
 | |
| 
 | |
|   * static variables with or without section attributes
 | |
|   * global variables with section attributes
 | |
| 
 | |
| The latter is for future extraction of map key/value type id's from a
 | |
| map definition.
 | |
| 
 | |
| 2.2.15 BTF_KIND_DATASEC
 | |
| ~~~~~~~~~~~~~~~~~~~~~~~
 | |
| 
 | |
| ``struct btf_type`` encoding requirement:
 | |
|   * ``name_off``: offset to a valid name associated with a variable or
 | |
|                   one of .data/.bss/.rodata
 | |
|   * ``info.kind_flag``: 0
 | |
|   * ``info.kind``: BTF_KIND_DATASEC
 | |
|   * ``info.vlen``: # of variables
 | |
|   * ``size``: total section size in bytes (0 at compilation time, patched
 | |
|               to actual size by BPF loaders such as libbpf)
 | |
| 
 | |
| ``btf_type`` is followed by ``info.vlen`` number of ``struct btf_var_secinfo``.::
 | |
| 
 | |
|     struct btf_var_secinfo {
 | |
|         __u32   type;
 | |
|         __u32   offset;
 | |
|         __u32   size;
 | |
|     };
 | |
| 
 | |
| ``struct btf_var_secinfo`` encoding:
 | |
|   * ``type``: the type of the BTF_KIND_VAR variable
 | |
|   * ``offset``: the in-section offset of the variable
 | |
|   * ``size``: the size of the variable in bytes
 | |
| 
 | |
| 2.2.16 BTF_KIND_FLOAT
 | |
| ~~~~~~~~~~~~~~~~~~~~~
 | |
| 
 | |
| ``struct btf_type`` encoding requirement:
 | |
|  * ``name_off``: any valid offset
 | |
|  * ``info.kind_flag``: 0
 | |
|  * ``info.kind``: BTF_KIND_FLOAT
 | |
|  * ``info.vlen``: 0
 | |
|  * ``size``: the size of the float type in bytes: 2, 4, 8, 12 or 16.
 | |
| 
 | |
| No additional type data follow ``btf_type``.
 | |
| 
 | |
| 2.2.17 BTF_KIND_DECL_TAG
 | |
| ~~~~~~~~~~~~~~~~~~~~~~~~
 | |
| 
 | |
| ``struct btf_type`` encoding requirement:
 | |
|  * ``name_off``: offset to a non-empty string
 | |
|  * ``info.kind_flag``: 0
 | |
|  * ``info.kind``: BTF_KIND_DECL_TAG
 | |
|  * ``info.vlen``: 0
 | |
|  * ``type``: ``struct``, ``union``, ``func``, ``var`` or ``typedef``
 | |
| 
 | |
| ``btf_type`` is followed by ``struct btf_decl_tag``.::
 | |
| 
 | |
|     struct btf_decl_tag {
 | |
|         __u32   component_idx;
 | |
|     };
 | |
| 
 | |
| The ``name_off`` encodes btf_decl_tag attribute string.
 | |
| The ``type`` should be ``struct``, ``union``, ``func``, ``var`` or ``typedef``.
 | |
| For ``var`` or ``typedef`` type, ``btf_decl_tag.component_idx`` must be ``-1``.
 | |
| For the other three types, if the btf_decl_tag attribute is
 | |
| applied to the ``struct``, ``union`` or ``func`` itself,
 | |
| ``btf_decl_tag.component_idx`` must be ``-1``. Otherwise,
 | |
| the attribute is applied to a ``struct``/``union`` member or
 | |
| a ``func`` argument, and ``btf_decl_tag.component_idx`` should be a
 | |
| valid index (starting from 0) pointing to a member or an argument.
 | |
| 
 | |
| 2.2.18 BTF_KIND_TYPE_TAG
 | |
| ~~~~~~~~~~~~~~~~~~~~~~~~
 | |
| 
 | |
| ``struct btf_type`` encoding requirement:
 | |
|  * ``name_off``: offset to a non-empty string
 | |
|  * ``info.kind_flag``: 0
 | |
|  * ``info.kind``: BTF_KIND_TYPE_TAG
 | |
|  * ``info.vlen``: 0
 | |
|  * ``type``: the type with ``btf_type_tag`` attribute
 | |
| 
 | |
| Currently, ``BTF_KIND_TYPE_TAG`` is only emitted for pointer types.
 | |
| It has the following btf type chain:
 | |
| ::
 | |
| 
 | |
|   ptr -> [type_tag]*
 | |
|       -> [const | volatile | restrict | typedef]*
 | |
|       -> base_type
 | |
| 
 | |
| Basically, a pointer type points to zero or more
 | |
| type_tag, then zero or more const/volatile/restrict/typedef
 | |
| and finally the base type. The base type is one of
 | |
| int, ptr, array, struct, union, enum, func_proto and float types.
 | |
| 
 | |
| 2.2.19 BTF_KIND_ENUM64
 | |
| ~~~~~~~~~~~~~~~~~~~~~~
 | |
| 
 | |
| ``struct btf_type`` encoding requirement:
 | |
|   * ``name_off``: 0 or offset to a valid C identifier
 | |
|   * ``info.kind_flag``: 0 for unsigned, 1 for signed
 | |
|   * ``info.kind``: BTF_KIND_ENUM64
 | |
|   * ``info.vlen``: number of enum values
 | |
|   * ``size``: 1/2/4/8
 | |
| 
 | |
| ``btf_type`` is followed by ``info.vlen`` number of ``struct btf_enum64``.::
 | |
| 
 | |
|     struct btf_enum64 {
 | |
|         __u32   name_off;
 | |
|         __u32   val_lo32;
 | |
|         __u32   val_hi32;
 | |
|     };
 | |
| 
 | |
| The ``btf_enum64`` encoding:
 | |
|   * ``name_off``: offset to a valid C identifier
 | |
|   * ``val_lo32``: lower 32-bit value for a 64-bit value
 | |
|   * ``val_hi32``: high 32-bit value for a 64-bit value
 | |
| 
 | |
| If the original enum value is signed and the size is less than 8,
 | |
| that value will be sign extended into 8 bytes.
 | |
| 
 | |
| 2.3 Constant Values
 | |
| -------------------
 | |
| 
 | |
| .. _BTF_Function_Linkage_Constants:
 | |
| 
 | |
| 2.3.1 Function Linkage Constant Values
 | |
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 | |
| .. table:: Function Linkage Values and Meanings
 | |
| 
 | |
|   ===================  =====  ===========
 | |
|   kind                 value  description
 | |
|   ===================  =====  ===========
 | |
|   ``BTF_FUNC_STATIC``  0x0    definition of subprogram not visible outside containing compilation unit
 | |
|   ``BTF_FUNC_GLOBAL``  0x1    definition of subprogram visible outside containing compilation unit
 | |
|   ``BTF_FUNC_EXTERN``  0x2    declaration of a subprogram whose definition is outside the containing compilation unit
 | |
|   ===================  =====  ===========
 | |
| 
 | |
| 
 | |
| .. _BTF_Var_Linkage_Constants:
 | |
| 
 | |
| 2.3.2 Variable Linkage Constant Values
 | |
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 | |
| .. table:: Variable Linkage Values and Meanings
 | |
| 
 | |
|   ============================  =====  ===========
 | |
|   kind                          value  description
 | |
|   ============================  =====  ===========
 | |
|   ``BTF_VAR_STATIC``            0x0    definition of global variable not visible outside containing compilation unit
 | |
|   ``BTF_VAR_GLOBAL_ALLOCATED``  0x1    definition of global variable visible outside containing compilation unit
 | |
|   ``BTF_VAR_GLOBAL_EXTERN``     0x2    declaration of global variable whose definition is outside the containing compilation unit
 | |
|   ============================  =====  ===========
 | |
| 
 | |
| 3. BTF Kernel API
 | |
| =================
 | |
| 
 | |
| The following bpf syscall command involves BTF:
 | |
|    * BPF_BTF_LOAD: load a blob of BTF data into kernel
 | |
|    * BPF_MAP_CREATE: map creation with btf key and value type info.
 | |
|    * BPF_PROG_LOAD: prog load with btf function and line info.
 | |
|    * BPF_BTF_GET_FD_BY_ID: get a btf fd
 | |
|    * BPF_OBJ_GET_INFO_BY_FD: btf, func_info, line_info
 | |
|      and other btf related info are returned.
 | |
| 
 | |
| The workflow typically looks like:
 | |
| ::
 | |
| 
 | |
|   Application:
 | |
|       BPF_BTF_LOAD
 | |
|           |
 | |
|           v
 | |
|       BPF_MAP_CREATE and BPF_PROG_LOAD
 | |
|           |
 | |
|           V
 | |
|       ......
 | |
| 
 | |
|   Introspection tool:
 | |
|       ......
 | |
|       BPF_{PROG,MAP}_GET_NEXT_ID (get prog/map id's)
 | |
|           |
 | |
|           V
 | |
|       BPF_{PROG,MAP}_GET_FD_BY_ID (get a prog/map fd)
 | |
|           |
 | |
|           V
 | |
|       BPF_OBJ_GET_INFO_BY_FD (get bpf_prog_info/bpf_map_info with btf_id)
 | |
|           |                                     |
 | |
|           V                                     |
 | |
|       BPF_BTF_GET_FD_BY_ID (get btf_fd)         |
 | |
|           |                                     |
 | |
|           V                                     |
 | |
|       BPF_OBJ_GET_INFO_BY_FD (get btf)          |
 | |
|           |                                     |
 | |
|           V                                     V
 | |
|       pretty print types, dump func signatures and line info, etc.
 | |
| 
 | |
| 
 | |
| 3.1 BPF_BTF_LOAD
 | |
| ----------------
 | |
| 
 | |
| Load a blob of BTF data into kernel. A blob of data, described in
 | |
| :ref:`BTF_Type_String`, can be directly loaded into the kernel. A ``btf_fd``
 | |
| is returned to a userspace.
 | |
| 
 | |
| 3.2 BPF_MAP_CREATE
 | |
| ------------------
 | |
| 
 | |
| A map can be created with ``btf_fd`` and specified key/value type id.::
 | |
| 
 | |
|     __u32   btf_fd;         /* fd pointing to a BTF type data */
 | |
|     __u32   btf_key_type_id;        /* BTF type_id of the key */
 | |
|     __u32   btf_value_type_id;      /* BTF type_id of the value */
 | |
| 
 | |
| In libbpf, the map can be defined with extra annotation like below:
 | |
| ::
 | |
| 
 | |
|     struct {
 | |
|         __uint(type, BPF_MAP_TYPE_ARRAY);
 | |
|         __type(key, int);
 | |
|         __type(value, struct ipv_counts);
 | |
|         __uint(max_entries, 4);
 | |
|     } btf_map SEC(".maps");
 | |
| 
 | |
| During ELF parsing, libbpf is able to extract key/value type_id's and assign
 | |
| them to BPF_MAP_CREATE attributes automatically.
 | |
| 
 | |
| .. _BPF_Prog_Load:
 | |
| 
 | |
| 3.3 BPF_PROG_LOAD
 | |
| -----------------
 | |
| 
 | |
| During prog_load, func_info and line_info can be passed to kernel with proper
 | |
| values for the following attributes:
 | |
| ::
 | |
| 
 | |
|     __u32           insn_cnt;
 | |
|     __aligned_u64   insns;
 | |
|     ......
 | |
|     __u32           prog_btf_fd;    /* fd pointing to BTF type data */
 | |
|     __u32           func_info_rec_size;     /* userspace bpf_func_info size */
 | |
|     __aligned_u64   func_info;      /* func info */
 | |
|     __u32           func_info_cnt;  /* number of bpf_func_info records */
 | |
|     __u32           line_info_rec_size;     /* userspace bpf_line_info size */
 | |
|     __aligned_u64   line_info;      /* line info */
 | |
|     __u32           line_info_cnt;  /* number of bpf_line_info records */
 | |
| 
 | |
| The func_info and line_info are an array of below, respectively.::
 | |
| 
 | |
|     struct bpf_func_info {
 | |
|         __u32   insn_off; /* [0, insn_cnt - 1] */
 | |
|         __u32   type_id;  /* pointing to a BTF_KIND_FUNC type */
 | |
|     };
 | |
|     struct bpf_line_info {
 | |
|         __u32   insn_off; /* [0, insn_cnt - 1] */
 | |
|         __u32   file_name_off; /* offset to string table for the filename */
 | |
|         __u32   line_off; /* offset to string table for the source line */
 | |
|         __u32   line_col; /* line number and column number */
 | |
|     };
 | |
| 
 | |
| func_info_rec_size is the size of each func_info record, and
 | |
| line_info_rec_size is the size of each line_info record. Passing the record
 | |
| size to kernel make it possible to extend the record itself in the future.
 | |
| 
 | |
| Below are requirements for func_info:
 | |
|   * func_info[0].insn_off must be 0.
 | |
|   * the func_info insn_off is in strictly increasing order and matches
 | |
|     bpf func boundaries.
 | |
| 
 | |
| Below are requirements for line_info:
 | |
|   * the first insn in each func must have a line_info record pointing to it.
 | |
|   * the line_info insn_off is in strictly increasing order.
 | |
| 
 | |
| For line_info, the line number and column number are defined as below:
 | |
| ::
 | |
| 
 | |
|     #define BPF_LINE_INFO_LINE_NUM(line_col)        ((line_col) >> 10)
 | |
|     #define BPF_LINE_INFO_LINE_COL(line_col)        ((line_col) & 0x3ff)
 | |
| 
 | |
| 3.4 BPF_{PROG,MAP}_GET_NEXT_ID
 | |
| ------------------------------
 | |
| 
 | |
| In kernel, every loaded program, map or btf has a unique id. The id won't
 | |
| change during the lifetime of a program, map, or btf.
 | |
| 
 | |
| The bpf syscall command BPF_{PROG,MAP}_GET_NEXT_ID returns all id's, one for
 | |
| each command, to user space, for bpf program or maps, respectively, so an
 | |
| inspection tool can inspect all programs and maps.
 | |
| 
 | |
| 3.5 BPF_{PROG,MAP}_GET_FD_BY_ID
 | |
| -------------------------------
 | |
| 
 | |
| An introspection tool cannot use id to get details about program or maps.
 | |
| A file descriptor needs to be obtained first for reference-counting purpose.
 | |
| 
 | |
| 3.6 BPF_OBJ_GET_INFO_BY_FD
 | |
| --------------------------
 | |
| 
 | |
| Once a program/map fd is acquired, an introspection tool can get the detailed
 | |
| information from kernel about this fd, some of which are BTF-related. For
 | |
| example, ``bpf_map_info`` returns ``btf_id`` and key/value type ids.
 | |
| ``bpf_prog_info`` returns ``btf_id``, func_info, and line info for translated
 | |
| bpf byte codes, and jited_line_info.
 | |
| 
 | |
| 3.7 BPF_BTF_GET_FD_BY_ID
 | |
| ------------------------
 | |
| 
 | |
| With ``btf_id`` obtained in ``bpf_map_info`` and ``bpf_prog_info``, bpf
 | |
| syscall command BPF_BTF_GET_FD_BY_ID can retrieve a btf fd. Then, with
 | |
| command BPF_OBJ_GET_INFO_BY_FD, the btf blob, originally loaded into the
 | |
| kernel with BPF_BTF_LOAD, can be retrieved.
 | |
| 
 | |
| With the btf blob, ``bpf_map_info``, and ``bpf_prog_info``, an introspection
 | |
| tool has full btf knowledge and is able to pretty print map key/values, dump
 | |
| func signatures and line info, along with byte/jit codes.
 | |
| 
 | |
| 4. ELF File Format Interface
 | |
| ============================
 | |
| 
 | |
| 4.1 .BTF section
 | |
| ----------------
 | |
| 
 | |
| The .BTF section contains type and string data. The format of this section is
 | |
| same as the one describe in :ref:`BTF_Type_String`.
 | |
| 
 | |
| .. _BTF_Ext_Section:
 | |
| 
 | |
| 4.2 .BTF.ext section
 | |
| --------------------
 | |
| 
 | |
| The .BTF.ext section encodes func_info, line_info and CO-RE relocations
 | |
| which needs loader manipulation before loading into the kernel.
 | |
| 
 | |
| The specification for .BTF.ext section is defined at ``tools/lib/bpf/btf.h``
 | |
| and ``tools/lib/bpf/btf.c``.
 | |
| 
 | |
| The current header of .BTF.ext section::
 | |
| 
 | |
|     struct btf_ext_header {
 | |
|         __u16   magic;
 | |
|         __u8    version;
 | |
|         __u8    flags;
 | |
|         __u32   hdr_len;
 | |
| 
 | |
|         /* All offsets are in bytes relative to the end of this header */
 | |
|         __u32   func_info_off;
 | |
|         __u32   func_info_len;
 | |
|         __u32   line_info_off;
 | |
|         __u32   line_info_len;
 | |
| 
 | |
|         /* optional part of .BTF.ext header */
 | |
|         __u32   core_relo_off;
 | |
|         __u32   core_relo_len;
 | |
|     };
 | |
| 
 | |
| It is very similar to .BTF section. Instead of type/string section, it
 | |
| contains func_info, line_info and core_relo sub-sections.
 | |
| See :ref:`BPF_Prog_Load` for details about func_info and line_info
 | |
| record format.
 | |
| 
 | |
| The func_info is organized as below.::
 | |
| 
 | |
|      func_info_rec_size              /* __u32 value */
 | |
|      btf_ext_info_sec for section #1 /* func_info for section #1 */
 | |
|      btf_ext_info_sec for section #2 /* func_info for section #2 */
 | |
|      ...
 | |
| 
 | |
| ``func_info_rec_size`` specifies the size of ``bpf_func_info`` structure when
 | |
| .BTF.ext is generated. ``btf_ext_info_sec``, defined below, is a collection of
 | |
| func_info for each specific ELF section.::
 | |
| 
 | |
|      struct btf_ext_info_sec {
 | |
|         __u32   sec_name_off; /* offset to section name */
 | |
|         __u32   num_info;
 | |
|         /* Followed by num_info * record_size number of bytes */
 | |
|         __u8    data[0];
 | |
|      };
 | |
| 
 | |
| Here, num_info must be greater than 0.
 | |
| 
 | |
| The line_info is organized as below.::
 | |
| 
 | |
|      line_info_rec_size              /* __u32 value */
 | |
|      btf_ext_info_sec for section #1 /* line_info for section #1 */
 | |
|      btf_ext_info_sec for section #2 /* line_info for section #2 */
 | |
|      ...
 | |
| 
 | |
| ``line_info_rec_size`` specifies the size of ``bpf_line_info`` structure when
 | |
| .BTF.ext is generated.
 | |
| 
 | |
| The interpretation of ``bpf_func_info->insn_off`` and
 | |
| ``bpf_line_info->insn_off`` is different between kernel API and ELF API. For
 | |
| kernel API, the ``insn_off`` is the instruction offset in the unit of ``struct
 | |
| bpf_insn``. For ELF API, the ``insn_off`` is the byte offset from the
 | |
| beginning of section (``btf_ext_info_sec->sec_name_off``).
 | |
| 
 | |
| The core_relo is organized as below.::
 | |
| 
 | |
|      core_relo_rec_size              /* __u32 value */
 | |
|      btf_ext_info_sec for section #1 /* core_relo for section #1 */
 | |
|      btf_ext_info_sec for section #2 /* core_relo for section #2 */
 | |
| 
 | |
| ``core_relo_rec_size`` specifies the size of ``bpf_core_relo``
 | |
| structure when .BTF.ext is generated. All ``bpf_core_relo`` structures
 | |
| within a single ``btf_ext_info_sec`` describe relocations applied to
 | |
| section named by ``btf_ext_info_sec->sec_name_off``.
 | |
| 
 | |
| See :ref:`Documentation/bpf/llvm_reloc.rst <btf-co-re-relocations>`
 | |
| for more information on CO-RE relocations.
 | |
| 
 | |
| 4.2 .BTF_ids section
 | |
| --------------------
 | |
| 
 | |
| The .BTF_ids section encodes BTF ID values that are used within the kernel.
 | |
| 
 | |
| This section is created during the kernel compilation with the help of
 | |
| macros defined in ``include/linux/btf_ids.h`` header file. Kernel code can
 | |
| use them to create lists and sets (sorted lists) of BTF ID values.
 | |
| 
 | |
| The ``BTF_ID_LIST`` and ``BTF_ID`` macros define unsorted list of BTF ID values,
 | |
| with following syntax::
 | |
| 
 | |
|   BTF_ID_LIST(list)
 | |
|   BTF_ID(type1, name1)
 | |
|   BTF_ID(type2, name2)
 | |
| 
 | |
| resulting in following layout in .BTF_ids section::
 | |
| 
 | |
|   __BTF_ID__type1__name1__1:
 | |
|   .zero 4
 | |
|   __BTF_ID__type2__name2__2:
 | |
|   .zero 4
 | |
| 
 | |
| The ``u32 list[];`` variable is defined to access the list.
 | |
| 
 | |
| The ``BTF_ID_UNUSED`` macro defines 4 zero bytes. It's used when we
 | |
| want to define unused entry in BTF_ID_LIST, like::
 | |
| 
 | |
|       BTF_ID_LIST(bpf_skb_output_btf_ids)
 | |
|       BTF_ID(struct, sk_buff)
 | |
|       BTF_ID_UNUSED
 | |
|       BTF_ID(struct, task_struct)
 | |
| 
 | |
| The ``BTF_SET_START/END`` macros pair defines sorted list of BTF ID values
 | |
| and their count, with following syntax::
 | |
| 
 | |
|   BTF_SET_START(set)
 | |
|   BTF_ID(type1, name1)
 | |
|   BTF_ID(type2, name2)
 | |
|   BTF_SET_END(set)
 | |
| 
 | |
| resulting in following layout in .BTF_ids section::
 | |
| 
 | |
|   __BTF_ID__set__set:
 | |
|   .zero 4
 | |
|   __BTF_ID__type1__name1__3:
 | |
|   .zero 4
 | |
|   __BTF_ID__type2__name2__4:
 | |
|   .zero 4
 | |
| 
 | |
| The ``struct btf_id_set set;`` variable is defined to access the list.
 | |
| 
 | |
| The ``typeX`` name can be one of following::
 | |
| 
 | |
|    struct, union, typedef, func
 | |
| 
 | |
| and is used as a filter when resolving the BTF ID value.
 | |
| 
 | |
| All the BTF ID lists and sets are compiled in the .BTF_ids section and
 | |
| resolved during the linking phase of kernel build by ``resolve_btfids`` tool.
 | |
| 
 | |
| 5. Using BTF
 | |
| ============
 | |
| 
 | |
| 5.1 bpftool map pretty print
 | |
| ----------------------------
 | |
| 
 | |
| With BTF, the map key/value can be printed based on fields rather than simply
 | |
| raw bytes. This is especially valuable for large structure or if your data
 | |
| structure has bitfields. For example, for the following map,::
 | |
| 
 | |
|       enum A { A1, A2, A3, A4, A5 };
 | |
|       typedef enum A ___A;
 | |
|       struct tmp_t {
 | |
|            char a1:4;
 | |
|            int  a2:4;
 | |
|            int  :4;
 | |
|            __u32 a3:4;
 | |
|            int b;
 | |
|            ___A b1:4;
 | |
|            enum A b2:4;
 | |
|       };
 | |
|       struct {
 | |
|            __uint(type, BPF_MAP_TYPE_ARRAY);
 | |
|            __type(key, int);
 | |
|            __type(value, struct tmp_t);
 | |
|            __uint(max_entries, 1);
 | |
|       } tmpmap SEC(".maps");
 | |
| 
 | |
| bpftool is able to pretty print like below:
 | |
| ::
 | |
| 
 | |
|       [{
 | |
|             "key": 0,
 | |
|             "value": {
 | |
|                 "a1": 0x2,
 | |
|                 "a2": 0x4,
 | |
|                 "a3": 0x6,
 | |
|                 "b": 7,
 | |
|                 "b1": 0x8,
 | |
|                 "b2": 0xa
 | |
|             }
 | |
|         }
 | |
|       ]
 | |
| 
 | |
| 5.2 bpftool prog dump
 | |
| ---------------------
 | |
| 
 | |
| The following is an example showing how func_info and line_info can help prog
 | |
| dump with better kernel symbol names, function prototypes and line
 | |
| information.::
 | |
| 
 | |
|     $ bpftool prog dump jited pinned /sys/fs/bpf/test_btf_haskv
 | |
|     [...]
 | |
|     int test_long_fname_2(struct dummy_tracepoint_args * arg):
 | |
|     bpf_prog_44a040bf25481309_test_long_fname_2:
 | |
|     ; static int test_long_fname_2(struct dummy_tracepoint_args *arg)
 | |
|        0:   push   %rbp
 | |
|        1:   mov    %rsp,%rbp
 | |
|        4:   sub    $0x30,%rsp
 | |
|        b:   sub    $0x28,%rbp
 | |
|        f:   mov    %rbx,0x0(%rbp)
 | |
|       13:   mov    %r13,0x8(%rbp)
 | |
|       17:   mov    %r14,0x10(%rbp)
 | |
|       1b:   mov    %r15,0x18(%rbp)
 | |
|       1f:   xor    %eax,%eax
 | |
|       21:   mov    %rax,0x20(%rbp)
 | |
|       25:   xor    %esi,%esi
 | |
|     ; int key = 0;
 | |
|       27:   mov    %esi,-0x4(%rbp)
 | |
|     ; if (!arg->sock)
 | |
|       2a:   mov    0x8(%rdi),%rdi
 | |
|     ; if (!arg->sock)
 | |
|       2e:   cmp    $0x0,%rdi
 | |
|       32:   je     0x0000000000000070
 | |
|       34:   mov    %rbp,%rsi
 | |
|     ; counts = bpf_map_lookup_elem(&btf_map, &key);
 | |
|     [...]
 | |
| 
 | |
| 5.3 Verifier Log
 | |
| ----------------
 | |
| 
 | |
| The following is an example of how line_info can help debugging verification
 | |
| failure.::
 | |
| 
 | |
|        /* The code at tools/testing/selftests/bpf/test_xdp_noinline.c
 | |
|         * is modified as below.
 | |
|         */
 | |
|        data = (void *)(long)xdp->data;
 | |
|        data_end = (void *)(long)xdp->data_end;
 | |
|        /*
 | |
|        if (data + 4 > data_end)
 | |
|                return XDP_DROP;
 | |
|        */
 | |
|        *(u32 *)data = dst->dst;
 | |
| 
 | |
|     $ bpftool prog load ./test_xdp_noinline.o /sys/fs/bpf/test_xdp_noinline type xdp
 | |
|         ; data = (void *)(long)xdp->data;
 | |
|         224: (79) r2 = *(u64 *)(r10 -112)
 | |
|         225: (61) r2 = *(u32 *)(r2 +0)
 | |
|         ; *(u32 *)data = dst->dst;
 | |
|         226: (63) *(u32 *)(r2 +0) = r1
 | |
|         invalid access to packet, off=0 size=4, R2(id=0,off=0,r=0)
 | |
|         R2 offset is outside of the packet
 | |
| 
 | |
| 6. BTF Generation
 | |
| =================
 | |
| 
 | |
| You need latest pahole
 | |
| 
 | |
|   https://git.kernel.org/pub/scm/devel/pahole/pahole.git/
 | |
| 
 | |
| or llvm (8.0 or later). The pahole acts as a dwarf2btf converter. It doesn't
 | |
| support .BTF.ext and btf BTF_KIND_FUNC type yet. For example,::
 | |
| 
 | |
|       -bash-4.4$ cat t.c
 | |
|       struct t {
 | |
|         int a:2;
 | |
|         int b:3;
 | |
|         int c:2;
 | |
|       } g;
 | |
|       -bash-4.4$ gcc -c -O2 -g t.c
 | |
|       -bash-4.4$ pahole -JV t.o
 | |
|       File t.o:
 | |
|       [1] STRUCT t kind_flag=1 size=4 vlen=3
 | |
|               a type_id=2 bitfield_size=2 bits_offset=0
 | |
|               b type_id=2 bitfield_size=3 bits_offset=2
 | |
|               c type_id=2 bitfield_size=2 bits_offset=5
 | |
|       [2] INT int size=4 bit_offset=0 nr_bits=32 encoding=SIGNED
 | |
| 
 | |
| The llvm is able to generate .BTF and .BTF.ext directly with -g for bpf target
 | |
| only. The assembly code (-S) is able to show the BTF encoding in assembly
 | |
| format.::
 | |
| 
 | |
|     -bash-4.4$ cat t2.c
 | |
|     typedef int __int32;
 | |
|     struct t2 {
 | |
|       int a2;
 | |
|       int (*f2)(char q1, __int32 q2, ...);
 | |
|       int (*f3)();
 | |
|     } g2;
 | |
|     int main() { return 0; }
 | |
|     int test() { return 0; }
 | |
|     -bash-4.4$ clang -c -g -O2 --target=bpf t2.c
 | |
|     -bash-4.4$ readelf -S t2.o
 | |
|       ......
 | |
|       [ 8] .BTF              PROGBITS         0000000000000000  00000247
 | |
|            000000000000016e  0000000000000000           0     0     1
 | |
|       [ 9] .BTF.ext          PROGBITS         0000000000000000  000003b5
 | |
|            0000000000000060  0000000000000000           0     0     1
 | |
|       [10] .rel.BTF.ext      REL              0000000000000000  000007e0
 | |
|            0000000000000040  0000000000000010          16     9     8
 | |
|       ......
 | |
|     -bash-4.4$ clang -S -g -O2 --target=bpf t2.c
 | |
|     -bash-4.4$ cat t2.s
 | |
|       ......
 | |
|             .section        .BTF,"",@progbits
 | |
|             .short  60319                   # 0xeb9f
 | |
|             .byte   1
 | |
|             .byte   0
 | |
|             .long   24
 | |
|             .long   0
 | |
|             .long   220
 | |
|             .long   220
 | |
|             .long   122
 | |
|             .long   0                       # BTF_KIND_FUNC_PROTO(id = 1)
 | |
|             .long   218103808               # 0xd000000
 | |
|             .long   2
 | |
|             .long   83                      # BTF_KIND_INT(id = 2)
 | |
|             .long   16777216                # 0x1000000
 | |
|             .long   4
 | |
|             .long   16777248                # 0x1000020
 | |
|       ......
 | |
|             .byte   0                       # string offset=0
 | |
|             .ascii  ".text"                 # string offset=1
 | |
|             .byte   0
 | |
|             .ascii  "/home/yhs/tmp-pahole/t2.c" # string offset=7
 | |
|             .byte   0
 | |
|             .ascii  "int main() { return 0; }" # string offset=33
 | |
|             .byte   0
 | |
|             .ascii  "int test() { return 0; }" # string offset=58
 | |
|             .byte   0
 | |
|             .ascii  "int"                   # string offset=83
 | |
|       ......
 | |
|             .section        .BTF.ext,"",@progbits
 | |
|             .short  60319                   # 0xeb9f
 | |
|             .byte   1
 | |
|             .byte   0
 | |
|             .long   24
 | |
|             .long   0
 | |
|             .long   28
 | |
|             .long   28
 | |
|             .long   44
 | |
|             .long   8                       # FuncInfo
 | |
|             .long   1                       # FuncInfo section string offset=1
 | |
|             .long   2
 | |
|             .long   .Lfunc_begin0
 | |
|             .long   3
 | |
|             .long   .Lfunc_begin1
 | |
|             .long   5
 | |
|             .long   16                      # LineInfo
 | |
|             .long   1                       # LineInfo section string offset=1
 | |
|             .long   2
 | |
|             .long   .Ltmp0
 | |
|             .long   7
 | |
|             .long   33
 | |
|             .long   7182                    # Line 7 Col 14
 | |
|             .long   .Ltmp3
 | |
|             .long   7
 | |
|             .long   58
 | |
|             .long   8206                    # Line 8 Col 14
 | |
| 
 | |
| 7. Testing
 | |
| ==========
 | |
| 
 | |
| The kernel BPF selftest `tools/testing/selftests/bpf/prog_tests/btf.c`_
 | |
| provides an extensive set of BTF-related tests.
 | |
| 
 | |
| .. Links
 | |
| .. _tools/testing/selftests/bpf/prog_tests/btf.c:
 | |
|    https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/tree/tools/testing/selftests/bpf/prog_tests/btf.c
 |