ia64/xen-unstable

changeset 5330:411d895b167e

bitkeeper revision 1.1665.4.1 (42a40cf0EmwulK0I8hNEb2dVbDEkvQ)

xc_private.h, xc_linux_build.c, Makefile:
Add support for loading ``bin'' format images, as used by ReactOS.
Move image probing/parsing/loading code out of domain builder to allow
multiple image formats without having to duplicate the domain building
code.
xc_load_elf.c, xc_load_bin.c:
new file
xc_vmx_build.c:
Cleanup.
Signed-Off-By: Ge van Geldorp <gvg@reactos.com>
Signed-off-by: Christian Limpach <Christian.Limpach@cl.cam.ac.uk>
author cl349@firebug.cl.cam.ac.uk
date Mon Jun 06 08:44:32 2005 +0000 (2005-06-06)
parents 0b862197be40
children c2f094c21ddf
files .rootkeys tools/libxc/Makefile tools/libxc/xc_linux_build.c tools/libxc/xc_load_bin.c tools/libxc/xc_load_elf.c tools/libxc/xc_private.h tools/libxc/xc_vmx_build.c
line diff
     1.1 --- a/.rootkeys	Sat Jun 04 13:07:05 2005 +0000
     1.2 +++ b/.rootkeys	Mon Jun 06 08:44:32 2005 +0000
     1.3 @@ -712,6 +712,8 @@ 4227c129ZKjJPNYooHVzBCyinf7Y6Q tools/lib
     1.4  3fbba6dbNCU7U6nsMYiXzKkp3ztaJg tools/libxc/xc_linux_build.c
     1.5  3fbba6dbl267zZOAVHYLOdLCdhcZMw tools/libxc/xc_linux_restore.c
     1.6  3fbba6db7li3FJiABYtCmuGxOJxEGw tools/libxc/xc_linux_save.c
     1.7 +42a40bc3vE3p9fPSJZQZK0MdQF9B8g tools/libxc/xc_load_bin.c
     1.8 +42a40bc4diWfFsPGf0RW7qXMufU4YQ tools/libxc/xc_load_elf.c
     1.9  3fbba6db7WnnJr0KFrIFrqNlSKvFYg tools/libxc/xc_misc.c
    1.10  4051bce6CHAsYh8P5t2OHDtRWOP9og tools/libxc/xc_physdev.c
    1.11  41cc934aO1m6NxEh_8eDr9bJIMoLFA tools/libxc/xc_plan9_build.c
     2.1 --- a/tools/libxc/Makefile	Sat Jun 04 13:07:05 2005 +0000
     2.2 +++ b/tools/libxc/Makefile	Mon Jun 06 08:44:32 2005 +0000
     2.3 @@ -19,6 +19,8 @@ SRCS     += xc_core.c
     2.4  SRCS     += xc_domain.c
     2.5  SRCS     += xc_evtchn.c
     2.6  SRCS     += xc_gnttab.c
     2.7 +SRCS     += xc_load_bin.c
     2.8 +SRCS     += xc_load_elf.c
     2.9  SRCS     += xc_linux_build.c
    2.10  SRCS     += xc_plan9_build.c
    2.11  SRCS     += xc_linux_restore.c
     3.1 --- a/tools/libxc/xc_linux_build.c	Sat Jun 04 13:07:05 2005 +0000
     3.2 +++ b/tools/libxc/xc_linux_build.c	Mon Jun 06 08:44:32 2005 +0000
     3.3 @@ -33,30 +33,19 @@
     3.4  #define round_pgup(_p)    (((_p)+(PAGE_SIZE-1))&PAGE_MASK)
     3.5  #define round_pgdown(_p)  ((_p)&PAGE_MASK)
     3.6  
     3.7 -struct domain_setup_info
     3.8 +static int probeimageformat(char *image,
     3.9 +                            unsigned long image_size,
    3.10 +                            struct load_funcs *load_funcs)
    3.11  {
    3.12 -    unsigned long v_start;
    3.13 -    unsigned long v_end;
    3.14 -    unsigned long v_kernstart;
    3.15 -    unsigned long v_kernend;
    3.16 -    unsigned long v_kernentry;
    3.17 +    if ( probe_elf(image, image_size, load_funcs) &&
    3.18 +         probe_bin(image, image_size, load_funcs) )
    3.19 +    {
    3.20 +        ERROR( "Unrecognized image format" );
    3.21 +        return -EINVAL;
    3.22 +    }
    3.23  
    3.24 -    unsigned int  load_symtab;
    3.25 -    unsigned long symtab_addr;
    3.26 -    unsigned long symtab_len;
    3.27 -};
    3.28 -
    3.29 -static int
    3.30 -parseelfimage(
    3.31 -    char *elfbase, unsigned long elfsize, struct domain_setup_info *dsi);
    3.32 -static int
    3.33 -loadelfimage(
    3.34 -    char *elfbase, int xch, u32 dom, unsigned long *parray,
    3.35 -    struct domain_setup_info *dsi);
    3.36 -static int
    3.37 -loadelfsymtab(
    3.38 -    char *elfbase, int xch, u32 dom, unsigned long *parray,
    3.39 -    struct domain_setup_info *dsi);
    3.40 +    return 0;
    3.41 +}
    3.42  
    3.43  static int setup_guest(int xc_handle,
    3.44                           u32 dom,
    3.45 @@ -94,6 +83,7 @@ static int setup_guest(int xc_handle,
    3.46      unsigned long ppt_alloc;
    3.47      unsigned long *physmap, *physmap_e, physmap_pfn;
    3.48  
    3.49 +    struct load_funcs load_funcs;
    3.50      struct domain_setup_info dsi;
    3.51      unsigned long vinitrd_start;
    3.52      unsigned long vinitrd_end;
    3.53 @@ -107,9 +97,13 @@ static int setup_guest(int xc_handle,
    3.54      unsigned long vpt_end;
    3.55      unsigned long v_end;
    3.56  
    3.57 +    rc = probeimageformat(image, image_size, &load_funcs);
    3.58 +    if ( rc != 0 )
    3.59 +        goto error_out;
    3.60 +
    3.61      memset(&dsi, 0, sizeof(struct domain_setup_info));
    3.62  
    3.63 -    rc = parseelfimage(image, image_size, &dsi);
    3.64 +    rc = (load_funcs.parseimage)(image, image_size, &dsi);
    3.65      if ( rc != 0 )
    3.66          goto error_out;
    3.67  
    3.68 @@ -198,7 +192,8 @@ static int setup_guest(int xc_handle,
    3.69          goto error_out;
    3.70      }
    3.71  
    3.72 -    loadelfimage(image, xc_handle, dom, page_array, &dsi);
    3.73 +    (load_funcs.loadimage)(image, image_size, xc_handle, dom, page_array,
    3.74 +			   &dsi);
    3.75  
    3.76      /* Load the initial ramdisk image. */
    3.77      if ( initrd_len != 0 )
    3.78 @@ -593,266 +588,3 @@ int xc_linux_build(int xc_handle,
    3.79  
    3.80      return -1;
    3.81  }
    3.82 -
    3.83 -static inline int is_loadable_phdr(Elf_Phdr *phdr)
    3.84 -{
    3.85 -    return ((phdr->p_type == PT_LOAD) &&
    3.86 -            ((phdr->p_flags & (PF_W|PF_X)) != 0));
    3.87 -}
    3.88 -
    3.89 -static int parseelfimage(char *elfbase, 
    3.90 -                         unsigned long elfsize,
    3.91 -                         struct domain_setup_info *dsi)
    3.92 -{
    3.93 -    Elf_Ehdr *ehdr = (Elf_Ehdr *)elfbase;
    3.94 -    Elf_Phdr *phdr;
    3.95 -    Elf_Shdr *shdr;
    3.96 -    unsigned long kernstart = ~0UL, kernend=0UL;
    3.97 -    char *shstrtab, *guestinfo=NULL, *p;
    3.98 -    int h;
    3.99 -
   3.100 -    if ( !IS_ELF(*ehdr) )
   3.101 -    {
   3.102 -        ERROR("Kernel image does not have an ELF header.");
   3.103 -        return -EINVAL;
   3.104 -    }
   3.105 -
   3.106 -    if ( (ehdr->e_phoff + (ehdr->e_phnum * ehdr->e_phentsize)) > elfsize )
   3.107 -    {
   3.108 -        ERROR("ELF program headers extend beyond end of image.");
   3.109 -        return -EINVAL;
   3.110 -    }
   3.111 -
   3.112 -    if ( (ehdr->e_shoff + (ehdr->e_shnum * ehdr->e_shentsize)) > elfsize )
   3.113 -    {
   3.114 -        ERROR("ELF section headers extend beyond end of image.");
   3.115 -        return -EINVAL;
   3.116 -    }
   3.117 -
   3.118 -    /* Find the section-header strings table. */
   3.119 -    if ( ehdr->e_shstrndx == SHN_UNDEF )
   3.120 -    {
   3.121 -        ERROR("ELF image has no section-header strings table (shstrtab).");
   3.122 -        return -EINVAL;
   3.123 -    }
   3.124 -    shdr = (Elf_Shdr *)(elfbase + ehdr->e_shoff + 
   3.125 -                        (ehdr->e_shstrndx*ehdr->e_shentsize));
   3.126 -    shstrtab = elfbase + shdr->sh_offset;
   3.127 -    
   3.128 -    /* Find the special '__xen_guest' section and check its contents. */
   3.129 -    for ( h = 0; h < ehdr->e_shnum; h++ )
   3.130 -    {
   3.131 -        shdr = (Elf_Shdr *)(elfbase + ehdr->e_shoff + (h*ehdr->e_shentsize));
   3.132 -        if ( strcmp(&shstrtab[shdr->sh_name], "__xen_guest") != 0 )
   3.133 -            continue;
   3.134 -
   3.135 -        guestinfo = elfbase + shdr->sh_offset;
   3.136 -
   3.137 -        if ( (strstr(guestinfo, "LOADER=generic") == NULL) &&
   3.138 -             (strstr(guestinfo, "GUEST_OS=linux") == NULL) )
   3.139 -        {
   3.140 -            ERROR("Will only load images built for the generic loader "
   3.141 -                  "or Linux images");
   3.142 -            ERROR("Actually saw: '%s'", guestinfo);
   3.143 -            return -EINVAL;
   3.144 -        }
   3.145 -
   3.146 -        if ( (strstr(guestinfo, "XEN_VER=3.0") == NULL) )
   3.147 -        {
   3.148 -            ERROR("Will only load images built for Xen v3.0");
   3.149 -            ERROR("Actually saw: '%s'", guestinfo);
   3.150 -            return -EINVAL;
   3.151 -        }
   3.152 -
   3.153 -        break;
   3.154 -    }
   3.155 -    if ( guestinfo == NULL )
   3.156 -    {
   3.157 -        ERROR("Not a Xen-ELF image: '__xen_guest' section not found.");
   3.158 -        return -EINVAL;
   3.159 -    }
   3.160 -
   3.161 -    for ( h = 0; h < ehdr->e_phnum; h++ ) 
   3.162 -    {
   3.163 -        phdr = (Elf_Phdr *)(elfbase + ehdr->e_phoff + (h*ehdr->e_phentsize));
   3.164 -        if ( !is_loadable_phdr(phdr) )
   3.165 -            continue;
   3.166 -        if ( phdr->p_paddr < kernstart )
   3.167 -            kernstart = phdr->p_paddr;
   3.168 -        if ( (phdr->p_paddr + phdr->p_memsz) > kernend )
   3.169 -            kernend = phdr->p_paddr + phdr->p_memsz;
   3.170 -    }
   3.171 -
   3.172 -    if ( (kernstart > kernend) || 
   3.173 -         (ehdr->e_entry < kernstart) || 
   3.174 -         (ehdr->e_entry > kernend) )
   3.175 -    {
   3.176 -        ERROR("Malformed ELF image.");
   3.177 -        return -EINVAL;
   3.178 -    }
   3.179 -
   3.180 -    dsi->v_start = kernstart;
   3.181 -    if ( (p = strstr(guestinfo, "VIRT_BASE=")) != NULL )
   3.182 -        dsi->v_start = strtoul(p+10, &p, 0);
   3.183 -
   3.184 -    if ( (p = strstr(guestinfo, "BSD_SYMTAB")) != NULL )
   3.185 -        dsi->load_symtab = 1;
   3.186 -
   3.187 -    dsi->v_kernstart = kernstart;
   3.188 -    dsi->v_kernend   = kernend;
   3.189 -    dsi->v_kernentry = ehdr->e_entry;
   3.190 -    dsi->v_end       = dsi->v_kernend;
   3.191 -
   3.192 -    loadelfsymtab(elfbase, 0, 0, NULL, dsi);
   3.193 -
   3.194 -    return 0;
   3.195 -}
   3.196 -
   3.197 -static int
   3.198 -loadelfimage(
   3.199 -    char *elfbase, int xch, u32 dom, unsigned long *parray,
   3.200 -    struct domain_setup_info *dsi)
   3.201 -{
   3.202 -    Elf_Ehdr *ehdr = (Elf_Ehdr *)elfbase;
   3.203 -    Elf_Phdr *phdr;
   3.204 -    int h;
   3.205 -
   3.206 -    char         *va;
   3.207 -    unsigned long pa, done, chunksz;
   3.208 -
   3.209 -    for ( h = 0; h < ehdr->e_phnum; h++ ) 
   3.210 -    {
   3.211 -        phdr = (Elf_Phdr *)(elfbase + ehdr->e_phoff + (h*ehdr->e_phentsize));
   3.212 -        if ( !is_loadable_phdr(phdr) )
   3.213 -            continue;
   3.214 -        
   3.215 -        for ( done = 0; done < phdr->p_filesz; done += chunksz )
   3.216 -        {
   3.217 -            pa = (phdr->p_paddr + done) - dsi->v_start;
   3.218 -            va = xc_map_foreign_range(
   3.219 -                xch, dom, PAGE_SIZE, PROT_WRITE, parray[pa>>PAGE_SHIFT]);
   3.220 -            chunksz = phdr->p_filesz - done;
   3.221 -            if ( chunksz > (PAGE_SIZE - (pa & (PAGE_SIZE-1))) )
   3.222 -                chunksz = PAGE_SIZE - (pa & (PAGE_SIZE-1));
   3.223 -            memcpy(va + (pa & (PAGE_SIZE-1)),
   3.224 -                   elfbase + phdr->p_offset + done, chunksz);
   3.225 -            munmap(va, PAGE_SIZE);
   3.226 -        }
   3.227 -
   3.228 -        for ( ; done < phdr->p_memsz; done += chunksz )
   3.229 -        {
   3.230 -            pa = (phdr->p_paddr + done) - dsi->v_start;
   3.231 -            va = xc_map_foreign_range(
   3.232 -                xch, dom, PAGE_SIZE, PROT_WRITE, parray[pa>>PAGE_SHIFT]);
   3.233 -            chunksz = phdr->p_memsz - done;
   3.234 -            if ( chunksz > (PAGE_SIZE - (pa & (PAGE_SIZE-1))) )
   3.235 -                chunksz = PAGE_SIZE - (pa & (PAGE_SIZE-1));
   3.236 -            memset(va + (pa & (PAGE_SIZE-1)), 0, chunksz);
   3.237 -            munmap(va, PAGE_SIZE);
   3.238 -        }
   3.239 -    }
   3.240 -
   3.241 -    loadelfsymtab(elfbase, xch, dom, parray, dsi);
   3.242 -
   3.243 -    return 0;
   3.244 -}
   3.245 -
   3.246 -#define ELFROUND (ELFSIZE / 8)
   3.247 -
   3.248 -static int
   3.249 -loadelfsymtab(
   3.250 -    char *elfbase, int xch, u32 dom, unsigned long *parray,
   3.251 -    struct domain_setup_info *dsi)
   3.252 -{
   3.253 -    Elf_Ehdr *ehdr = (Elf_Ehdr *)elfbase, *sym_ehdr;
   3.254 -    Elf_Shdr *shdr;
   3.255 -    unsigned long maxva, symva;
   3.256 -    char *p;
   3.257 -    int h, i;
   3.258 -
   3.259 -    if ( !dsi->load_symtab )
   3.260 -        return 0;
   3.261 -
   3.262 -    p = malloc(sizeof(int) + sizeof(Elf_Ehdr) +
   3.263 -               ehdr->e_shnum * sizeof(Elf_Shdr));
   3.264 -    if (p == NULL)
   3.265 -        return 0;
   3.266 -
   3.267 -    maxva = (dsi->v_kernend + ELFROUND - 1) & ~(ELFROUND - 1);
   3.268 -    symva = maxva;
   3.269 -    maxva += sizeof(int);
   3.270 -    dsi->symtab_addr = maxva;
   3.271 -    dsi->symtab_len = 0;
   3.272 -    maxva += sizeof(Elf_Ehdr) + ehdr->e_shnum * sizeof(Elf_Shdr);
   3.273 -    maxva = (maxva + ELFROUND - 1) & ~(ELFROUND - 1);
   3.274 -
   3.275 -    shdr = (Elf_Shdr *)(p + sizeof(int) + sizeof(Elf_Ehdr));
   3.276 -    memcpy(shdr, elfbase + ehdr->e_shoff, ehdr->e_shnum * sizeof(Elf_Shdr));
   3.277 -
   3.278 -    for ( h = 0; h < ehdr->e_shnum; h++ ) 
   3.279 -    {
   3.280 -        if ( shdr[h].sh_type == SHT_STRTAB )
   3.281 -        {
   3.282 -            /* Look for a strtab @i linked to symtab @h. */
   3.283 -            for ( i = 0; i < ehdr->e_shnum; i++ )
   3.284 -                if ( (shdr[i].sh_type == SHT_SYMTAB) &&
   3.285 -                     (shdr[i].sh_link == h) )
   3.286 -                    break;
   3.287 -            /* Skip symtab @h if we found no corresponding strtab @i. */
   3.288 -            if ( i == ehdr->e_shnum )
   3.289 -            {
   3.290 -                shdr[h].sh_offset = 0;
   3.291 -                continue;
   3.292 -            }
   3.293 -        }
   3.294 -
   3.295 -        if ( (shdr[h].sh_type == SHT_STRTAB) ||
   3.296 -             (shdr[h].sh_type == SHT_SYMTAB) )
   3.297 -        {
   3.298 -            if ( parray != NULL )
   3.299 -                xc_map_memcpy(maxva, elfbase + shdr[h].sh_offset, shdr[h].sh_size,
   3.300 -                           xch, dom, parray, dsi->v_start);
   3.301 -
   3.302 -            /* Mangled to be based on ELF header location. */
   3.303 -            shdr[h].sh_offset = maxva - dsi->symtab_addr;
   3.304 -
   3.305 -            dsi->symtab_len += shdr[h].sh_size;
   3.306 -            maxva += shdr[h].sh_size;
   3.307 -            maxva = (maxva + ELFROUND - 1) & ~(ELFROUND - 1);
   3.308 -        }
   3.309 -
   3.310 -        shdr[h].sh_name = 0;  /* Name is NULL. */
   3.311 -    }
   3.312 -
   3.313 -    if ( dsi->symtab_len == 0 )
   3.314 -    {
   3.315 -        dsi->symtab_addr = 0;
   3.316 -        goto out;
   3.317 -    }
   3.318 -
   3.319 -    if ( parray != NULL )
   3.320 -    {
   3.321 -        *(int *)p = maxva - dsi->symtab_addr;
   3.322 -        sym_ehdr = (Elf_Ehdr *)(p + sizeof(int));
   3.323 -        memcpy(sym_ehdr, ehdr, sizeof(Elf_Ehdr));
   3.324 -        sym_ehdr->e_phoff = 0;
   3.325 -        sym_ehdr->e_shoff = sizeof(Elf_Ehdr);
   3.326 -        sym_ehdr->e_phentsize = 0;
   3.327 -        sym_ehdr->e_phnum = 0;
   3.328 -        sym_ehdr->e_shstrndx = SHN_UNDEF;
   3.329 -
   3.330 -        /* Copy total length, crafted ELF header and section header table */
   3.331 -        xc_map_memcpy(symva, p, sizeof(int) + sizeof(Elf_Ehdr) +
   3.332 -                   ehdr->e_shnum * sizeof(Elf_Shdr), xch, dom, parray,
   3.333 -                   dsi->v_start);
   3.334 -    }
   3.335 -
   3.336 -    dsi->symtab_len = maxva - dsi->symtab_addr;
   3.337 -    dsi->v_end = round_pgup(maxva);
   3.338 -
   3.339 - out:
   3.340 -    if ( p != NULL )
   3.341 -        free(p);
   3.342 -
   3.343 -    return 0;
   3.344 -}
     4.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     4.2 +++ b/tools/libxc/xc_load_bin.c	Mon Jun 06 08:44:32 2005 +0000
     4.3 @@ -0,0 +1,299 @@
     4.4 +/******************************************************************************
     4.5 + * xc_bin_load.c
     4.6 + *
     4.7 + * Based on xc_elf_load.c
     4.8 + *
     4.9 + * Loads simple binary images. It's like a .COM file in MS-DOS. No headers are
    4.10 + * present. The only requirement is that it must have a xen_bin_image table
    4.11 + * somewhere in the first 8192 bytes, starting on a 32-bit aligned address.
    4.12 + * Those familiar with the multiboot specification should recognize this, it's
    4.13 + * (almost) the same as the multiboot header.
    4.14 + * The layout of the xen_bin_image table is:
    4.15 + *
    4.16 + * Offset Type Name          Note
    4.17 + * 0      u32  magic         required
    4.18 + * 4      u32  flags         required
    4.19 + * 8      u32  checksum      required
    4.20 + * 12     u32  header_addr   required
    4.21 + * 16     u32  load_addr     required
    4.22 + * 20     u32  load_end_addr required
    4.23 + * 24     u32  bss_end_addr  required
    4.24 + * 28     u32  entry_addr    required
    4.25 + *
    4.26 + * - magic
    4.27 + *   Magic number identifying the table. For images to be loaded by Xen 3, the
    4.28 + *   magic value is 0x336ec578 ("xEn3" with the 0x80 bit of the "E" set).
    4.29 + * - flags
    4.30 + *   bit 0: indicates whether the image needs to be loaded on a page boundary
    4.31 + *   bit 1: reserved, must be 0 (the multiboot spec uses this bit to indicate
    4.32 + *          that memory info should be passed to the image)
    4.33 + *   bit 2: reserved, must be 0 (the multiboot spec uses this bit to indicate
    4.34 + *          that the bootloader should pass video mode info to the image)
    4.35 + *   bit 16: reserved, must be 1 (the multiboot spec uses this bit to indicate
    4.36 + *           that the values in the fields header_addr - entry_addr are
    4.37 + *           valid)
    4.38 + *   All other bits should be set to 0.
    4.39 + * - checksum
    4.40 + *   When added to "magic" and "flags", the resulting value should be 0.
    4.41 + * - header_addr
    4.42 + *   Contains the virtual address corresponding to the beginning of the
    4.43 + *   table - the memory location at which the magic value is supposed to be
    4.44 + *   loaded. This field serves to synchronize the mapping between OS image
    4.45 + *   offsets and virtual memory addresses.
    4.46 + * - load_addr
    4.47 + *   Contains the virtual address of the beginning of the text segment. The
    4.48 + *   offset in the OS image file at which to start loading is defined by the
    4.49 + *   offset at which the table was found, minus (header addr - load addr).
    4.50 + *   load addr must be less than or equal to header addr.
    4.51 + * - load_end_addr
    4.52 + *   Contains the virtual address of the end of the data segment.
    4.53 + *   (load_end_addr - load_addr) specifies how much data to load. This implies
    4.54 + *   that the text and data segments must be consecutive in the OS image. If
    4.55 + *   this field is zero, the domain builder assumes that the text and data
    4.56 + *   segments occupy the whole OS image file.
    4.57 + * - bss_end_addr
    4.58 + *   Contains the virtual address of the end of the bss segment. The domain
    4.59 + *   builder initializes this area to zero, and reserves the memory it occupies
    4.60 + *   to avoid placing boot modules and other data relevant to the loaded image
    4.61 + *   in that area. If this field is zero, the domain builder assumes that no bss
    4.62 + *   segment is present.
    4.63 + * - entry_addr
    4.64 + *   The virtual address at which to start execution of the loaded image.
    4.65 + *
    4.66 + * Some of the field descriptions were copied from "The Multiboot
    4.67 + * Specification", Copyright 1995, 96 Bryan Ford <baford@cs.utah.edu>,
    4.68 + * Erich Stefan Boleyn <erich@uruk.org> Copyright 1999, 2000, 2001, 2002
    4.69 + * Free Software Foundation, Inc.
    4.70 + */
    4.71 +
    4.72 +#include "xc_private.h"
    4.73 +#include <stdlib.h>
    4.74 +
    4.75 +#define L1_PROT (_PAGE_PRESENT|_PAGE_RW|_PAGE_ACCESSED)
    4.76 +#define L2_PROT (_PAGE_PRESENT|_PAGE_RW|_PAGE_ACCESSED|_PAGE_DIRTY|_PAGE_USER)
    4.77 +
    4.78 +#define round_pgup(_p)    (((_p)+(PAGE_SIZE-1))&PAGE_MASK)
    4.79 +#define round_pgdown(_p)  ((_p)&PAGE_MASK)
    4.80 +
    4.81 +struct xen_bin_image_table
    4.82 +{
    4.83 +    unsigned long magic;
    4.84 +    unsigned long flags;
    4.85 +    unsigned long checksum;
    4.86 +    unsigned long header_addr;
    4.87 +    unsigned long load_addr;
    4.88 +    unsigned long load_end_addr;
    4.89 +    unsigned long bss_end_addr;
    4.90 +    unsigned long entry_addr;
    4.91 +};
    4.92 +
    4.93 +#define XEN_REACTOS_MAGIC3 0x336ec578
    4.94 +
    4.95 +#define XEN_REACTOS_FLAG_ALIGN4K     0x00000001
    4.96 +#define XEN_REACTOS_FLAG_NEEDMEMINFO 0x00000002
    4.97 +#define XEN_REACTOS_FLAG_NEEDVIDINFO 0x00000004
    4.98 +#define XEN_REACTOS_FLAG_ADDRSVALID  0x00010000
    4.99 +
   4.100 +/* Flags we test for */
   4.101 +#define FLAGS_MASK     ((~ 0) & (~ XEN_REACTOS_FLAG_ALIGN4K))
   4.102 +#define FLAGS_REQUIRED XEN_REACTOS_FLAG_ADDRSVALID
   4.103 +
   4.104 +static struct xen_bin_image_table *
   4.105 +findtable(char *image, unsigned long image_size);
   4.106 +static int
   4.107 +parsebinimage(
   4.108 +    char *image, unsigned long image_size, struct domain_setup_info *dsi);
   4.109 +static int
   4.110 +loadbinimage(
   4.111 +    char *image, unsigned long image_size, int xch, u32 dom,
   4.112 +    unsigned long *parray, struct domain_setup_info *dsi);
   4.113 +
   4.114 +int xc_bin_probe(char *image,
   4.115 +                 unsigned long image_size,
   4.116 +                 struct load_funcs *load_funcs)
   4.117 +{
   4.118 +    if ( NULL == findtable(image, image_size) )
   4.119 +    {
   4.120 +        return -EINVAL;
   4.121 +    }
   4.122 +
   4.123 +    load_funcs->parseimage = parsebinimage;
   4.124 +    load_funcs->loadimage = loadbinimage;
   4.125 +
   4.126 +    return 0;
   4.127 +}
   4.128 +
   4.129 +static struct xen_bin_image_table *
   4.130 +findtable(char *image, unsigned long image_size)
   4.131 +{
   4.132 +    struct xen_bin_image_table *table;
   4.133 +    unsigned long *probe_ptr;
   4.134 +    unsigned probe_index;
   4.135 +    unsigned probe_count;
   4.136 +
   4.137 +    /* Don't go outside the image */
   4.138 +    if ( image_size < sizeof(struct xen_bin_image_table) )
   4.139 +    {
   4.140 +        return NULL;
   4.141 +    }
   4.142 +    probe_count = image_size;
   4.143 +    /* Restrict to first 8k */
   4.144 +    if ( 8192 < probe_count )
   4.145 +    {
   4.146 +        probe_count = 8192;
   4.147 +    }
   4.148 +    probe_count = (probe_count - sizeof(struct xen_bin_image_table)) /
   4.149 +                  sizeof(unsigned long);
   4.150 +
   4.151 +    /* Search for the magic header */
   4.152 +    probe_ptr = (unsigned long *) image;
   4.153 +    table = NULL;
   4.154 +    for ( probe_index = 0; probe_index < probe_count; probe_index++ )
   4.155 +    {
   4.156 +        if ( XEN_REACTOS_MAGIC3 == *probe_ptr )
   4.157 +        {
   4.158 +            table = (struct xen_bin_image_table *) probe_ptr;
   4.159 +            /* Checksum correct? */
   4.160 +            if ( 0 == table->magic + table->flags + table->checksum )
   4.161 +            {
   4.162 +                return table;
   4.163 +            }
   4.164 +        }
   4.165 +        probe_ptr++;
   4.166 +    }
   4.167 +
   4.168 +    return NULL;
   4.169 +}
   4.170 +
   4.171 +static int parsebinimage(char *image, 
   4.172 +                         unsigned long image_size,
   4.173 +                         struct domain_setup_info *dsi)
   4.174 +{
   4.175 +    struct xen_bin_image_table *image_info;
   4.176 +    unsigned long start_addr;
   4.177 +    unsigned long end_addr;
   4.178 +
   4.179 +    image_info = findtable(image, image_size);
   4.180 +    if ( NULL == image_info )
   4.181 +    {
   4.182 +        ERROR("Image does not have a valid xen_bin_image_table table.");
   4.183 +        return -EINVAL;
   4.184 +    }
   4.185 +
   4.186 +    /* Check the flags */
   4.187 +    if ( FLAGS_REQUIRED != (image_info->flags & FLAGS_MASK) )
   4.188 +    {
   4.189 +        ERROR("xen_bin_image_table flags required 0x%08x found 0x%08lx",
   4.190 +              FLAGS_REQUIRED, image_info->flags & FLAGS_MASK);
   4.191 +        return -EINVAL;
   4.192 +    }
   4.193 +
   4.194 +    /* Sanity check on the addresses */
   4.195 +    if ( image_info->header_addr < image_info->load_addr ||
   4.196 +         ((char *) image_info - image) <
   4.197 +         (image_info->header_addr - image_info->load_addr) )
   4.198 +    {
   4.199 +        ERROR("Invalid header_addr.");
   4.200 +        return -EINVAL;
   4.201 +    }
   4.202 +    start_addr = image_info->header_addr - ((char *) image_info - image);
   4.203 +    if ( 0 != image_info->load_end_addr &&
   4.204 +         ( image_info->load_end_addr < image_info->load_end_addr ||
   4.205 +           start_addr + image_size < image_info->load_end_addr ) )
   4.206 +    {
   4.207 +        ERROR("Invalid load_end_addr");
   4.208 +        return -EINVAL;
   4.209 +    }
   4.210 +    end_addr = (0 == image_info->load_end_addr ? start_addr + image_size :
   4.211 +                                                 image_info->load_end_addr);
   4.212 +    if ( 0 != image_info->bss_end_addr &&
   4.213 +         image_info->bss_end_addr < end_addr )
   4.214 +    {
   4.215 +        ERROR("Invalid bss_end_addr");
   4.216 +        return -EINVAL;
   4.217 +    }
   4.218 +
   4.219 +    dsi->v_start = image_info->load_addr;
   4.220 +    if ( 0 != image_info->bss_end_addr )
   4.221 +    {
   4.222 +        dsi->v_end = image_info->bss_end_addr;
   4.223 +    }
   4.224 +    else if ( 0 != image_info->load_end_addr )
   4.225 +    {
   4.226 +        dsi->v_end = image_info->load_end_addr;
   4.227 +    }
   4.228 +    else
   4.229 +    {
   4.230 +        dsi->v_end = image_info->load_addr + image_size -
   4.231 +                     (((char *) image_info - image) -
   4.232 +                      (image_info->header_addr - image_info->load_addr));
   4.233 +    }
   4.234 +    dsi->v_kernstart = dsi->v_start;
   4.235 +    dsi->v_kernend = dsi->v_end;
   4.236 +    dsi->v_kernentry = image_info->entry_addr;
   4.237 +
   4.238 +    return 0;
   4.239 +}
   4.240 +
   4.241 +static int
   4.242 +loadbinimage(
   4.243 +    char *image, unsigned long image_size, int xch, u32 dom,
   4.244 +    unsigned long *parray, struct domain_setup_info *dsi)
   4.245 +{
   4.246 +    unsigned long size;
   4.247 +    char         *va;
   4.248 +    unsigned long done, chunksz;
   4.249 +    struct xen_bin_image_table *image_info;
   4.250 +
   4.251 +    image_info = findtable(image, image_size);
   4.252 +    if ( NULL == image_info )
   4.253 +    {
   4.254 +        ERROR("Image does not have a valid xen_bin_image_table table.");
   4.255 +        return -EINVAL;
   4.256 +    }
   4.257 +
   4.258 +    /* Determine image size */
   4.259 +    if ( 0 == image_info->load_end_addr )
   4.260 +    {
   4.261 +        size = image_size  - (((char *) image_info - image) -
   4.262 +                              (image_info->header_addr -
   4.263 +                               image_info->load_addr));
   4.264 +    }
   4.265 +    else
   4.266 +    {
   4.267 +        size = image_info->load_end_addr - image_info->load_addr;
   4.268 +    }
   4.269 +
   4.270 +    /* It's possible that we need to skip the first part of the image */
   4.271 +    image += ((char *)image_info - image) -
   4.272 +             (image_info->header_addr - image_info->load_addr);
   4.273 +
   4.274 +    for ( done = 0; done < size; done += chunksz )
   4.275 +    {
   4.276 +        va = xc_map_foreign_range(
   4.277 +            xch, dom, PAGE_SIZE, PROT_WRITE, parray[done>>PAGE_SHIFT]);
   4.278 +        chunksz = size - done;
   4.279 +        if ( chunksz > PAGE_SIZE )
   4.280 +            chunksz = PAGE_SIZE;
   4.281 +        memcpy(va, image + done, chunksz);
   4.282 +        munmap(va, PAGE_SIZE);
   4.283 +    }
   4.284 +
   4.285 +    if ( 0 != image_info->bss_end_addr &&
   4.286 +         image_info->load_addr + size < image_info->bss_end_addr )
   4.287 +    {
   4.288 +        size = image_info->bss_end_addr - image_info->load_addr;
   4.289 +    }
   4.290 +    for ( ; done < size; done += chunksz )
   4.291 +    {
   4.292 +        va = xc_map_foreign_range(
   4.293 +            xch, dom, PAGE_SIZE, PROT_WRITE, parray[done>>PAGE_SHIFT]);
   4.294 +        chunksz = size - done;
   4.295 +        if ( chunksz > (PAGE_SIZE - (done & (PAGE_SIZE-1))) )
   4.296 +            chunksz = PAGE_SIZE - (done & (PAGE_SIZE-1));
   4.297 +        memset(va + (done & (PAGE_SIZE-1)), 0, chunksz);
   4.298 +        munmap(va, PAGE_SIZE);
   4.299 +    }
   4.300 +
   4.301 +    return 0;
   4.302 +}
     5.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     5.2 +++ b/tools/libxc/xc_load_elf.c	Mon Jun 06 08:44:32 2005 +0000
     5.3 @@ -0,0 +1,310 @@
     5.4 +/******************************************************************************
     5.5 + * xc_elf_load.c
     5.6 + */
     5.7 +
     5.8 +#include "xc_private.h"
     5.9 +
    5.10 +#if defined(__i386__)
    5.11 +#define ELFSIZE 32
    5.12 +#endif
    5.13 +#if defined(__x86_64__)
    5.14 +#define ELFSIZE 64
    5.15 +#endif
    5.16 +
    5.17 +#include "xc_elf.h"
    5.18 +#include <stdlib.h>
    5.19 +
    5.20 +#define round_pgup(_p)    (((_p)+(PAGE_SIZE-1))&PAGE_MASK)
    5.21 +#define round_pgdown(_p)  ((_p)&PAGE_MASK)
    5.22 +
    5.23 +static int
    5.24 +parseelfimage(
    5.25 +    char *image, unsigned long image_size, struct domain_setup_info *dsi);
    5.26 +static int
    5.27 +loadelfimage(
    5.28 +    char *image, unsigned long image_size, int xch, u32 dom,
    5.29 +    unsigned long *parray, struct domain_setup_info *dsi);
    5.30 +static int
    5.31 +loadelfsymtab(
    5.32 +    char *image, int xch, u32 dom, unsigned long *parray,
    5.33 +    struct domain_setup_info *dsi);
    5.34 +
    5.35 +int xc_elf_probe(char *image,
    5.36 +                 unsigned long image_size,
    5.37 +                 struct load_funcs *load_funcs)
    5.38 +{
    5.39 +    Elf_Ehdr *ehdr = (Elf_Ehdr *)image;
    5.40 +
    5.41 +    if ( !IS_ELF(*ehdr) )
    5.42 +    {
    5.43 +        return -EINVAL;
    5.44 +    }
    5.45 +
    5.46 +    load_funcs->parseimage = parseelfimage;
    5.47 +    load_funcs->loadimage = loadelfimage;
    5.48 +
    5.49 +    return 0;
    5.50 +}
    5.51 +
    5.52 +static inline int is_loadable_phdr(Elf_Phdr *phdr)
    5.53 +{
    5.54 +    return ((phdr->p_type == PT_LOAD) &&
    5.55 +            ((phdr->p_flags & (PF_W|PF_X)) != 0));
    5.56 +}
    5.57 +
    5.58 +static int parseelfimage(char *image, 
    5.59 +                         unsigned long elfsize,
    5.60 +                         struct domain_setup_info *dsi)
    5.61 +{
    5.62 +    Elf_Ehdr *ehdr = (Elf_Ehdr *)image;
    5.63 +    Elf_Phdr *phdr;
    5.64 +    Elf_Shdr *shdr;
    5.65 +    unsigned long kernstart = ~0UL, kernend=0UL;
    5.66 +    char *shstrtab, *guestinfo=NULL, *p;
    5.67 +    int h;
    5.68 +
    5.69 +    if ( !IS_ELF(*ehdr) )
    5.70 +    {
    5.71 +        ERROR("Kernel image does not have an ELF header.");
    5.72 +        return -EINVAL;
    5.73 +    }
    5.74 +
    5.75 +    if ( (ehdr->e_phoff + (ehdr->e_phnum * ehdr->e_phentsize)) > elfsize )
    5.76 +    {
    5.77 +        ERROR("ELF program headers extend beyond end of image.");
    5.78 +        return -EINVAL;
    5.79 +    }
    5.80 +
    5.81 +    if ( (ehdr->e_shoff + (ehdr->e_shnum * ehdr->e_shentsize)) > elfsize )
    5.82 +    {
    5.83 +        ERROR("ELF section headers extend beyond end of image.");
    5.84 +        return -EINVAL;
    5.85 +    }
    5.86 +
    5.87 +    /* Find the section-header strings table. */
    5.88 +    if ( ehdr->e_shstrndx == SHN_UNDEF )
    5.89 +    {
    5.90 +        ERROR("ELF image has no section-header strings table (shstrtab).");
    5.91 +        return -EINVAL;
    5.92 +    }
    5.93 +    shdr = (Elf_Shdr *)(image + ehdr->e_shoff + 
    5.94 +                        (ehdr->e_shstrndx*ehdr->e_shentsize));
    5.95 +    shstrtab = image + shdr->sh_offset;
    5.96 +    
    5.97 +    /* Find the special '__xen_guest' section and check its contents. */
    5.98 +    for ( h = 0; h < ehdr->e_shnum; h++ )
    5.99 +    {
   5.100 +        shdr = (Elf_Shdr *)(image + ehdr->e_shoff + (h*ehdr->e_shentsize));
   5.101 +        if ( strcmp(&shstrtab[shdr->sh_name], "__xen_guest") != 0 )
   5.102 +            continue;
   5.103 +
   5.104 +        guestinfo = image + shdr->sh_offset;
   5.105 +
   5.106 +        if ( (strstr(guestinfo, "LOADER=generic") == NULL) &&
   5.107 +             (strstr(guestinfo, "GUEST_OS=linux") == NULL) )
   5.108 +        {
   5.109 +            ERROR("Will only load images built for the generic loader "
   5.110 +                  "or Linux images");
   5.111 +            ERROR("Actually saw: '%s'", guestinfo);
   5.112 +            return -EINVAL;
   5.113 +        }
   5.114 +
   5.115 +        if ( (strstr(guestinfo, "XEN_VER=3.0") == NULL) )
   5.116 +        {
   5.117 +            ERROR("Will only load images built for Xen v3.0");
   5.118 +            ERROR("Actually saw: '%s'", guestinfo);
   5.119 +            return -EINVAL;
   5.120 +        }
   5.121 +
   5.122 +        break;
   5.123 +    }
   5.124 +    if ( guestinfo == NULL )
   5.125 +    {
   5.126 +        ERROR("Not a Xen-ELF image: '__xen_guest' section not found.");
   5.127 +        return -EINVAL;
   5.128 +    }
   5.129 +
   5.130 +    for ( h = 0; h < ehdr->e_phnum; h++ ) 
   5.131 +    {
   5.132 +        phdr = (Elf_Phdr *)(image + ehdr->e_phoff + (h*ehdr->e_phentsize));
   5.133 +        if ( !is_loadable_phdr(phdr) )
   5.134 +            continue;
   5.135 +        if ( phdr->p_paddr < kernstart )
   5.136 +            kernstart = phdr->p_paddr;
   5.137 +        if ( (phdr->p_paddr + phdr->p_memsz) > kernend )
   5.138 +            kernend = phdr->p_paddr + phdr->p_memsz;
   5.139 +    }
   5.140 +
   5.141 +    if ( (kernstart > kernend) || 
   5.142 +         (ehdr->e_entry < kernstart) || 
   5.143 +         (ehdr->e_entry > kernend) )
   5.144 +    {
   5.145 +        ERROR("Malformed ELF image.");
   5.146 +        return -EINVAL;
   5.147 +    }
   5.148 +
   5.149 +    dsi->v_start = kernstart;
   5.150 +    if ( (p = strstr(guestinfo, "VIRT_BASE=")) != NULL )
   5.151 +        dsi->v_start = strtoul(p+10, &p, 0);
   5.152 +
   5.153 +    if ( (p = strstr(guestinfo, "BSD_SYMTAB")) != NULL )
   5.154 +        dsi->load_symtab = 1;
   5.155 +
   5.156 +    dsi->v_kernstart = kernstart;
   5.157 +    dsi->v_kernend   = kernend;
   5.158 +    dsi->v_kernentry = ehdr->e_entry;
   5.159 +    dsi->v_end       = dsi->v_kernend;
   5.160 +
   5.161 +    loadelfsymtab(image, 0, 0, NULL, dsi);
   5.162 +
   5.163 +    return 0;
   5.164 +}
   5.165 +
   5.166 +static int
   5.167 +loadelfimage(
   5.168 +    char *image, unsigned long elfsize, int xch, u32 dom,
   5.169 +    unsigned long *parray, struct domain_setup_info *dsi)
   5.170 +{
   5.171 +    Elf_Ehdr *ehdr = (Elf_Ehdr *)image;
   5.172 +    Elf_Phdr *phdr;
   5.173 +    int h;
   5.174 +
   5.175 +    char         *va;
   5.176 +    unsigned long pa, done, chunksz;
   5.177 +
   5.178 +    for ( h = 0; h < ehdr->e_phnum; h++ ) 
   5.179 +    {
   5.180 +        phdr = (Elf_Phdr *)(image + ehdr->e_phoff + (h*ehdr->e_phentsize));
   5.181 +        if ( !is_loadable_phdr(phdr) )
   5.182 +            continue;
   5.183 +        
   5.184 +        for ( done = 0; done < phdr->p_filesz; done += chunksz )
   5.185 +        {
   5.186 +            pa = (phdr->p_paddr + done) - dsi->v_start;
   5.187 +            va = xc_map_foreign_range(
   5.188 +                xch, dom, PAGE_SIZE, PROT_WRITE, parray[pa>>PAGE_SHIFT]);
   5.189 +            chunksz = phdr->p_filesz - done;
   5.190 +            if ( chunksz > (PAGE_SIZE - (pa & (PAGE_SIZE-1))) )
   5.191 +                chunksz = PAGE_SIZE - (pa & (PAGE_SIZE-1));
   5.192 +            memcpy(va + (pa & (PAGE_SIZE-1)),
   5.193 +                   image + phdr->p_offset + done, chunksz);
   5.194 +            munmap(va, PAGE_SIZE);
   5.195 +        }
   5.196 +
   5.197 +        for ( ; done < phdr->p_memsz; done += chunksz )
   5.198 +        {
   5.199 +            pa = (phdr->p_paddr + done) - dsi->v_start;
   5.200 +            va = xc_map_foreign_range(
   5.201 +                xch, dom, PAGE_SIZE, PROT_WRITE, parray[pa>>PAGE_SHIFT]);
   5.202 +            chunksz = phdr->p_memsz - done;
   5.203 +            if ( chunksz > (PAGE_SIZE - (pa & (PAGE_SIZE-1))) )
   5.204 +                chunksz = PAGE_SIZE - (pa & (PAGE_SIZE-1));
   5.205 +            memset(va + (pa & (PAGE_SIZE-1)), 0, chunksz);
   5.206 +            munmap(va, PAGE_SIZE);
   5.207 +        }
   5.208 +    }
   5.209 +
   5.210 +    loadelfsymtab(image, xch, dom, parray, dsi);
   5.211 +
   5.212 +    return 0;
   5.213 +}
   5.214 +
   5.215 +#define ELFROUND (ELFSIZE / 8)
   5.216 +
   5.217 +static int
   5.218 +loadelfsymtab(
   5.219 +    char *image, int xch, u32 dom, unsigned long *parray,
   5.220 +    struct domain_setup_info *dsi)
   5.221 +{
   5.222 +    Elf_Ehdr *ehdr = (Elf_Ehdr *)image, *sym_ehdr;
   5.223 +    Elf_Shdr *shdr;
   5.224 +    unsigned long maxva, symva;
   5.225 +    char *p;
   5.226 +    int h, i;
   5.227 +
   5.228 +    if ( !dsi->load_symtab )
   5.229 +        return 0;
   5.230 +
   5.231 +    p = malloc(sizeof(int) + sizeof(Elf_Ehdr) +
   5.232 +               ehdr->e_shnum * sizeof(Elf_Shdr));
   5.233 +    if (p == NULL)
   5.234 +        return 0;
   5.235 +
   5.236 +    maxva = (dsi->v_kernend + ELFROUND - 1) & ~(ELFROUND - 1);
   5.237 +    symva = maxva;
   5.238 +    maxva += sizeof(int);
   5.239 +    dsi->symtab_addr = maxva;
   5.240 +    dsi->symtab_len = 0;
   5.241 +    maxva += sizeof(Elf_Ehdr) + ehdr->e_shnum * sizeof(Elf_Shdr);
   5.242 +    maxva = (maxva + ELFROUND - 1) & ~(ELFROUND - 1);
   5.243 +
   5.244 +    shdr = (Elf_Shdr *)(p + sizeof(int) + sizeof(Elf_Ehdr));
   5.245 +    memcpy(shdr, image + ehdr->e_shoff, ehdr->e_shnum * sizeof(Elf_Shdr));
   5.246 +
   5.247 +    for ( h = 0; h < ehdr->e_shnum; h++ ) 
   5.248 +    {
   5.249 +        if ( shdr[h].sh_type == SHT_STRTAB )
   5.250 +        {
   5.251 +            /* Look for a strtab @i linked to symtab @h. */
   5.252 +            for ( i = 0; i < ehdr->e_shnum; i++ )
   5.253 +                if ( (shdr[i].sh_type == SHT_SYMTAB) &&
   5.254 +                     (shdr[i].sh_link == h) )
   5.255 +                    break;
   5.256 +            /* Skip symtab @h if we found no corresponding strtab @i. */
   5.257 +            if ( i == ehdr->e_shnum )
   5.258 +            {
   5.259 +                shdr[h].sh_offset = 0;
   5.260 +                continue;
   5.261 +            }
   5.262 +        }
   5.263 +
   5.264 +        if ( (shdr[h].sh_type == SHT_STRTAB) ||
   5.265 +             (shdr[h].sh_type == SHT_SYMTAB) )
   5.266 +        {
   5.267 +            if ( parray != NULL )
   5.268 +                xc_map_memcpy(maxva, image + shdr[h].sh_offset, shdr[h].sh_size,
   5.269 +                           xch, dom, parray, dsi->v_start);
   5.270 +
   5.271 +            /* Mangled to be based on ELF header location. */
   5.272 +            shdr[h].sh_offset = maxva - dsi->symtab_addr;
   5.273 +
   5.274 +            dsi->symtab_len += shdr[h].sh_size;
   5.275 +            maxva += shdr[h].sh_size;
   5.276 +            maxva = (maxva + ELFROUND - 1) & ~(ELFROUND - 1);
   5.277 +        }
   5.278 +
   5.279 +        shdr[h].sh_name = 0;  /* Name is NULL. */
   5.280 +    }
   5.281 +
   5.282 +    if ( dsi->symtab_len == 0 )
   5.283 +    {
   5.284 +        dsi->symtab_addr = 0;
   5.285 +        goto out;
   5.286 +    }
   5.287 +
   5.288 +    if ( parray != NULL )
   5.289 +    {
   5.290 +        *(int *)p = maxva - dsi->symtab_addr;
   5.291 +        sym_ehdr = (Elf_Ehdr *)(p + sizeof(int));
   5.292 +        memcpy(sym_ehdr, ehdr, sizeof(Elf_Ehdr));
   5.293 +        sym_ehdr->e_phoff = 0;
   5.294 +        sym_ehdr->e_shoff = sizeof(Elf_Ehdr);
   5.295 +        sym_ehdr->e_phentsize = 0;
   5.296 +        sym_ehdr->e_phnum = 0;
   5.297 +        sym_ehdr->e_shstrndx = SHN_UNDEF;
   5.298 +
   5.299 +        /* Copy total length, crafted ELF header and section header table */
   5.300 +        xc_map_memcpy(symva, p, sizeof(int) + sizeof(Elf_Ehdr) +
   5.301 +                   ehdr->e_shnum * sizeof(Elf_Shdr), xch, dom, parray,
   5.302 +                   dsi->v_start);
   5.303 +    }
   5.304 +
   5.305 +    dsi->symtab_len = maxva - dsi->symtab_addr;
   5.306 +    dsi->v_end = round_pgup(maxva);
   5.307 +
   5.308 + out:
   5.309 +    if ( p != NULL )
   5.310 +        free(p);
   5.311 +
   5.312 +    return 0;
   5.313 +}
     6.1 --- a/tools/libxc/xc_private.h	Sat Jun 04 13:07:05 2005 +0000
     6.2 +++ b/tools/libxc/xc_private.h	Mon Jun 06 08:44:32 2005 +0000
     6.3 @@ -76,6 +76,31 @@ typedef unsigned long l4_pgentry_t;
     6.4  	(((_a) >> L4_PAGETABLE_SHIFT) & (L4_PAGETABLE_ENTRIES - 1))
     6.5  #endif
     6.6  
     6.7 +struct domain_setup_info
     6.8 +{
     6.9 +    unsigned long v_start;
    6.10 +    unsigned long v_end;
    6.11 +    unsigned long v_kernstart;
    6.12 +    unsigned long v_kernend;
    6.13 +    unsigned long v_kernentry;
    6.14 +
    6.15 +    unsigned int  load_symtab;
    6.16 +    unsigned long symtab_addr;
    6.17 +    unsigned long symtab_len;
    6.18 +};
    6.19 +
    6.20 +typedef int (*parseimagefunc)(char *image, unsigned long image_size,
    6.21 +			      struct domain_setup_info *dsi);
    6.22 +typedef int (*loadimagefunc)(char *image, unsigned long image_size, int xch,
    6.23 +			     u32 dom, unsigned long *parray,
    6.24 +			     struct domain_setup_info *dsi);
    6.25 +
    6.26 +struct load_funcs
    6.27 +{
    6.28 +    parseimagefunc parseimage;
    6.29 +    loadimagefunc loadimage;
    6.30 +};
    6.31 +
    6.32  #define ERROR(_m, _a...)  \
    6.33      fprintf(stderr, "ERROR: " _m "\n" , ## _a )
    6.34  
    6.35 @@ -260,7 +285,7 @@ typedef struct mfn_mapper {
    6.36      
    6.37  } mfn_mapper_t;
    6.38  
    6.39 -unsigned long xc_get_m2p_start_mfn ( int xc_handle );
    6.40 +unsigned long xc_get_m2p_start_mfn (int xc_handle);
    6.41  
    6.42  int xc_copy_to_domain_page(int xc_handle, u32 domid,
    6.43                              unsigned long dst_pfn, void *src_page);
    6.44 @@ -273,7 +298,11 @@ void xc_map_memcpy(unsigned long dst, ch
    6.45                     int xch, u32 dom, unsigned long *parray,
    6.46                     unsigned long vstart);
    6.47  
    6.48 -int pin_table(
    6.49 -    int xc_handle, unsigned int type, unsigned long mfn, domid_t dom);
    6.50 +int pin_table(int xc_handle, unsigned int type, unsigned long mfn,
    6.51 +	      domid_t dom);
    6.52 +
    6.53 +/* image loading */
    6.54 +int probe_elf(char *image, unsigned long image_size, struct load_funcs *funcs);
    6.55 +int probe_bin(char *image, unsigned long image_size, struct load_funcs *funcs);
    6.56  
    6.57  #endif /* __XC_PRIVATE_H__ */
     7.1 --- a/tools/libxc/xc_vmx_build.c	Sat Jun 04 13:07:05 2005 +0000
     7.2 +++ b/tools/libxc/xc_vmx_build.c	Mon Jun 06 08:44:32 2005 +0000
     7.3 @@ -20,22 +20,13 @@
     7.4  #define LINUX_KERNEL_ENTR_ADDR   0x00100000
     7.5  #define LINUX_PAGE_OFFSET        0xC0000000
     7.6  
     7.7 -struct domain_setup_info
     7.8 -{
     7.9 -    unsigned long v_start;
    7.10 -    unsigned long v_end;
    7.11 -    unsigned long v_kernstart;
    7.12 -    unsigned long v_kernend;
    7.13 -    unsigned long v_kernentry;
    7.14 -};
    7.15 -
    7.16  static int
    7.17  parseelfimage(
    7.18      char *elfbase, unsigned long elfsize, struct domain_setup_info *dsi);
    7.19  static int
    7.20  loadelfimage(
    7.21      char *elfbase, int xch, u32 dom, unsigned long *parray,
    7.22 -    unsigned long vstart);
    7.23 +    struct domain_setup_info *dsi);
    7.24  
    7.25  static void build_e820map(struct mem_map *mem_mapp, unsigned long mem_size)
    7.26  {
    7.27 @@ -255,7 +246,7 @@ static int setup_guest(int xc_handle,
    7.28          goto error_out;
    7.29      }
    7.30  
    7.31 -    loadelfimage(image, xc_handle, dom, page_array, dsi.v_start);
    7.32 +    loadelfimage(image, xc_handle, dom, page_array, &dsi);
    7.33  
    7.34      /* Load the initial ramdisk image. */
    7.35      if ( initrd_len != 0 )
    7.36 @@ -626,6 +617,7 @@ int xc_vmx_build(int xc_handle,
    7.37  
    7.38      launch_op.cmd = DOM0_SETDOMAININFO;
    7.39      rc = do_dom0_op(xc_handle, &launch_op);
    7.40 +    
    7.41      return rc;
    7.42  
    7.43   error_out:
    7.44 @@ -717,7 +709,7 @@ static int parseelfimage(char *elfbase,
    7.45  static int
    7.46  loadelfimage(
    7.47      char *elfbase, int xch, u32 dom, unsigned long *parray,
    7.48 -    unsigned long vstart)
    7.49 +    struct domain_setup_info *dsi)
    7.50  {
    7.51      Elf_Ehdr *ehdr = (Elf_Ehdr *)elfbase;
    7.52      Elf_Phdr *phdr;
    7.53 @@ -734,7 +726,7 @@ loadelfimage(
    7.54          
    7.55          for ( done = 0; done < phdr->p_filesz; done += chunksz )
    7.56          {
    7.57 -            pa = (phdr->p_paddr + done) - vstart - LINUX_PAGE_OFFSET;
    7.58 +            pa = (phdr->p_paddr + done) - dsi->v_start - LINUX_PAGE_OFFSET;
    7.59              if ((va = xc_map_foreign_range(
    7.60  			xch, dom, PAGE_SIZE, PROT_WRITE,
    7.61  			parray[pa>>PAGE_SHIFT])) == 0)
    7.62 @@ -749,7 +741,7 @@ loadelfimage(
    7.63  
    7.64          for ( ; done < phdr->p_memsz; done += chunksz )
    7.65          {
    7.66 -            pa = (phdr->p_paddr + done) - vstart - LINUX_PAGE_OFFSET;
    7.67 +            pa = (phdr->p_paddr + done) - dsi->v_start - LINUX_PAGE_OFFSET;
    7.68              if ((va = xc_map_foreign_range(
    7.69  			xch, dom, PAGE_SIZE, PROT_WRITE,
    7.70  			parray[pa>>PAGE_SHIFT])) == 0)