summaryrefslogtreecommitdiff
path: root/obsolete/support/undump
diff options
context:
space:
mode:
Diffstat (limited to 'obsolete/support/undump')
-rw-r--r--obsolete/support/undump/0UNSUPPORTED5
-rw-r--r--obsolete/support/undump/Encore/BU-README12
-rw-r--r--obsolete/support/undump/Encore/Makefile13
-rw-r--r--obsolete/support/undump/Encore/dumpcore.c43
-rw-r--r--obsolete/support/undump/Encore/dumpit.c74
-rw-r--r--obsolete/support/undump/Encore/undo.c480
-rw-r--r--obsolete/support/undump/Encore/undo.h70
-rw-r--r--obsolete/support/undump/Encore/undump.128
-rw-r--r--obsolete/support/undump/Encore/undump.c374
-rw-r--r--obsolete/support/undump/Encore/unexec.c1143
-rw-r--r--obsolete/support/undump/Encore/unexec.c-dist1134
-rw-r--r--obsolete/support/undump/Encore/unexec.diff91
-rw-r--r--obsolete/support/undump/Makefile.BALANCE11
-rw-r--r--obsolete/support/undump/Makefile.PYR9
-rw-r--r--obsolete/support/undump/Makefile.SUN414
-rw-r--r--obsolete/support/undump/Makefile.SUN_V214
-rw-r--r--obsolete/support/undump/Makefile.SUN_V314
-rw-r--r--obsolete/support/undump/Makefile.SYS_V14
-rw-r--r--obsolete/support/undump/Makefile.VAX4_213
-rw-r--r--obsolete/support/undump/Makefile.VAX4_313
-rw-r--r--obsolete/support/undump/Setup.BALANCE4
-rw-r--r--obsolete/support/undump/Setup.PYR7
-rw-r--r--obsolete/support/undump/Setup.SUN45
-rw-r--r--obsolete/support/undump/Setup.SUN_V25
-rw-r--r--obsolete/support/undump/Setup.SUN_V35
-rw-r--r--obsolete/support/undump/Setup.SYS_V5
-rw-r--r--obsolete/support/undump/Setup.VAX4_25
-rw-r--r--obsolete/support/undump/Setup.VAX4_34
-rw-r--r--obsolete/support/undump/scanargs.1446
-rw-r--r--obsolete/support/undump/scanargs.c879
-rw-r--r--obsolete/support/undump/undump.128
-rw-r--r--obsolete/support/undump/undump.BALANCE.c298
-rw-r--r--obsolete/support/undump/undump.PYR.c287
-rw-r--r--obsolete/support/undump/undump.SUN4.c367
-rw-r--r--obsolete/support/undump/undump.SUN_V2.c352
-rw-r--r--obsolete/support/undump/undump.SUN_V3352
-rw-r--r--obsolete/support/undump/undump.SUN_V3.c352
-rw-r--r--obsolete/support/undump/undump.SYS_V.c250
-rw-r--r--obsolete/support/undump/undump.VAX4_2.c272
-rw-r--r--obsolete/support/undump/undump.VAX4_3.c264
40 files changed, 7756 insertions, 0 deletions
diff --git a/obsolete/support/undump/0UNSUPPORTED b/obsolete/support/undump/0UNSUPPORTED
new file mode 100644
index 0000000000..64cacca715
--- /dev/null
+++ b/obsolete/support/undump/0UNSUPPORTED
@@ -0,0 +1,5 @@
+
+The programs in this directory are now unsupported.
+For almost all systems, undumped TeX is an inferior approach
+and the intrinsic machine dependency of these programs makes
+them too costly to maintain with any promise of reliability.
diff --git a/obsolete/support/undump/Encore/BU-README b/obsolete/support/undump/Encore/BU-README
new file mode 100644
index 0000000000..1708792a51
--- /dev/null
+++ b/obsolete/support/undump/Encore/BU-README
@@ -0,0 +1,12 @@
+
+ The files you are looking for are undump.c and unexec.c. If you have
+ problems with this, please contact me by phone. I will be out of
+ town from the 12th to the 19th of December 88.
+
+ Tom Meier
+ Boston Univeristy Info Tech
+
+ 617-353-2780
+
+ p.s. I included the other files for history.
+
diff --git a/obsolete/support/undump/Encore/Makefile b/obsolete/support/undump/Encore/Makefile
new file mode 100644
index 0000000000..77de95bc65
--- /dev/null
+++ b/obsolete/support/undump/Encore/Makefile
@@ -0,0 +1,13 @@
+BINDIR=/usr/local
+
+undump: undump.o scanargs.o
+ cc -O -o undump undump.o scanargs.o
+
+undump.o: undump.c
+ cc -O -c undump.c
+
+clean:
+ rm -f *.o
+
+install: undump
+ cp undump $(BINDIR)
diff --git a/obsolete/support/undump/Encore/dumpcore.c b/obsolete/support/undump/Encore/dumpcore.c
new file mode 100644
index 0000000000..e607a95c70
--- /dev/null
+++ b/obsolete/support/undump/Encore/dumpcore.c
@@ -0,0 +1,43 @@
+#include <stdio.h>
+#include <sys/param.h>
+#include <sys/file.h>
+#include <aouthdr.h>
+#include <sys/ptrace.h>
+
+struct ptrace_user u;
+
+
+main(argc,argv)
+int argc;
+char *argv[];
+{
+
+ int fd;
+
+ if (argc < 2) {
+ printf("give me a break, and a file...\n");
+ exit(0);
+ }
+
+ fd = open(argv[1],O_RDONLY);
+ read(fd,&u,sizeof (struct ptrace_user));
+ printf("sizeof ptrace: %o\n",sizeof(struct ptrace_user));
+ printf("dsize: %lo\n",u.pt_dsize);
+ printf("ssize: %lo\n",u.pt_ssize);
+ printf("magic: %o\n",u.pt_aouthdr.magic);
+ printf("vstamp: %o\n",u.pt_aouthdr.vstamp);
+ printf("tsize: %lo\n",u.pt_aouthdr.tsize);
+ printf("dsize: %lo\n",u.pt_aouthdr.dsize);
+ printf("bsize: %lo\n",u.pt_aouthdr.bsize);
+ printf("msize: %lo\n",u.pt_aouthdr.msize);
+ printf("mod_start: %lo\n",u.pt_aouthdr.mod_start);
+ printf("entry: %lo\n",u.pt_aouthdr.entry);
+ printf("text_start: %lo\n",u.pt_aouthdr.text_start);
+ printf("data_start: %lo\n",u.pt_aouthdr.data_start);
+ printf("entry_mod: %lo\n",u.pt_aouthdr.entry_mod);
+ printf("flags: %o\n",u.pt_aouthdr.flags);
+ printf("\n");
+ close(fd);
+ }
+
+
diff --git a/obsolete/support/undump/Encore/dumpit.c b/obsolete/support/undump/Encore/dumpit.c
new file mode 100644
index 0000000000..3090a83820
--- /dev/null
+++ b/obsolete/support/undump/Encore/dumpit.c
@@ -0,0 +1,74 @@
+#include <stdio.h>
+#include <sys/file.h>
+#include <filehdr.h>
+#include <aouthdr.h>
+#include <scnhdr.h>
+
+
+#define MAXSCNS 16
+struct filehdr hdr;
+AOUTHDR shdr;
+struct scnhdr scns[MAXSCNS];
+int nscns;
+
+
+main(argc,argv)
+int argc;
+char *argv[];
+{
+
+ int fd,i;
+
+ if (argc < 2) {
+ printf("give me a break, and a file...\n");
+ exit(0);
+ }
+ fd = open(argv[1],O_RDONLY);
+ read(fd,&hdr,sizeof(struct filehdr));
+ nscns = hdr.f_nscns;
+ printf("magic: %o\n",hdr.f_magic);
+ printf("sections: %o\n",hdr.f_nscns);
+ printf("timestamp: %lo\n",hdr.f_timdat);
+ printf("sym ptr: %lo\n",hdr.f_symptr);
+ printf("num sym ents: %lo\n",hdr.f_nsyms);
+ printf("size of syshdr: %o\n",hdr.f_opthdr);
+ printf("flags: %o\n",hdr.f_flags);
+ printf("\n");
+ if (hdr.f_opthdr != 0) {
+ read(fd,&shdr,sizeof(AOUTHDR));
+ printf("magic: %o\n",shdr.magic);
+ printf("vstamp: %o\n",shdr.vstamp);
+ printf("tsize: %lo\n",shdr.tsize);
+ printf("dsize: %lo\n",shdr.dsize);
+ printf("bsize: %lo\n",shdr.bsize);
+ printf("msize: %lo\n",shdr.msize);
+ printf("mod_start: %lo\n",shdr.mod_start);
+ printf("entry: %lo\n",shdr.entry);
+ printf("text_start: %lo\n",shdr.text_start);
+ printf("data_start: %lo\n",shdr.data_start);
+ printf("entry_mod: %lo\n",shdr.entry_mod);
+ printf("flags: %o\n",shdr.flags);
+ printf("\n");
+ }
+ for(i=0;(i != nscns);i++) {
+ read(fd,&scns[i],sizeof(struct scnhdr));
+ }
+ for(i=0;(i != nscns);i++) {
+ printf("name: %s\n",scns[i].s_name);
+ printf("paddr: %lo\n",scns[i].s_paddr);
+ printf("vaddr: %lo\n",scns[i].s_vaddr);
+ printf("size: %lo\n",scns[i].s_size);
+ printf("scnptr: %lo\n",scns[i].s_scnptr);
+ printf("relptr: %lo\n",scns[i].s_relptr);
+ printf("lnnoptr: %lo\n",scns[i].s_lnnoptr);
+ printf("nreloc: %o\n",scns[i].s_nreloc);
+ printf("nlnno: %o\n",scns[i].s_nlnno);
+ printf("flags: %lo\n",scns[i].s_flags);
+ printf("symptr: %lo\n",scns[i].s_symptr);
+ printf("modno: %o\n",scns[i].s_modno);
+ printf("\n");
+ }
+ close(fd);
+ }
+
+
diff --git a/obsolete/support/undump/Encore/undo.c b/obsolete/support/undump/Encore/undo.c
new file mode 100644
index 0000000000..c0ee0dfcf6
--- /dev/null
+++ b/obsolete/support/undump/Encore/undo.c
@@ -0,0 +1,480 @@
+/* Support routines for the undo facility.
+ Copyright (C) 1985, 1986 Free Software Foundation, Inc.
+
+This file is part of GNU Emacs.
+
+GNU Emacs is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY. No author or distributor
+accepts responsibility to anyone for the consequences of using it
+or for whether it serves any particular purpose or works at all,
+unless he says so in writing. Refer to the GNU Emacs General Public
+License for full details.
+
+Everyone is granted permission to copy, modify and redistribute
+GNU Emacs, but only under the conditions described in the
+GNU Emacs General Public License. A copy of this license is
+supposed to have been given to you along with GNU Emacs so you
+can know your rights and responsibilities. It should be in a
+file named COPYING. Among other things, the copyright notice
+and this notice must be preserved on all copies. */
+
+
+#include "config.h"
+#include "lisp.h"
+#include "undo.h"
+#include "commands.h"
+#include "buffer.h"
+
+/* Access undo records of current buffer */
+/* These assume that `u' points to the buffer's undodata */
+#define UndoRQ (u->undorecs)
+#define UndoCQ (u->undochars)
+#define FillRQ (u->nextrec)
+#define FillCQ (u->nextchar)
+
+/* Record last undo record made, and what buffer made in */
+static struct UndoRec *LastUndoRec;
+static struct buffer *LastUndoBuf;
+
+/* Record progress of undoing */
+static NUndone;
+static NCharsLeft;
+static LastUndoneC;
+static LastUndone;
+static struct buffer *LastUndoneBuf;
+
+Lisp_Object Fundo_boundary ();
+
+make_undo_records (b)
+ struct buffer *b;
+{
+ register struct UndoData *u;
+ b->undodata = u = (struct UndoData *) xmalloc (sizeof (struct UndoData));
+ u->undorecs
+ = (struct UndoRec *) xmalloc (sizeof (struct UndoRec) * InitNUndoR);
+ u->undochars = (char *) xmalloc (InitNUndoC);
+ u->undorecs[InitNUndoR - 1].kind = Unundoable;
+ u->nextrec = 0;
+ u->nextchar = 0;
+ u->num_undorecs = InitNUndoR;
+ u->num_undochars = InitNUndoC;
+}
+
+free_undo_records (b)
+ struct buffer *b;
+{
+ register struct UndoData *u = b->undodata;
+ free (u->undorecs);
+ free (u->undochars);
+ free (u);
+}
+
+struct UndoRec *
+record_undo (kind, pos, len)
+ enum Ukinds kind;
+{
+ register struct UndoData *u = bf_cur->undodata;
+ register struct UndoRec *p = &UndoRQ[FillRQ];
+ register struct UndoRec *np;
+
+ FillRQ++;
+ if (FillRQ >= NUndoR)
+ FillRQ = 0;
+ else if (FillRQ >= u->num_undorecs)
+ {
+ np = (struct UndoRec *) xrealloc (UndoRQ, NUndoR * sizeof *p);
+ if (np)
+ {
+ UndoRQ = np;
+ p = &UndoRQ[FillRQ-1];
+ u->num_undorecs = NUndoR;
+ np[NUndoR - 1].kind = Unundoable;
+ }
+ else
+ FillRQ = 0;
+ }
+ UndoRQ[FillRQ].kind = Unundoable;
+ p -> kind = kind;
+ p -> pos = pos;
+ p -> len = len;
+ LastUndoRec = p;
+ LastUndoBuf = bf_cur;
+ if (kind != Uboundary)
+ LastUndone = -1;
+ return p;
+}
+
+record_insert (pos, n)
+{
+ register struct UndoRec *p = LastUndoRec;
+ if (!bf_cur->undodata)
+ return;
+ if (LastUndoBuf != bf_cur)
+ {
+ Fundo_boundary ();
+ p = 0;
+ }
+
+ if (bf_modified <= bf_cur->save_modified)
+ record_undo (Uunmod, pos, bf_cur->modtime);
+
+ if (p && p -> kind == Udelete && p -> pos + p -> len == pos)
+ p -> len += n;
+ else
+ record_undo (Udelete, pos, n);
+}
+
+record_delete (pos, n)
+ int pos, n;
+{
+ register struct UndoRec *p = LastUndoRec;
+
+ if (!bf_cur->undodata)
+ return;
+ if (LastUndoBuf != bf_cur)
+ {
+ Fundo_boundary ();
+ p = 0;
+ }
+
+ if (bf_modified <= bf_cur->save_modified)
+ record_undo (Uunmod, pos, bf_cur->modtime);
+
+ if (p && p->kind == Uinsert && p->pos == pos && p->len > 0)
+ p->len += n;
+ else if (point == pos + n)
+ record_undo (Uinsert, pos + n, - n);
+ else
+ record_undo (Uinsert, pos, n);
+
+ record_chars (pos, n);
+}
+
+record_chars (pos, n)
+ register int pos, n;
+{
+ if (pos < bf_s1 + 1 && pos + n > bf_s1 + 1)
+ {
+ record_block (&CharAt (pos), bf_s1 + 1 - pos);
+ n -= bf_s1 + 1 - pos;
+ pos = bf_s1 + 1;
+ }
+
+ record_block (&CharAt (pos), n);
+}
+
+record_block (p, n)
+ register char *p;
+ register int n;
+{
+ register char *cp;
+ register struct UndoData *u = bf_cur->undodata;
+ register int i;
+
+ NCharsLeft -= n;
+ cp = &UndoCQ[FillCQ];
+
+ while (n > 0)
+ {
+ i = u->num_undochars - FillCQ;
+ if (i > n) i = n;
+ if (i > 0)
+ {
+ bcopy (p, cp, i);
+ p += i;
+ FillCQ += i;
+ n -= i;
+ }
+
+ if (n == 0)
+ break;
+
+ if (FillCQ >= NUndoC)
+ {
+ FillCQ = 0;
+ cp = UndoCQ;
+ }
+ else
+ {
+ cp = (char *) xrealloc (UndoCQ, NUndoC);
+ UndoCQ = cp;
+ cp += FillCQ;
+ NCharsLeft += NUndoC - u->num_undochars;
+ u->num_undochars = NUndoC;
+ }
+ }
+}
+
+record_change (pos, n)
+ int pos, n;
+{
+ register struct UndoRec *p = LastUndoRec;
+ if (!bf_cur->undodata)
+ return;
+ if (LastUndoBuf != bf_cur)
+ {
+ Fundo_boundary ();
+ p = 0;
+ }
+
+ if (bf_modified <= bf_cur->save_modified)
+ record_undo (Uunmod, pos, bf_cur->modtime);
+
+ if (p && p->kind == Uchange && p->len > 0 && p->pos + p->len == pos)
+ p->len += n;
+ else if (point == pos + n)
+ record_undo (Uchange, pos + n, -n);
+ else
+ record_undo (Uchange, pos, n);
+
+ record_chars (pos, n);
+}
+
+record_change1 (pos, bufp, n)
+ int pos;
+ char *bufp;
+ int n;
+{
+ register struct UndoRec *p = LastUndoRec;
+ if (!bf_cur->undodata)
+ return;
+ if (LastUndoBuf != bf_cur)
+ {
+ Fundo_boundary ();
+ p = 0;
+ }
+ if (p && p->kind == Uchange && p->len > 0 && p->pos + p->len == pos)
+ p -> len += n;
+ else
+ record_undo (Uchange, pos, n);
+
+ record_block (bufp, n);
+}
+
+DoneIsDone ()
+{
+ register struct UndoData *u = bf_cur->undodata;
+ register struct UndoRec *p;
+
+ if (!u)
+ return 0;
+
+ p = &UndoRQ[(FillRQ + u->num_undorecs - 1) % u->num_undorecs];
+ if (p->kind != Unundoable)
+ record_undo (Unundoable, point, 0);
+ return 0;
+}
+
+DEFUN ("undo-boundary", Fundo_boundary, Sundo_boundary, 0, 0, 0,
+ "Mark a boundary between units of undo.\n\
+An undo command will stop at this point,\n\
+but another undo command will undo to the previous boundary.")
+ ()
+{
+ register struct UndoData *u = bf_cur->undodata;
+ register struct UndoRec *p;
+
+ if (!u)
+ return Qnil;
+
+ p = &UndoRQ[(FillRQ + u->num_undorecs - 1) % u->num_undorecs];
+ if (p->kind != Uboundary)
+ record_undo (Uboundary, point, 0);
+ return Qnil;
+}
+
+DEFUN ("undo-more", Fundo_more, Sundo_more, 1, 1, 0,
+ "Undo back N undo-boundaries beyond what was already undone recently.\n\
+Call undo-start to get ready to undo recent changes,\n\
+then call undo-more one or more times to undo them.")
+ (pfxarg)
+ Lisp_Object pfxarg;
+{
+ register struct UndoData *u = bf_cur->undodata;
+ register int n = 0;
+ register int chars;
+ register int i = LastUndone;
+ register int arg = XINT (pfxarg);
+ register int len, pos;
+ char tembuf[NUndoC];
+
+ if (!u)
+ return Qnil;
+
+ if (LastUndoneBuf != bf_cur ||
+ i == -1)
+ error ("Cannot undo more: changes have been made since the last undo");
+
+ while (1)
+ {
+ while (UndoRQ[i = (!i ? u->num_undorecs-1 : i-1)].kind != Uboundary)
+ {
+ len = UndoRQ[i].len;
+ if (len < 0) len = - len;
+ if (((UndoRQ[i].kind == Uinsert || UndoRQ[i].kind == Uchange)
+ && (NCharsLeft -= len) < 0)
+ || UndoRQ[i].kind == Unundoable || NUndone >= u->num_undorecs)
+ error ("No further undo information available");
+ NUndone++;
+ n++;
+ }
+ NUndone++;
+ n++;
+ if (--arg <= 0)
+ break;
+ }
+
+ i = LastUndone;
+ chars = LastUndoneC;
+ while (--n >= 0)
+ {
+ if (!i)
+ i = u->num_undorecs;
+ i--;
+
+ len = UndoRQ[i].len;
+ pos = UndoRQ[i].pos;
+
+ if (UndoRQ[i].kind == Uchange || UndoRQ[i].kind == Uinsert)
+ if (len < 0)
+ {
+ pos += len;
+ len = - len;
+ }
+
+#ifdef SWITCH_ENUM_BUG
+ switch ((int) UndoRQ[i].kind)
+#else
+ switch (UndoRQ[i].kind)
+#endif
+ {
+ case Uchange:
+ case Udelete:
+ if (pos < FirstCharacter || pos + len > NumCharacters + 1)
+ error ("Changes to be undone are outside visible portion of buffer");
+ SetPoint (pos);
+ break;
+
+ case Uinsert:
+ if (pos < FirstCharacter || pos > NumCharacters + 1)
+ error ("Changes to be undone are outside visible portion of buffer");
+ SetPoint (pos);
+ }
+
+#ifdef SWITCH_ENUM_BUG
+ switch ((int) UndoRQ[i].kind)
+#else
+ switch (UndoRQ[i].kind)
+#endif
+ {
+ case Uboundary:
+ break;
+
+ case Udelete:
+ del_range (point, point + len);
+ break;
+
+ case Uchange:
+ if (len > NUndoC)
+ /* Should have already said "No more undo info available" */
+ abort ();
+ save_undone_chars (pos, len, tembuf);
+ chars -= len;
+ if (chars < 0)
+ {
+ replace_chars (point - chars, len + chars, UndoCQ);
+ replace_chars (point, - chars, UndoCQ + chars + u->num_undochars);
+ chars += u->num_undochars;
+ }
+ else
+ replace_chars (point, len, UndoCQ + chars);
+ record_change1 (point, tembuf, len);
+ SetPoint (UndoRQ[i].pos);
+ break;
+
+ case Uinsert:
+ chars -= len;
+ if (chars < 0)
+ {
+ InsCStr (UndoCQ + chars + u->num_undochars, - chars);
+ InsCStr (UndoCQ, len + chars);
+ chars += u->num_undochars;
+ }
+ else
+ InsCStr (UndoCQ + chars, len);
+ SetPoint (UndoRQ[i].pos);
+ break;
+
+ case Uunmod:
+ /* If this Uunmod records an obsolete save
+ (not matching the actual disk file)
+ then don't mark unmodified. */
+ if (len != bf_cur->modtime)
+ break;
+#ifdef CLASH_DETECTION
+ Funlock_buffer ();
+#endif /* CLASH_DETECTION */
+ bf_cur->save_modified = bf_modified;
+ RedoModes++;
+ break;
+
+ default:
+ error ("Something rotten in undo");
+ return Qnil;
+ }
+ }
+ LastUndone = i;
+ LastUndoneC = chars;
+ return Qnil;
+}
+
+replace_chars (pos, n, string)
+ register int pos, n;
+ register unsigned char *string;
+{
+ modify_region (pos, pos + n);
+ while (--n >= 0)
+ {
+ CharAt (pos) = *string++;
+ pos++;
+ }
+}
+
+save_undone_chars (pos, n, p)
+ register int pos, n;
+ register char *p;
+{
+ if (pos < bf_s1 + 1 && pos + n > bf_s1 + 1)
+ {
+ bcopy (&CharAt (pos), p, bf_s1 + 1 - pos);
+ p += bf_s1 + 1 - pos;
+ n -= bf_s1 + 1 - pos;
+ pos = bf_s1 + 1;
+ }
+
+ bcopy (&CharAt (pos), p, n);
+}
+
+DEFUN ("undo-start", Fundo_start, Sundo_start, 0, 0, 0,
+ "Move undo-pointer to front of undo records.\n\
+The next call to undo-more will undo the most recently made change.")
+ ()
+{
+ register struct UndoData *u = bf_cur->undodata;
+
+ if (!u)
+ error ("Undo information not kept for this buffer");
+ LastUndoneBuf = bf_cur;
+ NCharsLeft = u->num_undochars;
+ NUndone = 0;
+ LastUndone = FillRQ;
+ LastUndoneC = FillCQ;
+ return Qnil;
+}
+
+syms_of_undo ()
+{
+ defsubr (&Sundo_start);
+ defsubr (&Sundo_boundary);
+ defsubr (&Sundo_more);
+}
diff --git a/obsolete/support/undump/Encore/undo.h b/obsolete/support/undump/Encore/undo.h
new file mode 100644
index 0000000000..11b3b8cf16
--- /dev/null
+++ b/obsolete/support/undump/Encore/undo.h
@@ -0,0 +1,70 @@
+/* Definitions of objects used by the GNU Emacs undo facility.
+ Copyright (C) 1985 Free Software Foundation, Inc.
+
+This file is part of GNU Emacs.
+
+GNU Emacs is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY. No author or distributor
+accepts responsibility to anyone for the consequences of using it
+or for whether it serves any particular purpose or works at all,
+unless he says so in writing. Refer to the GNU Emacs General Public
+License for full details.
+
+Everyone is granted permission to copy, modify and redistribute
+GNU Emacs, but only under the conditions described in the
+GNU Emacs General Public License. A copy of this license is
+supposed to have been given to you along with GNU Emacs so you
+can know your rights and responsibilities. It should be in a
+file named COPYING. Among other things, the copyright notice
+and this notice must be preserved on all copies. */
+
+
+enum Ukinds { /* The events that can exist in the undo
+ queue. */
+ Uboundary, /* A boundary between sets of undoable things
+ */
+ Unundoable, /* What's done is done -- some things can't
+ be undone */
+ Udelete, /* Delete characters to perform the undo */
+ Uinsert, /* Insert .... */
+ Uchange, /* Replace characters */
+ Uunmod, /* Clear modification-flag to perform undo */
+};
+
+struct UndoRec { /* A record of a single undo action */
+ enum Ukinds kind; /* the kind of action to be undone */
+ int pos; /* Where change starts or ends. */
+ int len; /* Number of characters to insert, delete or
+ replace. Negative means they stretch
+ back from `pos'. */
+};
+
+/* Note: in a record of type Uunmod, the `len' field is really
+ the buffer->modtime associated with the state at that time.
+ The buffer is marked as unmodified by undoing the Uunmod
+ only if the modtime field matches. */
+
+/* The undo history consists of two circular queues, one of characters and
+ one of UndoRecs. When Uinsert recs are added to UndoRQ characters get
+ added to UndoCQ. The position of the characters can be reconstructed by
+ subtracting len from the fill pointer. */
+
+#define NUndoR (((1 << 13) - 4) / sizeof (struct UndoRec))
+#define NUndoC ((1 << 13) - 4)
+
+/* Initially allocate them these sizes;
+ if these sizes get filled up, make them full size */
+
+#define InitNUndoR 8
+#define InitNUndoC (512 - 4)
+
+struct UndoData
+ {
+ struct UndoRec *undorecs; /* The undo records, NUndoR of them */
+ char *undochars; /* And the characters associated, NUndoC in all */
+ int nextrec; /* Indices for storing in above two */
+ int nextchar;
+ int num_undorecs; /* Sizes allocated */
+ int num_undochars;
+ };
+
diff --git a/obsolete/support/undump/Encore/undump.1 b/obsolete/support/undump/Encore/undump.1
new file mode 100644
index 0000000000..797cdb0377
--- /dev/null
+++ b/obsolete/support/undump/Encore/undump.1
@@ -0,0 +1,28 @@
+.TH UNDUMP 1 "University of Utah"
+.SH NAME
+undump \- convert a core dump to an executable a.out file
+.SH SYNOPSIS
+undump new-a.out-file [old-a.out-file] [core-file]
+.SH DESCRIPTION
+Undump takes a core dump file and the executable "a.out" file which
+caused it and produces a new executable file with all static
+variables initialised to the values they held at the time of the
+core dump. It is primarily useful for programs which take a long time
+to initialise themselves, e.g. Emacs. The idea is to go through all of
+the initialisations and then create a core dump (e.g. with the abort()
+call). One then uses undump to make a new executable file with all of it
+done. This usually implies the use of a global flag variable which says
+whether or not initialisation has been done.
+.PP
+Undump's arguments, old-a.out-file and core-file, default to "a.out" and
+"core", respectively.
+.PP
+A few things to keep in mind about undump:
+.IP
+It doesn't preserve open files.
+.IP
+The program will be re-entered at the beginning of main(), not at the point
+where the core dump occurred.
+.SH BUGS
+Probably should have an option to not require
+old-a.out-file if the core came from a 407 file.
diff --git a/obsolete/support/undump/Encore/undump.c b/obsolete/support/undump/Encore/undump.c
new file mode 100644
index 0000000000..02d8b1d582
--- /dev/null
+++ b/obsolete/support/undump/Encore/undump.c
@@ -0,0 +1,374 @@
+/*
+ * This program was advertised on unix-wizards. I have had such a large
+ * response I'm sending it out to the world.
+ *
+ * Here is the source. It works fine under 4.1bsd, I see no fundamental
+ * reason why it shouldn't work on an 11. (Except possibly small format
+ * changes in exec header or user structure.) No documentation yet.
+ * Usage is
+ * undump new-a.out-file [old-a.out-file] [core-file]
+ * where old-a.out-file and core-file default to "a.out" and "core",
+ * respectively. Probably should have an option to not require
+ * old-a.out-file if the core came from a 407 file.
+ *
+ * It doesn't preserve open files, and the program is re-entered at main
+ * when you run it. It's used locally to dump a lisp and restart it.
+ *
+ * It requires a local subroutine called scanargs, somewhat similar to
+ * getopt (I think). You should be able to easily get around this, though.
+ * =Spencer
+ */
+
+
+/*
+ * undump.c - Convert a core file to an a.out.
+ *
+ * Author: Spencer W. Thomas
+ * Computer Science Dept.
+ * University of Utah
+ * Date: Wed Feb 17 1982
+ * Copyright (c) 1982 Spencer W. Thomas
+ *
+ * Usage:
+ * undump new-a.out [a.out] [core]
+ */
+
+#include <stdio.h>
+#include <sys/param.h>
+#include <sys/dir.h>
+#include <sys/stat.h>
+#include <aouthdr.h>
+#include <filehdr.h>
+#include <scnhdr.h>
+#include <linenum.h>
+#include <sys/ptrace.h>
+
+#define PSIZE 10240
+#define MAXSCNS 8
+
+struct ptrace_user u;
+AOUTHDR ahdr, oahdr;
+struct filehdr fhdr, ofhdr;
+struct scnhdr scns[MAXSCNS];
+int nscns;
+long cur_pos, sym_top;
+
+
+main(argc, argv)
+char **argv;
+{
+ char *new_name, *a_out_name = "a.out", *core_name = "core";
+ FILE *new, *a_out, *core;
+
+ if (scanargs(argc, argv, "undump new-a.out!s a.out%s core%s",
+ &new_name, &a_out_name, &core_name)
+ != 1)
+ exit(1);
+
+ if ((a_out = fopen(a_out_name, "r")) == NULL)
+ {
+ perror(a_out_name);
+ exit(1);
+ }
+ if ((core = fopen(core_name, "r")) == NULL)
+ {
+ perror(core_name);
+ exit(1);
+ }
+ if ((new = fopen(new_name, "w")) == NULL)
+ {
+ perror(new_name);
+ exit(1);
+ }
+
+ read_u(core);
+ make_hdr(new, a_out);
+ copy_text(new, a_out);
+ copy_data(new, core);
+ copy_sym(new, a_out);
+ fclose(new);
+ fclose(core);
+ fclose(a_out);
+ mark_x(new_name);
+}
+
+/*
+ * read the u structure from the core file.
+ */
+read_u(core)
+FILE *core;
+{
+ if ( fread(&u, sizeof u, 1, core) != 1 )
+ {
+ perror("Couldn't read user structure from core file");
+ exit(1);
+ }
+}
+
+/*
+ * Make the header in the new a.out from the header in the old one
+ * modified by the new data size.
+ */
+make_hdr(new, a_out)
+FILE *new, *a_out;
+{
+
+ int i;
+
+/* sym_top points to the beginning of the line#/sym/str data */
+
+/*
+ * read file header from a.out
+ */
+
+ if (fread(&fhdr, sizeof fhdr, 1, a_out) != 1)
+ {
+ perror("Couldn't read file header from a.out file");
+ exit(1);
+ }
+
+/*
+ * read system header from a.out COFF format
+ */
+
+ if (fhdr.f_opthdr > 0)
+ {
+ if (fread(&ahdr, sizeof ahdr, 1, a_out) != 1)
+ {
+ perror("Couldn't read system file header from a.out file");
+ exit(1);
+ }
+
+/*
+ * read section headers from a.out COFF format
+ */
+
+ nscns = fhdr.f_nscns;
+ for(i=0;(i != nscns);i++) {
+ if (fread(&scns[i], sizeof(struct scnhdr), 1, a_out) != 1) {
+ perror("Couldn't read section headers from a.out file");
+ exit(1);
+ }
+ }
+ }
+
+
+/* if N_BADMAG(hdr)
+ {
+ fprintf(stderr, "a.out file doesn't have legal magic number\n");
+ exit(1);
+ } */
+
+
+
+ if (ahdr.magic != u.pt_aouthdr.magic ||
+ ahdr.tsize != u.pt_aouthdr.tsize ||
+ ahdr.dsize != u.pt_aouthdr.dsize ||
+ ahdr.entry != u.pt_aouthdr.entry)
+ {
+ fprintf(stderr, "Core file didn't come from this a.out\n");
+ exit(1);
+ }
+
+ printf("Data segment size was %u", ahdr.dsize);
+ ahdr.dsize = u.pt_dsize;
+ ahdr.bsize = 0; /* all data is inited now! */
+ printf(" now is %u\n", ahdr.dsize);
+
+
+/*
+ * point to top of old line#/symbol/string info if there is any so
+ * we can find it later...
+ */
+
+ sym_top = 0;
+ if (scns[0].s_nlnno != 0)
+ sym_top = scns[0].s_lnnoptr;
+ else if (fhdr.f_nsyms != 0)
+ sym_top = fhdr.f_symptr;
+
+ scns[1].s_size = u.pt_dsize;
+ scns[2].s_size = 0;
+ scns[2].s_vaddr = 0;
+ scns[2].s_paddr = 0;
+
+ cur_pos = scns[1].s_scnptr + scns[1].s_size;
+
+ if (scns[0].s_nlnno != 0) {
+ scns[0].s_lnnoptr = cur_pos;
+ cur_pos += scns[0].s_nlnno * sizeof(struct lineno);
+ }
+ if (fhdr.f_nsyms != 0) {
+ fhdr.f_symptr = cur_pos;
+ }
+
+
+
+
+ if (fwrite(&fhdr, sizeof fhdr, 1, new) != 1)
+ {
+ perror("Couldn't write file header to new a.out file");
+ exit(1);
+ }
+ if (fhdr.f_opthdr > 0)
+ {
+ if (fwrite(&ahdr, sizeof ahdr, 1, new) != 1)
+ {
+ perror("Couldn't write system file header to new a.out file");
+ exit(1);
+ }
+ for(i=0;(i != nscns);i++) {
+ if (fwrite(&scns[i], sizeof(struct scnhdr), 1, new) != 1) {
+ perror("Couldn't write section headers to new a.out file");
+ exit(1);
+ }
+ }
+ }
+
+}
+
+/*
+ * Copy the text from the a.out to the new a.out
+ */
+copy_text(new, a_out)
+FILE *new, *a_out;
+{
+ char page[PSIZE];
+ int txtcnt;
+
+ txtcnt = ahdr.tsize;
+
+ fseek(new, scns[0].s_scnptr, 0);
+ fseek(a_out, scns[0].s_scnptr, 0);
+
+/* if (hdr.a_magic == OMAGIC)
+ {
+ printf("a.out file is not shared text, getting text from core file\n");
+ fseek(a_out, hdr.a_text, 1); * skip over text *
+ return;
+ } */
+
+
+ while (txtcnt >= PSIZE)
+ {
+ if (fread(page, PSIZE, 1, a_out) != 1)
+ {
+ perror("Read failure on a.out text");
+ exit(1);
+ }
+ if (fwrite(page, PSIZE, 1, new) != 1)
+ {
+ perror("Write failure in text segment");
+ exit(1);
+ }
+ txtcnt -= PSIZE;
+ }
+ if (txtcnt)
+ {
+ if (fread(page, txtcnt, 1, a_out) != 1)
+ {
+ perror("Read failure on a.out text");
+ exit(1);
+ }
+ if (fwrite(page, txtcnt, 1, new) != 1)
+ {
+ perror("Write failure in text segment");
+ exit(1);
+ }
+ }
+}
+
+/*
+ * copy the data from the core file to the new a.out
+ */
+copy_data(new, core)
+FILE *new, *core;
+{
+ char page[PSIZE];
+ int datacnt;
+
+
+ datacnt = u.pt_dsize;
+
+/* if (hdr.a_magic == OMAGIC)
+ datacnt += u.u_tsize; */
+ fseek(core,(long) sizeof(struct ptrace_user), 0);
+ fseek(new, scns[1].s_scnptr, 0);
+ while (datacnt >= PSIZE)
+ {
+ if (fread(page, PSIZE, 1, core) != 1)
+ {
+ perror("Read failure on core data");
+ exit(1);
+ }
+ if (fwrite(page, PSIZE, 1, new) != 1)
+ {
+ perror("Write failure in data segment");
+ exit(1);
+ }
+ datacnt -= PSIZE;
+ }
+ if (datacnt)
+ {
+ if (fread(page, datacnt, 1, core) != 1)
+ {
+ perror("Read failure on core data");
+ exit(1);
+ }
+ if (fwrite(page, datacnt, 1, new) != 1)
+ {
+ perror("Write failure in data segment");
+ exit(1);
+ }
+ }
+}
+
+/*
+ * Copy the relocation information and symbol table from the a.out to the new
+ */
+copy_sym(new, a_out)
+FILE *new, *a_out;
+{
+ char page[PSIZE];
+ int n;
+
+ fseek(a_out, sym_top, 0); /* skip over data segment */
+ while ((n = fread(page, 1, PSIZE, a_out)) > 0)
+ {
+ if (fwrite(page, 1, n, new) != n)
+ {
+ perror("Error writing symbol table to new a.out");
+ fprintf(stderr, "new a.out should be ok otherwise\n");
+ return;
+ }
+ }
+ if (n < 0)
+ {
+ perror("Error reading symbol table from a.out");
+ fprintf(stderr, "new a.out should be ok otherwise\n");
+ }
+}
+
+/*
+ * After succesfully building the new a.out, mark it executable
+ */
+mark_x(name)
+char *name;
+{
+ struct stat sbuf;
+ int um;
+
+ um = umask(777);
+ umask(um);
+ if (stat(name, &sbuf) == -1)
+ {
+ perror ("Can't stat new a.out");
+ fprintf(stderr, "Setting protection to %o\n", 0777 & ~um);
+ sbuf.st_mode = 0777;
+ }
+ sbuf.st_mode |= 0111 & ~um;
+ if (chmod(name, sbuf.st_mode) == -1)
+ perror("Couldn't change mode of new a.out to executable");
+
+}
+
diff --git a/obsolete/support/undump/Encore/unexec.c b/obsolete/support/undump/Encore/unexec.c
new file mode 100644
index 0000000000..a4ced6bf69
--- /dev/null
+++ b/obsolete/support/undump/Encore/unexec.c
@@ -0,0 +1,1143 @@
+/* Copyright (C) 1985, 1986, 1987 Free Software Foundation, Inc.
+
+ NO WARRANTY
+
+ BECAUSE THIS PROGRAM IS LICENSED FREE OF CHARGE, WE PROVIDE ABSOLUTELY
+NO WARRANTY, TO THE EXTENT PERMITTED BY APPLICABLE STATE LAW. EXCEPT
+WHEN OTHERWISE STATED IN WRITING, FREE SOFTWARE FOUNDATION, INC,
+RICHARD M. STALLMAN AND/OR OTHER PARTIES PROVIDE THIS PROGRAM "AS IS"
+WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY
+AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE
+DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR
+CORRECTION.
+
+ IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW WILL RICHARD M.
+STALLMAN, THE FREE SOFTWARE FOUNDATION, INC., AND/OR ANY OTHER PARTY
+WHO MAY MODIFY AND REDISTRIBUTE THIS PROGRAM AS PERMITTED BELOW, BE
+LIABLE TO YOU FOR DAMAGES, INCLUDING ANY LOST PROFITS, LOST MONIES, OR
+OTHER SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
+USE OR INABILITY TO USE (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR
+DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY THIRD PARTIES OR
+A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS) THIS
+PROGRAM, EVEN IF YOU HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH
+DAMAGES, OR FOR ANY CLAIM BY ANY OTHER PARTY.
+
+ GENERAL PUBLIC LICENSE TO COPY
+
+ 1. You may copy and distribute verbatim copies of this source file
+as you receive it, in any medium, provided that you conspicuously and
+appropriately publish on each copy a valid copyright notice "Copyright
+(C) 1987 Free Software Foundation, Inc."; and include following the
+copyright notice a verbatim copy of the above disclaimer of warranty
+and of this License. You may charge a distribution fee for the
+physical act of transferring a copy.
+
+ 2. You may modify your copy or copies of this source file or
+any portion of it, and copy and distribute such modifications under
+the terms of Paragraph 1 above, provided that you also do the following:
+
+ a) cause the modified files to carry prominent notices stating
+ that you changed the files and the date of any change; and
+
+ b) cause the whole of any work that you distribute or publish,
+ that in whole or in part contains or is a derivative of this
+ program or any part thereof, to be licensed at no charge to all
+ third parties on terms identical to those contained in this
+ License Agreement (except that you may choose to grant more
+ extensive warranty protection to third parties, at your option).
+
+ c) You may charge a distribution fee for the physical act of
+ transferring a copy, and you may at your option offer warranty
+ protection in exchange for a fee.
+
+ 3. You may copy and distribute this program or any portion of it in
+compiled, executable or object code form under the terms of Paragraphs
+1 and 2 above provided that you do the following:
+
+ a) cause each such copy to be accompanied by the
+ corresponding machine-readable source code, which must
+ be distributed under the terms of Paragraphs 1 and 2 above; or,
+
+ b) cause each such copy to be accompanied by a
+ written offer, with no time limit, to give any third party
+ free (except for a nominal shipping charge) a machine readable
+ copy of the corresponding source code, to be distributed
+ under the terms of Paragraphs 1 and 2 above; or,
+
+ c) in the case of a recipient of this program in compiled, executable
+ or object code form (without the corresponding source code) you
+ shall cause copies you distribute to be accompanied by a copy
+ of the written offer of source code which you received along
+ with the copy you received.
+
+ 4. You may not copy, sublicense, distribute or transfer this program
+except as expressly provided under this License Agreement. Any attempt
+otherwise to copy, sublicense, distribute or transfer this program is void and
+your rights to use the program under this License agreement shall be
+automatically terminated. However, parties who have received computer
+software programs from you with this License Agreement will not have
+their licenses terminated so long as such parties remain in full compliance.
+
+ 5. If you wish to incorporate parts of this program into other free
+programs whose distribution conditions are different, write to the Free
+Software Foundation at 675 Mass Ave, Cambridge, MA 02139. We have not yet
+worked out a simple rule that can be stated here, but we will often permit
+this. We will be guided by the two goals of preserving the free status of
+all derivatives of our free software and of promoting the sharing and reuse of
+software.
+
+
+In other words, you are welcome to use, share and improve this program.
+You are forbidden to forbid anyone else to use, share and improve
+what you give them. Help stamp out software-hoarding! */
+
+
+/*
+ * unexec.c - Convert a running program into an a.out file.
+ *
+ * Author: Spencer W. Thomas
+ * Computer Science Dept.
+ * University of Utah
+ * Date: Tue Mar 2 1982
+ * Modified heavily since then.
+ *
+ * Synopsis:
+ * unexec (new_name, a_name, data_start, bss_start, entry_address)
+ * char *new_name, *a_name;
+ * unsigned data_start, bss_start, entry_address;
+ *
+ * Takes a snapshot of the program and makes an a.out format file in the
+ * file named by the string argument new_name.
+ * If a_name is non-NULL, the symbol table will be taken from the given file.
+ * On some machines, an existing a_name file is required.
+ *
+ * The boundaries within the a.out file may be adjusted with the data_start
+ * and bss_start arguments. Either or both may be given as 0 for defaults.
+ *
+ * Data_start gives the boundary between the text segment and the data
+ * segment of the program. The text segment can contain shared, read-only
+ * program code and literal data, while the data segment is always unshared
+ * and unprotected. Data_start gives the lowest unprotected address.
+ * The value you specify may be rounded down to a suitable boundary
+ * as required by the machine you are using.
+ *
+ * Specifying zero for data_start means the boundary between text and data
+ * should not be the same as when the program was loaded.
+ * If NO_REMAP is defined, the argument data_start is ignored and the
+ * segment boundaries are never changed.
+ *
+ * Bss_start indicates how much of the data segment is to be saved in the
+ * a.out file and restored when the program is executed. It gives the lowest
+ * unsaved address, and is rounded up to a page boundary. The default when 0
+ * is given assumes that the entire data segment is to be stored, including
+ * the previous data and bss as well as any additional storage allocated with
+ * break (2).
+ *
+ * The new file is set up to start at entry_address.
+ *
+ * If you make improvements I'd like to get them too.
+ * harpo!utah-cs!thomas, thomas@Utah-20
+ *
+ */
+
+/* There are several compilation parameters affecting unexec:
+
+* COFF
+
+Define this if your system uses COFF for executables.
+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
+as part of the text segment.
+
+Saving them as text is good because it allows users to share more.
+
+However, on machines that locate the text area far from the data area,
+the boundary cannot feasibly be moved. Such machines require
+NO_REMAP.
+
+Also, remapping can cause trouble with the built-in startup routine
+/lib/crt0.o, which defines `environ' as an initialized variable.
+Dumping `environ' as pure does not work! So, to use remapping,
+you must write a startup routine for your machine in Emacs's crt0.c.
+If NO_REMAP is defined, Emacs uses the system's crt0.o.
+
+* SECTION_ALIGNMENT
+
+Some machines that use COFF executables require that each section
+start on a certain boundary *in the COFF file*. Such machines should
+define SECTION_ALIGNMENT to a mask of the low-order bits that must be
+zero on such a boundary. This mask is used to control padding between
+segments in the COFF file.
+
+If SECTION_ALIGNMENT is not defined, the segments are written
+consecutively with no attempt at alignment. This is right for
+unmodified system V.
+
+* SEGMENT_MASK
+
+Some machines require that the beginnings and ends of segments
+*in core* be on certain boundaries. For most machines, a page
+boundary is sufficient. That is the default. When a larger
+boundary is needed, define SEGMENT_MASK to a mask of
+the bits that must be zero on such a boundary.
+
+* A_TEXT_OFFSET(HDR)
+
+Some machines count the a.out header as part of the size of the text
+segment (a_text); they may actually load the header into core as the
+first data in the text segment. Some have additional padding between
+the header and the real text of the program that is counted in a_text.
+
+For these machines, define A_TEXT_OFFSET(HDR) to examine the header
+structure HDR and return the number of bytes to add to `a_text'
+before writing it (above and beyond the number of bytes of actual
+program text). HDR's standard fields are already correct, except that
+this adjustment to the `a_text' field has not yet been made;
+thus, the amount of offset can depend on the data in the file.
+
+* A_TEXT_SEEK(HDR)
+
+If defined, this macro specifies the number of bytes to seek into the
+a.out file before starting to write the text segment.a
+
+* 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
+initialize nonstandard fields in the file header
+
+* ADDR_CORRECT(ADDR)
+
+Macro to correct an int which is the bit pattern of a pointer to a byte
+into an int which is the number of a byte.
+
+This macro has a default definition which is usually right.
+This default definition is a no-op on most machines (where a
+pointer looks like an int) but not on all machines.
+
+*/
+
+#ifndef emacs
+#define PERROR(arg) perror (arg); return -1
+#else
+#include "config.h"
+#define PERROR(file) report_error (file, new)
+#endif
+
+#ifndef CANNOT_DUMP /* all rest of file! */
+
+#ifndef CANNOT_UNEXEC /* most of rest of file */
+
+#ifndef mips /* mips machine requires completely separate code. */
+
+#include <a.out.h>
+/* Define getpagesize () if the system does not.
+ Note that this may depend on symbols defined in a.out.h
+ */
+#include "getpagesize.h"
+
+#ifndef makedev /* Try to detect types.h already loaded */
+#include <sys/types.h>
+#endif
+#include <stdio.h>
+#include <sys/stat.h>
+#include <errno.h>
+
+extern char *start_of_text (); /* Start of text */
+extern char *start_of_data (); /* Start of initialized data */
+
+#ifdef COFF
+#ifndef USG
+#ifndef STRIDE
+#ifndef UMAX
+/* I have a suspicion that these are turned off on all systems
+ and can be deleted. Try it in version 19. */
+#include <filehdr.h>
+#include <aouthdr.h>
+#include <scnhdr.h>
+#include <syms.h>
+#endif /* not UMAX */
+#endif /* Not STRIDE */
+#endif /* not USG */
+static long block_copy_start; /* Old executable start point */
+static struct filehdr f_hdr; /* File header */
+static struct aouthdr f_ohdr; /* Optional file header (a.out) */
+long bias; /* Bias to add for growth */
+long lnnoptr; /* Pointer to line-number info within file */
+#define SYMS_START block_copy_start
+
+static long text_scnptr;
+static long data_scnptr;
+
+#else /* not COFF */
+
+extern char *sbrk ();
+
+#define SYMS_START ((long) N_SYMOFF (ohdr))
+
+#ifdef HPUX
+#ifdef HP9000S200_ID
+#define MY_ID HP9000S200_ID
+#else
+#include <model.h>
+#define MY_ID MYSYS
+#endif /* no HP9000S200_ID */
+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 struct exec hdr, ohdr;
+
+#else /* not HPUX */
+
+#if defined (USG) && !defined (IRIS)
+static struct bhdr hdr, ohdr;
+#define a_magic fmagic
+#define a_text tsize
+#define a_data dsize
+#define a_bss bsize
+#define a_syms ssize
+#define a_trsize rtsize
+#define a_drsize rdsize
+#define a_entry entry
+#define N_BADMAG(x) \
+ (((x).fmagic)!=OMAGIC && ((x).fmagic)!=NMAGIC &&\
+ ((x).fmagic)!=FMAGIC && ((x).fmagic)!=IMAGIC)
+#define NEWMAGIC FMAGIC
+#else /* IRIS or not USG */
+static struct exec hdr, ohdr;
+#define NEWMAGIC ZMAGIC
+#endif /* IRIS or not USG */
+#endif /* not HPUX */
+
+static int unexec_text_start;
+static int unexec_data_start;
+
+#endif /* not COFF */
+
+static int pagemask;
+
+/* Correct an int which is the bit pattern of a pointer to a byte
+ into an int which is the number of a byte.
+ This is a no-op on ordinary machines, but not on all. */
+
+#ifndef ADDR_CORRECT /* Let m-*.h files override this definition */
+#define ADDR_CORRECT(x) ((char *)(x) - (char*)0)
+#endif
+
+#ifdef emacs
+
+static
+report_error (file, fd)
+ char *file;
+ int fd;
+{
+ if (fd)
+ close (fd);
+ error ("Failure operating on %s", file);
+}
+#endif /* emacs */
+
+#define ERROR0(msg) report_error_1 (new, msg, 0, 0); return -1
+#define ERROR1(msg,x) report_error_1 (new, msg, x, 0); return -1
+#define ERROR2(msg,x,y) report_error_1 (new, msg, x, y); return -1
+
+static
+report_error_1 (fd, msg, a1, a2)
+ int fd;
+ char *msg;
+ int a1, a2;
+{
+ close (fd);
+#ifdef emacs
+ error (msg, a1, a2);
+#else
+ fprintf (stderr, msg, a1, a2);
+ fprintf (stderr, "\n");
+#endif
+}
+
+/* ****************************************************************
+ * 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, 0)) < 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) < 0
+ || copy_sym (new, a_out, a_name, new_name) < 0
+#ifdef COFF
+ || adjust_lnnoptrs (new, a_out, new_name) < 0
+#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
+ *
+ * Make the header in the new a.out from the header in core.
+ * Modify the text and data sizes.
+ */
+static int
+make_hdr (new, a_out, data_start, bss_start, entry_address, a_name, new_name)
+ int new, a_out;
+ unsigned data_start, bss_start, entry_address;
+ char *a_name;
+ char *new_name;
+{
+ int tem;
+#ifdef COFF
+ auto struct scnhdr f_thdr; /* Text section header */
+ auto struct scnhdr f_dhdr; /* Data section header */
+ auto struct scnhdr f_bhdr; /* Bss section header */
+ auto struct scnhdr scntemp; /* Temporary section header */
+ register int scns;
+#endif /* COFF */
+ unsigned int bss_end;
+#ifdef UMAX
+ extern etext;
+#endif
+
+ pagemask = getpagesize () - 1;
+
+ /* Adjust text/data boundary. */
+#ifdef NO_REMAP
+ data_start = (int) start_of_data ();
+#else /* not NO_REMAP */
+#ifndef UMAX
+ if (!data_start)
+#endif
+ data_start = (int) start_of_data ();
+#endif /* not NO_REMAP */
+ data_start = ADDR_CORRECT (data_start);
+
+#ifdef SEGMENT_MASK
+ data_start = data_start & ~SEGMENT_MASK; /* (Down) to segment boundary. */
+#else
+ data_start = data_start & ~pagemask; /* (Down) to page boundary. */
+#endif
+
+ bss_end = ADDR_CORRECT (sbrk (0)) + pagemask;
+ bss_end &= ~ pagemask;
+
+ /* Adjust data/bss boundary. */
+ if (bss_start != 0)
+ {
+ bss_start = (ADDR_CORRECT (bss_start) + pagemask);
+ /* (Up) to page bdry. */
+ bss_start &= ~ pagemask;
+ if (bss_start > bss_end)
+ {
+ ERROR1 ("unexec: Specified bss_start (%u) is past end of program",
+ bss_start);
+ }
+ }
+ else
+ bss_start = bss_end;
+
+ if (data_start > bss_start) /* Can't have negative data size. */
+ {
+ ERROR2 ("unexec: data_start (%u) can't be greater than bss_start (%u)",
+ data_start, bss_start);
+ }
+
+#ifdef COFF
+ /* Salvage as much info from the existing file as possible */
+ if (a_out >= 0)
+ {
+ if (read (a_out, &f_hdr, sizeof (f_hdr)) != sizeof (f_hdr))
+ {
+ PERROR (a_name);
+ }
+ block_copy_start += sizeof (f_hdr);
+ if (f_hdr.f_opthdr > 0)
+ {
+ if (read (a_out, &f_ohdr, sizeof (f_ohdr)) != sizeof (f_ohdr))
+ {
+ PERROR (a_name);
+ }
+ block_copy_start += sizeof (f_ohdr);
+ }
+ /* Loop through section headers, copying them in */
+ for (scns = f_hdr.f_nscns; scns > 0; scns--) {
+ if (read (a_out, &scntemp, sizeof (scntemp)) != sizeof (scntemp))
+ {
+ PERROR (a_name);
+ }
+ if (scntemp.s_scnptr > 0L)
+ {
+ if (block_copy_start < scntemp.s_scnptr + scntemp.s_size)
+ block_copy_start = scntemp.s_scnptr + scntemp.s_size;
+ }
+ if (strcmp (scntemp.s_name, ".text") == 0)
+ {
+ f_thdr = scntemp;
+ }
+ else if (strcmp (scntemp.s_name, ".data") == 0)
+ {
+ f_dhdr = scntemp;
+ }
+ else if (strcmp (scntemp.s_name, ".bss") == 0)
+ {
+ f_bhdr = scntemp;
+ }
+ }
+ }
+ else
+ {
+ ERROR0 ("can't build a COFF file from scratch yet");
+ }
+
+ /* Now we alter the contents of all the f_*hdr variables
+ to correspond to what we want to dump. */
+
+ f_hdr.f_flags |= (F_RELFLG | F_EXEC);
+#ifdef EXEC_MAGIC
+ f_ohdr.magic = EXEC_MAGIC;
+#endif
+#ifndef NO_REMAP
+ f_ohdr.text_start = (long) start_of_text ();
+#ifdef UMAX
+ f_ohdr.tsize = (long) &etext;
+#else
+ f_ohdr.tsize = data_start - f_ohdr.text_start;
+#endif
+ f_ohdr.data_start = data_start;
+#endif /* NO_REMAP */
+ f_ohdr.dsize = bss_start - f_ohdr.data_start;
+ f_ohdr.bsize = bss_end - bss_start;
+ 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));
+ lnnoptr = f_thdr.s_lnnoptr;
+#ifdef SECTION_ALIGNMENT
+ /* Some systems require special alignment
+ of the sections in the file itself. */
+ f_thdr.s_scnptr
+ = (f_thdr.s_scnptr + SECTION_ALIGNMENT) & ~SECTION_ALIGNMENT;
+#endif /* SECTION_ALIGNMENT */
+ text_scnptr = f_thdr.s_scnptr;
+ f_dhdr.s_paddr = f_ohdr.data_start;
+ 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;
+#ifdef SECTION_ALIGNMENT
+ /* Some systems require special alignment
+ of the sections in the file itself. */
+ f_dhdr.s_scnptr
+ = (f_dhdr.s_scnptr + SECTION_ALIGNMENT) & ~SECTION_ALIGNMENT;
+#endif /* SECTION_ALIGNMENT */
+ data_scnptr = f_dhdr.s_scnptr;
+ f_bhdr.s_paddr = f_ohdr.data_start + f_ohdr.dsize;
+ f_bhdr.s_vaddr = f_ohdr.data_start + f_ohdr.dsize;
+ f_bhdr.s_size = f_ohdr.bsize;
+ f_bhdr.s_scnptr = 0L;
+ bias = f_dhdr.s_scnptr + f_dhdr.s_size - block_copy_start;
+
+ if (f_hdr.f_symptr > 0L)
+ {
+ f_hdr.f_symptr += bias;
+ }
+
+ if (f_thdr.s_lnnoptr > 0L)
+ {
+ f_thdr.s_lnnoptr += bias;
+ }
+
+#ifdef ADJUST_EXEC_HEADER
+ ADJUST_EXEC_HEADER
+#endif /* ADJUST_EXEC_HEADER */
+
+ if (write (new, &f_hdr, sizeof (f_hdr)) != sizeof (f_hdr))
+ {
+ PERROR (new_name);
+ }
+
+ if (write (new, &f_ohdr, sizeof (f_ohdr)) != sizeof (f_ohdr))
+ {
+ PERROR (new_name);
+ }
+
+ if (write (new, &f_thdr, sizeof (f_thdr)) != sizeof (f_thdr))
+ {
+ PERROR (new_name);
+ }
+
+ if (write (new, &f_dhdr, sizeof (f_dhdr)) != sizeof (f_dhdr))
+ {
+ PERROR (new_name);
+ }
+
+ if (write (new, &f_bhdr, sizeof (f_bhdr)) != sizeof (f_bhdr))
+ {
+ PERROR (new_name);
+ }
+ return (0);
+
+#else /* if not COFF */
+
+ /* Get symbol table info from header of a.out file if given one. */
+ if (a_out >= 0)
+ {
+ if (read (a_out, &ohdr, sizeof hdr) != sizeof hdr)
+ {
+ PERROR (a_name);
+ }
+
+ if N_BADMAG (ohdr)
+ {
+ ERROR1 ("invalid magic number in %s", a_name);
+ }
+ hdr = ohdr;
+ }
+ else
+ {
+ bzero (hdr, sizeof hdr);
+ }
+
+ unexec_text_start = (long) start_of_text ();
+ unexec_data_start = data_start;
+
+ /* Machine-dependent fixup for header, or maybe for unexec_text_start */
+#ifdef ADJUST_EXEC_HEADER
+ ADJUST_EXEC_HEADER;
+#endif /* ADJUST_EXEC_HEADER */
+
+ hdr.a_trsize = 0;
+ hdr.a_drsize = 0;
+ if (entry_address != 0)
+ hdr.a_entry = entry_address;
+
+ hdr.a_bss = bss_end - bss_start;
+ hdr.a_data = bss_start - data_start;
+#ifdef NO_REMAP
+ hdr.a_text = ohdr.a_text;
+#else /* not NO_REMAP */
+ hdr.a_text = data_start - unexec_text_start;
+#endif /* not NO_REMAP */
+
+#ifdef A_TEXT_OFFSET
+ hdr.a_text += A_TEXT_OFFSET (ohdr);
+#endif
+
+ if (write (new, &hdr, sizeof hdr) != sizeof hdr)
+ {
+ PERROR (new_name);
+ }
+
+#ifdef A_TEXT_OFFSET
+ hdr.a_text -= A_TEXT_OFFSET (ohdr);
+#endif
+
+ return 0;
+
+#endif /* not COFF */
+}
+
+/* ****************************************************************
+ * copy_text_and_data
+ *
+ * Copy the text and data segments from memory to the new a.out
+ */
+static int
+copy_text_and_data (new)
+ int new;
+{
+ register char *end;
+ register char *ptr;
+
+#ifdef COFF
+ lseek (new, (long) text_scnptr, 0);
+ ptr = (char *) f_ohdr.text_start;
+ end = ptr + f_ohdr.tsize;
+ write_segment (new, ptr, end);
+
+ lseek (new, (long) data_scnptr, 0);
+ ptr = (char *) f_ohdr.data_start;
+ end = ptr + f_ohdr.dsize;
+ write_segment (new, ptr, end);
+
+#else /* if not COFF */
+
+/* Some machines count the header as part of the text segment.
+ That is to say, the header appears in core
+ just before the address that start_of_text () returns.
+ For them, N_TXTOFF is the place where the header goes.
+ We must adjust the seek to the place after the header.
+ Note that at this point hdr.a_text does *not* count
+ the extra A_TEXT_OFFSET bytes, only the actual bytes of code. */
+
+#ifdef A_TEXT_SEEK
+ lseek (new, (long) A_TEXT_SEEK (hdr), 0);
+#else
+#ifdef A_TEXT_OFFSET
+ /* Note that on the Sequent machine A_TEXT_OFFSET != sizeof (hdr)
+ and sizeof (hdr) is the correct amount to add here. */
+ /* In version 19, eliminate this case and use A_TEXT_SEEK whenever
+ N_TXTOFF is not right. */
+ lseek (new, (long) N_TXTOFF (hdr) + sizeof (hdr), 0);
+#else
+ lseek (new, (long) N_TXTOFF (hdr), 0);
+#endif /* no A_TEXT_OFFSET */
+#endif /* no A_TEXT_SEEK */
+
+ ptr = (char *) unexec_text_start;
+ end = ptr + hdr.a_text;
+ write_segment (new, ptr, end);
+
+ ptr = (char *) unexec_data_start;
+ end = ptr + hdr.a_data;
+/* This lseek is certainly incorrect when A_TEXT_OFFSET
+ and I believe it is a no-op otherwise.
+ Let's see if its absence ever fails. */
+/* lseek (new, (long) N_TXTOFF (hdr) + hdr.a_text, 0); */
+ write_segment (new, ptr, end);
+
+#endif /* not COFF */
+
+ return 0;
+}
+
+write_segment (new, ptr, end)
+ int new;
+ register char *ptr, *end;
+{
+ register int i, nwrite, ret;
+ char buf[80];
+ extern int errno;
+ char zeros[128];
+
+ bzero (zeros, sizeof zeros);
+
+ for (i = 0; ptr < end;)
+ {
+ /* distance to next multiple of 128. */
+ nwrite = (((int) ptr + 128) & -128) - (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 && errno == EFAULT)
+ write (new, zeros, nwrite);
+ 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);
+ }
+ i += nwrite;
+ ptr += nwrite;
+ }
+}
+
+/* ****************************************************************
+ * copy_sym
+ *
+ * Copy the relocation information and symbol table from the a.out to the new
+ */
+static int
+copy_sym (new, a_out, a_name, new_name)
+ int new, a_out;
+ char *a_name, *new_name;
+{
+ char page[1024];
+ int n;
+
+ if (a_out < 0)
+ return 0;
+
+#ifdef COFF
+ if (SYMS_START == 0L)
+ return 0;
+#endif /* COFF */
+
+#ifdef COFF
+ if (lnnoptr) /* if there is line number info */
+ lseek (a_out, lnnoptr, 0); /* start copying from there */
+ else
+#endif /* COFF */
+ lseek (a_out, SYMS_START, 0); /* Position a.out to symtab. */
+
+ while ((n = read (a_out, page, sizeof page)) > 0)
+ {
+ if (write (new, page, n) != n)
+ {
+ PERROR (new_name);
+ }
+ }
+ if (n < 0)
+ {
+ PERROR (a_name);
+ }
+ return 0;
+}
+
+/* ****************************************************************
+ * mark_x
+ *
+ * After succesfully building the new a.out, mark it executable
+ */
+static
+mark_x (name)
+ char *name;
+{
+ struct stat sbuf;
+ int um;
+ int new = 0; /* for PERROR */
+
+ um = umask (777);
+ umask (um);
+ if (stat (name, &sbuf) == -1)
+ {
+ PERROR (name);
+ }
+ sbuf.st_mode |= 0111 & ~um;
+ if (chmod (name, sbuf.st_mode) == -1)
+ PERROR (name);
+}
+
+/*
+ * If the COFF file contains a symbol table and a line number section,
+ * then any auxiliary entries that have values for x_lnnoptr must
+ * be adjusted by the amount that the line number section has moved
+ * in the file (bias computed in make_hdr). The #@$%&* designers of
+ * the auxiliary entry structures used the absolute file offsets for
+ * the line number entry rather than an offset from the start of the
+ * line number section!
+ *
+ * When I figure out how to scan through the symbol table and pick out
+ * the auxiliary entries that need adjustment, this routine will
+ * be fixed. As it is now, all such entries are wrong and sdb
+ * will complain. Fred Fish, UniSoft Systems Inc.
+ */
+
+#ifdef COFF
+
+/* This function is probably very slow. Instead of reopening the new
+ file for input and output it should copy from the old to the new
+ using the two descriptors already open (WRITEDESC and READDESC).
+ Instead of reading one small structure at a time it should use
+ a reasonable size buffer. But I don't have time to work on such
+ things, so I am installing it as submitted to me. -- RMS. */
+
+adjust_lnnoptrs (writedesc, readdesc, new_name)
+ int writedesc;
+ int readdesc;
+ char *new_name;
+{
+ register int nsyms;
+ register int new;
+#ifdef amdahl_uts
+ SYMENT symentry;
+ AUXENT auxentry;
+#else
+ struct syment symentry;
+ struct auxent auxentry;
+#endif
+
+ if (!lnnoptr || !f_hdr.f_symptr)
+ return 0;
+
+ if ((new = open (new_name, 2)) < 0)
+ {
+ PERROR (new_name);
+ return -1;
+ }
+
+ lseek (new, f_hdr.f_symptr, 0);
+ for (nsyms = 0; nsyms < f_hdr.f_nsyms; nsyms++)
+ {
+ read (new, &symentry, SYMESZ);
+ if (symentry.n_numaux)
+ {
+ read (new, &auxentry, AUXESZ);
+ nsyms++;
+ if (ISFCN (symentry.n_type)) {
+ auxentry.x_sym.x_fcnary.x_fcn.x_lnnoptr += bias;
+ lseek (new, -AUXESZ, 1);
+ write (new, &auxentry, AUXESZ);
+ }
+ }
+ }
+ close (new);
+}
+
+#endif /* COFF */
+
+
+#else /* mips */
+
+/* Unexec for mips machines.
+ Note that I regard it as the responsibility of people at Mips
+ to tell me about any changes that need to be made in this code.
+ I won't take responsibility to think about it even if a change
+ I make elsewhere causes it to break. -- RMS. */
+
+#include <sys/types.h>
+#include <sys/file.h>
+#include <sys/stat.h>
+#include <stdio.h>
+#include <varargs.h>
+#include <filehdr.h>
+#include <aouthdr.h>
+#include <scnhdr.h>
+#include <sym.h>
+
+#define private static
+
+extern int errno;
+extern int sys_nerr;
+extern char *sys_errlist[];
+#define EEOF -1
+
+private void
+fatal(s, va_alist)
+ va_dcl
+{
+ va_list ap;
+ if (errno == EEOF) {
+ fputs("unexec: unexpected end of file, ", stderr);
+ }
+ else if (errno < sys_nerr) {
+ fprintf(stderr, "unexec: %s, ", sys_errlist[errno]);
+ }
+ else {
+ fprintf(stderr, "unexec: error code %d, ", errno);
+ }
+ va_start(ap);
+ _doprnt(s, ap, stderr);
+ fputs(".\n", stderr);
+ exit(1);
+}
+
+#define READ(_fd, _buffer, _size, _error_message, _error_arg) \
+ errno = EEOF; \
+ if (read(_fd, _buffer, _size) != _size) \
+ fatal(_error_message, _error_arg);
+
+#define WRITE(_fd, _buffer, _size, _error_message, _error_arg) \
+ if (write(_fd, _buffer, _size) != _size) \
+ fatal(_error_message, _error_arg);
+
+#define SEEK(_fd, _position, _error_message, _error_arg) \
+ errno = EEOF; \
+ if (lseek(_fd, _position, L_SET) != _position) \
+ fatal(_error_message, _error_arg);
+
+struct headers {
+ struct filehdr fhdr;
+ struct aouthdr aout;
+ struct scnhdr text_section;
+ struct scnhdr rdata_section;
+ struct scnhdr data_section;
+ struct scnhdr sdata_section;
+ struct scnhdr sbss_section;
+ struct scnhdr bss_section;
+};
+
+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, old;
+ int pagesize, brk;
+ int newsyms, symrel;
+ int nread;
+ struct headers hdr;
+#define BUFSIZE 8192
+ char buffer[BUFSIZE];
+
+ old = open (a_name, O_RDONLY, 0);
+ if (old < 0) fatal("openning %s", a_name);
+
+ new = creat (new_name, 0666);
+ if (new < 0) fatal("creating %s", new_name);
+
+ hdr = *((struct headers *)TEXT_START);
+ if (hdr.fhdr.f_magic != MIPSELMAGIC
+ && hdr.fhdr.f_magic != MIPSEBMAGIC) {
+ fprintf(stderr, "unexec: input file magic number is %x, not %x or %x.\n",
+ hdr.fhdr.f_magic, MIPSELMAGIC, MIPSEBMAGIC);
+ exit(1);
+ }
+ if (hdr.fhdr.f_opthdr != sizeof(hdr.aout)) {
+ fprintf(stderr, "unexec: input a.out header is %d bytes, not %d.\n",
+ hdr.fhdr.f_opthdr, sizeof(hdr.aout));
+ exit(1);
+ }
+#if 0
+ if (hdr.aout.magic != ZMAGIC
+ && hdr.aout.magic != NMAGIC
+ && hdr.aout.magic != OMAGIC) {
+ fprintf(stderr, "unexec: input file a.out magic number is %o, not %o, %o, or %o.\n",
+ hdr.aout.magic, ZMAGIC, NMAGIC, OMAGIC);
+ exit(1);
+ }
+#else
+ if (hdr.aout.magic != ZMAGIC) {
+ fprintf(stderr, "unexec: input file a.out magic number is %o, not %o.\n",
+ hdr.aout.magic, ZMAGIC);
+ exit(1);
+ }
+#endif
+ if (hdr.fhdr.f_nscns != 6) {
+ fprintf(stderr, "unexec: %d sections instead of 6.\n", hdr.fhdr.f_nscns);
+ }
+#define CHECK_SCNHDR(field, name, flags) \
+ if (strcmp(hdr.field.s_name, name) != 0) { \
+ fprintf(stderr, "unexec: %s section where %s expected.\n", \
+ hdr.field.s_name, name); \
+ exit(1); \
+ } \
+ else if (hdr.field.s_flags != flags) { \
+ fprintf(stderr, "unexec: %x flags where %x expected in %s section.\n", \
+ hdr.field.s_flags, flags, name); \
+ }
+ CHECK_SCNHDR(text_section, _TEXT, STYP_TEXT);
+ CHECK_SCNHDR(rdata_section, _RDATA, STYP_RDATA);
+ CHECK_SCNHDR(data_section, _DATA, STYP_DATA);
+ CHECK_SCNHDR(sdata_section, _SDATA, STYP_SDATA);
+ CHECK_SCNHDR(sbss_section, _SBSS, STYP_SBSS);
+ CHECK_SCNHDR(bss_section, _BSS, STYP_BSS);
+
+ pagesize = getpagesize();
+ brk = (sbrk(0) + pagesize - 1) & (-pagesize);
+ hdr.aout.dsize = brk - DATA_START;
+ hdr.aout.bsize = 0;
+ if (entry_address == 0) {
+ extern __start();
+ hdr.aout.entry = (unsigned)__start;
+ }
+ else {
+ hdr.aout.entry = entry_address;
+ }
+ hdr.aout.bss_start = hdr.aout.data_start + hdr.aout.dsize;
+ hdr.rdata_section.s_size = data_start - DATA_START;
+ hdr.data_section.s_vaddr = data_start;
+ hdr.data_section.s_paddr = data_start;
+ hdr.data_section.s_size = brk - DATA_START;
+ hdr.data_section.s_scnptr = hdr.rdata_section.s_scnptr
+ + hdr.rdata_section.s_size;
+ hdr.sdata_section.s_vaddr = hdr.data_section.s_vaddr
+ + hdr.data_section.s_size;
+ hdr.sdata_section.s_paddr = hdr.sdata_section.s_paddr;
+ hdr.sdata_section.s_size = 0;
+ hdr.sdata_section.s_scnptr = hdr.data_section.s_scnptr
+ + hdr.data_section.s_size;
+ hdr.sbss_section.s_vaddr = hdr.sdata_section.s_vaddr
+ + hdr.sdata_section.s_size;
+ hdr.sbss_section.s_paddr = hdr.sbss_section.s_vaddr;
+ hdr.sbss_section.s_size = 0;
+ hdr.sbss_section.s_scnptr = hdr.sdata_section.s_scnptr
+ + hdr.sdata_section.s_size;
+ hdr.bss_section.s_vaddr = hdr.sbss_section.s_vaddr
+ + hdr.sbss_section.s_size;
+ hdr.bss_section.s_paddr = hdr.bss_section.s_vaddr;
+ hdr.bss_section.s_size = 0;
+ hdr.bss_section.s_scnptr = hdr.sbss_section.s_scnptr
+ + hdr.sbss_section.s_size;
+
+ WRITE(new, TEXT_START, hdr.aout.tsize,
+ "writing text section to %s", new_name);
+ WRITE(new, DATA_START, hdr.aout.dsize,
+ "writing text section to %s", new_name);
+
+ SEEK(old, hdr.fhdr.f_symptr, "seeking to start of symbols in %s", a_name);
+ errno = EEOF;
+ nread = read(old, buffer, BUFSIZE);
+ if (nread < sizeof(HDRR)) fatal("reading symbols from %s", a_name);
+#define symhdr ((pHDRR)buffer)
+ newsyms = hdr.aout.tsize + hdr.aout.dsize;
+ symrel = newsyms - hdr.fhdr.f_symptr;
+ hdr.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;
+#undef symhdr
+ do {
+ if (write(new, buffer, nread) != nread)
+ fatal("writing symbols to %s", new_name);
+ nread = read(old, buffer, BUFSIZE);
+ if (nread < 0) fatal("reading symbols from %s", a_name);
+#undef BUFSIZE
+ } while (nread != 0);
+
+ SEEK(new, 0, "seeking to start of header in %s", new_name);
+ WRITE(new, &hdr, sizeof(hdr),
+ "writing header of %s", new_name);
+
+ close(old);
+ close(new);
+ mark_x(new_name);
+}
+
+/*
+ * mark_x
+ *
+ * After succesfully building the new a.out, mark it executable
+ */
+static
+mark_x (name)
+ char *name;
+{
+ struct stat sbuf;
+ int um = umask (777);
+ umask (um);
+ if (stat(name, &sbuf) < 0)
+ fatal("getting protection on %s", name);
+ sbuf.st_mode |= 0111 & ~um;
+ if (chmod(name, sbuf.st_mode) < 0)
+ fatal("setting protection on %s", name);
+}
+
+#endif /* mips */
+
+#endif /* not CANNOT_UNEXEC */
+
+#endif /* not CANNOT_DUMP */
diff --git a/obsolete/support/undump/Encore/unexec.c-dist b/obsolete/support/undump/Encore/unexec.c-dist
new file mode 100644
index 0000000000..9855e90485
--- /dev/null
+++ b/obsolete/support/undump/Encore/unexec.c-dist
@@ -0,0 +1,1134 @@
+/* Copyright (C) 1985, 1986, 1987 Free Software Foundation, Inc.
+
+ NO WARRANTY
+
+ BECAUSE THIS PROGRAM IS LICENSED FREE OF CHARGE, WE PROVIDE ABSOLUTELY
+NO WARRANTY, TO THE EXTENT PERMITTED BY APPLICABLE STATE LAW. EXCEPT
+WHEN OTHERWISE STATED IN WRITING, FREE SOFTWARE FOUNDATION, INC,
+RICHARD M. STALLMAN AND/OR OTHER PARTIES PROVIDE THIS PROGRAM "AS IS"
+WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY
+AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE
+DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR
+CORRECTION.
+
+ IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW WILL RICHARD M.
+STALLMAN, THE FREE SOFTWARE FOUNDATION, INC., AND/OR ANY OTHER PARTY
+WHO MAY MODIFY AND REDISTRIBUTE THIS PROGRAM AS PERMITTED BELOW, BE
+LIABLE TO YOU FOR DAMAGES, INCLUDING ANY LOST PROFITS, LOST MONIES, OR
+OTHER SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
+USE OR INABILITY TO USE (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR
+DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY THIRD PARTIES OR
+A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS) THIS
+PROGRAM, EVEN IF YOU HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH
+DAMAGES, OR FOR ANY CLAIM BY ANY OTHER PARTY.
+
+ GENERAL PUBLIC LICENSE TO COPY
+
+ 1. You may copy and distribute verbatim copies of this source file
+as you receive it, in any medium, provided that you conspicuously and
+appropriately publish on each copy a valid copyright notice "Copyright
+(C) 1987 Free Software Foundation, Inc."; and include following the
+copyright notice a verbatim copy of the above disclaimer of warranty
+and of this License. You may charge a distribution fee for the
+physical act of transferring a copy.
+
+ 2. You may modify your copy or copies of this source file or
+any portion of it, and copy and distribute such modifications under
+the terms of Paragraph 1 above, provided that you also do the following:
+
+ a) cause the modified files to carry prominent notices stating
+ that you changed the files and the date of any change; and
+
+ b) cause the whole of any work that you distribute or publish,
+ that in whole or in part contains or is a derivative of this
+ program or any part thereof, to be licensed at no charge to all
+ third parties on terms identical to those contained in this
+ License Agreement (except that you may choose to grant more
+ extensive warranty protection to third parties, at your option).
+
+ c) You may charge a distribution fee for the physical act of
+ transferring a copy, and you may at your option offer warranty
+ protection in exchange for a fee.
+
+ 3. You may copy and distribute this program or any portion of it in
+compiled, executable or object code form under the terms of Paragraphs
+1 and 2 above provided that you do the following:
+
+ a) cause each such copy to be accompanied by the
+ corresponding machine-readable source code, which must
+ be distributed under the terms of Paragraphs 1 and 2 above; or,
+
+ b) cause each such copy to be accompanied by a
+ written offer, with no time limit, to give any third party
+ free (except for a nominal shipping charge) a machine readable
+ copy of the corresponding source code, to be distributed
+ under the terms of Paragraphs 1 and 2 above; or,
+
+ c) in the case of a recipient of this program in compiled, executable
+ or object code form (without the corresponding source code) you
+ shall cause copies you distribute to be accompanied by a copy
+ of the written offer of source code which you received along
+ with the copy you received.
+
+ 4. You may not copy, sublicense, distribute or transfer this program
+except as expressly provided under this License Agreement. Any attempt
+otherwise to copy, sublicense, distribute or transfer this program is void and
+your rights to use the program under this License agreement shall be
+automatically terminated. However, parties who have received computer
+software programs from you with this License Agreement will not have
+their licenses terminated so long as such parties remain in full compliance.
+
+ 5. If you wish to incorporate parts of this program into other free
+programs whose distribution conditions are different, write to the Free
+Software Foundation at 675 Mass Ave, Cambridge, MA 02139. We have not yet
+worked out a simple rule that can be stated here, but we will often permit
+this. We will be guided by the two goals of preserving the free status of
+all derivatives of our free software and of promoting the sharing and reuse of
+software.
+
+
+In other words, you are welcome to use, share and improve this program.
+You are forbidden to forbid anyone else to use, share and improve
+what you give them. Help stamp out software-hoarding! */
+
+
+/*
+ * unexec.c - Convert a running program into an a.out file.
+ *
+ * Author: Spencer W. Thomas
+ * Computer Science Dept.
+ * University of Utah
+ * Date: Tue Mar 2 1982
+ * Modified heavily since then.
+ *
+ * Synopsis:
+ * unexec (new_name, a_name, data_start, bss_start, entry_address)
+ * char *new_name, *a_name;
+ * unsigned data_start, bss_start, entry_address;
+ *
+ * Takes a snapshot of the program and makes an a.out format file in the
+ * file named by the string argument new_name.
+ * If a_name is non-NULL, the symbol table will be taken from the given file.
+ * On some machines, an existing a_name file is required.
+ *
+ * The boundaries within the a.out file may be adjusted with the data_start
+ * and bss_start arguments. Either or both may be given as 0 for defaults.
+ *
+ * Data_start gives the boundary between the text segment and the data
+ * segment of the program. The text segment can contain shared, read-only
+ * program code and literal data, while the data segment is always unshared
+ * and unprotected. Data_start gives the lowest unprotected address.
+ * The value you specify may be rounded down to a suitable boundary
+ * as required by the machine you are using.
+ *
+ * Specifying zero for data_start means the boundary between text and data
+ * should not be the same as when the program was loaded.
+ * If NO_REMAP is defined, the argument data_start is ignored and the
+ * segment boundaries are never changed.
+ *
+ * Bss_start indicates how much of the data segment is to be saved in the
+ * a.out file and restored when the program is executed. It gives the lowest
+ * unsaved address, and is rounded up to a page boundary. The default when 0
+ * is given assumes that the entire data segment is to be stored, including
+ * the previous data and bss as well as any additional storage allocated with
+ * break (2).
+ *
+ * The new file is set up to start at entry_address.
+ *
+ * If you make improvements I'd like to get them too.
+ * harpo!utah-cs!thomas, thomas@Utah-20
+ *
+ */
+
+/* There are several compilation parameters affecting unexec:
+
+* COFF
+
+Define this if your system uses COFF for executables.
+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
+as part of the text segment.
+
+Saving them as text is good because it allows users to share more.
+
+However, on machines that locate the text area far from the data area,
+the boundary cannot feasibly be moved. Such machines require
+NO_REMAP.
+
+Also, remapping can cause trouble with the built-in startup routine
+/lib/crt0.o, which defines `environ' as an initialized variable.
+Dumping `environ' as pure does not work! So, to use remapping,
+you must write a startup routine for your machine in Emacs's crt0.c.
+If NO_REMAP is defined, Emacs uses the system's crt0.o.
+
+* SECTION_ALIGNMENT
+
+Some machines that use COFF executables require that each section
+start on a certain boundary *in the COFF file*. Such machines should
+define SECTION_ALIGNMENT to a mask of the low-order bits that must be
+zero on such a boundary. This mask is used to control padding between
+segments in the COFF file.
+
+If SECTION_ALIGNMENT is not defined, the segments are written
+consecutively with no attempt at alignment. This is right for
+unmodified system V.
+
+* SEGMENT_MASK
+
+Some machines require that the beginnings and ends of segments
+*in core* be on certain boundaries. For most machines, a page
+boundary is sufficient. That is the default. When a larger
+boundary is needed, define SEGMENT_MASK to a mask of
+the bits that must be zero on such a boundary.
+
+* A_TEXT_OFFSET(HDR)
+
+Some machines count the a.out header as part of the size of the text
+segment (a_text); they may actually load the header into core as the
+first data in the text segment. Some have additional padding between
+the header and the real text of the program that is counted in a_text.
+
+For these machines, define A_TEXT_OFFSET(HDR) to examine the header
+structure HDR and return the number of bytes to add to `a_text'
+before writing it (above and beyond the number of bytes of actual
+program text). HDR's standard fields are already correct, except that
+this adjustment to the `a_text' field has not yet been made;
+thus, the amount of offset can depend on the data in the file.
+
+* A_TEXT_SEEK(HDR)
+
+If defined, this macro specifies the number of bytes to seek into the
+a.out file before starting to write the text segment.a
+
+* 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
+initialize nonstandard fields in the file header
+
+* ADDR_CORRECT(ADDR)
+
+Macro to correct an int which is the bit pattern of a pointer to a byte
+into an int which is the number of a byte.
+
+This macro has a default definition which is usually right.
+This default definition is a no-op on most machines (where a
+pointer looks like an int) but not on all machines.
+
+*/
+
+#ifndef emacs
+#define PERROR(arg) perror (arg); return -1
+#else
+#include "config.h"
+#define PERROR(file) report_error (file, new)
+#endif
+
+#ifndef CANNOT_DUMP /* all rest of file! */
+
+#ifndef CANNOT_UNEXEC /* most of rest of file */
+
+#ifndef mips /* mips machine requires completely separate code. */
+
+#include <a.out.h>
+/* Define getpagesize () if the system does not.
+ Note that this may depend on symbols defined in a.out.h
+ */
+#include "getpagesize.h"
+
+#ifndef makedev /* Try to detect types.h already loaded */
+#include <sys/types.h>
+#endif
+#include <stdio.h>
+#include <sys/stat.h>
+#include <errno.h>
+
+extern char *start_of_text (); /* Start of text */
+extern char *start_of_data (); /* Start of initialized data */
+
+#ifdef COFF
+#ifndef USG
+#ifndef STRIDE
+#ifndef UMAX
+/* I have a suspicion that these are turned off on all systems
+ and can be deleted. Try it in version 19. */
+#include <filehdr.h>
+#include <aouthdr.h>
+#include <scnhdr.h>
+#include <syms.h>
+#endif /* not UMAX */
+#endif /* Not STRIDE */
+#endif /* not USG */
+static long block_copy_start; /* Old executable start point */
+static struct filehdr f_hdr; /* File header */
+static struct aouthdr f_ohdr; /* Optional file header (a.out) */
+long bias; /* Bias to add for growth */
+long lnnoptr; /* Pointer to line-number info within file */
+#define SYMS_START block_copy_start
+
+static long text_scnptr;
+static long data_scnptr;
+
+#else /* not COFF */
+
+extern char *sbrk ();
+
+#define SYMS_START ((long) N_SYMOFF (ohdr))
+
+#ifdef HPUX
+#ifdef HP9000S200_ID
+#define MY_ID HP9000S200_ID
+#else
+#include <model.h>
+#define MY_ID MYSYS
+#endif /* no HP9000S200_ID */
+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 struct exec hdr, ohdr;
+
+#else /* not HPUX */
+
+#if defined (USG) && !defined (IRIS)
+static struct bhdr hdr, ohdr;
+#define a_magic fmagic
+#define a_text tsize
+#define a_data dsize
+#define a_bss bsize
+#define a_syms ssize
+#define a_trsize rtsize
+#define a_drsize rdsize
+#define a_entry entry
+#define N_BADMAG(x) \
+ (((x).fmagic)!=OMAGIC && ((x).fmagic)!=NMAGIC &&\
+ ((x).fmagic)!=FMAGIC && ((x).fmagic)!=IMAGIC)
+#define NEWMAGIC FMAGIC
+#else /* IRIS or not USG */
+static struct exec hdr, ohdr;
+#define NEWMAGIC ZMAGIC
+#endif /* IRIS or not USG */
+#endif /* not HPUX */
+
+static int unexec_text_start;
+static int unexec_data_start;
+
+#endif /* not COFF */
+
+static int pagemask;
+
+/* Correct an int which is the bit pattern of a pointer to a byte
+ into an int which is the number of a byte.
+ This is a no-op on ordinary machines, but not on all. */
+
+#ifndef ADDR_CORRECT /* Let m-*.h files override this definition */
+#define ADDR_CORRECT(x) ((char *)(x) - (char*)0)
+#endif
+
+#ifdef emacs
+
+static
+report_error (file, fd)
+ char *file;
+ int fd;
+{
+ if (fd)
+ close (fd);
+ error ("Failure operating on %s", file);
+}
+#endif /* emacs */
+
+#define ERROR0(msg) report_error_1 (new, msg, 0, 0); return -1
+#define ERROR1(msg,x) report_error_1 (new, msg, x, 0); return -1
+#define ERROR2(msg,x,y) report_error_1 (new, msg, x, y); return -1
+
+static
+report_error_1 (fd, msg, a1, a2)
+ int fd;
+ char *msg;
+ int a1, a2;
+{
+ close (fd);
+#ifdef emacs
+ error (msg, a1, a2);
+#else
+ fprintf (stderr, msg, a1, a2);
+ fprintf (stderr, "\n");
+#endif
+}
+
+/* ****************************************************************
+ * 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, 0)) < 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) < 0
+ || copy_sym (new, a_out, a_name, new_name) < 0
+#ifdef COFF
+ || adjust_lnnoptrs (new, a_out, new_name) < 0
+#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
+ *
+ * Make the header in the new a.out from the header in core.
+ * Modify the text and data sizes.
+ */
+static int
+make_hdr (new, a_out, data_start, bss_start, entry_address, a_name, new_name)
+ int new, a_out;
+ unsigned data_start, bss_start, entry_address;
+ char *a_name;
+ char *new_name;
+{
+ int tem;
+#ifdef COFF
+ auto struct scnhdr f_thdr; /* Text section header */
+ auto struct scnhdr f_dhdr; /* Data section header */
+ auto struct scnhdr f_bhdr; /* Bss section header */
+ auto struct scnhdr scntemp; /* Temporary section header */
+ register int scns;
+#endif /* COFF */
+ unsigned int bss_end;
+
+ pagemask = getpagesize () - 1;
+
+ /* Adjust text/data boundary. */
+#ifdef NO_REMAP
+ data_start = (int) start_of_data ();
+#else /* not NO_REMAP */
+ if (!data_start)
+ data_start = (int) start_of_data ();
+#endif /* not NO_REMAP */
+ data_start = ADDR_CORRECT (data_start);
+
+#ifdef SEGMENT_MASK
+ data_start = data_start & ~SEGMENT_MASK; /* (Down) to segment boundary. */
+#else
+ data_start = data_start & ~pagemask; /* (Down) to page boundary. */
+#endif
+
+ bss_end = ADDR_CORRECT (sbrk (0)) + pagemask;
+ bss_end &= ~ pagemask;
+
+ /* Adjust data/bss boundary. */
+ if (bss_start != 0)
+ {
+ bss_start = (ADDR_CORRECT (bss_start) + pagemask);
+ /* (Up) to page bdry. */
+ bss_start &= ~ pagemask;
+ if (bss_start > bss_end)
+ {
+ ERROR1 ("unexec: Specified bss_start (%u) is past end of program",
+ bss_start);
+ }
+ }
+ else
+ bss_start = bss_end;
+
+ if (data_start > bss_start) /* Can't have negative data size. */
+ {
+ ERROR2 ("unexec: data_start (%u) can't be greater than bss_start (%u)",
+ data_start, bss_start);
+ }
+
+#ifdef COFF
+ /* Salvage as much info from the existing file as possible */
+ if (a_out >= 0)
+ {
+ if (read (a_out, &f_hdr, sizeof (f_hdr)) != sizeof (f_hdr))
+ {
+ PERROR (a_name);
+ }
+ block_copy_start += sizeof (f_hdr);
+ if (f_hdr.f_opthdr > 0)
+ {
+ if (read (a_out, &f_ohdr, sizeof (f_ohdr)) != sizeof (f_ohdr))
+ {
+ PERROR (a_name);
+ }
+ block_copy_start += sizeof (f_ohdr);
+ }
+ /* Loop through section headers, copying them in */
+ for (scns = f_hdr.f_nscns; scns > 0; scns--) {
+ if (read (a_out, &scntemp, sizeof (scntemp)) != sizeof (scntemp))
+ {
+ PERROR (a_name);
+ }
+ if (scntemp.s_scnptr > 0L)
+ {
+ if (block_copy_start < scntemp.s_scnptr + scntemp.s_size)
+ block_copy_start = scntemp.s_scnptr + scntemp.s_size;
+ }
+ if (strcmp (scntemp.s_name, ".text") == 0)
+ {
+ f_thdr = scntemp;
+ }
+ else if (strcmp (scntemp.s_name, ".data") == 0)
+ {
+ f_dhdr = scntemp;
+ }
+ else if (strcmp (scntemp.s_name, ".bss") == 0)
+ {
+ f_bhdr = scntemp;
+ }
+ }
+ }
+ else
+ {
+ ERROR0 ("can't build a COFF file from scratch yet");
+ }
+
+ /* Now we alter the contents of all the f_*hdr variables
+ to correspond to what we want to dump. */
+
+ f_hdr.f_flags |= (F_RELFLG | F_EXEC);
+#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;
+ f_ohdr.data_start = data_start;
+#endif /* NO_REMAP */
+ f_ohdr.dsize = bss_start - f_ohdr.data_start;
+ f_ohdr.bsize = bss_end - bss_start;
+ 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));
+ lnnoptr = f_thdr.s_lnnoptr;
+#ifdef SECTION_ALIGNMENT
+ /* Some systems require special alignment
+ of the sections in the file itself. */
+ f_thdr.s_scnptr
+ = (f_thdr.s_scnptr + SECTION_ALIGNMENT) & ~SECTION_ALIGNMENT;
+#endif /* SECTION_ALIGNMENT */
+ text_scnptr = f_thdr.s_scnptr;
+ f_dhdr.s_paddr = f_ohdr.data_start;
+ 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;
+#ifdef SECTION_ALIGNMENT
+ /* Some systems require special alignment
+ of the sections in the file itself. */
+ f_dhdr.s_scnptr
+ = (f_dhdr.s_scnptr + SECTION_ALIGNMENT) & ~SECTION_ALIGNMENT;
+#endif /* SECTION_ALIGNMENT */
+ data_scnptr = f_dhdr.s_scnptr;
+ f_bhdr.s_paddr = f_ohdr.data_start + f_ohdr.dsize;
+ f_bhdr.s_vaddr = f_ohdr.data_start + f_ohdr.dsize;
+ f_bhdr.s_size = f_ohdr.bsize;
+ f_bhdr.s_scnptr = 0L;
+ bias = f_dhdr.s_scnptr + f_dhdr.s_size - block_copy_start;
+
+ if (f_hdr.f_symptr > 0L)
+ {
+ f_hdr.f_symptr += bias;
+ }
+
+ if (f_thdr.s_lnnoptr > 0L)
+ {
+ f_thdr.s_lnnoptr += bias;
+ }
+
+#ifdef ADJUST_EXEC_HEADER
+ ADJUST_EXEC_HEADER
+#endif /* ADJUST_EXEC_HEADER */
+
+ if (write (new, &f_hdr, sizeof (f_hdr)) != sizeof (f_hdr))
+ {
+ PERROR (new_name);
+ }
+
+ if (write (new, &f_ohdr, sizeof (f_ohdr)) != sizeof (f_ohdr))
+ {
+ PERROR (new_name);
+ }
+
+ if (write (new, &f_thdr, sizeof (f_thdr)) != sizeof (f_thdr))
+ {
+ PERROR (new_name);
+ }
+
+ if (write (new, &f_dhdr, sizeof (f_dhdr)) != sizeof (f_dhdr))
+ {
+ PERROR (new_name);
+ }
+
+ if (write (new, &f_bhdr, sizeof (f_bhdr)) != sizeof (f_bhdr))
+ {
+ PERROR (new_name);
+ }
+ return (0);
+
+#else /* if not COFF */
+
+ /* Get symbol table info from header of a.out file if given one. */
+ if (a_out >= 0)
+ {
+ if (read (a_out, &ohdr, sizeof hdr) != sizeof hdr)
+ {
+ PERROR (a_name);
+ }
+
+ if N_BADMAG (ohdr)
+ {
+ ERROR1 ("invalid magic number in %s", a_name);
+ }
+ hdr = ohdr;
+ }
+ else
+ {
+ bzero (hdr, sizeof hdr);
+ }
+
+ unexec_text_start = (long) start_of_text ();
+ unexec_data_start = data_start;
+
+ /* Machine-dependent fixup for header, or maybe for unexec_text_start */
+#ifdef ADJUST_EXEC_HEADER
+ ADJUST_EXEC_HEADER;
+#endif /* ADJUST_EXEC_HEADER */
+
+ hdr.a_trsize = 0;
+ hdr.a_drsize = 0;
+ if (entry_address != 0)
+ hdr.a_entry = entry_address;
+
+ hdr.a_bss = bss_end - bss_start;
+ hdr.a_data = bss_start - data_start;
+#ifdef NO_REMAP
+ hdr.a_text = ohdr.a_text;
+#else /* not NO_REMAP */
+ hdr.a_text = data_start - unexec_text_start;
+#endif /* not NO_REMAP */
+
+#ifdef A_TEXT_OFFSET
+ hdr.a_text += A_TEXT_OFFSET (ohdr);
+#endif
+
+ if (write (new, &hdr, sizeof hdr) != sizeof hdr)
+ {
+ PERROR (new_name);
+ }
+
+#ifdef A_TEXT_OFFSET
+ hdr.a_text -= A_TEXT_OFFSET (ohdr);
+#endif
+
+ return 0;
+
+#endif /* not COFF */
+}
+
+/* ****************************************************************
+ * copy_text_and_data
+ *
+ * Copy the text and data segments from memory to the new a.out
+ */
+static int
+copy_text_and_data (new)
+ int new;
+{
+ register char *end;
+ register char *ptr;
+
+#ifdef COFF
+ lseek (new, (long) text_scnptr, 0);
+ ptr = (char *) f_ohdr.text_start;
+ end = ptr + f_ohdr.tsize;
+ write_segment (new, ptr, end);
+
+ lseek (new, (long) data_scnptr, 0);
+ ptr = (char *) f_ohdr.data_start;
+ end = ptr + f_ohdr.dsize;
+ write_segment (new, ptr, end);
+
+#else /* if not COFF */
+
+/* Some machines count the header as part of the text segment.
+ That is to say, the header appears in core
+ just before the address that start_of_text () returns.
+ For them, N_TXTOFF is the place where the header goes.
+ We must adjust the seek to the place after the header.
+ Note that at this point hdr.a_text does *not* count
+ the extra A_TEXT_OFFSET bytes, only the actual bytes of code. */
+
+#ifdef A_TEXT_SEEK
+ lseek (new, (long) A_TEXT_SEEK (hdr), 0);
+#else
+#ifdef A_TEXT_OFFSET
+ /* Note that on the Sequent machine A_TEXT_OFFSET != sizeof (hdr)
+ and sizeof (hdr) is the correct amount to add here. */
+ /* In version 19, eliminate this case and use A_TEXT_SEEK whenever
+ N_TXTOFF is not right. */
+ lseek (new, (long) N_TXTOFF (hdr) + sizeof (hdr), 0);
+#else
+ lseek (new, (long) N_TXTOFF (hdr), 0);
+#endif /* no A_TEXT_OFFSET */
+#endif /* no A_TEXT_SEEK */
+
+ ptr = (char *) unexec_text_start;
+ end = ptr + hdr.a_text;
+ write_segment (new, ptr, end);
+
+ ptr = (char *) unexec_data_start;
+ end = ptr + hdr.a_data;
+/* This lseek is certainly incorrect when A_TEXT_OFFSET
+ and I believe it is a no-op otherwise.
+ Let's see if its absence ever fails. */
+/* lseek (new, (long) N_TXTOFF (hdr) + hdr.a_text, 0); */
+ write_segment (new, ptr, end);
+
+#endif /* not COFF */
+
+ return 0;
+}
+
+write_segment (new, ptr, end)
+ int new;
+ register char *ptr, *end;
+{
+ register int i, nwrite, ret;
+ char buf[80];
+ extern int errno;
+ char zeros[128];
+
+ bzero (zeros, sizeof zeros);
+
+ for (i = 0; ptr < end;)
+ {
+ /* distance to next multiple of 128. */
+ nwrite = (((int) ptr + 128) & -128) - (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 && errno == EFAULT)
+ write (new, zeros, nwrite);
+ 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);
+ }
+ i += nwrite;
+ ptr += nwrite;
+ }
+}
+
+/* ****************************************************************
+ * copy_sym
+ *
+ * Copy the relocation information and symbol table from the a.out to the new
+ */
+static int
+copy_sym (new, a_out, a_name, new_name)
+ int new, a_out;
+ char *a_name, *new_name;
+{
+ char page[1024];
+ int n;
+
+ if (a_out < 0)
+ return 0;
+
+#ifdef COFF
+ if (SYMS_START == 0L)
+ return 0;
+#endif /* COFF */
+
+#ifdef COFF
+ if (lnnoptr) /* if there is line number info */
+ lseek (a_out, lnnoptr, 0); /* start copying from there */
+ else
+#endif /* COFF */
+ lseek (a_out, SYMS_START, 0); /* Position a.out to symtab. */
+
+ while ((n = read (a_out, page, sizeof page)) > 0)
+ {
+ if (write (new, page, n) != n)
+ {
+ PERROR (new_name);
+ }
+ }
+ if (n < 0)
+ {
+ PERROR (a_name);
+ }
+ return 0;
+}
+
+/* ****************************************************************
+ * mark_x
+ *
+ * After succesfully building the new a.out, mark it executable
+ */
+static
+mark_x (name)
+ char *name;
+{
+ struct stat sbuf;
+ int um;
+ int new = 0; /* for PERROR */
+
+ um = umask (777);
+ umask (um);
+ if (stat (name, &sbuf) == -1)
+ {
+ PERROR (name);
+ }
+ sbuf.st_mode |= 0111 & ~um;
+ if (chmod (name, sbuf.st_mode) == -1)
+ PERROR (name);
+}
+
+/*
+ * If the COFF file contains a symbol table and a line number section,
+ * then any auxiliary entries that have values for x_lnnoptr must
+ * be adjusted by the amount that the line number section has moved
+ * in the file (bias computed in make_hdr). The #@$%&* designers of
+ * the auxiliary entry structures used the absolute file offsets for
+ * the line number entry rather than an offset from the start of the
+ * line number section!
+ *
+ * When I figure out how to scan through the symbol table and pick out
+ * the auxiliary entries that need adjustment, this routine will
+ * be fixed. As it is now, all such entries are wrong and sdb
+ * will complain. Fred Fish, UniSoft Systems Inc.
+ */
+
+#ifdef COFF
+
+/* This function is probably very slow. Instead of reopening the new
+ file for input and output it should copy from the old to the new
+ using the two descriptors already open (WRITEDESC and READDESC).
+ Instead of reading one small structure at a time it should use
+ a reasonable size buffer. But I don't have time to work on such
+ things, so I am installing it as submitted to me. -- RMS. */
+
+adjust_lnnoptrs (writedesc, readdesc, new_name)
+ int writedesc;
+ int readdesc;
+ char *new_name;
+{
+ register int nsyms;
+ register int new;
+#ifdef amdahl_uts
+ SYMENT symentry;
+ AUXENT auxentry;
+#else
+ struct syment symentry;
+ struct auxent auxentry;
+#endif
+
+ if (!lnnoptr || !f_hdr.f_symptr)
+ return 0;
+
+ if ((new = open (new_name, 2)) < 0)
+ {
+ PERROR (new_name);
+ return -1;
+ }
+
+ lseek (new, f_hdr.f_symptr, 0);
+ for (nsyms = 0; nsyms < f_hdr.f_nsyms; nsyms++)
+ {
+ read (new, &symentry, SYMESZ);
+ if (symentry.n_numaux)
+ {
+ read (new, &auxentry, AUXESZ);
+ nsyms++;
+ if (ISFCN (symentry.n_type)) {
+ auxentry.x_sym.x_fcnary.x_fcn.x_lnnoptr += bias;
+ lseek (new, -AUXESZ, 1);
+ write (new, &auxentry, AUXESZ);
+ }
+ }
+ }
+ close (new);
+}
+
+#endif /* COFF */
+
+
+#else /* mips */
+
+/* Unexec for mips machines.
+ Note that I regard it as the responsibility of people at Mips
+ to tell me about any changes that need to be made in this code.
+ I won't take responsibility to think about it even if a change
+ I make elsewhere causes it to break. -- RMS. */
+
+#include <sys/types.h>
+#include <sys/file.h>
+#include <sys/stat.h>
+#include <stdio.h>
+#include <varargs.h>
+#include <filehdr.h>
+#include <aouthdr.h>
+#include <scnhdr.h>
+#include <sym.h>
+
+#define private static
+
+extern int errno;
+extern int sys_nerr;
+extern char *sys_errlist[];
+#define EEOF -1
+
+private void
+fatal(s, va_alist)
+ va_dcl
+{
+ va_list ap;
+ if (errno == EEOF) {
+ fputs("unexec: unexpected end of file, ", stderr);
+ }
+ else if (errno < sys_nerr) {
+ fprintf(stderr, "unexec: %s, ", sys_errlist[errno]);
+ }
+ else {
+ fprintf(stderr, "unexec: error code %d, ", errno);
+ }
+ va_start(ap);
+ _doprnt(s, ap, stderr);
+ fputs(".\n", stderr);
+ exit(1);
+}
+
+#define READ(_fd, _buffer, _size, _error_message, _error_arg) \
+ errno = EEOF; \
+ if (read(_fd, _buffer, _size) != _size) \
+ fatal(_error_message, _error_arg);
+
+#define WRITE(_fd, _buffer, _size, _error_message, _error_arg) \
+ if (write(_fd, _buffer, _size) != _size) \
+ fatal(_error_message, _error_arg);
+
+#define SEEK(_fd, _position, _error_message, _error_arg) \
+ errno = EEOF; \
+ if (lseek(_fd, _position, L_SET) != _position) \
+ fatal(_error_message, _error_arg);
+
+struct headers {
+ struct filehdr fhdr;
+ struct aouthdr aout;
+ struct scnhdr text_section;
+ struct scnhdr rdata_section;
+ struct scnhdr data_section;
+ struct scnhdr sdata_section;
+ struct scnhdr sbss_section;
+ struct scnhdr bss_section;
+};
+
+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, old;
+ int pagesize, brk;
+ int newsyms, symrel;
+ int nread;
+ struct headers hdr;
+#define BUFSIZE 8192
+ char buffer[BUFSIZE];
+
+ old = open (a_name, O_RDONLY, 0);
+ if (old < 0) fatal("openning %s", a_name);
+
+ new = creat (new_name, 0666);
+ if (new < 0) fatal("creating %s", new_name);
+
+ hdr = *((struct headers *)TEXT_START);
+ if (hdr.fhdr.f_magic != MIPSELMAGIC
+ && hdr.fhdr.f_magic != MIPSEBMAGIC) {
+ fprintf(stderr, "unexec: input file magic number is %x, not %x or %x.\n",
+ hdr.fhdr.f_magic, MIPSELMAGIC, MIPSEBMAGIC);
+ exit(1);
+ }
+ if (hdr.fhdr.f_opthdr != sizeof(hdr.aout)) {
+ fprintf(stderr, "unexec: input a.out header is %d bytes, not %d.\n",
+ hdr.fhdr.f_opthdr, sizeof(hdr.aout));
+ exit(1);
+ }
+#if 0
+ if (hdr.aout.magic != ZMAGIC
+ && hdr.aout.magic != NMAGIC
+ && hdr.aout.magic != OMAGIC) {
+ fprintf(stderr, "unexec: input file a.out magic number is %o, not %o, %o, or %o.\n",
+ hdr.aout.magic, ZMAGIC, NMAGIC, OMAGIC);
+ exit(1);
+ }
+#else
+ if (hdr.aout.magic != ZMAGIC) {
+ fprintf(stderr, "unexec: input file a.out magic number is %o, not %o.\n",
+ hdr.aout.magic, ZMAGIC);
+ exit(1);
+ }
+#endif
+ if (hdr.fhdr.f_nscns != 6) {
+ fprintf(stderr, "unexec: %d sections instead of 6.\n", hdr.fhdr.f_nscns);
+ }
+#define CHECK_SCNHDR(field, name, flags) \
+ if (strcmp(hdr.field.s_name, name) != 0) { \
+ fprintf(stderr, "unexec: %s section where %s expected.\n", \
+ hdr.field.s_name, name); \
+ exit(1); \
+ } \
+ else if (hdr.field.s_flags != flags) { \
+ fprintf(stderr, "unexec: %x flags where %x expected in %s section.\n", \
+ hdr.field.s_flags, flags, name); \
+ }
+ CHECK_SCNHDR(text_section, _TEXT, STYP_TEXT);
+ CHECK_SCNHDR(rdata_section, _RDATA, STYP_RDATA);
+ CHECK_SCNHDR(data_section, _DATA, STYP_DATA);
+ CHECK_SCNHDR(sdata_section, _SDATA, STYP_SDATA);
+ CHECK_SCNHDR(sbss_section, _SBSS, STYP_SBSS);
+ CHECK_SCNHDR(bss_section, _BSS, STYP_BSS);
+
+ pagesize = getpagesize();
+ brk = (sbrk(0) + pagesize - 1) & (-pagesize);
+ hdr.aout.dsize = brk - DATA_START;
+ hdr.aout.bsize = 0;
+ if (entry_address == 0) {
+ extern __start();
+ hdr.aout.entry = (unsigned)__start;
+ }
+ else {
+ hdr.aout.entry = entry_address;
+ }
+ hdr.aout.bss_start = hdr.aout.data_start + hdr.aout.dsize;
+ hdr.rdata_section.s_size = data_start - DATA_START;
+ hdr.data_section.s_vaddr = data_start;
+ hdr.data_section.s_paddr = data_start;
+ hdr.data_section.s_size = brk - DATA_START;
+ hdr.data_section.s_scnptr = hdr.rdata_section.s_scnptr
+ + hdr.rdata_section.s_size;
+ hdr.sdata_section.s_vaddr = hdr.data_section.s_vaddr
+ + hdr.data_section.s_size;
+ hdr.sdata_section.s_paddr = hdr.sdata_section.s_paddr;
+ hdr.sdata_section.s_size = 0;
+ hdr.sdata_section.s_scnptr = hdr.data_section.s_scnptr
+ + hdr.data_section.s_size;
+ hdr.sbss_section.s_vaddr = hdr.sdata_section.s_vaddr
+ + hdr.sdata_section.s_size;
+ hdr.sbss_section.s_paddr = hdr.sbss_section.s_vaddr;
+ hdr.sbss_section.s_size = 0;
+ hdr.sbss_section.s_scnptr = hdr.sdata_section.s_scnptr
+ + hdr.sdata_section.s_size;
+ hdr.bss_section.s_vaddr = hdr.sbss_section.s_vaddr
+ + hdr.sbss_section.s_size;
+ hdr.bss_section.s_paddr = hdr.bss_section.s_vaddr;
+ hdr.bss_section.s_size = 0;
+ hdr.bss_section.s_scnptr = hdr.sbss_section.s_scnptr
+ + hdr.sbss_section.s_size;
+
+ WRITE(new, TEXT_START, hdr.aout.tsize,
+ "writing text section to %s", new_name);
+ WRITE(new, DATA_START, hdr.aout.dsize,
+ "writing text section to %s", new_name);
+
+ SEEK(old, hdr.fhdr.f_symptr, "seeking to start of symbols in %s", a_name);
+ errno = EEOF;
+ nread = read(old, buffer, BUFSIZE);
+ if (nread < sizeof(HDRR)) fatal("reading symbols from %s", a_name);
+#define symhdr ((pHDRR)buffer)
+ newsyms = hdr.aout.tsize + hdr.aout.dsize;
+ symrel = newsyms - hdr.fhdr.f_symptr;
+ hdr.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;
+#undef symhdr
+ do {
+ if (write(new, buffer, nread) != nread)
+ fatal("writing symbols to %s", new_name);
+ nread = read(old, buffer, BUFSIZE);
+ if (nread < 0) fatal("reading symbols from %s", a_name);
+#undef BUFSIZE
+ } while (nread != 0);
+
+ SEEK(new, 0, "seeking to start of header in %s", new_name);
+ WRITE(new, &hdr, sizeof(hdr),
+ "writing header of %s", new_name);
+
+ close(old);
+ close(new);
+ mark_x(new_name);
+}
+
+/*
+ * mark_x
+ *
+ * After succesfully building the new a.out, mark it executable
+ */
+static
+mark_x (name)
+ char *name;
+{
+ struct stat sbuf;
+ int um = umask (777);
+ umask (um);
+ if (stat(name, &sbuf) < 0)
+ fatal("getting protection on %s", name);
+ sbuf.st_mode |= 0111 & ~um;
+ if (chmod(name, sbuf.st_mode) < 0)
+ fatal("setting protection on %s", name);
+}
+
+#endif /* mips */
+
+#endif /* not CANNOT_UNEXEC */
+
+#endif /* not CANNOT_DUMP */
diff --git a/obsolete/support/undump/Encore/unexec.diff b/obsolete/support/undump/Encore/unexec.diff
new file mode 100644
index 0000000000..886d0bd42a
--- /dev/null
+++ b/obsolete/support/undump/Encore/unexec.diff
@@ -0,0 +1,91 @@
+*** unexec.c-dist Tue Sep 29 15:20:15 1987
+--- unexec.c Tue Sep 29 17:50:03 1987
+***************
+*** 428,433
+ register int scns;
+ #endif /* COFF */
+ unsigned int bss_end;
+
+ pagemask = getpagesize () - 1;
+
+
+--- 428,436 -----
+ register int scns;
+ #endif /* COFF */
+ unsigned int bss_end;
++ #ifdef UMAX
++ extern etext;
++ #endif
+
+ pagemask = getpagesize () - 1;
+
+***************
+*** 435,440
+ #ifdef NO_REMAP
+ data_start = (int) start_of_data ();
+ #else /* not NO_REMAP */
+ if (!data_start)
+ data_start = (int) start_of_data ();
+ #endif /* not NO_REMAP */
+
+--- 438,444 -----
+ #ifdef NO_REMAP
+ data_start = (int) start_of_data ();
+ #else /* not NO_REMAP */
++ #ifndef UMAX
+ if (!data_start)
+ #endif
+ data_start = (int) start_of_data ();
+***************
+*** 436,441
+ data_start = (int) start_of_data ();
+ #else /* not NO_REMAP */
+ if (!data_start)
+ data_start = (int) start_of_data ();
+ #endif /* not NO_REMAP */
+ data_start = ADDR_CORRECT (data_start);
+
+--- 440,446 -----
+ #else /* not NO_REMAP */
+ #ifndef UMAX
+ if (!data_start)
++ #endif
+ data_start = (int) start_of_data ();
+ #endif /* not NO_REMAP */
+ data_start = ADDR_CORRECT (data_start);
+***************
+*** 526,531
+ #endif
+ #ifndef NO_REMAP
+ f_ohdr.text_start = (long) start_of_text ();
+ f_ohdr.tsize = data_start - f_ohdr.text_start;
+ f_ohdr.data_start = data_start;
+ #endif /* NO_REMAP */
+
+--- 531,539 -----
+ #endif
+ #ifndef NO_REMAP
+ f_ohdr.text_start = (long) start_of_text ();
++ #ifdef UMAX
++ f_ohdr.tsize = (long) &etext;
++ #else
+ f_ohdr.tsize = data_start - f_ohdr.text_start;
+ #endif
+ f_ohdr.data_start = data_start;
+***************
+*** 527,532
+ #ifndef NO_REMAP
+ f_ohdr.text_start = (long) start_of_text ();
+ f_ohdr.tsize = data_start - f_ohdr.text_start;
+ f_ohdr.data_start = data_start;
+ #endif /* NO_REMAP */
+ f_ohdr.dsize = bss_start - f_ohdr.data_start;
+
+--- 535,541 -----
+ f_ohdr.tsize = (long) &etext;
+ #else
+ f_ohdr.tsize = data_start - f_ohdr.text_start;
++ #endif
+ f_ohdr.data_start = data_start;
+ #endif /* NO_REMAP */
+ f_ohdr.dsize = bss_start - f_ohdr.data_start;
diff --git a/obsolete/support/undump/Makefile.BALANCE b/obsolete/support/undump/Makefile.BALANCE
new file mode 100644
index 0000000000..fa377fed1f
--- /dev/null
+++ b/obsolete/support/undump/Makefile.BALANCE
@@ -0,0 +1,11 @@
+BINDIR=/usr/local/bin
+CFLAGS = -O
+
+undump: & undump.o scanargs.o
+ cc -o undump undump.o scanargs.o
+
+clean:
+ rm -f *.o
+
+install: undump
+ cp undump $(BINDIR)
diff --git a/obsolete/support/undump/Makefile.PYR b/obsolete/support/undump/Makefile.PYR
new file mode 100644
index 0000000000..a7db084836
--- /dev/null
+++ b/obsolete/support/undump/Makefile.PYR
@@ -0,0 +1,9 @@
+BINDIR=/usr/local/bin
+
+undump: undump.c
+ cc -O -o undump undump.c
+clean:
+ rm -f *.o undump
+
+install: undump
+ cp undump $(BINDIR)
diff --git a/obsolete/support/undump/Makefile.SUN4 b/obsolete/support/undump/Makefile.SUN4
new file mode 100644
index 0000000000..2aacc18bbf
--- /dev/null
+++ b/obsolete/support/undump/Makefile.SUN4
@@ -0,0 +1,14 @@
+BINDIR=/usr/local
+CFLAGS= -g -Dsun3
+
+undump: undump.o
+ cc $(CFLAGS) -o undump undump.o
+
+undump.o: undump.c
+ cc $(CFLAGS) -c undump.c
+
+clean:
+ rm -f *.o
+
+install: undump
+ cp undump $(BINDIR)
diff --git a/obsolete/support/undump/Makefile.SUN_V2 b/obsolete/support/undump/Makefile.SUN_V2
new file mode 100644
index 0000000000..b92f3af043
--- /dev/null
+++ b/obsolete/support/undump/Makefile.SUN_V2
@@ -0,0 +1,14 @@
+BINDIR=/usr/local
+CFLAGS= -g -Dsun3
+
+undump: undump.o scanargs.o
+ cc $(CFLAGS) -o undump undump.o scanargs.o
+
+undump.o: undump.c
+ cc $(CFLAGS) -c undump.c
+
+clean:
+ rm -f *.o
+
+install: undump
+ cp undump $(BINDIR)
diff --git a/obsolete/support/undump/Makefile.SUN_V3 b/obsolete/support/undump/Makefile.SUN_V3
new file mode 100644
index 0000000000..b92f3af043
--- /dev/null
+++ b/obsolete/support/undump/Makefile.SUN_V3
@@ -0,0 +1,14 @@
+BINDIR=/usr/local
+CFLAGS= -g -Dsun3
+
+undump: undump.o scanargs.o
+ cc $(CFLAGS) -o undump undump.o scanargs.o
+
+undump.o: undump.c
+ cc $(CFLAGS) -c undump.c
+
+clean:
+ rm -f *.o
+
+install: undump
+ cp undump $(BINDIR)
diff --git a/obsolete/support/undump/Makefile.SYS_V b/obsolete/support/undump/Makefile.SYS_V
new file mode 100644
index 0000000000..62831e78f3
--- /dev/null
+++ b/obsolete/support/undump/Makefile.SYS_V
@@ -0,0 +1,14 @@
+BINDIR=/usr/local
+CFLAGS= -O
+
+undump: undump.o
+ cc $(CFLAGS) -o undump undump.o
+
+undump.o: undump.c
+ cc $(CFLAGS) -c undump.c
+
+clean:
+ rm -f *.o
+
+install: undump
+ cp undump $(BINDIR)
diff --git a/obsolete/support/undump/Makefile.VAX4_2 b/obsolete/support/undump/Makefile.VAX4_2
new file mode 100644
index 0000000000..77de95bc65
--- /dev/null
+++ b/obsolete/support/undump/Makefile.VAX4_2
@@ -0,0 +1,13 @@
+BINDIR=/usr/local
+
+undump: undump.o scanargs.o
+ cc -O -o undump undump.o scanargs.o
+
+undump.o: undump.c
+ cc -O -c undump.c
+
+clean:
+ rm -f *.o
+
+install: undump
+ cp undump $(BINDIR)
diff --git a/obsolete/support/undump/Makefile.VAX4_3 b/obsolete/support/undump/Makefile.VAX4_3
new file mode 100644
index 0000000000..77de95bc65
--- /dev/null
+++ b/obsolete/support/undump/Makefile.VAX4_3
@@ -0,0 +1,13 @@
+BINDIR=/usr/local
+
+undump: undump.o scanargs.o
+ cc -O -o undump undump.o scanargs.o
+
+undump.o: undump.c
+ cc -O -c undump.c
+
+clean:
+ rm -f *.o
+
+install: undump
+ cp undump $(BINDIR)
diff --git a/obsolete/support/undump/Setup.BALANCE b/obsolete/support/undump/Setup.BALANCE
new file mode 100644
index 0000000000..9dcb1f3cbb
--- /dev/null
+++ b/obsolete/support/undump/Setup.BALANCE
@@ -0,0 +1,4 @@
+# /bin/sh
+# setup the ./undump area for Sequent Balance/DYNIX
+cp Makefile.BALANCE Makefile
+cp undump.BALANCE.c undump.c
diff --git a/obsolete/support/undump/Setup.PYR b/obsolete/support/undump/Setup.PYR
new file mode 100644
index 0000000000..907be482b0
--- /dev/null
+++ b/obsolete/support/undump/Setup.PYR
@@ -0,0 +1,7 @@
+#!/bin/sh
+# setup the ./undump area for Pyramid
+cp Makefile.PYR Makefile
+cp undump.PYR.c undump.c
+
+
+
diff --git a/obsolete/support/undump/Setup.SUN4 b/obsolete/support/undump/Setup.SUN4
new file mode 100644
index 0000000000..238b9de2d5
--- /dev/null
+++ b/obsolete/support/undump/Setup.SUN4
@@ -0,0 +1,5 @@
+#!/bin/sh
+# setup the ./undump area for Sun4
+cp Makefile.SUN4 Makefile
+cp undump.SUN4.c undump.c
+
diff --git a/obsolete/support/undump/Setup.SUN_V2 b/obsolete/support/undump/Setup.SUN_V2
new file mode 100644
index 0000000000..c79fcea64d
--- /dev/null
+++ b/obsolete/support/undump/Setup.SUN_V2
@@ -0,0 +1,5 @@
+#!/bin/sh
+# setup the ./undump area for Sun2 running O.S. 3.2 or above
+echo If you are not running O.S. 3.2, use Setup.VAX4_2 instead
+cp Makefile.SUN_V2 Makefile
+cp undump.SUN_V2.c undump.c
diff --git a/obsolete/support/undump/Setup.SUN_V3 b/obsolete/support/undump/Setup.SUN_V3
new file mode 100644
index 0000000000..1bf48da26d
--- /dev/null
+++ b/obsolete/support/undump/Setup.SUN_V3
@@ -0,0 +1,5 @@
+#!/bin/sh
+# setup the ./undump area for Sun3 running O.S. 3.0 or above
+cp Makefile.SUN_V3 Makefile
+cp undump.SUN_V3.c undump.c
+
diff --git a/obsolete/support/undump/Setup.SYS_V b/obsolete/support/undump/Setup.SYS_V
new file mode 100644
index 0000000000..1832a36228
--- /dev/null
+++ b/obsolete/support/undump/Setup.SYS_V
@@ -0,0 +1,5 @@
+#!/bin/sh
+# setup the ./undump area for System V
+cp Makefile.SYS_V Makefile
+cp undump.SYS_V.c undump.c
+
diff --git a/obsolete/support/undump/Setup.VAX4_2 b/obsolete/support/undump/Setup.VAX4_2
new file mode 100644
index 0000000000..3aae9fe29e
--- /dev/null
+++ b/obsolete/support/undump/Setup.VAX4_2
@@ -0,0 +1,5 @@
+#!/bin/sh
+# setup the ./undump area for Vax running BSD 4.2
+cp Makefile.VAX4_2 Makefile
+cp undump.VAX4_2.c undump.c
+
diff --git a/obsolete/support/undump/Setup.VAX4_3 b/obsolete/support/undump/Setup.VAX4_3
new file mode 100644
index 0000000000..bea5d5dd0b
--- /dev/null
+++ b/obsolete/support/undump/Setup.VAX4_3
@@ -0,0 +1,4 @@
+#!/bin/sh
+# setup the ./undump area for Vax running BSD 4.3
+cp Makefile.VAX4_3 Makefile
+cp undump.VAX4_3.c undump.c
diff --git a/obsolete/support/undump/scanargs.1 b/obsolete/support/undump/scanargs.1
new file mode 100644
index 0000000000..827788f4e3
--- /dev/null
+++ b/obsolete/support/undump/scanargs.1
@@ -0,0 +1,446 @@
+.TH SCANARGS 3 "AMPEX CORP."
+.SH NAME
+scanargs, qscanargs - formatted conversion from command argument list
+.SH SYNOPSIS
+.B "#include <stdio.h>"
+.PP
+.B "scanargs(argc, argv, format"
+[, pointer]...
+.B )
+.br
+.B "int argc;"
+.br
+.B "char *argv[];"
+.br
+.B "char *format;"
+.SH DESCRIPTION
+.I Scanargs
+reads
+.I argc
+arguments from an argument list pointed to by
+.I argv.
+It converts the argument list according to the format string,
+and stores the results of the conversions in its parameters.
+.I Qscanargs
+is a smaller and less powerful version which does not understand floating
+point.
+.PP
+Scanargs expects as its parameters an argument count
+.I argc,
+a pointer to an argument list
+.I argv
+(see
+.IR exec (2)),
+a control string
+.I format,
+described below, and a set of
+.I pointer
+arguments indicating where the converted output should be stored.
+.PP
+The control string contains specifications, which are used to direct
+interpretation of argument sequences. It contains
+the necessary information to describe an acceptable
+syntax for the argument list, and the expected meaning of each argument.
+.PP
+If the scanning fails it will print a cryptic
+message telling why it failed, and generate a
+.I usage
+message from the control string.
+.PP
+The control string is composed of two parts:
+.PP
+.B Name:\ \
+The first characters in the string are assumed to be the calling
+name of the program being executed. This is used for generation of
+usage messages, but is otherwise ignored.
+If this field is a % sign, it is replaced with the contents of
+.IR argv [0]
+in the message.
+.PP
+.B Conversions:\ \
+Following the name, an optional list of conversion specifications is given,
+with separating spaces. The structure of a conversion specification:
+.RS
+.PP
+.B "label_key_conversion"
+.RE
+.PP
+consists of a
+.I label
+which is a string of non-space characters describing the acceptable
+argument, a
+.I key
+which may be either of
+.TP 4
+.B %
+The argument is optional. Its absence is ignored.
+.TP 4
+.B !
+A required argument. If absent, an error return ensues.
+.PP
+and a
+.I conversion
+character which indicates the interpretation of the argument; the corresponding
+pointer parameter must be of a restricted type.
+.PP
+The following conversion characters are supported:
+.TP 4
+.B d D
+a decimal integer is expected; the corresponding parameter should be an
+.I int
+or a
+.I long
+(if
+.B D
+is specified) pointer.
+.TP 4
+.B o O
+an octal integer is expected; the corresponding parameter should be an
+.I int
+or a
+.I long
+pointer.
+.TP 4
+.B x X
+a hexadecimal integer is expected; the corresponding parameter should be an
+.I int
+or a
+.I long
+pointer.
+.TP 4
+.B n N
+an integer numeric conversion using
+.I C
+language syntax. Numbers beginning
+.B 0x
+are hexadecimal, numbers beginning
+.B 0
+are octal, and other numbers are decimal. Negative hex numbers must have
+the minus sign
+.I following
+the
+.BR 0x ,
+i.e. negative 0xa would be given as 0x\-a. The corresponding pointer
+should point to an
+.I int
+or a
+.I long.
+.TP 4
+.B f F
+a floating point number is expected; the corresponding parameter should
+be a pointer to a
+.I float
+or a
+.I double.
+Not available in
+.I qscanargs.
+.TP 4
+.B "x X d D o O f F"
+all numeric types supported by
+.I scanf(3S)
+are legal in
+.I scanargs;
+.I qscanargs
+supports all but
+.B f
+and
+.B F
+formats, and avoids including the large size of the
+.I scanf
+routine.
+.TP 4
+.B s
+a character string is expected; the corresponding parameter should be the
+address of a pointer to
+.I char.
+.TP 4
+.B \-
+a single character flag is expected; the corresponding parameter should
+be an
+.I int
+pointer. The occurrence of a
+.B \-
+followed by the character specified in the label
+will cause the setting of the least significant bit of the integer pointed to
+by the corresponding parameter. The label may consist of up to sixteen
+(32 on a VAX) option
+characters, in which case one of the bits of the integer is independantly
+set to reflect which one of the flags was present. (The right most character
+corresponds to the LSB of the integer) Only one option may be chosen from
+each conversion specification. The bits which are not set will remain in
+their previous state. For example, a specification of
+.B abc%\-
+would match one of
+.B \-a \-b
+or
+.B \-c
+in the argument list.
+.B \-c
+would cause the corresponding variable to be set to 1,
+.B \-b
+to 2, and
+.B \-a
+to 4. (Actually, these bits would be ored in, but assuming an intial value
+of 0, this is true).
+.PP
+.RS 4
+The
+.B \-
+may be followed immediately by more label_key_conversion specifications.
+These should not be separated by blanks and should not contain any
+.B \-
+specifications. They will be processed only if the flag argument is scanned.
+This allows optional specification of parameters corresponding to a flag
+(e.g.
+.I \-f file
+). Corresponding arguments on the command line must appear between the flag
+which introduces them and the next flag in the command line.
+.RE
+.TP 4
+.B $
+This may appear only as the last specifier in the format string, and is used
+to "eat up" the rest of the command arguments. The corresponding function
+argument is an
+.I int
+pointer. An index into
+.I argv
+to the dividing point between the arguments which have been used, and those
+which have not is returned. This index points to the first unused command
+argument. If there is no such dividing point, an error
+will be generated.
+.PP
+A string or numeric conversion character may be preceded by a
+.B *
+or a
+.B ,
+to indicate that a list of such arguments is expected. If
+.B ,
+is used, then the AT&T proposed argument standard is followed, and a single
+string is expected, with the individual list elements separated by commas or
+spaces. Two commas in a row will produce a null entry (0 if numeric,
+zero-length string if string conversion), but multiple spaces, and spaces
+following a comma, are taken as a single separator. If
+.B *
+is specified, then multiple arguments are parsed to produce the list. A
+format specifier with a
+.B *
+or a
+.B ,
+takes two arguments. The first is an
+.B int
+pointer, the number of items in the list is returned here. The second is a
+pointer to pointer to the correct data type for the format specifier. A
+pointer to the list of arguments is returned here.
+.PP
+The scanner will process the control string from left to right,
+and where there are multiple conversions of the same type, they will
+be assigned one to one with their order of occurrence in the argument list.
+Where the order of the arguments is not ambiguous in the control string,
+they may occur in any order in the argument list. (ie. A decimal number
+will not be confused with a flag, but may
+be confused with an octal number or another decimal number. So if an
+octal and a decimal number are to be arguments, their order will determine
+their conversion, while a decimal number and a flag as arguments may occur
+in any order and still be converted correctly.)
+.PP
+An argument list that does not match the requirements of the control
+string will cause the printing of a short message telling why, and
+a message telling what the correct usage is.
+This usage is gleaned from the control string, and the labels are used
+directly. The labels should be both terse and descriptive! Spaces, tabs,
+and newlines in the format string will be reproduced in the usage message,
+and can be used for effective prettyprinting. A single tab (following a
+newline) will indent the line directly under the command name in the usage
+message.
+.PP
+The
+.I scanargs
+function returns 1 when the argument list matched the requirements
+of the control string, and returns 0 if there was a failure.
+Parameters for any conversions not matched are left untouched.
+.br
+For example, the call
+.RS
+.PP
+int i; double x; char *name;
+.br
+scanargs(argc, argv, "program decimal%d floating%F file%s"
+.in 15
+, &i, &x, &name );
+.RE
+.PP
+in a C program executed by the shell command
+.RS
+.PP
+.I %
+program 10 3.5397 inputfile
+.RE
+.PP
+will assign to
+.I i
+the value 10,
+.I x
+the value 3.5397, and
+.I name
+will point to the string "inputfile".
+.PP
+If the program was executed by the shell command
+.RS
+.PP
+.I %
+program 3.4 .7 inputfile
+.RE
+.PP
+the following would be printed on the standard error:
+.RS
+.PP
+extra arguments not processed
+.br
+usage : program [decimal] [floating] [file]
+.RE
+.PP
+because 3.4 matches the type of 'floating' and inputfile matches
+the type of 'file', leaving .7 unmatched (it is considered a string by
+scanargs, to be considered a number, it must begin with a digit).
+.PP
+Finally, executing the command
+.RS
+.br
+.I %
+program 10
+.RE
+.br
+would assign 10 to
+.IR i ,
+leaving
+.I x
+and
+.I name
+unaffected.
+.PP
+This call could be used for the
+.IR diff (1)
+command
+.RS
+.PP
+int blanks; int flags; char *file1; char *file2;
+.br
+scanargs(argc, argv, "diff b%\- efh%\- file1!s file2!s"
+.in 15
+, &blanks, &flags, &file1, &file2 );
+.RE
+.PP
+and would only allow one of either
+.B "\-e \-f"
+or
+.B \-h
+to be chosen optionally, with
+.B \-b
+as an independent option.
+.B File1
+and
+.B file2
+are both required.
+The usage message for this version of
+.I diff
+would be
+.RS
+.PP
+usage : diff [\-b] \-{efh} file1 file2
+.RE
+
+This call could be used for a simplified version of the
+.IR sed (1)
+command
+.RS
+.PP
+int efile; int noprint; char *script; char *file1; char *file2;
+.br
+scanargs(argc, argv, "sed n%\- script%s f%\-editfile!s file%s"
+.in 15
+, &noprint, &script, &efile, &file1, &file2 );
+.RE
+.PP
+If the
+.B \-f
+option is specified, then a file name must be given as the next string
+argument.
+The usage message for this version of
+.I sed
+would be
+.RS
+.PP
+usage : sed [\-n] [script] [\-f editfile] file
+.RE
+
+.PP
+Further notes on putting together a format string:
+.PP
+It is still possible for conditional arguments to be confused with
+arguments which stand alone. For this reason, it is recommended that
+all flags (and associated conditional arguments) be specified first in
+the scanargs format string. This ordering is not necessary for the
+command line arguments, however. The only case which could still cause
+confusion if these rules are followed is illustrated below:
+.br
+.RS
+format string: "prog d%\-num%d othernum%d"
+.br
+command line: prog \-d 9
+.RE
+.br
+It is unclear whether the number 9 should be associated with the
+.I num
+parameter or the
+.I othernum
+parameter.
+.I Scanargs
+assigns it to the
+.I num
+parameter. To force it to be associated with
+.I othernum
+the
+command could be invoked as either
+.br
+.RS
+ prog 9 \-d
+.br
+or prog \-d \-\- 9
+.RE
+.br
+The
+.B \-\-
+in the second example is interpreted as a flag, thereby
+terminating the scan for arguments introduced by the
+.BR \-d .
+According to the proposed standard, an argument of
+.B \-\-
+is to be interpreted as terminating the optional arguments on a flag.
+.PP
+Note that if the format string in the above example were
+.br
+.RS
+ "prog othernum%d d%\-num%d"
+.RE
+.br
+it would be impossible to assign a value to
+.I num
+without also
+assigning a value to
+.I othernum.
+
+.SH SEE ALSO
+exec(2), scanf(3S)
+.SH DIAGNOSTICS
+Returns 0 on error, 1 on success.
+.SH AUTHOR
+Gary Newman \(em Ampex Corporation
+.br
+Spencer W. Thomas \(em University of Utah
+.SH BUGS
+By its nature a call to scanargs defines a syntax
+which may be ambiguous, and although the results may be surprising,
+they are quite predictable.
+The heuristic used to tell string arguments from numeric arguments is just
+that. In fact, that you can't give a number as a string argument
+is sort of bogus.
diff --git a/obsolete/support/undump/scanargs.c b/obsolete/support/undump/scanargs.c
new file mode 100644
index 0000000000..ec78837f93
--- /dev/null
+++ b/obsolete/support/undump/scanargs.c
@@ -0,0 +1,879 @@
+/*
+ * $Header: scanargs.c,v 1.7 86/11/16 03:25:48 thomas Exp $
+ * Version 7 compatible
+ * Argument scanner, scans argv style argument list.
+ *
+ * Some stuff is a kludge because sscanf screws up
+ *
+ * Gary Newman - 10/4/1979 - Ampex Corp.
+ *
+ * Modified by Spencer W. Thomas, Univ. of Utah, 5/81 to
+ * add args introduced by a flag, add qscanargs call,
+ * allow empty flags.
+ *
+ * Compiling with QUICK defined generates 'qscanargs' ==
+ * scanargs w/o floating point support; avoids huge size
+ * of scanf.
+ *
+ * If you make improvements we'd like to get them too.
+ * Jay Lepreau lepreau@utah-20, decvax!harpo!utah-cs!lepreau
+ * Spencer Thomas thomas@utah-20, decvax!harpo!utah-cs!thomas
+ *
+ * (I know the code is ugly, but it just grew, you see ...)
+ *
+ * Modified by: Spencer W. Thomas
+ * Date: Feb 25 1983
+ * 1. Fixed scanning of optional args. Now args introduced by a flag
+ * must follow the flag which introduces them and precede any other
+ * flag argument. It is still possible for a flag introduced
+ * argument to be mistaken for a "bare" argument which occurs
+ * earlier in the format string. This implies that flags may not
+ * be conditional upon other flags, and a message will be generated
+ * if this is attempted.
+ *
+ * 2. Usage message can be formatted by inserting newlines, tabs and
+ * spaces into the format string. This is especially useful for
+ * long argument lists.
+ *
+ * 3. Added n/N types for "numeric" args. These args are scanned
+ * using the C language conventions - a number starting 0x is
+ * hexadecimal, a number starting with 0 is octal, otherwise it is
+ * decimal.
+ *
+ * Modified at BRL 16-May-88 by Mike Muuss to avoid Alliant STDC desire
+ * to have all "void" functions so declared.
+ */
+
+#include <stdio.h>
+#include <ctype.h>
+#include <varargs.h>
+
+typedef char bool;
+/*
+ * An explicit assumption is made in this code that all pointers look
+ * alike, except possible char * pointers.
+ */
+typedef int *ptr;
+
+#define YES 1
+#define NO 0
+#define ERROR(msg) {fprintf(stderr, "msg\n"); goto error; }
+
+/*
+ * Storage allocation macros
+ */
+#define NEW( type, cnt ) (type *) malloc( (cnt) * sizeof( type ) )
+#define RENEW( type, ptr, cnt ) (type *) realloc( ptr, (cnt) * sizeof( type ) )
+
+static char * prformat();
+static bool isnum();
+static int _do_scanargs();
+void scan_usage();
+
+/*
+ * Argument list is (argc, argv, format, ... )
+ */
+#ifndef QUICK
+scanargs ( va_alist )
+#else
+qscanargs ( va_alist )
+#endif
+va_dcl
+{
+ va_list argl;
+ int retval;
+
+ va_start( argl );
+ retval = _do_scanargs( argl );
+ va_end( argl );
+ return retval;
+}
+
+/*
+ * This routine is necessary because of a pyramid compiler botch that
+ * uses parameter registers in a varargs routine. The extra
+ * subroutine call isolates the args on the register stack so they
+ * don't get trashed.
+ */
+
+static
+_do_scanargs( argl )
+va_list argl;
+{
+ int argc; /* Actual arguments */
+ char **argv;
+ char *format;
+
+ register check; /* check counter to be sure all argvs
+ are processed */
+ register char *cp;
+ register cnt;
+ int optarg = 0; /* where optional args start */
+ int nopt;
+ char tmpflg, /* temp flag */
+ typchr; /* type char from format string */
+ char c;
+ bool * arg_used; /* array of flags */
+ char * malloc();
+ ptr aptr; /* pointer to return loc */
+
+ bool required;
+ int excnt; /* which flag is set */
+ bool exflag; /* when set, one of a set of exclusive
+ flags is set */
+
+ bool list_of; /* set if parsing off a list of args */
+ bool comma_list; /* set if AT&T style multiple args */
+ int * cnt_arg; /* where to stuff list count */
+ int list_cnt; /* how many in list */
+ /* These are used to build return lists */
+ char ** strlist;
+ int * intlist;
+ long * longlist;
+ float * fltlist;
+ double *dbllist;
+
+ char *ncp; /* remember cp during flag scanning */
+#ifndef QUICK
+ char *cntrl; /* control string for scanf's */
+ char junk[2]; /* junk buffer for scanf's */
+
+ cntrl = "% %1s"; /* control string initialization for
+ scanf's */
+#endif
+
+ argc = va_arg( argl, int );
+ argv = va_arg( argl, char ** );
+ format = va_arg( argl, char * );
+
+ arg_used = NEW( bool, argc );
+ if (arg_used == NULL)
+ {
+ fprintf(stderr, "malloc failed in scanargs, exiting\n");
+ exit(-1);
+ }
+ else
+ {
+ for (cnt=0; cnt<argc; cnt++)
+ arg_used[cnt] = NO;
+ }
+
+ check = 0;
+ cp = format;
+ /*
+ * Skip program name
+ */
+ while ( *cp != ' ' && *cp != '\t' && *cp != '\n' && *cp != '\0' )
+ cp++;
+
+ while (*cp)
+ {
+ required = NO; /* reset per-arg flags */
+ list_of = NO;
+ comma_list = NO;
+ list_cnt = 0;
+ switch (*(cp++))
+ {
+ default: /* all other chars */
+ break;
+ case ' ': /* separators */
+ case '\t':
+ case '\n':
+ optarg = 0; /* end of optional arg string */
+ break;
+
+ case '!': /* required argument */
+ required = YES;
+ case '%': /* not required argument */
+reswitch: /* after finding '*' or ',' */
+ switch (typchr = *(cp++))
+ {
+ case ',': /* argument is AT&T list of things */
+ comma_list = YES;
+ case '*': /* argument is list of things */
+ list_of = YES;
+ list_cnt = 0; /* none yet */
+ cnt_arg = va_arg( argl, int *); /* item count * here */
+ goto reswitch; /* try again */
+
+ case '$': /* "rest" of argument list */
+ while ( argc > 1 && !arg_used[argc-1] )
+ argc--; /* find last used argument */
+ *va_arg( argl, int * ) = argc;
+ break;
+
+ case '-': /* argument is flag */
+ if (optarg > 0)
+ ERROR(Format error: flag conditional on flag not allowed);
+
+ /* go back to label */
+ ncp = cp-1; /* remember */
+ cp -= 3;
+ for (excnt = exflag = 0
+ ; *cp != ' ' && !(*cp=='-' &&(cp[-1]=='!'||cp[-1]=='%'));
+ (--cp, excnt++))
+ {
+ for (cnt = optarg+1; cnt < argc; cnt++)
+ {
+ /* flags all start with - */
+ if (*argv[cnt] == '-' && !arg_used[cnt] &&
+ !isdigit(argv[cnt][1]))
+ if (*(argv[cnt] + 1) == *cp)
+ {
+ if (*(argv[cnt] + 2) != 0)
+ ERROR (extra flags ignored);
+ if (exflag)
+ ERROR (more than one exclusive flag chosen);
+ exflag++;
+ required = NO;
+ check += cnt;
+ arg_used[cnt] = 1;
+ nopt = cnt;
+ *va_arg( argl, int *) |= (1 << excnt);
+ break;
+ }
+ }
+ }
+ if (required)
+ ERROR (flag argument missing);
+ cp = ncp;
+ /*
+ * If none of these flags were found, skip any
+ * optional arguments (in the varargs list, too).
+ */
+ if (!exflag)
+ {
+ va_arg( argl, int * ); /* skip the arg, too */
+ while (*++cp && ! isspace(*cp))
+ if (*cp == '!' || *cp == '%')
+ {
+ if ( *++cp == '*' || *cp == ',' )
+ {
+ cp++;
+ va_arg( argl, int * );
+ }
+ /*
+ * Assume that char * might be a
+ * different size, but that all
+ * other pointers are same size.
+ */
+ if ( *cp == 's' )
+ va_arg( argl, char * );
+ else
+ va_arg( argl, ptr );
+ }
+ }
+ else
+ {
+ optarg = nopt;
+ cp++; /* skip over - */
+ }
+
+ break;
+
+ case 's': /* char string */
+ case 'd': /* decimal # */
+ case 'o': /* octal # */
+ case 'x': /* hexadecimal # */
+ case 'n': /* "number" in C syntax */
+#ifndef QUICK
+ case 'f': /* floating # */
+#endif
+ case 'D': /* long decimal # */
+ case 'O': /* long octal # */
+ case 'X': /* long hexadecimal # */
+ case 'N': /* long number in C syntax */
+#ifndef QUICK
+ case 'F': /* double precision floating # */
+#ifdef sgi
+ /* Fix for broken SGI IRIS floats */
+ if ( typchr == 'F' ) typchr = 'f';
+#endif /* sgi */
+#endif /* QUICK */
+ for (cnt = optarg+1; cnt < argc; cnt++)
+ {
+ ncp = argv[cnt];
+
+ if ( isnum( ncp, typchr, comma_list ) )
+ {
+ ; /* it's ok, then */
+ }
+ else if ( *ncp == '-' && ncp[1] != '\0' )
+ if ( optarg > 0 ) /* end optional args? */
+ {
+ /* Eat the arg, too, if necessary */
+ if ( list_cnt == 0 )
+ if ( typchr == 's' )
+ va_arg( argl, char * );
+ else
+ va_arg( argl, ptr );
+ break;
+ }
+ else
+ continue;
+ else if ( typchr != 's' )
+ continue; /* not number, keep looking */
+
+ /*
+ * Otherwise usable argument may already
+ * be used. (Must check this after
+ * checking for flag, though.)
+ */
+ if (arg_used[cnt]) continue;
+
+ /*
+ * If it's a comma-and-or-space-separated
+ * list then count how many, and separate
+ * the list into an array of strings.
+ */
+ if ( comma_list )
+ {
+ register char * s;
+ int pass;
+
+ /*
+ * On pass 0, just count them. On
+ * pass 1, null terminate each string
+ */
+ for ( pass = 0; pass <= 1; pass++ )
+ {
+ for ( s = ncp; *s != '\0'; )
+ {
+ if ( pass )
+ strlist[list_cnt] = s;
+ while ( (c = *s) != '\0' && c != ' ' &&
+ c != '\t' && c != ',' )
+ s++;
+ if ( pass )
+ *s = '\0';
+
+ list_cnt++; /* count separators */
+ /*
+ * Two commas in a row give a null
+ * string, but two spaces
+ * don't. Also skip spaces
+ * after a comma.
+ */
+ if ( c != '\0' )
+ while ( *++s == ' ' || *s == '\t' )
+ ;
+ }
+ if ( pass == 0 )
+ {
+ strlist = NEW( char *, list_cnt );
+ list_cnt = 0;
+ }
+ }
+ }
+ else if ( list_of )
+ list_cnt++; /* getting them one at a time */
+ /*
+ * If it's either type of list, then alloc
+ * storage space for the returned values
+ * (except that comma-separated string
+ * lists already are done).
+ */
+ if ( list_of )
+ {
+ if ( list_cnt == 1 || comma_list )
+ switch( typchr )
+ {
+ case 's':
+ if ( !comma_list )
+ strlist = NEW( char *, 1 );
+ aptr = (ptr) &strlist[0];
+ break;
+ case 'n':
+ case 'd':
+ case 'o':
+ case 'x':
+ intlist = NEW( int, list_cnt );
+ aptr = (ptr) &intlist[0];
+ break;
+ case 'N':
+ case 'D':
+ case 'O':
+ case 'X':
+ longlist = NEW( long, list_cnt );
+ aptr = (ptr) &longlist[0];
+ break;
+ case 'f':
+ fltlist = NEW( float, list_cnt );
+ aptr = (ptr) &fltlist[0];
+ break;
+ case 'F':
+ dbllist = NEW( double, list_cnt );
+ aptr = (ptr) &dbllist[0];
+ break;
+ }
+ else
+ switch( typchr )
+ {
+ case 's':
+ strlist = RENEW( char *, strlist,
+ list_cnt );
+ aptr = (ptr) &strlist[list_cnt-1];
+ break;
+ case 'n':
+ case 'd':
+ case 'o':
+ case 'x':
+ intlist = RENEW( int, intlist,
+ list_cnt );
+ aptr = (ptr) &intlist[list_cnt-1];
+ break;
+ case 'N':
+ case 'D':
+ case 'O':
+ case 'X':
+ longlist = RENEW( long, longlist,
+ list_cnt );
+ aptr = (ptr) &longlist[list_cnt-1];
+ break;
+ case 'f':
+ fltlist = RENEW( float, fltlist,
+ list_cnt );
+ aptr = (ptr) &fltlist[list_cnt-1];
+ break;
+ case 'F':
+ dbllist = RENEW( double, dbllist,
+ list_cnt );
+ aptr = (ptr) &dbllist[list_cnt-1];
+ break;
+ }
+ }
+ else
+ aptr = va_arg( argl, ptr );
+
+ if ( typchr == 's' )
+ {
+ if ( ! comma_list )
+ *(char **)aptr = ncp;
+ }
+ else
+ {
+ nopt = 0;
+ do {
+ /*
+ * Need to update aptr if parsing
+ * a comma list
+ */
+ if ( comma_list && nopt > 0 )
+ {
+ ncp = strlist[nopt];
+ switch( typchr )
+ {
+ case 'n':
+ case 'd':
+ case 'o':
+ case 'x':
+ aptr = (ptr) &intlist[nopt];
+ break;
+ case 'N':
+ case 'D':
+ case 'O':
+ case 'X':
+ aptr = (ptr) &longlist[nopt];
+ break;
+ case 'f':
+ aptr = (ptr) &fltlist[nopt];
+ break;
+ case 'F':
+ aptr = (ptr) &dbllist[nopt];
+ break;
+ }
+ }
+ /*
+ * Do conversion for n and N types
+ */
+ tmpflg = typchr;
+ if (typchr == 'n' || typchr == 'N' )
+ if (*ncp != '0')
+ tmpflg = 'd';
+ else if (*(ncp+1) == 'x' ||
+ *(ncp+1) == 'X')
+ {
+ tmpflg = 'x';
+ ncp += 2;
+ }
+ else
+ tmpflg = 'o';
+ if (typchr == 'N')
+ toupper( tmpflg );
+
+
+#ifndef QUICK
+ cntrl[1] = tmpflg;/* put in conversion */
+ if (sscanf (ncp, cntrl, aptr, junk) != 1)
+ ERROR (Bad numeric argument);
+#else
+ if (numcvt(ncp, tmpflg, aptr) != 1)
+ ERROR (Bad numeric argument);
+#endif
+ } while ( comma_list && ++nopt < list_cnt );
+ }
+ check += cnt;
+ arg_used[cnt] = 1;
+ required = NO;
+ /*
+ * If not looking for multiple args,
+ * then done, otherwise, keep looking.
+ */
+ if ( !( list_of && !comma_list ) )
+ break;
+ else
+ continue;
+ }
+ if (required)
+ switch (typchr)
+ {
+ case 'x':
+ case 'X':
+ ERROR (missing hexadecimal argument);
+ case 's':
+ ERROR (missing string argument);
+ case 'o':
+ case 'O':
+ ERROR (missing octal argument);
+ case 'd':
+ case 'D':
+ ERROR (missing decimal argument);
+ case 'f':
+ case 'F':
+ ERROR (missing floating argument);
+ case 'n':
+ case 'N':
+ ERROR (missing numeric argument);
+ }
+ if ( list_cnt > 0 )
+ {
+ *cnt_arg = list_cnt;
+ switch ( typchr )
+ {
+ case 's':
+ *va_arg( argl, char *** ) = strlist;
+ break;
+ case 'n':
+ case 'd':
+ case 'o':
+ case 'x':
+ *va_arg( argl, int ** ) = intlist;
+ break;
+ case 'N':
+ case 'D':
+ case 'O':
+ case 'X':
+ *va_arg( argl, long ** ) = longlist;
+ break;
+ case 'f':
+ *va_arg( argl, float ** ) = fltlist;
+ break;
+ case 'F':
+ *va_arg( argl, double **) = dbllist;
+ break;
+ }
+ if ( typchr != 's' )
+ free( (char *) strlist );
+ }
+ else if ( cnt >= argc )
+ {
+ /* Fell off end looking, so must eat the arg */
+ if ( typchr == 's' )
+ va_arg( argl, char * );
+ else
+ va_arg( argl, ptr );
+ }
+ break;
+ default: /* error */
+ fprintf (stderr, "error in call to scanargs\n");
+ return (0);
+ }
+ }
+ }
+
+ /* Count up empty flags */
+ for (cnt=1; cnt<argc; cnt++)
+ if (argv[cnt][0] == '-' && argv[cnt][1] == '-' && argv[cnt][2] == 0
+ && !arg_used[cnt] )
+ check += cnt;
+
+ /* sum from 1 to N = n*(n+1)/2 used to count up checks */
+ if (check != (((argc - 1) * argc) / 2))
+ ERROR (extra arguments not processed);
+
+ free(arg_used);
+ return (1);
+
+error:
+ scan_usage( argv, format );
+ free(arg_used);
+ return 0;
+}
+
+void
+scan_usage( argv, format )
+char ** argv;
+char * format;
+{
+ register char * cp;
+
+ fprintf (stderr, "usage : ");
+ if (*(cp = format) != ' ')
+ {
+ if ( *cp == '%' )
+ {
+ /*
+ * This is bogus, but until everyone can agree on a name
+ * for (rindex/strrchr) ....
+ */
+ for ( cp = argv[0]; *cp != '\0'; cp++ )
+ ; /* find the end of the string */
+ for ( ; cp > argv[0] && *cp != '/'; cp-- )
+ ; /* find the last / */
+ if ( *cp == '/' )
+ cp++;
+ fprintf( stderr, "%s", cp );
+
+ cp = format + 1; /* reset to where it should be */
+ }
+ while (putc (*cp++, stderr) != ' ');
+ }
+ else
+ fprintf (stderr, "?? ");
+ while (*cp == ' ')
+ cp++;
+ prformat (cp, NO);
+}
+
+static char *
+prformat (format, recurse)
+char *format;
+{
+ register char *cp;
+ bool required, comma_list;
+ int list_of;
+
+ cp = format;
+ if (recurse)
+ putc (' ', stderr);
+
+ required = NO;
+ list_of = 0;
+ comma_list = NO;
+ while (*cp)
+ {
+ switch (*cp)
+ {
+ default:
+ cp++;
+ break;
+ case ' ':
+ case '\n':
+ case '\t':
+ /* allow annotations */
+ for ( ; format < cp; format++ )
+ putc( *format, stderr );
+ putc(*cp, stderr);
+ format = ++cp;
+ break;
+ case '!':
+ required = YES;
+ case '%':
+reswitch:
+ switch (*++cp)
+ {
+ case ',':
+ comma_list++;
+ case '*':
+ list_of++;
+ goto reswitch;
+
+ case '$': /* "rest" of argument list */
+ if (!required)
+ putc ('[', stderr);
+ for (; format < cp - 1 - list_of; format++)
+ putc (*format, stderr);
+ fputs( " ...", stderr );
+ if ( !required )
+ putc( ']', stderr );
+ break;
+
+ case '-': /* flags */
+ if (!required)
+ putc ('[', stderr);
+ putc ('-', stderr);
+
+ if (cp - format > 2 + list_of)
+ putc ('{', stderr);
+ cp = format;
+ while (*cp != '%' && *cp != '!')
+ putc (*cp++, stderr);
+ if (cp - format > 1 + list_of)
+ putc ('}', stderr);
+ cp += 2; /* skip !- or %- */
+ if (*cp && !isspace(*cp))
+ cp = prformat (cp, YES);
+ /* this is a recursive call */
+
+ cp--; /* don't ignore next character */
+
+ if (!required)
+ putc (']', stderr);
+ break;
+ case 's': /* char string */
+ case 'd': /* decimal # */
+ case 'o': /* octal # */
+ case 'x': /* hexadecimal # */
+ case 'f': /* floating # */
+ case 'D': /* long decimal # */
+ case 'O': /* long octal # */
+ case 'X': /* long hexadecimal # */
+ case 'F': /* double precision floating # */
+ case 'n': /* numeric arg (C format) */
+ case 'N': /* long numeric arg */
+ if (!required)
+ putc ('[', stderr);
+ for (; format < cp - 1 - list_of; format++)
+ putc (*format, stderr);
+ if ( list_of != 0 )
+ {
+ if ( comma_list )
+ putc( ',', stderr );
+ else
+ putc( ' ', stderr );
+ fputs( "...", stderr );
+ }
+ if (!required)
+ putc (']', stderr);
+ break;
+ default:
+ break;
+ }
+ required = NO;
+ list_of = NO;
+ comma_list = NO;
+ if (*cp) /* check for end of string */
+ format = ++cp;
+ if (*cp && !isspace(*cp))
+ putc (' ', stderr);
+ }
+ if (recurse && isspace(*cp))
+ break;
+ }
+ if (!recurse)
+ {
+ for ( ; format < cp; format++ )
+ putc( *format, stderr );
+ putc ('\n', stderr);
+ }
+ return (cp);
+}
+
+/*
+ * isnum - determine whether a string MIGHT represent a number.
+ * typchr indicates the type of argument we are looking for, and
+ * determines the legal character set. If comma_list is YES, then
+ * space and comma are also legal characters.
+ */
+static bool
+isnum( str, typchr, comma_list )
+register char * str;
+char typchr;
+bool comma_list;
+{
+ register char * allowed, * digits, * cp;
+ bool hasdigit = NO;
+
+ switch( typchr )
+ {
+ case 'n':
+ case 'N':
+ allowed = " \t,+-x0123456789abcdefABCDEF";
+ break;
+ case 'd':
+ case 'D':
+ allowed = " \t,+-0123456789";
+ break;
+ case 'o':
+ case 'O':
+ allowed = " \t,01234567";
+ break;
+ case 'x':
+ case 'X':
+ allowed = " \t,0123456789abcdefABCDEF";
+ break;
+ case 'f':
+ case 'F':
+ allowed = " \t,+-eE.0123456789";
+ break;
+ case 's': /* only throw out decimal numbers */
+ default:
+ allowed = " \t,+-.0123456789";
+ break;
+ }
+ digits = allowed;
+ while ( *digits != '0' )
+ digits++;
+ if ( ! comma_list )
+ allowed += 3; /* then don't allow space, tab, comma */
+
+ while ( *str != '\0' )
+ {
+ for ( cp = allowed; *cp != '\0' && *cp != *str; cp++ )
+ ;
+ if ( *cp == '\0' )
+ return NO; /* if not in allowed chars, not number */
+ if ( cp - digits >= 0 )
+ hasdigit = YES;
+ str++;
+ }
+ return hasdigit;
+}
+
+#ifdef QUICK
+numcvt(str, conv, val)
+register char *str;
+char conv;
+int *val;
+{
+ int base, neg = 0;
+ register unsigned int d;
+ long retval = 0;
+ register char *digits;
+ extern char *index();
+ if (conv == 'o' || conv == 'O')
+ base = 8;
+ else if (conv == 'd' || conv == 'D')
+ base = 10;
+ else if (conv == 'x' || conv == 'X')
+ base = 16;
+ else
+ return 0;
+
+ if (*str == '-')
+ {
+ neg = 1;
+ str++;
+ }
+ while (*str)
+ {
+ if (*str >= '0' && *str < '0'+base)
+ d = *str - '0';
+ else if (base == 16 && *str >= 'a' && *str <= 'f')
+ d = 10 + *str - 'a';
+ else if (base == 16 && *str >= 'A' && *str <= 'F')
+ d = 10 + *str - 'A';
+ else
+ return 0;
+ retval = retval*base + d;
+ str++;
+ }
+ if (neg)
+ retval = -retval;
+ if (conv == 'D' || conv == 'O' || conv == 'X')
+ *(long *) val = retval;
+ else
+ *val = (int) retval;
+ return 1;
+}
+#endif QUICK
diff --git a/obsolete/support/undump/undump.1 b/obsolete/support/undump/undump.1
new file mode 100644
index 0000000000..797cdb0377
--- /dev/null
+++ b/obsolete/support/undump/undump.1
@@ -0,0 +1,28 @@
+.TH UNDUMP 1 "University of Utah"
+.SH NAME
+undump \- convert a core dump to an executable a.out file
+.SH SYNOPSIS
+undump new-a.out-file [old-a.out-file] [core-file]
+.SH DESCRIPTION
+Undump takes a core dump file and the executable "a.out" file which
+caused it and produces a new executable file with all static
+variables initialised to the values they held at the time of the
+core dump. It is primarily useful for programs which take a long time
+to initialise themselves, e.g. Emacs. The idea is to go through all of
+the initialisations and then create a core dump (e.g. with the abort()
+call). One then uses undump to make a new executable file with all of it
+done. This usually implies the use of a global flag variable which says
+whether or not initialisation has been done.
+.PP
+Undump's arguments, old-a.out-file and core-file, default to "a.out" and
+"core", respectively.
+.PP
+A few things to keep in mind about undump:
+.IP
+It doesn't preserve open files.
+.IP
+The program will be re-entered at the beginning of main(), not at the point
+where the core dump occurred.
+.SH BUGS
+Probably should have an option to not require
+old-a.out-file if the core came from a 407 file.
diff --git a/obsolete/support/undump/undump.BALANCE.c b/obsolete/support/undump/undump.BALANCE.c
new file mode 100644
index 0000000000..e8bdedec11
--- /dev/null
+++ b/obsolete/support/undump/undump.BALANCE.c
@@ -0,0 +1,298 @@
+/*
+ * This program is hacked for Sequent Balance.
+ * The original is from 4.2undump.c of UNIX TeX distribution.
+ * This is tested on Serquent Balance 21000, DYNIX 2.1.1
+ * with UNIX TeX 2.1. Modification may be necessary for newer DYNIX.
+ * Takashi Chikayama, ICOT Research Center.
+ */
+
+/*
+ * This program was advertised on unix-wizards. I have had such a large
+ * response I'm sending it out to the world.
+ *
+ * Here is the source. It works fine under 4.1bsd, I see no fundamental
+ * reason why it shouldn't work on an 11. (Except possibly small format
+ * changes in exec header or user structure.) No documentation yet.
+ * Usage is
+ * undump new-a.out-file [old-a.out-file] [core-file]
+ * where old-a.out-file and core-file default to "a.out" and "core",
+ * respectively. Probably should have an option to not require
+ * old-a.out-file if the core came from a 407 file.
+ *
+ * It doesn't preserve open files, and the program is re-entered at main
+ * when you run it. It's used locally to dump a lisp and restart it.
+ *
+ * It requires a local subroutine called scanargs, somewhat similar to
+ * getopt (I think). You should be able to easily get around this, though.
+ * =Spencer
+ */
+
+
+/*
+ * undump.c - Convert a core file to an a.out.
+ *
+ * Author: Spencer W. Thomas
+ * Computer Science Dept.
+ * University of Utah
+ * Date: Wed Feb 17 1982
+ * Copyright (c) 1982 Spencer W. Thomas
+ *
+ * Modification for Balance/DYNIX 2.1.1:
+ * Takashi Chikayama
+ * ICOT Research Center
+ * Date: Wed Nov 25 1987
+ * Copyright (c) 1987 Takashi Chikayama
+ * See copy_text for details.
+ *
+ * Usage:
+ * undump new-a.out [a.out] [core]
+ */
+
+#include <stdio.h>
+#include <sys/param.h>
+#include <sys/dir.h>
+#include <sys/user.h>
+#include <sys/stat.h>
+#include <a.out.h>
+
+#define PSIZE 10240
+
+struct user u;
+struct exec hdr, ohdr;
+
+main(argc, argv)
+char **argv;
+{
+ char *new_name, *a_out_name = "a.out", *core_name = "core";
+ FILE *new, *a_out, *core;
+
+ if (scanargs(argc, argv, "undump new-a.out!s a.out%s core%s",
+ &new_name, &a_out_name, &core_name)
+ != 1)
+ exit(1);
+
+ if ((a_out = fopen(a_out_name, "r")) == NULL)
+ {
+ perror(a_out_name);
+ exit(1);
+ }
+ if ((core = fopen(core_name, "r")) == NULL)
+ {
+ perror(core_name);
+ exit(1);
+ }
+ if ((new = fopen(new_name, "w")) == NULL)
+ {
+ perror(new_name);
+ exit(1);
+ }
+
+ read_u(core);
+ make_hdr(new, a_out);
+ copy_text(new, a_out);
+ copy_data(new, core);
+ copy_sym(new, a_out);
+ fclose(new);
+ fclose(core);
+ fclose(a_out);
+ mark_x(new_name);
+}
+
+/*
+ * read the u structure from the core file.
+ */
+read_u(core)
+FILE *core;
+{
+ if ( fread(&u, sizeof u, 1, core) != 1 )
+ {
+ perror("Couldn't read user structure from core file");
+ exit(1);
+ }
+}
+
+/*
+ * Make the header in the new a.out from the header in the old one
+ * modified by the new data size.
+ */
+make_hdr(new, a_out)
+FILE *new, *a_out;
+{
+ if (fread(&hdr, sizeof hdr, 1, a_out) != 1)
+ {
+ perror("Couldn't read header from a.out file");
+ exit(1);
+ }
+ ohdr = hdr;
+ if N_BADMAG(hdr)
+ {
+ fprintf(stderr, "a.out file doesn't have legal magic number\n");
+ exit(1);
+ }
+
+/*** Checks are omitted for now. (T.C.)
+ if (hdr.a_magic != u.u_exdata.ux_mag ||
+ hdr.a_text != u.u_exdata.ux_tsize ||
+ hdr.a_data != u.u_exdata.ux_dsize ||
+ hdr.a_entry != u.u_exdata.ux_entloc)
+ {
+ fprintf(stderr, "Core file didn't come from this a.out\n");
+ exit(1);
+ }
+***/
+
+ printf("Data segment size was %u", hdr.a_data);
+ hdr.a_data = ctob(u.u_dsize);
+ hdr.a_bss = 0; /* all data is inited now! */
+ printf(" now is %u\n", hdr.a_data);
+ if (fwrite(&hdr, sizeof hdr, 1, new) != 1)
+ {
+ perror("Couldn't write header to new a.out file");
+ exit(1);
+ }
+}
+
+/*
+ * Copy the text from the a.out to the new a.out
+ */
+copy_text(new, a_out)
+FILE *new, *a_out;
+{
+ char page[PSIZE];
+/*
+ * Modification by T.C.:
+ * Text size is actually smaller in files in case of DYNIX.
+ * As a_text includes exec structure, we avoid overwriting it here.
+ */
+ int txtcnt = hdr.a_text - N_ADDRADJ(hdr) - sizeof(struct exec);
+ fseek(new, sizeof(struct exec), 0);
+ fseek(a_out, sizeof(struct exec), 0);
+ if (hdr.a_magic == OMAGIC)
+ {
+ printf("a.out file is not shared text, getting text from core file\n");
+ fseek(a_out, hdr.a_text, 1); /* skip over text */
+ return;
+ }
+ while (txtcnt >= PSIZE)
+ {
+ if (fread(page, PSIZE, 1, a_out) != 1)
+ {
+ perror("Read failure on a.out text");
+ exit(1);
+ }
+ if (fwrite(page, PSIZE, 1, new) != 1)
+ {
+ perror("Write failure in text segment");
+ exit(1);
+ }
+ txtcnt -= PSIZE;
+ }
+ if (txtcnt)
+ {
+ if (fread(page, txtcnt, 1, a_out) != 1)
+ {
+ perror("Read failure on a.out text");
+ exit(1);
+ }
+ if (fwrite(page, txtcnt, 1, new) != 1)
+ {
+ perror("Write failure in text segment");
+ exit(1);
+ }
+ }
+}
+
+/*
+ * copy the data from the core file to the new a.out
+ */
+copy_data(new, core)
+FILE *new, *core;
+{
+ char page[PSIZE];
+ int datacnt = ctob(u.u_dsize);
+
+ if (hdr.a_magic == OMAGIC)
+ datacnt += u.u_tsize;
+ fseek(core, ctob(UPAGES), 0);
+ while (datacnt >= PSIZE)
+ {
+ if (fread(page, PSIZE, 1, core) != 1)
+ {
+ perror("Read failure on core data");
+ exit(1);
+ }
+ if (fwrite(page, PSIZE, 1, new) != 1)
+ {
+ perror("Write failure in data segment");
+ exit(1);
+ }
+ datacnt -= PSIZE;
+ }
+ if (datacnt)
+ {
+ if (fread(page, datacnt, 1, core) != 1)
+ {
+ perror("Read failure on core data");
+ exit(1);
+ }
+ if (fwrite(page, datacnt, 1, new) != 1)
+ {
+ perror("Write failure in data segment");
+ exit(1);
+ }
+ }
+}
+
+/*
+ * Copy the relocation information and symbol table from the a.out to the new
+ */
+copy_sym(new, a_out)
+FILE *new, *a_out;
+{
+ char page[PSIZE];
+ int n;
+
+/*
+ * Modification by T.C.:
+ * Use macro N_SYMOFF to compute symbol table offset.
+ */
+ fseek(a_out, N_SYMOFF(ohdr), 0); /* find symbol table */
+ while ((n = fread(page, 1, PSIZE, a_out)) > 0)
+ {
+ if (fwrite(page, 1, n, new) != n)
+ {
+ perror("Error writing symbol table to new a.out");
+ fprintf(stderr, "new a.out should be ok otherwise\n");
+ return;
+ }
+ }
+ if (n < 0)
+ {
+ perror("Error reading symbol table from a.out");
+ fprintf(stderr, "new a.out should be ok otherwise\n");
+ }
+}
+
+/*
+ * After succesfully building the new a.out, mark it executable
+ */
+mark_x(name)
+char *name;
+{
+ struct stat sbuf;
+ int um;
+
+ um = umask(777);
+ umask(um);
+ if (stat(name, &sbuf) == -1)
+ {
+ perror ("Can't stat new a.out");
+ fprintf(stderr, "Setting protection to %o\n", 0777 & ~um);
+ sbuf.st_mode = 0777;
+ }
+ sbuf.st_mode |= 0111 & ~um;
+ if (chmod(name, sbuf.st_mode) == -1)
+ perror("Couldn't change mode of new a.out to executable");
+
+}
+
diff --git a/obsolete/support/undump/undump.PYR.c b/obsolete/support/undump/undump.PYR.c
new file mode 100644
index 0000000000..0dd413c77e
--- /dev/null
+++ b/obsolete/support/undump/undump.PYR.c
@@ -0,0 +1,287 @@
+/*
+ * This program was advertised on unix-wizards. I have had such a large
+ * response I'm sending it out to the world.
+ *
+ * Here is the source. It works fine under 4.1bsd, I see no fundamental
+ * reason why it shouldn't work on an 11. (Except possibly small format
+ * changes in exec header or user structure.) No documentation yet.
+ * Usage is
+ * undump new-a.out-file [old-a.out-file] [core-file]
+ * where old-a.out-file and core-file default to "a.out" and "core",
+ * respectively. Probably should have an option to not require
+ * old-a.out-file if the core came from a 407 file.
+ *
+ * It doesn't preserve open files, and the program is re-entered at main
+ * when you run it. It's used locally to dump a lisp and restart it.
+ *
+ * It requires a local subroutine called scanargs, somewhat similar to
+ * getopt (I think). You should be able to easily get around this, though.
+ * =Spencer
+ *
+ * Scanargs didn't work on the Pyramid, and its function was
+ * too simple in this case to bother with repair, so it was chucked.
+ * -Mike
+ */
+
+
+/*
+ * undump.c - Convert a core file to an a.out.
+ *
+ * Author: Spencer W. Thomas
+ * Computer Science Dept.
+ * University of Utah
+ * Date: Wed Feb 17 1982
+ * Copyright (c) 1982 Spencer W. Thomas
+ *
+ * Usage:
+ * undump new-a.out [a.out] [core]
+ */
+
+#include <stdio.h>
+#include <sys/param.h>
+#include <sys/dir.h>
+#include <sys/user.h>
+#include <sys/stat.h>
+#include <a.out.h>
+
+#define PSIZE 10240
+#define ctob(x) (x<<PGSHIFT) /* Pyramid */
+
+struct user u;
+struct exec hdr, ohdr;
+
+main(argc, argv)
+char **argv;
+{
+ char *new_name, *a_out_name = "a.out", *core_name = "core";
+ FILE *new, *a_out, *core;
+
+ /*if (scanargs(argc, argv, "undump new-a.out!s a.out%s core%s",
+ /*&new_name, &a_out_name, &core_name)
+ /*!= 1)
+ /*exit(1);*/
+ if ((argc > 4)|| (argc < 2)) {
+ fprintf(stderr, "Usage: %s new-a.out [old-a.out] [core]\n",argv[0]);
+ exit(1);
+ }
+ new_name = argv[1];
+ if (argc > 2) a_out_name = argv[2];
+ if (argc > 3) core_name = argv[3];
+ if ((a_out = fopen(a_out_name, "r")) == NULL)
+ {
+ perror(a_out_name);
+ exit(1);
+ }
+ if ((core = fopen(core_name, "r")) == NULL)
+ {
+ perror(core_name);
+ exit(1);
+ }
+ if ((new = fopen(new_name, "w")) == NULL)
+ {
+ perror(new_name);
+ exit(1);
+ }
+
+ read_u(core);
+ make_hdr(new, a_out);
+ copy_text(new, a_out);
+ copy_data(new, core);
+ copy_sym(new, a_out);
+ fclose(new);
+ fclose(core);
+ fclose(a_out);
+ mark_x(new_name);
+}
+
+/*
+ * read the u structure from the core file.
+ */
+read_u(core)
+FILE *core;
+{
+ if ( fread(&u, sizeof u, 1, core) != 1 )
+ {
+ perror("Couldn't read user structure from core file");
+ exit(1);
+ }
+}
+
+/*
+ * Make the header in the new a.out from the header in the old one
+ * modified by the new data size.
+ */
+make_hdr(new, a_out)
+FILE *new, *a_out;
+{
+ if (fread(&hdr, sizeof hdr, 1, a_out) != 1)
+ {
+ perror("Couldn't read header from a.out file");
+ exit(1);
+ }
+ ohdr = hdr;
+ if N_BADMAG(hdr)
+ {
+ fprintf(stderr, "a.out file doesn't have legal magic number\n");
+ exit(1);
+ }
+ if (hdr.a_magic != u.u_exdata.ux_mag ||
+ hdr.a_text != u.u_exdata.ux_tsize ||
+ hdr.a_data != u.u_exdata.ux_dsize ||
+ hdr.a_entry != u.u_exdata.ux_entloc)
+ {
+ fprintf(stderr, "Core file didn't come from this a.out\n");
+fprintf(stderr, "magic: %o %o", hdr.a_magic, u.u_exdata.ux_mag);
+fprintf(stderr, "text: %o %o", hdr.a_text, u.u_exdata.ux_tsize);
+fprintf(stderr, "data: %o %o", hdr.a_data, u.u_exdata.ux_dsize);
+fprintf(stderr, "entry: %o %o", hdr.a_entry, u.u_exdata.ux_entloc);
+ exit(1);
+ }
+
+ printf("Data segment size was %u", hdr.a_data);
+ hdr.a_data = ctob(u.u_dsize);
+ hdr.a_bss = 0; /* all data is inited now! */
+ printf(" now is %u\n", hdr.a_data);
+ if (fwrite(&hdr, sizeof hdr, 1, new) != 1)
+ {
+ perror("Couldn't write header to new a.out file");
+ exit(1);
+ }
+}
+
+/*
+ * Copy the text from the a.out to the new a.out
+ */
+copy_text(new, a_out)
+FILE *new, *a_out;
+{
+ char page[PSIZE];
+ int txtcnt = hdr.a_text;
+
+ fseek(new, N_TXTOFF(hdr), 0);
+ fseek(a_out, N_TXTOFF(hdr), 0);
+ if (hdr.a_magic == OMAGIC)
+ {
+ printf("a.out file is not shared text, getting text from core file\n");
+ fseek(a_out, hdr.a_text, 1); /* skip over text */
+ return;
+ }
+ while (txtcnt >= PSIZE)
+ {
+ if (fread(page, PSIZE, 1, a_out) != 1)
+ {
+ perror("Read failure on a.out text");
+ exit(1);
+ }
+ if (fwrite(page, PSIZE, 1, new) != 1)
+ {
+ perror("Write failure in text segment");
+ exit(1);
+ }
+ txtcnt -= PSIZE;
+ }
+ if (txtcnt)
+ {
+ if (fread(page, txtcnt, 1, a_out) != 1)
+ {
+ perror("Read failure on a.out text");
+ exit(1);
+ }
+ if (fwrite(page, txtcnt, 1, new) != 1)
+ {
+ perror("Write failure in text segment");
+ exit(1);
+ }
+ }
+}
+
+/*
+ * copy the data from the core file to the new a.out
+ */
+copy_data(new, core)
+FILE *new, *core;
+{
+ char page[PSIZE];
+ int datacnt = ctob(u.u_dsize);
+
+ if (hdr.a_magic == OMAGIC)
+ datacnt += u.u_tsize;
+ fseek(core, ctob(UPAGES), 0);
+ while (datacnt >= PSIZE)
+ {
+ if (fread(page, PSIZE, 1, core) != 1)
+ {
+ perror("Read failure on core data");
+ exit(1);
+ }
+ if (fwrite(page, PSIZE, 1, new) != 1)
+ {
+ perror("Write failure in data segment");
+ exit(1);
+ }
+ datacnt -= PSIZE;
+ }
+ if (datacnt)
+ {
+ if (fread(page, datacnt, 1, core) != 1)
+ {
+ perror("Read failure on core data");
+ exit(1);
+ }
+ if (fwrite(page, datacnt, 1, new) != 1)
+ {
+ perror("Write failure in data segment");
+ exit(1);
+ }
+ }
+}
+
+/*
+ * Copy the relocation information and symbol table from the a.out to the new
+ */
+copy_sym(new, a_out)
+FILE *new, *a_out;
+{
+ char page[PSIZE];
+ int n;
+
+ fseek(a_out, ohdr.a_data, 1); /* skip over data segment */
+ while ((n = fread(page, 1, PSIZE, a_out)) > 0)
+ {
+ if (fwrite(page, 1, n, new) != n)
+ {
+ perror("Error writing symbol table to new a.out");
+ fprintf(stderr, "new a.out should be ok otherwise\n");
+ return;
+ }
+ }
+ if (n < 0)
+ {
+ perror("Error reading symbol table from a.out");
+ fprintf(stderr, "new a.out should be ok otherwise\n");
+ }
+}
+
+/*
+ * After succesfully building the new a.out, mark it executable
+ */
+mark_x(name)
+char *name;
+{
+ struct stat sbuf;
+ int um;
+
+ um = umask(777);
+ umask(um);
+ if (stat(name, &sbuf) == -1)
+ {
+ perror ("Can't stat new a.out");
+ fprintf(stderr, "Setting protection to %o\n", 0777 & ~um);
+ sbuf.st_mode = 0777;
+ }
+ sbuf.st_mode |= 0111 & ~um;
+ if (chmod(name, sbuf.st_mode) == -1)
+ perror("Couldn't change mode of new a.out to executable");
+
+}
+
diff --git a/obsolete/support/undump/undump.SUN4.c b/obsolete/support/undump/undump.SUN4.c
new file mode 100644
index 0000000000..fa518f733b
--- /dev/null
+++ b/obsolete/support/undump/undump.SUN4.c
@@ -0,0 +1,367 @@
+/*
+ * This program was advertised on unix-wizards. I have had such a large
+ * response I'm sending it out to the world.
+ *
+ * Here is the source. It works fine under 4.1bsd, I see no fundamental
+ * reason why it shouldn't work on an 11. (Except possibly small format
+ * changes in exec header or user structure.) No documentation yet.
+ * Usage is
+ * undump new-a.out-file [old-a.out-file] [core-file]
+ * where old-a.out-file and core-file default to "a.out" and "core",
+ * respectively. Probably should have an option to not require
+ * old-a.out-file if the core came from a 407 file.
+ *
+ * It doesn't preserve open files, and the program is re-entered at main
+ * when you run it. It's used locally to dump a lisp and restart it.
+ *
+ * Other versions of this program required a local subroutine called
+ * scanargs, which has been eliminated in the SUN4 version.
+ */
+
+
+/*
+ * Barry Shein (BZS@BU-CS.CSNET) - Add SUN/3 changes, tried and
+ * worked on TeX but not certain about OMAGIC files. Build it
+ * on a SUN/3 with -Dsun3 on the command line. (1/26/86)
+ *
+ *
+ * This version has applied the patch for a SUN4 contributed by
+ * Christopher A. Welty (weltyc@nisc.nyser.net).
+ * It has not been tested, and I do not know what the effect of
+ * the "#ifdef sun3" lines will be.
+ *
+ * Christopher Welty describes the patch as follows,
+ *
+ * Here is the quick hack to the SUN 3 undump that I made. The problem is
+ * that scanargs doesn't use varargs (the Other Unix Text Formatter is
+ * full of problems like this :-) so I just used brute force...
+ *
+ */
+
+/*
+ * undump.c - Convert a core file to an a.out.
+ *
+ * Author: Spencer W. Thomas
+ * Computer Science Dept.
+ * University of Utah
+ * Date: Wed Feb 17 1982
+ * Copyright (c) 1982 Spencer W. Thomas
+ *
+ * Usage:
+ * undump new-a.out [a.out] [core]
+ */
+
+#include <stdio.h>
+#include <sys/param.h>
+#include <sys/dir.h>
+
+#ifdef sun3
+#include <sys/core.h>
+#include <machine/param.h>
+#else
+#include <sys/user.h>
+#endif
+
+#include <sys/stat.h>
+#include <a.out.h>
+
+#ifdef sun3
+#define PSIZE NBPG
+#else
+#define PSIZE 10240
+#endif sun3
+
+#define TEXITUDE
+
+#ifdef sun3
+struct core c ;
+#else
+struct user u;
+#endif
+
+struct exec hdr, ohdr;
+
+main(argc, argv)
+char **argv;
+{
+ char *new_name, *a_out_name = "a.out", *core_name = "core";
+ FILE *new, *a_out, *core;
+
+ if ( argc < 2 || argc > 4 ) {
+ fprintf(stderr, "usage: %s new-a.out [a.out] [core]\n",argv[0]);
+ exit(1);
+ }
+
+ new_name = argv[1];
+ if ( argc > 2 )
+ a_out_name = argv[2];
+ if ( argc > 3 )
+ core_name = argv[3];
+
+ if ((a_out = fopen(a_out_name, "r")) == NULL)
+ {
+ perror(a_out_name);
+ exit(1);
+ }
+ if ((core = fopen(core_name, "r")) == NULL)
+ {
+ perror(core_name);
+ exit(1);
+ }
+ if ((new = fopen(new_name, "w")) == NULL)
+ {
+ perror(new_name);
+ exit(1);
+ }
+
+#ifdef sun3
+ read_c(core);
+#else
+ read_u(core);
+#endif
+ make_hdr(new, a_out);
+ copy_text(new, a_out);
+ copy_data(new, core);
+ copy_sym(new, a_out);
+ fclose(new);
+ fclose(core);
+ fclose(a_out);
+ mark_x(new_name);
+}
+
+#ifdef sun3
+read_c(core) FILE *core;
+{
+ if(fread(&c, sizeof c, 1, core) != 1) {
+ perror("Couldn't read core header");
+ exit(1);
+ }
+ if(c.c_magic != CORE_MAGIC) {
+ fprintf(stderr,"Not a core file\n");
+ exit(1);
+ }
+}
+
+#else
+/*
+ * read the u structure from the core file.
+ */
+read_u(core)
+FILE *core;
+{
+ if ( fread(&u, sizeof u, 1, core) != 1 )
+ {
+ perror("Couldn't read user structure from core file");
+ exit(1);
+ }
+}
+#endif sun3
+
+/*
+ * Make the header in the new a.out from the header in the old one
+ * modified by the new data size.
+ */
+make_hdr(new, a_out)
+FILE *new, *a_out;
+{
+ if (fread(&hdr, sizeof hdr, 1, a_out) != 1)
+ {
+ perror("Couldn't read header from a.out file");
+ exit(1);
+ }
+ ohdr = hdr;
+ if N_BADMAG(hdr)
+ {
+ fprintf(stderr, "a.out file doesn't have legal magic number\n");
+ exit(1);
+ }
+#ifdef sun3
+ if (hdr.a_magic != c.c_aouthdr.a_magic ||
+ hdr.a_text != c.c_aouthdr.a_text ||
+ hdr.a_data != c.c_aouthdr.a_data ||
+ hdr.a_entry != c.c_aouthdr.a_entry)
+#else
+ if (hdr.a_magic != u.u_exdata.ux_mag ||
+ hdr.a_text != u.u_exdata.ux_tsize ||
+ hdr.a_data != u.u_exdata.ux_dsize ||
+ hdr.a_entry != u.u_exdata.ux_entloc)
+#endif sun3
+ {
+ fprintf(stderr, "Core file didn't come from this a.out\n");
+#ifndef TEXITUDE
+ exit(1);
+#endif
+ }
+
+ printf("Data segment size was %u", hdr.a_data);
+#ifdef sun3
+ hdr.a_data = c.c_dsize;
+#else
+ hdr.a_data = ctob(u.u_dsize);
+#endif sun3
+ hdr.a_bss = 0; /* all data is inited now! */
+ printf(" now is %u\n", hdr.a_data);
+ if (fwrite(&hdr, sizeof hdr, 1, new) != 1)
+ {
+ perror("Couldn't write header to new a.out file");
+ exit(1);
+ }
+}
+
+/*
+ * Copy the text from the a.out to the new a.out
+ */
+copy_text(new, a_out)
+FILE *new, *a_out;
+{
+ char page[PSIZE];
+ int txtcnt = hdr.a_text;
+
+#ifdef sun3
+ fseek(new,(long) N_TXTOFF(hdr)+sizeof(hdr),0);
+ fseek(a_out,(long) N_TXTOFF(hdr)+sizeof(hdr),0);
+ txtcnt -= sizeof(hdr);
+#else
+ fseek(new, N_TXTOFF(hdr), 0);
+ fseek(a_out, N_TXTOFF(hdr), 0);
+#endif sun3
+ if (hdr.a_magic == OMAGIC)
+ {
+ printf("a.out file is not shared text, getting text from core file\n");
+ fseek(a_out, hdr.a_text, 1); /* skip over text */
+ return;
+ }
+ while (txtcnt >= PSIZE)
+ {
+ if (fread(page, PSIZE, 1, a_out) != 1)
+ {
+ perror("Read failure on a.out text");
+ exit(1);
+ }
+ if (fwrite(page, PSIZE, 1, new) != 1)
+ {
+ perror("Write failure in text segment");
+ exit(1);
+ }
+ txtcnt -= PSIZE;
+ }
+ if (txtcnt)
+ {
+ if (fread(page, txtcnt, 1, a_out) != 1)
+ {
+ perror("Read failure on a.out text");
+ exit(1);
+ }
+ if (fwrite(page, txtcnt, 1, new) != 1)
+ {
+ perror("Write failure in text segment");
+ exit(1);
+ }
+ }
+}
+
+/*
+ * copy the data from the core file to the new a.out
+ */
+copy_data(new, core)
+FILE *new, *core;
+{
+ char page[PSIZE];
+#ifdef sun3
+ int datacnt = c.c_dsize;
+#else
+ int datacnt = ctob(u.u_dsize);
+#endif sun3
+
+ if (hdr.a_magic == OMAGIC)
+#ifdef sun3
+ datacnt += c.c_tsize; /* BZS - not sure about this */
+#else
+ datacnt += u.u_tsize;
+#endif
+
+#ifndef sun3 /* for the sun3 the data should be right where we left off */
+ fseek(core, ctob(UPAGES), 0);
+#endif
+ while (datacnt >= PSIZE)
+ {
+ if (fread(page, PSIZE, 1, core) != 1)
+ {
+ perror("Read failure on core data");
+ exit(1);
+ }
+ if (fwrite(page, PSIZE, 1, new) != 1)
+ {
+ perror("Write failure in data segment");
+ exit(1);
+ }
+ datacnt -= PSIZE;
+ }
+ if (datacnt)
+ {
+ if (fread(page, datacnt, 1, core) != 1)
+ {
+ perror("Read failure on core data");
+ exit(1);
+ }
+ if (fwrite(page, datacnt, 1, new) != 1)
+ {
+ perror("Write failure in data segment");
+ exit(1);
+ }
+ }
+}
+
+/*
+ * Copy the relocation information and symbol table from the a.out to the new
+ */
+copy_sym(new, a_out)
+FILE *new, *a_out;
+{
+ char page[PSIZE];
+ int n;
+
+#ifdef sun3
+ fseek(a_out, N_SYMOFF(ohdr), 0);
+#else
+ fseek(a_out, ohdr.a_data, 1); /* skip over data segment */
+#endif sun3
+ while ((n = fread(page, 1, PSIZE, a_out)) > 0)
+ {
+ if (fwrite(page, 1, n, new) != n)
+ {
+ perror("Error writing symbol table to new a.out");
+ fprintf(stderr, "new a.out should be ok otherwise\n");
+ return;
+ }
+ }
+ if (n < 0)
+ {
+ perror("Error reading symbol table from a.out");
+ fprintf(stderr, "new a.out should be ok otherwise\n");
+ }
+}
+
+/*
+ * After succesfully building the new a.out, mark it executable
+ */
+mark_x(name)
+char *name;
+{
+ struct stat sbuf;
+ int um;
+
+ um = umask(777);
+ umask(um);
+ if (stat(name, &sbuf) == -1)
+ {
+ perror ("Can't stat new a.out");
+ fprintf(stderr, "Setting protection to %o\n", 0777 & ~um);
+ sbuf.st_mode = 0777;
+ }
+ sbuf.st_mode |= 0111 & ~um;
+ if (chmod(name, sbuf.st_mode) == -1)
+ perror("Couldn't change mode of new a.out to executable");
+
+}
+
diff --git a/obsolete/support/undump/undump.SUN_V2.c b/obsolete/support/undump/undump.SUN_V2.c
new file mode 100644
index 0000000000..ebff8a31f7
--- /dev/null
+++ b/obsolete/support/undump/undump.SUN_V2.c
@@ -0,0 +1,352 @@
+/*
+ * This program was advertised on unix-wizards. I have had such a large
+ * response I'm sending it out to the world.
+ *
+ * Here is the source. It works fine under 4.1bsd, I see no fundamental
+ * reason why it shouldn't work on an 11. (Except possibly small format
+ * changes in exec header or user structure.) No documentation yet.
+ * Usage is
+ * undump new-a.out-file [old-a.out-file] [core-file]
+ * where old-a.out-file and core-file default to "a.out" and "core",
+ * respectively. Probably should have an option to not require
+ * old-a.out-file if the core came from a 407 file.
+ *
+ * It doesn't preserve open files, and the program is re-entered at main
+ * when you run it. It's used locally to dump a lisp and restart it.
+ *
+ * It requires a local subroutine called scanargs, somewhat similar to
+ * getopt (I think). You should be able to easily get around this, though.
+ * =Spencer
+ */
+
+
+/*
+ * Barry Shein (BZS@BU-CS.CSNET) - Add SUN/3 changes, tried and
+ * worked on TeX but not certain about OMAGIC files. Build it
+ * on a SUN/3 with -Dsun3 on the command line. (1/26/86)
+ *
+ *
+ * Believed to work on a Sun2 with O.S. 3.2 as well. If it
+ * doesn't, try the 4.2undump.c (P. A. MacKay. (2/23/86)
+ */
+/*
+ * undump.c - Convert a core file to an a.out.
+ *
+ * Author: Spencer W. Thomas
+ * Computer Science Dept.
+ * University of Utah
+ * Date: Wed Feb 17 1982
+ * Copyright (c) 1982 Spencer W. Thomas
+ *
+ * Usage:
+ * undump new-a.out [a.out] [core]
+ */
+
+#include <stdio.h>
+#include <sys/param.h>
+#include <sys/dir.h>
+
+#ifdef sun3
+#include <sys/core.h>
+#include <machine/param.h>
+#else
+#include <sys/user.h>
+#endif
+
+#include <sys/stat.h>
+#include <a.out.h>
+
+#ifdef sun3
+#define PSIZE NBPG
+#else
+#define PSIZE 10240
+#endif sun3
+
+#define TEXITUDE
+
+#ifdef sun3
+struct core c ;
+#else
+struct user u;
+#endif
+
+struct exec hdr, ohdr;
+
+main(argc, argv)
+char **argv;
+{
+ char *new_name, *a_out_name = "a.out", *core_name = "core";
+ FILE *new, *a_out, *core;
+
+ if (scanargs(argc, argv, "undump new-a.out!s a.out%s core%s",
+ &new_name, &a_out_name, &core_name)
+ != 1)
+ exit(1);
+
+ if ((a_out = fopen(a_out_name, "r")) == NULL)
+ {
+ perror(a_out_name);
+ exit(1);
+ }
+ if ((core = fopen(core_name, "r")) == NULL)
+ {
+ perror(core_name);
+ exit(1);
+ }
+ if ((new = fopen(new_name, "w")) == NULL)
+ {
+ perror(new_name);
+ exit(1);
+ }
+
+#ifdef sun3
+ read_c(core);
+#else
+ read_u(core);
+#endif
+ make_hdr(new, a_out);
+ copy_text(new, a_out);
+ copy_data(new, core);
+ copy_sym(new, a_out);
+ fclose(new);
+ fclose(core);
+ fclose(a_out);
+ mark_x(new_name);
+}
+
+#ifdef sun3
+read_c(core) FILE *core;
+{
+ if(fread(&c, sizeof c, 1, core) != 1) {
+ perror("Couldn't read core header");
+ exit(1);
+ }
+ if(c.c_magic != CORE_MAGIC) {
+ fprintf(stderr,"Not a core file\n");
+ exit(1);
+ }
+}
+
+#else
+/*
+ * read the u structure from the core file.
+ */
+read_u(core)
+FILE *core;
+{
+ if ( fread(&u, sizeof u, 1, core) != 1 )
+ {
+ perror("Couldn't read user structure from core file");
+ exit(1);
+ }
+}
+#endif sun3
+
+/*
+ * Make the header in the new a.out from the header in the old one
+ * modified by the new data size.
+ */
+make_hdr(new, a_out)
+FILE *new, *a_out;
+{
+ if (fread(&hdr, sizeof hdr, 1, a_out) != 1)
+ {
+ perror("Couldn't read header from a.out file");
+ exit(1);
+ }
+ ohdr = hdr;
+ if N_BADMAG(hdr)
+ {
+ fprintf(stderr, "a.out file doesn't have legal magic number\n");
+ exit(1);
+ }
+#ifdef sun3
+ if (hdr.a_magic != c.c_aouthdr.a_magic ||
+ hdr.a_text != c.c_aouthdr.a_text ||
+ hdr.a_data != c.c_aouthdr.a_data ||
+ hdr.a_entry != c.c_aouthdr.a_entry)
+#else
+ if (hdr.a_magic != u.u_exdata.ux_mag ||
+ hdr.a_text != u.u_exdata.ux_tsize ||
+ hdr.a_data != u.u_exdata.ux_dsize ||
+ hdr.a_entry != u.u_exdata.ux_entloc)
+#endif sun3
+ {
+ fprintf(stderr, "Core file didn't come from this a.out\n");
+#ifndef TEXITUDE
+ exit(1);
+#endif
+ }
+
+ printf("Data segment size was %u", hdr.a_data);
+#ifdef sun3
+ hdr.a_data = c.c_dsize;
+#else
+ hdr.a_data = ctob(u.u_dsize);
+#endif sun3
+ hdr.a_bss = 0; /* all data is inited now! */
+ printf(" now is %u\n", hdr.a_data);
+ if (fwrite(&hdr, sizeof hdr, 1, new) != 1)
+ {
+ perror("Couldn't write header to new a.out file");
+ exit(1);
+ }
+}
+
+/*
+ * Copy the text from the a.out to the new a.out
+ */
+copy_text(new, a_out)
+FILE *new, *a_out;
+{
+ char page[PSIZE];
+ int txtcnt = hdr.a_text;
+
+#ifdef sun3
+ fseek(new,(long) N_TXTOFF(hdr)+sizeof(hdr),0);
+ fseek(a_out,(long) N_TXTOFF(hdr)+sizeof(hdr),0);
+ txtcnt -= sizeof(hdr);
+#else
+ fseek(new, N_TXTOFF(hdr), 0);
+ fseek(a_out, N_TXTOFF(hdr), 0);
+#endif sun3
+ if (hdr.a_magic == OMAGIC)
+ {
+ printf("a.out file is not shared text, getting text from core file\n");
+ fseek(a_out, hdr.a_text, 1); /* skip over text */
+ return;
+ }
+ while (txtcnt >= PSIZE)
+ {
+ if (fread(page, PSIZE, 1, a_out) != 1)
+ {
+ perror("Read failure on a.out text");
+ exit(1);
+ }
+ if (fwrite(page, PSIZE, 1, new) != 1)
+ {
+ perror("Write failure in text segment");
+ exit(1);
+ }
+ txtcnt -= PSIZE;
+ }
+ if (txtcnt)
+ {
+ if (fread(page, txtcnt, 1, a_out) != 1)
+ {
+ perror("Read failure on a.out text");
+ exit(1);
+ }
+ if (fwrite(page, txtcnt, 1, new) != 1)
+ {
+ perror("Write failure in text segment");
+ exit(1);
+ }
+ }
+}
+
+/*
+ * copy the data from the core file to the new a.out
+ */
+copy_data(new, core)
+FILE *new, *core;
+{
+ char page[PSIZE];
+#ifdef sun3
+ int datacnt = c.c_dsize;
+#else
+ int datacnt = ctob(u.u_dsize);
+#endif sun3
+
+ if (hdr.a_magic == OMAGIC)
+#ifdef sun3
+ datacnt += c.c_tsize; /* BZS - not sure about this */
+#else
+ datacnt += u.u_tsize;
+#endif
+
+#ifndef sun3 /* for the sun3 the data should be right where we left off */
+ fseek(core, ctob(UPAGES), 0);
+#endif
+ while (datacnt >= PSIZE)
+ {
+ if (fread(page, PSIZE, 1, core) != 1)
+ {
+ perror("Read failure on core data");
+ exit(1);
+ }
+ if (fwrite(page, PSIZE, 1, new) != 1)
+ {
+ perror("Write failure in data segment");
+ exit(1);
+ }
+ datacnt -= PSIZE;
+ }
+ if (datacnt)
+ {
+ if (fread(page, datacnt, 1, core) != 1)
+ {
+ perror("Read failure on core data");
+ exit(1);
+ }
+ if (fwrite(page, datacnt, 1, new) != 1)
+ {
+ perror("Write failure in data segment");
+ exit(1);
+ }
+ }
+}
+
+/*
+ * Copy the relocation information and symbol table from the a.out to the new
+ */
+copy_sym(new, a_out)
+FILE *new, *a_out;
+{
+ char page[PSIZE];
+ int n;
+
+#ifdef sun3
+ fseek(a_out, N_SYMOFF(ohdr), 0);
+#else
+ fseek(a_out, ohdr.a_data, 1); /* skip over data segment */
+#endif sun3
+ while ((n = fread(page, 1, PSIZE, a_out)) > 0)
+ {
+ if (fwrite(page, 1, n, new) != n)
+ {
+ perror("Error writing symbol table to new a.out");
+ fprintf(stderr, "new a.out should be ok otherwise\n");
+ return;
+ }
+ }
+ if (n < 0)
+ {
+ perror("Error reading symbol table from a.out");
+ fprintf(stderr, "new a.out should be ok otherwise\n");
+ }
+}
+
+/*
+ * After succesfully building the new a.out, mark it executable
+ */
+mark_x(name)
+char *name;
+{
+ struct stat sbuf;
+ int um;
+
+ um = umask(777);
+ umask(um);
+ if (stat(name, &sbuf) == -1)
+ {
+ perror ("Can't stat new a.out");
+ fprintf(stderr, "Setting protection to %o\n", 0777 & ~um);
+ sbuf.st_mode = 0777;
+ }
+ sbuf.st_mode |= 0111 & ~um;
+ if (chmod(name, sbuf.st_mode) == -1)
+ perror("Couldn't change mode of new a.out to executable");
+
+}
+
diff --git a/obsolete/support/undump/undump.SUN_V3 b/obsolete/support/undump/undump.SUN_V3
new file mode 100644
index 0000000000..ebff8a31f7
--- /dev/null
+++ b/obsolete/support/undump/undump.SUN_V3
@@ -0,0 +1,352 @@
+/*
+ * This program was advertised on unix-wizards. I have had such a large
+ * response I'm sending it out to the world.
+ *
+ * Here is the source. It works fine under 4.1bsd, I see no fundamental
+ * reason why it shouldn't work on an 11. (Except possibly small format
+ * changes in exec header or user structure.) No documentation yet.
+ * Usage is
+ * undump new-a.out-file [old-a.out-file] [core-file]
+ * where old-a.out-file and core-file default to "a.out" and "core",
+ * respectively. Probably should have an option to not require
+ * old-a.out-file if the core came from a 407 file.
+ *
+ * It doesn't preserve open files, and the program is re-entered at main
+ * when you run it. It's used locally to dump a lisp and restart it.
+ *
+ * It requires a local subroutine called scanargs, somewhat similar to
+ * getopt (I think). You should be able to easily get around this, though.
+ * =Spencer
+ */
+
+
+/*
+ * Barry Shein (BZS@BU-CS.CSNET) - Add SUN/3 changes, tried and
+ * worked on TeX but not certain about OMAGIC files. Build it
+ * on a SUN/3 with -Dsun3 on the command line. (1/26/86)
+ *
+ *
+ * Believed to work on a Sun2 with O.S. 3.2 as well. If it
+ * doesn't, try the 4.2undump.c (P. A. MacKay. (2/23/86)
+ */
+/*
+ * undump.c - Convert a core file to an a.out.
+ *
+ * Author: Spencer W. Thomas
+ * Computer Science Dept.
+ * University of Utah
+ * Date: Wed Feb 17 1982
+ * Copyright (c) 1982 Spencer W. Thomas
+ *
+ * Usage:
+ * undump new-a.out [a.out] [core]
+ */
+
+#include <stdio.h>
+#include <sys/param.h>
+#include <sys/dir.h>
+
+#ifdef sun3
+#include <sys/core.h>
+#include <machine/param.h>
+#else
+#include <sys/user.h>
+#endif
+
+#include <sys/stat.h>
+#include <a.out.h>
+
+#ifdef sun3
+#define PSIZE NBPG
+#else
+#define PSIZE 10240
+#endif sun3
+
+#define TEXITUDE
+
+#ifdef sun3
+struct core c ;
+#else
+struct user u;
+#endif
+
+struct exec hdr, ohdr;
+
+main(argc, argv)
+char **argv;
+{
+ char *new_name, *a_out_name = "a.out", *core_name = "core";
+ FILE *new, *a_out, *core;
+
+ if (scanargs(argc, argv, "undump new-a.out!s a.out%s core%s",
+ &new_name, &a_out_name, &core_name)
+ != 1)
+ exit(1);
+
+ if ((a_out = fopen(a_out_name, "r")) == NULL)
+ {
+ perror(a_out_name);
+ exit(1);
+ }
+ if ((core = fopen(core_name, "r")) == NULL)
+ {
+ perror(core_name);
+ exit(1);
+ }
+ if ((new = fopen(new_name, "w")) == NULL)
+ {
+ perror(new_name);
+ exit(1);
+ }
+
+#ifdef sun3
+ read_c(core);
+#else
+ read_u(core);
+#endif
+ make_hdr(new, a_out);
+ copy_text(new, a_out);
+ copy_data(new, core);
+ copy_sym(new, a_out);
+ fclose(new);
+ fclose(core);
+ fclose(a_out);
+ mark_x(new_name);
+}
+
+#ifdef sun3
+read_c(core) FILE *core;
+{
+ if(fread(&c, sizeof c, 1, core) != 1) {
+ perror("Couldn't read core header");
+ exit(1);
+ }
+ if(c.c_magic != CORE_MAGIC) {
+ fprintf(stderr,"Not a core file\n");
+ exit(1);
+ }
+}
+
+#else
+/*
+ * read the u structure from the core file.
+ */
+read_u(core)
+FILE *core;
+{
+ if ( fread(&u, sizeof u, 1, core) != 1 )
+ {
+ perror("Couldn't read user structure from core file");
+ exit(1);
+ }
+}
+#endif sun3
+
+/*
+ * Make the header in the new a.out from the header in the old one
+ * modified by the new data size.
+ */
+make_hdr(new, a_out)
+FILE *new, *a_out;
+{
+ if (fread(&hdr, sizeof hdr, 1, a_out) != 1)
+ {
+ perror("Couldn't read header from a.out file");
+ exit(1);
+ }
+ ohdr = hdr;
+ if N_BADMAG(hdr)
+ {
+ fprintf(stderr, "a.out file doesn't have legal magic number\n");
+ exit(1);
+ }
+#ifdef sun3
+ if (hdr.a_magic != c.c_aouthdr.a_magic ||
+ hdr.a_text != c.c_aouthdr.a_text ||
+ hdr.a_data != c.c_aouthdr.a_data ||
+ hdr.a_entry != c.c_aouthdr.a_entry)
+#else
+ if (hdr.a_magic != u.u_exdata.ux_mag ||
+ hdr.a_text != u.u_exdata.ux_tsize ||
+ hdr.a_data != u.u_exdata.ux_dsize ||
+ hdr.a_entry != u.u_exdata.ux_entloc)
+#endif sun3
+ {
+ fprintf(stderr, "Core file didn't come from this a.out\n");
+#ifndef TEXITUDE
+ exit(1);
+#endif
+ }
+
+ printf("Data segment size was %u", hdr.a_data);
+#ifdef sun3
+ hdr.a_data = c.c_dsize;
+#else
+ hdr.a_data = ctob(u.u_dsize);
+#endif sun3
+ hdr.a_bss = 0; /* all data is inited now! */
+ printf(" now is %u\n", hdr.a_data);
+ if (fwrite(&hdr, sizeof hdr, 1, new) != 1)
+ {
+ perror("Couldn't write header to new a.out file");
+ exit(1);
+ }
+}
+
+/*
+ * Copy the text from the a.out to the new a.out
+ */
+copy_text(new, a_out)
+FILE *new, *a_out;
+{
+ char page[PSIZE];
+ int txtcnt = hdr.a_text;
+
+#ifdef sun3
+ fseek(new,(long) N_TXTOFF(hdr)+sizeof(hdr),0);
+ fseek(a_out,(long) N_TXTOFF(hdr)+sizeof(hdr),0);
+ txtcnt -= sizeof(hdr);
+#else
+ fseek(new, N_TXTOFF(hdr), 0);
+ fseek(a_out, N_TXTOFF(hdr), 0);
+#endif sun3
+ if (hdr.a_magic == OMAGIC)
+ {
+ printf("a.out file is not shared text, getting text from core file\n");
+ fseek(a_out, hdr.a_text, 1); /* skip over text */
+ return;
+ }
+ while (txtcnt >= PSIZE)
+ {
+ if (fread(page, PSIZE, 1, a_out) != 1)
+ {
+ perror("Read failure on a.out text");
+ exit(1);
+ }
+ if (fwrite(page, PSIZE, 1, new) != 1)
+ {
+ perror("Write failure in text segment");
+ exit(1);
+ }
+ txtcnt -= PSIZE;
+ }
+ if (txtcnt)
+ {
+ if (fread(page, txtcnt, 1, a_out) != 1)
+ {
+ perror("Read failure on a.out text");
+ exit(1);
+ }
+ if (fwrite(page, txtcnt, 1, new) != 1)
+ {
+ perror("Write failure in text segment");
+ exit(1);
+ }
+ }
+}
+
+/*
+ * copy the data from the core file to the new a.out
+ */
+copy_data(new, core)
+FILE *new, *core;
+{
+ char page[PSIZE];
+#ifdef sun3
+ int datacnt = c.c_dsize;
+#else
+ int datacnt = ctob(u.u_dsize);
+#endif sun3
+
+ if (hdr.a_magic == OMAGIC)
+#ifdef sun3
+ datacnt += c.c_tsize; /* BZS - not sure about this */
+#else
+ datacnt += u.u_tsize;
+#endif
+
+#ifndef sun3 /* for the sun3 the data should be right where we left off */
+ fseek(core, ctob(UPAGES), 0);
+#endif
+ while (datacnt >= PSIZE)
+ {
+ if (fread(page, PSIZE, 1, core) != 1)
+ {
+ perror("Read failure on core data");
+ exit(1);
+ }
+ if (fwrite(page, PSIZE, 1, new) != 1)
+ {
+ perror("Write failure in data segment");
+ exit(1);
+ }
+ datacnt -= PSIZE;
+ }
+ if (datacnt)
+ {
+ if (fread(page, datacnt, 1, core) != 1)
+ {
+ perror("Read failure on core data");
+ exit(1);
+ }
+ if (fwrite(page, datacnt, 1, new) != 1)
+ {
+ perror("Write failure in data segment");
+ exit(1);
+ }
+ }
+}
+
+/*
+ * Copy the relocation information and symbol table from the a.out to the new
+ */
+copy_sym(new, a_out)
+FILE *new, *a_out;
+{
+ char page[PSIZE];
+ int n;
+
+#ifdef sun3
+ fseek(a_out, N_SYMOFF(ohdr), 0);
+#else
+ fseek(a_out, ohdr.a_data, 1); /* skip over data segment */
+#endif sun3
+ while ((n = fread(page, 1, PSIZE, a_out)) > 0)
+ {
+ if (fwrite(page, 1, n, new) != n)
+ {
+ perror("Error writing symbol table to new a.out");
+ fprintf(stderr, "new a.out should be ok otherwise\n");
+ return;
+ }
+ }
+ if (n < 0)
+ {
+ perror("Error reading symbol table from a.out");
+ fprintf(stderr, "new a.out should be ok otherwise\n");
+ }
+}
+
+/*
+ * After succesfully building the new a.out, mark it executable
+ */
+mark_x(name)
+char *name;
+{
+ struct stat sbuf;
+ int um;
+
+ um = umask(777);
+ umask(um);
+ if (stat(name, &sbuf) == -1)
+ {
+ perror ("Can't stat new a.out");
+ fprintf(stderr, "Setting protection to %o\n", 0777 & ~um);
+ sbuf.st_mode = 0777;
+ }
+ sbuf.st_mode |= 0111 & ~um;
+ if (chmod(name, sbuf.st_mode) == -1)
+ perror("Couldn't change mode of new a.out to executable");
+
+}
+
diff --git a/obsolete/support/undump/undump.SUN_V3.c b/obsolete/support/undump/undump.SUN_V3.c
new file mode 100644
index 0000000000..ebff8a31f7
--- /dev/null
+++ b/obsolete/support/undump/undump.SUN_V3.c
@@ -0,0 +1,352 @@
+/*
+ * This program was advertised on unix-wizards. I have had such a large
+ * response I'm sending it out to the world.
+ *
+ * Here is the source. It works fine under 4.1bsd, I see no fundamental
+ * reason why it shouldn't work on an 11. (Except possibly small format
+ * changes in exec header or user structure.) No documentation yet.
+ * Usage is
+ * undump new-a.out-file [old-a.out-file] [core-file]
+ * where old-a.out-file and core-file default to "a.out" and "core",
+ * respectively. Probably should have an option to not require
+ * old-a.out-file if the core came from a 407 file.
+ *
+ * It doesn't preserve open files, and the program is re-entered at main
+ * when you run it. It's used locally to dump a lisp and restart it.
+ *
+ * It requires a local subroutine called scanargs, somewhat similar to
+ * getopt (I think). You should be able to easily get around this, though.
+ * =Spencer
+ */
+
+
+/*
+ * Barry Shein (BZS@BU-CS.CSNET) - Add SUN/3 changes, tried and
+ * worked on TeX but not certain about OMAGIC files. Build it
+ * on a SUN/3 with -Dsun3 on the command line. (1/26/86)
+ *
+ *
+ * Believed to work on a Sun2 with O.S. 3.2 as well. If it
+ * doesn't, try the 4.2undump.c (P. A. MacKay. (2/23/86)
+ */
+/*
+ * undump.c - Convert a core file to an a.out.
+ *
+ * Author: Spencer W. Thomas
+ * Computer Science Dept.
+ * University of Utah
+ * Date: Wed Feb 17 1982
+ * Copyright (c) 1982 Spencer W. Thomas
+ *
+ * Usage:
+ * undump new-a.out [a.out] [core]
+ */
+
+#include <stdio.h>
+#include <sys/param.h>
+#include <sys/dir.h>
+
+#ifdef sun3
+#include <sys/core.h>
+#include <machine/param.h>
+#else
+#include <sys/user.h>
+#endif
+
+#include <sys/stat.h>
+#include <a.out.h>
+
+#ifdef sun3
+#define PSIZE NBPG
+#else
+#define PSIZE 10240
+#endif sun3
+
+#define TEXITUDE
+
+#ifdef sun3
+struct core c ;
+#else
+struct user u;
+#endif
+
+struct exec hdr, ohdr;
+
+main(argc, argv)
+char **argv;
+{
+ char *new_name, *a_out_name = "a.out", *core_name = "core";
+ FILE *new, *a_out, *core;
+
+ if (scanargs(argc, argv, "undump new-a.out!s a.out%s core%s",
+ &new_name, &a_out_name, &core_name)
+ != 1)
+ exit(1);
+
+ if ((a_out = fopen(a_out_name, "r")) == NULL)
+ {
+ perror(a_out_name);
+ exit(1);
+ }
+ if ((core = fopen(core_name, "r")) == NULL)
+ {
+ perror(core_name);
+ exit(1);
+ }
+ if ((new = fopen(new_name, "w")) == NULL)
+ {
+ perror(new_name);
+ exit(1);
+ }
+
+#ifdef sun3
+ read_c(core);
+#else
+ read_u(core);
+#endif
+ make_hdr(new, a_out);
+ copy_text(new, a_out);
+ copy_data(new, core);
+ copy_sym(new, a_out);
+ fclose(new);
+ fclose(core);
+ fclose(a_out);
+ mark_x(new_name);
+}
+
+#ifdef sun3
+read_c(core) FILE *core;
+{
+ if(fread(&c, sizeof c, 1, core) != 1) {
+ perror("Couldn't read core header");
+ exit(1);
+ }
+ if(c.c_magic != CORE_MAGIC) {
+ fprintf(stderr,"Not a core file\n");
+ exit(1);
+ }
+}
+
+#else
+/*
+ * read the u structure from the core file.
+ */
+read_u(core)
+FILE *core;
+{
+ if ( fread(&u, sizeof u, 1, core) != 1 )
+ {
+ perror("Couldn't read user structure from core file");
+ exit(1);
+ }
+}
+#endif sun3
+
+/*
+ * Make the header in the new a.out from the header in the old one
+ * modified by the new data size.
+ */
+make_hdr(new, a_out)
+FILE *new, *a_out;
+{
+ if (fread(&hdr, sizeof hdr, 1, a_out) != 1)
+ {
+ perror("Couldn't read header from a.out file");
+ exit(1);
+ }
+ ohdr = hdr;
+ if N_BADMAG(hdr)
+ {
+ fprintf(stderr, "a.out file doesn't have legal magic number\n");
+ exit(1);
+ }
+#ifdef sun3
+ if (hdr.a_magic != c.c_aouthdr.a_magic ||
+ hdr.a_text != c.c_aouthdr.a_text ||
+ hdr.a_data != c.c_aouthdr.a_data ||
+ hdr.a_entry != c.c_aouthdr.a_entry)
+#else
+ if (hdr.a_magic != u.u_exdata.ux_mag ||
+ hdr.a_text != u.u_exdata.ux_tsize ||
+ hdr.a_data != u.u_exdata.ux_dsize ||
+ hdr.a_entry != u.u_exdata.ux_entloc)
+#endif sun3
+ {
+ fprintf(stderr, "Core file didn't come from this a.out\n");
+#ifndef TEXITUDE
+ exit(1);
+#endif
+ }
+
+ printf("Data segment size was %u", hdr.a_data);
+#ifdef sun3
+ hdr.a_data = c.c_dsize;
+#else
+ hdr.a_data = ctob(u.u_dsize);
+#endif sun3
+ hdr.a_bss = 0; /* all data is inited now! */
+ printf(" now is %u\n", hdr.a_data);
+ if (fwrite(&hdr, sizeof hdr, 1, new) != 1)
+ {
+ perror("Couldn't write header to new a.out file");
+ exit(1);
+ }
+}
+
+/*
+ * Copy the text from the a.out to the new a.out
+ */
+copy_text(new, a_out)
+FILE *new, *a_out;
+{
+ char page[PSIZE];
+ int txtcnt = hdr.a_text;
+
+#ifdef sun3
+ fseek(new,(long) N_TXTOFF(hdr)+sizeof(hdr),0);
+ fseek(a_out,(long) N_TXTOFF(hdr)+sizeof(hdr),0);
+ txtcnt -= sizeof(hdr);
+#else
+ fseek(new, N_TXTOFF(hdr), 0);
+ fseek(a_out, N_TXTOFF(hdr), 0);
+#endif sun3
+ if (hdr.a_magic == OMAGIC)
+ {
+ printf("a.out file is not shared text, getting text from core file\n");
+ fseek(a_out, hdr.a_text, 1); /* skip over text */
+ return;
+ }
+ while (txtcnt >= PSIZE)
+ {
+ if (fread(page, PSIZE, 1, a_out) != 1)
+ {
+ perror("Read failure on a.out text");
+ exit(1);
+ }
+ if (fwrite(page, PSIZE, 1, new) != 1)
+ {
+ perror("Write failure in text segment");
+ exit(1);
+ }
+ txtcnt -= PSIZE;
+ }
+ if (txtcnt)
+ {
+ if (fread(page, txtcnt, 1, a_out) != 1)
+ {
+ perror("Read failure on a.out text");
+ exit(1);
+ }
+ if (fwrite(page, txtcnt, 1, new) != 1)
+ {
+ perror("Write failure in text segment");
+ exit(1);
+ }
+ }
+}
+
+/*
+ * copy the data from the core file to the new a.out
+ */
+copy_data(new, core)
+FILE *new, *core;
+{
+ char page[PSIZE];
+#ifdef sun3
+ int datacnt = c.c_dsize;
+#else
+ int datacnt = ctob(u.u_dsize);
+#endif sun3
+
+ if (hdr.a_magic == OMAGIC)
+#ifdef sun3
+ datacnt += c.c_tsize; /* BZS - not sure about this */
+#else
+ datacnt += u.u_tsize;
+#endif
+
+#ifndef sun3 /* for the sun3 the data should be right where we left off */
+ fseek(core, ctob(UPAGES), 0);
+#endif
+ while (datacnt >= PSIZE)
+ {
+ if (fread(page, PSIZE, 1, core) != 1)
+ {
+ perror("Read failure on core data");
+ exit(1);
+ }
+ if (fwrite(page, PSIZE, 1, new) != 1)
+ {
+ perror("Write failure in data segment");
+ exit(1);
+ }
+ datacnt -= PSIZE;
+ }
+ if (datacnt)
+ {
+ if (fread(page, datacnt, 1, core) != 1)
+ {
+ perror("Read failure on core data");
+ exit(1);
+ }
+ if (fwrite(page, datacnt, 1, new) != 1)
+ {
+ perror("Write failure in data segment");
+ exit(1);
+ }
+ }
+}
+
+/*
+ * Copy the relocation information and symbol table from the a.out to the new
+ */
+copy_sym(new, a_out)
+FILE *new, *a_out;
+{
+ char page[PSIZE];
+ int n;
+
+#ifdef sun3
+ fseek(a_out, N_SYMOFF(ohdr), 0);
+#else
+ fseek(a_out, ohdr.a_data, 1); /* skip over data segment */
+#endif sun3
+ while ((n = fread(page, 1, PSIZE, a_out)) > 0)
+ {
+ if (fwrite(page, 1, n, new) != n)
+ {
+ perror("Error writing symbol table to new a.out");
+ fprintf(stderr, "new a.out should be ok otherwise\n");
+ return;
+ }
+ }
+ if (n < 0)
+ {
+ perror("Error reading symbol table from a.out");
+ fprintf(stderr, "new a.out should be ok otherwise\n");
+ }
+}
+
+/*
+ * After succesfully building the new a.out, mark it executable
+ */
+mark_x(name)
+char *name;
+{
+ struct stat sbuf;
+ int um;
+
+ um = umask(777);
+ umask(um);
+ if (stat(name, &sbuf) == -1)
+ {
+ perror ("Can't stat new a.out");
+ fprintf(stderr, "Setting protection to %o\n", 0777 & ~um);
+ sbuf.st_mode = 0777;
+ }
+ sbuf.st_mode |= 0111 & ~um;
+ if (chmod(name, sbuf.st_mode) == -1)
+ perror("Couldn't change mode of new a.out to executable");
+
+}
+
diff --git a/obsolete/support/undump/undump.SYS_V.c b/obsolete/support/undump/undump.SYS_V.c
new file mode 100644
index 0000000000..8d61cb61ee
--- /dev/null
+++ b/obsolete/support/undump/undump.SYS_V.c
@@ -0,0 +1,250 @@
+/*
+ * undump - resurrect a core file into a running program.
+ *
+ * for UNIX System V on a 3Bx
+ * that uses the Common Object File Format
+ *
+ * Author:
+ * Lou Salkind
+ * New York University
+ * Tue Mar 3 13:18:25 EST 1987
+ *
+ * Adapted from:
+ * Spencer Thomas's undump and the file unexec.c in GNU emacs
+ */
+
+#include <sys/param.h>
+#include <sys/types.h>
+#include <sys/psw.h>
+#include <sys/pcb.h>
+#include <sys/signal.h>
+#include <sys/fs/s5dir.h>
+#include <sys/user.h>
+
+#include <stdio.h>
+#include <sys/stat.h>
+
+#include <aouthdr.h>
+#include <filehdr.h>
+#include <scnhdr.h>
+#include <syms.h>
+
+#define PAGE_SIZE NBPC
+
+struct filehdr fh;
+AOUTHDR aout;
+struct scnhdr tsc;
+struct scnhdr dsc;
+struct scnhdr bsc;
+
+long bias;
+long lnnoptr;
+long text_scnptr;
+long data_scnptr;
+long symlocptr;
+
+main(argc, argv)
+ char **argv;
+{
+ FILE *afp, *cfp, *nfp;
+ struct user u;
+ long off;
+ long size;
+ struct scnhdr sc;
+ int i, n;
+ char *a_out_name = "a.out";
+ char *core_name = "core";
+ char *new_name;
+
+ if (argc < 2 || argc > 4) {
+ fprintf(stderr, "usage: %s new [a.out [core]]\n", argv[0]);
+ exit(1);
+ }
+ new_name = argv[1];
+ if (argc > 2)
+ a_out_name = argv[2];
+ if (argc > 3)
+ core_name = argv[3];
+ afp = fopen(a_out_name, "r");
+ if (afp == 0)
+ Perror(a_out_name);
+ cfp = fopen(core_name, "r");
+ if (cfp == 0)
+ Perror(core_name);
+ nfp = fopen(new_name, "w");
+ if (nfp == 0)
+ Perror(new_name);
+
+ if (fread(&fh, sizeof fh, 1, afp) != 1)
+ Perror("fh read");
+ if (fread(&aout, sizeof aout, 1, afp) != 1)
+ Perror("aout read");
+
+ for (i = 0; i < fh.f_nscns; i++) {
+ if (fread(&sc, sizeof(sc), 1, afp) != 1)
+ Perror("read");
+ if (strcmp(sc.s_name, ".text") == 0) {
+ tsc = sc;
+ } else if (strcmp(sc.s_name, ".data") == 0) {
+ dsc = sc;
+ } else if (strcmp(sc.s_name, ".bss") == 0) {
+ bsc = sc;
+ }
+ }
+
+ if (fread(&u, sizeof u, 1, cfp) != 1)
+ Perror("core read");
+ if (u.u_exdata.ux_tsize != aout.tsize ||
+ u.u_exdata.ux_dsize != aout.dsize ||
+ u.u_exdata.ux_bsize != aout.bsize) {
+ fprintf("mismatch between %s and %s sizes\n", a_out_name, core_name);
+ exit(1);
+ }
+
+ off = USIZE*PAGE_SIZE;
+ size = u.u_dsize *PAGE_SIZE;
+
+ fh.f_flags |= F_RELFLG | F_EXEC;
+ aout.dsize = size;
+ aout.bsize = 0;
+ tsc.s_size = aout.tsize;
+ tsc.s_scnptr = sizeof(fh) + sizeof(aout);
+ tsc.s_scnptr += fh.f_nscns * sizeof (struct scnhdr);
+ text_scnptr = tsc.s_scnptr;
+ lnnoptr = tsc.s_lnnoptr;
+ symlocptr = fh.f_symptr;
+
+ dsc.s_paddr = dsc.s_vaddr = aout.data_start;
+ dsc.s_size = aout.dsize;
+ dsc.s_scnptr = tsc.s_scnptr + tsc.s_size;
+ data_scnptr = dsc.s_scnptr;
+
+ bsc.s_paddr = bsc.s_vaddr = aout.data_start + aout.dsize;
+ bsc.s_size = aout.bsize;
+ bsc.s_scnptr = 0L;
+ bias = dsc.s_scnptr + dsc.s_size - lnnoptr;
+
+ if (fh.f_symptr > 0L)
+ fh.f_symptr += bias;
+ if (tsc.s_lnnoptr > 0L)
+ tsc.s_lnnoptr += bias;
+
+ if (fwrite(&fh, sizeof(fh), 1, nfp) != 1)
+ Perror("fh write");
+ if (fwrite(&aout, sizeof(aout), 1, nfp) != 1)
+ Perror("aout write");
+ if (fwrite(&tsc, sizeof(tsc), 1, nfp) != 1)
+ Perror("ts write");
+ if (fwrite(&dsc, sizeof(dsc), 1, nfp) != 1)
+ Perror("ds write");
+ if (fwrite(&bsc, sizeof(bsc), 1, nfp) != 1)
+ Perror("bs write");
+ fseek(nfp, (long)text_scnptr, 0);
+ copy(afp, nfp, aout.tsize);
+ fseek(cfp, off, 0);
+ fseek(nfp, (long)data_scnptr, 0);
+ copy(cfp, nfp, size);
+ copy_syms(afp, nfp);
+ fclose(nfp);
+ fclose(afp);
+ fclose(cfp);
+ mark_x(new_name);
+ exit(0);
+}
+
+copy_syms(afp, nfp)
+ register FILE *afp, *nfp;
+{
+ char page[BUFSIZ];
+ register int n;
+ register int nsyms;
+ struct syment symentry;
+ AUXENT auxentry;
+
+ /* if there are line numbers, copy them */
+ if (lnnoptr) {
+ if (fseek(afp, lnnoptr, 0) == -1L)
+ Perror("ln fseek");
+ copy(afp, nfp, symlocptr - lnnoptr);
+ }
+
+ /* now write the symbol table */
+ if (fseek(nfp, fh.f_symptr, 0) == -1L)
+ Perror("fh fseek");
+ for (nsyms = 0; nsyms < fh.f_nsyms; nsyms++) {
+ if (fread(&symentry, SYMESZ, 1, afp) != 1)
+ Perror("sym fread");
+ if (fwrite(&symentry, SYMESZ, 1, nfp) != 1)
+ Perror("sym fwrite");
+ /*
+ * adjust relative offsets of line numbers for
+ * function definitions
+ */
+ if (symentry.n_numaux) {
+ if (fread(&auxentry, AUXESZ, 1, afp) != 1)
+ Perror("aux fread");
+ nsyms++;
+ if (ISFCN (symentry.n_type))
+ auxentry.x_sym.x_fcnary.x_fcn.x_lnnoptr += bias;
+ if (fwrite(&auxentry, AUXESZ, 1, nfp) != 1)
+ Perror("aux fwrite");
+ }
+ }
+
+ /* finally write the string table, if any */
+ while ((n = fread(page, 1, sizeof page, afp)) > 0) {
+ if (fwrite(page, 1, n, nfp) != n)
+ Perror("sym write");
+ }
+ if (n < 0)
+ Perror("sym read");
+}
+
+/*
+ * After succesfully building the new a.out, mark it executable
+ */
+mark_x(name)
+char *name;
+{
+ struct stat sbuf;
+ int um;
+
+ um = umask(777);
+ umask(um);
+ if (stat(name, &sbuf) == -1)
+ {
+ perror ("Can't stat new a.out");
+ fprintf(stderr, "Setting protection to %o\n", 0777 & ~um);
+ sbuf.st_mode = 0777;
+ }
+ sbuf.st_mode |= 0111 & ~um;
+ if (chmod(name, sbuf.st_mode) == -1)
+ perror("Couldn't change mode of new a.out to executable");
+
+}
+
+copy(a, b, size)
+ register FILE *a, *b;
+ long size;
+{
+ char buf[BUFSIZ];
+ register int i, n;
+
+ while (size > 0) {
+ i = size;
+ if (i > sizeof buf)
+ i = sizeof buf;
+ if ((n = fread(buf, 1, i, a)) <= 0)
+ Perror("copy read");
+ if (fwrite(buf, 1, n, b) != n)
+ Perror("copy write");
+ size -= n;
+ }
+}
+
+Perror(s)
+ char *s;
+{
+ perror(s);
+ exit(1);
+}
diff --git a/obsolete/support/undump/undump.VAX4_2.c b/obsolete/support/undump/undump.VAX4_2.c
new file mode 100644
index 0000000000..f5588abf6e
--- /dev/null
+++ b/obsolete/support/undump/undump.VAX4_2.c
@@ -0,0 +1,272 @@
+/*
+ * This program was advertised on unix-wizards. I have had such a large
+ * response I'm sending it out to the world.
+ *
+ * Here is the source. It works fine under 4.1bsd, I see no fundamental
+ * reason why it shouldn't work on an 11. (Except possibly small format
+ * changes in exec header or user structure.) No documentation yet.
+ * Usage is
+ * undump new-a.out-file [old-a.out-file] [core-file]
+ * where old-a.out-file and core-file default to "a.out" and "core",
+ * respectively. Probably should have an option to not require
+ * old-a.out-file if the core came from a 407 file.
+ *
+ * It doesn't preserve open files, and the program is re-entered at main
+ * when you run it. It's used locally to dump a lisp and restart it.
+ *
+ * It requires a local subroutine called scanargs, somewhat similar to
+ * getopt (I think). You should be able to easily get around this, though.
+ * =Spencer
+ */
+
+
+/*
+ * undump.c - Convert a core file to an a.out.
+ *
+ * Author: Spencer W. Thomas
+ * Computer Science Dept.
+ * University of Utah
+ * Date: Wed Feb 17 1982
+ * Copyright (c) 1982 Spencer W. Thomas
+ *
+ * Usage:
+ * undump new-a.out [a.out] [core]
+ */
+
+#include <stdio.h>
+#include <sys/param.h>
+#include <sys/dir.h>
+#include <sys/user.h>
+#include <sys/stat.h>
+#include <a.out.h>
+
+#define PSIZE 10240
+
+struct user u;
+struct exec hdr, ohdr;
+
+main(argc, argv)
+char **argv;
+{
+ char *new_name, *a_out_name = "a.out", *core_name = "core";
+ FILE *new, *a_out, *core;
+
+ if (scanargs(argc, argv, "undump new-a.out!s a.out%s core%s",
+ &new_name, &a_out_name, &core_name)
+ != 1)
+ exit(1);
+
+ if ((a_out = fopen(a_out_name, "r")) == NULL)
+ {
+ perror(a_out_name);
+ exit(1);
+ }
+ if ((core = fopen(core_name, "r")) == NULL)
+ {
+ perror(core_name);
+ exit(1);
+ }
+ if ((new = fopen(new_name, "w")) == NULL)
+ {
+ perror(new_name);
+ exit(1);
+ }
+
+ read_u(core);
+ make_hdr(new, a_out);
+ copy_text(new, a_out);
+ copy_data(new, core);
+ copy_sym(new, a_out);
+ fclose(new);
+ fclose(core);
+ fclose(a_out);
+ mark_x(new_name);
+}
+
+/*
+ * read the u structure from the core file.
+ */
+read_u(core)
+FILE *core;
+{
+ if ( fread(&u, sizeof u, 1, core) != 1 )
+ {
+ perror("Couldn't read user structure from core file");
+ exit(1);
+ }
+}
+
+/*
+ * Make the header in the new a.out from the header in the old one
+ * modified by the new data size.
+ */
+make_hdr(new, a_out)
+FILE *new, *a_out;
+{
+ if (fread(&hdr, sizeof hdr, 1, a_out) != 1)
+ {
+ perror("Couldn't read header from a.out file");
+ exit(1);
+ }
+ ohdr = hdr;
+ if N_BADMAG(hdr)
+ {
+ fprintf(stderr, "a.out file doesn't have legal magic number\n");
+ exit(1);
+ }
+ if (hdr.a_magic != u.u_exdata.ux_mag ||
+ hdr.a_text != u.u_exdata.ux_tsize ||
+ hdr.a_data != u.u_exdata.ux_dsize ||
+ hdr.a_entry != u.u_exdata.ux_entloc)
+ {
+ fprintf(stderr, "Core file didn't come from this a.out\n");
+ exit(1);
+ }
+
+ printf("Data segment size was %u", hdr.a_data);
+ hdr.a_data = ctob(u.u_dsize);
+ hdr.a_bss = 0; /* all data is inited now! */
+ printf(" now is %u\n", hdr.a_data);
+ if (fwrite(&hdr, sizeof hdr, 1, new) != 1)
+ {
+ perror("Couldn't write header to new a.out file");
+ exit(1);
+ }
+}
+
+/*
+ * Copy the text from the a.out to the new a.out
+ */
+copy_text(new, a_out)
+FILE *new, *a_out;
+{
+ char page[PSIZE];
+ int txtcnt = hdr.a_text;
+
+ fseek(new, N_TXTOFF(hdr), 0);
+ fseek(a_out, N_TXTOFF(hdr), 0);
+ if (hdr.a_magic == OMAGIC)
+ {
+ printf("a.out file is not shared text, getting text from core file\n");
+ fseek(a_out, hdr.a_text, 1); /* skip over text */
+ return;
+ }
+ while (txtcnt >= PSIZE)
+ {
+ if (fread(page, PSIZE, 1, a_out) != 1)
+ {
+ perror("Read failure on a.out text");
+ exit(1);
+ }
+ if (fwrite(page, PSIZE, 1, new) != 1)
+ {
+ perror("Write failure in text segment");
+ exit(1);
+ }
+ txtcnt -= PSIZE;
+ }
+ if (txtcnt)
+ {
+ if (fread(page, txtcnt, 1, a_out) != 1)
+ {
+ perror("Read failure on a.out text");
+ exit(1);
+ }
+ if (fwrite(page, txtcnt, 1, new) != 1)
+ {
+ perror("Write failure in text segment");
+ exit(1);
+ }
+ }
+}
+
+/*
+ * copy the data from the core file to the new a.out
+ */
+copy_data(new, core)
+FILE *new, *core;
+{
+ char page[PSIZE];
+ int datacnt = ctob(u.u_dsize);
+
+ if (hdr.a_magic == OMAGIC)
+ datacnt += u.u_tsize;
+ fseek(core, ctob(UPAGES), 0);
+ while (datacnt >= PSIZE)
+ {
+ if (fread(page, PSIZE, 1, core) != 1)
+ {
+ perror("Read failure on core data");
+ exit(1);
+ }
+ if (fwrite(page, PSIZE, 1, new) != 1)
+ {
+ perror("Write failure in data segment");
+ exit(1);
+ }
+ datacnt -= PSIZE;
+ }
+ if (datacnt)
+ {
+ if (fread(page, datacnt, 1, core) != 1)
+ {
+ perror("Read failure on core data");
+ exit(1);
+ }
+ if (fwrite(page, datacnt, 1, new) != 1)
+ {
+ perror("Write failure in data segment");
+ exit(1);
+ }
+ }
+}
+
+/*
+ * Copy the relocation information and symbol table from the a.out to the new
+ */
+copy_sym(new, a_out)
+FILE *new, *a_out;
+{
+ char page[PSIZE];
+ int n;
+
+ fseek(a_out, ohdr.a_data, 1); /* skip over data segment */
+ while ((n = fread(page, 1, PSIZE, a_out)) > 0)
+ {
+ if (fwrite(page, 1, n, new) != n)
+ {
+ perror("Error writing symbol table to new a.out");
+ fprintf(stderr, "new a.out should be ok otherwise\n");
+ return;
+ }
+ }
+ if (n < 0)
+ {
+ perror("Error reading symbol table from a.out");
+ fprintf(stderr, "new a.out should be ok otherwise\n");
+ }
+}
+
+/*
+ * After succesfully building the new a.out, mark it executable
+ */
+mark_x(name)
+char *name;
+{
+ struct stat sbuf;
+ int um;
+
+ um = umask(777);
+ umask(um);
+ if (stat(name, &sbuf) == -1)
+ {
+ perror ("Can't stat new a.out");
+ fprintf(stderr, "Setting protection to %o\n", 0777 & ~um);
+ sbuf.st_mode = 0777;
+ }
+ sbuf.st_mode |= 0111 & ~um;
+ if (chmod(name, sbuf.st_mode) == -1)
+ perror("Couldn't change mode of new a.out to executable");
+
+}
+
diff --git a/obsolete/support/undump/undump.VAX4_3.c b/obsolete/support/undump/undump.VAX4_3.c
new file mode 100644
index 0000000000..19fe9315bb
--- /dev/null
+++ b/obsolete/support/undump/undump.VAX4_3.c
@@ -0,0 +1,264 @@
+/*
+ * This program was advertised on unix-wizards. I have had such a large
+ * response I'm sending it out to the world.
+ *
+ * Here is the source. It works fine under 4.1bsd, I see no fundamental
+ * reason why it shouldn't work on an 11. (Except possibly small format
+ * changes in exec header or user structure.) No documentation yet.
+ * Usage is
+ * undump new-a.out-file [old-a.out-file] [core-file]
+ * where old-a.out-file and core-file default to "a.out" and "core",
+ * respectively. Probably should have an option to not require
+ * old-a.out-file if the core came from a 407 file.
+ *
+ * It doesn't preserve open files, and the program is re-entered at main
+ * when you run it. It's used locally to dump a lisp and restart it.
+ *
+ * It requires a local subroutine called scanargs, somewhat similar to
+ * getopt (I think). You should be able to easily get around this, though.
+ * =Spencer
+ */
+
+
+/*
+ * undump.c - Convert a core file to an a.out.
+ *
+ * Author: Spencer W. Thomas
+ * Computer Science Dept.
+ * University of Utah
+ * Date: Wed Feb 17 1982
+ * Copyright (c) 1982 Spencer W. Thomas
+ *
+ * Usage:
+ * undump new-a.out [a.out] [core]
+ */
+
+#include <stdio.h>
+#include <sys/param.h>
+#include <sys/dir.h>
+#include <sys/user.h>
+#include <sys/stat.h>
+#include <a.out.h>
+
+#define PSIZE 10240
+
+struct user u;
+struct exec hdr, ohdr;
+
+main(argc, argv)
+char **argv;
+{
+ char *new_name, *a_out_name = "a.out", *core_name = "core";
+ FILE *new, *a_out, *core;
+
+ if (scanargs(argc, argv, "undump new-a.out!s a.out%s core%s",
+ &new_name, &a_out_name, &core_name)
+ != 1)
+ exit(1);
+
+ if ((a_out = fopen(a_out_name, "r")) == NULL)
+ {
+ perror(a_out_name);
+ exit(1);
+ }
+ if ((core = fopen(core_name, "r")) == NULL)
+ {
+ perror(core_name);
+ exit(1);
+ }
+ if ((new = fopen(new_name, "w")) == NULL)
+ {
+ perror(new_name);
+ exit(1);
+ }
+
+ read_u(core);
+ make_hdr(new, a_out);
+ copy_text(new, a_out);
+ copy_data(new, core);
+ copy_sym(new, a_out);
+ fclose(new);
+ fclose(core);
+ fclose(a_out);
+ mark_x(new_name);
+}
+
+/*
+ * read the u structure from the core file.
+ */
+read_u(core)
+FILE *core;
+{
+ if ( fread(&u, sizeof u, 1, core) != 1 )
+ {
+ perror("Couldn't read user structure from core file");
+ exit(1);
+ }
+}
+
+/*
+ * Make the header in the new a.out from the header in the old one
+ * modified by the new data size.
+ */
+make_hdr(new, a_out)
+FILE *new, *a_out;
+{
+ if (fread(&hdr, sizeof hdr, 1, a_out) != 1)
+ {
+ perror("Couldn't read header from a.out file");
+ exit(1);
+ }
+ ohdr = hdr;
+ if N_BADMAG(hdr)
+ {
+ fprintf(stderr, "a.out file doesn't have legal magic number\n");
+ exit(1);
+ }
+
+ printf("Data segment size was %u", hdr.a_data);
+ hdr.a_data = ctob(u.u_dsize);
+ hdr.a_bss = 0; /* all data is inited now! */
+ printf(" now is %u\n", hdr.a_data);
+ if (fwrite(&hdr, sizeof hdr, 1, new) != 1)
+ {
+ perror("Couldn't write header to new a.out file");
+ exit(1);
+ }
+}
+
+/*
+ * Copy the text from the a.out to the new a.out
+ */
+copy_text(new, a_out)
+FILE *new, *a_out;
+{
+ char page[PSIZE];
+ int txtcnt = hdr.a_text;
+
+ fseek(new, N_TXTOFF(hdr), 0);
+ fseek(a_out, N_TXTOFF(hdr), 0);
+ if (hdr.a_magic == OMAGIC)
+ {
+ printf("a.out file is not shared text, getting text from core file\n");
+ fseek(a_out, hdr.a_text, 1); /* skip over text */
+ return;
+ }
+ while (txtcnt >= PSIZE)
+ {
+ if (fread(page, PSIZE, 1, a_out) != 1)
+ {
+ perror("Read failure on a.out text");
+ exit(1);
+ }
+ if (fwrite(page, PSIZE, 1, new) != 1)
+ {
+ perror("Write failure in text segment");
+ exit(1);
+ }
+ txtcnt -= PSIZE;
+ }
+ if (txtcnt)
+ {
+ if (fread(page, txtcnt, 1, a_out) != 1)
+ {
+ perror("Read failure on a.out text");
+ exit(1);
+ }
+ if (fwrite(page, txtcnt, 1, new) != 1)
+ {
+ perror("Write failure in text segment");
+ exit(1);
+ }
+ }
+}
+
+/*
+ * copy the data from the core file to the new a.out
+ */
+copy_data(new, core)
+FILE *new, *core;
+{
+ char page[PSIZE];
+ int datacnt = ctob(u.u_dsize);
+
+ if (hdr.a_magic == OMAGIC)
+ datacnt += u.u_tsize;
+ fseek(core, ctob(UPAGES), 0);
+ while (datacnt >= PSIZE)
+ {
+ if (fread(page, PSIZE, 1, core) != 1)
+ {
+ perror("Read failure on core data");
+ exit(1);
+ }
+ if (fwrite(page, PSIZE, 1, new) != 1)
+ {
+ perror("Write failure in data segment");
+ exit(1);
+ }
+ datacnt -= PSIZE;
+ }
+ if (datacnt)
+ {
+ if (fread(page, datacnt, 1, core) != 1)
+ {
+ perror("Read failure on core data");
+ exit(1);
+ }
+ if (fwrite(page, datacnt, 1, new) != 1)
+ {
+ perror("Write failure in data segment");
+ exit(1);
+ }
+ }
+}
+
+/*
+ * Copy the relocation information and symbol table from the a.out to the new
+ */
+copy_sym(new, a_out)
+FILE *new, *a_out;
+{
+ char page[PSIZE];
+ int n;
+
+ fseek(a_out, ohdr.a_data, 1); /* skip over data segment */
+ while ((n = fread(page, 1, PSIZE, a_out)) > 0)
+ {
+ if (fwrite(page, 1, n, new) != n)
+ {
+ perror("Error writing symbol table to new a.out");
+ fprintf(stderr, "new a.out should be ok otherwise\n");
+ return;
+ }
+ }
+ if (n < 0)
+ {
+ perror("Error reading symbol table from a.out");
+ fprintf(stderr, "new a.out should be ok otherwise\n");
+ }
+}
+
+/*
+ * After succesfully building the new a.out, mark it executable
+ */
+mark_x(name)
+char *name;
+{
+ struct stat sbuf;
+ int um;
+
+ um = umask(777);
+ umask(um);
+ if (stat(name, &sbuf) == -1)
+ {
+ perror ("Can't stat new a.out");
+ fprintf(stderr, "Setting protection to %o\n", 0777 & ~um);
+ sbuf.st_mode = 0777;
+ }
+ sbuf.st_mode |= 0111 & ~um;
+ if (chmod(name, sbuf.st_mode) == -1)
+ perror("Couldn't change mode of new a.out to executable");
+
+}
+