177e67a51acb825d79d25be687c085833713d5205Greg Clayton#!/usr/bin/python
277e67a51acb825d79d25be687c085833713d5205Greg Clayton
377e67a51acb825d79d25be687c085833713d5205Greg Clayton#----------------------------------------------------------------------
477e67a51acb825d79d25be687c085833713d5205Greg Clayton# Be sure to add the python path that points to the LLDB shared library.
577e67a51acb825d79d25be687c085833713d5205Greg Clayton#
677e67a51acb825d79d25be687c085833713d5205Greg Clayton# # To use this in the embedded python interpreter using "lldb" just
777e67a51acb825d79d25be687c085833713d5205Greg Clayton# import it with the full path using the "command script import"
877e67a51acb825d79d25be687c085833713d5205Greg Clayton# command
977e67a51acb825d79d25be687c085833713d5205Greg Clayton#   (lldb) command script import /path/to/cmdtemplate.py
1077e67a51acb825d79d25be687c085833713d5205Greg Clayton#----------------------------------------------------------------------
1177e67a51acb825d79d25be687c085833713d5205Greg Clayton
1277e67a51acb825d79d25be687c085833713d5205Greg Claytonimport commands
1377e67a51acb825d79d25be687c085833713d5205Greg Claytonimport platform
1477e67a51acb825d79d25be687c085833713d5205Greg Claytonimport os
150b541255798a762bc24b1a1aab9bedab9f8744ddGreg Claytonimport re
16ecced8806156d010299dea1c6309f575965f3a36Greg Claytonimport signal
1777e67a51acb825d79d25be687c085833713d5205Greg Claytonimport sys
1877e67a51acb825d79d25be687c085833713d5205Greg Clayton
1977e67a51acb825d79d25be687c085833713d5205Greg Claytontry:
2077e67a51acb825d79d25be687c085833713d5205Greg Clayton    # Just try for LLDB in case PYTHONPATH is already correctly setup
2177e67a51acb825d79d25be687c085833713d5205Greg Clayton    import lldb
2277e67a51acb825d79d25be687c085833713d5205Greg Claytonexcept ImportError:
2377e67a51acb825d79d25be687c085833713d5205Greg Clayton    lldb_python_dirs = list()
2477e67a51acb825d79d25be687c085833713d5205Greg Clayton    # lldb is not in the PYTHONPATH, try some defaults for the current platform
2577e67a51acb825d79d25be687c085833713d5205Greg Clayton    platform_system = platform.system()
2677e67a51acb825d79d25be687c085833713d5205Greg Clayton    if platform_system == 'Darwin':
2777e67a51acb825d79d25be687c085833713d5205Greg Clayton        # On Darwin, try the currently selected Xcode directory
2877e67a51acb825d79d25be687c085833713d5205Greg Clayton        xcode_dir = commands.getoutput("xcode-select --print-path")
2977e67a51acb825d79d25be687c085833713d5205Greg Clayton        if xcode_dir:
3077e67a51acb825d79d25be687c085833713d5205Greg Clayton            lldb_python_dirs.append(os.path.realpath(xcode_dir + '/../SharedFrameworks/LLDB.framework/Resources/Python'))
3177e67a51acb825d79d25be687c085833713d5205Greg Clayton            lldb_python_dirs.append(xcode_dir + '/Library/PrivateFrameworks/LLDB.framework/Resources/Python')
3277e67a51acb825d79d25be687c085833713d5205Greg Clayton        lldb_python_dirs.append('/System/Library/PrivateFrameworks/LLDB.framework/Resources/Python')
3377e67a51acb825d79d25be687c085833713d5205Greg Clayton    success = False
3477e67a51acb825d79d25be687c085833713d5205Greg Clayton    for lldb_python_dir in lldb_python_dirs:
3577e67a51acb825d79d25be687c085833713d5205Greg Clayton        if os.path.exists(lldb_python_dir):
3677e67a51acb825d79d25be687c085833713d5205Greg Clayton            if not (sys.path.__contains__(lldb_python_dir)):
3777e67a51acb825d79d25be687c085833713d5205Greg Clayton                sys.path.append(lldb_python_dir)
3877e67a51acb825d79d25be687c085833713d5205Greg Clayton                try:
3977e67a51acb825d79d25be687c085833713d5205Greg Clayton                    import lldb
4077e67a51acb825d79d25be687c085833713d5205Greg Clayton                except ImportError:
4177e67a51acb825d79d25be687c085833713d5205Greg Clayton                    pass
4277e67a51acb825d79d25be687c085833713d5205Greg Clayton                else:
4377e67a51acb825d79d25be687c085833713d5205Greg Clayton                    print 'imported lldb from: "%s"' % (lldb_python_dir)
4477e67a51acb825d79d25be687c085833713d5205Greg Clayton                    success = True
4577e67a51acb825d79d25be687c085833713d5205Greg Clayton                    break
4677e67a51acb825d79d25be687c085833713d5205Greg Clayton    if not success:
4777e67a51acb825d79d25be687c085833713d5205Greg Clayton        print "error: couldn't locate the 'lldb' module, please set PYTHONPATH correctly"
4877e67a51acb825d79d25be687c085833713d5205Greg Clayton        sys.exit(1)
4977e67a51acb825d79d25be687c085833713d5205Greg Clayton
5077e67a51acb825d79d25be687c085833713d5205Greg Claytonimport commands
5177e67a51acb825d79d25be687c085833713d5205Greg Claytonimport optparse
5277e67a51acb825d79d25be687c085833713d5205Greg Claytonimport shlex
5377e67a51acb825d79d25be687c085833713d5205Greg Claytonimport time
5477e67a51acb825d79d25be687c085833713d5205Greg Clayton
550b541255798a762bc24b1a1aab9bedab9f8744ddGreg Claytondef regex_option_callback(option, opt_str, value, parser):
560b541255798a762bc24b1a1aab9bedab9f8744ddGreg Clayton    if opt_str == "--std":
570b541255798a762bc24b1a1aab9bedab9f8744ddGreg Clayton        value = '^std::'
580b541255798a762bc24b1a1aab9bedab9f8744ddGreg Clayton    regex = re.compile(value)
590b541255798a762bc24b1a1aab9bedab9f8744ddGreg Clayton    parser.values.skip_type_regexes.append (regex)
600b541255798a762bc24b1a1aab9bedab9f8744ddGreg Clayton
610b541255798a762bc24b1a1aab9bedab9f8744ddGreg Claytondef create_types_options(for_lldb_command):
620b541255798a762bc24b1a1aab9bedab9f8744ddGreg Clayton    if for_lldb_command:
630b541255798a762bc24b1a1aab9bedab9f8744ddGreg Clayton        usage = "usage: %prog [options]"
640b541255798a762bc24b1a1aab9bedab9f8744ddGreg Clayton        description='''This command will help check for padding in between
650b541255798a762bc24b1a1aab9bedab9f8744ddGreg Claytonbase classes and members in structs and classes. It will summarize the types
660b541255798a762bc24b1a1aab9bedab9f8744ddGreg Claytonand how much padding was found. If no types are specified with the --types TYPENAME
670b541255798a762bc24b1a1aab9bedab9f8744ddGreg Claytonoption, all structure and class types will be verified. If no modules are
680b541255798a762bc24b1a1aab9bedab9f8744ddGreg Claytonspecified with the --module option, only the target's main executable will be
690b541255798a762bc24b1a1aab9bedab9f8744ddGreg Claytonsearched.
700b541255798a762bc24b1a1aab9bedab9f8744ddGreg Clayton'''
710b541255798a762bc24b1a1aab9bedab9f8744ddGreg Clayton    else:
720b541255798a762bc24b1a1aab9bedab9f8744ddGreg Clayton        usage = "usage: %prog [options] EXEPATH [EXEPATH ...]"
730b541255798a762bc24b1a1aab9bedab9f8744ddGreg Clayton        description='''This command will help check for padding in between
740b541255798a762bc24b1a1aab9bedab9f8744ddGreg Claytonbase classes and members in structures and classes. It will summarize the types
750b541255798a762bc24b1a1aab9bedab9f8744ddGreg Claytonand how much padding was found. One or more paths to executable files must be
760b541255798a762bc24b1a1aab9bedab9f8744ddGreg Claytonspecified and targets will be created with these modules. If no types are
770b541255798a762bc24b1a1aab9bedab9f8744ddGreg Claytonspecified with the --types TYPENAME option, all structure and class types will
780b541255798a762bc24b1a1aab9bedab9f8744ddGreg Claytonbe verified in all specified modules.
7977e67a51acb825d79d25be687c085833713d5205Greg Clayton'''
8077e67a51acb825d79d25be687c085833713d5205Greg Clayton    parser = optparse.OptionParser(description=description, prog='framestats',usage=usage)
810b541255798a762bc24b1a1aab9bedab9f8744ddGreg Clayton    if not for_lldb_command:
820b541255798a762bc24b1a1aab9bedab9f8744ddGreg Clayton        parser.add_option('-a', '--arch', type='string', dest='arch', help='The architecture to use when creating the debug target.', default=None)
839bb6d255db5fb13c983cb0fa470248fc1242c05fGreg Clayton        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".')
8477e67a51acb825d79d25be687c085833713d5205Greg Clayton    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=[])
8577e67a51acb825d79d25be687c085833713d5205Greg Clayton    parser.add_option('-d', '--debug', action='store_true', dest='debug', help='Pause 10 seconds to wait for a debugger to attach.', default=False)
860b541255798a762bc24b1a1aab9bedab9f8744ddGreg Clayton    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=[])
870b541255798a762bc24b1a1aab9bedab9f8744ddGreg Clayton    parser.add_option('-v', '--verbose', action='store_true', dest='verbose', help='Enable verbose logging and information.', default=False)
880b541255798a762bc24b1a1aab9bedab9f8744ddGreg Clayton    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=[])
890b541255798a762bc24b1a1aab9bedab9f8744ddGreg Clayton    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=[])
9077e67a51acb825d79d25be687c085833713d5205Greg Clayton    return parser
9177e67a51acb825d79d25be687c085833713d5205Greg Clayton
920b541255798a762bc24b1a1aab9bedab9f8744ddGreg Claytondef verify_type (target, options, type):
9377e67a51acb825d79d25be687c085833713d5205Greg Clayton    print type
9477e67a51acb825d79d25be687c085833713d5205Greg Clayton    typename = type.GetName()
9577e67a51acb825d79d25be687c085833713d5205Greg Clayton    # print 'type: %s' % (typename)
960b541255798a762bc24b1a1aab9bedab9f8744ddGreg Clayton    (end_offset, padding) = verify_type_recursive (target, options, type, None, 0, 0, 0)
9777e67a51acb825d79d25be687c085833713d5205Greg Clayton    byte_size = type.GetByteSize()
9877e67a51acb825d79d25be687c085833713d5205Greg Clayton    # if end_offset < byte_size:
9977e67a51acb825d79d25be687c085833713d5205Greg Clayton    #     last_member_padding = byte_size - end_offset
10077e67a51acb825d79d25be687c085833713d5205Greg Clayton    #     print '%+4u <%u> padding' % (end_offset, last_member_padding)
10177e67a51acb825d79d25be687c085833713d5205Greg Clayton    #     padding += last_member_padding
10277e67a51acb825d79d25be687c085833713d5205Greg Clayton    print 'Total byte size: %u' % (byte_size)
10377e67a51acb825d79d25be687c085833713d5205Greg Clayton    print 'Total pad bytes: %u' % (padding)
10477e67a51acb825d79d25be687c085833713d5205Greg Clayton    if padding > 0:
10577e67a51acb825d79d25be687c085833713d5205Greg Clayton        print 'Padding percentage: %2.2f %%' % ((float(padding) / float(byte_size)) * 100.0)
106e4513b950e0e31783bff8ecece8723eb1d18901bGreg Clayton    print
10777e67a51acb825d79d25be687c085833713d5205Greg Clayton
1080b541255798a762bc24b1a1aab9bedab9f8744ddGreg Claytondef verify_type_recursive (target, options, type, member_name, depth, base_offset, padding):
10977e67a51acb825d79d25be687c085833713d5205Greg Clayton    prev_end_offset = base_offset
11077e67a51acb825d79d25be687c085833713d5205Greg Clayton    typename = type.GetName()
11177e67a51acb825d79d25be687c085833713d5205Greg Clayton    byte_size = type.GetByteSize()
11277e67a51acb825d79d25be687c085833713d5205Greg Clayton    if member_name and member_name != typename:
1130b541255798a762bc24b1a1aab9bedab9f8744ddGreg Clayton        print '%+4u <%3u> %s%s %s;' % (base_offset, byte_size, '    ' * depth, typename, member_name)
11477e67a51acb825d79d25be687c085833713d5205Greg Clayton    else:
1150b541255798a762bc24b1a1aab9bedab9f8744ddGreg Clayton        print '%+4u {%3u} %s%s' % (base_offset, byte_size, '    ' * depth, typename)
11677e67a51acb825d79d25be687c085833713d5205Greg Clayton
1170b541255798a762bc24b1a1aab9bedab9f8744ddGreg Clayton    for type_regex in options.skip_type_regexes:
1180b541255798a762bc24b1a1aab9bedab9f8744ddGreg Clayton        match = type_regex.match (typename)
1190b541255798a762bc24b1a1aab9bedab9f8744ddGreg Clayton        if match:
1200b541255798a762bc24b1a1aab9bedab9f8744ddGreg Clayton            return (base_offset + byte_size, padding)
1210b541255798a762bc24b1a1aab9bedab9f8744ddGreg Clayton
12277e67a51acb825d79d25be687c085833713d5205Greg Clayton    members = type.members
12377e67a51acb825d79d25be687c085833713d5205Greg Clayton    if members:
12477e67a51acb825d79d25be687c085833713d5205Greg Clayton        for member_idx, member in enumerate(members):
12577e67a51acb825d79d25be687c085833713d5205Greg Clayton            member_type = member.GetType()
12677e67a51acb825d79d25be687c085833713d5205Greg Clayton            member_canonical_type = member_type.GetCanonicalType()
12777e67a51acb825d79d25be687c085833713d5205Greg Clayton            member_type_class = member_canonical_type.GetTypeClass()
12877e67a51acb825d79d25be687c085833713d5205Greg Clayton            member_name = member.GetName()
12977e67a51acb825d79d25be687c085833713d5205Greg Clayton            member_offset = member.GetOffsetInBytes()
13077e67a51acb825d79d25be687c085833713d5205Greg Clayton            member_total_offset = member_offset + base_offset
13177e67a51acb825d79d25be687c085833713d5205Greg Clayton            member_byte_size = member_type.GetByteSize()
1320b541255798a762bc24b1a1aab9bedab9f8744ddGreg Clayton            member_is_class_or_struct = False
13377e67a51acb825d79d25be687c085833713d5205Greg Clayton            if member_type_class == lldb.eTypeClassStruct or member_type_class == lldb.eTypeClassClass:
1340b541255798a762bc24b1a1aab9bedab9f8744ddGreg Clayton                member_is_class_or_struct = True
13577e67a51acb825d79d25be687c085833713d5205Greg Clayton            if member_idx == 0 and member_offset == target.GetAddressByteSize() and type.IsPolymorphicClass():
13677e67a51acb825d79d25be687c085833713d5205Greg Clayton                ptr_size = target.GetAddressByteSize()
13777e67a51acb825d79d25be687c085833713d5205Greg Clayton                print '%+4u <%3u> %s__vtbl_ptr_type * _vptr;' % (prev_end_offset, ptr_size, '    ' * (depth + 1))
13877e67a51acb825d79d25be687c085833713d5205Greg Clayton                prev_end_offset = ptr_size
13977e67a51acb825d79d25be687c085833713d5205Greg Clayton            else:
14077e67a51acb825d79d25be687c085833713d5205Greg Clayton                if prev_end_offset < member_total_offset:
14177e67a51acb825d79d25be687c085833713d5205Greg Clayton                    member_padding = member_total_offset - prev_end_offset
14277e67a51acb825d79d25be687c085833713d5205Greg Clayton                    padding = padding + member_padding
14377e67a51acb825d79d25be687c085833713d5205Greg Clayton                    print '%+4u <%3u> %s<PADDING>' % (prev_end_offset, member_padding, '    ' * (depth + 1))
14477e67a51acb825d79d25be687c085833713d5205Greg Clayton
1450b541255798a762bc24b1a1aab9bedab9f8744ddGreg Clayton            if member_is_class_or_struct:
1460b541255798a762bc24b1a1aab9bedab9f8744ddGreg Clayton                (prev_end_offset, padding) = verify_type_recursive (target, options, member_canonical_type, member_name, depth + 1, member_total_offset, padding)
14777e67a51acb825d79d25be687c085833713d5205Greg Clayton            else:
14877e67a51acb825d79d25be687c085833713d5205Greg Clayton                prev_end_offset = member_total_offset + member_byte_size
1490b541255798a762bc24b1a1aab9bedab9f8744ddGreg Clayton                member_typename = member_type.GetName()
15077e67a51acb825d79d25be687c085833713d5205Greg Clayton                if member.IsBitfield():
1510b541255798a762bc24b1a1aab9bedab9f8744ddGreg Clayton                    print '%+4u <%3u> %s%s:%u %s;' % (member_total_offset, member_byte_size, '    ' * (depth + 1), member_typename, member.GetBitfieldSizeInBits(), member_name)
15277e67a51acb825d79d25be687c085833713d5205Greg Clayton                else:
1530b541255798a762bc24b1a1aab9bedab9f8744ddGreg Clayton                    print '%+4u <%3u> %s%s %s;' % (member_total_offset, member_byte_size, '    ' * (depth + 1), member_typename, member_name)
15477e67a51acb825d79d25be687c085833713d5205Greg Clayton
15577e67a51acb825d79d25be687c085833713d5205Greg Clayton        if prev_end_offset < byte_size:
15677e67a51acb825d79d25be687c085833713d5205Greg Clayton            last_member_padding = byte_size - prev_end_offset
15777e67a51acb825d79d25be687c085833713d5205Greg Clayton            print '%+4u <%3u> %s<PADDING>' % (prev_end_offset, last_member_padding, '    ' * (depth + 1))
15877e67a51acb825d79d25be687c085833713d5205Greg Clayton            padding += last_member_padding
15977e67a51acb825d79d25be687c085833713d5205Greg Clayton    else:
16077e67a51acb825d79d25be687c085833713d5205Greg Clayton        if type.IsPolymorphicClass():
16177e67a51acb825d79d25be687c085833713d5205Greg Clayton            ptr_size = target.GetAddressByteSize()
16277e67a51acb825d79d25be687c085833713d5205Greg Clayton            print '%+4u <%3u> %s__vtbl_ptr_type * _vptr;' % (prev_end_offset, ptr_size, '    ' * (depth + 1))
16377e67a51acb825d79d25be687c085833713d5205Greg Clayton            prev_end_offset = ptr_size
1640b541255798a762bc24b1a1aab9bedab9f8744ddGreg Clayton        prev_end_offset = base_offset + byte_size
16577e67a51acb825d79d25be687c085833713d5205Greg Clayton
16677e67a51acb825d79d25be687c085833713d5205Greg Clayton    return (prev_end_offset, padding)
16777e67a51acb825d79d25be687c085833713d5205Greg Clayton
1680b541255798a762bc24b1a1aab9bedab9f8744ddGreg Claytondef check_padding_command (debugger, command, result, dict):
16977e67a51acb825d79d25be687c085833713d5205Greg Clayton    # Use the Shell Lexer to properly parse up command options just like a
17077e67a51acb825d79d25be687c085833713d5205Greg Clayton    # shell would
17177e67a51acb825d79d25be687c085833713d5205Greg Clayton    command_args = shlex.split(command)
1720b541255798a762bc24b1a1aab9bedab9f8744ddGreg Clayton    parser = create_types_options(True)
17377e67a51acb825d79d25be687c085833713d5205Greg Clayton    try:
17477e67a51acb825d79d25be687c085833713d5205Greg Clayton        (options, args) = parser.parse_args(command_args)
17577e67a51acb825d79d25be687c085833713d5205Greg Clayton    except:
17677e67a51acb825d79d25be687c085833713d5205Greg Clayton        # if you don't handle exceptions, passing an incorrect argument to the OptionParser will cause LLDB to exit
17777e67a51acb825d79d25be687c085833713d5205Greg Clayton        # (courtesy of OptParse dealing with argument errors by throwing SystemExit)
17877e67a51acb825d79d25be687c085833713d5205Greg Clayton        result.SetStatus (lldb.eReturnStatusFailed)
17977e67a51acb825d79d25be687c085833713d5205Greg Clayton        return "option parsing failed" # returning a string is the same as returning an error whose description is the string
1800b541255798a762bc24b1a1aab9bedab9f8744ddGreg Clayton    verify_types(options, debugger.GetSelectedTarget(), command_args)
1810b541255798a762bc24b1a1aab9bedab9f8744ddGreg Clayton
1820b541255798a762bc24b1a1aab9bedab9f8744ddGreg Clayton
1830b541255798a762bc24b1a1aab9bedab9f8744ddGreg Claytondef verify_types (target, options):
1840b541255798a762bc24b1a1aab9bedab9f8744ddGreg Clayton
1850b541255798a762bc24b1a1aab9bedab9f8744ddGreg Clayton    if not target:
1860b541255798a762bc24b1a1aab9bedab9f8744ddGreg Clayton        print 'error: invalid target'
1870b541255798a762bc24b1a1aab9bedab9f8744ddGreg Clayton        return
1880b541255798a762bc24b1a1aab9bedab9f8744ddGreg Clayton
1890b541255798a762bc24b1a1aab9bedab9f8744ddGreg Clayton    modules = list()
1900b541255798a762bc24b1a1aab9bedab9f8744ddGreg Clayton    if len(options.modules) == 0:
1910b541255798a762bc24b1a1aab9bedab9f8744ddGreg Clayton        # Append just the main executable if nothing was specified
1920b541255798a762bc24b1a1aab9bedab9f8744ddGreg Clayton        module = target.modules[0]
1930b541255798a762bc24b1a1aab9bedab9f8744ddGreg Clayton        if module:
1940b541255798a762bc24b1a1aab9bedab9f8744ddGreg Clayton            modules.append(module)
1950b541255798a762bc24b1a1aab9bedab9f8744ddGreg Clayton    else:
1960b541255798a762bc24b1a1aab9bedab9f8744ddGreg Clayton        for module_name in options.modules:
1970b541255798a762bc24b1a1aab9bedab9f8744ddGreg Clayton            module = lldb.target.module[module_name]
1980b541255798a762bc24b1a1aab9bedab9f8744ddGreg Clayton            if module:
1990b541255798a762bc24b1a1aab9bedab9f8744ddGreg Clayton                modules.append(module)
2000b541255798a762bc24b1a1aab9bedab9f8744ddGreg Clayton
2010b541255798a762bc24b1a1aab9bedab9f8744ddGreg Clayton    if modules:
2020b541255798a762bc24b1a1aab9bedab9f8744ddGreg Clayton        for module in modules:
2030b541255798a762bc24b1a1aab9bedab9f8744ddGreg Clayton            print 'module: %s' % (module.file)
2040b541255798a762bc24b1a1aab9bedab9f8744ddGreg Clayton            if options.typenames:
2050b541255798a762bc24b1a1aab9bedab9f8744ddGreg Clayton                for typename in options.typenames:
2060b541255798a762bc24b1a1aab9bedab9f8744ddGreg Clayton                    types = module.FindTypes(typename)
2070b541255798a762bc24b1a1aab9bedab9f8744ddGreg Clayton                    if types.GetSize():
2080b541255798a762bc24b1a1aab9bedab9f8744ddGreg Clayton                        print 'Found %u types matching "%s" in "%s"' % (len(types), typename, module.file)
2090b541255798a762bc24b1a1aab9bedab9f8744ddGreg Clayton                        for type in types:
2100b541255798a762bc24b1a1aab9bedab9f8744ddGreg Clayton                            verify_type (target, options, type)
2110b541255798a762bc24b1a1aab9bedab9f8744ddGreg Clayton                    else:
2120b541255798a762bc24b1a1aab9bedab9f8744ddGreg Clayton                        print 'error: no type matches "%s" in "%s"' % (typename, module.file)
2130b541255798a762bc24b1a1aab9bedab9f8744ddGreg Clayton            else:
2140b541255798a762bc24b1a1aab9bedab9f8744ddGreg Clayton                types = module.GetTypes(lldb.eTypeClassClass | lldb.eTypeClassStruct)
2150b541255798a762bc24b1a1aab9bedab9f8744ddGreg Clayton                print 'Found %u types in "%s"' % (len(types), module.file)
2160b541255798a762bc24b1a1aab9bedab9f8744ddGreg Clayton                for type in types:
2170b541255798a762bc24b1a1aab9bedab9f8744ddGreg Clayton                    verify_type (target, options, type)
2180b541255798a762bc24b1a1aab9bedab9f8744ddGreg Clayton    else:
2190b541255798a762bc24b1a1aab9bedab9f8744ddGreg Clayton        print 'error: no modules'
2200b541255798a762bc24b1a1aab9bedab9f8744ddGreg Clayton
2210b541255798a762bc24b1a1aab9bedab9f8744ddGreg Claytonif __name__ == '__main__':
2220b541255798a762bc24b1a1aab9bedab9f8744ddGreg Clayton    debugger = lldb.SBDebugger.Create()
2230b541255798a762bc24b1a1aab9bedab9f8744ddGreg Clayton    parser = create_types_options(False)
2240b541255798a762bc24b1a1aab9bedab9f8744ddGreg Clayton
2250b541255798a762bc24b1a1aab9bedab9f8744ddGreg Clayton    # try:
2260b541255798a762bc24b1a1aab9bedab9f8744ddGreg Clayton    (options, args) = parser.parse_args(sys.argv[1:])
2270b541255798a762bc24b1a1aab9bedab9f8744ddGreg Clayton    # except:
2280b541255798a762bc24b1a1aab9bedab9f8744ddGreg Clayton    #     print "error: option parsing failed"
2290b541255798a762bc24b1a1aab9bedab9f8744ddGreg Clayton    #     sys.exit(1)
23077e67a51acb825d79d25be687c085833713d5205Greg Clayton
231ecced8806156d010299dea1c6309f575965f3a36Greg Clayton    if options.debug:
232ecced8806156d010299dea1c6309f575965f3a36Greg Clayton        print "Waiting for debugger to attach to process %d" % os.getpid()
233ecced8806156d010299dea1c6309f575965f3a36Greg Clayton        os.kill(os.getpid(), signal.SIGSTOP)
234ecced8806156d010299dea1c6309f575965f3a36Greg Clayton
23577e67a51acb825d79d25be687c085833713d5205Greg Clayton    for path in args:
23677e67a51acb825d79d25be687c085833713d5205Greg Clayton    # in a command - the lldb.* convenience variables are not to be used
23777e67a51acb825d79d25be687c085833713d5205Greg Clayton    # and their values (if any) are undefined
23877e67a51acb825d79d25be687c085833713d5205Greg Clayton    # this is the best practice to access those objects from within a command
23977e67a51acb825d79d25be687c085833713d5205Greg Clayton        error = lldb.SBError()
24077e67a51acb825d79d25be687c085833713d5205Greg Clayton        target = debugger.CreateTarget (path,
24177e67a51acb825d79d25be687c085833713d5205Greg Clayton                                        options.arch,
24277e67a51acb825d79d25be687c085833713d5205Greg Clayton                                        options.platform,
24377e67a51acb825d79d25be687c085833713d5205Greg Clayton                                        True,
24477e67a51acb825d79d25be687c085833713d5205Greg Clayton                                        error)
24577e67a51acb825d79d25be687c085833713d5205Greg Clayton        if error.Fail():
24677e67a51acb825d79d25be687c085833713d5205Greg Clayton            print error.GetCString()
24777e67a51acb825d79d25be687c085833713d5205Greg Clayton            continue
2480b541255798a762bc24b1a1aab9bedab9f8744ddGreg Clayton        verify_types (target, options)
24977e67a51acb825d79d25be687c085833713d5205Greg Clayton
25077e67a51acb825d79d25be687c085833713d5205Greg Claytonelif getattr(lldb, 'debugger', None):
2510b541255798a762bc24b1a1aab9bedab9f8744ddGreg Clayton    lldb.debugger.HandleCommand('command script add -f types.check_padding_command check_padding')
2520b541255798a762bc24b1a1aab9bedab9f8744ddGreg Clayton    print '"check_padding" command installed, use the "--help" option for detailed help'