Index: emacs/Makefile.in
===================================================================
RCS file: /cvs/Darwin/src/live/emacs/emacs/Makefile.in,v
retrieving revision 1.1.1.7
retrieving revision 1.7
diff -u -r1.1.1.7 -r1.7
--- Makefile.in	2002/09/10 23:31:56	1.1.1.7
+++ Makefile.in	2002/09/11 01:34:01	1.7
@@ -329,7 +329,6 @@
 	    libexecdir=${libexecdir} archlibdir=${archlibdir} \
 	    INSTALL_STRIP=${INSTALL_STRIP})
 	${INSTALL_PROGRAM} $(INSTALL_STRIP) src/emacs ${bindir}/emacs-${version}
-	-chmod 1755  ${bindir}/emacs-${version}
 	rm -f ${bindir}/$(EMACS)
 	-ln ${bindir}/emacs-${version} ${bindir}/$(EMACS)
 	-unset CDPATH; \
@@ -447,7 +446,7 @@
 	-chmod -R a+r ${datadir}/emacs ${COPYDESTS} ${infodir}
 	thisdir=`/bin/pwd`; \
 	cd ${srcdir}/etc; \
-	for page in emacs etags ctags gfdl ; do \
+	for page in emacs etags gfdl ; do \
 	  (cd $${thisdir}; \
 	   ${INSTALL_DATA} ${srcdir}/etc/$${page}.1 ${man1dir}/$${page}${manext}; \
 	   chmod a+r ${man1dir}/$${page}${manext}); \
Index: emacs/lib-src/Makefile.in
===================================================================
RCS file: /cvs/Darwin/src/live/emacs/emacs/lib-src/Makefile.in,v
retrieving revision 1.1.1.6
retrieving revision 1.4
diff -u -r1.1.1.6 -r1.4
--- Makefile.in	2001/10/31 17:59:51	1.1.1.6
+++ Makefile.in	2001/12/13 02:44:29	1.4
@@ -92,7 +92,7 @@
 
 # Things that a user might actually run,
 # which should be installed in bindir.
-INSTALLABLES = etags ctags emacsclient b2m ebrowse
+INSTALLABLES = etags emacsclient b2m ebrowse
 INSTALLABLE_SCRIPTS = rcs-checkin grep-changelog
 
 # Things that Emacs runs internally, or during the build process,
Index: emacs/lisp/abbrev.elc
===================================================================
RCS file: abbrev.elc
diff -N abbrev.elc
Binary files /dev/null and /tmp/cvs000907 differ
Index: emacs/lisp/abbrevlist.elc
===================================================================
RCS file: abbrevlist.elc
diff -N abbrevlist.elc
Binary files /dev/null and /tmp/cvs000907 differ
Index: emacs/lisp/add-log.elc
===================================================================
RCS file: add-log.elc
diff -N add-log.elc
Binary files /dev/null and /tmp/cvs000907 differ
Index: emacs/lisp/align.elc
===================================================================
RCS file: align.elc
diff -N align.elc
Binary files /dev/null and /tmp/cvs000907 differ
Index: emacs/lisp/site-init.el
===================================================================
RCS file: site-init.el
diff -N site-init.el
--- emacs/lisp/site-init.el	Tue Sep 17 14:45:13 2002
+++ /tmp/cvs000907	Tue Sep 17 16:29:04 2002
@@ -0,0 +1,4 @@
+;; gnuserv setup.
+(autoload 'gnuserv-start "gnuserv-compat"
+  "Allow this Emacs process to be a server for client processes."
+  t)
Index: emacs/man/Makefile.in
===================================================================
RCS file: /cvs/Darwin/src/live/emacs/emacs/man/Makefile.in,v
retrieving revision 1.1.1.7
retrieving revision 1.3
diff -u -r1.1.1.7 -r1.3
--- Makefile.in	2002/09/10 23:34:32	1.1.1.7
+++ Makefile.in	2002/09/11 01:34:03	1.3
@@ -31,7 +31,7 @@
 
 
 # The makeinfo program is part of the Texinfo distribution.
-MAKEINFO = makeinfo
+MAKEINFO = echo makeinfo
 INFO_TARGETS = ../info/emacs ../info/ccmode ../info/cl \
 	        ../info/dired-x ../info/ediff ../info/forms ../info/gnus \
 		../info/info ../info/message ../info/mh-e ../info/reftex \
Index: emacs/src/emacs.c
===================================================================
RCS file: /cvs/Darwin/src/live/emacs/emacs/src/emacs.c,v
retrieving revision 1.1.1.7
retrieving revision 1.10
diff -u -r1.1.1.7 -r1.10
--- emacs.c	2002/09/10 23:34:58	1.1.1.7
+++ emacs.c	2002/09/11 01:34:03	1.10
@@ -779,15 +779,20 @@
     }
 #endif
 
-#ifdef NeXT
+#if defined(NeXT) || defined(RHAPSODY) || defined(DARWIN)
   {
     extern int malloc_cookie;
-    /* This helps out unexnext.c.  */
+    /* This helps out unexnext.c/unexdyld.c. */
     if (initialized)
-      if (malloc_jumpstart (malloc_cookie) != 0)
-	printf ("malloc jumpstart failed!\n");
+      {
+	if (malloc_jumpstart (malloc_cookie) != 0)
+	  {
+	    fprintf (stderr, "Fatal malloc_jumpstart() error\n");
+	    exit (1);
+	  }
+      }
   }
-#endif /* NeXT */
+#endif /* NeXT || RHAPSODY || DARWIN */
 
 #ifdef VMS
   /* If -map specified, map the data file in */
@@ -1466,7 +1471,7 @@
 #ifdef VMS
   init_vmsfns ();
 #endif /* VMS */
-  init_process ();
+  init_emacs_process ();
 #ifdef HAVE_SOUND
   init_sound ();
 #endif
Index: emacs/src/floatfns.c
===================================================================
RCS file: /cvs/Darwin/src/live/emacs/emacs/src/floatfns.c,v
retrieving revision 1.1.1.7
retrieving revision 1.4
diff -u -r1.1.1.7 -r1.4
--- floatfns.c	2002/09/10 23:34:59	1.1.1.7
+++ floatfns.c	2002/09/11 01:34:04	1.4
@@ -978,6 +978,9 @@
 #endif /* FLOAT_CATCH_SIGILL */
 
 #ifdef HAVE_MATHERR
+#ifdef __APPLE_CC__
+__private_extern__
+#endif
 int 
 matherr (x)
      struct exception *x;
Index: emacs/src/getloadavg.c
===================================================================
RCS file: /cvs/Darwin/src/live/emacs/emacs/src/getloadavg.c,v
retrieving revision 1.1.1.6
retrieving revision 1.4
diff -u -r1.1.1.6 -r1.4
--- getloadavg.c	2001/10/31 17:58:36	1.1.1.6
+++ getloadavg.c	2001/10/31 19:00:48	1.4
@@ -54,6 +54,8 @@
    hpux
    __MSDOS__			No-op for MSDOS.
    NeXT
+   RHAPSODY			Mac OS X Server
+   DARWIN			Darwin (Mac OS)
    sgi
    sequent			Sequent Dynix 3.x.x (BSD)
    _SEQUENT_			Sequent DYNIX/ptx 1.x.x (SYSV)
@@ -401,7 +403,7 @@
 #  define host_self mach_host_self
 # endif
 
-# ifdef NeXT
+# if defined(NeXT) || defined(RHAPSODY) || defined(DARWIN)
 #  ifdef HAVE_MACH_MACH_H
 #   include <mach/mach.h>
 #  else
@@ -449,7 +451,7 @@
 
 /* Avoid static vars inside a function since in HPUX they dump as pure.  */
 
