direct-io.hg

changeset 11237:d57b174adfd6

[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@xensource.com>
author Ian Campbell <ian.campbell@xensource.com>
date Wed Aug 23 14:37:39 2006 +0100 (2006-08-23)
parents 7ca72a1c4182
children faadbf5ba8d6
files tools/libxc/xc_linux_build.c tools/libxc/xc_load_bin.c tools/libxc/xc_load_elf.c tools/libxc/xg_private.h
line diff
     1.1 --- a/tools/libxc/xc_linux_build.c	Wed Aug 23 14:36:09 2006 +0100
     1.2 +++ b/tools/libxc/xc_linux_build.c	Wed Aug 23 14:37:39 2006 +0100
     1.3 @@ -655,11 +655,13 @@ static int setup_guest(int xc_handle,
     1.4                         uint32_t required_features[XENFEAT_NR_SUBMAPS])
     1.5  {
     1.6      xen_pfn_t *page_array = NULL;
     1.7 -    unsigned long count, i, hypercall_pfn;
     1.8 +    unsigned long count, i;
     1.9 +    unsigned long long hypercall_page;
    1.10 +    int hypercall_page_defined;
    1.11      start_info_t *start_info;
    1.12      shared_info_t *shared_info;
    1.13      xc_mmu_t *mmu = NULL;
    1.14 -    char *p;
    1.15 +    const char *p;
    1.16      DECLARE_DOM0_OP;
    1.17      int rc;
    1.18  
    1.19 @@ -704,12 +706,9 @@ static int setup_guest(int xc_handle,
    1.20          goto error_out;
    1.21  
    1.22      /* Parse and validate kernel features. */
    1.23 -    p = strstr(dsi.xen_guest_string, "FEATURES=");
    1.24 -    if ( p != NULL )
    1.25 +    if ( (p = xen_elfnote_string(&dsi, XEN_ELFNOTE_FEATURES)) != NULL )
    1.26      {
    1.27 -        if ( !parse_features(p + strlen("FEATURES="),
    1.28 -                             supported_features,
    1.29 -                             required_features) )
    1.30 +        if ( !parse_features(p, supported_features, required_features) )
    1.31          {
    1.32              ERROR("Failed to parse guest kernel features.");
    1.33              goto error_out;
    1.34 @@ -1071,16 +1070,16 @@ static int setup_guest(int xc_handle,
    1.35      if ( xc_finish_mmu_updates(xc_handle, mmu) )
    1.36          goto error_out;
    1.37  
    1.38 -    p = strstr(dsi.xen_guest_string, "HYPERCALL_PAGE=");
    1.39 -    if ( p != NULL )
    1.40 +    hypercall_page = xen_elfnote_numeric(&dsi, XEN_ELFNOTE_HYPERCALL_PAGE,
    1.41 +                                         &hypercall_page_defined);
    1.42 +    if ( hypercall_page_defined )
    1.43      {
    1.44 -        p += strlen("HYPERCALL_PAGE=");
    1.45 -        hypercall_pfn = strtoul(p, NULL, 16);
    1.46 -        if ( hypercall_pfn >= nr_pages )
    1.47 +        unsigned long long pfn = (hypercall_page - dsi.v_start) >> PAGE_SHIFT;
    1.48 +        if ( pfn >= nr_pages )
    1.49              goto error_out;
    1.50          op.u.hypercall_init.domain = (domid_t)dom;
    1.51          op.u.hypercall_init.gmfn   = shadow_mode_enabled ?
    1.52 -            hypercall_pfn : page_array[hypercall_pfn];
    1.53 +            pfn : page_array[pfn];
    1.54          op.cmd = DOM0_HYPERCALL_INIT;
    1.55          if ( xc_dom0_op(xc_handle, &op) )
    1.56              goto error_out;
     2.1 --- a/tools/libxc/xc_load_bin.c	Wed Aug 23 14:36:09 2006 +0100
     2.2 +++ b/tools/libxc/xc_load_bin.c	Wed Aug 23 14:37:39 2006 +0100
     2.3 @@ -227,7 +227,7 @@ static int parsebinimage(const char *ima
     2.4      dsi->v_kernstart = dsi->v_start;
     2.5      dsi->v_kernend = dsi->v_end;
     2.6      dsi->v_kernentry = image_info->entry_addr;
     2.7 -    dsi->xen_guest_string = "";
     2.8 +    dsi->__xen_guest_string = "";
     2.9  
    2.10      return 0;
    2.11  }
     3.1 --- a/tools/libxc/xc_load_elf.c	Wed Aug 23 14:36:09 2006 +0100
     3.2 +++ b/tools/libxc/xc_load_elf.c	Wed Aug 23 14:37:39 2006 +0100
     3.3 @@ -5,6 +5,7 @@
     3.4  #include "xg_private.h"
     3.5  #include "xc_elf.h"
     3.6  #include <stdlib.h>
     3.7 +#include <inttypes.h>
     3.8  
     3.9  #define round_pgup(_p)    (((_p)+(PAGE_SIZE-1))&PAGE_MASK)
    3.10  #define round_pgdown(_p)  ((_p)&PAGE_MASK)
    3.11 @@ -65,17 +66,190 @@ static inline int is_loadable_phdr(Elf_P
    3.12              ((phdr->p_flags & (PF_W|PF_X)) != 0));
    3.13  }
    3.14  
    3.15 +/*
    3.16 + * Fallback for kernels containing only the legacy __xen_guest string
    3.17 + * and no ELF notes.
    3.18 + */
    3.19 +static int is_xen_guest_section(Elf_Shdr *shdr, const char *shstrtab)
    3.20 +{
    3.21 +    return strcmp(&shstrtab[shdr->sh_name], "__xen_guest") == 0;
    3.22 +}
    3.23 +
    3.24 +static const char *xen_guest_lookup(struct domain_setup_info *dsi, int type)
    3.25 +{
    3.26 +    const char *xenguest_fallbacks[] = {
    3.27 +        [XEN_ELFNOTE_ENTRY] = "VIRT_ENTRY=",
    3.28 +        [XEN_ELFNOTE_HYPERCALL_PAGE] = "HYPERCALL_PAGE=",
    3.29 +        [XEN_ELFNOTE_VIRT_BASE] = "VIRT_BASE=",
    3.30 +        [XEN_ELFNOTE_PADDR_OFFSET] = "ELF_PADDR_OFFSET=",
    3.31 +        [XEN_ELFNOTE_XEN_VERSION] = "XEN_VER=",
    3.32 +        [XEN_ELFNOTE_GUEST_OS] = "GUEST_OS=",
    3.33 +        [XEN_ELFNOTE_GUEST_VERSION] = "GUEST_VER=",
    3.34 +        [XEN_ELFNOTE_LOADER] = "LOADER=",
    3.35 +        [XEN_ELFNOTE_PAE_MODE] = "PAE=",
    3.36 +        [XEN_ELFNOTE_FEATURES] = "FEATURES=",
    3.37 +        [XEN_ELFNOTE_BSD_SYMTAB] = "BSD_SYMTAB=",
    3.38 +    };
    3.39 +    const char *fallback;
    3.40 +    const char *p;
    3.41 +
    3.42 +    if ( type > sizeof(xenguest_fallbacks) )
    3.43 +        return NULL;
    3.44 +
    3.45 +    if ( (fallback = xenguest_fallbacks[type]) == NULL )
    3.46 +        return NULL;
    3.47 +
    3.48 +    if ( (p = strstr(dsi->__xen_guest_string,fallback)) == NULL )
    3.49 +        return NULL;
    3.50 +
    3.51 +    return p + strlen(fallback);
    3.52 +}
    3.53 +
    3.54 +static const char *xen_guest_string(struct domain_setup_info *dsi, int type)
    3.55 +{
    3.56 +    const char *p = xen_guest_lookup(dsi, type);
    3.57 +
    3.58 +    DPRINTF("found __xen_guest entry for type %#x = \"%s\"\n",
    3.59 +            type, p);
    3.60 +
    3.61 +    /*
    3.62 +     * We special case this since the __xen_guest_section treats the
    3.63 +     * mere precense of the BSD_SYMTAB string as true or false.
    3.64 +     */
    3.65 +    if ( type == XEN_ELFNOTE_BSD_SYMTAB )
    3.66 +        return p ? "yes" : "no";
    3.67 +    return p;
    3.68 +}
    3.69 +
    3.70 +static unsigned long long xen_guest_numeric(struct domain_setup_info *dsi,
    3.71 +                                                   int type, int *defined)
    3.72 +{
    3.73 +    const char *p = xen_guest_lookup(dsi, type);
    3.74 +    unsigned long long value;
    3.75 +
    3.76 +    if ( p == NULL )
    3.77 +        return 0;
    3.78 +
    3.79 +    errno = 0;
    3.80 +    value = strtoull(p, NULL, 0);
    3.81 +    if ( errno < 0 )
    3.82 +        return 0;
    3.83 +
    3.84 +    /* We special case this since __xen_guest_section contains a PFN
    3.85 +     * for this field not a virtual address.
    3.86 +     */
    3.87 +    if (type == XEN_ELFNOTE_HYPERCALL_PAGE)
    3.88 +        value = dsi->v_start + (value<<PAGE_SHIFT);
    3.89 +
    3.90 +    DPRINTF("found __xen_guest entry for type %#x = %#llx\n",
    3.91 +            type, value);
    3.92 +
    3.93 +    *defined = 1;
    3.94 +    return value;
    3.95 +}
    3.96 +
    3.97 +/*
    3.98 + * Interface to the Xen ELF notes.
    3.99 + */
   3.100 +#define ELFNOTE_NAME(_n_)   ((void*)(_n_) + sizeof(*(_n_)))
   3.101 +#define ELFNOTE_DESC(_n_)   (ELFNOTE_NAME(_n_) + (((_n_)->namesz+3)&~3))
   3.102 +#define ELFNOTE_NEXT(_n_)   (ELFNOTE_DESC(_n_) + (((_n_)->descsz+3)&~3))
   3.103 +
   3.104 +static int is_xen_elfnote_section(const char *image, Elf_Shdr *shdr)
   3.105 +{
   3.106 +    Elf_Note *note;
   3.107 +
   3.108 +    if ( shdr->sh_type != SHT_NOTE )
   3.109 +        return 0;
   3.110 +
   3.111 +    for ( note = (Elf_Note *)(image + shdr->sh_offset);
   3.112 +          note < (Elf_Note *)(image + shdr->sh_offset + shdr->sh_size);
   3.113 +          note = ELFNOTE_NEXT(note) )
   3.114 +    {
   3.115 +        if ( !strncmp(ELFNOTE_NAME(note), "Xen", 4) )
   3.116 +            return 1;
   3.117 +    }
   3.118 +
   3.119 +    return 0;
   3.120 +}
   3.121 +
   3.122 +static Elf_Note *xen_elfnote_lookup(struct domain_setup_info *dsi, int type)
   3.123 +{
   3.124 +    Elf_Note *note;
   3.125 +
   3.126 +    for ( note = (Elf_Note *)dsi->__elfnote_section;
   3.127 +          note < (Elf_Note *)dsi->__elfnote_section_end;
   3.128 +          note = ELFNOTE_NEXT(note) )
   3.129 +    {
   3.130 +        if ( strncmp(ELFNOTE_NAME(note), "Xen", 4) )
   3.131 +            continue;
   3.132 +
   3.133 +        if ( note->type == type )
   3.134 +            return note;
   3.135 +    }
   3.136 +
   3.137 +    DPRINTF("unable to find Xen ELF note with type %#x\n", type);
   3.138 +    return NULL;
   3.139 +}
   3.140 +
   3.141 +const char *xen_elfnote_string(struct domain_setup_info *dsi, int type)
   3.142 +{
   3.143 +    Elf_Note *note;
   3.144 +
   3.145 +    if ( !dsi->__elfnote_section )
   3.146 +        return xen_guest_string(dsi, type);
   3.147 +
   3.148 +    note = xen_elfnote_lookup(dsi, type);
   3.149 +    if ( note == NULL )
   3.150 +        return NULL;
   3.151 +
   3.152 +    DPRINTF("found Xen ELF note type %#x = \"%s\"\n",
   3.153 +            type, (char *)ELFNOTE_DESC(note));
   3.154 +
   3.155 +    return (const char *)ELFNOTE_DESC(note);
   3.156 +}
   3.157 +
   3.158 +unsigned long long xen_elfnote_numeric(struct domain_setup_info *dsi,
   3.159 +                                       int type, int *defined)
   3.160 +{
   3.161 +    Elf_Note *note;
   3.162 +
   3.163 +    *defined = 0;
   3.164 +
   3.165 +    if ( !dsi->__elfnote_section )
   3.166 +        return xen_guest_numeric(dsi, type, defined);
   3.167 +
   3.168 +    note = xen_elfnote_lookup(dsi, type);
   3.169 +    if ( note == NULL )
   3.170 +    {
   3.171 +        return 0;
   3.172 +    }
   3.173 +
   3.174 +    switch ( note->descsz )
   3.175 +    {
   3.176 +    case 4:
   3.177 +        *defined = 1;
   3.178 +        return *(uint32_t*)ELFNOTE_DESC(note);
   3.179 +    case 8:
   3.180 +        *defined = 1;
   3.181 +        return *(uint64_t*)ELFNOTE_DESC(note);
   3.182 +    default:
   3.183 +        ERROR("elfnotes: unknown data size %#x for numeric type note %#x\n",
   3.184 +              note->descsz, type);
   3.185 +        return 0;
   3.186 +    }
   3.187 +}
   3.188 +
   3.189  static int parseelfimage(const char *image,
   3.190 -                         unsigned long elfsize,
   3.191 +                         unsigned long image_len,
   3.192                           struct domain_setup_info *dsi)
   3.193  {
   3.194      Elf_Ehdr *ehdr = (Elf_Ehdr *)image;
   3.195      Elf_Phdr *phdr;
   3.196      Elf_Shdr *shdr;
   3.197 -    Elf_Addr kernstart = ~0, kernend = 0, vaddr, virt_base, elf_pa_off;
   3.198 -    const char *shstrtab;
   3.199 -    char *guestinfo=NULL, *p;
   3.200 -    int h, virt_base_defined, elf_pa_off_defined;
   3.201 +    Elf_Addr kernstart = ~0, kernend = 0, vaddr, virt_entry;
   3.202 +    const char *shstrtab, *p;
   3.203 +    int h, virt_base_defined, elf_pa_off_defined, virt_entry_defined;
   3.204  
   3.205      if ( !IS_ELF(*ehdr) )
   3.206      {
   3.207 @@ -92,13 +266,13 @@ static int parseelfimage(const char *ima
   3.208          return -EINVAL;
   3.209      }
   3.210  
   3.211 -    if ( (ehdr->e_phoff + (ehdr->e_phnum * ehdr->e_phentsize)) > elfsize )
   3.212 +    if ( (ehdr->e_phoff + (ehdr->e_phnum*ehdr->e_phentsize)) > image_len )
   3.213      {
   3.214          ERROR("ELF program headers extend beyond end of image.");
   3.215          return -EINVAL;
   3.216      }
   3.217  
   3.218 -    if ( (ehdr->e_shoff + (ehdr->e_shnum * ehdr->e_shentsize)) > elfsize )
   3.219 +    if ( (ehdr->e_shoff + (ehdr->e_shnum*ehdr->e_shentsize)) > image_len )
   3.220      {
   3.221          ERROR("ELF section headers extend beyond end of image.");
   3.222          return -EINVAL;
   3.223 @@ -114,69 +288,119 @@ static int parseelfimage(const char *ima
   3.224                          (ehdr->e_shstrndx*ehdr->e_shentsize));
   3.225      shstrtab = image + shdr->sh_offset;
   3.226  
   3.227 -    /* Find the special '__xen_guest' section and check its contents. */
   3.228 +    dsi->__elfnote_section = NULL;
   3.229 +    dsi->__xen_guest_string = NULL;
   3.230 +
   3.231 +    /* Look for .notes segment containing at least one Xen note */
   3.232      for ( h = 0; h < ehdr->e_shnum; h++ )
   3.233      {
   3.234          shdr = (Elf_Shdr *)(image + ehdr->e_shoff + (h*ehdr->e_shentsize));
   3.235 -        if ( strcmp(&shstrtab[shdr->sh_name], "__xen_guest") != 0 )
   3.236 +        if ( !is_xen_elfnote_section(image, shdr) )
   3.237              continue;
   3.238 +        DPRINTF("found note section containing Xen entries\n");
   3.239 +        dsi->__elfnote_section = (void *)image + shdr->sh_offset;
   3.240 +        dsi->__elfnote_section_end =
   3.241 +            (void *)image + shdr->sh_offset + shdr->sh_size;
   3.242 +        break;
   3.243 +    }
   3.244  
   3.245 -        guestinfo = (char *)image + shdr->sh_offset;
   3.246 +    /* Fall back to looking for the special '__xen_guest' section. */
   3.247 +    if ( dsi->__elfnote_section == NULL )
   3.248 +    {
   3.249 +        for ( h = 0; h < ehdr->e_shnum; h++ )
   3.250 +        {
   3.251 +            shdr = (Elf_Shdr *)(image + ehdr->e_shoff + (h*ehdr->e_shentsize));
   3.252 +            if ( is_xen_guest_section(shdr, shstrtab) )
   3.253 +            {
   3.254 +                DPRINTF("found a legacy __xen_guest section\n");
   3.255 +                dsi->__xen_guest_string = (char *)image + shdr->sh_offset;
   3.256 +                break;
   3.257 +            }
   3.258 +        }
   3.259 +    }
   3.260  
   3.261 -        if ( (strstr(guestinfo, "LOADER=generic") == NULL) &&
   3.262 -             (strstr(guestinfo, "GUEST_OS=linux") == NULL) )
   3.263 +    /* Check the contents of the Xen notes or guest string. */
   3.264 +    if ( dsi->__elfnote_section || dsi->__xen_guest_string )
   3.265 +    {
   3.266 +        const char *loader = xen_elfnote_string(dsi, XEN_ELFNOTE_LOADER);
   3.267 +        const char *guest_os = xen_elfnote_string(dsi, XEN_ELFNOTE_GUEST_OS);
   3.268 +        const char *xen_version =
   3.269 +            xen_elfnote_string(dsi, XEN_ELFNOTE_XEN_VERSION);
   3.270 +
   3.271 +        if ( ( loader == NULL || strncmp(loader, "generic", 7) ) &&
   3.272 +             ( guest_os == NULL || strncmp(guest_os, "linux", 5) ) )
   3.273          {
   3.274              ERROR("Will only load images built for the generic loader "
   3.275                    "or Linux images");
   3.276 -            ERROR("Actually saw: '%s'", guestinfo);
   3.277              return -EINVAL;
   3.278          }
   3.279  
   3.280 -        if ( (strstr(guestinfo, "XEN_VER=xen-3.0") == NULL) )
   3.281 +        if ( xen_version == NULL || strncmp(xen_version, "xen-3.0", 7) )
   3.282          {
   3.283              ERROR("Will only load images built for Xen v3.0");
   3.284 -            ERROR("Actually saw: '%s'", guestinfo);
   3.285              return -EINVAL;
   3.286          }
   3.287 -
   3.288 -        dsi->pae_kernel = PAEKERN_no;
   3.289 -        p = strstr(guestinfo, "PAE=yes");
   3.290 -        if ( p != NULL )
   3.291 -        {
   3.292 -            dsi->pae_kernel = PAEKERN_yes;
   3.293 -            if ( !strncmp(p+7, "[extended-cr3]", 14) )
   3.294 -                dsi->pae_kernel = PAEKERN_extended_cr3;
   3.295 -        }
   3.296 -
   3.297 -        break;
   3.298      }
   3.299 -
   3.300 -    if ( guestinfo == NULL )
   3.301 +    else
   3.302      {
   3.303  #ifdef __ia64__
   3.304 -        guestinfo = "";
   3.305 +        dsi->__elfnote_section = NULL;
   3.306 +        dsi->__xen_guest_string = "";
   3.307  #else
   3.308 -        ERROR("Not a Xen-ELF image: '__xen_guest' section not found.");
   3.309 +        ERROR("Not a Xen-ELF image: "
   3.310 +              "No ELF notes or '__xen_guest' section found.");
   3.311          return -EINVAL;
   3.312  #endif
   3.313      }
   3.314  
   3.315 -    dsi->xen_guest_string = guestinfo;
   3.316 +    dsi->pae_kernel = PAEKERN_no;
   3.317 +    if ( dsi->__elfnote_section )
   3.318 +    {
   3.319 +        p = xen_elfnote_string(dsi, XEN_ELFNOTE_PAE_MODE);
   3.320 +        if ( p != NULL && strncmp(p, "yes", 3) == 0 )
   3.321 +            dsi->pae_kernel = PAEKERN_extended_cr3;
   3.322 +
   3.323 +    }
   3.324 +    else
   3.325 +    {
   3.326 +        p = xen_guest_lookup(dsi, XEN_ELFNOTE_PAE_MODE);
   3.327 +        if ( p != NULL && strncmp(p, "yes", 3) == 0 )
   3.328 +        {
   3.329 +            dsi->pae_kernel = PAEKERN_yes;
   3.330 +            if ( !strncmp(p+4, "[extended-cr3]", 14) )
   3.331 +                dsi->pae_kernel = PAEKERN_extended_cr3;
   3.332 +        }
   3.333 +    }
   3.334  
   3.335 -    /* Initial guess for virt_base is 0 if it is not explicitly defined. */
   3.336 -    p = strstr(guestinfo, "VIRT_BASE=");
   3.337 -    virt_base_defined = (p != NULL);
   3.338 -    virt_base = virt_base_defined ? strtoull(p+10, &p, 0) : 0;
   3.339 +    /* Initial guess for v_start is 0 if it is not explicitly defined. */
   3.340 +    dsi->v_start =
   3.341 +        xen_elfnote_numeric(dsi, XEN_ELFNOTE_VIRT_BASE, &virt_base_defined);
   3.342 +    if ( !virt_base_defined )
   3.343 +        dsi->v_start = 0;
   3.344  
   3.345 -    /* Initial guess for elf_pa_off is virt_base if not explicitly defined. */
   3.346 -    p = strstr(guestinfo, "ELF_PADDR_OFFSET=");
   3.347 -    elf_pa_off_defined = (p != NULL);
   3.348 -    elf_pa_off = elf_pa_off_defined ? strtoull(p+17, &p, 0) : virt_base;
   3.349 +    /*
   3.350 +     * If we are using the legacy __xen_guest section then elf_pa_off
   3.351 +     * defaults to v_start in order to maintain compatibility with
   3.352 +     * older hypervisors which set padd in the ELF header to
   3.353 +     * virt_base.
   3.354 +     *
   3.355 +     * If we are using the modern ELF notes interface then the default
   3.356 +     * is 0.
   3.357 +     */
   3.358 +    dsi->elf_paddr_offset =
   3.359 +        xen_elfnote_numeric(dsi, XEN_ELFNOTE_PADDR_OFFSET, &elf_pa_off_defined);
   3.360 +    if ( !elf_pa_off_defined )
   3.361 +    {
   3.362 +        if ( dsi->__elfnote_section )
   3.363 +            dsi->elf_paddr_offset = 0;
   3.364 +        else
   3.365 +            dsi->elf_paddr_offset = dsi->v_start;
   3.366 +    }
   3.367  
   3.368      if ( elf_pa_off_defined && !virt_base_defined )
   3.369      {
   3.370 -        ERROR("Neither ELF_PADDR_OFFSET nor VIRT_BASE found in __xen_guest"
   3.371 -              " section.");
   3.372 +        ERROR("Neither ELF_PADDR_OFFSET nor VIRT_BASE found in ELF "
   3.373 +              " notes or __xen_guest section.");
   3.374          return -EINVAL;
   3.375      }
   3.376  
   3.377 @@ -185,7 +409,7 @@ static int parseelfimage(const char *ima
   3.378          phdr = (Elf_Phdr *)(image + ehdr->e_phoff + (h*ehdr->e_phentsize));
   3.379          if ( !is_loadable_phdr(phdr) )
   3.380              continue;
   3.381 -        vaddr = phdr->p_paddr - elf_pa_off + virt_base;
   3.382 +        vaddr = phdr->p_paddr - dsi->elf_paddr_offset + dsi->v_start;
   3.383          if ( (vaddr + phdr->p_memsz) < vaddr )
   3.384          {
   3.385              ERROR("ELF program header %d is too large.", h);
   3.386 @@ -198,17 +422,12 @@ static int parseelfimage(const char *ima
   3.387              kernend = vaddr + phdr->p_memsz;
   3.388      }
   3.389  
   3.390 -    /*
   3.391 -     * Legacy compatibility and images with no __xen_guest section: assume
   3.392 -     * header addresses are virtual addresses, and that guest memory should be
   3.393 -     * mapped starting at kernel load address.
   3.394 -     */
   3.395 -    dsi->v_start          = virt_base_defined  ? virt_base  : kernstart;
   3.396 -    dsi->elf_paddr_offset = elf_pa_off_defined ? elf_pa_off : dsi->v_start;
   3.397 +    dsi->v_kernentry = ehdr->e_entry;
   3.398  
   3.399 -    dsi->v_kernentry = ehdr->e_entry;
   3.400 -    if ( (p = strstr(guestinfo, "VIRT_ENTRY=")) != NULL )
   3.401 -        dsi->v_kernentry = strtoull(p+11, &p, 0);
   3.402 +    virt_entry =
   3.403 +        xen_elfnote_numeric(dsi, XEN_ELFNOTE_ENTRY, &virt_entry_defined);
   3.404 +    if ( virt_entry_defined )
   3.405 +        dsi->v_kernentry = virt_entry;
   3.406  
   3.407      if ( (kernstart > kernend) ||
   3.408           (dsi->v_kernentry < kernstart) ||
   3.409 @@ -219,7 +438,8 @@ static int parseelfimage(const char *ima
   3.410          return -EINVAL;
   3.411      }
   3.412  
   3.413 -    if ( (p = strstr(guestinfo, "BSD_SYMTAB")) != NULL )
   3.414 +    p = xen_elfnote_string(dsi, XEN_ELFNOTE_BSD_SYMTAB);
   3.415 +    if ( p != NULL && strncmp(p, "yes", 3) == 0 )
   3.416          dsi->load_symtab = 1;
   3.417  
   3.418      dsi->v_kernstart = kernstart;
     4.1 --- a/tools/libxc/xg_private.h	Wed Aug 23 14:36:09 2006 +0100
     4.2 +++ b/tools/libxc/xg_private.h	Wed Aug 23 14:37:39 2006 +0100
     4.3 @@ -5,6 +5,7 @@
     4.4  #include <errno.h>
     4.5  #include <fcntl.h>
     4.6  #include <stdio.h>
     4.7 +#include <stdlib.h>
     4.8  #include <string.h>
     4.9  #include <sys/mman.h>
    4.10  #include <sys/types.h>
    4.11 @@ -16,6 +17,7 @@
    4.12  
    4.13  #include <xen/sys/privcmd.h>
    4.14  #include <xen/memory.h>
    4.15 +#include <xen/elfnote.h>
    4.16  
    4.17  /* valgrind cannot see when a hypercall has filled in some values.  For this
    4.18     reason, we must zero the dom0_op_t instance before a call, if using
    4.19 @@ -149,8 +151,15 @@ struct domain_setup_info
    4.20      unsigned long symtab_addr;
    4.21      unsigned long symtab_len;
    4.22  
    4.23 -    /* __xen_guest info string for convenient loader parsing. */
    4.24 -    char *xen_guest_string;
    4.25 +    /*
    4.26 +     * Only one of __elfnote_* or __xen_guest_string will be
    4.27 +     * non-NULL.
    4.28 +     *
    4.29 +     * You should use the xen_elfnote_* accessors below in order to
    4.30 +     * pickup the correct one and retain backwards compatibility.
    4.31 +     */
    4.32 +    void *__elfnote_section, *__elfnote_section_end;
    4.33 +    char *__xen_guest_string;
    4.34  };
    4.35  
    4.36  typedef int (*parseimagefunc)(const char *image, unsigned long image_size,
    4.37 @@ -160,6 +169,21 @@ typedef int (*loadimagefunc)(const char 
    4.38                               uint32_t dom, xen_pfn_t *parray,
    4.39                               struct domain_setup_info *dsi);
    4.40  
    4.41 +/*
    4.42 + * If an ELF note of the given type is found then the value contained
    4.43 + * in the note is returned and *defined is set to non-zero. If no such
    4.44 + * note is found then *defined is set to 0 and 0 is returned.
    4.45 + */
    4.46 +extern unsigned long long xen_elfnote_numeric(struct domain_setup_info *dsi,
    4.47 +					      int type, int *defined);
    4.48 +
    4.49 +/*
    4.50 + * If an ELF note of the given type is found then the string contained
    4.51 + * in the value is returned, otherwise NULL is returned.
    4.52 + */
    4.53 +extern const char * xen_elfnote_string(struct domain_setup_info *dsi,
    4.54 +				       int type);
    4.55 +
    4.56  struct load_funcs
    4.57  {
    4.58      parseimagefunc parseimage;