Hi, Sun Feng
Thank you for the patch.
On Mon, Oct 28, 2024 at 11:32 AM <devel-request(a)lists.crash-utility.osci.io>
wrote:
>
> Date: Wed, 23 Oct 2024 08:53:58 +0800
> From: Sun Feng <loyou85(a)gmail.com>
> Subject: [Crash-utility] [PATCH] mod: introduce -v option to display
> modules with valid version
> To: devel(a)lists.crash-utility.osci.io
> Cc: Sun Feng <loyou85(a)gmail.com>
> Message-ID: <20241023005358.11328-1-loyou85(a)gmail.com>
>
> With this option, we can get module version easily in kdump,
> it's helpful when developing external modules.
It seems to be a specific case?
>
>
> crash> mod -v
> NAME VERSION
> ahci 3.0
> vxlan 0.1.2.1
> dca 1.12.1
> ...
>
> Signed-off-by: Sun Feng <loyou85(a)gmail.com>
> ---
> defs.h | 3 +++
> help.c | 12 +++++++++++-
> kernel.c | 46 +++++++++++++++++++++++++++++++++++++++++++++-
> symbols.c | 44 +++++++++++++++++++++++++++++++++++++++-----
> 4 files changed, 98 insertions(+), 7 deletions(-)
>
> diff --git a/defs.h b/defs.h
> index e2a9278..f14fcdf 100644
> --- a/defs.h
> +++ b/defs.h
> @@ -2244,6 +2244,7 @@ struct offset_table { /* stash of
commonly-used offsets */
> long rb_list_head;
> long file_f_inode;
> long page_page_type;
> + long module_version;
> };
>
> struct size_table { /* stash of commonly-used sizes */
> @@ -2935,6 +2936,7 @@ struct symbol_table_data {
>
> #define MAX_MOD_NAMELIST (256)
> #define MAX_MOD_NAME (64)
> +#define MAX_MOD_VERSION (64)
> #define MAX_MOD_SEC_NAME (64)
>
> #define MOD_EXT_SYMS (0x1)
> @@ -2984,6 +2986,7 @@ struct load_module {
> long mod_size;
> char mod_namelist[MAX_MOD_NAMELIST];
> char mod_name[MAX_MOD_NAME];
> + char mod_version[MAX_MOD_VERSION];
> ulong mod_flags;
> struct syment *mod_symtable;
> struct syment *mod_symend;
> diff --git a/help.c b/help.c
> index e95ac1d..1bac5e1 100644
> --- a/help.c
> +++ b/help.c
> @@ -5719,7 +5719,7 @@ NULL
> char *help_mod[] = {
> "mod",
> "module information and loading of symbols and debugging data",
> -"-s module [objfile] | -d module | -S [directory] [-D|-t|-r|-R|-o|-g]",
> +"-s module [objfile] | -d module | -S [directory]
[-D|-t|-r|-R|-o|-g|-v]",
> " With no arguments, this command displays basic information of the
currently",
> " installed modules, consisting of the module address, name, base
address,",
> " size, the object file name (if known), and whether the module was
compiled",
> @@ -5791,6 +5791,7 @@ char *help_mod[] = {
> " -g When used with -s or -S, add a module object's
section",
> " start and end addresses to its symbol list.",
> " -o Load module symbols with old mechanism.",
> +" -v Display modules with valid version.",
> " ",
> " If the %s session was invoked with the \"--mod <directory>\"
option, or",
> " a CRASH_MODULE_PATH environment variable exists, then
/lib/modules/<release>",
> @@ -5881,6 +5882,15 @@ char *help_mod[] = {
> " vxglm P(U)",
> " vxgms P(U)",
> " vxodm P(U)",
> +" ",
> +" Display modules with valid version:",
> +" ",
> +" %s> mod -v",
> +" NAME VERSION",
> +" ahci 3.0",
> +" vxlan 0.1.2.1",
> +" dca 1.12.1",
> +" ...",
> NULL
> };
There are many kernel modules, which do not have the actual value for the field
"version"(null), E.g:
crash> struct module c008000005cb1d00
struct module {
...
version = 0x0,
srcversion = 0xc00000009c3628c0 "7D7FAEDDA764AC772D6F805",
...
Currently, it is also easy to view the version string, for example:
crash> mod
MODULE NAME TEXT_BASE SIZE OBJECT FILE
c008000004400080 libcrc32c c008000004260000 196608 (not loaded)
[CONFIG_KALLSYMS]
...
c0080000044a0700 sg c008000004480000 262144 (not loaded)
[CONFIG_KALLSYMS]
...
crash> struct module c0080000044a0700|grep -w version
version = 0xc000000009d67f20 "3.5.36",
Could you please explain the current background? Why is it needed? As you saw, it's
not too hard to get a module version string based on crash internal command.
Agreed, there is no need to bring in extra code to implement this when
we already have an approach to achieve the same.
Thanks,
Tao Liu
Thanks
Lianbo
>
>
> diff --git a/kernel.c b/kernel.c
> index adb19ad..91eef2a 100644
> --- a/kernel.c
> +++ b/kernel.c
> @@ -3593,6 +3593,9 @@ module_init(void)
> MEMBER_OFFSET_INIT(module_num_gpl_syms, "module",
> "num_gpl_syms");
>
> + if (MEMBER_EXISTS("module", "version"))
> + MEMBER_OFFSET_INIT(module_version, "module",
"version");
> +
> if (MEMBER_EXISTS("module", "mem")) { /* 6.4
and later */
> kt->flags2 |= KMOD_MEMORY; /* MODULE_MEMORY() can be
used. */
>
> @@ -4043,6 +4046,7 @@ irregularity:
> #define REMOTE_MODULE_SAVE_MSG (6)
> #define REINIT_MODULES (7)
> #define LIST_ALL_MODULE_TAINT (8)
> +#define LIST_ALL_MODULE_VERSION (9)
>
> void
> cmd_mod(void)
> @@ -4117,7 +4121,7 @@ cmd_mod(void)
> address = 0;
> flag = LIST_MODULE_HDR;
>
> - while ((c = getopt(argcnt, args, "Rd:Ds:Sot")) != EOF) {
> + while ((c = getopt(argcnt, args, "Rd:Ds:Sotv")) != EOF) {
> switch(c)
> {
> case 'R':
> @@ -4195,6 +4199,13 @@ cmd_mod(void)
> flag = LIST_ALL_MODULE_TAINT;
> break;
>
> + case 'v':
> + if (flag)
> + cmd_usage(pc->curcmd, SYNOPSIS);
> + else
> + flag = LIST_ALL_MODULE_VERSION;
> + break;
> +
> default:
> argerrs++;
> break;
> @@ -4578,10 +4589,12 @@ do_module_cmd(ulong flag, char *modref, ulong address,
> struct load_module *lm, *lmp;
> int maxnamelen;
> int maxsizelen;
> + int maxversionlen;
> char buf1[BUFSIZE];
> char buf2[BUFSIZE];
> char buf3[BUFSIZE];
> char buf4[BUFSIZE];
> + char buf5[BUFSIZE];
>
> if (NO_MODULES())
> return;
> @@ -4744,6 +4757,37 @@ do_module_cmd(ulong flag, char *modref, ulong address,
> case LIST_ALL_MODULE_TAINT:
> show_module_taint();
> break;
> +
> + case LIST_ALL_MODULE_VERSION:
> + maxnamelen = maxversionlen = 0;
> +
> + for (i = 0; i < kt->mods_installed; i++) {
> + lm = &st->load_modules[i];
> + maxnamelen = strlen(lm->mod_name) > maxnamelen ?
> + strlen(lm->mod_name) : maxnamelen;
> +
> + maxversionlen = strlen(lm->mod_version) > maxversionlen
?
> + strlen(lm->mod_version) : maxversionlen;
> + }
> +
> + fprintf(fp, "%s %s\n",
> + mkstring(buf2, maxnamelen, LJUST, "NAME"),
> + mkstring(buf5, maxversionlen, LJUST, "VERSION"));
> +
> + for (i = 0; i < kt->mods_installed; i++) {
> + lm = &st->load_modules[i];
> + if ((!address || (lm->module_struct == address) ||
> + (lm->mod_base == address)) &&
> + strlen(lm->mod_version)) {
> + fprintf(fp, "%s ", mkstring(buf2,
maxnamelen,
> + LJUST, lm->mod_name));
> + fprintf(fp, "%s ", mkstring(buf5,
maxversionlen,
> + LJUST, lm->mod_version));
> +
> + fprintf(fp, "\n");
> + }
> + }
> + break;
> }
> }
>
> diff --git a/symbols.c b/symbols.c
> index d00fbd7..9d90df7 100644
> --- a/symbols.c
> +++ b/symbols.c
> @@ -1918,6 +1918,7 @@ store_module_symbols_6_4(ulong total, int mods_installed)
> {
> int i, m, t;
> ulong mod, mod_next;
> + ulong version;
> char *mod_name;
> uint nsyms, ngplsyms;
> ulong syms, gpl_syms;
> @@ -1930,6 +1931,7 @@ store_module_symbols_6_4(ulong total, int mods_installed)
> struct load_module *lm;
> char buf1[BUFSIZE];
> char buf2[BUFSIZE];
> + char mod_version[BUFSIZE];
> char *strbuf = NULL, *modbuf, *modsymbuf;
> struct syment *sp;
> ulong first, last;
> @@ -1980,6 +1982,13 @@ store_module_symbols_6_4(ulong total, int mods_installed)
>
> mod_name = modbuf + OFFSET(module_name);
>
> + BZERO(mod_version, BUFSIZE);
> + if (MEMBER_EXISTS("module", "version")) {
> + version = ULONG(modbuf + OFFSET(module_version));
> + if (version)
> + read_string(version, mod_version, BUFSIZE - 1);
> + }
> +
> lm = &st->load_modules[m++];
> BZERO(lm, sizeof(struct load_module));
>
> @@ -2003,9 +2012,15 @@ store_module_symbols_6_4(ulong total, int mods_installed)
> error(INFO, "module name greater than MAX_MOD_NAME:
%s\n", mod_name);
> strncpy(lm->mod_name, mod_name, MAX_MOD_NAME-1);
> }
> + if (strlen(mod_version) < MAX_MOD_VERSION)
> + strcpy(lm->mod_version, mod_version);
> + else {
> + error(INFO, "module version greater than
MAX_MOD_VERSION: %s\n", mod_version);
> + strncpy(lm->mod_version, mod_version, MAX_MOD_VERSION-1);
> + }
> if (CRASHDEBUG(3))
> - fprintf(fp, "%lx (%lx): %s syms: %d gplsyms: %d ksyms:
%ld\n",
> - mod, lm->mod_base, lm->mod_name, nsyms,
ngplsyms, nksyms);
> + fprintf(fp, "%lx (%lx): %s syms: %d gplsyms: %d ksyms:
%ld version: %s\n",
> + mod, lm->mod_base, lm->mod_name, nsyms,
ngplsyms, nksyms, lm->mod_version);
>
> lm->mod_flags = MOD_EXT_SYMS;
> lm->mod_ext_symcnt = mcnt;
> @@ -2271,6 +2286,7 @@ store_module_symbols_v2(ulong total, int mods_installed)
> {
> int i, m;
> ulong mod, mod_next;
> + ulong version;
> char *mod_name;
> uint nsyms, ngplsyms;
> ulong syms, gpl_syms;
> @@ -2285,6 +2301,7 @@ store_module_symbols_v2(ulong total, int mods_installed)
> char buf2[BUFSIZE];
> char buf3[BUFSIZE];
> char buf4[BUFSIZE];
> + char mod_version[BUFSIZE];
> char *strbuf, *modbuf, *modsymbuf;
> struct syment *sp;
> ulong first, last;
> @@ -2344,6 +2361,13 @@ store_module_symbols_v2(ulong total, int mods_installed)
>
> mod_name = modbuf + OFFSET(module_name);
>
> + BZERO(mod_version, BUFSIZE);
> + if (MEMBER_EXISTS("module", "version")) {
> + version = ULONG(modbuf + OFFSET(module_version));
> + if (version)
> + read_string(version, mod_version, BUFSIZE - 1);
> + }
> +
> lm = &st->load_modules[m++];
> BZERO(lm, sizeof(struct load_module));
> lm->mod_base = ULONG(modbuf + MODULE_OFFSET2(module_module_core,
rx));
> @@ -2357,11 +2381,19 @@ store_module_symbols_v2(ulong total, int mods_installed)
> mod_name);
> strncpy(lm->mod_name, mod_name, MAX_MOD_NAME-1);
> }
> + if (strlen(mod_version) < MAX_MOD_VERSION)
> + strcpy(lm->mod_version, mod_version);
> + else {
> + error(INFO,
> + "module version greater than MAX_MOD_VERSION:
%s\n",
> + mod_version);
> + strncpy(lm->mod_version, mod_version, MAX_MOD_VERSION-1);
> + }
> if (CRASHDEBUG(3))
> fprintf(fp,
> - "%lx (%lx): %s syms: %d gplsyms: %d ksyms:
%ld\n",
> - mod, lm->mod_base, lm->mod_name, nsyms,
> - ngplsyms, nksyms);
> + "%lx (%lx): %s syms: %d gplsyms: %d ksyms: %ld
version: %s\n",
> + mod, lm->mod_base, lm->mod_name, nsyms,
> + ngplsyms, nksyms, lm->mod_version);
> lm->mod_flags = MOD_EXT_SYMS;
> lm->mod_ext_symcnt = mcnt;
> lm->mod_init_module_ptr = ULONG(modbuf +
> @@ -10177,6 +10209,8 @@ dump_offset_table(char *spec, ulong makestruct)
> OFFSET(module_next));
> fprintf(fp, " module_name: %ld\n",
> OFFSET(module_name));
> + fprintf(fp, " module_version: %ld\n",
> + OFFSET(module_version));
> fprintf(fp, " module_syms: %ld\n",
> OFFSET(module_syms));
> fprintf(fp, " module_nsyms: %ld\n",
> --
> 2.43.0
--
Crash-utility mailing list -- devel(a)lists.crash-utility.osci.io
To unsubscribe send an email to devel-leave(a)lists.crash-utility.osci.io
https://${domain_name}/admin/lists/devel.lists.crash-utility.osci.io/
Contribution Guidelines:
https://github.com/crash-utility/crash/wiki