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