[binutils-gdb] libctf, dump: fix slice dumping

Nick Alcock nix@sourceware.org
Wed Jul 22 17:10:41 GMT 2020


https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=70447401740235d828c4b7b87e398eeae4801094

commit 70447401740235d828c4b7b87e398eeae4801094
Author: Nick Alcock <nick.alcock@oracle.com>
Date:   Mon May 11 18:18:50 2020 +0100

    libctf, dump: fix slice dumping
    
    Now that we can have slices of anything terminating in an int, we must
    dump things accordingly, or slices of typedefs appear as
    
      c5b: __u8 -> 16c: __u8 -> 78: short unsigned int (size 0x2)
    
    which is unhelpful.  If things *are* printed as slices, the name is
    missing:
    
      a15: [slice 0x8:0x4]-> 16c: __u8 -> 78: short unsigned int (size 0x2)
    
    And struct members give no clue they're a slice at all, which is a shame
    since bitfields are the major use of this type kind:
    
           [0x8] (ID 0xa15) (kind 10) __u8  dst_reg
    
    Fix things so that everything slicelike or integral gets its encoding
    printed, and everything with a name gets the name printed:
    
      a15: __u8  [slice 0x8:0x4] (size 0x1) -> 1ff: __u8 (size 0x1) -> 37: unsigned char [0x0:0x8] (size 0x1)
         [0x0] (ID 0xa15) (kind 10) __u8:4 (aligned at 0x1, format 0x2, offset:bits 0x8:0x4)
    
    Bitfield struct members get a technically redundant but much
    easier-to-understand dumping now:
    
        [0x0] (ID 0x80000005) (kind 6) struct bpf_insn (aligned at 0x1)
            [0x0] (ID 0x222) (kind 10) __u8 code (aligned at 0x1)
            [0x8] (ID 0x1e9e) (kind 10) __u8  dst_reg:4 (aligned at 0x1, format 0x2, offset:bits 0x8:0x4)
            [0xc] (ID 0x1e46) (kind 10) __u8  src_reg:4 (aligned at 0x1, format 0x2, offset:bits 0xc:0x4)
            [0x10] (ID 0xf35) (kind 10) __s16 off (aligned at 0x2)
            [0x20] (ID 0x1718) (kind 10) __s32 imm (aligned at 0x4)
    
    This also fixes one place where a failure to format a type would be
    erroneously considered an out-of-memory condition.
    
    libctf/
            * ctf-dump.c (ctf_is_slice): Delete, unnecessary.
            (ctf_dump_format_type): improve slice formatting.  Always print
            the type size, even of slices.
            (ctf_dump_member): Print slices (-> bitfields) differently from
            non-slices.  Failure to format a type is not an OOM.

Diff:
---
 libctf/ChangeLog  |  8 +++++
 libctf/ctf-dump.c | 92 ++++++++++++++++++++++++++++++++++---------------------
 2 files changed, 65 insertions(+), 35 deletions(-)

diff --git a/libctf/ChangeLog b/libctf/ChangeLog
index b13c51c88e6..841f1462f29 100644
--- a/libctf/ChangeLog
+++ b/libctf/ChangeLog
@@ -1,3 +1,11 @@
+2020-07-22  Nick Alcock  <nick.alcock@oracle.com>
+
+	* ctf-dump.c (ctf_is_slice): Delete, unnecessary.
+	(ctf_dump_format_type): improve slice formatting.  Always print
+	the type size, even of slices.
+	(ctf_dump_member): Print slices (-> bitfields) differently from
+	non-slices.  Failure to format a type is not an OOM.
+
 2020-07-22  Nick Alcock  <nick.alcock@oracle.com>
 
 	* ctf-dump.c (ctf_dump_format_type): Emit a warning.
diff --git a/libctf/ctf-dump.c b/libctf/ctf-dump.c
index 55aa496e8b7..94d6bc6f018 100644
--- a/libctf/ctf-dump.c
+++ b/libctf/ctf-dump.c
@@ -79,20 +79,6 @@ ctf_dump_free (ctf_dump_state_t *state)
     }
 }
 
-/* Slices need special handling to distinguish them from their referenced
-   type.  */
-
-static int
-ctf_is_slice (ctf_file_t *fp, ctf_id_t id, ctf_encoding_t *enc)
-{
-  int kind = ctf_type_kind (fp, id);
-
-  return (((kind == CTF_K_INTEGER) || (kind == CTF_K_ENUM)
-	   || (kind == CTF_K_FLOAT))
-	  && ctf_type_reference (fp, id) != CTF_ERR
-	  && ctf_type_encoding (fp, id, enc) == 0);
-}
-
 /* Return a dump for a single type, without member info: but do show the
    type's references.  */
 
@@ -129,26 +115,45 @@ ctf_dump_format_type (ctf_file_t *fp, ctf_id_t id, int flag)
 	  goto err;
 	}
 
