-
Notifications
You must be signed in to change notification settings - Fork 804
/
fbchisellldbobjcruntimehelpers.py
124 lines (94 loc) · 3.43 KB
/
fbchisellldbobjcruntimehelpers.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
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
#!/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 fbchisellldbbase as fb
import lldb
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()