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 2021/11/24 02:48:12 UTC

[incubator-nuttx] branch master updated: binfmt/elf: add bare metal coredump support

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/incubator-nuttx.git


The following commit(s) were added to refs/heads/master by this push:
     new 7cbb8da  binfmt/elf: add bare metal coredump support
7cbb8da is described below

commit 7cbb8da692f48c459a5b881438c0bad704713a36
Author: chao.an <an...@xiaomi.com>
AuthorDate: Wed Nov 17 23:53:28 2021 +0800

    binfmt/elf: add bare metal coredump support
    
    Signed-off-by: chao.an <an...@xiaomi.com>
---
 arch/arm/include/elf.h          |   9 +
 binfmt/Makefile                 |   1 +
 binfmt/binfmt_coredump.c        |  69 ++++++++
 binfmt/elf.c                    |  31 ++++
 binfmt/libelf/Kconfig           |  11 ++
 binfmt/libelf/Make.defs         |   6 +
 binfmt/libelf/libelf_coredump.c | 370 ++++++++++++++++++++++++++++++++++++++++
 binfmt/nxflat.c                 |   1 +
 include/nuttx/binfmt/binfmt.h   |  31 ++++
 include/nuttx/binfmt/elf.h      |  30 ++++
 include/nuttx/elf.h             |  64 +++++++
 11 files changed, 623 insertions(+)

diff --git a/arch/arm/include/elf.h b/arch/arm/include/elf.h
index e74fbf4..f23bc87 100644
--- a/arch/arm/include/elf.h
+++ b/arch/arm/include/elf.h
@@ -248,4 +248,13 @@
 #define DT_ARM_PREEMPTMAP        0x70000002
 #define DT_ARM_RESERVED2         0x70000003
 
+/* ELF register definitions */
+
+/* Holds the general purpose registers $a1 * through to $pc
+ * at indices 0 to 15.  At index 16 the program status register.
+ * Index 17 should be set to zero.
+ */
+
+typedef unsigned long elf_gregset_t[18];
+
 #endif /* __ARCH_ARM_INCLUDE_ELF_H */
diff --git a/binfmt/Makefile b/binfmt/Makefile
index ad37a6b..2050090 100644
--- a/binfmt/Makefile
+++ b/binfmt/Makefile
@@ -25,6 +25,7 @@ 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_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
new file mode 100644
index 0000000..3ac198a
--- /dev/null
+++ b/binfmt/binfmt_coredump.c
@@ -0,0 +1,69 @@
+/****************************************************************************
+ * binfmt/binfmt_coredump.c
+ *
+ * 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 struct memory_region_s *regions,
+              FAR struct lib_outstream_s *stream)
+{
+  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);
+          if (ret == OK)
+            {
+              break;
+            }
+        }
+    }
+
+  return ret;
+}
+
+#endif /* CONFIG_BINFMT_DISABLE */
diff --git a/binfmt/elf.c b/binfmt/elf.c
index fd99c3d..1496361 100644
--- a/binfmt/elf.c
+++ b/binfmt/elf.c
@@ -72,6 +72,10 @@ 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 struct memory_region_s *regions,
+                          FAR struct lib_outstream_s *stream);
+#endif
 #if defined(CONFIG_DEBUG_FEATURES) && defined(CONFIG_DEBUG_BINFMT)
 static void elf_dumploadinfo(FAR struct elf_loadinfo_s *loadinfo);
 #endif
@@ -85,6 +89,9 @@ static struct binfmt_s g_elfbinfmt =
   NULL,             /* next */
   elf_loadbinary,   /* load */
   NULL,             /* unload */
+#ifdef CONFIG_ELF_COREDUMP
+  elf_dumpbinary,   /* coredump */
+#endif
 };
 
 /****************************************************************************
@@ -296,6 +303,30 @@ errout_with_init:
 }
 
 /****************************************************************************
+ * 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 struct memory_region_s *regions,
+                          FAR struct lib_outstream_s *stream)
+{
+  struct elf_dumpinfo_s dumpinfo;
+
+  dumpinfo.regions = regions;
+  dumpinfo.stream  = stream;
+
+  return elf_coredump(&dumpinfo);
+}
+#endif
+
+/****************************************************************************
  * Public Functions
  ****************************************************************************/
 
