You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@nuttx.apache.org by xi...@apache.org on 2024/10/12 04:29:19 UTC

(nuttx) 06/20: coredump:Move coredump to sched/misc

This is an automated email from the ASF dual-hosted git repository.

xiaoxiang pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/nuttx.git

commit 52126aede114fe0d9264acf3a6fcccbf0a80ba16
Author: anjiahao <an...@xiaomi.com>
AuthorDate: Sat Jul 6 15:22:51 2024 +0800

    coredump:Move coredump to sched/misc
    
    1. move coredump form libelf to sched/misc
    2. rename core_dump to coredump
    
    Signed-off-by: anjiahao <an...@xiaomi.com>
---
 Documentation/guides/coredump.rst                  |   4 +-
 binfmt/CMakeLists.txt                              |   3 +-
 binfmt/Makefile                                    |   1 -
 binfmt/binfmt_coredump.c                           |  72 ---
 binfmt/elf.c                                       |  34 --
 binfmt/libelf/CMakeLists.txt                       |   5 -
 binfmt/libelf/Kconfig                              |  11 -
 binfmt/libelf/Make.defs                            |   6 -
 binfmt/libelf/libelf_coredump.c                    | 666 ---------------------
 binfmt/nxflat.c                                    |   1 -
 boards/Kconfig                                     |   4 +-
 .../imx6/sabre-6quad/configs/coredump/defconfig    |   3 +-
 include/nuttx/binfmt/binfmt.h                      |  37 --
 include/nuttx/binfmt/elf.h                         |  31 -
 include/nuttx/coredump.h                           |  37 +-
 include/nuttx/elf.h                                |   2 +-
 sched/Kconfig                                      |  12 +
 sched/misc/CMakeLists.txt                          |   2 +-
 sched/misc/Make.defs                               |   2 +-
 sched/misc/coredump.c                              | 643 +++++++++++++++++++-
 20 files changed, 697 insertions(+), 879 deletions(-)

diff --git a/Documentation/guides/coredump.rst b/Documentation/guides/coredump.rst
index 94dfa7fc30..9b68c755cc 100644
--- a/Documentation/guides/coredump.rst
+++ b/Documentation/guides/coredump.rst
@@ -16,9 +16,7 @@ Enable Kconfig
 
     .. code-block:: console
 
-      CONFIG_ELF=y                        /* Enable ELF */
-
-      CONFIG_ELF_COREDUMP=y               /* Enable ELF Coredump */
+      CONFIG_COREDUMP=y                   /* Enable Coredump */
 
       CONFIG_BOARD_COREDUMP_SYSLOG=y      /* Enable Board Coredump, if exceptions and assertions occur, */
 
diff --git a/binfmt/CMakeLists.txt b/binfmt/CMakeLists.txt
index 35f8f9cdb3..0f0578ebce 100644
--- a/binfmt/CMakeLists.txt
+++ b/binfmt/CMakeLists.txt
@@ -39,8 +39,7 @@ list(
   binfmt_exec.c
   binfmt_copyargv.c
   binfmt_copyactions.c
-  binfmt_dumpmodule.c
-  binfmt_coredump.c)
+  binfmt_dumpmodule.c)
 
 if(CONFIG_BINFMT_LOADABLE)
   list(APPEND SRCS binfmt_exit.c)
diff --git a/binfmt/Makefile b/binfmt/Makefile
index 8916865990..02b48c2b13 100644
--- a/binfmt/Makefile
+++ b/binfmt/Makefile
@@ -27,7 +27,6 @@ include $(TOPDIR)/Make.defs
 CSRCS  = binfmt_globals.c binfmt_initialize.c binfmt_register.c binfmt_unregister.c
 CSRCS += binfmt_loadmodule.c binfmt_unloadmodule.c binfmt_execmodule.c
 CSRCS += binfmt_exec.c binfmt_copyargv.c binfmt_copyactions.c binfmt_dumpmodule.c
-CSRCS += binfmt_coredump.c
 
 ifeq ($(CONFIG_BINFMT_LOADABLE),y)
 CSRCS += binfmt_exit.c
diff --git a/binfmt/binfmt_coredump.c b/binfmt/binfmt_coredump.c
deleted file mode 100644
index a4fd7eea59..0000000000
--- a/binfmt/binfmt_coredump.c
+++ /dev/null
@@ -1,72 +0,0 @@
-/****************************************************************************
- * binfmt/binfmt_coredump.c
- *
- * SPDX-License-Identifier: Apache-2.0
- *
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.  The
- * ASF licenses this file to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance with the
- * License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
- * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
- * License for the specific language governing permissions and limitations
- * under the License.
- *
- ****************************************************************************/
-
-/****************************************************************************
- * Included Files
- ****************************************************************************/
-
-#include <nuttx/config.h>
-
-#include <nuttx/binfmt/binfmt.h>
-#include <errno.h>
-
-#include "binfmt.h"
-
-#ifndef CONFIG_BINFMT_DISABLE
-
-/****************************************************************************
- * Public Functions
- ****************************************************************************/
-
-/****************************************************************************
- * Name: core_dump
- *
- * Description:
- *   This function for generating core dump stream.
- *
- ****************************************************************************/
-
-int core_dump(FAR const struct memory_region_s *regions,
-              FAR struct lib_outstream_s *stream,
-              pid_t pid)
-{
-  FAR struct binfmt_s *binfmt;
-  int ret = -ENOENT;
-
-  for (binfmt = g_binfmts; binfmt; binfmt = binfmt->next)
-    {
-      /* Use this handler to try to load the format */
-
-      if (binfmt->coredump)
-        {
-          ret = binfmt->coredump(regions, stream, pid);
-          if (ret == OK)
-            {
-              break;
-            }
-        }
-    }
-
-  return ret;
-}
-
-#endif /* CONFIG_BINFMT_DISABLE */
diff --git a/binfmt/elf.c b/binfmt/elf.c
index 42fbaca0c4..2ae29db77b 100644
--- a/binfmt/elf.c
+++ b/binfmt/elf.c
@@ -69,11 +69,6 @@ static int elf_loadbinary(FAR struct binary_s *binp,
                           FAR const char *filename,
                           FAR const struct symtab_s *exports,
                           int nexports);
-#ifdef CONFIG_ELF_COREDUMP
-static int elf_dumpbinary(FAR const struct memory_region_s *regions,
-                          FAR struct lib_outstream_s *stream,
-                          pid_t pid);
-#endif
 #if defined(CONFIG_DEBUG_FEATURES) && defined(CONFIG_DEBUG_BINFMT)
 static void elf_dumploadinfo(FAR struct elf_loadinfo_s *loadinfo);
 #endif
@@ -87,9 +82,6 @@ static struct binfmt_s g_elfbinfmt =
   NULL,             /* next */
   elf_loadbinary,   /* load */
   NULL,             /* unload */
-#ifdef CONFIG_ELF_COREDUMP
-  elf_dumpbinary,   /* coredump */
-#endif
 };
 
 /****************************************************************************
@@ -370,32 +362,6 @@ errout_with_init:
   return ret;
 }
 
-/****************************************************************************
- * Name: elf_dumpbinary
- *
- * Description:
- *   Generat the core dump stream as ELF structure.
- *
- * Returned Value:
- *   Zero (OK) on success; a negated errno value on failure.
- *
- ****************************************************************************/
-
-#ifdef CONFIG_ELF_COREDUMP
-static int elf_dumpbinary(FAR const struct memory_region_s *regions,
-                          FAR struct lib_outstream_s *stream,
-                          pid_t pid)
-{
-  struct elf_dumpinfo_s dumpinfo;
-
-  dumpinfo.regions = regions;
-  dumpinfo.stream  = stream;
-  dumpinfo.pid     = pid;
-
-  return elf_coredump(&dumpinfo);
-}
-#endif
-
 /****************************************************************************
  * Public Functions
  ****************************************************************************/
