home *** CD-ROM | disk | FTP | other *** search
/ Linux Cubed Series 2: Applications / Linux Cubed Series 2 - Applications.iso / editors / emacs / xemacs / xemacs-1.004 / xemacs-1 / xemacs-19.13 / src / unexalpha.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-07-28  |  9.7 KB  |  340 lines

  1. /* Unexec for MIPS (including IRIS4D).
  2.    Copyright (C) 1988 Free Software Foundation, Inc.
  3.  
  4. This file is part of XEmacs.
  5.  
  6. XEmacs is free software; you can redistribute it and/or modify it
  7. under the terms of the GNU General Public License as published by the
  8. Free Software Foundation; either version 2, or (at your option) any
  9. later version.
  10.  
  11. XEmacs is distributed in the hope that it will be useful, but WITHOUT
  12. ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13. FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14. for more details.
  15.  
  16. You should have received a copy of the GNU General Public License
  17. along with XEmacs; see the file COPYING.  If not, write to the Free
  18. Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
  19.  
  20. /* Synched up with: Not synched with FSF. */
  21.  
  22.  
  23. #include <config.h>
  24. #include <sys/types.h>
  25. #include <sys/file.h>
  26. #include <sys/stat.h>
  27. #include <stdio.h>
  28. #include <varargs.h>
  29. #include <filehdr.h>
  30. #include <aouthdr.h>
  31. #include <scnhdr.h>
  32. #include <sym.h>
  33.  
  34. #if defined (IRIS_4D) || defined (sony)
  35. #include "getpagesize.h"
  36. #include <fcntl.h>
  37. #endif
  38.  
  39. static void fatal_unexec ();
  40. static void mark_x ();
  41.  
  42. #define READ(_fd, _buffer, _size, _error_message, _error_arg) \
  43.     errno = EEOF; \
  44.     if (read (_fd, _buffer, _size) != _size) \
  45.       fatal_unexec (_error_message, _error_arg);
  46.  
  47. #define WRITE(_fd, _buffer, _size, _error_message, _error_arg) \
  48.     if (write (_fd, _buffer, _size) != _size) \
  49.       fatal_unexec (_error_message, _error_arg);
  50.  
  51. #define SEEK(_fd, _position, _error_message, _error_arg) \
  52.     errno = EEOF; \
  53.     if (lseek (_fd, _position, L_SET) != _position) \
  54.       fatal_unexec (_error_message, _error_arg);
  55.  
  56. extern int errno;
  57. extern int sys_nerr;
  58. extern char *sys_errlist[];
  59. #define EEOF -1
  60.  
  61. static struct scnhdr *text_section;
  62. static struct scnhdr *init_section;
  63. static struct scnhdr *finit_section;
  64. static struct scnhdr *rdata_section;
  65. static struct scnhdr *xdata_section;
  66. static struct scnhdr *pdata_section;
  67. static struct scnhdr *data_section;
  68. static struct scnhdr *lit8_section;
  69. static struct scnhdr *lit4_section;
  70. static struct scnhdr *sdata_section;
  71. static struct scnhdr *sbss_section;
  72. static struct scnhdr *bss_section;
  73.  
  74.  
  75. struct headers {
  76.     struct filehdr fhdr;
  77.     struct aouthdr aout;
  78.     struct scnhdr section[16];
  79. };
  80.  
  81. /* Define name of label for entry point for the dumped executable.  */
  82.  
  83. #ifndef DEFAULT_ENTRY_ADDRESS
  84. #define DEFAULT_ENTRY_ADDRESS __start
  85. #endif
  86.  
  87. unexec (new_name, a_name, data_start, bss_start, entry_address)
  88.      char *new_name, *a_name;
  89.      unsigned long data_start, bss_start, entry_address;
  90. {
  91.   int new, old;
  92.   long pagesize, brk;
  93.   long newsyms, symrel;
  94.   int nread;
  95.   struct headers hdr;
  96.   int i;
  97.   long vaddr, scnptr;
  98. #define BUFSIZE 8192
  99.   char buffer[BUFSIZE];
  100.  
  101.   old = open (a_name, O_RDONLY, 0);
  102.   if (old < 0) fatal_unexec ("opening %s", a_name);
  103.  
  104.   new = creat (new_name, 0666);
  105.   if (new < 0) fatal_unexec ("creating %s", new_name);
  106.  
  107.   hdr = *((struct headers *)TEXT_START);
  108. #ifdef MIPS2
  109.   if (hdr.fhdr.f_magic != MIPSELMAGIC
  110.       && hdr.fhdr.f_magic != MIPSEBMAGIC
  111.       && hdr.fhdr.f_magic != (MIPSELMAGIC | 1)
  112.       && hdr.fhdr.f_magic != (MIPSEBMAGIC | 1))
  113.     {
  114.       fprintf (stderr,
  115.            "unexec: input file magic number is %x, not %x, %x, %x or %x.\n",
  116.            hdr.fhdr.f_magic,
  117.            MIPSELMAGIC, MIPSEBMAGIC,
  118.            MIPSELMAGIC | 1, MIPSEBMAGIC | 1);
  119.       exit(1);
  120.     }
  121. #else /* not MIPS2 */
  122. #ifdef __alpha
  123.   if (hdr.fhdr.f_magic != ALPHAMAGIC
  124.       && hdr.fhdr.f_magic != ALPHAUMAGIC)
  125.     {
  126.       fprintf(stderr, "unexec: input file magic number is %x, not %x or %x.\n",
  127.               hdr.fhdr.f_magic, ALPHAMAGIC, ALPHAUMAGIC);
  128.       exit(1);
  129.     }
  130. #else /* not alpha */
  131.   if (hdr.fhdr.f_magic != MIPSELMAGIC
  132.       && hdr.fhdr.f_magic != MIPSEBMAGIC)
  133.     {
  134.       fprintf(stderr, "unexec: input file magic number is %x, not %x or %x.\n",
  135.               hdr.fhdr.f_magic, MIPSELMAGIC, MIPSEBMAGIC);
  136.       exit(1);
  137.     }
  138. #endif /* not alpha */
  139. #endif /* not MIPS2 */
  140.  
  141.   if (hdr.fhdr.f_opthdr != sizeof (hdr.aout))
  142.     {
  143.       fprintf (stderr, "unexec: input a.out header is %d bytes, not %d.\n",
  144.            hdr.fhdr.f_opthdr, sizeof (hdr.aout));
  145.       exit (1);
  146.     }
  147.   if (hdr.aout.magic != ZMAGIC)
  148.     {
  149.       fprintf (stderr, "unexec: input file a.out magic number is %o, not %o.\n",
  150.            hdr.aout.magic, ZMAGIC);
  151.       exit (1);
  152.     }
  153.  
  154. #define CHECK_SCNHDR(ptr, name, flags) \
  155. for( i = 0, ptr = NULL; i < hdr.fhdr.f_nscns && !ptr; i++){ \
  156.     if (hdr.section[i].s_name && strcmp (hdr.section[i].s_name, name) == 0){ \
  157.        if (hdr.section[i].s_flags != flags) { \
  158.       fprintf(stderr, "unexec: %x flags (%x expected) in %s section.\n", \
  159.         hdr.section[i].s_flags, flags, name); \
  160.     } \
  161.     ptr = hdr.section + i; \
  162.      } \
  163.      if(ptr) \
  164.      break;\
  165. }
  166.        
  167.  
  168.   CHECK_SCNHDR (text_section,  _TEXT,  STYP_TEXT);
  169.   CHECK_SCNHDR (init_section,  _INIT,  STYP_INIT);
  170.   CHECK_SCNHDR (rdata_section, _RDATA, STYP_RDATA);
  171. #ifdef _RCONST
  172.   /* XEmacs change from Dirk Grunwald <grunwald@foobar.cs.colorado.edu> */
  173.   if (rdata_section == NULL)
  174.     {
  175.       CHECK_SCNHDR (rdata_section, _RCONST, STYP_RCONST);
  176.     }
  177. #endif
  178. #ifdef _XDATA
  179.   CHECK_SCNHDR(xdata_section, _XDATA, STYP_XDATA);
  180.   CHECK_SCNHDR(pdata_section, _PDATA, STYP_PDATA);
  181. #endif
  182.   CHECK_SCNHDR (data_section,  _DATA,  STYP_DATA);
  183. #ifdef _LIT8
  184.   CHECK_SCNHDR (lit8_section,  _LIT8,  STYP_LIT8);
  185.   CHECK_SCNHDR (lit4_section,  _LIT4,  STYP_LIT4);
  186. #endif /* _LIT8 */
  187.   CHECK_SCNHDR (sdata_section, _SDATA, STYP_SDATA);
  188.   CHECK_SCNHDR (sbss_section,  _SBSS,  STYP_SBSS);
  189.   CHECK_SCNHDR (bss_section,   _BSS,   STYP_BSS);
  190. #if 0 /* Apparently this error check goes off on irix 3.3,
  191.      but it doesn't indicate a real problem.  */
  192.   if (i != hdr.fhdr.f_nscns)
  193.     fprintf (stderr, "unexec: %d sections found instead of %d.\n",
  194.          i, hdr.fhdr.f_nscns);
  195. #endif
  196.  
  197.   text_section->s_scnptr = 0;
  198.  
  199.   pagesize = getpagesize ();
  200.   brk = (sbrk (0) + pagesize - 1) & (-pagesize);
  201.   hdr.aout.dsize = brk - DATA_START;
  202.   hdr.aout.bsize = 0;
  203.   if (entry_address == 0)
  204.     {
  205.       extern DEFAULT_ENTRY_ADDRESS ();
  206.       hdr.aout.entry = (unsigned long)DEFAULT_ENTRY_ADDRESS;
  207.     }
  208.   else
  209.     hdr.aout.entry = entry_address;
  210.  
  211.   hdr.aout.bss_start = hdr.aout.data_start + hdr.aout.dsize;
  212.   rdata_section->s_size = data_start - DATA_START;
  213.  
  214.   /* Adjust start and virtual addresses of rdata_section, too.  */
  215.   rdata_section->s_vaddr = DATA_START;
  216.   rdata_section->s_paddr = DATA_START;
  217.   rdata_section->s_scnptr = text_section->s_scnptr + hdr.aout.tsize;
  218.  
  219.   data_section->s_vaddr = data_start;
  220.   data_section->s_paddr = data_start;
  221.   data_section->s_size = brk - data_start;
  222.   data_section->s_scnptr = rdata_section->s_scnptr + rdata_section->s_size;
  223.   vaddr = data_section->s_vaddr + data_section->s_size;
  224.   scnptr = data_section->s_scnptr + data_section->s_size;
  225.   if (lit8_section != NULL)
  226.     {
  227.       lit8_section->s_vaddr = vaddr;
  228.       lit8_section->s_paddr = vaddr;
  229.       lit8_section->s_size = 0;
  230.       lit8_section->s_scnptr = scnptr;
  231.     }
  232.   if (lit4_section != NULL)
  233.     {
  234.       lit4_section->s_vaddr = vaddr;
  235.       lit4_section->s_paddr = vaddr;
  236.       lit4_section->s_size = 0;
  237.       lit4_section->s_scnptr = scnptr;
  238.     }
  239.   if (sdata_section != NULL)
  240.     {
  241.       sdata_section->s_vaddr = vaddr;
  242.       sdata_section->s_paddr = vaddr;
  243.       sdata_section->s_size = 0;
  244.       sdata_section->s_scnptr = scnptr;
  245.     }
  246.   if (sbss_section != NULL)
  247.     {
  248.       sbss_section->s_vaddr = vaddr;
  249.       sbss_section->s_paddr = vaddr;
  250.       sbss_section->s_size = 0;
  251.       sbss_section->s_scnptr = scnptr;
  252.     }
  253.   if (bss_section != NULL)
  254.     {
  255.       bss_section->s_vaddr = vaddr;
  256.       bss_section->s_paddr = vaddr;
  257.       bss_section->s_size = 0;
  258.       bss_section->s_scnptr = scnptr;
  259.     }
  260.  
  261.   WRITE (new, TEXT_START, hdr.aout.tsize,
  262.      "writing text section to %s", new_name);
  263.   WRITE (new, DATA_START, hdr.aout.dsize,
  264.      "writing text section to %s", new_name);
  265.  
  266.   SEEK (old, hdr.fhdr.f_symptr, "seeking to start of symbols in %s", a_name);
  267.   errno = EEOF;
  268.   nread = read (old, buffer, BUFSIZE);
  269.   if (nread < sizeof (HDRR)) fatal_unexec ("reading symbols from %s", a_name);
  270. #define symhdr ((pHDRR)buffer)
  271.   newsyms = hdr.aout.tsize + hdr.aout.dsize;
  272.   symrel = newsyms - hdr.fhdr.f_symptr;
  273.   hdr.fhdr.f_symptr = newsyms;
  274.   symhdr->cbLineOffset += symrel;
  275.   symhdr->cbDnOffset += symrel;
  276.   symhdr->cbPdOffset += symrel;
  277.   symhdr->cbSymOffset += symrel;
  278.   symhdr->cbOptOffset += symrel;
  279.   symhdr->cbAuxOffset += symrel;
  280.   symhdr->cbSsOffset += symrel;
  281.   symhdr->cbSsExtOffset += symrel;
  282.   symhdr->cbFdOffset += symrel;
  283.   symhdr->cbRfdOffset += symrel;
  284.   symhdr->cbExtOffset += symrel;
  285. #undef symhdr
  286.   do
  287.     {
  288.       if (write (new, buffer, nread) != nread)
  289.     fatal_unexec ("writing symbols to %s", new_name);
  290.       nread = read (old, buffer, BUFSIZE);
  291.       if (nread < 0) fatal_unexec ("reading symbols from %s", a_name);
  292. #undef BUFSIZE
  293.     } while (nread != 0);
  294.  
  295.   SEEK (new, 0, "seeking to start of header in %s", new_name);
  296.   WRITE (new, &hdr, sizeof (hdr),
  297.      "writing header of %s", new_name);
  298.  
  299.   close (old);
  300.   close (new);
  301.   mark_x (new_name);
  302. }
  303.  
  304. /*
  305.  * mark_x
  306.  *
  307.  * After successfully building the new a.out, mark it executable
  308.  */
  309.  
  310. static void
  311. mark_x (name)
  312.      char *name;
  313. {
  314.   struct stat sbuf;
  315.   int um = umask (777);
  316.   umask (um);
  317.   if (stat (name, &sbuf) < 0)
  318.     fatal_unexec ("getting protection on %s", name);
  319.   sbuf.st_mode |= 0111 & ~um;
  320.   if (chmod (name, sbuf.st_mode) < 0)
  321.     fatal_unexec ("setting protection on %s", name);
  322. }
  323.  
  324. static void
  325. fatal_unexec (s, va_alist)
  326.      va_dcl
  327. {
  328.   va_list ap;
  329.   if (errno == EEOF)
  330.     fputs ("unexec: unexpected end of file, ", stderr);
  331.   else if (errno < sys_nerr)
  332.     fprintf (stderr, "unexec: %s, ", sys_errlist[errno]);
  333.   else
  334.     fprintf (stderr, "unexec: error code %d, ", errno);
  335.   va_start (ap);
  336.   _doprnt (s, ap, stderr);
  337.   fputs (".\n", stderr);
  338.   exit (1);
  339. }
  340.