(scan_lists): Follow coding convention.
[bpt/emacs.git] / src / unexec.c
index aa41700..2ca70b7 100644 (file)
@@ -1,10 +1,11 @@
-/* Copyright (C) 1985,86,87,88,92,93,94 Free Software Foundation, Inc.
+/* Copyright (C) 1985, 1986, 1987, 1988, 1992, 1993, 1994, 2001, 2002, 2003,
+                 2004, 2005, 2006, 2007, 2008  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)
+the Free Software Foundation; either version 3, or (at your option)
 any later version.
 
 GNU Emacs is distributed in the hope that it will be useful,
@@ -14,8 +15,8 @@ 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 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+Boston, MA 02110-1301, USA.  */
 
 
 /*
@@ -76,14 +77,6 @@ Boston, MA 02111-1307, USA.  */
 
 Define this if your system uses COFF for executables.
 
-* COFF_ENCAPSULATE
-
-Define this if you are using the GNU coff encapsulated a.out format.
-This is closer to a.out than COFF. You should *not* define COFF if
-you define COFF_ENCAPSULATE
-
-Otherwise we assume you use Berkeley format.
-
 * NO_REMAP
 
 Define this if you do not want to try to save Emacs's pure data areas
@@ -140,11 +133,6 @@ thus, the amount of offset can depend on the data in the file.
 If defined, this macro specifies the number of bytes to seek into the
 a.out file before starting to write the text segment.
 
-* EXEC_MAGIC
-
-For machines using COFF, this macro, if defined, is a value stored
-into the magic number field of the output file.
-
 * ADJUST_EXEC_HEADER
 
 This macro can be used to generate statements to adjust or
@@ -164,7 +152,6 @@ pointer looks like an int) but not on all machines.
 #ifndef emacs
 #define PERROR(arg) perror (arg); return -1
 #else
-#define IN_UNEXEC
 #include <config.h>
 #define PERROR(file) report_error (file, new)
 #endif
@@ -198,12 +185,7 @@ struct aouthdr
 };
 #endif /* not MSDOS */
 #else  /* not COFF */
-#ifdef COFF_ENCAPSULATE
-int need_coff_header = 1;
-#include <coff-encap/a.out.encap.h> /* The location might be a poor assumption */
-#else  /* not COFF_ENCAPSULATE */
 #include <a.out.h>
-#endif /* not COFF_ENCAPSULATE */
 #endif /* not COFF */
 
 /* Define getpagesize if the system does not.
@@ -268,11 +250,6 @@ extern char *sbrk ();
 
 #define SYMS_START ((long) N_SYMOFF (ohdr))
 
-/* Some machines override the structure name for an a.out header.  */
-#ifndef EXEC_HDR_TYPE
-#define EXEC_HDR_TYPE struct exec
-#endif
-
 #ifdef HPUX
 #ifdef HP9000S200_ID
 #define MY_ID HP9000S200_ID
@@ -284,11 +261,11 @@ static MAGIC OLDMAGIC = {MY_ID, SHARE_MAGIC};
 static MAGIC NEWMAGIC = {MY_ID, DEMAND_MAGIC};
 #define N_TXTOFF(x) TEXT_OFFSET(x)
 #define N_SYMOFF(x) LESYM_OFFSET(x)
-static EXEC_HDR_TYPE hdr, ohdr;
+static struct exec hdr, ohdr;
 
 #else /* not HPUX */
 
-#if defined (USG) && !defined (IBMAIX) && !defined (IRIS) && !defined (COFF_ENCAPSULATE) && !defined (GNU_LINUX)
+#if defined (USG) && !defined (IRIS) && !defined (GNU_LINUX)
 static struct bhdr hdr, ohdr;
 #define a_magic fmagic
 #define a_text tsize
@@ -302,20 +279,15 @@ static struct bhdr hdr, ohdr;
     (((x).fmagic)!=OMAGIC && ((x).fmagic)!=NMAGIC &&\
      ((x).fmagic)!=FMAGIC && ((x).fmagic)!=IMAGIC)
 #define NEWMAGIC FMAGIC
-#else /* IRIS or IBMAIX or not USG */
-static EXEC_HDR_TYPE hdr, ohdr;
+#else /* IRIS or not USG */
+static struct exec hdr, ohdr;
 #define NEWMAGIC ZMAGIC
-#endif /* IRIS or IBMAIX not USG */
+#endif /* IRIS or not USG */
 #endif /* not HPUX */
 
 static int unexec_text_start;
 static int unexec_data_start;
 
