macdependency/MacDependency/ArchitectureModel.mm
2016-11-19 17:02:31 +01:00

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