Imported Upstream version 2.6.1
[platform/upstream/cryptsetup.git] / lib / libcryptsetup_symver.h
1 /*
2  * Helpers for defining versioned symbols
3  *
4  * Copyright (C) 2021-2023 Red Hat, Inc. All rights reserved.
5  *
6  * This program is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU General Public License
8  * as published by the Free Software Foundation; either version 2
9  * of the License, or (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
19  */
20
21 #ifndef _LIBCRYPTSETUP_SYMVER_H
22 #define _LIBCRYPTSETUP_SYMVER_H
23
24 /*
25  * Note on usage:
26  *
27  * Do not use CRYPT_SYMBOL_EXPORT_NEW and CRYPT_SYMBOL_EXPORT_OLD on public
28  * symbols being exported only once. Linker will handle it automatically as
29  * always.
30  *
31  * It's supposed to be used only with symbols that are exported in at least
32  * two versions simultaneously as follows:
33  *
34  * - the latest version is marked with _NEW variant and all other compatible
35  *   symbols should be marked with _OLD variant
36  *
37  * Examples:
38  *
39  * - int crypt_func_X(unsigned *x, long y) gets introduced in CRYPTSETUP_2.4.
40  *
41  *   No need to use any macro referenced here, just add proper version
42  *   mapping in libcryptsetup.sym file.
43  *
44  *   In later version CRYPTSETUP_2.5 symbol crypt_func_X has to fixed
45  *   in incompatible way by adding new function parameter. The new version
46  *   has to be added in mapping file libcryptsetup.sym as well.
47  *
48  *   The definition of compatible function gets prefixed with following macro:
49  *
50  *   CRYPT_SYMBOL_EXPORT_OLD(int, crypt_func_X, 2, 4,
51  *                           unsigned *x, long y)
52  *   {
53  *      function body
54  *   }
55  *
56  *   Whereas new version introduced in CRYPTSETUP_2.5 is defined as follows:
57  *
58  *   CRYPT_SYMBOL_EXPORT_NEW(int, crypt_func_X, 2, 5,
59  *                           unsigned *x, long y, void *new_parameter)
60  *   {
61  *      function body
62  *   }
63  *
64  *   If in later version CRYPTSETUP_2.6 yet another version of crypt_func_X gets
65  *   introduced it will be prefixed with CRYPT_SYMBOL_EXPORT_NEW(int, crypt_func_X, 2, 6...)
66  *   macro and all previous versions CRYPTSETUP_2.4 and CRYPTSETUP_2.5 will be
67  *   under CRYPT_SYMBOL_EXPORT_OLD(int, crypt_func_X, ...) macro
68  */
69
70 #if HAVE_ATTRIBUTE_SYMVER
71 #  define _CRYPT_SYMVER(_local_sym, _public_sym, _ver_str, _maj, _min)     \
72      __attribute__((__symver__(#_public_sym _ver_str #_maj "." #_min)))
73 #endif
74
75 #if !defined(_CRYPT_SYMVER) && (defined(__GNUC__) || defined(__clang__))
76 #  define _CRYPT_SYMVER(_local_sym, _public_sym, _ver_str, _maj, _min)         \
77      __asm__(".symver " #_local_sym "," #_public_sym _ver_str #_maj "." #_min);
78 #endif
79
80 #define _CRYPT_FUNC(_public_sym, _prefix_str, _maj, _min, _ret, ...)                                    \
81   _ret __##_public_sym##_v##_maj##_##_min(__VA_ARGS__);                                                 \
82   _CRYPT_SYMVER(__##_public_sym##_v##_maj##_##_min, _public_sym, _prefix_str "CRYPTSETUP_", _maj, _min) \
83   _ret __##_public_sym##_v##_maj##_##_min(__VA_ARGS__)
84
85 #ifdef _CRYPT_SYMVER
86
87 #  define CRYPT_SYMBOL_EXPORT_OLD(_ret, _public_sym, _maj, _min, ...)  \
88      _CRYPT_FUNC(_public_sym, "@", _maj, _min, _ret, __VA_ARGS__)
89 #  define CRYPT_SYMBOL_EXPORT_NEW(_ret, _public_sym, _maj, _min, ...)  \
90      _CRYPT_FUNC(_public_sym, "@@", _maj, _min, _ret, __VA_ARGS__)
91
92 #else /* no support for symbol versioning at all */
93
94 #  define CRYPT_SYMBOL_EXPORT_OLD(_ret, _public_sym, _maj, _min, ...)  \
95      static inline __attribute__((unused))                             \
96        _ret __##_public_sym##_v##_maj##_##_min(__VA_ARGS__)
97
98 #  define CRYPT_SYMBOL_EXPORT_NEW(_ret, _public_sym, _maj, _min, ...) \
99      _ret _public_sym(__VA_ARGS__)
100
101 #endif
102
103 #endif /* _LIBCRYPTSETUP_SYMVER_H */