]> git.ipfire.org Git - thirdparty/binutils-gdb.git/commitdiff
libctf: serialize: type section sizing
authorNick Alcock <nick.alcock@oracle.com>
Fri, 25 Apr 2025 13:17:36 +0000 (14:17 +0100)
committerNick Alcock <nick.alcock@oracle.com>
Fri, 25 Apr 2025 17:07:44 +0000 (18:07 +0100)
This is made much simpler by the fact that the DTD representation
now tracks the size of each vlen, so we don't need per-type-kind
code to track it ourselves any more.  There's extra code to handle
type suppression, CTF_K_BIG elision, and prefixes.

libctf/ctf-serialize.c

index e0b5e87ea9a1cb3a7fb9ed9ec6c757caa47c3d4f..e0f86c85372c2dd270d775365e8d0509f0029750 100644 (file)
@@ -915,60 +915,57 @@ static size_t
 ctf_type_sect_size (ctf_dict_t *fp)
 {
   ctf_dtdef_t *dtd;
-  size_t type_size;
+  size_t type_size = 0;
 
-  for (type_size = 0, dtd = ctf_list_next (&fp->ctf_dtdefs);
+  for (dtd = ctf_list_next (&fp->ctf_dtdefs);
        dtd != NULL; dtd = ctf_list_next (dtd))
     {
-      uint32_t kind = LCTF_INFO_KIND (fp, dtd->dtd_data.ctt_info);
-      uint32_t vlen = LCTF_INFO_VLEN (fp, dtd->dtd_data.ctt_info);
-      size_t type_ctt_size = dtd->dtd_data.ctt_size;
+      uint32_t kind = LCTF_KIND (fp, dtd->dtd_buf);
+      ctf_type_t *tp = dtd->dtd_buf;
 
-      /* Shrink ctf_type_t-using types from a ctf_type_t to a ctf_stype_t
-        if possible.  */
+      /* Check for suppressions: a suppression consumes precisely one ctf_type_t
+        record of space.  */
 
-      if (kind == CTF_K_STRUCT || kind == CTF_K_UNION)
+      if (fp->ctf_write_suppressions)
        {
-         size_t lsize = CTF_TYPE_LSIZE (&dtd->dtd_data);
+         int suppress = 0;
 
-         if (lsize <= CTF_MAX_SIZE)
-           type_ctt_size = lsize;
+         while (kind = LCTF_INFO_UNPREFIXED_KIND (fp, tp->ctt_info),
+                LCTF_IS_PREFIXED_KIND (kind))
+           {
+             if ((kind != CTF_K_BIG) || tp->ctt_size != 0
+                 || LCTF_INFO_UNPREFIXED_VLEN (fp, tp->ctt_info) != 0)
+               if (ctf_dynset_lookup (fp->ctf_write_suppressions,
+                                      (const void *) (uintptr_t) kind) != NULL)
+                 {
+                   type_size += sizeof (ctf_type_t);
+                   suppress = 1;
+                   break;
+                 }
+
+             tp++;
+           }
+         if (suppress)
+           continue;
        }
 
-      if (type_ctt_size != CTF_LSIZE_SENT)
-       type_size += sizeof (ctf_stype_t);
-      else
-       type_size += sizeof (ctf_type_t);
+      /* Type headers: elide CTF_K_BIG from types if possible.  Must match
+        corresponding elision in ctf_emit_type_sect.  */
 
-      switch (kind)
+      tp = dtd->dtd_buf;
+      while (kind = LCTF_INFO_UNPREFIXED_KIND (fp, tp->ctt_info),
+            LCTF_IS_PREFIXED_KIND (kind))
        {
-       case CTF_K_INTEGER:
-       case CTF_K_FLOAT:
-         type_size += sizeof (uint32_t);
-         break;
-       case CTF_K_ARRAY:
-         type_size += sizeof (ctf_array_t);
-         break;
-       case CTF_K_SLICE:
-         type_size += sizeof (ctf_slice_t);
-         break;
-       case CTF_K_FUNCTION:
-         type_size += sizeof (uint32_t) * (vlen + (vlen & 1));
-         break;
-       case CTF_K_STRUCT:
-       case CTF_K_UNION:
-         if (type_ctt_size < CTF_LSTRUCT_THRESH)
-           type_size += sizeof (ctf_member_t) * vlen;
-         else
-           type_size += sizeof (ctf_lmember_t) * vlen;
-         break;
-       case CTF_K_ENUM:
-         type_size += sizeof (ctf_enum_t) * vlen;
-         break;
+         if ((kind != CTF_K_BIG) || tp->ctt_size != 0
+             || LCTF_INFO_UNPREFIXED_VLEN (fp, tp->ctt_info) != 0)
+           type_size += sizeof (ctf_type_t);
+         tp++;
        }
+      type_size += sizeof (ctf_type_t);
+      type_size += dtd->dtd_vlen_size;
     }
 
-  return type_size + fp->ctf_header->cth_stroff - fp->ctf_header->cth_typeoff;
+  return type_size + fp->ctf_header->btf.bth_type_len;
 }
 
 /* Take a final lap through the dynamic type definition list and copy the