coredump: add a new elf note with siginfo of the signal
[deliverable/linux.git] / fs / binfmt_elf.c
index 4450e82a05aab4ae95f77f78fa8504a53b2f04cf..865f9be6a2d3d52064912083ee4cbf243c46515a 100644 (file)
 #include <asm/page.h>
 #include <asm/exec.h>
 
+#ifndef user_siginfo_t
+#define user_siginfo_t siginfo_t
+#endif
+
 static int load_elf_binary(struct linux_binprm *bprm, struct pt_regs *regs);
 static int load_elf_library(struct file *);
 static unsigned long elf_map(struct file *, unsigned long, struct elf_phdr *,
@@ -1372,6 +1376,16 @@ static void fill_auxv_note(struct memelfnote *note, struct mm_struct *mm)
        fill_note(note, "CORE", NT_AUXV, i * sizeof(elf_addr_t), auxv);
 }
 
+static void fill_siginfo_note(struct memelfnote *note, user_siginfo_t *csigdata,
+               siginfo_t *siginfo)
+{
+       mm_segment_t old_fs = get_fs();
+       set_fs(KERNEL_DS);
+       copy_siginfo_to_user((user_siginfo_t __user *) csigdata, siginfo);
+       set_fs(old_fs);
+       fill_note(note, "CORE", NT_SIGINFO, sizeof(*csigdata), csigdata);
+}
+
 #ifdef CORE_DUMP_USE_REGSET
 #include <linux/regset.h>
 
@@ -1385,7 +1399,9 @@ struct elf_thread_core_info {
 struct elf_note_info {
        struct elf_thread_core_info *thread;
        struct memelfnote psinfo;
+       struct memelfnote signote;
        struct memelfnote auxv;
+       user_siginfo_t csigdata;
        size_t size;
        int thread_notes;
 };
@@ -1559,6 +1575,9 @@ static int fill_note_info(struct elfhdr *elf, int phdrs,
        fill_psinfo(psinfo, dump_task->group_leader, dump_task->mm);
        info->size += notesize(&info->psinfo);
 
+       fill_siginfo_note(&info->signote, &info->csigdata, siginfo);
+       info->size += notesize(&info->signote);
+
        fill_auxv_note(&info->auxv, current->mm);
        info->size += notesize(&info->auxv);
 
@@ -1588,6 +1607,8 @@ static int write_note_info(struct elf_note_info *info,
 
                if (first && !writenote(&info->psinfo, file, foffset))
                        return 0;
+               if (first && !writenote(&info->signote, file, foffset))
+                       return 0;
                if (first && !writenote(&info->auxv, file, foffset))
                        return 0;
 
@@ -1681,6 +1702,7 @@ struct elf_note_info {
 #ifdef ELF_CORE_COPY_XFPREGS
        elf_fpxregset_t *xfpu;
 #endif
+       user_siginfo_t csigdata;
        int thread_status_size;
        int numnote;
 };
@@ -1690,8 +1712,8 @@ static int elf_note_info_init(struct elf_note_info *info)
        memset(info, 0, sizeof(*info));
        INIT_LIST_HEAD(&info->thread_list);
 
-       /* Allocate space for six ELF notes */
-       info->notes = kmalloc(6 * sizeof(struct memelfnote), GFP_KERNEL);
+       /* Allocate space for ELF notes */
+       info->notes = kmalloc(7 * sizeof(struct memelfnote), GFP_KERNEL);
        if (!info->notes)
                return 0;
        info->psinfo = kmalloc(sizeof(*info->psinfo), GFP_KERNEL);
@@ -1763,6 +1785,7 @@ static int fill_note_info(struct elfhdr *elf, int phdrs,
 
        info->numnote = 2;
 
+       fill_siginfo_note(&info->notes[info->numnote++], &info->csigdata, siginfo);
        fill_auxv_note(&info->notes[info->numnote++], current->mm);
 
        /* Try to dump the FPU. */
This page took 0.035385 seconds and 5 git commands to generate.