blob: 0caca30a416d9a1608bde695bffa7ca2bc4b782d [file] [log] [blame]
Johnny Chenafd19042011-03-28 22:40:32 +00001#!/usr/bin/env python
2
3"""
4Run lldb to disassemble all the available functions for an executable image.
5
6"""
7
8import os
9import sys
10from optparse import OptionParser
11
12def setupSysPath():
13 """
14 Add LLDB.framework/Resources/Python to the search paths for modules.
15 """
16 # Get the directory containing the current script.
17 scriptPath = sys.path[0]
18 if not scriptPath.endswith(os.path.join('utils', 'test')):
19 print "This script expects to reside in lldb's utils/test directory."
20 sys.exit(-1)
21
22 # This is our base name component.
23 base = os.path.abspath(os.path.join(scriptPath, os.pardir, os.pardir))
24
25 # This is for the goodies in the test directory under base.
26 sys.path.append(os.path.join(base,'test'))
27
28 # These are for xcode build directories.
29 xcode3_build_dir = ['build']
30 xcode4_build_dir = ['build', 'lldb', 'Build', 'Products']
31 dbg = ['Debug']
32 rel = ['Release']
33 bai = ['BuildAndIntegration']
34 python_resource_dir = ['LLDB.framework', 'Resources', 'Python']
35
36 dbgPath = os.path.join(base, *(xcode3_build_dir + dbg + python_resource_dir))
37 dbgPath2 = os.path.join(base, *(xcode4_build_dir + dbg + python_resource_dir))
38 relPath = os.path.join(base, *(xcode3_build_dir + rel + python_resource_dir))
39 relPath2 = os.path.join(base, *(xcode4_build_dir + rel + python_resource_dir))
40 baiPath = os.path.join(base, *(xcode3_build_dir + bai + python_resource_dir))
41 baiPath2 = os.path.join(base, *(xcode4_build_dir + bai + python_resource_dir))
42
43 lldbPath = None
44 if os.path.isfile(os.path.join(dbgPath, 'lldb.py')):
45 lldbPath = dbgPath
46 elif os.path.isfile(os.path.join(dbgPath2, 'lldb.py')):
47 lldbPath = dbgPath2
48 elif os.path.isfile(os.path.join(relPath, 'lldb.py')):
49 lldbPath = relPath
50 elif os.path.isfile(os.path.join(relPath2, 'lldb.py')):
51 lldbPath = relPath2
52 elif os.path.isfile(os.path.join(baiPath, 'lldb.py')):
53 lldbPath = baiPath
54 elif os.path.isfile(os.path.join(baiPath2, 'lldb.py')):
55 lldbPath = baiPath2
56
57 if not lldbPath:
58 print 'This script requires lldb.py to be in either ' + dbgPath + ',',
59 print relPath + ', or ' + baiPath
60 sys.exit(-1)
61
62 # This is to locate the lldb.py module. Insert it right after sys.path[0].
63 sys.path[1:1] = [lldbPath]
64 print "sys.path:", sys.path
65
66
67def run_command(ci, cmd, res):
68 print "run command:", cmd
69 ci.HandleCommand(cmd, res)
70 if res.Succeeded():
71 print "output:", res.GetOutput()
72 else:
73 print "run command failed!"
74 print "error:", res.GetError()
75
76def do_lldb_disassembly(lldb_commands, lldb_options, exe):
77 import lldb, lldbutil, atexit
78
79 # Create the debugger instance now.
80 dbg = lldb.SBDebugger.Create()
81 if not dbg.IsValid():
82 raise Exception('Invalid debugger instance')
83
84 # Register an exit callback.
85 atexit.register(lambda: lldb.SBDebugger.Terminate())
86
87 # We want our debugger to be synchronous.
88 dbg.SetAsync(False)
89
90 # Get the command interpreter from the debugger.
91 ci = dbg.GetCommandInterpreter()
92 if not ci:
93 raise Exception('Could not get the command interpreter')
94
95 # And the associated result object.
96 res = lldb.SBCommandReturnObject()
97
98 # See if there any extra command(s) to execute before we issue the file command.
99 for cmd in lldb_commands:
100 run_command(ci, cmd, res)
101
102 # Now issue the file command.
103 run_command(ci, 'file %s' % exe, res)
104
105 # Send the 'image dump symtab' command.
106 run_command(ci, 'image dump symtab', res)
107
108def main():
109 # This is to set up the Python path to include the pexpect-2.4 dir.
110 # Remember to update this when/if things change.
111 scriptPath = sys.path[0]
112 sys.path.append(os.path.join(scriptPath, os.pardir, os.pardir, 'test', 'pexpect-2.4'))
113
114 parser = OptionParser(usage="""\
115Run lldb to disassemble all the available functions for an executable image.
116
117Usage: %prog [options]
118""")
119 parser.add_option('-C', '--lldb-command',
120 type='string', action='append', metavar='COMMAND',
121 default=[], dest='lldb_commands',
122 help='Command(s) lldb executes after starting up (can be empty)')
123 parser.add_option('-O', '--lldb-options',
124 type='string', action='store',
125 dest='lldb_options',
126 help="""The options passed to 'lldb' command if specified.""")
127 parser.add_option('-e', '--executable',
128 type='string', action='store',
129 dest='executable',
130 help="""The executable to do disassembly on.""")
131
132 opts, args = parser.parse_args()
133
134 lldb_commands = opts.lldb_commands
135 lldb_options = opts.lldb_options
136
137 if not opts.executable:
138 parser.print_help()
139 sys.exit(1)
140 executable = opts.executable
141
142 # We have parsed the options.
143 print "lldb commands:", lldb_commands
144 print "lldb options:", lldb_options
145 print "executable:", executable
146
147 setupSysPath()
148 do_lldb_disassembly(lldb_commands, lldb_options, executable)
149
150if __name__ == '__main__':
151 main()