diff -urN -X dontdiff linux/fs/proc/kcore.c 2327-kcore/fs/proc/kcore.c
--- linux/fs/proc/kcore.c       Thu Nov 11 03:47:57 1999
+++ 2327-kcore/fs/proc/kcore.c  Fri Nov 12 17:20:28 1999
@@ -189,7 +189,7 @@
 * store an ELF coredump header in the supplied buffer
 * num_vma is the number of elements in vmlist
 */
-static void elf_kcore_store_hdr(char *bufp, int num_vma, int elf_buflen)
+static void elf_kcore_store_hdr(char *bufp, int num_vma, int dataoff)
{
       struct elf_prstatus prstatus;   /* NT_PRSTATUS */
       struct elf_prpsinfo prpsinfo;   /* NT_PRPSINFO */
@@ -235,18 +235,20 @@
       nhdr->p_flags   = 0;
       nhdr->p_align   = 0;

-       /* setup ELF PT_LOAD program header */
+       /* setup ELF PT_LOAD program header for the
+        * virtual range 0xc0000000 -> high_memory */
       phdr = (struct elf_phdr *) bufp;
       bufp += sizeof(struct elf_phdr);
       offset += sizeof(struct elf_phdr);
       phdr->p_type    = PT_LOAD;
       phdr->p_flags   = PF_R|PF_W|PF_X;
-       phdr->p_offset  = elf_buflen;
+       phdr->p_offset  = dataoff;
       phdr->p_vaddr   = PAGE_OFFSET;
       phdr->p_paddr   = __pa(PAGE_OFFSET);
       phdr->p_filesz  = phdr->p_memsz = ((unsigned long)high_memory - PAGE_OFFSET);
       phdr->p_align   = PAGE_SIZE;

+       /* setup ELF PT_LOAD program headers, one for every kvma range */
       for (m=vmlist; m; m=m->next) {
               phdr = (struct elf_phdr *) bufp;
               bufp += sizeof(struct elf_phdr);
@@ -254,9 +256,9 @@

               phdr->p_type    = PT_LOAD;
               phdr->p_flags   = PF_R|PF_W|PF_X;
-               phdr->p_offset  = (size_t)m->addr - PAGE_OFFSET + elf_buflen;
+               phdr->p_offset  = (size_t)m->addr - PAGE_OFFSET + dataoff;
               phdr->p_vaddr   = (size_t)m->addr;
-               phdr->p_paddr   = __pa(m);
+               phdr->p_paddr   = __pa(m->addr);
               phdr->p_filesz  = phdr->p_memsz = m->size;
               phdr->p_align   = PAGE_SIZE;
       }
@@ -310,13 +312,16 @@
/*
 * read from the ELF header and then kernel memory
 */
-static ssize_t read_kcore(struct file *file, char *buffer, size_t buflen,
-                             loff_t *fpos)
+static ssize_t read_kcore(struct file *file, char *buffer, size_t buflen, loff_t *fpos)
{
       ssize_t acc = 0;
       size_t size, tsz;
       char * elf_buffer;
-       int elf_buflen = 0, num_vma = 0;
+       size_t elf_buflen = 0;
+       int num_vma = 0;
+
+       if (verify_area(VERIFY_WRITE, buffer, buflen))
+               return -EFAULT;

       /* XXX we need to somehow lock vmlist between here
        * and after elf_kcore_store_hdr() returns.
@@ -340,7 +345,7 @@
                       return -ENOMEM;
               memset(elf_buffer, 0, elf_buflen);
               elf_kcore_store_hdr(elf_buffer, num_vma, elf_buflen);
-               copy_to_user(buffer, elf_buffer, tsz);
+               copy_to_user(buffer, elf_buffer + *fpos, tsz);
               kfree(elf_buffer);
               buflen -= tsz;
               *fpos += tsz;
@@ -349,7 +354,7 @@

               /* leave now if filled buffer already */
               if (buflen == 0)
-                       return tsz;
+                       return acc;
       }

       /* where page 0 not mapped, write zeros into buffer */
@@ -374,14 +379,10 @@
#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
+       copy_to_user(buffer, __va(*fpos - elf_buflen), buflen);
+
       acc += buflen;
       *fpos += buflen;
-
       return acc;

}