[Patch 2/21] Create elfcore-common.c for ELF class independent core generation helpers

Previous message: [thread] [date] [author]
Next message: [thread] [date] [author]
From: Suzuki K. Poulose
Date: Tuesday, December 14, 2010 - 2:57 am

Move the common code, shared by both native and compat ELF core generation code
to a single instance.These functions could be re-used later for application
core dump infrastructure.

Signed-off-by: Suzuki K. Poulose <suzuki@in.ibm.com>
---
 fs/Makefile                      |    1 
 fs/binfmt_elf.c                  |  129 ---------------------------------------
 fs/elfcore-common.c              |  126 ++++++++++++++++++++++++++++++++++++++
 include/linux/elfcore-internal.h |   35 ++++++++++
 4 files changed, 163 insertions(+), 128 deletions(-)

Index: linux-2.6.36-rc7/fs/binfmt_elf.c
===================================================================
--- linux-2.6.36-rc7.orig/fs/binfmt_elf.c
+++ linux-2.6.36-rc7/fs/binfmt_elf.c
@@ -46,6 +46,7 @@ static unsigned long elf_map(struct file
  * don't even try.
  */
 #ifdef CONFIG_ELF_CORE
+#include <linux/elfcore-internal.h>
 static int elf_core_dump(struct coredump_params *cprm);
 #else
 #define elf_core_dump	NULL
@@ -1087,98 +1088,6 @@ out:
  * Jeremy Fitzhardinge <jeremy@sw.oz.au>
  */
 
-/*
- * Decide what to dump of a segment, part, all or none.
- */
-static unsigned long vma_dump_size(struct vm_area_struct *vma,
-				   unsigned long mm_flags)
-{
-#define FILTER(type)	(mm_flags & (1UL << MMF_DUMP_##type))
-
-	/* The vma can be set up to tell us the answer directly.  */
-	if (vma->vm_flags & VM_ALWAYSDUMP)
-		goto whole;
-
-	/* Hugetlb memory check */
-	if (vma->vm_flags & VM_HUGETLB) {
-		if ((vma->vm_flags & VM_SHARED) && FILTER(HUGETLB_SHARED))
-			goto whole;
-		if (!(vma->vm_flags & VM_SHARED) && FILTER(HUGETLB_PRIVATE))
-			goto whole;
-	}
-
-	/* Do not dump I/O mapped devices or special mappings */
-	if (vma->vm_flags & (VM_IO | VM_RESERVED))
-		return 0;
-
-	/* By default, dump shared memory if mapped from an anonymous file. */
-	if (vma->vm_flags & VM_SHARED) {
-		if (vma->vm_file->f_path.dentry->d_inode->i_nlink == 0 ?
-		    FILTER(ANON_SHARED) : FILTER(MAPPED_SHARED))
-			goto whole;
-		return 0;
-	}
-
-	/* Dump segments that have been written to.  */
-	if (vma->anon_vma && FILTER(ANON_PRIVATE))
-		goto whole;
-	if (vma->vm_file == NULL)
-		return 0;
-
-	if (FILTER(MAPPED_PRIVATE))
-		goto whole;
-
-	/*
-	 * If this looks like the beginning of a DSO or executable mapping,
-	 * check for an ELF header.  If we find one, dump the first page to
-	 * aid in determining what was mapped here.
-	 */
-	if (FILTER(ELF_HEADERS) &&
-	    vma->vm_pgoff == 0 && (vma->vm_flags & VM_READ)) {
-		u32 __user *header = (u32 __user *) vma->vm_start;
-		u32 word;
-		mm_segment_t fs = get_fs();
-		/*
-		 * Doing it this way gets the constant folded by GCC.
-		 */
-		union {
-			u32 cmp;
-			char elfmag[SELFMAG];
-		} magic;
-		BUILD_BUG_ON(SELFMAG != sizeof word);
-		magic.elfmag[EI_MAG0] = ELFMAG0;
-		magic.elfmag[EI_MAG1] = ELFMAG1;
-		magic.elfmag[EI_MAG2] = ELFMAG2;
-		magic.elfmag[EI_MAG3] = ELFMAG3;
-		/*
-		 * Switch to the user "segment" for get_user(),
-		 * then put back what elf_core_dump() had in place.
-		 */
-		set_fs(USER_DS);
-		if (unlikely(get_user(word, header)))
-			word = 0;
-		set_fs(fs);
-		if (word == magic.cmp)
-			return PAGE_SIZE;
-	}
-
-#undef	FILTER
-
-	return 0;
-
-whole:
-	return vma->vm_end - vma->vm_start;
-}
-
-/* An ELF note in memory */
-struct memelfnote
-{
-	const char *name;
-	int type;
-	unsigned int datasz;
-	void *data;
-};
-
 static int notesize(struct memelfnote *en)
 {
 	int sz;
@@ -1256,16 +1165,6 @@ static void fill_elf_note_phdr(struct el
 	return;
 }
 
-static void fill_note(struct memelfnote *note, const char *name, int type, 
-		unsigned int sz, void *data)
-{
-	note->name = name;
-	note->type = type;
-	note->datasz = sz;
-	note->data = data;
-	return;
-}
-
 /*
  * fill up all the fields in prstatus from the given task struct, except
  * registers which need to be filled up separately.
@@ -1812,32 +1711,6 @@ static void free_note_info(struct elf_no
 
 #endif
 
-static struct vm_area_struct *first_vma(struct task_struct *tsk,
-					struct vm_area_struct *gate_vma)
-{
-	struct vm_area_struct *ret = tsk->mm->mmap;
-
-	if (ret)
-		return ret;
-	return gate_vma;
-}
-/*
- * Helper function for iterating across a vma list.  It ensures that the caller
- * will visit `gate_vma' prior to terminating the search.
- */
-static struct vm_area_struct *next_vma(struct vm_area_struct *this_vma,
-					struct vm_area_struct *gate_vma)
-{
-	struct vm_area_struct *ret;
-
-	ret = this_vma->vm_next;
-	if (ret)
-		return ret;
-	if (this_vma == gate_vma)
-		return NULL;
-	return gate_vma;
-}
-
 static void fill_extnum_info(struct elfhdr *elf, struct elf_shdr *shdr4extnum,
 			     elf_addr_t e_shoff, int segs)
 {
Index: linux-2.6.36-rc7/fs/elfcore-common.c
===================================================================
--- /dev/null
+++ linux-2.6.36-rc7/fs/elfcore-common.c
@@ -0,0 +1,131 @@
+/*
+ * Copyright 1993, 1994: Eric Youngdale (ericy@cais.com).
+ *
+ * Initial write up for ELF_CORE :
+ * Modelled on fs/exec.c:aout_core_dump()
+ *	 Jeremy Fitzhardinge <jeremy@sw.oz.au>
+ *
+ * Moved common routines used by both native and compat ELF core generation
+ * from binfmt_elf.c to a single instance.
+ *	Suzuki K. Poulose <suzuki@in.ibm.com>
+ */
+
+#include <linux/mm.h>
+#include <linux/mman.h>
+#include <linux/sched.h>
+#include <linux/fs.h>
+#include <linux/elf.h>
+#include <asm/uaccess.h>
+#include <asm/param.h>
+#include <asm/page.h>
+
+#include <linux/elfcore-internal.h>
+
+struct vm_area_struct *first_vma(struct task_struct *tsk,
+					struct vm_area_struct *gate_vma)
+{
+	struct vm_area_struct *ret = tsk->mm->mmap;
+
+	if (ret)
+		return ret;
+	return gate_vma;
+}
+/*
+ * Helper function for iterating across a vma list.  It ensures that the caller
+ * will visit `gate_vma' prior to terminating the search.
+ */
+struct vm_area_struct *next_vma(struct vm_area_struct *this_vma,
+					struct vm_area_struct *gate_vma)
+{
+	struct vm_area_struct *ret;
+
+	ret = this_vma->vm_next;
+	if (ret)
+		return ret;
+	if (this_vma == gate_vma)
+		return NULL;
+	return gate_vma;
+}
+
+/*
+ * Decide what to dump of a segment, part, all or none.
+ */
+unsigned long vma_dump_size(struct vm_area_struct *vma,
+					 unsigned long mm_flags)
+{
+#define FILTER(type)	(mm_flags & (1UL << MMF_DUMP_##type))
+
+	/* The vma can be set up to tell us the answer directly.  */
+	if (vma->vm_flags & VM_ALWAYSDUMP)
+		goto whole;
+
+	/* Hugetlb memory check */
+	if (vma->vm_flags & VM_HUGETLB) {
+		if ((vma->vm_flags & VM_SHARED) && FILTER(HUGETLB_SHARED))
+			goto whole;
+		if (!(vma->vm_flags & VM_SHARED) && FILTER(HUGETLB_PRIVATE))
+			goto whole;
+	}
+
+	/* Do not dump I/O mapped devices or special mappings */
+	if (vma->vm_flags & (VM_IO | VM_RESERVED))
+		return 0;
+
+	/* By default, dump shared memory if mapped from an anonymous file. */
+	if (vma->vm_flags & VM_SHARED) {
+		if (vma->vm_file->f_path.dentry->d_inode->i_nlink == 0 ?
+		    FILTER(ANON_SHARED) : FILTER(MAPPED_SHARED))
+			goto whole;
+		return 0;
+	}
+
+	/* Dump segments that have been written to.  */
+	if (vma->anon_vma && FILTER(ANON_PRIVATE))
+		goto whole;
+	if (vma->vm_file == NULL)
+		return 0;
+
+	if (FILTER(MAPPED_PRIVATE))
+		goto whole;
+
+	/*
+	 * If this looks like the beginning of a DSO or executable mapping,
+	 * check for an ELF header.  If we find one, dump the first page to
+	 * aid in determining what was mapped here.
+	 */
+	if (FILTER(ELF_HEADERS) &&
+	    vma->vm_pgoff == 0 && (vma->vm_flags & VM_READ)) {
+		u32 __user *header = (u32 __user *) vma->vm_start;
+		u32 word;
+		mm_segment_t fs = get_fs();
+		/*
+		 * Doing it this way gets the constant folded by GCC.
+		 */
+		union {
+			u32 cmp;
+			char elfmag[SELFMAG];
+		} magic;
+		BUILD_BUG_ON(SELFMAG != sizeof word);
+		magic.elfmag[EI_MAG0] = ELFMAG0;
+		magic.elfmag[EI_MAG1] = ELFMAG1;
+		magic.elfmag[EI_MAG2] = ELFMAG2;
+		magic.elfmag[EI_MAG3] = ELFMAG3;
+		/*
+		 * Switch to the user "segment" for get_user(),
+		 * then put back what elf_core_dump() had in place.
+		 */
+		set_fs(USER_DS);
+		if (unlikely(get_user(word, header)))
+			word = 0;
+		set_fs(fs);
+		if (word == magic.cmp)
+			return PAGE_SIZE;
+	}
+
+#undef	FILTER
+
+	return 0;
+
+whole:
+	return vma->vm_end - vma->vm_start;
+}
Index: linux-2.6.36-rc7/include/linux/elfcore-internal.h
===================================================================
--- /dev/null
+++ linux-2.6.36-rc7/include/linux/elfcore-internal.h
@@ -0,0 +1,44 @@
+/*
+ * Common routines for native and compat elf core generation.
+ *
+ * Copyright 1993, 1994: Eric Youngdale (ericy@cais.com).
+ *
+ * Modelled on fs/exec.c:aout_core_dump()
+ * Jeremy Fitzhardinge <jeremy@sw.oz.au>
+ *
+ * Moved the common routines from binfmt_elf.c to elfcore-common.c
+ *  - Suzuki K. Poulose <suzuki@in.ibm.com>
+ */
+
+#ifndef __ELF_CORE_INTERNAL_H
+#define __ELF_CORE_INTERNAL_H
+
+#ifdef __KERNEL__
+
+/* An ELF note in memory */
+struct memelfnote
+{
+	const char *name;
+	int type;
+	unsigned int datasz;
+	void *data;
+};
+
+static inline void fill_note(struct memelfnote *note, const char *name,
+				int type, unsigned int sz, void *data)
+{
+	note->name = name;
+	note->type = type;
+	note->datasz = sz;
+	note->data = data;
+}
+
+extern struct vm_area_struct *first_vma(struct task_struct *tsk,
+					struct vm_area_struct *gate_vma);
+extern struct vm_area_struct *next_vma(struct vm_area_struct *this_vma,
+					struct vm_area_struct *gate_vma);
+extern unsigned long vma_dump_size(struct vm_area_struct *vma,
+					 unsigned long mm_flags);
+
+#endif
+#endif
Index: linux-2.6.36-rc7/fs/Makefile
===================================================================
--- linux-2.6.36-rc7.orig/fs/Makefile
+++ linux-2.6.36-rc7/fs/Makefile
@@ -42,6 +42,7 @@ obj-y				+= binfmt_script.o
 
 obj-$(CONFIG_BINFMT_ELF)	+= binfmt_elf.o
 obj-$(CONFIG_COMPAT_BINFMT_ELF)	+= compat_binfmt_elf.o
+obj-$(CONFIG_ELF_CORE)		+= elfcore-common.o
 obj-$(CONFIG_BINFMT_ELF_FDPIC)	+= binfmt_elf_fdpic.o
 obj-$(CONFIG_BINFMT_SOM)	+= binfmt_som.o
 obj-$(CONFIG_BINFMT_FLAT)	+= binfmt_flat.o
--
Previous message: [thread] [date] [author]
Next message: [thread] [date] [author]

Messages in current thread:
[RFC] [Patch 0/21] Non disruptive application core dump in ..., Suzuki K. Poulose, (Tue Dec 14, 2:52 am)
[Patch 1/21] Reuse freezable() predicate, Suzuki K. Poulose, (Tue Dec 14, 2:54 am)
[Patch 2/21] Create elfcore-common.c for ELF class indepen ..., Suzuki K. Poulose, (Tue Dec 14, 2:57 am)
[Patch 3/21] Make vma_dump_size() generic, Suzuki K. Poulose, (Tue Dec 14, 3:00 am)
[Patch 4/21] Make fill_psinfo generic, Suzuki K. Poulose, (Tue Dec 14, 3:01 am)
[Patch 5/21] Rename compat versions of the reusable core g ..., Suzuki K. Poulose, (Tue Dec 14, 3:03 am)
[Patch 6/21] Export the reusable ELF core generation routines, Suzuki K. Poulose, (Tue Dec 14, 3:04 am)
[Patch 7/21] Define API for reading arch specif Program He ..., Suzuki K. Poulose, (Tue Dec 14, 3:05 am)
[Patch 8/21] ia64 Implementation of elf_core_copy_extra_ph ..., Suzuki K. Poulose, (Tue Dec 14, 3:08 am)
[Patch 9/21] UML (i386) Implementation of elf_core_copy_ex ..., Suzuki K. Poulose, (Tue Dec 14, 3:09 am)
[Patch 10/21] Create /proc/pid/core entry, Suzuki K. Poulose, (Tue Dec 14, 3:11 am)
[Patch 11/21] Track the core generation requests, Suzuki K. Poulose, (Tue Dec 14, 3:12 am)
[Patch 12/21] Check if the process is an ELF executable, Suzuki K. Poulose, (Tue Dec 14, 3:13 am)
[Patch 13/21] Freeze / Thaw threads, Suzuki K. Poulose, (Tue Dec 14, 3:15 am)
[Patch 14/21] Create ELF header, Suzuki K. Poulose, (Tue Dec 14, 3:16 am)
[Patch 15/21] Collect ELF Core notes data, Suzuki K. Poulose, (Tue Dec 14, 3:17 am)
[Patch 16/21] Wait for threads to freeze, Suzuki K. Poulose, (Tue Dec 14, 3:19 am)
[Patch 17/21] Calculate the size of the core file, Suzuki K. Poulose, (Tue Dec 14, 3:20 am)
[Patch 18/21] Generate the data sections for ELF Core, Suzuki K. Poulose, (Tue Dec 14, 3:22 am)
[Patch 19/21] Identify the ELF class of the process, Suzuki K. Poulose, (Tue Dec 14, 3:24 am)
[Patch 20/21] Add supporting for compat ELF class data str ..., Suzuki K. Poulose, (Tue Dec 14, 3:26 am)
[Patch 21/21] Compat ELF class Core generation support, Suzuki K. Poulose, (Tue Dec 14, 3:27 am)
Re: [Patch 10/21] Create /proc/pid/core entry, Cong Wang, (Tue Dec 14, 3:36 am)
Re: [Patch 11/21] Track the core generation requests, Alexey Dobriyan, (Tue Dec 14, 3:51 am)
Re: [RFC] [Patch 0/21] Non disruptive application core dum ..., Suzuki K. Poulose, (Tue Dec 14, 7:59 am)
Re: [Patch 10/21] Create /proc/pid/core entry, Suzuki K. Poulose, (Tue Dec 14, 8:02 am)
Re: [Patch 3/21] Make vma_dump_size() generic, Oleg Nesterov, (Tue Dec 14, 8:53 am)
Re: [Patch 4/21] Make fill_psinfo generic, Oleg Nesterov, (Tue Dec 14, 8:53 am)
Re: [Patch 4/21] Make fill_psinfo generic, Linus Torvalds, (Tue Dec 14, 8:55 am)
Re: [Patch 11/21] Track the core generation requests, Oleg Nesterov, (Tue Dec 14, 9:04 am)
Re: [Patch 13/21] Freeze / Thaw threads, Oleg Nesterov, (Tue Dec 14, 9:17 am)
Re: [Patch 14/21] Create ELF header, Oleg Nesterov, (Tue Dec 14, 9:24 am)
Re: [Patch 15/21] Collect ELF Core notes data, Oleg Nesterov, (Tue Dec 14, 9:37 am)
Re: [Patch 16/21] Wait for threads to freeze, Oleg Nesterov, (Tue Dec 14, 9:42 am)
Re: [RFC] [Patch 0/21] Non disruptive application core dum ..., KAMEZAWA Hiroyuki, (Tue Dec 14, 6:04 pm)
Re: [Patch 4/21] Make fill_psinfo generic, Suzuki K. Poulose, (Tue Dec 14, 7:22 pm)
Re: [Patch 5/21] Rename compat versions of the reusable co ..., Suzuki K. Poulose, (Tue Dec 14, 7:30 pm)
Re: [RFC] [Patch 0/21] Non disruptive application core dum ..., Suzuki K. Poulose, (Tue Dec 14, 10:24 pm)
Re: [RFC] [Patch 0/21] Non disruptive application core dum ..., Suzuki K. Poulose, (Tue Dec 14, 10:34 pm)
Re: [RFC] [Patch 0/21] Non disruptive application core dum ..., Suzuki K. Poulose, (Wed Dec 15, 4:26 am)
Re: [Patch 18/21] Generate the data sections for ELF Core, Suzuki K. Poulose, (Wed Dec 15, 5:46 am)
Re: [RFC] [Patch 0/21] Non disruptive application core dum ..., Suzuki K. Poulose, (Thu Dec 16, 12:57 am)