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