summaryrefslogtreecommitdiffstats
path: root/sys
diff options
context:
space:
mode:
Diffstat (limited to 'sys')
-rw-r--r--sys/kern/kern_linker.c100
-rw-r--r--sys/sys/linker.h8
2 files changed, 95 insertions, 13 deletions
diff --git a/sys/kern/kern_linker.c b/sys/kern/kern_linker.c
index 321436d..93166a1 100644
--- a/sys/kern/kern_linker.c
+++ b/sys/kern/kern_linker.c
@@ -791,18 +791,18 @@ linker_file_lookup_symbol_internal(linker_file_t file, const char *name,
return (0);
}
-#ifdef DDB
/*
- * DDB Helpers. DDB has to look across multiple files with their own symbol
- * tables and string tables.
+ * Both DDB and stack(9) rely on the kernel linker to provide forward and
+ * backward lookup of symbols. However, DDB and sometimes stack(9) need to
+ * do this in a lockfree manner. We provide a set of internal helper
+ * routines to perform these operations without locks, and then wrappers that
+ * optionally lock.
*
- * Note that we do not obey list locking protocols here. We really don't need
- * DDB to hang because somebody's got the lock held. We'll take the chance
- * that the files list is inconsistant instead.
+ * linker_debug_lookup() is ifdef DDB as currently it's only used by DDB.
*/
-
-int
-linker_ddb_lookup(const char *symstr, c_linker_sym_t *sym)
+#ifdef DDB
+static int
+linker_debug_lookup(const char *symstr, c_linker_sym_t *sym)
{
linker_file_t lf;
@@ -812,9 +812,10 @@ linker_ddb_lookup(const char *symstr, c_linker_sym_t *sym)
}
return (ENOENT);
}
+#endif
-int
-linker_ddb_search_symbol(caddr_t value, c_linker_sym_t *sym, long *diffp)
+static int
+linker_debug_search_symbol(caddr_t value, c_linker_sym_t *sym, long *diffp)
{
linker_file_t lf;
c_linker_sym_t best, es;
@@ -844,8 +845,8 @@ linker_ddb_search_symbol(caddr_t value, c_linker_sym_t *sym, long *diffp)
}
}
-int
-linker_ddb_symbol_values(c_linker_sym_t sym, linker_symval_t *symval)
+static int
+linker_debug_symbol_values(c_linker_sym_t sym, linker_symval_t *symval)
{
linker_file_t lf;
@@ -855,9 +856,82 @@ linker_ddb_symbol_values(c_linker_sym_t sym, linker_symval_t *symval)
}
return (ENOENT);
}
+
+static int
+linker_debug_search_symbol_name(caddr_t value, char *buf, u_int buflen,
+ long *offset)
+{
+ linker_symval_t symval;
+ c_linker_sym_t sym;
+ int error;
+
+ *offset = 0;
+ error = linker_debug_search_symbol(value, &sym, offset);
+ if (error)
+ return (error);
+ error = linker_debug_symbol_values(sym, &symval);
+ if (error)
+ return (error);
+ strlcpy(buf, symval.name, buflen);
+ return (0);
+}
+
+#ifdef DDB
+/*
+ * DDB Helpers. DDB has to look across multiple files with their own symbol
+ * tables and string tables.
+ *
+ * Note that we do not obey list locking protocols here. We really don't need
+ * DDB to hang because somebody's got the lock held. We'll take the chance
+ * that the files list is inconsistant instead.
+ */
+int
+linker_ddb_lookup(const char *symstr, c_linker_sym_t *sym)
+{
+
+ return (linker_debug_lookup(symstr, sym));
+}
+
+int
+linker_ddb_search_symbol(caddr_t value, c_linker_sym_t *sym, long *diffp)
+{
+
+ return (linker_debug_search_symbol(value, sym, diffp));
+}
+
+int
+linker_ddb_symbol_values(c_linker_sym_t sym, linker_symval_t *symval)
+{
+
+ return (linker_debug_symbol_values(sym, symval));
+}
+
+int
+linker_ddb_search_symbol_name(caddr_t value, char *buf, u_int buflen,
+ long *offset)
+{
+
+ return (linker_debug_search_symbol_name(value, buf, buflen, offset));
+}
#endif
/*
+ * stack(9) helper for non-debugging environemnts. Unlike DDB helpers, we do
+ * obey locking protocols, and offer a significantly less complex interface.
+ */
+int
+linker_search_symbol_name(caddr_t value, char *buf, u_int buflen,
+ long *offset)
+{
+ int error;
+
+ KLD_LOCK();
+ error = linker_debug_search_symbol_name(value, buf, buflen, offset);
+ KLD_UNLOCK();
+ return (error);
+}
+
+/*
* Syscalls.
*/
int
diff --git a/sys/sys/linker.h b/sys/sys/linker.h
index c5087c8..6655d46 100644
--- a/sys/sys/linker.h
+++ b/sys/sys/linker.h
@@ -176,6 +176,14 @@ int linker_ddb_lookup(const char *_symstr, c_linker_sym_t *_sym);
int linker_ddb_search_symbol(caddr_t _value, c_linker_sym_t *_sym,
long *_diffp);
int linker_ddb_symbol_values(c_linker_sym_t _sym, linker_symval_t *_symval);
+int linker_ddb_search_symbol_name(caddr_t value, char *buf, u_int buflen,
+ long *offset);
+
+/*
+ * stack(9) helper for situations where kernel locking is required.
+ */
+int linker_search_symbol_name(caddr_t value, char *buf, u_int buflen,
+ long *offset);
/* HWPMC helper */
OpenPOWER on IntegriCloud