-#ifdef COFF_ENCAPSULATE
-/* coffheader is defined in the GNU a.out.encap.h file.  */
-struct coffheader coffheader;
-#endif
-
 #endif /* not COFF */
 
 static int pagemask;
@@ -367,48 +339,6 @@ static int copy_text_and_data ();
 static int copy_sym ();
 static void mark_x ();
 
-/* ****************************************************************
- * unexec
- *
- * driving logic.
- */
-unexec (new_name, a_name, data_start, bss_start, entry_address)
-     char *new_name, *a_name;
-     unsigned data_start, bss_start, entry_address;
-{
-  int new, a_out = -1;
-
-  if (a_name && (a_out = open (a_name, O_RDONLY)) < 0)
-    {
-      PERROR (a_name);
-    }
-  if ((new = creat (new_name, 0666)) < 0)
-    {
-      PERROR (new_name);
-    }
-
-  if (make_hdr (new, a_out, data_start, bss_start, entry_address, a_name, new_name) < 0
-      || copy_text_and_data (new, a_out) < 0
-      || copy_sym (new, a_out, a_name, new_name) < 0
-#ifdef COFF
-#ifndef COFF_BSD_SYMBOLS
-      || adjust_lnnoptrs (new, a_out, new_name) < 0
-#endif
-#endif
-      )
-    {
-      close (new);
-      /* unlink (new_name);            /* Failed, unlink new a.out */
-      return -1;
-    }
-
-  close (new);
-  if (a_out >= 0)
-    close (a_out);
-  mark_x (new_name);
-  return 0;
-}
-
 /* ****************************************************************
  * make_hdr
  *
@@ -563,12 +493,6 @@ make_hdr (new, a_out, data_start, bss_start, entry_address, a_name, new_name)
 #endif
 
   f_hdr.f_flags |= (F_RELFLG | F_EXEC);
-#ifdef TPIX
-  f_hdr.f_nscns = 3;
-#endif
-#ifdef EXEC_MAGIC
-  f_ohdr.magic = EXEC_MAGIC;
-#endif
 #ifndef NO_REMAP
   f_ohdr.text_start = (long) start_of_text ();
   f_ohdr.tsize = data_start - f_ohdr.text_start;
@@ -576,13 +500,11 @@ make_hdr (new, a_out, data_start, bss_start, entry_address, a_name, new_name)
 #endif /* NO_REMAP */
   f_ohdr.dsize = bss_start - f_ohdr.data_start;
   f_ohdr.bsize = bss_end - bss_start;
-#ifndef KEEP_OLD_TEXT_SCNPTR
   /* On some machines, the old values are right.
      ??? Maybe on all machines with NO_REMAP.  */
   f_thdr.s_size = f_ohdr.tsize;
   f_thdr.s_scnptr = sizeof (f_hdr) + sizeof (f_ohdr);
   f_thdr.s_scnptr += (f_hdr.f_nscns) * (sizeof (f_thdr));
-#endif /* KEEP_OLD_TEXT_SCNPTR */
 #ifdef ADJUST_TEXT_SCNHDR_SIZE
   /* On some machines, `text size' includes all headers.  */
   f_thdr.s_size -= f_thdr.s_scnptr;
@@ -594,16 +516,8 @@ make_hdr (new, a_out, data_start, bss_start, entry_address, a_name, new_name)
   f_thdr.s_scnptr
     = (f_thdr.s_scnptr + SECTION_ALIGNMENT) & ~SECTION_ALIGNMENT;
 #endif /* SECTION_ALIGNMENT */
-#ifdef TPIX
-  f_thdr.s_scnptr = 0xd0;
-#endif
   text_scnptr = f_thdr.s_scnptr;
-#ifdef ADJUST_TEXTBASE
-  text_scnptr = sizeof (f_hdr) + sizeof (f_ohdr) + (f_hdr.f_nscns) * (sizeof (f_thdr));
-#endif
-#ifndef KEEP_OLD_PADDR
   f_dhdr.s_paddr = f_ohdr.data_start;
-#endif /* KEEP_OLD_PADDR */
   f_dhdr.s_vaddr = f_ohdr.data_start;
   f_dhdr.s_size = f_ohdr.dsize;
   f_dhdr.s_scnptr = f_thdr.s_scnptr + f_thdr.s_size;
@@ -620,9 +534,7 @@ make_hdr (new, a_out, data_start, bss_start, entry_address, a_name, new_name)
     = (f_dhdr.s_scnptr + DATA_SECTION_ALIGNMENT) & ~DATA_SECTION_ALIGNMENT;
 #endif /* DATA_SECTION_ALIGNMENT */
   data_scnptr = f_dhdr.s_scnptr;
