diff options
author | Johnny Chen <johnny.chen@apple.com> | 2011-08-19 20:51:15 +0000 |
---|---|---|
committer | Johnny Chen <johnny.chen@apple.com> | 2011-08-19 20:51:15 +0000 |
commit | 758f288cdd47e01fe26337ffc6b4737342cdd1be (patch) | |
tree | b4ee3525006b49483d48f6599ebfa5dce43a8582 /lldb/utils/test | |
parent | d07e1048440229a0a6d495c64941407d1bc96d15 (diff) | |
download | bcm5719-llvm-758f288cdd47e01fe26337ffc6b4737342cdd1be.tar.gz bcm5719-llvm-758f288cdd47e01fe26337ffc6b4737342cdd1be.zip |
Add a Python script to locate each binary file under a root directory which matches some pathname pattern
and to invoke lldb-disasm.py on the binary file to disassemble its symbols. The number of symbols can
be specified by, for example, '-n 10000', to specify 10,000 symbols to disassemble for each module.
By default, only 1000 symbols from each module are disassembled.
Example:
utils/test/run-dis.py -r '/Developer/Platforms/iPhoneOS.platform/DeviceSupport/4.3/Symbols' -p '^/System/Library/.*Frameworks/.*\.framework/[^/]+$'
tries to disassemble every public/private frameworks (by default only 1000 symbols are disassembled) under iOS4.3.
llvm-svn: 138078
Diffstat (limited to 'lldb/utils/test')
-rwxr-xr-x | lldb/utils/test/lldb-disasm.py | 40 | ||||
-rwxr-xr-x | lldb/utils/test/run-dis.py | 126 |
2 files changed, 148 insertions, 18 deletions
diff --git a/lldb/utils/test/lldb-disasm.py b/lldb/utils/test/lldb-disasm.py index 7825ca93086..7987c6b01c3 100755 --- a/lldb/utils/test/lldb-disasm.py +++ b/lldb/utils/test/lldb-disasm.py @@ -62,18 +62,18 @@ def setupSysPath(): # This is to locate the lldb.py module. Insert it right after sys.path[0]. sys.path[1:1] = [lldbPath] - print "sys.path:", sys.path + #print "sys.path:", sys.path -def run_command(ci, cmd, res, echoInput=True, echoOutput=True): - if echoInput: +def run_command(ci, cmd, res, echo=True): + if echo: print "run command:", cmd ci.HandleCommand(cmd, res) if res.Succeeded(): - if echoOutput: + if echo: print "run_command output:", res.GetOutput() else: - if echoOutput: + if echo: print "run command failed!" print "run_command error:", res.GetError() @@ -104,10 +104,10 @@ def do_lldb_disassembly(lldb_commands, exe, disassemble_options, num_symbols, # See if there any extra command(s) to execute before we issue the file command. for cmd in lldb_commands: - run_command(ci, cmd, res) + run_command(ci, cmd, res, not quiet_disassembly) # Now issue the file command. - run_command(ci, 'file %s' % exe, res) + run_command(ci, 'file %s' % exe, res, not quiet_disassembly) # Create a target. #target = dbg.CreateTarget(exe) @@ -123,7 +123,8 @@ def do_lldb_disassembly(lldb_commands, exe, disassemble_options, num_symbols, # If we specify the symbols to disassemble, ignore symbol table dump. if symbols: for i in range(len(symbols)): - print "symbol:", symbols[i] + if verbose: + print "symbol:", symbols[i] yield symbols[i] else: limited = True if num != -1 else False @@ -133,7 +134,8 @@ def do_lldb_disassembly(lldb_commands, exe, disassemble_options, num_symbols, pattern = re.compile(re_symbol_pattern) stream = lldb.SBStream() for m in target.module_iter(): - print "module:", m + if verbose: + print "module:", m for s in m: if limited and count >= num: return @@ -144,7 +146,8 @@ def do_lldb_disassembly(lldb_commands, exe, disassemble_options, num_symbols, continue # If we come here, we're ready to disassemble the symbol. - print "symbol:", s.GetName() + if verbose: + print "symbol:", s.GetName() if IsCodeType(s): if limited: count = count + 1 @@ -161,7 +164,7 @@ def do_lldb_disassembly(lldb_commands, exe, disassemble_options, num_symbols, # Disassembly time. for symbol in symbol_iter(num_symbols, symbols_to_disassemble, re_symbol_pattern, target, not quiet_disassembly): cmd = "disassemble %s '%s'" % (disassemble_options, symbol) - run_command(ci, cmd, res, True, not quiet_disassembly) + run_command(ci, cmd, res, not quiet_disassembly) def main(): @@ -220,13 +223,14 @@ Usage: %prog [options] re_symbol_pattern = opts.re_symbol_pattern # We have parsed the options. - print "lldb commands:", lldb_commands - print "executable:", executable - print "disassemble options:", disassemble_options - print "quiet disassembly output:", quiet_disassembly - print "num of symbols to disassemble:", num_symbols - print "symbols to disassemble:", symbols_to_disassemble - print "regular expression of symbols to disassemble:", re_symbol_pattern + if not quiet_disassembly: + print "lldb commands:", lldb_commands + print "executable:", executable + print "disassemble options:", disassemble_options + print "quiet disassembly output:", quiet_disassembly + print "num of symbols to disassemble:", num_symbols + print "symbols to disassemble:", symbols_to_disassemble + print "regular expression of symbols to disassemble:", re_symbol_pattern setupSysPath() do_lldb_disassembly(lldb_commands, executable, disassemble_options, diff --git a/lldb/utils/test/run-dis.py b/lldb/utils/test/run-dis.py new file mode 100755 index 00000000000..40089bddb66 --- /dev/null +++ b/lldb/utils/test/run-dis.py @@ -0,0 +1,126 @@ +#!/usr/bin/env python + +""" +Run lldb disassembler on all the binaries specified by a combination of root dir +and path pattern. +""" + +import os, sys, subprocess +import re +from optparse import OptionParser + +# The directory of this Python script as well as the lldb-disasm.py workhorse. +scriptPath = None + +# The root directory for the SDK symbols. +root_dir = None + +# The regular expression pattern to match the desired pathname to the binaries. +path_pattern = None + +# And the re-compiled regular expression object. +path_regexp = None + +# If specified, number of symbols to disassemble for each qualified binary. +num_symbols = -1 + +# Command template of the invocation of lldb disassembler. +template = './lldb-disasm.py -C "platform select remote-ios" -o "-n" -q -e %s -n %s' + +# Regular expression for detecting file output for Mach-o binary. +mach_o = re.compile('\sMach-O.+binary') +def isbinary(path): + file_output = subprocess.Popen(["file", path], + stdout=subprocess.PIPE).stdout.read() + return (mach_o.search(file_output) is not None) + +def visit(suffix, dir, names): + """Look for matched file and invoke lldb disassembly on it.""" + global scriptPath + global root_dir + global path_pattern + global path_regexp + global num_symbols + + old_dir = os.getcwd() + for name in names: + path = os.path.join(dir, name) + if os.path.isdir(path): + continue + if name.endswith(".h"): + continue + + replaced_path = path.replace(root_dir, "", 1) + if not path_regexp.search(replaced_path): + continue + if suffix and not name.endswith(suffix): + continue + if not isbinary(path): + continue + + os.chdir(scriptPath) + command = template % (path, num_symbols if num_symbols > 0 else 1000) + print "Running %s" % (command) + os.system(command) + + os.chdir(old_dir) + +def main(): + """Read the root dir and the path spec, invoke lldb-disasm.py on the file.""" + global scriptPath + global root_dir + global path_pattern + global path_regexp + global num_symbols + + scriptPath = sys.path[0] + + parser = OptionParser(usage="""\ +Run lldb disassembler on all the binaries specified by a combination of root dir +and path pattern. +""") + parser.add_option('-r', '--root-dir', + type='string', action='store', + dest='root_dir', + help='Mandatory: the root directory for the SDK symbols.') + parser.add_option('-p', '--path-pattern', + type='string', action='store', + dest='path_pattern', + help='Mandatory: regular expression pattern for the desired binaries.') + parser.add_option('-s', '--suffix', + type='string', action='store', default=None, + dest='suffix', + help='Specify the suffix of the binaries to look for.') + parser.add_option('-n', '--num-symbols', + type='int', action='store', default=-1, + dest='num_symbols', + help="""The number of symbols to disassemble, if specified.""") + + + opts, args = parser.parse_args() + if not opts.root_dir or not opts.path_pattern: + parser.print_help() + sys.exit(1) + + # Sanity check the root directory. + root_dir = opts.root_dir + root_dir = os.path.abspath(root_dir) + if not os.path.isdir(root_dir): + parser.print_help() + sys.exit(1) + + path_pattern = opts.path_pattern + path_regexp = re.compile(path_pattern) + suffix = opts.suffix + num_symbols = opts.num_symbols + + print "Root directory for SDK symbols:", root_dir + print "Regular expression for the binaries:", path_pattern + print "Suffix of the binaries to look for:", suffix + print "num of symbols to disassemble:", num_symbols + + os.path.walk(root_dir, visit, suffix) + + +if __name__ == '__main__': + main() |