NEW_AUX_ENT(AT_SYSINFO_EHDR, (unsigned long) GATE_EHDR);                \
 } while (0)
 
-
-/*
- * These macros parameterize elf_core_dump in fs/binfmt_elf.c to write out
- * extra segments containing the gate 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 gate DSO was being used.
- */
-#define ELF_CORE_EXTRA_PHDRS           (GATE_EHDR->e_phnum)
-#define ELF_CORE_WRITE_EXTRA_PHDRS                                             \
-do {                                                                           \
-       const struct elf_phdr *const gate_phdrs =                             \
-               (const struct elf_phdr *) (GATE_ADDR + GATE_EHDR->e_phoff);   \
-       int i;                                                                  \
-       Elf64_Off ofs = 0;                                                    \
-       for (i = 0; i < GATE_EHDR->e_phnum; ++i) {                              \
-               struct elf_phdr phdr = gate_phdrs[i];                         \
-               if (phdr.p_type == PT_LOAD) {                                   \
-                       phdr.p_memsz = PAGE_ALIGN(phdr.p_memsz);              \
-                       phdr.p_filesz = phdr.p_memsz;                         \
-                       if (ofs == 0) {                                       \
-                               ofs = phdr.p_offset = offset;                 \
-                       offset += phdr.p_filesz;                                \
-               }                                                             \
-               else                                                          \
-                               phdr.p_offset = ofs;                          \
-               }                                                             \
-               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 {                                                                   \
-       const struct elf_phdr *const gate_phdrs =                             \
-               (const struct elf_phdr *) (GATE_ADDR + GATE_EHDR->e_phoff);   \
-       int i;                                                          \
-       for (i = 0; i < GATE_EHDR->e_phnum; ++i) {                      \
-               if (gate_phdrs[i].p_type == PT_LOAD) {                        \
-                       DUMP_WRITE((void *) gate_phdrs[i].p_vaddr,            \
-                                  PAGE_ALIGN(gate_phdrs[i].p_memsz));        \
-                       break;                                                \
-               }                                                             \
-       }                                                               \
-} while (0)
-
 /*
  * format for entries in the Global Offset Table
  */
 
 obj-$(CONFIG_DMAR)             += pci-dma.o
 obj-$(CONFIG_SWIOTLB)          += pci-swiotlb.o
 
+obj-$(CONFIG_BINFMT_ELF)       += elfcore.o
+
 # fp_emulate() expects f2-f5,f16-f31 to contain the user-level state.
 CFLAGS_traps.o  += -mfixed-range=f2-f5,f16-f31
 
 
--- /dev/null
+#include <linux/elf.h>
+#include <linux/coredump.h>
+#include <linux/fs.h>
+#include <linux/mm.h>
+
+#include <asm/elf.h>
+
+
+Elf64_Half elf_core_extra_phdrs(void)
+{
+       return GATE_EHDR->e_phnum;
+}
+
+int elf_core_write_extra_phdrs(struct file *file, loff_t offset, size_t *size,
+                              unsigned long limit)
+{
+       const struct elf_phdr *const gate_phdrs =
+               (const struct elf_phdr *) (GATE_ADDR + GATE_EHDR->e_phoff);
+       int i;
+       Elf64_Off ofs = 0;
+
+       for (i = 0; i < GATE_EHDR->e_phnum; ++i) {
+               struct elf_phdr phdr = gate_phdrs[i];
+
+               if (phdr.p_type == PT_LOAD) {
+                       phdr.p_memsz = PAGE_ALIGN(phdr.p_memsz);
+                       phdr.p_filesz = phdr.p_memsz;
+                       if (ofs == 0) {
+                               ofs = phdr.p_offset = offset;
+                               offset += phdr.p_filesz;
+                       } else {
+                               phdr.p_offset = ofs;
+                       }
+               } else {
+                       phdr.p_offset += ofs;
+               }
+               phdr.p_paddr = 0; /* match other core phdrs */
+               *size += sizeof(phdr);
+               if (*size > limit || !dump_write(file, &phdr, sizeof(phdr)))
+                       return 0;
+       }
+       return 1;
+}
+
+int elf_core_write_extra_data(struct file *file, size_t *size,
+                             unsigned long limit)
+{
+       const struct elf_phdr *const gate_phdrs =
+               (const struct elf_phdr *) (GATE_ADDR + GATE_EHDR->e_phoff);
+       int i;
+
+       for (i = 0; i < GATE_EHDR->e_phnum; ++i) {
+               if (gate_phdrs[i].p_type == PT_LOAD) {
+                       void *addr = (void *)gate_phdrs[i].p_vaddr;
+                       size_t memsz = PAGE_ALIGN(gate_phdrs[i].p_memsz);
+
+                       *size += memsz;
+                       if (*size > limit || !dump_write(file, addr, memsz))
+                               return 0;
+                       break;
+               }
+       }
+       return 1;
+}
 
        ptrace_user.o setjmp.o signal.o stub.o stub_segv.o syscalls.o sysrq.o \
        sys_call_table.o tls.o
 
+obj-$(CONFIG_BINFMT_ELF) += elfcore.o
+
 subarch-obj-y = lib/semaphore_32.o lib/string_32.o
 subarch-obj-$(CONFIG_HIGHMEM) += mm/highmem_32.o
 subarch-obj-$(CONFIG_MODULES) += kernel/module.o
 
        }                                                       \
 } while (0)
 
