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