aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--sys/kern/kern_linker.c55
-rw-r--r--sys/sys/linker.h11
2 files changed, 64 insertions, 2 deletions
diff --git a/sys/kern/kern_linker.c b/sys/kern/kern_linker.c
index 6d0665bf77d7..04bd2060f80a 100644
--- a/sys/kern/kern_linker.c
+++ b/sys/kern/kern_linker.c
@@ -23,7 +23,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $Id: kern_linker.c,v 1.15 1998/11/06 15:10:17 peter Exp $
+ * $Id: kern_linker.c,v 1.16 1998/11/10 08:49:28 peter Exp $
*/
#include "opt_ddb.h"
@@ -769,6 +769,59 @@ kldfirstmod(struct proc* p, struct kldfirstmod_args* uap)
return error;
}
+int
+kldsym(struct proc *p, struct kldsym_args *uap)
+{
+ char *symstr = NULL;
+ linker_sym_t sym;
+ linker_symval_t symval;
+ linker_file_t lf;
+ struct kld_sym_lookup lookup;
+ int error = 0;
+
+ if (error = copyin(SCARG(uap, data), &lookup, sizeof(lookup)))
+ goto out;
+ if (lookup.version != sizeof(lookup) || SCARG(uap, cmd) != KLDSYM_LOOKUP) {
+ error = EINVAL;
+ goto out;
+ }
+
+ symstr = malloc(MAXPATHLEN, M_TEMP, M_WAITOK);
+ if (error = copyinstr(lookup.symname, symstr, MAXPATHLEN, NULL))
+ goto out;
+
+ if (SCARG(uap, fileid) != 0) {
+ lf = linker_find_file_by_id(SCARG(uap, fileid));
+ if (lf == NULL) {
+ error = ENOENT;
+ goto out;
+ }
+ if (lf->ops->lookup_symbol(lf, symstr, &sym) == 0 &&
+ lf->ops->symbol_values(lf, sym, &symval) == 0) {
+ lookup.symvalue = (u_long)symval.value;
+ lookup.symsize = symval.size;
+ error = copyout(&lookup, SCARG(uap, data), sizeof(lookup));
+ } else
+ error = ENOENT;
+ } else {
+ for (lf = TAILQ_FIRST(&files); lf; lf = TAILQ_NEXT(lf, link)) {
+ if (lf->ops->lookup_symbol(lf, symstr, &sym) == 0 &&
+ lf->ops->symbol_values(lf, sym, &symval) == 0) {
+ lookup.symvalue = (u_long)symval.value;
+ lookup.symsize = symval.size;
+ error = copyout(&lookup, SCARG(uap, data), sizeof(lookup));
+ break;
+ }
+ }
+ if (!lf)
+ error = ENOENT;
+ }
+out:
+ if (symstr)
+ free(symstr, M_TEMP);
+ return error;
+}
+
/*
* Preloaded module support
*/
diff --git a/sys/sys/linker.h b/sys/sys/linker.h
index 565239daa62c..52536ee98e2e 100644
--- a/sys/sys/linker.h
+++ b/sys/sys/linker.h
@@ -23,7 +23,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $Id: linker.h,v 1.9 1998/10/16 03:55:01 peter Exp $
+ * $Id: linker.h,v 1.10 1998/11/04 15:20:58 peter Exp $
*/
#ifndef _SYS_LINKER_H_
@@ -264,6 +264,14 @@ struct kld_file_stat {
size_t size; /* size in bytes */
};
+struct kld_sym_lookup {
+ int version; /* set to sizeof(struct kld_sym_lookup) */
+ char *symname; /* Symbol name we are looking up */
+ u_long symvalue;
+ size_t symsize;
+};
+#define KLDSYM_LOOKUP 1
+
#ifndef KERNEL
#include <sys/cdefs.h>
@@ -275,6 +283,7 @@ int kldfind(const char* file);
int kldnext(int fileid);
int kldstat(int fileid, struct kld_file_stat* stat);
int kldfirstmod(int fileid);
+int kldsym(int _fileid, int _cmd, void *_data);
__END_DECLS
#endif