/* SPDX-License-Identifier: (LGPL-2.1 OR BSD-2-Clause) */12/*3* Common user-facing libbpf helpers.4*5* Copyright (c) 2019 Facebook6*/78#ifndef __LIBBPF_LIBBPF_COMMON_H9#define __LIBBPF_LIBBPF_COMMON_H1011#include <string.h>12#include "libbpf_version.h"1314#ifndef LIBBPF_API15#define LIBBPF_API __attribute__((visibility("default")))16#endif1718#define LIBBPF_DEPRECATED(msg) __attribute__((deprecated(msg)))1920/* Mark a symbol as deprecated when libbpf version is >= {major}.{minor} */21#define LIBBPF_DEPRECATED_SINCE(major, minor, msg) \22__LIBBPF_MARK_DEPRECATED_ ## major ## _ ## minor \23(LIBBPF_DEPRECATED("libbpf v" # major "." # minor "+: " msg))2425#define __LIBBPF_CURRENT_VERSION_GEQ(major, minor) \26(LIBBPF_MAJOR_VERSION > (major) || \27(LIBBPF_MAJOR_VERSION == (major) && LIBBPF_MINOR_VERSION >= (minor)))2829/* Add checks for other versions below when planning deprecation of API symbols30* with the LIBBPF_DEPRECATED_SINCE macro.31*/32#if __LIBBPF_CURRENT_VERSION_GEQ(1, 0)33#define __LIBBPF_MARK_DEPRECATED_1_0(X) X34#else35#define __LIBBPF_MARK_DEPRECATED_1_0(X)36#endif3738/* This set of internal macros allows to do "function overloading" based on39* number of arguments provided by used in backwards-compatible way during the40* transition to libbpf 1.041* It's ugly but necessary evil that will be cleaned up when we get to 1.0.42* See bpf_prog_load() overload for example.43*/44#define ___libbpf_cat(A, B) A ## B45#define ___libbpf_select(NAME, NUM) ___libbpf_cat(NAME, NUM)46#define ___libbpf_nth(_1, _2, _3, _4, _5, _6, N, ...) N47#define ___libbpf_cnt(...) ___libbpf_nth(__VA_ARGS__, 6, 5, 4, 3, 2, 1)48#define ___libbpf_overload(NAME, ...) ___libbpf_select(NAME, ___libbpf_cnt(__VA_ARGS__))(__VA_ARGS__)4950/* Helper macro to declare and initialize libbpf options struct51*52* This dance with uninitialized declaration, followed by memset to zero,53* followed by assignment using compound literal syntax is done to preserve54* ability to use a nice struct field initialization syntax and **hopefully**55* have all the padding bytes initialized to zero. It's not guaranteed though,56* when copying literal, that compiler won't copy garbage in literal's padding57* bytes, but that's the best way I've found and it seems to work in practice.58*59* Macro declares opts struct of given type and name, zero-initializes,60* including any extra padding, it with memset() and then assigns initial61* values provided by users in struct initializer-syntax as varargs.62*/63#define LIBBPF_OPTS(TYPE, NAME, ...) \64struct TYPE NAME = ({ \65memset(&NAME, 0, sizeof(struct TYPE)); \66(struct TYPE) { \67.sz = sizeof(struct TYPE), \68__VA_ARGS__ \69}; \70})7172/* Helper macro to clear and optionally reinitialize libbpf options struct73*74* Small helper macro to reset all fields and to reinitialize the common75* structure size member. Values provided by users in struct initializer-76* syntax as varargs can be provided as well to reinitialize options struct77* specific members.78*/79#define LIBBPF_OPTS_RESET(NAME, ...) \80do { \81typeof(NAME) ___##NAME = ({ \82memset(&___##NAME, 0, sizeof(NAME)); \83(typeof(NAME)) { \84.sz = sizeof(NAME), \85__VA_ARGS__ \86}; \87}); \88memcpy(&NAME, &___##NAME, sizeof(NAME)); \89} while (0)9091#endif /* __LIBBPF_LIBBPF_COMMON_H */929394