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