Yonghong Song | ffcf7ce | 2019-01-18 13:56:49 -0800 | [diff] [blame] | 1 | ===================== |
| 2 | BPF Type Format (BTF) |
| 3 | ===================== |
| 4 | |
| 5 | 1. Introduction |
Dave Tucker | 3ff36bf | 2021-11-12 21:17:22 +0000 | [diff] [blame] | 6 | =============== |
Yonghong Song | ffcf7ce | 2019-01-18 13:56:49 -0800 | [diff] [blame] | 7 | |
Andrii Nakryiko | 9ab5305 | 2019-02-28 17:12:20 -0800 | [diff] [blame] | 8 | BTF (BPF Type Format) is the metadata format which encodes the debug info |
| 9 | related to BPF program/map. The name BTF was used initially to describe data |
| 10 | types. The BTF was later extended to include function info for defined |
| 11 | subroutines, and line info for source/line information. |
Yonghong Song | ffcf7ce | 2019-01-18 13:56:49 -0800 | [diff] [blame] | 12 | |
Andrii Nakryiko | 9ab5305 | 2019-02-28 17:12:20 -0800 | [diff] [blame] | 13 | The debug info is used for map pretty print, function signature, etc. The |
| 14 | function signature enables better bpf program/function kernel symbol. The line |
| 15 | info helps generate source annotated translated byte code, jited code and |
| 16 | verifier log. |
Yonghong Song | ffcf7ce | 2019-01-18 13:56:49 -0800 | [diff] [blame] | 17 | |
| 18 | The BTF specification contains two parts, |
| 19 | * BTF kernel API |
| 20 | * BTF ELF file format |
| 21 | |
Andrii Nakryiko | 9ab5305 | 2019-02-28 17:12:20 -0800 | [diff] [blame] | 22 | The kernel API is the contract between user space and kernel. The kernel |
| 23 | verifies the BTF info before using it. The ELF file format is a user space |
| 24 | contract between ELF file and libbpf loader. |
Yonghong Song | ffcf7ce | 2019-01-18 13:56:49 -0800 | [diff] [blame] | 25 | |
Andrii Nakryiko | 9ab5305 | 2019-02-28 17:12:20 -0800 | [diff] [blame] | 26 | The type and string sections are part of the BTF kernel API, describing the |
| 27 | debug info (mostly types related) referenced by the bpf program. These two |
| 28 | sections are discussed in details in :ref:`BTF_Type_String`. |
Yonghong Song | ffcf7ce | 2019-01-18 13:56:49 -0800 | [diff] [blame] | 29 | |
| 30 | .. _BTF_Type_String: |
| 31 | |
| 32 | 2. BTF Type and String Encoding |
Dave Tucker | 3ff36bf | 2021-11-12 21:17:22 +0000 | [diff] [blame] | 33 | =============================== |
Yonghong Song | ffcf7ce | 2019-01-18 13:56:49 -0800 | [diff] [blame] | 34 | |
Andrii Nakryiko | 9ab5305 | 2019-02-28 17:12:20 -0800 | [diff] [blame] | 35 | The file ``include/uapi/linux/btf.h`` provides high-level definition of how |
| 36 | types/strings are encoded. |
Yonghong Song | ffcf7ce | 2019-01-18 13:56:49 -0800 | [diff] [blame] | 37 | |
| 38 | The beginning of data blob must be:: |
| 39 | |
| 40 | struct btf_header { |
| 41 | __u16 magic; |
| 42 | __u8 version; |
| 43 | __u8 flags; |
| 44 | __u32 hdr_len; |
| 45 | |
| 46 | /* All offsets are in bytes relative to the end of this header */ |
| 47 | __u32 type_off; /* offset of type section */ |
| 48 | __u32 type_len; /* length of type section */ |
| 49 | __u32 str_off; /* offset of string section */ |
| 50 | __u32 str_len; /* length of string section */ |
| 51 | }; |
| 52 | |
| 53 | The magic is ``0xeB9F``, which has different encoding for big and little |
Andrii Nakryiko | 9ab5305 | 2019-02-28 17:12:20 -0800 | [diff] [blame] | 54 | endian systems, and can be used to test whether BTF is generated for big- or |
| 55 | little-endian target. The ``btf_header`` is designed to be extensible with |
| 56 | ``hdr_len`` equal to ``sizeof(struct btf_header)`` when a data blob is |
| 57 | generated. |
Yonghong Song | ffcf7ce | 2019-01-18 13:56:49 -0800 | [diff] [blame] | 58 | |
| 59 | 2.1 String Encoding |
Dave Tucker | 3ff36bf | 2021-11-12 21:17:22 +0000 | [diff] [blame] | 60 | ------------------- |
Yonghong Song | ffcf7ce | 2019-01-18 13:56:49 -0800 | [diff] [blame] | 61 | |
Andrii Nakryiko | 9ab5305 | 2019-02-28 17:12:20 -0800 | [diff] [blame] | 62 | The first string in the string section must be a null string. The rest of |
| 63 | string table is a concatenation of other null-terminated strings. |
Yonghong Song | ffcf7ce | 2019-01-18 13:56:49 -0800 | [diff] [blame] | 64 | |
| 65 | 2.2 Type Encoding |
Dave Tucker | 3ff36bf | 2021-11-12 21:17:22 +0000 | [diff] [blame] | 66 | ----------------- |
Yonghong Song | ffcf7ce | 2019-01-18 13:56:49 -0800 | [diff] [blame] | 67 | |
Andrii Nakryiko | 9ab5305 | 2019-02-28 17:12:20 -0800 | [diff] [blame] | 68 | The type id ``0`` is reserved for ``void`` type. The type section is parsed |
| 69 | sequentially and type id is assigned to each recognized type starting from id |
| 70 | ``1``. Currently, the following types are supported:: |
Yonghong Song | ffcf7ce | 2019-01-18 13:56:49 -0800 | [diff] [blame] | 71 | |
| 72 | #define BTF_KIND_INT 1 /* Integer */ |
| 73 | #define BTF_KIND_PTR 2 /* Pointer */ |
| 74 | #define BTF_KIND_ARRAY 3 /* Array */ |
| 75 | #define BTF_KIND_STRUCT 4 /* Struct */ |
| 76 | #define BTF_KIND_UNION 5 /* Union */ |
Yonghong Song | 61dbd59 | 2022-06-06 23:27:24 -0700 | [diff] [blame] | 77 | #define BTF_KIND_ENUM 6 /* Enumeration up to 32-bit values */ |
Yonghong Song | ffcf7ce | 2019-01-18 13:56:49 -0800 | [diff] [blame] | 78 | #define BTF_KIND_FWD 7 /* Forward */ |
| 79 | #define BTF_KIND_TYPEDEF 8 /* Typedef */ |
| 80 | #define BTF_KIND_VOLATILE 9 /* Volatile */ |
| 81 | #define BTF_KIND_CONST 10 /* Const */ |
| 82 | #define BTF_KIND_RESTRICT 11 /* Restrict */ |
| 83 | #define BTF_KIND_FUNC 12 /* Function */ |
| 84 | #define BTF_KIND_FUNC_PROTO 13 /* Function Proto */ |
Daniel Borkmann | f063c88 | 2019-04-09 23:20:08 +0200 | [diff] [blame] | 85 | #define BTF_KIND_VAR 14 /* Variable */ |
| 86 | #define BTF_KIND_DATASEC 15 /* Section */ |
Ilya Leoshkevich | 6be6a0b | 2021-02-26 21:22:56 +0100 | [diff] [blame] | 87 | #define BTF_KIND_FLOAT 16 /* Floating point */ |
Yonghong Song | 223f903 | 2021-10-12 09:48:38 -0700 | [diff] [blame] | 88 | #define BTF_KIND_DECL_TAG 17 /* Decl Tag */ |
Yonghong Song | d52f5c6 | 2021-11-11 17:26:56 -0800 | [diff] [blame] | 89 | #define BTF_KIND_TYPE_TAG 18 /* Type Tag */ |
Yonghong Song | 61dbd59 | 2022-06-06 23:27:24 -0700 | [diff] [blame] | 90 | #define BTF_KIND_ENUM64 19 /* Enumeration up to 64-bit values */ |
Yonghong Song | ffcf7ce | 2019-01-18 13:56:49 -0800 | [diff] [blame] | 91 | |
| 92 | Note that the type section encodes debug info, not just pure types. |
| 93 | ``BTF_KIND_FUNC`` is not a type, and it represents a defined subprogram. |
| 94 | |
| 95 | Each type contains the following common data:: |
| 96 | |
| 97 | struct btf_type { |
| 98 | __u32 name_off; |
| 99 | /* "info" bits arrangement |
| 100 | * bits 0-15: vlen (e.g. # of struct's members) |
| 101 | * bits 16-23: unused |
Ilya Leoshkevich | 6be6a0b | 2021-02-26 21:22:56 +0100 | [diff] [blame] | 102 | * bits 24-28: kind (e.g. int, ptr, array...etc) |
| 103 | * bits 29-30: unused |
Yonghong Song | ffcf7ce | 2019-01-18 13:56:49 -0800 | [diff] [blame] | 104 | * bit 31: kind_flag, currently used by |
Yonghong Song | 61dbd59 | 2022-06-06 23:27:24 -0700 | [diff] [blame] | 105 | * struct, union, fwd, enum and enum64. |
Yonghong Song | ffcf7ce | 2019-01-18 13:56:49 -0800 | [diff] [blame] | 106 | */ |
| 107 | __u32 info; |
Yonghong Song | 61dbd59 | 2022-06-06 23:27:24 -0700 | [diff] [blame] | 108 | /* "size" is used by INT, ENUM, STRUCT, UNION and ENUM64. |
Yonghong Song | ffcf7ce | 2019-01-18 13:56:49 -0800 | [diff] [blame] | 109 | * "size" tells the size of the type it is describing. |
| 110 | * |
| 111 | * "type" is used by PTR, TYPEDEF, VOLATILE, CONST, RESTRICT, |
Yonghong Song | d52f5c6 | 2021-11-11 17:26:56 -0800 | [diff] [blame] | 112 | * FUNC, FUNC_PROTO, DECL_TAG and TYPE_TAG. |
Yonghong Song | ffcf7ce | 2019-01-18 13:56:49 -0800 | [diff] [blame] | 113 | * "type" is a type_id referring to another type. |
| 114 | */ |
| 115 | union { |
| 116 | __u32 size; |
| 117 | __u32 type; |
| 118 | }; |
| 119 | }; |
| 120 | |
Andrii Nakryiko | 9ab5305 | 2019-02-28 17:12:20 -0800 | [diff] [blame] | 121 | For certain kinds, the common data are followed by kind-specific data. The |
| 122 | ``name_off`` in ``struct btf_type`` specifies the offset in the string table. |
| 123 | The following sections detail encoding of each kind. |
Yonghong Song | ffcf7ce | 2019-01-18 13:56:49 -0800 | [diff] [blame] | 124 | |
| 125 | 2.2.1 BTF_KIND_INT |
| 126 | ~~~~~~~~~~~~~~~~~~ |
| 127 | |
| 128 | ``struct btf_type`` encoding requirement: |
| 129 | * ``name_off``: any valid offset |
| 130 | * ``info.kind_flag``: 0 |
| 131 | * ``info.kind``: BTF_KIND_INT |
| 132 | * ``info.vlen``: 0 |
| 133 | * ``size``: the size of the int type in bytes. |
| 134 | |
Andrii Nakryiko | 5efc529 | 2019-02-28 17:12:19 -0800 | [diff] [blame] | 135 | ``btf_type`` is followed by a ``u32`` with the following bits arrangement:: |
Yonghong Song | ffcf7ce | 2019-01-18 13:56:49 -0800 | [diff] [blame] | 136 | |
| 137 | #define BTF_INT_ENCODING(VAL) (((VAL) & 0x0f000000) >> 24) |
Gary Lin | 948dc8c | 2019-05-13 17:45:48 +0800 | [diff] [blame] | 138 | #define BTF_INT_OFFSET(VAL) (((VAL) & 0x00ff0000) >> 16) |
Yonghong Song | ffcf7ce | 2019-01-18 13:56:49 -0800 | [diff] [blame] | 139 | #define BTF_INT_BITS(VAL) ((VAL) & 0x000000ff) |
| 140 | |
| 141 | The ``BTF_INT_ENCODING`` has the following attributes:: |
| 142 | |
| 143 | #define BTF_INT_SIGNED (1 << 0) |
| 144 | #define BTF_INT_CHAR (1 << 1) |
| 145 | #define BTF_INT_BOOL (1 << 2) |
| 146 | |
Andrii Nakryiko | 9ab5305 | 2019-02-28 17:12:20 -0800 | [diff] [blame] | 147 | The ``BTF_INT_ENCODING()`` provides extra information: signedness, char, or |
| 148 | bool, for the int type. The char and bool encoding are mostly useful for |
| 149 | pretty print. At most one encoding can be specified for the int type. |
Yonghong Song | ffcf7ce | 2019-01-18 13:56:49 -0800 | [diff] [blame] | 150 | |
Andrii Nakryiko | 9ab5305 | 2019-02-28 17:12:20 -0800 | [diff] [blame] | 151 | The ``BTF_INT_BITS()`` specifies the number of actual bits held by this int |
| 152 | type. For example, a 4-bit bitfield encodes ``BTF_INT_BITS()`` equals to 4. |
| 153 | The ``btf_type.size * 8`` must be equal to or greater than ``BTF_INT_BITS()`` |
| 154 | for the type. The maximum value of ``BTF_INT_BITS()`` is 128. |
Yonghong Song | ffcf7ce | 2019-01-18 13:56:49 -0800 | [diff] [blame] | 155 | |
Andrii Nakryiko | 9ab5305 | 2019-02-28 17:12:20 -0800 | [diff] [blame] | 156 | The ``BTF_INT_OFFSET()`` specifies the starting bit offset to calculate values |
Jesper Dangaard Brouer | f52c97d | 2019-03-25 15:12:15 +0100 | [diff] [blame] | 157 | for this int. For example, a bitfield struct member has: |
Mauro Carvalho Chehab | d857a3f | 2019-06-07 15:54:21 -0300 | [diff] [blame] | 158 | |
Jesper Dangaard Brouer | f52c97d | 2019-03-25 15:12:15 +0100 | [diff] [blame] | 159 | * btf member bit offset 100 from the start of the structure, |
| 160 | * btf member pointing to an int type, |
| 161 | * the int type has ``BTF_INT_OFFSET() = 2`` and ``BTF_INT_BITS() = 4`` |
Yonghong Song | ffcf7ce | 2019-01-18 13:56:49 -0800 | [diff] [blame] | 162 | |
Andrii Nakryiko | 9ab5305 | 2019-02-28 17:12:20 -0800 | [diff] [blame] | 163 | Then in the struct memory layout, this member will occupy ``4`` bits starting |
| 164 | from bits ``100 + 2 = 102``. |
Yonghong Song | ffcf7ce | 2019-01-18 13:56:49 -0800 | [diff] [blame] | 165 | |
Andrii Nakryiko | 9ab5305 | 2019-02-28 17:12:20 -0800 | [diff] [blame] | 166 | Alternatively, the bitfield struct member can be the following to access the |
| 167 | same bits as the above: |
Mauro Carvalho Chehab | d857a3f | 2019-06-07 15:54:21 -0300 | [diff] [blame] | 168 | |
Yonghong Song | ffcf7ce | 2019-01-18 13:56:49 -0800 | [diff] [blame] | 169 | * btf member bit offset 102, |
| 170 | * btf member pointing to an int type, |
| 171 | * the int type has ``BTF_INT_OFFSET() = 0`` and ``BTF_INT_BITS() = 4`` |
| 172 | |
Andrii Nakryiko | 9ab5305 | 2019-02-28 17:12:20 -0800 | [diff] [blame] | 173 | The original intention of ``BTF_INT_OFFSET()`` is to provide flexibility of |
| 174 | bitfield encoding. Currently, both llvm and pahole generate |
| 175 | ``BTF_INT_OFFSET() = 0`` for all int types. |
Yonghong Song | ffcf7ce | 2019-01-18 13:56:49 -0800 | [diff] [blame] | 176 | |
| 177 | 2.2.2 BTF_KIND_PTR |
| 178 | ~~~~~~~~~~~~~~~~~~ |
| 179 | |
| 180 | ``struct btf_type`` encoding requirement: |
| 181 | * ``name_off``: 0 |
| 182 | * ``info.kind_flag``: 0 |
| 183 | * ``info.kind``: BTF_KIND_PTR |
| 184 | * ``info.vlen``: 0 |
| 185 | * ``type``: the pointee type of the pointer |
| 186 | |
| 187 | No additional type data follow ``btf_type``. |
| 188 | |
| 189 | 2.2.3 BTF_KIND_ARRAY |
| 190 | ~~~~~~~~~~~~~~~~~~~~ |
| 191 | |
| 192 | ``struct btf_type`` encoding requirement: |
| 193 | * ``name_off``: 0 |
| 194 | * ``info.kind_flag``: 0 |
| 195 | * ``info.kind``: BTF_KIND_ARRAY |
| 196 | * ``info.vlen``: 0 |
| 197 | * ``size/type``: 0, not used |
| 198 | |
Andrii Nakryiko | 5efc529 | 2019-02-28 17:12:19 -0800 | [diff] [blame] | 199 | ``btf_type`` is followed by one ``struct btf_array``:: |
Yonghong Song | ffcf7ce | 2019-01-18 13:56:49 -0800 | [diff] [blame] | 200 | |
| 201 | struct btf_array { |
| 202 | __u32 type; |
| 203 | __u32 index_type; |
| 204 | __u32 nelems; |
| 205 | }; |
| 206 | |
| 207 | The ``struct btf_array`` encoding: |
| 208 | * ``type``: the element type |
| 209 | * ``index_type``: the index type |
| 210 | * ``nelems``: the number of elements for this array (``0`` is also allowed). |
| 211 | |
Andrii Nakryiko | 9ab5305 | 2019-02-28 17:12:20 -0800 | [diff] [blame] | 212 | The ``index_type`` can be any regular int type (``u8``, ``u16``, ``u32``, |
| 213 | ``u64``, ``unsigned __int128``). The original design of including |
| 214 | ``index_type`` follows DWARF, which has an ``index_type`` for its array type. |
Yonghong Song | ffcf7ce | 2019-01-18 13:56:49 -0800 | [diff] [blame] | 215 | Currently in BTF, beyond type verification, the ``index_type`` is not used. |
| 216 | |
| 217 | The ``struct btf_array`` allows chaining through element type to represent |
Andrii Nakryiko | 9ab5305 | 2019-02-28 17:12:20 -0800 | [diff] [blame] | 218 | multidimensional arrays. For example, for ``int a[5][6]``, the following type |
| 219 | information illustrates the chaining: |
Yonghong Song | ffcf7ce | 2019-01-18 13:56:49 -0800 | [diff] [blame] | 220 | |
| 221 | * [1]: int |
| 222 | * [2]: array, ``btf_array.type = [1]``, ``btf_array.nelems = 6`` |
| 223 | * [3]: array, ``btf_array.type = [2]``, ``btf_array.nelems = 5`` |
| 224 | |
Andrii Nakryiko | 9ab5305 | 2019-02-28 17:12:20 -0800 | [diff] [blame] | 225 | Currently, both pahole and llvm collapse multidimensional array into |
| 226 | one-dimensional array, e.g., for ``a[5][6]``, the ``btf_array.nelems`` is |
| 227 | equal to ``30``. This is because the original use case is map pretty print |
| 228 | where the whole array is dumped out so one-dimensional array is enough. As |
| 229 | more BTF usage is explored, pahole and llvm can be changed to generate proper |
| 230 | chained representation for multidimensional arrays. |
Yonghong Song | ffcf7ce | 2019-01-18 13:56:49 -0800 | [diff] [blame] | 231 | |
| 232 | 2.2.4 BTF_KIND_STRUCT |
| 233 | ~~~~~~~~~~~~~~~~~~~~~ |
| 234 | 2.2.5 BTF_KIND_UNION |
| 235 | ~~~~~~~~~~~~~~~~~~~~ |
| 236 | |
| 237 | ``struct btf_type`` encoding requirement: |
| 238 | * ``name_off``: 0 or offset to a valid C identifier |
| 239 | * ``info.kind_flag``: 0 or 1 |
| 240 | * ``info.kind``: BTF_KIND_STRUCT or BTF_KIND_UNION |
| 241 | * ``info.vlen``: the number of struct/union members |
| 242 | * ``info.size``: the size of the struct/union in bytes |
| 243 | |
| 244 | ``btf_type`` is followed by ``info.vlen`` number of ``struct btf_member``.:: |
| 245 | |
| 246 | struct btf_member { |
| 247 | __u32 name_off; |
| 248 | __u32 type; |
| 249 | __u32 offset; |
| 250 | }; |
| 251 | |
| 252 | ``struct btf_member`` encoding: |
| 253 | * ``name_off``: offset to a valid C identifier |
| 254 | * ``type``: the member type |
| 255 | * ``offset``: <see below> |
| 256 | |
Andrii Nakryiko | 9ab5305 | 2019-02-28 17:12:20 -0800 | [diff] [blame] | 257 | If the type info ``kind_flag`` is not set, the offset contains only bit offset |
| 258 | of the member. Note that the base type of the bitfield can only be int or enum |
| 259 | type. If the bitfield size is 32, the base type can be either int or enum |
| 260 | type. If the bitfield size is not 32, the base type must be int, and int type |
| 261 | ``BTF_INT_BITS()`` encodes the bitfield size. |
Yonghong Song | ffcf7ce | 2019-01-18 13:56:49 -0800 | [diff] [blame] | 262 | |
Andrii Nakryiko | 9ab5305 | 2019-02-28 17:12:20 -0800 | [diff] [blame] | 263 | If the ``kind_flag`` is set, the ``btf_member.offset`` contains both member |
| 264 | bitfield size and bit offset. The bitfield size and bit offset are calculated |
| 265 | as below.:: |
Yonghong Song | ffcf7ce | 2019-01-18 13:56:49 -0800 | [diff] [blame] | 266 | |
| 267 | #define BTF_MEMBER_BITFIELD_SIZE(val) ((val) >> 24) |
| 268 | #define BTF_MEMBER_BIT_OFFSET(val) ((val) & 0xffffff) |
| 269 | |
Andrii Nakryiko | 9ab5305 | 2019-02-28 17:12:20 -0800 | [diff] [blame] | 270 | In this case, if the base type is an int type, it must be a regular int type: |
Yonghong Song | ffcf7ce | 2019-01-18 13:56:49 -0800 | [diff] [blame] | 271 | |
| 272 | * ``BTF_INT_OFFSET()`` must be 0. |
| 273 | * ``BTF_INT_BITS()`` must be equal to ``{1,2,4,8,16} * 8``. |
| 274 | |
Vegard Nossum | 86b17aa | 2023-10-27 13:54:20 +0200 | [diff] [blame] | 275 | Commit 9d5f9f701b18 introduced ``kind_flag`` and explains why both modes |
| 276 | exist. |
Yonghong Song | ffcf7ce | 2019-01-18 13:56:49 -0800 | [diff] [blame] | 277 | |
| 278 | 2.2.6 BTF_KIND_ENUM |
| 279 | ~~~~~~~~~~~~~~~~~~~ |
| 280 | |
| 281 | ``struct btf_type`` encoding requirement: |
| 282 | * ``name_off``: 0 or offset to a valid C identifier |
Yonghong Song | 61dbd59 | 2022-06-06 23:27:24 -0700 | [diff] [blame] | 283 | * ``info.kind_flag``: 0 for unsigned, 1 for signed |
Yonghong Song | ffcf7ce | 2019-01-18 13:56:49 -0800 | [diff] [blame] | 284 | * ``info.kind``: BTF_KIND_ENUM |
| 285 | * ``info.vlen``: number of enum values |
Yonghong Song | 61dbd59 | 2022-06-06 23:27:24 -0700 | [diff] [blame] | 286 | * ``size``: 1/2/4/8 |
Yonghong Song | ffcf7ce | 2019-01-18 13:56:49 -0800 | [diff] [blame] | 287 | |
| 288 | ``btf_type`` is followed by ``info.vlen`` number of ``struct btf_enum``.:: |
| 289 | |
| 290 | struct btf_enum { |
| 291 | __u32 name_off; |
| 292 | __s32 val; |
| 293 | }; |
| 294 | |
| 295 | The ``btf_enum`` encoding: |
| 296 | * ``name_off``: offset to a valid C identifier |
| 297 | * ``val``: any value |
| 298 | |
Yonghong Song | 61dbd59 | 2022-06-06 23:27:24 -0700 | [diff] [blame] | 299 | If the original enum value is signed and the size is less than 4, |
| 300 | that value will be sign extended into 4 bytes. If the size is 8, |
| 301 | the value will be truncated into 4 bytes. |
| 302 | |
Yonghong Song | ffcf7ce | 2019-01-18 13:56:49 -0800 | [diff] [blame] | 303 | 2.2.7 BTF_KIND_FWD |
| 304 | ~~~~~~~~~~~~~~~~~~ |
| 305 | |
| 306 | ``struct btf_type`` encoding requirement: |
| 307 | * ``name_off``: offset to a valid C identifier |
| 308 | * ``info.kind_flag``: 0 for struct, 1 for union |
| 309 | * ``info.kind``: BTF_KIND_FWD |
| 310 | * ``info.vlen``: 0 |
| 311 | * ``type``: 0 |
| 312 | |
| 313 | No additional type data follow ``btf_type``. |
| 314 | |
| 315 | 2.2.8 BTF_KIND_TYPEDEF |
| 316 | ~~~~~~~~~~~~~~~~~~~~~~ |
| 317 | |
| 318 | ``struct btf_type`` encoding requirement: |
| 319 | * ``name_off``: offset to a valid C identifier |
| 320 | * ``info.kind_flag``: 0 |
| 321 | * ``info.kind``: BTF_KIND_TYPEDEF |
| 322 | * ``info.vlen``: 0 |
| 323 | * ``type``: the type which can be referred by name at ``name_off`` |
| 324 | |
| 325 | No additional type data follow ``btf_type``. |
| 326 | |
| 327 | 2.2.9 BTF_KIND_VOLATILE |
| 328 | ~~~~~~~~~~~~~~~~~~~~~~~ |
| 329 | |
| 330 | ``struct btf_type`` encoding requirement: |
| 331 | * ``name_off``: 0 |
| 332 | * ``info.kind_flag``: 0 |
| 333 | * ``info.kind``: BTF_KIND_VOLATILE |
| 334 | * ``info.vlen``: 0 |
| 335 | * ``type``: the type with ``volatile`` qualifier |
| 336 | |
| 337 | No additional type data follow ``btf_type``. |
| 338 | |
| 339 | 2.2.10 BTF_KIND_CONST |
| 340 | ~~~~~~~~~~~~~~~~~~~~~ |
| 341 | |
| 342 | ``struct btf_type`` encoding requirement: |
| 343 | * ``name_off``: 0 |
| 344 | * ``info.kind_flag``: 0 |
| 345 | * ``info.kind``: BTF_KIND_CONST |
| 346 | * ``info.vlen``: 0 |
| 347 | * ``type``: the type with ``const`` qualifier |
| 348 | |
| 349 | No additional type data follow ``btf_type``. |
| 350 | |
| 351 | 2.2.11 BTF_KIND_RESTRICT |
| 352 | ~~~~~~~~~~~~~~~~~~~~~~~~ |
| 353 | |
| 354 | ``struct btf_type`` encoding requirement: |
| 355 | * ``name_off``: 0 |
| 356 | * ``info.kind_flag``: 0 |
| 357 | * ``info.kind``: BTF_KIND_RESTRICT |
| 358 | * ``info.vlen``: 0 |
| 359 | * ``type``: the type with ``restrict`` qualifier |
| 360 | |
| 361 | No additional type data follow ``btf_type``. |
| 362 | |
| 363 | 2.2.12 BTF_KIND_FUNC |
| 364 | ~~~~~~~~~~~~~~~~~~~~ |
| 365 | |
| 366 | ``struct btf_type`` encoding requirement: |
| 367 | * ``name_off``: offset to a valid C identifier |
| 368 | * ``info.kind_flag``: 0 |
| 369 | * ``info.kind``: BTF_KIND_FUNC |
Indu Bhagat | e5e2342 | 2022-07-14 15:33:10 -0700 | [diff] [blame] | 370 | * ``info.vlen``: linkage information (BTF_FUNC_STATIC, BTF_FUNC_GLOBAL |
| 371 | or BTF_FUNC_EXTERN) |
Yonghong Song | ffcf7ce | 2019-01-18 13:56:49 -0800 | [diff] [blame] | 372 | * ``type``: a BTF_KIND_FUNC_PROTO type |
| 373 | |
| 374 | No additional type data follow ``btf_type``. |
| 375 | |
Andrii Nakryiko | 5efc529 | 2019-02-28 17:12:19 -0800 | [diff] [blame] | 376 | A BTF_KIND_FUNC defines not a type, but a subprogram (function) whose |
Andrii Nakryiko | 9ab5305 | 2019-02-28 17:12:20 -0800 | [diff] [blame] | 377 | signature is defined by ``type``. The subprogram is thus an instance of that |
| 378 | type. The BTF_KIND_FUNC may in turn be referenced by a func_info in the |
| 379 | :ref:`BTF_Ext_Section` (ELF) or in the arguments to :ref:`BPF_Prog_Load` |
| 380 | (ABI). |
Yonghong Song | ffcf7ce | 2019-01-18 13:56:49 -0800 | [diff] [blame] | 381 | |
Indu Bhagat | e5e2342 | 2022-07-14 15:33:10 -0700 | [diff] [blame] | 382 | Currently, only linkage values of BTF_FUNC_STATIC and BTF_FUNC_GLOBAL are |
| 383 | supported in the kernel. |
| 384 | |
Yonghong Song | ffcf7ce | 2019-01-18 13:56:49 -0800 | [diff] [blame] | 385 | 2.2.13 BTF_KIND_FUNC_PROTO |
| 386 | ~~~~~~~~~~~~~~~~~~~~~~~~~~ |
| 387 | |
| 388 | ``struct btf_type`` encoding requirement: |
| 389 | * ``name_off``: 0 |
| 390 | * ``info.kind_flag``: 0 |
| 391 | * ``info.kind``: BTF_KIND_FUNC_PROTO |
| 392 | * ``info.vlen``: # of parameters |
| 393 | * ``type``: the return type |
| 394 | |
| 395 | ``btf_type`` is followed by ``info.vlen`` number of ``struct btf_param``.:: |
| 396 | |
| 397 | struct btf_param { |
| 398 | __u32 name_off; |
| 399 | __u32 type; |
| 400 | }; |
| 401 | |
Andrii Nakryiko | 9ab5305 | 2019-02-28 17:12:20 -0800 | [diff] [blame] | 402 | If a BTF_KIND_FUNC_PROTO type is referred by a BTF_KIND_FUNC type, then |
| 403 | ``btf_param.name_off`` must point to a valid C identifier except for the |
| 404 | possible last argument representing the variable argument. The btf_param.type |
| 405 | refers to parameter type. |
Yonghong Song | ffcf7ce | 2019-01-18 13:56:49 -0800 | [diff] [blame] | 406 | |
Andrii Nakryiko | 9ab5305 | 2019-02-28 17:12:20 -0800 | [diff] [blame] | 407 | If the function has variable arguments, the last parameter is encoded with |
| 408 | ``name_off = 0`` and ``type = 0``. |
Yonghong Song | ffcf7ce | 2019-01-18 13:56:49 -0800 | [diff] [blame] | 409 | |
Daniel Borkmann | f063c88 | 2019-04-09 23:20:08 +0200 | [diff] [blame] | 410 | 2.2.14 BTF_KIND_VAR |
| 411 | ~~~~~~~~~~~~~~~~~~~ |
| 412 | |
| 413 | ``struct btf_type`` encoding requirement: |
| 414 | * ``name_off``: offset to a valid C identifier |
| 415 | * ``info.kind_flag``: 0 |
| 416 | * ``info.kind``: BTF_KIND_VAR |
| 417 | * ``info.vlen``: 0 |
| 418 | * ``type``: the type of the variable |
| 419 | |
| 420 | ``btf_type`` is followed by a single ``struct btf_variable`` with the |
| 421 | following data:: |
| 422 | |
| 423 | struct btf_var { |
| 424 | __u32 linkage; |
| 425 | }; |
| 426 | |
| 427 | ``struct btf_var`` encoding: |
| 428 | * ``linkage``: currently only static variable 0, or globally allocated |
| 429 | variable in ELF sections 1 |
| 430 | |
| 431 | Not all type of global variables are supported by LLVM at this point. |
| 432 | The following is currently available: |
| 433 | |
| 434 | * static variables with or without section attributes |
| 435 | * global variables with section attributes |
| 436 | |
| 437 | The latter is for future extraction of map key/value type id's from a |
| 438 | map definition. |
| 439 | |
| 440 | 2.2.15 BTF_KIND_DATASEC |
| 441 | ~~~~~~~~~~~~~~~~~~~~~~~ |
| 442 | |
| 443 | ``struct btf_type`` encoding requirement: |
| 444 | * ``name_off``: offset to a valid name associated with a variable or |
| 445 | one of .data/.bss/.rodata |
| 446 | * ``info.kind_flag``: 0 |
| 447 | * ``info.kind``: BTF_KIND_DATASEC |
| 448 | * ``info.vlen``: # of variables |
| 449 | * ``size``: total section size in bytes (0 at compilation time, patched |
| 450 | to actual size by BPF loaders such as libbpf) |
| 451 | |
| 452 | ``btf_type`` is followed by ``info.vlen`` number of ``struct btf_var_secinfo``.:: |
| 453 | |
| 454 | struct btf_var_secinfo { |
| 455 | __u32 type; |
| 456 | __u32 offset; |
| 457 | __u32 size; |
| 458 | }; |
| 459 | |
| 460 | ``struct btf_var_secinfo`` encoding: |
| 461 | * ``type``: the type of the BTF_KIND_VAR variable |
| 462 | * ``offset``: the in-section offset of the variable |
| 463 | * ``size``: the size of the variable in bytes |
| 464 | |
Ilya Leoshkevich | 6be6a0b | 2021-02-26 21:22:56 +0100 | [diff] [blame] | 465 | 2.2.16 BTF_KIND_FLOAT |
| 466 | ~~~~~~~~~~~~~~~~~~~~~ |
| 467 | |
| 468 | ``struct btf_type`` encoding requirement: |
| 469 | * ``name_off``: any valid offset |
| 470 | * ``info.kind_flag``: 0 |
| 471 | * ``info.kind``: BTF_KIND_FLOAT |
| 472 | * ``info.vlen``: 0 |
| 473 | * ``size``: the size of the float type in bytes: 2, 4, 8, 12 or 16. |
| 474 | |
| 475 | No additional type data follow ``btf_type``. |
| 476 | |
Yonghong Song | 223f903 | 2021-10-12 09:48:38 -0700 | [diff] [blame] | 477 | 2.2.17 BTF_KIND_DECL_TAG |
| 478 | ~~~~~~~~~~~~~~~~~~~~~~~~ |
Yonghong Song | 48f5a6c | 2021-09-14 15:31:03 -0700 | [diff] [blame] | 479 | |
| 480 | ``struct btf_type`` encoding requirement: |
| 481 | * ``name_off``: offset to a non-empty string |
| 482 | * ``info.kind_flag``: 0 |
Yonghong Song | 223f903 | 2021-10-12 09:48:38 -0700 | [diff] [blame] | 483 | * ``info.kind``: BTF_KIND_DECL_TAG |
Yonghong Song | 48f5a6c | 2021-09-14 15:31:03 -0700 | [diff] [blame] | 484 | * ``info.vlen``: 0 |
Yonghong Song | 5a86713 | 2021-10-21 12:56:49 -0700 | [diff] [blame] | 485 | * ``type``: ``struct``, ``union``, ``func``, ``var`` or ``typedef`` |
Yonghong Song | 48f5a6c | 2021-09-14 15:31:03 -0700 | [diff] [blame] | 486 | |
Yonghong Song | 223f903 | 2021-10-12 09:48:38 -0700 | [diff] [blame] | 487 | ``btf_type`` is followed by ``struct btf_decl_tag``.:: |
Yonghong Song | 48f5a6c | 2021-09-14 15:31:03 -0700 | [diff] [blame] | 488 | |
Yonghong Song | 223f903 | 2021-10-12 09:48:38 -0700 | [diff] [blame] | 489 | struct btf_decl_tag { |
Yonghong Song | 48f5a6c | 2021-09-14 15:31:03 -0700 | [diff] [blame] | 490 | __u32 component_idx; |
| 491 | }; |
| 492 | |
Yonghong Song | 223f903 | 2021-10-12 09:48:38 -0700 | [diff] [blame] | 493 | The ``name_off`` encodes btf_decl_tag attribute string. |
Yonghong Song | 5a86713 | 2021-10-21 12:56:49 -0700 | [diff] [blame] | 494 | The ``type`` should be ``struct``, ``union``, ``func``, ``var`` or ``typedef``. |
| 495 | For ``var`` or ``typedef`` type, ``btf_decl_tag.component_idx`` must be ``-1``. |
Yonghong Song | 223f903 | 2021-10-12 09:48:38 -0700 | [diff] [blame] | 496 | For the other three types, if the btf_decl_tag attribute is |
Yonghong Song | 48f5a6c | 2021-09-14 15:31:03 -0700 | [diff] [blame] | 497 | applied to the ``struct``, ``union`` or ``func`` itself, |
Yonghong Song | 223f903 | 2021-10-12 09:48:38 -0700 | [diff] [blame] | 498 | ``btf_decl_tag.component_idx`` must be ``-1``. Otherwise, |
Yonghong Song | 48f5a6c | 2021-09-14 15:31:03 -0700 | [diff] [blame] | 499 | the attribute is applied to a ``struct``/``union`` member or |
Yonghong Song | 223f903 | 2021-10-12 09:48:38 -0700 | [diff] [blame] | 500 | a ``func`` argument, and ``btf_decl_tag.component_idx`` should be a |
Yonghong Song | 48f5a6c | 2021-09-14 15:31:03 -0700 | [diff] [blame] | 501 | valid index (starting from 0) pointing to a member or an argument. |
| 502 | |
Yonghong Song | 61dbd59 | 2022-06-06 23:27:24 -0700 | [diff] [blame] | 503 | 2.2.18 BTF_KIND_TYPE_TAG |
Yonghong Song | d52f5c6 | 2021-11-11 17:26:56 -0800 | [diff] [blame] | 504 | ~~~~~~~~~~~~~~~~~~~~~~~~ |
| 505 | |
| 506 | ``struct btf_type`` encoding requirement: |
| 507 | * ``name_off``: offset to a non-empty string |
| 508 | * ``info.kind_flag``: 0 |
| 509 | * ``info.kind``: BTF_KIND_TYPE_TAG |
| 510 | * ``info.vlen``: 0 |
| 511 | * ``type``: the type with ``btf_type_tag`` attribute |
| 512 | |
Yonghong Song | b729038 | 2022-01-27 07:46:27 -0800 | [diff] [blame] | 513 | Currently, ``BTF_KIND_TYPE_TAG`` is only emitted for pointer types. |
| 514 | It has the following btf type chain: |
| 515 | :: |
| 516 | |
| 517 | ptr -> [type_tag]* |
| 518 | -> [const | volatile | restrict | typedef]* |
| 519 | -> base_type |
| 520 | |
| 521 | Basically, a pointer type points to zero or more |
| 522 | type_tag, then zero or more const/volatile/restrict/typedef |
| 523 | and finally the base type. The base type is one of |
| 524 | int, ptr, array, struct, union, enum, func_proto and float types. |
| 525 | |
Yonghong Song | 61dbd59 | 2022-06-06 23:27:24 -0700 | [diff] [blame] | 526 | 2.2.19 BTF_KIND_ENUM64 |
| 527 | ~~~~~~~~~~~~~~~~~~~~~~ |
| 528 | |
| 529 | ``struct btf_type`` encoding requirement: |
| 530 | * ``name_off``: 0 or offset to a valid C identifier |
| 531 | * ``info.kind_flag``: 0 for unsigned, 1 for signed |
| 532 | * ``info.kind``: BTF_KIND_ENUM64 |
| 533 | * ``info.vlen``: number of enum values |
| 534 | * ``size``: 1/2/4/8 |
| 535 | |
| 536 | ``btf_type`` is followed by ``info.vlen`` number of ``struct btf_enum64``.:: |
| 537 | |
| 538 | struct btf_enum64 { |
| 539 | __u32 name_off; |
| 540 | __u32 val_lo32; |
| 541 | __u32 val_hi32; |
| 542 | }; |
| 543 | |
| 544 | The ``btf_enum64`` encoding: |
| 545 | * ``name_off``: offset to a valid C identifier |
| 546 | * ``val_lo32``: lower 32-bit value for a 64-bit value |
| 547 | * ``val_hi32``: high 32-bit value for a 64-bit value |
| 548 | |
| 549 | If the original enum value is signed and the size is less than 8, |
| 550 | that value will be sign extended into 8 bytes. |
| 551 | |
Yonghong Song | ffcf7ce | 2019-01-18 13:56:49 -0800 | [diff] [blame] | 552 | 3. BTF Kernel API |
Dave Tucker | 3ff36bf | 2021-11-12 21:17:22 +0000 | [diff] [blame] | 553 | ================= |
Yonghong Song | ffcf7ce | 2019-01-18 13:56:49 -0800 | [diff] [blame] | 554 | |
| 555 | The following bpf syscall command involves BTF: |
| 556 | * BPF_BTF_LOAD: load a blob of BTF data into kernel |
| 557 | * BPF_MAP_CREATE: map creation with btf key and value type info. |
| 558 | * BPF_PROG_LOAD: prog load with btf function and line info. |
| 559 | * BPF_BTF_GET_FD_BY_ID: get a btf fd |
| 560 | * BPF_OBJ_GET_INFO_BY_FD: btf, func_info, line_info |
| 561 | and other btf related info are returned. |
| 562 | |
| 563 | The workflow typically looks like: |
| 564 | :: |
| 565 | |
| 566 | Application: |
| 567 | BPF_BTF_LOAD |
| 568 | | |
| 569 | v |
| 570 | BPF_MAP_CREATE and BPF_PROG_LOAD |
| 571 | | |
| 572 | V |
| 573 | ...... |
| 574 | |
| 575 | Introspection tool: |
| 576 | ...... |
| 577 | BPF_{PROG,MAP}_GET_NEXT_ID (get prog/map id's) |
| 578 | | |
| 579 | V |
| 580 | BPF_{PROG,MAP}_GET_FD_BY_ID (get a prog/map fd) |
| 581 | | |
| 582 | V |
| 583 | BPF_OBJ_GET_INFO_BY_FD (get bpf_prog_info/bpf_map_info with btf_id) |
| 584 | | | |
| 585 | V | |
| 586 | BPF_BTF_GET_FD_BY_ID (get btf_fd) | |
| 587 | | | |
| 588 | V | |
| 589 | BPF_OBJ_GET_INFO_BY_FD (get btf) | |
| 590 | | | |
| 591 | V V |
| 592 | pretty print types, dump func signatures and line info, etc. |
| 593 | |
| 594 | |
| 595 | 3.1 BPF_BTF_LOAD |
Dave Tucker | 3ff36bf | 2021-11-12 21:17:22 +0000 | [diff] [blame] | 596 | ---------------- |
Yonghong Song | ffcf7ce | 2019-01-18 13:56:49 -0800 | [diff] [blame] | 597 | |
Andrii Nakryiko | 9ab5305 | 2019-02-28 17:12:20 -0800 | [diff] [blame] | 598 | Load a blob of BTF data into kernel. A blob of data, described in |
| 599 | :ref:`BTF_Type_String`, can be directly loaded into the kernel. A ``btf_fd`` |
| 600 | is returned to a userspace. |
Yonghong Song | ffcf7ce | 2019-01-18 13:56:49 -0800 | [diff] [blame] | 601 | |
| 602 | 3.2 BPF_MAP_CREATE |
Dave Tucker | 3ff36bf | 2021-11-12 21:17:22 +0000 | [diff] [blame] | 603 | ------------------ |
Yonghong Song | ffcf7ce | 2019-01-18 13:56:49 -0800 | [diff] [blame] | 604 | |
| 605 | A map can be created with ``btf_fd`` and specified key/value type id.:: |
| 606 | |
| 607 | __u32 btf_fd; /* fd pointing to a BTF type data */ |
| 608 | __u32 btf_key_type_id; /* BTF type_id of the key */ |
| 609 | __u32 btf_value_type_id; /* BTF type_id of the value */ |
| 610 | |
| 611 | In libbpf, the map can be defined with extra annotation like below: |
| 612 | :: |
| 613 | |
Andrii Nakryiko | 96c8530 | 2022-01-19 22:05:29 -0800 | [diff] [blame] | 614 | struct { |
| 615 | __uint(type, BPF_MAP_TYPE_ARRAY); |
| 616 | __type(key, int); |
| 617 | __type(value, struct ipv_counts); |
| 618 | __uint(max_entries, 4); |
| 619 | } btf_map SEC(".maps"); |
Yonghong Song | ffcf7ce | 2019-01-18 13:56:49 -0800 | [diff] [blame] | 620 | |
Andrii Nakryiko | 96c8530 | 2022-01-19 22:05:29 -0800 | [diff] [blame] | 621 | During ELF parsing, libbpf is able to extract key/value type_id's and assign |
| 622 | them to BPF_MAP_CREATE attributes automatically. |
Yonghong Song | ffcf7ce | 2019-01-18 13:56:49 -0800 | [diff] [blame] | 623 | |
| 624 | .. _BPF_Prog_Load: |
| 625 | |
| 626 | 3.3 BPF_PROG_LOAD |
Dave Tucker | 3ff36bf | 2021-11-12 21:17:22 +0000 | [diff] [blame] | 627 | ----------------- |
Yonghong Song | ffcf7ce | 2019-01-18 13:56:49 -0800 | [diff] [blame] | 628 | |
Andrii Nakryiko | 9ab5305 | 2019-02-28 17:12:20 -0800 | [diff] [blame] | 629 | During prog_load, func_info and line_info can be passed to kernel with proper |
| 630 | values for the following attributes: |
Yonghong Song | ffcf7ce | 2019-01-18 13:56:49 -0800 | [diff] [blame] | 631 | :: |
| 632 | |
| 633 | __u32 insn_cnt; |
| 634 | __aligned_u64 insns; |
| 635 | ...... |
| 636 | __u32 prog_btf_fd; /* fd pointing to BTF type data */ |
| 637 | __u32 func_info_rec_size; /* userspace bpf_func_info size */ |
| 638 | __aligned_u64 func_info; /* func info */ |
| 639 | __u32 func_info_cnt; /* number of bpf_func_info records */ |
| 640 | __u32 line_info_rec_size; /* userspace bpf_line_info size */ |
| 641 | __aligned_u64 line_info; /* line info */ |
| 642 | __u32 line_info_cnt; /* number of bpf_line_info records */ |
| 643 | |
| 644 | The func_info and line_info are an array of below, respectively.:: |
| 645 | |
| 646 | struct bpf_func_info { |
| 647 | __u32 insn_off; /* [0, insn_cnt - 1] */ |
| 648 | __u32 type_id; /* pointing to a BTF_KIND_FUNC type */ |
| 649 | }; |
| 650 | struct bpf_line_info { |
| 651 | __u32 insn_off; /* [0, insn_cnt - 1] */ |
| 652 | __u32 file_name_off; /* offset to string table for the filename */ |
| 653 | __u32 line_off; /* offset to string table for the source line */ |
| 654 | __u32 line_col; /* line number and column number */ |
| 655 | }; |
| 656 | |
Andrii Nakryiko | 9ab5305 | 2019-02-28 17:12:20 -0800 | [diff] [blame] | 657 | func_info_rec_size is the size of each func_info record, and |
| 658 | line_info_rec_size is the size of each line_info record. Passing the record |
| 659 | size to kernel make it possible to extend the record itself in the future. |
Yonghong Song | ffcf7ce | 2019-01-18 13:56:49 -0800 | [diff] [blame] | 660 | |
| 661 | Below are requirements for func_info: |
| 662 | * func_info[0].insn_off must be 0. |
| 663 | * the func_info insn_off is in strictly increasing order and matches |
| 664 | bpf func boundaries. |
| 665 | |
| 666 | Below are requirements for line_info: |
Andrii Nakryiko | 5efc529 | 2019-02-28 17:12:19 -0800 | [diff] [blame] | 667 | * the first insn in each func must have a line_info record pointing to it. |
Yonghong Song | ffcf7ce | 2019-01-18 13:56:49 -0800 | [diff] [blame] | 668 | * the line_info insn_off is in strictly increasing order. |
| 669 | |
| 670 | For line_info, the line number and column number are defined as below: |
| 671 | :: |
| 672 | |
| 673 | #define BPF_LINE_INFO_LINE_NUM(line_col) ((line_col) >> 10) |
| 674 | #define BPF_LINE_INFO_LINE_COL(line_col) ((line_col) & 0x3ff) |
| 675 | |
| 676 | 3.4 BPF_{PROG,MAP}_GET_NEXT_ID |
Dave Tucker | 3ff36bf | 2021-11-12 21:17:22 +0000 | [diff] [blame] | 677 | ------------------------------ |
Yonghong Song | ffcf7ce | 2019-01-18 13:56:49 -0800 | [diff] [blame] | 678 | |
Andrii Nakryiko | 9ab5305 | 2019-02-28 17:12:20 -0800 | [diff] [blame] | 679 | In kernel, every loaded program, map or btf has a unique id. The id won't |
| 680 | change during the lifetime of a program, map, or btf. |
Yonghong Song | ffcf7ce | 2019-01-18 13:56:49 -0800 | [diff] [blame] | 681 | |
Andrii Nakryiko | 9ab5305 | 2019-02-28 17:12:20 -0800 | [diff] [blame] | 682 | The bpf syscall command BPF_{PROG,MAP}_GET_NEXT_ID returns all id's, one for |
| 683 | each command, to user space, for bpf program or maps, respectively, so an |
| 684 | inspection tool can inspect all programs and maps. |
Yonghong Song | ffcf7ce | 2019-01-18 13:56:49 -0800 | [diff] [blame] | 685 | |
| 686 | 3.5 BPF_{PROG,MAP}_GET_FD_BY_ID |
Dave Tucker | 3ff36bf | 2021-11-12 21:17:22 +0000 | [diff] [blame] | 687 | ------------------------------- |
Yonghong Song | ffcf7ce | 2019-01-18 13:56:49 -0800 | [diff] [blame] | 688 | |
Andrii Nakryiko | 5efc529 | 2019-02-28 17:12:19 -0800 | [diff] [blame] | 689 | An introspection tool cannot use id to get details about program or maps. |
| 690 | A file descriptor needs to be obtained first for reference-counting purpose. |
Yonghong Song | ffcf7ce | 2019-01-18 13:56:49 -0800 | [diff] [blame] | 691 | |
| 692 | 3.6 BPF_OBJ_GET_INFO_BY_FD |
Dave Tucker | 3ff36bf | 2021-11-12 21:17:22 +0000 | [diff] [blame] | 693 | -------------------------- |
Yonghong Song | ffcf7ce | 2019-01-18 13:56:49 -0800 | [diff] [blame] | 694 | |
Andrii Nakryiko | 9ab5305 | 2019-02-28 17:12:20 -0800 | [diff] [blame] | 695 | Once a program/map fd is acquired, an introspection tool can get the detailed |
| 696 | information from kernel about this fd, some of which are BTF-related. For |
| 697 | example, ``bpf_map_info`` returns ``btf_id`` and key/value type ids. |
| 698 | ``bpf_prog_info`` returns ``btf_id``, func_info, and line info for translated |
| 699 | bpf byte codes, and jited_line_info. |
Yonghong Song | ffcf7ce | 2019-01-18 13:56:49 -0800 | [diff] [blame] | 700 | |
| 701 | 3.7 BPF_BTF_GET_FD_BY_ID |
Dave Tucker | 3ff36bf | 2021-11-12 21:17:22 +0000 | [diff] [blame] | 702 | ------------------------ |
Yonghong Song | ffcf7ce | 2019-01-18 13:56:49 -0800 | [diff] [blame] | 703 | |
Andrii Nakryiko | 9ab5305 | 2019-02-28 17:12:20 -0800 | [diff] [blame] | 704 | With ``btf_id`` obtained in ``bpf_map_info`` and ``bpf_prog_info``, bpf |
| 705 | syscall command BPF_BTF_GET_FD_BY_ID can retrieve a btf fd. Then, with |
| 706 | command BPF_OBJ_GET_INFO_BY_FD, the btf blob, originally loaded into the |
| 707 | kernel with BPF_BTF_LOAD, can be retrieved. |
Yonghong Song | ffcf7ce | 2019-01-18 13:56:49 -0800 | [diff] [blame] | 708 | |
Andrii Nakryiko | 5efc529 | 2019-02-28 17:12:19 -0800 | [diff] [blame] | 709 | With the btf blob, ``bpf_map_info``, and ``bpf_prog_info``, an introspection |
Andrii Nakryiko | 9ab5305 | 2019-02-28 17:12:20 -0800 | [diff] [blame] | 710 | tool has full btf knowledge and is able to pretty print map key/values, dump |
| 711 | func signatures and line info, along with byte/jit codes. |
Yonghong Song | ffcf7ce | 2019-01-18 13:56:49 -0800 | [diff] [blame] | 712 | |
| 713 | 4. ELF File Format Interface |
Dave Tucker | 3ff36bf | 2021-11-12 21:17:22 +0000 | [diff] [blame] | 714 | ============================ |
Yonghong Song | ffcf7ce | 2019-01-18 13:56:49 -0800 | [diff] [blame] | 715 | |
| 716 | 4.1 .BTF section |
Dave Tucker | 3ff36bf | 2021-11-12 21:17:22 +0000 | [diff] [blame] | 717 | ---------------- |
Yonghong Song | ffcf7ce | 2019-01-18 13:56:49 -0800 | [diff] [blame] | 718 | |
Andrii Nakryiko | 9ab5305 | 2019-02-28 17:12:20 -0800 | [diff] [blame] | 719 | The .BTF section contains type and string data. The format of this section is |
| 720 | same as the one describe in :ref:`BTF_Type_String`. |
Yonghong Song | ffcf7ce | 2019-01-18 13:56:49 -0800 | [diff] [blame] | 721 | |
| 722 | .. _BTF_Ext_Section: |
| 723 | |
| 724 | 4.2 .BTF.ext section |
Dave Tucker | 3ff36bf | 2021-11-12 21:17:22 +0000 | [diff] [blame] | 725 | -------------------- |
Yonghong Song | ffcf7ce | 2019-01-18 13:56:49 -0800 | [diff] [blame] | 726 | |
Eduard Zingerman | be4033d | 2023-08-27 01:29:12 +0300 | [diff] [blame] | 727 | The .BTF.ext section encodes func_info, line_info and CO-RE relocations |
| 728 | which needs loader manipulation before loading into the kernel. |
Yonghong Song | ffcf7ce | 2019-01-18 13:56:49 -0800 | [diff] [blame] | 729 | |
Andrii Nakryiko | 9ab5305 | 2019-02-28 17:12:20 -0800 | [diff] [blame] | 730 | The specification for .BTF.ext section is defined at ``tools/lib/bpf/btf.h`` |
| 731 | and ``tools/lib/bpf/btf.c``. |
Yonghong Song | ffcf7ce | 2019-01-18 13:56:49 -0800 | [diff] [blame] | 732 | |
| 733 | The current header of .BTF.ext section:: |
| 734 | |
| 735 | struct btf_ext_header { |
| 736 | __u16 magic; |
| 737 | __u8 version; |
| 738 | __u8 flags; |
| 739 | __u32 hdr_len; |
| 740 | |
| 741 | /* All offsets are in bytes relative to the end of this header */ |
| 742 | __u32 func_info_off; |
| 743 | __u32 func_info_len; |
| 744 | __u32 line_info_off; |
| 745 | __u32 line_info_len; |
Eduard Zingerman | be4033d | 2023-08-27 01:29:12 +0300 | [diff] [blame] | 746 | |
| 747 | /* optional part of .BTF.ext header */ |
| 748 | __u32 core_relo_off; |
| 749 | __u32 core_relo_len; |
Yonghong Song | ffcf7ce | 2019-01-18 13:56:49 -0800 | [diff] [blame] | 750 | }; |
| 751 | |
Andrii Nakryiko | 9ab5305 | 2019-02-28 17:12:20 -0800 | [diff] [blame] | 752 | It is very similar to .BTF section. Instead of type/string section, it |
Eduard Zingerman | be4033d | 2023-08-27 01:29:12 +0300 | [diff] [blame] | 753 | contains func_info, line_info and core_relo sub-sections. |
| 754 | See :ref:`BPF_Prog_Load` for details about func_info and line_info |
| 755 | record format. |
Yonghong Song | ffcf7ce | 2019-01-18 13:56:49 -0800 | [diff] [blame] | 756 | |
| 757 | The func_info is organized as below.:: |
| 758 | |
Eduard Zingerman | be4033d | 2023-08-27 01:29:12 +0300 | [diff] [blame] | 759 | func_info_rec_size /* __u32 value */ |
Yonghong Song | ffcf7ce | 2019-01-18 13:56:49 -0800 | [diff] [blame] | 760 | btf_ext_info_sec for section #1 /* func_info for section #1 */ |
| 761 | btf_ext_info_sec for section #2 /* func_info for section #2 */ |
| 762 | ... |
| 763 | |
Andrii Nakryiko | 9ab5305 | 2019-02-28 17:12:20 -0800 | [diff] [blame] | 764 | ``func_info_rec_size`` specifies the size of ``bpf_func_info`` structure when |
| 765 | .BTF.ext is generated. ``btf_ext_info_sec``, defined below, is a collection of |
| 766 | func_info for each specific ELF section.:: |
Yonghong Song | ffcf7ce | 2019-01-18 13:56:49 -0800 | [diff] [blame] | 767 | |
| 768 | struct btf_ext_info_sec { |
| 769 | __u32 sec_name_off; /* offset to section name */ |
| 770 | __u32 num_info; |
| 771 | /* Followed by num_info * record_size number of bytes */ |
| 772 | __u8 data[0]; |
| 773 | }; |
| 774 | |
| 775 | Here, num_info must be greater than 0. |
| 776 | |
| 777 | The line_info is organized as below.:: |
| 778 | |
Eduard Zingerman | be4033d | 2023-08-27 01:29:12 +0300 | [diff] [blame] | 779 | line_info_rec_size /* __u32 value */ |
Yonghong Song | ffcf7ce | 2019-01-18 13:56:49 -0800 | [diff] [blame] | 780 | btf_ext_info_sec for section #1 /* line_info for section #1 */ |
| 781 | btf_ext_info_sec for section #2 /* line_info for section #2 */ |
| 782 | ... |
| 783 | |
Andrii Nakryiko | 9ab5305 | 2019-02-28 17:12:20 -0800 | [diff] [blame] | 784 | ``line_info_rec_size`` specifies the size of ``bpf_line_info`` structure when |
| 785 | .BTF.ext is generated. |
Yonghong Song | ffcf7ce | 2019-01-18 13:56:49 -0800 | [diff] [blame] | 786 | |
| 787 | The interpretation of ``bpf_func_info->insn_off`` and |
Andrii Nakryiko | 9ab5305 | 2019-02-28 17:12:20 -0800 | [diff] [blame] | 788 | ``bpf_line_info->insn_off`` is different between kernel API and ELF API. For |
| 789 | kernel API, the ``insn_off`` is the instruction offset in the unit of ``struct |
| 790 | bpf_insn``. For ELF API, the ``insn_off`` is the byte offset from the |
| 791 | beginning of section (``btf_ext_info_sec->sec_name_off``). |
Yonghong Song | ffcf7ce | 2019-01-18 13:56:49 -0800 | [diff] [blame] | 792 | |
Eduard Zingerman | be4033d | 2023-08-27 01:29:12 +0300 | [diff] [blame] | 793 | The core_relo is organized as below.:: |
| 794 | |
| 795 | core_relo_rec_size /* __u32 value */ |
| 796 | btf_ext_info_sec for section #1 /* core_relo for section #1 */ |
| 797 | btf_ext_info_sec for section #2 /* core_relo for section #2 */ |
| 798 | |
| 799 | ``core_relo_rec_size`` specifies the size of ``bpf_core_relo`` |
| 800 | structure when .BTF.ext is generated. All ``bpf_core_relo`` structures |
| 801 | within a single ``btf_ext_info_sec`` describe relocations applied to |
| 802 | section named by ``btf_ext_info_sec->sec_name_off``. |
| 803 | |
Eduard Zingerman | 3888fa1 | 2023-09-01 15:59:35 +0300 | [diff] [blame] | 804 | See :ref:`Documentation/bpf/llvm_reloc.rst <btf-co-re-relocations>` |
Eduard Zingerman | be4033d | 2023-08-27 01:29:12 +0300 | [diff] [blame] | 805 | for more information on CO-RE relocations. |
| 806 | |
Jiri Olsa | 232ce4b | 2020-07-11 23:53:27 +0200 | [diff] [blame] | 807 | 4.2 .BTF_ids section |
Dave Tucker | 3ff36bf | 2021-11-12 21:17:22 +0000 | [diff] [blame] | 808 | -------------------- |
Jiri Olsa | 232ce4b | 2020-07-11 23:53:27 +0200 | [diff] [blame] | 809 | |
| 810 | The .BTF_ids section encodes BTF ID values that are used within the kernel. |
| 811 | |
| 812 | This section is created during the kernel compilation with the help of |
| 813 | macros defined in ``include/linux/btf_ids.h`` header file. Kernel code can |
| 814 | use them to create lists and sets (sorted lists) of BTF ID values. |
| 815 | |
| 816 | The ``BTF_ID_LIST`` and ``BTF_ID`` macros define unsorted list of BTF ID values, |
| 817 | with following syntax:: |
| 818 | |
| 819 | BTF_ID_LIST(list) |
| 820 | BTF_ID(type1, name1) |
| 821 | BTF_ID(type2, name2) |
| 822 | |
| 823 | resulting in following layout in .BTF_ids section:: |
| 824 | |
| 825 | __BTF_ID__type1__name1__1: |
| 826 | .zero 4 |
| 827 | __BTF_ID__type2__name2__2: |
| 828 | .zero 4 |
| 829 | |
| 830 | The ``u32 list[];`` variable is defined to access the list. |
| 831 | |
| 832 | The ``BTF_ID_UNUSED`` macro defines 4 zero bytes. It's used when we |
| 833 | want to define unused entry in BTF_ID_LIST, like:: |
| 834 | |
| 835 | BTF_ID_LIST(bpf_skb_output_btf_ids) |
| 836 | BTF_ID(struct, sk_buff) |
| 837 | BTF_ID_UNUSED |
| 838 | BTF_ID(struct, task_struct) |
| 839 | |
Jiri Olsa | 68a26bc | 2020-08-25 21:21:21 +0200 | [diff] [blame] | 840 | The ``BTF_SET_START/END`` macros pair defines sorted list of BTF ID values |
| 841 | and their count, with following syntax:: |
| 842 | |
| 843 | BTF_SET_START(set) |
| 844 | BTF_ID(type1, name1) |
| 845 | BTF_ID(type2, name2) |
| 846 | BTF_SET_END(set) |
| 847 | |
| 848 | resulting in following layout in .BTF_ids section:: |
| 849 | |
| 850 | __BTF_ID__set__set: |
| 851 | .zero 4 |
| 852 | __BTF_ID__type1__name1__3: |
| 853 | .zero 4 |
| 854 | __BTF_ID__type2__name2__4: |
| 855 | .zero 4 |
| 856 | |
| 857 | The ``struct btf_id_set set;`` variable is defined to access the list. |
| 858 | |
| 859 | The ``typeX`` name can be one of following:: |
| 860 | |
| 861 | struct, union, typedef, func |
| 862 | |
| 863 | and is used as a filter when resolving the BTF ID value. |
| 864 | |
Jiri Olsa | 232ce4b | 2020-07-11 23:53:27 +0200 | [diff] [blame] | 865 | All the BTF ID lists and sets are compiled in the .BTF_ids section and |
| 866 | resolved during the linking phase of kernel build by ``resolve_btfids`` tool. |
| 867 | |
Yonghong Song | ffcf7ce | 2019-01-18 13:56:49 -0800 | [diff] [blame] | 868 | 5. Using BTF |
Dave Tucker | 3ff36bf | 2021-11-12 21:17:22 +0000 | [diff] [blame] | 869 | ============ |
Yonghong Song | ffcf7ce | 2019-01-18 13:56:49 -0800 | [diff] [blame] | 870 | |
| 871 | 5.1 bpftool map pretty print |
Dave Tucker | 3ff36bf | 2021-11-12 21:17:22 +0000 | [diff] [blame] | 872 | ---------------------------- |
Yonghong Song | ffcf7ce | 2019-01-18 13:56:49 -0800 | [diff] [blame] | 873 | |
Andrii Nakryiko | 9ab5305 | 2019-02-28 17:12:20 -0800 | [diff] [blame] | 874 | With BTF, the map key/value can be printed based on fields rather than simply |
| 875 | raw bytes. This is especially valuable for large structure or if your data |
| 876 | structure has bitfields. For example, for the following map,:: |
Yonghong Song | ffcf7ce | 2019-01-18 13:56:49 -0800 | [diff] [blame] | 877 | |
| 878 | enum A { A1, A2, A3, A4, A5 }; |
| 879 | typedef enum A ___A; |
| 880 | struct tmp_t { |
| 881 | char a1:4; |
| 882 | int a2:4; |
| 883 | int :4; |
| 884 | __u32 a3:4; |
| 885 | int b; |
| 886 | ___A b1:4; |
| 887 | enum A b2:4; |
| 888 | }; |
Andrii Nakryiko | 96c8530 | 2022-01-19 22:05:29 -0800 | [diff] [blame] | 889 | struct { |
| 890 | __uint(type, BPF_MAP_TYPE_ARRAY); |
| 891 | __type(key, int); |
| 892 | __type(value, struct tmp_t); |
| 893 | __uint(max_entries, 1); |
| 894 | } tmpmap SEC(".maps"); |
Yonghong Song | ffcf7ce | 2019-01-18 13:56:49 -0800 | [diff] [blame] | 895 | |
| 896 | bpftool is able to pretty print like below: |
| 897 | :: |
| 898 | |
| 899 | [{ |
| 900 | "key": 0, |
| 901 | "value": { |
| 902 | "a1": 0x2, |
| 903 | "a2": 0x4, |
| 904 | "a3": 0x6, |
| 905 | "b": 7, |
| 906 | "b1": 0x8, |
| 907 | "b2": 0xa |
| 908 | } |
| 909 | } |
| 910 | ] |
| 911 | |
| 912 | 5.2 bpftool prog dump |
Dave Tucker | 3ff36bf | 2021-11-12 21:17:22 +0000 | [diff] [blame] | 913 | --------------------- |
Yonghong Song | ffcf7ce | 2019-01-18 13:56:49 -0800 | [diff] [blame] | 914 | |
Andrii Nakryiko | 9ab5305 | 2019-02-28 17:12:20 -0800 | [diff] [blame] | 915 | The following is an example showing how func_info and line_info can help prog |
| 916 | dump with better kernel symbol names, function prototypes and line |
| 917 | information.:: |
Yonghong Song | ffcf7ce | 2019-01-18 13:56:49 -0800 | [diff] [blame] | 918 | |
| 919 | $ bpftool prog dump jited pinned /sys/fs/bpf/test_btf_haskv |
| 920 | [...] |
| 921 | int test_long_fname_2(struct dummy_tracepoint_args * arg): |
| 922 | bpf_prog_44a040bf25481309_test_long_fname_2: |
| 923 | ; static int test_long_fname_2(struct dummy_tracepoint_args *arg) |
| 924 | 0: push %rbp |
| 925 | 1: mov %rsp,%rbp |
| 926 | 4: sub $0x30,%rsp |
| 927 | b: sub $0x28,%rbp |
| 928 | f: mov %rbx,0x0(%rbp) |
| 929 | 13: mov %r13,0x8(%rbp) |
| 930 | 17: mov %r14,0x10(%rbp) |
| 931 | 1b: mov %r15,0x18(%rbp) |
| 932 | 1f: xor %eax,%eax |
| 933 | 21: mov %rax,0x20(%rbp) |
| 934 | 25: xor %esi,%esi |
| 935 | ; int key = 0; |
| 936 | 27: mov %esi,-0x4(%rbp) |
| 937 | ; if (!arg->sock) |
| 938 | 2a: mov 0x8(%rdi),%rdi |
| 939 | ; if (!arg->sock) |
| 940 | 2e: cmp $0x0,%rdi |
| 941 | 32: je 0x0000000000000070 |
| 942 | 34: mov %rbp,%rsi |
| 943 | ; counts = bpf_map_lookup_elem(&btf_map, &key); |
| 944 | [...] |
| 945 | |
Andrii Nakryiko | 5efc529 | 2019-02-28 17:12:19 -0800 | [diff] [blame] | 946 | 5.3 Verifier Log |
Dave Tucker | 3ff36bf | 2021-11-12 21:17:22 +0000 | [diff] [blame] | 947 | ---------------- |
Yonghong Song | ffcf7ce | 2019-01-18 13:56:49 -0800 | [diff] [blame] | 948 | |
Andrii Nakryiko | 9ab5305 | 2019-02-28 17:12:20 -0800 | [diff] [blame] | 949 | The following is an example of how line_info can help debugging verification |
| 950 | failure.:: |
Yonghong Song | ffcf7ce | 2019-01-18 13:56:49 -0800 | [diff] [blame] | 951 | |
| 952 | /* The code at tools/testing/selftests/bpf/test_xdp_noinline.c |
| 953 | * is modified as below. |
| 954 | */ |
| 955 | data = (void *)(long)xdp->data; |
| 956 | data_end = (void *)(long)xdp->data_end; |
| 957 | /* |
| 958 | if (data + 4 > data_end) |
| 959 | return XDP_DROP; |
| 960 | */ |
| 961 | *(u32 *)data = dst->dst; |
| 962 | |
| 963 | $ bpftool prog load ./test_xdp_noinline.o /sys/fs/bpf/test_xdp_noinline type xdp |
| 964 | ; data = (void *)(long)xdp->data; |
| 965 | 224: (79) r2 = *(u64 *)(r10 -112) |
| 966 | 225: (61) r2 = *(u32 *)(r2 +0) |
| 967 | ; *(u32 *)data = dst->dst; |
| 968 | 226: (63) *(u32 *)(r2 +0) = r1 |
| 969 | invalid access to packet, off=0 size=4, R2(id=0,off=0,r=0) |
| 970 | R2 offset is outside of the packet |
| 971 | |
| 972 | 6. BTF Generation |
Dave Tucker | 3ff36bf | 2021-11-12 21:17:22 +0000 | [diff] [blame] | 973 | ================= |
Yonghong Song | ffcf7ce | 2019-01-18 13:56:49 -0800 | [diff] [blame] | 974 | |
| 975 | You need latest pahole |
| 976 | |
| 977 | https://git.kernel.org/pub/scm/devel/pahole/pahole.git/ |
| 978 | |
Andrii Nakryiko | 9ab5305 | 2019-02-28 17:12:20 -0800 | [diff] [blame] | 979 | or llvm (8.0 or later). The pahole acts as a dwarf2btf converter. It doesn't |
| 980 | support .BTF.ext and btf BTF_KIND_FUNC type yet. For example,:: |
Yonghong Song | ffcf7ce | 2019-01-18 13:56:49 -0800 | [diff] [blame] | 981 | |
| 982 | -bash-4.4$ cat t.c |
| 983 | struct t { |
| 984 | int a:2; |
| 985 | int b:3; |
| 986 | int c:2; |
| 987 | } g; |
| 988 | -bash-4.4$ gcc -c -O2 -g t.c |
| 989 | -bash-4.4$ pahole -JV t.o |
| 990 | File t.o: |
| 991 | [1] STRUCT t kind_flag=1 size=4 vlen=3 |
| 992 | a type_id=2 bitfield_size=2 bits_offset=0 |
| 993 | b type_id=2 bitfield_size=3 bits_offset=2 |
| 994 | c type_id=2 bitfield_size=2 bits_offset=5 |
| 995 | [2] INT int size=4 bit_offset=0 nr_bits=32 encoding=SIGNED |
| 996 | |
Andrii Nakryiko | 9ab5305 | 2019-02-28 17:12:20 -0800 | [diff] [blame] | 997 | The llvm is able to generate .BTF and .BTF.ext directly with -g for bpf target |
| 998 | only. The assembly code (-S) is able to show the BTF encoding in assembly |
| 999 | format.:: |
Yonghong Song | ffcf7ce | 2019-01-18 13:56:49 -0800 | [diff] [blame] | 1000 | |
| 1001 | -bash-4.4$ cat t2.c |
| 1002 | typedef int __int32; |
| 1003 | struct t2 { |
| 1004 | int a2; |
| 1005 | int (*f2)(char q1, __int32 q2, ...); |
| 1006 | int (*f3)(); |
| 1007 | } g2; |
| 1008 | int main() { return 0; } |
| 1009 | int test() { return 0; } |
Fangrui Song | bbaf1ff | 2023-06-24 00:18:56 +0000 | [diff] [blame] | 1010 | -bash-4.4$ clang -c -g -O2 --target=bpf t2.c |
Yonghong Song | ffcf7ce | 2019-01-18 13:56:49 -0800 | [diff] [blame] | 1011 | -bash-4.4$ readelf -S t2.o |
| 1012 | ...... |
| 1013 | [ 8] .BTF PROGBITS 0000000000000000 00000247 |
| 1014 | 000000000000016e 0000000000000000 0 0 1 |
| 1015 | [ 9] .BTF.ext PROGBITS 0000000000000000 000003b5 |
| 1016 | 0000000000000060 0000000000000000 0 0 1 |
| 1017 | [10] .rel.BTF.ext REL 0000000000000000 000007e0 |
| 1018 | 0000000000000040 0000000000000010 16 9 8 |
| 1019 | ...... |
Fangrui Song | bbaf1ff | 2023-06-24 00:18:56 +0000 | [diff] [blame] | 1020 | -bash-4.4$ clang -S -g -O2 --target=bpf t2.c |
Yonghong Song | ffcf7ce | 2019-01-18 13:56:49 -0800 | [diff] [blame] | 1021 | -bash-4.4$ cat t2.s |
| 1022 | ...... |
| 1023 | .section .BTF,"",@progbits |
| 1024 | .short 60319 # 0xeb9f |
| 1025 | .byte 1 |
| 1026 | .byte 0 |
| 1027 | .long 24 |
| 1028 | .long 0 |
| 1029 | .long 220 |
| 1030 | .long 220 |
| 1031 | .long 122 |
| 1032 | .long 0 # BTF_KIND_FUNC_PROTO(id = 1) |
| 1033 | .long 218103808 # 0xd000000 |
| 1034 | .long 2 |
| 1035 | .long 83 # BTF_KIND_INT(id = 2) |
| 1036 | .long 16777216 # 0x1000000 |
| 1037 | .long 4 |
| 1038 | .long 16777248 # 0x1000020 |
| 1039 | ...... |
| 1040 | .byte 0 # string offset=0 |
| 1041 | .ascii ".text" # string offset=1 |
| 1042 | .byte 0 |
| 1043 | .ascii "/home/yhs/tmp-pahole/t2.c" # string offset=7 |
| 1044 | .byte 0 |
| 1045 | .ascii "int main() { return 0; }" # string offset=33 |
| 1046 | .byte 0 |
| 1047 | .ascii "int test() { return 0; }" # string offset=58 |
| 1048 | .byte 0 |
| 1049 | .ascii "int" # string offset=83 |
| 1050 | ...... |
| 1051 | .section .BTF.ext,"",@progbits |
| 1052 | .short 60319 # 0xeb9f |
| 1053 | .byte 1 |
| 1054 | .byte 0 |
| 1055 | .long 24 |
| 1056 | .long 0 |
| 1057 | .long 28 |
| 1058 | .long 28 |
| 1059 | .long 44 |
| 1060 | .long 8 # FuncInfo |
| 1061 | .long 1 # FuncInfo section string offset=1 |
| 1062 | .long 2 |
| 1063 | .long .Lfunc_begin0 |
| 1064 | .long 3 |
| 1065 | .long .Lfunc_begin1 |
| 1066 | .long 5 |
| 1067 | .long 16 # LineInfo |
| 1068 | .long 1 # LineInfo section string offset=1 |
| 1069 | .long 2 |
| 1070 | .long .Ltmp0 |
| 1071 | .long 7 |
| 1072 | .long 33 |
| 1073 | .long 7182 # Line 7 Col 14 |
| 1074 | .long .Ltmp3 |
| 1075 | .long 7 |
| 1076 | .long 58 |
| 1077 | .long 8206 # Line 8 Col 14 |
| 1078 | |
| 1079 | 7. Testing |
Dave Tucker | 3ff36bf | 2021-11-12 21:17:22 +0000 | [diff] [blame] | 1080 | ========== |
Yonghong Song | ffcf7ce | 2019-01-18 13:56:49 -0800 | [diff] [blame] | 1081 | |
Rong Tao | b74344c | 2022-11-22 08:50:42 +0800 | [diff] [blame] | 1082 | The kernel BPF selftest `tools/testing/selftests/bpf/prog_tests/btf.c`_ |
| 1083 | provides an extensive set of BTF-related tests. |
| 1084 | |
| 1085 | .. Links |
| 1086 | .. _tools/testing/selftests/bpf/prog_tests/btf.c: |
| 1087 | https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/tree/tools/testing/selftests/bpf/prog_tests/btf.c |