diff --git a/binfmt/libelf/CMakeLists.txt b/binfmt/libelf/CMakeLists.txt
index aa6fedd582..8df1a0bd52 100644
--- a/binfmt/libelf/CMakeLists.txt
+++ b/binfmt/libelf/CMakeLists.txt
@@ -40,11 +40,6 @@ if(CONFIG_ELF)
     libelf_unload.c
     libelf_verify.c)
 
-  if(CONFIG_ELF_COREDUMP)
-    list(APPEND SRCS libelf_coredump.c)
-    target_include_directories(binfmt PRIVATE ${NUTTX_DIR}/sched)
-  endif()
-
   if(CONFIG_BINFMT_CONSTRUCTORS)
     list(APPEND SRCS libelf_ctors.c libelf_dtors.c)
   endif()
diff --git a/binfmt/libelf/Kconfig b/binfmt/libelf/Kconfig
index dbba7921e4..f33d737021 100644
--- a/binfmt/libelf/Kconfig
+++ b/binfmt/libelf/Kconfig
@@ -63,17 +63,6 @@ config ELF_SYMBOL_CACHECOUNT
 		This is a cache that is used to store elf symbol table to
 		reduce access fs. Default: 256
 
-config ELF_COREDUMP
-	bool "ELF Coredump"
-	depends on ARCH_HAVE_TCBINFO
-	default n
-	---help---
-		Generate ELF core dump to provide information about the CPU state and the
-		memory state of program.
-		The memory state embeds a snapshot of all segments mapped in the
-		memory space of the program. The CPU state contains register values
-		when the core dump has been generated.
-
 config ELF_LOADTO_LMA
 	bool "ELF load sections to LMA"
 	default n
diff --git a/binfmt/libelf/Make.defs b/binfmt/libelf/Make.defs
index ee138761bc..8c1a53182d 100644
--- a/binfmt/libelf/Make.defs
+++ b/binfmt/libelf/Make.defs
@@ -28,12 +28,6 @@ CSRCS += libelf_bind.c libelf_init.c libelf_addrenv.c libelf_iobuffer.c
 CSRCS += libelf_load.c libelf_read.c libelf_sections.c libelf_symbols.c
 CSRCS += libelf_uninit.c libelf_unload.c libelf_verify.c
 
-ifeq ($(CONFIG_ELF_COREDUMP),y)
-CSRCS += libelf_coredump.c
-
-CFLAGS += ${INCDIR_PREFIX}$(TOPDIR)$(DELIM)sched
-endif
-
 ifeq ($(CONFIG_BINFMT_CONSTRUCTORS),y)
 CSRCS += libelf_ctors.c libelf_dtors.c
 endif
