diff options
author | Greg Clayton <gclayton@apple.com> | 2013-07-11 22:38:00 +0000 |
---|---|---|
committer | Greg Clayton <gclayton@apple.com> | 2013-07-11 22:38:00 +0000 |
commit | 04bd68407470536d2d2c6274b6b5dae754c1c9b0 (patch) | |
tree | 00115336549556b7b16611709fcbae2f89bbc803 /lldb/examples/python | |
parent | 10691b1d3674f76174e38a5c95c7dcb815534a1d (diff) | |
download | bcm5719-llvm-04bd68407470536d2d2c6274b6b5dae754c1c9b0.tar.gz bcm5719-llvm-04bd68407470536d2d2c6274b6b5dae754c1c9b0.zip |
Added a memory.py module that contains a 'memfind' command which allows you to search memory for a byte pattern.
llvm-svn: 186127
Diffstat (limited to 'lldb/examples/python')
-rwxr-xr-x | lldb/examples/python/memory.py | 181 |
1 files changed, 181 insertions, 0 deletions
diff --git a/lldb/examples/python/memory.py b/lldb/examples/python/memory.py new file mode 100755 index 00000000000..ae78e24e2e2 --- /dev/null +++ b/lldb/examples/python/memory.py @@ -0,0 +1,181 @@ +#!/usr/bin/python + +#---------------------------------------------------------------------- +# Be sure to add the python path that points to the LLDB shared library. +# +# # To use this in the embedded python interpreter using "lldb" just +# import it with the full path using the "command script import" +# command +# (lldb) command script import /path/to/cmdtemplate.py +#---------------------------------------------------------------------- + +import commands +import platform +import os +import re +import sys + +try: + # Just try for LLDB in case PYTHONPATH is already correctly setup + import lldb +except ImportError: + lldb_python_dirs = list() + # lldb is not in the PYTHONPATH, try some defaults for the current platform + platform_system = platform.system() + if platform_system == 'Darwin': + # On Darwin, try the currently selected Xcode directory + xcode_dir = commands.getoutput("xcode-select --print-path") + if xcode_dir: + lldb_python_dirs.append(os.path.realpath(xcode_dir + '/../SharedFrameworks/LLDB.framework/Resources/Python')) + lldb_python_dirs.append(xcode_dir + '/Library/PrivateFrameworks/LLDB.framework/Resources/Python') + lldb_python_dirs.append('/System/Library/PrivateFrameworks/LLDB.framework/Resources/Python') + success = False + for lldb_python_dir in lldb_python_dirs: + if os.path.exists(lldb_python_dir): + if not (sys.path.__contains__(lldb_python_dir)): + sys.path.append(lldb_python_dir) + try: + import lldb + except ImportError: + pass + else: + print 'imported lldb from: "%s"' % (lldb_python_dir) + success = True + break + if not success: + print "error: couldn't locate the 'lldb' module, please set PYTHONPATH correctly" + sys.exit(1) + +import commands +import optparse +import shlex +import string +import struct +import time + +def append_data_callback(option, opt_str, value, parser): + if opt_str == "--uint8": + int8 = int(value, 0) + parser.values.data += struct.pack('1B',int8) + if opt_str == "--uint16": + int16 = int(value, 0) + parser.values.data += struct.pack('1H',int16) + if opt_str == "--uint32": + int32 = int(value, 0) + parser.values.data += struct.pack('1I',int32) + if opt_str == "--uint64": + int64 = int(value, 0) + parser.values.data += struct.pack('1Q',int64) + if opt_str == "--int8": + int8 = int(value, 0) + parser.values.data += struct.pack('1b',int8) + if opt_str == "--int16": + int16 = int(value, 0) + parser.values.data += struct.pack('1h',int16) + if opt_str == "--int32": + int32 = int(value, 0) + parser.values.data += struct.pack('1i',int32) + if opt_str == "--int64": + int64 = int(value, 0) + parser.values.data += struct.pack('1q',int64) + +def create_memfind_options(): + usage = "usage: %prog [options] STARTADDR [ENDADDR]" + description='''This command can find data in a specified address range. +Options are used to specify the data that is to be looked for and the options +can be specified multiple times to look for longer streams of data. +''' + parser = optparse.OptionParser(description=description, prog='memfind',usage=usage) + parser.add_option('-s', '--size', type='int', metavar='BYTESIZE', dest='size', help='Specify the byte size to search.', default=0) + parser.add_option('--int8', action="callback", callback=append_data_callback, type='string', metavar='INT', dest='data', help='Specify a 8 bit signed integer value to search for in memory.', default='') + parser.add_option('--int16', action="callback", callback=append_data_callback, type='string', metavar='INT', dest='data', help='Specify a 16 bit signed integer value to search for in memory.', default='') + parser.add_option('--int32', action="callback", callback=append_data_callback, type='string', metavar='INT', dest='data', help='Specify a 32 bit signed integer value to search for in memory.', default='') + parser.add_option('--int64', action="callback", callback=append_data_callback, type='string', metavar='INT', dest='data', help='Specify a 64 bit signed integer value to search for in memory.', default='') + parser.add_option('--uint8', action="callback", callback=append_data_callback, type='string', metavar='INT', dest='data', help='Specify a 8 bit unsigned integer value to search for in memory.', default='') + parser.add_option('--uint16', action="callback", callback=append_data_callback, type='string', metavar='INT', dest='data', help='Specify a 16 bit unsigned integer value to search for in memory.', default='') + parser.add_option('--uint32', action="callback", callback=append_data_callback, type='string', metavar='INT', dest='data', help='Specify a 32 bit unsigned integer value to search for in memory.', default='') + parser.add_option('--uint64', action="callback", callback=append_data_callback, type='string', metavar='INT', dest='data', help='Specify a 64 bit unsigned integer value to search for in memory.', default='') + return parser + +def memfind_command (debugger, command, result, dict): + # Use the Shell Lexer to properly parse up command options just like a + # shell would + command_args = shlex.split(command) + parser = create_memfind_options() + (options, args) = parser.parse_args(command_args) + # try: + # (options, args) = parser.parse_args(command_args) + # except: + # # if you don't handle exceptions, passing an incorrect argument to the OptionParser will cause LLDB to exit + # # (courtesy of OptParse dealing with argument errors by throwing SystemExit) + # result.SetStatus (lldb.eReturnStatusFailed) + # print >>result, "error: option parsing failed" # returning a string is the same as returning an error whose description is the string + # return + memfind (debugger.GetSelectedTarget(), options, args, result) + +def print_error(str, show_usage, result): + print >>result, str + if show_usage: + print >>result, create_memfind_options().format_help() + +def memfind (target, options, args, result): + num_args = len(args) + start_addr = 0 + if num_args == 1: + if options.size > 0: + print_error ("error: --size must be specified if there is no ENDADDR argument", True, result) + return + start_addr = int(args[0], 0) + elif num_args == 2: + if options.size != 0: + print_error ("error: --size can't be specified with an ENDADDR argument", True, result) + return + start_addr = int(args[0], 0) + end_addr = int(args[1], 0) + if start_addr >= end_addr: + print_error ("error: inavlid memory range [%#x - %#x)" % (start_addr, end_addr), True, result) + return + options.size = end_addr - start_addr + else: + print_error ("error: memfind takes 1 or 2 arguments", True, result) + return + + if not options.data: + print >>result, 'error: no data specified to search for' + return + + if not target: + print >>result, 'error: invalid target' + return + process = target.process + if not process: + print >>result, 'error: invalid process' + return + + error = lldb.SBError() + bytes = process.ReadMemory (start_addr, options.size, error) + if error.Success(): + num_matches = 0 + print >>result, "Searching memory range [%#x - %#x) for" % (start_addr, end_addr), + for byte in options.data: + print >>result, '%2.2x' % ord(byte), + print >>result + + match_index = string.find(bytes, options.data) + while match_index != -1: + num_matches = num_matches + 1 + print >>result, '%#x: %#x + %u' % (start_addr + match_index, start_addr, match_index) + match_index = string.find(bytes, options.data, match_index + 1) + + if num_matches == 0: + print >>result, "error: no matches found" + else: + print >>result, 'error: %s' % (error.GetCString()) + + +if __name__ == '__main__': + print 'error: this script is designed to be used within the embedded script interpreter in LLDB' +elif getattr(lldb, 'debugger', None): + memfind_command.__doc__ = create_memfind_options().format_help() + lldb.debugger.HandleCommand('command script add -f memory.memfind_command memfind') + print '"memfind" command installed, use the "--help" option for detailed help' |