public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
From: Hui Zhu <teawater@gmail.com>
To: "linux-kernel@vger.kernel.org" <linux-kernel@vger.kernel.org>
Cc: acme@redhat.com, bp@suse.de, gthelen@google.com,
	rui.zhang@intel.com, jacob.jun.pan@linux.intel.com,
	albcamus@gmail.com
Subject: [PATCH 2/2] tool and script help GDB load Linux kernel modules (script)
Date: Sat, 21 Dec 2013 23:50:13 +0800	[thread overview]
Message-ID: <52B5B8B5.6010909@gmail.com> (raw)

getmod.py is a application of KGTP (https://kgtp.googlecode.com) too.

After GDB connected to the gdbstub such as KGTP, KGDB, QEMU, call it with
GDB command "source getmod.py".  Then GDB will auto load all the debug
info of Linux Kernel modules.

Because GDB need parse the struct the data of module list, this script is
slower than getmod.

Signed-off-by: Hui Zhu <teawater@gmail.com>
---
--- /dev/null
+++ b/scripts/getmod.py
@@ -0,0 +1,151 @@
+#!/usr/bin/python
+
+# This script is used by GDB to load the symbols from Linux kernel modules
+# Copyright(C) KGTP team (https://kgtp.googlecode.com), 2011-2013
+# Licensed under the GNU General Public License, version 2.0 (GPLv2)
+
+#Set special mod_search_dir
+#set $mod_search_dir="dir"
+#Clear special mod_search_dir
+#set $mod_search_dir=(void)1
+#Not ignore gtp.ko
+#set $ignore_gtp_ko=0
+
+import gdb
+import os
+
+def get_pagination():
+	buf = gdb.execute("show pagination", False, True)
+	begin = buf.find("State of pagination is ") + len("State of pagination is ")
+	if begin < 0:
+		raise NotImplementedError("Cannot get pagination")
+	buf = buf[begin:]
+	end = buf.rfind(".")
+	buf = buf[:end]
+
+	return buf
+
+pagination = get_pagination()
+gdb.execute("set pagination off", False, False)
+
+def format_file(name):
+	tmp = ""
+	for c in name:
+		if c == "_":
+			c = "-"
+		tmp += c
+	return tmp
+
+#Check if the target is available
+if str(gdb.selected_thread()) == "None":
+	raise gdb.error("Please connect to Linux Kernel before use the script.")
+
+#Output the help
+print "Use GDB command \"set $mod_search_dir=dir\" to set an directory for search the modules."
+
+ignore_gtp_ko = gdb.parse_and_eval("$ignore_gtp_ko")
+if ignore_gtp_ko.type.code == gdb.TYPE_CODE_INT:
+	ignore_gtp_ko = int(ignore_gtp_ko)
+else:
+	ignore_gtp_ko = 1
+
+#Get the mod_search_dir
+mod_search_dir_list = []
+#Get dir from $mod_search_dir
+tmp_dir = gdb.parse_and_eval("$mod_search_dir")
+if tmp_dir.type.code == gdb.TYPE_CODE_ARRAY:
+	tmp_dir = str(tmp_dir)
+	tmp_dir = tmp_dir[1:len(tmp_dir)]
+	tmp_dir = tmp_dir[0:tmp_dir.index("\"")]
+	mod_search_dir_list.append(tmp_dir)
+#Get dir that same with current vmlinux
+tmp_dir = str(gdb.execute("info files", False, True))
+tmp_dir = tmp_dir[tmp_dir.index("Symbols from \"")+len("Symbols from \""):len(tmp_dir)]
+tmp_dir = tmp_dir[0:tmp_dir.index("\"")]
+tmp_dir = tmp_dir[0:tmp_dir.rindex("/")]
+mod_search_dir_list.append(tmp_dir)
+#Get the dir of current Kernel
+tmp_dir = "/lib/modules/" + str(os.uname()[2])
+if os.path.isdir(tmp_dir):
+	mod_search_dir_list.append(tmp_dir)
+#Let user choice dir
+mod_search_dir = ""
+while mod_search_dir == "":
+	for i in range(0, len(mod_search_dir_list)):
+		print str(i)+". "+mod_search_dir_list[i]
+	try:
+		s = input('Select a directory for search the modules [0]:')
+	except SyntaxError:
+		s = 0
+	except:
+		continue
+	if s < 0 or s >= len(mod_search_dir_list):
+		continue
+	mod_search_dir = mod_search_dir_list[s]
+
+mod_list_offset = long(gdb.parse_and_eval("((size_t) &(((struct module *)0)->list))"))
+mod_list = long(gdb.parse_and_eval("(&modules)"))
+mod_list_current = mod_list
+
+while 1:
+	mod_list_current = long(gdb.parse_and_eval("((struct list_head *) "+str(mod_list_current)+")->next"))
+
+	#check if need break the loop
+	if mod_list == mod_list_current:
+		break
+
+	mod = mod_list_current - mod_list_offset
+
+	#get mod_name
+	mod_name = str(gdb.parse_and_eval("((struct module *)"+str(mod)+")->name"))
+	mod_name = mod_name[mod_name.index("\"")+1:len(mod_name)]
+	mod_name = mod_name[0:mod_name.index("\"")]
+	mod_name += ".ko"
+	mod_name = format_file(mod_name)
+
+	#get mod_dir_name
+	mod_dir_name = ""
+	for root, dirs, files in os.walk(mod_search_dir):
+		for afile in files:
+			tmp_file = format_file(afile)
+			if tmp_file == mod_name:
+				mod_dir_name = os.path.join(root,afile)
+				break
+		if mod_dir_name != "":
+			break
+
+	command = " "
+
+	#Add module_core to command
+	tmp = str(gdb.parse_and_eval("((struct module *)"+str(mod)+")->module_core"))
+	if tmp.find('<') >= 0:
+		tmp = tmp[:tmp.index('<')]
+	command += tmp
+
+	#Add each sect_attrs->attrs to command
+	#get nsections
+	nsections = int(gdb.parse_and_eval("((struct module *)"+str(mod)+")->sect_attrs->nsections"))
+	sect_attrs = long(gdb.parse_and_eval("(u64)((struct module *)"+str(mod)+")->sect_attrs"))
+	for i in range(0, nsections):
+		command += " -s"
+		tmp = str(gdb.parse_and_eval("((struct module_sect_attrs *)"+str(sect_attrs)+")->attrs["+str(i)+"].name"))
+		tmp = tmp[tmp.index("\"")+1:len(tmp)]
+		tmp = tmp[0:tmp.index("\"")]
+		command += " "+tmp
+		tmp = str(gdb.parse_and_eval("((struct module_sect_attrs *)"+str(sect_attrs)+")->attrs["+str(i)+"].address"))
+		command += " "+tmp
+
+	if mod_dir_name == "":
+		print "Cannot find out",mod_name,"from directory."
+		print "Please use following command load the symbols from it:"
+		print "add-symbol-file some_dir/"+mod_name+command
+	else:
+		if ignore_gtp_ko and mod_name == "gtp.ko":
+			print "gtp.ko is ignored.  You can use command \"set $ignore_gtp_ko=0\" to close this ignore."
+			print "Or you can use following command load the symbols from it:"
+			print "add-symbol-file "+mod_dir_name+command
+		else:
+			#print "add-symbol-file "+mod_dir_name+command
+			gdb.execute("add-symbol-file "+mod_dir_name+command, False, False)
+
+gdb.execute("set pagination " + pagination, False, False)

                 reply	other threads:[~2013-12-21 15:50 UTC|newest]

Thread overview: [no followups] expand[flat|nested]  mbox.gz  Atom feed

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=52B5B8B5.6010909@gmail.com \
    --to=teawater@gmail.com \
    --cc=acme@redhat.com \
    --cc=albcamus@gmail.com \
    --cc=bp@suse.de \
    --cc=gthelen@google.com \
    --cc=jacob.jun.pan@linux.intel.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=rui.zhang@intel.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox