1 | #import <Foundation/Foundation.h> |
2 | |
3 | // SourceBase will be the base class of Source. We'll pass a Source object into a |
4 | // function as a SourceBase, and then see if the dynamic typing can get us through the KVO |
5 | // goo and all the way back to Source. |
6 | |
7 | @interface SourceBase: NSObject |
8 | { |
9 | uint32_t _value; |
10 | } |
11 | - (SourceBase *) init; |
12 | - (uint32_t) getValue; |
13 | @end |
14 | |
15 | @implementation SourceBase |
16 | - (SourceBase *) init |
17 | { |
18 | [super init]; |
19 | _value = 10; |
20 | return self; |
21 | } |
22 | - (uint32_t) getValue |
23 | { |
24 | return _value; |
25 | } |
26 | @end |
27 | |
28 | // Source is a class that will be observed by the Observer class below. |
29 | // When Observer sets itself up to observe this property (in initWithASource) |
30 | // the KVO system will overwrite the "isa" pointer of the object with the "kvo'ed" |
31 | // one. |
32 | |
33 | @interface Source : SourceBase |
34 | { |
35 | int _property; |
36 | } |
37 | - (Source *) init; |
38 | - (void) setProperty: (int) newValue; |
39 | @end |
40 | |
41 | @implementation Source |
42 | - (Source *) init |
43 | { |
44 | [super init]; |
45 | _property = 20; |
46 | return self; |
47 | } |
48 | - (void) setProperty: (int) newValue |
49 | { |
50 | _property = newValue; // This is the line in setProperty, make sure we step to here. |
51 | } |
52 | @end |
53 | |
54 | @interface SourceDerived : Source |
55 | { |
56 | int _derivedValue; |
57 | } |
58 | - (SourceDerived *) init; |
59 | - (uint32_t) getValue; |
60 | @end |
61 | |
62 | @implementation SourceDerived |
63 | - (SourceDerived *) init |
64 | { |
65 | [super init]; |
66 | _derivedValue = 30; |
67 | return self; |
68 | } |
69 | - (uint32_t) getValue |
70 | { |
71 | return _derivedValue; |
72 | } |
73 | @end |
74 | |
75 | // Observer is the object that will watch Source and cause KVO to swizzle it... |
76 | |
77 | @interface Observer : NSObject |
78 | { |
79 | Source *_source; |
80 | } |
81 | + (Observer *) observerWithSource: (Source *) source; |
82 | - (Observer *) initWithASource: (Source *) source; |
83 | - (void) observeValueForKeyPath: (NSString *) path |
84 | ofObject: (id) object |
85 | change: (NSDictionary *) change |
86 | context: (void *) context; |
87 | @end |
88 | |
89 | @implementation Observer |
90 | |
91 | + (Observer *) observerWithSource: (Source *) inSource; |
92 | { |
93 | Observer *retval; |
94 | |
95 | retval = [[Observer alloc] initWithASource: inSource]; |
96 | return retval; |
97 | } |
98 | |
99 | - (Observer *) initWithASource: (Source *) source |
100 | { |
101 | [super init]; |
102 | _source = source; |
103 | [_source addObserver: self |
104 | forKeyPath: @"property" |
105 | options: (NSKeyValueObservingOptionNew | NSKeyValueObservingOptionOld) |
106 | context: NULL]; |
107 | return self; |
108 | } |
109 | |
110 | - (void) observeValueForKeyPath: (NSString *) path |
111 | ofObject: (id) object |
112 | change: (NSDictionary *) change |
113 | context: (void *) context |
114 | { |
115 | printf ("Observer function called.\n" ); |
116 | return; |
117 | } |
118 | @end |
119 | |
120 | |
121 | int patval; // external symbol, will not be completely stripped |
122 | int pat(int in) { // external symbol, will not be completely stripped |
123 | if (patval == 0) |
124 | patval = in; |
125 | return patval; |
126 | } |
127 | |
128 | static int fooval; // static symbol, stripped |
129 | int foo() { // external symbol, will not be completely stripped |
130 | if (fooval == 0) |
131 | fooval = 5; |
132 | return fooval; |
133 | } |
134 | |
135 | int bazval = 10; // external symbol, will not be completely stripped |
136 | int baz () { // external symbol, will not be completely stripped |
137 | return foo() + bazval; |
138 | } |
139 | |
140 | static int barval = 15; // static symbol, stripped |
141 | static int bar () { // static symbol, stripped; __lldb_unnamed_symbol from func starts |
142 | return baz() + barval; |
143 | } |
144 | |
145 | int calculate () // external symbol, will not be completely stripped |
146 | { |
147 | return bar(); |
148 | } |
149 | |
150 | |