-/*
- * 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                                                 \
-       (vsyscall_ehdr ? (((struct elfhdr *)vsyscall_ehdr)->e_phnum) : 0 )
-
-#define ELF_CORE_WRITE_EXTRA_PHDRS                                           \
-if ( vsyscall_ehdr ) {                                                       \
-       const struct elfhdr *const ehdrp = (struct elfhdr *)vsyscall_ehdr;    \
-       const struct elf_phdr *const phdrp =                                  \
-               (const struct elf_phdr *) (vsyscall_ehdr + ehdrp->e_phoff);   \
-       int i;                                                                \
-       Elf32_Off ofs = 0;                                                    \
-       for (i = 0; i < ehdrp->e_phnum; ++i) {                                \
-               struct elf_phdr phdr = phdrp[i];                              \
-               if (phdr.p_type == PT_LOAD) {                                 \
-                       ofs = phdr.p_offset = offset;                         \
-                       offset += phdr.p_filesz;                              \
-               }                                                             \
-               else                                                          \
-                       phdr.p_offset += ofs;                                 \
-               phdr.p_paddr = 0; /* match other core phdrs */                \
-               DUMP_WRITE(&phdr, sizeof(phdr));                              \
-       }                                                                     \
-}
-#define ELF_CORE_WRITE_EXTRA_DATA                                            \
-if ( vsyscall_ehdr ) {                                                       \
-       const struct elfhdr *const ehdrp = (struct elfhdr *)vsyscall_ehdr;    \
-       const struct elf_phdr *const phdrp =                                  \
-               (const struct elf_phdr *) (vsyscall_ehdr + ehdrp->e_phoff);   \
-       int i;                                                                \
-       for (i = 0; i < ehdrp->e_phnum; ++i) {                                \
-               if (phdrp[i].p_type == PT_LOAD)                               \
-                       DUMP_WRITE((void *) phdrp[i].p_vaddr,                 \
-                                  phdrp[i].p_filesz);                        \
-       }                                                                     \
-}
-
 #endif
 
--- /dev/null
+#include <linux/elf.h>
+#include <linux/coredump.h>
+#include <linux/fs.h>
+#include <linux/mm.h>
+
+#include <asm/elf.h>
+
+
+Elf32_Half elf_core_extra_phdrs(void)
+{
+       return vsyscall_ehdr ? (((struct elfhdr *)vsyscall_ehdr)->e_phnum) : 0;
+}
+
+int elf_core_write_extra_phdrs(struct file *file, loff_t offset, size_t *size,
+                              unsigned long limit)
+{
+       if ( vsyscall_ehdr ) {
+               const struct elfhdr *const ehdrp =
+                       (struct elfhdr *) vsyscall_ehdr;
+               const struct elf_phdr *const phdrp =
+                       (const struct elf_phdr *) (vsyscall_ehdr + ehdrp->e_phoff);
+               int i;
+               Elf32_Off ofs = 0;
+
+               for (i = 0; i < ehdrp->e_phnum; ++i) {
+                       struct elf_phdr phdr = phdrp[i];
+
+                       if (phdr.p_type == PT_LOAD) {
+                               ofs = phdr.p_offset = offset;
+                               offset += phdr.p_filesz;
+                       } else {
+                               phdr.p_offset += ofs;
+                       }
+                       phdr.p_paddr = 0; /* match other core phdrs */
+                       *size += sizeof(phdr);
+                       if (*size > limit
+                           || !dump_write(file, &phdr, sizeof(phdr)))
+                               return 0;
+               }
+       }
+       return 1;
+}
+
+int elf_core_write_extra_data(struct file *file, size_t *size,
+                             unsigned long limit)
+{
+       if ( vsyscall_ehdr ) {
+               const struct elfhdr *const ehdrp =
+                       (struct elfhdr *) vsyscall_ehdr;
+               const struct elf_phdr *const phdrp =
+                       (const struct elf_phdr *) (vsyscall_ehdr + ehdrp->e_phoff);
+               int i;
+
+               for (i = 0; i < ehdrp->e_phnum; ++i) {
+                       if (phdrp[i].p_type == PT_LOAD) {
+                               void *addr = (void *) phdrp[i].p_vaddr;
+                               size_t filesz = phdrp[i].p_filesz;
+
+                               *size += filesz;
+                               if (*size > limit
+                                   || !dump_write(file, addr, filesz))
+                                       return 0;
+                       }
+               }
+       }
+       return 1;
+}
 
         * Please check DEFAULT_MAX_MAP_COUNT definition when you modify here.
         */
        segs = current->mm->map_count;
