const char *name;
ctf_dynhash_remove (fp->ctf_dthash, (void *) (uintptr_t) dtd->dtd_type);
+ free (dtd->dtd_vlen);
switch (kind)
{
static ctf_id_t
ctf_add_generic (ctf_dict_t *fp, uint32_t flag, const char *name, int kind,
- ctf_dtdef_t **rp)
+ size_t vlen, ctf_dtdef_t **rp)
{
ctf_dtdef_t *dtd;
ctf_id_t type;
/* Make sure ptrtab always grows to be big enough for all types. */
if (ctf_grow_ptrtab (fp) < 0)
- return CTF_ERR; /* errno is set for us. */
+ return CTF_ERR; /* errno is set for us. */
- if ((dtd = malloc (sizeof (ctf_dtdef_t))) == NULL)
+ if ((dtd = calloc (1, sizeof (ctf_dtdef_t))) == NULL)
return (ctf_set_errno (fp, EAGAIN));
+ if (vlen > 0)
+ {
+ if ((dtd->dtd_vlen = calloc (1, vlen)) == NULL)
+ goto oom;
+ }
+ else
+ dtd->dtd_vlen = NULL;
+
type = ++fp->ctf_typemax;
type = LCTF_INDEX_TO_TYPE (fp, type, (fp->ctf_flags & LCTF_CHILD));
- memset (dtd, 0, sizeof (ctf_dtdef_t));
dtd->dtd_data.ctt_name = ctf_str_add_ref (fp, name, &dtd->dtd_data.ctt_name);
dtd->dtd_type = type;
if (dtd->dtd_data.ctt_name == 0 && name != NULL && name[0] != '\0')
- {
- free (dtd);
- return (ctf_set_errno (fp, EAGAIN));
- }
+ goto oom;
if (ctf_dtd_insert (fp, dtd, flag, kind) < 0)
- {
- free (dtd);
- return CTF_ERR; /* errno is set for us. */
- }
+ goto err; /* errno is set for us. */
+
fp->ctf_flags |= LCTF_DIRTY;
*rp = dtd;
return type;
+
+ oom:
+ ctf_set_errno (fp, EAGAIN);
+ err:
+ free (dtd->dtd_vlen);
+ free (dtd);
+ return CTF_ERR;
}
/* When encoding integer sizes, we want to convert a byte count in the range
{
ctf_dtdef_t *dtd;
ctf_id_t type;
+ uint32_t encoding;
if (ep == NULL)
return (ctf_set_errno (fp, EINVAL));
if (name == NULL || name[0] == '\0')
return (ctf_set_errno (fp, ECTF_NONAME));
- if ((type = ctf_add_generic (fp, flag, name, kind, &dtd)) == CTF_ERR)
+ if (!ctf_assert (fp, kind == CTF_K_INTEGER || kind == CTF_K_FLOAT))
+ return -1; /* errno is set for us. */
+
+ if ((type = ctf_add_generic (fp, flag, name, kind, sizeof (uint32_t),
+ &dtd)) == CTF_ERR)
return CTF_ERR; /* errno is set for us. */
dtd->dtd_data.ctt_info = CTF_TYPE_INFO (kind, flag, 0);
dtd->dtd_data.ctt_size = clp2 (P2ROUNDUP (ep->cte_bits, CHAR_BIT)
/ CHAR_BIT);
- dtd->dtd_u.dtu_enc = *ep;
+ switch (kind)
+ {
+ case CTF_K_INTEGER:
+ encoding = CTF_INT_DATA (ep->cte_format, ep->cte_offset, ep->cte_bits);
+ break;
+ case CTF_K_FLOAT:
+ encoding = CTF_FP_DATA (ep->cte_format, ep->cte_offset, ep->cte_bits);
+ break;
+ }
+ memcpy (dtd->dtd_vlen, &encoding, sizeof (encoding));
return type;
}
if (ref != 0 && ctf_lookup_by_id (&tmp, ref) == NULL)
return CTF_ERR; /* errno is set for us. */
- if ((type = ctf_add_generic (fp, flag, NULL, kind, &dtd)) == CTF_ERR)
+ if ((type = ctf_add_generic (fp, flag, NULL, kind, 0, &dtd)) == CTF_ERR)
return CTF_ERR; /* errno is set for us. */
dtd->dtd_data.ctt_info = CTF_TYPE_INFO (kind, flag, 0);
const ctf_encoding_t *ep)
{
ctf_dtdef_t *dtd;
+ ctf_slice_t slice;
ctf_id_t resolved_ref = ref;
ctf_id_t type;
int kind;
&& (ref != 0))
return (ctf_set_errno (fp, ECTF_NOTINTFP));
- if ((type = ctf_add_generic (fp, flag, NULL, CTF_K_SLICE, &dtd)) == CTF_ERR)
+ if ((type = ctf_add_generic (fp, flag, NULL, CTF_K_SLICE,
+ sizeof (ctf_slice_t), &dtd)) == CTF_ERR)
return CTF_ERR; /* errno is set for us. */
+ memset (&slice, 0, sizeof (ctf_slice_t));
+
dtd->dtd_data.ctt_info = CTF_TYPE_INFO (CTF_K_SLICE, flag, 0);
dtd->dtd_data.ctt_size = clp2 (P2ROUNDUP (ep->cte_bits, CHAR_BIT)
/ CHAR_BIT);
- dtd->dtd_u.dtu_slice.cts_type = (uint32_t) ref;
- dtd->dtd_u.dtu_slice.cts_bits = ep->cte_bits;
- dtd->dtd_u.dtu_slice.cts_offset = ep->cte_offset;
+ slice.cts_type = (uint32_t) ref;
+ slice.cts_bits = ep->cte_bits;
+ slice.cts_offset = ep->cte_offset;
+ memcpy (dtd->dtd_vlen, &slice, sizeof (ctf_slice_t));
return type;
}
return (ctf_set_errno (fp, ECTF_INCOMPLETE));
}
- if ((type = ctf_add_generic (fp, flag, NULL, CTF_K_ARRAY, &dtd)) == CTF_ERR)
+ if ((type = ctf_add_generic (fp, flag, NULL, CTF_K_ARRAY,
+ 0, &dtd)) == CTF_ERR)
return CTF_ERR; /* errno is set for us. */
dtd->dtd_data.ctt_info = CTF_TYPE_INFO (CTF_K_ARRAY, flag, 0);
}
if ((type = ctf_add_generic (fp, flag, NULL, CTF_K_FUNCTION,
- &dtd)) == CTF_ERR)
+ 0, &dtd)) == CTF_ERR)
{
free (vdat);
return CTF_ERR; /* errno is set for us. */
if (type != 0 && ctf_type_kind (fp, type) == CTF_K_FORWARD)
dtd = ctf_dtd_lookup (fp, type);
else if ((type = ctf_add_generic (fp, flag, name, CTF_K_STRUCT,
- &dtd)) == CTF_ERR)
+ 0, &dtd)) == CTF_ERR)
return CTF_ERR; /* errno is set for us. */
dtd->dtd_data.ctt_info = CTF_TYPE_INFO (CTF_K_STRUCT, flag, 0);
if (type != 0 && ctf_type_kind (fp, type) == CTF_K_FORWARD)
dtd = ctf_dtd_lookup (fp, type);
else if ((type = ctf_add_generic (fp, flag, name, CTF_K_UNION,
- &dtd)) == CTF_ERR)
+ 0, &dtd)) == CTF_ERR)
return CTF_ERR; /* errno is set for us */
dtd->dtd_data.ctt_info = CTF_TYPE_INFO (CTF_K_UNION, flag, 0);
if (type != 0 && ctf_type_kind (fp, type) == CTF_K_FORWARD)
dtd = ctf_dtd_lookup (fp, type);
else if ((type = ctf_add_generic (fp, flag, name, CTF_K_ENUM,
- &dtd)) == CTF_ERR)
+ 0, &dtd)) == CTF_ERR)
return CTF_ERR; /* errno is set for us. */
dtd->dtd_data.ctt_info = CTF_TYPE_INFO (CTF_K_ENUM, flag, 0);
if (type)
return type;
- if ((type = ctf_add_generic (fp, flag, name, kind, &dtd)) == CTF_ERR)
+ if ((type = ctf_add_generic (fp, flag, name, kind, 0, &dtd)) == CTF_ERR)
return CTF_ERR; /* errno is set for us. */
dtd->dtd_data.ctt_info = CTF_TYPE_INFO (CTF_K_FORWARD, flag, 0);
if (ref != 0 && ctf_lookup_by_id (&tmp, ref) == NULL)
return CTF_ERR; /* errno is set for us. */
- if ((type = ctf_add_generic (fp, flag, name, CTF_K_TYPEDEF,
+ if ((type = ctf_add_generic (fp, flag, name, CTF_K_TYPEDEF, 0,
&dtd)) == CTF_ERR)
return CTF_ERR; /* errno is set for us. */
manually so as to avoid repeated lookups in ctf_add_member
and to ensure the exact same member offsets as in src_type. */
- dst_type = ctf_add_generic (dst_fp, flag, name, kind, &dtd);
+ dst_type = ctf_add_generic (dst_fp, flag, name, kind, 0, &dtd);
if (dst_type == CTF_ERR)
return CTF_ERR; /* errno is set for us. */
sp = (const ctf_slice_t *) ((uintptr_t) tp + increment);
}
else
- sp = &dtd->dtd_u.dtu_slice;
+ sp = (const ctf_slice_t *) dtd->dtd_vlen;
return sp->cts_type;
}
ctf_dtdef_t *dtd;
const ctf_type_t *tp;
ssize_t increment;
+ const unsigned char *vlen;
uint32_t data;
if ((tp = ctf_lookup_by_id (&fp, type)) == NULL)
return -1; /* errno is set for us. */
if ((dtd = ctf_dynamic_type (ofp, type)) != NULL)
+ vlen = dtd->dtd_vlen;
+ else
{
- switch (LCTF_INFO_KIND (fp, tp->ctt_info))
- {
- case CTF_K_INTEGER:
- case CTF_K_FLOAT:
- *ep = dtd->dtd_u.dtu_enc;
- break;
- case CTF_K_SLICE:
- {
- 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);
-
- ep->cte_format = underlying_en.cte_format;
- ep->cte_offset = slice->cts_offset;
- ep->cte_bits = slice->cts_bits;
- break;
- }
- default:
- return (ctf_set_errno (ofp, ECTF_NOTINTFP));
- }
- return 0;
+ ctf_get_ctt_size (fp, tp, NULL, &increment);
+ vlen = (const unsigned char *) ((uintptr_t) tp + increment);
}
- (void) ctf_get_ctt_size (fp, tp, NULL, &increment);
-
switch (LCTF_INFO_KIND (fp, tp->ctt_info))
{
case CTF_K_INTEGER:
- data = *(const uint32_t *) ((uintptr_t) tp + increment);
+ data = *(const uint32_t *) vlen;
ep->cte_format = CTF_INT_ENCODING (data);
ep->cte_offset = CTF_INT_OFFSET (data);
ep->cte_bits = CTF_INT_BITS (data);
break;
case CTF_K_FLOAT:
- data = *(const uint32_t *) ((uintptr_t) tp + increment);
+ data = *(const uint32_t *) vlen;
ep->cte_format = CTF_FP_ENCODING (data);
ep->cte_offset = CTF_FP_OFFSET (data);
ep->cte_bits = CTF_FP_BITS (data);
ctf_encoding_t underlying_en;
ctf_id_t underlying;
- slice = (ctf_slice_t *) ((uintptr_t) tp + increment);
+ slice = (ctf_slice_t *) vlen;
underlying = ctf_type_resolve (fp, slice->cts_type);
- data = ctf_type_encoding (fp, underlying, &underlying_en);
+ if (ctf_type_encoding (fp, underlying, &underlying_en) < 0)
+ return -1; /* errno is set for us. */
ep->cte_format = underlying_en.cte_format;
ep->cte_offset = slice->cts_offset;