162306a36Sopenharmony_ci/* SPDX-License-Identifier: (LGPL-2.1 OR BSD-2-Clause) */ 262306a36Sopenharmony_ci 362306a36Sopenharmony_ci/* 462306a36Sopenharmony_ci * Common user-facing libbpf helpers. 562306a36Sopenharmony_ci * 662306a36Sopenharmony_ci * Copyright (c) 2019 Facebook 762306a36Sopenharmony_ci */ 862306a36Sopenharmony_ci 962306a36Sopenharmony_ci#ifndef __LIBBPF_LIBBPF_COMMON_H 1062306a36Sopenharmony_ci#define __LIBBPF_LIBBPF_COMMON_H 1162306a36Sopenharmony_ci 1262306a36Sopenharmony_ci#include <string.h> 1362306a36Sopenharmony_ci#include "libbpf_version.h" 1462306a36Sopenharmony_ci 1562306a36Sopenharmony_ci#ifndef LIBBPF_API 1662306a36Sopenharmony_ci#define LIBBPF_API __attribute__((visibility("default"))) 1762306a36Sopenharmony_ci#endif 1862306a36Sopenharmony_ci 1962306a36Sopenharmony_ci#define LIBBPF_DEPRECATED(msg) __attribute__((deprecated(msg))) 2062306a36Sopenharmony_ci 2162306a36Sopenharmony_ci/* Mark a symbol as deprecated when libbpf version is >= {major}.{minor} */ 2262306a36Sopenharmony_ci#define LIBBPF_DEPRECATED_SINCE(major, minor, msg) \ 2362306a36Sopenharmony_ci __LIBBPF_MARK_DEPRECATED_ ## major ## _ ## minor \ 2462306a36Sopenharmony_ci (LIBBPF_DEPRECATED("libbpf v" # major "." # minor "+: " msg)) 2562306a36Sopenharmony_ci 2662306a36Sopenharmony_ci#define __LIBBPF_CURRENT_VERSION_GEQ(major, minor) \ 2762306a36Sopenharmony_ci (LIBBPF_MAJOR_VERSION > (major) || \ 2862306a36Sopenharmony_ci (LIBBPF_MAJOR_VERSION == (major) && LIBBPF_MINOR_VERSION >= (minor))) 2962306a36Sopenharmony_ci 3062306a36Sopenharmony_ci/* Add checks for other versions below when planning deprecation of API symbols 3162306a36Sopenharmony_ci * with the LIBBPF_DEPRECATED_SINCE macro. 3262306a36Sopenharmony_ci */ 3362306a36Sopenharmony_ci#if __LIBBPF_CURRENT_VERSION_GEQ(1, 0) 3462306a36Sopenharmony_ci#define __LIBBPF_MARK_DEPRECATED_1_0(X) X 3562306a36Sopenharmony_ci#else 3662306a36Sopenharmony_ci#define __LIBBPF_MARK_DEPRECATED_1_0(X) 3762306a36Sopenharmony_ci#endif 3862306a36Sopenharmony_ci 3962306a36Sopenharmony_ci/* This set of internal macros allows to do "function overloading" based on 4062306a36Sopenharmony_ci * number of arguments provided by used in backwards-compatible way during the 4162306a36Sopenharmony_ci * transition to libbpf 1.0 4262306a36Sopenharmony_ci * It's ugly but necessary evil that will be cleaned up when we get to 1.0. 4362306a36Sopenharmony_ci * See bpf_prog_load() overload for example. 4462306a36Sopenharmony_ci */ 4562306a36Sopenharmony_ci#define ___libbpf_cat(A, B) A ## B 4662306a36Sopenharmony_ci#define ___libbpf_select(NAME, NUM) ___libbpf_cat(NAME, NUM) 4762306a36Sopenharmony_ci#define ___libbpf_nth(_1, _2, _3, _4, _5, _6, N, ...) N 4862306a36Sopenharmony_ci#define ___libbpf_cnt(...) ___libbpf_nth(__VA_ARGS__, 6, 5, 4, 3, 2, 1) 4962306a36Sopenharmony_ci#define ___libbpf_overload(NAME, ...) ___libbpf_select(NAME, ___libbpf_cnt(__VA_ARGS__))(__VA_ARGS__) 5062306a36Sopenharmony_ci 5162306a36Sopenharmony_ci/* Helper macro to declare and initialize libbpf options struct 5262306a36Sopenharmony_ci * 5362306a36Sopenharmony_ci * This dance with uninitialized declaration, followed by memset to zero, 5462306a36Sopenharmony_ci * followed by assignment using compound literal syntax is done to preserve 5562306a36Sopenharmony_ci * ability to use a nice struct field initialization syntax and **hopefully** 5662306a36Sopenharmony_ci * have all the padding bytes initialized to zero. It's not guaranteed though, 5762306a36Sopenharmony_ci * when copying literal, that compiler won't copy garbage in literal's padding 5862306a36Sopenharmony_ci * bytes, but that's the best way I've found and it seems to work in practice. 5962306a36Sopenharmony_ci * 6062306a36Sopenharmony_ci * Macro declares opts struct of given type and name, zero-initializes, 6162306a36Sopenharmony_ci * including any extra padding, it with memset() and then assigns initial 6262306a36Sopenharmony_ci * values provided by users in struct initializer-syntax as varargs. 6362306a36Sopenharmony_ci */ 6462306a36Sopenharmony_ci#define LIBBPF_OPTS(TYPE, NAME, ...) \ 6562306a36Sopenharmony_ci struct TYPE NAME = ({ \ 6662306a36Sopenharmony_ci memset(&NAME, 0, sizeof(struct TYPE)); \ 6762306a36Sopenharmony_ci (struct TYPE) { \ 6862306a36Sopenharmony_ci .sz = sizeof(struct TYPE), \ 6962306a36Sopenharmony_ci __VA_ARGS__ \ 7062306a36Sopenharmony_ci }; \ 7162306a36Sopenharmony_ci }) 7262306a36Sopenharmony_ci 7362306a36Sopenharmony_ci/* Helper macro to clear and optionally reinitialize libbpf options struct 7462306a36Sopenharmony_ci * 7562306a36Sopenharmony_ci * Small helper macro to reset all fields and to reinitialize the common 7662306a36Sopenharmony_ci * structure size member. Values provided by users in struct initializer- 7762306a36Sopenharmony_ci * syntax as varargs can be provided as well to reinitialize options struct 7862306a36Sopenharmony_ci * specific members. 7962306a36Sopenharmony_ci */ 8062306a36Sopenharmony_ci#define LIBBPF_OPTS_RESET(NAME, ...) \ 8162306a36Sopenharmony_ci do { \ 8262306a36Sopenharmony_ci typeof(NAME) ___##NAME = ({ \ 8362306a36Sopenharmony_ci memset(&___##NAME, 0, sizeof(NAME)); \ 8462306a36Sopenharmony_ci (typeof(NAME)) { \ 8562306a36Sopenharmony_ci .sz = sizeof(NAME), \ 8662306a36Sopenharmony_ci __VA_ARGS__ \ 8762306a36Sopenharmony_ci }; \ 8862306a36Sopenharmony_ci }); \ 8962306a36Sopenharmony_ci memcpy(&NAME, &___##NAME, sizeof(NAME)); \ 9062306a36Sopenharmony_ci } while (0) 9162306a36Sopenharmony_ci 9262306a36Sopenharmony_ci#endif /* __LIBBPF_LIBBPF_COMMON_H */ 93