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@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. */
Could you please point out where the percpu area is? That can help us to understand easily. For example:
The percpu area is included in the .data..percpu section, and not in any module memory areas.
# objdump -h vmlinux|grep percpu
19 .data..percpu 00035000 0000000000000000 0000000003240000 02600000 2**12
+ 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;
The variable mod_section_data should be initialized once the memory is allocated successfully. Here it should set useful values to the member variables, unless it needs to set the zero for some of the member variables every time.
Thanks
Lianbo
+ 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