Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(151)

Unified Diff: class-dump/src/CDClassDump.m

Issue 7793008: Add the 3.3.3 sources for class-dump. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/deps/third_party/
Patch Set: Created 9 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « class-dump/src/CDClassDump.h ('k') | class-dump/src/CDClassDumpVisitor.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: class-dump/src/CDClassDump.m
===================================================================
--- class-dump/src/CDClassDump.m (revision 0)
+++ class-dump/src/CDClassDump.m (revision 0)
@@ -0,0 +1,400 @@
+// -*- mode: ObjC -*-
+
+// This file is part of class-dump, a utility for examining the Objective-C segment of Mach-O files.
+// Copyright (C) 1997-1998, 2000-2001, 2004-2010 Steve Nygard.
+
+#import "CDClassDump.h"
+
+#import "NSArray-Extensions.h"
+#import "NSString-Extensions.h"
+#import "CDFatArch.h"
+#import "CDFatFile.h"
+#import "CDLCDylib.h"
+#import "CDMachOFile.h"
+#import "CDObjectiveCProcessor.h"
+#import "CDStructureTable.h"
+#import "CDSymbolReferences.h"
+#import "CDType.h"
+#import "CDTypeFormatter.h"
+#import "CDTypeParser.h"
+#import "CDVisitor.h"
+#import "CDLCSegment.h"
+#import "CDTypeController.h"
+#import "CDSearchPathState.h"
+
+@implementation CDClassDump
+
+- (id)init;
+{
+ if ([super init] == nil)
+ return nil;
+
+ searchPathState = [[CDSearchPathState alloc] init];
+ sdkRoot = nil;
+
+ machOFiles = [[NSMutableArray alloc] init];
+ machOFilesByID = [[NSMutableDictionary alloc] init];
+ objcProcessors = [[NSMutableArray alloc] init];
+
+ typeController = [[CDTypeController alloc] initWithClassDump:self];
+
+ // These can be ppc, ppc7400, ppc64, i386, x86_64
+ targetArch.cputype = CPU_TYPE_ANY;
+ targetArch.cpusubtype = 0;
+
+ flags.shouldShowHeader = YES;
+
+ return self;
+}
+
+- (void)dealloc;
+{
+ [searchPathState release];
+ [sdkRoot release];
+
+ [machOFiles release];
+ [machOFilesByID release];
+ [objcProcessors release];
+
+ [typeController release];
+
+ if (flags.shouldMatchRegex)
+ regfree(&compiledRegex);
+
+ [super dealloc];
+}
+
+@synthesize searchPathState;
+
+- (BOOL)shouldProcessRecursively;
+{
+ return flags.shouldProcessRecursively;
+}
+
+- (void)setShouldProcessRecursively:(BOOL)newFlag;
+{
+ flags.shouldProcessRecursively = newFlag;
+}
+
+- (BOOL)shouldSortClasses;
+{
+ return flags.shouldSortClasses;
+}
+
+- (void)setShouldSortClasses:(BOOL)newFlag;
+{
+ flags.shouldSortClasses = newFlag;
+}
+
+- (BOOL)shouldSortClassesByInheritance;
+{
+ return flags.shouldSortClassesByInheritance;
+}
+
+- (void)setShouldSortClassesByInheritance:(BOOL)newFlag;
+{
+ flags.shouldSortClassesByInheritance = newFlag;
+}
+
+- (BOOL)shouldSortMethods;
+{
+ return flags.shouldSortMethods;
+}
+
+- (void)setShouldSortMethods:(BOOL)newFlag;
+{
+ flags.shouldSortMethods = newFlag;
+}
+
+- (BOOL)shouldShowIvarOffsets;
+{
+ return flags.shouldShowIvarOffsets;
+}
+
+- (void)setShouldShowIvarOffsets:(BOOL)newFlag;
+{
+ flags.shouldShowIvarOffsets = newFlag;
+}
+
+- (BOOL)shouldShowMethodAddresses;
+{
+ return flags.shouldShowMethodAddresses;
+}
+
+- (void)setShouldShowMethodAddresses:(BOOL)newFlag;
+{
+ flags.shouldShowMethodAddresses = newFlag;
+}
+
+- (BOOL)shouldMatchRegex;
+{
+ return flags.shouldMatchRegex;
+}
+
+- (void)setShouldMatchRegex:(BOOL)newFlag;
+{
+ if (flags.shouldMatchRegex && newFlag == NO)
+ regfree(&compiledRegex);
+
+ flags.shouldMatchRegex = newFlag;
+}
+
+- (BOOL)shouldShowHeader;
+{
+ return flags.shouldShowHeader;
+}
+
+- (void)setShouldShowHeader:(BOOL)newFlag;
+{
+ flags.shouldShowHeader = newFlag;
+}
+
+- (BOOL)setRegex:(char *)regexCString errorMessage:(NSString **)errorMessagePointer;
+{
+ int result;
+
+ if (flags.shouldMatchRegex)
+ regfree(&compiledRegex);
+
+ result = regcomp(&compiledRegex, regexCString, REG_EXTENDED);
+ if (result != 0) {
+ char regex_error_buffer[256];
+
+ if (regerror(result, &compiledRegex, regex_error_buffer, 256) > 0) {
+ if (errorMessagePointer != NULL) {
+ *errorMessagePointer = [NSString stringWithUTF8String:regex_error_buffer];
+ }
+ } else {
+ if (errorMessagePointer != NULL)
+ *errorMessagePointer = nil;
+ }
+
+ return NO;
+ }
+
+ [self setShouldMatchRegex:YES];
+
+ return YES;
+}
+
+- (BOOL)regexMatchesString:(NSString *)aString;
+{
+ int result;
+
+ result = regexec(&compiledRegex, [aString UTF8String], 0, NULL, 0);
+ if (result != 0) {
+ if (result != REG_NOMATCH) {
+ char regex_error_buffer[256];
+
+ if (regerror(result, &compiledRegex, regex_error_buffer, 256) > 0)
+ NSLog(@"Error with regex matching string, %@", [NSString stringWithUTF8String:regex_error_buffer]);
+ }
+
+ return NO;
+ }
+
+ return YES;
+}
+
+@synthesize sdkRoot;
+
+- (NSArray *)machOFiles;
+{
+ return machOFiles;
+}
+
+- (NSArray *)objcProcessors;
+{
+ return objcProcessors;
+}
+
+@synthesize targetArch;
+
+- (BOOL)containsObjectiveCData;
+{
+ for (CDObjectiveCProcessor *processor in objcProcessors) {
+ if ([processor hasObjectiveCData])
+ return YES;
+ }
+
+ return NO;
+}
+
+- (BOOL)hasEncryptedFiles;
+{
+ for (CDMachOFile *machOFile in machOFiles) {
+ if ([machOFile isEncrypted]) {
+ return YES;
+ }
+ }
+
+ return NO;
+}
+
+- (CDTypeController *)typeController;
+{
+ return typeController;
+}
+
+- (BOOL)loadFile:(CDFile *)aFile;
+{
+ CDMachOFile *aMachOFile;
+
+ //NSLog(@"targetArch: (%08x, %08x)", targetArch.cputype, targetArch.cpusubtype);
+ aMachOFile = [aFile machOFileWithArch:targetArch];
+ //NSLog(@"aMachOFile: %@", aMachOFile);
+ if (aMachOFile == nil) {
+ fprintf(stderr, "Error: file doesn't contain the specified arch.\n\n");
+ return NO;
+ }
+
+ // Set before processing recursively. This was getting caught on CoreUI on 10.6
+ assert([aMachOFile filename] != nil);
+ [machOFiles addObject:aMachOFile];
+ [machOFilesByID setObject:aMachOFile forKey:[aMachOFile filename]];
+
+ if ([self shouldProcessRecursively]) {
+ @try {
+ for (CDLoadCommand *loadCommand in [aMachOFile loadCommands]) {
+ if ([loadCommand isKindOfClass:[CDLCDylib class]]) {
+ CDLCDylib *aDylibCommand;
+
+ aDylibCommand = (CDLCDylib *)loadCommand;
+ if ([aDylibCommand cmd] == LC_LOAD_DYLIB) {
+ [searchPathState pushSearchPaths:[aMachOFile runPaths]];
+ [self machOFileWithID:[aDylibCommand path]]; // Loads as a side effect
+ [searchPathState popSearchPaths];
+ }
+ }
+ }
+ }
+ @catch (NSException *exception) {
+ [aMachOFile release];
+ return NO;
+ }
+ }
+
+ return YES;
+}
+
+- (void)processObjectiveCData;
+{
+ for (CDMachOFile *machOFile in machOFiles) {
+ CDObjectiveCProcessor *aProcessor;
+
+ aProcessor = [[[machOFile processorClass] alloc] initWithMachOFile:machOFile];
+ [aProcessor process];
+ [objcProcessors addObject:aProcessor];
+ [aProcessor release];
+ }
+}
+
+// This visits everything segment processors, classes, categories. It skips over modules. Need something to visit modules so we can generate separate headers.
+- (void)recursivelyVisit:(CDVisitor *)aVisitor;
+{
+ [aVisitor willBeginVisiting];
+
+ if ([self containsObjectiveCData] || [self hasEncryptedFiles]) {
+ for (CDObjectiveCProcessor *processor in objcProcessors) {
+ [processor recursivelyVisit:aVisitor];
+ }
+ }
+
+ [aVisitor didEndVisiting];
+}
+
+- (CDMachOFile *)machOFileWithID:(NSString *)anID;
+{
+ NSString *adjustedID = nil;
+ CDMachOFile *aMachOFile;
+ NSString *executablePathPrefix = @"@executable_path";
+ NSString *rpathPrefix = @"@rpath";
+
+ if ([anID hasPrefix:executablePathPrefix]) {
+ adjustedID = [anID stringByReplacingOccurrencesOfString:executablePathPrefix withString:searchPathState.executablePath];
+ } else if ([anID hasPrefix:rpathPrefix]) {
+ //NSLog(@"Searching for %@ through run paths: %@", anID, [searchPathState searchPaths]);
+ for (NSString *searchPath in [searchPathState searchPaths]) {
+ NSString *str = [anID stringByReplacingOccurrencesOfString:rpathPrefix withString:searchPath];
+ //NSLog(@"trying %@", str);
+ if ([[NSFileManager defaultManager] fileExistsAtPath:str]) {
+ adjustedID = str;
+ //NSLog(@"Found it!");
+ break;
+ }
+ }
+ if (adjustedID == nil) {
+ adjustedID = anID;
+ //NSLog(@"Did not find it.");
+ }
+ } else if (sdkRoot != nil) {
+ adjustedID = [sdkRoot stringByAppendingPathComponent:anID];
+ } else {
+ adjustedID = anID;
+ }
+
+ aMachOFile = [machOFilesByID objectForKey:adjustedID];
+ if (aMachOFile == nil) {
+ NSData *data;
+ CDFile *aFile;
+
+ data = [[NSData alloc] initWithContentsOfMappedFile:adjustedID];
+ aFile = [CDFile fileWithData:data filename:adjustedID searchPathState:searchPathState];
+ [data release];
+
+ if (aFile == nil || [self loadFile:aFile] == NO)
+ NSLog(@"Warning: Failed to load: %@", adjustedID);
+
+ aMachOFile = [machOFilesByID objectForKey:adjustedID];
+ if (aMachOFile == nil) {
+ NSLog(@"Warning: Couldn't load MachOFile with ID: %@, adjustedID: %@", anID, adjustedID);
+ }
+ }
+
+ return aMachOFile;
+}
+
+- (void)appendHeaderToString:(NSMutableString *)resultString;
+{
+ // Since this changes each version, for regression testing it'll be better to be able to not show it.
+ if (flags.shouldShowHeader == NO)
+ return;
+
+ [resultString appendString:@"/*\n"];
+ [resultString appendFormat:@" * Generated by class-dump %s.\n", CLASS_DUMP_VERSION];
+ [resultString appendString:@" *\n"];
+ [resultString appendString:@" * class-dump is Copyright (C) 1997-1998, 2000-2001, 2004-2010 by Steve Nygard.\n"];
+ [resultString appendString:@" */\n\n"];
+
+ if (sdkRoot != nil) {
+ [resultString appendString:@"/*\n"];
+ [resultString appendFormat:@" * SDK Root: %@\n", sdkRoot];
+ [resultString appendString:@" */\n\n"];
+ }
+}
+
+- (void)registerTypes;
+{
+ for (CDObjectiveCProcessor *processor in objcProcessors) {
+ [processor registerTypesWithObject:typeController phase:0];
+ }
+ [typeController endPhase:0];
+
+ [typeController workSomeMagic];
+}
+
+- (void)showHeader;
+{
+ if ([machOFiles count] > 0) {
+ [[[machOFiles lastObject] headerString:YES] print];
+ }
+}
+
+- (void)showLoadCommands;
+{
+ if ([machOFiles count] > 0) {
+ [[[machOFiles lastObject] loadCommandString:YES] print];
+ }
+}
+
+@end
Property changes on: class-dump/src/CDClassDump.m
___________________________________________________________________
Added: svn:eol-style
+ LF
« no previous file with comments | « class-dump/src/CDClassDump.h ('k') | class-dump/src/CDClassDumpVisitor.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698