WARNING - OLD ARCHIVES

This is an archived copy of the Xen.org mailing list, which we have preserved to ensure that existing links to archives are not broken. The live archive, which contains the latest emails, can be found at http://lists.xen.org/
   
 
 
Xen 
 
Home Products Support Community News
 
   
 

xen-changelog

[Xen-changelog] [xen-unstable] Xen coredump format: ELF formatified with

To: xen-changelog@xxxxxxxxxxxxxxxxxxx
Subject: [Xen-changelog] [xen-unstable] Xen coredump format: ELF formatified with note section.
From: Xen patchbot-unstable <patchbot-unstable@xxxxxxxxxxxxxxxxxxx>
Date: Mon, 26 Feb 2007 03:50:21 -0800
Delivery-date: Mon, 26 Feb 2007 04:40:52 -0800
Envelope-to: www-data@xxxxxxxxxxxxxxxxxx
List-help: <mailto:xen-changelog-request@lists.xensource.com?subject=help>
List-id: BK change log <xen-changelog.lists.xensource.com>
List-post: <mailto:xen-changelog@lists.xensource.com>
List-subscribe: <http://lists.xensource.com/cgi-bin/mailman/listinfo/xen-changelog>, <mailto:xen-changelog-request@lists.xensource.com?subject=subscribe>
List-unsubscribe: <http://lists.xensource.com/cgi-bin/mailman/listinfo/xen-changelog>, <mailto:xen-changelog-request@lists.xensource.com?subject=unsubscribe>
Reply-to: xen-devel@xxxxxxxxxxxxxxxxxxx
Sender: xen-changelog-bounces@xxxxxxxxxxxxxxxxxxx
# HG changeset patch
# User Keir Fraser <keir@xxxxxxxxxxxxx>
# Date 1172327502 0
# Node ID 3dac99b6034e789b0a43152ebe5ef8ed70fb8472
# Parent  f61992cb82fe6022728977ee87afd65554afdaff
Xen coredump format: ELF formatified with note section.
added PFN-GMFN table for non-auto translated physmap
added PFN table for auto translated physmap.
HVM domain support.
IA64 support

Signed-off-by: Isaku Yamahata <yamahata@xxxxxxxxxxxxx>

Use the guest's own p2m table instead of xc_get_pfn_list(), which
cannot handle PFNs with no MFN.
Dump a zeroed page for PFNs with no MFN.
Clearly deprecate xc_get_pfn_list().
Do not include a P2M table with HVM domains.
Refuse to dump HVM until we can map its pages with PFNs.

Signed-off-by: John Levon <john.levon@xxxxxxx>
---
 tools/libxc/Makefile         |    2 
 tools/libxc/xc_core.c        |  765 +++++++++++++++++++++++++++++++++++++++----
 tools/libxc/xc_core.h        |  165 +++++++++
 tools/libxc/xc_core_ia64.c   |  315 +++++++++++++++++
 tools/libxc/xc_core_ia64.h   |   60 +++
 tools/libxc/xc_core_x86.c    |  136 +++++++
 tools/libxc/xc_core_x86.h    |   64 +++
 tools/libxc/xc_efi.h         |   68 +++
 tools/libxc/xenctrl.h        |    5 
 xen/include/public/elfnote.h |   35 +
 10 files changed, 1561 insertions(+), 54 deletions(-)

diff -r f61992cb82fe -r 3dac99b6034e tools/libxc/Makefile
--- a/tools/libxc/Makefile      Sat Feb 24 14:19:42 2007 +0000
+++ b/tools/libxc/Makefile      Sat Feb 24 14:31:42 2007 +0000
@@ -6,6 +6,8 @@ MINOR    = 0
 
 CTRL_SRCS-y       :=
 CTRL_SRCS-y       += xc_core.c
+CTRL_SRCS-$(CONFIG_X86) += xc_core_x86.c
+CTRL_SRCS-$(CONFIG_IA64) += xc_core_ia64.c
 CTRL_SRCS-y       += xc_domain.c
 CTRL_SRCS-y       += xc_evtchn.c
 CTRL_SRCS-y       += xc_misc.c
diff -r f61992cb82fe -r 3dac99b6034e tools/libxc/xc_core.c
--- a/tools/libxc/xc_core.c     Sat Feb 24 14:19:42 2007 +0000
+++ b/tools/libxc/xc_core.c     Sat Feb 24 14:31:42 2007 +0000
@@ -1,10 +1,62 @@
+/*
+ * Elf format, (pfn, gmfn) table, IA64 support.
+ * Copyright (c) 2007 Isaku Yamahata <yamahata at valinux co jp>
+ *                    VA Linux Systems Japan K.K.
+ *
+ * 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_ia64_mmapped_regs if ia64                      |
+ *  |    .xen_shared_info if present                         |
+ *  |    .xen_p2m or .xen_pfn                                |
+ *  |    .xen_pages                                          |
+ *  +--------------------------------------------------------+
+ *  |.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_ia64_mmapped_regs if ia64                          |
+ *  |       mmapped_regs_t[nr_vcpus]                         |
+ *  +--------------------------------------------------------+
+ *  |.xen_shared_info if possible                            |
+ *  +--------------------------------------------------------+
+ *  |.xen_p2m or .xen_pfn                                    |
+ *  |    .xen_p2m: struct xen_dumpcore_p2m[nr_pages]         |
+ *  |    .xen_pfn: uint64_t[nr_pages]                        |
+ *  +--------------------------------------------------------+
+ *  |.xen_pages                                              |
+ *  |    page * nr_pages                                     |
+ *  +--------------------------------------------------------+
+ *  |.shstrtab: section header string table                  |
+ *  +--------------------------------------------------------+
+ *
+ */
+
 #include "xg_private.h"
+#include "xc_core.h"
+#include "xc_dom.h"
 #include <stdlib.h>
 #include <unistd.h>
 
 /* number of pages to write at a time */
 #define DUMP_INCREMENT (4 * 1024)