diff --git a/binfmt/libelf/libelf_coredump.c b/binfmt/libelf/libelf_coredump.c
deleted file mode 100644
index a37bbdeada..0000000000
--- a/binfmt/libelf/libelf_coredump.c
+++ /dev/null
@@ -1,666 +0,0 @@
-/****************************************************************************
- * binfmt/libelf/libelf_coredump.c
- *
- * SPDX-License-Identifier: Apache-2.0
- *
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.  The
- * ASF licenses this file to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance with the
- * License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
- * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
- * License for the specific language governing permissions and limitations
- * under the License.
- *
- ****************************************************************************/
-
-/****************************************************************************
- * Included Files
- ****************************************************************************/
-
-#include <nuttx/config.h>
-#include <nuttx/arch.h>
-
-#include <sys/stat.h>
-#include <sys/param.h>
-
-#include <stdio.h>
-#include <stdint.h>
-#include <string.h>
-#include <debug.h>
-#include <errno.h>
-
-#include <nuttx/elf.h>
-#include <nuttx/binfmt/elf.h>
-#include <nuttx/binfmt/binfmt.h>
-#include <nuttx/sched.h>
-#include <sched/sched.h>
-
-/****************************************************************************
- * Pre-processor Definitions
- ****************************************************************************/
-
-#ifdef PAGESIZE
-#  define ELF_PAGESIZE PAGESIZE
-#else
-#  define ELF_PAGESIZE 1024
-#endif
-
-#define PROGRAM_ALIGNMENT 64
-
-#define ROUNDUP(x, y)     ((x + (y - 1)) / (y)) * (y)
-#define ROUNDDOWN(x ,y)   (((x) / (y)) * (y))
-
-/****************************************************************************
- * Private Data
- ****************************************************************************/
-
-static uint8_t g_running_regs[XCPTCONTEXT_SIZE] aligned_data(16);
-
-/****************************************************************************
- * Private Functions
- ****************************************************************************/
-
-/****************************************************************************
- * Name: elf_flush
- *
- * Description:
- *   Flush the out stream
- *
- ****************************************************************************/
-
-static int elf_flush(FAR struct elf_dumpinfo_s *cinfo)
-{
-  return lib_stream_flush(cinfo->stream);
-}
-
-/****************************************************************************
- * Name: elf_emit
- *
- * Description:
- *   Send the dump data to binfmt_outstream_s
- *
- ****************************************************************************/
-
-static int elf_emit(FAR struct elf_dumpinfo_s *cinfo,
-                    FAR const void *buf, size_t len)
-{
-  FAR const uint8_t *ptr = buf;
-  size_t total = len;
-  int ret = 0;
-
-  while (total > 0)
-    {
-      ret = lib_stream_puts(cinfo->stream, ptr, total);
-      if (ret < 0)
-        {
-          break;
-        }
-
-      total -= ret;
-      ptr   += ret;
-    }
-
-  return ret < 0 ? ret : len - total;
-}
-
-/****************************************************************************
- * Name: elf_emit_align
- *
- * Description:
- *   Align the filled data according to the current offset
- *
- ****************************************************************************/
-
-static int elf_emit_align(FAR struct elf_dumpinfo_s *cinfo)
-{
-  off_t align = ROUNDUP(cinfo->stream->nput,
-                        ELF_PAGESIZE) - cinfo->stream->nput;
-  unsigned char null[256];
-  off_t total = align;
-  off_t ret = 0;
-
-  memset(null, 0, sizeof(null));
-
-  while (total > 0)
-    {
-      ret = elf_emit(cinfo, null, total > sizeof(null) ?
-                                 sizeof(null) : total);
-      if (ret <= 0)
-        {
-          break;
-        }
-
-      total -= ret;
-    }
-
-  return ret < 0 ? ret : align;
-}
-
-/****************************************************************************
- * Name: elf_emit_hdr
- *
- * Description:
- *   Fill the elf header
- *
- ****************************************************************************/
-
-static int elf_emit_hdr(FAR struct elf_dumpinfo_s *cinfo,
-                        int segs)
-{
-  Elf_Ehdr ehdr;
-
-  memset(&ehdr, 0, sizeof(ehdr));
-  memcpy(ehdr.e_ident, ELFMAG, EI_MAGIC_SIZE);
-
-  ehdr.e_ident[EI_CLASS]   = ELF_CLASS;
-  ehdr.e_ident[EI_DATA]    = ELF_DATA;
-  ehdr.e_ident[EI_VERSION] = EV_CURRENT;
-  ehdr.e_ident[EI_OSABI]   = ELF_OSABI;
-
-  ehdr.e_type              = ET_CORE;
-  ehdr.e_machine           = EM_ARCH;
-  ehdr.e_version           = EV_CURRENT;
-  ehdr.e_phoff             = sizeof(Elf_Ehdr);
-  ehdr.e_flags             = EF_FLAG;
-  ehdr.e_ehsize            = sizeof(Elf_Ehdr);
-  ehdr.e_phentsize         = sizeof(Elf_Phdr);
-  ehdr.e_phnum             = segs;
-
-  return elf_emit(cinfo, &ehdr, sizeof(ehdr));
-}
-
-/****************************************************************************
- * Name: elf_get_ntcb
- *
- * Description:
- *   Calculate the note segment size
- *
- ****************************************************************************/
-
-static int elf_get_ntcb(void)
-{
-  int count = 0;
-  int i;
-
-  for (i = 0; i < g_npidhash; i++)
-    {
-      if (g_pidhash[i] != NULL)
-        {
-          count++;
-        }
-    }
-
-  return count;
-}
-
-/****************************************************************************
- * Name: elf_get_note_size
- *
- * Description:
- *   Calculate the note segment size
- *
- ****************************************************************************/
-
-static int elf_get_note_size(int stksegs)
-{
-  int total;
-
-  total  = stksegs * (sizeof(Elf_Nhdr) + ROUNDUP(CONFIG_TASK_NAME_SIZE, 8) +
-                     sizeof(elf_prstatus_t));
-  total += stksegs * (sizeof(Elf_Nhdr) + ROUNDUP(CONFIG_TASK_NAME_SIZE, 8) +
-                     sizeof(elf_prpsinfo_t));
-  return total;
-}
-
-/****************************************************************************
- * Name: elf_emit_tcb_note
- *
- * Description:
- *   Fill the note segment information from tcb
- *
- ****************************************************************************/
-
-static void elf_emit_tcb_note(FAR struct elf_dumpinfo_s *cinfo,
-                              FAR struct tcb_s *tcb)
-{
-  char name[ROUNDUP(CONFIG_TASK_NAME_SIZE, 8)];
-  elf_prstatus_t status;
-  elf_prpsinfo_t info;
-  FAR uintptr_t *regs;
-  Elf_Nhdr nhdr;
-  int i;
-
-  memset(&info,   0x0, sizeof(info));
-  memset(&status, 0x0, sizeof(status));
-
-  /* Fill Process info */
-
-  nhdr.n_namesz = sizeof(name);
-  nhdr.n_descsz = sizeof(info);
-  nhdr.n_type   = NT_PRPSINFO;
-
-  elf_emit(cinfo, &nhdr, sizeof(nhdr));
-
-  strlcpy(name, get_task_name(tcb), sizeof(name));
-  elf_emit(cinfo, name, sizeof(name));
-
-  info.pr_pid   = tcb->pid;
-  strlcpy(info.pr_fname, get_task_name(tcb), sizeof(info.pr_fname));
-  elf_emit(cinfo, &info, sizeof(info));
-
-  /* Fill Process status */
-
-  nhdr.n_descsz = sizeof(status);
-  nhdr.n_type   = NT_PRSTATUS;
-
-  elf_emit(cinfo, &nhdr, sizeof(nhdr));
-  elf_emit(cinfo, name, sizeof(name));
-
-  status.pr_pid = tcb->pid;
-
-  if (running_task() == tcb)
-    {
-      if (up_interrupt_context())
-        {
-          regs = (FAR uintptr_t *)up_current_regs();
-        }
-      else
-        {
-          up_saveusercontext(g_running_regs);
-          regs = (FAR uintptr_t *)g_running_regs;
-        }
-    }
-  else
-    {
-      regs = (FAR uintptr_t *)tcb->xcp.regs;
-    }
-
-  if (regs != NULL)
-    {
-      for (i = 0; i < nitems(status.pr_regs); i++)
-        {
-          if (g_tcbinfo.reg_off.p[i] == UINT16_MAX)
-            {
-              continue;
-            }
-          else
-            {
-              status.pr_regs[i] = *(FAR uintptr_t *)
-                  ((FAR uint8_t *)regs + g_tcbinfo.reg_off.p[i]);
-            }
-        }
-    }
-
-  elf_emit(cinfo, &status, sizeof(status));
-}
-
-/****************************************************************************
- * Name: elf_emit_note
- *
- * Description:
- *   Fill the note segment information
- *
- ****************************************************************************/
-
-static void elf_emit_note(FAR struct elf_dumpinfo_s *cinfo)
-{
-  int i;
-
-  if (cinfo->pid == INVALID_PROCESS_ID)
-    {
-      for (i = 0; i < g_npidhash; i++)
-        {
-          if (g_pidhash[i] != NULL)
-            {
-              elf_emit_tcb_note(cinfo, g_pidhash[i]);
-            }
-        }
-    }
-  else
-    {
-      elf_emit_tcb_note(cinfo, nxsched_get_tcb(cinfo->pid));
-    }
-}
-
-/****************************************************************************
- * Name: elf_emit_tcb_stack
- *
- * Description:
- *   Fill the task stack information from tcb
- *
- ****************************************************************************/
-
-static void elf_emit_tcb_stack(FAR struct elf_dumpinfo_s *cinfo,
-                               FAR struct tcb_s *tcb)
-{
-  uintptr_t buf = 0;
-  uintptr_t sp;
-  size_t len;
-
-  if (running_task() != tcb)
-    {
-      sp = up_getusrsp(tcb->xcp.regs);
-
-      if (sp > (uintptr_t)tcb->stack_base_ptr &&
-          sp < (uintptr_t)tcb->stack_base_ptr + tcb->adj_stack_size)
-        {
-          len = ((uintptr_t)tcb->stack_base_ptr +
-                            tcb->adj_stack_size) - sp;
-          buf = sp;
-        }
-#ifdef CONFIG_STACK_COLORATION
-      else
-        {
-          len = up_check_tcbstack(tcb);
-          buf = (uintptr_t)tcb->stack_base_ptr +
-                           (tcb->adj_stack_size - len);
-        }
-#endif
-    }
-
-  if (buf == 0)
-    {
-      buf = (uintptr_t)tcb->stack_alloc_ptr;
-      len = tcb->adj_stack_size +
-            (tcb->stack_base_ptr - tcb->stack_alloc_ptr);
-    }
-
-  sp  = ROUNDDOWN(buf, PROGRAM_ALIGNMENT);
-  len = ROUNDUP(len + (buf - sp), PROGRAM_ALIGNMENT);
-  buf = sp;
-
-  elf_emit(cinfo, (FAR void *)buf, len);
-
-  /* Align to page */
-
-  elf_emit_align(cinfo);
-}
-
-/****************************************************************************
- * Name: elf_emit_stack
- *
- * Description:
- *   Fill the task stack information
- *
- ****************************************************************************/
-
-static void elf_emit_stack(FAR struct elf_dumpinfo_s *cinfo)
-{
-  int i;
-
-  if (cinfo->pid == INVALID_PROCESS_ID)
-    {
-      for (i = 0; i < g_npidhash; i++)
-        {
-          if (g_pidhash[i] != NULL)
-            {
-              elf_emit_tcb_stack(cinfo, g_pidhash[i]);
-            }
-        }
-    }
-  else
-    {
-      elf_emit_tcb_stack(cinfo, nxsched_get_tcb(cinfo->pid));
-    }
-}
-
-/****************************************************************************
- * Name: elf_emit_memory
- *
- * Description:
- *   Fill the note segment information
- *
- ****************************************************************************/
-
-static void elf_emit_memory(FAR struct elf_dumpinfo_s *cinfo, int memsegs)
-{
-  int i;
-
-  for (i = 0; i < memsegs; i++)
-    {
-      if (cinfo->regions[i].flags & PF_REGISTER)
-        {
-          FAR uintptr_t *start = (FAR uintptr_t *)cinfo->regions[i].start;
-          FAR uintptr_t *end = (FAR uintptr_t *)cinfo->regions[i].end;
-          uintptr_t buf[64];
-          size_t offset = 0;
-
-          while (start < end)
-            {
-              buf[offset++] = *start++;
-
-              if (offset % (sizeof(buf) / sizeof(uintptr_t)) == 0)
-                {
-                  elf_emit(cinfo, buf, sizeof(buf));
-                  offset = 0;
-                }
-            }
-
-          if (offset != 0)
-            {
-              elf_emit(cinfo, buf, offset * sizeof(uintptr_t));
-            }
-        }
-      else
-        {
-          elf_emit(cinfo, (FAR void *)cinfo->regions[i].start,
-                   cinfo->regions[i].end - cinfo->regions[i].start);
-        }
-
-      /* Align to page */
-
-      elf_emit_align(cinfo);
-    }
-}
-
-/****************************************************************************
- * Name: elf_emit_tcb_phdr
- *
- * Description:
- *   Fill the program segment header from tcb
- *
- ****************************************************************************/
-
-static void elf_emit_tcb_phdr(FAR struct elf_dumpinfo_s *cinfo,
-                              FAR struct tcb_s *tcb,
-                              FAR Elf_Phdr *phdr, FAR off_t *offset)
-{
-  uintptr_t sp;
-
-  phdr->p_vaddr = 0;
-
-  if (running_task() != tcb)
-    {
-      sp = up_getusrsp(tcb->xcp.regs);
-
-      if (sp > (uintptr_t)tcb->stack_base_ptr &&
-          sp < (uintptr_t)tcb->stack_base_ptr + tcb->adj_stack_size)
-        {
-          phdr->p_filesz = ((uintptr_t)tcb->stack_base_ptr +
-                           tcb->adj_stack_size) - sp;
-          phdr->p_vaddr  = sp;
-        }
-#ifdef CONFIG_STACK_COLORATION
-      else
-        {
-          phdr->p_filesz = up_check_tcbstack(tcb);
-          phdr->p_vaddr  = (uintptr_t)tcb->stack_base_ptr +
-                           (tcb->adj_stack_size - phdr->p_filesz);
-        }
-#endif
-    }
-
-  if (phdr->p_vaddr == 0)
-    {
-      phdr->p_vaddr  = (uintptr_t)tcb->stack_alloc_ptr;
-      phdr->p_filesz = tcb->adj_stack_size +
-                      (tcb->stack_base_ptr - tcb->stack_alloc_ptr);
-    }
-
-  sp = ROUNDDOWN(phdr->p_vaddr, PROGRAM_ALIGNMENT);
-  phdr->p_filesz = ROUNDUP(phdr->p_filesz +
-                           (phdr->p_vaddr - sp), PROGRAM_ALIGNMENT);
-  phdr->p_vaddr  = sp;
-
-  phdr->p_type   = PT_LOAD;
-  phdr->p_offset = ROUNDUP(*offset, ELF_PAGESIZE);
-  phdr->p_paddr  = phdr->p_vaddr;
-  phdr->p_memsz  = phdr->p_filesz;
-  phdr->p_flags  = PF_X | PF_W | PF_R;
-  phdr->p_align  = ELF_PAGESIZE;
-  *offset       += ROUNDUP(phdr->p_memsz, ELF_PAGESIZE);
-
-  elf_emit(cinfo, phdr, sizeof(*phdr));
-}
-
-/****************************************************************************
- * Name: elf_emit_phdr
- *
- * Description:
- *   Fill the program segment header
- *
- ****************************************************************************/
-
-static void elf_emit_phdr(FAR struct elf_dumpinfo_s *cinfo,
-                          int stksegs, int memsegs)
-{
-  off_t offset = cinfo->stream->nput +
-                 (stksegs + memsegs + 1) * sizeof(Elf_Phdr);
-  Elf_Phdr phdr;
-  int i;
-
-  memset(&phdr, 0, sizeof(Elf_Phdr));
-
-  phdr.p_type   = PT_NOTE;
-  phdr.p_offset = offset;
-  phdr.p_filesz = elf_get_note_size(stksegs);
-  offset       += phdr.p_filesz;
-
-  elf_emit(cinfo, &phdr, sizeof(phdr));
-
-  if (cinfo->pid == INVALID_PROCESS_ID)
-    {
-      for (i = 0; i < g_npidhash; i++)
-        {
-          if (g_pidhash[i] != NULL)
-            {
-              elf_emit_tcb_phdr(cinfo, g_pidhash[i], &phdr, &offset);
-            }
-        }
-    }
-  else
-    {
-      elf_emit_tcb_phdr(cinfo, nxsched_get_tcb(cinfo->pid),
-                        &phdr, &offset);
-    }
-
-  /* Write program headers for segments dump */
-
-  for (i = 0; i < memsegs; i++)
-    {
-      phdr.p_type   = PT_LOAD;
-      phdr.p_offset = ROUNDUP(offset, ELF_PAGESIZE);
-      phdr.p_vaddr  = cinfo->regions[i].start;
-      phdr.p_paddr  = phdr.p_vaddr;
-      phdr.p_filesz = cinfo->regions[i].end - cinfo->regions[i].start;
-      phdr.p_memsz  = phdr.p_filesz;
-      phdr.p_flags  = cinfo->regions[i].flags;
-      phdr.p_align  = ELF_PAGESIZE;
-      offset       += ROUNDUP(phdr.p_memsz, ELF_PAGESIZE);
-      elf_emit(cinfo, &phdr, sizeof(phdr));
-    }
-}
-
-/****************************************************************************
- * Public Functions
- ****************************************************************************/
-
-/****************************************************************************
- * Name: elf_coredump
- *
- * Description:
- *   Generat the core dump stream as ELF structure.
- *
- * Input Parameters:
- *   dumpinfo - elf coredump informations
- *
- * Returned Value:
- *   Zero (OK) on success; a negated errno value on failure.
- *
- ****************************************************************************/
-
-int elf_coredump(FAR struct elf_dumpinfo_s *cinfo)
-{
-  irqstate_t flags;
-  int memsegs = 0;
-  int stksegs;
-
-  flags = enter_critical_section();
-
-  if (cinfo->pid != INVALID_PROCESS_ID)
-    {
-      if (nxsched_get_tcb(cinfo->pid) == NULL)
-        {
-          leave_critical_section(flags);
-          return -EINVAL;
-        }
-
-      stksegs = 1;
-    }
-  else
-    {
-      stksegs = elf_get_ntcb();
-    }
-
-  /* Check the memory region */
-
-  if (cinfo->regions != NULL)
-    {
-      for (; cinfo->regions[memsegs].start <
-             cinfo->regions[memsegs].end; memsegs++);
-    }
-
-  /* Fill notes section */
-
-  elf_emit_hdr(cinfo, stksegs + memsegs + 1);
-
-  /* Fill all the program information about the process for the
-   * notes.  This also sets up the file header.
-   */
-
-  elf_emit_phdr(cinfo, stksegs, memsegs);
-
-  /* Fill note information */
-
-  elf_emit_note(cinfo);
-
-  /* Align to page */
-
-  elf_emit_align(cinfo);
-
-  /* Dump stack */
-
-  elf_emit_stack(cinfo);
-
-  /* Dump memory segments */
-
-  if (memsegs > 0)
-    {
-      elf_emit_memory(cinfo, memsegs);
-    }
-
-  /* Flush the dump */
-
-  elf_flush(cinfo);
-
-  leave_critical_section(flags);
-
-  return OK;
-}
diff --git a/binfmt/nxflat.c b/binfmt/nxflat.c
index b1ec250e63..175c3eb5dd 100644
--- a/binfmt/nxflat.c
+++ b/binfmt/nxflat.c
@@ -81,7 +81,6 @@ static struct binfmt_s g_nxflatbinfmt =
   NULL,                /* next */
   nxflat_loadbinary,   /* load */
   nxflat_unloadbinary, /* unload */
