xref: /linux/scripts/gendwarfksyms/examples/kabi.h (revision ba6ec09911b805778a2fed6d626bfe77b011a717)
1936cf61cSSami Tolvanen /* SPDX-License-Identifier: GPL-2.0 */
2936cf61cSSami Tolvanen /*
3936cf61cSSami Tolvanen  * Copyright (C) 2024 Google LLC
4936cf61cSSami Tolvanen  *
5936cf61cSSami Tolvanen  * Example macros for maintaining kABI stability.
6936cf61cSSami Tolvanen  *
7936cf61cSSami Tolvanen  * This file is based on android_kabi.h, which has the following notice:
8936cf61cSSami Tolvanen  *
9936cf61cSSami Tolvanen  * Heavily influenced by rh_kabi.h which came from the RHEL/CENTOS kernel
10936cf61cSSami Tolvanen  * and was:
11936cf61cSSami Tolvanen  *	Copyright (c) 2014 Don Zickus
12936cf61cSSami Tolvanen  *	Copyright (c) 2015-2018 Jiri Benc
13936cf61cSSami Tolvanen  *	Copyright (c) 2015 Sabrina Dubroca, Hannes Frederic Sowa
14936cf61cSSami Tolvanen  *	Copyright (c) 2016-2018 Prarit Bhargava
15936cf61cSSami Tolvanen  *	Copyright (c) 2017 Paolo Abeni, Larry Woodman
16936cf61cSSami Tolvanen  */
17936cf61cSSami Tolvanen 
18936cf61cSSami Tolvanen #ifndef __KABI_H__
19936cf61cSSami Tolvanen #define __KABI_H__
20936cf61cSSami Tolvanen 
21936cf61cSSami Tolvanen /* Kernel macros for userspace testing. */
22936cf61cSSami Tolvanen #ifndef __aligned
23936cf61cSSami Tolvanen #define __aligned(x) __attribute__((__aligned__(x)))
24936cf61cSSami Tolvanen #endif
25936cf61cSSami Tolvanen #ifndef __used
26936cf61cSSami Tolvanen #define __used __attribute__((__used__))
27936cf61cSSami Tolvanen #endif
28936cf61cSSami Tolvanen #ifndef __section
29936cf61cSSami Tolvanen #define __section(section) __attribute__((__section__(section)))
30936cf61cSSami Tolvanen #endif
31936cf61cSSami Tolvanen #ifndef __PASTE
32936cf61cSSami Tolvanen #define ___PASTE(a, b) a##b
33936cf61cSSami Tolvanen #define __PASTE(a, b) ___PASTE(a, b)
34936cf61cSSami Tolvanen #endif
35936cf61cSSami Tolvanen #ifndef __stringify
36936cf61cSSami Tolvanen #define __stringify_1(x...) #x
37936cf61cSSami Tolvanen #define __stringify(x...) __stringify_1(x)
38936cf61cSSami Tolvanen #endif
39936cf61cSSami Tolvanen 
40936cf61cSSami Tolvanen #define __KABI_RULE(hint, target, value)                             \
41936cf61cSSami Tolvanen 	static const char __PASTE(__gendwarfksyms_rule_,             \
42936cf61cSSami Tolvanen 				  __COUNTER__)[] __used __aligned(1) \
43936cf61cSSami Tolvanen 		__section(".discard.gendwarfksyms.kabi_rules") =     \
44936cf61cSSami Tolvanen 			"1\0" #hint "\0" #target "\0" #value
45936cf61cSSami Tolvanen 
46*a9369418SSami Tolvanen #define __KABI_NORMAL_SIZE_ALIGN(_orig, _new)                                             \
47*a9369418SSami Tolvanen 	union {                                                                           \
48*a9369418SSami Tolvanen 		_Static_assert(                                                           \
49*a9369418SSami Tolvanen 			sizeof(struct { _new; }) <= sizeof(struct { _orig; }),            \
50*a9369418SSami Tolvanen 			__FILE__ ":" __stringify(__LINE__) ": " __stringify(              \
51*a9369418SSami Tolvanen 				_new) " is larger than " __stringify(_orig));             \
52*a9369418SSami Tolvanen 		_Static_assert(                                                           \
53*a9369418SSami Tolvanen 			__alignof__(struct { _new; }) <=                                  \
54*a9369418SSami Tolvanen 				__alignof__(struct { _orig; }),                           \
55*a9369418SSami Tolvanen 			__FILE__ ":" __stringify(__LINE__) ": " __stringify(              \
56*a9369418SSami Tolvanen 				_orig) " is not aligned the same as " __stringify(_new)); \
57*a9369418SSami Tolvanen 	}
58*a9369418SSami Tolvanen 
59*a9369418SSami Tolvanen #define __KABI_REPLACE(_orig, _new)                    \
60*a9369418SSami Tolvanen 	union {                                        \
61*a9369418SSami Tolvanen 		_new;                                  \
62*a9369418SSami Tolvanen 		struct {                               \
63*a9369418SSami Tolvanen 			_orig;                         \
64*a9369418SSami Tolvanen 		};                                     \
65*a9369418SSami Tolvanen 		__KABI_NORMAL_SIZE_ALIGN(_orig, _new); \
66*a9369418SSami Tolvanen 	}
67*a9369418SSami Tolvanen 
68936cf61cSSami Tolvanen /*
69936cf61cSSami Tolvanen  * KABI_DECLONLY(fqn)
70936cf61cSSami Tolvanen  *   Treat the struct/union/enum fqn as a declaration, i.e. even if
71936cf61cSSami Tolvanen  *   a definition is available, don't expand the contents.
72936cf61cSSami Tolvanen  */
73936cf61cSSami Tolvanen #define KABI_DECLONLY(fqn) __KABI_RULE(declonly, fqn, )
74936cf61cSSami Tolvanen 
75936cf61cSSami Tolvanen /*
76936cf61cSSami Tolvanen  * KABI_ENUMERATOR_IGNORE(fqn, field)
77936cf61cSSami Tolvanen  *   When expanding enum fqn, skip the provided field. This makes it
78936cf61cSSami Tolvanen  *   possible to hide added enum fields from versioning.
79936cf61cSSami Tolvanen  */
80936cf61cSSami Tolvanen #define KABI_ENUMERATOR_IGNORE(fqn, field) \
81936cf61cSSami Tolvanen 	__KABI_RULE(enumerator_ignore, fqn field, )
82936cf61cSSami Tolvanen 
83936cf61cSSami Tolvanen /*
84936cf61cSSami Tolvanen  * KABI_ENUMERATOR_VALUE(fqn, field, value)
85936cf61cSSami Tolvanen  *   When expanding enum fqn, use the provided value for the
86936cf61cSSami Tolvanen  *   specified field. This makes it possible to override enumerator
87936cf61cSSami Tolvanen  *   values when calculating versions.
88936cf61cSSami Tolvanen  */
89936cf61cSSami Tolvanen #define KABI_ENUMERATOR_VALUE(fqn, field, value) \
90936cf61cSSami Tolvanen 	__KABI_RULE(enumerator_value, fqn field, value)
91936cf61cSSami Tolvanen 
92*a9369418SSami Tolvanen /*
93*a9369418SSami Tolvanen  * KABI_RESERVE
94*a9369418SSami Tolvanen  *   Reserve some "padding" in a structure for use by LTS backports.
95*a9369418SSami Tolvanen  *   This is normally placed at the end of a structure.
96*a9369418SSami Tolvanen  *   number: the "number" of the padding variable in the structure.  Start with
97*a9369418SSami Tolvanen  *   1 and go up.
98*a9369418SSami Tolvanen  */
99*a9369418SSami Tolvanen #define KABI_RESERVE(n) unsigned long __kabi_reserved##n
100*a9369418SSami Tolvanen 
101*a9369418SSami Tolvanen /*
102*a9369418SSami Tolvanen  * KABI_RESERVE_ARRAY
103*a9369418SSami Tolvanen  *   Same as _BACKPORT_RESERVE but allocates an array with the specified
104*a9369418SSami Tolvanen  *   size in bytes.
105*a9369418SSami Tolvanen  */
106*a9369418SSami Tolvanen #define KABI_RESERVE_ARRAY(n, s) \
107*a9369418SSami Tolvanen 	unsigned char __aligned(8) __kabi_reserved##n[s]
108*a9369418SSami Tolvanen 
109*a9369418SSami Tolvanen /*
110*a9369418SSami Tolvanen  * KABI_IGNORE
111*a9369418SSami Tolvanen  *   Add a new field that's ignored in versioning.
112*a9369418SSami Tolvanen  */
113*a9369418SSami Tolvanen #define KABI_IGNORE(n, _new)                     \
114*a9369418SSami Tolvanen 	union {                                  \
115*a9369418SSami Tolvanen 		_new;                            \
116*a9369418SSami Tolvanen 		unsigned char __kabi_ignored##n; \
117*a9369418SSami Tolvanen 	}
118*a9369418SSami Tolvanen 
119*a9369418SSami Tolvanen /*
120*a9369418SSami Tolvanen  * KABI_REPLACE
121*a9369418SSami Tolvanen  *   Replace a field with a compatible new field.
122*a9369418SSami Tolvanen  */
123*a9369418SSami Tolvanen #define KABI_REPLACE(_oldtype, _oldname, _new) \
124*a9369418SSami Tolvanen 	__KABI_REPLACE(_oldtype __kabi_renamed##_oldname, struct { _new; })
125*a9369418SSami Tolvanen 
126*a9369418SSami Tolvanen /*
127*a9369418SSami Tolvanen  * KABI_USE(number, _new)
128*a9369418SSami Tolvanen  *   Use a previous padding entry that was defined with KABI_RESERVE
129*a9369418SSami Tolvanen  *   number: the previous "number" of the padding variable
130*a9369418SSami Tolvanen  *   _new: the variable to use now instead of the padding variable
131*a9369418SSami Tolvanen  */
132*a9369418SSami Tolvanen #define KABI_USE(number, _new) __KABI_REPLACE(KABI_RESERVE(number), _new)
133*a9369418SSami Tolvanen 
134*a9369418SSami Tolvanen /*
135*a9369418SSami Tolvanen  * KABI_USE2(number, _new1, _new2)
136*a9369418SSami Tolvanen  *   Use a previous padding entry that was defined with KABI_RESERVE for
137*a9369418SSami Tolvanen  *   two new variables that fit into 64 bits.  This is good for when you do not
138*a9369418SSami Tolvanen  *   want to "burn" a 64bit padding variable for a smaller variable size if not
139*a9369418SSami Tolvanen  *   needed.
140*a9369418SSami Tolvanen  */
141*a9369418SSami Tolvanen #define KABI_USE2(number, _new1, _new2)        \
142*a9369418SSami Tolvanen 	__KABI_REPLACE(                        \
143*a9369418SSami Tolvanen 		KABI_RESERVE(number), struct { \
144*a9369418SSami Tolvanen 			_new1;                 \
145*a9369418SSami Tolvanen 			_new2;                 \
146*a9369418SSami Tolvanen 		})
147*a9369418SSami Tolvanen /*
148*a9369418SSami Tolvanen  * KABI_USE_ARRAY(number, bytes, _new)
149*a9369418SSami Tolvanen  *   Use a previous padding entry that was defined with KABI_RESERVE_ARRAY
150*a9369418SSami Tolvanen  *   number: the previous "number" of the padding variable
151*a9369418SSami Tolvanen  *   bytes: the size in bytes reserved for the array
152*a9369418SSami Tolvanen  *   _new: the variable to use now instead of the padding variable
153*a9369418SSami Tolvanen  */
154*a9369418SSami Tolvanen #define KABI_USE_ARRAY(number, bytes, _new) \
155*a9369418SSami Tolvanen 	__KABI_REPLACE(KABI_RESERVE_ARRAY(number, bytes), _new)
156*a9369418SSami Tolvanen 
157936cf61cSSami Tolvanen #endif /* __KABI_H__ */
158