[DTrace-devel] [PATCH v2 11/11] htab reduction: symtab

Nick Alcock nick.alcock at oracle.com
Wed Oct 20 11:54:04 PDT 2021


The symtab is a major performance sink.  The symtabs in a running DTrace
vary from tiny (most modules) to huge (20,000+ entries in the vmlinux
symtab), but all of them are stuffed into fixed-size htabs of size 211,
leading to hash chains hundreds long.  Combine that with the exponential
explosion of symtab lookups at startup time (something to be fixed in a
later commit), and huge amounts of time get spent traversing bucket
chains on every DTrace startup (and a lot of time doubtless gets wasted
at runtime too).  Symbol lookup is also slow: it does one lookup per
loaded module until it finds the right one.

This is silly: most lookups are done over all modules, and for those
that aren't, we can intern all symbol names into a global
(per-dtrace_hdl) htab and walk matching names until we find one in the
right module (most names are unique across all modules, and for all such
names, as well as for names where we only want the first matching one,
there is no need to walk at all). This requires the storage of a module
back-pointer in the symbol so we can populate the module name in
dtrace_lookup_by_name, but that's easy enough.  We also store the hval
of the name so we don't need to recompute it over and over again, since
it can never change.

We can simplify the dt_symbol a bit, throwing out explicit storage of
the offset pointer and explicit checking of the DT_ST_PACKED flag on
every name lookup, and instead just replace the name pointer in each
symbol with a pointer into the strtab when packing happens.  We still
need to check the packed flag at destroy time to see whether we need to
free the string, but this simplifies all lookups and in particular makes
it easier than it would otherwise be to look up the symbol name when
doing a htab comparison.  Since the dt_htab naturally supports multiple
entries with the same name (returning the first inserted by default,
unless the caller explicitly walks through them, as we do when a symbol
from a specific module is requested) this lets us throw out the entirety
of the dt_symtab_purge complexity: should it turn out to be actually
important (if there are vast numbers of symbols with the same name
in a lot of modules), it's much easier to implement by just walking
the htab links now, just as is done in dt_module_symbol_by_name.

The only extra bit of fragility this adds is that destruction of the
centralized dt_kernsym_t makes all symbol name lookups fail, since we no
longer have any per-symbol hashtabs.  So we add a new dt_module_fini
that ensures that modules are destroyed right after the kernsym hashtab,
so there is no room for any name lookups to sneak in.

Speeds up startup from ~3.8s/invocation to ~0.9s/invocation.  Speeds up
a full test run by about 20 minutes, which is less than I would expect
given that we have a thousand-odd tests: I suspect cache effects or
something. Still, it's faster than it was.

Signed-off-by: Nick Alcock <nick.alcock at oracle.com>
---
 libdtrace/dt_impl.h   |   1 +
 libdtrace/dt_module.c |  54 +++++++---
 libdtrace/dt_open.c   |   3 +
 libdtrace/dt_symtab.c | 231 +++++++++++++++++-------------------------
 libdtrace/dt_symtab.h |  22 ++--
 5 files changed, 152 insertions(+), 159 deletions(-)

