mirror of
https://github.com/QuasarApp/macdependency.git
synced 2025-04-27 21:04:31 +00:00
252 lines
7.9 KiB
Plaintext
252 lines
7.9 KiB
Plaintext
//
|
|
// ArchitectureModel.m
|
|
// MacDependency
|
|
//
|
|
// Created by Konrad Windszus on 22.08.09.
|
|
// Copyright 2009 Konrad Windszus. All rights reserved.
|
|
//
|
|
|
|
#import "ArchitectureModel.h"
|
|
#import "VersionFormatter.h"
|
|
#import "ConversionStdString.h"
|
|
|
|
#include "MachO/machoexception.h"
|
|
#include "MachO/symboltablecommand.h"
|
|
|
|
#import "SymbolTableEntryModel.h"
|
|
#import "MyDocument.h"
|
|
|
|
// declare private methods
|
|
@interface ArchitectureModel ()
|
|
- (void) initSymbols;
|
|
@end
|
|
|
|
|
|
@implementation ArchitectureModel
|
|
|
|
- (id) initWithArchitecture:(MachOArchitecture*)anArchitecture file:(MachO*)aFile document:(MyDocument*)aDocument isRoot:(BOOL)isRoot{
|
|
architecture = anArchitecture;
|
|
file = aFile;
|
|
document = aDocument;
|
|
symbolEntries = nil;
|
|
|
|
// create model with the current architecture selected (create from existing model)
|
|
if (isRoot) {
|
|
machOModel = nil;
|
|
} else {
|
|
machOModel = [[MachOModel alloc]initWithFile:aFile document:aDocument architecture:anArchitecture loadChildren:NO];
|
|
}
|
|
|
|
return self;
|
|
}
|
|
|
|
|
|
- (NSArray*) rootModel {
|
|
// always reload model (for error messages)
|
|
machOModel = [[MachOModel alloc]initWithFile:file document:document architecture:architecture loadChildren:YES];
|
|
NSArray* rootModel = [NSArray arrayWithObject:machOModel];
|
|
return rootModel;
|
|
}
|
|
|
|
+ (NSString*) cpuType:(MachOHeader::CpuType)cpuType {
|
|
NSString* label;
|
|
switch (cpuType) {
|
|
case MachOHeader::CpuTypePowerPc:
|
|
label = NSLocalizedString(@"CPU_TYPE_PPC", nil);
|
|
break;
|
|
case MachOHeader::CpuTypeI386:
|
|
label = NSLocalizedString(@"CPU_TYPE_I386", nil);
|
|
break;
|
|
case MachOHeader::CpuTypePowerPc64:
|
|
label = NSLocalizedString(@"CPU_TYPE_PPC64", nil);
|
|
break;
|
|
case MachOHeader::CpuTypeX8664:
|
|
label = NSLocalizedString(@"CPU_TYPE_X8664", nil);
|
|
break;
|
|
default:
|
|
label = NSLocalizedString(@"UNDEFINED", nil);
|
|
break;
|
|
|
|
}
|
|
return label;
|
|
}
|
|
|
|
- (NSString*) label {
|
|
return [ArchitectureModel cpuType:architecture->getHeader()->getCpuType()];
|
|
}
|
|
|
|
- (NSString*) uuid {
|
|
// use CFUUID
|
|
CFUUIDRef uuid = CFUUIDCreateFromUUIDBytes(kCFAllocatorDefault, *((CFUUIDBytes*)architecture->getUuid()));
|
|
CFStringRef result = CFUUIDCreateString(kCFAllocatorDefault, uuid);
|
|
CFRelease(uuid);
|
|
return (NSString*) CFBridgingRelease(result);
|
|
}
|
|
|
|
- (NSString*) fileType {
|
|
NSString* type;
|
|
switch(architecture->getHeader()->getFileType()) {
|
|
case MachOHeader::FileTypeObject: /* relocatable object file */
|
|
type = NSLocalizedString(@"FILE_TYPE_OBJECT", nil);
|
|
break;
|
|
case MachOHeader::FileTypeExecutable: /* demand paged executable file */
|
|
type = NSLocalizedString(@"FILE_TYPE_EXECUTABLE", nil);
|
|
break;
|
|
case MachOHeader::FileTypeVmLib: /* fixed VM shared library file */
|
|
type = NSLocalizedString(@"FILE_TYPE_VM_SHARED_LIBRARY", nil);
|
|
break;
|
|
case MachOHeader::FileTypeCore: /* core file */
|
|
type = NSLocalizedString(@"FILE_TYPE_CORE", nil);
|
|
break;
|
|
case MachOHeader::FileTypePreload: /* preloaded executable file */
|
|
type = NSLocalizedString(@"FILE_TYPE_PRELOADED_EXECUTABLE", nil);
|
|
break;
|
|
case MachOHeader::FileTypeDylib: /* dynamically bound shared library */
|
|
type = NSLocalizedString(@"FILE_TYPE_SHARED_LIBRARY", nil);
|
|
break;
|
|
case MachOHeader::FileTypeDylinker: /* dynamic link editor */
|
|
type = NSLocalizedString(@"FILE_TYPE_DYNAMIC_LINKER", nil);
|
|
break;
|
|
case MachOHeader::FileTypeBundle: /* dynamically bound bundle file */
|
|
type = NSLocalizedString(@"FILE_TYPE_BUNDLE", nil);
|
|
break;
|
|
case MachOHeader::FileTypeDylibStub: /* shared library stub for static linking only, no section contents */
|
|
type = NSLocalizedString(@"FILE_TYPE_STATIC_LIBRARY", nil);
|
|
break;
|
|
case MachOHeader::FileTypeDsym: /* companion file with only debug sections */
|
|
type = NSLocalizedString(@"FILE_TYPE_DSYM", nil);
|
|
break;
|
|
case MachOHeader::FileTypeKextBundle: /* kext bundle */
|
|
type = NSLocalizedString(@"FILE_TYPE_KEXT_BUNDLE", nil);
|
|
break;
|
|
default:
|
|
type = NSLocalizedString(@"UNDEFINED", @"Unknown");
|
|
}
|
|
return type;
|
|
}
|
|
|
|
- (NSString*) identifier {
|
|
NSString* identifier = [NSString string];
|
|
DylibCommand* dynamicLibraryIdCommand = architecture->getDynamicLibIdCommand();
|
|
if (dynamicLibraryIdCommand != NULL) {
|
|
identifier = [NSString stringWithStdString:dynamicLibraryIdCommand->getName()];
|
|
}
|
|
return identifier;
|
|
}
|
|
|
|
- (NSString*) dynamicLinker {
|
|
NSString* dynamicLinker;
|
|
dynamicLinker = [NSString stringWithStdString:architecture->getDynamicLinker()];
|
|
return dynamicLinker;
|
|
}
|
|
|
|
- (NSString*) rpath {
|
|
std::vector<std::string*> rpaths = architecture->getRpaths(false);
|
|
NSMutableString* rpath = [NSMutableString string];
|
|
for (std::vector<std::string*>::iterator it = rpaths.begin();
|
|
it != rpaths.end();
|
|
++it)
|
|
{
|
|
[rpath appendFormat:@"%@; ", [NSString stringWithStdString:**it]];
|
|
}
|
|
return rpath;
|
|
}
|
|
|
|
- (NSNumber*) showIdentifier {
|
|
NSNumber* result;
|
|
if ([[self identifier] length] == 0) {
|
|
result = [NSNumber numberWithBool:true];
|
|
} else {
|
|
result = [NSNumber numberWithBool:false];
|
|
}
|
|
return result;
|
|
}
|
|
|
|
- (NSString*) size {
|
|
NSString* size;
|
|
// regard the correct format specifier %qu for unsigned long
|
|
unsigned int architectureSize = architecture->getSize();
|
|
unsigned long long fileSize = file->getSize();
|
|
if (fileSize != architectureSize) {
|
|
size = [NSString stringWithFormat:NSLocalizedString(@"SIZE_FORMAT_ARCHITECTURE", nil),
|
|
fileSize/1024L, architectureSize/1024];
|
|
} else {
|
|
size = [NSString stringWithFormat:NSLocalizedString(@"SIZE_FORMAT", nil),
|
|
fileSize/1024L];
|
|
}
|
|
return size;
|
|
}
|
|
|
|
- (NSString*) version {
|
|
NSString* version = @"?";
|
|
DylibCommand* dynamicLibraryIdCommand = architecture->getDynamicLibIdCommand();
|
|
if (dynamicLibraryIdCommand != NULL) {
|
|
VersionFormatter* versionFormatter = [[VersionFormatter alloc] init];
|
|
|
|
time_t timestamp = dynamicLibraryIdCommand->getTimeStamp();
|
|
NSString* currentVersion = [versionFormatter stringForObjectValue:[NSNumber numberWithUnsignedInt:dynamicLibraryIdCommand->getCurrentVersion()]];
|
|
NSString* compatibleVersion = [versionFormatter stringForObjectValue:[NSNumber numberWithUnsignedInt:dynamicLibraryIdCommand->getCompatibleVersion()]];
|
|
if ([currentVersion length]+[compatibleVersion length] > 0) {
|
|
if (timestamp > 1) {
|
|
NSDate* date = [NSDate dateWithTimeIntervalSince1970:timestamp];
|
|
|
|
// this date formatter should be identical to NSDateFormatter in IB
|
|
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
|
|
[dateFormatter setDateStyle:NSDateFormatterMediumStyle];
|
|
[dateFormatter setTimeStyle:NSDateFormatterMediumStyle];
|
|
|
|
version = [NSString stringWithFormat:NSLocalizedString(@"VERSION_FORMAT_TIMESTAMP", nil),
|
|
currentVersion,
|
|
compatibleVersion,
|
|
[dateFormatter stringFromDate:date]];
|
|
}
|
|
else {
|
|
version = [NSString stringWithFormat:NSLocalizedString(@"VERSION_FORMAT", nil),
|
|
currentVersion,
|
|
compatibleVersion];
|
|
}
|
|
}
|
|
} else {
|
|
version = [machOModel version];
|
|
}
|
|
return version;
|
|
}
|
|
|
|
|
|
- (void) initSymbols {
|
|
symbolEntries = [NSMutableArray arrayWithCapacity:20];
|
|
for (MachOArchitecture::LoadCommandsConstIterator lcIter = architecture->getLoadCommandsBegin();
|
|
lcIter != architecture->getLoadCommandsEnd();
|
|
++lcIter)
|
|
{
|
|
// check if it is dylibcommand
|
|
SymbolTableCommand* command = dynamic_cast<SymbolTableCommand*> (*lcIter);
|
|
if (command != 0) {
|
|
for (SymbolTableCommand::SymbolTableEntriesConstIterator it = command->getSymbolTableEntryBegin(); it != command->getSymbolTableEntryEnd(); it++) {
|
|
SymbolTableEntryModel* symbolModel = [[SymbolTableEntryModel alloc] initWithEntry:*(it) demangleNamesPtr:[[document symbolTableController]demangleNamesPtr] document:document];
|
|
[symbolEntries addObject:symbolModel];
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
- (NSArray*) symbols {
|
|
if (symbolEntries == nil) {
|
|
[self initSymbols];
|
|
}
|
|
return symbolEntries;
|
|
}
|
|
|
|
- (void) setSymbols:(NSMutableArray*) newSymbolEntries {
|
|
symbolEntries = newSymbolEntries;
|
|
}
|
|
|
|
- (void) refreshSymbols {
|
|
[self initSymbols];
|
|
[self setSymbols:symbolEntries];
|
|
}
|
|
|
|
|
|
|
|
@end
|