mirror of
https://git.FreeBSD.org/src.git
synced 2025-01-23 16:01:42 +00:00
libctf: Handle CTFv3 containers
In general, the patch adds indirection to minimize the amount of code that needs to know about differences between v2 and v3. Specifically, some new ctf_get_ctt_* functions are added, and new LCTF_* macros are added to use the underlying container's version to do the right thing. CTF containers can have parent/child relationships, wherein a type ID in one container refers to a type in the parent. It is permitted for the parent and child to have different versions. MFC after: 1 month Sponsored by: The FreeBSD Foundation Differential Revision: https://reviews.freebsd.org/D34363
This commit is contained in:
parent
8dbae4ce32
commit
a6fb869173
cddl/contrib/opensolaris
common/ctf
lib/libctf/common
@ -87,48 +87,85 @@ ctf_create(int *errp)
|
||||
}
|
||||
|
||||
static uchar_t *
|
||||
ctf_copy_smembers(ctf_dtdef_t *dtd, uint_t soff, uchar_t *t)
|
||||
ctf_copy_smembers(const ctf_file_t *fp, ctf_dtdef_t *dtd, uint_t soff,
|
||||
uchar_t *t)
|
||||
{
|
||||
ctf_dmdef_t *dmd = ctf_list_next(&dtd->dtd_u.dtu_members);
|
||||
ctf_member_t ctm;
|
||||
size_t sz;
|
||||
uint_t name;
|
||||
|
||||
for (; dmd != NULL; dmd = ctf_list_next(dmd)) {
|
||||
if (dmd->dmd_name) {
|
||||
ctm.ctm_name = soff;
|
||||
name = soff;
|
||||
soff += strlen(dmd->dmd_name) + 1;
|
||||
} else
|
||||
ctm.ctm_name = 0;
|
||||
name = 0;
|
||||
|
||||
ctm.ctm_type = (ushort_t)dmd->dmd_type;
|
||||
ctm.ctm_offset = (ushort_t)dmd->dmd_offset;
|
||||
if (fp->ctf_version == CTF_VERSION_2) {
|
||||
struct ctf_member_v2 ctm;
|
||||
|
||||
bcopy(&ctm, t, sizeof (ctm));
|
||||
t += sizeof (ctm);
|
||||
ctm.ctm_name = name;
|
||||
ctm.ctm_type = (ushort_t)dmd->dmd_type;
|
||||
ctm.ctm_offset = (ushort_t)dmd->dmd_offset;
|
||||
|
||||
sz = sizeof (ctm);
|
||||
bcopy(&ctm, t, sz);
|
||||
t += sz;
|
||||
} else {
|
||||
struct ctf_member_v3 ctm;
|
||||
|
||||
ctm.ctm_name = name;
|
||||
ctm.ctm_type = dmd->dmd_type;
|
||||
ctm.ctm_offset = dmd->dmd_offset;
|
||||
|
||||
sz = sizeof (ctm);
|
||||
bcopy(&ctm, t, sz);
|
||||
t += sz;
|
||||
}
|
||||
}
|
||||
|
||||
return (t);
|
||||
}
|
||||
|
||||
static uchar_t *
|
||||
ctf_copy_lmembers(ctf_dtdef_t *dtd, uint_t soff, uchar_t *t)
|
||||
ctf_copy_lmembers(const ctf_file_t *fp, ctf_dtdef_t *dtd, uint_t soff,
|
||||
uchar_t *t)
|
||||
{
|
||||
ctf_dmdef_t *dmd = ctf_list_next(&dtd->dtd_u.dtu_members);
|
||||
ctf_lmember_t ctlm;
|
||||
size_t sz;
|
||||
uint_t name;
|
||||
|
||||
for (; dmd != NULL; dmd = ctf_list_next(dmd)) {
|
||||
if (dmd->dmd_name) {
|
||||
ctlm.ctlm_name = soff;
|
||||
name = soff;
|
||||
soff += strlen(dmd->dmd_name) + 1;
|
||||
} else
|
||||
ctlm.ctlm_name = 0;
|
||||
name = 0;
|
||||
|
||||
ctlm.ctlm_type = (ushort_t)dmd->dmd_type;
|
||||
ctlm.ctlm_pad = 0;
|
||||
ctlm.ctlm_offsethi = CTF_OFFSET_TO_LMEMHI(dmd->dmd_offset);
|
||||
ctlm.ctlm_offsetlo = CTF_OFFSET_TO_LMEMLO(dmd->dmd_offset);
|
||||
if (fp->ctf_version == CTF_VERSION_2) {
|
||||
struct ctf_lmember_v2 ctlm;
|
||||
|
||||
bcopy(&ctlm, t, sizeof (ctlm));
|
||||
t += sizeof (ctlm);
|
||||
ctlm.ctlm_name = name;
|
||||
ctlm.ctlm_type = (ushort_t)dmd->dmd_type;
|
||||
ctlm.ctlm_pad = 0;
|
||||
ctlm.ctlm_offsethi = CTF_OFFSET_TO_LMEMHI(dmd->dmd_offset);
|
||||
ctlm.ctlm_offsetlo = CTF_OFFSET_TO_LMEMLO(dmd->dmd_offset);
|
||||
|
||||
sz = sizeof (ctlm);
|
||||
bcopy(&ctlm, t, sz);
|
||||
t += sz;
|
||||
} else {
|
||||
struct ctf_lmember_v3 ctlm;
|
||||
|
||||
ctlm.ctlm_name = name;
|
||||
ctlm.ctlm_type = dmd->dmd_type;
|
||||
ctlm.ctlm_offsethi = CTF_OFFSET_TO_LMEMHI(dmd->dmd_offset);
|
||||
ctlm.ctlm_offsetlo = CTF_OFFSET_TO_LMEMLO(dmd->dmd_offset);
|
||||
|
||||
sz = sizeof (ctlm);
|
||||
bcopy(&ctlm, t, sz);
|
||||
t += sz;
|
||||
}
|
||||
}
|
||||
|
||||
return (t);
|
||||
@ -259,7 +296,7 @@ ctf_update(ctf_file_t *fp)
|
||||
*/
|
||||
bzero(&hdr, sizeof (hdr));
|
||||
hdr.cth_magic = CTF_MAGIC;
|
||||
hdr.cth_version = CTF_VERSION;
|
||||
hdr.cth_version = fp->ctf_version;
|
||||
|
||||
if (fp->ctf_flags & LCTF_CHILD)
|
||||
hdr.cth_parname = 1; /* i.e. _CTF_STRTAB_TEMPLATE[1] */
|
||||
@ -271,13 +308,20 @@ ctf_update(ctf_file_t *fp)
|
||||
for (size = 0, dtd = ctf_list_next(&fp->ctf_dtdefs);
|
||||
dtd != NULL; dtd = ctf_list_next(dtd)) {
|
||||
|
||||
uint_t kind = CTF_INFO_KIND(dtd->dtd_data.ctt_info);
|
||||
uint_t vlen = CTF_INFO_VLEN(dtd->dtd_data.ctt_info);
|
||||
uint_t kind = LCTF_INFO_KIND(fp, dtd->dtd_data.ctt_info);
|
||||
uint_t vlen = LCTF_INFO_VLEN(fp, dtd->dtd_data.ctt_info);
|
||||
|
||||
if (dtd->dtd_data.ctt_size != CTF_LSIZE_SENT)
|
||||
size += sizeof (ctf_stype_t);
|
||||
else
|
||||
size += sizeof (ctf_type_t);
|
||||
if (fp->ctf_version == CTF_VERSION_2) {
|
||||
if (dtd->dtd_data.ctt_size != CTF_V2_LSIZE_SENT)
|
||||
size += sizeof (struct ctf_stype_v2);
|
||||
else
|
||||
size += sizeof (struct ctf_type_v2);
|
||||
} else {
|
||||
if (dtd->dtd_data.ctt_size != LCTF_LSIZE_SENT(fp))
|
||||
size += sizeof (struct ctf_stype_v3);
|
||||
else
|
||||
size += sizeof (struct ctf_type_v3);
|
||||
}
|
||||
|
||||
switch (kind) {
|
||||
case CTF_K_INTEGER:
|
||||
@ -285,17 +329,32 @@ ctf_update(ctf_file_t *fp)
|
||||
size += sizeof (uint_t);
|
||||
break;
|
||||
case CTF_K_ARRAY:
|
||||
size += sizeof (ctf_array_t);
|
||||
size += fp->ctf_version == CTF_VERSION_2 ?
|
||||
sizeof (struct ctf_array_v2) :
|
||||
sizeof (struct ctf_array_v3);
|
||||
break;
|
||||
case CTF_K_FUNCTION:
|
||||
size += sizeof (ushort_t) * (vlen + (vlen & 1));
|
||||
size += roundup2(fp->ctf_idwidth * vlen, 4);
|
||||
break;
|
||||
case CTF_K_STRUCT:
|
||||
case CTF_K_UNION:
|
||||
if (dtd->dtd_data.ctt_size < CTF_LSTRUCT_THRESH)
|
||||
size += sizeof (ctf_member_t) * vlen;
|
||||
else
|
||||
size += sizeof (ctf_lmember_t) * vlen;
|
||||
if (fp->ctf_version == CTF_VERSION_2) {
|
||||
if (dtd->dtd_data.ctt_size <
|
||||
LCTF_LSTRUCT_THRESH(fp))
|
||||
size += sizeof (struct ctf_member_v2) *
|
||||
vlen;
|
||||
else
|
||||
size += sizeof (struct ctf_lmember_v2) *
|
||||
vlen;
|
||||
} else {
|
||||
if (dtd->dtd_data.ctt_size <
|
||||
LCTF_LSTRUCT_THRESH(fp))
|
||||
size += sizeof (struct ctf_member_v3) *
|
||||
vlen;
|
||||
else
|
||||
size += sizeof (struct ctf_lmember_v3) *
|
||||
vlen;
|
||||
}
|
||||
break;
|
||||
case CTF_K_ENUM:
|
||||
size += sizeof (ctf_enum_t) * vlen;
|
||||
@ -328,11 +387,11 @@ ctf_update(ctf_file_t *fp)
|
||||
*/
|
||||
for (dtd = ctf_list_next(&fp->ctf_dtdefs);
|
||||
dtd != NULL; dtd = ctf_list_next(dtd)) {
|
||||
void *tp;
|
||||
uint_t kind = LCTF_INFO_KIND(fp, dtd->dtd_data.ctt_info);
|
||||
uint_t vlen = LCTF_INFO_VLEN(fp, dtd->dtd_data.ctt_info);
|
||||
struct ctf_type_v2 ctt;
|
||||
|
||||
uint_t kind = CTF_INFO_KIND(dtd->dtd_data.ctt_info);
|
||||
uint_t vlen = CTF_INFO_VLEN(dtd->dtd_data.ctt_info);
|
||||
|
||||
ctf_array_t cta;
|
||||
uint_t encoding;
|
||||
size_t len;
|
||||
|
||||
@ -344,12 +403,27 @@ ctf_update(ctf_file_t *fp)
|
||||
} else
|
||||
dtd->dtd_data.ctt_name = 0;
|
||||
|
||||
if (dtd->dtd_data.ctt_size != CTF_LSIZE_SENT)
|
||||
len = sizeof (ctf_stype_t);
|
||||
else
|
||||
len = sizeof (ctf_type_t);
|
||||
if (fp->ctf_version == CTF_VERSION_2) {
|
||||
ctt.ctt_name = dtd->dtd_data.ctt_name;
|
||||
ctt.ctt_info = (ushort_t)dtd->dtd_data.ctt_info;
|
||||
ctt.ctt_size = (ushort_t)dtd->dtd_data.ctt_size;
|
||||
if (dtd->dtd_data.ctt_size != CTF_V2_LSIZE_SENT)
|
||||
len = sizeof (struct ctf_stype_v2);
|
||||
else {
|
||||
len = sizeof (struct ctf_type_v2);
|
||||
ctt.ctt_lsizehi = dtd->dtd_data.ctt_lsizehi;
|
||||
ctt.ctt_lsizelo = dtd->dtd_data.ctt_lsizelo;
|
||||
}
|
||||
tp = &ctt;
|
||||
} else {
|
||||
if (dtd->dtd_data.ctt_size != LCTF_LSIZE_SENT(fp))
|
||||
len = sizeof (struct ctf_stype_v3);
|
||||
else
|
||||
len = sizeof (struct ctf_type_v3);
|
||||
tp = &dtd->dtd_data;
|
||||
}
|
||||
|
||||
bcopy(&dtd->dtd_data, t, len);
|
||||
bcopy(tp, t, len);
|
||||
t += len;
|
||||
|
||||
switch (kind) {
|
||||
@ -371,24 +445,52 @@ ctf_update(ctf_file_t *fp)
|
||||
break;
|
||||
|
||||
case CTF_K_ARRAY:
|
||||
cta.cta_contents = (ushort_t)
|
||||
dtd->dtd_u.dtu_arr.ctr_contents;
|
||||
cta.cta_index = (ushort_t)
|
||||
dtd->dtd_u.dtu_arr.ctr_index;
|
||||
cta.cta_nelems = dtd->dtd_u.dtu_arr.ctr_nelems;
|
||||
bcopy(&cta, t, sizeof (cta));
|
||||
t += sizeof (cta);
|
||||
if (fp->ctf_version == CTF_VERSION_2) {
|
||||
struct ctf_array_v2 cta;
|
||||
|
||||
cta.cta_contents =
|
||||
(uint16_t)dtd->dtd_u.dtu_arr.ctr_contents;
|
||||
cta.cta_index =
|
||||
(uint16_t)dtd->dtd_u.dtu_arr.ctr_index;
|
||||
cta.cta_nelems = dtd->dtd_u.dtu_arr.ctr_nelems;
|
||||
|
||||
bcopy(&cta, t, sizeof (cta));
|
||||
t += sizeof (cta);
|
||||
} else {
|
||||
struct ctf_array_v3 cta;
|
||||
|
||||
cta.cta_contents =
|
||||
dtd->dtd_u.dtu_arr.ctr_contents;
|
||||
cta.cta_index = dtd->dtd_u.dtu_arr.ctr_index;
|
||||
cta.cta_nelems = dtd->dtd_u.dtu_arr.ctr_nelems;
|
||||
|
||||
bcopy(&cta, t, sizeof (cta));
|
||||
t += sizeof (cta);
|
||||
}
|
||||
break;
|
||||
|
||||
case CTF_K_FUNCTION: {
|
||||
ushort_t *argv = (ushort_t *)(uintptr_t)t;
|
||||
char *argv = (char *)(uintptr_t)t;
|
||||
uint_t argc;
|
||||
|
||||
for (argc = 0; argc < vlen; argc++)
|
||||
*argv++ = (ushort_t)dtd->dtd_u.dtu_argv[argc];
|
||||
if (fp->ctf_version == CTF_VERSION_2) {
|
||||
ushort_t arg;
|
||||
|
||||
if (vlen & 1)
|
||||
*argv++ = 0; /* pad to 4-byte boundary */
|
||||
for (argc = 0; argc < vlen;
|
||||
argc++, argv += sizeof(arg)) {
|
||||
arg =
|
||||
(ushort_t)dtd->dtd_u.dtu_argv[argc];
|
||||
memcpy(argv, &arg, sizeof(arg));
|
||||
}
|
||||
} else {
|
||||
uint_t arg;
|
||||
|
||||
for (argc = 0; argc < vlen;
|
||||
argc++, argv += sizeof(arg)) {
|
||||
arg = (uint_t)dtd->dtd_u.dtu_argv[argc];
|
||||
memcpy(argv, &arg, sizeof(arg));
|
||||
}
|
||||
}
|
||||
|
||||
t = (uchar_t *)argv;
|
||||
break;
|
||||
@ -396,10 +498,12 @@ ctf_update(ctf_file_t *fp)
|
||||
|
||||
case CTF_K_STRUCT:
|
||||
case CTF_K_UNION:
|
||||
if (dtd->dtd_data.ctt_size < CTF_LSTRUCT_THRESH)
|
||||
t = ctf_copy_smembers(dtd, (uint_t)(s - s0), t);
|
||||
if (dtd->dtd_data.ctt_size < LCTF_LSTRUCT_THRESH(fp))
|
||||
t = ctf_copy_smembers(fp, dtd, (uint_t)(s - s0),
|
||||
t);
|
||||
else
|
||||
t = ctf_copy_lmembers(dtd, (uint_t)(s - s0), t);
|
||||
t = ctf_copy_lmembers(fp, dtd, (uint_t)(s - s0),
|
||||
t);
|
||||
s = ctf_copy_membnames(dtd, s);
|
||||
break;
|
||||
|
||||
@ -495,7 +599,7 @@ ctf_dtd_delete(ctf_file_t *fp, ctf_dtdef_t *dtd)
|
||||
if (p != NULL)
|
||||
*q = p->dtd_hash;
|
||||
|
||||
kind = CTF_INFO_KIND(dtd->dtd_data.ctt_info);
|
||||
kind = LCTF_INFO_KIND(fp, dtd->dtd_data.ctt_info);
|
||||
switch (kind) {
|
||||
case CTF_K_STRUCT:
|
||||
case CTF_K_UNION:
|
||||
@ -515,11 +619,11 @@ ctf_dtd_delete(ctf_file_t *fp, ctf_dtdef_t *dtd)
|
||||
break;
|
||||
case CTF_K_FUNCTION:
|
||||
ctf_ref_dec(fp, dtd->dtd_data.ctt_type);
|
||||
for (i = 0; i < CTF_INFO_VLEN(dtd->dtd_data.ctt_info); i++)
|
||||
for (i = 0; i < LCTF_INFO_VLEN(fp, dtd->dtd_data.ctt_info); i++)
|
||||
if (dtd->dtd_u.dtu_argv[i] != 0)
|
||||
ctf_ref_dec(fp, dtd->dtd_u.dtu_argv[i]);
|
||||
ctf_free(dtd->dtd_u.dtu_argv, sizeof (ctf_id_t) *
|
||||
CTF_INFO_VLEN(dtd->dtd_data.ctt_info));
|
||||
LCTF_INFO_VLEN(fp, dtd->dtd_data.ctt_info));
|
||||
break;
|
||||
case CTF_K_ARRAY:
|
||||
ctf_ref_dec(fp, dtd->dtd_u.dtu_arr.ctr_contents);
|
||||
@ -584,7 +688,7 @@ ctf_discard(ctf_file_t *fp)
|
||||
|
||||
for (dtd = ctf_list_prev(&fp->ctf_dtdefs); dtd != NULL; dtd = ntd) {
|
||||
ntd = ctf_list_prev(dtd);
|
||||
if (CTF_TYPE_TO_INDEX(dtd->dtd_type) <= fp->ctf_dtoldid)
|
||||
if (LCTF_TYPE_TO_INDEX(fp, dtd->dtd_type) <= fp->ctf_dtoldid)
|
||||
continue; /* skip types that have been committed */
|
||||
|
||||
ctf_dtd_delete(fp, dtd);
|
||||
@ -609,7 +713,7 @@ ctf_add_generic(ctf_file_t *fp, uint_t flag, const char *name, ctf_dtdef_t **rp)
|
||||
if (!(fp->ctf_flags & LCTF_RDWR))
|
||||
return (ctf_set_errno(fp, ECTF_RDONLY));
|
||||
|
||||
if (CTF_INDEX_TO_TYPE(fp->ctf_dtnextid, 1) > CTF_MAX_TYPE)
|
||||
if (LCTF_INDEX_TO_TYPE(fp, fp->ctf_dtnextid, 1) > LCTF_MAX_TYPE(fp))
|
||||
return (ctf_set_errno(fp, ECTF_FULL));
|
||||
|
||||
if ((dtd = ctf_alloc(sizeof (ctf_dtdef_t))) == NULL)
|
||||
@ -621,7 +725,7 @@ ctf_add_generic(ctf_file_t *fp, uint_t flag, const char *name, ctf_dtdef_t **rp)
|
||||
}
|
||||
|
||||
type = fp->ctf_dtnextid++;
|
||||
type = CTF_INDEX_TO_TYPE(type, (fp->ctf_flags & LCTF_CHILD));
|
||||
type = LCTF_INDEX_TO_TYPE(fp, type, (fp->ctf_flags & LCTF_CHILD));
|
||||
|
||||
bzero(dtd, sizeof (ctf_dtdef_t));
|
||||
dtd->dtd_name = s;
|
||||
@ -669,7 +773,7 @@ ctf_add_encoded(ctf_file_t *fp, uint_t flag,
|
||||
if ((type = ctf_add_generic(fp, flag, name, &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_info = LCTF_TYPE_INFO(fp, kind, flag, 0);
|
||||
dtd->dtd_data.ctt_size = clp2(P2ROUNDUP(ep->cte_bits, NBBY) / NBBY);
|
||||
dtd->dtd_u.dtu_enc = *ep;
|
||||
|
||||
@ -682,7 +786,7 @@ ctf_add_reftype(ctf_file_t *fp, uint_t flag, ctf_id_t ref, uint_t kind)
|
||||
ctf_dtdef_t *dtd;
|
||||
ctf_id_t type;
|
||||
|
||||
if (ref == CTF_ERR || ref < 0 || ref > CTF_MAX_TYPE)
|
||||
if (ref == CTF_ERR || ref > LCTF_MAX_TYPE(fp))
|
||||
return (ctf_set_errno(fp, EINVAL));
|
||||
|
||||
if ((type = ctf_add_generic(fp, flag, NULL, &dtd)) == CTF_ERR)
|
||||
@ -690,8 +794,8 @@ ctf_add_reftype(ctf_file_t *fp, uint_t flag, ctf_id_t ref, uint_t kind)
|
||||
|
||||
ctf_ref_inc(fp, ref);
|
||||
|
||||
dtd->dtd_data.ctt_info = CTF_TYPE_INFO(kind, flag, 0);
|
||||
dtd->dtd_data.ctt_type = (ushort_t)ref;
|
||||
dtd->dtd_data.ctt_info = LCTF_TYPE_INFO(fp, kind, flag, 0);
|
||||
dtd->dtd_data.ctt_type = (uint_t)ref;
|
||||
|
||||
return (type);
|
||||
}
|
||||
@ -739,7 +843,7 @@ ctf_add_array(ctf_file_t *fp, uint_t flag, const ctf_arinfo_t *arp)
|
||||
if ((type = ctf_add_generic(fp, flag, NULL, &dtd)) == CTF_ERR)
|
||||
return (CTF_ERR); /* errno is set for us */
|
||||
|
||||
dtd->dtd_data.ctt_info = CTF_TYPE_INFO(CTF_K_ARRAY, flag, 0);
|
||||
dtd->dtd_data.ctt_info = LCTF_TYPE_INFO(fp, CTF_K_ARRAY, flag, 0);
|
||||
dtd->dtd_data.ctt_size = 0;
|
||||
dtd->dtd_u.dtu_arr = *arp;
|
||||
ctf_ref_inc(fp, arp->ctr_contents);
|
||||
@ -757,7 +861,8 @@ ctf_set_array(ctf_file_t *fp, ctf_id_t type, const ctf_arinfo_t *arp)
|
||||
if (!(fp->ctf_flags & LCTF_RDWR))
|
||||
return (ctf_set_errno(fp, ECTF_RDONLY));
|
||||
|
||||
if (dtd == NULL || CTF_INFO_KIND(dtd->dtd_data.ctt_info) != CTF_K_ARRAY)
|
||||
if (dtd == NULL ||
|
||||
LCTF_INFO_KIND(fp, dtd->dtd_data.ctt_info) != CTF_K_ARRAY)
|
||||
return (ctf_set_errno(fp, ECTF_BADID));
|
||||
|
||||
fpd = fp;
|
||||
@ -799,7 +904,7 @@ ctf_add_function(ctf_file_t *fp, uint_t flag,
|
||||
if (ctc->ctc_flags & CTF_FUNC_VARARG)
|
||||
vlen++; /* add trailing zero to indicate varargs (see below) */
|
||||
|
||||
if (vlen > CTF_MAX_VLEN)
|
||||
if (vlen > LCTF_MAX_VLEN(fp))
|
||||
return (ctf_set_errno(fp, EOVERFLOW));
|
||||
|
||||
fpd = fp;
|
||||
@ -822,8 +927,8 @@ ctf_add_function(ctf_file_t *fp, uint_t flag,
|
||||
return (CTF_ERR); /* errno is set for us */
|
||||
}
|
||||
|
||||
dtd->dtd_data.ctt_info = CTF_TYPE_INFO(CTF_K_FUNCTION, flag, vlen);
|
||||
dtd->dtd_data.ctt_type = (ushort_t)ctc->ctc_return;
|
||||
dtd->dtd_data.ctt_info = LCTF_TYPE_INFO(fp, CTF_K_FUNCTION, flag, vlen);
|
||||
dtd->dtd_data.ctt_type = ctc->ctc_return;
|
||||
|
||||
ctf_ref_inc(fp, ctc->ctc_return);
|
||||
for (i = 0; i < ctc->ctc_argc; i++)
|
||||
@ -853,7 +958,7 @@ ctf_add_struct(ctf_file_t *fp, uint_t flag, const char *name)
|
||||
else if ((type = ctf_add_generic(fp, flag, name, &dtd)) == CTF_ERR)
|
||||
return (CTF_ERR); /* errno is set for us */
|
||||
|
||||
dtd->dtd_data.ctt_info = CTF_TYPE_INFO(CTF_K_STRUCT, flag, 0);
|
||||
dtd->dtd_data.ctt_info = LCTF_TYPE_INFO(fp, CTF_K_STRUCT, flag, 0);
|
||||
dtd->dtd_data.ctt_size = 0;
|
||||
|
||||
return (type);
|
||||
@ -875,7 +980,7 @@ ctf_add_union(ctf_file_t *fp, uint_t flag, const char *name)
|
||||
else if ((type = ctf_add_generic(fp, flag, name, &dtd)) == CTF_ERR)
|
||||
return (CTF_ERR); /* errno is set for us */
|
||||
|
||||
dtd->dtd_data.ctt_info = CTF_TYPE_INFO(CTF_K_UNION, flag, 0);
|
||||
dtd->dtd_data.ctt_info = LCTF_TYPE_INFO(fp, CTF_K_UNION, flag, 0);
|
||||
dtd->dtd_data.ctt_size = 0;
|
||||
|
||||
return (type);
|
||||
@ -897,7 +1002,7 @@ ctf_add_enum(ctf_file_t *fp, uint_t flag, const char *name)
|
||||
else if ((type = ctf_add_generic(fp, flag, name, &dtd)) == CTF_ERR)
|
||||
return (CTF_ERR); /* errno is set for us */
|
||||
|
||||
dtd->dtd_data.ctt_info = CTF_TYPE_INFO(CTF_K_ENUM, flag, 0);
|
||||
dtd->dtd_data.ctt_info = LCTF_TYPE_INFO(fp, CTF_K_ENUM, flag, 0);
|
||||
dtd->dtd_data.ctt_size = fp->ctf_dmodel->ctd_int;
|
||||
|
||||
return (type);
|
||||
@ -936,7 +1041,7 @@ ctf_add_forward(ctf_file_t *fp, uint_t flag, const char *name, uint_t kind)
|
||||
if ((type = ctf_add_generic(fp, flag, name, &dtd)) == CTF_ERR)
|
||||
return (CTF_ERR); /* errno is set for us */
|
||||
|
||||
dtd->dtd_data.ctt_info = CTF_TYPE_INFO(CTF_K_FORWARD, flag, 0);
|
||||
dtd->dtd_data.ctt_info = LCTF_TYPE_INFO(fp, CTF_K_FORWARD, flag, 0);
|
||||
dtd->dtd_data.ctt_type = kind;
|
||||
|
||||
return (type);
|
||||
@ -957,8 +1062,8 @@ ctf_add_typedef(ctf_file_t *fp, uint_t flag, const char *name, ctf_id_t ref)
|
||||
if ((type = ctf_add_generic(fp, flag, name, &dtd)) == CTF_ERR)
|
||||
return (CTF_ERR); /* errno is set for us */
|
||||
|
||||
dtd->dtd_data.ctt_info = CTF_TYPE_INFO(CTF_K_TYPEDEF, flag, 0);
|
||||
dtd->dtd_data.ctt_type = (ushort_t)ref;
|
||||
dtd->dtd_data.ctt_info = LCTF_TYPE_INFO(fp, CTF_K_TYPEDEF, flag, 0);
|
||||
dtd->dtd_data.ctt_type = ref;
|
||||
ctf_ref_inc(fp, ref);
|
||||
|
||||
return (type);
|
||||
@ -1000,14 +1105,14 @@ ctf_add_enumerator(ctf_file_t *fp, ctf_id_t enid, const char *name, int value)
|
||||
if (dtd == NULL)
|
||||
return (ctf_set_errno(fp, ECTF_BADID));
|
||||
|
||||
kind = CTF_INFO_KIND(dtd->dtd_data.ctt_info);
|
||||
root = CTF_INFO_ISROOT(dtd->dtd_data.ctt_info);
|
||||
vlen = CTF_INFO_VLEN(dtd->dtd_data.ctt_info);
|
||||
kind = LCTF_INFO_KIND(fp, dtd->dtd_data.ctt_info);
|
||||
root = LCTF_INFO_ROOT(fp, dtd->dtd_data.ctt_info);
|
||||
vlen = LCTF_INFO_VLEN(fp, dtd->dtd_data.ctt_info);
|
||||
|
||||
if (kind != CTF_K_ENUM)
|
||||
return (ctf_set_errno(fp, ECTF_NOTENUM));
|
||||
|
||||
if (vlen == CTF_MAX_VLEN)
|
||||
if (vlen > LCTF_MAX_VLEN(fp))
|
||||
return (ctf_set_errno(fp, ECTF_DTFULL));
|
||||
|
||||
for (dmd = ctf_list_next(&dtd->dtd_u.dtu_members);
|
||||
@ -1029,7 +1134,7 @@ ctf_add_enumerator(ctf_file_t *fp, ctf_id_t enid, const char *name, int value)
|
||||
dmd->dmd_offset = 0;
|
||||
dmd->dmd_value = value;
|
||||
|
||||
dtd->dtd_data.ctt_info = CTF_TYPE_INFO(kind, root, vlen + 1);
|
||||
dtd->dtd_data.ctt_info = LCTF_TYPE_INFO(fp, kind, root, vlen + 1);
|
||||
ctf_list_append(&dtd->dtd_u.dtu_members, dmd);
|
||||
|
||||
fp->ctf_dtstrlen += strlen(s) + 1;
|
||||
@ -1054,14 +1159,14 @@ ctf_add_member(ctf_file_t *fp, ctf_id_t souid, const char *name, ctf_id_t type)
|
||||
if (dtd == NULL)
|
||||
return (ctf_set_errno(fp, ECTF_BADID));
|
||||
|
||||
kind = CTF_INFO_KIND(dtd->dtd_data.ctt_info);
|
||||
root = CTF_INFO_ISROOT(dtd->dtd_data.ctt_info);
|
||||
vlen = CTF_INFO_VLEN(dtd->dtd_data.ctt_info);
|
||||
kind = LCTF_INFO_KIND(fp, dtd->dtd_data.ctt_info);
|
||||
root = LCTF_INFO_ROOT(fp, dtd->dtd_data.ctt_info);
|
||||
vlen = LCTF_INFO_VLEN(fp, dtd->dtd_data.ctt_info);
|
||||
|
||||
if (kind != CTF_K_STRUCT && kind != CTF_K_UNION)
|
||||
return (ctf_set_errno(fp, ECTF_NOTSOU));
|
||||
|
||||
if (vlen == CTF_MAX_VLEN)
|
||||
if (vlen > LCTF_MAX_VLEN(fp))
|
||||
return (ctf_set_errno(fp, ECTF_DTFULL));
|
||||
|
||||
if (name != NULL) {
|
||||
@ -1121,14 +1226,14 @@ ctf_add_member(ctf_file_t *fp, ctf_id_t souid, const char *name, ctf_id_t type)
|
||||
ssize = MAX(ssize, msize);
|
||||
}
|
||||
|
||||
if (ssize > CTF_MAX_SIZE) {
|
||||
dtd->dtd_data.ctt_size = CTF_LSIZE_SENT;
|
||||
if (ssize > LCTF_MAX_SIZE(fp)) {
|
||||
dtd->dtd_data.ctt_size = LCTF_LSIZE_SENT(fp);
|
||||
dtd->dtd_data.ctt_lsizehi = CTF_SIZE_TO_LSIZE_HI(ssize);
|
||||
dtd->dtd_data.ctt_lsizelo = CTF_SIZE_TO_LSIZE_LO(ssize);
|
||||
} else
|
||||
dtd->dtd_data.ctt_size = (ushort_t)ssize;
|
||||
dtd->dtd_data.ctt_size = ssize;
|
||||
|
||||
dtd->dtd_data.ctt_info = CTF_TYPE_INFO(kind, root, vlen + 1);
|
||||
dtd->dtd_data.ctt_info = LCTF_TYPE_INFO(fp, kind, root, vlen + 1);
|
||||
ctf_list_append(&dtd->dtd_u.dtu_members, dmd);
|
||||
|
||||
if (s != NULL)
|
||||
@ -1233,10 +1338,10 @@ static long
|
||||
soucmp(ctf_file_t *src_fp, ctf_id_t src_type, ctf_file_t *dst_fp,
|
||||
ctf_id_t dst_type)
|
||||
{
|
||||
const ctf_type_t *src_tp, *dst_tp;
|
||||
const void *src_tp, *dst_tp;
|
||||
const char *src_name, *dst_name;
|
||||
ssize_t src_sz, dst_sz, src_inc, dst_inc;
|
||||
uint_t kind, n;
|
||||
uint_t dst_kind, dst_vlen, src_kind, src_vlen, n;
|
||||
|
||||
if ((src_type = ctf_type_resolve(src_fp, src_type)) == CTF_ERR)
|
||||
return (CTF_ERR);
|
||||
@ -1248,47 +1353,37 @@ soucmp(ctf_file_t *src_fp, ctf_id_t src_type, ctf_file_t *dst_fp,
|
||||
if ((dst_tp = ctf_lookup_by_id(&dst_fp, dst_type)) == NULL)
|
||||
return (CTF_ERR);
|
||||
|
||||
if ((kind = LCTF_INFO_KIND(src_fp, src_tp->ctt_info)) !=
|
||||
LCTF_INFO_KIND(dst_fp, dst_tp->ctt_info))
|
||||
ctf_get_ctt_info(src_fp, src_tp, &src_kind, &src_vlen, NULL);
|
||||
ctf_get_ctt_info(dst_fp, dst_tp, &dst_kind, &dst_vlen, NULL);
|
||||
|
||||
if (src_kind != dst_kind)
|
||||
return (ctf_set_errno(dst_fp, ECTF_CONFLICT));
|
||||
if (kind != CTF_K_STRUCT && kind != CTF_K_UNION)
|
||||
if (src_kind != CTF_K_STRUCT && src_kind != CTF_K_UNION)
|
||||
return (ctf_set_errno(dst_fp, ECTF_CONFLICT));
|
||||
if ((n = LCTF_INFO_VLEN(src_fp, src_tp->ctt_info)) !=
|
||||
LCTF_INFO_VLEN(dst_fp, dst_tp->ctt_info))
|
||||
if (src_vlen != dst_vlen)
|
||||
return (ctf_set_errno(dst_fp, ECTF_CONFLICT));
|
||||
|
||||
(void) ctf_get_ctt_size(src_fp, src_tp, &src_sz, &src_inc);
|
||||
(void) ctf_get_ctt_size(dst_fp, dst_tp, &dst_sz, &dst_inc);
|
||||
if (src_sz != dst_sz || src_inc != dst_inc)
|
||||
if (src_sz != dst_sz)
|
||||
return (ctf_set_errno(dst_fp, ECTF_CONFLICT));
|
||||
|
||||
if (src_sz < CTF_LSTRUCT_THRESH) {
|
||||
const ctf_member_t *src_mp, *dst_mp;
|
||||
const char *src_mp, *dst_mp;
|
||||
ulong_t src_offset, dst_offset;
|
||||
|
||||
src_mp = (const ctf_member_t *)((uintptr_t)src_tp + src_inc);
|
||||
dst_mp = (const ctf_member_t *)((uintptr_t)dst_tp + dst_inc);
|
||||
for (; n != 0; n--, src_mp++, dst_mp++) {
|
||||
if (src_mp->ctm_offset != dst_mp->ctm_offset)
|
||||
return (ctf_set_errno(dst_fp, ECTF_CONFLICT));
|
||||
src_name = ctf_strptr(src_fp, src_mp->ctm_name);
|
||||
dst_name = ctf_strptr(dst_fp, dst_mp->ctm_name);
|
||||
if (strcmp(src_name, dst_name) != 0)
|
||||
return (ctf_set_errno(dst_fp, ECTF_CONFLICT));
|
||||
}
|
||||
} else {
|
||||
const ctf_lmember_t *src_mp, *dst_mp;
|
||||
src_mp = (const char *)src_tp + src_inc;
|
||||
dst_mp = (const char *)dst_tp + dst_inc;
|
||||
for (n = src_vlen; n != 0;
|
||||
n--, src_mp += src_inc, dst_mp += dst_inc) {
|
||||
ctf_get_ctm_info(src_fp, src_mp, src_sz, &src_inc, NULL,
|
||||
&src_offset, &src_name);
|
||||
ctf_get_ctm_info(dst_fp, dst_mp, dst_sz, &dst_inc, NULL,
|
||||
&dst_offset, &dst_name);
|
||||
|
||||
src_mp = (const ctf_lmember_t *)((uintptr_t)src_tp + src_inc);
|
||||
dst_mp = (const ctf_lmember_t *)((uintptr_t)dst_tp + dst_inc);
|
||||
for (; n != 0; n--, src_mp++, dst_mp++) {
|
||||
if (src_mp->ctlm_offsethi != dst_mp->ctlm_offsethi ||
|
||||
src_mp->ctlm_offsetlo != dst_mp->ctlm_offsetlo)
|
||||
return (ctf_set_errno(dst_fp, ECTF_CONFLICT));
|
||||
src_name = ctf_strptr(src_fp, src_mp->ctlm_name);
|
||||
dst_name = ctf_strptr(dst_fp, dst_mp->ctlm_name);
|
||||
if (strcmp(src_name, dst_name) != 0)
|
||||
return (ctf_set_errno(dst_fp, ECTF_CONFLICT));
|
||||
}
|
||||
if (src_offset != dst_offset)
|
||||
return (ctf_set_errno(dst_fp, ECTF_CONFLICT));
|
||||
if (strcmp(src_name, dst_name) != 0)
|
||||
return (ctf_set_errno(dst_fp, ECTF_CONFLICT));
|
||||
}
|
||||
|
||||
return (0);
|
||||
@ -1307,9 +1402,9 @@ ctf_add_type(ctf_file_t *dst_fp, ctf_file_t *src_fp, ctf_id_t src_type)
|
||||
ctf_id_t dst_type = CTF_ERR;
|
||||
uint_t dst_kind = CTF_K_UNKNOWN;
|
||||
|
||||
const ctf_type_t *tp;
|
||||
const void *tp;
|
||||
const char *name;
|
||||
uint_t kind, flag, vlen;
|
||||
uint_t type, kind, flag, vlen;
|
||||
|
||||
ctf_bundle_t src, dst;
|
||||
ctf_encoding_t src_en, main_en, dst_en;
|
||||
@ -1331,10 +1426,9 @@ ctf_add_type(ctf_file_t *dst_fp, ctf_file_t *src_fp, ctf_id_t src_type)
|
||||
if ((tp = ctf_lookup_by_id(&src_fp, src_type)) == NULL)
|
||||
return (ctf_set_errno(dst_fp, ctf_errno(src_fp)));
|
||||
|
||||
name = ctf_strptr(src_fp, tp->ctt_name);
|
||||
kind = LCTF_INFO_KIND(src_fp, tp->ctt_info);
|
||||
flag = LCTF_INFO_ROOT(src_fp, tp->ctt_info);
|
||||
vlen = LCTF_INFO_VLEN(src_fp, tp->ctt_info);
|
||||
name = ctf_type_rname(src_fp, tp);
|
||||
|
||||
ctf_get_ctt_info(src_fp, tp, &kind, &vlen, &flag);
|
||||
|
||||
switch (kind) {
|
||||
case CTF_K_STRUCT:
|
||||
@ -1389,10 +1483,10 @@ ctf_add_type(ctf_file_t *dst_fp, ctf_file_t *src_fp, ctf_id_t src_type)
|
||||
*/
|
||||
if (dst_type == CTF_ERR && name[0] != '\0') {
|
||||
for (dtd = ctf_list_prev(&dst_fp->ctf_dtdefs); dtd != NULL &&
|
||||
CTF_TYPE_TO_INDEX(dtd->dtd_type) > dst_fp->ctf_dtoldid;
|
||||
dtd = ctf_list_prev(dtd)) {
|
||||
if (CTF_INFO_KIND(dtd->dtd_data.ctt_info) != kind ||
|
||||
dtd->dtd_name == NULL ||
|
||||
LCTF_TYPE_TO_INDEX(dst_fp, dtd->dtd_type) >
|
||||
dst_fp->ctf_dtoldid; dtd = ctf_list_prev(dtd)) {
|
||||
if (LCTF_INFO_KIND(dst_fp, dtd->dtd_data.ctt_info) !=
|
||||
kind || dtd->dtd_name == NULL ||
|
||||
strcmp(dtd->dtd_name, name) != 0)
|
||||
continue;
|
||||
if (kind == CTF_K_INTEGER || kind == CTF_K_FLOAT) {
|
||||
@ -1499,7 +1593,8 @@ ctf_add_type(ctf_file_t *dst_fp, ctf_file_t *src_fp, ctf_id_t src_type)
|
||||
break;
|
||||
|
||||
case CTF_K_FUNCTION:
|
||||
ctc.ctc_return = ctf_add_type(dst_fp, src_fp, tp->ctt_type);
|
||||
ctf_get_ctt_index(src_fp, tp, NULL, &type, NULL);
|
||||
ctc.ctc_return = ctf_add_type(dst_fp, src_fp, type);
|
||||
ctc.ctc_argc = 0;
|
||||
ctc.ctc_flags = 0;
|
||||
|
||||
@ -1541,14 +1636,16 @@ ctf_add_type(ctf_file_t *dst_fp, ctf_file_t *src_fp, ctf_id_t src_type)
|
||||
if (ctf_member_iter(src_fp, src_type, membadd, &dst) != 0)
|
||||
errs++; /* increment errs and fail at bottom of case */
|
||||
|
||||
if ((size = ctf_type_size(src_fp, src_type)) > CTF_MAX_SIZE) {
|
||||
dtd->dtd_data.ctt_size = CTF_LSIZE_SENT;
|
||||
if ((size = ctf_type_size(src_fp, src_type)) >
|
||||
LCTF_MAX_SIZE(src_fp)) {
|
||||
dtd->dtd_data.ctt_size = LCTF_LSIZE_SENT(dst_fp);
|
||||
dtd->dtd_data.ctt_lsizehi = CTF_SIZE_TO_LSIZE_HI(size);
|
||||
dtd->dtd_data.ctt_lsizelo = CTF_SIZE_TO_LSIZE_LO(size);
|
||||
} else
|
||||
dtd->dtd_data.ctt_size = (ushort_t)size;
|
||||
dtd->dtd_data.ctt_size = size;
|
||||
|
||||
dtd->dtd_data.ctt_info = CTF_TYPE_INFO(kind, flag, vlen);
|
||||
dtd->dtd_data.ctt_info = LCTF_TYPE_INFO(dst_fp, kind, flag,
|
||||
vlen);
|
||||
|
||||
/*
|
||||
* Make a final pass through the members changing each dmd_type
|
||||
|
@ -88,10 +88,10 @@ ctf_decl_push(ctf_decl_t *cd, ctf_file_t *fp, ctf_id_t type)
|
||||
{
|
||||
ctf_decl_node_t *cdp;
|
||||
ctf_decl_prec_t prec;
|
||||
uint_t kind, n = 1;
|
||||
uint_t ctype, kind, n = 1;
|
||||
int is_qual = 0;
|
||||
|
||||
const ctf_type_t *tp;
|
||||
const void *tp;
|
||||
ctf_arinfo_t ar;
|
||||
|
||||
if ((tp = ctf_lookup_by_id(&fp, type)) == NULL) {
|
||||
@ -99,7 +99,10 @@ ctf_decl_push(ctf_decl_t *cd, ctf_file_t *fp, ctf_id_t type)
|
||||
return;
|
||||
}
|
||||
|
||||
switch (kind = LCTF_INFO_KIND(fp, tp->ctt_info)) {
|
||||
ctf_get_ctt_info(fp, tp, &kind, NULL, NULL);
|
||||
ctf_get_ctt_index(fp, tp, NULL, &ctype, NULL);
|
||||
|
||||
switch (kind) {
|
||||
case CTF_K_ARRAY:
|
||||
(void) ctf_array_info(fp, type, &ar);
|
||||
ctf_decl_push(cd, fp, ar.ctr_contents);
|
||||
@ -108,27 +111,27 @@ ctf_decl_push(ctf_decl_t *cd, ctf_file_t *fp, ctf_id_t type)
|
||||
break;
|
||||
|
||||
case CTF_K_TYPEDEF:
|
||||
if (ctf_strptr(fp, tp->ctt_name)[0] == '\0') {
|
||||
ctf_decl_push(cd, fp, tp->ctt_type);
|
||||
if (ctf_type_rname(fp, tp)[0] == '\0') {
|
||||
ctf_decl_push(cd, fp, ctype);
|
||||
return;
|
||||
}
|
||||
prec = CTF_PREC_BASE;
|
||||
break;
|
||||
|
||||
case CTF_K_FUNCTION:
|
||||
ctf_decl_push(cd, fp, tp->ctt_type);
|
||||
ctf_decl_push(cd, fp, ctype);
|
||||
prec = CTF_PREC_FUNCTION;
|
||||
break;
|
||||
|
||||
case CTF_K_POINTER:
|
||||
ctf_decl_push(cd, fp, tp->ctt_type);
|
||||
ctf_decl_push(cd, fp, ctype);
|
||||
prec = CTF_PREC_POINTER;
|
||||
break;
|
||||
|
||||
case CTF_K_VOLATILE:
|
||||
case CTF_K_CONST:
|
||||
case CTF_K_RESTRICT:
|
||||
ctf_decl_push(cd, fp, tp->ctt_type);
|
||||
ctf_decl_push(cd, fp, ctype);
|
||||
prec = cd->cd_qualp;
|
||||
is_qual++;
|
||||
break;
|
||||
|
@ -29,7 +29,7 @@
|
||||
|
||||
#include <ctf_impl.h>
|
||||
|
||||
static const ushort_t _CTF_EMPTY[1] = { 0 };
|
||||
static const uint_t _CTF_EMPTY[1] = { 0 };
|
||||
|
||||
int
|
||||
ctf_hash_create(ctf_hash_t *hp, ulong_t nelems)
|
||||
@ -43,7 +43,7 @@ ctf_hash_create(ctf_hash_t *hp, ulong_t nelems)
|
||||
*/
|
||||
if (nelems == 0) {
|
||||
bzero(hp, sizeof (ctf_hash_t));
|
||||
hp->h_buckets = (ushort_t *)_CTF_EMPTY;
|
||||
hp->h_buckets = (uint_t *)_CTF_EMPTY;
|
||||
hp->h_nbuckets = 1;
|
||||
return (0);
|
||||
}
|
||||
@ -52,7 +52,7 @@ ctf_hash_create(ctf_hash_t *hp, ulong_t nelems)
|
||||
hp->h_nelems = nelems + 1; /* we use index zero as a sentinel */
|
||||
hp->h_free = 1; /* first free element is index 1 */
|
||||
|
||||
hp->h_buckets = ctf_alloc(sizeof (ushort_t) * hp->h_nbuckets);
|
||||
hp->h_buckets = ctf_alloc(sizeof (uint_t) * hp->h_nbuckets);
|
||||
hp->h_chains = ctf_alloc(sizeof (ctf_helem_t) * hp->h_nelems);
|
||||
|
||||
if (hp->h_buckets == NULL || hp->h_chains == NULL) {
|
||||
@ -60,7 +60,7 @@ ctf_hash_create(ctf_hash_t *hp, ulong_t nelems)
|
||||
return (EAGAIN);
|
||||
}
|
||||
|
||||
bzero(hp->h_buckets, sizeof (ushort_t) * hp->h_nbuckets);
|
||||
bzero(hp->h_buckets, sizeof (uint_t) * hp->h_nbuckets);
|
||||
bzero(hp->h_chains, sizeof (ctf_helem_t) * hp->h_nelems);
|
||||
|
||||
return (0);
|
||||
@ -92,7 +92,7 @@ ctf_hash_compute(const char *key, size_t len)
|
||||
}
|
||||
|
||||
int
|
||||
ctf_hash_insert(ctf_hash_t *hp, ctf_file_t *fp, ushort_t type, uint_t name)
|
||||
ctf_hash_insert(ctf_hash_t *hp, ctf_file_t *fp, uint_t type, uint_t name)
|
||||
{
|
||||
ctf_strs_t *ctsp = &fp->ctf_str[CTF_NAME_STID(name)];
|
||||
const char *str = ctsp->cts_strs + CTF_NAME_OFFSET(name);
|
||||
@ -129,7 +129,7 @@ ctf_hash_insert(ctf_hash_t *hp, ctf_file_t *fp, ushort_t type, uint_t name)
|
||||
* If the key is not present, then call ctf_hash_insert() and hash it in.
|
||||
*/
|
||||
int
|
||||
ctf_hash_define(ctf_hash_t *hp, ctf_file_t *fp, ushort_t type, uint_t name)
|
||||
ctf_hash_define(ctf_hash_t *hp, ctf_file_t *fp, uint_t type, uint_t name)
|
||||
{
|
||||
const char *str = ctf_strptr(fp, name);
|
||||
ctf_helem_t *hep = ctf_hash_lookup(hp, fp, str, strlen(str));
|
||||
@ -147,7 +147,7 @@ ctf_hash_lookup(ctf_hash_t *hp, ctf_file_t *fp, const char *key, size_t len)
|
||||
ctf_helem_t *hep;
|
||||
ctf_strs_t *ctsp;
|
||||
const char *str;
|
||||
ushort_t i;
|
||||
uint_t i;
|
||||
|
||||
ulong_t h = ctf_hash_compute(key, len) % hp->h_nbuckets;
|
||||
|
||||
@ -167,7 +167,7 @@ void
|
||||
ctf_hash_destroy(ctf_hash_t *hp)
|
||||
{
|
||||
if (hp->h_buckets != NULL && hp->h_nbuckets != 1) {
|
||||
ctf_free(hp->h_buckets, sizeof (ushort_t) * hp->h_nbuckets);
|
||||
ctf_free(hp->h_buckets, sizeof (uint_t) * hp->h_nbuckets);
|
||||
hp->h_buckets = NULL;
|
||||
}
|
||||
|
||||
|
@ -65,15 +65,15 @@ extern "C" {
|
||||
|
||||
typedef struct ctf_helem {
|
||||
uint_t h_name; /* reference to name in string table */
|
||||
ushort_t h_type; /* corresponding type ID number */
|
||||
ushort_t h_next; /* index of next element in hash chain */
|
||||
uint_t h_type; /* corresponding type ID number */
|
||||
uint_t h_next; /* index of next element in hash chain */
|
||||
} ctf_helem_t;
|
||||
|
||||
typedef struct ctf_hash {
|
||||
ushort_t *h_buckets; /* hash bucket array (chain indices) */
|
||||
uint_t *h_buckets; /* hash bucket array (chain indices) */
|
||||
ctf_helem_t *h_chains; /* hash chains buffer */
|
||||
ushort_t h_nbuckets; /* number of elements in bucket array */
|
||||
ushort_t h_nelems; /* number of elements in hash table */
|
||||
uint_t h_nbuckets; /* number of elements in bucket array */
|
||||
uint_t h_nelems; /* number of elements in hash table */
|
||||
uint_t h_free; /* index of next free hash element */
|
||||
} ctf_hash_t;
|
||||
|
||||
@ -99,9 +99,20 @@ typedef struct ctf_lookup {
|
||||
} ctf_lookup_t;
|
||||
|
||||
typedef struct ctf_fileops {
|
||||
ushort_t (*ctfo_get_kind)(ushort_t);
|
||||
ushort_t (*ctfo_get_root)(ushort_t);
|
||||
ushort_t (*ctfo_get_vlen)(ushort_t);
|
||||
uint_t (*ctfo_get_kind)(uint_t);
|
||||
uint_t (*ctfo_get_root)(uint_t);
|
||||
uint_t (*ctfo_get_vlen)(uint_t);
|
||||
uint_t (*ctfo_get_max_vlen)(void);
|
||||
uint_t (*ctfo_get_max_size)(void);
|
||||
uint_t (*ctfo_get_max_type)(void);
|
||||
uint_t (*ctfo_get_lsize_sent)(void);
|
||||
uint_t (*ctfo_get_lstruct_thresh)(void);
|
||||
|
||||
uint_t (*ctfo_type_info)(uint_t, uint_t, uint_t);
|
||||
int (*ctfo_type_isparent)(uint_t);
|
||||
int (*ctfo_type_ischild)(uint_t);
|
||||
uint_t (*ctfo_type_to_index)(uint_t);
|
||||
uint_t (*ctfo_index_to_type)(uint_t, uint_t);
|
||||
} ctf_fileops_t;
|
||||
|
||||
typedef struct ctf_list {
|
||||
@ -149,7 +160,7 @@ typedef struct ctf_dtdef {
|
||||
struct ctf_dtdef *dtd_hash; /* hash chain pointer for ctf_dthash */
|
||||
char *dtd_name; /* name associated with definition (if any) */
|
||||
ctf_id_t dtd_type; /* type identifier for this definition */
|
||||
ctf_type_t dtd_data; /* type node (see <sys/ctf.h>) */
|
||||
struct ctf_type_v3 dtd_data; /* type node (see <sys/ctf.h>) */
|
||||
int dtd_ref; /* recfount for dyanmic types */
|
||||
union {
|
||||
ctf_list_t dtu_members; /* struct, union, or enum */
|
||||
@ -194,7 +205,7 @@ struct ctf_file {
|
||||
uint_t *ctf_sxlate; /* translation table for symtab entries */
|
||||
ulong_t ctf_nsyms; /* number of entries in symtab xlate table */
|
||||
uint_t *ctf_txlate; /* translation table for type IDs */
|
||||
ushort_t *ctf_ptrtab; /* translation table for pointer-to lookups */
|
||||
uint_t *ctf_ptrtab; /* translation table for pointer-to lookups */
|
||||
ulong_t ctf_typemax; /* maximum valid type ID number */
|
||||
const ctf_dmodel_t *ctf_dmodel; /* data model pointer (see above) */
|
||||
struct ctf_file *ctf_parent; /* parent CTF container (if any) */
|
||||
@ -204,6 +215,7 @@ struct ctf_file {
|
||||
uint_t ctf_flags; /* libctf flags (see below) */
|
||||
int ctf_errno; /* error code for most recent error */
|
||||
int ctf_version; /* CTF data version */
|
||||
size_t ctf_idwidth; /* Size, in bytes, of a type ID */
|
||||
ctf_dtdef_t **ctf_dthash; /* hash of dynamic type definitions */
|
||||
ulong_t ctf_dthashlen; /* size of dynamic type hash bucket array */
|
||||
ctf_list_t ctf_dtdefs; /* list of dynamic type definitions */
|
||||
@ -214,11 +226,24 @@ struct ctf_file {
|
||||
};
|
||||
|
||||
#define LCTF_INDEX_TO_TYPEPTR(fp, i) \
|
||||
((ctf_type_t *)((uintptr_t)(fp)->ctf_buf + (fp)->ctf_txlate[(i)]))
|
||||
((void *)((uintptr_t)(fp)->ctf_buf + (fp)->ctf_txlate[(i)]))
|
||||
|
||||
#define LCTF_INFO_KIND(fp, info) ((fp)->ctf_fileops->ctfo_get_kind(info))
|
||||
#define LCTF_INFO_ROOT(fp, info) ((fp)->ctf_fileops->ctfo_get_root(info))
|
||||
#define LCTF_INFO_VLEN(fp, info) ((fp)->ctf_fileops->ctfo_get_vlen(info))
|
||||
#define LCTF_MAX_VLEN(fp) ((fp)->ctf_fileops->ctfo_get_max_vlen())
|
||||
#define LCTF_MAX_SIZE(fp) ((fp)->ctf_fileops->ctfo_get_max_size())
|
||||
#define LCTF_MAX_TYPE(fp) ((fp)->ctf_fileops->ctfo_get_max_type())
|
||||
#define LCTF_LSIZE_SENT(fp) \
|
||||
((fp)->ctf_fileops->ctfo_get_lsize_sent())
|
||||
#define LCTF_LSTRUCT_THRESH(fp) \
|
||||
((fp)->ctf_fileops->ctfo_get_lstruct_thresh())
|
||||
|
||||
#define LCTF_TYPE_INFO(fp, k, r, l) ((fp)->ctf_fileops->ctfo_type_info(k, r, l))
|
||||
#define LCTF_TYPE_ISPARENT(fp, id) ((fp)->ctf_fileops->ctfo_type_isparent(id))
|
||||
#define LCTF_TYPE_ISCHILD(fp, id) ((fp)->ctf_fileops->ctfo_type_ischild(id))
|
||||
#define LCTF_TYPE_TO_INDEX(fp, t) ((fp)->ctf_fileops->ctfo_type_to_index(t))
|
||||
#define LCTF_INDEX_TO_TYPE(fp, id, c) ((fp)->ctf_fileops->ctfo_index_to_type(id, c))
|
||||
|
||||
#define LCTF_MMAP 0x0001 /* libctf should munmap buffers on close */
|
||||
#define LCTF_CHILD 0x0002 /* CTF container is a child */
|
||||
@ -276,14 +301,22 @@ enum {
|
||||
ECTF_NOTDYN /* type is not a dynamic type */
|
||||
};
|
||||
|
||||
extern ssize_t ctf_get_ctt_size(const ctf_file_t *, const ctf_type_t *,
|
||||
ssize_t *, ssize_t *);
|
||||
extern void ctf_get_ctt_index(const ctf_file_t *fp, const void *v,
|
||||
uint_t *indexp, uint_t *typep, int *ischildp);
|
||||
extern ssize_t ctf_get_ctt_size(const ctf_file_t *, const void *v, ssize_t *,
|
||||
ssize_t *);
|
||||
extern void ctf_get_ctt_info(const ctf_file_t *, const void *v, uint_t *kind,
|
||||
uint_t *vlen, int *isroot);
|
||||
|
||||
extern const ctf_type_t *ctf_lookup_by_id(ctf_file_t **, ctf_id_t);
|
||||
extern void ctf_get_ctm_info(const ctf_file_t *fp, const void *v, size_t sz,
|
||||
size_t *incrementp, uint_t *typep, ulong_t *offsetp, const char **namep);
|
||||
|
||||
extern const void *ctf_lookup_by_id(ctf_file_t **, ctf_id_t);
|
||||
extern const char *ctf_type_rname(ctf_file_t *, const void *);
|
||||
|
||||
extern int ctf_hash_create(ctf_hash_t *, ulong_t);
|
||||
extern int ctf_hash_insert(ctf_hash_t *, ctf_file_t *, ushort_t, uint_t);
|
||||
extern int ctf_hash_define(ctf_hash_t *, ctf_file_t *, ushort_t, uint_t);
|
||||
extern int ctf_hash_insert(ctf_hash_t *, ctf_file_t *, uint_t, uint_t);
|
||||
extern int ctf_hash_define(ctf_hash_t *, ctf_file_t *, uint_t, uint_t);
|
||||
extern ctf_helem_t *ctf_hash_lookup(ctf_hash_t *, ctf_file_t *,
|
||||
const char *, size_t);
|
||||
extern uint_t ctf_hash_size(const ctf_hash_t *);
|
||||
|
@ -111,17 +111,17 @@ ctf_lookup_by_name(ctf_file_t *fp, const char *name)
|
||||
* data includes "struct foo *" but not "foo_t *" and
|
||||
* the user tries to access "foo_t *" in the debugger.
|
||||
*/
|
||||
ntype = fp->ctf_ptrtab[CTF_TYPE_TO_INDEX(type)];
|
||||
ntype = fp->ctf_ptrtab[LCTF_TYPE_TO_INDEX(fp, type)];
|
||||
if (ntype == 0) {
|
||||
ntype = ctf_type_resolve(fp, type);
|
||||
if (ntype == CTF_ERR || (ntype = fp->ctf_ptrtab[
|
||||
CTF_TYPE_TO_INDEX(ntype)]) == 0) {
|
||||
LCTF_TYPE_TO_INDEX(fp, ntype)]) == 0) {
|
||||
(void) ctf_set_errno(fp, ECTF_NOTYPE);
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
|
||||
type = CTF_INDEX_TO_TYPE(ntype,
|
||||
type = LCTF_INDEX_TO_TYPE(fp, ntype,
|
||||
(fp->ctf_flags & LCTF_CHILD));
|
||||
|
||||
q = p + 1;
|
||||
@ -203,7 +203,7 @@ ctf_lookup_by_symbol(ctf_file_t *fp, ulong_t symidx)
|
||||
if (fp->ctf_sxlate[symidx] == -1u)
|
||||
return (ctf_set_errno(fp, ECTF_NOTYPEDAT));
|
||||
|
||||
type = *(ushort_t *)((uintptr_t)fp->ctf_buf + fp->ctf_sxlate[symidx]);
|
||||
type = *(uint_t *)((uintptr_t)fp->ctf_buf + fp->ctf_sxlate[symidx]);
|
||||
if (type == 0)
|
||||
return (ctf_set_errno(fp, ECTF_NOTYPEDAT));
|
||||
|
||||
@ -215,18 +215,24 @@ ctf_lookup_by_symbol(ctf_file_t *fp, ulong_t symidx)
|
||||
* given type ID. If the ID is invalid, the function returns NULL.
|
||||
* This function is not exported outside of the library.
|
||||
*/
|
||||
const ctf_type_t *
|
||||
const void *
|
||||
ctf_lookup_by_id(ctf_file_t **fpp, ctf_id_t type)
|
||||
{
|
||||
ctf_file_t *fp = *fpp; /* caller passes in starting CTF container */
|
||||
|
||||
if ((fp->ctf_flags & LCTF_CHILD) && CTF_TYPE_ISPARENT(type) &&
|
||||
(fp = fp->ctf_parent) == NULL) {
|
||||
(void) ctf_set_errno(*fpp, ECTF_NOPARENT);
|
||||
return (NULL);
|
||||
if ((fp->ctf_flags & LCTF_CHILD) && LCTF_TYPE_ISPARENT(fp, type)) {
|
||||
if (fp->ctf_parent == NULL) {
|
||||
(void) ctf_set_errno(*fpp, ECTF_NOPARENT);
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
/* The parent may be using a different CTF version. */
|
||||
type = LCTF_TYPE_TO_INDEX(fp, type);
|
||||
fp = fp->ctf_parent;
|
||||
} else {
|
||||
type = LCTF_TYPE_TO_INDEX(fp, type);
|
||||
}
|
||||
|
||||
type = CTF_TYPE_TO_INDEX(type);
|
||||
if (type > 0 && type <= fp->ctf_typemax) {
|
||||
*fpp = fp; /* function returns ending CTF container */
|
||||
return (LCTF_INDEX_TO_TYPEPTR(fp, type));
|
||||
@ -244,8 +250,8 @@ int
|
||||
ctf_func_info(ctf_file_t *fp, ulong_t symidx, ctf_funcinfo_t *fip)
|
||||
{
|
||||
const ctf_sect_t *sp = &fp->ctf_symtab;
|
||||
const ushort_t *dp;
|
||||
ushort_t info, kind, n;
|
||||
const uint_t *dp;
|
||||
uint_t info, kind, n;
|
||||
|
||||
if (sp->cts_data == NULL)
|
||||
return (ctf_set_errno(fp, ECTF_NOSYMTAB));
|
||||
@ -266,7 +272,7 @@ ctf_func_info(ctf_file_t *fp, ulong_t symidx, ctf_funcinfo_t *fip)
|
||||
if (fp->ctf_sxlate[symidx] == -1u)
|
||||
return (ctf_set_errno(fp, ECTF_NOFUNCDAT));
|
||||
|
||||
dp = (ushort_t *)((uintptr_t)fp->ctf_buf + fp->ctf_sxlate[symidx]);
|
||||
dp = (uint_t *)((uintptr_t)fp->ctf_buf + fp->ctf_sxlate[symidx]);
|
||||
|
||||
info = *dp++;
|
||||
kind = LCTF_INFO_KIND(fp, info);
|
||||
@ -297,17 +303,17 @@ ctf_func_info(ctf_file_t *fp, ulong_t symidx, ctf_funcinfo_t *fip)
|
||||
int
|
||||
ctf_func_args(ctf_file_t *fp, ulong_t symidx, uint_t argc, ctf_id_t *argv)
|
||||
{
|
||||
const ushort_t *dp;
|
||||
const uint_t *dp;
|
||||
ctf_funcinfo_t f;
|
||||
|
||||
if (ctf_func_info(fp, symidx, &f) == CTF_ERR)
|
||||
return (CTF_ERR); /* errno is set for us */
|
||||
|
||||
/*
|
||||
* The argument data is two ushort_t's past the translation table
|
||||
* The argument data is two uint_t's past the translation table
|
||||
* offset: one for the function info, and one for the return type.
|
||||
*/
|
||||
dp = (ushort_t *)((uintptr_t)fp->ctf_buf + fp->ctf_sxlate[symidx]) + 2;
|
||||
dp = (uint_t *)((uintptr_t)fp->ctf_buf + fp->ctf_sxlate[symidx]) + 2;
|
||||
|
||||
for (argc = MIN(argc, f.ctc_argc); argc != 0; argc--)
|
||||
*argv++ = *dp++;
|
||||
|
@ -44,28 +44,184 @@ const char _CTF_NULLSTR[] = "";
|
||||
int _libctf_version = CTF_VERSION; /* library client version */
|
||||
int _libctf_debug = 0; /* debugging messages enabled */
|
||||
|
||||
static ushort_t
|
||||
get_kind_v2(ushort_t info)
|
||||
static uint_t
|
||||
get_kind_v2(uint_t info)
|
||||
{
|
||||
return (CTF_INFO_KIND(info));
|
||||
return (CTF_V2_INFO_KIND((ushort_t)info));
|
||||
}
|
||||
|
||||
static ushort_t
|
||||
get_root_v2(ushort_t info)
|
||||
static uint_t
|
||||
get_root_v2(uint_t info)
|
||||
{
|
||||
return (CTF_INFO_ISROOT(info));
|
||||
return (CTF_V2_INFO_ISROOT((ushort_t)info));
|
||||
}
|
||||
|
||||
static ushort_t
|
||||
get_vlen_v2(ushort_t info)
|
||||
static uint_t
|
||||
get_vlen_v2(uint_t info)
|
||||
{
|
||||
return (CTF_INFO_VLEN(info));
|
||||
return (CTF_V2_INFO_VLEN((ushort_t)info));
|
||||
}
|
||||
|
||||
static uint_t
|
||||
get_max_vlen_v2(void)
|
||||
{
|
||||
return (CTF_V2_MAX_VLEN);
|
||||
}
|
||||
|
||||
static uint_t
|
||||
get_max_size_v2(void)
|
||||
{
|
||||
return (CTF_V2_MAX_SIZE);
|
||||
}
|
||||
|
||||
static uint_t
|
||||
get_max_type_v2(void)
|
||||
{
|
||||
return (CTF_V2_MAX_TYPE);
|
||||
}
|
||||
|
||||
static uint_t
|
||||
get_lsize_sent_v2(void)
|
||||
{
|
||||
return (CTF_V2_LSIZE_SENT);
|
||||
}
|
||||
|
||||
static uint_t
|
||||
get_lstruct_thresh_v2(void)
|
||||
{
|
||||
return (CTF_V2_LSTRUCT_THRESH);
|
||||
}
|
||||
|
||||
static uint_t
|
||||
type_info_v2(uint_t kind, uint_t isroot, uint_t len)
|
||||
{
|
||||
return (CTF_V2_TYPE_INFO(kind, isroot, len));
|
||||
}
|
||||
|
||||
static int
|
||||
type_isparent_v2(uint_t id)
|
||||
{
|
||||
return (CTF_V2_TYPE_ISPARENT(id));
|
||||
}
|
||||
|
||||
static int
|
||||
type_ischild_v2(uint_t id)
|
||||
{
|
||||
return (CTF_V2_TYPE_ISCHILD(id));
|
||||
}
|
||||
|
||||
static uint_t
|
||||
type_to_index_v2(uint_t t)
|
||||
{
|
||||
return (CTF_V2_TYPE_TO_INDEX(t));
|
||||
}
|
||||
|
||||
static uint_t
|
||||
index_to_type_v2(uint_t id, uint_t child)
|
||||
{
|
||||
return (CTF_V2_INDEX_TO_TYPE(id, child));
|
||||
}
|
||||
|
||||
static uint_t
|
||||
get_kind_v3(uint_t info)
|
||||
{
|
||||
return (CTF_V3_INFO_KIND(info));
|
||||
}
|
||||
|
||||
static uint_t
|
||||
get_root_v3(uint_t info)
|
||||
{
|
||||
return (CTF_V3_INFO_ISROOT(info));
|
||||
}
|
||||
|
||||
static uint_t
|
||||
get_vlen_v3(uint_t info)
|
||||
{
|
||||
return (CTF_V3_INFO_VLEN(info));
|
||||
}
|
||||
|
||||
static uint_t
|
||||
get_max_vlen_v3(void)
|
||||
{
|
||||
return (CTF_V3_MAX_VLEN);
|
||||
}
|
||||
|
||||
static uint_t
|
||||
get_max_size_v3(void)
|
||||
{
|
||||
return (CTF_V3_MAX_SIZE);
|
||||
}
|
||||
|
||||
static uint_t
|
||||
get_max_type_v3(void)
|
||||
{
|
||||
return (CTF_V3_MAX_TYPE);
|
||||
}
|
||||
|
||||
static uint_t
|
||||
get_lsize_sent_v3(void)
|
||||
{
|
||||
return (CTF_V3_LSIZE_SENT);
|
||||
}
|
||||
|
||||
static uint_t
|
||||
get_lstruct_thresh_v3(void)
|
||||
{
|
||||
return (CTF_V3_LSTRUCT_THRESH);
|
||||
}
|
||||
|
||||
static uint_t
|
||||
type_info_v3(uint_t kind, uint_t isroot, uint_t len)
|
||||
{
|
||||
return (CTF_V3_TYPE_INFO(kind, isroot, len));
|
||||
}
|
||||
|
||||
static int
|
||||
type_isparent_v3(uint_t id)
|
||||
{
|
||||
return (CTF_V3_TYPE_ISPARENT(id));
|
||||
}
|
||||
|
||||
static int
|
||||
type_ischild_v3(uint_t id)
|
||||
{
|
||||
return (CTF_V3_TYPE_ISCHILD(id));
|
||||
}
|
||||
|
||||
static uint_t
|
||||
type_to_index_v3(uint_t t)
|
||||
{
|
||||
return (CTF_V3_TYPE_TO_INDEX(t));
|
||||
}
|
||||
|
||||
static uint_t
|
||||
index_to_type_v3(uint_t id, uint_t child)
|
||||
{
|
||||
return (CTF_V3_INDEX_TO_TYPE(id, child));
|
||||
}
|
||||
|
||||
#define CTF_FILEOPS_ENTRY(v) \
|
||||
{ \
|
||||
.ctfo_get_kind = get_kind_v ## v, \
|
||||
.ctfo_get_root = get_root_v ## v, \
|
||||
.ctfo_get_vlen = get_vlen_v ## v, \
|
||||
.ctfo_get_max_vlen = get_max_vlen_v ## v, \
|
||||
.ctfo_get_max_size = get_max_size_v ## v, \
|
||||
.ctfo_get_max_type = get_max_type_v ## v, \
|
||||
.ctfo_get_lsize_sent = get_lsize_sent_v ## v, \
|
||||
.ctfo_get_lstruct_thresh = get_lstruct_thresh_v ## v, \
|
||||
.ctfo_type_info = type_info_v ## v, \
|
||||
.ctfo_type_isparent = type_isparent_v ## v, \
|
||||
.ctfo_type_ischild = type_ischild_v ## v, \
|
||||
.ctfo_type_to_index = type_to_index_v ## v, \
|
||||
.ctfo_index_to_type = index_to_type_v ## v \
|
||||
}
|
||||
|
||||
static const ctf_fileops_t ctf_fileops[] = {
|
||||
{ NULL, NULL },
|
||||
{ NULL, NULL },
|
||||
{ get_kind_v2, get_root_v2, get_vlen_v2 },
|
||||
CTF_FILEOPS_ENTRY(2),
|
||||
CTF_FILEOPS_ENTRY(3),
|
||||
};
|
||||
|
||||
/*
|
||||
@ -100,7 +256,8 @@ init_symtab(ctf_file_t *fp, const ctf_header_t *hp,
|
||||
uint_t objtoff = hp->cth_objtoff;
|
||||
uint_t funcoff = hp->cth_funcoff;
|
||||
|
||||
ushort_t info, vlen;
|
||||
uint_t info, vlen;
|
||||
|
||||
Elf64_Sym sym, *gsp;
|
||||
const char *name;
|
||||
|
||||
@ -138,7 +295,7 @@ init_symtab(ctf_file_t *fp, const ctf_header_t *hp,
|
||||
}
|
||||
|
||||
*xp = objtoff;
|
||||
objtoff += sizeof (ushort_t);
|
||||
objtoff += fp->ctf_idwidth;
|
||||
break;
|
||||
|
||||
case STT_FUNC:
|
||||
@ -149,7 +306,7 @@ init_symtab(ctf_file_t *fp, const ctf_header_t *hp,
|
||||
|
||||
*xp = funcoff;
|
||||
|
||||
info = *(ushort_t *)((uintptr_t)fp->ctf_buf + funcoff);
|
||||
info = *(uint_t *)((uintptr_t)fp->ctf_buf + funcoff);
|
||||
vlen = LCTF_INFO_VLEN(fp, info);
|
||||
|
||||
/*
|
||||
@ -159,9 +316,10 @@ init_symtab(ctf_file_t *fp, const ctf_header_t *hp,
|
||||
*/
|
||||
if (LCTF_INFO_KIND(fp, info) == CTF_K_UNKNOWN &&
|
||||
vlen == 0)
|
||||
funcoff += sizeof (ushort_t); /* skip pad */
|
||||
funcoff += fp->ctf_idwidth;
|
||||
else
|
||||
funcoff += sizeof (ushort_t) * (vlen + 2);
|
||||
funcoff +=
|
||||
roundup2(fp->ctf_idwidth * (vlen + 2), 4);
|
||||
break;
|
||||
|
||||
default:
|
||||
@ -181,15 +339,13 @@ init_symtab(ctf_file_t *fp, const ctf_header_t *hp,
|
||||
static int
|
||||
init_types(ctf_file_t *fp, const ctf_header_t *cth)
|
||||
{
|
||||
/* LINTED - pointer alignment */
|
||||
const ctf_type_t *tbuf = (ctf_type_t *)(fp->ctf_buf + cth->cth_typeoff);
|
||||
/* LINTED - pointer alignment */
|
||||
const ctf_type_t *tend = (ctf_type_t *)(fp->ctf_buf + cth->cth_stroff);
|
||||
const void *tbuf = (const void *)(fp->ctf_buf + cth->cth_typeoff);
|
||||
const void *tend = (const void *)(fp->ctf_buf + cth->cth_stroff);
|
||||
|
||||
ulong_t pop[CTF_K_MAX + 1] = { 0 };
|
||||
const ctf_type_t *tp;
|
||||
const void *tp;
|
||||
ctf_hash_t *hp;
|
||||
ushort_t id, dst;
|
||||
uint_t id, dst;
|
||||
uint_t *xp;
|
||||
|
||||
/*
|
||||
@ -207,14 +363,14 @@ init_types(ctf_file_t *fp, const ctf_header_t *cth)
|
||||
* pass, we count the number of each type and the total number of types.
|
||||
*/
|
||||
for (tp = tbuf; tp < tend; fp->ctf_typemax++) {
|
||||
ushort_t kind = LCTF_INFO_KIND(fp, tp->ctt_info);
|
||||
ulong_t vlen = LCTF_INFO_VLEN(fp, tp->ctt_info);
|
||||
ssize_t size, increment;
|
||||
|
||||
size_t vbytes;
|
||||
uint_t n;
|
||||
uint_t kind, n, type, vlen;
|
||||
|
||||
(void) ctf_get_ctt_size(fp, tp, &size, &increment);
|
||||
ctf_get_ctt_info(fp, tp, &kind, &vlen, NULL);
|
||||
ctf_get_ctt_index(fp, tp, NULL, &type, NULL);
|
||||
|
||||
switch (kind) {
|
||||
case CTF_K_INTEGER:
|
||||
@ -222,30 +378,30 @@ init_types(ctf_file_t *fp, const ctf_header_t *cth)
|
||||
vbytes = sizeof (uint_t);
|
||||
break;
|
||||
case CTF_K_ARRAY:
|
||||
vbytes = sizeof (ctf_array_t);
|
||||
if (fp->ctf_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(fp->ctf_idwidth * vlen, 4);
|
||||
break;
|
||||
case CTF_K_STRUCT:
|
||||
case CTF_K_UNION:
|
||||
if (size < CTF_LSTRUCT_THRESH) {
|
||||
ctf_member_t *mp = (ctf_member_t *)
|
||||
((uintptr_t)tp + increment);
|
||||
case CTF_K_UNION: {
|
||||
size_t increment1;
|
||||
uint_t type;
|
||||
const void *mp =
|
||||
(const void *)((uintptr_t)tp + increment);
|
||||
|
||||
vbytes = sizeof (ctf_member_t) * vlen;
|
||||
for (n = vlen; n != 0; n--, mp++)
|
||||
child |= CTF_TYPE_ISCHILD(mp->ctm_type);
|
||||
} else {
|
||||
ctf_lmember_t *lmp = (ctf_lmember_t *)
|
||||
((uintptr_t)tp + increment);
|
||||
|
||||
vbytes = sizeof (ctf_lmember_t) * vlen;
|
||||
for (n = vlen; n != 0; n--, lmp++)
|
||||
child |=
|
||||
CTF_TYPE_ISCHILD(lmp->ctlm_type);
|
||||
vbytes = 0;
|
||||
for (n = vlen; n != 0; n--, mp += increment1) {
|
||||
ctf_get_ctm_info(fp, mp, size, &increment1, &type,
|
||||
NULL, NULL);
|
||||
child |= LCTF_TYPE_ISCHILD(fp, type);
|
||||
vbytes += increment1;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case CTF_K_ENUM:
|
||||
vbytes = sizeof (ctf_enum_t) * vlen;
|
||||
break;
|
||||
@ -255,11 +411,10 @@ init_types(ctf_file_t *fp, const ctf_header_t *cth)
|
||||
* 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;
|
||||
@ -269,14 +424,14 @@ init_types(ctf_file_t *fp, const ctf_header_t *cth)
|
||||
case CTF_K_VOLATILE:
|
||||
case CTF_K_CONST:
|
||||
case CTF_K_RESTRICT:
|
||||
child |= CTF_TYPE_ISCHILD(tp->ctt_type);
|
||||
child |= LCTF_TYPE_ISCHILD(fp, type);
|
||||
vbytes = 0;
|
||||
break;
|
||||
default:
|
||||
ctf_dprintf("detected invalid CTF kind -- %u\n", kind);
|
||||
return (ECTF_CORRUPT);
|
||||
}
|
||||
tp = (ctf_type_t *)((uintptr_t)tp + increment + vbytes);
|
||||
tp = (const void *)((uintptr_t)tp + increment + vbytes);
|
||||
pop[kind]++;
|
||||
}
|
||||
|
||||
@ -310,7 +465,7 @@ init_types(ctf_file_t *fp, const ctf_header_t *cth)
|
||||
return (err);
|
||||
|
||||
fp->ctf_txlate = ctf_alloc(sizeof (uint_t) * (fp->ctf_typemax + 1));
|
||||
fp->ctf_ptrtab = ctf_alloc(sizeof (ushort_t) * (fp->ctf_typemax + 1));
|
||||
fp->ctf_ptrtab = ctf_alloc(sizeof (uint_t) * (fp->ctf_typemax + 1));
|
||||
|
||||
if (fp->ctf_txlate == NULL || fp->ctf_ptrtab == NULL)
|
||||
return (EAGAIN); /* memory allocation failed */
|
||||
@ -319,15 +474,15 @@ init_types(ctf_file_t *fp, const ctf_header_t *cth)
|
||||
*xp++ = 0; /* type id 0 is used as a sentinel value */
|
||||
|
||||
bzero(fp->ctf_txlate, sizeof (uint_t) * (fp->ctf_typemax + 1));
|
||||
bzero(fp->ctf_ptrtab, sizeof (ushort_t) * (fp->ctf_typemax + 1));
|
||||
bzero(fp->ctf_ptrtab, sizeof (uint_t) * (fp->ctf_typemax + 1));
|
||||
|
||||
/*
|
||||
* In the second pass through the types, we fill in each entry of the
|
||||
* type and pointer tables and add names to the appropriate hashes.
|
||||
*/
|
||||
for (id = 1, tp = tbuf; tp < tend; xp++, id++) {
|
||||
ushort_t kind = LCTF_INFO_KIND(fp, tp->ctt_info);
|
||||
ulong_t vlen = LCTF_INFO_VLEN(fp, tp->ctt_info);
|
||||
const struct ctf_type_v3 *ctt = tp;
|
||||
uint_t kind, type, vlen;
|
||||
ssize_t size, increment;
|
||||
|
||||
const char *name;
|
||||
@ -336,7 +491,9 @@ init_types(ctf_file_t *fp, const ctf_header_t *cth)
|
||||
ctf_encoding_t cte;
|
||||
|
||||
(void) ctf_get_ctt_size(fp, tp, &size, &increment);
|
||||
name = ctf_strptr(fp, tp->ctt_name);
|
||||
ctf_get_ctt_info(fp, tp, &kind, &vlen, NULL);
|
||||
ctf_get_ctt_index(fp, tp, NULL, &type, NULL);
|
||||
name = ctf_type_rname(fp, tp);
|
||||
|
||||
switch (kind) {
|
||||
case CTF_K_INTEGER:
|
||||
@ -349,7 +506,8 @@ init_types(ctf_file_t *fp, const ctf_header_t *cth)
|
||||
if ((hep = ctf_hash_lookup(&fp->ctf_names, fp,
|
||||
name, strlen(name))) == NULL) {
|
||||
err = ctf_hash_insert(&fp->ctf_names, fp,
|
||||
CTF_INDEX_TO_TYPE(id, child), tp->ctt_name);
|
||||
LCTF_INDEX_TO_TYPE(fp, id, child),
|
||||
ctt->ctt_name);
|
||||
if (err != 0 && err != ECTF_STRTAB)
|
||||
return (err);
|
||||
} else if (ctf_type_encoding(fp, hep->h_type,
|
||||
@ -358,56 +516,89 @@ init_types(ctf_file_t *fp, const ctf_header_t *cth)
|
||||
* Work-around SOS8 stabs bug: replace existing
|
||||
* intrinsic w/ same name if it was zero bits.
|
||||
*/
|
||||
hep->h_type = CTF_INDEX_TO_TYPE(id, child);
|
||||
hep->h_type = LCTF_INDEX_TO_TYPE(fp, id, child);
|
||||
}
|
||||
vbytes = sizeof (uint_t);
|
||||
break;
|
||||
|
||||
case CTF_K_ARRAY:
|
||||
vbytes = sizeof (ctf_array_t);
|
||||
if (fp->ctf_version == CTF_VERSION_2)
|
||||
vbytes = sizeof (struct ctf_array_v2);
|
||||
else
|
||||
vbytes = sizeof (struct ctf_array_v3);
|
||||
break;
|
||||
|
||||
case CTF_K_FUNCTION:
|
||||
err = ctf_hash_insert(&fp->ctf_names, fp,
|
||||
CTF_INDEX_TO_TYPE(id, child), tp->ctt_name);
|
||||
LCTF_INDEX_TO_TYPE(fp, id, child), ctt->ctt_name);
|
||||
if (err != 0 && err != ECTF_STRTAB)
|
||||
return (err);
|
||||
vbytes = sizeof (ushort_t) * (vlen + (vlen & 1));
|
||||
vbytes = roundup2(fp->ctf_idwidth * vlen, 4);
|
||||
break;
|
||||
|
||||
case CTF_K_STRUCT:
|
||||
err = ctf_hash_define(&fp->ctf_structs, fp,
|
||||
CTF_INDEX_TO_TYPE(id, child), tp->ctt_name);
|
||||
LCTF_INDEX_TO_TYPE(fp, id, child), ctt->ctt_name);
|
||||
|
||||
if (err != 0 && err != ECTF_STRTAB)
|
||||
return (err);
|
||||
|
||||
if (size < CTF_LSTRUCT_THRESH)
|
||||
vbytes = sizeof (ctf_member_t) * vlen;
|
||||
else {
|
||||
vbytes = sizeof (ctf_lmember_t) * vlen;
|
||||
nlstructs++;
|
||||
if (fp->ctf_version == CTF_VERSION_2) {
|
||||
if (size < LCTF_LSTRUCT_THRESH(fp))
|
||||
vbytes = sizeof (struct ctf_member_v2) *
|
||||
vlen;
|
||||
else {
|
||||
vbytes =
|
||||
sizeof (struct ctf_lmember_v2) *
|
||||
vlen;
|
||||
nlstructs++;
|
||||
}
|
||||
} else {
|
||||
if (size < LCTF_LSTRUCT_THRESH(fp))
|
||||
vbytes = sizeof (struct ctf_member_v3) *
|
||||
vlen;
|
||||
else {
|
||||
vbytes =
|
||||
sizeof (struct ctf_lmember_v3) *
|
||||
vlen;
|
||||
nlstructs++;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case CTF_K_UNION:
|
||||
err = ctf_hash_define(&fp->ctf_unions, fp,
|
||||
CTF_INDEX_TO_TYPE(id, child), tp->ctt_name);
|
||||
LCTF_INDEX_TO_TYPE(fp, id, child), ctt->ctt_name);
|
||||
|
||||
if (err != 0 && err != ECTF_STRTAB)
|
||||
return (err);
|
||||
|
||||
if (size < CTF_LSTRUCT_THRESH)
|
||||
vbytes = sizeof (ctf_member_t) * vlen;
|
||||
else {
|
||||
vbytes = sizeof (ctf_lmember_t) * vlen;
|
||||
nlunions++;
|
||||
if (fp->ctf_version == CTF_VERSION_2) {
|
||||
if (size < LCTF_LSTRUCT_THRESH(fp))
|
||||
vbytes = sizeof (struct ctf_member_v2) *
|
||||
vlen;
|
||||
else {
|
||||
vbytes =
|
||||
sizeof (struct ctf_lmember_v2) *
|
||||
vlen;
|
||||
nlunions++;
|
||||
}
|
||||
} else {
|
||||
if (size < LCTF_LSTRUCT_THRESH(fp))
|
||||
vbytes = sizeof (struct ctf_member_v3) *
|
||||
vlen;
|
||||
else {
|
||||
vbytes =
|
||||
sizeof (struct ctf_lmember_v3) *
|
||||
vlen;
|
||||
nlunions++;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case CTF_K_ENUM:
|
||||
err = ctf_hash_define(&fp->ctf_enums, fp,
|
||||
CTF_INDEX_TO_TYPE(id, child), tp->ctt_name);
|
||||
LCTF_INDEX_TO_TYPE(fp, id, child), ctt->ctt_name);
|
||||
|
||||
if (err != 0 && err != ECTF_STRTAB)
|
||||
return (err);
|
||||
@ -417,7 +608,7 @@ init_types(ctf_file_t *fp, const ctf_header_t *cth)
|
||||
|
||||
case CTF_K_TYPEDEF:
|
||||
err = ctf_hash_insert(&fp->ctf_names, fp,
|
||||
CTF_INDEX_TO_TYPE(id, child), tp->ctt_name);
|
||||
LCTF_INDEX_TO_TYPE(fp, id, child), ctt->ctt_name);
|
||||
if (err != 0 && err != ECTF_STRTAB)
|
||||
return (err);
|
||||
vbytes = 0;
|
||||
@ -428,7 +619,7 @@ init_types(ctf_file_t *fp, const ctf_header_t *cth)
|
||||
* Only insert forward tags into the given hash if the
|
||||
* type or tag name is not already present.
|
||||
*/
|
||||
switch (tp->ctt_type) {
|
||||
switch (type) {
|
||||
case CTF_K_STRUCT:
|
||||
hp = &fp->ctf_structs;
|
||||
break;
|
||||
@ -445,7 +636,8 @@ init_types(ctf_file_t *fp, const ctf_header_t *cth)
|
||||
if (ctf_hash_lookup(hp, fp,
|
||||
name, strlen(name)) == NULL) {
|
||||
err = ctf_hash_insert(hp, fp,
|
||||
CTF_INDEX_TO_TYPE(id, child), tp->ctt_name);
|
||||
LCTF_INDEX_TO_TYPE(fp, id, child),
|
||||
ctt->ctt_name);
|
||||
if (err != 0 && err != ECTF_STRTAB)
|
||||
return (err);
|
||||
}
|
||||
@ -458,17 +650,17 @@ init_types(ctf_file_t *fp, const ctf_header_t *cth)
|
||||
* container, then store the index of the pointer type
|
||||
* in fp->ctf_ptrtab[ index of referenced type ].
|
||||
*/
|
||||
if (CTF_TYPE_ISCHILD(tp->ctt_type) == child &&
|
||||
CTF_TYPE_TO_INDEX(tp->ctt_type) <= fp->ctf_typemax)
|
||||
if (LCTF_TYPE_ISCHILD(fp, type) == child &&
|
||||
LCTF_TYPE_TO_INDEX(fp, type) <= fp->ctf_typemax)
|
||||
fp->ctf_ptrtab[
|
||||
CTF_TYPE_TO_INDEX(tp->ctt_type)] = id;
|
||||
LCTF_TYPE_TO_INDEX(fp, type)] = id;
|
||||
/*FALLTHRU*/
|
||||
|
||||
case CTF_K_VOLATILE:
|
||||
case CTF_K_CONST:
|
||||
case CTF_K_RESTRICT:
|
||||
err = ctf_hash_insert(&fp->ctf_names, fp,
|
||||
CTF_INDEX_TO_TYPE(id, child), tp->ctt_name);
|
||||
LCTF_INDEX_TO_TYPE(fp, id, child), ctt->ctt_name);
|
||||
if (err != 0 && err != ECTF_STRTAB)
|
||||
return (err);
|
||||
/*FALLTHRU*/
|
||||
@ -479,7 +671,7 @@ init_types(ctf_file_t *fp, const ctf_header_t *cth)
|
||||
}
|
||||
|
||||
*xp = (uint_t)((uintptr_t)tp - (uintptr_t)fp->ctf_buf);
|
||||
tp = (ctf_type_t *)((uintptr_t)tp + increment + vbytes);
|
||||
tp = (const void *)((uintptr_t)tp + increment + vbytes);
|
||||
}
|
||||
|
||||
ctf_dprintf("%lu total types processed\n", fp->ctf_typemax);
|
||||
@ -499,14 +691,17 @@ init_types(ctf_file_t *fp, const ctf_header_t *cth)
|
||||
*/
|
||||
for (id = 1; id <= fp->ctf_typemax; id++) {
|
||||
if ((dst = fp->ctf_ptrtab[id]) != 0) {
|
||||
tp = LCTF_INDEX_TO_TYPEPTR(fp, id);
|
||||
uint_t index, kind;
|
||||
int ischild;
|
||||
|
||||
if (LCTF_INFO_KIND(fp, tp->ctt_info) == CTF_K_TYPEDEF &&
|
||||
strcmp(ctf_strptr(fp, tp->ctt_name), "") == 0 &&
|
||||
CTF_TYPE_ISCHILD(tp->ctt_type) == child &&
|
||||
CTF_TYPE_TO_INDEX(tp->ctt_type) <= fp->ctf_typemax)
|
||||
fp->ctf_ptrtab[
|
||||
CTF_TYPE_TO_INDEX(tp->ctt_type)] = dst;
|
||||
tp = LCTF_INDEX_TO_TYPEPTR(fp, id);
|
||||
ctf_get_ctt_info(fp, tp, &kind, NULL, NULL);
|
||||
ctf_get_ctt_index(fp, tp, &index, NULL, &ischild);
|
||||
|
||||
if (kind == CTF_K_TYPEDEF &&
|
||||
strcmp(ctf_type_rname(fp, tp), "") == 0 &&
|
||||
ischild == child && index <= fp->ctf_typemax)
|
||||
fp->ctf_ptrtab[index] = dst;
|
||||
}
|
||||
}
|
||||
|
||||
@ -560,7 +755,8 @@ ctf_bufopen(const ctf_sect_t *ctfsect, const ctf_sect_t *symsect,
|
||||
if (pp->ctp_magic != CTF_MAGIC)
|
||||
return (ctf_set_open_errno(errp, ECTF_NOCTFBUF));
|
||||
|
||||
if (pp->ctp_version == CTF_VERSION_2) {
|
||||
if (pp->ctp_version == CTF_VERSION_2 ||
|
||||
pp->ctp_version == CTF_VERSION_3) {
|
||||
if (ctfsect->cts_size < sizeof (ctf_header_t))
|
||||
return (ctf_set_open_errno(errp, ECTF_NOCTFBUF));
|
||||
|
||||
@ -642,6 +838,7 @@ ctf_bufopen(const ctf_sect_t *ctfsect, const ctf_sect_t *symsect,
|
||||
|
||||
bzero(fp, sizeof (ctf_file_t));
|
||||
fp->ctf_version = hp.cth_version;
|
||||
fp->ctf_idwidth = fp->ctf_version == CTF_VERSION_2 ? 2 : 4;
|
||||
fp->ctf_fileops = &ctf_fileops[hp.cth_version];
|
||||
bcopy(ctfsect, &fp->ctf_data, sizeof (ctf_sect_t));
|
||||
|
||||
@ -911,7 +1108,7 @@ ctf_close(ctf_file_t *fp)
|
||||
|
||||
if (fp->ctf_ptrtab != NULL) {
|
||||
ctf_free(fp->ctf_ptrtab,
|
||||
sizeof (ushort_t) * (fp->ctf_typemax + 1));
|
||||
sizeof (uint_t) * (fp->ctf_typemax + 1));
|
||||
}
|
||||
|
||||
ctf_hash_destroy(&fp->ctf_structs);
|
||||
|
@ -27,18 +27,90 @@
|
||||
|
||||
#include <ctf_impl.h>
|
||||
|
||||
void
|
||||
ctf_get_ctt_index(const ctf_file_t *fp, const void *v, uint_t *indexp,
|
||||
uint_t *typep, int *ischildp)
|
||||
{
|
||||
uint_t index, type;
|
||||
int ischild;
|
||||
|
||||
if (fp->ctf_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;
|
||||
}
|
||||
|
||||
void
|
||||
ctf_get_ctt_info(const ctf_file_t *fp, const void *v, uint_t *kindp,
|
||||
uint_t *vlenp, int *isrootp)
|
||||
{
|
||||
uint_t kind, vlen;
|
||||
int isroot;
|
||||
|
||||
if (fp->ctf_version == CTF_VERSION_2) {
|
||||
const 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 {
|
||||
const 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);
|
||||
}
|
||||
|
||||
if (kindp != NULL)
|
||||
*kindp = kind;
|
||||
if (vlenp != NULL)
|
||||
*vlenp = vlen;
|
||||
if (isrootp != NULL)
|
||||
*isrootp = isroot;
|
||||
}
|
||||
|
||||
ssize_t
|
||||
ctf_get_ctt_size(const ctf_file_t *fp, const ctf_type_t *tp, ssize_t *sizep,
|
||||
ctf_get_ctt_size(const ctf_file_t *fp, const void *v, 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 (fp->ctf_version == CTF_VERSION_2) {
|
||||
const struct ctf_type_v2 *ctt = v;
|
||||
|
||||
if (ctt->ctt_size == CTF_V2_LSIZE_SENT) {
|
||||
size = (size_t)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 = v;
|
||||
|
||||
if (ctt->ctt_size == CTF_V3_LSIZE_SENT) {
|
||||
size = (size_t)CTF_TYPE_LSIZE(ctt);
|
||||
increment = sizeof (struct ctf_type_v3);
|
||||
} else {
|
||||
size = ctt->ctt_size;
|
||||
increment = sizeof (struct ctf_stype_v3);
|
||||
}
|
||||
}
|
||||
|
||||
if (sizep)
|
||||
@ -49,6 +121,61 @@ ctf_get_ctt_size(const ctf_file_t *fp, const ctf_type_t *tp, ssize_t *sizep,
|
||||
return (size);
|
||||
}
|
||||
|
||||
/*
|
||||
* Fetch info for a struct or union member.
|
||||
*/
|
||||
void
|
||||
ctf_get_ctm_info(const ctf_file_t *fp, const void *v, size_t size,
|
||||
size_t *incrementp, uint_t *typep, ulong_t *offsetp, const char **namep)
|
||||
{
|
||||
size_t increment;
|
||||
ulong_t offset;
|
||||
uint_t name, type;
|
||||
|
||||
if (fp->ctf_version == CTF_VERSION_2) {
|
||||
if (size < CTF_V2_LSTRUCT_THRESH) {
|
||||
const struct ctf_member_v2 *ctm = v;
|
||||
|
||||
name = ctm->ctm_name;
|
||||
type = ctm->ctm_type;
|
||||
offset = ctm->ctm_offset;
|
||||
increment = sizeof(*ctm);
|
||||
} else {
|
||||
const struct ctf_lmember_v2 *ctlm = v;
|
||||
|
||||
name = ctlm->ctlm_name;
|
||||
type = ctlm->ctlm_type;
|
||||
offset = (ulong_t)CTF_LMEM_OFFSET(ctlm);
|
||||
increment = sizeof(*ctlm);
|
||||
}
|
||||
} else {
|
||||
if (size < CTF_V3_LSTRUCT_THRESH) {
|
||||
const struct ctf_member_v3 *ctm = v;
|
||||
|
||||
name = ctm->ctm_name;
|
||||
type = ctm->ctm_type;
|
||||
offset = ctm->ctm_offset;
|
||||
increment = sizeof(*ctm);
|
||||
} else {
|
||||
const struct ctf_lmember_v3 *ctlm = v;
|
||||
|
||||
name = ctlm->ctlm_name;
|
||||
type = ctlm->ctlm_type;
|
||||
offset = (ulong_t)CTF_LMEM_OFFSET(ctlm);
|
||||
increment = sizeof(*ctlm);
|
||||
}
|
||||
}
|
||||
|
||||
if (incrementp != NULL)
|
||||
*incrementp = increment;
|
||||
if (typep != NULL)
|
||||
*typep = type;
|
||||
if (offsetp != NULL)
|
||||
*offsetp = offset;
|
||||
if (namep != NULL)
|
||||
*namep = ctf_strraw(fp, name);
|
||||
}
|
||||
|
||||
/*
|
||||
* Iterate over the members of a STRUCT or UNION. We pass the name, member
|
||||
* type, and offset of each member to the specified callback function.
|
||||
@ -57,9 +184,9 @@ int
|
||||
ctf_member_iter(ctf_file_t *fp, ctf_id_t type, ctf_member_f *func, void *arg)
|
||||
{
|
||||
ctf_file_t *ofp = fp;
|
||||
const ctf_type_t *tp;
|
||||
const void *tp;
|
||||
ssize_t size, increment;
|
||||
uint_t kind, n;
|
||||
uint_t kind, n, vlen;
|
||||
int rc;
|
||||
|
||||
if ((type = ctf_type_resolve(fp, type)) == CTF_ERR)
|
||||
@ -69,32 +196,22 @@ ctf_member_iter(ctf_file_t *fp, ctf_id_t type, ctf_member_f *func, void *arg)
|
||||
return (CTF_ERR); /* errno is set for us */
|
||||
|
||||
(void) ctf_get_ctt_size(fp, tp, &size, &increment);
|
||||
kind = LCTF_INFO_KIND(fp, tp->ctt_info);
|
||||
ctf_get_ctt_info(fp, tp, &kind, &vlen, NULL);
|
||||
|
||||
if (kind != CTF_K_STRUCT && kind != CTF_K_UNION)
|
||||
return (ctf_set_errno(ofp, ECTF_NOTSOU));
|
||||
|
||||
if (size < CTF_LSTRUCT_THRESH) {
|
||||
const ctf_member_t *mp = (const ctf_member_t *)
|
||||
((uintptr_t)tp + increment);
|
||||
const char *mp = (const char *)((uintptr_t)tp + increment);
|
||||
|
||||
for (n = LCTF_INFO_VLEN(fp, tp->ctt_info); n != 0; n--, mp++) {
|
||||
const char *name = ctf_strptr(fp, mp->ctm_name);
|
||||
if ((rc = func(name, mp->ctm_type, mp->ctm_offset,
|
||||
arg)) != 0)
|
||||
return (rc);
|
||||
}
|
||||
for (n = vlen; n != 0; n--, mp += increment) {
|
||||
const char *name;
|
||||
ulong_t offset;
|
||||
uint_t type;
|
||||
|
||||
} else {
|
||||
const ctf_lmember_t *lmp = (const ctf_lmember_t *)
|
||||
((uintptr_t)tp + increment);
|
||||
|
||||
for (n = LCTF_INFO_VLEN(fp, tp->ctt_info); n != 0; n--, lmp++) {
|
||||
const char *name = ctf_strptr(fp, lmp->ctlm_name);
|
||||
if ((rc = func(name, lmp->ctlm_type,
|
||||
(ulong_t)CTF_LMEM_OFFSET(lmp), arg)) != 0)
|
||||
return (rc);
|
||||
}
|
||||
ctf_get_ctm_info(fp, mp, size, &increment, &type, &offset,
|
||||
&name);
|
||||
if ((rc = func(name, type, offset, arg)) != 0)
|
||||
return (rc);
|
||||
}
|
||||
|
||||
return (0);
|
||||
@ -108,10 +225,10 @@ int
|
||||
ctf_enum_iter(ctf_file_t *fp, ctf_id_t type, ctf_enum_f *func, void *arg)
|
||||
{
|
||||
ctf_file_t *ofp = fp;
|
||||
const ctf_type_t *tp;
|
||||
const void *tp;
|
||||
const ctf_enum_t *ep;
|
||||
ssize_t increment;
|
||||
uint_t n;
|
||||
uint_t kind, n, vlen;
|
||||
int rc;
|
||||
|
||||
if ((type = ctf_type_resolve(fp, type)) == CTF_ERR)
|
||||
@ -120,14 +237,15 @@ ctf_enum_iter(ctf_file_t *fp, ctf_id_t type, ctf_enum_f *func, void *arg)
|
||||
if ((tp = ctf_lookup_by_id(&fp, type)) == NULL)
|
||||
return (CTF_ERR); /* errno is set for us */
|
||||
|
||||
if (LCTF_INFO_KIND(fp, tp->ctt_info) != CTF_K_ENUM)
|
||||
ctf_get_ctt_info(fp, tp, &kind, &vlen, NULL);
|
||||
if (kind != CTF_K_ENUM)
|
||||
return (ctf_set_errno(ofp, ECTF_NOTENUM));
|
||||
|
||||
(void) ctf_get_ctt_size(fp, tp, NULL, &increment);
|
||||
|
||||
ep = (const ctf_enum_t *)((uintptr_t)tp + increment);
|
||||
|
||||
for (n = LCTF_INFO_VLEN(fp, tp->ctt_info); n != 0; n--, ep++) {
|
||||
for (n = vlen; n != 0; n--, ep++) {
|
||||
const char *name = ctf_strptr(fp, ep->cte_name);
|
||||
if ((rc = func(name, ep->cte_value, arg)) != 0)
|
||||
return (rc);
|
||||
@ -145,11 +263,13 @@ ctf_type_iter(ctf_file_t *fp, ctf_type_f *func, void *arg)
|
||||
{
|
||||
ctf_id_t id, max = fp->ctf_typemax;
|
||||
int rc, child = (fp->ctf_flags & LCTF_CHILD);
|
||||
int isroot;
|
||||
|
||||
for (id = 1; id <= max; id++) {
|
||||
const ctf_type_t *tp = LCTF_INDEX_TO_TYPEPTR(fp, id);
|
||||
if (CTF_INFO_ISROOT(tp->ctt_info) &&
|
||||
(rc = func(CTF_INDEX_TO_TYPE(id, child), arg)) != 0)
|
||||
const void *tp = LCTF_INDEX_TO_TYPEPTR(fp, id);
|
||||
ctf_get_ctt_info(fp, tp, NULL, NULL, &isroot);
|
||||
if (isroot &&
|
||||
(rc = func(LCTF_INDEX_TO_TYPE(fp, id, child), arg)) != 0)
|
||||
return (rc);
|
||||
}
|
||||
|
||||
@ -168,21 +288,23 @@ ctf_type_resolve(ctf_file_t *fp, ctf_id_t type)
|
||||
{
|
||||
ctf_id_t prev = type, otype = type;
|
||||
ctf_file_t *ofp = fp;
|
||||
const ctf_type_t *tp;
|
||||
const void *tp;
|
||||
uint_t kind, ctype;
|
||||
|
||||
while ((tp = ctf_lookup_by_id(&fp, type)) != NULL) {
|
||||
switch (LCTF_INFO_KIND(fp, tp->ctt_info)) {
|
||||
ctf_get_ctt_info(fp, tp, &kind, NULL, NULL);
|
||||
switch (kind) {
|
||||
case CTF_K_TYPEDEF:
|
||||
case CTF_K_VOLATILE:
|
||||
case CTF_K_CONST:
|
||||
case CTF_K_RESTRICT:
|
||||
if (tp->ctt_type == type || tp->ctt_type == otype ||
|
||||
tp->ctt_type == prev) {
|
||||
ctf_get_ctt_index(fp, tp, NULL, &ctype, NULL);
|
||||
if (ctype == type || ctype == otype || ctype == prev) {
|
||||
ctf_dprintf("type %ld cycle detected\n", otype);
|
||||
return (ctf_set_errno(ofp, ECTF_CORRUPT));
|
||||
}
|
||||
prev = type;
|
||||
type = tp->ctt_type;
|
||||
type = ctype;
|
||||
break;
|
||||
default:
|
||||
return (type);
|
||||
@ -237,9 +359,8 @@ ctf_type_qlname(ctf_file_t *fp, ctf_id_t type, char *buf, size_t len,
|
||||
cdp != NULL; cdp = ctf_list_next(cdp)) {
|
||||
|
||||
ctf_file_t *rfp = fp;
|
||||
const ctf_type_t *tp =
|
||||
ctf_lookup_by_id(&rfp, cdp->cd_type);
|
||||
const char *name = ctf_strptr(rfp, tp->ctt_name);
|
||||
const void *tp = ctf_lookup_by_id(&rfp, cdp->cd_type);
|
||||
const char *name = ctf_type_rname(rfp, tp);
|
||||
|
||||
if (k != CTF_K_POINTER && k != CTF_K_ARRAY)
|
||||
ctf_decl_sprintf(&cd, " ");
|
||||
@ -335,6 +456,23 @@ ctf_type_qname(ctf_file_t *fp, ctf_id_t type, char *buf, size_t len,
|
||||
return (rv >= 0 && rv < len ? buf : NULL);
|
||||
}
|
||||
|
||||
const char *
|
||||
ctf_type_rname(ctf_file_t *fp, const void *v)
|
||||
{
|
||||
uint_t name;
|
||||
|
||||
if (fp->ctf_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(fp, name));
|
||||
}
|
||||
|
||||
/*
|
||||
* Resolve the type down to a base type node, and then return the size
|
||||
@ -343,9 +481,10 @@ ctf_type_qname(ctf_file_t *fp, ctf_id_t type, char *buf, size_t len,
|
||||
ssize_t
|
||||
ctf_type_size(ctf_file_t *fp, ctf_id_t type)
|
||||
{
|
||||
const ctf_type_t *tp;
|
||||
const void *tp;
|
||||
ssize_t size;
|
||||
ctf_arinfo_t ar;
|
||||
uint_t kind;
|
||||
|
||||
if ((type = ctf_type_resolve(fp, type)) == CTF_ERR)
|
||||
return (-1); /* errno is set for us */
|
||||
@ -353,7 +492,9 @@ ctf_type_size(ctf_file_t *fp, ctf_id_t type)
|
||||
if ((tp = ctf_lookup_by_id(&fp, type)) == NULL)
|
||||
return (-1); /* errno is set for us */
|
||||
|
||||
switch (LCTF_INFO_KIND(fp, tp->ctt_info)) {
|
||||
ctf_get_ctt_info(fp, tp, &kind, NULL, NULL);
|
||||
|
||||
switch (kind) {
|
||||
case CTF_K_POINTER:
|
||||
return (fp->ctf_dmodel->ctd_pointer);
|
||||
|
||||
@ -392,8 +533,9 @@ ctf_type_size(ctf_file_t *fp, ctf_id_t type)
|
||||
ssize_t
|
||||
ctf_type_align(ctf_file_t *fp, ctf_id_t type)
|
||||
{
|
||||
const ctf_type_t *tp;
|
||||
const void *tp;
|
||||
ctf_arinfo_t r;
|
||||
uint_t kind, vlen;
|
||||
|
||||
if ((type = ctf_type_resolve(fp, type)) == CTF_ERR)
|
||||
return (-1); /* errno is set for us */
|
||||
@ -401,7 +543,9 @@ ctf_type_align(ctf_file_t *fp, ctf_id_t type)
|
||||
if ((tp = ctf_lookup_by_id(&fp, type)) == NULL)
|
||||
return (-1); /* errno is set for us */
|
||||
|
||||
switch (LCTF_INFO_KIND(fp, tp->ctt_info)) {
|
||||
ctf_get_ctt_info(fp, tp, &kind, &vlen, NULL);
|
||||
|
||||
switch (kind) {
|
||||
case CTF_K_POINTER:
|
||||
case CTF_K_FUNCTION:
|
||||
return (fp->ctf_dmodel->ctd_pointer);
|
||||
@ -413,7 +557,7 @@ ctf_type_align(ctf_file_t *fp, ctf_id_t type)
|
||||
|
||||
case CTF_K_STRUCT:
|
||||
case CTF_K_UNION: {
|
||||
uint_t n = LCTF_INFO_VLEN(fp, tp->ctt_info);
|
||||
uint_t n = vlen;
|
||||
ssize_t size, increment;
|
||||
size_t align = 0;
|
||||
const void *vmp;
|
||||
@ -421,21 +565,16 @@ ctf_type_align(ctf_file_t *fp, ctf_id_t type)
|
||||
(void) ctf_get_ctt_size(fp, tp, &size, &increment);
|
||||
vmp = (uchar_t *)tp + increment;
|
||||
|
||||
if (LCTF_INFO_KIND(fp, tp->ctt_info) == CTF_K_STRUCT)
|
||||
if (kind == CTF_K_STRUCT)
|
||||
n = MIN(n, 1); /* only use first member for structs */
|
||||
|
||||
if (size < CTF_LSTRUCT_THRESH) {
|
||||
const ctf_member_t *mp = vmp;
|
||||
for (; n != 0; n--, mp++) {
|
||||
ssize_t am = ctf_type_align(fp, mp->ctm_type);
|
||||
align = MAX(align, am);
|
||||
}
|
||||
} else {
|
||||
const ctf_lmember_t *lmp = vmp;
|
||||
for (; n != 0; n--, lmp++) {
|
||||
ssize_t am = ctf_type_align(fp, lmp->ctlm_type);
|
||||
align = MAX(align, am);
|
||||
}
|
||||
for (const char *mp = vmp; n != 0; n--, mp += increment) {
|
||||
uint_t type;
|
||||
|
||||
ctf_get_ctm_info(fp, mp, size, &increment, &type,
|
||||
NULL, NULL);
|
||||
ssize_t am = ctf_type_align(fp, type);
|
||||
align = MAX(align, am);
|
||||
}
|
||||
|
||||
return (align);
|
||||
@ -455,12 +594,15 @@ ctf_type_align(ctf_file_t *fp, ctf_id_t type)
|
||||
int
|
||||
ctf_type_kind(ctf_file_t *fp, ctf_id_t type)
|
||||
{
|
||||
const ctf_type_t *tp;
|
||||
const void *tp;
|
||||
uint_t kind;
|
||||
|
||||
if ((tp = ctf_lookup_by_id(&fp, type)) == NULL)
|
||||
return (CTF_ERR); /* errno is set for us */
|
||||
|
||||
return (LCTF_INFO_KIND(fp, tp->ctt_info));
|
||||
ctf_get_ctt_info(fp, tp, &kind, NULL, NULL);
|
||||
|
||||
return (kind);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -471,18 +613,22 @@ ctf_id_t
|
||||
ctf_type_reference(ctf_file_t *fp, ctf_id_t type)
|
||||
{
|
||||
ctf_file_t *ofp = fp;
|
||||
const ctf_type_t *tp;
|
||||
const void *tp;
|
||||
uint_t ctype, kind;
|
||||
|
||||
if ((tp = ctf_lookup_by_id(&fp, type)) == NULL)
|
||||
return (CTF_ERR); /* errno is set for us */
|
||||
|
||||
switch (LCTF_INFO_KIND(fp, tp->ctt_info)) {
|
||||
ctf_get_ctt_info(fp, tp, &kind, NULL, NULL);
|
||||
|
||||
switch (kind) {
|
||||
case CTF_K_POINTER:
|
||||
case CTF_K_TYPEDEF:
|
||||
case CTF_K_VOLATILE:
|
||||
case CTF_K_CONST:
|
||||
case CTF_K_RESTRICT:
|
||||
return (tp->ctt_type);
|
||||
ctf_get_ctt_index(fp, tp, NULL, &ctype, NULL);
|
||||
return (ctype);
|
||||
default:
|
||||
return (ctf_set_errno(ofp, ECTF_NOTREF));
|
||||
}
|
||||
@ -504,8 +650,8 @@ ctf_type_pointer(ctf_file_t *fp, ctf_id_t type)
|
||||
if (ctf_lookup_by_id(&fp, type) == NULL)
|
||||
return (CTF_ERR); /* errno is set for us */
|
||||
|
||||
if ((ntype = fp->ctf_ptrtab[CTF_TYPE_TO_INDEX(type)]) != 0)
|
||||
return (CTF_INDEX_TO_TYPE(ntype, (fp->ctf_flags & LCTF_CHILD)));
|
||||
if ((ntype = fp->ctf_ptrtab[LCTF_TYPE_TO_INDEX(fp, type)]) != 0)
|
||||
return (LCTF_INDEX_TO_TYPE(fp, ntype, (fp->ctf_flags & LCTF_CHILD)));
|
||||
|
||||
if ((type = ctf_type_resolve(fp, type)) == CTF_ERR)
|
||||
return (ctf_set_errno(ofp, ECTF_NOTYPE));
|
||||
@ -513,8 +659,8 @@ ctf_type_pointer(ctf_file_t *fp, ctf_id_t type)
|
||||
if (ctf_lookup_by_id(&fp, type) == NULL)
|
||||
return (ctf_set_errno(ofp, ECTF_NOTYPE));
|
||||
|
||||
if ((ntype = fp->ctf_ptrtab[CTF_TYPE_TO_INDEX(type)]) != 0)
|
||||
return (CTF_INDEX_TO_TYPE(ntype, (fp->ctf_flags & LCTF_CHILD)));
|
||||
if ((ntype = fp->ctf_ptrtab[LCTF_TYPE_TO_INDEX(fp, type)]) != 0)
|
||||
return (LCTF_INDEX_TO_TYPE(fp, ntype, (fp->ctf_flags & LCTF_CHILD)));
|
||||
|
||||
return (ctf_set_errno(ofp, ECTF_NOTYPE));
|
||||
}
|
||||
@ -526,16 +672,17 @@ int
|
||||
ctf_type_encoding(ctf_file_t *fp, ctf_id_t type, ctf_encoding_t *ep)
|
||||
{
|
||||
ctf_file_t *ofp = fp;
|
||||
const ctf_type_t *tp;
|
||||
const void *tp;
|
||||
ssize_t increment;
|
||||
uint_t data;
|
||||
uint_t data, kind;
|
||||
|
||||
if ((tp = ctf_lookup_by_id(&fp, type)) == NULL)
|
||||
return (CTF_ERR); /* errno is set for us */
|
||||
|
||||
(void) ctf_get_ctt_size(fp, tp, NULL, &increment);
|
||||
ctf_get_ctt_info(fp, tp, &kind, NULL, NULL);
|
||||
|
||||
switch (LCTF_INFO_KIND(fp, tp->ctt_info)) {
|
||||
switch (kind) {
|
||||
case CTF_K_INTEGER:
|
||||
data = *(const uint_t *)((uintptr_t)tp + increment);
|
||||
ep->cte_format = CTF_INT_ENCODING(data);
|
||||
@ -570,10 +717,10 @@ ctf_type_cmp(ctf_file_t *lfp, ctf_id_t ltype, ctf_file_t *rfp, ctf_id_t rtype)
|
||||
if (lfp == rfp)
|
||||
return (rval);
|
||||
|
||||
if (CTF_TYPE_ISPARENT(ltype) && lfp->ctf_parent != NULL)
|
||||
if (LCTF_TYPE_ISPARENT(lfp, ltype) && lfp->ctf_parent != NULL)
|
||||
lfp = lfp->ctf_parent;
|
||||
|
||||
if (CTF_TYPE_ISPARENT(rtype) && rfp->ctf_parent != NULL)
|
||||
if (LCTF_TYPE_ISPARENT(rfp, rtype) && rfp->ctf_parent != NULL)
|
||||
rfp = rfp->ctf_parent;
|
||||
|
||||
if (lfp < rfp)
|
||||
@ -595,7 +742,7 @@ int
|
||||
ctf_type_compat(ctf_file_t *lfp, ctf_id_t ltype,
|
||||
ctf_file_t *rfp, ctf_id_t rtype)
|
||||
{
|
||||
const ctf_type_t *ltp, *rtp;
|
||||
const void *ltp, *rtp;
|
||||
ctf_encoding_t le, re;
|
||||
ctf_arinfo_t la, ra;
|
||||
uint_t lkind, rkind;
|
||||
@ -612,8 +759,7 @@ ctf_type_compat(ctf_file_t *lfp, ctf_id_t ltype,
|
||||
if (lkind != rkind ||
|
||||
(ltp = ctf_lookup_by_id(&lfp, ltype)) == NULL ||
|
||||
(rtp = ctf_lookup_by_id(&rfp, rtype)) == NULL ||
|
||||
strcmp(ctf_strptr(lfp, ltp->ctt_name),
|
||||
ctf_strptr(rfp, rtp->ctt_name)) != 0)
|
||||
strcmp(ctf_type_rname(lfp, ltp), ctf_type_rname(rfp, rtp)) != 0)
|
||||
return (0);
|
||||
|
||||
switch (lkind) {
|
||||
@ -647,9 +793,9 @@ _ctf_member_info(ctf_file_t *fp, ctf_id_t type, const char *name, ulong_t off,
|
||||
ctf_membinfo_t *mip)
|
||||
{
|
||||
ctf_file_t *ofp = fp;
|
||||
const ctf_type_t *tp;
|
||||
const void *tp;
|
||||
ssize_t size, increment;
|
||||
uint_t kind, n;
|
||||
uint_t kind, n, vlen;
|
||||
|
||||
if ((type = ctf_type_resolve(fp, type)) == CTF_ERR)
|
||||
return (CTF_ERR); /* errno is set for us */
|
||||
@ -658,41 +804,27 @@ _ctf_member_info(ctf_file_t *fp, ctf_id_t type, const char *name, ulong_t off,
|
||||
return (CTF_ERR); /* errno is set for us */
|
||||
|
||||
(void) ctf_get_ctt_size(fp, tp, &size, &increment);
|
||||
kind = LCTF_INFO_KIND(fp, tp->ctt_info);
|
||||
ctf_get_ctt_info(fp, tp, &kind, &vlen, NULL);
|
||||
|
||||
if (kind != CTF_K_STRUCT && kind != CTF_K_UNION)
|
||||
return (ctf_set_errno(ofp, ECTF_NOTSOU));
|
||||
|
||||
if (size < CTF_LSTRUCT_THRESH) {
|
||||
const ctf_member_t *mp = (const ctf_member_t *)
|
||||
((uintptr_t)tp + increment);
|
||||
const char *mp = (const char *)((uintptr_t)tp + increment);
|
||||
|
||||
for (n = LCTF_INFO_VLEN(fp, tp->ctt_info); n != 0; n--, mp++) {
|
||||
if (mp->ctm_name == 0 &&
|
||||
_ctf_member_info(fp, mp->ctm_type, name,
|
||||
mp->ctm_offset + off, mip) == 0)
|
||||
return (0);
|
||||
if (strcmp(ctf_strptr(fp, mp->ctm_name), name) == 0) {
|
||||
mip->ctm_type = mp->ctm_type;
|
||||
mip->ctm_offset = mp->ctm_offset + off;
|
||||
return (0);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
const ctf_lmember_t *lmp = (const ctf_lmember_t *)
|
||||
((uintptr_t)tp + increment);
|
||||
for (n = vlen; n != 0; n--, mp += increment) {
|
||||
const char *name1;
|
||||
ulong_t offset;
|
||||
uint_t type;
|
||||
|
||||
for (n = LCTF_INFO_VLEN(fp, tp->ctt_info); n != 0; n--, lmp++) {
|
||||
if (lmp->ctlm_name == 0 &&
|
||||
_ctf_member_info(fp, lmp->ctlm_name, name,
|
||||
(ulong_t)CTF_LMEM_OFFSET(lmp) + off, mip) == 0)
|
||||
return (0);
|
||||
if (strcmp(ctf_strptr(fp, lmp->ctlm_name), name) == 0) {
|
||||
mip->ctm_type = lmp->ctlm_type;
|
||||
mip->ctm_offset =
|
||||
(ulong_t)CTF_LMEM_OFFSET(lmp) + off;
|
||||
return (0);
|
||||
}
|
||||
ctf_get_ctm_info(fp, mp, size, &increment, &type, &offset,
|
||||
&name1);
|
||||
if (name1 == NULL &&
|
||||
_ctf_member_info(fp, type, name1, offset + off, mip) == 0)
|
||||
return (0);
|
||||
if (strcmp(name1, name) == 0) {
|
||||
mip->ctm_type = type;
|
||||
mip->ctm_offset = offset + off;
|
||||
return (0);
|
||||
}
|
||||
}
|
||||
|
||||
@ -717,22 +849,34 @@ int
|
||||
ctf_array_info(ctf_file_t *fp, ctf_id_t type, ctf_arinfo_t *arp)
|
||||
{
|
||||
ctf_file_t *ofp = fp;
|
||||
const ctf_type_t *tp;
|
||||
const ctf_array_t *ap;
|
||||
const void *ap, *tp;
|
||||
ssize_t increment;
|
||||
uint_t kind;
|
||||
|
||||
if ((tp = ctf_lookup_by_id(&fp, type)) == NULL)
|
||||
return (CTF_ERR); /* errno is set for us */
|
||||
|
||||
if (LCTF_INFO_KIND(fp, tp->ctt_info) != CTF_K_ARRAY)
|
||||
ctf_get_ctt_info(fp, tp, &kind, NULL, NULL);
|
||||
|
||||
if (kind != CTF_K_ARRAY)
|
||||
return (ctf_set_errno(ofp, ECTF_NOTARRAY));
|
||||
|
||||
(void) ctf_get_ctt_size(fp, 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;
|
||||
ap = (const void *)((uintptr_t)tp + increment);
|
||||
if (fp->ctf_version == CTF_VERSION_2) {
|
||||
const struct ctf_array_v2 *ap2 = ap;
|
||||
|
||||
arp->ctr_contents = ap2->cta_contents;
|
||||
arp->ctr_index = ap2->cta_index;
|
||||
arp->ctr_nelems = ap2->cta_nelems;
|
||||
} else {
|
||||
const struct ctf_array_v3 *ap3 = ap;
|
||||
|
||||
arp->ctr_contents = ap3->cta_contents;
|
||||
arp->ctr_index = ap3->cta_index;
|
||||
arp->ctr_nelems = ap3->cta_nelems;
|
||||
}
|
||||
|
||||
return (0);
|
||||
}
|
||||
@ -745,10 +889,10 @@ const char *
|
||||
ctf_enum_name(ctf_file_t *fp, ctf_id_t type, int value)
|
||||
{
|
||||
ctf_file_t *ofp = fp;
|
||||
const ctf_type_t *tp;
|
||||
const void *tp;
|
||||
const ctf_enum_t *ep;
|
||||
ssize_t increment;
|
||||
uint_t n;
|
||||
uint_t kind, n, vlen;
|
||||
|
||||
if ((type = ctf_type_resolve(fp, type)) == CTF_ERR)
|
||||
return (NULL); /* errno is set for us */
|
||||
@ -756,7 +900,9 @@ ctf_enum_name(ctf_file_t *fp, ctf_id_t type, int value)
|
||||
if ((tp = ctf_lookup_by_id(&fp, type)) == NULL)
|
||||
return (NULL); /* errno is set for us */
|
||||
|
||||
if (LCTF_INFO_KIND(fp, tp->ctt_info) != CTF_K_ENUM) {
|
||||
ctf_get_ctt_info(fp, tp, &kind, &vlen, NULL);
|
||||
|
||||
if (kind != CTF_K_ENUM) {
|
||||
(void) ctf_set_errno(ofp, ECTF_NOTENUM);
|
||||
return (NULL);
|
||||
}
|
||||
@ -765,7 +911,7 @@ ctf_enum_name(ctf_file_t *fp, ctf_id_t type, int value)
|
||||
|
||||
ep = (const ctf_enum_t *)((uintptr_t)tp + increment);
|
||||
|
||||
for (n = LCTF_INFO_VLEN(fp, tp->ctt_info); n != 0; n--, ep++) {
|
||||
for (n = vlen; n != 0; n--, ep++) {
|
||||
if (ep->cte_value == value)
|
||||
return (ctf_strptr(fp, ep->cte_name));
|
||||
}
|
||||
@ -782,10 +928,10 @@ int
|
||||
ctf_enum_value(ctf_file_t *fp, ctf_id_t type, const char *name, int *valp)
|
||||
{
|
||||
ctf_file_t *ofp = fp;
|
||||
const ctf_type_t *tp;
|
||||
const void *tp;
|
||||
const ctf_enum_t *ep;
|
||||
ssize_t size, increment;
|
||||
uint_t n;
|
||||
uint_t kind, n, vlen;
|
||||
|
||||
if ((type = ctf_type_resolve(fp, type)) == CTF_ERR)
|
||||
return (CTF_ERR); /* errno is set for us */
|
||||
@ -793,7 +939,9 @@ ctf_enum_value(ctf_file_t *fp, ctf_id_t type, const char *name, int *valp)
|
||||
if ((tp = ctf_lookup_by_id(&fp, type)) == NULL)
|
||||
return (CTF_ERR); /* errno is set for us */
|
||||
|
||||
if (LCTF_INFO_KIND(fp, tp->ctt_info) != CTF_K_ENUM) {
|
||||
ctf_get_ctt_info(fp, tp, &kind, &vlen, NULL);
|
||||
|
||||
if (kind != CTF_K_ENUM) {
|
||||
(void) ctf_set_errno(ofp, ECTF_NOTENUM);
|
||||
return (CTF_ERR);
|
||||
}
|
||||
@ -802,7 +950,7 @@ ctf_enum_value(ctf_file_t *fp, ctf_id_t type, const char *name, int *valp)
|
||||
|
||||
ep = (const ctf_enum_t *)((uintptr_t)tp + increment);
|
||||
|
||||
for (n = LCTF_INFO_VLEN(fp, tp->ctt_info); n != 0; n--, ep++) {
|
||||
for (n = vlen; n != 0; n--, ep++) {
|
||||
if (strcmp(ctf_strptr(fp, ep->cte_name), name) == 0) {
|
||||
if (valp != NULL)
|
||||
*valp = ep->cte_value;
|
||||
@ -826,9 +974,9 @@ ctf_type_rvisit(ctf_file_t *fp, ctf_id_t type, ctf_visit_f *func, void *arg,
|
||||
const char *name, ulong_t offset, int depth)
|
||||
{
|
||||
ctf_id_t otype = type;
|
||||
const ctf_type_t *tp;
|
||||
const void *tp;
|
||||
ssize_t size, increment;
|
||||
uint_t kind, n;
|
||||
uint_t kind, n, vlen;
|
||||
int rc;
|
||||
|
||||
if ((type = ctf_type_resolve(fp, type)) == CTF_ERR)
|
||||
@ -840,35 +988,24 @@ ctf_type_rvisit(ctf_file_t *fp, ctf_id_t type, ctf_visit_f *func, void *arg,
|
||||
if ((rc = func(name, otype, offset, depth, arg)) != 0)
|
||||
return (rc);
|
||||
|
||||
kind = LCTF_INFO_KIND(fp, tp->ctt_info);
|
||||
ctf_get_ctt_info(fp, tp, &kind, &vlen, NULL);
|
||||
|
||||
if (kind != CTF_K_STRUCT && kind != CTF_K_UNION)
|
||||
return (0);
|
||||
|
||||
(void) ctf_get_ctt_size(fp, tp, &size, &increment);
|
||||
|
||||
if (size < CTF_LSTRUCT_THRESH) {
|
||||
const ctf_member_t *mp = (const ctf_member_t *)
|
||||
((uintptr_t)tp + increment);
|
||||
const char *mp = (const char *)((uintptr_t)tp + increment);
|
||||
for (n = vlen; n != 0; n--, mp += increment) {
|
||||
const char *name;
|
||||
ulong_t offset1;
|
||||
uint_t type;
|
||||
|
||||
for (n = LCTF_INFO_VLEN(fp, tp->ctt_info); n != 0; n--, mp++) {
|
||||
if ((rc = ctf_type_rvisit(fp, mp->ctm_type,
|
||||
func, arg, ctf_strptr(fp, mp->ctm_name),
|
||||
offset + mp->ctm_offset, depth + 1)) != 0)
|
||||
return (rc);
|
||||
}
|
||||
|
||||
} else {
|
||||
const ctf_lmember_t *lmp = (const ctf_lmember_t *)
|
||||
((uintptr_t)tp + increment);
|
||||
|
||||
for (n = LCTF_INFO_VLEN(fp, tp->ctt_info); n != 0; n--, lmp++) {
|
||||
if ((rc = ctf_type_rvisit(fp, lmp->ctlm_type,
|
||||
func, arg, ctf_strptr(fp, lmp->ctlm_name),
|
||||
offset + (ulong_t)CTF_LMEM_OFFSET(lmp),
|
||||
depth + 1)) != 0)
|
||||
return (rc);
|
||||
}
|
||||
ctf_get_ctm_info(fp, mp, size, &increment, &type, &offset1,
|
||||
&name);
|
||||
if ((rc = ctf_type_rvisit(fp, type, func, arg, name,
|
||||
offset + offset1, depth + 1)) != 0)
|
||||
return (rc);
|
||||
}
|
||||
|
||||
return (0);
|
||||
|
@ -245,7 +245,8 @@ ctf_fdopen(int fd, int *errp)
|
||||
*/
|
||||
if (nbytes >= (ssize_t) sizeof (ctf_preamble_t) &&
|
||||
hdr.ctf.ctp_magic == CTF_MAGIC) {
|
||||
if (hdr.ctf.ctp_version > CTF_VERSION)
|
||||
if (hdr.ctf.ctp_version != CTF_VERSION_2 &&
|
||||
hdr.ctf.ctp_version != CTF_VERSION_3)
|
||||
return (ctf_set_open_errno(errp, ECTF_CTFVERS));
|
||||
|
||||
ctfsect.cts_data = mmap64(NULL, st.st_size, PROT_READ,
|
||||
|
Loading…
Reference in New Issue
Block a user