File Index
Files and directories
Sign in
FILE

kabi_ex.h

File preview with syntax highlighting.

linux-6.19.14/scripts/gendwarfksyms/examples/kabi_ex.h C
  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__ */
~/ Read-only file preview.