libctf-bitfield-name-lookup.c revision 1.1 1 1.1 christos /* Verify that name lookup of basic types including old-style bitfield types
2 1.1 christos yields the non-bitfield. */
3 1.1 christos
4 1.1 christos #include <ctf-api.h>
5 1.1 christos #include <inttypes.h>
6 1.1 christos #include <stdio.h>
7 1.1 christos #include <stdlib.h>
8 1.1 christos
9 1.1 christos int bitfieldery (int count, int up, int pos)
10 1.1 christos {
11 1.1 christos unsigned char *ctf_written;
12 1.1 christos size_t size;
13 1.1 christos ctf_dict_t *dict;
14 1.1 christos const char *err = "opening";
15 1.1 christos int open_err;
16 1.1 christos ctf_encoding_t en;
17 1.1 christos ctf_encoding_t basic;
18 1.1 christos ctf_id_t type;
19 1.1 christos size_t i;
20 1.1 christos
21 1.1 christos /* This is rendered annoying by two factors: old-style bitfields are not
22 1.1 christos generated by current compilers, so we need to build a suitable dict by
23 1.1 christos hand; and this is an open-time bug, so we need to serialize it and then
24 1.1 christos load it back in again. */
25 1.1 christos
26 1.1 christos if ((dict = ctf_create (&open_err)) == NULL)
27 1.1 christos goto open_err;
28 1.1 christos
29 1.1 christos /* Populate with a pile of bitfields of increasing/decreasing size, with a
30 1.1 christos single basic type dropped in at position POS. Oscillate the offset
31 1.1 christos between 0 and 1. */
32 1.1 christos
33 1.1 christos basic.cte_bits = count;
34 1.1 christos basic.cte_offset = 0;
35 1.1 christos basic.cte_format = CTF_INT_SIGNED;
36 1.1 christos
37 1.1 christos en.cte_bits = up ? 0 : count - 1;
38 1.1 christos en.cte_offset = 0;
39 1.1 christos en.cte_format = CTF_INT_SIGNED;
40 1.1 christos
41 1.1 christos for (i = 0; i < count; i++)
42 1.1 christos {
43 1.1 christos if (i == pos)
44 1.1 christos {
45 1.1 christos err = "populating with basic type";
46 1.1 christos if (ctf_add_integer (dict, CTF_ADD_ROOT, "int", &basic) < 0)
47 1.1 christos goto err;
48 1.1 christos }
49 1.1 christos
50 1.1 christos err = "populating";
51 1.1 christos if (ctf_add_integer (dict, CTF_ADD_ROOT, "int", &en) < 0)
52 1.1 christos goto err;
53 1.1 christos
54 1.1 christos en.cte_bits += up ? 1 : -1;
55 1.1 christos if (en.cte_offset == 0)
56 1.1 christos en.cte_offset = 1;
57 1.1 christos else
58 1.1 christos en.cte_offset = 0;
59 1.1 christos }
60 1.1 christos
61 1.1 christos /* Possibly populate with at-end basic type. */
62 1.1 christos if (i == pos)
63 1.1 christos {
64 1.1 christos err = "populating with basic type";
65 1.1 christos if (ctf_add_integer (dict, CTF_ADD_ROOT, "int", &basic) < 0)
66 1.1 christos goto err;
67 1.1 christos }
68 1.1 christos
69 1.1 christos err = "writing";
70 1.1 christos if ((ctf_written = ctf_write_mem (dict, &size, 4096)) == NULL)
71 1.1 christos goto err;
72 1.1 christos ctf_dict_close (dict);
73 1.1 christos
74 1.1 christos err = "opening";
75 1.1 christos if ((dict = ctf_simple_open ((char *) ctf_written, size, NULL, 0,
76 1.1 christos 0, NULL, 0, &open_err)) == NULL)
77 1.1 christos goto open_err;
78 1.1 christos
79 1.1 christos err = "looking up";
80 1.1 christos if ((type = ctf_lookup_by_name (dict, "int")) == CTF_ERR)
81 1.1 christos goto err;
82 1.1 christos
83 1.1 christos err = "encoding check";
84 1.1 christos if (ctf_type_encoding (dict, type, &en) < 0)
85 1.1 christos goto err;
86 1.1 christos
87 1.1 christos if (en.cte_bits < count || en.cte_offset != 0)
88 1.1 christos {
89 1.1 christos fprintf (stderr, "Name lookup with count %i, pos %i, counting %s "
90 1.1 christos "gave bitfield ID %lx with bits %i, offset %i\n", count, pos,
91 1.1 christos up ? "up" : "down", type, en.cte_bits, en.cte_offset);
92 1.1 christos return 1;
93 1.1 christos }
94 1.1 christos ctf_dict_close (dict);
95 1.1 christos free (ctf_written);
96 1.1 christos
97 1.1 christos return 0;
98 1.1 christos
99 1.1 christos open_err:
100 1.1 christos fprintf (stdout, "Error %s: %s\n", err, ctf_errmsg (open_err));
101 1.1 christos return 1;
102 1.1 christos
103 1.1 christos err:
104 1.1 christos fprintf (stdout, "Error %s: %s\n", err, ctf_errmsg (ctf_errno (dict)));
105 1.1 christos return 1;
106 1.1 christos }
107 1.1 christos
108 1.1 christos /* Do a bunch of tests with a type of a given size: up and down, basic type
109 1.1 christos at and near the start and end, and in the middle. */
110 1.1 christos
111 1.1 christos void mass_bitfieldery (long size)
112 1.1 christos {
113 1.1 christos size *= 8;
114 1.1 christos bitfieldery (size, 1, 0);
115 1.1 christos bitfieldery (size, 0, 0);
116 1.1 christos bitfieldery (size, 1, 1);
117 1.1 christos bitfieldery (size, 0, 1);
118 1.1 christos bitfieldery (size, 1, size / 2);
119 1.1 christos bitfieldery (size, 0, size / 2);
120 1.1 christos bitfieldery (size, 1, size - 1);
121 1.1 christos bitfieldery (size, 0, size - 1);
122 1.1 christos bitfieldery (size, 1, size);
123 1.1 christos bitfieldery (size, 0, size);
124 1.1 christos }
125 1.1 christos
126 1.1 christos int main (void)
127 1.1 christos {
128 1.1 christos mass_bitfieldery (sizeof (char));
129 1.1 christos mass_bitfieldery (sizeof (short));
130 1.1 christos mass_bitfieldery (sizeof (int));
131 1.1 christos mass_bitfieldery (sizeof (long));
132 1.1 christos mass_bitfieldery (sizeof (uint64_t));
133 1.1 christos
134 1.1 christos printf ("All done.\n");
135 1.1 christos
136 1.1 christos return 0;
137 1.1 christos }
138