diff options
Diffstat (limited to 'runtime')
-rw-r--r-- | runtime/ChangeLog | 7 | ||||
-rw-r--r-- | runtime/runtime.h | 68 | ||||
-rw-r--r-- | runtime/sym.c | 4 | ||||
-rw-r--r-- | runtime/sym.h | 25 |
4 files changed, 91 insertions, 13 deletions
diff --git a/runtime/ChangeLog b/runtime/ChangeLog index 548f908e..196d9486 100644 --- a/runtime/ChangeLog +++ b/runtime/ChangeLog @@ -1,3 +1,10 @@ +2005-10-06 Frank Ch. Eigler <fche@elastic.org> + + PR 1332. + * sym.h: New file to declare explicit symbol table struct. + * runtime.h (_stp_kallsyms_lookup_tabled): Use it if available. + * sym.c (_stp_symbol_sprint): HAS_LOOKUP mooted. + 2005-09-30 Graydon Hoare <graydon@redhat.com> * loc2c-runtime.h (_put_user_asm): Fix bracket-matching. diff --git a/runtime/runtime.h b/runtime/runtime.h index 94a210a6..bcee85d5 100644 --- a/runtime/runtime.h +++ b/runtime/runtime.h @@ -60,29 +60,79 @@ static struct #include "string.c" #include "arith.c" #include "copy.c" +#include "sym.h" + /************* Module Stuff ********************/ -#if defined (__x86_64__) || defined (__i386__) -#define HAS_LOOKUP 1 static int (*_stp_kta)(unsigned long addr); static const char * (*_stp_kallsyms_lookup)(unsigned long addr, unsigned long *symbolsize, unsigned long *offset, char **modname, char *namebuf); -int init_module (void) + +/* This implementation is used if stap_[num_]symbols are available. */ +static const char * _stp_kallsyms_lookup_tabled (unsigned long addr, + unsigned long *symbolsize, + unsigned long *offset, + char **modname, + char *namebuf) { - _stp_kta = (int (*)(unsigned long))kallsyms_lookup_name("__kernel_text_address"); - _stp_kallsyms_lookup = (const char * (*)(unsigned long,unsigned long *,unsigned long *,char **,char *)) - kallsyms_lookup_name("kallsyms_lookup"); - return _stp_transport_init(); + unsigned begin = 0; + unsigned end = stap_num_symbols; + /*const*/ struct stap_symbol* s; + + /* binary search on index [begin,end) */ + do + { + unsigned mid = (begin + end) / 2; + if (addr < stap_symbols[mid].addr) + end = mid; + else + begin = mid; + } while (begin + 1 < end); + /* result index in $begin, guaranteed between [0,stap_num_symbols) */ + + s = & stap_symbols [begin]; + if (addr < s->addr) + return NULL; + else + { + if (offset) *offset = addr - s->addr; + if (modname) *modname = (char *) s->modname; + if (symbolsize) + { + if ((begin + 1) < stap_num_symbols) + *symbolsize = stap_symbols[begin+1].addr - s->addr; + else + *symbolsize = 0; + // NB: This is only a heuristic. Sometimes there are large + // gaps between text areas of modules. + } + if (namebuf) + { + strlcpy (namebuf, s->symbol, KSYM_NAME_LEN+1); + return namebuf; + } + else + return s->symbol; + } } -#else + + + int init_module (void) { + _stp_kta = (int (*)(unsigned long))kallsyms_lookup_name("__kernel_text_address"); + + if (stap_num_symbols > 0) + _stp_kallsyms_lookup = & _stp_kallsyms_lookup_tabled; + else + _stp_kallsyms_lookup = (const char * (*)(unsigned long,unsigned long *,unsigned long *,char **,char *)) + kallsyms_lookup_name("kallsyms_lookup"); + return _stp_transport_init(); } -#endif int probe_start(void); diff --git a/runtime/sym.c b/runtime/sym.c index 344df373..6e686051 100644 --- a/runtime/sym.c +++ b/runtime/sym.c @@ -18,7 +18,6 @@ String _stp_symbol_sprint (String str, unsigned long address) { -#ifdef HAS_LOOKUP char *modname; const char *name; unsigned long offset, size; @@ -34,9 +33,6 @@ String _stp_symbol_sprint (String str, unsigned long address) else _stp_sprintf (str, " : %s+%#lx/%#lx", name, offset, size); } -#else - _stp_sprintf (str, "0x%lx", address); -#endif return str; } diff --git a/runtime/sym.h b/runtime/sym.h new file mode 100644 index 00000000..6ed08b06 --- /dev/null +++ b/runtime/sym.h @@ -0,0 +1,25 @@ +/* + * Copyright (C) 2005 Red Hat Inc. + * + * This file is part of systemtap, and is free software. You can + * redistribute it and/or modify it under the terms of the GNU General + * Public License (GPL); either version 2, or (at your option) any + * later version. + */ + +#ifndef _STAP_SYMBOLS_H_ +#define _STAP_SYMBOLS_H_ + + +/* A symbol table defined by the translator. */ +struct stap_symbol { + unsigned long addr; + const char *symbol; + const char *modname; +}; + +extern struct stap_symbol stap_symbols []; +extern unsigned stap_num_symbols; + + +#endif /* _RUNTIME_H_ */ |