aboutsummaryrefslogtreecommitdiffstats
path: root/fs/binfmt_elf.c
diff options
context:
space:
mode:
authorRoland McGrath <roland@redhat.com>2007-01-26 03:56:49 -0500
committerLinus Torvalds <torvalds@woody.linux-foundation.org>2007-01-26 16:50:58 -0500
commitf47aef55d9a18945fcdd7fd6bf01121ce973b91b (patch)
tree69f5f6c1fd4ae27d18344ae4b33b5c7bd4b18699 /fs/binfmt_elf.c
parente5b97dde514f9bd43f9e525451d0a863c4fc8a9a (diff)
[PATCH] i386 vDSO: use VM_ALWAYSDUMP
This patch fixes core dumps to include the vDSO vma, which is left out now. It removes the special-case core writing macros, which were not doing the right thing for the vDSO vma anyway. Instead, it uses VM_ALWAYSDUMP in the vma; there is no need for the fixmap page to be installed. It handles the CONFIG_COMPAT_VDSO case by making elf_core_dump use the fake vma from get_gate_vma after real vmas in the same way the /proc/PID/maps code does. This changes core dumps so they no longer include the non-PT_LOAD phdrs from the vDSO. I made the change to add them in the first place, but in turned out that nothing ever wanted them there since the advent of NT_AUXV. It's cleaner to leave them out, and just let the phdrs inside the vDSO image speak for themselves. Signed-off-by: Roland McGrath <roland@redhat.com> Cc: Ingo Molnar <mingo@elte.hu> Cc: Paul Mackerras <paulus@samba.org> Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org> Cc: Andi Kleen <ak@suse.de> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'fs/binfmt_elf.c')
-rw-r--r--fs/binfmt_elf.c38
1 files changed, 35 insertions, 3 deletions
diff --git a/fs/binfmt_elf.c b/fs/binfmt_elf.c
index 6fec8bfa6bac..90461f49e902 100644
--- a/fs/binfmt_elf.c
+++ b/fs/binfmt_elf.c
@@ -1428,6 +1428,32 @@ static int elf_dump_thread_status(long signr, struct elf_thread_status *t)
1428 return sz; 1428 return sz;
1429} 1429}
1430 1430
1431static struct vm_area_struct *first_vma(struct task_struct *tsk,
1432 struct vm_area_struct *gate_vma)
1433{
1434 struct vm_area_struct *ret = tsk->mm->mmap;
1435
1436 if (ret)
1437 return ret;
1438 return gate_vma;
1439}
1440/*
1441 * Helper function for iterating across a vma list. It ensures that the caller
1442 * will visit `gate_vma' prior to terminating the search.
1443 */
1444static struct vm_area_struct *next_vma(struct vm_area_struct *this_vma,
1445 struct vm_area_struct *gate_vma)
1446{
1447 struct vm_area_struct *ret;
1448
1449 ret = this_vma->vm_next;
1450 if (ret)
1451 return ret;
1452 if (this_vma == gate_vma)
1453 return NULL;
1454 return gate_vma;
1455}
1456
1431/* 1457/*
1432 * Actual dumper 1458 * Actual dumper
1433 * 1459 *
@@ -1443,7 +1469,7 @@ static int elf_core_dump(long signr, struct pt_regs *regs, struct file *file)
1443 int segs; 1469 int segs;
1444 size_t size = 0; 1470 size_t size = 0;
1445 int i; 1471 int i;
1446 struct vm_area_struct *vma; 1472 struct vm_area_struct *vma, *gate_vma;
1447 struct elfhdr *elf = NULL; 1473 struct elfhdr *elf = NULL;
1448 loff_t offset = 0, dataoff, foffset; 1474 loff_t offset = 0, dataoff, foffset;
1449 unsigned long limit = current->signal->rlim[RLIMIT_CORE].rlim_cur; 1475 unsigned long limit = current->signal->rlim[RLIMIT_CORE].rlim_cur;
@@ -1529,6 +1555,10 @@ static int elf_core_dump(long signr, struct pt_regs *regs, struct file *file)
1529 segs += ELF_CORE_EXTRA_PHDRS; 1555 segs += ELF_CORE_EXTRA_PHDRS;
1530#endif 1556#endif
1531 1557
1558 gate_vma = get_gate_vma(current);
1559 if (gate_vma != NULL)
1560 segs++;
1561
1532 /* Set up header */ 1562 /* Set up header */
1533 fill_elf_header(elf, segs + 1); /* including notes section */ 1563 fill_elf_header(elf, segs + 1); /* including notes section */
1534 1564
@@ -1596,7 +1626,8 @@ static int elf_core_dump(long signr, struct pt_regs *regs, struct file *file)
1596 dataoff = offset = roundup(offset, ELF_EXEC_PAGESIZE); 1626 dataoff = offset = roundup(offset, ELF_EXEC_PAGESIZE);
1597 1627
1598 /* Write program headers for segments dump */ 1628 /* Write program headers for segments dump */
1599 for (vma = current->mm->mmap; vma != NULL; vma = vma->vm_next) { 1629 for (vma = first_vma(current, gate_vma); vma != NULL;
1630 vma = next_vma(vma, gate_vma)) {
1600 struct elf_phdr phdr; 1631 struct elf_phdr phdr;
1601 size_t sz; 1632 size_t sz;
1602 1633
@@ -1645,7 +1676,8 @@ static int elf_core_dump(long signr, struct pt_regs *regs, struct file *file)
1645 /* Align to page */ 1676 /* Align to page */
1646 DUMP_SEEK(dataoff - foffset); 1677 DUMP_SEEK(dataoff - foffset);
1647 1678
1648 for (vma = current->mm->mmap; vma != NULL; vma = vma->vm_next) { 1679 for (vma = first_vma(current, gate_vma); vma != NULL;
1680 vma = next_vma(vma, gate_vma)) {
1649 unsigned long addr; 1681 unsigned long addr;
1650 1682
1651 if (!maydump(vma)) 1683 if (!maydump(vma))