and fix off-by-one bug in "help -s" output with CRASHDEBUG(1) Signed-off-by: Kazuhito Hagio <k-hagio-ab@xxxxxxx> --- symbols.c | 111 +++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 109 insertions(+), 2 deletions(-) diff --git a/symbols.c b/symbols.c index 5399c7494cb1..a432909ff28e 100644 --- a/symbols.c +++ b/symbols.c @@ -110,6 +110,7 @@ static int module_mem_type(ulong, struct load_module *); static ulong module_mem_end(ulong, struct load_module *); static int _in_module_range(ulong, struct load_module *, int, int); struct syment *value_search_module_v2(ulong, ulong *); +struct syment *next_module_symbol(char *, struct syment *, ulong); static const char *module_start_tags[]; static const char *module_start_strs[]; @@ -4116,9 +4117,9 @@ dump_symbol_table(void) fprintf(fp, " loaded_objfile: %lx\n", (ulong)lm->loaded_objfile); - if (CRASHDEBUG(1)) { + if (CRASHDEBUG(1) && lm->mod_load_symtable) { for (sp = lm->mod_load_symtable; - sp < lm->mod_load_symend; sp++) { + sp <= lm->mod_load_symend; sp++) { fprintf(fp, " %lx %s\n", sp->value, sp->name); } @@ -5857,6 +5858,106 @@ closest_symbol_value(ulong value) return(0); } +/* Only for 6.4 and later */ +struct syment * +next_module_symbol(char *symbol, struct syment *sp_in, ulong val_in) +{ + int i, j, k; + struct load_module *lm; + struct syment *sp, *sp_end; + + if (symbol) + goto symbol_search; + if (val_in) + goto value_search; + + /* for sp_in */ + for (i = 0; i < st->mods_installed; i++) { + lm = &st->load_modules[i]; + + /* quick check: sp_in is not in the module range. */ + if (sp_in < lm->symtable[lm->address_order[0]] || + sp_in > lm->symend[lm->address_order[lm->nr_mems-1]]) + continue; + + for (j = 0; j < lm->nr_mems; j++) { + k = lm->address_order[j]; + if (sp_in < lm->symtable[k] || sp_in > lm->symend[k]) + continue; + + if (sp_in == lm->symend[k]) + return next_module_symbol(NULL, NULL, sp_in->value); + + sp = sp_in + 1; + if (MODULE_PSEUDO_SYMBOL(sp)) + return next_module_symbol(NULL, NULL, sp->value); + + return sp; + } + } + return NULL; + +value_search: + sp = sp_end = NULL; + for (i = 0; i < st->mods_installed; i++) { + lm = &st->load_modules[i]; + + /* quick check: val_in is higher than the highest in the module. */ + if (val_in > lm->symend[lm->address_order[lm->nr_mems-1]]->value) + continue; + + for (j = 0; j < lm->nr_mems; j++) { + k = lm->address_order[j]; + if (val_in < lm->symtable[k]->value && + (sp == NULL || lm->symtable[k]->value < sp->value)) { + sp = lm->symtable[k]; + sp_end = lm->symend[k]; + break; + } + } + } + for ( ; sp < sp_end; sp++) { + if (MODULE_PSEUDO_SYMBOL(sp)) + continue; + if (sp->value > val_in) + return sp; + } + return NULL; + +symbol_search: + /* + * Deal with a few special cases... + * + * hmm, looks like crash now does not use these special cases. + * + if (strstr(symbol, " module)")) { + sprintf(buf, "_MODULE_START_"); + strcat(buf, &symbol[1]); + p1 = strstr(buf, " module)"); + *p1 = NULLCHAR; + symbol = buf; + } + + if (STREQ(symbol, "_end")) { + if (!st->mods_installed) + return NULL; + + lm = &st->load_modules[0]; + + return lm->mod_symtable; + } + */ + if ((sp = symbol_search(symbol))) { + sp++; + if (MODULE_PSEUDO_SYMBOL(sp) && strstr(sp->name, "_END")) + return next_module_symbol(NULL, NULL, sp->value); + + return sp; + } + + return NULL; +} + /* * For a given symbol, return a pointer to the next (higher) symbol's syment. * Either a symbol name or syment pointer may be passed as an argument. @@ -5886,6 +5987,9 @@ next_symbol(char *symbol, struct syment *sp_in) search_init = FALSE; + if (MODULE_MEMORY()) + return next_module_symbol(NULL, sp_in, 0); + for (i = 0; i < st->mods_installed; i++) { lm = &st->load_modules[i]; if (lm->mod_flags & MOD_INIT) @@ -5928,6 +6032,9 @@ next_symbol(char *symbol, struct syment *sp_in) } + if (MODULE_MEMORY()) + return next_module_symbol(symbol, NULL, 0); + /* * Deal with a few special cases... */ -- 2.31.1 -- Crash-utility mailing list Crash-utility@xxxxxxxxxx https://listman.redhat.com/mailman/listinfo/crash-utility Contribution Guidelines: https://github.com/crash-utility/crash/wiki