ia64/linux-2.6.18-xen.hg

changeset 520:906b14e26f2f

Fix inclusion of VDSO in core dumps.

This makes backtraces useful when they touch the VDSO.

Patch taken from linux-2.6-misc-fix-vdso-in-core-dumps.patch by Roland
McGrath in RHEL 5.

Signed-off-by: Ian Campbell <ian.campbell@citrix.com>
CC: Roland McGrath <roland@redhat.com>
CC: Hollis Blanchard <hollisb@us.ibm.com>
author Keir Fraser <keir.fraser@citrix.com>
date Tue Apr 15 15:15:26 2008 +0100 (2008-04-15)
parents d71965a78c20
children e5f0712d7520
files arch/i386/kernel/sysenter.c arch/powerpc/kernel/vdso.c arch/x86_64/ia32/ia32_binfmt.c arch/x86_64/ia32/syscall32.c fs/binfmt_elf.c include/asm-i386/elf.h include/linux/mm.h
line diff
     1.1 --- a/arch/i386/kernel/sysenter.c	Mon Apr 14 10:00:58 2008 +0100
     1.2 +++ b/arch/i386/kernel/sysenter.c	Tue Apr 15 15:15:26 2008 +0100
     1.3 @@ -109,11 +109,6 @@ int __init sysenter_setup(void)
     1.4  #ifdef CONFIG_COMPAT_VDSO
     1.5  	__set_fixmap(FIX_VDSO, __pa(syscall_page), PAGE_READONLY);
     1.6  	printk("Compat vDSO mapped to %08lx.\n", __fix_to_virt(FIX_VDSO));
     1.7 -#else
     1.8 -	/*
     1.9 -	 * In the non-compat case the ELF coredumping code needs the fixmap:
    1.10 -	 */
    1.11 -	__set_fixmap(FIX_VDSO, __pa(syscall_page), PAGE_KERNEL_RO);
    1.12  #endif
    1.13  
    1.14  	if (!boot_cpu_has(X86_FEATURE_SEP)) {
    1.15 @@ -176,6 +171,13 @@ int arch_setup_additional_pages(struct l
    1.16  	vma->vm_end = addr + PAGE_SIZE;
    1.17  	/* MAYWRITE to allow gdb to COW and set breakpoints */
    1.18  	vma->vm_flags = VM_READ|VM_EXEC|VM_MAYREAD|VM_MAYEXEC|VM_MAYWRITE;
    1.19 +	/*
    1.20 +	 * Make sure the vDSO gets into every core dump.
    1.21 +	 * Dumping its contents makes post-mortem fully interpretable later
    1.22 +	 * without matching up the same kernel and hardware config to see
    1.23 +	 * what PC values meant.
    1.24 +	 */
    1.25 +	vma->vm_flags |= VM_ALWAYSDUMP;
    1.26  	vma->vm_flags |= mm->def_flags;
    1.27  	vma->vm_page_prot = protection_map[vma->vm_flags & 7];
    1.28  	vma->vm_ops = &syscall_vm_ops;
     2.1 --- a/arch/powerpc/kernel/vdso.c	Mon Apr 14 10:00:58 2008 +0100
     2.2 +++ b/arch/powerpc/kernel/vdso.c	Tue Apr 15 15:15:26 2008 +0100
     2.3 @@ -282,6 +282,13 @@ int arch_setup_additional_pages(struct l
     2.4  	 * pages though
     2.5  	 */
     2.6  	vma->vm_flags = VM_READ|VM_EXEC|VM_MAYREAD|VM_MAYWRITE|VM_MAYEXEC;
     2.7 +	/*
     2.8 +	 * Make sure the vDSO gets into every core dump.
     2.9 +	 * Dumping its contents makes post-mortem fully interpretable later
    2.10 +	 * without matching up the same kernel and hardware config to see
    2.11 +	 * what PC values meant.
    2.12 +	 */
    2.13 +	vma->vm_flags |= VM_ALWAYSDUMP;
    2.14  	vma->vm_flags |= mm->def_flags;
    2.15  	vma->vm_page_prot = protection_map[vma->vm_flags & 0x7];
    2.16  	vma->vm_ops = &vdso_vmops;
     3.1 --- a/arch/x86_64/ia32/ia32_binfmt.c	Mon Apr 14 10:00:58 2008 +0100
     3.2 +++ b/arch/x86_64/ia32/ia32_binfmt.c	Tue Apr 15 15:15:26 2008 +0100
     3.3 @@ -65,55 +65,6 @@ typedef unsigned int elf_greg_t;
     3.4  #define ELF_NGREG (sizeof (struct user_regs_struct32) / sizeof(elf_greg_t))
     3.5  typedef elf_greg_t elf_gregset_t[ELF_NGREG];
     3.6  
     3.7 -/*
     3.8 - * These macros parameterize elf_core_dump in fs/binfmt_elf.c to write out
     3.9 - * extra segments containing the vsyscall DSO contents.  Dumping its
    3.10 - * contents makes post-mortem fully interpretable later without matching up
    3.11 - * the same kernel and hardware config to see what PC values meant.
    3.12 - * Dumping its extra ELF program headers includes all the other information
    3.13 - * a debugger needs to easily find how the vsyscall DSO was being used.
    3.14 - */
    3.15 -#define ELF_CORE_EXTRA_PHDRS	(find_vma(current->mm, VSYSCALL32_BASE) ?     \
    3.16 -    (VSYSCALL32_EHDR->e_phnum) : 0)
    3.17 -#define ELF_CORE_WRITE_EXTRA_PHDRS					      \
    3.18 -do {									      \
    3.19 -	if (find_vma(current->mm, VSYSCALL32_BASE)) { 			      \
    3.20 -		const struct elf32_phdr *const vsyscall_phdrs =		      \
    3.21 -			(const struct elf32_phdr *) (VSYSCALL32_BASE	      \
    3.22 -						   + VSYSCALL32_EHDR->e_phoff);\
    3.23 -		int i;							      \
    3.24 -		Elf32_Off ofs = 0;					      \
    3.25 -		for (i = 0; i < VSYSCALL32_EHDR->e_phnum; ++i) {	      \
    3.26 -			struct elf32_phdr phdr = vsyscall_phdrs[i];	      \
    3.27 -			if (phdr.p_type == PT_LOAD) {			      \
    3.28 -				BUG_ON(ofs != 0);			      \
    3.29 -				ofs = phdr.p_offset = offset;		      \
    3.30 -				phdr.p_memsz = PAGE_ALIGN(phdr.p_memsz);      \
    3.31 -				phdr.p_filesz = phdr.p_memsz;		      \
    3.32 -				offset += phdr.p_filesz;		      \
    3.33 -			}						      \
    3.34 -			else						      \
    3.35 -				phdr.p_offset += ofs;			      \
    3.36 -			phdr.p_paddr = 0; /* match other core phdrs */	      \
    3.37 -			DUMP_WRITE(&phdr, sizeof(phdr));		      \
    3.38 -		}							      \
    3.39 -	}								      \
    3.40 -} while (0)
    3.41 -#define ELF_CORE_WRITE_EXTRA_DATA					      \
    3.42 -do {									      \
    3.43 -	if (find_vma(current->mm, VSYSCALL32_BASE)) { 			      \
    3.44 -		const struct elf32_phdr *const vsyscall_phdrs =		      \
    3.45 -			(const struct elf32_phdr *) (VSYSCALL32_BASE	      \
    3.46 -						   + VSYSCALL32_EHDR->e_phoff);      \
    3.47 -		int i;							      \
    3.48 -		for (i = 0; i < VSYSCALL32_EHDR->e_phnum; ++i) {	      \
    3.49 -			if (vsyscall_phdrs[i].p_type == PT_LOAD)	      \
    3.50 -				DUMP_WRITE((void *) (u64) vsyscall_phdrs[i].p_vaddr,\
    3.51 -				    PAGE_ALIGN(vsyscall_phdrs[i].p_memsz));   \
    3.52 -		}							      \
    3.53 -	}								      \
    3.54 -} while (0)
    3.55 -
    3.56  struct elf_siginfo
    3.57  {
    3.58  	int	si_signo;			/* signal number */
     4.1 --- a/arch/x86_64/ia32/syscall32.c	Mon Apr 14 10:00:58 2008 +0100
     4.2 +++ b/arch/x86_64/ia32/syscall32.c	Tue Apr 15 15:15:26 2008 +0100
     4.3 @@ -59,6 +59,13 @@ int syscall32_setup_pages(struct linux_b
     4.4  	vma->vm_end = VSYSCALL32_END;
     4.5  	/* MAYWRITE to allow gdb to COW and set breakpoints */
     4.6  	vma->vm_flags = VM_READ|VM_EXEC|VM_MAYREAD|VM_MAYEXEC|VM_MAYWRITE;
     4.7 +	/*
     4.8 +	 * Make sure the vDSO gets into every core dump.
     4.9 +	 * Dumping its contents makes post-mortem fully interpretable later
    4.10 +	 * without matching up the same kernel and hardware config to see
    4.11 +	 * what PC values meant.
    4.12 +	 */
    4.13 +	vma->vm_flags |= VM_ALWAYSDUMP;
    4.14  	vma->vm_flags |= mm->def_flags;
    4.15  	vma->vm_page_prot = protection_map[vma->vm_flags & 7];
    4.16  	vma->vm_ops = &syscall32_vm_ops;
     5.1 --- a/fs/binfmt_elf.c	Mon Apr 14 10:00:58 2008 +0100
     5.2 +++ b/fs/binfmt_elf.c	Tue Apr 15 15:15:26 2008 +0100
     5.3 @@ -1170,6 +1170,10 @@ static int dump_seek(struct file *file, 
     5.4   */
     5.5  static int maydump(struct vm_area_struct *vma)
     5.6  {
     5.7 +	/* The vma can be set up to tell us the answer directly.  */
     5.8 +	if (vma->vm_flags & VM_ALWAYSDUMP)
     5.9 +		return 1;
    5.10 +
    5.11  	/* Do not dump I/O mapped devices or special mappings */
    5.12  	if (vma->vm_flags & (VM_IO | VM_RESERVED))
    5.13  		return 0;
     6.1 --- a/include/asm-i386/elf.h	Mon Apr 14 10:00:58 2008 +0100
     6.2 +++ b/include/asm-i386/elf.h	Tue Apr 15 15:15:26 2008 +0100
     6.3 @@ -169,50 +169,6 @@ do if (vdso_enabled) {						\
     6.4  		NEW_AUX_ENT(AT_SYSINFO_EHDR, VDSO_COMPAT_BASE);	\
     6.5  } while (0)
     6.6  
     6.7 -/*
     6.8 - * These macros parameterize elf_core_dump in fs/binfmt_elf.c to write out
     6.9 - * extra segments containing the vsyscall DSO contents.  Dumping its
    6.10 - * contents makes post-mortem fully interpretable later without matching up
    6.11 - * the same kernel and hardware config to see what PC values meant.
    6.12 - * Dumping its extra ELF program headers includes all the other information
    6.13 - * a debugger needs to easily find how the vsyscall DSO was being used.
    6.14 - */
    6.15 -#define ELF_CORE_EXTRA_PHDRS		(VDSO_HIGH_EHDR->e_phnum)
    6.16 -#define ELF_CORE_WRITE_EXTRA_PHDRS					      \
    6.17 -do {									      \
    6.18 -	const struct elf_phdr *const vsyscall_phdrs =			      \
    6.19 -		(const struct elf_phdr *) (VDSO_HIGH_BASE		      \
    6.20 -					   + VDSO_HIGH_EHDR->e_phoff);    \
    6.21 -	int i;								      \
    6.22 -	Elf32_Off ofs = 0;						      \
    6.23 -	for (i = 0; i < VDSO_HIGH_EHDR->e_phnum; ++i) {		      \
    6.24 -		struct elf_phdr phdr = vsyscall_phdrs[i];		      \
    6.25 -		if (phdr.p_type == PT_LOAD) {				      \
    6.26 -			BUG_ON(ofs != 0);				      \
    6.27 -			ofs = phdr.p_offset = offset;			      \
    6.28 -			phdr.p_memsz = PAGE_ALIGN(phdr.p_memsz);	      \
    6.29 -			phdr.p_filesz = phdr.p_memsz;			      \
    6.30 -			offset += phdr.p_filesz;			      \
    6.31 -		}							      \
    6.32 -		else							      \
    6.33 -			phdr.p_offset += ofs;				      \
    6.34 -		phdr.p_paddr = 0; /* match other core phdrs */		      \
    6.35 -		DUMP_WRITE(&phdr, sizeof(phdr));			      \
    6.36 -	}								      \
    6.37 -} while (0)
    6.38 -#define ELF_CORE_WRITE_EXTRA_DATA					      \
    6.39 -do {									      \
    6.40 -	const struct elf_phdr *const vsyscall_phdrs =			      \
    6.41 -		(const struct elf_phdr *) (VDSO_HIGH_BASE		      \
    6.42 -					   + VDSO_HIGH_EHDR->e_phoff);    \
    6.43 -	int i;								      \
    6.44 -	for (i = 0; i < VDSO_HIGH_EHDR->e_phnum; ++i) {		      \
    6.45 -		if (vsyscall_phdrs[i].p_type == PT_LOAD)		      \
    6.46 -			DUMP_WRITE((void *) vsyscall_phdrs[i].p_vaddr,	      \
    6.47 -				   PAGE_ALIGN(vsyscall_phdrs[i].p_memsz));    \
    6.48 -	}								      \
    6.49 -} while (0)
    6.50 -
    6.51  #endif
    6.52  
    6.53  #endif
     7.1 --- a/include/linux/mm.h	Mon Apr 14 10:00:58 2008 +0100
     7.2 +++ b/include/linux/mm.h	Tue Apr 15 15:15:26 2008 +0100
     7.3 @@ -167,6 +167,7 @@ extern unsigned int kobjsize(const void 
     7.4  #ifdef CONFIG_XEN
     7.5  #define VM_FOREIGN	0x04000000	/* Has pages belonging to another VM */
     7.6  #endif
     7.7 +#define VM_ALWAYSDUMP	0x08000000	/* Always include in core dumps */
     7.8  
     7.9  #ifndef VM_STACK_DEFAULT_FLAGS		/* arch can override this */
    7.10  #define VM_STACK_DEFAULT_FLAGS VM_DATA_DEFAULT_FLAGS