#!/usr/bin/python # This script is used by GDB to load the symbols from Linux kernel modules # GPL # Copyright(C) Hui Zhu (teawater@gmail.com), 2011 #Set special mod_search_dir #set $mod_search_dir="dir" #Clear special mod_search_dir #set $mod_search_dir=(void)1 import gdb; import os; def format_file(name): tmp = ""; for c in name: if c == "_": c = "-"; tmp += c; return tmp; #Get the mod_search_dir mod_search_dir = gdb.parse_and_eval("$mod_search_dir"); if mod_search_dir.type.code == gdb.TYPE_CODE_ARRAY: mod_search_dir = str(mod_search_dir); mod_search_dir = mod_search_dir[1:len(mod_search_dir)]; mod_search_dir = mod_search_dir[0:mod_name.index("\"")]; else: mod_search_dir = str(gdb.execute("info files", False, True)); mod_search_dir = mod_search_dir[mod_search_dir.index("Symbols from \"")+len("Symbols from \""):len(mod_search_dir)]; mod_search_dir = mod_search_dir[0:mod_search_dir.index("\"")]; mod_search_dir = mod_search_dir[0:mod_search_dir.rindex("/")]; print "Search modules from "+mod_search_dir+"\n"; 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 command += str(gdb.parse_and_eval("((struct module *)"+str(mod)+")->module_core")); #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 "Can 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: #print "add-symbol-file "+mod_dir_name+command; gdb.execute("add-symbol-file "+mod_dir_name+command, False, False);