patch-2.3.28 linux/fs/proc/kcore.c
Next file: linux/fs/super.c
Previous file: linux/fs/proc/inode.c
Back to the patch index
Back to the overall index
- Lines: 107
- Date:
Fri Nov 12 10:37:24 1999
- Orig file:
v2.3.27/linux/fs/proc/kcore.c
- Orig date:
Thu Nov 11 20:11:50 1999
diff -u --recursive --new-file v2.3.27/linux/fs/proc/kcore.c linux/fs/proc/kcore.c
@@ -16,7 +16,6 @@
#include <linux/elf.h>
#include <linux/elfcore.h>
#include <linux/vmalloc.h>
-#include <linux/proc_fs.h>
#include <asm/uaccess.h>
@@ -189,7 +188,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 +234,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 +255,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 +311,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 +344,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 +353,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 +378,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;
}
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)