-#ifndef KEEP_OLD_PADDR
   f_bhdr.s_paddr = f_ohdr.data_start + f_ohdr.dsize;
-#endif /* KEEP_OLD_PADDR */
   f_bhdr.s_vaddr = f_ohdr.data_start + f_ohdr.dsize;
   f_bhdr.s_size = f_ohdr.bsize;
   f_bhdr.s_scnptr = 0L;
@@ -727,16 +639,6 @@ make_hdr (new, a_out, data_start, bss_start, entry_address, a_name, new_name)
   /* Get symbol table info from header of a.out file if given one. */
   if (a_out >= 0)
     {
-#ifdef COFF_ENCAPSULATE
-      if (read (a_out, &coffheader, sizeof coffheader) != sizeof coffheader)
-       {
-         PERROR(a_name);
-       }
-      if (coffheader.f_magic != COFF_MAGIC)
-       {
-         ERROR1("%s doesn't have legal coff magic number\n", a_name);
-       }
-#endif
       if (read (a_out, &ohdr, sizeof hdr) != sizeof hdr)
        {
          PERROR (a_name);
@@ -750,17 +652,10 @@ make_hdr (new, a_out, data_start, bss_start, entry_address, a_name, new_name)
     }
   else
     {
-#ifdef COFF_ENCAPSULATE
-      /* We probably could without too much trouble. The code is in gld
-       * but I don't have that much time or incentive.
-       */
-      ERROR0 ("can't build a COFF file from scratch yet");
-#else
 #ifdef MSDOS   /* Demacs 1.1.1 91/10/16 HIRANO Satoshi */
       bzero ((void *)&hdr, sizeof hdr);
 #else
       bzero (&hdr, sizeof hdr);
-#endif
 #endif
     }
 
@@ -790,32 +685,6 @@ make_hdr (new, a_out, data_start, bss_start, entry_address, a_name, new_name)
 
 #endif /* not NO_REMAP */
 
-#ifdef COFF_ENCAPSULATE
-  /* We are encapsulating BSD format within COFF format.  */
-  {
-    struct coffscn *tp, *dp, *bp;
-    tp = &coffheader.scns[0];
-    dp = &coffheader.scns[1];
-    bp = &coffheader.scns[2];
-    tp->s_size = hdr.a_text + sizeof(struct exec);
-    dp->s_paddr = data_start;
-    dp->s_vaddr = data_start;
-    dp->s_size = hdr.a_data;
-    bp->s_paddr = dp->s_vaddr + dp->s_size;
-    bp->s_vaddr = bp->s_paddr;
-    bp->s_size = hdr.a_bss;
-    coffheader.tsize = tp->s_size;
-    coffheader.dsize = dp->s_size;
-    coffheader.bsize = bp->s_size;
-    coffheader.text_start = tp->s_vaddr;
-    coffheader.data_start = dp->s_vaddr;
-  }
-  if (write (new, &coffheader, sizeof coffheader) != sizeof coffheader)
-    {
-      PERROR(new_name);
-    }
-#endif /* COFF_ENCAPSULATE */
-
   if (write (new, &hdr, sizeof hdr) != sizeof hdr)
     {
       PERROR (new_name);
@@ -835,6 +704,61 @@ make_hdr (new, a_out, data_start, bss_start, entry_address, a_name, new_name)
 #endif /* not COFF */
 }
 \f
+write_segment (new, ptr, end)
+     int new;
+     register char *ptr, *end;
+{
+  register int i, nwrite, ret;
+  char buf[80];
+#ifndef USE_CRT_DLL
+  extern int errno;
+#endif
+  /* This is the normal amount to write at once.
+     It is the size of block that NFS uses.  */
+  int writesize = 1 << 13;
+  int pagesize = getpagesize ();
+  char zeros[1 << 13];
+
+  bzero (zeros, sizeof (zeros));
+
+  for (i = 0; ptr < end;)
+    {
+      /* Distance to next multiple of writesize.  */
+      nwrite = (((int) ptr + writesize) & -writesize) - (int) ptr;
+      /* But not beyond specified end.  */
+      if (nwrite > end - ptr) nwrite = end - ptr;
+      ret = write (new, ptr, nwrite);
+      /* If write gets a page fault, it means we reached
+        a gap between the old text segment and the old data segment.
+        This gap has probably been remapped into part of the text segment.
+        So write zeros for it.  */
+      if (ret == -1
+#ifdef EFAULT
+         && errno == EFAULT
+#endif
+         )
+       {
+         /* Write only a page of zeros at once,
+            so that we we don't overshoot the start
+            of the valid memory in the old data segment.  */
+         if (nwrite > pagesize)
+           nwrite = pagesize;
+         write (new, zeros, nwrite);
+       }
+#if 0 /* Now that we have can ask `write' to write more than a page,
+        it is legit for write do less than the whole amount specified.  */
+      else if (nwrite != ret)
+       {
+         sprintf (buf,
+                  "unexec write failure: addr 0x%x, fileno %d, size 0x%x, wrote 0x%x, errno %d",
+                  ptr, new, nwrite, ret, errno);
+         PERROR (buf);
+       }
+#endif
+      i += nwrite;
+      ptr += nwrite;
+    }
+}
 /* ****************************************************************
  * copy_text_and_data
  *
@@ -921,10 +845,6 @@ copy_text_and_data (new, a_out)
 
   lseek (new, (long) text_scnptr, 0);
   ptr = (char *) f_ohdr.text_start;
-#ifdef HEADER_INCL_IN_TEXT
-  /* For Gould UTX/32, text starts after headers */
-  ptr = (char *) (ptr + text_scnptr);
-#endif /* HEADER_INCL_IN_TEXT */
   end = ptr + f_ohdr.tsize;
   write_segment (new, ptr, end);
 
@@ -961,92 +881,9 @@ copy_text_and_data (new, a_out)
   lseek (new, (long) N_TXTOFF (hdr), 0);
 #endif /* no A_TEXT_SEEK */
 
-#ifdef RISCiX
-
-  /* Acorn's RISC-iX has a wacky way of initialising the position of the heap.
-   * There is a little table in crt0.o that is filled at link time with
-   * the min and current brk positions, among other things.  When start
-   * runs, it copies the table to where these parameters live during
-   * execution.  This data is in text space, so it cannot be modified here
-   * before saving the executable, so the data is written manually.  In
-   * addition, the table does not have a label, and the nearest accessible
-   * label (mcount) is not prefixed with a '_', thus making it inaccessible
-   * from within C programs.  To overcome this, emacs's executable is passed
-   * through the command 'nm %s | fgrep mcount' into a pipe, and the
-   * resultant output is then used to find the address of 'mcount'.  As far as
-   * is possible to determine, in RISC-iX releases prior to 1.2, the negative
-   * offset of the table from mcount is 0x2c, whereas from 1.2 onwards it is
-   * 0x30.  bss_end has been rounded up to page boundary.  This solution is
-   * based on suggestions made by Kevin Welton and Steve Hunt of Acorn, and
-   * avoids the need for a custom version of crt0.o for emacs which has its
-   * table in data space.
-   */
-
-  {
-    char command[1024];
-    char errbuf[1024];
-    char address_text[32];
-    int  proforma[4];
-    FILE *pfile;
-    char *temp_ptr;
-    char c;
-    int mcount_address, mcount_offset, count;
-    extern char *_execname;
-
-
-    /* The use of _execname is incompatible with RISCiX 1.1 */
-    sprintf (command, "nm %s | fgrep mcount", _execname);
-
-    if ( (pfile = popen(command, "r")) == NULL)
-    {
-      sprintf (errbuf, "Could not open pipe");
-      PERROR (errbuf);
-    }
-
-    count=0;
-    while ( ((c=getc(pfile)) != EOF) && (c != ' ') && (count < 31))
-      address_text[count++]=c;
-    address_text[count]=0;
-
-    if ((count == 0) || pclose(pfile) != NULL)
-    {
-      sprintf (errbuf, "Failed to execute the command '%s'\n", command);
-      PERROR (errbuf);
-    }
-
-    sscanf(address_text, "%x", &mcount_address);
-    ptr = (char *) unexec_text_start;
-    mcount_offset = (char *)mcount_address - ptr;
-
-#ifdef RISCiX_1_1
-#define EDATA_OFFSET 0x2c
-#else
-#define EDATA_OFFSET 0x30
-#endif
-
-    end = ptr + mcount_offset - EDATA_OFFSET;
-
-    write_segment (new, ptr, end);
-
-    proforma[0] = bss_end;     /* becomes _edata */
-    proforma[1] = bss_end;     /* becomes _end */
-    proforma[2] = bss_end;     /* becomes _minbrk */
-    proforma[3] = bss_end;     /* becomes _curbrk */
-
-    write (new, proforma, 16);
-
-    temp_ptr = ptr;
-    ptr = end + 16;
-    end = temp_ptr + hdr.a_text;
-
-    write_segment (new, ptr, end);
-  }
-
-#else /* !RISCiX */
   ptr = (char *) unexec_text_start;
   end = ptr + hdr.a_text;
   write_segment (new, ptr, end);
-#endif /* RISCiX */
 
   ptr = (char *) unexec_data_start;
   end = ptr + hdr.a_data;
@@ -1060,62 +897,6 @@ copy_text_and_data (new, a_out)
 
   return 0;
 }
