Revert "[clang-repl] Implement partial translation units and error recovery."
[llvm-project.git] / lldb / examples / python / memory.py
blob26703462c2cde93ee7f6ed80a9429a62cb1884d9
1 #!/usr/bin/env python
3 #----------------------------------------------------------------------
4 # Be sure to add the python path that points to the LLDB shared library.
6 # # To use this in the embedded python interpreter using "lldb" just
7 # import it with the full path using the "command script import"
8 # command
9 # (lldb) command script import /path/to/cmdtemplate.py
10 #----------------------------------------------------------------------
12 from __future__ import print_function
14 import platform
15 import os
16 import re
17 import sys
18 import subprocess
20 try:
21 # Just try for LLDB in case PYTHONPATH is already correctly setup
22 import lldb
23 except ImportError:
24 lldb_python_dirs = list()
25 # lldb is not in the PYTHONPATH, try some defaults for the current platform
26 platform_system = platform.system()
27 if platform_system == 'Darwin':
28 # On Darwin, try the currently selected Xcode directory
29 xcode_dir = subprocess.check_output("xcode-select --print-path", shell=True)
30 if xcode_dir:
31 lldb_python_dirs.append(
32 os.path.realpath(
33 xcode_dir +
34 '/../SharedFrameworks/LLDB.framework/Resources/Python'))
35 lldb_python_dirs.append(
36 xcode_dir + '/Library/PrivateFrameworks/LLDB.framework/Resources/Python')
37 lldb_python_dirs.append(
38 '/System/Library/PrivateFrameworks/LLDB.framework/Resources/Python')
39 success = False
40 for lldb_python_dir in lldb_python_dirs:
41 if os.path.exists(lldb_python_dir):
42 if not (sys.path.__contains__(lldb_python_dir)):
43 sys.path.append(lldb_python_dir)
44 try:
45 import lldb
46 except ImportError:
47 pass
48 else:
49 print('imported lldb from: "%s"' % (lldb_python_dir))
50 success = True
51 break
52 if not success:
53 print("error: couldn't locate the 'lldb' module, please set PYTHONPATH correctly")
54 sys.exit(1)
56 import optparse
57 import shlex
58 import string
59 import struct
60 import time
63 def append_data_callback(option, opt_str, value, parser):
64 if opt_str == "--uint8":
65 int8 = int(value, 0)
66 parser.values.data += struct.pack('1B', int8)
67 if opt_str == "--uint16":
68 int16 = int(value, 0)
69 parser.values.data += struct.pack('1H', int16)
70 if opt_str == "--uint32":
71 int32 = int(value, 0)
72 parser.values.data += struct.pack('1I', int32)
73 if opt_str == "--uint64":
74 int64 = int(value, 0)
75 parser.values.data += struct.pack('1Q', int64)
76 if opt_str == "--int8":
77 int8 = int(value, 0)
78 parser.values.data += struct.pack('1b', int8)
79 if opt_str == "--int16":
80 int16 = int(value, 0)
81 parser.values.data += struct.pack('1h', int16)
82 if opt_str == "--int32":
83 int32 = int(value, 0)
84 parser.values.data += struct.pack('1i', int32)
85 if opt_str == "--int64":
86 int64 = int(value, 0)
87 parser.values.data += struct.pack('1q', int64)
90 def create_memfind_options():
91 usage = "usage: %prog [options] STARTADDR [ENDADDR]"
92 description = '''This command can find data in a specified address range.
93 Options are used to specify the data that is to be looked for and the options
94 can be specified multiple times to look for longer streams of data.
95 '''
96 parser = optparse.OptionParser(
97 description=description,
98 prog='memfind',
99 usage=usage)
100 parser.add_option(
101 '-s',
102 '--size',
103 type='int',
104 metavar='BYTESIZE',
105 dest='size',
106 help='Specify the byte size to search.',
107 default=0)
108 parser.add_option(
109 '--int8',
110 action="callback",
111 callback=append_data_callback,
112 type='string',
113 metavar='INT',
114 dest='data',
115 help='Specify a 8 bit signed integer value to search for in memory.',
116 default='')
117 parser.add_option(
118 '--int16',
119 action="callback",
120 callback=append_data_callback,
121 type='string',
122 metavar='INT',
123 dest='data',
124 help='Specify a 16 bit signed integer value to search for in memory.',
125 default='')
126 parser.add_option(
127 '--int32',
128 action="callback",
129 callback=append_data_callback,
130 type='string',
131 metavar='INT',
132 dest='data',
133 help='Specify a 32 bit signed integer value to search for in memory.',
134 default='')
135 parser.add_option(
136 '--int64',
137 action="callback",
138 callback=append_data_callback,
139 type='string',
140 metavar='INT',
141 dest='data',
142 help='Specify a 64 bit signed integer value to search for in memory.',
143 default='')
144 parser.add_option(
145 '--uint8',
146 action="callback",
147 callback=append_data_callback,
148 type='string',
149 metavar='INT',
150 dest='data',
151 help='Specify a 8 bit unsigned integer value to search for in memory.',
152 default='')
153 parser.add_option(
154 '--uint16',
155 action="callback",
156 callback=append_data_callback,
157 type='string',
158 metavar='INT',
159 dest='data',
160 help='Specify a 16 bit unsigned integer value to search for in memory.',
161 default='')
162 parser.add_option(
163 '--uint32',
164 action="callback",
165 callback=append_data_callback,
166 type='string',
167 metavar='INT',
168 dest='data',
169 help='Specify a 32 bit unsigned integer value to search for in memory.',
170 default='')
171 parser.add_option(
172 '--uint64',
173 action="callback",
174 callback=append_data_callback,
175 type='string',
176 metavar='INT',
177 dest='data',
178 help='Specify a 64 bit unsigned integer value to search for in memory.',
179 default='')
180 return parser
183 def memfind_command(debugger, command, result, dict):
184 # Use the Shell Lexer to properly parse up command options just like a
185 # shell would
186 command_args = shlex.split(command)
187 parser = create_memfind_options()
188 (options, args) = parser.parse_args(command_args)
189 # try:
190 # (options, args) = parser.parse_args(command_args)
191 # except:
192 # # if you don't handle exceptions, passing an incorrect argument to the OptionParser will cause LLDB to exit
193 # # (courtesy of OptParse dealing with argument errors by throwing SystemExit)
194 # result.SetStatus (lldb.eReturnStatusFailed)
195 # print >>result, "error: option parsing failed" # returning a string is the same as returning an error whose description is the string
196 # return
197 memfind(debugger.GetSelectedTarget(), options, args, result)
200 def print_error(str, show_usage, result):
201 print(str, file=result)
202 if show_usage:
203 print(create_memfind_options().format_help(), file=result)
206 def memfind(target, options, args, result):
207 num_args = len(args)
208 start_addr = 0
209 if num_args == 1:
210 if options.size > 0:
211 print_error(
212 "error: --size must be specified if there is no ENDADDR argument",
213 True,
214 result)
215 return
216 start_addr = int(args[0], 0)
217 elif num_args == 2:
218 if options.size != 0:
219 print_error(
220 "error: --size can't be specified with an ENDADDR argument",
221 True,
222 result)
223 return
224 start_addr = int(args[0], 0)
225 end_addr = int(args[1], 0)
226 if start_addr >= end_addr:
227 print_error(
228 "error: inavlid memory range [%#x - %#x)" %
229 (start_addr, end_addr), True, result)
230 return
231 options.size = end_addr - start_addr
232 else:
233 print_error("error: memfind takes 1 or 2 arguments", True, result)
234 return
236 if not options.data:
237 print('error: no data specified to search for', file=result)
238 return
240 if not target:
241 print('error: invalid target', file=result)
242 return
243 process = target.process
244 if not process:
245 print('error: invalid process', file=result)
246 return
248 error = lldb.SBError()
249 bytes = process.ReadMemory(start_addr, options.size, error)
250 if error.Success():
251 num_matches = 0
252 print("Searching memory range [%#x - %#x) for" % (
253 start_addr, end_addr), end=' ', file=result)
254 for byte in options.data:
255 print('%2.2x' % ord(byte), end=' ', file=result)
256 print(file=result)
258 match_index = string.find(bytes, options.data)
259 while match_index != -1:
260 num_matches = num_matches + 1
261 print('%#x: %#x + %u' % (start_addr +
262 match_index, start_addr, match_index), file=result)
263 match_index = string.find(bytes, options.data, match_index + 1)
265 if num_matches == 0:
266 print("error: no matches found", file=result)
267 else:
268 print('error: %s' % (error.GetCString()), file=result)
271 if __name__ == '__main__':
272 print('error: this script is designed to be used within the embedded script interpreter in LLDB')
273 elif getattr(lldb, 'debugger', None):
274 memfind_command.__doc__ = create_memfind_options().format_help()
275 lldb.debugger.HandleCommand(
276 'command script add -f memory.memfind_command memfind')
277 print('"memfind" command installed, use the "--help" option for detailed help')