-#ifdef ELF_CORE_EXTRA_PHDRS
-       segs += ELF_CORE_EXTRA_PHDRS;
-#endif
+       segs += elf_core_extra_phdrs();
 
        gate_vma = get_gate_vma(current);
        if (gate_vma != NULL)
                        goto end_coredump;
        }
 
-#ifdef ELF_CORE_WRITE_EXTRA_PHDRS
-       ELF_CORE_WRITE_EXTRA_PHDRS;
-#endif
+       if (!elf_core_write_extra_phdrs(cprm->file, offset, &size, cprm->limit))
+               goto end_coredump;
 
        /* write out the notes section */
        if (!write_note_info(&info, cprm->file, &foffset))
                }
        }
 
-#ifdef ELF_CORE_WRITE_EXTRA_DATA
-       ELF_CORE_WRITE_EXTRA_DATA;
-#endif
+       if (!elf_core_write_extra_data(cprm->file, &size, cprm->limit))
+               goto end_coredump;
 
 end_coredump:
        set_fs(fs);
 
        elf_core_copy_regs(&prstatus->pr_reg, cprm->regs);
 
        segs = current->mm->map_count;
-#ifdef ELF_CORE_EXTRA_PHDRS
-       segs += ELF_CORE_EXTRA_PHDRS;
-#endif
+       segs += elf_core_extra_phdrs();
 
        /* Set up header */
        fill_elf_fdpic_header(elf, segs + 1);   /* including notes section */
                        goto end_coredump;
        }
 
-#ifdef ELF_CORE_WRITE_EXTRA_PHDRS
-       ELF_CORE_WRITE_EXTRA_PHDRS;
-#endif
+       if (!elf_core_write_extra_phdrs(cprm->file, offset, &size, cprm->limit))
+               goto end_coredump;
 
        /* write out the notes section */
        for (i = 0; i < numnote; i++)
                                    mm_flags) < 0)
                goto end_coredump;
 
-#ifdef ELF_CORE_WRITE_EXTRA_DATA
-       ELF_CORE_WRITE_EXTRA_DATA;
-#endif
+       if (!elf_core_write_extra_data(cprm->file, &size, cprm->limit))
+               goto end_coredump;
 
        if (cprm->file->f_pos != offset) {
                /* Sanity check */
 
 
 #undef elfhdr
 #undef elf_phdr
+#undef elf_shdr
 #undef elf_note
 #undef elf_addr_t
 #define elfhdr         elf32_hdr
 #define elf_phdr       elf32_phdr
+#define elf_shdr       elf32_shdr
 #define elf_note       elf32_note
 #define elf_addr_t     Elf32_Addr
 
 
 #define elf_phdr       elf32_phdr
 #define elf_note       elf32_note
 #define elf_addr_t     Elf32_Off
+#define Elf_Half       Elf32_Half
 
 #else
 
 #define elf_phdr       elf64_phdr
 #define elf_note       elf64_note
 #define elf_addr_t     Elf64_Off
+#define Elf_Half       Elf64_Half
 
 #endif
 
 
 #include <linux/user.h>
 #endif
 #include <linux/ptrace.h>
+#include <linux/elf.h>
+#include <linux/fs.h>
 
 struct elf_siginfo
 {
 
 #endif /* __KERNEL__ */
 
+/*
+ * These functions parameterize elf_core_dump in fs/binfmt_elf.c to write out
+ * extra segments containing the gate 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 gate DSO was being used.
+ */
+extern Elf_Half elf_core_extra_phdrs(void);
+extern int
+elf_core_write_extra_phdrs(struct file *file, loff_t offset, size_t *size,
+                          unsigned long limit);
+extern int
+elf_core_write_extra_data(struct file *file, size_t *size, unsigned long limit);
 
 #endif /* _LINUX_ELFCORE_H */
 
 obj-$(CONFIG_TASKSTATS) += taskstats.o tsacct.o
 obj-$(CONFIG_TRACEPOINTS) += tracepoint.o
 obj-$(CONFIG_LATENCYTOP) += latencytop.o
+obj-$(CONFIG_BINFMT_ELF) += elfcore.o
+obj-$(CONFIG_COMPAT_BINFMT_ELF) += elfcore.o
+obj-$(CONFIG_BINFMT_ELF_FDPIC) += elfcore.o
 obj-$(CONFIG_FUNCTION_TRACER) += trace/
 obj-$(CONFIG_TRACING) += trace/
 obj-$(CONFIG_X86_DS) += trace/
 
--- /dev/null
+#include <linux/elf.h>
+#include <linux/fs.h>
+#include <linux/mm.h>
+
+#include <asm/elf.h>
+
+
+Elf_Half __weak elf_core_extra_phdrs(void)
+{
+       return 0;
+}
+
+int __weak elf_core_write_extra_phdrs(struct file *file, loff_t offset, size_t *size,
+                                     unsigned long limit)
+{
+       return 1;
+}
+
+int __weak elf_core_write_extra_data(struct file *file, size_t *size,
+                                    unsigned long limit)
+{
+       return 1;
+}