154ce4db571fef8c5e619fe807f6c75d25c514d8fGreg Clayton#!/usr/bin/python
254ce4db571fef8c5e619fe807f6c75d25c514d8fGreg Clayton
354ce4db571fef8c5e619fe807f6c75d25c514d8fGreg Clayton#----------------------------------------------------------------------
454ce4db571fef8c5e619fe807f6c75d25c514d8fGreg Clayton# For the shells csh, tcsh:
554ce4db571fef8c5e619fe807f6c75d25c514d8fGreg Clayton#   ( setenv PYTHONPATH /Applications/Xcode.app/Contents/SharedFrameworks/LLDB.framework/Resources/Python ; ./globals.py <path> [<path> ...])
654ce4db571fef8c5e619fe807f6c75d25c514d8fGreg Clayton#
754ce4db571fef8c5e619fe807f6c75d25c514d8fGreg Clayton# For the shells sh, bash:
854ce4db571fef8c5e619fe807f6c75d25c514d8fGreg Clayton#   PYTHONPATH=/Applications/Xcode.app/Contents/SharedFrameworks/LLDB.framework/Resources/Python ./globals.py <path> [<path> ...]
954ce4db571fef8c5e619fe807f6c75d25c514d8fGreg Clayton#----------------------------------------------------------------------
1054ce4db571fef8c5e619fe807f6c75d25c514d8fGreg Clayton
1154ce4db571fef8c5e619fe807f6c75d25c514d8fGreg Claytonimport lldb
1254ce4db571fef8c5e619fe807f6c75d25c514d8fGreg Claytonimport commands
1354ce4db571fef8c5e619fe807f6c75d25c514d8fGreg Claytonimport optparse
1454ce4db571fef8c5e619fe807f6c75d25c514d8fGreg Claytonimport os
1554ce4db571fef8c5e619fe807f6c75d25c514d8fGreg Claytonimport shlex
1654ce4db571fef8c5e619fe807f6c75d25c514d8fGreg Claytonimport sys
1754ce4db571fef8c5e619fe807f6c75d25c514d8fGreg Clayton
1854ce4db571fef8c5e619fe807f6c75d25c514d8fGreg Claytondef get_globals(raw_path, options):
1954ce4db571fef8c5e619fe807f6c75d25c514d8fGreg Clayton    error = lldb.SBError()
2054ce4db571fef8c5e619fe807f6c75d25c514d8fGreg Clayton    # Resolve the path if needed
2154ce4db571fef8c5e619fe807f6c75d25c514d8fGreg Clayton    path = os.path.expanduser(raw_path)
2254ce4db571fef8c5e619fe807f6c75d25c514d8fGreg Clayton    # Create a target using path + options
2354ce4db571fef8c5e619fe807f6c75d25c514d8fGreg Clayton    target = lldb.debugger.CreateTarget(path, options.arch, options.platform, False, error)
2454ce4db571fef8c5e619fe807f6c75d25c514d8fGreg Clayton    if target:
2554ce4db571fef8c5e619fe807f6c75d25c514d8fGreg Clayton        # Get the executable module
2654ce4db571fef8c5e619fe807f6c75d25c514d8fGreg Clayton        module = target.module[target.executable.basename]
2754ce4db571fef8c5e619fe807f6c75d25c514d8fGreg Clayton        if module:
2854ce4db571fef8c5e619fe807f6c75d25c514d8fGreg Clayton            # Keep track of which variables we have already looked up
2954ce4db571fef8c5e619fe807f6c75d25c514d8fGreg Clayton            global_names = list()
3054ce4db571fef8c5e619fe807f6c75d25c514d8fGreg Clayton            # Iterate through all symbols in the symbol table and watch for any DATA symbols
3154ce4db571fef8c5e619fe807f6c75d25c514d8fGreg Clayton            for symbol in module.symbols:
3254ce4db571fef8c5e619fe807f6c75d25c514d8fGreg Clayton                if symbol.type == lldb.eSymbolTypeData:
3354ce4db571fef8c5e619fe807f6c75d25c514d8fGreg Clayton                    # The symbol is a DATA symbol, lets try and find all global variables
3454ce4db571fef8c5e619fe807f6c75d25c514d8fGreg Clayton                    # that match this name and print them
3554ce4db571fef8c5e619fe807f6c75d25c514d8fGreg Clayton                    global_name = symbol.name
3654ce4db571fef8c5e619fe807f6c75d25c514d8fGreg Clayton                    # Make sure we don't lookup the same variable twice
3754ce4db571fef8c5e619fe807f6c75d25c514d8fGreg Clayton                    if global_name not in global_names:
3854ce4db571fef8c5e619fe807f6c75d25c514d8fGreg Clayton                        global_names.append(global_name)
3954ce4db571fef8c5e619fe807f6c75d25c514d8fGreg Clayton                        # Find all global variables by name
4054ce4db571fef8c5e619fe807f6c75d25c514d8fGreg Clayton                        global_variable_list = module.FindGlobalVariables (target, global_name, lldb.UINT32_MAX)
4154ce4db571fef8c5e619fe807f6c75d25c514d8fGreg Clayton                        if global_variable_list:
4254ce4db571fef8c5e619fe807f6c75d25c514d8fGreg Clayton                            # Print results for anything that matched
4354ce4db571fef8c5e619fe807f6c75d25c514d8fGreg Clayton                            for global_variable in global_variable_list:
4454ce4db571fef8c5e619fe807f6c75d25c514d8fGreg Clayton                                print 'name = %s' % global_variable.name    # returns the global variable name as a string
4554ce4db571fef8c5e619fe807f6c75d25c514d8fGreg Clayton                                print 'value = %s' % global_variable.value  # Returns the variable value as a string
4654ce4db571fef8c5e619fe807f6c75d25c514d8fGreg Clayton                                print 'type = %s' % global_variable.type    # Returns an lldb.SBType object
4754ce4db571fef8c5e619fe807f6c75d25c514d8fGreg Clayton                                print 'addr = %s' % global_variable.addr    # Returns an lldb.SBAddress (section offset address) for this global
4854ce4db571fef8c5e619fe807f6c75d25c514d8fGreg Clayton                                print 'file_addr = 0x%x' % global_variable.addr.file_addr    # Returns the file virtual address for this global
4954ce4db571fef8c5e619fe807f6c75d25c514d8fGreg Clayton                                print 'location = %s' % global_variable.location    # returns the global variable value as a string
5054ce4db571fef8c5e619fe807f6c75d25c514d8fGreg Clayton                                print 'size = %s' % global_variable.size    # Returns the size in bytes of this global variable
5154ce4db571fef8c5e619fe807f6c75d25c514d8fGreg Clayton                                print
5254ce4db571fef8c5e619fe807f6c75d25c514d8fGreg Clayton
5354ce4db571fef8c5e619fe807f6c75d25c514d8fGreg Claytondef globals(command_args):
5454ce4db571fef8c5e619fe807f6c75d25c514d8fGreg Clayton    '''Extract all globals from any arguments which must be paths to object files.'''
5554ce4db571fef8c5e619fe807f6c75d25c514d8fGreg Clayton    usage = "usage: %prog [options] <PATH> [PATH ...]"
5654ce4db571fef8c5e619fe807f6c75d25c514d8fGreg Clayton    description='''This command will find all globals in the specified object file and return an list() of lldb.SBValue objects (which might be empty).'''
5754ce4db571fef8c5e619fe807f6c75d25c514d8fGreg Clayton    parser = optparse.OptionParser(description=description, prog='globals',usage=usage)
5854ce4db571fef8c5e619fe807f6c75d25c514d8fGreg Clayton    parser.add_option('-v', '--verbose', action='store_true', dest='verbose', help='display verbose debug info', default=False)
5954ce4db571fef8c5e619fe807f6c75d25c514d8fGreg Clayton    parser.add_option('-a', '--arch', type='string', metavar='arch', dest='arch', help='Specify an architecture (or triple) to use when extracting from a file.')
609bb6d255db5fb13c983cb0fa470248fc1242c05fGreg 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".')
6154ce4db571fef8c5e619fe807f6c75d25c514d8fGreg Clayton    try:
6254ce4db571fef8c5e619fe807f6c75d25c514d8fGreg Clayton        (options, args) = parser.parse_args(command_args)
6354ce4db571fef8c5e619fe807f6c75d25c514d8fGreg Clayton    except:
6454ce4db571fef8c5e619fe807f6c75d25c514d8fGreg Clayton        return
6554ce4db571fef8c5e619fe807f6c75d25c514d8fGreg Clayton
6654ce4db571fef8c5e619fe807f6c75d25c514d8fGreg Clayton    for path in args:
6754ce4db571fef8c5e619fe807f6c75d25c514d8fGreg Clayton        get_globals (path, options)
6854ce4db571fef8c5e619fe807f6c75d25c514d8fGreg Clayton
6954ce4db571fef8c5e619fe807f6c75d25c514d8fGreg Claytonif __name__ == '__main__':
7054ce4db571fef8c5e619fe807f6c75d25c514d8fGreg Clayton    lldb.debugger = lldb.SBDebugger.Create()
7154ce4db571fef8c5e619fe807f6c75d25c514d8fGreg Clayton    globals (sys.argv[1:])
7254ce4db571fef8c5e619fe807f6c75d25c514d8fGreg Clayton
73