linux/tools/lib/bpf/libbpf_internal.h
<<
>>
Prefs
   1/* SPDX-License-Identifier: (LGPL-2.1 OR BSD-2-Clause) */
   2
   3/*
   4 * Internal libbpf helpers.
   5 *
   6 * Copyright (c) 2019 Facebook
   7 */
   8
   9#ifndef __LIBBPF_LIBBPF_INTERNAL_H
  10#define __LIBBPF_LIBBPF_INTERNAL_H
  11
  12#include <stdlib.h>
  13#include <limits.h>
  14#include <errno.h>
  15#include <linux/err.h>
  16#include <fcntl.h>
  17#include <unistd.h>
  18#include "libbpf_legacy.h"
  19#include "relo_core.h"
  20
  21/* make sure libbpf doesn't use kernel-only integer typedefs */
  22#pragma GCC poison u8 u16 u32 u64 s8 s16 s32 s64
  23
  24/* prevent accidental re-addition of reallocarray() */
  25#pragma GCC poison reallocarray
  26
  27#include "libbpf.h"
  28#include "btf.h"
  29
  30#ifndef EM_BPF
  31#define EM_BPF 247
  32#endif
  33
  34#ifndef R_BPF_64_64
  35#define R_BPF_64_64 1
  36#endif
  37#ifndef R_BPF_64_ABS64
  38#define R_BPF_64_ABS64 2
  39#endif
  40#ifndef R_BPF_64_ABS32
  41#define R_BPF_64_ABS32 3
  42#endif
  43#ifndef R_BPF_64_32
  44#define R_BPF_64_32 10
  45#endif
  46
  47#ifndef SHT_LLVM_ADDRSIG
  48#define SHT_LLVM_ADDRSIG 0x6FFF4C03
  49#endif
  50
  51/* if libelf is old and doesn't support mmap(), fall back to read() */
  52#ifndef ELF_C_READ_MMAP
  53#define ELF_C_READ_MMAP ELF_C_READ
  54#endif
  55
  56/* Older libelf all end up in this expression, for both 32 and 64 bit */
  57#ifndef ELF64_ST_VISIBILITY
  58#define ELF64_ST_VISIBILITY(o) ((o) & 0x03)
  59#endif
  60
  61#define BTF_INFO_ENC(kind, kind_flag, vlen) \
  62        ((!!(kind_flag) << 31) | ((kind) << 24) | ((vlen) & BTF_MAX_VLEN))
  63#define BTF_TYPE_ENC(name, info, size_or_type) (name), (info), (size_or_type)
  64#define BTF_INT_ENC(encoding, bits_offset, nr_bits) \
  65        ((encoding) << 24 | (bits_offset) << 16 | (nr_bits))
  66#define BTF_TYPE_INT_ENC(name, encoding, bits_offset, bits, sz) \
  67        BTF_TYPE_ENC(name, BTF_INFO_ENC(BTF_KIND_INT, 0, 0), sz), \
  68        BTF_INT_ENC(encoding, bits_offset, bits)
  69#define BTF_MEMBER_ENC(name, type, bits_offset) (name), (type), (bits_offset)
  70#define BTF_PARAM_ENC(name, type) (name), (type)
  71#define BTF_VAR_SECINFO_ENC(type, offset, size) (type), (offset), (size)
  72#define BTF_TYPE_FLOAT_ENC(name, sz) \
  73        BTF_TYPE_ENC(name, BTF_INFO_ENC(BTF_KIND_FLOAT, 0, 0), sz)
  74#define BTF_TYPE_DECL_TAG_ENC(value, type, component_idx) \
  75        BTF_TYPE_ENC(value, BTF_INFO_ENC(BTF_KIND_DECL_TAG, 0, 0), type), (component_idx)
  76
  77#ifndef likely
  78#define likely(x) __builtin_expect(!!(x), 1)
  79#endif
  80#ifndef unlikely
  81#define unlikely(x) __builtin_expect(!!(x), 0)
  82#endif
  83#ifndef min
  84# define min(x, y) ((x) < (y) ? (x) : (y))
  85#endif
  86#ifndef max
  87# define max(x, y) ((x) < (y) ? (y) : (x))
  88#endif
  89#ifndef offsetofend
  90# define offsetofend(TYPE, FIELD) \
  91        (offsetof(TYPE, FIELD) + sizeof(((TYPE *)0)->FIELD))
  92#endif
  93
  94/* Check whether a string `str` has prefix `pfx`, regardless if `pfx` is
  95 * a string literal known at compilation time or char * pointer known only at
  96 * runtime.
  97 */
  98#define str_has_pfx(str, pfx) \
  99        (strncmp(str, pfx, __builtin_constant_p(pfx) ? sizeof(pfx) - 1 : strlen(pfx)) == 0)
 100
 101/* Symbol versioning is different between static and shared library.
 102 * Properly versioned symbols are needed for shared library, but
 103 * only the symbol of the new version is needed for static library.
 104 * Starting with GNU C 10, use symver attribute instead of .symver assembler
 105 * directive, which works better with GCC LTO builds.
 106 */
 107#if defined(SHARED) && defined(__GNUC__) && __GNUC__ >= 10
 108
 109#define DEFAULT_VERSION(internal_name, api_name, version) \
 110        __attribute__((symver(#api_name "@@" #version)))
 111#define COMPAT_VERSION(internal_name, api_name, version) \
 112        __attribute__((symver(#api_name "@" #version)))
 113
 114#elif defined(SHARED)
 115
 116#define COMPAT_VERSION(internal_name, api_name, version) \
 117        asm(".symver " #internal_name "," #api_name "@" #version);
 118#define DEFAULT_VERSION(internal_name, api_name, version) \
 119        asm(".symver " #internal_name "," #api_name "@@" #version);
 120
 121#else /* !SHARED */
 122
 123#define COMPAT_VERSION(internal_name, api_name, version)
 124#define DEFAULT_VERSION(internal_name, api_name, version) \
 125        extern typeof(internal_name) api_name \
 126        __attribute__((alias(#internal_name)));
 127
 128#endif
 129
 130extern void libbpf_print(enum libbpf_print_level level,
 131                         const char *format, ...)
 132        __attribute__((format(printf, 2, 3)));
 133
 134#define __pr(level, fmt, ...)   \
 135do {                            \
 136        libbpf_print(level, "libbpf: " fmt, ##__VA_ARGS__);     \
 137} while (0)
 138
 139#define pr_warn(fmt, ...)       __pr(LIBBPF_WARN, fmt, ##__VA_ARGS__)
 140#define pr_info(fmt, ...)       __pr(LIBBPF_INFO, fmt, ##__VA_ARGS__)
 141#define pr_debug(fmt, ...)      __pr(LIBBPF_DEBUG, fmt, ##__VA_ARGS__)
 142
 143#ifndef __has_builtin
 144#define __has_builtin(x) 0
 145#endif
 146/*
 147 * Re-implement glibc's reallocarray() for libbpf internal-only use.
 148 * reallocarray(), unfortunately, is not available in all versions of glibc,
 149 * so requires extra feature detection and using reallocarray() stub from
 150 * <tools/libc_compat.h> and COMPAT_NEED_REALLOCARRAY. All this complicates
 151 * build of libbpf unnecessarily and is just a maintenance burden. Instead,
 152 * it's trivial to implement libbpf-specific internal version and use it
 153 * throughout libbpf.
 154 */
 155static inline void *libbpf_reallocarray(void *ptr, size_t nmemb, size_t size)
 156{
 157        size_t total;
 158
 159#if __has_builtin(__builtin_mul_overflow)
 160        if (unlikely(__builtin_mul_overflow(nmemb, size, &total)))
 161                return NULL;
 162#else
 163        if (size == 0 || nmemb > ULONG_MAX / size)
 164                return NULL;
 165        total = nmemb * size;
 166#endif
 167        return realloc(ptr, total);
 168}
 169
 170struct btf;
 171struct btf_type;
 172
 173struct btf_type *btf_type_by_id(struct btf *btf, __u32 type_id);
 174const char *btf_kind_str(const struct btf_type *t);
 175const struct btf_type *skip_mods_and_typedefs(const struct btf *btf, __u32 id, __u32 *res_id);
 176
 177static inline enum btf_func_linkage btf_func_linkage(const struct btf_type *t)
 178{
 179        return (enum btf_func_linkage)(int)btf_vlen(t);
 180}
 181
 182static inline __u32 btf_type_info(int kind, int vlen, int kflag)
 183{
 184        return (kflag << 31) | (kind << 24) | vlen;
 185}
 186
 187enum map_def_parts {
 188        MAP_DEF_MAP_TYPE        = 0x001,
 189        MAP_DEF_KEY_TYPE        = 0x002,
 190        MAP_DEF_KEY_SIZE        = 0x004,
 191        MAP_DEF_VALUE_TYPE      = 0x008,
 192        MAP_DEF_VALUE_SIZE      = 0x010,
 193        MAP_DEF_MAX_ENTRIES     = 0x020,
 194        MAP_DEF_MAP_FLAGS       = 0x040,
 195        MAP_DEF_NUMA_NODE       = 0x080,
 196        MAP_DEF_PINNING         = 0x100,
 197        MAP_DEF_INNER_MAP       = 0x200,
 198        MAP_DEF_MAP_EXTRA       = 0x400,
 199
 200        MAP_DEF_ALL             = 0x7ff, /* combination of all above */
 201};
 202
 203struct btf_map_def {
 204        enum map_def_parts parts;
 205        __u32 map_type;
 206        __u32 key_type_id;
 207        __u32 key_size;
 208        __u32 value_type_id;
 209        __u32 value_size;
 210        __u32 max_entries;
 211        __u32 map_flags;
 212        __u32 numa_node;
 213        __u32 pinning;
 214        __u64 map_extra;
 215};
 216
 217int parse_btf_map_def(const char *map_name, struct btf *btf,
 218                      const struct btf_type *def_t, bool strict,
 219                      struct btf_map_def *map_def, struct btf_map_def *inner_def);
 220
 221void *libbpf_add_mem(void **data, size_t *cap_cnt, size_t elem_sz,
 222                     size_t cur_cnt, size_t max_cnt, size_t add_cnt);
 223int libbpf_ensure_mem(void **data, size_t *cap_cnt, size_t elem_sz, size_t need_cnt);
 224
 225static inline bool libbpf_is_mem_zeroed(const char *p, ssize_t len)
 226{
 227        while (len > 0) {
 228                if (*p)
 229                        return false;
 230                p++;
 231                len--;
 232        }
 233        return true;
 234}
 235
 236static inline bool libbpf_validate_opts(const char *opts,
 237                                        size_t opts_sz, size_t user_sz,
 238                                        const char *type_name)
 239{
 240        if (user_sz < sizeof(size_t)) {
 241                pr_warn("%s size (%zu) is too small\n", type_name, user_sz);
 242                return false;
 243        }
 244        if (!libbpf_is_mem_zeroed(opts + opts_sz, (ssize_t)user_sz - opts_sz)) {
 245                pr_warn("%s has non-zero extra bytes\n", type_name);
 246                return false;
 247        }
 248        return true;
 249}
 250
 251#define OPTS_VALID(opts, type)                                                \
 252        (!(opts) || libbpf_validate_opts((const char *)opts,                  \
 253                                         offsetofend(struct type,             \
 254                                                     type##__last_field),     \
 255                                         (opts)->sz, #type))
 256#define OPTS_HAS(opts, field) \
 257        ((opts) && opts->sz >= offsetofend(typeof(*(opts)), field))
 258#define OPTS_GET(opts, field, fallback_value) \
 259        (OPTS_HAS(opts, field) ? (opts)->field : fallback_value)
 260#define OPTS_SET(opts, field, value)            \
 261        do {                                    \
 262                if (OPTS_HAS(opts, field))      \
 263                        (opts)->field = value;  \
 264        } while (0)
 265
 266#define OPTS_ZEROED(opts, last_nonzero_field)                                 \
 267({                                                                            \
 268        ssize_t __off = offsetofend(typeof(*(opts)), last_nonzero_field);     \
 269        !(opts) || libbpf_is_mem_zeroed((const void *)opts + __off,           \
 270                                        (opts)->sz - __off);                  \
 271})
 272
 273
 274int parse_cpu_mask_str(const char *s, bool **mask, int *mask_sz);
 275int parse_cpu_mask_file(const char *fcpu, bool **mask, int *mask_sz);
 276int libbpf__load_raw_btf(const char *raw_types, size_t types_len,
 277                         const char *str_sec, size_t str_len);
 278
 279struct bpf_prog_load_params {
 280        enum bpf_prog_type prog_type;
 281        enum bpf_attach_type expected_attach_type;
 282        const char *name;
 283        const struct bpf_insn *insns;
 284        size_t insn_cnt;
 285        const char *license;
 286        __u32 kern_version;
 287        __u32 attach_prog_fd;
 288        __u32 attach_btf_obj_fd;
 289        __u32 attach_btf_id;
 290        __u32 prog_ifindex;
 291        __u32 prog_btf_fd;
 292        __u32 prog_flags;
 293
 294        __u32 func_info_rec_size;
 295        const void *func_info;
 296        __u32 func_info_cnt;
 297
 298        __u32 line_info_rec_size;
 299        const void *line_info;
 300        __u32 line_info_cnt;
 301
 302        __u32 log_level;
 303        char *log_buf;
 304        size_t log_buf_sz;
 305        int *fd_array;
 306};
 307
 308int libbpf__bpf_prog_load(const struct bpf_prog_load_params *load_attr);
 309
 310struct bpf_create_map_params {
 311        const char *name;
 312        enum bpf_map_type map_type;
 313        __u32 map_flags;
 314        __u32 key_size;
 315        __u32 value_size;
 316        __u32 max_entries;
 317        __u32 numa_node;
 318        __u32 btf_fd;
 319        __u32 btf_key_type_id;
 320        __u32 btf_value_type_id;
 321        __u32 map_ifindex;
 322        union {
 323                __u32 inner_map_fd;
 324                __u32 btf_vmlinux_value_type_id;
 325        };
 326        __u64 map_extra;
 327};
 328
 329int libbpf__bpf_create_map_xattr(const struct bpf_create_map_params *create_attr);
 330
 331struct btf *btf_get_from_fd(int btf_fd, struct btf *base_btf);
 332void btf_get_kernel_prefix_kind(enum bpf_attach_type attach_type,
 333                                const char **prefix, int *kind);
 334
 335struct btf_ext_info {
 336        /*
 337         * info points to the individual info section (e.g. func_info and
 338         * line_info) from the .BTF.ext. It does not include the __u32 rec_size.
 339         */
 340        void *info;
 341        __u32 rec_size;
 342        __u32 len;
 343};
 344
 345#define for_each_btf_ext_sec(seg, sec)                                  \
 346        for (sec = (seg)->info;                                         \
 347             (void *)sec < (seg)->info + (seg)->len;                    \
 348             sec = (void *)sec + sizeof(struct btf_ext_info_sec) +      \
 349                   (seg)->rec_size * sec->num_info)
 350
 351#define for_each_btf_ext_rec(seg, sec, i, rec)                          \
 352        for (i = 0, rec = (void *)&(sec)->data;                         \
 353             i < (sec)->num_info;                                       \
 354             i++, rec = (void *)rec + (seg)->rec_size)
 355
 356/*
 357 * The .BTF.ext ELF section layout defined as
 358 *   struct btf_ext_header
 359 *   func_info subsection
 360 *
 361 * The func_info subsection layout:
 362 *   record size for struct bpf_func_info in the func_info subsection
 363 *   struct btf_sec_func_info for section #1
 364 *   a list of bpf_func_info records for section #1
 365 *     where struct bpf_func_info mimics one in include/uapi/linux/bpf.h
 366 *     but may not be identical
 367 *   struct btf_sec_func_info for section #2
 368 *   a list of bpf_func_info records for section #2
 369 *   ......
 370 *
 371 * Note that the bpf_func_info record size in .BTF.ext may not
 372 * be the same as the one defined in include/uapi/linux/bpf.h.
 373 * The loader should ensure that record_size meets minimum
 374 * requirement and pass the record as is to the kernel. The
 375 * kernel will handle the func_info properly based on its contents.
 376 */
 377struct btf_ext_header {
 378        __u16   magic;
 379        __u8    version;
 380        __u8    flags;
 381        __u32   hdr_len;
 382
 383        /* All offsets are in bytes relative to the end of this header */
 384        __u32   func_info_off;
 385        __u32   func_info_len;
 386        __u32   line_info_off;
 387        __u32   line_info_len;
 388
 389        /* optional part of .BTF.ext header */
 390        __u32   core_relo_off;
 391        __u32   core_relo_len;
 392};
 393
 394struct btf_ext {
 395        union {
 396                struct btf_ext_header *hdr;
 397                void *data;
 398        };
 399        struct btf_ext_info func_info;
 400        struct btf_ext_info line_info;
 401        struct btf_ext_info core_relo_info;
 402        __u32 data_size;
 403};
 404
 405struct btf_ext_info_sec {
 406        __u32   sec_name_off;
 407        __u32   num_info;
 408        /* Followed by num_info * record_size number of bytes */
 409        __u8    data[];
 410};
 411
 412/* The minimum bpf_func_info checked by the loader */
 413struct bpf_func_info_min {
 414        __u32   insn_off;
 415        __u32   type_id;
 416};
 417
 418/* The minimum bpf_line_info checked by the loader */
 419struct bpf_line_info_min {
 420        __u32   insn_off;
 421        __u32   file_name_off;
 422        __u32   line_off;
 423        __u32   line_col;
 424};
 425
 426
 427typedef int (*type_id_visit_fn)(__u32 *type_id, void *ctx);
 428typedef int (*str_off_visit_fn)(__u32 *str_off, void *ctx);
 429int btf_type_visit_type_ids(struct btf_type *t, type_id_visit_fn visit, void *ctx);
 430int btf_type_visit_str_offs(struct btf_type *t, str_off_visit_fn visit, void *ctx);
 431int btf_ext_visit_type_ids(struct btf_ext *btf_ext, type_id_visit_fn visit, void *ctx);
 432int btf_ext_visit_str_offs(struct btf_ext *btf_ext, str_off_visit_fn visit, void *ctx);
 433__s32 btf__find_by_name_kind_own(const struct btf *btf, const char *type_name,
 434                                 __u32 kind);
 435
 436extern enum libbpf_strict_mode libbpf_mode;
 437
 438/* handle direct returned errors */
 439static inline int libbpf_err(int ret)
 440{
 441        if (ret < 0)
 442                errno = -ret;
 443        return ret;
 444}
 445
 446/* handle errno-based (e.g., syscall or libc) errors according to libbpf's
 447 * strict mode settings
 448 */
 449static inline int libbpf_err_errno(int ret)
 450{
 451        if (libbpf_mode & LIBBPF_STRICT_DIRECT_ERRS)
 452                /* errno is already assumed to be set on error */
 453                return ret < 0 ? -errno : ret;
 454
 455        /* legacy: on error return -1 directly and don't touch errno */
 456        return ret;
 457}
 458
 459/* handle error for pointer-returning APIs, err is assumed to be < 0 always */
 460static inline void *libbpf_err_ptr(int err)
 461{
 462        /* set errno on error, this doesn't break anything */
 463        errno = -err;
 464
 465        if (libbpf_mode & LIBBPF_STRICT_CLEAN_PTRS)
 466                return NULL;
 467
 468        /* legacy: encode err as ptr */
 469        return ERR_PTR(err);
 470}
 471
 472/* handle pointer-returning APIs' error handling */
 473static inline void *libbpf_ptr(void *ret)
 474{
 475        /* set errno on error, this doesn't break anything */
 476        if (IS_ERR(ret))
 477                errno = -PTR_ERR(ret);
 478
 479        if (libbpf_mode & LIBBPF_STRICT_CLEAN_PTRS)
 480                return IS_ERR(ret) ? NULL : ret;
 481
 482        /* legacy: pass-through original pointer */
 483        return ret;
 484}
 485
 486static inline bool str_is_empty(const char *s)
 487{
 488        return !s || !s[0];
 489}
 490
 491static inline bool is_ldimm64_insn(struct bpf_insn *insn)
 492{
 493        return insn->code == (BPF_LD | BPF_IMM | BPF_DW);
 494}
 495
 496/* if fd is stdin, stdout, or stderr, dup to a fd greater than 2
 497 * Takes ownership of the fd passed in, and closes it if calling
 498 * fcntl(fd, F_DUPFD_CLOEXEC, 3).
 499 */
 500static inline int ensure_good_fd(int fd)
 501{
 502        int old_fd = fd, saved_errno;
 503
 504        if (fd < 0)
 505                return fd;
 506        if (fd < 3) {
 507                fd = fcntl(fd, F_DUPFD_CLOEXEC, 3);
 508                saved_errno = errno;
 509                close(old_fd);
 510                if (fd < 0) {
 511                        pr_warn("failed to dup FD %d to FD > 2: %d\n", old_fd, -saved_errno);
 512                        errno = saved_errno;
 513                }
 514        }
 515        return fd;
 516}
 517
 518#endif /* __LIBBPF_LIBBPF_INTERNAL_H */
 519