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] [TOOLS] Allow tools to load kernels which

To: xen-changelog@xxxxxxxxxxxxxxxxxxx
Subject: [Xen-changelog] [xen-unstable] [TOOLS] Allow tools to load kernels which use an ELF notes segment.
From: Xen patchbot-unstable <patchbot-unstable@xxxxxxxxxxxxxxxxxxx>
Date: Wed, 23 Aug 2006 19:00:35 +0000
Delivery-date: Wed, 23 Aug 2006 12:00:59 -0700
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 Ian Campbell <ian.campbell@xxxxxxxxxxxxx>
# Node ID d57b174adfd63787198c7ba4ea64e957caf592d0
# Parent  7ca72a1c41827abbfe65b38d95d05be2f57c16a4
[TOOLS] Allow tools to load kernels which use an ELF notes segment.

Compatability with kernels using the __xen_guest section is retained.

Signed-off-by: Ian Campbell <ian.campbell@xxxxxxxxxxxxx>
---
 tools/libxc/xc_linux_build.c |   29 +--
 tools/libxc/xc_load_bin.c    |    2 
 tools/libxc/xc_load_elf.c    |  342 +++++++++++++++++++++++++++++++++++--------
 tools/libxc/xg_private.h     |   28 +++
 4 files changed, 322 insertions(+), 79 deletions(-)

