[commit][3508] Implement full help and version information for the Cocoa VM .

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
1 message Options
Reply | Threaded
Open this post in threaded view
|

[commit][3508] Implement full help and version information for the Cocoa VM .

commits-3
 
Revision: 3508
Author:   eliot
Date:     2015-11-30 12:14:11 -0800 (Mon, 30 Nov 2015)
Log Message:
-----------
Implement full help and version information for the Cocoa VM.
Copy rather than move the build .app when composing the VM .app (as yet 32-bit
Spur build only).

Modified Paths:
--------------
    branches/Cog/build.macos32x86/squeak.cog.spur/SqueakCogSpur32x86.xcodeproj/project.pbxproj
    branches/Cog/build.macos32x86/squeak.cog.spur/makeiosvm
    branches/Cog/platforms/Mac OS/vm/sqMacUnixCommandLineInterface.c
    branches/Cog/platforms/iOS/vm/Common/Classes/sqSqueakMainApp.m
    branches/Cog/platforms/iOS/vm/Common/main.m
    branches/Cog/platforms/iOS/vm/OSX/sqSqueakOSXApplication+attributes.m
    branches/Cog/platforms/iOS/vm/OSX/sqSqueakOSXApplication.h
    branches/Cog/platforms/iOS/vm/OSX/sqSqueakOSXApplication.m
    branches/Cog/platforms/unix/vm/sqUnixMain.c

Added Paths:
-----------
    branches/Cog/platforms/iOS/vm/Common/version.c

Property Changed:
----------------
    branches/Cog/platforms/Cross/vm/sqSCCSVersion.h

