diff options
author | Roland McGrath <roland@redhat.com> | 2007-01-26 03:56:49 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@woody.linux-foundation.org> | 2007-01-26 16:50:58 -0500 |
commit | f47aef55d9a18945fcdd7fd6bf01121ce973b91b (patch) | |
tree | 69f5f6c1fd4ae27d18344ae4b33b5c7bd4b18699 /fs | |
parent | e5b97dde514f9bd43f9e525451d0a863c4fc8a9a (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')
-rw-r--r-- | fs/binfmt_elf.c | 38 |
1 files changed, 35 insertions, 3 deletions
diff --git a/fs/binfmt_elf.c b/fs/binfmt_elf.c index 6fec8bfa6ba..90461f49e90 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 | ||
1431 | static 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 | */ | ||
1444 | static 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)) |