From 640b1ba8e04143897763f902538015a7a528a58d Mon Sep 17 00:00:00 2001 From: Joey Schulze Date: Thu, 31 May 2007 15:23:42 +0000 Subject: [PATCH] Improved symbol lookup, since symbols are spread over the entire address space. Return the symbol that fits best instead of the first hit. --- ksym.c | 40 ++++++++++++++++++++++++++++++++++------ ksym_mod.c | 25 ++++++++++++++++++------- 2 files changed, 52 insertions(+), 13 deletions(-) diff --git a/ksym.c b/ksym.c index 32fb6e9..208ea67 100644 --- a/ksym.c +++ b/ksym.c @@ -118,6 +118,11 @@ * * Mon May 28 08:27:51 CEST 2007: Martin Schulze * Added back /usr/src/linux/System.map as fall-back location. + * + * Thu May 31 16:56:26 CEST 2007: Martin Schulze + * Improved symbol lookup, since symbols are spread over the entire + * address space. Return the symbol that fits best instead of + * the first hit. */ @@ -654,13 +659,16 @@ char * LookupSymbol(value, sym) auto int lp; auto char *last; + auto char *name; + + struct symbol ksym, msym; if (!sym_array) return((char *) 0); last = sym_array[0].name; - sym->offset = 0; - sym->size = 0; + ksym.offset = 0; + ksym.size = 0; if ( value < sym_array[0].value ) return((char *) 0); @@ -668,16 +676,34 @@ char * LookupSymbol(value, sym) { if ( sym_array[lp].value > value ) { - sym->offset = value - sym_array[lp-1].value; - sym->size = sym_array[lp].value - \ + ksym.offset = value - sym_array[lp-1].value; + ksym.size = sym_array[lp].value - \ sym_array[lp-1].value; - return(last); + break; } last = sym_array[lp].name; } - if ( (last = LookupModuleSymbol(value, sym)) != (char *) 0 ) + name = LookupModuleSymbol(value, &msym); + + if ( ksym.offset == 0 && msym.offset == 0 ) + { + return((char *) 0); + } + + if ( ksym.size < msym.size ) + { + sym->offset = ksym.offset; + sym->size = ksym.size; return(last); + } + else + { + sym->offset = msym.offset; + sym->size = msym.size; + return(name); + } + return((char *) 0); } @@ -750,6 +776,8 @@ extern char * ExpandKadds(line, el) auto struct symbol sym; + sym.offset = 0; + sym.size = 0; /* * This is as handy a place to put this as anyplace. diff --git a/ksym_mod.c b/ksym_mod.c index fc21e3a..b7b1d23 100644 --- a/ksym_mod.c +++ b/ksym_mod.c @@ -96,6 +96,11 @@ * Thu May 31 12:12:23 CEST 2007: Martin Schulze * Only read kernel symbols from /proc/kallsyms if no System.map * has been read as it may contain more symbols. + * + * Thu May 31 16:56:26 CEST 2007: Martin Schulze + * Improved symbol lookup, since symbols are spread over the entire + * address space. Return the symbol that fits best instead of + * the first hit. */ @@ -508,29 +513,35 @@ extern char * LookupModuleSymbol(value, sym) * Run through the list of symbols in this module and * see if the address can be resolved. */ - for(nsym= 1, last = &mp->sym_array[0]; + for(nsym = 1, last = &mp->sym_array[0]; nsym < mp->num_syms; ++nsym) { if ( mp->sym_array[nsym].value > value ) - { + { + if ( sym->size == 0 || + (mp->sym_array[nsym].value-last->value) < sym->size ) + { sym->offset = value - last->value; sym->size = mp->sym_array[nsym].value - \ last->value; + ret[sizeof(ret)-1] = '\0'; if ( mp->name == NULL ) - return(last->name); + snprintf(ret, sizeof(ret)-1, + "%s", last->name); else - { - ret[sizeof(ret)-1] = '\0'; snprintf(ret, sizeof(ret)-1, "%s:%s", mp->name, last->name); - return(ret); - } + } + break; } last = &mp->sym_array[nsym]; } } + if ( sym->size > 0 ) + return(ret); + /* It has been a hopeless exercise. */ return((char *) 0); }