summaryrefslogtreecommitdiff
path: root/obsolete/support/undump/Encore/undump.c
diff options
context:
space:
mode:
Diffstat (limited to 'obsolete/support/undump/Encore/undump.c')
-rw-r--r--obsolete/support/undump/Encore/undump.c374
1 files changed, 374 insertions, 0 deletions
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");
+
+}
+