-  NULL,                /* coredump */
 };
 
 /****************************************************************************
diff --git a/boards/Kconfig b/boards/Kconfig
index e98058c9e6..44d2ec5cd0 100644
--- a/boards/Kconfig
+++ b/boards/Kconfig
@@ -4634,14 +4634,14 @@ config BOARD_CRASHDUMP
 config BOARD_COREDUMP_SYSLOG
 	bool "Enable Core dump to syslog"
 	default n
-	depends on ELF_COREDUMP
+	depends on COREDUMP
 	---help---
 		Enable put coredump to syslog when crash.
 
 config BOARD_COREDUMP_BLKDEV
 	bool "Enable Core Dump to block device"
 	default n
-	depends on ELF_COREDUMP
+	depends on COREDUMP
 	---help---
 		Enable save coredump at block device when crash.
 
diff --git a/boards/arm/imx6/sabre-6quad/configs/coredump/defconfig b/boards/arm/imx6/sabre-6quad/configs/coredump/defconfig
index da7f72396b..e8112e8b25 100644
--- a/boards/arm/imx6/sabre-6quad/configs/coredump/defconfig
+++ b/boards/arm/imx6/sabre-6quad/configs/coredump/defconfig
@@ -21,13 +21,12 @@ CONFIG_BOARD_COREDUMP_SYSLOG=y
 CONFIG_BOARD_LOOPSPERMSEC=99369
 CONFIG_BOOT_RUNFROMSDRAM=y
 CONFIG_BUILTIN=y
+CONFIG_COREDUMP=y
 CONFIG_DEBUG_ASSERTIONS=y
 CONFIG_DEBUG_FEATURES=y
 CONFIG_DEBUG_FULLOPT=y
 CONFIG_DEBUG_SYMBOLS=y
 CONFIG_DEV_ZERO=y
-CONFIG_ELF=y
-CONFIG_ELF_COREDUMP=y
 CONFIG_EXAMPLES_HELLO=y
 CONFIG_EXPERIMENTAL=y
 CONFIG_FS_PROCFS=y
diff --git a/include/nuttx/binfmt/binfmt.h b/include/nuttx/binfmt/binfmt.h
index 044719692f..9582ee1ac4 100644
--- a/include/nuttx/binfmt/binfmt.h
+++ b/include/nuttx/binfmt/binfmt.h
@@ -31,18 +31,14 @@
 
 #include <spawn.h>
 #include <sys/types.h>
-#include <sys/utsname.h>
 
 #include <nuttx/sched.h>
-#include <nuttx/streams.h>
-#include <nuttx/memoryregion.h>
 
 /****************************************************************************
  * Pre-processor Definitions
  ****************************************************************************/
 
 #define BINFMT_NALLOC     4
