forked from facebook/chisel
-
Notifications
You must be signed in to change notification settings - Fork 0
/
fblldbobjcruntimehelpers.py
98 lines (80 loc) · 3.11 KB
/
fblldbobjcruntimehelpers.py
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
#!/usr/bin/python
# Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved
#
# This source code is licensed under the MIT license found in the
# LICENSE file in the root directory of this source tree.
import re
import lldb
import fblldbbase as fb
def objc_getClass(className):
command = '(void*)objc_getClass("{}")'.format(className)
value = fb.evaluateExpression(command)
return value
def object_getClass(object):
command = '(void*)object_getClass((id){})'.format(object)
value = fb.evaluateExpression(command)
return value
def class_getName(klass):
command = '(const char*)class_getName((Class){})'.format(klass)
value = fb.evaluateExpressionValue(command).GetSummary().strip('"')
return value
def class_getSuperclass(klass):
command = '(void*)class_getSuperclass((Class){})'.format(klass)
value = fb.evaluateExpression(command)
return value
def class_isMetaClass(klass):
command = 'class_isMetaClass((Class){})'.format(klass)
return fb.evaluateBooleanExpression(command)
def class_getInstanceMethod(klass, selector):
command = '(void*)class_getInstanceMethod((Class){}, @selector({}))'.format(klass, selector)
value = fb.evaluateExpression(command)
return value
def currentArch():
targetTriple = lldb.debugger.GetSelectedTarget().GetTriple()
arch = targetTriple.split('-')[0]
if arch == 'x86_64h':
arch = 'x86_64'
return arch
def functionPreambleExpressionForSelf():
import re
arch = currentArch()
expressionForSelf = None
if arch == 'i386':
expressionForSelf = '*(id*)($esp+4)'
elif arch == 'x86_64':
expressionForSelf = '(id)$rdi'
elif arch == 'arm64':
expressionForSelf = '(id)$x0'
elif re.match(r'^armv.*$', arch):
expressionForSelf = '(id)$r0'
return expressionForSelf
def functionPreambleExpressionForObjectParameterAtIndex(parameterIndex):
arch = currentArch()
expresssion = None
if arch == 'i386':
expresssion = '*(id*)($esp + ' + str(12 + parameterIndex * 4) + ')'
elif arch == 'x86_64':
if parameterIndex > 3:
raise Exception("Current implementation can not return object at index greater than 3 for x86_64")
registersList = ['rdx', 'rcx', 'r8', 'r9']
expresssion = '(id)$' + registersList[parameterIndex]
elif arch == 'arm64':
if parameterIndex > 5:
raise Exception("Current implementation can not return object at index greater than 5 for arm64")
expresssion = '(id)$x' + str(parameterIndex + 2)
elif re.match(r'^armv.*$', arch):
if parameterIndex > 1:
raise Exception("Current implementation can not return object at index greater than 1 for arm32")
expresssion = '(id)$r' + str(parameterIndex + 2)
return expresssion
def isMacintoshArch():
arch = currentArch()
if not arch == 'x86_64':
return False
nsClassName = 'NSApplication'
command = '(void*)objc_getClass("{}")'.format(nsClassName)
return (fb.evaluateBooleanExpression(command + '!= nil'))
def isIOSSimulator():
return fb.evaluateExpressionValue('(id)[[UIDevice currentDevice] model]').GetObjectDescription().lower().find('simulator') >= 0
def isIOSDevice():
return not isMacintoshArch() and not isIOSSimulator()