diff -urN linux/fs/proc/Makefile linux-2.3.3-kcore/fs/proc/Makefile
--- linux/fs/proc/Makefile	Wed Jun 24 22:30:10 1998
+++ linux-2.3.3-kcore/fs/proc/Makefile	Tue May 25 10:02:56 1999
@@ -9,7 +9,7 @@
 
 O_TARGET := proc.o
 O_OBJS   := inode.o root.o base.o generic.o mem.o link.o fd.o array.o \
-		kmsg.o scsi.o proc_tty.o
+		kmsg.o scsi.o proc_tty.o kcore.o
 ifdef CONFIG_OMIRR
 O_OBJS   := $(O_OBJS) omirr.o
 endif
diff -urN linux/fs/proc/kcore.c linux-2.3.3-kcore/fs/proc/kcore.c
--- linux/fs/proc/kcore.c	Thu Jan  1 01:00:00 1970
+++ linux-2.3.3-kcore/fs/proc/kcore.c	Tue May 25 10:03:21 1999
@@ -0,0 +1,281 @@
+/*
+ * kernel ELF core dumper
+ *
+ * Modelled on fs/exec.c:aout_core_dump()
+ * Jeremy Fitzhardinge <jeremy@sw.oz.au>
+ * Implemented by David Howells <David.Howells@nexor.co.uk>
+ * Minor modifications by Tigran Aivazian <tigran@sco.com>
+ */
+
+#include <linux/mm.h>
+#include <linux/proc_fs.h>
+#include <linux/elf.h>
+#include <linux/elfcore.h>
+#include <asm/uaccess.h>
+
+#define roundup(x, y)  ((((x)+((y)-1))/(y))*(y))
+
+/* An ELF note in memory */
+struct memelfnote
+{
+	const char *name;
+	int type;
+	unsigned int datasz;
+	void *data;
+};
+
+extern char saved_command_line[];
+
+/*****************************************************************************/
+/*
+ * determine size of ELF note
+ */
+static int notesize(struct memelfnote *en)
+{
+	int sz;
+
+	sz = sizeof(struct elf_note);
+	sz += roundup(strlen(en->name), 4);
+	sz += roundup(en->datasz, 4);
+
+	return sz;
+} /* end notesize() */
+
+/*****************************************************************************/
+/*
+ * store a note in the header buffer
+ */
+static char *storenote(struct memelfnote *men, char *bufp)
+{
+	struct elf_note en;
+
+#define DUMP_WRITE(addr,nr) do { memcpy(bufp,addr,nr); bufp += nr; } while(0)
+
+	en.n_namesz = strlen(men->name);
+	en.n_descsz = men->datasz;
+	en.n_type = men->type;
+
+	DUMP_WRITE(&en, sizeof(en));
+	DUMP_WRITE(men->name, en.n_namesz);
+
+	/* XXX - cast from long long to long to avoid need for libgcc.a */
+	bufp = (char*) roundup((unsigned long)bufp,4);
+	DUMP_WRITE(men->data, men->datasz);
+	bufp = (char*) roundup((unsigned long)bufp,4);
+
+#undef DUMP_WRITE
+
+	return bufp;
+} /* end storenote() */
+
+/*****************************************************************************/
+/*
+ * store an ELF coredump header in the supplied buffer
+ * - assume the memory image is the size specified
+ */
+static void elf_kcore_store_hdr(char *bufp, size_t size, off_t dataoff)
+{
+	struct elf_prstatus prstatus;	/* NT_PRSTATUS */
+	struct elf_prpsinfo psinfo;	/* NT_PRPSINFO */
+	struct elf_phdr *nhdr, *dhdr;
+	struct elfhdr *elf;
+	struct memelfnote notes[3];
+	off_t offset = 0;
+
+	/* acquire an ELF header block from the buffer */
+	elf = (struct elfhdr *) bufp;
+	bufp += sizeof(*elf);
+	offset += sizeof(*elf);
+
+	/* set up header */
+	memcpy(elf->e_ident,ELFMAG,SELFMAG);
+	elf->e_ident[EI_CLASS]	= ELF_CLASS;
+	elf->e_ident[EI_DATA]	= ELF_DATA;
+	elf->e_ident[EI_VERSION]= EV_CURRENT;
+	memset(elf->e_ident+EI_PAD,0,EI_NIDENT-EI_PAD);
+
+	elf->e_type	= ET_CORE;
+	elf->e_machine	= ELF_ARCH;
+	elf->e_version	= EV_CURRENT;
+	elf->e_entry	= 0;
+	elf->e_phoff	= sizeof(*elf);
+	elf->e_shoff	= 0;
+	elf->e_flags	= 0;
+	elf->e_ehsize	= sizeof(*elf);
+	elf->e_phentsize= sizeof(struct elf_phdr);
+	elf->e_phnum	= 2;			/* no. of segments */
+	elf->e_shentsize= 0;
+	elf->e_shnum	= 0;
+	elf->e_shstrndx	= 0;
+
+	/* acquire an ELF program header blocks from the buffer for notes */
+	nhdr = (struct elf_phdr *) bufp;
+	bufp += sizeof(*nhdr);
+	offset += sizeof(*nhdr);
+
+	/* store program headers for notes dump */
+	nhdr->p_type	= PT_NOTE;
+	nhdr->p_offset	= 0;
+	nhdr->p_vaddr	= 0;
+	nhdr->p_paddr	= 0;
+	nhdr->p_memsz	= 0;
+	nhdr->p_flags	= 0;
+	nhdr->p_align	= 0;
+
+	/* acquire an ELF program header blocks from the buffer for data */
+	dhdr = (struct elf_phdr *) bufp;
+	bufp += sizeof(*dhdr);
+	offset += sizeof(*dhdr);
+
+	/* store program headers for data dump */
+	dhdr->p_type	= PT_LOAD;
+	dhdr->p_flags	= PF_R|PF_W|PF_X;
+	dhdr->p_offset	= dataoff;
+	dhdr->p_vaddr	= PAGE_OFFSET;
+	dhdr->p_paddr	= __pa(PAGE_OFFSET);
+	dhdr->p_filesz	= size;
+	dhdr->p_memsz	= size;
+	dhdr->p_align	= PAGE_SIZE;
+
+	/*
+	 * Set up the notes in similar form to SVR4 core dumps made
+	 * with info from their /proc.
+	 */
+	nhdr->p_offset	= offset;
+	nhdr->p_filesz	= 0;
+
+	/* set up the process status */
+	notes[0].name = "CORE";
+	notes[0].type = NT_PRSTATUS;
+	notes[0].datasz = sizeof(prstatus);
+	notes[0].data = &prstatus;
+
+	memset(&prstatus,0,sizeof(prstatus));
+
+	nhdr->p_filesz	= notesize(&notes[0]);
+	bufp = storenote(&notes[0],bufp);
+
+	/* set up the process info */
+	notes[1].name	= "CORE";
+	notes[1].type	= NT_PRPSINFO;
+	notes[1].datasz	= sizeof(psinfo);
+	notes[1].data	= &psinfo;
+
+	memset(&psinfo,0,sizeof(psinfo));
+	psinfo.pr_state	= 0;
+	psinfo.pr_sname	= 'R';
+	psinfo.pr_zomb	= 0;
+
+	strcpy(psinfo.pr_fname,"vmlinux");
+	strncpy(psinfo.pr_psargs,saved_command_line,ELF_PRARGSZ);
+
+	nhdr->p_filesz	= notesize(&notes[1]);
+	bufp = storenote(&notes[1],bufp);
+
+	/* set up the task structure */
+	notes[2].name	= "CORE";
+	notes[2].type	= NT_TASKSTRUCT;
+	notes[2].datasz	= sizeof(*current);
+	notes[2].data	= current;
+
+	nhdr->p_filesz	= notesize(&notes[2]);
+	bufp = storenote(&notes[2],bufp);
+
+} /* end elf_kcore_store_hdr() */
+
+/*****************************************************************************/
+/*
+ * read from the ELF header and then kernel memory
+ */
+static ssize_t elf_kcore_read(struct file *file, char *buffer, size_t buflen,
+			      loff_t *fpos)
+{
+	ssize_t acc;
+	size_t size, tsz;
+	char *page;
+
+	/* work out how much file we allow to be read */
+	size = ((size_t)high_memory - PAGE_OFFSET) + PAGE_SIZE;
+	acc = 0;
+
+	/* see if file pointer already beyond EOF */
+	if (buflen==0 || *fpos>=size)
+		return 0;
+
+	/* trim buflen to not go beyond EOF */
+	if (buflen > size-*fpos)
+		buflen = size - *fpos;
+
+	/* construct an ELF core header if we'll need some of it */
+	if (*fpos<PAGE_SIZE) {
+		/* get a buffer */
+		page = (char*) __get_free_page(GFP_KERNEL);
+		if (!page)
+			return -ENOMEM;
+
+		tsz = PAGE_SIZE-*fpos;
+		if (buflen < tsz)
+			tsz = buflen;
+
+		/* create a header */
+		memset(page,0,PAGE_SIZE);
+		elf_kcore_store_hdr(page,size-PAGE_SIZE,PAGE_SIZE);
+
+		/* copy data to the users buffer */
+		copy_to_user(buffer,page,tsz);
+		buflen -= tsz;
+		*fpos += tsz;
+		buffer += tsz;
+		acc += tsz;
+
+		free_page((unsigned long) page);
+
+		/* leave now if filled buffer already */
+		if (buflen==0)
+			return tsz;
+	}
+
+	/* where page 0 not mapped, write zeros into buffer */
+#if defined (__i386__) || defined (__mc68000__)
+	if (*fpos < PAGE_SIZE*2) {
+		/* work out how much to clear */
+		tsz = PAGE_SIZE*2 - *fpos;
+		if (buflen < tsz)
+			tsz = buflen;
+
+		/* write zeros to buffer */
+		clear_user(buffer,tsz);
+		buflen -= tsz;
+		*fpos += tsz;
+		buffer += tsz;
+		acc += tsz;
+
+		/* leave now if filled buffer already */
+		if (buflen==0)
+			return tsz;
+	}
+#endif
+
+	/* fill the remainder of the buffer from kernel VM space */
+#if defined (__i386__) || defined (__mc68000__)
+	copy_to_user(buffer,__va(*fpos-PAGE_SIZE),buflen);
+#else
+	copy_to_user(buffer,__va(*fpos),buflen);
+#endif
+	acc += buflen;
+
+	return acc;
+
+} /* end elf_kcore_read() */
+
+/*****************************************************************************/
+/* data structures for registering /proc/kcore_elf */
+
+static struct file_operations elf_kcore_operations = {
+	read:		elf_kcore_read
+};
+
+/* root.c places this into struct proc_dir_entry proc_root_kcore_elf */
+struct inode_operations proc_kcore_elf_inode_operations = {
+	&elf_kcore_operations
+};
diff -urN linux/fs/proc/root.c linux-2.3.3-kcore/fs/proc/root.c
--- linux/fs/proc/root.c	Wed Apr 28 16:47:39 1999
+++ linux-2.3.3-kcore/fs/proc/root.c	Tue May 25 10:04:36 1999
@@ -566,6 +566,11 @@
 	S_IFREG | S_IRUSR, 1, 0, 0,
 	0, &proc_kcore_inode_operations
 };
