.. | .. |
---|
1 | | -/* SPDX-License-Identifier: LGPL-2.1 */ |
---|
| 1 | +/* SPDX-License-Identifier: (LGPL-2.1 OR BSD-2-Clause) */ |
---|
2 | 2 | /* Copyright (c) 2018 Facebook */ |
---|
3 | 3 | |
---|
4 | | -#ifndef __BPF_BTF_H |
---|
5 | | -#define __BPF_BTF_H |
---|
| 4 | +#ifndef __LIBBPF_BTF_H |
---|
| 5 | +#define __LIBBPF_BTF_H |
---|
6 | 6 | |
---|
| 7 | +#include <stdarg.h> |
---|
| 8 | +#include <stdbool.h> |
---|
| 9 | +#include <linux/btf.h> |
---|
7 | 10 | #include <linux/types.h> |
---|
8 | 11 | |
---|
| 12 | +#include "libbpf_common.h" |
---|
| 13 | + |
---|
| 14 | +#ifdef __cplusplus |
---|
| 15 | +extern "C" { |
---|
| 16 | +#endif |
---|
| 17 | + |
---|
9 | 18 | #define BTF_ELF_SEC ".BTF" |
---|
| 19 | +#define BTF_EXT_ELF_SEC ".BTF.ext" |
---|
| 20 | +#define MAPS_ELF_SEC ".maps" |
---|
10 | 21 | |
---|
11 | 22 | struct btf; |
---|
| 23 | +struct btf_ext; |
---|
12 | 24 | struct btf_type; |
---|
13 | 25 | |
---|
14 | | -typedef int (*btf_print_fn_t)(const char *, ...) |
---|
15 | | - __attribute__((format(printf, 1, 2))); |
---|
| 26 | +struct bpf_object; |
---|
16 | 27 | |
---|
17 | | -void btf__free(struct btf *btf); |
---|
18 | | -struct btf *btf__new(__u8 *data, __u32 size, btf_print_fn_t err_log); |
---|
19 | | -__s32 btf__find_by_name(const struct btf *btf, const char *type_name); |
---|
20 | | -const struct btf_type *btf__type_by_id(const struct btf *btf, __u32 id); |
---|
21 | | -__s64 btf__resolve_size(const struct btf *btf, __u32 type_id); |
---|
22 | | -int btf__resolve_type(const struct btf *btf, __u32 type_id); |
---|
23 | | -int btf__fd(const struct btf *btf); |
---|
24 | | -const char *btf__name_by_offset(const struct btf *btf, __u32 offset); |
---|
| 28 | +enum btf_endianness { |
---|
| 29 | + BTF_LITTLE_ENDIAN = 0, |
---|
| 30 | + BTF_BIG_ENDIAN = 1, |
---|
| 31 | +}; |
---|
25 | 32 | |
---|
| 33 | +LIBBPF_API void btf__free(struct btf *btf); |
---|
| 34 | +LIBBPF_API struct btf *btf__new(const void *data, __u32 size); |
---|
| 35 | +LIBBPF_API struct btf *btf__new_empty(void); |
---|
| 36 | +LIBBPF_API struct btf *btf__parse(const char *path, struct btf_ext **btf_ext); |
---|
| 37 | +LIBBPF_API struct btf *btf__parse_elf(const char *path, struct btf_ext **btf_ext); |
---|
| 38 | +LIBBPF_API struct btf *btf__parse_raw(const char *path); |
---|
| 39 | +LIBBPF_API int btf__finalize_data(struct bpf_object *obj, struct btf *btf); |
---|
| 40 | +LIBBPF_API int btf__load(struct btf *btf); |
---|
| 41 | +LIBBPF_API __s32 btf__find_by_name(const struct btf *btf, |
---|
| 42 | + const char *type_name); |
---|
| 43 | +LIBBPF_API __s32 btf__find_by_name_kind(const struct btf *btf, |
---|
| 44 | + const char *type_name, __u32 kind); |
---|
| 45 | +LIBBPF_API __u32 btf__get_nr_types(const struct btf *btf); |
---|
| 46 | +LIBBPF_API const struct btf_type *btf__type_by_id(const struct btf *btf, |
---|
| 47 | + __u32 id); |
---|
| 48 | +LIBBPF_API size_t btf__pointer_size(const struct btf *btf); |
---|
| 49 | +LIBBPF_API int btf__set_pointer_size(struct btf *btf, size_t ptr_sz); |
---|
| 50 | +LIBBPF_API enum btf_endianness btf__endianness(const struct btf *btf); |
---|
| 51 | +LIBBPF_API int btf__set_endianness(struct btf *btf, enum btf_endianness endian); |
---|
| 52 | +LIBBPF_API __s64 btf__resolve_size(const struct btf *btf, __u32 type_id); |
---|
| 53 | +LIBBPF_API int btf__resolve_type(const struct btf *btf, __u32 type_id); |
---|
| 54 | +LIBBPF_API int btf__align_of(const struct btf *btf, __u32 id); |
---|
| 55 | +LIBBPF_API int btf__fd(const struct btf *btf); |
---|
| 56 | +LIBBPF_API void btf__set_fd(struct btf *btf, int fd); |
---|
| 57 | +LIBBPF_API const void *btf__get_raw_data(const struct btf *btf, __u32 *size); |
---|
| 58 | +LIBBPF_API const char *btf__name_by_offset(const struct btf *btf, __u32 offset); |
---|
| 59 | +LIBBPF_API const char *btf__str_by_offset(const struct btf *btf, __u32 offset); |
---|
| 60 | +LIBBPF_API int btf__get_from_id(__u32 id, struct btf **btf); |
---|
| 61 | +LIBBPF_API int btf__get_map_kv_tids(const struct btf *btf, const char *map_name, |
---|
| 62 | + __u32 expected_key_size, |
---|
| 63 | + __u32 expected_value_size, |
---|
| 64 | + __u32 *key_type_id, __u32 *value_type_id); |
---|
| 65 | + |
---|
| 66 | +LIBBPF_API struct btf_ext *btf_ext__new(__u8 *data, __u32 size); |
---|
| 67 | +LIBBPF_API void btf_ext__free(struct btf_ext *btf_ext); |
---|
| 68 | +LIBBPF_API const void *btf_ext__get_raw_data(const struct btf_ext *btf_ext, |
---|
| 69 | + __u32 *size); |
---|
| 70 | +LIBBPF_API LIBBPF_DEPRECATED("btf_ext__reloc_func_info was never meant as a public API and has wrong assumptions embedded in it; it will be removed in the future libbpf versions") |
---|
| 71 | +int btf_ext__reloc_func_info(const struct btf *btf, |
---|
| 72 | + const struct btf_ext *btf_ext, |
---|
| 73 | + const char *sec_name, __u32 insns_cnt, |
---|
| 74 | + void **func_info, __u32 *cnt); |
---|
| 75 | +LIBBPF_API LIBBPF_DEPRECATED("btf_ext__reloc_line_info was never meant as a public API and has wrong assumptions embedded in it; it will be removed in the future libbpf versions") |
---|
| 76 | +int btf_ext__reloc_line_info(const struct btf *btf, |
---|
| 77 | + const struct btf_ext *btf_ext, |
---|
| 78 | + const char *sec_name, __u32 insns_cnt, |
---|
| 79 | + void **line_info, __u32 *cnt); |
---|
| 80 | +LIBBPF_API __u32 btf_ext__func_info_rec_size(const struct btf_ext *btf_ext); |
---|
| 81 | +LIBBPF_API __u32 btf_ext__line_info_rec_size(const struct btf_ext *btf_ext); |
---|
| 82 | + |
---|
| 83 | +LIBBPF_API struct btf *libbpf_find_kernel_btf(void); |
---|
| 84 | + |
---|
| 85 | +LIBBPF_API int btf__find_str(struct btf *btf, const char *s); |
---|
| 86 | +LIBBPF_API int btf__add_str(struct btf *btf, const char *s); |
---|
| 87 | + |
---|
| 88 | +LIBBPF_API int btf__add_int(struct btf *btf, const char *name, size_t byte_sz, int encoding); |
---|
| 89 | +LIBBPF_API int btf__add_ptr(struct btf *btf, int ref_type_id); |
---|
| 90 | +LIBBPF_API int btf__add_array(struct btf *btf, |
---|
| 91 | + int index_type_id, int elem_type_id, __u32 nr_elems); |
---|
| 92 | +/* struct/union construction APIs */ |
---|
| 93 | +LIBBPF_API int btf__add_struct(struct btf *btf, const char *name, __u32 sz); |
---|
| 94 | +LIBBPF_API int btf__add_union(struct btf *btf, const char *name, __u32 sz); |
---|
| 95 | +LIBBPF_API int btf__add_field(struct btf *btf, const char *name, int field_type_id, |
---|
| 96 | + __u32 bit_offset, __u32 bit_size); |
---|
| 97 | + |
---|
| 98 | +/* enum construction APIs */ |
---|
| 99 | +LIBBPF_API int btf__add_enum(struct btf *btf, const char *name, __u32 bytes_sz); |
---|
| 100 | +LIBBPF_API int btf__add_enum_value(struct btf *btf, const char *name, __s64 value); |
---|
| 101 | + |
---|
| 102 | +enum btf_fwd_kind { |
---|
| 103 | + BTF_FWD_STRUCT = 0, |
---|
| 104 | + BTF_FWD_UNION = 1, |
---|
| 105 | + BTF_FWD_ENUM = 2, |
---|
| 106 | +}; |
---|
| 107 | + |
---|
| 108 | +LIBBPF_API int btf__add_fwd(struct btf *btf, const char *name, enum btf_fwd_kind fwd_kind); |
---|
| 109 | +LIBBPF_API int btf__add_typedef(struct btf *btf, const char *name, int ref_type_id); |
---|
| 110 | +LIBBPF_API int btf__add_volatile(struct btf *btf, int ref_type_id); |
---|
| 111 | +LIBBPF_API int btf__add_const(struct btf *btf, int ref_type_id); |
---|
| 112 | +LIBBPF_API int btf__add_restrict(struct btf *btf, int ref_type_id); |
---|
| 113 | + |
---|
| 114 | +/* func and func_proto construction APIs */ |
---|
| 115 | +LIBBPF_API int btf__add_func(struct btf *btf, const char *name, |
---|
| 116 | + enum btf_func_linkage linkage, int proto_type_id); |
---|
| 117 | +LIBBPF_API int btf__add_func_proto(struct btf *btf, int ret_type_id); |
---|
| 118 | +LIBBPF_API int btf__add_func_param(struct btf *btf, const char *name, int type_id); |
---|
| 119 | + |
---|
| 120 | +/* var & datasec construction APIs */ |
---|
| 121 | +LIBBPF_API int btf__add_var(struct btf *btf, const char *name, int linkage, int type_id); |
---|
| 122 | +LIBBPF_API int btf__add_datasec(struct btf *btf, const char *name, __u32 byte_sz); |
---|
| 123 | +LIBBPF_API int btf__add_datasec_var_info(struct btf *btf, int var_type_id, |
---|
| 124 | + __u32 offset, __u32 byte_sz); |
---|
| 125 | + |
---|
| 126 | +struct btf_dedup_opts { |
---|
| 127 | + unsigned int dedup_table_size; |
---|
| 128 | + bool dont_resolve_fwds; |
---|
| 129 | +}; |
---|
| 130 | + |
---|
| 131 | +LIBBPF_API int btf__dedup(struct btf *btf, struct btf_ext *btf_ext, |
---|
| 132 | + const struct btf_dedup_opts *opts); |
---|
| 133 | + |
---|
| 134 | +struct btf_dump; |
---|
| 135 | + |
---|
| 136 | +struct btf_dump_opts { |
---|
| 137 | + void *ctx; |
---|
| 138 | +}; |
---|
| 139 | + |
---|
| 140 | +typedef void (*btf_dump_printf_fn_t)(void *ctx, const char *fmt, va_list args); |
---|
| 141 | + |
---|
| 142 | +LIBBPF_API struct btf_dump *btf_dump__new(const struct btf *btf, |
---|
| 143 | + const struct btf_ext *btf_ext, |
---|
| 144 | + const struct btf_dump_opts *opts, |
---|
| 145 | + btf_dump_printf_fn_t printf_fn); |
---|
| 146 | +LIBBPF_API void btf_dump__free(struct btf_dump *d); |
---|
| 147 | + |
---|
| 148 | +LIBBPF_API int btf_dump__dump_type(struct btf_dump *d, __u32 id); |
---|
| 149 | + |
---|
| 150 | +struct btf_dump_emit_type_decl_opts { |
---|
| 151 | + /* size of this struct, for forward/backward compatiblity */ |
---|
| 152 | + size_t sz; |
---|
| 153 | + /* optional field name for type declaration, e.g.: |
---|
| 154 | + * - struct my_struct <FNAME> |
---|
| 155 | + * - void (*<FNAME>)(int) |
---|
| 156 | + * - char (*<FNAME>)[123] |
---|
| 157 | + */ |
---|
| 158 | + const char *field_name; |
---|
| 159 | + /* extra indentation level (in number of tabs) to emit for multi-line |
---|
| 160 | + * type declarations (e.g., anonymous struct); applies for lines |
---|
| 161 | + * starting from the second one (first line is assumed to have |
---|
| 162 | + * necessary indentation already |
---|
| 163 | + */ |
---|
| 164 | + int indent_level; |
---|
| 165 | + /* strip all the const/volatile/restrict mods */ |
---|
| 166 | + bool strip_mods; |
---|
| 167 | + size_t :0; |
---|
| 168 | +}; |
---|
| 169 | +#define btf_dump_emit_type_decl_opts__last_field strip_mods |
---|
| 170 | + |
---|
| 171 | +LIBBPF_API int |
---|
| 172 | +btf_dump__emit_type_decl(struct btf_dump *d, __u32 id, |
---|
| 173 | + const struct btf_dump_emit_type_decl_opts *opts); |
---|
| 174 | + |
---|
| 175 | +/* |
---|
| 176 | + * A set of helpers for easier BTF types handling |
---|
| 177 | + */ |
---|
| 178 | +static inline __u16 btf_kind(const struct btf_type *t) |
---|
| 179 | +{ |
---|
| 180 | + return BTF_INFO_KIND(t->info); |
---|
| 181 | +} |
---|
| 182 | + |
---|
| 183 | +static inline __u16 btf_vlen(const struct btf_type *t) |
---|
| 184 | +{ |
---|
| 185 | + return BTF_INFO_VLEN(t->info); |
---|
| 186 | +} |
---|
| 187 | + |
---|
| 188 | +static inline bool btf_kflag(const struct btf_type *t) |
---|
| 189 | +{ |
---|
| 190 | + return BTF_INFO_KFLAG(t->info); |
---|
| 191 | +} |
---|
| 192 | + |
---|
| 193 | +static inline bool btf_is_void(const struct btf_type *t) |
---|
| 194 | +{ |
---|
| 195 | + return btf_kind(t) == BTF_KIND_UNKN; |
---|
| 196 | +} |
---|
| 197 | + |
---|
| 198 | +static inline bool btf_is_int(const struct btf_type *t) |
---|
| 199 | +{ |
---|
| 200 | + return btf_kind(t) == BTF_KIND_INT; |
---|
| 201 | +} |
---|
| 202 | + |
---|
| 203 | +static inline bool btf_is_ptr(const struct btf_type *t) |
---|
| 204 | +{ |
---|
| 205 | + return btf_kind(t) == BTF_KIND_PTR; |
---|
| 206 | +} |
---|
| 207 | + |
---|
| 208 | +static inline bool btf_is_array(const struct btf_type *t) |
---|
| 209 | +{ |
---|
| 210 | + return btf_kind(t) == BTF_KIND_ARRAY; |
---|
| 211 | +} |
---|
| 212 | + |
---|
| 213 | +static inline bool btf_is_struct(const struct btf_type *t) |
---|
| 214 | +{ |
---|
| 215 | + return btf_kind(t) == BTF_KIND_STRUCT; |
---|
| 216 | +} |
---|
| 217 | + |
---|
| 218 | +static inline bool btf_is_union(const struct btf_type *t) |
---|
| 219 | +{ |
---|
| 220 | + return btf_kind(t) == BTF_KIND_UNION; |
---|
| 221 | +} |
---|
| 222 | + |
---|
| 223 | +static inline bool btf_is_composite(const struct btf_type *t) |
---|
| 224 | +{ |
---|
| 225 | + __u16 kind = btf_kind(t); |
---|
| 226 | + |
---|
| 227 | + return kind == BTF_KIND_STRUCT || kind == BTF_KIND_UNION; |
---|
| 228 | +} |
---|
| 229 | + |
---|
| 230 | +static inline bool btf_is_enum(const struct btf_type *t) |
---|
| 231 | +{ |
---|
| 232 | + return btf_kind(t) == BTF_KIND_ENUM; |
---|
| 233 | +} |
---|
| 234 | + |
---|
| 235 | +static inline bool btf_is_fwd(const struct btf_type *t) |
---|
| 236 | +{ |
---|
| 237 | + return btf_kind(t) == BTF_KIND_FWD; |
---|
| 238 | +} |
---|
| 239 | + |
---|
| 240 | +static inline bool btf_is_typedef(const struct btf_type *t) |
---|
| 241 | +{ |
---|
| 242 | + return btf_kind(t) == BTF_KIND_TYPEDEF; |
---|
| 243 | +} |
---|
| 244 | + |
---|
| 245 | +static inline bool btf_is_volatile(const struct btf_type *t) |
---|
| 246 | +{ |
---|
| 247 | + return btf_kind(t) == BTF_KIND_VOLATILE; |
---|
| 248 | +} |
---|
| 249 | + |
---|
| 250 | +static inline bool btf_is_const(const struct btf_type *t) |
---|
| 251 | +{ |
---|
| 252 | + return btf_kind(t) == BTF_KIND_CONST; |
---|
| 253 | +} |
---|
| 254 | + |
---|
| 255 | +static inline bool btf_is_restrict(const struct btf_type *t) |
---|
| 256 | +{ |
---|
| 257 | + return btf_kind(t) == BTF_KIND_RESTRICT; |
---|
| 258 | +} |
---|
| 259 | + |
---|
| 260 | +static inline bool btf_is_mod(const struct btf_type *t) |
---|
| 261 | +{ |
---|
| 262 | + __u16 kind = btf_kind(t); |
---|
| 263 | + |
---|
| 264 | + return kind == BTF_KIND_VOLATILE || |
---|
| 265 | + kind == BTF_KIND_CONST || |
---|
| 266 | + kind == BTF_KIND_RESTRICT; |
---|
| 267 | +} |
---|
| 268 | + |
---|
| 269 | +static inline bool btf_is_func(const struct btf_type *t) |
---|
| 270 | +{ |
---|
| 271 | + return btf_kind(t) == BTF_KIND_FUNC; |
---|
| 272 | +} |
---|
| 273 | + |
---|
| 274 | +static inline bool btf_is_func_proto(const struct btf_type *t) |
---|
| 275 | +{ |
---|
| 276 | + return btf_kind(t) == BTF_KIND_FUNC_PROTO; |
---|
| 277 | +} |
---|
| 278 | + |
---|
| 279 | +static inline bool btf_is_var(const struct btf_type *t) |
---|
| 280 | +{ |
---|
| 281 | + return btf_kind(t) == BTF_KIND_VAR; |
---|
| 282 | +} |
---|
| 283 | + |
---|
| 284 | +static inline bool btf_is_datasec(const struct btf_type *t) |
---|
| 285 | +{ |
---|
| 286 | + return btf_kind(t) == BTF_KIND_DATASEC; |
---|
| 287 | +} |
---|
| 288 | + |
---|
| 289 | +static inline __u8 btf_int_encoding(const struct btf_type *t) |
---|
| 290 | +{ |
---|
| 291 | + return BTF_INT_ENCODING(*(__u32 *)(t + 1)); |
---|
| 292 | +} |
---|
| 293 | + |
---|
| 294 | +static inline __u8 btf_int_offset(const struct btf_type *t) |
---|
| 295 | +{ |
---|
| 296 | + return BTF_INT_OFFSET(*(__u32 *)(t + 1)); |
---|
| 297 | +} |
---|
| 298 | + |
---|
| 299 | +static inline __u8 btf_int_bits(const struct btf_type *t) |
---|
| 300 | +{ |
---|
| 301 | + return BTF_INT_BITS(*(__u32 *)(t + 1)); |
---|
| 302 | +} |
---|
| 303 | + |
---|
| 304 | +static inline struct btf_array *btf_array(const struct btf_type *t) |
---|
| 305 | +{ |
---|
| 306 | + return (struct btf_array *)(t + 1); |
---|
| 307 | +} |
---|
| 308 | + |
---|
| 309 | +static inline struct btf_enum *btf_enum(const struct btf_type *t) |
---|
| 310 | +{ |
---|
| 311 | + return (struct btf_enum *)(t + 1); |
---|
| 312 | +} |
---|
| 313 | + |
---|
| 314 | +static inline struct btf_member *btf_members(const struct btf_type *t) |
---|
| 315 | +{ |
---|
| 316 | + return (struct btf_member *)(t + 1); |
---|
| 317 | +} |
---|
| 318 | + |
---|
| 319 | +/* Get bit offset of a member with specified index. */ |
---|
| 320 | +static inline __u32 btf_member_bit_offset(const struct btf_type *t, |
---|
| 321 | + __u32 member_idx) |
---|
| 322 | +{ |
---|
| 323 | + const struct btf_member *m = btf_members(t) + member_idx; |
---|
| 324 | + bool kflag = btf_kflag(t); |
---|
| 325 | + |
---|
| 326 | + return kflag ? BTF_MEMBER_BIT_OFFSET(m->offset) : m->offset; |
---|
| 327 | +} |
---|
| 328 | +/* |
---|
| 329 | + * Get bitfield size of a member, assuming t is BTF_KIND_STRUCT or |
---|
| 330 | + * BTF_KIND_UNION. If member is not a bitfield, zero is returned. |
---|
| 331 | + */ |
---|
| 332 | +static inline __u32 btf_member_bitfield_size(const struct btf_type *t, |
---|
| 333 | + __u32 member_idx) |
---|
| 334 | +{ |
---|
| 335 | + const struct btf_member *m = btf_members(t) + member_idx; |
---|
| 336 | + bool kflag = btf_kflag(t); |
---|
| 337 | + |
---|
| 338 | + return kflag ? BTF_MEMBER_BITFIELD_SIZE(m->offset) : 0; |
---|
| 339 | +} |
---|
| 340 | + |
---|
| 341 | +static inline struct btf_param *btf_params(const struct btf_type *t) |
---|
| 342 | +{ |
---|
| 343 | + return (struct btf_param *)(t + 1); |
---|
| 344 | +} |
---|
| 345 | + |
---|
| 346 | +static inline struct btf_var *btf_var(const struct btf_type *t) |
---|
| 347 | +{ |
---|
| 348 | + return (struct btf_var *)(t + 1); |
---|
| 349 | +} |
---|
| 350 | + |
---|
| 351 | +static inline struct btf_var_secinfo * |
---|
| 352 | +btf_var_secinfos(const struct btf_type *t) |
---|
| 353 | +{ |
---|
| 354 | + return (struct btf_var_secinfo *)(t + 1); |
---|
| 355 | +} |
---|
| 356 | + |
---|
| 357 | +#ifdef __cplusplus |
---|
| 358 | +} /* extern "C" */ |
---|
26 | 359 | #endif |
---|
| 360 | + |
---|
| 361 | +#endif /* __LIBBPF_BTF_H */ |
---|