summaryrefslogtreecommitdiff
path: root/usr/src/common/ctf
diff options
context:
space:
mode:
authormws <none@none>2006-01-08 14:39:10 -0800
committermws <none@none>2006-01-08 14:39:10 -0800
commite4586ebf2f01666696316c178da243993b1a0c04 (patch)
tree8b48d38ef0f5c3449bce818de6bc85cbc54e7771 /usr/src/common/ctf
parent0578ac30778226273ab5a411148294e23d339851 (diff)
downloadillumos-joyent-e4586ebf2f01666696316c178da243993b1a0c04.tar.gz
6198296 dtrace's printf() misses a corner case
6235357 dtrace(1M) can't ignore SIGINT and SIGTERM 6282866 D string behaviors need some cleanup 6304467 dtrace -G by itself does nothing and produces no output 6305443 dtrace falls for typedef fake 6312329 qlen.d example won't parse 6312678 D compiler needs to resolve direct_declarator IDENT/TNAME ambiguity 6320980 ctf_enum_value() returns NULL instead of CTF_ERR on failure 6327910 req.flg entry missing for usr/src/common/smbios 6335522 smbios_bufopen() computes intermediate checksum using unpacked header 6335549 prtdiag: can't get smbios tables on toshiba tecra s1 laptop 6335559 smbios utility reports bogus cache size information 6368524 ctf_lookup_by_name() qualifier check can be made more efficient 6368526 fmd -o debug=help core dumps after printing help message 6368529 Psetbkpt() is returning EBUSY instead of setting errno to EBUSY
Diffstat (limited to 'usr/src/common/ctf')
-rw-r--r--usr/src/common/ctf/ctf_create.c219
-rw-r--r--usr/src/common/ctf/ctf_hash.c21
-rw-r--r--usr/src/common/ctf/ctf_impl.h11
-rw-r--r--usr/src/common/ctf/ctf_lookup.c42
-rw-r--r--usr/src/common/ctf/ctf_open.c104
-rw-r--r--usr/src/common/ctf/ctf_types.c9
6 files changed, 266 insertions, 140 deletions
diff --git a/usr/src/common/ctf/ctf_create.c b/usr/src/common/ctf/ctf_create.c
index 0fcdd75566..a4f3df34e8 100644
--- a/usr/src/common/ctf/ctf_create.c
+++ b/usr/src/common/ctf/ctf_create.c
@@ -19,8 +19,9 @@
*
* CDDL HEADER END
*/
+
/*
- * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -51,9 +52,14 @@ ctf_create(int *errp)
{
static const ctf_header_t hdr = { { CTF_MAGIC, CTF_VERSION, 0 } };
+ const ulong_t hashlen = 128;
+ ctf_dtdef_t **hash = ctf_alloc(hashlen * sizeof (ctf_dtdef_t *));
ctf_sect_t cts;
ctf_file_t *fp;
+ if (hash == NULL)
+ return (ctf_set_open_errno(errp, EAGAIN));
+
cts.cts_name = _CTF_SECTION;
cts.cts_type = SHT_PROGBITS;
cts.cts_flags = 0;
@@ -62,13 +68,19 @@ ctf_create(int *errp)
cts.cts_entsize = 1;
cts.cts_offset = 0;
- if ((fp = ctf_bufopen(&cts, NULL, NULL, errp)) != NULL) {
- fp->ctf_flags |= LCTF_RDWR;
- fp->ctf_dtstrlen = sizeof (_CTF_STRTAB_TEMPLATE);
- fp->ctf_dtnextid = 1;
- fp->ctf_dtoldid = 0;
+ if ((fp = ctf_bufopen(&cts, NULL, NULL, errp)) == NULL) {
+ ctf_free(hash, hashlen * sizeof (ctf_dtdef_t *));
+ return (NULL);
}
+ fp->ctf_flags |= LCTF_RDWR;
+ fp->ctf_dthashlen = hashlen;
+ bzero(hash, hashlen * sizeof (ctf_dtdef_t *));
+ fp->ctf_dthash = hash;
+ fp->ctf_dtstrlen = sizeof (_CTF_STRTAB_TEMPLATE);
+ fp->ctf_dtnextid = 1;
+ fp->ctf_dtoldid = 0;
+
return (fp);
}
@@ -371,13 +383,18 @@ ctf_update(ctf_file_t *fp)
nfp->ctf_refcnt = fp->ctf_refcnt;
nfp->ctf_flags |= fp->ctf_flags & ~LCTF_DIRTY;
nfp->ctf_data.cts_data = NULL; /* force ctf_data_free() on close */
+ nfp->ctf_dthash = fp->ctf_dthash;
+ nfp->ctf_dthashlen = fp->ctf_dthashlen;
nfp->ctf_dtdefs = fp->ctf_dtdefs;
nfp->ctf_dtstrlen = fp->ctf_dtstrlen;
nfp->ctf_dtnextid = fp->ctf_dtnextid;
nfp->ctf_dtoldid = fp->ctf_dtnextid - 1;
nfp->ctf_specific = fp->ctf_specific;
+ fp->ctf_dthash = NULL;
+ fp->ctf_dthashlen = 0;
bzero(&fp->ctf_dtdefs, sizeof (ctf_list_t));
+
bcopy(fp, &ofp, sizeof (ctf_file_t));
bcopy(nfp, fp, sizeof (ctf_file_t));
bcopy(&ofp, nfp, sizeof (ctf_file_t));
@@ -398,6 +415,82 @@ ctf_update(ctf_file_t *fp)
return (0);
}
+void
+ctf_dtd_insert(ctf_file_t *fp, ctf_dtdef_t *dtd)
+{
+ ulong_t h = dtd->dtd_type & (fp->ctf_dthashlen - 1);
+
+ dtd->dtd_hash = fp->ctf_dthash[h];
+ fp->ctf_dthash[h] = dtd;
+ ctf_list_append(&fp->ctf_dtdefs, dtd);
+}
+
+void
+ctf_dtd_delete(ctf_file_t *fp, ctf_dtdef_t *dtd)
+{
+ ulong_t h = dtd->dtd_type & (fp->ctf_dthashlen - 1);
+ ctf_dtdef_t *p, **q = &fp->ctf_dthash[h];
+ ctf_dmdef_t *dmd, *nmd;
+ size_t len;
+
+ for (p = *q; p != NULL; p = p->dtd_hash) {
+ if (p != dtd)
+ q = &p->dtd_hash;
+ else
+ break;
+ }
+
+ if (p != NULL)
+ *q = p->dtd_hash;
+
+ switch (CTF_INFO_KIND(dtd->dtd_data.ctt_info)) {
+ case CTF_K_STRUCT:
+ case CTF_K_UNION:
+ case CTF_K_ENUM:
+ for (dmd = ctf_list_next(&dtd->dtd_u.dtu_members);
+ dmd != NULL; dmd = nmd) {
+ if (dmd->dmd_name != NULL) {
+ len = strlen(dmd->dmd_name) + 1;
+ ctf_free(dmd->dmd_name, len);
+ fp->ctf_dtstrlen -= len;
+ }
+ nmd = ctf_list_next(dmd);
+ ctf_free(dmd, sizeof (ctf_dmdef_t));
+ }
+ break;
+ case CTF_K_FUNCTION:
+ ctf_free(dtd->dtd_u.dtu_argv, sizeof (ctf_id_t) *
+ CTF_INFO_VLEN(dtd->dtd_data.ctt_info));
+ break;
+ }
+
+ if (dtd->dtd_name) {
+ len = strlen(dtd->dtd_name) + 1;
+ ctf_free(dtd->dtd_name, len);
+ fp->ctf_dtstrlen -= len;
+ }
+
+ ctf_list_delete(&fp->ctf_dtdefs, dtd);
+ ctf_free(dtd, sizeof (ctf_dtdef_t));
+}
+
+ctf_dtdef_t *
+ctf_dtd_lookup(ctf_file_t *fp, ctf_id_t type)
+{
+ ulong_t h = type & (fp->ctf_dthashlen - 1);
+ ctf_dtdef_t *dtd;
+
+ if (fp->ctf_dthash == NULL)
+ return (NULL);
+
+ for (dtd = fp->ctf_dthash[h]; dtd != NULL; dtd = dtd->dtd_hash) {
+ if (dtd->dtd_type == type)
+ break;
+ }
+
+ return (dtd);
+}
+
/*
* Discard all of the dynamic type definitions that have been added to the
* container since the last call to ctf_update(). We locate such types by
@@ -408,8 +501,6 @@ int
ctf_discard(ctf_file_t *fp)
{
ctf_dtdef_t *dtd, *ntd;
- ctf_dmdef_t *dmd, *nmd;
- size_t len;
if (!(fp->ctf_flags & LCTF_RDWR))
return (ctf_set_errno(fp, ECTF_RDONLY));
@@ -421,36 +512,8 @@ ctf_discard(ctf_file_t *fp)
if (dtd->dtd_type <= fp->ctf_dtoldid)
continue; /* skip types that have been committed */
- switch (CTF_INFO_KIND(dtd->dtd_data.ctt_info)) {
- case CTF_K_STRUCT:
- case CTF_K_UNION:
- case CTF_K_ENUM:
- for (dmd = ctf_list_next(&dtd->dtd_u.dtu_members);
- dmd != NULL; dmd = nmd) {
- if (dmd->dmd_name != NULL) {
- len = strlen(dmd->dmd_name) + 1;
- ctf_free(dmd->dmd_name, len);
- fp->ctf_dtstrlen -= len;
- }
- nmd = ctf_list_next(dmd);
- ctf_free(dmd, sizeof (ctf_dmdef_t));
- }
- break;
- case CTF_K_FUNCTION:
- ctf_free(dtd->dtd_u.dtu_argv, sizeof (ctf_id_t) *
- CTF_INFO_VLEN(dtd->dtd_data.ctt_info));
- break;
- }
-
- if (dtd->dtd_name) {
- len = strlen(dtd->dtd_name) + 1;
- ctf_free(dtd->dtd_name, len);
- fp->ctf_dtstrlen -= len;
- }
-
ntd = ctf_list_next(dtd);
- ctf_list_delete(&fp->ctf_dtdefs, dtd);
- ctf_free(dtd, sizeof (ctf_dtdef_t));
+ ctf_dtd_delete(fp, dtd);
}
fp->ctf_dtnextid = fp->ctf_dtoldid + 1;
@@ -493,7 +556,7 @@ ctf_add_generic(ctf_file_t *fp, uint_t flag, const char *name, ctf_dtdef_t **rp)
if (s != NULL)
fp->ctf_dtstrlen += strlen(s) + 1;
- ctf_list_append(&fp->ctf_dtdefs, dtd);
+ ctf_dtd_insert(fp, dtd);
fp->ctf_flags |= LCTF_DIRTY;
*rp = dtd;
@@ -599,17 +662,11 @@ ctf_add_array(ctf_file_t *fp, uint_t flag, const ctf_arinfo_t *arp)
int
ctf_set_array(ctf_file_t *fp, ctf_id_t type, const ctf_arinfo_t *arp)
{
- ctf_dtdef_t *dtd;
+ ctf_dtdef_t *dtd = ctf_dtd_lookup(fp, type);
if (!(fp->ctf_flags & LCTF_RDWR))
return (ctf_set_errno(fp, ECTF_RDONLY));
- for (dtd = ctf_list_next(&fp->ctf_dtdefs);
- dtd != NULL; dtd = ctf_list_next(dtd)) {
- if (dtd->dtd_type == type)
- break;
- }
-
if (dtd == NULL || CTF_INFO_KIND(dtd->dtd_data.ctt_info) != CTF_K_ARRAY)
return (ctf_set_errno(fp, ECTF_BADID));
@@ -661,36 +718,61 @@ ctf_add_function(ctf_file_t *fp, uint_t flag,
ctf_id_t
ctf_add_struct(ctf_file_t *fp, uint_t flag, const char *name)
{
+ ctf_hash_t *hp = &fp->ctf_structs;
+ ctf_helem_t *hep = NULL;
ctf_dtdef_t *dtd;
ctf_id_t type;
- if ((type = ctf_add_generic(fp, flag, name, &dtd)) == CTF_ERR)
+ if (name != NULL)
+ hep = ctf_hash_lookup(hp, fp, name, strlen(name));
+
+ if (hep != NULL && ctf_type_kind(fp, hep->h_type) == CTF_K_FORWARD)
+ dtd = ctf_dtd_lookup(fp, type = hep->h_type);
+ 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_size = 0;
+
return (type);
}
ctf_id_t
ctf_add_union(ctf_file_t *fp, uint_t flag, const char *name)
{
+ ctf_hash_t *hp = &fp->ctf_unions;
+ ctf_helem_t *hep = NULL;
ctf_dtdef_t *dtd;
ctf_id_t type;
- if ((type = ctf_add_generic(fp, flag, name, &dtd)) == CTF_ERR)
+ if (name != NULL)
+ hep = ctf_hash_lookup(hp, fp, name, strlen(name));
+
+ if (hep != NULL && ctf_type_kind(fp, hep->h_type) == CTF_K_FORWARD)
+ dtd = ctf_dtd_lookup(fp, type = hep->h_type);
+ 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_size = 0;
+
return (type);
}
ctf_id_t
ctf_add_enum(ctf_file_t *fp, uint_t flag, const char *name)
{
+ ctf_hash_t *hp = &fp->ctf_enums;
+ ctf_helem_t *hep = NULL;
ctf_dtdef_t *dtd;
ctf_id_t type;
- if ((type = ctf_add_generic(fp, flag, name, &dtd)) == CTF_ERR)
+ if (name != NULL)
+ hep = ctf_hash_lookup(hp, fp, name, strlen(name));
+
+ if (hep != NULL && ctf_type_kind(fp, hep->h_type) == CTF_K_FORWARD)
+ dtd = ctf_dtd_lookup(fp, type = hep->h_type);
+ 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);
@@ -702,16 +784,39 @@ ctf_add_enum(ctf_file_t *fp, uint_t flag, const char *name)
ctf_id_t
ctf_add_forward(ctf_file_t *fp, uint_t flag, const char *name, uint_t kind)
{
+ ctf_hash_t *hp;
+ ctf_helem_t *hep;
ctf_dtdef_t *dtd;
ctf_id_t type;
- if (kind != CTF_K_STRUCT && kind != CTF_K_UNION && kind != CTF_K_ENUM)
+ switch (kind) {
+ case CTF_K_STRUCT:
+ hp = &fp->ctf_structs;
+ break;
+ case CTF_K_UNION:
+ hp = &fp->ctf_unions;
+ break;
+ case CTF_K_ENUM:
+ hp = &fp->ctf_enums;
+ break;
+ default:
return (ctf_set_errno(fp, ECTF_NOTSUE));
+ }
+
+ /*
+ * If the type is already defined or exists as a forward tag, just
+ * return the ctf_id_t of the existing definition.
+ */
+ if (name != NULL && (hep = ctf_hash_lookup(hp,
+ fp, name, strlen(name))) != NULL)
+ return (hep->h_type);
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_type = kind;
+
return (type);
}
@@ -754,7 +859,7 @@ ctf_add_restrict(ctf_file_t *fp, uint_t flag, ctf_id_t ref)
int
ctf_add_enumerator(ctf_file_t *fp, ctf_id_t enid, const char *name, int value)
{
- ctf_dtdef_t *dtd;
+ ctf_dtdef_t *dtd = ctf_dtd_lookup(fp, enid);
ctf_dmdef_t *dmd;
uint_t kind, vlen, root;
@@ -766,12 +871,6 @@ ctf_add_enumerator(ctf_file_t *fp, ctf_id_t enid, const char *name, int value)
if (!(fp->ctf_flags & LCTF_RDWR))
return (ctf_set_errno(fp, ECTF_RDONLY));
- for (dtd = ctf_list_next(&fp->ctf_dtdefs);
- dtd != NULL; dtd = ctf_list_next(dtd)) {
- if (dtd->dtd_type == enid)
- break;
- }
-
if (dtd == NULL)
return (ctf_set_errno(fp, ECTF_BADID));
@@ -816,7 +915,7 @@ ctf_add_enumerator(ctf_file_t *fp, ctf_id_t enid, const char *name, int value)
int
ctf_add_member(ctf_file_t *fp, ctf_id_t souid, const char *name, ctf_id_t type)
{
- ctf_dtdef_t *dtd;
+ ctf_dtdef_t *dtd = ctf_dtd_lookup(fp, souid);
ctf_dmdef_t *dmd;
ssize_t msize, malign, ssize;
@@ -826,12 +925,6 @@ ctf_add_member(ctf_file_t *fp, ctf_id_t souid, const char *name, ctf_id_t type)
if (!(fp->ctf_flags & LCTF_RDWR))
return (ctf_set_errno(fp, ECTF_RDONLY));
- for (dtd = ctf_list_next(&fp->ctf_dtdefs);
- dtd != NULL; dtd = ctf_list_next(dtd)) {
- if (dtd->dtd_type == souid)
- break;
- }
-
if (dtd == NULL)
return (ctf_set_errno(fp, ECTF_BADID));
diff --git a/usr/src/common/ctf/ctf_hash.c b/usr/src/common/ctf/ctf_hash.c
index ff2ba61352..b10a7618f6 100644
--- a/usr/src/common/ctf/ctf_hash.c
+++ b/usr/src/common/ctf/ctf_hash.c
@@ -19,8 +19,9 @@
*
* CDDL HEADER END
*/
+
/*
- * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -122,6 +123,24 @@ ctf_hash_insert(ctf_hash_t *hp, ctf_file_t *fp, ushort_t type, uint_t name)
return (0);
}
+/*
+ * Wrapper for ctf_hash_lookup/ctf_hash_insert: if the key is already in the
+ * hash, override the previous definition with this new official definition.
+ * 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)
+{
+ const char *str = ctf_strptr(fp, name);
+ ctf_helem_t *hep = ctf_hash_lookup(hp, fp, str, strlen(str));
+
+ if (hep == NULL)
+ return (ctf_hash_insert(hp, fp, type, name));
+
+ hep->h_type = type;
+ return (0);
+}
+
ctf_helem_t *
ctf_hash_lookup(ctf_hash_t *hp, ctf_file_t *fp, const char *key, size_t len)
{
diff --git a/usr/src/common/ctf/ctf_impl.h b/usr/src/common/ctf/ctf_impl.h
index e56dbdff31..99990806a3 100644
--- a/usr/src/common/ctf/ctf_impl.h
+++ b/usr/src/common/ctf/ctf_impl.h
@@ -19,8 +19,9 @@
*
* CDDL HEADER END
*/
+
/*
- * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -144,6 +145,7 @@ typedef struct ctf_dmdef {
typedef struct ctf_dtdef {
ctf_list_t dtd_list; /* list forward/back pointers */
+ 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>) */
@@ -200,6 +202,8 @@ 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 */
+ 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 */
size_t ctf_dtstrlen; /* total length of dynamic type strings */
ulong_t ctf_dtnextid; /* next dynamic type id to assign */
@@ -275,6 +279,7 @@ extern const ctf_type_t *ctf_lookup_by_id(ctf_file_t **, ctf_id_t);
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 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 *);
@@ -287,6 +292,10 @@ extern void ctf_list_append(ctf_list_t *, void *);
extern void ctf_list_prepend(ctf_list_t *, void *);
extern void ctf_list_delete(ctf_list_t *, void *);
+extern void ctf_dtd_insert(ctf_file_t *, ctf_dtdef_t *);
+extern void ctf_dtd_delete(ctf_file_t *, ctf_dtdef_t *);
+extern ctf_dtdef_t *ctf_dtd_lookup(ctf_file_t *, ctf_id_t);
+
extern void ctf_decl_init(ctf_decl_t *, char *, size_t);
extern void ctf_decl_fini(ctf_decl_t *);
extern void ctf_decl_push(ctf_decl_t *, ctf_file_t *, ctf_id_t);
diff --git a/usr/src/common/ctf/ctf_lookup.c b/usr/src/common/ctf/ctf_lookup.c
index 4285c74d92..f8fa724355 100644
--- a/usr/src/common/ctf/ctf_lookup.c
+++ b/usr/src/common/ctf/ctf_lookup.c
@@ -19,8 +19,9 @@
*
* CDDL HEADER END
*/
+
/*
- * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -31,7 +32,17 @@
/*
* Compare the given input string and length against a table of known C storage
- * qualifier keywords. We just ignore these in ctf_lookup_by_name, below.
+ * qualifier keywords. We just ignore these in ctf_lookup_by_name, below. To
+ * do this quickly, we use a pre-computed Perfect Hash Function similar to the
+ * technique originally described in the classic paper:
+ *
+ * R.J. Cichelli, "Minimal Perfect Hash Functions Made Simple",
+ * Communications of the ACM, Volume 23, Issue 1, January 1980, pp. 17-19.
+ *
+ * For an input string S of length N, we use hash H = S[N - 1] + N - 105, which
+ * for the current set of qualifiers yields a unique H in the range [0 .. 20].
+ * The hash can be modified when the keyword set changes as necessary. We also
+ * store the length of each keyword and check it prior to the final strcmp().
*/
static int
isqualifier(const char *s, size_t len)
@@ -39,26 +50,19 @@ isqualifier(const char *s, size_t len)
static const struct qual {
const char *q_name;
size_t q_len;
- } q[] = {
- { "auto", 4 },
- { "const", 5 },
- { "extern", 6 },
- { "register", 8 },
- { "restrict", 8 },
- { "_Restrict", 9 },
- { "static", 6 },
- { "volatile", 8 },
- { NULL, 0 }
+ } qhash[] = {
+ { "static", 6 }, { "", 0 }, { "", 0 }, { "", 0 },
+ { "volatile", 8 }, { "", 0 }, { "", 0 }, { "", 0 }, { "", 0 },
+ { "", 0 }, { "auto", 4 }, { "extern", 6 }, { "", 0 }, { "", 0 },
+ { "", 0 }, { "", 0 }, { "const", 5 }, { "register", 8 },
+ { "", 0 }, { "restrict", 8 }, { "_Restrict", 9 }
};
- int i;
+ int h = s[len - 1] + (int)len - 105;
+ const struct qual *qp = &qhash[h];
- for (i = 0; q[i].q_name != NULL; i++) {
- if (len == q[i].q_len && strncmp(s, q[i].q_name, len) == 0)
- return (1);
- }
-
- return (0);
+ return (h >= 0 && h < sizeof (qhash) / sizeof (qhash[0]) &&
+ len == qp->q_len && strncmp(qp->q_name, s, qp->q_len) == 0);
}
/*
diff --git a/usr/src/common/ctf/ctf_open.c b/usr/src/common/ctf/ctf_open.c
index b37e0a0797..e49a4cb329 100644
--- a/usr/src/common/ctf/ctf_open.c
+++ b/usr/src/common/ctf/ctf_open.c
@@ -19,8 +19,9 @@
*
* CDDL HEADER END
*/
+
/*
- * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -195,15 +196,16 @@ init_symtab(ctf_file_t *fp, const ctf_header_t *hp,
* and initialize the hash tables of each named type.
*/
static int
-init_types(ctf_file_t *fp, const ctf_header_t *hp)
+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 + hp->cth_typeoff);
+ 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 + hp->cth_stroff);
+ const ctf_type_t *tend = (ctf_type_t *)(fp->ctf_buf + cth->cth_stroff);
ulong_t pop[CTF_K_MAX + 1] = { 0 };
const ctf_type_t *tp;
+ ctf_hash_t *hp;
ushort_t id, dst;
uint_t *xp;
@@ -213,7 +215,7 @@ init_types(ctf_file_t *fp, const ctf_header_t *hp)
* date cth_parname, we also scan the types themselves for references
* to values in the range reserved for child types in our first pass.
*/
- int child = hp->cth_parname != 0;
+ int child = cth->cth_parname != 0;
int nlstructs = 0, nlunions = 0;
int err;
@@ -266,6 +268,17 @@ init_types(ctf_file_t *fp, const ctf_header_t *hp)
vbytes = sizeof (ctf_enum_t) * vlen;
break;
case CTF_K_FORWARD:
+ /*
+ * For forward declarations, ctt_type is the CTF_K_*
+ * 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)
+ pop[CTF_K_STRUCT]++;
+ else
+ pop[tp->ctt_type]++;
+ /*FALLTHRU*/
case CTF_K_UNKNOWN:
vbytes = 0;
break;
@@ -299,8 +312,7 @@ init_types(ctf_file_t *fp, const ctf_header_t *hp)
* Now that we've counted up the number of each type, we can allocate
* the hash tables, type translation table, and pointer table.
*/
- if ((err = ctf_hash_create(&fp->ctf_structs,
- pop[CTF_K_STRUCT] + pop[CTF_K_FORWARD])) != 0)
+ if ((err = ctf_hash_create(&fp->ctf_structs, pop[CTF_K_STRUCT])) != 0)
return (err);
if ((err = ctf_hash_create(&fp->ctf_unions, pop[CTF_K_UNION])) != 0)
@@ -382,18 +394,11 @@ init_types(ctf_file_t *fp, const ctf_header_t *hp)
break;
case CTF_K_STRUCT:
- /*
- * If a struct's name is already present as a forward
- * tag, then replace the tag with the struct definition.
- */
- if ((hep = ctf_hash_lookup(&fp->ctf_structs, fp,
- name, strlen(name))) == NULL) {
- err = ctf_hash_insert(&fp->ctf_structs, fp,
- CTF_INDEX_TO_TYPE(id, child), tp->ctt_name);
- if (err != 0 && err != ECTF_STRTAB)
- return (err);
- } else
- hep->h_type = CTF_INDEX_TO_TYPE(id, child);
+ err = ctf_hash_define(&fp->ctf_structs, fp,
+ CTF_INDEX_TO_TYPE(id, child), tp->ctt_name);
+
+ if (err != 0 && err != ECTF_STRTAB)
+ return (err);
if (fp->ctf_version == CTF_VERSION_1 ||
size < CTF_LSTRUCT_THRESH)
@@ -405,8 +410,9 @@ init_types(ctf_file_t *fp, const ctf_header_t *hp)
break;
case CTF_K_UNION:
- err = ctf_hash_insert(&fp->ctf_unions, fp,
+ err = ctf_hash_define(&fp->ctf_unions, fp,
CTF_INDEX_TO_TYPE(id, child), tp->ctt_name);
+
if (err != 0 && err != ECTF_STRTAB)
return (err);
@@ -420,10 +426,12 @@ init_types(ctf_file_t *fp, const ctf_header_t *hp)
break;
case CTF_K_ENUM:
- err = ctf_hash_insert(&fp->ctf_enums, fp,
+ err = ctf_hash_define(&fp->ctf_enums, fp,
CTF_INDEX_TO_TYPE(id, child), tp->ctt_name);
+
if (err != 0 && err != ECTF_STRTAB)
return (err);
+
vbytes = sizeof (ctf_enum_t) * vlen;
break;
@@ -437,12 +445,26 @@ init_types(ctf_file_t *fp, const ctf_header_t *hp)
case CTF_K_FORWARD:
/*
- * Only insert forward tags into the struct hash if the
- * struct or tag name is not already present.
+ * Only insert forward tags into the given hash if the
+ * type or tag name is not already present.
*/
- if (ctf_hash_lookup(&fp->ctf_structs, fp,
+ switch (tp->ctt_type) {
+ case CTF_K_STRUCT:
+ hp = &fp->ctf_structs;
+ break;
+ case CTF_K_UNION:
+ hp = &fp->ctf_unions;
+ break;
+ case CTF_K_ENUM:
+ hp = &fp->ctf_enums;
+ break;
+ default:
+ hp = &fp->ctf_structs;
+ }
+
+ if (ctf_hash_lookup(hp, fp,
name, strlen(name)) == NULL) {
- err = ctf_hash_insert(&fp->ctf_structs, fp,
+ err = ctf_hash_insert(hp, fp,
CTF_INDEX_TO_TYPE(id, child), tp->ctt_name);
if (err != 0 && err != ECTF_STRTAB)
return (err);
@@ -774,7 +796,6 @@ void
ctf_close(ctf_file_t *fp)
{
ctf_dtdef_t *dtd, *ntd;
- ctf_dmdef_t *dmd, *nmd;
if (fp == NULL)
return; /* allow ctf_close(NULL) to simplify caller code */
@@ -786,36 +807,15 @@ ctf_close(ctf_file_t *fp)
return;
}
- for (dtd = ctf_list_next(&fp->ctf_dtdefs); dtd != NULL; dtd = ntd) {
- switch (CTF_INFO_KIND(dtd->dtd_data.ctt_info)) {
- case CTF_K_STRUCT:
- case CTF_K_UNION:
- case CTF_K_ENUM:
- for (dmd = ctf_list_next(&dtd->dtd_u.dtu_members);
- dmd != NULL; dmd = nmd) {
- if (dmd->dmd_name != NULL) {
- ctf_free(dmd->dmd_name,
- strlen(dmd->dmd_name) + 1);
- }
- nmd = ctf_list_next(dmd);
- ctf_free(dmd, sizeof (ctf_dmdef_t));
- }
- break;
- case CTF_K_FUNCTION:
- ctf_free(dtd->dtd_u.dtu_argv, sizeof (ctf_id_t) *
- CTF_INFO_VLEN(dtd->dtd_data.ctt_info));
- break;
- }
-
- if (dtd->dtd_name != NULL)
- ctf_free(dtd->dtd_name, strlen(dtd->dtd_name) + 1);
+ if (fp->ctf_parent != NULL)
+ ctf_close(fp->ctf_parent);
+ for (dtd = ctf_list_next(&fp->ctf_dtdefs); dtd != NULL; dtd = ntd) {
ntd = ctf_list_next(dtd);
- ctf_free(dtd, sizeof (ctf_dtdef_t));
+ ctf_dtd_delete(fp, dtd);
}
- if (fp->ctf_parent != NULL)
- ctf_close(fp->ctf_parent);
+ ctf_free(fp->ctf_dthash, fp->ctf_dthashlen * sizeof (ctf_dtdef_t *));
if (fp->ctf_flags & LCTF_MMAP) {
if (fp->ctf_data.cts_data != NULL)
diff --git a/usr/src/common/ctf/ctf_types.c b/usr/src/common/ctf/ctf_types.c
index 401dccd871..290c518ae7 100644
--- a/usr/src/common/ctf/ctf_types.c
+++ b/usr/src/common/ctf/ctf_types.c
@@ -19,8 +19,9 @@
*
* CDDL HEADER END
*/
+
/*
- * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -747,14 +748,14 @@ ctf_enum_value(ctf_file_t *fp, ctf_id_t type, const char *name, int *valp)
uint_t n;
if ((type = ctf_type_resolve(fp, type)) == CTF_ERR)
- return (NULL); /* errno is set for us */
+ return (CTF_ERR); /* errno is set for us */
if ((tp = ctf_lookup_by_id(&fp, type)) == NULL)
- return (NULL); /* errno is set for us */
+ return (CTF_ERR); /* errno is set for us */
if (LCTF_INFO_KIND(fp, tp->ctt_info) != CTF_K_ENUM) {
(void) ctf_set_errno(ofp, ECTF_NOTENUM);
- return (NULL);
+ return (CTF_ERR);
}
(void) ctf_get_ctt_size(fp, tp, &size, &increment);