Linux kernel mirror (for testing)
git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel
os
linux
fork
Configure Feed
Select the types of activity you want to include in your feed.
1/* SPDX-License-Identifier: GPL-2.0 */
2/*
3 * kabi_ex.h
4 *
5 * Copyright (C) 2024 Google LLC
6 *
7 * Examples for kABI stability features with --stable.
8 */
9
10/*
11 * The comments below each example contain the expected gendwarfksyms
12 * output, which can be verified using LLVM's FileCheck tool:
13 *
14 * https://llvm.org/docs/CommandGuide/FileCheck.html
15 *
16 * Usage:
17 *
18 * $ gcc -g -c examples/kabi_ex.c -o examples/kabi_ex.o
19 *
20 * $ nm examples/kabi_ex.o | awk '{ print $NF }' | \
21 * ./gendwarfksyms --stable --dump-dies \
22 * examples/kabi_ex.o 2>&1 >/dev/null | \
23 * FileCheck examples/kabi_ex.h --check-prefix=STABLE
24
25 * $ nm examples/kabi_ex.o | awk '{ print $NF }' | \
26 * ./gendwarfksyms --stable --dump-versions \
27 * examples/kabi_ex.o 2>&1 >/dev/null | \
28 * sort | \
29 * FileCheck examples/kabi_ex.h --check-prefix=VERSIONS
30 */
31
32#ifndef __KABI_EX_H__
33#define __KABI_EX_H__
34
35#include "kabi.h"
36
37/*
38 * Example: kABI rules
39 */
40
41struct s {
42 int a;
43};
44
45KABI_DECLONLY(s);
46
47/*
48 * STABLE: variable structure_type s {
49 * STABLE-NEXT: }
50 */
51
52enum e {
53 A,
54 B,
55 C,
56 D,
57};
58
59KABI_ENUMERATOR_IGNORE(e, B);
60KABI_ENUMERATOR_IGNORE(e, C);
61KABI_ENUMERATOR_VALUE(e, D, 123456789);
62
63/*
64 * STABLE: variable enumeration_type e {
65 * STABLE-NEXT: enumerator A = 0 ,
66 * STABLE-NEXT: enumerator D = 123456789
67 * STABLE-NEXT: } byte_size(4)
68*/
69
70/*
71 * Example: Reserved fields
72 */
73struct ex0a {
74 int a;
75 KABI_RESERVE(0);
76 KABI_RESERVE(1);
77};
78
79/*
80 * STABLE: variable structure_type ex0a {
81 * STABLE-NEXT: member base_type int byte_size(4) encoding(5) a data_member_location(0) ,
82 * STABLE-NEXT: member base_type [[ULONG:long unsigned int|unsigned long]] byte_size(8) encoding(7) data_member_location(8) ,
83 * STABLE-NEXT: member base_type [[ULONG]] byte_size(8) encoding(7) data_member_location(16)
84 * STABLE-NEXT: } byte_size(24)
85 */
86
87struct ex0b {
88 int a;
89 KABI_RESERVE(0);
90 KABI_USE2(1, int b, int c);
91};
92
93/*
94 * STABLE: variable structure_type ex0b {
95 * STABLE-NEXT: member base_type int byte_size(4) encoding(5) a data_member_location(0) ,
96 * STABLE-NEXT: member base_type [[ULONG]] byte_size(8) encoding(7) data_member_location(8) ,
97 * STABLE-NEXT: member base_type [[ULONG]] byte_size(8) encoding(7) data_member_location(16)
98 * STABLE-NEXT: } byte_size(24)
99 */
100
101struct ex0c {
102 int a;
103 KABI_USE(0, void *p);
104 KABI_USE2(1, int b, int c);
105};
106
107/*
108 * STABLE: variable structure_type ex0c {
109 * STABLE-NEXT: member base_type int byte_size(4) encoding(5) a data_member_location(0) ,
110 * STABLE-NEXT: member base_type [[ULONG]] byte_size(8) encoding(7) data_member_location(8) ,
111 * STABLE-NEXT: member base_type [[ULONG]] byte_size(8) encoding(7) data_member_location(16)
112 * STABLE-NEXT: } byte_size(24)
113 */
114
115/*
116 * Example: A reserved array
117 */
118
119struct ex1a {
120 unsigned int a;
121 KABI_RESERVE_ARRAY(0, 64);
122};
123
124/*
125 * STABLE: variable structure_type ex1a {
126 * STABLE-NEXT: member base_type unsigned int byte_size(4) encoding(7) a data_member_location(0) ,
127 * STABLE-NEXT: member array_type[64] {
128 * STABLE-NEXT: base_type unsigned char byte_size(1) encoding(8)
129 * STABLE-NEXT: } data_member_location(8)
130 * STABLE-NEXT: } byte_size(72)
131 */
132
133struct ex1b {
134 unsigned int a;
135 KABI_USE_ARRAY(
136 0, 64, struct {
137 void *p;
138 KABI_RESERVE_ARRAY(1, 56);
139 });
140};
141
142/*
143 * STABLE: variable structure_type ex1b {
144 * STABLE-NEXT: member base_type unsigned int byte_size(4) encoding(7) a data_member_location(0) ,
145 * STABLE-NEXT: member array_type[64] {
146 * STABLE-NEXT: base_type unsigned char byte_size(1) encoding(8)
147 * STABLE-NEXT: } data_member_location(8)
148 * STABLE-NEXT: } byte_size(72)
149 */
150
151struct ex1c {
152 unsigned int a;
153 KABI_USE_ARRAY(0, 64, void *p[8]);
154};
155
156/*
157 * STABLE: variable structure_type ex1c {
158 * STABLE-NEXT: member base_type unsigned int byte_size(4) encoding(7) a data_member_location(0) ,
159 * STABLE-NEXT: member array_type[64] {
160 * STABLE-NEXT: base_type unsigned char byte_size(1) encoding(8)
161 * STABLE-NEXT: } data_member_location(8)
162 * STABLE-NEXT: } byte_size(72)
163 */
164
165/*
166 * Example: An ignored field added to an alignment hole
167 */
168
169struct ex2a {
170 int a;
171 unsigned long b;
172 int c;
173 unsigned long d;
174};
175
176/*
177 * STABLE: variable structure_type ex2a {
178 * STABLE-NEXT: member base_type int byte_size(4) encoding(5) a data_member_location(0) ,
179 * STABLE-NEXT: member base_type [[ULONG]] byte_size(8) encoding(7) b data_member_location(8)
180 * STABLE-NEXT: member base_type int byte_size(4) encoding(5) c data_member_location(16) ,
181 * STABLE-NEXT: member base_type [[ULONG]] byte_size(8) encoding(7) d data_member_location(24)
182 * STABLE-NEXT: } byte_size(32)
183 */
184
185struct ex2b {
186 int a;
187 KABI_IGNORE(0, unsigned int n);
188 unsigned long b;
189 int c;
190 unsigned long d;
191};
192
193_Static_assert(sizeof(struct ex2a) == sizeof(struct ex2b), "ex2a size doesn't match ex2b");
194
195/*
196 * STABLE: variable structure_type ex2b {
197 * STABLE-NEXT: member base_type int byte_size(4) encoding(5) a data_member_location(0) ,
198 * STABLE-NEXT: member base_type [[ULONG]] byte_size(8) encoding(7) b data_member_location(8)
199 * STABLE-NEXT: member base_type int byte_size(4) encoding(5) c data_member_location(16) ,
200 * STABLE-NEXT: member base_type [[ULONG]] byte_size(8) encoding(7) d data_member_location(24)
201 * STABLE-NEXT: } byte_size(32)
202 */
203
204struct ex2c {
205 int a;
206 KABI_IGNORE(0, unsigned int n);
207 unsigned long b;
208 int c;
209 KABI_IGNORE(1, unsigned int m);
210 unsigned long d;
211};
212
213_Static_assert(sizeof(struct ex2a) == sizeof(struct ex2c), "ex2a size doesn't match ex2c");
214
215/*
216 * STABLE: variable structure_type ex2c {
217 * STABLE-NEXT: member base_type int byte_size(4) encoding(5) a data_member_location(0) ,
218 * STABLE-NEXT: member base_type [[ULONG]] byte_size(8) encoding(7) b data_member_location(8)
219 * STABLE-NEXT: member base_type int byte_size(4) encoding(5) c data_member_location(16) ,
220 * STABLE-NEXT: member base_type [[ULONG]] byte_size(8) encoding(7) d data_member_location(24)
221 * STABLE-NEXT: } byte_size(32)
222 */
223
224
225/*
226 * Example: A replaced field
227 */
228
229struct ex3a {
230 unsigned long a;
231 unsigned long unused;
232};
233
234/*
235 * STABLE: variable structure_type ex3a {
236 * STABLE-NEXT: member base_type [[ULONG]] byte_size(8) encoding(7) a data_member_location(0)
237 * STABLE-NEXT: member base_type [[ULONG]] byte_size(8) encoding(7) unused data_member_location(8)
238 * STABLE-NEXT: } byte_size(16)
239 */
240
241struct ex3b {
242 unsigned long a;
243 KABI_REPLACE(unsigned long, unused, unsigned long renamed);
244};
245
246_Static_assert(sizeof(struct ex3a) == sizeof(struct ex3b), "ex3a size doesn't match ex3b");
247
248/*
249 * STABLE: variable structure_type ex3b {
250 * STABLE-NEXT: member base_type [[ULONG]] byte_size(8) encoding(7) a data_member_location(0)
251 * STABLE-NEXT: member base_type [[ULONG]] byte_size(8) encoding(7) unused data_member_location(8)
252 * STABLE-NEXT: } byte_size(16)
253 */
254
255struct ex3c {
256 unsigned long a;
257 KABI_REPLACE(unsigned long, unused, long replaced);
258};
259
260_Static_assert(sizeof(struct ex3a) == sizeof(struct ex3c), "ex3a size doesn't match ex3c");
261
262/*
263 * STABLE: variable structure_type ex3c {
264 * STABLE-NEXT: member base_type [[ULONG]] byte_size(8) encoding(7) a data_member_location(0)
265 * STABLE-NEXT: member base_type [[ULONG]] byte_size(8) encoding(7) unused data_member_location(8)
266 * STABLE-NEXT: } byte_size(16)
267 */
268
269/*
270 * Example: An ignored field added to an end of a partially opaque struct,
271 * while keeping the byte_size attribute unchanged.
272 */
273
274struct ex4a {
275 unsigned long a;
276 KABI_IGNORE(0, unsigned long b);
277};
278
279/*
280 * This may be safe if the structure allocation is managed by the core kernel
281 * and the layout remains unchanged except for appended new members.
282 */
283KABI_BYTE_SIZE(ex4a, 8);
284
285/*
286 * STABLE: variable structure_type ex4a {
287 * STABLE-NEXT: member base_type [[ULONG]] byte_size(8) encoding(7) a data_member_location(0)
288 * STABLE-NEXT: } byte_size(8)
289 */
290
291/*
292 * Example: A type string override.
293 */
294
295struct ex5a {
296 unsigned long a;
297};
298
299/*
300 * This may be safe if the structure is fully opaque to modules, even though
301 * its definition has inadvertently become part of the ABI.
302 */
303KABI_TYPE_STRING(
304 "s#ex5a",
305 "structure_type ex5a { member pointer_type { s#ex4a } byte_size(8) p data_member_location(0) } byte_size(8)");
306
307/*
308 * Make sure the fully expanded type string includes ex4a.
309 *
310 * VERSIONS: ex5a variable structure_type ex5a {
311 * VERSIONS-SAME: member pointer_type {
312 * VERSIONS-SAME: structure_type ex4a {
313 * VERSIONS-SAME: member base_type [[ULONG:long unsigned int|unsigned long]] byte_size(8) encoding(7) a data_member_location(0)
314 * VERSIONS-SAME: } byte_size(8)
315 * VERSIONS-SAME: } byte_size(8) p data_member_location(0)
316 * VERSIONS-SAME: } byte_size(8)
317 */
318
319/*
320 * Example: A type string definition for a non-existent type.
321 */
322
323struct ex5b {
324 unsigned long a;
325};
326
327/* Replace the type string for struct ex5b */
328KABI_TYPE_STRING(
329 "s#ex5b",
330 "structure_type ex5b { member pointer_type { s#ex5c } byte_size(8) p data_member_location(0) } byte_size(8)");
331
332/* Define a type string for a non-existent struct ex5c */
333KABI_TYPE_STRING(
334 "s#ex5c",
335 "structure_type ex5c { member base_type int byte_size(4) encoding(5) n data_member_location(0) } byte_size(8)");
336
337/*
338 * Make sure the fully expanded type string includes the definition for ex5c.
339 *
340 * VERSIONS: ex5b variable structure_type ex5b {
341 * VERSIONS-SAME: member pointer_type {
342 * VERSIONS-SAME: structure_type ex5c {
343 * VERSIONS-SAME: member base_type int byte_size(4) encoding(5) n data_member_location(0)
344 * VERSIONS-SAME: } byte_size(8)
345 * VERSIONS-SAME: } byte_size(8) p data_member_location(0)
346 * VERSIONS-SAME: } byte_size(8)
347 */
348
349/*
350 * Example: A type string override for a symbol.
351 */
352
353KABI_TYPE_STRING("ex6a", "variable s#ex5c");
354
355/*
356 * VERSIONS: ex6a variable structure_type ex5c {
357 * VERSIONS-SAME: member base_type int byte_size(4) encoding(5) n data_member_location(0)
358 * VERSIONS-SAME: } byte_size(8)
359 */
360#endif /* __KABI_EX_H__ */