summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authordfr <dfr@FreeBSD.org>1998-08-12 08:44:21 +0000
committerdfr <dfr@FreeBSD.org>1998-08-12 08:44:21 +0000
commit83a1a3f54192b4d44b8c8005fd239b808921a00d (patch)
treea363c4b2d7436b2f2026b1801319b94bf7a1e0a3
parent235b27cb8f07021d421f50ffdf3d09e2b30c613d (diff)
downloadFreeBSD-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.c15
-rw-r--r--sys/kern/link_aout.c77
-rw-r--r--sys/sys/linker.h21
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.
OpenPOWER on IntegriCloud