-# ifdef NeXT
+# if defined(NeXT) || defined(RHAPSODY) || defined(DARWIN)
 static processor_set_t default_set;
 static int getloadavg_initialized;
 # endif /* NeXT */
@@ -486,6 +488,9 @@
    Return the number written (never more than 3, but may be less than NELEM),
    or -1 if an error occurred.  */
 
+#ifdef __APPLE_CC__
+__private_extern__
+#endif
 int
 getloadavg (loadavg, nelem)
      double loadavg[];
@@ -626,14 +631,10 @@
 
 # endif /* __NetBSD__ */
 
-# if !defined (LDAV_DONE) && defined (NeXT)
+# if !defined (LDAV_DONE) && (defined(NeXT) || defined(RHAPSODY) || defined(DARWIN))
 #  define LDAV_DONE
   /* The NeXT code was adapted from iscreen 3.2.  */
 
-  host_t host;
-  struct processor_set_basic_info info;
-  unsigned info_count;
-
   /* We only know how to get the 1-minute average for this system,
      so even if the caller asks for more than 1, we only return 1.  */
 
@@ -643,10 +644,19 @@
 	getloadavg_initialized = 1;
     }
 
+#ifndef DARWIN
+#define processor_set_load_info processor_set_basic_info
+#define PROCESSOR_SET_LOAD_INFO PROCESSOR_SET_BASIC_INFO
+#define PROCESSOR_SET_LOAD_INFO_COUNT PROCESSOR_SET_BASIC_INFO_COUNT
+#endif
+
   if (getloadavg_initialized)
     {
-      info_count = PROCESSOR_SET_BASIC_INFO_COUNT;
-      if (processor_set_info (default_set, PROCESSOR_SET_BASIC_INFO, &host,
+      struct processor_set_load_info info;
+      host_t host;
+      unsigned info_count = PROCESSOR_SET_LOAD_INFO_COUNT;
+
+      if (processor_set_info (default_set, PROCESSOR_SET_LOAD_INFO, &host,
 			      (processor_set_info_t) &info, &info_count)
 	  != KERN_SUCCESS)
 	getloadavg_initialized = 0;
Index: emacs/src/lisp.h
===================================================================
RCS file: /cvs/Darwin/src/live/emacs/emacs/src/lisp.h,v
retrieving revision 1.1.1.7
retrieving revision 1.4
diff -u -r1.1.1.7 -r1.4
--- lisp.h	2002/09/10 23:35:02	1.1.1.7
+++ lisp.h	2002/09/11 01:34:04	1.4
@@ -2770,7 +2770,7 @@
 extern void close_process_descs P_ ((void));
 extern void status_notify P_ ((void));
 extern int read_process_output P_ ((Lisp_Object, int));
-extern void init_process P_ ((void));
+extern void init_emacs_process P_ ((void));
 extern void syms_of_process P_ ((void));
 
 /* defined in callproc.c */
Index: emacs/src/process.c
===================================================================
RCS file: /cvs/Darwin/src/live/emacs/emacs/src/process.c,v
retrieving revision 1.1.1.7
retrieving revision 1.6
diff -u -r1.1.1.7 -r1.6
--- process.c	2002/09/10 23:35:04	1.1.1.7
+++ process.c	2002/09/11 01:34:04	1.6
@@ -1482,7 +1482,11 @@
     current_dir = ENCODE_FILE (current_dir);
 
 #ifndef WINDOWSNT
+#ifndef PUMA_VFORK_ISSUES_CLEARED_UP
+    pid = fork ();
+#else
     pid = vfork ();
+#endif
     if (pid == 0)
 #endif /* not WINDOWSNT */
       {
@@ -4604,7 +4608,7 @@
 }
 
 void
-init_process ()
+init_emacs_process ()
 {
   register int i;
 
@@ -5003,7 +5007,7 @@
 }
 
 void
-init_process ()
+init_emacs_process ()
 {
 }
 
Index: emacs/src/regex.c
===================================================================
RCS file: /cvs/Darwin/src/live/emacs/emacs/src/regex.c,v
retrieving revision 1.1.1.7
retrieving revision 1.4
diff -u -r1.1.1.7 -r1.4
Index: emacs/src/sysdep.c
===================================================================
RCS file: /cvs/Darwin/src/live/emacs/emacs/src/sysdep.c,v
retrieving revision 1.1.1.5
retrieving revision 1.4
diff -u -r1.1.1.5 -r1.4
--- sysdep.c	2002/09/10 23:35:06	1.1.1.5
+++ sysdep.c	2002/09/11 01:34:04	1.4
@@ -813,7 +813,12 @@
   synch_process_alive = 1;
 #endif /* __DJGPP__ > 1 */
 #else  
+#ifndef PUMA_VFORK_ISSUES_CLEARED_UP
+  pid = fork ();
+#else
   pid = vfork ();
+#endif
+
   if (pid == -1)
     error ("Can't spawn subshell");
 #endif
Index: emacs/src/term.c
===================================================================
RCS file: /cvs/Darwin/src/live/emacs/emacs/src/term.c,v
retrieving revision 1.1.1.6
retrieving revision 1.3
diff -u -r1.1.1.6 -r1.3
Index: emacs/src/termcap.c
===================================================================
RCS file: /cvs/Darwin/src/live/emacs/emacs/src/termcap.c,v
retrieving revision 1.1.1.6
retrieving revision 1.6
diff -u -r1.1.1.6 -r1.6
--- termcap.c	2001/10/31 17:58:46	1.1.1.6
+++ termcap.c	2002/01/08 02:38:33	1.6
@@ -144,6 +144,9 @@
   return NULL;
 }
 
+#ifdef __APPLE_CC__
+__private_extern__
+#endif
 int
 tgetnum (cap)
      char *cap;
@@ -154,6 +157,9 @@
   return atoi (ptr);
 }
 
+#ifdef __APPLE_CC__
+__private_extern__
+#endif
 int
 tgetflag (cap)
      char *cap;
@@ -167,6 +173,9 @@
    to store the string.  That pointer is advanced over the space used.
    If AREA is null, space is allocated with `malloc'.  */
 
+#ifdef __APPLE_CC__
+__private_extern__
+#endif
 char *
 tgetstr (cap, area)
      char *cap;
@@ -311,6 +320,9 @@
 
 #endif /* 0  */
 
+#ifdef __APPLE_CC__
+__private_extern__
+#endif
 void
 tputs (str, nlines, outfun)
      register char *str;
@@ -436,6 +448,9 @@
    0 if the data base is accessible but the type NAME is not defined
    in it, and some other value otherwise.  */
 
+#ifdef __APPLE_CC__
+__private_extern__
+#endif
 int
 tgetent (bp, name)
      char *bp, *name;
Index: emacs/src/tparam.c
===================================================================
RCS file: /cvs/Darwin/src/live/emacs/emacs/src/tparam.c,v
retrieving revision 1.1.1.6
retrieving revision 1.5
diff -u -r1.1.1.6 -r1.5
--- tparam.c	2001/10/31 17:58:47	1.1.1.6
+++ tparam.c	2002/01/08 02:38:33	1.5
@@ -110,6 +110,9 @@
 
 static char tgoto_buf[50];
 
+#ifdef __APPLE_CC__
+__private_extern__
+#endif
 char *
 tgoto (cm, hpos, vpos)
      char *cm;
Index: emacs/src/unexdyld.c
===================================================================
RCS file: unexdyld.c
diff -N unexdyld.c
--- emacs/src/unexdyld.c	Tue Sep 17 14:45:13 2002
+++ /tmp/cvs000907	Tue Sep 17 16:29:09 2002
@@ -0,0 +1,996 @@
+/* Dump Emacs in macho format.
+   Copyright (C) 1990, 1993 Free Software Foundation, Inc.
+   Derived from unexnext.c by Bradley Taylor (btaylor@next.com).
+
+This file is part of GNU Emacs.
+
+GNU Emacs is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Emacs is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Emacs; see the file COPYING.  If not, write to
+the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA.  */
+
+#include "config.h"
+#include <stdio.h>
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+#include <libc.h>
+#include <mach-o/nlist.h>
+#include <mach/mach.h>
+#ifndef NeXT
+#include <mach/machine/vm_param.h>
+#endif
+#include <mach-o/ldsyms.h>
+#include <mach-o/loader.h>
+#include <mach-o/reloc.h>
+
+extern int malloc_freezedry (void);
+
+int malloc_cookie;
+
+#define VERBOSE
+
+#ifdef VERBOSE
+#define SHOW_MCOPY_WRITES
+#define SHOW_MCOPY_READS
+#endif
+
+typedef struct region_t
+{
+  struct region_t *next;
+  vm_address_t address;
+  vm_size_t size;
+  vm_prot_t protection;
+  vm_prot_t max_protection;
+
+  /* And some info about where it was written to disk. */
+  unsigned long file_offset;
+  unsigned long file_size;
+} region_t;
+
+typedef struct section_list_t
+{
+  struct section_list_t *next;
+  struct section section;
+} section_list_t;
+
+static void fatal_unexec (char *format, ...)
+{
+  va_list ap;
+   
+  va_start (ap, format);
+  fprintf (stderr, "unexec: ");
+  vfprintf (stderr, format, ap);
+  fprintf (stderr, "\n");
+  va_end (ap);
+  exit (1);
+}
+
+static void print_region (struct region_t *region)
+{
+  printf ("0x%8lx - 0x%8lx, length: 0x%8lx, protection: %c%c%c, max_protection: %c%c%c\n",
+	  region->address, region->address + region->size, region->size,
+	  (region->protection & VM_PROT_READ) ? 'r' : '-',
+	  (region->protection & VM_PROT_WRITE) ? 'w' : '-',
+	  (region->protection & VM_PROT_EXECUTE) ? 'x' : '-',
+	  (region->max_protection & VM_PROT_READ) ? 'r' : '-',
+	  (region->max_protection & VM_PROT_WRITE) ? 'w' : '-',
+	  (region->max_protection & VM_PROT_EXECUTE) ? 'x' : '-');
+}
+
+static void print_regions (struct region_t *regions)
+{
+  while (regions != NULL)
+    {
+      print_region (regions);
+      regions = regions->next;
+    }
+}
+
+static void print_section (struct section *section)
+{
+  printf ("0x%8lx - 0x%8lx, length: 0x%8lx, offset: 0x%8lx\n",
+	  section->addr, section->addr + section->size, section->size, section->offset);
+}
+
+static void print_sections (section_list_t *sections)
+{
+  while (sections != NULL)
+    {
+      print_section (&(sections->section));
+      sections = sections->next;
+    }
+}
+
+static section_list_t *create_new_section_list(struct section *section_pointer)
+{
+    section_list_t *section_list;
+
+    section_list = malloc (sizeof (section_list_t));
+    section_list->next = NULL;
+    section_list->section = *section_pointer;
+
+    return section_list;
+}
+
+static void append_section_list(section_list_t **first_list, section_list_t *last_list)
+{
+    section_list_t *current;
+
+    if (*first_list == NULL) {
+        *first_list = last_list;
+        return;
+    }
+
+    current = *first_list;
+    while (current->next != NULL)
+        current = current->next;
+
+    current->next = last_list;
+}
+
+static void free_section_list(section_list_t *section_list)
+{
+    section_list_t *next;
+
+    while (section_list != NULL)
+    {
+        next = section_list->next;
+        free(section_list);
+        section_list = next;
+    }
+}
+
+static void add_sections_from_segment(section_list_t **all_sections, struct segment_command *segment)
+{
+    struct section *section_pointer;
+    int index;
+
+    section_pointer = (struct section *)(segment + 1);
+    for (index = 0; index < segment->nsects; index++) {
+        append_section_list (all_sections, create_new_section_list (section_pointer));
+        section_pointer++;
+    }
+}
+
+static int section_with_address (section_list_t *sections, unsigned long address)
+{
+    int current_section, found_section;
+
+    found_section = 0;
+    current_section = 1;
+    while (sections != NULL)
+    {
+        if (address >= sections->section.addr && address < sections->section.addr + sections->section.size) {
+            found_section = current_section;
+            break;
+        }
+        sections = sections->next;
+        current_section++;
+    }
+
+    return found_section;
+}
+
+/*
+ * Copy len bytes from ffd@fpos to tfd@tpos.
+ * If both file descriptors are -1, copy in memory (handles overlapping copies).
+ * If either ffd or tfd are -1, either read or write len bytes.
+ */
+
+static void mcopy (int ffd, int tfd,
+                   unsigned long fpos, unsigned long tpos, unsigned long len, char *reason)
+{
+  if ((ffd == -1) && (tfd == -1))
+    {
+      char *f, *t, *e;
+      if (fpos > tpos)
+        {
+	  f = (char *)fpos;
+	  t = (char *)tpos;
+	  e = (char *)(fpos + len);
+	  while (f < e) *t++ = *f++;
+        }
+      else if (tpos > fpos)
+        {
+	  f = (char *)(fpos + len);
+	  t = (char *)(tpos + len);
+	  e = (char *)fpos;
+	  while (f > e) *--t = *--f;         
+        }   
+#ifdef SHOW_MCOPY_READS
+      printf ("read: %10lu - %10lu, length: %10lu [from MEM]  (%s)\n", tpos, tpos+len, len, reason);
+#endif
+    }
+  else if (ffd == -1)
+    {
+      if (lseek (tfd, tpos, L_SET) < 0)
+	fatal_unexec ("cannot seek target");
+      if (write (tfd, (void *)fpos, len) != len)
+	fatal_unexec ("cannot write target");
+#ifdef SHOW_MCOPY_WRITES
+      printf ("write: %10lu - %10lu, length: %10lu [from MEM]  (%s)\n", tpos, tpos+len, len, reason);
+#endif
+    }
+  else if (tfd == -1)
+    {
+      if (lseek (ffd, fpos, L_SET) < 0)
+	fatal_unexec ("cannot seek source");
+      if (read (ffd, (void *)tpos, len) != len)
+	fatal_unexec ("cannot read source");
+#ifdef SHOW_MCOPY_READS
+      printf ("read: %10lu - %10lu, length: %10lu [from DISK] (%s)\n", tpos, tpos+len, len, reason);
+#endif
+    }
+  else
+    {
+      int bread;
+      char *buf = alloca (1 << 16);
+
+#ifdef SHOW_MCOPY_WRITES
+      printf ("write: %10lu - %10lu, length: %10lu [from DISK] (%s)\n", tpos, tpos+len, len, reason);
+#endif
+
+      if (lseek (ffd, fpos, L_SET) < 0)
+	fatal_unexec ("cannot seek source");
+      
+      if (lseek (tfd, tpos, L_SET) < 0)
+	fatal_unexec ("cannot seek target");
+      
+      while((len > 0) && (bread = read (ffd, buf, MIN(1 << 16, len))) > 0)
+        {
+	  if (bread < 0)
+	    fatal_unexec ("cannot read source");
+	  if (write (tfd, buf, bread) != bread)
+	    fatal_unexec ("cannot write target");
+	  len -= bread;
+        }
+    }
+}
+
+/*
+ * The process of dumping (or unexecing) is the opposite of exec().
+ * It takes the original executable and parts of memory that have been
+ * loaded with data, and creates a new executable.  This allows
+ * standard lisp files to be loaded "instantly", because they are part
+ * of the executable.
+ *
+ * This involves using vm_region() to build a list of allocated memory
+ * regions, combining adjacent "similar" regions to reduce their
+ * number, skipping read-only regions and parts of regions covered by
+ * non-data segment load commands, and finally replacing the (usually
+ * one) data segment with a new segment for each region.
+ *
+ * File offsets in load commands that follow the data segment must be
+ * adjusted by the change in size of the data segment.  The size of
+ * the load commands can increase without affecting file offsets --
+ * see the note below.
+ *
+ * Data associated with the LC_SYMTAB and LC_DYSYMTAB is found in the
+ * __LINKEDIT segment -- there is no extra data to be written for
+ * these load commands.
+ *
+ * Relocatable symbols from the data segment, which we took from
+ * memory, need to be unrelocated.  The relocatable address is found
+ * in the new mach-o file and then zeroed out.  Failure to do this
+ * typically results in a segmentation fault, with the offending
+ * address being double what it is at the same point in temacs, since
+ * it has been relocated twice.
+ *
+ * Be sure to study the loader.h file if you want to understand this.
+ * otool -lv shows the load commands of the file, and is very useful
+ * when debugging this code.  Also, 'size -m -x -l' gives a short
+ * list of the sections, and 'nm -maxp' and 'nm -map' are useful
+ * for the symbol table stuff.
+ *
+ * Note: This is not obvious, but the __TEXT section usually has a
+ *       file offset of 0, and so when it is written it will overwrite
+ *       any mach headers or load commands that have already been
+ *       written...  How much room is there before critial parts are
+ *       overwritten when we add load commands?
+ *
+ *    -- Steve Nygard
+ */
+
+static void unexec_doit(int infd,int outfd)
+{
+  int i, j, l, header_position, output_position;
+  region_t *regions = NULL, *cregion, **pregions;
+  struct mach_header mach_header;
+  struct load_command *load_command, *original_load_commands;
+  struct segment_command *segment_pointer;
+  struct symtab_command *symtab_pointer;
+  struct section *section_pointer;
+  section_list_t *all_sections = NULL;
+
+  unsigned long delta = 0;
+#if defined(NS_TARGET) || !defined(NeXT)
+  struct dysymtab_command *dysymtab;
+  struct twolevel_hints_command *hinttab;
+  unsigned long extreloff = 0;
+  unsigned long nextrel = 0;
+  unsigned long locreloff = 0;
+  unsigned long nlocrel = 0;
+  struct relocation_info reloc_info;
+  unsigned long fixed_reloc_count = 0;
+#endif
+
+  struct segment_command new_data_segment;
+  section_list_t *original_sections, *new_sections, **sect_ptr, *section_item;
+
+  malloc_cookie = malloc_freezedry();
+#ifdef VERBOSE
+  printf ("malloc_cookie: %lx\n", malloc_cookie);
+#endif
+  if (malloc_cookie == 0)
+    {
+      fprintf(stderr, "Error in malloc_freezedry()\n");
+      abort();
+    }
+
+  {
+    vm_address_t address;
+    vm_size_t size;
+    mach_port_t object_name;
+#ifdef DARWIN
+    task_t task = mach_task_self();
+    struct vm_region_basic_info info;
+    mach_msg_type_number_t info_count = VM_REGION_BASIC_INFO_COUNT;
+#else
+    task_t task = task_self();
+    vm_prot_t protection, max_protection;
+    vm_inherit_t inheritance;
+    boolean_t shared;
+    vm_offset_t offset;
+#endif
+
+    for (address = VM_MIN_ADDRESS, pregions = &regions;
+#ifdef DARWIN
+	 vm_region(task, &address, &size, VM_REGION_BASIC_INFO, 
+		   (vm_region_info_t)&info, &info_count, &object_name) == KERN_SUCCESS;
+#else
+	 vm_region(task, &address, &size, &protection, &max_protection,
+		   &inheritance, &shared, &object_name, &offset) == KERN_SUCCESS;
+#endif
+	 address += size)
+      {
+	(*pregions) = alloca (sizeof(region_t));
+	(*pregions)->address = address;
+	(*pregions)->size = size;
+#ifdef DARWIN
+	(*pregions)->protection = info.protection;
+	(*pregions)->max_protection = info.max_protection;
+#else
+	(*pregions)->protection = protection;
+	(*pregions)->max_protection = max_protection;
+#endif
+	(*pregions)->file_offset = 0;
+	(*pregions)->file_size = 0;
+	(*pregions)->next = 0;
+	pregions = &((*pregions)->next);
+#ifdef DARWIN
+	if (object_name != MACH_PORT_NULL)
+	  mach_port_deallocate(mach_task_self(), object_name);
+	info_count = VM_REGION_BASIC_INFO_COUNT;
+#endif
+      }
+  }
+#ifdef VERBOSE   
+  printf ("Regions.\n");
+  print_regions (regions);
+  printf ("----------------------------------------------------------------------\n");
+#endif
+   
+  /*
+   * Concatenate regions that are adjacent in memory and share the same
+   * protection attributes.
+   */
+
+  for (cregion = regions; cregion; cregion = cregion->next)
+    {
+      while ((cregion->next) &&
+	     (cregion->next->address == cregion->address + cregion->size) &&
+	     (cregion->next->protection == cregion->protection) &&
+	     (cregion->next->max_protection == cregion->max_protection))
+        {
+	  cregion->size += cregion->next->size;
+	  cregion->next = cregion->next->next;
+        }
+    }
+#ifdef VERBOSE   
+  printf ("Concatenated regions.\n");
+  print_regions (regions);
+  printf ("----------------------------------------------------------------------\n");
+#endif
+
+  /*
+   * Remove read-only regions, and regions above a fixed limit.
+   * Could have been done before allocating, but this way we can show
+   * the regions before and after while debugging.
+   */
+
+  for (pregions = &regions; *pregions != NULL;)
+    {
+      if ( !((*pregions)->protection & VM_PROT_WRITE)
+	   || ((*pregions)->address >= 0x3000000))
+        {
+	  *pregions = (*pregions)->next;
+        }
+      else
+        {
+	  pregions = &((*pregions)->next);
+        }
+    }
+#ifdef VERBOSE
+  printf ("Skipped regions.\n");
+  print_regions (regions);
+  printf ("----------------------------------------------------------------------\n");
+#endif
+  /*
+     * Read original mach header and load commands.
+     */
+
+  mcopy (infd, -1, 0, (unsigned long) &mach_header, sizeof(mach_header), "read original mach header");
+  original_load_commands = alloca (mach_header.sizeofcmds);
+  mcopy (infd, -1, sizeof(mach_header), (unsigned long) original_load_commands, mach_header.sizeofcmds,
+         "read original load comands");
+
+  /*
+     * Skip (or adjust) regions that intersect memory represented by non-data
+     * segments from the original load commands.
+     */
+
+  for (pregions = &regions; *pregions;)
+    {
+      for (load_command = original_load_commands, i = 0;
+	   i < mach_header.ncmds;
+	   i++, load_command = (struct load_command *)(((void *)load_command) + load_command->cmdsize))
+        {
+	  unsigned long ob, oe;
+	  segment_pointer = (struct segment_command *)load_command;
+	  if (segment_pointer->cmd != LC_SEGMENT || (strcmp (segment_pointer->segname, SEG_DATA) == 0)) continue;
+	  ob = MAX((*pregions)->address, segment_pointer->vmaddr);
+	  oe = MIN((*pregions)->address + (*pregions)->size, segment_pointer->vmaddr + segment_pointer->vmsize);
+	  if (ob >= oe) continue;
+	  if (ob == (*pregions)->address)
+            {
+	      if (oe == (*pregions)->address + (*pregions)->size)
+                {
+		  goto skip_region;
+                }
+	      else
+                {
+		  (*pregions)->address = oe;
+		  (*pregions)->size -= (oe - ob);
+                }
+            }
+	  else
+            {
+	      if (oe == (*pregions)->address + (*pregions)->size)
+                {
+		  (*pregions)->size -= (oe - ob);
+                }
+	      else
+                {
+		  cregion = alloca (sizeof(*cregion));
+		  cregion->address = oe;
+		  cregion->size = ((*pregions)->address + (*pregions)->size) - oe;
+		  cregion->protection = (*pregions)->protection;
+		  cregion->max_protection = (*pregions)->max_protection;
+		  cregion->file_offset = 0;
+		  cregion->file_size = 0;
+		  cregion->next = (*pregions)->next;
+		  (*pregions)->size = ob - (*pregions)->address;
+		  (*pregions)->next = cregion;
+                }
+            }
+        }
+
+      pregions = &((*pregions)->next);
+      continue;
+
+    skip_region:
+      *pregions = (*pregions)->next;
+    }
+#ifdef VERBOSE
+  printf ("Munged regions (1).\n");
+  print_regions (regions);
+  printf ("----------------------------------------------------------------------\n");
+#endif
+
+  for (load_command = original_load_commands, i = mach_header.ncmds, header_position = sizeof(mach_header), output_position = 0;
+       i > 0;
+       i--, load_command = (struct load_command *)(((void *)load_command) + load_command->cmdsize))
+    {
+      switch (load_command->cmd)
+        {
+	case LC_SEGMENT:
+	  segment_pointer = (struct segment_command *)load_command;
+
+	  if (strcmp (segment_pointer->segname, SEG_DATA) == 0)
+	    {
+#if 1
+	      unsigned long current_address;
+
+	      original_sections = NULL;
+	      new_sections = NULL;
+	      sect_ptr = &original_sections;
+
+	      section_pointer = (struct section *)(segment_pointer + 1);
+	      for (l = 0; l < segment_pointer->nsects; l++)
+		{
+		  if (!strncmp (section_pointer->sectname, "__la_symbol_ptr", 16))
+		    {
+		      section_item = alloca (sizeof (section_list_t));
+		      section_item->next = *sect_ptr;
+		      section_item->section = *section_pointer;
+		      *sect_ptr = section_item;
+		      sect_ptr = &(section_item->next);
+		    }
+		  else if (!strncmp (section_pointer->sectname, "__nl_symbol_ptr", 16))
+		    {
+		      section_item = alloca (sizeof (section_list_t));
+		      section_item->next = *sect_ptr;
+		      section_item->section = *section_pointer;
+		      *sect_ptr = section_item;
+		      sect_ptr = &(section_item->next);
+		    }
+		  else if (!strncmp (section_pointer->sectname, "__dyld", 16))
+		    {
+		      section_item = alloca (sizeof (section_list_t));
+		      section_item->next = *sect_ptr;
+		      section_item->section = *section_pointer;
+		      *sect_ptr = section_item;
+		      sect_ptr = &(section_item->next);
+		    }
+
+		  section_pointer++;
+		}
+
+	      cregion = regions;
+	      /* new_data_segment */
+	      new_data_segment.cmd = LC_SEGMENT;
+	      strncpy (new_data_segment.segname, SEG_DATA, 16);
+	      new_data_segment.vmaddr = cregion->address;
+	      new_data_segment.vmsize = 0;
+	      new_data_segment.fileoff = 0;
+	      new_data_segment.filesize = 0;
+	      new_data_segment.maxprot = cregion->max_protection;
+	      new_data_segment.initprot = cregion->protection;
+	      new_data_segment.flags = segment_pointer->flags;
+	      new_data_segment.nsects = 0;
+	      new_data_segment.cmdsize = sizeof (struct segment_command);
+#ifdef VERBOSE
+	      printf ("Original sections:\n");
+	      print_sections (original_sections);
+	      printf ("----------------------------------------------------------------------\n");
+#endif
+	      /* Create list of new segments */
+	      sect_ptr = &new_sections;
+	      current_address = new_data_segment.vmaddr;
+	      while (original_sections != NULL)
+		{
+		  if (current_address < original_sections->section.addr)
+		    {
+		      /* Create new section for this. */
+		      section_item = alloca (sizeof (section_list_t));
+		      section_item->next = *sect_ptr;
+
+		      section_pointer = &(section_item->section);
+		      strncpy (section_pointer->sectname, "__data", 16);
+		      strncpy (section_pointer->segname, SEG_DATA, 16);
+		      section_pointer->addr = current_address;
+		      section_pointer->size = original_sections->section.addr - current_address;
+		      section_pointer->offset = 0;
+		      section_pointer->align = 2; /* Yuck. */
+		      section_pointer->reloff = 0;
+		      section_pointer->nreloc = 0;
+		      section_pointer->flags = 0; /* S_REGULAR? */
+		      section_pointer->reserved1 = 0;
+		      section_pointer->reserved2 = 0;
+
+		      *sect_ptr = section_item;
+		      sect_ptr = &(section_item->next);
+		      current_address = original_sections->section.addr;
+		    }
+
+		  /* Put/copy this section into new list */
+		  section_item = original_sections;
+		  original_sections = original_sections->next;
+		  section_item->next = *sect_ptr; /* Should be NULL... */
+		  *sect_ptr = section_item;
+		  sect_ptr = &(section_item->next);
+
+		  /* increase current address */
+		  current_address += section_item->section.size;
+		}
+	      /* if current address < end of region, add final section. */
+	      if (current_address < cregion->address + cregion->size)
+		{
+		  /* Create new section for this. */
+		  section_item = alloca (sizeof (section_list_t));
+		  section_item->next = *sect_ptr;
+
+		  section_pointer = &(section_item->section);
+		  strncpy (section_pointer->sectname, "__data", 16);
+		  strncpy (section_pointer->segname, SEG_DATA, 16);
+		  section_pointer->addr = current_address;
+		  section_pointer->size = cregion->address + cregion->size - current_address;
+		  section_pointer->offset = 0;
+		  section_pointer->align = 2; /* Yuck. */
+		  section_pointer->reloff = 0;
+		  section_pointer->nreloc = 0;
+		  section_pointer->flags = 0; /* S_REGULAR? */
+		  section_pointer->reserved1 = 0;
+		  section_pointer->reserved2 = 0;
+
+		  *sect_ptr = section_item;
+		  sect_ptr = &(section_item->next);
+
+		}
+#ifdef VERBOSE
+	      printf ("New sections:\n");
+	      print_sections (new_sections);
+	      printf ("----------------------------------------------------------------------\n");
+#endif
+	      /**
+	       * Go through new list of sections
+	       *  - write section to disk, either from memory or original file
+	       *  - say, if offset == 0, take from memory, otherwise from original file at that offset
+	       *  - set offset of section
+	       *  - set fileoff of segment to be that of the first section
+	       *  - increase output position
+	       **/
+
+	      sect_ptr = &new_sections;
+	      while (*sect_ptr != NULL)
+		{
+		  section_pointer = &((*sect_ptr)->section);
+		  if (new_data_segment.fileoff == 0)
+		    new_data_segment.fileoff = output_position;
+		  new_data_segment.vmsize += section_pointer->size;
+		  new_data_segment.filesize += section_pointer->size;
+		  new_data_segment.nsects++;
+		  new_data_segment.cmdsize += sizeof (struct section);
+                  printf ("section is '%s'\n", section_pointer->sectname);
+		  if (section_pointer->offset == 0)
+		    {
+		      mcopy (-1, outfd, (unsigned long) section_pointer->addr, output_position, section_pointer->size,
+                             "SEG_DATA: write section data from memory");
+		    }
+		  else
+		    {
+		      mcopy (infd, outfd, (unsigned long) section_pointer->offset, output_position, section_pointer->size,
+                             "SEG_DATA: write section data from original file");
+		    }
+		  section_pointer->offset = output_position;
+		  output_position += section_pointer->size;
+
+		  sect_ptr = &((*sect_ptr)->next);
+		}
+
+	      /* Write data segment and sections, increasing the header position */
+	      mcopy (-1, outfd, (unsigned long) &new_data_segment, header_position, sizeof (struct segment_command),
+                     "SEG_DATA: write segment command");
+	      header_position += sizeof (struct segment_command);
+	      while (new_sections != NULL)
+		{
+		  mcopy (-1, outfd, (unsigned long) &(new_sections->section), header_position, sizeof (struct section),
+                         "SEG_DATA: write section command");
+                  // Need to add this section to a list of all the sections
+		  header_position += sizeof (struct section);
+                  append_section_list (&all_sections, create_new_section_list (&(new_sections->section)));
+		  new_sections = new_sections->next;
+		}
+	      mach_header.ncmds++;
+
+	      /* Finally, skip first data segment. */
+	      regions = regions->next;
+#endif
+
+#if 1
+	      /* Write remainder of regions as data segments */
+	      mach_header.ncmds--;
+	      j = segment_pointer->cmdsize; /* Save original command size for loop. */
+	      for (cregion = regions; cregion != NULL; cregion = cregion->next)
+		{
+		  mcopy (-1, outfd, cregion->address, output_position, cregion->size,
+                         "SEG_DATA: write remainder data");
+		  segment_pointer->cmd = LC_SEGMENT;
+		  segment_pointer->cmdsize = sizeof(*segment_pointer);
+		  strncpy (segment_pointer->segname, SEG_DATA, sizeof(segment_pointer->segname));
+		  segment_pointer->vmaddr = cregion->address;
+		  segment_pointer->vmsize = cregion->size;
+		  segment_pointer->filesize = cregion->size;
+		  segment_pointer->maxprot = cregion->max_protection;
+		  segment_pointer->initprot = cregion->protection;
+		  segment_pointer->nsects = 0;
+		  segment_pointer->flags = 0;
+		  segment_pointer->fileoff = output_position;
+		  output_position += segment_pointer->filesize;
+		  mcopy (-1, outfd, (unsigned long)segment_pointer, header_position, segment_pointer->cmdsize,
+                         "SEG_DATA: write segment command for remainder data");
+		  header_position += segment_pointer->cmdsize;
+		  mach_header.ncmds++;
+
+		  cregion->file_offset = segment_pointer->fileoff;
+		  cregion->file_size = segment_pointer->filesize;
+		}
+	      segment_pointer->cmdsize = j;
+
+#endif
+	    }
+	  else
+	    {
+#ifdef VERBOSE
+              printf ("segment is '%s':\n", segment_pointer->segname);
+#endif
+	      mcopy (infd, outfd, segment_pointer->fileoff, output_position, segment_pointer->filesize,
+                     "SEG_OTHER: write segment data");
+	      section_pointer = (struct section *) (((void *)segment_pointer)+sizeof(*segment_pointer));
+	      for(j = 0; j < segment_pointer->nsects; j++)
+		{
+		  if (section_pointer[j].offset != 0)
+		    section_pointer[j].offset = (section_pointer[j].offset - segment_pointer->fileoff) + output_position;
+		  if (section_pointer[j].reloff != 0)
+		    section_pointer[j].reloff = (section_pointer[j].reloff - segment_pointer->fileoff) + output_position;
+		}
+
+	      if (strcmp (segment_pointer->segname, SEG_LINKEDIT) == 0)
+		{
+		  delta = output_position - segment_pointer->fileoff;
+		}
+
+	      segment_pointer->fileoff = output_position;
+	      output_position += segment_pointer->filesize;
+
+	      mcopy (-1, outfd, (unsigned long)load_command, header_position, load_command->cmdsize,
+                     "SEG_OTHER: write segment command and its sections");
+	      header_position += load_command->cmdsize;
+
+              // Now, scan the segments for sections, so we have a list of all the sections to use to fix up
+              // the symbol table entries.
+              add_sections_from_segment(&all_sections, segment_pointer);
+	    }
+	  break;
+
+	case LC_SYMTAB:
+        {
+            struct nlist *symtab;
+
+            symtab_pointer = (struct symtab_command *)load_command;
+
+            symtab = malloc(symtab_pointer->nsyms * sizeof(struct nlist));
+            mcopy(infd, -1, symtab_pointer->symoff, (unsigned long)symtab, symtab_pointer->nsyms * sizeof(struct nlist),
+                  "Read old symbol table into memory");
+
+            symtab_pointer->symoff += delta;
+            symtab_pointer->stroff += delta;
+            mcopy (-1, outfd, (unsigned long)load_command, header_position, load_command->cmdsize,
+                   "write symtab command");
+            header_position += load_command->cmdsize;
+            printf ("LC_SYMTAB: symoff = %ld, nsyms = %ld, stroff = %ld, strsize = %ld\n",
+                    symtab_pointer->symoff, symtab_pointer->nsyms, symtab_pointer->stroff, symtab_pointer->strsize);
+
+            // We've already written out the symbol table, but we're going to read it back in, adjust the
+            // symbol table entries, and write out the result again.
+
+            if (all_sections != NULL)
+            {
+                int index;
+                struct nlist *nlist_pointer;
+                section_list_t *section;
+                int section_index;
+                int changed_symtabs;
+
+                printf ("All sections:\n");
+                print_sections (all_sections);
+
+                changed_symtabs = 0;
+                nlist_pointer = symtab;
+
+                for (index = 0; index < symtab_pointer->nsyms; index++) {
+                    if ((nlist_pointer->n_type & N_TYPE) == N_SECT) {
+                        section_index = section_with_address(all_sections, nlist_pointer->n_value);
+#if 0
+                        printf ("%5d: 0x%08lx 0x%02x 0x%02x (0x%02x) 0x%04x 0x%08lx\n",
+                                index, nlist_pointer->n_un.n_strx, nlist_pointer->n_type & 0xff, nlist_pointer->n_sect & 0xff,
+                                section_index,
+                                nlist_pointer->n_desc & 0xffff, nlist_pointer->n_value);
+#endif
+                        if (nlist_pointer->n_sect != section_index) {
+                            nlist_pointer->n_sect = section_index;
+                            changed_symtabs++;
+                        }
+                    }
+                    nlist_pointer++;
+                }
+
+                printf ("Adjusted n_sect for %d symbol table entries.\n", changed_symtabs);
+                mcopy(-1, outfd, (unsigned long)symtab, symtab_pointer->symoff, symtab_pointer->nsyms * sizeof(struct nlist),
+                      "write updated symbol table");
+
+                free_section_list(all_sections);
+            }
+
+            free(symtab);
+        }
+        break;
+#if defined(NS_TARGET) || !defined(NeXT)
+	case LC_DYSYMTAB:
+	  dysymtab = (struct dysymtab_command *)load_command;
+	  extreloff = dysymtab->extreloff;
+	  nextrel = dysymtab->nextrel;
+
+	  locreloff = dysymtab->locreloff;
+	  nlocrel = dysymtab->nlocrel;
+
+	  if (dysymtab->nindirectsyms > 0) {
+	    dysymtab->indirectsymoff += delta;
+	  }
+	  if (nextrel > 0) {
+	    dysymtab->extreloff += delta;
+	  }
+
+	  if (nlocrel > 0) {
+	    dysymtab->locreloff += delta;
+	  }
+	  mcopy (-1, outfd, (unsigned long)load_command, header_position, load_command->cmdsize,
+                 "write dysymtab command");
+	  header_position += load_command->cmdsize;
+
+	  break;
+
+       case LC_TWOLEVEL_HINTS: 
+          hinttab = (struct twolevel_hints_command *)load_command;
+          hinttab->offset += delta;
+          
+          mcopy (-1, outfd, (unsigned long)load_command, header_position, load_command->cmdsize,
+                 "write two-level hint command");
+          header_position += load_command->cmdsize;
+
+          break;
+#endif
+	default:
+	  {
+	    char *reason, *cmdstr;
+
+	    /* Create a string that tells what load command is being left
+	     * alone. */
+	    switch (load_command->cmd)
+	      {
+	      case LC_UNIXTHREAD:
+		cmdstr = "LC_UNIXTHREAD";
+		break;
+	      case LC_LOAD_DYLIB:
+		cmdstr = "LC_LOAD_DYLIB";
+		break;
+	      case LC_LOAD_DYLINKER:
+		cmdstr = "LC_LOAD_DYLINKER";
+		break;
+	      default:
+		cmdstr = NULL;
+	      }
+	    if (cmdstr != NULL)
+	      {
+		asprintf(&reason, "write other load command (%s)", cmdstr);
+	      }
+	    else
+	      {
+		asprintf(&reason, "write other load command (0x%x)", load_command->cmd);
+	      }
+
+	    mcopy (-1, outfd, (unsigned long)load_command, header_position, load_command->cmdsize,
+		   reason);
+	    free(reason);
+	    header_position += load_command->cmdsize;
+	  }
+        }
+    }
+
+  mach_header.sizeofcmds = header_position - sizeof(mach_header);
+  mcopy (-1, outfd, (unsigned long) &mach_header, 0, sizeof(mach_header), "write mach header");
+
+#if defined(NS_TARGET) || !defined(NeXT)
+  if (mach_header.flags & MH_PREBOUND) {
+    /* Don't mess with prebound executables */
+    return;
+  }
+
+  /*
+     * Fix up relocation entries in the data segment(s).
+     */
+  if (lseek (infd, locreloff, L_SET) < 0)
+    fatal_unexec ("cannot seek input file");
+
+  fixed_reloc_count = 0;
+  for (i = 0; i < nlocrel; i++)
+    {
+      long zeroval = 0;
+      struct scattered_relocation_info *si;
+
+      if (read (infd, &reloc_info, sizeof(reloc_info)) != sizeof(reloc_info))
+	fatal_unexec ("cannot read input file");
+
+#if 1
+#ifdef VERBOSE
+      printf ("%2d: reloc: %lx, start: %lx, end: %lx\n", i, reloc_info.r_address,
+	      new_data_segment.vmaddr, new_data_segment.vmaddr + new_data_segment.filesize);
+#endif
+      if (reloc_info.r_address >= new_data_segment.vmaddr
+	  && reloc_info.r_address < new_data_segment.vmaddr + new_data_segment.filesize)
+        {
+	  fixed_reloc_count++;
+	  mcopy (-1, outfd, (unsigned long) &zeroval,
+		 new_data_segment.fileoff + reloc_info.r_address - new_data_segment.vmaddr,
+		 1 << reloc_info.r_length, "fix local relocation entry");
+        }
+#endif
+    }
+  printf ("Fixed %lu/%lu local relocation entries in data segment(s).\n", fixed_reloc_count, nlocrel);
+
+  if (lseek (infd, extreloff, L_SET) < 0)
+    fatal_unexec ("cannot seek input file");
+
+  for (i = 0; i < nextrel; i++)
+    {
+      long zeroval = 0;
+
+      if (read (infd, &reloc_info, sizeof(reloc_info)) != sizeof(reloc_info))
+	fatal_unexec ("cannot read input file");
+
+#if 1
+#ifdef VERBOSE
+      printf ("%2d: reloc: %lx, start: %lx, end: %lx\n", i, reloc_info.r_address,
+	      new_data_segment.vmaddr, new_data_segment.vmaddr + new_data_segment.filesize);
+#endif
+      if (reloc_info.r_address >= new_data_segment.vmaddr
+	  && reloc_info.r_address < new_data_segment.vmaddr + new_data_segment.filesize)
+        {
+	  fixed_reloc_count++;
+	  mcopy (-1, outfd, (unsigned long) &zeroval,
+		 new_data_segment.fileoff + reloc_info.r_address - new_data_segment.vmaddr,
+		 1 << reloc_info.r_length, "fix external relocation entry");
+        }
+#endif
+    }
+
+  printf ("Fixed %lu/%lu external relocation entries in data segment(s).\n", fixed_reloc_count, nextrel);
+
+#endif
+}
+
+void unexec (char *outfile, char *infile)
+{
+  char tmpfile[MAXPATHLEN + 1];
+  int infd, outfd;
+   
+  if ((infd = open (infile, O_RDONLY, 0)) < 0)
+    fatal_unexec ("cannot open input file `%s'", infile);
+
+  strcpy (tmpfile, outfile);
+  strcat (tmpfile, "-temp");
+   
+  if ((outfd = open (tmpfile, O_RDWR|O_TRUNC|O_CREAT, 0755)) < 0)
+    fatal_unexec ("cannot open temporary output file `%s'", tmpfile);
+
+  unexec_doit (infd, outfd);
+
+  close (infd);
+  close (outfd);
+  if (rename (tmpfile, outfile) < 0)
+    {
+      unlink (tmpfile);
+      fatal_unexec ("cannot rename `%s' to `%s'", tmpfile, outfile);
+    }  
+}
Index: emacs/src/unexnext.c
===================================================================
RCS file: /cvs/Darwin/src/live/emacs/emacs/src/unexnext.c,v
retrieving revision 1.1.1.5
retrieving revision 1.3
diff -u -r1.1.1.5 -r1.3
Index: emacs/src/m/powermacintosh.h
===================================================================
RCS file: powermacintosh.h
diff -N powermacintosh.h
--- /dev/null	Tue Sep 17 14:45:13 2002
+++ emacs/src/m/powermacintosh.h	Tue Sep 17 16:29:09 2002
@@ -0,0 +1,45 @@
+/* Apple Power Macintosh machine/system dependent defines
+   Copyright (C) 1997 Free Software Foundation, Inc.
+
+This file is part of GNU Emacs.
+
+GNU Emacs is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Emacs is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Emacs; see the file COPYING.  If not, write to
+the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA.  */
+
+
+/* The following line tells the configuration script what sort of 
+   operating system this machine is likely to run.
+   USUAL-OPSYS="darwin"  */
+
+/* Define WORDS_BIG_ENDIAN iff lowest-numbered byte in a word
+   is the most significant byte.  */
+
+#define WORDS_BIG_ENDIAN
+
+/* Define NO_ARG_ARRAY if you cannot take the address of the first of a
+ * group of arguments and treat it as an array of the arguments.  */
+
+#define NO_ARG_ARRAY
+
+/* Use type int rather than a union, to represent Lisp_Object */
+/* This is desirable for most machines.	 */
+
+#define NO_UNION_TYPE
+
+/* Define addresses, macros, change some setup for dump */
+
+#define NO_REMAP
+
+#define DATA_SEG_BITS 0
Index: emacs/src/s/darwin.h
===================================================================
RCS file: darwin.h
diff -N darwin.h
--- /dev/null	Tue Sep 17 14:45:13 2002
+++ emacs/src/s/darwin.h	Tue Sep 17 16:29:09 2002
@@ -0,0 +1,104 @@
+/* Configuration file for Darwin OS.
+   Copyright (C) 1997 Free Software Foundation, Inc.
+
+This file is part of GNU Emacs.
+
+GNU Emacs is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Emacs is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Emacs; see the file COPYING.  If not, write to
+the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA.  */
+
+/* We give these symbols the numeric values found in <sys/param.h> to
+   avoid warnings about redefined macros.  */
+#define BSD 199506
+#define BSD4_3 1
+#define BSD4_4 1
+
+#include "bsd4-3.h"
+
+/* SYSTEM_TYPE should indicate the kind of system you are using.
+   It sets the Lisp variable system-type.  We'll need to undo the bsd one. */
+
+#undef SYSTEM_TYPE
+#define SYSTEM_TYPE "darwin"
+
+#ifndef DARWIN
+#define DARWIN
+#endif
+
+#undef KERNEL_FILE
+#define KERNEL_FILE "/mach_kernel"
+
+#define HAVE_ALLOCA
+
+#define HAVE_MACH_MACH_H
+
+#define SYSTEM_MALLOC
+
+#define WAIT_USE_INT
+
+#define SOCKLEN_TYPE int
+
+#define GETPGRP_NO_ARG
+
+#ifdef HAVE_LIBNCURSES
+#define TERMINFO
+#define LIBS_TERMCAP -lncurses
+#else
+#define TERMCAP_FILE "/usr/share/misc/termcap" 
+#endif
+
+#define PENDING_OUTPUT_COUNT(FILE) ((FILE)->_p - (FILE)->_bf._base)
+
+#define A_OUT_H_FILE <sys/exec.h>
+
+/* Data type of load average, as read out of kmem.  */
+#define LOAD_AVE_TYPE long
+
+#define ABORT_RETURN_TYPE __private_extern__ void
+
+/* Convert that into an integer that is 100 for a load average of 1.0  */
+#define LOAD_AVE_CVT(x) (int) (((double)(x)) * 100.0 / FSCALE)
+
+#define UNEXEC unexdyld.o
+
+/* Definitions for how to compile & link.  */
+
+/* Link this program just by running cc.  */
+#define ORDINARY_LINK
+
+/* #define C_SWITCH_SYSTEM */
+
+/* We don't have a g library, so override the -lg LIBS_DEBUG switch */
+#define LIBS_DEBUG
+
+/* Adding -lm confuses the dynamic linker, so omit it. */
+#define LIB_MATH
+
+/* Definitions for how to dump.  */
+
+#define START_FILES pre-crt0.o
+
+/* start_of_text isn't actually used, so make it compile without error.  */
+#define TEXT_START (0)
+
+/* This seems to be right for end_of_text, but it may not be used anyway.  */
+#define TEXT_END get_etext()
+
+/* This seems to be right for end_of_data, but it may not be used anyway.  */
+#define DATA_END get_edata()
+
+/* Don't close pty in process.c to make it a controlling terminal.  It is
+ * already the controlling terminal of the subprocess, because we did ioctl
+ * TIOCSCTTY.  */
+#define DONT_REOPEN_PTY
Index: emacs/src/s/rhapsody.h
===================================================================
RCS file: rhapsody.h
diff -N rhapsody.h
--- /dev/null	Tue Sep 17 14:45:13 2002
+++ emacs/src/s/rhapsody.h	Tue Sep 17 16:29:09 2002
@@ -0,0 +1,89 @@
+/* Configuration file for Mac OS X Server.
+   Copyright (C) 1997 Free Software Foundation, Inc.
+
+This file is part of GNU Emacs.
+
+GNU Emacs is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Emacs is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Emacs; see the file COPYING.  If not, write to
+the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA.  */
+
+/* We give these symbols the numeric values found in <sys/param.h> to
+   avoid warnings about redefined macros.  */
+#define BSD 199506
+#define BSD4_3 1
+#define BSD4_4 1
+
+#include "bsd4-3.h"
+
+/* SYSTEM_TYPE should indicate the kind of system you are using.
+   It sets the Lisp variable system-type.  We'll need to undo the bsd one. */
+
+#undef SYSTEM_TYPE
+#define SYSTEM_TYPE "apple-rhapsody"
+
+#ifndef RHAPSODY
+#define RHAPSODY
+#endif
+
+#define HAVE_ALLOCA
+
+#define HAVE_MACH_MACH_H
+
+#define SYSTEM_MALLOC
+
+#define WAIT_USE_INT
+
+#define SOCKLEN_TYPE int
+
+#define GETPGRP_NO_ARG
+
+#define TERMCAP_FILE "/usr/share/misc/termcap"
+
+#define PENDING_OUTPUT_COUNT(FILE) ((FILE)->_p - (FILE)->_bf._base)
+
+#define A_OUT_H_FILE <sys/exec.h>
+
+/* Data type of load average, as read out of kmem.  */
+#define LOAD_AVE_TYPE long
+
+/* Convert that into an integer that is 100 for a load average of 1.0  */
+#define LOAD_AVE_CVT(x) (int) (((double)(x)) * 100.0 / FSCALE)
+
+#define UNEXEC unexdyld.o
+
+/* Definitions for how to compile & link.  */
+
+/* Link this program just by running cc.  */
+#define ORDINARY_LINK
+
+/* #define C_SWITCH_SYSTEM */
+
+/* We don't have a g library, so override the -lg LIBS_DEBUG switch */
+#define LIBS_DEBUG
+
+/* Adding -lm confuses the dynamic linker, so omit it. */
+#define LIB_MATH
+
+/* Definitions for how to dump.  */
+
+#define START_FILES pre-crt0.o
+
+/* start_of_text isn't actually used, so make it compile without error.  */
+#define TEXT_START (0)
+
+/* This seems to be right for end_of_text, but it may not be used anyway.  */
+#define TEXT_END get_etext()
+
+/* This seems to be right for end_of_data, but it may not be used anyway.  */
+#define DATA_END get_edata()
Index: emacs/configure
--- configure.orig	Tue Oct 19 23:56:50 2004
+++ configure	Tue Oct 19 23:58:32 2004
@@ -1179,6 +1179,24 @@
     machine=hp800 opsys=nextstep
   ;;
 