+static struct proc_dir_entry proc_root_kcore_elf = {
+	PROC_KCORE_ELF, 9, "kcore_elf",
+	S_IFREG | S_IRUSR, 1, 0, 0,
+	0, &proc_kcore_elf_inode_operations
+};
 #ifdef CONFIG_MODULES
 static struct proc_dir_entry proc_root_modules = {
 	PROC_MODULES, 7, "modules",
@@ -693,6 +698,8 @@
 #endif
 	proc_register(&proc_root, &proc_root_kcore);
 	proc_root_kcore.size = (MAP_NR(high_memory) << PAGE_SHIFT) + PAGE_SIZE;
+	proc_register(&proc_root, &proc_root_kcore_elf);
+	proc_root_kcore_elf.size = (MAP_NR(high_memory) << PAGE_SHIFT) + PAGE_SIZE;
 
 #ifdef CONFIG_MODULES
 	proc_register(&proc_root, &proc_root_modules);
diff -urN linux/include/linux/proc_fs.h linux-2.3.3-kcore/include/linux/proc_fs.h
--- linux/include/linux/proc_fs.h	Sun May 16 21:18:51 1999
+++ linux-2.3.3-kcore/include/linux/proc_fs.h	Tue May 25 10:05:21 1999
@@ -52,7 +52,8 @@
 	PROC_STRAM,
 	PROC_SOUND,
 	PROC_MTRR, /* whether enabled or not */
-	PROC_FS
+	PROC_FS,
+	PROC_KCORE_ELF
 };
 
 enum pid_directory_inos {
@@ -413,6 +414,7 @@
 extern struct inode_operations proc_array_inode_operations;
 extern struct inode_operations proc_arraylong_inode_operations;
 extern struct inode_operations proc_kcore_inode_operations;
+extern struct inode_operations proc_kcore_elf_inode_operations;
 extern struct inode_operations proc_profile_inode_operations;
 extern struct inode_operations proc_kmsg_inode_operations;
 extern struct inode_operations proc_link_inode_operations;
