Support percpu symbols for "sym" options and etc.
crash> mod -s kvm_intel
MODULE NAME BASE SIZE OBJECT FILE
ffffffffc0b1b480 kvm_intel ffffffffc0d0c000 372736
/home/kernel/linux-next-next-20230310/arch/x86/kvm/kvm-intel.ko
crash> sym -m kvm_intel | head
35020 MODULE PERCPU START: kvm_intel
35020 (d) loaded_vmcss_on_cpu
35030 (d) vmxarea
35038 (D) current_vmcs
35040 (d) wakeup_vcpus_on_cpu_lock
35050 (d) wakeup_vcpus_on_cpu
35060 MODULE PERCPU END: kvm_intel
ffffffffc0aae000 MODULE RO_AFTER_INIT START: kvm_intel
ffffffffc0ab1720 (D) vmx_capability
ffffffffc0ab1740 (D) vmcs_config
crash> sym vmxarea
35030 (d) vmxarea [kvm_intel]
Signed-off-by: Kazuhito Hagio <k-hagio-ab(a)nec.com>
---
symbols.c | 82 ++++++++++++++++++++++++++-----------------------------
1 file changed, 38 insertions(+), 44 deletions(-)
diff --git a/symbols.c b/symbols.c
index 8343081f51f7..40e992e9ee12 100644
--- a/symbols.c
+++ b/symbols.c
@@ -1302,7 +1302,7 @@ symname_hash_search(struct syment *table[], char *name)
static void
module_symbol_dump(char *module)
{
- int i, j, m, start, percpu_syms;
+ int i, j, m;
struct syment *sp, *sp_end;
struct load_module *lm;
const char *p1, *p2;
@@ -1319,6 +1319,19 @@ module_symbol_dump(char *module)
if (received_SIGINT() || output_closed())
return;
+ /* The percpu area isn't included in any module memory area. */
+ if (MODULE_PERCPU_SYMS_LOADED(lm)) {
+ p1 = "MODULE PERCPU START";
+ p2 = lm->mod_name;
+ fprintf(fp, "%lx %s: %s\n", lm->mod_percpu, p1, p2);
+
+ dump_percpu_symbols(lm);
+
+ p1 = "MODULE PERCPU END";
+ fprintf(fp, "%lx %s: %s\n",
+ lm->mod_percpu + lm->mod_percpu_size, p1, p2);
+ }
+
for (m = 0; m < lm->nr_mems; m++) {
j = lm->address_order[m];
@@ -1327,21 +1340,8 @@ module_symbol_dump(char *module)
sp = lm->symtable[j];
sp_end = lm->symend[j];
- percpu_syms = 0;
- for (start = FALSE; sp <= sp_end; sp++) {
- /* TODO
- if (IN_MODULE_PERCPU(sp->value, lm)) {
- if (percpu_syms == DISPLAYED)
- continue;
- if (!start) {
- percpu_syms = TBD;
- continue;
- }
- dump_percpu_symbols(lm);
- percpu_syms = DISPLAYED;
- }
- */
+ for ( ; sp <= sp_end; sp++) {
if (MODULE_PSEUDO_SYMBOL(sp)) {
if (MODULE_SECTION_START(sp)) {
p1 = sp->name + strlen("_MODULE_SECTION_START ");
@@ -1352,30 +1352,15 @@ module_symbol_dump(char *module)
} else if (STRNEQ(sp->name, module_start_tags[j])) {
p1 = module_start_strs[j];
p2 = sp->name + strlen(module_start_tags[j]);
- start = TRUE;
} else if (STRNEQ(sp->name, module_end_tags[j])) {
p1 = module_end_strs[j];
p2 = sp->name + strlen(module_end_tags[j]);
- /* TODO
- if (MODULE_PERCPU_SYMS_LOADED(lm) &&
- !percpu_syms) {
- dump_percpu_symbols(lm);
- percpu_syms = DISPLAYED;
- }
- */
} else {
p1 = "unknown tag";
p2 = sp->name;
}
fprintf(fp, "%lx %s: %s\n", sp->value, p1, p2);
-
- /* TODO
- if (percpu_syms == TBD) {
- dump_percpu_symbols(lm);
- percpu_syms = DISPLAYED;
- }
- */
} else
show_symbol(sp, 0, SHOW_RADIX());
}
@@ -1497,8 +1482,14 @@ dump_percpu_symbols(struct load_module *lm)
struct syment *sp, *sp_end;
if (MODULE_PERCPU_SYMS_LOADED(lm)) {
- sp = lm->mod_symtable;
- sp_end = lm->mod_symend;
+ if (MODULE_MEMORY()) {
+ /* The lm should have mod_load_symtable. */
+ sp = lm->mod_load_symtable;
+ sp_end = lm->mod_load_symend;
+ } else {
+ sp = lm->mod_symtable;
+ sp_end = lm->mod_symend;
+ }
for ( ; sp <= sp_end; sp++) {
if (IN_MODULE_PERCPU(sp->value, lm))
show_symbol(sp, 0, SHOW_RADIX());
@@ -2314,6 +2305,11 @@ store_module_symbols_v3(ulong total, int mods_installed)
if (symbol_query("__insmod_", NULL, NULL))
st->flags |= INSMOD_BUILTIN;
+ if (CRASHDEBUG(2)) {
+ for (sp = st->ext_module_symtable; sp < st->ext_module_symend; sp++)
+ fprintf(fp, "%16lx %s\n", sp->value, sp->name);
+ }
+
if (mcnt > total)
error(FATAL, "store_module_symbols_v3: total: %ld mcnt: %d\n", total, mcnt);
}
@@ -12128,6 +12124,13 @@ store_section_data(struct load_module *lm, bfd *bfd, asection
*section)
lm->mod_section_data[i].section = section;
lm->mod_section_data[i].priority = prio;
lm->mod_section_data[i].flags = section->flags & ~SEC_FOUND;
+ lm->mod_section_data[i].size = bfd_section_size(section);
+ lm->mod_section_data[i].offset = 0;
+ lm->mod_section_data[i].addr = 0;
+ if (strlen(name) < MAX_MOD_SEC_NAME)
+ strcpy(lm->mod_section_data[i].name, name);
+ else
+ strncpy(lm->mod_section_data[i].name, name, MAX_MOD_SEC_NAME-1);
/*
* The percpu section isn't included in kallsyms or module_core area.
*/
@@ -12135,14 +12138,8 @@ store_section_data(struct load_module *lm, bfd *bfd, asection
*section)
(STREQ(name,".data.percpu") || STREQ(name, ".data..percpu"))) {
lm->mod_percpu_size = bfd_section_size(section);
lm->mod_section_data[i].flags |= SEC_FOUND;
+ lm->mod_section_data[i].addr = lm->mod_percpu;
}
- lm->mod_section_data[i].size = bfd_section_size(section);
- lm->mod_section_data[i].offset = 0;
- lm->mod_section_data[i].addr = 0;
- if (strlen(name) < MAX_MOD_SEC_NAME)
- strcpy(lm->mod_section_data[i].name, name);
- else
- strncpy(lm->mod_section_data[i].name, name, MAX_MOD_SEC_NAME-1);
lm->mod_sections += 1;
}
@@ -13546,11 +13543,8 @@ append_section_symbols:
}
lm->symtable = lm->load_symtable;
lm->symend = lm->load_symend;
- for (i = MOD_TEXT; i < MOD_MEM_NUM_TYPES; i++) {
- if (!lm->symtable[i])
- continue;
- mod_symtable_hash_install_range(lm->symtable[i], lm->symend[i]);
- }
+ /* percpu symbols is out of the ranges.. */
+ mod_symtable_hash_install_range(lm->mod_load_symtable, lm->mod_load_symend);
} else {
mod_symtable_hash_remove_range(lm->mod_symtable, lm->mod_symend);
lm->mod_symtable = lm->mod_load_symtable;
--
2.31.1