#!/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> ...]
#----------------------------------------------------------------------
from __future__ import print_function

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:])
