From af02f41bd03adc6844df59a468ff9eca33e5dff5 Mon Sep 17 00:00:00 2001 From: Steve Nygard Date: Sat, 31 Jul 1999 03:32:25 +0000 Subject: [PATCH] Initial revision. --- MappedFile.h | 54 ++ MappedFile.m | 131 +++++ Nextstep/Makefile | 52 ++ Nextstep/Makefile.postamble | 117 +++++ Nextstep/Makefile.preamble | 107 ++++ Nextstep/PB.project | 30 ++ ObjcCategory.h | 55 ++ ObjcCategory.m | 117 +++++ ObjcClass.h | 62 +++ ObjcClass.m | 186 +++++++ ObjcIvar.h | 49 ++ ObjcIvar.m | 68 +++ ObjcMethod.h | 54 ++ ObjcMethod.m | 89 ++++ ObjcProtocol.h | 56 +++ ObjcProtocol.m | 128 +++++ ObjcThing.h | 48 ++ ObjcThing.m | 46 ++ Openstep/Makefile | 53 ++ Openstep/Makefile.postamble | 126 +++++ Openstep/Makefile.preamble | 130 +++++ Openstep/PB.project | 46 ++ Rhapsody/Makefile | 60 +++ Rhapsody/Makefile.postamble | 126 +++++ Rhapsody/Makefile.preamble | 130 +++++ Rhapsody/PB.project | 52 ++ class-dump.h | 137 +++++ class-dump.m | 979 ++++++++++++++++++++++++++++++++++++ datatypes.h | 86 ++++ datatypes.m | 607 ++++++++++++++++++++++ gram.y | 411 +++++++++++++++ h.template | 11 + lexer.c | 104 ++++ m.template | 18 + my_regex.c | 72 +++ my_regex.h | 42 ++ 36 files changed, 4639 insertions(+) create mode 100644 MappedFile.h create mode 100644 MappedFile.m create mode 100644 Nextstep/Makefile create mode 100644 Nextstep/Makefile.postamble create mode 100644 Nextstep/Makefile.preamble create mode 100644 Nextstep/PB.project create mode 100644 ObjcCategory.h create mode 100644 ObjcCategory.m create mode 100644 ObjcClass.h create mode 100644 ObjcClass.m create mode 100644 ObjcIvar.h create mode 100644 ObjcIvar.m create mode 100644 ObjcMethod.h create mode 100644 ObjcMethod.m create mode 100644 ObjcProtocol.h create mode 100644 ObjcProtocol.m create mode 100644 ObjcThing.h create mode 100644 ObjcThing.m create mode 100644 Openstep/Makefile create mode 100644 Openstep/Makefile.postamble create mode 100644 Openstep/Makefile.preamble create mode 100644 Openstep/PB.project create mode 100644 Rhapsody/Makefile create mode 100644 Rhapsody/Makefile.postamble create mode 100644 Rhapsody/Makefile.preamble create mode 100644 Rhapsody/PB.project create mode 100644 class-dump.h create mode 100644 class-dump.m create mode 100644 datatypes.h create mode 100644 datatypes.m create mode 100644 gram.y create mode 100644 h.template create mode 100644 lexer.c create mode 100644 m.template create mode 100644 my_regex.c create mode 100644 my_regex.h diff --git a/MappedFile.h b/MappedFile.h new file mode 100644 index 00000000..049b012b --- /dev/null +++ b/MappedFile.h @@ -0,0 +1,54 @@ +// +// $Id: MappedFile.h,v 1.1 1999/07/31 03:32:26 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 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@telusplanet.net +// + +#include +#include + +#if NS_TARGET_MAJOR >= 4 +#import +#else +#import +#import +#endif + +// And most of this could be done with NSData - initWithContentsOfMappedFile: + +@interface MappedFile : NSObject +{ + NSString *filename; + NSData *data; +} + +- initWithFilename:(NSString *)aFilename; +- (void) dealloc; + +- (NSString *) filename; +- (const void *) data; + +- (NSString *) pathToMainFileOfWrapper:(NSString *)path; + +@end diff --git a/MappedFile.m b/MappedFile.m new file mode 100644 index 00000000..a19e6da8 --- /dev/null +++ b/MappedFile.m @@ -0,0 +1,131 @@ +// +// $Id: MappedFile.m,v 1.1 1999/07/31 03:32:27 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 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@telusplanet.net +// + +#import "MappedFile.h" +#if NS_TARGET_MAJOR < 4 +#import +#import +#import +#import + +@interface NSString (Foundation4PathCompatibility) +- (NSArray *)pathComponents; +@end + +@implementation NSString (Foundation4PathCompatibility) +- (NSArray *)pathComponents +{ + return [self componentsSeparatedByString:@"/"]; +} +@end + +#endif + +#include +#include +#include + +@implementation MappedFile + +// 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) + 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]; + + [wrappers addObject:@"app"]; + [wrappers addObject:@"framework"]; + [wrappers addObject:@"bundle"]; + [wrappers addObject:@"palette"]; + + if ([wrappers containsObject:[standardPath pathExtension]] == YES) + { + standardPath = [self pathToMainFileOfWrapper:standardPath]; + } + + data = [[NSData dataWithContentsOfMappedFile:standardPath] retain]; + if (data == nil) + { + NSLog (@"Couldn't map file: %@", standardPath); + return nil; + } + + filename = [standardPath retain]; + + return self; +} + +- (void) dealloc +{ + [data release]; + [filename release]; + + [super dealloc]; +} + +- (NSString *) filename +{ + return filename; +} + +- (const void *) data +{ + return [data bytes]; +} + +// How does this handle something ending in "/"? + +- (NSString *) pathToMainFileOfWrapper:(NSString *)path +{ + NSRange range; + NSMutableString *tmp; + NSString *extension; + NSString *base; + + base = [[path pathComponents] lastObject]; + NSAssert (base != nil, @"No base."); + + extension = [NSString stringWithFormat:@".%@", [base pathExtension]]; + + tmp = [NSMutableString stringWithFormat:@"%@/%@", path, base]; + range = [tmp rangeOfString:extension options:NSBackwardsSearch]; + [tmp deleteCharactersInRange:range]; + + return tmp; +} + +@end diff --git a/Nextstep/Makefile b/Nextstep/Makefile new file mode 100644 index 00000000..0721336c --- /dev/null +++ b/Nextstep/Makefile @@ -0,0 +1,52 @@ +# +# Generated by the NeXT Project Builder. +# +# NOTE: Do NOT change this file -- Project Builder maintains it. +# +# Put all of your customizations in files called Makefile.preamble +# and Makefile.postamble (both optional), and Makefile will include them. +# + +NAME = class-dump + +PROJECTVERSION = 2.6 +LANGUAGE = English + +CLASSES = MappedFile.m ObjcCategory.m ObjcClass.m ObjcIvar.m\ + ObjcMethod.m ObjcProtocol.m ObjcThing.m + +HFILES = class-dump.h datatypes.h MappedFile.h ObjcCategory.h\ + ObjcClass.h ObjcIvar.h ObjcMethod.h ObjcProtocol.h\ + ObjcThing.h my_regex.h + +OTHERLINKED = gram.y + +MFILES = class-dump.m datatypes.m + +CFILES = lexer.c my_regex.c + +OTHERSRCS = Makefile.preamble Makefile Makefile.postamble m.template\ + h.template + +OTHERLINKEDOFILES = gram.o + +MAKEFILEDIR = /NextDeveloper/Makefiles/app +MAKEFILE = tool.make +INSTALLDIR = /usr/local/bin +INSTALLFLAGS = -c -s -m 755 +SOURCEMODE = 444 + +LIBS = -lFoundation_s +DEBUG_LIBS = $(LIBS) +PROF_LIBS = $(LIBS) + + + + +-include Makefile.preamble + +include $(MAKEFILEDIR)/$(MAKEFILE) + +-include Makefile.postamble + +-include Makefile.dependencies diff --git a/Nextstep/Makefile.postamble b/Nextstep/Makefile.postamble new file mode 100644 index 00000000..a65c81fc --- /dev/null +++ b/Nextstep/Makefile.postamble @@ -0,0 +1,117 @@ +############################################################################### +# NeXT Makefile.postamble Template +# Copyright 1993, NeXT Computer, Inc. +# +# This Makefile is used for configuring the standard app makefiles associated +# with ProjectBuilder. +# +# Use this template to set attributes for a project, sub-project, bundle, or +# palette. Each node in the project's tree of sub-projects and bundles +# should have it's own Makefile.preamble and Makefile.postamble. Additional +# rules (e.g., after_install) that are defined by the developer should be +# defined in this file. +# +############################################################################### +# +# Here are the variables exported by the common "app" makefiles that can be +# used in any customizations you make to the template below: +# +# PRODUCT_ROOT - Name of top-level app-wrapper (e.g., Webster.app) +# OFILE_DIR - Directory into which .o object files are generated. +# (Note that this name is calculated based on the target +# architectures specified in Project Builder). +# DERIVED_SRC_DIR - Directory used for all other derived files +# ALL_CFLAGS - All the flags passed to the cc(1) driver for compilations +# +# NAME - name of application, bundle, subproject, palette, etc. +# LANGUAGE - langage in which the project is written (default "English") +# ENGLISH - boolean flag set iff $(LANGUAGE) = "English" +# JAPANESE - boolean flag set iff $(LANGUAGE) = "Japanese" +# LOCAL_RESOURCES - localized resources (e.g. nib's, images) of project +# GLOBAL_RESOURCES - non-localized resources of project +# PROJECTVERSION - version of ProjectBuilder that output Makefile +# APPICON - application icon file +# DOCICONS - dock icon files +# ICONSECTIONS - Specifies icon sections when linking executable +# +# CLASSES - Class implementation files in project. +# HFILES - Header files in project. +# MFILES - Other Objective-C source files in project. +# CFILES - Other C source files in project. +# PSWFILES - .psw files in the project +# PSWMFILES - .pswm files in the project +# SUBPROJECTS - Subprojects of this project +# BUNDLES - Bundle subprojects of this project +# OTHERSRCS - Other miscellaneous sources of this project +# OTHERLINKED - Source files not matching a standard source extention +# +# LIBS - Libraries to link with when making app target +# DEBUG_LIBS - Libraries to link with when making debug target +# PROF_LIBS - Libraries to link with when making profile target +# OTHERLINKEDOFILES - Other relocatable files to (always) link in. +# +# APP_MAKEFILE_DIR - Directory in which to find generic set of Makefiles +# MAKEFILEDIR - Directory in which to find $(MAKEFILE) +# MAKEFILE - Top level mechanism Makefile (e.g., app.make, bundle.make) +# INSTALLDIR - Directory app will be installed into by 'install' target + + +# Change defaults assumed by the standard app makefiles here. Edit the +# following default values as appropriate. (Note that if no Makefile.postamble +# exists, these values will have defaults set in common.make). + +# Add Makefile.preamble, Makefile.postamble, and Makefile.dependencies here if +# you would like changes to them to invalidate previous builds. The project +# depends on $(MAKEFILES) so that changes to Makefiles will trigger a re-build. +#MAKEFILES = Makefile + +# Optimization flag passed to compiler: +#OPTIMIZATION_CFLAG = -O + +# Flags always passed to compiler: +#COMMON_CFLAGS = $(PROJECT_SPECIFIC_CFLAGS) -g -Wall + +# Flags passed to compiler in normal 'app' compiles: +#NORMAL_CFLAGS = $(COMMON_CFLAGS) $(OPTIMIZATION_CFLAG) + +# Flags passed to compiler in 'debug' compiles: +#DEBUG_CFLAGS = $(COMMON_CFLAGS) -DDEBUG + +# Flags passed to compiler in 'profile' compiles +#PROFILE_CFLAGS = $(COMMON_CFLAGS) -pg $(OPTIMIZATION_CFLAG) -DPROFILE + +# Flags passed to yacc +#YFLAGS = -d + +# Ownership and permissions of files installed by 'install' target +#INSTALL_AS_USER = root # User to chown app to +#INSTALL_AS_GROUP = wheel # Group to chgrp app to +#INSTALL_PERMISSIONS = # If set, 'install' chmod's executable to this + +# Options to strip for bundles, apps with bundles, and apps without bundles, +# respectively. +#RELOCATABLE_STRIP_OPTS = -x -u +#DYLD_APP_STRIP_OPTS = -A -n +#APP_STRIP_OPTS = +#TOOL_STRIP_OPTS = +#LIBRARY_STRIP_OPTS = -x -S # Note: -S strips debugging symbols +# (Note: APP_STRIP_OPTS and TOOL_STRIP_OPTS default to empty, but +# developers doing their own dynamic loading should set this to +# $(DYLD_APP_STRIP_OPTS)). + + +######################################################################### +# Put rules to extend the behavior of the standard Makefiles here. Typical +# user-defined rules are before_install and after_install (please don't +# redefine things like install or app, as they are owned by the top-level +# Makefile API), which are rules that get invoked before and after the install +# target runs. Such rules should be specified with the '::' syntax rather than +# a single colon. + +YFLAGS = --yacc -d +YACC = bison +LEX = flex + + + + diff --git a/Nextstep/Makefile.preamble b/Nextstep/Makefile.preamble new file mode 100644 index 00000000..03402567 --- /dev/null +++ b/Nextstep/Makefile.preamble @@ -0,0 +1,107 @@ +############################################################################### +# NeXT Makefile.preamble Template +# Copyright 1993, NeXT Computer, Inc. +# +# This Makefile is used for configuring the standard app makefiles associated +# with ProjectBuilder. +# +# Use this template to set attributes for a project, sub-project, bundle, or +# palette. Each node in the project's tree of sub-projects and bundles +# should have it's own Makefile.preamble and Makefile.postamble. +# +############################################################################### +## Configure the flags passed to $(CC) here. These flags will also be +## inherited by all nested sub-projects and bundles. Put your -I, -D, -U, and +## -L flags here. To change the default flags that get passed to ${CC} +## (e.g. change -O to -O2), see Makefile.postamble. + +# Flags passed to compiler (in addition to -g, -O, etc) +OTHER_CFLAGS = +# Flags passed to ld (in addition to -ObjC, etc.) +OTHER_LDFLAGS = +BUNDLELDFLAGS = # use iff project is a bundle +PALETTELDFLAGS = # use iff project is a palette + +## Specify which headers in this project should be published to the outside +## world in a flat header directory given in PUBLIC_HEADER_DIR (which will be +## prepended by DSTROOT, below. Any subset of these public headers can be +## precompiled automatically after installation, with extra user-defined flags. +PUBLIC_HEADER_DIR = +PUBLIC_HEADERS = +PUBLIC_PRECOMPILED_HEADERS = +PUBLIC_PRECOMPILED_HEADERS_CFLAGS = + +## Configure what is linked in at each level here. Libraries are only used in +## the final 'app' linking step. Final 'app' linking is only done via the +## 'app', 'debug', and 'profile' targets when they are invoked for +## the top-level app. + +# Additional relocatables to be linked in at this level +OTHER_OFILES = +# Additional libs to link apps against ('app' target) +OTHER_LIBS = +# Additional libs to link apps against ('debug' target) +OTHER_DEBUG_LIBS = +# Additional libs to link apps against ('profile' target) +OTHER_PROF_LIBS = + +# More 'app' libraries when $(JAPANESE) = "YES" +OTHER_JAPANESE_LIBS = +# More 'debug' libraries when $(JAPANESE) = "YES" +OTHER_JAPANESE_DEBUG_LIBS = +# More 'profile' libs when $(JAPANESE) = "YES" +OTHER_JAPANESE_PROF_LIBS = + +# If this is a bundle, and you *know* the enclosing application will not +# be linking with a library which you require in your bundle code, then +# mention it here so that it gets linked into the bundle. Note that this +# is wasteful but sometimes necessary. +BUNDLE_LIBS = + +## Configure how things get built here. Additional dependencies, sourcefiles, +## derived files, and build order should be specified here. + +# Other dependencies of this project +OTHER_PRODUCT_DEPENDS = +# Built *before* building subprojects/bundles +OTHER_INITIAL_TARGETS = gram.o +# Other source files maintained by .pre/postamble +OTHER_SOURCEFILES = +# Additional files to be removed by `make clean' +OTHER_GARBAGE = +# Precompiled headers to be built before any compilation occurs (e.g., draw.p) +PRECOMPS = + +# Targets to be built before installation +OTHER_INSTALL_DEPENDS = + +# A virtual root directory (other than /) to be prepended to the $(INSTALLDIR) +# passed from ProjectBuilder. +DSTROOT = + +# Set the following to "YES" if you want the old behavior of recursively +# cleaning all nested subprojects during 'make clean'. +CLEAN_ALL_SUBPROJECTS = + +## Add more obscure source files here to cause them to be automatically +## processed by the appropriate tool. Note that these files should also be +## added to "Supporting Files" in ProjectBuilder. The desired .o files that +## result from these files should also be added to OTHER_OFILES above so they +## will be linked in. + +# .msg files that should have msgwrap run on them +MSGFILES = +# .defs files that should have mig run on them +DEFSFILES = +# .mig files (no .defs files) that should have mig run on them +MIGFILES = + +## Add additional Help directories here (add them to the project as "Other +## Resources" in Project Builder) so that they will be compressed into .store +## files and copied into the app wrapper. If the help directories themselves +## need to also be in the app wrapper, then a cp command will need to be added +## in an after_install target. +OTHER_HELP_DIRS = + +# Don't add more rules here unless you want the first one to be the default +# target for make! Put all your targets in Makefile.postamble. diff --git a/Nextstep/PB.project b/Nextstep/PB.project new file mode 100644 index 00000000..c0a9494c --- /dev/null +++ b/Nextstep/PB.project @@ -0,0 +1,30 @@ +INSTALLDIR = /usr/local/bin; +FILESTABLE = { + TOOLS = (); + M_FILES = ("class-dump.m", datatypes.m); + OTHER_LINKED = (gram.y); + LIBS = (); + H_FILES = ("class-dump.h", datatypes.h, MappedFile.h, ObjcCategory.h, ObjcClass.h, ObjcIvar.h, ObjcMethod.h, ObjcProtocol.h, ObjcThing.h, my_regex.h); + CLASSES = (MappedFile.m, ObjcCategory.m, ObjcClass.m, ObjcIvar.m, ObjcMethod.m, ObjcProtocol.m, ObjcThing.m); + PUBLIC_HEADERS = (); + C_FILES = (lexer.c, my_regex.c); + PROJECT_HEADERS = (); + OTHER_SOURCES = (Makefile.preamble, Makefile, Makefile.postamble, m.template, h.template); + SUBPROJECTS = (); + BUNDLES = (); + OTHER_LIBS = (Foundation_s); + PRECOMPILED_HEADERS = (); +}; +GENERATEMAIN = YES; +DOCICONFILES = (); +WINDOWS_BUILDTOOL = $NEXT_ROOT/NextDeveloper/Executables/make; +MAKEFILEDIR = "$(NEXT_ROOT)/NextDeveloper/Makefiles/pb_makefiles"; +NEXTSTEP_BUILDTOOL = /bin/gnumake; +DOCEXTENSIONS = (); +PROJECTTYPE = Tool; +PROJECTVERSION = 2.6; +LOCALIZABLE_FILES = { +}; +PROJECTNAME = "class-dump"; +PDO_UNIX_BUILDTOOL = $NEXT_ROOT/NextDeveloper/bin/make; + diff --git a/ObjcCategory.h b/ObjcCategory.h new file mode 100644 index 00000000..05df2ea0 --- /dev/null +++ b/ObjcCategory.h @@ -0,0 +1,55 @@ +// +// $Id: ObjcCategory.h,v 1.1 1999/07/31 03:32:27 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 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@telusplanet.net +// + +#if NS_TARGET_MAJOR >= 4 +#import +#else +#import +#import +#endif +#import "ObjcThing.h" + +@interface ObjcCategory : ObjcThing +{ + NSString *class_name; + NSString *category_name; + NSMutableArray *class_methods; + NSMutableArray *instance_methods; + NSMutableArray *protocols; +} + +- initWithClassName:(NSString *)className categoryName:(NSString *)categoryName; +- (void) dealloc; + +- (NSString *) sortableName; + +- (void) addClassMethods:(NSArray *)newClassMethods; +- (void) addInstanceMethods:(NSArray *)newInstanceMethods; + +- (void) showDefinition:(int)flags; + +@end diff --git a/ObjcCategory.m b/ObjcCategory.m new file mode 100644 index 00000000..9de0d6f2 --- /dev/null +++ b/ObjcCategory.m @@ -0,0 +1,117 @@ +// +// $Id: ObjcCategory.m,v 1.1 1999/07/31 03:32:26 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 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@telusplanet.net +// + +#import "ObjcCategory.h" +#import "ObjcMethod.h" +#if NS_TARGET_MAJOR < 4 +#import +#endif +#import + +@implementation ObjcCategory + +- initWithClassName:(NSString *)className categoryName:(NSString *)categoryName +{ + if ([super init] == nil) + return nil; + + class_name = [className retain]; + category_name = [categoryName retain]; + class_methods = [[NSMutableArray array] retain]; + instance_methods = [[NSMutableArray array] retain]; + protocols = [[NSMutableArray array] retain]; + + return self; +} + +- (void) dealloc +{ + [class_name release]; + [category_name release]; + [class_methods release]; + [instance_methods release]; + [protocols release]; + + [super dealloc]; +} + +- (NSString *) sortableName +{ + return [NSString stringWithFormat:@"%@ %@", class_name, category_name]; +} + +- (void) addClassMethods:(NSArray *)newClassMethods +{ + [class_methods addObjectsFromArray:newClassMethods]; +} + +- (void) addInstanceMethods:(NSArray *)newInstanceMethods +{ + [instance_methods addObjectsFromArray:newInstanceMethods]; +} + +- (void) showDefinition:(int)flags +{ + NSEnumerator *enumerator; + ObjcMethod *method; + + printf ("@interface %s(%s)\n", [class_name cString], [category_name cString]); + + if (flags & F_SORT_METHODS) + enumerator = [[class_methods sortedArrayUsingSelector:@selector (orderByMethodName:)] objectEnumerator]; + else + enumerator = [class_methods reverseObjectEnumerator]; + + while (method = [enumerator nextObject]) + { + [method showMethod:'+']; + if (flags & F_SHOW_METHOD_ADDRESS) + { + printf ("\t// IMP=0x%08lx", [method address]); + } + printf ("\n"); + } + + if (flags & F_SORT_METHODS) + enumerator = [[instance_methods sortedArrayUsingSelector:@selector (orderByMethodName:)] objectEnumerator]; + else + enumerator = [instance_methods reverseObjectEnumerator]; + + while (method = [enumerator nextObject]) + { + [method showMethod:'-']; + if (flags & F_SHOW_METHOD_ADDRESS) + { + printf ("\t// IMP=0x%08lx", [method address]); + } + printf ("\n"); + } + + printf ("@end\n\n"); +} + +@end diff --git a/ObjcClass.h b/ObjcClass.h new file mode 100644 index 00000000..e5c7d50c --- /dev/null +++ b/ObjcClass.h @@ -0,0 +1,62 @@ +// +// $Id: ObjcClass.h,v 1.1 1999/07/31 03:32:26 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 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@telusplanet.net +// + +#if NS_TARGET_MAJOR >= 4 +#import +#else +#import +#import +#endif +#import "ObjcThing.h" + +@interface ObjcClass : ObjcThing +{ + NSString *class_name; + NSString *super_class_name; + NSMutableArray *ivars; + NSMutableArray *class_methods; + NSMutableArray *instance_methods; + NSMutableArray *protocol_names; +} + +- initWithClassName:(NSString *)className superClassName:(NSString *)superClassName; +- (void) dealloc; + +- (NSString *) description; +- (NSString *) className; +- (NSArray *) protocolNames; + +- (NSString *) sortableName; + +- (void) addIvars:(NSArray *)ivars; +- (void) addClassMethods:(NSArray *)newClassMethods; +- (void) addInstanceMethods:(NSArray *)newInstanceMethods; +- (void) addProtocolNames:(NSArray *)newProtocolNames; + +- (void) showDefinition:(int)flags; + +@end diff --git a/ObjcClass.m b/ObjcClass.m new file mode 100644 index 00000000..ffe60f9f --- /dev/null +++ b/ObjcClass.m @@ -0,0 +1,186 @@ +// +// $Id: ObjcClass.m,v 1.1 1999/07/31 03:32:26 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 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@telusplanet.net +// + +#import "ObjcClass.h" +#include "datatypes.h" +#import "ObjcIvar.h" +#import "ObjcMethod.h" +#if NS_TARGET_MAJOR < 4 +#import +#endif +#import + +@implementation ObjcClass + +- initWithClassName:(NSString *)className superClassName:(NSString *)superClassName +{ + if ([super init] == nil) + return nil; + + class_name = [className retain]; + super_class_name = [superClassName retain]; + ivars = [[NSMutableArray array] retain]; + class_methods = [[NSMutableArray array] retain]; + instance_methods = [[NSMutableArray array] retain]; + protocol_names = [[NSMutableArray array] retain]; + + return self; +} + +- (void) dealloc +{ + [class_name release]; + [super_class_name release]; + [ivars release]; + [class_methods release]; + [instance_methods release]; + [protocol_names release]; + + [super dealloc]; +} + +- (void) addIvars:(NSArray *)newIvars +{ + [ivars addObjectsFromArray:newIvars]; +} + +- (NSString *) description +{ + return [NSString stringWithFormat:@"@interface %@:%@ {\n%@\n}\n%@\n%@", + class_name, super_class_name, ivars, class_methods, instance_methods]; +} + +- (NSString *) className +{ + return class_name; +} + +- (NSArray *) protocolNames +{ + return protocol_names; +} + +- (NSString *) sortableName +{ + return class_name; +} + +- (void) addClassMethods:(NSArray *)newClassMethods +{ + [class_methods addObjectsFromArray:newClassMethods]; +} + +- (void) addInstanceMethods:(NSArray *)newInstanceMethods +{ + [instance_methods addObjectsFromArray:newInstanceMethods]; +} + +- (void) addProtocolNames:(NSArray *)newProtocolNames +{ + [protocol_names addObjectsFromArray:newProtocolNames]; +} + +- (void) showDefinition:(int)flags +{ + NSEnumerator *enumerator; + ObjcIvar *ivar; + ObjcMethod *method; + NSString *protocolName; + + printf ("@interface %s", [class_name cString]); + if (super_class_name != nil) + printf (":%s", [super_class_name cString]); + + if ([protocol_names count] > 0) + { + enumerator = [protocol_names objectEnumerator]; + printf (" <"); + protocolName = [enumerator nextObject]; + if (protocolName != nil) + { + printf ("%s", [protocolName cString]); + + while (protocolName = [enumerator nextObject]) + { + printf (", %s", [protocolName cString]); + } + } + + printf (">"); + } + + printf ("\n{\n"); + + enumerator = [ivars objectEnumerator]; + while (ivar = [enumerator nextObject]) + { + [ivar showIvarAtLevel:2]; + if (flags & F_SHOW_IVAR_OFFSET) + { + printf ("\t// %ld = 0x%lx", [ivar offset], [ivar offset]); + } + printf ("\n"); + } + + //printf ("%s\n", [[ivars description] cString]); + printf ("}\n\n"); + + //NSLog (@"class_methods: %@", class_methods); + + if (flags & F_SORT_METHODS) + enumerator = [[class_methods sortedArrayUsingSelector:@selector (orderByMethodName:)] objectEnumerator]; + else + enumerator = [class_methods reverseObjectEnumerator]; + + while (method = [enumerator nextObject]) + { + [method showMethod:'+']; + if (flags & F_SHOW_METHOD_ADDRESS) + { + printf ("\t// IMP=0x%08lx", [method address]); + } + printf ("\n"); + } + + if (flags & F_SORT_METHODS) + enumerator = [[instance_methods sortedArrayUsingSelector:@selector (orderByMethodName:)] objectEnumerator]; + else + enumerator = [instance_methods reverseObjectEnumerator]; + while (method = [enumerator nextObject]) + { + [method showMethod:'-']; + if (flags & F_SHOW_METHOD_ADDRESS) + { + printf ("\t// IMP=0x%08lx", [method address]); + } + printf ("\n"); + } + + printf ("\n@end\n\n"); +} + +@end diff --git a/ObjcIvar.h b/ObjcIvar.h new file mode 100644 index 00000000..f14c62e2 --- /dev/null +++ b/ObjcIvar.h @@ -0,0 +1,49 @@ +// +// $Id: ObjcIvar.h,v 1.1 1999/07/31 03:32:26 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 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@telusplanet.net +// + +#if NS_TARGET_MAJOR >= 4 +#import +#else +#import +#endif + +@interface ObjcIvar : NSObject +{ + NSString *ivar_name; + NSString *ivar_type; + long ivar_offset; +} + +- initWithName:(NSString *)ivarName type:(NSString *)ivarType offset:(long)ivarOffset; +- (void) dealloc; + +- (NSString *) description; + +- (long) offset; +- (void) showIvarAtLevel:(int)level; + +@end diff --git a/ObjcIvar.m b/ObjcIvar.m new file mode 100644 index 00000000..d3ec7347 --- /dev/null +++ b/ObjcIvar.m @@ -0,0 +1,68 @@ +// +// $Id: ObjcIvar.m,v 1.1 1999/07/31 03:32:26 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 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@telusplanet.net +// + +#import "ObjcIvar.h" +#include "datatypes.h" + +@implementation ObjcIvar + +- initWithName:(NSString *)ivarName type:(NSString *)ivarType offset:(long)ivarOffset +{ + if ([super init] == nil) + return nil; + + ivar_name = [ivarName retain]; + ivar_type = [ivarType retain]; + ivar_offset = ivarOffset; + + return self; +} + +- (void) dealloc +{ + [ivar_name release]; + [ivar_type release]; + + [super dealloc]; +} + +- (NSString *) description +{ + return [NSString stringWithFormat:@"%@/%@\t// %x", ivar_name, ivar_type, ivar_offset]; +} + +- (long) offset +{ + return ivar_offset; +} + +- (void) showIvarAtLevel:(int)level +{ + format_type ([ivar_type cString], [ivar_name cString], level); +} + +@end diff --git a/ObjcMethod.h b/ObjcMethod.h new file mode 100644 index 00000000..905c2ad0 --- /dev/null +++ b/ObjcMethod.h @@ -0,0 +1,54 @@ +// +// $Id: ObjcMethod.h,v 1.1 1999/07/31 03:32:26 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 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@telusplanet.net +// + +#if NS_TARGET_MAJOR >= 4 +#import +#else +#import +#endif + +@interface ObjcMethod : NSObject +{ + NSString *method_name; + NSString *method_type; + BOOL is_protocol_method; + long method_address; // Note: protocols will not have method addresses +} + +- initWithMethodName:(NSString *)methodName type:(NSString *)methodType; +- initWithMethodName:(NSString *)methodName type:(NSString *)methodType address:(long)methodAddress; +- (void) dealloc; + +- (NSString *) description; +- (NSString *) methodName; +- (long) address; + +- (void) showMethod:(char)prefix; + +- (NSComparisonResult) orderByMethodName:(ObjcMethod *)otherMethod; + +@end diff --git a/ObjcMethod.m b/ObjcMethod.m new file mode 100644 index 00000000..bf158235 --- /dev/null +++ b/ObjcMethod.m @@ -0,0 +1,89 @@ +// +// $Id: ObjcMethod.m,v 1.1 1999/07/31 03:32:26 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 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@telusplanet.net +// + +#import "ObjcMethod.h" +#include "datatypes.h" + +@implementation ObjcMethod + +- initWithMethodName:(NSString *)methodName type:(NSString *)methodType +{ + if ([self initWithMethodName:methodName type:methodType address:0] == nil) + return nil; + + is_protocol_method = YES; + + return self; +} + +- initWithMethodName:(NSString *)methodName type:(NSString *)methodType address:(long)methodAddress +{ + [super init]; + + method_name = [methodName retain]; + method_type = [methodType retain]; + method_address = methodAddress; + is_protocol_method = NO; + + return self; +} + +- (void) dealloc +{ + [method_name release]; + [method_type release]; + + [super dealloc]; +} + +- (NSString *) description +{ + return [NSString stringWithFormat:@"%@/%@\t// %x", method_name, method_type, method_address]; +} + +- (NSString *) methodName +{ + return method_name; +} + +- (long) address +{ + return method_address; +} + +- (void) showMethod:(char)prefix +{ + format_method (prefix, [method_name cString], [method_type cString]); +} + +- (NSComparisonResult) orderByMethodName:(ObjcMethod *)otherMethod +{ + return [method_name compare:[otherMethod methodName]]; +} + + +@end diff --git a/ObjcProtocol.h b/ObjcProtocol.h new file mode 100644 index 00000000..87518345 --- /dev/null +++ b/ObjcProtocol.h @@ -0,0 +1,56 @@ +// +// $Id: ObjcProtocol.h,v 1.1 1999/07/31 03:32:26 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 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@telusplanet.net +// + +#if NS_TARGET_MAJOR >= 4 +#import +#else +#import +#import +#endif +#import "ObjcThing.h" +#import "ObjcMethod.h" + +@interface ObjcProtocol : ObjcThing +{ + NSString *protocol_name; + NSMutableArray *protocol_names; + NSMutableArray *protocol_methods; +} + +- initWithProtocolName:(NSString *)protocolName; +- (void) dealloc; + +- (NSString *) protocolName; +- (NSString *) sortableName; + +- (void) addProtocolNames:(NSArray *)newProtocolNames; +- (void) addProtocolMethod:(ObjcMethod *)newMethod; +- (void) addProtocolMethods:(NSArray *)newProtocolMethods; + +- (void) showDefinition:(int)flags; + +@end diff --git a/ObjcProtocol.m b/ObjcProtocol.m new file mode 100644 index 00000000..7b8412ca --- /dev/null +++ b/ObjcProtocol.m @@ -0,0 +1,128 @@ +// +// $Id: ObjcProtocol.m,v 1.1 1999/07/31 03:32:26 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 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@telusplanet.net +// + +#import "ObjcProtocol.h" +#if NS_TARGET_MAJOR < 4 +#import +#endif +#import + +@implementation ObjcProtocol + +- initWithProtocolName:(NSString *)protocolName +{ + if ([super init] == nil) + return nil; + + protocol_name = [protocolName retain]; + protocol_names = [[NSMutableArray array] retain]; + protocol_methods = [[NSMutableArray array] retain]; + + return self; +} + +- (void) dealloc +{ + [protocol_name release]; + [protocol_names release]; + [protocol_methods release]; + + [super dealloc]; +} + +- (NSString *) protocolName +{ + return protocol_name; +} + +- (NSString *) sortableName +{ + return protocol_name; +} + +- (void) addProtocolNames:(NSArray *)newProtocolNames +{ + [protocol_names addObjectsFromArray:newProtocolNames]; +} + +- (void) addProtocolMethod:(ObjcMethod *)newMethod +{ + [protocol_methods addObject:newMethod]; +} + +- (void) addProtocolMethods:(NSArray *)newProtocolMethods +{ + [protocol_methods addObjectsFromArray:newProtocolMethods]; +} + +- (void) showDefinition:(int)flags +{ + NSEnumerator *enumerator; + ObjcMethod *method; + NSString *protocolName; + + printf ("@protocol %s", [protocol_name cString]); + + if ([protocol_names count] > 0) + { + enumerator = [protocol_names objectEnumerator]; + printf (" <"); + protocolName = [enumerator nextObject]; + if (protocolName != nil) + { + printf ("%s", [protocolName cString]); + + while (protocolName = [enumerator nextObject]) + { + printf (", %s", [protocolName cString]); + } + } + + printf (">"); + } + + printf ("\n"); + + if (flags & F_SORT_METHODS) + enumerator = [[protocol_methods sortedArrayUsingSelector:@selector (orderByMethodName:)] objectEnumerator]; + else + enumerator = [protocol_methods objectEnumerator]; + + while (method = [enumerator nextObject]) + { + [method showMethod:'-']; + if (flags & F_SHOW_METHOD_ADDRESS) + { + printf ("\t// IMP=0x%08lx", [method address]); + } + printf ("\n"); + } + + printf ("@end\n\n"); +} + +@end diff --git a/ObjcThing.h b/ObjcThing.h new file mode 100644 index 00000000..f24423b4 --- /dev/null +++ b/ObjcThing.h @@ -0,0 +1,48 @@ +// +// $Id: ObjcThing.h,v 1.1 1999/07/31 03:32:26 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 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@telusplanet.net +// + +#if NS_TARGET_MAJOR >= 4 +#import +#else +#import +#endif + +#define F_SORT_METHODS (1 << 0) +#define F_SHOW_IVAR_OFFSET (1 << 1) +#define F_SHOW_METHOD_ADDRESS (1 << 2) + +@interface ObjcThing : NSObject +{ +} + +- (NSString *) sortableName; + +- (void) showDefinition:(int)flags; + +- (NSComparisonResult) orderByName:(ObjcThing *)otherThing; + +@end diff --git a/ObjcThing.m b/ObjcThing.m new file mode 100644 index 00000000..80ddde28 --- /dev/null +++ b/ObjcThing.m @@ -0,0 +1,46 @@ +// +// $Id: ObjcThing.m,v 1.1 1999/07/31 03:32:27 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 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@telusplanet.net +// + +#import "ObjcThing.h" + +@implementation ObjcThing + +- (NSString *) sortableName +{ + return @""; +} + +- (void) showDefinition:(int)flags +{ +} + +- (NSComparisonResult) orderByName:(ObjcThing *)otherThing +{ + return [[self sortableName] compare:[otherThing sortableName]]; +} + +@end diff --git a/Openstep/Makefile b/Openstep/Makefile new file mode 100644 index 00000000..71d437ca --- /dev/null +++ b/Openstep/Makefile @@ -0,0 +1,53 @@ +# +# Generated by the NeXT Project Builder. +# +# NOTE: Do NOT change this file -- Project Builder maintains it. +# +# Put all of your customizations in files called Makefile.preamble +# and Makefile.postamble (both optional), and Makefile will include them. +# + +NAME = class-dump + +PROJECTVERSION = 2.6 +PROJECT_TYPE = Tool +LANGUAGE = English + +CLASSES = MappedFile.m ObjcCategory.m ObjcClass.m ObjcIvar.m\ + ObjcMethod.m ObjcProtocol.m ObjcThing.m + +HFILES = class-dump.h datatypes.h MappedFile.h ObjcCategory.h\ + ObjcClass.h ObjcIvar.h ObjcMethod.h ObjcProtocol.h\ + ObjcThing.h my_regex.h + +OTHERLINKED = gram.y + +MFILES = class-dump.m datatypes.m + +CFILES = lexer.c my_regex.c + +OTHERSRCS = Makefile.preamble Makefile Makefile.postamble m.template\ + h.template + +OTHERLINKEDOFILES = gram.o + +MAKEFILEDIR = $(NEXT_ROOT)/NextDeveloper/Makefiles/pb_makefiles +CODE_GEN_STYLE = DYNAMIC +MAKEFILE = tool.make +LIBS = +DEBUG_LIBS = $(LIBS) +PROF_LIBS = $(LIBS) + + +FRAMEWORKS = -framework Foundation + + +include $(MAKEFILEDIR)/platform.make + +-include Makefile.preamble + +include $(MAKEFILEDIR)/$(MAKEFILE) + +-include Makefile.postamble + +-include Makefile.dependencies diff --git a/Openstep/Makefile.postamble b/Openstep/Makefile.postamble new file mode 100644 index 00000000..661fb61d --- /dev/null +++ b/Openstep/Makefile.postamble @@ -0,0 +1,126 @@ +############################################################################### +# NeXT Makefile.postamble +# Copyright 1996, NeXT Software, Inc. +# +# This Makefile is used for configuring the standard app makefiles associated +# with ProjectBuilder. +# +# Use this template to set attributes for a project, sub-project, bundle, or +# palette. Each node in the project's tree of sub-projects and bundles +# should have it's own Makefile.preamble and Makefile.postamble. Additional +# rules (e.g., after_install) that are defined by the developer should be +# defined in this file. +# +############################################################################### +# +# Here are the variables exported by the common "app" makefiles that can be +# used in any customizations you make to the template below: +# +# PRODUCT_ROOT - Name of the directory to which resources are copied. +# OFILE_DIR - Directory into which .o object files are generated. +# (Note that this name is calculated based on the target +# architectures specified in Project Builder). +# DERIVED_SRC_DIR - Directory used for all other derived files +# ALL_CFLAGS - All the flags passed to the cc(1) driver for compilations +# +# NAME - name of application, bundle, subproject, palette, etc. +# LANGUAGE - langage in which the project is written (default "English") +# LOCAL_RESOURCES - localized resources (e.g. nib's, images) of project +# GLOBAL_RESOURCES - non-localized resources of project +# PROJECTVERSION - version of ProjectBuilder project (NS3.X = 1.1, NS4.0 = 2.0) +# ICONSECTIONS - Specifies icon sections when linking executable +# +# CLASSES - Class implementation files in project. +# HFILES - Header files in project. +# MFILES - Other Objective-C source files in project. +# CFILES - Other C source files in project. +# PSWFILES - .psw files in the project +# PSWMFILES - .pswm files in the project +# SUBPROJECTS - Subprojects of this project +# BUNDLES - Bundle subprojects of this project +# OTHERSRCS - Other miscellaneous sources of this project +# OTHERLINKED - Source files not matching a standard source extention +# +# LIBS - Libraries to link with when making app target +# DEBUG_LIBS - Libraries to link with when making debug target +# PROF_LIBS - Libraries to link with when making profile target +# OTHERLINKEDOFILES - Other relocatable files to (always) link in. +# +# APP_MAKEFILE_DIR - Directory in which to find generic set of Makefiles +# MAKEFILEDIR - Directory in which to find $(MAKEFILE) +# MAKEFILE - Top level mechanism Makefile (e.g., app.make, bundle.make) +# INSTALLDIR - Directory app will be installed into by 'install' target +# +############################################################################### + + +# Change defaults assumed by the standard makefiles here. Edit the +# following default values as appropriate. (Note that if no Makefile.postamble +# exists, these values will have defaults set in common.make). + +# Versioning of frameworks, libraries, bundles, and palettes: +#CURRENTLY_ACTIVE_VERSION = YES + # Set to "NO" to produce a compatibility binary +#DEPLOY_WITH_VERSION_NAME = A + # This should be incremented as your API changes. +#COMPATIBILITY_PROJECT_VERSION = 1 + # This should be incremented as your API grows. +#CURRENT_PROJECT_VERSION = 1 + # Defaults to using the "vers_string" hack. + +# Some compiler flags can be easily overridden here, but onlytake effect at +# the top-level: +#OPTIMIZATION_CFLAG = -O +#DEBUG_SYMBOLS_CFLAG = -g +#WARNING_CFLAGS = -Wmost +#DEBUG_BUILD_CFLAGS = -DDEBUG +#PROFILE_BUILD_CFLAGS = -pg -DPROFILE + +# This definition will suppress stripping of debug symbols when an executable +# is installed. By default it is YES. +# STRIP_ON_INSTALL = NO + +# Flags passed to yacc +#YFLAGS = -d + +# Library and Framework projects only: +# 1. If you want something other than the default .dylib name, override it here +#DYLIB_INSTALL_NAME = lib$(NAME).dylib + +# 2. If you want to change the -install_name flag from the absolute path to the development area, change it here. One good choice is the installation directory. Another one might be none at all. +#DYLIB_INSTALL_DIR = $(INSTALLDIR) + +# Ownership and permissions of files installed by 'install' target +#INSTALL_AS_USER = root + # User/group ownership +#INSTALL_AS_GROUP = wheel + # (probably want to set both of these) +#INSTALL_PERMISSIONS = + # If set, 'install' chmod's executable to this + +# Options to strip for various project types. Note: -S strips debugging symbols +# (executables can be stripped down further with -x or, if they load no bundles, with no +# options at all). +#APP_STRIP_OPTS = -S +#TOOL_STRIP_OPTS = -S +#LIBRARY_STRIP_OPTS = -S + # for .a archives +#DYNAMIC_STRIP_OPTS = -S + # for bundles and shared libraries + +######################################################################### +# Put rules to extend the behavior of the standard Makefiles here. "Official" +# user-defined rules are: +# * before_install +# * after_install +# * after_installhdrs +# You should avoid redefining things like "install" or "app", as they are +# owned by the top-level Makefile API and no context has been set up for where +# derived files should go. +# +# Note: on MS Windows, executables, have an extension, so rules and dependencies +# for generated tools should use $(EXECUTABLE_EXT) on the end. + +YACC = bison +LEX = flex + diff --git a/Openstep/Makefile.preamble b/Openstep/Makefile.preamble new file mode 100644 index 00000000..59867374 --- /dev/null +++ b/Openstep/Makefile.preamble @@ -0,0 +1,130 @@ +############################################################################### +# NeXT Makefile.preamble +# Copyright 1996, NeXT Software, Inc. +# +# This Makefile is used for configuring the standard app makefiles associated +# with ProjectBuilder. +# +# Use this template to set attributes for a project. Each node in a project +# tree of sub-projects, tools, etc. should have its own Makefile.preamble and +# Makefile.postamble. +# +############################################################################### +## Configure the flags passed to $(CC) here. These flags will also be +## inherited by all nested sub-projects and bundles. Put your -I, -D, -U, and +## -L flags in ProjectBuilder's Build Options inspector if at all possible. +## To change the default flags that get passed to ${CC} +## (e.g. change -O to -O2), see Makefile.postamble. + +# Flags passed to compiler (in addition to -g, -O, etc) +OTHER_CFLAGS = +# Flags passed to ld (in addition to -ObjC, etc.) +OTHER_LDFLAGS = +# Flags passed to libtool when building libraries +OTHER_LIBTOOL_FLAGS = +# For ordering named sections on NEXTSTEP (see ld(1)) +SECTORDER_FLAGS = + +# If you do not want any headers exported before compilations begin, +# uncomment the following line. This can be a big time saver. +#SKIP_EXPORTING_HEADERS = YES + +# Stuff related to exporting headers from this project that isn't already +# handled by PB. +OTHER_PUBLIC_HEADERS = +OTHER_PROJECT_HEADERS = +OTHER_PRIVATE_HEADERS = + +# Set these two macros if you want a precomp to be built as part of +# installation. The cc -precomp will be run in the public header directory +# on the specified public header files with the specified additional flags. +PUBLIC_PRECOMPILED_HEADERS = +PUBLIC_PRECOMPILED_HEADERS_CFLAGS = + +# Set this for library projects if you want to publish header files. If your +# app or tool project exports headers Don't +# include $(DSTROOT); this is added for you automatically. +PUBLIC_HEADER_DIR = +PRIVATE_HEADER_DIR = + +# If, in a subproject, you want to append to the parent's PUBLIC_HEADER_DIR# +# (say, to add a subdirectory like "/sys"), you can use: +PUBLIC_HEADER_DIR_SUFFIX = +PRIVATE_HEADER_DIR_SUFFIX = + +# Set this for dynamic library projects on platforms where code which references +# a dynamic library must link against an import library (i.e., Windows NT) +# Don't include $(DSTROOT); this is added for you automatically. +IMPORT_LIBRARY_DIR = + +# Additional (non-localized) resources for this project, which can be generated +OTHER_RESOURCES = + +# Uncomment this to produce a static archive-style (.a) library +#LIBRARY_STYLE = STATIC + +# Set this to YES if you don't want a final libtool call for a library/framework. +BUILD_OFILES_LIST_ONLY = + +# Additional relocatables to be linked into this project +OTHER_OFILES = +# Additional libraries to link against +OTHER_LIBS = +# To include a version string, project source must exist in a directory named +# $(NAME).%d[.%d][.%d] and the following line must be uncommented. +# OTHER_GENERATED_OFILES = $(VERS_OFILE) + +## Configure how things get built here. Additional dependencies, source files, +## derived files, and build order should be specified here. + +# Other dependencies of this project +OTHER_PRODUCT_DEPENDS = +# Built *before* building subprojects/bundles +OTHER_INITIAL_TARGETS = +# Other source files maintained by .pre/postamble +OTHER_SOURCEFILES = +# Additional files to be removed by `make clean' +OTHER_GARBAGE = + +# Targets to build before installation +OTHER_INSTALL_DEPENDS = + +# More obscure flags you might want to set for pswrap, yacc, lex, etc. +PSWFLAGS = +YFLAGS = --yacc +LFLAGS = + +## Delete this line if you want fast and loose cleans that will not remove +## things like precomps and user-defined OTHER_GARBAGE in subprojects. +CLEAN_ALL_SUBPROJECTS = YES + +## Add more obscure source files here to cause them to be automatically +## processed by the appropriate tool. Note that these files should also be +## added to "Supporting Files" in ProjectBuilder. The desired .o files that +## result from these files should also be added to OTHER_OFILES above so they +## will be linked in. + +# .msg files that should have msgwrap run on them +MSGFILES = +# .defs files that should have mig run on them +DEFSFILES = +# .mig files (no .defs files) that should have mig run on them +MIGFILES = +# .x files that should have rpcgen run on them +RPCFILES = + +## Add additional Help directories here (add them to the project as "Other +## Resources" in Project Builder) so that they will be compressed into .store +## files and copied into the app wrapper. If the help directories themselves +## need to also be in the app wrapper, then a cp command will need to be added +## in an after_install target. +OTHER_HELP_DIRS = + +# After you have saved your project using the 4.0 PB, you will automatically +# start using the makefiles in /NextDeveloper/Makefiles/project. If you should +# need to revert back to the old 3.3 Makefile behavior, override MAKEFILEDIR to +# be /NextDeveloper/Makefiles/app. + +# Don't add more rules here unless you want the first one to be the default +# target for make! Put all your targets in Makefile.postamble. + diff --git a/Openstep/PB.project b/Openstep/PB.project new file mode 100644 index 00000000..0d1e6716 --- /dev/null +++ b/Openstep/PB.project @@ -0,0 +1,46 @@ +{ + DYNAMIC_CODE_GEN = YES; + FILESTABLE = { + BUNDLES = (); + CLASSES = ( + MappedFile.m, + ObjcCategory.m, + ObjcClass.m, + ObjcIvar.m, + ObjcMethod.m, + ObjcProtocol.m, + ObjcThing.m + ); + FRAMEWORKS = (Foundation.framework); + H_FILES = ( + "class-dump.h", + datatypes.h, + MappedFile.h, + ObjcCategory.h, + ObjcClass.h, + ObjcIvar.h, + ObjcMethod.h, + ObjcProtocol.h, + ObjcThing.h, + my_regex.h + ); + LIBS = (); + OTHER_LIBS = (); + OTHER_LINKED = (gram.y, lexer.c, "class-dump.m", datatypes.m, my_regex.c); + OTHER_SOURCES = (Makefile.preamble, Makefile, Makefile.postamble, m.template, h.template); + PRECOMPILED_HEADERS = (); + PROJECT_HEADERS = (); + PUBLIC_HEADERS = (); + SUBPROJECTS = (); + TOOLS = (); + }; + LANGUAGE = English; + LOCALIZABLE_FILES = {}; + MAKEFILEDIR = "$(NEXT_ROOT)/NextDeveloper/Makefiles/pb_makefiles"; + NEXTSTEP_BUILDTOOL = /bin/gnumake; + PDO_UNIX_BUILDTOOL = $NEXT_ROOT/NextDeveloper/bin/make; + PROJECTNAME = "class-dump"; + PROJECTTYPE = Tool; + PROJECTVERSION = 2.6; + WINDOWS_BUILDTOOL = $NEXT_ROOT/NextDeveloper/Executables/make; +} diff --git a/Rhapsody/Makefile b/Rhapsody/Makefile new file mode 100644 index 00000000..f8444245 --- /dev/null +++ b/Rhapsody/Makefile @@ -0,0 +1,60 @@ +# +# Generated by the NeXT Project Builder. +# +# NOTE: Do NOT change this file -- Project Builder maintains it. +# +# Put all of your customizations in files called Makefile.preamble +# and Makefile.postamble (both optional), and Makefile will include them. +# + +NAME = class-dump + +PROJECTVERSION = 2.7 +PROJECT_TYPE = Tool +LANGUAGE = English + +CLASSES = MappedFile.m ObjcCategory.m ObjcClass.m ObjcIvar.m\ + ObjcMethod.m ObjcProtocol.m ObjcThing.m + +HFILES = class-dump.h datatypes.h MappedFile.h ObjcCategory.h\ + ObjcClass.h ObjcIvar.h ObjcMethod.h ObjcProtocol.h\ + ObjcThing.h my_regex.h + +OTHERLINKED = gram.y + +MFILES = class-dump.m datatypes.m + +CFILES = lexer.c my_regex.c + +OTHERSRCS = Makefile.preamble Makefile Makefile.postamble m.template\ + h.template + +OTHERLINKEDOFILES = gram.o + +MAKEFILEDIR = $(MAKEFILEPATH)/pb_makefiles +CODE_GEN_STYLE = DYNAMIC +MAKEFILE = tool.make +LIBS = +DEBUG_LIBS = $(LIBS) +PROF_LIBS = $(LIBS) + + +FRAMEWORKS = -framework Foundation + + +NEXTSTEP_OBJCPLUS_COMPILER = /usr/bin/cc +WINDOWS_OBJCPLUS_COMPILER = $(DEVDIR)/gcc +PDO_UNIX_OBJCPLUS_COMPILER = $(NEXTDEV_BIN)/gcc +NEXTSTEP_JAVA_COMPILER = /usr/bin/javac +WINDOWS_JAVA_COMPILER = $(JDKBINDIR)/javac.exe +PDO_UNIX_JAVA_COMPILER = $(NEXTDEV_BIN)/javac + +include $(MAKEFILEDIR)/platform.make + +-include Makefile.preamble + +include $(MAKEFILEDIR)/$(MAKEFILE) + +-include Makefile.postamble + +-include Makefile.dependencies diff --git a/Rhapsody/Makefile.postamble b/Rhapsody/Makefile.postamble new file mode 100644 index 00000000..661fb61d --- /dev/null +++ b/Rhapsody/Makefile.postamble @@ -0,0 +1,126 @@ +############################################################################### +# NeXT Makefile.postamble +# Copyright 1996, NeXT Software, Inc. +# +# This Makefile is used for configuring the standard app makefiles associated +# with ProjectBuilder. +# +# Use this template to set attributes for a project, sub-project, bundle, or +# palette. Each node in the project's tree of sub-projects and bundles +# should have it's own Makefile.preamble and Makefile.postamble. Additional +# rules (e.g., after_install) that are defined by the developer should be +# defined in this file. +# +############################################################################### +# +# Here are the variables exported by the common "app" makefiles that can be +# used in any customizations you make to the template below: +# +# PRODUCT_ROOT - Name of the directory to which resources are copied. +# OFILE_DIR - Directory into which .o object files are generated. +# (Note that this name is calculated based on the target +# architectures specified in Project Builder). +# DERIVED_SRC_DIR - Directory used for all other derived files +# ALL_CFLAGS - All the flags passed to the cc(1) driver for compilations +# +# NAME - name of application, bundle, subproject, palette, etc. +# LANGUAGE - langage in which the project is written (default "English") +# LOCAL_RESOURCES - localized resources (e.g. nib's, images) of project +# GLOBAL_RESOURCES - non-localized resources of project +# PROJECTVERSION - version of ProjectBuilder project (NS3.X = 1.1, NS4.0 = 2.0) +# ICONSECTIONS - Specifies icon sections when linking executable +# +# CLASSES - Class implementation files in project. +# HFILES - Header files in project. +# MFILES - Other Objective-C source files in project. +# CFILES - Other C source files in project. +# PSWFILES - .psw files in the project +# PSWMFILES - .pswm files in the project +# SUBPROJECTS - Subprojects of this project +# BUNDLES - Bundle subprojects of this project +# OTHERSRCS - Other miscellaneous sources of this project +# OTHERLINKED - Source files not matching a standard source extention +# +# LIBS - Libraries to link with when making app target +# DEBUG_LIBS - Libraries to link with when making debug target +# PROF_LIBS - Libraries to link with when making profile target +# OTHERLINKEDOFILES - Other relocatable files to (always) link in. +# +# APP_MAKEFILE_DIR - Directory in which to find generic set of Makefiles +# MAKEFILEDIR - Directory in which to find $(MAKEFILE) +# MAKEFILE - Top level mechanism Makefile (e.g., app.make, bundle.make) +# INSTALLDIR - Directory app will be installed into by 'install' target +# +############################################################################### + + +# Change defaults assumed by the standard makefiles here. Edit the +# following default values as appropriate. (Note that if no Makefile.postamble +# exists, these values will have defaults set in common.make). + +# Versioning of frameworks, libraries, bundles, and palettes: +#CURRENTLY_ACTIVE_VERSION = YES + # Set to "NO" to produce a compatibility binary +#DEPLOY_WITH_VERSION_NAME = A + # This should be incremented as your API changes. +#COMPATIBILITY_PROJECT_VERSION = 1 + # This should be incremented as your API grows. +#CURRENT_PROJECT_VERSION = 1 + # Defaults to using the "vers_string" hack. + +# Some compiler flags can be easily overridden here, but onlytake effect at +# the top-level: +#OPTIMIZATION_CFLAG = -O +#DEBUG_SYMBOLS_CFLAG = -g +#WARNING_CFLAGS = -Wmost +#DEBUG_BUILD_CFLAGS = -DDEBUG +#PROFILE_BUILD_CFLAGS = -pg -DPROFILE + +# This definition will suppress stripping of debug symbols when an executable +# is installed. By default it is YES. +# STRIP_ON_INSTALL = NO + +# Flags passed to yacc +#YFLAGS = -d + +# Library and Framework projects only: +# 1. If you want something other than the default .dylib name, override it here +#DYLIB_INSTALL_NAME = lib$(NAME).dylib + +# 2. If you want to change the -install_name flag from the absolute path to the development area, change it here. One good choice is the installation directory. Another one might be none at all. +#DYLIB_INSTALL_DIR = $(INSTALLDIR) + +# Ownership and permissions of files installed by 'install' target +#INSTALL_AS_USER = root + # User/group ownership +#INSTALL_AS_GROUP = wheel + # (probably want to set both of these) +#INSTALL_PERMISSIONS = + # If set, 'install' chmod's executable to this + +# Options to strip for various project types. Note: -S strips debugging symbols +# (executables can be stripped down further with -x or, if they load no bundles, with no +# options at all). +#APP_STRIP_OPTS = -S +#TOOL_STRIP_OPTS = -S +#LIBRARY_STRIP_OPTS = -S + # for .a archives +#DYNAMIC_STRIP_OPTS = -S + # for bundles and shared libraries + +######################################################################### +# Put rules to extend the behavior of the standard Makefiles here. "Official" +# user-defined rules are: +# * before_install +# * after_install +# * after_installhdrs +# You should avoid redefining things like "install" or "app", as they are +# owned by the top-level Makefile API and no context has been set up for where +# derived files should go. +# +# Note: on MS Windows, executables, have an extension, so rules and dependencies +# for generated tools should use $(EXECUTABLE_EXT) on the end. + +YACC = bison +LEX = flex + diff --git a/Rhapsody/Makefile.preamble b/Rhapsody/Makefile.preamble new file mode 100644 index 00000000..1e000280 --- /dev/null +++ b/Rhapsody/Makefile.preamble @@ -0,0 +1,130 @@ +############################################################################### +# NeXT Makefile.preamble +# Copyright 1996, NeXT Software, Inc. +# +# This Makefile is used for configuring the standard app makefiles associated +# with ProjectBuilder. +# +# Use this template to set attributes for a project. Each node in a project +# tree of sub-projects, tools, etc. should have its own Makefile.preamble and +# Makefile.postamble. +# +############################################################################### +## Configure the flags passed to $(CC) here. These flags will also be +## inherited by all nested sub-projects and bundles. Put your -I, -D, -U, and +## -L flags in ProjectBuilder's Build Options inspector if at all possible. +## To change the default flags that get passed to ${CC} +## (e.g. change -O to -O2), see Makefile.postamble. + +# Flags passed to compiler (in addition to -g, -O, etc) +OTHER_CFLAGS = +# Flags passed to ld (in addition to -ObjC, etc.) +OTHER_LDFLAGS = +# Flags passed to libtool when building libraries +OTHER_LIBTOOL_FLAGS = +# For ordering named sections on NEXTSTEP (see ld(1)) +SECTORDER_FLAGS = + +# If you do not want any headers exported before compilations begin, +# uncomment the following line. This can be a big time saver. +#SKIP_EXPORTING_HEADERS = YES + +# Stuff related to exporting headers from this project that isn't already +# handled by PB. +OTHER_PUBLIC_HEADERS = +OTHER_PROJECT_HEADERS = +OTHER_PRIVATE_HEADERS = + +# Set these two macros if you want a precomp to be built as part of +# installation. The cc -precomp will be run in the public header directory +# on the specified public header files with the specified additional flags. +PUBLIC_PRECOMPILED_HEADERS = +PUBLIC_PRECOMPILED_HEADERS_CFLAGS = + +# Set this for library projects if you want to publish header files. If your +# app or tool project exports headers Don't +# include $(DSTROOT); this is added for you automatically. +PUBLIC_HEADER_DIR = +PRIVATE_HEADER_DIR = + +# If, in a subproject, you want to append to the parent's PUBLIC_HEADER_DIR# +# (say, to add a subdirectory like "/sys"), you can use: +PUBLIC_HEADER_DIR_SUFFIX = +PRIVATE_HEADER_DIR_SUFFIX = + +# Set this for dynamic library projects on platforms where code which references +# a dynamic library must link against an import library (i.e., Windows NT) +# Don't include $(DSTROOT); this is added for you automatically. +IMPORT_LIBRARY_DIR = + +# Additional (non-localized) resources for this project, which can be generated +OTHER_RESOURCES = + +# Uncomment this to produce a static archive-style (.a) library +#LIBRARY_STYLE = STATIC + +# Set this to YES if you don't want a final libtool call for a library/framework. +BUILD_OFILES_LIST_ONLY = + +# Additional relocatables to be linked into this project +OTHER_OFILES = +# Additional libraries to link against +OTHER_LIBS = +# To include a version string, project source must exist in a directory named +# $(NAME).%d[.%d][.%d] and the following line must be uncommented. +# OTHER_GENERATED_OFILES = $(VERS_OFILE) + +## Configure how things get built here. Additional dependencies, source files, +## derived files, and build order should be specified here. + +# Other dependencies of this project +OTHER_PRODUCT_DEPENDS = +# Built *before* building subprojects/bundles +OTHER_INITIAL_TARGETS = +# Other source files maintained by .pre/postamble +OTHER_SOURCEFILES = +# Additional files to be removed by `make clean' +OTHER_GARBAGE = + +# Targets to build before installation +OTHER_INSTALL_DEPENDS = + +# More obscure flags you might want to set for pswrap, yacc, lex, etc. +PSWFLAGS = +YFLAGS = --yacc +LFLAGS = + +## Delete this line if you want fast and loose cleans that will not remove +## things like precomps and user-defined OTHER_GARBAGE in subprojects. +CLEAN_ALL_SUBPROJECTS = YES + +## Add more obscure source files here to cause them to be automatically +## processed by the appropriate tool. Note that these files should also be +## added to "Supporting Files" in ProjectBuilder. The desired .o files that +## result from these files should also be added to OTHER_OFILES above so they +## will be linked in. + +# .msg files that should have msgwrap run on them +MSGFILES = +# .defs files that should have mig run on them +DEFSFILES = +# .mig files (no .defs files) that should have mig run on them +MIGFILES = +# .x files that should have rpcgen run on them +RPCFILES = + +## Add additional Help directories here (add them to the project as "Other +## Resources" in Project Builder) so that they will be compressed into .store +## files and copied into the app wrapper. If the help directories themselves +## need to also be in the app wrapper, then a cp command will need to be added +## in an after_install target. +OTHER_HELP_DIRS = + +# After you have saved your project using the 4.0 PB, you will automatically +# start using the makefiles in $(SYSTEM_DEVELOPER_DIR)/Makefiles/project. If you should +# need to revert back to the old 3.3 Makefile behavior, override MAKEFILEDIR to +# be $(SYSTEM_DEVELOPER_DIR)/Makefiles/app. + +# Don't add more rules here unless you want the first one to be the default +# target for make! Put all your targets in Makefile.postamble. + diff --git a/Rhapsody/PB.project b/Rhapsody/PB.project new file mode 100644 index 00000000..2ab92760 --- /dev/null +++ b/Rhapsody/PB.project @@ -0,0 +1,52 @@ +{ + DYNAMIC_CODE_GEN = YES; + FILESTABLE = { + BUNDLES = (); + CLASSES = ( + MappedFile.m, + ObjcCategory.m, + ObjcClass.m, + ObjcIvar.m, + ObjcMethod.m, + ObjcProtocol.m, + ObjcThing.m + ); + FRAMEWORKS = (Foundation.framework); + H_FILES = ( + "class-dump.h", + datatypes.h, + MappedFile.h, + ObjcCategory.h, + ObjcClass.h, + ObjcIvar.h, + ObjcMethod.h, + ObjcProtocol.h, + ObjcThing.h, + my_regex.h + ); + LIBS = (); + OTHER_LIBS = (); + OTHER_LINKED = (gram.y, lexer.c, "class-dump.m", datatypes.m, my_regex.c); + OTHER_SOURCES = (Makefile.preamble, Makefile, Makefile.postamble, m.template, h.template); + PRECOMPILED_HEADERS = (); + PROJECT_HEADERS = (); + PUBLIC_HEADERS = (); + SUBPROJECTS = (); + TOOLS = (); + }; + LANGUAGE = English; + LOCALIZABLE_FILES = {}; + MAKEFILEDIR = "$(MAKEFILEPATH)/pb_makefiles"; + NEXTSTEP_BUILDTOOL = /bin/gnumake; + NEXTSTEP_JAVA_COMPILER = /usr/bin/javac; + NEXTSTEP_OBJCPLUS_COMPILER = /usr/bin/cc; + PDO_UNIX_BUILDTOOL = $NEXT_ROOT/Developer/bin/make; + PDO_UNIX_JAVA_COMPILER = "$(NEXTDEV_BIN)/javac"; + PDO_UNIX_OBJCPLUS_COMPILER = "$(NEXTDEV_BIN)/gcc"; + PROJECTNAME = "class-dump"; + PROJECTTYPE = Tool; + PROJECTVERSION = 2.7; + WINDOWS_BUILDTOOL = $NEXT_ROOT/Developer/Executables/make; + WINDOWS_JAVA_COMPILER = "$(JDKBINDIR)/javac.exe"; + WINDOWS_OBJCPLUS_COMPILER = "$(DEVDIR)/gcc"; +} diff --git a/class-dump.h b/class-dump.h new file mode 100644 index 00000000..bb574bba --- /dev/null +++ b/class-dump.h @@ -0,0 +1,137 @@ +// +// $Id: class-dump.h,v 1.1 1999/07/31 03:32:26 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 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@telusplanet.net +// + +#ifndef __CLASS_DUMP_H +#define __CLASS_DUMP_H + +struct my_objc_module +{ + long version; + long size; + long name; + long symtab; +}; + +// Section: __symbols +struct my_objc_symtab +{ + long sel_ref_cnt; + long refs; + short cls_def_count; + short cat_def_count; + long class_pointer; +}; + +// Section: __class +struct my_objc_class +{ + long isa; + long super_class; + long name; + long version; + long info; + long instance_size; + long ivars; + long methods; + long cache; + long protocols; +}; + +// Section: ?? +struct my_objc_category +{ + long category_name; + long class_name; + long methods; + long class_methods; + long protocols; +}; + +// Section: __instance_vars +struct my_objc_ivars +{ + long ivar_count; + // Followed by ivars +}; + +// Section: __instance_vars +struct my_objc_ivar +{ + long name; + long type; + long offset; +}; + +// Section: __inst_meth +struct my_objc_methods +{ + long _obsolete; + long method_count; + // Followed by methods +}; + +// Section: __inst_meth +struct my_objc_method +{ + long name; + long types; + long imp; +}; + +// Section: __meta_class +struct my_objc_isa +{ +}; + +struct my_objc_protocol_list +{ + long next; + long count; + long list; +}; + +struct my_objc_protocol +{ + long isa; + long protocol_name; + long protocol_list; + long instance_methods; +}; + +struct my_objc_prot_inst_meth +{ + long name; + long types; +}; + +struct my_objc_prot_inst_meth_list +{ + long count; + long methods; +}; + +#endif diff --git a/class-dump.m b/class-dump.m new file mode 100644 index 00000000..fb28d5f7 --- /dev/null +++ b/class-dump.m @@ -0,0 +1,979 @@ +// +// $Id: class-dump.m,v 1.1 1999/07/31 03:32:26 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 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@telusplanet.net +// + +#include +#include +#include + +#include +#include + +#include +#include + +#include +#include + +#if NS_TARGET_MAJOR >= 4 +#import +#else +#import +#import +#import +#import +#import +#endif + +#include "datatypes.h" +#include "class-dump.h" + +#include "my_regex.h" + +#import "ObjcThing.h" +#import "ObjcClass.h" +#import "ObjcCategory.h" +#import "ObjcProtocol.h" +#import "ObjcIvar.h" +#import "ObjcMethod.h" +#import "MappedFile.h" + +#ifndef LC_PREBOUND_DYLIB +#define LC_PREBOUND_DYLIB 0x10 +#endif + +#ifndef LC_LOAD_DYLIB +#define LC_LOAD_DYLIB 0x0c + +struct dylib { + union lc_str name; + unsigned long timestamp; + unsigned long current_version; + unsigned long compatibility_version; +}; + +struct dylib_command { + unsigned long cmd; + unsigned long cmdsize; + struct dylib dylib; +}; +#endif + +//---------------------------------------------------------------------- + +#define CLASS_DUMP_VERSION "2.1.2" + +int expand_structures_flag = 0; +int char_star_flag = 0; + +BOOL show_ivar_offsets_flag = NO; +BOOL show_method_addresses_flag = NO; +BOOL expand_protocols_flag = NO; +BOOL match_flag = NO; +BOOL expand_frameworks_flag = NO; +BOOL sort_flag = NO; + +int swap_fat = 0; +int swap_macho = 0; + +#define MAX_SECTIONS 2048 + +NSMutableArray *mappedFiles; + +char *current_filename = NULL; + +struct section_info +{ + char *filename; + char name[17]; + struct section *section; + void *start; + long vmaddr; + long size; +} objc_sections[MAX_SECTIONS]; + +int section_count = 0; + +//---------------------------------------------------------------------- + +#define SEC_CLASS "__class" +#define SEC_SYMBOLS "__symbols" +#define SEC_PROTOCOL "__protocol" +#define SEC_CATEGORY "__category" +#define SEC_CLS_METH "__cls_meth" +#define SEC_INST_METH "__inst_meth" +#define SEC_META_CLASS "__meta_class" +#define SEC_CLASS_NAMES "__class_names" +#define SEC_MODULE_INFO "__module_info" +#define SEC_CAT_CLS_METH "__cat_cls_meth" +#define SEC_INSTANCE_VARS "__instance_vars" +#define SEC_CAT_INST_METH "__cat_inst_meth" +#define SEC_METH_VAR_TYPES "__meth_var_types" +#define SEC_METH_VAR_NAMES "__meth_var_names" + +//====================================================================== + +char *file_type_names[] = +{ + "MH_", + "MH_OBJECT", + "MH_EXECUTE", + "MH_FVMLIB", + "MH_CORE", + "MH_PRELOAD", + "MH_DYLIB", + "MH_DYLINKER", + "MH_BUNDLE", +}; + +char *load_command_names[] = +{ + "LC_", + "LC_SEGMENT", + "LC_SYMTAB", + "LC_SYMSEG", + "LC_THREAD", + "LC_UNIXTHREAD", + "LC_LOADFVMLIB", + "LC_IDFVMLIB", + "LC_IDENT", + "LC_FVMFILE", + "LC_PREPAGE", + "LC_DYSYMTAB", + "LC_LOAD_DYLIB", + "LC_ID_DYLIB", + "LC_LOAD_DYLINKER", + "LC_ID_DYLINKER", + "LC_PREBOUND_DYLIB", +}; + +NSMutableDictionary *protocols; + +//====================================================================== + +void process_file (void *ptr, char *filename); + +int process_macho (void *ptr, char *filename); +unsigned long process_load_command (void *start, void *ptr, char *filename); +void process_dylib_command (void *start, void *ptr); +void process_fvmlib_command (void *start, void *ptr); +void process_segment_command (void *start, void *ptr, char *filename); +void process_objc_segment (void *start, void *ptr, char *filename); + +struct section_info *find_objc_section (char *name, char *filename); +void *translate_address_to_pointer (long addr, char *section); +char *string_at (long addr, char *section); +NSString *nsstring_at (long addr, char *section); + +struct section_info *section_of_address (long addr); +NSArray *handle_objc_symtab (struct my_objc_symtab *symtab); +ObjcClass *handle_objc_class (struct my_objc_class *ocl); +ObjcCategory *handle_objc_category (struct my_objc_category *ocat); +NSArray *handle_objc_protocols (struct my_objc_protocol_list *plist, BOOL expandProtocols); +NSArray *handle_objc_meta_class (struct my_objc_class *ocl); +NSArray *handle_objc_ivars (struct my_objc_ivars *ivars); +NSArray *handle_objc_methods (struct my_objc_methods *methods, char ch); + +void show_single_module (struct section_info *module_info); +void show_all_modules (void); +void build_up_objc_segments (char *filename); + +//====================================================================== + +void process_file (void *ptr, char *filename) +{ + struct mach_header *mh = (struct mach_header *)ptr; + struct fat_header *fh = (struct fat_header *)ptr; + struct fat_arch *fa = (struct fat_arch *)(fh + 1); + int l; + int result = 1; + + if (mh->magic == FAT_CIGAM) + { + // Fat file... Other endian. + + swap_fat = 1; + for (l = 0; l < NXSwapLong (fh->nfat_arch); l++) + { +#ifdef VERBOSE + printf ("archs: %ld\n", NXSwapLong (fh->nfat_arch)); + printf ("offset: %lx\n", NXSwapLong (fa->offset)); + printf ("arch: %08lx\n", NXSwapLong (fa->cputype)); +#endif + result = process_macho (ptr + NXSwapLong (fa->offset), filename); + if (result == 0) + break; + fa++; + } + } + else if (mh->magic == FAT_MAGIC) + { + // Fat file... This endian. + + for (l = 0; l < fh->nfat_arch; l++) + { +#ifdef VERBOSE + printf ("archs: %ld\n", fh->nfat_arch); + printf ("offset: %lx\n", fa->offset); + printf ("arch: %08x\n", fa->cputype); +#endif + result = process_macho (ptr + fa->offset, filename); + if (result == 0) + break; + fa++; + } + } + else + { + result = process_macho (ptr, filename); + } + + switch (result) + { + case 0: + break; + + case 1: + printf ("Error: File did not contain an executable with our endian.\n"); + break; + + default: + printf ("Error: processing Mach-O file.\n"); + } +} + +//---------------------------------------------------------------------- + +// Returns 0 if this was our endian, 1 if it was not, 2 otherwise. + +int process_macho (void *ptr, char *filename) +{ + struct mach_header *mh = (struct mach_header *)ptr; + int l; + void *start = ptr; + + if (mh->magic == MH_CIGAM) + { + swap_macho = 1; + return 1; + } + else if (mh->magic != MH_MAGIC) + { + printf ("This is not a Mach-O file.\n"); + return 2; + } + + ptr += sizeof (struct mach_header); + + for (l = 0; l < mh->ncmds; l++) + { + ptr += process_load_command (start, ptr, filename); + } + + return 0; +} + +//---------------------------------------------------------------------- + +unsigned long process_load_command (void *start, void *ptr, char *filename) +{ + struct load_command *lc = (struct load_command *)ptr; + +#ifdef VERBOSE + if (lc->cmd <= LC_PREBOUND_DYLIB) + { + printf ("%s\n", load_command_names[ lc->cmd ]); + } + else + { + printf ("%08lx\n", lc->cmd); + } +#endif + + if (lc->cmd == LC_SEGMENT) + { + process_segment_command (start, ptr, filename); + } + else if (lc->cmd == LC_LOAD_DYLIB) + { + process_dylib_command (start, ptr); + } + else if (lc->cmd == LC_LOADFVMLIB) + { + process_fvmlib_command (start, ptr); + } + + return lc->cmdsize; +} + +//---------------------------------------------------------------------- + +void process_dylib_command (void *start, void *ptr) +{ + struct dylib_command *dc = (struct dylib_command *)ptr; + + build_up_objc_segments (ptr + dc->dylib.name.offset); +} + +//---------------------------------------------------------------------- + +void process_fvmlib_command (void *start, void *ptr) +{ + struct fvmlib_command *fc = (struct fvmlib_command *)ptr; + + build_up_objc_segments (ptr + fc->fvmlib.name.offset); +} + +//---------------------------------------------------------------------- + +void process_segment_command (void *start, void *ptr, char *filename) +{ + struct segment_command *sc = (struct segment_command *)ptr; + char name[17]; + + strncpy (name, sc->segname, 16); + name[16] = 0; + + if (!strcmp (name, SEG_OBJC) || !strcmp(name, "") /* for .o files. */) + { + process_objc_segment (start, ptr, filename); + } +} + +//---------------------------------------------------------------------- + +void process_objc_segment (void *start, void *ptr, char *filename) +{ + struct segment_command *sc = (struct segment_command *)ptr; + struct section *section = (struct section *)(sc + 1); + int l; + + for (l = 0; l < sc->nsects; l++) + { + if (section_count >= MAX_SECTIONS) + { + printf ("Error: Maximum number of sections reached.\n"); + return; + } + + objc_sections[section_count].filename = filename; + strncpy (objc_sections[section_count].name, section->sectname, 16); + objc_sections[section_count].name[16] = 0; + objc_sections[section_count].section = section; + objc_sections[section_count].start = start + section->offset; + objc_sections[section_count].vmaddr = section->addr; + objc_sections[section_count].size = section->size; + if (!strcmp(section->segname, SEG_OBJC)) section_count++; + section++; + } +} + +//---------------------------------------------------------------------- + +// Find the Objective-C segment for the given filename noted in our +// list. + +struct section_info *find_objc_section (char *name, char *filename) +{ + int l; + + for (l = 0; l < section_count; l++) + { + if (!strcmp (name, objc_sections[l].name) && !strcmp (filename, objc_sections[l].filename)) + { + return &objc_sections[l]; + } + } + + return NULL; +} + +//---------------------------------------------------------------------- + +void debug_section_overlap (void) +{ + int l; + + for (l = 0; l < section_count; l++) + { + printf ("%10ld to %10ld [size 0x%08ld] %-16s of %s\n", + objc_sections[l].vmaddr, objc_sections[l].vmaddr + objc_sections[l].size, objc_sections[l].size, + objc_sections[l].name, objc_sections[l].filename); + } +} + +//---------------------------------------------------------------------- + +// +// Take a long from the Mach-O file (which is really a pointer when +// the section is loaded at the proper location) and translate it into +// a pointer to where we have the file mapped. +// + +void *translate_address_to_pointer (long addr, char *section) +{ + int l; + int count = 0; + + for (l = 0; l < section_count; l++) + { + if (addr >= objc_sections[l].vmaddr && addr < objc_sections[l].vmaddr + objc_sections[l].size + && !strcmp (objc_sections[l].name, section)) + { + count++; + } + } + + if (count > 1) + { + // If there are still duplicates, we choose the one for the current file. + for (l = 0; l < section_count; l++) + { + if (addr >= objc_sections[l].vmaddr && addr < objc_sections[l].vmaddr + objc_sections[l].size + && !strcmp (objc_sections[l].name, section) + && !strcmp (objc_sections[l].filename, current_filename)) + { + return objc_sections[l].start + addr - objc_sections[l].vmaddr; + } + } + } + else + { + for (l = 0; l < section_count; l++) + { + if (addr >= objc_sections[l].vmaddr && addr < objc_sections[l].vmaddr + objc_sections[l].size + && !strcmp (objc_sections[l].name, section)) + { + return objc_sections[l].start + addr - objc_sections[l].vmaddr; + } + } + } + + if (addr != 0) + printf ("address (0x%08lx) not in '%s' section of OBJC segment!\n", addr, section); + + return NULL; +} + +//---------------------------------------------------------------------- + +char *string_at (long addr, char *section) +{ + return (char *)translate_address_to_pointer (addr, section); +} + +//---------------------------------------------------------------------- + +NSString *nsstring_at (long addr, char *section) +{ + char *str = string_at (addr, section); + return (str == NULL) ? (NSString *)@"" : [NSString stringWithCString:str]; +} + +//---------------------------------------------------------------------- + +struct section_info *section_of_address (long addr) +{ + int l; + + for (l = 0; l < section_count; l++) + { + if (addr >= objc_sections[l].vmaddr && addr < objc_sections[l].vmaddr + objc_sections[l].size) + { + return &objc_sections[l]; + } + } + + return NULL; +} + +//====================================================================== + +NSArray *handle_objc_symtab (struct my_objc_symtab *symtab) +{ + NSMutableArray *classList = [NSMutableArray array]; + ObjcThing *objcThing; + long *class_pointer; + int l; + + if (symtab == NULL) + { + printf ("NULL symtab...\n"); + return nil; + } + + class_pointer = &symtab->class_pointer; + + for (l = 0; l < symtab->cls_def_count; l++) + { + objcThing = handle_objc_class (translate_address_to_pointer (*class_pointer, SEC_CLASS)); + if (objcThing != nil) + [classList addObject:objcThing]; + + class_pointer++; + } + + for (l = 0; l < symtab->cat_def_count; l++) + { + objcThing = handle_objc_category (translate_address_to_pointer (*class_pointer, SEC_CATEGORY)); + if (objcThing != nil) + [classList addObject:objcThing]; + + class_pointer++; + } + + return classList; +} + +//---------------------------------------------------------------------- + +ObjcClass *handle_objc_class (struct my_objc_class *ocl) +{ + ObjcClass *objcClass; + NSArray *tmp; + + if (ocl == NULL) + return nil; + + tmp = handle_objc_protocols ((struct my_objc_protocol_list *)translate_address_to_pointer (ocl->protocols, SEC_CAT_CLS_METH), YES); + + if (string_at (ocl->super_class, SEC_CLASS_NAMES) == NULL) + { + objcClass = [[[ObjcClass alloc] initWithClassName:nsstring_at (ocl->name, SEC_CLASS_NAMES) superClassName:nil] autorelease]; + } + else + { + objcClass = [[[ObjcClass alloc] initWithClassName:nsstring_at (ocl->name, SEC_CLASS_NAMES) + superClassName:nsstring_at (ocl->super_class, SEC_CLASS_NAMES)] autorelease]; + } + + [objcClass addProtocolNames:tmp]; + + tmp = handle_objc_ivars ((struct my_objc_ivars *)translate_address_to_pointer (ocl->ivars, SEC_INSTANCE_VARS)); + [objcClass addIvars:tmp]; + + tmp = handle_objc_meta_class ((struct my_objc_class *)translate_address_to_pointer (ocl->isa, SEC_META_CLASS)); + [objcClass addClassMethods:tmp]; + + tmp = handle_objc_methods ((struct my_objc_methods *)translate_address_to_pointer (ocl->methods, SEC_INST_METH), '-'); + [objcClass addInstanceMethods:tmp]; + + return objcClass; +} + +//---------------------------------------------------------------------- + +ObjcCategory *handle_objc_category (struct my_objc_category *ocat) +{ + ObjcCategory *objcCategory; + NSArray *tmp; + + if (ocat == NULL) + return nil; + + objcCategory = [[[ObjcCategory alloc] initWithClassName:nsstring_at (ocat->class_name, SEC_CLASS_NAMES) + categoryName:nsstring_at (ocat->category_name, SEC_CLASS_NAMES)] autorelease]; + + tmp = handle_objc_methods ((struct my_objc_methods *)translate_address_to_pointer (ocat->class_methods, SEC_CAT_CLS_METH), '+'); + [objcCategory addClassMethods:tmp]; + + tmp = handle_objc_methods ((struct my_objc_methods *)translate_address_to_pointer (ocat->methods, SEC_CAT_INST_METH), '-'); + [objcCategory addInstanceMethods:tmp]; + + return objcCategory; +} + +//---------------------------------------------------------------------- + +// Return list of protocol names. +NSArray *handle_objc_protocols (struct my_objc_protocol_list *plist, BOOL expandProtocols) +{ + NSMutableArray *protocolArray = [NSMutableArray array]; + ObjcProtocol *objcProtocol; + struct my_objc_protocol *prot; + struct my_objc_prot_inst_meth_list *mlist; + struct my_objc_prot_inst_meth *meth; + int l, p; + long *ptr; + NSArray *parentProtocols; + + if (plist == NULL) + return nil; + + ptr = &plist->list; + + for (p = 0; p < plist->count; p++) + { + prot = translate_address_to_pointer (*ptr, SEC_PROTOCOL); + + objcProtocol = [[[ObjcProtocol alloc] initWithProtocolName:nsstring_at (prot->protocol_name, SEC_CLASS_NAMES)] autorelease]; + [protocolArray addObject:[objcProtocol protocolName]]; + + parentProtocols = handle_objc_protocols (translate_address_to_pointer (prot->protocol_list, SEC_CAT_CLS_METH), + expand_protocols_flag); + [objcProtocol addProtocolNames:parentProtocols]; + + mlist = translate_address_to_pointer (prot->instance_methods, SEC_CAT_INST_METH); + if (mlist != NULL) + { + meth = (struct my_objc_prot_inst_meth *)&mlist->methods; + + for (l = 0; l < mlist->count; l++) + { + [objcProtocol addProtocolMethod:[[[ObjcMethod alloc] initWithMethodName:nsstring_at (meth->name, SEC_METH_VAR_NAMES) + type:nsstring_at (meth->types, SEC_METH_VAR_TYPES)] autorelease]]; + meth++; + } + } + + if (expandProtocols == YES && [protocols objectForKey:[objcProtocol protocolName]] == nil) + { + [protocols setObject:objcProtocol forKey:[objcProtocol protocolName]]; + objcProtocol = nil; + } + + ptr++; + } + + return protocolArray; +} + +//---------------------------------------------------------------------- + +NSArray *handle_objc_meta_class (struct my_objc_class *ocl) +{ + if (ocl == NULL) + return nil; + + return handle_objc_methods ((struct my_objc_methods *)translate_address_to_pointer (ocl->methods, SEC_CLS_METH), '+'); +} + +//---------------------------------------------------------------------- + +NSArray *handle_objc_ivars (struct my_objc_ivars *ivars) +{ + struct my_objc_ivar *ivar = (struct my_objc_ivar *)(ivars + 1); + NSMutableArray *ivarArray = [NSMutableArray array]; + ObjcIvar *objcIvar; + int l; + + if (ivars == NULL) + return nil; + + for (l = 0; l < ivars->ivar_count; l++) + { + objcIvar = [[[ObjcIvar alloc] initWithName:nsstring_at (ivar->name, SEC_METH_VAR_NAMES) + type:nsstring_at (ivar->type, SEC_METH_VAR_TYPES) + offset:ivar->offset] autorelease]; + [ivarArray addObject:objcIvar]; + + ivar++; + } + + return ivarArray; +} + +//---------------------------------------------------------------------- + +NSArray *handle_objc_methods (struct my_objc_methods *methods, char ch) +{ + struct my_objc_method *method = (struct my_objc_method *)(methods + 1); + NSMutableArray *methodArray = [NSMutableArray array]; + ObjcMethod *objcMethod; + int l; + + if (methods == NULL) + return nil; + + for (l = 0; l < methods->method_count; l++) + { + // Sometimes the name, types, and implementation are all zero. However, the + // implementation may legitimately be zero (most often the first method of an object file), + // so we check the name instead. + + if (method->name != 0) + { + objcMethod = [[[ObjcMethod alloc] initWithMethodName:nsstring_at (method->name, SEC_METH_VAR_NAMES) + type:nsstring_at (method->types, SEC_METH_VAR_TYPES) + address:method->imp] autorelease]; + [methodArray addObject:objcMethod]; + } + method++; + } + + return methodArray; +} + +//====================================================================== + +void show_single_module (struct section_info *module_info) +{ + struct my_objc_module *m; + int module_count; + int l; + char *tmp; + id en, thing, key; + NSMutableArray *classList = [NSMutableArray array]; + NSArray *newClasses; + int flags = 0; + + if (module_info == NULL) + { + return; + } + + if (sort_flag == YES) + flags |= F_SORT_METHODS; + + if (show_ivar_offsets_flag == YES) + flags |= F_SHOW_IVAR_OFFSET; + + if (show_method_addresses_flag == YES) + flags |= F_SHOW_METHOD_ADDRESS; + + tmp = current_filename; + m = module_info->start; + module_count = module_info->size / sizeof (struct my_objc_module); + + printf ("\n/*\n * File: %s\n */\n\n", module_info->filename); + current_filename = module_info->filename; + + for (l = 0; l < module_count; l++) + { + newClasses = handle_objc_symtab ((struct my_objc_symtab *)translate_address_to_pointer (m->symtab, SEC_SYMBOLS)); + [classList addObjectsFromArray:newClasses]; + m++; + } + + + if (sort_flag == YES) + en = [[[protocols allKeys] sortedArrayUsingSelector:@selector (compare:)] objectEnumerator]; + else + en = [[protocols allKeys] objectEnumerator]; + + while (key = [en nextObject]) + { + thing = [protocols objectForKey:key]; + if (match_flag == NO || RE_EXEC ([[thing sortableName] cString]) == 1) + [thing showDefinition:flags]; + } + + if (sort_flag == YES) + en = [[classList sortedArrayUsingSelector:@selector (orderByName:)] objectEnumerator]; + else + en = [classList objectEnumerator]; + + while (thing = [en nextObject]) + { + if (match_flag == NO || RE_EXEC ([[thing sortableName] cString]) == 1) + [thing showDefinition:flags]; + } + + [protocols removeAllObjects]; + + current_filename = tmp; +} + +//---------------------------------------------------------------------- + +void show_all_modules (void) +{ + int l; + + for (l = section_count - 1; l >= 0; l--) + { + if (!strcmp (objc_sections[l].name, SEC_MODULE_INFO)) + { + show_single_module ((struct section_info *)&objc_sections[l]); + } + } +} + +//---------------------------------------------------------------------- + +void build_up_objc_segments (char *filename) +{ + MappedFile *mappedFile; + NSEnumerator *mfEnumerator; + + // Only process each file once. + + mfEnumerator = [mappedFiles objectEnumerator]; + while (mappedFile = [mfEnumerator nextObject]) + { + if (!strcmp (filename, [[mappedFile filename] cString])) + return; + } + + mappedFile = [[[MappedFile alloc] initWithFilename:[NSString stringWithCString:filename]] autorelease]; + //NSCAssert (mappedFile != nil, @"Could not map file..."); + if (mappedFile != nil) + { + [mappedFiles addObject:mappedFile]; + + process_file ((void *)[mappedFile data], filename); + } +} + +//---------------------------------------------------------------------- + +void print_usage (void) +{ + fprintf (stderr, + "class-dump %s\n" + "Usage: class-dump [-a] [-A] [-e] [-R] [-C regex] [-r] [-s] [-S] executable-file\n" + " -a show instance variable offsets\n" + " -A show implementation addresses\n" + " -e expand structure (and union) definition whenever possible\n" + " -R recursively expand @protocol <>\n" + " -C only display classes matching regular expression\n" + " -r recursively expand frameworks and fixed VM shared libraries\n" + " -s convert STR to char *\n" + " -S sort protocols, classes, and methods\n", + CLASS_DUMP_VERSION + ); +} + +//---------------------------------------------------------------------- + +void print_header (void) +{ + printf ( + "/*\n" + " * Generated by class-dump (version %s).\n" + " *\n" + " * class-dump is Copyright (C) 1997 by Steve Nygard.\n" + " */\n", CLASS_DUMP_VERSION + ); +} + +//====================================================================== + +int main (int argc, char *argv[]) +{ + NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; + int c; + extern int optind; + extern char *optarg; + int error_flag = 0; + const char *tmp; + + if (argc == 1) + { + print_usage(); + exit (2); + } + + while ( (c = getopt (argc, argv, "aAeRC:rsS")) != EOF) + { + switch (c) + { + case 'a': + show_ivar_offsets_flag = YES; + break; + + case 'A': + show_method_addresses_flag = YES; + break; + + case 'e': + expand_structures_flag = 1; + break; + + case 'R': + expand_protocols_flag = YES; + break; + + case 'C': + if (match_flag == YES) + { + printf ("Error: sorry, only one -C allowed\n"); + error_flag++; + } + else + { + match_flag = YES; + + tmp = RE_COMP (optarg); + if (tmp != NULL) + { + printf ("Error: %s\n", tmp); + exit (1); + } + } + break; + + case 'r': + expand_frameworks_flag = YES; + break; + + case 's': + char_star_flag = 1; + break; + + case 'S': + sort_flag = YES; + break; + + case '?': + default: + error_flag++; + break; + } + } + + if (error_flag > 0) + { + print_usage (); + exit (2); + } + + mappedFiles = [NSMutableArray array]; + protocols = [NSMutableDictionary dictionary]; + + if (optind < argc) + { + build_up_objc_segments (argv[optind]); + + print_header (); + + //debug_section_overlap (); + + if (section_count > 0) + { + if (expand_frameworks_flag == NO) + show_single_module ((struct section_info *)find_objc_section (SEC_MODULE_INFO, argv[optind])); + else + show_all_modules (); + } + } + + [mappedFiles removeAllObjects]; + + [pool release]; + + return 0; +} diff --git a/datatypes.h b/datatypes.h new file mode 100644 index 00000000..604bd104 --- /dev/null +++ b/datatypes.h @@ -0,0 +1,86 @@ +// +// $Id: datatypes.h,v 1.1 1999/07/31 03:32:26 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 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@telusplanet.net +// + +#ifndef __DATATYPES_H +#define __DATATYPES_H + +struct my_objc_type +{ + struct my_objc_type *link; + struct my_objc_type *subtype; + struct my_objc_type *next; + int type; + char *var_name; + char *type_name; +}; + +#define array_size type_name +#define bitfield_size type_name + +#define IS_ID(a) ((a)->type == '@' && (a)->type_name == NULL) + +struct method_type +{ + struct method_type *link; + struct method_type *next; + char *name; + struct my_objc_type *type; +}; + +// These are from gram.y: +extern void format_type (const char *type, const char *name, int level); +extern void format_method (char method_type, const char *name, const char *types); + +//====================================================================== + +struct my_objc_type *create_empty_type (void); +struct my_objc_type *create_simple_type (int type); +struct my_objc_type *create_id_type (char *name); +struct my_objc_type *create_struct_type (char *name, struct my_objc_type *members); +struct my_objc_type *create_union_type (struct my_objc_type *members, char *type_name); +struct my_objc_type *create_bitfield_type (char *size); +struct my_objc_type *create_array_type (char *count, struct my_objc_type *type); +struct my_objc_type *create_pointer_type (struct my_objc_type *type); +struct my_objc_type *create_modified_type (int modifier, struct my_objc_type *type); + +struct method_type *create_method_type (struct my_objc_type *t, char *name); + +struct my_objc_type *reverse_types (struct my_objc_type *t); +struct method_type *reverse_method_types (struct method_type *m); + +void indent_to_level (int level); + +void print_type (struct my_objc_type *t, int expand, int level); +void print_method (char method_type, const char *method_name, struct method_type *m); + +void free_objc_type (struct my_objc_type *t); +void free_method_type (struct method_type *m); + +void free_allocated_types (void); +void free_allocated_methods (void); + +#endif diff --git a/datatypes.m b/datatypes.m new file mode 100644 index 00000000..8bdb5c86 --- /dev/null +++ b/datatypes.m @@ -0,0 +1,607 @@ +// +// $Id: datatypes.m,v 1.1 1999/07/31 03:32:26 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 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@telusplanet.net +// + +#include +#include +#include +#include + +#if NS_TARGET_MAJOR >= 4 +#import +#else +#import +#import + +@interface NSString (Foundation4Compatibility) ++ string; +@end + +@implementation NSString (Foundation4Compatibility) ++ string { return [[self class] stringWithCapacity:1]; } +@end +#endif + +#include "datatypes.h" +#include "gram.h" + +NSString *string_indent_to_level (int level); +NSString *string_from_members (struct my_objc_type *t, int level); +NSString *string_from_simple_type (char c); +NSString *string_from_type (struct my_objc_type *t, NSString *inner, int expand, int level); + +// Not ^ or b +static char *simple_types = "cislqCISLQfdv*#:%?rnNoORV"; + +static char *simple_type_names[] = +{ + "char", + "int", + "short", + "long", + "long long", + "unsigned char", + "unsigned int", + "unsigned short", + "unsigned long", + "unsigned long long", + "float", + "double", + "void", + "STR", + "Class", + "SEL", + "NXAtom", + "UNKNOWN", + "const", + "in", + "inout", + "out", + "bycopy", + "byref", + "oneway" +}; + +struct my_objc_type *allocated_types = NULL; +struct method_type *allocated_methods = NULL; + +//====================================================================== +// Type creation functions +//====================================================================== + +struct my_objc_type *create_empty_type (void) +{ + struct my_objc_type *tmp = malloc (sizeof (struct my_objc_type)); + + assert (tmp != NULL); + + tmp->link = allocated_types; + allocated_types = tmp; + + tmp->subtype = NULL; + tmp->next = NULL; + tmp->type = 0; + tmp->var_name = NULL; + tmp->type_name = NULL; + + return tmp; +} + +struct my_objc_type *create_simple_type (int type) +{ + struct my_objc_type *t = create_empty_type (); + + extern int char_star_flag; + + if (char_star_flag == 1 && type == '*') + { + t->type = '^'; + t->subtype = create_simple_type ('c'); + } + else + { + t->type = type; + } + + return t; +} + +struct my_objc_type *create_id_type (char *name) +{ + struct my_objc_type *t = create_empty_type (); + + t->type_name = name; + + if (name != NULL) + { + t->type = T_NAMED_OBJECT; + return create_pointer_type (t); + } + else + { + t->type = '@'; + } + + return t; +} + +struct my_objc_type *create_struct_type (char *name, struct my_objc_type *members) +{ + struct my_objc_type *t = create_empty_type (); + + t->type = '{'; + t->type_name = name; + t->subtype = members; + + return t; +} + +struct my_objc_type *create_union_type (struct my_objc_type *members, char *type_name) +{ + struct my_objc_type *t = create_empty_type (); + + t->type = '('; + t->subtype = members; + t->type_name = type_name; + + return t; +} + +struct my_objc_type *create_bitfield_type (char *size) +{ + struct my_objc_type *t = create_empty_type (); + + t->type = 'b'; + t->bitfield_size = size; + + return t; +} + +struct my_objc_type *create_array_type (char *count, struct my_objc_type *type) +{ + struct my_objc_type *t = create_empty_type (); + + t->type = '['; + t->array_size = count; + t->subtype = type; + + return t; +} + +struct my_objc_type *create_pointer_type (struct my_objc_type *type) +{ + struct my_objc_type *t = create_empty_type (); + + t->type = '^'; + t->subtype = type; + + return t; +} + +struct my_objc_type *create_modified_type (int modifier, struct my_objc_type *type) +{ + struct my_objc_type *t = create_empty_type (); + + t->type = modifier; + t->subtype = type; + + return t; +} + +//====================================================================== +// Method creation functions +//====================================================================== + +struct method_type *create_method_type (struct my_objc_type *t, char *name) +{ + struct method_type *tmp = malloc (sizeof (struct method_type)); + + assert (tmp != NULL); + + tmp->link = allocated_methods; + allocated_methods = tmp; + + tmp->next = NULL; + tmp->name = name; + tmp->type = t; + + return tmp; +} + +//====================================================================== +// Misc functions +//====================================================================== + +struct my_objc_type *reverse_types (struct my_objc_type *t) +{ + struct my_objc_type *head = NULL; + struct my_objc_type *tmp; + + while (t != NULL) + { + tmp = t; + t = t->next; + tmp->next = head; + head = tmp; + } + + return head; +} + +struct method_type *reverse_method_types (struct method_type *m) +{ + struct method_type *head = NULL; + struct method_type *tmp; + + while (m != NULL) + { + tmp = m; + m = m->next; + tmp->next = head; + head = tmp; + } + + return head; +} + +//====================================================================== +// Display functions +//====================================================================== + +void indent_to_level (int level) +{ + int l; + + for (l = 0; l < level; l++) + printf (" "); +} + +NSString *string_indent_to_level (int level) +{ + NSMutableString *str; + int l; + + str = [NSMutableString string]; + for (l = 0; l < level; l++) + [str appendString:@" "]; + + return str; +} + +NSString *string_from_members (struct my_objc_type *t, int level) +{ + NSMutableString *str; + + str = [NSMutableString string]; + + while (t != NULL) + { + [str appendString:string_indent_to_level (level)]; + [str appendString:string_from_type (t, nil, 1, level)]; + [str appendString:@";\n"]; + t = t->next; + } + + return str; +} + +NSString *string_from_simple_type (char c) +{ + char *ptr = strchr (simple_types, c); + NSString *str = nil; + + if (ptr != NULL) + str = [NSString stringWithFormat:@"%s", simple_type_names[ ptr - simple_types ]]; + else + NSLog (@"Unknown simple type '%c'", c); + + return str; +} + +NSString *string_from_type (struct my_objc_type *t, NSString *inner, int expand, int level) +{ + NSString *tmp; + NSString *name, *type_name; + + if (t == NULL) + return inner; + + if (inner == nil) + inner = @""; + + //NSLog (@"sft: '%c', inner: '%@'", t->type, inner); + + switch (t->type) + { + case T_NAMED_OBJECT: + if (t->var_name == NULL) + name = @""; + else + name = [NSString stringWithFormat:@" %s", t->var_name]; + + tmp = [NSString stringWithFormat:@"%s%@ %@", t->type_name, name, inner]; // We always have a pointer to this type + break; + + case '@': + if (t->var_name == NULL) + name = @""; + else + name = [NSString stringWithFormat:@" %s", t->var_name]; + + if ([inner length] > 0) + tmp = [NSString stringWithFormat:@"id%@ %@", name, inner]; + else + tmp = [NSString stringWithFormat:@"id%@%@", name, inner]; + break; + + case 'b': + if (t->var_name == NULL) + name = @""; + else + name = [NSString stringWithFormat:@"%s", t->var_name]; + + tmp = [NSString stringWithFormat:@"int %@:%s%@", name, t->bitfield_size, inner]; + break; + + case '[': + if (t->var_name == NULL) + name = @""; + else + name = [NSString stringWithFormat:@"%s", t->var_name]; + + tmp = [NSString stringWithFormat:@"%@%@[%s]", inner, name, t->array_size]; + tmp = string_from_type (t->subtype, tmp, expand, level); + break; + + case '(': + if (t->var_name == NULL) + name = @""; + else + name = [NSString stringWithFormat:@"%s", t->var_name]; + + if (t->type_name == NULL) + type_name = @""; + else + type_name = [NSString stringWithFormat:@" %s", t->type_name]; + + tmp = [NSString stringWithFormat:@"union%@", type_name]; + if (expand == 1 && t->subtype != NULL) + { + tmp = [NSString stringWithFormat:@"%@ {\n%@%@}", tmp, string_from_members (t->subtype, level + 1), + string_indent_to_level (level)]; + } + + if ([inner length] > 0 || [name length] > 0) + { + tmp = [NSString stringWithFormat:@"%@ %@%@", tmp, inner, name]; + } + break; + + case '{': + if (t->var_name == NULL) + name = @""; + else + name = [NSString stringWithFormat:@"%s", t->var_name]; + + if (t->type_name == NULL) + type_name = @""; + else + type_name = [NSString stringWithFormat:@" %s", t->type_name]; + + tmp = [NSString stringWithFormat:@"struct%@", type_name]; + if (expand == 1 && t->subtype != NULL) + { + tmp = [NSString stringWithFormat:@"%@ {\n%@%@}", tmp, string_from_members (t->subtype, level + 1), + string_indent_to_level (level)]; + } + + if ([inner length] > 0 || [name length] > 0) + { + tmp = [NSString stringWithFormat:@"%@ %@%@", tmp, inner, name]; + } + break; + + case '^': + if (t->var_name == NULL) + name = @""; + else + name = [NSString stringWithFormat:@"%s", t->var_name]; + + if (t->subtype != NULL && t->subtype->type == '[') + tmp = [NSString stringWithFormat:@"(*%@%@)", inner, name]; + else + tmp = [NSString stringWithFormat:@"*%@%@", name, inner]; + + tmp = string_from_type (t->subtype, tmp, expand, level); + break; + + case 'r': + case 'n': + case 'N': + case 'o': + case 'O': + case 'R': + case 'V': + tmp = string_from_type (t->subtype, inner, expand, level); + tmp = [NSString stringWithFormat:@"%@ %@", string_from_simple_type (t->type), tmp]; + break; + + default: + if (t->var_name == NULL) + name = @""; + else + name = [NSString stringWithFormat:@"%s", t->var_name]; + + if ([name length] == 0 && [inner length] == 0) + tmp = string_from_simple_type (t->type); + else + tmp = [NSString stringWithFormat:@"%@ %@%@", string_from_simple_type (t->type), name, inner]; + break; + } + + return tmp; +} + +void print_type (struct my_objc_type *t, int expand, int level) +{ + NSString *str; + + str = string_from_type (t, nil, expand, level); + + printf ("%s", [str cString]); +} + +void print_method (char method_type, const char *method_name, struct method_type *m) +{ + extern int expand_structures_flag; + int l; + BOOL noMoreTypes; + + printf ("%c ", method_type); + if (m == NULL) + { + printf ("%s; /* Error: No method types. */", method_name); + return; + } + + noMoreTypes = NO; + + if (!IS_ID (m->type)) + { + printf ("("); + print_type (m->type, expand_structures_flag, 0); + printf (")"); + } + + for (l = 0; l < 3 && m != NULL; l++) + m = m->next; + + while (*method_name != '\0') + { + while (*method_name != '\0' && *method_name != ':') + { + putchar (*method_name); + method_name++; + } + + if (*method_name == ':') + { + printf (":"); + if (m == NULL) + { + noMoreTypes = YES; + method_name++; + } + else + { + if (!IS_ID (m->type)) + { + printf ("("); + print_type (m->type, expand_structures_flag, 0); + printf (")"); + } + printf ("fp%s", m->name); + method_name++; + if (*method_name != '\0' && *method_name != ':') + printf (" "); + m = m->next; + } + } + } + printf (";"); + + if (noMoreTypes == YES) + { + printf (" /* Error: Ran out of types for this method. */"); + } +} + +//====================================================================== + +void free_objc_type (struct my_objc_type *t) +{ + struct my_objc_type *tmp; + + while (t != NULL) + { + tmp = t; + t = t->next; + + if (tmp->var_name != NULL) + free (tmp->var_name); + if (tmp->type_name != NULL) + free (tmp->type_name); + if (tmp->subtype != NULL) + free_objc_type (tmp->subtype); + } +} + +void free_method_type (struct method_type *m) +{ + struct method_type *tmp; + + while (m != NULL) + { + tmp = m; + m = m->next; + + if (tmp->name != NULL) + free (tmp->name); + free_objc_type (tmp->type); + } +} + +//====================================================================== + +void free_allocated_types (void) +{ + struct my_objc_type *tmp; + + while (allocated_types != NULL) + { + tmp = allocated_types; + allocated_types = allocated_types->link; + + if (tmp->var_name != NULL) + free (tmp->var_name); + if (tmp->type_name != NULL) + free (tmp->type_name); + } +} + +void free_allocated_methods (void) +{ + struct method_type *tmp; + + while (allocated_methods != NULL) + { + tmp = allocated_methods; + allocated_methods = allocated_methods->link; + + if (tmp->name != NULL) + free (tmp->name); + } +} diff --git a/gram.y b/gram.y new file mode 100644 index 00000000..3e7f885a --- /dev/null +++ b/gram.y @@ -0,0 +1,411 @@ +%{ + +// +// $Id: gram.y,v 1.1 1999/07/31 03:32:27 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 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@telusplanet.net +// + +#include +#include +#include +#include + +#include "datatypes.h" + +extern int ident_state; +extern char yytext[]; + +struct method_type *rtype = NULL; +int parsing_ivar = 0; + +//---------------------------------------------------------------------- + +char *strdup (const char *str); +int yylex (void); +int yyerror (char *s); + +//---------------------------------------------------------------------- + +char *strdup (const char *str) +{ + char *ptr = malloc (strlen (str) + 1); + + assert (ptr != NULL); + + strcpy (ptr, str); + + return ptr; +} + +%} + +%union +{ + int u_int; + char *u_str; + struct my_objc_type *u_type; + struct method_type *u_meth; +}; + +%type start +%type method_type_list method_type + +%type type +%type modifier +%type unmodified_type +%type simple_type +%type id_type +%type structure_type +%type optional_format +%type taglist +%type tag +%type quoted_name +%type quoted_name_prefix +%type union_type +%type union_types +%type array_type +%type identifier +%type number + + +%type 'c' 'i' 's' 'l' 'q' +%type 'C' 'I' 'S' 'L' 'Q' +%type 'f' 'd' 'v' '*' '#' +%type ':' '%' 'r' 'n' 'N' +%type 'o' 'O' 'R' 'V' + +%type '^' 'b' + +%token TK_NUMBER +%token TK_IDENTIFIER + +%token T_NAMED_OBJECT + +%expect 1 + +%% + +start: + type + { + rtype = create_method_type ($1, NULL); + $$ = 0; + } + | method_type_list + { + rtype = reverse_method_types ($1); + $$ = 0; + } + ; + +method_type_list: + method_type + | method_type_list method_type + { + $2->next = $1; + $$ = $2; + } + ; + +method_type: + type number + { + $$ = create_method_type ($1, $2); + } + ; + +type: unmodified_type + | modifier type + { + $$ = create_modified_type ($1, $2); + } + ; + +modifier: + 'r' { $$ = 'r'; } + | 'n' { $$ = 'n'; } + | 'N' { $$ = 'N'; } + | 'o' { $$ = 'o'; } + | 'O' { $$ = 'O'; } + | 'R' { $$ = 'R'; } + | 'V' { $$ = 'V'; } + ; + +unmodified_type: + simple_type + { + $$ = create_simple_type ($1); + } + | id_type + | '^' type + { + $$ = create_pointer_type ($2); + } + | 'b' number + { + $$ = create_bitfield_type ($2); + } + | structure_type + | union_type + | array_type + ; + +simple_type: + 'c' { $$ = 'c'; } + | 'i' { $$ = 'i'; } + | 's' { $$ = 's'; } + | 'l' { $$ = 'l'; } + | 'q' { $$ = 'q'; } + | 'C' { $$ = 'C'; } + | 'I' { $$ = 'I'; } + | 'S' { $$ = 'S'; } + | 'L' { $$ = 'L'; } + | 'Q' { $$ = 'Q'; } + | 'f' { $$ = 'f'; } + | 'd' { $$ = 'd'; } + | 'v' { $$ = 'v'; } + | '*' { $$ = '*'; } + | '#' { $$ = '#'; } + | ':' { $$ = ':'; } + | '%' { $$ = '%'; } + | '?' { $$ = '?'; } + ; + +/* This gives the shift/reduce error... */ + +id_type: + '@' + { + $$ = create_id_type (NULL); + } + | '@' quoted_name + { + $$ = create_id_type ($2); + } + ; + +structure_type: + '{' { ident_state = 1; } identifier optional_format '}' + { + $$ = create_struct_type ($3, $4); + } + ; + +optional_format: + /* empty */ + { + $$ = NULL; + } + | '=' taglist + { + $$ = reverse_types ($2); + } + ; + +taglist: + /* empty */ + { + $$ = NULL; + } + | taglist tag + { + $2->next = $1; + $$ = $2; + } + ; + +tag: + quoted_name type + { + $2->var_name = $1; + $$ = $2; + } + | type + { + $1->var_name = strdup ("___"); + $$ = $1; + } + ; + +quoted_name: + quoted_name_prefix identifier '"' + { + $$ = $2; + } + | quoted_name_prefix '"' + { + $$ = strdup (""); + } + ; + +quoted_name_prefix: + '"' { ident_state = 1; } + ; + +union_type: + union_type_prefix union_types ')' + { + $$ = create_union_type (reverse_types ($2), NULL); + } + | union_type_prefix identifier ')' + { + $$ = create_union_type (NULL, $2); + } + ; + +union_type_prefix: + '(' + { + /* + * Great - for a union, an instance variable has a name, and no type, + * but a method has the types, and no name! + */ + if (parsing_ivar == 1) + ident_state = 1; + } + ; + +union_types: + /* empty */ + { + $$ = NULL; + } + | union_types type + { + $2->var_name = strdup ("___"); + $2->next = $1; + $$ = $2; + } + ; + +array_type: + '[' number type ']' + { + $$ = create_array_type ($2, $3); + } + ; + +identifier: + TK_IDENTIFIER + { + $$ = strdup (yytext); + } + ; + +number: + TK_NUMBER + { + $$ = strdup (yytext); + } + ; + +%% + +extern yy_scan_string(); + +int yyerror (char *s) +{ + fprintf (stderr, "%s\n", s); + return 0; +} + +int parse_ivar_type (void) +{ + parsing_ivar = 1; + return yyparse(); +} + +int parse_method_type (void) +{ + parsing_ivar = 0; + return yyparse(); +} + +void format_type (const char *type, const char *name, int level) +{ + int parse_flag; + extern int expand_structures_flag; + + rtype = NULL; + yy_scan_string (type); + parse_flag = parse_ivar_type(); + + if (parse_flag == 0) + { + if (name != NULL) + rtype->type->var_name = strdup (name); + indent_to_level (level); + print_type (rtype->type, expand_structures_flag, level); + printf (";"); + + rtype = NULL; + } + else + { + printf ("Error! format_type (%s, %s)\n", type, name); + printf ("\n\n"); + } + + free_allocated_methods(); + free_allocated_types(); +} + +void format_method (char method_type, const char *name, const char *types) +{ + int parse_flag; + + if (name == NULL) + { + printf ("%c (method name not found in OBJC segments), args: %s", method_type, types); + return; + } + + if (*name == '\0' || *types == '\0') + { + printf ("Error! format_method (%c, '%s', '%s')", method_type, name, types); + return; + } + + rtype = NULL; + yy_scan_string (types); + parse_flag = parse_method_type(); + + if (parse_flag == 0) + { + print_method (method_type, name, rtype); + rtype = NULL; + } + else + { + extern const char *scanner_ptr; + + printf ("Error! format_method (%c, %s, %s )\n", method_type, name, types); + printf ("at %s\n", scanner_ptr); + printf ("\n\n"); + } + + free_allocated_methods(); + free_allocated_types(); +} diff --git a/h.template b/h.template new file mode 100644 index 00000000..f3c1b049 --- /dev/null +++ b/h.template @@ -0,0 +1,11 @@ +$$ +/* $FILENAME$ created by $USERNAME$ on $DATE$ */ + +#import + +@interface $FILENAMESANSEXTENSION$ : NSObject +{ + +} + +@end diff --git a/lexer.c b/lexer.c new file mode 100644 index 00000000..e41046a9 --- /dev/null +++ b/lexer.c @@ -0,0 +1,104 @@ +// +// $Id: lexer.c,v 1.1 1999/07/31 03:32:27 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 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@telusplanet.net +// + +#include +#include +#include "gram.h" + +#define LEX_BUFFER_SIZE 1024 + +int ident_state = 0; + +char yytext[LEX_BUFFER_SIZE]; +static const char *yyend = yytext + LEX_BUFFER_SIZE - 1; +static const char *string = NULL; +const char *scanner_ptr = NULL; + +#define is_other(x) (x=='$'||x=='_'||x=='<'||x=='>') + +void yy_scan_string (const char *str) +{ + scanner_ptr = string = str; +} + +int yylex (void) +{ + if (ident_state == 1) + { + if (*scanner_ptr == '?') + { + scanner_ptr++; + strcpy (yytext, "?"); + ident_state = 0; + return TK_IDENTIFIER; + } + + if (*scanner_ptr == '"') + { + scanner_ptr++; + ident_state = 0; + return '"'; + } + + if (isalpha (*scanner_ptr) || is_other (*scanner_ptr)) + { + char *yptr = yytext; + *yptr++ = *scanner_ptr++; + + // Need bounds checking. + while ((isalnum (*scanner_ptr) || is_other (*scanner_ptr)) && yptr < yyend) + { + *yptr++ = *scanner_ptr++; + } + *yptr = 0; + + ident_state = 0; + return TK_IDENTIFIER; + } + } + + if (isdigit (*scanner_ptr)) + { + char *yptr = yytext; + + //printf ("here\n"); + + while ((isdigit (*scanner_ptr)) && yptr < yyend) + { + *yptr++ = *scanner_ptr++; + } + *yptr = 0; + ident_state = 0; + + return TK_NUMBER; + } + + if (*scanner_ptr == 0) + return 0; + + return *scanner_ptr++; +} diff --git a/m.template b/m.template new file mode 100644 index 00000000..1216fe50 --- /dev/null +++ b/m.template @@ -0,0 +1,18 @@ +$$ Lines starting with $$ are not inserted into newly created files +$$ The following substitutions are made: +$$ +$$ $FILENAME$ e.g. foo.m +$$ $FILENAMESANSEXTENSION$ e.g. foo +$$ $DIRECTORY$ e.g. /tmp/MyNewApp +$$ $PROJECTNAME$ e.g. MyNewApp +$$ $SUBPROJECTNAME$ e.g. TheGoodPart.subproj +$$ $USERNAME$ e.g. mwagner +$$ $DATE$ e.g. Jan-1-1994 +$$ +/* $FILENAME$ created by $USERNAME$ on $DATE$ */ + +#import "$FILENAMESANSEXTENSION$.h" + +@implementation $FILENAMESANSEXTENSION$ + +@end diff --git a/my_regex.c b/my_regex.c new file mode 100644 index 00000000..a19178c9 --- /dev/null +++ b/my_regex.c @@ -0,0 +1,72 @@ +// +// $Id: my_regex.c,v 1.1 1999/07/31 03:32:27 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 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@telusplanet.net +// + +#include +#include + +#import "my_regex.h" + +#ifdef __APPLE_CPP__ + +// +// This provides functions compatible with the interface of the old style +// regular expression matching functions. Note, however, that we use the +// extended regular expression syntax. +// + +static regex_t compiled_regex; +static char regex_error_buffer[256]; + +char *my_re_comp (const char *pattern) +{ + int result; + + result = regcomp (&compiled_regex, pattern, REG_EXTENDED); + if (result != 0) + { + regerror (result, &compiled_regex, regex_error_buffer, sizeof (regex_error_buffer)); + return regex_error_buffer; + } + + return NULL; +} + +int my_re_exec (const char *text) +{ + int result; + + result = regexec (&compiled_regex, text, 0, NULL, 0); + + return (result == 0) ? 1 : 0; +} + +void my_re_free (void) +{ + regfree (&compiled_regex); +} + +#endif diff --git a/my_regex.h b/my_regex.h new file mode 100644 index 00000000..8d19c86d --- /dev/null +++ b/my_regex.h @@ -0,0 +1,42 @@ +// +// $Id: my_regex.h,v 1.1 1999/07/31 03:32:27 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 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@telusplanet.net +// + +#include // This is the same name for both the old and new versions. + +#ifdef __APPLE_CPP__ +char *my_re_comp (const char *pattern); +int my_re_exec (const char *text); +void my_re_free (void); + +#define RE_COMP(pattern) my_re_comp(pattern) +#define RE_EXEC(text) my_re_exec(text) +#define RE_FREE() my_re_free() +#else +#define RE_COMP(pattern) re_comp(pattern) +#define RE_EXEC(text) re_exec(text) +#define RE_FREE() /* empty */ +#endif