ia64/xen-unstable

changeset 2681:d7a5a934e8d6

bitkeeper revision 1.1159.1.253 (4177acb31pR6O7gnvHBPRklwripeYQ)

Remove netbsd domain builder.
author cl349@freefall.cl.cam.ac.uk
date Thu Oct 21 12:33:55 2004 +0000 (2004-10-21)
parents 71ca04e8f096
children 7bc73b540515 7eb0f01df59a
files .rootkeys tools/libxc/Makefile tools/libxc/xc_netbsd_build.c
line diff
     1.1 --- a/.rootkeys	Thu Oct 21 12:30:11 2004 +0000
     1.2 +++ b/.rootkeys	Thu Oct 21 12:33:55 2004 +0000
     1.3 @@ -339,7 +339,6 @@ 3fbba6dbNCU7U6nsMYiXzKkp3ztaJg tools/lib
     1.4  3fbba6dbl267zZOAVHYLOdLCdhcZMw tools/libxc/xc_linux_restore.c
     1.5  3fbba6db7li3FJiABYtCmuGxOJxEGw tools/libxc/xc_linux_save.c
     1.6  3fbba6db7WnnJr0KFrIFrqNlSKvFYg tools/libxc/xc_misc.c
     1.7 -40278d9ctaHVDaEuwhXI3Om2JOjx9w tools/libxc/xc_netbsd_build.c
     1.8  4051bce6CHAsYh8P5t2OHDtRWOP9og tools/libxc/xc_physdev.c
     1.9  3fbba6dctWRWlFJkYb6hdix2X4WMuw tools/libxc/xc_private.c
    1.10  3fbba6dcbVrG2hPzEzwdeV_UC8kydQ tools/libxc/xc_private.h
     2.1 --- a/tools/libxc/Makefile	Thu Oct 21 12:30:11 2004 +0000
     2.2 +++ b/tools/libxc/Makefile	Thu Oct 21 12:33:55 2004 +0000
     2.3 @@ -27,7 +27,6 @@ SRCS     += xc_linux_build.c
     2.4  SRCS     += xc_linux_restore.c
     2.5  SRCS     += xc_linux_save.c
     2.6  SRCS     += xc_misc.c
     2.7 -SRCS     += xc_netbsd_build.c
     2.8  SRCS     += xc_physdev.c
     2.9  SRCS     += xc_private.c
    2.10  SRCS     += xc_rrobin.c
     3.1 --- a/tools/libxc/xc_netbsd_build.c	Thu Oct 21 12:30:11 2004 +0000
     3.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
     3.3 @@ -1,710 +0,0 @@
     3.4 -/******************************************************************************
     3.5 - * xc_netbsd_build.c
     3.6 - */
     3.7 -
     3.8 -#include "xc_private.h"
     3.9 -#define ELFSIZE 32  /* XXX */
    3.10 -#include "xc_elf.h"
    3.11 -#include <zlib.h>
    3.12 -
    3.13 -#ifdef DEBUG
    3.14 -#define DPRINTF(x) printf x
    3.15 -#else
    3.16 -#define DPRINTF(x)
    3.17 -#endif
    3.18 -
    3.19 -static int loadelfimage(gzFile, int, u32, unsigned long *, unsigned long,
    3.20 -                        unsigned long *, unsigned long *,
    3.21 -                        unsigned long *, unsigned long *);
    3.22 -
    3.23 -#define ELFROUND (ELFSIZE / 8)
    3.24 -
    3.25 -#define L1_PROT (_PAGE_PRESENT|_PAGE_RW|_PAGE_ACCESSED)
    3.26 -#define L2_PROT (_PAGE_PRESENT|_PAGE_RW|_PAGE_ACCESSED|_PAGE_DIRTY|_PAGE_USER)
    3.27 -
    3.28 -static long get_tot_pages(int xc_handle, u32 domid)
    3.29 -{
    3.30 -    dom0_op_t op;
    3.31 -    op.cmd = DOM0_GETDOMAININFO;
    3.32 -    op.u.getdomaininfo.domain = (domid_t)domid;
    3.33 -    op.u.getdomaininfo.ctxt = NULL;
    3.34 -    return (do_dom0_op(xc_handle, &op) < 0) ? 
    3.35 -        -1 : op.u.getdomaininfo.tot_pages;
    3.36 -}
    3.37 -
    3.38 -static int get_pfn_list(int xc_handle,
    3.39 -                        u32 domid, 
    3.40 -                        unsigned long *pfn_buf, 
    3.41 -                        unsigned long max_pfns)
    3.42 -{
    3.43 -    dom0_op_t op;
    3.44 -    int ret;
    3.45 -    op.cmd = DOM0_GETMEMLIST;
    3.46 -    op.u.getmemlist.domain   = (domid_t)domid;
    3.47 -    op.u.getmemlist.max_pfns = max_pfns;
    3.48 -    op.u.getmemlist.buffer   = pfn_buf;
    3.49 -
    3.50 -    if ( mlock(pfn_buf, max_pfns * sizeof(unsigned long)) != 0 )
    3.51 -        return -1;
    3.52 -
    3.53 -    ret = do_dom0_op(xc_handle, &op);
    3.54 -
    3.55 -    (void)munlock(pfn_buf, max_pfns * sizeof(unsigned long));
    3.56 -
    3.57 -    return (ret < 0) ? -1 : op.u.getmemlist.num_pfns;
    3.58 -}
    3.59 -
    3.60 -static int setup_guestos(int xc_handle,
    3.61 -                         u32 dom, 
    3.62 -                         gzFile kernel_gfd, 
    3.63 -                         unsigned long tot_pages,
    3.64 -                         unsigned long *virt_startinfo_addr, 
    3.65 -                         unsigned long *virt_load_addr, 
    3.66 -                         full_execution_context_t *ctxt,
    3.67 -                         const char *cmdline,
    3.68 -                         unsigned long shared_info_frame,
    3.69 -                         unsigned int control_evtchn)
    3.70 -{
    3.71 -    l1_pgentry_t *vl1tab=NULL, *vl1e=NULL;
    3.72 -    l2_pgentry_t *vl2tab=NULL, *vl2e=NULL;
    3.73 -    unsigned long *page_array = NULL;
    3.74 -    int alloc_index, num_pt_pages;
    3.75 -    unsigned long l2tab;
    3.76 -    unsigned long l1tab;
    3.77 -    unsigned long count, pt_start;
    3.78 -    unsigned long symtab_addr = 0, symtab_len = 0;
    3.79 -    start_info_t *start_info;
    3.80 -    shared_info_t *shared_info;
    3.81 -    unsigned long ksize;
    3.82 -    mmu_t *mmu = NULL;
    3.83 -    int i;
    3.84 -
    3.85 -    if ( (page_array = malloc(tot_pages * sizeof(unsigned long))) == NULL )
    3.86 -    {
    3.87 -        PERROR("Could not allocate memory");
    3.88 -        goto error_out;
    3.89 -    }
    3.90 -
    3.91 -    if ( get_pfn_list(xc_handle, dom, page_array, tot_pages) != tot_pages )
    3.92 -    {
    3.93 -        PERROR("Could not get the page frame list");
    3.94 -        goto error_out;
    3.95 -    }
    3.96 -
    3.97 -    if (loadelfimage(kernel_gfd, xc_handle, dom, page_array, tot_pages,
    3.98 -                     virt_load_addr, &ksize, &symtab_addr, &symtab_len))
    3.99 -        goto error_out;
   3.100 -
   3.101 -    /* ksize is kernel-image size rounded up to a page boundary. */
   3.102 -
   3.103 -    alloc_index = tot_pages - 1;
   3.104 -
   3.105 -    /* Count bottom-level PTs, rounding up. */
   3.106 -    num_pt_pages = (l1_table_offset(*virt_load_addr) + tot_pages + 1023)
   3.107 -        / 1024;
   3.108 -
   3.109 -    /* We must also count the page directory. */
   3.110 -    num_pt_pages++;
   3.111 -
   3.112 -    /* Index of first PT page. */
   3.113 -    pt_start = tot_pages - num_pt_pages;
   3.114 -
   3.115 -    /*
   3.116 -     * First allocate page for page dir. Allocation goes backwards from the end
   3.117 -     * of the allocated physical address space.
   3.118 -     */
   3.119 -    l2tab = page_array[alloc_index] << PAGE_SHIFT;
   3.120 -    alloc_index--;
   3.121 -    ctxt->pt_base = l2tab;
   3.122 -    
   3.123 -    if ( (mmu = init_mmu_updates(xc_handle, dom)) == NULL )
   3.124 -        goto error_out;
   3.125 -    
   3.126 -    /* Initialise the page tables. */
   3.127 -    if ( (vl2tab = xc_map_foreign_range(xc_handle, dom, PAGE_SIZE,
   3.128 -                                        PROT_READ|PROT_WRITE,
   3.129 -                                        l2tab >> PAGE_SHIFT)) == NULL )
   3.130 -        goto error_out;
   3.131 -    memset(vl2tab, 0, PAGE_SIZE);
   3.132 -    vl2e = &vl2tab[l2_table_offset(*virt_load_addr)];
   3.133 -    for ( count = 0; count < tot_pages; count++ )
   3.134 -    {
   3.135 -        if ( ((unsigned long)vl1e & (PAGE_SIZE-1)) == 0 )
   3.136 -        {
   3.137 -            l1tab = page_array[alloc_index--] << PAGE_SHIFT;
   3.138 -            if ( vl1tab != NULL )
   3.139 -                munmap(vl1tab, PAGE_SIZE);
   3.140 -            if ( (vl1tab = xc_map_foreign_range(xc_handle, dom, PAGE_SIZE,
   3.141 -                                                PROT_READ|PROT_WRITE,
   3.142 -                                                l1tab >> PAGE_SHIFT)) == NULL )
   3.143 -            {
   3.144 -                munmap(vl2tab, PAGE_SIZE);
   3.145 -                goto error_out;
   3.146 -            }
   3.147 -            memset(vl1tab, 0, PAGE_SIZE);
   3.148 -            vl1e = &vl1tab[l1_table_offset(*virt_load_addr + 
   3.149 -                                           (count<<PAGE_SHIFT))];
   3.150 -            *vl2e++ = l1tab | L2_PROT;
   3.151 -        }
   3.152 -
   3.153 -        *vl1e = (page_array[count] << PAGE_SHIFT) | L1_PROT;
   3.154 -        if ( count >= pt_start )
   3.155 -            *vl1e &= ~_PAGE_RW;
   3.156 -        vl1e++;
   3.157 -
   3.158 -        if ( add_mmu_update(xc_handle, mmu,
   3.159 -                            (page_array[count] << PAGE_SHIFT) | 
   3.160 -                            MMU_MACHPHYS_UPDATE, count) )
   3.161 -        {
   3.162 -            munmap(vl1tab, PAGE_SIZE);
   3.163 -            munmap(vl2tab, PAGE_SIZE);
   3.164 -            goto error_out;
   3.165 -        }
   3.166 -    }
   3.167 -    munmap(vl1tab, PAGE_SIZE);
   3.168 -    munmap(vl2tab, PAGE_SIZE);
   3.169 -
   3.170 -    /*
   3.171 -     * Pin down l2tab addr as page dir page - causes hypervisor to provide
   3.172 -     * correct protection for the page
   3.173 -     */ 
   3.174 -    if ( add_mmu_update(xc_handle, mmu,
   3.175 -                        l2tab | MMU_EXTENDED_COMMAND, MMUEXT_PIN_L2_TABLE) )
   3.176 -        goto error_out;
   3.177 -
   3.178 -    *virt_startinfo_addr =
   3.179 -        *virt_load_addr + ((alloc_index-1) << PAGE_SHIFT);
   3.180 -
   3.181 -    start_info = xc_map_foreign_range(
   3.182 -        xc_handle, dom, PAGE_SIZE, PROT_WRITE, page_array[alloc_index-1]);
   3.183 -    memset(start_info, 0, sizeof(*start_info));
   3.184 -    start_info->pt_base     = *virt_load_addr + ((tot_pages-1) << PAGE_SHIFT);
   3.185 -    start_info->mod_start   = symtab_addr;
   3.186 -    start_info->mod_len     = symtab_len;
   3.187 -    start_info->nr_pages    = tot_pages;
   3.188 -    start_info->shared_info = shared_info_frame << PAGE_SHIFT;
   3.189 -    start_info->flags       = 0;
   3.190 -    start_info->domain_controller_evtchn = control_evtchn;
   3.191 -    strncpy(start_info->cmd_line, cmdline, MAX_CMDLINE);
   3.192 -    start_info->cmd_line[MAX_CMDLINE-1] = '\0';
   3.193 -    munmap(start_info, PAGE_SIZE);
   3.194 -
   3.195 -    /* shared_info page starts its life empty. */
   3.196 -    shared_info = xc_map_foreign_range(
   3.197 -        xc_handle, dom, PAGE_SIZE, PROT_WRITE, shared_info_frame);
   3.198 -    memset(shared_info, 0, PAGE_SIZE);
   3.199 -    /* Mask all upcalls... */
   3.200 -    for ( i = 0; i < MAX_VIRT_CPUS; i++ )
   3.201 -        shared_info->vcpu_data[i].evtchn_upcall_mask = 1;
   3.202 -    munmap(shared_info, PAGE_SIZE);
   3.203 -
   3.204 -    /* Send the page update requests down to the hypervisor. */
   3.205 -    if ( finish_mmu_updates(xc_handle, mmu) )
   3.206 -        goto error_out;
   3.207 -
   3.208 -    free(mmu);
   3.209 -    free(page_array);
   3.210 -    return 0;
   3.211 -
   3.212 - error_out:
   3.213 -    if ( mmu != NULL )
   3.214 -        free(mmu);
   3.215 -    if ( page_array == NULL )
   3.216 -        free(page_array);
   3.217 -    return -1;
   3.218 -}
   3.219 -
   3.220 -int xc_netbsd_build(int xc_handle,
   3.221 -                    u32 domid,
   3.222 -                    const char *image_name,
   3.223 -                    const char *cmdline,
   3.224 -                    unsigned int control_evtchn)
   3.225 -{
   3.226 -    dom0_op_t launch_op, op;
   3.227 -    unsigned long load_addr;
   3.228 -    long tot_pages;
   3.229 -    int kernel_fd = -1;
   3.230 -    gzFile kernel_gfd = NULL;
   3.231 -    int rc, i;
   3.232 -    full_execution_context_t st_ctxt, *ctxt = &st_ctxt;
   3.233 -    unsigned long virt_startinfo_addr;
   3.234 -
   3.235 -    if ( (tot_pages = get_tot_pages(xc_handle, domid)) < 0 )
   3.236 -    {
   3.237 -        PERROR("Could not find total pages for domain");
   3.238 -        return 1;
   3.239 -    }
   3.240 -
   3.241 -    kernel_fd = open(image_name, O_RDONLY);
   3.242 -    if ( kernel_fd < 0 )
   3.243 -    {
   3.244 -        PERROR("Could not open kernel image");
   3.245 -        return 1;
   3.246 -    }
   3.247 -
   3.248 -    if ( (kernel_gfd = gzdopen(kernel_fd, "rb")) == NULL )
   3.249 -    {
   3.250 -        PERROR("Could not allocate decompression state for state file");
   3.251 -        close(kernel_fd);
   3.252 -        return 1;
   3.253 -    }
   3.254 -
   3.255 -    if ( mlock(&st_ctxt, sizeof(st_ctxt) ) )
   3.256 -    {   
   3.257 -        PERROR("Unable to mlock ctxt");
   3.258 -        return 1;
   3.259 -    }
   3.260 -
   3.261 -    op.cmd = DOM0_GETDOMAININFO;
   3.262 -    op.u.getdomaininfo.domain = (domid_t)domid;
   3.263 -    op.u.getdomaininfo.ctxt = ctxt;
   3.264 -    if ( (do_dom0_op(xc_handle, &op) < 0) || 
   3.265 -         ((u16)op.u.getdomaininfo.domain != domid) )
   3.266 -    {
   3.267 -        PERROR("Could not get info on domain");
   3.268 -        goto error_out;
   3.269 -    }
   3.270 -    if ( !(op.u.getdomaininfo.flags & DOMFLAGS_PAUSED) ||
   3.271 -         (op.u.getdomaininfo.ctxt->pt_base != 0) )
   3.272 -    {
   3.273 -        ERROR("Domain is already constructed");
   3.274 -        goto error_out;
   3.275 -    }
   3.276 -
   3.277 -    if ( setup_guestos(xc_handle, domid, kernel_gfd, tot_pages,
   3.278 -                       &virt_startinfo_addr,
   3.279 -                       &load_addr, &st_ctxt, cmdline,
   3.280 -                       op.u.getdomaininfo.shared_info_frame,
   3.281 -                       control_evtchn) < 0 )
   3.282 -    {
   3.283 -        ERROR("Error constructing guest OS");
   3.284 -        goto error_out;
   3.285 -    }
   3.286 -
   3.287 -    if ( kernel_fd >= 0 )
   3.288 -        close(kernel_fd);
   3.289 -    if( kernel_gfd )
   3.290 -        gzclose(kernel_gfd);
   3.291 -
   3.292 -    ctxt->flags = 0;
   3.293 -
   3.294 -    /*
   3.295 -     * Initial register values:
   3.296 -     *  DS,ES,FS,GS = FLAT_GUESTOS_DS
   3.297 -     *       CS:EIP = FLAT_GUESTOS_CS:start_pc
   3.298 -     *       SS:ESP = FLAT_GUESTOS_DS:start_stack
   3.299 -     *          ESI = start_info
   3.300 -     *  [EAX,EBX,ECX,EDX,EDI,EBP are zero]
   3.301 -     *       EFLAGS = IF | 2 (bit 1 is reserved and should always be 1)
   3.302 -     */
   3.303 -    ctxt->cpu_ctxt.ds = FLAT_GUESTOS_DS;
   3.304 -    ctxt->cpu_ctxt.es = FLAT_GUESTOS_DS;
   3.305 -    ctxt->cpu_ctxt.fs = FLAT_GUESTOS_DS;
   3.306 -    ctxt->cpu_ctxt.gs = FLAT_GUESTOS_DS;
   3.307 -    ctxt->cpu_ctxt.ss = FLAT_GUESTOS_DS;
   3.308 -    ctxt->cpu_ctxt.cs = FLAT_GUESTOS_CS;
   3.309 -    ctxt->cpu_ctxt.eip = load_addr;
   3.310 -    ctxt->cpu_ctxt.esp = virt_startinfo_addr;
   3.311 -    ctxt->cpu_ctxt.esi = virt_startinfo_addr;
   3.312 -    ctxt->cpu_ctxt.eflags = (1<<9) | (1<<2);
   3.313 -
   3.314 -    /* FPU is set up to default initial state. */
   3.315 -    memset(ctxt->fpu_ctxt, 0, sizeof(ctxt->fpu_ctxt));
   3.316 -
   3.317 -    /* Virtual IDT is empty at start-of-day. */
   3.318 -    for ( i = 0; i < 256; i++ )
   3.319 -    {
   3.320 -        ctxt->trap_ctxt[i].vector = i;
   3.321 -        ctxt->trap_ctxt[i].cs     = FLAT_GUESTOS_CS;
   3.322 -    }
   3.323 -    ctxt->fast_trap_idx = 0;
   3.324 -
   3.325 -    /* No LDT. */
   3.326 -    ctxt->ldt_ents = 0;
   3.327 -    
   3.328 -    /* Use the default Xen-provided GDT. */
   3.329 -    ctxt->gdt_ents = 0;
   3.330 -
   3.331 -    /* Ring 1 stack is the initial stack. */
   3.332 -    ctxt->guestos_ss  = FLAT_GUESTOS_DS;
   3.333 -    ctxt->guestos_esp = virt_startinfo_addr;
   3.334 -
   3.335 -    /* No debugging. */
   3.336 -    memset(ctxt->debugreg, 0, sizeof(ctxt->debugreg));
   3.337 -
   3.338 -    /* No callback handlers. */
   3.339 -    ctxt->event_callback_cs     = FLAT_GUESTOS_CS;
   3.340 -    ctxt->event_callback_eip    = 0;
   3.341 -    ctxt->failsafe_callback_cs  = FLAT_GUESTOS_CS;
   3.342 -    ctxt->failsafe_callback_eip = 0;
   3.343 -
   3.344 -    memset( &launch_op, 0, sizeof(launch_op) );
   3.345 -
   3.346 -    launch_op.u.builddomain.domain   = (domid_t)domid;
   3.347 -    launch_op.u.builddomain.ctxt = ctxt;
   3.348 -    launch_op.cmd = DOM0_BUILDDOMAIN;
   3.349 -    rc = do_dom0_op(xc_handle, &launch_op);
   3.350 -    
   3.351 -    return rc;
   3.352 -
   3.353 - error_out:
   3.354 -    if ( kernel_fd >= 0 )
   3.355 -        close(kernel_fd);
   3.356 -    if( kernel_gfd )
   3.357 -        gzclose(kernel_gfd);
   3.358 -
   3.359 -    return -1;
   3.360 -}
   3.361 -
   3.362 -#define MYSEEK_BUFSIZE 1024
   3.363 -static off_t
   3.364 -myseek(gzFile gfd, off_t offset, int whence)
   3.365 -{
   3.366 -    unsigned char tmp[MYSEEK_BUFSIZE];
   3.367 -    int c;
   3.368 -
   3.369 -    if ( offset < 0 )
   3.370 -    {
   3.371 -        ERROR("seek back not supported");
   3.372 -        return -1;
   3.373 -    }
   3.374 -
   3.375 -    while ( offset != 0 )
   3.376 -    {
   3.377 -        c = offset;
   3.378 -        if ( c > MYSEEK_BUFSIZE )
   3.379 -            c = MYSEEK_BUFSIZE;
   3.380 -        if ( gzread(gfd, tmp, c) != c )
   3.381 -        {
   3.382 -            PERROR("Error seeking in image.");
   3.383 -            return -1;
   3.384 -        }
   3.385 -        offset -= c;
   3.386 -    }
   3.387 -
   3.388 -    return 0;   /* XXX */
   3.389 -}
   3.390 -
   3.391 -/* 
   3.392 - * NetBSD memory layout:
   3.393 - *
   3.394 - * ---------------- *virt_load_addr = ehdr.e_entry (0xc0100000)
   3.395 - * | kernel text  |
   3.396 - * |              |
   3.397 - * ----------------
   3.398 - * | kernel data  |
   3.399 - * |              |
   3.400 - * ----------------
   3.401 - * | kernel bss   |
   3.402 - * |              |
   3.403 - * ---------------- *symtab_addr
   3.404 - * | symtab size  |   = *symtab_len
   3.405 - * ----------------
   3.406 - * | elf header   |   offsets to symbol sections mangled to be relative
   3.407 - * |              |   to headers location
   3.408 - * ----------------
   3.409 - * | sym section  |
   3.410 - * | headers      |
   3.411 - * ----------------
   3.412 - * | sym sections |
   3.413 - * |              |
   3.414 - * ---------------- *symtab_addr + *symtab_len
   3.415 - * | padding      |
   3.416 - * ---------------- ehdr.e_entry + *ksize << PAGE_SHIFT
   3.417 - */
   3.418 -
   3.419 -#define IS_TEXT(p) (p.p_flags & PF_X)
   3.420 -#define IS_DATA(p) (p.p_flags & PF_W)
   3.421 -#define IS_BSS(p) (p.p_filesz < p.p_memsz)
   3.422 -
   3.423 -static int
   3.424 -loadelfimage(gzFile kernel_gfd, int xch, u32 dom, unsigned long *page_array,
   3.425 -             unsigned long tot_pages, unsigned long *virt_load_addr,
   3.426 -             unsigned long *ksize, unsigned long *symtab_addr,
   3.427 -             unsigned long *symtab_len)
   3.428 -{
   3.429 -    Elf_Ehdr ehdr;
   3.430 -    Elf_Phdr *phdr;
   3.431 -    Elf_Shdr *shdr;
   3.432 -    void *vaddr;
   3.433 -    char page[PAGE_SIZE], *p;
   3.434 -    unsigned long iva, maxva, symva;
   3.435 -    int c, curpos, h, i, ret, s;
   3.436 -
   3.437 -    ret = -1;
   3.438 -    phdr = NULL;
   3.439 -    p = NULL;
   3.440 -    maxva = 0;
   3.441 -
   3.442 -    if ( gzread(kernel_gfd, &ehdr, sizeof(Elf_Ehdr)) != sizeof(Elf_Ehdr) )
   3.443 -    {
   3.444 -        PERROR("Error reading kernel image ELF header.");
   3.445 -        goto out;
   3.446 -    }
   3.447 -    curpos = sizeof(Elf_Ehdr);
   3.448 -
   3.449 -    if ( !IS_ELF(ehdr) )
   3.450 -    {
   3.451 -        PERROR("Image does not have an ELF header.");
   3.452 -        goto out;
   3.453 -    }
   3.454 -
   3.455 -    *virt_load_addr = ehdr.e_entry;
   3.456 -
   3.457 -    if ( (*virt_load_addr & (PAGE_SIZE-1)) != 0 )
   3.458 -    {
   3.459 -        ERROR("We can only deal with page-aligned load addresses");
   3.460 -        goto out;
   3.461 -    }
   3.462 -
   3.463 -    if ( (*virt_load_addr + (tot_pages << PAGE_SHIFT)) > 
   3.464 -         HYPERVISOR_VIRT_START )
   3.465 -    {
   3.466 -        ERROR("Cannot map all domain memory without hitting Xen space");
   3.467 -        goto out;
   3.468 -    }
   3.469 -
   3.470 -
   3.471 -    phdr = malloc(ehdr.e_phnum * sizeof(Elf_Phdr));
   3.472 -    if ( phdr == NULL )
   3.473 -    {
   3.474 -        ERROR("Cannot allocate memory for Elf_Phdrs");
   3.475 -        goto out;
   3.476 -    }
   3.477 -
   3.478 -    if ( myseek(kernel_gfd, ehdr.e_phoff - curpos, SEEK_SET) == -1 )
   3.479 -    {
   3.480 -        ERROR("Seek to program header failed");
   3.481 -        goto out;
   3.482 -    }
   3.483 -    curpos = ehdr.e_phoff;
   3.484 -
   3.485 -    if ( gzread(kernel_gfd, phdr, ehdr.e_phnum * sizeof(Elf_Phdr)) !=
   3.486 -         ehdr.e_phnum * sizeof(Elf_Phdr) )
   3.487 -    {
   3.488 -        PERROR("Error reading kernel image ELF program header.");
   3.489 -        goto out;
   3.490 -    }
   3.491 -    curpos += ehdr.e_phnum * sizeof(Elf_Phdr);
   3.492 -
   3.493 -    /* Copy run-time 'load' segments that are writeable and/or executable. */
   3.494 -    for ( h = 0; h < ehdr.e_phnum; h++ ) 
   3.495 -    {
   3.496 -        if ( (phdr[h].p_type != PT_LOAD) ||
   3.497 -             ((phdr[h].p_flags & (PF_W|PF_X)) == 0) )
   3.498 -            continue;
   3.499 -
   3.500 -        if ( IS_TEXT(phdr[h]) || IS_DATA(phdr[h]) )
   3.501 -        {
   3.502 -            if ( myseek(kernel_gfd, phdr[h].p_offset - curpos, 
   3.503 -                        SEEK_SET) == -1 )
   3.504 -            {
   3.505 -                ERROR("Seek to section failed");
   3.506 -                goto out;
   3.507 -            }
   3.508 -            curpos = phdr[h].p_offset;
   3.509 -
   3.510 -            for ( iva = phdr[h].p_vaddr;
   3.511 -                  iva < phdr[h].p_vaddr + phdr[h].p_filesz; 
   3.512 -                  iva += c)
   3.513 -            {
   3.514 -                c = PAGE_SIZE - (iva & (PAGE_SIZE - 1));
   3.515 -                if (iva + c > phdr[h].p_vaddr + phdr[h].p_filesz)
   3.516 -                    c = phdr[h].p_vaddr + phdr[h].p_filesz - iva;
   3.517 -                if ( gzread(kernel_gfd, page, c) != c )
   3.518 -                {
   3.519 -                    PERROR("Error reading kernel image page.");
   3.520 -                    goto out;
   3.521 -                }
   3.522 -                curpos += c;
   3.523 -                vaddr = xc_map_foreign_range(
   3.524 -                    xch, dom, PAGE_SIZE, PROT_WRITE, 
   3.525 -                    page_array[(iva - *virt_load_addr) >> PAGE_SHIFT]);
   3.526 -                if ( vaddr == NULL )
   3.527 -                {
   3.528 -                    ERROR("Couldn't map guest memory");
   3.529 -                    goto out;
   3.530 -                }
   3.531 -                DPRINTF(("copy page %p to %p, count 0x%x\n", (void *)iva,
   3.532 -                         vaddr + (iva & (PAGE_SIZE - 1)), c));
   3.533 -                memcpy(vaddr + (iva & (PAGE_SIZE - 1)), page, c);
   3.534 -                munmap(vaddr, PAGE_SIZE);
   3.535 -            }
   3.536 -
   3.537 -            if ( phdr[h].p_vaddr + phdr[h].p_filesz > maxva )
   3.538 -                maxva = phdr[h].p_vaddr + phdr[h].p_filesz;
   3.539 -        }
   3.540 -
   3.541 -        if ( IS_BSS(phdr[h]) )
   3.542 -        {
   3.543 -            /* XXX maybe clear phdr[h].p_memsz bytes from
   3.544 -               phdr[h].p_vaddr + phdr[h].p_filesz ??? */
   3.545 -            if (phdr[h].p_vaddr + phdr[h].p_memsz > maxva)
   3.546 -                maxva = phdr[h].p_vaddr + phdr[h].p_memsz;
   3.547 -            DPRINTF(("bss from %p to %p, maxva %p\n",
   3.548 -                     (void *)(phdr[h].p_vaddr + phdr[h].p_filesz),
   3.549 -                     (void *)(phdr[h].p_vaddr + phdr[h].p_memsz),
   3.550 -                     (void *)maxva));
   3.551 -        }
   3.552 -    }
   3.553 -
   3.554 -    p = malloc(sizeof(int) + sizeof(Elf_Ehdr) +
   3.555 -               ehdr.e_shnum * sizeof(Elf_Shdr));
   3.556 -    if ( p == NULL )
   3.557 -    {
   3.558 -        ERROR("Cannot allocate memory for Elf_Shdrs");
   3.559 -        goto out;
   3.560 -    }
   3.561 -
   3.562 -    shdr = (Elf_Shdr *)(p + sizeof(int) + sizeof(Elf_Ehdr));
   3.563 -
   3.564 -    if ( myseek(kernel_gfd, ehdr.e_shoff - curpos, SEEK_SET) == -1 )
   3.565 -    {
   3.566 -        ERROR("Seek to symbol header failed");
   3.567 -        goto out;
   3.568 -    }
   3.569 -    curpos = ehdr.e_shoff;
   3.570 -
   3.571 -    if ( gzread(kernel_gfd, shdr, ehdr.e_shnum * sizeof(Elf_Shdr)) !=
   3.572 -         ehdr.e_shnum * sizeof(Elf_Shdr) ) 
   3.573 -    {
   3.574 -        PERROR("Error reading kernel image ELF symbol header.");
   3.575 -        goto out;
   3.576 -    }
   3.577 -    curpos += ehdr.e_shnum * sizeof(Elf_Shdr);
   3.578 -
   3.579 -    maxva = (maxva + ELFROUND - 1) & ~(ELFROUND - 1);
   3.580 -    symva = maxva;
   3.581 -    maxva += sizeof(int);
   3.582 -    *symtab_addr = maxva;
   3.583 -    *symtab_len = 0;
   3.584 -    maxva += sizeof(Elf_Ehdr) + ehdr.e_shnum * sizeof(Elf_Shdr);
   3.585 -    maxva = (maxva + ELFROUND - 1) & ~(ELFROUND - 1);
   3.586 -
   3.587 -    /* Copy kernel string / symbol tables into physical memory */
   3.588 -    for ( h = 0; h < ehdr.e_shnum; h++ )
   3.589 -    {
   3.590 -        if ( shdr[h].sh_type == SHT_STRTAB )
   3.591 -        {
   3.592 -            /* Look for a strtab @i linked to symtab @h. */
   3.593 -            for ( i = 0; i < ehdr.e_shnum; i++ )
   3.594 -                if ( (shdr[i].sh_type == SHT_SYMTAB) &&
   3.595 -                     (shdr[i].sh_link == h) )
   3.596 -                    break;
   3.597 -            /* Skip symtab @h if we found no corresponding strtab @i. */
   3.598 -            if ( i == ehdr.e_shnum )
   3.599 -            {
   3.600 -                shdr[h].sh_offset = 0;
   3.601 -                continue;
   3.602 -            }
   3.603 -        }
   3.604 -
   3.605 -        if ( (shdr[h].sh_type == SHT_STRTAB) ||
   3.606 -             (shdr[h].sh_type == SHT_SYMTAB) )
   3.607 -        {
   3.608 -            if ( myseek(kernel_gfd, shdr[h].sh_offset - curpos, 
   3.609 -                        SEEK_SET) == -1 )
   3.610 -            {
   3.611 -                ERROR("Seek to symbol section failed");
   3.612 -                goto out;
   3.613 -            }
   3.614 -            curpos = shdr[h].sh_offset;
   3.615 -
   3.616 -            /* Mangled to be based on ELF header location. */
   3.617 -            shdr[h].sh_offset = maxva - *symtab_addr;
   3.618 -
   3.619 -            DPRINTF(("copy section %d, size 0x%x\n", h, shdr[h].sh_size));
   3.620 -            for ( i = 0; i < shdr[h].sh_size; i += c, maxva += c )
   3.621 -            {
   3.622 -                c = PAGE_SIZE - (maxva & (PAGE_SIZE - 1));
   3.623 -                if ( c > (shdr[h].sh_size - i) )
   3.624 -                    c = shdr[h].sh_size - i;
   3.625 -                if ( gzread(kernel_gfd, page, c) != c )
   3.626 -                {
   3.627 -                    PERROR("Error reading kernel image page.");
   3.628 -                    goto out;
   3.629 -                }
   3.630 -                curpos += c;
   3.631 -
   3.632 -                vaddr = xc_map_foreign_range(
   3.633 -                    xch, dom, PAGE_SIZE, PROT_WRITE,
   3.634 -                    page_array[(maxva - *virt_load_addr) >> PAGE_SHIFT]);
   3.635 -                if ( vaddr == NULL )
   3.636 -                {
   3.637 -                    ERROR("Couldn't map guest memory");
   3.638 -                    goto out;
   3.639 -                }
   3.640 -                DPRINTF(("copy page %p to %p, count 0x%x\n", (void *)maxva,
   3.641 -                         vaddr + (maxva & (PAGE_SIZE - 1)), c));
   3.642 -                memcpy(vaddr + (maxva & (PAGE_SIZE - 1)), page, c);
   3.643 -                munmap(vaddr, PAGE_SIZE);
   3.644 -            }
   3.645 -
   3.646 -            *symtab_len += shdr[h].sh_size;
   3.647 -            maxva = (maxva + ELFROUND - 1) & ~(ELFROUND - 1);
   3.648 -
   3.649 -        }
   3.650 -        shdr[h].sh_name = 0;  /* Name is NULL. */
   3.651 -    }
   3.652 -
   3.653 -    if ( *symtab_len == 0 ) 
   3.654 -    {
   3.655 -        DPRINTF(("no symbol table\n"));
   3.656 -        *symtab_addr = 0;
   3.657 -        ret = 0;
   3.658 -        goto out;
   3.659 -    }
   3.660 -
   3.661 -    DPRINTF(("sym header va %p from %p/%p size %x/%x\n", (void *)symva,
   3.662 -             shdr, p, ehdr.e_shnum * sizeof(Elf_Shdr),
   3.663 -             ehdr.e_shnum * sizeof(Elf_Shdr) + sizeof(Elf_Ehdr)));
   3.664 -    ehdr.e_phoff = 0;
   3.665 -    ehdr.e_shoff = sizeof(Elf_Ehdr);
   3.666 -    ehdr.e_phentsize = 0;
   3.667 -    ehdr.e_phnum = 0;
   3.668 -    ehdr.e_shstrndx = SHN_UNDEF;
   3.669 -    memcpy(p + sizeof(int), &ehdr, sizeof(Elf_Ehdr));
   3.670 -    *(int *)p = maxva - *symtab_addr;
   3.671 -
   3.672 -    /* Copy total length, crafted ELF header and section header table */
   3.673 -    s = sizeof(int) + sizeof(Elf_Ehdr) + ehdr.e_shnum * sizeof(Elf_Shdr);
   3.674 -    for ( i = 0; i < s; i += c, symva += c ) 
   3.675 -    {
   3.676 -        c = PAGE_SIZE - (symva & (PAGE_SIZE - 1));
   3.677 -        if ( c > s - i )
   3.678 -            c = s - i;
   3.679 -        vaddr = xc_map_foreign_range(
   3.680 -            xch, dom, PAGE_SIZE, PROT_WRITE,
   3.681 -            page_array[(symva - *virt_load_addr) >> PAGE_SHIFT]);
   3.682 -        if ( vaddr == NULL )
   3.683 -        {
   3.684 -            ERROR("Couldn't map guest memory");
   3.685 -            goto out;
   3.686 -        }
   3.687 -        DPRINTF(("copy page %p to %p, count 0x%x\n", (void *)symva,
   3.688 -                 vaddr + (symva & (PAGE_SIZE - 1)), c));
   3.689 -        memcpy(vaddr + (symva & (PAGE_SIZE - 1)), p + i, c);
   3.690 -        munmap(vaddr, PAGE_SIZE);
   3.691 -    }
   3.692 -
   3.693 -    *symtab_len = maxva - *symtab_addr;
   3.694 -
   3.695 -    ret = 0;
   3.696 -
   3.697 - out:
   3.698 -    if ( ret == 0 )
   3.699 -    {
   3.700 -        maxva = (maxva + PAGE_SIZE - 1) & ~(PAGE_SIZE - 1);
   3.701 -        *ksize = (maxva - *virt_load_addr) >> PAGE_SHIFT;
   3.702 -
   3.703 -        DPRINTF(("virt_addr %p, kpages 0x%lx, symtab_addr %p, symtab_len %p\n",
   3.704 -                 (void *)*virt_load_addr, *ksize, (void *)*symtab_addr,
   3.705 -                 (void *)*symtab_len));
   3.706 -    }
   3.707 -
   3.708 -    if ( phdr != NULL )
   3.709 -        free(phdr);
   3.710 -    if ( p != NULL )
   3.711 -        free(p);
   3.712 -    return ret;
   3.713 -}