summaryrefslogtreecommitdiff
path: root/examples/python
diff options
context:
space:
mode:
authorDimitry Andric <dim@FreeBSD.org>2019-08-20 18:01:57 +0000
committerDimitry Andric <dim@FreeBSD.org>2019-08-20 18:01:57 +0000
commit88c643b6fec27eec436c8d138fee6346e92337d6 (patch)
tree82cd13b2f3cde1c9e5f79689ba4e6ba67694843f /examples/python
parent94994d372d014ce4c8758b9605d63fae651bd8aa (diff)
Notes
Diffstat (limited to 'examples/python')
-rwxr-xr-xexamples/python/bsd.py564
-rw-r--r--examples/python/cmdtemplate.py147
-rwxr-xr-xexamples/python/crashlog.py1027
-rwxr-xr-xexamples/python/delta.py134
-rw-r--r--examples/python/diagnose_nsstring.py183
-rw-r--r--examples/python/diagnose_unwind.py313
-rwxr-xr-xexamples/python/dict_utils.py62
-rwxr-xr-xexamples/python/disasm-stress-test.py230
-rwxr-xr-xexamples/python/disasm.py126
-rw-r--r--examples/python/disassembly_mode.py48
-rwxr-xr-xexamples/python/file_extract.py226
-rwxr-xr-xexamples/python/gdb_disassemble.py26
-rwxr-xr-xexamples/python/gdbremote.py1630
-rwxr-xr-xexamples/python/globals.py106
-rw-r--r--examples/python/jump.py196
-rw-r--r--examples/python/lldb_module_utils.py191
-rw-r--r--examples/python/lldbtk.py613
-rwxr-xr-xexamples/python/mach_o.py1845
-rwxr-xr-xexamples/python/memory.py276
-rw-r--r--examples/python/operating_system.py231
-rwxr-xr-xexamples/python/performance.py392
-rwxr-xr-xexamples/python/process_events.py417
-rw-r--r--examples/python/pytracer.py360
-rwxr-xr-xexamples/python/sbvalue.py268
-rw-r--r--examples/python/scripted_step.py244
-rw-r--r--examples/python/shadow.py58
-rw-r--r--examples/python/sources.py31
-rwxr-xr-xexamples/python/stacks.py69
-rw-r--r--examples/python/step_and_print.py24
-rwxr-xr-xexamples/python/symbolication.py727
-rwxr-xr-xexamples/python/types.py356
-rw-r--r--examples/python/x86_64_linux_target_definition.py775
-rw-r--r--examples/python/x86_64_qemu_target_definition.py773
-rw-r--r--examples/python/x86_64_target_definition.py778
34 files changed, 0 insertions, 13446 deletions
diff --git a/examples/python/bsd.py b/examples/python/bsd.py
deleted file mode 100755
index 3e9528c65845..000000000000
--- a/examples/python/bsd.py
+++ /dev/null
@@ -1,564 +0,0 @@
-#!/usr/bin/python
-
-import cmd
-import optparse
-import os
-import shlex
-import struct
-import sys
-
-ARMAG = "!<arch>\n"
-SARMAG = 8
-ARFMAG = "`\n"
-AR_EFMT1 = "#1/"
-
-
-def memdump(src, bytes_per_line=16, address=0):
- FILTER = ''.join([(len(repr(chr(x))) == 3) and chr(x) or '.'
- for x in range(256)])
- for i in range(0, len(src), bytes_per_line):
- s = src[i:i+bytes_per_line]
- hex_bytes = ' '.join(["%02x" % (ord(x)) for x in s])
- ascii = s.translate(FILTER)
- print("%#08.8x: %-*s %s" % (address+i, bytes_per_line*3, hex_bytes,
- ascii))
-
-
-class Object(object):
- def __init__(self, file):
- def read_str(file, str_len):
- return file.read(str_len).rstrip('\0 ')
-
- def read_int(file, str_len, base):
- return int(read_str(file, str_len), base)
-
- self.offset = file.tell()
- self.file = file
- self.name = read_str(file, 16)
- self.date = read_int(file, 12, 10)
- self.uid = read_int(file, 6, 10)
- self.gid = read_int(file, 6, 10)
- self.mode = read_int(file, 8, 8)
- self.size = read_int(file, 10, 10)
- if file.read(2) != ARFMAG:
- raise ValueError('invalid BSD object at offset %#08.8x' % (
- self.offset))
- # If we have an extended name read it. Extended names start with
- name_len = 0
- if self.name.startswith(AR_EFMT1):
- name_len = int(self.name[len(AR_EFMT1):], 10)
- self.name = read_str(file, name_len)
- self.obj_offset = file.tell()
- self.obj_size = self.size - name_len
- file.seek(self.obj_size, 1)
-
- def dump(self, f=sys.stdout, flat=True):
- if flat:
- f.write('%#08.8x: %#08.8x %5u %5u %6o %#08.8x %s\n' % (self.offset,
- self.date, self.uid, self.gid, self.mode, self.size,
- self.name))
- else:
- f.write('%#08.8x: \n' % self.offset)
- f.write(' name = "%s"\n' % self.name)
- f.write(' date = %#08.8x\n' % self.date)
- f.write(' uid = %i\n' % self.uid)
- f.write(' gid = %i\n' % self.gid)
- f.write(' mode = %o\n' % self.mode)
- f.write(' size = %#08.8x\n' % (self.size))
- self.file.seek(self.obj_offset, 0)
- first_bytes = self.file.read(4)
- f.write('bytes = ')
- memdump(first_bytes)
-
- def get_bytes(self):
- saved_pos = self.file.tell()
- self.file.seek(self.obj_offset, 0)
- bytes = self.file.read(self.obj_size)
- self.file.seek(saved_pos, 0)
- return bytes
-
- def save(self, path=None, overwrite=False):
- '''
- Save the contents of the object to disk using 'path' argument as
- the path, or save it to the current working directory using the
- object name.
- '''
-
- if path is None:
- path = self.name
- if not overwrite and os.path.exists(path):
- print('error: outfile "%s" already exists' % (path))
- return
- print('Saving "%s" to "%s"...' % (self.name, path))
- with open(path, 'w') as f:
- f.write(self.get_bytes())
-
-
-class StringTable(object):
- def __init__(self, bytes):
- self.bytes = bytes
-
- def get_string(self, offset):
- length = len(self.bytes)
- if offset >= length:
- return None
- return self.bytes[offset:self.bytes.find('\0', offset)]
-
-
-class Archive(object):
- def __init__(self, path):
- self.path = path
- self.file = open(path, 'r')
- self.objects = []
- self.offset_to_object = {}
- if self.file.read(SARMAG) != ARMAG:
- print("error: file isn't a BSD archive")
- while True:
- try:
- self.objects.append(Object(self.file))
- except ValueError:
- break
-
- def get_object_at_offset(self, offset):
- if offset in self.offset_to_object:
- return self.offset_to_object[offset]
- for obj in self.objects:
- if obj.offset == offset:
- self.offset_to_object[offset] = obj
- return obj
- return None
-
- def find(self, name, mtime=None, f=sys.stdout):
- '''
- Find an object(s) by name with optional modification time. There
- can be multple objects with the same name inside and possibly with
- the same modification time within a BSD archive so clients must be
- prepared to get multiple results.
- '''
- matches = []
- for obj in self.objects:
- if obj.name == name and (mtime is None or mtime == obj.date):
- matches.append(obj)
- return matches
-
- @classmethod
- def dump_header(self, f=sys.stdout):
- f.write(' DATE UID GID MODE SIZE NAME\n')
- f.write(' ---------- ----- ----- ------ ---------- '
- '--------------\n')
-
- def get_symdef(self):
- def get_uint32(file):
- '''Extract a uint32_t from the current file position.'''
- v, = struct.unpack('=I', file.read(4))
- return v
-
- for obj in self.objects:
- symdef = []
- if obj.name.startswith("__.SYMDEF"):
- self.file.seek(obj.obj_offset, 0)
- ranlib_byte_size = get_uint32(self.file)
- num_ranlib_structs = ranlib_byte_size/8
- str_offset_pairs = []
- for _ in range(num_ranlib_structs):
- strx = get_uint32(self.file)
- offset = get_uint32(self.file)
- str_offset_pairs.append((strx, offset))
- strtab_len = get_uint32(self.file)
- strtab = StringTable(self.file.read(strtab_len))
- for s in str_offset_pairs:
- symdef.append((strtab.get_string(s[0]), s[1]))
- return symdef
-
- def get_object_dicts(self):
- '''
- Returns an array of object dictionaries that contain they following
- keys:
- 'object': the actual bsd.Object instance
- 'symdefs': an array of symbol names that the object contains
- as found in the "__.SYMDEF" item in the archive
- '''
- symdefs = self.get_symdef()
- symdef_dict = {}
- if symdefs:
- for (name, offset) in symdefs:
- if offset in symdef_dict:
- object_dict = symdef_dict[offset]
- else:
- object_dict = {
- 'object': self.get_object_at_offset(offset),
- 'symdefs': []
- }
- symdef_dict[offset] = object_dict
- object_dict['symdefs'].append(name)
- object_dicts = []
- for offset in sorted(symdef_dict):
- object_dicts.append(symdef_dict[offset])
- return object_dicts
-
- def dump(self, f=sys.stdout, flat=True):
- f.write('%s:\n' % self.path)
- if flat:
- self.dump_header(f=f)
- for obj in self.objects:
- obj.dump(f=f, flat=flat)
-
-class Interactive(cmd.Cmd):
- '''Interactive prompt for exploring contents of BSD archive files, type
- "help" to see a list of supported commands.'''
- image_option_parser = None
-
- def __init__(self, archives):
- cmd.Cmd.__init__(self)
- self.use_rawinput = False
- self.intro = ('Interactive BSD archive prompt, type "help" to see a '
- 'list of supported commands.')
- self.archives = archives
- self.prompt = '% '
-
- def default(self, line):
- '''Catch all for unknown command, which will exit the interpreter.'''
- print("unknown command: %s" % line)
- return True
-
- def do_q(self, line):
- '''Quit command'''
- return True
-
- def do_quit(self, line):
- '''Quit command'''
- return True
-
- def do_extract(self, line):
- args = shlex.split(line)
- if args:
- extracted = False
- for object_name in args:
- for archive in self.archives:
- matches = archive.find(object_name)
- if matches:
- for object in matches:
- object.save(overwrite=False)
- extracted = True
- if not extracted:
- print('error: no object matches "%s" in any archives' % (
- object_name))
- else:
- print('error: must specify the name of an object to extract')
-
- def do_ls(self, line):
- args = shlex.split(line)
- if args:
- for object_name in args:
- for archive in self.archives:
- matches = archive.find(object_name)
- if matches:
- for object in matches:
- object.dump(flat=False)
- else:
- print('error: no object matches "%s" in "%s"' % (
- object_name, archive.path))
- else:
- for archive in self.archives:
- archive.dump(flat=True)
- print('')
-
-
-
-def main():
- parser = optparse.OptionParser(
- prog='bsd',
- description='Utility for BSD archives')
- parser.add_option(
- '--object',
- type='string',
- dest='object_name',
- default=None,
- help=('Specify the name of a object within the BSD archive to get '
- 'information on'))
- parser.add_option(
- '-s', '--symbol',
- type='string',
- dest='find_symbol',
- default=None,
- help=('Specify the name of a symbol within the BSD archive to get '
- 'information on from SYMDEF'))
- parser.add_option(
- '--symdef',
- action='store_true',
- dest='symdef',
- default=False,
- help=('Dump the information in the SYMDEF.'))
- parser.add_option(
- '-v', '--verbose',
- action='store_true',
- dest='verbose',
- default=False,
- help='Enable verbose output')
- parser.add_option(
- '-e', '--extract',
- action='store_true',
- dest='extract',
- default=False,
- help=('Specify this to extract the object specified with the --object '
- 'option. There must be only one object with a matching name or '
- 'the --mtime option must be specified to uniquely identify a '
- 'single object.'))
- parser.add_option(
- '-m', '--mtime',
- type='int',
- dest='mtime',
- default=None,
- help=('Specify the modification time of the object an object. This '
- 'option is used with either the --object or --extract options.'))
- parser.add_option(
- '-o', '--outfile',
- type='string',
- dest='outfile',
- default=None,
- help=('Specify a different name or path for the file to extract when '
- 'using the --extract option. If this option isn\'t specified, '
- 'then the extracted object file will be extracted into the '
- 'current working directory if a file doesn\'t already exist '
- 'with that name.'))
- parser.add_option(
- '-i', '--interactive',
- action='store_true',
- dest='interactive',
- default=False,
- help=('Enter an interactive shell that allows users to interactively '
- 'explore contents of .a files.'))
-
- (options, args) = parser.parse_args(sys.argv[1:])
-
- if options.interactive:
- archives = []
- for path in args:
- archives.append(Archive(path))
- interpreter = Interactive(archives)
- interpreter.cmdloop()
- return
-
- for path in args:
- archive = Archive(path)
- if options.object_name:
- print('%s:\n' % (path))
- matches = archive.find(options.object_name, options.mtime)
- if matches:
- dump_all = True
- if options.extract:
- if len(matches) == 1:
- dump_all = False
- matches[0].save(path=options.outfile, overwrite=False)
- else:
- print('error: multiple objects match "%s". Specify '
- 'the modification time using --mtime.' % (
- options.object_name))
- if dump_all:
- for obj in matches:
- obj.dump(flat=False)
- else:
- print('error: object "%s" not found in archive' % (
- options.object_name))
- elif options.find_symbol:
- symdefs = archive.get_symdef()
- if symdefs:
- success = False
- for (name, offset) in symdefs:
- obj = archive.get_object_at_offset(offset)
- if name == options.find_symbol:
- print('Found "%s" in:' % (options.find_symbol))
- obj.dump(flat=False)
- success = True
- if not success:
- print('Didn\'t find "%s" in any objects' % (
- options.find_symbol))
- else:
- print("error: no __.SYMDEF was found")
- elif options.symdef:
- object_dicts = archive.get_object_dicts()
- for object_dict in object_dicts:
- object_dict['object'].dump(flat=False)
- print("symbols:")
- for name in object_dict['symdefs']:
- print(" %s" % (name))
- else:
- archive.dump(flat=not options.verbose)
-
-
-if __name__ == '__main__':
- main()
-
-
-def print_mtime_error(result, dmap_mtime, actual_mtime):
- print >>result, ("error: modification time in debug map (%#08.8x) doesn't "
- "match the .o file modification time (%#08.8x)" % (
- dmap_mtime, actual_mtime))
-
-
-def print_file_missing_error(result, path):
- print >>result, "error: file \"%s\" doesn't exist" % (path)
-
-
-def print_multiple_object_matches(result, object_name, mtime, matches):
- print >>result, ("error: multiple matches for object '%s' with with "
- "modification time %#08.8x:" % (object_name, mtime))
- Archive.dump_header(f=result)
- for match in matches:
- match.dump(f=result, flat=True)
-
-
-def print_archive_object_error(result, object_name, mtime, archive):
- matches = archive.find(object_name, f=result)
- if len(matches) > 0:
- print >>result, ("error: no objects have a modification time that "
- "matches %#08.8x for '%s'. Potential matches:" % (
- mtime, object_name))
- Archive.dump_header(f=result)
- for match in matches:
- match.dump(f=result, flat=True)
- else:
- print >>result, "error: no object named \"%s\" found in archive:" % (
- object_name)
- Archive.dump_header(f=result)
- for match in archive.objects:
- match.dump(f=result, flat=True)
- # archive.dump(f=result, flat=True)
-
-
-class VerifyDebugMapCommand:
- name = "verify-debug-map-objects"
-
- def create_options(self):
- usage = "usage: %prog [options]"
- description = '''This command reports any .o files that are missing
-or whose modification times don't match in the debug map of an executable.'''
-
- self.parser = optparse.OptionParser(
- description=description,
- prog=self.name,
- usage=usage,
- add_help_option=False)
-
- self.parser.add_option(
- '-e', '--errors',
- action='store_true',
- dest='errors',
- default=False,
- help="Only show errors")
-
- def get_short_help(self):
- return "Verify debug map object files."
-
- def get_long_help(self):
- return self.help_string
-
- def __init__(self, debugger, unused):
- self.create_options()
- self.help_string = self.parser.format_help()
-
- def __call__(self, debugger, command, exe_ctx, result):
- import lldb
- # Use the Shell Lexer to properly parse up command options just like a
- # shell would
- command_args = shlex.split(command)
-
- try:
- (options, args) = self.parser.parse_args(command_args)
- except:
- result.SetError("option parsing failed")
- return
-
- # Always get program state from the SBExecutionContext passed in
- target = exe_ctx.GetTarget()
- if not target.IsValid():
- result.SetError("invalid target")
- return
- archives = {}
- for module_spec in args:
- module = target.module[module_spec]
- if not (module and module.IsValid()):
- result.SetError('error: invalid module specification: "%s". '
- 'Specify the full path, basename, or UUID of '
- 'a module ' % (module_spec))
- return
- num_symbols = module.GetNumSymbols()
- num_errors = 0
- for i in range(num_symbols):
- symbol = module.GetSymbolAtIndex(i)
- if symbol.GetType() != lldb.eSymbolTypeObjectFile:
- continue
- path = symbol.GetName()
- if not path:
- continue
- # Extract the value of the symbol by dumping the
- # symbol. The value is the mod time.
- dmap_mtime = int(str(symbol).split('value = ')
- [1].split(',')[0], 16)
- if not options.errors:
- print >>result, '%s' % (path)
- if os.path.exists(path):
- actual_mtime = int(os.stat(path).st_mtime)
- if dmap_mtime != actual_mtime:
- num_errors += 1
- if options.errors:
- print >>result, '%s' % (path),
- print_mtime_error(result, dmap_mtime,
- actual_mtime)
- elif path[-1] == ')':
- (archive_path, object_name) = path[0:-1].split('(')
- if not archive_path and not object_name:
- num_errors += 1
- if options.errors:
- print >>result, '%s' % (path),
- print_file_missing_error(path)
- continue
- if not os.path.exists(archive_path):
- num_errors += 1
- if options.errors:
- print >>result, '%s' % (path),
- print_file_missing_error(archive_path)
- continue
- if archive_path in archives:
- archive = archives[archive_path]
- else:
- archive = Archive(archive_path)
- archives[archive_path] = archive
- matches = archive.find(object_name, dmap_mtime)
- num_matches = len(matches)
- if num_matches == 1:
- print >>result, '1 match'
- obj = matches[0]
- if obj.date != dmap_mtime:
- num_errors += 1
- if options.errors:
- print >>result, '%s' % (path),
- print_mtime_error(result, dmap_mtime, obj.date)
- elif num_matches == 0:
- num_errors += 1
- if options.errors:
- print >>result, '%s' % (path),
- print_archive_object_error(result, object_name,
- dmap_mtime, archive)
- elif num_matches > 1:
- num_errors += 1
- if options.errors:
- print >>result, '%s' % (path),
- print_multiple_object_matches(result,
- object_name,
- dmap_mtime, matches)
- if num_errors > 0:
- print >>result, "%u errors found" % (num_errors)
- else:
- print >>result, "No errors detected in debug map"
-
-
-def __lldb_init_module(debugger, dict):
- # This initializer is being run from LLDB in the embedded command
- # interpreter.
- # Add any commands contained in this module to LLDB
- debugger.HandleCommand(
- 'command script add -c %s.VerifyDebugMapCommand %s' % (
- __name__, VerifyDebugMapCommand.name))
- print('The "%s" command has been installed, type "help %s" for detailed '
- 'help.' % (VerifyDebugMapCommand.name, VerifyDebugMapCommand.name))
diff --git a/examples/python/cmdtemplate.py b/examples/python/cmdtemplate.py
deleted file mode 100644
index 0acb04ef4715..000000000000
--- a/examples/python/cmdtemplate.py
+++ /dev/null
@@ -1,147 +0,0 @@
-#!/usr/bin/python
-
-# ---------------------------------------------------------------------
-# Be sure to add the python path that points to the LLDB shared library.
-#
-# # To use this in the embedded python interpreter using "lldb" just
-# import it with the full path using the "command script import"
-# command
-# (lldb) command script import /path/to/cmdtemplate.py
-# ---------------------------------------------------------------------
-
-import inspect
-import lldb
-import optparse
-import shlex
-import sys
-
-
-class FrameStatCommand:
- program = 'framestats'
-
- @classmethod
- def register_lldb_command(cls, debugger, module_name):
- parser = cls.create_options()
- cls.__doc__ = parser.format_help()
- # Add any commands contained in this module to LLDB
- command = 'command script add -c %s.%s %s' % (module_name,
- cls.__name__,
- cls.program)
- debugger.HandleCommand(command)
- print('The "{0}" command has been installed, type "help {0}" or "{0} '
- '--help" for detailed help.'.format(cls.program))
-
- @classmethod
- def create_options(cls):
-
- usage = "usage: %prog [options]"
- description = ('This command is meant to be an example of how to make '
- 'an LLDB command that does something useful, follows '
- 'best practices, and exploits the SB API. '
- 'Specifically, this command computes the aggregate '
- 'and average size of the variables in the current '
- 'frame and allows you to tweak exactly which variables '
- 'are to be accounted in the computation.')
-
- # Pass add_help_option = False, since this keeps the command in line
- # with lldb commands, and we wire up "help command" to work by
- # providing the long & short help methods below.
- parser = optparse.OptionParser(
- description=description,
- prog=cls.program,
- usage=usage,
- add_help_option=False)
-
- parser.add_option(
- '-i',
- '--in-scope',
- action='store_true',
- dest='inscope',
- help='in_scope_only = True',
- default=True)
-
- parser.add_option(
- '-a',
- '--arguments',
- action='store_true',
- dest='arguments',
- help='arguments = True',
- default=True)
-
- parser.add_option(
- '-l',
- '--locals',
- action='store_true',
- dest='locals',
- help='locals = True',
- default=True)
-
- parser.add_option(
- '-s',
- '--statics',
- action='store_true',
- dest='statics',
- help='statics = True',
- default=True)
-
- return parser
-
- def get_short_help(self):
- return "Example command for use in debugging"
-
- def get_long_help(self):
- return self.help_string
-
- def __init__(self, debugger, unused):
- self.parser = self.create_options()
- self.help_string = self.parser.format_help()
-
- def __call__(self, debugger, command, exe_ctx, result):
- # Use the Shell Lexer to properly parse up command options just like a
- # shell would
- command_args = shlex.split(command)
-
- try:
- (options, args) = self.parser.parse_args(command_args)
- except:
- # if you don't handle exceptions, passing an incorrect argument to
- # the OptionParser will cause LLDB to exit (courtesy of OptParse
- # dealing with argument errors by throwing SystemExit)
- result.SetError("option parsing failed")
- return
-
- # Always get program state from the lldb.SBExecutionContext passed
- # in as exe_ctx
- frame = exe_ctx.GetFrame()
- if not frame.IsValid():
- result.SetError("invalid frame")
- return
-
- variables_list = frame.GetVariables(
- options.arguments,
- options.locals,
- options.statics,
- options.inscope)
- variables_count = variables_list.GetSize()
- if variables_count == 0:
- print >> result, "no variables here"
- return
- total_size = 0
- for i in range(0, variables_count):
- variable = variables_list.GetValueAtIndex(i)
- variable_type = variable.GetType()
- total_size = total_size + variable_type.GetByteSize()
- average_size = float(total_size) / variables_count
- print >>result, ("Your frame has %d variables. Their total size "
- "is %d bytes. The average size is %f bytes") % (
- variables_count, total_size, average_size)
- # not returning anything is akin to returning success
-
-
-def __lldb_init_module(debugger, dict):
- # Register all classes that have a register_lldb_command method
- for _name, cls in inspect.getmembers(sys.modules[__name__]):
- if inspect.isclass(cls) and callable(getattr(cls,
- "register_lldb_command",
- None)):
- cls.register_lldb_command(debugger, __name__)
diff --git a/examples/python/crashlog.py b/examples/python/crashlog.py
deleted file mode 100755
index 7eb86db7ce09..000000000000
--- a/examples/python/crashlog.py
+++ /dev/null
@@ -1,1027 +0,0 @@
-#!/usr/bin/python
-
-#----------------------------------------------------------------------
-# Be sure to add the python path that points to the LLDB shared library.
-#
-# To use this in the embedded python interpreter using "lldb":
-#
-# cd /path/containing/crashlog.py
-# lldb
-# (lldb) script import crashlog
-# "crashlog" command installed, type "crashlog --help" for detailed help
-# (lldb) crashlog ~/Library/Logs/DiagnosticReports/a.crash
-#
-# The benefit of running the crashlog command inside lldb in the
-# embedded python interpreter is when the command completes, there
-# will be a target with all of the files loaded at the locations
-# described in the crash log. Only the files that have stack frames
-# in the backtrace will be loaded unless the "--load-all" option
-# has been specified. This allows users to explore the program in the
-# state it was in right at crash time.
-#
-# On MacOSX csh, tcsh:
-# ( setenv PYTHONPATH /path/to/LLDB.framework/Resources/Python ; ./crashlog.py ~/Library/Logs/DiagnosticReports/a.crash )
-#
-# On MacOSX sh, bash:
-# PYTHONPATH=/path/to/LLDB.framework/Resources/Python ./crashlog.py ~/Library/Logs/DiagnosticReports/a.crash
-#----------------------------------------------------------------------
-
-import commands
-import cmd
-import datetime
-import glob
-import optparse
-import os
-import platform
-import plistlib
-import pprint # pp = pprint.PrettyPrinter(indent=4); pp.pprint(command_args)
-import re
-import shlex
-import string
-import sys
-import time
-import uuid
-
-try:
- # Just try for LLDB in case PYTHONPATH is already correctly setup
- import lldb
-except ImportError:
- lldb_python_dirs = list()
- # lldb is not in the PYTHONPATH, try some defaults for the current platform
- platform_system = platform.system()
- if platform_system == 'Darwin':
- # On Darwin, try the currently selected Xcode directory
- xcode_dir = commands.getoutput("xcode-select --print-path")
- if xcode_dir:
- lldb_python_dirs.append(
- os.path.realpath(
- xcode_dir +
- '/../SharedFrameworks/LLDB.framework/Resources/Python'))
- lldb_python_dirs.append(
- xcode_dir + '/Library/PrivateFrameworks/LLDB.framework/Resources/Python')
- lldb_python_dirs.append(
- '/System/Library/PrivateFrameworks/LLDB.framework/Resources/Python')
- success = False
- for lldb_python_dir in lldb_python_dirs:
- if os.path.exists(lldb_python_dir):
- if not (sys.path.__contains__(lldb_python_dir)):
- sys.path.append(lldb_python_dir)
- try:
- import lldb
- except ImportError:
- pass
- else:
- print 'imported lldb from: "%s"' % (lldb_python_dir)
- success = True
- break
- if not success:
- print "error: couldn't locate the 'lldb' module, please set PYTHONPATH correctly"
- sys.exit(1)
-
-from lldb.utils import symbolication
-
-PARSE_MODE_NORMAL = 0
-PARSE_MODE_THREAD = 1
-PARSE_MODE_IMAGES = 2
-PARSE_MODE_THREGS = 3
-PARSE_MODE_SYSTEM = 4
-
-
-class CrashLog(symbolication.Symbolicator):
- """Class that does parses darwin crash logs"""
- parent_process_regex = re.compile('^Parent Process:\s*(.*)\[(\d+)\]')
- thread_state_regex = re.compile('^Thread ([0-9]+) crashed with')
- thread_regex = re.compile('^Thread ([0-9]+)([^:]*):(.*)')
- app_backtrace_regex = re.compile(
- '^Application Specific Backtrace ([0-9]+)([^:]*):(.*)')
- frame_regex = re.compile('^([0-9]+)\s+(.+?)\s+(0x[0-9a-fA-F]{7}[0-9a-fA-F]+) +(.*)')
- image_regex_uuid = re.compile(
- '(0x[0-9a-fA-F]+)[-\s]+(0x[0-9a-fA-F]+)\s+[+]?(.+?)\s+(\(.+\))?\s?(<([-0-9a-fA-F]+)>)? (.*)')
- empty_line_regex = re.compile('^$')
-
- class Thread:
- """Class that represents a thread in a darwin crash log"""
-
- def __init__(self, index, app_specific_backtrace):
- self.index = index
- self.frames = list()
- self.idents = list()
- self.registers = dict()
- self.reason = None
- self.queue = None
- self.app_specific_backtrace = app_specific_backtrace
-
- def dump(self, prefix):
- if self.app_specific_backtrace:
- print "%Application Specific Backtrace[%u] %s" % (prefix, self.index, self.reason)
- else:
- print "%sThread[%u] %s" % (prefix, self.index, self.reason)
- if self.frames:
- print "%s Frames:" % (prefix)
- for frame in self.frames:
- frame.dump(prefix + ' ')
- if self.registers:
- print "%s Registers:" % (prefix)
- for reg in self.registers.keys():
- print "%s %-5s = %#16.16x" % (prefix, reg, self.registers[reg])
-
- def dump_symbolicated(self, crash_log, options):
- this_thread_crashed = self.app_specific_backtrace
- if not this_thread_crashed:
- this_thread_crashed = self.did_crash()
- if options.crashed_only and this_thread_crashed == False:
- return
-
- print "%s" % self
- #prev_frame_index = -1
- display_frame_idx = -1
- for frame_idx, frame in enumerate(self.frames):
- disassemble = (
- this_thread_crashed or options.disassemble_all_threads) and frame_idx < options.disassemble_depth
- if frame_idx == 0:
- symbolicated_frame_addresses = crash_log.symbolicate(
- frame.pc & crash_log.addr_mask, options.verbose)
- else:
- # Any frame above frame zero and we have to subtract one to
- # get the previous line entry
- symbolicated_frame_addresses = crash_log.symbolicate(
- (frame.pc & crash_log.addr_mask) - 1, options.verbose)
-
- if symbolicated_frame_addresses:
- symbolicated_frame_address_idx = 0
- for symbolicated_frame_address in symbolicated_frame_addresses:
- display_frame_idx += 1
- print '[%3u] %s' % (frame_idx, symbolicated_frame_address)
- if (options.source_all or self.did_crash(
- )) and display_frame_idx < options.source_frames and options.source_context:
- source_context = options.source_context
- line_entry = symbolicated_frame_address.get_symbol_context().line_entry
- if line_entry.IsValid():
- strm = lldb.SBStream()
- if line_entry:
- lldb.debugger.GetSourceManager().DisplaySourceLinesWithLineNumbers(
- line_entry.file, line_entry.line, source_context, source_context, "->", strm)
- source_text = strm.GetData()
- if source_text:
- # Indent the source a bit
- indent_str = ' '
- join_str = '\n' + indent_str
- print '%s%s' % (indent_str, join_str.join(source_text.split('\n')))
- if symbolicated_frame_address_idx == 0:
- if disassemble:
- instructions = symbolicated_frame_address.get_instructions()
- if instructions:
- print
- symbolication.disassemble_instructions(
- crash_log.get_target(),
- instructions,
- frame.pc,
- options.disassemble_before,
- options.disassemble_after,
- frame.index > 0)
- print
- symbolicated_frame_address_idx += 1
- else:
- print frame
-
- def add_ident(self, ident):
- if ident not in self.idents:
- self.idents.append(ident)
-
- def did_crash(self):
- return self.reason is not None
-
- def __str__(self):
- if self.app_specific_backtrace:
- s = "Application Specific Backtrace[%u]" % self.index
- else:
- s = "Thread[%u]" % self.index
- if self.reason:
- s += ' %s' % self.reason
- return s
-
- class Frame:
- """Class that represents a stack frame in a thread in a darwin crash log"""
-
- def __init__(self, index, pc, description):
- self.pc = pc
- self.description = description
- self.index = index
-
- def __str__(self):
- if self.description:
- return "[%3u] 0x%16.16x %s" % (
- self.index, self.pc, self.description)
- else:
- return "[%3u] 0x%16.16x" % (self.index, self.pc)
-
- def dump(self, prefix):
- print "%s%s" % (prefix, str(self))
-
- class DarwinImage(symbolication.Image):
- """Class that represents a binary images in a darwin crash log"""
- dsymForUUIDBinary = os.path.expanduser('~rc/bin/dsymForUUID')
- if not os.path.exists(dsymForUUIDBinary):
- dsymForUUIDBinary = commands.getoutput('which dsymForUUID')
-
- dwarfdump_uuid_regex = re.compile(
- 'UUID: ([-0-9a-fA-F]+) \(([^\(]+)\) .*')
-
- def __init__(
- self,
- text_addr_lo,
- text_addr_hi,
- identifier,
- version,
- uuid,
- path):
- symbolication.Image.__init__(self, path, uuid)
- self.add_section(
- symbolication.Section(
- text_addr_lo,
- text_addr_hi,
- "__TEXT"))
- self.identifier = identifier
- self.version = version
-
- def find_matching_slice(self):
- dwarfdump_cmd_output = commands.getoutput(
- 'dwarfdump --uuid "%s"' % self.path)
- self_uuid = self.get_uuid()
- for line in dwarfdump_cmd_output.splitlines():
- match = self.dwarfdump_uuid_regex.search(line)
- if match:
- dwarf_uuid_str = match.group(1)
- dwarf_uuid = uuid.UUID(dwarf_uuid_str)
- if self_uuid == dwarf_uuid:
- self.resolved_path = self.path
- self.arch = match.group(2)
- return True
- if not self.resolved_path:
- self.unavailable = True
- print("error\n error: unable to locate '%s' with UUID %s"
- % (self.path, uuid_str))
- return False
-
- def locate_module_and_debug_symbols(self):
- # Don't load a module twice...
- if self.resolved:
- return True
- # Mark this as resolved so we don't keep trying
- self.resolved = True
- uuid_str = self.get_normalized_uuid_string()
- print 'Getting symbols for %s %s...' % (uuid_str, self.path),
- if os.path.exists(self.dsymForUUIDBinary):
- dsym_for_uuid_command = '%s %s' % (
- self.dsymForUUIDBinary, uuid_str)
- s = commands.getoutput(dsym_for_uuid_command)
- if s:
- try:
- plist_root = plistlib.readPlistFromString(s)
- except:
- print("Got exception: ", sys.exc_value, " handling dsymForUUID output: \n", s)
- raise
- if plist_root:
- plist = plist_root[uuid_str]
- if plist:
- if 'DBGArchitecture' in plist:
- self.arch = plist['DBGArchitecture']
- if 'DBGDSYMPath' in plist:
- self.symfile = os.path.realpath(
- plist['DBGDSYMPath'])
- if 'DBGSymbolRichExecutable' in plist:
- self.path = os.path.expanduser(
- plist['DBGSymbolRichExecutable'])
- self.resolved_path = self.path
- if not self.resolved_path and os.path.exists(self.path):
- if not self.find_matching_slice():
- return False
- if not self.resolved_path and not os.path.exists(self.path):
- try:
- import subprocess
- dsym = subprocess.check_output(
- ["/usr/bin/mdfind",
- "com_apple_xcode_dsym_uuids == %s"%uuid_str])[:-1]
- if dsym and os.path.exists(dsym):
- print('falling back to binary inside "%s"'%dsym)
- self.symfile = dsym
- dwarf_dir = os.path.join(dsym, 'Contents/Resources/DWARF')
- for filename in os.listdir(dwarf_dir):
- self.path = os.path.join(dwarf_dir, filename)
- if not self.find_matching_slice():
- return False
- break
- except:
- pass
- if (self.resolved_path and os.path.exists(self.resolved_path)) or (
- self.path and os.path.exists(self.path)):
- print 'ok'
- # if self.resolved_path:
- # print ' exe = "%s"' % self.resolved_path
- # if self.symfile:
- # print ' dsym = "%s"' % self.symfile
- return True
- else:
- self.unavailable = True
- return False
-
- def __init__(self, path):
- """CrashLog constructor that take a path to a darwin crash log file"""
- symbolication.Symbolicator.__init__(self)
- self.path = os.path.expanduser(path)
- self.info_lines = list()
- self.system_profile = list()
- self.threads = list()
- self.backtraces = list() # For application specific backtraces
- self.idents = list() # A list of the required identifiers for doing all stack backtraces
- self.crashed_thread_idx = -1
- self.version = -1
- self.error = None
- self.target = None
- # With possible initial component of ~ or ~user replaced by that user's
- # home directory.
- try:
- f = open(self.path)
- except IOError:
- self.error = 'error: cannot open "%s"' % self.path
- return
-
- self.file_lines = f.read().splitlines()
- parse_mode = PARSE_MODE_NORMAL
- thread = None
- app_specific_backtrace = False
- for line in self.file_lines:
- # print line
- line_len = len(line)
- if line_len == 0:
- if thread:
- if parse_mode == PARSE_MODE_THREAD:
- if thread.index == self.crashed_thread_idx:
- thread.reason = ''
- if self.thread_exception:
- thread.reason += self.thread_exception
- if self.thread_exception_data:
- thread.reason += " (%s)" % self.thread_exception_data
- if app_specific_backtrace:
- self.backtraces.append(thread)
- else:
- self.threads.append(thread)
- thread = None
- else:
- # only append an extra empty line if the previous line
- # in the info_lines wasn't empty
- if len(self.info_lines) > 0 and len(self.info_lines[-1]):
- self.info_lines.append(line)
- parse_mode = PARSE_MODE_NORMAL
- # print 'PARSE_MODE_NORMAL'
- elif parse_mode == PARSE_MODE_NORMAL:
- if line.startswith('Process:'):
- (self.process_name, pid_with_brackets) = line[
- 8:].strip().split(' [')
- self.process_id = pid_with_brackets.strip('[]')
- elif line.startswith('Path:'):
- self.process_path = line[5:].strip()
- elif line.startswith('Identifier:'):
- self.process_identifier = line[11:].strip()
- elif line.startswith('Version:'):
- version_string = line[8:].strip()
- matched_pair = re.search("(.+)\((.+)\)", version_string)
- if matched_pair:
- self.process_version = matched_pair.group(1)
- self.process_compatability_version = matched_pair.group(
- 2)
- else:
- self.process = version_string
- self.process_compatability_version = version_string
- elif self.parent_process_regex.search(line):
- parent_process_match = self.parent_process_regex.search(
- line)
- self.parent_process_name = parent_process_match.group(1)
- self.parent_process_id = parent_process_match.group(2)
- elif line.startswith('Exception Type:'):
- self.thread_exception = line[15:].strip()
- continue
- elif line.startswith('Exception Codes:'):
- self.thread_exception_data = line[16:].strip()
- continue
- elif line.startswith('Exception Subtype:'): # iOS
- self.thread_exception_data = line[18:].strip()
- continue
- elif line.startswith('Crashed Thread:'):
- self.crashed_thread_idx = int(line[15:].strip().split()[0])
- continue
- elif line.startswith('Triggered by Thread:'): # iOS
- self.crashed_thread_idx = int(line[20:].strip().split()[0])
- continue
- elif line.startswith('Report Version:'):
- self.version = int(line[15:].strip())
- continue
- elif line.startswith('System Profile:'):
- parse_mode = PARSE_MODE_SYSTEM
- continue
- elif (line.startswith('Interval Since Last Report:') or
- line.startswith('Crashes Since Last Report:') or
- line.startswith('Per-App Interval Since Last Report:') or
- line.startswith('Per-App Crashes Since Last Report:') or
- line.startswith('Sleep/Wake UUID:') or
- line.startswith('Anonymous UUID:')):
- # ignore these
- continue
- elif line.startswith('Thread'):
- thread_state_match = self.thread_state_regex.search(line)
- if thread_state_match:
- app_specific_backtrace = False
- thread_state_match = self.thread_regex.search(line)
- thread_idx = int(thread_state_match.group(1))
- parse_mode = PARSE_MODE_THREGS
- thread = self.threads[thread_idx]
- else:
- thread_match = self.thread_regex.search(line)
- if thread_match:
- app_specific_backtrace = False
- parse_mode = PARSE_MODE_THREAD
- thread_idx = int(thread_match.group(1))
- thread = CrashLog.Thread(thread_idx, False)
- continue
- elif line.startswith('Binary Images:'):
- parse_mode = PARSE_MODE_IMAGES
- continue
- elif line.startswith('Application Specific Backtrace'):
- app_backtrace_match = self.app_backtrace_regex.search(line)
- if app_backtrace_match:
- parse_mode = PARSE_MODE_THREAD
- app_specific_backtrace = True
- idx = int(app_backtrace_match.group(1))
- thread = CrashLog.Thread(idx, True)
- elif line.startswith('Last Exception Backtrace:'): # iOS
- parse_mode = PARSE_MODE_THREAD
- app_specific_backtrace = True
- idx = 1
- thread = CrashLog.Thread(idx, True)
- self.info_lines.append(line.strip())
- elif parse_mode == PARSE_MODE_THREAD:
- if line.startswith('Thread'):
- continue
- frame_match = self.frame_regex.search(line)
- if frame_match:
- ident = frame_match.group(2)
- thread.add_ident(ident)
- if ident not in self.idents:
- self.idents.append(ident)
- thread.frames.append(CrashLog.Frame(int(frame_match.group(1)), int(
- frame_match.group(3), 0), frame_match.group(4)))
- else:
- print 'error: frame regex failed for line: "%s"' % line
- elif parse_mode == PARSE_MODE_IMAGES:
- image_match = self.image_regex_uuid.search(line)
- if image_match:
- (img_lo, img_hi, img_name, img_version,
- _, img_uuid, img_path) = image_match.groups()
- image = CrashLog.DarwinImage(int(img_lo, 0), int(img_hi, 0),
- img_name.strip(),
- img_version.strip()
- if img_version else "",
- uuid.UUID(img_uuid), img_path)
- self.images.append(image)
- else:
- print "error: image regex failed for: %s" % line
-
- elif parse_mode == PARSE_MODE_THREGS:
- stripped_line = line.strip()
- # "r12: 0x00007fff6b5939c8 r13: 0x0000000007000006 r14: 0x0000000000002a03 r15: 0x0000000000000c00"
- reg_values = re.findall(
- '([a-zA-Z0-9]+: 0[Xx][0-9a-fA-F]+) *', stripped_line)
- for reg_value in reg_values:
- # print 'reg_value = "%s"' % reg_value
- (reg, value) = reg_value.split(': ')
- # print 'reg = "%s"' % reg
- # print 'value = "%s"' % value
- thread.registers[reg.strip()] = int(value, 0)
- elif parse_mode == PARSE_MODE_SYSTEM:
- self.system_profile.append(line)
- f.close()
-
- def dump(self):
- print "Crash Log File: %s" % (self.path)
- if self.backtraces:
- print "\nApplication Specific Backtraces:"
- for thread in self.backtraces:
- thread.dump(' ')
- print "\nThreads:"
- for thread in self.threads:
- thread.dump(' ')
- print "\nImages:"
- for image in self.images:
- image.dump(' ')
-
- def find_image_with_identifier(self, identifier):
- for image in self.images:
- if image.identifier == identifier:
- return image
- regex_text = '^.*\.%s$' % (re.escape(identifier))
- regex = re.compile(regex_text)
- for image in self.images:
- if regex.match(image.identifier):
- return image
- return None
-
- def create_target(self):
- # print 'crashlog.create_target()...'
- if self.target is None:
- self.target = symbolication.Symbolicator.create_target(self)
- if self.target:
- return self.target
- # We weren't able to open the main executable as, but we can still
- # symbolicate
- print 'crashlog.create_target()...2'
- if self.idents:
- for ident in self.idents:
- image = self.find_image_with_identifier(ident)
- if image:
- self.target = image.create_target()
- if self.target:
- return self.target # success
- print 'crashlog.create_target()...3'
- for image in self.images:
- self.target = image.create_target()
- if self.target:
- return self.target # success
- print 'crashlog.create_target()...4'
- print 'error: unable to locate any executables from the crash log'
- return self.target
-
- def get_target(self):
- return self.target
-
-
-def usage():
- print "Usage: lldb-symbolicate.py [-n name] executable-image"
- sys.exit(0)
-
-
-class Interactive(cmd.Cmd):
- '''Interactive prompt for analyzing one or more Darwin crash logs, type "help" to see a list of supported commands.'''
- image_option_parser = None
-
- def __init__(self, crash_logs):
- cmd.Cmd.__init__(self)
- self.use_rawinput = False
- self.intro = 'Interactive crashlogs prompt, type "help" to see a list of supported commands.'
- self.crash_logs = crash_logs
- self.prompt = '% '
-
- def default(self, line):
- '''Catch all for unknown command, which will exit the interpreter.'''
- print "uknown command: %s" % line
- return True
-
- def do_q(self, line):
- '''Quit command'''
- return True
-
- def do_quit(self, line):
- '''Quit command'''
- return True
-
- def do_symbolicate(self, line):
- description = '''Symbolicate one or more darwin crash log files by index to provide source file and line information,
- inlined stack frames back to the concrete functions, and disassemble the location of the crash
- for the first frame of the crashed thread.'''
- option_parser = CreateSymbolicateCrashLogOptions(
- 'symbolicate', description, False)
- command_args = shlex.split(line)
- try:
- (options, args) = option_parser.parse_args(command_args)
- except:
- return
-
- if args:
- # We have arguments, they must valid be crash log file indexes
- for idx_str in args:
- idx = int(idx_str)
- if idx < len(self.crash_logs):
- SymbolicateCrashLog(self.crash_logs[idx], options)
- else:
- print 'error: crash log index %u is out of range' % (idx)
- else:
- # No arguments, symbolicate all crash logs using the options
- # provided
- for idx in range(len(self.crash_logs)):
- SymbolicateCrashLog(self.crash_logs[idx], options)
-
- def do_list(self, line=None):
- '''Dump a list of all crash logs that are currently loaded.
-
- USAGE: list'''
- print '%u crash logs are loaded:' % len(self.crash_logs)
- for (crash_log_idx, crash_log) in enumerate(self.crash_logs):
- print '[%u] = %s' % (crash_log_idx, crash_log.path)
-
- def do_image(self, line):
- '''Dump information about one or more binary images in the crash log given an image basename, or all images if no arguments are provided.'''
- usage = "usage: %prog [options] <PATH> [PATH ...]"
- description = '''Dump information about one or more images in all crash logs. The <PATH> can be a full path, image basename, or partial path. Searches are done in this order.'''
- command_args = shlex.split(line)
- if not self.image_option_parser:
- self.image_option_parser = optparse.OptionParser(
- description=description, prog='image', usage=usage)
- self.image_option_parser.add_option(
- '-a',
- '--all',
- action='store_true',
- help='show all images',
- default=False)
- try:
- (options, args) = self.image_option_parser.parse_args(command_args)
- except:
- return
-
- if args:
- for image_path in args:
- fullpath_search = image_path[0] == '/'
- for (crash_log_idx, crash_log) in enumerate(self.crash_logs):
- matches_found = 0
- for (image_idx, image) in enumerate(crash_log.images):
- if fullpath_search:
- if image.get_resolved_path() == image_path:
- matches_found += 1
- print '[%u] ' % (crash_log_idx), image
- else:
- image_basename = image.get_resolved_path_basename()
- if image_basename == image_path:
- matches_found += 1
- print '[%u] ' % (crash_log_idx), image
- if matches_found == 0:
- for (image_idx, image) in enumerate(crash_log.images):
- resolved_image_path = image.get_resolved_path()
- if resolved_image_path and string.find(
- image.get_resolved_path(), image_path) >= 0:
- print '[%u] ' % (crash_log_idx), image
- else:
- for crash_log in self.crash_logs:
- for (image_idx, image) in enumerate(crash_log.images):
- print '[%u] %s' % (image_idx, image)
- return False
-
-
-def interactive_crashlogs(options, args):
- crash_log_files = list()
- for arg in args:
- for resolved_path in glob.glob(arg):
- crash_log_files.append(resolved_path)
-
- crash_logs = list()
- for crash_log_file in crash_log_files:
- # print 'crash_log_file = "%s"' % crash_log_file
- crash_log = CrashLog(crash_log_file)
- if crash_log.error:
- print crash_log.error
- continue
- if options.debug:
- crash_log.dump()
- if not crash_log.images:
- print 'error: no images in crash log "%s"' % (crash_log)
- continue
- else:
- crash_logs.append(crash_log)
-
- interpreter = Interactive(crash_logs)
- # List all crash logs that were imported
- interpreter.do_list()
- interpreter.cmdloop()
-
-
-def save_crashlog(debugger, command, exe_ctx, result, dict):
- usage = "usage: %prog [options] <output-path>"
- description = '''Export the state of current target into a crashlog file'''
- parser = optparse.OptionParser(
- description=description,
- prog='save_crashlog',
- usage=usage)
- parser.add_option(
- '-v',
- '--verbose',
- action='store_true',
- dest='verbose',
- help='display verbose debug info',
- default=False)
- try:
- (options, args) = parser.parse_args(shlex.split(command))
- except:
- result.PutCString("error: invalid options")
- return
- if len(args) != 1:
- result.PutCString(
- "error: invalid arguments, a single output file is the only valid argument")
- return
- out_file = open(args[0], 'w')
- if not out_file:
- result.PutCString(
- "error: failed to open file '%s' for writing...",
- args[0])
- return
- target = exe_ctx.target
- if target:
- identifier = target.executable.basename
- process = exe_ctx.process
- if process:
- pid = process.id
- if pid != lldb.LLDB_INVALID_PROCESS_ID:
- out_file.write(
- 'Process: %s [%u]\n' %
- (identifier, pid))
- out_file.write('Path: %s\n' % (target.executable.fullpath))
- out_file.write('Identifier: %s\n' % (identifier))
- out_file.write('\nDate/Time: %s\n' %
- (datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")))
- out_file.write(
- 'OS Version: Mac OS X %s (%s)\n' %
- (platform.mac_ver()[0], commands.getoutput('sysctl -n kern.osversion')))
- out_file.write('Report Version: 9\n')
- for thread_idx in range(process.num_threads):
- thread = process.thread[thread_idx]
- out_file.write('\nThread %u:\n' % (thread_idx))
- for (frame_idx, frame) in enumerate(thread.frames):
- frame_pc = frame.pc
- frame_offset = 0
- if frame.function:
- block = frame.GetFrameBlock()
- block_range = block.range[frame.addr]
- if block_range:
- block_start_addr = block_range[0]
- frame_offset = frame_pc - block_start_addr.load_addr
- else:
- frame_offset = frame_pc - frame.function.addr.load_addr
- elif frame.symbol:
- frame_offset = frame_pc - frame.symbol.addr.load_addr
- out_file.write(
- '%-3u %-32s 0x%16.16x %s' %
- (frame_idx, frame.module.file.basename, frame_pc, frame.name))
- if frame_offset > 0:
- out_file.write(' + %u' % (frame_offset))
- line_entry = frame.line_entry
- if line_entry:
- if options.verbose:
- # This will output the fullpath + line + column
- out_file.write(' %s' % (line_entry))
- else:
- out_file.write(
- ' %s:%u' %
- (line_entry.file.basename, line_entry.line))
- column = line_entry.column
- if column:
- out_file.write(':%u' % (column))
- out_file.write('\n')
-
- out_file.write('\nBinary Images:\n')
- for module in target.modules:
- text_segment = module.section['__TEXT']
- if text_segment:
- text_segment_load_addr = text_segment.GetLoadAddress(target)
- if text_segment_load_addr != lldb.LLDB_INVALID_ADDRESS:
- text_segment_end_load_addr = text_segment_load_addr + text_segment.size
- identifier = module.file.basename
- module_version = '???'
- module_version_array = module.GetVersion()
- if module_version_array:
- module_version = '.'.join(
- map(str, module_version_array))
- out_file.write(
- ' 0x%16.16x - 0x%16.16x %s (%s - ???) <%s> %s\n' %
- (text_segment_load_addr,
- text_segment_end_load_addr,
- identifier,
- module_version,
- module.GetUUIDString(),
- module.file.fullpath))
- out_file.close()
- else:
- result.PutCString("error: invalid target")
-
-
-def Symbolicate(debugger, command, result, dict):
- try:
- SymbolicateCrashLogs(shlex.split(command))
- except:
- result.PutCString("error: python exception %s" % sys.exc_info()[0])
-
-
-def SymbolicateCrashLog(crash_log, options):
- if crash_log.error:
- print crash_log.error
- return
- if options.debug:
- crash_log.dump()
- if not crash_log.images:
- print 'error: no images in crash log'
- return
-
- if options.dump_image_list:
- print "Binary Images:"
- for image in crash_log.images:
- if options.verbose:
- print image.debug_dump()
- else:
- print image
-
- target = crash_log.create_target()
- if not target:
- return
- exe_module = target.GetModuleAtIndex(0)
- images_to_load = list()
- loaded_images = list()
- if options.load_all_images:
- # --load-all option was specified, load everything up
- for image in crash_log.images:
- images_to_load.append(image)
- else:
- # Only load the images found in stack frames for the crashed threads
- if options.crashed_only:
- for thread in crash_log.threads:
- if thread.did_crash():
- for ident in thread.idents:
- images = crash_log.find_images_with_identifier(ident)
- if images:
- for image in images:
- images_to_load.append(image)
- else:
- print 'error: can\'t find image for identifier "%s"' % ident
- else:
- for ident in crash_log.idents:
- images = crash_log.find_images_with_identifier(ident)
- if images:
- for image in images:
- images_to_load.append(image)
- else:
- print 'error: can\'t find image for identifier "%s"' % ident
-
- for image in images_to_load:
- if image not in loaded_images:
- err = image.add_module(target)
- if err:
- print err
- else:
- # print 'loaded %s' % image
- loaded_images.append(image)
-
- if crash_log.backtraces:
- for thread in crash_log.backtraces:
- thread.dump_symbolicated(crash_log, options)
- print
-
- for thread in crash_log.threads:
- thread.dump_symbolicated(crash_log, options)
- print
-
-
-def CreateSymbolicateCrashLogOptions(
- command_name,
- description,
- add_interactive_options):
- usage = "usage: %prog [options] <FILE> [FILE ...]"
- option_parser = optparse.OptionParser(
- description=description, prog='crashlog', usage=usage)
- option_parser.add_option(
- '--verbose',
- '-v',
- action='store_true',
- dest='verbose',
- help='display verbose debug info',
- default=False)
- option_parser.add_option(
- '--debug',
- '-g',
- action='store_true',
- dest='debug',
- help='display verbose debug logging',
- default=False)
- option_parser.add_option(
- '--load-all',
- '-a',
- action='store_true',
- dest='load_all_images',
- help='load all executable images, not just the images found in the crashed stack frames',
- default=False)
- option_parser.add_option(
- '--images',
- action='store_true',
- dest='dump_image_list',
- help='show image list',
- default=False)
- option_parser.add_option(
- '--debug-delay',
- type='int',
- dest='debug_delay',
- metavar='NSEC',
- help='pause for NSEC seconds for debugger',
- default=0)
- option_parser.add_option(
- '--crashed-only',
- '-c',
- action='store_true',
- dest='crashed_only',
- help='only symbolicate the crashed thread',
- default=False)
- option_parser.add_option(
- '--disasm-depth',
- '-d',
- type='int',
- dest='disassemble_depth',
- help='set the depth in stack frames that should be disassembled (default is 1)',
- default=1)
- option_parser.add_option(
- '--disasm-all',
- '-D',
- action='store_true',
- dest='disassemble_all_threads',
- help='enabled disassembly of frames on all threads (not just the crashed thread)',
- default=False)
- option_parser.add_option(
- '--disasm-before',
- '-B',
- type='int',
- dest='disassemble_before',
- help='the number of instructions to disassemble before the frame PC',
- default=4)
- option_parser.add_option(
- '--disasm-after',
- '-A',
- type='int',
- dest='disassemble_after',
- help='the number of instructions to disassemble after the frame PC',
- default=4)
- option_parser.add_option(
- '--source-context',
- '-C',
- type='int',
- metavar='NLINES',
- dest='source_context',
- help='show NLINES source lines of source context (default = 4)',
- default=4)
- option_parser.add_option(
- '--source-frames',
- type='int',
- metavar='NFRAMES',
- dest='source_frames',
- help='show source for NFRAMES (default = 4)',
- default=4)
- option_parser.add_option(
- '--source-all',
- action='store_true',
- dest='source_all',
- help='show source for all threads, not just the crashed thread',
- default=False)
- if add_interactive_options:
- option_parser.add_option(
- '-i',
- '--interactive',
- action='store_true',
- help='parse all crash logs and enter interactive mode',
- default=False)
- return option_parser
-
-
-def SymbolicateCrashLogs(command_args):
- description = '''Symbolicate one or more darwin crash log files to provide source file and line information,
-inlined stack frames back to the concrete functions, and disassemble the location of the crash
-for the first frame of the crashed thread.
-If this script is imported into the LLDB command interpreter, a "crashlog" command will be added to the interpreter
-for use at the LLDB command line. After a crash log has been parsed and symbolicated, a target will have been
-created that has all of the shared libraries loaded at the load addresses found in the crash log file. This allows
-you to explore the program as if it were stopped at the locations described in the crash log and functions can
-be disassembled and lookups can be performed using the addresses found in the crash log.'''
- option_parser = CreateSymbolicateCrashLogOptions(
- 'crashlog', description, True)
- try:
- (options, args) = option_parser.parse_args(command_args)
- except:
- return
-
- if options.debug:
- print 'command_args = %s' % command_args
- print 'options', options
- print 'args', args
-
- if options.debug_delay > 0:
- print "Waiting %u seconds for debugger to attach..." % options.debug_delay
- time.sleep(options.debug_delay)
- error = lldb.SBError()
-
- if args:
- if options.interactive:
- interactive_crashlogs(options, args)
- else:
- for crash_log_file in args:
- crash_log = CrashLog(crash_log_file)
- SymbolicateCrashLog(crash_log, options)
-if __name__ == '__main__':
- # Create a new debugger instance
- lldb.debugger = lldb.SBDebugger.Create()
- SymbolicateCrashLogs(sys.argv[1:])
- lldb.SBDebugger.Destroy(lldb.debugger)
-elif getattr(lldb, 'debugger', None):
- lldb.debugger.HandleCommand(
- 'command script add -f lldb.macosx.crashlog.Symbolicate crashlog')
- lldb.debugger.HandleCommand(
- 'command script add -f lldb.macosx.crashlog.save_crashlog save_crashlog')
- print '"crashlog" and "save_crashlog" command installed, use the "--help" option for detailed help'
diff --git a/examples/python/delta.py b/examples/python/delta.py
deleted file mode 100755
index 1b192aceb9da..000000000000
--- a/examples/python/delta.py
+++ /dev/null
@@ -1,134 +0,0 @@
-#!/usr/bin/python
-
-#----------------------------------------------------------------------
-# This module will enable GDB remote packet logging when the
-# 'start_gdb_log' command is called with a filename to log to. When the
-# 'stop_gdb_log' command is called, it will disable the logging and
-# print out statistics about how long commands took to execute and also
-# will primnt ou
-# Be sure to add the python path that points to the LLDB shared library.
-#
-# To use this in the embedded python interpreter using "lldb" just
-# import it with the full path using the "command script import"
-# command. This can be done from the LLDB command line:
-# (lldb) command script import /path/to/gdbremote.py
-# Or it can be added to your ~/.lldbinit file so this module is always
-# available.
-#----------------------------------------------------------------------
-
-import commands
-import optparse
-import os
-import shlex
-import re
-import tempfile
-
-
-def start_gdb_log(debugger, command, result, dict):
- '''Start logging GDB remote packets by enabling logging with timestamps and
- thread safe logging. Follow a call to this function with a call to "stop_gdb_log"
- in order to dump out the commands.'''
- global log_file
- if log_file:
- result.PutCString(
- 'error: logging is already in progress with file "%s"',
- log_file)
- else:
- args_len = len(args)
- if args_len == 0:
- log_file = tempfile.mktemp()
- elif len(args) == 1:
- log_file = args[0]
-
- if log_file:
- debugger.HandleCommand(
- 'log enable --threadsafe --timestamp --file "%s" gdb-remote packets' %
- log_file)
- result.PutCString(
- "GDB packet logging enable with log file '%s'\nUse the 'stop_gdb_log' command to stop logging and show packet statistics." %
- log_file)
- return
-
- result.PutCString('error: invalid log file path')
- result.PutCString(usage)
-
-
-def parse_time_log(debugger, command, result, dict):
- # Any commands whose names might be followed by more valid C identifier
- # characters must be listed here
- command_args = shlex.split(command)
- parse_time_log_args(command_args)
-
-
-def parse_time_log_args(command_args):
- usage = "usage: parse_time_log [options] [<LOGFILEPATH>]"
- description = '''Parse a log file that contains timestamps and convert the timestamps to delta times between log lines.'''
- parser = optparse.OptionParser(
- description=description,
- prog='parse_time_log',
- usage=usage)
- parser.add_option(
- '-v',
- '--verbose',
- action='store_true',
- dest='verbose',
- help='display verbose debug info',
- default=False)
- try:
- (options, args) = parser.parse_args(command_args)
- except:
- return
- for log_file in args:
- parse_log_file(log_file, options)
-
-
-def parse_log_file(file, options):
- '''Parse a log file that was contains timestamps. These logs are typically
- generated using:
- (lldb) log enable --threadsafe --timestamp --file <FILE> ....
-
- This log file will contain timestamps and this function will then normalize
- those packets to be relative to the first value timestamp that is found and
- show delta times between log lines and also keep track of how long it takes
- for GDB remote commands to make a send/receive round trip. This can be
- handy when trying to figure out why some operation in the debugger is taking
- a long time during a preset set of debugger commands.'''
-
- print '#----------------------------------------------------------------------'
- print "# Log file: '%s'" % file
- print '#----------------------------------------------------------------------'
-
- timestamp_regex = re.compile('(\s*)([1-9][0-9]+\.[0-9]+)([^0-9].*)$')
-
- base_time = 0.0
- last_time = 0.0
- file = open(file)
- lines = file.read().splitlines()
- for line in lines:
- match = timestamp_regex.match(line)
- if match:
- curr_time = float(match.group(2))
- delta = 0.0
- if base_time:
- delta = curr_time - last_time
- else:
- base_time = curr_time
-
- print '%s%.6f %+.6f%s' % (match.group(1), curr_time - base_time, delta, match.group(3))
- last_time = curr_time
- else:
- print line
-
-
-if __name__ == '__main__':
- import sys
- parse_time_log_args(sys.argv[1:])
-
-else:
- import lldb
- if lldb.debugger:
- # This initializer is being run from LLDB in the embedded command interpreter
- # Add any commands contained in this module to LLDB
- lldb.debugger.HandleCommand(
- 'command script add -f delta.parse_time_log parse_time_log')
- print 'The "parse_time_log" command is now installed and ready for use, type "parse_time_log --help" for more information'
diff --git a/examples/python/diagnose_nsstring.py b/examples/python/diagnose_nsstring.py
deleted file mode 100644
index 0404f714f74a..000000000000
--- a/examples/python/diagnose_nsstring.py
+++ /dev/null
@@ -1,183 +0,0 @@
-# This implements the "diagnose-nsstring" command, usually installed in the debug session like
-# command script import lldb.diagnose
-# it is used when NSString summary formatter fails to replicate the logic that went into LLDB making the
-# decisions it did and providing some useful context information that can
-# be used for improving the formatter
-
-import lldb
-
-
-def read_memory(process, location, size):
- data = ""
- error = lldb.SBError()
- for x in range(0, size - 1):
- byte = process.ReadUnsignedFromMemory(x + location, 1, error)
- if error.fail:
- data = data + "err%s" % "" if x == size - 2 else ":"
- else:
- try:
- data = data + "0x%x" % byte
- if byte == 0:
- data = data + "(\\0)"
- elif byte == 0xa:
- data = data + "(\\a)"
- elif byte == 0xb:
- data = data + "(\\b)"
- elif byte == 0xc:
- data = data + "(\\c)"
- elif byte == '\n':
- data = data + "(\\n)"
- else:
- data = data + "(%s)" % chr(byte)
- if x < size - 2:
- data = data + ":"
- except Exception as e:
- print e
- return data
-
-
-def diagnose_nsstring_Command_Impl(debugger, command, result, internal_dict):
- """
- A command to diagnose the LLDB NSString data formatter
- invoke as
- (lldb) diagnose-nsstring <expr returning NSString>
- e.g.
- (lldb) diagnose-nsstring @"Hello world"
- """
- target = debugger.GetSelectedTarget()
- process = target.GetProcess()
- thread = process.GetSelectedThread()
- frame = thread.GetSelectedFrame()
- if not target.IsValid() or not process.IsValid():
- return "unable to get target/process - cannot proceed"
- options = lldb.SBExpressionOptions()
- options.SetFetchDynamicValue()
- error = lldb.SBError()
- if frame.IsValid():
- nsstring = frame.EvaluateExpression(command, options)
- else:
- nsstring = target.EvaluateExpression(command, options)
- print >>result, str(nsstring)
- nsstring_address = nsstring.GetValueAsUnsigned(0)
- if nsstring_address == 0:
- return "unable to obtain the string - cannot proceed"
- expression = "\
-struct $__lldb__notInlineMutable {\
- char* buffer;\
- signed long length;\
- signed long capacity;\
- unsigned int hasGap:1;\
- unsigned int isFixedCapacity:1;\
- unsigned int isExternalMutable:1;\
- unsigned int capacityProvidedExternally:1;\n\
-#if __LP64__\n\
- unsigned long desiredCapacity:60;\n\
-#else\n\
- unsigned long desiredCapacity:28;\n\
-#endif\n\
- void* contentsAllocator;\
-};\
-\
-struct $__lldb__CFString {\
- void* _cfisa;\
- uint8_t _cfinfo[4];\
- uint32_t _rc;\
- union {\
- struct __inline1 {\
- signed long length;\
- } inline1;\
- struct __notInlineImmutable1 {\
- char* buffer;\
- signed long length;\
- void* contentsDeallocator;\
- } notInlineImmutable1;\
- struct __notInlineImmutable2 {\
- char* buffer;\
- void* contentsDeallocator;\
- } notInlineImmutable2;\
- struct $__lldb__notInlineMutable notInlineMutable;\
- } variants;\
-};\
-"
-
- expression = expression + "*(($__lldb__CFString*) %d)" % nsstring_address
- # print expression
- dumped = target.EvaluateExpression(expression, options)
- print >>result, str(dumped)
-
- little_endian = (target.byte_order == lldb.eByteOrderLittle)
- ptr_size = target.addr_size
-
- info_bits = dumped.GetChildMemberWithName("_cfinfo").GetChildAtIndex(
- 0 if little_endian else 3).GetValueAsUnsigned(0)
- is_mutable = (info_bits & 1) == 1
- is_inline = (info_bits & 0x60) == 0
- has_explicit_length = (info_bits & (1 | 4)) != 4
- is_unicode = (info_bits & 0x10) == 0x10
- is_special = (
- nsstring.GetDynamicValue(
- lldb.eDynamicCanRunTarget).GetTypeName() == "NSPathStore2")
- has_null = (info_bits & 8) == 8
-
- print >>result, "\nInfo=%d\nMutable=%s\nInline=%s\nExplicit=%s\nUnicode=%s\nSpecial=%s\nNull=%s\n" % \
- (info_bits, "yes" if is_mutable else "no", "yes" if is_inline else "no", "yes" if has_explicit_length else "no", "yes" if is_unicode else "no", "yes" if is_special else "no", "yes" if has_null else "no")
-
- explicit_length_offset = 0
- if not has_null and has_explicit_length and not is_special:
- explicit_length_offset = 2 * ptr_size
- if is_mutable and not is_inline:
- explicit_length_offset = explicit_length_offset + ptr_size
- elif is_inline:
- pass
- elif not is_inline and not is_mutable:
- explicit_length_offset = explicit_length_offset + ptr_size
- else:
- explicit_length_offset = 0
-
- if explicit_length_offset == 0:
- print >>result, "There is no explicit length marker - skipping this step\n"
- else:
- explicit_length_offset = nsstring_address + explicit_length_offset
- explicit_length = process.ReadUnsignedFromMemory(
- explicit_length_offset, 4, error)
- print >>result, "Explicit length location is at 0x%x - read value is %d\n" % (
- explicit_length_offset, explicit_length)
-
- if is_mutable:
- location = 2 * ptr_size + nsstring_address
- location = process.ReadPointerFromMemory(location, error)
- elif is_inline and has_explicit_length and not is_unicode and not is_special and not is_mutable:
- location = 3 * ptr_size + nsstring_address
- elif is_unicode:
- location = 2 * ptr_size + nsstring_address
- if is_inline:
- if not has_explicit_length:
- print >>result, "Unicode & Inline & !Explicit is a new combo - no formula for it"
- else:
- location += ptr_size
- else:
- location = process.ReadPointerFromMemory(location, error)
- elif is_special:
- location = nsstring_address + ptr_size + 4
- elif is_inline:
- location = 2 * ptr_size + nsstring_address
- if not has_explicit_length:
- location += 1
- else:
- location = 2 * ptr_size + nsstring_address
- location = process.ReadPointerFromMemory(location, error)
- print >>result, "Expected data location: 0x%x\n" % (location)
- print >>result, "1K of data around location: %s\n" % read_memory(
- process, location, 1024)
- print >>result, "5K of data around string pointer: %s\n" % read_memory(
- process, nsstring_address, 1024 * 5)
-
-
-def __lldb_init_module(debugger, internal_dict):
- debugger.HandleCommand(
- "command script add -f %s.diagnose_nsstring_Command_Impl diagnose-nsstring" %
- __name__)
- print 'The "diagnose-nsstring" command has been installed, type "help diagnose-nsstring" for detailed help.'
-
-__lldb_init_module(lldb.debugger, None)
-__lldb_init_module = None
diff --git a/examples/python/diagnose_unwind.py b/examples/python/diagnose_unwind.py
deleted file mode 100644
index b90372970e5d..000000000000
--- a/examples/python/diagnose_unwind.py
+++ /dev/null
@@ -1,313 +0,0 @@
-# This implements the "diagnose-unwind" command, usually installed
-# in the debug session like
-# command script import lldb.diagnose
-# it is used when lldb's backtrace fails -- it collects and prints
-# information about the stack frames, and tries an alternate unwind
-# algorithm, that will help to understand why lldb's unwind algorithm
-# did not succeed.
-
-import optparse
-import lldb
-import re
-import shlex
-
-# Print the frame number, pc, frame pointer, module UUID and function name
-# Returns the SBModule that contains the PC, if it could be found
-
-
-def backtrace_print_frame(target, frame_num, addr, fp):
- process = target.GetProcess()
- addr_for_printing = addr
- addr_width = process.GetAddressByteSize() * 2
- if frame_num > 0:
- addr = addr - 1
-
- sbaddr = lldb.SBAddress()
- try:
- sbaddr.SetLoadAddress(addr, target)
- module_description = ""
- if sbaddr.GetModule():
- module_filename = ""
- module_uuid_str = sbaddr.GetModule().GetUUIDString()
- if module_uuid_str is None:
- module_uuid_str = ""
- if sbaddr.GetModule().GetFileSpec():
- module_filename = sbaddr.GetModule().GetFileSpec().GetFilename()
- if module_filename is None:
- module_filename = ""
- if module_uuid_str != "" or module_filename != "":
- module_description = '%s %s' % (
- module_filename, module_uuid_str)
- except Exception:
- print '%2d: pc==0x%-*x fp==0x%-*x' % (frame_num, addr_width, addr_for_printing, addr_width, fp)
- return
-
- sym_ctx = target.ResolveSymbolContextForAddress(
- sbaddr, lldb.eSymbolContextEverything)
- if sym_ctx.IsValid() and sym_ctx.GetSymbol().IsValid():
- function_start = sym_ctx.GetSymbol().GetStartAddress().GetLoadAddress(target)
- offset = addr - function_start
- print '%2d: pc==0x%-*x fp==0x%-*x %s %s + %d' % (frame_num, addr_width, addr_for_printing, addr_width, fp, module_description, sym_ctx.GetSymbol().GetName(), offset)
- else:
- print '%2d: pc==0x%-*x fp==0x%-*x %s' % (frame_num, addr_width, addr_for_printing, addr_width, fp, module_description)
- return sbaddr.GetModule()
-
-# A simple stack walk algorithm that follows the frame chain.
-# Returns a two-element list; the first element is a list of modules
-# seen and the second element is a list of addresses seen during the backtrace.
-
-
-def simple_backtrace(debugger):
- target = debugger.GetSelectedTarget()
- process = target.GetProcess()
- cur_thread = process.GetSelectedThread()
-
- initial_fp = cur_thread.GetFrameAtIndex(0).GetFP()
-
- # If the pseudoreg "fp" isn't recognized, on arm hardcode to r7 which is
- # correct for Darwin programs.
- if initial_fp == lldb.LLDB_INVALID_ADDRESS and target.triple[0:3] == "arm":
- for reggroup in cur_thread.GetFrameAtIndex(1).registers:
- if reggroup.GetName() == "General Purpose Registers":
- for reg in reggroup:
- if reg.GetName() == "r7":
- initial_fp = int(reg.GetValue(), 16)
-
- module_list = []
- address_list = [cur_thread.GetFrameAtIndex(0).GetPC()]
- this_module = backtrace_print_frame(
- target, 0, cur_thread.GetFrameAtIndex(0).GetPC(), initial_fp)
- print_stack_frame(process, initial_fp)
- print ""
- if this_module is not None:
- module_list.append(this_module)
- if cur_thread.GetNumFrames() < 2:
- return [module_list, address_list]
-
- cur_fp = process.ReadPointerFromMemory(initial_fp, lldb.SBError())
- cur_pc = process.ReadPointerFromMemory(
- initial_fp + process.GetAddressByteSize(), lldb.SBError())
-
- frame_num = 1
-
- while cur_pc != 0 and cur_fp != 0 and cur_pc != lldb.LLDB_INVALID_ADDRESS and cur_fp != lldb.LLDB_INVALID_ADDRESS:
- address_list.append(cur_pc)
- this_module = backtrace_print_frame(target, frame_num, cur_pc, cur_fp)
- print_stack_frame(process, cur_fp)
- print ""
- if this_module is not None:
- module_list.append(this_module)
- frame_num = frame_num + 1
- next_pc = 0
- next_fp = 0
- if target.triple[
- 0:6] == "x86_64" or target.triple[
- 0:4] == "i386" or target.triple[
- 0:3] == "arm":
- error = lldb.SBError()
- next_pc = process.ReadPointerFromMemory(
- cur_fp + process.GetAddressByteSize(), error)
- if not error.Success():
- next_pc = 0
- next_fp = process.ReadPointerFromMemory(cur_fp, error)
- if not error.Success():
- next_fp = 0
- # Clear the 0th bit for arm frames - this indicates it is a thumb frame
- if target.triple[0:3] == "arm" and (next_pc & 1) == 1:
- next_pc = next_pc & ~1
- cur_pc = next_pc
- cur_fp = next_fp
- this_module = backtrace_print_frame(target, frame_num, cur_pc, cur_fp)
- print_stack_frame(process, cur_fp)
- print ""
- if this_module is not None:
- module_list.append(this_module)
- return [module_list, address_list]
-
-
-def print_stack_frame(process, fp):
- if fp == 0 or fp == lldb.LLDB_INVALID_ADDRESS or fp == 1:
- return
- addr_size = process.GetAddressByteSize()
- addr = fp - (2 * addr_size)
- i = 0
- outline = "Stack frame from $fp-%d: " % (2 * addr_size)
- error = lldb.SBError()
- try:
- while i < 5 and error.Success():
- address = process.ReadPointerFromMemory(
- addr + (i * addr_size), error)
- outline += " 0x%x" % address
- i += 1
- print outline
- except Exception:
- return
-
-
-def diagnose_unwind(debugger, command, result, dict):
- """
- Gather diagnostic information to help debug incorrect unwind (backtrace)
- behavior in lldb. When there is a backtrace that doesn't look
- correct, run this command with the correct thread selected and a
- large amount of diagnostic information will be printed, it is likely
- to be helpful when reporting the problem.
- """
-
- command_args = shlex.split(command)
- parser = create_diagnose_unwind_options()
- try:
- (options, args) = parser.parse_args(command_args)
- except:
- return
- target = debugger.GetSelectedTarget()
- if target:
- process = target.GetProcess()
- if process:
- thread = process.GetSelectedThread()
- if thread:
- lldb_versions_match = re.search(
- r'[lL][lL][dD][bB]-(\d+)([.](\d+))?([.](\d+))?',
- debugger.GetVersionString())
- lldb_version = 0
- lldb_minor = 0
- if len(lldb_versions_match.groups()
- ) >= 1 and lldb_versions_match.groups()[0]:
- lldb_major = int(lldb_versions_match.groups()[0])
- if len(lldb_versions_match.groups()
- ) >= 5 and lldb_versions_match.groups()[4]:
- lldb_minor = int(lldb_versions_match.groups()[4])
-
- modules_seen = []
- addresses_seen = []
-
- print 'LLDB version %s' % debugger.GetVersionString()
- print 'Unwind diagnostics for thread %d' % thread.GetIndexID()
- print ""
- print "============================================================================================="
- print ""
- print "OS plugin setting:"
- debugger.HandleCommand(
- "settings show target.process.python-os-plugin-path")
- print ""
- print "Live register context:"
- thread.SetSelectedFrame(0)
- debugger.HandleCommand("register read")
- print ""
- print "============================================================================================="
- print ""
- print "lldb's unwind algorithm:"
- print ""
- frame_num = 0
- for frame in thread.frames:
- if not frame.IsInlined():
- this_module = backtrace_print_frame(
- target, frame_num, frame.GetPC(), frame.GetFP())
- print_stack_frame(process, frame.GetFP())
- print ""
- if this_module is not None:
- modules_seen.append(this_module)
- addresses_seen.append(frame.GetPC())
- frame_num = frame_num + 1
- print ""
- print "============================================================================================="
- print ""
- print "Simple stack walk algorithm:"
- print ""
- (module_list, address_list) = simple_backtrace(debugger)
- if module_list and module_list is not None:
- modules_seen += module_list
- if address_list and address_list is not None:
- addresses_seen = set(addresses_seen)
- addresses_seen.update(set(address_list))
-
- print ""
- print "============================================================================================="
- print ""
- print "Modules seen in stack walks:"
- print ""
- modules_already_seen = set()
- for module in modules_seen:
- if module is not None and module.GetFileSpec().GetFilename() is not None:
- if not module.GetFileSpec().GetFilename() in modules_already_seen:
- debugger.HandleCommand(
- 'image list %s' %
- module.GetFileSpec().GetFilename())
- modules_already_seen.add(
- module.GetFileSpec().GetFilename())
-
- print ""
- print "============================================================================================="
- print ""
- print "Disassembly ofaddresses seen in stack walks:"
- print ""
- additional_addresses_to_disassemble = addresses_seen
- for frame in thread.frames:
- if not frame.IsInlined():
- print "--------------------------------------------------------------------------------------"
- print ""
- print "Disassembly of %s, frame %d, address 0x%x" % (frame.GetFunctionName(), frame.GetFrameID(), frame.GetPC())
- print ""
- if target.triple[
- 0:6] == "x86_64" or target.triple[
- 0:4] == "i386":
- debugger.HandleCommand(
- 'disassemble -F att -a 0x%x' % frame.GetPC())
- else:
- debugger.HandleCommand(
- 'disassemble -a 0x%x' %
- frame.GetPC())
- if frame.GetPC() in additional_addresses_to_disassemble:
- additional_addresses_to_disassemble.remove(
- frame.GetPC())
-
- for address in list(additional_addresses_to_disassemble):
- print "--------------------------------------------------------------------------------------"
- print ""
- print "Disassembly of 0x%x" % address
- print ""
- if target.triple[
- 0:6] == "x86_64" or target.triple[
- 0:4] == "i386":
- debugger.HandleCommand(
- 'disassemble -F att -a 0x%x' % address)
- else:
- debugger.HandleCommand('disassemble -a 0x%x' % address)
-
- print ""
- print "============================================================================================="
- print ""
- additional_addresses_to_show_unwind = addresses_seen
- for frame in thread.frames:
- if not frame.IsInlined():
- print "--------------------------------------------------------------------------------------"
- print ""
- print "Unwind instructions for %s, frame %d" % (frame.GetFunctionName(), frame.GetFrameID())
- print ""
- debugger.HandleCommand(
- 'image show-unwind -a "0x%x"' % frame.GetPC())
- if frame.GetPC() in additional_addresses_to_show_unwind:
- additional_addresses_to_show_unwind.remove(
- frame.GetPC())
-
- for address in list(additional_addresses_to_show_unwind):
- print "--------------------------------------------------------------------------------------"
- print ""
- print "Unwind instructions for 0x%x" % address
- print ""
- debugger.HandleCommand(
- 'image show-unwind -a "0x%x"' % address)
-
-
-def create_diagnose_unwind_options():
- usage = "usage: %prog"
- description = '''Print diagnostic information about a thread backtrace which will help to debug unwind problems'''
- parser = optparse.OptionParser(
- description=description,
- prog='diagnose_unwind',
- usage=usage)
- return parser
-
-lldb.debugger.HandleCommand(
- 'command script add -f %s.diagnose_unwind diagnose-unwind' %
- __name__)
-print 'The "diagnose-unwind" command has been installed, type "help diagnose-unwind" for detailed help.'
diff --git a/examples/python/dict_utils.py b/examples/python/dict_utils.py
deleted file mode 100755
index 7cdd0ac6f3c2..000000000000
--- a/examples/python/dict_utils.py
+++ /dev/null
@@ -1,62 +0,0 @@
-
-class LookupDictionary(dict):
- """
- a dictionary which can lookup value by key, or keys by value
- """
-
- def __init__(self, items=[]):
- """items can be a list of pair_lists or a dictionary"""
- dict.__init__(self, items)
-
- def get_keys_for_value(self, value, fail_value=None):
- """find the key(s) as a list given a value"""
- list_result = [item[0] for item in self.items() if item[1] == value]
- if len(list_result) > 0:
- return list_result
- return fail_value
-
- def get_first_key_for_value(self, value, fail_value=None):
- """return the first key of this dictionary given the value"""
- list_result = [item[0] for item in self.items() if item[1] == value]
- if len(list_result) > 0:
- return list_result[0]
- return fail_value
-
- def get_value(self, key, fail_value=None):
- """find the value given a key"""
- if key in self:
- return self[key]
- return fail_value
-
-
-class Enum(LookupDictionary):
-
- def __init__(self, initial_value=0, items=[]):
- """items can be a list of pair_lists or a dictionary"""
- LookupDictionary.__init__(self, items)
- self.value = initial_value
-
- def set_value(self, v):
- v_typename = typeof(v).__name__
- if v_typename == 'str':
- if str in self:
- v = self[v]
- else:
- v = 0
- else:
- self.value = v
-
- def get_enum_value(self):
- return self.value
-
- def get_enum_name(self):
- return self.__str__()
-
- def __str__(self):
- s = self.get_first_key_for_value(self.value, None)
- if s is None:
- s = "%#8.8x" % self.value
- return s
-
- def __repr__(self):
- return self.__str__()
diff --git a/examples/python/disasm-stress-test.py b/examples/python/disasm-stress-test.py
deleted file mode 100755
index 2c20ffb92369..000000000000
--- a/examples/python/disasm-stress-test.py
+++ /dev/null
@@ -1,230 +0,0 @@
-#!/usr/bin/python
-
-import argparse
-import datetime
-import re
-import subprocess
-import sys
-import time
-
-parser = argparse.ArgumentParser(
- description="Run an exhaustive test of the LLDB disassembler for a specific architecture.")
-
-parser.add_argument(
- '--arch',
- required=True,
- action='store',
- help='The architecture whose disassembler is to be tested')
-parser.add_argument(
- '--bytes',
- required=True,
- action='store',
- type=int,
- help='The byte width of instructions for that architecture')
-parser.add_argument(
- '--random',
- required=False,
- action='store_true',
- help='Enables non-sequential testing')
-parser.add_argument(
- '--start',
- required=False,
- action='store',
- type=int,
- help='The first instruction value to test')
-parser.add_argument(
- '--skip',
- required=False,
- action='store',
- type=int,
- help='The interval between instructions to test')
-parser.add_argument(
- '--log',
- required=False,
- action='store',
- help='A log file to write the most recent instruction being tested')
-parser.add_argument(
- '--time',
- required=False,
- action='store_true',
- help='Every 100,000 instructions, print an ETA to standard out')
-parser.add_argument(
- '--lldb',
- required=False,
- action='store',
- help='The path to LLDB.framework, if LLDB should be overridden')
-
-arguments = sys.argv[1:]
-
-arg_ns = parser.parse_args(arguments)
-
-
-def AddLLDBToSysPathOnMacOSX():
- def GetLLDBFrameworkPath():
- lldb_path = subprocess.check_output(["xcrun", "-find", "lldb"])
- re_result = re.match("(.*)/Developer/usr/bin/lldb", lldb_path)
- if re_result is None:
- return None
- xcode_contents_path = re_result.group(1)
- return xcode_contents_path + "/SharedFrameworks/LLDB.framework"
-
- lldb_framework_path = GetLLDBFrameworkPath()
-
- if lldb_framework_path is None:
- print "Couldn't find LLDB.framework"
- sys.exit(-1)
-
- sys.path.append(lldb_framework_path + "/Resources/Python")
-
-if arg_ns.lldb is None:
- AddLLDBToSysPathOnMacOSX()
-else:
- sys.path.append(arg_ns.lldb + "/Resources/Python")
-
-import lldb
-
-debugger = lldb.SBDebugger.Create()
-
-if debugger.IsValid() == False:
- print "Couldn't create an SBDebugger"
- sys.exit(-1)
-
-target = debugger.CreateTargetWithFileAndArch(None, arg_ns.arch)
-
-if target.IsValid() == False:
- print "Couldn't create an SBTarget for architecture " + arg_ns.arch
- sys.exit(-1)
-
-
-def ResetLogFile(log_file):
- if log_file != sys.stdout:
- log_file.seek(0)
-
-
-def PrintByteArray(log_file, byte_array):
- for byte in byte_array:
- print >>log_file, hex(byte) + " ",
- print >>log_file
-
-
-class SequentialInstructionProvider:
-
- def __init__(self, byte_width, log_file, start=0, skip=1):
- self.m_byte_width = byte_width
- self.m_log_file = log_file
- self.m_start = start
- self.m_skip = skip
- self.m_value = start
- self.m_last = (1 << (byte_width * 8)) - 1
-
- def PrintCurrentState(self, ret):
- ResetLogFile(self.m_log_file)
- print >>self.m_log_file, self.m_value
- PrintByteArray(self.m_log_file, ret)
-
- def GetNextInstruction(self):
- if self.m_value > self.m_last:
- return None
- ret = bytearray(self.m_byte_width)
- for i in range(self.m_byte_width):
- ret[self.m_byte_width - (i + 1)] = (self.m_value >> (i * 8)) & 255
- self.PrintCurrentState(ret)
- self.m_value += self.m_skip
- return ret
-
- def GetNumInstructions(self):
- return (self.m_last - self.m_start) / self.m_skip
-
- def __iter__(self):
- return self
-
- def next(self):
- ret = self.GetNextInstruction()
- if ret is None:
- raise StopIteration
- return ret
-
-
-class RandomInstructionProvider:
-
- def __init__(self, byte_width, log_file):
- self.m_byte_width = byte_width
- self.m_log_file = log_file
- self.m_random_file = open("/dev/random", 'r')
-
- def PrintCurrentState(self, ret):
- ResetLogFile(self.m_log_file)
- PrintByteArray(self.m_log_file, ret)
-
- def GetNextInstruction(self):
- ret = bytearray(self.m_byte_width)
- for i in range(self.m_byte_width):
- ret[i] = self.m_random_file.read(1)
- self.PrintCurrentState(ret)
- return ret
-
- def __iter__(self):
- return self
-
- def next(self):
- ret = self.GetNextInstruction()
- if ret is None:
- raise StopIteration
- return ret
-
-log_file = None
-
-
-def GetProviderWithArguments(args):
- global log_file
- if args.log is not None:
- log_file = open(args.log, 'w')
- else:
- log_file = sys.stdout
- instruction_provider = None
- if args.random:
- instruction_provider = RandomInstructionProvider(args.bytes, log_file)
- else:
- start = 0
- skip = 1
- if args.start is not None:
- start = args.start
- if args.skip is not None:
- skip = args.skip
- instruction_provider = SequentialInstructionProvider(
- args.bytes, log_file, start, skip)
- return instruction_provider
-
-instruction_provider = GetProviderWithArguments(arg_ns)
-
-fake_address = lldb.SBAddress()
-
-actually_time = arg_ns.time and not arg_ns.random
-
-if actually_time:
- num_instructions_logged = 0
- total_num_instructions = instruction_provider.GetNumInstructions()
- start_time = time.time()
-
-for inst_bytes in instruction_provider:
- if actually_time:
- if (num_instructions_logged != 0) and (
- num_instructions_logged % 100000 == 0):
- curr_time = time.time()
- elapsed_time = curr_time - start_time
- remaining_time = float(
- total_num_instructions - num_instructions_logged) * (
- float(elapsed_time) / float(num_instructions_logged))
- print str(datetime.timedelta(seconds=remaining_time))
- num_instructions_logged = num_instructions_logged + 1
- inst_list = target.GetInstructions(fake_address, inst_bytes)
- if not inst_list.IsValid():
- print >>log_file, "Invalid instruction list"
- continue
- inst = inst_list.GetInstructionAtIndex(0)
- if not inst.IsValid():
- print >>log_file, "Invalid instruction"
- continue
- instr_output_stream = lldb.SBStream()
- inst.GetDescription(instr_output_stream)
- print >>log_file, instr_output_stream.GetData()
diff --git a/examples/python/disasm.py b/examples/python/disasm.py
deleted file mode 100755
index af024a6887da..000000000000
--- a/examples/python/disasm.py
+++ /dev/null
@@ -1,126 +0,0 @@
-#!/usr/bin/python
-
-#----------------------------------------------------------------------
-# Be sure to add the python path that points to the LLDB shared library.
-# On MacOSX csh, tcsh:
-# setenv PYTHONPATH /Developer/Library/PrivateFrameworks/LLDB.framework/Resources/Python
-# On MacOSX sh, bash:
-# export PYTHONPATH=/Developer/Library/PrivateFrameworks/LLDB.framework/Resources/Python
-#----------------------------------------------------------------------
-
-import lldb
-import os
-import sys
-
-
-def disassemble_instructions(insts):
- for i in insts:
- print i
-
-
-def usage():
- print "Usage: disasm.py [-n name] executable-image"
- print " By default, it breaks at and disassembles the 'main' function."
- sys.exit(0)
-
-if len(sys.argv) == 2:
- fname = 'main'
- exe = sys.argv[1]
-elif len(sys.argv) == 4:
- if sys.argv[1] != '-n':
- usage()
- else:
- fname = sys.argv[2]
- exe = sys.argv[3]
-else:
- usage()
-
-# Create a new debugger instance
-debugger = lldb.SBDebugger.Create()
-
-# When we step or continue, don't return from the function until the process
-# stops. We do this by setting the async mode to false.
-debugger.SetAsync(False)
-
-# Create a target from a file and arch
-print "Creating a target for '%s'" % exe
-
-target = debugger.CreateTargetWithFileAndArch(exe, lldb.LLDB_ARCH_DEFAULT)
-
-if target:
- # If the target is valid set a breakpoint at main
- main_bp = target.BreakpointCreateByName(
- fname, target.GetExecutable().GetFilename())
-
- print main_bp
-
- # Launch the process. Since we specified synchronous mode, we won't return
- # from this function until we hit the breakpoint at main
- process = target.LaunchSimple(None, None, os.getcwd())
-
- # Make sure the launch went ok
- if process:
- # Print some simple process info
- state = process.GetState()
- print process
- if state == lldb.eStateStopped:
- # Get the first thread
- thread = process.GetThreadAtIndex(0)
- if thread:
- # Print some simple thread info
- print thread
- # Get the first frame
- frame = thread.GetFrameAtIndex(0)
- if frame:
- # Print some simple frame info
- print frame
- function = frame.GetFunction()
- # See if we have debug info (a function)
- if function:
- # We do have a function, print some info for the
- # function
- print function
- # Now get all instructions for this function and print
- # them
- insts = function.GetInstructions(target)
- disassemble_instructions(insts)
- else:
- # See if we have a symbol in the symbol table for where
- # we stopped
- symbol = frame.GetSymbol()
- if symbol:
- # We do have a symbol, print some info for the
- # symbol
- print symbol
- # Now get all instructions for this symbol and
- # print them
- insts = symbol.GetInstructions(target)
- disassemble_instructions(insts)
-
- registerList = frame.GetRegisters()
- print "Frame registers (size of register set = %d):" % registerList.GetSize()
- for value in registerList:
- # print value
- print "%s (number of children = %d):" % (value.GetName(), value.GetNumChildren())
- for child in value:
- print "Name: ", child.GetName(), " Value: ", child.GetValue()
-
- print "Hit the breakpoint at main, enter to continue and wait for program to exit or 'Ctrl-D'/'quit' to terminate the program"
- next = sys.stdin.readline()
- if not next or next.rstrip('\n') == 'quit':
- print "Terminating the inferior process..."
- process.Kill()
- else:
- # Now continue to the program exit
- process.Continue()
- # When we return from the above function we will hopefully be at the
- # program exit. Print out some process info
- print process
- elif state == lldb.eStateExited:
- print "Didn't hit the breakpoint at main, program has exited..."
- else:
- print "Unexpected process state: %s, killing process..." % debugger.StateAsCString(state)
- process.Kill()
-
-
-lldb.SBDebugger.Terminate()
diff --git a/examples/python/disassembly_mode.py b/examples/python/disassembly_mode.py
deleted file mode 100644
index 19647cc6555e..000000000000
--- a/examples/python/disassembly_mode.py
+++ /dev/null
@@ -1,48 +0,0 @@
-""" Adds the 'toggle-disassembly' command to switch you into a disassembly only mode """
-import lldb
-
-class DisassemblyMode:
- def __init__(self, debugger, unused):
- self.dbg = debugger
- self.interp = debugger.GetCommandInterpreter()
- self.store_state()
- self.mode_off = True
-
- def store_state(self):
- self.dis_count = self.get_string_value("stop-disassembly-count")
- self.dis_display = self.get_string_value("stop-disassembly-display")
- self.before_count = self.get_string_value("stop-line-count-before")
- self.after_count = self.get_string_value("stop-line-count-after")
-
- def get_string_value(self, setting):
- result = lldb.SBCommandReturnObject()
- self.interp.HandleCommand("settings show " + setting, result)
- value = result.GetOutput().split(" = ")[1].rstrip("\n")
- return value
-
- def set_value(self, setting, value):
- result = lldb.SBCommandReturnObject()
- self.interp.HandleCommand("settings set " + setting + " " + value, result)
-
- def __call__(self, debugger, command, exe_ctx, result):
- if self.mode_off:
- self.mode_off = False
- self.store_state()
- self.set_value("stop-disassembly-display","always")
- self.set_value("stop-disassembly-count", "8")
- self.set_value("stop-line-count-before", "0")
- self.set_value("stop-line-count-after", "0")
- result.AppendMessage("Disassembly mode on.")
- else:
- self.mode_off = True
- self.set_value("stop-disassembly-display",self.dis_display)
- self.set_value("stop-disassembly-count", self.dis_count)
- self.set_value("stop-line-count-before", self.before_count)
- self.set_value("stop-line-count-after", self.after_count)
- result.AppendMessage("Disassembly mode off.")
-
- def get_short_help(self):
- return "Toggles between a disassembly only mode and normal source mode\n"
-
-def __lldb_init_module(debugger, unused):
- debugger.HandleCommand("command script add -c disassembly_mode.DisassemblyMode toggle-disassembly")
diff --git a/examples/python/file_extract.py b/examples/python/file_extract.py
deleted file mode 100755
index 7a617e911068..000000000000
--- a/examples/python/file_extract.py
+++ /dev/null
@@ -1,226 +0,0 @@
-#! /usr/bin/env python
-
-import string
-import struct
-import sys
-
-
-class FileExtract:
- '''Decode binary data from a file'''
-
- def __init__(self, f, b='='):
- '''Initialize with an open binary file and optional byte order'''
-
- self.file = f
- self.byte_order = b
- self.offsets = list()
-
- def set_byte_order(self, b):
- '''Set the byte order, valid values are "big", "little", "swap", "native", "<", ">", "@", "="'''
- if b == 'big':
- self.byte_order = '>'
- elif b == 'little':
- self.byte_order = '<'
- elif b == 'swap':
- # swap what ever the current byte order is
- self.byte_order = swap_unpack_char()
- elif b == 'native':
- self.byte_order = '='
- elif b == '<' or b == '>' or b == '@' or b == '=':
- self.byte_order = b
- else:
- print "error: invalid byte order specified: '%s'" % b
-
- def is_in_memory(self):
- return False
-
- def seek(self, offset, whence=0):
- if self.file:
- return self.file.seek(offset, whence)
- raise ValueError
-
- def tell(self):
- if self.file:
- return self.file.tell()
- raise ValueError
-
- def read_size(self, byte_size):
- s = self.file.read(byte_size)
- if len(s) != byte_size:
- return None
- return s
-
- def push_offset_and_seek(self, offset):
- '''Push the current file offset and seek to "offset"'''
- self.offsets.append(self.file.tell())
- self.file.seek(offset, 0)
-
- def pop_offset_and_seek(self):
- '''Pop a previously pushed file offset, or do nothing if there were no previously pushed offsets'''
- if len(self.offsets) > 0:
- self.file.seek(self.offsets.pop())
-
- def get_sint8(self, fail_value=0):
- '''Extract a single int8_t from the binary file at the current file position, returns a single integer'''
- s = self.read_size(1)
- if s:
- v, = struct.unpack(self.byte_order + 'b', s)
- return v
- else:
- return fail_value
-
- def get_uint8(self, fail_value=0):
- '''Extract a single uint8_t from the binary file at the current file position, returns a single integer'''
- s = self.read_size(1)
- if s:
- v, = struct.unpack(self.byte_order + 'B', s)
- return v
- else:
- return fail_value
-
- def get_sint16(self, fail_value=0):
- '''Extract a single int16_t from the binary file at the current file position, returns a single integer'''
- s = self.read_size(2)
- if s:
- v, = struct.unpack(self.byte_order + 'h', s)
- return v
- else:
- return fail_value
-
- def get_uint16(self, fail_value=0):
- '''Extract a single uint16_t from the binary file at the current file position, returns a single integer'''
- s = self.read_size(2)
- if s:
- v, = struct.unpack(self.byte_order + 'H', s)
- return v
- else:
- return fail_value
-
- def get_sint32(self, fail_value=0):
- '''Extract a single int32_t from the binary file at the current file position, returns a single integer'''
- s = self.read_size(4)
- if s:
- v, = struct.unpack(self.byte_order + 'i', s)
- return v
- else:
- return fail_value
-
- def get_uint32(self, fail_value=0):
- '''Extract a single uint32_t from the binary file at the current file position, returns a single integer'''
- s = self.read_size(4)
- if s:
- v, = struct.unpack(self.byte_order + 'I', s)
- return v
- else:
- return fail_value
-
- def get_sint64(self, fail_value=0):
- '''Extract a single int64_t from the binary file at the current file position, returns a single integer'''
- s = self.read_size(8)
- if s:
- v, = struct.unpack(self.byte_order + 'q', s)
- return v
- else:
- return fail_value
-
- def get_uint64(self, fail_value=0):
- '''Extract a single uint64_t from the binary file at the current file position, returns a single integer'''
- s = self.read_size(8)
- if s:
- v, = struct.unpack(self.byte_order + 'Q', s)
- return v
- else:
- return fail_value
-
- def get_fixed_length_c_string(
- self,
- n,
- fail_value='',
- isprint_only_with_space_padding=False):
- '''Extract a single fixed length C string from the binary file at the current file position, returns a single C string'''
- s = self.read_size(n)
- if s:
- cstr, = struct.unpack(self.byte_order + ("%i" % n) + 's', s)
- # Strip trialing NULLs
- cstr = string.strip(cstr, "\0")
- if isprint_only_with_space_padding:
- for c in cstr:
- if c in string.printable or ord(c) == 0:
- continue
- return fail_value
- return cstr
- else:
- return fail_value
-
- def get_c_string(self):
- '''Extract a single NULL terminated C string from the binary file at the current file position, returns a single C string'''
- cstr = ''
- byte = self.get_uint8()
- while byte != 0:
- cstr += "%c" % byte
- byte = self.get_uint8()
- return cstr
-
- def get_n_sint8(self, n, fail_value=0):
- '''Extract "n" int8_t integers from the binary file at the current file position, returns a list of integers'''
- s = self.read_size(n)
- if s:
- return struct.unpack(self.byte_order + ("%u" % n) + 'b', s)
- else:
- return (fail_value,) * n
-
- def get_n_uint8(self, n, fail_value=0):
- '''Extract "n" uint8_t integers from the binary file at the current file position, returns a list of integers'''
- s = self.read_size(n)
- if s:
- return struct.unpack(self.byte_order + ("%u" % n) + 'B', s)
- else:
- return (fail_value,) * n
-
- def get_n_sint16(self, n, fail_value=0):
- '''Extract "n" int16_t integers from the binary file at the current file position, returns a list of integers'''
- s = self.read_size(2 * n)
- if s:
- return struct.unpack(self.byte_order + ("%u" % n) + 'h', s)
- else:
- return (fail_value,) * n
-
- def get_n_uint16(self, n, fail_value=0):
- '''Extract "n" uint16_t integers from the binary file at the current file position, returns a list of integers'''
- s = self.read_size(2 * n)
- if s:
- return struct.unpack(self.byte_order + ("%u" % n) + 'H', s)
- else:
- return (fail_value,) * n
-
- def get_n_sint32(self, n, fail_value=0):
- '''Extract "n" int32_t integers from the binary file at the current file position, returns a list of integers'''
- s = self.read_size(4 * n)
- if s:
- return struct.unpack(self.byte_order + ("%u" % n) + 'i', s)
- else:
- return (fail_value,) * n
-
- def get_n_uint32(self, n, fail_value=0):
- '''Extract "n" uint32_t integers from the binary file at the current file position, returns a list of integers'''
- s = self.read_size(4 * n)
- if s:
- return struct.unpack(self.byte_order + ("%u" % n) + 'I', s)
- else:
- return (fail_value,) * n
-
- def get_n_sint64(self, n, fail_value=0):
- '''Extract "n" int64_t integers from the binary file at the current file position, returns a list of integers'''
- s = self.read_size(8 * n)
- if s:
- return struct.unpack(self.byte_order + ("%u" % n) + 'q', s)
- else:
- return (fail_value,) * n
-
- def get_n_uint64(self, n, fail_value=0):
- '''Extract "n" uint64_t integers from the binary file at the current file position, returns a list of integers'''
- s = self.read_size(8 * n)
- if s:
- return struct.unpack(self.byte_order + ("%u" % n) + 'Q', s)
- else:
- return (fail_value,) * n
diff --git a/examples/python/gdb_disassemble.py b/examples/python/gdb_disassemble.py
deleted file mode 100755
index 2590aba8c85c..000000000000
--- a/examples/python/gdb_disassemble.py
+++ /dev/null
@@ -1,26 +0,0 @@
-import lldb
-
-
-def disassemble(debugger, command, result, dict):
- if lldb.frame.function:
- instructions = lldb.frame.function.instructions
- start_addr = lldb.frame.function.addr.load_addr
- name = lldb.frame.function.name
- elif lldb.frame.symbol:
- instructions = lldb.frame.symbol.instructions
- start_addr = lldb.frame.symbol.addr.load_addr
- name = lldb.frame.symbol.name
-
- for inst in instructions:
- inst_addr = inst.addr.load_addr
- inst_offset = inst_addr - start_addr
- comment = inst.comment
- if comment:
- print "<%s + %-4u> 0x%x %8s %s ; %s" % (name, inst_offset, inst_addr, inst.mnemonic, inst.operands, comment)
- else:
- print "<%s + %-4u> 0x%x %8s %s" % (name, inst_offset, inst_addr, inst.mnemonic, inst.operands)
-
-# Install the command when the module gets imported
-lldb.debugger.HandleCommand(
- 'command script add -f gdb_disassemble.disassemble gdb-disassemble')
-print 'Installed "gdb-disassemble" command for disassembly'
diff --git a/examples/python/gdbremote.py b/examples/python/gdbremote.py
deleted file mode 100755
index 4ca8a1b82e84..000000000000
--- a/examples/python/gdbremote.py
+++ /dev/null
@@ -1,1630 +0,0 @@
-#!/usr/bin/python
-
-#----------------------------------------------------------------------
-# This module will enable GDB remote packet logging when the
-# 'start_gdb_log' command is called with a filename to log to. When the
-# 'stop_gdb_log' command is called, it will disable the logging and
-# print out statistics about how long commands took to execute and also
-# will primnt ou
-# Be sure to add the python path that points to the LLDB shared library.
-#
-# To use this in the embedded python interpreter using "lldb" just
-# import it with the full path using the "command script import"
-# command. This can be done from the LLDB command line:
-# (lldb) command script import /path/to/gdbremote.py
-# Or it can be added to your ~/.lldbinit file so this module is always
-# available.
-#----------------------------------------------------------------------
-
-import binascii
-import commands
-import json
-import math
-import optparse
-import os
-import re
-import shlex
-import string
-import sys
-import tempfile
-import xml.etree.ElementTree as ET
-
-#----------------------------------------------------------------------
-# Global variables
-#----------------------------------------------------------------------
-g_log_file = ''
-g_byte_order = 'little'
-g_number_regex = re.compile('^(0x[0-9a-fA-F]+|[0-9]+)')
-g_thread_id_regex = re.compile('^(-1|[0-9a-fA-F]+|0)')
-
-
-class TerminalColors:
- '''Simple terminal colors class'''
-
- def __init__(self, enabled=True):
- # TODO: discover terminal type from "file" and disable if
- # it can't handle the color codes
- self.enabled = enabled
-
- def reset(self):
- '''Reset all terminal colors and formatting.'''
- if self.enabled:
- return "\x1b[0m"
- return ''
-
- def bold(self, on=True):
- '''Enable or disable bold depending on the "on" parameter.'''
- if self.enabled:
- if on:
- return "\x1b[1m"
- else:
- return "\x1b[22m"
- return ''
-
- def italics(self, on=True):
- '''Enable or disable italics depending on the "on" parameter.'''
- if self.enabled:
- if on:
- return "\x1b[3m"
- else:
- return "\x1b[23m"
- return ''
-
- def underline(self, on=True):
- '''Enable or disable underline depending on the "on" parameter.'''
- if self.enabled:
- if on:
- return "\x1b[4m"
- else:
- return "\x1b[24m"
- return ''
-
- def inverse(self, on=True):
- '''Enable or disable inverse depending on the "on" parameter.'''
- if self.enabled:
- if on:
- return "\x1b[7m"
- else:
- return "\x1b[27m"
- return ''
-
- def strike(self, on=True):
- '''Enable or disable strike through depending on the "on" parameter.'''
- if self.enabled:
- if on:
- return "\x1b[9m"
- else:
- return "\x1b[29m"
- return ''
-
- def black(self, fg=True):
- '''Set the foreground or background color to black.
- The foreground color will be set if "fg" tests True. The background color will be set if "fg" tests False.'''
- if self.enabled:
- if fg:
- return "\x1b[30m"
- else:
- return "\x1b[40m"
- return ''
-
- def red(self, fg=True):
- '''Set the foreground or background color to red.
- The foreground color will be set if "fg" tests True. The background color will be set if "fg" tests False.'''
- if self.enabled:
- if fg:
- return "\x1b[31m"
- else:
- return "\x1b[41m"
- return ''
-
- def green(self, fg=True):
- '''Set the foreground or background color to green.
- The foreground color will be set if "fg" tests True. The background color will be set if "fg" tests False.'''
- if self.enabled:
- if fg:
- return "\x1b[32m"
- else:
- return "\x1b[42m"
- return ''
-
- def yellow(self, fg=True):
- '''Set the foreground or background color to yellow.
- The foreground color will be set if "fg" tests True. The background color will be set if "fg" tests False.'''
- if self.enabled:
- if fg:
- return "\x1b[33m"
- else:
- return "\x1b[43m"
- return ''
-
- def blue(self, fg=True):
- '''Set the foreground or background color to blue.
- The foreground color will be set if "fg" tests True. The background color will be set if "fg" tests False.'''
- if self.enabled:
- if fg:
- return "\x1b[34m"
- else:
- return "\x1b[44m"
- return ''
-
- def magenta(self, fg=True):
- '''Set the foreground or background color to magenta.
- The foreground color will be set if "fg" tests True. The background color will be set if "fg" tests False.'''
- if self.enabled:
- if fg:
- return "\x1b[35m"
- else:
- return "\x1b[45m"
- return ''
-
- def cyan(self, fg=True):
- '''Set the foreground or background color to cyan.
- The foreground color will be set if "fg" tests True. The background color will be set if "fg" tests False.'''
- if self.enabled:
- if fg:
- return "\x1b[36m"
- else:
- return "\x1b[46m"
- return ''
-
- def white(self, fg=True):
- '''Set the foreground or background color to white.
- The foreground color will be set if "fg" tests True. The background color will be set if "fg" tests False.'''
- if self.enabled:
- if fg:
- return "\x1b[37m"
- else:
- return "\x1b[47m"
- return ''
-
- def default(self, fg=True):
- '''Set the foreground or background color to the default.
- The foreground color will be set if "fg" tests True. The background color will be set if "fg" tests False.'''
- if self.enabled:
- if fg:
- return "\x1b[39m"
- else:
- return "\x1b[49m"
- return ''
-
-
-def start_gdb_log(debugger, command, result, dict):
- '''Start logging GDB remote packets by enabling logging with timestamps and
- thread safe logging. Follow a call to this function with a call to "stop_gdb_log"
- in order to dump out the commands.'''
- global g_log_file
- command_args = shlex.split(command)
- usage = "usage: start_gdb_log [options] [<LOGFILEPATH>]"
- description = '''The command enables GDB remote packet logging with timestamps. The packets will be logged to <LOGFILEPATH> if supplied, or a temporary file will be used. Logging stops when stop_gdb_log is called and the packet times will
- be aggregated and displayed.'''
- parser = optparse.OptionParser(
- description=description,
- prog='start_gdb_log',
- usage=usage)
- parser.add_option(
- '-v',
- '--verbose',
- action='store_true',
- dest='verbose',
- help='display verbose debug info',
- default=False)
- try:
- (options, args) = parser.parse_args(command_args)
- except:
- return
-
- if g_log_file:
- result.PutCString(
- 'error: logging is already in progress with file "%s"' %
- g_log_file)
- else:
- args_len = len(args)
- if args_len == 0:
- g_log_file = tempfile.mktemp()
- elif len(args) == 1:
- g_log_file = args[0]
-
- if g_log_file:
- debugger.HandleCommand(
- 'log enable --threadsafe --timestamp --file "%s" gdb-remote packets' %
- g_log_file)
- result.PutCString(
- "GDB packet logging enable with log file '%s'\nUse the 'stop_gdb_log' command to stop logging and show packet statistics." %
- g_log_file)
- return
-
- result.PutCString('error: invalid log file path')
- result.PutCString(usage)
-
-
-def stop_gdb_log(debugger, command, result, dict):
- '''Stop logging GDB remote packets to the file that was specified in a call
- to "start_gdb_log" and normalize the timestamps to be relative to the first
- timestamp in the log file. Also print out statistics for how long each
- command took to allow performance bottlenecks to be determined.'''
- global g_log_file
- # Any commands whose names might be followed by more valid C identifier
- # characters must be listed here
- command_args = shlex.split(command)
- usage = "usage: stop_gdb_log [options]"
- description = '''The command stops a previously enabled GDB remote packet logging command. Packet logging must have been previously enabled with a call to start_gdb_log.'''
- parser = optparse.OptionParser(
- description=description,
- prog='stop_gdb_log',
- usage=usage)
- parser.add_option(
- '-v',
- '--verbose',
- action='store_true',
- dest='verbose',
- help='display verbose debug info',
- default=False)
- parser.add_option(
- '-q',
- '--quiet',
- action='store_true',
- dest='quiet',
- help='display verbose debug info',
- default=False)
- parser.add_option(
- '-C',
- '--color',
- action='store_true',
- dest='color',
- help='add terminal colors',
- default=False)
- parser.add_option(
- '-c',
- '--sort-by-count',
- action='store_true',
- dest='sort_count',
- help='display verbose debug info',
- default=False)
- parser.add_option(
- '-s',
- '--symbolicate',
- action='store_true',
- dest='symbolicate',
- help='symbolicate addresses in log using current "lldb.target"',
- default=False)
- try:
- (options, args) = parser.parse_args(command_args)
- except:
- return
- options.colors = TerminalColors(options.color)
- options.symbolicator = None
- if options.symbolicate:
- if lldb.target:
- import lldb.utils.symbolication
- options.symbolicator = lldb.utils.symbolication.Symbolicator()
- options.symbolicator.target = lldb.target
- else:
- print "error: can't symbolicate without a target"
-
- if not g_log_file:
- result.PutCString(
- 'error: logging must have been previously enabled with a call to "stop_gdb_log"')
- elif os.path.exists(g_log_file):
- if len(args) == 0:
- debugger.HandleCommand('log disable gdb-remote packets')
- result.PutCString(
- "GDB packet logging disabled. Logged packets are in '%s'" %
- g_log_file)
- parse_gdb_log_file(g_log_file, options)
- else:
- result.PutCString(usage)
- else:
- print 'error: the GDB packet log file "%s" does not exist' % g_log_file
-
-
-def is_hex_byte(str):
- if len(str) == 2:
- return str[0] in string.hexdigits and str[1] in string.hexdigits
- return False
-
-def get_hex_string_if_all_printable(str):
- try:
- s = binascii.unhexlify(str)
- if all(c in string.printable for c in s):
- return s
- except TypeError:
- pass
- return None
-
-# global register info list
-g_register_infos = list()
-g_max_register_info_name_len = 0
-
-
-class RegisterInfo:
- """Class that represents register information"""
-
- def __init__(self, kvp):
- self.info = dict()
- for kv in kvp:
- key = kv[0]
- value = kv[1]
- self.info[key] = value
-
- def name(self):
- '''Get the name of the register.'''
- if self.info and 'name' in self.info:
- return self.info['name']
- return None
-
- def bit_size(self):
- '''Get the size in bits of the register.'''
- if self.info and 'bitsize' in self.info:
- return int(self.info['bitsize'])
- return 0
-
- def byte_size(self):
- '''Get the size in bytes of the register.'''
- return self.bit_size() / 8
-
- def get_value_from_hex_string(self, hex_str):
- '''Dump the register value given a native byte order encoded hex ASCII byte string.'''
- encoding = self.info['encoding']
- bit_size = self.bit_size()
- packet = Packet(hex_str)
- if encoding == 'uint':
- uval = packet.get_hex_uint(g_byte_order)
- if bit_size == 8:
- return '0x%2.2x' % (uval)
- elif bit_size == 16:
- return '0x%4.4x' % (uval)
- elif bit_size == 32:
- return '0x%8.8x' % (uval)
- elif bit_size == 64:
- return '0x%16.16x' % (uval)
- bytes = list()
- uval = packet.get_hex_uint8()
- while uval is not None:
- bytes.append(uval)
- uval = packet.get_hex_uint8()
- value_str = '0x'
- if g_byte_order == 'little':
- bytes.reverse()
- for byte in bytes:
- value_str += '%2.2x' % byte
- return '%s' % (value_str)
-
- def __str__(self):
- '''Dump the register info key/value pairs'''
- s = ''
- for key in self.info.keys():
- if s:
- s += ', '
- s += "%s=%s " % (key, self.info[key])
- return s
-
-
-class Packet:
- """Class that represents a packet that contains string data"""
-
- def __init__(self, packet_str):
- self.str = packet_str
-
- def peek_char(self):
- ch = 0
- if self.str:
- ch = self.str[0]
- return ch
-
- def get_char(self):
- ch = 0
- if self.str:
- ch = self.str[0]
- self.str = self.str[1:]
- return ch
-
- def skip_exact_string(self, s):
- if self.str and self.str.startswith(s):
- self.str = self.str[len(s):]
- return True
- else:
- return False
-
- def get_thread_id(self, fail_value=-1):
- match = g_number_regex.match(self.str)
- if match:
- number_str = match.group(1)
- self.str = self.str[len(number_str):]
- return int(number_str, 0)
- else:
- return fail_value
-
- def get_hex_uint8(self):
- if self.str and len(self.str) >= 2 and self.str[
- 0] in string.hexdigits and self.str[1] in string.hexdigits:
- uval = int(self.str[0:2], 16)
- self.str = self.str[2:]
- return uval
- return None
-
- def get_hex_uint16(self, byte_order):
- uval = 0
- if byte_order == 'big':
- uval |= self.get_hex_uint8() << 8
- uval |= self.get_hex_uint8()
- else:
- uval |= self.get_hex_uint8()
- uval |= self.get_hex_uint8() << 8
- return uval
-
- def get_hex_uint32(self, byte_order):
- uval = 0
- if byte_order == 'big':
- uval |= self.get_hex_uint8() << 24
- uval |= self.get_hex_uint8() << 16
- uval |= self.get_hex_uint8() << 8
- uval |= self.get_hex_uint8()
- else:
- uval |= self.get_hex_uint8()
- uval |= self.get_hex_uint8() << 8
- uval |= self.get_hex_uint8() << 16
- uval |= self.get_hex_uint8() << 24
- return uval
-
- def get_hex_uint64(self, byte_order):
- uval = 0
- if byte_order == 'big':
- uval |= self.get_hex_uint8() << 56
- uval |= self.get_hex_uint8() << 48
- uval |= self.get_hex_uint8() << 40
- uval |= self.get_hex_uint8() << 32
- uval |= self.get_hex_uint8() << 24
- uval |= self.get_hex_uint8() << 16
- uval |= self.get_hex_uint8() << 8
- uval |= self.get_hex_uint8()
- else:
- uval |= self.get_hex_uint8()
- uval |= self.get_hex_uint8() << 8
- uval |= self.get_hex_uint8() << 16
- uval |= self.get_hex_uint8() << 24
- uval |= self.get_hex_uint8() << 32
- uval |= self.get_hex_uint8() << 40
- uval |= self.get_hex_uint8() << 48
- uval |= self.get_hex_uint8() << 56
- return uval
-
- def get_number(self, fail_value=-1):
- '''Get a number from the packet. The number must be in big endian format and should be parsed
- according to its prefix (starts with "0x" means hex, starts with "0" means octal, starts with
- [1-9] means decimal, etc)'''
- match = g_number_regex.match(self.str)
- if match:
- number_str = match.group(1)
- self.str = self.str[len(number_str):]
- return int(number_str, 0)
- else:
- return fail_value
-
- def get_hex_ascii_str(self, n=0):
- hex_chars = self.get_hex_chars(n)
- if hex_chars:
- return binascii.unhexlify(hex_chars)
- else:
- return None
-
- def get_hex_chars(self, n=0):
- str_len = len(self.str)
- if n == 0:
- # n was zero, so we need to determine all hex chars and
- # stop when we hit the end of the string of a non-hex character
- while n < str_len and self.str[n] in string.hexdigits:
- n = n + 1
- else:
- if n > str_len:
- return None # Not enough chars
- # Verify all chars are hex if a length was specified
- for i in range(n):
- if self.str[i] not in string.hexdigits:
- return None # Not all hex digits
- if n == 0:
- return None
- hex_str = self.str[0:n]
- self.str = self.str[n:]
- return hex_str
-
- def get_hex_uint(self, byte_order, n=0):
- if byte_order == 'big':
- hex_str = self.get_hex_chars(n)
- if hex_str is None:
- return None
- return int(hex_str, 16)
- else:
- uval = self.get_hex_uint8()
- if uval is None:
- return None
- uval_result = 0
- shift = 0
- while uval is not None:
- uval_result |= (uval << shift)
- shift += 8
- uval = self.get_hex_uint8()
- return uval_result
-
- def get_key_value_pairs(self):
- kvp = list()
- if ';' in self.str:
- key_value_pairs = string.split(self.str, ';')
- for key_value_pair in key_value_pairs:
- if len(key_value_pair):
- kvp.append(string.split(key_value_pair, ':'))
- return kvp
-
- def split(self, ch):
- return string.split(self.str, ch)
-
- def split_hex(self, ch, byte_order):
- hex_values = list()
- strings = string.split(self.str, ch)
- for str in strings:
- hex_values.append(Packet(str).get_hex_uint(byte_order))
- return hex_values
-
- def __str__(self):
- return self.str
-
- def __len__(self):
- return len(self.str)
-
-g_thread_suffix_regex = re.compile(';thread:([0-9a-fA-F]+);')
-
-
-def get_thread_from_thread_suffix(str):
- if str:
- match = g_thread_suffix_regex.match(str)
- if match:
- return int(match.group(1), 16)
- return None
-
-
-def cmd_qThreadStopInfo(options, cmd, args):
- packet = Packet(args)
- tid = packet.get_hex_uint('big')
- print "get_thread_stop_info (tid = 0x%x)" % (tid)
-
-
-def cmd_stop_reply(options, cmd, args):
- print "get_last_stop_info()"
- return False
-
-
-def rsp_stop_reply(options, cmd, cmd_args, rsp):
- global g_byte_order
- packet = Packet(rsp)
- stop_type = packet.get_char()
- if stop_type == 'T' or stop_type == 'S':
- signo = packet.get_hex_uint8()
- key_value_pairs = packet.get_key_value_pairs()
- for key_value_pair in key_value_pairs:
- key = key_value_pair[0]
- if is_hex_byte(key):
- reg_num = Packet(key).get_hex_uint8()
- if reg_num < len(g_register_infos):
- reg_info = g_register_infos[reg_num]
- key_value_pair[0] = reg_info.name()
- key_value_pair[1] = reg_info.get_value_from_hex_string(
- key_value_pair[1])
- elif key == 'jthreads' or key == 'jstopinfo':
- key_value_pair[1] = binascii.unhexlify(key_value_pair[1])
- key_value_pairs.insert(0, ['signal', signo])
- print 'stop_reply():'
- dump_key_value_pairs(key_value_pairs)
- elif stop_type == 'W':
- exit_status = packet.get_hex_uint8()
- print 'stop_reply(): exit (status=%i)' % exit_status
- elif stop_type == 'O':
- print 'stop_reply(): stdout = "%s"' % packet.str
-
-
-def cmd_unknown_packet(options, cmd, args):
- if args:
- print "cmd: %s, args: %s", cmd, args
- else:
- print "cmd: %s", cmd
- return False
-
-
-def cmd_qSymbol(options, cmd, args):
- if args == ':':
- print 'ready to serve symbols'
- else:
- packet = Packet(args)
- symbol_addr = packet.get_hex_uint('big')
- if symbol_addr is None:
- if packet.skip_exact_string(':'):
- symbol_name = packet.get_hex_ascii_str()
- print 'lookup_symbol("%s") -> symbol not available yet' % (symbol_name)
- else:
- print 'error: bad command format'
- else:
- if packet.skip_exact_string(':'):
- symbol_name = packet.get_hex_ascii_str()
- print 'lookup_symbol("%s") -> 0x%x' % (symbol_name, symbol_addr)
- else:
- print 'error: bad command format'
-
-def cmd_QSetWithHexString(options, cmd, args):
- print '%s("%s")' % (cmd[:-1], binascii.unhexlify(args))
-
-def cmd_QSetWithString(options, cmd, args):
- print '%s("%s")' % (cmd[:-1], args)
-
-def cmd_QSetWithUnsigned(options, cmd, args):
- print '%s(%i)' % (cmd[:-1], int(args))
-
-def rsp_qSymbol(options, cmd, cmd_args, rsp):
- if len(rsp) == 0:
- print "Unsupported"
- else:
- if rsp == "OK":
- print "No more symbols to lookup"
- else:
- packet = Packet(rsp)
- if packet.skip_exact_string("qSymbol:"):
- symbol_name = packet.get_hex_ascii_str()
- print 'lookup_symbol("%s")' % (symbol_name)
- else:
- print 'error: response string should start with "qSymbol:": respnse is "%s"' % (rsp)
-
-
-def cmd_qXfer(options, cmd, args):
- # $qXfer:features:read:target.xml:0,1ffff#14
- print "read target special data %s" % (args)
- return True
-
-
-def rsp_qXfer(options, cmd, cmd_args, rsp):
- data = string.split(cmd_args, ':')
- if data[0] == 'features':
- if data[1] == 'read':
- filename, extension = os.path.splitext(data[2])
- if extension == '.xml':
- response = Packet(rsp)
- xml_string = response.get_hex_ascii_str()
- if xml_string:
- ch = xml_string[0]
- if ch == 'l':
- xml_string = xml_string[1:]
- xml_root = ET.fromstring(xml_string)
- for reg_element in xml_root.findall("./feature/reg"):
- if not 'value_regnums' in reg_element.attrib:
- reg_info = RegisterInfo([])
- if 'name' in reg_element.attrib:
- reg_info.info[
- 'name'] = reg_element.attrib['name']
- else:
- reg_info.info['name'] = 'unspecified'
- if 'encoding' in reg_element.attrib:
- reg_info.info['encoding'] = reg_element.attrib[
- 'encoding']
- else:
- reg_info.info['encoding'] = 'uint'
- if 'offset' in reg_element.attrib:
- reg_info.info[
- 'offset'] = reg_element.attrib['offset']
- if 'bitsize' in reg_element.attrib:
- reg_info.info[
- 'bitsize'] = reg_element.attrib['bitsize']
- g_register_infos.append(reg_info)
- print 'XML for "%s":' % (data[2])
- ET.dump(xml_root)
-
-
-def cmd_A(options, cmd, args):
- print 'launch process:'
- packet = Packet(args)
- while True:
- arg_len = packet.get_number()
- if arg_len == -1:
- break
- if not packet.skip_exact_string(','):
- break
- arg_idx = packet.get_number()
- if arg_idx == -1:
- break
- if not packet.skip_exact_string(','):
- break
- arg_value = packet.get_hex_ascii_str(arg_len)
- print 'argv[%u] = "%s"' % (arg_idx, arg_value)
-
-
-def cmd_qC(options, cmd, args):
- print "query_current_thread_id()"
-
-
-def rsp_qC(options, cmd, cmd_args, rsp):
- packet = Packet(rsp)
- if packet.skip_exact_string("QC"):
- tid = packet.get_thread_id()
- print "current_thread_id = %#x" % (tid)
- else:
- print "current_thread_id = old thread ID"
-
-
-def cmd_query_packet(options, cmd, args):
- if args:
- print "%s%s" % (cmd, args)
- else:
- print "%s" % (cmd)
- return False
-
-
-def rsp_ok_error(rsp):
- print "rsp: ", rsp
-
-
-def rsp_ok_means_supported(options, cmd, cmd_args, rsp):
- if rsp == 'OK':
- print "%s%s is supported" % (cmd, cmd_args)
- elif rsp == '':
- print "%s%s is not supported" % (cmd, cmd_args)
- else:
- print "%s%s -> %s" % (cmd, cmd_args, rsp)
-
-
-def rsp_ok_means_success(options, cmd, cmd_args, rsp):
- if rsp == 'OK':
- print "success"
- elif rsp == '':
- print "%s%s is not supported" % (cmd, cmd_args)
- else:
- print "%s%s -> %s" % (cmd, cmd_args, rsp)
-
-
-def dump_key_value_pairs(key_value_pairs):
- max_key_len = 0
- for key_value_pair in key_value_pairs:
- key_len = len(key_value_pair[0])
- if max_key_len < key_len:
- max_key_len = key_len
- for key_value_pair in key_value_pairs:
- key = key_value_pair[0]
- value = key_value_pair[1]
- unhex_value = get_hex_string_if_all_printable(value)
- if unhex_value:
- print "%*s = %s (%s)" % (max_key_len, key, value, unhex_value)
- else:
- print "%*s = %s" % (max_key_len, key, value)
-
-
-def rsp_dump_key_value_pairs(options, cmd, cmd_args, rsp):
- if rsp:
- print '%s response:' % (cmd)
- packet = Packet(rsp)
- key_value_pairs = packet.get_key_value_pairs()
- dump_key_value_pairs(key_value_pairs)
- else:
- print "not supported"
-
-
-def cmd_c(options, cmd, args):
- print "continue()"
- return False
-
-
-def cmd_s(options, cmd, args):
- print "step()"
- return False
-
-
-def cmd_qSpeedTest(options, cmd, args):
- print("qSpeedTest: cmd='%s', args='%s'" % (cmd, args))
-
-
-def rsp_qSpeedTest(options, cmd, cmd_args, rsp):
- print("qSpeedTest: rsp='%s' cmd='%s', args='%s'" % (rsp, cmd, args))
-
-
-def cmd_vCont(options, cmd, args):
- if args == '?':
- print "%s: get supported extended continue modes" % (cmd)
- else:
- got_other_threads = 0
- s = ''
- for thread_action in string.split(args[1:], ';'):
- (short_action, thread) = string.split(thread_action, ':')
- tid = int(thread, 16)
- if short_action == 'c':
- action = 'continue'
- elif short_action == 's':
- action = 'step'
- elif short_action[0] == 'C':
- action = 'continue with signal 0x%s' % (short_action[1:])
- elif short_action == 'S':
- action = 'step with signal 0x%s' % (short_action[1:])
- else:
- action = short_action
- if s:
- s += ', '
- if tid == -1:
- got_other_threads = 1
- s += 'other-threads:'
- else:
- s += 'thread 0x%4.4x: %s' % (tid, action)
- if got_other_threads:
- print "extended_continue (%s)" % (s)
- else:
- print "extended_continue (%s, other-threads: suspend)" % (s)
- return False
-
-
-def rsp_vCont(options, cmd, cmd_args, rsp):
- if cmd_args == '?':
- # Skip the leading 'vCont;'
- rsp = rsp[6:]
- modes = string.split(rsp, ';')
- s = "%s: supported extended continue modes include: " % (cmd)
-
- for i, mode in enumerate(modes):
- if i:
- s += ', '
- if mode == 'c':
- s += 'continue'
- elif mode == 'C':
- s += 'continue with signal'
- elif mode == 's':
- s += 'step'
- elif mode == 'S':
- s += 'step with signal'
- elif mode == 't':
- s += 'stop'
- # else:
- # s += 'unrecognized vCont mode: ', str(mode)
- print s
- elif rsp:
- if rsp[0] == 'T' or rsp[0] == 'S' or rsp[0] == 'W' or rsp[0] == 'X':
- rsp_stop_reply(options, cmd, cmd_args, rsp)
- return
- if rsp[0] == 'O':
- print "stdout: %s" % (rsp)
- return
- else:
- print "not supported (cmd = '%s', args = '%s', rsp = '%s')" % (cmd, cmd_args, rsp)
-
-
-def cmd_vAttach(options, cmd, args):
- (extra_command, args) = string.split(args, ';')
- if extra_command:
- print "%s%s(%s)" % (cmd, extra_command, args)
- else:
- print "attach(pid = %u)" % int(args, 16)
- return False
-
-
-def cmd_qRegisterInfo(options, cmd, args):
- print 'query_register_info(reg_num=%i)' % (int(args, 16))
- return False
-
-
-def rsp_qRegisterInfo(options, cmd, cmd_args, rsp):
- global g_max_register_info_name_len
- print 'query_register_info(reg_num=%i):' % (int(cmd_args, 16)),
- if len(rsp) == 3 and rsp[0] == 'E':
- g_max_register_info_name_len = 0
- for reg_info in g_register_infos:
- name_len = len(reg_info.name())
- if g_max_register_info_name_len < name_len:
- g_max_register_info_name_len = name_len
- print' DONE'
- else:
- packet = Packet(rsp)
- reg_info = RegisterInfo(packet.get_key_value_pairs())
- g_register_infos.append(reg_info)
- print reg_info
- return False
-
-
-def cmd_qThreadInfo(options, cmd, args):
- if cmd == 'qfThreadInfo':
- query_type = 'first'
- else:
- query_type = 'subsequent'
- print 'get_current_thread_list(type=%s)' % (query_type)
- return False
-
-
-def rsp_qThreadInfo(options, cmd, cmd_args, rsp):
- packet = Packet(rsp)
- response_type = packet.get_char()
- if response_type == 'm':
- tids = packet.split_hex(';', 'big')
- for i, tid in enumerate(tids):
- if i:
- print ',',
- print '0x%x' % (tid),
- print
- elif response_type == 'l':
- print 'END'
-
-
-def rsp_hex_big_endian(options, cmd, cmd_args, rsp):
- if rsp == '':
- print "%s%s is not supported" % (cmd, cmd_args)
- else:
- packet = Packet(rsp)
- uval = packet.get_hex_uint('big')
- print '%s: 0x%x' % (cmd, uval)
-
-
-def cmd_read_mem_bin(options, cmd, args):
- # x0x7fff5fc39200,0x200
- packet = Packet(args)
- addr = packet.get_hex_uint('big')
- comma = packet.get_char()
- size = packet.get_hex_uint('big')
- print 'binary_read_memory (addr = 0x%16.16x, size = %u)' % (addr, size)
- return False
-
-
-def rsp_mem_bin_bytes(options, cmd, cmd_args, rsp):
- packet = Packet(cmd_args)
- addr = packet.get_hex_uint('big')
- comma = packet.get_char()
- size = packet.get_hex_uint('big')
- print 'memory:'
- if size > 0:
- dump_hex_memory_buffer(addr, rsp)
-
-
-def cmd_read_memory(options, cmd, args):
- packet = Packet(args)
- addr = packet.get_hex_uint('big')
- comma = packet.get_char()
- size = packet.get_hex_uint('big')
- print 'read_memory (addr = 0x%16.16x, size = %u)' % (addr, size)
- return False
-
-
-def dump_hex_memory_buffer(addr, hex_byte_str):
- packet = Packet(hex_byte_str)
- idx = 0
- ascii = ''
- uval = packet.get_hex_uint8()
- while uval is not None:
- if ((idx % 16) == 0):
- if ascii:
- print ' ', ascii
- ascii = ''
- print '0x%x:' % (addr + idx),
- print '%2.2x' % (uval),
- if 0x20 <= uval and uval < 0x7f:
- ascii += '%c' % uval
- else:
- ascii += '.'
- uval = packet.get_hex_uint8()
- idx = idx + 1
- if ascii:
- print ' ', ascii
- ascii = ''
-
-
-def cmd_write_memory(options, cmd, args):
- packet = Packet(args)
- addr = packet.get_hex_uint('big')
- if packet.get_char() != ',':
- print 'error: invalid write memory command (missing comma after address)'
- return
- size = packet.get_hex_uint('big')
- if packet.get_char() != ':':
- print 'error: invalid write memory command (missing colon after size)'
- return
- print 'write_memory (addr = 0x%16.16x, size = %u, data:' % (addr, size)
- dump_hex_memory_buffer(addr, packet.str)
- return False
-
-
-def cmd_alloc_memory(options, cmd, args):
- packet = Packet(args)
- byte_size = packet.get_hex_uint('big')
- if packet.get_char() != ',':
- print 'error: invalid allocate memory command (missing comma after address)'
- return
- print 'allocate_memory (byte-size = %u (0x%x), permissions = %s)' % (byte_size, byte_size, packet.str)
- return False
-
-
-def rsp_alloc_memory(options, cmd, cmd_args, rsp):
- packet = Packet(rsp)
- addr = packet.get_hex_uint('big')
- print 'addr = 0x%x' % addr
-
-
-def cmd_dealloc_memory(options, cmd, args):
- packet = Packet(args)
- addr = packet.get_hex_uint('big')
- if packet.get_char() != ',':
- print 'error: invalid allocate memory command (missing comma after address)'
- else:
- print 'deallocate_memory (addr = 0x%x, permissions = %s)' % (addr, packet.str)
- return False
-
-
-def rsp_memory_bytes(options, cmd, cmd_args, rsp):
- addr = Packet(cmd_args).get_hex_uint('big')
- dump_hex_memory_buffer(addr, rsp)
-
-
-def get_register_name_equal_value(options, reg_num, hex_value_str):
- if reg_num < len(g_register_infos):
- reg_info = g_register_infos[reg_num]
- value_str = reg_info.get_value_from_hex_string(hex_value_str)
- s = reg_info.name() + ' = '
- if options.symbolicator:
- symbolicated_addresses = options.symbolicator.symbolicate(
- int(value_str, 0))
- if symbolicated_addresses:
- s += options.colors.magenta()
- s += '%s' % symbolicated_addresses[0]
- s += options.colors.reset()
- return s
- s += value_str
- return s
- else:
- reg_value = Packet(hex_value_str).get_hex_uint(g_byte_order)
- return 'reg(%u) = 0x%x' % (reg_num, reg_value)
-
-
-def cmd_read_one_reg(options, cmd, args):
- packet = Packet(args)
- reg_num = packet.get_hex_uint('big')
- tid = get_thread_from_thread_suffix(packet.str)
- name = None
- if reg_num < len(g_register_infos):
- name = g_register_infos[reg_num].name()
- if packet.str:
- packet.get_char() # skip ;
- thread_info = packet.get_key_value_pairs()
- tid = int(thread_info[0][1], 16)
- s = 'read_register (reg_num=%u' % reg_num
- if name:
- s += ' (%s)' % (name)
- if tid is not None:
- s += ', tid = 0x%4.4x' % (tid)
- s += ')'
- print s
- return False
-
-
-def rsp_read_one_reg(options, cmd, cmd_args, rsp):
- packet = Packet(cmd_args)
- reg_num = packet.get_hex_uint('big')
- print get_register_name_equal_value(options, reg_num, rsp)
-
-
-def cmd_write_one_reg(options, cmd, args):
- packet = Packet(args)
- reg_num = packet.get_hex_uint('big')
- if packet.get_char() != '=':
- print 'error: invalid register write packet'
- else:
- name = None
- hex_value_str = packet.get_hex_chars()
- tid = get_thread_from_thread_suffix(packet.str)
- s = 'write_register (reg_num=%u' % reg_num
- if name:
- s += ' (%s)' % (name)
- s += ', value = '
- s += get_register_name_equal_value(options, reg_num, hex_value_str)
- if tid is not None:
- s += ', tid = 0x%4.4x' % (tid)
- s += ')'
- print s
- return False
-
-
-def dump_all_regs(packet):
- for reg_info in g_register_infos:
- nibble_size = reg_info.bit_size() / 4
- hex_value_str = packet.get_hex_chars(nibble_size)
- if hex_value_str is not None:
- value = reg_info.get_value_from_hex_string(hex_value_str)
- print '%*s = %s' % (g_max_register_info_name_len, reg_info.name(), value)
- else:
- return
-
-
-def cmd_read_all_regs(cmd, cmd_args):
- packet = Packet(cmd_args)
- packet.get_char() # toss the 'g' command character
- tid = get_thread_from_thread_suffix(packet.str)
- if tid is not None:
- print 'read_all_register(thread = 0x%4.4x)' % tid
- else:
- print 'read_all_register()'
- return False
-
-
-def rsp_read_all_regs(options, cmd, cmd_args, rsp):
- packet = Packet(rsp)
- dump_all_regs(packet)
-
-
-def cmd_write_all_regs(options, cmd, args):
- packet = Packet(args)
- print 'write_all_registers()'
- dump_all_regs(packet)
- return False
-
-g_bp_types = ["software_bp", "hardware_bp", "write_wp", "read_wp", "access_wp"]
-
-
-def cmd_bp(options, cmd, args):
- if cmd == 'Z':
- s = 'set_'
- else:
- s = 'clear_'
- packet = Packet(args)
- bp_type = packet.get_hex_uint('big')
- packet.get_char() # Skip ,
- bp_addr = packet.get_hex_uint('big')
- packet.get_char() # Skip ,
- bp_size = packet.get_hex_uint('big')
- s += g_bp_types[bp_type]
- s += " (addr = 0x%x, size = %u)" % (bp_addr, bp_size)
- print s
- return False
-
-
-def cmd_mem_rgn_info(options, cmd, args):
- packet = Packet(args)
- packet.get_char() # skip ':' character
- addr = packet.get_hex_uint('big')
- print 'get_memory_region_info (addr=0x%x)' % (addr)
- return False
-
-
-def cmd_kill(options, cmd, args):
- print 'kill_process()'
- return False
-
-
-def cmd_jThreadsInfo(options, cmd, args):
- print 'jThreadsInfo()'
- return False
-
-
-def cmd_jGetLoadedDynamicLibrariesInfos(options, cmd, args):
- print 'jGetLoadedDynamicLibrariesInfos()'
- return False
-
-
-def decode_packet(s, start_index=0):
- # print '\ndecode_packet("%s")' % (s[start_index:])
- index = s.find('}', start_index)
- have_escapes = index != -1
- if have_escapes:
- normal_s = s[start_index:index]
- else:
- normal_s = s[start_index:]
- # print 'normal_s = "%s"' % (normal_s)
- if have_escapes:
- escape_char = '%c' % (ord(s[index + 1]) ^ 0x20)
- # print 'escape_char for "%s" = %c' % (s[index:index+2], escape_char)
- return normal_s + escape_char + decode_packet(s, index + 2)
- else:
- return normal_s
-
-
-def rsp_json(options, cmd, cmd_args, rsp):
- print '%s() reply:' % (cmd)
- json_tree = json.loads(rsp)
- print json.dumps(json_tree, indent=4, separators=(',', ': '))
-
-
-def rsp_jGetLoadedDynamicLibrariesInfos(options, cmd, cmd_args, rsp):
- if cmd_args:
- rsp_json(options, cmd, cmd_args, rsp)
- else:
- rsp_ok_means_supported(options, cmd, cmd_args, rsp)
-
-gdb_remote_commands = {
- '\\?': {'cmd': cmd_stop_reply, 'rsp': rsp_stop_reply, 'name': "stop reply pacpket"},
- 'qThreadStopInfo': {'cmd': cmd_qThreadStopInfo, 'rsp': rsp_stop_reply, 'name': "stop reply pacpket"},
- 'QStartNoAckMode': {'cmd': cmd_query_packet, 'rsp': rsp_ok_means_supported, 'name': "query if no ack mode is supported"},
- 'QThreadSuffixSupported': {'cmd': cmd_query_packet, 'rsp': rsp_ok_means_supported, 'name': "query if thread suffix is supported"},
- 'QListThreadsInStopReply': {'cmd': cmd_query_packet, 'rsp': rsp_ok_means_supported, 'name': "query if threads in stop reply packets are supported"},
- 'QSetDetachOnError:': {'cmd': cmd_QSetWithUnsigned, 'rsp': rsp_ok_means_success, 'name': "set if we should detach on error"},
- 'QSetDisableASLR:': {'cmd': cmd_QSetWithUnsigned, 'rsp': rsp_ok_means_success, 'name': "set if we should disable ASLR"},
- 'qLaunchSuccess': {'cmd': cmd_query_packet, 'rsp': rsp_ok_means_success, 'name': "check on launch success for the A packet"},
- 'A': {'cmd': cmd_A, 'rsp': rsp_ok_means_success, 'name': "launch process"},
- 'QLaunchArch:': {'cmd': cmd_QSetWithString, 'rsp': rsp_ok_means_supported, 'name': "set the arch to launch in case the file contains multiple architectures"},
- 'qVAttachOrWaitSupported': {'cmd': cmd_query_packet, 'rsp': rsp_ok_means_supported, 'name': "set the launch architecture"},
- 'qHostInfo': {'cmd': cmd_query_packet, 'rsp': rsp_dump_key_value_pairs, 'name': "get host information"},
- 'qC': {'cmd': cmd_qC, 'rsp': rsp_qC, 'name': "return the current thread ID"},
- 'vCont': {'cmd': cmd_vCont, 'rsp': rsp_vCont, 'name': "extended continue command"},
- 'qSpeedTest': {'cmd':cmd_qSpeedTest, 'rsp': rsp_qSpeedTest, 'name': 'speed test packdet'},
- 'vAttach': {'cmd': cmd_vAttach, 'rsp': rsp_stop_reply, 'name': "attach to process"},
- 'c': {'cmd': cmd_c, 'rsp': rsp_stop_reply, 'name': "continue"},
- 's': {'cmd': cmd_s, 'rsp': rsp_stop_reply, 'name': "step"},
- 'qRegisterInfo': {'cmd': cmd_qRegisterInfo, 'rsp': rsp_qRegisterInfo, 'name': "query register info"},
- 'qfThreadInfo': {'cmd': cmd_qThreadInfo, 'rsp': rsp_qThreadInfo, 'name': "get current thread list"},
- 'qsThreadInfo': {'cmd': cmd_qThreadInfo, 'rsp': rsp_qThreadInfo, 'name': "get current thread list"},
- 'qShlibInfoAddr': {'cmd': cmd_query_packet, 'rsp': rsp_hex_big_endian, 'name': "get shared library info address"},
- 'qMemoryRegionInfo': {'cmd': cmd_mem_rgn_info, 'rsp': rsp_dump_key_value_pairs, 'name': "get memory region information"},
- 'qProcessInfo': {'cmd': cmd_query_packet, 'rsp': rsp_dump_key_value_pairs, 'name': "get process info"},
- 'qSupported': {'cmd': cmd_query_packet, 'rsp': rsp_ok_means_supported, 'name': "query supported"},
- 'qXfer:': {'cmd': cmd_qXfer, 'rsp': rsp_qXfer, 'name': "qXfer"},
- 'qSymbol:': {'cmd': cmd_qSymbol, 'rsp': rsp_qSymbol, 'name': "qSymbol"},
- 'QSetSTDIN:' : {'cmd' : cmd_QSetWithHexString, 'rsp' : rsp_ok_means_success, 'name': "set STDIN prior to launching with A packet"},
- 'QSetSTDOUT:' : {'cmd' : cmd_QSetWithHexString, 'rsp' : rsp_ok_means_success, 'name': "set STDOUT prior to launching with A packet"},
- 'QSetSTDERR:' : {'cmd' : cmd_QSetWithHexString, 'rsp' : rsp_ok_means_success, 'name': "set STDERR prior to launching with A packet"},
- 'QEnvironment:' : {'cmd' : cmd_QSetWithString, 'rsp' : rsp_ok_means_success, 'name': "set an environment variable prior to launching with A packet"},
- 'QEnvironmentHexEncoded:' : {'cmd' : cmd_QSetWithHexString, 'rsp' : rsp_ok_means_success, 'name': "set an environment variable prior to launching with A packet"},
- 'x': {'cmd': cmd_read_mem_bin, 'rsp': rsp_mem_bin_bytes, 'name': "read memory binary"},
- 'X': {'cmd': cmd_write_memory, 'rsp': rsp_ok_means_success, 'name': "write memory binary"},
- 'm': {'cmd': cmd_read_memory, 'rsp': rsp_memory_bytes, 'name': "read memory"},
- 'M': {'cmd': cmd_write_memory, 'rsp': rsp_ok_means_success, 'name': "write memory"},
- '_M': {'cmd': cmd_alloc_memory, 'rsp': rsp_alloc_memory, 'name': "allocate memory"},
- '_m': {'cmd': cmd_dealloc_memory, 'rsp': rsp_ok_means_success, 'name': "deallocate memory"},
- 'p': {'cmd': cmd_read_one_reg, 'rsp': rsp_read_one_reg, 'name': "read single register"},
- 'P': {'cmd': cmd_write_one_reg, 'rsp': rsp_ok_means_success, 'name': "write single register"},
- 'g': {'cmd': cmd_read_all_regs, 'rsp': rsp_read_all_regs, 'name': "read all registers"},
- 'G': {'cmd': cmd_write_all_regs, 'rsp': rsp_ok_means_success, 'name': "write all registers"},
- 'z': {'cmd': cmd_bp, 'rsp': rsp_ok_means_success, 'name': "clear breakpoint or watchpoint"},
- 'Z': {'cmd': cmd_bp, 'rsp': rsp_ok_means_success, 'name': "set breakpoint or watchpoint"},
- 'k': {'cmd': cmd_kill, 'rsp': rsp_stop_reply, 'name': "kill process"},
- 'jThreadsInfo': {'cmd': cmd_jThreadsInfo, 'rsp': rsp_json, 'name': "JSON get all threads info"},
- 'jGetLoadedDynamicLibrariesInfos:': {'cmd': cmd_jGetLoadedDynamicLibrariesInfos, 'rsp': rsp_jGetLoadedDynamicLibrariesInfos, 'name': 'JSON get loaded dynamic libraries'},
-}
-
-
-def calculate_mean_and_standard_deviation(floats):
- sum = 0.0
- count = len(floats)
- if count == 0:
- return (0.0, 0.0)
- for f in floats:
- sum += f
- mean = sum / count
- accum = 0.0
- for f in floats:
- delta = f - mean
- accum += delta * delta
-
- std_dev = math.sqrt(accum / (count - 1))
- return (mean, std_dev)
-
-
-def parse_gdb_log_file(path, options):
- f = open(path)
- parse_gdb_log(f, options)
- f.close()
-
-
-def round_up(n, incr):
- return float(((int(n) + incr) / incr) * incr)
-
-
-def plot_latencies(sec_times):
- # import numpy as np
- import matplotlib.pyplot as plt
-
- for (i, name) in enumerate(sec_times.keys()):
- times = sec_times[name]
- if len(times) <= 1:
- continue
- plt.subplot(2, 1, 1)
- plt.title('Packet "%s" Times' % (name))
- plt.xlabel('Packet')
- units = 'ms'
- adj_times = []
- max_time = 0.0
- for time in times:
- time = time * 1000.0
- adj_times.append(time)
- if time > max_time:
- max_time = time
- if max_time < 1.0:
- units = 'us'
- max_time = 0.0
- for i in range(len(adj_times)):
- adj_times[i] *= 1000.0
- if adj_times[i] > max_time:
- max_time = adj_times[i]
- plt.ylabel('Time (%s)' % (units))
- max_y = None
- for i in [5.0, 10.0, 25.0, 50.0]:
- if max_time < i:
- max_y = round_up(max_time, i)
- break
- if max_y is None:
- max_y = round_up(max_time, 100.0)
- plt.ylim(0.0, max_y)
- plt.plot(adj_times, 'o-')
- plt.show()
-
-
-def parse_gdb_log(file, options):
- '''Parse a GDB log file that was generated by enabling logging with:
- (lldb) log enable --threadsafe --timestamp --file <FILE> gdb-remote packets
- This log file will contain timestamps and this function will then normalize
- those packets to be relative to the first value timestamp that is found and
- show delta times between log lines and also keep track of how long it takes
- for GDB remote commands to make a send/receive round trip. This can be
- handy when trying to figure out why some operation in the debugger is taking
- a long time during a preset set of debugger commands.'''
-
- tricky_commands = ['qRegisterInfo']
- timestamp_regex = re.compile('(\s*)([1-9][0-9]+\.[0-9]+)([^0-9].*)$')
- packet_name_regex = re.compile('([A-Za-z_]+)[^a-z]')
- packet_transmit_name_regex = re.compile(
- '(?P<direction>send|read) packet: (?P<packet>.*)')
- packet_contents_name_regex = re.compile('\$([^#]*)#[0-9a-fA-F]{2}')
- packet_checksum_regex = re.compile('.*#[0-9a-fA-F]{2}$')
- packet_names_regex_str = '(' + \
- '|'.join(gdb_remote_commands.keys()) + ')(.*)'
- packet_names_regex = re.compile(packet_names_regex_str)
-
- base_time = 0.0
- last_time = 0.0
- min_time = 100000000.0
- packet_total_times = {}
- all_packet_times = []
- packet_times = {}
- packet_counts = {}
- lines = file.read().splitlines()
- last_command = None
- last_command_args = None
- last_command_packet = None
- hide_next_response = False
- num_lines = len(lines)
- skip_count = 0
- for (line_index, line) in enumerate(lines):
- # See if we need to skip any lines
- if skip_count > 0:
- skip_count -= 1
- continue
- m = packet_transmit_name_regex.search(line)
- is_command = False
- direction = None
- if m:
- direction = m.group('direction')
- is_command = direction == 'send'
- packet = m.group('packet')
- sys.stdout.write(options.colors.green())
- if not options.quiet and not hide_next_response:
- print '# ', line
- sys.stdout.write(options.colors.reset())
-
- # print 'direction = "%s", packet = "%s"' % (direction, packet)
-
- if packet[0] == '+':
- if is_command:
- print '-->',
- else:
- print '<--',
- if not options.quiet:
- print 'ACK'
- continue
- elif packet[0] == '-':
- if is_command:
- print '-->',
- else:
- print '<--',
- if not options.quiet:
- print 'NACK'
- continue
- elif packet[0] == '$':
- m = packet_contents_name_regex.match(packet)
- if not m and packet[0] == '$':
- multiline_packet = packet
- idx = line_index + 1
- while idx < num_lines:
- if not options.quiet and not hide_next_response:
- print '# ', lines[idx]
- multiline_packet += lines[idx]
- m = packet_contents_name_regex.match(multiline_packet)
- if m:
- packet = multiline_packet
- skip_count = idx - line_index
- break
- else:
- idx += 1
- if m:
- if is_command:
- print '-->',
- else:
- print '<--',
- contents = decode_packet(m.group(1))
- if is_command:
- hide_next_response = False
- m = packet_names_regex.match(contents)
- if m:
- last_command = m.group(1)
- if last_command == '?':
- last_command = '\\?'
- packet_name = last_command
- last_command_args = m.group(2)
- last_command_packet = contents
- hide_next_response = gdb_remote_commands[last_command][
- 'cmd'](options, last_command, last_command_args)
- else:
- packet_match = packet_name_regex.match(contents)
- if packet_match:
- packet_name = packet_match.group(1)
- for tricky_cmd in tricky_commands:
- if packet_name.find(tricky_cmd) == 0:
- packet_name = tricky_cmd
- else:
- packet_name = contents
- last_command = None
- last_command_args = None
- last_command_packet = None
- elif last_command:
- gdb_remote_commands[last_command]['rsp'](
- options, last_command, last_command_args, contents)
- else:
- print 'error: invalid packet: "', packet, '"'
- else:
- print '???'
- else:
- print '## ', line
- match = timestamp_regex.match(line)
- if match:
- curr_time = float(match.group(2))
- if last_time and not is_command:
- delta = curr_time - last_time
- all_packet_times.append(delta)
- delta = 0.0
- if base_time:
- delta = curr_time - last_time
- else:
- base_time = curr_time
-
- if not is_command:
- if line.find('read packet: $') >= 0 and packet_name:
- if packet_name in packet_total_times:
- packet_total_times[packet_name] += delta
- packet_counts[packet_name] += 1
- else:
- packet_total_times[packet_name] = delta
- packet_counts[packet_name] = 1
- if packet_name not in packet_times:
- packet_times[packet_name] = []
- packet_times[packet_name].append(delta)
- packet_name = None
- if min_time > delta:
- min_time = delta
-
- if not options or not options.quiet:
- print '%s%.6f %+.6f%s' % (match.group(1),
- curr_time - base_time,
- delta,
- match.group(3))
- last_time = curr_time
- # else:
- # print line
- (average, std_dev) = calculate_mean_and_standard_deviation(all_packet_times)
- if average and std_dev:
- print '%u packets with average packet time of %f and standard deviation of %f' % (len(all_packet_times), average, std_dev)
- if packet_total_times:
- total_packet_time = 0.0
- total_packet_count = 0
- for key, vvv in packet_total_times.items():
- # print ' key = (%s) "%s"' % (type(key), key)
- # print 'value = (%s) %s' % (type(vvv), vvv)
- # if type(vvv) == 'float':
- total_packet_time += vvv
- for key, vvv in packet_counts.items():
- total_packet_count += vvv
-
- print '#------------------------------------------------------------'
- print '# Packet timing summary:'
- print '# Totals: time = %6f, count = %6d' % (total_packet_time,
- total_packet_count)
- print '# Min packet time: time = %6f' % (min_time)
- print '#------------------------------------------------------------'
- print '# Packet Time (sec) Percent Count Latency'
- print '#------------------------- ----------- ------- ------ -------'
- if options and options.sort_count:
- res = sorted(
- packet_counts,
- key=packet_counts.__getitem__,
- reverse=True)
- else:
- res = sorted(
- packet_total_times,
- key=packet_total_times.__getitem__,
- reverse=True)
-
- if last_time > 0.0:
- for item in res:
- packet_total_time = packet_total_times[item]
- packet_percent = (
- packet_total_time / total_packet_time) * 100.0
- packet_count = packet_counts[item]
- print " %24s %11.6f %5.2f%% %6d %9.6f" % (
- item, packet_total_time, packet_percent, packet_count,
- float(packet_total_time) / float(packet_count))
- if options.plot:
- plot_latencies(packet_times)
-
-if __name__ == '__main__':
- usage = "usage: gdbremote [options]"
- description = '''The command disassembles a GDB remote packet log.'''
- parser = optparse.OptionParser(
- description=description,
- prog='gdbremote',
- usage=usage)
- parser.add_option(
- '-v',
- '--verbose',
- action='store_true',
- dest='verbose',
- help='display verbose debug info',
- default=False)
- parser.add_option(
- '--plot',
- action='store_true',
- dest='plot',
- help='plot packet latencies by packet type',
- default=False)
- parser.add_option(
- '-q',
- '--quiet',
- action='store_true',
- dest='quiet',
- help='display verbose debug info',
- default=False)
- parser.add_option(
- '-C',
- '--color',
- action='store_true',
- dest='color',
- help='add terminal colors',
- default=False)
- parser.add_option(
- '-c',
- '--sort-by-count',
- action='store_true',
- dest='sort_count',
- help='display verbose debug info',
- default=False)
- parser.add_option(
- '--crashlog',
- type='string',
- dest='crashlog',
- help='symbolicate using a darwin crash log file',
- default=False)
- try:
- (options, args) = parser.parse_args(sys.argv[1:])
- except:
- print 'error: argument error'
- sys.exit(1)
-
- options.colors = TerminalColors(options.color)
- options.symbolicator = None
- if options.crashlog:
- import lldb
- lldb.debugger = lldb.SBDebugger.Create()
- import lldb.macosx.crashlog
- options.symbolicator = lldb.macosx.crashlog.CrashLog(options.crashlog)
- print '%s' % (options.symbolicator)
-
- # This script is being run from the command line, create a debugger in case we are
- # going to use any debugger functions in our function.
- if len(args):
- for file in args:
- print '#----------------------------------------------------------------------'
- print "# GDB remote log file: '%s'" % file
- print '#----------------------------------------------------------------------'
- parse_gdb_log_file(file, options)
- if options.symbolicator:
- print '%s' % (options.symbolicator)
- else:
- parse_gdb_log(sys.stdin, options)
-
-else:
- import lldb
- if lldb.debugger:
- # This initializer is being run from LLDB in the embedded command interpreter
- # Add any commands contained in this module to LLDB
- lldb.debugger.HandleCommand(
- 'command script add -f gdbremote.start_gdb_log start_gdb_log')
- lldb.debugger.HandleCommand(
- 'command script add -f gdbremote.stop_gdb_log stop_gdb_log')
- print 'The "start_gdb_log" and "stop_gdb_log" commands are now installed and ready for use, type "start_gdb_log --help" or "stop_gdb_log --help" for more information'
diff --git a/examples/python/globals.py b/examples/python/globals.py
deleted file mode 100755
index 43bd915b3933..000000000000
--- a/examples/python/globals.py
+++ /dev/null
@@ -1,106 +0,0 @@
-#!/usr/bin/python
-
-#----------------------------------------------------------------------
-# For the shells csh, tcsh:
-# ( setenv PYTHONPATH /Applications/Xcode.app/Contents/SharedFrameworks/LLDB.framework/Resources/Python ; ./globals.py <path> [<path> ...])
-#
-# For the shells sh, bash:
-# PYTHONPATH=/Applications/Xcode.app/Contents/SharedFrameworks/LLDB.framework/Resources/Python ./globals.py <path> [<path> ...]
-#----------------------------------------------------------------------
-
-import lldb
-import commands
-import optparse
-import os
-import shlex
-import sys
-
-
-def get_globals(raw_path, options):
- error = lldb.SBError()
- # Resolve the path if needed
- path = os.path.expanduser(raw_path)
- # Create a target using path + options
- target = lldb.debugger.CreateTarget(
- path, options.arch, options.platform, False, error)
- if target:
- # Get the executable module
- module = target.module[target.executable.basename]
- if module:
- # Keep track of which variables we have already looked up
- global_names = list()
- # Iterate through all symbols in the symbol table and watch for any
- # DATA symbols
- for symbol in module.symbols:
- if symbol.type == lldb.eSymbolTypeData:
- # The symbol is a DATA symbol, lets try and find all global variables
- # that match this name and print them
- global_name = symbol.name
- # Make sure we don't lookup the same variable twice
- if global_name not in global_names:
- global_names.append(global_name)
- # Find all global variables by name
- global_variable_list = module.FindGlobalVariables(
- target, global_name, lldb.UINT32_MAX)
- if global_variable_list:
- # Print results for anything that matched
- for global_variable in global_variable_list:
- # returns the global variable name as a string
- print 'name = %s' % global_variable.name
- # Returns the variable value as a string
- print 'value = %s' % global_variable.value
- print 'type = %s' % global_variable.type # Returns an lldb.SBType object
- # Returns an lldb.SBAddress (section offset
- # address) for this global
- print 'addr = %s' % global_variable.addr
- # Returns the file virtual address for this
- # global
- print 'file_addr = 0x%x' % global_variable.addr.file_addr
- # returns the global variable value as a string
- print 'location = %s' % global_variable.location
- # Returns the size in bytes of this global
- # variable
- print 'size = %s' % global_variable.size
- print
-
-
-def globals(command_args):
- '''Extract all globals from any arguments which must be paths to object files.'''
- usage = "usage: %prog [options] <PATH> [PATH ...]"
- description = '''This command will find all globals in the specified object file and return an list() of lldb.SBValue objects (which might be empty).'''
- parser = optparse.OptionParser(
- description=description,
- prog='globals',
- usage=usage)
- parser.add_option(
- '-v',
- '--verbose',
- action='store_true',
- dest='verbose',
- help='display verbose debug info',
- default=False)
- parser.add_option(
- '-a',
- '--arch',
- type='string',
- metavar='arch',
- dest='arch',
- help='Specify an architecture (or triple) to use when extracting from a file.')
- parser.add_option(
- '-p',
- '--platform',
- type='string',
- metavar='platform',
- dest='platform',
- help='Specify the platform to use when creating the debug target. Valid values include "localhost", "darwin-kernel", "ios-simulator", "remote-freebsd", "remote-macosx", "remote-ios", "remote-linux".')
- try:
- (options, args) = parser.parse_args(command_args)
- except:
- return
-
- for path in args:
- get_globals(path, options)
-
-if __name__ == '__main__':
- lldb.debugger = lldb.SBDebugger.Create()
- globals(sys.argv[1:])
diff --git a/examples/python/jump.py b/examples/python/jump.py
deleted file mode 100644
index 6e41b4c8098f..000000000000
--- a/examples/python/jump.py
+++ /dev/null
@@ -1,196 +0,0 @@
-import lldb
-import re
-
-
-def parse_linespec(linespec, frame, result):
- """Handles a subset of GDB-style linespecs. Specifically:
-
- number - A line in the current file
- +offset - The line /offset/ lines after this line
- -offset - The line /offset/ lines before this line
- filename:number - Line /number/ in file /filename/
- function - The start of /function/
- *address - The pointer target of /address/, which must be a literal (but see `` in LLDB)
-
- We explicitly do not handle filename:function because it is ambiguous in Objective-C.
-
- This function returns a list of addresses."""
-
- breakpoint = None
- target = frame.GetThread().GetProcess().GetTarget()
-
- matched = False
-
- if (not matched):
- mo = re.match("^([0-9]+)$", linespec)
- if (mo is not None):
- matched = True
- # print "Matched <linenum>"
- line_number = int(mo.group(1))
- line_entry = frame.GetLineEntry()
- if not line_entry.IsValid():
- result.AppendMessage(
- "Specified a line in the current file, but the current frame doesn't have line table information.")
- return
- breakpoint = target.BreakpointCreateByLocation(
- line_entry.GetFileSpec(), line_number)
-
- if (not matched):
- mo = re.match("^\+([0-9]+)$", linespec)
- if (mo is not None):
- matched = True
- # print "Matched +<count>"
- line_number = int(mo.group(1))
- line_entry = frame.GetLineEntry()
- if not line_entry.IsValid():
- result.AppendMessage(
- "Specified a line in the current file, but the current frame doesn't have line table information.")
- return
- breakpoint = target.BreakpointCreateByLocation(
- line_entry.GetFileSpec(), (line_entry.GetLine() + line_number))
-
- if (not matched):
- mo = re.match("^\-([0-9]+)$", linespec)
- if (mo is not None):
- matched = True
- # print "Matched -<count>"
- line_number = int(mo.group(1))
- line_entry = frame.GetLineEntry()
- if not line_entry.IsValid():
- result.AppendMessage(
- "Specified a line in the current file, but the current frame doesn't have line table information.")
- return
- breakpoint = target.BreakpointCreateByLocation(
- line_entry.GetFileSpec(), (line_entry.GetLine() - line_number))
-
- if (not matched):
- mo = re.match("^(.*):([0-9]+)$", linespec)
- if (mo is not None):
- matched = True
- # print "Matched <filename>:<linenum>"
- file_name = mo.group(1)
- line_number = int(mo.group(2))
- breakpoint = target.BreakpointCreateByLocation(
- file_name, line_number)
-
- if (not matched):
- mo = re.match("\*((0x)?([0-9a-f]+))$", linespec)
- if (mo is not None):
- matched = True
- # print "Matched <address-expression>"
- address = long(mo.group(1), base=0)
- breakpoint = target.BreakpointCreateByAddress(address)
-
- if (not matched):
- # print "Trying <function-name>"
- breakpoint = target.BreakpointCreateByName(linespec)
-
- num_locations = breakpoint.GetNumLocations()
-
- if (num_locations == 0):
- result.AppendMessage(
- "The line specification provided doesn't resolve to any addresses.")
-
- addr_list = []
-
- for location_index in range(num_locations):
- location = breakpoint.GetLocationAtIndex(location_index)
- addr_list.append(location.GetAddress())
-
- target.BreakpointDelete(breakpoint.GetID())
-
- return addr_list
-
-
-def usage_string():
- return """ Sets the program counter to a specific address.
-
-Syntax: jump <linespec> [<location-id>]
-
-Command Options Usage:
- jump <linenum>
- jump +<count>
- jump -<count>
- jump <filename>:<linenum>
- jump <function-name>
- jump *<address-expression>
-
-<location-id> serves to disambiguate when multiple locations could be meant."""
-
-
-def jump(debugger, command, result, internal_dict):
- if (command == ""):
- result.AppendMessage(usage_string())
-
- args = command.split()
-
- if not debugger.IsValid():
- result.AppendMessage("Invalid debugger!")
- return
-
- target = debugger.GetSelectedTarget()
- if not target.IsValid():
- result.AppendMessage("jump requires a valid target.")
- return
-
- process = target.GetProcess()
- if not process.IsValid():
- result.AppendMessage("jump requires a valid process.")
- return
-
- thread = process.GetSelectedThread()
- if not thread.IsValid():
- result.AppendMessage("jump requires a valid thread.")
- return
-
- frame = thread.GetSelectedFrame()
- if not frame.IsValid():
- result.AppendMessage("jump requires a valid frame.")
- return
-
- addresses = parse_linespec(args[0], frame, result)
-
- stream = lldb.SBStream()
-
- if len(addresses) == 0:
- return
-
- desired_address = addresses[0]
-
- if len(addresses) > 1:
- if len(args) == 2:
- desired_index = int(args[1])
- if (desired_index >= 0) and (desired_index < len(addresses)):
- desired_address = addresses[desired_index]
- else:
- result.AppendMessage(
- "Desired index " +
- args[1] +
- " is not one of the options.")
- return
- else:
- index = 0
- result.AppendMessage(
- "The specified location resolves to multiple targets.")
- for address in addresses:
- stream.Clear()
- address.GetDescription(stream)
- result.AppendMessage(
- " Location ID " +
- str(index) +
- ": " +
- stream.GetData())
- index = index + 1
- result.AppendMessage(
- "Please type 'jump " +
- command +
- " <location-id>' to choose one.")
- return
-
- frame.SetPC(desired_address.GetLoadAddress(target))
-
-if lldb.debugger:
- # Module is being run inside the LLDB interpreter
- jump.__doc__ = usage_string()
- lldb.debugger.HandleCommand('command script add -f jump.jump jump')
- print 'The "jump" command has been installed, type "help jump" or "jump <ENTER>" for detailed help.'
diff --git a/examples/python/lldb_module_utils.py b/examples/python/lldb_module_utils.py
deleted file mode 100644
index 006f232681f8..000000000000
--- a/examples/python/lldb_module_utils.py
+++ /dev/null
@@ -1,191 +0,0 @@
-#!/usr/bin/python
-
-import lldb
-import optparse
-import shlex
-import string
-import sys
-
-
-class DumpLineTables:
- command_name = "dump-line-tables"
- short_decription = "Dumps full paths to compile unit files and optionally all line table files."
- description = 'Dumps all line tables from all compile units for any modules specified as arguments. Specifying the --verbose flag will output address ranges for each line entry.'
- usage = "usage: %prog [options] MODULE1 [MODULE2 ...]"
- def create_options(self):
- self.parser = optparse.OptionParser(
- description=self.description,
- prog=self.command_name,
- usage=self.usage)
-
- self.parser.add_option(
- '-v',
- '--verbose',
- action='store_true',
- dest='verbose',
- help='Display verbose output.',
- default=False)
-
- def get_short_help(self):
- return self.short_decription
-
- def get_long_help(self):
- return self.help_string
-
- def __init__(self, debugger, unused):
- self.create_options()
- self.help_string = self.parser.format_help()
-
- def __call__(self, debugger, command, exe_ctx, result):
- # Use the Shell Lexer to properly parse up command options just like a
- # shell would
- command_args = shlex.split(command)
-
- try:
- (options, args) = self.parser.parse_args(command_args)
- except:
- # if you don't handle exceptions, passing an incorrect argument to the OptionParser will cause LLDB to exit
- # (courtesy of OptParse dealing with argument errors by throwing SystemExit)
- result.SetError("option parsing failed")
- return
-
- # Always get program state from the SBExecutionContext passed in as exe_ctx
- target = exe_ctx.GetTarget()
- if not target.IsValid():
- result.SetError("invalid target")
- return
-
- for module_path in args:
- module = target.module[module_path]
- if not module:
- result.SetError('no module found that matches "%s".' % (module_path))
- return
- num_cus = module.GetNumCompileUnits()
- print >>result, 'Module: "%s"' % (module.file.fullpath),
- if num_cus == 0:
- print >>result, 'no debug info.'
- continue
- print >>result, 'has %u compile units:' % (num_cus)
- for cu_idx in range(num_cus):
- cu = module.GetCompileUnitAtIndex(cu_idx)
- print >>result, ' Compile Unit: %s' % (cu.file.fullpath)
- for line_idx in range(cu.GetNumLineEntries()):
- line_entry = cu.GetLineEntryAtIndex(line_idx)
- start_file_addr = line_entry.addr.file_addr
- end_file_addr = line_entry.end_addr.file_addr
- # If the two addresses are equal, this line table entry
- # is a termination entry
- if options.verbose:
- if start_file_addr != end_file_addr:
- result.PutCString(
- ' [%#x - %#x): %s' %
- (start_file_addr, end_file_addr, line_entry))
- else:
- if start_file_addr == end_file_addr:
- result.PutCString(' %#x: END' %
- (start_file_addr))
- else:
- result.PutCString(
- ' %#x: %s' %
- (start_file_addr, line_entry))
- if start_file_addr == end_file_addr:
- result.PutCString("\n")
-
-
-class DumpFiles:
- command_name = "dump-files"
- short_description = "Dumps full paths to compile unit files and optionally all line table files."
- usage = "usage: %prog [options] MODULE1 [MODULE2 ...]"
- description = '''This class adds a dump-files command to the LLDB interpreter.
-
-This command will dump all compile unit file paths found for each source file
-for the binaries specified as arguments in the current target. Specify the
---support-files or -s option to see all file paths that a compile unit uses in
-its lines tables. This is handy for troubleshooting why breakpoints aren't
-working in IDEs that specify full paths to source files when setting file and
-line breakpoints. Sometimes symlinks cause the debug info to contain the symlink
-path and an IDE will resolve the path to the actual file and use the resolved
-path when setting breakpoints.
-'''
- def create_options(self):
- # Pass add_help_option = False, since this keeps the command in line with lldb commands,
- # and we wire up "help command" to work by providing the long & short help methods below.
- self.parser = optparse.OptionParser(
- description = self.description,
- prog = self.command_name,
- usage = self.usage,
- add_help_option = False)
-
- self.parser.add_option(
- '-s',
- '--support-files',
- action = 'store_true',
- dest = 'support_files',
- help = 'Dumps full paths to all files used in a compile unit.',
- default = False)
-
- def get_short_help(self):
- return self.short_description
-
- def get_long_help(self):
- return self.help_string
-
- def __init__(self, debugger, unused):
- self.create_options()
- self.help_string = self.parser.format_help()
-
- def __call__(self, debugger, command, exe_ctx, result):
- # Use the Shell Lexer to properly parse up command options just like a
- # shell would
- command_args = shlex.split(command)
-
- try:
- (options, args) = self.parser.parse_args(command_args)
- except:
- # if you don't handle exceptions, passing an incorrect argument to the OptionParser will cause LLDB to exit
- # (courtesy of OptParse dealing with argument errors by throwing SystemExit)
- result.SetError("option parsing failed")
- return
-
- # Always get program state from the SBExecutionContext passed in as exe_ctx
- target = exe_ctx.GetTarget()
- if not target.IsValid():
- result.SetError("invalid target")
- return
-
- if len(args) == 0:
- result.SetError("one or more executable paths must be specified")
- return
-
- for module_path in args:
- module = target.module[module_path]
- if not module:
- result.SetError('no module found that matches "%s".' % (module_path))
- return
- num_cus = module.GetNumCompileUnits()
- print >>result, 'Module: "%s"' % (module.file.fullpath),
- if num_cus == 0:
- print >>result, 'no debug info.'
- continue
- print >>result, 'has %u compile units:' % (num_cus)
- for i in range(num_cus):
- cu = module.GetCompileUnitAtIndex(i)
- print >>result, ' Compile Unit: %s' % (cu.file.fullpath)
- if options.support_files:
- num_support_files = cu.GetNumSupportFiles()
- for j in range(num_support_files):
- path = cu.GetSupportFileAtIndex(j).fullpath
- print >>result, ' file[%u]: %s' % (j, path)
-
-
-def __lldb_init_module(debugger, dict):
- # This initializer is being run from LLDB in the embedded command interpreter
-
- # Add any commands contained in this module to LLDB
- debugger.HandleCommand(
- 'command script add -c %s.DumpLineTables %s' % (__name__,
- DumpLineTables.command_name))
- debugger.HandleCommand(
- 'command script add -c %s.DumpFiles %s' % (__name__, DumpFiles.command_name))
- print 'The "%s" and "%s" commands have been installed.' % (DumpLineTables.command_name,
- DumpFiles.command_name)
diff --git a/examples/python/lldbtk.py b/examples/python/lldbtk.py
deleted file mode 100644
index a978b9e07037..000000000000
--- a/examples/python/lldbtk.py
+++ /dev/null
@@ -1,613 +0,0 @@
-#!/usr/bin/python
-
-import lldb
-import shlex
-import sys
-from Tkinter import *
-import ttk
-
-
-class ValueTreeItemDelegate(object):
-
- def __init__(self, value):
- self.value = value
-
- def get_item_dictionary(self):
- name = self.value.name
- if name is None:
- name = ''
- typename = self.value.type
- if typename is None:
- typename = ''
- value = self.value.value
- if value is None:
- value = ''
- summary = self.value.summary
- if summary is None:
- summary = ''
- has_children = self.value.MightHaveChildren()
- return {'#0': name,
- 'typename': typename,
- 'value': value,
- 'summary': summary,
- 'children': has_children,
- 'tree-item-delegate': self}
-
- def get_child_item_dictionaries(self):
- item_dicts = list()
- for i in range(self.value.num_children):
- item_delegate = ValueTreeItemDelegate(
- self.value.GetChildAtIndex(i))
- item_dicts.append(item_delegate.get_item_dictionary())
- return item_dicts
-
-
-class FrameTreeItemDelegate(object):
-
- def __init__(self, frame):
- self.frame = frame
-
- def get_item_dictionary(self):
- id = self.frame.GetFrameID()
- name = 'frame #%u' % (id)
- value = '0x%16.16x' % (self.frame.GetPC())
- stream = lldb.SBStream()
- self.frame.GetDescription(stream)
- summary = stream.GetData().split("`")[1]
- return {
- '#0': name,
- 'value': value,
- 'summary': summary,
- 'children': self.frame.GetVariables(
- True,
- True,
- True,
- True).GetSize() > 0,
- 'tree-item-delegate': self}
-
- def get_child_item_dictionaries(self):
- item_dicts = list()
- variables = self.frame.GetVariables(True, True, True, True)
- n = variables.GetSize()
- for i in range(n):
- item_delegate = ValueTreeItemDelegate(variables[i])
- item_dicts.append(item_delegate.get_item_dictionary())
- return item_dicts
-
-
-class ThreadTreeItemDelegate(object):
-
- def __init__(self, thread):
- self.thread = thread
-
- def get_item_dictionary(self):
- num_frames = self.thread.GetNumFrames()
- name = 'thread #%u' % (self.thread.GetIndexID())
- value = '0x%x' % (self.thread.GetThreadID())
- summary = '%u frames' % (num_frames)
- return {'#0': name,
- 'value': value,
- 'summary': summary,
- 'children': num_frames > 0,
- 'tree-item-delegate': self}
-
- def get_child_item_dictionaries(self):
- item_dicts = list()
- for frame in self.thread:
- item_delegate = FrameTreeItemDelegate(frame)
- item_dicts.append(item_delegate.get_item_dictionary())
- return item_dicts
-
-
-class ProcessTreeItemDelegate(object):
-
- def __init__(self, process):
- self.process = process
-
- def get_item_dictionary(self):
- id = self.process.GetProcessID()
- num_threads = self.process.GetNumThreads()
- value = str(self.process.GetProcessID())
- summary = self.process.target.executable.fullpath
- return {'#0': 'process',
- 'value': value,
- 'summary': summary,
- 'children': num_threads > 0,
- 'tree-item-delegate': self}
-
- def get_child_item_dictionaries(self):
- item_dicts = list()
- for thread in self.process:
- item_delegate = ThreadTreeItemDelegate(thread)
- item_dicts.append(item_delegate.get_item_dictionary())
- return item_dicts
-
-
-class TargetTreeItemDelegate(object):
-
- def __init__(self, target):
- self.target = target
-
- def get_item_dictionary(self):
- value = str(self.target.triple)
- summary = self.target.executable.fullpath
- return {'#0': 'target',
- 'value': value,
- 'summary': summary,
- 'children': True,
- 'tree-item-delegate': self}
-
- def get_child_item_dictionaries(self):
- item_dicts = list()
- image_item_delegate = TargetImagesTreeItemDelegate(self.target)
- item_dicts.append(image_item_delegate.get_item_dictionary())
- return item_dicts
-
-
-class TargetImagesTreeItemDelegate(object):
-
- def __init__(self, target):
- self.target = target
-
- def get_item_dictionary(self):
- value = str(self.target.triple)
- summary = self.target.executable.fullpath
- num_modules = self.target.GetNumModules()
- return {'#0': 'images',
- 'value': '',
- 'summary': '%u images' % num_modules,
- 'children': num_modules > 0,
- 'tree-item-delegate': self}
-
- def get_child_item_dictionaries(self):
- item_dicts = list()
- for i in range(self.target.GetNumModules()):
- module = self.target.GetModuleAtIndex(i)
- image_item_delegate = ModuleTreeItemDelegate(
- self.target, module, i)
- item_dicts.append(image_item_delegate.get_item_dictionary())
- return item_dicts
-
-
-class ModuleTreeItemDelegate(object):
-
- def __init__(self, target, module, index):
- self.target = target
- self.module = module
- self.index = index
-
- def get_item_dictionary(self):
- name = 'module %u' % (self.index)
- value = self.module.file.basename
- summary = self.module.file.dirname
- return {'#0': name,
- 'value': value,
- 'summary': summary,
- 'children': True,
- 'tree-item-delegate': self}
-
- def get_child_item_dictionaries(self):
- item_dicts = list()
- sections_item_delegate = ModuleSectionsTreeItemDelegate(
- self.target, self.module)
- item_dicts.append(sections_item_delegate.get_item_dictionary())
-
- symbols_item_delegate = ModuleSymbolsTreeItemDelegate(
- self.target, self.module)
- item_dicts.append(symbols_item_delegate.get_item_dictionary())
-
- comp_units_item_delegate = ModuleCompileUnitsTreeItemDelegate(
- self.target, self.module)
- item_dicts.append(comp_units_item_delegate.get_item_dictionary())
- return item_dicts
-
-
-class ModuleSectionsTreeItemDelegate(object):
-
- def __init__(self, target, module):
- self.target = target
- self.module = module
-
- def get_item_dictionary(self):
- name = 'sections'
- value = ''
- summary = '%u sections' % (self.module.GetNumSections())
- return {'#0': name,
- 'value': value,
- 'summary': summary,
- 'children': True,
- 'tree-item-delegate': self}
-
- def get_child_item_dictionaries(self):
- item_dicts = list()
- num_sections = self.module.GetNumSections()
- for i in range(num_sections):
- section = self.module.GetSectionAtIndex(i)
- image_item_delegate = SectionTreeItemDelegate(self.target, section)
- item_dicts.append(image_item_delegate.get_item_dictionary())
- return item_dicts
-
-
-class SectionTreeItemDelegate(object):
-
- def __init__(self, target, section):
- self.target = target
- self.section = section
-
- def get_item_dictionary(self):
- name = self.section.name
- section_load_addr = self.section.GetLoadAddress(self.target)
- if section_load_addr != lldb.LLDB_INVALID_ADDRESS:
- value = '0x%16.16x' % (section_load_addr)
- else:
- value = '0x%16.16x *' % (self.section.file_addr)
- summary = ''
- return {'#0': name,
- 'value': value,
- 'summary': summary,
- 'children': self.section.GetNumSubSections() > 0,
- 'tree-item-delegate': self}
-
- def get_child_item_dictionaries(self):
- item_dicts = list()
- num_sections = self.section.GetNumSubSections()
- for i in range(num_sections):
- section = self.section.GetSubSectionAtIndex(i)
- image_item_delegate = SectionTreeItemDelegate(self.target, section)
- item_dicts.append(image_item_delegate.get_item_dictionary())
- return item_dicts
-
-
-class ModuleCompileUnitsTreeItemDelegate(object):
-
- def __init__(self, target, module):
- self.target = target
- self.module = module
-
- def get_item_dictionary(self):
- name = 'compile units'
- value = ''
- summary = '%u compile units' % (self.module.GetNumSections())
- return {'#0': name,
- 'value': value,
- 'summary': summary,
- 'children': self.module.GetNumCompileUnits() > 0,
- 'tree-item-delegate': self}
-
- def get_child_item_dictionaries(self):
- item_dicts = list()
- num_cus = self.module.GetNumCompileUnits()
- for i in range(num_cus):
- cu = self.module.GetCompileUnitAtIndex(i)
- image_item_delegate = CompileUnitTreeItemDelegate(self.target, cu)
- item_dicts.append(image_item_delegate.get_item_dictionary())
- return item_dicts
-
-
-class CompileUnitTreeItemDelegate(object):
-
- def __init__(self, target, cu):
- self.target = target
- self.cu = cu
-
- def get_item_dictionary(self):
- name = self.cu.GetFileSpec().basename
- value = ''
- num_lines = self.cu.GetNumLineEntries()
- summary = ''
- return {'#0': name,
- 'value': value,
- 'summary': summary,
- 'children': num_lines > 0,
- 'tree-item-delegate': self}
-
- def get_child_item_dictionaries(self):
- item_dicts = list()
- item_delegate = LineTableTreeItemDelegate(self.target, self.cu)
- item_dicts.append(item_delegate.get_item_dictionary())
- return item_dicts
-
-
-class LineTableTreeItemDelegate(object):
-
- def __init__(self, target, cu):
- self.target = target
- self.cu = cu
-
- def get_item_dictionary(self):
- name = 'line table'
- value = ''
- num_lines = self.cu.GetNumLineEntries()
- summary = '%u line entries' % (num_lines)
- return {'#0': name,
- 'value': value,
- 'summary': summary,
- 'children': num_lines > 0,
- 'tree-item-delegate': self}
-
- def get_child_item_dictionaries(self):
- item_dicts = list()
- num_lines = self.cu.GetNumLineEntries()
- for i in range(num_lines):
- line_entry = self.cu.GetLineEntryAtIndex(i)
- item_delegate = LineEntryTreeItemDelegate(
- self.target, line_entry, i)
- item_dicts.append(item_delegate.get_item_dictionary())
- return item_dicts
-
-
-class LineEntryTreeItemDelegate(object):
-
- def __init__(self, target, line_entry, index):
- self.target = target
- self.line_entry = line_entry
- self.index = index
-
- def get_item_dictionary(self):
- name = str(self.index)
- address = self.line_entry.GetStartAddress()
- load_addr = address.GetLoadAddress(self.target)
- if load_addr != lldb.LLDB_INVALID_ADDRESS:
- value = '0x%16.16x' % (load_addr)
- else:
- value = '0x%16.16x *' % (address.file_addr)
- summary = self.line_entry.GetFileSpec().fullpath + ':' + \
- str(self.line_entry.line)
- return {'#0': name,
- 'value': value,
- 'summary': summary,
- 'children': False,
- 'tree-item-delegate': self}
-
- def get_child_item_dictionaries(self):
- item_dicts = list()
- return item_dicts
-
-
-class InstructionTreeItemDelegate(object):
-
- def __init__(self, target, instr):
- self.target = target
- self.instr = instr
-
- def get_item_dictionary(self):
- address = self.instr.GetAddress()
- load_addr = address.GetLoadAddress(self.target)
- if load_addr != lldb.LLDB_INVALID_ADDRESS:
- name = '0x%16.16x' % (load_addr)
- else:
- name = '0x%16.16x *' % (address.file_addr)
- value = self.instr.GetMnemonic(
- self.target) + ' ' + self.instr.GetOperands(self.target)
- summary = self.instr.GetComment(self.target)
- return {'#0': name,
- 'value': value,
- 'summary': summary,
- 'children': False,
- 'tree-item-delegate': self}
-
-
-class ModuleSymbolsTreeItemDelegate(object):
-
- def __init__(self, target, module):
- self.target = target
- self.module = module
-
- def get_item_dictionary(self):
- name = 'symbols'
- value = ''
- summary = '%u symbols' % (self.module.GetNumSymbols())
- return {'#0': name,
- 'value': value,
- 'summary': summary,
- 'children': True,
- 'tree-item-delegate': self}
-
- def get_child_item_dictionaries(self):
- item_dicts = list()
- num_symbols = self.module.GetNumSymbols()
- for i in range(num_symbols):
- symbol = self.module.GetSymbolAtIndex(i)
- image_item_delegate = SymbolTreeItemDelegate(
- self.target, symbol, i)
- item_dicts.append(image_item_delegate.get_item_dictionary())
- return item_dicts
-
-
-class SymbolTreeItemDelegate(object):
-
- def __init__(self, target, symbol, index):
- self.target = target
- self.symbol = symbol
- self.index = index
-
- def get_item_dictionary(self):
- address = self.symbol.GetStartAddress()
- name = '[%u]' % self.index
- symbol_load_addr = address.GetLoadAddress(self.target)
- if symbol_load_addr != lldb.LLDB_INVALID_ADDRESS:
- value = '0x%16.16x' % (symbol_load_addr)
- else:
- value = '0x%16.16x *' % (address.file_addr)
- summary = self.symbol.name
- return {'#0': name,
- 'value': value,
- 'summary': summary,
- 'children': False,
- 'tree-item-delegate': self}
-
- def get_child_item_dictionaries(self):
- item_dicts = list()
- return item_dicts
-
-
-class DelegateTree(ttk.Frame):
-
- def __init__(self, column_dicts, delegate, title, name):
- ttk.Frame.__init__(self, name=name)
- self.pack(expand=Y, fill=BOTH)
- self.master.title(title)
- self.delegate = delegate
- self.columns_dicts = column_dicts
- self.item_id_to_item_dict = dict()
- frame = Frame(self)
- frame.pack(side=TOP, fill=BOTH, expand=Y)
- self._create_treeview(frame)
- self._populate_root()
-
- def _create_treeview(self, parent):
- frame = ttk.Frame(parent)
- frame.pack(side=TOP, fill=BOTH, expand=Y)
-
- column_ids = list()
- for i in range(1, len(self.columns_dicts)):
- column_ids.append(self.columns_dicts[i]['id'])
- # create the tree and scrollbars
- self.tree = ttk.Treeview(columns=column_ids)
-
- scroll_bar_v = ttk.Scrollbar(orient=VERTICAL, command=self.tree.yview)
- scroll_bar_h = ttk.Scrollbar(
- orient=HORIZONTAL, command=self.tree.xview)
- self.tree['yscroll'] = scroll_bar_v.set
- self.tree['xscroll'] = scroll_bar_h.set
-
- # setup column headings and columns properties
- for columns_dict in self.columns_dicts:
- self.tree.heading(
- columns_dict['id'],
- text=columns_dict['text'],
- anchor=columns_dict['anchor'])
- self.tree.column(
- columns_dict['id'],
- stretch=columns_dict['stretch'])
-
- # add tree and scrollbars to frame
- self.tree.grid(in_=frame, row=0, column=0, sticky=NSEW)
- scroll_bar_v.grid(in_=frame, row=0, column=1, sticky=NS)
- scroll_bar_h.grid(in_=frame, row=1, column=0, sticky=EW)
-
- # set frame resizing priorities
- frame.rowconfigure(0, weight=1)
- frame.columnconfigure(0, weight=1)
-
- # action to perform when a node is expanded
- self.tree.bind('<<TreeviewOpen>>', self._update_tree)
-
- def insert_items(self, parent_id, item_dicts):
- for item_dict in item_dicts:
- name = None
- values = list()
- first = True
- for columns_dict in self.columns_dicts:
- if first:
- name = item_dict[columns_dict['id']]
- first = False
- else:
- values.append(item_dict[columns_dict['id']])
- item_id = self.tree.insert(parent_id, # root item has an empty name
- END,
- text=name,
- values=values)
- self.item_id_to_item_dict[item_id] = item_dict
- if item_dict['children']:
- self.tree.insert(item_id, END, text='dummy')
-
- def _populate_root(self):
- # use current directory as root node
- self.insert_items('', self.delegate.get_child_item_dictionaries())
-
- def _update_tree(self, event):
- # user expanded a node - build the related directory
- item_id = self.tree.focus() # the id of the expanded node
- children = self.tree.get_children(item_id)
- if len(children):
- first_child = children[0]
- # if the node only has a 'dummy' child, remove it and
- # build new directory; skip if the node is already
- # populated
- if self.tree.item(first_child, option='text') == 'dummy':
- self.tree.delete(first_child)
- item_dict = self.item_id_to_item_dict[item_id]
- item_dicts = item_dict[
- 'tree-item-delegate'].get_child_item_dictionaries()
- self.insert_items(item_id, item_dicts)
-
-
-@lldb.command("tk-variables")
-def tk_variable_display(debugger, command, result, dict):
- # needed for tree creation in TK library as it uses sys.argv...
- sys.argv = ['tk-variables']
- target = debugger.GetSelectedTarget()
- if not target:
- print >>result, "invalid target"
- return
- process = target.GetProcess()
- if not process:
- print >>result, "invalid process"
- return
- thread = process.GetSelectedThread()
- if not thread:
- print >>result, "invalid thread"
- return
- frame = thread.GetSelectedFrame()
- if not frame:
- print >>result, "invalid frame"
- return
- # Parse command line args
- command_args = shlex.split(command)
- column_dicts = [{'id': '#0', 'text': 'Name', 'anchor': W, 'stretch': 0},
- {'id': 'typename', 'text': 'Type', 'anchor': W, 'stretch': 0},
- {'id': 'value', 'text': 'Value', 'anchor': W, 'stretch': 0},
- {'id': 'summary', 'text': 'Summary', 'anchor': W, 'stretch': 1}]
- tree = DelegateTree(
- column_dicts,
- FrameTreeItemDelegate(frame),
- 'Variables',
- 'lldb-tk-variables')
- tree.mainloop()
-
-
-@lldb.command("tk-process")
-def tk_process_display(debugger, command, result, dict):
- # needed for tree creation in TK library as it uses sys.argv...
- sys.argv = ['tk-process']
- target = debugger.GetSelectedTarget()
- if not target:
- print >>result, "invalid target"
- return
- process = target.GetProcess()
- if not process:
- print >>result, "invalid process"
- return
- # Parse command line args
- columnd_dicts = [{'id': '#0', 'text': 'Name', 'anchor': W, 'stretch': 0},
- {'id': 'value', 'text': 'Value', 'anchor': W, 'stretch': 0},
- {'id': 'summary', 'text': 'Summary', 'anchor': W, 'stretch': 1}]
- command_args = shlex.split(command)
- tree = DelegateTree(
- columnd_dicts,
- ProcessTreeItemDelegate(process),
- 'Process',
- 'lldb-tk-process')
- tree.mainloop()
-
-
-@lldb.command("tk-target")
-def tk_target_display(debugger, command, result, dict):
- # needed for tree creation in TK library as it uses sys.argv...
- sys.argv = ['tk-target']
- target = debugger.GetSelectedTarget()
- if not target:
- print >>result, "invalid target"
- return
- # Parse command line args
- columnd_dicts = [{'id': '#0', 'text': 'Name', 'anchor': W, 'stretch': 0},
- {'id': 'value', 'text': 'Value', 'anchor': W, 'stretch': 0},
- {'id': 'summary', 'text': 'Summary', 'anchor': W, 'stretch': 1}]
- command_args = shlex.split(command)
- tree = DelegateTree(
- columnd_dicts,
- TargetTreeItemDelegate(target),
- 'Target',
- 'lldb-tk-target')
- tree.mainloop()
diff --git a/examples/python/mach_o.py b/examples/python/mach_o.py
deleted file mode 100755
index faa05ac83078..000000000000
--- a/examples/python/mach_o.py
+++ /dev/null
@@ -1,1845 +0,0 @@
-#!/usr/bin/python
-
-import cmd
-import dict_utils
-import file_extract
-import optparse
-import re
-import struct
-import string
-import StringIO
-import sys
-import uuid
-
-# Mach header "magic" constants
-MH_MAGIC = 0xfeedface
-MH_CIGAM = 0xcefaedfe
-MH_MAGIC_64 = 0xfeedfacf
-MH_CIGAM_64 = 0xcffaedfe
-FAT_MAGIC = 0xcafebabe
-FAT_CIGAM = 0xbebafeca
-
-# Mach haeder "filetype" constants
-MH_OBJECT = 0x00000001
-MH_EXECUTE = 0x00000002
-MH_FVMLIB = 0x00000003
-MH_CORE = 0x00000004
-MH_PRELOAD = 0x00000005
-MH_DYLIB = 0x00000006
-MH_DYLINKER = 0x00000007
-MH_BUNDLE = 0x00000008
-MH_DYLIB_STUB = 0x00000009
-MH_DSYM = 0x0000000a
-MH_KEXT_BUNDLE = 0x0000000b
-
-# Mach haeder "flag" constant bits
-MH_NOUNDEFS = 0x00000001
-MH_INCRLINK = 0x00000002
-MH_DYLDLINK = 0x00000004
-MH_BINDATLOAD = 0x00000008
-MH_PREBOUND = 0x00000010
-MH_SPLIT_SEGS = 0x00000020
-MH_LAZY_INIT = 0x00000040
-MH_TWOLEVEL = 0x00000080
-MH_FORCE_FLAT = 0x00000100
-MH_NOMULTIDEFS = 0x00000200
-MH_NOFIXPREBINDING = 0x00000400
-MH_PREBINDABLE = 0x00000800
-MH_ALLMODSBOUND = 0x00001000
-MH_SUBSECTIONS_VIA_SYMBOLS = 0x00002000
-MH_CANONICAL = 0x00004000
-MH_WEAK_DEFINES = 0x00008000
-MH_BINDS_TO_WEAK = 0x00010000
-MH_ALLOW_STACK_EXECUTION = 0x00020000
-MH_ROOT_SAFE = 0x00040000
-MH_SETUID_SAFE = 0x00080000
-MH_NO_REEXPORTED_DYLIBS = 0x00100000
-MH_PIE = 0x00200000
-MH_DEAD_STRIPPABLE_DYLIB = 0x00400000
-MH_HAS_TLV_DESCRIPTORS = 0x00800000
-MH_NO_HEAP_EXECUTION = 0x01000000
-
-# Mach load command constants
-LC_REQ_DYLD = 0x80000000
-LC_SEGMENT = 0x00000001
-LC_SYMTAB = 0x00000002
-LC_SYMSEG = 0x00000003
-LC_THREAD = 0x00000004
-LC_UNIXTHREAD = 0x00000005
-LC_LOADFVMLIB = 0x00000006
-LC_IDFVMLIB = 0x00000007
-LC_IDENT = 0x00000008
-LC_FVMFILE = 0x00000009
-LC_PREPAGE = 0x0000000a
-LC_DYSYMTAB = 0x0000000b
-LC_LOAD_DYLIB = 0x0000000c
-LC_ID_DYLIB = 0x0000000d
-LC_LOAD_DYLINKER = 0x0000000e
-LC_ID_DYLINKER = 0x0000000f
-LC_PREBOUND_DYLIB = 0x00000010
-LC_ROUTINES = 0x00000011
-LC_SUB_FRAMEWORK = 0x00000012
-LC_SUB_UMBRELLA = 0x00000013
-LC_SUB_CLIENT = 0x00000014
-LC_SUB_LIBRARY = 0x00000015
-LC_TWOLEVEL_HINTS = 0x00000016
-LC_PREBIND_CKSUM = 0x00000017
-LC_LOAD_WEAK_DYLIB = 0x00000018 | LC_REQ_DYLD
-LC_SEGMENT_64 = 0x00000019
-LC_ROUTINES_64 = 0x0000001a
-LC_UUID = 0x0000001b
-LC_RPATH = 0x0000001c | LC_REQ_DYLD
-LC_CODE_SIGNATURE = 0x0000001d
-LC_SEGMENT_SPLIT_INFO = 0x0000001e
-LC_REEXPORT_DYLIB = 0x0000001f | LC_REQ_DYLD
-LC_LAZY_LOAD_DYLIB = 0x00000020
-LC_ENCRYPTION_INFO = 0x00000021
-LC_DYLD_INFO = 0x00000022
-LC_DYLD_INFO_ONLY = 0x00000022 | LC_REQ_DYLD
-LC_LOAD_UPWARD_DYLIB = 0x00000023 | LC_REQ_DYLD
-LC_VERSION_MIN_MACOSX = 0x00000024
-LC_VERSION_MIN_IPHONEOS = 0x00000025
-LC_FUNCTION_STARTS = 0x00000026
-LC_DYLD_ENVIRONMENT = 0x00000027
-
-# Mach CPU constants
-CPU_ARCH_MASK = 0xff000000
-CPU_ARCH_ABI64 = 0x01000000
-CPU_TYPE_ANY = 0xffffffff
-CPU_TYPE_VAX = 1
-CPU_TYPE_MC680x0 = 6
-CPU_TYPE_I386 = 7
-CPU_TYPE_X86_64 = CPU_TYPE_I386 | CPU_ARCH_ABI64
-CPU_TYPE_MIPS = 8
-CPU_TYPE_MC98000 = 10
-CPU_TYPE_HPPA = 11
-CPU_TYPE_ARM = 12
-CPU_TYPE_MC88000 = 13
-CPU_TYPE_SPARC = 14
-CPU_TYPE_I860 = 15
-CPU_TYPE_ALPHA = 16
-CPU_TYPE_POWERPC = 18
-CPU_TYPE_POWERPC64 = CPU_TYPE_POWERPC | CPU_ARCH_ABI64
-
-# VM protection constants
-VM_PROT_READ = 1
-VM_PROT_WRITE = 2
-VM_PROT_EXECUTE = 4
-
-# VM protection constants
-N_STAB = 0xe0
-N_PEXT = 0x10
-N_TYPE = 0x0e
-N_EXT = 0x01
-
-# Values for nlist N_TYPE bits of the "Mach.NList.type" field.
-N_UNDF = 0x0
-N_ABS = 0x2
-N_SECT = 0xe
-N_PBUD = 0xc
-N_INDR = 0xa
-
-# Section indexes for the "Mach.NList.sect_idx" fields
-NO_SECT = 0
-MAX_SECT = 255
-
-# Stab defines
-N_GSYM = 0x20
-N_FNAME = 0x22
-N_FUN = 0x24
-N_STSYM = 0x26
-N_LCSYM = 0x28
-N_BNSYM = 0x2e
-N_OPT = 0x3c
-N_RSYM = 0x40
-N_SLINE = 0x44
-N_ENSYM = 0x4e
-N_SSYM = 0x60
-N_SO = 0x64
-N_OSO = 0x66
-N_LSYM = 0x80
-N_BINCL = 0x82
-N_SOL = 0x84
-N_PARAMS = 0x86
-N_VERSION = 0x88
-N_OLEVEL = 0x8A
-N_PSYM = 0xa0
-N_EINCL = 0xa2
-N_ENTRY = 0xa4
-N_LBRAC = 0xc0
-N_EXCL = 0xc2
-N_RBRAC = 0xe0
-N_BCOMM = 0xe2
-N_ECOMM = 0xe4
-N_ECOML = 0xe8
-N_LENG = 0xfe
-
-vm_prot_names = ['---', 'r--', '-w-', 'rw-', '--x', 'r-x', '-wx', 'rwx']
-
-
-def dump_memory(base_addr, data, hex_bytes_len, num_per_line):
- hex_bytes = data.encode('hex')
- if hex_bytes_len == -1:
- hex_bytes_len = len(hex_bytes)
- addr = base_addr
- ascii_str = ''
- i = 0
- while i < hex_bytes_len:
- if ((i / 2) % num_per_line) == 0:
- if i > 0:
- print ' %s' % (ascii_str)
- ascii_str = ''
- print '0x%8.8x:' % (addr + i),
- hex_byte = hex_bytes[i:i + 2]
- print hex_byte,
- int_byte = int(hex_byte, 16)
- ascii_char = '%c' % (int_byte)
- if int_byte >= 32 and int_byte < 127:
- ascii_str += ascii_char
- else:
- ascii_str += '.'
- i = i + 2
- if ascii_str:
- if (i / 2) % num_per_line:
- padding = num_per_line - ((i / 2) % num_per_line)
- else:
- padding = 0
- print '%*s%s' % (padding * 3 + 1, '', ascii_str)
- print
-
-
-class TerminalColors:
- '''Simple terminal colors class'''
-
- def __init__(self, enabled=True):
- # TODO: discover terminal type from "file" and disable if
- # it can't handle the color codes
- self.enabled = enabled
-
- def reset(self):
- '''Reset all terminal colors and formatting.'''
- if self.enabled:
- return "\x1b[0m"
- return ''
-
- def bold(self, on=True):
- '''Enable or disable bold depending on the "on" parameter.'''
- if self.enabled:
- if on:
- return "\x1b[1m"
- else:
- return "\x1b[22m"
- return ''
-
- def italics(self, on=True):
- '''Enable or disable italics depending on the "on" parameter.'''
- if self.enabled:
- if on:
- return "\x1b[3m"
- else:
- return "\x1b[23m"
- return ''
-
- def underline(self, on=True):
- '''Enable or disable underline depending on the "on" parameter.'''
- if self.enabled:
- if on:
- return "\x1b[4m"
- else:
- return "\x1b[24m"
- return ''
-
- def inverse(self, on=True):
- '''Enable or disable inverse depending on the "on" parameter.'''
- if self.enabled:
- if on:
- return "\x1b[7m"
- else:
- return "\x1b[27m"
- return ''
-
- def strike(self, on=True):
- '''Enable or disable strike through depending on the "on" parameter.'''
- if self.enabled:
- if on:
- return "\x1b[9m"
- else:
- return "\x1b[29m"
- return ''
-
- def black(self, fg=True):
- '''Set the foreground or background color to black.
- The foreground color will be set if "fg" tests True. The background color will be set if "fg" tests False.'''
- if self.enabled:
- if fg:
- return "\x1b[30m"
- else:
- return "\x1b[40m"
- return ''
-
- def red(self, fg=True):
- '''Set the foreground or background color to red.
- The foreground color will be set if "fg" tests True. The background color will be set if "fg" tests False.'''
- if self.enabled:
- if fg:
- return "\x1b[31m"
- else:
- return "\x1b[41m"
- return ''
-
- def green(self, fg=True):
- '''Set the foreground or background color to green.
- The foreground color will be set if "fg" tests True. The background color will be set if "fg" tests False.'''
- if self.enabled:
- if fg:
- return "\x1b[32m"
- else:
- return "\x1b[42m"
- return ''
-
- def yellow(self, fg=True):
- '''Set the foreground or background color to yellow.
- The foreground color will be set if "fg" tests True. The background color will be set if "fg" tests False.'''
- if self.enabled:
- if fg:
- return "\x1b[43m"
- else:
- return "\x1b[33m"
- return ''
-
- def blue(self, fg=True):
- '''Set the foreground or background color to blue.
- The foreground color will be set if "fg" tests True. The background color will be set if "fg" tests False.'''
- if self.enabled:
- if fg:
- return "\x1b[34m"
- else:
- return "\x1b[44m"
- return ''
-
- def magenta(self, fg=True):
- '''Set the foreground or background color to magenta.
- The foreground color will be set if "fg" tests True. The background color will be set if "fg" tests False.'''
- if self.enabled:
- if fg:
- return "\x1b[35m"
- else:
- return "\x1b[45m"
- return ''
-
- def cyan(self, fg=True):
- '''Set the foreground or background color to cyan.
- The foreground color will be set if "fg" tests True. The background color will be set if "fg" tests False.'''
- if self.enabled:
- if fg:
- return "\x1b[36m"
- else:
- return "\x1b[46m"
- return ''
-
- def white(self, fg=True):
- '''Set the foreground or background color to white.
- The foreground color will be set if "fg" tests True. The background color will be set if "fg" tests False.'''
- if self.enabled:
- if fg:
- return "\x1b[37m"
- else:
- return "\x1b[47m"
- return ''
-
- def default(self, fg=True):
- '''Set the foreground or background color to the default.
- The foreground color will be set if "fg" tests True. The background color will be set if "fg" tests False.'''
- if self.enabled:
- if fg:
- return "\x1b[39m"
- else:
- return "\x1b[49m"
- return ''
-
-
-def swap_unpack_char():
- """Returns the unpack prefix that will for non-native endian-ness."""
- if struct.pack('H', 1).startswith("\x00"):
- return '<'
- return '>'
-
-
-def dump_hex_bytes(addr, s, bytes_per_line=16):
- i = 0
- line = ''
- for ch in s:
- if (i % bytes_per_line) == 0:
- if line:
- print line
- line = '%#8.8x: ' % (addr + i)
- line += "%02X " % ord(ch)
- i += 1
- print line
-
-
-def dump_hex_byte_string_diff(addr, a, b, bytes_per_line=16):
- i = 0
- line = ''
- a_len = len(a)
- b_len = len(b)
- if a_len < b_len:
- max_len = b_len
- else:
- max_len = a_len
- tty_colors = TerminalColors(True)
- for i in range(max_len):
- ch = None
- if i < a_len:
- ch_a = a[i]
- ch = ch_a
- else:
- ch_a = None
- if i < b_len:
- ch_b = b[i]
- if not ch:
- ch = ch_b
- else:
- ch_b = None
- mismatch = ch_a != ch_b
- if (i % bytes_per_line) == 0:
- if line:
- print line
- line = '%#8.8x: ' % (addr + i)
- if mismatch:
- line += tty_colors.red()
- line += "%02X " % ord(ch)
- if mismatch:
- line += tty_colors.default()
- i += 1
-
- print line
-
-
-class Mach:
- """Class that does everything mach-o related"""
-
- class Arch:
- """Class that implements mach-o architectures"""
-
- def __init__(self, c=0, s=0):
- self.cpu = c
- self.sub = s
-
- def set_cpu_type(self, c):
- self.cpu = c
-
- def set_cpu_subtype(self, s):
- self.sub = s
-
- def set_arch(self, c, s):
- self.cpu = c
- self.sub = s
-
- def is_64_bit(self):
- return (self.cpu & CPU_ARCH_ABI64) != 0
-
- cpu_infos = [
- ["arm", CPU_TYPE_ARM, CPU_TYPE_ANY],
- ["arm", CPU_TYPE_ARM, 0],
- ["armv4", CPU_TYPE_ARM, 5],
- ["armv6", CPU_TYPE_ARM, 6],
- ["armv5", CPU_TYPE_ARM, 7],
- ["xscale", CPU_TYPE_ARM, 8],
- ["armv7", CPU_TYPE_ARM, 9],
- ["armv7f", CPU_TYPE_ARM, 10],
- ["armv7s", CPU_TYPE_ARM, 11],
- ["armv7k", CPU_TYPE_ARM, 12],
- ["armv7m", CPU_TYPE_ARM, 15],
- ["armv7em", CPU_TYPE_ARM, 16],
- ["ppc", CPU_TYPE_POWERPC, CPU_TYPE_ANY],
- ["ppc", CPU_TYPE_POWERPC, 0],
- ["ppc601", CPU_TYPE_POWERPC, 1],
- ["ppc602", CPU_TYPE_POWERPC, 2],
- ["ppc603", CPU_TYPE_POWERPC, 3],
- ["ppc603e", CPU_TYPE_POWERPC, 4],
- ["ppc603ev", CPU_TYPE_POWERPC, 5],
- ["ppc604", CPU_TYPE_POWERPC, 6],
- ["ppc604e", CPU_TYPE_POWERPC, 7],
- ["ppc620", CPU_TYPE_POWERPC, 8],
- ["ppc750", CPU_TYPE_POWERPC, 9],
- ["ppc7400", CPU_TYPE_POWERPC, 10],
- ["ppc7450", CPU_TYPE_POWERPC, 11],
- ["ppc970", CPU_TYPE_POWERPC, 100],
- ["ppc64", CPU_TYPE_POWERPC64, 0],
- ["ppc970-64", CPU_TYPE_POWERPC64, 100],
- ["i386", CPU_TYPE_I386, 3],
- ["i486", CPU_TYPE_I386, 4],
- ["i486sx", CPU_TYPE_I386, 0x84],
- ["i386", CPU_TYPE_I386, CPU_TYPE_ANY],
- ["x86_64", CPU_TYPE_X86_64, 3],
- ["x86_64", CPU_TYPE_X86_64, CPU_TYPE_ANY],
- ]
-
- def __str__(self):
- for info in self.cpu_infos:
- if self.cpu == info[1] and (self.sub & 0x00ffffff) == info[2]:
- return info[0]
- return "{0}.{1}".format(self.cpu, self.sub)
-
- class Magic(dict_utils.Enum):
-
- enum = {
- 'MH_MAGIC': MH_MAGIC,
- 'MH_CIGAM': MH_CIGAM,
- 'MH_MAGIC_64': MH_MAGIC_64,
- 'MH_CIGAM_64': MH_CIGAM_64,
- 'FAT_MAGIC': FAT_MAGIC,
- 'FAT_CIGAM': FAT_CIGAM
- }
-
- def __init__(self, initial_value=0):
- dict_utils.Enum.__init__(self, initial_value, self.enum)
-
- def is_skinny_mach_file(self):
- return self.value == MH_MAGIC or self.value == MH_CIGAM or self.value == MH_MAGIC_64 or self.value == MH_CIGAM_64
-
- def is_universal_mach_file(self):
- return self.value == FAT_MAGIC or self.value == FAT_CIGAM
-
- def unpack(self, data):
- data.set_byte_order('native')
- self.value = data.get_uint32()
-
- def get_byte_order(self):
- if self.value == MH_CIGAM or self.value == MH_CIGAM_64 or self.value == FAT_CIGAM:
- return swap_unpack_char()
- else:
- return '='
-
- def is_64_bit(self):
- return self.value == MH_MAGIC_64 or self.value == MH_CIGAM_64
-
- def __init__(self):
- self.magic = Mach.Magic()
- self.content = None
- self.path = None
-
- def extract(self, path, extractor):
- self.path = path
- self.unpack(extractor)
-
- def parse(self, path):
- self.path = path
- try:
- f = open(self.path)
- file_extractor = file_extract.FileExtract(f, '=')
- self.unpack(file_extractor)
- # f.close()
- except IOError as xxx_todo_changeme:
- (errno, strerror) = xxx_todo_changeme.args
- print "I/O error({0}): {1}".format(errno, strerror)
- except ValueError:
- print "Could not convert data to an integer."
- except:
- print "Unexpected error:", sys.exc_info()[0]
- raise
-
- def compare(self, rhs):
- self.content.compare(rhs.content)
-
- def dump(self, options=None):
- self.content.dump(options)
-
- def dump_header(self, dump_description=True, options=None):
- self.content.dump_header(dump_description, options)
-
- def dump_load_commands(self, dump_description=True, options=None):
- self.content.dump_load_commands(dump_description, options)
-
- def dump_sections(self, dump_description=True, options=None):
- self.content.dump_sections(dump_description, options)
-
- def dump_section_contents(self, options):
- self.content.dump_section_contents(options)
-
- def dump_symtab(self, dump_description=True, options=None):
- self.content.dump_symtab(dump_description, options)
-
- def dump_symbol_names_matching_regex(self, regex, file=None):
- self.content.dump_symbol_names_matching_regex(regex, file)
-
- def description(self):
- return self.content.description()
-
- def unpack(self, data):
- self.magic.unpack(data)
- if self.magic.is_skinny_mach_file():
- self.content = Mach.Skinny(self.path)
- elif self.magic.is_universal_mach_file():
- self.content = Mach.Universal(self.path)
- else:
- self.content = None
-
- if self.content is not None:
- self.content.unpack(data, self.magic)
-
- def is_valid(self):
- return self.content is not None
-
- class Universal:
-
- def __init__(self, path):
- self.path = path
- self.type = 'universal'
- self.file_off = 0
- self.magic = None
- self.nfat_arch = 0
- self.archs = list()
-
- def description(self):
- s = '%#8.8x: %s (' % (self.file_off, self.path)
- archs_string = ''
- for arch in self.archs:
- if len(archs_string):
- archs_string += ', '
- archs_string += '%s' % arch.arch
- s += archs_string
- s += ')'
- return s
-
- def unpack(self, data, magic=None):
- self.file_off = data.tell()
- if magic is None:
- self.magic = Mach.Magic()
- self.magic.unpack(data)
- else:
- self.magic = magic
- self.file_off = self.file_off - 4
- # Universal headers are always in big endian
- data.set_byte_order('big')
- self.nfat_arch = data.get_uint32()
- for i in range(self.nfat_arch):
- self.archs.append(Mach.Universal.ArchInfo())
- self.archs[i].unpack(data)
- for i in range(self.nfat_arch):
- self.archs[i].mach = Mach.Skinny(self.path)
- data.seek(self.archs[i].offset, 0)
- skinny_magic = Mach.Magic()
- skinny_magic.unpack(data)
- self.archs[i].mach.unpack(data, skinny_magic)
-
- def compare(self, rhs):
- print 'error: comparing two universal files is not supported yet'
- return False
-
- def dump(self, options):
- if options.dump_header:
- print
- print "Universal Mach File: magic = %s, nfat_arch = %u" % (self.magic, self.nfat_arch)
- print
- if self.nfat_arch > 0:
- if options.dump_header:
- self.archs[0].dump_header(True, options)
- for i in range(self.nfat_arch):
- self.archs[i].dump_flat(options)
- if options.dump_header:
- print
- for i in range(self.nfat_arch):
- self.archs[i].mach.dump(options)
-
- def dump_header(self, dump_description=True, options=None):
- if dump_description:
- print self.description()
- for i in range(self.nfat_arch):
- self.archs[i].mach.dump_header(True, options)
- print
-
- def dump_load_commands(self, dump_description=True, options=None):
- if dump_description:
- print self.description()
- for i in range(self.nfat_arch):
- self.archs[i].mach.dump_load_commands(True, options)
- print
-
- def dump_sections(self, dump_description=True, options=None):
- if dump_description:
- print self.description()
- for i in range(self.nfat_arch):
- self.archs[i].mach.dump_sections(True, options)
- print
-
- def dump_section_contents(self, options):
- for i in range(self.nfat_arch):
- self.archs[i].mach.dump_section_contents(options)
- print
-
- def dump_symtab(self, dump_description=True, options=None):
- if dump_description:
- print self.description()
- for i in range(self.nfat_arch):
- self.archs[i].mach.dump_symtab(True, options)
- print
-
- def dump_symbol_names_matching_regex(self, regex, file=None):
- for i in range(self.nfat_arch):
- self.archs[i].mach.dump_symbol_names_matching_regex(
- regex, file)
-
- class ArchInfo:
-
- def __init__(self):
- self.arch = Mach.Arch(0, 0)
- self.offset = 0
- self.size = 0
- self.align = 0
- self.mach = None
-
- def unpack(self, data):
- # Universal headers are always in big endian
- data.set_byte_order('big')
- self.arch.cpu, self.arch.sub, self.offset, self.size, self.align = data.get_n_uint32(
- 5)
-
- def dump_header(self, dump_description=True, options=None):
- if options.verbose:
- print "CPU SUBTYPE OFFSET SIZE ALIGN"
- print "---------- ---------- ---------- ---------- ----------"
- else:
- print "ARCH FILEOFFSET FILESIZE ALIGN"
- print "---------- ---------- ---------- ----------"
-
- def dump_flat(self, options):
- if options.verbose:
- print "%#8.8x %#8.8x %#8.8x %#8.8x %#8.8x" % (self.arch.cpu, self.arch.sub, self.offset, self.size, self.align)
- else:
- print "%-10s %#8.8x %#8.8x %#8.8x" % (self.arch, self.offset, self.size, self.align)
-
- def dump(self):
- print " cputype: %#8.8x" % self.arch.cpu
- print "cpusubtype: %#8.8x" % self.arch.sub
- print " offset: %#8.8x" % self.offset
- print " size: %#8.8x" % self.size
- print " align: %#8.8x" % self.align
-
- def __str__(self):
- return "Mach.Universal.ArchInfo: %#8.8x %#8.8x %#8.8x %#8.8x %#8.8x" % (
- self.arch.cpu, self.arch.sub, self.offset, self.size, self.align)
-
- def __repr__(self):
- return "Mach.Universal.ArchInfo: %#8.8x %#8.8x %#8.8x %#8.8x %#8.8x" % (
- self.arch.cpu, self.arch.sub, self.offset, self.size, self.align)
-
- class Flags:
-
- def __init__(self, b):
- self.bits = b
-
- def __str__(self):
- s = ''
- if self.bits & MH_NOUNDEFS:
- s += 'MH_NOUNDEFS | '
- if self.bits & MH_INCRLINK:
- s += 'MH_INCRLINK | '
- if self.bits & MH_DYLDLINK:
- s += 'MH_DYLDLINK | '
- if self.bits & MH_BINDATLOAD:
- s += 'MH_BINDATLOAD | '
- if self.bits & MH_PREBOUND:
- s += 'MH_PREBOUND | '
- if self.bits & MH_SPLIT_SEGS:
- s += 'MH_SPLIT_SEGS | '
- if self.bits & MH_LAZY_INIT:
- s += 'MH_LAZY_INIT | '
- if self.bits & MH_TWOLEVEL:
- s += 'MH_TWOLEVEL | '
- if self.bits & MH_FORCE_FLAT:
- s += 'MH_FORCE_FLAT | '
- if self.bits & MH_NOMULTIDEFS:
- s += 'MH_NOMULTIDEFS | '
- if self.bits & MH_NOFIXPREBINDING:
- s += 'MH_NOFIXPREBINDING | '
- if self.bits & MH_PREBINDABLE:
- s += 'MH_PREBINDABLE | '
- if self.bits & MH_ALLMODSBOUND:
- s += 'MH_ALLMODSBOUND | '
- if self.bits & MH_SUBSECTIONS_VIA_SYMBOLS:
- s += 'MH_SUBSECTIONS_VIA_SYMBOLS | '
- if self.bits & MH_CANONICAL:
- s += 'MH_CANONICAL | '
- if self.bits & MH_WEAK_DEFINES:
- s += 'MH_WEAK_DEFINES | '
- if self.bits & MH_BINDS_TO_WEAK:
- s += 'MH_BINDS_TO_WEAK | '
- if self.bits & MH_ALLOW_STACK_EXECUTION:
- s += 'MH_ALLOW_STACK_EXECUTION | '
- if self.bits & MH_ROOT_SAFE:
- s += 'MH_ROOT_SAFE | '
- if self.bits & MH_SETUID_SAFE:
- s += 'MH_SETUID_SAFE | '
- if self.bits & MH_NO_REEXPORTED_DYLIBS:
- s += 'MH_NO_REEXPORTED_DYLIBS | '
- if self.bits & MH_PIE:
- s += 'MH_PIE | '
- if self.bits & MH_DEAD_STRIPPABLE_DYLIB:
- s += 'MH_DEAD_STRIPPABLE_DYLIB | '
- if self.bits & MH_HAS_TLV_DESCRIPTORS:
- s += 'MH_HAS_TLV_DESCRIPTORS | '
- if self.bits & MH_NO_HEAP_EXECUTION:
- s += 'MH_NO_HEAP_EXECUTION | '
- # Strip the trailing " |" if we have any flags
- if len(s) > 0:
- s = s[0:-2]
- return s
-
- class FileType(dict_utils.Enum):
-
- enum = {
- 'MH_OBJECT': MH_OBJECT,
- 'MH_EXECUTE': MH_EXECUTE,
- 'MH_FVMLIB': MH_FVMLIB,
- 'MH_CORE': MH_CORE,
- 'MH_PRELOAD': MH_PRELOAD,
- 'MH_DYLIB': MH_DYLIB,
- 'MH_DYLINKER': MH_DYLINKER,
- 'MH_BUNDLE': MH_BUNDLE,
- 'MH_DYLIB_STUB': MH_DYLIB_STUB,
- 'MH_DSYM': MH_DSYM,
- 'MH_KEXT_BUNDLE': MH_KEXT_BUNDLE
- }
-
- def __init__(self, initial_value=0):
- dict_utils.Enum.__init__(self, initial_value, self.enum)
-
- class Skinny:
-
- def __init__(self, path):
- self.path = path
- self.type = 'skinny'
- self.data = None
- self.file_off = 0
- self.magic = 0
- self.arch = Mach.Arch(0, 0)
- self.filetype = Mach.FileType(0)
- self.ncmds = 0
- self.sizeofcmds = 0
- self.flags = Mach.Flags(0)
- self.uuid = None
- self.commands = list()
- self.segments = list()
- self.sections = list()
- self.symbols = list()
- self.sections.append(Mach.Section())
-
- def description(self):
- return '%#8.8x: %s (%s)' % (self.file_off, self.path, self.arch)
-
- def unpack(self, data, magic=None):
- self.data = data
- self.file_off = data.tell()
- if magic is None:
- self.magic = Mach.Magic()
- self.magic.unpack(data)
- else:
- self.magic = magic
- self.file_off = self.file_off - 4
- data.set_byte_order(self.magic.get_byte_order())
- self.arch.cpu, self.arch.sub, self.filetype.value, self.ncmds, self.sizeofcmds, bits = data.get_n_uint32(
- 6)
- self.flags.bits = bits
-
- if self.is_64_bit():
- data.get_uint32() # Skip reserved word in mach_header_64
-
- for i in range(0, self.ncmds):
- lc = self.unpack_load_command(data)
- self.commands.append(lc)
-
- def get_data(self):
- if self.data:
- self.data.set_byte_order(self.magic.get_byte_order())
- return self.data
- return None
-
- def unpack_load_command(self, data):
- lc = Mach.LoadCommand()
- lc.unpack(self, data)
- lc_command = lc.command.get_enum_value()
- if (lc_command == LC_SEGMENT or
- lc_command == LC_SEGMENT_64):
- lc = Mach.SegmentLoadCommand(lc)
- lc.unpack(self, data)
- elif (lc_command == LC_LOAD_DYLIB or
- lc_command == LC_ID_DYLIB or
- lc_command == LC_LOAD_WEAK_DYLIB or
- lc_command == LC_REEXPORT_DYLIB):
- lc = Mach.DylibLoadCommand(lc)
- lc.unpack(self, data)
- elif (lc_command == LC_LOAD_DYLINKER or
- lc_command == LC_SUB_FRAMEWORK or
- lc_command == LC_SUB_CLIENT or
- lc_command == LC_SUB_UMBRELLA or
- lc_command == LC_SUB_LIBRARY or
- lc_command == LC_ID_DYLINKER or
- lc_command == LC_RPATH):
- lc = Mach.LoadDYLDLoadCommand(lc)
- lc.unpack(self, data)
- elif (lc_command == LC_DYLD_INFO_ONLY):
- lc = Mach.DYLDInfoOnlyLoadCommand(lc)
- lc.unpack(self, data)
- elif (lc_command == LC_SYMTAB):
- lc = Mach.SymtabLoadCommand(lc)
- lc.unpack(self, data)
- elif (lc_command == LC_DYSYMTAB):
- lc = Mach.DYLDSymtabLoadCommand(lc)
- lc.unpack(self, data)
- elif (lc_command == LC_UUID):
- lc = Mach.UUIDLoadCommand(lc)
- lc.unpack(self, data)
- elif (lc_command == LC_CODE_SIGNATURE or
- lc_command == LC_SEGMENT_SPLIT_INFO or
- lc_command == LC_FUNCTION_STARTS):
- lc = Mach.DataBlobLoadCommand(lc)
- lc.unpack(self, data)
- elif (lc_command == LC_UNIXTHREAD):
- lc = Mach.UnixThreadLoadCommand(lc)
- lc.unpack(self, data)
- elif (lc_command == LC_ENCRYPTION_INFO):
- lc = Mach.EncryptionInfoLoadCommand(lc)
- lc.unpack(self, data)
- lc.skip(data)
- return lc
-
- def compare(self, rhs):
- print "\nComparing:"
- print "a) %s %s" % (self.arch, self.path)
- print "b) %s %s" % (rhs.arch, rhs.path)
- result = True
- if self.type == rhs.type:
- for lhs_section in self.sections[1:]:
- rhs_section = rhs.get_section_by_section(lhs_section)
- if rhs_section:
- print 'comparing %s.%s...' % (lhs_section.segname, lhs_section.sectname),
- sys.stdout.flush()
- lhs_data = lhs_section.get_contents(self)
- rhs_data = rhs_section.get_contents(rhs)
- if lhs_data and rhs_data:
- if lhs_data == rhs_data:
- print 'ok'
- else:
- lhs_data_len = len(lhs_data)
- rhs_data_len = len(rhs_data)
- # if lhs_data_len < rhs_data_len:
- # if lhs_data == rhs_data[0:lhs_data_len]:
- # print 'section data for %s matches the first %u bytes' % (lhs_section.sectname, lhs_data_len)
- # else:
- # # TODO: check padding
- # result = False
- # elif lhs_data_len > rhs_data_len:
- # if lhs_data[0:rhs_data_len] == rhs_data:
- # print 'section data for %s matches the first %u bytes' % (lhs_section.sectname, lhs_data_len)
- # else:
- # # TODO: check padding
- # result = False
- # else:
- result = False
- print 'error: sections differ'
- # print 'a) %s' % (lhs_section)
- # dump_hex_byte_string_diff(0, lhs_data, rhs_data)
- # print 'b) %s' % (rhs_section)
- # dump_hex_byte_string_diff(0, rhs_data, lhs_data)
- elif lhs_data and not rhs_data:
- print 'error: section data missing from b:'
- print 'a) %s' % (lhs_section)
- print 'b) %s' % (rhs_section)
- result = False
- elif not lhs_data and rhs_data:
- print 'error: section data missing from a:'
- print 'a) %s' % (lhs_section)
- print 'b) %s' % (rhs_section)
- result = False
- elif lhs_section.offset or rhs_section.offset:
- print 'error: section data missing for both a and b:'
- print 'a) %s' % (lhs_section)
- print 'b) %s' % (rhs_section)
- result = False
- else:
- print 'ok'
- else:
- result = False
- print 'error: section %s is missing in %s' % (lhs_section.sectname, rhs.path)
- else:
- print 'error: comaparing a %s mach-o file with a %s mach-o file is not supported' % (self.type, rhs.type)
- result = False
- if not result:
- print 'error: mach files differ'
- return result
-
- def dump_header(self, dump_description=True, options=None):
- if options.verbose:
- print "MAGIC CPU SUBTYPE FILETYPE NUM CMDS SIZE CMDS FLAGS"
- print "---------- ---------- ---------- ---------- -------- ---------- ----------"
- else:
- print "MAGIC ARCH FILETYPE NUM CMDS SIZE CMDS FLAGS"
- print "------------ ---------- -------------- -------- ---------- ----------"
-
- def dump_flat(self, options):
- if options.verbose:
- print "%#8.8x %#8.8x %#8.8x %#8.8x %#8u %#8.8x %#8.8x" % (self.magic, self.arch.cpu, self.arch.sub, self.filetype.value, self.ncmds, self.sizeofcmds, self.flags.bits)
- else:
- print "%-12s %-10s %-14s %#8u %#8.8x %s" % (self.magic, self.arch, self.filetype, self.ncmds, self.sizeofcmds, self.flags)
-
- def dump(self, options):
- if options.dump_header:
- self.dump_header(True, options)
- if options.dump_load_commands:
- self.dump_load_commands(False, options)
- if options.dump_sections:
- self.dump_sections(False, options)
- if options.section_names:
- self.dump_section_contents(options)
- if options.dump_symtab:
- self.get_symtab()
- if len(self.symbols):
- self.dump_sections(False, options)
- else:
- print "No symbols"
- if options.find_mangled:
- self.dump_symbol_names_matching_regex(re.compile('^_?_Z'))
-
- def dump_header(self, dump_description=True, options=None):
- if dump_description:
- print self.description()
- print "Mach Header"
- print " magic: %#8.8x %s" % (self.magic.value, self.magic)
- print " cputype: %#8.8x %s" % (self.arch.cpu, self.arch)
- print " cpusubtype: %#8.8x" % self.arch.sub
- print " filetype: %#8.8x %s" % (self.filetype.get_enum_value(), self.filetype.get_enum_name())
- print " ncmds: %#8.8x %u" % (self.ncmds, self.ncmds)
- print " sizeofcmds: %#8.8x" % self.sizeofcmds
- print " flags: %#8.8x %s" % (self.flags.bits, self.flags)
-
- def dump_load_commands(self, dump_description=True, options=None):
- if dump_description:
- print self.description()
- for lc in self.commands:
- print lc
-
- def get_section_by_name(self, name):
- for section in self.sections:
- if section.sectname and section.sectname == name:
- return section
- return None
-
- def get_section_by_section(self, other_section):
- for section in self.sections:
- if section.sectname == other_section.sectname and section.segname == other_section.segname:
- return section
- return None
-
- def dump_sections(self, dump_description=True, options=None):
- if dump_description:
- print self.description()
- num_sections = len(self.sections)
- if num_sections > 1:
- self.sections[1].dump_header()
- for sect_idx in range(1, num_sections):
- print "%s" % self.sections[sect_idx]
-
- def dump_section_contents(self, options):
- saved_section_to_disk = False
- for sectname in options.section_names:
- section = self.get_section_by_name(sectname)
- if section:
- sect_bytes = section.get_contents(self)
- if options.outfile:
- if not saved_section_to_disk:
- outfile = open(options.outfile, 'w')
- if options.extract_modules:
- # print "Extracting modules from mach file..."
- data = file_extract.FileExtract(
- StringIO.StringIO(sect_bytes), self.data.byte_order)
- version = data.get_uint32()
- num_modules = data.get_uint32()
- # print "version = %u, num_modules = %u" %
- # (version, num_modules)
- for i in range(num_modules):
- data_offset = data.get_uint64()
- data_size = data.get_uint64()
- name_offset = data.get_uint32()
- language = data.get_uint32()
- flags = data.get_uint32()
- data.seek(name_offset)
- module_name = data.get_c_string()
- # print "module[%u] data_offset = %#16.16x,
- # data_size = %#16.16x, name_offset =
- # %#16.16x (%s), language = %u, flags =
- # %#x" % (i, data_offset, data_size,
- # name_offset, module_name, language,
- # flags)
- data.seek(data_offset)
- outfile.write(data.read_size(data_size))
- else:
- print "Saving section %s to '%s'" % (sectname, options.outfile)
- outfile.write(sect_bytes)
- outfile.close()
- saved_section_to_disk = True
- else:
- print "error: you can only save a single section to disk at a time, skipping section '%s'" % (sectname)
- else:
- print 'section %s:\n' % (sectname)
- section.dump_header()
- print '%s\n' % (section)
- dump_memory(0, sect_bytes, options.max_count, 16)
- else:
- print 'error: no section named "%s" was found' % (sectname)
-
- def get_segment(self, segname):
- if len(self.segments) == 1 and self.segments[0].segname == '':
- return self.segments[0]
- for segment in self.segments:
- if segment.segname == segname:
- return segment
- return None
-
- def get_first_load_command(self, lc_enum_value):
- for lc in self.commands:
- if lc.command.value == lc_enum_value:
- return lc
- return None
-
- def get_symtab(self):
- if self.data and not self.symbols:
- lc_symtab = self.get_first_load_command(LC_SYMTAB)
- if lc_symtab:
- symtab_offset = self.file_off
- if self.data.is_in_memory():
- linkedit_segment = self.get_segment('__LINKEDIT')
- if linkedit_segment:
- linkedit_vmaddr = linkedit_segment.vmaddr
- linkedit_fileoff = linkedit_segment.fileoff
- symtab_offset = linkedit_vmaddr + lc_symtab.symoff - linkedit_fileoff
- symtab_offset = linkedit_vmaddr + lc_symtab.stroff - linkedit_fileoff
- else:
- symtab_offset += lc_symtab.symoff
-
- self.data.seek(symtab_offset)
- is_64 = self.is_64_bit()
- for i in range(lc_symtab.nsyms):
- nlist = Mach.NList()
- nlist.unpack(self, self.data, lc_symtab)
- self.symbols.append(nlist)
- else:
- print "no LC_SYMTAB"
-
- def dump_symtab(self, dump_description=True, options=None):
- self.get_symtab()
- if dump_description:
- print self.description()
- for i, symbol in enumerate(self.symbols):
- print '[%5u] %s' % (i, symbol)
-
- def dump_symbol_names_matching_regex(self, regex, file=None):
- self.get_symtab()
- for symbol in self.symbols:
- if symbol.name and regex.search(symbol.name):
- print symbol.name
- if file:
- file.write('%s\n' % (symbol.name))
-
- def is_64_bit(self):
- return self.magic.is_64_bit()
-
- class LoadCommand:
-
- class Command(dict_utils.Enum):
- enum = {
- 'LC_SEGMENT': LC_SEGMENT,
- 'LC_SYMTAB': LC_SYMTAB,
- 'LC_SYMSEG': LC_SYMSEG,
- 'LC_THREAD': LC_THREAD,
- 'LC_UNIXTHREAD': LC_UNIXTHREAD,
- 'LC_LOADFVMLIB': LC_LOADFVMLIB,
- 'LC_IDFVMLIB': LC_IDFVMLIB,
- 'LC_IDENT': LC_IDENT,
- 'LC_FVMFILE': LC_FVMFILE,
- 'LC_PREPAGE': LC_PREPAGE,
- 'LC_DYSYMTAB': LC_DYSYMTAB,
- 'LC_LOAD_DYLIB': LC_LOAD_DYLIB,
- 'LC_ID_DYLIB': LC_ID_DYLIB,
- 'LC_LOAD_DYLINKER': LC_LOAD_DYLINKER,
- 'LC_ID_DYLINKER': LC_ID_DYLINKER,
- 'LC_PREBOUND_DYLIB': LC_PREBOUND_DYLIB,
- 'LC_ROUTINES': LC_ROUTINES,
- 'LC_SUB_FRAMEWORK': LC_SUB_FRAMEWORK,
- 'LC_SUB_UMBRELLA': LC_SUB_UMBRELLA,
- 'LC_SUB_CLIENT': LC_SUB_CLIENT,
- 'LC_SUB_LIBRARY': LC_SUB_LIBRARY,
- 'LC_TWOLEVEL_HINTS': LC_TWOLEVEL_HINTS,
- 'LC_PREBIND_CKSUM': LC_PREBIND_CKSUM,
- 'LC_LOAD_WEAK_DYLIB': LC_LOAD_WEAK_DYLIB,
- 'LC_SEGMENT_64': LC_SEGMENT_64,
- 'LC_ROUTINES_64': LC_ROUTINES_64,
- 'LC_UUID': LC_UUID,
- 'LC_RPATH': LC_RPATH,
- 'LC_CODE_SIGNATURE': LC_CODE_SIGNATURE,
- 'LC_SEGMENT_SPLIT_INFO': LC_SEGMENT_SPLIT_INFO,
- 'LC_REEXPORT_DYLIB': LC_REEXPORT_DYLIB,
- 'LC_LAZY_LOAD_DYLIB': LC_LAZY_LOAD_DYLIB,
- 'LC_ENCRYPTION_INFO': LC_ENCRYPTION_INFO,
- 'LC_DYLD_INFO': LC_DYLD_INFO,
- 'LC_DYLD_INFO_ONLY': LC_DYLD_INFO_ONLY,
- 'LC_LOAD_UPWARD_DYLIB': LC_LOAD_UPWARD_DYLIB,
- 'LC_VERSION_MIN_MACOSX': LC_VERSION_MIN_MACOSX,
- 'LC_VERSION_MIN_IPHONEOS': LC_VERSION_MIN_IPHONEOS,
- 'LC_FUNCTION_STARTS': LC_FUNCTION_STARTS,
- 'LC_DYLD_ENVIRONMENT': LC_DYLD_ENVIRONMENT
- }
-
- def __init__(self, initial_value=0):
- dict_utils.Enum.__init__(self, initial_value, self.enum)
-
- def __init__(self, c=None, l=0, o=0):
- if c is not None:
- self.command = c
- else:
- self.command = Mach.LoadCommand.Command(0)
- self.length = l
- self.file_off = o
-
- def unpack(self, mach_file, data):
- self.file_off = data.tell()
- self.command.value, self.length = data.get_n_uint32(2)
-
- def skip(self, data):
- data.seek(self.file_off + self.length, 0)
-
- def __str__(self):
- lc_name = self.command.get_enum_name()
- return '%#8.8x: <%#4.4x> %-24s' % (self.file_off,
- self.length, lc_name)
-
- class Section:
-
- def __init__(self):
- self.index = 0
- self.is_64 = False
- self.sectname = None
- self.segname = None
- self.addr = 0
- self.size = 0
- self.offset = 0
- self.align = 0
- self.reloff = 0
- self.nreloc = 0
- self.flags = 0
- self.reserved1 = 0
- self.reserved2 = 0
- self.reserved3 = 0
-
- def unpack(self, is_64, data):
- self.is_64 = is_64
- self.sectname = data.get_fixed_length_c_string(16, '', True)
- self.segname = data.get_fixed_length_c_string(16, '', True)
- if self.is_64:
- self.addr, self.size = data.get_n_uint64(2)
- self.offset, self.align, self.reloff, self.nreloc, self.flags, self.reserved1, self.reserved2, self.reserved3 = data.get_n_uint32(
- 8)
- else:
- self.addr, self.size = data.get_n_uint32(2)
- self.offset, self.align, self.reloff, self.nreloc, self.flags, self.reserved1, self.reserved2 = data.get_n_uint32(
- 7)
-
- def dump_header(self):
- if self.is_64:
- print "INDEX ADDRESS SIZE OFFSET ALIGN RELOFF NRELOC FLAGS RESERVED1 RESERVED2 RESERVED3 NAME"
- print "===== ------------------ ------------------ ---------- ---------- ---------- ---------- ---------- ---------- ---------- ---------- ----------------------"
- else:
- print "INDEX ADDRESS SIZE OFFSET ALIGN RELOFF NRELOC FLAGS RESERVED1 RESERVED2 NAME"
- print "===== ---------- ---------- ---------- ---------- ---------- ---------- ---------- ---------- ---------- ----------------------"
-
- def __str__(self):
- if self.is_64:
- return "[%3u] %#16.16x %#16.16x %#8.8x %#8.8x %#8.8x %#8.8x %#8.8x %#8.8x %#8.8x %#8.8x %s.%s" % (
- self.index, self.addr, self.size, self.offset, self.align, self.reloff, self.nreloc, self.flags, self.reserved1, self.reserved2, self.reserved3, self.segname, self.sectname)
- else:
- return "[%3u] %#8.8x %#8.8x %#8.8x %#8.8x %#8.8x %#8.8x %#8.8x %#8.8x %#8.8x %s.%s" % (
- self.index, self.addr, self.size, self.offset, self.align, self.reloff, self.nreloc, self.flags, self.reserved1, self.reserved2, self.segname, self.sectname)
-
- def get_contents(self, mach_file):
- '''Get the section contents as a python string'''
- if self.size > 0 and mach_file.get_segment(
- self.segname).filesize > 0:
- data = mach_file.get_data()
- if data:
- section_data_offset = mach_file.file_off + self.offset
- # print '%s.%s is at offset 0x%x with size 0x%x' %
- # (self.segname, self.sectname, section_data_offset,
- # self.size)
- data.push_offset_and_seek(section_data_offset)
- bytes = data.read_size(self.size)
- data.pop_offset_and_seek()
- return bytes
- return None
-
- class DylibLoadCommand(LoadCommand):
-
- def __init__(self, lc):
- Mach.LoadCommand.__init__(self, lc.command, lc.length, lc.file_off)
- self.name = None
- self.timestamp = 0
- self.current_version = 0
- self.compatibility_version = 0
-
- def unpack(self, mach_file, data):
- byte_order_char = mach_file.magic.get_byte_order()
- name_offset, self.timestamp, self.current_version, self.compatibility_version = data.get_n_uint32(
- 4)
- data.seek(self.file_off + name_offset, 0)
- self.name = data.get_fixed_length_c_string(self.length - 24)
-
- def __str__(self):
- s = Mach.LoadCommand.__str__(self)
- s += "%#8.8x %#8.8x %#8.8x " % (self.timestamp,
- self.current_version,
- self.compatibility_version)
- s += self.name
- return s
-
- class LoadDYLDLoadCommand(LoadCommand):
-
- def __init__(self, lc):
- Mach.LoadCommand.__init__(self, lc.command, lc.length, lc.file_off)
- self.name = None
-
- def unpack(self, mach_file, data):
- data.get_uint32()
- self.name = data.get_fixed_length_c_string(self.length - 12)
-
- def __str__(self):
- s = Mach.LoadCommand.__str__(self)
- s += "%s" % self.name
- return s
-
- class UnixThreadLoadCommand(LoadCommand):
-
- class ThreadState:
-
- def __init__(self):
- self.flavor = 0
- self.count = 0
- self.register_values = list()
-
- def unpack(self, data):
- self.flavor, self.count = data.get_n_uint32(2)
- self.register_values = data.get_n_uint32(self.count)
-
- def __str__(self):
- s = "flavor = %u, count = %u, regs =" % (
- self.flavor, self.count)
- i = 0
- for register_value in self.register_values:
- if i % 8 == 0:
- s += "\n "
- s += " %#8.8x" % register_value
- i += 1
- return s
-
- def __init__(self, lc):
- Mach.LoadCommand.__init__(self, lc.command, lc.length, lc.file_off)
- self.reg_sets = list()
-
- def unpack(self, mach_file, data):
- reg_set = Mach.UnixThreadLoadCommand.ThreadState()
- reg_set.unpack(data)
- self.reg_sets.append(reg_set)
-
- def __str__(self):
- s = Mach.LoadCommand.__str__(self)
- for reg_set in self.reg_sets:
- s += "%s" % reg_set
- return s
-
- class DYLDInfoOnlyLoadCommand(LoadCommand):
-
- def __init__(self, lc):
- Mach.LoadCommand.__init__(self, lc.command, lc.length, lc.file_off)
- self.rebase_off = 0
- self.rebase_size = 0
- self.bind_off = 0
- self.bind_size = 0
- self.weak_bind_off = 0
- self.weak_bind_size = 0
- self.lazy_bind_off = 0
- self.lazy_bind_size = 0
- self.export_off = 0
- self.export_size = 0
-
- def unpack(self, mach_file, data):
- byte_order_char = mach_file.magic.get_byte_order()
- self.rebase_off, self.rebase_size, self.bind_off, self.bind_size, self.weak_bind_off, self.weak_bind_size, self.lazy_bind_off, self.lazy_bind_size, self.export_off, self.export_size = data.get_n_uint32(
- 10)
-
- def __str__(self):
- s = Mach.LoadCommand.__str__(self)
- s += "rebase_off = %#8.8x, rebase_size = %u, " % (
- self.rebase_off, self.rebase_size)
- s += "bind_off = %#8.8x, bind_size = %u, " % (
- self.bind_off, self.bind_size)
- s += "weak_bind_off = %#8.8x, weak_bind_size = %u, " % (
- self.weak_bind_off, self.weak_bind_size)
- s += "lazy_bind_off = %#8.8x, lazy_bind_size = %u, " % (
- self.lazy_bind_off, self.lazy_bind_size)
- s += "export_off = %#8.8x, export_size = %u, " % (
- self.export_off, self.export_size)
- return s
-
- class DYLDSymtabLoadCommand(LoadCommand):
-
- def __init__(self, lc):
- Mach.LoadCommand.__init__(self, lc.command, lc.length, lc.file_off)
- self.ilocalsym = 0
- self.nlocalsym = 0
- self.iextdefsym = 0
- self.nextdefsym = 0
- self.iundefsym = 0
- self.nundefsym = 0
- self.tocoff = 0
- self.ntoc = 0
- self.modtaboff = 0
- self.nmodtab = 0
- self.extrefsymoff = 0
- self.nextrefsyms = 0
- self.indirectsymoff = 0
- self.nindirectsyms = 0
- self.extreloff = 0
- self.nextrel = 0
- self.locreloff = 0
- self.nlocrel = 0
-
- def unpack(self, mach_file, data):
- byte_order_char = mach_file.magic.get_byte_order()
- self.ilocalsym, self.nlocalsym, self.iextdefsym, self.nextdefsym, self.iundefsym, self.nundefsym, self.tocoff, self.ntoc, self.modtaboff, self.nmodtab, self.extrefsymoff, self.nextrefsyms, self.indirectsymoff, self.nindirectsyms, self.extreloff, self.nextrel, self.locreloff, self.nlocrel = data.get_n_uint32(
- 18)
-
- def __str__(self):
- s = Mach.LoadCommand.__str__(self)
- # s += "ilocalsym = %u, nlocalsym = %u, " % (self.ilocalsym, self.nlocalsym)
- # s += "iextdefsym = %u, nextdefsym = %u, " % (self.iextdefsym, self.nextdefsym)
- # s += "iundefsym %u, nundefsym = %u, " % (self.iundefsym, self.nundefsym)
- # s += "tocoff = %#8.8x, ntoc = %u, " % (self.tocoff, self.ntoc)
- # s += "modtaboff = %#8.8x, nmodtab = %u, " % (self.modtaboff, self.nmodtab)
- # s += "extrefsymoff = %#8.8x, nextrefsyms = %u, " % (self.extrefsymoff, self.nextrefsyms)
- # s += "indirectsymoff = %#8.8x, nindirectsyms = %u, " % (self.indirectsymoff, self.nindirectsyms)
- # s += "extreloff = %#8.8x, nextrel = %u, " % (self.extreloff, self.nextrel)
- # s += "locreloff = %#8.8x, nlocrel = %u" % (self.locreloff,
- # self.nlocrel)
- s += "ilocalsym = %-10u, nlocalsym = %u\n" % (
- self.ilocalsym, self.nlocalsym)
- s += " iextdefsym = %-10u, nextdefsym = %u\n" % (
- self.iextdefsym, self.nextdefsym)
- s += " iundefsym = %-10u, nundefsym = %u\n" % (
- self.iundefsym, self.nundefsym)
- s += " tocoff = %#8.8x, ntoc = %u\n" % (
- self.tocoff, self.ntoc)
- s += " modtaboff = %#8.8x, nmodtab = %u\n" % (
- self.modtaboff, self.nmodtab)
- s += " extrefsymoff = %#8.8x, nextrefsyms = %u\n" % (
- self.extrefsymoff, self.nextrefsyms)
- s += " indirectsymoff = %#8.8x, nindirectsyms = %u\n" % (
- self.indirectsymoff, self.nindirectsyms)
- s += " extreloff = %#8.8x, nextrel = %u\n" % (
- self.extreloff, self.nextrel)
- s += " locreloff = %#8.8x, nlocrel = %u" % (
- self.locreloff, self.nlocrel)
- return s
-
- class SymtabLoadCommand(LoadCommand):
-
- def __init__(self, lc):
- Mach.LoadCommand.__init__(self, lc.command, lc.length, lc.file_off)
- self.symoff = 0
- self.nsyms = 0
- self.stroff = 0
- self.strsize = 0
-
- def unpack(self, mach_file, data):
- byte_order_char = mach_file.magic.get_byte_order()
- self.symoff, self.nsyms, self.stroff, self.strsize = data.get_n_uint32(
- 4)
-
- def __str__(self):
- s = Mach.LoadCommand.__str__(self)
- s += "symoff = %#8.8x, nsyms = %u, stroff = %#8.8x, strsize = %u" % (
- self.symoff, self.nsyms, self.stroff, self.strsize)
- return s
-
- class UUIDLoadCommand(LoadCommand):
-
- def __init__(self, lc):
- Mach.LoadCommand.__init__(self, lc.command, lc.length, lc.file_off)
- self.uuid = None
-
- def unpack(self, mach_file, data):
- uuid_data = data.get_n_uint8(16)
- uuid_str = ''
- for byte in uuid_data:
- uuid_str += '%2.2x' % byte
- self.uuid = uuid.UUID(uuid_str)
- mach_file.uuid = self.uuid
-
- def __str__(self):
- s = Mach.LoadCommand.__str__(self)
- s += self.uuid.__str__()
- return s
-
- class DataBlobLoadCommand(LoadCommand):
-
- def __init__(self, lc):
- Mach.LoadCommand.__init__(self, lc.command, lc.length, lc.file_off)
- self.dataoff = 0
- self.datasize = 0
-
- def unpack(self, mach_file, data):
- byte_order_char = mach_file.magic.get_byte_order()
- self.dataoff, self.datasize = data.get_n_uint32(2)
-
- def __str__(self):
- s = Mach.LoadCommand.__str__(self)
- s += "dataoff = %#8.8x, datasize = %u" % (
- self.dataoff, self.datasize)
- return s
-
- class EncryptionInfoLoadCommand(LoadCommand):
-
- def __init__(self, lc):
- Mach.LoadCommand.__init__(self, lc.command, lc.length, lc.file_off)
- self.cryptoff = 0
- self.cryptsize = 0
- self.cryptid = 0
-
- def unpack(self, mach_file, data):
- byte_order_char = mach_file.magic.get_byte_order()
- self.cryptoff, self.cryptsize, self.cryptid = data.get_n_uint32(3)
-
- def __str__(self):
- s = Mach.LoadCommand.__str__(self)
- s += "file-range = [%#8.8x - %#8.8x), cryptsize = %u, cryptid = %u" % (
- self.cryptoff, self.cryptoff + self.cryptsize, self.cryptsize, self.cryptid)
- return s
-
- class SegmentLoadCommand(LoadCommand):
-
- def __init__(self, lc):
- Mach.LoadCommand.__init__(self, lc.command, lc.length, lc.file_off)
- self.segname = None
- self.vmaddr = 0
- self.vmsize = 0
- self.fileoff = 0
- self.filesize = 0
- self.maxprot = 0
- self.initprot = 0
- self.nsects = 0
- self.flags = 0
-
- def unpack(self, mach_file, data):
- is_64 = self.command.get_enum_value() == LC_SEGMENT_64
- self.segname = data.get_fixed_length_c_string(16, '', True)
- if is_64:
- self.vmaddr, self.vmsize, self.fileoff, self.filesize = data.get_n_uint64(
- 4)
- else:
- self.vmaddr, self.vmsize, self.fileoff, self.filesize = data.get_n_uint32(
- 4)
- self.maxprot, self.initprot, self.nsects, self.flags = data.get_n_uint32(
- 4)
- mach_file.segments.append(self)
- for i in range(self.nsects):
- section = Mach.Section()
- section.unpack(is_64, data)
- section.index = len(mach_file.sections)
- mach_file.sections.append(section)
-
- def __str__(self):
- s = Mach.LoadCommand.__str__(self)
- if self.command.get_enum_value() == LC_SEGMENT:
- s += "%#8.8x %#8.8x %#8.8x %#8.8x " % (
- self.vmaddr, self.vmsize, self.fileoff, self.filesize)
- else:
- s += "%#16.16x %#16.16x %#16.16x %#16.16x " % (
- self.vmaddr, self.vmsize, self.fileoff, self.filesize)
- s += "%s %s %3u %#8.8x" % (vm_prot_names[self.maxprot], vm_prot_names[
- self.initprot], self.nsects, self.flags)
- s += ' ' + self.segname
- return s
-
- class NList:
-
- class Type:
-
- class Stab(dict_utils.Enum):
- enum = {
- 'N_GSYM': N_GSYM,
- 'N_FNAME': N_FNAME,
- 'N_FUN': N_FUN,
- 'N_STSYM': N_STSYM,
- 'N_LCSYM': N_LCSYM,
- 'N_BNSYM': N_BNSYM,
- 'N_OPT': N_OPT,
- 'N_RSYM': N_RSYM,
- 'N_SLINE': N_SLINE,
- 'N_ENSYM': N_ENSYM,
- 'N_SSYM': N_SSYM,
- 'N_SO': N_SO,
- 'N_OSO': N_OSO,
- 'N_LSYM': N_LSYM,
- 'N_BINCL': N_BINCL,
- 'N_SOL': N_SOL,
- 'N_PARAMS': N_PARAMS,
- 'N_VERSION': N_VERSION,
- 'N_OLEVEL': N_OLEVEL,
- 'N_PSYM': N_PSYM,
- 'N_EINCL': N_EINCL,
- 'N_ENTRY': N_ENTRY,
- 'N_LBRAC': N_LBRAC,
- 'N_EXCL': N_EXCL,
- 'N_RBRAC': N_RBRAC,
- 'N_BCOMM': N_BCOMM,
- 'N_ECOMM': N_ECOMM,
- 'N_ECOML': N_ECOML,
- 'N_LENG': N_LENG
- }
-
- def __init__(self, magic=0):
- dict_utils.Enum.__init__(self, magic, self.enum)
-
- def __init__(self, t=0):
- self.value = t
-
- def __str__(self):
- n_type = self.value
- if n_type & N_STAB:
- stab = Mach.NList.Type.Stab(self.value)
- return '%s' % stab
- else:
- type = self.value & N_TYPE
- type_str = ''
- if type == N_UNDF:
- type_str = 'N_UNDF'
- elif type == N_ABS:
- type_str = 'N_ABS '
- elif type == N_SECT:
- type_str = 'N_SECT'
- elif type == N_PBUD:
- type_str = 'N_PBUD'
- elif type == N_INDR:
- type_str = 'N_INDR'
- else:
- type_str = "??? (%#2.2x)" % type
- if n_type & N_PEXT:
- type_str += ' | PEXT'
- if n_type & N_EXT:
- type_str += ' | EXT '
- return type_str
-
- def __init__(self):
- self.index = 0
- self.name_offset = 0
- self.name = 0
- self.type = Mach.NList.Type()
- self.sect_idx = 0
- self.desc = 0
- self.value = 0
-
- def unpack(self, mach_file, data, symtab_lc):
- self.index = len(mach_file.symbols)
- self.name_offset = data.get_uint32()
- self.type.value, self.sect_idx = data.get_n_uint8(2)
- self.desc = data.get_uint16()
- if mach_file.is_64_bit():
- self.value = data.get_uint64()
- else:
- self.value = data.get_uint32()
- data.push_offset_and_seek(
- mach_file.file_off +
- symtab_lc.stroff +
- self.name_offset)
- # print "get string for symbol[%u]" % self.index
- self.name = data.get_c_string()
- data.pop_offset_and_seek()
-
- def __str__(self):
- name_display = ''
- if len(self.name):
- name_display = ' "%s"' % self.name
- return '%#8.8x %#2.2x (%-20s) %#2.2x %#4.4x %16.16x%s' % (self.name_offset,
- self.type.value, self.type, self.sect_idx, self.desc, self.value, name_display)
-
- class Interactive(cmd.Cmd):
- '''Interactive command interpreter to mach-o files.'''
-
- def __init__(self, mach, options):
- cmd.Cmd.__init__(self)
- self.intro = 'Interactive mach-o command interpreter'
- self.prompt = 'mach-o: %s %% ' % mach.path
- self.mach = mach
- self.options = options
-
- def default(self, line):
- '''Catch all for unknown command, which will exit the interpreter.'''
- print "uknown command: %s" % line
- return True
-
- def do_q(self, line):
- '''Quit command'''
- return True
-
- def do_quit(self, line):
- '''Quit command'''
- return True
-
- def do_header(self, line):
- '''Dump mach-o file headers'''
- self.mach.dump_header(True, self.options)
- return False
-
- def do_load(self, line):
- '''Dump all mach-o load commands'''
- self.mach.dump_load_commands(True, self.options)
- return False
-
- def do_sections(self, line):
- '''Dump all mach-o sections'''
- self.mach.dump_sections(True, self.options)
- return False
-
- def do_symtab(self, line):
- '''Dump all mach-o symbols in the symbol table'''
- self.mach.dump_symtab(True, self.options)
- return False
-
-if __name__ == '__main__':
- parser = optparse.OptionParser(
- description='A script that parses skinny and universal mach-o files.')
- parser.add_option(
- '--arch',
- '-a',
- type='string',
- metavar='arch',
- dest='archs',
- action='append',
- help='specify one or more architectures by name')
- parser.add_option(
- '-v',
- '--verbose',
- action='store_true',
- dest='verbose',
- help='display verbose debug info',
- default=False)
- parser.add_option(
- '-H',
- '--header',
- action='store_true',
- dest='dump_header',
- help='dump the mach-o file header',
- default=False)
- parser.add_option(
- '-l',
- '--load-commands',
- action='store_true',
- dest='dump_load_commands',
- help='dump the mach-o load commands',
- default=False)
- parser.add_option(
- '-s',
- '--symtab',
- action='store_true',
- dest='dump_symtab',
- help='dump the mach-o symbol table',
- default=False)
- parser.add_option(
- '-S',
- '--sections',
- action='store_true',
- dest='dump_sections',
- help='dump the mach-o sections',
- default=False)
- parser.add_option(
- '--section',
- type='string',
- metavar='sectname',
- dest='section_names',
- action='append',
- help='Specify one or more section names to dump',
- default=[])
- parser.add_option(
- '-o',
- '--out',
- type='string',
- dest='outfile',
- help='Used in conjunction with the --section=NAME option to save a single section\'s data to disk.',
- default=False)
- parser.add_option(
- '-i',
- '--interactive',
- action='store_true',
- dest='interactive',
- help='enable interactive mode',
- default=False)
- parser.add_option(
- '-m',
- '--mangled',
- action='store_true',
- dest='find_mangled',
- help='dump all mangled names in a mach file',
- default=False)
- parser.add_option(
- '-c',
- '--compare',
- action='store_true',
- dest='compare',
- help='compare two mach files',
- default=False)
- parser.add_option(
- '-M',
- '--extract-modules',
- action='store_true',
- dest='extract_modules',
- help='Extract modules from file',
- default=False)
- parser.add_option(
- '-C',
- '--count',
- type='int',
- dest='max_count',
- help='Sets the max byte count when dumping section data',
- default=-1)
-
- (options, mach_files) = parser.parse_args()
- if options.extract_modules:
- if options.section_names:
- print "error: can't use --section option with the --extract-modules option"
- exit(1)
- if not options.outfile:
- print "error: the --output=FILE option must be specified with the --extract-modules option"
- exit(1)
- options.section_names.append("__apple_ast")
- if options.compare:
- if len(mach_files) == 2:
- mach_a = Mach()
- mach_b = Mach()
- mach_a.parse(mach_files[0])
- mach_b.parse(mach_files[1])
- mach_a.compare(mach_b)
- else:
- print 'error: --compare takes two mach files as arguments'
- else:
- if not (options.dump_header or options.dump_load_commands or options.dump_symtab or options.dump_sections or options.find_mangled or options.section_names):
- options.dump_header = True
- options.dump_load_commands = True
- if options.verbose:
- print 'options', options
- print 'mach_files', mach_files
- for path in mach_files:
- mach = Mach()
- mach.parse(path)
- if options.interactive:
- interpreter = Mach.Interactive(mach, options)
- interpreter.cmdloop()
- else:
- mach.dump(options)
diff --git a/examples/python/memory.py b/examples/python/memory.py
deleted file mode 100755
index 5e2f636dc3e6..000000000000
--- a/examples/python/memory.py
+++ /dev/null
@@ -1,276 +0,0 @@
-#!/usr/bin/python
-
-#----------------------------------------------------------------------
-# Be sure to add the python path that points to the LLDB shared library.
-#
-# # To use this in the embedded python interpreter using "lldb" just
-# import it with the full path using the "command script import"
-# command
-# (lldb) command script import /path/to/cmdtemplate.py
-#----------------------------------------------------------------------
-
-import commands
-import platform
-import os
-import re
-import sys
-
-try:
- # Just try for LLDB in case PYTHONPATH is already correctly setup
- import lldb
-except ImportError:
- lldb_python_dirs = list()
- # lldb is not in the PYTHONPATH, try some defaults for the current platform
- platform_system = platform.system()
- if platform_system == 'Darwin':
- # On Darwin, try the currently selected Xcode directory
- xcode_dir = commands.getoutput("xcode-select --print-path")
- if xcode_dir:
- lldb_python_dirs.append(
- os.path.realpath(
- xcode_dir +
- '/../SharedFrameworks/LLDB.framework/Resources/Python'))
- lldb_python_dirs.append(
- xcode_dir + '/Library/PrivateFrameworks/LLDB.framework/Resources/Python')
- lldb_python_dirs.append(
- '/System/Library/PrivateFrameworks/LLDB.framework/Resources/Python')
- success = False
- for lldb_python_dir in lldb_python_dirs:
- if os.path.exists(lldb_python_dir):
- if not (sys.path.__contains__(lldb_python_dir)):
- sys.path.append(lldb_python_dir)
- try:
- import lldb
- except ImportError:
- pass
- else:
- print 'imported lldb from: "%s"' % (lldb_python_dir)
- success = True
- break
- if not success:
- print "error: couldn't locate the 'lldb' module, please set PYTHONPATH correctly"
- sys.exit(1)
-
-import commands
-import optparse
-import shlex
-import string
-import struct
-import time
-
-
-def append_data_callback(option, opt_str, value, parser):
- if opt_str == "--uint8":
- int8 = int(value, 0)
- parser.values.data += struct.pack('1B', int8)
- if opt_str == "--uint16":
- int16 = int(value, 0)
- parser.values.data += struct.pack('1H', int16)
- if opt_str == "--uint32":
- int32 = int(value, 0)
- parser.values.data += struct.pack('1I', int32)
- if opt_str == "--uint64":
- int64 = int(value, 0)
- parser.values.data += struct.pack('1Q', int64)
- if opt_str == "--int8":
- int8 = int(value, 0)
- parser.values.data += struct.pack('1b', int8)
- if opt_str == "--int16":
- int16 = int(value, 0)
- parser.values.data += struct.pack('1h', int16)
- if opt_str == "--int32":
- int32 = int(value, 0)
- parser.values.data += struct.pack('1i', int32)
- if opt_str == "--int64":
- int64 = int(value, 0)
- parser.values.data += struct.pack('1q', int64)
-
-
-def create_memfind_options():
- usage = "usage: %prog [options] STARTADDR [ENDADDR]"
- description = '''This command can find data in a specified address range.
-Options are used to specify the data that is to be looked for and the options
-can be specified multiple times to look for longer streams of data.
-'''
- parser = optparse.OptionParser(
- description=description,
- prog='memfind',
- usage=usage)
- parser.add_option(
- '-s',
- '--size',
- type='int',
- metavar='BYTESIZE',
- dest='size',
- help='Specify the byte size to search.',
- default=0)
- parser.add_option(
- '--int8',
- action="callback",
- callback=append_data_callback,
- type='string',
- metavar='INT',
- dest='data',
- help='Specify a 8 bit signed integer value to search for in memory.',
- default='')
- parser.add_option(
- '--int16',
- action="callback",
- callback=append_data_callback,
- type='string',
- metavar='INT',
- dest='data',
- help='Specify a 16 bit signed integer value to search for in memory.',
- default='')
- parser.add_option(
- '--int32',
- action="callback",
- callback=append_data_callback,
- type='string',
- metavar='INT',
- dest='data',
- help='Specify a 32 bit signed integer value to search for in memory.',
- default='')
- parser.add_option(
- '--int64',
- action="callback",
- callback=append_data_callback,
- type='string',
- metavar='INT',
- dest='data',
- help='Specify a 64 bit signed integer value to search for in memory.',
- default='')
- parser.add_option(
- '--uint8',
- action="callback",
- callback=append_data_callback,
- type='string',
- metavar='INT',
- dest='data',
- help='Specify a 8 bit unsigned integer value to search for in memory.',
- default='')
- parser.add_option(
- '--uint16',
- action="callback",
- callback=append_data_callback,
- type='string',
- metavar='INT',
- dest='data',
- help='Specify a 16 bit unsigned integer value to search for in memory.',
- default='')
- parser.add_option(
- '--uint32',
- action="callback",
- callback=append_data_callback,
- type='string',
- metavar='INT',
- dest='data',
- help='Specify a 32 bit unsigned integer value to search for in memory.',
- default='')
- parser.add_option(
- '--uint64',
- action="callback",
- callback=append_data_callback,
- type='string',
- metavar='INT',
- dest='data',
- help='Specify a 64 bit unsigned integer value to search for in memory.',
- default='')
- return parser
-
-
-def memfind_command(debugger, command, result, dict):
- # Use the Shell Lexer to properly parse up command options just like a
- # shell would
- command_args = shlex.split(command)
- parser = create_memfind_options()
- (options, args) = parser.parse_args(command_args)
- # try:
- # (options, args) = parser.parse_args(command_args)
- # except:
- # # if you don't handle exceptions, passing an incorrect argument to the OptionParser will cause LLDB to exit
- # # (courtesy of OptParse dealing with argument errors by throwing SystemExit)
- # result.SetStatus (lldb.eReturnStatusFailed)
- # print >>result, "error: option parsing failed" # returning a string is the same as returning an error whose description is the string
- # return
- memfind(debugger.GetSelectedTarget(), options, args, result)
-
-
-def print_error(str, show_usage, result):
- print >>result, str
- if show_usage:
- print >>result, create_memfind_options().format_help()
-
-
-def memfind(target, options, args, result):
- num_args = len(args)
- start_addr = 0
- if num_args == 1:
- if options.size > 0:
- print_error(
- "error: --size must be specified if there is no ENDADDR argument",
- True,
- result)
- return
- start_addr = int(args[0], 0)
- elif num_args == 2:
- if options.size != 0:
- print_error(
- "error: --size can't be specified with an ENDADDR argument",
- True,
- result)
- return
- start_addr = int(args[0], 0)
- end_addr = int(args[1], 0)
- if start_addr >= end_addr:
- print_error(
- "error: inavlid memory range [%#x - %#x)" %
- (start_addr, end_addr), True, result)
- return
- options.size = end_addr - start_addr
- else:
- print_error("error: memfind takes 1 or 2 arguments", True, result)
- return
-
- if not options.data:
- print >>result, 'error: no data specified to search for'
- return
-
- if not target:
- print >>result, 'error: invalid target'
- return
- process = target.process
- if not process:
- print >>result, 'error: invalid process'
- return
-
- error = lldb.SBError()
- bytes = process.ReadMemory(start_addr, options.size, error)
- if error.Success():
- num_matches = 0
- print >>result, "Searching memory range [%#x - %#x) for" % (
- start_addr, end_addr),
- for byte in options.data:
- print >>result, '%2.2x' % ord(byte),
- print >>result
-
- match_index = string.find(bytes, options.data)
- while match_index != -1:
- num_matches = num_matches + 1
- print >>result, '%#x: %#x + %u' % (start_addr +
- match_index, start_addr, match_index)
- match_index = string.find(bytes, options.data, match_index + 1)
-
- if num_matches == 0:
- print >>result, "error: no matches found"
- else:
- print >>result, 'error: %s' % (error.GetCString())
-
-
-if __name__ == '__main__':
- print 'error: this script is designed to be used within the embedded script interpreter in LLDB'
-elif getattr(lldb, 'debugger', None):
- memfind_command.__doc__ = create_memfind_options().format_help()
- lldb.debugger.HandleCommand(
- 'command script add -f memory.memfind_command memfind')
- print '"memfind" command installed, use the "--help" option for detailed help'
diff --git a/examples/python/operating_system.py b/examples/python/operating_system.py
deleted file mode 100644
index bfa13f0568ea..000000000000
--- a/examples/python/operating_system.py
+++ /dev/null
@@ -1,231 +0,0 @@
-#!/usr/bin/python
-
-import lldb
-import struct
-
-
-class OperatingSystemPlugIn(object):
- """Class that provides data for an instance of a LLDB 'OperatingSystemPython' plug-in class"""
-
- def __init__(self, process):
- '''Initialization needs a valid.SBProcess object.
-
- This plug-in will get created after a live process is valid and has stopped for the
- first time.'''
- self.process = None
- self.registers = None
- self.threads = None
- if isinstance(process, lldb.SBProcess) and process.IsValid():
- self.process = process
- self.threads = None # Will be an dictionary containing info for each thread
-
- def get_target(self):
- # NOTE: Don't use "lldb.target" when trying to get your target as the "lldb.target"
- # tracks the current target in the LLDB command interpreter which isn't the
- # correct thing to use for this plug-in.
- return self.process.target
-
- def create_thread(self, tid, context):
- if tid == 0x444444444:
- thread_info = {
- 'tid': tid,
- 'name': 'four',
- 'queue': 'queue4',
- 'state': 'stopped',
- 'stop_reason': 'none'}
- self.threads.append(thread_info)
- return thread_info
- return None
-
- def get_thread_info(self):
- if not self.threads:
- # The sample dictionary below shows the values that can be returned for a thread
- # tid => thread ID (mandatory)
- # name => thread name (optional key/value pair)
- # queue => thread dispatch queue name (optional key/value pair)
- # state => thred state (mandatory, set to 'stopped' for now)
- # stop_reason => thread stop reason. (mandatory, usually set to 'none')
- # Possible values include:
- # 'breakpoint' if the thread is stopped at a breakpoint
- # 'none' thread is just stopped because the process is stopped
- # 'trace' the thread just single stepped
- # The usual value for this while threads are in memory is 'none'
- # register_data_addr => the address of the register data in memory (optional key/value pair)
- # Specifying this key/value pair for a thread will avoid a call to get_register_data()
- # and can be used when your registers are in a thread context structure that is contiguous
- # in memory. Don't specify this if your register layout in memory doesn't match the layout
- # described by the dictionary returned from a call to the
- # get_register_info() method.
- self.threads = [{'tid': 0x111111111,
- 'name': 'one',
- 'queue': 'queue1',
- 'state': 'stopped',
- 'stop_reason': 'breakpoint'},
- {'tid': 0x222222222,
- 'name': 'two',
- 'queue': 'queue2',
- 'state': 'stopped',
- 'stop_reason': 'none'},
- {'tid': 0x333333333,
- 'name': 'three',
- 'queue': 'queue3',
- 'state': 'stopped',
- 'stop_reason': 'trace',
- 'register_data_addr': 0x100000000}]
- return self.threads
-
- def get_register_info(self):
- if self.registers is None:
- self.registers = dict()
- triple = self.process.target.triple
- if triple:
- arch = triple.split('-')[0]
- if arch == 'x86_64':
- self.registers['sets'] = ['GPR', 'FPU', 'EXC']
- self.registers['registers'] = [
- {'name': 'rax', 'bitsize': 64, 'offset': 0, 'encoding': 'uint', 'format': 'hex', 'set': 0, 'gcc': 0, 'dwarf': 0},
- {'name': 'rbx', 'bitsize': 64, 'offset': 8, 'encoding': 'uint', 'format': 'hex', 'set': 0, 'gcc': 3, 'dwarf': 3},
- {'name': 'rcx', 'bitsize': 64, 'offset': 16, 'encoding': 'uint', 'format': 'hex', 'set': 0, 'gcc': 2, 'dwarf': 2, 'generic': 'arg4', 'alt-name': 'arg4', },
- {'name': 'rdx', 'bitsize': 64, 'offset': 24, 'encoding': 'uint', 'format': 'hex', 'set': 0, 'gcc': 1, 'dwarf': 1, 'generic': 'arg3', 'alt-name': 'arg3', },
- {'name': 'rdi', 'bitsize': 64, 'offset': 32, 'encoding': 'uint', 'format': 'hex', 'set': 0, 'gcc': 5, 'dwarf': 5, 'generic': 'arg1', 'alt-name': 'arg1', },
- {'name': 'rsi', 'bitsize': 64, 'offset': 40, 'encoding': 'uint', 'format': 'hex', 'set': 0, 'gcc': 4, 'dwarf': 4, 'generic': 'arg2', 'alt-name': 'arg2', },
- {'name': 'rbp', 'bitsize': 64, 'offset': 48, 'encoding': 'uint', 'format': 'hex', 'set': 0, 'gcc': 6, 'dwarf': 6, 'generic': 'fp', 'alt-name': 'fp', },
- {'name': 'rsp', 'bitsize': 64, 'offset': 56, 'encoding': 'uint', 'format': 'hex', 'set': 0, 'gcc': 7, 'dwarf': 7, 'generic': 'sp', 'alt-name': 'sp', },
- {'name': 'r8', 'bitsize': 64, 'offset': 64, 'encoding': 'uint', 'format': 'hex', 'set': 0, 'gcc': 8, 'dwarf': 8, 'generic': 'arg5', 'alt-name': 'arg5', },
- {'name': 'r9', 'bitsize': 64, 'offset': 72, 'encoding': 'uint', 'format': 'hex', 'set': 0, 'gcc': 9, 'dwarf': 9, 'generic': 'arg6', 'alt-name': 'arg6', },
- {'name': 'r10', 'bitsize': 64, 'offset': 80, 'encoding': 'uint', 'format': 'hex', 'set': 0, 'gcc': 10, 'dwarf': 10},
- {'name': 'r11', 'bitsize': 64, 'offset': 88, 'encoding': 'uint', 'format': 'hex', 'set': 0, 'gcc': 11, 'dwarf': 11},
- {'name': 'r12', 'bitsize': 64, 'offset': 96, 'encoding': 'uint', 'format': 'hex', 'set': 0, 'gcc': 12, 'dwarf': 12},
- {'name': 'r13', 'bitsize': 64, 'offset': 104, 'encoding': 'uint', 'format': 'hex', 'set': 0, 'gcc': 13, 'dwarf': 13},
- {'name': 'r14', 'bitsize': 64, 'offset': 112, 'encoding': 'uint', 'format': 'hex', 'set': 0, 'gcc': 14, 'dwarf': 14},
- {'name': 'r15', 'bitsize': 64, 'offset': 120, 'encoding': 'uint', 'format': 'hex', 'set': 0, 'gcc': 15, 'dwarf': 15},
- {'name': 'rip', 'bitsize': 64, 'offset': 128, 'encoding': 'uint', 'format': 'hex', 'set': 0, 'gcc': 16, 'dwarf': 16, 'generic': 'pc', 'alt-name': 'pc'},
- {'name': 'rflags', 'bitsize': 64, 'offset': 136, 'encoding': 'uint', 'format': 'hex', 'set': 0, 'generic': 'flags', 'alt-name': 'flags'},
- {'name': 'cs', 'bitsize': 64, 'offset': 144, 'encoding': 'uint', 'format': 'hex', 'set': 0},
- {'name': 'fs', 'bitsize': 64, 'offset': 152, 'encoding': 'uint', 'format': 'hex', 'set': 0},
- {'name': 'gs', 'bitsize': 64, 'offset': 160, 'encoding': 'uint', 'format': 'hex', 'set': 0},
- ]
- return self.registers
-
- def get_register_data(self, tid):
- if tid == 0x111111111:
- return struct.pack(
- '21Q',
- 1,
- 2,
- 3,
- 4,
- 5,
- 6,
- 7,
- 8,
- 9,
- 10,
- 11,
- 12,
- 13,
- 14,
- 15,
- 16,
- 17,
- 18,
- 19,
- 20,
- 21)
- elif tid == 0x222222222:
- return struct.pack(
- '21Q',
- 11,
- 12,
- 13,
- 14,
- 15,
- 16,
- 17,
- 18,
- 19,
- 110,
- 111,
- 112,
- 113,
- 114,
- 115,
- 116,
- 117,
- 118,
- 119,
- 120,
- 121)
- elif tid == 0x333333333:
- return struct.pack(
- '21Q',
- 21,
- 22,
- 23,
- 24,
- 25,
- 26,
- 27,
- 28,
- 29,
- 210,
- 211,
- 212,
- 213,
- 214,
- 215,
- 216,
- 217,
- 218,
- 219,
- 220,
- 221)
- elif tid == 0x444444444:
- return struct.pack(
- '21Q',
- 31,
- 32,
- 33,
- 34,
- 35,
- 36,
- 37,
- 38,
- 39,
- 310,
- 311,
- 312,
- 313,
- 314,
- 315,
- 316,
- 317,
- 318,
- 319,
- 320,
- 321)
- else:
- return struct.pack(
- '21Q',
- 41,
- 42,
- 43,
- 44,
- 45,
- 46,
- 47,
- 48,
- 49,
- 410,
- 411,
- 412,
- 413,
- 414,
- 415,
- 416,
- 417,
- 418,
- 419,
- 420,
- 421)
- return None
diff --git a/examples/python/performance.py b/examples/python/performance.py
deleted file mode 100755
index f1bc94f4b43a..000000000000
--- a/examples/python/performance.py
+++ /dev/null
@@ -1,392 +0,0 @@
-#!/usr/bin/python
-
-#----------------------------------------------------------------------
-# Be sure to add the python path that points to the LLDB shared library.
-# On MacOSX csh, tcsh:
-# setenv PYTHONPATH /Applications/Xcode.app/Contents/SharedFrameworks/LLDB.framework/Resources/Python
-# On MacOSX sh, bash:
-# export PYTHONPATH=/Applications/Xcode.app/Contents/SharedFrameworks/LLDB.framework/Resources/Python
-#----------------------------------------------------------------------
-
-import commands
-import optparse
-import os
-import platform
-import re
-import resource
-import sys
-import time
-import types
-
-#----------------------------------------------------------------------
-# Code that auto imports LLDB
-#----------------------------------------------------------------------
-try:
- # Just try for LLDB in case PYTHONPATH is already correctly setup
- import lldb
-except ImportError:
- lldb_python_dirs = list()
- # lldb is not in the PYTHONPATH, try some defaults for the current platform
- platform_system = platform.system()
- if platform_system == 'Darwin':
- # On Darwin, try the currently selected Xcode directory
- xcode_dir = commands.getoutput("xcode-select --print-path")
- if xcode_dir:
- lldb_python_dirs.append(
- os.path.realpath(
- xcode_dir +
- '/../SharedFrameworks/LLDB.framework/Resources/Python'))
- lldb_python_dirs.append(
- xcode_dir + '/Library/PrivateFrameworks/LLDB.framework/Resources/Python')
- lldb_python_dirs.append(
- '/System/Library/PrivateFrameworks/LLDB.framework/Resources/Python')
- success = False
- for lldb_python_dir in lldb_python_dirs:
- if os.path.exists(lldb_python_dir):
- if not (sys.path.__contains__(lldb_python_dir)):
- sys.path.append(lldb_python_dir)
- try:
- import lldb
- except ImportError:
- pass
- else:
- print 'imported lldb from: "%s"' % (lldb_python_dir)
- success = True
- break
- if not success:
- print "error: couldn't locate the 'lldb' module, please set PYTHONPATH correctly"
- sys.exit(1)
-
-
-class Timer:
-
- def __enter__(self):
- self.start = time.clock()
- return self
-
- def __exit__(self, *args):
- self.end = time.clock()
- self.interval = self.end - self.start
-
-
-class Action(object):
- """Class that encapsulates actions to take when a thread stops for a reason."""
-
- def __init__(self, callback=None, callback_owner=None):
- self.callback = callback
- self.callback_owner = callback_owner
-
- def ThreadStopped(self, thread):
- assert False, "performance.Action.ThreadStopped(self, thread) must be overridden in a subclass"
-
-
-class PlanCompleteAction (Action):
-
- def __init__(self, callback=None, callback_owner=None):
- Action.__init__(self, callback, callback_owner)
-
- def ThreadStopped(self, thread):
- if thread.GetStopReason() == lldb.eStopReasonPlanComplete:
- if self.callback:
- if self.callback_owner:
- self.callback(self.callback_owner, thread)
- else:
- self.callback(thread)
- return True
- return False
-
-
-class BreakpointAction (Action):
-
- def __init__(
- self,
- callback=None,
- callback_owner=None,
- name=None,
- module=None,
- file=None,
- line=None,
- breakpoint=None):
- Action.__init__(self, callback, callback_owner)
- self.modules = lldb.SBFileSpecList()
- self.files = lldb.SBFileSpecList()
- self.breakpoints = list()
- # "module" can be a list or a string
- if breakpoint:
- self.breakpoints.append(breakpoint)
- else:
- if module:
- if isinstance(module, types.ListType):
- for module_path in module:
- self.modules.Append(
- lldb.SBFileSpec(module_path, False))
- elif isinstance(module, types.StringTypes):
- self.modules.Append(lldb.SBFileSpec(module, False))
- if name:
- # "file" can be a list or a string
- if file:
- if isinstance(file, types.ListType):
- self.files = lldb.SBFileSpecList()
- for f in file:
- self.files.Append(lldb.SBFileSpec(f, False))
- elif isinstance(file, types.StringTypes):
- self.files.Append(lldb.SBFileSpec(file, False))
- self.breakpoints.append(
- self.target.BreakpointCreateByName(
- name, self.modules, self.files))
- elif file and line:
- self.breakpoints.append(
- self.target.BreakpointCreateByLocation(
- file, line))
-
- def ThreadStopped(self, thread):
- if thread.GetStopReason() == lldb.eStopReasonBreakpoint:
- for bp in self.breakpoints:
- if bp.GetID() == thread.GetStopReasonDataAtIndex(0):
- if self.callback:
- if self.callback_owner:
- self.callback(self.callback_owner, thread)
- else:
- self.callback(thread)
- return True
- return False
-
-
-class TestCase:
- """Class that aids in running performance tests."""
-
- def __init__(self):
- self.verbose = False
- self.debugger = lldb.SBDebugger.Create()
- self.target = None
- self.process = None
- self.thread = None
- self.launch_info = None
- self.done = False
- self.listener = self.debugger.GetListener()
- self.user_actions = list()
- self.builtin_actions = list()
- self.bp_id_to_dict = dict()
-
- def Setup(self, args):
- self.launch_info = lldb.SBLaunchInfo(args)
-
- def Run(self, args):
- assert False, "performance.TestCase.Run(self, args) must be subclassed"
-
- def Launch(self):
- if self.target:
- error = lldb.SBError()
- self.process = self.target.Launch(self.launch_info, error)
- if not error.Success():
- print "error: %s" % error.GetCString()
- if self.process:
- self.process.GetBroadcaster().AddListener(self.listener,
- lldb.SBProcess.eBroadcastBitStateChanged | lldb.SBProcess.eBroadcastBitInterrupt)
- return True
- return False
-
- def WaitForNextProcessEvent(self):
- event = None
- if self.process:
- while event is None:
- process_event = lldb.SBEvent()
- if self.listener.WaitForEvent(lldb.UINT32_MAX, process_event):
- state = lldb.SBProcess.GetStateFromEvent(process_event)
- if self.verbose:
- print "event = %s" % (lldb.SBDebugger.StateAsCString(state))
- if lldb.SBProcess.GetRestartedFromEvent(process_event):
- continue
- if state == lldb.eStateInvalid or state == lldb.eStateDetached or state == lldb.eStateCrashed or state == lldb.eStateUnloaded or state == lldb.eStateExited:
- event = process_event
- self.done = True
- elif state == lldb.eStateConnected or state == lldb.eStateAttaching or state == lldb.eStateLaunching or state == lldb.eStateRunning or state == lldb.eStateStepping or state == lldb.eStateSuspended:
- continue
- elif state == lldb.eStateStopped:
- event = process_event
- call_test_step = True
- fatal = False
- selected_thread = False
- for thread in self.process:
- frame = thread.GetFrameAtIndex(0)
- select_thread = False
-
- stop_reason = thread.GetStopReason()
- if self.verbose:
- print "tid = %#x pc = %#x " % (thread.GetThreadID(), frame.GetPC()),
- if stop_reason == lldb.eStopReasonNone:
- if self.verbose:
- print "none"
- elif stop_reason == lldb.eStopReasonTrace:
- select_thread = True
- if self.verbose:
- print "trace"
- elif stop_reason == lldb.eStopReasonPlanComplete:
- select_thread = True
- if self.verbose:
- print "plan complete"
- elif stop_reason == lldb.eStopReasonThreadExiting:
- if self.verbose:
- print "thread exiting"
- elif stop_reason == lldb.eStopReasonExec:
- if self.verbose:
- print "exec"
- elif stop_reason == lldb.eStopReasonInvalid:
- if self.verbose:
- print "invalid"
- elif stop_reason == lldb.eStopReasonException:
- select_thread = True
- if self.verbose:
- print "exception"
- fatal = True
- elif stop_reason == lldb.eStopReasonBreakpoint:
- select_thread = True
- bp_id = thread.GetStopReasonDataAtIndex(0)
- bp_loc_id = thread.GetStopReasonDataAtIndex(1)
- if self.verbose:
- print "breakpoint id = %d.%d" % (bp_id, bp_loc_id)
- elif stop_reason == lldb.eStopReasonWatchpoint:
- select_thread = True
- if self.verbose:
- print "watchpoint id = %d" % (thread.GetStopReasonDataAtIndex(0))
- elif stop_reason == lldb.eStopReasonSignal:
- select_thread = True
- if self.verbose:
- print "signal %d" % (thread.GetStopReasonDataAtIndex(0))
-
- if select_thread and not selected_thread:
- self.thread = thread
- selected_thread = self.process.SetSelectedThread(
- thread)
-
- for action in self.user_actions:
- action.ThreadStopped(thread)
-
- if fatal:
- # if self.verbose:
- # Xcode.RunCommand(self.debugger,"bt all",true)
- sys.exit(1)
- return event
-
-
-class Measurement:
- '''A class that encapsulates a measurement'''
-
- def __init__(self):
- object.__init__(self)
-
- def Measure(self):
- assert False, "performance.Measurement.Measure() must be subclassed"
-
-
-class MemoryMeasurement(Measurement):
- '''A class that can measure memory statistics for a process.'''
-
- def __init__(self, pid):
- Measurement.__init__(self)
- self.pid = pid
- self.stats = [
- "rprvt",
- "rshrd",
- "rsize",
- "vsize",
- "vprvt",
- "kprvt",
- "kshrd",
- "faults",
- "cow",
- "pageins"]
- self.command = "top -l 1 -pid %u -stats %s" % (
- self.pid, ",".join(self.stats))
- self.value = dict()
-
- def Measure(self):
- output = commands.getoutput(self.command).split("\n")[-1]
- values = re.split('[-+\s]+', output)
- for (idx, stat) in enumerate(values):
- multiplier = 1
- if stat:
- if stat[-1] == 'K':
- multiplier = 1024
- stat = stat[:-1]
- elif stat[-1] == 'M':
- multiplier = 1024 * 1024
- stat = stat[:-1]
- elif stat[-1] == 'G':
- multiplier = 1024 * 1024 * 1024
- elif stat[-1] == 'T':
- multiplier = 1024 * 1024 * 1024 * 1024
- stat = stat[:-1]
- self.value[self.stats[idx]] = int(stat) * multiplier
-
- def __str__(self):
- '''Dump the MemoryMeasurement current value'''
- s = ''
- for key in self.value.keys():
- if s:
- s += "\n"
- s += "%8s = %s" % (key, self.value[key])
- return s
-
-
-class TesterTestCase(TestCase):
-
- def __init__(self):
- TestCase.__init__(self)
- self.verbose = True
- self.num_steps = 5
-
- def BreakpointHit(self, thread):
- bp_id = thread.GetStopReasonDataAtIndex(0)
- loc_id = thread.GetStopReasonDataAtIndex(1)
- print "Breakpoint %i.%i hit: %s" % (bp_id, loc_id, thread.process.target.FindBreakpointByID(bp_id))
- thread.StepOver()
-
- def PlanComplete(self, thread):
- if self.num_steps > 0:
- thread.StepOver()
- self.num_steps = self.num_steps - 1
- else:
- thread.process.Kill()
-
- def Run(self, args):
- self.Setup(args)
- with Timer() as total_time:
- self.target = self.debugger.CreateTarget(args[0])
- if self.target:
- with Timer() as breakpoint_timer:
- bp = self.target.BreakpointCreateByName("main")
- print(
- 'Breakpoint time = %.03f sec.' %
- breakpoint_timer.interval)
-
- self.user_actions.append(
- BreakpointAction(
- breakpoint=bp,
- callback=TesterTestCase.BreakpointHit,
- callback_owner=self))
- self.user_actions.append(
- PlanCompleteAction(
- callback=TesterTestCase.PlanComplete,
- callback_owner=self))
-
- if self.Launch():
- while not self.done:
- self.WaitForNextProcessEvent()
- else:
- print "error: failed to launch process"
- else:
- print "error: failed to create target with '%s'" % (args[0])
- print('Total time = %.03f sec.' % total_time.interval)
-
-
-if __name__ == '__main__':
- lldb.SBDebugger.Initialize()
- test = TesterTestCase()
- test.Run(sys.argv[1:])
- mem = MemoryMeasurement(os.getpid())
- mem.Measure()
- print str(mem)
- lldb.SBDebugger.Terminate()
- # print "sleeeping for 100 seconds"
- # time.sleep(100)
diff --git a/examples/python/process_events.py b/examples/python/process_events.py
deleted file mode 100755
index c93020a979f0..000000000000
--- a/examples/python/process_events.py
+++ /dev/null
@@ -1,417 +0,0 @@
-#!/usr/bin/python
-
-#----------------------------------------------------------------------
-# Be sure to add the python path that points to the LLDB shared library.
-# On MacOSX csh, tcsh:
-# setenv PYTHONPATH /Applications/Xcode.app/Contents/SharedFrameworks/LLDB.framework/Resources/Python
-# On MacOSX sh, bash:
-# export PYTHONPATH=/Applications/Xcode.app/Contents/SharedFrameworks/LLDB.framework/Resources/Python
-#----------------------------------------------------------------------
-
-import commands
-import optparse
-import os
-import platform
-import sys
-
-#----------------------------------------------------------------------
-# Code that auto imports LLDB
-#----------------------------------------------------------------------
-try:
- # Just try for LLDB in case PYTHONPATH is already correctly setup
- import lldb
-except ImportError:
- lldb_python_dirs = list()
- # lldb is not in the PYTHONPATH, try some defaults for the current platform
- platform_system = platform.system()
- if platform_system == 'Darwin':
- # On Darwin, try the currently selected Xcode directory
- xcode_dir = commands.getoutput("xcode-select --print-path")
- if xcode_dir:
- lldb_python_dirs.append(
- os.path.realpath(
- xcode_dir +
- '/../SharedFrameworks/LLDB.framework/Resources/Python'))
- lldb_python_dirs.append(
- xcode_dir + '/Library/PrivateFrameworks/LLDB.framework/Resources/Python')
- lldb_python_dirs.append(
- '/System/Library/PrivateFrameworks/LLDB.framework/Resources/Python')
- success = False
- for lldb_python_dir in lldb_python_dirs:
- if os.path.exists(lldb_python_dir):
- if not (sys.path.__contains__(lldb_python_dir)):
- sys.path.append(lldb_python_dir)
- try:
- import lldb
- except ImportError:
- pass
- else:
- print 'imported lldb from: "%s"' % (lldb_python_dir)
- success = True
- break
- if not success:
- print "error: couldn't locate the 'lldb' module, please set PYTHONPATH correctly"
- sys.exit(1)
-
-
-def print_threads(process, options):
- if options.show_threads:
- for thread in process:
- print '%s %s' % (thread, thread.GetFrameAtIndex(0))
-
-
-def run_commands(command_interpreter, commands):
- return_obj = lldb.SBCommandReturnObject()
- for command in commands:
- command_interpreter.HandleCommand(command, return_obj)
- if return_obj.Succeeded():
- print return_obj.GetOutput()
- else:
- print return_obj
- if options.stop_on_error:
- break
-
-
-def main(argv):
- description = '''Debugs a program using the LLDB python API and uses asynchronous broadcast events to watch for process state changes.'''
- epilog = '''Examples:
-
-#----------------------------------------------------------------------
-# Run "/bin/ls" with the arguments "-lAF /tmp/", and set a breakpoint
-# at "malloc" and backtrace and read all registers each time we stop
-#----------------------------------------------------------------------
-% ./process_events.py --breakpoint malloc --stop-command bt --stop-command 'register read' -- /bin/ls -lAF /tmp/
-
-'''
- optparse.OptionParser.format_epilog = lambda self, formatter: self.epilog
- parser = optparse.OptionParser(
- description=description,
- prog='process_events',
- usage='usage: process_events [options] program [arg1 arg2]',
- epilog=epilog)
- parser.add_option(
- '-v',
- '--verbose',
- action='store_true',
- dest='verbose',
- help="Enable verbose logging.",
- default=False)
- parser.add_option(
- '-b',
- '--breakpoint',
- action='append',
- type='string',
- metavar='BPEXPR',
- dest='breakpoints',
- help='Breakpoint commands to create after the target has been created, the values will be sent to the "_regexp-break" command which supports breakpoints by name, file:line, and address.')
- parser.add_option(
- '-a',
- '--arch',
- type='string',
- dest='arch',
- help='The architecture to use when creating the debug target.',
- default=None)
- parser.add_option(
- '--platform',
- type='string',
- metavar='platform',
- dest='platform',
- help='Specify the platform to use when creating the debug target. Valid values include "localhost", "darwin-kernel", "ios-simulator", "remote-freebsd", "remote-macosx", "remote-ios", "remote-linux".',
- default=None)
- parser.add_option(
- '-l',
- '--launch-command',
- action='append',
- type='string',
- metavar='CMD',
- dest='launch_commands',
- help='LLDB command interpreter commands to run once after the process has launched. This option can be specified more than once.',
- default=[])
- parser.add_option(
- '-s',
- '--stop-command',
- action='append',
- type='string',
- metavar='CMD',
- dest='stop_commands',
- help='LLDB command interpreter commands to run each time the process stops. This option can be specified more than once.',
- default=[])
- parser.add_option(
- '-c',
- '--crash-command',
- action='append',
- type='string',
- metavar='CMD',
- dest='crash_commands',
- help='LLDB command interpreter commands to run in case the process crashes. This option can be specified more than once.',
- default=[])
- parser.add_option(
- '-x',
- '--exit-command',
- action='append',
- type='string',
- metavar='CMD',
- dest='exit_commands',
- help='LLDB command interpreter commands to run once after the process has exited. This option can be specified more than once.',
- default=[])
- parser.add_option(
- '-T',
- '--no-threads',
- action='store_false',
- dest='show_threads',
- help="Don't show threads when process stops.",
- default=True)
- parser.add_option(
- '--ignore-errors',
- action='store_false',
- dest='stop_on_error',
- help="Don't stop executing LLDB commands if the command returns an error. This applies to all of the LLDB command interpreter commands that get run for launch, stop, crash and exit.",
- default=True)
- parser.add_option(
- '-n',
- '--run-count',
- type='int',
- dest='run_count',
- metavar='N',
- help='How many times to run the process in case the process exits.',
- default=1)
- parser.add_option(
- '-t',
- '--event-timeout',
- type='int',
- dest='event_timeout',
- metavar='SEC',
- help='Specify the timeout in seconds to wait for process state change events.',
- default=lldb.UINT32_MAX)
- parser.add_option(
- '-e',
- '--environment',
- action='append',
- type='string',
- metavar='ENV',
- dest='env_vars',
- help='Environment variables to set in the inferior process when launching a process.')
- parser.add_option(
- '-d',
- '--working-dir',
- type='string',
- metavar='DIR',
- dest='working_dir',
- help='The the current working directory when launching a process.',
- default=None)
- parser.add_option(
- '-p',
- '--attach-pid',
- type='int',
- dest='attach_pid',
- metavar='PID',
- help='Specify a process to attach to by process ID.',
- default=-1)
- parser.add_option(
- '-P',
- '--attach-name',
- type='string',
- dest='attach_name',
- metavar='PROCESSNAME',
- help='Specify a process to attach to by name.',
- default=None)
- parser.add_option(
- '-w',
- '--attach-wait',
- action='store_true',
- dest='attach_wait',
- help='Wait for the next process to launch when attaching to a process by name.',
- default=False)
- try:
- (options, args) = parser.parse_args(argv)
- except:
- return
-
- attach_info = None
- launch_info = None
- exe = None
- if args:
- exe = args.pop(0)
- launch_info = lldb.SBLaunchInfo(args)
- if options.env_vars:
- launch_info.SetEnvironmentEntries(options.env_vars, True)
- if options.working_dir:
- launch_info.SetWorkingDirectory(options.working_dir)
- elif options.attach_pid != -1:
- if options.run_count == 1:
- attach_info = lldb.SBAttachInfo(options.attach_pid)
- else:
- print "error: --run-count can't be used with the --attach-pid option"
- sys.exit(1)
- elif not options.attach_name is None:
- if options.run_count == 1:
- attach_info = lldb.SBAttachInfo(
- options.attach_name, options.attach_wait)
- else:
- print "error: --run-count can't be used with the --attach-name option"
- sys.exit(1)
- else:
- print 'error: a program path for a program to debug and its arguments are required'
- sys.exit(1)
-
- # Create a new debugger instance
- debugger = lldb.SBDebugger.Create()
- debugger.SetAsync(True)
- command_interpreter = debugger.GetCommandInterpreter()
- # Create a target from a file and arch
-
- if exe:
- print "Creating a target for '%s'" % exe
- error = lldb.SBError()
- target = debugger.CreateTarget(
- exe, options.arch, options.platform, True, error)
-
- if target:
-
- # Set any breakpoints that were specified in the args if we are launching. We use the
- # command line command to take advantage of the shorthand breakpoint
- # creation
- if launch_info and options.breakpoints:
- for bp in options.breakpoints:
- debugger.HandleCommand("_regexp-break %s" % (bp))
- run_commands(command_interpreter, ['breakpoint list'])
-
- for run_idx in range(options.run_count):
- # Launch the process. Since we specified synchronous mode, we won't return
- # from this function until we hit the breakpoint at main
- error = lldb.SBError()
-
- if launch_info:
- if options.run_count == 1:
- print 'Launching "%s"...' % (exe)
- else:
- print 'Launching "%s"... (launch %u of %u)' % (exe, run_idx + 1, options.run_count)
-
- process = target.Launch(launch_info, error)
- else:
- if options.attach_pid != -1:
- print 'Attaching to process %i...' % (options.attach_pid)
- else:
- if options.attach_wait:
- print 'Waiting for next to process named "%s" to launch...' % (options.attach_name)
- else:
- print 'Attaching to existing process named "%s"...' % (options.attach_name)
- process = target.Attach(attach_info, error)
-
- # Make sure the launch went ok
- if process and process.GetProcessID() != lldb.LLDB_INVALID_PROCESS_ID:
-
- pid = process.GetProcessID()
- print 'Process is %i' % (pid)
- if attach_info:
- # continue process if we attached as we won't get an
- # initial event
- process.Continue()
-
- listener = debugger.GetListener()
- # sign up for process state change events
- stop_idx = 0
- done = False
- while not done:
- event = lldb.SBEvent()
- if listener.WaitForEvent(options.event_timeout, event):
- if lldb.SBProcess.EventIsProcessEvent(event):
- state = lldb.SBProcess.GetStateFromEvent(event)
- if state == lldb.eStateInvalid:
- # Not a state event
- print 'process event = %s' % (event)
- else:
- print "process state changed event: %s" % (lldb.SBDebugger.StateAsCString(state))
- if state == lldb.eStateStopped:
- if stop_idx == 0:
- if launch_info:
- print "process %u launched" % (pid)
- run_commands(
- command_interpreter, ['breakpoint list'])
- else:
- print "attached to process %u" % (pid)
- for m in target.modules:
- print m
- if options.breakpoints:
- for bp in options.breakpoints:
- debugger.HandleCommand(
- "_regexp-break %s" % (bp))
- run_commands(
- command_interpreter, ['breakpoint list'])
- run_commands(
- command_interpreter, options.launch_commands)
- else:
- if options.verbose:
- print "process %u stopped" % (pid)
- run_commands(
- command_interpreter, options.stop_commands)
- stop_idx += 1
- print_threads(process, options)
- print "continuing process %u" % (pid)
- process.Continue()
- elif state == lldb.eStateExited:
- exit_desc = process.GetExitDescription()
- if exit_desc:
- print "process %u exited with status %u: %s" % (pid, process.GetExitStatus(), exit_desc)
- else:
- print "process %u exited with status %u" % (pid, process.GetExitStatus())
- run_commands(
- command_interpreter, options.exit_commands)
- done = True
- elif state == lldb.eStateCrashed:
- print "process %u crashed" % (pid)
- print_threads(process, options)
- run_commands(
- command_interpreter, options.crash_commands)
- done = True
- elif state == lldb.eStateDetached:
- print "process %u detached" % (pid)
- done = True
- elif state == lldb.eStateRunning:
- # process is running, don't say anything,
- # we will always get one of these after
- # resuming
- if options.verbose:
- print "process %u resumed" % (pid)
- elif state == lldb.eStateUnloaded:
- print "process %u unloaded, this shouldn't happen" % (pid)
- done = True
- elif state == lldb.eStateConnected:
- print "process connected"
- elif state == lldb.eStateAttaching:
- print "process attaching"
- elif state == lldb.eStateLaunching:
- print "process launching"
- else:
- print 'event = %s' % (event)
- else:
- # timeout waiting for an event
- print "no process event for %u seconds, killing the process..." % (options.event_timeout)
- done = True
- # Now that we are done dump the stdout and stderr
- process_stdout = process.GetSTDOUT(1024)
- if process_stdout:
- print "Process STDOUT:\n%s" % (process_stdout)
- while process_stdout:
- process_stdout = process.GetSTDOUT(1024)
- print process_stdout
- process_stderr = process.GetSTDERR(1024)
- if process_stderr:
- print "Process STDERR:\n%s" % (process_stderr)
- while process_stderr:
- process_stderr = process.GetSTDERR(1024)
- print process_stderr
- process.Kill() # kill the process
- else:
- if error:
- print error
- else:
- if launch_info:
- print 'error: launch failed'
- else:
- print 'error: attach failed'
-
- lldb.SBDebugger.Terminate()
-
-if __name__ == '__main__':
- main(sys.argv[1:])
diff --git a/examples/python/pytracer.py b/examples/python/pytracer.py
deleted file mode 100644
index a166f21e9839..000000000000
--- a/examples/python/pytracer.py
+++ /dev/null
@@ -1,360 +0,0 @@
-import sys
-import inspect
-from collections import OrderedDict
-
-
-class TracebackFancy:
-
- def __init__(self, traceback):
- self.t = traceback
-
- def getFrame(self):
- return FrameFancy(self.t.tb_frame)
-
- def getLineNumber(self):
- return self.t.tb_lineno if self.t is not None else None
-
- def getNext(self):
- return TracebackFancy(self.t.tb_next)
-
- def __str__(self):
- if self.t is None:
- return ""
- str_self = "%s @ %s" % (
- self.getFrame().getName(), self.getLineNumber())
- return str_self + "\n" + self.getNext().__str__()
-
-
-class ExceptionFancy:
-
- def __init__(self, frame):
- self.etraceback = frame.f_exc_traceback
- self.etype = frame.exc_type
- self.evalue = frame.f_exc_value
-
- def __init__(self, tb, ty, va):
- self.etraceback = tb
- self.etype = ty
- self.evalue = va
-
- def getTraceback(self):
- return TracebackFancy(self.etraceback)
-
- def __nonzero__(self):
- return self.etraceback is not None or self.etype is not None or self.evalue is not None
-
- def getType(self):
- return str(self.etype)
-
- def getValue(self):
- return self.evalue
-
-
-class CodeFancy:
-
- def __init__(self, code):
- self.c = code
-
- def getArgCount(self):
- return self.c.co_argcount if self.c is not None else 0
-
- def getFilename(self):
- return self.c.co_filename if self.c is not None else ""
-
- def getVariables(self):
- return self.c.co_varnames if self.c is not None else []
-
- def getName(self):
- return self.c.co_name if self.c is not None else ""
-
- def getFileName(self):
- return self.c.co_filename if self.c is not None else ""
-
-
-class ArgsFancy:
-
- def __init__(self, frame, arginfo):
- self.f = frame
- self.a = arginfo
-
- def __str__(self):
- args, varargs, kwargs = self.getArgs(), self.getVarArgs(), self.getKWArgs()
- ret = ""
- count = 0
- size = len(args)
- for arg in args:
- ret = ret + ("%s = %s" % (arg, args[arg]))
- count = count + 1
- if count < size:
- ret = ret + ", "
- if varargs:
- if size > 0:
- ret = ret + " "
- ret = ret + "varargs are " + str(varargs)
- if kwargs:
- if size > 0:
- ret = ret + " "
- ret = ret + "kwargs are " + str(kwargs)
- return ret
-
- def getNumArgs(wantVarargs=False, wantKWArgs=False):
- args, varargs, keywords, values = self.a
- size = len(args)
- if varargs and wantVarargs:
- size = size + len(self.getVarArgs())
- if keywords and wantKWArgs:
- size = size + len(self.getKWArgs())
- return size
-
- def getArgs(self):
- args, _, _, values = self.a
- argWValues = OrderedDict()
- for arg in args:
- argWValues[arg] = values[arg]
- return argWValues
-
- def getVarArgs(self):
- _, vargs, _, _ = self.a
- if vargs:
- return self.f.f_locals[vargs]
- return ()
-
- def getKWArgs(self):
- _, _, kwargs, _ = self.a
- if kwargs:
- return self.f.f_locals[kwargs]
- return {}
-
-
-class FrameFancy:
-
- def __init__(self, frame):
- self.f = frame
-
- def getCaller(self):
- return FrameFancy(self.f.f_back)
-
- def getLineNumber(self):
- return self.f.f_lineno if self.f is not None else 0
-
- def getCodeInformation(self):
- return CodeFancy(self.f.f_code) if self.f is not None else None
-
- def getExceptionInfo(self):
- return ExceptionFancy(self.f) if self.f is not None else None
-
- def getName(self):
- return self.getCodeInformation().getName() if self.f is not None else ""
-
- def getFileName(self):
- return self.getCodeInformation().getFileName() if self.f is not None else ""
-
- def getLocals(self):
- return self.f.f_locals if self.f is not None else {}
-
- def getArgumentInfo(self):
- return ArgsFancy(
- self.f, inspect.getargvalues(
- self.f)) if self.f is not None else None
-
-
-class TracerClass:
-
- def callEvent(self, frame):
- pass
-
- def lineEvent(self, frame):
- pass
-
- def returnEvent(self, frame, retval):
- pass
-
- def exceptionEvent(self, frame, exception, value, traceback):
- pass
-
- def cCallEvent(self, frame, cfunct):
- pass
-
- def cReturnEvent(self, frame, cfunct):
- pass
-
- def cExceptionEvent(self, frame, cfunct):
- pass
-
-tracer_impl = TracerClass()
-
-
-def the_tracer_entrypoint(frame, event, args):
- if tracer_impl is None:
- return None
- if event == "call":
- call_retval = tracer_impl.callEvent(FrameFancy(frame))
- if not call_retval:
- return None
- return the_tracer_entrypoint
- elif event == "line":
- line_retval = tracer_impl.lineEvent(FrameFancy(frame))
- if not line_retval:
- return None
- return the_tracer_entrypoint
- elif event == "return":
- tracer_impl.returnEvent(FrameFancy(frame), args)
- elif event == "exception":
- exty, exva, extb = args
- exception_retval = tracer_impl.exceptionEvent(
- FrameFancy(frame), ExceptionFancy(extb, exty, exva))
- if not exception_retval:
- return None
- return the_tracer_entrypoint
- elif event == "c_call":
- tracer_impl.cCallEvent(FrameFancy(frame), args)
- elif event == "c_return":
- tracer_impl.cReturnEvent(FrameFancy(frame), args)
- elif event == "c_exception":
- tracer_impl.cExceptionEvent(FrameFancy(frame), args)
- return None
-
-
-def enable(t=None):
- global tracer_impl
- if t:
- tracer_impl = t
- sys.settrace(the_tracer_entrypoint)
-
-
-def disable():
- sys.settrace(None)
-
-
-class LoggingTracer:
-
- def callEvent(self, frame):
- print "call " + frame.getName() + " from " + frame.getCaller().getName() + " @ " + str(frame.getCaller().getLineNumber()) + " args are " + str(frame.getArgumentInfo())
-
- def lineEvent(self, frame):
- print "running " + frame.getName() + " @ " + str(frame.getLineNumber()) + " locals are " + str(frame.getLocals()) + " in " + frame.getFileName()
-
- def returnEvent(self, frame, retval):
- print "return from " + frame.getName() + " value is " + str(retval) + " locals are " + str(frame.getLocals())
-
- def exceptionEvent(self, frame, exception):
- print "exception %s %s raised from %s @ %s" % (exception.getType(), str(exception.getValue()), frame.getName(), frame.getLineNumber())
- print "tb: " + str(exception.getTraceback())
-
-# the same functionality as LoggingTracer, but with a little more
-# lldb-specific smarts
-
-
-class LLDBAwareTracer:
-
- def callEvent(self, frame):
- if frame.getName() == "<module>":
- return
- if frame.getName() == "run_one_line":
- print "call run_one_line(%s)" % (frame.getArgumentInfo().getArgs()["input_string"])
- return
- if "Python.framework" in frame.getFileName():
- print "call into Python at " + frame.getName()
- return
- if frame.getName() == "__init__" and frame.getCaller().getName(
- ) == "run_one_line" and frame.getCaller().getLineNumber() == 101:
- return False
- strout = "call " + frame.getName()
- if (frame.getCaller().getFileName() == ""):
- strout += " from LLDB - args are "
- args = frame.getArgumentInfo().getArgs()
- for arg in args:
- if arg == "dict" or arg == "internal_dict":
- continue
- strout = strout + ("%s = %s " % (arg, args[arg]))
- else:
- strout += " from " + frame.getCaller().getName() + " @ " + \
- str(frame.getCaller().getLineNumber()) + " args are " + str(frame.getArgumentInfo())
- print strout
-
- def lineEvent(self, frame):
- if frame.getName() == "<module>":
- return
- if frame.getName() == "run_one_line":
- print "running run_one_line(%s) @ %s" % (frame.getArgumentInfo().getArgs()["input_string"], frame.getLineNumber())
- return
- if "Python.framework" in frame.getFileName():
- print "running into Python at " + frame.getName() + " @ " + str(frame.getLineNumber())
- return
- strout = "running " + frame.getName() + " @ " + str(frame.getLineNumber()) + \
- " locals are "
- if (frame.getCaller().getFileName() == ""):
- locals = frame.getLocals()
- for local in locals:
- if local == "dict" or local == "internal_dict":
- continue
- strout = strout + ("%s = %s " % (local, locals[local]))
- else:
- strout = strout + str(frame.getLocals())
- strout = strout + " in " + frame.getFileName()
- print strout
-
- def returnEvent(self, frame, retval):
- if frame.getName() == "<module>":
- return
- if frame.getName() == "run_one_line":
- print "return from run_one_line(%s) return value is %s" % (frame.getArgumentInfo().getArgs()["input_string"], retval)
- return
- if "Python.framework" in frame.getFileName():
- print "return from Python at " + frame.getName() + " return value is " + str(retval)
- return
- strout = "return from " + frame.getName() + " return value is " + \
- str(retval) + " locals are "
- if (frame.getCaller().getFileName() == ""):
- locals = frame.getLocals()
- for local in locals:
- if local == "dict" or local == "internal_dict":
- continue
- strout = strout + ("%s = %s " % (local, locals[local]))
- else:
- strout = strout + str(frame.getLocals())
- strout = strout + " in " + frame.getFileName()
- print strout
-
- def exceptionEvent(self, frame, exception):
- if frame.getName() == "<module>":
- return
- print "exception %s %s raised from %s @ %s" % (exception.getType(), str(exception.getValue()), frame.getName(), frame.getLineNumber())
- print "tb: " + str(exception.getTraceback())
-
-
-def f(x, y=None):
- if x > 0:
- return 2 + f(x - 2)
- return 35
-
-
-def g(x):
- return 1.134 / x
-
-
-def print_keyword_args(**kwargs):
- # kwargs is a dict of the keyword args passed to the function
- for key, value in kwargs.iteritems():
- print "%s = %s" % (key, value)
-
-
-def total(initial=5, *numbers, **keywords):
- count = initial
- for number in numbers:
- count += number
- for key in keywords:
- count += keywords[key]
- return count
-
-if __name__ == "__main__":
- enable(LoggingTracer())
- f(5)
- f(5, 1)
- print_keyword_args(first_name="John", last_name="Doe")
- total(10, 1, 2, 3, vegetables=50, fruits=100)
- try:
- g(0)
- except:
- pass
- disable()
diff --git a/examples/python/sbvalue.py b/examples/python/sbvalue.py
deleted file mode 100755
index 6e512998da2f..000000000000
--- a/examples/python/sbvalue.py
+++ /dev/null
@@ -1,268 +0,0 @@
-#!/usr/bin/python
-
-import lldb
-
-
-class value(object):
- '''A class that wraps an lldb.SBValue object and returns an object that
- can be used as an object with attribytes:\n
- argv = a.value(lldb.frame.FindVariable('argv'))\n
- argv.name - return the name of the value that this object contains\n
- argv.type - return the lldb.SBType for this value
- argv.type_name - return the name of the type
- argv.size - return the byte size of this value
- argv.is_in_scope - return true if this value is currently in scope
- argv.is_pointer - return true if this value is a pointer
- argv.format - return the current format for this value
- argv.value - return the value's value as a string
- argv.summary - return a summary of this value's value
- argv.description - return the runtime description for this value
- argv.location - return a string that represents the values location (address, register, etc)
- argv.target - return the lldb.SBTarget for this value
- argv.process - return the lldb.SBProcess for this value
- argv.thread - return the lldb.SBThread for this value
- argv.frame - return the lldb.SBFrame for this value
- argv.num_children - return the number of children this value has
- argv.children - return a list of sbvalue objects that represents all of the children of this value
- '''
-
- def __init__(self, sbvalue):
- self.sbvalue = sbvalue
-
- def __nonzero__(self):
- return self.sbvalue.__nonzero__()
-
- def __repr__(self):
- return self.sbvalue.__repr__()
-
- def __str__(self):
- return self.sbvalue.__str__()
-
- def __getitem__(self, key):
- if isinstance(key, int):
- return value(
- self.sbvalue.GetChildAtIndex(
- key, lldb.eNoDynamicValues, True))
- raise TypeError
-
- def __getattr__(self, name):
- if name == 'name':
- return self.sbvalue.GetName()
- if name == 'type':
- return self.sbvalue.GetType()
- if name == 'type_name':
- return self.sbvalue.GetTypeName()
- if name == 'size':
- return self.sbvalue.GetByteSize()
- if name == 'is_in_scope':
- return self.sbvalue.IsInScope()
- if name == 'is_pointer':
- return self.sbvalue.TypeIsPointerType()
- if name == 'format':
- return self.sbvalue.GetFormat()
- if name == 'value':
- return self.sbvalue.GetValue()
- if name == 'summary':
- return self.sbvalue.GetSummary()
- if name == 'description':
- return self.sbvalue.GetObjectDescription()
- if name == 'location':
- return self.sbvalue.GetLocation()
- if name == 'target':
- return self.sbvalue.GetTarget()
- if name == 'process':
- return self.sbvalue.GetProcess()
- if name == 'thread':
- return self.sbvalue.GetThread()
- if name == 'frame':
- return self.sbvalue.GetFrame()
- if name == 'num_children':
- return self.sbvalue.GetNumChildren()
- if name == 'children':
- # Returns an array of sbvalue objects, one for each child of
- # the value for the lldb.SBValue
- children = []
- for i in range(self.sbvalue.GetNumChildren()):
- children.append(
- value(
- self.sbvalue.GetChildAtIndex(
- i,
- lldb.eNoDynamicValues,
- True)))
- return children
- raise AttributeError
-
-
-class variable(object):
- '''A class that treats a lldb.SBValue and allows it to be used just as
- a variable would be in code. So if you have a Point structure variable
- in your code, you would be able to do: "pt.x + pt.y"'''
-
- def __init__(self, sbvalue):
- self.sbvalue = sbvalue
-
- def __nonzero__(self):
- return self.sbvalue.__nonzero__()
-
- def __repr__(self):
- return self.sbvalue.__repr__()
-
- def __str__(self):
- return self.sbvalue.__str__()
-
- def __getitem__(self, key):
- # Allow array access if this value has children...
- if isinstance(key, int):
- return variable(
- self.sbvalue.GetValueForExpressionPath(
- "[%i]" %
- key))
- raise TypeError
-
- def __getattr__(self, name):
- child_sbvalue = self.sbvalue.GetChildMemberWithName(name)
- if child_sbvalue:
- return variable(child_sbvalue)
- raise AttributeError
-
- def __add__(self, other):
- return int(self) + int(other)
-
- def __sub__(self, other):
- return int(self) - int(other)
-
- def __mul__(self, other):
- return int(self) * int(other)
-
- def __floordiv__(self, other):
- return int(self) // int(other)
-
- def __mod__(self, other):
- return int(self) % int(other)
-
- def __divmod__(self, other):
- return int(self) % int(other)
-
- def __pow__(self, other):
- return int(self) ** int(other)
-
- def __lshift__(self, other):
- return int(self) << int(other)
-
- def __rshift__(self, other):
- return int(self) >> int(other)
-
- def __and__(self, other):
- return int(self) & int(other)
-
- def __xor__(self, other):
- return int(self) ^ int(other)
-
- def __or__(self, other):
- return int(self) | int(other)
-
- def __div__(self, other):
- return int(self) / int(other)
-
- def __truediv__(self, other):
- return int(self) / int(other)
-
- def __iadd__(self, other):
- result = self.__add__(other)
- self.sbvalue.SetValueFromCString(str(result))
- return result
-
- def __isub__(self, other):
- result = self.__sub__(other)
- self.sbvalue.SetValueFromCString(str(result))
- return result
-
- def __imul__(self, other):
- result = self.__mul__(other)
- self.sbvalue.SetValueFromCString(str(result))
- return result
-
- def __idiv__(self, other):
- result = self.__div__(other)
- self.sbvalue.SetValueFromCString(str(result))
- return result
-
- def __itruediv__(self, other):
- result = self.__truediv__(other)
- self.sbvalue.SetValueFromCString(str(result))
- return result
-
- def __ifloordiv__(self, other):
- result = self.__floordiv__(self, other)
- self.sbvalue.SetValueFromCString(str(result))
- return result
-
- def __imod__(self, other):
- result = self.__and__(self, other)
- self.sbvalue.SetValueFromCString(str(result))
- return result
-
- def __ipow__(self, other):
- result = self.__pow__(self, other)
- self.sbvalue.SetValueFromCString(str(result))
- return result
-
- def __ipow__(self, other, modulo):
- result = self.__pow__(self, other, modulo)
- self.sbvalue.SetValueFromCString(str(result))
- return result
-
- def __ilshift__(self, other):
- result = self.__lshift__(self, other)
- self.sbvalue.SetValueFromCString(str(result))
- return result
-
- def __irshift__(self, other):
- result = self.__rshift__(self, other)
- self.sbvalue.SetValueFromCString(str(result))
- return result
-
- def __iand__(self, other):
- result = self.__and__(self, other)
- self.sbvalue.SetValueFromCString(str(result))
- return result
-
- def __ixor__(self, other):
- result = self.__xor__(self, other)
- self.sbvalue.SetValueFromCString(str(result))
- return result
-
- def __ior__(self, other):
- result = self.__ior__(self, other)
- self.sbvalue.SetValueFromCString(str(result))
- return result
-
- def __neg__(self):
- return -int(self)
-
- def __pos__(self):
- return +int(self)
-
- def __abs__(self):
- return abs(int(self))
-
- def __invert__(self):
- return ~int(self)
-
- def __complex__(self):
- return complex(int(self))
-
- def __int__(self):
- return self.sbvalue.GetValueAsSigned()
-
- def __long__(self):
- return self.sbvalue.GetValueAsSigned()
-
- def __float__(self):
- return float(self.sbvalue.GetValueAsSigned())
-
- def __oct__(self):
- return '0%o' % self.sbvalue.GetValueAsSigned()
-
- def __hex__(self):
- return '0x%x' % self.sbvalue.GetValueAsSigned()
diff --git a/examples/python/scripted_step.py b/examples/python/scripted_step.py
deleted file mode 100644
index 453b5e229fb4..000000000000
--- a/examples/python/scripted_step.py
+++ /dev/null
@@ -1,244 +0,0 @@
-#############################################################################
-# This script contains two trivial examples of simple "scripted step" classes.
-# To fully understand how the lldb "Thread Plan" architecture works, read the
-# comments at the beginning of ThreadPlan.h in the lldb sources. The python
-# interface is a reduced version of the full internal mechanism, but captures
-# most of the power with a much simpler interface.
-#
-# But I'll attempt a brief summary here.
-# Stepping in lldb is done independently for each thread. Moreover, the stepping
-# operations are stackable. So for instance if you did a "step over", and in
-# the course of stepping over you hit a breakpoint, stopped and stepped again,
-# the first "step-over" would be suspended, and the new step operation would
-# be enqueued. Then if that step over caused the program to hit another breakpoint,
-# lldb would again suspend the second step and return control to the user, so
-# now there are two pending step overs. Etc. with all the other stepping
-# operations. Then if you hit "continue" the bottom-most step-over would complete,
-# and another continue would complete the first "step-over".
-#
-# lldb represents this system with a stack of "Thread Plans". Each time a new
-# stepping operation is requested, a new plan is pushed on the stack. When the
-# operation completes, it is pushed off the stack.
-#
-# The bottom-most plan in the stack is the immediate controller of stepping,
-# most importantly, when the process resumes, the bottom most plan will get
-# asked whether to set the program running freely, or to instruction-single-step
-# the current thread. In the scripted interface, you indicate this by returning
-# False or True respectively from the should_step method.
-#
-# Each time the process stops the thread plan stack for each thread that stopped
-# "for a reason", Ii.e. a single-step completed on that thread, or a breakpoint
-# was hit), is queried to determine how to proceed, starting from the most
-# recently pushed plan, in two stages:
-#
-# 1) Each plan is asked if it "explains" the stop. The first plan to claim the
-# stop wins. In scripted Thread Plans, this is done by returning True from
-# the "explains_stop method. This is how, for instance, control is returned
-# to the User when the "step-over" plan hits a breakpoint. The step-over
-# plan doesn't explain the breakpoint stop, so it returns false, and the
-# breakpoint hit is propagated up the stack to the "base" thread plan, which
-# is the one that handles random breakpoint hits.
-#
-# 2) Then the plan that won the first round is asked if the process should stop.
-# This is done in the "should_stop" method. The scripted plans actually do
-# three jobs in should_stop:
-# a) They determine if they have completed their job or not. If they have
-# they indicate that by calling SetPlanComplete on their thread plan.
-# b) They decide whether they want to return control to the user or not.
-# They do this by returning True or False respectively.
-# c) If they are not done, they set up whatever machinery they will use
-# the next time the thread continues.
-#
-# Note that deciding to return control to the user, and deciding your plan
-# is done, are orthgonal operations. You could set up the next phase of
-# stepping, and then return True from should_stop, and when the user next
-# "continued" the process your plan would resume control. Of course, the
-# user might also "step-over" or some other operation that would push a
-# different plan, which would take control till it was done.
-#
-# One other detail you should be aware of, if the plan below you on the
-# stack was done, then it will be popped and the next plan will take control
-# and its "should_stop" will be called.
-#
-# Note also, there should be another method called when your plan is popped,
-# to allow you to do whatever cleanup is required. I haven't gotten to that
-# yet. For now you should do that at the same time you mark your plan complete.
-#
-# 3) After the round of negotiation over whether to stop or not is done, all the
-# plans get asked if they are "stale". If they are say they are stale
-# then they will get popped. This question is asked with the "is_stale" method.
-#
-# This is useful, for instance, in the FinishPrintAndContinue plan. What might
-# happen here is that after continuing but before the finish is done, the program
-# could hit another breakpoint and stop. Then the user could use the step
-# command repeatedly until they leave the frame of interest by stepping.
-# In that case, the step plan is the one that will be responsible for stopping,
-# and the finish plan won't be asked should_stop, it will just be asked if it
-# is stale. In this case, if the step_out plan that the FinishPrintAndContinue
-# plan is driving is stale, so is ours, and it is time to do our printing.
-#
-# Both examples show stepping through an address range for 20 bytes from the
-# current PC. The first one does it by single stepping and checking a condition.
-# It doesn't, however handle the case where you step into another frame while
-# still in the current range in the starting frame.
-#
-# That is better handled in the second example by using the built-in StepOverRange
-# thread plan.
-#
-# To use these stepping modes, you would do:
-#
-# (lldb) command script import scripted_step.py
-# (lldb) thread step-scripted -C scripted_step.SimpleStep
-# or
-#
-# (lldb) thread step-scripted -C scripted_step.StepWithPlan
-
-import lldb
-
-
-class SimpleStep:
-
- def __init__(self, thread_plan, dict):
- self.thread_plan = thread_plan
- self.start_address = thread_plan.GetThread().GetFrameAtIndex(0).GetPC()
-
- def explains_stop(self, event):
- # We are stepping, so if we stop for any other reason, it isn't
- # because of us.
- if self.thread_plan.GetThread().GetStopReason() == lldb.eStopReasonTrace:
- return True
- else:
- return False
-
- def should_stop(self, event):
- cur_pc = self.thread_plan.GetThread().GetFrameAtIndex(0).GetPC()
-
- if cur_pc < self.start_address or cur_pc >= self.start_address + 20:
- self.thread_plan.SetPlanComplete(True)
- return True
- else:
- return False
-
- def should_step(self):
- return True
-
-
-class StepWithPlan:
-
- def __init__(self, thread_plan, dict):
- self.thread_plan = thread_plan
- self.start_address = thread_plan.GetThread().GetFrameAtIndex(0).GetPCAddress()
- self.step_thread_plan = thread_plan.QueueThreadPlanForStepOverRange(
- self.start_address, 20)
-
- def explains_stop(self, event):
- # Since all I'm doing is running a plan, I will only ever get askedthis
- # if myplan doesn't explain the stop, and in that caseI don'teither.
- return False
-
- def should_stop(self, event):
- if self.step_thread_plan.IsPlanComplete():
- self.thread_plan.SetPlanComplete(True)
- return True
- else:
- return False
-
- def should_step(self):
- return False
-
-# Here's another example which does "step over" through the current function,
-# and when it stops at each line, it checks some condition (in this example the
-# value of a variable) and stops if that condition is true.
-
-
-class StepCheckingCondition:
-
- def __init__(self, thread_plan, dict):
- self.thread_plan = thread_plan
- self.start_frame = thread_plan.GetThread().GetFrameAtIndex(0)
- self.queue_next_plan()
-
- def queue_next_plan(self):
- cur_frame = self.thread_plan.GetThread().GetFrameAtIndex(0)
- cur_line_entry = cur_frame.GetLineEntry()
- start_address = cur_line_entry.GetStartAddress()
- end_address = cur_line_entry.GetEndAddress()
- line_range = end_address.GetFileAddress() - start_address.GetFileAddress()
- self.step_thread_plan = self.thread_plan.QueueThreadPlanForStepOverRange(
- start_address, line_range)
-
- def explains_stop(self, event):
- # We are stepping, so if we stop for any other reason, it isn't
- # because of us.
- return False
-
- def should_stop(self, event):
- if not self.step_thread_plan.IsPlanComplete():
- return False
-
- frame = self.thread_plan.GetThread().GetFrameAtIndex(0)
- if not self.start_frame.IsEqual(frame):
- self.thread_plan.SetPlanComplete(True)
- return True
-
- # This part checks the condition. In this case we are expecting
- # some integer variable called "a", and will stop when it is 20.
- a_var = frame.FindVariable("a")
-
- if not a_var.IsValid():
- print "A was not valid."
- return True
-
- error = lldb.SBError()
- a_value = a_var.GetValueAsSigned(error)
- if not error.Success():
- print "A value was not good."
- return True
-
- if a_value == 20:
- self.thread_plan.SetPlanComplete(True)
- return True
- else:
- self.queue_next_plan()
- return False
-
- def should_step(self):
- return True
-
-# Here's an example that steps out of the current frame, gathers some information
-# and then continues. The information in this case is rax. Currently the thread
-# plans are not a safe place to call lldb command-line commands, so the information
-# is gathered through SB API calls.
-
-
-class FinishPrintAndContinue:
-
- def __init__(self, thread_plan, dict):
- self.thread_plan = thread_plan
- self.step_out_thread_plan = thread_plan.QueueThreadPlanForStepOut(
- 0, True)
- self.thread = self.thread_plan.GetThread()
-
- def is_stale(self):
- if self.step_out_thread_plan.IsPlanStale():
- self.do_print()
- return True
- else:
- return False
-
- def explains_stop(self, event):
- return False
-
- def should_stop(self, event):
- if self.step_out_thread_plan.IsPlanComplete():
- self.do_print()
- self.thread_plan.SetPlanComplete(True)
- return False
-
- def do_print(self):
- frame_0 = self.thread.frames[0]
- rax_value = frame_0.FindRegister("rax")
- if rax_value.GetError().Success():
- print "RAX on exit: ", rax_value.GetValue()
- else:
- print "Couldn't get rax value:", rax_value.GetError().GetCString()
diff --git a/examples/python/shadow.py b/examples/python/shadow.py
deleted file mode 100644
index 0556cfc553ce..000000000000
--- a/examples/python/shadow.py
+++ /dev/null
@@ -1,58 +0,0 @@
-#!/usr/bin/python
-
-import lldb
-import shlex
-
-
-@lldb.command("shadow")
-def check_shadow_command(debugger, command, exe_ctx, result, dict):
- '''Check the currently selected stack frame for shadowed variables'''
- process = exe_ctx.GetProcess()
- state = process.GetState()
- if state != lldb.eStateStopped:
- print >>result, "process must be stopped, state is %s" % lldb.SBDebugger.StateAsCString(
- state)
- return
- frame = exe_ctx.GetFrame()
- if not frame:
- print >>result, "invalid frame"
- return
- # Parse command line args
- command_args = shlex.split(command)
- # TODO: add support for using arguments that are passed to this command...
-
- # Make a dictionary of variable name to "SBBlock and SBValue"
- shadow_dict = {}
-
- num_shadowed_variables = 0
- # Get the deepest most block from the current frame
- block = frame.GetBlock()
- # Iterate through the block and all of its parents
- while block.IsValid():
- # Get block variables from the current block only
- block_vars = block.GetVariables(frame, True, True, True, 0)
- # Iterate through all variables in the current block
- for block_var in block_vars:
- # Since we can have multiple shadowed variables, we our variable
- # name dictionary to have an array or "block + variable" pairs so
- # We can correctly print out all shadowed variables and whow which
- # blocks they come from
- block_var_name = block_var.GetName()
- if block_var_name in shadow_dict:
- shadow_dict[block_var_name].append(block_var)
- else:
- shadow_dict[block_var_name] = [block_var]
- # Get the parent block and continue
- block = block.GetParent()
-
- num_shadowed_variables = 0
- if shadow_dict:
- for name in shadow_dict.keys():
- shadow_vars = shadow_dict[name]
- if len(shadow_vars) > 1:
- print '"%s" is shadowed by the following declarations:' % (name)
- num_shadowed_variables += 1
- for shadow_var in shadow_vars:
- print >>result, str(shadow_var.GetDeclaration())
- if num_shadowed_variables == 0:
- print >>result, 'no variables are shadowed'
diff --git a/examples/python/sources.py b/examples/python/sources.py
deleted file mode 100644
index b912f43f72c3..000000000000
--- a/examples/python/sources.py
+++ /dev/null
@@ -1,31 +0,0 @@
-#!/usr/bin/python
-
-import lldb
-import shlex
-
-
-def dump_module_sources(module, result):
- if module:
- print >> result, "Module: %s" % (module.file)
- for compile_unit in module.compile_units:
- if compile_unit.file:
- print >> result, " %s" % (compile_unit.file)
-
-
-def info_sources(debugger, command, result, dict):
- description = '''This command will dump all compile units in any modules that are listed as arguments, or for all modules if no arguments are supplied.'''
- module_names = shlex.split(command)
- target = debugger.GetSelectedTarget()
- if module_names:
- for module_name in module_names:
- dump_module_sources(target.module[module_name], result)
- else:
- for module in target.modules:
- dump_module_sources(module, result)
-
-
-def __lldb_init_module(debugger, dict):
- # Add any commands contained in this module to LLDB
- debugger.HandleCommand(
- 'command script add -f sources.info_sources info_sources')
- print 'The "info_sources" command has been installed, type "help info_sources" or "info_sources --help" for detailed help.'
diff --git a/examples/python/stacks.py b/examples/python/stacks.py
deleted file mode 100755
index fec879993d96..000000000000
--- a/examples/python/stacks.py
+++ /dev/null
@@ -1,69 +0,0 @@
-#!/usr/bin/python
-
-import lldb
-import commands
-import optparse
-import shlex
-
-
-def stack_frames(debugger, command, result, dict):
- command_args = shlex.split(command)
- usage = "usage: %prog [options] <PATH> [PATH ...]"
- description = '''This command will enumerate all stack frames, print the stack size for each, and print an aggregation of which functions have the largest stack frame sizes at the end.'''
- parser = optparse.OptionParser(
- description=description, prog='ls', usage=usage)
- parser.add_option(
- '-v',
- '--verbose',
- action='store_true',
- dest='verbose',
- help='display verbose debug info',
- default=False)
- try:
- (options, args) = parser.parse_args(command_args)
- except:
- return
-
- target = debugger.GetSelectedTarget()
- process = target.GetProcess()
-
- frame_info = {}
- for thread in process:
- last_frame = None
- print "thread %u" % (thread.id)
- for frame in thread.frames:
- if last_frame:
- frame_size = 0
- if frame.idx == 1:
- if frame.fp == last_frame.fp:
- # No frame one the first frame (might be right at the
- # entry point)
- first_frame_size = 0
- frame_size = frame.fp - frame.sp
- else:
- # First frame that has a valid size
- first_frame_size = last_frame.fp - last_frame.sp
- print "<%#7x> %s" % (first_frame_size, last_frame)
- if first_frame_size:
- name = last_frame.name
- if name not in frame_info:
- frame_info[name] = first_frame_size
- else:
- frame_info[name] += first_frame_size
- else:
- # Second or higher frame
- frame_size = frame.fp - last_frame.fp
- print "<%#7x> %s" % (frame_size, frame)
- if frame_size > 0:
- name = frame.name
- if name not in frame_info:
- frame_info[name] = frame_size
- else:
- frame_info[name] += frame_size
- last_frame = frame
- print frame_info
-
-
-lldb.debugger.HandleCommand(
- "command script add -f stacks.stack_frames stack_frames")
-print "A new command called 'stack_frames' was added, type 'stack_frames --help' for more information."
diff --git a/examples/python/step_and_print.py b/examples/python/step_and_print.py
deleted file mode 100644
index 41364ef97ba8..000000000000
--- a/examples/python/step_and_print.py
+++ /dev/null
@@ -1,24 +0,0 @@
-""" Does a step-over then prints the local variables or only the ones passed in """
-import lldb
-
-class StepAndPrint:
- def __init__(self, debugger, unused):
- return
-
- def __call__(self, debugger, command, exe_ctx, result):
- # Set the command to synchronous so the step will complete
- # before we try to run the frame variable.
- old_async = debugger.GetAsync()
- debugger.SetAsync(False)
-
- debugger.HandleCommand("thread step-over")
- print("---------- Values: -------------------\n")
- debugger.HandleCommand("frame variable %s"%(command))
-
- debugger.SetAsync(old_async)
-
- def get_short_help(self):
- return "Does a step-over then runs frame variable passing the command args to it\n"
-
-def __lldb_init_module(debugger, unused):
- debugger.HandleCommand("command script add -c step_and_print.StepAndPrint sap")
diff --git a/examples/python/symbolication.py b/examples/python/symbolication.py
deleted file mode 100755
index b655ad0d179d..000000000000
--- a/examples/python/symbolication.py
+++ /dev/null
@@ -1,727 +0,0 @@
-#!/usr/bin/python
-
-#----------------------------------------------------------------------
-# Be sure to add the python path that points to the LLDB shared library.
-#
-# To use this in the embedded python interpreter using "lldb":
-#
-# cd /path/containing/crashlog.py
-# lldb
-# (lldb) script import crashlog
-# "crashlog" command installed, type "crashlog --help" for detailed help
-# (lldb) crashlog ~/Library/Logs/DiagnosticReports/a.crash
-#
-# The benefit of running the crashlog command inside lldb in the
-# embedded python interpreter is when the command completes, there
-# will be a target with all of the files loaded at the locations
-# described in the crash log. Only the files that have stack frames
-# in the backtrace will be loaded unless the "--load-all" option
-# has been specified. This allows users to explore the program in the
-# state it was in right at crash time.
-#
-# On MacOSX csh, tcsh:
-# ( setenv PYTHONPATH /path/to/LLDB.framework/Resources/Python ; ./crashlog.py ~/Library/Logs/DiagnosticReports/a.crash )
-#
-# On MacOSX sh, bash:
-# PYTHONPATH=/path/to/LLDB.framework/Resources/Python ./crashlog.py ~/Library/Logs/DiagnosticReports/a.crash
-#----------------------------------------------------------------------
-
-import lldb
-import commands
-import optparse
-import os
-import plistlib
-import re
-import shlex
-import sys
-import time
-import uuid
-
-
-class Address:
- """Class that represents an address that will be symbolicated"""
-
- def __init__(self, target, load_addr):
- self.target = target
- self.load_addr = load_addr # The load address that this object represents
- # the resolved lldb.SBAddress (if any), named so_addr for
- # section/offset address
- self.so_addr = None
- self.sym_ctx = None # The cached symbol context for this address
- # Any original textual description of this address to be used as a
- # backup in case symbolication fails
- self.description = None
- self.symbolication = None # The cached symbolicated string that describes this address
- self.inlined = False
-
- def __str__(self):
- s = "%#16.16x" % (self.load_addr)
- if self.symbolication:
- s += " %s" % (self.symbolication)
- elif self.description:
- s += " %s" % (self.description)
- elif self.so_addr:
- s += " %s" % (self.so_addr)
- return s
-
- def resolve_addr(self):
- if self.so_addr is None:
- self.so_addr = self.target.ResolveLoadAddress(self.load_addr)
- return self.so_addr
-
- def is_inlined(self):
- return self.inlined
-
- def get_symbol_context(self):
- if self.sym_ctx is None:
- sb_addr = self.resolve_addr()
- if sb_addr:
- self.sym_ctx = self.target.ResolveSymbolContextForAddress(
- sb_addr, lldb.eSymbolContextEverything)
- else:
- self.sym_ctx = lldb.SBSymbolContext()
- return self.sym_ctx
-
- def get_instructions(self):
- sym_ctx = self.get_symbol_context()
- if sym_ctx:
- function = sym_ctx.GetFunction()
- if function:
- return function.GetInstructions(self.target)
- return sym_ctx.GetSymbol().GetInstructions(self.target)
- return None
-
- def symbolicate(self, verbose=False):
- if self.symbolication is None:
- self.symbolication = ''
- self.inlined = False
- sym_ctx = self.get_symbol_context()
- if sym_ctx:
- module = sym_ctx.GetModule()
- if module:
- # Print full source file path in verbose mode
- if verbose:
- self.symbolication += str(module.GetFileSpec()) + '`'
- else:
- self.symbolication += module.GetFileSpec().GetFilename() + '`'
- function_start_load_addr = -1
- function = sym_ctx.GetFunction()
- block = sym_ctx.GetBlock()
- line_entry = sym_ctx.GetLineEntry()
- symbol = sym_ctx.GetSymbol()
- inlined_block = block.GetContainingInlinedBlock()
- if function:
- self.symbolication += function.GetName()
-
- if inlined_block:
- self.inlined = True
- self.symbolication += ' [inlined] ' + \
- inlined_block.GetInlinedName()
- block_range_idx = inlined_block.GetRangeIndexForBlockAddress(
- self.so_addr)
- if block_range_idx < lldb.UINT32_MAX:
- block_range_start_addr = inlined_block.GetRangeStartAddress(
- block_range_idx)
- function_start_load_addr = block_range_start_addr.GetLoadAddress(
- self.target)
- if function_start_load_addr == -1:
- function_start_load_addr = function.GetStartAddress().GetLoadAddress(self.target)
- elif symbol:
- self.symbolication += symbol.GetName()
- function_start_load_addr = symbol.GetStartAddress().GetLoadAddress(self.target)
- else:
- self.symbolication = ''
- return False
-
- # Dump the offset from the current function or symbol if it
- # is non zero
- function_offset = self.load_addr - function_start_load_addr
- if function_offset > 0:
- self.symbolication += " + %u" % (function_offset)
- elif function_offset < 0:
- self.symbolication += " %i (invalid negative offset, file a bug) " % function_offset
-
- # Print out any line information if any is available
- if line_entry.GetFileSpec():
- # Print full source file path in verbose mode
- if verbose:
- self.symbolication += ' at %s' % line_entry.GetFileSpec()
- else:
- self.symbolication += ' at %s' % line_entry.GetFileSpec().GetFilename()
- self.symbolication += ':%u' % line_entry.GetLine()
- column = line_entry.GetColumn()
- if column > 0:
- self.symbolication += ':%u' % column
- return True
- return False
-
-
-class Section:
- """Class that represents an load address range"""
- sect_info_regex = re.compile('(?P<name>[^=]+)=(?P<range>.*)')
- addr_regex = re.compile('^\s*(?P<start>0x[0-9A-Fa-f]+)\s*$')
- range_regex = re.compile(
- '^\s*(?P<start>0x[0-9A-Fa-f]+)\s*(?P<op>[-+])\s*(?P<end>0x[0-9A-Fa-f]+)\s*$')
-
- def __init__(self, start_addr=None, end_addr=None, name=None):
- self.start_addr = start_addr
- self.end_addr = end_addr
- self.name = name
-
- @classmethod
- def InitWithSBTargetAndSBSection(cls, target, section):
- sect_load_addr = section.GetLoadAddress(target)
- if sect_load_addr != lldb.LLDB_INVALID_ADDRESS:
- obj = cls(
- sect_load_addr,
- sect_load_addr +
- section.size,
- section.name)
- return obj
- else:
- return None
-
- def contains(self, addr):
- return self.start_addr <= addr and addr < self.end_addr
-
- def set_from_string(self, s):
- match = self.sect_info_regex.match(s)
- if match:
- self.name = match.group('name')
- range_str = match.group('range')
- addr_match = self.addr_regex.match(range_str)
- if addr_match:
- self.start_addr = int(addr_match.group('start'), 16)
- self.end_addr = None
- return True
-
- range_match = self.range_regex.match(range_str)
- if range_match:
- self.start_addr = int(range_match.group('start'), 16)
- self.end_addr = int(range_match.group('end'), 16)
- op = range_match.group('op')
- if op == '+':
- self.end_addr += self.start_addr
- return True
- print 'error: invalid section info string "%s"' % s
- print 'Valid section info formats are:'
- print 'Format Example Description'
- print '--------------------- -----------------------------------------------'
- print '<name>=<base> __TEXT=0x123000 Section from base address only'
- print '<name>=<base>-<end> __TEXT=0x123000-0x124000 Section from base address and end address'
- print '<name>=<base>+<size> __TEXT=0x123000+0x1000 Section from base address and size'
- return False
-
- def __str__(self):
- if self.name:
- if self.end_addr is not None:
- if self.start_addr is not None:
- return "%s=[0x%16.16x - 0x%16.16x)" % (
- self.name, self.start_addr, self.end_addr)
- else:
- if self.start_addr is not None:
- return "%s=0x%16.16x" % (self.name, self.start_addr)
- return self.name
- return "<invalid>"
-
-
-class Image:
- """A class that represents an executable image and any associated data"""
-
- def __init__(self, path, uuid=None):
- self.path = path
- self.resolved_path = None
- self.resolved = False
- self.unavailable = False
- self.uuid = uuid
- self.section_infos = list()
- self.identifier = None
- self.version = None
- self.arch = None
- self.module = None
- self.symfile = None
- self.slide = None
-
- @classmethod
- def InitWithSBTargetAndSBModule(cls, target, module):
- '''Initialize this Image object with a module from a target.'''
- obj = cls(module.file.fullpath, module.uuid)
- obj.resolved_path = module.platform_file.fullpath
- obj.resolved = True
- obj.arch = module.triple
- for section in module.sections:
- symb_section = Section.InitWithSBTargetAndSBSection(
- target, section)
- if symb_section:
- obj.section_infos.append(symb_section)
- obj.arch = module.triple
- obj.module = module
- obj.symfile = None
- obj.slide = None
- return obj
-
- def dump(self, prefix):
- print "%s%s" % (prefix, self)
-
- def debug_dump(self):
- print 'path = "%s"' % (self.path)
- print 'resolved_path = "%s"' % (self.resolved_path)
- print 'resolved = %i' % (self.resolved)
- print 'unavailable = %i' % (self.unavailable)
- print 'uuid = %s' % (self.uuid)
- print 'section_infos = %s' % (self.section_infos)
- print 'identifier = "%s"' % (self.identifier)
- print 'version = %s' % (self.version)
- print 'arch = %s' % (self.arch)
- print 'module = %s' % (self.module)
- print 'symfile = "%s"' % (self.symfile)
- print 'slide = %i (0x%x)' % (self.slide, self.slide)
-
- def __str__(self):
- s = ''
- if self.uuid:
- s += "%s " % (self.get_uuid())
- if self.arch:
- s += "%s " % (self.arch)
- if self.version:
- s += "%s " % (self.version)
- resolved_path = self.get_resolved_path()
- if resolved_path:
- s += "%s " % (resolved_path)
- for section_info in self.section_infos:
- s += ", %s" % (section_info)
- if self.slide is not None:
- s += ', slide = 0x%16.16x' % self.slide
- return s
-
- def add_section(self, section):
- # print "added '%s' to '%s'" % (section, self.path)
- self.section_infos.append(section)
-
- def get_section_containing_load_addr(self, load_addr):
- for section_info in self.section_infos:
- if section_info.contains(load_addr):
- return section_info
- return None
-
- def get_resolved_path(self):
- if self.resolved_path:
- return self.resolved_path
- elif self.path:
- return self.path
- return None
-
- def get_resolved_path_basename(self):
- path = self.get_resolved_path()
- if path:
- return os.path.basename(path)
- return None
-
- def symfile_basename(self):
- if self.symfile:
- return os.path.basename(self.symfile)
- return None
-
- def has_section_load_info(self):
- return self.section_infos or self.slide is not None
-
- def load_module(self, target):
- if self.unavailable:
- return None # We already warned that we couldn't find this module, so don't return an error string
- # Load this module into "target" using the section infos to
- # set the section load addresses
- if self.has_section_load_info():
- if target:
- if self.module:
- if self.section_infos:
- num_sections_loaded = 0
- for section_info in self.section_infos:
- if section_info.name:
- section = self.module.FindSection(
- section_info.name)
- if section:
- error = target.SetSectionLoadAddress(
- section, section_info.start_addr)
- if error.Success():
- num_sections_loaded += 1
- else:
- return 'error: %s' % error.GetCString()
- else:
- return 'error: unable to find the section named "%s"' % section_info.name
- else:
- return 'error: unable to find "%s" section in "%s"' % (
- range.name, self.get_resolved_path())
- if num_sections_loaded == 0:
- return 'error: no sections were successfully loaded'
- else:
- err = target.SetModuleLoadAddress(
- self.module, self.slide)
- if err.Fail():
- return err.GetCString()
- return None
- else:
- return 'error: invalid module'
- else:
- return 'error: invalid target'
- else:
- return 'error: no section infos'
-
- def add_module(self, target):
- '''Add the Image described in this object to "target" and load the sections if "load" is True.'''
- if target:
- # Try and find using UUID only first so that paths need not match
- # up
- uuid_str = self.get_normalized_uuid_string()
- if uuid_str:
- self.module = target.AddModule(None, None, uuid_str)
- if not self.module:
- self.locate_module_and_debug_symbols()
- if self.unavailable:
- return None
- resolved_path = self.get_resolved_path()
- self.module = target.AddModule(
- resolved_path, self.arch, uuid_str, self.symfile)
- if not self.module:
- return 'error: unable to get module for (%s) "%s"' % (
- self.arch, self.get_resolved_path())
- if self.has_section_load_info():
- return self.load_module(target)
- else:
- return None # No sections, the module was added to the target, so success
- else:
- return 'error: invalid target'
-
- def locate_module_and_debug_symbols(self):
- # By default, just use the paths that were supplied in:
- # self.path
- # self.resolved_path
- # self.module
- # self.symfile
- # Subclasses can inherit from this class and override this function
- self.resolved = True
- return True
-
- def get_uuid(self):
- if not self.uuid and self.module:
- self.uuid = uuid.UUID(self.module.GetUUIDString())
- return self.uuid
-
- def get_normalized_uuid_string(self):
- if self.uuid:
- return str(self.uuid).upper()
- return None
-
- def create_target(self):
- '''Create a target using the information in this Image object.'''
- if self.unavailable:
- return None
-
- if self.locate_module_and_debug_symbols():
- resolved_path = self.get_resolved_path()
- path_spec = lldb.SBFileSpec(resolved_path)
- #result.PutCString ('plist[%s] = %s' % (uuid, self.plist))
- error = lldb.SBError()
- target = lldb.debugger.CreateTarget(
- resolved_path, self.arch, None, False, error)
- if target:
- self.module = target.FindModule(path_spec)
- if self.has_section_load_info():
- err = self.load_module(target)
- if err:
- print 'ERROR: ', err
- return target
- else:
- print 'error: unable to create a valid target for (%s) "%s"' % (self.arch, self.path)
- else:
- print 'error: unable to locate main executable (%s) "%s"' % (self.arch, self.path)
- return None
-
-
-class Symbolicator:
-
- def __init__(self):
- """A class the represents the information needed to symbolicate addresses in a program"""
- self.target = None
- self.images = list() # a list of images to be used when symbolicating
- self.addr_mask = 0xffffffffffffffff
-
- @classmethod
- def InitWithSBTarget(cls, target):
- obj = cls()
- obj.target = target
- obj.images = list()
- triple = target.triple
- if triple:
- arch = triple.split('-')[0]
- if "arm" in arch:
- obj.addr_mask = 0xfffffffffffffffe
-
- for module in target.modules:
- image = Image.InitWithSBTargetAndSBModule(target, module)
- obj.images.append(image)
- return obj
-
- def __str__(self):
- s = "Symbolicator:\n"
- if self.target:
- s += "Target = '%s'\n" % (self.target)
- s += "Target modules:\n"
- for m in self.target.modules:
- s += str(m) + "\n"
- s += "Images:\n"
- for image in self.images:
- s += ' %s\n' % (image)
- return s
-
- def find_images_with_identifier(self, identifier):
- images = list()
- for image in self.images:
- if image.identifier == identifier:
- images.append(image)
- if len(images) == 0:
- regex_text = '^.*\.%s$' % (re.escape(identifier))
- regex = re.compile(regex_text)
- for image in self.images:
- if regex.match(image.identifier):
- images.append(image)
- return images
-
- def find_image_containing_load_addr(self, load_addr):
- for image in self.images:
- if image.get_section_containing_load_addr(load_addr):
- return image
- return None
-
- def create_target(self):
- if self.target:
- return self.target
-
- if self.images:
- for image in self.images:
- self.target = image.create_target()
- if self.target:
- if self.target.GetAddressByteSize() == 4:
- triple = self.target.triple
- if triple:
- arch = triple.split('-')[0]
- if "arm" in arch:
- self.addr_mask = 0xfffffffffffffffe
- return self.target
- return None
-
- def symbolicate(self, load_addr, verbose=False):
- if not self.target:
- self.create_target()
- if self.target:
- live_process = False
- process = self.target.process
- if process:
- state = process.state
- if state > lldb.eStateUnloaded and state < lldb.eStateDetached:
- live_process = True
- # If we don't have a live process, we can attempt to find the image
- # that a load address belongs to and lazily load its module in the
- # target, but we shouldn't do any of this if we have a live process
- if not live_process:
- image = self.find_image_containing_load_addr(load_addr)
- if image:
- image.add_module(self.target)
- symbolicated_address = Address(self.target, load_addr)
- if symbolicated_address.symbolicate(verbose):
- if symbolicated_address.so_addr:
- symbolicated_addresses = list()
- symbolicated_addresses.append(symbolicated_address)
- # See if we were able to reconstruct anything?
- while True:
- inlined_parent_so_addr = lldb.SBAddress()
- inlined_parent_sym_ctx = symbolicated_address.sym_ctx.GetParentOfInlinedScope(
- symbolicated_address.so_addr, inlined_parent_so_addr)
- if not inlined_parent_sym_ctx:
- break
- if not inlined_parent_so_addr:
- break
-
- symbolicated_address = Address(
- self.target, inlined_parent_so_addr.GetLoadAddress(
- self.target))
- symbolicated_address.sym_ctx = inlined_parent_sym_ctx
- symbolicated_address.so_addr = inlined_parent_so_addr
- symbolicated_address.symbolicate(verbose)
-
- # push the new frame onto the new frame stack
- symbolicated_addresses.append(symbolicated_address)
-
- if symbolicated_addresses:
- return symbolicated_addresses
- else:
- print 'error: no target in Symbolicator'
- return None
-
-
-def disassemble_instructions(
- target,
- instructions,
- pc,
- insts_before_pc,
- insts_after_pc,
- non_zeroeth_frame):
- lines = list()
- pc_index = -1
- comment_column = 50
- for inst_idx, inst in enumerate(instructions):
- inst_pc = inst.GetAddress().GetLoadAddress(target)
- if pc == inst_pc:
- pc_index = inst_idx
- mnemonic = inst.GetMnemonic(target)
- operands = inst.GetOperands(target)
- comment = inst.GetComment(target)
- #data = inst.GetData (target)
- lines.append("%#16.16x: %8s %s" % (inst_pc, mnemonic, operands))
- if comment:
- line_len = len(lines[-1])
- if line_len < comment_column:
- lines[-1] += ' ' * (comment_column - line_len)
- lines[-1] += "; %s" % comment
-
- if pc_index >= 0:
- # If we are disassembling the non-zeroeth frame, we need to backup the
- # PC by 1
- if non_zeroeth_frame and pc_index > 0:
- pc_index = pc_index - 1
- if insts_before_pc == -1:
- start_idx = 0
- else:
- start_idx = pc_index - insts_before_pc
- if start_idx < 0:
- start_idx = 0
- if insts_before_pc == -1:
- end_idx = inst_idx
- else:
- end_idx = pc_index + insts_after_pc
- if end_idx > inst_idx:
- end_idx = inst_idx
- for i in range(start_idx, end_idx + 1):
- if i == pc_index:
- print ' -> ', lines[i]
- else:
- print ' ', lines[i]
-
-
-def print_module_section_data(section):
- print section
- section_data = section.GetSectionData()
- if section_data:
- ostream = lldb.SBStream()
- section_data.GetDescription(ostream, section.GetFileAddress())
- print ostream.GetData()
-
-
-def print_module_section(section, depth):
- print section
- if depth > 0:
- num_sub_sections = section.GetNumSubSections()
- for sect_idx in range(num_sub_sections):
- print_module_section(
- section.GetSubSectionAtIndex(sect_idx), depth - 1)
-
-
-def print_module_sections(module, depth):
- for sect in module.section_iter():
- print_module_section(sect, depth)
-
-
-def print_module_symbols(module):
- for sym in module:
- print sym
-
-
-def Symbolicate(command_args):
-
- usage = "usage: %prog [options] <addr1> [addr2 ...]"
- description = '''Symbolicate one or more addresses using LLDB's python scripting API..'''
- parser = optparse.OptionParser(
- description=description,
- prog='crashlog.py',
- usage=usage)
- parser.add_option(
- '-v',
- '--verbose',
- action='store_true',
- dest='verbose',
- help='display verbose debug info',
- default=False)
- parser.add_option(
- '-p',
- '--platform',
- type='string',
- metavar='platform',
- dest='platform',
- help='Specify the platform to use when creating the debug target. Valid values include "localhost", "darwin-kernel", "ios-simulator", "remote-freebsd", "remote-macosx", "remote-ios", "remote-linux".')
- parser.add_option(
- '-f',
- '--file',
- type='string',
- metavar='file',
- dest='file',
- help='Specify a file to use when symbolicating')
- parser.add_option(
- '-a',
- '--arch',
- type='string',
- metavar='arch',
- dest='arch',
- help='Specify a architecture to use when symbolicating')
- parser.add_option(
- '-s',
- '--slide',
- type='int',
- metavar='slide',
- dest='slide',
- help='Specify the slide to use on the file specified with the --file option',
- default=None)
- parser.add_option(
- '--section',
- type='string',
- action='append',
- dest='section_strings',
- help='specify <sect-name>=<start-addr> or <sect-name>=<start-addr>-<end-addr>')
- try:
- (options, args) = parser.parse_args(command_args)
- except:
- return
- symbolicator = Symbolicator()
- images = list()
- if options.file:
- image = Image(options.file)
- image.arch = options.arch
- # Add any sections that were specified with one or more --section
- # options
- if options.section_strings:
- for section_str in options.section_strings:
- section = Section()
- if section.set_from_string(section_str):
- image.add_section(section)
- else:
- sys.exit(1)
- if options.slide is not None:
- image.slide = options.slide
- symbolicator.images.append(image)
-
- target = symbolicator.create_target()
- if options.verbose:
- print symbolicator
- if target:
- for addr_str in args:
- addr = int(addr_str, 0)
- symbolicated_addrs = symbolicator.symbolicate(
- addr, options.verbose)
- for symbolicated_addr in symbolicated_addrs:
- print symbolicated_addr
- print
- else:
- print 'error: no target for %s' % (symbolicator)
-
-if __name__ == '__main__':
- # Create a new debugger instance
- lldb.debugger = lldb.SBDebugger.Create()
- Symbolicate(sys.argv[1:])
diff --git a/examples/python/types.py b/examples/python/types.py
deleted file mode 100755
index a8aac24f4a07..000000000000
--- a/examples/python/types.py
+++ /dev/null
@@ -1,356 +0,0 @@
-#!/usr/bin/python
-
-#----------------------------------------------------------------------
-# Be sure to add the python path that points to the LLDB shared library.
-#
-# # To use this in the embedded python interpreter using "lldb" just
-# import it with the full path using the "command script import"
-# command
-# (lldb) command script import /path/to/cmdtemplate.py
-#----------------------------------------------------------------------
-
-import commands
-import platform
-import os
-import re
-import signal
-import sys
-
-try:
- # Just try for LLDB in case PYTHONPATH is already correctly setup
- import lldb
-except ImportError:
- lldb_python_dirs = list()
- # lldb is not in the PYTHONPATH, try some defaults for the current platform
- platform_system = platform.system()
- if platform_system == 'Darwin':
- # On Darwin, try the currently selected Xcode directory
- xcode_dir = commands.getoutput("xcode-select --print-path")
- if xcode_dir:
- lldb_python_dirs.append(
- os.path.realpath(
- xcode_dir +
- '/../SharedFrameworks/LLDB.framework/Resources/Python'))
- lldb_python_dirs.append(
- xcode_dir + '/Library/PrivateFrameworks/LLDB.framework/Resources/Python')
- lldb_python_dirs.append(
- '/System/Library/PrivateFrameworks/LLDB.framework/Resources/Python')
- success = False
- for lldb_python_dir in lldb_python_dirs:
- if os.path.exists(lldb_python_dir):
- if not (sys.path.__contains__(lldb_python_dir)):
- sys.path.append(lldb_python_dir)
- try:
- import lldb
- except ImportError:
- pass
- else:
- print 'imported lldb from: "%s"' % (lldb_python_dir)
- success = True
- break
- if not success:
- print "error: couldn't locate the 'lldb' module, please set PYTHONPATH correctly"
- sys.exit(1)
-
-import commands
-import optparse
-import shlex
-import time
-
-
-def regex_option_callback(option, opt_str, value, parser):
- if opt_str == "--std":
- value = '^std::'
- regex = re.compile(value)
- parser.values.skip_type_regexes.append(regex)
-
-
-def create_types_options(for_lldb_command):
- if for_lldb_command:
- usage = "usage: %prog [options]"
- description = '''This command will help check for padding in between
-base classes and members in structs and classes. It will summarize the types
-and how much padding was found. If no types are specified with the --types TYPENAME
-option, all structure and class types will be verified. If no modules are
-specified with the --module option, only the target's main executable will be
-searched.
-'''
- else:
- usage = "usage: %prog [options] EXEPATH [EXEPATH ...]"
- description = '''This command will help check for padding in between
-base classes and members in structures and classes. It will summarize the types
-and how much padding was found. One or more paths to executable files must be
-specified and targets will be created with these modules. If no types are
-specified with the --types TYPENAME option, all structure and class types will
-be verified in all specified modules.
-'''
- parser = optparse.OptionParser(
- description=description,
- prog='framestats',
- usage=usage)
- if not for_lldb_command:
- parser.add_option(
- '-a',
- '--arch',
- type='string',
- dest='arch',
- help='The architecture to use when creating the debug target.',
- default=None)
- parser.add_option(
- '-p',
- '--platform',
- type='string',
- metavar='platform',
- dest='platform',
- help='Specify the platform to use when creating the debug target. Valid values include "localhost", "darwin-kernel", "ios-simulator", "remote-freebsd", "remote-macosx", "remote-ios", "remote-linux".')
- parser.add_option(
- '-m',
- '--module',
- action='append',
- type='string',
- metavar='MODULE',
- dest='modules',
- help='Specify one or more modules which will be used to verify the types.',
- default=[])
- parser.add_option(
- '-d',
- '--debug',
- action='store_true',
- dest='debug',
- help='Pause 10 seconds to wait for a debugger to attach.',
- default=False)
- parser.add_option(
- '-t',
- '--type',
- action='append',
- type='string',
- metavar='TYPENAME',
- dest='typenames',
- help='Specify one or more type names which should be verified. If no type names are specified, all class and struct types will be verified.',
- default=[])
- parser.add_option(
- '-v',
- '--verbose',
- action='store_true',
- dest='verbose',
- help='Enable verbose logging and information.',
- default=False)
- parser.add_option(
- '-s',
- '--skip-type-regex',
- action="callback",
- callback=regex_option_callback,
- type='string',
- metavar='REGEX',
- dest='skip_type_regexes',
- help='Regular expressions that, if they match the current member typename, will cause the type to no be recursively displayed.',
- default=[])
- parser.add_option(
- '--std',
- action="callback",
- callback=regex_option_callback,
- metavar='REGEX',
- dest='skip_type_regexes',
- help="Don't' recurse into types in the std namespace.",
- default=[])
- return parser
-
-
-def verify_type(target, options, type):
- print type
- typename = type.GetName()
- # print 'type: %s' % (typename)
- (end_offset, padding) = verify_type_recursive(
- target, options, type, None, 0, 0, 0)
- byte_size = type.GetByteSize()
- # if end_offset < byte_size:
- # last_member_padding = byte_size - end_offset
- # print '%+4u <%u> padding' % (end_offset, last_member_padding)
- # padding += last_member_padding
- print 'Total byte size: %u' % (byte_size)
- print 'Total pad bytes: %u' % (padding)
- if padding > 0:
- print 'Padding percentage: %2.2f %%' % ((float(padding) / float(byte_size)) * 100.0)
- print
-
-
-def verify_type_recursive(
- target,
- options,
- type,
- member_name,
- depth,
- base_offset,
- padding):
- prev_end_offset = base_offset
- typename = type.GetName()
- byte_size = type.GetByteSize()
- if member_name and member_name != typename:
- print '%+4u <%3u> %s%s %s;' % (base_offset, byte_size, ' ' * depth, typename, member_name)
- else:
- print '%+4u {%3u} %s%s' % (base_offset, byte_size, ' ' * depth, typename)
-
- for type_regex in options.skip_type_regexes:
- match = type_regex.match(typename)
- if match:
- return (base_offset + byte_size, padding)
-
- members = type.members
- if members:
- for member_idx, member in enumerate(members):
- member_type = member.GetType()
- member_canonical_type = member_type.GetCanonicalType()
- member_type_class = member_canonical_type.GetTypeClass()
- member_name = member.GetName()
- member_offset = member.GetOffsetInBytes()
- member_total_offset = member_offset + base_offset
- member_byte_size = member_type.GetByteSize()
- member_is_class_or_struct = False
- if member_type_class == lldb.eTypeClassStruct or member_type_class == lldb.eTypeClassClass:
- member_is_class_or_struct = True
- if member_idx == 0 and member_offset == target.GetAddressByteSize(
- ) and type.IsPolymorphicClass():
- ptr_size = target.GetAddressByteSize()
- print '%+4u <%3u> %s__vtbl_ptr_type * _vptr;' % (prev_end_offset, ptr_size, ' ' * (depth + 1))
- prev_end_offset = ptr_size
- else:
- if prev_end_offset < member_total_offset:
- member_padding = member_total_offset - prev_end_offset
- padding = padding + member_padding
- print '%+4u <%3u> %s<PADDING>' % (prev_end_offset, member_padding, ' ' * (depth + 1))
-
- if member_is_class_or_struct:
- (prev_end_offset,
- padding) = verify_type_recursive(target,
- options,
- member_canonical_type,
- member_name,
- depth + 1,
- member_total_offset,
- padding)
- else:
- prev_end_offset = member_total_offset + member_byte_size
- member_typename = member_type.GetName()
- if member.IsBitfield():
- print '%+4u <%3u> %s%s:%u %s;' % (member_total_offset, member_byte_size, ' ' * (depth + 1), member_typename, member.GetBitfieldSizeInBits(), member_name)
- else:
- print '%+4u <%3u> %s%s %s;' % (member_total_offset, member_byte_size, ' ' * (depth + 1), member_typename, member_name)
-
- if prev_end_offset < byte_size:
- last_member_padding = byte_size - prev_end_offset
- print '%+4u <%3u> %s<PADDING>' % (prev_end_offset, last_member_padding, ' ' * (depth + 1))
- padding += last_member_padding
- else:
- if type.IsPolymorphicClass():
- ptr_size = target.GetAddressByteSize()
- print '%+4u <%3u> %s__vtbl_ptr_type * _vptr;' % (prev_end_offset, ptr_size, ' ' * (depth + 1))
- prev_end_offset = ptr_size
- prev_end_offset = base_offset + byte_size
-
- return (prev_end_offset, padding)
-
-
-def check_padding_command(debugger, command, result, dict):
- # Use the Shell Lexer to properly parse up command options just like a
- # shell would
- command_args = shlex.split(command)
- parser = create_types_options(True)
- try:
- (options, args) = parser.parse_args(command_args)
- except:
- # if you don't handle exceptions, passing an incorrect argument to the OptionParser will cause LLDB to exit
- # (courtesy of OptParse dealing with argument errors by throwing SystemExit)
- result.SetStatus(lldb.eReturnStatusFailed)
- # returning a string is the same as returning an error whose
- # description is the string
- return "option parsing failed"
- verify_types(debugger.GetSelectedTarget(), options)
-
-
-@lldb.command("parse_all_struct_class_types")
-def parse_all_struct_class_types(debugger, command, result, dict):
- command_args = shlex.split(command)
- for f in command_args:
- error = lldb.SBError()
- target = debugger.CreateTarget(f, None, None, False, error)
- module = target.GetModuleAtIndex(0)
- print "Parsing all types in '%s'" % (module)
- types = module.GetTypes(lldb.eTypeClassClass | lldb.eTypeClassStruct)
- for t in types:
- print t
- print ""
-
-
-def verify_types(target, options):
-
- if not target:
- print 'error: invalid target'
- return
-
- modules = list()
- if len(options.modules) == 0:
- # Append just the main executable if nothing was specified
- module = target.modules[0]
- if module:
- modules.append(module)
- else:
- for module_name in options.modules:
- module = lldb.target.module[module_name]
- if module:
- modules.append(module)
-
- if modules:
- for module in modules:
- print 'module: %s' % (module.file)
- if options.typenames:
- for typename in options.typenames:
- types = module.FindTypes(typename)
- if types.GetSize():
- print 'Found %u types matching "%s" in "%s"' % (len(types), typename, module.file)
- for type in types:
- verify_type(target, options, type)
- else:
- print 'error: no type matches "%s" in "%s"' % (typename, module.file)
- else:
- types = module.GetTypes(
- lldb.eTypeClassClass | lldb.eTypeClassStruct)
- print 'Found %u types in "%s"' % (len(types), module.file)
- for type in types:
- verify_type(target, options, type)
- else:
- print 'error: no modules'
-
-if __name__ == '__main__':
- debugger = lldb.SBDebugger.Create()
- parser = create_types_options(False)
-
- # try:
- (options, args) = parser.parse_args(sys.argv[1:])
- # except:
- # print "error: option parsing failed"
- # sys.exit(1)
-
- if options.debug:
- print "Waiting for debugger to attach to process %d" % os.getpid()
- os.kill(os.getpid(), signal.SIGSTOP)
-
- for path in args:
- # in a command - the lldb.* convenience variables are not to be used
- # and their values (if any) are undefined
- # this is the best practice to access those objects from within a
- # command
- error = lldb.SBError()
- target = debugger.CreateTarget(path,
- options.arch,
- options.platform,
- True,
- error)
- if error.Fail():
- print error.GetCString()
- continue
- verify_types(target, options)
-
-elif getattr(lldb, 'debugger', None):
- lldb.debugger.HandleCommand(
- 'command script add -f types.check_padding_command check_padding')
- print '"check_padding" command installed, use the "--help" option for detailed help'
diff --git a/examples/python/x86_64_linux_target_definition.py b/examples/python/x86_64_linux_target_definition.py
deleted file mode 100644
index 9417b21abd66..000000000000
--- a/examples/python/x86_64_linux_target_definition.py
+++ /dev/null
@@ -1,775 +0,0 @@
-#!/usr/bin/python
-#===-- x86_64_linux_target_definition.py -----------------------------*- C++ -*-===//
-#
-# The LLVM Compiler Infrastructure
-#
-# This file is distributed under the University of Illinois Open Source
-# License. See LICENSE.TXT for details.
-#
-#===----------------------------------------------------------------------===//
-
-#----------------------------------------------------------------------
-# DESCRIPTION
-#
-# This file can be used with the following setting:
-# plugin.process.gdb-remote.target-definition-file
-# This setting should be used when you are trying to connect to a
-# remote GDB server that doesn't support any of the register discovery
-# packets that LLDB normally uses.
-#
-# Why is this necessary? LLDB doesn't require a new build of LLDB that
-# targets each new architecture you will debug with. Instead, all
-# architectures are supported and LLDB relies on extra GDB server
-# packets to discover the target we are connecting to so that is can
-# show the right registers for each target. This allows the GDB server
-# to change and add new registers without requiring a new LLDB build
-# just so we can see new registers.
-#
-# This file implements the x86_64 registers for the darwin version of
-# GDB and allows you to connect to servers that use this register set.
-#
-# USAGE
-#
-# (lldb) settings set plugin.process.gdb-remote.target-definition-file /path/to/x86_64_linux_target_definition.py
-# (lldb) gdb-remote other.baz.com:1234
-#
-# The target definition file will get used if and only if the
-# qRegisterInfo packets are not supported when connecting to a remote
-# GDB server.
-#----------------------------------------------------------------------
-from lldb import *
-
-# Compiler and DWARF register numbers
-name_to_gcc_dwarf_regnum = {
- 'rax': 0,
- 'rdx': 1,
- 'rcx': 2,
- 'rbx': 3,
- 'rsi': 4,
- 'rdi': 5,
- 'rbp': 6,
- 'rsp': 7,
- 'r8': 8,
- 'r9': 9,
- 'r10': 10,
- 'r11': 11,
- 'r12': 12,
- 'r13': 13,
- 'r14': 14,
- 'r15': 15,
- 'rip': 16,
- 'xmm0': 17,
- 'xmm1': 18,
- 'xmm2': 19,
- 'xmm3': 20,
- 'xmm4': 21,
- 'xmm5': 22,
- 'xmm6': 23,
- 'xmm7': 24,
- 'xmm8': 25,
- 'xmm9': 26,
- 'xmm10': 27,
- 'xmm11': 28,
- 'xmm12': 29,
- 'xmm13': 30,
- 'xmm14': 31,
- 'xmm15': 32,
- 'stmm0': 33,
- 'stmm1': 34,
- 'stmm2': 35,
- 'stmm3': 36,
- 'stmm4': 37,
- 'stmm5': 38,
- 'stmm6': 39,
- 'stmm7': 30,
- 'ymm0': 41,
- 'ymm1': 42,
- 'ymm2': 43,
- 'ymm3': 44,
- 'ymm4': 45,
- 'ymm5': 46,
- 'ymm6': 47,
- 'ymm7': 48,
- 'ymm8': 49,
- 'ymm9': 40,
- 'ymm10': 41,
- 'ymm11': 42,
- 'ymm12': 43,
- 'ymm13': 44,
- 'ymm14': 45,
- 'ymm15': 46
-}
-
-name_to_gdb_regnum = {
- 'rax': 0,
- 'rbx': 1,
- 'rcx': 2,
- 'rdx': 3,
- 'rsi': 4,
- 'rdi': 5,
- 'rbp': 6,
- 'rsp': 7,
- 'r8': 8,
- 'r9': 9,
- 'r10': 10,
- 'r11': 11,
- 'r12': 12,
- 'r13': 13,
- 'r14': 14,
- 'r15': 15,
- 'rip': 16,
- 'rflags': 17,
- 'cs': 18,
- 'ss': 19,
- 'ds': 20,
- 'es': 21,
- 'fs': 22,
- 'gs': 23,
- 'stmm0': 24,
- 'stmm1': 25,
- 'stmm2': 26,
- 'stmm3': 27,
- 'stmm4': 28,
- 'stmm5': 29,
- 'stmm6': 30,
- 'stmm7': 31,
- 'fctrl': 32,
- 'fstat': 33,
- 'ftag': 34,
- 'fiseg': 35,
- 'fioff': 36,
- 'foseg': 37,
- 'fooff': 38,
- 'fop': 39,
- 'xmm0': 40,
- 'xmm1': 41,
- 'xmm2': 42,
- 'xmm3': 43,
- 'xmm4': 44,
- 'xmm5': 45,
- 'xmm6': 46,
- 'xmm7': 47,
- 'xmm8': 48,
- 'xmm9': 49,
- 'xmm10': 50,
- 'xmm11': 51,
- 'xmm12': 52,
- 'xmm13': 53,
- 'xmm14': 54,
- 'xmm15': 55,
- 'mxcsr': 56,
- 'ymm0': 57,
- 'ymm1': 58,
- 'ymm2': 59,
- 'ymm3': 60,
- 'ymm4': 61,
- 'ymm5': 62,
- 'ymm6': 63,
- 'ymm7': 64,
- 'ymm8': 65,
- 'ymm9': 66,
- 'ymm10': 67,
- 'ymm11': 68,
- 'ymm12': 69,
- 'ymm13': 70,
- 'ymm14': 71,
- 'ymm15': 72
-}
-
-name_to_generic_regnum = {
- 'rip': LLDB_REGNUM_GENERIC_PC,
- 'rsp': LLDB_REGNUM_GENERIC_SP,
- 'rbp': LLDB_REGNUM_GENERIC_FP,
- 'rdi': LLDB_REGNUM_GENERIC_ARG1,
- 'rsi': LLDB_REGNUM_GENERIC_ARG2,
- 'rdx': LLDB_REGNUM_GENERIC_ARG3,
- 'rcx': LLDB_REGNUM_GENERIC_ARG4,
- 'r8': LLDB_REGNUM_GENERIC_ARG5,
- 'r9': LLDB_REGNUM_GENERIC_ARG6
-}
-
-
-def get_reg_num(reg_num_dict, reg_name):
- if reg_name in reg_num_dict:
- return reg_num_dict[reg_name]
- return LLDB_INVALID_REGNUM
-
-x86_64_register_infos = [
- {'name': 'rax',
- 'set': 0,
- 'bitsize': 64,
- 'encoding': eEncodingUint,
- 'format': eFormatAddressInfo},
- {'name': 'rbx',
- 'set': 0,
- 'bitsize': 64,
- 'encoding': eEncodingUint,
- 'format': eFormatAddressInfo},
- {'name': 'rcx', 'set': 0, 'bitsize': 64, 'encoding': eEncodingUint,
- 'format': eFormatAddressInfo, 'alt-name': 'arg4'},
- {'name': 'rdx', 'set': 0, 'bitsize': 64, 'encoding': eEncodingUint,
- 'format': eFormatAddressInfo, 'alt-name': 'arg3'},
- {'name': 'rsi', 'set': 0, 'bitsize': 64, 'encoding': eEncodingUint,
- 'format': eFormatAddressInfo, 'alt-name': 'arg2'},
- {'name': 'rdi', 'set': 0, 'bitsize': 64, 'encoding': eEncodingUint,
- 'format': eFormatAddressInfo, 'alt-name': 'arg1'},
- {'name': 'rbp', 'set': 0, 'bitsize': 64, 'encoding': eEncodingUint,
- 'format': eFormatAddressInfo, 'alt-name': 'fp'},
- {'name': 'rsp', 'set': 0, 'bitsize': 64, 'encoding': eEncodingUint,
- 'format': eFormatAddressInfo, 'alt-name': 'sp'},
- {'name': 'r8', 'set': 0, 'bitsize': 64, 'encoding': eEncodingUint,
- 'format': eFormatAddressInfo, 'alt-name': 'arg5'},
- {'name': 'r9', 'set': 0, 'bitsize': 64, 'encoding': eEncodingUint,
- 'format': eFormatAddressInfo, 'alt-name': 'arg6'},
- {'name': 'r10',
- 'set': 0,
- 'bitsize': 64,
- 'encoding': eEncodingUint,
- 'format': eFormatAddressInfo},
- {'name': 'r11',
- 'set': 0,
- 'bitsize': 64,
- 'encoding': eEncodingUint,
- 'format': eFormatAddressInfo},
- {'name': 'r12',
- 'set': 0,
- 'bitsize': 64,
- 'encoding': eEncodingUint,
- 'format': eFormatAddressInfo},
- {'name': 'r13',
- 'set': 0,
- 'bitsize': 64,
- 'encoding': eEncodingUint,
- 'format': eFormatAddressInfo},
- {'name': 'r14',
- 'set': 0,
- 'bitsize': 64,
- 'encoding': eEncodingUint,
- 'format': eFormatAddressInfo},
- {'name': 'r15',
- 'set': 0,
- 'bitsize': 64,
- 'encoding': eEncodingUint,
- 'format': eFormatAddressInfo},
- {'name': 'rip', 'set': 0, 'bitsize': 64, 'encoding': eEncodingUint,
- 'format': eFormatAddressInfo, 'alt-name': 'pc'},
- {'name': 'rflags', 'set': 0, 'bitsize': 32,
- 'encoding': eEncodingUint, 'format': eFormatHex},
- {'name': 'cs', 'set': 0, 'bitsize': 32,
- 'encoding': eEncodingUint, 'format': eFormatHex},
- {'name': 'ss', 'set': 0, 'bitsize': 32,
- 'encoding': eEncodingUint, 'format': eFormatHex},
- {'name': 'ds', 'set': 0, 'bitsize': 32,
- 'encoding': eEncodingUint, 'format': eFormatHex},
- {'name': 'es', 'set': 0, 'bitsize': 32,
- 'encoding': eEncodingUint, 'format': eFormatHex},
- {'name': 'fs', 'set': 0, 'bitsize': 32,
- 'encoding': eEncodingUint, 'format': eFormatHex},
- {'name': 'gs', 'set': 0, 'bitsize': 32,
- 'encoding': eEncodingUint, 'format': eFormatHex},
- {'name': 'stmm0',
- 'set': 1,
- 'bitsize': 80,
- 'encoding': eEncodingVector,
- 'format': eFormatVectorOfUInt8},
- {'name': 'stmm1',
- 'set': 1,
- 'bitsize': 80,
- 'encoding': eEncodingVector,
- 'format': eFormatVectorOfUInt8},
- {'name': 'stmm2',
- 'set': 1,
- 'bitsize': 80,
- 'encoding': eEncodingVector,
- 'format': eFormatVectorOfUInt8},
- {'name': 'stmm3',
- 'set': 1,
- 'bitsize': 80,
- 'encoding': eEncodingVector,
- 'format': eFormatVectorOfUInt8},
- {'name': 'stmm4',
- 'set': 1,
- 'bitsize': 80,
- 'encoding': eEncodingVector,
- 'format': eFormatVectorOfUInt8},
- {'name': 'stmm5',
- 'set': 1,
- 'bitsize': 80,
- 'encoding': eEncodingVector,
- 'format': eFormatVectorOfUInt8},
- {'name': 'stmm6',
- 'set': 1,
- 'bitsize': 80,
- 'encoding': eEncodingVector,
- 'format': eFormatVectorOfUInt8},
- {'name': 'stmm7',
- 'set': 1,
- 'bitsize': 80,
- 'encoding': eEncodingVector,
- 'format': eFormatVectorOfUInt8},
- {'name': 'fctrl', 'set': 1, 'bitsize': 32,
- 'encoding': eEncodingUint, 'format': eFormatHex},
- {'name': 'fstat', 'set': 1, 'bitsize': 32,
- 'encoding': eEncodingUint, 'format': eFormatHex},
- {'name': 'ftag', 'set': 1, 'bitsize': 32,
- 'encoding': eEncodingUint, 'format': eFormatHex},
- {'name': 'fiseg', 'set': 1, 'bitsize': 32,
- 'encoding': eEncodingUint, 'format': eFormatHex},
- {'name': 'fioff', 'set': 1, 'bitsize': 32,
- 'encoding': eEncodingUint, 'format': eFormatHex},
- {'name': 'foseg', 'set': 1, 'bitsize': 32,
- 'encoding': eEncodingUint, 'format': eFormatHex},
- {'name': 'fooff', 'set': 1, 'bitsize': 32,
- 'encoding': eEncodingUint, 'format': eFormatHex},
- {'name': 'fop', 'set': 1, 'bitsize': 32,
- 'encoding': eEncodingUint, 'format': eFormatHex},
- {'name': 'xmm0',
- 'set': 1,
- 'bitsize': 128,
- 'encoding': eEncodingVector,
- 'format': eFormatVectorOfUInt8},
- {'name': 'xmm1',
- 'set': 1,
- 'bitsize': 128,
- 'encoding': eEncodingVector,
- 'format': eFormatVectorOfUInt8},
- {'name': 'xmm2',
- 'set': 1,
- 'bitsize': 128,
- 'encoding': eEncodingVector,
- 'format': eFormatVectorOfUInt8},
- {'name': 'xmm3',
- 'set': 1,
- 'bitsize': 128,
- 'encoding': eEncodingVector,
- 'format': eFormatVectorOfUInt8},
- {'name': 'xmm4',
- 'set': 1,
- 'bitsize': 128,
- 'encoding': eEncodingVector,
- 'format': eFormatVectorOfUInt8},
- {'name': 'xmm5',
- 'set': 1,
- 'bitsize': 128,
- 'encoding': eEncodingVector,
- 'format': eFormatVectorOfUInt8},
- {'name': 'xmm6',
- 'set': 1,
- 'bitsize': 128,
- 'encoding': eEncodingVector,
- 'format': eFormatVectorOfUInt8},
- {'name': 'xmm7',
- 'set': 1,
- 'bitsize': 128,
- 'encoding': eEncodingVector,
- 'format': eFormatVectorOfUInt8},
- {'name': 'xmm8',
- 'set': 1,
- 'bitsize': 128,
- 'encoding': eEncodingVector,
- 'format': eFormatVectorOfUInt8},
- {'name': 'xmm9',
- 'set': 1,
- 'bitsize': 128,
- 'encoding': eEncodingVector,
- 'format': eFormatVectorOfUInt8},
- {'name': 'xmm10',
- 'set': 1,
- 'bitsize': 128,
- 'encoding': eEncodingVector,
- 'format': eFormatVectorOfUInt8},
- {'name': 'xmm11',
- 'set': 1,
- 'bitsize': 128,
- 'encoding': eEncodingVector,
- 'format': eFormatVectorOfUInt8},
- {'name': 'xmm12',
- 'set': 1,
- 'bitsize': 128,
- 'encoding': eEncodingVector,
- 'format': eFormatVectorOfUInt8},
- {'name': 'xmm13',
- 'set': 1,
- 'bitsize': 128,
- 'encoding': eEncodingVector,
- 'format': eFormatVectorOfUInt8},
- {'name': 'xmm14',
- 'set': 1,
- 'bitsize': 128,
- 'encoding': eEncodingVector,
- 'format': eFormatVectorOfUInt8},
- {'name': 'xmm15',
- 'set': 1,
- 'bitsize': 128,
- 'encoding': eEncodingVector,
- 'format': eFormatVectorOfUInt8},
- {'name': 'mxcsr', 'set': 1, 'bitsize': 32,
- 'encoding': eEncodingUint, 'format': eFormatHex},
- {'name': 'orig_rax', 'set': 1, 'bitsize': 64,
- 'encoding': eEncodingUint, 'format': eFormatHex},
- # Registers that are contained in or composed of one of more other
- # registers
- {'name': 'eax',
- 'set': 0,
- 'bitsize': 32,
- 'encoding': eEncodingUint,
- 'format': eFormatHex,
- 'slice': 'rax[31:0]'},
- {'name': 'ebx',
- 'set': 0,
- 'bitsize': 32,
- 'encoding': eEncodingUint,
- 'format': eFormatHex,
- 'slice': 'rbx[31:0]'},
- {'name': 'ecx',
- 'set': 0,
- 'bitsize': 32,
- 'encoding': eEncodingUint,
- 'format': eFormatHex,
- 'slice': 'rcx[31:0]'},
- {'name': 'edx',
- 'set': 0,
- 'bitsize': 32,
- 'encoding': eEncodingUint,
- 'format': eFormatHex,
- 'slice': 'rdx[31:0]'},
- {'name': 'edi',
- 'set': 0,
- 'bitsize': 32,
- 'encoding': eEncodingUint,
- 'format': eFormatHex,
- 'slice': 'rdi[31:0]'},
- {'name': 'esi',
- 'set': 0,
- 'bitsize': 32,
- 'encoding': eEncodingUint,
- 'format': eFormatHex,
- 'slice': 'rsi[31:0]'},
- {'name': 'ebp',
- 'set': 0,
- 'bitsize': 32,
- 'encoding': eEncodingUint,
- 'format': eFormatHex,
- 'slice': 'rbp[31:0]'},
- {'name': 'esp',
- 'set': 0,
- 'bitsize': 32,
- 'encoding': eEncodingUint,
- 'format': eFormatHex,
- 'slice': 'rsp[31:0]'},
- {'name': 'r8d',
- 'set': 0,
- 'bitsize': 32,
- 'encoding': eEncodingUint,
- 'format': eFormatHex,
- 'slice': 'r8[31:0]'},
- {'name': 'r9d',
- 'set': 0,
- 'bitsize': 32,
- 'encoding': eEncodingUint,
- 'format': eFormatHex,
- 'slice': 'r9[31:0]'},
- {'name': 'r10d',
- 'set': 0,
- 'bitsize': 32,
- 'encoding': eEncodingUint,
- 'format': eFormatHex,
- 'slice': 'r10[31:0]'},
- {'name': 'r11d',
- 'set': 0,
- 'bitsize': 32,
- 'encoding': eEncodingUint,
- 'format': eFormatHex,
- 'slice': 'r11[31:0]'},
- {'name': 'r12d',
- 'set': 0,
- 'bitsize': 32,
- 'encoding': eEncodingUint,
- 'format': eFormatHex,
- 'slice': 'r12[31:0]'},
- {'name': 'r13d',
- 'set': 0,
- 'bitsize': 32,
- 'encoding': eEncodingUint,
- 'format': eFormatHex,
- 'slice': 'r13[31:0]'},
- {'name': 'r14d',
- 'set': 0,
- 'bitsize': 32,
- 'encoding': eEncodingUint,
- 'format': eFormatHex,
- 'slice': 'r14[31:0]'},
- {'name': 'r15d',
- 'set': 0,
- 'bitsize': 32,
- 'encoding': eEncodingUint,
- 'format': eFormatHex,
- 'slice': 'r15[31:0]'},
-
- {'name': 'ax',
- 'set': 0,
- 'bitsize': 16,
- 'encoding': eEncodingUint,
- 'format': eFormatHex,
- 'slice': 'rax[15:0]'},
- {'name': 'bx',
- 'set': 0,
- 'bitsize': 16,
- 'encoding': eEncodingUint,
- 'format': eFormatHex,
- 'slice': 'rbx[15:0]'},
- {'name': 'cx',
- 'set': 0,
- 'bitsize': 16,
- 'encoding': eEncodingUint,
- 'format': eFormatHex,
- 'slice': 'rcx[15:0]'},
- {'name': 'dx',
- 'set': 0,
- 'bitsize': 16,
- 'encoding': eEncodingUint,
- 'format': eFormatHex,
- 'slice': 'rdx[15:0]'},
- {'name': 'di',
- 'set': 0,
- 'bitsize': 16,
- 'encoding': eEncodingUint,
- 'format': eFormatHex,
- 'slice': 'rdi[15:0]'},
- {'name': 'si',
- 'set': 0,
- 'bitsize': 16,
- 'encoding': eEncodingUint,
- 'format': eFormatHex,
- 'slice': 'rsi[15:0]'},
- {'name': 'bp',
- 'set': 0,
- 'bitsize': 16,
- 'encoding': eEncodingUint,
- 'format': eFormatHex,
- 'slice': 'rbp[15:0]'},
- {'name': 'sp',
- 'set': 0,
- 'bitsize': 16,
- 'encoding': eEncodingUint,
- 'format': eFormatHex,
- 'slice': 'rsp[15:0]'},
- {'name': 'r8w',
- 'set': 0,
- 'bitsize': 16,
- 'encoding': eEncodingUint,
- 'format': eFormatHex,
- 'slice': 'r8[15:0]'},
- {'name': 'r9w',
- 'set': 0,
- 'bitsize': 16,
- 'encoding': eEncodingUint,
- 'format': eFormatHex,
- 'slice': 'r9[15:0]'},
- {'name': 'r10w',
- 'set': 0,
- 'bitsize': 16,
- 'encoding': eEncodingUint,
- 'format': eFormatHex,
- 'slice': 'r10[15:0]'},
- {'name': 'r11w',
- 'set': 0,
- 'bitsize': 16,
- 'encoding': eEncodingUint,
- 'format': eFormatHex,
- 'slice': 'r11[15:0]'},
- {'name': 'r12w',
- 'set': 0,
- 'bitsize': 16,
- 'encoding': eEncodingUint,
- 'format': eFormatHex,
- 'slice': 'r12[15:0]'},
- {'name': 'r13w',
- 'set': 0,
- 'bitsize': 16,
- 'encoding': eEncodingUint,
- 'format': eFormatHex,
- 'slice': 'r13[15:0]'},
- {'name': 'r14w',
- 'set': 0,
- 'bitsize': 16,
- 'encoding': eEncodingUint,
- 'format': eFormatHex,
- 'slice': 'r14[15:0]'},
- {'name': 'r15w',
- 'set': 0,
- 'bitsize': 16,
- 'encoding': eEncodingUint,
- 'format': eFormatHex,
- 'slice': 'r15[15:0]'},
-
- {'name': 'ah',
- 'set': 0,
- 'bitsize': 8,
- 'encoding': eEncodingUint,
- 'format': eFormatHex,
- 'slice': 'rax[15:8]'},
- {'name': 'bh',
- 'set': 0,
- 'bitsize': 8,
- 'encoding': eEncodingUint,
- 'format': eFormatHex,
- 'slice': 'rbx[15:8]'},
- {'name': 'ch',
- 'set': 0,
- 'bitsize': 8,
- 'encoding': eEncodingUint,
- 'format': eFormatHex,
- 'slice': 'rcx[15:8]'},
- {'name': 'dh',
- 'set': 0,
- 'bitsize': 8,
- 'encoding': eEncodingUint,
- 'format': eFormatHex,
- 'slice': 'rdx[15:8]'},
-
- {'name': 'al',
- 'set': 0,
- 'bitsize': 8,
- 'encoding': eEncodingUint,
- 'format': eFormatHex,
- 'slice': 'rax[7:0]'},
- {'name': 'bl',
- 'set': 0,
- 'bitsize': 8,
- 'encoding': eEncodingUint,
- 'format': eFormatHex,
- 'slice': 'rbx[7:0]'},
- {'name': 'cl',
- 'set': 0,
- 'bitsize': 8,
- 'encoding': eEncodingUint,
- 'format': eFormatHex,
- 'slice': 'rcx[7:0]'},
- {'name': 'dl',
- 'set': 0,
- 'bitsize': 8,
- 'encoding': eEncodingUint,
- 'format': eFormatHex,
- 'slice': 'rdx[7:0]'},
- {'name': 'dil',
- 'set': 0,
- 'bitsize': 8,
- 'encoding': eEncodingUint,
- 'format': eFormatHex,
- 'slice': 'rdi[7:0]'},
- {'name': 'sil',
- 'set': 0,
- 'bitsize': 8,
- 'encoding': eEncodingUint,
- 'format': eFormatHex,
- 'slice': 'rsi[7:0]'},
- {'name': 'bpl',
- 'set': 0,
- 'bitsize': 8,
- 'encoding': eEncodingUint,
- 'format': eFormatHex,
- 'slice': 'rbp[7:0]'},
- {'name': 'spl',
- 'set': 0,
- 'bitsize': 8,
- 'encoding': eEncodingUint,
- 'format': eFormatHex,
- 'slice': 'rsp[7:0]'},
- {'name': 'r8l',
- 'set': 0,
- 'bitsize': 8,
- 'encoding': eEncodingUint,
- 'format': eFormatHex,
- 'slice': 'r8[7:0]'},
- {'name': 'r9l',
- 'set': 0,
- 'bitsize': 8,
- 'encoding': eEncodingUint,
- 'format': eFormatHex,
- 'slice': 'r9[7:0]'},
- {'name': 'r10l',
- 'set': 0,
- 'bitsize': 8,
- 'encoding': eEncodingUint,
- 'format': eFormatHex,
- 'slice': 'r10[7:0]'},
- {'name': 'r11l',
- 'set': 0,
- 'bitsize': 8,
- 'encoding': eEncodingUint,
- 'format': eFormatHex,
- 'slice': 'r11[7:0]'},
- {'name': 'r12l',
- 'set': 0,
- 'bitsize': 8,
- 'encoding': eEncodingUint,
- 'format': eFormatHex,
- 'slice': 'r12[7:0]'},
- {'name': 'r13l',
- 'set': 0,
- 'bitsize': 8,
- 'encoding': eEncodingUint,
- 'format': eFormatHex,
- 'slice': 'r13[7:0]'},
- {'name': 'r14l',
- 'set': 0,
- 'bitsize': 8,
- 'encoding': eEncodingUint,
- 'format': eFormatHex,
- 'slice': 'r14[7:0]'},
- {'name': 'r15l',
- 'set': 0,
- 'bitsize': 8,
- 'encoding': eEncodingUint,
- 'format': eFormatHex,
- 'slice': 'r15[7:0]'},
-]
-
-g_target_definition = None
-
-
-def get_target_definition():
- global g_target_definition
- if g_target_definition is None:
- g_target_definition = {}
- offset = 0
- for reg_info in x86_64_register_infos:
- reg_name = reg_info['name']
-
- # Only fill in the offset if there is no 'slice' in the register
- # info
- if 'slice' not in reg_info and 'composite' not in reg_info:
- reg_info['offset'] = offset
- offset += reg_info['bitsize'] / 8
-
- # Set the GCC/DWARF register number for this register if it has one
- reg_num = get_reg_num(name_to_gcc_dwarf_regnum, reg_name)
- if reg_num != LLDB_INVALID_REGNUM:
- reg_info['gcc'] = reg_num
- reg_info['dwarf'] = reg_num
-
- # Set the generic register number for this register if it has one
- reg_num = get_reg_num(name_to_generic_regnum, reg_name)
- if reg_num != LLDB_INVALID_REGNUM:
- reg_info['generic'] = reg_num
-
- # Set the GDB register number for this register if it has one
- reg_num = get_reg_num(name_to_gdb_regnum, reg_name)
- if reg_num != LLDB_INVALID_REGNUM:
- reg_info['gdb'] = reg_num
-
- g_target_definition['sets'] = [
- 'General Purpose Registers',
- 'Floating Point Registers']
- g_target_definition['registers'] = x86_64_register_infos
- g_target_definition[
- 'host-info'] = {'triple': 'x86_64-*-linux', 'endian': eByteOrderLittle}
- g_target_definition['g-packet-size'] = offset
- g_target_definition['breakpoint-pc-offset'] = -1
- return g_target_definition
-
-
-def get_dynamic_setting(target, setting_name):
- if setting_name == 'gdb-server-target-definition':
- return get_target_definition()
diff --git a/examples/python/x86_64_qemu_target_definition.py b/examples/python/x86_64_qemu_target_definition.py
deleted file mode 100644
index 5b4ea480ccf3..000000000000
--- a/examples/python/x86_64_qemu_target_definition.py
+++ /dev/null
@@ -1,773 +0,0 @@
-#!/usr/bin/python
-#===-- x86_64_qemu_target_definition.py -----------------------------*- C++ -*-===//
-#
-# The LLVM Compiler Infrastructure
-#
-# This file is distributed under the University of Illinois Open Source
-# License. See LICENSE.TXT for details.
-#
-#===----------------------------------------------------------------------===//
-
-#----------------------------------------------------------------------
-# DESCRIPTION
-#
-# This file can be used with the following setting:
-# plugin.process.gdb-remote.target-definition-file
-# This setting should be used when you are trying to connect to a
-# remote GDB server that doesn't support any of the register discovery
-# packets that LLDB normally uses.
-#
-# Why is this necessary? LLDB doesn't require a new build of LLDB that
-# targets each new architecture you will debug with. Instead, all
-# architectures are supported and LLDB relies on extra GDB server
-# packets to discover the target we are connecting to so that is can
-# show the right registers for each target. This allows the remote stub
-# to change and add new registers without requiring a new LLDB build
-# just so we can see new registers.
-#
-# This file implements the x86_64 registers for the user mode qemu on linux.
-# The only difference with the Linux file is the absense of orig_rax register.
-#
-# USAGE
-#
-# (lldb) settings set plugin.process.gdb-remote.target-definition-file /path/to/x86_64_qemu_target_definition.py
-# (lldb) gdb-remote other.baz.com:1234
-#
-# The target definition file will get used if and only if the
-# qRegisterInfo packets are not supported when connecting to a remote
-# GDB stub.
-#----------------------------------------------------------------------
-from lldb import *
-
-# Compiler and DWARF register numbers
-name_to_gcc_dwarf_regnum = {
- 'rax': 0,
- 'rdx': 1,
- 'rcx': 2,
- 'rbx': 3,
- 'rsi': 4,
- 'rdi': 5,
- 'rbp': 6,
- 'rsp': 7,
- 'r8': 8,
- 'r9': 9,
- 'r10': 10,
- 'r11': 11,
- 'r12': 12,
- 'r13': 13,
- 'r14': 14,
- 'r15': 15,
- 'rip': 16,
- 'xmm0': 17,
- 'xmm1': 18,
- 'xmm2': 19,
- 'xmm3': 20,
- 'xmm4': 21,
- 'xmm5': 22,
- 'xmm6': 23,
- 'xmm7': 24,
- 'xmm8': 25,
- 'xmm9': 26,
- 'xmm10': 27,
- 'xmm11': 28,
- 'xmm12': 29,
- 'xmm13': 30,
- 'xmm14': 31,
- 'xmm15': 32,
- 'stmm0': 33,
- 'stmm1': 34,
- 'stmm2': 35,
- 'stmm3': 36,
- 'stmm4': 37,
- 'stmm5': 38,
- 'stmm6': 39,
- 'stmm7': 30,
- 'ymm0': 41,
- 'ymm1': 42,
- 'ymm2': 43,
- 'ymm3': 44,
- 'ymm4': 45,
- 'ymm5': 46,
- 'ymm6': 47,
- 'ymm7': 48,
- 'ymm8': 49,
- 'ymm9': 40,
- 'ymm10': 41,
- 'ymm11': 42,
- 'ymm12': 43,
- 'ymm13': 44,
- 'ymm14': 45,
- 'ymm15': 46
-}
-
-name_to_gdb_regnum = {
- 'rax': 0,
- 'rbx': 1,
- 'rcx': 2,
- 'rdx': 3,
- 'rsi': 4,
- 'rdi': 5,
- 'rbp': 6,
- 'rsp': 7,
- 'r8': 8,
- 'r9': 9,
- 'r10': 10,
- 'r11': 11,
- 'r12': 12,
- 'r13': 13,
- 'r14': 14,
- 'r15': 15,
- 'rip': 16,
- 'rflags': 17,
- 'cs': 18,
- 'ss': 19,
- 'ds': 20,
- 'es': 21,
- 'fs': 22,
- 'gs': 23,
- 'stmm0': 24,
- 'stmm1': 25,
- 'stmm2': 26,
- 'stmm3': 27,
- 'stmm4': 28,
- 'stmm5': 29,
- 'stmm6': 30,
- 'stmm7': 31,
- 'fctrl': 32,
- 'fstat': 33,
- 'ftag': 34,
- 'fiseg': 35,
- 'fioff': 36,
- 'foseg': 37,
- 'fooff': 38,
- 'fop': 39,
- 'xmm0': 40,
- 'xmm1': 41,
- 'xmm2': 42,
- 'xmm3': 43,
- 'xmm4': 44,
- 'xmm5': 45,
- 'xmm6': 46,
- 'xmm7': 47,
- 'xmm8': 48,
- 'xmm9': 49,
- 'xmm10': 50,
- 'xmm11': 51,
- 'xmm12': 52,
- 'xmm13': 53,
- 'xmm14': 54,
- 'xmm15': 55,
- 'mxcsr': 56,
- 'ymm0': 57,
- 'ymm1': 58,
- 'ymm2': 59,
- 'ymm3': 60,
- 'ymm4': 61,
- 'ymm5': 62,
- 'ymm6': 63,
- 'ymm7': 64,
- 'ymm8': 65,
- 'ymm9': 66,
- 'ymm10': 67,
- 'ymm11': 68,
- 'ymm12': 69,
- 'ymm13': 70,
- 'ymm14': 71,
- 'ymm15': 72
-}
-
-name_to_generic_regnum = {
- 'rip': LLDB_REGNUM_GENERIC_PC,
- 'rsp': LLDB_REGNUM_GENERIC_SP,
- 'rbp': LLDB_REGNUM_GENERIC_FP,
- 'rdi': LLDB_REGNUM_GENERIC_ARG1,
- 'rsi': LLDB_REGNUM_GENERIC_ARG2,
- 'rdx': LLDB_REGNUM_GENERIC_ARG3,
- 'rcx': LLDB_REGNUM_GENERIC_ARG4,
- 'r8': LLDB_REGNUM_GENERIC_ARG5,
- 'r9': LLDB_REGNUM_GENERIC_ARG6
-}
-
-
-def get_reg_num(reg_num_dict, reg_name):
- if reg_name in reg_num_dict:
- return reg_num_dict[reg_name]
- return LLDB_INVALID_REGNUM
-
-x86_64_register_infos = [
- {'name': 'rax',
- 'set': 0,
- 'bitsize': 64,
- 'encoding': eEncodingUint,
- 'format': eFormatAddressInfo},
- {'name': 'rbx',
- 'set': 0,
- 'bitsize': 64,
- 'encoding': eEncodingUint,
- 'format': eFormatAddressInfo},
- {'name': 'rcx', 'set': 0, 'bitsize': 64, 'encoding': eEncodingUint,
- 'format': eFormatAddressInfo, 'alt-name': 'arg4'},
- {'name': 'rdx', 'set': 0, 'bitsize': 64, 'encoding': eEncodingUint,
- 'format': eFormatAddressInfo, 'alt-name': 'arg3'},
- {'name': 'rsi', 'set': 0, 'bitsize': 64, 'encoding': eEncodingUint,
- 'format': eFormatAddressInfo, 'alt-name': 'arg2'},
- {'name': 'rdi', 'set': 0, 'bitsize': 64, 'encoding': eEncodingUint,
- 'format': eFormatAddressInfo, 'alt-name': 'arg1'},
- {'name': 'rbp', 'set': 0, 'bitsize': 64, 'encoding': eEncodingUint,
- 'format': eFormatAddressInfo, 'alt-name': 'fp'},
- {'name': 'rsp', 'set': 0, 'bitsize': 64, 'encoding': eEncodingUint,
- 'format': eFormatAddressInfo, 'alt-name': 'sp'},
- {'name': 'r8', 'set': 0, 'bitsize': 64, 'encoding': eEncodingUint,
- 'format': eFormatAddressInfo, 'alt-name': 'arg5'},
- {'name': 'r9', 'set': 0, 'bitsize': 64, 'encoding': eEncodingUint,
- 'format': eFormatAddressInfo, 'alt-name': 'arg6'},
- {'name': 'r10',
- 'set': 0,
- 'bitsize': 64,
- 'encoding': eEncodingUint,
- 'format': eFormatAddressInfo},
- {'name': 'r11',
- 'set': 0,
- 'bitsize': 64,
- 'encoding': eEncodingUint,
- 'format': eFormatAddressInfo},
- {'name': 'r12',
- 'set': 0,
- 'bitsize': 64,
- 'encoding': eEncodingUint,
- 'format': eFormatAddressInfo},
- {'name': 'r13',
- 'set': 0,
- 'bitsize': 64,
- 'encoding': eEncodingUint,
- 'format': eFormatAddressInfo},
- {'name': 'r14',
- 'set': 0,
- 'bitsize': 64,
- 'encoding': eEncodingUint,
- 'format': eFormatAddressInfo},
- {'name': 'r15',
- 'set': 0,
- 'bitsize': 64,
- 'encoding': eEncodingUint,
- 'format': eFormatAddressInfo},
- {'name': 'rip', 'set': 0, 'bitsize': 64, 'encoding': eEncodingUint,
- 'format': eFormatAddressInfo, 'alt-name': 'pc'},
- {'name': 'rflags', 'set': 0, 'bitsize': 32,
- 'encoding': eEncodingUint, 'format': eFormatHex},
- {'name': 'cs', 'set': 0, 'bitsize': 32,
- 'encoding': eEncodingUint, 'format': eFormatHex},
- {'name': 'ss', 'set': 0, 'bitsize': 32,
- 'encoding': eEncodingUint, 'format': eFormatHex},
- {'name': 'ds', 'set': 0, 'bitsize': 32,
- 'encoding': eEncodingUint, 'format': eFormatHex},
- {'name': 'es', 'set': 0, 'bitsize': 32,
- 'encoding': eEncodingUint, 'format': eFormatHex},
- {'name': 'fs', 'set': 0, 'bitsize': 32,
- 'encoding': eEncodingUint, 'format': eFormatHex},
- {'name': 'gs', 'set': 0, 'bitsize': 32,
- 'encoding': eEncodingUint, 'format': eFormatHex},
- {'name': 'stmm0',
- 'set': 1,
- 'bitsize': 80,
- 'encoding': eEncodingVector,
- 'format': eFormatVectorOfUInt8},
- {'name': 'stmm1',
- 'set': 1,
- 'bitsize': 80,
- 'encoding': eEncodingVector,
- 'format': eFormatVectorOfUInt8},
- {'name': 'stmm2',
- 'set': 1,
- 'bitsize': 80,
- 'encoding': eEncodingVector,
- 'format': eFormatVectorOfUInt8},
- {'name': 'stmm3',
- 'set': 1,
- 'bitsize': 80,
- 'encoding': eEncodingVector,
- 'format': eFormatVectorOfUInt8},
- {'name': 'stmm4',
- 'set': 1,
- 'bitsize': 80,
- 'encoding': eEncodingVector,
- 'format': eFormatVectorOfUInt8},
- {'name': 'stmm5',
- 'set': 1,
- 'bitsize': 80,
- 'encoding': eEncodingVector,
- 'format': eFormatVectorOfUInt8},
- {'name': 'stmm6',
- 'set': 1,
- 'bitsize': 80,
- 'encoding': eEncodingVector,
- 'format': eFormatVectorOfUInt8},
- {'name': 'stmm7',
- 'set': 1,
- 'bitsize': 80,
- 'encoding': eEncodingVector,
- 'format': eFormatVectorOfUInt8},
- {'name': 'fctrl', 'set': 1, 'bitsize': 32,
- 'encoding': eEncodingUint, 'format': eFormatHex},
- {'name': 'fstat', 'set': 1, 'bitsize': 32,
- 'encoding': eEncodingUint, 'format': eFormatHex},
- {'name': 'ftag', 'set': 1, 'bitsize': 32,
- 'encoding': eEncodingUint, 'format': eFormatHex},
- {'name': 'fiseg', 'set': 1, 'bitsize': 32,
- 'encoding': eEncodingUint, 'format': eFormatHex},
- {'name': 'fioff', 'set': 1, 'bitsize': 32,
- 'encoding': eEncodingUint, 'format': eFormatHex},
- {'name': 'foseg', 'set': 1, 'bitsize': 32,
- 'encoding': eEncodingUint, 'format': eFormatHex},
- {'name': 'fooff', 'set': 1, 'bitsize': 32,
- 'encoding': eEncodingUint, 'format': eFormatHex},
- {'name': 'fop', 'set': 1, 'bitsize': 32,
- 'encoding': eEncodingUint, 'format': eFormatHex},
- {'name': 'xmm0',
- 'set': 1,
- 'bitsize': 128,
- 'encoding': eEncodingVector,
- 'format': eFormatVectorOfUInt8},
- {'name': 'xmm1',
- 'set': 1,
- 'bitsize': 128,
- 'encoding': eEncodingVector,
- 'format': eFormatVectorOfUInt8},
- {'name': 'xmm2',
- 'set': 1,
- 'bitsize': 128,
- 'encoding': eEncodingVector,
- 'format': eFormatVectorOfUInt8},
- {'name': 'xmm3',
- 'set': 1,
- 'bitsize': 128,
- 'encoding': eEncodingVector,
- 'format': eFormatVectorOfUInt8},
- {'name': 'xmm4',
- 'set': 1,
- 'bitsize': 128,
- 'encoding': eEncodingVector,
- 'format': eFormatVectorOfUInt8},
- {'name': 'xmm5',
- 'set': 1,
- 'bitsize': 128,
- 'encoding': eEncodingVector,
- 'format': eFormatVectorOfUInt8},
- {'name': 'xmm6',
- 'set': 1,
- 'bitsize': 128,
- 'encoding': eEncodingVector,
- 'format': eFormatVectorOfUInt8},
- {'name': 'xmm7',
- 'set': 1,
- 'bitsize': 128,
- 'encoding': eEncodingVector,
- 'format': eFormatVectorOfUInt8},
- {'name': 'xmm8',
- 'set': 1,
- 'bitsize': 128,
- 'encoding': eEncodingVector,
- 'format': eFormatVectorOfUInt8},
- {'name': 'xmm9',
- 'set': 1,
- 'bitsize': 128,
- 'encoding': eEncodingVector,
- 'format': eFormatVectorOfUInt8},
- {'name': 'xmm10',
- 'set': 1,
- 'bitsize': 128,
- 'encoding': eEncodingVector,
- 'format': eFormatVectorOfUInt8},
- {'name': 'xmm11',
- 'set': 1,
- 'bitsize': 128,
- 'encoding': eEncodingVector,
- 'format': eFormatVectorOfUInt8},
- {'name': 'xmm12',
- 'set': 1,
- 'bitsize': 128,
- 'encoding': eEncodingVector,
- 'format': eFormatVectorOfUInt8},
- {'name': 'xmm13',
- 'set': 1,
- 'bitsize': 128,
- 'encoding': eEncodingVector,
- 'format': eFormatVectorOfUInt8},
- {'name': 'xmm14',
- 'set': 1,
- 'bitsize': 128,
- 'encoding': eEncodingVector,
- 'format': eFormatVectorOfUInt8},
- {'name': 'xmm15',
- 'set': 1,
- 'bitsize': 128,
- 'encoding': eEncodingVector,
- 'format': eFormatVectorOfUInt8},
- {'name': 'mxcsr', 'set': 1, 'bitsize': 32,
- 'encoding': eEncodingUint, 'format': eFormatHex},
- # Registers that are contained in or composed of one of more other
- # registers
- {'name': 'eax',
- 'set': 0,
- 'bitsize': 32,
- 'encoding': eEncodingUint,
- 'format': eFormatHex,
- 'slice': 'rax[31:0]'},
- {'name': 'ebx',
- 'set': 0,
- 'bitsize': 32,
- 'encoding': eEncodingUint,
- 'format': eFormatHex,
- 'slice': 'rbx[31:0]'},
- {'name': 'ecx',
- 'set': 0,
- 'bitsize': 32,
- 'encoding': eEncodingUint,
- 'format': eFormatHex,
- 'slice': 'rcx[31:0]'},
- {'name': 'edx',
- 'set': 0,
- 'bitsize': 32,
- 'encoding': eEncodingUint,
- 'format': eFormatHex,
- 'slice': 'rdx[31:0]'},
- {'name': 'edi',
- 'set': 0,
- 'bitsize': 32,
- 'encoding': eEncodingUint,
- 'format': eFormatHex,
- 'slice': 'rdi[31:0]'},
- {'name': 'esi',
- 'set': 0,
- 'bitsize': 32,
- 'encoding': eEncodingUint,
- 'format': eFormatHex,
- 'slice': 'rsi[31:0]'},
- {'name': 'ebp',
- 'set': 0,
- 'bitsize': 32,
- 'encoding': eEncodingUint,
- 'format': eFormatHex,
- 'slice': 'rbp[31:0]'},
- {'name': 'esp',
- 'set': 0,
- 'bitsize': 32,
- 'encoding': eEncodingUint,
- 'format': eFormatHex,
- 'slice': 'rsp[31:0]'},
- {'name': 'r8d',
- 'set': 0,
- 'bitsize': 32,
- 'encoding': eEncodingUint,
- 'format': eFormatHex,
- 'slice': 'r8[31:0]'},
- {'name': 'r9d',
- 'set': 0,
- 'bitsize': 32,
- 'encoding': eEncodingUint,
- 'format': eFormatHex,
- 'slice': 'r9[31:0]'},
- {'name': 'r10d',
- 'set': 0,
- 'bitsize': 32,
- 'encoding': eEncodingUint,
- 'format': eFormatHex,
- 'slice': 'r10[31:0]'},
- {'name': 'r11d',
- 'set': 0,
- 'bitsize': 32,
- 'encoding': eEncodingUint,
- 'format': eFormatHex,
- 'slice': 'r11[31:0]'},
- {'name': 'r12d',
- 'set': 0,
- 'bitsize': 32,
- 'encoding': eEncodingUint,
- 'format': eFormatHex,
- 'slice': 'r12[31:0]'},
- {'name': 'r13d',
- 'set': 0,
- 'bitsize': 32,
- 'encoding': eEncodingUint,
- 'format': eFormatHex,
- 'slice': 'r13[31:0]'},
- {'name': 'r14d',
- 'set': 0,
- 'bitsize': 32,
- 'encoding': eEncodingUint,
- 'format': eFormatHex,
- 'slice': 'r14[31:0]'},
- {'name': 'r15d',
- 'set': 0,
- 'bitsize': 32,
- 'encoding': eEncodingUint,
- 'format': eFormatHex,
- 'slice': 'r15[31:0]'},
-
- {'name': 'ax',
- 'set': 0,
- 'bitsize': 16,
- 'encoding': eEncodingUint,
- 'format': eFormatHex,
- 'slice': 'rax[15:0]'},
- {'name': 'bx',
- 'set': 0,
- 'bitsize': 16,
- 'encoding': eEncodingUint,
- 'format': eFormatHex,
- 'slice': 'rbx[15:0]'},
- {'name': 'cx',
- 'set': 0,
- 'bitsize': 16,
- 'encoding': eEncodingUint,
- 'format': eFormatHex,
- 'slice': 'rcx[15:0]'},
- {'name': 'dx',
- 'set': 0,
- 'bitsize': 16,
- 'encoding': eEncodingUint,
- 'format': eFormatHex,
- 'slice': 'rdx[15:0]'},
- {'name': 'di',
- 'set': 0,
- 'bitsize': 16,
- 'encoding': eEncodingUint,
- 'format': eFormatHex,
- 'slice': 'rdi[15:0]'},
- {'name': 'si',
- 'set': 0,
- 'bitsize': 16,
- 'encoding': eEncodingUint,
- 'format': eFormatHex,
- 'slice': 'rsi[15:0]'},
- {'name': 'bp',
- 'set': 0,
- 'bitsize': 16,
- 'encoding': eEncodingUint,
- 'format': eFormatHex,
- 'slice': 'rbp[15:0]'},
- {'name': 'sp',
- 'set': 0,
- 'bitsize': 16,
- 'encoding': eEncodingUint,
- 'format': eFormatHex,
- 'slice': 'rsp[15:0]'},
- {'name': 'r8w',
- 'set': 0,
- 'bitsize': 16,
- 'encoding': eEncodingUint,
- 'format': eFormatHex,
- 'slice': 'r8[15:0]'},
- {'name': 'r9w',
- 'set': 0,
- 'bitsize': 16,
- 'encoding': eEncodingUint,
- 'format': eFormatHex,
- 'slice': 'r9[15:0]'},
- {'name': 'r10w',
- 'set': 0,
- 'bitsize': 16,
- 'encoding': eEncodingUint,
- 'format': eFormatHex,
- 'slice': 'r10[15:0]'},
- {'name': 'r11w',
- 'set': 0,
- 'bitsize': 16,
- 'encoding': eEncodingUint,
- 'format': eFormatHex,
- 'slice': 'r11[15:0]'},
- {'name': 'r12w',
- 'set': 0,
- 'bitsize': 16,
- 'encoding': eEncodingUint,
- 'format': eFormatHex,
- 'slice': 'r12[15:0]'},
- {'name': 'r13w',
- 'set': 0,
- 'bitsize': 16,
- 'encoding': eEncodingUint,
- 'format': eFormatHex,
- 'slice': 'r13[15:0]'},
- {'name': 'r14w',
- 'set': 0,
- 'bitsize': 16,
- 'encoding': eEncodingUint,
- 'format': eFormatHex,
- 'slice': 'r14[15:0]'},
- {'name': 'r15w',
- 'set': 0,
- 'bitsize': 16,
- 'encoding': eEncodingUint,
- 'format': eFormatHex,
- 'slice': 'r15[15:0]'},
-
- {'name': 'ah',
- 'set': 0,
- 'bitsize': 8,
- 'encoding': eEncodingUint,
- 'format': eFormatHex,
- 'slice': 'rax[15:8]'},
- {'name': 'bh',
- 'set': 0,
- 'bitsize': 8,
- 'encoding': eEncodingUint,
- 'format': eFormatHex,
- 'slice': 'rbx[15:8]'},
- {'name': 'ch',
- 'set': 0,
- 'bitsize': 8,
- 'encoding': eEncodingUint,
- 'format': eFormatHex,
- 'slice': 'rcx[15:8]'},
- {'name': 'dh',
- 'set': 0,
- 'bitsize': 8,
- 'encoding': eEncodingUint,
- 'format': eFormatHex,
- 'slice': 'rdx[15:8]'},
-
- {'name': 'al',
- 'set': 0,
- 'bitsize': 8,
- 'encoding': eEncodingUint,
- 'format': eFormatHex,
- 'slice': 'rax[7:0]'},
- {'name': 'bl',
- 'set': 0,
- 'bitsize': 8,
- 'encoding': eEncodingUint,
- 'format': eFormatHex,
- 'slice': 'rbx[7:0]'},
- {'name': 'cl',
- 'set': 0,
- 'bitsize': 8,
- 'encoding': eEncodingUint,
- 'format': eFormatHex,
- 'slice': 'rcx[7:0]'},
- {'name': 'dl',
- 'set': 0,
- 'bitsize': 8,
- 'encoding': eEncodingUint,
- 'format': eFormatHex,
- 'slice': 'rdx[7:0]'},
- {'name': 'dil',
- 'set': 0,
- 'bitsize': 8,
- 'encoding': eEncodingUint,
- 'format': eFormatHex,
- 'slice': 'rdi[7:0]'},
- {'name': 'sil',
- 'set': 0,
- 'bitsize': 8,
- 'encoding': eEncodingUint,
- 'format': eFormatHex,
- 'slice': 'rsi[7:0]'},
- {'name': 'bpl',
- 'set': 0,
- 'bitsize': 8,
- 'encoding': eEncodingUint,
- 'format': eFormatHex,
- 'slice': 'rbp[7:0]'},
- {'name': 'spl',
- 'set': 0,
- 'bitsize': 8,
- 'encoding': eEncodingUint,
- 'format': eFormatHex,
- 'slice': 'rsp[7:0]'},
- {'name': 'r8l',
- 'set': 0,
- 'bitsize': 8,
- 'encoding': eEncodingUint,
- 'format': eFormatHex,
- 'slice': 'r8[7:0]'},
- {'name': 'r9l',
- 'set': 0,
- 'bitsize': 8,
- 'encoding': eEncodingUint,
- 'format': eFormatHex,
- 'slice': 'r9[7:0]'},
- {'name': 'r10l',
- 'set': 0,
- 'bitsize': 8,
- 'encoding': eEncodingUint,
- 'format': eFormatHex,
- 'slice': 'r10[7:0]'},
- {'name': 'r11l',
- 'set': 0,
- 'bitsize': 8,
- 'encoding': eEncodingUint,
- 'format': eFormatHex,
- 'slice': 'r11[7:0]'},
- {'name': 'r12l',
- 'set': 0,
- 'bitsize': 8,
- 'encoding': eEncodingUint,
- 'format': eFormatHex,
- 'slice': 'r12[7:0]'},
- {'name': 'r13l',
- 'set': 0,
- 'bitsize': 8,
- 'encoding': eEncodingUint,
- 'format': eFormatHex,
- 'slice': 'r13[7:0]'},
- {'name': 'r14l',
- 'set': 0,
- 'bitsize': 8,
- 'encoding': eEncodingUint,
- 'format': eFormatHex,
- 'slice': 'r14[7:0]'},
- {'name': 'r15l',
- 'set': 0,
- 'bitsize': 8,
- 'encoding': eEncodingUint,
- 'format': eFormatHex,
- 'slice': 'r15[7:0]'},
-]
-
-g_target_definition = None
-
-
-def get_target_definition():
- global g_target_definition
- if g_target_definition is None:
- g_target_definition = {}
- offset = 0
- for reg_info in x86_64_register_infos:
- reg_name = reg_info['name']
-
- # Only fill in the offset if there is no 'slice' in the register
- # info
- if 'slice' not in reg_info and 'composite' not in reg_info:
- reg_info['offset'] = offset
- offset += reg_info['bitsize'] / 8
-
- # Set the GCC/DWARF register number for this register if it has one
- reg_num = get_reg_num(name_to_gcc_dwarf_regnum, reg_name)
- if reg_num != LLDB_INVALID_REGNUM:
- reg_info['gcc'] = reg_num
- reg_info['dwarf'] = reg_num
-
- # Set the generic register number for this register if it has one
- reg_num = get_reg_num(name_to_generic_regnum, reg_name)
- if reg_num != LLDB_INVALID_REGNUM:
- reg_info['generic'] = reg_num
-
- # Set the GDB register number for this register if it has one
- reg_num = get_reg_num(name_to_gdb_regnum, reg_name)
- if reg_num != LLDB_INVALID_REGNUM:
- reg_info['gdb'] = reg_num
-
- g_target_definition['sets'] = [
- 'General Purpose Registers',
- 'Floating Point Registers']
- g_target_definition['registers'] = x86_64_register_infos
- g_target_definition[
- 'host-info'] = {'triple': 'x86_64-*-linux', 'endian': eByteOrderLittle}
- g_target_definition['g-packet-size'] = offset
- g_target_definition['breakpoint-pc-offset'] = -1
- return g_target_definition
-
-
-def get_dynamic_setting(target, setting_name):
- if setting_name == 'gdb-server-target-definition':
- return get_target_definition()
diff --git a/examples/python/x86_64_target_definition.py b/examples/python/x86_64_target_definition.py
deleted file mode 100644
index 03411cf07c20..000000000000
--- a/examples/python/x86_64_target_definition.py
+++ /dev/null
@@ -1,778 +0,0 @@
-#!/usr/bin/python
-#===-- x86_64_target_definition.py -----------------------------*- C++ -*-===//
-#
-# The LLVM Compiler Infrastructure
-#
-# This file is distributed under the University of Illinois Open Source
-# License. See LICENSE.TXT for details.
-#
-#===----------------------------------------------------------------------===//
-
-#----------------------------------------------------------------------
-# DESCRIPTION
-#
-# This file can be used with the following setting:
-# plugin.process.gdb-remote.target-definition-file
-# This setting should be used when you are trying to connect to a
-# remote GDB server that doesn't support any of the register discovery
-# packets that LLDB normally uses.
-#
-# Why is this necessary? LLDB doesn't require a new build of LLDB that
-# targets each new architecture you will debug with. Instead, all
-# architectures are supported and LLDB relies on extra GDB server
-# packets to discover the target we are connecting to so that is can
-# show the right registers for each target. This allows the GDB server
-# to change and add new registers without requiring a new LLDB build
-# just so we can see new registers.
-#
-# This file implements the x86_64 registers for the darwin version of
-# GDB and allows you to connect to servers that use this register set.
-#
-# USAGE
-#
-# (lldb) settings set plugin.process.gdb-remote.target-definition-file /path/to/x86_64_target_definition.py
-# (lldb) gdb-remote other.baz.com:1234
-#
-# The target definition file will get used if and only if the
-# qRegisterInfo packets are not supported when connecting to a remote
-# GDB server.
-#----------------------------------------------------------------------
-from lldb import *
-
-# Compiler and DWARF register numbers
-name_to_gcc_dwarf_regnum = {
- 'rax': 0,
- 'rdx': 1,
- 'rcx': 2,
- 'rbx': 3,
- 'rsi': 4,
- 'rdi': 5,
- 'rbp': 6,
- 'rsp': 7,
- 'r8': 8,
- 'r9': 9,
- 'r10': 10,
- 'r11': 11,
- 'r12': 12,
- 'r13': 13,
- 'r14': 14,
- 'r15': 15,
- 'rip': 16,
- 'xmm0': 17,
- 'xmm1': 18,
- 'xmm2': 19,
- 'xmm3': 20,
- 'xmm4': 21,
- 'xmm5': 22,
- 'xmm6': 23,
- 'xmm7': 24,
- 'xmm8': 25,
- 'xmm9': 26,
- 'xmm10': 27,
- 'xmm11': 28,
- 'xmm12': 29,
- 'xmm13': 30,
- 'xmm14': 31,
- 'xmm15': 32,
- 'stmm0': 33,
- 'stmm1': 34,
- 'stmm2': 35,
- 'stmm3': 36,
- 'stmm4': 37,
- 'stmm5': 38,
- 'stmm6': 39,
- 'stmm7': 30,
- 'ymm0': 41,
- 'ymm1': 42,
- 'ymm2': 43,
- 'ymm3': 44,
- 'ymm4': 45,
- 'ymm5': 46,
- 'ymm6': 47,
- 'ymm7': 48,
- 'ymm8': 49,
- 'ymm9': 40,
- 'ymm10': 41,
- 'ymm11': 42,
- 'ymm12': 43,
- 'ymm13': 44,
- 'ymm14': 45,
- 'ymm15': 46
-}
-
-name_to_gdb_regnum = {
- 'rax': 0,
- 'rbx': 1,
- 'rcx': 2,
- 'rdx': 3,
- 'rsi': 4,
- 'rdi': 5,
- 'rbp': 6,
- 'rsp': 7,
- 'r8': 8,
- 'r9': 9,
- 'r10': 10,
- 'r11': 11,
- 'r12': 12,
- 'r13': 13,
- 'r14': 14,
- 'r15': 15,
- 'rip': 16,
- 'rflags': 17,
- 'cs': 18,
- 'ss': 19,
- 'ds': 20,
- 'es': 21,
- 'fs': 22,
- 'gs': 23,
- 'stmm0': 24,
- 'stmm1': 25,
- 'stmm2': 26,
- 'stmm3': 27,
- 'stmm4': 28,
- 'stmm5': 29,
- 'stmm6': 30,
- 'stmm7': 31,
- 'fctrl': 32,
- 'fstat': 33,
- 'ftag': 34,
- 'fiseg': 35,
- 'fioff': 36,
- 'foseg': 37,
- 'fooff': 38,
- 'fop': 39,
- 'xmm0': 40,
- 'xmm1': 41,
- 'xmm2': 42,
- 'xmm3': 43,
- 'xmm4': 44,
- 'xmm5': 45,
- 'xmm6': 46,
- 'xmm7': 47,
- 'xmm8': 48,
- 'xmm9': 49,
- 'xmm10': 50,
- 'xmm11': 51,
- 'xmm12': 52,
- 'xmm13': 53,
- 'xmm14': 54,
- 'xmm15': 55,
- 'mxcsr': 56,
- 'ymm0': 57,
- 'ymm1': 58,
- 'ymm2': 59,
- 'ymm3': 60,
- 'ymm4': 61,
- 'ymm5': 62,
- 'ymm6': 63,
- 'ymm7': 64,
- 'ymm8': 65,
- 'ymm9': 66,
- 'ymm10': 67,
- 'ymm11': 68,
- 'ymm12': 69,
- 'ymm13': 70,
- 'ymm14': 71,
- 'ymm15': 72
-}
-
-name_to_generic_regnum = {
- 'rip': LLDB_REGNUM_GENERIC_PC,
- 'rsp': LLDB_REGNUM_GENERIC_SP,
- 'rbp': LLDB_REGNUM_GENERIC_FP,
- 'rdi': LLDB_REGNUM_GENERIC_ARG1,
- 'rsi': LLDB_REGNUM_GENERIC_ARG2,
- 'rdx': LLDB_REGNUM_GENERIC_ARG3,
- 'rcx': LLDB_REGNUM_GENERIC_ARG4,
- 'r8': LLDB_REGNUM_GENERIC_ARG5,
- 'r9': LLDB_REGNUM_GENERIC_ARG6
-}
-
-
-def get_reg_num(reg_num_dict, reg_name):
- if reg_name in reg_num_dict:
- return reg_num_dict[reg_name]
- return LLDB_INVALID_REGNUM
-
-
-def get_reg_num(reg_num_dict, reg_name):
- if reg_name in reg_num_dict:
- return reg_num_dict[reg_name]
- return LLDB_INVALID_REGNUM
-
-x86_64_register_infos = [
- {'name': 'rax',
- 'set': 0,
- 'bitsize': 64,
- 'encoding': eEncodingUint,
- 'format': eFormatAddressInfo},
- {'name': 'rbx',
- 'set': 0,
- 'bitsize': 64,
- 'encoding': eEncodingUint,
- 'format': eFormatAddressInfo},
- {'name': 'rcx', 'set': 0, 'bitsize': 64, 'encoding': eEncodingUint,
- 'format': eFormatAddressInfo, 'alt-name': 'arg4'},
- {'name': 'rdx', 'set': 0, 'bitsize': 64, 'encoding': eEncodingUint,
- 'format': eFormatAddressInfo, 'alt-name': 'arg3'},
- {'name': 'rsi', 'set': 0, 'bitsize': 64, 'encoding': eEncodingUint,
- 'format': eFormatAddressInfo, 'alt-name': 'arg2'},
- {'name': 'rdi', 'set': 0, 'bitsize': 64, 'encoding': eEncodingUint,
- 'format': eFormatAddressInfo, 'alt-name': 'arg1'},
- {'name': 'rbp', 'set': 0, 'bitsize': 64, 'encoding': eEncodingUint,
- 'format': eFormatAddressInfo, 'alt-name': 'fp'},
- {'name': 'rsp', 'set': 0, 'bitsize': 64, 'encoding': eEncodingUint,
- 'format': eFormatAddressInfo, 'alt-name': 'sp'},
- {'name': 'r8', 'set': 0, 'bitsize': 64, 'encoding': eEncodingUint,
- 'format': eFormatAddressInfo, 'alt-name': 'arg5'},
- {'name': 'r9', 'set': 0, 'bitsize': 64, 'encoding': eEncodingUint,
- 'format': eFormatAddressInfo, 'alt-name': 'arg6'},
- {'name': 'r10',
- 'set': 0,
- 'bitsize': 64,
- 'encoding': eEncodingUint,
- 'format': eFormatAddressInfo},
- {'name': 'r11',
- 'set': 0,
- 'bitsize': 64,
- 'encoding': eEncodingUint,
- 'format': eFormatAddressInfo},
- {'name': 'r12',
- 'set': 0,
- 'bitsize': 64,
- 'encoding': eEncodingUint,
- 'format': eFormatAddressInfo},
- {'name': 'r13',
- 'set': 0,
- 'bitsize': 64,
- 'encoding': eEncodingUint,
- 'format': eFormatAddressInfo},
- {'name': 'r14',
- 'set': 0,
- 'bitsize': 64,
- 'encoding': eEncodingUint,
- 'format': eFormatAddressInfo},
- {'name': 'r15',
- 'set': 0,
- 'bitsize': 64,
- 'encoding': eEncodingUint,
- 'format': eFormatAddressInfo},
- {'name': 'rip', 'set': 0, 'bitsize': 64, 'encoding': eEncodingUint,
- 'format': eFormatAddressInfo, 'alt-name': 'pc'},
- {'name': 'rflags', 'set': 0, 'bitsize': 32,
- 'encoding': eEncodingUint, 'format': eFormatHex},
- {'name': 'cs', 'set': 0, 'bitsize': 32,
- 'encoding': eEncodingUint, 'format': eFormatHex},
- {'name': 'ss', 'set': 0, 'bitsize': 32,
- 'encoding': eEncodingUint, 'format': eFormatHex},
- {'name': 'ds', 'set': 0, 'bitsize': 32,
- 'encoding': eEncodingUint, 'format': eFormatHex},
- {'name': 'es', 'set': 0, 'bitsize': 32,
- 'encoding': eEncodingUint, 'format': eFormatHex},
- {'name': 'fs', 'set': 0, 'bitsize': 32,
- 'encoding': eEncodingUint, 'format': eFormatHex},
- {'name': 'gs', 'set': 0, 'bitsize': 32,
- 'encoding': eEncodingUint, 'format': eFormatHex},
- {'name': 'stmm0',
- 'set': 1,
- 'bitsize': 80,
- 'encoding': eEncodingVector,
- 'format': eFormatVectorOfUInt8},
- {'name': 'stmm1',
- 'set': 1,
- 'bitsize': 80,
- 'encoding': eEncodingVector,
- 'format': eFormatVectorOfUInt8},
- {'name': 'stmm2',
- 'set': 1,
- 'bitsize': 80,
- 'encoding': eEncodingVector,
- 'format': eFormatVectorOfUInt8},
- {'name': 'stmm3',
- 'set': 1,
- 'bitsize': 80,
- 'encoding': eEncodingVector,
- 'format': eFormatVectorOfUInt8},
- {'name': 'stmm4',
- 'set': 1,
- 'bitsize': 80,
- 'encoding': eEncodingVector,
- 'format': eFormatVectorOfUInt8},
- {'name': 'stmm5',
- 'set': 1,
- 'bitsize': 80,
- 'encoding': eEncodingVector,
- 'format': eFormatVectorOfUInt8},
- {'name': 'stmm6',
- 'set': 1,
- 'bitsize': 80,
- 'encoding': eEncodingVector,
- 'format': eFormatVectorOfUInt8},
- {'name': 'stmm7',
- 'set': 1,
- 'bitsize': 80,
- 'encoding': eEncodingVector,
- 'format': eFormatVectorOfUInt8},
- {'name': 'fctrl', 'set': 1, 'bitsize': 32,
- 'encoding': eEncodingUint, 'format': eFormatHex},
- {'name': 'fstat', 'set': 1, 'bitsize': 32,
- 'encoding': eEncodingUint, 'format': eFormatHex},
- {'name': 'ftag', 'set': 1, 'bitsize': 32,
- 'encoding': eEncodingUint, 'format': eFormatHex},
- {'name': 'fiseg', 'set': 1, 'bitsize': 32,
- 'encoding': eEncodingUint, 'format': eFormatHex},
- {'name': 'fioff', 'set': 1, 'bitsize': 32,
- 'encoding': eEncodingUint, 'format': eFormatHex},
- {'name': 'foseg', 'set': 1, 'bitsize': 32,
- 'encoding': eEncodingUint, 'format': eFormatHex},
- {'name': 'fooff', 'set': 1, 'bitsize': 32,
- 'encoding': eEncodingUint, 'format': eFormatHex},
- {'name': 'fop', 'set': 1, 'bitsize': 32,
- 'encoding': eEncodingUint, 'format': eFormatHex},
- {'name': 'xmm0',
- 'set': 1,
- 'bitsize': 128,
- 'encoding': eEncodingVector,
- 'format': eFormatVectorOfUInt8},
- {'name': 'xmm1',
- 'set': 1,
- 'bitsize': 128,
- 'encoding': eEncodingVector,
- 'format': eFormatVectorOfUInt8},
- {'name': 'xmm2',
- 'set': 1,
- 'bitsize': 128,
- 'encoding': eEncodingVector,
- 'format': eFormatVectorOfUInt8},
- {'name': 'xmm3',
- 'set': 1,
- 'bitsize': 128,
- 'encoding': eEncodingVector,
- 'format': eFormatVectorOfUInt8},
- {'name': 'xmm4',
- 'set': 1,
- 'bitsize': 128,
- 'encoding': eEncodingVector,
- 'format': eFormatVectorOfUInt8},
- {'name': 'xmm5',
- 'set': 1,
- 'bitsize': 128,
- 'encoding': eEncodingVector,
- 'format': eFormatVectorOfUInt8},
- {'name': 'xmm6',
- 'set': 1,
- 'bitsize': 128,
- 'encoding': eEncodingVector,
- 'format': eFormatVectorOfUInt8},
- {'name': 'xmm7',
- 'set': 1,
- 'bitsize': 128,
- 'encoding': eEncodingVector,
- 'format': eFormatVectorOfUInt8},
- {'name': 'xmm8',
- 'set': 1,
- 'bitsize': 128,
- 'encoding': eEncodingVector,
- 'format': eFormatVectorOfUInt8},
- {'name': 'xmm9',
- 'set': 1,
- 'bitsize': 128,
- 'encoding': eEncodingVector,
- 'format': eFormatVectorOfUInt8},
- {'name': 'xmm10',
- 'set': 1,
- 'bitsize': 128,
- 'encoding': eEncodingVector,
- 'format': eFormatVectorOfUInt8},
- {'name': 'xmm11',
- 'set': 1,
- 'bitsize': 128,
- 'encoding': eEncodingVector,
- 'format': eFormatVectorOfUInt8},
- {'name': 'xmm12',
- 'set': 1,
- 'bitsize': 128,
- 'encoding': eEncodingVector,
- 'format': eFormatVectorOfUInt8},
- {'name': 'xmm13',
- 'set': 1,
- 'bitsize': 128,
- 'encoding': eEncodingVector,
- 'format': eFormatVectorOfUInt8},
- {'name': 'xmm14',
- 'set': 1,
- 'bitsize': 128,
- 'encoding': eEncodingVector,
- 'format': eFormatVectorOfUInt8},
- {'name': 'xmm15',
- 'set': 1,
- 'bitsize': 128,
- 'encoding': eEncodingVector,
- 'format': eFormatVectorOfUInt8},
- {'name': 'mxcsr', 'set': 1, 'bitsize': 32,
- 'encoding': eEncodingUint, 'format': eFormatHex},
- # Registers that are contained in or composed of one of more other
- # registers
- {'name': 'eax',
- 'set': 0,
- 'bitsize': 32,
- 'encoding': eEncodingUint,
- 'format': eFormatHex,
- 'slice': 'rax[31:0]'},
- {'name': 'ebx',
- 'set': 0,
- 'bitsize': 32,
- 'encoding': eEncodingUint,
- 'format': eFormatHex,
- 'slice': 'rbx[31:0]'},
- {'name': 'ecx',
- 'set': 0,
- 'bitsize': 32,
- 'encoding': eEncodingUint,
- 'format': eFormatHex,
- 'slice': 'rcx[31:0]'},
- {'name': 'edx',
- 'set': 0,
- 'bitsize': 32,
- 'encoding': eEncodingUint,
- 'format': eFormatHex,
- 'slice': 'rdx[31:0]'},
- {'name': 'edi',
- 'set': 0,
- 'bitsize': 32,
- 'encoding': eEncodingUint,
- 'format': eFormatHex,
- 'slice': 'rdi[31:0]'},
- {'name': 'esi',
- 'set': 0,
- 'bitsize': 32,
- 'encoding': eEncodingUint,
- 'format': eFormatHex,
- 'slice': 'rsi[31:0]'},
- {'name': 'ebp',
- 'set': 0,
- 'bitsize': 32,
- 'encoding': eEncodingUint,
- 'format': eFormatHex,
- 'slice': 'rbp[31:0]'},
- {'name': 'esp',
- 'set': 0,
- 'bitsize': 32,
- 'encoding': eEncodingUint,
- 'format': eFormatHex,
- 'slice': 'rsp[31:0]'},
- {'name': 'r8d',
- 'set': 0,
- 'bitsize': 32,
- 'encoding': eEncodingUint,
- 'format': eFormatHex,
- 'slice': 'r8[31:0]'},
- {'name': 'r9d',
- 'set': 0,
- 'bitsize': 32,
- 'encoding': eEncodingUint,
- 'format': eFormatHex,
- 'slice': 'r9[31:0]'},
- {'name': 'r10d',
- 'set': 0,
- 'bitsize': 32,
- 'encoding': eEncodingUint,
- 'format': eFormatHex,
- 'slice': 'r10[31:0]'},
- {'name': 'r11d',
- 'set': 0,
- 'bitsize': 32,
- 'encoding': eEncodingUint,
- 'format': eFormatHex,
- 'slice': 'r11[31:0]'},
- {'name': 'r12d',
- 'set': 0,
- 'bitsize': 32,
- 'encoding': eEncodingUint,
- 'format': eFormatHex,
- 'slice': 'r12[31:0]'},
- {'name': 'r13d',
- 'set': 0,
- 'bitsize': 32,
- 'encoding': eEncodingUint,
- 'format': eFormatHex,
- 'slice': 'r13[31:0]'},
- {'name': 'r14d',
- 'set': 0,
- 'bitsize': 32,
- 'encoding': eEncodingUint,
- 'format': eFormatHex,
- 'slice': 'r14[31:0]'},
- {'name': 'r15d',
- 'set': 0,
- 'bitsize': 32,
- 'encoding': eEncodingUint,
- 'format': eFormatHex,
- 'slice': 'r15[31:0]'},
-
- {'name': 'ax',
- 'set': 0,
- 'bitsize': 16,
- 'encoding': eEncodingUint,
- 'format': eFormatHex,
- 'slice': 'rax[15:0]'},
- {'name': 'bx',
- 'set': 0,
- 'bitsize': 16,
- 'encoding': eEncodingUint,
- 'format': eFormatHex,
- 'slice': 'rbx[15:0]'},
- {'name': 'cx',
- 'set': 0,
- 'bitsize': 16,
- 'encoding': eEncodingUint,
- 'format': eFormatHex,
- 'slice': 'rcx[15:0]'},
- {'name': 'dx',
- 'set': 0,
- 'bitsize': 16,
- 'encoding': eEncodingUint,
- 'format': eFormatHex,
- 'slice': 'rdx[15:0]'},
- {'name': 'di',
- 'set': 0,
- 'bitsize': 16,
- 'encoding': eEncodingUint,
- 'format': eFormatHex,
- 'slice': 'rdi[15:0]'},
- {'name': 'si',
- 'set': 0,
- 'bitsize': 16,
- 'encoding': eEncodingUint,
- 'format': eFormatHex,
- 'slice': 'rsi[15:0]'},
- {'name': 'bp',
- 'set': 0,
- 'bitsize': 16,
- 'encoding': eEncodingUint,
- 'format': eFormatHex,
- 'slice': 'rbp[15:0]'},
- {'name': 'sp',
- 'set': 0,
- 'bitsize': 16,
- 'encoding': eEncodingUint,
- 'format': eFormatHex,
- 'slice': 'rsp[15:0]'},
- {'name': 'r8w',
- 'set': 0,
- 'bitsize': 16,
- 'encoding': eEncodingUint,
- 'format': eFormatHex,
- 'slice': 'r8[15:0]'},
- {'name': 'r9w',
- 'set': 0,
- 'bitsize': 16,
- 'encoding': eEncodingUint,
- 'format': eFormatHex,
- 'slice': 'r9[15:0]'},
- {'name': 'r10w',
- 'set': 0,
- 'bitsize': 16,
- 'encoding': eEncodingUint,
- 'format': eFormatHex,
- 'slice': 'r10[15:0]'},
- {'name': 'r11w',
- 'set': 0,
- 'bitsize': 16,
- 'encoding': eEncodingUint,
- 'format': eFormatHex,
- 'slice': 'r11[15:0]'},
- {'name': 'r12w',
- 'set': 0,
- 'bitsize': 16,
- 'encoding': eEncodingUint,
- 'format': eFormatHex,
- 'slice': 'r12[15:0]'},
- {'name': 'r13w',
- 'set': 0,
- 'bitsize': 16,
- 'encoding': eEncodingUint,
- 'format': eFormatHex,
- 'slice': 'r13[15:0]'},
- {'name': 'r14w',
- 'set': 0,
- 'bitsize': 16,
- 'encoding': eEncodingUint,
- 'format': eFormatHex,
- 'slice': 'r14[15:0]'},
- {'name': 'r15w',
- 'set': 0,
- 'bitsize': 16,
- 'encoding': eEncodingUint,
- 'format': eFormatHex,
- 'slice': 'r15[15:0]'},
-
- {'name': 'ah',
- 'set': 0,
- 'bitsize': 8,
- 'encoding': eEncodingUint,
- 'format': eFormatHex,
- 'slice': 'rax[15:8]'},
- {'name': 'bh',
- 'set': 0,
- 'bitsize': 8,
- 'encoding': eEncodingUint,
- 'format': eFormatHex,
- 'slice': 'rbx[15:8]'},
- {'name': 'ch',
- 'set': 0,
- 'bitsize': 8,
- 'encoding': eEncodingUint,
- 'format': eFormatHex,
- 'slice': 'rcx[15:8]'},
- {'name': 'dh',
- 'set': 0,
- 'bitsize': 8,
- 'encoding': eEncodingUint,
- 'format': eFormatHex,
- 'slice': 'rdx[15:8]'},
-
- {'name': 'al',
- 'set': 0,
- 'bitsize': 8,
- 'encoding': eEncodingUint,
- 'format': eFormatHex,
- 'slice': 'rax[7:0]'},
- {'name': 'bl',
- 'set': 0,
- 'bitsize': 8,
- 'encoding': eEncodingUint,
- 'format': eFormatHex,
- 'slice': 'rbx[7:0]'},
- {'name': 'cl',
- 'set': 0,
- 'bitsize': 8,
- 'encoding': eEncodingUint,
- 'format': eFormatHex,
- 'slice': 'rcx[7:0]'},
- {'name': 'dl',
- 'set': 0,
- 'bitsize': 8,
- 'encoding': eEncodingUint,
- 'format': eFormatHex,
- 'slice': 'rdx[7:0]'},
- {'name': 'dil',
- 'set': 0,
- 'bitsize': 8,
- 'encoding': eEncodingUint,
- 'format': eFormatHex,
- 'slice': 'rdi[7:0]'},
- {'name': 'sil',
- 'set': 0,
- 'bitsize': 8,
- 'encoding': eEncodingUint,
- 'format': eFormatHex,
- 'slice': 'rsi[7:0]'},
- {'name': 'bpl',
- 'set': 0,
- 'bitsize': 8,
- 'encoding': eEncodingUint,
- 'format': eFormatHex,
- 'slice': 'rbp[7:0]'},
- {'name': 'spl',
- 'set': 0,
- 'bitsize': 8,
- 'encoding': eEncodingUint,
- 'format': eFormatHex,
- 'slice': 'rsp[7:0]'},
- {'name': 'r8l',
- 'set': 0,
- 'bitsize': 8,
- 'encoding': eEncodingUint,
- 'format': eFormatHex,
- 'slice': 'r8[7:0]'},
- {'name': 'r9l',
- 'set': 0,
- 'bitsize': 8,
- 'encoding': eEncodingUint,
- 'format': eFormatHex,
- 'slice': 'r9[7:0]'},
- {'name': 'r10l',
- 'set': 0,
- 'bitsize': 8,
- 'encoding': eEncodingUint,
- 'format': eFormatHex,
- 'slice': 'r10[7:0]'},
- {'name': 'r11l',
- 'set': 0,
- 'bitsize': 8,
- 'encoding': eEncodingUint,
- 'format': eFormatHex,
- 'slice': 'r11[7:0]'},
- {'name': 'r12l',
- 'set': 0,
- 'bitsize': 8,
- 'encoding': eEncodingUint,
- 'format': eFormatHex,
- 'slice': 'r12[7:0]'},
- {'name': 'r13l',
- 'set': 0,
- 'bitsize': 8,
- 'encoding': eEncodingUint,
- 'format': eFormatHex,
- 'slice': 'r13[7:0]'},
- {'name': 'r14l',
- 'set': 0,
- 'bitsize': 8,
- 'encoding': eEncodingUint,
- 'format': eFormatHex,
- 'slice': 'r14[7:0]'},
- {'name': 'r15l',
- 'set': 0,
- 'bitsize': 8,
- 'encoding': eEncodingUint,
- 'format': eFormatHex,
- 'slice': 'r15[7:0]'},
-]
-
-g_target_definition = None
-
-
-def get_target_definition():
- global g_target_definition
- if g_target_definition is None:
- g_target_definition = {}
- offset = 0
- for reg_info in x86_64_register_infos:
- reg_name = reg_info['name']
-
- # Only fill in the offset if there is no 'slice' in the register
- # info
- if 'slice' not in reg_info and 'composite' not in reg_info:
- reg_info['offset'] = offset
- offset += reg_info['bitsize'] / 8
-
- # Set the GCC/DWARF register number for this register if it has one
- reg_num = get_reg_num(name_to_gcc_dwarf_regnum, reg_name)
- if reg_num != LLDB_INVALID_REGNUM:
- reg_info['gcc'] = reg_num
- reg_info['dwarf'] = reg_num
-
- # Set the generic register number for this register if it has one
- reg_num = get_reg_num(name_to_generic_regnum, reg_name)
- if reg_num != LLDB_INVALID_REGNUM:
- reg_info['generic'] = reg_num
-
- # Set the GDB register number for this register if it has one
- reg_num = get_reg_num(name_to_gdb_regnum, reg_name)
- if reg_num != LLDB_INVALID_REGNUM:
- reg_info['gdb'] = reg_num
-
- g_target_definition['sets'] = [
- 'General Purpose Registers',
- 'Floating Point Registers']
- g_target_definition['registers'] = x86_64_register_infos
- g_target_definition[
- 'host-info'] = {'triple': 'x86_64-apple-macosx', 'endian': eByteOrderLittle}
- g_target_definition['g-packet-size'] = offset
- return g_target_definition
-
-
-def get_dynamic_setting(target, setting_name):
- if setting_name == 'gdb-server-target-definition':
- return get_target_definition()