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...@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

--
Crash-utility mailing list
Crash-utility@redhat.com
https://listman.redhat.com/mailman/listinfo/crash-utility
Contribution Guidelines: https://github.com/crash-utility/crash/wiki

Reply via email to