-      /* Slices get a different print representation.  */
+      if (asprintf (&bit, " %s%lx: ", nonroot_leader, id) < 0)
+	goto oom;
+      str = str_append (str, bit);
+      free (bit);
+      bit = NULL;
+
+      if (buf[0] != '\0')
+	{
+	  str = str_append (str, buf);
+	  str = str_append (str, " ");
+	}
+
+      free (buf);
+      buf = NULL;
 
-      if (ctf_is_slice (fp, id, &enc))
+      /* Slices get a different print representation.  */
+      if (ctf_type_kind_unsliced (fp, id) == CTF_K_SLICE)
 	{
 	  ctf_type_encoding (fp, id, &enc);
-	  if (asprintf (&bit, " %s%lx: [slice 0x%x:0x%x]%s",
-			nonroot_leader, id, enc.cte_offset, enc.cte_bits,
-			nonroot_trailer) < 0)
+	  if (asprintf (&bit, "[slice 0x%x:0x%x] ",
+			enc.cte_offset, enc.cte_bits) < 0)
 	    goto oom;
 	}
-      else
+      else if (ctf_type_kind (fp, id) == CTF_K_INTEGER)
 	{
-	  if (asprintf (&bit, " %s%lx: %s (size 0x%lx)%s", nonroot_leader,
-			id, buf[0] == '\0' ? "(nameless)" : buf,
-			(unsigned long) ctf_type_size (fp, id),
-			nonroot_trailer) < 0)
+	  ctf_type_encoding (fp, id, &enc);
+	  if (asprintf (&bit, "[0x%x:0x%x] ",
+			enc.cte_offset, enc.cte_bits) < 0)
 	    goto oom;
 	}
-      free (buf);
-      buf = NULL;
+      str = str_append (str, bit);
+      free (bit);
+      bit = NULL;
+
+      if (asprintf (&bit, "(size 0x%lx)%s",
+		    (unsigned long) ctf_type_size (fp, id),
+		    nonroot_trailer) < 0)
+	goto oom;
+
       str = str_append (str, bit);
       free (bit);
       bit = NULL;
@@ -516,6 +521,7 @@ ctf_dump_member (const char *name, ctf_id_t id, unsigned long offset,
   char *typestr = NULL;
   char *bit = NULL;
   ctf_encoding_t ep;
+  int has_encoding = 0;
   ssize_t i;
 
   for (i = 0; i < depth; i++)
@@ -535,24 +541,40 @@ ctf_dump_member (const char *name, ctf_id_t id, unsigned long offset,
 	  return 0;
 	}
 
-      goto oom;
+      return -1;				/* errno is set for us.  */
+    }
+
+  if (ctf_type_encoding (state->cdm_fp, id, &ep) == 0)
+    {
+      has_encoding = 1;
+      ctf_type_encoding (state->cdm_fp, id, &ep);
+
+      if (asprintf (&bit, "    [0x%lx] (ID 0x%lx) (kind %i) %s%s%s:%i "
+		    "(aligned at 0x%lx", offset, id,
+		    ctf_type_kind (state->cdm_fp, id), typestr,
+		    (name[0] != 0 && typestr[0] != 0) ? " " : "", name,
+		    ep.cte_bits, (unsigned long) ctf_type_align (state->cdm_fp,
+								 id)) < 0)
+	goto oom;
+    }
+  else
+    {
+      if (asprintf (&bit, "    [0x%lx] (ID 0x%lx) (kind %i) %s%s%s "
+		    "(aligned at 0x%lx", offset, id,
+		    ctf_type_kind (state->cdm_fp, id), typestr,
+		    (name[0] != 0 && typestr[0] != 0) ? " " : "", name,
+		    (unsigned long) ctf_type_align (state->cdm_fp, id)) < 0)
+	goto oom;
     }
 
-  if (asprintf (&bit, "    [0x%lx] (ID 0x%lx) (kind %i) %s %s (aligned at 0x%lx",
-		offset, id, ctf_type_kind (state->cdm_fp, id), typestr, name,
-		(unsigned long) ctf_type_align (state->cdm_fp, id)) < 0)
-    goto oom;
   *state->cdm_str = str_append (*state->cdm_str, bit);
   free (typestr);
   free (bit);
   typestr = NULL;
   bit = NULL;
 
-  if ((ctf_type_kind (state->cdm_fp, id) == CTF_K_INTEGER)
-      || (ctf_type_kind (state->cdm_fp, id) == CTF_K_FLOAT)
-      || (ctf_is_slice (state->cdm_fp, id, &ep) == CTF_K_ENUM))
+  if (has_encoding)
     {
-      ctf_type_encoding (state->cdm_fp, id, &ep);
       if (asprintf (&bit, ", format 0x%x, offset:bits 0x%x:0x%x", ep.cte_format,
 		    ep.cte_offset, ep.cte_bits) < 0)
 	goto oom;


More information about the Binutils-cvs mailing list