├── .github └── workflows │ └── build.yml ├── .gitignore ├── LICENSE ├── MacDependency ├── ArchitectureModel.h ├── ArchitectureModel.mm ├── ArchitecturesController.h ├── ArchitecturesController.mm ├── AutoExpandOutlineView.h ├── AutoExpandOutlineView.m ├── Base.lproj │ ├── MainMenu.xib │ └── MyDocument.xib ├── ConversionStdString.h ├── ConversionStdString.mm ├── ExtTreeModel.h ├── Images.xcassets │ └── AppIcon.appiconset │ │ ├── Contents.json │ │ ├── icon_128x128.png │ │ ├── icon_128x128@2x.png │ │ ├── icon_16x16.png │ │ ├── icon_16x16@2x.png │ │ ├── icon_256x256.png │ │ ├── icon_256x256@2x.png │ │ ├── icon_32x32.png │ │ ├── icon_32x32@2x.png │ │ ├── icon_512x512.png │ │ └── icon_512x512@2x.png ├── Info.plist ├── MacDependency.xcodeproj │ ├── TemplateIcon.icns │ ├── project.pbxproj │ ├── project.xcworkspace │ │ ├── contents.xcworkspacedata │ │ └── xcshareddata │ │ │ └── IDEWorkspaceChecks.plist │ └── xcshareddata │ │ └── xcschemes │ │ └── MacDependency.xcscheme ├── MacDependency_Prefix.h ├── MachOModel.h ├── MachOModel.mm ├── MyDocument.h ├── MyDocument.mm ├── MyDocumentWindow.h ├── MyDocumentWindow.m ├── PrioritySplitViewDelegate.h ├── PrioritySplitViewDelegate.m ├── SymbolTableController.h ├── SymbolTableController.mm ├── SymbolTableEntryModel.h ├── SymbolTableEntryModel.mm ├── SymbolTableEntryTypeFormatter.h ├── SymbolTableEntryTypeFormatter.mm ├── TreeControllerExtension.h ├── TreeControllerExtension.m ├── VersionFormatter.h ├── VersionFormatter.m ├── en.lproj │ ├── Credits.rtf │ ├── InfoPlist.strings │ └── Localizable.strings └── main.m ├── MachO ├── Info.plist ├── MachO.xcodeproj │ ├── TemplateIcon.icns │ ├── project.pbxproj │ └── xcshareddata │ │ └── xcschemes │ │ └── MachO.xcscheme ├── MachO_Prefix.h ├── dylibcommand.cpp ├── dylibcommand.h ├── dylinkercommand.cpp ├── dylinkercommand.h ├── dynamicloader.cpp ├── dynamicloader.h ├── en.lproj │ └── InfoPlist.strings ├── genericcommand.cpp ├── genericcommand.h ├── internalfile.cpp ├── internalfile.h ├── loadcommand.cpp ├── loadcommand.h ├── macho.cpp ├── macho.h ├── macho32header.cpp ├── macho32header.h ├── macho64header.cpp ├── macho64header.h ├── macho_global.h ├── machoarchitecture.cpp ├── machoarchitecture.h ├── machocache.cpp ├── machocache.h ├── machodemangleexception.cpp ├── machodemangleexception.h ├── machoexception.cpp ├── machoexception.h ├── machofile.cpp ├── machofile.h ├── machoheader.cpp ├── machoheader.h ├── rpathcommand.cpp ├── rpathcommand.h ├── symboltablecommand.cpp ├── symboltablecommand.h ├── symboltableentry.cpp ├── symboltableentry.h ├── symboltableentry32.cpp ├── symboltableentry32.h ├── symboltableentry64.cpp ├── symboltableentry64.h ├── uuidcommand.cpp └── uuidcommand.h ├── README.md └── images └── macdependency.png /.github/workflows/build.yml: -------------------------------------------------------------------------------- 1 | name: build 2 | on: [push, pull_request] 3 | jobs: 4 | build: 5 | runs-on: macos-latest 6 | steps: 7 | - uses: actions/checkout@v2 8 | # https://github.com/mxcl/xcodebuild 9 | - uses: mxcl/xcodebuild@v1 10 | with: 11 | platform: macOS 12 | working-directory: MacDependency 13 | action: build # default = `test` -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Created by https://www.toptal.com/developers/gitignore/api/xcode 2 | # Edit at https://www.toptal.com/developers/gitignore?templates=xcode 3 | 4 | ### Xcode ### 5 | ## User settings 6 | xcuserdata/ 7 | *.xcuserstate 8 | 9 | ## Xcode 8 and earlier 10 | *.xcscmblueprint 11 | *.xccheckout 12 | 13 | ### Xcode Patch ### 14 | *.xcodeproj/* 15 | !*.xcodeproj/project.pbxproj 16 | !*.xcodeproj/xcshareddata/ 17 | !*.xcworkspace/contents.xcworkspacedata 18 | /*.gcno 19 | **/xcshareddata/WorkspaceSettings.xcsettings 20 | 21 | # End of https://www.toptal.com/developers/gitignore/api/xcode 22 | 23 | build/ 24 | build.xcresult/ -------------------------------------------------------------------------------- /MacDependency/ArchitectureModel.h: -------------------------------------------------------------------------------- 1 | // 2 | // ArchitectureModel.h 3 | // MacDependency 4 | // 5 | // Created by Konrad Windszus on 22.08.09. 6 | // Copyright 2009 Konrad Windszus. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "MachOModel.h" 11 | #include "macho/machoarchitecture.h" 12 | #include "MachO/machoheader.h" 13 | 14 | @class MyDocument; 15 | 16 | @interface ArchitectureModel : NSObject { 17 | MachOArchitecture* architecture; 18 | MachOModel* machOModel; 19 | MachO* file; 20 | MyDocument* document; 21 | NSMutableArray* symbolEntries; 22 | 23 | } 24 | - (id) initWithArchitecture:(MachOArchitecture*)architecture file:(MachO*)file document:(MyDocument*)document isRoot:(BOOL)isRoot; 25 | - (NSString*) label; 26 | - (NSString*) fileType; 27 | - (NSString*) identifier; 28 | - (NSString*) size; 29 | - (NSString*) version; 30 | - (NSString*) uuid; 31 | - (NSString*) rpath; 32 | - (NSString*) dynamicLinker; 33 | - (NSNumber*) showIdentifier; 34 | 35 | + (NSString*) cpuType:(MachOHeader::CpuType)cpuType; 36 | 37 | - (void) refreshSymbols; 38 | - (NSArray*) symbols; 39 | - (void) setSymbols:(NSMutableArray*) symbolEntries; 40 | @end 41 | -------------------------------------------------------------------------------- /MacDependency/ArchitectureModel.mm: -------------------------------------------------------------------------------- 1 | // 2 | // ArchitectureModel.m 3 | // MacDependency 4 | // 5 | // Created by Konrad Windszus on 22.08.09. 6 | // Copyright 2009 Konrad Windszus. All rights reserved. 7 | // 8 | 9 | #import "ArchitectureModel.h" 10 | #import "VersionFormatter.h" 11 | #import "ConversionStdString.h" 12 | 13 | #include "MachO/machoexception.h" 14 | #include "MachO/symboltablecommand.h" 15 | 16 | #import "SymbolTableEntryModel.h" 17 | #import "MyDocument.h" 18 | 19 | // declare private methods 20 | @interface ArchitectureModel () 21 | - (void) initSymbols; 22 | @end 23 | 24 | 25 | @implementation ArchitectureModel 26 | 27 | - (id) initWithArchitecture:(MachOArchitecture*)anArchitecture file:(MachO*)aFile document:(MyDocument*)aDocument isRoot:(BOOL)isRoot{ 28 | architecture = anArchitecture; 29 | file = aFile; 30 | document = aDocument; 31 | symbolEntries = nil; 32 | 33 | // create model with the current architecture selected (create from existing model) 34 | if (isRoot) { 35 | machOModel = nil; 36 | } else { 37 | machOModel = [[MachOModel alloc]initWithFile:aFile document:aDocument architecture:anArchitecture loadChildren:NO]; 38 | } 39 | 40 | return self; 41 | } 42 | 43 | 44 | - (NSArray*) rootModel { 45 | // always reload model (for error messages) 46 | machOModel = [[MachOModel alloc]initWithFile:file document:document architecture:architecture loadChildren:YES]; 47 | NSArray* rootModel = [NSArray arrayWithObject:machOModel]; 48 | return rootModel; 49 | } 50 | 51 | + (NSString*) cpuType:(MachOHeader::CpuType)cpuType { 52 | NSString* label; 53 | switch (cpuType) { 54 | case MachOHeader::CpuTypePowerPc: 55 | label = NSLocalizedString(@"CPU_TYPE_PPC", nil); 56 | break; 57 | case MachOHeader::CpuTypeI386: 58 | label = NSLocalizedString(@"CPU_TYPE_I386", nil); 59 | break; 60 | case MachOHeader::CpuTypePowerPc64: 61 | label = NSLocalizedString(@"CPU_TYPE_PPC64", nil); 62 | break; 63 | case MachOHeader::CpuTypeX8664: 64 | label = NSLocalizedString(@"CPU_TYPE_X8664", nil); 65 | break; 66 | case MachOHeader::CpuTypeArm: 67 | label = NSLocalizedString(@"CPU_TYPE_ARM", nil); 68 | break; 69 | case MachOHeader::CpuTypeArm64: 70 | label = NSLocalizedString(@"CPU_TYPE_ARM64", nil); 71 | break; 72 | case MachOHeader::CpuTypeArm6432: 73 | label = NSLocalizedString(@"CPU_TYPE_ARM6432", nil); 74 | break; 75 | default: 76 | label = NSLocalizedString(@"UNDEFINED", nil); 77 | break; 78 | 79 | } 80 | return label; 81 | } 82 | 83 | - (NSString*) label { 84 | return [ArchitectureModel cpuType:architecture->getHeader()->getCpuType()]; 85 | } 86 | 87 | - (NSString*) uuid { 88 | CFStringRef result; 89 | CFUUIDBytes* uuidPtr = (CFUUIDBytes*)architecture->getUuid(); 90 | if (uuidPtr) { 91 | // use CFUUID 92 | CFUUIDRef uuid = CFUUIDCreateFromUUIDBytes(kCFAllocatorDefault, *uuidPtr); 93 | result = CFUUIDCreateString(kCFAllocatorDefault, uuid); 94 | CFRelease(uuid); 95 | } else { 96 | result = CFStringCreateWithCString(NULL, "[No UUID]", kCFStringEncodingASCII); 97 | } 98 | return (NSString*) CFBridgingRelease(result); 99 | } 100 | 101 | - (NSString*) fileType { 102 | NSString* type; 103 | switch(architecture->getHeader()->getFileType()) { 104 | case MachOHeader::FileTypeObject: /* relocatable object file */ 105 | type = NSLocalizedString(@"FILE_TYPE_OBJECT", nil); 106 | break; 107 | case MachOHeader::FileTypeExecutable: /* demand paged executable file */ 108 | type = NSLocalizedString(@"FILE_TYPE_EXECUTABLE", nil); 109 | break; 110 | case MachOHeader::FileTypeVmLib: /* fixed VM shared library file */ 111 | type = NSLocalizedString(@"FILE_TYPE_VM_SHARED_LIBRARY", nil); 112 | break; 113 | case MachOHeader::FileTypeCore: /* core file */ 114 | type = NSLocalizedString(@"FILE_TYPE_CORE", nil); 115 | break; 116 | case MachOHeader::FileTypePreload: /* preloaded executable file */ 117 | type = NSLocalizedString(@"FILE_TYPE_PRELOADED_EXECUTABLE", nil); 118 | break; 119 | case MachOHeader::FileTypeDylib: /* dynamically bound shared library */ 120 | type = NSLocalizedString(@"FILE_TYPE_SHARED_LIBRARY", nil); 121 | break; 122 | case MachOHeader::FileTypeDylinker: /* dynamic link editor */ 123 | type = NSLocalizedString(@"FILE_TYPE_DYNAMIC_LINKER", nil); 124 | break; 125 | case MachOHeader::FileTypeBundle: /* dynamically bound bundle file */ 126 | type = NSLocalizedString(@"FILE_TYPE_BUNDLE", nil); 127 | break; 128 | case MachOHeader::FileTypeDylibStub: /* shared library stub for static linking only, no section contents */ 129 | type = NSLocalizedString(@"FILE_TYPE_STATIC_LIBRARY", nil); 130 | break; 131 | case MachOHeader::FileTypeDsym: /* companion file with only debug sections */ 132 | type = NSLocalizedString(@"FILE_TYPE_DSYM", nil); 133 | break; 134 | case MachOHeader::FileTypeKextBundle: /* kext bundle */ 135 | type = NSLocalizedString(@"FILE_TYPE_KEXT_BUNDLE", nil); 136 | break; 137 | default: 138 | type = NSLocalizedString(@"UNDEFINED", @"Unknown"); 139 | } 140 | return type; 141 | } 142 | 143 | - (NSString*) identifier { 144 | NSString* identifier = [NSString string]; 145 | DylibCommand* dynamicLibraryIdCommand = architecture->getDynamicLibIdCommand(); 146 | if (dynamicLibraryIdCommand != NULL) { 147 | identifier = [NSString stringWithStdString:dynamicLibraryIdCommand->getName()]; 148 | } 149 | return identifier; 150 | } 151 | 152 | - (NSString*) dynamicLinker { 153 | NSString* dynamicLinker; 154 | dynamicLinker = [NSString stringWithStdString:architecture->getDynamicLinker()]; 155 | return dynamicLinker; 156 | } 157 | 158 | - (NSString*) rpath { 159 | std::vector rpaths = architecture->getRpaths(false); 160 | NSMutableString* rpath = [NSMutableString string]; 161 | for (std::vector::iterator it = rpaths.begin(); 162 | it != rpaths.end(); 163 | ++it) 164 | { 165 | [rpath appendFormat:@"%@; ", [NSString stringWithStdString:**it]]; 166 | } 167 | return rpath; 168 | } 169 | 170 | - (NSNumber*) showIdentifier { 171 | NSNumber* result; 172 | if ([[self identifier] length] == 0) { 173 | result = [NSNumber numberWithBool:true]; 174 | } else { 175 | result = [NSNumber numberWithBool:false]; 176 | } 177 | return result; 178 | } 179 | 180 | - (NSString*) size { 181 | NSString* size; 182 | // regard the correct format specifier %qu for unsigned long 183 | unsigned int architectureSize = architecture->getSize(); 184 | unsigned long long fileSize = file->getSize(); 185 | if (fileSize != architectureSize) { 186 | size = [NSString stringWithFormat:NSLocalizedString(@"SIZE_FORMAT_ARCHITECTURE", nil), 187 | fileSize/1024L, architectureSize/1024]; 188 | } else { 189 | size = [NSString stringWithFormat:NSLocalizedString(@"SIZE_FORMAT", nil), 190 | fileSize/1024L]; 191 | } 192 | return size; 193 | } 194 | 195 | - (NSString*) version { 196 | NSString* version = @"?"; 197 | DylibCommand* dynamicLibraryIdCommand = architecture->getDynamicLibIdCommand(); 198 | if (dynamicLibraryIdCommand != NULL) { 199 | VersionFormatter* versionFormatter = [[VersionFormatter alloc] init]; 200 | 201 | time_t timestamp = dynamicLibraryIdCommand->getTimeStamp(); 202 | NSString* currentVersion = [versionFormatter stringForObjectValue:[NSNumber numberWithUnsignedInt:dynamicLibraryIdCommand->getCurrentVersion()]]; 203 | NSString* compatibleVersion = [versionFormatter stringForObjectValue:[NSNumber numberWithUnsignedInt:dynamicLibraryIdCommand->getCompatibleVersion()]]; 204 | if ([currentVersion length]+[compatibleVersion length] > 0) { 205 | if (timestamp > 1) { 206 | NSDate* date = [NSDate dateWithTimeIntervalSince1970:timestamp]; 207 | 208 | // this date formatter should be identical to NSDateFormatter in IB 209 | NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init]; 210 | [dateFormatter setDateStyle:NSDateFormatterMediumStyle]; 211 | [dateFormatter setTimeStyle:NSDateFormatterMediumStyle]; 212 | 213 | version = [NSString stringWithFormat:NSLocalizedString(@"VERSION_FORMAT_TIMESTAMP", nil), 214 | currentVersion, 215 | compatibleVersion, 216 | [dateFormatter stringFromDate:date]]; 217 | } 218 | else { 219 | version = [NSString stringWithFormat:NSLocalizedString(@"VERSION_FORMAT", nil), 220 | currentVersion, 221 | compatibleVersion]; 222 | } 223 | } 224 | } else { 225 | version = [machOModel version]; 226 | } 227 | return version; 228 | } 229 | 230 | 231 | - (void) initSymbols { 232 | symbolEntries = [NSMutableArray arrayWithCapacity:20]; 233 | for (MachOArchitecture::LoadCommandsConstIterator lcIter = architecture->getLoadCommandsBegin(); 234 | lcIter != architecture->getLoadCommandsEnd(); 235 | ++lcIter) 236 | { 237 | // check if it is dylibcommand 238 | SymbolTableCommand* command = dynamic_cast (*lcIter); 239 | if (command != 0) { 240 | for (SymbolTableCommand::SymbolTableEntriesConstIterator it = command->getSymbolTableEntryBegin(); it != command->getSymbolTableEntryEnd(); it++) { 241 | SymbolTableEntryModel* symbolModel = [[SymbolTableEntryModel alloc] initWithEntry:*(it) demangleNamesPtr:[[document symbolTableController]demangleNamesPtr] document:document]; 242 | [symbolEntries addObject:symbolModel]; 243 | } 244 | } 245 | } 246 | } 247 | 248 | - (NSArray*) symbols { 249 | if (symbolEntries == nil) { 250 | [self initSymbols]; 251 | } 252 | return symbolEntries; 253 | } 254 | 255 | - (void) setSymbols:(NSMutableArray*) newSymbolEntries { 256 | symbolEntries = newSymbolEntries; 257 | } 258 | 259 | - (void) refreshSymbols { 260 | [self initSymbols]; 261 | [self setSymbols:symbolEntries]; 262 | } 263 | 264 | 265 | 266 | @end 267 | -------------------------------------------------------------------------------- /MacDependency/ArchitecturesController.h: -------------------------------------------------------------------------------- 1 | // 2 | // ArchitecturesController.h 3 | // MacDependency 4 | // 5 | // Created by Konrad Windszus on 22.08.09. 6 | // Copyright 2009 Konrad Windszus. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @class MyDocument; 12 | 13 | @interface ArchitecturesController : NSArrayController { 14 | IBOutlet MyDocument* document; 15 | } 16 | @end 17 | -------------------------------------------------------------------------------- /MacDependency/ArchitecturesController.mm: -------------------------------------------------------------------------------- 1 | // 2 | // ArchitecturesController.m 3 | // MacDependency 4 | // 5 | // Created by Konrad Windszus on 22.08.09. 6 | // Copyright 2009 Konrad Windszus. All rights reserved. 7 | // 8 | // Only used for root architectures. 9 | // 10 | #import "ArchitecturesController.h" 11 | #import "MyDocument.h" 12 | 13 | // declare private methods 14 | @interface ArchitecturesController () 15 | @end 16 | 17 | @implementation ArchitecturesController 18 | 19 | - (id)initWithCoder:(NSCoder *)decoder { 20 | self = [super initWithCoder:decoder]; 21 | if (self) { 22 | 23 | } 24 | return self; 25 | } 26 | 27 | 28 | 29 | - (void)awakeFromNib 30 | { 31 | [super awakeFromNib]; 32 | } 33 | 34 | - (BOOL)setSelectionIndex:(NSUInteger)index { 35 | // clear log 36 | [document clearLog]; 37 | [document resetNumDependencies]; 38 | return [super setSelectionIndex:index]; 39 | } 40 | 41 | 42 | 43 | @end 44 | -------------------------------------------------------------------------------- /MacDependency/AutoExpandOutlineView.h: -------------------------------------------------------------------------------- 1 | // 2 | // AutoExpandOutlineView.h 3 | // MacDependency 4 | // 5 | // Created by Konrad Windszus on 03.09.09. 6 | // Copyright 2009 Konrad Windszus. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | 12 | @interface AutoExpandOutlineView : NSOutlineView { 13 | 14 | } 15 | 16 | @end 17 | -------------------------------------------------------------------------------- /MacDependency/AutoExpandOutlineView.m: -------------------------------------------------------------------------------- 1 | // 2 | // AutoExpandOutlineView.m 3 | // MacDependency 4 | // 5 | // Created by Konrad Windszus on 03.09.09. 6 | // Copyright 2009 Konrad Windszus. All rights reserved. 7 | // 8 | 9 | #import "AutoExpandOutlineView.h" 10 | 11 | 12 | @implementation AutoExpandOutlineView 13 | 14 | 15 | // gets called after binding has changed 16 | - (void)reloadData; 17 | { 18 | [super reloadData]; 19 | 20 | // auto expand root item 21 | NSTreeNode* item = [self itemAtRow:0]; 22 | if (item) 23 | [self expandItem:item]; 24 | } 25 | 26 | @end 27 | -------------------------------------------------------------------------------- /MacDependency/Base.lproj/MainMenu.xib: -------------------------------------------------------------------------------- 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 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | -------------------------------------------------------------------------------- /MacDependency/ConversionStdString.h: -------------------------------------------------------------------------------- 1 | // 2 | // ConversionStdString.h 3 | // MacDependency 4 | // 5 | // Created by Konrad Windszus on 17.07.09. 6 | // Copyright 2009 Konrad Windszus. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | #include 12 | 13 | @interface NSString (ConversionStdString) 14 | 15 | + (NSString*) stringWithStdString:(const std::string&)string; 16 | - (std::string) stdString; 17 | + (NSString*) stringWithStdWString:(const std::wstring&)string; 18 | - (std::wstring) stdWString; 19 | @end 20 | -------------------------------------------------------------------------------- /MacDependency/ConversionStdString.mm: -------------------------------------------------------------------------------- 1 | // 2 | // ConversionStdString.m 3 | // MacDependency 4 | // 5 | // Created by Konrad Windszus on 17.07.09. 6 | // Copyright 2009 Konrad Windszus. All rights reserved. 7 | // 8 | // Conversion functions for NSString from/to std::string and std::wstring 9 | #import "ConversionStdString.h" 10 | 11 | 12 | @implementation NSString (ConversionStdString) 13 | + (NSString*) stringWithStdString:(const std::string&)string { 14 | return [NSString stringWithCString:string.c_str() encoding:NSASCIIStringEncoding]; 15 | } 16 | 17 | - (std::string) stdString { 18 | return std::string([self cStringUsingEncoding:NSASCIIStringEncoding]); 19 | } 20 | 21 | #if TARGET_RT_BIG_ENDIAN 22 | const NSStringEncoding kEncoding_wchar_t = 23 | CFStringConvertEncodingToNSStringEncoding(kCFStringEncodingUTF32BE); 24 | #else 25 | const NSStringEncoding kEncoding_wchar_t = 26 | CFStringConvertEncodingToNSStringEncoding(kCFStringEncodingUTF32LE); 27 | #endif 28 | 29 | +(NSString*) stringWithStdWString:(const std::wstring&)ws 30 | { 31 | char* data = (char*)ws.data(); 32 | size_t size = ws.size() * sizeof(wchar_t); 33 | 34 | NSString* result = [[NSString alloc] initWithBytes:data length:size 35 | encoding:kEncoding_wchar_t]; 36 | return result; 37 | } 38 | 39 | -(std::wstring) stdWString 40 | { 41 | NSData* asData = [self dataUsingEncoding:kEncoding_wchar_t]; 42 | return std::wstring((wchar_t*)[asData bytes], [asData length] / 43 | sizeof(wchar_t)); 44 | } 45 | 46 | @end 47 | -------------------------------------------------------------------------------- /MacDependency/ExtTreeModel.h: -------------------------------------------------------------------------------- 1 | // 2 | // ExtTreeModel.h 3 | // MacDependency 4 | // 5 | // Created by Konrad Windszus on 02.09.09. 6 | // Copyright 2009 Konrad Windszus. All rights reserved. 7 | // 8 | // Protocol which provides a method to get the parent (used by TreeControllerExtension) 9 | #import 10 | 11 | 12 | @protocol ExtTreeModel 13 | - (id) parent; 14 | @end 15 | -------------------------------------------------------------------------------- /MacDependency/Images.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "size" : "16x16", 5 | "idiom" : "mac", 6 | "filename" : "icon_16x16.png", 7 | "scale" : "1x" 8 | }, 9 | { 10 | "size" : "16x16", 11 | "idiom" : "mac", 12 | "filename" : "icon_16x16@2x.png", 13 | "scale" : "2x" 14 | }, 15 | { 16 | "size" : "32x32", 17 | "idiom" : "mac", 18 | "filename" : "icon_32x32.png", 19 | "scale" : "1x" 20 | }, 21 | { 22 | "size" : "32x32", 23 | "idiom" : "mac", 24 | "filename" : "icon_32x32@2x.png", 25 | "scale" : "2x" 26 | }, 27 | { 28 | "size" : "128x128", 29 | "idiom" : "mac", 30 | "filename" : "icon_128x128.png", 31 | "scale" : "1x" 32 | }, 33 | { 34 | "size" : "128x128", 35 | "idiom" : "mac", 36 | "filename" : "icon_128x128@2x.png", 37 | "scale" : "2x" 38 | }, 39 | { 40 | "size" : "256x256", 41 | "idiom" : "mac", 42 | "filename" : "icon_256x256.png", 43 | "scale" : "1x" 44 | }, 45 | { 46 | "size" : "256x256", 47 | "idiom" : "mac", 48 | "filename" : "icon_256x256@2x.png", 49 | "scale" : "2x" 50 | }, 51 | { 52 | "size" : "512x512", 53 | "idiom" : "mac", 54 | "filename" : "icon_512x512.png", 55 | "scale" : "1x" 56 | }, 57 | { 58 | "size" : "512x512", 59 | "idiom" : "mac", 60 | "filename" : "icon_512x512@2x.png", 61 | "scale" : "2x" 62 | } 63 | ], 64 | "info" : { 65 | "version" : 1, 66 | "author" : "xcode" 67 | } 68 | } -------------------------------------------------------------------------------- /MacDependency/Images.xcassets/AppIcon.appiconset/icon_128x128.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kwin/macdependency/1cf589d0ccceb9c90ee94b3ad3a79e67a66e5e38/MacDependency/Images.xcassets/AppIcon.appiconset/icon_128x128.png -------------------------------------------------------------------------------- /MacDependency/Images.xcassets/AppIcon.appiconset/icon_128x128@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kwin/macdependency/1cf589d0ccceb9c90ee94b3ad3a79e67a66e5e38/MacDependency/Images.xcassets/AppIcon.appiconset/icon_128x128@2x.png -------------------------------------------------------------------------------- /MacDependency/Images.xcassets/AppIcon.appiconset/icon_16x16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kwin/macdependency/1cf589d0ccceb9c90ee94b3ad3a79e67a66e5e38/MacDependency/Images.xcassets/AppIcon.appiconset/icon_16x16.png -------------------------------------------------------------------------------- /MacDependency/Images.xcassets/AppIcon.appiconset/icon_16x16@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kwin/macdependency/1cf589d0ccceb9c90ee94b3ad3a79e67a66e5e38/MacDependency/Images.xcassets/AppIcon.appiconset/icon_16x16@2x.png -------------------------------------------------------------------------------- /MacDependency/Images.xcassets/AppIcon.appiconset/icon_256x256.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kwin/macdependency/1cf589d0ccceb9c90ee94b3ad3a79e67a66e5e38/MacDependency/Images.xcassets/AppIcon.appiconset/icon_256x256.png -------------------------------------------------------------------------------- /MacDependency/Images.xcassets/AppIcon.appiconset/icon_256x256@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kwin/macdependency/1cf589d0ccceb9c90ee94b3ad3a79e67a66e5e38/MacDependency/Images.xcassets/AppIcon.appiconset/icon_256x256@2x.png -------------------------------------------------------------------------------- /MacDependency/Images.xcassets/AppIcon.appiconset/icon_32x32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kwin/macdependency/1cf589d0ccceb9c90ee94b3ad3a79e67a66e5e38/MacDependency/Images.xcassets/AppIcon.appiconset/icon_32x32.png -------------------------------------------------------------------------------- /MacDependency/Images.xcassets/AppIcon.appiconset/icon_32x32@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kwin/macdependency/1cf589d0ccceb9c90ee94b3ad3a79e67a66e5e38/MacDependency/Images.xcassets/AppIcon.appiconset/icon_32x32@2x.png -------------------------------------------------------------------------------- /MacDependency/Images.xcassets/AppIcon.appiconset/icon_512x512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kwin/macdependency/1cf589d0ccceb9c90ee94b3ad3a79e67a66e5e38/MacDependency/Images.xcassets/AppIcon.appiconset/icon_512x512.png -------------------------------------------------------------------------------- /MacDependency/Images.xcassets/AppIcon.appiconset/icon_512x512@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kwin/macdependency/1cf589d0ccceb9c90ee94b3ad3a79e67a66e5e38/MacDependency/Images.xcassets/AppIcon.appiconset/icon_512x512@2x.png -------------------------------------------------------------------------------- /MacDependency/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | English 7 | CFBundleDocumentTypes 8 | 9 | 10 | CFBundleTypeExtensions 11 | 12 | app 13 | txt 14 | * 15 | 16 | CFBundleTypeIconFile 17 | 18 | CFBundleTypeName 19 | DocumentType 20 | CFBundleTypeRole 21 | Viewer 22 | NSDocumentClass 23 | MyDocument 24 | 25 | 26 | CFBundleExecutable 27 | ${EXECUTABLE_NAME} 28 | CFBundleIdentifier 29 | $(PRODUCT_BUNDLE_IDENTIFIER) 30 | CFBundleInfoDictionaryVersion 31 | 6.0 32 | CFBundleName 33 | ${PRODUCT_NAME} 34 | CFBundlePackageType 35 | APPL 36 | CFBundleShortVersionString 37 | 1.1.1 38 | CFBundleSignature 39 | ???? 40 | LSApplicationCategoryType 41 | public.app-category.developer-tools 42 | NSMainNibFile 43 | MainMenu 44 | NSPrincipalClass 45 | NSApplication 46 | 47 | 48 | -------------------------------------------------------------------------------- /MacDependency/MacDependency.xcodeproj/TemplateIcon.icns: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kwin/macdependency/1cf589d0ccceb9c90ee94b3ad3a79e67a66e5e38/MacDependency/MacDependency.xcodeproj/TemplateIcon.icns -------------------------------------------------------------------------------- /MacDependency/MacDependency.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 46; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | 27817EA41DE0C139000AA552 /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 27817EA31DE0C139000AA552 /* Images.xcassets */; }; 11 | 8D15AC340486D014006FF6A4 /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1058C7A7FEA54F5311CA2CBB /* Cocoa.framework */; }; 12 | 8E1314FA100F7BFC00367510 /* MyDocument.mm in Sources */ = {isa = PBXBuildFile; fileRef = 8E1314F9100F7BFC00367510 /* MyDocument.mm */; }; 13 | 8E1314FC100F7C0C00367510 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 8E1314FB100F7C0C00367510 /* main.m */; }; 14 | 8E131507100F7C3C00367510 /* Credits.rtf in Resources */ = {isa = PBXBuildFile; fileRef = 8E1314FF100F7C3C00367510 /* Credits.rtf */; }; 15 | 8E131508100F7C3C00367510 /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 8E131501100F7C3C00367510 /* InfoPlist.strings */; }; 16 | 8E131509100F7C3C00367510 /* MainMenu.xib in Resources */ = {isa = PBXBuildFile; fileRef = 8E131503100F7C3C00367510 /* MainMenu.xib */; }; 17 | 8E13150A100F7C3C00367510 /* MyDocument.xib in Resources */ = {isa = PBXBuildFile; fileRef = 8E131505100F7C3C00367510 /* MyDocument.xib */; }; 18 | 8E1315C5100F8F1400367510 /* Localizable.strings in Resources */ = {isa = PBXBuildFile; fileRef = 8E1315C3100F8F1400367510 /* Localizable.strings */; }; 19 | 8E212D84101212FF0078924A /* SymbolTableEntryTypeFormatter.mm in Sources */ = {isa = PBXBuildFile; fileRef = 8E212D83101212FF0078924A /* SymbolTableEntryTypeFormatter.mm */; }; 20 | 8E49358B100A5714004B7E53 /* MachO.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 8E493565100A53DA004B7E53 /* MachO.framework */; }; 21 | 8E493597100A5871004B7E53 /* MachO.framework in Copy Frameworks */ = {isa = PBXBuildFile; fileRef = 8E493565100A53DA004B7E53 /* MachO.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, ); }; }; 22 | 8EAEBA2310126AB100E1D5D2 /* SymbolTableController.mm in Sources */ = {isa = PBXBuildFile; fileRef = 8EAEBA2210126AB100E1D5D2 /* SymbolTableController.mm */; }; 23 | 8EB56272104EA241006A44CD /* TreeControllerExtension.m in Sources */ = {isa = PBXBuildFile; fileRef = 8EB56271104EA241006A44CD /* TreeControllerExtension.m */; }; 24 | 8EB5640E104FE62F006A44CD /* AutoExpandOutlineView.m in Sources */ = {isa = PBXBuildFile; fileRef = 8EB5640D104FE62F006A44CD /* AutoExpandOutlineView.m */; }; 25 | 8EC4F16010400F02001F9FB8 /* ArchitecturesController.mm in Sources */ = {isa = PBXBuildFile; fileRef = 8EC4F15F10400F02001F9FB8 /* ArchitecturesController.mm */; }; 26 | 8EC4F16A1040126A001F9FB8 /* ArchitectureModel.mm in Sources */ = {isa = PBXBuildFile; fileRef = 8EC4F1691040126A001F9FB8 /* ArchitectureModel.mm */; }; 27 | 8ECFE3461061192D00685EDF /* PrioritySplitViewDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 8ECFE3451061192D00685EDF /* PrioritySplitViewDelegate.m */; }; 28 | 8ED32F48100B68FF00EBF623 /* MachOModel.mm in Sources */ = {isa = PBXBuildFile; fileRef = 8ED32F47100B68FF00EBF623 /* MachOModel.mm */; }; 29 | 8ED330CE100BD19800EBF623 /* SymbolTableEntryModel.mm in Sources */ = {isa = PBXBuildFile; fileRef = 8ED330CD100BD19800EBF623 /* SymbolTableEntryModel.mm */; }; 30 | 8ED4567B10516D6200FAC99F /* MyDocumentWindow.m in Sources */ = {isa = PBXBuildFile; fileRef = 8ED4567A10516D6200FAC99F /* MyDocumentWindow.m */; }; 31 | 8EFDEF7A101007B300E4D54D /* ConversionStdString.mm in Sources */ = {isa = PBXBuildFile; fileRef = 8EFDEF79101007B300E4D54D /* ConversionStdString.mm */; }; 32 | 8EFDEF9310100F1700E4D54D /* VersionFormatter.m in Sources */ = {isa = PBXBuildFile; fileRef = 8EFDEF9210100F1700E4D54D /* VersionFormatter.m */; }; 33 | /* End PBXBuildFile section */ 34 | 35 | /* Begin PBXContainerItemProxy section */ 36 | 8E493564100A53DA004B7E53 /* PBXContainerItemProxy */ = { 37 | isa = PBXContainerItemProxy; 38 | containerPortal = 8E493560100A53DA004B7E53 /* MachO.xcodeproj */; 39 | proxyType = 2; 40 | remoteGlobalIDString = 8DC2EF5B0486A6940098B216; 41 | remoteInfo = MachO; 42 | }; 43 | 8ED32F30100B5EFA00EBF623 /* PBXContainerItemProxy */ = { 44 | isa = PBXContainerItemProxy; 45 | containerPortal = 8E493560100A53DA004B7E53 /* MachO.xcodeproj */; 46 | proxyType = 1; 47 | remoteGlobalIDString = 8DC2EF4F0486A6940098B216; 48 | remoteInfo = MachO; 49 | }; 50 | /* End PBXContainerItemProxy section */ 51 | 52 | /* Begin PBXCopyFilesBuildPhase section */ 53 | 8E493598100A588F004B7E53 /* Copy Frameworks */ = { 54 | isa = PBXCopyFilesBuildPhase; 55 | buildActionMask = 2147483647; 56 | dstPath = ""; 57 | dstSubfolderSpec = 10; 58 | files = ( 59 | 8E493597100A5871004B7E53 /* MachO.framework in Copy Frameworks */, 60 | ); 61 | name = "Copy Frameworks"; 62 | runOnlyForDeploymentPostprocessing = 0; 63 | }; 64 | /* End PBXCopyFilesBuildPhase section */ 65 | 66 | /* Begin PBXFileReference section */ 67 | 1058C7A7FEA54F5311CA2CBB /* Cocoa.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Cocoa.framework; path = /System/Library/Frameworks/Cocoa.framework; sourceTree = ""; }; 68 | 13E42FBA07B3F13500E4EEF1 /* CoreData.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreData.framework; path = /System/Library/Frameworks/CoreData.framework; sourceTree = ""; }; 69 | 27817EA31DE0C139000AA552 /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Images.xcassets; sourceTree = ""; }; 70 | 2A37F4C4FDCFA73011CA2CEA /* AppKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AppKit.framework; path = /System/Library/Frameworks/AppKit.framework; sourceTree = ""; }; 71 | 2A37F4C5FDCFA73011CA2CEA /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = /System/Library/Frameworks/Foundation.framework; sourceTree = ""; }; 72 | 32DBCF750370BD2300C91783 /* MacDependency_Prefix.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MacDependency_Prefix.h; sourceTree = ""; }; 73 | 8D15AC370486D014006FF6A4 /* MacDependency.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = MacDependency.app; sourceTree = BUILT_PRODUCTS_DIR; }; 74 | 8E1314F8100F7BFC00367510 /* MyDocument.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MyDocument.h; sourceTree = ""; wrapsLines = 0; }; 75 | 8E1314F9100F7BFC00367510 /* MyDocument.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = MyDocument.mm; sourceTree = ""; wrapsLines = 0; }; 76 | 8E1314FB100F7C0C00367510 /* main.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; wrapsLines = 0; }; 77 | 8E1314FD100F7C1D00367510 /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 78 | 8E212D82101212FF0078924A /* SymbolTableEntryTypeFormatter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SymbolTableEntryTypeFormatter.h; sourceTree = ""; wrapsLines = 0; }; 79 | 8E212D83101212FF0078924A /* SymbolTableEntryTypeFormatter.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = SymbolTableEntryTypeFormatter.mm; sourceTree = ""; wrapsLines = 0; }; 80 | 8E493560100A53DA004B7E53 /* MachO.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = MachO.xcodeproj; path = ../MachO/MachO.xcodeproj; sourceTree = SOURCE_ROOT; }; 81 | 8EAEBA2110126AB100E1D5D2 /* SymbolTableController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SymbolTableController.h; sourceTree = ""; wrapsLines = 0; }; 82 | 8EAEBA2210126AB100E1D5D2 /* SymbolTableController.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = SymbolTableController.mm; sourceTree = ""; wrapsLines = 0; }; 83 | 8EB56270104EA241006A44CD /* TreeControllerExtension.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TreeControllerExtension.h; sourceTree = ""; wrapsLines = 0; }; 84 | 8EB56271104EA241006A44CD /* TreeControllerExtension.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TreeControllerExtension.m; sourceTree = ""; wrapsLines = 0; }; 85 | 8EB56382104EF61E006A44CD /* ExtTreeModel.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ExtTreeModel.h; sourceTree = ""; wrapsLines = 0; }; 86 | 8EB5640C104FE62F006A44CD /* AutoExpandOutlineView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AutoExpandOutlineView.h; sourceTree = ""; wrapsLines = 0; }; 87 | 8EB5640D104FE62F006A44CD /* AutoExpandOutlineView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AutoExpandOutlineView.m; sourceTree = ""; wrapsLines = 0; }; 88 | 8EC4F15E10400F02001F9FB8 /* ArchitecturesController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ArchitecturesController.h; sourceTree = ""; wrapsLines = 0; }; 89 | 8EC4F15F10400F02001F9FB8 /* ArchitecturesController.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = ArchitecturesController.mm; sourceTree = ""; wrapsLines = 0; }; 90 | 8EC4F1681040126A001F9FB8 /* ArchitectureModel.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ArchitectureModel.h; sourceTree = ""; wrapsLines = 0; }; 91 | 8EC4F1691040126A001F9FB8 /* ArchitectureModel.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = ArchitectureModel.mm; sourceTree = ""; wrapsLines = 0; }; 92 | 8ECFE3441061192D00685EDF /* PrioritySplitViewDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PrioritySplitViewDelegate.h; sourceTree = ""; wrapsLines = 0; }; 93 | 8ECFE3451061192D00685EDF /* PrioritySplitViewDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = PrioritySplitViewDelegate.m; sourceTree = ""; wrapsLines = 0; }; 94 | 8ED32F46100B68FF00EBF623 /* MachOModel.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MachOModel.h; sourceTree = ""; wrapsLines = 0; }; 95 | 8ED32F47100B68FF00EBF623 /* MachOModel.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = MachOModel.mm; sourceTree = ""; wrapsLines = 0; }; 96 | 8ED330CC100BD19800EBF623 /* SymbolTableEntryModel.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SymbolTableEntryModel.h; sourceTree = ""; wrapsLines = 0; }; 97 | 8ED330CD100BD19800EBF623 /* SymbolTableEntryModel.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = SymbolTableEntryModel.mm; sourceTree = ""; wrapsLines = 0; }; 98 | 8ED4567910516D6200FAC99F /* MyDocumentWindow.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MyDocumentWindow.h; sourceTree = ""; wrapsLines = 0; }; 99 | 8ED4567A10516D6200FAC99F /* MyDocumentWindow.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MyDocumentWindow.m; sourceTree = ""; wrapsLines = 0; }; 100 | 8EFDEF78101007B300E4D54D /* ConversionStdString.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ConversionStdString.h; sourceTree = ""; wrapsLines = 0; }; 101 | 8EFDEF79101007B300E4D54D /* ConversionStdString.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = ConversionStdString.mm; sourceTree = ""; wrapsLines = 0; }; 102 | 8EFDEF9110100F1700E4D54D /* VersionFormatter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = VersionFormatter.h; sourceTree = ""; wrapsLines = 0; }; 103 | 8EFDEF9210100F1700E4D54D /* VersionFormatter.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = VersionFormatter.m; sourceTree = ""; wrapsLines = 0; }; 104 | ADCDF191276D87BD002476ED /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/MainMenu.xib; sourceTree = ""; }; 105 | ADCDF192276D87BD002476ED /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/MyDocument.xib; sourceTree = ""; }; 106 | ADCDF194276D87BF002476ED /* en */ = {isa = PBXFileReference; lastKnownFileType = text.rtf; name = en; path = en.lproj/Credits.rtf; sourceTree = ""; }; 107 | ADCDF195276D87BF002476ED /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/InfoPlist.strings; sourceTree = ""; }; 108 | ADCDF196276D87BF002476ED /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/Localizable.strings; sourceTree = ""; }; 109 | /* End PBXFileReference section */ 110 | 111 | /* Begin PBXFrameworksBuildPhase section */ 112 | 8D15AC330486D014006FF6A4 /* Frameworks */ = { 113 | isa = PBXFrameworksBuildPhase; 114 | buildActionMask = 2147483647; 115 | files = ( 116 | 8E49358B100A5714004B7E53 /* MachO.framework in Frameworks */, 117 | 8D15AC340486D014006FF6A4 /* Cocoa.framework in Frameworks */, 118 | ); 119 | runOnlyForDeploymentPostprocessing = 0; 120 | }; 121 | /* End PBXFrameworksBuildPhase section */ 122 | 123 | /* Begin PBXGroup section */ 124 | 1058C7A6FEA54F5311CA2CBB /* Linked Frameworks */ = { 125 | isa = PBXGroup; 126 | children = ( 127 | 1058C7A7FEA54F5311CA2CBB /* Cocoa.framework */, 128 | ); 129 | name = "Linked Frameworks"; 130 | sourceTree = ""; 131 | }; 132 | 1058C7A8FEA54F5311CA2CBB /* Other Frameworks */ = { 133 | isa = PBXGroup; 134 | children = ( 135 | 2A37F4C4FDCFA73011CA2CEA /* AppKit.framework */, 136 | 13E42FBA07B3F13500E4EEF1 /* CoreData.framework */, 137 | 2A37F4C5FDCFA73011CA2CEA /* Foundation.framework */, 138 | ); 139 | name = "Other Frameworks"; 140 | sourceTree = ""; 141 | }; 142 | 19C28FB0FE9D524F11CA2CBB /* Products */ = { 143 | isa = PBXGroup; 144 | children = ( 145 | 8D15AC370486D014006FF6A4 /* MacDependency.app */, 146 | ); 147 | name = Products; 148 | sourceTree = ""; 149 | }; 150 | 2A37F4AAFDCFA73011CA2CEA /* MacDependency */ = { 151 | isa = PBXGroup; 152 | children = ( 153 | 8E493560100A53DA004B7E53 /* MachO.xcodeproj */, 154 | 2A37F4ABFDCFA73011CA2CEA /* Classes */, 155 | 2A37F4AFFDCFA73011CA2CEA /* Other Sources */, 156 | 2A37F4B8FDCFA73011CA2CEA /* Resources */, 157 | 2A37F4C3FDCFA73011CA2CEA /* Frameworks */, 158 | 19C28FB0FE9D524F11CA2CBB /* Products */, 159 | ); 160 | name = MacDependency; 161 | sourceTree = ""; 162 | }; 163 | 2A37F4ABFDCFA73011CA2CEA /* Classes */ = { 164 | isa = PBXGroup; 165 | children = ( 166 | 8ECFE3441061192D00685EDF /* PrioritySplitViewDelegate.h */, 167 | 8ECFE3451061192D00685EDF /* PrioritySplitViewDelegate.m */, 168 | 8EC4F15E10400F02001F9FB8 /* ArchitecturesController.h */, 169 | 8EC4F15F10400F02001F9FB8 /* ArchitecturesController.mm */, 170 | 8E1314F8100F7BFC00367510 /* MyDocument.h */, 171 | 8E1314F9100F7BFC00367510 /* MyDocument.mm */, 172 | 8ED32F46100B68FF00EBF623 /* MachOModel.h */, 173 | 8ED32F47100B68FF00EBF623 /* MachOModel.mm */, 174 | 8EC4F1691040126A001F9FB8 /* ArchitectureModel.mm */, 175 | 8EC4F1681040126A001F9FB8 /* ArchitectureModel.h */, 176 | 8ED330CC100BD19800EBF623 /* SymbolTableEntryModel.h */, 177 | 8ED330CD100BD19800EBF623 /* SymbolTableEntryModel.mm */, 178 | 8EFDEF78101007B300E4D54D /* ConversionStdString.h */, 179 | 8EFDEF79101007B300E4D54D /* ConversionStdString.mm */, 180 | 8EFDEF9110100F1700E4D54D /* VersionFormatter.h */, 181 | 8EFDEF9210100F1700E4D54D /* VersionFormatter.m */, 182 | 8E212D82101212FF0078924A /* SymbolTableEntryTypeFormatter.h */, 183 | 8E212D83101212FF0078924A /* SymbolTableEntryTypeFormatter.mm */, 184 | 8EAEBA2110126AB100E1D5D2 /* SymbolTableController.h */, 185 | 8EAEBA2210126AB100E1D5D2 /* SymbolTableController.mm */, 186 | 8EB56270104EA241006A44CD /* TreeControllerExtension.h */, 187 | 8EB56271104EA241006A44CD /* TreeControllerExtension.m */, 188 | 8EB56382104EF61E006A44CD /* ExtTreeModel.h */, 189 | 8EB5640C104FE62F006A44CD /* AutoExpandOutlineView.h */, 190 | 8EB5640D104FE62F006A44CD /* AutoExpandOutlineView.m */, 191 | 8ED4567910516D6200FAC99F /* MyDocumentWindow.h */, 192 | 8ED4567A10516D6200FAC99F /* MyDocumentWindow.m */, 193 | ); 194 | name = Classes; 195 | sourceTree = ""; 196 | }; 197 | 2A37F4AFFDCFA73011CA2CEA /* Other Sources */ = { 198 | isa = PBXGroup; 199 | children = ( 200 | 8E1314FB100F7C0C00367510 /* main.m */, 201 | 32DBCF750370BD2300C91783 /* MacDependency_Prefix.h */, 202 | ); 203 | name = "Other Sources"; 204 | sourceTree = ""; 205 | }; 206 | 2A37F4B8FDCFA73011CA2CEA /* Resources */ = { 207 | isa = PBXGroup; 208 | children = ( 209 | 27817EA31DE0C139000AA552 /* Images.xcassets */, 210 | 8E1314FF100F7C3C00367510 /* Credits.rtf */, 211 | 8E131501100F7C3C00367510 /* InfoPlist.strings */, 212 | 8E131503100F7C3C00367510 /* MainMenu.xib */, 213 | 8E131505100F7C3C00367510 /* MyDocument.xib */, 214 | 8E1314FD100F7C1D00367510 /* Info.plist */, 215 | 8E1315C3100F8F1400367510 /* Localizable.strings */, 216 | ); 217 | name = Resources; 218 | sourceTree = ""; 219 | }; 220 | 2A37F4C3FDCFA73011CA2CEA /* Frameworks */ = { 221 | isa = PBXGroup; 222 | children = ( 223 | 1058C7A6FEA54F5311CA2CBB /* Linked Frameworks */, 224 | 1058C7A8FEA54F5311CA2CBB /* Other Frameworks */, 225 | ); 226 | name = Frameworks; 227 | sourceTree = ""; 228 | }; 229 | 8E493561100A53DA004B7E53 /* Products */ = { 230 | isa = PBXGroup; 231 | children = ( 232 | 8E493565100A53DA004B7E53 /* MachO.framework */, 233 | ); 234 | name = Products; 235 | sourceTree = ""; 236 | }; 237 | /* End PBXGroup section */ 238 | 239 | /* Begin PBXNativeTarget section */ 240 | 8D15AC270486D014006FF6A4 /* MacDependency */ = { 241 | isa = PBXNativeTarget; 242 | buildConfigurationList = C05733C708A9546B00998B17 /* Build configuration list for PBXNativeTarget "MacDependency" */; 243 | buildPhases = ( 244 | 8D15AC2B0486D014006FF6A4 /* Resources */, 245 | 8D15AC300486D014006FF6A4 /* Sources */, 246 | 8D15AC330486D014006FF6A4 /* Frameworks */, 247 | 8E493598100A588F004B7E53 /* Copy Frameworks */, 248 | ); 249 | buildRules = ( 250 | ); 251 | dependencies = ( 252 | 8ED32F31100B5EFA00EBF623 /* PBXTargetDependency */, 253 | ); 254 | name = MacDependency; 255 | productInstallPath = "$(HOME)/Applications"; 256 | productName = MacDependency; 257 | productReference = 8D15AC370486D014006FF6A4 /* MacDependency.app */; 258 | productType = "com.apple.product-type.application"; 259 | }; 260 | /* End PBXNativeTarget section */ 261 | 262 | /* Begin PBXProject section */ 263 | 2A37F4A9FDCFA73011CA2CEA /* Project object */ = { 264 | isa = PBXProject; 265 | attributes = { 266 | LastUpgradeCheck = 1310; 267 | ORGANIZATIONNAME = "Konrad Windszus"; 268 | }; 269 | buildConfigurationList = C05733CB08A9546B00998B17 /* Build configuration list for PBXProject "MacDependency" */; 270 | compatibilityVersion = "Xcode 3.2"; 271 | developmentRegion = en; 272 | hasScannedForEncodings = 1; 273 | knownRegions = ( 274 | English, 275 | en, 276 | Base, 277 | ); 278 | mainGroup = 2A37F4AAFDCFA73011CA2CEA /* MacDependency */; 279 | projectDirPath = ""; 280 | projectReferences = ( 281 | { 282 | ProductGroup = 8E493561100A53DA004B7E53 /* Products */; 283 | ProjectRef = 8E493560100A53DA004B7E53 /* MachO.xcodeproj */; 284 | }, 285 | ); 286 | projectRoot = ""; 287 | targets = ( 288 | 8D15AC270486D014006FF6A4 /* MacDependency */, 289 | ); 290 | }; 291 | /* End PBXProject section */ 292 | 293 | /* Begin PBXReferenceProxy section */ 294 | 8E493565100A53DA004B7E53 /* MachO.framework */ = { 295 | isa = PBXReferenceProxy; 296 | fileType = wrapper.framework; 297 | path = MachO.framework; 298 | remoteRef = 8E493564100A53DA004B7E53 /* PBXContainerItemProxy */; 299 | sourceTree = BUILT_PRODUCTS_DIR; 300 | }; 301 | /* End PBXReferenceProxy section */ 302 | 303 | /* Begin PBXResourcesBuildPhase section */ 304 | 8D15AC2B0486D014006FF6A4 /* Resources */ = { 305 | isa = PBXResourcesBuildPhase; 306 | buildActionMask = 2147483647; 307 | files = ( 308 | 8E131507100F7C3C00367510 /* Credits.rtf in Resources */, 309 | 8E131508100F7C3C00367510 /* InfoPlist.strings in Resources */, 310 | 8E131509100F7C3C00367510 /* MainMenu.xib in Resources */, 311 | 27817EA41DE0C139000AA552 /* Images.xcassets in Resources */, 312 | 8E13150A100F7C3C00367510 /* MyDocument.xib in Resources */, 313 | 8E1315C5100F8F1400367510 /* Localizable.strings in Resources */, 314 | ); 315 | runOnlyForDeploymentPostprocessing = 0; 316 | }; 317 | /* End PBXResourcesBuildPhase section */ 318 | 319 | /* Begin PBXSourcesBuildPhase section */ 320 | 8D15AC300486D014006FF6A4 /* Sources */ = { 321 | isa = PBXSourcesBuildPhase; 322 | buildActionMask = 2147483647; 323 | files = ( 324 | 8ED32F48100B68FF00EBF623 /* MachOModel.mm in Sources */, 325 | 8ED330CE100BD19800EBF623 /* SymbolTableEntryModel.mm in Sources */, 326 | 8E1314FA100F7BFC00367510 /* MyDocument.mm in Sources */, 327 | 8E1314FC100F7C0C00367510 /* main.m in Sources */, 328 | 8EFDEF7A101007B300E4D54D /* ConversionStdString.mm in Sources */, 329 | 8EFDEF9310100F1700E4D54D /* VersionFormatter.m in Sources */, 330 | 8E212D84101212FF0078924A /* SymbolTableEntryTypeFormatter.mm in Sources */, 331 | 8EAEBA2310126AB100E1D5D2 /* SymbolTableController.mm in Sources */, 332 | 8EC4F16010400F02001F9FB8 /* ArchitecturesController.mm in Sources */, 333 | 8EC4F16A1040126A001F9FB8 /* ArchitectureModel.mm in Sources */, 334 | 8EB56272104EA241006A44CD /* TreeControllerExtension.m in Sources */, 335 | 8EB5640E104FE62F006A44CD /* AutoExpandOutlineView.m in Sources */, 336 | 8ED4567B10516D6200FAC99F /* MyDocumentWindow.m in Sources */, 337 | 8ECFE3461061192D00685EDF /* PrioritySplitViewDelegate.m in Sources */, 338 | ); 339 | runOnlyForDeploymentPostprocessing = 0; 340 | }; 341 | /* End PBXSourcesBuildPhase section */ 342 | 343 | /* Begin PBXTargetDependency section */ 344 | 8ED32F31100B5EFA00EBF623 /* PBXTargetDependency */ = { 345 | isa = PBXTargetDependency; 346 | name = MachO; 347 | targetProxy = 8ED32F30100B5EFA00EBF623 /* PBXContainerItemProxy */; 348 | }; 349 | /* End PBXTargetDependency section */ 350 | 351 | /* Begin PBXVariantGroup section */ 352 | 8E1314FF100F7C3C00367510 /* Credits.rtf */ = { 353 | isa = PBXVariantGroup; 354 | children = ( 355 | ADCDF194276D87BF002476ED /* en */, 356 | ); 357 | name = Credits.rtf; 358 | sourceTree = ""; 359 | }; 360 | 8E131501100F7C3C00367510 /* InfoPlist.strings */ = { 361 | isa = PBXVariantGroup; 362 | children = ( 363 | ADCDF195276D87BF002476ED /* en */, 364 | ); 365 | name = InfoPlist.strings; 366 | sourceTree = ""; 367 | }; 368 | 8E131503100F7C3C00367510 /* MainMenu.xib */ = { 369 | isa = PBXVariantGroup; 370 | children = ( 371 | ADCDF191276D87BD002476ED /* Base */, 372 | ); 373 | name = MainMenu.xib; 374 | sourceTree = ""; 375 | }; 376 | 8E131505100F7C3C00367510 /* MyDocument.xib */ = { 377 | isa = PBXVariantGroup; 378 | children = ( 379 | ADCDF192276D87BD002476ED /* Base */, 380 | ); 381 | name = MyDocument.xib; 382 | sourceTree = ""; 383 | }; 384 | 8E1315C3100F8F1400367510 /* Localizable.strings */ = { 385 | isa = PBXVariantGroup; 386 | children = ( 387 | ADCDF196276D87BF002476ED /* en */, 388 | ); 389 | name = Localizable.strings; 390 | sourceTree = ""; 391 | }; 392 | /* End PBXVariantGroup section */ 393 | 394 | /* Begin XCBuildConfiguration section */ 395 | C05733C808A9546B00998B17 /* Debug */ = { 396 | isa = XCBuildConfiguration; 397 | buildSettings = { 398 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 399 | CLANG_ENABLE_OBJC_ARC = YES; 400 | CODE_SIGN_IDENTITY = "-"; 401 | COPY_PHASE_STRIP = NO; 402 | GCC_DYNAMIC_NO_PIC = NO; 403 | GCC_MODEL_TUNING = G5; 404 | GCC_OPTIMIZATION_LEVEL = 0; 405 | INFOPLIST_FILE = Info.plist; 406 | MACOSX_DEPLOYMENT_TARGET = 10.9; 407 | PRODUCT_BUNDLE_IDENTIFIER = "com.googlecode.${PRODUCT_NAME:identifier}"; 408 | PRODUCT_NAME = MacDependency; 409 | SDKROOT = macosx; 410 | }; 411 | name = Debug; 412 | }; 413 | C05733C908A9546B00998B17 /* Release */ = { 414 | isa = XCBuildConfiguration; 415 | buildSettings = { 416 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 417 | CLANG_ENABLE_OBJC_ARC = YES; 418 | CODE_SIGN_IDENTITY = "-"; 419 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 420 | GCC_MODEL_TUNING = G5; 421 | INFOPLIST_FILE = Info.plist; 422 | MACOSX_DEPLOYMENT_TARGET = 10.9; 423 | PRODUCT_BUNDLE_IDENTIFIER = "com.googlecode.${PRODUCT_NAME:identifier}"; 424 | PRODUCT_NAME = MacDependency; 425 | SDKROOT = macosx; 426 | }; 427 | name = Release; 428 | }; 429 | C05733CC08A9546B00998B17 /* Debug */ = { 430 | isa = XCBuildConfiguration; 431 | buildSettings = { 432 | ALWAYS_SEARCH_USER_PATHS = NO; 433 | CLANG_CXX_LANGUAGE_STANDARD = "c++0x"; 434 | CLANG_CXX_LIBRARY = "libc++"; 435 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 436 | CLANG_WARN_BOOL_CONVERSION = YES; 437 | CLANG_WARN_COMMA = YES; 438 | CLANG_WARN_CONSTANT_CONVERSION = YES; 439 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 440 | CLANG_WARN_EMPTY_BODY = YES; 441 | CLANG_WARN_ENUM_CONVERSION = YES; 442 | CLANG_WARN_INFINITE_RECURSION = YES; 443 | CLANG_WARN_INT_CONVERSION = YES; 444 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 445 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 446 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 447 | CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; 448 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 449 | CLANG_WARN_STRICT_PROTOTYPES = YES; 450 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 451 | CLANG_WARN_UNREACHABLE_CODE = YES; 452 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 453 | ENABLE_STRICT_OBJC_MSGSEND = YES; 454 | ENABLE_TESTABILITY = YES; 455 | GCC_C_LANGUAGE_STANDARD = c99; 456 | GCC_NO_COMMON_BLOCKS = YES; 457 | GCC_OPTIMIZATION_LEVEL = 0; 458 | GCC_PRECOMPILE_PREFIX_HEADER = YES; 459 | GCC_PREFIX_HEADER = MacDependency_Prefix.h; 460 | GCC_TREAT_IMPLICIT_FUNCTION_DECLARATIONS_AS_ERRORS = YES; 461 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 462 | GCC_WARN_ABOUT_MISSING_FIELD_INITIALIZERS = YES; 463 | GCC_WARN_ABOUT_MISSING_PROTOTYPES = YES; 464 | GCC_WARN_ABOUT_RETURN_TYPE = YES; 465 | GCC_WARN_ALLOW_INCOMPLETE_PROTOCOL = YES; 466 | GCC_WARN_CHECK_SWITCH_STATEMENTS = YES; 467 | GCC_WARN_FOUR_CHARACTER_CONSTANTS = YES; 468 | GCC_WARN_NON_VIRTUAL_DESTRUCTOR = YES; 469 | GCC_WARN_SHADOW = YES; 470 | GCC_WARN_STRICT_SELECTOR_MATCH = YES; 471 | GCC_WARN_UNDECLARED_SELECTOR = YES; 472 | GCC_WARN_UNINITIALIZED_AUTOS = YES; 473 | GCC_WARN_UNUSED_FUNCTION = YES; 474 | GCC_WARN_UNUSED_LABEL = YES; 475 | GCC_WARN_UNUSED_VALUE = YES; 476 | GCC_WARN_UNUSED_VARIABLE = YES; 477 | HEADER_SEARCH_PATHS = ( 478 | /opt/local/include, 479 | ./../, 480 | ); 481 | MACOSX_DEPLOYMENT_TARGET = 10.7; 482 | ONLY_ACTIVE_ARCH = YES; 483 | SDKROOT = macosx; 484 | }; 485 | name = Debug; 486 | }; 487 | C05733CD08A9546B00998B17 /* Release */ = { 488 | isa = XCBuildConfiguration; 489 | buildSettings = { 490 | ALWAYS_SEARCH_USER_PATHS = NO; 491 | CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES; 492 | CLANG_CXX_LANGUAGE_STANDARD = "c++0x"; 493 | CLANG_CXX_LIBRARY = "libc++"; 494 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 495 | CLANG_WARN_BOOL_CONVERSION = YES; 496 | CLANG_WARN_COMMA = YES; 497 | CLANG_WARN_CONSTANT_CONVERSION = YES; 498 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 499 | CLANG_WARN_EMPTY_BODY = YES; 500 | CLANG_WARN_ENUM_CONVERSION = YES; 501 | CLANG_WARN_INFINITE_RECURSION = YES; 502 | CLANG_WARN_INT_CONVERSION = YES; 503 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 504 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 505 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 506 | CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; 507 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 508 | CLANG_WARN_STRICT_PROTOTYPES = YES; 509 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 510 | CLANG_WARN_UNREACHABLE_CODE = YES; 511 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 512 | ENABLE_STRICT_OBJC_MSGSEND = YES; 513 | GCC_C_LANGUAGE_STANDARD = c99; 514 | GCC_NO_COMMON_BLOCKS = YES; 515 | GCC_PRECOMPILE_PREFIX_HEADER = YES; 516 | GCC_PREFIX_HEADER = MacDependency_Prefix.h; 517 | GCC_WARN_ABOUT_RETURN_TYPE = YES; 518 | GCC_WARN_UNINITIALIZED_AUTOS = YES; 519 | GCC_WARN_UNUSED_VARIABLE = YES; 520 | HEADER_SEARCH_PATHS = ( 521 | /opt/local/include, 522 | ./../, 523 | ); 524 | MACOSX_DEPLOYMENT_TARGET = 10.9; 525 | SDKROOT = macosx; 526 | }; 527 | name = Release; 528 | }; 529 | /* End XCBuildConfiguration section */ 530 | 531 | /* Begin XCConfigurationList section */ 532 | C05733C708A9546B00998B17 /* Build configuration list for PBXNativeTarget "MacDependency" */ = { 533 | isa = XCConfigurationList; 534 | buildConfigurations = ( 535 | C05733C808A9546B00998B17 /* Debug */, 536 | C05733C908A9546B00998B17 /* Release */, 537 | ); 538 | defaultConfigurationIsVisible = 0; 539 | defaultConfigurationName = Release; 540 | }; 541 | C05733CB08A9546B00998B17 /* Build configuration list for PBXProject "MacDependency" */ = { 542 | isa = XCConfigurationList; 543 | buildConfigurations = ( 544 | C05733CC08A9546B00998B17 /* Debug */, 545 | C05733CD08A9546B00998B17 /* Release */, 546 | ); 547 | defaultConfigurationIsVisible = 0; 548 | defaultConfigurationName = Release; 549 | }; 550 | /* End XCConfigurationList section */ 551 | }; 552 | rootObject = 2A37F4A9FDCFA73011CA2CEA /* Project object */; 553 | } 554 | -------------------------------------------------------------------------------- /MacDependency/MacDependency.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /MacDependency/MacDependency.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /MacDependency/MacDependency.xcodeproj/xcshareddata/xcschemes/MacDependency.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 37 | 38 | 39 | 40 | 41 | 42 | 52 | 54 | 60 | 61 | 62 | 63 | 69 | 71 | 77 | 78 | 79 | 80 | 82 | 83 | 86 | 87 | 88 | -------------------------------------------------------------------------------- /MacDependency/MacDependency_Prefix.h: -------------------------------------------------------------------------------- 1 | // 2 | // Prefix header for all source files of the 'MacDependency' target in the 'MacDependency' project 3 | // 4 | 5 | #ifdef __OBJC__ 6 | #import 7 | #endif 8 | 9 | #ifdef __cplusplus 10 | 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include 18 | 19 | #include 20 | #include 21 | 22 | #endif 23 | -------------------------------------------------------------------------------- /MacDependency/MachOModel.h: -------------------------------------------------------------------------------- 1 | // 2 | // MachOModel.h 3 | // MacDependency 4 | // 5 | // Created by Konrad Windszus on 13.07.09. 6 | // Copyright 2009 Konrad Windszus. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "ExtTreeModel.h" 11 | #import "MachO/machoarchitecture.h" 12 | #import "MachO/dylibcommand.h" 13 | #import "MachO/macho.h" 14 | #import "ArchitecturesController.h" 15 | 16 | @class MyDocument; 17 | 18 | enum State { 19 | StateNormal, 20 | StateWarning, 21 | StateError 22 | }; 23 | 24 | @interface MachOModel : NSObject { 25 | NSMutableArray* children; 26 | MachO* file; 27 | MyDocument* document; 28 | MachOModel* parent; 29 | MachOArchitecture* architecture; // current architecture 30 | DylibCommand* command; 31 | State state; 32 | } 33 | 34 | - (id) initWithFile:(MachO*)machO document:(MyDocument*)document architecture:(MachOArchitecture*)architecture loadChildren:(BOOL)loadChildren; 35 | - (id) initWithFilename:(std::string&)filename command:(DylibCommand*)command document:(MyDocument*)document parent:(MachOModel*)parent; 36 | 37 | - (NSArray*) children; 38 | - (BOOL) isLeaf; 39 | - (NSColor*) textColor; 40 | - (NSString*) name; 41 | - (NSNumber*) currentVersion; 42 | - (NSNumber*) compatibleVersion; 43 | - (NSString*) filename; 44 | - (NSString*) dependencyType; 45 | - (NSString*) version; 46 | - (NSDate*) lastModificationTime; 47 | - (NSArray*) architectures; 48 | - (NSNumber*) size; 49 | 50 | @end 51 | -------------------------------------------------------------------------------- /MacDependency/MachOModel.mm: -------------------------------------------------------------------------------- 1 | // 2 | // MachOModel.m 3 | // MacDependency 4 | // 5 | // Created by Konrad Windszus on 13.07.09. 6 | // Copyright 2009 Konrad Windszus. All rights reserved. 7 | // 8 | 9 | #import "MachOModel.h" 10 | #import "MyDocument.h" 11 | 12 | #import "ConversionStdString.h" 13 | #import "VersionFormatter.h" 14 | #import "ArchitectureModel.h" 15 | 16 | #include "MachO/machoexception.h" 17 | #include "MachO/machoheader.h" 18 | #include "MachO/symboltablecommand.h" 19 | 20 | 21 | // declare private methods 22 | @interface MachOModel () 23 | - (void) initChildren; 24 | - (void) checkConstraints:(DylibCommand*) dylibId; 25 | - (void) setStateWithWarning:(BOOL)isWarning; 26 | - (id) initWithFile:(MachO*)file command:(DylibCommand*)command document:(MyDocument*)document parent:(MachOModel*)parent architecture:(MachOArchitecture*)architecture; 27 | @end 28 | 29 | @implementation MachOModel 30 | 31 | - (id) initWithFile:(MachO*)aFile document:(MyDocument*)aDocument architecture:(MachOArchitecture*)anArchitecture loadChildren:(BOOL)loadChildren { 32 | state = StateNormal; 33 | if (!(self = [self initWithFile:aFile command:nil document:aDocument parent:nil architecture:anArchitecture])) return nil; 34 | if (loadChildren) { 35 | [self initChildren]; 36 | } 37 | return self; 38 | } 39 | 40 | // called by initChildren (calls initWithFile internally) 41 | - (id) initWithFilename:(std::string&)filename command:(DylibCommand*)aCommand document:(MyDocument*)aDocument parent:(MachOModel*)aParent { 42 | BOOL isWeakReference = (command && !command->isNecessary()); 43 | MachO* aFile = nullptr; 44 | MachOArchitecture* anArchitecture = nullptr; 45 | state = StateNormal; 46 | try { 47 | aFile = [aDocument cache]->getFile(filename, aParent->file); // throws exception in case file is not found 48 | anArchitecture = aFile->getCompatibleArchitecture(aParent->architecture); 49 | if (!anArchitecture) { 50 | [self setStateWithWarning:isWeakReference]; 51 | NSString* log = [NSString stringWithFormat:NSLocalizedString(@"ERR_ARCHITECTURE_MISMATCH", nil), filename.c_str(), [parent name]]; 52 | [aDocument appendLogLine:log withModel:self state:state]; 53 | } 54 | 55 | } catch (MachOException& exc) { 56 | [self setStateWithWarning:isWeakReference]; 57 | NSString* log = [NSString stringWithStdString:exc.getCause()]; 58 | [aDocument appendLogLine:log withModel:self state:state]; 59 | // distinguish between weak and strong. In both cases append to tree with a status color 60 | } 61 | [aDocument incrementNumDependencies]; 62 | if (!(self = [self initWithFile:aFile command:aCommand document:aDocument parent:aParent architecture:anArchitecture])) return nil; 63 | return self; 64 | } 65 | 66 | // private 67 | - (id) initWithFile:(MachO*)aFile command:(DylibCommand*)aCommand document:(MyDocument*)aDocument parent:(MachOModel*)aParent architecture:(MachOArchitecture*)anArchitecture { 68 | if (self = [super init]) { 69 | document = aDocument; 70 | parent = aParent; 71 | command = aCommand; 72 | file = aFile; 73 | children = nil; 74 | architecture = anArchitecture; 75 | if (architecture) { 76 | DylibCommand* dylibId = architecture->getDynamicLibIdCommand(); 77 | if (dylibId && command) { 78 | [self checkConstraints:dylibId]; 79 | } 80 | } 81 | 82 | } return self; 83 | } 84 | 85 | 86 | - (void) setStateWithWarning:(BOOL)isWarning { 87 | State newState = StateError; 88 | if (isWarning) { 89 | newState = StateWarning; 90 | } 91 | 92 | if (self->state < newState) { 93 | self->state = newState; 94 | } 95 | } 96 | 97 | - (id) parent { 98 | return parent; 99 | } 100 | 101 | - (void) checkConstraints:(DylibCommand*) dylibId { 102 | // check version information (only compatible version information is relevant) 103 | unsigned int minVersion = dylibId->getCompatibleVersion(); 104 | unsigned int requestedMinVersion = command->getCompatibleVersion(); 105 | unsigned int requestedMaxVersion = command->getCurrentVersion(); 106 | 107 | VersionFormatter* versionFormatter = [[VersionFormatter alloc] init]; 108 | 109 | BOOL isWeakReference = (command && !command->isNecessary()); 110 | 111 | NSString* log; 112 | // check minimum version 113 | if (minVersion != 0 && requestedMinVersion != 0 && minVersion < requestedMinVersion) { 114 | [self setStateWithWarning:isWeakReference]; 115 | log = [NSString stringWithFormat:NSLocalizedString(@"ERR_MINIMUM_VERSION", nil), parent->command->getName().c_str(), [parent name], [versionFormatter stringForObjectValue:[NSNumber numberWithUnsignedInt:requestedMinVersion]], [versionFormatter stringForObjectValue:[NSNumber numberWithUnsignedInt:minVersion]]]; 116 | [document appendLogLine:log withModel:self state:state]; 117 | 118 | } 119 | 120 | // extended checks which are currently not done by dyld 121 | 122 | // check maximum version 123 | if (minVersion != 0 && requestedMaxVersion != 0 && minVersion > requestedMaxVersion) { 124 | [self setStateWithWarning:YES]; 125 | log = [NSString stringWithFormat:NSLocalizedString(@"ERR_MAXIMUM_VERSION", nil), command->getName().c_str(), [parent name], [versionFormatter stringForObjectValue:[NSNumber numberWithUnsignedInt:requestedMaxVersion]], [versionFormatter stringForObjectValue:[NSNumber numberWithUnsignedInt:minVersion]]]; 126 | [document appendLogLine:log withModel:self state:state]; 127 | 128 | } 129 | 130 | // check names 131 | if (dylibId->getName() != command->getName()) { 132 | [self setStateWithWarning:YES]; 133 | log = [NSString stringWithFormat:NSLocalizedString(@"ERR_NAME_MISMATCH", nil), command->getName().c_str(), [parent name], dylibId->getName().c_str()]; 134 | [document appendLogLine:log withModel:self state:state]; 135 | } 136 | 137 | // TODO: check for relative paths, since they can lead to problems 138 | } 139 | 140 | - (NSArray*)children { 141 | if (children == nil) { 142 | [self initChildren]; 143 | } 144 | return children; 145 | } 146 | 147 | - (void) initChildren { 148 | // TODO: tweak capacity 149 | children = [NSMutableArray arrayWithCapacity:20]; 150 | if (architecture) { 151 | std::string workingDirectory = [[document workingDirectory] stdString]; 152 | for (MachOArchitecture::LoadCommandsConstIterator it = architecture->getLoadCommandsBegin(); 153 | it != architecture->getLoadCommandsEnd(); 154 | ++it) { 155 | 156 | LoadCommand* childLoadCommand = (*it); 157 | // check if it is dylibcommand 158 | DylibCommand* dylibCommand = dynamic_cast (childLoadCommand); 159 | if (dylibCommand != NULL && !dylibCommand->isId()) { 160 | std::string filename = architecture->getResolvedName(dylibCommand->getName(), workingDirectory); 161 | 162 | [children addObject: [[MachOModel alloc] initWithFilename: filename command: dylibCommand document: document parent: self]]; 163 | } 164 | } 165 | } 166 | } 167 | 168 | - (BOOL)isLeaf { 169 | [self children]; 170 | if ([children count] == 0) 171 | return YES; 172 | return NO; 173 | } 174 | 175 | - (NSColor*) textColor { 176 | NSColor* color; 177 | switch(state) { 178 | case StateWarning: 179 | color = [NSColor systemOrangeColor]; 180 | break; 181 | case StateError: 182 | color = [NSColor systemOrangeColor]; 183 | break; 184 | default: 185 | color = [NSColor labelColor]; 186 | } 187 | return color; 188 | } 189 | 190 | - (NSString*) filename { 191 | std::string filename; 192 | if (file) 193 | filename = file->getFileName(); 194 | return [NSString stringWithStdString:filename]; 195 | } 196 | 197 | - (NSString*) version { 198 | if (file) { 199 | return [NSString stringWithStdString:file->getVersion()]; 200 | } 201 | return @""; 202 | } 203 | 204 | - (NSNumber*) size { 205 | if (file != nullptr) 206 | return @(file->getSize()); 207 | return @(0); 208 | } 209 | 210 | - (NSString*) name { 211 | std::string name; 212 | if (command) { 213 | name = command->getName(); 214 | } else if (file) { 215 | name = file->getName(); 216 | } 217 | return [NSString stringWithStdString:name]; 218 | } 219 | 220 | - (NSNumber*) currentVersion { 221 | if (command) { 222 | return [NSNumber numberWithUnsignedInt:command->getCurrentVersion()]; 223 | } 224 | return [NSNumber numberWithUnsignedInt:0]; 225 | } 226 | 227 | - (NSNumber*) compatibleVersion { 228 | if (command) { 229 | return [NSNumber numberWithUnsignedInt:command->getCompatibleVersion()]; 230 | } 231 | return [NSNumber numberWithUnsignedInt:0]; 232 | } 233 | 234 | - (NSDate*) lastModificationTime { 235 | if (file) 236 | return [NSDate dateWithTimeIntervalSince1970:file->getLastModificationTime()]; 237 | return NULL; 238 | } 239 | 240 | - (NSString*) dependencyType { 241 | NSString* type; 242 | if (!command) { 243 | return @""; 244 | } 245 | switch(command->getType()) { 246 | 247 | case DylibCommand::DependencyWeak: 248 | type = NSLocalizedString(@"DEPENDENCY_TYPE_WEAK", nil); 249 | break; 250 | case DylibCommand::DependencyDelayed: 251 | type = NSLocalizedString(@"DEPENDENCY_TYPE_DELAYED", nil); 252 | break; 253 | case DylibCommand::DependencyNormal: 254 | type = NSLocalizedString(@"DEPENDENCY_TYPE_NORMAL", nil); 255 | break; 256 | default: 257 | type = NSLocalizedString(@"UNDEFINED", @"Unknown"); 258 | } 259 | return type; 260 | } 261 | 262 | - (NSArray*) architectures { 263 | NSMutableArray* architectures = [NSMutableArray arrayWithCapacity:4]; 264 | 265 | if (file) { 266 | for (MachO::MachOArchitecturesIterator iter = file->getArchitecturesBegin(); iter != file->getArchitecturesEnd(); iter++) { 267 | // create model for architecture 268 | ArchitectureModel* currentArchitecture = [[ArchitectureModel alloc]initWithArchitecture:(*iter) file:file document:document isRoot:NO]; 269 | // correct order (current architecture should have first index) 270 | if ((*iter) == architecture) { 271 | [architectures insertObject:currentArchitecture atIndex:0]; // insert at beginning 272 | } else { 273 | [architectures addObject:currentArchitecture]; // insert at end 274 | } 275 | 276 | } 277 | } 278 | return architectures; 279 | } 280 | @end 281 | -------------------------------------------------------------------------------- /MacDependency/MyDocument.h: -------------------------------------------------------------------------------- 1 | // 2 | // MyDocument.h 3 | // MacDependency 4 | // 5 | // Created by Konrad Windszus on 19.06.09. 6 | // Copyright Konrad Windszus 2009 . All rights reserved. 7 | // 8 | 9 | 10 | #import 11 | #import "MachO/macho.h" 12 | #import "MachO/machocache.h" 13 | #import "MachOModel.h" 14 | #import "PrioritySplitViewDelegate.h" 15 | #import "SymbolTableController.h" 16 | 17 | @interface MyDocument : NSDocument 18 | { 19 | MachOCache* cache; 20 | MachO* machO; 21 | NSArray* contents; 22 | NSAttributedString* log; 23 | PrioritySplitViewDelegate* splitViewDelegate; 24 | IBOutlet NSTreeController* dependenciesController; 25 | IBOutlet NSTextField* textFieldFilename; 26 | IBOutlet NSTextField* textFieldBottomBar; 27 | IBOutlet NSSplitView* mainSplitView; 28 | IBOutlet SymbolTableController* symbolTableController; 29 | unsigned int numDependencies; 30 | } 31 | - (NSAttributedString*)log; 32 | - (void)setLog:(NSAttributedString *)newLog; 33 | - (void)appendLogLine:(NSString *)line withModel:(MachOModel*)aModel state:(State)aState; 34 | - (void)clearLog; 35 | - (NSString*) workingDirectory; 36 | 37 | - (void)incrementNumDependencies; 38 | - (void)resetNumDependencies; 39 | 40 | - (MachOCache*)cache; 41 | 42 | - (NSArray*)architectures; 43 | - (IBAction)clickRevealInFinder:(id)sender; 44 | - (NSString*)dependencyStatus; 45 | - (SymbolTableController*)symbolTableController; 46 | @end 47 | -------------------------------------------------------------------------------- /MacDependency/MyDocument.mm: -------------------------------------------------------------------------------- 1 | // 2 | // MyDocument.m 3 | // MacDependency 4 | // 5 | // Created by Konrad Windszus on 19.06.09. 6 | // Copyright Konrad Windszus 2009 . All rights reserved. 7 | // 8 | 9 | #import "MyDocument.h" 10 | #import "ConversionStdString.h" 11 | #import "MachOModel.h" 12 | #import "TreeControllerExtension.h" 13 | #import "ArchitectureModel.h" 14 | #include "MachO/machoexception.h" 15 | 16 | 17 | 18 | // declare private methods 19 | @interface MyDocument () 20 | - (NSString*) serializeIndexPath:(NSIndexPath*)indexPath; 21 | - (NSIndexPath*) deserializeIndexPath:(NSString*)link; 22 | @end 23 | 24 | @implementation MyDocument 25 | 26 | - (id)init 27 | { 28 | self = [super init]; 29 | if (self) { 30 | 31 | // Add your subclass-specific initialization here. 32 | // If an error occurs here, send a [self release] message and return nil. 33 | //contents = [[NSMutableArray alloc] init]; 34 | cache = new MachOCache(); 35 | log = [[NSAttributedString alloc] initWithString:@""]; 36 | numDependencies = 0; 37 | splitViewDelegate = [[PrioritySplitViewDelegate alloc] init]; 38 | 39 | } 40 | return self; 41 | } 42 | 43 | - (void) dealloc 44 | { 45 | delete cache; 46 | } 47 | 48 | 49 | - (NSString *)windowNibName 50 | { 51 | // Override returning the nib file name of the document 52 | // If you need to use a subclass of NSWindowController or if your document supports multiple NSWindowControllers, you should remove this method and override -makeWindowControllers instead. 53 | return @"MyDocument"; 54 | } 55 | 56 | - (void)windowControllerDidLoadNib:(NSWindowController *) aController 57 | { 58 | [super windowControllerDidLoadNib:aController]; 59 | 60 | // Add any code here that needs to be executed once the windowController has loaded the document's window. 61 | } 62 | 63 | 64 | - (NSData *)dataOfType:(NSString *)typeName error:(NSError **)outError 65 | { 66 | // Insert code here to write your document to data of the specified type. If the given outError != NULL, ensure that you set *outError when returning nil. 67 | 68 | // You can also choose to override -fileWrapperOfType:error:, -writeToURL:ofType:error:, or -writeToURL:ofType:forSaveOperation:originalContentsURL:error: instead. 69 | 70 | // For applications targeted for Panther or earlier systems, you should use the deprecated API -dataRepresentationOfType:. In this case you can also choose to override -fileWrapperRepresentationOfType: or -writeToFile:ofType: instead. 71 | 72 | if ( outError != NULL ) { 73 | *outError = [NSError errorWithDomain:NSOSStatusErrorDomain code:unimpErr userInfo:NULL]; 74 | } 75 | return nil; 76 | } 77 | 78 | 79 | - (BOOL)readFromURL:(NSURL *)absoluteURL ofType:(NSString *)typeName error:(NSError **)outError 80 | { 81 | // TODO: detect changes on document file (FSEvents) or alternatively make reload possible 82 | 83 | // load file 84 | NSString* filePath = [absoluteURL path]; 85 | 86 | // convert to std:string 87 | std::string fileString = [filePath stdString]; 88 | try { 89 | machO = cache->getFile(fileString, NULL); 90 | } catch (MachOException& exc) { 91 | NSString* msg = [NSString stringWithUTF8String:exc.getCause().c_str()]; 92 | 93 | 94 | // create and return custom domain error (the localized description key is overwritten by OS, so no point in setting it here) 95 | NSArray *objArray = [NSArray arrayWithObjects:@"", msg, @"Try again with another file", nil]; 96 | NSArray *keyArray = [NSArray arrayWithObjects:NSLocalizedDescriptionKey, NSLocalizedFailureReasonErrorKey, NSLocalizedRecoverySuggestionErrorKey, nil]; 97 | 98 | NSDictionary *eDict = [NSDictionary dictionaryWithObjects:objArray forKeys:keyArray]; 99 | 100 | // fill outError 101 | *outError = [NSError errorWithDomain:@"MachO" code:0 userInfo:eDict]; 102 | return NO; 103 | } 104 | return YES; 105 | } 106 | 107 | -(void)awakeFromNib { 108 | [[textFieldBottomBar cell] setBackgroundStyle:NSBackgroundStyleRaised]; 109 | 110 | [splitViewDelegate setPriority:1 forViewAtIndex:0]; 111 | [splitViewDelegate setPriority:0 forViewAtIndex:1]; 112 | [splitViewDelegate setMinimumLength:150 forViewAtIndex:0]; 113 | [splitViewDelegate setMinimumLength:400 forViewAtIndex:1]; 114 | [mainSplitView setDelegate:splitViewDelegate]; 115 | } 116 | 117 | - (NSAttributedString*)log { 118 | return log; 119 | } 120 | 121 | - (void)setLog:(NSAttributedString *)newLog { 122 | log = newLog; 123 | } 124 | 125 | - (void)clearLog { 126 | NSAttributedString* newLog = [[NSAttributedString alloc] initWithString:@""]; 127 | [self setLog:newLog]; 128 | } 129 | 130 | - (void)appendLogLine:(NSString *)line withModel:(MachOModel*)model state:(State)state { 131 | 132 | NSMutableAttributedString* newLog = [[NSMutableAttributedString alloc] init]; 133 | [newLog appendAttributedString:log]; 134 | 135 | NSString* prefix; 136 | switch (state) { 137 | case StateError: 138 | prefix = NSLocalizedString(@"LOG_PREFIX_ERROR", nil); 139 | break; 140 | default: 141 | prefix = NSLocalizedString(@"LOG_PREFIX_WARNING", nil); 142 | break; 143 | } 144 | 145 | NSString* newLine = [NSString stringWithFormat:@"%@%@\n\n", prefix, line]; 146 | NSDictionary* attributes; 147 | 148 | if (model) { 149 | attributes = [NSDictionary dictionaryWithObjectsAndKeys:model, NSLinkAttributeName, [NSCursor pointingHandCursor], NSCursorAttributeName, NSLocalizedString(@"LOG_LINK_TOOLTIP", nil), NSToolTipAttributeName, nil]; 150 | } else { 151 | attributes = [NSDictionary dictionary]; 152 | } 153 | NSAttributedString* newLogLine = [[NSAttributedString alloc]initWithString:newLine attributes:attributes]; 154 | 155 | [newLog appendAttributedString:newLogLine]; 156 | [self setLog:newLog]; 157 | } 158 | 159 | - (NSString*) workingDirectory { 160 | // don't release the returned string!!, apparently then filename is released also 161 | NSString* filePath = [[super fileURL] path]; 162 | return [filePath stringByDeletingLastPathComponent]; 163 | } 164 | 165 | 166 | - (NSString*) serializeIndexPath:(NSIndexPath*)indexPath { 167 | NSMutableString* link = [NSMutableString stringWithCapacity:20]; 168 | for (int depth = 0; depth < [indexPath length]; depth++) { 169 | [link appendFormat: @"%ld;", [indexPath indexAtPosition: depth]]; 170 | } 171 | return link; 172 | } 173 | 174 | - (NSIndexPath*) deserializeIndexPath:(NSString*)link { 175 | NSIndexPath* indexPath = nil; 176 | 177 | // tokenize string 178 | NSArray* indices = [link componentsSeparatedByString:@";"]; 179 | 180 | // go through tokens 181 | NSEnumerator *enumerator = [indices objectEnumerator]; 182 | NSString* token = [enumerator nextObject]; 183 | if (token) { 184 | indexPath = [NSIndexPath indexPathWithIndex: [token intValue]]; 185 | while ((token = [enumerator nextObject])) { 186 | if ([token length] > 0) 187 | indexPath = [indexPath indexPathByAddingIndex:[token intValue]]; 188 | } 189 | } 190 | return indexPath; 191 | } 192 | 193 | 194 | // delegate method 195 | - (BOOL)textView:(NSTextView *)aTextView clickedOnLink:(id)link atIndex:(NSUInteger)charIndex { 196 | [dependenciesController setSelectedObject: link]; 197 | 198 | // we need no further processing of the link 199 | return YES; 200 | } 201 | 202 | 203 | - (MachOCache*)cache { 204 | return cache; 205 | } 206 | 207 | - (NSArray*) architectures { 208 | NSMutableArray* architectures = [NSMutableArray arrayWithCapacity:4]; 209 | 210 | if (machO) { 211 | MachOArchitecture* architecture = machO->getHostCompatibleArchitecture(); 212 | if (!architecture) { 213 | // no host-compatible architecture found (just take first architecture) 214 | architecture = *(machO->getArchitecturesBegin()); 215 | } 216 | for (MachO::MachOArchitecturesIterator iter = machO->getArchitecturesBegin(); iter != machO->getArchitecturesEnd(); iter++) { 217 | // create model for architecture 218 | ArchitectureModel* currentArchitecture = [[ArchitectureModel alloc]initWithArchitecture:(*iter) file:machO document:self isRoot:YES]; 219 | // correct order (current architecture should have first index) 220 | if ((*iter) == architecture) { 221 | [architectures insertObject:currentArchitecture atIndex:0]; // insert at beginning 222 | } else { 223 | [architectures addObject:currentArchitecture]; // insert at end 224 | } 225 | 226 | } 227 | } 228 | return architectures; 229 | } 230 | 231 | - (IBAction)clickRevealInFinder:(id)sender { 232 | NSString* filename = [textFieldFilename stringValue]; 233 | 234 | [[NSWorkspace sharedWorkspace] selectFile: filename inFileViewerRootedAtPath: @""]; 235 | 236 | } 237 | 238 | - (void)incrementNumDependencies { 239 | [self willChangeValueForKey:@"dependencyStatus"]; 240 | numDependencies++; 241 | [self didChangeValueForKey:@"dependencyStatus"]; 242 | } 243 | 244 | - (void)resetNumDependencies { 245 | [self willChangeValueForKey:@"dependencyStatus"]; 246 | numDependencies = 0; 247 | [self didChangeValueForKey:@"dependencyStatus"]; 248 | } 249 | 250 | 251 | - (NSString*)dependencyStatus { 252 | NSString* status = [NSString stringWithFormat:NSLocalizedString(@"DEPENDENCY_STATUS", nil), numDependencies, cache->getNumEntries()]; 253 | return status; 254 | } 255 | 256 | - (SymbolTableController*)symbolTableController { 257 | return symbolTableController; 258 | } 259 | 260 | @end 261 | -------------------------------------------------------------------------------- /MacDependency/MyDocumentWindow.h: -------------------------------------------------------------------------------- 1 | // 2 | // MyDocumentWindow.h 3 | // MacDependency 4 | // 5 | // Created by Konrad Windszus on 04.09.09. 6 | // Copyright 2009 Konrad Windszus. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | 12 | @interface MyDocumentWindow : NSWindow { 13 | 14 | } 15 | 16 | @end 17 | -------------------------------------------------------------------------------- /MacDependency/MyDocumentWindow.m: -------------------------------------------------------------------------------- 1 | // 2 | // MyDocumentWindow.m 3 | // MacDependency 4 | // 5 | // Created by Konrad Windszus on 04.09.09. 6 | // Copyright 2009 Konrad Windszus. All rights reserved. 7 | // 8 | // Window class for document windows 9 | // 10 | #import "MyDocumentWindow.h" 11 | 12 | 13 | @implementation MyDocumentWindow 14 | 15 | -(void)awakeFromNib { 16 | [super awakeFromNib]; 17 | 18 | // set bottom bar 19 | [self setContentBorderThickness:24.0 forEdge:NSMinYEdge]; 20 | } 21 | @end 22 | -------------------------------------------------------------------------------- /MacDependency/PrioritySplitViewDelegate.h: -------------------------------------------------------------------------------- 1 | // 2 | // PrioritySplitViewDelegate.h 3 | // ColumnSplitView 4 | // 5 | // Created by Matt Gallagher on 2009/09/01. 6 | // Copyright 2009 Matt Gallagher. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface PrioritySplitViewDelegate : NSObject 12 | { 13 | NSMutableDictionary *lengthsByViewIndex; 14 | NSMutableDictionary *viewIndicesByPriority; 15 | } 16 | 17 | - (void)setMinimumLength:(CGFloat)minLength 18 | forViewAtIndex:(NSInteger)viewIndex; 19 | - (void)setPriority:(NSInteger)priorityIndex 20 | forViewAtIndex:(NSInteger)viewIndex; 21 | 22 | @end 23 | -------------------------------------------------------------------------------- /MacDependency/PrioritySplitViewDelegate.m: -------------------------------------------------------------------------------- 1 | // 2 | // PrioritySplitViewDelegate.m 3 | // ColumnSplitView 4 | // 5 | // Created by Matt Gallagher on 2009/09/01. 6 | // Copyright 2009 Matt Gallagher. All rights reserved. 7 | // 8 | // see http://cocoawithlove.com/2009/09/nssplitview-delegate-for-priority-based.html 9 | // 10 | #import "PrioritySplitViewDelegate.h" 11 | 12 | 13 | @implementation PrioritySplitViewDelegate 14 | 15 | 16 | - (void)setMinimumLength:(CGFloat)minLength forViewAtIndex:(NSInteger)viewIndex 17 | { 18 | if (!lengthsByViewIndex) 19 | { 20 | lengthsByViewIndex = [[NSMutableDictionary alloc] initWithCapacity:0]; 21 | } 22 | [lengthsByViewIndex 23 | setObject:[NSNumber numberWithDouble:minLength] 24 | forKey:[NSNumber numberWithInteger:viewIndex]]; 25 | } 26 | 27 | - (void)setPriority:(NSInteger)priorityIndex forViewAtIndex:(NSInteger)viewIndex 28 | { 29 | if (!viewIndicesByPriority) 30 | { 31 | viewIndicesByPriority = [[NSMutableDictionary alloc] initWithCapacity:0]; 32 | } 33 | [viewIndicesByPriority 34 | setObject:[NSNumber numberWithInteger:viewIndex] 35 | forKey:[NSNumber numberWithInteger:priorityIndex]]; 36 | } 37 | 38 | - (CGFloat)splitView:(NSSplitView *)sender 39 | constrainMinCoordinate:(CGFloat)proposedMin ofSubviewAt:(NSInteger)offset 40 | { 41 | NSView *subview = [[sender subviews] objectAtIndex:offset]; 42 | NSRect subviewFrame = subview.frame; 43 | CGFloat frameOrigin; 44 | if ([sender isVertical]) 45 | { 46 | frameOrigin = subviewFrame.origin.x; 47 | } 48 | else 49 | { 50 | frameOrigin = subviewFrame.origin.y; 51 | } 52 | 53 | CGFloat minimumSize = 54 | [[lengthsByViewIndex objectForKey:[NSNumber numberWithInteger:offset]] 55 | doubleValue]; 56 | 57 | return frameOrigin + minimumSize; 58 | } 59 | 60 | - (CGFloat)splitView:(NSSplitView *)sender 61 | constrainMaxCoordinate:(CGFloat)proposedMax ofSubviewAt:(NSInteger)offset 62 | { 63 | NSView *growingSubview = [[sender subviews] objectAtIndex:offset]; 64 | NSView *shrinkingSubview = [[sender subviews] objectAtIndex:offset + 1]; 65 | NSRect growingSubviewFrame = growingSubview.frame; 66 | NSRect shrinkingSubviewFrame = shrinkingSubview.frame; 67 | CGFloat shrinkingSize; 68 | CGFloat currentCoordinate; 69 | if ([sender isVertical]) 70 | { 71 | currentCoordinate = 72 | growingSubviewFrame.origin.x + growingSubviewFrame.size.width; 73 | shrinkingSize = shrinkingSubviewFrame.size.width; 74 | } 75 | else 76 | { 77 | currentCoordinate = 78 | growingSubviewFrame.origin.y + growingSubviewFrame.size.height; 79 | shrinkingSize = shrinkingSubviewFrame.size.height; 80 | } 81 | 82 | CGFloat minimumSize = 83 | [[lengthsByViewIndex objectForKey:[NSNumber numberWithInteger:offset + 1]] 84 | doubleValue]; 85 | 86 | return currentCoordinate + (shrinkingSize - minimumSize); 87 | } 88 | 89 | - (void)splitView:(NSSplitView *)sender 90 | resizeSubviewsWithOldSize:(NSSize)oldSize 91 | { 92 | NSArray *subviews = [sender subviews]; 93 | NSInteger subviewsCount = [subviews count]; 94 | 95 | BOOL isVertical = [sender isVertical]; 96 | 97 | CGFloat delta = [sender isVertical] ? 98 | (sender.bounds.size.width - oldSize.width) : 99 | (sender.bounds.size.height - oldSize.height); 100 | 101 | NSInteger viewCountCheck = 0; 102 | 103 | for (NSNumber *priorityIndex in 104 | [[viewIndicesByPriority allKeys] sortedArrayUsingSelector:@selector(compare:)]) 105 | { 106 | NSNumber *viewIndex = [viewIndicesByPriority objectForKey:priorityIndex]; 107 | NSInteger viewIndexValue = [viewIndex integerValue]; 108 | if (viewIndexValue >= subviewsCount) 109 | { 110 | continue; 111 | } 112 | 113 | NSView *view = [subviews objectAtIndex:viewIndexValue]; 114 | 115 | NSSize frameSize = [view frame].size; 116 | NSNumber *minLength = [lengthsByViewIndex objectForKey:viewIndex]; 117 | CGFloat minLengthValue = [minLength doubleValue]; 118 | 119 | if (isVertical) 120 | { 121 | frameSize.height = sender.bounds.size.height; 122 | if (delta > 0 || 123 | frameSize.width + delta >= minLengthValue) 124 | { 125 | frameSize.width += delta; 126 | delta = 0; 127 | } 128 | else if (delta < 0) 129 | { 130 | delta += frameSize.width - minLengthValue; 131 | frameSize.width = minLengthValue; 132 | } 133 | } 134 | else 135 | { 136 | frameSize.width = sender.bounds.size.width; 137 | if (delta > 0 || 138 | frameSize.height + delta >= minLengthValue) 139 | { 140 | frameSize.height += delta; 141 | delta = 0; 142 | } 143 | else if (delta < 0) 144 | { 145 | delta += frameSize.height - minLengthValue; 146 | frameSize.height = minLengthValue; 147 | } 148 | } 149 | 150 | [view setFrameSize:frameSize]; 151 | viewCountCheck++; 152 | } 153 | 154 | NSAssert1(viewCountCheck == [subviews count], 155 | @"Number of valid views in priority list is less than the subview count" 156 | @" of split view %p.", 157 | sender); 158 | NSAssert3(fabs(delta) < 0.5, 159 | @"Split view %p resized smaller than minimum %@ of %f", 160 | sender, 161 | isVertical ? @"width" : @"height", 162 | sender.frame.size.width - delta); 163 | 164 | CGFloat offset = 0; 165 | CGFloat dividerThickness = [sender dividerThickness]; 166 | for (NSView *subview in subviews) 167 | { 168 | NSRect viewFrame = subview.frame; 169 | NSPoint viewOrigin = viewFrame.origin; 170 | viewOrigin.x = offset; 171 | [subview setFrameOrigin:viewOrigin]; 172 | offset += viewFrame.size.width + dividerThickness; 173 | } 174 | } 175 | 176 | @end 177 | 178 | 179 | 180 | 181 | -------------------------------------------------------------------------------- /MacDependency/SymbolTableController.h: -------------------------------------------------------------------------------- 1 | // 2 | // SymbolTableController.h 3 | // MacDependency 4 | // 5 | // Created by Konrad Windszus on 18.07.09. 6 | // Copyright 2009 Konrad Windszus. All rights reserved. 7 | // 8 | 9 | @class MyDocument; 10 | 11 | @interface SymbolTableController : NSArrayController { 12 | NSPredicate* nameFilter; 13 | IBOutlet NSSegmentedControl* typeFilterControl; 14 | IBOutlet NSButton* demangleNamesControl; 15 | BOOL demangleNames; 16 | IBOutlet MyDocument* document; 17 | } 18 | 19 | - (void)setNameFilter:(NSPredicate*) nameFilter; 20 | - (NSPredicate*)nameFilter; 21 | 22 | - (IBAction)typeFilterChanged:(id)sender; 23 | 24 | - (BOOL)demangleNames; 25 | - (BOOL*)demangleNamesPtr; 26 | - (void)setDemangleNames:(BOOL)demangle; 27 | 28 | @end 29 | -------------------------------------------------------------------------------- /MacDependency/SymbolTableController.mm: -------------------------------------------------------------------------------- 1 | // 2 | // SymbolTableController.m 3 | // MacDependency 4 | // 5 | // Created by Konrad Windszus on 18.07.09. 6 | // Copyright 2009 Konrad Windszus. All rights reserved. 7 | // 8 | 9 | #import "SymbolTableController.h" 10 | #import "MyDocument.h" 11 | #include "MachO/symboltableentry.h" 12 | 13 | 14 | @interface SymbolTableController() 15 | -(void)setFilter; 16 | - (NSPredicate*) typeFilter; 17 | @end 18 | 19 | @implementation SymbolTableController 20 | 21 | 22 | const int TYPE[] = {SymbolTableEntry::TypeExported, SymbolTableEntry::TypeImported}; 23 | 24 | - (id)initWithCoder:(NSCoder *)decoder { 25 | self = [super initWithCoder:decoder]; 26 | if (self) { 27 | demangleNames = true; 28 | } 29 | return self; 30 | } 31 | 32 | // called when all connections were made 33 | - (void)awakeFromNib { 34 | [self setFilter]; 35 | } 36 | 37 | - (NSPredicate*) typeFilter { 38 | NSMutableString* typeFilter = [NSMutableString string]; 39 | 40 | for (int segment=0; segment < sizeof(TYPE)/sizeof(*TYPE); segment++) { 41 | if ([typeFilterControl isSelectedForSegment:segment]) { 42 | NSString* condition = [NSString stringWithFormat:@"type=%d", TYPE[segment]]; 43 | if ([typeFilter length] > 0) { 44 | [typeFilter appendString:@" or "]; 45 | } 46 | [typeFilter appendString:condition]; 47 | } 48 | } 49 | 50 | // select nothing if no filter set 51 | NSPredicate* predicate; 52 | if ([typeFilter length] == 0) { 53 | predicate = [NSPredicate predicateWithValue:NO]; 54 | } else { 55 | predicate = [NSPredicate predicateWithFormat:typeFilter]; 56 | } 57 | return predicate; 58 | } 59 | 60 | - (NSPredicate*)nameFilter { 61 | return nameFilter; 62 | } 63 | 64 | 65 | - (void)setNameFilter:(NSPredicate*) newNameFilter { 66 | nameFilter = newNameFilter; 67 | [self setFilter]; 68 | } 69 | 70 | - (IBAction)typeFilterChanged:(id)sender { 71 | [self setFilter]; 72 | } 73 | 74 | -(void)setFilter { 75 | NSPredicate* typeFilter = [self typeFilter]; 76 | NSPredicate* predicate; 77 | if (nameFilter) { 78 | predicate = [NSCompoundPredicate andPredicateWithSubpredicates:[NSArray arrayWithObjects:nameFilter, typeFilter, nil]]; 79 | } else { 80 | predicate = typeFilter; 81 | } 82 | //NSLog(@"%@", predicate); 83 | [self setFilterPredicate:predicate]; 84 | } 85 | 86 | - (BOOL)demangleNames { 87 | return demangleNames; 88 | } 89 | 90 | - (BOOL*)demangleNamesPtr { 91 | return &demangleNames; 92 | } 93 | 94 | - (void)setDemangleNames:(BOOL)demangle { 95 | self->demangleNames = demangle; 96 | 97 | // refresh 98 | [self rearrangeObjects]; 99 | } 100 | 101 | @end 102 | -------------------------------------------------------------------------------- /MacDependency/SymbolTableEntryModel.h: -------------------------------------------------------------------------------- 1 | // 2 | // SymbolEntryModel.h 3 | // MacDependency 4 | // 5 | // Created by Konrad Windszus on 13.07.09. 6 | // Copyright 2009 Konrad Windszus. All rights reserved. 7 | // 8 | 9 | #import 10 | #include "MachO/machofile.h" 11 | #include "MachO/symboltableentry.h" 12 | @class MyDocument; 13 | 14 | @interface SymbolTableEntryModel : NSObject { 15 | const SymbolTableEntry* entry; 16 | const BOOL* demangleNames; 17 | MyDocument* document; 18 | } 19 | 20 | - (id) initWithEntry:(const SymbolTableEntry*)entry demangleNamesPtr:(BOOL*)demangleNames document:(MyDocument*)document; 21 | - (NSString*) name; 22 | - (NSNumber*) type; 23 | @end 24 | -------------------------------------------------------------------------------- /MacDependency/SymbolTableEntryModel.mm: -------------------------------------------------------------------------------- 1 | // 2 | // SymbolEntryModel.mm 3 | // MacDependency 4 | // 5 | // Created by Konrad Windszus on 13.07.09. 6 | // Copyright 2009 Konrad Windszus. All rights reserved. 7 | // 8 | 9 | #import "SymbolTableEntryModel.h" 10 | #import "MachOModel.h" 11 | #import "ConversionStdString.h" 12 | #import "MyDocument.h" 13 | #include "MachO/machodemangleexception.h" 14 | 15 | @implementation SymbolTableEntryModel 16 | 17 | - (id) initWithEntry:(const SymbolTableEntry*)anEntry demangleNamesPtr:(BOOL*)demangle document:(MyDocument*)aDocument { 18 | self = [super init]; 19 | if (self) { 20 | entry = anEntry; 21 | self->demangleNames = demangle; 22 | document = aDocument; 23 | } 24 | return self; 25 | } 26 | 27 | - (NSString*) name { 28 | try { 29 | return [NSString stringWithStdString: entry->getName(*demangleNames)]; 30 | } catch (MachODemangleException& e) { 31 | // in case of demangling problems (probably c++filt not installed) 32 | NSString* error = NSLocalizedString(@"ERR_NO_DEMANGLER", nil); 33 | [document appendLogLine:error withModel:nil state:StateError]; 34 | // disable name demangling 35 | [[document symbolTableController] setDemangleNames:NO]; 36 | } 37 | return [NSString stringWithStdString:entry->getName(false)]; 38 | } 39 | 40 | - (NSNumber*) type { 41 | return [NSNumber numberWithUnsignedInt:entry->getType()]; 42 | } 43 | 44 | @end 45 | -------------------------------------------------------------------------------- /MacDependency/SymbolTableEntryTypeFormatter.h: -------------------------------------------------------------------------------- 1 | // 2 | // SymbolTableEntryTypeFormatter.h 3 | // MacDependency 4 | // 5 | // Created by Konrad Windszus on 18.07.09. 6 | // Copyright 2009 Konrad Windszus. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | 12 | @interface SymbolTableEntryTypeFormatter : NSFormatter { 13 | 14 | } 15 | 16 | @end 17 | -------------------------------------------------------------------------------- /MacDependency/SymbolTableEntryTypeFormatter.mm: -------------------------------------------------------------------------------- 1 | // 2 | // SymbolTableEntryTypeFormatter.m 3 | // MacDependency 4 | // 5 | // Created by Konrad Windszus on 18.07.09. 6 | // Copyright 2009 Konrad Windszus. All rights reserved. 7 | // 8 | // Formatter for types of symbol table entries. We need a formatter to provide a valid sort order. 9 | #import "SymbolTableEntryTypeFormatter.h" 10 | #include "MachO/symboltableentry.h" 11 | 12 | @implementation SymbolTableEntryTypeFormatter 13 | // conversion to string 14 | - (NSString*) stringForObjectValue:(id)obj { 15 | // must be a NSNumber 16 | if (![obj isKindOfClass:[NSNumber class]]) { 17 | return nil; 18 | } 19 | 20 | // NSNumber contains the version as unsigned int 21 | unsigned int typeNumber = [obj unsignedIntValue]; 22 | NSString* type; 23 | switch(typeNumber) { 24 | case SymbolTableEntry::TypeExported: 25 | type = NSLocalizedString(@"SYMBOL_TYPE_EXPORT", @"Export"); 26 | break; 27 | case SymbolTableEntry::TypeImported: 28 | type = NSLocalizedString(@"SYMBOL_TYPE_IMPORT", @"Import"); 29 | break; 30 | default: 31 | type = NSLocalizedString(@"UNKNOWN", @"Unknown"); 32 | 33 | } 34 | return type; 35 | } 36 | 37 | 38 | // conversion from string (not necessary) 39 | - (BOOL) getObjectValue:(id*)obj forString:(NSString*)string errorDescription:(NSString**)errorString { 40 | return NO; 41 | } 42 | @end 43 | -------------------------------------------------------------------------------- /MacDependency/TreeControllerExtension.h: -------------------------------------------------------------------------------- 1 | // 2 | // TreeControllerExtension.h 3 | // MacDependency 4 | // 5 | // Created by Konrad Windszus on 02.09.09. 6 | // Copyright 2009 Konrad Windszus. All rights reserved. 7 | // 8 | // NSTreeController-DMExtensions.h 9 | // Library 10 | // 11 | // Created by William Shipley on 3/10/06. 12 | // Copyright 2006 Delicious Monster Software, LLC. Some rights reserved, 13 | // see Creative Commons license on wilshipley.com 14 | // @see http://wilshipley.com/blog/2006/04/pimp-my-code-part-10-whining-about.html 15 | #import 16 | #import "ExtTreeModel.h" 17 | 18 | @interface NSTreeController (TreeControllerExtension) 19 | - (BOOL)setSelectedObjects:(NSArray *)newSelectedObjects; 20 | - (BOOL)setSelectedObject:(id )object; 21 | - (NSIndexPath *)indexPathToObject:(id )object; 22 | @end 23 | -------------------------------------------------------------------------------- /MacDependency/TreeControllerExtension.m: -------------------------------------------------------------------------------- 1 | // 2 | // TreeControllerExtension.m 3 | // MacDependency 4 | // 5 | // Created by Konrad Windszus on 02.09.09. 6 | // Copyright 2009 Konrad Windszus. All rights reserved. 7 | // 8 | // Extension to NSTreeController to provide methods to select an item if only its data pointer is known. 9 | 10 | 11 | #import "TreeControllerExtension.h" 12 | 13 | 14 | @interface NSTreeController (TreeControllerExtension_Private) 15 | - (NSIndexPath *)_indexPathFromIndexPath:(NSIndexPath *)baseIndexPath inChildren:(NSArray **)children 16 | toObject:(id )object; 17 | @end 18 | 19 | 20 | @implementation NSTreeController (TreeControllerExtension) 21 | 22 | - (BOOL)setSelectedObjects:(NSArray *)newSelectedObjects 23 | { 24 | NSMutableArray *indexPaths = [NSMutableArray array]; 25 | unsigned int selectedObjectIndex; 26 | for (selectedObjectIndex = 0; selectedObjectIndex < [newSelectedObjects count]; 27 | selectedObjectIndex++) { 28 | id selectedObject = [newSelectedObjects objectAtIndex:selectedObjectIndex]; 29 | NSIndexPath *indexPath = [self indexPathToObject:selectedObject]; 30 | if (indexPath) 31 | [indexPaths addObject:indexPath]; 32 | } 33 | return [self setSelectionIndexPaths:indexPaths]; 34 | } 35 | 36 | - (BOOL)setSelectedObject:(id )object 37 | { 38 | NSIndexPath *indexPath = [self indexPathToObject:object]; 39 | if (indexPath) { 40 | return [self setSelectionIndexPath:indexPath]; 41 | } 42 | return NO; 43 | } 44 | 45 | - (NSIndexPath *)indexPathToObject:(id )object 46 | { 47 | NSArray *children = [self content]; 48 | return [self _indexPathFromIndexPath:nil inChildren:&children toObject:object]; 49 | } 50 | 51 | @end 52 | 53 | @implementation NSTreeController (TreeControllerExtension_Private) 54 | 55 | // inspired by: http://wilshipley.com/blog/2006/04/pimp-my-code-part-10-whining-about.html but much faster and does not rely 56 | // on dirty and undocumented selectors of arrangedObjects. 57 | - (NSIndexPath *)_indexPathFromIndexPath:(NSIndexPath *)baseIndexPath inChildren:(NSArray **)children 58 | toObject:(id )object; 59 | { 60 | 61 | NSIndexPath* indexPath = nil; 62 | // go back to root 63 | id parent = [object parent]; 64 | if (parent) { 65 | baseIndexPath = [self _indexPathFromIndexPath:baseIndexPath inChildren:children toObject:parent]; 66 | if (!baseIndexPath) 67 | return nil; 68 | } 69 | 70 | // go through children (content) 71 | unsigned int childIndex; 72 | NSMutableArray* sortedChildren = [NSMutableArray arrayWithArray:*children]; 73 | [sortedChildren sortUsingDescriptors:[self sortDescriptors]]; 74 | 75 | for (childIndex = 0; childIndex < [sortedChildren count]; childIndex++) { 76 | id childObject = [sortedChildren objectAtIndex:childIndex]; 77 | if ([object isEqual:childObject]) { 78 | 79 | NSString *childrenKeyPath = [self childrenKeyPath]; 80 | NSArray* childsChildren = [childObject valueForKey:childrenKeyPath]; 81 | *children = childsChildren; 82 | 83 | // create current NSIndex 84 | if (!baseIndexPath) { 85 | indexPath = [NSIndexPath indexPathWithIndex:childIndex]; 86 | } else { 87 | indexPath = [baseIndexPath indexPathByAddingIndex:childIndex]; 88 | } 89 | return indexPath; 90 | } 91 | } 92 | return nil; // something wrong here (can't find object) 93 | } 94 | 95 | @end -------------------------------------------------------------------------------- /MacDependency/VersionFormatter.h: -------------------------------------------------------------------------------- 1 | // 2 | // VersionFormatter.h 3 | // MacDependency 4 | // 5 | // Created by Konrad Windszus on 17.07.09. 6 | // Copyright 2009 Konrad Windszus. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | 12 | @interface VersionFormatter : NSFormatter { 13 | 14 | } 15 | 16 | @end 17 | -------------------------------------------------------------------------------- /MacDependency/VersionFormatter.m: -------------------------------------------------------------------------------- 1 | // 2 | // VersionFormatter.m 3 | // MacDependency 4 | // 5 | // Created by Konrad Windszus on 17.07.09. 6 | // Copyright 2009 Konrad Windszus. All rights reserved. 7 | // 8 | // Formatter for version integers (4 byte) in the form xxxx.xx.xx 9 | #import "VersionFormatter.h" 10 | 11 | #define HIBYTE(x) ( (unsigned char) ((x) >> 8) ) 12 | #define LOBYTE(x) ( (unsigned char) (x) ) 13 | #define HIWORD(x) ( (unsigned short) ( (x) >> 16) ) 14 | #define LOWORD(x) ( (unsigned short) (x) ) 15 | 16 | @implementation VersionFormatter 17 | 18 | // conversion to string 19 | - (NSString*) stringForObjectValue:(id)obj { 20 | // must be a NSNumber 21 | if (![obj isKindOfClass:[NSNumber class]]) { 22 | return nil; 23 | } 24 | 25 | // NSNumber contains the version as unsigned int 26 | unsigned int version = [obj unsignedIntValue]; 27 | 28 | if (version == 0) { 29 | return [NSString string]; 30 | } 31 | NSString* versionString = [NSString stringWithFormat:@"%d.%d.%d", HIWORD(version), (unsigned short)HIBYTE(LOWORD(version)), (unsigned short)LOBYTE(LOWORD(version)) ]; 32 | return versionString; 33 | } 34 | 35 | 36 | // conversion from string (not necessary) 37 | - (BOOL) getObjectValue:(id*)obj forString:(NSString*)string errorDescription:(NSString**)errorString { 38 | return NO; 39 | } 40 | @end 41 | -------------------------------------------------------------------------------- /MacDependency/en.lproj/Credits.rtf: -------------------------------------------------------------------------------- 1 | {\rtf1\ansi\ansicpg1252\cocoartf1404\cocoasubrtf470 2 | {\fonttbl\f0\fswiss\fcharset0 Helvetica;} 3 | {\colortbl;\red255\green255\blue255;} 4 | \paperw12240\paperh15840\viewkind0 5 | \pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\partightenfactor0 6 | 7 | \f0\b\fs24 \cf0 Development 8 | \b0 \ 9 | Konrad Windszus\ 10 | \ 11 | 12 | \b Website\ 13 | \pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\pardirnatural\partightenfactor0 14 | \cf0 {\field{\*\fldinst{HYPERLINK "https://github.com/kwin/macdependency"}}{\fldrslt 15 | \b0 https://github.com/kwin/macdependency}}} 16 | -------------------------------------------------------------------------------- /MacDependency/en.lproj/InfoPlist.strings: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kwin/macdependency/1cf589d0ccceb9c90ee94b3ad3a79e67a66e5e38/MacDependency/en.lproj/InfoPlist.strings -------------------------------------------------------------------------------- /MacDependency/en.lproj/Localizable.strings: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kwin/macdependency/1cf589d0ccceb9c90ee94b3ad3a79e67a66e5e38/MacDependency/en.lproj/Localizable.strings -------------------------------------------------------------------------------- /MacDependency/main.m: -------------------------------------------------------------------------------- 1 | // 2 | // main.m 3 | // MacDependency 4 | // 5 | // Created by Konrad Windszus on 19.06.09. 6 | // Copyright Konrad Windszus 2009 . All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | int main(int argc, char *argv[]) 12 | { 13 | return NSApplicationMain(argc, (const char **) argv); 14 | } 15 | -------------------------------------------------------------------------------- /MachO/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | English 7 | CFBundleExecutable 8 | ${EXECUTABLE_NAME} 9 | CFBundleIconFile 10 | 11 | CFBundleIdentifier 12 | $(PRODUCT_BUNDLE_IDENTIFIER) 13 | CFBundleInfoDictionaryVersion 14 | 6.0 15 | CFBundleName 16 | ${PRODUCT_NAME} 17 | CFBundlePackageType 18 | FMWK 19 | CFBundleShortVersionString 20 | 1.1.1 21 | CFBundleSignature 22 | ???? 23 | NSPrincipalClass 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /MachO/MachO.xcodeproj/TemplateIcon.icns: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kwin/macdependency/1cf589d0ccceb9c90ee94b3ad3a79e67a66e5e38/MachO/MachO.xcodeproj/TemplateIcon.icns -------------------------------------------------------------------------------- /MachO/MachO.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 46; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | 8DC2EF530486A6940098B216 /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 089C1666FE841158C02AAC07 /* InfoPlist.strings */; }; 11 | 8E131537100F7C6B00367510 /* dylibcommand.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8E131514100F7C6B00367510 /* dylibcommand.cpp */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; }; 12 | 8E131538100F7C6B00367510 /* dylibcommand.h in Headers */ = {isa = PBXBuildFile; fileRef = 8E131515100F7C6B00367510 /* dylibcommand.h */; settings = {ATTRIBUTES = (Public, ); }; }; 13 | 8E131539100F7C6B00367510 /* dynamicloader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8E131516100F7C6B00367510 /* dynamicloader.cpp */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; }; 14 | 8E13153A100F7C6B00367510 /* dynamicloader.h in Headers */ = {isa = PBXBuildFile; fileRef = 8E131517100F7C6B00367510 /* dynamicloader.h */; }; 15 | 8E13153B100F7C6B00367510 /* genericcommand.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8E131518100F7C6B00367510 /* genericcommand.cpp */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; }; 16 | 8E13153C100F7C6B00367510 /* genericcommand.h in Headers */ = {isa = PBXBuildFile; fileRef = 8E131519100F7C6B00367510 /* genericcommand.h */; settings = {ATTRIBUTES = (Public, ); }; }; 17 | 8E13153D100F7C6B00367510 /* internalfile.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8E13151A100F7C6B00367510 /* internalfile.cpp */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; }; 18 | 8E13153E100F7C6B00367510 /* internalfile.h in Headers */ = {isa = PBXBuildFile; fileRef = 8E13151B100F7C6B00367510 /* internalfile.h */; }; 19 | 8E13153F100F7C6B00367510 /* loadcommand.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8E13151C100F7C6B00367510 /* loadcommand.cpp */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; }; 20 | 8E131540100F7C6B00367510 /* loadcommand.h in Headers */ = {isa = PBXBuildFile; fileRef = 8E13151D100F7C6B00367510 /* loadcommand.h */; settings = {ATTRIBUTES = (Public, ); }; }; 21 | 8E131541100F7C6B00367510 /* macho.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8E13151E100F7C6B00367510 /* macho.cpp */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; }; 22 | 8E131542100F7C6B00367510 /* macho.h in Headers */ = {isa = PBXBuildFile; fileRef = 8E13151F100F7C6B00367510 /* macho.h */; settings = {ATTRIBUTES = (Public, ); }; }; 23 | 8E131543100F7C6B00367510 /* macho32header.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8E131520100F7C6B00367510 /* macho32header.cpp */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; }; 24 | 8E131544100F7C6B00367510 /* macho32header.h in Headers */ = {isa = PBXBuildFile; fileRef = 8E131521100F7C6B00367510 /* macho32header.h */; }; 25 | 8E131545100F7C6B00367510 /* macho64header.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8E131522100F7C6B00367510 /* macho64header.cpp */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; }; 26 | 8E131546100F7C6B00367510 /* macho64header.h in Headers */ = {isa = PBXBuildFile; fileRef = 8E131523100F7C6B00367510 /* macho64header.h */; }; 27 | 8E131547100F7C6B00367510 /* macho_global.h in Headers */ = {isa = PBXBuildFile; fileRef = 8E131524100F7C6B00367510 /* macho_global.h */; settings = {ATTRIBUTES = (Public, ); }; }; 28 | 8E131548100F7C6B00367510 /* machoarchitecture.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8E131525100F7C6B00367510 /* machoarchitecture.cpp */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; }; 29 | 8E131549100F7C6B00367510 /* machoarchitecture.h in Headers */ = {isa = PBXBuildFile; fileRef = 8E131526100F7C6B00367510 /* machoarchitecture.h */; settings = {ATTRIBUTES = (Public, ); }; }; 30 | 8E13154A100F7C6B00367510 /* machoexception.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8E131527100F7C6B00367510 /* machoexception.cpp */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; }; 31 | 8E13154B100F7C6B00367510 /* machoexception.h in Headers */ = {isa = PBXBuildFile; fileRef = 8E131528100F7C6B00367510 /* machoexception.h */; settings = {ATTRIBUTES = (Public, ); }; }; 32 | 8E13154C100F7C6B00367510 /* machofile.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8E131529100F7C6B00367510 /* machofile.cpp */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; }; 33 | 8E13154D100F7C6B00367510 /* machofile.h in Headers */ = {isa = PBXBuildFile; fileRef = 8E13152A100F7C6B00367510 /* machofile.h */; settings = {ATTRIBUTES = (Public, ); }; }; 34 | 8E13154E100F7C6B00367510 /* machoheader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8E13152B100F7C6B00367510 /* machoheader.cpp */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; }; 35 | 8E13154F100F7C6B00367510 /* machoheader.h in Headers */ = {isa = PBXBuildFile; fileRef = 8E13152C100F7C6B00367510 /* machoheader.h */; settings = {ATTRIBUTES = (Public, ); }; }; 36 | 8E131550100F7C6B00367510 /* rpathcommand.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8E13152D100F7C6B00367510 /* rpathcommand.cpp */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; }; 37 | 8E131551100F7C6B00367510 /* rpathcommand.h in Headers */ = {isa = PBXBuildFile; fileRef = 8E13152E100F7C6B00367510 /* rpathcommand.h */; }; 38 | 8E131552100F7C6B00367510 /* symboltablecommand.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8E13152F100F7C6B00367510 /* symboltablecommand.cpp */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; }; 39 | 8E131553100F7C6B00367510 /* symboltablecommand.h in Headers */ = {isa = PBXBuildFile; fileRef = 8E131530100F7C6B00367510 /* symboltablecommand.h */; settings = {ATTRIBUTES = (Public, ); }; }; 40 | 8E131554100F7C6B00367510 /* symboltableentry.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8E131531100F7C6B00367510 /* symboltableentry.cpp */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; }; 41 | 8E131555100F7C6B00367510 /* symboltableentry.h in Headers */ = {isa = PBXBuildFile; fileRef = 8E131532100F7C6B00367510 /* symboltableentry.h */; settings = {ATTRIBUTES = (Public, ); }; }; 42 | 8E131556100F7C6B00367510 /* symboltableentry32.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8E131533100F7C6B00367510 /* symboltableentry32.cpp */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; }; 43 | 8E131557100F7C6B00367510 /* symboltableentry32.h in Headers */ = {isa = PBXBuildFile; fileRef = 8E131534100F7C6B00367510 /* symboltableentry32.h */; }; 44 | 8E131571100F7DB600367510 /* symboltableentry64.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8E13156F100F7DB600367510 /* symboltableentry64.cpp */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; }; 45 | 8E131572100F7DB600367510 /* symboltableentry64.h in Headers */ = {isa = PBXBuildFile; fileRef = 8E131570100F7DB600367510 /* symboltableentry64.h */; }; 46 | 8E212E93101237A50078924A /* machodemangleexception.h in Headers */ = {isa = PBXBuildFile; fileRef = 8E212E91101237A50078924A /* machodemangleexception.h */; settings = {ATTRIBUTES = (Public, ); }; }; 47 | 8E212E94101237A50078924A /* machodemangleexception.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8E212E92101237A50078924A /* machodemangleexception.cpp */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; }; 48 | 8E49393F100AA468004B7E53 /* CoreFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 8E49393E100AA468004B7E53 /* CoreFoundation.framework */; }; 49 | 8EA3DFF411AFD3790093CD87 /* uuidcommand.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8EA3DFF211AFD3790093CD87 /* uuidcommand.cpp */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; }; 50 | 8EA3DFF511AFD3790093CD87 /* uuidcommand.h in Headers */ = {isa = PBXBuildFile; fileRef = 8EA3DFF311AFD3790093CD87 /* uuidcommand.h */; }; 51 | 8EA3E17A11B12B5A0093CD87 /* dylinkercommand.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8EA3E17811B12B5A0093CD87 /* dylinkercommand.cpp */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; }; 52 | 8EA3E17B11B12B5A0093CD87 /* dylinkercommand.h in Headers */ = {isa = PBXBuildFile; fileRef = 8EA3E17911B12B5A0093CD87 /* dylinkercommand.h */; }; 53 | 8ED32FDE100B99EC00EBF623 /* machocache.h in Headers */ = {isa = PBXBuildFile; fileRef = 8ED32FDC100B99EC00EBF623 /* machocache.h */; settings = {ATTRIBUTES = (Public, ); }; }; 54 | 8ED32FDF100B99EC00EBF623 /* machocache.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8ED32FDD100B99EC00EBF623 /* machocache.cpp */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; }; 55 | /* End PBXBuildFile section */ 56 | 57 | /* Begin PBXFileReference section */ 58 | 0867D69BFE84028FC02AAC07 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = /System/Library/Frameworks/Foundation.framework; sourceTree = ""; }; 59 | 0867D6A5FE840307C02AAC07 /* AppKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AppKit.framework; path = /System/Library/Frameworks/AppKit.framework; sourceTree = ""; }; 60 | 32DBCF5E0370ADEE00C91783 /* MachO_Prefix.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MachO_Prefix.h; sourceTree = ""; wrapsLines = 0; }; 61 | 8DC2EF5B0486A6940098B216 /* MachO.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = MachO.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 62 | 8E131514100F7C6B00367510 /* dylibcommand.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = dylibcommand.cpp; sourceTree = ""; wrapsLines = 0; }; 63 | 8E131515100F7C6B00367510 /* dylibcommand.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = dylibcommand.h; sourceTree = ""; wrapsLines = 0; }; 64 | 8E131516100F7C6B00367510 /* dynamicloader.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = dynamicloader.cpp; sourceTree = ""; wrapsLines = 0; }; 65 | 8E131517100F7C6B00367510 /* dynamicloader.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = dynamicloader.h; sourceTree = ""; wrapsLines = 0; }; 66 | 8E131518100F7C6B00367510 /* genericcommand.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = genericcommand.cpp; sourceTree = ""; wrapsLines = 0; }; 67 | 8E131519100F7C6B00367510 /* genericcommand.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = genericcommand.h; sourceTree = ""; wrapsLines = 0; }; 68 | 8E13151A100F7C6B00367510 /* internalfile.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = internalfile.cpp; sourceTree = ""; wrapsLines = 0; }; 69 | 8E13151B100F7C6B00367510 /* internalfile.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = internalfile.h; sourceTree = ""; wrapsLines = 0; }; 70 | 8E13151C100F7C6B00367510 /* loadcommand.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = loadcommand.cpp; sourceTree = ""; wrapsLines = 0; }; 71 | 8E13151D100F7C6B00367510 /* loadcommand.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = loadcommand.h; sourceTree = ""; wrapsLines = 0; }; 72 | 8E13151E100F7C6B00367510 /* macho.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = macho.cpp; sourceTree = ""; wrapsLines = 0; }; 73 | 8E13151F100F7C6B00367510 /* macho.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = macho.h; sourceTree = ""; wrapsLines = 0; }; 74 | 8E131520100F7C6B00367510 /* macho32header.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = macho32header.cpp; sourceTree = ""; wrapsLines = 0; }; 75 | 8E131521100F7C6B00367510 /* macho32header.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = macho32header.h; sourceTree = ""; wrapsLines = 0; }; 76 | 8E131522100F7C6B00367510 /* macho64header.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = macho64header.cpp; sourceTree = ""; wrapsLines = 0; }; 77 | 8E131523100F7C6B00367510 /* macho64header.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = macho64header.h; sourceTree = ""; wrapsLines = 0; }; 78 | 8E131524100F7C6B00367510 /* macho_global.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = macho_global.h; sourceTree = ""; wrapsLines = 0; }; 79 | 8E131525100F7C6B00367510 /* machoarchitecture.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = machoarchitecture.cpp; sourceTree = ""; wrapsLines = 0; }; 80 | 8E131526100F7C6B00367510 /* machoarchitecture.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = machoarchitecture.h; sourceTree = ""; wrapsLines = 0; }; 81 | 8E131527100F7C6B00367510 /* machoexception.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = machoexception.cpp; sourceTree = ""; wrapsLines = 0; }; 82 | 8E131528100F7C6B00367510 /* machoexception.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = machoexception.h; sourceTree = ""; wrapsLines = 0; }; 83 | 8E131529100F7C6B00367510 /* machofile.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = machofile.cpp; sourceTree = ""; wrapsLines = 0; }; 84 | 8E13152A100F7C6B00367510 /* machofile.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = machofile.h; sourceTree = ""; wrapsLines = 0; }; 85 | 8E13152B100F7C6B00367510 /* machoheader.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = machoheader.cpp; sourceTree = ""; wrapsLines = 0; }; 86 | 8E13152C100F7C6B00367510 /* machoheader.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = machoheader.h; sourceTree = ""; wrapsLines = 0; }; 87 | 8E13152D100F7C6B00367510 /* rpathcommand.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = rpathcommand.cpp; sourceTree = ""; wrapsLines = 0; }; 88 | 8E13152E100F7C6B00367510 /* rpathcommand.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = rpathcommand.h; sourceTree = ""; wrapsLines = 0; }; 89 | 8E13152F100F7C6B00367510 /* symboltablecommand.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = symboltablecommand.cpp; sourceTree = ""; wrapsLines = 0; }; 90 | 8E131530100F7C6B00367510 /* symboltablecommand.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = symboltablecommand.h; sourceTree = ""; wrapsLines = 0; }; 91 | 8E131531100F7C6B00367510 /* symboltableentry.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = symboltableentry.cpp; sourceTree = ""; wrapsLines = 0; }; 92 | 8E131532100F7C6B00367510 /* symboltableentry.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = symboltableentry.h; sourceTree = ""; wrapsLines = 0; }; 93 | 8E131533100F7C6B00367510 /* symboltableentry32.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = symboltableentry32.cpp; sourceTree = ""; wrapsLines = 0; }; 94 | 8E131534100F7C6B00367510 /* symboltableentry32.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = symboltableentry32.h; sourceTree = ""; wrapsLines = 0; }; 95 | 8E131558100F7C9200367510 /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 96 | 8E13156F100F7DB600367510 /* symboltableentry64.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = symboltableentry64.cpp; sourceTree = ""; wrapsLines = 0; }; 97 | 8E131570100F7DB600367510 /* symboltableentry64.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = symboltableentry64.h; sourceTree = ""; wrapsLines = 0; }; 98 | 8E212E91101237A50078924A /* machodemangleexception.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = machodemangleexception.h; sourceTree = ""; wrapsLines = 0; }; 99 | 8E212E92101237A50078924A /* machodemangleexception.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = machodemangleexception.cpp; sourceTree = ""; wrapsLines = 0; }; 100 | 8E49393E100AA468004B7E53 /* CoreFoundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreFoundation.framework; path = /System/Library/Frameworks/CoreFoundation.framework; sourceTree = ""; }; 101 | 8E8C73DF106AA95D0037CF19 /* libboost_filesystem.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libboost_filesystem.a; path = /usr/local/lib/static/libboost_filesystem.a; sourceTree = ""; }; 102 | 8E8C73E0106AA95D0037CF19 /* libboost_system.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libboost_system.a; path = /usr/local/lib/static/libboost_system.a; sourceTree = ""; }; 103 | 8EA3DFF211AFD3790093CD87 /* uuidcommand.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = uuidcommand.cpp; sourceTree = ""; wrapsLines = 0; }; 104 | 8EA3DFF311AFD3790093CD87 /* uuidcommand.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = uuidcommand.h; sourceTree = ""; wrapsLines = 0; }; 105 | 8EA3E17811B12B5A0093CD87 /* dylinkercommand.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = dylinkercommand.cpp; sourceTree = ""; wrapsLines = 0; }; 106 | 8EA3E17911B12B5A0093CD87 /* dylinkercommand.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = dylinkercommand.h; sourceTree = ""; wrapsLines = 0; }; 107 | 8ED32FDC100B99EC00EBF623 /* machocache.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = machocache.h; sourceTree = ""; wrapsLines = 0; }; 108 | 8ED32FDD100B99EC00EBF623 /* machocache.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = machocache.cpp; sourceTree = ""; wrapsLines = 0; }; 109 | ADCDF193276D87BF002476ED /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/InfoPlist.strings; sourceTree = ""; }; 110 | D2F7E79907B2D74100F64583 /* CoreData.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreData.framework; path = /System/Library/Frameworks/CoreData.framework; sourceTree = ""; }; 111 | /* End PBXFileReference section */ 112 | 113 | /* Begin PBXFrameworksBuildPhase section */ 114 | 8DC2EF560486A6940098B216 /* Frameworks */ = { 115 | isa = PBXFrameworksBuildPhase; 116 | buildActionMask = 2147483647; 117 | files = ( 118 | 8E49393F100AA468004B7E53 /* CoreFoundation.framework in Frameworks */, 119 | ); 120 | runOnlyForDeploymentPostprocessing = 0; 121 | }; 122 | /* End PBXFrameworksBuildPhase section */ 123 | 124 | /* Begin PBXGroup section */ 125 | 034768DFFF38A50411DB9C8B /* Products */ = { 126 | isa = PBXGroup; 127 | children = ( 128 | 8DC2EF5B0486A6940098B216 /* MachO.framework */, 129 | ); 130 | name = Products; 131 | sourceTree = ""; 132 | }; 133 | 0867D691FE84028FC02AAC07 /* MachO */ = { 134 | isa = PBXGroup; 135 | children = ( 136 | 08FB77AEFE84172EC02AAC07 /* Classes */, 137 | 32C88DFF0371C24200C91783 /* Other Sources */, 138 | 089C1665FE841158C02AAC07 /* Resources */, 139 | 0867D69AFE84028FC02AAC07 /* External Frameworks and Libraries */, 140 | 034768DFFF38A50411DB9C8B /* Products */, 141 | ); 142 | name = MachO; 143 | sourceTree = ""; 144 | }; 145 | 0867D69AFE84028FC02AAC07 /* External Frameworks and Libraries */ = { 146 | isa = PBXGroup; 147 | children = ( 148 | 1058C7B0FEA5585E11CA2CBB /* Linked Frameworks */, 149 | 1058C7B2FEA5585E11CA2CBB /* Other Frameworks */, 150 | ); 151 | name = "External Frameworks and Libraries"; 152 | sourceTree = ""; 153 | }; 154 | 089C1665FE841158C02AAC07 /* Resources */ = { 155 | isa = PBXGroup; 156 | children = ( 157 | 8E131558100F7C9200367510 /* Info.plist */, 158 | 089C1666FE841158C02AAC07 /* InfoPlist.strings */, 159 | ); 160 | name = Resources; 161 | sourceTree = ""; 162 | }; 163 | 08FB77AEFE84172EC02AAC07 /* Classes */ = { 164 | isa = PBXGroup; 165 | children = ( 166 | 8EA3E17811B12B5A0093CD87 /* dylinkercommand.cpp */, 167 | 8EA3E17911B12B5A0093CD87 /* dylinkercommand.h */, 168 | 8EA3DFF211AFD3790093CD87 /* uuidcommand.cpp */, 169 | 8EA3DFF311AFD3790093CD87 /* uuidcommand.h */, 170 | 8E131514100F7C6B00367510 /* dylibcommand.cpp */, 171 | 8E131515100F7C6B00367510 /* dylibcommand.h */, 172 | 8E131516100F7C6B00367510 /* dynamicloader.cpp */, 173 | 8E131517100F7C6B00367510 /* dynamicloader.h */, 174 | 8E131518100F7C6B00367510 /* genericcommand.cpp */, 175 | 8E131519100F7C6B00367510 /* genericcommand.h */, 176 | 8E13151A100F7C6B00367510 /* internalfile.cpp */, 177 | 8E13151B100F7C6B00367510 /* internalfile.h */, 178 | 8E13151C100F7C6B00367510 /* loadcommand.cpp */, 179 | 8E13151D100F7C6B00367510 /* loadcommand.h */, 180 | 8E13151E100F7C6B00367510 /* macho.cpp */, 181 | 8E13151F100F7C6B00367510 /* macho.h */, 182 | 8E131520100F7C6B00367510 /* macho32header.cpp */, 183 | 8E131521100F7C6B00367510 /* macho32header.h */, 184 | 8E131522100F7C6B00367510 /* macho64header.cpp */, 185 | 8E131523100F7C6B00367510 /* macho64header.h */, 186 | 8E131524100F7C6B00367510 /* macho_global.h */, 187 | 8E131525100F7C6B00367510 /* machoarchitecture.cpp */, 188 | 8E131526100F7C6B00367510 /* machoarchitecture.h */, 189 | 8E131527100F7C6B00367510 /* machoexception.cpp */, 190 | 8E212E91101237A50078924A /* machodemangleexception.h */, 191 | 8E212E92101237A50078924A /* machodemangleexception.cpp */, 192 | 8E131528100F7C6B00367510 /* machoexception.h */, 193 | 8E131529100F7C6B00367510 /* machofile.cpp */, 194 | 8E13152A100F7C6B00367510 /* machofile.h */, 195 | 8E13152B100F7C6B00367510 /* machoheader.cpp */, 196 | 8E13152C100F7C6B00367510 /* machoheader.h */, 197 | 8E13152D100F7C6B00367510 /* rpathcommand.cpp */, 198 | 8E13152E100F7C6B00367510 /* rpathcommand.h */, 199 | 8E13152F100F7C6B00367510 /* symboltablecommand.cpp */, 200 | 8E131530100F7C6B00367510 /* symboltablecommand.h */, 201 | 8E131531100F7C6B00367510 /* symboltableentry.cpp */, 202 | 8E131532100F7C6B00367510 /* symboltableentry.h */, 203 | 8E131533100F7C6B00367510 /* symboltableentry32.cpp */, 204 | 8E131534100F7C6B00367510 /* symboltableentry32.h */, 205 | 8E13156F100F7DB600367510 /* symboltableentry64.cpp */, 206 | 8E131570100F7DB600367510 /* symboltableentry64.h */, 207 | 8ED32FDC100B99EC00EBF623 /* machocache.h */, 208 | 8ED32FDD100B99EC00EBF623 /* machocache.cpp */, 209 | ); 210 | name = Classes; 211 | sourceTree = ""; 212 | }; 213 | 1058C7B0FEA5585E11CA2CBB /* Linked Frameworks */ = { 214 | isa = PBXGroup; 215 | children = ( 216 | 8E8C73DF106AA95D0037CF19 /* libboost_filesystem.a */, 217 | 8E8C73E0106AA95D0037CF19 /* libboost_system.a */, 218 | 8E49393E100AA468004B7E53 /* CoreFoundation.framework */, 219 | ); 220 | name = "Linked Frameworks"; 221 | sourceTree = ""; 222 | }; 223 | 1058C7B2FEA5585E11CA2CBB /* Other Frameworks */ = { 224 | isa = PBXGroup; 225 | children = ( 226 | 0867D6A5FE840307C02AAC07 /* AppKit.framework */, 227 | D2F7E79907B2D74100F64583 /* CoreData.framework */, 228 | 0867D69BFE84028FC02AAC07 /* Foundation.framework */, 229 | ); 230 | name = "Other Frameworks"; 231 | sourceTree = ""; 232 | }; 233 | 32C88DFF0371C24200C91783 /* Other Sources */ = { 234 | isa = PBXGroup; 235 | children = ( 236 | 32DBCF5E0370ADEE00C91783 /* MachO_Prefix.h */, 237 | ); 238 | name = "Other Sources"; 239 | sourceTree = ""; 240 | }; 241 | /* End PBXGroup section */ 242 | 243 | /* Begin PBXHeadersBuildPhase section */ 244 | 8DC2EF500486A6940098B216 /* Headers */ = { 245 | isa = PBXHeadersBuildPhase; 246 | buildActionMask = 2147483647; 247 | files = ( 248 | 8ED32FDE100B99EC00EBF623 /* machocache.h in Headers */, 249 | 8E131538100F7C6B00367510 /* dylibcommand.h in Headers */, 250 | 8E13153A100F7C6B00367510 /* dynamicloader.h in Headers */, 251 | 8E13153C100F7C6B00367510 /* genericcommand.h in Headers */, 252 | 8E13153E100F7C6B00367510 /* internalfile.h in Headers */, 253 | 8E131540100F7C6B00367510 /* loadcommand.h in Headers */, 254 | 8E131542100F7C6B00367510 /* macho.h in Headers */, 255 | 8E131544100F7C6B00367510 /* macho32header.h in Headers */, 256 | 8E131546100F7C6B00367510 /* macho64header.h in Headers */, 257 | 8E131547100F7C6B00367510 /* macho_global.h in Headers */, 258 | 8E131549100F7C6B00367510 /* machoarchitecture.h in Headers */, 259 | 8E13154B100F7C6B00367510 /* machoexception.h in Headers */, 260 | 8E13154D100F7C6B00367510 /* machofile.h in Headers */, 261 | 8E13154F100F7C6B00367510 /* machoheader.h in Headers */, 262 | 8E131551100F7C6B00367510 /* rpathcommand.h in Headers */, 263 | 8E131553100F7C6B00367510 /* symboltablecommand.h in Headers */, 264 | 8E131555100F7C6B00367510 /* symboltableentry.h in Headers */, 265 | 8E131557100F7C6B00367510 /* symboltableentry32.h in Headers */, 266 | 8E131572100F7DB600367510 /* symboltableentry64.h in Headers */, 267 | 8E212E93101237A50078924A /* machodemangleexception.h in Headers */, 268 | 8EA3DFF511AFD3790093CD87 /* uuidcommand.h in Headers */, 269 | 8EA3E17B11B12B5A0093CD87 /* dylinkercommand.h in Headers */, 270 | ); 271 | runOnlyForDeploymentPostprocessing = 0; 272 | }; 273 | /* End PBXHeadersBuildPhase section */ 274 | 275 | /* Begin PBXNativeTarget section */ 276 | 8DC2EF4F0486A6940098B216 /* MachO */ = { 277 | isa = PBXNativeTarget; 278 | buildConfigurationList = 1DEB91AD08733DA50010E9CD /* Build configuration list for PBXNativeTarget "MachO" */; 279 | buildPhases = ( 280 | 8DC2EF500486A6940098B216 /* Headers */, 281 | 8DC2EF520486A6940098B216 /* Resources */, 282 | 8DC2EF540486A6940098B216 /* Sources */, 283 | 8DC2EF560486A6940098B216 /* Frameworks */, 284 | ); 285 | buildRules = ( 286 | ); 287 | dependencies = ( 288 | ); 289 | name = MachO; 290 | productInstallPath = "$(HOME)/Library/Frameworks"; 291 | productName = MachO; 292 | productReference = 8DC2EF5B0486A6940098B216 /* MachO.framework */; 293 | productType = "com.apple.product-type.framework"; 294 | }; 295 | /* End PBXNativeTarget section */ 296 | 297 | /* Begin PBXProject section */ 298 | 0867D690FE84028FC02AAC07 /* Project object */ = { 299 | isa = PBXProject; 300 | attributes = { 301 | LastUpgradeCheck = 1320; 302 | }; 303 | buildConfigurationList = 1DEB91B108733DA50010E9CD /* Build configuration list for PBXProject "MachO" */; 304 | compatibilityVersion = "Xcode 3.2"; 305 | developmentRegion = English; 306 | hasScannedForEncodings = 1; 307 | knownRegions = ( 308 | English, 309 | en, 310 | ); 311 | mainGroup = 0867D691FE84028FC02AAC07 /* MachO */; 312 | productRefGroup = 034768DFFF38A50411DB9C8B /* Products */; 313 | projectDirPath = ""; 314 | projectRoot = ""; 315 | targets = ( 316 | 8DC2EF4F0486A6940098B216 /* MachO */, 317 | ); 318 | }; 319 | /* End PBXProject section */ 320 | 321 | /* Begin PBXResourcesBuildPhase section */ 322 | 8DC2EF520486A6940098B216 /* Resources */ = { 323 | isa = PBXResourcesBuildPhase; 324 | buildActionMask = 2147483647; 325 | files = ( 326 | 8DC2EF530486A6940098B216 /* InfoPlist.strings in Resources */, 327 | ); 328 | runOnlyForDeploymentPostprocessing = 0; 329 | }; 330 | /* End PBXResourcesBuildPhase section */ 331 | 332 | /* Begin PBXSourcesBuildPhase section */ 333 | 8DC2EF540486A6940098B216 /* Sources */ = { 334 | isa = PBXSourcesBuildPhase; 335 | buildActionMask = 2147483647; 336 | files = ( 337 | 8ED32FDF100B99EC00EBF623 /* machocache.cpp in Sources */, 338 | 8E131537100F7C6B00367510 /* dylibcommand.cpp in Sources */, 339 | 8E131539100F7C6B00367510 /* dynamicloader.cpp in Sources */, 340 | 8E13153B100F7C6B00367510 /* genericcommand.cpp in Sources */, 341 | 8E13153D100F7C6B00367510 /* internalfile.cpp in Sources */, 342 | 8E13153F100F7C6B00367510 /* loadcommand.cpp in Sources */, 343 | 8E131541100F7C6B00367510 /* macho.cpp in Sources */, 344 | 8E131543100F7C6B00367510 /* macho32header.cpp in Sources */, 345 | 8E131545100F7C6B00367510 /* macho64header.cpp in Sources */, 346 | 8E131548100F7C6B00367510 /* machoarchitecture.cpp in Sources */, 347 | 8E13154A100F7C6B00367510 /* machoexception.cpp in Sources */, 348 | 8E13154C100F7C6B00367510 /* machofile.cpp in Sources */, 349 | 8E13154E100F7C6B00367510 /* machoheader.cpp in Sources */, 350 | 8E131550100F7C6B00367510 /* rpathcommand.cpp in Sources */, 351 | 8E131552100F7C6B00367510 /* symboltablecommand.cpp in Sources */, 352 | 8E131554100F7C6B00367510 /* symboltableentry.cpp in Sources */, 353 | 8E131556100F7C6B00367510 /* symboltableentry32.cpp in Sources */, 354 | 8E131571100F7DB600367510 /* symboltableentry64.cpp in Sources */, 355 | 8E212E94101237A50078924A /* machodemangleexception.cpp in Sources */, 356 | 8EA3DFF411AFD3790093CD87 /* uuidcommand.cpp in Sources */, 357 | 8EA3E17A11B12B5A0093CD87 /* dylinkercommand.cpp in Sources */, 358 | ); 359 | runOnlyForDeploymentPostprocessing = 0; 360 | }; 361 | /* End PBXSourcesBuildPhase section */ 362 | 363 | /* Begin PBXVariantGroup section */ 364 | 089C1666FE841158C02AAC07 /* InfoPlist.strings */ = { 365 | isa = PBXVariantGroup; 366 | children = ( 367 | ADCDF193276D87BF002476ED /* en */, 368 | ); 369 | name = InfoPlist.strings; 370 | sourceTree = ""; 371 | }; 372 | /* End PBXVariantGroup section */ 373 | 374 | /* Begin XCBuildConfiguration section */ 375 | 1DEB91AE08733DA50010E9CD /* Debug */ = { 376 | isa = XCBuildConfiguration; 377 | buildSettings = { 378 | ALWAYS_SEARCH_USER_PATHS = YES; 379 | CLANG_ENABLE_OBJC_ARC = YES; 380 | COPY_PHASE_STRIP = NO; 381 | DYLIB_COMPATIBILITY_VERSION = 1; 382 | DYLIB_CURRENT_VERSION = 1; 383 | FRAMEWORK_VERSION = A; 384 | GCC_DYNAMIC_NO_PIC = NO; 385 | GCC_MODEL_TUNING = G5; 386 | GCC_OPTIMIZATION_LEVEL = 0; 387 | GCC_PRECOMPILE_PREFIX_HEADER = YES; 388 | GCC_PREFIX_HEADER = MachO_Prefix.h; 389 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 390 | GCC_WARN_CHECK_SWITCH_STATEMENTS = YES; 391 | GCC_WARN_EFFECTIVE_CPLUSPLUS_VIOLATIONS = YES; 392 | GCC_WARN_INHIBIT_ALL_WARNINGS = YES; 393 | GCC_WARN_INITIALIZER_NOT_FULLY_BRACKETED = YES; 394 | GCC_WARN_NON_VIRTUAL_DESTRUCTOR = YES; 395 | INFOPLIST_FILE = Info.plist; 396 | INSTALL_PATH = "@executable_path/../Frameworks"; 397 | MACOSX_DEPLOYMENT_TARGET = 10.9; 398 | OTHER_LDFLAGS = "-Wl,-search_paths_first"; 399 | PRODUCT_BUNDLE_IDENTIFIER = "com.googlecode.${PRODUCT_NAME:identifier}"; 400 | PRODUCT_NAME = MachO; 401 | SDKROOT = macosx; 402 | WRAPPER_EXTENSION = framework; 403 | }; 404 | name = Debug; 405 | }; 406 | 1DEB91AF08733DA50010E9CD /* Release */ = { 407 | isa = XCBuildConfiguration; 408 | buildSettings = { 409 | CLANG_ENABLE_OBJC_ARC = YES; 410 | DEAD_CODE_STRIPPING = NO; 411 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 412 | DYLIB_COMPATIBILITY_VERSION = 1; 413 | DYLIB_CURRENT_VERSION = 1; 414 | FRAMEWORK_VERSION = A; 415 | GCC_MODEL_TUNING = G5; 416 | GCC_PRECOMPILE_PREFIX_HEADER = YES; 417 | GCC_PREFIX_HEADER = MachO_Prefix.h; 418 | INFOPLIST_FILE = Info.plist; 419 | INSTALL_PATH = "@executable_path/../Frameworks"; 420 | MACOSX_DEPLOYMENT_TARGET = 10.9; 421 | OTHER_LDFLAGS = "-Wl,-search_paths_first"; 422 | PRODUCT_BUNDLE_IDENTIFIER = "com.googlecode.${PRODUCT_NAME:identifier}"; 423 | PRODUCT_NAME = MachO; 424 | SDKROOT = macosx; 425 | WRAPPER_EXTENSION = framework; 426 | }; 427 | name = Release; 428 | }; 429 | 1DEB91B208733DA50010E9CD /* Debug */ = { 430 | isa = XCBuildConfiguration; 431 | buildSettings = { 432 | CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES; 433 | CLANG_CXX_LANGUAGE_STANDARD = "c++0x"; 434 | CLANG_CXX_LIBRARY = "libc++"; 435 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 436 | CLANG_WARN_BOOL_CONVERSION = YES; 437 | CLANG_WARN_COMMA = YES; 438 | CLANG_WARN_CONSTANT_CONVERSION = YES; 439 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 440 | CLANG_WARN_EMPTY_BODY = YES; 441 | CLANG_WARN_ENUM_CONVERSION = YES; 442 | CLANG_WARN_INFINITE_RECURSION = YES; 443 | CLANG_WARN_INT_CONVERSION = YES; 444 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 445 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 446 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 447 | CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; 448 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 449 | CLANG_WARN_STRICT_PROTOTYPES = YES; 450 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 451 | CLANG_WARN_UNREACHABLE_CODE = YES; 452 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 453 | DEPLOYMENT_LOCATION = NO; 454 | ENABLE_STRICT_OBJC_MSGSEND = YES; 455 | ENABLE_TESTABILITY = YES; 456 | GCC_INLINES_ARE_PRIVATE_EXTERN = NO; 457 | GCC_NO_COMMON_BLOCKS = YES; 458 | GCC_OPTIMIZATION_LEVEL = 0; 459 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 460 | GCC_WARN_ABOUT_RETURN_TYPE = YES; 461 | GCC_WARN_UNDECLARED_SELECTOR = YES; 462 | GCC_WARN_UNINITIALIZED_AUTOS = YES; 463 | GCC_WARN_UNUSED_FUNCTION = YES; 464 | GCC_WARN_UNUSED_VARIABLE = YES; 465 | MACOSX_DEPLOYMENT_TARGET = 10.7; 466 | ONLY_ACTIVE_ARCH = YES; 467 | SDKROOT = macosx; 468 | }; 469 | name = Debug; 470 | }; 471 | 1DEB91B308733DA50010E9CD /* Release */ = { 472 | isa = XCBuildConfiguration; 473 | buildSettings = { 474 | CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES; 475 | CLANG_CXX_LANGUAGE_STANDARD = "c++0x"; 476 | CLANG_CXX_LIBRARY = "libc++"; 477 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 478 | CLANG_WARN_BOOL_CONVERSION = YES; 479 | CLANG_WARN_COMMA = YES; 480 | CLANG_WARN_CONSTANT_CONVERSION = YES; 481 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 482 | CLANG_WARN_EMPTY_BODY = YES; 483 | CLANG_WARN_ENUM_CONVERSION = YES; 484 | CLANG_WARN_INFINITE_RECURSION = YES; 485 | CLANG_WARN_INT_CONVERSION = YES; 486 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 487 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 488 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 489 | CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; 490 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 491 | CLANG_WARN_STRICT_PROTOTYPES = YES; 492 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 493 | CLANG_WARN_UNREACHABLE_CODE = YES; 494 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 495 | ENABLE_STRICT_OBJC_MSGSEND = YES; 496 | GCC_NO_COMMON_BLOCKS = YES; 497 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 498 | GCC_WARN_ABOUT_RETURN_TYPE = YES; 499 | GCC_WARN_UNDECLARED_SELECTOR = YES; 500 | GCC_WARN_UNINITIALIZED_AUTOS = YES; 501 | GCC_WARN_UNUSED_FUNCTION = YES; 502 | GCC_WARN_UNUSED_VARIABLE = YES; 503 | MACOSX_DEPLOYMENT_TARGET = 10.7; 504 | SDKROOT = macosx; 505 | }; 506 | name = Release; 507 | }; 508 | /* End XCBuildConfiguration section */ 509 | 510 | /* Begin XCConfigurationList section */ 511 | 1DEB91AD08733DA50010E9CD /* Build configuration list for PBXNativeTarget "MachO" */ = { 512 | isa = XCConfigurationList; 513 | buildConfigurations = ( 514 | 1DEB91AE08733DA50010E9CD /* Debug */, 515 | 1DEB91AF08733DA50010E9CD /* Release */, 516 | ); 517 | defaultConfigurationIsVisible = 0; 518 | defaultConfigurationName = Release; 519 | }; 520 | 1DEB91B108733DA50010E9CD /* Build configuration list for PBXProject "MachO" */ = { 521 | isa = XCConfigurationList; 522 | buildConfigurations = ( 523 | 1DEB91B208733DA50010E9CD /* Debug */, 524 | 1DEB91B308733DA50010E9CD /* Release */, 525 | ); 526 | defaultConfigurationIsVisible = 0; 527 | defaultConfigurationName = Release; 528 | }; 529 | /* End XCConfigurationList section */ 530 | }; 531 | rootObject = 0867D690FE84028FC02AAC07 /* Project object */; 532 | } 533 | -------------------------------------------------------------------------------- /MachO/MachO.xcodeproj/xcshareddata/xcschemes/MachO.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 32 | 33 | 43 | 44 | 50 | 51 | 52 | 53 | 59 | 60 | 66 | 67 | 68 | 69 | 71 | 72 | 75 | 76 | 77 | -------------------------------------------------------------------------------- /MachO/MachO_Prefix.h: -------------------------------------------------------------------------------- 1 | // 2 | // Prefix header for all source files of the 'MachO' target in the 'MachO' project. 3 | // 4 | 5 | #ifdef __OBJC__ 6 | #import 7 | #endif 8 | 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | 17 | #include 18 | #include 19 | 20 | #include 21 | #include 22 | #include 23 | #include 24 | 25 | #include 26 | #include 27 | -------------------------------------------------------------------------------- /MachO/dylibcommand.cpp: -------------------------------------------------------------------------------- 1 | #include "dylibcommand.h" 2 | #include "machofile.h" 3 | #include "machoheader.h" 4 | 5 | #define HIBYTE(x) ( (unsigned char) ((x) >> 8) ) 6 | #define LOBYTE(x) ( (unsigned char) (x) ) 7 | #define HIWORD(x) ( (unsigned short) ( (x) >> 16) ) 8 | #define LOWORD(x) ( (unsigned short) (x) ) 9 | 10 | #define MAKEVERSION(x,y,z) 0x00000000 | (x << 16) | (y << 8) | z 11 | 12 | DylibCommand::DylibCommand(MachOHeader* header, DependencyType type) : 13 | LoadCommand(header), type(type) 14 | { 15 | file.readBytes((char*)&command, sizeof(command)); 16 | } 17 | 18 | DylibCommand::~DylibCommand() { 19 | } 20 | 21 | unsigned int DylibCommand::getSize() const { 22 | return file.getUint32(command.cmdsize); 23 | } 24 | 25 | std::string DylibCommand::getName() const { 26 | return getLcDataString(command.dylib.name.offset); 27 | } 28 | 29 | unsigned int DylibCommand::getCurrentVersion() const { 30 | return file.getUint32(command.dylib.current_version); 31 | } 32 | 33 | unsigned int DylibCommand::getCompatibleVersion() const { 34 | return file.getUint32(command.dylib.compatibility_version); 35 | } 36 | 37 | time_t DylibCommand::getTimeStamp() const { 38 | return file.getUint32(command.dylib.timestamp); 39 | } 40 | 41 | std::string DylibCommand::getVersionString(unsigned int version) { 42 | std::stringstream versionString; 43 | versionString << HIWORD(version) << "." << (unsigned short)HIBYTE(LOWORD(version)) << "." << (unsigned short)LOBYTE(LOWORD(version)); 44 | return versionString.str(); 45 | } 46 | 47 | 48 | -------------------------------------------------------------------------------- /MachO/dylibcommand.h: -------------------------------------------------------------------------------- 1 | #ifndef DYLIBCOMMAND_H 2 | #define DYLIBCOMMAND_H 3 | 4 | #include "macho_global.h" 5 | #include "loadcommand.h" 6 | class EXPORT DylibCommand : public LoadCommand 7 | { 8 | public: 9 | enum DependencyType { 10 | DependencyWeak, // dependency is allowed to be missing 11 | DependencyDelayed, // dependency is loaded when it is needed (not at start) 12 | DependencyNormal, 13 | DependencyId 14 | }; 15 | 16 | DylibCommand(MachOHeader* header, DependencyType type); 17 | virtual ~DylibCommand(); 18 | virtual unsigned int getSize() const; 19 | virtual unsigned int getStructureSize() const { return sizeof(command); } 20 | bool isId() const { return type==DependencyId; } 21 | bool isNecessary() const { return type!=DependencyWeak; } 22 | DependencyType getType() const { return type; } 23 | std::string getName() const; 24 | unsigned int getCurrentVersion() const; 25 | unsigned int getCompatibleVersion() const; 26 | time_t getTimeStamp() const; 27 | static std::string getVersionString(unsigned int version); 28 | 29 | private: 30 | dylib_command command; 31 | DependencyType type; 32 | 33 | }; 34 | 35 | #endif // DYLIBCOMMAND_H 36 | -------------------------------------------------------------------------------- /MachO/dylinkercommand.cpp: -------------------------------------------------------------------------------- 1 | #include "dylinkercommand.h" 2 | #include "machofile.h" 3 | #include "machoheader.h" 4 | #include 5 | 6 | DylinkerCommand::DylinkerCommand(MachOHeader* header) : 7 | LoadCommand(header) { 8 | file.readBytes((char*)&command, sizeof(command)); 9 | } 10 | 11 | DylinkerCommand::~DylinkerCommand() { 12 | } 13 | 14 | unsigned int DylinkerCommand::getSize() const { 15 | return file.getUint32(command.cmdsize); 16 | } 17 | 18 | std::string DylinkerCommand::getName() const { 19 | return getLcDataString(command.name.offset); 20 | } 21 | 22 | -------------------------------------------------------------------------------- /MachO/dylinkercommand.h: -------------------------------------------------------------------------------- 1 | #ifndef DYLINKERCOMMAND_H 2 | #define DYLINKERCOMMAND_H 3 | 4 | #include "macho_global.h" 5 | #include "loadcommand.h" 6 | class EXPORT DylinkerCommand : public LoadCommand 7 | { 8 | public: 9 | DylinkerCommand(MachOHeader* header); 10 | virtual ~DylinkerCommand(); 11 | virtual unsigned int getSize() const; 12 | virtual unsigned int getStructureSize() const { return sizeof(command); } 13 | std::string getName() const; 14 | private: 15 | dylinker_command command; 16 | 17 | }; 18 | 19 | #endif // DYLINKERCOMMAND_H 20 | -------------------------------------------------------------------------------- /MachO/dynamicloader.cpp: -------------------------------------------------------------------------------- 1 | #include "dynamicloader.h" 2 | #include "machofile.h" 3 | #include "machoarchitecture.h" 4 | 5 | #include 6 | #include 7 | #include 8 | 9 | /* 10 | This class emulates the search path mechanism of dyld 11 | http://developer.apple.com/documentation/Darwin/Reference/Manpages/man1/dyld.1.html 12 | Unfortunately the several documents from apple contradict each other. Therefore I analyzed the source of the original dyld 13 | http://www.opensource.apple.com/source/dyld/dyld-97.1/src/dyld.cpp 14 | */ 15 | 16 | const char DynamicLoader::EnvironmentPathVariable::PATHS_SEPARATOR = ':'; 17 | 18 | DynamicLoader::EnvironmentPathVariable::EnvironmentPathVariable() { 19 | // never call that explicitly 20 | } 21 | 22 | DynamicLoader::EnvironmentPathVariable::EnvironmentPathVariable(const char* homePath, const std::string& name, const StringList& defaultValues) 23 | { 24 | this->homePath = homePath; 25 | const char* envValue = getenv(name.c_str()); 26 | std::string values; 27 | if (envValue) { 28 | values = envValue; 29 | } 30 | 31 | if (!values.empty()) { 32 | std::stringstream v(values); 33 | std::string item; 34 | while (std::getline(v, item, PATHS_SEPARATOR)) { 35 | addPath(item); 36 | } 37 | } else { 38 | setPaths(defaultValues); 39 | } 40 | } 41 | 42 | void DynamicLoader::EnvironmentPathVariable::setPaths(const StringList& paths) { 43 | this->paths = paths; 44 | 45 | for (StringList::iterator it = this->paths.begin(); it!=this->paths.end(); ++it) { 46 | replaceHomeDirectory(*it); 47 | } 48 | } 49 | 50 | void DynamicLoader::EnvironmentPathVariable::addPath(const std::string& path) { 51 | paths.push_back(path); 52 | replaceHomeDirectory(paths.back()); 53 | } 54 | 55 | bool DynamicLoader::EnvironmentPathVariable::replaceHomeDirectory(std::string& path) { 56 | size_t homePos = path.find("~/"); 57 | if (homePos != std::string::npos) { 58 | path.replace(homePos, 1, homePath); 59 | return true; 60 | } 61 | return false; 62 | } 63 | 64 | bool DynamicLoader::EnvironmentPathVariable::isEmpty() const { 65 | if (!paths.empty()) { 66 | return paths.front().empty(); 67 | } 68 | return true; 69 | } 70 | 71 | // the order must be the order of the enum! 72 | const char* DynamicLoader::ENVIRONMENT_VARIABLE_NAMES[DynamicLoader::NumEnvironmentVariables] = { 73 | "LD_LIBRARY_PATH", 74 | "DYLD_FRAMEWORK_PATH", 75 | "DYLD_LIBRARY_PATH", 76 | "DYLD_FALLBACK_FRAMEWORK_PATH", 77 | "DYLD_FALLBACK_LIBRARY_PATH", 78 | "DYLD_IMAGE_SUFFIX" 79 | }; 80 | 81 | const char* DynamicLoader::PLACEHOLDERS[DynamicLoader::NumPlaceholders] = { 82 | "@executable_path", 83 | "@loader_path", 84 | "@rpath" 85 | }; 86 | 87 | const char* DynamicLoader::PATH_SEPARATOR = "/"; 88 | 89 | const char* DynamicLoader::DEFAULT_FRAMEWORK_PATH[] = { 90 | "~/Library/Frameworks", 91 | "/Library/Frameworks", 92 | "/Network/Library/Frameworks", 93 | "/System/Library/Frameworks" 94 | }; 95 | 96 | const char* DynamicLoader::DEFAULT_LIBRARY_PATH[] = { 97 | "~/lib", 98 | "/usr/local/lib", 99 | "/lib", 100 | "/usr/lib" 101 | }; 102 | 103 | // unfortunately cannot make stringList const here, but treat it as const 104 | const StringList DynamicLoader::ENVIRONMENT_VARIABLE_DEFAULT_VALUES[DynamicLoader::NumEnvironmentVariables] = { 105 | StringList(), 106 | StringList(), 107 | StringList(), 108 | StringList(DEFAULT_FRAMEWORK_PATH, DEFAULT_FRAMEWORK_PATH + sizeof(DEFAULT_FRAMEWORK_PATH) / sizeof(*DEFAULT_FRAMEWORK_PATH)), 109 | StringList(DEFAULT_LIBRARY_PATH, DEFAULT_LIBRARY_PATH + sizeof(DEFAULT_LIBRARY_PATH) / sizeof(*DEFAULT_LIBRARY_PATH)), 110 | StringList() 111 | }; 112 | 113 | DynamicLoader::DynamicLoader() 114 | { 115 | homePath = strdup(getUserHomeDirectory()); 116 | // init/read out some variables 117 | for (unsigned int i=0; i < NumEnvironmentVariables; i++) { 118 | environmentVariables[i] = EnvironmentPathVariable(homePath, ENVIRONMENT_VARIABLE_NAMES[i], ENVIRONMENT_VARIABLE_DEFAULT_VALUES[i]); 119 | } 120 | 121 | } 122 | 123 | DynamicLoader::~DynamicLoader() { 124 | free((void*)homePath); 125 | } 126 | 127 | const char* DynamicLoader::getUserHomeDirectory() const { 128 | struct passwd* pwd = getpwuid(getuid()); 129 | if (pwd) 130 | { 131 | return pwd->pw_dir; 132 | } 133 | else 134 | { 135 | // try the $HOME environment variable 136 | return getenv("HOME"); 137 | } 138 | } 139 | 140 | std::string DynamicLoader::replacePlaceholder(const std::string& name, const MachOArchitecture* architecture) const { 141 | std::string resolvedName = name; 142 | if (name.find(PLACEHOLDERS[ExecutablePath]) == 0) { 143 | resolvedName.replace(0, strlen(PLACEHOLDERS[ExecutablePath]), architecture->getFile()->getExecutablePath()); 144 | } else if (name.find(PLACEHOLDERS[LoaderPath]) == 0) { 145 | resolvedName.replace(0, strlen(PLACEHOLDERS[LoaderPath]), architecture->getFile()->getDirectory()); 146 | } 147 | return resolvedName; 148 | } 149 | 150 | std::string DynamicLoader::getPathname(const std::string& name, const MachOArchitecture* architecture, const std::string& workingPath) const { 151 | // simple name (only the last part of the name, after the last PATH_SEPARATOR) 152 | size_t lastSlashPosition = name.rfind(PATH_SEPARATOR); 153 | std::string simpleName; 154 | if (lastSlashPosition != std::string::npos && lastSlashPosition < name.length() - 1) { 155 | simpleName = name.substr(lastSlashPosition+1); 156 | } else { 157 | simpleName = name; 158 | } 159 | 160 | // try LD_LIBRARY_PATH 161 | std::string pathName; 162 | pathName = getExistingPathname(simpleName, environmentVariables[LdLibraryPath], workingPath); 163 | if (!pathName.empty()) 164 | return pathName; 165 | 166 | std::string frameworkName = getFrameworkName(name); 167 | if (!frameworkName.empty()) { 168 | // strip the already contained suffix 169 | pathName = getExistingPathname(frameworkName, environmentVariables[DyldFrameworkPath], workingPath); 170 | if (!pathName.empty()) 171 | return pathName; 172 | } 173 | 174 | pathName = getExistingPathname(simpleName, environmentVariables[DyldLibraryPath], workingPath); 175 | if (!pathName.empty()) 176 | return pathName; 177 | 178 | // resolve placeholder 179 | std::string resolvedName = replacePlaceholder(name, architecture); 180 | if (!resolvedName.empty()) { 181 | pathName = getExistingPathname(resolvedName, workingPath); 182 | if (!pathName.empty()) 183 | return pathName; 184 | } 185 | 186 | if (name.find(PLACEHOLDERS[Rpath]) == 0) { 187 | // substitute @rpath with all -rpath paths up the load chain 188 | std::vector rpaths = architecture->getRpaths(); 189 | 190 | for (std::vector::iterator it = rpaths.begin(); it != rpaths.end(); ++it) { 191 | // rpath may contain @loader_path or @executable_path 192 | std::string rpath = replacePlaceholder((**it), architecture); 193 | resolvedName = name; 194 | resolvedName.replace(0, strlen(PLACEHOLDERS[Rpath]), rpath); 195 | pathName = getExistingPathname(resolvedName, workingPath); 196 | if (!pathName.empty()) 197 | return pathName; 198 | } 199 | 200 | // after checking against all stored rpaths substitute @rpath with LD_LIBRARY_PATH (if it is set) 201 | EnvironmentPathVariable ldLibraryPaths = environmentVariables[LdLibraryPath]; 202 | if (!ldLibraryPaths.isEmpty()) { 203 | for (StringList::const_iterator it = ldLibraryPaths.getPaths().begin(); it != ldLibraryPaths.getPaths().end(); ++it) { 204 | resolvedName = name; 205 | resolvedName.replace(0, strlen(PLACEHOLDERS[Rpath]), (*it)); 206 | pathName = getExistingPathname(resolvedName, workingPath); 207 | if (!pathName.empty()) 208 | return pathName; 209 | } 210 | } 211 | } 212 | 213 | // check pure path (either absolute or relative to working directory) 214 | pathName = getExistingPathname(name, workingPath); 215 | if (!pathName.empty()) 216 | return pathName; 217 | 218 | // try fallbacks (or its defaults) 219 | if (!frameworkName.empty()) { 220 | pathName = getExistingPathname(frameworkName, environmentVariables[DyldFallbackFrameworkPath], workingPath); 221 | if (!pathName.empty()) 222 | return pathName; 223 | } 224 | 225 | return getExistingPathname(name, environmentVariables[DyldFallbackLibraryPath], workingPath); 226 | } 227 | 228 | // returns the name is of a framework without any preceeding path information if name specifies a framework, otherwise an invalid string 229 | std::string DynamicLoader::getFrameworkName(const std::string& name, const bool strippedSuffix) const { 230 | // fail fast in case of dylibs 231 | if (name.find(".framework/") == std::string::npos) { 232 | return ""; 233 | } 234 | 235 | /* first look for the form Foo.framework/Foo 236 | next look for the form Foo.framework/Versions/A/Foo 237 | A and Foo are arbitrary strings without a slash */ 238 | 239 | // get Foo (part after last slash) 240 | size_t lastSlashPosition = name.rfind(PATH_SEPARATOR); 241 | if (lastSlashPosition == std::string::npos || lastSlashPosition == name.length() -1) { 242 | return ""; 243 | } 244 | 245 | const std::string foo = name.substr(lastSlashPosition+1); 246 | const std::string frameworkPart = foo+".framework/"; 247 | const std::string framework = frameworkPart + foo; 248 | 249 | if (endsWith(name, framework)) { 250 | // strip first part 251 | return framework; 252 | } 253 | int startPosition = name.find(frameworkPart+"Versions/"); 254 | bool hasCorrectEnd = endsWith(name, foo); 255 | 256 | // TODO: check between Versions/ and foo there must be no additional slash 257 | if (startPosition != std::string::npos) { 258 | if (hasCorrectEnd) { 259 | return name.substr(startPosition); 260 | } else if (strippedSuffix == false) { 261 | // maybe we have a case, where name contains a suffix in foo (which then of course occurs only in the last foo) 262 | // does foo already contain a suffix? 263 | size_t suffixStart = foo.rfind("_"); 264 | if (suffixStart != std::string::npos) { 265 | std::string newName = name; 266 | newName.erase(lastSlashPosition+1+suffixStart); 267 | return getFrameworkName(newName, true); 268 | } 269 | } 270 | } 271 | 272 | // if we are at this part the given name was no framework 273 | return ""; 274 | } 275 | 276 | std::string DynamicLoader::getExistingPathname(const std::string& name, const EnvironmentPathVariable& environmentPathVariable, const std::string& workingPath) const { 277 | std::string result; 278 | const StringList directories = environmentPathVariable.getPaths(); 279 | for (StringList::const_iterator it = directories.begin(); it != directories.end(); ++it) { 280 | result = getExistingPathname(name, *it, workingPath); 281 | if (!result.empty()) 282 | return result; 283 | } 284 | return result; 285 | } 286 | 287 | std::string DynamicLoader::getExistingPathname(const std::string& file, const std::string& directory, const std::string& workingPath) const { 288 | std::string name = file; 289 | if (!directory.empty()) { 290 | if (!endsWith(directory, "/")) { 291 | name = directory + "/" + file; 292 | } else { 293 | name = directory + file; 294 | } 295 | } 296 | return getExistingPathname(name, workingPath); 297 | } 298 | 299 | std::string DynamicLoader::getExistingPathname(const std::string& name, const std::string& workingPath, bool withSuffix) const { 300 | 301 | // complete path 302 | std::string usedName = name; 303 | bool tryAgainWithoutSuffix = false; 304 | 305 | // first try with suffix 306 | if (withSuffix && !environmentVariables[DyldImageSuffix].isEmpty()) { 307 | // only one suffix is considered 308 | const std::string suffix = environmentVariables[DyldImageSuffix].getPaths().front(); 309 | // where should we append suffix? 310 | if (endsWith(name, ".dylib")) { 311 | usedName.insert(name.rfind("."), suffix); 312 | } else { 313 | usedName += suffix; 314 | } 315 | tryAgainWithoutSuffix = true; 316 | } 317 | 318 | // make path absolute (with working directory) if it is not absolute yet 319 | if (usedName.compare(0, 1, "/") != 0) { 320 | usedName = workingPath + "/" + usedName; 321 | } 322 | 323 | struct stat buffer; 324 | if (stat(usedName.c_str(), &buffer) == 0) { 325 | return usedName; 326 | } else { 327 | // try without suffix 328 | if (tryAgainWithoutSuffix) { 329 | return getExistingPathname(name, workingPath, false); 330 | } 331 | } 332 | return ""; 333 | } 334 | 335 | bool DynamicLoader::endsWith(const std::string& str, const std::string& substr) { 336 | size_t i = str.rfind(substr); 337 | return (i != std::string::npos) && (i == (str.length() - substr.length())); 338 | } 339 | -------------------------------------------------------------------------------- /MachO/dynamicloader.h: -------------------------------------------------------------------------------- 1 | #ifndef DYNAMICLOADER_H 2 | #define DYNAMICLOADER_H 3 | 4 | #include "macho_global.h" 5 | 6 | typedef std::list StringList; 7 | 8 | class MachOArchitecture; 9 | class DynamicLoader 10 | { 11 | public: 12 | DynamicLoader(); 13 | virtual ~DynamicLoader(); 14 | 15 | std::string replacePlaceholder(const std::string& name, const MachOArchitecture* architecture) const; 16 | std::string getPathname(const std::string& name, const MachOArchitecture* architecture, const std::string& workingDirectory) const; 17 | 18 | private: 19 | class EnvironmentPathVariable 20 | { 21 | public: 22 | EnvironmentPathVariable(); 23 | EnvironmentPathVariable(const char* homePath, const std::string& name, const StringList& defaultValues = StringList()); 24 | 25 | bool isEmpty() const; 26 | const StringList& getPaths() const { return paths; } 27 | 28 | private: 29 | 30 | void setPaths(const StringList& paths); 31 | void addPath(const std::string& path); 32 | bool replaceHomeDirectory(std::string& path); 33 | StringList paths; 34 | static const char PATHS_SEPARATOR; 35 | const char* homePath; 36 | }; 37 | 38 | enum { 39 | LdLibraryPath, 40 | DyldFrameworkPath, 41 | DyldLibraryPath, 42 | DyldFallbackFrameworkPath, 43 | DyldFallbackLibraryPath, 44 | DyldImageSuffix, 45 | NumEnvironmentVariables 46 | }; 47 | 48 | enum Placeholder { 49 | ExecutablePath, 50 | LoaderPath, 51 | Rpath, 52 | NumPlaceholders 53 | }; 54 | 55 | static const char* PLACEHOLDERS[NumPlaceholders]; 56 | static const char* ENVIRONMENT_VARIABLE_NAMES[NumEnvironmentVariables]; 57 | static const char* PATH_SEPARATOR; 58 | static const StringList ENVIRONMENT_VARIABLE_DEFAULT_VALUES[NumEnvironmentVariables]; 59 | 60 | static const char* DEFAULT_FRAMEWORK_PATH[]; 61 | static const char* DEFAULT_LIBRARY_PATH[]; 62 | const char* homePath; 63 | 64 | EnvironmentPathVariable environmentVariables[NumEnvironmentVariables]; 65 | 66 | std::string getFrameworkName(const std::string& name, const bool strippedSuffix = false) const; 67 | const char* getUserHomeDirectory() const; 68 | 69 | std::string getExistingPathname(const std::string& name, const EnvironmentPathVariable& environmentPathVariable, const std::string& workingPath) const; 70 | std::string getExistingPathname(const std::string& name, const std::string& directory, const std::string& workingPath) const; 71 | std::string getExistingPathname(const std::string& name, const std::string& workingPath, bool withSuffix=true) const; 72 | 73 | static bool endsWith(const std::string& str, const std::string& substr); 74 | }; 75 | 76 | #endif // DYNAMICLOADER_H 77 | -------------------------------------------------------------------------------- /MachO/en.lproj/InfoPlist.strings: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kwin/macdependency/1cf589d0ccceb9c90ee94b3ad3a79e67a66e5e38/MachO/en.lproj/InfoPlist.strings -------------------------------------------------------------------------------- /MachO/genericcommand.cpp: -------------------------------------------------------------------------------- 1 | #include "genericcommand.h" 2 | #include "machofile.h" 3 | #include "machoheader.h" 4 | 5 | GenericCommand::GenericCommand(MachOHeader* header) : 6 | LoadCommand(header) 7 | { 8 | file.readBytes((char*)&command, sizeof(command)); 9 | } 10 | 11 | unsigned int GenericCommand::getSize() const { 12 | return file.getUint32(command.cmdsize); 13 | } 14 | -------------------------------------------------------------------------------- /MachO/genericcommand.h: -------------------------------------------------------------------------------- 1 | #ifndef GENERICCOMMAND_H 2 | #define GENERICCOMMAND_H 3 | 4 | #include "loadcommand.h" 5 | 6 | class GenericCommand : public LoadCommand 7 | { 8 | public: 9 | GenericCommand(MachOHeader* header); 10 | virtual unsigned int getSize() const; 11 | private: 12 | load_command command; 13 | }; 14 | 15 | #endif // GENERICCOMMAND_H 16 | -------------------------------------------------------------------------------- /MachO/internalfile.cpp: -------------------------------------------------------------------------------- 1 | #include "internalfile.h" 2 | #include "machoexception.h" 3 | 4 | // use reference counting to reuse files for all used architectures 5 | InternalFile* InternalFile::create(InternalFile* file) { 6 | file->counter++; 7 | return file; 8 | } 9 | 10 | InternalFile* InternalFile::create(const std::string& filename) { 11 | return new InternalFile(filename); 12 | } 13 | 14 | void InternalFile::release() { 15 | counter--; 16 | if (counter < 1) { 17 | delete this; 18 | } 19 | } 20 | 21 | InternalFile::InternalFile(const std::string& filename) : 22 | filename(filename), counter(1) 23 | { 24 | // open file handle 25 | file.open(this->filename, std::ios_base::in | std::ios_base::binary); 26 | if (file.fail()) { 27 | std::ostringstream error; 28 | error << "Couldn't open file '" << filename << "'."; 29 | throw MachOException(error.str()); 30 | } 31 | 32 | struct stat buffer; 33 | if (stat(filename.c_str(), &buffer) >= 0) { 34 | _fileSize = buffer.st_size; 35 | _lastWriteTime = buffer.st_mtime; 36 | } 37 | } 38 | 39 | // destructor is private since we use reference counting mechanism 40 | InternalFile::~InternalFile() { 41 | file.close(); 42 | } 43 | 44 | /* returns whole filename (including path)*/ 45 | std::string InternalFile::getName() const { 46 | // Try to canonicalize path. 47 | char buffer[PATH_MAX]; 48 | if (realpath(filename.c_str(), buffer) == nullptr) 49 | return filename; 50 | 51 | return buffer; 52 | } 53 | 54 | /* returns filename without path */ 55 | std::string InternalFile::getTitle() const { 56 | return filename; 57 | } 58 | 59 | unsigned long long InternalFile::getSize() const { 60 | return _fileSize; 61 | } 62 | 63 | bool InternalFile::seek(long long int position) { 64 | file.seekg(position, std::ios_base::beg); 65 | if (file.fail()) { 66 | file.clear(); 67 | return false; 68 | } 69 | return true; 70 | } 71 | 72 | std::streamsize InternalFile::read(char* buffer, std::streamsize size) { 73 | file.read(buffer, size); 74 | if (file.fail()) { 75 | file.clear(); 76 | return file.gcount(); 77 | } 78 | // TODO: handle badbit 79 | return size; 80 | } 81 | 82 | long long int InternalFile::getPosition() { 83 | return file.tellg(); 84 | } 85 | 86 | time_t InternalFile::getLastModificationTime() const { 87 | return _lastWriteTime; 88 | } 89 | -------------------------------------------------------------------------------- /MachO/internalfile.h: -------------------------------------------------------------------------------- 1 | #ifndef INTERNALFILE_H 2 | #define INTERNALFILE_H 3 | 4 | #include "macho_global.h" 5 | 6 | class InternalFile 7 | { 8 | 9 | public: 10 | virtual ~InternalFile(); 11 | 12 | static InternalFile* create(InternalFile* file); 13 | static InternalFile* create(const std::string& filename); 14 | void release(); 15 | 16 | std::string getFolder() const; 17 | std::string getName() const; 18 | std::string getTitle() const; 19 | unsigned long long getSize() const; 20 | bool seek(long long int position); 21 | std::streamsize read(char* buffer, std::streamsize size); 22 | long long int getPosition(); 23 | time_t getLastModificationTime() const; 24 | 25 | private: 26 | unsigned int counter; 27 | 28 | InternalFile(const std::string& filename); 29 | std::ifstream file; 30 | std::string filename; 31 | size_t _fileSize; 32 | time_t _lastWriteTime; 33 | }; 34 | 35 | #endif // INTERNALFILE_H 36 | -------------------------------------------------------------------------------- /MachO/loadcommand.cpp: -------------------------------------------------------------------------------- 1 | #include "loadcommand.h" 2 | #include "dylibcommand.h" 3 | #include "genericcommand.h" 4 | #include "symboltablecommand.h" 5 | #include "rpathcommand.h" 6 | #include "uuidcommand.h" 7 | #include "dylinkercommand.h" 8 | #include "machoexception.h" 9 | #include "machoheader.h" 10 | 11 | 12 | LoadCommand* LoadCommand::getLoadCommand(unsigned int cmd, MachOHeader* header) { 13 | 14 | LoadCommand* loadCommand; 15 | switch(cmd) { 16 | case LC_LOAD_DYLINKER: 17 | loadCommand = new DylinkerCommand(header); 18 | break; 19 | case LC_UUID: 20 | loadCommand = new UuidCommand(header); 21 | break; 22 | case LC_LAZY_LOAD_DYLIB: // dependency is loaded when it is needed 23 | loadCommand = new DylibCommand(header, DylibCommand::DependencyDelayed); 24 | break; 25 | case LC_LOAD_WEAK_DYLIB: // dependency is allowed to be missing 26 | loadCommand = new DylibCommand(header, DylibCommand::DependencyWeak); 27 | break; 28 | case LC_REEXPORT_DYLIB: 29 | case LC_LOAD_DYLIB: 30 | loadCommand = new DylibCommand(header, DylibCommand::DependencyNormal); 31 | break; 32 | case LC_ID_DYLIB: 33 | loadCommand = new DylibCommand(header, DylibCommand::DependencyId); 34 | break; 35 | case LC_SYMTAB: 36 | loadCommand = new SymbolTableCommand(header); 37 | break; 38 | case LC_RPATH: 39 | loadCommand = new RpathCommand(header); 40 | break; 41 | default: 42 | loadCommand = new GenericCommand(header); 43 | break; 44 | } 45 | return loadCommand; 46 | } 47 | 48 | 49 | LoadCommand::LoadCommand(MachOHeader* header) : 50 | header(header), file(header->getFile()), offset(file.getPosition()), lcData(0) 51 | { 52 | 53 | } 54 | 55 | LoadCommand::~LoadCommand() { 56 | delete[] lcData; 57 | } 58 | 59 | void LoadCommand::readLcData() const { 60 | file.seek(offset + getStructureSize()); 61 | unsigned int size = getSize() - getStructureSize(); 62 | lcData = new char[size]; 63 | file.readBytes(lcData, size); 64 | } 65 | 66 | // the offset is not yet in correct byte order here 67 | const char* LoadCommand::getLcDataString(unsigned int offset) const { 68 | if (!lcData) 69 | readLcData(); 70 | 71 | return lcData+file.getUint32(offset)-getStructureSize(); 72 | } 73 | -------------------------------------------------------------------------------- /MachO/loadcommand.h: -------------------------------------------------------------------------------- 1 | #ifndef LOADCOMMAND_H 2 | #define LOADCOMMAND_H 3 | #include "macho_global.h" 4 | 5 | class MachOHeader; 6 | class MachOFile; 7 | 8 | class EXPORT LoadCommand 9 | { 10 | protected: 11 | LoadCommand(MachOHeader* header); 12 | public: 13 | static LoadCommand* getLoadCommand(unsigned int cmd, MachOHeader* header); 14 | virtual ~LoadCommand(); 15 | virtual unsigned int getSize() const = 0; 16 | // is smaller than getSize() because it only returns the size of the command structure 17 | // only necessary if command uses getLcData() 18 | virtual unsigned int getStructureSize() const { return 0; } 19 | protected: 20 | MachOHeader* header; 21 | MachOFile& file; 22 | const unsigned int offset; 23 | 24 | const char* getLcDataString(unsigned int offset) const; 25 | private: 26 | mutable char* lcData; 27 | 28 | void readLcData() const; 29 | }; 30 | 31 | #endif // LOADCOMMAND_H 32 | -------------------------------------------------------------------------------- /MachO/macho.cpp: -------------------------------------------------------------------------------- 1 | #include "macho.h" 2 | #include "machoexception.h" 3 | #include "machofile.h" 4 | #include "machoarchitecture.h" 5 | #include "dynamicloader.h" 6 | #include "machoheader.h" 7 | 8 | #include 9 | 10 | // see http://developer.apple.com/mac/library/documentation/DeveloperTools/Conceptual/MachORuntime/Reference/reference.html 11 | // for MachO specification 12 | 13 | // static variables 14 | DynamicLoader* MachO::dynamicLoader = 0; 15 | int MachO::referenceCounter = 0; 16 | 17 | MachO::MachO(const std::string& filename, const MachO* parent) : parent(parent), bundle(NULL) 18 | { 19 | // check if filename is bundle 20 | std::string appFilename = getApplicationInBundle(filename); 21 | init(appFilename, parent); 22 | 23 | if (referenceCounter == 0) { 24 | dynamicLoader = new DynamicLoader(); 25 | } 26 | referenceCounter++; 27 | } 28 | 29 | std::string MachO::getApplicationInBundle(const std::string& filename) { 30 | CFURLRef bundleUrl = 0; 31 | std::string appFilename = filename; 32 | bundleUrl = CFURLCreateFromFileSystemRepresentation(NULL, (const UInt8 *)filename.c_str() , filename.length(), true); 33 | if (bundleUrl != NULL) { 34 | bundle = CFBundleCreate(NULL, bundleUrl); 35 | CFRelease(bundleUrl); 36 | if (bundle != NULL) { 37 | CFURLRef executableUrl = CFBundleCopyExecutableURL(bundle); 38 | if (executableUrl != 0) { 39 | char executableFile[FILENAME_MAX]; 40 | CFURLGetFileSystemRepresentation(executableUrl, true, (UInt8 *)executableFile, FILENAME_MAX); 41 | appFilename = executableFile; 42 | CFRelease(executableUrl); 43 | //this->bundlePath = filename; 44 | } 45 | } 46 | } 47 | return appFilename; 48 | } 49 | 50 | void MachO::init(const std::string& fileName, const MachO* parent) 51 | { 52 | MachOFile* parentFile = 0; 53 | if (parent) { 54 | parentFile = parent->file; 55 | } 56 | file = new MachOFile(fileName, parentFile); 57 | // read out magic number 58 | uint32_t magic = file->readUint32(); 59 | 60 | // Universal magic is always BE 61 | if (file->getUint32BE(magic) == FAT_MAGIC) { 62 | // this is an universal file 63 | 64 | // get number of architecture headers (BE) 65 | uint32_t numberOfArchitectures = file->readUint32BE(); 66 | 67 | // read out all architecture headers 68 | fat_arch fatArch[numberOfArchitectures]; 69 | file->readBytes((char*)fatArch, sizeof(fat_arch)*numberOfArchitectures); 70 | 71 | // go through all architectures 72 | for (unsigned int n=0; n < numberOfArchitectures; n++) { 73 | unsigned int offset = file->getUint32BE(fatArch[n].offset); 74 | file->seek(offset); 75 | // read out magic number 76 | uint32_t magic = file->readUint32(); 77 | file->seek(offset); 78 | MachOArchitecture* architecture = new MachOArchitecture(*file, magic, file->getUint32BE(fatArch[n].size)); 79 | if (parent) 80 | architecture->initParentArchitecture(parent->getCompatibleArchitecture(architecture)); 81 | architectures.push_back(architecture); 82 | } 83 | } else { 84 | // seek back to beginning 85 | file->seek(0); 86 | MachOArchitecture* architecture = new MachOArchitecture(*file, magic, getSize()); 87 | if (parent) 88 | architecture->initParentArchitecture(parent->getCompatibleArchitecture(architecture)); 89 | architectures.push_back(architecture); 90 | } 91 | } 92 | 93 | 94 | MachO::~MachO() { 95 | referenceCounter--; 96 | if (referenceCounter == 0) { 97 | delete dynamicLoader; 98 | dynamicLoader = 0; 99 | } 100 | 101 | for (MachOArchitecturesIterator it = architectures.begin(); 102 | it != architectures.end(); 103 | ++it) 104 | { 105 | delete *it; 106 | } 107 | delete file; 108 | if (bundle) 109 | CFRelease(bundle); 110 | } 111 | 112 | // choose an architecture which is compatible to the given architecture 113 | MachOArchitecture* MachO::getCompatibleArchitecture(MachOArchitecture* destArchitecture) const { 114 | MachOHeader::CpuType destCpuType = destArchitecture->getHeader()->getCpuType(); 115 | 116 | // go through all architectures 117 | for (MachOArchitecturesConstIterator it = architectures.begin(); 118 | it != architectures.end(); 119 | ++it) 120 | { 121 | // TODO: match subtypes (only for PowerPC necessary) 122 | if ((*it)->getHeader()->getCpuType() == destCpuType) 123 | return *it; 124 | } 125 | return 0; 126 | } 127 | 128 | MachOArchitecture* MachO::getHostCompatibleArchitecture() const { 129 | 130 | unsigned int destCpuType = MachOHeader::getHostCpuType(); 131 | // go through all architectures 132 | for (MachOArchitecturesConstIterator it = architectures.begin(); 133 | it != architectures.end(); 134 | ++it) 135 | { 136 | // TODO: match subtypes (only for PowerPC necessary) 137 | if ((*it)->getHeader()->getCpuType() == destCpuType) 138 | return *it; 139 | } 140 | return 0; 141 | } 142 | 143 | unsigned long long MachO::getSize() const { 144 | return file->getSize(); 145 | } 146 | 147 | 148 | time_t MachO::getLastModificationTime() const { 149 | return file->getLastModificationTime(); 150 | } 151 | 152 | // return bundle version if available, otherwise NULL string 153 | std::string MachO::getVersion() const { 154 | std::string version; 155 | if (bundle != 0) { 156 | CFStringRef cfVersion = (CFStringRef)CFBundleGetValueForInfoDictionaryKey(bundle, kCFBundleVersionKey); 157 | // is version available at all? 158 | if (cfVersion) { 159 | version = extractStringFromCFStringRef(cfVersion); 160 | } 161 | } 162 | return version; 163 | } 164 | 165 | std::string MachO::getName() const { 166 | std::string name; 167 | if (bundle != 0) { 168 | CFStringRef cfBundleName = (CFStringRef)CFBundleGetValueForInfoDictionaryKey(bundle, kCFBundleNameKey); 169 | // is version available at all? 170 | if (cfBundleName) { 171 | name = extractStringFromCFStringRef(cfBundleName); 172 | } else { 173 | // take bundle executable name 174 | CFURLRef bundleUrl = CFBundleCopyExecutableURL(bundle); 175 | cfBundleName = CFURLCopyLastPathComponent(bundleUrl); 176 | name = extractStringFromCFStringRef(cfBundleName); 177 | CFRelease(cfBundleName); 178 | CFRelease(bundleUrl); 179 | 180 | } 181 | } else { 182 | name = file->getTitle(); 183 | } 184 | return name; 185 | } 186 | 187 | std::string MachO::extractStringFromCFStringRef(CFStringRef cfStringRef) { 188 | std::string string; 189 | const char* szString = CFStringGetCStringPtr(cfStringRef, kCFStringEncodingASCII); 190 | if (szString == NULL) { 191 | CFIndex stringLength = CFStringGetMaximumSizeForEncoding(CFStringGetLength(cfStringRef), kCFStringEncodingASCII); 192 | 193 | char szStringNew[stringLength + 1]; 194 | if (CFStringGetCString(cfStringRef, 195 | szStringNew, 196 | stringLength+1, 197 | kCFStringEncodingASCII 198 | )) 199 | string = szStringNew; 200 | delete[] szString; 201 | } else { 202 | string = szString; 203 | } 204 | return string; 205 | } 206 | 207 | std::string MachO::getFileName() const { 208 | std::string filename = file->getName(); 209 | return filename; 210 | } 211 | 212 | MachO::MachOArchitecturesIterator MachO::getArchitecturesBegin() { return architectures.begin(); } 213 | 214 | MachO::MachOArchitecturesIterator MachO::getArchitecturesEnd() { return architectures.end(); } 215 | -------------------------------------------------------------------------------- /MachO/macho.h: -------------------------------------------------------------------------------- 1 | #ifndef MACHO_H 2 | #define MACHO_H 3 | 4 | #include "macho_global.h" 5 | #include 6 | 7 | class MachOFile; 8 | class MachOArchitecture; 9 | class DynamicLoader; 10 | 11 | class EXPORT MachO { 12 | private: 13 | typedef std::list MachOArchitectures; 14 | public: 15 | MachO(const std::string& fileName, const MachO* parent = 0); 16 | ~MachO(); 17 | 18 | std::string getFileName() const; 19 | 20 | typedef MachOArchitectures::iterator MachOArchitecturesIterator; 21 | typedef MachOArchitectures::const_iterator MachOArchitecturesConstIterator; 22 | MachOArchitecturesIterator getArchitecturesBegin(); 23 | MachOArchitecturesIterator getArchitecturesEnd(); 24 | MachOArchitecture* getCompatibleArchitecture(MachOArchitecture* destArchitecture) const; 25 | MachOArchitecture* getHostCompatibleArchitecture() const; 26 | unsigned long long getSize() const; 27 | time_t getLastModificationTime() const; 28 | std::string getVersion() const; 29 | std::string getName() const; 30 | const MachO* getParent() { return parent;} 31 | static DynamicLoader* dynamicLoader; 32 | static int referenceCounter; 33 | private: 34 | const MachO* parent; 35 | MachOFile* file; 36 | MachOArchitectures architectures; 37 | CFBundleRef bundle; 38 | 39 | std::string getApplicationInBundle(const std::string& bundlePath); 40 | static std::string extractStringFromCFStringRef(CFStringRef cfStringRef); 41 | void init(const std::string& fileName, const MachO* parent); 42 | 43 | }; 44 | 45 | #endif // MACHO_H 46 | -------------------------------------------------------------------------------- /MachO/macho32header.cpp: -------------------------------------------------------------------------------- 1 | #include "macho32header.h" 2 | #include "machoexception.h" 3 | 4 | MachO32Header::MachO32Header(const MachOFile& file, bool reversedBO) : 5 | MachOHeader(file, reversedBO) 6 | { 7 | this->file.readBytes((char*)&header, sizeof(header)); 8 | } 9 | 10 | MachOHeader::CpuType MachO32Header::getCpuType() const { 11 | return MachOHeader::getCpuType(file.getUint32(header.cputype)); 12 | } 13 | 14 | unsigned int MachO32Header::getInternalFileType() const { 15 | return file.getUint32(header.filetype); 16 | } 17 | 18 | bool MachO32Header::is64Bit() const { 19 | return false; 20 | } 21 | 22 | unsigned int MachO32Header::getNumberOfLoadCommands() const { 23 | return file.getUint32(header.ncmds); 24 | } 25 | 26 | unsigned int MachO32Header::getLoadCommandSize() const { 27 | return file.getUint32(header.sizeofcmds);; 28 | } 29 | 30 | unsigned int MachO32Header::getSize() const { 31 | return sizeof(header); 32 | } 33 | -------------------------------------------------------------------------------- /MachO/macho32header.h: -------------------------------------------------------------------------------- 1 | #ifndef MACHO32HEADER_H 2 | #define MACHO32HEADER_H 3 | 4 | 5 | #include "machoheader.h" 6 | 7 | class MachO32Header : public MachOHeader 8 | { 9 | public: 10 | MachO32Header(const MachOFile& file, bool reversedBO); 11 | virtual unsigned int getNumberOfLoadCommands() const; 12 | virtual bool is64Bit() const; 13 | virtual unsigned int getLoadCommandSize() const; // size of load command following the header 14 | virtual unsigned int getSize() const; // size of header only 15 | virtual MachOHeader::CpuType getCpuType() const; 16 | protected: 17 | virtual unsigned int getInternalFileType() const; 18 | private: 19 | mach_header header; 20 | }; 21 | 22 | #endif // MACHO32HEADER_H 23 | -------------------------------------------------------------------------------- /MachO/macho64header.cpp: -------------------------------------------------------------------------------- 1 | #include "macho64header.h" 2 | #include "machoexception.h" 3 | 4 | MachO64Header::MachO64Header(const MachOFile& file, bool reversedBO) : 5 | MachOHeader(file, reversedBO) 6 | { 7 | 8 | this->file.readBytes((char*)&header, sizeof(header)); 9 | } 10 | 11 | MachOHeader::CpuType MachO64Header::getCpuType() const { 12 | return MachOHeader::getCpuType(file.getUint32(header.cputype)); 13 | } 14 | 15 | unsigned int MachO64Header::getInternalFileType() const { 16 | return file.getUint32(header.filetype); 17 | } 18 | 19 | bool MachO64Header::is64Bit() const { 20 | return true; 21 | } 22 | 23 | unsigned int MachO64Header::getNumberOfLoadCommands() const { 24 | return file.getUint32(header.ncmds); 25 | } 26 | 27 | unsigned int MachO64Header::getLoadCommandSize() const { 28 | return file.getUint32(header.sizeofcmds); 29 | } 30 | 31 | unsigned int MachO64Header::getSize() const { 32 | return sizeof(header); 33 | } 34 | -------------------------------------------------------------------------------- /MachO/macho64header.h: -------------------------------------------------------------------------------- 1 | #ifndef MACHO64HEADER_H 2 | #define MACHO64HEADER_H 3 | 4 | #include "machoheader.h" 5 | 6 | class MachO64Header : public MachOHeader 7 | { 8 | public: 9 | MachO64Header(const MachOFile& file, bool reversedBO); 10 | virtual unsigned int getNumberOfLoadCommands() const; 11 | virtual bool is64Bit() const; 12 | virtual unsigned int getLoadCommandSize() const; // size of load command following the header 13 | virtual unsigned int getSize() const; // size of header only 14 | virtual MachOHeader::CpuType getCpuType() const; 15 | protected: 16 | virtual unsigned int getInternalFileType() const; 17 | private: 18 | mach_header_64 header; 19 | }; 20 | 21 | #endif // MACHO64HEADER_H 22 | -------------------------------------------------------------------------------- /MachO/macho_global.h: -------------------------------------------------------------------------------- 1 | #ifndef MACHO_GLOBAL_H 2 | #define MACHO_GLOBAL_H 3 | 4 | // TODO: use visibility options http://developer.apple.com/mac/library/documentation/DeveloperTools/Conceptual/CppRuntimeEnv/Articles/SymbolVisibility.html 5 | 6 | #if defined(MACHO_LIBRARY) 7 | #define EXPORT 8 | #else 9 | #define EXPORT __attribute__((visibility("default"))) 10 | #endif 11 | 12 | #endif // MACHO_GLOBAL_H 13 | -------------------------------------------------------------------------------- /MachO/machoarchitecture.cpp: -------------------------------------------------------------------------------- 1 | #include "machoarchitecture.h" 2 | #include "machofile.h" 3 | #include "machoheader.h" 4 | #include "loadcommand.h" 5 | #include "dylibcommand.h" 6 | #include "machoexception.h" 7 | #include "rpathcommand.h" 8 | #include "uuidcommand.h" 9 | #include "dylinkercommand.h" 10 | #include "macho.h" 11 | #include "dynamicloader.h" 12 | 13 | 14 | MachOArchitecture::MachOArchitecture(MachOFile& file, uint32_t magic, unsigned int size) : 15 | header(MachOHeader::getHeader(file, magic)), file(header->getFile()), size(size), hasReadLoadCommands(false), parent(0), dynamicLibIdCommand(0), uuid(0) 16 | { 17 | } 18 | 19 | void MachOArchitecture::initParentArchitecture(const MachOArchitecture* parent) { 20 | this->parent = parent; 21 | } 22 | 23 | std::string MachOArchitecture::getResolvedName(const std::string& name, const std::string& workingPath) const { 24 | std::string absoluteFileName = MachO::dynamicLoader->getPathname(name, this, workingPath); 25 | if (!absoluteFileName.empty()) 26 | return absoluteFileName; 27 | // return unresolved name if it cannot be resolved to a valid absolute name 28 | return name; 29 | } 30 | 31 | std::vector MachOArchitecture::getRpaths(bool recursively) const { 32 | // try to get it from the parent (recursively) 33 | std::vector prevRpaths; 34 | if (recursively && parent) { 35 | prevRpaths = parent->getRpaths(recursively); 36 | } else { 37 | prevRpaths = std::vector(); 38 | } 39 | // add own rpaths to the end 40 | prevRpaths.insert(prevRpaths.end(), rpaths.begin(), rpaths.end()); 41 | return prevRpaths; 42 | } 43 | 44 | void MachOArchitecture::readLoadCommands() const { 45 | // read out number of commands 46 | unsigned int numberOfCommands = header->getNumberOfLoadCommands(); 47 | // read out command identifiers 48 | for (unsigned int n=0; n(loadCommand); 57 | if (dylibCommand != 0 && dylibCommand->isId()) { 58 | dynamicLibIdCommand = dylibCommand; 59 | } 60 | 61 | // for rpath command... 62 | RpathCommand* rpathCommand = dynamic_cast(loadCommand); 63 | if (rpathCommand != 0) { 64 | // try to replace placeholder 65 | std::string resolvedRpath = MachO::dynamicLoader->replacePlaceholder(rpathCommand->getPath(), this); 66 | if (resolvedRpath.empty()) { 67 | resolvedRpath = rpathCommand->getPath(); 68 | } 69 | rpaths.push_back(new std::string(resolvedRpath)); 70 | } 71 | 72 | // for uuid command... 73 | UuidCommand* uuidCommand = dynamic_cast(loadCommand); 74 | if (uuidCommand != 0) { 75 | uuid = uuidCommand->getUuid(); 76 | } 77 | 78 | // for dylinker command 79 | DylinkerCommand* dylinkerCommand = dynamic_cast(loadCommand); 80 | if (dylinkerCommand != 0) { 81 | dylinker = dylinkerCommand->getName(); 82 | } 83 | 84 | loadCommands.push_back(loadCommand); 85 | file.seek(commandOffset + loadCommand->getSize()); 86 | } 87 | hasReadLoadCommands = true; 88 | } 89 | 90 | MachOArchitecture::~MachOArchitecture() { 91 | delete header; 92 | 93 | for (LoadCommandsIterator it = loadCommands.begin(); 94 | it != loadCommands.end(); 95 | ++it) 96 | { 97 | delete *it; 98 | } 99 | 100 | for (std::vector::iterator it2 = rpaths.begin(); 101 | it2 != rpaths.end(); 102 | ++it2) 103 | { 104 | delete *it2; 105 | } 106 | } 107 | 108 | unsigned int MachOArchitecture::getSize() const { 109 | return size; 110 | } 111 | 112 | const uint8_t* MachOArchitecture::getUuid() const { 113 | return uuid; 114 | } 115 | 116 | 117 | 118 | -------------------------------------------------------------------------------- /MachO/machoarchitecture.h: -------------------------------------------------------------------------------- 1 | #ifndef MACHOARCHITECTURE_H 2 | #define MACHOARCHITECTURE_H 3 | 4 | #include "macho_global.h" 5 | 6 | class MachOFile; 7 | class MachOHeader; 8 | class LoadCommand; 9 | class DylibCommand; 10 | 11 | class EXPORT MachOArchitecture 12 | { 13 | private: 14 | typedef std::list LoadCommands; 15 | typedef LoadCommands::iterator LoadCommandsIterator; 16 | public: 17 | typedef LoadCommands::const_iterator LoadCommandsConstIterator; 18 | 19 | MachOArchitecture(MachOFile& file, uint32_t magic, unsigned int size); 20 | ~MachOArchitecture(); 21 | 22 | const MachOHeader* getHeader() { return header; } 23 | LoadCommandsConstIterator getLoadCommandsBegin() const { if(!hasReadLoadCommands) { readLoadCommands(); } return loadCommands.begin(); } 24 | LoadCommandsConstIterator getLoadCommandsEnd() const { if(!hasReadLoadCommands) { readLoadCommands(); } return loadCommands.end(); } 25 | DylibCommand* getDynamicLibIdCommand() const { if(!hasReadLoadCommands) { readLoadCommands(); } return dynamicLibIdCommand; } 26 | unsigned int getSize() const; 27 | void initParentArchitecture(const MachOArchitecture* parent); 28 | const MachOFile* getFile() const { return &file; } 29 | std::string getDynamicLinker() const { return dylinker; } 30 | std::vector getRpaths(bool recursively = true) const; 31 | std::string getResolvedName(const std::string& name, const std::string& workingPath) const; 32 | const uint8_t* getUuid() const; 33 | 34 | private: 35 | MachOHeader* header; 36 | MachOFile& file; 37 | const unsigned int size; 38 | mutable bool hasReadLoadCommands; 39 | void readLoadCommands() const; 40 | const MachOArchitecture* parent; // architecture from which this architecture was loaded 41 | 42 | // all those are mutable, because they are initialized not in the constructor, but in the readLoadCommands method 43 | mutable LoadCommands loadCommands; 44 | mutable DylibCommand* dynamicLibIdCommand; 45 | mutable std::vector rpaths; 46 | mutable const uint8_t* uuid; 47 | mutable std::string dylinker; 48 | }; 49 | 50 | #endif // MACHOARCHITECTURE_H 51 | -------------------------------------------------------------------------------- /MachO/machocache.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * machocache.cpp 3 | * MachO 4 | * 5 | * Created by Konrad Windszus on 13.07.09. 6 | * Copyright 2009 __MyCompanyName__. All rights reserved. 7 | * 8 | */ 9 | 10 | #include "machocache.h" 11 | #include "macho.h" 12 | 13 | MachOCache::MachOCache() { 14 | 15 | } 16 | 17 | MachOCache::~MachOCache() { 18 | // remove all cache entries 19 | for (CacheMapIterator it = cache.begin(); it != cache.end(); it++) { 20 | delete it->second; 21 | } 22 | } 23 | 24 | MachO* MachOCache::getFile(const std::string& filename, const MachO* parent) { 25 | CacheMapIterator it = cache.find(filename); 26 | 27 | // check if already in cache? 28 | if (it == cache.end()) { 29 | MachO* file = new MachO(filename, parent); 30 | cache[filename] = file; 31 | return file; 32 | } 33 | else { 34 | return it->second; 35 | } 36 | } 37 | 38 | unsigned int MachOCache::getNumEntries() { 39 | return cache.size(); 40 | } 41 | -------------------------------------------------------------------------------- /MachO/machocache.h: -------------------------------------------------------------------------------- 1 | #ifndef MACHOCACHE_H 2 | #define MACHOCACHE_H 3 | 4 | #include "macho_global.h" 5 | 6 | class MachO; 7 | class EXPORT MachOCache 8 | { 9 | public: 10 | MachOCache(); 11 | ~MachOCache(); 12 | MachO* getFile(const std::string& filename, const MachO* parent); 13 | unsigned int getNumEntries(); 14 | private: 15 | typedef std::map CacheMap; 16 | typedef CacheMap::iterator CacheMapIterator; 17 | CacheMap cache; 18 | }; 19 | 20 | #endif // MACHOCACHE_H 21 | -------------------------------------------------------------------------------- /MachO/machodemangleexception.cpp: -------------------------------------------------------------------------------- 1 | #include "machodemangleexception.h" 2 | 3 | MachODemangleException::MachODemangleException(const std::string& cause) : 4 | MachOException(cause) 5 | { 6 | } 7 | -------------------------------------------------------------------------------- /MachO/machodemangleexception.h: -------------------------------------------------------------------------------- 1 | #ifndef MACHODEMANGLEEXCEPTION_H 2 | #define MACHODEMANGLEEXCEPTION_H 3 | 4 | #include "macho_global.h" 5 | #include "machoexception.h" 6 | 7 | 8 | class EXPORT MachODemangleException : public MachOException 9 | { 10 | 11 | public: 12 | MachODemangleException(const std::string&); 13 | }; 14 | 15 | #endif // MACHODEMANGLEEXCEPTION_H 16 | 17 | 18 | -------------------------------------------------------------------------------- /MachO/machoexception.cpp: -------------------------------------------------------------------------------- 1 | #include "machoexception.h" 2 | 3 | MachOException::MachOException(const std::string& cause) : cause(cause) 4 | { 5 | } 6 | 7 | -------------------------------------------------------------------------------- /MachO/machoexception.h: -------------------------------------------------------------------------------- 1 | #ifndef MACHOEXCEPTION_H 2 | #define MACHOEXCEPTION_H 3 | 4 | #include "macho_global.h" 5 | 6 | class EXPORT MachOException 7 | { 8 | public: 9 | MachOException(const std::string&); 10 | const std::string& getCause() { return cause; } 11 | private: 12 | const std::string cause; 13 | }; 14 | 15 | #endif // MACHOEXCEPTION_H 16 | -------------------------------------------------------------------------------- /MachO/machofile.cpp: -------------------------------------------------------------------------------- 1 | #include "machofile.h" 2 | #include "machoexception.h" 3 | #include "internalfile.h" 4 | 5 | MachOFile::MachOFile(const std::string& filename,const MachOFile* parent, bool reversedByteOrder) : 6 | file(InternalFile::create(filename)), position(0), reversedByteOrder(reversedByteOrder), parent(parent) 7 | { 8 | if (parent) { 9 | executablePath = parent->executablePath; 10 | } else { 11 | executablePath = getDirectory(); 12 | } 13 | } 14 | 15 | MachOFile::MachOFile(const MachOFile& file, bool reversedByteOrder) : 16 | file(InternalFile::create(file.file)), position(file.position), reversedByteOrder(reversedByteOrder), parent(file.parent), executablePath(file.executablePath) 17 | { 18 | } 19 | 20 | MachOFile::~MachOFile() { 21 | file->release(); 22 | } 23 | 24 | std::string MachOFile::getName() const { 25 | std::string filename = file->getName(); 26 | return filename; 27 | } 28 | 29 | std::string MachOFile::getDirectory() const { 30 | size_t found = file->getName().find_last_of("/"); 31 | return(file->getName().substr(0, found)); 32 | } 33 | 34 | std::string MachOFile::getTitle() const { return file->getTitle(); } 35 | unsigned long long MachOFile::getSize() const { return file->getSize(); } 36 | time_t MachOFile::getLastModificationTime() const { return file->getLastModificationTime(); } 37 | 38 | uint32_t MachOFile::readUint32() { 39 | unsigned int temp; 40 | readBytes((char*)&temp, sizeof(temp)); 41 | return getUint32(temp); 42 | } 43 | 44 | uint32_t MachOFile::readUint32LE() { 45 | unsigned int temp; 46 | readBytes((char*)&temp, sizeof(temp)); 47 | return getUint32LE(temp); 48 | } 49 | 50 | uint32_t MachOFile::readUint32BE() { 51 | unsigned int temp; 52 | readBytes((char*)&temp, sizeof(temp)); 53 | return getUint32BE(temp); 54 | } 55 | 56 | uint32_t MachOFile::getUint32BE(uint32_t data) { 57 | return convertByteOrder((char*)&data, true, sizeof(data)); 58 | } 59 | 60 | uint32_t MachOFile::getUint32LE(uint32_t data) { 61 | return convertByteOrder((char*)&data, false, sizeof(data)); 62 | } 63 | 64 | void MachOFile::readBytes(char* result, size_t size) { 65 | if (file->getPosition() != position) { 66 | file->seek(position); 67 | } 68 | if (file->read(result, size) != size) 69 | throw MachOException("File '" + file->getName() + "' not big enough. Probably no valid Mach-O!"); 70 | position += size; 71 | } 72 | 73 | // convert from big endian or little endian to native format (Intel=little endian) and return as unsigned int (32bit) 74 | unsigned int MachOFile::convertByteOrder(char* data, bool isBigEndian, unsigned int numberOfBytes) { 75 | 76 | assert(numberOfBytes> 0); 77 | assert(numberOfBytes <= 4); // max 4 byte 78 | 79 | unsigned int result = 0; 80 | 81 | // big endian extract (most significant byte first) (will work on little and big-endian computers) 82 | unsigned int numberOfShifts = isBigEndian ? numberOfBytes - 1 : 0; 83 | 84 | for (unsigned int n = 0; n < numberOfBytes; n++) { 85 | result |= static_cast(data[n]) << (8 * numberOfShifts); // the bit shift will do the correct byte order for you 86 | numberOfShifts += isBigEndian ? -1 : +1; 87 | } 88 | return result; 89 | } 90 | 91 | uint32_t MachOFile::reverseByteOrder(uint32_t data) { 92 | char* sourceData = (char*)&data; 93 | uint32_t result; 94 | char* destData = (char*)&result; 95 | 96 | destData[3] = sourceData[0]; 97 | destData[2] = sourceData[1]; 98 | destData[1] = sourceData[2]; 99 | destData[0] = sourceData[3]; 100 | 101 | return result; 102 | } 103 | 104 | 105 | -------------------------------------------------------------------------------- /MachO/machofile.h: -------------------------------------------------------------------------------- 1 | #ifndef MACHOFILE_H 2 | #define MACHOFILE_H 3 | 4 | #include "macho_global.h" 5 | 6 | class InternalFile; 7 | class MachOFile 8 | { 9 | public: 10 | MachOFile(const std::string& filename, const MachOFile* parent, bool reversedByteOrder = false); 11 | MachOFile(const MachOFile& file, bool reversedByteOrder); 12 | ~MachOFile(); 13 | 14 | uint32_t readUint32(); 15 | uint32_t readUint32LE(); 16 | uint32_t readUint32BE(); 17 | 18 | void readBytes(char* result, size_t size); 19 | 20 | uint32_t getUint32(unsigned int data) const {return (reversedByteOrder?reverseByteOrder(data):data);} 21 | static uint32_t getUint32LE(uint32_t data); 22 | static uint32_t getUint32BE(uint32_t data); 23 | std::string getDirectory() const; 24 | std::string getName() const; 25 | std::string getTitle() const; 26 | unsigned long long getSize() const; 27 | void seek(long long int offset) { position = offset; } 28 | long long int getPosition() const { return position; } 29 | const std::string& getExecutablePath() const { return executablePath; } 30 | time_t getLastModificationTime() const; 31 | 32 | private: 33 | static unsigned int convertByteOrder(char* data, bool isBigEndian, unsigned int numberOfBytes); 34 | static unsigned int reverseByteOrder(unsigned int data); 35 | 36 | InternalFile* file; 37 | long long int position; 38 | const bool reversedByteOrder; 39 | const MachOFile* parent; 40 | std::string executablePath; 41 | 42 | }; 43 | 44 | #endif // MACHOFILE_H 45 | -------------------------------------------------------------------------------- /MachO/machoheader.cpp: -------------------------------------------------------------------------------- 1 | #include "machoheader.h" 2 | #include "machofile.h" 3 | #include "macho32header.h" 4 | #include "macho64header.h" 5 | #include "machoexception.h" 6 | #include 7 | 8 | MachOHeader* MachOHeader::getHeader(MachOFile& file, uint32_t magic) { 9 | MachOHeader* header; 10 | switch (magic) { 11 | case MH_MAGIC: 12 | header = new MachO32Header(file, false); 13 | break; 14 | case MH_CIGAM: 15 | header = new MachO32Header(file, true); 16 | break; 17 | case MH_MAGIC_64: 18 | header = new MachO64Header(file, false); 19 | break; 20 | case MH_CIGAM_64: 21 | header = new MachO64Header(file, true); 22 | break; 23 | default: 24 | throw MachOException("Invalid magic number. No Mach-O file."); 25 | } 26 | return header; 27 | } 28 | 29 | // for every header create a new filehandler with correct byte order 30 | MachOHeader::MachOHeader(const MachOFile& file, bool reversedBO) : 31 | file(file, reversedBO), offset(this->file.getPosition()) 32 | { 33 | } 34 | 35 | MachOHeader::~MachOHeader() { 36 | 37 | } 38 | 39 | // taken over from dyld.cpp (V 97.1) 40 | MachOHeader::CpuType MachOHeader::getHostCpuType() { 41 | struct host_basic_info info; 42 | mach_msg_type_number_t count = HOST_BASIC_INFO_COUNT; 43 | mach_port_t hostPort = mach_host_self(); 44 | kern_return_t result = host_info(hostPort, HOST_BASIC_INFO, (host_info_t)&info, &count); 45 | mach_port_deallocate(mach_task_self(), hostPort); 46 | if (result != KERN_SUCCESS) 47 | throw "host_info() failed"; 48 | //sHostCPUsubtype = info.cpu_subtype; 49 | return getCpuType(info.cpu_type); 50 | } 51 | 52 | MachOHeader::CpuType MachOHeader::getCpuType(unsigned int cpu) { 53 | MachOHeader::CpuType cpuType; 54 | switch(cpu) { 55 | case CPU_TYPE_POWERPC: 56 | cpuType = MachOHeader::CpuTypePowerPc; 57 | break; 58 | case CPU_TYPE_I386: 59 | cpuType = MachOHeader::CpuTypeI386; 60 | break; 61 | case CPU_TYPE_POWERPC64: 62 | cpuType = MachOHeader::CpuTypePowerPc64; 63 | break; 64 | case CPU_TYPE_X86_64: 65 | cpuType = MachOHeader::CpuTypeX8664; 66 | break; 67 | case CPU_TYPE_ARM: 68 | cpuType = MachOHeader::CpuTypeArm; 69 | break; 70 | case CPU_TYPE_ARM64: 71 | cpuType = MachOHeader::CpuTypeArm64; 72 | break; 73 | case CPU_TYPE_ARM64_32: 74 | cpuType = MachOHeader::CpuTypeArm6432; 75 | break; 76 | default: 77 | cpuType = MachOHeader::CpuTypeOther; 78 | } 79 | return cpuType; 80 | } 81 | 82 | MachOHeader::FileType MachOHeader::getFileType() const { 83 | unsigned int fileType = getInternalFileType(); 84 | if (fileType > NumFileTypes || fileType < 1) { 85 | return NumFileTypes; 86 | } 87 | return static_cast(fileType-1); 88 | } 89 | -------------------------------------------------------------------------------- /MachO/machoheader.h: -------------------------------------------------------------------------------- 1 | #ifndef MACHOHEADER_H 2 | #define MACHOHEADER_H 3 | 4 | #include "macho_global.h" 5 | #include "machofile.h" 6 | 7 | class EXPORT MachOHeader 8 | { 9 | public: 10 | static MachOHeader* getHeader(MachOFile& file, uint32_t magic); 11 | virtual ~MachOHeader(); 12 | 13 | enum CpuType { 14 | CpuTypePowerPc, 15 | CpuTypeI386, 16 | CpuTypePowerPc64, 17 | CpuTypeX8664, 18 | CpuTypeArm, 19 | CpuTypeArm64, 20 | CpuTypeArm6432, 21 | CpuTypeOther, 22 | NumCpuTypes 23 | }; 24 | 25 | enum FileType { 26 | 27 | FileTypeObject, /* relocatable object file */ 28 | FileTypeExecutable, /* demand paged executable file */ 29 | FileTypeVmLib, /* fixed VM shared library file */ 30 | FileTypeCore, /* core file */ 31 | FileTypePreload, /* preloaded executable file */ 32 | FileTypeDylib, /* dynamically bound shared library */ 33 | FileTypeDylinker, /* dynamic link editor */ 34 | FileTypeBundle, /* dynamically bound bundle file */ 35 | FileTypeDylibStub, /* shared library stub for static linking only, no section contents */ 36 | FileTypeDsym, /* companion file with only debug sections */ 37 | FileTypeKextBundle, /* x86 64 kext bundle */ 38 | NumFileTypes /* stands also for unknown types */ 39 | }; 40 | FileType getFileType() const; 41 | virtual CpuType getCpuType() const = 0; 42 | static CpuType getHostCpuType(); 43 | static CpuType getCpuType(unsigned int internalCpuType); 44 | virtual unsigned int getNumberOfLoadCommands() const = 0; 45 | virtual bool is64Bit() const = 0; 46 | MachOFile& getFile() { return file;} 47 | unsigned int getOffset() const { return offset; } 48 | virtual unsigned int getLoadCommandSize() const = 0; // size of load command following the header 49 | virtual unsigned int getSize() const = 0; // size of header only 50 | 51 | protected: 52 | MachOHeader(const MachOFile& file, bool reversedBO); 53 | MachOFile file; 54 | const unsigned int offset; 55 | virtual unsigned int getInternalFileType() const = 0; 56 | }; 57 | 58 | #endif // MACHOHEADER_H 59 | -------------------------------------------------------------------------------- /MachO/rpathcommand.cpp: -------------------------------------------------------------------------------- 1 | #include "rpathcommand.h" 2 | #include "machofile.h" 3 | #include "machoheader.h" 4 | 5 | RpathCommand::RpathCommand(MachOHeader* header) : 6 | LoadCommand(header) 7 | { 8 | file.readBytes((char*)&command, sizeof(command)); 9 | } 10 | 11 | RpathCommand::~RpathCommand() { 12 | } 13 | 14 | unsigned int RpathCommand::getSize() const { 15 | return file.getUint32(command.cmdsize); 16 | } 17 | 18 | const char* RpathCommand::getPath() const { 19 | return getLcDataString(command.path.offset); 20 | } 21 | -------------------------------------------------------------------------------- /MachO/rpathcommand.h: -------------------------------------------------------------------------------- 1 | #ifndef RPATHCOMMAND_H 2 | #define RPATHCOMMAND_H 3 | 4 | #include "macho_global.h" 5 | #include "loadcommand.h" 6 | 7 | class EXPORT RpathCommand : public LoadCommand 8 | { 9 | public: 10 | RpathCommand(MachOHeader* header); 11 | virtual ~RpathCommand(); 12 | 13 | virtual unsigned int getSize() const; 14 | virtual unsigned int getStructureSize() const { return sizeof(command); } 15 | const char* getPath() const; 16 | private: 17 | rpath_command command; 18 | }; 19 | 20 | #endif // RPATHCOMMAND_H 21 | -------------------------------------------------------------------------------- /MachO/symboltablecommand.cpp: -------------------------------------------------------------------------------- 1 | #include "symboltablecommand.h" 2 | #include "symboltableentry.h" 3 | #include "symboltableentry32.h" 4 | #include "symboltableentry64.h" 5 | #include "machofile.h" 6 | #include "machoheader.h" 7 | 8 | SymbolTableCommand::SymbolTableCommand(MachOHeader* header) : 9 | LoadCommand(header), symbols32(0), symbols64(0), stringTable(0) 10 | { 11 | file.readBytes((char*)&command, sizeof(command)); 12 | // delay loading symbol table 13 | } 14 | 15 | void SymbolTableCommand::readSymbolTable() const { 16 | unsigned int stringTableLength = file.getUint32(command.strsize); 17 | stringTable = new char[stringTableLength]; 18 | 19 | // offset relative to beginning of architecture 20 | file.seek(header->getOffset() + file.getUint32(command.stroff)); 21 | file.readBytes(stringTable, file.getUint32(command.strsize)); 22 | 23 | unsigned int numberOfSymbols = file.getUint32(command.nsyms); 24 | // offset relative to beginning of architecture 25 | if (header->is64Bit()) { 26 | symbols64 = new struct nlist_64[numberOfSymbols]; 27 | file.seek(header->getOffset() + file.getUint32(command.symoff)); 28 | file.readBytes((char*)symbols64, sizeof(*symbols64) * numberOfSymbols); 29 | for (unsigned int n = 0; n < numberOfSymbols; n++) { 30 | SymbolTableEntry* entry = new SymbolTableEntry64(file, &symbols64[n], stringTable); 31 | symbolTableEntries.push_back(entry); 32 | } 33 | } else { 34 | symbols32 = new struct nlist[numberOfSymbols]; 35 | file.seek(header->getOffset() + file.getUint32(command.symoff)); 36 | file.readBytes((char*)symbols32, sizeof(*symbols32) * numberOfSymbols); 37 | for (unsigned int n = 0; n < numberOfSymbols; n++) { 38 | SymbolTableEntry* entry = new SymbolTableEntry32(file, &symbols32[n], stringTable); 39 | symbolTableEntries.push_back(entry); 40 | } 41 | } 42 | } 43 | 44 | SymbolTableCommand::~SymbolTableCommand() 45 | { 46 | for (SymbolTableEntriesIterator it = symbolTableEntries.begin(); 47 | it != symbolTableEntries.end(); 48 | ++it) 49 | { 50 | delete *it; 51 | } 52 | delete[] symbols32; 53 | delete[] symbols64; 54 | delete[] stringTable; 55 | } 56 | 57 | unsigned int SymbolTableCommand::getSize() const { 58 | return file.getUint32(command.cmdsize); 59 | } 60 | 61 | SymbolTableCommand::SymbolTableEntriesConstIterator SymbolTableCommand::getSymbolTableEntryBegin() const { 62 | if (stringTable == 0) 63 | readSymbolTable(); 64 | return symbolTableEntries.begin(); 65 | } 66 | 67 | SymbolTableCommand::SymbolTableEntriesConstIterator SymbolTableCommand::getSymbolTableEntryEnd() const { 68 | if (stringTable == 0) 69 | readSymbolTable(); 70 | return symbolTableEntries.end(); 71 | } 72 | 73 | /* 74 | const std::vector* SymbolTableCommand::getSymbolTableEntries() const { 75 | if (stringTable == 0) 76 | readSymbolTable(); 77 | return &symbolTableEntries; 78 | }*/ 79 | 80 | -------------------------------------------------------------------------------- /MachO/symboltablecommand.h: -------------------------------------------------------------------------------- 1 | #ifndef SYMBOLTABLECOMMAND_H 2 | #define SYMBOLTABLECOMMAND_H 3 | 4 | #include "loadcommand.h" 5 | 6 | class SymbolTableEntry; 7 | class EXPORT SymbolTableCommand : public LoadCommand 8 | { 9 | private: 10 | typedef std::list SymbolTableEntries; 11 | typedef SymbolTableEntries::iterator SymbolTableEntriesIterator; 12 | public: 13 | typedef SymbolTableEntries::const_iterator SymbolTableEntriesConstIterator; 14 | 15 | SymbolTableCommand(MachOHeader* header); 16 | virtual ~SymbolTableCommand(); 17 | virtual unsigned int getSize() const; 18 | 19 | SymbolTableEntriesConstIterator getSymbolTableEntryBegin() const; 20 | SymbolTableEntriesConstIterator getSymbolTableEntryEnd() const; 21 | //const std::vector* getSymbolTableEntries() const; 22 | private: 23 | symtab_command command; 24 | mutable struct nlist* symbols32; 25 | mutable struct nlist_64* symbols64; 26 | mutable char* stringTable; 27 | mutable SymbolTableEntries symbolTableEntries; 28 | 29 | void readSymbolTable() const; 30 | }; 31 | 32 | #endif // SYMBOLTABLECOMMAND_H 33 | -------------------------------------------------------------------------------- /MachO/symboltableentry.cpp: -------------------------------------------------------------------------------- 1 | #include "symboltableentry.h" 2 | #include "macho.h" 3 | #include "machofile.h" 4 | 5 | SymbolTableEntry::SymbolTableEntry(MachOFile& file, char* stringTable) 6 | : file(file), stringTable(stringTable) 7 | { 8 | } 9 | 10 | SymbolTableEntry::~SymbolTableEntry() { 11 | 12 | } 13 | 14 | std::string SymbolTableEntry::getName(bool shouldDemangle) const { 15 | const char *name = getInternalName(); 16 | std::string result = name; 17 | if (shouldDemangle) { 18 | int status = 0; 19 | 20 | // Convert real name to readable string. +1 to skip the leading underscore. 21 | char *realName = abi::__cxa_demangle(name + 1, nullptr, nullptr, &status); 22 | if (realName != nullptr) 23 | result = realName; 24 | free(realName); 25 | } 26 | return result; 27 | } 28 | 29 | SymbolTableEntry::Type SymbolTableEntry::getType() const { 30 | unsigned int type = getInternalType(); 31 | 32 | if (type & N_STAB) { 33 | return TypeDebug; 34 | } 35 | if (type & N_PEXT) { 36 | return TypePrivateExtern; 37 | } 38 | if (type & N_EXT) { 39 | if ((type & N_TYPE) == N_UNDF) 40 | return TypeImported; 41 | else 42 | return TypeExported; 43 | } 44 | else 45 | return TypeLocal; 46 | } 47 | -------------------------------------------------------------------------------- /MachO/symboltableentry.h: -------------------------------------------------------------------------------- 1 | #ifndef SYMBOLTABLEENTRY_H 2 | #define SYMBOLTABLEENTRY_H 3 | 4 | #include "macho_global.h" 5 | #include 6 | class MachOFile; 7 | 8 | class EXPORT SymbolTableEntry 9 | { 10 | public: 11 | SymbolTableEntry(MachOFile& file, char* stringTable); 12 | virtual ~SymbolTableEntry(); 13 | std::string getName(bool shouldDemangle) const; 14 | 15 | enum Type { 16 | TypeExported = 0, 17 | TypeImported, 18 | TypeLocal, 19 | TypeDebug, 20 | TypePrivateExtern, 21 | NumTypes 22 | }; 23 | 24 | Type getType() const; 25 | virtual unsigned int getInternalType() const = 0; 26 | virtual const char* getInternalName() const = 0; 27 | 28 | protected: 29 | MachOFile& file; 30 | char* stringTable; 31 | }; 32 | 33 | #endif // SYMBOLTABLEENTRY_H 34 | -------------------------------------------------------------------------------- /MachO/symboltableentry32.cpp: -------------------------------------------------------------------------------- 1 | #include "symboltableentry32.h" 2 | #include "machofile.h" 3 | 4 | SymbolTableEntry32::SymbolTableEntry32(MachOFile& file, struct nlist* entry, char* stringTable) : 5 | SymbolTableEntry(file, stringTable), entry(entry) 6 | { 7 | } 8 | 9 | const char* SymbolTableEntry32::getInternalName() const { 10 | return &stringTable[file.getUint32(entry->n_un.n_strx)]; 11 | } 12 | 13 | unsigned int SymbolTableEntry32::getInternalType() const { 14 | return entry->n_type; 15 | } 16 | 17 | 18 | -------------------------------------------------------------------------------- /MachO/symboltableentry32.h: -------------------------------------------------------------------------------- 1 | #ifndef SYMBOLTABLEENTRY32_H 2 | #define SYMBOLTABLEENTRY32_H 3 | 4 | #include "symboltableentry.h" 5 | 6 | class SymbolTableEntry32 : public SymbolTableEntry 7 | { 8 | public: 9 | SymbolTableEntry32(MachOFile& file, struct nlist* entry, char* stringTable); 10 | virtual const char* getInternalName() const; 11 | virtual unsigned int getInternalType() const; 12 | private: 13 | struct nlist* entry; 14 | }; 15 | 16 | 17 | #endif // SYMBOLTABLEENTRY32_H 18 | -------------------------------------------------------------------------------- /MachO/symboltableentry64.cpp: -------------------------------------------------------------------------------- 1 | #include "symboltableentry64.h" 2 | #include "machofile.h" 3 | 4 | SymbolTableEntry64::SymbolTableEntry64(MachOFile& file, struct nlist_64* entry, char* stringTable) : 5 | SymbolTableEntry(file, stringTable), entry(entry) 6 | { 7 | } 8 | 9 | const char* SymbolTableEntry64::getInternalName() const { 10 | return &stringTable[file.getUint32(entry->n_un.n_strx)]; 11 | } 12 | 13 | unsigned int SymbolTableEntry64::getInternalType() const { 14 | return entry->n_type; 15 | } 16 | 17 | -------------------------------------------------------------------------------- /MachO/symboltableentry64.h: -------------------------------------------------------------------------------- 1 | #ifndef SYMBOLTABLEENTRY64_H 2 | #define SYMBOLTABLEENTRY64_H 3 | 4 | #include "symboltableentry.h" 5 | 6 | class SymbolTableEntry64 : public SymbolTableEntry 7 | { 8 | public: 9 | SymbolTableEntry64(MachOFile& file, struct nlist_64* entry, char* stringTable); 10 | virtual const char* getInternalName() const; 11 | virtual unsigned int getInternalType() const; 12 | private: 13 | struct nlist_64* entry; 14 | }; 15 | 16 | #endif // SYMBOLTABLEENTRY64_H 17 | -------------------------------------------------------------------------------- /MachO/uuidcommand.cpp: -------------------------------------------------------------------------------- 1 | #include "uuidcommand.h" 2 | #include "machofile.h" 3 | #include "machoheader.h" 4 | #include 5 | 6 | UuidCommand::UuidCommand(MachOHeader* header) : 7 | LoadCommand(header) 8 | { 9 | file.readBytes((char*)&command, sizeof(command)); 10 | } 11 | 12 | UuidCommand::~UuidCommand() { 13 | } 14 | 15 | unsigned int UuidCommand::getSize() const { 16 | return file.getUint32(command.cmdsize); 17 | } 18 | 19 | const uint8_t* UuidCommand::getUuid() const { 20 | return command.uuid; 21 | } 22 | 23 | -------------------------------------------------------------------------------- /MachO/uuidcommand.h: -------------------------------------------------------------------------------- 1 | #ifndef UUIDCOMMAND_H 2 | #define UUIDCOMMAND_H 3 | 4 | #include "macho_global.h" 5 | #include "loadcommand.h" 6 | class EXPORT UuidCommand : public LoadCommand 7 | { 8 | public: 9 | UuidCommand(MachOHeader* header); 10 | virtual ~UuidCommand(); 11 | virtual unsigned int getSize() const; 12 | virtual unsigned int getStructureSize() const { return sizeof(command); } 13 | const uint8_t* getUuid() const; 14 | 15 | private: 16 | uuid_command command; 17 | 18 | }; 19 | 20 | #endif // UUIDCOMMAND_H 21 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | [![License](https://img.shields.io/github/license/kwin/macdependency)](https://www.gnu.org/licenses/gpl-3.0.en.html) 2 | [![Build Status](https://github.com/kwin/macdependency/actions/workflows/build.yml/badge.svg)](https://github.com/kwin/macdependency/actions/workflows/maven.yml) 3 | 4 | MacDependency shows all dependent libraries and frameworks of a given executable, dynamic library or framework on Mac OS X. It is a GUI replacement for the otool command, and provides almost the same functionality as the Dependency Walker (http://www.dependencywalker.com) on Windows. 5 | 6 | More information available in the [Wiki](../../wiki). 7 | 8 | ![Screenshot](images/macdependency.png) 9 | -------------------------------------------------------------------------------- /images/macdependency.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kwin/macdependency/1cf589d0ccceb9c90ee94b3ad3a79e67a66e5e38/images/macdependency.png --------------------------------------------------------------------------------