xref: /linux/scripts/gendwarfksyms/examples/kabi_ex.h (revision ba6ec09911b805778a2fed6d626bfe77b011a717)
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 
26 #ifndef __KABI_EX_H__
27 #define __KABI_EX_H__
28 
29 #include "kabi.h"
30 
31 /*
32  * Example: kABI rules
33  */
34 
35 struct s {
36 	int a;
37 };
38 
39 KABI_DECLONLY(s);
40 
41 /*
42  * STABLE:      variable structure_type s {
43  * STABLE-NEXT: }
44  */
45 
46 enum e {
47 	A,
48 	B,
49 	C,
50 	D,
51 };
52 
53 KABI_ENUMERATOR_IGNORE(e, B);
54 KABI_ENUMERATOR_IGNORE(e, C);
55 KABI_ENUMERATOR_VALUE(e, D, 123456789);
56 
57 /*
58  * STABLE:      variable enumeration_type e {
59  * STABLE-NEXT:   enumerator A = 0 ,
60  * STABLE-NEXT:   enumerator D = 123456789
61  * STABLE-NEXT: } byte_size(4)
62 */
63 
64 /*
65  * Example: Reserved fields
66  */
67 struct ex0a {
68 	int a;
69 	KABI_RESERVE(0);
70 	KABI_RESERVE(1);
71 };
72 
73 /*
74  * STABLE:      variable structure_type ex0a {
75  * STABLE-NEXT:   member base_type int byte_size(4) encoding(5) a data_member_location(0) ,
76  * STABLE-NEXT:   member base_type [[ULONG:long unsigned int|unsigned long]] byte_size(8) encoding(7) data_member_location(8) ,
77  * STABLE-NEXT:   member base_type [[ULONG]] byte_size(8) encoding(7) data_member_location(16)
78  * STABLE-NEXT: } byte_size(24)
79  */
80 
81 struct ex0b {
82 	int a;
83 	KABI_RESERVE(0);
84 	KABI_USE2(1, int b, int c);
85 };
86 
87 /*
88  * STABLE:      variable structure_type ex0b {
89  * STABLE-NEXT:   member base_type int byte_size(4) encoding(5) a data_member_location(0) ,
90  * STABLE-NEXT:   member base_type [[ULONG]] byte_size(8) encoding(7) data_member_location(8) ,
91  * STABLE-NEXT:   member base_type [[ULONG]] byte_size(8) encoding(7) data_member_location(16)
92  * STABLE-NEXT: } byte_size(24)
93  */
94 
95 struct ex0c {
96 	int a;
97 	KABI_USE(0, void *p);
98 	KABI_USE2(1, int b, int c);
99 };
100 
101 /*
102  * STABLE:      variable structure_type ex0c {
103  * STABLE-NEXT:   member base_type int byte_size(4) encoding(5) a data_member_location(0) ,
104  * STABLE-NEXT:   member base_type [[ULONG]] byte_size(8) encoding(7) data_member_location(8) ,
105  * STABLE-NEXT:   member base_type [[ULONG]] byte_size(8) encoding(7) data_member_location(16)
106  * STABLE-NEXT: } byte_size(24)
107  */
108 
109 /*
110  * Example: A reserved array
111  */
112 
113 struct ex1a {
114 	unsigned int a;
115 	KABI_RESERVE_ARRAY(0, 64);
116 };
117 
118 /*
119  * STABLE:      variable structure_type ex1a {
120  * STABLE-NEXT:   member base_type unsigned int byte_size(4) encoding(7) a data_member_location(0) ,
121  * STABLE-NEXT:   member array_type[64] {
122  * STABLE-NEXT:     base_type unsigned char byte_size(1) encoding(8)
123  * STABLE-NEXT:   } data_member_location(8)
124  * STABLE-NEXT: } byte_size(72)
125  */
126 
127 struct ex1b {
128 	unsigned int a;
129 	KABI_USE_ARRAY(
130 		0, 64, struct {
131 			void *p;
132 			KABI_RESERVE_ARRAY(1, 56);
133 		});
134 };
135 
136 /*
137  * STABLE:      variable structure_type ex1b {
138  * STABLE-NEXT:   member base_type unsigned int byte_size(4) encoding(7) a data_member_location(0) ,
139  * STABLE-NEXT:   member array_type[64] {
140  * STABLE-NEXT:     base_type unsigned char byte_size(1) encoding(8)
141  * STABLE-NEXT:   } data_member_location(8)
142  * STABLE-NEXT: } byte_size(72)
143  */
144 
145 struct ex1c {
146 	unsigned int a;
147 	KABI_USE_ARRAY(0, 64, void *p[8]);
148 };
149 
150 /*
151  * STABLE:      variable structure_type ex1c {
152  * STABLE-NEXT:   member base_type unsigned int byte_size(4) encoding(7) a data_member_location(0) ,
153  * STABLE-NEXT:   member array_type[64] {
154  * STABLE-NEXT:     base_type unsigned char byte_size(1) encoding(8)
155  * STABLE-NEXT:   } data_member_location(8)
156  * STABLE-NEXT: } byte_size(72)
157  */
158 
159 /*
160  * Example: An ignored field added to an alignment hole
161  */
162 
163 struct ex2a {
164 	int a;
165 	unsigned long b;
166 	int c;
167 	unsigned long d;
168 };
169 
170 /*
171  * STABLE:      variable structure_type ex2a {
172  * STABLE-NEXT:   member base_type int byte_size(4) encoding(5) a data_member_location(0) ,
173  * STABLE-NEXT:   member base_type [[ULONG:long unsigned int|unsigned long]] byte_size(8) encoding(7) b data_member_location(8)
174  * STABLE-NEXT:   member base_type int byte_size(4) encoding(5) c data_member_location(16) ,
175  * STABLE-NEXT:   member base_type [[ULONG]] byte_size(8) encoding(7) d data_member_location(24)
176  * STABLE-NEXT: } byte_size(32)
177  */
178 
179 struct ex2b {
180 	int a;
181 	KABI_IGNORE(0, unsigned int n);
182 	unsigned long b;
183 	int c;
184 	unsigned long d;
185 };
186 
187 _Static_assert(sizeof(struct ex2a) == sizeof(struct ex2b), "ex2a size doesn't match ex2b");
188 
189 /*
190  * STABLE:      variable structure_type ex2b {
191  * STABLE-NEXT:   member base_type int byte_size(4) encoding(5) a data_member_location(0) ,
192  * STABLE-NEXT:   member base_type [[ULONG]] byte_size(8) encoding(7) b data_member_location(8)
193  * STABLE-NEXT:   member base_type int byte_size(4) encoding(5) c data_member_location(16) ,
194  * STABLE-NEXT:   member base_type [[ULONG]] byte_size(8) encoding(7) d data_member_location(24)
195  * STABLE-NEXT: } byte_size(32)
196  */
197 
198 struct ex2c {
199 	int a;
200 	KABI_IGNORE(0, unsigned int n);
201 	unsigned long b;
202 	int c;
203 	KABI_IGNORE(1, unsigned int m);
204 	unsigned long d;
205 };
206 
207 _Static_assert(sizeof(struct ex2a) == sizeof(struct ex2c), "ex2a size doesn't match ex2c");
208 
209 /*
210  * STABLE:      variable structure_type ex2c {
211  * STABLE-NEXT:   member base_type int byte_size(4) encoding(5) a data_member_location(0) ,
212  * STABLE-NEXT:   member base_type [[ULONG]] byte_size(8) encoding(7) b data_member_location(8)
213  * STABLE-NEXT:   member base_type int byte_size(4) encoding(5) c data_member_location(16) ,
214  * STABLE-NEXT:   member base_type [[ULONG]] byte_size(8) encoding(7) d data_member_location(24)
215  * STABLE-NEXT: } byte_size(32)
216  */
217 
218 
219 /*
220  * Example: A replaced field
221  */
222 
223 struct ex3a {
224 	unsigned long a;
225 	unsigned long unused;
226 };
227 
228 /*
229  * STABLE:      variable structure_type ex3a {
230  * STABLE-NEXT:   member base_type [[ULONG:long unsigned int|unsigned long]] byte_size(8) encoding(7) a data_member_location(0)
231  * STABLE-NEXT:   member base_type [[ULONG]] byte_size(8) encoding(7) unused data_member_location(8)
232  * STABLE-NEXT: } byte_size(16)
233  */
234 
235 struct ex3b {
236 	unsigned long a;
237 	KABI_REPLACE(unsigned long, unused, unsigned long renamed);
238 };
239 
240 _Static_assert(sizeof(struct ex3a) == sizeof(struct ex3b), "ex3a size doesn't match ex3b");
241 
242 /*
243  * STABLE:      variable structure_type ex3b {
244  * STABLE-NEXT:   member base_type [[ULONG]] byte_size(8) encoding(7) a data_member_location(0)
245  * STABLE-NEXT:   member base_type [[ULONG]] byte_size(8) encoding(7) unused data_member_location(8)
246  * STABLE-NEXT: } byte_size(16)
247  */
248 
249 struct ex3c {
250 	unsigned long a;
251 	KABI_REPLACE(unsigned long, unused, long replaced);
252 };
253 
254 _Static_assert(sizeof(struct ex3a) == sizeof(struct ex3c), "ex3a size doesn't match ex3c");
255 
256 /*
257  * STABLE:      variable structure_type ex3c {
258  * STABLE-NEXT:   member base_type [[ULONG]] byte_size(8) encoding(7) a data_member_location(0)
259  * STABLE-NEXT:   member base_type [[ULONG]] byte_size(8) encoding(7) unused data_member_location(8)
260  * STABLE-NEXT: } byte_size(16)
261  */
262 
263 #endif /* __KABI_EX_H__ */
264