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 121int patval; // external symbol, will not be completely stripped 122int pat(int in) { // external symbol, will not be completely stripped 123 if (patval == 0) 124 patval = in; 125 return patval; 126} 127 128static int fooval; // static symbol, stripped 129int foo() { // external symbol, will not be completely stripped 130 if (fooval == 0) 131 fooval = 5; 132 return fooval; 133} 134 135int bazval = 10; // external symbol, will not be completely stripped 136int baz () { // external symbol, will not be completely stripped 137 return foo() + bazval; 138} 139 140static int barval = 15; // static symbol, stripped 141static int bar () { // static symbol, stripped; __lldb_unnamed_symbol from func starts 142 return baz() + barval; 143} 144 145int calculate () // external symbol, will not be completely stripped 146{ 147 return bar(); 148} 149 150