[PATCH 4/4] elf core: Rewrite offset and segs initialization simply

From: HATAYAMA Daisuke
Date: Wed Dec 29 2010 - 16:26:05 EST


Offset handling here has so far been scattered so difficult to
understand how foffset and dataoff variables are initialized at first
sight. Now section header table moved to next to ELF header, offset
handling can be rewritten more simply. This patch initializes foffset
and dataoff variables without using offset variable. Also, rewrite
segs initialization simply.

Signed-off-by: HATAYAMA Daisuke <d.hatayama@xxxxxxxxxxxxxx>
---
fs/binfmt_elf.c | 44 ++++++++++++++++++--------------------------
fs/binfmt_elf_fdpic.c | 42 ++++++++++++++++--------------------------
2 files changed, 34 insertions(+), 52 deletions(-)

diff --git a/fs/binfmt_elf.c b/fs/binfmt_elf.c
index 3ba6838..710abdc 100644
--- a/fs/binfmt_elf.c
+++ b/fs/binfmt_elf.c
@@ -1874,10 +1874,10 @@ static int elf_core_dump(struct coredump_params *cprm)
int has_dumped = 0;
mm_segment_t fs;
int segs;
- size_t size = 0;
+ size_t size = 0, note_size;
struct vm_area_struct *vma, *gate_vma;
struct elfhdr *elf = NULL;
- loff_t offset = 0, dataoff, foffset;
+ loff_t offset, dataoff, foffset;
struct elf_note_info info;
struct elf_phdr *phdr4note = NULL;
struct elf_shdr *shdr0 = NULL;
@@ -1898,19 +1898,17 @@ static int elf_core_dump(struct coredump_params *cprm)
elf = kmalloc(sizeof(*elf), GFP_KERNEL);
if (!elf)
goto out;
+
+ gate_vma = get_gate_vma(current);
+
/*
* The number of segs are recored into ELF header as 16bit value.
* Please check DEFAULT_MAX_MAP_COUNT definition when you modify here.
*/
- segs = current->mm->map_count;
- segs += elf_core_extra_phdrs();
-
- gate_vma = get_gate_vma(current);
- if (gate_vma != NULL)
- segs++;
-
- /* for notes section */
- segs++;
+ segs = current->mm->map_count
+ + elf_core_extra_phdrs()
+ + (gate_vma ? 1 : 0)
+ + 1; /* for notes section */

/*
* Collect all the non-memory information about the process for the
@@ -1925,23 +1923,17 @@ static int elf_core_dump(struct coredump_params *cprm)
fs = get_fs();
set_fs(KERNEL_DS);

- foffset = offset = elf->e_phoff + segs * elf->e_phentsize;
+ note_size = get_note_info_size(&info)
+ + elf_coredump_extra_notes_size();

- /* Write notes phdr entry */
- {
- size_t sz = get_note_info_size(&info);
+ foffset = elf->e_phoff + segs * elf->e_phentsize;
+ dataoff = roundup(foffset + note_size, ELF_EXEC_PAGESIZE);
+ offset = dataoff;

- sz += elf_coredump_extra_notes_size();
-
- phdr4note = kmalloc(sizeof(*phdr4note), GFP_KERNEL);
- if (!phdr4note)
- goto end_coredump;
-
- fill_elf_note_phdr(phdr4note, sz, offset);
- offset += sz;
- }
-
- dataoff = offset = roundup(offset, ELF_EXEC_PAGESIZE);
+ phdr4note = kmalloc(sizeof(*phdr4note), GFP_KERNEL);
+ if (!phdr4note)
+ goto end_coredump;
+ fill_elf_note_phdr(phdr4note, note_size, foffset);

if (elf->e_shoff) {
shdr0 = kmalloc(sizeof(*shdr0), GFP_KERNEL);
diff --git a/fs/binfmt_elf_fdpic.c b/fs/binfmt_elf_fdpic.c
index 59c7284..971a39e 100644
--- a/fs/binfmt_elf_fdpic.c
+++ b/fs/binfmt_elf_fdpic.c
@@ -1596,11 +1596,11 @@ static int elf_fdpic_core_dump(struct
coredump_params *cprm)
int has_dumped = 0;
mm_segment_t fs;
int segs;
- size_t size = 0;
+ size_t size = 0, note_size;
int i;
struct vm_area_struct *vma;
struct elfhdr *elf = NULL;
- loff_t offset = 0, dataoff, foffset;
+ loff_t offset, dataoff, foffset;
int numnote;
struct memelfnote *notes = NULL;
struct elf_prstatus *prstatus = NULL; /* NT_PRSTATUS */
@@ -1678,11 +1678,9 @@ static int elf_fdpic_core_dump(struct
coredump_params *cprm)
fill_prstatus(prstatus, current, cprm->signr);
elf_core_copy_regs(&prstatus->pr_reg, cprm->regs);

- segs = current->mm->map_count;
- segs += elf_core_extra_phdrs();
-
- /* for notes section */
- segs++;
+ segs = current->mm->map_count
+ + elf_core_extra_phdrs()
+ + 1; /* for notes section */

/* Set up header */
fill_elf_fdpic_header(elf, segs);
@@ -1724,27 +1722,19 @@ static int elf_fdpic_core_dump(struct
coredump_params *cprm)
fs = get_fs();
set_fs(KERNEL_DS);

- foffset = offset = elf->e_phoff + segs * elf->e_phentsize;
-
- /* Write notes phdr entry */
- {
- int sz = 0;
-
- for (i = 0; i < numnote; i++)
- sz += notesize(notes + i);
-
- sz += thread_status_size;
-
- phdr4note = kmalloc(sizeof(*phdr4note), GFP_KERNEL);
- if (!phdr4note)
- goto end_coredump;
+ note_size = 0;
+ for (i = 0; i < numnote; i++)
+ note_size += notesize(notes + i);
+ note_size += thread_status_size;

- fill_elf_note_phdr(phdr4note, sz, offset);
- offset += sz;
- }
+ foffset = offset = elf->e_phoff + segs * elf->e_phentsize;
+ dataoff = roundup(foffset + note_size, ELF_EXEC_PAGESIZE);
+ offset = dataoff;

- /* Page-align dumped data */
- dataoff = offset = roundup(offset, ELF_EXEC_PAGESIZE);
+ phdr4note = kmalloc(sizeof(*phdr4note), GFP_KERNEL);
+ if (!phdr4note)
+ goto end_coredump;
+ fill_elf_note_phdr(phdr4note, note_size, foffset);

if (elf->e_shoff) {
shdr0 = kmalloc(sizeof(*shdr0), GFP_KERNEL);
--
1.7.1
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/