Annotation of GNUtools/emacs/src/unexmips.c, revision 1.1.1.1

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

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.