[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[xen staging] tools/libs: move xc_core* from libxenctrl to libxenguest



commit 455790573d3bbad6d5a1bb7e9d28b6dd71075693
Author:     Juergen Gross <jgross@xxxxxxxx>
AuthorDate: Fri Jun 4 08:02:13 2021 +0200
Commit:     Julien Grall <jgrall@xxxxxxxxxx>
CommitDate: Fri Jun 4 18:56:46 2021 +0100

    tools/libs: move xc_core* from libxenctrl to libxenguest
    
    The functionality in xc_core* should be part of libxenguest instead
    of libxenctrl. Users are already either in libxenguest, or in xl.
    There is one single exception: xc_core_arch_auto_translated_physmap()
    is being used by xc_domain_memory_mapping(), which is used by qemu.
    So leave the xc_core_arch_auto_translated_physmap() functionality in
    libxenctrl.
    
    This will make it easier to merge common functionality of xc_core*
    and xg_sr_save*.
    
    Signed-off-by: Juergen Gross <jgross@xxxxxxxx>
    Acked-by: Wei Liu <wl@xxxxxxx>
---
 tools/libs/ctrl/Makefile           |    3 -
 tools/libs/ctrl/xc_core.c          | 1027 ------------------------------------
 tools/libs/ctrl/xc_core.h          |  176 ------
 tools/libs/ctrl/xc_core_arm.c      |  113 ----
 tools/libs/ctrl/xc_core_arm.h      |   59 ---
 tools/libs/ctrl/xc_core_x86.c      |  391 --------------
 tools/libs/ctrl/xc_core_x86.h      |   60 ---
 tools/libs/ctrl/xc_domain.c        |    2 -
 tools/libs/ctrl/xc_private.h       |   12 +
 tools/libs/guest/Makefile          |    3 +
 tools/libs/guest/xg_core.c         | 1027 ++++++++++++++++++++++++++++++++++++
 tools/libs/guest/xg_core.h         |  175 ++++++
 tools/libs/guest/xg_core_arm.c     |  107 ++++
 tools/libs/guest/xg_core_arm.h     |   59 +++
 tools/libs/guest/xg_core_x86.c     |  385 ++++++++++++++
 tools/libs/guest/xg_core_x86.h     |   60 +++
 tools/libs/guest/xg_dom_boot.c     |    2 +-
 tools/libs/guest/xg_domain.c       |    2 +-
 tools/libs/guest/xg_offline_page.c |    2 +-
 tools/libs/guest/xg_resume.c       |    2 +-
 20 files changed, 1832 insertions(+), 1835 deletions(-)

diff --git a/tools/libs/ctrl/Makefile b/tools/libs/ctrl/Makefile
index fbeb3a3537..519246b0d6 100644
--- a/tools/libs/ctrl/Makefile
+++ b/tools/libs/ctrl/Makefile
@@ -2,9 +2,6 @@ XEN_ROOT = $(CURDIR)/../../..
 include $(XEN_ROOT)/tools/Rules.mk
 
 SRCS-y       += xc_altp2m.c
-SRCS-y       += xc_core.c
-SRCS-$(CONFIG_X86) += xc_core_x86.c
-SRCS-$(CONFIG_ARM) += xc_core_arm.c
 SRCS-y       += xc_cpupool.c
 SRCS-y       += xc_domain.c
 SRCS-y       += xc_evtchn.c
diff --git a/tools/libs/ctrl/xc_core.c b/tools/libs/ctrl/xc_core.c
deleted file mode 100644
index 9576bec5a3..0000000000
--- a/tools/libs/ctrl/xc_core.c
+++ /dev/null
@@ -1,1027 +0,0 @@
-/*
- * Elf format, (pfn, gmfn) table, IA64 support.
- * Copyright (c) 2007 Isaku Yamahata <yamahata at valinux co jp>
- *                    VA Linux Systems Japan K.K.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation;
- * version 2.1 of the License.
- *
- * This library 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
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; If not, see <http://www.gnu.org/licenses/>.
- */
-
-/*
- * xen dump-core file format follows ELF format specification.
- * Analisys tools shouldn't depends on the order of sections.
- * They should follow elf header and check section names.
- *
- *  +--------------------------------------------------------+
- *  |ELF header                                              |
- *  +--------------------------------------------------------+
- *  |section headers                                         |
- *  |    null section header                                 |
- *  |    .shstrtab                                           |
- *  |    .note.Xen                                           |
- *  |    .xen_prstatus                                       |
- *  |    .xen_shared_info if present                         |
- *  |    .xen_pages                                          |
- *  |    .xen_p2m or .xen_pfn                                |
- *  +--------------------------------------------------------+
- *  |.note.Xen:note section                                  |
- *  |    "Xen" is used as note name,                         |
- *  |    types are defined in xen/include/public/elfnote.h   |
- *  |    and descriptors are defined in xc_core.h.           |
- *  |    dumpcore none                                       |
- *  |    dumpcore header                                     |
- *  |    dumpcore xen version                                |
- *  |    dumpcore format version                             |
- *  +--------------------------------------------------------+
- *  |.xen_prstatus                                           |
- *  |       vcpu_guest_context_t[nr_vcpus]                   |
- *  +--------------------------------------------------------+
- *  |.xen_shared_info if possible                            |
- *  +--------------------------------------------------------+
- *  |.xen_pages                                              |
- *  |    page * nr_pages                                     |
- *  +--------------------------------------------------------+
- *  |.xen_p2m or .xen_pfn                                    |
- *  |    .xen_p2m: struct xen_dumpcore_p2m[nr_pages]         |
- *  |    .xen_pfn: uint64_t[nr_pages]                        |
- *  +--------------------------------------------------------+
- *  |.shstrtab: section header string table                  |
- *  +--------------------------------------------------------+
- *
- */
-
-#include "xc_private.h"
-#include "xc_core.h"
-#include <stdlib.h>
-#include <unistd.h>
-
-#include <xen/libelf/libelf.h>
-
-/* number of pages to write at a time */
-#define DUMP_INCREMENT (4 * 1024)
-
-/* string table */
-struct xc_core_strtab {
-    char       *strings;
-    uint16_t    length;
-    uint16_t    max;
-};
-
-static struct xc_core_strtab*
-xc_core_strtab_init(xc_interface *xch)
-{
-    struct xc_core_strtab *strtab;
-    char *strings;
-    strtab = malloc(sizeof(*strtab));
-    if ( strtab == NULL )
-        return NULL;
-
-    strings = malloc(PAGE_SIZE);
-    if ( strings == NULL )
-    {
-        PERROR("Could not allocate string table init");
-        free(strtab);
-        return NULL;
-    }
-    strtab->strings = strings;
-    strtab->max = PAGE_SIZE;
-
-    /* index 0 represents none */
-    strtab->strings[0] = '\0';
-    strtab->length = 1;
-
-    return strtab;
-}
-
-static void
-xc_core_strtab_free(struct xc_core_strtab *strtab)
-{
-    free(strtab->strings);
-    free(strtab);
-}
-
-static uint16_t
-xc_core_strtab_get(xc_interface *xch, struct xc_core_strtab *strtab, const 
char *name)
-{
-    uint16_t ret = 0;
-    uint16_t len = strlen(name) + 1;
-
-    if ( strtab->length > UINT16_MAX - len )
-    {
-        PERROR("too long string table");
-        errno = E2BIG;
-        return ret;
-    }
-    
-    if ( strtab->length + len > strtab->max )
-    {
-        char *tmp;
-        if ( strtab->max > UINT16_MAX / 2 )
-        {
-            PERROR("too long string table");
-            errno = ENOMEM;
-            return ret;
-        }
-
-        tmp = realloc(strtab->strings, strtab->max * 2);
-        if ( tmp == NULL )
-        {
-            PERROR("Could not allocate string table");
-            return ret;
-        }
-
-        strtab->strings = tmp;
-        strtab->max *= 2;
-    }
-
-    ret = strtab->length;
-    strcpy(strtab->strings + strtab->length, name);
-    strtab->length += len;
-    return ret;
-}
-
-
-/* section headers */
-struct xc_core_section_headers {
-    uint16_t    num;
-    uint16_t    num_max;
-
-    Elf64_Shdr  *shdrs;
-};
-#define SHDR_INIT       ((uint16_t)16)
-#define SHDR_INC        ((uint16_t)4)
-
-static struct xc_core_section_headers*
-xc_core_shdr_init(xc_interface *xch)
-{
-    struct xc_core_section_headers *sheaders;
-    sheaders = malloc(sizeof(*sheaders));
-    if ( sheaders == NULL )
-        return NULL;
-
-    sheaders->num = 0;
-    sheaders->num_max = SHDR_INIT;
-    sheaders->shdrs = malloc(sizeof(sheaders->shdrs[0]) * sheaders->num_max);
-    if ( sheaders->shdrs == NULL )
-    {
-        free(sheaders);
-        return NULL;
-    }
-    return sheaders;
-}
-
-static void
-xc_core_shdr_free(struct xc_core_section_headers *sheaders)
-{
-    free(sheaders->shdrs);
-    free(sheaders);
-}
-
-Elf64_Shdr*
-xc_core_shdr_get(xc_interface *xch,
-                 struct xc_core_section_headers *sheaders)
-{
-    Elf64_Shdr *shdr;
-
-    if ( sheaders->num == sheaders->num_max )
-    {
-        Elf64_Shdr *shdrs;
-        if ( sheaders->num_max > UINT16_MAX - SHDR_INC )
-        {
-            errno = E2BIG;
-            return NULL;
-        }
-        sheaders->num_max += SHDR_INC;
-        shdrs = realloc(sheaders->shdrs,
-                        sizeof(sheaders->shdrs[0]) * sheaders->num_max);
-        if ( shdrs == NULL )
-            return NULL;
-        sheaders->shdrs = shdrs;
-    }
-
-    shdr = &sheaders->shdrs[sheaders->num];
-    sheaders->num++;
-    memset(shdr, 0, sizeof(*shdr));
-    return shdr;
-}
-
-int
-xc_core_shdr_set(xc_interface *xch,
-                 Elf64_Shdr *shdr,
-                 struct xc_core_strtab *strtab,
-                 const char *name, uint32_t type,
-                 uint64_t offset, uint64_t size,
-                 uint64_t addralign, uint64_t entsize)
-{
-    uint64_t name_idx = xc_core_strtab_get(xch, strtab, name);
-    if ( name_idx == 0 )
-        return -1;
-
-    shdr->sh_name = name_idx;
-    shdr->sh_type = type;
-    shdr->sh_offset = offset;
-    shdr->sh_size = size;
-    shdr->sh_addralign = addralign;
-    shdr->sh_entsize = entsize;
-    return 0;
-}
-
-static void
-xc_core_ehdr_init(Elf64_Ehdr *ehdr)
-{
-    memset(ehdr, 0, sizeof(*ehdr));
-    ehdr->e_ident[EI_MAG0] = ELFMAG0;
-    ehdr->e_ident[EI_MAG1] = ELFMAG1;
-    ehdr->e_ident[EI_MAG2] = ELFMAG2;
-    ehdr->e_ident[EI_MAG3] = ELFMAG3;
-    ehdr->e_ident[EI_CLASS] = ELFCLASS64;
-    ehdr->e_ident[EI_DATA] = ELF_ARCH_DATA;
-    ehdr->e_ident[EI_VERSION] = EV_CURRENT;
-    ehdr->e_ident[EI_OSABI] = ELFOSABI_SYSV;
-    ehdr->e_ident[EI_ABIVERSION] = EV_CURRENT;
-
-    ehdr->e_type = ET_CORE;
-    /* e_machine will be filled in later */
-    ehdr->e_version = EV_CURRENT;
-    ehdr->e_entry = 0;
-    ehdr->e_phoff = 0;
-    ehdr->e_shoff = sizeof(*ehdr);
-    ehdr->e_flags = ELF_CORE_EFLAGS;
-    ehdr->e_ehsize = sizeof(*ehdr);
-    ehdr->e_phentsize = sizeof(Elf64_Phdr);
-    ehdr->e_phnum = 0;
-    ehdr->e_shentsize = sizeof(Elf64_Shdr);
-    /* ehdr->e_shnum and ehdr->e_shstrndx aren't known here yet.
-     * fill it later */
-}
-
-static int
-elfnote_fill_xen_version(xc_interface *xch,
-                         struct xen_dumpcore_elfnote_xen_version_desc
-                         *xen_version)
-{
-    int rc;
-    memset(xen_version, 0, sizeof(*xen_version));
-
-    rc = xc_version(xch, XENVER_version, NULL);
-    if ( rc < 0 )
-        return rc;
-    xen_version->major_version = rc >> 16;
-    xen_version->minor_version = rc & ((1 << 16) - 1);
-
-    rc = xc_version(xch, XENVER_extraversion,
-                    &xen_version->extra_version);
-    if ( rc < 0 )
-        return rc;
-
-    rc = xc_version(xch, XENVER_compile_info,
-                    &xen_version->compile_info);
-    if ( rc < 0 )
-        return rc;
-
-    rc = xc_version(xch,
-                    XENVER_capabilities, &xen_version->capabilities);
-    if ( rc < 0 )
-        return rc;
-
-    rc = xc_version(xch, XENVER_changeset, &xen_version->changeset);
-    if ( rc < 0 )
-        return rc;
-
-    rc = xc_version(xch, XENVER_platform_parameters,
-                    &xen_version->platform_parameters);
-    if ( rc < 0 )
-        return rc;
-
-    rc = xc_version(xch, XENVER_pagesize, NULL);
-    if ( rc < 0 )
-        return rc;
-    xen_version->pagesize = rc;
-
-    return 0;
-}
-
-static void
-elfnote_fill_format_version(struct xen_dumpcore_elfnote_format_version_desc
-                            *format_version)
-{
-    format_version->version = XEN_DUMPCORE_FORMAT_VERSION_CURRENT;
-}
-
-static void
-elfnote_init(struct elfnote *elfnote)
-{
-    /* elf note section */
-    memset(elfnote, 0, sizeof(*elfnote));
-    elfnote->namesz = strlen(XEN_DUMPCORE_ELFNOTE_NAME) + 1;
-    strncpy(elfnote->name, XEN_DUMPCORE_ELFNOTE_NAME, sizeof(elfnote->name));
-}
-
-static int
-elfnote_dump_none(xc_interface *xch, void *args, dumpcore_rtn_t dump_rtn)
-{
-    int sts;
-    struct elfnote elfnote;
-    struct xen_dumpcore_elfnote_none_desc none;
-
-    elfnote_init(&elfnote);
-    /* Avoid compile warning about constant-zero-sized memset(). */
-    /*memset(&none, 0, sizeof(none));*/
-
-    elfnote.descsz = sizeof(none);
-    elfnote.type = XEN_ELFNOTE_DUMPCORE_NONE;
-    sts = dump_rtn(xch, args, (char*)&elfnote, sizeof(elfnote));
-    if ( sts != 0 )
-        return sts;
-    return dump_rtn(xch, args, (char*)&none, sizeof(none));
-}
-
-static int
-elfnote_dump_core_header(
-    xc_interface *xch,
-    void *args, dumpcore_rtn_t dump_rtn, const xc_dominfo_t *info,
-    int nr_vcpus, unsigned long nr_pages)
-{
-    int sts;
-    struct elfnote elfnote;
-    struct xen_dumpcore_elfnote_header_desc header;
-    
-    elfnote_init(&elfnote);
-    memset(&header, 0, sizeof(header));
-    
-    elfnote.descsz = sizeof(header);
-    elfnote.type = XEN_ELFNOTE_DUMPCORE_HEADER;
-    header.xch_magic = info->hvm ? XC_CORE_MAGIC_HVM : XC_CORE_MAGIC;
-    header.xch_nr_vcpus = nr_vcpus;
-    header.xch_nr_pages = nr_pages;
-    header.xch_page_size = PAGE_SIZE;
-    sts = dump_rtn(xch, args, (char*)&elfnote, sizeof(elfnote));
-    if ( sts != 0 )
-        return sts;
-    return dump_rtn(xch, args, (char*)&header, sizeof(header));
-}
-
-static int
-elfnote_dump_xen_version(xc_interface *xch, void *args,
-                         dumpcore_rtn_t dump_rtn, unsigned int guest_width)
-{
-    int sts;
-    struct elfnote elfnote;
-    struct xen_dumpcore_elfnote_xen_version_desc xen_version;
-
-    elfnote_init(&elfnote);
-    memset(&xen_version, 0, sizeof(xen_version));
-
-    elfnote.descsz = sizeof(xen_version);
-    elfnote.type = XEN_ELFNOTE_DUMPCORE_XEN_VERSION;
-    elfnote_fill_xen_version(xch, &xen_version);
-    if (guest_width < sizeof(unsigned long))
-    {
-        // 32 bit elf file format differs in pagesize's alignment
-        char *p = (char *)&xen_version.pagesize;
-        memmove(p - 4, p, sizeof(xen_version.pagesize));
-    }
-    sts = dump_rtn(xch, args, (char*)&elfnote, sizeof(elfnote));
-    if ( sts != 0 )
-        return sts;
-    return dump_rtn(xch, args, (char*)&xen_version, sizeof(xen_version));
-}
-
-static int
-elfnote_dump_format_version(xc_interface *xch,
-                            void *args, dumpcore_rtn_t dump_rtn)
-{
-    int sts;
-    struct elfnote elfnote;
-    struct xen_dumpcore_elfnote_format_version_desc format_version;
-
-    elfnote_init(&elfnote);
-    memset(&format_version, 0, sizeof(format_version));
-    
-    elfnote.descsz = sizeof(format_version);
-    elfnote.type = XEN_ELFNOTE_DUMPCORE_FORMAT_VERSION;
-    elfnote_fill_format_version(&format_version);
-    sts = dump_rtn(xch, args, (char*)&elfnote, sizeof(elfnote));
-    if ( sts != 0 )
-        return sts;
-    return dump_rtn(xch, args, (char*)&format_version, sizeof(format_version));
-}
-
-int
-xc_domain_dumpcore_via_callback(xc_interface *xch,
-                                uint32_t domid,
-                                void *args,
-                                dumpcore_rtn_t dump_rtn)
-{
-    xc_dominfo_t info;
-    shared_info_any_t *live_shinfo = NULL;
-    struct domain_info_context _dinfo = {};
-    struct domain_info_context *dinfo = &_dinfo;
-
-    int nr_vcpus = 0;
-    char *dump_mem, *dump_mem_start = NULL;
-    vcpu_guest_context_any_t *ctxt = NULL;
-    struct xc_core_arch_context arch_ctxt;
-    char dummy[PAGE_SIZE];
-    int dummy_len;
-    int sts = -1;
-
-    unsigned long i;
-    unsigned long j;
-    unsigned long nr_pages;
-    unsigned long max_mfn;
-
-    xc_core_memory_map_t *memory_map = NULL;
-    unsigned int nr_memory_map;
-    unsigned int map_idx;
-
-    int auto_translated_physmap;
-    xen_pfn_t *p2m = NULL;
-    struct xen_dumpcore_p2m *p2m_array = NULL;
-
-    uint64_t *pfn_array = NULL;
-
-    Elf64_Ehdr ehdr;
-    uint64_t filesz;
-    uint64_t offset;
-    uint64_t fixup;
-
-    struct xc_core_strtab *strtab = NULL;
-    uint16_t strtab_idx;
-    struct xc_core_section_headers *sheaders = NULL;
-    Elf64_Shdr *shdr;
- 
-    xc_core_arch_context_init(&arch_ctxt);
-    if ( (dump_mem_start = malloc(DUMP_INCREMENT*PAGE_SIZE)) == NULL )
-    {
-        PERROR("Could not allocate dump_mem");
-        goto out;
-    }
-
-    if ( xc_domain_getinfo(xch, domid, 1, &info) != 1 )
-    {
-        PERROR("Could not get info for domain");
-        goto out;
-    }
-    /* Map the shared info frame */
-    live_shinfo = xc_map_foreign_range(xch, domid, PAGE_SIZE,
-                                       PROT_READ, info.shared_info_frame);
-    if ( !live_shinfo && !info.hvm )
-    {
-        PERROR("Couldn't map live_shinfo");
-        goto out;
-    }
-    auto_translated_physmap = xc_core_arch_auto_translated_physmap(&info);
-
-    if ( !auto_translated_physmap )
-
-    {
-        if ( xc_domain_get_guest_width(xch, domid, &dinfo->guest_width) != 0 )
-        {
-            PERROR("Could not get address size for domain");
-            goto out;
-        }
-    }
-    else
-    {
-        /*
-         * Autotranslated guest never sets guest width in the first
-         * place. Force guest_width to be sizeof(unsigned long) so
-         * code below functions properly.
-         *
-         * Here is why this is correct.
-         *
-         * 1. Before f969bc9fc, xc_domain_get_guest_width for HVM (x86
-         * and ARM) always returned hypervisor's idea of
-         * sizeof(unsigned long).
-         *
-         * 2. There has never been a situation in which hypervisor's
-         * word width is smaller than toolstack domain's (i.e. no
-         * 32bit hypervisor + 64bit toolstack).
-         *
-         * Predicates in code test guest_width against toolstack
-         * domain's sizeof(unsigned long), so setting guest_width to
-         * toolstack domain's idea of sizeof(unsigned long) matches
-         * the original behaviour for HVM guests.
-         */
-        dinfo->guest_width = sizeof(unsigned long);
-    }
-
-    if ( domid != info.domid )
-    {
-        PERROR("Domain %d does not exist", domid);
-        goto out;
-    }
-
-    ctxt = calloc(sizeof(*ctxt), info.max_vcpu_id + 1);
-    if ( !ctxt )
-    {
-        PERROR("Could not allocate vcpu context array");
-        goto out;
-    }
-
-    for ( i = 0; i <= info.max_vcpu_id; i++ )
-    {
-        if ( xc_vcpu_getcontext(xch, domid, i, &ctxt[nr_vcpus]) == 0 )
-        {
-            if ( xc_core_arch_context_get(&arch_ctxt, &ctxt[nr_vcpus],
-                                          xch, domid) )
-                continue;
-            nr_vcpus++;
-        }
-    }
-    if ( nr_vcpus == 0 )
-    {
-        PERROR("No VCPU context could be grabbed");
-        goto out;
-    }
-
-    /* obtain memory map */
-    sts = xc_core_arch_memory_map_get(xch, &arch_ctxt, &info,
-                                      live_shinfo, &memory_map,
-                                      &nr_memory_map);
-    if ( sts != 0 )
-        goto out;
-
-    /*
-     * Note: this is the *current* number of pages and may change under
-     * a live dump-core.  We'll just take this value, and if more pages
-     * exist, we'll skip them.  If there's less, then we'll just not use
-     * all the array...
-     *
-     * We don't want to use the total potential size of the memory map
-     * since that is usually much higher than info.nr_pages.
-     */
-    nr_pages = info.nr_pages;
-
-    if ( !auto_translated_physmap )
-    {
-        /* obtain p2m table */
-        p2m_array = malloc(nr_pages * sizeof(p2m_array[0]));
-        if ( p2m_array == NULL )
-        {
-            PERROR("Could not allocate p2m array");
-            goto out;
-        }
-
-        sts = xc_core_arch_map_p2m(xch, dinfo, &info, live_shinfo, &p2m);
-        if ( sts != 0 )
-            goto out;
-
-        sts = xc_maximum_ram_page(xch, &max_mfn);
-        if ( sts != 0 )
-            goto out;
-    }
-    else
-    {
-        pfn_array = malloc(nr_pages * sizeof(pfn_array[0]));
-        if ( pfn_array == NULL )
-        {
-            PERROR("Could not allocate pfn array");
-            goto out;
-        }
-    }
-
-    /* ehdr.e_shnum and ehdr.e_shstrndx aren't known here yet. fill it later*/
-    xc_core_ehdr_init(&ehdr);
-
-    /* create section header */
-    strtab = xc_core_strtab_init(xch);
-    if ( strtab == NULL )
-    {
-        PERROR("Could not allocate string table");
-        goto out;
-    }
-    sheaders = xc_core_shdr_init(xch);
-    if ( sheaders == NULL )
-    {
-        PERROR("Could not allocate section headers");
-        goto out;
-    }
-    /* null section */
-    shdr = xc_core_shdr_get(xch,sheaders);
-    if ( shdr == NULL )
-    {
-        PERROR("Could not get section header for null section");
-        goto out;
-    }
-
-    /* .shstrtab */
-    shdr = xc_core_shdr_get(xch,sheaders);
-    if ( shdr == NULL )
-    {
-        PERROR("Could not get section header for shstrtab");
-        goto out;
-    }
-    strtab_idx = shdr - sheaders->shdrs;
-    /* strtab_shdr.sh_offset, strtab_shdr.sh_size aren't unknown.
-     * fill it later
-     */
-    sts = xc_core_shdr_set(xch, shdr, strtab, ELF_SHSTRTAB, SHT_STRTAB, 0, 0, 
0, 0);
-    if ( sts != 0 )
-        goto out;
-
-    /* elf note section */
-    /* here the number of section header is unknown. fix up offset later. */
-    offset = sizeof(ehdr);
-    filesz =
-        sizeof(struct xen_dumpcore_elfnote_none) +         /* none */
-        sizeof(struct xen_dumpcore_elfnote_header) +       /* core header */
-        sizeof(struct xen_dumpcore_elfnote_xen_version) +  /* xen version */
-        sizeof(struct xen_dumpcore_elfnote_format_version);/* format version */
-    shdr = xc_core_shdr_get(xch,sheaders);
-    if ( shdr == NULL )
-    {
-        PERROR("Could not get section header for note section");
-        goto out;
-    }
-    sts = xc_core_shdr_set(xch, shdr, strtab, XEN_DUMPCORE_SEC_NOTE, SHT_NOTE,
-                           offset, filesz, 0, 0);
-    if ( sts != 0 )
-        goto out;
-    offset += filesz;
-
-    /* prstatus */
-    shdr = xc_core_shdr_get(xch,sheaders);
-    if ( shdr == NULL )
-    {
-        PERROR("Could not get section header for .xen_prstatus");
-        goto out;
-    }
-    filesz = sizeof(*ctxt) * nr_vcpus;
-    sts = xc_core_shdr_set(xch, shdr, strtab, XEN_DUMPCORE_SEC_PRSTATUS,
-                           SHT_PROGBITS, offset, filesz,
-                           __alignof__(*ctxt), sizeof(*ctxt));
-    if ( sts != 0 )
-        goto out;
-    offset += filesz;
-
-    /* arch context */
-    sts = xc_core_arch_context_get_shdr(xch, &arch_ctxt, sheaders, strtab,
-                                        &filesz, offset);
-    if ( sts != 0 )
-        goto out;
-    offset += filesz;
-
-    /* shared_info */
-    if ( live_shinfo != NULL )
-    {
-        shdr = xc_core_shdr_get(xch,sheaders);
-        if ( shdr == NULL )
-        {
-            PERROR("Could not get section header for .xen_shared_info");
-            goto out;
-        }
-        filesz = PAGE_SIZE;
-        sts = xc_core_shdr_set(xch, shdr, strtab, XEN_DUMPCORE_SEC_SHARED_INFO,
-                               SHT_PROGBITS, offset, filesz,
-                               __alignof__(*live_shinfo), PAGE_SIZE);
-        if ( sts != 0 )
-            goto out;
-        offset += filesz;
-    }
-
-    /*
-     * pages and p2m/pfn are the last section to allocate section headers
-     * so that we know the number of section headers here.
-     * 2 = pages section and p2m/pfn table section
-     */
-    fixup = (sheaders->num + 2) * sizeof(*shdr);
-    /* zeroth section should have zero offset */
-    for ( i = 1; i < sheaders->num; i++ )
-        sheaders->shdrs[i].sh_offset += fixup;
-    offset += fixup;
-    dummy_len = ROUNDUP(offset, PAGE_SHIFT) - offset; /* padding length */
-    offset += dummy_len;
-
-    /* pages */
-    shdr = xc_core_shdr_get(xch,sheaders);
-    if ( shdr == NULL )
-    {
-        PERROR("could not get section headers for .xen_pages");
-        goto out;
-    }
-    filesz = (uint64_t)nr_pages * PAGE_SIZE;
-    sts = xc_core_shdr_set(xch, shdr, strtab, XEN_DUMPCORE_SEC_PAGES, 
SHT_PROGBITS,
-                           offset, filesz, PAGE_SIZE, PAGE_SIZE);
-    if ( sts != 0 )
-        goto out;
-    offset += filesz;
-
-    /* p2m/pfn table */
-    shdr = xc_core_shdr_get(xch,sheaders);
-    if ( shdr == NULL )
-    {
-        PERROR("Could not get section header for .xen_{p2m, pfn} table");
-        goto out;
-    }
-    if ( !auto_translated_physmap )
-    {
-        filesz = (uint64_t)nr_pages * sizeof(p2m_array[0]);
-        sts = xc_core_shdr_set(xch, shdr, strtab, XEN_DUMPCORE_SEC_P2M,
-                               SHT_PROGBITS,
-                               offset, filesz, __alignof__(p2m_array[0]),
-                               sizeof(p2m_array[0]));
-    }
-    else
-    {
-        filesz = (uint64_t)nr_pages * sizeof(pfn_array[0]);
-        sts = xc_core_shdr_set(xch, shdr, strtab, XEN_DUMPCORE_SEC_PFN,
-                               SHT_PROGBITS,
-                               offset, filesz, __alignof__(pfn_array[0]),
-                               sizeof(pfn_array[0]));
-    }
-    if ( sts != 0 )
-        goto out;
-    offset += filesz;
-
-    /* fixing up section header string table section header */
-    filesz = strtab->length;
-    sheaders->shdrs[strtab_idx].sh_offset = offset;
-    sheaders->shdrs[strtab_idx].sh_size = filesz;
-
-    /* write out elf header */
-    ehdr.e_shnum = sheaders->num;
-    ehdr.e_shstrndx = strtab_idx;
-    ehdr.e_machine = ELF_ARCH_MACHINE;
-    sts = dump_rtn(xch, args, (char*)&ehdr, sizeof(ehdr));
-    if ( sts != 0 )
-        goto out;
-
-    /* section headers */
-    sts = dump_rtn(xch, args, (char*)sheaders->shdrs,
-                   sheaders->num * sizeof(sheaders->shdrs[0]));
-    if ( sts != 0 )
-        goto out;
-
-    /* elf note section: xen core header */
-    sts = elfnote_dump_none(xch, args, dump_rtn);
-    if ( sts != 0 )
-        goto out;
-
-    /* elf note section: xen core header */
-    sts = elfnote_dump_core_header(xch, args, dump_rtn, &info, nr_vcpus, 
nr_pages);
-    if ( sts != 0 )
-        goto out;
-
-    /* elf note section: xen version */
-    sts = elfnote_dump_xen_version(xch, args, dump_rtn, dinfo->guest_width);
-    if ( sts != 0 )
-        goto out;
-
-    /* elf note section: format version */
-    sts = elfnote_dump_format_version(xch, args, dump_rtn);
-    if ( sts != 0 )
-        goto out;
-
-    /* prstatus: .xen_prstatus */
-    sts = dump_rtn(xch, args, (char *)ctxt, sizeof(*ctxt) * nr_vcpus);
-    if ( sts != 0 )
-        goto out;
-
-    if ( live_shinfo != NULL )
-    {
-        /* shared_info: .xen_shared_info */
-        sts = dump_rtn(xch, args, (char*)live_shinfo, PAGE_SIZE);
-        if ( sts != 0 )
-            goto out;
-    }
-
-    /* arch specific context */
-    sts = xc_core_arch_context_dump(xch, &arch_ctxt, args, dump_rtn);
-    if ( sts != 0 )
-        goto out;
-
-    /* Pad the output data to page alignment. */
-    memset(dummy, 0, PAGE_SIZE);
-    sts = dump_rtn(xch, args, dummy, dummy_len);
-    if ( sts != 0 )
-        goto out;
-
-    /* dump pages: .xen_pages */
-    j = 0;
-    dump_mem = dump_mem_start;
-    for ( map_idx = 0; map_idx < nr_memory_map; map_idx++ )
-    {
-        uint64_t pfn_start;
-        uint64_t pfn_end;
-
-        pfn_start = memory_map[map_idx].addr >> PAGE_SHIFT;
-        pfn_end = pfn_start + (memory_map[map_idx].size >> PAGE_SHIFT);
-        for ( i = pfn_start; i < pfn_end; i++ )
-        {
-            uint64_t gmfn;
-            void *vaddr;
-
-            if ( !auto_translated_physmap )
-            {
-                if ( i >= dinfo->p2m_size )
-                    break;
-
-                if ( dinfo->guest_width >= sizeof(unsigned long) )
-                {
-                    if ( dinfo->guest_width == sizeof(unsigned long) )
-                        gmfn = p2m[i];
-                    else
-                        gmfn = ((uint64_t *)p2m)[i];
-                    if ( gmfn == INVALID_PFN )
-                        continue;
-                }
-                else
-                {
-                    gmfn = ((uint32_t *)p2m)[i];
-                    if ( gmfn == (uint32_t)INVALID_PFN )
-                       continue;
-                }
-                if ( gmfn > max_mfn )
-                    continue;
-
-                if ( j >= nr_pages )
-                {
-                    j++;
-                    continue;
-                }
-
-                p2m_array[j].pfn = i;
-                p2m_array[j].gmfn = gmfn;
-            }
-            else
-            {
-                if ( !xc_core_arch_gpfn_may_present(&arch_ctxt, i) )
-                    continue;
-
-                if ( j >= nr_pages )
-                {
-                    j++;
-                    continue;
-                }
-
-                gmfn = i;
-                pfn_array[j] = i;
-            }
-
-            vaddr = xc_map_foreign_range(
-                xch, domid, PAGE_SIZE, PROT_READ, gmfn);
-            if ( vaddr == NULL )
-                continue;
-            memcpy(dump_mem, vaddr, PAGE_SIZE);
-            munmap(vaddr, PAGE_SIZE);
-            dump_mem += PAGE_SIZE;
-            if ( (j + 1) % DUMP_INCREMENT == 0 )
-            {
-                sts = dump_rtn(
-                    xch, args, dump_mem_start, dump_mem - dump_mem_start);
-                if ( sts != 0 )
-                    goto out;
-                dump_mem = dump_mem_start;
-            }
-
-            j++;
-        }
-    }
-
-    if ( j > nr_pages )
-    {
-        /*
-         * When live dump-mode (-L option) is specified,
-         * guest domain may increase memory.
-         */
-        IPRINTF("exceeded nr_pages (%ld) losing %ld pages", nr_pages, j - 
nr_pages);
-    }
-
-    sts = dump_rtn(xch, args, dump_mem_start, dump_mem - dump_mem_start);
-    if ( sts != 0 )
-        goto out;
-    if ( j < nr_pages )
-    {
-        /* When live dump-mode (-L option) is specified,
-         * guest domain may reduce memory. pad with zero pages.
-         */
-        DPRINTF("j (%ld) != nr_pages (%ld)", j, nr_pages);
-        memset(dump_mem_start, 0, PAGE_SIZE);
-        for (; j < nr_pages; j++) {
-            sts = dump_rtn(xch, args, dump_mem_start, PAGE_SIZE);
-            if ( sts != 0 )
-                goto out;
-            if ( !auto_translated_physmap )
-            {
-                p2m_array[j].pfn = XC_CORE_INVALID_PFN;
-                p2m_array[j].gmfn = XC_CORE_INVALID_GMFN;
-            }
-            else
-                pfn_array[j] = XC_CORE_INVALID_PFN;
-        }
-    }
-
-    /* p2m/pfn table: .xen_p2m/.xen_pfn */
-    if ( !auto_translated_physmap )
-        sts = dump_rtn(
-            xch, args, (char *)p2m_array, sizeof(p2m_array[0]) * nr_pages);
-    else
-        sts = dump_rtn(
-            xch, args, (char *)pfn_array, sizeof(pfn_array[0]) * nr_pages);
-    if ( sts != 0 )
-        goto out;
-
-    /* elf section header string table: .shstrtab */
-    sts = dump_rtn(xch, args, strtab->strings, strtab->length);
-    if ( sts != 0 )
-        goto out;
-
-    sts = 0;
-
-out:
-    if ( memory_map != NULL )
-        free(memory_map);
-    if ( p2m != NULL )
-        munmap(p2m, PAGE_SIZE * dinfo->p2m_frames);
-    if ( p2m_array != NULL )
-        free(p2m_array);
-    if ( pfn_array != NULL )
-        free(pfn_array);
-    if ( sheaders != NULL )
-        xc_core_shdr_free(sheaders);
-    if ( strtab != NULL )
-        xc_core_strtab_free(strtab);
-    if ( ctxt != NULL )
-        free(ctxt);
-    if ( dump_mem_start != NULL )
-        free(dump_mem_start);
-    if ( live_shinfo != NULL )
-        munmap(live_shinfo, PAGE_SIZE);
-    xc_core_arch_context_free(&arch_ctxt);
-
-    return sts;
-}
-
-/* Callback args for writing to a local dump file. */
-struct dump_args {
-    int     fd;
-};
-
-/* Callback routine for writing to a local dump file. */
-static int local_file_dump(xc_interface *xch,
-                           void *args, char *buffer, unsigned int length)
-{
-    struct dump_args *da = args;
-
-    if ( write_exact(da->fd, buffer, length) == -1 )
-    {
-        PERROR("Failed to write buffer");
-        return -errno;
-    }
-
-    if ( length >= (DUMP_INCREMENT * PAGE_SIZE) )
-    {
-        // Now dumping pages -- make sure we discard clean pages from
-        // the cache after each write
-        discard_file_cache(xch, da->fd, 0 /* no flush */);
-    }
-
-    return 0;
-}
-
-int
-xc_domain_dumpcore(xc_interface *xch,
-                   uint32_t domid,
-                   const char *corename)
-{
-    struct dump_args da;
-    int sts;
-
-    if ( (da.fd = open(corename, O_CREAT|O_RDWR|O_TRUNC, S_IWUSR|S_IRUSR)) < 0 
)
-    {
-        PERROR("Could not open corefile %s", corename);
-        return -errno;
-    }
-
-    sts = xc_domain_dumpcore_via_callback(
-        xch, domid, &da, &local_file_dump);
-
-    /* flush and discard any remaining portion of the file from cache */
-    discard_file_cache(xch, da.fd, 1/* flush first*/);
-
-    close(da.fd);
-
-    return sts;
-}
-
-/*
- * Local variables:
- * mode: C
- * c-file-style: "BSD"
- * c-basic-offset: 4
- * tab-width: 4
- * indent-tabs-mode: nil
- * End:
- */
diff --git a/tools/libs/ctrl/xc_core.h b/tools/libs/ctrl/xc_core.h
deleted file mode 100644
index 8ea1f93a10..0000000000
--- a/tools/libs/ctrl/xc_core.h
+++ /dev/null
@@ -1,176 +0,0 @@
-/*
- * Copyright (c) 2006 Isaku Yamahata <yamahata at valinux co jp>
- *                    VA Linux Systems Japan K.K.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library 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
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; If not, see <http://www.gnu.org/licenses/>.
- *
- */
-
-#ifndef XC_CORE_H
-#define XC_CORE_H
-
-#include "xen/version.h"
-#include "xc_private.h"
-#include "xen/libelf/elfstructs.h"
-
-/* section names */
-#define XEN_DUMPCORE_SEC_NOTE                   ".note.Xen"
-#define XEN_DUMPCORE_SEC_PRSTATUS               ".xen_prstatus"
-#define XEN_DUMPCORE_SEC_SHARED_INFO            ".xen_shared_info"
-#define XEN_DUMPCORE_SEC_P2M                    ".xen_p2m"
-#define XEN_DUMPCORE_SEC_PFN                    ".xen_pfn"
-#define XEN_DUMPCORE_SEC_PAGES                  ".xen_pages"
-
-/* elf note name */
-#define XEN_DUMPCORE_ELFNOTE_NAME               "Xen"
-/* note numbers are defined in xen/elfnote.h */
-
-struct elfnote {
-    uint32_t    namesz; /* Elf_Note note; */
-    uint32_t    descsz;
-    uint32_t    type;
-    char        name[4]; /* sizeof("Xen") = 4
-                          * Fotunately this is 64bit aligned so that
-                          * we can use same structore for both 32/64bit
-                          */
-};
-
-struct xen_dumpcore_elfnote_none_desc {
-    /* nothing */
-};
-
-struct xen_dumpcore_elfnote_header_desc {
-    uint64_t    xch_magic;
-    uint64_t    xch_nr_vcpus;
-    uint64_t    xch_nr_pages;
-    uint64_t    xch_page_size;
-};
-
-struct xen_dumpcore_elfnote_xen_version_desc {
-    uint64_t                    major_version;
-    uint64_t                    minor_version;
-    xen_extraversion_t          extra_version;
-    xen_compile_info_t          compile_info;
-    xen_capabilities_info_t     capabilities;
-    xen_changeset_info_t        changeset;
-    xen_platform_parameters_t   platform_parameters;
-    uint64_t                    pagesize;
-};
-
-#define XEN_DUMPCORE_FORMAT_VERSION(major, minor)  \
-    ((major) << 32) | ((minor) & 0xffffffff)
-#define XEN_DUMPCORE_FORMAT_MAJOR(version)      ((major) >> 32)
-#define XEN_DUMPCORE_FORMAT_MINOR(version)      ((minor) & 0xffffffff)
-
-#define XEN_DUMPCORE_FORMAT_MAJOR_CURRENT       ((uint64_t)0)
-#define XEN_DUMPCORE_FORMAT_MINOR_CURRENT       ((uint64_t)1)
-#define XEN_DUMPCORE_FORMAT_VERSION_CURRENT                         \
-    XEN_DUMPCORE_FORMAT_VERSION(XEN_DUMPCORE_FORMAT_MAJOR_CURRENT,  \
-                                XEN_DUMPCORE_FORMAT_MINOR_CURRENT)
-
-struct xen_dumpcore_elfnote_format_version_desc {
-    uint64_t    version;
-};
-
-
-struct xen_dumpcore_elfnote_none {
-    struct elfnote                              elfnote;
-    struct xen_dumpcore_elfnote_none_desc       none;
-};
-
-struct xen_dumpcore_elfnote_header {
-    struct elfnote                              elfnote;
-    struct xen_dumpcore_elfnote_header_desc     header;
-};
-
-struct xen_dumpcore_elfnote_xen_version {
-    struct elfnote                                     elfnote;
-    struct xen_dumpcore_elfnote_xen_version_desc        xen_version;
-};
-
-struct xen_dumpcore_elfnote_format_version {
-    struct elfnote                                      elfnote;
-    struct xen_dumpcore_elfnote_format_version_desc     format_version;
-};
-
-#define XC_CORE_INVALID_PFN     (~(uint64_t)0)
-#define XC_CORE_INVALID_GMFN    (~(uint64_t)0)
-struct xen_dumpcore_p2m {
-    uint64_t    pfn;
-    uint64_t    gmfn;
-};
-
-
-struct xc_core_strtab;
-struct xc_core_section_headers;
-
-Elf64_Shdr*
-xc_core_shdr_get(xc_interface *xch,
-                 struct xc_core_section_headers *sheaders);
-int
-xc_core_shdr_set(xc_interface *xch,
-                 Elf64_Shdr *shdr,
-                 struct xc_core_strtab *strtab,
-                 const char *name, uint32_t type,
-                 uint64_t offset, uint64_t size,
-                 uint64_t addralign, uint64_t entsize);
-
-struct xc_core_memory_map {
-    uint64_t    addr;
-    uint64_t    size;
-};
-typedef struct xc_core_memory_map xc_core_memory_map_t;
-int xc_core_arch_auto_translated_physmap(const xc_dominfo_t *info);
-struct xc_core_arch_context;
-int xc_core_arch_memory_map_get(xc_interface *xch,
-                                struct xc_core_arch_context *arch_ctxt,
-                                xc_dominfo_t *info, shared_info_any_t 
*live_shinfo,
-                                xc_core_memory_map_t **mapp,
-                                unsigned int *nr_entries);
-int xc_core_arch_map_p2m(xc_interface *xch, struct domain_info_context *dinfo,
-                         xc_dominfo_t *info, shared_info_any_t *live_shinfo,
-                         xen_pfn_t **live_p2m);
-
-int xc_core_arch_map_p2m_writable(xc_interface *xch, struct 
domain_info_context *dinfo,
-                                  xc_dominfo_t *info,
-                                  shared_info_any_t *live_shinfo,
-                                  xen_pfn_t **live_p2m);
-
-int xc_core_arch_get_scratch_gpfn(xc_interface *xch, uint32_t domid,
-                                  xen_pfn_t *gpfn);
-
-
-#if defined (__i386__) || defined (__x86_64__)
-# include "xc_core_x86.h"
-#elif defined (__arm__) || defined(__aarch64__)
-# include "xc_core_arm.h"
-#else
-# error "unsupported architecture"
-#endif
-
-#ifndef ELF_CORE_EFLAGS
-# define ELF_CORE_EFLAGS 0
-#endif
-
-#endif /* XC_CORE_H */
-
-/*
- * Local variables:
- * mode: C
- * c-file-style: "BSD"
- * c-basic-offset: 4
- * tab-width: 4
- * indent-tabs-mode: nil
- * End:
- */
diff --git a/tools/libs/ctrl/xc_core_arm.c b/tools/libs/ctrl/xc_core_arm.c
deleted file mode 100644
index 93765a565f..0000000000
--- a/tools/libs/ctrl/xc_core_arm.c
+++ /dev/null
@@ -1,113 +0,0 @@
-/*
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library 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
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; If not, see <http://www.gnu.org/licenses/>.
- *
- * Copyright (c) 2011 Citrix Systems
- *
- */
-
-#include "xc_private.h"
-#include "xc_core.h"
-
-#include <xen-tools/libs.h>
-
-int
-xc_core_arch_gpfn_may_present(struct xc_core_arch_context *arch_ctxt,
-                              unsigned long pfn)
-{
-    /* TODO: memory from DT */
-    if (pfn >= 0x80000 && pfn < 0x88000)
-        return 1;
-    return 0;
-}
-
-int
-xc_core_arch_auto_translated_physmap(const xc_dominfo_t *info)
-{
-    return 1;
-}
-
-int
-xc_core_arch_memory_map_get(xc_interface *xch, struct xc_core_arch_context 
*unused,
-                            xc_dominfo_t *info, shared_info_any_t *live_shinfo,
-                            xc_core_memory_map_t **mapp,
-                            unsigned int *nr_entries)
-{
-    xen_pfn_t p2m_size = 0;
-    xc_core_memory_map_t *map;
-
-    if ( xc_domain_nr_gpfns(xch, info->domid, &p2m_size) < 0 )
-        return -1;
-
-    map = malloc(sizeof(*map));
-    if ( map == NULL )
-    {
-        PERROR("Could not allocate memory");
-        return -1;
-    }
-
-    map->addr = 0;
-    map->size = ((uint64_t)p2m_size) << PAGE_SHIFT;
-
-    *mapp = map;
-    *nr_entries = 1;
-    return 0;
-}
-
-static int
-xc_core_arch_map_p2m_rw(xc_interface *xch, struct domain_info_context *dinfo, 
xc_dominfo_t *info,
-                        shared_info_any_t *live_shinfo, xen_pfn_t **live_p2m, 
int rw)
-{
-    errno = ENOSYS;
-    return -1;
-}
-
-int
-xc_core_arch_map_p2m(xc_interface *xch, struct domain_info_context *dinfo, 
xc_dominfo_t *info,
-                        shared_info_any_t *live_shinfo, xen_pfn_t **live_p2m)
-{
-    return xc_core_arch_map_p2m_rw(xch, dinfo, info, live_shinfo, live_p2m, 0);
-}
-
-int
-xc_core_arch_map_p2m_writable(xc_interface *xch, struct domain_info_context 
*dinfo, xc_dominfo_t *info,
-                              shared_info_any_t *live_shinfo, xen_pfn_t 
**live_p2m)
-{
-    return xc_core_arch_map_p2m_rw(xch, dinfo, info, live_shinfo, live_p2m, 1);
-}
-
-int
-xc_core_arch_get_scratch_gpfn(xc_interface *xch, uint32_t domid,
-                              xen_pfn_t *gpfn)
-{
-    /*
-     * The Grant Table region space is not used until the guest is
-     * booting. Use the first page for the scratch pfn.
-     */
-    BUILD_BUG_ON(GUEST_GNTTAB_SIZE < XC_PAGE_SIZE);
-
-    *gpfn = GUEST_GNTTAB_BASE >> XC_PAGE_SHIFT;
-
-    return 0;
-}
-
-
-/*
- * Local variables:
- * mode: C
- * c-file-style: "BSD"
- * c-basic-offset: 4
- * tab-width: 4
- * indent-tabs-mode: nil
- * End:
- */
diff --git a/tools/libs/ctrl/xc_core_arm.h b/tools/libs/ctrl/xc_core_arm.h
deleted file mode 100644
index 162f7a7569..0000000000
--- a/tools/libs/ctrl/xc_core_arm.h
+++ /dev/null
@@ -1,59 +0,0 @@
-/*
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library 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
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; If not, see <http://www.gnu.org/licenses/>.
- *
- * Copyright (c) 2012 Citrix Systems
- *
- */
-
-#ifndef XC_CORE_ARM_H
-#define XC_CORE_ARM_H
-
-#define ELF_ARCH_DATA           ELFDATA2LSB
-#define ELF_ARCH_MACHINE        EM_ARM
-
-struct xc_core_arch_context {
-    /* nothing */
-};
-
-#define xc_core_arch_context_init(arch_ctxt)            do {} while (0)
-#define xc_core_arch_context_free(arch_ctxt)            do {} while (0)
-#define xc_core_arch_context_get(arch_ctxt, ctxt, xch, domid) \
-                                                                (0)
-#define xc_core_arch_context_dump(xch, arch_ctxt, args, dump_rtn)    (0)
-
-int
-xc_core_arch_gpfn_may_present(struct xc_core_arch_context *arch_ctxt,
-                              unsigned long pfn);
-static inline int
-xc_core_arch_context_get_shdr(xc_interface *xch,
-                              struct xc_core_arch_context *arch_ctxt, 
-                              struct xc_core_section_headers *sheaders,
-                              struct xc_core_strtab *strtab,
-                              uint64_t *filesz, uint64_t offset)
-{
-    *filesz = 0;
-    return 0;
-}
-
-#endif /* XC_CORE_ARM_H */
-
-/*
- * Local variables:
- * mode: C
- * c-file-style: "BSD"
- * c-basic-offset: 4
- * tab-width: 4
- * indent-tabs-mode: nil
- * End:
- */
diff --git a/tools/libs/ctrl/xc_core_x86.c b/tools/libs/ctrl/xc_core_x86.c
deleted file mode 100644
index c8f71d4b75..0000000000
--- a/tools/libs/ctrl/xc_core_x86.c
+++ /dev/null
@@ -1,391 +0,0 @@
-/*
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library 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
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; If not, see <http://www.gnu.org/licenses/>.
- *
- * Copyright (c) 2007 Isaku Yamahata <yamahata at valinux co jp>
- *                    VA Linux Systems Japan K.K.
- *
- */
-
-#include <inttypes.h>
-#include "xc_private.h"
-#include "xc_core.h"
-#include <xen/hvm/e820.h>
-
-int
-xc_core_arch_gpfn_may_present(struct xc_core_arch_context *arch_ctxt,
-                              unsigned long pfn)
-{
-    if ((pfn >= 0xa0 && pfn < 0xc0) /* VGA hole */
-        || (pfn >= (HVM_BELOW_4G_MMIO_START >> PAGE_SHIFT)
-            && pfn < (1ULL<<32) >> PAGE_SHIFT)) /* MMIO */
-        return 0;
-    return 1;
-}
-
-int
-xc_core_arch_auto_translated_physmap(const xc_dominfo_t *info)
-{
-    return info->hvm;
-}
-
-int
-xc_core_arch_memory_map_get(xc_interface *xch, struct xc_core_arch_context 
*unused,
-                            xc_dominfo_t *info, shared_info_any_t *live_shinfo,
-                            xc_core_memory_map_t **mapp,
-                            unsigned int *nr_entries)
-{
-    xen_pfn_t p2m_size = 0;
-    xc_core_memory_map_t *map;
-
-    if ( xc_domain_nr_gpfns(xch, info->domid, &p2m_size) < 0 )
-        return -1;
-
-    map = malloc(sizeof(*map));
-    if ( map == NULL )
-    {
-        PERROR("Could not allocate memory");
-        return -1;
-    }
-
-    map->addr = 0;
-    map->size = ((uint64_t)p2m_size) << PAGE_SHIFT;
-
-    *mapp = map;
-    *nr_entries = 1;
-    return 0;
-}
-
-static inline bool is_canonical_address(uint64_t vaddr)
-{
-    return ((int64_t)vaddr >> 47) == ((int64_t)vaddr >> 63);
-}
-
-/* Virtual address ranges reserved for hypervisor. */
-#define HYPERVISOR_VIRT_START_X86_64 0xFFFF800000000000ULL
-#define HYPERVISOR_VIRT_END_X86_64   0xFFFF87FFFFFFFFFFULL
-
-#define HYPERVISOR_VIRT_START_X86_32 0x00000000F5800000ULL
-#define HYPERVISOR_VIRT_END_X86_32   0x00000000FFFFFFFFULL
-
-static xen_pfn_t *
-xc_core_arch_map_p2m_list_rw(xc_interface *xch, struct domain_info_context 
*dinfo,
-                             uint32_t dom, shared_info_any_t *live_shinfo,
-                             uint64_t p2m_cr3)
-{
-    uint64_t p2m_vaddr, p2m_end, mask, off;
-    xen_pfn_t p2m_mfn, mfn, saved_mfn, max_pfn;
-    uint64_t *ptes = NULL;
-    xen_pfn_t *mfns = NULL;
-    unsigned int fpp, n_pages, level, n_levels, shift,
-                 idx_start, idx_end, idx, saved_idx;
-
-    p2m_vaddr = GET_FIELD(live_shinfo, arch.p2m_vaddr, dinfo->guest_width);
-    fpp = PAGE_SIZE / dinfo->guest_width;
-    dinfo->p2m_frames = (dinfo->p2m_size - 1) / fpp + 1;
-    p2m_end = p2m_vaddr + dinfo->p2m_frames * PAGE_SIZE - 1;
-
-    if ( dinfo->guest_width == 8 )
-    {
-        mask = 0x0000ffffffffffffULL;
-        n_levels = 4;
-        p2m_mfn = p2m_cr3 >> 12;
-        if ( !is_canonical_address(p2m_vaddr) ||
-             !is_canonical_address(p2m_end) ||
-             p2m_end < p2m_vaddr ||
-             (p2m_vaddr <= HYPERVISOR_VIRT_END_X86_64 &&
-              p2m_end > HYPERVISOR_VIRT_START_X86_64) )
-        {
-            ERROR("Bad virtual p2m address range %#" PRIx64 "-%#" PRIx64,
-                  p2m_vaddr, p2m_end);
-            errno = ERANGE;
-            goto out;
-        }
-    }
-    else
-    {
-        mask = 0x00000000ffffffffULL;
-        n_levels = 3;
-        if ( p2m_cr3 & ~mask )
-            p2m_mfn = ~0UL;
-        else
-            p2m_mfn = (uint32_t)((p2m_cr3 >> 12) | (p2m_cr3 << 20));
-        if ( p2m_vaddr > mask || p2m_end > mask || p2m_end < p2m_vaddr ||
-             (p2m_vaddr <= HYPERVISOR_VIRT_END_X86_32 &&
-              p2m_end > HYPERVISOR_VIRT_START_X86_32) )
-        {
-            ERROR("Bad virtual p2m address range %#" PRIx64 "-%#" PRIx64,
-                  p2m_vaddr, p2m_end);
-            errno = ERANGE;
-            goto out;
-        }
-    }
-
-    mfns = malloc(sizeof(*mfns));
-    if ( !mfns )
-    {
-        ERROR("Cannot allocate memory for array of %u mfns", 1);
-        goto out;
-    }
-    mfns[0] = p2m_mfn;
-    off = 0;
-    saved_mfn = 0;
-    idx_start = idx_end = saved_idx = 0;
-
-    for ( level = n_levels; level > 0; level-- )
-    {
-        n_pages = idx_end - idx_start + 1;
-        ptes = xc_map_foreign_pages(xch, dom, PROT_READ, mfns, n_pages);
-        if ( !ptes )
-        {
-            PERROR("Failed to map %u page table pages for p2m list", n_pages);
-            goto out;
-        }
-        free(mfns);
-
-        shift = level * 9 + 3;
-        idx_start = ((p2m_vaddr - off) & mask) >> shift;
-        idx_end = ((p2m_end - off) & mask) >> shift;
-        idx = idx_end - idx_start + 1;
-        mfns = malloc(sizeof(*mfns) * idx);
-        if ( !mfns )
-        {
-            ERROR("Cannot allocate memory for array of %u mfns", idx);
-            goto out;
-        }
-
-        for ( idx = idx_start; idx <= idx_end; idx++ )
-        {
-            mfn = (ptes[idx] & 0x000ffffffffff000ULL) >> PAGE_SHIFT;
-            if ( mfn == 0 )
-            {
-                ERROR("Bad mfn %#lx during page table walk for vaddr %#" 
PRIx64 " at level %d of p2m list",
-                      mfn, off + ((uint64_t)idx << shift), level);
-                errno = ERANGE;
-                goto out;
-            }
-            mfns[idx - idx_start] = mfn;
-
-            /* Maximum pfn check at level 2. Same reasoning as for p2m tree. */
-            if ( level == 2 )
-            {
-                if ( mfn != saved_mfn )
-                {
-                    saved_mfn = mfn;
-                    saved_idx = idx - idx_start;
-                }
-            }
-        }
-
-        if ( level == 2 )
-        {
-            if ( saved_idx == idx_end )
-                saved_idx++;
-            max_pfn = ((xen_pfn_t)saved_idx << 9) * fpp;
-            if ( max_pfn < dinfo->p2m_size )
-            {
-                dinfo->p2m_size = max_pfn;
-                dinfo->p2m_frames = (dinfo->p2m_size + fpp - 1) / fpp;
-                p2m_end = p2m_vaddr + dinfo->p2m_frames * PAGE_SIZE - 1;
-                idx_end = idx_start + saved_idx;
-            }
-        }
-
-        munmap(ptes, n_pages * PAGE_SIZE);
-        ptes = NULL;
-        off = p2m_vaddr & ((mask >> shift) << shift);
-    }
-
-    return mfns;
-
- out:
-    free(mfns);
-    if ( ptes )
-        munmap(ptes, n_pages * PAGE_SIZE);
-
-    return NULL;
-}
-
-static xen_pfn_t *
-xc_core_arch_map_p2m_tree_rw(xc_interface *xch, struct domain_info_context 
*dinfo,
-                             uint32_t dom, shared_info_any_t *live_shinfo)
-{
-    /* Double and single indirect references to the live P2M table */
-    xen_pfn_t *live_p2m_frame_list_list;
-    xen_pfn_t *live_p2m_frame_list = NULL;
-    /* Copies of the above. */
-    xen_pfn_t *p2m_frame_list_list = NULL;
-    xen_pfn_t *p2m_frame_list;
-
-    int err;
-    int i;
-
-    live_p2m_frame_list_list =
-        xc_map_foreign_range(xch, dom, PAGE_SIZE, PROT_READ,
-                             GET_FIELD(live_shinfo, 
arch.pfn_to_mfn_frame_list_list, dinfo->guest_width));
-
-    if ( !live_p2m_frame_list_list )
-    {
-        PERROR("Couldn't map p2m_frame_list_list (errno %d)", errno);
-        goto out;
-    }
-
-    /* Get a local copy of the live_P2M_frame_list_list */
-    if ( !(p2m_frame_list_list = malloc(PAGE_SIZE)) )
-    {
-        ERROR("Couldn't allocate p2m_frame_list_list array");
-        goto out;
-    }
-    memcpy(p2m_frame_list_list, live_p2m_frame_list_list, PAGE_SIZE);
-
-    /* Canonicalize guest's unsigned long vs ours */
-    if ( dinfo->guest_width > sizeof(unsigned long) )
-        for ( i = 0; i < PAGE_SIZE/sizeof(unsigned long); i++ )
-            if ( i < PAGE_SIZE/dinfo->guest_width )
-                p2m_frame_list_list[i] = ((uint64_t *)p2m_frame_list_list)[i];
-            else
-                p2m_frame_list_list[i] = 0;
-    else if ( dinfo->guest_width < sizeof(unsigned long) )
-        for ( i = PAGE_SIZE/sizeof(unsigned long) - 1; i >= 0; i-- )
-            p2m_frame_list_list[i] = ((uint32_t *)p2m_frame_list_list)[i];
-
-    live_p2m_frame_list =
-        xc_map_foreign_pages(xch, dom, PROT_READ,
-                             p2m_frame_list_list,
-                             P2M_FLL_ENTRIES);
-
-    if ( !live_p2m_frame_list )
-    {
-        PERROR("Couldn't map p2m_frame_list");
-        goto out;
-    }
-
-    /* Get a local copy of the live_P2M_frame_list */
-    if ( !(p2m_frame_list = malloc(P2M_TOOLS_FL_SIZE)) )
-    {
-        ERROR("Couldn't allocate p2m_frame_list array");
-        goto out;
-    }
-    memset(p2m_frame_list, 0, P2M_TOOLS_FL_SIZE);
-    memcpy(p2m_frame_list, live_p2m_frame_list, P2M_GUEST_FL_SIZE);
-
-    /* Canonicalize guest's unsigned long vs ours */
-    if ( dinfo->guest_width > sizeof(unsigned long) )
-        for ( i = 0; i < P2M_FL_ENTRIES; i++ )
-            p2m_frame_list[i] = ((uint64_t *)p2m_frame_list)[i];
-    else if ( dinfo->guest_width < sizeof(unsigned long) )
-        for ( i = P2M_FL_ENTRIES - 1; i >= 0; i-- )
-            p2m_frame_list[i] = ((uint32_t *)p2m_frame_list)[i];
-
-    dinfo->p2m_frames = P2M_FL_ENTRIES;
-
-    return p2m_frame_list;
-
- out:
-    err = errno;
-
-    if ( live_p2m_frame_list_list )
-        munmap(live_p2m_frame_list_list, PAGE_SIZE);
-
-    if ( live_p2m_frame_list )
-        munmap(live_p2m_frame_list, P2M_FLL_ENTRIES * PAGE_SIZE);
-
-    free(p2m_frame_list_list);
-
-    errno = err;
-
-    return NULL;
-}
-
-static int
-xc_core_arch_map_p2m_rw(xc_interface *xch, struct domain_info_context *dinfo, 
xc_dominfo_t *info,
-                        shared_info_any_t *live_shinfo, xen_pfn_t **live_p2m, 
int rw)
-{
-    xen_pfn_t *p2m_frame_list = NULL;
-    uint64_t p2m_cr3;
-    uint32_t dom = info->domid;
-    int ret = -1;
-    int err;
-
-    if ( xc_domain_nr_gpfns(xch, info->domid, &dinfo->p2m_size) < 0 )
-    {
-        ERROR("Could not get maximum GPFN!");
-        goto out;
-    }
-
-    if ( dinfo->p2m_size < info->nr_pages  )
-    {
-        ERROR("p2m_size < nr_pages -1 (%lx < %lx", dinfo->p2m_size, 
info->nr_pages - 1);
-        goto out;
-    }
-
-    p2m_cr3 = GET_FIELD(live_shinfo, arch.p2m_cr3, dinfo->guest_width);
-
-    p2m_frame_list = p2m_cr3 ? xc_core_arch_map_p2m_list_rw(xch, dinfo, dom, 
live_shinfo, p2m_cr3)
-                             : xc_core_arch_map_p2m_tree_rw(xch, dinfo, dom, 
live_shinfo);
-
-    if ( !p2m_frame_list )
-        goto out;
-
-    *live_p2m = xc_map_foreign_pages(xch, dom,
-                                    rw ? (PROT_READ | PROT_WRITE) : PROT_READ,
-                                    p2m_frame_list,
-                                    dinfo->p2m_frames);
-
-    if ( !*live_p2m )
-    {
-        PERROR("Couldn't map p2m table");
-        goto out;
-    }
-
-    ret = 0;
-
-out:
-    err = errno;
-
-    free(p2m_frame_list);
-
-    errno = err;
-    return ret;
-}
-
-int
-xc_core_arch_map_p2m(xc_interface *xch, struct domain_info_context *dinfo, 
xc_dominfo_t *info,
-                        shared_info_any_t *live_shinfo, xen_pfn_t **live_p2m)
-{
-    return xc_core_arch_map_p2m_rw(xch, dinfo, info, live_shinfo, live_p2m, 0);
-}
-
-int
-xc_core_arch_map_p2m_writable(xc_interface *xch, struct domain_info_context 
*dinfo, xc_dominfo_t *info,
-                              shared_info_any_t *live_shinfo, xen_pfn_t 
**live_p2m)
-{
-    return xc_core_arch_map_p2m_rw(xch, dinfo, info, live_shinfo, live_p2m, 1);
-}
-
-int
-xc_core_arch_get_scratch_gpfn(xc_interface *xch, uint32_t domid,
-                              xen_pfn_t *gpfn)
-{
-    return xc_domain_nr_gpfns(xch, domid, gpfn);
-}
-
-/*
- * Local variables:
- * mode: C
- * c-file-style: "BSD"
- * c-basic-offset: 4
- * tab-width: 4
- * indent-tabs-mode: nil
- * End:
- */
diff --git a/tools/libs/ctrl/xc_core_x86.h b/tools/libs/ctrl/xc_core_x86.h
deleted file mode 100644
index 867146b1d9..0000000000
--- a/tools/libs/ctrl/xc_core_x86.h
+++ /dev/null
@@ -1,60 +0,0 @@
-/*
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library 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
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; If not, see <http://www.gnu.org/licenses/>.
- *
- * Copyright (c) 2007 Isaku Yamahata <yamahata at valinux co jp>
- *                    VA Linux Systems Japan K.K.
- *
- */
-
-#ifndef XC_CORE_X86_H
-#define XC_CORE_X86_H
-
-#define ELF_ARCH_DATA           ELFDATA2LSB
-#define ELF_ARCH_MACHINE       (dinfo->guest_width == 8 ? EM_X86_64 : EM_386)
-
-struct xc_core_arch_context {
-    /* nothing */
-};
-
-#define xc_core_arch_context_init(arch_ctxt)            do {} while (0)
-#define xc_core_arch_context_free(arch_ctxt)            do {} while (0)
-#define xc_core_arch_context_get(arch_ctxt, ctxt, xch, domid) \
-                                                                (0)
-#define xc_core_arch_context_dump(xch, arch_ctxt, args, dump_rtn)    (0)
-
-int
-xc_core_arch_gpfn_may_present(struct xc_core_arch_context *arch_ctxt,
-                              unsigned long pfn);
-static inline int
-xc_core_arch_context_get_shdr(xc_interface *xch,
-                              struct xc_core_arch_context *arch_ctxt, 
-                              struct xc_core_section_headers *sheaders,
-                              struct xc_core_strtab *strtab,
-                              uint64_t *filesz, uint64_t offset)
-{
-    *filesz = 0;
-    return 0;
-}
-
-#endif /* XC_CORE_X86_H */
-
-/*
- * Local variables:
- * mode: C
- * c-file-style: "BSD"
- * c-basic-offset: 4
- * tab-width: 4
- * indent-tabs-mode: nil
- * End:
- */
diff --git a/tools/libs/ctrl/xc_domain.c b/tools/libs/ctrl/xc_domain.c
index e7cea4a17d..7d118848f1 100644
--- a/tools/libs/ctrl/xc_domain.c
+++ b/tools/libs/ctrl/xc_domain.c
@@ -19,8 +19,6 @@
  * Copyright (c) 2003, K A Fraser.
  */
 
-#include "xc_private.h"
-#include "xc_core.h"
 #include "xc_private.h"
 #include <xen/memory.h>
 #include <xen/hvm/hvm_op.h>
diff --git a/tools/libs/ctrl/xc_private.h b/tools/libs/ctrl/xc_private.h
index 8ebc0b59da..dff0f0289b 100644
--- a/tools/libs/ctrl/xc_private.h
+++ b/tools/libs/ctrl/xc_private.h
@@ -467,6 +467,18 @@ void *xc_vm_event_enable(xc_interface *xch, uint32_t 
domain_id, int param,
 
 int do_dm_op(xc_interface *xch, uint32_t domid, unsigned int nr_bufs, ...);
 
+#if defined (__i386__) || defined (__x86_64__)
+static inline int xc_core_arch_auto_translated_physmap(const xc_dominfo_t 
*info)
+{
+    return info->hvm;
+}
+#elif defined (__arm__) || defined(__aarch64__)
+static inline int xc_core_arch_auto_translated_physmap(const xc_dominfo_t 
*info)
+{
+    return 1;
+}
+#endif
+
 #endif /* __XC_PRIVATE_H__ */
 
 /*
diff --git a/tools/libs/guest/Makefile b/tools/libs/guest/Makefile
index 2a2323ff09..2ce92d247e 100644
--- a/tools/libs/guest/Makefile
+++ b/tools/libs/guest/Makefile
@@ -24,6 +24,9 @@ SRCS-y += xg_offline_page.c
 else
 SRCS-y += xg_nomigrate.c
 endif
+SRCS-y       += xg_core.c
+SRCS-$(CONFIG_X86) += xg_core_x86.c
+SRCS-$(CONFIG_ARM) += xg_core_arm.c
 
 CFLAGS += -I$(XEN_libxenctrl)
 
diff --git a/tools/libs/guest/xg_core.c b/tools/libs/guest/xg_core.c
new file mode 100644
index 0000000000..c52f1161c1
--- /dev/null
+++ b/tools/libs/guest/xg_core.c
@@ -0,0 +1,1027 @@
+/*
+ * Elf format, (pfn, gmfn) table, IA64 support.
+ * Copyright (c) 2007 Isaku Yamahata <yamahata at valinux co jp>
+ *                    VA Linux Systems Japan K.K.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/*
+ * xen dump-core file format follows ELF format specification.
+ * Analisys tools shouldn't depends on the order of sections.
+ * They should follow elf header and check section names.
+ *
+ *  +--------------------------------------------------------+
+ *  |ELF header                                              |
+ *  +--------------------------------------------------------+
+ *  |section headers                                         |
+ *  |    null section header                                 |
+ *  |    .shstrtab                                           |
+ *  |    .note.Xen                                           |
+ *  |    .xen_prstatus                                       |
+ *  |    .xen_shared_info if present                         |
+ *  |    .xen_pages                                          |
+ *  |    .xen_p2m or .xen_pfn                                |
+ *  +--------------------------------------------------------+
+ *  |.note.Xen:note section                                  |
+ *  |    "Xen" is used as note name,                         |
+ *  |    types are defined in xen/include/public/elfnote.h   |
+ *  |    and descriptors are defined in xc_core.h.           |
+ *  |    dumpcore none                                       |
+ *  |    dumpcore header                                     |
+ *  |    dumpcore xen version                                |
+ *  |    dumpcore format version                             |
+ *  +--------------------------------------------------------+
+ *  |.xen_prstatus                                           |
+ *  |       vcpu_guest_context_t[nr_vcpus]                   |
+ *  +--------------------------------------------------------+
+ *  |.xen_shared_info if possible                            |
+ *  +--------------------------------------------------------+
+ *  |.xen_pages                                              |
+ *  |    page * nr_pages                                     |
+ *  +--------------------------------------------------------+
+ *  |.xen_p2m or .xen_pfn                                    |
+ *  |    .xen_p2m: struct xen_dumpcore_p2m[nr_pages]         |
+ *  |    .xen_pfn: uint64_t[nr_pages]                        |
+ *  +--------------------------------------------------------+
+ *  |.shstrtab: section header string table                  |
+ *  +--------------------------------------------------------+
+ *
+ */
+
+#include "xc_private.h"
+#include "xg_core.h"
+#include <stdlib.h>
+#include <unistd.h>
+
+#include <xen/libelf/libelf.h>
+
+/* number of pages to write at a time */
+#define DUMP_INCREMENT (4 * 1024)
+
+/* string table */
+struct xc_core_strtab {
+    char       *strings;
+    uint16_t    length;
+    uint16_t    max;
+};
+
+static struct xc_core_strtab*
+xc_core_strtab_init(xc_interface *xch)
+{
+    struct xc_core_strtab *strtab;
+    char *strings;
+    strtab = malloc(sizeof(*strtab));
+    if ( strtab == NULL )
+        return NULL;
+
+    strings = malloc(PAGE_SIZE);
+    if ( strings == NULL )
+    {
+        PERROR("Could not allocate string table init");
+        free(strtab);
+        return NULL;
+    }
+    strtab->strings = strings;
+    strtab->max = PAGE_SIZE;
+
+    /* index 0 represents none */
+    strtab->strings[0] = '\0';
+    strtab->length = 1;
+
+    return strtab;
+}
+
+static void
+xc_core_strtab_free(struct xc_core_strtab *strtab)
+{
+    free(strtab->strings);
+    free(strtab);
+}
+
+static uint16_t
+xc_core_strtab_get(xc_interface *xch, struct xc_core_strtab *strtab, const 
char *name)
+{
+    uint16_t ret = 0;
+    uint16_t len = strlen(name) + 1;
+
+    if ( strtab->length > UINT16_MAX - len )
+    {
+        PERROR("too long string table");
+        errno = E2BIG;
+        return ret;
+    }
+    
+    if ( strtab->length + len > strtab->max )
+    {
+        char *tmp;
+        if ( strtab->max > UINT16_MAX / 2 )
+        {
+            PERROR("too long string table");
+            errno = ENOMEM;
+            return ret;
+        }
+
+        tmp = realloc(strtab->strings, strtab->max * 2);
+        if ( tmp == NULL )
+        {
+            PERROR("Could not allocate string table");
+            return ret;
+        }
+
+        strtab->strings = tmp;
+        strtab->max *= 2;
+    }
+
+    ret = strtab->length;
+    strcpy(strtab->strings + strtab->length, name);
+    strtab->length += len;
+    return ret;
+}
+
+
+/* section headers */
+struct xc_core_section_headers {
+    uint16_t    num;
+    uint16_t    num_max;
+
+    Elf64_Shdr  *shdrs;
+};
+#define SHDR_INIT       ((uint16_t)16)
+#define SHDR_INC        ((uint16_t)4)
+
+static struct xc_core_section_headers*
+xc_core_shdr_init(xc_interface *xch)
+{
+    struct xc_core_section_headers *sheaders;
+    sheaders = malloc(sizeof(*sheaders));
+    if ( sheaders == NULL )
+        return NULL;
+
+    sheaders->num = 0;
+    sheaders->num_max = SHDR_INIT;
+    sheaders->shdrs = malloc(sizeof(sheaders->shdrs[0]) * sheaders->num_max);
+    if ( sheaders->shdrs == NULL )
+    {
+        free(sheaders);
+        return NULL;
+    }
+    return sheaders;
+}
+
+static void
+xc_core_shdr_free(struct xc_core_section_headers *sheaders)
+{
+    free(sheaders->shdrs);
+    free(sheaders);
+}
+
+Elf64_Shdr*
+xc_core_shdr_get(xc_interface *xch,
+                 struct xc_core_section_headers *sheaders)
+{
+    Elf64_Shdr *shdr;
+
+    if ( sheaders->num == sheaders->num_max )
+    {
+        Elf64_Shdr *shdrs;
+        if ( sheaders->num_max > UINT16_MAX - SHDR_INC )
+        {
+            errno = E2BIG;
+            return NULL;
+        }
+        sheaders->num_max += SHDR_INC;
+        shdrs = realloc(sheaders->shdrs,
+                        sizeof(sheaders->shdrs[0]) * sheaders->num_max);
+        if ( shdrs == NULL )
+            return NULL;
+        sheaders->shdrs = shdrs;
+    }
+
+    shdr = &sheaders->shdrs[sheaders->num];
+    sheaders->num++;
+    memset(shdr, 0, sizeof(*shdr));
+    return shdr;
+}
+
+int
+xc_core_shdr_set(xc_interface *xch,
+                 Elf64_Shdr *shdr,
+                 struct xc_core_strtab *strtab,
+                 const char *name, uint32_t type,
+                 uint64_t offset, uint64_t size,
+                 uint64_t addralign, uint64_t entsize)
+{
+    uint64_t name_idx = xc_core_strtab_get(xch, strtab, name);
+    if ( name_idx == 0 )
+        return -1;
+
+    shdr->sh_name = name_idx;
+    shdr->sh_type = type;
+    shdr->sh_offset = offset;
+    shdr->sh_size = size;
+    shdr->sh_addralign = addralign;
+    shdr->sh_entsize = entsize;
+    return 0;
+}
+
+static void
+xc_core_ehdr_init(Elf64_Ehdr *ehdr)
+{
+    memset(ehdr, 0, sizeof(*ehdr));
+    ehdr->e_ident[EI_MAG0] = ELFMAG0;
+    ehdr->e_ident[EI_MAG1] = ELFMAG1;
+    ehdr->e_ident[EI_MAG2] = ELFMAG2;
+    ehdr->e_ident[EI_MAG3] = ELFMAG3;
+    ehdr->e_ident[EI_CLASS] = ELFCLASS64;
+    ehdr->e_ident[EI_DATA] = ELF_ARCH_DATA;
+    ehdr->e_ident[EI_VERSION] = EV_CURRENT;
+    ehdr->e_ident[EI_OSABI] = ELFOSABI_SYSV;
+    ehdr->e_ident[EI_ABIVERSION] = EV_CURRENT;
+
+    ehdr->e_type = ET_CORE;
+    /* e_machine will be filled in later */
+    ehdr->e_version = EV_CURRENT;
+    ehdr->e_entry = 0;
+    ehdr->e_phoff = 0;
+    ehdr->e_shoff = sizeof(*ehdr);
+    ehdr->e_flags = ELF_CORE_EFLAGS;
+    ehdr->e_ehsize = sizeof(*ehdr);
+    ehdr->e_phentsize = sizeof(Elf64_Phdr);
+    ehdr->e_phnum = 0;
+    ehdr->e_shentsize = sizeof(Elf64_Shdr);
+    /* ehdr->e_shnum and ehdr->e_shstrndx aren't known here yet.
+     * fill it later */
+}
+
+static int
+elfnote_fill_xen_version(xc_interface *xch,
+                         struct xen_dumpcore_elfnote_xen_version_desc
+                         *xen_version)
+{
+    int rc;
+    memset(xen_version, 0, sizeof(*xen_version));
+
+    rc = xc_version(xch, XENVER_version, NULL);
+    if ( rc < 0 )
+        return rc;
+    xen_version->major_version = rc >> 16;
+    xen_version->minor_version = rc & ((1 << 16) - 1);
+
+    rc = xc_version(xch, XENVER_extraversion,
+                    &xen_version->extra_version);
+    if ( rc < 0 )
+        return rc;
+
+    rc = xc_version(xch, XENVER_compile_info,
+                    &xen_version->compile_info);
+    if ( rc < 0 )
+        return rc;
+
+    rc = xc_version(xch,
+                    XENVER_capabilities, &xen_version->capabilities);
+    if ( rc < 0 )
+        return rc;
+
+    rc = xc_version(xch, XENVER_changeset, &xen_version->changeset);
+    if ( rc < 0 )
+        return rc;
+
+    rc = xc_version(xch, XENVER_platform_parameters,
+                    &xen_version->platform_parameters);
+    if ( rc < 0 )
+        return rc;
+
+    rc = xc_version(xch, XENVER_pagesize, NULL);
+    if ( rc < 0 )
+        return rc;
+    xen_version->pagesize = rc;
+
+    return 0;
+}
+
+static void
+elfnote_fill_format_version(struct xen_dumpcore_elfnote_format_version_desc
+                            *format_version)
+{
+    format_version->version = XEN_DUMPCORE_FORMAT_VERSION_CURRENT;
+}
+
+static void
+elfnote_init(struct elfnote *elfnote)
+{
+    /* elf note section */
+    memset(elfnote, 0, sizeof(*elfnote));
+    elfnote->namesz = strlen(XEN_DUMPCORE_ELFNOTE_NAME) + 1;
+    strncpy(elfnote->name, XEN_DUMPCORE_ELFNOTE_NAME, sizeof(elfnote->name));
+}
+
+static int
+elfnote_dump_none(xc_interface *xch, void *args, dumpcore_rtn_t dump_rtn)
+{
+    int sts;
+    struct elfnote elfnote;
+    struct xen_dumpcore_elfnote_none_desc none;
+
+    elfnote_init(&elfnote);
+    /* Avoid compile warning about constant-zero-sized memset(). */
+    /*memset(&none, 0, sizeof(none));*/
+
+    elfnote.descsz = sizeof(none);
+    elfnote.type = XEN_ELFNOTE_DUMPCORE_NONE;
+    sts = dump_rtn(xch, args, (char*)&elfnote, sizeof(elfnote));
+    if ( sts != 0 )
+        return sts;
+    return dump_rtn(xch, args, (char*)&none, sizeof(none));
+}
+
+static int
+elfnote_dump_core_header(
+    xc_interface *xch,
+    void *args, dumpcore_rtn_t dump_rtn, const xc_dominfo_t *info,
+    int nr_vcpus, unsigned long nr_pages)
+{
+    int sts;
+    struct elfnote elfnote;
+    struct xen_dumpcore_elfnote_header_desc header;
+    
+    elfnote_init(&elfnote);
+    memset(&header, 0, sizeof(header));
+    
+    elfnote.descsz = sizeof(header);
+    elfnote.type = XEN_ELFNOTE_DUMPCORE_HEADER;
+    header.xch_magic = info->hvm ? XC_CORE_MAGIC_HVM : XC_CORE_MAGIC;
+    header.xch_nr_vcpus = nr_vcpus;
+    header.xch_nr_pages = nr_pages;
+    header.xch_page_size = PAGE_SIZE;
+    sts = dump_rtn(xch, args, (char*)&elfnote, sizeof(elfnote));
+    if ( sts != 0 )
+        return sts;
+    return dump_rtn(xch, args, (char*)&header, sizeof(header));
+}
+
+static int
+elfnote_dump_xen_version(xc_interface *xch, void *args,
+                         dumpcore_rtn_t dump_rtn, unsigned int guest_width)
+{
+    int sts;
+    struct elfnote elfnote;
+    struct xen_dumpcore_elfnote_xen_version_desc xen_version;
+
+    elfnote_init(&elfnote);
+    memset(&xen_version, 0, sizeof(xen_version));
+
+    elfnote.descsz = sizeof(xen_version);
+    elfnote.type = XEN_ELFNOTE_DUMPCORE_XEN_VERSION;
+    elfnote_fill_xen_version(xch, &xen_version);
+    if (guest_width < sizeof(unsigned long))
+    {
+        // 32 bit elf file format differs in pagesize's alignment
+        char *p = (char *)&xen_version.pagesize;
+        memmove(p - 4, p, sizeof(xen_version.pagesize));
+    }
+    sts = dump_rtn(xch, args, (char*)&elfnote, sizeof(elfnote));
+    if ( sts != 0 )
+        return sts;
+    return dump_rtn(xch, args, (char*)&xen_version, sizeof(xen_version));
+}
+
+static int
+elfnote_dump_format_version(xc_interface *xch,
+                            void *args, dumpcore_rtn_t dump_rtn)
+{
+    int sts;
+    struct elfnote elfnote;
+    struct xen_dumpcore_elfnote_format_version_desc format_version;
+
+    elfnote_init(&elfnote);
+    memset(&format_version, 0, sizeof(format_version));
+    
+    elfnote.descsz = sizeof(format_version);
+    elfnote.type = XEN_ELFNOTE_DUMPCORE_FORMAT_VERSION;
+    elfnote_fill_format_version(&format_version);
+    sts = dump_rtn(xch, args, (char*)&elfnote, sizeof(elfnote));
+    if ( sts != 0 )
+        return sts;
+    return dump_rtn(xch, args, (char*)&format_version, sizeof(format_version));
+}
+
+int
+xc_domain_dumpcore_via_callback(xc_interface *xch,
+                                uint32_t domid,
+                                void *args,
+                                dumpcore_rtn_t dump_rtn)
+{
+    xc_dominfo_t info;
+    shared_info_any_t *live_shinfo = NULL;
+    struct domain_info_context _dinfo = {};
+    struct domain_info_context *dinfo = &_dinfo;
+
+    int nr_vcpus = 0;
+    char *dump_mem, *dump_mem_start = NULL;
+    vcpu_guest_context_any_t *ctxt = NULL;
+    struct xc_core_arch_context arch_ctxt;
+    char dummy[PAGE_SIZE];
+    int dummy_len;
+    int sts = -1;
+
+    unsigned long i;
+    unsigned long j;
+    unsigned long nr_pages;
+    unsigned long max_mfn;
+
+    xc_core_memory_map_t *memory_map = NULL;
+    unsigned int nr_memory_map;
+    unsigned int map_idx;
+
+    int auto_translated_physmap;
+    xen_pfn_t *p2m = NULL;
+    struct xen_dumpcore_p2m *p2m_array = NULL;
+
+    uint64_t *pfn_array = NULL;
+
+    Elf64_Ehdr ehdr;
+    uint64_t filesz;
+    uint64_t offset;
+    uint64_t fixup;
+
+    struct xc_core_strtab *strtab = NULL;
+    uint16_t strtab_idx;
+    struct xc_core_section_headers *sheaders = NULL;
+    Elf64_Shdr *shdr;
+ 
+    xc_core_arch_context_init(&arch_ctxt);
+    if ( (dump_mem_start = malloc(DUMP_INCREMENT*PAGE_SIZE)) == NULL )
+    {
+        PERROR("Could not allocate dump_mem");
+        goto out;
+    }
+
+    if ( xc_domain_getinfo(xch, domid, 1, &info) != 1 )
+    {
+        PERROR("Could not get info for domain");
+        goto out;
+    }
+    /* Map the shared info frame */
+    live_shinfo = xc_map_foreign_range(xch, domid, PAGE_SIZE,
+                                       PROT_READ, info.shared_info_frame);
+    if ( !live_shinfo && !info.hvm )
+    {
+        PERROR("Couldn't map live_shinfo");
+        goto out;
+    }
+    auto_translated_physmap = xc_core_arch_auto_translated_physmap(&info);
+
+    if ( !auto_translated_physmap )
+
+    {
+        if ( xc_domain_get_guest_width(xch, domid, &dinfo->guest_width) != 0 )
+        {
+            PERROR("Could not get address size for domain");
+            goto out;
+        }
+    }
+    else
+    {
+        /*
+         * Autotranslated guest never sets guest width in the first
+         * place. Force guest_width to be sizeof(unsigned long) so
+         * code below functions properly.
+         *
+         * Here is why this is correct.
+         *
+         * 1. Before f969bc9fc, xc_domain_get_guest_width for HVM (x86
+         * and ARM) always returned hypervisor's idea of
+         * sizeof(unsigned long).
+         *
+         * 2. There has never been a situation in which hypervisor's
+         * word width is smaller than toolstack domain's (i.e. no
+         * 32bit hypervisor + 64bit toolstack).
+         *
+         * Predicates in code test guest_width against toolstack
+         * domain's sizeof(unsigned long), so setting guest_width to
+         * toolstack domain's idea of sizeof(unsigned long) matches
+         * the original behaviour for HVM guests.
+         */
+        dinfo->guest_width = sizeof(unsigned long);
+    }
+
+    if ( domid != info.domid )
+    {
+        PERROR("Domain %d does not exist", domid);
+        goto out;
+    }
+
+    ctxt = calloc(sizeof(*ctxt), info.max_vcpu_id + 1);
+    if ( !ctxt )
+    {
+        PERROR("Could not allocate vcpu context array");
+        goto out;
+    }
+
+    for ( i = 0; i <= info.max_vcpu_id; i++ )
+    {
+        if ( xc_vcpu_getcontext(xch, domid, i, &ctxt[nr_vcpus]) == 0 )
+        {
+            if ( xc_core_arch_context_get(&arch_ctxt, &ctxt[nr_vcpus],
+                                          xch, domid) )
+                continue;
+            nr_vcpus++;
+        }
+    }
+    if ( nr_vcpus == 0 )
+    {
+        PERROR("No VCPU context could be grabbed");
+        goto out;
+    }
+
+    /* obtain memory map */
+    sts = xc_core_arch_memory_map_get(xch, &arch_ctxt, &info,
+                                      live_shinfo, &memory_map,
+                                      &nr_memory_map);
+    if ( sts != 0 )
+        goto out;
+
+    /*
+     * Note: this is the *current* number of pages and may change under
+     * a live dump-core.  We'll just take this value, and if more pages
+     * exist, we'll skip them.  If there's less, then we'll just not use
+     * all the array...
+     *
+     * We don't want to use the total potential size of the memory map
+     * since that is usually much higher than info.nr_pages.
+     */
+    nr_pages = info.nr_pages;
+
+    if ( !auto_translated_physmap )
+    {
+        /* obtain p2m table */
+        p2m_array = malloc(nr_pages * sizeof(p2m_array[0]));
+        if ( p2m_array == NULL )
+        {
+            PERROR("Could not allocate p2m array");
+            goto out;
+        }
+
+        sts = xc_core_arch_map_p2m(xch, dinfo, &info, live_shinfo, &p2m);
+        if ( sts != 0 )
+            goto out;
+
+        sts = xc_maximum_ram_page(xch, &max_mfn);
+        if ( sts != 0 )
+            goto out;
+    }
+    else
+    {
+        pfn_array = malloc(nr_pages * sizeof(pfn_array[0]));
+        if ( pfn_array == NULL )
+        {
+            PERROR("Could not allocate pfn array");
+            goto out;
+        }
+    }
+
+    /* ehdr.e_shnum and ehdr.e_shstrndx aren't known here yet. fill it later*/
+    xc_core_ehdr_init(&ehdr);
+
+    /* create section header */
+    strtab = xc_core_strtab_init(xch);
+    if ( strtab == NULL )
+    {
+        PERROR("Could not allocate string table");
+        goto out;
+    }
+    sheaders = xc_core_shdr_init(xch);
+    if ( sheaders == NULL )
+    {
+        PERROR("Could not allocate section headers");
+        goto out;
+    }
+    /* null section */
+    shdr = xc_core_shdr_get(xch,sheaders);
+    if ( shdr == NULL )
+    {
+        PERROR("Could not get section header for null section");
+        goto out;
+    }
+
+    /* .shstrtab */
+    shdr = xc_core_shdr_get(xch,sheaders);
+    if ( shdr == NULL )
+    {
+        PERROR("Could not get section header for shstrtab");
+        goto out;
+    }
+    strtab_idx = shdr - sheaders->shdrs;
+    /* strtab_shdr.sh_offset, strtab_shdr.sh_size aren't unknown.
+     * fill it later
+     */
+    sts = xc_core_shdr_set(xch, shdr, strtab, ELF_SHSTRTAB, SHT_STRTAB, 0, 0, 
0, 0);
+    if ( sts != 0 )
+        goto out;
+
+    /* elf note section */
+    /* here the number of section header is unknown. fix up offset later. */
+    offset = sizeof(ehdr);
+    filesz =
+        sizeof(struct xen_dumpcore_elfnote_none) +         /* none */
+        sizeof(struct xen_dumpcore_elfnote_header) +       /* core header */
+        sizeof(struct xen_dumpcore_elfnote_xen_version) +  /* xen version */
+        sizeof(struct xen_dumpcore_elfnote_format_version);/* format version */
+    shdr = xc_core_shdr_get(xch,sheaders);
+    if ( shdr == NULL )
+    {
+        PERROR("Could not get section header for note section");
+        goto out;
+    }
+    sts = xc_core_shdr_set(xch, shdr, strtab, XEN_DUMPCORE_SEC_NOTE, SHT_NOTE,
+                           offset, filesz, 0, 0);
+    if ( sts != 0 )
+        goto out;
+    offset += filesz;
+
+    /* prstatus */
+    shdr = xc_core_shdr_get(xch,sheaders);
+    if ( shdr == NULL )
+    {
+        PERROR("Could not get section header for .xen_prstatus");
+        goto out;
+    }
+    filesz = sizeof(*ctxt) * nr_vcpus;
+    sts = xc_core_shdr_set(xch, shdr, strtab, XEN_DUMPCORE_SEC_PRSTATUS,
+                           SHT_PROGBITS, offset, filesz,
+                           __alignof__(*ctxt), sizeof(*ctxt));
+    if ( sts != 0 )
+        goto out;
+    offset += filesz;
+
+    /* arch context */
+    sts = xc_core_arch_context_get_shdr(xch, &arch_ctxt, sheaders, strtab,
+                                        &filesz, offset);
+    if ( sts != 0 )
+        goto out;
+    offset += filesz;
+
+    /* shared_info */
+    if ( live_shinfo != NULL )
+    {
+        shdr = xc_core_shdr_get(xch,sheaders);
+        if ( shdr == NULL )
+        {
+            PERROR("Could not get section header for .xen_shared_info");
+            goto out;
+        }
+        filesz = PAGE_SIZE;
+        sts = xc_core_shdr_set(xch, shdr, strtab, XEN_DUMPCORE_SEC_SHARED_INFO,
+                               SHT_PROGBITS, offset, filesz,
+                               __alignof__(*live_shinfo), PAGE_SIZE);
+        if ( sts != 0 )
+            goto out;
+        offset += filesz;
+    }
+
+    /*
+     * pages and p2m/pfn are the last section to allocate section headers
+     * so that we know the number of section headers here.
+     * 2 = pages section and p2m/pfn table section
+     */
+    fixup = (sheaders->num + 2) * sizeof(*shdr);
+    /* zeroth section should have zero offset */
+    for ( i = 1; i < sheaders->num; i++ )
+        sheaders->shdrs[i].sh_offset += fixup;
+    offset += fixup;
+    dummy_len = ROUNDUP(offset, PAGE_SHIFT) - offset; /* padding length */
+    offset += dummy_len;
+
+    /* pages */
+    shdr = xc_core_shdr_get(xch,sheaders);
+    if ( shdr == NULL )
+    {
+        PERROR("could not get section headers for .xen_pages");
+        goto out;
+    }
+    filesz = (uint64_t)nr_pages * PAGE_SIZE;
+    sts = xc_core_shdr_set(xch, shdr, strtab, XEN_DUMPCORE_SEC_PAGES, 
SHT_PROGBITS,
+                           offset, filesz, PAGE_SIZE, PAGE_SIZE);
+    if ( sts != 0 )
+        goto out;
+    offset += filesz;
+
+    /* p2m/pfn table */
+    shdr = xc_core_shdr_get(xch,sheaders);
+    if ( shdr == NULL )
+    {
+        PERROR("Could not get section header for .xen_{p2m, pfn} table");
+        goto out;
+    }
+    if ( !auto_translated_physmap )
+    {
+        filesz = (uint64_t)nr_pages * sizeof(p2m_array[0]);
+        sts = xc_core_shdr_set(xch, shdr, strtab, XEN_DUMPCORE_SEC_P2M,
+                               SHT_PROGBITS,
+                               offset, filesz, __alignof__(p2m_array[0]),
+                               sizeof(p2m_array[0]));
+    }
+    else
+    {
+        filesz = (uint64_t)nr_pages * sizeof(pfn_array[0]);
+        sts = xc_core_shdr_set(xch, shdr, strtab, XEN_DUMPCORE_SEC_PFN,
+                               SHT_PROGBITS,
+                               offset, filesz, __alignof__(pfn_array[0]),
+                               sizeof(pfn_array[0]));
+    }
+    if ( sts != 0 )
+        goto out;
+    offset += filesz;
+
+    /* fixing up section header string table section header */
+    filesz = strtab->length;
+    sheaders->shdrs[strtab_idx].sh_offset = offset;
+    sheaders->shdrs[strtab_idx].sh_size = filesz;
+
+    /* write out elf header */
+    ehdr.e_shnum = sheaders->num;
+    ehdr.e_shstrndx = strtab_idx;
+    ehdr.e_machine = ELF_ARCH_MACHINE;
+    sts = dump_rtn(xch, args, (char*)&ehdr, sizeof(ehdr));
+    if ( sts != 0 )
+        goto out;
+
+    /* section headers */
+    sts = dump_rtn(xch, args, (char*)sheaders->shdrs,
+                   sheaders->num * sizeof(sheaders->shdrs[0]));
+    if ( sts != 0 )
+        goto out;
+
+    /* elf note section: xen core header */
+    sts = elfnote_dump_none(xch, args, dump_rtn);
+    if ( sts != 0 )
+        goto out;
+
+    /* elf note section: xen core header */
+    sts = elfnote_dump_core_header(xch, args, dump_rtn, &info, nr_vcpus, 
nr_pages);
+    if ( sts != 0 )
+        goto out;
+
+    /* elf note section: xen version */
+    sts = elfnote_dump_xen_version(xch, args, dump_rtn, dinfo->guest_width);
+    if ( sts != 0 )
+        goto out;
+
+    /* elf note section: format version */
+    sts = elfnote_dump_format_version(xch, args, dump_rtn);
+    if ( sts != 0 )
+        goto out;
+
+    /* prstatus: .xen_prstatus */
+    sts = dump_rtn(xch, args, (char *)ctxt, sizeof(*ctxt) * nr_vcpus);
+    if ( sts != 0 )
+        goto out;
+
+    if ( live_shinfo != NULL )
+    {
+        /* shared_info: .xen_shared_info */
+        sts = dump_rtn(xch, args, (char*)live_shinfo, PAGE_SIZE);
+        if ( sts != 0 )
+            goto out;
+    }
+
+    /* arch specific context */
+    sts = xc_core_arch_context_dump(xch, &arch_ctxt, args, dump_rtn);
+    if ( sts != 0 )
+        goto out;
+
+    /* Pad the output data to page alignment. */
+    memset(dummy, 0, PAGE_SIZE);
+    sts = dump_rtn(xch, args, dummy, dummy_len);
+    if ( sts != 0 )
+        goto out;
+
+    /* dump pages: .xen_pages */
+    j = 0;
+    dump_mem = dump_mem_start;
+    for ( map_idx = 0; map_idx < nr_memory_map; map_idx++ )
+    {
+        uint64_t pfn_start;
+        uint64_t pfn_end;
+
+        pfn_start = memory_map[map_idx].addr >> PAGE_SHIFT;
+        pfn_end = pfn_start + (memory_map[map_idx].size >> PAGE_SHIFT);
+        for ( i = pfn_start; i < pfn_end; i++ )
+        {
+            uint64_t gmfn;
+            void *vaddr;
+
+            if ( !auto_translated_physmap )
+            {
+                if ( i >= dinfo->p2m_size )
+                    break;
+
+                if ( dinfo->guest_width >= sizeof(unsigned long) )
+                {
+                    if ( dinfo->guest_width == sizeof(unsigned long) )
+                        gmfn = p2m[i];
+                    else
+                        gmfn = ((uint64_t *)p2m)[i];
+                    if ( gmfn == INVALID_PFN )
+                        continue;
+                }
+                else
+                {
+                    gmfn = ((uint32_t *)p2m)[i];
+                    if ( gmfn == (uint32_t)INVALID_PFN )
+                       continue;
+                }
+                if ( gmfn > max_mfn )
+                    continue;
+
+                if ( j >= nr_pages )
+                {
+                    j++;
+                    continue;
+                }
+
+                p2m_array[j].pfn = i;
+                p2m_array[j].gmfn = gmfn;
+            }
+            else
+            {
+                if ( !xc_core_arch_gpfn_may_present(&arch_ctxt, i) )
+                    continue;
+
+                if ( j >= nr_pages )
+                {
+                    j++;
+                    continue;
+                }
+
+                gmfn = i;
+                pfn_array[j] = i;
+            }
+
+            vaddr = xc_map_foreign_range(
+                xch, domid, PAGE_SIZE, PROT_READ, gmfn);
+            if ( vaddr == NULL )
+                continue;
+            memcpy(dump_mem, vaddr, PAGE_SIZE);
+            munmap(vaddr, PAGE_SIZE);
+            dump_mem += PAGE_SIZE;
+            if ( (j + 1) % DUMP_INCREMENT == 0 )
+            {
+                sts = dump_rtn(
+                    xch, args, dump_mem_start, dump_mem - dump_mem_start);
+                if ( sts != 0 )
+                    goto out;
+                dump_mem = dump_mem_start;
+            }
+
+            j++;
+        }
+    }
+
+    if ( j > nr_pages )
+    {
+        /*
+         * When live dump-mode (-L option) is specified,
+         * guest domain may increase memory.
+         */
+        IPRINTF("exceeded nr_pages (%ld) losing %ld pages", nr_pages, j - 
nr_pages);
+    }
+
+    sts = dump_rtn(xch, args, dump_mem_start, dump_mem - dump_mem_start);
+    if ( sts != 0 )
+        goto out;
+    if ( j < nr_pages )
+    {
+        /* When live dump-mode (-L option) is specified,
+         * guest domain may reduce memory. pad with zero pages.
+         */
+        DPRINTF("j (%ld) != nr_pages (%ld)", j, nr_pages);
+        memset(dump_mem_start, 0, PAGE_SIZE);
+        for (; j < nr_pages; j++) {
+            sts = dump_rtn(xch, args, dump_mem_start, PAGE_SIZE);
+            if ( sts != 0 )
+                goto out;
+            if ( !auto_translated_physmap )
+            {
+                p2m_array[j].pfn = XC_CORE_INVALID_PFN;
+                p2m_array[j].gmfn = XC_CORE_INVALID_GMFN;
+            }
+            else
+                pfn_array[j] = XC_CORE_INVALID_PFN;
+        }
+    }
+
+    /* p2m/pfn table: .xen_p2m/.xen_pfn */
+    if ( !auto_translated_physmap )
+        sts = dump_rtn(
+            xch, args, (char *)p2m_array, sizeof(p2m_array[0]) * nr_pages);
+    else
+        sts = dump_rtn(
+            xch, args, (char *)pfn_array, sizeof(pfn_array[0]) * nr_pages);
+    if ( sts != 0 )
+        goto out;
+
+    /* elf section header string table: .shstrtab */
+    sts = dump_rtn(xch, args, strtab->strings, strtab->length);
+    if ( sts != 0 )
+        goto out;
+
+    sts = 0;
+
+out:
+    if ( memory_map != NULL )
+        free(memory_map);
+    if ( p2m != NULL )
+        munmap(p2m, PAGE_SIZE * dinfo->p2m_frames);
+    if ( p2m_array != NULL )
+        free(p2m_array);
+    if ( pfn_array != NULL )
+        free(pfn_array);
+    if ( sheaders != NULL )
+        xc_core_shdr_free(sheaders);
+    if ( strtab != NULL )
+        xc_core_strtab_free(strtab);
+    if ( ctxt != NULL )
+        free(ctxt);
+    if ( dump_mem_start != NULL )
+        free(dump_mem_start);
+    if ( live_shinfo != NULL )
+        munmap(live_shinfo, PAGE_SIZE);
+    xc_core_arch_context_free(&arch_ctxt);
+
+    return sts;
+}
+
+/* Callback args for writing to a local dump file. */
+struct dump_args {
+    int     fd;
+};
+
+/* Callback routine for writing to a local dump file. */
+static int local_file_dump(xc_interface *xch,
+                           void *args, char *buffer, unsigned int length)
+{
+    struct dump_args *da = args;
+
+    if ( write_exact(da->fd, buffer, length) == -1 )
+    {
+        PERROR("Failed to write buffer");
+        return -errno;
+    }
+
+    if ( length >= (DUMP_INCREMENT * PAGE_SIZE) )
+    {
+        // Now dumping pages -- make sure we discard clean pages from
+        // the cache after each write
+        discard_file_cache(xch, da->fd, 0 /* no flush */);
+    }
+
+    return 0;
+}
+
+int
+xc_domain_dumpcore(xc_interface *xch,
+                   uint32_t domid,
+                   const char *corename)
+{
+    struct dump_args da;
+    int sts;
+
+    if ( (da.fd = open(corename, O_CREAT|O_RDWR|O_TRUNC, S_IWUSR|S_IRUSR)) < 0 
)
+    {
+        PERROR("Could not open corefile %s", corename);
+        return -errno;
+    }
+
+    sts = xc_domain_dumpcore_via_callback(
+        xch, domid, &da, &local_file_dump);
+
+    /* flush and discard any remaining portion of the file from cache */
+    discard_file_cache(xch, da.fd, 1/* flush first*/);
+
+    close(da.fd);
+
+    return sts;
+}
+
+/*
+ * Local variables:



 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.