diff options
author | dfr <dfr@FreeBSD.org> | 1998-08-12 08:44:21 +0000 |
---|---|---|
committer | dfr <dfr@FreeBSD.org> | 1998-08-12 08:44:21 +0000 |
commit | 83a1a3f54192b4d44b8c8005fd239b808921a00d (patch) | |
tree | a363c4b2d7436b2f2026b1801319b94bf7a1e0a3 | |
parent | 235b27cb8f07021d421f50ffdf3d09e2b30c613d (diff) | |
download | FreeBSD-src-83a1a3f54192b4d44b8c8005fd239b808921a00d.zip FreeBSD-src-83a1a3f54192b4d44b8c8005fd239b808921a00d.tar.gz |
Modify the internal interfaces to the kernel linker to make it possible
for DDB to use its symbol tables.
-rw-r--r-- | sys/kern/kern_linker.c | 15 | ||||
-rw-r--r-- | sys/kern/link_aout.c | 77 | ||||
-rw-r--r-- | sys/sys/linker.h | 21 |
3 files changed, 97 insertions, 16 deletions
diff --git a/sys/kern/kern_linker.c b/sys/kern/kern_linker.c index 807b6f5..4f25dcd 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.5 1997/12/12 04:00:59 dyson Exp $ + * $Id: kern_linker.c,v 1.6 1998/01/01 08:56:24 bde Exp $ */ #include <sys/param.h> @@ -331,23 +331,26 @@ linker_file_add_dependancy(linker_file_t file, linker_file_t dep) caddr_t linker_file_lookup_symbol(linker_file_t file, const char* name, int deps) { + linker_sym_t sym; + linker_symval_t symval; caddr_t address; - size_t size; size_t common_size = 0; int i; KLD_DPF(SYM, ("linker_file_lookup_symbol: file=%x, name=%s, deps=%d", file, name, deps)); - if (file->ops->lookup_symbol(file, name, &address, &size) == 0) - if (address == 0) + if (file->ops->lookup_symbol(file, name, &sym) == 0) { + file->ops->symbol_values(file, sym, &symval); + if (symval.value == 0) /* * For commons, first look them up in the dependancies and * only allocate space if not found there. */ - common_size = size; + common_size = symval.size; else - return address; + return symval.value; + } if (deps) for (i = 0; i < file->ndeps; i++) { diff --git a/sys/kern/link_aout.c b/sys/kern/link_aout.c index 4126ae1..5b4e47c 100644 --- a/sys/kern/link_aout.c +++ b/sys/kern/link_aout.c @@ -23,7 +23,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: link_aout.c,v 1.7 1998/07/07 04:31:27 bde Exp $ + * $Id: link_aout.c,v 1.8 1998/07/15 02:32:11 bde Exp $ */ #include <sys/param.h> @@ -43,7 +43,11 @@ static int link_aout_load_file(const char*, linker_file_t*); static int link_aout_lookup_symbol(linker_file_t, const char*, - caddr_t*, size_t*); + linker_sym_t*); +static void link_aout_symbol_values(linker_file_t file, linker_sym_t sym, + linker_symval_t* symval); +static int link_aout_search_symbol(linker_file_t lf, caddr_t value, + linker_sym_t* sym, long* diffp); static void link_aout_unload(linker_file_t); /* @@ -59,6 +63,8 @@ static struct linker_class_ops link_aout_class_ops = { static struct linker_file_ops link_aout_file_ops = { link_aout_lookup_symbol, + link_aout_symbol_values, + link_aout_search_symbol, link_aout_unload, }; @@ -374,7 +380,7 @@ symbol_hash_value(aout_file_t af, const char* name) int link_aout_lookup_symbol(linker_file_t file, const char* name, - caddr_t* address, size_t* size) + linker_sym_t* sym) { aout_file_t af = file->priv; long hashval; @@ -437,15 +443,70 @@ restart: if (np->nz_other == AUX_FUNC) /* weak function */ return ENOENT; - *address = 0; - *size = np->nz_value; - } else { - *address = AOUT_RELOC(af, char, np->nz_value); - *size = np->nz_size; } + *sym = (linker_sym_t) np; + return 0; } + +static void +link_aout_symbol_values(linker_file_t file, linker_sym_t sym, + linker_symval_t* symval) +{ + aout_file_t af = file->priv; + struct nzlist* np = (struct nzlist*) sym; + char* stringbase; + + stringbase = AOUT_RELOC(af, char, LD_STRINGS(af->dynamic)); + + symval->name = stringbase + np->nz_strx + 1; /* +1 for '_' */ + if (np->nz_type == N_UNDF+N_EXT && np->nz_value != 0) { + symval->value = 0; + symval->size = np->nz_value; + } else { + symval->value = AOUT_RELOC(af, char, np->nz_value); + symval->size = np->nz_size; + } +} + +static int +link_aout_search_symbol(linker_file_t lf, caddr_t value, + linker_sym_t* sym, long* diffp) +{ + aout_file_t af = lf->priv; + u_long off = (u_long) value; + u_long diff = off; + struct nzlist* sp; + struct nzlist* ep; + struct nzlist* best = 0; + int i; + + for (sp = AOUT_RELOC(af, struct nzlist, LD_SYMBOL(af->dynamic)), + ep = (struct nzlist *) ((caddr_t) sp + LD_STABSZ(af->dynamic)); + sp < ep; sp++) { + if (sp->nz_name == 0) + continue; + if (off >= sp->nz_value) { + if (off - sp->nz_value < diff) { + diff = off - sp->nz_value; + best = sp; + if (diff == 0) + break; + } else if (off - sp->nz_value == diff) { + best = sp; + } + } + } + if (best == 0) + *diffp = off; + else + *diffp = diff; + *sym = (linker_sym_t) best; + + return 0; +} + #endif /* !__alpha__ */ diff --git a/sys/sys/linker.h b/sys/sys/linker.h index 8aafe03..1f82e12 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.2 1997/11/20 20:07:59 bde Exp $ + * $Id: linker.h,v 1.3 1998/01/01 08:55:37 bde Exp $ */ #ifndef _SYS_LINKER_H_ @@ -41,6 +41,17 @@ MALLOC_DECLARE(M_LINKER); typedef struct linker_file* linker_file_t; typedef TAILQ_HEAD(, linker_file) linker_file_list_t; +typedef caddr_t linker_sym_t; /* opaque symbol */ + +/* + * expanded out linker_sym_t + */ +typedef struct linker_symval { + const char* name; + caddr_t value; + size_t size; +} linker_symval_t; + struct linker_file_ops { /* * Lookup a symbol in the file's symbol table. If the symbol is @@ -50,7 +61,13 @@ struct linker_file_ops { * set *address the value of the symbol. */ int (*lookup_symbol)(linker_file_t, const char* name, - caddr_t* address, size_t* size); + linker_sym_t* sym); + + void (*symbol_values)(linker_file_t, linker_sym_t, + linker_symval_t*); + + int (*search_symbol)(linker_file_t, caddr_t value, + linker_sym_t* sym, long* diffp); /* * Unload a file, releasing dependancies and freeing storage. |