-
-write_segment (new, ptr, end)
-     int new;
-     register char *ptr, *end;
-{
-  register int i, nwrite, ret;
-  char buf[80];
-#ifndef USE_CRT_DLL
-  extern int errno;
-#endif
-  /* This is the normal amount to write at once.
-     It is the size of block that NFS uses.  */
-  int writesize = 1 << 13;
-  int pagesize = getpagesize ();
-  char zeros[1 << 13];
-
-  bzero (zeros, sizeof (zeros));
-
-  for (i = 0; ptr < end;)
-    {
-      /* Distance to next multiple of writesize.  */
-      nwrite = (((int) ptr + writesize) & -writesize) - (int) ptr;
-      /* But not beyond specified end.  */
-      if (nwrite > end - ptr) nwrite = end - ptr;
-      ret = write (new, ptr, nwrite);
-      /* If write gets a page fault, it means we reached
-        a gap between the old text segment and the old data segment.
-        This gap has probably been remapped into part of the text segment.
-        So write zeros for it.  */
-      if (ret == -1
-#ifdef EFAULT
-         && errno == EFAULT
-#endif
-         )
-       {
-         /* Write only a page of zeros at once,
-            so that we we don't overshoot the start
-            of the valid memory in the old data segment.  */
-         if (nwrite > pagesize)
-           nwrite = pagesize;
-         write (new, zeros, nwrite);
-       }
-#if 0 /* Now that we have can ask `write' to write more than a page,
-        it is legit for write do less than the whole amount specified.  */
-      else if (nwrite != ret)
-       {
-         sprintf (buf,
-                  "unexec write failure: addr 0x%x, fileno %d, size 0x%x, wrote 0x%x, errno %d",
-                  ptr, new, nwrite, ret, errno);
-         PERROR (buf);
-       }
-#endif
-      i += nwrite;
-      ptr += nwrite;
-    }
-}
 \f
 /* ****************************************************************
  * copy_sym
@@ -1217,13 +998,8 @@ adjust_lnnoptrs (writedesc, readdesc, new_name)
 {
   register int nsyms;
   register int new;
-#if defined (amdahl_uts) || defined (pfa)
-  SYMENT symentry;
-  AUXENT auxentry;
-#else
   struct syment symentry;
   union auxent auxentry;
-#endif
 
   if (!lnnoptr || !f_hdr.f_symptr)
     return 0;
@@ -1264,4 +1040,49 @@ adjust_lnnoptrs (writedesc, readdesc, new_name)
 
 #endif /* COFF */
 
