diff --git a/Makefile b/Makefile
index 221fbd8..1174628 100644
--- a/Makefile
+++ b/Makefile
@@ -135,7 +135,8 @@ iov.o: iov.c iov.h
 ######################################################################
 
 qemu-img.o: qemu-img-cmds.h
-qemu-img.o qemu-tool.o qemu-nbd.o qemu-io.o: $(GENERATED_HEADERS)
+qemu-core-filter.o: qemu-core-filter.h
+qemu-img.o qemu-tool.o qemu-nbd.o qemu-io.o qemu-core-filter.o: $(GENERATED_HEADERS)
 
 qemu-img$(EXESUF): qemu-img.o qemu-tool.o qemu-error.o $(block-obj-y) $(qobject-obj-y)
 
@@ -143,6 +144,8 @@ qemu-nbd$(EXESUF): qemu-nbd.o qemu-tool.o qemu-error.o $(block-obj-y) $(qobject-
 
 qemu-io$(EXESUF): qemu-io.o cmd.o qemu-tool.o qemu-error.o $(block-obj-y) $(qobject-obj-y)
 
+qemu-core-filter$(EXESUF): qemu-core-filter.o
+
 qemu-img-cmds.h: $(SRC_PATH)/qemu-img-cmds.hx
 	$(call quiet-command,sh $(SRC_PATH)/hxtool -h < $< > $@,"  GEN   $@")
 
@@ -324,6 +327,7 @@ tarbin:
 	$(patsubst %,$(bindir)/%, $(USER_PROGS)) \
 	$(bindir)/qemu-img \
 	$(bindir)/qemu-nbd \
+	$(bindir)/qemu-core-filter \
 	$(datadir)/bios.bin \
 	$(datadir)/vgabios.bin \
 	$(datadir)/vgabios-cirrus.bin \
diff --git a/configure b/configure
index c0d8aa5..7aa8189 100755
--- a/configure
+++ b/configure
@@ -271,6 +271,7 @@ vnc_sasl=""
 xen=""
 linux_aio=""
 vhost_net=""
+core_filter_tool="no"
 
 gprof="no"
 debug_tcg="no"
@@ -687,6 +688,10 @@ for opt do
   ;;
   --enable-vhost-net) vhost_net="yes"
   ;;
+  --disable-core-filter) core_filter_tool="no"
+  ;;
+  --enable-core-filter) core_filter_tool="yes"
+  ;;
   --*dir)
   ;;
   *) echo "ERROR: unknown option $opt"; show_help="yes"
@@ -865,6 +870,8 @@ echo "  --enable-docs            enable documentation build"
 echo "  --disable-docs           disable documentation build"
 echo "  --disable-vhost-net      disable vhost-net acceleration support"
 echo "  --enable-vhost-net       enable vhost-net acceleration support"
+echo "  --disable-core-filter    do not build qemu-core-filter tool (default)"
+echo "  --enable-core-filter     build qemu-core-filter tool"
 echo ""
 echo "NOTE: The object files are built at the place where configure is launched"
 exit 1
@@ -1021,6 +1028,18 @@ case "$cpu" in
   ;;
 esac
 
+#########################################
+# qemu-core-filter tool for x86 and x86_64
+if test "$core_filter_tool" != "no"; then
+  if test \( "$cpu" = "i386" -o "$cpu" = "x86_64" \) -a \
+          "$targetos" == "Linux" ; then \
+    core_filter_tool=yes
+  else
+    echo -n "Currently qemu-core-filter is only supported for Linux"
+    echo " on x86 and x86_64."
+    exit 1;
+  fi
+fi
 
 ##########################################
 # NPTL probe
@@ -1048,6 +1067,21 @@ EOF
 fi
 
 ##########################################
+# elfutils/version.h header file check
+
+if test "$core_filter_tool" != "no" ; then
+  elf_version_h=no
+  cat > $TMPC <<EOF
+#include <elfutils/version.h>
+int main(void) { return 0; }
+EOF
+
+  if compile_prog "" ""; then
+    elf_version_h=yes
+  fi
+fi
+
+##########################################
 # zlib check
 
 cat > $TMPC << EOF
@@ -1086,6 +1120,34 @@ EOF
 fi
 
 ##########################################
+# elfutils library probe
+
+if test "$core_filter_tool" != "no" ; then
+  elf_libs="-ldw -lelf"
+  cat > $TMPC <<EOF
+#include <elf.h>
+#include <dwarf.h>
+#include <elfutils/libdw.h>
+int main(void) {
+  dwarf_begin_elf(NULL, 0, NULL);
+  dwarf_attr(NULL, 0, NULL);
+  elf_version(EV_CURRENT);
+  return 0;
+}
+EOF
+  if compile_prog "" "$elf_libs" ; then
+    core_filter_tool=yes
+    libs_tools="$libs_tools $elf_libs"
+  else
+    if test "$core_filter_tool" = "yes" ; then
+      echo "ERROR: elfutils libraries (libdw and libelf) are missing."
+      exit 1;
+    fi
+    core_filter_tool=no
+  fi
+fi
+
+##########################################
 # pkgconfig probe
 
 pkgconfig="${cross_prefix}pkg-config"
@@ -2014,6 +2076,10 @@ if test "$softmmu" = yes ; then
   fi
 fi
 
+if test "$core_filter_tool" = "yes"; then \
+  tools="qemu-core-filter\$(EXESUF) $tools"
+fi
+
 # Mac OS X ships with a broken assembler
 roms=
 if test \( "$cpu" = "i386" -o "$cpu" = "x86_64" \) -a \
@@ -2086,6 +2152,7 @@ echo "preadv support    $preadv"
 echo "fdatasync         $fdatasync"
 echo "uuid support      $uuid"
 echo "vhost-net support $vhost_net"
+echo "build core-filter $core_filter_tool"
 
 if test $sdl_too_old = "yes"; then
 echo "-> Your SDL version is too old - please upgrade to have SDL support"
@@ -2312,6 +2379,11 @@ echo "CONFIG_UNAME_RELEASE=\"$uname_release\"" >> $config_host_mak
 if test "$zero_malloc" = "yes" ; then
   echo "CONFIG_ZERO_MALLOC=y" >> $config_host_mak
 fi
+if test "$core_filter_tool" = "yes"; then
+  if test "$elf_version_h" = "yes" ; then
+    echo "HAVE_ELFUTILS_VERSION_H=y" >> $config_host_mak
+  fi
+fi
 
 # USB host support
 case "$usb" in
diff --git a/create_config b/create_config
index 0098e68..59227f1 100755
--- a/create_config
+++ b/create_config
@@ -37,6 +37,9 @@ case $line in
     done
     echo "    NULL"
     ;;
+ HAVE_ELFUTILS_VERSION_H=y)
+    echo "#define HAVE_ELFUTILS_VERSION_H 1"
+    ;;
  CONFIG_*=y) # configuration
     name=${line%=*}
     echo "#define $name 1"
