xref: /illumos-gate/usr/src/test/util-tests/tests/ctf/test-sou.c (revision 8b184c19c5f61fa8890900f7bab686bf19b543d3)
1 /*
2  * This file and its contents are supplied under the terms of the
3  * Common Development and Distribution License ("CDDL"), version 1.0.
4  * You may only use this file in accordance with the terms of version
5  * 1.0 of the CDDL.
6  *
7  * A full copy of the text of the CDDL should have accompanied this
8  * source.  A copy of the CDDL is also available via the Internet at
9  * http://www.illumos.org/license/CDDL.
10  */
11 
12 /*
13  * Copyright (c) 2019, Joyent, Inc.
14  * Copyright 2025 Oxide Computer Company
15  */
16 
17 #include <sys/types.h>
18 #include <complex.h>
19 
20 /*
21  * Test various structure and union constructs, including various things that
22  * have caused regressions in the past.
23  */
24 
25 /*
26  * Basic, simple struct.
27  */
28 struct foo {
29 	int a;
30 	float b;
31 	const char *c;
32 };
33 
34 struct foo foo;
35 
36 /*
37  * Self-referential structs
38  */
39 struct node {
40 	struct node *prev;
41 	struct node *next;
42 };
43 
44 typedef struct nlist {
45 	size_t size;
46 	size_t off;
47 	struct node head;
48 } nlist_t;
49 
50 nlist_t head;
51 
52 /*
53  * Struct that has a forward declaration.
54  */
55 typedef struct forward forward_t;
56 struct forward {
57 	void *past;
58 	void *present;
59 	void *future;
60 };
61 
62 const forward_t forward;
63 
64 /*
65  * Here, we have a pair of structures that basically round up to different
66  * sizes. As in, the size of the structure is somewhat compiler dependent.
67  */
68 struct round_up {
69 	uint8_t triforce;
70 	uint32_t link;
71 	uint8_t zelda;
72 	uint8_t ganon;
73 };
74 
75 #pragma pack(1)
76 struct fixed_up {
77 	uint8_t triforce;
78 	uint32_t link;
79 	uint8_t zelda;
80 	uint8_t ganon;
81 };
82 #pragma pack()
83 
84 struct round_up oot;
85 struct fixed_up botw;
86 
87 /*
88  * Various GNU and c99 style arrays
89  */
90 enum material {
91 	COPPER,
92 	IRON,
93 	STEEL,
94 	ADAMANTIUM,
95 	MYTHRIL,
96 	ORIHALCUM
97 };
98 
99 struct component {
100 	enum material m;
101 	uint64_t grade;
102 	uint64_t count;
103 	const char *locations[4];
104 };
105 
106 struct mysterious_barrel {
107 	const char *name;
108 	size_t capacity;
109 	struct component optional[];
110 };
111 
112 struct dusk_barrel {
113 	const char *name;
114 	size_t opacity;
115 	struct component optional[0];
116 };
117 
118 struct mysterious_barrel sophie;
119 struct dusk_barrel ayesha;
120 
121 /*
122  * Various bitfield forms.
123  */
124 
125 /*
126  * Variant of the Intel system_desc.
127  */
128 struct stats {
129 	uint64_t hp:16;
130 	uint64_t mp:16;
131 	uint64_t str:8;
132 	uint64_t dex:4;
133 	uint64_t con:1;
134 	uint64_t inte:2;
135 	uint64_t wis:1;
136 	uint64_t cha:4;
137 	uint64_t sanity:1;
138 	uint64_t attack:2;
139 	uint64_t mattack:1;
140 	uint64_t defense:8;
141 	uint64_t mdefense:32;
142 	uint64_t evasion:8;
143 	uint64_t crit:5;
144 	uint64_t luck:19;
145 };
146 
147 struct stats stats;
148 
149 /*
150  * More odd length structures due to bitfields
151  */
152 struct fellowship {
153 	uint16_t frodo:1;
154 	uint16_t sam:1;
155 	uint16_t merry:1;
156 	uint16_t pippin:1;
157 	uint16_t aragorn:1;
158 	uint16_t boromir:1;
159 	uint16_t legolas:1;
160 	uint16_t gimli:1;
161 	uint16_t gandalf:1;
162 };
163 
164 struct fellowship ring;
165 
166 struct rings {
167 	uint32_t elves:3;
168 	uint32_t dwarves:7;
169 	uint32_t men:9;
170 	uint8_t one;
171 	uint8_t silmarils[3];
172 };
173 
174 struct rings rings;
175 
176 /*
177  * Regression, we didn't handle receiving a negative offset from DWARF with
178  * this.
179  */
180 #pragma pack(1)
181 struct csts {
182 	unsigned int rdy:7;
183 	unsigned int csts:32;
184 };
185 
186 struct csts nvme;
187 #pragma pack()
188 
189 /*
190  * Onto unions
191  */
192 union jrpg {
193 	int ff;
194 	double atelier[4];
195 	const char *tales;
196 	int (*chrono)(void);
197 	struct rings xeno;
198 };
199 
200 union jrpg games;
201 
202 #pragma pack(1)
203 struct android {
204 	uint32_t _2b:16;
205 	uint32_t _9s:16;
206 };
207 
208 union nier {
209 	uint32_t automata;
210 	struct android android;
211 };
212 #pragma pack()
213 
214 union nier nier;
215 
216 union kh {
217 	int sora:3;
218 	char riku:7;
219 	double kairi;
220 	complex double namine;
221 };
222 
223 union kh kh;
224 
225 /*
226  * Anonymous union in a struct, GNU extension / C11
227  */
228 
229 struct trigger {
230 	uint8_t chrono;
231 	uint8_t cross;
232 	union {
233 		void *lavos;
234 		int *crono;
235 		uint64_t schala[3];
236 	};
237 };
238 
239 struct trigger ct;
240 
241 /*
242  * This is an array/union combo that failed conversion previously. Because it is
243  * static, we need to have a dummy function to make sure that clang doesn't
244  * optimize it away. Hopefully even with optimizations, this'll still be kept
245  * even though it's a constant.
246  */
247 static const union regress {
248 	unsigned int i[3];
249 	long double e;
250 } regress[9];
251 
252 unsigned int
get_regress(void)253 get_regress(void)
254 {
255 	return (regress[0].i[2]);
256 }
257 
258 /*
259  * Now we have a series of different anonymous unions and structures.
260  */
261 struct anon_basic {
262 	int a;
263 	union {
264 		int b;
265 		double c;
266 		const char *d;
267 	};
268 	struct {
269 		int e;
270 		const char *f;
271 		unsigned int g[10];
272 	};
273 };
274 
275 struct anon_basic anon_basic;
276 
277 struct nested {
278 	int a;
279 	union {
280 		int b;
281 		struct {
282 			int c;
283 			int d;
284 			int e;
285 			union {
286 				int g;
287 				struct {
288 					int h;
289 				};
290 			};
291 			struct {
292 				int i;
293 				struct {
294 					int j;
295 					union {
296 						int k;
297 						struct {
298 							int l;
299 							int m;
300 						};
301 						union {
302 							int n;
303 							struct {
304 								int o;
305 								int p;
306 							};
307 						};
308 					};
309 				};
310 			};
311 		};
312 	};
313 };
314 
315 struct nested nested;
316