4 Run lldb to disassemble all the available functions for an executable image.
11 from optparse import OptionParser
16 Add LLDB.framework/Resources/Python and the test dir to the sys.path.
18 # Get the directory containing the current script.
19 scriptPath = sys.path[0]
20 if not scriptPath.endswith(os.path.join('utils', 'test')):
21 print "This script expects to reside in lldb's utils/test directory."
24 # This is our base name component.
25 base = os.path.abspath(os.path.join(scriptPath, os.pardir, os.pardir))
27 # This is for the goodies in the test directory under base.
28 sys.path.append(os.path.join(base, 'test'))
30 # These are for xcode build directories.
31 xcode3_build_dir = ['build']
32 xcode4_build_dir = ['build', 'lldb', 'Build', 'Products']
35 bai = ['BuildAndIntegration']
36 python_resource_dir = ['LLDB.framework', 'Resources', 'Python']
38 dbgPath = os.path.join(
39 base, *(xcode3_build_dir + dbg + python_resource_dir))
40 dbgPath2 = os.path.join(
41 base, *(xcode4_build_dir + dbg + python_resource_dir))
42 relPath = os.path.join(
43 base, *(xcode3_build_dir + rel + python_resource_dir))
44 relPath2 = os.path.join(
45 base, *(xcode4_build_dir + rel + python_resource_dir))
46 baiPath = os.path.join(
47 base, *(xcode3_build_dir + bai + python_resource_dir))
48 baiPath2 = os.path.join(
49 base, *(xcode4_build_dir + bai + python_resource_dir))
52 if os.path.isfile(os.path.join(dbgPath, 'lldb.py')):
54 elif os.path.isfile(os.path.join(dbgPath2, 'lldb.py')):
56 elif os.path.isfile(os.path.join(relPath, 'lldb.py')):
58 elif os.path.isfile(os.path.join(relPath2, 'lldb.py')):
60 elif os.path.isfile(os.path.join(baiPath, 'lldb.py')):
62 elif os.path.isfile(os.path.join(baiPath2, 'lldb.py')):
66 print 'This script requires lldb.py to be in either ' + dbgPath + ',',
67 print relPath + ', or ' + baiPath
70 # This is to locate the lldb.py module. Insert it right after sys.path[0].
71 sys.path[1:1] = [lldbPath]
72 # print "sys.path:", sys.path
75 def run_command(ci, cmd, res, echo=True):
77 print "run command:", cmd
78 ci.HandleCommand(cmd, res)
81 print "run_command output:", res.GetOutput()
84 print "run command failed!"
85 print "run_command error:", res.GetError()
88 def do_lldb_disassembly(lldb_commands, exe, disassemble_options, num_symbols,
89 symbols_to_disassemble,
96 # Create the debugger instance now.
97 dbg = lldb.SBDebugger.Create()
99 raise Exception('Invalid debugger instance')
101 # Register an exit callback.
102 atexit.register(lambda: lldb.SBDebugger.Terminate())
104 # We want our debugger to be synchronous.
107 # Get the command interpreter from the debugger.
108 ci = dbg.GetCommandInterpreter()
110 raise Exception('Could not get the command interpreter')
112 # And the associated result object.
113 res = lldb.SBCommandReturnObject()
115 # See if there any extra command(s) to execute before we issue the file
117 for cmd in lldb_commands:
118 run_command(ci, cmd, res, not quiet_disassembly)
120 # Now issue the file command.
121 run_command(ci, 'file %s' % exe, res, not quiet_disassembly)
124 #target = dbg.CreateTarget(exe)
125 target = dbg.GetSelectedTarget()
126 stream = lldb.SBStream()
128 def IsCodeType(symbol):
129 """Check whether an SBSymbol represents code."""
130 return symbol.GetType() == lldb.eSymbolTypeCode
132 # Define a generator for the symbols to disassemble.
133 def symbol_iter(num, symbols, re_symbol_pattern, target, verbose):
134 # If we specify the symbols to disassemble, ignore symbol table dump.
136 for i in range(len(symbols)):
138 print "symbol:", symbols[i]
141 limited = True if num != -1 else False
144 if re_symbol_pattern:
145 pattern = re.compile(re_symbol_pattern)
146 stream = lldb.SBStream()
147 for m in target.module_iter():
151 if limited and count >= num:
153 # If a regexp symbol pattern is supplied, consult it.
154 if re_symbol_pattern:
155 # If the pattern does not match, look for the next
157 if not pattern.match(s.GetName()):
160 # If we come here, we're ready to disassemble the symbol.
162 print "symbol:", s.GetName()
167 print "returning symbol:", s.GetName()
170 print "start address:", s.GetStartAddress()
171 print "end address:", s.GetEndAddress()
172 s.GetDescription(stream)
173 print "symbol description:", stream.GetData()
177 for symbol in symbol_iter(
179 symbols_to_disassemble,
182 not quiet_disassembly):
183 cmd = "disassemble %s '%s'" % (disassemble_options, symbol)
184 run_command(ci, cmd, res, not quiet_disassembly)
188 # This is to set up the Python path to include the pexpect-2.4 dir.
189 # Remember to update this when/if things change.
190 scriptPath = sys.path[0]
199 parser = OptionParser(usage="""\
200 Run lldb to disassemble all the available functions for an executable image.
202 Usage: %prog [options]
211 dest='lldb_commands',
212 help='Command(s) lldb executes after starting up (can be empty)')
219 help="""Mandatory: the executable to do disassembly on.""")
225 dest='disassemble_options',
226 help="""Mandatory: the options passed to lldb's 'disassemble' command.""")
229 '--quiet-disassembly',
232 dest='quiet_disassembly',
233 help="""The symbol(s) to invoke lldb's 'disassemble' command on, if specified.""")
241 help="""The number of symbols to disassemble, if specified.""")
247 dest='re_symbol_pattern',
248 help="""The regular expression of symbols to invoke lldb's 'disassemble' command.""")
256 dest='symbols_to_disassemble',
257 help="""The symbol(s) to invoke lldb's 'disassemble' command on, if specified.""")
259 opts, args = parser.parse_args()
261 lldb_commands = opts.lldb_commands
263 if not opts.executable or not opts.disassemble_options:
267 executable = opts.executable
268 disassemble_options = opts.disassemble_options
269 quiet_disassembly = opts.quiet_disassembly
270 num_symbols = opts.num_symbols
271 symbols_to_disassemble = opts.symbols_to_disassemble
272 re_symbol_pattern = opts.re_symbol_pattern
274 # We have parsed the options.
275 if not quiet_disassembly:
276 print "lldb commands:", lldb_commands
277 print "executable:", executable
278 print "disassemble options:", disassemble_options
279 print "quiet disassembly output:", quiet_disassembly
280 print "num of symbols to disassemble:", num_symbols
281 print "symbols to disassemble:", symbols_to_disassemble
282 print "regular expression of symbols to disassemble:", re_symbol_pattern
285 do_lldb_disassembly(lldb_commands, executable, disassemble_options,
287 symbols_to_disassemble,
291 if __name__ == '__main__':