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

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



# 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


 


Rackspace

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