diff --git a/qemu-core-filter.c b/qemu-core-filter.c
new file mode 100644
index 0000000..ab90c61
--- /dev/null
+++ b/qemu-core-filter.c
@@ -0,0 +1,1976 @@
+/*
+ * qemu-core-filter.c
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * Copyright (C) 2010 IBM Corporation
+ * Author: Mahesh Salgaonkar <mahesh@linux.vnet.ibm.com>
+ *
+ * Adopted from: http://sourceforge.net/projects/makedumpfile
+ *    Some of the code source are adopted from makdumpfile project
+ *    which is GPL License sources.
+ */
+#include "qemu-core-filter.h"
+
+struct CoreDumpInfo *in_core = NULL;
+struct CoreDumpInfo *out_core = NULL;
+
+struct GuestOSMemMap    *guest_os_memmap = NULL;
+struct DwarfInfo dwarf_info;
+
+int debug_flag = 0;
+int force_overwrite = 0;
+const off_t failed = (off_t)-1;
+
+const char *debuginfo_directory = "/usr/lib/debug";
+
+#ifndef BUILD_ID_SUPPORT
+const char *debuginfo_default_paths[] = {
+    "/bin",
+    "/usr/bin",
+    "/usr/libexec",
+    NULL
+};
+#endif
+
+static int get_debug_info(void);
+
+static struct option longopts[] = {
+    {"symbols", required_argument, NULL, 's'},
+    {"force", required_argument, NULL, 'f'},
+    {"help", no_argument, NULL, 'h'},
+    { 0, 0, 0, 0}
+};
+
+static void print_usage(void)
+{
+    printf("\n");
+    printf("QEMU coredump filter version %s (qemu-core-filter-%s)\n", VERSION, VERSION);
+    printf("Usage:\n");
+    printf("\n");
+    printf("    qemu-core-filter [options] CORE DUMPFILE\n");
+    printf("\n");
+    printf("\n");
+    printf("Available options:\n");
+    printf("  -s|--symbols FILENAME\n");
+    printf("         This is a pathname to the qemu debuginfo file.\n");
+    printf("         This file must have the debug information.\n");
+    printf("  -f|--force\n");
+    printf("         force overwrite if o/p DUMPFILE already exists.\n");
+    printf("  -d\n");
+    printf("         Turn on the debug messages.\n");
+    printf("  -h|--help\n");
+    printf("         Prinf this message.\n");
+    printf("  CORE:\n");
+    printf("         This is a pathname to the qemu coredump image.\n");
+    printf("  DUMPFILE:\n");
+    printf("         This is a pathname to a file created by this command.\n");
+    printf("\n");
+}
+
+static int get_elf64_ehdr(Elf64_Ehdr *ehdr)
+{
+    if (lseek(in_core->fd_corefile, 0, SEEK_SET) == failed) {
+        ERRMSG("Can't seek the dump memory(%s). %s\n",
+            in_core->corefile_name, strerror(errno));
+        return FALSE;
+    }
+    if (read(in_core->fd_corefile, ehdr, sizeof(Elf64_Ehdr))
+        != sizeof(Elf64_Ehdr)) {
+        ERRMSG("Can't read the dump memory(%s). %s\n",
+            in_core->corefile_name, strerror(errno));
+        return FALSE;
+    }
+    if (ehdr->e_ident[EI_CLASS] != ELFCLASS64) {
+        ERRMSG("Can't get valid e_ident.\n");
+        return FALSE;
+    }
+    return TRUE;
+}
+
+static int get_elf64_phdr(int fd, char *filename, int index, Elf64_Phdr *phdr)
+{
+    off_t offset;
+
+    offset = sizeof(Elf64_Ehdr) + sizeof(Elf64_Phdr) * index;
+
+    if (lseek(fd, offset, SEEK_SET) == failed) {
+        ERRMSG("Can't seek %s. %s\n", filename, strerror(errno));
+        return FALSE;
+    }
+    if (read(fd, phdr, sizeof(Elf64_Phdr)) != sizeof(Elf64_Phdr)) {
+        ERRMSG("Can't read %s. %s\n", filename, strerror(errno));
+        return FALSE;
+    }
+    return TRUE;
+}
+
+static int get_elf32_ehdr(Elf32_Ehdr *ehdr)
+{
+    if (lseek(in_core->fd_corefile, 0, SEEK_SET) == failed) {
+        ERRMSG("Can't seek the dump memory(%s). %s\n",
+            in_core->corefile_name, strerror(errno));
+        return FALSE;
+    }
+    if (read(in_core->fd_corefile, ehdr, sizeof(Elf32_Ehdr))
+        != sizeof(Elf32_Ehdr)) {
+        ERRMSG("Can't read the dump memory(%s). %s\n",
+            in_core->corefile_name, strerror(errno));
+        return FALSE;
+    }
+    if (ehdr->e_ident[EI_CLASS] != ELFCLASS32) {
+        ERRMSG("Can't get valid e_ident.\n");
+        return FALSE;
+    }
+    return TRUE;
+}
+
+static int get_elf32_phdr(int fd, char *filename, int index, Elf32_Phdr *phdr)
+{
+    off_t offset;
+
+    offset = sizeof(Elf32_Ehdr) + sizeof(Elf32_Phdr) * index;
+
+    if (lseek(fd, offset, SEEK_SET) == failed) {
+        ERRMSG("Can't seek %s. %s\n", filename, strerror(errno));
+        return FALSE;
+    }
+    if (read(fd, phdr, sizeof(Elf32_Phdr)) != sizeof(Elf32_Phdr)) {
+        ERRMSG("Can't read %s. %s\n", filename, strerror(errno));
+        return FALSE;
+    }
+    return TRUE;
+}
+
+static int check_elf_format(int fd, char *filename, int *phnum, int *num_load,
+                    int *elf_type)
+{
+    int i;
+    Elf64_Ehdr ehdr64;
+    Elf64_Phdr load64;
+    Elf32_Ehdr ehdr32;
+    Elf32_Phdr load32;
+
+    if (lseek(fd, 0, SEEK_SET) == failed) {
+        ERRMSG("Can't seek %s. %s\n", filename, strerror(errno));
+        return FALSE;
+    }
+    if (read(fd, &ehdr64, sizeof(Elf64_Ehdr)) != sizeof(Elf64_Ehdr)) {
+        ERRMSG("Can't read %s. %s\n", filename, strerror(errno));
+        return FALSE;
+    }
+    if (lseek(fd, 0, SEEK_SET) == failed) {
+        ERRMSG("Can't seek %s. %s\n", filename, strerror(errno));
+        return FALSE;
+    }
+    if (read(fd, &ehdr32, sizeof(Elf32_Ehdr)) != sizeof(Elf32_Ehdr)) {
+        ERRMSG("Can't read %s. %s\n", filename, strerror(errno));
+        return FALSE;
+    }
+    (*num_load) = 0;
+    if ((ehdr64.e_ident[EI_CLASS] == ELFCLASS64)
+        && (ehdr32.e_ident[EI_CLASS] != ELFCLASS32)) {
+        (*elf_type) = ehdr64.e_type;
+        (*phnum) = ehdr64.e_phnum;
+        for (i = 0; i < ehdr64.e_phnum; i++) {
+            if (!get_elf64_phdr(fd, filename, i, &load64)) {
+                ERRMSG("Can't find Phdr %d.\n", i);
+                return FALSE;
+            }
+            /* DEBUG_MSG("load64.p_type = %d\n", load64.p_type); */
+            if (load64.p_type == PT_LOAD)
+                (*num_load)++;
+        }
+        return ELF64;
+
+    } else if ((ehdr64.e_ident[EI_CLASS] != ELFCLASS64)
+        && (ehdr32.e_ident[EI_CLASS] == ELFCLASS32)) {
+        (*elf_type) = ehdr32.e_type;
+        (*phnum) = ehdr32.e_phnum;
+        for (i = 0; i < ehdr32.e_phnum; i++) {
+            if (!get_elf32_phdr(fd, filename, i, &load32)) {
+                ERRMSG("Can't find Phdr %d.\n", i);
+                return FALSE;
+            }
+            /* DEBUG_MSG("load32.p_type = %d\n", load32.p_type); */
+            if (load32.p_type == PT_LOAD)
+                (*num_load)++;
+        }
+        return ELF32;
+    }
+    ERRMSG("Can't get valid ehdr.\n");
+    return FALSE;
+}
+
+static int open_debugfile(void)
+{
+    in_core->fd_qemu_debug = open(in_core->name_qemu_debug, O_RDONLY);
+    if (in_core->fd_qemu_debug < 0) {
+        ERRMSG("Can't open debuginfo file for reading. %s\n",
+            strerror(errno));
+        return -errno;
+    }
+    return 0;
+}
+
+static int qemu_validate_options(void)
+{
+    /* Open input core file for reading. */
+    in_core->fd_corefile = open(in_core->corefile_name,
+                        O_RDONLY | O_LARGEFILE);
+    if (in_core->fd_corefile < 0) {
+        ERRMSG("Can't open input core file for reading. %s\n",
+            strerror(errno));
+        return -errno;
+    }
+
+    /* Open debuginfo file */
+    if (in_core->name_qemu_debug) {
+        int retval = open_debugfile();
+        if (retval) {
+            return retval;
+        }
+    }
+    return 0;
+}
+
+static void free_core_info(struct CoreDumpInfo * core_info)
+{
+    if (core_info->fd_corefile > 0) {
+        close(core_info->fd_corefile);
+    }
+
+    if (core_info->fd_qemu_debug > 0) {
+        close(core_info->fd_qemu_debug);
+    }
+
+    if (core_info->pt_load_segments) {
+        free(core_info->pt_load_segments);
+    }
+
+#ifdef BUILD_ID_SUPPORT
+    if (core_info->build_id) {
+        free(core_info->build_id);
+    }
+
+    if (core_info->dbg_build_id) {
+        free(core_info->dbg_build_id);
+    }
+
+#else
+    if (core_info->pgm_name) {
+        free(core_info->pgm_name);
+    }
+#endif
+}
+
+static void free_guest_os_memmap(void)
+{
+    struct GuestOSMemMap *p, *n;
+
+    p = guest_os_memmap;
+
+    while (p) {
+        n = p->next;
+        free(p);
+        p = n;
+    }
+    guest_os_memmap = NULL;
+}
+
+static int get_elf_phdr_memory(int index, Elf64_Phdr *phdr)
+{
+    Elf32_Phdr phdr32;
+
+    if (in_core->flag_elf64) { /* ELF64 */
+        if (!get_elf64_phdr(in_core->fd_corefile,
+                in_core->corefile_name, index, phdr)) {
+            ERRMSG("Can't find Phdr %d.\n", index);
+            return FALSE;
+        }
+    } else {
+        if (!get_elf32_phdr(in_core->fd_corefile,
+                in_core->corefile_name, index, &phdr32)) {
+            ERRMSG("Can't find Phdr %d.\n", index);
+            return FALSE;
+        }
+        memset(phdr, 0, sizeof(Elf64_Phdr));
+        phdr->p_type   = phdr32.p_type;
+        phdr->p_flags  = phdr32.p_flags;
+        phdr->p_offset = phdr32.p_offset;
+        phdr->p_vaddr  = phdr32.p_vaddr;
+        phdr->p_paddr  = phdr32.p_paddr;
+        phdr->p_filesz = phdr32.p_filesz;
+        phdr->p_memsz  = phdr32.p_memsz;
+        phdr->p_align  = phdr32.p_align;
+    }
+    return TRUE;
+}
+
+static int dump_Elf_load(Elf64_Phdr *prog, int num_load)
+{
+    struct PTLoadSegment *pls;
+
+    if (prog->p_type != PT_LOAD) {
+        ERRMSG("%s isn't the dump memory.\n", in_core->corefile_name);
+        return FALSE;
+    }
+
+    pls = &in_core->pt_load_segments[num_load];
+    pls->virt_start  = prog->p_vaddr;
+    pls->virt_end    = pls->virt_start + prog->p_filesz;
+    pls->file_offset = prog->p_offset;
+
+    DEBUG_MSG("LOAD (%d)\n", num_load);
+    DEBUG_MSG("  virt_start : %llx\n", pls->virt_start);
+    DEBUG_MSG("  virt_end   : %llx\n", pls->virt_end);
+
+    return TRUE;
+}
+
+#ifndef BUILD_ID_SUPPORT
+static char * get_core_note_pgmname(Elf *elfd, GElf_Phdr *phdr)
+{
+    Elf_Data *notes_data = NULL;
+    size_t offset = 0;
+    size_t name_offset = 0;
+    size_t desc_offset = 0;
+    size_t pgm_name_offset = 0;
+    GElf_Nhdr nhdr;
+
+    notes_data = elf_getdata_rawchunk(elfd, phdr->p_offset, phdr->p_filesz,
+                    ELF_T_NHDR);
+    if (!notes_data) {
+        ERRMSG("Can't get raw chunk from notes section.\n");
+        return NULL;
+    }
+
+    while ((offset = gelf_getnote(notes_data, offset, &nhdr,
+                    &name_offset, &desc_offset)) > 0) {
+        if (nhdr.n_namesz != sizeof "CORE" ||
+            memcmp(notes_data->d_buf + name_offset, "CORE",
+                sizeof "CORE")) {
+            continue;
+        }
+
+        if (nhdr.n_type != NT_PRPSINFO)
+            continue;
+
+        pgm_name_offset = desc_offset + nhdr.n_descsz - 80 - 16;
+        return strndup(notes_data->d_buf + pgm_name_offset, 16);
+    }
+    return NULL;
+}
+
+static char * get_debug_file(const char *path)
+{
+    char *dbg_link, *ptr;
+
+    dbg_link = malloc(strlen(debuginfo_directory) + strlen(path) +
+                      strlen(in_core->pgm_name) + 1 +
+                      sizeof ".debug" + 1);
+    if (!dbg_link) {
+        ERRMSG("Can't allocate memory for debuginfo file name.\n");
+        return NULL;
+    }
+
+    ptr = dbg_link;
+    ptr += sprintf(ptr, "%s%s/%s.debug", debuginfo_directory, path,
+                                         in_core->pgm_name);
+
+    DEBUG_MSG("Looking for debuginfo file at: %s\n", dbg_link);
+
+    ptr = realpath(dbg_link, NULL);
+    free(dbg_link);
+
+    return ptr;
+}
+
+static char * get_debugfile_by_core_name(void)
+{
+    char *dbg_file;
+    int i = 0;
+
+    if (!in_core->pgm_name) {
+        return NULL;
+    }
+
+    /* find DEBUG DIR/<default-path>/pgm_name>.debug file */
+    for (i = 0; debuginfo_default_paths[i] != NULL; i++) {
+        dbg_file = get_debug_file(debuginfo_default_paths[i]);
+
+        if (dbg_file) {
+            return dbg_file;
+        }
+    }
+
+    return NULL;
+}
+#else
+
+static GElf_Addr *
+get_auxv_phdr(Elf *elfd, GElf_Phdr *phdr, GElf_Addr *auxv_phdr)
+{
+    Elf_Data *notes_data, *auxv_data = NULL;
+    unsigned long auxv_data_sz = 0;
+    size_t offset = 0;
+    size_t name_offset = 0;
+    size_t desc_offset = 0;
+    size_t num_auxv = 0;
+    GElf_Nhdr nhdr;
+    int i;
+
+    notes_data = elf_getdata_rawchunk(elfd, phdr->p_offset, phdr->p_filesz,
+                    ELF_T_NHDR);
+    if (!notes_data) {
+        ERRMSG("Can't get raw chunk from notes section.\n");
+        return NULL;
+    }
+
+    while ((offset = gelf_getnote(notes_data, offset, &nhdr,
+                    &name_offset, &desc_offset)) > 0) {
+        if (nhdr.n_namesz != sizeof "CORE" ||
+            memcmp(notes_data->d_buf + name_offset, "CORE",
+                sizeof "CORE")) {
+            continue;
+        }
+
+        if (nhdr.n_type != NT_AUXV)
+            continue;
+
+        auxv_data_sz = nhdr.n_descsz;
+        auxv_data = elf_getdata_rawchunk(elfd,
+                    phdr->p_offset + desc_offset,
+                    nhdr.n_descsz, ELF_T_AUXV);
+        if (!auxv_data) {
+            ERRMSG("Can't get AUXV\n");
+            return NULL;
+        }
+        DEBUG_MSG("Found AUXV at %p of size %lu\n", auxv_data,
+                                auxv_data_sz);
+        break;
+    }
+
+    if (!auxv_data || !auxv_data_sz) {
+        return NULL;
+    }
+
+    num_auxv = auxv_data_sz / gelf_fsize(elfd, ELF_T_AUXV, 1, EV_CURRENT);
+
+    for (i = 0; i < num_auxv; i++) {
+        GElf_auxv_t *auxv, auxv_mem;
+
+        if ((auxv = gelf_getauxv(auxv_data, i, &auxv_mem)) == NULL) {
+            return NULL;
+        }
+
+        if (auxv->a_type == AT_PHDR) {
+            *auxv_phdr = auxv->a_un.a_val;
+            DEBUG_MSG("AUXV Phdr = %llx\n", *auxv_phdr);
+            return auxv_phdr;
+        }
+    }
+    return NULL;
+}
+
+static struct PTLoadSegment * find_memseg(GElf_Addr auxv_addr, size_t size)
+{
+    struct PTLoadSegment *pls = NULL;
+    int i;
+
+    for (i = 0; i < in_core->num_load_memory; i++) {
+        pls = &in_core->pt_load_segments[i];
+
+        if (pls->virt_start <= auxv_addr &&
+            pls->virt_end > (auxv_addr + size)) {
+            DEBUG_MSG("auxv phdr lies in load segment(O=0x%llx, "
+                "[0x%llx - 0x%llx])\n",
+                pls->file_offset, pls->virt_start,
+                pls->virt_end);
+            return pls;
+        }
+    }
+    return NULL;
+}
+
+static Elf * get_app_elfd(Elf *elfd, GElf_Addr auxv_phdr)
+{
+    struct PTLoadSegment *pls;
+    unsigned long long filesz;
+    Elf_Data *data;
+    unsigned char *e_indent;
+    void *app_ehdr_mem;
+
+    if ((pls = find_memseg(auxv_phdr, ELF_T_EHDR)) == NULL) {
+        ERRMSG("Can't locate load segment for AUXV\n");
+        return NULL;
+    }
+
+    filesz = pls->virt_end - pls->virt_start;
+
+    data = elf_getdata_rawchunk(elfd, pls->file_offset, filesz,
+                                ELF_T_EHDR);
+    if (!data) {
+        ERRMSG("Can't read the load segment.\n");
+        return NULL;
+    }
+
+    e_indent = (unsigned char *)data->d_buf;
+    if (memcmp(e_indent, ELFMAG, SELFMAG) ||
+        (e_indent[EI_CLASS] <= ELFCLASSNONE) ||
+        (e_indent[EI_CLASS] >= ELFCLASSNUM) ||
+        (e_indent[EI_DATA] <= ELFDATANONE) ||
+        (e_indent[EI_DATA] >= ELFDATANUM) ||
+        (e_indent[EI_VERSION] <= EV_NONE) ||
+        (e_indent[EI_VERSION] >= EV_NUM)) {
+        ERRMSG("Invalid ELF header in load segment.\n");
+        return NULL;
+    }
+
+    app_ehdr_mem = calloc(1, filesz);
+    if (!app_ehdr_mem) {
+        ERRMSG("Can't allocate memory for application ELF header.\n");
+        return NULL;
+    }
+
+    memcpy(app_ehdr_mem, data->d_buf, filesz);
+
+    if (gelf_getclass(elfd) == ELFCLASS32) {
+        Elf32_Ehdr *ehdr = app_ehdr_mem;
+        ehdr->e_shoff = 0;
+        ehdr->e_shnum = 0;
+    } else {
+        Elf64_Ehdr *ehdr = app_ehdr_mem;
+        ehdr->e_shoff = 0;
+        ehdr->e_shnum = 0;
+    }
+
+    return elf_memory(app_ehdr_mem, filesz);
+
+}
+
+static unsigned char * note_getbuildid(Elf_Data *data, size_t *len)
+{
+    GElf_Nhdr *nhdr;
+    size_t offset = 0, name_off, desc_off;
+    unsigned char *buildid = NULL;
+    int found = 0;
+    unsigned char *id;
+
+    if (data->d_type != ELF_T_NHDR) {
+        return NULL;
+    }
+
+    while (offset < data->d_size) {
+        nhdr = data->d_buf + offset;
+        name_off = offset + sizeof(*nhdr);
+        desc_off = name_off + NOTE_ALIGN(nhdr->n_namesz);
+
+        if ((nhdr->n_namesz == sizeof "GNU")
+            && (nhdr->n_type == NT_GNU_BUILD_ID)
+            && (!memcmp(data->d_buf + name_off, "GNU", sizeof "GNU"))) {
+            DEBUG_MSG("Found build id at %#x %#x %#x\n",
+                    offset, name_off, desc_off);
+            found = 1;
+            *len = nhdr->n_descsz;
+            id = data->d_buf + desc_off;
+            break;
+        }
+        offset = desc_off + NOTE_ALIGN(nhdr->n_descsz);
+    }
+
+    if (found) {
+        buildid = malloc(*len);
+        if (!buildid) {
+            ERRMSG("Can't allocate memory for build-id\n");
+            return NULL;
+        }
+        memcpy(buildid, id, *len);
+        return buildid;
+    }
+    return NULL;
+}
+
+static unsigned char * get_buildid(Elf *elfd, size_t *len)
+{
+    GElf_Ehdr ehdr;
+    Elf_Data *data;
+    unsigned char *buildid = NULL;
+    int i;
+
+    if (gelf_getehdr(elfd, &ehdr) == NULL) {
+        ERRMSG("Can't get ELF header\n");
+        return NULL;
+    }
+
+    for (i = 0; i < ehdr.e_phnum; i++) {
+        GElf_Phdr nphdr;
+
+        if (gelf_getphdr(elfd, i, &nphdr) == NULL) {
+            return NULL;
+        }
+
+        if (nphdr.p_type != PT_NOTE) {
+            continue;
+        }
+
+        data = elf_getdata_rawchunk(elfd, nphdr.p_offset,
+                        nphdr.p_filesz, ELF_T_NHDR);
+        if (!data) {
+            ERRMSG("Can't read NOTE segment.\n");
+            return NULL;
+        }
+
+        buildid = note_getbuildid(data, len);
+        if (buildid) {
+            return buildid;
+        }
+    }
+
+    return NULL;
+}
+
+static unsigned char * get_debug_buildid(size_t *len)
+{
+    Elf *elfd;
+
+    if (lseek(dwarf_info.fd_debuginfo, 0, SEEK_SET) == failed) {
+        ERRMSG("Can't seek the kernel file(%s). %s\n",
+            dwarf_info.name_debuginfo, strerror(errno));
+        return FALSE;
+    }
+    if (!(elfd = elf_begin(dwarf_info.fd_debuginfo, ELF_C_READ_MMAP, NULL))) {
+        ERRMSG("Can't get first elf header of %s.\n",
+            dwarf_info.name_debuginfo);
+        return FALSE;
+    }
+
+    dwarf_info.build_id = get_buildid(elfd, &dwarf_info.build_id_size);
+    elf_end(elfd);
+
+    if (!dwarf_info.build_id) {
+        dwarf_info.cmd = DWARF_INFO_GET_BUILD_ID;
+
+        if (!get_debug_info()) {
+            return NULL;
+        }
+    }
+
+    *len = dwarf_info.build_id_size;
+    return dwarf_info.build_id;
+}
+
+static char * get_debugfile_by_build_id(void)
+{
+    char *dbg_link, *ptr;
+    unsigned char *id;
+    int i;
+
+    if (!in_core->build_id) {
+        return NULL;
+    }
+
+    id = in_core->build_id;
+
+    /* DEBUG DIR/.build-id/ab/cdef... */
+    dbg_link = malloc(strlen(debuginfo_directory) + sizeof "/.build-id/" +
+                      (2 * in_core->build_id_size) + 1 +
+                      sizeof ".debug" + 1);
+    if (!dbg_link) {
+        ERRMSG("Can't allocate memory for debuginfo file name.\n");
+        return NULL;
+    }
+
+    ptr = dbg_link;
+    ptr += sprintf(ptr, "%s/.build-id/%02x/", debuginfo_directory, id[0]);
+
+    for (i = 1; i < in_core->build_id_size; i++) {
+        ptr += sprintf(ptr, "%02x", id[i]);
+    }
+
+    sprintf(ptr, ".debug");
+
+    DEBUG_MSG("Debuginfo link file: %s\n", dbg_link);
+
+    ptr = realpath(dbg_link, NULL);
+    free(dbg_link);
+
+    return ptr;
+}
+#endif
+
+#ifdef BUILD_ID_SUPPORT
+static unsigned char * get_core_buildid(size_t *len)
+#else
+static char * get_core_pgmname(void)
+#endif
+{
+    Elf *elfd = NULL;
+    GElf_Ehdr ehdr_mem, *ehdr = NULL;
+    int i;
+#ifdef BUILD_ID_SUPPORT
+    Elf *app_elfd = NULL;
+    GElf_Addr auxv_phdr = 0;
+    unsigned char *build_id = NULL;
+#else
+    char *pgm_name = NULL;
+#endif
+
+    if (lseek(in_core->fd_corefile, 0, SEEK_SET) == failed) {
+        ERRMSG("Can't seek the dump memory(%s). %s\n",
+            in_core->corefile_name, strerror(errno));
+        return NULL;
+    }
+
+    elfd = elf_begin(in_core->fd_corefile, ELF_C_READ_MMAP, NULL);
+    if (elfd == NULL) {
+        ERRMSG("Can't get first elf header of %s.\n",
+            in_core->corefile_name);
+        return NULL;
+    }
+
+    if ((ehdr = gelf_getehdr(elfd, &ehdr_mem)) == NULL) {
+        ERRMSG("Can't get the ELF header\n");
+        goto out;
+    }
+
+    for (i = 0; i < ehdr->e_phnum; i++) {
+        GElf_Phdr *phdr, phdr_mem;
+
+        if ((phdr = gelf_getphdr(elfd, i, &phdr_mem)) == NULL) {
+            goto out;
+        }
+
+        if (phdr->p_type != PT_NOTE) {
+            continue;
+        }
+
+#ifdef BUILD_ID_SUPPORT
+        if (get_auxv_phdr(elfd, phdr, &auxv_phdr)) {
+            break;
+        }
+#else
+        if ((pgm_name = get_core_note_pgmname(elfd, phdr))) {
+            break;
+        }
+#endif
+    }
+
+#ifdef BUILD_ID_SUPPORT
+    if (!auxv_phdr) {
+        DEBUG_MSG("Can't locate AUXV Phdr.\n");
+        goto out;
+    }
+
+    /*
+     * Get application ELF header from load segment.
+     */
+    if ((app_elfd = get_app_elfd(elfd, auxv_phdr)) == NULL) {
+        DEBUG_MSG("Couldn't find the Application ELF header.\n");
+        goto out;
+    }
+
+    build_id = get_buildid(app_elfd, len);
+#endif
+
+out:
+    if (elfd) {
+        elf_end(elfd);
+    }
+
+#ifdef BUILD_ID_SUPPORT
+    return build_id;
+#else
+    return pgm_name;
+#endif
+}
+
+
+static int get_elf_info(void)
+{
+    int i, j, phnum, num_load, elf_format, elf_type;
+    Elf64_Phdr phdr;
+
+    if (elf_version(EV_CURRENT) == EV_NONE) {
+        /*
+         * library out of date
+         */
+        ERRMSG("Elf library out of date!\n");
+        return -EINVAL;
+    }
+
+    /*
+     * Check ELF64 or ELF32.
+     */
+    elf_format = check_elf_format(in_core->fd_corefile,
+                in_core->corefile_name,
+                &phnum, &num_load, &elf_type);
+
+    if (elf_format == ELF64) {
+        in_core->flag_elf64 = TRUE;
+    } else if (elf_format == ELF32) {
+        in_core->flag_elf64 = FALSE;
+    } else {
+        return -EINVAL;
+    }
+
+    if (elf_type == ET_CORE) {
+        in_core->elf_type = ET_CORE;
+    } else {
+        return -EINVAL;
+    }
+
+    in_core->num_load_memory = num_load;
+
+    if (!in_core->num_load_memory) {
+        ERRMSG("Can't get the number of PT_LOAD.\n");
+        return -EINVAL;
+    }
+    if ((in_core->pt_load_segments = (struct PTLoadSegment *)
+        calloc(1, sizeof(struct PTLoadSegment) *
+        in_core->num_load_memory)) == NULL) {
+        ERRMSG("Can't allocate memory for the PT_LOAD. %s\n",
+            strerror(errno));
+        return -ENOMEM;
+    }
+
+    for (i = 0, j = 0; i < phnum; i++) {
+        if (!get_elf_phdr_memory(i, &phdr)) {
+            return FALSE;
+        }
+
+        if (phdr.p_type != PT_LOAD) {
+            continue;
+        }
+
+        if (!in_core->page_size) {
+            in_core->page_size = (long) phdr.p_align;
+        }
+
+        if (j == 0) {
+            in_core->offset_load = phdr.p_offset;
+            if (!in_core->offset_load) {
+                ERRMSG("Can't get the offset of page data.\n");
+                return -EINVAL;
+            }
+        }
+        if (j >= in_core->num_load_memory) {
+            return -EINVAL;
+        }
+
+        if (!dump_Elf_load(&phdr, j)) {
+            return -EINVAL;
+        }
+        j++;
+    }
+
+#ifdef BUILD_ID_SUPPORT
+    in_core->build_id = get_core_buildid(&in_core->build_id_size);
+    if (in_core->build_id == NULL) {
+        ERRMSG("Failed to extract build-id info from core file: %s\n",
+            in_core->corefile_name);
+        return -EINVAL;
+    }
+
+    DEBUG_PRINT_BUILDID("core file build-id:", in_core->build_id,
+                    in_core->build_id_size);
+#else
+    in_core->pgm_name = get_core_pgmname();
+    if (in_core->pgm_name == NULL) {
+        ERRMSG("Failed to extract program name from core file: %s\n",
+            in_core->corefile_name);
+        return -EINVAL;
+    }
+    DEBUG_MSG("Program name: %s\n", in_core->pgm_name);
+#endif
+
+    return 0;
+}
+
+/* Get symbol address for a given symbol name from debuginfo file. */
+static unsigned long long get_symbol_addr(const char *symname)
+{
+    int i;
+    unsigned long long symbol = NOT_FOUND_SYMBOL;
+    Elf *elfd = NULL;
+    GElf_Shdr shdr;
+    GElf_Sym sym;
+    Elf_Data *data = NULL;
+    Elf_Scn *scn = NULL;
+    char *sym_name = NULL;
+
+    if (lseek(dwarf_info.fd_debuginfo, 0, SEEK_SET) == failed) {
+        ERRMSG("Can't seek the debuginfo file(%s). %s\n",
+            dwarf_info.name_debuginfo, strerror(errno));
+        return NOT_FOUND_SYMBOL;
+    }
+    if (!(elfd = elf_begin(dwarf_info.fd_debuginfo, ELF_C_READ, NULL))) {
+        ERRMSG("Can't get first elf header of %s.\n",
+            dwarf_info.name_debuginfo);
+        return NOT_FOUND_SYMBOL;
+    }
+    while ((scn = elf_nextscn(elfd, scn)) != NULL) {
+        if (gelf_getshdr(scn, &shdr) == NULL) {
+            ERRMSG("Can't get section header.\n");
+            goto out;
+        }
+        if (shdr.sh_type == SHT_SYMTAB) {
+            break;
+        }
+    }
+    if (!scn) {
+        ERRMSG("Can't find symbol table from debuginfo file %s.\n",
+                dwarf_info.name_debuginfo);
+        goto out;
+    }
+
+    data = elf_getdata(scn, data);
+
+    if ((!data) || (data->d_size == 0)) {
+        ERRMSG("No data in symbol table.\n");
+        goto out;
+    }
+
+    for (i = 0; i < (shdr.sh_size/shdr.sh_entsize); i++) {
+        if (gelf_getsym(data, i, &sym) == NULL) {
+            ERRMSG("Can't get symbol at index %d.\n", i);
+            goto out;
+        }
+        sym_name = elf_strptr(elfd, shdr.sh_link, sym.st_name);
+
+        if (sym_name == NULL) {
+            continue;
+        }
+
+        if (!strcmp(sym_name, symname)) {
+            symbol = sym.st_value;
+            break;
+        }
+    }
+out:
+    if (elfd != NULL)
+        elf_end(elfd);
+
+    return symbol;
+}
+
+static int get_data_member_location(Dwarf_Die *die, long *offset)
+{
+    size_t expcnt;
+    Dwarf_Attribute attr;
+    Dwarf_Op *expr;
+
+    if (dwarf_attr(die, DW_AT_data_member_location, &attr) == NULL) {
+        return FALSE;
+    }
+
+    if (dwarf_getlocation(&attr, &expr, &expcnt) < 0) {
+        return FALSE;
+    }
+
+    (*offset) = expr[0].number;
+
+    return TRUE;
+}
+
+static void search_member(Dwarf *dwarfd, Dwarf_Die *die)
+{
+    int tag;
+    long offset;
+    const char *name;
+    Dwarf_Die child, *walker;
+
+    if (dwarf_child(die, &child) != 0) {
+        return;
+    }
+
+    walker = &child;
+
+    do {
+        tag  = dwarf_tag(walker);
+        name = dwarf_diename(walker);
+
+        if (tag != DW_TAG_member) {
+            continue;
+        }
+
+        if ((!name) || strcmp(name, dwarf_info.member_name)) {
+            continue;
+        }
+        /*
+         * Get the member offset.
+         */
+        if (!get_data_member_location(walker, &offset)) {
+            continue;
+        }
+        dwarf_info.member_offset = offset;
+        return;
+    } while (!dwarf_siblingof(walker, walker));
+
+    /*
+     * Return even if not found.
+     */
+    return;
+}
+
+static void search_structure(Dwarf *dwarfd, Dwarf_Die *die, int *found)
+{
+    int tag;
+    const char *name;
+
+    /*
+     * If we get to here then we don't have any more
+     * children, check to see if this is a relevant tag
+     */
+    do {
+        tag  = dwarf_tag(die);
+        name = dwarf_diename(die);
+        if ((tag != DW_TAG_structure_type) || (!name)
+            || strcmp(name, dwarf_info.struct_name)) {
+            continue;
+        }
+        /*
+         * Skip if DW_AT_byte_size is not included.
+         */
+        dwarf_info.struct_size = dwarf_bytesize(die);
+
+        if (dwarf_info.struct_size > 0) {
+            break;
+        }
+
+    } while (!dwarf_siblingof(die, die));
+
+    if (dwarf_info.struct_size <= 0) {
+        /*
+         * Not found the demanded structure.
+         */
+        return;
+    }
+
+    /*
+     * Found the demanded structure.
+     */
+    *found = TRUE;
+    switch (dwarf_info.cmd) {
+    case DWARF_INFO_GET_STRUCT_SIZE:
+        break;
+    case DWARF_INFO_GET_MEMBER_OFFSET:
+        search_member(dwarfd, die);
+        break;
+    }
+}
+
+static void search_die_tree(Dwarf *dwarfd, Dwarf_Die *die, int *found)
+{
+    Dwarf_Die child;
+
+    /*
+     * start by looking at the children
+     */
+    if (dwarf_child(die, &child) == 0) {
+        search_die_tree(dwarfd, &child, found);
+    }
+
+    if (*found) {
+        return;
+    }
+
+    search_structure(dwarfd, die, found);
+}
+
+static int get_debug_info(void)
+{
+    int found = FALSE;
+    char *name = NULL;
+    size_t shstrndx, header_size;
+    uint8_t address_size, offset_size;
+    Dwarf *dwarfd = NULL;
+    Elf *elfd = NULL;
+    Dwarf_Off off = 0, next_off = 0, abbrev_offset = 0;
+    Elf_Scn *scn = NULL;
+    GElf_Shdr scnhdr_mem, *scnhdr = NULL;
+    Dwarf_Die cu_die;
+    const char *section_name = ".debug_info";
+
+    int ret = FALSE;
+
+    if (lseek(dwarf_info.fd_debuginfo, 0, SEEK_SET) == failed) {
+        ERRMSG("Can't seek the kernel file(%s). %s\n",
+            dwarf_info.name_debuginfo, strerror(errno));
+        return FALSE;
+    }
+    if (!(elfd = elf_begin(dwarf_info.fd_debuginfo, ELF_C_READ_MMAP, NULL))) {
+        ERRMSG("Can't get first elf header of %s.\n",
+            dwarf_info.name_debuginfo);
+        return FALSE;
+    }
+    if (!(dwarfd = dwarf_begin_elf(elfd, DWARF_C_READ, NULL))) {
+        ERRMSG("Can't create a handle for a new debug session.\n");
+        goto out;
+    }
+    if (elf_getshdrstrndx(elfd, &shstrndx) < 0) {
+        ERRMSG("Can't get the section index of the string table.\n");
+        goto out;
+    }
+
+#ifdef BUILD_ID_SUPPORT
+    if (dwarf_info.cmd == DWARF_INFO_GET_BUILD_ID) {
+        section_name = ".note.gnu.build-id";
+    }
+#endif
+    /*
+     * Search for ".debug_info" section.
+     */
+    while ((scn = elf_nextscn(elfd, scn)) != NULL) {
+        scnhdr = gelf_getshdr(scn, &scnhdr_mem);
+        name = elf_strptr(elfd, shstrndx, scnhdr->sh_name);
+        if (!strcmp(name, section_name)) {
+            break;
+        }
+    }
+    if (strcmp(name, section_name)) {
+        ERRMSG("Can't get %s section.\n", section_name);
+        goto out;
+    }
+
+#ifdef BUILD_ID_SUPPORT
+    if (dwarf_info.cmd == DWARF_INFO_GET_BUILD_ID) {
+        Elf_Data *data = elf_getdata(scn, NULL);
+        if (!data) {
+            ERRMSG("Can't read the section data for build-id.\n");
+            goto out;
+        }
+        dwarf_info.build_id =
+            note_getbuildid(data, &dwarf_info.build_id_size);
+        if (dwarf_info.build_id) {
+            ret = TRUE;
+        }
+        goto out;
+    }
+#endif
+
+    /*
+     * Search by each CompileUnit.
+     */
+    while (dwarf_nextcu(dwarfd, off, &next_off, &header_size,
+        &abbrev_offset, &address_size, &offset_size) == 0) {
+        off += header_size;
+        if (dwarf_offdie(dwarfd, off, &cu_die) == NULL) {
+            ERRMSG("Can't get CU die.\n");
+            goto out;
+        }
+        search_die_tree(dwarfd, &cu_die, &found);
+        if (found) {
+            break;
+        }
+        off = next_off;
+    }
+    ret = TRUE;
+out:
+    if (dwarfd != NULL) {
+        dwarf_end(dwarfd);
+    }
+    if (elfd != NULL) {
+        elf_end(elfd);
+    }
+
+    return ret;
+}
+
+/*
+ * Get the size of structure.
+ */
+static long get_structure_size(const char *structname)
+{
+    dwarf_info.cmd = DWARF_INFO_GET_STRUCT_SIZE;
+
+    dwarf_info.struct_name = structname;
+    dwarf_info.struct_size = NOT_FOUND_STRUCTURE;
+
+    if (!get_debug_info()) {
+        return FAILED_DWARFINFO;
+    }
+
+    return dwarf_info.struct_size;
+}
+
+/*
+ * Get the offset of member.
+ */
+static long
+get_member_offset(const char *structname, const char *membername, int cmd)
+{
+    dwarf_info.cmd = cmd;
+    dwarf_info.struct_name = structname;
+    dwarf_info.struct_size = NOT_FOUND_STRUCTURE;
+    dwarf_info.member_name = membername;
+    dwarf_info.member_offset = NOT_FOUND_STRUCTURE;
+
+    if (!get_debug_info()) {
+        return FAILED_DWARFINFO;
+    }
+
+    return dwarf_info.member_offset;
+}
+
+static int is_in_same_page(unsigned long vaddr1, unsigned long vaddr2)
+{
+    if (round(vaddr1, in_core->page_size)
+                    == round(vaddr2, in_core->page_size)) {
+        return TRUE;
+    }
+
+    return FALSE;
+}
+
+/*
+ * Convert virtual Address to File Offset.
+ *  If this function returns 0x0, File Offset isn't found.
+ *  The File Offset 0x0 is in the ELF header.
+ *  It is not in the memory image.
+ */
+static off_t vaddr_to_offset(unsigned long long vaddr)
+{
+    int i;
+    off_t offset;
+    struct PTLoadSegment *pls;
+
+    for (i = offset = 0; i < in_core->num_load_memory; i++) {
+        pls = &in_core->pt_load_segments[i];
+        if ((vaddr >= pls->virt_start)
+            && (vaddr < pls->virt_end)) {
+            offset = (off_t)(vaddr - pls->virt_start) + pls->file_offset;
+                break;
+        }
+    }
+    return offset;
+}
+
+static int readmem(unsigned long long addr, void *bufptr, size_t size)
+{
+    size_t read_size, next_size;
+    off_t offset = 0;
+    unsigned long long next_addr;
+    char *next_ptr;
+
+    read_size = size;
+
+    /*
+     * Read each page, because pages are not necessarily continuous.
+     * Ex) pages in vmalloc area
+     */
+    if (!is_in_same_page(addr, addr + size - 1)) {
+        read_size = in_core->page_size - (addr % in_core->page_size);
+        next_addr = roundup(addr + 1, in_core->page_size);
+        next_size = size - read_size;
+        next_ptr  = (char *)bufptr + read_size;
+
+        if (!readmem(next_addr, next_ptr, next_size)) {
+            goto error;
+        }
+    }
+
+    if (!(offset = vaddr_to_offset(addr))) {
+        ERRMSG("Can't convert a virtual address(%llx) to offset.\n",
+            addr);
+        goto error;
+    }
+
+    if (lseek(in_core->fd_corefile, offset, SEEK_SET) == failed) {
+        ERRMSG("Can't seek the dump memory(%s). %s\n",
+            in_core->corefile_name, strerror(errno));
+        goto error;
+    }
+
+    if (read(in_core->fd_corefile, bufptr, read_size) != read_size) {
+        ERRMSG("Can't read the dump memory(%s). %s\n",
+            in_core->corefile_name, strerror(errno));
+        goto error;
+    }
+
+    return size;
+error:
+    ERRMSG("addr:%llx, size:%zd\n", addr, size);
+    return FALSE;
+}
+
+static int collect_debuginfo(char *dbg_filename, int dbg_fd)
+{
+#ifdef BUILD_ID_SUPPORT
+    size_t len = 0;
+#endif
+
+    dwarf_info.fd_debuginfo = dbg_fd;
+    dwarf_info.name_debuginfo = dbg_filename;
+
+#ifdef BUILD_ID_SUPPORT
+    /*
+     * First verify whether debuginfo build-id matches with that of
+     * coredump file.
+     */
+    in_core->dbg_build_id = get_debug_buildid(&len);
+    if (!in_core->dbg_build_id) {
+        ERRMSG("Can't read build-id from debuginfo file: %s\n",
+                    dwarf_info.name_debuginfo);
+        return -EINVAL;
+    }
+    in_core->dbg_build_id_size = len;
+    DEBUG_PRINT_BUILDID("debuginfo file build-id:",
+                in_core->dbg_build_id,
+                in_core->dbg_build_id_size);
+
+    if ((in_core->build_id_size != in_core->dbg_build_id_size)
+        || (memcmp(in_core->build_id, in_core->dbg_build_id,
+                    in_core->build_id_size))) {
+        ERRMSG("build-id mismatch found."
+                " incorrect debuginfo file: %s\n",
+                dwarf_info.name_debuginfo);
+        return -EINVAL;
+    }
+#endif
+
+    /*
+     * Start loading symbol from debuginfo file.
+     */
+    DEBUG_MSG("Reading symbols from %s.\n", dwarf_info.name_debuginfo);
+    in_core->ram_blocks.sym_name = (char *)RAM_BLOCKS_SYMNAME;
+
+    /* Initialize ram_blocks symbol address */
+    SYMBOL(ram_blocks) = get_symbol_addr(RAM_BLOCKS_SYMNAME);
+    if (SYMBOL(ram_blocks) == NOT_FOUND_SYMBOL) {
+        ERRMSG("Symbol not found: %s\n", RAM_BLOCKS_SYMNAME);
+        return -EINVAL;
+    }
+    DEBUG_MSG("ram_blocks:addr = 0x%llx\n", SYMBOL(ram_blocks));
+
+    /* Initialize ram_blocks symbol size */
+    SIZE(ram_blocks) = get_structure_size(RAM_BLOCKS_STRUCTNAME);
+    if (SIZE(ram_blocks) == FAILED_DWARFINFO) {
+        return -EINVAL;
+    }
+
+    DEBUG_MSG("ram_blocks:size = 0x%lx\n", SIZE(ram_blocks));
+
+    /* Initialize offset value for ram_blocks.host member */
+    OFFSET(host) = get_member_offset(RAM_BLOCKS_STRUCTNAME, "host",
+                    DWARF_INFO_GET_MEMBER_OFFSET);
+    if (OFFSET(host) == FAILED_DWARFINFO) {
+        return -EINVAL;
+    }
+
+    DEBUG_MSG("ram_blocks:m.host = 0x%lx\n", OFFSET(host));
+
+    /* Initialize offset value for ram_blocks.length member */
+    OFFSET(length) = get_member_offset(RAM_BLOCKS_STRUCTNAME, "length",
+                    DWARF_INFO_GET_MEMBER_OFFSET);
+    if (OFFSET(length) == FAILED_DWARFINFO) {
+        return -EINVAL;
+    }
+
+    DEBUG_MSG("ram_blocks:m.length = 0x%lx\n", OFFSET(length));
+
+    /* Initialize offset value for ram_blocks.next member */
+    OFFSET(next) = get_member_offset(RAM_BLOCKS_STRUCTNAME, "next",
+                    DWARF_INFO_GET_MEMBER_OFFSET);
+    if (OFFSET(next) == FAILED_DWARFINFO) {
+        return -EINVAL;
+    }
+
+    DEBUG_MSG("ram_blocks:m.next = 0x%lx\n", OFFSET(next));
+    return 0;
+}
+
+static int get_qemu_debuginfo(void)
+{
+    /*
+     * If user has not specified debuginfo file then search it using
+     * build-id.
+     */
+    if (!in_core->name_qemu_debug) {
+#ifdef BUILD_ID_SUPPORT
+        in_core->name_qemu_debug = get_debugfile_by_build_id();
+#else
+        in_core->name_qemu_debug = get_debugfile_by_core_name();
+#endif
+        if (!in_core->name_qemu_debug) {
+            ERRMSG("Missing separate debuginfo file. "
+                "Use '-s' option to specify debuginfo file manually.\n");
+            return -EINVAL;
+        }
+
+        DEBUG_MSG("debuginfo file found: %s\n", in_core->name_qemu_debug);
+        if (open_debugfile())
+            return -EINVAL;
+    }
+
+    return collect_debuginfo(in_core->name_qemu_debug, in_core->fd_qemu_debug);
+}
+
+static int update_guest_os_memmap(unsigned char *ram_block_mem)
+{
+    struct GuestOSMemMap *node;
+
+    node = malloc(sizeof(*node));
+    if (!node) {
+        DEBUG_MSG("Can't allocate memory for Guest OS memory map.\n");
+        return -ENOMEM;
+    }
+
+    node->mem_start = ULONG(ram_block_mem + OFFSET(host));
+    node->mem_end = node->mem_start + ULONG(ram_block_mem + OFFSET(length));
+    node->next = NULL;
+
+    DEBUG_MSG("Guest OS memory: start(0x%llx) end(0x%llx)\n", node->mem_start,
+                            node->mem_end);
+
+    if (guest_os_memmap == NULL) {
+        guest_os_memmap = node;
+    } else {
+        node->next = guest_os_memmap;
+        guest_os_memmap = node;
+    }
+    return 0;
+}
+
+static int build_guest_os_memmap(void)
+{
+    unsigned long ram_blocks;
+    unsigned char *ram_block_mem;
+    int err = 0;
+
+    DEBUG_MSG("Building Guest OS memory mappings.\n");
+    if (!readmem(in_core->ram_blocks.sym_addr, &ram_blocks,
+                sizeof(ram_blocks))) {
+        ERRMSG("Can't get the value of ram_blocks.\n");
+        return -EINVAL;
+    }
+
+    ram_block_mem = malloc(in_core->ram_blocks.sym_size);
+    if (!ram_block_mem) {
+        ERRMSG("Can't allocate memory for a struct RAMBlock. %s\n",
+                strerror(errno));
+        return -ENOMEM;
+    }
+
+    while (ram_blocks) {
+        DEBUG_MSG("ram_blocks => 0x%08lx\n", ram_blocks);
+
+        if (!readmem(ram_blocks, ram_block_mem,
+                    in_core->ram_blocks.sym_size)) {
+            ERRMSG("Can't get struct RAMBlock.\n");
+            err = -EINVAL;
+            goto out;
+        }
+
+        err = update_guest_os_memmap(ram_block_mem);
+        if (err) {
+            goto out;
+        }
+
+        ram_blocks = ULONG(ram_block_mem + OFFSET(next));
+    }
+out:
+    free(ram_block_mem);
+    return err;
+}
+
+static int get_phnum_memory(void)
+{
+    int phnum;
+    Elf64_Ehdr ehdr64;
+    Elf32_Ehdr ehdr32;
+
+    if (in_core->flag_elf64) { /* ELF64 */
+        if (!get_elf64_ehdr(&ehdr64)) {
+            ERRMSG("Can't get ehdr64.\n");
+            return FALSE;
+        }
+        phnum = ehdr64.e_phnum;
+    } else {                /* ELF32 */
+        if (!get_elf32_ehdr(&ehdr32)) {
+            ERRMSG("Can't get ehdr32.\n");
+            return FALSE;
+        }
+        phnum = ehdr32.e_phnum;
+    }
+
+    return phnum;
+}
+
+static int
+write_and_check_space(int fd, void *buf, size_t buf_size, char *file_name)
+{
+    int status, written_size = 0;
+
+    while (written_size < buf_size) {
+        status = write(fd, buf + written_size,
+                   buf_size - written_size);
+        if (0 < status) {
+            written_size += status;
+            continue;
+        }
+        if (errno == ENOSPC) {
+            out_core->flag_nospace = TRUE;
+        }
+        ERRMSG("\nCan't write the dump file(%s). %s\n",
+                file_name, strerror(errno));
+        return FALSE;
+    }
+    return TRUE;
+}
+
+static int write_buffer(int fd, off_t offset, void *buf, size_t buf_size,
+                                                    char *file_name)
+{
+    DEBUG_MSG("offset: 0x%08lx, off end: 0x%08lx, size = %zd\n",
+                    (unsigned long int)offset,
+                    (unsigned long int)(offset + buf_size),
+                    buf_size);
+
+    if (lseek(fd, offset, SEEK_SET) == failed) {
+        ERRMSG("Can't seek the dump file(%s). %s\n",
+            file_name, strerror(errno));
+        return FALSE;
+    }
+    if (!write_and_check_space(fd, buf, buf_size, file_name)) {
+        return FALSE;
+    }
+
+    return TRUE;
+}
+
+static int write_cache(struct CacheData *cd, void *buf, size_t size)
+{
+    if (!write_buffer(cd->fd, cd->offset, buf, size,
+                cd->file_name)) {
+        return FALSE;
+    }
+
+    cd->offset += size;
+    return TRUE;
+}
+
+static int write_elf_phdr(struct CacheData *cd_hdr, Elf64_Phdr *load)
+{
+    Elf32_Phdr load32;
+
+    if (in_core->flag_elf64) { /* ELF64 */
+        if (!write_cache(cd_hdr, load, sizeof(Elf64_Phdr))) {
+            return FALSE;
+        }
+    } else {
+        memset(&load32, 0, sizeof(Elf32_Phdr));
+        load32.p_type   = load->p_type;
+        load32.p_flags  = load->p_flags;
+        load32.p_offset = load->p_offset;
+        load32.p_vaddr  = load->p_vaddr;
+        load32.p_paddr  = load->p_paddr;
+        load32.p_filesz = load->p_filesz;
+        load32.p_memsz  = load->p_memsz;
+        load32.p_align  = load->p_align;
+
+        if (!write_cache(cd_hdr, &load32, sizeof(Elf32_Phdr))) {
+            return FALSE;
+        }
+    }
+    return TRUE;
+}
+
+static void guest_mem_adjust(Elf64_Phdr *load)
+{
+    struct GuestOSMemMap *p;
+    Elf64_Addr vm_start, vm_end;
+
+    if (!load->p_filesz) {
+        return;
+    }
+
+    vm_start = load->p_vaddr;
+    vm_end = load->p_vaddr + load->p_filesz;
+
+    p = guest_os_memmap;
+    while (p) {
+        if ((p->mem_start >= vm_start) && (p->mem_start < vm_end)) {
+            load->p_filesz = p->mem_start - vm_start;
+            return;
+        } else if ((p->mem_end > vm_start) && (p->mem_end <= vm_end)) {
+            load->p_filesz = 0;
+            return;
+        } else if ((p->mem_start < vm_start) && (p->mem_end > vm_end)) {
+            load->p_filesz = 0;
+            return;
+        }
+        p = p->next;
+    }
+    return;
+}
+
+static int write_elf_header(struct CacheData *cd_header)
+{
+    int i, phnum;
+    off_t offset_note_memory, offset_note_dumpfile;
+    size_t size_note;
+    Elf64_Ehdr ehdr64;
+    Elf32_Ehdr ehdr32;
+    Elf64_Phdr note;
+
+    char *buf = NULL;
+
+    int ret = FALSE;
+
+    DEBUG_MSG("Writing ELF Header\n");
+
+    if (in_core->flag_elf64) { /* ELF64 */
+        if (!get_elf64_ehdr(&ehdr64)) {
+            ERRMSG("Can't get ehdr64.\n");
+            goto out;
+        }
+    } else {                /* ELF32 */
+        if (!get_elf32_ehdr(&ehdr32)) {
+            ERRMSG("Can't get ehdr32.\n");
+            goto out;
+        }
+    }
+
+    /*
+     * Write an ELF header.
+     */
+    if (in_core->flag_elf64) { /* ELF64 */
+        if (!write_buffer(out_core->fd_corefile, 0, &ehdr64, sizeof(ehdr64),
+            out_core->corefile_name)) {
+            goto out;
+        }
+
+    } else {                /* ELF32 */
+        if (!write_buffer(out_core->fd_corefile, 0, &ehdr32, sizeof(ehdr32),
+            out_core->corefile_name)) {
+            goto out;
+        }
+    }
+
+    /*
+     * Write a PT_NOTE header.
+     */
+    DEBUG_MSG("Writing PT_NOTE Header\n");
+
+    if (!(phnum = get_phnum_memory())) {
+        goto out;
+    }
+
+    for (i = 0; i < phnum; i++) {
+        if (!get_elf_phdr_memory(i, &note)) {
+            return FALSE;
+        }
+        if (note.p_type == PT_NOTE) {
+            break;
+        }
+    }
+    if (note.p_type != PT_NOTE) {
+        ERRMSG("Can't get a PT_NOTE header.\n");
+        goto out;
+    }
+
+    if (in_core->flag_elf64) { /* ELF64 */
+        cd_header->offset    = sizeof(ehdr64);
+        offset_note_dumpfile = sizeof(ehdr64)
+            + sizeof(Elf64_Phdr) * ehdr64.e_phnum;
+    } else {
+        cd_header->offset    = sizeof(ehdr32);
+        offset_note_dumpfile = sizeof(ehdr32)
+            + sizeof(Elf32_Phdr) * ehdr32.e_phnum;
+    }
+    offset_note_memory = note.p_offset;
+    note.p_offset      = offset_note_dumpfile;
+    size_note          = note.p_filesz;
+    DEBUG_MSG("offset_note_memory(0x%08lx), offset_note_dumpfile(0x%08lx),"
+            "size_note = %zd\n", (unsigned long int) offset_note_memory,
+            (unsigned long int) offset_note_dumpfile,
+            size_note);
+
+    if (!write_elf_phdr(cd_header, &note)) {
+        goto out;
+    }
+
+    /*
+     * Write a PT_NOTE segment.
+     * PT_LOAD header will be written later.
+     */
+    if ((buf = malloc(size_note)) == NULL) {
+        ERRMSG("Can't allocate memory for PT_NOTE segment. %s\n",
+            strerror(errno));
+        goto out;
+    }
+    if (lseek(in_core->fd_corefile, offset_note_memory, SEEK_SET) == failed) {
+        ERRMSG("Can't seek the dump memory(%s). %s\n",
+            in_core->corefile_name, strerror(errno));
+        goto out;
+    }
+    if (read(in_core->fd_corefile, buf, size_note) != size_note) {
+        ERRMSG("Can't read the dump memory(%s). %s\n",
+            in_core->corefile_name, strerror(errno));
+        goto out;
+    }
+    if (!write_buffer(out_core->fd_corefile, offset_note_dumpfile, buf,
+        size_note, out_core->corefile_name)) {
+        goto out;
+    }
+
+    /*
+     * Set an offset of PT_LOAD segment.
+     */
+    out_core->offset_load = offset_note_dumpfile + size_note;
+
+    ret = TRUE;
+out:
+    if (buf != NULL) {
+        free(buf);
+    }
+
+    return ret;
+}
+
+static int
+write_elf_load_segment(struct CacheData *cd_page, unsigned long long paddr,
+               off_t off_memory, long long size)
+{
+    long long bufsz_write;
+    long page_size = in_core->page_size;
+    char buf[in_core->page_size];
+
+    if (lseek(in_core->fd_corefile, off_memory, SEEK_SET) < 0) {
+        ERRMSG("Can't seek the dump memory(%s). %s\n",
+            in_core->corefile_name, strerror(errno));
+        return FALSE;
+    }
+
+    while (size > 0) {
+        if (size >= page_size) {
+            bufsz_write = page_size;
+        } else {
+            bufsz_write = size;
+        }
+
+        if (read(in_core->fd_corefile, buf, bufsz_write) != bufsz_write) {
+            ERRMSG("Can't read the dump memory(%s). %s\n",
+                in_core->corefile_name, strerror(errno));
+            return FALSE;
+        }
+        if (!write_cache(cd_page, buf, bufsz_write)) {
+            return FALSE;
+        }
+        size -= page_size;
+    }
+
+    return TRUE;
+}
+
+static int
+write_elf_pages(struct CacheData *cd_header, struct CacheData *cd_page)
+{
+    int i, phnum;
+    unsigned long long paddr;
+    off_t off_memory;
+    Elf64_Phdr load;
+
+    cd_page->offset = out_core->offset_load;
+
+    if (!(phnum = get_phnum_memory())) {
+        return FALSE;
+    }
+
+    for (i = 0; i < phnum; i++) {
+        if (!get_elf_phdr_memory(i, &load)) {
+            return FALSE;
+        }
+
+        if (load.p_type != PT_LOAD) {
+            continue;
+        }
+
+        off_memory = load.p_offset;
+        cd_page->offset = roundup(cd_page->offset, in_core->page_size);
+        load.p_offset = cd_page->offset;
+
+        paddr     = load.p_paddr;
+
+        /*
+         * adjust PT_LOAD to filter guest os memory from
+         * cordump.
+         */
+        guest_mem_adjust(&load);
+
+        /*
+         * Write a PT_LOAD header.
+         */
+        if (!write_elf_phdr(cd_header, &load)) {
+            return FALSE;
+        }
+
+        /*
+         * Write a PT_LOAD segment.
+         */
+        if (!write_elf_load_segment(cd_page, paddr, off_memory,
+                                    load.p_filesz)) {
+            return FALSE;
+        }
+    }
+    return TRUE;
+}
+
+static int prepare_cache_data(struct CacheData *cd)
+{
+    cd->fd        = out_core->fd_corefile;
+    cd->file_name    = out_core->corefile_name;
+
+    return 0;
+}
+
+static int open_outcorefile(void)
+{
+    int out_flag = O_CREAT | O_WRONLY | O_LARGEFILE;
+
+    if (force_overwrite) {
+        out_flag |= O_TRUNC;
+    } else {
+        out_flag |= O_EXCL;
+    }
+
+    /* Open target core file for writing. */
+    out_core->fd_corefile = open(out_core->corefile_name, out_flag,
+                S_IRUSR|S_IWUSR);
+    if (out_core->fd_corefile < 0) {
+        if (errno == EEXIST) {
+            ERRMSG("core file already exists. "
+                    "Use '-f' option to overwrite. %s\n",
+                    out_core->corefile_name);
+        } else {
+            ERRMSG("Can't open target core file for writing. %s\n",
+                    strerror(errno));
+        }
+        return -errno;
+    }
+    return 0;
+}
+
+static int writeout_coredump(void)
+{
+    int ret = 0;
+    struct CacheData cd_header, cd_page;
+
+    if ((ret = open_outcorefile())) {
+        return ret;
+    }
+
+    out_core->flag_nospace = FALSE;
+
+    prepare_cache_data(&cd_header);
+    prepare_cache_data(&cd_page);
+
+    if (!write_elf_header(&cd_header)) {
+        goto out;
+    }
+
+    write_elf_pages(&cd_header, &cd_page);
+
+out:
+    if (out_core->flag_nospace) {
+        return -ENOSPC;
+    } else {
+        return ret;
+    }
+}
+
+int main(int argc, char *argv[])
+{
+    int opt, err = 0;
+
+    in_core = (struct CoreDumpInfo *) calloc(1, sizeof(struct CoreDumpInfo));
+    if (in_core == NULL) {
+        ERRMSG("Can't allocate memory for core info cache. %s\n",
+            strerror(errno));
+        return -ENOMEM;
+    }
+
+    out_core = (struct CoreDumpInfo *) calloc(1, sizeof(struct CoreDumpInfo));
+    if (out_core == NULL) {
+        ERRMSG("Can't allocate memory for core info cache. %s\n",
+            strerror(errno));
+        return -ENOMEM;
+    }
+
+    while ((opt = getopt_long(argc, argv, "s:hdf", longopts, NULL)) != -1) {
+        switch (opt) {
+        case 's':
+            in_core->name_qemu_debug = optarg;
+            break;
+        case 'h':
+            print_usage();
+            goto out;
+        case 'd':
+            debug_flag = 1;
+            break;
+        case 'f':
+            force_overwrite = 1;
+            break;
+        default:
+            ERRMSG("Command line parameter is invalid.\n");
+            ERRMSG("Try 'qemu-core-filter --help' for more information.\n");
+            goto out;
+        }
+    }
+
+    if (argc != optind + 2) {
+        print_usage();
+        err = -EINVAL;
+        goto out;
+    }
+
+    in_core->corefile_name = argv[optind];
+    DEBUG_MSG("In core file name: %s\n", in_core->corefile_name);
+
+    out_core->corefile_name = argv[optind + 1];
+    DEBUG_MSG("Out core file name: %s\n", out_core->corefile_name);
+
+    err = qemu_validate_options();
+    if (err) {
+        goto out;
+    }
+
+    err = get_elf_info();
+    if (err) {
+        goto out;
+    }
+
+    err = get_qemu_debuginfo();
+    if (err) {
+        goto out;
+    }
+
+    err = build_guest_os_memmap();
+    if (err) {
+        goto out;
+    }
+
+    err = writeout_coredump();
+
+out:
+    if (in_core) {
+        free_core_info(in_core);
+        free(in_core);
+    }
+    if (out_core) {
+        free_core_info(out_core);
+        free(out_core);
+    }
+    free_guest_os_memmap();
+
+    return err;
+}
diff --git a/qemu-core-filter.h b/qemu-core-filter.h
new file mode 100644
index 0000000..5dbdcd1
--- /dev/null
+++ b/qemu-core-filter.h
@@ -0,0 +1,216 @@
+/*
+ * qemu-core-filter.h
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * Copyright (C) 2010 IBM Corporation
+ * Author: Mahesh Salgaonkar <mahesh@linux.vnet.ibm.com>
+ *
+ * Adopted from: http://sourceforge.net/projects/makedumpfile
+ *    Some of the code source are adopted from makdumpfile project
+ *    which is GPL License sources.
+ */
+#include "config-host.h"
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/types.h>
+#include <unistd.h>
+#include <sys/stat.h>
+#include <sys/param.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <elf.h>
+#include <gelf.h>
+#include <elfutils/libdw.h>
+#include <libelf.h>
+#include <dwarf.h>
+#include <getopt.h>
+
+#ifdef HAVE_ELFUTILS_VERSION_H
+#include <elfutils/version.h>
+
+#if !_ELFUTILS_PREREQ(0, 142)
+#define elf_getshdrstrndx elf_getshstrndx
+#endif
+
+#if _ELFUTILS_PREREQ(0, 138)
+/* build-id support is introduced only from elfutils >= 0.138 */
+#define BUILD_ID_SUPPORT    1
+#endif
+
+#else /* !HAVE_ELFUTILS_VERSION_H */
+
+#define elf_getshdrstrndx elf_getshstrndx
+
+#endif
+
+#ifndef VERSION
+#define VERSION  "0.3.1"
+#endif
+
+#define round(x, y)     (((x) / (y)) * (y))
+
+#define TRUE            1
+#define FALSE           0
+
+#define ELF32           1
+#define ELF64           2
+
+/*
+ * for symbol
+ */
+#define NOT_FOUND_SYMBOL        (0)
+#define RAM_BLOCKS_SYMNAME      "ram_blocks"
+#define RAM_BLOCKS_STRUCTNAME   "RAMBlock"
+
+#define SYMBOL(X)       (in_core->X.sym_addr)
+#define SIZE(x)         (in_core->x.sym_size)
+#define OFFSET(x)       (in_core->ram_blocks.offset.x)
+#define ULONG(ADDR)     (*((unsigned long *)(ADDR)))
+
+#define BITPERBYTE      8
+#define BYTE(x)         (x / BITPERBYTE)
+#define BIT(x)          (x % BITPERBYTE)
+#define NOTE_ALIGN(s)   (((s) + 3) & -4U)
+
+/*
+ * for dwarf
+ */
+
+#define NOT_FOUND_STRUCTURE (-1)
+#define FAILED_DWARFINFO    (-2)
+
+enum {
+    DWARF_INFO_GET_STRUCT_SIZE,
+    DWARF_INFO_GET_MEMBER_OFFSET,
+#ifdef BUILD_ID_SUPPORT
+    DWARF_INFO_GET_BUILD_ID
+#endif
+};
+
+struct DwarfInfo {
+    unsigned int    cmd;              /* IN  */
+    int     fd_debuginfo;             /* IN  */
+    const char    *name_debuginfo;    /* IN  */
+    const char    *struct_name;       /* IN  */
+    const char    *member_name;       /* IN  */
+    long    struct_size;              /* OUT */
+    long    member_offset;            /* OUT */
+#ifdef BUILD_ID_SUPPORT
+    unsigned char    *build_id;       /* OUT */
+    size_t  build_id_size;            /* OUT */
+#endif
+};
+
+struct PTLoadSegment {
+    off_t                 file_offset;
+    unsigned long long    virt_start;
+    unsigned long long    virt_end;
+};
+
+struct SymbolInfo {
+    char        *sym_name;
+    unsigned long long    sym_addr;
+    long        sym_size;
+    struct offset {
+        long    host;
+        long    length;
+        long    next;
+    } offset;
+};
+
+struct GuestOSMemMap {
+    unsigned long long    mem_start;
+    unsigned long long    mem_end;
+    struct GuestOSMemMap  *next;
+};
+
+struct CoreDumpInfo {
+
+    /*
+     * coredump image info
+     */
+    char       *corefile_name;    /* Core dump file name.    */
+    int        fd_corefile;
+
+    /*
+     * General info
+     */
+    int        flag_elf64;        /* flag for ELF64 format   */
+    int        elf_type;
+    int        flag_nospace;      /* No space left on device */
+    int        offset_load;
+
+    /*
+     * ELF info
+     */
+
+    int         num_load_memory;
+    long        page_size;
+#ifdef BUILD_ID_SUPPORT
+    unsigned char    *build_id;   /* Unique build id         */
+    size_t      build_id_size;    /* Size of build id        */
+#else
+    char        *pgm_name;        /* program name.           */
+#endif
+
+    /*
+     * Debug info
+     */
+
+    char       *name_qemu_debug;  /* QEMU Debuginfo file name */
+    int        fd_qemu_debug;
+#ifdef BUILD_ID_SUPPORT
+    unsigned char    *dbg_build_id;     /* debuginfo build id */
+    size_t     dbg_build_id_size;
+#endif
+
+    struct PTLoadSegment    *pt_load_segments;
+    struct SymbolInfo    ram_blocks;
+};
+
+struct CacheData {
+    int   fd;
+    char  *file_name;
+    off_t offset;
+};
+
+#define ERRMSG(x...) \
+do { \
+    fprintf(stderr, x); \
+} while (0)
+
+#define DEBUG_MSG(x...) \
+do { \
+    if (debug_flag) { \
+        fprintf(stderr, __FUNCTION__); \
+        fprintf(stderr, ": "); \
+        fprintf(stderr, x); \
+    } \
+} while (0)
+
+#ifdef BUILD_ID_SUPPORT
+#define DEBUG_PRINT_BUILDID(msg, id, sz) \
+do { \
+    int i; \
+    if (debug_flag) { \
+        fprintf(stderr, __FUNCTION__); \
+        fprintf(stderr, ": "); \
+        fprintf(stderr, msg); \
+        fprintf(stderr, " "); \
+        for (i = 0; i < (sz); i++) \
+            fprintf(stderr, "%02x", id[i]); \
+        fprintf(stderr, "\n"); \
+    } \
+} while (0)
+#endif /* BUILD_ID_SUPPORT */
+
