see PrebindingFrameworks
#import <Cocoa/Cocoa.h>
id MachOPathForFrameworkAtPath(id path) { id extension=[path pathExtension]; id manager=[NSFileManager defaultManager]; BOOL isDir; if ([extension isEqualToString:@”framework”]) { id versionDirectory=[path stringByAppendingPathComponent:@”Versions”]; if ([manager fileExistsAtPath:versionDirectory isDirectory:&isDir] && isDir) { id frameworkName=path lastPathComponent] stringByDeletingPathExtension]; path=[[[NSString stringWithFormat:@”%@/Current/%@”, versionDirectory, frameworkName]; if ([manager fileExistsAtPath:path]) return path; else return nil; } else return nil; } else return path; }
id AddressRangeForFrameworkAtPath(id path) { id otoolTask=[[[NSTask alloc] init] autorelease]; id outputPipe=[NSPipe pipe]; path=MachOPathForFrameworkAtPath(path); if (!path) return nil; [otoolTask setLaunchPath:@”/usr/bin/otool”]; [otoolTask setArguments:[NSArray arrayWithObjects:@”-lv”, path, nil]]; [otoolTask setStandardOutput:outputPipe]; [otoolTask launch]; id outputHandle=[outputPipe fileHandleForReading]; id outputData=[outputHandle readDataToEndOfFile]; id outputString=[NSString stringWithCString:[outputData bytes] length:[outputData length]]; id lines=[outputString componentsSeparatedByString:@”\n”]; id lineEnum; id line; lineEnum=[lines objectEnumerator]; unsigned long totalLength=0; id baseAddressString=nil; while (line=[lineEnum nextObject]) { NSRange range=[line rangeOfString:@”vmaddr “]; if (range.length) { line=[line stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceCharacterSet]]; id components=[line componentsSeparatedByString:@” “]; id nextLine=[lineEnum nextObject]; range=[nextLine rangeOfString:@”vmsize “]; if (!range.length) continue; nextLine=[nextLine stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceCharacterSet]]; id nextLineComponents=[nextLine componentsSeparatedByString:@” “]; if ([components count]==2 && [nextLineComponents count]==2) { id addressString=[components objectAtIndex:1]; if (!baseAddressString) baseAddressString=addressString; id sizeString=[nextLineComponents objectAtIndex:1]; totalLength+=strtoul([sizeString cString], nil, 16); } } }
unsigned long baseAddressValue=strtoul([baseAddressString cString], nil, 16);
unsigned long nextFreeAddressValue=(baseAddressValue+totalLength);
return [NSString stringWithFormat:@"{ %u, %u }", baseAddressValue, totalLength]; }
int AddressRangeSort(id obj1, id obj2, void *context) { id range1=[obj1 objectForKey:@”range”]; id range2=[obj2 objectForKey:@”range”]; unsigned int v1 = NSRangeFromString(range1).location; unsigned int v2 = NSRangeFromString(range2).location; if (v1 < v2) return NSOrderedAscending; else if (v1 > v2) return NSOrderedDescending; else return NSOrderedSame;
}
int main(int argc, char *argv[]) {
NSAutoreleasePool *pool=[[NSAutoreleasePool alloc] init];
id manager=[NSFileManager defaultManager];
if (argc<2) {
NSLog(@”machoinfo
return 0; }