Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F115813766
D34361.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
14 KB
Referenced Files
None
Subscribers
None
D34361.diff
View Options
diff --git a/sys/cddl/dev/fbt/fbt.c b/sys/cddl/dev/fbt/fbt.c
--- a/sys/cddl/dev/fbt/fbt.c
+++ b/sys/cddl/dev/fbt/fbt.c
@@ -370,12 +370,12 @@
const Elf_Sym *symp = lc->symtab;
const ctf_header_t *hp = (const ctf_header_t *) lc->ctftab;
const uint8_t *ctfdata = lc->ctftab + sizeof(ctf_header_t);
+ size_t idwidth;
int i;
uint32_t *ctfoff;
uint32_t objtoff = hp->cth_objtoff;
uint32_t funcoff = hp->cth_funcoff;
- ushort_t info;
- ushort_t vlen;
+ uint_t kind, info, vlen;
/* Sanity check. */
if (hp->cth_magic != CTF_MAGIC) {
@@ -391,6 +391,8 @@
ctfoff = malloc(sizeof(uint32_t) * lc->nsym, M_LINKER, M_WAITOK);
*lc->ctfoffp = ctfoff;
+ idwidth = hp->cth_version == CTF_VERSION_2 ? 2 : 4;
+
for (i = 0; i < lc->nsym; i++, ctfoff++, symp++) {
if (symp->st_name == 0 || symp->st_shndx == SHN_UNDEF) {
*ctfoff = 0xffffffff;
@@ -400,13 +402,13 @@
switch (ELF_ST_TYPE(symp->st_info)) {
case STT_OBJECT:
if (objtoff >= hp->cth_funcoff ||
- (symp->st_shndx == SHN_ABS && symp->st_value == 0)) {
+ (symp->st_shndx == SHN_ABS && symp->st_value == 0)) {
*ctfoff = 0xffffffff;
- break;
- }
+ break;
+ }
- *ctfoff = objtoff;
- objtoff += sizeof (ushort_t);
+ *ctfoff = objtoff;
+ objtoff += idwidth;
break;
case STT_FUNC:
@@ -417,18 +419,25 @@
*ctfoff = funcoff;
- info = *((const ushort_t *)(ctfdata + funcoff));
- vlen = CTF_INFO_VLEN(info);
+ info = 0;
+ memcpy(&info, ctfdata + funcoff, idwidth);
+ if (hp->cth_version == CTF_VERSION_2) {
+ kind = CTF_V2_INFO_KIND(info);
+ vlen = CTF_V2_INFO_VLEN(info);
+ } else {
+ kind = CTF_V3_INFO_KIND(info);
+ vlen = CTF_V3_INFO_VLEN(info);
+ }
/*
* If we encounter a zero pad at the end, just skip it.
* Otherwise skip over the function and its return type
* (+2) and the argument list (vlen).
*/
- if (CTF_INFO_KIND(info) == CTF_K_UNKNOWN && vlen == 0)
- funcoff += sizeof (ushort_t); /* skip pad */
+ if (kind == CTF_K_UNKNOWN && vlen == 0)
+ funcoff += idwidth;
else
- funcoff += sizeof (ushort_t) * (vlen + 2);
+ funcoff += idwidth * (vlen + 2);
break;
default:
@@ -440,18 +449,61 @@
return (0);
}
+static void
+fbt_get_ctt_index(uint8_t version, const void *v, uint_t *indexp,
+ uint_t *typep, int *ischildp)
+{
+ uint_t index, type;
+ int ischild;
+
+ if (version == CTF_VERSION_2) {
+ const struct ctf_type_v2 *ctt = v;
+
+ type = ctt->ctt_type;
+ index = CTF_V2_TYPE_TO_INDEX(ctt->ctt_type);
+ ischild = CTF_V2_TYPE_ISCHILD(ctt->ctt_type);
+ } else {
+ const struct ctf_type_v3 *ctt = v;
+
+ type = ctt->ctt_type;
+ index = CTF_V3_TYPE_TO_INDEX(ctt->ctt_type);
+ ischild = CTF_V3_TYPE_ISCHILD(ctt->ctt_type);
+ }
+
+ if (indexp != NULL)
+ *indexp = index;
+ if (typep != NULL)
+ *typep = type;
+ if (ischildp != NULL)
+ *ischildp = ischild;
+}
+
static ssize_t
-fbt_get_ctt_size(uint8_t version, const ctf_type_t *tp, ssize_t *sizep,
+fbt_get_ctt_size(uint8_t version, const void *tp, ssize_t *sizep,
ssize_t *incrementp)
{
ssize_t size, increment;
- if (tp->ctt_size == CTF_LSIZE_SENT) {
- size = CTF_TYPE_LSIZE(tp);
- increment = sizeof (ctf_type_t);
+ if (version == CTF_VERSION_2) {
+ const struct ctf_type_v2 *ctt = tp;
+
+ if (ctt->ctt_size == CTF_V2_LSIZE_SENT) {
+ size = CTF_TYPE_LSIZE(ctt);
+ increment = sizeof (struct ctf_type_v2);
+ } else {
+ size = ctt->ctt_size;
+ increment = sizeof (struct ctf_stype_v2);
+ }
} else {
- size = tp->ctt_size;
- increment = sizeof (ctf_stype_t);
+ const struct ctf_type_v3 *ctt = tp;
+
+ if (ctt->ctt_size == CTF_V3_LSIZE_SENT) {
+ size = CTF_TYPE_LSIZE(ctt);
+ increment = sizeof (struct ctf_type_v3);
+ } else {
+ size = ctt->ctt_size;
+ increment = sizeof (struct ctf_stype_v3);
+ }
}
if (sizep)
@@ -462,41 +514,69 @@
return (size);
}
+static void
+fbt_get_ctt_info(uint8_t version, const void *tp, uint_t *kindp, uint_t *vlenp,
+ int *isrootp)
+{
+ uint_t kind, vlen;
+ int isroot;
+
+ if (version == CTF_VERSION_2) {
+ const struct ctf_type_v2 *ctt = tp;
+
+ 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 {
+ const struct ctf_type_v3 *ctt = tp;
+
+ kind = CTF_V3_INFO_KIND(ctt->ctt_info);
+ vlen = CTF_V3_INFO_VLEN(ctt->ctt_info);
+ isroot = CTF_V3_INFO_ISROOT(ctt->ctt_info);
+ }
+
+ if (kindp != NULL)
+ *kindp = kind;
+ if (vlenp != NULL)
+ *vlenp = vlen;
+ if (isrootp != NULL)
+ *isrootp = isroot;
+}
+
static int
fbt_typoff_init(linker_ctf_t *lc)
{
const ctf_header_t *hp = (const ctf_header_t *) lc->ctftab;
- const ctf_type_t *tbuf;
- const ctf_type_t *tend;
- const ctf_type_t *tp;
+ const void *tbuf, *tend, *tp;
const uint8_t *ctfdata = lc->ctftab + sizeof(ctf_header_t);
+ size_t idwidth;
int ctf_typemax = 0;
uint32_t *xp;
ulong_t pop[CTF_K_MAX + 1] = { 0 };
uint8_t version;
-
/* Sanity check. */
if (hp->cth_magic != CTF_MAGIC)
return (EINVAL);
version = hp->cth_version;
+ idwidth = version == CTF_VERSION_2 ? 2 : 4;
- tbuf = (const ctf_type_t *) (ctfdata + hp->cth_typeoff);
- tend = (const ctf_type_t *) (ctfdata + hp->cth_stroff);
+ tbuf = (const void *) (ctfdata + hp->cth_typeoff);
+ tend = (const void *) (ctfdata + hp->cth_stroff);
/*
* We make two passes through the entire type section. In this first
* pass, we count the number of each type and the total number of types.
*/
for (tp = tbuf; tp < tend; ctf_typemax++) {
- ushort_t kind = CTF_INFO_KIND(tp->ctt_info);
- ulong_t vlen = CTF_INFO_VLEN(tp->ctt_info);
+ uint_t kind, type, vlen;
ssize_t size, increment;
-
size_t vbytes;
(void) fbt_get_ctt_size(version, tp, &size, &increment);
+ fbt_get_ctt_info(version, tp, &kind, &vlen, NULL);
+ fbt_get_ctt_index(version, tp, NULL, &type, NULL);
switch (kind) {
case CTF_K_INTEGER:
@@ -504,17 +584,31 @@
vbytes = sizeof (uint_t);
break;
case CTF_K_ARRAY:
- vbytes = sizeof (ctf_array_t);
+ if (version == CTF_VERSION_2)
+ vbytes = sizeof (struct ctf_array_v2);
+ else
+ vbytes = sizeof (struct ctf_array_v3);
break;
case CTF_K_FUNCTION:
- vbytes = sizeof (ushort_t) * (vlen + (vlen & 1));
+ vbytes = roundup2(idwidth * vlen, sizeof(uint32_t));
break;
case CTF_K_STRUCT:
case CTF_K_UNION:
- if (size < CTF_LSTRUCT_THRESH)
- vbytes = sizeof (ctf_member_t) * vlen;
- else
- vbytes = sizeof (ctf_lmember_t) * vlen;
+ if (version == CTF_VERSION_2) {
+ if (size < CTF_V2_LSTRUCT_THRESH)
+ vbytes =
+ sizeof (struct ctf_member_v2) * vlen;
+ else
+ vbytes =
+ sizeof (struct ctf_lmember_v2) * vlen;
+ } else {
+ if (size < CTF_V3_LSTRUCT_THRESH)
+ vbytes =
+ sizeof (struct ctf_member_v3) * vlen;
+ else
+ vbytes =
+ sizeof (struct ctf_lmember_v3) * vlen;
+ }
break;
case CTF_K_ENUM:
vbytes = sizeof (ctf_enum_t) * vlen;
@@ -525,11 +619,10 @@
* kind for the tag, so bump that population count too.
* If ctt_type is unknown, treat the tag as a struct.
*/
- if (tp->ctt_type == CTF_K_UNKNOWN ||
- tp->ctt_type >= CTF_K_MAX)
+ if (type == CTF_K_UNKNOWN || type >= CTF_K_MAX)
pop[CTF_K_STRUCT]++;
else
- pop[tp->ctt_type]++;
+ pop[type]++;
/*FALLTHRU*/
case CTF_K_UNKNOWN:
vbytes = 0;
@@ -545,7 +638,7 @@
printf("%s(%d): detected invalid CTF kind -- %u\n", __func__, __LINE__, kind);
return (EIO);
}
- tp = (ctf_type_t *)((uintptr_t)tp + increment + vbytes);
+ tp = (const void *)((uintptr_t)tp + increment + vbytes);
pop[kind]++;
}
@@ -565,13 +658,13 @@
* In the second pass, fill in the type offset.
*/
for (tp = tbuf; tp < tend; xp++) {
- ushort_t kind = CTF_INFO_KIND(tp->ctt_info);
- ulong_t vlen = CTF_INFO_VLEN(tp->ctt_info);
ssize_t size, increment;
+ uint_t kind, vlen;
size_t vbytes;
(void) fbt_get_ctt_size(version, tp, &size, &increment);
+ fbt_get_ctt_info(version, tp, &kind, &vlen, NULL);
switch (kind) {
case CTF_K_INTEGER:
@@ -579,17 +672,31 @@
vbytes = sizeof (uint_t);
break;
case CTF_K_ARRAY:
- vbytes = sizeof (ctf_array_t);
+ if (version == CTF_VERSION_2)
+ vbytes = sizeof (struct ctf_array_v2);
+ else
+ vbytes = sizeof (struct ctf_array_v3);
break;
case CTF_K_FUNCTION:
- vbytes = sizeof (ushort_t) * (vlen + (vlen & 1));
+ vbytes = roundup2(idwidth * vlen, sizeof(uint32_t));
break;
case CTF_K_STRUCT:
case CTF_K_UNION:
- if (size < CTF_LSTRUCT_THRESH)
- vbytes = sizeof (ctf_member_t) * vlen;
- else
- vbytes = sizeof (ctf_lmember_t) * vlen;
+ if (version == CTF_VERSION_2) {
+ if (size < CTF_V2_LSTRUCT_THRESH)
+ vbytes =
+ sizeof (struct ctf_member_v2) * vlen;
+ else
+ vbytes =
+ sizeof (struct ctf_lmember_v2) * vlen;
+ } else {
+ if (size < CTF_V3_LSTRUCT_THRESH)
+ vbytes =
+ sizeof (struct ctf_member_v3) * vlen;
+ else
+ vbytes =
+ sizeof (struct ctf_lmember_v3) * vlen;
+ }
break;
case CTF_K_ENUM:
vbytes = sizeof (ctf_enum_t) * vlen;
@@ -610,7 +717,7 @@
return (EIO);
}
*xp = (uint32_t)((uintptr_t) tp - (uintptr_t) ctfdata);
- tp = (ctf_type_t *)((uintptr_t)tp + increment + vbytes);
+ tp = (const void *)((uintptr_t)tp + increment + vbytes);
}
return (0);
@@ -748,10 +855,10 @@
}
}
-static const ctf_type_t *
+static const void *
ctf_lookup_by_id(linker_ctf_t *lc, ctf_id_t type)
{
- const ctf_type_t *tp;
+ const void *tp;
uint32_t offset;
uint32_t *typoff = *lc->typoffp;
@@ -766,7 +873,7 @@
return(NULL);
}
- tp = (const ctf_type_t *)(lc->ctftab + offset + sizeof(ctf_header_t));
+ tp = (const void *) (lc->ctftab + offset + sizeof(ctf_header_t));
return (tp);
}
@@ -775,24 +882,36 @@
fbt_array_info(linker_ctf_t *lc, ctf_id_t type, ctf_arinfo_t *arp)
{
const ctf_header_t *hp = (const ctf_header_t *) lc->ctftab;
- const ctf_type_t *tp;
- const ctf_array_t *ap;
+ const void *tp;
ssize_t increment;
+ uint_t kind;
bzero(arp, sizeof(*arp));
if ((tp = ctf_lookup_by_id(lc, type)) == NULL)
return;
- if (CTF_INFO_KIND(tp->ctt_info) != CTF_K_ARRAY)
+ fbt_get_ctt_info(hp->cth_version, tp, &kind, NULL, NULL);
+ if (kind != CTF_K_ARRAY)
return;
(void) fbt_get_ctt_size(hp->cth_version, tp, NULL, &increment);
- ap = (const ctf_array_t *)((uintptr_t)tp + increment);
- arp->ctr_contents = ap->cta_contents;
- arp->ctr_index = ap->cta_index;
- arp->ctr_nelems = ap->cta_nelems;
+ if (hp->cth_version == CTF_VERSION_2) {
+ const struct ctf_array_v2 *ap;
+
+ ap = (const struct ctf_array_v2 *)((uintptr_t)tp + increment);
+ arp->ctr_contents = ap->cta_contents;
+ arp->ctr_index = ap->cta_index;
+ arp->ctr_nelems = ap->cta_nelems;
+ } else {
+ const struct ctf_array_v3 *ap;
+
+ ap = (const struct ctf_array_v3 *)((uintptr_t)tp + increment);
+ arp->ctr_contents = ap->cta_contents;
+ arp->ctr_index = ap->cta_index;
+ arp->ctr_nelems = ap->cta_nelems;
+ }
}
static const char *
@@ -809,15 +928,35 @@
return (strp);
}
+static const char *
+ctf_type_rname(linker_ctf_t *lc, const void *v)
+{
+ const ctf_header_t *hp = (const ctf_header_t *) lc->ctftab;
+ uint_t name;
+
+ if (hp->cth_version == CTF_VERSION_2) {
+ const struct ctf_type_v2 *ctt = v;
+
+ name = ctt->ctt_name;
+ } else {
+ const struct ctf_type_v3 *ctt = v;
+
+ name = ctt->ctt_name;
+ }
+
+ return (ctf_strptr(lc, name));
+}
+
static void
ctf_decl_push(ctf_decl_t *cd, linker_ctf_t *lc, ctf_id_t type)
{
+ const ctf_header_t *hp = (const ctf_header_t *) lc->ctftab;
ctf_decl_node_t *cdp;
ctf_decl_prec_t prec;
- uint_t kind, n = 1;
+ uint_t kind, n = 1, t;
int is_qual = 0;
- const ctf_type_t *tp;
+ const void *tp;
ctf_arinfo_t ar;
if ((tp = ctf_lookup_by_id(lc, type)) == NULL) {
@@ -825,7 +964,10 @@
return;
}
- switch (kind = CTF_INFO_KIND(tp->ctt_info)) {
+ fbt_get_ctt_info(hp->cth_version, tp, &kind, NULL, NULL);
+ fbt_get_ctt_index(hp->cth_version, tp, NULL, &t, NULL);
+
+ switch (kind) {
case CTF_K_ARRAY:
fbt_array_info(lc, type, &ar);
ctf_decl_push(cd, lc, ar.ctr_contents);
@@ -834,27 +976,27 @@
break;
case CTF_K_TYPEDEF:
- if (ctf_strptr(lc, tp->ctt_name)[0] == '\0') {
- ctf_decl_push(cd, lc, tp->ctt_type);
+ if (ctf_type_rname(lc, tp)[0] == '\0') {
+ ctf_decl_push(cd, lc, t);
return;
}
prec = CTF_PREC_BASE;
break;
case CTF_K_FUNCTION:
- ctf_decl_push(cd, lc, tp->ctt_type);
+ ctf_decl_push(cd, lc, t);
prec = CTF_PREC_FUNCTION;
break;
case CTF_K_POINTER:
- ctf_decl_push(cd, lc, tp->ctt_type);
+ ctf_decl_push(cd, lc, t);
prec = CTF_PREC_POINTER;
break;
case CTF_K_VOLATILE:
case CTF_K_CONST:
case CTF_K_RESTRICT:
- ctf_decl_push(cd, lc, tp->ctt_type);
+ ctf_decl_push(cd, lc, t);
prec = cd->cd_qualp;
is_qual++;
break;
@@ -943,9 +1085,8 @@
for (cdp = ctf_list_next(&cd.cd_nodes[prec]);
cdp != NULL; cdp = ctf_list_next(cdp)) {
- const ctf_type_t *tp =
- ctf_lookup_by_id(lc, cdp->cd_type);
- const char *name = ctf_strptr(lc, tp->ctt_name);
+ const void *tp = ctf_lookup_by_id(lc, cdp->cd_type);
+ const char *name = ctf_type_rname(lc, tp);
if (k != CTF_K_POINTER && k != CTF_K_ARRAY)
ctf_decl_sprintf(&cd, " ");
@@ -1005,15 +1146,18 @@
static void
fbt_getargdesc(void *arg __unused, dtrace_id_t id __unused, void *parg, dtrace_argdesc_t *desc)
{
- const ushort_t *dp;
+ const ctf_header_t *hp;
+ const char *dp;
fbt_probe_t *fbt = parg;
linker_ctf_t lc;
modctl_t *ctl = fbt->fbtp_ctl;
+ size_t idwidth;
int ndx = desc->dtargd_ndx;
int symindx = fbt->fbtp_symindx;
uint32_t *ctfoff;
- uint32_t offset;
- ushort_t info, kind, n;
+ uint32_t offset, type;
+ uint_t info, n;
+ ushort_t kind;
if (fbt->fbtp_roffset != 0 && desc->dtargd_ndx == 0) {
(void) strcpy(desc->dtargd_native, "int");
@@ -1054,11 +1198,20 @@
if ((offset = ctfoff[symindx]) == 0xffffffff)
return;
- dp = (const ushort_t *)(lc.ctftab + offset + sizeof(ctf_header_t));
+ hp = (const ctf_header_t *) lc.ctftab;
+ idwidth = hp->cth_version == CTF_VERSION_2 ? 2 : 4;
+ dp = (const char *)(lc.ctftab + offset + sizeof(ctf_header_t));
- info = *dp++;
- kind = CTF_INFO_KIND(info);
- n = CTF_INFO_VLEN(info);
+ info = 0;
+ memcpy(&info, dp, idwidth);
+ dp += idwidth;
+ if (hp->cth_version == CTF_VERSION_2) {
+ kind = CTF_V2_INFO_KIND(info);
+ n = CTF_V2_INFO_VLEN(info);
+ } else {
+ kind = CTF_V3_INFO_KIND(info);
+ n = CTF_V3_INFO_VLEN(info);
+ }
if (kind == CTF_K_UNKNOWN && n == 0) {
printf("%s(%d): Unknown function!\n",__func__,__LINE__);
@@ -1081,13 +1234,13 @@
return;
/* Skip the return type and arguments up to the one requested. */
- dp += ndx + 1;
+ dp += idwidth * (ndx + 1);
}
- if (fbt_type_name(&lc, *dp, desc->dtargd_native, sizeof(desc->dtargd_native)) > 0)
+ type = 0;
+ memcpy(&type, dp, idwidth);
+ if (fbt_type_name(&lc, type, desc->dtargd_native, sizeof(desc->dtargd_native)) > 0)
desc->dtargd_ndx = ndx;
-
- return;
}
static int
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Wed, Apr 30, 1:04 AM (16 h, 7 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
17849271
Default Alt Text
D34361.diff (14 KB)
Attached To
Mode
D34361: fbt: Add support for CTFv3 containers
Attached
Detach File
Event Timeline
Log In to Comment