-#define COREDUMP_MAGIC    0x434f5245
 
 /****************************************************************************
  * Public Types
@@ -138,22 +134,6 @@ struct binfmt_s
   /* Unload module callback */
 
   CODE int (*unload)(FAR struct binary_s *bin);
-
-  /* Coredump callback */
-
-  CODE int (*coredump)(FAR const struct memory_region_s *regions,
-                       FAR struct lib_outstream_s *stream,
-                       pid_t pid);
-};
-
-/* Coredump information for block header */
-
-struct coredump_info_s
-{
-  uint32_t       magic;
-  struct utsname name;
-  time_t         time;
-  size_t         size;
 };
 
 /****************************************************************************
@@ -209,23 +189,6 @@ int register_binfmt(FAR struct binfmt_s *binfmt);
 
 int unregister_binfmt(FAR struct binfmt_s *binfmt);
 
-/****************************************************************************
- * Name: core_dump
- *
- * Description:
- *   This function for generating core dump stream.
- *
- * Returned Value:
- *   This is a NuttX internal function so it follows the convention that
- *   0 (OK) is returned on success and a negated errno is returned on
- *   failure.
- *
- ****************************************************************************/
-
-int core_dump(FAR const struct memory_region_s *regions,
-              FAR struct lib_outstream_s *stream,
-              pid_t pid);
-
 /****************************************************************************
  * Name: load_module
  *
diff --git a/include/nuttx/binfmt/elf.h b/include/nuttx/binfmt/elf.h
index 854c010688..60793dabc8 100644
--- a/include/nuttx/binfmt/elf.h
+++ b/include/nuttx/binfmt/elf.h
@@ -129,19 +129,6 @@ struct elf_loadinfo_s
   struct file        file;       /* Descriptor for the file being loaded */
 };
 
-/* This struct provides a description of the dump information of
- * memory regions.
- */
-
-#ifdef CONFIG_ELF_COREDUMP
-struct elf_dumpinfo_s
-{
-  FAR const struct memory_region_s *regions;
-  FAR struct lib_outstream_s *stream;
-  pid_t                       pid;
-};
-#endif
-
 /****************************************************************************
  * Public Function Prototypes
  ****************************************************************************/
@@ -233,24 +220,6 @@ int elf_bind(FAR struct elf_loadinfo_s *loadinfo,
 
 int elf_unload(FAR struct elf_loadinfo_s *loadinfo);
 
-/****************************************************************************
- * Name: elf_coredump
- *
- * Description:
- *   Generat the core dump stream as ELF structure.
- *
- * Input Parameters:
- *   dumpinfo - elf coredump informations
- *
- * Returned Value:
- *   Zero (OK) on success; a negated errno value on failure.
- *
- ****************************************************************************/
-
-#ifdef CONFIG_ELF_COREDUMP
-int elf_coredump(FAR struct elf_dumpinfo_s *dumpinfo);
-#endif
-
 #undef EXTERN
 #if defined(__cplusplus)
 }
diff --git a/include/nuttx/coredump.h b/include/nuttx/coredump.h
index 46f1fa0975..ee798223a0 100644
--- a/include/nuttx/coredump.h
+++ b/include/nuttx/coredump.h
@@ -27,9 +27,32 @@
  * Included Files
  ****************************************************************************/
 
-#include <nuttx/memoryregion.h>
+#include <sys/utsname.h>
 #include <unistd.h>
 
+#include <nuttx/streams.h>
+#include <nuttx/memoryregion.h>
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+#define COREDUMP_MAGIC    0x434f5245
+
+/****************************************************************************
+ * Public Types
+ ****************************************************************************/
+
+/* Coredump information for block header */
+
+struct coredump_info_s
+{
+  uint32_t       magic;
+  struct utsname name;
+  time_t         time;
+  size_t         size;
+};
+
 /****************************************************************************
  * Public Function Prototypes
  ****************************************************************************/
@@ -54,4 +77,16 @@ int coredump_set_memory_region(FAR const struct memory_region_s *region);
 
 int coredump_add_memory_region(FAR const void *ptr, size_t size);
 
+/****************************************************************************
+ * Name: coredump
+ *
+ * Description:
+ *   This function for generating core dump stream.
+ *
+ ****************************************************************************/
+
+int coredump(FAR const struct memory_region_s *regions,
+             FAR struct lib_outstream_s *stream,
+             pid_t pid);
+
 #endif /* __INCLUDE_NUTTX_COREDUMP_H */
diff --git a/include/nuttx/elf.h b/include/nuttx/elf.h
index 522795de78..0737f5b615 100644
--- a/include/nuttx/elf.h
+++ b/include/nuttx/elf.h
@@ -40,7 +40,7 @@
  * Public Types
  ****************************************************************************/
 
