globals.py
4.62 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
#!/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> ...]
#----------------------------------------------------------------------
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:])