[Crash-utility] [PATCH] mod: introduce -v option to display modules with valid version

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



With this option, we can get module version easily in kdump,
it's helpful when developing external modules.

crash> mod -v
NAME   VERSION
ahci   3.0
vxlan  0.1.2.1
dca    1.12.1
...

Signed-off-by: Sun Feng <loyou85@xxxxxxxxx>
---
 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               
 };
 
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@xxxxxxxxxxxxxxxxxxxxxxxxxxx
To unsubscribe send an email to devel-leave@xxxxxxxxxxxxxxxxxxxxxxxxxxx
https://${domain_name}/admin/lists/devel.lists.crash-utility.osci.io/
Contribution Guidelines: https://github.com/crash-utility/crash/wiki




[Index of Archives]     [Fedora Development]     [Fedora Desktop]     [Fedora SELinux]     [Yosemite News]     [KDE Users]     [Fedora Tools]

 

Powered by Linux