v01i001: undump for 386i's
Charles Mcgrew
mcgrew at aramis.rutgers.edu
Sat May 6 03:26:10 AEST 1989
Submitted-by: mcvax!hslrswi!mwm at uunet.uu.net (Mike McGann)
Posting-number: Volume 1, Issue 1
Archive-name: undump-386i
# remove everything above the line that says '/bin/sh' and feed
# it to sh.
#!/bin/sh
#
#
# This is for a 386i, which unfortunately we don't have at Rutgers.
# I cannot therefore vouch for its working-ness.
#
#Charles
#
# 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:
# undump.SYS_V.c
# This archive created: Fri Jan 13 16:26:50 1989
export PATH; PATH=/bin:/usr/bin:$PATH
if test -f 'undump.SYS_V.c'
then
echo shar: "will not over-write existing file 'undump.SYS_V.c'"
else
cat << \SHAR_EOF > 'undump.SYS_V.c'
/*
* 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>
#ifndef i386
#include <sys/psw.h>
#include <sys/pcb.h>
#include <sys/fs/s5dir.h>
#endif
#ifdef i386
#include <sys/core.h>
#endif
#include <sys/signal.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;
#ifdef i386
struct core c;
#endif
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;
}
}
#ifndef i386
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;
#endif
#ifdef i386
if (fread(&c, sizeof(struct core), 1, cfp) != 1)
Perror("core read");
if ((c.c_aouthdr.a_text - c.c_aouthdr.a_trsize)!= aout.tsize ||
c.c_aouthdr.a_data != aout.dsize ||
c.c_aouthdr.a_bss != aout.bsize) {
fprintf("mismatch between %s and %s sizes\n", a_out_name, core_name);
exit(1);}
aout.dsize = c.c_dsize;
off = 0;
size = c.c_dsize;
#endif
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);
#ifndef i386
fseek(cfp, off, 0);
#endif
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);
}
SHAR_EOF
fi
exit 0
# End of shell archive
More information about the Comp.sources.sun
mailing list