+/* ****************************************************************
+ * unexec
+ *
+ * driving logic.
+ */
+unexec (new_name, a_name, data_start, bss_start, entry_address)
+     char *new_name, *a_name;
+     unsigned data_start, bss_start, entry_address;
+{
+  int new, a_out = -1;
+
+  if (a_name && (a_out = open (a_name, O_RDONLY)) < 0)
+    {
+      PERROR (a_name);
+    }
+  if ((new = creat (new_name, 0666)) < 0)
+    {
+      PERROR (new_name);
+    }
+
+  if (make_hdr (new, a_out, data_start, bss_start, entry_address, a_name, new_name) < 0
+      || copy_text_and_data (new, a_out) < 0
+      || copy_sym (new, a_out, a_name, new_name) < 0
+#ifdef COFF
+#ifndef COFF_BSD_SYMBOLS
+      || adjust_lnnoptrs (new, a_out, new_name) < 0
+#endif
+#endif
+      )
+    {
+      close (new);
+      /* unlink (new_name);            /* Failed, unlink new a.out */
+      return -1;
+    }
+
+  close (new);
+  if (a_out >= 0)
+    close (a_out);
+  mark_x (new_name);
+  return 0;
+}
+
 #endif /* not CANNOT_DUMP */
+
+/* arch-tag: 62409b69-e27a-4a7c-9413-0210d6b54e7f
+   (do not change this comment) */