diff options
author | Frank Ch. Eigler <fche@elastic.org> | 2008-07-17 06:42:45 -0400 |
---|---|---|
committer | Frank Ch. Eigler <fche@elastic.org> | 2008-07-17 06:42:45 -0400 |
commit | 7795c7e74987876f71fe85ab9119b8810e8897f0 (patch) | |
tree | 44761281ec3f8752b3adc055448945ef600e880c /runtime/sym.c | |
parent | 4464a6bb1793076b3fa85a25c5a489cd9ef7d367 (diff) | |
download | systemtap-steved-7795c7e74987876f71fe85ab9119b8810e8897f0.tar.gz systemtap-steved-7795c7e74987876f71fe85ab9119b8810e8897f0.tar.xz systemtap-steved-7795c7e74987876f71fe85ab9119b8810e8897f0.zip |
support multiple-relocatable-section modules such as hypothetical -ffunction-sections .ko's
Diffstat (limited to 'runtime/sym.c')
-rw-r--r-- | runtime/sym.c | 101 |
1 files changed, 49 insertions, 52 deletions
diff --git a/runtime/sym.c b/runtime/sym.c index 178c6219..dcdbaf69 100644 --- a/runtime/sym.c +++ b/runtime/sym.c @@ -20,10 +20,11 @@ * @{ */ +/* XXX: this needs to be address-space-specific. */ unsigned long _stp_module_relocate(const char *module, const char *section, unsigned long offset) { static struct _stp_module *last = NULL; - static struct _stp_symbol *last_sec; + static struct _stp_section *last_sec; unsigned long flags; unsigned i, j; @@ -42,7 +43,7 @@ unsigned long _stp_module_relocate(const char *module, const char *section, unsi /* Most likely our relocation is in the same section of the same module as the last. */ if (last) { - if (!strcmp(module, last->name) && !strcmp(section, last_sec->symbol)) { + if (!strcmp(module, last->name) && !strcmp(section, last_sec->name)) { offset += last_sec->addr; dbug_sym(1, "cached address=%lx\n", offset); return offset; @@ -55,7 +56,7 @@ unsigned long _stp_module_relocate(const char *module, const char *section, unsi continue; for (j = 0; j < last->num_sections; j++) { last_sec = &last->sections[j]; - if (!strcmp(section, last_sec->symbol)) { + if (!strcmp(section, last_sec->name)) { if (last_sec->addr == 0) /* module/section not in memory */ continue; @@ -72,73 +73,69 @@ unsigned long _stp_module_relocate(const char *module, const char *section, unsi } -/* Return the module that likely contains the given address. */ -/* XXX: This query only makes sense with respect to a particular - address space. A more general interface would have to identify - the address space, and also pass back the section. */ -static struct _stp_module *_stp_find_module_by_addr(unsigned long addr) -{ - unsigned i; - struct _stp_module *closest_module = NULL; - unsigned long closest_module_offset = ~0; /* minimum[addr - module->.text] */ - - for (i=0; i<_stp_num_modules; i++) - { - unsigned long module_text_addr, this_module_offset; - - if (_stp_modules[i]->num_sections < 1) continue; - module_text_addr = _stp_modules[i]->sections[0].addr; /* XXX: assume section[0]=>text */ - if (addr < module_text_addr) continue; - this_module_offset = module_text_addr - addr; - - if (this_module_offset < closest_module_offset) - { - closest_module = _stp_modules[i]; - closest_module_offset = this_module_offset; - } - } - - return closest_module; -} - - - +/* XXX: needs to be address-space-specific. */ static const char *_stp_kallsyms_lookup(unsigned long addr, unsigned long *symbolsize, - unsigned long *offset, char **modname, char *namebuf) + unsigned long *offset, + const char **modname, + /* char ** secname? */ + char *namebuf) { - struct _stp_module *m; - struct _stp_symbol *s; + struct _stp_module *m = NULL; + struct _stp_section *sec = NULL; + struct _stp_symbol *s = NULL; unsigned long flags; unsigned end, begin = 0; - m = _stp_find_module_by_addr(addr); - if (unlikely(m == NULL)) { - return NULL; - } - - /* NB: relativize the address to the (XXX) presumed text section. */ - addr -= m->sections[0].addr; - end = m->num_symbols; + /* Find the closest section (and its owner module); fill in m & sec. */ + { + unsigned midx = 0; + unsigned long closest_section_offset = ~0; + for (midx = 0; midx < _stp_num_modules; midx++) + { + unsigned secidx; + for (secidx = 0; secidx < _stp_modules[midx]->num_sections; secidx++) + { + unsigned long this_section_addr = _stp_modules[midx]->sections[secidx].addr; + unsigned long this_section_offset; + if (addr < this_section_addr) continue; + this_section_offset = this_section_addr - addr; + if (this_section_offset < closest_section_offset) + { + closest_section_offset = this_section_offset; + m = _stp_modules[midx]; + sec = & m->sections[secidx]; + } + } + } + } + + if (unlikely (m == NULL || sec == NULL)) + return NULL; + + /* NB: relativize the address to the section. */ + addr -= sec->addr; + end = sec->num_symbols; /* binary search for symbols within the module */ do { unsigned mid = (begin + end) / 2; - if (addr < m->symbols[mid].addr) + if (addr < sec->symbols[mid].addr) end = mid; else begin = mid; } while (begin + 1 < end); /* result index in $begin */ - s = &m->symbols[begin]; + s = & sec->symbols[begin]; if (likely(addr >= s->addr)) { if (offset) *offset = addr - s->addr; if (modname) *modname = m->name; + /* We could also pass sec->name here. */ if (symbolsize) { - if ((begin + 1) < m->num_symbols) - *symbolsize = m->symbols[begin + 1].addr - s->addr; + if ((begin + 1) < sec->num_symbols) + *symbolsize = sec->symbols[begin + 1].addr - s->addr; else *symbolsize = 0; // NB: This is only a heuristic. Sometimes there are large @@ -163,7 +160,7 @@ static const char *_stp_kallsyms_lookup(unsigned long addr, unsigned long *symbo void _stp_symbol_print(unsigned long address) { - char *modname; + const char *modname; const char *name; unsigned long offset, size; @@ -182,7 +179,7 @@ void _stp_symbol_print(unsigned long address) /* Like _stp_symbol_print, except only print if the address is a valid function address */ int _stp_func_print(unsigned long address, int verbose, int exact) { - char *modname; + const char *modname; const char *name; unsigned long offset, size; char *exstr; @@ -210,7 +207,7 @@ int _stp_func_print(unsigned long address, int verbose, int exact) void _stp_symbol_snprint(char *str, size_t len, unsigned long address) { - char *modname; + const char *modname; const char *name; unsigned long offset, size; |