mirror of
https://github.com/darlinghq/class-dump.git
synced 2024-11-27 06:10:25 +00:00
d62f2dd86f
to see if MpApp.app/Contents/MacOS/MyApp exists, and uses that. Actually, it also handles the OmniWeb hack where the real executable is MyApp.app/Contents/MacOS/.MyApp. (But it still won't find the frameworks that are stored in the app wrapper.)
308 lines
9.8 KiB
Objective-C
308 lines
9.8 KiB
Objective-C
//
|
|
// $Id: MappedFile.m,v 1.7 2000/10/15 02:47:20 nygard Exp $
|
|
//
|
|
|
|
//
|
|
// This file is a part of class-dump v2, a utility for examining the
|
|
// Objective-C segment of Mach-O files.
|
|
// Copyright (C) 1997, 1998, 1999, 2000 Steve Nygard
|
|
//
|
|
// This program is free software; you can redistribute it and/or modify
|
|
// it under the terms of the GNU General Public License as published by
|
|
// the Free Software Foundation; either version 2 of the License, or
|
|
// (at your option) any later version.
|
|
//
|
|
// This program is distributed in the hope that it will be useful,
|
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
// GNU General Public License for more details.
|
|
//
|
|
// You should have received a copy of the GNU General Public License
|
|
// along with this program; if not, write to the Free Software
|
|
// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
|
//
|
|
// You may contact the author by:
|
|
// e-mail: nygard@omnigroup.com
|
|
//
|
|
|
|
#import "MappedFile.h"
|
|
#if NS_TARGET_MAJOR < 4 && !defined(__APPLE__)
|
|
#import <foundation/NSArray.h>
|
|
#import <foundation/NSException.h>
|
|
#import <foundation/NSPathUtilities.h>
|
|
#import <foundation/NSUtilities.h>
|
|
|
|
@interface NSString (Foundation4PathCompatibility)
|
|
- (NSArray *)pathComponents;
|
|
@end
|
|
|
|
@implementation NSString (Foundation4PathCompatibility)
|
|
- (NSArray *)pathComponents
|
|
{
|
|
return [self componentsSeparatedByString:@"/"];
|
|
}
|
|
@end
|
|
|
|
#endif
|
|
|
|
#include <stdio.h>
|
|
#include <libc.h>
|
|
#include <ctype.h>
|
|
|
|
static BOOL debugFlag = NO;
|
|
|
|
static NSArray *envDyldFrameworkPath = nil;
|
|
static NSArray *envDyldLibraryPath = nil;
|
|
static NSArray *envDyldFallbackFrameworkPath = nil;
|
|
static NSArray *envDyldFallbackLibraryPath = nil;
|
|
static NSMutableArray *firstSearchPath = nil;
|
|
static NSMutableArray *secondSearchPath = nil;
|
|
|
|
@implementation MappedFile
|
|
|
|
+ (void) initialize
|
|
{
|
|
static BOOL initialized = NO;
|
|
NSDictionary *environment;
|
|
NSString *home, *debugFrameworkPaths;
|
|
|
|
if (initialized == YES)
|
|
return;
|
|
initialized = YES;
|
|
|
|
environment = [[NSProcessInfo processInfo] environment];
|
|
debugFrameworkPaths = [environment objectForKey:@"ClassDumpDebugFrameworkPaths"];
|
|
if (debugFrameworkPaths != nil && [debugFrameworkPaths isEqual:@"YES"])
|
|
debugFlag = YES;
|
|
|
|
envDyldFrameworkPath = [[environment objectForKey:@"DYLD_FRAMEWORK_PATH"] componentsSeparatedByString:@":"];
|
|
envDyldLibraryPath = [[environment objectForKey:@"DYLD_LIBRARY_PATH"] componentsSeparatedByString:@":"];
|
|
envDyldFallbackFrameworkPath = [[environment objectForKey:@"DYLD_FALLBACK_FRAMEWORK_PATH"] componentsSeparatedByString:@":"];
|
|
envDyldFallbackLibraryPath = [[environment objectForKey:@"DYLD_FALLBACK_LIBRARY_PATH"] componentsSeparatedByString:@":"];
|
|
home = [environment objectForKey:@"HOME"];
|
|
|
|
if (debugFlag == YES)
|
|
{
|
|
NSLog (@"envDyldFrameworkPath: %@", envDyldFrameworkPath);
|
|
NSLog (@"envDyldLibraryPath: %@", envDyldLibraryPath);
|
|
NSLog (@"envDyldFallbackFrameworkPath: %@", envDyldFallbackFrameworkPath);
|
|
}
|
|
|
|
if (envDyldFallbackFrameworkPath == nil)
|
|
envDyldFallbackFrameworkPath = [[NSArray arrayWithObjects:[NSString stringWithFormat:@"%@/Library/Frameworks", home],
|
|
@"/Local/Library/Frameworks",
|
|
@"/Network/Library/Frameworks",
|
|
@"/System/Library/Frameworks",
|
|
@"/LocalLibrary/Frameworks",
|
|
@"/NextLibrary/Frameworks",
|
|
nil] retain];
|
|
|
|
if (debugFlag == YES)
|
|
{
|
|
NSLog (@"envDyldFallbackFrameworkPath: %@", envDyldFallbackFrameworkPath);
|
|
NSLog (@"envDyldFallbackLibraryPath: %@", envDyldFallbackLibraryPath);
|
|
}
|
|
|
|
if (envDyldFallbackLibraryPath == nil)
|
|
envDyldFallbackLibraryPath = [[NSArray arrayWithObjects:[NSString stringWithFormat:@"%@/lib", home],
|
|
@"/usr/local/lib",
|
|
@"/lib",
|
|
@"/usr/lib",
|
|
nil] retain];
|
|
if (debugFlag == YES)
|
|
NSLog (@"envDyldFallbackLibraryPath: %@", envDyldFallbackLibraryPath);
|
|
|
|
firstSearchPath = [[NSMutableArray arrayWithArray:envDyldFrameworkPath] retain];
|
|
[firstSearchPath addObjectsFromArray:envDyldLibraryPath];
|
|
|
|
secondSearchPath = [[NSMutableArray arrayWithArray:envDyldFallbackFrameworkPath] retain];
|
|
[secondSearchPath addObjectsFromArray:envDyldFallbackLibraryPath];
|
|
}
|
|
|
|
+ (BOOL) debug
|
|
{
|
|
return debugFlag;
|
|
}
|
|
|
|
+ (void) setDebug:(BOOL)flag
|
|
{
|
|
debugFlag = flag;
|
|
}
|
|
|
|
// Will map filename into memory. If filename is a directory with specific suffixes, treat the directory as a wrapper.
|
|
|
|
- initWithFilename:(NSString *)aFilename
|
|
{
|
|
NSString *standardPath;
|
|
#if (NS_TARGET_MAJOR >= 4) || defined(__APPLE__)
|
|
NSMutableSet *wrappers = [NSMutableSet set];
|
|
#else
|
|
// for foundation 3.x (less efficient than a set but at least it works...)
|
|
NSMutableArray *wrappers = [NSMutableArray array];
|
|
#endif
|
|
if ([super init] == nil)
|
|
return nil;
|
|
|
|
standardPath = [aFilename stringByStandardizingPath];
|
|
|
|
// XXX: Try grabbing these from an environment variable & move to +initialize
|
|
[wrappers addObject:@"app"];
|
|
[wrappers addObject:@"framework"];
|
|
[wrappers addObject:@"bundle"];
|
|
[wrappers addObject:@"palette"];
|
|
[wrappers addObject:@"plugin"];
|
|
|
|
if ([wrappers containsObject:[standardPath pathExtension]] == YES)
|
|
{
|
|
standardPath = [self pathToMainFileOfWrapper:standardPath];
|
|
}
|
|
|
|
if (debugFlag == YES)
|
|
{
|
|
NSLog (@"----------------------------------------------------------------------");
|
|
NSLog (@"before: %@", standardPath);
|
|
}
|
|
|
|
filename = [self adjustedFrameworkPath:standardPath];
|
|
|
|
if (debugFlag == YES)
|
|
NSLog (@"after: %@", filename);
|
|
|
|
data = [[NSData dataWithContentsOfMappedFile:filename] retain];
|
|
if (data == nil)
|
|
{
|
|
NSLog (@"Couldn't map file: %@", filename);
|
|
return nil;
|
|
}
|
|
|
|
installName = [standardPath retain];
|
|
filename = [filename retain];
|
|
|
|
return self;
|
|
}
|
|
|
|
- (void) dealloc
|
|
{
|
|
[data release];
|
|
[filename release];
|
|
[installName release];
|
|
|
|
[super dealloc];
|
|
}
|
|
|
|
- (NSString *) installName
|
|
{
|
|
return installName;
|
|
}
|
|
|
|
- (NSString *) filename
|
|
{
|
|
return filename;
|
|
}
|
|
|
|
- (const void *) data
|
|
{
|
|
return [data bytes];
|
|
}
|
|
|
|
// How does this handle something ending in "/"?
|
|
|
|
- (NSString *) pathToMainFileOfWrapper:(NSString *)path
|
|
{
|
|
NSString *base, *extension, *mainFile;
|
|
|
|
base = [path lastPathComponent];
|
|
extension = [base pathExtension];
|
|
base = [base stringByDeletingPathExtension];
|
|
mainFile = [NSString stringWithFormat:@"%@/%@", path, base];
|
|
if ([@"app" isEqual:extension] == YES)
|
|
{
|
|
NSFileManager *fileManager;
|
|
NSString *alternateMainFile;
|
|
|
|
fileManager = [NSFileManager defaultManager];
|
|
// Currently OmniWeb uses a small file to change the library paths and then runs the real
|
|
// OmniWeb, which is in Contents/MacOS/.OmniWeb, so we'll check for this case first:
|
|
alternateMainFile = [NSString stringWithFormat:@"%@/Contents/MacOS/.%@", path, base];
|
|
if ([fileManager fileExistsAtPath:alternateMainFile] == YES)
|
|
mainFile = alternateMainFile;
|
|
else {
|
|
// Mac OS X has a different app layout now
|
|
alternateMainFile = [NSString stringWithFormat:@"%@/Contents/MacOS/%@", path, base];
|
|
if ([fileManager fileExistsAtPath:alternateMainFile] == YES)
|
|
mainFile = alternateMainFile;
|
|
}
|
|
}
|
|
|
|
return mainFile;
|
|
}
|
|
|
|
- (NSString *) adjustedFrameworkPath:(NSString *)path
|
|
{
|
|
NSArray *pathComponents;
|
|
int count, l;
|
|
NSString *tailString = nil, *frameworkName = nil, *version = nil;
|
|
NSRange tailRange;
|
|
NSString *adjustedPath;
|
|
NSFileManager *fileManager;
|
|
|
|
pathComponents = [path pathComponents];
|
|
count = [pathComponents count];
|
|
if (count - 1 >= 0)
|
|
frameworkName = [pathComponents objectAtIndex:count - 1];
|
|
|
|
if (count - 3 >= 0)
|
|
{
|
|
if ([[pathComponents objectAtIndex:count - 3] isEqual:@"Versions"] == YES)
|
|
version = [pathComponents objectAtIndex:count - 2];
|
|
}
|
|
|
|
if (debugFlag == YES)
|
|
NSLog (@"frameworkName: %@", frameworkName);
|
|
|
|
if (frameworkName == nil)
|
|
return path;
|
|
|
|
if (debugFlag == YES)
|
|
NSLog (@"version: %@", version);
|
|
if (version == nil)
|
|
tailString = [NSString stringWithFormat:@"%@.framework/%@", frameworkName, frameworkName];
|
|
else
|
|
tailString = [NSString stringWithFormat:@"%@.framework/Versions/%@/%@", frameworkName, version, frameworkName];
|
|
|
|
if (debugFlag == YES)
|
|
NSLog (@"tailString: %@", tailString);
|
|
|
|
tailRange = [path rangeOfString:tailString options:NSBackwardsSearch];
|
|
if (debugFlag == YES)
|
|
NSLog (@"tailRange.length: %d", tailRange.length);
|
|
if (tailRange.length == 0)
|
|
return path;
|
|
|
|
fileManager = [NSFileManager defaultManager];
|
|
|
|
count = [firstSearchPath count];
|
|
for (l = 0; l < count; l++)
|
|
{
|
|
adjustedPath = [NSString stringWithFormat:@"%@/%@", [firstSearchPath objectAtIndex:l], tailString];
|
|
if (debugFlag == YES)
|
|
NSLog (@"adjustedPath: %@", adjustedPath);
|
|
if ([fileManager fileExistsAtPath:adjustedPath] == YES)
|
|
return adjustedPath;
|
|
}
|
|
|
|
count = [secondSearchPath count];
|
|
for (l = 0; l < count; l++)
|
|
{
|
|
adjustedPath = [NSString stringWithFormat:@"%@/%@", [secondSearchPath objectAtIndex:l], tailString];
|
|
if (debugFlag == YES)
|
|
NSLog (@"adjustedPath: %@", adjustedPath);
|
|
if ([fileManager fileExistsAtPath:adjustedPath] == YES)
|
|
return adjustedPath;
|
|
}
|
|
|
|
return path;
|
|
}
|
|
|
|
@end
|