diff -r 7ca72a1c4182 -r d57b174adfd6 tools/libxc/xc_linux_build.c
--- a/tools/libxc/xc_linux_build.c      Wed Aug 23 14:36:09 2006 +0100
+++ b/tools/libxc/xc_linux_build.c      Wed Aug 23 14:37:39 2006 +0100
@@ -655,11 +655,13 @@ static int setup_guest(int xc_handle,
                        uint32_t required_features[XENFEAT_NR_SUBMAPS])
 {
     xen_pfn_t *page_array = NULL;
-    unsigned long count, i, hypercall_pfn;
+    unsigned long count, i;
+    unsigned long long hypercall_page;
+    int hypercall_page_defined;
     start_info_t *start_info;
     shared_info_t *shared_info;
     xc_mmu_t *mmu = NULL;
-    char *p;
+    const char *p;
     DECLARE_DOM0_OP;
     int rc;
 
@@ -704,12 +706,9 @@ static int setup_guest(int xc_handle,
         goto error_out;
 
     /* Parse and validate kernel features. */
-    p = strstr(dsi.xen_guest_string, "FEATURES=");
-    if ( p != NULL )
-    {
-        if ( !parse_features(p + strlen("FEATURES="),
-                             supported_features,
-                             required_features) )
+    if ( (p = xen_elfnote_string(&dsi, XEN_ELFNOTE_FEATURES)) != NULL )
+    {
+        if ( !parse_features(p, supported_features, required_features) )
         {
             ERROR("Failed to parse guest kernel features.");
             goto error_out;
@@ -1071,16 +1070,16 @@ static int setup_guest(int xc_handle,
     if ( xc_finish_mmu_updates(xc_handle, mmu) )
         goto error_out;
 
-    p = strstr(dsi.xen_guest_string, "HYPERCALL_PAGE=");
-    if ( p != NULL )
-    {
-        p += strlen("HYPERCALL_PAGE=");
-        hypercall_pfn = strtoul(p, NULL, 16);
-        if ( hypercall_pfn >= nr_pages )
+    hypercall_page = xen_elfnote_numeric(&dsi, XEN_ELFNOTE_HYPERCALL_PAGE,
+                                         &hypercall_page_defined);
+    if ( hypercall_page_defined )
+    {
+        unsigned long long pfn = (hypercall_page - dsi.v_start) >> PAGE_SHIFT;
+        if ( pfn >= nr_pages )
             goto error_out;
         op.u.hypercall_init.domain = (domid_t)dom;
         op.u.hypercall_init.gmfn   = shadow_mode_enabled ?
-            hypercall_pfn : page_array[hypercall_pfn];
+            pfn : page_array[pfn];
         op.cmd = DOM0_HYPERCALL_INIT;
         if ( xc_dom0_op(xc_handle, &op) )
             goto error_out;
diff -r 7ca72a1c4182 -r d57b174adfd6 tools/libxc/xc_load_bin.c
--- a/tools/libxc/xc_load_bin.c Wed Aug 23 14:36:09 2006 +0100
+++ b/tools/libxc/xc_load_bin.c Wed Aug 23 14:37:39 2006 +0100
@@ -227,7 +227,7 @@ static int parsebinimage(const char *ima
     dsi->v_kernstart = dsi->v_start;
     dsi->v_kernend = dsi->v_end;
     dsi->v_kernentry = image_info->entry_addr;
-    dsi->xen_guest_string = "";
+    dsi->__xen_guest_string = "";
 
     return 0;
 }
diff -r 7ca72a1c4182 -r d57b174adfd6 tools/libxc/xc_load_elf.c
--- a/tools/libxc/xc_load_elf.c Wed Aug 23 14:36:09 2006 +0100
+++ b/tools/libxc/xc_load_elf.c Wed Aug 23 14:37:39 2006 +0100
@@ -5,6 +5,7 @@
 #include "xg_private.h"
 #include "xc_elf.h"
 #include <stdlib.h>
+#include <inttypes.h>
 
 #define round_pgup(_p)    (((_p)+(PAGE_SIZE-1))&PAGE_MASK)
 #define round_pgdown(_p)  ((_p)&PAGE_MASK)
@@ -65,17 +66,190 @@ static inline int is_loadable_phdr(Elf_P
             ((phdr->p_flags & (PF_W|PF_X)) != 0));
 }
 
+/*
+ * Fallback for kernels containing only the legacy __xen_guest string
+ * and no ELF notes.
+ */
+static int is_xen_guest_section(Elf_Shdr *shdr, const char *shstrtab)
+{
+    return strcmp(&shstrtab[shdr->sh_name], "__xen_guest") == 0;
+}
+
+static const char *xen_guest_lookup(struct domain_setup_info *dsi, int type)
+{
+    const char *xenguest_fallbacks[] = {
+        [XEN_ELFNOTE_ENTRY] = "VIRT_ENTRY=",
+        [XEN_ELFNOTE_HYPERCALL_PAGE] = "HYPERCALL_PAGE=",
+        [XEN_ELFNOTE_VIRT_BASE] = "VIRT_BASE=",
+        [XEN_ELFNOTE_PADDR_OFFSET] = "ELF_PADDR_OFFSET=",
+        [XEN_ELFNOTE_XEN_VERSION] = "XEN_VER=",
+        [XEN_ELFNOTE_GUEST_OS] = "GUEST_OS=",
+        [XEN_ELFNOTE_GUEST_VERSION] = "GUEST_VER=",
+        [XEN_ELFNOTE_LOADER] = "LOADER=",
+        [XEN_ELFNOTE_PAE_MODE] = "PAE=",
+        [XEN_ELFNOTE_FEATURES] = "FEATURES=",
+        [XEN_ELFNOTE_BSD_SYMTAB] = "BSD_SYMTAB=",
+    };
+    const char *fallback;
+    const char *p;
+
+    if ( type > sizeof(xenguest_fallbacks) )
+        return NULL;
+
+    if ( (fallback = xenguest_fallbacks[type]) == NULL )
+        return NULL;
+
+    if ( (p = strstr(dsi->__xen_guest_string,fallback)) == NULL )
+        return NULL;
+
+    return p + strlen(fallback);
+}
+
+static const char *xen_guest_string(struct domain_setup_info *dsi, int type)
+{
+    const char *p = xen_guest_lookup(dsi, type);
+
+    DPRINTF("found __xen_guest entry for type %#x = \"%s\"\n",
+            type, p);
+
+    /*
+     * We special case this since the __xen_guest_section treats the
+     * mere precense of the BSD_SYMTAB string as true or false.
+     */
+    if ( type == XEN_ELFNOTE_BSD_SYMTAB )
+        return p ? "yes" : "no";
+    return p;
+}
+
+static unsigned long long xen_guest_numeric(struct domain_setup_info *dsi,
+                                                   int type, int *defined)
+{
+    const char *p = xen_guest_lookup(dsi, type);
+    unsigned long long value;
+
+    if ( p == NULL )
+        return 0;
+
+    errno = 0;
+    value = strtoull(p, NULL, 0);
+    if ( errno < 0 )
+        return 0;
+
+    /* We special case this since __xen_guest_section contains a PFN
+     * for this field not a virtual address.
+     */
+    if (type == XEN_ELFNOTE_HYPERCALL_PAGE)
+        value = dsi->v_start + (value<<PAGE_SHIFT);
+
+    DPRINTF("found __xen_guest entry for type %#x = %#llx\n",
+            type, value);
+
+    *defined = 1;
+    return value;
+}
+
+/*
+ * Interface to the Xen ELF notes.
+ */
+#define ELFNOTE_NAME(_n_)   ((void*)(_n_) + sizeof(*(_n_)))
+#define ELFNOTE_DESC(_n_)   (ELFNOTE_NAME(_n_) + (((_n_)->namesz+3)&~3))
+#define ELFNOTE_NEXT(_n_)   (ELFNOTE_DESC(_n_) + (((_n_)->descsz+3)&~3))
+
+static int is_xen_elfnote_section(const char *image, Elf_Shdr *shdr)
+{
+    Elf_Note *note;
+
+    if ( shdr->sh_type != SHT_NOTE )
+        return 0;
+
+    for ( note = (Elf_Note *)(image + shdr->sh_offset);
+          note < (Elf_Note *)(image + shdr->sh_offset + shdr->sh_size);
+          note = ELFNOTE_NEXT(note) )
+    {
+        if ( !strncmp(ELFNOTE_NAME(note), "Xen", 4) )
+            return 1;
+    }
+
+    return 0;
+}
+
+static Elf_Note *xen_elfnote_lookup(struct domain_setup_info *dsi, int type)
+{
+    Elf_Note *note;
+
+    for ( note = (Elf_Note *)dsi->__elfnote_section;
+          note < (Elf_Note *)dsi->__elfnote_section_end;
+          note = ELFNOTE_NEXT(note) )
+    {
+        if ( strncmp(ELFNOTE_NAME(note), "Xen", 4) )
+            continue;
+
+        if ( note->type == type )
+            return note;
+    }
+
+    DPRINTF("unable to find Xen ELF note with type %#x\n", type);
+    return NULL;
+}
+
+const char *xen_elfnote_string(struct domain_setup_info *dsi, int type)
+{
+    Elf_Note *note;
+
+    if ( !dsi->__elfnote_section )
+        return xen_guest_string(dsi, type);
+
+    note = xen_elfnote_lookup(dsi, type);
+    if ( note == NULL )
+        return NULL;
+
+    DPRINTF("found Xen ELF note type %#x = \"%s\"\n",
+            type, (char *)ELFNOTE_DESC(note));
+
+    return (const char *)ELFNOTE_DESC(note);
+}
+
+unsigned long long xen_elfnote_numeric(struct domain_setup_info *dsi,
+                                       int type, int *defined)
+{
+    Elf_Note *note;
+
+    *defined = 0;
+
+    if ( !dsi->__elfnote_section )
+        return xen_guest_numeric(dsi, type, defined);
+
+    note = xen_elfnote_lookup(dsi, type);
+    if ( note == NULL )
+    {
+        return 0;
+    }
+
+    switch ( note->descsz )
+    {
+    case 4:
+        *defined = 1;
+        return *(uint32_t*)ELFNOTE_DESC(note);
+    case 8:
+        *defined = 1;
+        return *(uint64_t*)ELFNOTE_DESC(note);
+    default:
+        ERROR("elfnotes: unknown data size %#x for numeric type note %#x\n",
+              note->descsz, type);
+        return 0;
+    }
+}
+
 static int parseelfimage(const char *image,
-                         unsigned long elfsize,
+                         unsigned long image_len,
                          struct domain_setup_info *dsi)
 {
     Elf_Ehdr *ehdr = (Elf_Ehdr *)image;
     Elf_Phdr *phdr;
     Elf_Shdr *shdr;
-    Elf_Addr kernstart = ~0, kernend = 0, vaddr, virt_base, elf_pa_off;
-    const char *shstrtab;
-    char *guestinfo=NULL, *p;
-    int h, virt_base_defined, elf_pa_off_defined;
+    Elf_Addr kernstart = ~0, kernend = 0, vaddr, virt_entry;
+    const char *shstrtab, *p;
+    int h, virt_base_defined, elf_pa_off_defined, virt_entry_defined;
 
     if ( !IS_ELF(*ehdr) )
     {
@@ -92,13 +266,13 @@ static int parseelfimage(const char *ima
         return -EINVAL;
     }
 
-    if ( (ehdr->e_phoff + (ehdr->e_phnum * ehdr->e_phentsize)) > elfsize )
+    if ( (ehdr->e_phoff + (ehdr->e_phnum*ehdr->e_phentsize)) > image_len )
     {
         ERROR("ELF program headers extend beyond end of image.");
         return -EINVAL;
     }
 
-    if ( (ehdr->e_shoff + (ehdr->e_shnum * ehdr->e_shentsize)) > elfsize )
+    if ( (ehdr->e_shoff + (ehdr->e_shnum*ehdr->e_shentsize)) > image_len )
     {
         ERROR("ELF section headers extend beyond end of image.");
         return -EINVAL;
@@ -114,69 +288,119 @@ static int parseelfimage(const char *ima
                         (ehdr->e_shstrndx*ehdr->e_shentsize));
     shstrtab = image + shdr->sh_offset;
 
-    /* Find the special '__xen_guest' section and check its contents. */
+    dsi->__elfnote_section = NULL;
+    dsi->__xen_guest_string = NULL;
+
+    /* Look for .notes segment containing at least one Xen note */
     for ( h = 0; h < ehdr->e_shnum; h++ )
     {
         shdr = (Elf_Shdr *)(image + ehdr->e_shoff + (h*ehdr->e_shentsize));
-        if ( strcmp(&shstrtab[shdr->sh_name], "__xen_guest") != 0 )
+        if ( !is_xen_elfnote_section(image, shdr) )
             continue;
-
-        guestinfo = (char *)image + shdr->sh_offset;
-
-        if ( (strstr(guestinfo, "LOADER=generic") == NULL) &&
-             (strstr(guestinfo, "GUEST_OS=linux") == NULL) )
+        DPRINTF("found note section containing Xen entries\n");
+        dsi->__elfnote_section = (void *)image + shdr->sh_offset;
+        dsi->__elfnote_section_end =
+            (void *)image + shdr->sh_offset + shdr->sh_size;
+        break;
+    }
+
+    /* Fall back to looking for the special '__xen_guest' section. */
+    if ( dsi->__elfnote_section == NULL )
+    {
+        for ( h = 0; h < ehdr->e_shnum; h++ )
+        {
+            shdr = (Elf_Shdr *)(image + ehdr->e_shoff + (h*ehdr->e_shentsize));
+            if ( is_xen_guest_section(shdr, shstrtab) )
+            {
+                DPRINTF("found a legacy __xen_guest section\n");
+                dsi->__xen_guest_string = (char *)image + shdr->sh_offset;
+                break;
+            }
+        }
+    }
+
+    /* Check the contents of the Xen notes or guest string. */
+    if ( dsi->__elfnote_section || dsi->__xen_guest_string )
+    {
+        const char *loader = xen_elfnote_string(dsi, XEN_ELFNOTE_LOADER);
+        const char *guest_os = xen_elfnote_string(dsi, XEN_ELFNOTE_GUEST_OS);
+        const char *xen_version =
+            xen_elfnote_string(dsi, XEN_ELFNOTE_XEN_VERSION);
+
+        if ( ( loader == NULL || strncmp(loader, "generic", 7) ) &&
+             ( guest_os == NULL || strncmp(guest_os, "linux", 5) ) )
         {
             ERROR("Will only load images built for the generic loader "
                   "or Linux images");
-            ERROR("Actually saw: '%s'", guestinfo);
             return -EINVAL;
         }
 
-        if ( (strstr(guestinfo, "XEN_VER=xen-3.0") == NULL) )
+        if ( xen_version == NULL || strncmp(xen_version, "xen-3.0", 7) )
         {
             ERROR("Will only load images built for Xen v3.0");
-            ERROR("Actually saw: '%s'", guestinfo);
             return -EINVAL;
         }
-
-        dsi->pae_kernel = PAEKERN_no;
-        p = strstr(guestinfo, "PAE=yes");
-        if ( p != NULL )
+    }
+    else
+    {
+#ifdef __ia64__
+        dsi->__elfnote_section = NULL;
+        dsi->__xen_guest_string = "";
+#else
+        ERROR("Not a Xen-ELF image: "
+              "No ELF notes or '__xen_guest' section found.");
+        return -EINVAL;
+#endif
+    }
+
+    dsi->pae_kernel = PAEKERN_no;
+    if ( dsi->__elfnote_section )
+    {
+        p = xen_elfnote_string(dsi, XEN_ELFNOTE_PAE_MODE);
+        if ( p != NULL && strncmp(p, "yes", 3) == 0 )
+            dsi->pae_kernel = PAEKERN_extended_cr3;
+
+    }
+    else
+    {
+        p = xen_guest_lookup(dsi, XEN_ELFNOTE_PAE_MODE);
+        if ( p != NULL && strncmp(p, "yes", 3) == 0 )
         {
             dsi->pae_kernel = PAEKERN_yes;
-            if ( !strncmp(p+7, "[extended-cr3]", 14) )
+            if ( !strncmp(p+4, "[extended-cr3]", 14) )
                 dsi->pae_kernel = PAEKERN_extended_cr3;
         }
-
-        break;
-    }
-
-    if ( guestinfo == NULL )
-    {
-#ifdef __ia64__
-        guestinfo = "";
-#else
-        ERROR("Not a Xen-ELF image: '__xen_guest' section not found.");
-        return -EINVAL;
-#endif
-    }
-
-    dsi->xen_guest_string = guestinfo;
-
-    /* Initial guess for virt_base is 0 if it is not explicitly defined. */
-    p = strstr(guestinfo, "VIRT_BASE=");
-    virt_base_defined = (p != NULL);
-    virt_base = virt_base_defined ? strtoull(p+10, &p, 0) : 0;
-
-    /* Initial guess for elf_pa_off is virt_base if not explicitly defined. */
-    p = strstr(guestinfo, "ELF_PADDR_OFFSET=");
-    elf_pa_off_defined = (p != NULL);
-    elf_pa_off = elf_pa_off_defined ? strtoull(p+17, &p, 0) : virt_base;
+    }
+
+    /* Initial guess for v_start is 0 if it is not explicitly defined. */
+    dsi->v_start =
+        xen_elfnote_numeric(dsi, XEN_ELFNOTE_VIRT_BASE, &virt_base_defined);
+    if ( !virt_base_defined )
+        dsi->v_start = 0;
+
+    /*
+     * If we are using the legacy __xen_guest section then elf_pa_off
+     * defaults to v_start in order to maintain compatibility with
+     * older hypervisors which set padd in the ELF header to
+     * virt_base.
+     *
+     * If we are using the modern ELF notes interface then the default
+     * is 0.
+     */
+    dsi->elf_paddr_offset =
+        xen_elfnote_numeric(dsi, XEN_ELFNOTE_PADDR_OFFSET, 
&elf_pa_off_defined);
+    if ( !elf_pa_off_defined )
+    {
+        if ( dsi->__elfnote_section )
+            dsi->elf_paddr_offset = 0;
+        else
+            dsi->elf_paddr_offset = dsi->v_start;
+    }
 
     if ( elf_pa_off_defined && !virt_base_defined )
     {
-        ERROR("Neither ELF_PADDR_OFFSET nor VIRT_BASE found in __xen_guest"
-              " section.");
+        ERROR("Neither ELF_PADDR_OFFSET nor VIRT_BASE found in ELF "
+              " notes or __xen_guest section.");
         return -EINVAL;
     }
 
@@ -185,7 +409,7 @@ static int parseelfimage(const char *ima
         phdr = (Elf_Phdr *)(image + ehdr->e_phoff + (h*ehdr->e_phentsize));
         if ( !is_loadable_phdr(phdr) )
             continue;
-        vaddr = phdr->p_paddr - elf_pa_off + virt_base;
+        vaddr = phdr->p_paddr - dsi->elf_paddr_offset + dsi->v_start;
         if ( (vaddr + phdr->p_memsz) < vaddr )
         {
             ERROR("ELF program header %d is too large.", h);
@@ -198,17 +422,12 @@ static int parseelfimage(const char *ima
             kernend = vaddr + phdr->p_memsz;
     }
 
-    /*
-     * Legacy compatibility and images with no __xen_guest section: assume
-     * header addresses are virtual addresses, and that guest memory should be
-     * mapped starting at kernel load address.
-     */
-    dsi->v_start          = virt_base_defined  ? virt_base  : kernstart;
-    dsi->elf_paddr_offset = elf_pa_off_defined ? elf_pa_off : dsi->v_start;
-
     dsi->v_kernentry = ehdr->e_entry;
-    if ( (p = strstr(guestinfo, "VIRT_ENTRY=")) != NULL )
-        dsi->v_kernentry = strtoull(p+11, &p, 0);
+
+    virt_entry =
+        xen_elfnote_numeric(dsi, XEN_ELFNOTE_ENTRY, &virt_entry_defined);
+    if ( virt_entry_defined )
+        dsi->v_kernentry = virt_entry;
 
     if ( (kernstart > kernend) ||
          (dsi->v_kernentry < kernstart) ||
@@ -219,7 +438,8 @@ static int parseelfimage(const char *ima
         return -EINVAL;
     }
 
-    if ( (p = strstr(guestinfo, "BSD_SYMTAB")) != NULL )
+    p = xen_elfnote_string(dsi, XEN_ELFNOTE_BSD_SYMTAB);
+    if ( p != NULL && strncmp(p, "yes", 3) == 0 )
         dsi->load_symtab = 1;
 
     dsi->v_kernstart = kernstart;
diff -r 7ca72a1c4182 -r d57b174adfd6 tools/libxc/xg_private.h
--- a/tools/libxc/xg_private.h  Wed Aug 23 14:36:09 2006 +0100
+++ b/tools/libxc/xg_private.h  Wed Aug 23 14:37:39 2006 +0100
@@ -5,6 +5,7 @@
 #include <errno.h>
 #include <fcntl.h>
 #include <stdio.h>
+#include <stdlib.h>
 #include <string.h>
 #include <sys/mman.h>
 #include <sys/types.h>
@@ -16,6 +17,7 @@
 
 #include <xen/sys/privcmd.h>
 #include <xen/memory.h>
+#include <xen/elfnote.h>
 
 /* valgrind cannot see when a hypercall has filled in some values.  For this
    reason, we must zero the dom0_op_t instance before a call, if using
@@ -149,8 +151,15 @@ struct domain_setup_info
     unsigned long symtab_addr;
     unsigned long symtab_len;
 
-    /* __xen_guest info string for convenient loader parsing. */
-    char *xen_guest_string;
+    /*
+     * Only one of __elfnote_* or __xen_guest_string will be
+     * non-NULL.
+     *
+     * You should use the xen_elfnote_* accessors below in order to
+     * pickup the correct one and retain backwards compatibility.
+     */
+    void *__elfnote_section, *__elfnote_section_end;
+    char *__xen_guest_string;
 };
 
 typedef int (*parseimagefunc)(const char *image, unsigned long image_size,
@@ -159,6 +168,21 @@ typedef int (*loadimagefunc)(const char 
                              int xch,
                              uint32_t dom, xen_pfn_t *parray,
                              struct domain_setup_info *dsi);
+
+/*
+ * If an ELF note of the given type is found then the value contained
+ * in the note is returned and *defined is set to non-zero. If no such
+ * note is found then *defined is set to 0 and 0 is returned.
+ */
+extern unsigned long long xen_elfnote_numeric(struct domain_setup_info *dsi,
+                                             int type, int *defined);
+
+/*
+ * If an ELF note of the given type is found then the string contained
+ * in the value is returned, otherwise NULL is returned.
+ */
+extern const char * xen_elfnote_string(struct domain_setup_info *dsi,
+                                      int type);
 
 struct load_funcs
 {

_______________________________________________
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] [TOOLS] Allow tools to load kernels which use an ELF notes segment., Xen patchbot-unstable <=