libctf: serialize: type section sizing

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.
This commit is contained in:
Nick Alcock
2025-04-25 14:17:36 +01:00
parent db98972145
commit 67cd167767

View File

@@ -915,60 +915,57 @@ static size_t
ctf_type_sect_size (ctf_dict_t *fp) ctf_type_sect_size (ctf_dict_t *fp)
{ {
ctf_dtdef_t *dtd; 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)) dtd != NULL; dtd = ctf_list_next (dtd))
{ {
uint32_t kind = LCTF_INFO_KIND (fp, dtd->dtd_data.ctt_info); uint32_t kind = LCTF_KIND (fp, dtd->dtd_buf);
uint32_t vlen = LCTF_INFO_VLEN (fp, dtd->dtd_data.ctt_info); ctf_type_t *tp = dtd->dtd_buf;
size_t type_ctt_size = dtd->dtd_data.ctt_size;
/* Shrink ctf_type_t-using types from a ctf_type_t to a ctf_stype_t /* Check for suppressions: a suppression consumes precisely one ctf_type_t
if possible. */ 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) while (kind = LCTF_INFO_UNPREFIXED_KIND (fp, tp->ctt_info),
type_ctt_size = lsize; LCTF_IS_PREFIXED_KIND (kind))
} {
if ((kind != CTF_K_BIG) || tp->ctt_size != 0
if (type_ctt_size != CTF_LSIZE_SENT) || LCTF_INFO_UNPREFIXED_VLEN (fp, tp->ctt_info) != 0)
type_size += sizeof (ctf_stype_t); if (ctf_dynset_lookup (fp->ctf_write_suppressions,
else (const void *) (uintptr_t) kind) != NULL)
{
type_size += sizeof (ctf_type_t); type_size += sizeof (ctf_type_t);
suppress = 1;
break;
}
switch (kind) tp++;
}
if (suppress)
continue;
}
/* Type headers: elide CTF_K_BIG from types if possible. Must match
corresponding elision in ctf_emit_type_sect. */
tp = dtd->dtd_buf;
while (kind = LCTF_INFO_UNPREFIXED_KIND (fp, tp->ctt_info),
LCTF_IS_PREFIXED_KIND (kind))
{ {
case CTF_K_INTEGER: if ((kind != CTF_K_BIG) || tp->ctt_size != 0
case CTF_K_FLOAT: || LCTF_INFO_UNPREFIXED_VLEN (fp, tp->ctt_info) != 0)
type_size += sizeof (uint32_t); type_size += sizeof (ctf_type_t);
break; tp++;
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;
} }
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 /* Take a final lap through the dynamic type definition list and copy the