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