diff --git a/binfmt/libelf/Kconfig b/binfmt/libelf/Kconfig
index 4cbe8c0..8ec9450 100644
--- a/binfmt/libelf/Kconfig
+++ b/binfmt/libelf/Kconfig
@@ -62,3 +62,14 @@ config ELF_SYMBOL_CACHECOUNT
 	---help---
 		This is a cache that is used to store elf symbol table to
 		reduce access fs. Default: 256
+
+config ELF_COREDUMP
+	bool "ELF Coredump"
+	select DEBUG_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/binfmt/libelf/Make.defs b/binfmt/libelf/Make.defs
index 3646fd3..1f9cb16 100644
--- a/binfmt/libelf/Make.defs
+++ b/binfmt/libelf/Make.defs
@@ -30,6 +30,12 @@ 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 += ${shell $(INCDIR) "$(CC)" $(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
new file mode 100644
index 0000000..e8eb84b
--- /dev/null
+++ b/binfmt/libelf/libelf_coredump.c
@@ -0,0 +1,370 @@
+/****************************************************************************
+ * binfmt/libelf/libelf_coredump.c
+ *
+ * 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 <sys/stat.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
+ ****************************************************************************/
+
+#define ELF_PAGESIZE    4096
+#define ELF_BLOCKSIZE   1024
+
+#define ARRAY_SIZE(x)   (sizeof(x) / sizeof((x)[0]))
+#define ROUNDUP(x, y)   ((x + (y - 1)) / (y)) * (y)
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: elf_flush
+ *
+ * Description:
+ *   Flush the out stream
+ *
+ ****************************************************************************/
+
+static int elf_flush(FAR struct elf_dumpinfo_s *cinfo)
+{
+  return cinfo->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 = cinfo->stream->puts(cinfo->stream, ptr, total > ELF_BLOCKSIZE ?
+                                ELF_BLOCKSIZE : 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_header
+ *
+ * Description:
+ *   Fill the elf header
+ *
+ ****************************************************************************/
+
+static int elf_emit_header(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_note_size
+ *
+ * Description:
+ *   Calculate the note segment size
+ *
+ ****************************************************************************/
+
+static int elf_get_note_size(void)
+{
+  int count = 0;
+  int total;
+  int i;
+
+  for (i = 0; i < g_npidhash; i++)
+    {
+      if (g_pidhash[i])
+        {
+          count++;
+        }
+    }
+
+  total  = count * (sizeof(Elf_Nhdr) + ROUNDUP(CONFIG_TASK_NAME_SIZE, 8) +
+                    sizeof(elf_prstatus_t));
+  total += count * (sizeof(Elf_Nhdr) + ROUNDUP(CONFIG_TASK_NAME_SIZE, 8) +
+                    sizeof(elf_prpsinfo_t));
+  return total;
+}
+
+/****************************************************************************
+ * Name: elf_emit_note_info
+ *
+ * Description:
+ *   Fill the note segment information
+ *
+ ****************************************************************************/
+
+static void elf_emit_note_info(FAR struct elf_dumpinfo_s *cinfo)
+{
+  char name[ROUNDUP(CONFIG_TASK_NAME_SIZE, 8)];
+  FAR struct tcb_s *tcb;
+  elf_prstatus_t status;
+  elf_prpsinfo_t info;
+  Elf_Nhdr nhdr;
+  int i;
+  int j;
+
+  memset(&info,   0x0, sizeof(info));
+  memset(&status, 0x0, sizeof(status));
+
+  for (i = 0; i < g_npidhash; i++)
+    {
+      if (g_pidhash[i] == NULL)
+        {
+          continue;
+        }
+
+      tcb = g_pidhash[i];
+
+      /* Fill Process info */
+
+      nhdr.n_namesz = sizeof(name);
+      nhdr.n_descsz = sizeof(info);
+      nhdr.n_type   = NT_PRPSINFO;
+
+      elf_emit(cinfo, &nhdr, sizeof(nhdr));
+
+      strncpy(name, tcb->name, sizeof(name));
+      elf_emit(cinfo, name, sizeof(name));
+
+      info.pr_pid   = tcb->pid;
+      strncpy(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;
+
+      for (j = 0; j < ARRAY_SIZE(status.pr_regs); j++)
+        {
+          status.pr_regs[j] = *(uintptr_t *)((uint8_t *)tcb +
+                                             g_tcbinfo.reg_offs[j]);
+        }
+
+      elf_emit(cinfo, &status, sizeof(status));
+    }
+}
+
+/****************************************************************************
+ * Name: elf_emit_program_header
+ *
+ * Description:
+ *   Fill the program segment header
+ *
+ ****************************************************************************/
+
+static void elf_emit_program_header(FAR struct elf_dumpinfo_s *cinfo,
+                                    int segs)
+{
+  off_t offset = cinfo->stream->nput + (segs + 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();
+  offset       += phdr.p_filesz;
+
+  elf_emit(cinfo, &phdr, sizeof(phdr));
+
+  /* Write program headers for segments dump */
+
+  for (i = 0; i < segs; i++)
+    {
+      phdr.p_type   = PT_LOAD;
+      phdr.p_offset = ROUNDUP(offset, ELF_PAGESIZE);
+      phdr.p_vaddr  = cinfo->regions[i].start;
+      phdr.p_paddr  = cinfo->regions[i].start;
+      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)
+{
+  int segs = 0;
+  int i;
+
+  /* Check the memory region */
+
+  if (cinfo->regions)
+    {
+      for (; cinfo->regions[segs].start <
+             cinfo->regions[segs].end; segs++);
+    }
+
+  if (segs == 0)
+    {
+      return -EINVAL;
+    }
+
+  /* Fill notes section */
+
+  elf_emit_header(cinfo, segs + 1);
+
+  /* Fill all the program information about the process for the
+   * notes.  This also sets up the file header.
+   */
+
+  elf_emit_program_header(cinfo, segs);
+
+  /* Fill note information */
+
+  elf_emit_note_info(cinfo);
+
+  /* Align to page */
+
+  elf_emit_align(cinfo);
+
+  /* Start dump the memory */
+
+  for (i = 0; i < segs; i++)
+    {
+      elf_emit(cinfo, (FAR void *)cinfo->regions[i].start,
+               cinfo->regions[i].end -
+               cinfo->regions[i].start);
+
+      /* Align to page */
+
+      elf_emit_align(cinfo);
+    }
+
+  /* Flush the dump */
+
+  return elf_flush(cinfo);
+}
diff --git a/binfmt/nxflat.c b/binfmt/nxflat.c
index 476a04a..9eac32e 100644
--- a/binfmt/nxflat.c
+++ b/binfmt/nxflat.c
@@ -84,6 +84,7 @@ static struct binfmt_s g_nxflatbinfmt =
   NULL,                /* next */
   nxflat_loadbinary,   /* load */
   nxflat_unloadbinary, /* unload */
+  NULL,                /* coredump */
 };
 
 /****************************************************************************
diff --git a/include/nuttx/binfmt/binfmt.h b/include/nuttx/binfmt/binfmt.h
index e49a80f..416cc6c 100644
--- a/include/nuttx/binfmt/binfmt.h
+++ b/include/nuttx/binfmt/binfmt.h
@@ -33,6 +33,7 @@
 
 #include <nuttx/arch.h>
 #include <nuttx/sched.h>
+#include <nuttx/streams.h>
 
 /****************************************************************************
  * Pre-processor Definitions
@@ -102,6 +103,15 @@ struct binary_s
   CODE int (*unload)(FAR struct binary_s *bin);
 };
 
+/* This describes binfmt coredump filed */
+
+struct memory_region_s
+{
+  uintptr_t start;   /* Start address of this region */
+  uintptr_t end;     /* End address of this region */
+  uint32_t  flags;   /* Figure 5-3: Segment Flag Bits: PF_[X|W|R] */
+};
+
 /* This describes one binary format handler */
 
 struct binfmt_s
@@ -120,6 +130,11 @@ struct binfmt_s
   /* Unload module callback */
 
   CODE int (*unload)(FAR struct binary_s *bin);
+
+  /* Unload module callback */
+
+  CODE int (*coredump)(FAR struct memory_region_s *regions,
+                       FAR struct lib_outstream_s *stream);
 };
 
 /****************************************************************************
@@ -176,6 +191,22 @@ 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 struct memory_region_s *regions,
+              FAR struct lib_outstream_s *stream);
+
+/****************************************************************************
  * Name: load_module
  *
  * Description:
diff --git a/include/nuttx/binfmt/elf.h b/include/nuttx/binfmt/elf.h
index 7d59f28..46e74bb 100644
--- a/include/nuttx/binfmt/elf.h
+++ b/include/nuttx/binfmt/elf.h
@@ -135,6 +135,18 @@ 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 struct memory_region_s *regions;
+  FAR struct lib_outstream_s *stream;
+};
+#endif
+
 /****************************************************************************
  * Public Function Prototypes
  ****************************************************************************/
@@ -255,6 +267,24 @@ int elf_bind(FAR struct elf_loadinfo_s *loadinfo,
 
 int elf_unload(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/elf.h b/include/nuttx/elf.h
index 19713d0..b9c2588 100644
--- a/include/nuttx/elf.h
+++ b/include/nuttx/elf.h
@@ -26,6 +26,70 @@
  ****************************************************************************/
 
 #include <elf.h>
+#ifdef CONFIG_ELF_COREDUMP
+#include <arch/elf.h>
+#endif
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+#define ELF_PRARGSZ    (80)  /* Number of chars for args */
+
+/****************************************************************************
+ * Public Types
+ ****************************************************************************/
+
+#ifdef CONFIG_ELF_COREDUMP
+typedef struct elf_prpsinfo_s
+{
+  char           pr_state;    /* Numeric process state */
+  char           pr_sname;    /* Char for pr_state */
+  char           pr_zomb;     /* Zombie */
+  char           pr_nice;     /* Nice val */
+  unsigned long  pr_flag;     /* Flags */
+  unsigned short pr_uid;
+  unsigned short pr_gid;
+  int            pr_pid;
+  int            pr_ppid;
+  int            pr_pgrp;
+  int            pr_sid;
+  char           pr_fname[16];           /* Filename of executable */
+  char           pr_psargs[ELF_PRARGSZ]; /* Initial part of arg list */
+} elf_prpsinfo_t;
+
+typedef struct elf_siginfo_s
+{
+  int            si_signo;    /* Signal number */
+  int            si_code;     /* Extra code */
+  int            si_errno;    /* Errno */
+} elf_siginfo_t;
+
+typedef struct elf_timeval_s
+{
+  long           tv_sec;      /* Seconds */
+  long           tv_usec;     /* Microseconds */
+} elf_timeval_t;
+
+typedef struct elf_prstatus_s
+{
+  elf_siginfo_t  pr_info;     /* Info associated with signal */
+  short          pr_cursig;   /* Current signal */
+  short          pr_padding;  /* Padding align */
+  unsigned long  pr_sigpend;  /* Set of pending signals */
+  unsigned long  pr_sighold;  /* Set of held signals */
+  int            pr_pid;
+  int            pr_ppid;
+  int            pr_pgrp;
+  int            pr_sid;
+  elf_timeval_t  pr_utime;    /* User time */
+  elf_timeval_t  pr_stime;    /* System time */
+  elf_timeval_t  pr_cutime;   /* Cumulative user time */
+  elf_timeval_t  pr_cstime;   /* Cumulative system time */
+  elf_gregset_t  pr_regs;
+  int            pr_fpvalid;  /* True if math co-processor being used */
+} elf_prstatus_t;
+#endif
 
 /****************************************************************************
  * Public Function Prototypes