Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/freebsd/freebsd-src.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMark Johnston <markj@FreeBSD.org>2022-03-07 16:54:18 +0300
committerMark Johnston <markj@FreeBSD.org>2022-04-18 19:38:45 +0300
commit105d1ae9041ff139c6db2f00eb4dd7441d47305f (patch)
tree05e1c145438229fd7684c5c1bb853a7c2bbe7693
parentdc543c8786a5345b24bbbf9f8e6725fed2a90b39 (diff)
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)
-rw-r--r--cddl/contrib/opensolaris/tools/ctf/cvt/ctf.c453
-rw-r--r--cddl/contrib/opensolaris/tools/ctf/cvt/ctfmerge.c4
-rw-r--r--cddl/contrib/opensolaris/tools/ctf/dump/dump.c286
-rw-r--r--sys/sys/ctf.h2
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);
ulong_t id;
int symidx;
@@ -331,10 +334,14 @@ read_funcs(const ctf_header_t *hp, const ctf_data_t *cd)
if (hp->cth_funcoff > hp->cth_typeoff)
WARN("file is corrupt -- cth_funcoff > cth_typeoff\n");
- for (symidx = -1, id = 0; fp < end; id++) {
- ushort_t info = *fp++;
- ushort_t kind = CTF_INFO_KIND(info);
- ushort_t n = CTF_INFO_VLEN(info);
+ for (symidx = -1, id = 0; v < end; id++) {
+ info = 0;
+ memcpy(&info, v, cd->cd_idwidth);
+ v += cd->cd_idwidth;
+ ushort_t kind = hp->cth_version == CTF_VERSION_2 ?
+ CTF_V2_INFO_KIND(info) : CTF_V3_INFO_KIND(info);
+ ushort_t n = hp->cth_version == CTF_VERSION_2 ?
+ CTF_V2_INFO_VLEN(info) : CTF_V3_INFO_VLEN(info);
ushort_t i;
int nextsym;
char *name;
@@ -354,7 +361,7 @@ read_funcs(const ctf_header_t *hp, const ctf_data_t *cd)
return (E_ERROR);
}
- if (fp + n > end) {
+ if (v + n * cd->cd_idwidth > end) {
(void) printf(" [%lu] vlen %u extends past section "
"boundary\n", id, n);
return (E_ERROR);
@@ -364,17 +371,24 @@ read_funcs(const ctf_header_t *hp, const ctf_data_t *cd)
(void) printf(" [%lu] FUNC ", id);
if (name != NULL)
(void) printf("(%s) ", name);
- (void) printf("returns: %u args: (", *fp++);
+ memcpy(&f, v, cd->cd_idwidth);
+ v += cd->cd_idwidth;
+ (void) printf("returns: %u args: (", f);
if (n != 0) {
- (void) printf("%u", *fp++);
- for (i = 1; i < n; i++)
- (void) printf(", %u", *fp++);
+ memcpy(&f, v, cd->cd_idwidth);
+ v += cd->cd_idwidth;
+ (void) printf("%u", f);
+ for (i = 1; i < n; i++) {
+ memcpy(&f, v, cd->cd_idwidth);
+ v += cd->cd_idwidth;
+ (void) printf(", %u", f);
+ }
}
(void) printf(")\n");
} else
- fp += n + 1; /* skip to next function definition */
+ v += n * cd->cd_idwidth + 1; /* skip to next function definition */
stats.s_nfunc++;
stats.s_nargs += n;
@@ -387,13 +401,10 @@ read_funcs(const ctf_header_t *hp, const ctf_data_t *cd)
static int
read_types(const ctf_header_t *hp, const ctf_data_t *cd)
{
- void *v = (void *) (cd->cd_ctfdata + hp->cth_typeoff);
- const ctf_type_t *tp = v;
-
- v = (void *) (cd->cd_ctfdata + hp->cth_stroff);
- const ctf_type_t *end = v;
-
+ const char *v = (void *) (cd->cd_ctfdata + hp->cth_typeoff);
+ const char *end = (void *) (cd->cd_ctfdata + hp->cth_stroff);
ulong_t id;
+ uint_t version;
if (flags != F_STATS)
print_line("- Types ");
@@ -407,103 +418,158 @@ read_types(const ctf_header_t *hp, const ctf_data_t *cd)
if (hp->cth_typeoff > hp->cth_stroff)
WARN("file is corrupt -- cth_typeoff > cth_stroff\n");
+ version = hp->cth_version;
+
id = 1;
if (hp->cth_parlabel || hp->cth_parname)
- id += 1 << CTF_PARENT_SHIFT;
+ id += 1ul << (hp->cth_version == CTF_VERSION_2 ?
+ CTF_V2_PARENT_SHIFT : CTF_V3_PARENT_SHIFT);
- for (/* */; tp < end; id++) {
- ulong_t i, n = CTF_INFO_VLEN(tp->ctt_info);
+ for (/* */; v < end; id++) {
+ struct ctf_type_v2 t2;
+ struct ctf_type_v3 t3;
+ ulong_t i, n;
size_t size, increment, vlen = 0;
- int kind = CTF_INFO_KIND(tp->ctt_info);
+ uint_t isroot, name, type;
+ int kind;
+
+ if (version == CTF_VERSION_2) {
+ memcpy(&t2, v, sizeof(t2));
+ name = t2.ctt_name;
+ n = CTF_V2_INFO_VLEN(t2.ctt_info);
+ isroot = CTF_V2_INFO_ISROOT(t2.ctt_info);
+ kind = CTF_V2_INFO_KIND(t2.ctt_info);
+ type = t2.ctt_type;
+
+ if (t2.ctt_size == CTF_V2_LSIZE_SENT) {
+ increment = sizeof (struct ctf_type_v2);
+ size = (size_t)CTF_TYPE_LSIZE(&t2);
+ } else {
+ increment = sizeof (struct ctf_stype_v2);
+ size = t2.ctt_size;
+ }
+ } else {
+ memcpy(&t3, v, sizeof(t3));
+ name = t3.ctt_name;
+ n = CTF_V3_INFO_VLEN(t3.ctt_info);
+ isroot = CTF_V3_INFO_ISROOT(t3.ctt_info);
+ kind = CTF_V3_INFO_KIND(t3.ctt_info);
+ type = t3.ctt_type;
+
+ if (t3.ctt_size == CTF_V3_LSIZE_SENT) {
+ increment = sizeof (struct ctf_type_v3);
+ size = (size_t)CTF_TYPE_LSIZE(&t3);
+ } else {
+ increment = sizeof (struct ctf_stype_v3);
+ size = t3.ctt_size;
+ }
+ }
union {
- const void *ptr;
- ctf_array_t *ap;
- const ctf_member_t *mp;
- const ctf_lmember_t *lmp;
+ const char *ptr;
+ struct ctf_array_v2 *ap2;
+ struct ctf_array_v3 *ap3;
+ const struct ctf_member_v2 *mp2;
+ const struct ctf_member_v3 *mp3;
+ const struct ctf_lmember_v2 *lmp2;
+ const struct ctf_lmember_v3 *lmp3;
const ctf_enum_t *ep;
- const ushort_t *argp;
} u;
+ u.ptr = v + increment;
+
if (flags != F_STATS) {
(void) printf(" %c%lu%c ",
- "[<"[CTF_INFO_ISROOT(tp->ctt_info)], id,
- "]>"[CTF_INFO_ISROOT(tp->ctt_info)]);
- }
-
- if (tp->ctt_size == CTF_LSIZE_SENT) {
- increment = sizeof (ctf_type_t);
- size = (size_t)CTF_TYPE_LSIZE(tp);
- } else {
- increment = sizeof (ctf_stype_t);
- size = tp->ctt_size;
+ "[<"[isroot], id, "]>"[isroot]);
}
- u.ptr = (const char *)tp + increment;
switch (kind) {
case CTF_K_INTEGER:
if (flags != F_STATS) {
- uint_t encoding = *((const uint_t *)u.ptr);
+ uint_t encoding =
+ *((const uint_t *)(const void *)u.ptr);
(void) printf("INTEGER %s encoding=%s offset=%u"
- " bits=%u", ref_to_str(tp->ctt_name, hp,
- cd), int_encoding_to_str(
+ " bits=%u", ref_to_str(name, hp, cd),
+ int_encoding_to_str(
CTF_INT_ENCODING(encoding)),
CTF_INT_OFFSET(encoding),
CTF_INT_BITS(encoding));
}
- vlen = sizeof (uint_t);
+ vlen = sizeof (uint32_t);
break;
case CTF_K_FLOAT:
if (flags != F_STATS) {
- uint_t encoding = *((const uint_t *)u.ptr);
+ uint_t encoding =
+ *((const uint_t *)(const void *)u.ptr);
(void) printf("FLOAT %s encoding=%s offset=%u "
- "bits=%u", ref_to_str(tp->ctt_name, hp,
- cd), fp_encoding_to_str(
+ "bits=%u", ref_to_str(name, hp, cd),
+ fp_encoding_to_str(
CTF_FP_ENCODING(encoding)),
CTF_FP_OFFSET(encoding),
CTF_FP_BITS(encoding));
}
- vlen = sizeof (uint_t);
+ vlen = sizeof (uint32_t);
break;
case CTF_K_POINTER:
if (flags != F_STATS) {
(void) printf("POINTER %s refers to %u",
- ref_to_str(tp->ctt_name, hp, cd),
- tp->ctt_type);
+ ref_to_str(name, hp, cd), type);
}
break;
- case CTF_K_ARRAY:
+ case CTF_K_ARRAY: {
+ uint_t contents, index, nelems;
+
+ if (version == CTF_VERSION_2) {
+ contents = u.ap2->cta_contents;
+ index = u.ap2->cta_index;
+ nelems = u.ap2->cta_nelems;
+ } else {
+ contents = u.ap3->cta_contents;
+ index = u.ap3->cta_index;
+ nelems = u.ap3->cta_nelems;
+ }
if (flags != F_STATS) {
(void) printf("ARRAY %s content: %u index: %u "
- "nelems: %u\n", ref_to_str(tp->ctt_name,
- hp, cd), u.ap->cta_contents,
- u.ap->cta_index, u.ap->cta_nelems);
+ "nelems: %u\n", ref_to_str(name, hp, cd),
+ contents, index, nelems);
}
- vlen = sizeof (ctf_array_t);
+ if (version == 2)
+ vlen = sizeof (struct ctf_array_v2);
+ else
+ vlen = sizeof (struct ctf_array_v3);
break;
+ }
+
+ case CTF_K_FUNCTION: {
+ uint_t arg = 0;
- case CTF_K_FUNCTION:
if (flags != F_STATS) {
(void) printf("FUNCTION %s returns: %u args: (",
- ref_to_str(tp->ctt_name, hp, cd),
- tp->ctt_type);
+ ref_to_str(name, hp, cd), type);
if (n != 0) {
- (void) printf("%u", *u.argp++);
- for (i = 1; i < n; i++, u.argp++)
- (void) printf(", %u", *u.argp);
+ memcpy(&arg, u.ptr, cd->cd_idwidth);
+ u.ptr += cd->cd_idwidth;
+ (void) printf("%u", arg);
+ for (i = 1; i < n;
+ i++, u.ptr += cd->cd_idwidth) {
+ memcpy(&arg, u.ptr,
+ cd->cd_idwidth);
+ (void) printf(", %u", arg);
+ }
}
(void) printf(")");
}
- vlen = sizeof (ushort_t) * (n + (n & 1));
+ vlen = roundup2(cd->cd_idwidth * n, 4);
break;
+ }
case CTF_K_STRUCT:
case CTF_K_UNION:
@@ -527,36 +593,64 @@ read_types(const ctf_header_t *hp, const ctf_data_t *cd)
if (flags != F_STATS) {
(void) printf(" %s (%zd bytes)\n",
- ref_to_str(tp->ctt_name, hp, cd), size);
-
- if (size >= CTF_LSTRUCT_THRESH) {
- for (i = 0; i < n; i++, u.lmp++) {
- (void) printf(
- "\t%s type=%u off=%llu\n",
- ref_to_str(u.lmp->ctlm_name,
- hp, cd), u.lmp->ctlm_type,
- (unsigned long long)
- CTF_LMEM_OFFSET(u.lmp));
+ ref_to_str(name, hp, cd), size);
+
+ if (version == CTF_VERSION_2) {
+ if (size >= CTF_V2_LSTRUCT_THRESH) {
+ for (i = 0; i < n; i++, u.lmp2++) {
+ (void) printf(
+ "\t%s type=%u off=%llu\n",
+ ref_to_str(u.lmp2->ctlm_name,
+ hp, cd), u.lmp2->ctlm_type,
+ (unsigned long long)
+ CTF_LMEM_OFFSET(u.lmp2));
+ }
+ } else {
+ for (i = 0; i < n; i++, u.mp2++) {
+ (void) printf(
+ "\t%s type=%u off=%u\n",
+ ref_to_str(u.mp2->ctm_name,
+ hp, cd), u.mp2->ctm_type,
+ u.mp2->ctm_offset);
+ }
}
} else {
- for (i = 0; i < n; i++, u.mp++) {
- (void) printf(
- "\t%s type=%u off=%u\n",
- ref_to_str(u.mp->ctm_name,
- hp, cd), u.mp->ctm_type,
- u.mp->ctm_offset);
+ if (size >= CTF_V3_LSTRUCT_THRESH) {
+ for (i = 0; i < n; i++, u.lmp3++) {
+ (void) printf(
+ "\t%s type=%u off=%llu\n",
+ ref_to_str(u.lmp3->ctlm_name,
+ hp, cd), u.lmp3->ctlm_type,
+ (unsigned long long)
+ CTF_LMEM_OFFSET(u.lmp3));
+ }
+ } else {
+ for (i = 0; i < n; i++, u.mp3++) {
+ (void) printf(
+ "\t%s type=%u off=%u\n",
+ ref_to_str(u.mp3->ctm_name,
+ hp, cd), u.mp3->ctm_type,
+ u.mp3->ctm_offset);
+ }
}
}
}
- vlen = n * (size >= CTF_LSTRUCT_THRESH ?
- sizeof (ctf_lmember_t) : sizeof (ctf_member_t));
+ if (version == CTF_VERSION_2) {
+ vlen = n * (size >= CTF_V2_LSTRUCT_THRESH ?
+ sizeof (struct ctf_lmember_v2) :
+ sizeof (struct ctf_member_v2));
+ } else {
+ vlen = n * (size >= CTF_V3_LSTRUCT_THRESH ?
+ sizeof (struct ctf_lmember_v3) :
+ sizeof (struct ctf_member_v3));
+ }
break;
case CTF_K_ENUM:
if (flags != F_STATS) {
(void) printf("ENUM %s\n",
- ref_to_str(tp->ctt_name, hp, cd));
+ ref_to_str(name, hp, cd));
for (i = 0; i < n; i++, u.ep++) {
(void) printf("\t%s = %d\n",
@@ -574,39 +668,35 @@ read_types(const ctf_header_t *hp, const ctf_data_t *cd)
case CTF_K_FORWARD:
if (flags != F_STATS) {
(void) printf("FORWARD %s",
- ref_to_str(tp->ctt_name, hp, cd));
+ ref_to_str(name, hp, cd));
}
break;
case CTF_K_TYPEDEF:
if (flags != F_STATS) {
(void) printf("TYPEDEF %s refers to %u",
- ref_to_str(tp->ctt_name, hp, cd),
- tp->ctt_type);
+ ref_to_str(name, hp, cd), type);
}
break;
case CTF_K_VOLATILE:
if (flags != F_STATS) {
(void) printf("VOLATILE %s refers to %u",
- ref_to_str(tp->ctt_name, hp, cd),
- tp->ctt_type);
+ ref_to_str(name, hp, cd), type);
}
break;
case CTF_K_CONST:
if (flags != F_STATS) {
(void) printf("CONST %s refers to %u",
- ref_to_str(tp->ctt_name, hp, cd),
- tp->ctt_type);
+ ref_to_str(name, hp, cd), type);
}
break;
case CTF_K_RESTRICT:
if (flags != F_STATS) {
(void) printf("RESTRICT %s refers to %u",
- ref_to_str(tp->ctt_name, hp, cd),
- tp->ctt_type);
+ ref_to_str(name, hp, cd), type);
}
break;
@@ -624,7 +714,7 @@ read_types(const ctf_header_t *hp, const ctf_data_t *cd)
stats.s_ntypes++;
stats.s_types[kind]++;
- tp = (ctf_type_t *)((uintptr_t)tp + increment + vlen);
+ v += increment + vlen;
}
return (E_SUCCESS);
@@ -935,14 +1025,16 @@ main(int argc, char *argv[])
if (pp->ctp_magic != CTF_MAGIC)
die("%s does not appear to contain CTF data\n", filename);
- if (pp->ctp_version == CTF_VERSION) {
+ if (pp->ctp_version >= CTF_VERSION_2) {
v = (void *) cd.cd_ctfdata;
hp = v;
cd.cd_ctfdata = (caddr_t)cd.cd_ctfdata + sizeof (ctf_header_t);
+ cd.cd_idwidth = pp->ctp_version == CTF_VERSION_2 ? 2 : 4;
+
if (cd.cd_ctflen < sizeof (ctf_header_t)) {
die("%s does not contain a v%d CTF header\n", filename,
- CTF_VERSION);
+ pp->ctp_version);
}
} else {
diff --git a/sys/sys/ctf.h b/sys/sys/ctf.h
index 4072e318320c..1a724c842fef 100644
--- a/sys/sys/ctf.h
+++ b/sys/sys/ctf.h
@@ -149,7 +149,7 @@ typedef struct ctf_enum {
} ctf_enum_t;
#define CTF_MAGIC 0xcff1
-#define CTF_VERSION CTF_VERSION_2
+#define CTF_VERSION CTF_VERSION_3
#define CTF_VERSION_3 3
#define CTF_VERSION_2 2
#define CTF_VERSION_1 1