emacs-diffs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Emacs-diffs] Changes to unexsunos4.c


From: Dan Nicolaescu
Subject: [Emacs-diffs] Changes to unexsunos4.c
Date: Sun, 13 Jan 2008 17:39:06 +0000

CVSROOT:        /cvsroot/emacs
Module name:    emacs
Changes by:     Dan Nicolaescu <dann>   08/01/13 17:39:05

Index: unexsunos4.c
===================================================================
RCS file: unexsunos4.c
diff -N unexsunos4.c
--- unexsunos4.c        8 Jan 2008 20:44:27 -0000       1.27
+++ /dev/null   1 Jan 1970 00:00:00 -0000
@@ -1,381 +0,0 @@
-/* Unexec for Sunos 4 using shared libraries.
-   Copyright (C) 1990, 1994, 1999, 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 3, 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., 51 Franklin Street, Fifth Floor,
-Boston, MA 02110-1301, USA.  */
-
-/* Contributed by Viktor Dukhovni.  */
-/*
- * Unexec for Berkeley a.out format + SUNOS shared libraries
- * The unexeced executable contains the __DYNAMIC area from the
- * original text file,  and then the rest of data + bss + malloced area of
- * the current process.  (The __DYNAMIC area is at the top of the process
- * data segment,  we use "data_start" defined externally to mark the start
- * of the "real" data segment.)
- *
- * For programs that want to remap some of the data segment read only
- * a run_time_remap is provided.  This attempts to remap largest area starting
- * and ending on page boundaries between "data_start" and "bndry"
- * For this it to figure out where the text file is located.  A path search
- * is attempted after trying argv[0] and if all fails we simply do not remap
- *
- * One feature of run_time_remap () is mandatory:  reseting the break.
- *
- *  Note that we can no longer map data into the text segment,  as this causes
- *  the __DYNAMIC struct to become read only,  breaking the runtime loader.
- *  Thus we no longer need to mess with a private crt0.c,  the standard one
- *  will do just fine,  since environ can live in the writable area between
- *  __DYNAMIC and data_start,  just make sure that pre-crt0.o (the name
- *  is somewhat abused here) is loaded first!
- *
- */
-
-#ifdef emacs
-#include <config.h>
-#endif
-
-#include <sys/param.h>
-#include <sys/mman.h>
-#include <sys/file.h>
-#include <sys/stat.h>
-#include <string.h>
-#include <stdio.h>
-#include <a.out.h>
-
-#if defined (SUNOS4) || defined (__FreeBSD__) || defined (__NetBSD__)
-#define UNDO_RELOCATION
-#endif
-
-#ifdef UNDO_RELOCATION
-#include <link.h>
-#endif
-
-#ifdef HAVE_UNISTD_H
-#include <unistd.h>
-#endif
-
-/* NetBSD needs this bit, but SunOS does not have it.  */
-#ifndef MAP_FILE
-#define MAP_FILE 0
-#endif
-
-
-/*
- * for programs other than emacs
- * define data_start + initialized here,  and make sure
- * this object is loaded first!
- * emacs will define these elsewhere,  and load the object containing
- * data_start (pre-crt0.o or firstfile.o?) first!
- * The custom crt0.o *must not* be loaded!
- */
-#ifndef emacs
-  static int data_start = 0;
-  static int initialized = 0;
-#else
-  extern int initialized;
-  extern unsigned data_start;
-  extern int pureptr;
-#endif
-
-extern char *getenv ();
-static unsigned brk_value;
-static struct exec nhdr;
-static int rd_only_len;
-static long cookie;
-
-
-unexec (new_name, a_name, bndry, bss_start, entry)
-     char *new_name, *a_name;
-     unsigned bndry, bss_start, entry;
-{
-  int fd, new;
-  char *old;
-  struct exec ohdr;            /* Allocate on the stack,  not needed in the 
next life */
-  struct stat stat;
-
-  if ((fd = open (a_name, O_RDONLY)) < 0)
-    {
-      fprintf (stderr, "%s: open: ", a_name);
-      perror (a_name);
-      exit (1);
-    }
-  if ((new = open (new_name, O_WRONLY | O_CREAT, 0666)) == -1)
-    {
-      fprintf (stderr, "%s: open: ", a_name);
-      perror (new_name);
-      exit (1);
-    }
-
-  if ((fstat (fd, &stat) == -1))
-    {
-      fprintf (stderr, "%s: ", a_name);
-      perror ("fstat");
-      exit (1);
-    }
-
-  old = (char *)mmap (0, stat.st_size, PROT_READ, MAP_FILE|MAP_SHARED, fd, 0);
-  if (old == (char *)-1)
-    {
-      fprintf (stderr, "%s: ", a_name);
-      perror ("mmap");
-      exit (1);
-    }
-  close (fd);
-
-  nhdr = ohdr = (*(struct exec *)old);
-
-
-  /*
-   * Remember a magic cookie so we know we've got the right binary
-   * when remapping.
-   */
-  cookie = time (0);
-
-  /* Save the break, it is reset to &_end (by ld.so?).  */
-  brk_value = (unsigned) sbrk (0);
-
-  /*
-   * Round up data start to a page boundary (Lose if not a 2 power!)
-   */
-  data_start = ((((int)&data_start) - 1) & ~(N_PAGSIZ (nhdr) - 1)) + N_PAGSIZ 
(nhdr);
-
-  /*
-   * Round down read only pages to a multiple of the page size
-   */
-  if (bndry)
-    rd_only_len = ((int)bndry & ~(N_PAGSIZ (nhdr) - 1)) - data_start;
-
-#ifndef emacs
-  /* Have to do this some time before dumping the data */
-  initialized = 1;
-#endif
-
-  /* Handle new data and bss sizes and optional new entry point.
-     No one actually uses bss_start and entry,  but tradition compels
-     one to support them.
-     Could complain if bss_start > brk_value,
-     but the caller is *supposed* to know what she is doing.  */
-  nhdr.a_data = (bss_start ? bss_start : brk_value) - N_DATADDR (nhdr);
-  nhdr.a_bss  = bss_start ? brk_value - bss_start : 0;
-  if (entry)
-    nhdr.a_entry = entry;
-
-  /*
-   * Write out the text segment with new header
-   * Dynamic executables are ZMAGIC with N_TXTOFF==0 and the header
-   * part of the text segment, but no need to rely on this.
-   * So write the TEXT first,  then go back replace the header.
-   * Doing it in the other order is less general!
-   */
-  lseek (new, N_TXTOFF (nhdr), L_SET);
-  write (new, old + N_TXTOFF (ohdr), N_TXTOFF (ohdr) + ohdr.a_text);
-  lseek (new, 0L, L_SET);
-  write (new, &nhdr, sizeof (nhdr));
-
-  /*
-   * Write out the head of the old data segment from the file not
-   * from core, this has the unresolved __DYNAMIC relocation data
-   * we need to reload
-   */
-  lseek (new, N_DATOFF (nhdr), L_SET);
-  write (new, old + N_DATOFF (ohdr), (int)&data_start - N_DATADDR (ohdr));
-
-  /*
-   * Copy the rest of the data from core
-   */
-  write (new, &data_start, N_BSSADDR (nhdr) - (int)&data_start);
-
-  /*
-   * Copy the symbol table and line numbers
-   */
-  lseek (new, N_TRELOFF (nhdr), L_SET);
-  write (new, old + N_TRELOFF (ohdr), stat.st_size - N_TRELOFF (ohdr));
-
-  /* Some other BSD systems use this file.
-     We don't know whether this change is right for them.  */
-#ifdef UNDO_RELOCATION
-  /* Undo the relocations done at startup by ld.so.
-     It will do these relocations again when we start the dumped Emacs.
-     Doing them twice gives incorrect results.  */
-  {
-    unsigned long daddr = N_DATADDR (ohdr);
-    unsigned long rel, erel;
-#ifdef SUNOS4
-#ifdef SUNOS4_SHARED_LIBRARIES
-    extern struct link_dynamic _DYNAMIC;
-
-    /*  SunOS4.x's ld_rel is relative to N_TXTADDR. */
-    if (!ohdr.a_dynamic)
-      /* This was statically linked.  */
-      rel = erel = 0;
-    else if (_DYNAMIC.ld_version < 2)
-      {
-       rel = _DYNAMIC.ld_un.ld_1->ld_rel + N_TXTADDR (ohdr);
-       erel = _DYNAMIC.ld_un.ld_1->ld_hash + N_TXTADDR (ohdr);
-      }
-    else
-      {
-       rel = _DYNAMIC.ld_un.ld_2->ld_rel + N_TXTADDR (ohdr);
-       erel = _DYNAMIC.ld_un.ld_2->ld_hash + N_TXTADDR (ohdr);
-      }
-#else /* not SUNOS4_SHARED_LIBRARIES */
-    rel = erel = 0;
-#endif /* not SUNOS4_SHARED_LIBRARIES */
-#ifdef sparc
-#define REL_INFO_TYPE          struct reloc_info_sparc
-#else
-#define REL_INFO_TYPE          struct relocation_info
-#endif /* sparc */
-#define REL_TARGET_ADDRESS(r)  (((REL_INFO_TYPE *)(r))->r_address)
-#endif /* SUNOS4 */
-#if defined (__FreeBSD__) || defined (__NetBSD__)
-    extern struct _dynamic _DYNAMIC;
-
-    /*  FreeBSD's LD_REL is a virtual address itself. */
-    rel = LD_REL (&_DYNAMIC);
-    erel = rel + LD_RELSZ (&_DYNAMIC);
-#define REL_INFO_TYPE          struct relocation_info
-#define REL_TARGET_ADDRESS(r)  (((REL_INFO_TYPE *)(r))->r_address)
-#endif
-
-    for (; rel < erel; rel += sizeof (REL_INFO_TYPE))
-      {
-       /*  This is the virtual address where ld.so will do relocation.  */
-       unsigned long target = REL_TARGET_ADDRESS (rel);
-       /*  This is the offset in the data segment.  */
-       unsigned long segoffset = target - daddr;
-
-       /*  If it is located below data_start, we have to do nothing here,
-           because the old data has been already written to the location. */
-       if (target < (unsigned long)&data_start)
-           continue;
-
-       lseek (new, N_DATOFF (nhdr) + segoffset, L_SET);
-       write (new, old + N_DATOFF (ohdr) + segoffset, sizeof (unsigned long));
-      }
-  }
-#endif /* UNDO_RELOCATION */
-
-  fchmod (new, 0755);
-}
-
-void
-run_time_remap (progname)
-     char *progname;
-{
-  char aout[MAXPATHLEN];
-  register char *path, *p;
-
-  /* Just in case */
-  if (!initialized)
-    return;
-
-  /* Restore the break */
-  brk ((char *) brk_value);
-
-  /*  If nothing to remap:  we are done! */
-  if (rd_only_len == 0)
-    return;
-
-  /*
-   * Attempt to find the executable
-   * First try argv[0],  will almost always succeed as shells tend to give
-   * the full path from the hash list rather than using execvp ()
-   */
-  if (is_it (progname))
-    return;
-
-  /*
-   * If argv[0] is a full path and does not exist,  not much sense in
-   * searching further
-   */
-  if (strchr (progname, '/'))
-    return;
-
-  /*
-   * Try to search for  argv[0] on the PATH
-   */
-  path = getenv ("PATH");
-  if (path == NULL)
-    return;
-
-  while (*path)
-    {
-      /* copy through ':' or end */
-      for (p = aout; *p = *path; ++p, ++path)
-       if (*p == ':')
-         {
-           ++path;             /* move past ':' */
-           break;
-         }
-      *p++ = '/';
-      strcpy (p, progname);
-      /*
-       * aout is a candidate full path name
-       */
-      if (is_it (aout))
-       return;
-    }
-}
-
-is_it (filename)
-  char *filename;
-{
-  int fd;
-  long filenames_cookie;
-  struct exec hdr;
-
-  /*
-   * Open an executable  and check for a valid header!
-   * Can't bcmp the header with what we had,  it may have been stripped!
-   * so we may save looking at non executables with the same name, mostly
-   * directories.
-   */
-  fd = open (filename, O_RDONLY);
-  if (fd != -1)
-    {
-      if (read (fd, &hdr, sizeof (hdr)) == sizeof (hdr)
-         && !N_BADMAG (hdr) && N_DATOFF (hdr) == N_DATOFF (nhdr)
-         && N_TRELOFF (hdr) == N_TRELOFF (nhdr))
-       {
-         /* compare cookies */
-         lseek (fd, N_DATOFF (hdr) + (int)&cookie - N_DATADDR (hdr), L_SET);
-         read (fd, &filenames_cookie, sizeof (filenames_cookie));
-         if (filenames_cookie == cookie)
-           {                   /* Eureka */
-
-             /*
-              * Do the mapping
-              * The PROT_EXEC may not be needed,  but it is safer this way.
-              * should the shared library decide to indirect through
-              * addresses in the data segment not part of __DYNAMIC
-              */
-             mmap ((char *) data_start, rd_only_len, PROT_READ | PROT_EXEC,
-                   MAP_FILE | MAP_SHARED | MAP_FIXED, fd,
-                   N_DATOFF (hdr) + data_start - N_DATADDR (hdr));
-             close (fd);
-             return 1;
-           }
-       }
-      close (fd);
-    }
-  return 0;
-}
-
-/* arch-tag: 30227420-2c6f-4700-a4f8-9e45e52f53b1
-   (do not change this comment) */




reply via email to

[Prev in Thread] Current Thread [Next in Thread]