Modified: branches/Cog/build.macos32x86/squeak.cog.spur/SqueakCogSpur32x86.xcodeproj/project.pbxproj
===================================================================
--- branches/Cog/build.macos32x86/squeak.cog.spur/SqueakCogSpur32x86.xcodeproj/project.pbxproj 2015-11-26 21:16:03 UTC (rev 3507)
+++ branches/Cog/build.macos32x86/squeak.cog.spur/SqueakCogSpur32x86.xcodeproj/project.pbxproj 2015-11-30 20:14:11 UTC (rev 3508)
@@ -7,6 +7,7 @@
  objects = {
 
 /* Begin PBXBuildFile section */
+ 731F205E1C0CDE2300A27A22 /* version.c in Sources */ = {isa = PBXBuildFile; fileRef = 731F205D1C0CDE2300A27A22 /* version.c */; };
  9402DD6010CE0C16005C2102 /* SqViewBitmapConversion.m in Sources */ = {isa = PBXBuildFile; fileRef = 9402DD5F10CE0C16005C2102 /* SqViewBitmapConversion.m */; };
  9402DD7010CE0E91005C2102 /* SqViewClut.m in Sources */ = {isa = PBXBuildFile; fileRef = 9402DD6F10CE0E91005C2102 /* SqViewClut.m */; };
  9422C3B51AFFFAC500448DC0 /* Localizable.strings in Resources */ = {isa = PBXBuildFile; fileRef = 9422C3B31AFFFAC500448DC0 /* Localizable.strings */; };
@@ -210,6 +211,7 @@
  1D3623250D0F684500981E51 /* SqueakNoOGLIPhoneAppDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SqueakNoOGLIPhoneAppDelegate.m; sourceTree = "<group>"; };
  1D3623EB0D0F72F000981E51 /* CoreGraphics.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreGraphics.framework; path = System/Library/Frameworks/CoreGraphics.framework; sourceTree = SDKROOT; };
  29B97316FDCFA39411CA2CEA /* main.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = main.m; path = vm/Common/main.m; sourceTree = "<group>"; };
+ 731F205D1C0CDE2300A27A22 /* version.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = version.c; path = vm/Common/version.c; sourceTree = "<group>"; };
  9400325B0DEF3936002FA1C4 /* sqDummyaio.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = sqDummyaio.h; sourceTree = "<group>"; };
  9400325C0DEF3936002FA1C4 /* sqDummyaio.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = sqDummyaio.c; sourceTree = "<group>"; };
  9402DD5E10CE0C16005C2102 /* SqViewBitmapConversion.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SqViewBitmapConversion.h; path = vm/OSX/SqViewBitmapConversion.h; sourceTree = "<group>"; };
@@ -773,6 +775,7 @@
  9452D5EF0E044AC2000AD792 /* Common */ = {
  isa = PBXGroup;
  children = (
+ 731F205D1C0CDE2300A27A22 /* version.c */,
  29B97316FDCFA39411CA2CEA /* main.m */,
  9478E0220EC8D957007096A7 /* plugins */,
  9452D5F00E044AD1000AD792 /* Classes */,
@@ -1759,6 +1762,7 @@
  9463C1D71AEE1693009C5CE5 /* study.c in Sources */,
  94584FDB10F02378001401E7 /* sqMacExtendedClipboard.m in Sources */,
  943B9CA11235C5120056205E /* sqMacHostWindow.m in Sources */,
+ 731F205E1C0CDE2300A27A22 /* version.c in Sources */,
  );
  runOnlyForDeploymentPostprocessing = 0;
  };

Modified: branches/Cog/build.macos32x86/squeak.cog.spur/makeiosvm
===================================================================
--- branches/Cog/build.macos32x86/squeak.cog.spur/makeiosvm 2015-11-26 21:16:03 UTC (rev 3507)
+++ branches/Cog/build.macos32x86/squeak.cog.spur/makeiosvm 2015-11-30 20:14:11 UTC (rev 3508)
@@ -62,9 +62,9 @@
 export TZ="`date +%Z`"
 xcodebuild -project $VMXCP.xcodeproj -configuration $BUILD_CONFIGURATION
 if [ -d "$DEST" ]; then
- mv build/$BUILD_CONFIGURATION/$APP/* "$DEST"
+ cp -Rp build/$BUILD_CONFIGURATION/$APP/* "$DEST"
 else
- mv build/$BUILD_CONFIGURATION/$APP "$DEST"
+ cp -Rp build/$BUILD_CONFIGURATION/$APP "$DEST"
 fi
 ../../scripts/versionInfoPlist ../../platforms CoreVM.plist "$DEST/Contents/Info.plist"
 


Property changes on: branches/Cog/platforms/Cross/vm/sqSCCSVersion.h
___________________________________________________________________
Modified: checkindate
   - Tue Nov 24 15:09:27 PST 2015
   + Mon Nov 30 12:12:08 PST 2015

Modified: branches/Cog/platforms/Mac OS/vm/sqMacUnixCommandLineInterface.c
===================================================================
--- branches/Cog/platforms/Mac OS/vm/sqMacUnixCommandLineInterface.c 2015-11-26 21:16:03 UTC (rev 3507)
+++ branches/Cog/platforms/Mac OS/vm/sqMacUnixCommandLineInterface.c 2015-11-30 20:14:11 UTC (rev 3508)
@@ -355,7 +355,11 @@
 
 static void printUsageNotes(void)
 {
-  printf("  If `-memory' is not specified then the heap will grow dynamically.\n");
+#if SPURVM
+ printf("  If `-memory' or '-maxoldspace' are not specified then the heap will grow dynamically.\n");
+#else
+ printf("  If `-memory' is not specified then the heap will grow dynamically.\n");
+#endif
   printf("  <argument>s are ignored, but are processed by the " IMAGE_DIALECT_NAME " image.\n");
   printf("  The first <argument> normally names a " IMAGE_DIALECT_NAME " `script' to execute.\n");
   printf("  Precede <arguments> by `--' to use default image.\n");

Modified: branches/Cog/platforms/iOS/vm/Common/Classes/sqSqueakMainApp.m
===================================================================
--- branches/Cog/platforms/iOS/vm/Common/Classes/sqSqueakMainApp.m 2015-11-26 21:16:03 UTC (rev 3507)
+++ branches/Cog/platforms/iOS/vm/Common/Classes/sqSqueakMainApp.m 2015-11-30 20:14:11 UTC (rev 3508)
@@ -21,10 +21,10 @@
  copies of the Software, and to permit persons to whom the
  Software is furnished to do so, subject to the following
  conditions:
-
+
  The above copyright notice and this permission notice shall be
  included in all copies or substantial portions of the Software.
-
+
  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
  EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
  OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
@@ -48,7 +48,7 @@
 #import <limits.h>
 #import "sqPlatformSpecific.h"
 
-#if COGVM
+#if STACKVM || COGVM
 #import "sqSCCSVersion.h"
 #else
 #import "sqMacV2Memory.h"
@@ -60,25 +60,34 @@
 #endif
 
 
-#warning what about these guyes?
+#ifdef BUILD_FOR_OSX
 /*** Variables -- globals for access from pluggable primitives ***/
 EXPORT(int) argCnt= 0;
 EXPORT(char**) argVec= 0;
 EXPORT(char**) envVec= 0;
+#endif
 
 extern sqSqueakAppDelegate *gDelegateApp;
 
 BOOL gQuitNowRightNow=NO;
 BOOL            gSqueakHeadless=NO;
+BOOL            gNoSignalHandlers=NO;
 int gSqueakUseFileMappedMMAP=0;
 char            gSqueakUntrustedDirectoryName[PATH_MAX];
 char            gSqueakTrustedDirectoryName[PATH_MAX];
+int blockOnError=0;
 
 extern sqInt printAllStacks(void);
 extern sqInt printCallStack(void);
 extern void dumpPrimTraceLog(void);
 extern BOOL NSApplicationLoad(void);
+extern void pushOutputFile(char *);
+extern void popOutputFile(void);
 
+static void reportStackState(char *, char *, int, ucontext_t *);
+static void block();
+static void *printRegisterState(ucontext_t *);
+
 /* Print an error message, possibly a stack trace, and exit. */
 /* Disable Intel compiler inlining of error which is used for breakpoints */
 #pragma auto_inline off
@@ -86,33 +95,26 @@
 void
 error(char *msg)
 {
- /* flag prevents recursive error when trying to print a broken stack */
- static sqInt printingStack = false;
-
- printf("\n%s\n\n", msg);
-
- if (ioOSThreadsEqual(ioCurrentOSThread(),getVMOSThread())) {
- if (!printingStack) {
- printingStack = true;
- printf("\n\nSmalltalk stack dump:\n");
- printCallStack();
- }
- }
- else
- printf("\nCan't dump Smalltalk stack. Not in VM thread\n");
- printf("\nMost recent primitives\n");
-# if COGVM
-    dumpPrimTraceLog();
-# endif
+ reportStackState(msg,0,0,0);
+ if (blockOnError) block();
  abort();
 }
 #pragma auto_inline on
 
-/*
- * Signal handlers
- *
- */
+static void
+block()
+{ struct timespec while_away_the_hours;
+  char pwd[PATH_MAX+1];
 
+ printf("blocking e.g. to allow attaching debugger\n");
+ printf("pid: %d pwd: %s vm:%s\n",
+ (int)getpid(), getcwd(pwd,PATH_MAX+1), argVec[0]);
+ while (1) {
+ while_away_the_hours.tv_sec = 3600;
+ nanosleep(&while_away_the_hours, 0);
+ }
+}
+
 /* Print an error message, possibly a stack trace, do /not/ exit.
  * Allows e.g. writing to a log file and stderr.
  */
@@ -125,28 +127,43 @@
 # endif
  /* flag prevents recursive error when trying to print a broken stack */
  static sqInt printingStack = false;
-    
+
  printf("\n%s%s%s\n\n", msg, date ? " " : "", date ? date : "");
 # if COGVM
     printf("%s\n\n", sourceVersionString('\n'));
 # endif
-    
+
 # if !defined(NOEXECINFO)
- printf("C stack backtrace:\n");
+ printf("C stack backtrace & registers:\n");
+ if (uap) {
+ addrs[0] = printRegisterState(uap);
+ depth = 1 + backtrace(addrs + 1, BACKTRACE_DEPTH);
+ }
+ else
+ depth = backtrace(addrs, BACKTRACE_DEPTH);
+# if 1 /* Mac OS's backtrace_symbols_fd prints NULL byte droppings each line */
  fflush(stdout); /* backtrace_symbols_fd uses unbuffered i/o */
- depth = backtrace(addrs, BACKTRACE_DEPTH);
  backtrace_symbols_fd(addrs, depth, fileno(stdout));
+# else
+ { int i; char **strings;
+  strings = backtrace_symbols(addrs, depth);
+  printf("(%s)\n", strings[0]);
+  for (i = 1; i < depth; i++)
+ printf("%s\n", strings[i]);
+ }
+# endif
 # endif
-    
+
  if (ioOSThreadsEqual(ioCurrentOSThread(),getVMOSThread())) {
  if (!printingStack) {
 # if COGVM
- /* If we're in generated machine code then the only way the stack
- * dump machinery has of giving us an accurate report is if we set
- * stackPointer & framePointer to the native stack & frame pointers.
- */
+ /* If we're in generated machine code then the only way the stack
+ * dump machinery has of giving us an accurate report is if we set
+ * stackPointer & framePointer to the native stack & frame pointers.
+ */
+ extern void ifValidWriteBackStackPointersSaveTo(void*,void*,char**,char**);
 # if __APPLE__ && __MACH__ && __i386__
-            /* see sys/ucontext.h; two different namings */
+ /* see sys/ucontext.h; two different namings */
 # if __GNUC__ && !__INTEL_COMPILER /* icc pretends to be gcc */
  void *fp = (void *)(uap ? uap->uc_mcontext->__ss.__ebp: 0);
  void *sp = (void *)(uap ? uap->uc_mcontext->__ss.__esp: 0);
@@ -161,10 +178,10 @@
 # error need to implement extracting pc from a ucontext_t on this system
 # endif
  char *savedSP, *savedFP;
-            
+
  ifValidWriteBackStackPointersSaveTo(fp,sp,&savedFP,&savedSP);
 # endif
-            
+
  printingStack = true;
  if (printAll) {
  printf("\n\nAll Smalltalk process stacks (active first):\n");
@@ -186,21 +203,57 @@
 # if STACKVM
  printf("\nMost recent primitives\n");
  dumpPrimTraceLog();
+# if COGVM
+ printf("\n");
+ reportMinimumUnusedHeadroom();
+# endif
 # endif
  printf("\n\t(%s)\n", msg);
  fflush(stdout);
 }
 
+/* Attempt to dump the registers to stdout.  Only do so if we know how. */
+static void *
+printRegisterState(ucontext_t *uap)
+{
+#if __DARWIN_UNIX03 && __APPLE__ && __MACH__ && __i386__
+ _STRUCT_X86_THREAD_STATE32 *regs = &uap->uc_mcontext->__ss;
+ printf( "\teax 0x%08x ebx 0x%08x ecx 0x%08x edx 0x%08x\n"
+ "\tedi 0x%08x esi 0x%08x ebp 0x%08x esp 0x%08x\n"
+ "\teip 0x%08x\n",
+ regs->__eax, regs->__ebx, regs->__ecx, regs->__edx,
+ regs->__edi, regs->__edi, regs->__ebp, regs->__esp,
+ regs->__eip);
+ return (void *)(regs->__eip);
+#elif __APPLE__ && __MACH__ && __i386__
+ _STRUCT_X86_THREAD_STATE32 *regs = &uap->uc_mcontext->ss;
+ printf( "\teax 0x%08x ebx 0x%08x ecx 0x%08x edx 0x%08x\n"
+ "\tedi 0x%08x esi 0x%08x ebp 0x%08x esp 0x%08x\n"
+ "\teip 0x%08x\n",
+ regs->eax, regs->ebx, regs->ecx, regs->edx,
+ regs->edi, regs->edi, regs->ebp, regs->esp,
+ regs->eip);
+ return (void *)(regs->eip);
+#else
+ printf("don't know how to derive register state from a ucontext_t on this platform\n");
+ return 0;
+#endif
+}
 static void
 getCrashDumpFilenameInto(char *buf)
 {
     char *slash;
-    
+
     strcpy(buf,imageName);
     slash = strrchr(buf,'/');
     strcpy(slash ? slash + 1 : buf, "crash.dmp");
 }
 
+/*
+ * Signal handlers
+ *
+ */
+
 void
 sigusr1(int sig, siginfo_t *info, void *uap)
 {
@@ -208,21 +261,20 @@
  time_t now = time(NULL);
  char ctimebuf[32];
  char crashdump[imageNameSize()+1];
- unsigned long pc;
-    
+
  if (!ioOSThreadsEqual(ioCurrentOSThread(),getVMOSThread())) {
  pthread_kill(getVMOSThread(),sig);
  errno = saved_errno;
  return;
  }
-    
+
  getCrashDumpFilenameInto(crashdump);
  ctime_r(&now,ctimebuf);
  pushOutputFile(crashdump);
  reportStackState("SIGUSR1", ctimebuf, 1, uap);
  popOutputFile();
  reportStackState("SIGUSR1", ctimebuf, 1, uap);
-    
+
  errno = saved_errno;
 }
 
@@ -232,7 +284,7 @@
  time_t now = time(NULL);
  char ctimebuf[32];
  char crashdump[imageNameSize()+1];
-    
+
  getCrashDumpFilenameInto(crashdump);
  ctime_r(&now,ctimebuf);
  pushOutputFile(crashdump);
@@ -245,10 +297,10 @@
 void
 sigsegv(int sig, siginfo_t *info, void *uap)
 {
-    
+
     /* error("Segmentation fault"); */
     static int printingStack= 0;
-    
+
     printf("\nSegmentation fault\n\ns");
     if (!printingStack) {
         printingStack= 1;
@@ -267,12 +319,14 @@
 attachToSignals() {
 #if COGVM
  struct sigaction sigusr1_handler_action, sigsegv_handler_action;
-        
+
+ if (gNoSignalHandlers) return;
+
     sigsegv_handler_action.sa_sigaction = sigsegv;
     sigsegv_handler_action.sa_flags = SA_NODEFER | SA_SIGINFO;
     sigemptyset(&sigsegv_handler_action.sa_mask);
     (void)sigaction(SIGSEGV, &sigsegv_handler_action, 0);
-        
+
     sigusr1_handler_action.sa_sigaction = sigusr1;
     sigusr1_handler_action.sa_flags = SA_NODEFER | SA_SIGINFO;
     sigemptyset(&sigusr1_handler_action.sa_mask);
@@ -306,7 +360,7 @@
  * a) Answer whether the C frame pointer is in use, for capture of the C stack
  *    pointers.
  */
-# if defined(i386) || defined(__i386) || defined(__i386__)
+
 /*
  * Cog has already captured CStackPointer  before calling this routine.  Record
  * the original value, capture the pointers again and determine if CFramePointer
@@ -320,13 +374,12 @@
  extern unsigned long CStackPointer, CFramePointer;
  extern void (*ceCaptureCStackPointers)(void);
  unsigned long currentCSP = CStackPointer;
-
+
  currentCSP = CStackPointer;
  ceCaptureCStackPointers();
  assert(CStackPointer < currentCSP);
  return CFramePointer >= CStackPointer && CFramePointer <= currentCSP;
 }
-# endif /* defined(i386) || defined(__i386) || defined(__i386__) */
 
 
 /* Answer an approximation of the size of the redzone (if any).  Do so by
@@ -341,7 +394,7 @@
 static char *p = 0;
 
 static void
-sighandler(int sig) { p = (char *)&sig; }
+sighandler(int sig, siginfo_t *info, void *uap) { p = (char *)&sig; }
 
 static int
 getRedzoneSize()

Modified: branches/Cog/platforms/iOS/vm/Common/main.m
===================================================================
--- branches/Cog/platforms/iOS/vm/Common/main.m 2015-11-26 21:16:03 UTC (rev 3507)
+++ branches/Cog/platforms/iOS/vm/Common/main.m 2015-11-30 20:14:11 UTC (rev 3508)
@@ -46,7 +46,7 @@
  extern char **envVec;
 
  argCnt = argc;
- argVec= argv;
+ argVec = argv;
  envVec = envp;
 
     return NSApplicationMain(argc,  (const char **) argv);

Copied: branches/Cog/platforms/iOS/vm/Common/version.c (from rev 3503, branches/Cog/platforms/Mac OS/vm/version.c)
===================================================================
--- branches/Cog/platforms/iOS/vm/Common/version.c                        (rev 0)
+++ branches/Cog/platforms/iOS/vm/Common/version.c 2015-11-30 20:14:11 UTC (rev 3508)
@@ -0,0 +1,15 @@
+#if !defined __VERSION__
+# define __VERSION__ "Unknown"
+#endif
+
+#if !defined(TZ)
+# define TZ ""
+# define SPACER ""
+#else
+# define SPACER " "
+#endif
+
+char vmBuildString[] = \
+ "Mac OS X built on " \
+ __DATE__" "__TIME__ SPACER TZ \
+ " Compiler: " __VERSION__;

Modified: branches/Cog/platforms/iOS/vm/OSX/sqSqueakOSXApplication+attributes.m
===================================================================
--- branches/Cog/platforms/iOS/vm/OSX/sqSqueakOSXApplication+attributes.m 2015-11-26 21:16:03 UTC (rev 3507)
+++ branches/Cog/platforms/iOS/vm/OSX/sqSqueakOSXApplication+attributes.m 2015-11-30 20:14:11 UTC (rev 3508)
@@ -15,10 +15,10 @@
  copies of the Software, and to permit persons to whom the
  Software is furnished to do so, subject to the following
  conditions:
-
+
  The above copyright notice and this permission notice shall be
  included in all copies or substantial portions of the Software.
-
+
  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
  EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
  OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
@@ -27,7 +27,7 @@
  WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
  FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
  OTHER DEALINGS IN THE SOFTWARE.
-
+
  The end-user documentation included with the redistribution, if any, must include the following acknowledgment:
  "This product includes software developed by Corporate Smalltalk Consulting Ltd (http://www.smalltalkconsulting.com)
  and its contributors", in the same place and form as other third-party acknowledgments.
@@ -48,107 +48,73 @@
  //indexNumber is a postive/negative number
 #warning to test
  switch (indexNumber) {
-        case 1001: /* OS type: "unix", "win32", "mac", ... */
- return "Mac OS";
-
- case 1002:  { /* OS name: "solaris2.5" on unix, "win95" on win32, ... */
- SInt32 myattr;
- static char data[32];
-
- Gestalt(gestaltSystemVersion, &myattr);
- sprintf(data,"%X",(unsigned int) myattr);
- return data;
+ case 1001: /* OS type: "unix", "win32", "mac", ... */
+ return "Mac OS";
+
+ case 1002:  { /* OS name: "solaris2.5" on unix, "win95" on win32, ... */
+ SInt32 myattr;
+ static char data[32];
+
+ Gestalt(gestaltSystemVersion, &myattr);
+ sprintf(data,"%X",(unsigned int) myattr);
+ return data;
+ }
+ case 1003: { /* processor architecture: "68k", "x86", "PowerPC", ...  */
+ SInt32 myattr;
+
+ Gestalt(gestaltSysArchitecture, &myattr);
+ if (myattr == gestalt68k)
+ return "68K";
+ if (myattr == gestaltPowerPC)
+ return "powerpc";
+ if (myattr == gestaltIntel)
+ return "intel";
+
+ return "unknown";
+ }
+
+#if 0 /* see iOS/vm/Common/Classes/sqSqueakMainApplication+attributes.m */
+   if (id == 1004) {
+ CFBundleRef mainBundle;
+ CFStringRef versionString;
+ static char data[255];
+ mainBundle = CFBundleGetMainBundle ();
+ versionString = CFBundleGetValueForInfoDictionaryKey(mainBundle, CFSTR("CFBundleShortVersionString"));
+ bzero(data,255);
+ strcat(data,interpreterVersion);
+ if (versionString) {
+ strcat(data," ");
+ CFStringGetCString (versionString, data+strlen(data), 255-strlen(data), gCurrentVMEncoding);
  }
- case 1003: { /* processor architecture: "68k", "x86", "PowerPC", ...  */
- SInt32 myattr;
-
- Gestalt(gestaltSysArchitecture, &myattr);
- if (myattr == gestalt68k)
- return "68K";
- if (myattr == gestaltPowerPC)
- return "powerpc";
- if (myattr == gestaltIntel)
- return "intel";
-
- return "unknown";
- }
-
- case 1005: {
- return "Aqua";
- }
-
-
- case 1006:  {/* vm build string also info.plist */
-#if (SQ_VI_BYTES_PER_WORD == 4)
-
-#if STACKVM
-
- return "Mac Cocoa Cog 5.8b12 21-Sep-10 >1B0534FA-246C-47C5-AB29-7A76C81CCDCB<";
-// return "Mac Cocoa Cog 5.8b11 12-Sep-10 >9BFC792A-F173-4C65-AD2A-FFFB1D52DAC2<";
-// return "Mac Cocoa Cog 5.8b10 07-Sep-10 >8AD3A516-DBAC-4CD4-BC89-8F21317DF7E1<";
-// return "Mac Cocoa Cog 5.8b9 06-Sep-10 >01641B99-1842-4422-A99D-43153BEDEFFA<";
-// return "Mac Cocoa Cog 5.8b8 04-Sep-10 >8A66B7E0-B578-4E5F-97B4-6195547A35F5<";
-// return "Mac Cocoa Cog 5.8b7 02-Sep-10 >4EBF00E3-453E-4010-9AC8-6B64C292984B<";
-// return "Mac Cocoa Cog 5.8b6 31-Aug-10 >DFB49E57-40FB-44B9-97D3-B7CA51608429<";
-// return "Mac Cocoa Cog 5.8b5 30-Aug-10 >0A92B82A-9AC1-4B0E-9DEE-440C3FFAE568<";
-// return "Mac Cocoa Cog 5.8b4 27-Aug-10 >5954D562-FB39-4195-9D19-EBB49FAECCF7<";
-// return "Mac Cocoa Cog 5.8b3 21-Aug-10 >5954D562-FB39-4195-9D19-EBB49FAECCF7<";
-// return "Mac Cocoa Cog 5.8b2 08-Jul-10 >7BCAB029-A835-4D12-946D-4AB7083D2955<";
-// return "Mac Cocoa Cog 5.8b1 07-Jul-10 >529F6B5A-DC81-4C1F-81B6-3D99741B954A<";
-#else
- return "Mac Cocoa 5.7b3 27-Aug-10 >7BCAB029-A835-4D12-946D-4AB7083D2955<";
-// return "Mac Cocoa 5.7b2 08-Jul-10 >7BCAB029-A835-4D12-946D-4AB7083D2955<";
-// return "Mac Cocoa 5.7b1 15-Jun-10 >34286DE5-3BD3-40D8-9700-4C41C772B16B<";
+ return data;            
+ }
 #endif
-// return "Mac Cocoa 5.7b1 15-Jun-10 >34286DE5-3BD3-40D8-9700-4C41C772B16B<";
-// return "Mac Cocoa 5.6b1 02-Mar-10 >9E99B1C2-0B6B-4944-8B6F-74030D14F3C6<";
-// return "Mac Cocoa 5.5b1 16-Feb-10 >2EE2964B-462A-4F66-92AF-C810216EF798<";
-// return "Mac Cocoa 5.4b2 24-Jan-10 >2EE2964B-462A-4F66-92AF-C810216EF798<";
-// return "Mac Cocoa 5.4b1 20-Jan-10 >F0EB07E3-7805-4C09-8419-D8316F7ADC21<";
-// return "Mac Cocoa 5.3b1 06-Jan-10 >0DADC752-8E86-48FC-8D6B-CC97482C6851<";
-// return "Mac Cocoa 5.2b3 05-Jan-10 >1618879A-3D07-427F-A8CB-5B3DF73ED840<";
-// return "Mac Cocoa 5.2b2 04-Jan-10 >94E27C49-8575-4604-A2C4-0A5C659CC734<";
-// return "Mac Cocoa 5.2b1 02-Jan-10 >D94A0034-7415-4AA1-AA7C-B35BBCDBA0D4<";
-// return "Mac Cocoa 5.1b1 25-Dec-09 >C0908D0B-4D97-47CA-9FAB-479AFC6BA978<";
-// return "Mac Cocoa 5.0b9 02-Dec-09 >C8598ABA-DA73-4A71-836C-62C4369D5A0F<";
-#else
- return "Mac Cocoa 5.7b2 64/64 bits 08-Jul-10 >7BCAB029-A835-4D12-946D-4AB7083D2955<";
-// return "Mac Cocoa 5.7b1 64/64 bits 15-Jun-10 >34286DE5-3BD3-40D8-9700-4C41C772B16B<";
-// return "Mac Cocoa 5.6b1 64/64 bits 02-Mar-10 >9E99B1C2-0B6B-4944-8B6F-74030D14F3C6<";
-// return "Mac Cocoa 5.5b1 64/64 bits 16-Feb-10 >70984CDA-9482-4E7F-BCF0-08C635E0A7BF<";
-// return "Mac Cocoa 5.4b2 64/64 bits 24-Jan-10 >70984CDA-9482-4E7F-BCF0-08C635E0A7BF<";
-// return "Mac Cocoa 5.4b1 64/64 bits 20-Jan-10 >E27846BC-15A7-4BE8-B467-B645E9D37163<";
-// return "Mac Cocoa 5.3b1 64/64 bits 06-Jan-10 >0DADC752-8E86-48FC-8D6B-CC97482C6851<";
-// return "Mac Cocoa 5.2b3 64/64 bits 05-Jan-10 >1618879A-3D07-427F-A8CB-5B3DF73ED840<";
-// return "Mac Cocoa 5.2b2 64/64 bits 04-Jan-10 >94E27C49-8575-4604-A2C4-0A5C659CC734<";
-// return "Mac Cocoa 5.2b1 64/64 bits 02-Jan-10 >D94A0034-7415-4AA1-AA7C-B35BBCDBA0D4<";
-// return "Mac Cocoa 5.1b1 64/64 bits 25-Dec-09 >C0908D0B-4D97-47CA-9FAB-479AFC6BA978<";
-// return "Mac Cocoa 5.0b9 64/64 bits 02-Dec-09 >C8598ABA-DA73-4A71-836C-62C4369D5A0F<";
-// return "Mac Cocoa 5.0b8 01-Dec-09 >2329A610-327B-403D-960E-EEF3C369D032<";
-// return "Mac Cocoa 5.0b7 29-Nov-09 >1215B15B-9463-4D53-BA13-AA989DAB5C01<";
-// return "Mac Cocoa 5.0b6 27-Nov-09 >CF087523-A432-4427-9AD3-4ACF26336A08<";
-// return "Mac Cocoa 5.0b5 26-Nov-09 >9C6EF973-CECF-4E38-B5E0-BB9986A03D5D<";
-// return "Mac Cocoa 5.0b4 26-Nov-09 >DA33132E-D7E6-48C4-8363-EB7408E3124B<";
-// return "Mac Cocoa 5.0.0b1 11-Nov-09 >40BF8061-CC65-4E5E-9841-6BB5E809A688<";
-#endif
- }
- case 1007: { /* vm build string also info.plist */
+
+ case 1005: {
+ return "Aqua";
+ }
+
+ case 1006:  {/* vm build string also info.plist */
+ extern char vmBuildString[];
+ return vmBuildString;
+ }
+ case 1007: { /* vm build string also info.plist */
 #if STACKVM
- extern char *__interpBuildInfo;
- return __interpBuildInfo;
+ extern char *__interpBuildInfo;
+ return __interpBuildInfo;
 #endif
- break;
- }
- case 1008: { /* vm build string also info.plist */
+ break;
+ }
+ case 1008: { /* vm build string also info.plist */
 # if COGVM
- extern char *__cogitBuildInfo;
- return __cogitBuildInfo;
+ extern char *__cogitBuildInfo;
+ return __cogitBuildInfo;
 #endif
- break;
- }
- default:
- break;
+ break;
  }
+ default:
+ break;
+ }
  return (char *) [super getAttribute: indexNumber];
 }
 @end

Modified: branches/Cog/platforms/iOS/vm/OSX/sqSqueakOSXApplication.h
===================================================================
--- branches/Cog/platforms/iOS/vm/OSX/sqSqueakOSXApplication.h 2015-11-26 21:16:03 UTC (rev 3507)
+++ branches/Cog/platforms/iOS/vm/OSX/sqSqueakOSXApplication.h 2015-11-30 20:14:11 UTC (rev 3508)
@@ -47,7 +47,7 @@
 @property (nonatomic,strong) NSCursor *squeakCursor;
 @property (nonatomic,assign) BOOL squeakHasCursor;
 
-- (NSInteger) parseArgument: (NSString *) argData peek: (NSString *) peek;
+- (NSInteger) parseArgument: (NSString *) argData peek: (char *) peek;
 - (void) parseArgs: (NSArray *) args;
 - (void) parseEnv: (NSDictionary *) env;
 - (long long) strtobkm: (const char *) chr;

Modified: branches/Cog/platforms/iOS/vm/OSX/sqSqueakOSXApplication.m
===================================================================
--- branches/Cog/platforms/iOS/vm/OSX/sqSqueakOSXApplication.m 2015-11-26 21:16:03 UTC (rev 3507)
+++ branches/Cog/platforms/iOS/vm/OSX/sqSqueakOSXApplication.m 2015-11-30 20:14:11 UTC (rev 3508)
@@ -36,6 +36,7 @@
  */
 //
 
+#include "sqSCCSVersion.h"
 
 #import "sqSqueakOSXApplication.h"
 #import "sqSqueakOSXFileDirectoryInterface.h"
@@ -43,6 +44,7 @@
 #import "sqSqueakOSXSoundCoreAudio.h"
 #import "sqSqueakSoundCoreAudioAPI.h"
 #import "sqSqueakOSXApplication+imageReadWrite.h"
+#import "sqSqueakOSXApplication+attributes.h"
 
 #if !defined(IMAGE_DIALECT_NAME)
 # if NewspeakVM
@@ -56,7 +58,7 @@
 # endif
 #endif
 
-usqInt gMaxHeapSize=(512*1024*1024)+(4*1024*1024); //Last part are "eden bytes" needed in the new startup
+usqInt gMaxHeapSize = 512*1024*1024;
 
 #if defined(__GNUC__) && ( defined(i386) || defined(__i386) || defined(__i386__)  \
 || defined(i486) || defined(__i486) || defined (__i486__) \
@@ -83,6 +85,7 @@
 # define mtfsfi(fpscr)
 #endif
 
+static char *getVersionInfo(int verbose);
 
 @implementation sqSqueakOSXApplication
 @synthesize squeakHasCursor,squeakCursor;
@@ -130,9 +133,9 @@
  [(sqSqueakOSXSoundCoreAudio *) self.soundInterfaceLogic soundInitOverride];
 
  snd_Start(2644, 22050, 1, 0);
- char slience[10576];
- bzero(&slience, sizeof(slience));
- snd_PlaySamplesFromAtLength(2644,(usqInt * ) &slience,0);
+ char silence[10576];
+ bzero(&silence, sizeof(silence));
+ snd_PlaySamplesFromAtLength(2644,(usqInt * ) &silence,0);
  [self.soundInterfaceLogic snd_Stop_Force];
 }
 
@@ -142,67 +145,217 @@
  [self parseEnv: [p environment]];
 }
 
-- (void) attachToSignals {
-    if (![self noHandlers]) {
-        attachToSignals();
-    }
-}
+- (int) parseArgument: (NSString *) argData peek: (char *) peek
+{
 
-- (NSInteger) parseArgument: (NSString *) argData peek: (NSString *) peek {
-
  if ([argData isEqualToString: @"--"]) {
  return 1;
  }
 
+ /* Options with no arguments */
+
  NS_DURING;
  if ([argData compare:  @"-psn_" options: NSLiteralSearch range: NSMakeRange(0,5)] == NSOrderedSame) {
  return 1;
  }
  NS_HANDLER;
  NS_ENDHANDLER;
-
+
  if ([argData isEqualToString: @"-help"]) {
  [self usage];
  exit(0);
  return 1;
  }
+ if ([argData isEqualToString: @"-version"]) {
+ printf("%s\n", getVersionInfo(0));
+ exit(0);
+ return 1;
+ }
+ if ([argData isEqualToString: @"-blockonerror"]) {
+ extern int blockOnError;
+ blockOnError = true;
+ return 1;
+ }
+ if ([argData isEqualToString: @"-blockonwarn"]) {
+ extern int blockOnError;
+ extern sqInt erroronwarn;
+ erroronwarn = blockOnError = true;
+ return 1;
+ }
+ if ([argData isEqualToString: @"-exitonwarn"]) {
+ extern sqInt erroronwarn;
+ erroronwarn = true;
+ return 1;
+ }
  if ([argData isEqualToString: @"-headless"]) {
  extern BOOL gSqueakHeadless;
  gSqueakHeadless = YES;
  return 1;
  }
-
-    if ([argData compare: @"--nohandlers"] == NSOrderedSame){
-        [self setNoHandlers: YES];
+ if ([argData isEqualToString: @"-headfull"]) {
+ extern BOOL gSqueakHeadless;
+ gSqueakHeadless = NO;
+ return 1;
+ }
+    if ([argData isEqualToString: @"-nohandlers"]) {
+ extern BOOL gNoSignalHandlers;
+        gNoSignalHandlers = YES;
         return 1;
     }
+ if ([argData isEqualToString: @"-timephases"]) {
+ extern void printPhaseTime(int);
+ printPhaseTime(1);
+ return 1;
+ }
+#if COGVM
+ if ([argData compare:  @"-trace" options: NSLiteralSearch range: NSMakeRange(0,6)] == NSOrderedSame) {
+ extern int traceFlags;
 
+ if ([argData length] == 6) {
+ traceFlags = 1;
+ return 1;
+ }
+ if ([argData length] <= 7
+ || [argData characterAtIndex: 6] != '='
+ || !isdigit([argData characterAtIndex: 7]))
+ return 0;
+
+ traceFlags = atoi([argData UTF8String] + 7);
+ return 1;
+ }
+ if ([argData isEqualToString: @"-tracestores"]) {
+ extern sqInt traceStores;
+ traceStores = 1;
+ return 1;
+ }
+#endif
+#if STACKVM
+ if ([argData isEqualToString: @"-checkpluginwrites"]) {
+ extern sqInt checkAllocFiller;
+ checkAllocFiller = 1;
+ return 1;
+ }
+ if ([argData isEqualToString: @"-noheartbeat"]) {
+ extern sqInt suppressHeartbeatFlag;
+ suppressHeartbeatFlag = 1;
+ return 1;
+ }
+ if ([argData isEqualToString: @"-warnpid"]) {
+ extern sqInt warnpid;
+ warnpid = getpid();
+ return 1;
+ }
+ if ([argData isEqualToString: @"-reportheadroom"]
+ || [argData isEqualToString: @"-rh"]) {
+ extern sqInt reportStackHeadroom;
+ reportStackHeadroom = 1;
+ return 1;
+ }
+#endif
+
+ /* Options with arguments */
+ if (!peek)
+ return 0;
+
  if ([argData isEqualToString: @"-memory"]) {
- gMaxHeapSize = (usqInt) [self strtobkm: [peek UTF8String]];
+ gMaxHeapSize = (usqInt) [self strtobkm: peek];
  return 2;
  }
     
     if ([argData isEqualToString: @"-NSDocumentRevisionsDebugMode"]) {
         return 2;
     }
-    
+
+#if STACKVM || NewspeakVM
+ if ([argData isEqualToString: @"-breaksel"]) {
+ extern void setBreakSelector(char *);
+ setBreakSelector(peek);
+ return 2;
+ }
+#endif
+#if STACKVM
+ if ([argData isEqualToString: @"-breakmnu"]) {
+ extern void setBreakMNUSelector(char *);
+ setBreakMNUSelector(peek);
+ return 2;
+ }
+ if ([argData isEqualToString: @"-eden"]) {
+ extern sqInt desiredEdenBytes;
+ desiredEdenBytes = [self strtobkm: peek];
+ return 2;
+ }
+ if ([argData isEqualToString: @"-leakcheck"]) {
+ extern sqInt checkForLeaks;
+ checkForLeaks = atoi(peek);
+ return 2;
+ }
+ if ([argData isEqualToString: @"-stackpages"]) {
+ extern sqInt desiredNumStackPages;
+ desiredNumStackPages = atoi(peek);
+ return 2;
+ }
+ if ([argData isEqualToString: @"-numextsems"]) {
+ ioSetMaxExtSemTableSize(atoi(peek));
+ return 2;
+ }
+ if ([argData isEqualToString: @"-pollpip"]) {
+ extern sqInt pollpip;
+ pollpip = atoi(peek);
+ return 2;
+ }
+#endif /* STACKVM */
+#if COGVM
+ if ([argData isEqualToString: @"-codesize"]) {
+ extern sqInt desiredCogCodeSize;
+ desiredCogCodeSize = [self strtobkm: peek];
+ return 2;
+ }
+ if ([argData isEqualToString: @"-dpcso"]) {
+ extern unsigned long debugPrimCallStackOffset;
+ debugPrimCallStackOffset = (unsigned long)[self strtobkm: peek];
+ return 2;
+ }
+ if ([argData isEqualToString: @"-cogmaxlits"]) {
+ extern sqInt maxLiteralCountForCompile;
+ maxLiteralCountForCompile = [self strtobkm: peek];
+ return 2;
+ }
+ if ([argData isEqualToString: @"-cogminjumps"]) {
+ extern sqInt minBackwardJumpCountForCompile;
+ minBackwardJumpCountForCompile = [self strtobkm: peek];
+ return 2;
+ }
+#endif /* COGVM */
+#if SPURVM
+ if ([argData isEqualToString: @"-maxoldspace"]) {
+ extern unsigned long maxOldSpaceSize;
+ maxOldSpaceSize = (unsigned long)[self strtobkm: peek];
+ return 2;
+ }
+#endif
+#if 0 /* Not sure if encoding is an issue with the Cocoa VM. eem 2015-11-30 */
+ if ([argData isEqualToString: @"-pathenc"]) {
+ setEncodingType(peek);
+ return 2;
+ }
+#endif
  return 0;
 }
 
+
 - (void) parseArgs: (NSArray *) args {
  commandLineArguments = [args copyWithZone:null];
  argsArguments = [[NSMutableArray alloc] initWithCapacity: [args count]];
-
+
  if ([args count] < 2)
  return;
  NSMutableArray *revisedArgs = AUTORELEASEOBJ([args mutableCopyWithZone: NULL]);
  [revisedArgs removeObjectAtIndex:0];
-
- NSUInteger i,result;
+
+ int i;
  BOOL optionsCompleted = NO;
- for (i=0; i<[revisedArgs count]; i++) {
+ for (i = 0; i < [revisedArgs count]; i++) {
  NSString *argData = revisedArgs[i];
- NSString *peek = (i == ([revisedArgs count] - 1)) ? @"" : revisedArgs[i+1];
  if ([argData isEqualToString: @"--"]) {
  optionsCompleted = YES;
  continue;
@@ -210,26 +363,27 @@
  if (!optionsCompleted && ![[argData substringToIndex: 1] isEqualToString: @"-"]) {
  optionsCompleted = YES;
  //guessing first parameter as image name
- if ([argData compare: @"--"] != NSOrderedSame) {
+ if ([argData compare: @"--"] != NSOrderedSame)
                 [self setImageNamePathIfItWasReadable:argData];
- } else {
+ else
  continue;
- }
  continue;
  }
- if (optionsCompleted) {
+ if (optionsCompleted)
  [self.argsArguments addObject: argData];
- } else {
- result = [self parseArgument: argData peek: peek];
- if (result == 0) /* option not recognised */ {
+ else {
+ int result = [self parseArgument: argData
+ peek: (char *)(i >= ([revisedArgs count] - 1)
+ ? 0
+ : [revisedArgs[i+1] UTF8String])];
+ if (result == 0) { /* option not recognised */
  fprintf(stderr, "unknown option: %s\n", [argData UTF8String]);
  [self usage];
  exit(1);
  }
- if (result == 2)
- i++;
+ if (result > 1)
+ i += result - 1;
  }
-
  }
 }
 
@@ -259,27 +413,76 @@
  gMaxHeapSize = (usqInt) [self strtobkm: [memoryString UTF8String]];
  }
 }
-  
+
 - (void) usage {
- printf("Usage: [<option>...] [<imageName> [<argument>...]]\n");
- printf("       [<option>...] -- [<argument>...]\n");
+ extern char **argVec;
+ printf("Usage: %s [<option>...] [<imageName> [<argument>...]]\n", argVec[0]);
+ printf("       %s [<option>...] -- [<argument>...]\n", argVec[0]);
  [self printUsage];
  printf("\nNotes:\n");
- printf("  <imageName> defaults to `%s'.\n", DEFAULT_IMAGE_NAME);
+ //printf("  <imageName> defaults to `%s'.\n", DEFAULT_IMAGE_NAME);
+ printf("  <imageName> defaults to `" DEFAULT_IMAGE_NAME "'.\n");
  [self printUsageNotes];
+ // exit(1);
 }
 
 - (void) printUsage {
  printf("\nCommon <option>s:\n");
- printf("  --help                 print this help message, then exit\n");
- printf("  --memory <size>[mk]    use fixed heap size (added to image size)\n");
- printf("  --headless             run in headless (no window) mode (default: false)\n");
-    printf("  --nohandlers           disable sigsegv & sigusr1 handlers\n");
+ printf("  -help                 print this help message, then exit\n");
+ printf("  -memory <size>[mk]    use fixed heap size (added to image size)\n");
+    printf("  -nohandlers           disable sigsegv & sigusr1 handlers\n");
+ printf("  -timephases           print start load and run times\n");
+#if STACKVM || NewspeakVM
+ printf("  -breaksel selector    set breakpoint on send of selector\n");
+#endif
+#if STACKVM
+ printf("  -breakmnu selector    set breakpoint on MNU of selector\n");
+ printf("  -eden <size>[mk]      set eden memory to bytes\n");
+ printf("  -leakcheck num        check for leaks in the heap\n");
+ printf("  -stackpages num       use n stack pages\n");
+ printf("  -numextsems num       make the external semaphore table num in size\n");
+ printf("  -noheartbeat          disable the heartbeat for VM debugging. disables input\n");
+ printf("  -pollpip              output . on each poll for input\n");
+ printf("  -checkpluginwrites    check for writes past end of object in plugins\n");
+#endif
+#if STACKVM || NewspeakVM
+# if COGVM
+ printf("  -trace[=num]          enable tracing (optionally to a specific value)\n");
+# else
+ printf("  -sendtrace            enable send tracing\n");
+# endif
+ printf("  -warnpid              print pid in warnings\n");
+#endif
+#if COGVM
+ printf("  -codesize <size>[mk]  set machine code memory to bytes\n");
+ printf("  -tracestores          enable store tracing (assert check stores)\n");
+ printf("  -cogmaxlits <n>       set max number of literals for methods to be compiled to machine code\n");
+ printf("  -cogminjumps <n>      set min number of backward jumps for interpreted methods to be considered for compilation to machine code\n");
+ printf("  -reportheadroom       report unused stack headroom on exit\n");
+#endif
+#if SPURVM
+ printf("  -maxoldspace <size>[mk]      set max size of old space memory to bytes\n");
+#endif
+#if 0 /* Not sure if encoding is an issue with the Cocoa VM. eem 2015-11-30 */
+ printf("  -pathenc <enc>        set encoding for pathnames (default: %s)\n",
+ getEncodingType([self currentVMEncoding]));
+#endif
+ printf("  -headless             run in headless (no window) mode (default: false)\n");
+ printf("  -headfull             run in headful (window) mode (default: true)\n");
+ printf("  -version              print version information, then exit\n");
+
+ printf("  -blockonerror         on error or segv block, not exit.  useful for attaching gdb\n");
+ printf("  -blockonwarn          on warning block, don't warn.  useful for attaching gdb\n");
+ printf("  -exitonwarn           treat warnings as errors, exiting on warn\n");
 }
 
 - (void) printUsageNotes
 {
+#if SPURVM
+ printf("  If `-memory' or '-maxoldspace' are not specified then the heap will grow dynamically.\n");
+#else
  printf("  If `-memory' is not specified then the heap will grow dynamically.\n");
+#endif
  printf("  <argument>s are ignored, but are processed by the Squeak image.\n");
  printf("  The first <argument> normally names a Squeak `script' to execute.\n");
  printf("  Precede <arguments> by `--' to use default image.\n");
@@ -289,21 +492,81 @@
 {
  NSFileManager *dfm = [NSFileManager defaultManager];
  BOOL isDirectory;
-
+
  [dfm fileExistsAtPath: filePath isDirectory: &isDirectory];
 
  if (isDirectory)
  return NO;
 
  BOOL fileIsReadable = [[NSFileManager defaultManager] isReadableFileAtPath: filePath];
-
+
  if (fileIsReadable == NO)
  return NO;
 
  if ([[[filePath lastPathComponent] pathExtension] compare: @"image" options: NSCaseInsensitiveSearch] ==   NSOrderedSame)
  return YES;
-
+
  return NO;
 }
 
 @end
+
+static char *
+getVersionInfo(int verbose)
+{
+#if STACKVM
+  extern char *__interpBuildInfo;
+# define INTERP_BUILD __interpBuildInfo
+# if COGVM
+  extern char *__cogitBuildInfo;
+# endif
+#else
+# define INTERP_BUILD interpreterVersion
+#endif
+  extern char vmBuildString[];
+  CFStringRef versionString;
+  char *info= (char *)malloc(4096);
+  info[0]= '\0';
+
+#if SPURVM
+# if BytesPerOop == 8
+# define ObjectMemory " Spur 64-bit"
+# else
+# define ObjectMemory " Spur"
+# endif
+#else
+# define ObjectMemory
+#endif
+#if defined(NDEBUG)
+# define BuildVariant "Production" ObjectMemory
+#elif DEBUGVM
+# define BuildVariant "Debug" ObjectMemory
+# else
+# define BuildVariant "Assert" ObjectMemory
+#endif
+
+  if (verbose)
+    sprintf(info+strlen(info), IMAGE_DIALECT_NAME " VM version: ");
+  sprintf(info+strlen(info), "%s ", VM_VERSION);
+  if ((versionString = CFBundleGetValueForInfoDictionaryKey(
+ CFBundleGetMainBundle(),
+ CFSTR("CFBundleVersion"))))
+#if 0 /* Not sure if encoding is an issue with the Cocoa VM. eem 2015-11-30 */
+    CFStringGetCString(versionString, info+strlen(info), 4095-strlen(info), gCurrentVMEncoding);
+#else
+    CFStringGetCString(versionString, info+strlen(info), 4095-strlen(info), kCFStringEncodingUTF8);
+#endif
+  sprintf(info+strlen(info), " %s [" BuildVariant " VM]\n", vmBuildString);
+  if (verbose)
+    sprintf(info+strlen(info), "Built from: ");
+  sprintf(info+strlen(info), "%s\n", INTERP_BUILD);
+#if COGVM
+  if (verbose)
+    sprintf(info+strlen(info), "With: ");
+  sprintf(info+strlen(info), "%s\n", __cogitBuildInfo); /* __cogitBuildInfo */
+#endif
+  if (verbose)
+    sprintf(info+strlen(info), "Revision: ");
+  sprintf(info+strlen(info), "%s\n", sourceVersionString('\n'));
+  return info;
+}

Modified: branches/Cog/platforms/unix/vm/sqUnixMain.c
===================================================================
--- branches/Cog/platforms/unix/vm/sqUnixMain.c 2015-11-26 21:16:03 UTC (rev 3507)
+++ branches/Cog/platforms/unix/vm/sqUnixMain.c 2015-11-30 20:14:11 UTC (rev 3508)
@@ -1585,7 +1585,11 @@
 
 static void vm_printUsageNotes(void)
 {
-  printf("  If `-memory' is not specified then the heap will grow dynamically.\n");
+#if SPURVM
+ printf("  If `-memory' or '-maxoldspace' are not specified then the heap will grow dynamically.\n");
+#else
+ printf("  If `-memory' is not specified then the heap will grow dynamically.\n");
+#endif
   printf("  <argument>s are ignored, but are processed by the " IMAGE_DIALECT_NAME " image.\n");
   printf("  The first <argument> normally names a " IMAGE_DIALECT_NAME " `script' to execute.\n");
   printf("  Precede <arguments> by `--' to use default image.\n");
@@ -2111,7 +2115,7 @@
  * b) answer the amount of stack room to ensure in a Cog stack page, including
  *    the size of the redzone, if any.
  */
-# if defined(i386) || defined(__i386) || defined(__i386__)
+
 /*
  * Cog has already captured CStackPointer  before calling this routine.  Record
  * the original value, capture the pointers again and determine if CFramePointer
@@ -2131,22 +2135,7 @@
  assert(CStackPointer < currentCSP);
  return CFramePointer >= CStackPointer && CFramePointer <= currentCSP;
 }
-# endif /* defined(i386) || defined(__i386) || defined(__i386__) */
-# if defined(__arm__) || defined(__arm32__) || defined(ARM32)
-/* Currently pretty sure fp is used but prepared to be shown wrong */
- int
-isCFramePointerInUse()
-{
- extern unsigned long CStackPointer, CFramePointer;
- extern void (*ceCaptureCStackPointers)(void);
- unsigned long currentCSP = CStackPointer;
 
- currentCSP = CStackPointer;
- ceCaptureCStackPointers();
- assert(CStackPointer < currentCSP);
- return CFramePointer >= CStackPointer && CFramePointer <= currentCSP;
-}
-#endif /* defined(__arm__) || defined(__arm32__) || defined(ARM32) */
 /* Answer an approximation of the size of the redzone (if any).  Do so by
  * sending a signal to the process and computing the difference between the
  * stack pointer in the signal handler and that in the caller. Assumes stacks
@@ -2159,7 +2148,7 @@
 static char * volatile p = 0;
 
 static void
-sighandler(int sig) { p = (char *)&sig; }
+sighandler(int sig, siginfo_t *info, void *uap) { p = (char *)&sig; }
 
 static int
 getRedzoneSize()