diff --git a/libdtrace/dt_impl.h b/libdtrace/dt_impl.h
index f1314bd228f2..164117546af0 100644
--- a/libdtrace/dt_impl.h
+++ b/libdtrace/dt_impl.h
@@ -297,6 +297,7 @@ struct dtrace_hdl {
 	dt_tstring_t *dt_tstrings; /* temporary string slots */
 	dt_list_t dt_modlist;	/* linked list of dt_module_t's */
 	dt_htab_t *dt_mods;	/* hash table of dt_module_t's */
+	dt_htab_t *dt_kernsyms; /* htab of kernel symbol names */
 	ctf_archive_t *dt_ctfa; /* ctf archive for the entire kernel tree */
 	ctf_file_t *dt_shared_ctf; /* Handle to the shared CTF */
 	char *dt_ctfa_path;	/* path to vmlinux.ctfa */
diff --git a/libdtrace/dt_module.c b/libdtrace/dt_module.c
index 8db357ab5d6a..7446fb736259 100644
--- a/libdtrace/dt_module.c
+++ b/libdtrace/dt_module.c
@@ -618,7 +618,7 @@ dt_module_unload(dtrace_hdl_t *dtp, dt_module_t *dmp)
 	free(dmp->dm_asmap);
 	dmp->dm_asmap = NULL;
 
-	dt_symtab_destroy(dmp->dm_kernsyms);
+	dt_symtab_destroy(dtp, dmp->dm_kernsyms);
 	dmp->dm_kernsyms = NULL;
 
 	dmp->dm_symfree = 0;
@@ -1115,13 +1115,13 @@ dt_modsym_update(dtrace_hdl_t *dtp, const char *line, int flag)
 
 	if (!skip) {
 		if (dmp->dm_kernsyms == NULL)
-			dmp->dm_kernsyms = dt_symtab_create();
+			dmp->dm_kernsyms = dt_symtab_create(dtp);
 
 		if (dmp->dm_kernsyms == NULL)
 			return EDT_NOMEM;
 
-		if (dt_symbol_insert(dmp->dm_kernsyms, sym_name, sym_addr, sym_size,
-			sym_type_to_info(sym_type)) == NULL)
+		if (dt_symbol_insert(dtp, dmp->dm_kernsyms, dmp, sym_name,
+			sym_addr, sym_size, sym_type_to_info(sym_type)) == NULL)
 			return EDT_NOMEM;
 	}
 
@@ -1237,7 +1237,6 @@ dtrace_update(dtrace_hdl_t *dtp)
 	    dmp = dt_list_next(dmp)) {
 		if (dmp->dm_kernsyms != NULL) {
 			dt_symtab_sort(dmp->dm_kernsyms, flag);
-			dt_symtab_purge(dmp->dm_kernsyms);
 			dt_symtab_pack(dmp->dm_kernsyms);
 		}
 	}
@@ -1327,9 +1326,6 @@ dt_module_from_object(dtrace_hdl_t *dtp, const char *object)
  * Only the st_info, st_value, and st_size fields of the GElf_Sym are guaranteed
  * to be populated: the st_shndx is populated but its only meaningful value is
  * SHN_UNDEF versus !SHN_UNDEF.
