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;
}