-#define round_pgup(_p)    (((_p)+(PAGE_SIZE-1))&PAGE_MASK)
 
 static int
 copy_from_domain_page(int xc_handle,
@@ -21,107 +73,712 @@ copy_from_domain_page(int xc_handle,
     return 0;
 }
 
+/* string table */
+struct xc_core_strtab {
+    char       *strings;
+    uint16_t    current;
+    uint16_t    max;
+};
+
+static struct xc_core_strtab*
+xc_core_strtab_init(void)
+{
+    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->current = 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(struct xc_core_strtab *strtab, const char *name)
+{
+    uint16_t ret = 0;
+    uint16_t len = strlen(name) + 1;
+
+    if ( strtab->current + len > strtab->max )
+    {
+        char *tmp;
+        if ( strtab->max * 2 < strtab->max )
+        {
+            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->current;
+    strcpy(strtab->strings + strtab->current, name);
+    strtab->current += len;
+    return ret;
+}
+
+
+/* section headers */
+struct xc_core_section_headers {
+    uint16_t    num;
+    uint16_t    num_max;
+
+    Elf_Shdr   *shdrs;
+};
+#define SHDR_INIT       16
+#define SHDR_INC        4
+
+static struct xc_core_section_headers*
+xc_core_shdr_init(void)
+{
+    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);
+}
+
+Elf_Shdr*
+xc_core_shdr_get(struct xc_core_section_headers *sheaders)
+{
+    Elf_Shdr *shdr;
+
+    if ( sheaders->num == sheaders->num_max )
+    {
+        Elf_Shdr *shdrs;
+        if ( sheaders->num_max + SHDR_INC < sheaders->num_max )
+        {
+            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(Elf_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(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 int
+elfnote_fill_xen_version(int xc_handle,
+                         struct xen_dumpcore_elfnote_xen_version_desc
+                         *xen_version)
+{
+    int rc;
+    memset(xen_version, 0, sizeof(*xen_version));
+
+    rc = xc_version(xc_handle, 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(xc_handle, XENVER_extraversion,
+                    &xen_version->extra_version);
+    if ( rc < 0 )
+        return rc;
+
+    rc = xc_version(xc_handle, XENVER_compile_info,
+                    &xen_version->compile_info);
+    if ( rc < 0 )
+        return rc;
+
+    rc = xc_version(xc_handle,
+                    XENVER_capabilities, &xen_version->capabilities);
+    if ( rc < 0 )
+        return rc;
+
+    rc = xc_version(xc_handle, XENVER_changeset, &xen_version->changeset);
+    if ( rc < 0 )
+        return rc;
+
+    rc = xc_version(xc_handle, XENVER_platform_parameters,
+                    &xen_version->platform_parameters);
+    if ( rc < 0 )
+        return rc;
+
+    rc = xc_version(xc_handle, XENVER_pagesize, NULL);
+    if ( rc < 0 )
+        return rc;
+    xen_version->pagesize = rc;
+
+    return 0;
+}
+
+static int
+elfnote_fill_format_version(struct xen_dumpcore_elfnote_format_version_desc
+                            *format_version)
+{
+    format_version->version = XEN_DUMPCORE_FORMAT_VERSION_CURRENT;
+    return 0;
+}
+
 int
 xc_domain_dumpcore_via_callback(int xc_handle,
                                 uint32_t domid,
                                 void *args,
                                 dumpcore_rtn_t dump_rtn)
 {
-    unsigned long nr_pages;
-    uint64_t *page_array = NULL;
     xc_dominfo_t info;
-    int i, nr_vcpus = 0;
+    shared_info_t *live_shinfo = NULL;
+
+    int nr_vcpus = 0;
     char *dump_mem, *dump_mem_start = NULL;
-    struct xc_core_header header;
     vcpu_guest_context_t  ctxt[MAX_VIRT_CPUS];
+    struct xc_core_arch_context arch_ctxt;
     char dummy[PAGE_SIZE];
     int dummy_len;
-    int sts;
-
+    int sts = -1;
+
+    unsigned long i;
+    unsigned long j;
+    unsigned long nr_pages;
+
+    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;
+    unsigned long max_pfn = 0;
+    struct xen_dumpcore_p2m *p2m_array = NULL;
+
+    uint64_t *pfn_array = NULL;
+
+    Elf_Ehdr ehdr;
+    unsigned long filesz;
+    unsigned long offset;
+    unsigned long fixup;
+
+    struct xc_core_strtab *strtab = NULL;
+    uint16_t strtab_idx;
+    struct xc_core_section_headers *sheaders = NULL;
+    Elf_Shdr *shdr;
+
+    /* elf notes */
+    struct xen_elfnote elfnote;
+    struct xen_dumpcore_elfnote_none_desc none;
+    struct xen_dumpcore_elfnote_header_desc header;
+    struct xen_dumpcore_elfnote_xen_version_desc xen_version;
+    struct xen_dumpcore_elfnote_format_version_desc format_version;
+
+    xc_core_arch_context_init(&arch_ctxt);
     if ( (dump_mem_start = malloc(DUMP_INCREMENT*PAGE_SIZE)) == NULL )
     {
         PERROR("Could not allocate dump_mem");
-        goto error_out;
+        goto out;
     }
 
     if ( xc_domain_getinfo(xc_handle, domid, 1, &info) != 1 )
     {
         PERROR("Could not get info for domain");
-        goto error_out;
-    }
+        goto out;
+    }
+    /* Map the shared info frame */
+    live_shinfo = xc_map_foreign_range(xc_handle, domid, PAGE_SIZE,
+                                       PROT_READ, info.shared_info_frame);
+    if ( !live_shinfo 
+#ifdef __ia64__
+         && !info.hvm
+#endif
+        )
+    {
+        PERROR("Couldn't map live_shinfo");
+        goto out;
+    }
+    auto_translated_physmap = xc_core_arch_auto_translated_physmap(&info);
 
     if ( domid != info.domid )
     {
         PERROR("Domain %d does not exist", domid);
-        goto error_out;
+        goto out;
     }
 
     for ( i = 0; i <= info.max_vcpu_id; i++ )
-        if ( xc_vcpu_getcontext(xc_handle, domid, i, &ctxt[nr_vcpus]) == 0)
+    {
+        if ( xc_vcpu_getcontext(xc_handle, domid, i, &ctxt[nr_vcpus]) == 0 )
+        {
+            if ( xc_core_arch_context_get(&arch_ctxt, &ctxt[nr_vcpus],
+                                          xc_handle, 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(xc_handle, &info, live_shinfo,
+                                      &memory_map, &nr_memory_map);
+    if ( sts != 0 )
+        goto out;
 
     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(xc_handle, &info, live_shinfo,
+                                   &p2m, &max_pfn);
+        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;
+        }
+    }
+
+    /* create .xen_p2m or .xen_pfn */
+    j = 0;
+    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++ )
+        {
+            if ( !auto_translated_physmap )
+            {
+                if ( p2m[i] == INVALID_P2M_ENTRY )
+                    continue;
+                p2m_array[j].pfn = i;
+                p2m_array[j].gmfn = p2m[i];
+            }
+            else
+            {
+                /* try to map page to determin wheter it has underlying page */
+                void *vaddr = xc_map_foreign_range(xc_handle, domid,
+                                                   PAGE_SIZE, PROT_READ, i);
+                if ( vaddr == NULL )
+                    continue;
+                munmap(vaddr, PAGE_SIZE);
+                pfn_array[j] = i;
+            }
+
+            j++;
+        }
+    }
+    if ( j != nr_pages )
+    {
+        PERROR("j (%ld) != nr_pages (%ld)", j , nr_pages);
+        /* When live dump-mode (-L option) is specified,
+         * guest domain may change its mapping.
+         */
+        nr_pages = j;
+    }
+
+    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] = ELFCLASS;
+    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;
+    ehdr.e_machine = ELF_ARCH_MACHINE;
+    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(Elf_Phdr);
+    ehdr.e_phnum = 0;
+    ehdr.e_shentsize = sizeof(Elf_Shdr);
+    /* ehdr.e_shnum and ehdr.e_shstrndx aren't known here yet. fill it later*/
+
+    /* create section header */
+    strtab = xc_core_strtab_init();
+    if ( strtab == NULL )
+    {
+        PERROR("Could not allocate string table");
+        goto out;
+    }
+    sheaders = xc_core_shdr_init();
+    if ( sheaders == NULL )
+    {
+        PERROR("Could not allocate section headers");
+        goto out;
+    }
+    /* null section */
+    shdr = xc_core_shdr_get(sheaders);
+    if ( shdr == NULL )
+    {
+        PERROR("Could not get section header for null section");
+        goto out;
+    }
+
+    /* .shstrtab */
+    shdr = xc_core_shdr_get(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(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(sheaders);
+    if ( shdr == NULL )
+    {
+        PERROR("Could not get section header for note section");
+        goto out;
+    }
+    sts = xc_core_shdr_set(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(sheaders);
+    if ( shdr == NULL )
+    {
+        PERROR("Could not get section header for .xen_prstatus");
+        goto out;
+    }
+    filesz = sizeof(ctxt[0]) * nr_vcpus;
+    sts = xc_core_shdr_set(shdr, strtab, XEN_DUMPCORE_SEC_PRSTATUS,
+                           SHT_PROGBITS, offset, filesz,
+                           __alignof__(ctxt[0]), sizeof(ctxt[0]));
+    if ( sts != 0 )
+        goto out;
+    offset += filesz;
+
+    /* arch context */
+    sts = xc_core_arch_context_get_shdr(&arch_ctxt, sheaders, strtab,
+                                        &filesz, offset);
+    if ( sts != 0)
+        goto out;
+    offset += filesz;
+
+    /* shared_info */
+    if ( live_shinfo != NULL )
+    {
+        shdr = xc_core_shdr_get(sheaders);
+        if ( shdr == NULL )
+        {
+            PERROR("Could not get section header for .xen_shared_info");
+            goto out;
+        }
+        filesz = PAGE_SIZE;
+        sts = xc_core_shdr_set(shdr, strtab, XEN_DUMPCORE_SEC_SHARED_INFO,
+                               SHT_PROGBITS, offset, filesz,
+                               __alignof__(*live_shinfo), PAGE_SIZE);
+        if ( sts != 0 )
+            goto out;
+        offset += filesz;
+    }
+
+    /* p2m/pfn table */
+    shdr = xc_core_shdr_get(sheaders);
+    if ( shdr == NULL )
+    {
+        PERROR("Could not get section header for .xen_{p2m, pfn} table");
+        goto out;
+    }
+    if ( !auto_translated_physmap )
+    {
+        filesz = nr_pages * sizeof(p2m_array[0]);
+        sts = xc_core_shdr_set(shdr, strtab, XEN_DUMPCORE_SEC_P2M,
+                               SHT_PROGBITS,
+                               offset, filesz, __alignof__(p2m_array[0]),
+                               sizeof(p2m_array[0]));
+        if ( sts != 0 )
+            goto out;
+    }
+    else
+    {
+        filesz = nr_pages * sizeof(pfn_array[0]);
+        sts = xc_core_shdr_set(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;
+
+    /* pages */
+    shdr = xc_core_shdr_get(sheaders);
+    if ( shdr == NULL )
+    {
+        PERROR("could not get section headers for .xen_pages");
+        goto out;
+    }
+
+    /*
+     * pages are the last section to allocate section headers
+     * so that we know the number of section headers here.
+     */
+    fixup = sheaders->num * 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;
+
+    filesz = nr_pages * PAGE_SIZE;
+    sts = xc_core_shdr_set(shdr, strtab, XEN_DUMPCORE_SEC_PAGES, SHT_PROGBITS,
+                           offset, filesz, PAGE_SIZE, PAGE_SIZE);
+    if ( sts != 0 )
+        goto out;
+    offset += filesz;
+
+    /* fixing up section header string table section header */
+    filesz = strtab->current;
+    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;
+    sts = dump_rtn(args, (char*)&ehdr, sizeof(ehdr));
+    if ( sts != 0 )
+        goto out;
+
+    /* section headers */
+    sts = dump_rtn(args, (char*)sheaders->shdrs,
+                   sheaders->num * sizeof(sheaders->shdrs[0]));
+    if ( sts != 0 )
+        goto out;
+
+    /* 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));
+
+    /* elf note section:xen core header */
+    elfnote.descsz = sizeof(none);
+    elfnote.type = XEN_ELFNOTE_DUMPCORE_NONE;
+    sts = dump_rtn(args, (char*)&elfnote, sizeof(elfnote));
+    if ( sts != 0 )
+        goto out;
+    sts = dump_rtn(args, (char*)&none, sizeof(none));
+    if ( sts != 0 )
+        goto out;
+
+    /* elf note section:xen core 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_ctxt_offset = sizeof(struct xc_core_header);
-    header.xch_index_offset = sizeof(struct xc_core_header) +
-        sizeof(vcpu_guest_context_t)*nr_vcpus;
-    dummy_len = (sizeof(struct xc_core_header) +
-                 (sizeof(vcpu_guest_context_t) * nr_vcpus) +
-                 (nr_pages * sizeof(*page_array)));
-    header.xch_pages_offset = round_pgup(dummy_len);
-
-    sts = dump_rtn(args, (char *)&header, sizeof(struct xc_core_header));
-    if ( sts != 0 )
-        goto error_out;
-
+    header.xch_page_size = PAGE_SIZE;
+    sts = dump_rtn(args, (char*)&elfnote, sizeof(elfnote));
+    if ( sts != 0 )
+        goto out;
+    sts = dump_rtn(args, (char*)&header, sizeof(header));
+    if ( sts != 0 )
+        goto out;
+
+    /* elf note section: xen version */
+    elfnote.descsz = sizeof(xen_version);
+    elfnote.type = XEN_ELFNOTE_DUMPCORE_XEN_VERSION;
+    elfnote_fill_xen_version(xc_handle, &xen_version);
+    sts = dump_rtn(args, (char*)&elfnote, sizeof(elfnote));
+    if ( sts != 0 )
+        goto out;
+    sts = dump_rtn(args, (char*)&xen_version, sizeof(xen_version));
+    if ( sts != 0 )
+        goto out;
+
+    /* elf note section: format version */
+    elfnote.descsz = sizeof(format_version);
+    elfnote.type = XEN_ELFNOTE_DUMPCORE_FORMAT_VERSION;
+    elfnote_fill_format_version(&format_version);
+    sts = dump_rtn(args, (char*)&elfnote, sizeof(elfnote));
+    if ( sts != 0 )
+        goto out;
+    sts = dump_rtn(args, (char*)&format_version, sizeof(format_version));
+    if ( sts != 0 )
+        goto out;
+
+    /* prstatus: .xen_prstatus */
     sts = dump_rtn(args, (char *)&ctxt, sizeof(ctxt[0]) * nr_vcpus);
     if ( sts != 0 )
-        goto error_out;
-
-    if ( (page_array = malloc(nr_pages * sizeof(*page_array))) == NULL )
-    {
-        IPRINTF("Could not allocate memory\n");
-        goto error_out;
-    }
-    if ( xc_get_pfn_list(xc_handle, domid, page_array, nr_pages) != nr_pages )
-    {
-        IPRINTF("Could not get the page frame list\n");
-        goto error_out;
-    }
-    sts = dump_rtn(args, (char *)page_array, nr_pages * sizeof(*page_array));
-    if ( sts != 0 )
-        goto error_out;
+        goto out;
+
+    if ( live_shinfo != NULL )
+    {
+        /* shared_info: .xen_shared_info */
+        sts = dump_rtn(args, (char*)live_shinfo, PAGE_SIZE);
+        if ( sts != 0 )
+            goto out;
+    }
+
+    /* arch specific context */
+    sts = xc_core_arch_context_dump(&arch_ctxt, args, dump_rtn);
+    if ( sts != 0 )
+        goto out;
+
+    /* p2m/pfn table: .xen_p2m/.xen_pfn */
+    if ( !auto_translated_physmap )
+        sts = dump_rtn(args, (char *)p2m_array,
+                       sizeof(p2m_array[0]) * nr_pages);
+    else
+        sts = dump_rtn(args, (char *)pfn_array,
+                       sizeof(pfn_array[0]) * nr_pages);
+    if ( sts != 0 )
+        goto out;
 
     /* Pad the output data to page alignment. */
     memset(dummy, 0, PAGE_SIZE);
-    sts = dump_rtn(args, dummy, header.xch_pages_offset - dummy_len);
-    if ( sts != 0 )
-        goto error_out;
-
+    sts = dump_rtn(args, dummy, dummy_len);
+    if ( sts != 0 )
+        goto out;
+
+    /* dump pages: .xen_pages */
     for ( dump_mem = dump_mem_start, i = 0; i < nr_pages; i++ )
     {
-        copy_from_domain_page(xc_handle, domid, page_array[i], dump_mem);
+        uint64_t gmfn;
+        if ( !auto_translated_physmap )
+            gmfn = p2m_array[i].gmfn;
+        else
+            gmfn = pfn_array[i];
+
+        copy_from_domain_page(xc_handle, domid, gmfn, dump_mem);
         dump_mem += PAGE_SIZE;
         if ( ((i + 1) % DUMP_INCREMENT == 0) || ((i + 1) == nr_pages) )
         {
             sts = dump_rtn(args, dump_mem_start, dump_mem - dump_mem_start);
             if ( sts != 0 )
-                goto error_out;
+                goto out;
             dump_mem = dump_mem_start;
         }
     }
 
-    free(dump_mem_start);
-    free(page_array);
-    return 0;
-
- error_out:
-    free(dump_mem_start);
-    free(page_array);
-    return -1;
+    /* elf section header string table: .shstrtab */
+    sts = dump_rtn(args, strtab->strings, strtab->current);
+    if ( sts != 0 )
+        goto out;
+
+    sts = 0;
+
+out:
+    if ( p2m != NULL )
+        munmap(p2m, PAGE_SIZE * P2M_FL_ENTRIES);
+    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 ( 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. */
diff -r f61992cb82fe -r 3dac99b6034e tools/libxc/xc_core.h
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/libxc/xc_core.h     Sat Feb 24 14:31:42 2007 +0000
@@ -0,0 +1,165 @@
+/*
+ * Copyright (c) 2006 Isaku Yamahata <yamahata at valinux co jp>
+ *                    VA Linux Systems Japan K.K.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *
+ */
+
+#ifndef XC_CORE_H
+#define XC_CORE_H
+
+#include "xen/version.h"
+#include "xg_private.h"
+#include "xen/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"
+
+#define XEN_DUMPCORE_SEC_IA64_MAPPED_REGS       ".xen_ia64_mapped_regs"
+
+/* elf note name */
+#define XEN_DUMPCORE_ELFNOTE_NAME               "Xen"
+/* note numbers are defined in xen/elfnote.h */
+
+struct xen_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 xen_elfnote                          elfnote;
+    struct xen_dumpcore_elfnote_none_desc       none;
+};
+
+struct xen_dumpcore_elfnote_header {
+    struct xen_elfnote                          elfnote;
+    struct xen_dumpcore_elfnote_header_desc     header;
+};
+
+struct xen_dumpcore_elfnote_xen_version {
+    struct xen_elfnote                                  elfnote;
+    struct xen_dumpcore_elfnote_xen_version_desc        xen_version;
+};
+
+struct xen_dumpcore_elfnote_format_version {
+    struct xen_elfnote                                  elfnote;
+    struct xen_dumpcore_elfnote_format_version_desc     format_version;
+};
+
+struct xen_dumpcore_p2m {
+    uint64_t    pfn;
+    uint64_t    gmfn;
+};
+
+
+struct xc_core_strtab;
+struct xc_core_section_headers;
+
+Elf_Shdr*
+xc_core_shdr_get(struct xc_core_section_headers *sheaders);
+int
+xc_core_shdr_set(Elf_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);
+int xc_core_arch_memory_map_get(int xc_handle, xc_dominfo_t *info,
+                                shared_info_t *live_shinfo,
+                                xc_core_memory_map_t **mapp,
+                                unsigned int *nr_entries);
+int xc_core_arch_map_p2m(int xc_handle, xc_dominfo_t *info,
+                         shared_info_t *live_shinfo, xen_pfn_t **live_p2m,
+                         unsigned long *pfnp);
+
+
+#if defined (__i386__) || defined (__x86_64__)
+# include "xc_core_x86.h"
+#elif defined (__ia64__)
+# include "xc_core_ia64.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-set-style: "BSD"
+ * c-basic-offset: 4
+ * tab-width: 4
+ * indent-tabs-mode: nil
+ * End:
+ */
diff -r f61992cb82fe -r 3dac99b6034e tools/libxc/xc_core_ia64.c
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/libxc/xc_core_ia64.c        Sat Feb 24 14:31:42 2007 +0000
@@ -0,0 +1,315 @@
+/*
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *
+ * Copyright (c) 2007 Isaku Yamahata <yamahata at valinux co jp>
+ *                    VA Linux Systems Japan K.K.
+ *
+ */
+
+#include "xg_private.h"
+#include "xc_core.h"
+#include "xc_efi.h"
+#include "xc_dom.h"
+
+int
+xc_core_arch_auto_translated_physmap(const xc_dominfo_t *info)
+{
+    /*
+     * on ia64, both paravirtualize domain and hvm domain are
+     * auto_translated_physmap mode
+     */
+    return 1;
+}
+
+/* see setup_guest() @ xc_linux_build.c */
+static int
+memory_map_get_old_domu(int xc_handle, xc_dominfo_t *info,
+                        shared_info_t *live_shinfo,
+                        xc_core_memory_map_t **mapp, unsigned int *nr_entries)
+{
+    xc_core_memory_map_t *map = NULL;
+
+    map = malloc(sizeof(*map));
+    if ( map == NULL )
+    {
+        PERROR("Could not allocate memory");
+        goto out;
+    }
+
+    map->addr = 0;
+    map->size = info->max_memkb * 1024;
+
+    *mapp = map;
+    *nr_entries = 1;
+    return 0;
+
+out:
+    if ( map != NULL )
+        free(map);
+    return -1;
+}
+
+/* see setup_guest() @ xc_ia64_hvm_build.c */
+static int
+memory_map_get_old_hvm(int xc_handle, xc_dominfo_t *info, 
+                       shared_info_t *live_shinfo,
+                       xc_core_memory_map_t **mapp, unsigned int *nr_entries)
+{
+    const xc_core_memory_map_t gfw_map[] = {
+        {IO_PAGE_START, IO_PAGE_SIZE},
+        {STORE_PAGE_START, STORE_PAGE_SIZE},
+        {BUFFER_IO_PAGE_START, BUFFER_IO_PAGE_SIZE},
+        {GFW_START, GFW_SIZE},
+    };
+    const unsigned int nr_gfw_map = sizeof(gfw_map)/sizeof(gfw_map[0]);
+    xc_core_memory_map_t *map = NULL;
+    unsigned int i;
+    
+#define VGA_IO_END      (VGA_IO_START + VGA_IO_SIZE)
+    /* [0, VGA_IO_START) [VGA_IO_END, 3GB), [4GB, ...) + gfw_map */
+    map = malloc((3 + nr_gfw_map) * sizeof(*map));
+    if ( map == NULL )
+    {
+        PERROR("Could not allocate memory");
+        goto out;
+    }
+
+    for ( i = 0; i < nr_gfw_map; i++ )
+        map[i] = gfw_map[i];
+    map[i].addr = 0;
+    map[i].size = info->max_memkb * 1024;
+    i++;
+    if ( map[i - 1].size < VGA_IO_END )
+    {
+        map[i - 1].size = VGA_IO_START;
+    }
+    else
+    {
+        map[i].addr = VGA_IO_END;
+        map[i].size = map[i - 1].size - VGA_IO_END;
+        map[i - 1].size = VGA_IO_START;
+        i++;
+        if ( map[i - 1].addr + map[i - 1].size > MMIO_START )
+        {
+            map[i].addr = MMIO_START + 1 * MEM_G;
+            map[i].size = map[i - 1].addr + map[i - 1].size - MMIO_START;
+            map[i - 1].size = MMIO_START - map[i - 1].addr;
+            i++;
+        }
+    }
+    *mapp = map;
+    *nr_entries = i;
+    return 0;
+
+out:
+    if ( map != NULL )
+        free(map);
+    return -1;
+}
+
+static int
+memory_map_get_old(int xc_handle, xc_dominfo_t *info, 
+                   shared_info_t *live_shinfo,
+                   xc_core_memory_map_t **mapp, unsigned int *nr_entries)
+{
+    if ( info->hvm )
+        return memory_map_get_old_hvm(xc_handle, info, live_shinfo,
+                                      mapp, nr_entries);
+    if ( live_shinfo == NULL )
+        return -1;
+    return memory_map_get_old_domu(xc_handle, info, live_shinfo,
+                                   mapp, nr_entries);
+}
+
+int
+xc_core_arch_memory_map_get(int xc_handle, xc_dominfo_t *info,
+                            shared_info_t *live_shinfo,
+                            xc_core_memory_map_t **mapp,
+                            unsigned int *nr_entries)
+{
+#ifdef notyet
+    int ret = -1;
+    xen_ia64_memmap_info_t *memmap_info;
+    xc_core_memory_map_t *map;
+    char *start;
+    char *end;
+    char *p;
+    efi_memory_desc_t *md;
+
+    if  ( live_shinfo == NULL || live_shinfo->arch.memmap_info_pfn == 0 )
+        goto old;
+
+    memmap_info = xc_map_foreign_range(xc_handle, info->domid,
+                                       PAGE_SIZE, PROT_READ,
+                                       live_shinfo->arch.memmap_info_pfn);
+    if ( memmap_info == NULL )
+    {
+        PERROR("Could not map memmap info.");
+        return -1;
+    }
+    if ( memmap_info->efi_memdesc_size != sizeof(*md) ||
+         (memmap_info->efi_memmap_size / memmap_info->efi_memdesc_size) == 0 ||
+         memmap_info->efi_memmap_size > PAGE_SIZE - sizeof(memmap_info) ||
+         memmap_info->efi_memdesc_version != EFI_MEMORY_DESCRIPTOR_VERSION )
+    {
+        PERROR("unknown memmap header. defaulting to compat mode.");
+        munmap(memmap_info, PAGE_SIZE);
+        goto old;
+    }
+
+    *nr_entries = memmap_info->efi_memmap_size / memmap_info->efi_memdesc_size;
+    map = malloc(*nr_entries * sizeof(*md));
+    if ( map == NULL )
+    {
+        PERROR("Could not allocate memory for memmap.");
+        goto out;
+    }
+    *mapp = map;
+
+    *nr_entries = 0;
+    start = (char*)&memmap_info->memdesc;
+    end = start + memmap_info->efi_memmap_size;
+    for ( p = start; p < end; p += memmap_info->efi_memdesc_size )
+    {
+        md = (efi_memory_desc_t*)p;
+        if ( md->type != EFI_CONVENTIONAL_MEMORY ||
+             md->attribute != EFI_MEMORY_WB ||
+             md->num_pages == 0 )
+            continue;
+
+        map[*nr_entries].addr = md->phys_addr;
+        map[*nr_entries].size = md->num_pages << EFI_PAGE_SHIFT;
+        (*nr_entries)++;
+    }
+    ret = 0;
+out:
+    munmap(memmap_info, PAGE_SIZE);
+    return ret;
+    
+old:
+#endif
+    return memory_map_get_old(xc_handle, info, live_shinfo, mapp, nr_entries);
+}
+
+int
+xc_core_arch_map_p2m(int xc_handle, xc_dominfo_t *info,
+                     shared_info_t *live_shinfo, xen_pfn_t **live_p2m,
+                     unsigned long *pfnp)
+{
+    /*
+     * on ia64, both paravirtualize domain and hvm domain are
+     * auto_translated_physmap mode
+     */
+    errno = ENOSYS;
+    return -1;
+}
+
+void
+xc_core_arch_context_init(struct xc_core_arch_context* arch_ctxt)
+{
+    int i;
+
+    arch_ctxt->mapped_regs_size =
+        (XMAPPEDREGS_SIZE < PAGE_SIZE) ? PAGE_SIZE: XMAPPEDREGS_SIZE;
+    arch_ctxt->nr_vcpus = 0;
+    for ( i = 0; i < MAX_VIRT_CPUS; i++ )
+        arch_ctxt->mapped_regs[i] = NULL;
+}
+
+void
+xc_core_arch_context_free(struct xc_core_arch_context* arch_ctxt)
+{
+    int i;
+    for ( i = 0; i < arch_ctxt->nr_vcpus; i++ )
+        if ( arch_ctxt->mapped_regs[i] != NULL )
+            munmap(arch_ctxt->mapped_regs[i], arch_ctxt->mapped_regs_size);
+}
+
+int
+xc_core_arch_context_get(struct xc_core_arch_context* arch_ctxt,
+                         vcpu_guest_context_t* ctxt,
+                         int xc_handle, uint32_t domid)
+{
+    mapped_regs_t* mapped_regs;
+    if ( ctxt->privregs_pfn == INVALID_P2M_ENTRY )
+    {
+        PERROR("Could not get mmapped privregs gmfn");
+        errno = ENOENT;
+        return -1;
+    }
+    mapped_regs = xc_map_foreign_range(xc_handle, domid,
+                                       arch_ctxt->mapped_regs_size,
+                                       PROT_READ, ctxt->privregs_pfn);
+    if ( mapped_regs == NULL )
+    {
+        PERROR("Could not map mapped privregs");
+        return -1;
+    }
+    arch_ctxt->mapped_regs[arch_ctxt->nr_vcpus] = mapped_regs;
+    arch_ctxt->nr_vcpus++;
+    return 0;
+}
+
+int
+xc_core_arch_context_get_shdr(struct xc_core_arch_context *arch_ctxt, 
+                              struct xc_core_section_headers *sheaders,
+                              struct xc_core_strtab *strtab,
+                              unsigned long *filesz, unsigned long offset)
+{
+    int sts = -1;
+    Elf_Shdr *shdr;
+
+    /* mmapped priv regs */
+    shdr = xc_core_shdr_get(sheaders);
+    if ( shdr == NULL )
+    {
+        PERROR("Could not get section header for .xen_ia64_mapped_regs");
+        return sts;
+    }
+    *filesz = arch_ctxt->mapped_regs_size * arch_ctxt->nr_vcpus;
+    sts = xc_core_shdr_set(shdr, strtab, XEN_DUMPCORE_SEC_IA64_MAPPED_REGS,
+                           SHT_PROGBITS, offset, *filesz,
+                           __alignof__(*arch_ctxt->mapped_regs[0]),
+                           arch_ctxt->mapped_regs_size);
+    return sts;
+}
+
+int
+xc_core_arch_context_dump(struct xc_core_arch_context* arch_ctxt,
+                          void* args, dumpcore_rtn_t dump_rtn)
+{
+    int sts = 0;
+    int i;
+    
+    /* ia64 mapped_regs: .xen_ia64_mapped_regs */
+    for ( i = 0; i < arch_ctxt->nr_vcpus; i++ )
+    {
+        sts = dump_rtn(args, (char*)arch_ctxt->mapped_regs[i],
+                       arch_ctxt->mapped_regs_size);
+        if ( sts != 0 )
+            break;
+    }
+    return sts;
+}
+
+/*
+ * Local variables:
+ * mode: C
+ * c-set-style: "BSD"
+ * c-basic-offset: 4
+ * tab-width: 4
+ * indent-tabs-mode: nil
+ * End:
+ */
diff -r f61992cb82fe -r 3dac99b6034e tools/libxc/xc_core_ia64.h
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/libxc/xc_core_ia64.h        Sat Feb 24 14:31:42 2007 +0000
@@ -0,0 +1,60 @@
+/*
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *
+ * Copyright (c) 2007 Isaku Yamahata <yamahata at valinux co jp>
+ *                    VA Linux Systems Japan K.K.
+ *
+ */
+
+#ifndef XC_CORE_IA64_H
+#define XC_CORE_IA64_H
+
+#define ELF_ARCH_DATA           ELFDATA2LSB
+#define ELF_ARCH_MACHINE        EM_IA_64
+
+struct xc_core_arch_context {
+    size_t mapped_regs_size;
+    int nr_vcpus;
+    mapped_regs_t* mapped_regs[MAX_VIRT_CPUS];
+};
+
+void
+xc_core_arch_context_init(struct xc_core_arch_context* arch_ctxt);
+void
+xc_core_arch_context_free(struct xc_core_arch_context* arch_ctxt);
+int
+xc_core_arch_context_get(struct xc_core_arch_context* arch_ctxt,
+                         vcpu_guest_context_t* ctxt,
+                         int xc_handle, uint32_t domid);
+int
+xc_core_arch_context_get_shdr(struct xc_core_arch_context* arch_ctxt, 
+                              struct xc_core_section_headers *sheaders,
+                              struct xc_core_strtab *strtab,
+                              unsigned long *filesz, unsigned long offset);
+int
+xc_core_arch_context_dump(struct xc_core_arch_context* arch_ctxt,
+                          void* args, dumpcore_rtn_t dump_rtn);
+
+#endif /* XC_CORE_IA64_H */
+
+/*
+ * Local variables:
+ * mode: C
+ * c-set-style: "BSD"
+ * c-basic-offset: 4
+ * tab-width: 4
+ * indent-tabs-mode: nil
+ * End:
+ */
diff -r f61992cb82fe -r 3dac99b6034e tools/libxc/xc_core_x86.c
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/libxc/xc_core_x86.c Sat Feb 24 14:31:42 2007 +0000
@@ -0,0 +1,136 @@
+/*
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *
+ * Copyright (c) 2007 Isaku Yamahata <yamahata at valinux co jp>
+ *                    VA Linux Systems Japan K.K.
+ *
+ */
+
+#include "xg_private.h"
+#include "xc_core.h"
+
+int
+xc_core_arch_auto_translated_physmap(const xc_dominfo_t *info)
+{
+    if ( info->hvm )
+        return 1;
+    return 0;
+}
+
+int
+xc_core_arch_memory_map_get(int xc_handle, xc_dominfo_t *info,
+                            shared_info_t *live_shinfo,
+                            xc_core_memory_map_t **mapp,
+                            unsigned int *nr_entries)
+{
+    unsigned long max_pfn = live_shinfo->arch.max_pfn;
+    xc_core_memory_map_t *map = NULL;
+
+    map = malloc(sizeof(*map));
+    if ( !map )
+    {
+        PERROR("Could not allocate memory");
+        goto out;
+    }
+
+    map->addr = 0;
+    map->size = max_pfn << PAGE_SHIFT;
+
+    *mapp = map;
+    *nr_entries = 1;
+    return 0;
+
+out:
+    if ( map )
+        free(map);
+    return -1;
+}
+
+int
+xc_core_arch_map_p2m(int xc_handle, xc_dominfo_t *info,
+                     shared_info_t *live_shinfo, xen_pfn_t **live_p2m,
+                     unsigned long *pfnp)
+{
+    /* Double and single indirect references to the live P2M table */
+    xen_pfn_t *live_p2m_frame_list_list = NULL;
+    xen_pfn_t *live_p2m_frame_list = NULL;
+    uint32_t dom = info->domid;
+    unsigned long max_pfn = live_shinfo->arch.max_pfn;
+    int ret = -1;
+    int err;
+
+    if ( max_pfn < info->nr_pages  )
+    {
+        ERROR("max_pfn < nr_pages -1 (%lx < %lx", max_pfn, info->nr_pages - 1);
+        goto out;
+    }
+
+    live_p2m_frame_list_list =
+        xc_map_foreign_range(xc_handle, dom, PAGE_SIZE, PROT_READ,
+                             live_shinfo->arch.pfn_to_mfn_frame_list_list);
+
+    if ( !live_p2m_frame_list_list )
+    {
+        PERROR("Couldn't map p2m_frame_list_list (errno %d)", errno);
+        goto out;
+    }
+
+    live_p2m_frame_list =
+        xc_map_foreign_batch(xc_handle, dom, PROT_READ,
+                             live_p2m_frame_list_list,
+                             P2M_FLL_ENTRIES);
+
+    if ( !live_p2m_frame_list )
+    {
+        PERROR("Couldn't map p2m_frame_list");
+        goto out;
+    }
+
+    *live_p2m = xc_map_foreign_batch(xc_handle, dom, PROT_READ,
+                                    live_p2m_frame_list,
+                                    P2M_FL_ENTRIES);
+
+    if ( !*live_p2m )
+    {
+        PERROR("Couldn't map p2m table");
+        goto out;
+    }
+
+    *pfnp = max_pfn;
+
+    ret = 0;
+
+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);
+
+    errno = err;
+    return ret;
+}
+
+/*
+ * Local variables:
+ * mode: C
+ * c-set-style: "BSD"
+ * c-basic-offset: 4
+ * tab-width: 4
+ * indent-tabs-mode: nil
+ * End:
+ */
diff -r f61992cb82fe -r 3dac99b6034e tools/libxc/xc_core_x86.h
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/libxc/xc_core_x86.h Sat Feb 24 14:31:42 2007 +0000
@@ -0,0 +1,64 @@
+/*
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *
+ * 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
+
+#if defined(__i386__) || defined(__x86_64__)
+#define ELF_ARCH_DATA           ELFDATA2LSB
+#if defined (__i386__)
+# define ELF_ARCH_MACHINE       EM_386
+#else
+# define ELF_ARCH_MACHINE       EM_X86_64
+#endif
+#endif /* __i386__ or __x86_64__ */
+
+
+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, xc_handle, domid) \
+                                                                (0)
+#define xc_core_arch_context_dump(arch_ctxt, args, dump_rtn)    (0)
+
+static inline int
+xc_core_arch_context_get_shdr(struct xc_core_arch_context *arch_ctxt, 
+                              struct xc_core_section_headers *sheaders,
+                              struct xc_core_strtab *strtab,
+                              unsigned long *filesz, unsigned long offset)
+{
+    *filesz = 0;
+    return 0;
+}
+
+#endif /* XC_CORE_X86_H */
+
+/*
+ * Local variables:
+ * mode: C
+ * c-set-style: "BSD"
+ * c-basic-offset: 4
+ * tab-width: 4
+ * indent-tabs-mode: nil
+ * End:
+ */
diff -r f61992cb82fe -r 3dac99b6034e tools/libxc/xc_efi.h
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/libxc/xc_efi.h      Sat Feb 24 14:31:42 2007 +0000
@@ -0,0 +1,68 @@
+#ifndef XC_EFI_H
+#define XC_EFI_H
+
+/* definitions from xen/include/asm-ia64/linux-xen/linux/efi.h */
+
+/*
+ * Extensible Firmware Interface
+ * Based on 'Extensible Firmware Interface Specification' version 0.9, April 
30, 1999
+ *
+ * Copyright (C) 1999 VA Linux Systems
+ * Copyright (C) 1999 Walt Drummond <drummond@xxxxxxxxxxx>
+ * Copyright (C) 1999, 2002-2003 Hewlett-Packard Co.
+ *     David Mosberger-Tang <davidm@xxxxxxxxxx>
+ *     Stephane Eranian <eranian@xxxxxxxxxx>
+ */
+
+/*
+ * Memory map descriptor:
+ */
+
+/* Memory types: */
+#define EFI_RESERVED_TYPE                0
+#define EFI_LOADER_CODE                  1
+#define EFI_LOADER_DATA                  2
+#define EFI_BOOT_SERVICES_CODE           3
+#define EFI_BOOT_SERVICES_DATA           4
+#define EFI_RUNTIME_SERVICES_CODE        5
+#define EFI_RUNTIME_SERVICES_DATA        6
+#define EFI_CONVENTIONAL_MEMORY          7
+#define EFI_UNUSABLE_MEMORY              8
+#define EFI_ACPI_RECLAIM_MEMORY          9
+#define EFI_ACPI_MEMORY_NVS             10
+#define EFI_MEMORY_MAPPED_IO            11
+#define EFI_MEMORY_MAPPED_IO_PORT_SPACE 12
+#define EFI_PAL_CODE                    13
+#define EFI_MAX_MEMORY_TYPE             14
+
+/* Attribute values: */
+#define EFI_MEMORY_UC           ((uint64_t)0x0000000000000001ULL)    /* 
uncached */
+#define EFI_MEMORY_WC           ((uint64_t)0x0000000000000002ULL)    /* 
write-coalescing */
+#define EFI_MEMORY_WT           ((uint64_t)0x0000000000000004ULL)    /* 
write-through */
+#define EFI_MEMORY_WB           ((uint64_t)0x0000000000000008ULL)    /* 
write-back */
+#define EFI_MEMORY_WP           ((uint64_t)0x0000000000001000ULL)    /* 
write-protect */
+#define EFI_MEMORY_RP           ((uint64_t)0x0000000000002000ULL)    /* 
read-protect */
+#define EFI_MEMORY_XP           ((uint64_t)0x0000000000004000ULL)    /* 
execute-protect */
+#define EFI_MEMORY_RUNTIME      ((uint64_t)0x8000000000000000ULL)    /* range 
requires runtime mapping */
+#define EFI_MEMORY_DESCRIPTOR_VERSION   1
+
+#define EFI_PAGE_SHIFT          12
+
+/*
+ * For current x86 implementations of EFI, there is
+ * additional padding in the mem descriptors.  This is not
+ * the case in ia64.  Need to have this fixed in the f/w.
+ */
+typedef struct {
+        uint32_t type;
+        uint32_t pad;
+        uint64_t phys_addr;
+        uint64_t virt_addr;
+        uint64_t num_pages;
+        uint64_t attribute;
+#if defined (__i386__)
+        uint64_t pad1;
+#endif
+} efi_memory_desc_t;
+
+#endif /* XC_EFI_H */
diff -r f61992cb82fe -r 3dac99b6034e tools/libxc/xenctrl.h
--- a/tools/libxc/xenctrl.h     Sat Feb 24 14:19:42 2007 +0000
+++ b/tools/libxc/xenctrl.h     Sat Feb 24 14:31:42 2007 +0000
@@ -570,6 +570,11 @@ unsigned long xc_translate_foreign_addre
 unsigned long xc_translate_foreign_address(int xc_handle, uint32_t dom,
                                            int vcpu, unsigned long long virt);
 
+
+/**
+ * DEPRECATED.  Avoid using this, as it does not correctly account for PFNs
+ * without a backing MFN.
+ */
 int xc_get_pfn_list(int xc_handle, uint32_t domid, uint64_t *pfn_buf,
                     unsigned long max_pfns);
 
diff -r f61992cb82fe -r 3dac99b6034e xen/include/public/elfnote.h
--- a/xen/include/public/elfnote.h      Sat Feb 24 14:19:42 2007 +0000
+++ b/xen/include/public/elfnote.h      Sat Feb 24 14:31:42 2007 +0000
@@ -175,6 +175,41 @@
  */
 #define XEN_ELFNOTE_CRASH_REGS 0x1000002
 
+
+/*
+ * xen dump-core none note.
+ * xm dump-core code will create one XEN_ELFNOTE_DUMPCORE_NONE
+ * in its dump file to indicate that the file is xen dump-core
+ * file. This note doesn't have any other information.
+ * See tools/libxc/xc_core.h for more information.
+ */
+#define XEN_ELFNOTE_DUMPCORE_NONE               0x2000000
+
+/*
+ * xen dump-core header note.
+ * xm dump-core code will create one XEN_ELFNOTE_DUMPCORE_HEADER
+ * in its dump file.
+ * See tools/libxc/xc_core.h for more information.
+ */
+#define XEN_ELFNOTE_DUMPCORE_HEADER             0x2000001
+
+/*
+ * xen dump-core xen version note.
+ * xm dump-core code will create one XEN_ELFNOTE_DUMPCORE_XEN_VERSION
+ * in its dump file. It contains the xen version obtained via the
+ * XENVER hypercall.
+ * See tools/libxc/xc_core.h for more information.
+ */
+#define XEN_ELFNOTE_DUMPCORE_XEN_VERSION        0x2000002
+
+/*
+ * xen dump-core format version note.
+ * xm dump-core code will create one XEN_ELFNOTE_DUMPCORE_FORMAT_VERSION
+ * in its dump file. It contains a format version identifier.
+ * See tools/libxc/xc_core.h for more information.
+ */
+#define XEN_ELFNOTE_DUMPCORE_FORMAT_VERSION     0x2000003
+
 #endif /* __XEN_PUBLIC_ELFNOTE_H__ */
 
 /*

_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog

<Prev in Thread] Current Thread [Next in Thread>
  • [Xen-changelog] [xen-unstable] Xen coredump format: ELF formatified with note section., Xen patchbot-unstable <=