- *
- * XXX profile this: possibly introduce a symbol->name mapping for
- * first-matching-symbol across all modules.
  */
 int
 dtrace_lookup_by_name(dtrace_hdl_t *dtp, const char *object, const char *name,
@@ -1366,6 +1362,36 @@ dtrace_lookup_by_name(dtrace_hdl_t *dtp, const char *object, const char *name,
 	if (symp == NULL)
 		symp = &sym;
 
+	/*
+	 * Search loaded kernel symbols first, iff searching all kernel symbols
+	 * is requested.  This is only an optimization: there are (obscure)
+	 * cases in which loaded kernel symbols might not end up in this hash
+	 * (e.g. if a kernel symbol is duplicated in multiple modules, then one
+	 * of them is unloaded).
+	 */
+	if ((object == DTRACE_OBJ_EVERY || object == DTRACE_OBJ_KMODS) &&
+	    dtp->dt_kernsyms) {
+		dt_symbol_t *dt_symp;
+
+		if ((dt_symp = dt_symbol_by_name(dtp, name)) != NULL) {
+			if (sip != NULL) {
+				dt_module_t *tmp;
+
+				tmp = dt_symbol_module(dt_symp);
+				sip->object = tmp->dm_name;
+				sip->name = dt_symbol_name(dt_symp);
+				sip->id = 0;	/* undefined */
+			}
+
+			dt_symbol_to_elfsym(dtp, dt_symp, symp);
+			return 0;
+		}
+	}
+
+	/*
+	 * Not found: search all modules, including non-kernel modules, loading
+	 * them as needed.
+	 */
 	for (; n > 0; n--, dmp = dt_list_next(dmp)) {
 		if ((dmp->dm_flags & mask) != bits)
 			continue; /* failed to match required attributes */
@@ -1373,6 +1399,10 @@ dtrace_lookup_by_name(dtrace_hdl_t *dtp, const char *object, const char *name,
 		if (dt_module_load(dtp, dmp) == -1)
 			continue; /* failed to load symbol table */
 
+		/*
+		 * If this is a kernel symbol, see if it's appeared.  If it has,
+		 * it must belong to this module.
+		 */
 		if ((dmp->dm_flags & DT_DM_KERNEL) &&
 		    (!(dmp->dm_flags & DT_DM_KERN_UNLOADED))) {
 			dt_symbol_t *dt_symp;
@@ -1380,14 +1410,14 @@ dtrace_lookup_by_name(dtrace_hdl_t *dtp, const char *object, const char *name,
 			if (!dmp->dm_kernsyms)
 				continue;
 
-			dt_symp = dt_symbol_by_name(dmp->dm_kernsyms, name);
+			dt_symp = dt_module_symbol_by_name(dtp, dmp, name);
 			if (!dt_symp)
 				continue;
+			assert(dt_symbol_module(dt_symp) == dmp);
 
 			if (sip != NULL) {
 				sip->object = dmp->dm_name;
-				sip->name = dt_symbol_name(dmp->dm_kernsyms,
-							   dt_symp);
+				sip->name = dt_symbol_name(dt_symp);
 				sip->id = 0;	/* undefined */
 			}
 			dt_symbol_to_elfsym(dtp, dt_symp, symp);
@@ -1499,7 +1529,7 @@ dtrace_lookup_by_addr(dtrace_hdl_t *dtp, GElf_Addr addr,
 
 		if (sip != NULL) {
 		    sip->object = dmp->dm_name;
-		    sip->name = dt_symbol_name(dmp->dm_kernsyms, dt_symp);
+		    sip->name = dt_symbol_name(dt_symp);
 		    sip->id = 0;	/* undefined */
 		}
 
diff --git a/libdtrace/dt_open.c b/libdtrace/dt_open.c
index 9a31fe5bf894..f35bf8255ead 100644
--- a/libdtrace/dt_open.c
+++ b/libdtrace/dt_open.c
@@ -1220,6 +1220,9 @@ dtrace_close(dtrace_hdl_t *dtp)
 	if (dtp->dt_bpfsyms != NULL)
 		dt_idhash_destroy(dtp->dt_bpfsyms);
 
+
+	dt_htab_destroy(dtp, dtp->dt_kernsyms);
+	dtp->dt_kernsyms = NULL;
 	dt_htab_destroy(dtp, dtp->dt_mods);
 	dt_htab_destroy(dtp, dtp->dt_kernpaths);
 
diff --git a/libdtrace/dt_symtab.c b/libdtrace/dt_symtab.c
index 4b7f8b9d66a4..db63cc88b4bd 100644
--- a/libdtrace/dt_symtab.c
+++ b/libdtrace/dt_symtab.c
@@ -29,14 +29,13 @@
 
 struct dt_symbol {
 	dt_list_t dts_list;		/* list forward/back pointers */
-	union {
-		char *str;		/* symbol name */
-		size_t off;		/* symbol offset in strtab */
-	} dts_name;
+	char *dts_name;			/* symbol name */
 	GElf_Addr dts_addr;		/* symbol address */
 	GElf_Xword dts_size;		/* symbol size */
 	unsigned char dts_info;		/* ELF symbol information */
-	struct dt_symbol *dts_next;	/* hash chain pointer */
+	uint32_t dts_hval;		/* cached hash value (for speed) */
+	dt_module_t *dts_dmp;		/* module this symbol is contained within */
+	struct dt_hentry dts_he;	/* htab links */
 };
 
 /*
@@ -57,8 +56,6 @@ typedef struct dt_symrange {
 
 struct dt_symtab {
 	dt_list_t dtst_symlist;		/* symbol list */
-	dt_symbol_t **dtst_syms_by_name;/* symbol name->addr hash buckets */
-	uint_t dtst_symbuckets;		/* number of buckets */
 	char *dtst_strtab;		/* string table of symbol names */
 	dt_symrange_t *dtst_ranges;	/* range->symbol mapping */
 	uint_t dtst_num_range;		/*   - number of ranges */
@@ -121,13 +118,13 @@ dt_symrange_sort_cmp(const void *lp, const void *rp)
 	 * Note: packed strtabs must already be sorted and can be
 	 * neither changed nor resorted.
 	 */
-	if (strcmp(lhs->dts_name.str, "cleanup_module") &&
-	    strcmp(rhs->dts_name.str, "cleanup_module") == 0)
+	if (strcmp(lhs->dts_name, "cleanup_module") &&
+	    strcmp(rhs->dts_name, "cleanup_module") == 0)
 		return -1;
-	if (strcmp(rhs->dts_name.str, "cleanup_module") &&
-	    strcmp(lhs->dts_name.str, "cleanup_module") == 0)
+	if (strcmp(rhs->dts_name, "cleanup_module") &&
+	    strcmp(lhs->dts_name, "cleanup_module") == 0)
 		return +1;
-	return strcmp(lhs->dts_name.str, rhs->dts_name.str);
+	return strcmp(lhs->dts_name, rhs->dts_name);
 }
 
 /*
@@ -145,31 +142,45 @@ static int dt_symbol_search_cmp(const void *lp, const void *rp)
 	return 0;
 }
 
+static uint32_t
+dt_symtab_hval(const dt_symbol_t *sym, void *arg)
+{
+	return sym->dts_hval ? sym->dts_hval : str2hval(sym->dts_name, 0);
+}
+
+static int
+dt_symtab_cmp(const dt_symbol_t *p,
+	      const dt_symbol_t *q)
+{
+	return strcmp(p->dts_name, q->dts_name);
+}
+
+DEFINE_HE_STD_LINK_FUNCS(dt_symtab, dt_symbol_t, dts_he)
+DEFINE_HTAB_STD_OPS(dt_symtab)
+
 dt_symtab_t *
-dt_symtab_create(void)
+dt_symtab_create(dtrace_hdl_t *dtp)
 {
-	dt_symtab_t *symtab = malloc(sizeof(struct dt_symtab));
+	dt_symtab_t *symtab;
 
-	if (symtab == NULL)
-		return NULL;
+	if (!dtp->dt_kernsyms) {
+		dtp->dt_kernsyms = dt_htab_create(dtp, &dt_symtab_htab_ops);
 
-	memset(symtab, 0, sizeof(struct dt_symtab));
+		if (!dtp->dt_kernsyms)
+			return NULL;
+	}
 
-	symtab->dtst_symbuckets = _dtrace_strbuckets;
-	symtab->dtst_syms_by_name = calloc(symtab->dtst_symbuckets,
-	    sizeof(struct dt_symbol *));
+	symtab = malloc(sizeof(struct dt_symtab));
 
-	if (symtab->dtst_syms_by_name == NULL) {
-		free(symtab->dtst_syms_by_name);
-		free(symtab);
+	if (symtab == NULL)
 		return NULL;
-	}
 
+	memset(symtab, 0, sizeof(struct dt_symtab));
 	return symtab;
 }
 
 void
-dt_symtab_destroy(dt_symtab_t *symtab)
+dt_symtab_destroy(dtrace_hdl_t *dtp, dt_symtab_t *symtab)
 {
 	dt_symbol_t *dtsp;
 	dt_symbol_t *last_dtsp = NULL;
@@ -178,26 +189,25 @@ dt_symtab_destroy(dt_symtab_t *symtab)
 		return;
 
 	free(symtab->dtst_ranges);
-	free(symtab->dtst_syms_by_name);
 	free(symtab->dtst_strtab);
 
 	for (dtsp = dt_list_next(&symtab->dtst_symlist); dtsp != NULL;
 	     dtsp = dt_list_next(dtsp)) {
 		if (!(symtab->dtst_flags & DT_ST_PACKED))
-			free(dtsp->dts_name.str);
+			free(dtsp->dts_name);
+		if (dtp->dt_kernsyms)
+			dt_htab_delete(dtp->dt_kernsyms, dtsp);
 		free(last_dtsp);
 		last_dtsp = dtsp;
 	}
 	free(last_dtsp);
-
 	free(symtab);
 }
 
 dt_symbol_t *
-dt_symbol_insert(dt_symtab_t *symtab, const char *name,
-    GElf_Addr addr, GElf_Xword size, unsigned char info)
+dt_symbol_insert(dtrace_hdl_t *dtp, dt_symtab_t *symtab, dt_module_t *dmp,
+    const char *name, GElf_Addr addr, GElf_Xword size, unsigned char info)
 {
-	uint_t h;
 	dt_symbol_t *dtsp;
 
 	/*
@@ -216,27 +226,21 @@ dt_symbol_insert(dt_symtab_t *symtab, const char *name,
 		}
 
 	memset(dtsp, 0, sizeof(dt_symbol_t));
-	dtsp->dts_name.str = strdup(name);
+	dtsp->dts_name = strdup(name);
+	dtsp->dts_hval = str2hval(name, 0);
 	dtsp->dts_addr = addr;
 	dtsp->dts_size = size;
 	dtsp->dts_info = info;
+	dtsp->dts_dmp = dmp;
 
-	if (dtsp->dts_name.str == NULL) {
-		free(dtsp->dts_name.str);
-		free(dtsp);
-		return NULL;
-	}
+	if (dtsp->dts_name == NULL)
+		goto oom;
 
 	/*
-	 * Address->symbol mapping.  Zero-size symbols do not
-	 * include any addresses and therefore are not added.
-	 * It is not yet necessary to set the range's addr and size.
+	 * Add to lookup-by-name hash table, after all current names.
 	 */
-
-	if (size > 0) {
-		symtab->dtst_ranges[symtab->dtst_num_range].dtsr_sym = dtsp;
-		symtab->dtst_num_range++;
-	}
+	if (dt_htab_insert(dtp->dt_kernsyms, dtsp) < 0)
+		goto oom;
 
 	/*
 	 * Append to the doubly linked list.
@@ -244,36 +248,46 @@ dt_symbol_insert(dt_symtab_t *symtab, const char *name,
 	dt_list_append(&symtab->dtst_symlist, dtsp);
 
 	/*
-	 * Add to lookup-by-name hash table.
+	 * Address->symbol mapping.  Zero-size symbols do not
+	 * include any addresses and therefore are not added.
+	 * It is not yet necessary to set the range's addr and size.
 	 */
-	h = str2hval(name, 0) % symtab->dtst_symbuckets;
-	dtsp->dts_next = symtab->dtst_syms_by_name[h];
-	symtab->dtst_syms_by_name[h] = dtsp;
+
+	if (size > 0)
+		symtab->dtst_ranges[symtab->dtst_num_range++].dtsr_sym = dtsp;
 
 	symtab->dtst_flags &= ~DT_ST_SORTED;
 
 	return dtsp;
+oom:
+	if (dtsp)
+		free(dtsp->dts_name);
+	free(dtsp);
+	return NULL;
 }
 
 dt_symbol_t *
-dt_symbol_by_name(dt_symtab_t *symtab, const char *name)
+dt_symbol_by_name(dtrace_hdl_t *dtp, const char *name)
 {
-	uint_t h = str2hval(name, 0) % symtab->dtst_symbuckets;
-	dt_symbol_t *dtsp;
-	int packed = symtab->dtst_flags & DT_ST_PACKED;
-
-	for (dtsp = symtab->dtst_syms_by_name[h]; dtsp != NULL;
-	     dtsp = dtsp->dts_next) {
-		if (packed) {
-			if (strcmp(&symtab->dtst_strtab[dtsp->dts_name.off],
-				name) == 0)
-				return dtsp;
-		}
-		else
-			if (strcmp(dtsp->dts_name.str, name) == 0)
-				return dtsp;
-	}
+	dt_symbol_t tmpl = {0};
+	tmpl.dts_name = (char *) name;
 
+	return dt_htab_lookup(dtp->dt_kernsyms, &tmpl);
+}
+
+/* Find a symbol in a given module.  */
+dt_symbol_t *
+dt_module_symbol_by_name(dtrace_hdl_t *dtp, dt_module_t *dmp, const char *name)
+{
+	dt_symbol_t *symbol;
+
+	symbol = dt_symbol_by_name(dtp, name);
+	while (symbol)
+	{
+		if (symbol->dts_dmp == dmp)
+			return symbol;
+		symbol = (dt_symbol_t *) symbol->dts_he.next;
+	}
 	return NULL;
 }
 
@@ -476,64 +490,6 @@ dt_symtab_sort(dt_symtab_t *symtab, int flag)
 	symtab->dtst_flags |= DT_ST_SORTED;
 }
 
-/*
- * Get next item on the linked list, keeping or eliminating the current item.
- */
-static
-dt_symbol_t **
-next_symp(dt_symbol_t **p, int *nelim, int keep) {
-	if (keep)
-		return &((*p)->dts_next);
-	else {
-		dt_symbol_t *tmp = (*p)->dts_next;
-		(*p)->dts_next = NULL;
-		*p = tmp;
-		*nelim += 1;
-		return p;
-	}
-}
-
-/*
- * Purge symbols from name-to-address hash buckets if they have duplicates.
- *
- * (Duplicates occur when symbols have the same name and are in the same module;
- * they just come from different translation units.  For example, they might have
- * file scope and come from different files.)
- */
-void
-dt_symtab_purge(dt_symtab_t *symtab)
-{
-	uint_t i;
-
-	/* loop over buckets */
-	for (i = 0; i < symtab->dtst_symbuckets; i++) {
-
-		/* walk the bucket's linked list */
-		dt_symbol_t **p1;
-		for (p1 = &symtab->dtst_syms_by_name[i]; *p1; ) {
-			int nelim = 0;
-			char *myname = (*p1)->dts_name.str;
-			dt_symbol_t **p2;
-
-			/*
-			 * Walk from the next item to the end of the list,
-			 * keeping only symbols whose names differ from myname.
-			 * (Compare symbol names by looking at dts_name.str,
-			 * since symtab is not packed yet.)
-			 */
-			for (p2 = &((*p1)->dts_next); *p2; )
-				p2 = next_symp(p2, &nelim,
-				    strcmp((*p2)->dts_name.str, myname));
-
-			/*
-			 * Advance p1, keeping the current item only if no
-			 * other symbols were eliminated (duplicated p1).
-			 */
-			p1 = next_symp(p1, &nelim, nelim == 0);
-		}
-	}
-}
-
 void
 dt_symtab_pack(dt_symtab_t *symtab)
 {
@@ -558,7 +514,7 @@ dt_symtab_pack(dt_symtab_t *symtab)
 	 */
 	for (dtsp = dt_list_next(&symtab->dtst_symlist); dtsp != NULL;
 	     dtsp = dt_list_next(dtsp))
-		strsz += strlen(dtsp->dts_name.str) + 1;
+		strsz += strlen(dtsp->dts_name) + 1;
 
 	symtab->dtst_strtab = malloc(strsz);
 	if (symtab->dtst_strtab == NULL)
@@ -569,11 +525,11 @@ dt_symtab_pack(dt_symtab_t *symtab)
 	 */
 	for (dtsp = dt_list_next(&symtab->dtst_symlist); dtsp != NULL;
 	     dtsp = dt_list_next(dtsp)) {
-		size_t len = strlen(dtsp->dts_name.str) + 1;
+		size_t len = strlen(dtsp->dts_name) + 1;
 
-		memcpy(&symtab->dtst_strtab[offset], dtsp->dts_name.str, len);
-		free(dtsp->dts_name.str);
-		dtsp->dts_name.off = offset;
+		memcpy(&symtab->dtst_strtab[offset], dtsp->dts_name, len);
+		free(dtsp->dts_name);
+		dtsp->dts_name = &symtab->dtst_strtab[offset];
 		offset += len;
 	}
 
@@ -581,19 +537,12 @@ dt_symtab_pack(dt_symtab_t *symtab)
 }
 
 /*
- * Return the name of a symbol.  Currently redundant, this will become useful
- * when dt_symtab_pack() starts compressing symbol names.  TODO: we must retain
- * ownership of the expanded string, even in this case: it is part of the
- * libdtrace API.  This is distinctly tricky: it may be simpler to change the
- * API to require caller-frees semantics.
+ * Return the name of a symbol.
  */
 const char *
-dt_symbol_name(dt_symtab_t *symtab _dt_unused_, dt_symbol_t *symbol)
+dt_symbol_name(const dt_symbol_t *symbol)
 {
-	if (symtab->dtst_flags & DT_ST_PACKED)
-		return &symtab->dtst_strtab[symbol->dts_name.off];
-	else
-		return symbol->dts_name.str;
+	return symbol->dts_name;
 }
 
 void
@@ -626,3 +575,9 @@ dt_symbol_to_elfsym(dtrace_hdl_t *dtp, dt_symbol_t *symbol, GElf_Sym *elf_symp)
 		/* unknown model, fall out with nothing changed */
 	}
 }
+
+dt_module_t *
+dt_symbol_module(dt_symbol_t *symbol)
+{
+	return symbol->dts_dmp;
+}
diff --git a/libdtrace/dt_symtab.h b/libdtrace/dt_symtab.h
index b2d5a26d3746..8d396c46c840 100644
--- a/libdtrace/dt_symtab.h
+++ b/libdtrace/dt_symtab.h
@@ -4,7 +4,7 @@
 
 /*
  * Oracle Linux DTrace.
- * Copyright (c) 2012, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2021, Oracle and/or its affiliates. All rights reserved.
  * Licensed under the Universal Permissive License v 1.0 as shown at
  * http://oss.oracle.com/licenses/upl.
  */
@@ -31,21 +31,25 @@ extern "C" {
 
 typedef struct dt_symbol dt_symbol_t;
 typedef struct dt_symtab dt_symtab_t;
-
-extern dt_symtab_t *dt_symtab_create(void);
-extern void dt_symtab_destroy(dt_symtab_t *symtab);
-extern dt_symbol_t *dt_symbol_insert(dt_symtab_t *symtab, const char *name,
-    GElf_Addr addr, GElf_Xword size, unsigned char info);
-extern dt_symbol_t *dt_symbol_by_name(dt_symtab_t *symtab, const char *name);
+struct dt_module;
+
+extern dt_symtab_t *dt_symtab_create(dtrace_hdl_t *dtp);
+extern void dt_symtab_destroy(dtrace_hdl_t *dtp, dt_symtab_t *symtab);
+extern dt_symbol_t *dt_symbol_insert(dtrace_hdl_t *dtp, dt_symtab_t *symtab,
+    struct dt_module *dmp, const char *name, GElf_Addr addr, GElf_Xword size,
+    unsigned char info);
+extern dt_symbol_t *dt_symbol_by_name(dtrace_hdl_t *dtp, const char *name);
+extern dt_symbol_t *dt_module_symbol_by_name(dtrace_hdl_t *dtp,
+    struct dt_module *dmp, const char *name);
 extern dt_symbol_t *dt_symbol_by_addr(dt_symtab_t *symtab, GElf_Addr dts_addr);
 
 extern void dt_symtab_sort(dt_symtab_t *symtab, int flag);
-extern void dt_symtab_purge(dt_symtab_t *symtab);
 extern void dt_symtab_pack(dt_symtab_t *symtab);
 
-extern const char *dt_symbol_name(dt_symtab_t *symtab, dt_symbol_t *symbol);
+extern const char *dt_symbol_name(const dt_symbol_t *symbol);
 extern void dt_symbol_to_elfsym(dtrace_hdl_t *dtp, dt_symbol_t *symbol,
     GElf_Sym *elf_symp);
+extern struct dt_module *dt_symbol_module(dt_symbol_t *symbol);
 
 #ifdef	__cplusplus
 }
-- 
2.33.1.257.g9e0974a4e8




More information about the DTrace-devel mailing list