libctf, types: support slices of anything terminating in an int
authorNick Alcock <nick.alcock@oracle.com>
Tue, 2 Jun 2020 19:43:03 +0000 (20:43 +0100)
committerNick Alcock <nick.alcock@oracle.com>
Wed, 22 Jul 2020 16:57:31 +0000 (17:57 +0100)
It is perfectly valid C to say e.g.

typedef u64 int;
struct foo_t
  {
    const volatile u64 wibble:2;
  };

i.e. bitfields have to be integral types, but they can be cv-qualified
integral types or typedefs of same, etc.

This is easy to fix: do a ctf_type_resolve_unsliced() at creation time
to ensure the ultimate type is integral, and ctf_type_resolve() at
lookup time so that if you somehow have e.g. a slice of a typedef of a
slice of a cv-qualified int, we pull the encoding that the topmost slice
is based on out of the subsidiary slice (and then modify it), not out of
the underlying int.  (This last bit is rather academic right now, since
all slices override exactly the same properties of the underlying type,
but it's still the right thing to do.)

libctf/
* ctf-create.c (ctf_add_slice): Support slices of any kind that
resolves to an integral type.
* ctf-types.c (ctf_type_encoding): Resolve the type before
fishing its encoding out.

libctf/ChangeLog
libctf/ctf-create.c
libctf/ctf-types.c

index 0aee504f3e16fd8e9474584d23088abfcf2fa869..78f8f7e3a6c32a789af3371b03f3cdb20eaed6ce 100644 (file)
@@ -1,3 +1,10 @@
+2020-07-22  Nick Alcock  <nick.alcock@oracle.com>
+
+       * ctf-create.c (ctf_add_slice): Support slices of any kind that
+       resolves to an integral type.
+       * ctf-types.c (ctf_type_encoding): Resolve the type before
+       fishing its encoding out.
+
 2020-07-22  Nick Alcock  <nick.alcock@oracle.com>
 
        * ctf-create.c (ctf_create): Mark dirty.
index 1416d187fd9fc4c19206a99f4f44e6a71cc23c02..c13b83d4d3b02d8c45104e31e9291115aa44a692 100644 (file)
@@ -944,6 +944,7 @@ ctf_add_slice (ctf_file_t *fp, uint32_t flag, ctf_id_t ref,
               const ctf_encoding_t *ep)
 {
   ctf_dtdef_t *dtd;
+  ctf_id_t resolved_ref = ref;
   ctf_id_t type;
   int kind;
   const ctf_type_t *tp;
@@ -961,7 +962,13 @@ ctf_add_slice (ctf_file_t *fp, uint32_t flag, ctf_id_t ref,
   if (ref != 0 && ((tp = ctf_lookup_by_id (&tmp, ref)) == NULL))
     return CTF_ERR;            /* errno is set for us.  */
 
-  kind = ctf_type_kind_unsliced (tmp, ref);
+  /* Make sure we ultimately point to an integral type.  We also allow slices to
+     point to the unimplemented type, for now, because the compiler can emit
+     such slices, though they're not very much use.  */
+
+  resolved_ref = ctf_type_resolve_unsliced (tmp, ref);
+  kind = ctf_type_kind_unsliced (tmp, resolved_ref);
+
   if ((kind != CTF_K_INTEGER) && (kind != CTF_K_FLOAT) &&
       (kind != CTF_K_ENUM)
       && (ref != 0))
index 9c10905ea11aca624dcdd2acce5cbb6844917dc1..f5a1fc0ae1218fcec740b74c96132ba9464ba66f 100644 (file)
@@ -758,9 +758,12 @@ ctf_type_encoding (ctf_file_t *fp, ctf_id_t type, ctf_encoding_t *ep)
          {
            const ctf_slice_t *slice;
            ctf_encoding_t underlying_en;
+           ctf_id_t underlying;
+
            slice = &dtd->dtd_u.dtu_slice;
+           underlying = ctf_type_resolve (fp, slice->cts_type);
+           data = ctf_type_encoding (fp, underlying, &underlying_en);
 
-           data = ctf_type_encoding (fp, slice->cts_type, &underlying_en);
            ep->cte_format = underlying_en.cte_format;
            ep->cte_offset = slice->cts_offset;
            ep->cte_bits = slice->cts_bits;
@@ -792,9 +795,11 @@ ctf_type_encoding (ctf_file_t *fp, ctf_id_t type, ctf_encoding_t *ep)
       {
        const ctf_slice_t *slice;
        ctf_encoding_t underlying_en;
+       ctf_id_t underlying;
 
        slice = (ctf_slice_t *) ((uintptr_t) tp + increment);
-       data = ctf_type_encoding (fp, slice->cts_type, &underlying_en);
+       underlying = ctf_type_resolve (fp, slice->cts_type);
+       data = ctf_type_encoding (fp, underlying, &underlying_en);
 
        ep->cte_format = underlying_en.cte_format;
        ep->cte_offset = slice->cts_offset;