diff options
| -rw-r--r-- | sys/kern/kern_linker.c | 55 | ||||
| -rw-r--r-- | sys/sys/linker.h | 11 |
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 |
