[PowerPC] Collect some CallLowering arguments into a struct. [NFC]
[llvm-project.git] / lldb / utils / test / lldb-disasm.py
blob339e8e7cabae4fdc068feba3053f6866bab9252b
1 #!/usr/bin/env python
3 """
4 Run lldb to disassemble all the available functions for an executable image.
6 """
8 from __future__ import print_function
10 import os
11 import re
12 import sys
13 from optparse import OptionParser
16 def setupSysPath():
17 """
18 Add LLDB.framework/Resources/Python and the test dir to the sys.path.
19 """
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.")
24 sys.exit(-1)
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']
35 dbg = ['Debug']
36 rel = ['Release']
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))
53 lldbPath = None
54 if os.path.isfile(os.path.join(dbgPath, 'lldb.py')):
55 lldbPath = dbgPath
56 elif os.path.isfile(os.path.join(dbgPath2, 'lldb.py')):
57 lldbPath = dbgPath2
58 elif os.path.isfile(os.path.join(relPath, 'lldb.py')):
59 lldbPath = relPath
60 elif os.path.isfile(os.path.join(relPath2, 'lldb.py')):
61 lldbPath = relPath2
62 elif os.path.isfile(os.path.join(baiPath, 'lldb.py')):
63 lldbPath = baiPath
64 elif os.path.isfile(os.path.join(baiPath2, 'lldb.py')):
65 lldbPath = baiPath2
67 if not lldbPath:
68 print('This script requires lldb.py to be in either ' + dbgPath + ',', end=' ')
69 print(relPath + ', or ' + baiPath)
70 sys.exit(-1)
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):
78 if echo:
79 print("run command:", cmd)
80 ci.HandleCommand(cmd, res)
81 if res.Succeeded():
82 if echo:
83 print("run_command output:", res.GetOutput())
84 else:
85 if echo:
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,
92 re_symbol_pattern,
93 quiet_disassembly):
94 import lldb
95 import atexit
96 import re
98 # Create the debugger instance now.
99 dbg = lldb.SBDebugger.Create()
100 if not dbg:
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.
107 dbg.SetAsync(False)
109 # Get the command interpreter from the debugger.
110 ci = dbg.GetCommandInterpreter()
111 if not ci:
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
118 # command.
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)
125 # Create a target.
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.
137 if symbols:
138 for i in range(len(symbols)):
139 if verbose:
140 print("symbol:", symbols[i])
141 yield symbols[i]
142 else:
143 limited = True if num != -1 else False
144 if limited:
145 count = 0
146 if re_symbol_pattern:
147 pattern = re.compile(re_symbol_pattern)
148 stream = lldb.SBStream()
149 for m in target.module_iter():
150 if verbose:
151 print("module:", m)
152 for s in m:
153 if limited and count >= num:
154 return
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
158 # symbol.
159 if not pattern.match(s.GetName()):
160 continue
162 # If we come here, we're ready to disassemble the symbol.
163 if verbose:
164 print("symbol:", s.GetName())
165 if IsCodeType(s):
166 if limited:
167 count = count + 1
168 if verbose:
169 print("returning symbol:", s.GetName())
170 yield s.GetName()
171 if verbose:
172 print("start address:", s.GetStartAddress())
173 print("end address:", s.GetEndAddress())
174 s.GetDescription(stream)
175 print("symbol description:", stream.GetData())
176 stream.Clear()
178 # Disassembly time.
179 for symbol in symbol_iter(
180 num_symbols,
181 symbols_to_disassemble,
182 re_symbol_pattern,
183 target,
184 not quiet_disassembly):
185 cmd = "disassemble %s '%s'" % (disassemble_options, symbol)
186 run_command(ci, cmd, res, not quiet_disassembly)
189 def main():
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]
193 sys.path.append(
194 os.path.join(
195 scriptPath,
196 os.pardir,
197 os.pardir,
198 'test',
199 'pexpect-2.4'))
201 parser = OptionParser(usage="""\
202 Run lldb to disassemble all the available functions for an executable image.
204 Usage: %prog [options]
205 """)
206 parser.add_option(
207 '-C',
208 '--lldb-command',
209 type='string',
210 action='append',
211 metavar='COMMAND',
212 default=[],
213 dest='lldb_commands',
214 help='Command(s) lldb executes after starting up (can be empty)')
215 parser.add_option(
216 '-e',
217 '--executable',
218 type='string',
219 action='store',
220 dest='executable',
221 help="""Mandatory: the executable to do disassembly on.""")
222 parser.add_option(
223 '-o',
224 '--options',
225 type='string',
226 action='store',
227 dest='disassemble_options',
228 help="""Mandatory: the options passed to lldb's 'disassemble' command.""")
229 parser.add_option(
230 '-q',
231 '--quiet-disassembly',
232 action='store_true',
233 default=False,
234 dest='quiet_disassembly',
235 help="""The symbol(s) to invoke lldb's 'disassemble' command on, if specified.""")
236 parser.add_option(
237 '-n',
238 '--num-symbols',
239 type='int',
240 action='store',
241 default=-1,
242 dest='num_symbols',
243 help="""The number of symbols to disassemble, if specified.""")
244 parser.add_option(
245 '-p',
246 '--symbol_pattern',
247 type='string',
248 action='store',
249 dest='re_symbol_pattern',
250 help="""The regular expression of symbols to invoke lldb's 'disassemble' command.""")
251 parser.add_option(
252 '-s',
253 '--symbol',
254 type='string',
255 action='append',
256 metavar='SYMBOL',
257 default=[],
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:
266 parser.print_help()
267 sys.exit(1)
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)
286 setupSysPath()
287 do_lldb_disassembly(lldb_commands, executable, disassemble_options,
288 num_symbols,
289 symbols_to_disassemble,
290 re_symbol_pattern,
291 quiet_disassembly)
293 if __name__ == '__main__':
294 main()