1*515bc8c1Sserge-sans-paille#!/usr/bin/env python
239cacebdSGreg Clayton
339cacebdSGreg Clayton#----------------------------------------------------------------------
439cacebdSGreg Clayton# For the shells csh, tcsh:
539cacebdSGreg Clayton#   ( setenv PYTHONPATH /Applications/Xcode.app/Contents/SharedFrameworks/LLDB.framework/Resources/Python ; ./globals.py <path> [<path> ...])
639cacebdSGreg Clayton#
739cacebdSGreg Clayton# For the shells sh, bash:
839cacebdSGreg Clayton#   PYTHONPATH=/Applications/Xcode.app/Contents/SharedFrameworks/LLDB.framework/Resources/Python ./globals.py <path> [<path> ...]
939cacebdSGreg Clayton#----------------------------------------------------------------------
10525cd59fSSerge Gueltonfrom __future__ import print_function
1139cacebdSGreg Clayton
1239cacebdSGreg Claytonimport lldb
1339cacebdSGreg Claytonimport optparse
1439cacebdSGreg Claytonimport os
1539cacebdSGreg Claytonimport shlex
1639cacebdSGreg Claytonimport sys
1739cacebdSGreg Clayton
18b9c1b51eSKate Stone
1939cacebdSGreg Claytondef get_globals(raw_path, options):
2039cacebdSGreg Clayton    error = lldb.SBError()
2139cacebdSGreg Clayton    # Resolve the path if needed
2239cacebdSGreg Clayton    path = os.path.expanduser(raw_path)
2339cacebdSGreg Clayton    # Create a target using path + options
24b9c1b51eSKate Stone    target = lldb.debugger.CreateTarget(
25b9c1b51eSKate Stone        path, options.arch, options.platform, False, error)
2639cacebdSGreg Clayton    if target:
2739cacebdSGreg Clayton        # Get the executable module
2839cacebdSGreg Clayton        module = target.module[target.executable.basename]
2939cacebdSGreg Clayton        if module:
3039cacebdSGreg Clayton            # Keep track of which variables we have already looked up
3139cacebdSGreg Clayton            global_names = list()
32b9c1b51eSKate Stone            # Iterate through all symbols in the symbol table and watch for any
33b9c1b51eSKate Stone            # DATA symbols
3439cacebdSGreg Clayton            for symbol in module.symbols:
3539cacebdSGreg Clayton                if symbol.type == lldb.eSymbolTypeData:
3639cacebdSGreg Clayton                    # The symbol is a DATA symbol, lets try and find all global variables
3739cacebdSGreg Clayton                    # that match this name and print them
3839cacebdSGreg Clayton                    global_name = symbol.name
3939cacebdSGreg Clayton                    # Make sure we don't lookup the same variable twice
4039cacebdSGreg Clayton                    if global_name not in global_names:
4139cacebdSGreg Clayton                        global_names.append(global_name)
4239cacebdSGreg Clayton                        # Find all global variables by name
43b9c1b51eSKate Stone                        global_variable_list = module.FindGlobalVariables(
44b9c1b51eSKate Stone                            target, global_name, lldb.UINT32_MAX)
4539cacebdSGreg Clayton                        if global_variable_list:
4639cacebdSGreg Clayton                            # Print results for anything that matched
4739cacebdSGreg Clayton                            for global_variable in global_variable_list:
48b9c1b51eSKate Stone                                # returns the global variable name as a string
49525cd59fSSerge Guelton                                print('name = %s' % global_variable.name)
50b9c1b51eSKate Stone                                # Returns the variable value as a string
51525cd59fSSerge Guelton                                print('value = %s' % global_variable.value)
52525cd59fSSerge Guelton                                print('type = %s' % global_variable.type)    # Returns an lldb.SBType object
53b9c1b51eSKate Stone                                # Returns an lldb.SBAddress (section offset
54b9c1b51eSKate Stone                                # address) for this global
55525cd59fSSerge Guelton                                print('addr = %s' % global_variable.addr)
56b9c1b51eSKate Stone                                # Returns the file virtual address for this
57b9c1b51eSKate Stone                                # global
58525cd59fSSerge Guelton                                print('file_addr = 0x%x' % global_variable.addr.file_addr)
59b9c1b51eSKate Stone                                # returns the global variable value as a string
60525cd59fSSerge Guelton                                print('location = %s' % global_variable.location)
61b9c1b51eSKate Stone                                # Returns the size in bytes of this global
62b9c1b51eSKate Stone                                # variable
63525cd59fSSerge Guelton                                print('size = %s' % global_variable.size)
64525cd59fSSerge Guelton                                print()
6539cacebdSGreg Clayton
66b9c1b51eSKate Stone
6739cacebdSGreg Claytondef globals(command_args):
6839cacebdSGreg Clayton    '''Extract all globals from any arguments which must be paths to object files.'''
6939cacebdSGreg Clayton    usage = "usage: %prog [options] <PATH> [PATH ...]"
7039cacebdSGreg 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).'''
71b9c1b51eSKate Stone    parser = optparse.OptionParser(
72b9c1b51eSKate Stone        description=description,
73b9c1b51eSKate Stone        prog='globals',
74b9c1b51eSKate Stone        usage=usage)
75b9c1b51eSKate Stone    parser.add_option(
76b9c1b51eSKate Stone        '-v',
77b9c1b51eSKate Stone        '--verbose',
78b9c1b51eSKate Stone        action='store_true',
79b9c1b51eSKate Stone        dest='verbose',
80b9c1b51eSKate Stone        help='display verbose debug info',
81b9c1b51eSKate Stone        default=False)
82b9c1b51eSKate Stone    parser.add_option(
83b9c1b51eSKate Stone        '-a',
84b9c1b51eSKate Stone        '--arch',
85b9c1b51eSKate Stone        type='string',
86b9c1b51eSKate Stone        metavar='arch',
87b9c1b51eSKate Stone        dest='arch',
88b9c1b51eSKate Stone        help='Specify an architecture (or triple) to use when extracting from a file.')
89b9c1b51eSKate Stone    parser.add_option(
90b9c1b51eSKate Stone        '-p',
91b9c1b51eSKate Stone        '--platform',
92b9c1b51eSKate Stone        type='string',
93b9c1b51eSKate Stone        metavar='platform',
94b9c1b51eSKate Stone        dest='platform',
95b9c1b51eSKate Stone        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".')
9639cacebdSGreg Clayton    try:
9739cacebdSGreg Clayton        (options, args) = parser.parse_args(command_args)
9839cacebdSGreg Clayton    except:
9939cacebdSGreg Clayton        return
10039cacebdSGreg Clayton
10139cacebdSGreg Clayton    for path in args:
10239cacebdSGreg Clayton        get_globals(path, options)
10339cacebdSGreg Clayton
10439cacebdSGreg Claytonif __name__ == '__main__':
10539cacebdSGreg Clayton    lldb.debugger = lldb.SBDebugger.Create()
10639cacebdSGreg Clayton    globals(sys.argv[1:])
107