changeset 8836:2afe507ed505

Initial revision
author Richard M. Stallman <rms@gnu.org>
date Sat, 17 Sep 1994 00:59:56 +0000
parents 48bcdcb9d191
children a48847852901
files src/m/alpha.h src/unexalpha.c
diffstat 2 files changed, 641 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/m/alpha.h	Sat Sep 17 00:59:56 1994 +0000
@@ -0,0 +1,201 @@
+/* machine description file For the alpha chip.
+   Copyright (C) 1994 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 1, 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, 675 Mass Ave, Cambridge, MA 02139, USA.  */
+
+
+/* The following line tells the configuration script what sort of 
+   operating system this machine is likely to run.
+   USUAL-OPSYS="note"
+
+NOTE-START
+Use -opsystem=osf1
+NOTE-END
+
+*/
+
+/* The following three symbols give information on
+ the size of various data types.  */
+
+#define SHORTBITS 16		/* Number of bits in a short */
+
+#define INTBITS 32		/* Number of bits in an int */
+
+#define LONGBITS 64		/* Number of bits in a long */
+
+/* Define BIG_ENDIAN iff lowest-numbered byte in a word
+   is the most significant byte.  */
+
+/* Alpha is not big-endian #define 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
+
+/* Define WORD_MACHINE if addresses and such have
+ * to be corrected before they can be used as byte counts.  */
+
+/* #define WORD_MACHINE */
+
+/* Now define a symbol for the cpu type, if your compiler
+   does not define it automatically:
+   Ones defined so far include vax, m68000, ns16000, pyramid,
+   orion, tahoe, APOLLO and many others */
+
+/* __alpha defined automatically */
+
+
+/* Use type EMACS_INT rather than a union, to represent Lisp_Object */
+/* This is desirable for most machines.  */
+
+#define NO_UNION_TYPE
+
+/* Define the type to use.  */
+#define EMACS_INT long
+#define EMACS_UINT unsigned long
+
+/* Define EXPLICIT_SIGN_EXTEND if XINT must explicitly sign-extend
+   the 24-bit bit field into an int.  In other words, if bit fields
+   are always unsigned.
+
+   If you use NO_UNION_TYPE, this flag does not matter.  */
+
+#define EXPLICIT_SIGN_EXTEND
+
+/* 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 CANNOT_DUMP on machines where unexec does not work.
+   Then the function dump-emacs will not be defined
+   and temacs will do (load "loadup") automatically unless told otherwise.  */
+
+/* #define CANNOT_DUMP */
+
+/* Define VIRT_ADDR_VARIES if the virtual addresses of
+   pure and impure space as loaded can vary, and even their
+   relative order cannot be relied on.
+
+   Otherwise Emacs assumes that text space precedes data space,
+   numerically.  */
+
+/* #define VIRT_ADDR_VARIES */
+
+/* Define C_ALLOCA if this machine does not support a true alloca
+   and the one written in C should be used instead.
+   Define HAVE_ALLOCA to say that the system provides a properly
+   working alloca function and it should be used.
+   Define neither one if an assembler-language alloca
+   in the file alloca.s should be used.  */
+
+#define HAVE_ALLOCA
+
+/* GNU malloc and the relocating allocator do not work together
+   with X. */
+
+#define SYSTEM_MALLOC
+
+/* Define NO_REMAP if memory segmentation makes it not work well
+   to change the boundary between the text section and data section
+   when Emacs is dumped.  If you define this, the preloaded Lisp
+   code will not be sharable; but that's better than failing completely.  */
+
+#define NO_REMAP
+
+/* Some really obscure 4.2-based systems (like Sequent DYNIX)
+ * do not support asynchronous I/O (using SIGIO) on sockets,
+ * even though it works fine on tty's.  If you have one of
+ * these systems, define the following, and then use it in
+ * config.h (or elsewhere) to decide when (not) to use SIGIO.
+ *
+ * You'd think this would go in an operating-system description file,
+ * but since it only occurs on some, but not all, BSD systems, the
+ * reasonable place to select for it is in the machine description
+ * file.
+ */
+
+/* #define NO_SOCK_SIGIO */
+
+
+#define HAVE_X11R4
+#define HAVE_X11R5
+
+
+/* Describe layout of the address space in an executing process.  */
+
+#define TEXT_START    0x120000000
+#define DATA_START    0x140000000
+
+/* This is necessary for mem-limits.h, so that start_of_data gives
+   the correct value */
+
+#define DATA_SEG_BITS 0x140000000
+
+
+#define ORDINARY_LINK
+
+#define LIBS_DEBUG
+#define START_FILES pre-crt0.o
+
+
+/* The program to be used for unexec. */
+
+#define UNEXEC unexalpha.o
+
+
+#define PNTR_COMPARISON_TYPE unsigned long
+
+/* On the 64 bit architecture, we can use 56 bits for addresses */
+
+#define VALBITS         56
+
+
+/* This definition of MARKBIT is necessary because of the comparison of
+   ARRAY_MARK_FLAG and MARKBIT in an #if in lisp.h, which cpp doesn't like. */
+
+#define MARKBIT         0x8000000000000000L
+
+
+/* Define XINT and XUINT so that they can take arguments of type int */
+
+#define XINT(a)         (((long)(a) << LONGBITS-VALBITS) >> LONGBITS-VALBITS)
+#define XUINT(a)        ((long)(a) & VALMASK)
+
+/* Define XPNTR to avoid or'ing with DATA_SEG_BITS */
+
+#define XPNTR(a) XUINT (a)
+
+
+/* Similarly, for XSETINT */
+
+#define XSETINT(a, b)   ((a) = (long)((a) & ~VALMASK) | (long)((b) & VALMASK))
+
+
+/* Make PURESIZE twice as large, as pointers are 64 bit */
+
+#ifdef MULTI_FRAME
+#define PURESIZE 460000
+#else
+#define PURESIZE 400000
+#endif
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/unexalpha.c	Sat Sep 17 00:59:56 1994 +0000
@@ -0,0 +1,440 @@
+/* Unexec for DEC alpha.  schoepf@sc.ZIB-Berlin.DE (Rainer Schoepf).
+
+   Copyright (C) 1994 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, 675 Mass Ave, Cambridge, MA 02139, USA.  */
+
+
+#include <config.h>
+#include <sys/types.h>
+#include <sys/file.h>
+#include <sys/stat.h>
+#include <sys/mman.h>
+#include <stdio.h>
+#include <varargs.h>
+#include <filehdr.h>
+#include <aouthdr.h>
+#include <scnhdr.h>
+#include <syms.h>
+
+static void fatal_unexec ();
+static void mark_x ();
+
+#define READ(_fd, _buffer, _size, _error_message, _error_arg) \
+	errno = EEOF; \
+	if (read (_fd, _buffer, _size) != _size) \
+	  fatal_unexec (_error_message, _error_arg);
+
+#define WRITE(_fd, _buffer, _size, _error_message, _error_arg) \
+	if (write (_fd, _buffer, _size) != _size) \
+	  fatal_unexec (_error_message, _error_arg);
+
+#define SEEK(_fd, _position, _error_message, _error_arg) \
+	errno = EEOF; \
+	if (lseek (_fd, _position, L_SET) != _position) \
+	  fatal_unexec (_error_message, _error_arg);
+
+extern int errno;
+extern char *strerror ();
+
+void *sbrk();
+
+#define EEOF -1
+
+static struct scnhdr *text_section;
+static struct scnhdr *init_section;
+static struct scnhdr *finit_section;
+static struct scnhdr *rdata_section;
+static struct scnhdr *data_section;
+static struct scnhdr *pdata_section;
+static struct scnhdr *xdata_section;
+static struct scnhdr *got_section;
+static struct scnhdr *lit8_section;
+static struct scnhdr *lit4_section;
+static struct scnhdr *sdata_section;
+static struct scnhdr *sbss_section;
+static struct scnhdr *bss_section;
+
+static unsigned int Brk;
+
+struct headers {
+    struct filehdr fhdr;
+    struct aouthdr aout;
+    struct scnhdr section[_MIPS_NSCNS_MAX];
+};
+
+
+
+/* Define name of label for entry point for the dumped executable.  */
+
+#ifndef DEFAULT_ENTRY_ADDRESS
+#define DEFAULT_ENTRY_ADDRESS __start
+#endif
+
+unexec (new_name, a_name, data_start, bss_start, entry_address)
+     char *new_name, *a_name;
+     unsigned long data_start, bss_start, entry_address;
+{
+  int new, old;
+  char * oldptr;
+  struct headers ohdr, nhdr;
+  struct stat stat;
+  long pagesize, brk;
+  long newsyms, symrel;
+  int nread;
+  int i;
+  long vaddr, scnptr;
+#define BUFSIZE 8192
+  char buffer[BUFSIZE];
+
+  if ((old = open (a_name, O_RDONLY)) < 0)
+    fatal_unexec ("opening %s", a_name);
+
+  new = creat (new_name, 0666);
+  if (new < 0) fatal_unexec ("creating %s", new_name);
+
+  if ((fstat (old, &stat) == -1))
+    fatal_unexec ("fstat %s", a_name);
+
+  oldptr = (char *)mmap (0, stat.st_size, PROT_READ, MAP_FILE|MAP_SHARED, old, 0);
+
+  if (oldptr == (char *)-1)
+    fatal_unexec ("mmap %s", a_name);
+
+  close (old);
+
+  /* This is a copy of the a.out header of the original executable */
+
+  ohdr = (*(struct headers *)oldptr);
+
+  /* This is where we build the new header from the in-memory copy */
+
+  nhdr = *((struct headers *)TEXT_START);
+
+  /* First do some consistency checks */
+
+  if (nhdr.fhdr.f_magic != ALPHAMAGIC
+      && nhdr.fhdr.f_magic != ALPHAUMAGIC)
+    {
+      fprintf (stderr, "unexec: input file magic number is %x, not %x or %x.\n",
+	       nhdr.fhdr.f_magic, ALPHAMAGIC, ALPHAUMAGIC);
+      exit (1);
+    }
+
+  if (nhdr.fhdr.f_opthdr != sizeof (nhdr.aout))
+    {
+      fprintf (stderr, "unexec: input a.out header is %d bytes, not %d.\n",
+	       nhdr.fhdr.f_opthdr, sizeof (nhdr.aout));
+      exit (1);
+    }
+  if (nhdr.aout.magic != ZMAGIC)
+    {
+      fprintf (stderr, "unexec: input file a.out magic number is %o, not %o.\n",
+	       nhdr.aout.magic, ZMAGIC);
+      exit (1);
+    }
+
+
+  /* Now check the existence of certain header section and grab
+     their addresses. */
+
+#define CHECK_SCNHDR(ptr, name, flags)					\
+  ptr = NULL;								\
+  for (i = 0; i < nhdr.fhdr.f_nscns && !ptr; i++)			\
+    if (strcmp (nhdr.section[i].s_name, name) == 0)			\
+      {									\
+	if (nhdr.section[i].s_flags != flags)				\
+	  fprintf (stderr, "unexec: %x flags (%x expected) in %s section.\n", \
+		   nhdr.section[i].s_flags, flags, name);		\
+	ptr = nhdr.section + i;						\
+      }									\
+
+  CHECK_SCNHDR (text_section,  _TEXT,  STYP_TEXT);
+  CHECK_SCNHDR (init_section,  _INIT,  STYP_INIT);
+#ifdef _FINI
+  CHECK_SCNHDR (finit_section, _FINI,  STYP_FINI);
+#endif /* _FINI */
+  CHECK_SCNHDR (rdata_section, _RDATA, STYP_RDATA);
+#ifdef _PDATA
+  CHECK_SCNHDR (pdata_section, _PDATA, STYP_PDATA);
+#endif _PDATA
+#ifdef _GOT
+  CHECK_SCNHDR (got_section,   _GOT,   STYP_GOT);
+#endif _GOT
+  CHECK_SCNHDR (data_section,  _DATA,  STYP_DATA);
+#ifdef _XDATA
+  CHECK_SCNHDR (xdata_section, _XDATA, STYP_XDATA);
+#endif /* _XDATA */
+#ifdef _LIT8
+  CHECK_SCNHDR (lit8_section,  _LIT8,  STYP_LIT8);
+  CHECK_SCNHDR (lit4_section,  _LIT4,  STYP_LIT4);
+#endif /* _LIT8 */
+  CHECK_SCNHDR (sdata_section, _SDATA, STYP_SDATA);
+  CHECK_SCNHDR (sbss_section,  _SBSS,  STYP_SBSS);
+  CHECK_SCNHDR (bss_section,   _BSS,   STYP_BSS);
+#if 0 /* Apparently this error check goes off on irix 3.3,
+	 but it doesn't indicate a real problem.  */
+  if (i != nhdr.fhdr.f_nscns)
+    fprintf (stderr, "unexec: %d sections found instead of %d.\n",
+	     i, nhdr.fhdr.f_nscns);
+#endif
+
+
+  pagesize = getpagesize ();
+  brk = (((long) (sbrk (0))) + pagesize - 1) & (-pagesize);
+
+  /* Remember the current break */
+
+  Brk = brk;
+
+  nhdr.aout.dsize = brk - DATA_START;
+  nhdr.aout.bsize = 0;
+  if (entry_address == 0)
+    {
+      extern DEFAULT_ENTRY_ADDRESS ();
+      nhdr.aout.entry = (unsigned long)DEFAULT_ENTRY_ADDRESS;
+    }
+  else
+    nhdr.aout.entry = entry_address;
+
+  nhdr.aout.bss_start = nhdr.aout.data_start + nhdr.aout.dsize;
+  rdata_section->s_size = data_start - DATA_START;
+
+  /* Adjust start and virtual addresses of rdata_section, too.  */
+  rdata_section->s_vaddr = DATA_START;
+  rdata_section->s_paddr = DATA_START;
+  rdata_section->s_scnptr = text_section->s_scnptr + nhdr.aout.tsize;
+
+  data_section->s_vaddr = data_start;
+  data_section->s_paddr = data_start;
+  data_section->s_size = brk - data_start;
+  data_section->s_scnptr = rdata_section->s_scnptr + rdata_section->s_size;
+  vaddr = data_section->s_vaddr + data_section->s_size;
+  scnptr = data_section->s_scnptr + data_section->s_size;
+  if (lit8_section != NULL)
+    {
+      lit8_section->s_vaddr = vaddr;
+      lit8_section->s_paddr = vaddr;
+      lit8_section->s_size = 0;
+      lit8_section->s_scnptr = scnptr;
+    }
+  if (lit4_section != NULL)
+    {
+      lit4_section->s_vaddr = vaddr;
+      lit4_section->s_paddr = vaddr;
+      lit4_section->s_size = 0;
+      lit4_section->s_scnptr = scnptr;
+    }
+  if (sdata_section != NULL)
+    {
+      sdata_section->s_vaddr = vaddr;
+      sdata_section->s_paddr = vaddr;
+      sdata_section->s_size = 0;
+      sdata_section->s_scnptr = scnptr;
+    }
+#ifdef _XDATA
+  if (xdata_section != NULL)
+    {
+      xdata_section->s_vaddr = vaddr;
+      xdata_section->s_paddr = vaddr;
+      xdata_section->s_size = 0;
+      xdata_section->s_scnptr = scnptr;
+    }
+#endif
+#ifdef _GOT
+  if (got_section != NULL)
+    {
+      got_section->s_vaddr = vaddr;
+      got_section->s_paddr = vaddr;
+      got_section->s_size = 0;
+      got_section->s_scnptr = scnptr;
+    }
+#endif /*_GOT */
+  if (sbss_section != NULL)
+    {
+      sbss_section->s_vaddr = vaddr;
+      sbss_section->s_paddr = vaddr;
+      sbss_section->s_size = 0;
+      sbss_section->s_scnptr = scnptr;
+    }
+  if (bss_section != NULL)
+    {
+      bss_section->s_vaddr = vaddr;
+      bss_section->s_paddr = vaddr;
+      bss_section->s_size = 0;
+      bss_section->s_scnptr = scnptr;
+    }
+
+  WRITE (new, (char *)TEXT_START, nhdr.aout.tsize,
+	 "writing text section to %s", new_name);
+  WRITE (new, (char *)DATA_START, nhdr.aout.dsize,
+	 "writing data section to %s", new_name);
+
+
+  /*
+   * Construct new symbol table header
+   */
+
+  bcopy (oldptr + nhdr.fhdr.f_symptr, buffer, cbHDRR);
+
+#define symhdr ((pHDRR)buffer)
+  newsyms = nhdr.aout.tsize + nhdr.aout.dsize;
+  symrel = newsyms - nhdr.fhdr.f_symptr;
+  nhdr.fhdr.f_symptr = newsyms;
+  symhdr->cbLineOffset += symrel;
+  symhdr->cbDnOffset += symrel;
+  symhdr->cbPdOffset += symrel;
+  symhdr->cbSymOffset += symrel;
+  symhdr->cbOptOffset += symrel;
+  symhdr->cbAuxOffset += symrel;
+  symhdr->cbSsOffset += symrel;
+  symhdr->cbSsExtOffset += symrel;
+  symhdr->cbFdOffset += symrel;
+  symhdr->cbRfdOffset += symrel;
+  symhdr->cbExtOffset += symrel;
+
+  WRITE (new, buffer, cbHDRR, "writing symbol table header of %s", new_name);
+
+  /*
+   * Copy the symbol table and line numbers
+   */
+  WRITE (new, oldptr + ohdr.fhdr.f_symptr + cbHDRR,
+	 stat.st_size - ohdr.fhdr.f_symptr - cbHDRR,
+	 "writing symbol table of %s", new_name);
+
+#if 0
+
+/* Not needed for now */
+
+  update_dynamic_symbols (oldptr, new, newsyms,
+			  ((pHDRR) (oldptr + ohdr.fhdr.f_symptr))->issExtMax,
+                          ((pHDRR) (oldptr + ohdr.fhdr.f_symptr))->cbExtOffset,
+                          ((pHDRR) (oldptr + ohdr.fhdr.f_symptr))->cbSsExtOffset);
+
+#endif
+
+#undef symhdr
+
+  SEEK (new, 0, "seeking to start of header in %s", new_name);
+  WRITE (new, &nhdr, sizeof (nhdr),
+	 "writing header of %s", new_name);
+
+  close (old);
+  close (new);
+  mark_x (new_name);
+}
+
+
+#if 0
+
+/* Not needed for now */
+
+/* The following function updates the values of some symbols
+   that are used by the dynamic loader:
+
+   _edata
+   _end
+
+*/
+
+
+update_dynamic_symbols (old, new, newsyms, nsyms, symoff, stroff)
+char *old;			/* Pointer to old executable */
+int new;			/* File descriptor for new executable */
+long newsyms;			/* Offset of Symbol table in new executable */
+int nsyms;			/* Number of symbol table entries */
+long symoff;			/* Offset of External Symbols in old file */
+long stroff;			/* Offset of string table in old file */
+{
+  long i;
+  int found = 0;
+  EXTR n_end, n_edata;
+
+  /* We go through the symbol table entries until we have found the two
+     symbols. */
+
+  /* cbEXTR is the size of an external symbol table entry */
+
+  for (i = 0; i < nsyms && found < 2; i += cbEXTR)
+    {
+      register pEXTR x = (pEXTR) (old + symoff + i);
+      char *s;
+  
+      s = old + stroff + x->asym.iss; /* name of the symbol */
+
+      if (!strcmp(s,"_edata"))
+	{
+	  found++;
+          bcopy (x, &n_edata, cbEXTR);
+	  n_edata.asym.value = Brk;
+	  SEEK (new, newsyms + cbHDRR + i,
+		"seeking to symbol _edata in %s", new_name);
+	  WRITE (new, n_edata, cbEXTR,
+		 "writing symbol table entry for _edata into %s", new_name);
+	}
+      else if (!strcmp(s,"_end"))
+	{
+	  found++;
+          bcopy (x, &n_end, cbEXTR);
+	  n_end.asym.value = Brk;
+	  SEEK (new, newsyms + cbHDRR + i,
+		"seeking to symbol _end in %s", new_name);
+	  WRITE (new, n_end, cbEXTR,
+		 "writing symbol table entry for _end into %s", new_name);
+	}
+    }
+
+}
+
+#endif
+
+
+/*
+ * mark_x
+ *
+ * After successfully building the new a.out, mark it executable
+ */
+
+static void
+mark_x (name)
+     char *name;
+{
+  struct stat sbuf;
+  int um = umask (777);
+  umask (um);
+  if (stat (name, &sbuf) < 0)
+    fatal_unexec ("getting protection on %s", name);
+  sbuf.st_mode |= 0111 & ~um;
+  if (chmod (name, sbuf.st_mode) < 0)
+    fatal_unexec ("setting protection on %s", name);
+}
+
+static void
+fatal_unexec (s, va_alist)
+    va_dcl
+{
+  va_list ap;
+  if (errno == EEOF)
+    fputs ("unexec: unexpected end of file, ", stderr);
+  else
+    fprintf (stderr, "unexec: %s, ", strerror (errno));
+  va_start (ap);
+  _doprnt (s, ap, stderr);
+  fputs (".\n", stderr);
+  exit (1);
+}
+