mirror of
https://github.com/torvalds/linux.git
synced 2024-11-11 22:51:42 +00:00
[PATCH] x86_64 ia32 vDSO: use VM_ALWAYSDUMP
This patch fixes ia32 core dumps on x86_64 to include just one phdr for the vDSO vma. Currently it writes a confused format with two phdrs for the address, one without contents and one with. This patch removes the special-case core writing macros for the ia32 vDSO. Instead, it uses VM_ALWAYSDUMP in the vma. This changes core dumps so they no longer include the non-PT_LOAD phdrs from the vDSO, consistent with fixed native i386 core dumps. 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>
This commit is contained in:
parent
f47aef55d9
commit
e03f0ca116
@ -64,55 +64,6 @@ typedef unsigned int elf_greg_t;
|
||||
#define ELF_NGREG (sizeof (struct user_regs_struct32) / sizeof(elf_greg_t))
|
||||
typedef elf_greg_t elf_gregset_t[ELF_NGREG];
|
||||
|
||||
/*
|
||||
* These macros parameterize elf_core_dump in fs/binfmt_elf.c to write out
|
||||
* extra segments containing the vsyscall DSO contents. Dumping its
|
||||
* contents makes post-mortem fully interpretable later without matching up
|
||||
* the same kernel and hardware config to see what PC values meant.
|
||||
* Dumping its extra ELF program headers includes all the other information
|
||||
* a debugger needs to easily find how the vsyscall DSO was being used.
|
||||
*/
|
||||
#define ELF_CORE_EXTRA_PHDRS (find_vma(current->mm, VSYSCALL32_BASE) ? \
|
||||
(VSYSCALL32_EHDR->e_phnum) : 0)
|
||||
#define ELF_CORE_WRITE_EXTRA_PHDRS \
|
||||
do { \
|
||||
if (find_vma(current->mm, VSYSCALL32_BASE)) { \
|
||||
const struct elf32_phdr *const vsyscall_phdrs = \
|
||||
(const struct elf32_phdr *) (VSYSCALL32_BASE \
|
||||
+ VSYSCALL32_EHDR->e_phoff);\
|
||||
int i; \
|
||||
Elf32_Off ofs = 0; \
|
||||
for (i = 0; i < VSYSCALL32_EHDR->e_phnum; ++i) { \
|
||||
struct elf32_phdr phdr = vsyscall_phdrs[i]; \
|
||||
if (phdr.p_type == PT_LOAD) { \
|
||||
BUG_ON(ofs != 0); \
|
||||
ofs = phdr.p_offset = offset; \
|
||||
phdr.p_memsz = PAGE_ALIGN(phdr.p_memsz); \
|
||||
phdr.p_filesz = phdr.p_memsz; \
|
||||
offset += phdr.p_filesz; \
|
||||
} \
|
||||
else \
|
||||
phdr.p_offset += ofs; \
|
||||
phdr.p_paddr = 0; /* match other core phdrs */ \
|
||||
DUMP_WRITE(&phdr, sizeof(phdr)); \
|
||||
} \
|
||||
} \
|
||||
} while (0)
|
||||
#define ELF_CORE_WRITE_EXTRA_DATA \
|
||||
do { \
|
||||
if (find_vma(current->mm, VSYSCALL32_BASE)) { \
|
||||
const struct elf32_phdr *const vsyscall_phdrs = \
|
||||
(const struct elf32_phdr *) (VSYSCALL32_BASE \
|
||||
+ VSYSCALL32_EHDR->e_phoff); \
|
||||
int i; \
|
||||
for (i = 0; i < VSYSCALL32_EHDR->e_phnum; ++i) { \
|
||||
if (vsyscall_phdrs[i].p_type == PT_LOAD) \
|
||||
DUMP_WRITE((void *) (u64) vsyscall_phdrs[i].p_vaddr,\
|
||||
PAGE_ALIGN(vsyscall_phdrs[i].p_memsz)); \
|
||||
} \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
struct elf_siginfo
|
||||
{
|
||||
int si_signo; /* signal number */
|
||||
|
@ -59,6 +59,13 @@ int syscall32_setup_pages(struct linux_binprm *bprm, int exstack)
|
||||
vma->vm_end = VSYSCALL32_END;
|
||||
/* MAYWRITE to allow gdb to COW and set breakpoints */
|
||||
vma->vm_flags = VM_READ|VM_EXEC|VM_MAYREAD|VM_MAYEXEC|VM_MAYWRITE;
|
||||
/*
|
||||
* Make sure the vDSO gets into every core dump.
|
||||
* Dumping its contents makes post-mortem fully interpretable later
|
||||
* without matching up the same kernel and hardware config to see
|
||||
* what PC values meant.
|
||||
*/
|
||||
vma->vm_flags |= VM_ALWAYSDUMP;
|
||||
vma->vm_flags |= mm->def_flags;
|
||||
vma->vm_page_prot = protection_map[vma->vm_flags & 7];
|
||||
vma->vm_ops = &syscall32_vm_ops;
|
||||
|
Loading…
Reference in New Issue
Block a user