-#ifdef CONFIG_ELF_COREDUMP
+#ifdef CONFIG_COREDUMP
 typedef struct elf_prpsinfo_s
 {
   char           pr_state;    /* Numeric process state */
diff --git a/sched/Kconfig b/sched/Kconfig
index fe7cd0008a..8b09ca1f02 100644
--- a/sched/Kconfig
+++ b/sched/Kconfig
@@ -2047,3 +2047,15 @@ config ASSERT_PAUSE_CPU_TIMEOUT
 	---help---
 		Timeout in milisecond to pause another CPU when assert. Only available
 		when SMP is enabled.
+		Enable to support perf events.
+
+config COREDUMP
+	bool "Coredump support"
+	depends on ARCH_HAVE_TCBINFO
+	default n
+	---help---
+		Generate ELF core dump to provide information about the CPU state and the
+		memory state of program.
+		The memory state embeds a snapshot of all segments mapped in the
+		memory space of the program. The CPU state contains register values
+		when the core dump has been generated.
diff --git a/sched/misc/CMakeLists.txt b/sched/misc/CMakeLists.txt
index d9afdf25ed..43003dee48 100644
--- a/sched/misc/CMakeLists.txt
+++ b/sched/misc/CMakeLists.txt
@@ -26,7 +26,7 @@ if(CONFIG_ARCH_DEADLOCKDUMP)
   list(APPEND SRCS deadlock.c)
 endif()
 
-if(CONFIG_BOARD_COREDUMP_SYSLOG OR CONFIG_BOARD_COREDUMP_BLKDEV)
+if(CONFIG_COREDUMP)
   list(APPEND SRCS coredump.c)
 endif()
 
diff --git a/sched/misc/Make.defs b/sched/misc/Make.defs
index c105d79f96..9a40bec31c 100644
--- a/sched/misc/Make.defs
+++ b/sched/misc/Make.defs
@@ -26,7 +26,7 @@ ifeq ($(CONFIG_ARCH_DEADLOCKDUMP),y)
 CSRCS += deadlock.c
 endif
 
-ifneq ($(CONFIG_BOARD_COREDUMP_SYSLOG)$(CONFIG_BOARD_COREDUMP_BLKDEV),)
+ifeq ($(CONFIG_COREDUMP),y)
 CSRCS += coredump.c
 endif
 
diff --git a/sched/misc/coredump.c b/sched/misc/coredump.c
index 16c6867b58..76d048251c 100644
--- a/sched/misc/coredump.c
+++ b/sched/misc/coredump.c
@@ -24,15 +24,55 @@
  * Included Files
  ****************************************************************************/
 
+#include <sys/stat.h>
+#include <sys/param.h>
+
 #include <syslog.h>
 #include <debug.h>
 
+#include <nuttx/coredump.h>
+#include <nuttx/elf.h>
+#include <nuttx/sched.h>
+
+#include "sched/sched.h"
 #include "coredump.h"
 
 /****************************************************************************
  * Private Data
  ****************************************************************************/
 
+#ifdef PAGESIZE
+#  define ELF_PAGESIZE    PAGESIZE
+#else
+#  define ELF_PAGESIZE    1024
+#endif
+
+#define PROGRAM_ALIGNMENT 64
+
+#define ROUNDUP(x, y)     ((x + (y - 1)) / (y)) * (y)
+#define ROUNDDOWN(x ,y)   (((x) / (y)) * (y))
+
+/****************************************************************************
+ * Private Types
+ ****************************************************************************/
+
+/* This struct provides a description of the dump information of
+ * memory regions.
+ */
+
+struct elf_dumpinfo_s
+{
+  FAR const struct memory_region_s *regions;
+  FAR struct lib_outstream_s *stream;
+  pid_t                       pid;
+};
+
+/****************************************************************************
+ * Private Data
+ ****************************************************************************/
+
+static uint8_t g_running_regs[XCPTCONTEXT_SIZE] aligned_data(16);
+
 #ifdef CONFIG_BOARD_COREDUMP_COMPRESSION
 static struct lib_lzfoutstream_s  g_lzfstream;
 #endif
@@ -63,6 +103,521 @@ static const struct memory_region_s *g_regions;
  * Private Functions
  ****************************************************************************/
 
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: elf_flush
+ *
+ * Description:
+ *   Flush the out stream
+ *
+ ****************************************************************************/
+
+static int elf_flush(FAR struct elf_dumpinfo_s *cinfo)
+{
+  return lib_stream_flush(cinfo->stream);
+}
+
+/****************************************************************************
+ * Name: elf_emit
+ *
+ * Description:
+ *   Send the dump data to binfmt_outstream_s
+ *
+ ****************************************************************************/
+
+static int elf_emit(FAR struct elf_dumpinfo_s *cinfo,
+                    FAR const void *buf, size_t len)
+{
+  FAR const uint8_t *ptr = buf;
+  size_t total = len;
+  int ret;
+
+  while (total > 0)
+    {
+      ret = lib_stream_puts(cinfo->stream, ptr, total);
+      if (ret < 0)
+        {
+          break;
+        }
+
+      total -= ret;
+      ptr   += ret;
+    }
+
+  return ret < 0 ? ret : len - total;
+}
+
+/****************************************************************************
+ * Name: elf_emit_align
+ *
+ * Description:
+ *   Align the filled data according to the current offset
+ *
+ ****************************************************************************/
+
+static int elf_emit_align(FAR struct elf_dumpinfo_s *cinfo)
+{
+  off_t align = ROUNDUP(cinfo->stream->nput,
+                        ELF_PAGESIZE) - cinfo->stream->nput;
+  unsigned char null[256];
+  off_t total = align;
+  off_t ret;
+
+  memset(null, 0, sizeof(null));
+
+  while (total > 0)
+    {
+      ret = elf_emit(cinfo, null, total > sizeof(null) ?
+                                 sizeof(null) : total);
+      if (ret <= 0)
+        {
+          break;
+        }
+
+      total -= ret;
+    }
+
+  return ret < 0 ? ret : align;
+}
+
+/****************************************************************************
+ * Name: elf_emit_hdr
+ *
+ * Description:
+ *   Fill the elf header
+ *
+ ****************************************************************************/
+
+static int elf_emit_hdr(FAR struct elf_dumpinfo_s *cinfo,
+                        int segs)
+{
+  Elf_Ehdr ehdr;
+
+  memset(&ehdr, 0, sizeof(ehdr));
+  memcpy(ehdr.e_ident, ELFMAG, EI_MAGIC_SIZE);
+
+  ehdr.e_ident[EI_CLASS]   = ELF_CLASS;
+  ehdr.e_ident[EI_DATA]    = ELF_DATA;
+  ehdr.e_ident[EI_VERSION] = EV_CURRENT;
+  ehdr.e_ident[EI_OSABI]   = ELF_OSABI;
+
+  ehdr.e_type              = ET_CORE;
+  ehdr.e_machine           = EM_ARCH;
+  ehdr.e_version           = EV_CURRENT;
+  ehdr.e_phoff             = sizeof(Elf_Ehdr);
+  ehdr.e_flags             = EF_FLAG;
+  ehdr.e_ehsize            = sizeof(Elf_Ehdr);
+  ehdr.e_phentsize         = sizeof(Elf_Phdr);
+  ehdr.e_phnum             = segs;
+
+  return elf_emit(cinfo, &ehdr, sizeof(ehdr));
+}
+
+/****************************************************************************
+ * Name: elf_get_ntcb
+ *
+ * Description:
+ *   Calculate the note segment size
+ *
+ ****************************************************************************/
+
+static int elf_get_ntcb(void)
+{
+  int count = 0;
+  int i;
+
+  for (i = 0; i < g_npidhash; i++)
+    {
+      if (g_pidhash[i] != NULL)
+        {
+          count++;
+        }
+    }
+
+  return count;
+}
+
+/****************************************************************************
+ * Name: elf_get_note_size
+ *
+ * Description:
+ *   Calculate the note segment size
+ *
+ ****************************************************************************/
+
+static int elf_get_note_size(int stksegs)
+{
+  int total;
+
+  total  = stksegs * (sizeof(Elf_Nhdr) + ROUNDUP(CONFIG_TASK_NAME_SIZE, 8) +
+                     sizeof(elf_prstatus_t));
+  total += stksegs * (sizeof(Elf_Nhdr) + ROUNDUP(CONFIG_TASK_NAME_SIZE, 8) +
+                     sizeof(elf_prpsinfo_t));
+  return total;
+}
+
+/****************************************************************************
+ * Name: elf_emit_tcb_note
+ *
+ * Description:
+ *   Fill the note segment information from tcb
+ *
+ ****************************************************************************/
+
+static void elf_emit_tcb_note(FAR struct elf_dumpinfo_s *cinfo,
+                              FAR struct tcb_s *tcb)
+{
+  char name[ROUNDUP(CONFIG_TASK_NAME_SIZE, 8)];
+  elf_prstatus_t status;
+  elf_prpsinfo_t info;
+  FAR uintptr_t *regs;
+  Elf_Nhdr nhdr;
+  int i;
+
+  memset(&info,   0x0, sizeof(info));
+  memset(&status, 0x0, sizeof(status));
+
+  /* Fill Process info */
+
+  nhdr.n_namesz = sizeof(name);
+  nhdr.n_descsz = sizeof(info);
+  nhdr.n_type   = NT_PRPSINFO;
+
+  elf_emit(cinfo, &nhdr, sizeof(nhdr));
+
+  strlcpy(name, tcb->name, sizeof(name));
+  elf_emit(cinfo, name, sizeof(name));
+
+  info.pr_pid   = tcb->pid;
+  strlcpy(info.pr_fname, tcb->name, sizeof(info.pr_fname));
+  elf_emit(cinfo, &info, sizeof(info));
+
+  /* Fill Process status */
+
+  nhdr.n_descsz = sizeof(status);
+  nhdr.n_type   = NT_PRSTATUS;
+
+  elf_emit(cinfo, &nhdr, sizeof(nhdr));
+  elf_emit(cinfo, name, sizeof(name));
+
+  status.pr_pid = tcb->pid;
+
+  if (running_task() == tcb)
+    {
+      if (up_interrupt_context())
+        {
+          regs = (FAR uintptr_t *)up_current_regs();
+        }
+      else
+        {
+          up_saveusercontext(g_running_regs);
+          regs = (FAR uintptr_t *)g_running_regs;
+        }
+    }
+  else
+    {
+      regs = (FAR uintptr_t *)tcb->xcp.regs;
+    }
+
+  if (regs != NULL)
+    {
+      for (i = 0; i < nitems(status.pr_regs); i++)
+        {
+          if (g_tcbinfo.reg_off.p[i] == UINT16_MAX)
+            {
+              continue;
+            }
+          else
+            {
+              status.pr_regs[i] =
+                *(uintptr_t *)((uint8_t *)regs + g_tcbinfo.reg_off.p[i]);
+            }
+        }
+    }
+
+  elf_emit(cinfo, &status, sizeof(status));
+}
+
+/****************************************************************************
+ * Name: elf_emit_note
+ *
+ * Description:
+ *   Fill the note segment information
+ *
+ ****************************************************************************/
+
+static void elf_emit_note(FAR struct elf_dumpinfo_s *cinfo)
+{
+  int i;
+
+  if (cinfo->pid == INVALID_PROCESS_ID)
+    {
+      for (i = 0; i < g_npidhash; i++)
+        {
+          if (g_pidhash[i] != NULL)
+            {
+              elf_emit_tcb_note(cinfo, g_pidhash[i]);
+            }
+        }
+    }
+  else
+    {
+      elf_emit_tcb_note(cinfo, nxsched_get_tcb(cinfo->pid));
+    }
+}
+
+/****************************************************************************
+ * Name: elf_emit_tcb_stack
+ *
+ * Description:
+ *   Fill the task stack information from tcb
+ *
+ ****************************************************************************/
+
+static void elf_emit_tcb_stack(FAR struct elf_dumpinfo_s *cinfo,
+                               FAR struct tcb_s *tcb)
+{
+  uintptr_t buf = 0;
+  uintptr_t sp;
+  size_t len;
+
+  if (running_task() != tcb)
+    {
+      sp = up_getusrsp(tcb->xcp.regs);
+
+      if (sp > (uintptr_t)tcb->stack_base_ptr &&
+          sp < (uintptr_t)tcb->stack_base_ptr + tcb->adj_stack_size)
+        {
+          len = ((uintptr_t)tcb->stack_base_ptr +
+                            tcb->adj_stack_size) - sp;
+          buf = sp;
+        }
+#ifdef CONFIG_STACK_COLORATION
+      else
+        {
+          len = up_check_tcbstack(tcb);
+          buf = (uintptr_t)tcb->stack_base_ptr +
+                           (tcb->adj_stack_size - len);
+        }
+#endif
+    }
+
+  if (buf == 0)
+    {
+      buf = (uintptr_t)tcb->stack_alloc_ptr;
+      len = tcb->adj_stack_size +
+            (tcb->stack_base_ptr - tcb->stack_alloc_ptr);
+    }
+
+  sp  = ROUNDDOWN(buf, PROGRAM_ALIGNMENT);
+  len = ROUNDUP(len + (buf - sp), PROGRAM_ALIGNMENT);
+  buf = sp;
+
+  elf_emit(cinfo, (FAR void *)buf, len);
+
+  /* Align to page */
+
+  elf_emit_align(cinfo);
+}
+
+/****************************************************************************
+ * Name: elf_emit_stack
+ *
+ * Description:
+ *   Fill the task stack information
+ *
+ ****************************************************************************/
+
+static void elf_emit_stack(FAR struct elf_dumpinfo_s *cinfo)
+{
+  int i;
+
+  if (cinfo->pid == INVALID_PROCESS_ID)
+    {
+      for (i = 0; i < g_npidhash; i++)
+        {
+          if (g_pidhash[i] != NULL)
+            {
+              elf_emit_tcb_stack(cinfo, g_pidhash[i]);
+            }
+        }
+    }
+  else
+    {
+      elf_emit_tcb_stack(cinfo, nxsched_get_tcb(cinfo->pid));
+    }
+}
+
+/****************************************************************************
+ * Name: elf_emit_memory
+ *
+ * Description:
+ *   Fill the note segment information
+ *
+ ****************************************************************************/
+
+static void elf_emit_memory(FAR struct elf_dumpinfo_s *cinfo, int memsegs)
+{
+  int i;
+
+  for (i = 0; i < memsegs; i++)
+    {
+      if (cinfo->regions[i].flags & PF_REGISTER)
+        {
+          FAR uintptr_t *start = (FAR uintptr_t *)cinfo->regions[i].start;
+          FAR uintptr_t *end = (FAR uintptr_t *)cinfo->regions[i].end;
+          uintptr_t buf[64];
+          size_t offset = 0;
+
+          while (start < end)
+            {
+              buf[offset++] = *start++;
+
+              if (offset % (sizeof(buf) / sizeof(uintptr_t)) == 0)
+                {
+                  elf_emit(cinfo, buf, sizeof(buf));
+                  offset = 0;
+                }
+            }
+
+          if (offset != 0)
+            {
+              elf_emit(cinfo, buf, offset * sizeof(uintptr_t));
+            }
+        }
+      else
+        {
+          elf_emit(cinfo, (FAR void *)cinfo->regions[i].start,
+                   cinfo->regions[i].end - cinfo->regions[i].start);
+        }
+
+      /* Align to page */
+
+      elf_emit_align(cinfo);
+    }
+}
+
+/****************************************************************************
+ * Name: elf_emit_tcb_phdr
+ *
+ * Description:
+ *   Fill the program segment header from tcb
+ *
+ ****************************************************************************/
+
+static void elf_emit_tcb_phdr(FAR struct elf_dumpinfo_s *cinfo,
+                              FAR struct tcb_s *tcb,
+                              FAR Elf_Phdr *phdr, off_t *offset)
+{
+  uintptr_t sp;
+
+  phdr->p_vaddr = 0;
+
+  if (running_task() != tcb)
+    {
+      sp = up_getusrsp(tcb->xcp.regs);
+
+      if (sp > (uintptr_t)tcb->stack_base_ptr &&
+          sp < (uintptr_t)tcb->stack_base_ptr + tcb->adj_stack_size)
+        {
+          phdr->p_filesz = ((uintptr_t)tcb->stack_base_ptr +
+                           tcb->adj_stack_size) - sp;
+          phdr->p_vaddr  = sp;
+        }
+#ifdef CONFIG_STACK_COLORATION
+      else
+        {
+          phdr->p_filesz = up_check_tcbstack(tcb);
+          phdr->p_vaddr  = (uintptr_t)tcb->stack_base_ptr +
+                           (tcb->adj_stack_size - phdr->p_filesz);
+        }
+#endif
+    }
+
+  if (phdr->p_vaddr == 0)
+    {
+      phdr->p_vaddr  = (uintptr_t)tcb->stack_alloc_ptr;
+      phdr->p_filesz = tcb->adj_stack_size +
+                      (tcb->stack_base_ptr - tcb->stack_alloc_ptr);
+    }
+
+  sp = ROUNDDOWN(phdr->p_vaddr, PROGRAM_ALIGNMENT);
+  phdr->p_filesz = ROUNDUP(phdr->p_filesz +
+                           (phdr->p_vaddr - sp), PROGRAM_ALIGNMENT);
+  phdr->p_vaddr  = sp;
+
+  phdr->p_type   = PT_LOAD;
+  phdr->p_offset = ROUNDUP(*offset, ELF_PAGESIZE);
+  phdr->p_paddr  = phdr->p_vaddr;
+  phdr->p_memsz  = phdr->p_filesz;
+  phdr->p_flags  = PF_X | PF_W | PF_R;
+  phdr->p_align  = ELF_PAGESIZE;
+  *offset       += ROUNDUP(phdr->p_memsz, ELF_PAGESIZE);
+
+  elf_emit(cinfo, phdr, sizeof(*phdr));
+}
+
+/****************************************************************************
+ * Name: elf_emit_phdr
+ *
+ * Description:
+ *   Fill the program segment header
+ *
+ ****************************************************************************/
+
+static void elf_emit_phdr(FAR struct elf_dumpinfo_s *cinfo,
+                          int stksegs, int memsegs)
+{
+  off_t offset = cinfo->stream->nput +
+                 (stksegs + memsegs + 1) * sizeof(Elf_Phdr);
+  Elf_Phdr phdr;
+  int i;
+
+  memset(&phdr, 0, sizeof(Elf_Phdr));
+
+  phdr.p_type   = PT_NOTE;
+  phdr.p_offset = offset;
+  phdr.p_filesz = elf_get_note_size(stksegs);
+  offset       += phdr.p_filesz;
+
+  elf_emit(cinfo, &phdr, sizeof(phdr));
+
+  if (cinfo->pid == INVALID_PROCESS_ID)
+    {
+      for (i = 0; i < g_npidhash; i++)
+        {
+          if (g_pidhash[i] != NULL)
+            {
+              elf_emit_tcb_phdr(cinfo, g_pidhash[i], &phdr, &offset);
+            }
+        }
+    }
+  else
+    {
+      elf_emit_tcb_phdr(cinfo, nxsched_get_tcb(cinfo->pid),
+                        &phdr, &offset);
+    }
+
+  /* Write program headers for segments dump */
+
+  for (i = 0; i < memsegs; i++)
+    {
+      phdr.p_type   = PT_LOAD;
+      phdr.p_offset = ROUNDUP(offset, ELF_PAGESIZE);
+      phdr.p_vaddr  = cinfo->regions[i].start;
+      phdr.p_paddr  = phdr.p_vaddr;
+      phdr.p_filesz = cinfo->regions[i].end - cinfo->regions[i].start;
+      phdr.p_memsz  = phdr.p_filesz;
+      phdr.p_flags  = cinfo->regions[i].flags;
+      phdr.p_align  = ELF_PAGESIZE;
+      offset       += ROUNDUP(phdr.p_memsz, ELF_PAGESIZE);
+      elf_emit(cinfo, &phdr, sizeof(phdr));
+    }
+}
+
 /****************************************************************************
  * Name: coredump_dump_syslog
  *
@@ -106,7 +661,7 @@ static void coredump_dump_syslog(pid_t pid)
 
   /* Do core dump */
 
-  core_dump(g_regions, stream, pid);
+  coredump(g_regions, stream, pid);
 
 #  ifdef CONFIG_BOARD_COREDUMP_COMPRESSION
   _alert("Finish coredump (Compression Enabled). %s formatted\n",
@@ -161,7 +716,7 @@ static void coredump_dump_blkdev(pid_t pid)
   stream = &g_lzfstream;
 #endif
 
-  ret = core_dump(g_regions, stream, pid);
+  ret = coredump(g_regions, stream, pid);
   if (ret < 0)
     {
       _alert("Coredump fail\n");
@@ -352,3 +907,87 @@ void coredump_dump(pid_t pid)
   coredump_dump_blkdev(pid);
 #endif
 }
+
+/****************************************************************************
+ * Name: coredump
+ *
+ * Description:
+ *   This function for generating core dump stream.
+ *
+ ****************************************************************************/
+
+int coredump(FAR const struct memory_region_s *regions,
+             FAR struct lib_outstream_s *stream,
+             pid_t pid)
+{
+  struct elf_dumpinfo_s cinfo;
+  irqstate_t flags;
+  int memsegs = 0;
+  int stksegs;
+
+  cinfo.regions = regions;
+  cinfo.stream  = stream;
+  cinfo.pid     = pid;
+
+  flags = enter_critical_section();
+
+  if (cinfo.pid != INVALID_PROCESS_ID)
+    {
+      if (nxsched_get_tcb(cinfo.pid) == NULL)
+        {
+          leave_critical_section(flags);
+          return -EINVAL;
+        }
+
+      stksegs = 1;
+    }
+  else
+    {
+      stksegs = elf_get_ntcb();
+    }
+
+  /* Check the memory region */
+
+  if (cinfo.regions != NULL)
+    {
+      for (; cinfo.regions[memsegs].start <
+             cinfo.regions[memsegs].end; memsegs++);
+    }
+
+  /* Fill notes section */
+
+  elf_emit_hdr(&cinfo, stksegs + memsegs + 1);
+
+  /* Fill all the program information about the process for the
+   * notes.  This also sets up the file header.
+   */
+
+  elf_emit_phdr(&cinfo, stksegs, memsegs);
+
+  /* Fill note information */
+
+  elf_emit_note(&cinfo);
+
+  /* Align to page */
+
+  elf_emit_align(&cinfo);
+
+  /* Dump stack */
+
+  elf_emit_stack(&cinfo);
+
+  /* Dump memory segments */
+
+  if (memsegs > 0)
+    {
+      elf_emit_memory(&cinfo, memsegs);
+    }
+
+  /* Flush the dump */
+
+  elf_flush(&cinfo);
+
+  leave_critical_section(flags);
+
+  return OK;
+}