On Thu, May 11, 2023 at 12:35 PM HAGIO KAZUHITO(萩尾 一仁) <k-hagio-ab@nec.com> wrote:
To "sym -m" print the symbols of a module in address order.
(but "sym -l" and "sym -M" still print modules in text address order.)


The current text address order is better to me, basically it can keep the same order with the definition mod_mem_type, which looks more natural. For example:
crash> sym -m kvm |grep MODULE
ffffffffc136e000 MODULE TEXT START: kvm
ffffffffc13e0000 MODULE TEXT END: kvm
ffffffffc1ceb000 MODULE DATA START: kvm
ffffffffc1d6b000 MODULE DATA END: kvm
ffffffffc291a000 MODULE RODATA START: kvm
ffffffffc296c000 MODULE RODATA END: kvm
ffffffffc11cf000 MODULE RO_AFTER_INIT START: kvm
ffffffffc11d1000 MODULE RO_AFTER_INIT END: kvm

And the internal output in each module memory type is sorted by address as below:
crash> sym -m kvm
ffffffffc136e000 MODULE TEXT START: kvm
ffffffffc136e000 (T) __pfx___traceiter_kvm_userspace_exit
ffffffffc136e010 (T) __traceiter_kvm_userspace_exit
ffffffffc136e050 (T) __pfx___traceiter_kvm_vcpu_wakeup
ffffffffc136e060 (T) __traceiter_kvm_vcpu_wakeup
ffffffffc136e0b0 (T) __pfx___traceiter_kvm_set_irq
ffffffffc136e0c0 (T) __traceiter_kvm_set_irq
ffffffffc136e110 (T) __pfx___traceiter_kvm_ioapic_set_irq
ffffffffc136e120 (T) __traceiter_kvm_ioapic_set_irq
ffffffffc136e170 (T) __pfx___traceiter_kvm_ioapic_delayed_eoi_inj
...
ffffffffc13df650 (t) kvm_x86_exit
ffffffffc13df650 (T) cleanup_module
ffffffffc13e0000 MODULE TEXT END: kvm

In addition, the sym -m option will be consistent with the styles of sym -l/-M options, and really simplify the code. Given that, I tend to print modules in *text address order* and do not need to change it.

Thanks.
Lianbo


Signed-off-by: Kazuhito Hagio <k-hagio-ab@nec.com>
---
 defs.h    |  2 ++
 symbols.c | 33 ++++++++++++++++++++++++++++++---
 2 files changed, 32 insertions(+), 3 deletions(-)

diff --git a/defs.h b/defs.h
index 655cd2add163..4051eb8d134e 100644
--- a/defs.h
+++ b/defs.h
@@ -2984,6 +2984,8 @@ struct load_module {
        struct module_memory mem[MOD_MEM_NUM_TYPES];
        struct syment *symtable[MOD_MEM_NUM_TYPES];
        struct syment *symend[MOD_MEM_NUM_TYPES];
+       int address_order[MOD_MEM_NUM_TYPES];
+       int nr_mems;
 };

 #define IN_MODULE(A,L)         (_in_module(A, L, MOD_TEXT))
diff --git a/symbols.c b/symbols.c
index 669fa2e2f3da..5edc4844b3d8 100644
--- a/symbols.c
+++ b/symbols.c
@@ -1300,7 +1300,7 @@ symname_hash_search(struct syment *table[], char *name)
 static void
 module_symbol_dump(char *module)
 {
-       int i, j, start, percpu_syms;
+       int i, j, m, start, percpu_syms;
         struct syment *sp, *sp_end;
        struct load_module *lm;
        const char *p1, *p2;
@@ -1317,7 +1317,8 @@ module_symbol_dump(char *module)
                if (received_SIGINT() || output_closed())
                        return;

-               for (j = MOD_TEXT; j < MOD_MEM_NUM_TYPES; j++) {
+               for (m = 0; m < lm->nr_mems; m++) {
+                       j = lm->address_order[m];

                        if (!lm->symtable[j])
                                continue;
@@ -1936,7 +1937,7 @@ static const char *module_end_strs[] = {
 void
 store_module_symbols_v3(ulong total, int mods_installed)
 {
-       int i, m;
+       int i, j, m;
        ulong mod, mod_next;
        char *mod_name;
        uint nsyms, ngplsyms;
@@ -2009,6 +2010,9 @@ store_module_symbols_v3(ulong total, int mods_installed)
                                                SIZE(module_memory) * i + OFFSET(module_memory_base));
                        lm->mem[i].size = UINT(modbuf + OFFSET(module_mem) +
                                                SIZE(module_memory) * i + OFFSET(module_memory_size));
+                       if (lm->mem[i].base)
+                               lm->nr_mems++;
+
                        if (i < MOD_INIT_TEXT)
                                size += lm->mem[i].size;
                }
@@ -2018,6 +2022,24 @@ store_module_symbols_v3(ulong total, int mods_installed)
                lm->mod_size = size;
                lm->module_struct = mod;

+               /* For "sym -m" to print in address order */
+               if (lm->nr_mems) {
+                       int idx = 0;
+                       ulong base, prev_min = 0, min = (ulong)-1;
+                       for (i = 0; i < lm->nr_mems; i++) {
+                               for (j = MOD_TEXT; j < MOD_MEM_NUM_TYPES; j++) {
+                                       base = lm->mem[j].base;
+                                       if (base > prev_min && base < min) {
+                                               min = base;
+                                               idx = j;
+                                       }
+                               }
+                               lm->address_order[i] = idx;
+                               prev_min = min;
+                               min = (ulong)-1;
+                       }
+               }
+
                if (strlen(mod_name) < MAX_MOD_NAME)
                        strcpy(lm->mod_name, mod_name);
                else {
@@ -4052,6 +4074,11 @@ dump_symbol_table(void)
                                fprintf(fp, "                mem[%d]: %lx (%x)\n",
                                        j, lm->mem[j].base, lm->mem[j].size);
                        }
+                       fprintf(fp, "               nr_mems: %d\n", lm->nr_mems);
+                       fprintf(fp, "         address_order:");
+                       for (j = 0; j < lm->nr_mems; j++)
+                               fprintf(fp, " %d", lm->address_order[j]);
+                       fprintf(fp, "\n");
                }

                for (s = 0; s < lm->mod_sections; s++) {
--
2.31.1