Skip to content

Instantly share code, notes, and snippets.

@SJLC
Created November 20, 2016 07:27
Show Gist options
  • Select an option

  • Save SJLC/b37d0f3e859bac7ac8fc751d883768e0 to your computer and use it in GitHub Desktop.

Select an option

Save SJLC/b37d0f3e859bac7ac8fc751d883768e0 to your computer and use it in GitHub Desktop.
# found gdb_strcmp at https://moythreads.com/wordpress/2015/06/25/gdb-strcmp-in-a-core-dump/
define gdb_strcmp
dont-repeat
set $result = 1
set $_i = 0
if ($arg0[0] == 0x0 && $arg1[0] != 0x0)
set $result = 0
end
if ($arg0[0] != 0x0 && $arg1[0] == 0x0)
set $result = 0
end
while ($result == 1 && $arg0[$_i] != 0x0 && $arg1[$_i] != 0x0)
if ($arg0[$_i] != $arg1[$_i])
set $result = 0
end
set $_i = $_i + 1
end
end
document gdb_strcmp
Determines if two C strings match
end
# use kernel variables to find section offsets for a .ko file in order to
# load module symbols at the proper addresses -- works when userspace has crunched
# too badly to use the /sys/module/*/sections technique
# https://www.linux.com/learn/kernel-newbie-corner-kernel-and-module-debugging-gdb
define find_module_sections
set $target_module_name = $arg0
set $target_module_path = $arg1
print "** module name:"
print $target_module_name
print "** path to module file:"
print $target_module_path
set $mod_list = modules.next
set $mod_name = ((struct module *)((unsigned)$mod_list-4))->name
gdb_strcmp $target_module_name $mod_name
set $not_found = ($result == 0)
while ($not_found)
set $mod_list = $mod_list.next
set $mod_name = ((struct module *)((unsigned)$mod_list-4))->name
gdb_strcmp $target_module_name $mod_name
set $not_found = ($result == 0)
end
print $mod_name
set $mod = (struct module *)((unsigned)$mod_list-4)
set $sec_count = $mod->sect_attrs->nsections
set $sec_num = 0
while ($sec_num < $sec_count)
set $sec_name = $mod->sect_attrs.attrs[$sec_num].mattr.attr.name
gdb_strcmp $sec_name ".text"
set $is_text = ($result == 1)
gdb_strcmp $sec_name ".data"
set $is_data = ($result == 1)
gdb_strcmp $sec_name ".bss"
set $is_bss = ($result == 1)
if ($is_text)
print ".text:"
print $sec_name
set $text_addr = $mod->sect_attrs.attrs[$sec_num].address
end
if ($is_data)
print ".data:"
print $sec_name
set $data_addr = $mod->sect_attrs.attrs[$sec_num].address
end
if ($is_bss)
print ".bss:"
print $sec_name
set $bss_addr = $mod->sect_attrs.attrs[$sec_num].address
end
set $sec_num++
end
# would like to just run:
# add-symbol-file $target_module_path $text_addr -s .data $data_addr -s .bss $bss_addr
# but that takes the variables literally instead of expanding them,
# and gdb 'eval' only works if malloc() is available
print "ugh... eval won't work here, so please run the command manually:"
printf "add-symbol-file <path> 0x%x -s .data 0x%x -s .bss 0x%x\n", $text_addr, $data_addr, $bss_addr
print "where <path> is:"
print $target_module_path
end
document find_module_sections
Find offsets for .text, .data, and .bss to be used when loading module file
Arguments:
module name (same as for 'lsmod' or /proc/modules)
path to module file (needs to have been built with CONFIG_DEBUG_INFO=y)
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment