xref: /linux/scripts/gendwarfksyms/examples/kabi_ex.h (revision ba6ec09911b805778a2fed6d626bfe77b011a717)
1936cf61cSSami Tolvanen /* SPDX-License-Identifier: GPL-2.0 */
2936cf61cSSami Tolvanen /*
3936cf61cSSami Tolvanen  * kabi_ex.h
4936cf61cSSami Tolvanen  *
5936cf61cSSami Tolvanen  * Copyright (C) 2024 Google LLC
6936cf61cSSami Tolvanen  *
7936cf61cSSami Tolvanen  * Examples for kABI stability features with --stable.
8936cf61cSSami Tolvanen  */
9936cf61cSSami Tolvanen 
10936cf61cSSami Tolvanen /*
11936cf61cSSami Tolvanen  * The comments below each example contain the expected gendwarfksyms
12936cf61cSSami Tolvanen  * output, which can be verified using LLVM's FileCheck tool:
13936cf61cSSami Tolvanen  *
14936cf61cSSami Tolvanen  * https://llvm.org/docs/CommandGuide/FileCheck.html
15936cf61cSSami Tolvanen  *
16936cf61cSSami Tolvanen  * Usage:
17936cf61cSSami Tolvanen  *
18936cf61cSSami Tolvanen  * $ gcc -g -c examples/kabi_ex.c -o examples/kabi_ex.o
19936cf61cSSami Tolvanen  *
20936cf61cSSami Tolvanen  * $ nm examples/kabi_ex.o | awk '{ print $NF }' | \
21936cf61cSSami Tolvanen  * 	./gendwarfksyms --stable --dump-dies \
22936cf61cSSami Tolvanen  * 		examples/kabi_ex.o 2>&1 >/dev/null | \
23936cf61cSSami Tolvanen  * 	FileCheck examples/kabi_ex.h --check-prefix=STABLE
24936cf61cSSami Tolvanen  */
25936cf61cSSami Tolvanen 
26936cf61cSSami Tolvanen #ifndef __KABI_EX_H__
27936cf61cSSami Tolvanen #define __KABI_EX_H__
28936cf61cSSami Tolvanen 
29936cf61cSSami Tolvanen #include "kabi.h"
30936cf61cSSami Tolvanen 
31936cf61cSSami Tolvanen /*
32936cf61cSSami Tolvanen  * Example: kABI rules
33936cf61cSSami Tolvanen  */
34936cf61cSSami Tolvanen 
35936cf61cSSami Tolvanen struct s {
36936cf61cSSami Tolvanen 	int a;
37936cf61cSSami Tolvanen };
38936cf61cSSami Tolvanen 
39936cf61cSSami Tolvanen KABI_DECLONLY(s);
40936cf61cSSami Tolvanen 
41936cf61cSSami Tolvanen /*
42936cf61cSSami Tolvanen  * STABLE:      variable structure_type s {
43936cf61cSSami Tolvanen  * STABLE-NEXT: }
44936cf61cSSami Tolvanen  */
45936cf61cSSami Tolvanen 
46936cf61cSSami Tolvanen enum e {
47936cf61cSSami Tolvanen 	A,
48936cf61cSSami Tolvanen 	B,
49936cf61cSSami Tolvanen 	C,
50936cf61cSSami Tolvanen 	D,
51936cf61cSSami Tolvanen };
52936cf61cSSami Tolvanen 
53936cf61cSSami Tolvanen KABI_ENUMERATOR_IGNORE(e, B);
54936cf61cSSami Tolvanen KABI_ENUMERATOR_IGNORE(e, C);
55936cf61cSSami Tolvanen KABI_ENUMERATOR_VALUE(e, D, 123456789);
56936cf61cSSami Tolvanen 
57936cf61cSSami Tolvanen /*
58936cf61cSSami Tolvanen  * STABLE:      variable enumeration_type e {
59936cf61cSSami Tolvanen  * STABLE-NEXT:   enumerator A = 0 ,
60936cf61cSSami Tolvanen  * STABLE-NEXT:   enumerator D = 123456789
61936cf61cSSami Tolvanen  * STABLE-NEXT: } byte_size(4)
62*a9369418SSami Tolvanen */
63*a9369418SSami Tolvanen 
64*a9369418SSami Tolvanen /*
65*a9369418SSami Tolvanen  * Example: Reserved fields
66*a9369418SSami Tolvanen  */
67*a9369418SSami Tolvanen struct ex0a {
68*a9369418SSami Tolvanen 	int a;
69*a9369418SSami Tolvanen 	KABI_RESERVE(0);
70*a9369418SSami Tolvanen 	KABI_RESERVE(1);
71*a9369418SSami Tolvanen };
72*a9369418SSami Tolvanen 
73*a9369418SSami Tolvanen /*
74*a9369418SSami Tolvanen  * STABLE:      variable structure_type ex0a {
75*a9369418SSami Tolvanen  * STABLE-NEXT:   member base_type int byte_size(4) encoding(5) a data_member_location(0) ,
76*a9369418SSami Tolvanen  * STABLE-NEXT:   member base_type [[ULONG:long unsigned int|unsigned long]] byte_size(8) encoding(7) data_member_location(8) ,
77*a9369418SSami Tolvanen  * STABLE-NEXT:   member base_type [[ULONG]] byte_size(8) encoding(7) data_member_location(16)
78*a9369418SSami Tolvanen  * STABLE-NEXT: } byte_size(24)
79*a9369418SSami Tolvanen  */
80*a9369418SSami Tolvanen 
81*a9369418SSami Tolvanen struct ex0b {
82*a9369418SSami Tolvanen 	int a;
83*a9369418SSami Tolvanen 	KABI_RESERVE(0);
84*a9369418SSami Tolvanen 	KABI_USE2(1, int b, int c);
85*a9369418SSami Tolvanen };
86*a9369418SSami Tolvanen 
87*a9369418SSami Tolvanen /*
88*a9369418SSami Tolvanen  * STABLE:      variable structure_type ex0b {
89*a9369418SSami Tolvanen  * STABLE-NEXT:   member base_type int byte_size(4) encoding(5) a data_member_location(0) ,
90*a9369418SSami Tolvanen  * STABLE-NEXT:   member base_type [[ULONG]] byte_size(8) encoding(7) data_member_location(8) ,
91*a9369418SSami Tolvanen  * STABLE-NEXT:   member base_type [[ULONG]] byte_size(8) encoding(7) data_member_location(16)
92*a9369418SSami Tolvanen  * STABLE-NEXT: } byte_size(24)
93*a9369418SSami Tolvanen  */
94*a9369418SSami Tolvanen 
95*a9369418SSami Tolvanen struct ex0c {
96*a9369418SSami Tolvanen 	int a;
97*a9369418SSami Tolvanen 	KABI_USE(0, void *p);
98*a9369418SSami Tolvanen 	KABI_USE2(1, int b, int c);
99*a9369418SSami Tolvanen };
100*a9369418SSami Tolvanen 
101*a9369418SSami Tolvanen /*
102*a9369418SSami Tolvanen  * STABLE:      variable structure_type ex0c {
103*a9369418SSami Tolvanen  * STABLE-NEXT:   member base_type int byte_size(4) encoding(5) a data_member_location(0) ,
104*a9369418SSami Tolvanen  * STABLE-NEXT:   member base_type [[ULONG]] byte_size(8) encoding(7) data_member_location(8) ,
105*a9369418SSami Tolvanen  * STABLE-NEXT:   member base_type [[ULONG]] byte_size(8) encoding(7) data_member_location(16)
106*a9369418SSami Tolvanen  * STABLE-NEXT: } byte_size(24)
107*a9369418SSami Tolvanen  */
108*a9369418SSami Tolvanen 
109*a9369418SSami Tolvanen /*
110*a9369418SSami Tolvanen  * Example: A reserved array
111*a9369418SSami Tolvanen  */
112*a9369418SSami Tolvanen 
113*a9369418SSami Tolvanen struct ex1a {
114*a9369418SSami Tolvanen 	unsigned int a;
115*a9369418SSami Tolvanen 	KABI_RESERVE_ARRAY(0, 64);
116*a9369418SSami Tolvanen };
117*a9369418SSami Tolvanen 
118*a9369418SSami Tolvanen /*
119*a9369418SSami Tolvanen  * STABLE:      variable structure_type ex1a {
120*a9369418SSami Tolvanen  * STABLE-NEXT:   member base_type unsigned int byte_size(4) encoding(7) a data_member_location(0) ,
121*a9369418SSami Tolvanen  * STABLE-NEXT:   member array_type[64] {
122*a9369418SSami Tolvanen  * STABLE-NEXT:     base_type unsigned char byte_size(1) encoding(8)
123*a9369418SSami Tolvanen  * STABLE-NEXT:   } data_member_location(8)
124*a9369418SSami Tolvanen  * STABLE-NEXT: } byte_size(72)
125*a9369418SSami Tolvanen  */
126*a9369418SSami Tolvanen 
127*a9369418SSami Tolvanen struct ex1b {
128*a9369418SSami Tolvanen 	unsigned int a;
129*a9369418SSami Tolvanen 	KABI_USE_ARRAY(
130*a9369418SSami Tolvanen 		0, 64, struct {
131*a9369418SSami Tolvanen 			void *p;
132*a9369418SSami Tolvanen 			KABI_RESERVE_ARRAY(1, 56);
133*a9369418SSami Tolvanen 		});
134*a9369418SSami Tolvanen };
135*a9369418SSami Tolvanen 
136*a9369418SSami Tolvanen /*
137*a9369418SSami Tolvanen  * STABLE:      variable structure_type ex1b {
138*a9369418SSami Tolvanen  * STABLE-NEXT:   member base_type unsigned int byte_size(4) encoding(7) a data_member_location(0) ,
139*a9369418SSami Tolvanen  * STABLE-NEXT:   member array_type[64] {
140*a9369418SSami Tolvanen  * STABLE-NEXT:     base_type unsigned char byte_size(1) encoding(8)
141*a9369418SSami Tolvanen  * STABLE-NEXT:   } data_member_location(8)
142*a9369418SSami Tolvanen  * STABLE-NEXT: } byte_size(72)
143*a9369418SSami Tolvanen  */
144*a9369418SSami Tolvanen 
145*a9369418SSami Tolvanen struct ex1c {
146*a9369418SSami Tolvanen 	unsigned int a;
147*a9369418SSami Tolvanen 	KABI_USE_ARRAY(0, 64, void *p[8]);
148*a9369418SSami Tolvanen };
149*a9369418SSami Tolvanen 
150*a9369418SSami Tolvanen /*
151*a9369418SSami Tolvanen  * STABLE:      variable structure_type ex1c {
152*a9369418SSami Tolvanen  * STABLE-NEXT:   member base_type unsigned int byte_size(4) encoding(7) a data_member_location(0) ,
153*a9369418SSami Tolvanen  * STABLE-NEXT:   member array_type[64] {
154*a9369418SSami Tolvanen  * STABLE-NEXT:     base_type unsigned char byte_size(1) encoding(8)
155*a9369418SSami Tolvanen  * STABLE-NEXT:   } data_member_location(8)
156*a9369418SSami Tolvanen  * STABLE-NEXT: } byte_size(72)
157*a9369418SSami Tolvanen  */
158*a9369418SSami Tolvanen 
159*a9369418SSami Tolvanen /*
160*a9369418SSami Tolvanen  * Example: An ignored field added to an alignment hole
161*a9369418SSami Tolvanen  */
162*a9369418SSami Tolvanen 
163*a9369418SSami Tolvanen struct ex2a {
164*a9369418SSami Tolvanen 	int a;
165*a9369418SSami Tolvanen 	unsigned long b;
166*a9369418SSami Tolvanen 	int c;
167*a9369418SSami Tolvanen 	unsigned long d;
168*a9369418SSami Tolvanen };
169*a9369418SSami Tolvanen 
170*a9369418SSami Tolvanen /*
171*a9369418SSami Tolvanen  * STABLE:      variable structure_type ex2a {
172*a9369418SSami Tolvanen  * STABLE-NEXT:   member base_type int byte_size(4) encoding(5) a data_member_location(0) ,
173*a9369418SSami Tolvanen  * STABLE-NEXT:   member base_type [[ULONG:long unsigned int|unsigned long]] byte_size(8) encoding(7) b data_member_location(8)
174*a9369418SSami Tolvanen  * STABLE-NEXT:   member base_type int byte_size(4) encoding(5) c data_member_location(16) ,
175*a9369418SSami Tolvanen  * STABLE-NEXT:   member base_type [[ULONG]] byte_size(8) encoding(7) d data_member_location(24)
176*a9369418SSami Tolvanen  * STABLE-NEXT: } byte_size(32)
177*a9369418SSami Tolvanen  */
178*a9369418SSami Tolvanen 
179*a9369418SSami Tolvanen struct ex2b {
180*a9369418SSami Tolvanen 	int a;
181*a9369418SSami Tolvanen 	KABI_IGNORE(0, unsigned int n);
182*a9369418SSami Tolvanen 	unsigned long b;
183*a9369418SSami Tolvanen 	int c;
184*a9369418SSami Tolvanen 	unsigned long d;
185*a9369418SSami Tolvanen };
186*a9369418SSami Tolvanen 
187*a9369418SSami Tolvanen _Static_assert(sizeof(struct ex2a) == sizeof(struct ex2b), "ex2a size doesn't match ex2b");
188*a9369418SSami Tolvanen 
189*a9369418SSami Tolvanen /*
190*a9369418SSami Tolvanen  * STABLE:      variable structure_type ex2b {
191*a9369418SSami Tolvanen  * STABLE-NEXT:   member base_type int byte_size(4) encoding(5) a data_member_location(0) ,
192*a9369418SSami Tolvanen  * STABLE-NEXT:   member base_type [[ULONG]] byte_size(8) encoding(7) b data_member_location(8)
193*a9369418SSami Tolvanen  * STABLE-NEXT:   member base_type int byte_size(4) encoding(5) c data_member_location(16) ,
194*a9369418SSami Tolvanen  * STABLE-NEXT:   member base_type [[ULONG]] byte_size(8) encoding(7) d data_member_location(24)
195*a9369418SSami Tolvanen  * STABLE-NEXT: } byte_size(32)
196*a9369418SSami Tolvanen  */
197*a9369418SSami Tolvanen 
198*a9369418SSami Tolvanen struct ex2c {
199*a9369418SSami Tolvanen 	int a;
200*a9369418SSami Tolvanen 	KABI_IGNORE(0, unsigned int n);
201*a9369418SSami Tolvanen 	unsigned long b;
202*a9369418SSami Tolvanen 	int c;
203*a9369418SSami Tolvanen 	KABI_IGNORE(1, unsigned int m);
204*a9369418SSami Tolvanen 	unsigned long d;
205*a9369418SSami Tolvanen };
206*a9369418SSami Tolvanen 
207*a9369418SSami Tolvanen _Static_assert(sizeof(struct ex2a) == sizeof(struct ex2c), "ex2a size doesn't match ex2c");
208*a9369418SSami Tolvanen 
209*a9369418SSami Tolvanen /*
210*a9369418SSami Tolvanen  * STABLE:      variable structure_type ex2c {
211*a9369418SSami Tolvanen  * STABLE-NEXT:   member base_type int byte_size(4) encoding(5) a data_member_location(0) ,
212*a9369418SSami Tolvanen  * STABLE-NEXT:   member base_type [[ULONG]] byte_size(8) encoding(7) b data_member_location(8)
213*a9369418SSami Tolvanen  * STABLE-NEXT:   member base_type int byte_size(4) encoding(5) c data_member_location(16) ,
214*a9369418SSami Tolvanen  * STABLE-NEXT:   member base_type [[ULONG]] byte_size(8) encoding(7) d data_member_location(24)
215*a9369418SSami Tolvanen  * STABLE-NEXT: } byte_size(32)
216*a9369418SSami Tolvanen  */
217*a9369418SSami Tolvanen 
218*a9369418SSami Tolvanen 
219*a9369418SSami Tolvanen /*
220*a9369418SSami Tolvanen  * Example: A replaced field
221*a9369418SSami Tolvanen  */
222*a9369418SSami Tolvanen 
223*a9369418SSami Tolvanen struct ex3a {
224*a9369418SSami Tolvanen 	unsigned long a;
225*a9369418SSami Tolvanen 	unsigned long unused;
226*a9369418SSami Tolvanen };
227*a9369418SSami Tolvanen 
228*a9369418SSami Tolvanen /*
229*a9369418SSami Tolvanen  * STABLE:      variable structure_type ex3a {
230*a9369418SSami Tolvanen  * STABLE-NEXT:   member base_type [[ULONG:long unsigned int|unsigned long]] byte_size(8) encoding(7) a data_member_location(0)
231*a9369418SSami Tolvanen  * STABLE-NEXT:   member base_type [[ULONG]] byte_size(8) encoding(7) unused data_member_location(8)
232*a9369418SSami Tolvanen  * STABLE-NEXT: } byte_size(16)
233*a9369418SSami Tolvanen  */
234*a9369418SSami Tolvanen 
235*a9369418SSami Tolvanen struct ex3b {
236*a9369418SSami Tolvanen 	unsigned long a;
237*a9369418SSami Tolvanen 	KABI_REPLACE(unsigned long, unused, unsigned long renamed);
238*a9369418SSami Tolvanen };
239*a9369418SSami Tolvanen 
240*a9369418SSami Tolvanen _Static_assert(sizeof(struct ex3a) == sizeof(struct ex3b), "ex3a size doesn't match ex3b");
241*a9369418SSami Tolvanen 
242*a9369418SSami Tolvanen /*
243*a9369418SSami Tolvanen  * STABLE:      variable structure_type ex3b {
244*a9369418SSami Tolvanen  * STABLE-NEXT:   member base_type [[ULONG]] byte_size(8) encoding(7) a data_member_location(0)
245*a9369418SSami Tolvanen  * STABLE-NEXT:   member base_type [[ULONG]] byte_size(8) encoding(7) unused data_member_location(8)
246*a9369418SSami Tolvanen  * STABLE-NEXT: } byte_size(16)
247*a9369418SSami Tolvanen  */
248*a9369418SSami Tolvanen 
249*a9369418SSami Tolvanen struct ex3c {
250*a9369418SSami Tolvanen 	unsigned long a;
251*a9369418SSami Tolvanen 	KABI_REPLACE(unsigned long, unused, long replaced);
252*a9369418SSami Tolvanen };
253*a9369418SSami Tolvanen 
254*a9369418SSami Tolvanen _Static_assert(sizeof(struct ex3a) == sizeof(struct ex3c), "ex3a size doesn't match ex3c");
255*a9369418SSami Tolvanen 
256*a9369418SSami Tolvanen /*
257*a9369418SSami Tolvanen  * STABLE:      variable structure_type ex3c {
258*a9369418SSami Tolvanen  * STABLE-NEXT:   member base_type [[ULONG]] byte_size(8) encoding(7) a data_member_location(0)
259*a9369418SSami Tolvanen  * STABLE-NEXT:   member base_type [[ULONG]] byte_size(8) encoding(7) unused data_member_location(8)
260*a9369418SSami Tolvanen  * STABLE-NEXT: } byte_size(16)
261936cf61cSSami Tolvanen  */
262936cf61cSSami Tolvanen 
263936cf61cSSami Tolvanen #endif /* __KABI_EX_H__ */
264