git: 105d1ae9041f - releng/13.1 - ctf: Add v3 support to CTF tools, ctf{convert,dump,merge}
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Mon, 18 Apr 2022 16:39:31 UTC
The branch releng/13.1 has been updated by markj:
URL: https://cgit.FreeBSD.org/src/commit/?id=105d1ae9041ff139c6db2f00eb4dd7441d47305f
commit 105d1ae9041ff139c6db2f00eb4dd7441d47305f
Author: Mark Johnston <markj@FreeBSD.org>
AuthorDate: 2022-03-07 13:54:18 +0000
Commit: Mark Johnston <markj@FreeBSD.org>
CommitDate: 2022-04-18 16:38:45 +0000
ctf: Add v3 support to CTF tools, ctf{convert,dump,merge}
ctfdump handles v2 and v3. ctfconvert now emits only CTFv3, whereas
ctfmerge can merge v2 and v3 containers into v3 containers.
Approved by: re (gjb)
Sponsored by: The FreeBSD Foundation
(cherry picked from commit bdf290cd3e1a69d41c2f8bb60bd415cfa78adba2)
(cherry picked from commit e5b54808f735f1a74716f1320916b8a961ddf92d)
---
cddl/contrib/opensolaris/tools/ctf/cvt/ctf.c | 453 ++++++++++++++--------
cddl/contrib/opensolaris/tools/ctf/cvt/ctfmerge.c | 4 +-
cddl/contrib/opensolaris/tools/ctf/dump/dump.c | 286 +++++++++-----
sys/sys/ctf.h | 2 +-
4 files changed, 473 insertions(+), 272 deletions(-)
diff --git a/cddl/contrib/opensolaris/tools/ctf/cvt/ctf.c b/cddl/contrib/opensolaris/tools/ctf/cvt/ctf.c
index 5cd2de9f43ea..b3b4c1f7168f 100644
--- a/cddl/contrib/opensolaris/tools/ctf/cvt/ctf.c
+++ b/cddl/contrib/opensolaris/tools/ctf/cvt/ctf.c
@@ -58,8 +58,7 @@ struct ctf_buf {
caddr_t ctb_end; /* pointer to end of buffer */
caddr_t ctb_ptr; /* pointer to empty buffer space */
size_t ctb_size; /* size of buffer */
- int nptent; /* number of processed types */
- int ntholes; /* number of type holes */
+ uint_t nptent; /* number of processed types */
};
/*
@@ -165,10 +164,10 @@ write_label(void *arg1, void *arg2)
static void
write_objects(iidesc_t *idp, ctf_buf_t *b)
{
- ushort_t id = (idp ? idp->ii_dtype->t_id : 0);
+ uint_t id = (idp ? idp->ii_dtype->t_id : 0);
if (target_requires_swap) {
- SWAP_16(id);
+ SWAP_32(id);
}
ctf_buf_write(b, &id, sizeof (id));
@@ -179,8 +178,8 @@ write_objects(iidesc_t *idp, ctf_buf_t *b)
static void
write_functions(iidesc_t *idp, ctf_buf_t *b)
{
- ushort_t fdata[2];
- ushort_t id;
+ uint_t fdata[2];
+ uint_t id;
int nargs;
int i;
@@ -194,17 +193,17 @@ write_functions(iidesc_t *idp, ctf_buf_t *b)
nargs = idp->ii_nargs + (idp->ii_vargs != 0);
- if (nargs > CTF_MAX_VLEN) {
+ if (nargs > CTF_V3_MAX_VLEN) {
terminate("function %s has too many args: %d > %d\n",
- idp->ii_name, nargs, CTF_MAX_VLEN);
+ idp->ii_name, nargs, CTF_V3_MAX_VLEN);
}
- fdata[0] = CTF_TYPE_INFO(CTF_K_FUNCTION, 1, nargs);
+ fdata[0] = CTF_V3_TYPE_INFO(CTF_K_FUNCTION, 1, nargs);
fdata[1] = idp->ii_dtype->t_id;
if (target_requires_swap) {
- SWAP_16(fdata[0]);
- SWAP_16(fdata[1]);
+ SWAP_32(fdata[0]);
+ SWAP_32(fdata[1]);
}
ctf_buf_write(b, fdata, sizeof (fdata));
@@ -213,7 +212,7 @@ write_functions(iidesc_t *idp, ctf_buf_t *b)
id = idp->ii_args[i]->t_id;
if (target_requires_swap) {
- SWAP_16(id);
+ SWAP_32(id);
}
ctf_buf_write(b, &id, sizeof (id));
@@ -234,29 +233,29 @@ write_functions(iidesc_t *idp, ctf_buf_t *b)
* doesn't need to care.
*/
static void
-write_sized_type_rec(ctf_buf_t *b, ctf_type_t *ctt, size_t size)
+write_sized_type_rec(ctf_buf_t *b, struct ctf_type_v3 *ctt, size_t size)
{
- if (size > CTF_MAX_SIZE) {
- ctt->ctt_size = CTF_LSIZE_SENT;
+ if (size > CTF_V3_MAX_SIZE) {
+ ctt->ctt_size = CTF_V3_LSIZE_SENT;
ctt->ctt_lsizehi = CTF_SIZE_TO_LSIZE_HI(size);
ctt->ctt_lsizelo = CTF_SIZE_TO_LSIZE_LO(size);
if (target_requires_swap) {
SWAP_32(ctt->ctt_name);
- SWAP_16(ctt->ctt_info);
- SWAP_16(ctt->ctt_size);
+ SWAP_32(ctt->ctt_info);
+ SWAP_32(ctt->ctt_size);
SWAP_32(ctt->ctt_lsizehi);
SWAP_32(ctt->ctt_lsizelo);
}
ctf_buf_write(b, ctt, sizeof (*ctt));
} else {
- ctf_stype_t *cts = (ctf_stype_t *)ctt;
+ struct ctf_stype_v3 *cts = (struct ctf_stype_v3 *)ctt;
- cts->ctt_size = (ushort_t)size;
+ cts->ctt_size = size;
if (target_requires_swap) {
SWAP_32(cts->ctt_name);
- SWAP_16(cts->ctt_info);
- SWAP_16(cts->ctt_size);
+ SWAP_32(cts->ctt_info);
+ SWAP_32(cts->ctt_size);
}
ctf_buf_write(b, cts, sizeof (*cts));
@@ -264,14 +263,14 @@ write_sized_type_rec(ctf_buf_t *b, ctf_type_t *ctt, size_t size)
}
static void
-write_unsized_type_rec(ctf_buf_t *b, ctf_type_t *ctt)
+write_unsized_type_rec(ctf_buf_t *b, struct ctf_type_v3 *ctt)
{
- ctf_stype_t *cts = (ctf_stype_t *)ctt;
+ struct ctf_stype_v3 *cts = (struct ctf_stype_v3 *)ctt;
if (target_requires_swap) {
SWAP_32(cts->ctt_name);
- SWAP_16(cts->ctt_info);
- SWAP_16(cts->ctt_size);
+ SWAP_32(cts->ctt_info);
+ SWAP_32(cts->ctt_size);
}
ctf_buf_write(b, cts, sizeof (*cts));
@@ -292,14 +291,12 @@ write_type(void *arg1, void *arg2)
int isroot = tp->t_flags & TDESC_F_ISROOT;
int i;
- ctf_type_t ctt;
- ctf_array_t cta;
- ctf_member_t ctm;
- ctf_lmember_t ctlm;
- ctf_enum_t cte;
- ushort_t id;
-
- ctlm.ctlm_pad = 0;
+ struct ctf_type_v3 ctt;
+ struct ctf_array_v3 cta;
+ struct ctf_member_v3 ctm;
+ struct ctf_lmember_v3 ctlm;
+ struct ctf_enum cte;
+ uint_t id;
/*
* There shouldn't be any holes in the type list (where a hole is
@@ -308,13 +305,13 @@ write_type(void *arg1, void *arg2)
* fake entries to fill the holes, or we won't be able to reconstruct
* the tree from the written data.
*/
- if (++b->nptent < CTF_TYPE_TO_INDEX(tp->t_id)) {
+ if (++b->nptent < CTF_V3_TYPE_TO_INDEX(tp->t_id)) {
debug(2, "genctf: type hole from %d < x < %d\n",
- b->nptent - 1, CTF_TYPE_TO_INDEX(tp->t_id));
+ b->nptent - 1, CTF_V3_TYPE_TO_INDEX(tp->t_id));
ctt.ctt_name = CTF_TYPE_NAME(CTF_STRTAB_0, 0);
- ctt.ctt_info = CTF_TYPE_INFO(0, 0, 0);
- while (b->nptent < CTF_TYPE_TO_INDEX(tp->t_id)) {
+ ctt.ctt_info = CTF_V3_TYPE_INFO(0, 0, 0);
+ while (b->nptent < CTF_V3_TYPE_TO_INDEX(tp->t_id)) {
write_sized_type_rec(b, &ctt, 0);
b->nptent++;
}
@@ -327,10 +324,10 @@ write_type(void *arg1, void *arg2)
case INTRINSIC:
ip = tp->t_intr;
if (ip->intr_type == INTR_INT)
- ctt.ctt_info = CTF_TYPE_INFO(CTF_K_INTEGER,
+ ctt.ctt_info = CTF_V3_TYPE_INFO(CTF_K_INTEGER,
isroot, 1);
else
- ctt.ctt_info = CTF_TYPE_INFO(CTF_K_FLOAT, isroot, 1);
+ ctt.ctt_info = CTF_V3_TYPE_INFO(CTF_K_FLOAT, isroot, 1);
write_sized_type_rec(b, &ctt, tp->t_size);
encoding = 0;
@@ -355,21 +352,21 @@ write_type(void *arg1, void *arg2)
break;
case POINTER:
- ctt.ctt_info = CTF_TYPE_INFO(CTF_K_POINTER, isroot, 0);
+ ctt.ctt_info = CTF_V3_TYPE_INFO(CTF_K_POINTER, isroot, 0);
ctt.ctt_type = tp->t_tdesc->t_id;
write_unsized_type_rec(b, &ctt);
break;
case ARRAY:
- ctt.ctt_info = CTF_TYPE_INFO(CTF_K_ARRAY, isroot, 1);
+ ctt.ctt_info = CTF_V3_TYPE_INFO(CTF_K_ARRAY, isroot, 1);
write_sized_type_rec(b, &ctt, tp->t_size);
cta.cta_contents = tp->t_ardef->ad_contents->t_id;
cta.cta_index = tp->t_ardef->ad_idxtype->t_id;
cta.cta_nelems = tp->t_ardef->ad_nelems;
if (target_requires_swap) {
- SWAP_16(cta.cta_contents);
- SWAP_16(cta.cta_index);
+ SWAP_32(cta.cta_contents);
+ SWAP_32(cta.cta_index);
SWAP_32(cta.cta_nelems);
}
ctf_buf_write(b, &cta, sizeof (cta));
@@ -380,19 +377,19 @@ write_type(void *arg1, void *arg2)
for (i = 0, mp = tp->t_members; mp != NULL; mp = mp->ml_next)
i++; /* count up struct or union members */
- if (i > CTF_MAX_VLEN) {
+ if (i > CTF_V3_MAX_VLEN) {
terminate("sou %s has too many members: %d > %d\n",
- tdesc_name(tp), i, CTF_MAX_VLEN);
+ tdesc_name(tp), i, CTF_V3_MAX_VLEN);
}
if (tp->t_type == STRUCT)
- ctt.ctt_info = CTF_TYPE_INFO(CTF_K_STRUCT, isroot, i);
+ ctt.ctt_info = CTF_V3_TYPE_INFO(CTF_K_STRUCT, isroot, i);
else
- ctt.ctt_info = CTF_TYPE_INFO(CTF_K_UNION, isroot, i);
+ ctt.ctt_info = CTF_V3_TYPE_INFO(CTF_K_UNION, isroot, i);
write_sized_type_rec(b, &ctt, tp->t_size);
- if (tp->t_size < CTF_LSTRUCT_THRESH) {
+ if (tp->t_size < CTF_V3_LSTRUCT_THRESH) {
for (mp = tp->t_members; mp != NULL; mp = mp->ml_next) {
offset = strtab_insert(&b->ctb_strtab,
mp->ml_name);
@@ -403,8 +400,8 @@ write_type(void *arg1, void *arg2)
ctm.ctm_offset = mp->ml_offset;
if (target_requires_swap) {
SWAP_32(ctm.ctm_name);
- SWAP_16(ctm.ctm_type);
- SWAP_16(ctm.ctm_offset);
+ SWAP_32(ctm.ctm_type);
+ SWAP_32(ctm.ctm_offset);
}
ctf_buf_write(b, &ctm, sizeof (ctm));
}
@@ -423,7 +420,7 @@ write_type(void *arg1, void *arg2)
if (target_requires_swap) {
SWAP_32(ctlm.ctlm_name);
- SWAP_16(ctlm.ctlm_type);
+ SWAP_32(ctlm.ctlm_type);
SWAP_32(ctlm.ctlm_offsethi);
SWAP_32(ctlm.ctlm_offsetlo);
}
@@ -437,11 +434,11 @@ write_type(void *arg1, void *arg2)
for (i = 0, ep = tp->t_emem; ep != NULL; ep = ep->el_next)
i++; /* count up enum members */
- if (i > CTF_MAX_VLEN) {
- i = CTF_MAX_VLEN;
+ if (i > CTF_V3_MAX_VLEN) {
+ i = CTF_V3_MAX_VLEN;
}
- ctt.ctt_info = CTF_TYPE_INFO(CTF_K_ENUM, isroot, i);
+ ctt.ctt_info = CTF_V3_TYPE_INFO(CTF_K_ENUM, isroot, i);
write_sized_type_rec(b, &ctt, tp->t_size);
for (ep = tp->t_emem; ep != NULL && i > 0; ep = ep->el_next) {
@@ -460,25 +457,25 @@ write_type(void *arg1, void *arg2)
break;
case FORWARD:
- ctt.ctt_info = CTF_TYPE_INFO(CTF_K_FORWARD, isroot, 0);
+ ctt.ctt_info = CTF_V3_TYPE_INFO(CTF_K_FORWARD, isroot, 0);
ctt.ctt_type = 0;
write_unsized_type_rec(b, &ctt);
break;
case TYPEDEF:
- ctt.ctt_info = CTF_TYPE_INFO(CTF_K_TYPEDEF, isroot, 0);
+ ctt.ctt_info = CTF_V3_TYPE_INFO(CTF_K_TYPEDEF, isroot, 0);
ctt.ctt_type = tp->t_tdesc->t_id;
write_unsized_type_rec(b, &ctt);
break;
case VOLATILE:
- ctt.ctt_info = CTF_TYPE_INFO(CTF_K_VOLATILE, isroot, 0);
+ ctt.ctt_info = CTF_V3_TYPE_INFO(CTF_K_VOLATILE, isroot, 0);
ctt.ctt_type = tp->t_tdesc->t_id;
write_unsized_type_rec(b, &ctt);
break;
case CONST:
- ctt.ctt_info = CTF_TYPE_INFO(CTF_K_CONST, isroot, 0);
+ ctt.ctt_info = CTF_V3_TYPE_INFO(CTF_K_CONST, isroot, 0);
ctt.ctt_type = tp->t_tdesc->t_id;
write_unsized_type_rec(b, &ctt);
break;
@@ -486,12 +483,12 @@ write_type(void *arg1, void *arg2)
case FUNCTION:
i = tp->t_fndef->fn_nargs + tp->t_fndef->fn_vargs;
- if (i > CTF_MAX_VLEN) {
+ if (i > CTF_V3_MAX_VLEN) {
terminate("function %s has too many args: %d > %d\n",
- tdesc_name(tp), i, CTF_MAX_VLEN);
+ tdesc_name(tp), i, CTF_V3_MAX_VLEN);
}
- ctt.ctt_info = CTF_TYPE_INFO(CTF_K_FUNCTION, isroot, i);
+ ctt.ctt_info = CTF_V3_TYPE_INFO(CTF_K_FUNCTION, isroot, i);
ctt.ctt_type = tp->t_fndef->fn_ret->t_id;
write_unsized_type_rec(b, &ctt);
@@ -499,7 +496,7 @@ write_type(void *arg1, void *arg2)
id = tp->t_fndef->fn_args[i]->t_id;
if (target_requires_swap) {
- SWAP_16(id);
+ SWAP_32(id);
}
ctf_buf_write(b, &id, sizeof (id));
@@ -511,14 +508,10 @@ write_type(void *arg1, void *arg2)
i++;
}
- if (i & 1) {
- id = 0;
- ctf_buf_write(b, &id, sizeof (id));
- }
break;
case RESTRICT:
- ctt.ctt_info = CTF_TYPE_INFO(CTF_K_RESTRICT, isroot, 0);
+ ctt.ctt_info = CTF_V3_TYPE_INFO(CTF_K_RESTRICT, isroot, 0);
ctt.ctt_type = tp->t_tdesc->t_id;
write_unsized_type_rec(b, &ctt);
break;
@@ -704,7 +697,7 @@ ctf_gen(iiburst_t *iiburst, size_t *resszp, int do_compress)
* integers; we pad these out to the next 4-byte boundary if needed.
*/
h.cth_magic = CTF_MAGIC;
- h.cth_version = CTF_VERSION;
+ h.cth_version = CTF_VERSION_3;
h.cth_flags = do_compress ? CTF_F_COMPRESS : 0;
h.cth_parlabel = strtab_insert(&buf->ctb_strtab,
iiburst->iib_td->td_parlabel);
@@ -761,14 +754,46 @@ ctf_gen(iiburst_t *iiburst, size_t *resszp, int do_compress)
}
static void
-get_ctt_size(ctf_type_t *ctt, size_t *sizep, size_t *incrementp)
+get_ctt_info(ctf_header_t *h, void *v, uint_t *kind, uint_t *vlen, int *isroot)
+{
+ if (h->cth_version == CTF_VERSION_2) {
+ struct ctf_type_v2 *ctt = v;
+
+ *kind = CTF_V2_INFO_KIND(ctt->ctt_info);
+ *vlen = CTF_V2_INFO_VLEN(ctt->ctt_info);
+ *isroot = CTF_V2_INFO_ISROOT(ctt->ctt_info);
+ } else {
+ struct ctf_type_v3 *ctt = v;
+
+ *kind = CTF_V3_INFO_KIND(ctt->ctt_info);
+ *vlen = CTF_V3_INFO_VLEN(ctt->ctt_info);
+ *isroot = CTF_V3_INFO_ISROOT(ctt->ctt_info);
+ }
+}
+
+static void
+get_ctt_size(ctf_header_t *h, void *v, size_t *sizep, size_t *incrementp)
{
- if (ctt->ctt_size == CTF_LSIZE_SENT) {
- *sizep = (size_t)CTF_TYPE_LSIZE(ctt);
- *incrementp = sizeof (ctf_type_t);
+ if (h->cth_version == CTF_VERSION_2) {
+ struct ctf_type_v2 *ctt = v;
+
+ if (ctt->ctt_size == CTF_V2_LSIZE_SENT) {
+ *sizep = (size_t)CTF_TYPE_LSIZE(ctt);
+ *incrementp = sizeof (struct ctf_type_v2);
+ } else {
+ *sizep = ctt->ctt_size;
+ *incrementp = sizeof (struct ctf_stype_v2);
+ }
} else {
- *sizep = ctt->ctt_size;
- *incrementp = sizeof (ctf_stype_t);
+ struct ctf_type_v3 *ctt = v;
+
+ if (ctt->ctt_size == CTF_V3_LSIZE_SENT) {
+ *sizep = (size_t)CTF_TYPE_LSIZE(ctt);
+ *incrementp = sizeof (struct ctf_type_v3);
+ } else {
+ *sizep = ctt->ctt_size;
+ *incrementp = sizeof (struct ctf_stype_v3);
+ }
}
}
@@ -776,18 +801,22 @@ static int
count_types(ctf_header_t *h, caddr_t data)
{
caddr_t dptr = data + h->cth_typeoff;
+ uint_t version = h->cth_version;
+ size_t idwidth;
int count = 0;
+ idwidth = version == CTF_VERSION_2 ? 2 : 4;
dptr = data + h->cth_typeoff;
while (dptr < data + h->cth_stroff) {
void *v = (void *) dptr;
- ctf_type_t *ctt = v;
- size_t vlen = CTF_INFO_VLEN(ctt->ctt_info);
size_t size, increment;
+ uint_t vlen, kind;
+ int isroot;
- get_ctt_size(ctt, &size, &increment);
+ get_ctt_info(h, v, &kind, &vlen, &isroot);
+ get_ctt_size(h, v, &size, &increment);
- switch (CTF_INFO_KIND(ctt->ctt_info)) {
+ switch (kind) {
case CTF_K_INTEGER:
case CTF_K_FLOAT:
dptr += 4;
@@ -799,17 +828,31 @@ count_types(ctf_header_t *h, caddr_t data)
case CTF_K_CONST:
case CTF_K_RESTRICT:
case CTF_K_FUNCTION:
- dptr += sizeof (ushort_t) * (vlen + (vlen & 1));
+ dptr += idwidth * vlen;
break;
case CTF_K_ARRAY:
- dptr += sizeof (ctf_array_t);
+ if (version == CTF_VERSION_2)
+ dptr += sizeof (struct ctf_array_v2);
+ else
+ dptr += sizeof (struct ctf_array_v3);
break;
case CTF_K_STRUCT:
case CTF_K_UNION:
- if (size < CTF_LSTRUCT_THRESH)
- dptr += sizeof (ctf_member_t) * vlen;
- else
- dptr += sizeof (ctf_lmember_t) * vlen;
+ if (version == CTF_VERSION_2) {
+ if (size < CTF_V2_LSTRUCT_THRESH)
+ dptr += sizeof (struct ctf_member_v2) *
+ vlen;
+ else
+ dptr += sizeof (struct ctf_lmember_v2) *
+ vlen;
+ } else {
+ if (size < CTF_V3_LSTRUCT_THRESH)
+ dptr += sizeof (struct ctf_member_v3) *
+ vlen;
+ else
+ dptr += sizeof (struct ctf_lmember_v3) *
+ vlen;
+ }
break;
case CTF_K_ENUM:
dptr += sizeof (ctf_enum_t) * vlen;
@@ -818,7 +861,7 @@ count_types(ctf_header_t *h, caddr_t data)
break;
default:
parseterminate("Unknown CTF type %d (#%d) at %#x",
- CTF_INFO_KIND(ctt->ctt_info), count, dptr - data);
+ kind, count, dptr - data);
}
dptr += increment;
@@ -895,11 +938,15 @@ resurrect_objects(ctf_header_t *h, tdata_t *td, tdesc_t **tdarr, int tdsize,
caddr_t buf = ctfdata + h->cth_objtoff;
size_t bufsz = h->cth_funcoff - h->cth_objtoff;
caddr_t dptr;
+ size_t idwidth;
+
+ idwidth = h->cth_version == CTF_VERSION_2 ? 2 : 4;
symit_reset(si);
- for (dptr = buf; dptr < buf + bufsz; dptr += 2) {
- void *v = (void *) dptr;
- ushort_t id = *((ushort_t *)v);
+ for (dptr = buf; dptr < buf + bufsz; dptr += idwidth) {
+ uint32_t id = 0;
+
+ memcpy(&id, (void *) dptr, idwidth);
iidesc_t *ii;
GElf_Sym *sym;
@@ -912,7 +959,7 @@ resurrect_objects(ctf_header_t *h, tdata_t *td, tdesc_t **tdarr, int tdsize,
if (id == 0) {
debug(3, "Skipping null object\n");
continue;
- } else if (id >= tdsize) {
+ } else if (id >= (uint_t)tdsize) {
parseterminate("Reference to invalid type %d", id);
}
@@ -937,18 +984,21 @@ resurrect_functions(ctf_header_t *h, tdata_t *td, tdesc_t **tdarr, int tdsize,
{
caddr_t buf = ctfdata + h->cth_funcoff;
size_t bufsz = h->cth_typeoff - h->cth_funcoff;
+ size_t idwidth;
caddr_t dptr = buf;
iidesc_t *ii;
- ushort_t info;
- ushort_t retid;
GElf_Sym *sym;
int i;
+ idwidth = h->cth_version == CTF_VERSION_2 ? 2 : 4;
+
symit_reset(si);
while (dptr < buf + bufsz) {
- void *v = (void *) dptr;
- info = *((ushort_t *)v);
- dptr += 2;
+ uint32_t id, info, retid;
+
+ info = 0;
+ memcpy(&info, (void *) dptr, idwidth);
+ dptr += idwidth;
if (!(sym = symit_next(si, STT_FUNC)) && info != 0)
parseterminate("Unexpected end of function symbols");
@@ -959,11 +1009,11 @@ resurrect_functions(ctf_header_t *h, tdata_t *td, tdesc_t **tdarr, int tdsize,
continue;
}
- v = (void *) dptr;
- retid = *((ushort_t *)v);
- dptr += 2;
+ retid = 0;
+ memcpy(&retid, (void *) dptr, idwidth);
+ dptr += idwidth;
- if (retid >= tdsize)
+ if (retid >= (uint_t)tdsize)
parseterminate("Reference to invalid type %d", retid);
ii = iidesc_new(symit_name(si));
@@ -973,15 +1023,18 @@ resurrect_functions(ctf_header_t *h, tdata_t *td, tdesc_t **tdarr, int tdsize,
ii->ii_owner = xstrdup(symit_curfile(si));
} else
ii->ii_type = II_GFUN;
- ii->ii_nargs = CTF_INFO_VLEN(info);
+ if (h->cth_version == CTF_VERSION_2)
+ ii->ii_nargs = CTF_V2_INFO_VLEN(info);
+ else
+ ii->ii_nargs = CTF_V3_INFO_VLEN(info);
if (ii->ii_nargs)
ii->ii_args =
xmalloc(sizeof (tdesc_t *) * ii->ii_nargs);
- for (i = 0; i < ii->ii_nargs; i++, dptr += 2) {
- v = (void *) dptr;
- ushort_t id = *((ushort_t *)v);
- if (id >= tdsize)
+ for (i = 0; i < ii->ii_nargs; i++, dptr += idwidth) {
+ id = 0;
+ memcpy(&id, (void *) dptr, idwidth);
+ if (id >= (uint_t)tdsize)
parseterminate("Reference to invalid type %d",
id);
ii->ii_args[i] = tdarr[id];
@@ -1011,55 +1064,65 @@ resurrect_types(ctf_header_t *h, tdata_t *td, tdesc_t **tdarr, int tdsize,
tdesc_t *tdp;
uint_t data;
uint_t encoding;
- size_t size, increment;
+ size_t idwidth, size, increment;
int tcnt;
int iicnt = 0;
tid_t tid, argid;
- int kind, vlen;
- int i;
+ int isroot, kind, vlen;
+ int i, version;
elist_t **epp;
mlist_t **mpp;
intr_t *ip;
- ctf_type_t *ctt;
- ctf_array_t *cta;
- ctf_enum_t *cte;
+ version = h->cth_version;
+ idwidth = version == CTF_VERSION_2 ? 2 : 4;
/*
* A maxid of zero indicates a request to resurrect all types, so reset
* maxid to the maximum type id.
*/
- if (maxid == 0)
- maxid = CTF_MAX_TYPE;
+ if (maxid == 0) {
+ maxid = version == CTF_VERSION_2 ?
+ CTF_V2_MAX_TYPE : CTF_V3_MAX_TYPE;
+ }
for (dptr = buf, tcnt = 0, tid = 1; dptr < buf + bufsz; tcnt++, tid++) {
+ ctf_enum_t *cte;
+ uint_t name, type;
+ void *v;
+
if (tid > maxid)
break;
if (tid >= tdsize)
parseterminate("Reference to invalid type %d", tid);
- void *v = (void *) dptr;
- ctt = v;
+ get_ctt_info(h, dptr, &kind, &vlen, &isroot);
+ get_ctt_size(h, dptr, &size, &increment);
+ if (version == CTF_VERSION_2) {
+ struct ctf_type_v2 *ctt = (void *) dptr;
- get_ctt_size(ctt, &size, &increment);
+ name = ctt->ctt_name;
+ type = ctt->ctt_type;
+ } else {
+ struct ctf_type_v3 *ctt = (void *) dptr;
+
+ name = ctt->ctt_name;
+ type = ctt->ctt_type;
+ }
dptr += increment;
tdp = tdarr[tid];
- if (CTF_NAME_STID(ctt->ctt_name) != CTF_STRTAB_0)
+ if (CTF_NAME_STID(name) != CTF_STRTAB_0)
parseterminate(
"Unable to cope with non-zero strtab id");
- if (CTF_NAME_OFFSET(ctt->ctt_name) != 0) {
- tdp->t_name =
- xstrdup(sbuf + CTF_NAME_OFFSET(ctt->ctt_name));
+ if (CTF_NAME_OFFSET(name) != 0) {
+ tdp->t_name = xstrdup(sbuf + CTF_NAME_OFFSET(name));
} else
tdp->t_name = NULL;
- kind = CTF_INFO_KIND(ctt->ctt_info);
- vlen = CTF_INFO_VLEN(ctt->ctt_info);
-
switch (kind) {
case CTF_K_INTEGER:
tdp->t_type = INTRINSIC;
@@ -1106,62 +1169,110 @@ resurrect_types(ctf_header_t *h, tdata_t *td, tdesc_t **tdarr, int tdsize,
case CTF_K_POINTER:
tdp->t_type = POINTER;
- tdp->t_tdesc = tdarr[ctt->ctt_type];
+ tdp->t_tdesc = tdarr[type];
break;
- case CTF_K_ARRAY:
+ case CTF_K_ARRAY: {
+ uint_t contents, index, nelems;
+
tdp->t_type = ARRAY;
tdp->t_size = size;
- v = (void *) dptr;
- cta = v;
- dptr += sizeof (ctf_array_t);
+ if (version == CTF_VERSION_2) {
+ struct ctf_array_v2 *cta = (void *) dptr;
+ contents = cta->cta_contents;
+ index = cta->cta_index;
+ nelems = cta->cta_nelems;
+ dptr += sizeof (*cta);
+ } else {
+ struct ctf_array_v3 *cta = (void *) dptr;
+ contents = cta->cta_contents;
+ index = cta->cta_index;
+ nelems = cta->cta_nelems;
+ dptr += sizeof (*cta);
+ }
tdp->t_ardef = xmalloc(sizeof (ardef_t));
- tdp->t_ardef->ad_contents = tdarr[cta->cta_contents];
- tdp->t_ardef->ad_idxtype = tdarr[cta->cta_index];
- tdp->t_ardef->ad_nelems = cta->cta_nelems;
+ tdp->t_ardef->ad_contents = tdarr[contents];
+ tdp->t_ardef->ad_idxtype = tdarr[index];
+ tdp->t_ardef->ad_nelems = nelems;
break;
+ }
case CTF_K_STRUCT:
- case CTF_K_UNION:
+ case CTF_K_UNION: {
tdp->t_type = (kind == CTF_K_STRUCT ? STRUCT : UNION);
tdp->t_size = size;
- if (size < CTF_LSTRUCT_THRESH) {
- for (i = 0, mpp = &tdp->t_members; i < vlen;
- i++, mpp = &((*mpp)->ml_next)) {
- v = (void *) dptr;
- ctf_member_t *ctm = v;
- dptr += sizeof (ctf_member_t);
-
- *mpp = xmalloc(sizeof (mlist_t));
- (*mpp)->ml_name = xstrdup(sbuf +
- ctm->ctm_name);
- (*mpp)->ml_type = tdarr[ctm->ctm_type];
- (*mpp)->ml_offset = ctm->ctm_offset;
- (*mpp)->ml_size = 0;
+ if (version == CTF_VERSION_2) {
+ if (size < CTF_V2_LSTRUCT_THRESH) {
+ for (i = 0, mpp = &tdp->t_members; i < vlen;
+ i++, mpp = &((*mpp)->ml_next)) {
+ v = (void *) dptr;
+ struct ctf_member_v2 *ctm = v;
+ dptr += sizeof (struct ctf_member_v2);
+
+ *mpp = xmalloc(sizeof (mlist_t));
+ (*mpp)->ml_name = xstrdup(sbuf +
+ ctm->ctm_name);
+ (*mpp)->ml_type = tdarr[ctm->ctm_type];
+ (*mpp)->ml_offset = ctm->ctm_offset;
+ (*mpp)->ml_size = 0;
+ }
+ } else {
+ for (i = 0, mpp = &tdp->t_members; i < vlen;
+ i++, mpp = &((*mpp)->ml_next)) {
+ v = (void *) dptr;
+ struct ctf_lmember_v2 *ctlm = v;
+ dptr += sizeof (struct ctf_lmember_v2);
+
+ *mpp = xmalloc(sizeof (mlist_t));
+ (*mpp)->ml_name = xstrdup(sbuf +
+ ctlm->ctlm_name);
+ (*mpp)->ml_type =
+ tdarr[ctlm->ctlm_type];
+ (*mpp)->ml_offset =
+ (int)CTF_LMEM_OFFSET(ctlm);
+ (*mpp)->ml_size = 0;
+ }
}
} else {
- for (i = 0, mpp = &tdp->t_members; i < vlen;
- i++, mpp = &((*mpp)->ml_next)) {
- v = (void *) dptr;
- ctf_lmember_t *ctlm = v;
- dptr += sizeof (ctf_lmember_t);
-
- *mpp = xmalloc(sizeof (mlist_t));
- (*mpp)->ml_name = xstrdup(sbuf +
- ctlm->ctlm_name);
- (*mpp)->ml_type =
- tdarr[ctlm->ctlm_type];
- (*mpp)->ml_offset =
- (int)CTF_LMEM_OFFSET(ctlm);
- (*mpp)->ml_size = 0;
+ if (size < CTF_V3_LSTRUCT_THRESH) {
+ for (i = 0, mpp = &tdp->t_members; i < vlen;
+ i++, mpp = &((*mpp)->ml_next)) {
+ v = (void *) dptr;
+ struct ctf_member_v3 *ctm = v;
+ dptr += sizeof (struct ctf_member_v3);
+
+ *mpp = xmalloc(sizeof (mlist_t));
+ (*mpp)->ml_name = xstrdup(sbuf +
+ ctm->ctm_name);
+ (*mpp)->ml_type = tdarr[ctm->ctm_type];
+ (*mpp)->ml_offset = ctm->ctm_offset;
+ (*mpp)->ml_size = 0;
+ }
+ } else {
+ for (i = 0, mpp = &tdp->t_members; i < vlen;
+ i++, mpp = &((*mpp)->ml_next)) {
+ v = (void *) dptr;
+ struct ctf_lmember_v3 *ctlm = v;
+ dptr += sizeof (struct ctf_lmember_v3);
+
+ *mpp = xmalloc(sizeof (mlist_t));
+ (*mpp)->ml_name = xstrdup(sbuf +
+ ctlm->ctlm_name);
+ (*mpp)->ml_type =
+ tdarr[ctlm->ctlm_type];
+ (*mpp)->ml_offset =
+ (int)CTF_LMEM_OFFSET(ctlm);
+ (*mpp)->ml_size = 0;
+ }
}
}
*mpp = NULL;
break;
+ }
case CTF_K_ENUM:
tdp->t_type = ENUM;
@@ -1187,26 +1298,26 @@ resurrect_types(ctf_header_t *h, tdata_t *td, tdesc_t **tdarr, int tdsize,
case CTF_K_TYPEDEF:
tdp->t_type = TYPEDEF;
- tdp->t_tdesc = tdarr[ctt->ctt_type];
+ tdp->t_tdesc = tdarr[type];
break;
case CTF_K_VOLATILE:
tdp->t_type = VOLATILE;
- tdp->t_tdesc = tdarr[ctt->ctt_type];
+ tdp->t_tdesc = tdarr[type];
break;
case CTF_K_CONST:
tdp->t_type = CONST;
- tdp->t_tdesc = tdarr[ctt->ctt_type];
+ tdp->t_tdesc = tdarr[type];
break;
case CTF_K_FUNCTION:
tdp->t_type = FUNCTION;
tdp->t_fndef = xcalloc(sizeof (fndef_t));
- tdp->t_fndef->fn_ret = tdarr[ctt->ctt_type];
+ tdp->t_fndef->fn_ret = tdarr[type];
- v = (void *) (dptr + (sizeof (ushort_t) * (vlen - 1)));
- if (vlen > 0 && *(ushort_t *)v == 0)
+ v = (void *) (dptr + (idwidth * (vlen - 1)));
+ if (vlen > 0 && *(uint_t *)v == 0)
tdp->t_fndef->fn_vargs = 1;
tdp->t_fndef->fn_nargs = vlen - tdp->t_fndef->fn_vargs;
@@ -1215,20 +1326,19 @@ resurrect_types(ctf_header_t *h, tdata_t *td, tdesc_t **tdarr, int tdsize,
for (i = 0; i < vlen; i++) {
v = (void *) dptr;
- argid = *(ushort_t *)v;
- dptr += sizeof (ushort_t);
+ memcpy(&argid, v, idwidth);
+ dptr += idwidth;
if (argid != 0)
tdp->t_fndef->fn_args[i] = tdarr[argid];
}
- if (vlen & 1)
- dptr += sizeof (ushort_t);
+ dptr = roundup2(dptr, 4);
break;
case CTF_K_RESTRICT:
tdp->t_type = RESTRICT;
- tdp->t_tdesc = tdarr[ctt->ctt_type];
+ tdp->t_tdesc = tdarr[type];
break;
case CTF_K_UNKNOWN:
@@ -1238,7 +1348,7 @@ resurrect_types(ctf_header_t *h, tdata_t *td, tdesc_t **tdarr, int tdsize,
warning("Can't parse unknown CTF type %d\n", kind);
}
- if (CTF_INFO_ISROOT(ctt->ctt_info)) {
+ if (isroot) {
iidesc_t *ii = iidesc_new(tdp->t_name);
if (tdp->t_type == STRUCT || tdp->t_type == UNION ||
tdp->t_type == ENUM)
@@ -1252,8 +1362,7 @@ resurrect_types(ctf_header_t *h, tdata_t *td, tdesc_t **tdarr, int tdsize,
}
debug(3, "Resurrected %d %stype %s (%d)\n", tdp->t_type,
- (CTF_INFO_ISROOT(ctt->ctt_info) ? "root " : ""),
- tdesc_name(tdp), tdp->t_id);
+ (isroot ? "root " : ""), tdesc_name(tdp), tdp->t_id);
}
debug(3, "Resurrected %d types (%d were roots)\n", tcnt, iicnt);
@@ -1353,7 +1462,7 @@ ctf_load(char *file, caddr_t buf, size_t bufsz, symit_data_t *si, char *label)
if (h->cth_magic != CTF_MAGIC)
parseterminate("Corrupt CTF - bad magic 0x%x", h->cth_magic);
- if (h->cth_version != CTF_VERSION)
+ if (h->cth_version != CTF_VERSION_2 && h->cth_version != CTF_VERSION_3)
parseterminate("Unknown CTF version %d", h->cth_version);
ctfdatasz = h->cth_stroff + h->cth_strlen;
diff --git a/cddl/contrib/opensolaris/tools/ctf/cvt/ctfmerge.c b/cddl/contrib/opensolaris/tools/ctf/cvt/ctfmerge.c
index ddb5f388ca98..161927cf0663 100644
--- a/cddl/contrib/opensolaris/tools/ctf/cvt/ctfmerge.c
+++ b/cddl/contrib/opensolaris/tools/ctf/cvt/ctfmerge.c
@@ -972,11 +972,11 @@ main(int argc, char **argv)
savetd = tdata_new();
- if (CTF_TYPE_ISCHILD(reftd->td_nextid))
+ if (CTF_V3_TYPE_ISCHILD(reftd->td_nextid))
terminate("No room for additional types in master\n");
savetd->td_nextid = withfile ? reftd->td_nextid :
- CTF_INDEX_TO_TYPE(1, TRUE);
+ CTF_V3_INDEX_TO_TYPE(1, TRUE);
merge_into_master(mstrtd, reftd, savetd, 0);
tdata_label_add(savetd, label, CTF_LABEL_LASTIDX);
diff --git a/cddl/contrib/opensolaris/tools/ctf/dump/dump.c b/cddl/contrib/opensolaris/tools/ctf/dump/dump.c
index 740485ddff03..6da2c2cf8b26 100644
--- a/cddl/contrib/opensolaris/tools/ctf/dump/dump.c
+++ b/cddl/contrib/opensolaris/tools/ctf/dump/dump.c
@@ -97,6 +97,8 @@ typedef struct ctf_data {
caddr_t cd_ctfdata; /* Pointer to the CTF data */
size_t cd_ctflen; /* Length of CTF data */
+ size_t cd_idwidth; /* Size of a type ID, in bytes */
+
/*
* cd_symdata will be non-NULL if the CTF data is being retrieved from
* an ELF file with a symbol table. cd_strdata and cd_nsyms should be
@@ -266,9 +268,8 @@ next_sym(const ctf_data_t *cd, const int symidx, const uchar_t matchtype,
static int
read_data(const ctf_header_t *hp, const ctf_data_t *cd)
{
- void *v = (void *) (cd->cd_ctfdata + hp->cth_objtoff);
- const ushort_t *idp = v;
- ulong_t n = (hp->cth_funcoff - hp->cth_objtoff) / sizeof (ushort_t);
+ const char *v = (void *) (cd->cd_ctfdata + hp->cth_objtoff);
+ ulong_t n = (hp->cth_funcoff - hp->cth_objtoff) / cd->cd_idwidth;
if (flags != F_STATS)
print_line("- Data Objects ");
@@ -287,6 +288,7 @@ read_data(const ctf_header_t *hp, const ctf_data_t *cd)
char *name = NULL;
for (symidx = -1, i = 0; i < (int) n; i++) {
+ uint32_t id = 0;
int nextsym;
if (cd->cd_symdata == NULL || (nextsym = next_sym(cd,
@@ -295,7 +297,9 @@ read_data(const ctf_header_t *hp, const ctf_data_t *cd)
else
symidx = nextsym;
- len = printf(" [%u] %u", i, *idp++);
+ memcpy(&id, v, cd->cd_idwidth);
+ v += cd->cd_idwidth;
+ len = printf(" [%u] %u", i, id);
if (name != NULL)
(void) printf("%*s%s (%u)", (15 - len), "",
name, symidx);
@@ -310,11 +314,10 @@ read_data(const ctf_header_t *hp, const ctf_data_t *cd)
static int
read_funcs(const ctf_header_t *hp, const ctf_data_t *cd)
{
- void *v = (void *) (cd->cd_ctfdata + hp->cth_funcoff);
- const ushort_t *fp = v;
+ const char *v = (void *) (cd->cd_ctfdata + hp->cth_funcoff);
+ uint_t f = 0, info;
- v = (void *) (cd->cd_ctfdata + hp->cth_typeoff);
- const ushort_t *end = v;
+ const char *end = (void *) (cd->cd_ctfdata + hp->cth_typeoff);
*** 448 LINES SKIPPED ***