xref: /illumos-gate/usr/src/cmd/dtrace/test/tst/common/bitfields/tst.bitfields.c (revision 2a295025ab352ac2f6469a947d5b5e2f9379f943)
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 2022 Oxide Computer Company
14  */
15 
16 /*
17  * This is designed to allow us to execute print() and various dereferencing
18  * operations with bitfields. It reads the values from argc and passes them to
19  * functions that we can then take apart. Crtitically this uses bitfields
20  * constructed via CTF and not the D compiler.
21  */
22 
23 #include <err.h>
24 #include <stdlib.h>
25 #include <stdint.h>
26 #include <stdlib.h>
27 #include <errno.h>
28 
29 typedef struct bit0 {
30 	uint32_t a:3;
31 	uint32_t b:2;
32 	uint32_t c:1;
33 	uint32_t d:1;
34 	uint32_t e:1;
35 	uint32_t f:1;
36 	uint32_t g:3;
37 	uint32_t h:3;
38 	uint32_t i:5;
39 	uint32_t j:4;
40 	uint32_t k:6;
41 	uint32_t l:1;
42 	uint32_t m:1;
43 } bit0_t;
44 
45 typedef struct bit1 {
46 	uint16_t a:1;
47 	uint16_t b:8;
48 	uint16_t c:3;
49 	uint16_t d:2;
50 	uint16_t e:1;
51 	uint16_t f:1;
52 } bit1_t;
53 
54 void
55 mumble(FILE *f, bit0_t *zero, bit1_t *one)
56 {
57 	(void) fprintf(f, "%u\n%u\n", zero->k, one->d);
58 }
59 
60 int
61 main(int argc, char *argv[])
62 {
63 	unsigned long l;
64 	uint16_t u16;
65 	uint32_t u32;
66 	FILE *f;
67 
68 	if (argc != 3) {
69 		errx(EXIT_FAILURE, "Need two ints");
70 	}
71 
72 	f = fopen("/dev/null", "rw+");
73 	if (f == NULL) {
74 		err(EXIT_FAILURE, "failed to open /dev/null");
75 	}
76 
77 	errno = 0;
78 	l = strtoul(argv[1], NULL, 0);
79 	if (errno != 0 || l == 0 || l > UINT16_MAX) {
80 		errx(EXIT_FAILURE, "invalid u16 value: %s", argv[1]);
81 	}
82 	u16 = (uint16_t)l;
83 
84 	l = strtoul(argv[2], NULL, 0);
85 	if (errno != 0 || l == 0 || l > UINT32_MAX) {
86 		errx(EXIT_FAILURE, "invalid u32 value: %s", argv[1]);
87 	}
88 	u32 = (uint32_t)l;
89 	mumble(f, (bit0_t *)&u32, (bit1_t *)&u16);
90 
91 	return (0);
92 }
93