aboutsummaryrefslogtreecommitdiff
path: root/libctf/ctf-create.c
diff options
context:
space:
mode:
Diffstat (limited to 'libctf/ctf-create.c')
-rw-r--r--libctf/ctf-create.c84
1 files changed, 57 insertions, 27 deletions
diff --git a/libctf/ctf-create.c b/libctf/ctf-create.c
index b2e0862..90db712 100644
--- a/libctf/ctf-create.c
+++ b/libctf/ctf-create.c
@@ -226,6 +226,7 @@ ctf_dtd_delete (ctf_dict_t *fp, ctf_dtdef_t *dtd)
const char *name;
ctf_dynhash_remove (fp->ctf_dthash, (void *) (uintptr_t) dtd->dtd_type);
+ free (dtd->dtd_vlen);
switch (kind)
{
@@ -406,7 +407,7 @@ ctf_rollback (ctf_dict_t *fp, ctf_snapshot_id_t id)
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;
@@ -425,33 +426,42 @@ ctf_add_generic (ctf_dict_t *fp, uint32_t flag, const char *name, int kind,
/* 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
@@ -477,6 +487,7 @@ ctf_add_encoded (ctf_dict_t *fp, uint32_t flag,
{
ctf_dtdef_t *dtd;
ctf_id_t type;
+ uint32_t encoding;
if (ep == NULL)
return (ctf_set_errno (fp, EINVAL));
@@ -484,13 +495,26 @@ ctf_add_encoded (ctf_dict_t *fp, uint32_t flag,
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;
}
@@ -509,7 +533,7 @@ ctf_add_reftype (ctf_dict_t *fp, uint32_t flag, ctf_id_t ref, uint32_t kind)
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);
@@ -539,6 +563,7 @@ ctf_add_slice (ctf_dict_t *fp, uint32_t flag, ctf_id_t ref,
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;
@@ -569,15 +594,19 @@ ctf_add_slice (ctf_dict_t *fp, uint32_t flag, ctf_id_t ref,
&& (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;
}
@@ -628,7 +657,8 @@ ctf_add_array (ctf_dict_t *fp, uint32_t flag, const ctf_arinfo_t *arp)
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);
@@ -700,7 +730,7 @@ ctf_add_function (ctf_dict_t *fp, uint32_t flag,
}
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. */
@@ -730,7 +760,7 @@ ctf_add_struct_sized (ctf_dict_t *fp, uint32_t flag, const char *name,
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);
@@ -767,7 +797,7 @@ ctf_add_union_sized (ctf_dict_t *fp, uint32_t flag, const char *name,
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);
@@ -803,7 +833,7 @@ ctf_add_enum (ctf_dict_t *fp, uint32_t flag, const char *name)
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);
@@ -861,7 +891,7 @@ ctf_add_forward (ctf_dict_t *fp, uint32_t flag, const char *name,
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);
@@ -887,7 +917,7 @@ ctf_add_typedef (ctf_dict_t *fp, uint32_t flag, const char *name,
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. */
@@ -1783,7 +1813,7 @@ ctf_add_type_internal (ctf_dict_t *dst_fp, ctf_dict_t *src_fp, ctf_id_t src_type
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. */