4 Run lldb to disassemble all the available functions for an executable image.
8 from __future__
import print_function
13 from optparse
import OptionParser
18 Add LLDB.framework/Resources/Python and the test dir to the sys.path.
20 # Get the directory containing the current script.
21 scriptPath
= sys
.path
[0]
22 if not scriptPath
.endswith(os
.path
.join('utils', 'test')):
23 print("This script expects to reside in lldb's utils/test directory.")
26 # This is our base name component.
27 base
= os
.path
.abspath(os
.path
.join(scriptPath
, os
.pardir
, os
.pardir
))
29 # This is for the goodies in the test directory under base.
30 sys
.path
.append(os
.path
.join(base
, 'test'))
32 # These are for xcode build directories.
33 xcode3_build_dir
= ['build']
34 xcode4_build_dir
= ['build', 'lldb', 'Build', 'Products']
37 bai
= ['BuildAndIntegration']
38 python_resource_dir
= ['LLDB.framework', 'Resources', 'Python']
40 dbgPath
= os
.path
.join(
41 base
, *(xcode3_build_dir
+ dbg
+ python_resource_dir
))
42 dbgPath2
= os
.path
.join(
43 base
, *(xcode4_build_dir
+ dbg
+ python_resource_dir
))
44 relPath
= os
.path
.join(
45 base
, *(xcode3_build_dir
+ rel
+ python_resource_dir
))
46 relPath2
= os
.path
.join(
47 base
, *(xcode4_build_dir
+ rel
+ python_resource_dir
))
48 baiPath
= os
.path
.join(
49 base
, *(xcode3_build_dir
+ bai
+ python_resource_dir
))
50 baiPath2
= os
.path
.join(
51 base
, *(xcode4_build_dir
+ bai
+ python_resource_dir
))
54 if os
.path
.isfile(os
.path
.join(dbgPath
, 'lldb.py')):
56 elif os
.path
.isfile(os
.path
.join(dbgPath2
, 'lldb.py')):
58 elif os
.path
.isfile(os
.path
.join(relPath
, 'lldb.py')):
60 elif os
.path
.isfile(os
.path
.join(relPath2
, 'lldb.py')):
62 elif os
.path
.isfile(os
.path
.join(baiPath
, 'lldb.py')):
64 elif os
.path
.isfile(os
.path
.join(baiPath2
, 'lldb.py')):
68 print('This script requires lldb.py to be in either ' + dbgPath
+ ',', end
=' ')
69 print(relPath
+ ', or ' + baiPath
)
72 # This is to locate the lldb.py module. Insert it right after sys.path[0].
73 sys
.path
[1:1] = [lldbPath
]
74 # print "sys.path:", sys.path
77 def run_command(ci
, cmd
, res
, echo
=True):
79 print("run command:", cmd
)
80 ci
.HandleCommand(cmd
, res
)
83 print("run_command output:", res
.GetOutput())
86 print("run command failed!")
87 print("run_command error:", res
.GetError())
90 def do_lldb_disassembly(lldb_commands
, exe
, disassemble_options
, num_symbols
,
91 symbols_to_disassemble
,
98 # Create the debugger instance now.
99 dbg
= lldb
.SBDebugger
.Create()
101 raise Exception('Invalid debugger instance')
103 # Register an exit callback.
104 atexit
.register(lambda: lldb
.SBDebugger
.Terminate())
106 # We want our debugger to be synchronous.
109 # Get the command interpreter from the debugger.
110 ci
= dbg
.GetCommandInterpreter()
112 raise Exception('Could not get the command interpreter')
114 # And the associated result object.
115 res
= lldb
.SBCommandReturnObject()
117 # See if there any extra command(s) to execute before we issue the file
119 for cmd
in lldb_commands
:
120 run_command(ci
, cmd
, res
, not quiet_disassembly
)
122 # Now issue the file command.
123 run_command(ci
, 'file %s' % exe
, res
, not quiet_disassembly
)
126 #target = dbg.CreateTarget(exe)
127 target
= dbg
.GetSelectedTarget()
128 stream
= lldb
.SBStream()
130 def IsCodeType(symbol
):
131 """Check whether an SBSymbol represents code."""
132 return symbol
.GetType() == lldb
.eSymbolTypeCode
134 # Define a generator for the symbols to disassemble.
135 def symbol_iter(num
, symbols
, re_symbol_pattern
, target
, verbose
):
136 # If we specify the symbols to disassemble, ignore symbol table dump.
138 for i
in range(len(symbols
)):
140 print("symbol:", symbols
[i
])
143 limited
= True if num
!= -1 else False
146 if re_symbol_pattern
:
147 pattern
= re
.compile(re_symbol_pattern
)
148 stream
= lldb
.SBStream()
149 for m
in target
.module_iter():
153 if limited
and count
>= num
:
155 # If a regexp symbol pattern is supplied, consult it.
156 if re_symbol_pattern
:
157 # If the pattern does not match, look for the next
159 if not pattern
.match(s
.GetName()):
162 # If we come here, we're ready to disassemble the symbol.
164 print("symbol:", s
.GetName())
169 print("returning symbol:", s
.GetName())
172 print("start address:", s
.GetStartAddress())
173 print("end address:", s
.GetEndAddress())
174 s
.GetDescription(stream
)
175 print("symbol description:", stream
.GetData())
179 for symbol
in symbol_iter(
181 symbols_to_disassemble
,
184 not quiet_disassembly
):
185 cmd
= "disassemble %s '%s'" % (disassemble_options
, symbol
)
186 run_command(ci
, cmd
, res
, not quiet_disassembly
)
190 # This is to set up the Python path to include the pexpect-2.4 dir.
191 # Remember to update this when/if things change.
192 scriptPath
= sys
.path
[0]
201 parser
= OptionParser(usage
="""\
202 Run lldb to disassemble all the available functions for an executable image.
204 Usage: %prog [options]
213 dest
='lldb_commands',
214 help='Command(s) lldb executes after starting up (can be empty)')
221 help="""Mandatory: the executable to do disassembly on.""")
227 dest
='disassemble_options',
228 help="""Mandatory: the options passed to lldb's 'disassemble' command.""")
231 '--quiet-disassembly',
234 dest
='quiet_disassembly',
235 help="""The symbol(s) to invoke lldb's 'disassemble' command on, if specified.""")
243 help="""The number of symbols to disassemble, if specified.""")
249 dest
='re_symbol_pattern',
250 help="""The regular expression of symbols to invoke lldb's 'disassemble' command.""")
258 dest
='symbols_to_disassemble',
259 help="""The symbol(s) to invoke lldb's 'disassemble' command on, if specified.""")
261 opts
, args
= parser
.parse_args()
263 lldb_commands
= opts
.lldb_commands
265 if not opts
.executable
or not opts
.disassemble_options
:
269 executable
= opts
.executable
270 disassemble_options
= opts
.disassemble_options
271 quiet_disassembly
= opts
.quiet_disassembly
272 num_symbols
= opts
.num_symbols
273 symbols_to_disassemble
= opts
.symbols_to_disassemble
274 re_symbol_pattern
= opts
.re_symbol_pattern
276 # We have parsed the options.
277 if not quiet_disassembly
:
278 print("lldb commands:", lldb_commands
)
279 print("executable:", executable
)
280 print("disassemble options:", disassemble_options
)
281 print("quiet disassembly output:", quiet_disassembly
)
282 print("num of symbols to disassemble:", num_symbols
)
283 print("symbols to disassemble:", symbols_to_disassemble
)
284 print("regular expression of symbols to disassemble:", re_symbol_pattern
)
287 do_lldb_disassembly(lldb_commands
, executable
, disassemble_options
,
289 symbols_to_disassemble
,
293 if __name__
== '__main__':