Looking for "undump" for SysV
joost helberg
joost at nixvia.UUCP
Sat Jan 28 00:06:18 AEST 1989
UNDUMP for coff-files:
#! /bin/sh
# This is a shell archive, meaning:
# 1. Remove everything above the #! /bin/sh line.
# 2. Save the resulting text in a file.
# 3. Execute the file with /bin/sh (not csh) to create the files:
# Makefile
# scanargs.c
# undump.c
# undump.1
# This archive created: Fri Jan 27 14:31:58 1989
export PATH; PATH=/bin:$PATH
if test -f 'Makefile'
then
echo shar: will not over-write existing file "'Makefile'"
else
cat << \SHAR_EOF > 'Makefile'
#/*
# * @(#)Makefile 1.2 88/05/27 eg4
# */
BINDIR=/usr/local
all undump: undump.o scanargs.o
cc -O -o undump undump.o scanargs.o
clean:
rm *.o undump
install: undump
cp undump $(BINDIR)
SHAR_EOF
fi # end of overwriting check
if test -f 'scanargs.c'
then
echo shar: will not over-write existing file "'scanargs.c'"
else
cat << \SHAR_EOF > 'scanargs.c'
/*
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 at utah-20, decvax!{harpo,randvax}!utah-cs!lepreau
Spencer Thomas thomas at utah-20, decvax!{harpo,randvax}!utah-cs!thomas
(There seems to be a bug here in that if the last option you have
is a flag, and the user enters args incorrectly, sometimes the usage
message printed will miss the null and go flying off thru core...)
--jay for spencer
*/
#include <stdio.h>
#include <ctype.h>
#define YES 1
#define NO 0
#define ERROR(msg) {fprintf(stderr, "msg\n"); goto error; }
char *prformat();
#ifndef QUICK
scanargs (argc, argv, format, arglist)
#else
qscanargs (argc, argv, format, arglist)
#endif
int argc;
char **argv;
char *format;
int arglist[];
{
#ifndef QUICK
_scanargs (argc, argv, format, &arglist);
#else
_qscanargs (argc, argv, format, &arglist);
#endif
}
#ifndef QUICK
_scanargs (argc, argv, format, arglist)
#else
_qscanargs (argc, argv, format, arglist)
#endif
int argc;
char **argv;
char *format;
int *arglist[];
{
register check; /* check counter to be sure all argvs
are processed */
register char *cp;
register cnt;
char tmpflg; /* temp flag */
char c;
char numnum; /* number of numbers already processed
*/
char numstr; /* count # of strings already
processed */
char tmpcnt; /* temp count of # things already
processed */
char required;
char exflag; /* when set, one of a set of exclusive
flags is set */
char excnt; /* count of which exclusive flag is
being processed */
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
check = numnum = numstr = 0;
cp = format;
while (*cp)
{
required = NO;
switch (*(cp++))
{
default: /* all other chars */
break;
case '!': /* required argument */
required = YES;
case '%': /* not required argument */
switch (tmpflg = *(cp++))
{
case '-': /* argument is flag */
/* go back to label */
ncp = cp-1; /* remember */
cp -= 3;
for (excnt = exflag = 0
; *cp != ' ' && !(*cp=='-' &&(cp[-1]=='!'||cp[-1]=='%'));
(--cp, excnt++))
{
for (cnt = 1; cnt < argc; cnt++)
{
/* flags all start with - */
if (*argv[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;
**arglist |=
(1 << excnt);
break;
}
}
}
if (required)
ERROR (flag argument missing);
cp = ncp;
if (!exflag) /* if no flags scanned, skip */
{
while (*++cp != ' ' && *cp)
if (*cp == '!' || *cp == '%')
arglist++;
}
else
cp++; /* skip over - */
while (*cp == ' ')
cp++;
arglist++;
break;
case 's': /* char string */
case 'd': /* decimal # */
case 'o': /* octal # */
case 'x': /* hexadecimal # */
#ifndef QUICK
case 'f': /* floating # */
#endif
case 'D': /* long decimal # */
case 'O': /* long octal # */
case 'X': /* long hexadecimal # */
#ifndef QUICK
case 'F': /* double precision floating # */
#endif
tmpcnt = tmpflg == 's' ? numstr : numnum;
for (cnt = 1; cnt < argc; cnt++)
{
if (tmpflg == 's')/* string */
{
if ((c = *argv[cnt]) == '-')
continue;
if (c >= '0' && c <= '9')
continue;
if (tmpcnt-- != 0)
continue;
**arglist = (int) argv[cnt];
check += cnt;
numstr++;
required = NO;
break;
}
if (*argv[cnt] == '-')
{
if(!isdigit (*(argv[cnt] + 1)))
continue;
}
else if (!isdigit(*argv[cnt]))
continue;
if (tmpcnt-- != 0)/* skip to new one */
continue;
#ifndef QUICK
/* kludge for sscanf */
if ((tmpflg == 'o' || tmpflg == 'O')
&& *argv[cnt] > '7')
ERROR (Bad numeric argument);
cntrl[1] = tmpflg;/* put in conversion */
if (sscanf (argv[cnt], cntrl, *arglist
,junk) != 1)
#else
if (numcvt(argv[cnt], tmpflg, *arglist) != 1)
#endif
ERROR (Bad numeric argument);
check += cnt;
numnum++;
required = NO;
break;
}
if (required)
switch (tmpflg)
{
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);
}
arglist++;
while (*cp == ' ')
cp++;
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] == 0)
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);
return (1);
error:
fprintf (stderr, "usage : ");
if (*(cp = format) != ' ')
while (putc (*cp++, stderr) != ' ');
else
fprintf (stderr, "?? ");
while (*cp == ' ')
cp++;
prformat (cp, NO);
return 0;
}
char *
prformat (format, recurse)
char *format;
{
register char *cp;
char required;
cp = format;
if (recurse)
putc (' ', stderr);
required = NO;
while (*cp)
{
if (recurse && *cp == ' ')
break;
switch (*cp)
{
default:
cp++;
break;
case '!':
required = YES;
case '%':
switch (*++cp)
{
case '-': /* flags */
if (!required)
{
putc ('[', stderr);
putc ('-', stderr);
}
else
{
putc ('-', stderr);
putc ('{', stderr);
}
cp = format;
while (*cp != '%' && *cp != '!')
putc (*cp++, stderr);
if (required)
putc ('}', stderr);
cp += 2; /* skip !- or %- */
if (*cp != ' ')
cp = prformat (cp, YES);
/* this is a recursive call */
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 # */
if (!required)
putc ('[', stderr);
for (; format < cp - 1; format++)
putc (*format, stderr);
if (!required)
putc (']', stderr);
break;
default:
break;
}
required = NO;
format = ++cp;
putc (' ', stderr);
}
}
if (!recurse)
putc ('\n', stderr);
return (cp);
}
#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
SHAR_EOF
fi # end of overwriting check
if test -f 'undump.c'
then
echo shar: will not over-write existing file "'undump.c'"
else
cat << \SHAR_EOF > 'undump.c'
/*
* %W% %E% %Q%
*/
/*
* 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
*
* Changed for COFF format by Piet van Oostrum (piet at ruuinfvax.uucp)
* 18-Aug-1987
*
*/
/*
* 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 <sys/types.h>
#include <signal.h>
#include <sys/dir.h>
#include <sys/sysmacros.h>
#include <stdio.h>
#include <sys/param.h>
#include <sys/user.h>
#include <sys/stat.h>
#include <a.out.h>
#include <core.h>
#define UPAGES 2 /* size of u-structure in clicks */
#define OMAGIC 0150
#define PSIZE 2048 /* click-size */
struct user u;
static struct filehdr f_hdr;
static struct aouthdr f_ohdr;
static struct scnhdr thdr, dhdr, bhdr;
long OldSym;
main(argc, argv)
char **argv;
{
char *new_name, *a_out_name = "a.out", *core_name = "core";
int 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 = open(a_out_name, 0)) <0)
{
perror(a_out_name);
exit(1);
}
if ((core = open(core_name, 0)) <0)
{
perror(core_name);
exit(1);
}
if ((new = creat(new_name, 0666)) <0)
{
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);
close(new);
close(core);
close(a_out);
mark_x(new_name);
}
/*
* read the u structure from the core file.
*/
read_u(core)
int core;
{
if (read (core, &u, sizeof u) != sizeof u )
{
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)
int new, a_out;
{
auto struct scnhdr scntemp; /* Temporary section header */
register int scns;
if (read (a_out, &f_hdr, sizeof (f_hdr)) != sizeof (f_hdr)
|| f_hdr.f_opthdr == 0
|| read (a_out, &f_ohdr, sizeof (f_ohdr)) != sizeof (f_ohdr))
{
perror("Couldn't read header from a.out file");
exit(1);
}
/*
if BADMAG(f_ohdr)
{
fprintf(stderr, "a.out file doesn't have legal magic number\n");
exit(1);
}
*/ /* not done for a while JAH */
/*
if (f_ohdr.magic != u.u_exdata.ux_mag ||
f_ohdr.tsize != u.u_exdata.ux_tsize ||
f_ohdr.dsize != u.u_exdata.ux_dsize ||
f_ohdr.entry != u.u_exdata.ux_entloc)
{
fprintf(stderr, "Core file didn't come from this a.out\n");
exit(1);
}
*//* not done for a while */
f_hdr.f_timdat = time(0);
printf("Data segment size was %u", f_ohdr.dsize);
f_ohdr.dsize = ctob(u.u_dsize);
f_ohdr.bsize = 0; /* all data is inited now! */
printf(" now is %u\n", f_ohdr.dsize);
/* 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 ("Couldn't read section header from a.out file");
exit(1);
}
if (scntemp.s_scnptr > 0L)
{
}
if (strcmp (scntemp.s_name, ".text") == 0)
{
thdr = scntemp;
}
else if (strcmp (scntemp.s_name, ".data") == 0)
{
dhdr = scntemp;
}
else if (strcmp (scntemp.s_name, ".bss") == 0)
{
bhdr = scntemp;
}
}
dhdr.s_size = f_ohdr.dsize;
bhdr.s_size = 0L;
bhdr.s_scnptr = 0L;
OldSym = f_hdr.f_symptr;
if (f_hdr.f_symptr > 0L)
{
f_hdr.f_symptr = dhdr.s_scnptr + dhdr.s_size;
}
if (thdr.s_lnnoptr > 0L)
{
thdr.s_lnnoptr += 0; /* ihave no soultion (i.e time) for that! JAH */
}
if (write(new, &f_hdr, sizeof f_hdr) != sizeof f_hdr
|| write(new, &f_ohdr, sizeof f_ohdr) != sizeof f_ohdr
|| write (new, &thdr, sizeof (thdr)) != sizeof (thdr)
|| write (new, &dhdr, sizeof (dhdr)) != sizeof (dhdr)
|| write (new, &bhdr, sizeof (bhdr)) != sizeof (bhdr))
{
perror("Couldn't write header to new a.out file");
exit(1);
}
return (0);
}
/*
* Copy the text from the a.out to the new a.out
*/
copy_text(new, a_out)
int new, a_out;
{
char page[PSIZE];
int txtcnt = f_ohdr.tsize;
lseek (new, thdr.s_scnptr, 0);
lseek(a_out, thdr.s_scnptr, 0);
if (f_ohdr.magic == OMAGIC)
{
printf("a.out file is not shared text, getting text from core file\n");
return;
}
while (txtcnt >= PSIZE)
{
if (read(a_out, page, PSIZE) != PSIZE)
{
perror("Read failure on a.out text");
exit(1);
}
if (write(new, page, PSIZE) != PSIZE)
{
perror("Write failure in text segment");
exit(1);
}
txtcnt -= PSIZE;
}
if (txtcnt)
{
if (read(a_out, page, txtcnt) != txtcnt)
{
perror("Read failure on a.out text");
exit(1);
}
if (write(new, page, txtcnt) != txtcnt)
{
perror("Write failure in text segment");
exit(1);
}
}
}
/*
* copy the data from the core file to the new a.out
*/
copy_data(new, core)
int new, core;
{
char page[PSIZE];
int datacnt = f_ohdr.dsize;
lseek (new, dhdr.s_scnptr, 0);
if (f_ohdr.magic == OMAGIC)
datacnt += f_ohdr.tsize;
lseek(core, ctob(UPAGES), 0);
while (datacnt >= PSIZE)
{
if (read(core, page, PSIZE) != PSIZE)
{
perror("Read failure on core data");
exit(1);
}
if (write(new, page, PSIZE) != PSIZE)
{
perror("Write failure in data segment");
exit(1);
}
datacnt -= PSIZE;
}
if (datacnt)
{
if (read(core, page, datacnt) != datacnt)
{
perror("Read failure on core data");
exit(1);
}
if (write(new, page, datacnt) != datacnt)
{
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)
int new, a_out;
{
char page[PSIZE];
int n;
lseek(a_out, OldSym, 0); /* skip over data segment */
while ((n = read(a_out, page, PSIZE)) > 0)
{
if (write(new, page, n) != 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");
}
SHAR_EOF
fi # end of overwriting check
if test -f 'undump.1'
then
echo shar: will not over-write existing file "'undump.1'"
else
cat << \SHAR_EOF > 'undump.1'
.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.
SHAR_EOF
fi # end of overwriting check
# End of shell archive
exit 0
|
| _ _ _ |
| / ) / ) / ) --
__) (_/ (_/ / (__
Tel: +3473 75154
Adr: nixdorf computer bv
mijlweg 9
4124 pj vianen
the netherlands
uucp: ....mcvax!unido!nixpbe!helberg.via
More information about the Comp.unix.wizards
mailing list