#!/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:])