+  ## Mac OS X Server
+  *-*-rhapsody*)
+     opsys=rhapsody
+     case "${canonical}" in
+       powerpc-*-rhapsody*) machine=powermacintosh ;;
+       i386-*-rhapsody*)    machine=intel386 ;;
+     esac
+   ;;
+ 
+   ## Darwin / Mac OS X
+   *-*-darwin*)
+     opsys=darwin
+     case "${canonical}" in
+       powerpc-*-darwin*) machine=powermacintosh ;;
+       i?86-*-darwin*)    machine=intel386 ;;
+     esac
+   ;;
+
   ## Orion machines
   orion-orion-bsd* )
     machine=orion opsys=bsd4-2
Index: emacs/configure.in
--- configure.in.orig	Tue Oct 19 23:56:54 2004
+++ configure.in	Tue Oct 19 23:59:29 2004
@@ -553,6 +553,24 @@
     machine=hp800 opsys=nextstep
   ;;
 
+   ## Mac OS X Server
+   *-*-rhapsody*)
+     opsys=rhapsody
+     case "${canonical}" in
+       powerpc-*-rhapsody*) machine=powermacintosh ;;
+       i386-*-rhapsody*)    machine=intel386 ;;
+     esac
+   ;;
+ 
+   ## Darwin / Mac OS X
+   *-*-darwin*)
+     opsys=darwin
+     case "${canonical}" in
+       powerpc-*-darwin*) machine=powermacintosh ;;
+       i?86-*-darwin*)    machine=intel386 ;;
+     esac
+   ;;
+
   ## Orion machines
   orion-orion-bsd* )
     machine=orion opsys=bsd4-2
