Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 25 Aug 1998 06:58:23 +0200
From:      Wolfram Schneider <wosch@panke.de.freebsd.org>
To:        hackers@FreeBSD.ORG
Subject:   undump utility
Message-ID:  <19980825065823.A1824@panke.de>

next in thread | raw e-mail | index | archive | help
I tried to write an undump uitility for FreeBSD. It sometimes
works for the emacs, but in most cases it core'd immediately.
I don't know why. Any hints?

Wolfram

# This is a shell archive.  Save it in a file, remove anything before
# this line, and then unpack it by entering "sh file".  Note, it may
# create directories; files and directories will be owned by you and
# have default permissions.
#
# This archive contains:
#
#	undump
#	undump/Makefile
#	undump/undump.c
#
echo c - undump
mkdir -p undump > /dev/null 2>&1
echo x - undump/Makefile
sed 's/^X//' >undump/Makefile << 'END-of-undump/Makefile'
XPROG=	undump
XNOMAN=
XCLEANFILES+= sh.core sh.undump sh.undump.core
X
Xdump: 
X	-/bin/sh -c 'kill -6 $$$$'
X
Xtest:	dump
X	./${PROG} -d sh.undump /bin/sh sh.core
X	wc -c sh.undump /bin/sh
X	size sh.undump /bin/sh
X	./sh.undump
X
X.include <bsd.prog.mk>
X
END-of-undump/Makefile
echo x - undump/undump.c
sed 's/^X//' >undump/undump.c << 'END-of-undump/undump.c'
X/*-
X * Copyright (c) Aug 1998 Wolfram Schneider <wosch@FreeBSD.org>, Berlin.
X * All rights reserved.
X *
X * Redistribution and use in source and binary forms, with or without
X * modification, are permitted provided that the following conditions
X * are met:
X * 1. Redistributions of source code must retain the above copyright
X *    notice, this list of conditions and the following disclaimer.
X * 2. Redistributions in binary form must reproduce the above copyright
X *    notice, this list of conditions and the following disclaimer in the
X *    documentation and/or other materials provided with the distribution.
X *
X * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
X * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
X * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
X * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
X * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
X * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
X * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
X * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
X * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
X * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
X * SUCH DAMAGE.
X *
X *	$Id$
X */
X
X/*
X * Convert a core dump to an executable binary. See perl -u
X *
X */
X
X#include <stdio.h>
X#include <a.out.h>
X
X/* core dump */
X#include <sys/param.h>
X#include <sys/user.h>
X
X#include <sys/types.h>
X#include <sys/mman.h>
X#include <sys/stat.h>
X#include <fcntl.h>
X#include <sys/uio.h>
X#include <unistd.h>
X
X#include <err.h>
X#include <stdlib.h>
X
Xextern char *optarg;
Xextern int optind;
X
Xint check_corefile_from_oldfile(char *oldp, char *corep);
Xint copy_text_from_oldfile_to_newfile(char *oldp, int newfd);
Xint copy_data_from_corefile_to_newfile(char *corep, int newfd);
Xint copy_symbol_from_oldfile_to_newfile(char *oldpp, int newfd, int len);
Xint set_exec_header(int newfd);
Xvoid usage();
X
X
Xint debug;
X
Xstatic struct exec oldhdr;   /* exec header from old binary file */
Xstatic struct exec newhdr;   /* exec header for the new file */
Xstatic struct user coreuser; /* text, data, and stack size from core dump */
X
X
Xmain(int argc, char **argv) 
X{
X	int c, oldfilelen;
X	struct stat sb;
X
X	char *newfile, *oldfile, *corefile;
X	int   newfd, oldfd, corefd;
X	char *oldp, *corep;
X
X	while((c = getopt(argc, argv, "d")) != -1) {
X		switch(c) {
X		case 'd':
X			debug++;
X			break;
X
X		default:
X			usage; 
X			exit(1);
X		}
X	}
X	argc -= optind;
X	argv += optind;
X
X	/* usage: undump newfile oldfile corefile */
X	if (argc < 3) {
X		fprintf(stderr, "Too few arguments\n");
X		usage();
X		exit(1);
X	}
X
X	newfile = argv[0];
X	oldfile = argv[1];
X	corefile = argv[2];
X
X	if ((newfd = open(newfile, O_CREAT | O_WRONLY, 0666)) == -1)
X		err(1, "corefile: %s", corefile);
X
X	if ((oldfd = open(oldfile,  O_RDONLY, 0)) == -1)
X		err(1, "Open oldfile: %s", oldfile);
X	if (stat(oldfile, &sb) == -1)
X		err(1, "Stat oldfile: %s", oldfile);
X	if ((oldp = (char *)mmap((caddr_t)0, sb.st_size, PROT_READ, 
X				MAP_SHARED, oldfd, (off_t)0)) ==  MAP_FAILED)
X		err(1, "mmap oldfile: %s", oldfile);
X	oldfilelen = sb.st_size;
X
X	if ((corefd = open(corefile, O_RDONLY, 0)) == -1)
X		err(1, "corefile: %s", corefile);
X	if (stat(corefile, &sb) == -1)
X		err(1, "Stat corefile: %s", corefile);
X	if ((corep = (char *)mmap((caddr_t)0, sb.st_size, PROT_READ, 
X				MAP_SHARED, corefd, (off_t)0)) ==  MAP_FAILED)
X		err(1, "mmap corefile: %s", corefile);
X
X
X
X	/* read exec header from old binary */
X	oldhdr = newhdr = *(struct exec *) oldp;
X
X	/* read text, data, and stack size from core dump */
X	coreuser = *(struct user *) corep;
X	
X
X	if (check_corefile_from_oldfile(oldp, corep)) {
X		fprintf(stderr, "Coredump %s was not generated from %s!\n",
X			corefile, oldfile);
X		exit(2);
X	}
X
X	copy_text_from_oldfile_to_newfile(oldp, newfd);
X	copy_data_from_corefile_to_newfile(corep, newfd);
X	copy_symbol_from_oldfile_to_newfile(oldp, newfd, oldfilelen);
X	set_exec_header(newfd);
X
X	if (fchmod(newfd, 0755) == -1) 
X		err(1, "set mode of new file: %s\n", newfile);
X	if (close(newfd) == -1) 
X		err(1, "closing newfile: %s\n", newfile);
X	close(oldfd);
X	close(corefd);
X
X}
X
Xvoid usage ()
X{
X	fprintf(stderr, "usage: undump [-d] newfile oldfile corefile\n");
X}
X
X
X/* 
X * check if the corefile was
X * created from the oldfile
X */
Xint check_corefile_from_oldfile(char *oldp, char *corep) 
X{
X	if (debug) {
X		printf("Old binary file: ");
X		printf("a_text: %u, a_data: %u, a_bss: %u, a_syms: %u\n",
X		       oldhdr.a_text, oldhdr.a_data, oldhdr.a_bss,
X		       oldhdr.a_syms);
X		printf("\t\t a_entry: %u, a_trsize: %u, a_drsize: %u\n", 
X		       oldhdr.a_entry, oldhdr.a_trsize, oldhdr.a_drsize);
X
X		printf("Core dump file: ");
X		printf("u_tsize: %u, u_dsize: %u, u_ssize: %u\n",
X		       ptoa(coreuser.u_tsize), 
X		       ptoa(coreuser.u_dsize), 
X		       ptoa(coreuser.u_ssize));
X	}
X	
X	if (oldhdr.a_text != ptoa(coreuser.u_tsize)) {
X		return(1);
X	}
X
X	return (0);
X}
X
X
X/* 
X * Copy text sgement from old file 
X * to new file.
X */
Xint copy_text_from_oldfile_to_newfile(char *oldp, int newfd) 
X{
X	if (debug) {
X		printf("Old binary file: N_TXTOFF: %u, N_TXTADDR: %u, "
X		       "a_text: %u\n", 
X		       N_TXTOFF(oldhdr), N_TXTADDR(oldhdr), oldhdr.a_text);
X	}
X	
X	if (lseek(newfd, (off_t)N_TXTOFF(newhdr), SEEK_SET) == -1)
X		err(1, NULL);
X	if (write(newfd, oldp + N_TXTOFF(oldhdr),  oldhdr.a_text) == -1)
X		err(1, NULL);
X	
X	return(0);
X};
X
X/*
X * Copy data from coredump file
X * into the data segement of the new file. 
X */
X
Xint copy_data_from_corefile_to_newfile(char *corep, int newfd) 
X{
X	if (debug) {
X		printf("Copy %u bytes from coredump data to new file\n",
X		       ptoa(coreuser.u_dsize));
X
X		printf("Old binary file: N_DATOFF: %u, N_DATADDR: %u, "
X		       "a_data: %u\n", 
X		       N_DATOFF(newhdr), N_DATADDR(newhdr), newhdr.a_data);
X
X	}
X
X	if (lseek(newfd, (off_t)N_DATOFF(newhdr), SEEK_SET) == -1)
X		err(1, NULL);
X
X	if (write(newfd, corep + ptoa(UPAGES), ptoa(coreuser.u_dsize)) == -1)
X		err(1, NULL);
X
X	return(0);
X};
X
X/*
X * Copy text relocations and the rest (data relocations, symbol table
X * string table) at end  of the new file. 
X */
X
Xint copy_symbol_from_oldfile_to_newfile(
X	char *oldp, int newfd, int oldfilelen)
X{
X	if (debug) {
X		printf("Copy %u bytes rel + sym from old file to new file\n",
X		       oldfilelen - N_RELOFF(oldhdr));
X		printf("N_RELOFF: %u\n", N_RELOFF(oldhdr));
X	}
X
X	if (lseek(newfd, (off_t)N_RELOFF(oldhdr), SEEK_SET) == -1)
X		err(1, NULL);
X
X	if (write(newfd, oldp + N_RELOFF(oldhdr), 
X		  oldfilelen - N_RELOFF(oldhdr)) == -1)
X		err(1, NULL);
X
X	return(0);
X};
X
X
X
X
X/*
X * Set the exec header values of the
X * new file
X */
Xint set_exec_header(int newfd) 
X{
X	/* set data segment size */
X	newhdr.a_data = ptoa(coreuser.u_dsize);
X
X	/* the bss segment is now in the data of the new file */
X	newhdr.a_bss = 0;
X
X
X	if (debug) {
X		printf("New binary file: ");
X		printf("a_text: %u, a_data: %u, a_bss: %u, a_syms: %u\n",
X		       newhdr.a_text, newhdr.a_data, newhdr.a_bss,
X		       newhdr.a_syms);
X		printf("\t\t a_entry: %u, a_trsize: %u, a_drsize: %u\n", 
X		       newhdr.a_entry, newhdr.a_trsize, newhdr.a_drsize);
X	}
X
X	/* write the exec header at the beginning of the new file */
X	if (lseek(newfd, (off_t)0, SEEK_SET) == -1)
X		err(1, NULL);
X
X	if (write(newfd, &newhdr, sizeof(newhdr)) == -1)
X		err(1, NULL);
X
X	return(0);
X};
X	     
END-of-undump/undump.c
exit

-- 
Wolfram Schneider <wosch@freebsd.org> http://www.freebsd.org/~w/

To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-hackers" in the body of the message



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?19980825065823.A1824>