From 04c74b6af0e7c93689c09af9719be1af03dca1fc Mon Sep 17 00:00:00 2001 From: Doug Schaefer Date: Wed, 7 Jul 2004 19:19:42 +0000 Subject: [PATCH] Initial contribution of Mac Port from Greg Watson. --- .../makegen/gnu/GnuMakefileGenerator.java | 4 +- .../plugin.properties | 11 +- .../plugin.xml | 449 ++++- core/org.eclipse.cdt.core.macosx/.cdtproject | 6 + core/org.eclipse.cdt.core.macosx/.classpath | 7 + core/org.eclipse.cdt.core.macosx/.cvsignore | 2 + core/org.eclipse.cdt.core.macosx/.project | 29 + core/org.eclipse.cdt.core.macosx/ChangeLog | 3 + .../build.properties | 8 + core/org.eclipse.cdt.core.macosx/fragment.xml | 23 + .../library/.cvsignore | 1 + .../library/Makefile | 46 + .../org.eclipse.cdt.core.macosx/library/PTY.h | 21 + .../library/PTYInputStream.h | 32 + .../library/PTYOutputStream.h | 29 + .../library/Spawner.h | 45 + .../library/SpawnerInputStream.h | 32 + .../library/SpawnerOutputStream.h | 29 + .../library/exec0.h | 11 + .../library/exec_unix.c | 135 ++ core/org.eclipse.cdt.core.macosx/library/io.c | 103 ++ .../library/openpty.c | 104 ++ .../library/openpty.h | 10 + .../library/pfind.c | 78 + .../org.eclipse.cdt.core.macosx/library/pty.c | 35 + .../library/ptyio.c | 107 ++ .../library/spawner.c | 218 +++ .../os/macosx/ppc/libpty.jnilib | Bin 0 -> 10220 bytes .../os/macosx/ppc/libspawner.jnilib | Bin 0 -> 15288 bytes .../cdt/internal/core/macosx/ProcessInfo.java | 45 + .../cdt/internal/core/macosx/ProcessList.java | 68 + core/org.eclipse.cdt.core/plugin.properties | 2 + core/org.eclipse.cdt.core/plugin.xml | 18 + .../utils/org/eclipse/cdt/utils/macho/AR.java | 336 ++++ .../cdt/utils/macho/ERandomAccessFile.java | 80 + .../org/eclipse/cdt/utils/macho/MachO.java | 1561 +++++++++++++++++ .../eclipse/cdt/utils/macho/MachOHelper.java | 315 ++++ .../cdt/utils/macho/SymbolSortCompare.java | 24 + .../cdt/utils/macho/parser/ARMember.java | 83 + .../cdt/utils/macho/parser/BinaryArchive.java | 80 + .../utils/macho/parser/MachOBinaryObject.java | 170 ++ .../cdt/utils/macho/parser/MachOParser.java | 147 ++ core/org.eclipse.cdt.ui/plugin.xml | 5 + .../cdt/ui/dialogs/MachOBinaryParserPage.java | 217 +++ 44 files changed, 4722 insertions(+), 7 deletions(-) create mode 100644 core/org.eclipse.cdt.core.macosx/.cdtproject create mode 100644 core/org.eclipse.cdt.core.macosx/.classpath create mode 100644 core/org.eclipse.cdt.core.macosx/.cvsignore create mode 100644 core/org.eclipse.cdt.core.macosx/.project create mode 100644 core/org.eclipse.cdt.core.macosx/ChangeLog create mode 100644 core/org.eclipse.cdt.core.macosx/build.properties create mode 100644 core/org.eclipse.cdt.core.macosx/fragment.xml create mode 100644 core/org.eclipse.cdt.core.macosx/library/.cvsignore create mode 100644 core/org.eclipse.cdt.core.macosx/library/Makefile create mode 100644 core/org.eclipse.cdt.core.macosx/library/PTY.h create mode 100644 core/org.eclipse.cdt.core.macosx/library/PTYInputStream.h create mode 100644 core/org.eclipse.cdt.core.macosx/library/PTYOutputStream.h create mode 100644 core/org.eclipse.cdt.core.macosx/library/Spawner.h create mode 100644 core/org.eclipse.cdt.core.macosx/library/SpawnerInputStream.h create mode 100644 core/org.eclipse.cdt.core.macosx/library/SpawnerOutputStream.h create mode 100644 core/org.eclipse.cdt.core.macosx/library/exec0.h create mode 100644 core/org.eclipse.cdt.core.macosx/library/exec_unix.c create mode 100644 core/org.eclipse.cdt.core.macosx/library/io.c create mode 100644 core/org.eclipse.cdt.core.macosx/library/openpty.c create mode 100644 core/org.eclipse.cdt.core.macosx/library/openpty.h create mode 100644 core/org.eclipse.cdt.core.macosx/library/pfind.c create mode 100644 core/org.eclipse.cdt.core.macosx/library/pty.c create mode 100644 core/org.eclipse.cdt.core.macosx/library/ptyio.c create mode 100644 core/org.eclipse.cdt.core.macosx/library/spawner.c create mode 100644 core/org.eclipse.cdt.core.macosx/os/macosx/ppc/libpty.jnilib create mode 100644 core/org.eclipse.cdt.core.macosx/os/macosx/ppc/libspawner.jnilib create mode 100644 core/org.eclipse.cdt.core.macosx/src/org/eclipse/cdt/internal/core/macosx/ProcessInfo.java create mode 100644 core/org.eclipse.cdt.core.macosx/src/org/eclipse/cdt/internal/core/macosx/ProcessList.java create mode 100644 core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/macho/AR.java create mode 100644 core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/macho/ERandomAccessFile.java create mode 100644 core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/macho/MachO.java create mode 100644 core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/macho/MachOHelper.java create mode 100644 core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/macho/SymbolSortCompare.java create mode 100644 core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/macho/parser/ARMember.java create mode 100644 core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/macho/parser/BinaryArchive.java create mode 100644 core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/macho/parser/MachOBinaryObject.java create mode 100644 core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/macho/parser/MachOParser.java create mode 100644 core/org.eclipse.cdt.ui/src/org/eclipse/cdt/ui/dialogs/MachOBinaryParserPage.java diff --git a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/makegen/gnu/GnuMakefileGenerator.java b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/makegen/gnu/GnuMakefileGenerator.java index 080ebe4a344..fda02ca13f0 100644 --- a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/makegen/gnu/GnuMakefileGenerator.java +++ b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/makegen/gnu/GnuMakefileGenerator.java @@ -347,7 +347,7 @@ public class GnuMakefileGenerator implements IManagedBuilderMakefileGenerator { outputPrefix = info.getOutputPrefix(outputExtension); // The command to build - String buildCmd = cmd + WHITESPACE + buildFlags + WHITESPACE + outflag + outputPrefix + OUT_MACRO + WHITESPACE + IN_MACRO; + String buildCmd = cmd + WHITESPACE + buildFlags + WHITESPACE + outflag + WHITESPACE + outputPrefix + OUT_MACRO + WHITESPACE + IN_MACRO; buffer.append(TAB + AT + ECHO + WHITESPACE + buildCmd + NEWLINE); buffer.append(TAB + AT + buildCmd); @@ -583,7 +583,7 @@ public class GnuMakefileGenerator implements IManagedBuilderMakefileGenerator { } buffer.append(NEWLINE); buffer.append(TAB + AT + ECHO + WHITESPACE + SINGLE_QUOTE + MESSAGE_START_BUILD + WHITESPACE + OUT_MACRO + SINGLE_QUOTE + NEWLINE); - buffer.append(TAB + cmd + WHITESPACE + flags + WHITESPACE + outflag + OUT_MACRO + WHITESPACE + "$(OBJS) $(USER_OBJS) $(LIBS)" + NEWLINE); //$NON-NLS-1$ + buffer.append(TAB + cmd + WHITESPACE + flags + WHITESPACE + outflag + WHITESPACE + OUT_MACRO + WHITESPACE + "$(OBJS) $(USER_OBJS) $(LIBS)" + NEWLINE); //$NON-NLS-1$ buffer.append(TAB + AT + ECHO + WHITESPACE + SINGLE_QUOTE + MESSAGE_FINISH_FILE + WHITESPACE + OUT_MACRO + SINGLE_QUOTE + NEWLINE + NEWLINE); // Always add a clean target diff --git a/build/org.eclipse.cdt.managedbuilder.ui/plugin.properties b/build/org.eclipse.cdt.managedbuilder.ui/plugin.properties index d141c037daa..624440fdfb0 100644 --- a/build/org.eclipse.cdt.managedbuilder.ui/plugin.properties +++ b/build/org.eclipse.cdt.managedbuilder.ui/plugin.properties @@ -29,7 +29,9 @@ TargetName.gnu.lib=Static Library (Gnu) TargetName.cygw.exe=Executable (Gnu on Windows) TargetName.cygw.so=Shared Library (Gnu on Windows) TargetName.cygw.lib=Static Library (Gnu on Windows) - +TargetName.macosx.exe=Executable (MacOS X) +TargetName.macosx.so=Shared Library (MacOS X) +TargetName.macosx.lib=Static Library (MacOS X) # No longer needed post-2.0 TargetName.cygw=Cygwin @@ -64,6 +66,10 @@ ToolName.linker.gnu.cpp = GCC C++ Linker ToolName.archiver.gnu = GCC Archiver ToolName.assembler.gnu = GCC Assembler +# Mach-O tool names +ToolName.linker.macosx.c = MacOS X C Linker +ToolName.linker.macosx.cpp = MacOS X C++ Linker + # Generic Category Names OptionCategory.Symbols = Symbols OptionCategory.Preproc = Preprocessor @@ -138,4 +144,5 @@ Option.Gnu.Assembler.version=Announce version (-v) Option.Windows.Windres.OutputFormat = Output format Option.Windows.Windres.OutputFormat.Coff = coff (--output-format coff) Option.Windows.Windres.OutputFormat.RC = rc (--output-format rc) -Option.Windows.Windres.OutputFormat.Res = res (--output-format res) \ No newline at end of file +Option.Windows.Windres.OutputFormat.Res = res (--output-format res) +Option.MacOSX.Linker.Shared=Shared (-Wl,-dylib) \ No newline at end of file diff --git a/build/org.eclipse.cdt.managedbuilder.ui/plugin.xml b/build/org.eclipse.cdt.managedbuilder.ui/plugin.xml index b61720b00a3..635d34ab4d8 100644 --- a/build/org.eclipse.cdt.managedbuilder.ui/plugin.xml +++ b/build/org.eclipse.cdt.managedbuilder.ui/plugin.xml @@ -479,6 +479,224 @@ name="%Option.Gnu.Assembler.version" id="gnu.both.asm.option.version"/> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/core/org.eclipse.cdt.core.macosx/.cdtproject b/core/org.eclipse.cdt.core.macosx/.cdtproject new file mode 100644 index 00000000000..31dce0c7c03 --- /dev/null +++ b/core/org.eclipse.cdt.core.macosx/.cdtproject @@ -0,0 +1,6 @@ + + + + + + diff --git a/core/org.eclipse.cdt.core.macosx/.classpath b/core/org.eclipse.cdt.core.macosx/.classpath new file mode 100644 index 00000000000..065ac06e197 --- /dev/null +++ b/core/org.eclipse.cdt.core.macosx/.classpath @@ -0,0 +1,7 @@ + + + + + + + diff --git a/core/org.eclipse.cdt.core.macosx/.cvsignore b/core/org.eclipse.cdt.core.macosx/.cvsignore new file mode 100644 index 00000000000..693869726de --- /dev/null +++ b/core/org.eclipse.cdt.core.macosx/.cvsignore @@ -0,0 +1,2 @@ +bin +doc diff --git a/core/org.eclipse.cdt.core.macosx/.project b/core/org.eclipse.cdt.core.macosx/.project new file mode 100644 index 00000000000..0cda5672e50 --- /dev/null +++ b/core/org.eclipse.cdt.core.macosx/.project @@ -0,0 +1,29 @@ + + + org.eclipse.cdt.core.macosx + + + org.eclipse.cdt.core + + + + org.eclipse.jdt.core.javabuilder + + + + + org.eclipse.pde.ManifestBuilder + + + + + org.eclipse.pde.SchemaBuilder + + + + + + org.eclipse.jdt.core.javanature + org.eclipse.pde.PluginNature + + diff --git a/core/org.eclipse.cdt.core.macosx/ChangeLog b/core/org.eclipse.cdt.core.macosx/ChangeLog new file mode 100644 index 00000000000..2d3f92fbf78 --- /dev/null +++ b/core/org.eclipse.cdt.core.macosx/ChangeLog @@ -0,0 +1,3 @@ +2004-04-25 Greg Watson + + Converted to MacOSX diff --git a/core/org.eclipse.cdt.core.macosx/build.properties b/core/org.eclipse.cdt.core.macosx/build.properties new file mode 100644 index 00000000000..4e44ac9b92f --- /dev/null +++ b/core/org.eclipse.cdt.core.macosx/build.properties @@ -0,0 +1,8 @@ +bin.includes = fragment.xml,\ + fragment.properties,\ + about.html,\ + cdt_macosx.jar,\ + os/ +src.includes = about.html,\ + library/ +source.cdt_macosx.jar = src/ diff --git a/core/org.eclipse.cdt.core.macosx/fragment.xml b/core/org.eclipse.cdt.core.macosx/fragment.xml new file mode 100644 index 00000000000..84fd4b3795d --- /dev/null +++ b/core/org.eclipse.cdt.core.macosx/fragment.xml @@ -0,0 +1,23 @@ + + + + + + + + + + + + + + diff --git a/core/org.eclipse.cdt.core.macosx/library/.cvsignore b/core/org.eclipse.cdt.core.macosx/library/.cvsignore new file mode 100644 index 00000000000..5761abcfdf0 --- /dev/null +++ b/core/org.eclipse.cdt.core.macosx/library/.cvsignore @@ -0,0 +1 @@ +*.o diff --git a/core/org.eclipse.cdt.core.macosx/library/Makefile b/core/org.eclipse.cdt.core.macosx/library/Makefile new file mode 100644 index 00000000000..4fd9486e984 --- /dev/null +++ b/core/org.eclipse.cdt.core.macosx/library/Makefile @@ -0,0 +1,46 @@ +# makefile for libspawner.so +# See http://developer.apple.com/documentation/Java/Conceptual/Java141Development/Core_APIs/chapter_6_section_4.html + +JAVA_HOME = /Library/Java/Home +ifeq ($(JAVA_HOME),) +$(warning JAVA_HOME not set in environment) +endif + +# Defaults which can be overridden. +OS = macosx +ARCH = ppc + +JDK_INCLUDES= $(JAVA_HOME)/include + +CC=gcc +LD=libtool +CPPFLAGS = -I. -I$(JDK_INCLUDES) #-I$(JDK_OS_INCLUDES) +CFLAGS +=-fPIC -D_REENTRANT + +INSTALL_DIR = ../os/$(OS)/$(ARCH) + +LIB_NAME_SPAWNER = libspawner.dylib +LIB_NAME_FULL_SPAWNER = $(INSTALL_DIR)/libspawner.jnilib +OBJS_SPAWNER=spawner.o io.o exec_unix.o pfind.o + +LIB_NAME_PTY = libpty.so +LIB_NAME_FULL_PTY = $(INSTALL_DIR)/libpty.jnilib +OBJS_PTY= openpty.o pty.o ptyio.o + +OBJS = $(OBJS_SPAWNER) $(OBJS_PTY) + +all: $(LIB_NAME_FULL_SPAWNER) $(LIB_NAME_FULL_PTY) + +rebuild: clean all + +$(LIB_NAME_FULL_SPAWNER) : $(OBJS_SPAWNER) + mkdir -p $(INSTALL_DIR) + $(CC) -dynamiclib -o $(LIB_NAME_FULL_SPAWNER) $(OBJS_SPAWNER) -lc -framework JavaVM + +$(LIB_NAME_FULL_PTY): $(OBJS_PTY) + mkdir -p $(INSTALL_DIR) + $(CC) -dynamiclib -o $(LIB_NAME_FULL_PTY) $(OBJS_PTY) -lc -framework JavaVM + +clean : + $(RM) $(OBJS_SPAWNER) $(LIB_NAME_FULL_SPAWNER) + $(RM) $(OBJS_PTY) $(LIB_NAME_FULL_PTY) diff --git a/core/org.eclipse.cdt.core.macosx/library/PTY.h b/core/org.eclipse.cdt.core.macosx/library/PTY.h new file mode 100644 index 00000000000..fabf58152d0 --- /dev/null +++ b/core/org.eclipse.cdt.core.macosx/library/PTY.h @@ -0,0 +1,21 @@ +/* DO NOT EDIT THIS FILE - it is machine generated */ +#include +/* Header for class org_eclipse_cdt_utils_pty_PTY */ + +#ifndef _Included_org_eclipse_cdt_utils_pty_PTY +#define _Included_org_eclipse_cdt_utils_pty_PTY +#ifdef __cplusplus +extern "C" { +#endif +/* + * Class: org_eclipse_cdt_utils_pty_PTY + * Method: forkpty + * Signature: ()I + */ +JNIEXPORT jstring JNICALL Java_org_eclipse_cdt_utils_pty_PTY_forkpty + (JNIEnv *, jobject); + +#ifdef __cplusplus +} +#endif +#endif diff --git a/core/org.eclipse.cdt.core.macosx/library/PTYInputStream.h b/core/org.eclipse.cdt.core.macosx/library/PTYInputStream.h new file mode 100644 index 00000000000..e7349272b56 --- /dev/null +++ b/core/org.eclipse.cdt.core.macosx/library/PTYInputStream.h @@ -0,0 +1,32 @@ +/* DO NOT EDIT THIS FILE - it is machine generated */ +#include +/* Header for class org_eclipse_cdt_utils_pty_PTYInputStream */ + +#ifndef _Included_org_eclipse_cdt_utils_pty_PTYInputStream +#define _Included_org_eclipse_cdt_utils_pty_PTYInputStream +#ifdef __cplusplus +extern "C" { +#endif +#undef org_eclipse_cdt_utils_pty_PTYInputStream_SKIP_BUFFER_SIZE +#define org_eclipse_cdt_utils_pty_PTYInputStream_SKIP_BUFFER_SIZE 2048L +/* Inaccessible static: skipBuffer */ +/* + * Class: org_eclipse_cdt_utils_pty_PTYInputStream + * Method: read0 + * Signature: (I[BI)I + */ +JNIEXPORT jint JNICALL Java_org_eclipse_cdt_utils_pty_PTYInputStream_read0 + (JNIEnv *, jobject, jint, jbyteArray, jint); + +/* + * Class: org_eclipse_cdt_utils_pty_PTYInputStream + * Method: close0 + * Signature: (I)I + */ +JNIEXPORT jint JNICALL Java_org_eclipse_cdt_utils_pty_PTYInputStream_close0 + (JNIEnv *, jobject, jint); + +#ifdef __cplusplus +} +#endif +#endif diff --git a/core/org.eclipse.cdt.core.macosx/library/PTYOutputStream.h b/core/org.eclipse.cdt.core.macosx/library/PTYOutputStream.h new file mode 100644 index 00000000000..fb28491060e --- /dev/null +++ b/core/org.eclipse.cdt.core.macosx/library/PTYOutputStream.h @@ -0,0 +1,29 @@ +/* DO NOT EDIT THIS FILE - it is machine generated */ +#include +/* Header for class org_eclipse_cdt_utils_pty_PTYOutputStream */ + +#ifndef _Included_org_eclipse_cdt_utils_pty_PTYOutputStream +#define _Included_org_eclipse_cdt_utils_pty_PTYOutputStream +#ifdef __cplusplus +extern "C" { +#endif +/* + * Class: org_eclipse_cdt_utils_pty_PTYOutputStream + * Method: write0 + * Signature: (I[BI)I + */ +JNIEXPORT jint JNICALL Java_org_eclipse_cdt_utils_pty_PTYOutputStream_write0 + (JNIEnv *, jobject, jint, jbyteArray, jint); + +/* + * Class: org_eclipse_cdt_utils_pty_PTYOutputStream + * Method: close0 + * Signature: (I)I + */ +JNIEXPORT jint JNICALL Java_org_eclipse_cdt_utils_pty_PTYOutputStream_close0 + (JNIEnv *, jobject, jint); + +#ifdef __cplusplus +} +#endif +#endif diff --git a/core/org.eclipse.cdt.core.macosx/library/Spawner.h b/core/org.eclipse.cdt.core.macosx/library/Spawner.h new file mode 100644 index 00000000000..287c8370ab0 --- /dev/null +++ b/core/org.eclipse.cdt.core.macosx/library/Spawner.h @@ -0,0 +1,45 @@ +/* DO NOT EDIT THIS FILE - it is machine generated */ +#include +/* Header for class com_qnx_tools_utils_spawner_Spawner */ + +#ifndef _Included_com_qnx_tools_utils_spawner_Spawner +#define _Included_com_qnx_tools_utils_spawner_Spawner +#ifdef __cplusplus +extern "C" { +#endif +/* + * Class: org_eclipse_cdt_utils_spawner_Spawner + * Method: exec0 + * Signature: ([Ljava/lang/String;[Ljava/lang/String;Ljava/lang/String;[I)I + */ +JNIEXPORT jint JNICALL Java_org_eclipse_cdt_utils_spawner_Spawner_exec0 + (JNIEnv *, jobject, jobjectArray, jobjectArray, jstring, jintArray); + +/* + * Class: org_eclipse_cdt_utils_spawner_Spawner + * Method: exec0 + * Signature: ([Ljava/lang/String;[Ljava/lang/String;Ljava/lang/String;[I)I + */ +JNIEXPORT jint JNICALL Java_org_eclipse_cdt_utils_spawner_Spawner_exec1 + (JNIEnv *, jobject, jobjectArray, jobjectArray, jstring); + +/* + * Class: org_eclipse_cdt_utils_spawner_Spawner + * Method: raise + * Signature: (II)I + */ +JNIEXPORT jint JNICALL Java_org_eclipse_cdt_utils_spawner_Spawner_raise + (JNIEnv *, jobject, jint, jint); + +/* + * Class: org_eclipse_cdt_utils_spawner_Spawner + * Method: waitFor + * Signature: (I)I + */ +JNIEXPORT jint JNICALL Java_org_eclipse_cdt_utils_spawner_Spawner_waitFor + (JNIEnv *, jobject, jint); + +#ifdef __cplusplus +} +#endif +#endif diff --git a/core/org.eclipse.cdt.core.macosx/library/SpawnerInputStream.h b/core/org.eclipse.cdt.core.macosx/library/SpawnerInputStream.h new file mode 100644 index 00000000000..ecf8f8c6a78 --- /dev/null +++ b/core/org.eclipse.cdt.core.macosx/library/SpawnerInputStream.h @@ -0,0 +1,32 @@ +/* DO NOT EDIT THIS FILE - it is machine generated */ +#include +/* Header for class com_qnx_tools_utils_spawner_SpawnerInputStream */ + +#ifndef _Included_com_qnx_tools_utils_spawner_SpawnerInputStream +#define _Included_com_qnx_tools_utils_spawner_SpawnerInputStream +#ifdef __cplusplus +extern "C" { +#endif +#undef com_qnx_tools_utils_spawner_SpawnerInputStream_SKIP_BUFFER_SIZE +#define com_qnx_tools_utils_spawner_SpawnerInputStream_SKIP_BUFFER_SIZE 2048L +/* Inaccessible static: skipBuffer */ +/* + * Class: org_elipse_cdt_utils_spawner_SpawnerInputStream + * Method: read0 + * Signature: (I[BI)I + */ +JNIEXPORT jint JNICALL Java_org_eclipse_cdt_utils_spawner_SpawnerInputStream_read0 + (JNIEnv *, jobject, jint, jbyteArray, jint); + +/* + * Class: org_eclipse_cdt_utils_spawner_SpawnerInputStream + * Method: close0 + * Signature: (I)I + */ +JNIEXPORT jint JNICALL Java_org_eclipse_cdt_utils_spawner_SpawnerInputStream_close0 + (JNIEnv *, jobject, jint); + +#ifdef __cplusplus +} +#endif +#endif diff --git a/core/org.eclipse.cdt.core.macosx/library/SpawnerOutputStream.h b/core/org.eclipse.cdt.core.macosx/library/SpawnerOutputStream.h new file mode 100644 index 00000000000..444d71c698c --- /dev/null +++ b/core/org.eclipse.cdt.core.macosx/library/SpawnerOutputStream.h @@ -0,0 +1,29 @@ +/* DO NOT EDIT THIS FILE - it is machine generated */ +#include +/* Header for class com_qnx_tools_utils_spawner_SpawnerOutputStream */ + +#ifndef _Included_com_qnx_tools_utils_spawner_SpawnerOutputStream +#define _Included_com_qnx_tools_utils_spawner_SpawnerOutputStream +#ifdef __cplusplus +extern "C" { +#endif +/* + * Class: org_eclipse_cdt_utils_spawner_SpawnerOutputStream + * Method: write0 + * Signature: (I[BI)I + */ +JNIEXPORT jint JNICALL Java_org_eclipse_cdt_utils_spawner_SpawnerOutputStream_write0 + (JNIEnv *, jobject, jint, jbyteArray, jint); + +/* + * Class: org_eclipse_cdt_utils_spawner_SpawnerOutputStream + * Method: close0 + * Signature: (I)I + */ +JNIEXPORT jint JNICALL Java_org_eclipse_cdt_utils_spawner_SpawnerOutputStream_close0 + (JNIEnv *, jobject, jint); + +#ifdef __cplusplus +} +#endif +#endif diff --git a/core/org.eclipse.cdt.core.macosx/library/exec0.h b/core/org.eclipse.cdt.core.macosx/library/exec0.h new file mode 100644 index 00000000000..354b1c3d769 --- /dev/null +++ b/core/org.eclipse.cdt.core.macosx/library/exec0.h @@ -0,0 +1,11 @@ +#include +#include +#include +#include +#include + +extern pid_t exec0(const char *path, char *const argv[], + char *const envp[], const char *dirpath, + int channels[3] ); + +extern int wait0(pid_t pid); diff --git a/core/org.eclipse.cdt.core.macosx/library/exec_unix.c b/core/org.eclipse.cdt.core.macosx/library/exec_unix.c new file mode 100644 index 00000000000..6cb8ac88d8b --- /dev/null +++ b/core/org.eclipse.cdt.core.macosx/library/exec_unix.c @@ -0,0 +1,135 @@ +#include "exec0.h" +#include +#include +#include +#include +#include +#include +#include + +/* from pfind.c */ +extern char *pfind(const char *name); + +pid_t +exec0(const char *path, char *const argv[], char *const envp[], + const char *dirpath, int channels[3]) +{ + int pipe0[2], pipe1[2], pipe2[2]; + pid_t childpid; + char *full_path; + + /* + * We use pfind() to check that the program exists and is an executable. + * If not pass the error up. Also execve() wants a full path. + */ + full_path = pfind(path); + if (full_path == NULL) { + fprintf(stderr, "Unable to find full path for \"%s\"\n", (path) ? path : ""); + return -1; + } + + /* + * Make sure we can create our pipes before forking. + */ + if (channels != NULL) { + if (pipe(pipe0) < 0 || pipe(pipe1) < 0 || pipe(pipe2) < 0) { + fprintf(stderr, "%s(%d): returning due to error.\n", + __FUNCTION__, __LINE__); + free(full_path); + return -1; + } + } + + childpid = fork(); + + if (childpid < 0) { + fprintf(stderr, "%s(%d): returning due to error: %s\n", + __FUNCTION__, __LINE__, strerror(errno)); + free(full_path); + return -1; + } else if (childpid == 0) { /* child */ + char *ptr; + + chdir(dirpath); + + if (channels != NULL) { + /* Close the write end of pipe0 */ + if (close(pipe0[1]) == -1) + perror("close(pipe0[1])"); + + /* Close the read end of pipe1 */ + if (close(pipe1[0]) == -1) + perror("close(pipe1[0])"); + + /* Close the read end of pipe2 */ + if (close(pipe2[0]) == -1) + perror("close(pipe2[0]))"); + + /* redirections */ + dup2(pipe0[0], STDIN_FILENO); /* dup stdin */ + dup2(pipe1[1], STDOUT_FILENO); /* dup stdout */ + dup2(pipe2[1], STDERR_FILENO); /* dup stderr */ + } + + /* Close all the fd's in the child */ + { + int fdlimit = sysconf(_SC_OPEN_MAX); + int fd = 3; + + while (fd < fdlimit) + close(fd++); + } + + if (envp[0] == NULL) { + execv(full_path, argv); + } else { + execve(full_path, argv, envp); + } + + _exit(127); + + } else if (childpid != 0) { /* parent */ + + char b; + + if (channels != NULL) { + /* close the read end of pipe1 */ + if (close(pipe0[0]) == -1) + perror("close(pipe0[0])"); + + /* close the write end of pipe2 */ + if (close(pipe1[1]) == -1) + perror("close(pipe1[1])"); + + /* close the write end of pipe2 */ + if (close(pipe2[1]) == -1) + perror("close(pipe2[1])"); + + channels[0] = pipe0[1]; /* Output Stream. */ + channels[1] = pipe1[0]; /* Input Stream. */ + channels[2] = pipe2[0]; /* Input Stream. */ + } + + free(full_path); + return childpid; + } + + free(full_path); + return -1; /*NOT REACHED */ +} + + +int wait0(pid_t pid) +{ + int status; + int val = -1; + + if (pid < 0 || waitpid(pid, &status, 0) < 0) + return -1; + + if (WIFEXITED(status)) { + val = WEXITSTATUS(status); + } + + return val; +} diff --git a/core/org.eclipse.cdt.core.macosx/library/io.c b/core/org.eclipse.cdt.core.macosx/library/io.c new file mode 100644 index 00000000000..499d4a7b567 --- /dev/null +++ b/core/org.eclipse.cdt.core.macosx/library/io.c @@ -0,0 +1,103 @@ +#include +#include +#include +#include +#include + +/* Header for class _org_eclipse_cdt_utils_spawner_SpawnerInputStream */ +/* Header for class _org_eclipse_cdt_utils_spawner_SpawnerOutputStream */ + +/* + * Class: org_eclipse_cdt_utils_spawner_SpawnerInputStream + * Method: read0 + * Signature: (I)I + */ +JNIEXPORT jint JNICALL +Java_org_eclipse_cdt_utils_spawner_SpawnerInputStream_read0(JNIEnv * env, + jobject jobj, + jint jfd, + jbyteArray buf, + jint buf_len) +{ + int fd; + int status; + jbyte *data; + int data_len; + + data = (*env)->GetByteArrayElements(env, buf, 0); + data_len = buf_len; + fd = jfd; + + status = read( fd, data, data_len ); + (*env)->ReleaseByteArrayElements(env, buf, data, 0); + + if (status == 0) { + /* EOF. */ + status = -1; + } else if (status == -1) { + /* Error, toss an exception */ + jclass exception = (*env)->FindClass(env, "java/io/IOException"); + if (exception == NULL) { + /* Give up. */ + return -1; + } + (*env)->ThrowNew(env, exception, "read error"); + } + + return status; +} + + +/* + * Class: org_eclipse_cdt_utils_spawner_SpawnerInputStream + * Method: close0 + * Signature: (I)I + */ +JNIEXPORT jint JNICALL +Java_org_eclipse_cdt_utils_spawner_SpawnerInputStream_close0(JNIEnv * env, + jobject jobj, + jint fd) +{ + return close(fd); +} + +/* + * Class: org_eclipse_cdt_utils_spawner_SpawnerOutputStream + * Method: write0 + * Signature: (II)I + */ +JNIEXPORT jint JNICALL +Java_org_eclipse_cdt_utils_spawner_SpawnerOutputStream_write0(JNIEnv * env, + jobject jobj, + jint jfd, + jbyteArray buf, + jint buf_len) +{ + int status; + int fd; + jbyte *data; + int data_len; + + data = (*env)->GetByteArrayElements(env, buf, 0); + data_len = buf_len; + fd = jfd; + + status = write(fd, data, data_len); + (*env)->ReleaseByteArrayElements(env, buf, data, 0); + + return status; +} + + +/* + * Class: org_eclipse_cdt_utils_spawner_SpawnerOutputStream + * Method: close0 + * Signature: (I)I + */ +JNIEXPORT jint JNICALL +Java_org_eclipse_cdt_utils_spawner_SpawnerOutputStream_close0(JNIEnv * env, + jobject jobj, + jint fd) +{ + return close(fd); +} diff --git a/core/org.eclipse.cdt.core.macosx/library/openpty.c b/core/org.eclipse.cdt.core.macosx/library/openpty.c new file mode 100644 index 00000000000..b1660a13b78 --- /dev/null +++ b/core/org.eclipse.cdt.core.macosx/library/openpty.c @@ -0,0 +1,104 @@ +/* + * (c) Copyright QNX Software Systems Ltd. 2002. + * All Rights Reserved. + * + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +/** + * This is taken from R. W. Stevens book. + * Alain Magloire. + */ + +int ptym_open (char *pts_name); +int ptys_open (int fdm, char * pts_name); + +int +openpty(int *amaster, int *aslave, char *name, struct termios *termp, struct winsize *winp) +{ + char line[20]; + line[0]=0; + *amaster = ptym_open(line); + if (*amaster < 0) + return -1; + *aslave = ptys_open(*amaster, line); + if (*aslave < 0) { + close(*amaster); + return -1; + } + if (name) + strcpy(name, line); +#ifndef TCSAFLUSH +#define TCSAFLUSH TCSETAF +#endif + if (termp) + (void) tcsetattr(*aslave, TCSAFLUSH, termp); +#ifdef TIOCSWINSZ + if (winp) + (void) ioctl(*aslave, TIOCSWINSZ, (char *)winp); +#endif + return 0; +} + +int +ptym_open(char * pts_name) +{ + char *ptr1, *ptr2; + int fdm; + + strcpy(pts_name, "/dev/ptyXY"); + /* array index: 012345689 (for references in following code) */ + for (ptr1 = "pqrstuvwxyzPQRST"; *ptr1 != 0; ptr1++) { + pts_name[8] = *ptr1; + for (ptr2 = "0123456789abcdef"; *ptr2 != 0; ptr2++) { + pts_name[9] = *ptr2; + /* try to open master */ + fdm = open(pts_name, O_RDWR); + if (fdm < 0) { + if (errno == ENOENT) {/* different from EIO */ + return -1; /* out of pty devices */ + } else { + continue; /* try next pty device */ + } + } + pts_name[5] = 't'; /* chage "pty" to "tty" */ + return fdm; /* got it, return fd of master */ + } + } + return -1; /* out of pty devices */ +} + +int +ptys_open(int fdm, char * pts_name) +{ + int gid, fds; + struct group *grptr; + + grptr = getgrnam("tty"); + if (grptr != NULL) { + gid = grptr->gr_gid; + } else { + gid = -1; /* group tty is not in the group file */ + } + + /* following two functions don't work unless we're root */ + chown(pts_name, getuid(), gid); + chmod(pts_name, S_IRUSR | S_IWUSR | S_IWGRP); + fds = open(pts_name, O_RDWR); + if (fds < 0) { + close(fdm); + return -1; + } + return fds; +} diff --git a/core/org.eclipse.cdt.core.macosx/library/openpty.h b/core/org.eclipse.cdt.core.macosx/library/openpty.h new file mode 100644 index 00000000000..fd7b7be1b2f --- /dev/null +++ b/core/org.eclipse.cdt.core.macosx/library/openpty.h @@ -0,0 +1,10 @@ +/* + * (c) Copyright QNX Software Systems Ltd. 2002. + * All Rights Reserved. + * + */ +#ifndef _OPENPTY_H +#define _OPENPTY_H +int ptym_open (char *pts_name); +int ptys_open (int fdm, char * pts_name); +#endif diff --git a/core/org.eclipse.cdt.core.macosx/library/pfind.c b/core/org.eclipse.cdt.core.macosx/library/pfind.c new file mode 100644 index 00000000000..d13dae5f0e2 --- /dev/null +++ b/core/org.eclipse.cdt.core.macosx/library/pfind.c @@ -0,0 +1,78 @@ +/* + * pfind.c - Search for a binary in $PATH. + */ + +#include +#include +#include +#include +#include + +#ifndef PATH_MAX +#define PATH_MAX 1024 +#endif + + +char * pfind(const char *name) +{ + char *tok; + char *sp; + char *path; + char fullpath[PATH_MAX+1]; + + /* Sanity check. */ + if (name == NULL) { + fprintf(stderr, "pfind(): Null argument.\n"); + return NULL; + } + + /* For absolute name or name with a path, check if it is an executable. */ + if (name[0] == '/' || name[0] == '.') { + if (access(name, X_OK | R_OK) == 0) { + return strdup(name); + } + return NULL; + } + + /* Search in the PATH environment. */ + path = getenv("PATH" ); + + if (path == NULL || strlen(path) <= 0) { + fprintf(stderr, "Unable to get $PATH.\n"); + return NULL; + } + + /* The value return by getenv() is readonly */ + path = strdup(path); + + tok = strtok_r(path, ":", &sp); + while (tok != NULL) { + snprintf(fullpath, sizeof(fullpath) - 1, "%s/%s", tok, name); + + if (access(fullpath, X_OK | R_OK) == 0) { + free(path); + return strdup(fullpath); + } + + tok = strtok_r( NULL, ":", &sp ); + } + + free(path); + return NULL; +} + +#ifdef BUILD_WITH_MAIN +int main(int argc, char **argv) +{ + int i; + char *fullpath; + + for (i=1; i= 0) { + /* Get a reference to the obj's class */ + cls = (*env)->GetObjectClass(env, jobj); + + /* Set the master fd. */ + fid = (*env)->GetFieldID(env, cls, "master", "I"); + if (fid == NULL) { + return NULL; + } + (*env)->SetIntField(env, jobj, fid, (jint)master); + + /* Create a new String for the slave. */ + jstr = (*env)->NewStringUTF(env, line); + } + return jstr; +} diff --git a/core/org.eclipse.cdt.core.macosx/library/ptyio.c b/core/org.eclipse.cdt.core.macosx/library/ptyio.c new file mode 100644 index 00000000000..67d7594154d --- /dev/null +++ b/core/org.eclipse.cdt.core.macosx/library/ptyio.c @@ -0,0 +1,107 @@ +#include +#include +#include +#include +#include + +/* Header for class _org_eclipse_cdt_utils_pty_PTYInputStream */ +/* Header for class _org_eclipse_cdt_utils_pty_PTYOutputStream */ + +/* + * Class: org_eclipse_cdt_utils_pty_PTYInputStream + * Method: read0 + * Signature: (I)I + */ +JNIEXPORT jint JNICALL +Java_org_eclipse_cdt_utils_pty_PTYInputStream_read0(JNIEnv * env, + jobject jobj, + jint jfd, + jbyteArray buf, + jint buf_len) +{ + int fd; + int status; + jbyte *data; + int data_len; + + data = (*env)->GetByteArrayElements(env, buf, 0); + data_len = buf_len; + fd = jfd; + + status = read( fd, data, data_len ); + (*env)->ReleaseByteArrayElements(env, buf, data, 0); + + if (status == 0) { + /* EOF. */ + status = -1; + } else if (status == -1) { + /* Error, toss an exception */ + /* Ignore the error for now, the debugger will attempt + * to close this multiple time. */ +#if 0 + jclass exception = (*env)->FindClass(env, "java/io/IOException"); + if (exception == NULL) { + /* Give up. */ + return -1; + } + (*env)->ThrowNew(env, exception, "read error"); +#endif + } + + return status; +} + + +/* + * Class: org_eclipse_cdt_utils_pty_PTYInputStream + * Method: close0 + * Signature: (I)I + */ +JNIEXPORT jint JNICALL +Java_org_eclipse_cdt_utils_pty_PTYInputStream_close0(JNIEnv * env, + jobject jobj, + jint fd) +{ + return close(fd); +} + +/* + * Class: org_eclipse_cdt_utils_pty_PTYOutputStream + * Method: write0 + * Signature: (II)I + */ +JNIEXPORT jint JNICALL +Java_org_eclipse_cdt_utils_pty_PTYOutputStream_write0(JNIEnv * env, + jobject jobj, + jint jfd, + jbyteArray buf, + jint buf_len) +{ + int status; + int fd; + jbyte *data; + int data_len; + + data = (*env)->GetByteArrayElements(env, buf, 0); + data_len = buf_len; + fd = jfd; + + status = write(fd, data, data_len); + (*env)->ReleaseByteArrayElements(env, buf, data, 0); + + return status; +} + + +/* + * Class: org_eclipse_cdt_utils_pty_PTYOutputStream + * Method: close0 + * Signature: (I)I + */ +JNIEXPORT jint JNICALL +Java_org_eclipse_cdt_utils_pty_PTYOutputStream_close0(JNIEnv * env, + jobject jobj, + jint fd) +{ + return close(fd); +} diff --git a/core/org.eclipse.cdt.core.macosx/library/spawner.c b/core/org.eclipse.cdt.core.macosx/library/spawner.c new file mode 100644 index 00000000000..4624d763cdd --- /dev/null +++ b/core/org.eclipse.cdt.core.macosx/library/spawner.c @@ -0,0 +1,218 @@ +#include +#include +#include +#include +#include +#include + +#include "exec0.h" +#include + + +#define DEBUGIT 0 + + +/* + * Header for class org_eclipse_cdt_utils_spawner_Spawner + */ + + +#if DEBUGIT +static void print_array(char **c_array) +{ + if (c_array) { + char **p = c_array; + for (; *p; p++) { + if (*p) { + fprintf(stderr, " %s", *p); + } + } + } else { + fprintf(stderr, "null"); + } + fprintf(stderr, "\n"); +} +#endif + + +static char **alloc_c_array(JNIEnv * env, jobjectArray j_array) +{ + int i; + jint c_array_size = (*env)->GetArrayLength(env, j_array); + char **c_array = calloc(c_array_size + 1, sizeof(*c_array)); + + if (c_array == NULL) + return NULL; + + for (i = 0; i < c_array_size; i++) { + jstring j_str = + (jstring) (*env)->GetObjectArrayElement(env, j_array, i); + const char *c_str = (*env)->GetStringUTFChars(env, j_str, NULL); + c_array[i] = (char *) strdup(c_str); + (*env)->ReleaseStringUTFChars(env, j_str, c_str); + (*env)->DeleteLocalRef(env, j_str); + } + + return c_array; +} + + +static void free_c_array(char **c_array) +{ + if (c_array) { + char **p = c_array; + for (; *p; p++) { + if (*p) { + free(*p); + } + } + free(c_array); + } +} + + +JNIEXPORT jint JNICALL +Java_org_eclipse_cdt_utils_spawner_Spawner_exec1(JNIEnv * env, jobject jobj, + jobjectArray jcmd, + jobjectArray jenv, + jstring jdir) +{ + const char *dirpath = (*env)->GetStringUTFChars(env, jdir, NULL); + char **cmd; + char **envp; + pid_t pid = -1; + + cmd = alloc_c_array(env, jcmd); + if (cmd == NULL) + goto bail_out; + + envp = alloc_c_array(env, jenv); + if (envp == NULL) + goto bail_out; + +#if DEBUGIT + fprintf(stderr, "command:"); + print_array(cmd); + fprintf(stderr, "Envp:"); + print_array(envp); + fprintf(stderr, "dirpath: %s\n", dirpath); +#endif + + pid = exec0(cmd[0], cmd, envp, dirpath, NULL); + if (pid < 0) + goto bail_out; + + bail_out: + (*env)->ReleaseStringUTFChars(env, jdir, dirpath); + if (cmd) + free_c_array(cmd); + if (envp) + free_c_array(envp); + return pid; +} + +/* + * Class: org_eclipse_cdt_utils_spawner_Spawner + * Method: exec0 + * Signature: ([Ljava/lang/String;[Ljava/lang/String;Ljava/lang/String;[I)I + */ +JNIEXPORT jint JNICALL +Java_org_eclipse_cdt_utils_spawner_Spawner_exec0(JNIEnv * env, jobject jobj, + jobjectArray jcmd, + jobjectArray jenv, + jstring jdir, + jintArray jchannels) +{ + jint *channels = (*env)->GetIntArrayElements(env, jchannels, 0); + const char *dirpath = (*env)->GetStringUTFChars(env, jdir, NULL); + char **cmd; + char **envp; + int fd[3]; + pid_t pid = -1; + + if (channels == NULL) + goto bail_out; + + cmd = alloc_c_array(env, jcmd); + if (cmd == NULL) + goto bail_out; + + envp = alloc_c_array(env, jenv); + if (envp == NULL) + goto bail_out; + +#if DEBUGIT + fprintf(stderr, "command:"); + print_array(cmd); + fprintf(stderr, "Envp:"); + print_array(envp); + fprintf(stderr, "dirpath: %s\n", dirpath); +#endif + + pid = exec0(cmd[0], cmd, envp, dirpath, fd); + if (pid < 0) + goto bail_out; + + channels[0] = fd[0]; + channels[1] = fd[1]; + channels[2] = fd[2]; + + bail_out: + (*env)->ReleaseIntArrayElements(env, jchannels, channels, 0); + (*env)->ReleaseStringUTFChars(env, jdir, dirpath); + if (cmd) + free_c_array(cmd); + if (envp) + free_c_array(envp); + return pid; +} + +/* + * Class: org_eclipse_cdt_utils_spawner_Spawner + * Method: raise + * Signature: (II)I + */ +JNIEXPORT jint JNICALL +Java_org_eclipse_cdt_utils_spawner_Spawner_raise(JNIEnv * env, jobject jobj, + jint pid, jint sig) +{ + int status = -1; + + switch (sig) { + case 0: /* NOOP */ + status = kill(pid, 0); + break; + + case 2: /* INTERRUPT */ + status = kill(pid, SIGINT); + break; + + case 9: /* KILL */ + status = kill(pid, SIGKILL); + break; + + case 15: /* TERM */ + status = kill(pid, SIGTERM); + break; + + default: + status = kill(pid, sig); /* WHAT ?? */ + break; + } + + return status; +} + + + +/* + * Class: org_eclipse_cdt_utils_spawner_Spawner + * Method: waitFor + * Signature: (I)I + */ +JNIEXPORT jint JNICALL +Java_org_eclipse_cdt_utils_spawner_Spawner_waitFor(JNIEnv * env, + jobject jobj, jint pid) +{ + return wait0(pid); +} diff --git a/core/org.eclipse.cdt.core.macosx/os/macosx/ppc/libpty.jnilib b/core/org.eclipse.cdt.core.macosx/os/macosx/ppc/libpty.jnilib new file mode 100644 index 0000000000000000000000000000000000000000..8f240a9318684bdaed5eadc01b0949674f37c989 GIT binary patch literal 10220 zcmeHNU2Ggz6+Zi8d!2tZKXseLSto9rgy2omv}_{>t({G~p=of5RXIY+^?G(}58mBb zW@nRiSf>-=BBKVhh$2~)>l!Iod5F{sfdoQLlNXc+tH29ylvDy#r1qiWr9f2kojZ5z zaqMK>3M3x(%4g4+d;aeI?wJ|S-1+R|f4xUU4}rKff|`lKVenT#0sN(e=snTbi=!oN zlRA>T2?q@z_9G!|y==4Ow&nhf6GTl(qywj*XXm)?@=%C^p%q7S17=nf?b5*V80+U; zKgoSDD5B!E`(kj2Lo3G!+$6d;M%arH6+$c8mXRM)L6^tacm*oVR`P{$pwBNW9FtwW zT`G`djGdo|aSVYJj+wNbmWJ|2h?V@=R<40BAJVBNL}oOb@s4E}-*PcGDC6y1yg^QMpZ2jqdk^I8wW_^2gOJv0k0TSrICEXHza%`BE*($P%s!t!>2qoA@2Fe(xQ4M) z#(70JSv_^`tucgnYUwWZq(Cdl4q+3P9%ok%_N{0|=j7baTSO)(RQTrW~ z3Xg9ss0YODVMScOyFk$IiGt&JPd_-$(e?~Dbi1#E?*yq9Wxf%#4FoWESHL-bz10!; zpCeF-1ZTV7q=vDH;A|xlnjLer^06yKm#;M2W8V+WR@Q~QDV$2B5vK{Mx{K5R)YJeiIwaw3Pj+Z|S&UU_x3xXDzj9;b%;=FSiJcfK- zH)sp%9Id&B^CCu@6QJRE8};+JzKd9=9g=b1y*2--itALqy0%=sM3dENnyTKQndF zyy+C;o$M5lyPNu|=O}@ki3#9Rp(a~mGffd-GKc>1GrK9`=_m1@it@|CFNyx-3V!3t zui4YHALr*er>G&v*kUdz%sVCXO;J1gpQ;RCtuPMs1ryVBKw*pV!WLtRcT)p!uqR=| zzKFrP1Dq!wqyUbSsI4rH6Y7|2t=)@*F`W7$*rCQMZv8eUQxsk{eysNvCD$D&)kHApXAg zC+Ed$xQaQwt*)iRm{S&WDj-)OMZpt1j#b8x*PH(`E=i0dxrj?}tHOn^S02{2a7nCk z{P)2i&{Ycqc@M?Ckne+hJ$~iYU|gLC@}9MVen$;GJy;+3OAY<)8v5%s^wk=A`Tv1; zuU|gDKwl02&Kmk?4So2*dit=2e$Lao&uT(TXR{(_W=dII7Unq}W?0NAUXXKO7!9$0iJo41jUx`1H9?&xSATC{G z+oP0A{YNTH}QKO#XTKk|6biIs$bB>Il>ks3TBEppHNtfjRyCC^>RS-s$pS zbOV2FAorbvCpPfc19A^H_)XOx!Ir0;k-NB!cOd`3C;uEl7Fseu$jLTDkg*5a_^FZ~ z!B#Nh$o@wm!%oWEA!8oFTkQ+J!M{4Jlr8v)L$noQ0(-1YH{CHHW+-w;%1yv3)QkY! z`XH}y$Hx5>ZguVNK;EI`n~-Bl{uSisl#KT+)bGlWh`zH?`bH3wzURu#uR*q4S;qgs zmDdad$G2R0-EGM0l{^mlxGS%H8*r zq8#|!qD=4kuopc3eZfNl)*2W(R(u|C*`Zkof^^)K*A$`H|--57He z)COYc_kebR9tS-J+6USTV!IX)?}hINJpqb>KDVC(Cp6SIg+RPl&b(D|)Q~(zT~QE( zTB87n^D^f#fCv5o?r*Zv(ZT!d_i2Hm4@;=qfVChW9fyyRtOUdV%G&7w|XNVkWqd^#tkk^#M8YIfF*N*J4^6%g9iin^V) z`C}aZd_6|;HgR9Bl z_kwF?RZd?o*YTRzWUo zHhpo_`#8y4Up;SIqoQCMdD}Hww$S$$k86wyh@CM@mZl$1Yr}f%c(KIvS*8q&1GLNjv(BdcdRP^61{0E@MI^x3@!4;v McWlt@mFMMu091t2ApigX literal 0 HcmV?d00001 diff --git a/core/org.eclipse.cdt.core.macosx/os/macosx/ppc/libspawner.jnilib b/core/org.eclipse.cdt.core.macosx/os/macosx/ppc/libspawner.jnilib new file mode 100644 index 0000000000000000000000000000000000000000..a7c51580ace9f341d842c57ecff09de4c8704f72 GIT binary patch literal 15288 zcmeHOe{5679Y6ayzes?LhAkADIy7k$n#KvgYSJ({)KD`rnu)YaRmzL={DNQO*slFt zoGO9G7Nnq}$!IX85~cZrBBr5HuTQKV*zJb6R?a*_>x(Ij$+mvC*MeL{93d zp_^^2?l9YNZnMG2cS=n*8)Tw0zYS@Sv4uAH_{oM_mX)NQ(4zY(hjg=zh72%@Ge$f& zmIboF(cjbGLsqQhhENN#I3pY-kian%)Pu;0B+L2QldhXIvKa7b%eD!PMM5G2md6J5 z12y76y*>KQ!R+A-Jj$$Is`7B@~4K?zExXlKS$<1T~ z$pP}pa_`RFySDpxW@EAg#e^gA>RJ4weo2=SjcX~W8&vPhbe;w0slDA3OL|6wN-UZ7 z#N&!5q75bE!2?k>(f)K)LyoJ_m^OmyeSuF;vPU4nvL}^HkUr6#v81k!wr^_()V4MQ zyv@PtU$JeXjj8DA)rJzm#F%GCA~>oZh$Tjnp05R;4L<($_F=2U^SGKwYO!e2(`$2hNnZ)NO3VD9RLTn*|2QCcO4%9>1h6By}iBA>9vH)p^f#IW4pUXVzHA6olUMZCjC?QZnpoBmPff53F5E!p?p568mE1Q^do*l20&Q2Igdh0R94j-$# zIB`@uJ6f_Ld&a>TzaBwRt-t!)2KG=EnFt`W(^;~9kRA(r4Z&1Im(P%hW*xSek$**t2)^3Aw zyRW@I_ldBZ8UJc^I&+XsWlpnW#y&P>;F-m6mUkE^Gf+nUTlU5WSEn-#%nv=k*U22? zl9cx1;XS~X9}#r{qk#oH24lX{td<@ypx=*&{f~w0L%omMA2MoL&nZ@ky0>lpdaZtq z%gmRj?_Qg3i_q=$&M=low-5Dw0k-VwxVAb?{q{R+yU4%sZO*#mYcbB;c-t&n=(o>q zE2kq}vvd~J`v?n+ljfs|?9-T`+ix_Y56mCo|1)5o2mcv?Klzs?+=ntW%R?xB<8vo<2_FP z-sZe!*Q0$M2;6D!nnZm2!6}}c=!4d(DZj|-giLF=3Gr))d=>Imo8^$PC$SL5WMJ<^ zELU9>xcX2&D9W8E|Bbt$@f`*Z z5yUseaXi2(KO!)+Fro6i}i6`K};L7ZaU7N_SB z^XCz#7Z9fxfyFF*J%`wTU5sNd=4r2(=YEXoTxK8BQFcz0)pyHy?x8Y}cUu*&r!r$( zb=W(^E|@V?^%lmi!|qNID_CF7>##FRcCb%OdJ*HOucCf=*(v75{v4q77ho0tu$8-M z-xlS+x0Ta5+MTEGznk&5qz>z%8MfZU821M77;Ezd{#1;LF%Q760Y1J{^gIWAhww}_ zMEh3-_wVLDmaMV$;W5vUil;)|$`4 zOMp@NcIX74v$cQ@_T2JD=zy24Dxfony3e5FGxz1PUqkMN>_9o;(+?T@a@i~1K~@HS z9D7;_&$SX_J`8{9{0!NiYn#0LSorW-#wOgm(py@Y<2Yn%>d?nt ztef+&y%O`5%_B}O1eogs^m_>W6>BaKBbRJA(f$N1TzviK!3nWeb{CBaIx7ocfb+uj zDUCJ2BpzRR?3{qkZ{YhZ`u2-6eO8?L0b8Et)qE!4u_ZN<-@poSWsVJfEVbeQea3I& zxhuP0iFS0ZT5F>THqzeHn7MigiQlz}k}$CwR7Oz~=#0e$b3NJVzrx&UVE4 z{zc=$I)lAHai9Lfp9ORKhilqsa7_!lE#|tYXvwYn@(}QQ%=|p$Ld-cb#y;2dloPSR zDs;5-U|!cOC~HRB7blYfQj#u+W^-98ci$I(=5B&vZwgcfBh<8}rZAdFp42)SoI+ZxpEy6{!yt zsc$P%Uwi9%>Ej~xzbjIIsYv}yk^0FZ_2DA*y+!IfiqzNLy59Lok^1+F)L$u5f2K(N zRFV2fk@~(O^&5-S*WbF{aowtyWxB7Fm0%M5?bxk#yWGvmB}|FLl4?s_ zi>n<^c0Sc=%XdE6F)zQK@~vdw-e$f|=K>q+c|K0VX@S$bX+*)q{?w=%)lFafdT?wb z<;K2W)!j{0%oVy&*PQe;CrN2uqWkzSisp4(%9Ic&Ay7h~gg^;_5&|UzN(ht?C?QZn zpoBmPff54$R|MR!?(i|@hQRq6!RrOD6CA$>=Jhp#w+Y@NIDTu)>qCMM3cgqH0m1RB zZLZfRc(362?tz#41&2>O-z_-4n&o-?7MpW?9mBaUcwF#^;9-+XJV>g)EzL{W-{fQGOk5FPZWx!0k*rn1g!(c^oqN zg5>;`t^Ch9+0mVookwl5Y?JXbx2(s6SixZ%qfPM;k8?ON2g@LMnGPVS5SR-gXh-8Wdyf?sF zK(sX0f#~Iehd}p&9ssq0=qpC_#WsNG`%N#1!nhr@5##~g1ETjjwtzZ8@aK!`%RpyH z&7iwMP7pBS+%0&6;8@Q*2p>5K8bK?edpGLu z0=YpApmiwU1j07K>(`>J5riF?PyfB(tsv67AJhhV0MrihfT)iRpnE_YL0(W7=phjG zcMoh)7~O}wrQZp8Gl=}!0wTS7jD_BVvfXFM562^^BoWH_y~l7Ws>qR8Y$O$D%J8W9 z>e~>$>c_2w99AQ7HNm(deAfO3me?<=N<@n%Rapt?a!S`C zNm;zWd%KQT6e{M}zPK#>%XiEP)ea~xtAff3hdgnu6GWh~9sF1?V zyatxaTofnA zl1eNJJpw?Wg@Da?}|8>Lz)gJc;rWd&y87c5?TuYS6_)SIUa+{rqWF-Vd3gBm9a!Tdt#}CqCOl{ z!m8)tWQyp4jhj6MD>TJgwCxJpuPEzfB{mw@B5J4|_~tGvbBnucM@vUrXX{q}pFJDX rLS4Ek$GgDSw{BerwxMPreferences>Java>Templates. + * To enable and disable the creation of type comments go to + * Window>Preferences>Java>Code Generation. + */ +public class ProcessInfo implements IProcessInfo { + + int pid; + String name; + + public ProcessInfo(String pidString, String name) { + try { + pid = Integer.parseInt(pidString); + } catch (NumberFormatException e) { + } + this.name = name; + } + + public ProcessInfo(int pid, String name) { + this.pid = pid; + this.name = name; + } + + /** + * @see org.eclipse.cdt.core.IProcessInfo#getName() + */ + public String getName() { + return name; + } + + /** + * @see org.eclipse.cdt.core.IProcessInfo#getPid() + */ + public int getPid() { + return pid; + } + +} diff --git a/core/org.eclipse.cdt.core.macosx/src/org/eclipse/cdt/internal/core/macosx/ProcessList.java b/core/org.eclipse.cdt.core.macosx/src/org/eclipse/cdt/internal/core/macosx/ProcessList.java new file mode 100644 index 00000000000..65b6237d723 --- /dev/null +++ b/core/org.eclipse.cdt.core.macosx/src/org/eclipse/cdt/internal/core/macosx/ProcessList.java @@ -0,0 +1,68 @@ +package org.eclipse.cdt.internal.core.macosx; + +import java.io.BufferedReader; +import java.io.InputStreamReader; +import java.util.ArrayList; + +import org.eclipse.cdt.core.IProcessInfo; +import org.eclipse.cdt.core.IProcessList; +import org.eclipse.cdt.utils.spawner.ProcessFactory; + +/** + * Insert the type's description here. + * @see IProcessList + */ +public class ProcessList implements IProcessList { + + ProcessInfo[] empty = new ProcessInfo[0]; + + public ProcessList() { + } + + /** + * Insert the method's description here. + * @see IProcessList#getProcessList + */ + public IProcessInfo [] getProcessList() { + Process ps; + BufferedReader psOutput; + String[] args = {"/bin/ps", "-a", "-o", "pid,command"}; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ + + try { + ps = ProcessFactory.getFactory().exec(args); + psOutput = new BufferedReader(new InputStreamReader(ps.getInputStream())); + } catch(Exception e) { + return new IProcessInfo[0]; + } + + //Read the output and parse it into an array list + ArrayList procInfo = new ArrayList(); + + try { + String lastline; + while ((lastline = psOutput.readLine()) != null) { + //The format of the output should be + //PID space name + + lastline = lastline.trim(); + int index = lastline.indexOf(' '); + if (index != -1) { + String pidString = lastline.substring(0, index).trim(); + try { + int pid = Integer.parseInt(pidString); + String arg = lastline.substring(index + 1); + procInfo.add(new ProcessInfo(pid, arg)); + } catch (NumberFormatException e) { + } + } + } + + } catch(Exception e) { + /* Ignore */ + } + + ps.destroy(); + return (IProcessInfo [])procInfo.toArray(new IProcessInfo[procInfo.size()]); + } + +} diff --git a/core/org.eclipse.cdt.core/plugin.properties b/core/org.eclipse.cdt.core/plugin.properties index 348b612ccdc..de645980556 100644 --- a/core/org.eclipse.cdt.core/plugin.properties +++ b/core/org.eclipse.cdt.core/plugin.properties @@ -30,6 +30,7 @@ GNUElfParser.name=GNU Elf Parser PEWindowsParser.name=PE Windows Parser CygwinPEParser.name=Cygwin PE Parser XCOFF32Parser.name=AIX XCOFF32 Parser +MachOParser.name=Mach-O Parser CDTGNUCErrorParser.name=CDT GNU C/C++ Error Parser CDTGNUAssemblerErrorParser.name=CDT GNU Assembler Error Parser @@ -50,3 +51,4 @@ fragmentName.linux = C/C++ Development Tools Core for Linux fragmentName.qnx = C/C++ Development Tools Core for QNX fragmentName.solaris = C/C++ Development Tools Core for Solaris fragmentName.win32 = C/C++ Development Tools Core for Windows +fragmentName.macosx = C/C++ Development Tools Core for MacOS X diff --git a/core/org.eclipse.cdt.core/plugin.xml b/core/org.eclipse.cdt.core/plugin.xml index 6230a2bc10c..a64d15b2ebd 100644 --- a/core/org.eclipse.cdt.core/plugin.xml +++ b/core/org.eclipse.cdt.core/plugin.xml @@ -123,6 +123,20 @@ + + + + + + + + @@ -371,6 +385,10 @@ enabled="true" pattern="*.exe"> + + diff --git a/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/macho/AR.java b/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/macho/AR.java new file mode 100644 index 00000000000..cd36b08d449 --- /dev/null +++ b/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/macho/AR.java @@ -0,0 +1,336 @@ +package org.eclipse.cdt.utils.macho; + +/* + * (c) Copyright QNX Software Systems Ltd. 2002. + * All Rights Reserved. + */ + +import java.io.File; +import java.io.IOException; +import java.io.RandomAccessFile; +import java.util.Vector; + +import org.eclipse.cdt.core.CCorePlugin; + +/** + * The AR class is used for parsing standard archive (ar) files. + * + * Each object within the archive is represented by an ARHeader class. Each of + * of these objects can then be turned into an Elf object for performing Elf + * class operations. + * @see ARHeader + */ +public class AR { + + protected String filename; + protected ERandomAccessFile efile; + protected long strtbl_pos = -1; + private ARHeader[] headers; + + public void dispose() { + try { + if (efile != null) { + efile.close(); + efile = null; + } + } catch (IOException e) { + } + } + + protected void finalize() throws Throwable { + try { + dispose(); + } finally { + super.finalize(); + } + } + + /** + * The ARHeader class is used to store the per-object file + * archive headers. It can also create an Mach-O object for inspecting + * the object file data. + */ + public class ARHeader { + + private String object_name; + private String modification_time; + private String uid; + private String gid; + private String mode; + private long size; + private long file_offset; + private long macho_offset; + + /** + * Remove the padding from the archive header strings. + */ + private String removeBlanks(String str) { + while (str.charAt(str.length() - 1) == ' ') + str = str.substring(0, str.length() - 1); + return str; + } + + /** + * Look up the name stored in the archive's string table based + * on the offset given. + * + * Maintains efile file location. + * + * @param offset + * Offset into the string table for first character of the name. + * @throws IOException + * offset not in string table bounds. + */ + private String nameFromStringTable(long offset) throws IOException { + StringBuffer name = new StringBuffer(0); + long pos = efile.getFilePointer(); + + try { + if (strtbl_pos != -1) { + byte temp; + efile.seek(strtbl_pos + offset); + while ((temp = efile.readByte()) != '\n') + name.append((char) temp); + } + } finally { + efile.seek(pos); + } + + return name.toString(); + } + + /** + * Creates a new archive header object. + * + * Assumes that efile is already at the correct location in the file. + * + * @throws IOException + * There was an error processing the header data from the file. + */ + public ARHeader() throws IOException { + byte[] object_name = new byte[16]; + byte[] modification_time = new byte[12]; + byte[] uid = new byte[6]; + byte[] gid = new byte[6]; + byte[] mode = new byte[8]; + byte[] size = new byte[10]; + byte[] trailer = new byte[2]; + + // + // Read in the archive header data. Fixed sizes. + // + efile.read(object_name); + efile.read(modification_time); + efile.read(uid); + efile.read(gid); + efile.read(mode); + efile.read(size); + efile.read(trailer); + + // + // Save this location so we can create the Mach-O object later. + // + macho_offset = efile.getFilePointer(); + + // + // Convert the raw bytes into strings and numbers. + // + this.object_name = removeBlanks(new String(object_name)); + this.modification_time = new String(modification_time); + this.uid = new String(uid); + this.gid = new String(gid); + this.mode = new String(mode); + this.size = Long.parseLong(removeBlanks(new String(size))); + + // + // If the name is of the format "#1/", real name directly follows the + // header. + // + if (this.object_name.length() > 3 + && this.object_name.charAt(0) == '#' + && this.object_name.charAt(1) == '1' + && this.object_name.charAt(2) == '/') { + try { + int len = Integer.parseInt(this.object_name.substring(3)); + byte[] real_name = new byte[len]; + efile.read(real_name); + this.object_name = new String(real_name); + long pos = efile.getFilePointer(); + efile.seek(macho_offset); + macho_offset = pos; + } catch (java.lang.Exception e) { + } + } + + // + // Strip the trailing / from the object name. + // + int len = this.object_name.length(); + if (len > 2 && this.object_name.charAt(len - 1) == '/') { + this.object_name = this.object_name.substring(0, len - 1); + } + + } + + /** Get the name of the object file */ + public String getObjectName() { + return object_name; + } + + /** Get the size of the object file . */ + public long getSize() { + return size; + } + + public String getArchiveName() { + return filename; + } + + /** + * Create an new MachO object for the object file. + * + * @throws IOException + * Not a valid MachO object file. + * @return A new MachO object. + * @see MachO#MachO( String, long ) + */ + public MachO getMachO() throws IOException { + return new MachO(filename, macho_offset); + } + + public MachO getMachO(boolean filter_on) throws IOException { + return new MachO(filename, macho_offset, filter_on); + } + + public byte[] getObjectData() throws IOException { + byte[] temp = new byte[(int) size]; + if (efile != null) { + efile.seek(macho_offset); + efile.read(temp); + } else { + efile = new ERandomAccessFile(filename, "r"); //$NON-NLS-1$ + efile.seek(macho_offset); + efile.read(temp); + efile.close(); + efile = null; + } + return temp; + } + } + + public static boolean isARHeader(byte[] ident) { + if (ident.length < 7 + || ident[0] != '!' + || ident[1] != '<' + || ident[2] != 'a' + || ident[3] != 'r' + || ident[4] != 'c' + || ident[5] != 'h' + || ident[6] != '>') + return false; + return true; + } + + /** + * Creates a new AR object from the contents of + * the given file. + * + * @param filename The file to process. + * @throws IOException The file is not a valid archive. + */ + public AR(String filename) throws IOException { + this.filename = filename; + efile = new ERandomAccessFile(filename, "r"); //$NON-NLS-1$ + String hdr = efile.readLine(); + if (hdr == null || hdr.compareTo("!") != 0) { //$NON-NLS-1$ + efile.close(); + throw new IOException(CCorePlugin.getResourceString("Util.exception.invalidArchive")); //$NON-NLS-1$ + } + } + + /** Load the headers from the file (if required). */ + private void loadHeaders() throws IOException { + if (headers != null) + return; + + Vector v = new Vector(); + try { + // + // Check for EOF condition + // + while (efile.getFilePointer() < efile.length()) { + ARHeader header = new ARHeader(); + String name = header.getObjectName(); + + long pos = efile.getFilePointer(); + + v.add(header); + + // + // Compute the location of the next header in the archive. + // + pos += header.getSize(); + if ((pos % 2) != 0) + pos++; + + efile.seek(pos); + } + } catch (IOException e) { + } + // strtbl_pos = ???; + headers = (ARHeader[]) v.toArray(new ARHeader[0]); + } + + /** + * Get an array of all the object file headers for this archive. + * + * @throws IOException + * Unable to process the archive file. + * @return An array of headers, one for each object within the archive. + * @see ARHeader + */ + public ARHeader[] getHeaders() throws IOException { + loadHeaders(); + return headers; + } + + private boolean stringInStrings(String str, String[] set) { + for (int i = 0; i < set.length; i++) + if (str.compareTo(set[i]) == 0) + return true; + return false; + } + + public String[] extractFiles(String outdir, String[] names) throws IOException { + Vector names_used = new Vector(); + String object_name; + int count; + + loadHeaders(); + + count = 0; + for (int i = 0; i < headers.length; i++) { + object_name = headers[i].getObjectName(); + if (names != null && !stringInStrings(object_name, names)) + continue; + + object_name = "" + count + "_" + object_name; //$NON-NLS-1$ //$NON-NLS-2$ + count++; + + byte[] data = headers[i].getObjectData(); + File output = new File(outdir, object_name); + names_used.add(object_name); + + RandomAccessFile rfile = new RandomAccessFile(output, "rw"); //$NON-NLS-1$ + rfile.write(data); + rfile.close(); + } + + return (String[]) names_used.toArray(new String[0]); + } + + public String[] extractFiles(String outdir) throws IOException { + return extractFiles(outdir, null); + } + +} diff --git a/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/macho/ERandomAccessFile.java b/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/macho/ERandomAccessFile.java new file mode 100644 index 00000000000..7d6eee5bc2f --- /dev/null +++ b/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/macho/ERandomAccessFile.java @@ -0,0 +1,80 @@ +package org.eclipse.cdt.utils.macho; + +/* + * (c) Copyright QNX Software Systems Ltd. 2002. + * All Rights Reserved. + */ + +import java.io.EOFException; +import java.io.File; +import java.io.IOException; +import java.io.RandomAccessFile; + +public class ERandomAccessFile extends RandomAccessFile { + private boolean isle; + private long ptr_offset; + int val[] = new int[4]; + + public ERandomAccessFile(String file, String mode) throws IOException { + super(file, mode); + } + + public ERandomAccessFile(File file, String mode) throws IOException { + super(file, mode); + } + + public void setEndian(boolean le) + { + isle = le; + } + + public final short readShortE() throws IOException { + val[0] = read(); + val[1] = read(); + if ((val[0] | val[1]) < 0) + throw new EOFException(); + if ( isle ) { + return (short)((val[1] << 8) + val[0]); + } else { + return (short)((val[0] << 8) + val[1]); + } + } + + public final int readIntE() throws IOException + { + val[0] = read(); + val[1] = read(); + val[2] = read(); + val[3] = read(); + if ((val[0] | val[1] | val[2] | val[3]) < 0) + throw new EOFException(); + if ( isle ) { + return ((val[3] << 24) + (val[2] << 16) + (val[1] << 8) + val[0]); + } else { + return ((val[0] << 24) + (val[1] << 16) + (val[2] << 8) + val[3]); + } + } + + public final long readLongE() throws IOException + { + return (long)readIntE(); + } + + public void setFileOffset( long offset ) throws IOException { + ptr_offset = offset; + super.seek( offset ); + } + + public long getFilePointer() throws IOException { + long ptr = super.getFilePointer(); + ptr = ptr - ptr_offset; + return ptr; + } + + public void seek( long pos ) throws IOException { + long real_pos = pos + ptr_offset; + super.seek( real_pos ); + } +} + + diff --git a/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/macho/MachO.java b/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/macho/MachO.java new file mode 100644 index 00000000000..ab1b869f654 --- /dev/null +++ b/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/macho/MachO.java @@ -0,0 +1,1561 @@ +package org.eclipse.cdt.utils.macho; + +/* + * (c) Copyright QNX Software Systems Ltd. 2002. + * All Rights Reserved. + */ + +import java.io.IOException; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Vector; +import java.util.Comparator; + +import org.eclipse.cdt.core.CCorePlugin; +import org.eclipse.cdt.utils.CPPFilt; + +// test checkin +public class MachO { + protected ERandomAccessFile efile; + + protected MachOhdr mhdr; + protected LoadCommand[] loadcommands; + protected boolean cppFiltEnabled = true; + protected CPPFilt cppFilt; + protected String file; + protected boolean debugsym = false; /* contains debugging symbols */ + + private Symbol[] symbols; /* symbols from SymtabCommand */ + private Symbol[] local_symbols; /* local symbols from DySymtabCommand */ + private boolean dynsym = false; /* set if DynSymtabCommand is present */ + private Line[] lines; /* line table */ + private Section[] sections; /* sections from SegmentCommand */ + private SymtabCommand symtab; /* SymtabCommand that contains the symbol table */ + + protected String EMPTY_STRING = ""; //$NON-NLS-1$ + + + public class MachOhdr { + + /* values of magic */ + public final static int MH_MAGIC = 0xfeedface; /* the mach magic number */ + public final static int MH_CIGAM = 0xcefaedfe; + + /* values of cputype */ + public final static int CPU_TYPE_ANY = -1; + public final static int CPU_TYPE_VAX = 1; + public final static int CPU_TYPE_MC680x0 = 6; + public final static int CPU_TYPE_I386 = 7; + public final static int CPU_TYPE_MC98000 = 10; + public final static int CPU_TYPE_HPPA = 11; + public final static int CPU_TYPE_MC88000 = 13; + public final static int CPU_TYPE_SPARC = 14; + public final static int CPU_TYPE_I860 = 15; + public final static int CPU_TYPE_POWERPC = 18; + + /* values of cpusubtype */ + public final static int CPU_SUBTYPE_MULTIPLE = -1; + public final static int CPU_SUBTYPE_LITTLE_ENDIAN = 0; + public final static int CPU_SUBTYPE_BIG_ENDIAN = 1; + public final static int CPU_SUBTYPE_VAX_ALL = 0; + public final static int CPU_SUBTYPE_VAX780 = 1; + public final static int CPU_SUBTYPE_VAX785 = 2; + public final static int CPU_SUBTYPE_VAX750 = 3; + public final static int CPU_SUBTYPE_VAX730 = 4; + public final static int CPU_SUBTYPE_UVAXI = 5; + public final static int CPU_SUBTYPE_UVAXII = 6; + public final static int CPU_SUBTYPE_VAX8200 = 7; + public final static int CPU_SUBTYPE_VAX8500 = 8; + public final static int CPU_SUBTYPE_VAX8600 = 9; + public final static int CPU_SUBTYPE_VAX8650 = 10; + public final static int CPU_SUBTYPE_VAX8800 = 11; + public final static int CPU_SUBTYPE_UVAXIII = 12; + public final static int CPU_SUBTYPE_MC680x0_ALL = 1; + public final static int CPU_SUBTYPE_MC68030 = 1; + public final static int CPU_SUBTYPE_MC68040 = 2; + public final static int CPU_SUBTYPE_MC68030_ONLY = 3; + public final static int CPU_SUBTYPE_I386_ALL = 3; + public final static int CPU_SUBTYPE_386 = 3; + public final static int CPU_SUBTYPE_486 = 4; + public final static int CPU_SUBTYPE_486SX = 132; + public final static int CPU_SUBTYPE_586 = 5; + public final static int CPU_SUBTYPE_PENT = 5; + public final static int CPU_SUBTYPE_PENTPRO = 32; + public final static int CPU_SUBTYPE_PENTII_M3 = 54; + public final static int CPU_SUBTYPE_PENTII_M5 = 86; + public final static int CPU_SUBTYPE_MIPS_ALL = 0; + public final static int CPU_SUBTYPE_MIPS_R2300 = 1; + public final static int CPU_SUBTYPE_MIPS_R2600 = 2; + public final static int CPU_SUBTYPE_MIPS_R2800 = 3; + public final static int CPU_SUBTYPE_MIPS_R2000a = 4; + public final static int CPU_SUBTYPE_MIPS_R2000 = 5; + public final static int CPU_SUBTYPE_MIPS_R3000a = 6; + public final static int CPU_SUBTYPE_MIPS_R3000 = 7; + public final static int CPU_SUBTYPE_MC98000_ALL = 0; + public final static int CPU_SUBTYPE_MC98601 = 1; + public final static int CPU_SUBTYPE_HPPA_ALL = 0; + public final static int CPU_SUBTYPE_HPPA_7100 = 0; + public final static int CPU_SUBTYPE_HPPA_7100LC = 1; + public final static int CPU_SUBTYPE_MC88000_ALL = 0; + public final static int CPU_SUBTYPE_MC88100 = 1; + public final static int CPU_SUBTYPE_MC88110 = 2; + public final static int CPU_SUBTYPE_SPARC_ALL = 0; + public final static int CPU_SUBTYPE_I860_ALL = 0; + public final static int CPU_SUBTYPE_I860_860 = 1; + public final static int CPU_SUBTYPE_POWERPC_ALL = 0; + public final static int CPU_SUBTYPE_POWERPC_601 = 1; + public final static int CPU_SUBTYPE_POWERPC_602 = 2; + public final static int CPU_SUBTYPE_POWERPC_603 = 3; + public final static int CPU_SUBTYPE_POWERPC_603e = 4; + public final static int CPU_SUBTYPE_POWERPC_603ev = 5; + public final static int CPU_SUBTYPE_POWERPC_604 = 6; + public final static int CPU_SUBTYPE_POWERPC_604e = 7; + public final static int CPU_SUBTYPE_POWERPC_620 = 8; + public final static int CPU_SUBTYPE_POWERPC_750 = 9; + public final static int CPU_SUBTYPE_POWERPC_7400 = 10; + public final static int CPU_SUBTYPE_POWERPC_7450 = 11; + public final static int CPU_SUBTYPE_POWERPC_970 = 100; + + /* values of filetype */ + public final static int MH_OBJECT = 0x1; /* relocatable object file */ + public final static int MH_EXECUTE = 0x2; /* demand paged executable file */ + public final static int MH_FVMLIB = 0x3; /* fixed VM shared library file */ + public final static int MH_CORE = 0x4; /* core file */ + public final static int MH_PRELOAD = 0x5; /* preloaded executable file */ + public final static int MH_DYLIB = 0x6; /* dynamically bound shared library */ + public final static int MH_DYLINKER = 0x7; /* dynamic link editor */ + public final static int MH_BUNDLE = 0x8; /* dynamically bound bundle file */ + public final static int MH_DYLIB_STUB = 0x9; /* shared library stub for static linking only, no section contents */ + + /* values of flags */ + public final static int MH_NOUNDEFS = 0x1; /* the object file has no undefined references */ + public final static int MH_INCRLINK = 0x2; /* the object file is the output of an incremental link against a base file and can't be link edited again */ + public final static int MH_DYLDLINK = 0x4; /* the object file is input for the dynamic linker and can't be staticly link edited again */ + public final static int MH_BINDATLOAD = 0x8; /* the object file's undefined references are bound by the dynamic linker when loaded. */ + public final static int MH_PREBOUND = 0x10; /* the file has its dynamic undefined references prebound. */ + public final static int MH_SPLIT_SEGS = 0x20; /* the file has its read-only and read-write segments split */ + public final static int MH_LAZY_INIT = 0x40; /* the shared library init routine is to be run lazily via catching memory faults to its writeable segments (obsolete) */ + public final static int MH_TWOLEVEL = 0x80; /* the image is using two-level name space bindings */ + public final static int MH_FORCE_FLAT = 0x100; /* the executable is forcing all images to use flat name space bindings */ + public final static int MH_NOMULTIDEFS = 0x200; /* this umbrella guarantees no multiple defintions of symbols in its sub-images so the two-level namespace hints can always be used. */ + public final static int MH_NOFIXPREBINDING = 0x400; /* do not have dyld notify the prebinding agent about this executable */ + + public int magic; /* mach magic number identifier */ + public int cputype; /* cpu specifier */ + public int cpusubtype; /* machine specifier */ + public int filetype; /* type of file */ + public int ncmds; /* number of load commands */ + public int sizeofcmds; /* the size of all the load commands */ + public int flags; /* flags */ + + protected MachOhdr() throws IOException { + efile.seek(0); + efile.setEndian(false); + magic = efile.readIntE(); + if ( magic == MH_CIGAM ) + efile.setEndian(true); + else if ( magic != MH_MAGIC ) + throw new IOException(CCorePlugin.getResourceString("Util.exception.notMACHO")); //$NON-NLS-1$ + cputype = efile.readIntE(); + cpusubtype = efile.readIntE(); + filetype = efile.readIntE(); + ncmds = efile.readIntE(); + sizeofcmds = efile.readIntE(); + flags = efile.readIntE(); + } + + protected MachOhdr(byte [] bytes) throws IOException { + boolean isle = false; + int offset = 0; + magic = makeInt(bytes, offset, isle); offset += 4; + if ( magic == MH_CIGAM ) + isle = true; + else if ( magic != MH_MAGIC ) + throw new IOException(CCorePlugin.getResourceString("Util.exception.notMACHO")); //$NON-NLS-1$ + cputype = makeInt(bytes, offset, isle); offset += 4; + cpusubtype = makeInt(bytes, offset, isle); offset += 4; + filetype = makeInt(bytes, offset, isle); offset += 4; + ncmds = makeInt(bytes, offset, isle); offset += 4; + sizeofcmds = makeInt(bytes, offset, isle); offset += 4; + flags = makeInt(bytes, offset, isle); offset += 4; + } + + private final short makeShort(byte [] val, int offset, boolean isle) throws IOException { + if (val.length < offset + 2) + throw new IOException(); + if ( isle ) { + return (short)(((val[offset + 1] & 0xff) << 8) + (val[offset + 0] & 0xff)); + } else { + return (short)(((val[offset + 0] & 0xff) << 8) + (val[offset + 1] & 0xff)); + } + } + + private final int makeInt(byte [] val, int offset, boolean isle) throws IOException + { + if (val.length < offset + 4) + throw new IOException(); + if ( isle ) { + return (((val[offset + 3] & 0xff) << 24) | + ((val[offset + 2] & 0xff) << 16) | + ((val[offset + 1] & 0xff) << 8) | + (val[offset + 0] & 0xff)); + } else { + return (int)(((val[offset + 0] & 0xff) << 24) | + ((val[offset + 1] & 0xff) << 16) | + ((val[offset + 2] & 0xff) << 8) | + (val[offset + 3] & 0xff)); + } + } + + } + + public class LoadCommand { + public final static int LC_REQ_DYLD = 0x80000000; + + /* values of cmd */ + public final static int LC_SEGMENT = 0x1; /* segment of this file to be mapped */ + public final static int LC_SYMTAB = 0x2; /* link-edit stab symbol table info */ + public final static int LC_SYMSEG = 0x3; /* link-edit gdb symbol table info (obsolete) */ + public final static int LC_THREAD = 0x4; /* thread */ + public final static int LC_UNIXTHREAD = 0x5; /* unix thread (includes a stack) */ + public final static int LC_LOADFVMLIB = 0x6; /* load a specified fixed VM shared library */ + public final static int LC_IDFVMLIB = 0x7; /* fixed VM shared library identification */ + public final static int LC_IDENT = 0x8; /* object identification info (obsolete) */ + public final static int LC_FVMFILE = 0x9; /* fixed VM file inclusion (internal use) */ + public final static int LC_PREPAGE = 0xa; /* prepage command (internal use) */ + public final static int LC_DYSYMTAB = 0xb; /* dynamic link-edit symbol table info */ + public final static int LC_LOAD_DYLIB = 0xc; /* load a dynamically linked shared library */ + public final static int LC_ID_DYLIB = 0xd; /* dynamically linked shared lib ident */ + public final static int LC_LOAD_DYLINKER = 0xe; /* load a dynamic linker */ + public final static int LC_ID_DYLINKER = 0xf; /* dynamic linker identification */ + public final static int LC_PREBOUND_DYLIB = 0x10; /* modules prebound for a dynamically linked shared library */ + public final static int LC_ROUTINES = 0x11; /* image routines */ + public final static int LC_SUB_FRAMEWORK = 0x12; /* sub framework */ + public final static int LC_SUB_UMBRELLA = 0x13; /* sub umbrella */ + public final static int LC_SUB_CLIENT = 0x14; /* sub client */ + public final static int LC_SUB_LIBRARY = 0x15; /* sub library */ + public final static int LC_TWOLEVEL_HINTS = 0x16; /* two-level namespace lookup hints */ + public final static int LC_PREBIND_CKSUM = 0x17; /* prebind checksum */ + /* + * load a dynamically linked shared library that is allowed to be missing + * (all symbols are weak imported). + */ + public final static int LC_LOAD_WEAK_DYLIB = (0x18 | LC_REQ_DYLD); + + public int cmd; + public int cmdsize; + } + + public class LCStr { + public long offset; + public long ptr; + } + + public class SegmentCommand extends LoadCommand { + /* values of flags */ + public final static long SG_HIGHVM = 0x1; + public final static long SG_FVMLIB = 0x2; + public final static long SG_NORELOC = 0x4; + + /* VM protection values */ + public final static int VM_PROT_NONE = 0x00; + public final static int VM_PROT_READ = 0x01; /* read permission */ + public final static int VM_PROT_WRITE = 0x02; /* write permission */ + public final static int VM_PROT_EXECUTE = 0x04; /* execute permission */ + public final static int VM_PROT_DEFAULT = (VM_PROT_READ|VM_PROT_WRITE); + public final static int VM_PROT_ALL = (VM_PROT_READ|VM_PROT_WRITE|VM_PROT_EXECUTE); + public final static int VM_PROT_NO_CHANGE = 0x08; + public final static int VM_PROT_COPY = 0x10; + public final static int VM_PROT_WANTS_COPY = 0x10; + + public String segname; /* segment name */ + public int vmaddr; /* memory address of this segment */ + public int vmsize; /* memory size of this segment */ + public int fileoff; /* file offset of this segment */ + public int filesize; /* amount to map from the file */ + public int maxprot; /* maximum VM protection */ + public int initprot; /* initial VM protection */ + public int nsects; /* number of sections in segment */ + public int flags; /* flags */ + + public boolean prot(int val) { + return (initprot & val) == val; + } + } + + public class Section { + + public final static int SECTION_TYP = 0x000000ff; /* 256 section types */ + public final static int SECTION_ATTRIBUTES = 0xffffff00; /* 24 section attributes */ + public final static int SECTION_ATTRIBUTES_USR =0xff000000; /* User setable attributes */ + + /* values of flags */ + public final static int S_REGULAR = 0x0; /* regular section */ + public final static int S_ZEROFILL = 0x1; /* zero fill on demand section */ + public final static int S_CSTRING_LITERALS = 0x2; /* section with only literal C strings*/ + public final static int S_4BYTE_LITERALS = 0x3; /* section with only 4 byte literals */ + public final static int S_8BYTE_LITERALS = 0x4; /* section with only 8 byte literals */ + public final static int S_LITERAL_POINTERS = 0x5; /* section with only pointers to literals */ + public final static int S_NON_LAZY_SYMBOL_POINTERS = 0x6; /* section with only non-lazy symbol pointers */ + public final static int S_LAZY_SYMBOL_POINTERS = 0x7; /* section with only lazy symbol pointers */ + public final static int S_SYMBOL_STUBS = 0x8; /* section with only symbol stubs, byte size of stub in the reserved2 field */ + public final static int S_MOD_INIT_FUNC_POINTERS = 0x9; /* section with only function pointers for initialization*/ + public final static int S_MOD_TERM_FUNC_POINTERS = 0xa; /* section with only function pointers for termination */ + public final static int S_COALESCED = 0xb; /* section contains symbols that are to be coalesced */ + public final static int S_ATTR_PURE_INSTRUCTIONS = 0x80000000; /* section contains only true machine instructions */ + public final static int S_ATTR_NO_TOC = 0x40000000; /* section contains coalesced symbols that are not to be in a ranlib table of contents */ + public final static int S_ATTR_STRIP_STATIC_SYMS = 0x20000000; /* ok to strip static symbols in this section in files with the MH_DYLDLINK flag */ + public final static int SECTION_ATTRIBUTES_SYS = 0x00ffff00; /* system setable attributes */ + public final static int S_ATTR_SOME_INSTRUCTIONS = 0x00000400; /* section contains some machine instructions */ + public final static int S_ATTR_EXT_RELOC = 0x00000200; /* section has external relocation entries */ + public final static int S_ATTR_LOC_RELOC = 0x00000100; /* section has local relocation entries */ + + public String sectname; /* name of this section */ + public String segname; /* name segment this section goes in */ + public SegmentCommand segment; /* segment this section goes in */ + public int addr; /* memory address of this section */ + public int size; /* size in bytes of this section */ + public int offset; /* file offset of this section */ + public int align; /* section alignment (power of 2) */ + public int reloff; /* file offset of relocation entries */ + public int nreloc; /* number of relocation entries */ + public int flags; /* flags (section type and attributes)*/ + public int reserved1; /* reserved */ + public int reserved2; /* reserved */ + + public int flags(int mask) { + return flags & mask; + } + } + + public class FVMLib { + public int name; /* library's target pathname */ + public int minor_version; /* library's minor version number */ + public int header_addr; /* library's header address */ + public String lc_str_name = null; + + public String toString() { + if ( lc_str_name == null ) { + return EMPTY_STRING; + } + return lc_str_name; + } + } + + public class FVMLibCommand extends LoadCommand { + public FVMLib fvmlib; /* the library identification */ + } + + public class DyLib { + public int name; /* library's path name */ + public int timestamp; /* library's build time stamp */ + public int current_version; /* library's current version number */ + public int compatibility_version; /* library's compatibility vers number*/ + public String lc_str_name = null; + + public String toString() { + if ( lc_str_name == null ) { + return EMPTY_STRING; + } + return lc_str_name; + } + } + + public class DyLibCommand extends LoadCommand { + public DyLib dylib; /* the library identification */ + } + + public class SubFrameworkCommand extends LoadCommand { + public int umbrella; /* the umbrella framework name */ + public String lc_str_name = null; + + public String toString() { + if ( lc_str_name == null ) { + return EMPTY_STRING; + } + return lc_str_name; + } + } + + public class SubClientCommand extends LoadCommand { + public int client; /* the client name */ + public String lc_str_name = null; + + public String toString() { + if ( lc_str_name == null ) { + return EMPTY_STRING; + } + return lc_str_name; + } + } + + public class SubUmbrellaCommand extends LoadCommand { + public int sub_umbrella; /* the sub_umbrella framework name */ + public String lc_str_name = null; + + public String toString() { + if ( lc_str_name == null ) { + return EMPTY_STRING; + } + return lc_str_name; + } + } + + public class SubLibraryCommand extends LoadCommand { + public int sub_library; /* the sub_library name */ + public String lc_str_name = null; + + public String toString() { + if ( lc_str_name == null ) { + return EMPTY_STRING; + } + return lc_str_name; + } + } + + public class PreboundDyLibCommand extends LoadCommand { + public int name; /* library's path name */ + public int nmodules; /* number of modules in library */ + public int linked_modules; /* bit vector of linked modules */ + public String lc_str_name = null; + + public String toString() { + if ( lc_str_name == null ) { + return EMPTY_STRING; + } + return lc_str_name; + } + } + + public class DyLinkerCommand extends LoadCommand { + public int name; /* dynamic linker's path name */ + public String lc_str_name = null; + + public String toString() { + if ( lc_str_name == null ) { + return EMPTY_STRING; + } + return lc_str_name; + } + } + + public class ThreadCommand extends LoadCommand { + } + + public class RoutinesCommand extends LoadCommand { + public int init_address; /* address of initialization routine */ + public int init_module; /* index into the module table that the init routine is defined in */ + public int reserved1; + public int reserved2; + public int reserved3; + public int reserved4; + public int reserved5; + public int reserved6; + } + + public class SymtabCommand extends LoadCommand { + public int symoff; /* symbol table offset */ + public int nsyms; /* number of symbol table entries */ + public int stroff; /* string table offset */ + public int strsize; /* string table size in bytes */ + } + + public class DySymtabCommand extends LoadCommand { + public int ilocalsym; /* index to local symbols */ + public int nlocalsym; /* number of local symbols */ + public int iextdefsym; /* index to externally defined symbols */ + public int nextdefsym; /* number of externally defined symbols */ + public int iundefsym; /* index to undefined symbols */ + public int nundefsym; /* number of undefined symbols */ + public int tocoff; /* file offset to table of contents */ + public int ntoc; /* number of entries in table of contents */ + public int modtaboff; /* file offset to module table */ + public int nmodtab; /* number of module table entries */ + public int extrefsymoff; /* offset to referenced symbol table */ + public int nextrefsyms; /* number of referenced symbol table entries */ + public int indirectsymoff; /* file offset to the indirect symbol table */ + public int nindirectsyms; /* number of indirect symbol table entries */ + public int extreloff; /* offset to external relocation entries */ + public int nextrel; /* number of external relocation entries */ + public int locreloff; /* offset to local relocation entries */ + public int nlocrel; /* number of local relocation entries */ + } + + public class DyLibTableOfContents { + public final static int INDIRECT_SYMBOL_LOCAL = 0x80000000; + public final static int INDIRECT_SYMBOL_ABS = 0x40000000; + public int symbol_index; /* the defined external symbol (index into the symbol table) */ + public int module_index; /* index into the module table this symbol is defined in */ + } + + public class DyLibModule { + public int module_name; /* the module name (index into string table) */ + public int iextdefsym; /* index into externally defined symbols */ + public int nextdefsym; /* number of externally defined symbols */ + public int irefsym; /* index into reference symbol table */ + public int nrefsym; /* number of reference symbol table entries */ + public int ilocalsym; /* index into symbols for local symbols */ + public int nlocalsym; /* number of local symbols */ + public int iextrel; /* index into external relocation entries */ + public int nextrel; /* number of external relocation entries */ + public int iinit_iterm; /* low 16 bits are the index into the init section, high 16 bits are the index into the term section */ + public int ninit_nterm; /* low 16 bits are the number of init section entries, high 16 bits are the number of term section entries */ + public int objc_module_info_addr; /* for this module address of the start of the (__OBJC,__module_info) section */ + public int objc_module_info_size; /* for this module size of the (__OBJC,__module_info) section */ + } + + public class DyLibReference { + public int isym; /* index into the symbol table */ + public int flags; /* flags to indicate the type of reference */ + } + + public class TwoLevelHintsCommand extends LoadCommand { + public int offset; /* offset to the hint table */ + public int nhints; /* number of hints in the hint table */ + public TwoLevelHint[] hints; + } + + public class TwoLevelHint { + public int isub_image; /* index into the sub images */ + public int itoc; /* index into the table of contents */ + } + + public class PrebindCksumCommand extends LoadCommand { + public int cksum; /* the check sum or zero */ + } + + public class SymSegCommand extends LoadCommand { + public int offset; /* symbol segment offset */ + public int size; /* symbol segment size in bytes */ + } + + public class IdentCommand extends LoadCommand { + } + + public class FVMFileCommand extends LoadCommand { + public int name; /* files pathname */ + public int header_addr; /* files virtual address */ + public String lc_str_name = null; + + public String toString() { + if ( lc_str_name == null ) { + return EMPTY_STRING; + } + return lc_str_name; + } + } + + private void commonSetup( String file, long offset, boolean filton ) + throws IOException + { + this.cppFiltEnabled = filton; + + try { + efile = new ERandomAccessFile(file, "r"); //$NON-NLS-1$ + efile.setFileOffset( offset ); + mhdr = new MachOhdr(); + this.file = file; + } finally { + if ( mhdr == null ) { + dispose(); + } + } + } + + protected String string_from_macho_symtab(MachO.SymtabCommand symtab, int index) throws IOException { + StringBuffer str = new StringBuffer(); + byte tmp; + if ( index > symtab.strsize ) { + return EMPTY_STRING; + } + efile.seek(symtab.stroff + index); + while( true ) { + tmp = efile.readByte(); + if ( tmp == 0 ) + break; + str.append((char)tmp); + } + return str.toString(); + } + + public class Symbol implements Comparable { + /* n_type bit masks */ + public final static int N_STAB = 0xe0; + public final static int N_PEXT = 0x10; + public final static int N_EXT = 0x01; + public final static int N_TYPE = 0x0e; /* type mask */ + /* Values of N_TYPE bits */ + public final static int N_UNDF = 0x0; + public final static int N_ABS = 0x2; + public final static int N_SECT = 0xe; + public final static int N_PBUD = 0xc; + public final static int N_INDR = 0xa; + /* Values of n_type if N_STAB bits are set (stabs) */ + public final static int N_GSYM = 0x20; /* global symbol: name,,NO_SECT,type,0 */ + public final static int N_FNAME = 0x22; /* procedure name (f77 kludge): name,,NO_SECT,0,0 */ + public final static int N_FUN = 0x24; /* procedure: name,,n_sect,linenumber,address */ + public final static int N_STSYM = 0x26; /* static symbol: name,,n_sect,type,address */ + public final static int N_LCSYM = 0x28; /* .lcomm symbol: name,,n_sect,type,address */ + public final static int N_BNSYM = 0x2e; /* begin nsect sym: 0,,n_sect,0,address */ + public final static int N_OPT = 0x3c; /* emitted with gcc2_compiled and in gcc source */ + public final static int N_RSYM = 0x40; /* register sym: name,,NO_SECT,type,register */ + public final static int N_SLINE = 0x44; /* src line: 0,,n_sect,linenumber,address */ + public final static int N_ENSYM = 0x4e; /* end nsect sym: 0,,n_sect,0,address */ + public final static int N_SSYM = 0x60; /* structure elt: name,,NO_SECT,type,struct_offset */ + public final static int N_SO = 0x64; /* source file name: name,,n_sect,0,address */ + public final static int N_LSYM = 0x80; /* local sym: name,,NO_SECT,type,offset */ + public final static int N_BINCL = 0x82; /* include file beginning: name,,NO_SECT,0,sum */ + public final static int N_SOL = 0x84; /* #included file name: name,,n_sect,0,address */ + public final static int N_PARAMS = 0x86; /* compiler parameters: name,,NO_SECT,0,0 */ + public final static int N_VERSION = 0x88; /* compiler version: name,,NO_SECT,0,0 */ + public final static int N_OLEVEL = 0x8A; /* compiler -O level: name,,NO_SECT,0,0 */ + public final static int N_PSYM = 0xa0; /* parameter: name,,NO_SECT,type,offset */ + public final static int N_EINCL = 0xa2; /* include file end: name,,NO_SECT,0,0 */ + public final static int N_ENTRY = 0xa4; /* alternate entry: name,,n_sect,linenumber,address */ + public final static int N_LBRAC = 0xc0; /* left bracket: 0,,NO_SECT,nesting level,address */ + public final static int N_EXCL = 0xc2; /* deleted include file: name,,NO_SECT,0,sum */ + public final static int N_RBRAC = 0xe0; /* right bracket: 0,,NO_SECT,nesting level,address */ + public final static int N_BCOMM = 0xe2; /* begin common: name,,NO_SECT,0,0 */ + public final static int N_ECOMM = 0xe4; /* end common: name,,n_sect,0,0 */ + public final static int N_ECOML = 0xe8; /* end common (local name): 0,,n_sect,0,address */ + public final static int N_LENG = 0xfe; /* second stab entry with length information */ + /* Values of n_sect */ + public final static int NO_SECT = 0; + public final static int MAX_SECT = 255; + /* Values of n_desc */ + public final static int REFERENCE_TYPE = 0xf; /* reference type mask */ + public final static int REFERENCE_FLAG_UNDEFINED_NON_LAZY = 0x0; + public final static int REFERENCE_FLAG_UNDEFINED_LAZY = 0x1; + public final static int REFERENCE_FLAG_DEFINED = 0x2; + public final static int REFERENCE_FLAG_PRIVATE_DEFINED = 0x3; + public final static int REFERENCE_FLAG_PRIVATE_UNDEFINED_NON_LAZY = 0x4; + public final static int REFERENCE_FLAG_PRIVATE_UNDEFINED_LAZY = 0x5; + public final static int REFERENCED_DYNAMICALLY = 0x10; + public final static int N_DESC_DISCARDED = 0x20; + public final static int N_WEAK_REF = 0x40; + public final static int N_WEAK_DEF = 0x80; + + public long n_strx; + public long n_value; + public short n_desc; + public byte n_type; + public byte n_sect; + + private String name = null; /* symbol name */ + private Line line = null; /* symbol line information */ + + private String cppFilt(String in) { + if (cppFiltEnabled) { + try { + if (in.indexOf("__") != -1 || in.indexOf("_._") != -1) { //$NON-NLS-1$ //$NON-NLS-2$ + if (cppFilt == null) { + cppFilt = new CPPFilt(); + } + return cppFilt.getFunction(in); + } + } catch (IOException e) { + return in; + } + } + return in; + } + + public Symbol() { + } + + public boolean n_type_mask(int mask) { + return (n_type & mask) != 0; + } + + public boolean n_type(int val) { + return (n_type & N_TYPE) == val; + } + + public boolean n_desc(int val) { + return (n_type & REFERENCE_TYPE) == val; + } + + public int compareTo(Object obj) { + long thisVal = 0; + long anotherVal = 0; + if ( obj instanceof Symbol ) { + Symbol sym = (Symbol)obj; + thisVal = this.n_value; + anotherVal = sym.n_value; + } else if ( obj instanceof Long ) { + Long val = (Long)obj; + anotherVal = val.longValue(); + thisVal = (long)this.n_value; + } + return (thisVal= 0) + lentry = (Line)lineList.get(l); + else + lineList.add(lentry); + + if (sym.n_type == Symbol.N_FUN) { + String func = sym.toString(); + if (func != null) { + int colon = func.indexOf(':'); + if (colon > 0) + lentry.function = func.substring(0, colon); + else + lentry.function = func; + } else { + lentry.function = EMPTY_STRING; + } + } + } + } + lineList.trimToSize(); + lines = (Line[])lineList.toArray(new Line[0]); + Arrays.sort(lines); + + /* now check for file names */ + for (int s = 0; s < symbols.length; s++) { + Symbol sym = symbols[s]; + if (sym.n_type == Symbol.N_SO) { + for (int l = 0; l < lines.length; l++) { + if (sym.n_value <= lines[l].address) { + lines[l].file = sym.toString(); + break; + } + } + } + } + + } + + private Section[] getSections(SegmentCommand seg) throws IOException { + if ( seg.nsects == 0 ) { + return new Section[0]; + } + Section[] sections = new Section[seg.nsects]; + for ( int i = 0; i < seg.nsects; i++ ) { + Section section = new Section(); + byte[] sectname = new byte[16]; + byte[] segname = new byte[16]; + efile.readFully(sectname); + section.sectname = new String(sectname, 0, 16); + efile.readFully(segname); + section.segment = seg; + section.segname = new String(segname, 0, 16); + section.addr = efile.readIntE(); + section.size = efile.readIntE(); + section.offset = efile.readIntE(); + section.align = efile.readIntE(); + section.reloff = efile.readIntE(); + section.nreloc = efile.readIntE(); + section.flags = efile.readIntE(); + section.reserved1 = efile.readIntE(); + section.reserved2 = efile.readIntE(); + sections[i] = section; + } + return sections; + } + + private TwoLevelHint[] getTwoLevelHints(int nhints) throws IOException { + if ( nhints == 0 ) { + return new TwoLevelHint[0]; + } + TwoLevelHint[] tlhints = new TwoLevelHint[nhints]; + for ( int i = 0; i < nhints; i++ ) { + int field = efile.readIntE(); + tlhints[i] = new TwoLevelHint(); + tlhints[i].isub_image = (field & 0xff000000) >> 24; + tlhints[i].itoc = field & 0x00ffffff; + } + return tlhints; + } + + private String getLCStr(int len) throws IOException { + if (len == 0) + return EMPTY_STRING; + StringBuffer str = new StringBuffer(); + for (; len > 0; len--) { + byte tmp = efile.readByte(); + if (tmp == 0) + break; + str.append((char)tmp); + } + return str.toString(); + } + + private void loadLoadCommands() throws IOException { + if ( loadcommands == null ) { + if ( mhdr.ncmds == 0 ) { + loadcommands = new LoadCommand[0]; + return; + } + loadcommands = new LoadCommand[mhdr.ncmds]; + for ( int i = 0; i < mhdr.ncmds; i++ ) { + int cmd = efile.readIntE(); + int len; + switch (cmd) { + case LoadCommand.LC_SEGMENT: + SegmentCommand seg = new SegmentCommand(); + byte[] segname = new byte[16]; + seg.cmd = cmd; + seg.cmdsize = efile.readIntE(); + efile.readFully(segname); + seg.segname = new String(segname, 0, 16); + seg.vmaddr = efile.readIntE(); + seg.vmsize = efile.readIntE(); + seg.fileoff = efile.readIntE(); + seg.filesize = efile.readIntE(); + seg.maxprot = efile.readIntE(); + seg.initprot = efile.readIntE(); + seg.nsects = efile.readIntE(); + seg.flags = efile.readIntE(); + sections = getSections(seg); + loadcommands[i] = seg; + break; + + case LoadCommand.LC_SYMTAB: + SymtabCommand stcmd = new SymtabCommand(); + stcmd.cmd = cmd; + stcmd.cmdsize = efile.readIntE(); + stcmd.symoff = efile.readIntE(); + stcmd.nsyms = efile.readIntE(); + stcmd.stroff = efile.readIntE(); + stcmd.strsize = efile.readIntE(); + loadcommands[i] = stcmd; + break; + + case LoadCommand.LC_SYMSEG: + SymSegCommand sscmd = new SymSegCommand(); + sscmd.cmd = cmd; + sscmd.cmdsize = efile.readIntE(); + sscmd.offset = efile.readIntE(); + sscmd.size = efile.readIntE(); + loadcommands[i] = sscmd; + break; + + case LoadCommand.LC_THREAD: + case LoadCommand.LC_UNIXTHREAD: + ThreadCommand thcmd = new ThreadCommand(); + thcmd.cmd = cmd; + thcmd.cmdsize = efile.readIntE(); + efile.skipBytes(thcmd.cmdsize - 8 /* sizeof(ThreadCommand) */); + loadcommands[i] = thcmd; + break; + + case LoadCommand.LC_LOADFVMLIB: + case LoadCommand.LC_IDFVMLIB: + FVMLibCommand fvmcmd = new FVMLibCommand(); + fvmcmd.cmd = cmd; + fvmcmd.cmdsize = efile.readIntE(); + fvmcmd.fvmlib = new FVMLib(); + fvmcmd.fvmlib.name = efile.readIntE(); + fvmcmd.fvmlib.minor_version = efile.readIntE(); + fvmcmd.fvmlib.header_addr = efile.readIntE(); + len = fvmcmd.cmdsize - 20 /* sizeof FVMLibCommand */; + fvmcmd.fvmlib.lc_str_name = getLCStr(len); + len -= fvmcmd.fvmlib.lc_str_name.length() + 1; + efile.skipBytes(len); + loadcommands[i] = fvmcmd; + break; + + case LoadCommand.LC_IDENT: + IdentCommand icmd = new IdentCommand(); + icmd.cmd = cmd; + icmd.cmdsize = efile.readIntE(); + loadcommands[i] = icmd; + break; + + case LoadCommand.LC_FVMFILE: + FVMFileCommand fcmd = new FVMFileCommand(); + fcmd.cmd = cmd; + fcmd.cmdsize = efile.readIntE(); + fcmd.name = efile.readIntE(); + fcmd.header_addr = efile.readIntE(); + len = fcmd.cmdsize - 16 /* sizeof FVMFileCommand */; + fcmd.lc_str_name = getLCStr(len); + len -= fcmd.lc_str_name.length() + 1; + efile.skipBytes(len); + loadcommands[i] = fcmd; + break; + + case LoadCommand.LC_DYSYMTAB: + DySymtabCommand dscmd = new DySymtabCommand(); + dscmd.cmd = cmd; + dscmd.cmdsize = efile.readIntE(); + dscmd.ilocalsym = efile.readIntE(); + dscmd.nlocalsym = efile.readIntE(); + dscmd.iextdefsym = efile.readIntE(); + dscmd.nextdefsym = efile.readIntE(); + dscmd.iundefsym = efile.readIntE(); + dscmd.nundefsym = efile.readIntE(); + dscmd.tocoff = efile.readIntE(); + dscmd.ntoc = efile.readIntE(); + dscmd.modtaboff = efile.readIntE(); + dscmd.nmodtab = efile.readIntE(); + dscmd.extrefsymoff = efile.readIntE(); + dscmd.nextrefsyms = efile.readIntE(); + dscmd.indirectsymoff = efile.readIntE(); + dscmd.nindirectsyms = efile.readIntE(); + dscmd.extreloff = efile.readIntE(); + dscmd.nextrel = efile.readIntE(); + dscmd.locreloff = efile.readIntE(); + dscmd.nlocrel = efile.readIntE(); + loadcommands[i] = dscmd; + dynsym = true; + break; + + case LoadCommand.LC_LOAD_DYLIB: + case LoadCommand.LC_ID_DYLIB: + DyLibCommand dylcmd = new DyLibCommand(); + dylcmd.cmd = cmd; + dylcmd.cmdsize = efile.readIntE(); + dylcmd.dylib = new DyLib(); + dylcmd.dylib.name = efile.readIntE(); + dylcmd.dylib.timestamp = efile.readIntE(); + dylcmd.dylib.current_version = efile.readIntE(); + dylcmd.dylib.compatibility_version = efile.readIntE(); + len = dylcmd.cmdsize - 24 /* sizeof DyLibCommand */; + dylcmd.dylib.lc_str_name = getLCStr(len); + len -= dylcmd.dylib.lc_str_name.length() + 1; + efile.skipBytes(len); + loadcommands[i] = dylcmd; + break; + + case LoadCommand.LC_LOAD_DYLINKER: + case LoadCommand.LC_ID_DYLINKER: + DyLinkerCommand dylkcmd = new DyLinkerCommand(); + dylkcmd.cmd = cmd; + dylkcmd.cmdsize = efile.readIntE(); + dylkcmd.name = efile.readIntE(); + len = dylkcmd.cmdsize - 12 /* sizeof(DyLinkerCommand) */; + dylkcmd.lc_str_name = getLCStr(len); + len -= dylkcmd.lc_str_name.length() + 1; + efile.skipBytes(len); + loadcommands[i] = dylkcmd; + break; + + case LoadCommand.LC_PREBOUND_DYLIB: + PreboundDyLibCommand pbcmd = new PreboundDyLibCommand(); + pbcmd.cmd = cmd; + pbcmd.cmdsize = efile.readIntE(); + pbcmd.name = efile.readIntE(); + pbcmd.nmodules = efile.readIntE(); + pbcmd.linked_modules = efile.readIntE(); + len = pbcmd.cmdsize - 20 /* sizeof(PreboundDyLibCommand) */; + pbcmd.lc_str_name = getLCStr(len); + len -= pbcmd.lc_str_name.length() + 1; + efile.skipBytes(len); + loadcommands[i] = pbcmd; + break; + + case LoadCommand.LC_ROUTINES: + RoutinesCommand rcmd = new RoutinesCommand(); + rcmd.cmd = cmd; + rcmd.cmdsize = efile.readIntE(); + rcmd.init_address = efile.readIntE(); + rcmd.init_module = efile.readIntE(); + rcmd.reserved1 = efile.readIntE(); + rcmd.reserved2 = efile.readIntE(); + rcmd.reserved3 = efile.readIntE(); + rcmd.reserved4 = efile.readIntE(); + rcmd.reserved5 = efile.readIntE(); + rcmd.reserved6 = efile.readIntE(); + loadcommands[i] = rcmd; + break; + + case LoadCommand.LC_SUB_FRAMEWORK: + SubFrameworkCommand subfcmd = new SubFrameworkCommand(); + subfcmd.cmd = cmd; + subfcmd.cmdsize = efile.readIntE(); + subfcmd.umbrella = efile.readIntE(); + len = subfcmd.cmdsize - 12 /* sizeof(SubFrameworkCommand) */ ; + subfcmd.lc_str_name = getLCStr(len); + len -= subfcmd.lc_str_name.length() + 1; + efile.skipBytes(len); + loadcommands[i] = subfcmd; + break; + + case LoadCommand.LC_SUB_UMBRELLA: + SubUmbrellaCommand subucmd = new SubUmbrellaCommand(); + subucmd.cmd = cmd; + subucmd.cmdsize = efile.readIntE(); + subucmd.sub_umbrella = efile.readIntE(); + len = subucmd.cmdsize - 12 /* sizeof(SubUmbrellaCommand) */; + subucmd.lc_str_name = getLCStr(len); + len -= subucmd.lc_str_name.length() + 1; + efile.skipBytes(len); + loadcommands[i] = subucmd; + break; + + case LoadCommand.LC_SUB_CLIENT: + SubClientCommand subccmd = new SubClientCommand(); + subccmd.cmd = cmd; + subccmd.cmdsize = efile.readIntE(); + subccmd.client = efile.readIntE(); + len = subccmd.cmdsize - 12 /* sizeof(SubClientCommand) */; + subccmd.lc_str_name = getLCStr(len); + len -= subccmd.lc_str_name.length() + 1; + efile.skipBytes(len); + loadcommands[i] = subccmd; + break; + + case LoadCommand.LC_SUB_LIBRARY: + SubLibraryCommand sublcmd = new SubLibraryCommand(); + sublcmd.cmd = cmd; + sublcmd.cmdsize = efile.readIntE(); + sublcmd.sub_library = efile.readIntE(); + len = sublcmd.cmdsize - 12 /* sizeof(SubLibraryCommand) */; + sublcmd.lc_str_name = getLCStr(len); + len -= sublcmd.lc_str_name.length() + 1; + efile.skipBytes(len); + loadcommands[i] = sublcmd; + break; + + case LoadCommand.LC_TWOLEVEL_HINTS: + TwoLevelHintsCommand tlhcmd = new TwoLevelHintsCommand(); + tlhcmd.cmd = cmd; + tlhcmd.cmdsize = efile.readIntE(); + tlhcmd.offset = efile.readIntE(); + tlhcmd.nhints = efile.readIntE(); + loadcommands[i] = tlhcmd; + break; + + case LoadCommand.LC_PREBIND_CKSUM: + PrebindCksumCommand pbccmd = new PrebindCksumCommand(); + pbccmd.cmd = cmd; + pbccmd.cmdsize = efile.readIntE(); + pbccmd.cksum = efile.readIntE(); + loadcommands[i] = pbccmd; + break; + } + } + } + } + + public void loadBinary() throws IOException { + if ( loadcommands == null ) { + loadLoadCommands(); + loadSymbolTable(); + loadLineTable(); + } + } + + public Symbol[] getSymbols() { + return symbols; + } + + public Symbol[] getDynamicSymbols() { + if (dynsym) { + return symbols; + } + return null; + } + + public Symbol[] getSymtabSymbols() { + return symbols; + } + + public Symbol[] getLocalSymbols() { + if (local_symbols == null) { + return symbols; + } + return local_symbols; + } + + public Line[] getLineTable() { + return lines; + } + + public Section[] getSections() { + return sections; + } + + public DyLib[] getDyLibs(int type) { + Vector v = new Vector(); + + for (int i = 0; i < loadcommands.length; i++) { + if (loadcommands[i].cmd == type) { + DyLibCommand dl = (DyLibCommand)loadcommands[i]; + v.add(dl.dylib); + } + } + return (DyLib[]) v.toArray(new DyLib[0]); + } + + /* return the address of the function that address is in */ + public Symbol getSymbol( long vma ) { + if ( symbols == null ) { + return null; + } + + //@@@ If this works, move it to a single instance in this class. + SymbolComparator symbol_comparator = new SymbolComparator(); + + int ndx = Arrays.binarySearch(symbols, new Long(vma), symbol_comparator); + if ( ndx > 0 ) + return symbols[ndx]; + if ( ndx == -1 ) { + return null; + } + ndx = -ndx - 1; + return symbols[ndx-1]; + } + + public long swapInt( long val ) { + if ( mhdr.magic == MachOhdr.MH_CIGAM ) { + short tmp[] = new short[4]; + tmp[0] = (short)(val & 0x00ff); + tmp[1] = (short)((val >> 8) & 0x00ff); + tmp[2] = (short)((val >> 16) & 0x00ff); + tmp[3] = (short)((val >> 24) & 0x00ff); + return (long)((tmp[0] << 24) + (tmp[1] << 16) + (tmp[2] << 8) + tmp[3]); + } + return val; + } + + public int swapShort( short val ) { + if ( mhdr.magic == MachOhdr.MH_CIGAM ) { + short tmp[] = new short[2]; + tmp[0] = (short)(val & 0x00ff); + tmp[1] = (short)((val >> 8) & 0x00ff); + return (short)((tmp[0] << 8) + tmp[1]); + } + return val; + } + + public String getFilename() { + return file; + } +} diff --git a/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/macho/MachOHelper.java b/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/macho/MachOHelper.java new file mode 100644 index 00000000000..8a33d32f13e --- /dev/null +++ b/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/macho/MachOHelper.java @@ -0,0 +1,315 @@ +package org.eclipse.cdt.utils.macho; + +/* + * (c) Copyright QNX Software Systems Ltd. 2002. + * All Rights Reserved. + */ + +import java.io.IOException; +import java.util.Arrays; +import java.util.Vector; + +/** + * MachOHelper is a wrapper class for the MachO class + * to provide higher level API for sorting/searching the MachO data. + * + * @see MachO + */ +public class MachOHelper { + + private MachO macho; + private MachO.MachOhdr hdr; + private MachO.Attribute attrib; + private MachO.Symbol[] dynsyms; + private MachO.Symbol[] symbols; + private MachO.Section[] sections; + private MachO.DyLib[] needed; + private MachO.DyLib[] sonames; + + public void dispose() { + if (macho != null) { + macho.dispose(); + macho = null; + } + } + + public class Sizes { + public long text; + public long data; + public long bss; + public long total; + public Sizes(long t, long d, long b) { + text = t; + data = d; + bss = b; + total = text + data + bss; + } + } + + private void loadBinary() throws IOException { + if (symbols == null) { + macho.loadBinary(); + symbols = macho.getSymtabSymbols(); + dynsyms = macho.getDynamicSymbols(); + sections = macho.getSections(); + needed = macho.getDyLibs(MachO.LoadCommand.LC_LOAD_DYLIB); + sonames = macho.getDyLibs(MachO.LoadCommand.LC_ID_DYLIB); + + if (dynsyms == null) + dynsyms = symbols; + } + } + + /** Common code used by all constructors */ + private void commonSetup() throws IOException { + hdr = macho.getMachOhdr(); + attrib = macho.getAttributes(); + } + + /** + * Create a new MachOHelper using an existing MachO + * object. + * @param macho An existing MachO object to wrap. + * @throws IOException Error processing the MachO file. + */ + public MachOHelper(MachO macho) throws IOException { + this.macho = macho; + commonSetup(); + } + + /** + * Create a new MachOHelper based on the given filename. + * + * @param filename The file to use for creating a new MachO object. + * @throws IOException Error processing the MachO file. + * @see MachO#MachO( String ) + */ + public MachOHelper(String filename) throws IOException { + macho = new MachO(filename); + commonSetup(); + } + + public MachOHelper(String filename, boolean filton) throws IOException { + macho = new MachO(filename, filton); + commonSetup(); + } + + /** Give back the MachO object that this helper is wrapping */ + public MachO getMachO() { + return macho; + } + + public MachO.Symbol[] getExternalFunctions() throws IOException { + Vector v = new Vector(); + + loadBinary(); + + for (int i = 0; i < dynsyms.length; i++) { + MachO.Symbol sym = dynsyms[i]; + if ((sym.n_type_mask(MachO.Symbol.N_PEXT) + || sym.n_type_mask(MachO.Symbol.N_EXT)) + && sym.n_desc(MachO.Symbol.REFERENCE_FLAG_UNDEFINED_LAZY)) { + String name = sym.toString(); + if (name != null && name.trim().length() > 0) + v.add(sym); + } + } + + MachO.Symbol[] ret = (MachO.Symbol[]) v.toArray(new MachO.Symbol[0]); + Arrays.sort(ret, new SymbolSortCompare()); + return ret; + } + + public MachO.Symbol[] getExternalObjects() throws IOException { + Vector v = new Vector(); + + loadBinary(); + + for (int i = 0; i < dynsyms.length; i++) { + MachO.Symbol sym = dynsyms[i]; + if ((sym.n_type_mask(MachO.Symbol.N_PEXT) + || sym.n_type_mask(MachO.Symbol.N_EXT)) + && sym.n_desc(MachO.Symbol.REFERENCE_FLAG_UNDEFINED_NON_LAZY)) { + String name = sym.toString(); + if (name != null && name.trim().length() > 0) + v.add(sym); + } + } + + MachO.Symbol[] ret = (MachO.Symbol[]) v.toArray(new MachO.Symbol[0]); + Arrays.sort(ret, new SymbolSortCompare()); + return ret; + } + + public MachO.Symbol[] getUndefined() throws IOException { + Vector v = new Vector(); + + loadBinary(); + + for (int i = 0; i < dynsyms.length; i++) { + if (dynsyms[i].n_type(MachO.Symbol.N_UNDF)) + v.add(dynsyms[i]); + } + + MachO.Symbol[] ret = (MachO.Symbol[]) v.toArray(new MachO.Symbol[0]); + Arrays.sort(ret, new SymbolSortCompare()); + return ret; + } + + /* + * TODO: I'm not sure if this are correct. Need to check + */ + public MachO.Symbol[] getLocalFunctions() throws IOException { + Vector v = new Vector(); + + loadBinary(); + + for (int i = 0; i < dynsyms.length; i++) { + MachO.Symbol sym = dynsyms[i]; + if ((!sym.n_type_mask(MachO.Symbol.N_PEXT) + && !sym.n_type_mask(MachO.Symbol.N_EXT)) + && sym.n_desc(MachO.Symbol.REFERENCE_FLAG_PRIVATE_UNDEFINED_LAZY)) { + String name = sym.toString(); + if (name != null && name.trim().length() > 0) + v.add(sym); + } + } + + MachO.Symbol[] ret = (MachO.Symbol[]) v.toArray(new MachO.Symbol[0]); + Arrays.sort(ret, new SymbolSortCompare()); + return ret; + } + + /* + * TODO: I'm not sure if this are correct. Need to check + */ + public MachO.Symbol[] getLocalObjects() throws IOException { + Vector v = new Vector(); + + loadBinary(); + + for (int i = 0; i < dynsyms.length; i++) { + MachO.Symbol sym = dynsyms[i]; + if ((!sym.n_type_mask(MachO.Symbol.N_PEXT) + && !sym.n_type_mask(MachO.Symbol.N_EXT)) + && sym.n_desc(MachO.Symbol.REFERENCE_FLAG_PRIVATE_UNDEFINED_NON_LAZY)) { + String name = sym.toString(); + if (name != null && name.trim().length() > 0) + v.add(sym); + } + } + + MachO.Symbol[] ret = (MachO.Symbol[]) v.toArray(new MachO.Symbol[0]); + Arrays.sort(ret, new SymbolSortCompare()); + return ret; + } + + public MachO.Symbol[] getCommonObjects() throws IOException { + Vector v = new Vector(); + + loadBinary(); + + for (int i = 0; i < dynsyms.length; i++) { + MachO.Symbol sym = dynsyms[i]; + if (sym.n_type_mask(MachO.Symbol.N_EXT) + && sym.n_type(MachO.Symbol.N_UNDF) + && sym.n_value != 0) { + v.add(symbols[i]); + } + } + + MachO.Symbol[] ret = (MachO.Symbol[]) v.toArray(new MachO.Symbol[0]); + Arrays.sort(ret, new SymbolSortCompare()); + return ret; + } + + public String[] getNeeded() throws IOException { + Vector v = new Vector(); + + loadBinary(); + + for (int i = 0; i < needed.length; i++) { + v.add(needed[i].toString()); + } + return (String[]) v.toArray(new String[0]); + } + + public String getSoname() throws IOException { + String soname = ""; //$NON-NLS-1$ + + loadBinary(); + + for (int i = 0; i < sonames.length; i++) { + soname = sonames[i].toString(); + } + return soname; + } + + private String getSubUsage(String full, String name) { + int start, end; + //boolean has_names = false; + //boolean has_languages = false; + start = 0; + end = 0; + + for (int i = 0; i < full.length(); i++) { + if (full.charAt(i) == '%') { + if (full.charAt(i + 1) == '-') { + if (start == 0) { + int eol = full.indexOf('\n', i + 2); + String temp = full.substring(i + 2, eol); + if (temp.compareTo(name) == 0) + start = eol; + + //has_names = true; + } else if (end == 0) { + end = i - 1; + } + } + + //if( full.charAt( i+1 ) == '=' ) + //has_languages = true; + } + } + + if (end == 0) + end = full.length(); + + if (start == 0) + return full; + + return full.substring(start, end); + } + + public String getQnxUsage() throws IOException { + return new String(""); //$NON-NLS-1$ + } + + public Sizes getSizes() throws IOException { + long text, data, bss; + + text = 0; + data = 0; + bss = 0; + + loadBinary(); + + for (int i = 0; i < sections.length; i++) { + MachO.SegmentCommand seg = sections[i].segment; + if (sections[i].flags(MachO.Section.SECTION_TYP) != MachO.Section.S_ZEROFILL) { + if (seg.prot(MachO.SegmentCommand.VM_PROT_EXECUTE)) { + text += sections[i].size; + } else if (!seg.prot(MachO.SegmentCommand.VM_PROT_WRITE)) { + data += sections[i].size; + } + } else { + if (seg.prot(MachO.SegmentCommand.VM_PROT_WRITE)) { + bss += sections[i].size; + } + } + } + + return new Sizes(text, data, bss); + } + +} diff --git a/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/macho/SymbolSortCompare.java b/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/macho/SymbolSortCompare.java new file mode 100644 index 00000000000..c64a25ccdf6 --- /dev/null +++ b/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/macho/SymbolSortCompare.java @@ -0,0 +1,24 @@ +package org.eclipse.cdt.utils.macho; + +/* + * (c) Copyright QNX Software Systems Ltd. 2002. + * All Rights Reserved. + */ + +import java.util.Comparator; + +public class SymbolSortCompare implements Comparator { + public int compare( Object o1, Object o2 ) { + String s1 = o1.toString().toLowerCase(); + String s2 = o2.toString().toLowerCase(); + + while( s1.length() > 0 && s1.charAt( 0 ) == '_' ) + s1 = s1.substring( 1 ); + + while( s2.length() > 0 && s2.charAt( 0 ) == '_' ) + s2 = s2.substring( 1 ); + + return s1.compareTo( s2 ); + } +} + diff --git a/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/macho/parser/ARMember.java b/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/macho/parser/ARMember.java new file mode 100644 index 00000000000..910da6d567d --- /dev/null +++ b/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/macho/parser/ARMember.java @@ -0,0 +1,83 @@ +/********************************************************************** + * Copyright (c) 2002,2003 QNX Software Systems and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * QNX Software Systems - Initial API and implementation +***********************************************************************/ +package org.eclipse.cdt.utils.macho.parser; + +import java.io.ByteArrayInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.util.List; + +import org.eclipse.cdt.core.CCorePlugin; +import org.eclipse.cdt.core.IBinaryParser; +import org.eclipse.cdt.utils.Addr2line; +import org.eclipse.cdt.utils.CPPFilt; +import org.eclipse.cdt.utils.Symbol; +import org.eclipse.cdt.utils.macho.AR; +import org.eclipse.cdt.utils.macho.MachO; +import org.eclipse.cdt.utils.macho.MachOHelper; +import org.eclipse.core.runtime.IPath; + +/** + * ARMember + */ +public class ARMember extends MachOBinaryObject { + AR.ARHeader header; + + public ARMember(IBinaryParser parser, IPath p, AR.ARHeader h) throws IOException { + super(parser, p); + header = h; + } + + /** + * @see org.eclipse.cdt.core.model.IBinaryParser.IBinaryFile#getContents() + */ + public InputStream getContents() { + InputStream stream = null; + if (path != null && header != null) { + try { + stream = new ByteArrayInputStream(header.getObjectData()); + } catch (IOException e) { + } + } + if (stream == null) { + stream = super.getContents(); + } + return stream; + } + + /** + * @see org.eclipse.cdt.core.model.IBinaryParser.IBinaryObject#getName() + */ + public String getName() { + if (header != null) { + return header.getObjectName(); + } + return ""; //$NON-NLS-1$ + } + + protected MachOHelper getMachOHelper() throws IOException { + if (header != null) { + return new MachOHelper(header.getMachO()); + } + throw new IOException(CCorePlugin.getResourceString("Util.exception.noFileAssociation")); //$NON-NLS-1$ + } + + protected void addSymbols(MachO.Symbol[] array, int type, Addr2line addr2line, CPPFilt cppfilt, List list) { + for (int i = 0; i < array.length; i++) { + Symbol sym = new Symbol(this); + sym.type = type; + sym.name = array[i].toString(); + sym.addr = array[i].n_value; + list.add(sym); + } + } + +} diff --git a/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/macho/parser/BinaryArchive.java b/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/macho/parser/BinaryArchive.java new file mode 100644 index 00000000000..a7b3e1e1710 --- /dev/null +++ b/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/macho/parser/BinaryArchive.java @@ -0,0 +1,80 @@ +/********************************************************************** + * Copyright (c) 2002,2003 QNX Software Systems and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * QNX Software Systems - Initial API and implementation +***********************************************************************/ +package org.eclipse.cdt.utils.macho.parser; + +import java.io.IOException; +import java.util.ArrayList; + +import org.eclipse.cdt.core.IBinaryParser; +import org.eclipse.cdt.core.IBinaryParser.IBinaryArchive; +import org.eclipse.cdt.core.IBinaryParser.IBinaryFile; +import org.eclipse.cdt.core.IBinaryParser.IBinaryObject; +import org.eclipse.cdt.utils.BinaryFile; +import org.eclipse.cdt.utils.macho.AR; +import org.eclipse.core.runtime.IPath; + +/** + */ +public class BinaryArchive extends BinaryFile implements IBinaryArchive { + + ArrayList children; + + public BinaryArchive(IBinaryParser parser, IPath p) throws IOException { + super(parser, p); + new AR(p.toOSString()).dispose(); // check file type + children = new ArrayList(5); + } + + /** + * @see org.eclipse.cdt.core.model.IBinaryParser.IBinaryArchive#getObjects() + */ + public IBinaryObject[] getObjects() { + if (hasChanged()) { + children.clear(); + AR ar = null; + try { + ar = new AR(getPath().toOSString()); + AR.ARHeader[] headers = ar.getHeaders(); + for (int i = 0; i < headers.length; i++) { + IBinaryObject bin = new ARMember(getBinaryParser(), getPath(), headers[i]); + children.add(bin); + } + } catch (IOException e) { + //e.printStackTrace(); + } + if (ar != null) { + ar.dispose(); + } + children.trimToSize(); + } + return (IBinaryObject[]) children.toArray(new IBinaryObject[0]); + } + + /** + * @see org.eclipse.cdt.core.model.IBinaryParser.IBinaryFile#getType() + */ + public int getType() { + return IBinaryFile.ARCHIVE; + } + + /** + * @see org.eclipse.cdt.core.model.IBinaryParser.IBinaryArchive#add(IBinaryObject[]) + */ + public void add(IBinaryObject[] objs) throws IOException { + } + + /** + * @see org.eclipse.cdt.core.model.IBinaryParser.IBinaryArchive#delete(IBinaryObject[]) + */ + public void delete(IBinaryObject[] objs) throws IOException { + } + +} diff --git a/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/macho/parser/MachOBinaryObject.java b/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/macho/parser/MachOBinaryObject.java new file mode 100644 index 00000000000..b26aba18d41 --- /dev/null +++ b/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/macho/parser/MachOBinaryObject.java @@ -0,0 +1,170 @@ +/********************************************************************** + * Copyright (c) 2002,2003,2004 QNX Software Systems and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * QNX Software Systems - Initial API and implementation +***********************************************************************/ +package org.eclipse.cdt.utils.macho.parser; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +import org.eclipse.cdt.core.IBinaryParser; +import org.eclipse.cdt.core.IBinaryParser.IBinaryFile; +import org.eclipse.cdt.core.IBinaryParser.ISymbol; +import org.eclipse.cdt.utils.*; +import org.eclipse.cdt.utils.BinaryObjectAdapter; +import org.eclipse.cdt.utils.CPPFilt; +import org.eclipse.cdt.utils.macho.MachO; +import org.eclipse.cdt.utils.macho.MachOHelper; +import org.eclipse.core.runtime.IPath; +import org.eclipse.core.runtime.Path; + +/* + * MachOBinaryObject + */ +public class MachOBinaryObject extends BinaryObjectAdapter { + + private BinaryObjectInfo info; + private ISymbol[] symbols; + + public MachOBinaryObject(IBinaryParser parser, IPath path) { + super(parser, path); + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.core.IBinaryParser.IBinaryFile#getType() + */ + public int getType() { + return IBinaryFile.OBJECT; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.core.IBinaryParser.IBinaryObject#getSymbols() + */ + public ISymbol[] getSymbols() { + // Call the hasChanged first, to initialize the timestamp + if (hasChanged() || symbols == null) { + try { + loadAll(); + } catch (IOException e) { + symbols = NO_SYMBOLS; + } + } + return symbols; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.utils.BinaryObjectAdapter#getBinaryObjectInfo() + */ + protected BinaryObjectInfo getBinaryObjectInfo() { + // Call the hasChanged first, to initialize the timestamp + if (hasChanged() || info == null) { + try { + loadInfo(); + } catch (IOException e) { + info = new BinaryObjectInfo(); + } + } + return info; + } + + protected MachOHelper getMachOHelper() throws IOException { + return new MachOHelper(getPath().toOSString()); + } + + protected void loadAll() throws IOException { + MachOHelper helper = null; + try { + helper = getMachOHelper(); + loadInfo(helper); + loadSymbols(helper); + } finally { + if (helper != null) { + helper.dispose(); + } + } + } + + protected void loadInfo() throws IOException { + MachOHelper helper = null; + try { + helper = getMachOHelper(); + loadInfo(helper); + } finally { + if (helper != null) { + helper.dispose(); + } + } + } + + protected void loadInfo(MachOHelper helper) throws IOException { + info = new BinaryObjectInfo(); + info.needed = helper.getNeeded(); + MachOHelper.Sizes sizes = helper.getSizes(); + info.bss = sizes.bss; + info.data = sizes.data; + info.text = sizes.text; + + info.soname = helper.getSoname(); + + MachO.Attribute attribute = helper.getMachO().getAttributes(); + info.isLittleEndian = attribute.isLittleEndian(); + info.hasDebug = attribute.hasDebug(); + info.cpu = attribute.getCPU(); + } + + protected void loadSymbols(MachOHelper helper) throws IOException { + ArrayList list = new ArrayList(); + // Hack should be remove when Elf is clean + helper.getMachO().setCppFilter(false); + + CPPFilt cppfilt = getCPPFilt(); + + addSymbols(helper.getExternalFunctions(), ISymbol.FUNCTION, cppfilt, list); + addSymbols(helper.getLocalFunctions(), ISymbol.FUNCTION, cppfilt, list); + addSymbols(helper.getExternalObjects(), ISymbol.VARIABLE, cppfilt, list); + addSymbols(helper.getLocalObjects(), ISymbol.VARIABLE, cppfilt, list); + list.trimToSize(); + + if (cppfilt != null) { + cppfilt.dispose(); + } + + symbols = (ISymbol[])list.toArray(NO_SYMBOLS); + Arrays.sort(symbols); + list.clear(); + } + + protected void addSymbols(MachO.Symbol[] array, int type, CPPFilt cppfilt, List list) { + for (int i = 0; i < array.length; i++) { + Symbol sym = new Symbol(this); + sym.type = type; + sym.name = array[i].toString(); + if (cppfilt != null) { + try { + sym.name = cppfilt.getFunction(sym.name); + } catch (IOException e1) { + cppfilt = null; + } + } + sym.addr = array[i].n_value; + sym.size = 0; + sym.filename = null; + sym.startLine = 0; + sym.endLine = sym.startLine; + String filename = array[i].getFilename(); + sym.filename = (filename != null) ? new Path(filename) : null; //$NON-NLS-1$ + sym.startLine = array[i].getLineNumber(sym.addr); + sym.endLine = array[i].getLineNumber(sym.addr + sym.size - 1); + list.add(sym); + } + } + +} diff --git a/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/macho/parser/MachOParser.java b/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/macho/parser/MachOParser.java new file mode 100644 index 00000000000..e0710e11efb --- /dev/null +++ b/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/macho/parser/MachOParser.java @@ -0,0 +1,147 @@ +/********************************************************************** + * Copyright (c) 2002,2003,2004 QNX Software Systems and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * QNX Software Systems - Initial API and implementation +***********************************************************************/ +package org.eclipse.cdt.utils.macho.parser; + +import java.io.EOFException; +import java.io.IOException; + +import org.eclipse.cdt.core.CCorePlugin; +import org.eclipse.cdt.core.IBinaryParser; +import org.eclipse.cdt.utils.ToolsProvider; +import org.eclipse.cdt.utils.macho.AR; +import org.eclipse.cdt.utils.macho.MachO; +import org.eclipse.cdt.utils.macho.MachO.Attribute; +import org.eclipse.core.runtime.IPath; + +/** + */ +public class MachOParser extends ToolsProvider implements IBinaryParser { + + /* (non-Javadoc) + * @see org.eclipse.cdt.core.IBinaryParser#getBinary(org.eclipse.core.runtime.IPath) + */ + public IBinaryFile getBinary(IPath path) throws IOException { + return getBinary(null, path); + } + + + public IBinaryFile getBinary(byte[] hints, IPath path) throws IOException { + if (path == null) { + throw new IOException(CCorePlugin.getResourceString("Util.exception.nullPath")); //$NON-NLS-1$ + } + + IBinaryFile binary = null; + try { + MachO.Attribute attribute = null; + if (hints != null && hints.length > 0) { + try { + attribute = MachO.getAttributes(hints); + } catch (EOFException eof) { + // continue, the array was to small. + } + } + + //Take a second run at it if the data array failed. + if(attribute == null) { + attribute = MachO.getAttributes(path.toOSString()); + } + + if (attribute != null) { + switch (attribute.getType()) { + case Attribute.MACHO_TYPE_EXE : + binary = createBinaryExecutable(path); + break; + + case Attribute.MACHO_TYPE_SHLIB : + binary = createBinaryShared(path); + break; + + case Attribute.MACHO_TYPE_OBJ : + binary = createBinaryObject(path); + break; + + case Attribute.MACHO_TYPE_CORE : + binary = createBinaryCore(path); + break; + } + } + } catch (IOException e) { + binary = createBinaryArchive(path); + } + return binary; + } + + /** + * @see org.eclipse.cdt.core.model.IBinaryParser#getFormat() + */ + public String getFormat() { + return "MACHO"; //$NON-NLS-1$ + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.core.IBinaryParser#isBinary(byte[], org.eclipse.core.runtime.IPath) + */ + public boolean isBinary(byte[] array, IPath path) { + return MachO.isMachOHeader(array) || AR.isARHeader(array); + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.core.IBinaryParser#getBufferSize() + */ + public int getHintBufferSize() { + return 128; + } + + /** + * @param path + * @return + */ + protected IBinaryArchive createBinaryArchive(IPath path) throws IOException { + return new BinaryArchive(this, path); + } + + protected IBinaryObject createBinaryObject(IPath path) throws IOException { + return new MachOBinaryObject(this, path); + } + + protected IBinaryExecutable createBinaryExecutable(IPath path) throws IOException { + return new MachOBinaryObject(this, path) { + /* (non-Javadoc) + * @see org.eclipse.cdt.utils.macho.parser.MachOBinaryObject#getType() + */ + public int getType() { + return IBinaryFile.EXECUTABLE; + } + }; + } + + protected IBinaryShared createBinaryShared(IPath path) throws IOException { + return new MachOBinaryObject(this, path) { + /* (non-Javadoc) + * @see org.eclipse.cdt.utils.macho.parser.MachOBinaryObject#getType() + */ + public int getType() { + return IBinaryFile.SHARED; + } + }; + } + + protected IBinaryObject createBinaryCore(IPath path) throws IOException { + return new MachOBinaryObject(this, path) { + /* (non-Javadoc) + * @see org.eclipse.cdt.utils.macho.parser.MachOBinaryObject#getType() + */ + public int getType() { + return IBinaryFile.CORE; + } + }; + } +} diff --git a/core/org.eclipse.cdt.ui/plugin.xml b/core/org.eclipse.cdt.ui/plugin.xml index 73d37a915b8..0a09461f250 100644 --- a/core/org.eclipse.cdt.ui/plugin.xml +++ b/core/org.eclipse.cdt.ui/plugin.xml @@ -703,6 +703,11 @@ parserID="org.eclipse.cdt.core.XCOFF32" id="XcoffBinaryParserPage"> + + diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/ui/dialogs/MachOBinaryParserPage.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/ui/dialogs/MachOBinaryParserPage.java new file mode 100644 index 00000000000..b993af0e719 --- /dev/null +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/ui/dialogs/MachOBinaryParserPage.java @@ -0,0 +1,217 @@ +/******************************************************************************* + * Copyright (c) 2003, 2004 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * QNX Software Systems - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.cdt.ui.dialogs; + +import java.io.File; + +import org.eclipse.cdt.core.CCorePlugin; +import org.eclipse.cdt.core.ICDescriptor; +import org.eclipse.cdt.core.ICExtensionReference; +import org.eclipse.cdt.internal.ui.CUIMessages; +import org.eclipse.cdt.ui.CUIPlugin; +import org.eclipse.cdt.utils.ui.controls.ControlFactory; +import org.eclipse.core.resources.IProject; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IConfigurationElement; +import org.eclipse.core.runtime.IExtensionPoint; +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.core.runtime.NullProgressMonitor; +import org.eclipse.core.runtime.Platform; +import org.eclipse.core.runtime.Preferences; +import org.eclipse.swt.SWT; +import org.eclipse.swt.events.ModifyEvent; +import org.eclipse.swt.events.ModifyListener; +import org.eclipse.swt.events.SelectionAdapter; +import org.eclipse.swt.events.SelectionEvent; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.Button; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.FileDialog; +import org.eclipse.swt.widgets.Group; +import org.eclipse.swt.widgets.Label; +import org.eclipse.swt.widgets.Text; + +/** + */ +public class MachOBinaryParserPage extends AbstractCOptionPage { + + public final static String PREF_CPPFILT_PATH = CUIPlugin.PLUGIN_ID + ".cppfilt"; //$NON-NLS-1$ + + protected Text fCPPFiltCommandText; + + /* + * (non-Javadoc) + * + * @see org.eclipse.cdt.ui.dialogs.ICOptionPage#performApply(org.eclipse.core.runtime.IProgressMonitor) + */ + public void performApply(IProgressMonitor monitor) throws CoreException { + if (monitor == null) { + monitor = new NullProgressMonitor(); + } + + String cppfilt = fCPPFiltCommandText.getText().trim(); + + monitor.beginTask(CUIMessages.getString("BinaryParserPage.task.savingAttributes"), 1); //$NON-NLS-1$ + IProject proj = getContainer().getProject(); + if (proj != null) { + String parserID = ""; //$NON-NLS-1$ + ICDescriptor cdesc = CCorePlugin.getDefault().getCProjectDescription(proj); + ICExtensionReference[] cext = cdesc.get(CCorePlugin.BINARY_PARSER_UNIQ_ID); + if (cext.length > 0) { + IExtensionPoint point = Platform.getExtensionRegistry().getExtensionPoint(CUIPlugin.PLUGIN_ID, "BinaryParserPage"); //$NON-NLS-1$ + IConfigurationElement[] infos = point.getConfigurationElements(); + for (int i = 0; i < infos.length; i++) { + String id = infos[i].getAttribute("parserID"); //$NON-NLS-1$ + String clazz = infos[i].getAttribute("class"); //$NON-NLS-1$ + String ego = getRealBinaryParserPage().getClass().getName(); + if (clazz != null && clazz.equals(ego)) { + parserID = id; + break; + } + } + for (int i = 0; i < cext.length; i++) { + if (cext[i].getID().equals(parserID)) { + + String orig = cext[i].getExtensionData("c++filt"); //$NON-NLS-1$ + if (orig == null || !orig.equals(cppfilt)) { + cext[i].setExtensionData("c++filt", cppfilt); //$NON-NLS-1$ + } + } + } + } + } else { + Preferences store = getContainer().getPreferences(); + if (store != null) { + store.setValue(PREF_CPPFILT_PATH, cppfilt); + } + } + } + + /** + * If this class is inherited from then this method MUST be implemented + * in the derived class. + */ + protected Object getRealBinaryParserPage() { + return this; + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.cdt.ui.dialogs.ICOptionPage#performDefaults() + */ + public void performDefaults() { + String addr2line = null; + String cppfilt = null; + IProject proj = getContainer().getProject(); + Preferences store = getContainer().getPreferences(); + if (store != null) { + if (proj != null) { + cppfilt = store.getString(PREF_CPPFILT_PATH); + } else { + cppfilt = store.getDefaultString(PREF_CPPFILT_PATH); + } + fCPPFiltCommandText.setText((cppfilt == null || cppfilt.length() == 0) ? "c++filt" : cppfilt); //$NON-NLS-1$ + } + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.jface.dialogs.IDialogPage#createControl(org.eclipse.swt.widgets.Composite) + */ + public void createControl(Composite parent) { + Group comp = new Group(parent, SWT.SHADOW_ETCHED_IN); + comp.setText(CUIMessages.getString("BinaryParserBlock.binaryParserOptions")); //$NON-NLS-1$ + comp.setLayout(new GridLayout(2, true)); + comp.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); + ((GridLayout) comp.getLayout()).makeColumnsEqualWidth = false; + + Label label = ControlFactory.createLabel(comp, CUIMessages.getString("BinaryParserPage.label.addr2lineCommand")); //$NON-NLS-1$ + GridData gd = new GridData(); + gd.horizontalSpan = 2; + label.setLayoutData(gd); + + Button button = ControlFactory.createPushButton(comp, CUIMessages.getString("BinaryParserPage.label.browse")); //$NON-NLS-1$ + button.addSelectionListener(new SelectionAdapter() { + + public void widgetSelected(SelectionEvent evt) { + //updateLaunchConfigurationDialog(); + } + + }); + + label = ControlFactory.createLabel(comp, CUIMessages.getString("BinaryParserPage.label.cppfiltCommand")); //$NON-NLS-1$ + gd = new GridData(); + gd.horizontalSpan = 2; + label.setLayoutData(gd); + + fCPPFiltCommandText = ControlFactory.createTextField(comp, SWT.SINGLE | SWT.BORDER); + gd = new GridData(GridData.FILL_HORIZONTAL); + fCPPFiltCommandText.setLayoutData(gd); + fCPPFiltCommandText.addModifyListener(new ModifyListener() { + + public void modifyText(ModifyEvent evt) { + //updateLaunchConfigurationDialog(); + } + }); + button = ControlFactory.createPushButton(comp, CUIMessages.getString("BinaryParserPage.label.browse")); //$NON-NLS-1$ + button.addSelectionListener(new SelectionAdapter() { + + public void widgetSelected(SelectionEvent evt) { + handleCPPFiltButtonSelected(); + //updateLaunchConfigurationDialog(); + } + + private void handleCPPFiltButtonSelected() { + FileDialog dialog = new FileDialog(getShell(), SWT.NONE); + dialog.setText(CUIMessages.getString("BinaryParserPage.label.cppfiltCommand")); //$NON-NLS-1$ + String command = fCPPFiltCommandText.getText().trim(); + int lastSeparatorIndex = command.lastIndexOf(File.separator); + if (lastSeparatorIndex != -1) { + dialog.setFilterPath(command.substring(0, lastSeparatorIndex)); + } + String res = dialog.open(); + if (res == null) { + return; + } + fCPPFiltCommandText.setText(res); + } + }); + + setControl(comp); + initialziedValues(); + } + + private void initialziedValues() { + String cppfilt = null; + IProject proj = getContainer().getProject(); + if (proj != null) { + try { + ICDescriptor cdesc = CCorePlugin.getDefault().getCProjectDescription(proj); + ICExtensionReference[] cext = cdesc.get(CCorePlugin.BINARY_PARSER_UNIQ_ID); + if (cext.length > 0) { + cppfilt = cext[0].getExtensionData("c++filt"); //$NON-NLS-1$ + } + } catch (CoreException e) { + } + } else { + Preferences store = getContainer().getPreferences(); + if (store != null) { + cppfilt = store.getString(PREF_CPPFILT_PATH); + } + } + fCPPFiltCommandText.setText((cppfilt == null || cppfilt.length() == 0) ? "c++filt" : cppfilt); //$NON-NLS-1$ + } + +}