ia64/xen-unstable

changeset 13968:0d488e53446a

Remove old elf-parsing code from tools and from Xen.
Signed-off-by: Keir Fraser <keir@xensource.com>
author kfraser@localhost.localdomain
date Thu Feb 15 10:25:39 2007 +0000 (2007-02-15)
parents 82f66bc01da2
children 047b3e9f9032
files 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.c tools/libxc/xg_private.h xen/common/elf.c
line diff
     1.1 --- a/tools/libxc/Makefile	Wed Feb 14 12:18:32 2007 -0800
     1.2 +++ b/tools/libxc/Makefile	Thu Feb 15 10:25:39 2007 +0000
     1.3 @@ -22,11 +22,7 @@ CTRL_SRCS-$(CONFIG_SunOS) += xc_solaris.
     1.4  CTRL_SRCS-$(CONFIG_X86_Linux) += xc_ptrace.c xc_ptrace_core.c
     1.5  
     1.6  GUEST_SRCS-y :=
     1.7 -GUEST_SRCS-y += xc_load_bin.c
     1.8 -GUEST_SRCS-y += xc_load_elf.c
     1.9  GUEST_SRCS-y += xg_private.c
    1.10 -#GUEST_SRCS-$(CONFIG_X86) += xc_linux_build.c
    1.11 -#GUEST_SRCS-$(CONFIG_IA64) += xc_linux_build.c
    1.12  GUEST_SRCS-$(CONFIG_MIGRATE) += xc_linux_restore.c xc_linux_save.c
    1.13  GUEST_SRCS-$(CONFIG_HVM) += xc_hvm_build.c xc_hvm_restore.c xc_hvm_save.c
    1.14  
     2.1 --- a/tools/libxc/xc_linux_build.c	Wed Feb 14 12:18:32 2007 -0800
     2.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
     2.3 @@ -1,1319 +0,0 @@
     2.4 -/******************************************************************************
     2.5 - * xc_linux_build.c
     2.6 - */
     2.7 -
     2.8 -#include <stddef.h>
     2.9 -#include "xg_private.h"
    2.10 -#include "xc_private.h"
    2.11 -#include <xenctrl.h>
    2.12 -
    2.13 -#include "xc_elf.h"
    2.14 -#include <stdlib.h>
    2.15 -#include <unistd.h>
    2.16 -#include <inttypes.h>
    2.17 -#include <zlib.h>
    2.18 -
    2.19 -/* Handy for printing out '0' prepended values at native pointer size */
    2.20 -#define _p(a) ((void *) ((ulong)a))
    2.21 -
    2.22 -#define L1_PROT (_PAGE_PRESENT|_PAGE_RW|_PAGE_ACCESSED)
    2.23 -#define L2_PROT (_PAGE_PRESENT|_PAGE_RW|_PAGE_ACCESSED|_PAGE_DIRTY|_PAGE_USER)
    2.24 -#if defined(__i386__)
    2.25 -#define L3_PROT (_PAGE_PRESENT)
    2.26 -#elif defined(__x86_64__)
    2.27 -#define L3_PROT (_PAGE_PRESENT|_PAGE_RW|_PAGE_ACCESSED|_PAGE_DIRTY|_PAGE_USER)
    2.28 -#define L4_PROT (_PAGE_PRESENT|_PAGE_RW|_PAGE_ACCESSED|_PAGE_DIRTY|_PAGE_USER)
    2.29 -#endif
    2.30 -
    2.31 -#define round_pgup(_p)    (((_p)+(PAGE_SIZE-1))&PAGE_MASK)
    2.32 -#define round_pgdown(_p)  ((_p)&PAGE_MASK)
    2.33 -
    2.34 -struct initrd_info {
    2.35 -    enum { INITRD_none, INITRD_file, INITRD_mem } type;
    2.36 -    /*
    2.37 -     * .len must be filled in by the user for type==INITRD_mem. It is
    2.38 -     * filled in by load_initrd() for INITRD_file and unused for
    2.39 -     * INITRD_none.
    2.40 -     */
    2.41 -    unsigned long len;
    2.42 -    union {
    2.43 -        gzFile file_handle;
    2.44 -        char *mem_addr;
    2.45 -    } u;
    2.46 -};
    2.47 -
    2.48 -static const char *feature_names[XENFEAT_NR_SUBMAPS*32] = {
    2.49 -    [XENFEAT_writable_page_tables]       = "writable_page_tables",
    2.50 -    [XENFEAT_writable_descriptor_tables] = "writable_descriptor_tables",
    2.51 -    [XENFEAT_auto_translated_physmap]    = "auto_translated_physmap",
    2.52 -    [XENFEAT_supervisor_mode_kernel]     = "supervisor_mode_kernel",
    2.53 -    [XENFEAT_pae_pgdir_above_4gb]        = "pae_pgdir_above_4gb"
    2.54 -};
    2.55 -
    2.56 -static inline void set_feature_bit (int nr, uint32_t *addr)
    2.57 -{
    2.58 -    addr[nr>>5] |= (1<<(nr&31));
    2.59 -}
    2.60 -
    2.61 -static inline int test_feature_bit(int nr, uint32_t *addr)
    2.62 -{
    2.63 -    return !!(addr[nr>>5] & (1<<(nr&31)));
    2.64 -}
    2.65 -
    2.66 -static int parse_features(
    2.67 -    const char *feats,
    2.68 -    uint32_t supported[XENFEAT_NR_SUBMAPS],
    2.69 -    uint32_t required[XENFEAT_NR_SUBMAPS])
    2.70 -{
    2.71 -    const char *end, *p;
    2.72 -    int i, req;
    2.73 -
    2.74 -    if ( (end = strchr(feats, ',')) == NULL )
    2.75 -        end = feats + strlen(feats);
    2.76 -
    2.77 -    while ( feats < end )
    2.78 -    {
    2.79 -        p = strchr(feats, '|');
    2.80 -        if ( (p == NULL) || (p > end) )
    2.81 -            p = end;
    2.82 -
    2.83 -        req = (*feats == '!');
    2.84 -        if ( req )
    2.85 -            feats++;
    2.86 -
    2.87 -        for ( i = 0; i < XENFEAT_NR_SUBMAPS*32; i++ )
    2.88 -        {
    2.89 -            if ( feature_names[i] == NULL )
    2.90 -                continue;
    2.91 -
    2.92 -            if ( strncmp(feature_names[i], feats, p-feats) == 0 )
    2.93 -            {
    2.94 -                set_feature_bit(i, supported);
    2.95 -                if ( required && req )
    2.96 -                    set_feature_bit(i, required);
    2.97 -                break;
    2.98 -            }
    2.99 -        }
   2.100 -
   2.101 -        if ( i == XENFEAT_NR_SUBMAPS*32 )
   2.102 -        {
   2.103 -            ERROR("Unknown feature \"%.*s\".", (int)(p-feats), feats);
   2.104 -            if ( req )
   2.105 -            {
   2.106 -                ERROR("Kernel requires an unknown hypervisor feature.");
   2.107 -                return -EINVAL;
   2.108 -            }
   2.109 -        }
   2.110 -
   2.111 -        feats = p;
   2.112 -        if ( *feats == '|' )
   2.113 -            feats++;
   2.114 -    }
   2.115 -
   2.116 -    return -EINVAL;
   2.117 -}
   2.118 -
   2.119 -static int probeimageformat(const char *image,
   2.120 -                            unsigned long image_size,
   2.121 -                            struct load_funcs *load_funcs)
   2.122 -{
   2.123 -    if ( probe_elf(image, image_size, load_funcs) &&
   2.124 -         probe_bin(image, image_size, load_funcs) )
   2.125 -    {
   2.126 -        xc_set_error(XC_INVALID_KERNEL, "Not a valid ELF or raw kernel image");
   2.127 -        return -EINVAL;
   2.128 -    }
   2.129 -
   2.130 -    return 0;
   2.131 -}
   2.132 -
   2.133 -static int load_initrd(int xc_handle, domid_t dom,
   2.134 -                struct initrd_info *initrd,
   2.135 -                unsigned long physbase,
   2.136 -                xen_pfn_t *phys_to_mach)
   2.137 -{
   2.138 -    char page[PAGE_SIZE];
   2.139 -    unsigned long pfn_start, pfn;
   2.140 -
   2.141 -    if ( initrd->type == INITRD_none )
   2.142 -        return 0;
   2.143 -
   2.144 -    pfn_start = physbase >> PAGE_SHIFT;
   2.145 -
   2.146 -    if ( initrd->type == INITRD_mem )
   2.147 -    {
   2.148 -        unsigned long nr_pages  = (initrd->len + PAGE_SIZE - 1) >> PAGE_SHIFT;
   2.149 -
   2.150 -        for ( pfn = pfn_start; pfn < (pfn_start + nr_pages); pfn++ )
   2.151 -        {
   2.152 -            xc_copy_to_domain_page(
   2.153 -                xc_handle, dom, phys_to_mach[pfn],
   2.154 -                &initrd->u.mem_addr[(pfn - pfn_start) << PAGE_SHIFT]);
   2.155 -        }
   2.156 -    }
   2.157 -    else
   2.158 -    {
   2.159 -        int readlen;
   2.160 -
   2.161 -        pfn = pfn_start;
   2.162 -        initrd->len = 0;
   2.163 -
   2.164 -        /* gzread returns 0 on EOF */
   2.165 -        while ( (readlen = gzread(initrd->u.file_handle, page, PAGE_SIZE)) )
   2.166 -        {
   2.167 -            if ( readlen < 0 )
   2.168 -            {
   2.169 -                PERROR("Error reading initrd image, could not");
   2.170 -                return -EINVAL;
   2.171 -            }
   2.172 -
   2.173 -            initrd->len += readlen;
   2.174 -            xc_copy_to_domain_page(xc_handle, dom, phys_to_mach[pfn++], page);
   2.175 -        }
   2.176 -    }
   2.177 -
   2.178 -    return 0;
   2.179 -}
   2.180 -
   2.181 -#define alloc_pt(ltab, vltab)                                           \
   2.182 -do {                                                                    \
   2.183 -    ltab = ppt_alloc++;                                                 \
   2.184 -    ltab = (uint64_t)page_array[ltab] << PAGE_SHIFT;                    \
   2.185 -    if ( vltab != NULL )                                                \
   2.186 -        munmap(vltab, PAGE_SIZE);                                       \
   2.187 -    if ( (vltab = xc_map_foreign_range(xc_handle, dom, PAGE_SIZE,       \
   2.188 -                                       PROT_READ|PROT_WRITE,            \
   2.189 -                                       ltab >> PAGE_SHIFT)) == NULL )   \
   2.190 -        goto error_out;                                                 \
   2.191 -    memset(vltab, 0x0, PAGE_SIZE);                                      \
   2.192 -} while ( 0 )
   2.193 -
   2.194 -#if defined(__i386__)
   2.195 -
   2.196 -static int setup_pg_tables(int xc_handle, uint32_t dom,
   2.197 -                           vcpu_guest_context_t *ctxt,
   2.198 -                           unsigned long dsi_v_start,
   2.199 -                           unsigned long v_end,
   2.200 -                           xen_pfn_t *page_array,
   2.201 -                           unsigned long vpt_start,
   2.202 -                           unsigned long vpt_end,
   2.203 -                           unsigned shadow_mode_enabled)
   2.204 -{
   2.205 -    l1_pgentry_t *vl1tab=NULL, *vl1e=NULL;
   2.206 -    l2_pgentry_t *vl2tab=NULL, *vl2e=NULL;
   2.207 -    unsigned long l1tab = 0;
   2.208 -    unsigned long l2tab = 0;
   2.209 -    unsigned long ppt_alloc;
   2.210 -    unsigned long count;
   2.211 -
   2.212 -    ppt_alloc = (vpt_start - dsi_v_start) >> PAGE_SHIFT;
   2.213 -    alloc_pt(l2tab, vl2tab);
   2.214 -    vl2e = &vl2tab[l2_table_offset(dsi_v_start)];
   2.215 -    ctxt->ctrlreg[3] = xen_pfn_to_cr3(l2tab >> PAGE_SHIFT);
   2.216 -
   2.217 -    for ( count = 0; count < ((v_end - dsi_v_start) >> PAGE_SHIFT); count++ )
   2.218 -    {
   2.219 -        if ( ((unsigned long)vl1e & (PAGE_SIZE-1)) == 0 )
   2.220 -        {
   2.221 -            alloc_pt(l1tab, vl1tab);
   2.222 -            vl1e = &vl1tab[l1_table_offset(dsi_v_start + (count<<PAGE_SHIFT))];
   2.223 -            *vl2e++ = l1tab | L2_PROT;
   2.224 -        }
   2.225 -
   2.226 -        *vl1e = (page_array[count] << PAGE_SHIFT) | L1_PROT;
   2.227 -
   2.228 -        if ( !shadow_mode_enabled )
   2.229 -            if ( (count >= ((vpt_start-dsi_v_start)>>PAGE_SHIFT)) &&
   2.230 -                 (count <  ((vpt_end  -dsi_v_start)>>PAGE_SHIFT)) )
   2.231 -                *vl1e &= ~_PAGE_RW;
   2.232 -
   2.233 -        vl1e++;
   2.234 -    }
   2.235 -    munmap(vl1tab, PAGE_SIZE);
   2.236 -    munmap(vl2tab, PAGE_SIZE);
   2.237 -    return 0;
   2.238 -
   2.239 - error_out:
   2.240 -    if (vl1tab)
   2.241 -        munmap(vl1tab, PAGE_SIZE);
   2.242 -    if (vl2tab)
   2.243 -        munmap(vl2tab, PAGE_SIZE);
   2.244 -    return -1;
   2.245 -}
   2.246 -
   2.247 -static int setup_pg_tables_pae(int xc_handle, uint32_t dom,
   2.248 -                               vcpu_guest_context_t *ctxt,
   2.249 -                               unsigned long dsi_v_start,
   2.250 -                               unsigned long v_end,
   2.251 -                               xen_pfn_t *page_array,
   2.252 -                               unsigned long vpt_start,
   2.253 -                               unsigned long vpt_end,
   2.254 -                               unsigned shadow_mode_enabled,
   2.255 -                               unsigned pae_mode)
   2.256 -{
   2.257 -    l1_pgentry_64_t *vl1tab = NULL, *vl1e = NULL;
   2.258 -    l2_pgentry_64_t *vl2tab = NULL, *vl2e = NULL;
   2.259 -    l3_pgentry_64_t *vl3tab = NULL, *vl3e = NULL;
   2.260 -    uint64_t l1tab, l2tab, l3tab;
   2.261 -    unsigned long ppt_alloc, count, nmfn;
   2.262 -
   2.263 -    /* First allocate page for page dir. */
   2.264 -    ppt_alloc = (vpt_start - dsi_v_start) >> PAGE_SHIFT;
   2.265 -
   2.266 -    if ( pae_mode == PAEKERN_extended_cr3 )
   2.267 -    {
   2.268 -        ctxt->vm_assist |= (1UL << VMASST_TYPE_pae_extended_cr3);
   2.269 -    }
   2.270 -    else if ( page_array[ppt_alloc] > 0xfffff )
   2.271 -    {
   2.272 -        nmfn = xc_make_page_below_4G(xc_handle, dom, page_array[ppt_alloc]);
   2.273 -        if ( nmfn == 0 )
   2.274 -        {
   2.275 -            DPRINTF("Couldn't get a page below 4GB :-(\n");
   2.276 -            goto error_out;
   2.277 -        }
   2.278 -        page_array[ppt_alloc] = nmfn;
   2.279 -    }
   2.280 -
   2.281 -    alloc_pt(l3tab, vl3tab);
   2.282 -    vl3e = &vl3tab[l3_table_offset_pae(dsi_v_start)];
   2.283 -    ctxt->ctrlreg[3] = xen_pfn_to_cr3(l3tab >> PAGE_SHIFT);
   2.284 -
   2.285 -    for ( count = 0; count < ((v_end - dsi_v_start) >> PAGE_SHIFT); count++)
   2.286 -    {
   2.287 -        if ( !((unsigned long)vl1e & (PAGE_SIZE-1)) )
   2.288 -        {
   2.289 -            if ( !((unsigned long)vl2e & (PAGE_SIZE-1)) )
   2.290 -            {
   2.291 -                alloc_pt(l2tab, vl2tab);
   2.292 -                vl2e = &vl2tab[l2_table_offset_pae(
   2.293 -                    dsi_v_start + (count << PAGE_SHIFT))];
   2.294 -                *vl3e++ = l2tab | L3_PROT;
   2.295 -            }
   2.296 -
   2.297 -            alloc_pt(l1tab, vl1tab);
   2.298 -            vl1e = &vl1tab[l1_table_offset_pae(
   2.299 -                dsi_v_start + (count << PAGE_SHIFT))];
   2.300 -            *vl2e++ = l1tab | L2_PROT;
   2.301 -
   2.302 -        }
   2.303 -
   2.304 -        *vl1e = ((uint64_t)page_array[count] << PAGE_SHIFT) | L1_PROT;
   2.305 -
   2.306 -        if ( !shadow_mode_enabled )
   2.307 -            if ( (count >= ((vpt_start-dsi_v_start)>>PAGE_SHIFT)) &&
   2.308 -                 (count <  ((vpt_end  -dsi_v_start)>>PAGE_SHIFT)) )
   2.309 -                *vl1e &= ~_PAGE_RW;
   2.310 -
   2.311 -        vl1e++;
   2.312 -    }
   2.313 -
   2.314 -    /* Xen requires a mid-level pgdir mapping 0xC0000000 region. */
   2.315 -    if ( (vl3tab[3] & _PAGE_PRESENT) == 0 )
   2.316 -    {
   2.317 -        alloc_pt(l2tab, vl2tab);
   2.318 -        vl3tab[3] = l2tab | L3_PROT;
   2.319 -    }
   2.320 -
   2.321 -    munmap(vl1tab, PAGE_SIZE);
   2.322 -    munmap(vl2tab, PAGE_SIZE);
   2.323 -    munmap(vl3tab, PAGE_SIZE);
   2.324 -    return 0;
   2.325 -
   2.326 - error_out:
   2.327 -    if (vl1tab)
   2.328 -        munmap(vl1tab, PAGE_SIZE);
   2.329 -    if (vl2tab)
   2.330 -        munmap(vl2tab, PAGE_SIZE);
   2.331 -    if (vl3tab)
   2.332 -        munmap(vl3tab, PAGE_SIZE);
   2.333 -    return -1;
   2.334 -}
   2.335 -
   2.336 -#endif
   2.337 -
   2.338 -#if defined(__x86_64__)
   2.339 -
   2.340 -static int setup_pg_tables_64(int xc_handle, uint32_t dom,
   2.341 -                              vcpu_guest_context_t *ctxt,
   2.342 -                              unsigned long dsi_v_start,
   2.343 -                              unsigned long v_end,
   2.344 -                              xen_pfn_t *page_array,
   2.345 -                              unsigned long vpt_start,
   2.346 -                              unsigned long vpt_end,
   2.347 -                              int shadow_mode_enabled)
   2.348 -{
   2.349 -    l1_pgentry_t *vl1tab=NULL, *vl1e=NULL;
   2.350 -    l2_pgentry_t *vl2tab=NULL, *vl2e=NULL;
   2.351 -    l3_pgentry_t *vl3tab=NULL, *vl3e=NULL;
   2.352 -    l4_pgentry_t *vl4tab=NULL, *vl4e=NULL;
   2.353 -    unsigned long l2tab = 0;
   2.354 -    unsigned long l1tab = 0;
   2.355 -    unsigned long l3tab = 0;
   2.356 -    unsigned long l4tab = 0;
   2.357 -    unsigned long ppt_alloc;
   2.358 -    unsigned long count;
   2.359 -
   2.360 -    /* First allocate page for page dir. */
   2.361 -    ppt_alloc = (vpt_start - dsi_v_start) >> PAGE_SHIFT;
   2.362 -    alloc_pt(l4tab, vl4tab);
   2.363 -    vl4e = &vl4tab[l4_table_offset(dsi_v_start)];
   2.364 -    ctxt->ctrlreg[3] = xen_pfn_to_cr3(l4tab >> PAGE_SHIFT);
   2.365 -
   2.366 -    for ( count = 0; count < ((v_end-dsi_v_start)>>PAGE_SHIFT); count++)
   2.367 -    {
   2.368 -        if ( !((unsigned long)vl1e & (PAGE_SIZE-1)) )
   2.369 -        {
   2.370 -            alloc_pt(l1tab, vl1tab);
   2.371 -
   2.372 -            if ( !((unsigned long)vl2e & (PAGE_SIZE-1)) )
   2.373 -            {
   2.374 -                alloc_pt(l2tab, vl2tab);
   2.375 -                if ( !((unsigned long)vl3e & (PAGE_SIZE-1)) )
   2.376 -                {
   2.377 -                    alloc_pt(l3tab, vl3tab);
   2.378 -                    vl3e = &vl3tab[l3_table_offset(dsi_v_start + (count<<PAGE_SHIFT))];
   2.379 -                    *vl4e++ = l3tab | L4_PROT;
   2.380 -                }
   2.381 -                vl2e = &vl2tab[l2_table_offset(dsi_v_start + (count<<PAGE_SHIFT))];
   2.382 -                *vl3e++ = l2tab | L3_PROT;
   2.383 -            }
   2.384 -            vl1e = &vl1tab[l1_table_offset(dsi_v_start + (count<<PAGE_SHIFT))];
   2.385 -            *vl2e++ = l1tab | L2_PROT;
   2.386 -        }
   2.387 -
   2.388 -        *vl1e = (page_array[count] << PAGE_SHIFT) | L1_PROT;
   2.389 -
   2.390 -        if ( !shadow_mode_enabled )
   2.391 -            if ( (count >= ((vpt_start-dsi_v_start)>>PAGE_SHIFT)) &&
   2.392 -                 (count <  ((vpt_end  -dsi_v_start)>>PAGE_SHIFT)) )
   2.393 -                *vl1e &= ~_PAGE_RW;
   2.394 -
   2.395 -        vl1e++;
   2.396 -    }
   2.397 -
   2.398 -    munmap(vl1tab, PAGE_SIZE);
   2.399 -    munmap(vl2tab, PAGE_SIZE);
   2.400 -    munmap(vl3tab, PAGE_SIZE);
   2.401 -    munmap(vl4tab, PAGE_SIZE);
   2.402 -    return 0;
   2.403 -
   2.404 - error_out:
   2.405 -    if (vl1tab)
   2.406 -        munmap(vl1tab, PAGE_SIZE);
   2.407 -    if (vl2tab)
   2.408 -        munmap(vl2tab, PAGE_SIZE);
   2.409 -    if (vl3tab)
   2.410 -        munmap(vl3tab, PAGE_SIZE);
   2.411 -    if (vl4tab)
   2.412 -        munmap(vl4tab, PAGE_SIZE);
   2.413 -    return -1;
   2.414 -}
   2.415 -#endif
   2.416 -
   2.417 -#ifdef __ia64__
   2.418 -static int setup_guest(int xc_handle,
   2.419 -                       uint32_t dom,
   2.420 -                       const char *image, unsigned long image_size,
   2.421 -                       struct initrd_info *initrd,
   2.422 -                       unsigned long nr_pages,
   2.423 -                       unsigned long *pvsi, unsigned long *pvke,
   2.424 -                       unsigned long *pvss, vcpu_guest_context_t *ctxt,
   2.425 -                       const char *cmdline,
   2.426 -                       unsigned long shared_info_frame,
   2.427 -                       unsigned long flags,
   2.428 -                       unsigned int store_evtchn, unsigned long *store_mfn,
   2.429 -                       unsigned int console_evtchn, unsigned long *console_mfn,
   2.430 -                       uint32_t required_features[XENFEAT_NR_SUBMAPS])
   2.431 -{
   2.432 -    xen_pfn_t *page_array = NULL;
   2.433 -    struct load_funcs load_funcs;
   2.434 -    struct domain_setup_info dsi;
   2.435 -    unsigned long vinitrd_start;
   2.436 -    unsigned long vinitrd_end;
   2.437 -    unsigned long v_end;
   2.438 -    unsigned long start_page, pgnr;
   2.439 -    start_info_t *start_info;
   2.440 -    unsigned long start_info_mpa;
   2.441 -    struct xen_ia64_boot_param *bp;
   2.442 -    shared_info_t *shared_info;
   2.443 -    int i;
   2.444 -    DECLARE_DOMCTL;
   2.445 -    int rc;
   2.446 -
   2.447 -    rc = probeimageformat(image, image_size, &load_funcs);
   2.448 -    if ( rc != 0 )
   2.449 -        goto error_out;
   2.450 -
   2.451 -    memset(&dsi, 0, sizeof(struct domain_setup_info));
   2.452 -
   2.453 -    rc = (load_funcs.parseimage)(image, image_size, &dsi);
   2.454 -    if ( rc != 0 )
   2.455 -        goto error_out;
   2.456 -
   2.457 -    if ( (page_array = malloc(nr_pages * sizeof(xen_pfn_t))) == NULL )
   2.458 -    {
   2.459 -        PERROR("Could not allocate memory");
   2.460 -        goto error_out;
   2.461 -    }
   2.462 -    for ( i = 0; i < nr_pages; i++ )
   2.463 -        page_array[i] = i;
   2.464 -    if ( xc_domain_memory_populate_physmap(xc_handle, dom, nr_pages,
   2.465 -                                           0, 0, page_array) )
   2.466 -    {
   2.467 -        PERROR("Could not allocate memory for PV guest.\n");
   2.468 -        goto error_out;
   2.469 -    }
   2.470 -
   2.471 -    dsi.v_start    = round_pgdown(dsi.v_start);
   2.472 -    vinitrd_start  = round_pgup(dsi.v_end);
   2.473 -    start_info_mpa = (nr_pages - 3) << PAGE_SHIFT;
   2.474 -    *pvke          = dsi.v_kernentry;
   2.475 -
   2.476 -    /* Build firmware.  */
   2.477 -    memset(&domctl.u.arch_setup, 0, sizeof(domctl.u.arch_setup));
   2.478 -    domctl.u.arch_setup.flags = 0;
   2.479 -    domctl.u.arch_setup.bp = start_info_mpa + sizeof (start_info_t);
   2.480 -    domctl.u.arch_setup.maxmem = (nr_pages - 3) << PAGE_SHIFT;
   2.481 -    domctl.cmd = XEN_DOMCTL_arch_setup;
   2.482 -    domctl.domain = (domid_t)dom;
   2.483 -    if ( xc_domctl(xc_handle, &domctl) )
   2.484 -        goto error_out;
   2.485 -
   2.486 -    start_page = dsi.v_start >> PAGE_SHIFT;
   2.487 -    /* in order to get initrd->len, we need to load initrd image at first */
   2.488 -    if ( load_initrd(xc_handle, dom, initrd,
   2.489 -                     vinitrd_start - dsi.v_start, page_array + start_page) )
   2.490 -        goto error_out;
   2.491 -
   2.492 -    vinitrd_end    = vinitrd_start + initrd->len;
   2.493 -    v_end          = round_pgup(vinitrd_end);
   2.494 -    pgnr = (v_end - dsi.v_start) >> PAGE_SHIFT;
   2.495 -    if ( pgnr > nr_pages )
   2.496 -    {
   2.497 -        PERROR("too small memory is specified. "
   2.498 -               "At least %ld kb is necessary.\n",
   2.499 -               pgnr << (PAGE_SHIFT - 10));
   2.500 -    }
   2.501 -
   2.502 -    IPRINTF("VIRTUAL MEMORY ARRANGEMENT:\n"
   2.503 -           " Loaded kernel: %p->%p\n"
   2.504 -           " Init. ramdisk: %p->%p\n"
   2.505 -           " TOTAL:         %p->%p\n",
   2.506 -           _p(dsi.v_kernstart), _p(dsi.v_kernend),
   2.507 -           _p(vinitrd_start),   _p(vinitrd_end),
   2.508 -           _p(dsi.v_start),     _p(v_end));
   2.509 -    IPRINTF(" ENTRY ADDRESS: %p\n", _p(dsi.v_kernentry));
   2.510 -
   2.511 -    (load_funcs.loadimage)(image, image_size, xc_handle, dom,
   2.512 -                           page_array + start_page, &dsi);
   2.513 -
   2.514 -    *store_mfn = page_array[nr_pages - 2]; //XXX
   2.515 -    *console_mfn = page_array[nr_pages - 1]; //XXX
   2.516 -    IPRINTF("start_info: 0x%lx at 0x%lx, "
   2.517 -           "store_mfn: 0x%lx at 0x%lx, "
   2.518 -           "console_mfn: 0x%lx at 0x%lx\n",
   2.519 -           page_array[nr_pages - 3], nr_pages - 3,
   2.520 -           *store_mfn,    nr_pages - 2,
   2.521 -           *console_mfn,  nr_pages - 1);
   2.522 -
   2.523 -    start_info = xc_map_foreign_range(
   2.524 -        xc_handle, dom, PAGE_SIZE, PROT_READ|PROT_WRITE,
   2.525 -        page_array[nr_pages - 3]);
   2.526 -    if ( start_info == NULL )
   2.527 -        goto error_out;
   2.528 -
   2.529 -    memset(start_info, 0, sizeof(*start_info));
   2.530 -    rc = xc_version(xc_handle, XENVER_version, NULL);
   2.531 -    sprintf(start_info->magic, "xen-%i.%i-ia64", rc >> 16, rc & (0xFFFF));
   2.532 -    start_info->flags        = flags;
   2.533 -    start_info->store_mfn    = nr_pages - 2;
   2.534 -    start_info->store_evtchn = store_evtchn;
   2.535 -    start_info->console.domU.mfn   = nr_pages - 1;
   2.536 -    start_info->console.domU.evtchn = console_evtchn;
   2.537 -    start_info->nr_pages       = nr_pages; // FIXME?: nr_pages - 2 ????
   2.538 -
   2.539 -    bp = (struct xen_ia64_boot_param *)(start_info + 1);
   2.540 -    bp->command_line = start_info_mpa + offsetof(start_info_t, cmd_line);
   2.541 -    if ( cmdline != NULL )
   2.542 -    {
   2.543 -        strncpy((char *)start_info->cmd_line, cmdline, MAX_GUEST_CMDLINE);
   2.544 -        start_info->cmd_line[MAX_GUEST_CMDLINE - 1] = 0;
   2.545 -    }
   2.546 -    if ( initrd->len != 0 )
   2.547 -    {
   2.548 -        bp->initrd_start    = vinitrd_start;
   2.549 -        bp->initrd_size     = initrd->len;
   2.550 -    }
   2.551 -    ctxt->user_regs.r28 = start_info_mpa + sizeof (start_info_t);
   2.552 -    munmap(start_info, PAGE_SIZE);
   2.553 -
   2.554 -    /*
   2.555 -     * shared_info is assiged into guest pseudo physical address space
   2.556 -     * by XEN_DOMCTL_arch_setup. shared_info_frame is stale value until that.
   2.557 -     * So passed shared_info_frame is stale. obtain the right value here.
   2.558 -     */
   2.559 -    domctl.cmd = XEN_DOMCTL_getdomaininfo;
   2.560 -    domctl.domain = (domid_t)dom;
   2.561 -    if ( (xc_domctl(xc_handle, &domctl) < 0) ||
   2.562 -         ((uint16_t)domctl.domain != dom) )
   2.563 -    {
   2.564 -        PERROR("Could not get info on domain");
   2.565 -        goto error_out;
   2.566 -    }
   2.567 -    shared_info_frame = domctl.u.getdomaininfo.shared_info_frame;
   2.568 -
   2.569 -    /* shared_info page starts its life empty. */
   2.570 -    shared_info = xc_map_foreign_range(
   2.571 -        xc_handle, dom, PAGE_SIZE, PROT_READ|PROT_WRITE, shared_info_frame);
   2.572 -    printf("shared_info = %p frame=%lx\n",
   2.573 -           shared_info, shared_info_frame);
   2.574 -    //memset(shared_info, 0, PAGE_SIZE);
   2.575 -    /* Mask all upcalls... */
   2.576 -    for ( i = 0; i < MAX_VIRT_CPUS; i++ )
   2.577 -        shared_info->vcpu_info[i].evtchn_upcall_mask = 1;
   2.578 -    shared_info->arch.start_info_pfn = nr_pages - 3;
   2.579 -
   2.580 -    munmap(shared_info, PAGE_SIZE);
   2.581 -    free(page_array);
   2.582 -    return 0;
   2.583 -
   2.584 - error_out:
   2.585 -    free(page_array);
   2.586 -    return -1;
   2.587 -}
   2.588 -#else /* x86 */
   2.589 -
   2.590 -/* Check if the platform supports the guest kernel format */
   2.591 -static int compat_check(int xc_handle, struct domain_setup_info *dsi)
   2.592 -{
   2.593 -    xen_capabilities_info_t xen_caps = "";
   2.594 -
   2.595 -    if (xc_version(xc_handle, XENVER_capabilities, &xen_caps) != 0) {
   2.596 -        xc_set_error(XC_INVALID_KERNEL,
   2.597 -                     "Cannot determine host capabilities.");
   2.598 -        return 0;
   2.599 -    }
   2.600 -
   2.601 -#ifndef __x86_64__//temp
   2.602 -    if (strstr(xen_caps, "xen-3.0-x86_32p")) {
   2.603 -        if (dsi->pae_kernel == PAEKERN_bimodal) {
   2.604 -            dsi->pae_kernel = PAEKERN_extended_cr3;
   2.605 -        } else if (dsi->pae_kernel == PAEKERN_no) {
   2.606 -            xc_set_error(XC_INVALID_KERNEL,
   2.607 -                         "Non PAE-kernel on PAE host.");
   2.608 -            return 0;
   2.609 -        }
   2.610 -    } else {
   2.611 -        if (dsi->pae_kernel == PAEKERN_bimodal) {
   2.612 -            dsi->pae_kernel = PAEKERN_no;
   2.613 -        } else if (dsi->pae_kernel != PAEKERN_no) {
   2.614 -            xc_set_error(XC_INVALID_KERNEL,
   2.615 -                         "PAE-kernel on non-PAE host.");
   2.616 -            return 0;
   2.617 -        }
   2.618 -    }
   2.619 -#endif
   2.620 -
   2.621 -    return 1;
   2.622 -}
   2.623 -
   2.624 -static inline int increment_ulong(unsigned long *pval, unsigned long inc)
   2.625 -{
   2.626 -    if ( inc >= -*pval )
   2.627 -    {
   2.628 -        ERROR("Value wrapped to zero: image too large?");
   2.629 -        return 0;
   2.630 -    }
   2.631 -    *pval += inc;
   2.632 -    return 1;
   2.633 -}
   2.634 -
   2.635 -static int setup_guest(int xc_handle,
   2.636 -                       uint32_t dom,
   2.637 -                       const char *image, unsigned long image_size,
   2.638 -                       struct initrd_info *initrd,
   2.639 -                       unsigned long nr_pages,
   2.640 -                       unsigned long *pvsi, unsigned long *pvke,
   2.641 -                       unsigned long *pvss, vcpu_guest_context_t *ctxt,
   2.642 -                       const char *cmdline,
   2.643 -                       unsigned long shared_info_frame,
   2.644 -                       unsigned long flags,
   2.645 -                       unsigned int store_evtchn, unsigned long *store_mfn,
   2.646 -                       unsigned int console_evtchn, unsigned long *console_mfn,
   2.647 -                       uint32_t required_features[XENFEAT_NR_SUBMAPS])
   2.648 -{
   2.649 -    xen_pfn_t *page_array = NULL;
   2.650 -    unsigned long count, i;
   2.651 -    unsigned long long hypercall_page;
   2.652 -    int hypercall_page_defined;
   2.653 -    start_info_t *start_info;
   2.654 -    shared_info_t *shared_info;
   2.655 -    const char *p;
   2.656 -    DECLARE_DOMCTL;
   2.657 -    int rc;
   2.658 -
   2.659 -    unsigned long nr_pt_pages;
   2.660 -    unsigned long physmap_pfn;
   2.661 -    xen_pfn_t *physmap, *physmap_e;
   2.662 -
   2.663 -    struct load_funcs load_funcs;
   2.664 -    struct domain_setup_info dsi;
   2.665 -    unsigned long vinitrd_start;
   2.666 -    unsigned long vphysmap_start;
   2.667 -    unsigned long vstartinfo_start;
   2.668 -    unsigned long vstoreinfo_start;
   2.669 -    unsigned long vconsole_start;
   2.670 -    unsigned long vsharedinfo_start = 0; /* XXX gcc */
   2.671 -    unsigned long vstack_start;
   2.672 -    unsigned long vstack_end;
   2.673 -    unsigned long vpt_start;
   2.674 -    unsigned long vpt_end;
   2.675 -    unsigned long v_end;
   2.676 -    unsigned long guest_store_mfn, guest_console_mfn, guest_shared_info_mfn;
   2.677 -    unsigned long shadow_mode_enabled;
   2.678 -    uint32_t supported_features[XENFEAT_NR_SUBMAPS] = { 0, };
   2.679 -
   2.680 -    rc = probeimageformat(image, image_size, &load_funcs);
   2.681 -    if ( rc != 0 )
   2.682 -        goto error_out;
   2.683 -
   2.684 -    memset(&dsi, 0, sizeof(struct domain_setup_info));
   2.685 -
   2.686 -    rc = (load_funcs.parseimage)(image, image_size, &dsi);
   2.687 -    if ( rc != 0 )
   2.688 -        goto error_out;
   2.689 -
   2.690 -    if ( (dsi.v_start & (PAGE_SIZE-1)) != 0 )
   2.691 -    {
   2.692 -        PERROR("Guest OS must load to a page boundary.");
   2.693 -        goto error_out;
   2.694 -    }
   2.695 -
   2.696 -    if ( !compat_check(xc_handle, &dsi) )
   2.697 -        goto error_out;
   2.698 -
   2.699 -    /* Parse and validate kernel features. */
   2.700 -    if ( (p = xen_elfnote_string(&dsi, XEN_ELFNOTE_FEATURES)) != NULL )
   2.701 -    {
   2.702 -        if ( !parse_features(p, supported_features, required_features) )
   2.703 -        {
   2.704 -            ERROR("Failed to parse guest kernel features.");
   2.705 -            goto error_out;
   2.706 -        }
   2.707 -
   2.708 -        IPRINTF("Supported features  = { %08x }.\n", supported_features[0]);
   2.709 -        IPRINTF("Required features   = { %08x }.\n", required_features[0]);
   2.710 -    }
   2.711 -
   2.712 -    for ( i = 0; i < XENFEAT_NR_SUBMAPS; i++ )
   2.713 -    {
   2.714 -        if ( (supported_features[i] & required_features[i]) !=
   2.715 -             required_features[i] )
   2.716 -        {
   2.717 -            ERROR("Guest kernel does not support a required feature.");
   2.718 -            goto error_out;
   2.719 -        }
   2.720 -    }
   2.721 -
   2.722 -    shadow_mode_enabled = test_feature_bit(XENFEAT_auto_translated_physmap,
   2.723 -                                           required_features);
   2.724 -
   2.725 -    if ( (page_array = malloc(nr_pages * sizeof(unsigned long))) == NULL )
   2.726 -    {
   2.727 -        PERROR("Could not allocate memory");
   2.728 -        goto error_out;
   2.729 -    }
   2.730 -
   2.731 -    for ( i = 0; i < nr_pages; i++ )
   2.732 -        page_array[i] = i;
   2.733 -
   2.734 -    if ( xc_domain_memory_populate_physmap(xc_handle, dom, nr_pages,
   2.735 -                                           0, 0, page_array) )
   2.736 -    {
   2.737 -        PERROR("Could not allocate memory for PV guest.\n");
   2.738 -        goto error_out;
   2.739 -    }
   2.740 -
   2.741 -
   2.742 -    if ( shadow_mode_enabled )
   2.743 -    {
   2.744 -        /*
   2.745 -         * Enable shadow translate mode. This must happen after
   2.746 -         * populate physmap because the p2m reservation is based on
   2.747 -         * the domain's current memory allocation.
   2.748 -         */
   2.749 -        if ( xc_shadow_control(xc_handle, dom,
   2.750 -                           XEN_DOMCTL_SHADOW_OP_ENABLE_TRANSLATE,
   2.751 -                           NULL, 0, NULL, 0, NULL) < 0 )
   2.752 -        {
   2.753 -            PERROR("Could not enable translation mode");
   2.754 -            goto error_out;
   2.755 -        }
   2.756 -
   2.757 -        /* Reinitialise the gpfn->gmfn array. */
   2.758 -        for ( i = 0; i < nr_pages; i++ )
   2.759 -            page_array[i] = i;
   2.760 -    }
   2.761 -
   2.762 -    rc = (load_funcs.loadimage)(image, image_size,
   2.763 -                           xc_handle, dom, page_array,
   2.764 -                           &dsi);
   2.765 -    if ( rc != 0 )
   2.766 -        goto error_out;
   2.767 -
   2.768 -    /*
   2.769 -     * Why do we need this? The number of page-table frames depends on the
   2.770 -     * size of the bootstrap address space. But the size of the address space
   2.771 -     * depends on the number of page-table frames (since each one is mapped
   2.772 -     * read-only). We have a pair of simultaneous equations in two unknowns,
   2.773 -     * which we solve by exhaustive search.
   2.774 -     */
   2.775 -    v_end = round_pgup(dsi.v_end);
   2.776 -    if ( v_end == 0 )
   2.777 -    {
   2.778 -        ERROR("End of mapped kernel image too close to end of memory");
   2.779 -        goto error_out;
   2.780 -    }
   2.781 -
   2.782 -    vinitrd_start = v_end;
   2.783 -    if ( load_initrd(xc_handle, dom, initrd,
   2.784 -                     vinitrd_start - dsi.v_start, page_array) )
   2.785 -        goto error_out;
   2.786 -    if ( !increment_ulong(&v_end, round_pgup(initrd->len)) )
   2.787 -        goto error_out;
   2.788 -
   2.789 -    vphysmap_start = v_end;
   2.790 -    if ( !increment_ulong(&v_end, round_pgup(nr_pages * sizeof(long))) )
   2.791 -        goto error_out;
   2.792 -    vstartinfo_start = v_end;
   2.793 -    if ( !increment_ulong(&v_end, PAGE_SIZE) )
   2.794 -        goto error_out;
   2.795 -    vstoreinfo_start = v_end;
   2.796 -    if ( !increment_ulong(&v_end, PAGE_SIZE) )
   2.797 -        goto error_out;
   2.798 -    vconsole_start = v_end;
   2.799 -    if ( !increment_ulong(&v_end, PAGE_SIZE) )
   2.800 -        goto error_out;
   2.801 -    if ( shadow_mode_enabled ) {
   2.802 -        vsharedinfo_start = v_end;
   2.803 -        if ( !increment_ulong(&v_end, PAGE_SIZE) )
   2.804 -            goto error_out;
   2.805 -    }
   2.806 -    vpt_start = v_end;
   2.807 -
   2.808 -    for ( nr_pt_pages = 2; ; nr_pt_pages++ )
   2.809 -    {
   2.810 -        /* vpt_end = vpt_staret + (nr_pt_pages * PAGE_SIZE); */
   2.811 -        vpt_end = vpt_start;
   2.812 -        if ( !increment_ulong(&vpt_end, nr_pt_pages * PAGE_SIZE) )
   2.813 -            goto error_out;
   2.814 -
   2.815 -        vstack_start = vpt_end;
   2.816 -        /* vstack_end = vstack_start + PAGE_SIZE; */
   2.817 -        vstack_end = vstack_start;
   2.818 -        if ( !increment_ulong(&vstack_end, PAGE_SIZE) )
   2.819 -            goto error_out;
   2.820 -
   2.821 -        /* v_end = (vstack_end + (1UL<<22)-1) & ~((1UL<<22)-1); */
   2.822 -        v_end = vstack_end;
   2.823 -        if ( !increment_ulong(&v_end, (1UL<<22)-1) )
   2.824 -            goto error_out;
   2.825 -        v_end &= ~((1UL<<22)-1);
   2.826 -
   2.827 -        if ( (v_end - vstack_end) < (512UL << 10) )
   2.828 -        {
   2.829 -            /* Add extra 4MB to get >= 512kB padding. */
   2.830 -            if ( !increment_ulong(&v_end, 1UL << 22) )
   2.831 -                goto error_out;
   2.832 -        }
   2.833 -
   2.834 -#define NR(_l,_h,_s)                                                    \
   2.835 -    (((((unsigned long)(_h) + ((1UL<<(_s))-1)) & ~((1UL<<(_s))-1)) -    \
   2.836 -    ((unsigned long)(_l) & ~((1UL<<(_s))-1))) >> (_s))
   2.837 -#if defined(__i386__)
   2.838 -        if ( dsi.pae_kernel != PAEKERN_no )
   2.839 -        {
   2.840 -            if ( (1 + /* # L3 */
   2.841 -                  NR(dsi.v_start, v_end, L3_PAGETABLE_SHIFT_PAE) + /* # L2 */
   2.842 -                  NR(dsi.v_start, v_end, L2_PAGETABLE_SHIFT_PAE) + /* # L1 */
   2.843 -                  /* Include a fourth mid-level page directory for Xen. */
   2.844 -                  (v_end <= (3 << L3_PAGETABLE_SHIFT_PAE)))
   2.845 -                  <= nr_pt_pages )
   2.846 -                break;
   2.847 -        }
   2.848 -        else
   2.849 -        {
   2.850 -            if ( (1 + /* # L2 */
   2.851 -                  NR(dsi.v_start, v_end, L2_PAGETABLE_SHIFT)) /* # L1 */
   2.852 -                 <= nr_pt_pages )
   2.853 -                break;
   2.854 -        }
   2.855 -#elif defined(__x86_64__)
   2.856 -        if ( (1 + /* # L4 */
   2.857 -              NR(dsi.v_start, v_end, L4_PAGETABLE_SHIFT) + /* # L3 */
   2.858 -              NR(dsi.v_start, v_end, L3_PAGETABLE_SHIFT) + /* # L2 */
   2.859 -              NR(dsi.v_start, v_end, L2_PAGETABLE_SHIFT))  /* # L1 */
   2.860 -             <= nr_pt_pages )
   2.861 -            break;
   2.862 -#endif
   2.863 -    }
   2.864 -
   2.865 -    IPRINTF("VIRTUAL MEMORY ARRANGEMENT:\n");
   2.866 -    IPRINTF(" Loaded kernel:    %p->%p\n", _p(dsi.v_kernstart),
   2.867 -           _p(dsi.v_kernend));
   2.868 -    if ( initrd->len )
   2.869 -        IPRINTF(" Initial ramdisk:  %p->%p\n", _p(vinitrd_start),
   2.870 -               _p(vinitrd_start + initrd->len));
   2.871 -    IPRINTF(" Phys-Mach map:    %p\n", _p(vphysmap_start));
   2.872 -    IPRINTF(" Start info:       %p\n", _p(vstartinfo_start));
   2.873 -    IPRINTF(" Store page:       %p\n", _p(vstoreinfo_start));
   2.874 -    IPRINTF(" Console page:     %p\n", _p(vconsole_start));
   2.875 -    if ( shadow_mode_enabled )
   2.876 -        IPRINTF(" Shared Info page: %p\n", _p(vsharedinfo_start));
   2.877 -    IPRINTF(" Page tables:      %p\n", _p(vpt_start));
   2.878 -    IPRINTF(" Boot stack:       %p\n", _p(vstack_start));
   2.879 -    IPRINTF(" TOTAL:            %p->%p\n", _p(dsi.v_start), _p(v_end));
   2.880 -    IPRINTF(" ENTRY ADDRESS:    %p\n", _p(dsi.v_kernentry));
   2.881 -
   2.882 -    if ( ((v_end - dsi.v_start)>>PAGE_SHIFT) > nr_pages )
   2.883 -    {
   2.884 -        PERROR("Initial guest OS requires too much space\n"
   2.885 -               "(%pMB is greater than %luMB limit)\n",
   2.886 -               _p((v_end-dsi.v_start)>>20), nr_pages>>(20-PAGE_SHIFT));
   2.887 -        goto error_out;
   2.888 -    }
   2.889 -
   2.890 -#if defined(__i386__)
   2.891 -    if ( dsi.pae_kernel != PAEKERN_no )
   2.892 -        rc = setup_pg_tables_pae(xc_handle, dom, ctxt,
   2.893 -                                 dsi.v_start, v_end,
   2.894 -                                 page_array, vpt_start, vpt_end,
   2.895 -                                 shadow_mode_enabled, dsi.pae_kernel);
   2.896 -    else
   2.897 -        rc = setup_pg_tables(xc_handle, dom, ctxt,
   2.898 -                             dsi.v_start, v_end,
   2.899 -                             page_array, vpt_start, vpt_end,
   2.900 -                             shadow_mode_enabled);
   2.901 -#endif
   2.902 -#if defined(__x86_64__)
   2.903 -    rc = setup_pg_tables_64(xc_handle, dom, ctxt,
   2.904 -                            dsi.v_start, v_end,
   2.905 -                            page_array, vpt_start, vpt_end,
   2.906 -                            shadow_mode_enabled);
   2.907 -#endif
   2.908 -    if ( rc != 0 )
   2.909 -        goto error_out;
   2.910 -
   2.911 -    /*
   2.912 -     * Pin down l2tab addr as page dir page - causes hypervisor to provide
   2.913 -     * correct protection for the page
   2.914 -     */
   2.915 -    if ( !shadow_mode_enabled )
   2.916 -    {
   2.917 -#if defined(__i386__)
   2.918 -        if ( dsi.pae_kernel != PAEKERN_no )
   2.919 -        {
   2.920 -            if ( pin_table(xc_handle, MMUEXT_PIN_L3_TABLE,
   2.921 -                           xen_cr3_to_pfn(ctxt->ctrlreg[3]), dom) )
   2.922 -                goto error_out;
   2.923 -        }
   2.924 -        else
   2.925 -        {
   2.926 -            if ( pin_table(xc_handle, MMUEXT_PIN_L2_TABLE,
   2.927 -                           xen_cr3_to_pfn(ctxt->ctrlreg[3]), dom) )
   2.928 -                goto error_out;
   2.929 -        }
   2.930 -#elif defined(__x86_64__)
   2.931 -        /*
   2.932 -         * Pin down l4tab addr as page dir page - causes hypervisor to  provide
   2.933 -         * correct protection for the page
   2.934 -         */
   2.935 -        if ( pin_table(xc_handle, MMUEXT_PIN_L4_TABLE,
   2.936 -                       xen_cr3_to_pfn(ctxt->ctrlreg[3]), dom) )
   2.937 -            goto error_out;
   2.938 -#endif
   2.939 -    }
   2.940 -
   2.941 -    /* Write the phys->machine table entries (machine->phys already done). */
   2.942 -    physmap_pfn = (vphysmap_start - dsi.v_start) >> PAGE_SHIFT;
   2.943 -    physmap = physmap_e = xc_map_foreign_range(
   2.944 -        xc_handle, dom, PAGE_SIZE, PROT_READ|PROT_WRITE,
   2.945 -        page_array[physmap_pfn++]);
   2.946 -    for ( count = 0; count < nr_pages; count++ )
   2.947 -    {
   2.948 -        *physmap_e++ = page_array[count];
   2.949 -        if ( ((unsigned long)physmap_e & (PAGE_SIZE-1)) == 0 )
   2.950 -        {
   2.951 -            munmap(physmap, PAGE_SIZE);
   2.952 -            physmap = physmap_e = xc_map_foreign_range(
   2.953 -                xc_handle, dom, PAGE_SIZE, PROT_READ|PROT_WRITE,
   2.954 -                page_array[physmap_pfn++]);
   2.955 -        }
   2.956 -    }
   2.957 -    munmap(physmap, PAGE_SIZE);
   2.958 -
   2.959 -    if ( shadow_mode_enabled )
   2.960 -    {
   2.961 -        struct xen_add_to_physmap xatp;
   2.962 -
   2.963 -        guest_shared_info_mfn = (vsharedinfo_start-dsi.v_start) >> PAGE_SHIFT;
   2.964 -
   2.965 -        /* Map shared info frame into guest physmap. */
   2.966 -        xatp.domid = dom;
   2.967 -        xatp.space = XENMAPSPACE_shared_info;
   2.968 -        xatp.idx   = 0;
   2.969 -        xatp.gpfn  = guest_shared_info_mfn;
   2.970 -        rc = xc_memory_op(xc_handle, XENMEM_add_to_physmap, &xatp);
   2.971 -        if ( rc != 0 )
   2.972 -        {
   2.973 -            PERROR("Cannot map shared info pfn");
   2.974 -            goto error_out;
   2.975 -        }
   2.976 -
   2.977 -        /* Map grant table frames into guest physmap. */
   2.978 -        for ( i = 0; ; i++ )
   2.979 -        {
   2.980 -            xatp.domid = dom;
   2.981 -            xatp.space = XENMAPSPACE_grant_table;
   2.982 -            xatp.idx   = i;
   2.983 -            xatp.gpfn  = nr_pages + i;
   2.984 -            rc = xc_memory_op(xc_handle, XENMEM_add_to_physmap, &xatp);
   2.985 -            if ( rc != 0 )
   2.986 -            {
   2.987 -                if ( errno == EINVAL )
   2.988 -                    break; /* done all grant tables */
   2.989 -                PERROR("Cannot map grant table pfn");
   2.990 -                goto error_out;
   2.991 -            }
   2.992 -        }
   2.993 -    }
   2.994 -    else
   2.995 -    {
   2.996 -        guest_shared_info_mfn = shared_info_frame;
   2.997 -    }
   2.998 -
   2.999 -    *store_mfn = page_array[(vstoreinfo_start-dsi.v_start) >> PAGE_SHIFT];
  2.1000 -    *console_mfn = page_array[(vconsole_start-dsi.v_start) >> PAGE_SHIFT];
  2.1001 -    if ( xc_clear_domain_page(xc_handle, dom, *store_mfn) ||
  2.1002 -         xc_clear_domain_page(xc_handle, dom, *console_mfn) )
  2.1003 -        goto error_out;
  2.1004 -    if ( shadow_mode_enabled )
  2.1005 -    {
  2.1006 -        guest_store_mfn = (vstoreinfo_start-dsi.v_start) >> PAGE_SHIFT;
  2.1007 -        guest_console_mfn = (vconsole_start-dsi.v_start) >> PAGE_SHIFT;
  2.1008 -    }
  2.1009 -    else
  2.1010 -    {
  2.1011 -        guest_store_mfn = *store_mfn;
  2.1012 -        guest_console_mfn = *console_mfn;
  2.1013 -    }
  2.1014 -
  2.1015 -    start_info = xc_map_foreign_range(
  2.1016 -        xc_handle, dom, PAGE_SIZE, PROT_READ|PROT_WRITE,
  2.1017 -        page_array[(vstartinfo_start-dsi.v_start)>>PAGE_SHIFT]);
  2.1018 -    /*shared_info, start_info */
  2.1019 -    memset(start_info, 0, sizeof(*start_info));
  2.1020 -    rc = xc_version(xc_handle, XENVER_version, NULL);
  2.1021 -    sprintf(start_info->magic, "xen-%i.%i-x86_%d%s",
  2.1022 -            rc >> 16, rc & (0xFFFF), (unsigned int)sizeof(long)*8,
  2.1023 -            (dsi.pae_kernel != PAEKERN_no) ? "p" : "");
  2.1024 -    start_info->nr_pages     = nr_pages;
  2.1025 -    start_info->shared_info  = guest_shared_info_mfn << PAGE_SHIFT;
  2.1026 -    start_info->flags        = flags;
  2.1027 -    start_info->pt_base      = vpt_start;
  2.1028 -    start_info->nr_pt_frames = nr_pt_pages;
  2.1029 -    start_info->mfn_list     = vphysmap_start;
  2.1030 -    start_info->store_mfn    = guest_store_mfn;
  2.1031 -    start_info->store_evtchn = store_evtchn;
  2.1032 -    start_info->console.domU.mfn   = guest_console_mfn;
  2.1033 -    start_info->console.domU.evtchn = console_evtchn;
  2.1034 -    if ( initrd->len != 0 )
  2.1035 -    {
  2.1036 -        start_info->mod_start    = vinitrd_start;
  2.1037 -        start_info->mod_len      = initrd->len;
  2.1038 -    }
  2.1039 -    if ( cmdline != NULL )
  2.1040 -    {
  2.1041 -        strncpy((char *)start_info->cmd_line, cmdline, MAX_GUEST_CMDLINE);
  2.1042 -        start_info->cmd_line[MAX_GUEST_CMDLINE-1] = '\0';
  2.1043 -    }
  2.1044 -    munmap(start_info, PAGE_SIZE);
  2.1045 -
  2.1046 -    /* shared_info page starts its life empty. */
  2.1047 -    shared_info = xc_map_foreign_range(
  2.1048 -        xc_handle, dom, PAGE_SIZE, PROT_READ|PROT_WRITE, shared_info_frame);
  2.1049 -    memset(shared_info, 0, PAGE_SIZE);
  2.1050 -    /* Mask all upcalls... */
  2.1051 -    for ( i = 0; i < MAX_VIRT_CPUS; i++ )
  2.1052 -        shared_info->vcpu_info[i].evtchn_upcall_mask = 1;
  2.1053 -
  2.1054 -    munmap(shared_info, PAGE_SIZE);
  2.1055 -
  2.1056 -    hypercall_page = xen_elfnote_numeric(&dsi, XEN_ELFNOTE_HYPERCALL_PAGE,
  2.1057 -                                         &hypercall_page_defined);
  2.1058 -    if ( hypercall_page_defined )
  2.1059 -    {
  2.1060 -        unsigned long long pfn = (hypercall_page - dsi.v_start) >> PAGE_SHIFT;
  2.1061 -        if ( pfn >= nr_pages )
  2.1062 -            goto error_out;
  2.1063 -        domctl.domain = (domid_t)dom;
  2.1064 -        domctl.u.hypercall_init.gmfn = page_array[pfn];
  2.1065 -        domctl.cmd = XEN_DOMCTL_hypercall_init;
  2.1066 -        if ( xc_domctl(xc_handle, &domctl) )
  2.1067 -            goto error_out;
  2.1068 -    }
  2.1069 -
  2.1070 -    free(page_array);
  2.1071 -
  2.1072 -    *pvsi = vstartinfo_start;
  2.1073 -    *pvss = vstack_start;
  2.1074 -    *pvke = dsi.v_kernentry;
  2.1075 -
  2.1076 -    return 0;
  2.1077 -
  2.1078 - error_out:
  2.1079 -    free(page_array);
  2.1080 -    return -1;
  2.1081 -}
  2.1082 -#endif
  2.1083 -
  2.1084 -static int xc_linux_build_internal(int xc_handle,
  2.1085 -                                   uint32_t domid,
  2.1086 -                                   unsigned int mem_mb,
  2.1087 -                                   const char *image,
  2.1088 -                                   unsigned long image_size,
  2.1089 -                                   struct initrd_info *initrd,
  2.1090 -                                   const char *cmdline,
  2.1091 -                                   const char *features,
  2.1092 -                                   unsigned long flags,
  2.1093 -                                   unsigned int store_evtchn,
  2.1094 -                                   unsigned long *store_mfn,
  2.1095 -                                   unsigned int console_evtchn,
  2.1096 -                                   unsigned long *console_mfn)
  2.1097 -{
  2.1098 -    struct xen_domctl launch_domctl;
  2.1099 -    DECLARE_DOMCTL;
  2.1100 -    int rc;
  2.1101 -    struct vcpu_guest_context st_ctxt, *ctxt = &st_ctxt;
  2.1102 -    unsigned long vstartinfo_start, vkern_entry, vstack_start;
  2.1103 -    uint32_t      features_bitmap[XENFEAT_NR_SUBMAPS] = { 0, };
  2.1104 -
  2.1105 -    if ( features != NULL )
  2.1106 -    {
  2.1107 -        if ( !parse_features(features, features_bitmap, NULL) )
  2.1108 -        {
  2.1109 -            PERROR("Failed to parse configured features\n");
  2.1110 -            goto error_out;
  2.1111 -        }
  2.1112 -    }
  2.1113 -
  2.1114 -    memset(ctxt, 0, sizeof(*ctxt));
  2.1115 -
  2.1116 -    if ( lock_pages(ctxt, sizeof(*ctxt) ) )
  2.1117 -    {
  2.1118 -        PERROR("%s: ctxt lock failed", __func__);
  2.1119 -        return 1;
  2.1120 -    }
  2.1121 -
  2.1122 -    domctl.cmd = XEN_DOMCTL_getdomaininfo;
  2.1123 -    domctl.domain = (domid_t)domid;
  2.1124 -    if ( (xc_domctl(xc_handle, &domctl) < 0) ||
  2.1125 -         ((uint16_t)domctl.domain != domid) )
  2.1126 -    {
  2.1127 -        PERROR("Could not get info on domain");
  2.1128 -        goto error_out;
  2.1129 -    }
  2.1130 -
  2.1131 -    if ( setup_guest(xc_handle, domid, image, image_size,
  2.1132 -                     initrd,
  2.1133 -                     mem_mb << (20 - PAGE_SHIFT),
  2.1134 -                     &vstartinfo_start, &vkern_entry,
  2.1135 -                     &vstack_start, ctxt, cmdline,
  2.1136 -                     domctl.u.getdomaininfo.shared_info_frame,
  2.1137 -                     flags, store_evtchn, store_mfn,
  2.1138 -                     console_evtchn, console_mfn,
  2.1139 -                     features_bitmap) < 0 )
  2.1140 -    {
  2.1141 -        goto error_out;
  2.1142 -    }
  2.1143 -
  2.1144 -#ifdef __ia64__
  2.1145 -    /* based on new_thread in xen/arch/ia64/domain.c */
  2.1146 -    ctxt->user_regs.cr_iip = vkern_entry;
  2.1147 -    ctxt->user_regs.cr_ifs = 1UL << 63;
  2.1148 -    ctxt->user_regs.ar_fpsr = xc_ia64_fpsr_default();
  2.1149 -#else /* x86 */
  2.1150 -    /*
  2.1151 -     * Initial register values:
  2.1152 -     *  DS,ES,FS,GS = FLAT_KERNEL_DS
  2.1153 -     *       CS:EIP = FLAT_KERNEL_CS:start_pc
  2.1154 -     *       SS:ESP = FLAT_KERNEL_DS:start_stack
  2.1155 -     *          ESI = start_info
  2.1156 -     *  [EAX,EBX,ECX,EDX,EDI,EBP are zero]
  2.1157 -     *       EFLAGS = IF | 2 (bit 1 is reserved and should always be 1)
  2.1158 -     */
  2.1159 -    ctxt->user_regs.ds = FLAT_KERNEL_DS;
  2.1160 -    ctxt->user_regs.es = FLAT_KERNEL_DS;
  2.1161 -    ctxt->user_regs.fs = FLAT_KERNEL_DS;
  2.1162 -    ctxt->user_regs.gs = FLAT_KERNEL_DS;
  2.1163 -    ctxt->user_regs.ss = FLAT_KERNEL_SS;
  2.1164 -    ctxt->user_regs.cs = FLAT_KERNEL_CS;
  2.1165 -    ctxt->user_regs.eip = vkern_entry;
  2.1166 -    ctxt->user_regs.esp = vstack_start + PAGE_SIZE;
  2.1167 -    ctxt->user_regs.esi = vstartinfo_start;
  2.1168 -    ctxt->user_regs.eflags = 1 << 9; /* Interrupt Enable */
  2.1169 -
  2.1170 -    ctxt->flags = VGCF_IN_KERNEL;
  2.1171 -
  2.1172 -    ctxt->kernel_ss = ctxt->user_regs.ss;
  2.1173 -    ctxt->kernel_sp = ctxt->user_regs.esp;
  2.1174 -#endif /* x86 */
  2.1175 -
  2.1176 -    memset(&launch_domctl, 0, sizeof(launch_domctl));
  2.1177 -
  2.1178 -    launch_domctl.domain = (domid_t)domid;
  2.1179 -    launch_domctl.u.vcpucontext.vcpu   = 0;
  2.1180 -    set_xen_guest_handle(launch_domctl.u.vcpucontext.ctxt, ctxt);
  2.1181 -
  2.1182 -    launch_domctl.cmd = XEN_DOMCTL_setvcpucontext;
  2.1183 -    rc = xc_domctl(xc_handle, &launch_domctl);
  2.1184 -
  2.1185 -    return rc;
  2.1186 -
  2.1187 - error_out:
  2.1188 -    return -1;
  2.1189 -}
  2.1190 -
  2.1191 -int xc_linux_build_mem(int xc_handle,
  2.1192 -                       uint32_t domid,
  2.1193 -                       unsigned int mem_mb,
  2.1194 -                       const char *image_buffer,
  2.1195 -                       unsigned long image_size,
  2.1196 -                       const char *initrd,
  2.1197 -                       unsigned long initrd_len,
  2.1198 -                       const char *cmdline,
  2.1199 -                       const char *features,
  2.1200 -                       unsigned long flags,
  2.1201 -                       unsigned int store_evtchn,
  2.1202 -                       unsigned long *store_mfn,
  2.1203 -                       unsigned int console_evtchn,
  2.1204 -                       unsigned long *console_mfn)
  2.1205 -{
  2.1206 -    int            sts;
  2.1207 -    char          *img_buf;
  2.1208 -    unsigned long  img_len;
  2.1209 -    struct initrd_info initrd_info = { .type = INITRD_none };
  2.1210 -
  2.1211 -    /* A kernel buffer is required */
  2.1212 -    if ( (image_buffer == NULL) || (image_size == 0) )
  2.1213 -    {
  2.1214 -        ERROR("kernel image buffer not present");
  2.1215 -        return -1;
  2.1216 -    }
  2.1217 -
  2.1218 -    /* If it's gzipped, inflate it;  otherwise, use as is */
  2.1219 -    /* xc_inflate_buffer may return the same buffer pointer if */
  2.1220 -    /* the buffer is already inflated */
  2.1221 -    img_buf = xc_inflate_buffer(image_buffer, image_size, &img_len);
  2.1222 -    if ( img_buf == NULL )
  2.1223 -    {
  2.1224 -        ERROR("unable to inflate kernel image buffer");
  2.1225 -        return -1;
  2.1226 -    }
  2.1227 -
  2.1228 -    /* RAM disks are optional; if we get one, inflate it */
  2.1229 -    if ( initrd != NULL )
  2.1230 -    {
  2.1231 -        initrd_info.type = INITRD_mem;
  2.1232 -        initrd_info.u.mem_addr = xc_inflate_buffer(
  2.1233 -            initrd, initrd_len, &initrd_info.len);
  2.1234 -        if ( initrd_info.u.mem_addr == NULL )
  2.1235 -        {
  2.1236 -            ERROR("unable to inflate ram disk buffer");
  2.1237 -            sts = -1;
  2.1238 -            goto out;
  2.1239 -        }
  2.1240 -    }
  2.1241 -
  2.1242 -    sts = xc_linux_build_internal(xc_handle, domid, mem_mb, img_buf, img_len,
  2.1243 -                                  &initrd_info, cmdline, features, flags,
  2.1244 -                                  store_evtchn, store_mfn,
  2.1245 -                                  console_evtchn, console_mfn);
  2.1246 -
  2.1247 - out:
  2.1248 -    /* The inflation routines may pass back the same buffer so be */
  2.1249 -    /* sure that we have a buffer and that it's not the one passed in. */
  2.1250 -    /* Don't unnecessarily annoy/surprise/confound the caller */
  2.1251 -    if ( (img_buf != NULL) && (img_buf != image_buffer) )
  2.1252 -        free(img_buf);
  2.1253 -    if ( (initrd_info.u.mem_addr != NULL) &&
  2.1254 -         (initrd_info.u.mem_addr != initrd) )
  2.1255 -        free(initrd_info.u.mem_addr);
  2.1256 -
  2.1257 -    return sts;
  2.1258 -}
  2.1259 -
  2.1260 -int xc_linux_build(int xc_handle,
  2.1261 -                   uint32_t domid,
  2.1262 -                   unsigned int mem_mb,
  2.1263 -                   const char *image_name,
  2.1264 -                   const char *initrd_name,
  2.1265 -                   const char *cmdline,
  2.1266 -                   const char *features,
  2.1267 -                   unsigned long flags,
  2.1268 -                   unsigned int store_evtchn,
  2.1269 -                   unsigned long *store_mfn,
  2.1270 -                   unsigned int console_evtchn,
  2.1271 -                   unsigned long *console_mfn)
  2.1272 -{
  2.1273 -    char *image = NULL;
  2.1274 -    unsigned long image_size;
  2.1275 -    struct initrd_info initrd_info = { .type = INITRD_none };
  2.1276 -    int fd = -1, sts = -1;
  2.1277 -
  2.1278 -    if ( (image_name == NULL) ||
  2.1279 -         ((image = xc_read_image(image_name, &image_size)) == NULL ))
  2.1280 -        return -1;
  2.1281 -
  2.1282 -    if ( (initrd_name != NULL) && (strlen(initrd_name) != 0) )
  2.1283 -    {
  2.1284 -        initrd_info.type = INITRD_file;
  2.1285 -
  2.1286 -        if ( (fd = open(initrd_name, O_RDONLY)) < 0 )
  2.1287 -        {
  2.1288 -            PERROR("Could not open the initial ramdisk image");
  2.1289 -            goto error_out;
  2.1290 -        }
  2.1291 -
  2.1292 -        if ( (initrd_info.u.file_handle = gzdopen(fd, "rb")) == NULL )
  2.1293 -        {
  2.1294 -            PERROR("Could not allocate decompression state for initrd");
  2.1295 -            goto error_out;
  2.1296 -        }
  2.1297 -    }
  2.1298 -
  2.1299 -    sts = xc_linux_build_internal(xc_handle, domid, mem_mb, image, image_size,
  2.1300 -                                  &initrd_info, cmdline, features, flags,
  2.1301 -                                  store_evtchn, store_mfn,
  2.1302 -                                  console_evtchn, console_mfn);
  2.1303 -
  2.1304 - error_out:
  2.1305 -    free(image);
  2.1306 -    if ( initrd_info.type == INITRD_file && initrd_info.u.file_handle )
  2.1307 -        gzclose(initrd_info.u.file_handle);
  2.1308 -    else if ( fd >= 0 )
  2.1309 -        close(fd);
  2.1310 -
  2.1311 -    return sts;
  2.1312 -}
  2.1313 -
  2.1314 -/*
  2.1315 - * Local variables:
  2.1316 - * mode: C
  2.1317 - * c-set-style: "BSD"
  2.1318 - * c-basic-offset: 4
  2.1319 - * tab-width: 4
  2.1320 - * indent-tabs-mode: nil
  2.1321 - * End:
  2.1322 - */
     3.1 --- a/tools/libxc/xc_load_bin.c	Wed Feb 14 12:18:32 2007 -0800
     3.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
     3.3 @@ -1,306 +0,0 @@
     3.4 -/******************************************************************************
     3.5 - * xc_bin_load.c
     3.6 - *
     3.7 - * Based on xc_elf_load.c
     3.8 - *
     3.9 - * Loads simple binary images. It's like a .COM file in MS-DOS. No headers are
    3.10 - * present. The only requirement is that it must have a xen_bin_image table
    3.11 - * somewhere in the first 8192 bytes, starting on a 32-bit aligned address.
    3.12 - * Those familiar with the multiboot specification should recognize this, it's
    3.13 - * (almost) the same as the multiboot header.
    3.14 - * The layout of the xen_bin_image table is:
    3.15 - *
    3.16 - * Offset Type Name          Note
    3.17 - * 0      uint32_t  magic         required
    3.18 - * 4      uint32_t  flags         required
    3.19 - * 8      uint32_t  checksum      required
    3.20 - * 12     uint32_t  header_addr   required
    3.21 - * 16     uint32_t  load_addr     required
    3.22 - * 20     uint32_t  load_end_addr required
    3.23 - * 24     uint32_t  bss_end_addr  required
    3.24 - * 28     uint32_t  entry_addr    required
    3.25 - *
    3.26 - * - magic
    3.27 - *   Magic number identifying the table. For images to be loaded by Xen 3, the
    3.28 - *   magic value is 0x336ec578 ("xEn3" with the 0x80 bit of the "E" set).
    3.29 - * - flags
    3.30 - *   bit 0: indicates whether the image needs to be loaded on a page boundary
    3.31 - *   bit 1: reserved, must be 0 (the multiboot spec uses this bit to indicate
    3.32 - *          that memory info should be passed to the image)
    3.33 - *   bit 2: reserved, must be 0 (the multiboot spec uses this bit to indicate
    3.34 - *          that the bootloader should pass video mode info to the image)
    3.35 - *   bit 16: reserved, must be 1 (the multiboot spec uses this bit to indicate
    3.36 - *           that the values in the fields header_addr - entry_addr are
    3.37 - *           valid)
    3.38 - *   All other bits should be set to 0.
    3.39 - * - checksum
    3.40 - *   When added to "magic" and "flags", the resulting value should be 0.
    3.41 - * - header_addr
    3.42 - *   Contains the virtual address corresponding to the beginning of the
    3.43 - *   table - the memory location at which the magic value is supposed to be
    3.44 - *   loaded. This field serves to synchronize the mapping between OS image
    3.45 - *   offsets and virtual memory addresses.
    3.46 - * - load_addr
    3.47 - *   Contains the virtual address of the beginning of the text segment. The
    3.48 - *   offset in the OS image file at which to start loading is defined by the
    3.49 - *   offset at which the table was found, minus (header addr - load addr).
    3.50 - *   load addr must be less than or equal to header addr.
    3.51 - * - load_end_addr
    3.52 - *   Contains the virtual address of the end of the data segment.
    3.53 - *   (load_end_addr - load_addr) specifies how much data to load. This implies
    3.54 - *   that the text and data segments must be consecutive in the OS image. If
    3.55 - *   this field is zero, the domain builder assumes that the text and data
    3.56 - *   segments occupy the whole OS image file.
    3.57 - * - bss_end_addr
    3.58 - *   Contains the virtual address of the end of the bss segment. The domain
    3.59 - *   builder initializes this area to zero, and reserves the memory it occupies
    3.60 - *   to avoid placing boot modules and other data relevant to the loaded image
    3.61 - *   in that area. If this field is zero, the domain builder assumes that no bss
    3.62 - *   segment is present.
    3.63 - * - entry_addr
    3.64 - *   The virtual address at which to start execution of the loaded image.
    3.65 - *
    3.66 - * Some of the field descriptions were copied from "The Multiboot
    3.67 - * Specification", Copyright 1995, 96 Bryan Ford <baford@cs.utah.edu>,
    3.68 - * Erich Stefan Boleyn <erich@uruk.org> Copyright 1999, 2000, 2001, 2002
    3.69 - * Free Software Foundation, Inc.
    3.70 - */
    3.71 -
    3.72 -#include "xg_private.h"
    3.73 -#include <stdlib.h>
    3.74 -
    3.75 -#define L1_PROT (_PAGE_PRESENT|_PAGE_RW|_PAGE_ACCESSED)
    3.76 -#define L2_PROT (_PAGE_PRESENT|_PAGE_RW|_PAGE_ACCESSED|_PAGE_DIRTY|_PAGE_USER)
    3.77 -
    3.78 -#define round_pgup(_p)    (((_p)+(PAGE_SIZE-1))&PAGE_MASK)
    3.79 -#define round_pgdown(_p)  ((_p)&PAGE_MASK)
    3.80 -
    3.81 -struct xen_bin_image_table
    3.82 -{
    3.83 -    unsigned long magic;
    3.84 -    unsigned long flags;
    3.85 -    unsigned long checksum;
    3.86 -    unsigned long header_addr;
    3.87 -    unsigned long load_addr;
    3.88 -    unsigned long load_end_addr;
    3.89 -    unsigned long bss_end_addr;
    3.90 -    unsigned long entry_addr;
    3.91 -};
    3.92 -
    3.93 -#define XEN_REACTOS_MAGIC3 0x336ec578
    3.94 -
    3.95 -#define XEN_REACTOS_FLAG_ALIGN4K     0x00000001
    3.96 -#define XEN_REACTOS_FLAG_NEEDMEMINFO 0x00000002
    3.97 -#define XEN_REACTOS_FLAG_NEEDVIDINFO 0x00000004
    3.98 -#define XEN_REACTOS_FLAG_ADDRSVALID  0x00010000
    3.99 -
   3.100 -/* Flags we test for */
   3.101 -#define FLAGS_MASK     ((~ 0) & (~ XEN_REACTOS_FLAG_ALIGN4K))
   3.102 -#define FLAGS_REQUIRED XEN_REACTOS_FLAG_ADDRSVALID
   3.103 -
   3.104 -static const struct xen_bin_image_table *
   3.105 -findtable(const char *image, unsigned long image_size);
   3.106 -static int
   3.107 -parsebinimage(
   3.108 -    const char *image, unsigned long image_size,
   3.109 -    struct domain_setup_info *dsi);
   3.110 -static int
   3.111 -loadbinimage(
   3.112 -    const char *image, unsigned long image_size, int xch, uint32_t dom,
   3.113 -    xen_pfn_t *parray, struct domain_setup_info *dsi);
   3.114 -
   3.115 -int probe_bin(const char *image,
   3.116 -              unsigned long image_size,
   3.117 -              struct load_funcs *load_funcs)
   3.118 -{
   3.119 -    if ( findtable(image, image_size) == NULL )
   3.120 -        return -EINVAL;
   3.121 -
   3.122 -    load_funcs->parseimage = parsebinimage;
   3.123 -    load_funcs->loadimage = loadbinimage;
   3.124 -
   3.125 -    return 0;
   3.126 -}
   3.127 -
   3.128 -static const struct xen_bin_image_table *
   3.129 -findtable(const char *image, unsigned long image_size)
   3.130 -{
   3.131 -    const struct xen_bin_image_table *table;
   3.132 -    const unsigned long *probe_ptr;
   3.133 -    unsigned probe_index;
   3.134 -    unsigned probe_count;
   3.135 -
   3.136 -    /* Don't go outside the image */
   3.137 -    if ( image_size < sizeof(struct xen_bin_image_table) )
   3.138 -        return NULL;
   3.139 -
   3.140 -    probe_count = image_size;
   3.141 -    /* Restrict to first 8k */
   3.142 -    if ( probe_count > 8192 )
   3.143 -        probe_count = 8192;
   3.144 -    probe_count = (probe_count - sizeof(struct xen_bin_image_table)) /
   3.145 -                  sizeof(unsigned long);
   3.146 -
   3.147 -    /* Search for the magic header */
   3.148 -    probe_ptr = (const unsigned long *) image;
   3.149 -    table = NULL;
   3.150 -    for ( probe_index = 0; probe_index < probe_count; probe_index++ )
   3.151 -    {
   3.152 -        if ( XEN_REACTOS_MAGIC3 == *probe_ptr )
   3.153 -        {
   3.154 -            table = (const struct xen_bin_image_table *) probe_ptr;
   3.155 -            /* Checksum correct? */
   3.156 -            if ( 0 == table->magic + table->flags + table->checksum )
   3.157 -            {
   3.158 -                return table;
   3.159 -            }
   3.160 -        }
   3.161 -        probe_ptr++;
   3.162 -    }
   3.163 -
   3.164 -    return NULL;
   3.165 -}
   3.166 -
   3.167 -static int parsebinimage(const char *image,
   3.168 -                         unsigned long image_size,
   3.169 -                         struct domain_setup_info *dsi)
   3.170 -{
   3.171 -    const struct xen_bin_image_table *image_info;
   3.172 -    unsigned long start_addr;
   3.173 -    unsigned long end_addr;
   3.174 -
   3.175 -    image_info = findtable(image, image_size);
   3.176 -    if ( NULL == image_info )
   3.177 -    {
   3.178 -        ERROR("Image does not have a valid xen_bin_image_table table.");
   3.179 -        return -EINVAL;
   3.180 -    }
   3.181 -
   3.182 -    /* Check the flags */
   3.183 -    if ( FLAGS_REQUIRED != (image_info->flags & FLAGS_MASK) )
   3.184 -    {
   3.185 -        ERROR("xen_bin_image_table flags required 0x%08x found 0x%08lx",
   3.186 -              FLAGS_REQUIRED, image_info->flags & FLAGS_MASK);
   3.187 -        return -EINVAL;
   3.188 -    }
   3.189 -
   3.190 -    /* Sanity check on the addresses */
   3.191 -    if ( image_info->header_addr < image_info->load_addr ||
   3.192 -         ((const char *) image_info - image) <
   3.193 -         (image_info->header_addr - image_info->load_addr) )
   3.194 -    {
   3.195 -        ERROR("Invalid header_addr.");
   3.196 -        return -EINVAL;
   3.197 -    }
   3.198 -    start_addr = image_info->header_addr - ((const char *) image_info - image);
   3.199 -    if ( 0 != image_info->load_end_addr &&
   3.200 -         ( image_info->load_end_addr < image_info->load_end_addr ||
   3.201 -           start_addr + image_size < image_info->load_end_addr ) )
   3.202 -    {
   3.203 -        ERROR("Invalid load_end_addr");
   3.204 -        return -EINVAL;
   3.205 -    }
   3.206 -    end_addr = (0 == image_info->load_end_addr ? start_addr + image_size :
   3.207 -                                                 image_info->load_end_addr);
   3.208 -    if ( 0 != image_info->bss_end_addr &&
   3.209 -         image_info->bss_end_addr < end_addr )
   3.210 -    {
   3.211 -        ERROR("Invalid bss_end_addr");
   3.212 -        return -EINVAL;
   3.213 -    }
   3.214 -
   3.215 -    dsi->v_start = image_info->load_addr;
   3.216 -    if ( 0 != image_info->bss_end_addr )
   3.217 -    {
   3.218 -        dsi->v_end = image_info->bss_end_addr;
   3.219 -    }
   3.220 -    else if ( 0 != image_info->load_end_addr )
   3.221 -    {
   3.222 -        dsi->v_end = image_info->load_end_addr;
   3.223 -    }
   3.224 -    else
   3.225 -    {
   3.226 -        dsi->v_end = image_info->load_addr + image_size -
   3.227 -                     (((const char *) image_info - image) -
   3.228 -                      (image_info->header_addr - image_info->load_addr));
   3.229 -    }
   3.230 -    dsi->v_kernstart = dsi->v_start;
   3.231 -    dsi->v_kernend = dsi->v_end;
   3.232 -    dsi->v_kernentry = image_info->entry_addr;
   3.233 -    dsi->__xen_guest_string = NULL;
   3.234 -
   3.235 -    return 0;
   3.236 -}
   3.237 -
   3.238 -static int
   3.239 -loadbinimage(
   3.240 -    const char *image, unsigned long image_size, int xch, uint32_t dom,
   3.241 -    xen_pfn_t *parray, struct domain_setup_info *dsi)
   3.242 -{
   3.243 -    unsigned long size;
   3.244 -    char         *va;
   3.245 -    unsigned long done, chunksz;
   3.246 -    const struct xen_bin_image_table *image_info;
   3.247 -
   3.248 -    image_info = findtable(image, image_size);
   3.249 -    if ( NULL == image_info )
   3.250 -    {
   3.251 -        ERROR("Image does not have a valid xen_bin_image_table table.");
   3.252 -        return -EINVAL;
   3.253 -    }
   3.254 -
   3.255 -    /* Determine image size */
   3.256 -    if ( 0 == image_info->load_end_addr )
   3.257 -    {
   3.258 -        size = image_size  - (((const char *)image_info - image) -
   3.259 -                              (image_info->header_addr -
   3.260 -                               image_info->load_addr));
   3.261 -    }
   3.262 -    else
   3.263 -    {
   3.264 -        size = image_info->load_end_addr - image_info->load_addr;
   3.265 -    }
   3.266 -
   3.267 -    /* It's possible that we need to skip the first part of the image */
   3.268 -    image += ((const char *)image_info - image) -
   3.269 -             (image_info->header_addr - image_info->load_addr);
   3.270 -
   3.271 -    for ( done = 0; done < size; done += chunksz )
   3.272 -    {
   3.273 -        va = xc_map_foreign_range(
   3.274 -            xch, dom, PAGE_SIZE, PROT_WRITE, parray[done>>PAGE_SHIFT]);
   3.275 -        chunksz = size - done;
   3.276 -        if ( chunksz > PAGE_SIZE )
   3.277 -            chunksz = PAGE_SIZE;
   3.278 -        memcpy(va, image + done, chunksz);
   3.279 -        munmap(va, PAGE_SIZE);
   3.280 -    }
   3.281 -
   3.282 -    if ( 0 != image_info->bss_end_addr &&
   3.283 -         image_info->load_addr + size < image_info->bss_end_addr )
   3.284 -    {
   3.285 -        size = image_info->bss_end_addr - image_info->load_addr;
   3.286 -    }
   3.287 -    for ( ; done < size; done += chunksz )
   3.288 -    {
   3.289 -        va = xc_map_foreign_range(
   3.290 -            xch, dom, PAGE_SIZE, PROT_WRITE, parray[done>>PAGE_SHIFT]);
   3.291 -        chunksz = size - done;
   3.292 -        if ( chunksz > (PAGE_SIZE - (done & (PAGE_SIZE-1))) )
   3.293 -            chunksz = PAGE_SIZE - (done & (PAGE_SIZE-1));
   3.294 -        memset(va + (done & (PAGE_SIZE-1)), 0, chunksz);
   3.295 -        munmap(va, PAGE_SIZE);
   3.296 -    }
   3.297 -
   3.298 -    return 0;
   3.299 -}
   3.300 -
   3.301 -/*
   3.302 - * Local variables:
   3.303 - * mode: C
   3.304 - * c-set-style: "BSD"
   3.305 - * c-basic-offset: 4
   3.306 - * tab-width: 4
   3.307 - * indent-tabs-mode: nil
   3.308 - * End:
   3.309 - */
     4.1 --- a/tools/libxc/xc_load_elf.c	Wed Feb 14 12:18:32 2007 -0800
     4.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
     4.3 @@ -1,684 +0,0 @@
     4.4 -/******************************************************************************
     4.5 - * xc_elf_load.c
     4.6 - */
     4.7 -
     4.8 -#include "xg_private.h"
     4.9 -#include "xc_elf.h"
    4.10 -#include <stdlib.h>
    4.11 -#include <inttypes.h>
    4.12 -
    4.13 -#define round_pgup(_p)    (((_p)+(PAGE_SIZE-1))&PAGE_MASK)
    4.14 -#define round_pgdown(_p)  ((_p)&PAGE_MASK)
    4.15 -
    4.16 -static int
    4.17 -parseelfimage(
    4.18 -    const char *image, unsigned long image_size,
    4.19 -    struct domain_setup_info *dsi);
    4.20 -static int
    4.21 -loadelfimage(
    4.22 -    const char *image, unsigned long image_size, int xch, uint32_t dom,
    4.23 -    xen_pfn_t *parray, struct domain_setup_info *dsi);
    4.24 -static int
    4.25 -loadelfsymtab(
    4.26 -    const char *image, int xch, uint32_t dom, xen_pfn_t *parray,
    4.27 -    struct domain_setup_info *dsi);
    4.28 -
    4.29 -/*
    4.30 - * Elf header attributes we require for each supported host platform.
    4.31 - * These are checked in parseelfimage().
    4.32 - */
    4.33 -#if defined(__ia64__)
    4.34 -#define ELFCLASS   ELFCLASS64
    4.35 -#define ELFCLASS_DESC "64-bit"
    4.36 -
    4.37 -#define ELFDATA    ELFDATA2LSB
    4.38 -#define ELFDATA_DESC "Little-Endian"
    4.39 -
    4.40 -#define ELFMACHINE EM_IA_64
    4.41 -#define ELFMACHINE_DESC "ia64"
    4.42 -
    4.43 -
    4.44 -#elif defined(__i386__)
    4.45 -#define ELFCLASS   ELFCLASS32
    4.46 -#define ELFCLASS_DESC "32-bit"
    4.47 -
    4.48 -#define ELFDATA    ELFDATA2LSB
    4.49 -#define ELFDATA_DESC "Little-Endian"
    4.50 -
    4.51 -#define ELFMACHINE EM_386
    4.52 -#define ELFMACHINE_DESC "i386"
    4.53 -
    4.54 -
    4.55 -#elif defined(__x86_64__)
    4.56 -#define ELFCLASS   ELFCLASS64
    4.57 -#define ELFCLASS_DESC "64-bit"
    4.58 -
    4.59 -#define ELFDATA    ELFDATA2LSB
    4.60 -#define ELFDATA_DESC "Little-Endian"
    4.61 -
    4.62 -#define ELFMACHINE EM_X86_64
    4.63 -#define ELFMACHINE_DESC "x86_64"
    4.64 -
    4.65 -
    4.66 -#elif defined(__powerpc__)
    4.67 -#define ELFCLASS   ELFCLASS64
    4.68 -#define ELFCLASS_DESC "64-bit"
    4.69 -
    4.70 -#define ELFDATA    ELFDATA2MSB
    4.71 -#define ELFDATA_DESC "Big-Endian"
    4.72 -
    4.73 -#define ELFMACHINE EM_PPC64
    4.74 -#define ELFMACHINE_DESC "ppc64"
    4.75 -#endif
    4.76 -
    4.77 -int probe_elf(const char *image,
    4.78 -              unsigned long image_size,
    4.79 -              struct load_funcs *load_funcs)
    4.80 -{
    4.81 -    const Elf_Ehdr *ehdr = (const Elf_Ehdr *)image;
    4.82 -
    4.83 -    if ( !IS_ELF(*ehdr) )
    4.84 -        return -EINVAL;
    4.85 -
    4.86 -    load_funcs->parseimage = parseelfimage;
    4.87 -    load_funcs->loadimage = loadelfimage;
    4.88 -
    4.89 -    return 0;
    4.90 -}
    4.91 -
    4.92 -static inline int is_loadable_phdr(const Elf_Phdr *phdr)
    4.93 -{
    4.94 -    return ((phdr->p_type == PT_LOAD) &&
    4.95 -            ((phdr->p_flags & (PF_W|PF_X)) != 0));
    4.96 -}
    4.97 -
    4.98 -/*
    4.99 - * Fallback for kernels containing only the legacy __xen_guest string
   4.100 - * and no ELF notes.
   4.101 - */
   4.102 -static int is_xen_guest_section(const Elf_Shdr *shdr, const char *shstrtab)
   4.103 -{
   4.104 -    return strcmp(&shstrtab[shdr->sh_name], "__xen_guest") == 0;
   4.105 -}
   4.106 -
   4.107 -static const char *xen_guest_lookup(
   4.108 -    const struct domain_setup_info *dsi, int type)
   4.109 -{
   4.110 -    const char *xenguest_fallbacks[] = {
   4.111 -        [XEN_ELFNOTE_ENTRY] = "VIRT_ENTRY=",
   4.112 -        [XEN_ELFNOTE_HYPERCALL_PAGE] = "HYPERCALL_PAGE=",
   4.113 -        [XEN_ELFNOTE_VIRT_BASE] = "VIRT_BASE=",
   4.114 -        [XEN_ELFNOTE_PADDR_OFFSET] = "ELF_PADDR_OFFSET=",
   4.115 -        [XEN_ELFNOTE_XEN_VERSION] = "XEN_VER=",
   4.116 -        [XEN_ELFNOTE_GUEST_OS] = "GUEST_OS=",
   4.117 -        [XEN_ELFNOTE_GUEST_VERSION] = "GUEST_VER=",
   4.118 -        [XEN_ELFNOTE_LOADER] = "LOADER=",
   4.119 -        [XEN_ELFNOTE_PAE_MODE] = "PAE=",
   4.120 -        [XEN_ELFNOTE_FEATURES] = "FEATURES=",
   4.121 -        [XEN_ELFNOTE_BSD_SYMTAB] = "BSD_SYMTAB=",
   4.122 -    };
   4.123 -    const char *fallback;
   4.124 -    const char *p;
   4.125 -
   4.126 -    if ( !dsi->__xen_guest_string )
   4.127 -        return NULL;
   4.128 -
   4.129 -    if ( type > sizeof(xenguest_fallbacks) )
   4.130 -        return NULL;
   4.131 -
   4.132 -    if ( (fallback = xenguest_fallbacks[type]) == NULL )
   4.133 -        return NULL;
   4.134 -
   4.135 -    if ( (p = strstr(dsi->__xen_guest_string,fallback)) == NULL )
   4.136 -        return NULL;
   4.137 -
   4.138 -    return p + strlen(fallback);
   4.139 -}
   4.140 -
   4.141 -static const char *xen_guest_string(
   4.142 -    const struct domain_setup_info *dsi, int type)
   4.143 -{
   4.144 -    const char *p = xen_guest_lookup(dsi, type);
   4.145 -
   4.146 -    /*
   4.147 -     * We special case this since the __xen_guest_section treats the
   4.148 -     * mere precense of the BSD_SYMTAB string as true or false.
   4.149 -     */
   4.150 -    if ( type == XEN_ELFNOTE_BSD_SYMTAB )
   4.151 -        return p ? "yes" : "no";
   4.152 -
   4.153 -    return p;
   4.154 -}
   4.155 -
   4.156 -static unsigned long long xen_guest_numeric(
   4.157 -    const struct domain_setup_info *dsi, int type, int *defined)
   4.158 -{
   4.159 -    const char *p = xen_guest_lookup(dsi, type);
   4.160 -    unsigned long long value;
   4.161 -
   4.162 -    if ( p == NULL )
   4.163 -        return 0;
   4.164 -
   4.165 -    errno = 0;
   4.166 -    value = strtoull(p, NULL, 0);
   4.167 -    if ( errno < 0 )
   4.168 -        return 0;
   4.169 -
   4.170 -    /* We special case this since __xen_guest_section contains a PFN
   4.171 -     * for this field not a virtual address.
   4.172 -     */
   4.173 -    if (type == XEN_ELFNOTE_HYPERCALL_PAGE)
   4.174 -        value = dsi->v_start + (value<<PAGE_SHIFT);
   4.175 -
   4.176 -    *defined = 1;
   4.177 -    return value;
   4.178 -}
   4.179 -
   4.180 -/*
   4.181 - * Interface to the Xen ELF notes.
   4.182 - */
   4.183 -#define ELFNOTE_NAME(_n_)   ((const char*)(_n_) + sizeof(*(_n_)))
   4.184 -#define ELFNOTE_DESC(_n_)   (ELFNOTE_NAME(_n_) + (((_n_)->namesz+3)&~3))
   4.185 -#define ELFNOTE_NEXT(_n_)   (ELFNOTE_DESC(_n_) + (((_n_)->descsz+3)&~3))
   4.186 -
   4.187 -static int is_xen_elfnote_section(const char *image, const Elf_Shdr *shdr)
   4.188 -{
   4.189 -    const Elf_Note *note;
   4.190 -
   4.191 -    if ( shdr->sh_type != SHT_NOTE )
   4.192 -        return 0;
   4.193 -
   4.194 -    for ( note = (const Elf_Note *)(image + shdr->sh_offset);
   4.195 -          note < (const Elf_Note *)(image + shdr->sh_offset + shdr->sh_size);
   4.196 -          note = (const Elf_Note *)ELFNOTE_NEXT(note) )
   4.197 -    {
   4.198 -        if ( !strncmp(ELFNOTE_NAME(note), "Xen", 4) )
   4.199 -            return 1;
   4.200 -    }
   4.201 -
   4.202 -    return 0;
   4.203 -}
   4.204 -
   4.205 -static const Elf_Note *xen_elfnote_lookup(
   4.206 -    const struct domain_setup_info *dsi, int type)
   4.207 -{
   4.208 -    const Elf_Note *note;
   4.209 -
   4.210 -    if ( !dsi->__elfnote_section )
   4.211 -        return NULL;
   4.212 -
   4.213 -    for ( note = (const Elf_Note *)dsi->__elfnote_section;
   4.214 -          note < (const Elf_Note *)dsi->__elfnote_section_end;
   4.215 -          note = (const Elf_Note *)ELFNOTE_NEXT(note) )
   4.216 -    {
   4.217 -        if ( strncmp(ELFNOTE_NAME(note), "Xen", 4) )
   4.218 -            continue;
   4.219 -
   4.220 -        if ( note->type == type )
   4.221 -            return note;
   4.222 -    }
   4.223 -
   4.224 -    return NULL;
   4.225 -}
   4.226 -
   4.227 -const char *xen_elfnote_string(const struct domain_setup_info *dsi, int type)
   4.228 -{
   4.229 -    const Elf_Note *note;
   4.230 -
   4.231 -    if ( !dsi->__elfnote_section )
   4.232 -        return xen_guest_string(dsi, type);
   4.233 -
   4.234 -    note = xen_elfnote_lookup(dsi, type);
   4.235 -    if ( note == NULL )
   4.236 -        return NULL;
   4.237 -
   4.238 -    return (const char *)ELFNOTE_DESC(note);
   4.239 -}
   4.240 -
   4.241 -unsigned long long xen_elfnote_numeric(const struct domain_setup_info *dsi,
   4.242 -                                       int type, int *defined)
   4.243 -{
   4.244 -    const Elf_Note *note;
   4.245 -
   4.246 -    *defined = 0;
   4.247 -
   4.248 -    if ( !dsi->__elfnote_section )
   4.249 -        return xen_guest_numeric(dsi, type, defined);
   4.250 -
   4.251 -    note = xen_elfnote_lookup(dsi, type);
   4.252 -    if ( note == NULL )
   4.253 -    {
   4.254 -        return 0;
   4.255 -    }
   4.256 -
   4.257 -    switch ( note->descsz )
   4.258 -    {
   4.259 -    case 4:
   4.260 -        *defined = 1;
   4.261 -        return *(const uint32_t*)ELFNOTE_DESC(note);
   4.262 -    case 8:
   4.263 -        *defined = 1;
   4.264 -        return *(const uint64_t*)ELFNOTE_DESC(note);
   4.265 -    default:
   4.266 -        xc_set_error(XC_INVALID_KERNEL,
   4.267 -                     "elfnotes: unknown data size %#x for numeric type note %#x\n",
   4.268 -              note->descsz, type);
   4.269 -        return 0;
   4.270 -    }
   4.271 -}
   4.272 -
   4.273 -static int parseelfimage(const char *image,
   4.274 -                         unsigned long image_len,
   4.275 -                         struct domain_setup_info *dsi)
   4.276 -{
   4.277 -    const Elf_Ehdr *ehdr = (const Elf_Ehdr *)image;
   4.278 -    const Elf_Phdr *phdr;
   4.279 -    const Elf_Shdr *shdr;
   4.280 -    Elf_Addr kernstart = ~0, kernend = 0, vaddr, virt_entry;
   4.281 -    const char *shstrtab, *p;
   4.282 -    int h, virt_base_defined, elf_pa_off_defined, virt_entry_defined;
   4.283 -
   4.284 -    if ( !IS_ELF(*ehdr) )
   4.285 -    {
   4.286 -        xc_set_error(XC_INVALID_KERNEL,
   4.287 -                     "Kernel image does not have an ELF header.");
   4.288 -        return -EINVAL;
   4.289 -    }
   4.290 -
   4.291 -    if (ehdr->e_machine != ELFMACHINE)
   4.292 -    {
   4.293 -        xc_set_error(XC_INVALID_KERNEL,
   4.294 -                     "Kernel ELF architecture '%d' does not match Xen architecture '%d' (%s)",
   4.295 -                     ehdr->e_machine, ELFMACHINE, ELFMACHINE_DESC);
   4.296 -        return -EINVAL;
   4.297 -    }
   4.298 -    if (ehdr->e_ident[EI_CLASS] != ELFCLASS)
   4.299 -    {
   4.300 -        xc_set_error(XC_INVALID_KERNEL,
   4.301 -                     "Kernel ELF wordsize '%d' does not match Xen wordsize '%d' (%s)",
   4.302 -                     ehdr->e_ident[EI_CLASS], ELFCLASS, ELFCLASS_DESC);
   4.303 -        return -EINVAL;
   4.304 -    }
   4.305 -    if (ehdr->e_ident[EI_DATA] != ELFDATA)
   4.306 -    {
   4.307 -        xc_set_error(XC_INVALID_KERNEL,
   4.308 -                     "Kernel ELF endianness '%d' does not match Xen endianness '%d' (%s)",
   4.309 -                     ehdr->e_ident[EI_DATA], ELFDATA, ELFDATA_DESC);
   4.310 -        return -EINVAL;
   4.311 -    }
   4.312 -    if (ehdr->e_type != ET_EXEC)
   4.313 -    {
   4.314 -        xc_set_error(XC_INVALID_KERNEL,
   4.315 -                     "Kernel ELF type '%d' does not match Xen type '%d'",
   4.316 -                     ehdr->e_type, ET_EXEC);
   4.317 -        return -EINVAL;
   4.318 -    }
   4.319 -
   4.320 -    if ( (ehdr->e_phoff + (ehdr->e_phnum*ehdr->e_phentsize)) > image_len )
   4.321 -    {
   4.322 -        xc_set_error(XC_INVALID_KERNEL,
   4.323 -                     "ELF program headers extend beyond end of image.");
   4.324 -        return -EINVAL;
   4.325 -    }
   4.326 -
   4.327 -    if ( (ehdr->e_shoff + (ehdr->e_shnum*ehdr->e_shentsize)) > image_len )
   4.328 -    {
   4.329 -        xc_set_error(XC_INVALID_KERNEL,
   4.330 -                     "ELF section headers extend beyond end of image.");
   4.331 -        return -EINVAL;
   4.332 -    }
   4.333 -
   4.334 -    dsi->__elfnote_section = NULL;
   4.335 -    dsi->__xen_guest_string = NULL;
   4.336 -
   4.337 -    /* Look for .notes segment containing at least one Xen note */
   4.338 -    for ( h = 0; h < ehdr->e_shnum; h++ )
   4.339 -    {
   4.340 -        shdr = (const Elf_Shdr *)(
   4.341 -            image + ehdr->e_shoff + (h*ehdr->e_shentsize));
   4.342 -        if ( !is_xen_elfnote_section(image, shdr) )
   4.343 -            continue;
   4.344 -        dsi->__elfnote_section = (const char *)image + shdr->sh_offset;
   4.345 -        dsi->__elfnote_section_end =
   4.346 -            (const char *)image + shdr->sh_offset + shdr->sh_size;
   4.347 -        break;
   4.348 -    }
   4.349 -
   4.350 -    /* Fall back to looking for the special '__xen_guest' section. */
   4.351 -    if ( dsi->__elfnote_section == NULL )
   4.352 -    {
   4.353 -        /* Find the section-header strings table. */
   4.354 -        if ( ehdr->e_shstrndx == SHN_UNDEF )
   4.355 -        {
   4.356 -            xc_set_error(XC_INVALID_KERNEL,
   4.357 -                         "ELF image has no section-header strings table.");
   4.358 -            return -EINVAL;
   4.359 -        }
   4.360 -        shdr = (const Elf_Shdr *)(image + ehdr->e_shoff +
   4.361 -                            (ehdr->e_shstrndx*ehdr->e_shentsize));
   4.362 -        shstrtab = image + shdr->sh_offset;
   4.363 -
   4.364 -        for ( h = 0; h < ehdr->e_shnum; h++ )
   4.365 -        {
   4.366 -            shdr = (const Elf_Shdr *)(
   4.367 -                image + ehdr->e_shoff + (h*ehdr->e_shentsize));
   4.368 -            if ( is_xen_guest_section(shdr, shstrtab) )
   4.369 -            {
   4.370 -                dsi->__xen_guest_string =
   4.371 -                    (const char *)image + shdr->sh_offset;
   4.372 -                break;
   4.373 -            }
   4.374 -        }
   4.375 -    }
   4.376 -
   4.377 -    /* Check the contents of the Xen notes or guest string. */
   4.378 -    if ( dsi->__elfnote_section || dsi->__xen_guest_string )
   4.379 -    {
   4.380 -        const char *loader = xen_elfnote_string(dsi, XEN_ELFNOTE_LOADER);
   4.381 -        const char *guest_os = xen_elfnote_string(dsi, XEN_ELFNOTE_GUEST_OS);
   4.382 -        const char *xen_version =
   4.383 -            xen_elfnote_string(dsi, XEN_ELFNOTE_XEN_VERSION);
   4.384 -
   4.385 -        if ( ( loader == NULL || strncmp(loader, "generic", 7) ) &&
   4.386 -             ( guest_os == NULL || strncmp(guest_os, "linux", 5) ) )
   4.387 -        {
   4.388 -            xc_set_error(XC_INVALID_KERNEL,
   4.389 -                         "Will only load images built for the generic loader "
   4.390 -                         "or Linux images");
   4.391 -            return -EINVAL;
   4.392 -        }
   4.393 -
   4.394 -        if ( xen_version == NULL || strncmp(xen_version, "xen-3.0", 7) )
   4.395 -        {
   4.396 -            xc_set_error(XC_INVALID_KERNEL,
   4.397 -                         "Will only load images built for Xen v3.0");
   4.398 -            return -EINVAL;
   4.399 -        }
   4.400 -    }
   4.401 -    else
   4.402 -    {
   4.403 -#if defined(__x86_64__) || defined(__i386__)
   4.404 -        xc_set_error(XC_INVALID_KERNEL,
   4.405 -                     "Not a Xen-ELF image: "
   4.406 -                     "No ELF notes or '__xen_guest' section found.");
   4.407 -        return -EINVAL;
   4.408 -#endif
   4.409 -    }
   4.410 -
   4.411 -    /*
   4.412 -     * A "bimodal" ELF note indicates the kernel will adjust to the current
   4.413 -     * paging mode, including handling extended cr3 syntax.  If we have ELF
   4.414 -     * notes then PAE=yes implies that we must support the extended cr3 syntax.
   4.415 -     * Otherwise we need to find the [extended-cr3] syntax in the __xen_guest
   4.416 -     * string. We use strstr() to look for "bimodal" to allow guests to use
   4.417 -     * "yes,bimodal" or "no,bimodal" for compatibility reasons.
   4.418 -     */
   4.419 -
   4.420 -    dsi->pae_kernel = PAEKERN_no;
   4.421 -    if ( dsi->__elfnote_section )
   4.422 -    {
   4.423 -        p = xen_elfnote_string(dsi, XEN_ELFNOTE_PAE_MODE);
   4.424 -        if ( p != NULL && strstr(p, "bimodal") != NULL )
   4.425 -            dsi->pae_kernel = PAEKERN_bimodal;
   4.426 -        else if ( p != NULL && strncmp(p, "yes", 3) == 0 )
   4.427 -            dsi->pae_kernel = PAEKERN_extended_cr3;
   4.428 -
   4.429 -    }
   4.430 -    else
   4.431 -    {
   4.432 -        p = xen_guest_lookup(dsi, XEN_ELFNOTE_PAE_MODE);
   4.433 -        if ( p != NULL && strncmp(p, "yes", 3) == 0 )
   4.434 -        {
   4.435 -            dsi->pae_kernel = PAEKERN_yes;
   4.436 -            if ( !strncmp(p+3, "[extended-cr3]", 14) )
   4.437 -                dsi->pae_kernel = PAEKERN_extended_cr3;
   4.438 -        }
   4.439 -    }
   4.440 -
   4.441 -    /* Initial guess for v_start is 0 if it is not explicitly defined. */
   4.442 -    dsi->v_start =
   4.443 -        xen_elfnote_numeric(dsi, XEN_ELFNOTE_VIRT_BASE, &virt_base_defined);
   4.444 -    if ( !virt_base_defined )
   4.445 -        dsi->v_start = 0;
   4.446 -
   4.447 -    /*
   4.448 -     * If we are using the legacy __xen_guest section then elf_pa_off
   4.449 -     * defaults to v_start in order to maintain compatibility with
   4.450 -     * older hypervisors which set padd in the ELF header to
   4.451 -     * virt_base.
   4.452 -     *
   4.453 -     * If we are using the modern ELF notes interface then the default
   4.454 -     * is 0.
   4.455 -     */
   4.456 -    dsi->elf_paddr_offset = xen_elfnote_numeric(dsi, XEN_ELFNOTE_PADDR_OFFSET,
   4.457 -                                                &elf_pa_off_defined);
   4.458 -    if ( !elf_pa_off_defined )
   4.459 -    {
   4.460 -        if ( dsi->__elfnote_section )
   4.461 -            dsi->elf_paddr_offset = 0;
   4.462 -        else
   4.463 -            dsi->elf_paddr_offset = dsi->v_start;
   4.464 -    }
   4.465 -
   4.466 -    if ( elf_pa_off_defined && !virt_base_defined )
   4.467 -    {
   4.468 -        xc_set_error(XC_INVALID_KERNEL,
   4.469 -                     "Neither ELF_PADDR_OFFSET nor VIRT_BASE found in ELF "
   4.470 -                     " notes or __xen_guest section.");
   4.471 -        return -EINVAL;
   4.472 -    }
   4.473 -
   4.474 -    for ( h = 0; h < ehdr->e_phnum; h++ )
   4.475 -    {
   4.476 -        phdr = (const Elf_Phdr *)(
   4.477 -            image + ehdr->e_phoff + (h*ehdr->e_phentsize));
   4.478 -        if ( !is_loadable_phdr(phdr) )
   4.479 -            continue;
   4.480 -        vaddr = phdr->p_paddr - dsi->elf_paddr_offset + dsi->v_start;
   4.481 -        if ( (vaddr + phdr->p_memsz) < vaddr )
   4.482 -        {
   4.483 -            xc_set_error(XC_INVALID_KERNEL,
   4.484 -                         "ELF program header %d is too large.", h);
   4.485 -            return -EINVAL;
   4.486 -        }
   4.487 -
   4.488 -        if ( vaddr < kernstart )
   4.489 -            kernstart = vaddr;
   4.490 -        if ( (vaddr + phdr->p_memsz) > kernend )
   4.491 -            kernend = vaddr + phdr->p_memsz;
   4.492 -    }
   4.493 -
   4.494 -    dsi->v_kernentry = ehdr->e_entry;
   4.495 -
   4.496 -    virt_entry =
   4.497 -        xen_elfnote_numeric(dsi, XEN_ELFNOTE_ENTRY, &virt_entry_defined);
   4.498 -    if ( virt_entry_defined )
   4.499 -        dsi->v_kernentry = virt_entry;
   4.500 -
   4.501 -    if ( (kernstart > kernend) ||
   4.502 -         (dsi->v_kernentry < kernstart) ||
   4.503 -         (dsi->v_kernentry > kernend) ||
   4.504 -         (dsi->v_start > kernstart) )
   4.505 -    {
   4.506 -        xc_set_error(XC_INVALID_KERNEL,
   4.507 -                     "ELF start or entries are out of bounds.");
   4.508 -        return -EINVAL;
   4.509 -    }
   4.510 -
   4.511 -    p = xen_elfnote_string(dsi, XEN_ELFNOTE_BSD_SYMTAB);
   4.512 -    if ( p != NULL && strncmp(p, "yes", 3) == 0 )
   4.513 -        dsi->load_symtab = 1;
   4.514 -
   4.515 -    dsi->v_kernstart = kernstart;
   4.516 -    dsi->v_kernend   = kernend;
   4.517 -    dsi->v_end       = dsi->v_kernend;
   4.518 -
   4.519 -    loadelfsymtab(image, 0, 0, NULL, dsi);
   4.520 -
   4.521 -    return 0;
   4.522 -}
   4.523 -
   4.524 -static int
   4.525 -loadelfimage(
   4.526 -    const char *image, unsigned long elfsize, int xch, uint32_t dom,
   4.527 -    xen_pfn_t *parray, struct domain_setup_info *dsi)
   4.528 -{
   4.529 -    const Elf_Ehdr *ehdr = (const Elf_Ehdr *)image;
   4.530 -    const Elf_Phdr *phdr;
   4.531 -    int h;
   4.532 -
   4.533 -    char         *va;
   4.534 -    unsigned long pa, done, chunksz;
   4.535 -
   4.536 -    for ( h = 0; h < ehdr->e_phnum; h++ )
   4.537 -    {
   4.538 -        phdr = (const Elf_Phdr *)(
   4.539 -            image + ehdr->e_phoff + (h*ehdr->e_phentsize));
   4.540 -        if ( !is_loadable_phdr(phdr) )
   4.541 -            continue;
   4.542 -
   4.543 -        for ( done = 0; done < phdr->p_filesz; done += chunksz )
   4.544 -        {
   4.545 -            pa = (phdr->p_paddr + done) - dsi->elf_paddr_offset;
   4.546 -            va = xc_map_foreign_range(
   4.547 -                xch, dom, PAGE_SIZE, PROT_WRITE, parray[pa>>PAGE_SHIFT]);
   4.548 -            if ( va == NULL )
   4.549 -                return -1;
   4.550 -            chunksz = phdr->p_filesz - done;
   4.551 -            if ( chunksz > (PAGE_SIZE - (pa & (PAGE_SIZE-1))) )
   4.552 -                chunksz = PAGE_SIZE - (pa & (PAGE_SIZE-1));
   4.553 -            memcpy(va + (pa & (PAGE_SIZE-1)),
   4.554 -                   image + phdr->p_offset + done, chunksz);
   4.555 -            munmap(va, PAGE_SIZE);
   4.556 -        }
   4.557 -
   4.558 -        for ( ; done < phdr->p_memsz; done += chunksz )
   4.559 -        {
   4.560 -            pa = (phdr->p_paddr + done) - dsi->elf_paddr_offset;
   4.561 -            va = xc_map_foreign_range(
   4.562 -                xch, dom, PAGE_SIZE, PROT_WRITE, parray[pa>>PAGE_SHIFT]);
   4.563 -            if ( va == NULL )
   4.564 -                return -1;
   4.565 -            chunksz = phdr->p_memsz - done;
   4.566 -            if ( chunksz > (PAGE_SIZE - (pa & (PAGE_SIZE-1))) )
   4.567 -                chunksz = PAGE_SIZE - (pa & (PAGE_SIZE-1));
   4.568 -            memset(va + (pa & (PAGE_SIZE-1)), 0, chunksz);
   4.569 -            munmap(va, PAGE_SIZE);
   4.570 -        }
   4.571 -    }
   4.572 -
   4.573 -    loadelfsymtab(image, xch, dom, parray, dsi);
   4.574 -
   4.575 -    return 0;
   4.576 -}
   4.577 -
   4.578 -#define ELFROUND (ELFSIZE / 8)
   4.579 -
   4.580 -static int
   4.581 -loadelfsymtab(
   4.582 -    const char *image, int xch, uint32_t dom, xen_pfn_t *parray,
   4.583 -    struct domain_setup_info *dsi)
   4.584 -{
   4.585 -    const Elf_Ehdr *ehdr = (const Elf_Ehdr *)image;
   4.586 -    Elf_Ehdr *sym_ehdr;
   4.587 -    Elf_Shdr *shdr;
   4.588 -    unsigned long maxva, symva;
   4.589 -    char *p;
   4.590 -    int h, i;
   4.591 -
   4.592 -    if ( !dsi->load_symtab )
   4.593 -        return 0;
   4.594 -
   4.595 -    p = malloc(sizeof(int) + sizeof(Elf_Ehdr) +
   4.596 -               ehdr->e_shnum * sizeof(Elf_Shdr));
   4.597 -    if (p == NULL)
   4.598 -        return 0;
   4.599 -
   4.600 -    maxva = (dsi->v_kernend + ELFROUND - 1) & ~(ELFROUND - 1);
   4.601 -    symva = maxva;
   4.602 -    maxva += sizeof(int);
   4.603 -    dsi->symtab_addr = maxva;
   4.604 -    dsi->symtab_len = 0;
   4.605 -    maxva += sizeof(Elf_Ehdr) + ehdr->e_shnum * sizeof(Elf_Shdr);
   4.606 -    maxva = (maxva + ELFROUND - 1) & ~(ELFROUND - 1);
   4.607 -
   4.608 -    shdr = (Elf_Shdr *)(p + sizeof(int) + sizeof(Elf_Ehdr));
   4.609 -    memcpy(shdr, image + ehdr->e_shoff, ehdr->e_shnum * sizeof(Elf_Shdr));
   4.610 -
   4.611 -    for ( h = 0; h < ehdr->e_shnum; h++ )
   4.612 -    {
   4.613 -        if ( shdr[h].sh_type == SHT_STRTAB )
   4.614 -        {
   4.615 -            /* Look for a strtab @i linked to symtab @h. */
   4.616 -            for ( i = 0; i < ehdr->e_shnum; i++ )
   4.617 -                if ( (shdr[i].sh_type == SHT_SYMTAB) &&
   4.618 -                     (shdr[i].sh_link == h) )
   4.619 -                    break;
   4.620 -            /* Skip symtab @h if we found no corresponding strtab @i. */
   4.621 -            if ( i == ehdr->e_shnum )
   4.622 -            {
   4.623 -                shdr[h].sh_offset = 0;
   4.624 -                continue;
   4.625 -            }
   4.626 -        }
   4.627 -
   4.628 -        if ( (shdr[h].sh_type == SHT_STRTAB) ||
   4.629 -             (shdr[h].sh_type == SHT_SYMTAB) )
   4.630 -        {
   4.631 -            if ( parray != NULL )
   4.632 -                xc_map_memcpy(maxva, image + shdr[h].sh_offset,
   4.633 -                              shdr[h].sh_size,
   4.634 -                              xch, dom, parray, dsi->v_start);
   4.635 -
   4.636 -            /* Mangled to be based on ELF header location. */
   4.637 -            shdr[h].sh_offset = maxva - dsi->symtab_addr;
   4.638 -
   4.639 -            dsi->symtab_len += shdr[h].sh_size;
   4.640 -            maxva += shdr[h].sh_size;
   4.641 -            maxva = (maxva + ELFROUND - 1) & ~(ELFROUND - 1);
   4.642 -        }
   4.643 -
   4.644 -        shdr[h].sh_name = 0;  /* Name is NULL. */
   4.645 -    }
   4.646 -
   4.647 -    if ( dsi->symtab_len == 0 )
   4.648 -    {
   4.649 -        dsi->symtab_addr = 0;
   4.650 -        goto out;
   4.651 -    }
   4.652 -
   4.653 -    if ( parray != NULL )
   4.654 -    {
   4.655 -        *(int *)p = maxva - dsi->symtab_addr;
   4.656 -        sym_ehdr = (Elf_Ehdr *)(p + sizeof(int));
   4.657 -        memcpy(sym_ehdr, ehdr, sizeof(Elf_Ehdr));
   4.658 -        sym_ehdr->e_phoff = 0;
   4.659 -        sym_ehdr->e_shoff = sizeof(Elf_Ehdr);
   4.660 -        sym_ehdr->e_phentsize = 0;
   4.661 -        sym_ehdr->e_phnum = 0;
   4.662 -        sym_ehdr->e_shstrndx = SHN_UNDEF;
   4.663 -
   4.664 -        /* Copy total length, crafted ELF header and section header table */
   4.665 -        xc_map_memcpy(symva, p, sizeof(int) + sizeof(Elf_Ehdr) +
   4.666 -                   ehdr->e_shnum * sizeof(Elf_Shdr), xch, dom, parray,
   4.667 -                   dsi->v_start);
   4.668 -    }
   4.669 -
   4.670 -    dsi->symtab_len = maxva - dsi->symtab_addr;
   4.671 -    dsi->v_end = round_pgup(maxva);
   4.672 -
   4.673 - out:
   4.674 -    free(p);
   4.675 -
   4.676 -    return 0;
   4.677 -}
   4.678 -
   4.679 -/*
   4.680 - * Local variables:
   4.681 - * mode: C
   4.682 - * c-set-style: "BSD"
   4.683 - * c-basic-offset: 4
   4.684 - * tab-width: 4
   4.685 - * indent-tabs-mode: nil
   4.686 - * End:
   4.687 - */
     5.1 --- a/tools/libxc/xc_private.c	Wed Feb 14 12:18:32 2007 -0800
     5.2 +++ b/tools/libxc/xc_private.c	Thu Feb 15 10:25:39 2007 +0000
     5.3 @@ -377,26 +377,6 @@ int xc_clear_domain_page(int xc_handle,
     5.4      return 0;
     5.5  }
     5.6  
     5.7 -void xc_map_memcpy(unsigned long dst, const char *src, unsigned long size,
     5.8 -                   int xch, uint32_t dom, xen_pfn_t *parray,
     5.9 -                   unsigned long vstart)
    5.10 -{
    5.11 -    char *va;
    5.12 -    unsigned long chunksz, done, pa;
    5.13 -
    5.14 -    for ( done = 0; done < size; done += chunksz )
    5.15 -    {
    5.16 -        pa = dst + done - vstart;
    5.17 -        va = xc_map_foreign_range(
    5.18 -            xch, dom, PAGE_SIZE, PROT_WRITE, parray[pa>>PAGE_SHIFT]);
    5.19 -        chunksz = size - done;
    5.20 -        if ( chunksz > (PAGE_SIZE - (pa & (PAGE_SIZE-1))) )
    5.21 -            chunksz = PAGE_SIZE - (pa & (PAGE_SIZE-1));
    5.22 -        memcpy(va + (pa & (PAGE_SIZE-1)), src + done, chunksz);
    5.23 -        munmap(va, PAGE_SIZE);
    5.24 -    }
    5.25 -}
    5.26 -
    5.27  int xc_domctl(int xc_handle, struct xen_domctl *domctl)
    5.28  {
    5.29      return do_domctl(xc_handle, domctl);
     6.1 --- a/tools/libxc/xg_private.h	Wed Feb 14 12:18:32 2007 -0800
     6.2 +++ b/tools/libxc/xg_private.h	Thu Feb 15 10:25:39 2007 +0000
     6.3 @@ -139,92 +139,15 @@ typedef l4_pgentry_64_t l4_pgentry_t;
     6.4  #define PAGE_SIZE_IA64          (1UL << PAGE_SHIFT_IA64)
     6.5  #define PAGE_MASK_IA64          (~(PAGE_SIZE_IA64-1))
     6.6  
     6.7 -struct domain_setup_info
     6.8 -{
     6.9 -    uint64_t v_start;
    6.10 -    uint64_t v_end;
    6.11 -    uint64_t v_kernstart;
    6.12 -    uint64_t v_kernend;
    6.13 -    uint64_t v_kernentry;
    6.14 -
    6.15 -    uint64_t elf_paddr_offset;
    6.16 -
    6.17  #define PAEKERN_no           0
    6.18  #define PAEKERN_yes          1
    6.19  #define PAEKERN_extended_cr3 2
    6.20  #define PAEKERN_bimodal      3
    6.21 -    unsigned int  pae_kernel;
    6.22 -
    6.23 -    unsigned int  load_symtab;
    6.24 -    unsigned long symtab_addr;
    6.25 -    unsigned long symtab_len;
    6.26 -
    6.27 -    /*
    6.28 -     * Only one of __elfnote_* or __xen_guest_string will be
    6.29 -     * non-NULL.
    6.30 -     *
    6.31 -     * You should use the xen_elfnote_* accessors below in order to
    6.32 -     * pickup the correct one and retain backwards compatibility.
    6.33 -     */
    6.34 -    const void *__elfnote_section, *__elfnote_section_end;
    6.35 -    const char *__xen_guest_string;
    6.36 -};
    6.37 -
    6.38 -typedef int (*parseimagefunc)(const char *image, unsigned long image_size,
    6.39 -                              struct domain_setup_info *dsi);
    6.40 -typedef int (*loadimagefunc)(const char *image, unsigned long image_size,
    6.41 -                             int xch,
    6.42 -                             uint32_t dom, xen_pfn_t *parray,
    6.43 -                             struct domain_setup_info *dsi);
    6.44 -
    6.45 -/*
    6.46 - * If an ELF note of the given type is found then the value contained
    6.47 - * in the note is returned and *defined is set to non-zero. If no such
    6.48 - * note is found then *defined is set to 0 and 0 is returned.
    6.49 - */
    6.50 -extern unsigned long long xen_elfnote_numeric(const struct domain_setup_info *dsi,
    6.51 -					      int type, int *defined);
    6.52 -
    6.53 -/*
    6.54 - * If an ELF note of the given type is found then the string contained
    6.55 - * in the value is returned, otherwise NULL is returned.
    6.56 - */
    6.57 -extern const char * xen_elfnote_string(const struct domain_setup_info *dsi,
    6.58 -				       int type);
    6.59 -
    6.60 -struct load_funcs
    6.61 -{
    6.62 -    parseimagefunc parseimage;
    6.63 -    loadimagefunc loadimage;
    6.64 -};
    6.65 -
    6.66 -#define mfn_mapper_queue_size 128
    6.67 -
    6.68 -typedef struct mfn_mapper {
    6.69 -    int xc_handle;
    6.70 -    int size;
    6.71 -    int prot;
    6.72 -    int error;
    6.73 -    int max_queue_size;
    6.74 -    void * addr;
    6.75 -    privcmd_mmap_t ioctl;
    6.76 -
    6.77 -} mfn_mapper_t;
    6.78  
    6.79  int xc_copy_to_domain_page(int xc_handle, uint32_t domid,
    6.80                              unsigned long dst_pfn, const char *src_page);
    6.81  
    6.82 -void xc_map_memcpy(unsigned long dst, const char *src, unsigned long size,
    6.83 -                   int xch, uint32_t dom, xen_pfn_t *parray,
    6.84 -                   unsigned long vstart);
    6.85 -
    6.86  int pin_table(int xc_handle, unsigned int type, unsigned long mfn,
    6.87                domid_t dom);
    6.88  
    6.89 -/* image loading */
    6.90 -int probe_elf(const char *image, unsigned long image_size,
    6.91 -              struct load_funcs *funcs);
    6.92 -int probe_bin(const char *image, unsigned long image_size,
    6.93 -              struct load_funcs *funcs);
    6.94 -
    6.95  #endif /* XG_PRIVATE_H */
     7.1 --- a/xen/common/elf.c	Wed Feb 14 12:18:32 2007 -0800
     7.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
     7.3 @@ -1,520 +0,0 @@
     7.4 -/******************************************************************************
     7.5 - * elf.c
     7.6 - * 
     7.7 - * Generic Elf-loading routines.
     7.8 - */
     7.9 -
    7.10 -#include <xen/config.h>
    7.11 -#include <xen/init.h>
    7.12 -#include <xen/lib.h>
    7.13 -#include <xen/mm.h>
    7.14 -#include <xen/elf.h>
    7.15 -#include <xen/sched.h>
    7.16 -#include <xen/errno.h>
    7.17 -#include <xen/inttypes.h>
    7.18 -
    7.19 -#include <public/elfnote.h>
    7.20 -
    7.21 -static void loadelfsymtab(struct domain_setup_info *dsi, int doload);
    7.22 -static inline int is_loadable_phdr(const Elf_Phdr *phdr)
    7.23 -{
    7.24 -    return ((phdr->p_type == PT_LOAD) &&
    7.25 -            ((phdr->p_flags & (PF_W|PF_X)) != 0));
    7.26 -}
    7.27 -
    7.28 -/*
    7.29 - * Fallback for kernels containing only the legacy __xen_guest string
    7.30 - * and no ELF notes.
    7.31 - */
    7.32 -static int is_xen_guest_section(const Elf_Shdr *shdr, const char *shstrtab)
    7.33 -{
    7.34 -    return strcmp(&shstrtab[shdr->sh_name], "__xen_guest") == 0;
    7.35 -}
    7.36 -
    7.37 -static const char *xen_guest_lookup(struct domain_setup_info *dsi, int type)
    7.38 -{
    7.39 -    const char *xenguest_fallbacks[] = {
    7.40 -        [XEN_ELFNOTE_ENTRY] = "VIRT_ENTRY=",
    7.41 -        [XEN_ELFNOTE_HYPERCALL_PAGE] = "HYPERCALL_PAGE=",
    7.42 -        [XEN_ELFNOTE_VIRT_BASE] = "VIRT_BASE=",
    7.43 -        [XEN_ELFNOTE_PADDR_OFFSET] = "ELF_PADDR_OFFSET=",
    7.44 -        [XEN_ELFNOTE_XEN_VERSION] = "XEN_VER=",
    7.45 -        [XEN_ELFNOTE_GUEST_OS] = "GUEST_OS=",
    7.46 -        [XEN_ELFNOTE_GUEST_VERSION] = "GUEST_VER=",
    7.47 -        [XEN_ELFNOTE_LOADER] = "LOADER=",
    7.48 -        [XEN_ELFNOTE_PAE_MODE] = "PAE=",
    7.49 -        [XEN_ELFNOTE_FEATURES] = "FEATURES=",
    7.50 -        [XEN_ELFNOTE_BSD_SYMTAB] = "BSD_SYMTAB=",
    7.51 -    };
    7.52 -    const char *fallback;
    7.53 -    const char *p;
    7.54 -
    7.55 -    if ( !dsi->__xen_guest_string )
    7.56 -        return NULL;
    7.57 -
    7.58 -    if ( type > sizeof(xenguest_fallbacks) )
    7.59 -        return NULL;
    7.60 -
    7.61 -    if ( (fallback = xenguest_fallbacks[type]) == NULL )
    7.62 -        return NULL;
    7.63 -
    7.64 -    if ( (p = strstr(dsi->__xen_guest_string,fallback)) == NULL )
    7.65 -        return NULL;
    7.66 -
    7.67 -    return p + strlen(fallback);
    7.68 -}
    7.69 -
    7.70 -static const char *xen_guest_string(struct domain_setup_info *dsi, int type)
    7.71 -{
    7.72 -    const char *p = xen_guest_lookup(dsi, type);
    7.73 -
    7.74 -    /*
    7.75 -     * We special case this since the __xen_guest_section treats the
    7.76 -     * mere precense of the BSD_SYMTAB string as true or false.
    7.77 -     */
    7.78 -    if ( type == XEN_ELFNOTE_BSD_SYMTAB )
    7.79 -        return p ? "yes" : "no";
    7.80 -
    7.81 -    return p;
    7.82 -}
    7.83 -
    7.84 -static unsigned long long xen_guest_numeric(struct domain_setup_info *dsi,
    7.85 -                                                   int type, int *defined)
    7.86 -{
    7.87 -    const char *p = xen_guest_lookup(dsi, type);
    7.88 -    unsigned long long value;
    7.89 -
    7.90 -    if ( p == NULL )
    7.91 -        return 0;
    7.92 -
    7.93 -    value = simple_strtoull(p, NULL, 0);
    7.94 -
    7.95 -    /* We special case this since __xen_guest_section contains a PFN
    7.96 -     * for this field not a virtual address.
    7.97 -     */
    7.98 -    if (type == XEN_ELFNOTE_HYPERCALL_PAGE)
    7.99 -        value = dsi->v_start + (value<<PAGE_SHIFT);
   7.100 -
   7.101 -    *defined = 1;
   7.102 -    return value;
   7.103 -}
   7.104 -
   7.105 -
   7.106 -static int is_xen_elfnote_section(const char *image, const Elf_Shdr *shdr)
   7.107 -{
   7.108 -    const Elf_Note *note;
   7.109 -
   7.110 -    if ( shdr->sh_type != SHT_NOTE )
   7.111 -        return 0;
   7.112 -
   7.113 -    for ( note = (const Elf_Note *)(image + shdr->sh_offset);
   7.114 -          note < (const Elf_Note *)(image + shdr->sh_offset + shdr->sh_size);
   7.115 -          note = ELFNOTE_NEXT(note) )
   7.116 -    {
   7.117 -        if ( !strncmp(ELFNOTE_NAME(note), "Xen", 4) )
   7.118 -            return 1;
   7.119 -    }
   7.120 -
   7.121 -    return 0;
   7.122 -}
   7.123 -
   7.124 -static const Elf_Note *xen_elfnote_lookup(
   7.125 -    struct domain_setup_info *dsi, int type)
   7.126 -{
   7.127 -    const Elf_Note *note;
   7.128 -
   7.129 -    if ( !dsi->__elfnote_section )
   7.130 -        return NULL;
   7.131 -
   7.132 -    for ( note = (const Elf_Note *)dsi->__elfnote_section;
   7.133 -          note < (const Elf_Note *)dsi->__elfnote_section_end;
   7.134 -          note = ELFNOTE_NEXT(note) )
   7.135 -    {
   7.136 -        if ( strncmp(ELFNOTE_NAME(note), "Xen", 4) )
   7.137 -            continue;
   7.138 -
   7.139 -        if ( note->type == type )
   7.140 -            return note;
   7.141 -    }
   7.142 -
   7.143 -    return NULL;
   7.144 -}
   7.145 -
   7.146 -const char *xen_elfnote_string(struct domain_setup_info *dsi, int type)
   7.147 -{
   7.148 -    const Elf_Note *note;
   7.149 -
   7.150 -    if ( !dsi->__elfnote_section )
   7.151 -        return xen_guest_string(dsi, type);
   7.152 -
   7.153 -    note = xen_elfnote_lookup(dsi, type);
   7.154 -    if ( note == NULL )
   7.155 -        return NULL;
   7.156 -
   7.157 -    return (const char *)ELFNOTE_DESC(note);
   7.158 -}
   7.159 -
   7.160 -unsigned long long xen_elfnote_numeric(struct domain_setup_info *dsi,
   7.161 -                                       int type, int *defined)
   7.162 -{
   7.163 -    const Elf_Note *note;
   7.164 -
   7.165 -    *defined = 0;
   7.166 -
   7.167 -    if ( !dsi->__elfnote_section )
   7.168 -        return xen_guest_numeric(dsi, type, defined);
   7.169 -
   7.170 -    note = xen_elfnote_lookup(dsi, type);
   7.171 -    if ( note == NULL )
   7.172 -    {
   7.173 -        return 0;
   7.174 -    }
   7.175 -
   7.176 -    switch ( note->descsz )
   7.177 -    {
   7.178 -    case 4:
   7.179 -        *defined = 1;
   7.180 -        return *(const uint32_t*)ELFNOTE_DESC(note);
   7.181 -    case 8:
   7.182 -        *defined = 1;
   7.183 -        return *(const uint64_t*)ELFNOTE_DESC(note);
   7.184 -    default:
   7.185 -        printk("ERROR: unknown data size %#x for numeric type note %#x\n",
   7.186 -               note->descsz, type);
   7.187 -        return 0;
   7.188 -    }
   7.189 -}
   7.190 -
   7.191 -int parseelfimage(struct domain_setup_info *dsi)
   7.192 -{
   7.193 -    const Elf_Ehdr *ehdr = (const Elf_Ehdr *)dsi->image_addr;
   7.194 -    const Elf_Phdr *phdr;
   7.195 -    const Elf_Shdr *shdr;
   7.196 -    Elf_Addr kernstart = ~0, kernend = 0, vaddr, virt_entry;
   7.197 -    const char *shstrtab, *p;
   7.198 -    const char *image = (char *)dsi->image_addr;
   7.199 -    const unsigned long image_len = dsi->image_len;
   7.200 -    int h, virt_base_defined, elf_pa_off_defined, virt_entry_defined;
   7.201 -
   7.202 -    if ( !elf_sanity_check(ehdr) )
   7.203 -        return -ENOSYS;
   7.204 -
   7.205 -    if ( (ehdr->e_phoff + (ehdr->e_phnum*ehdr->e_phentsize)) > image_len )
   7.206 -    {
   7.207 -        printk("ELF program headers extend beyond end of image.\n");
   7.208 -        return -EINVAL;
   7.209 -    }
   7.210 -
   7.211 -    if ( (ehdr->e_shoff + (ehdr->e_shnum*ehdr->e_shentsize)) > image_len )
   7.212 -    {
   7.213 -        printk("ELF section headers extend beyond end of image.\n");
   7.214 -        return -EINVAL;
   7.215 -    }
   7.216 -
   7.217 -    dsi->__elfnote_section = NULL;
   7.218 -    dsi->__xen_guest_string = NULL;
   7.219 -
   7.220 -    /* Look for .notes segment containing at least one Xen note */
   7.221 -    for ( h = 0; h < ehdr->e_shnum; h++ )
   7.222 -    {
   7.223 -        shdr = (const Elf_Shdr *)(
   7.224 -            image + ehdr->e_shoff + (h*ehdr->e_shentsize));
   7.225 -        if ( !is_xen_elfnote_section(image, shdr) )
   7.226 -            continue;
   7.227 -        dsi->__elfnote_section = (const char *)image + shdr->sh_offset;
   7.228 -        dsi->__elfnote_section_end =
   7.229 -            (const char *)image + shdr->sh_offset + shdr->sh_size;
   7.230 -        break;
   7.231 -    }
   7.232 -
   7.233 -    /* Fall back to looking for the special '__xen_guest' section. */
   7.234 -    if ( dsi->__elfnote_section == NULL )
   7.235 -    {
   7.236 -        /* Find the section-header strings table. */
   7.237 -        if ( ehdr->e_shstrndx == SHN_UNDEF )
   7.238 -        {
   7.239 -            printk("ELF image has no section-header strings table.\n");
   7.240 -            return -EINVAL;
   7.241 -        }
   7.242 -        shdr = (const Elf_Shdr *)(image + ehdr->e_shoff +
   7.243 -                            (ehdr->e_shstrndx*ehdr->e_shentsize));
   7.244 -        shstrtab = image + shdr->sh_offset;
   7.245 -
   7.246 -        for ( h = 0; h < ehdr->e_shnum; h++ )
   7.247 -        {
   7.248 -            shdr = (const Elf_Shdr *)(
   7.249 -                image + ehdr->e_shoff + (h*ehdr->e_shentsize));
   7.250 -            if ( is_xen_guest_section(shdr, shstrtab) )
   7.251 -            {
   7.252 -                dsi->__xen_guest_string =
   7.253 -                    (const char *)image + shdr->sh_offset;
   7.254 -                break;
   7.255 -            }
   7.256 -        }
   7.257 -    }
   7.258 -
   7.259 -    /* Check the contents of the Xen notes or guest string. */
   7.260 -    if ( dsi->__elfnote_section || dsi->__xen_guest_string )
   7.261 -    {
   7.262 -        const char *loader = xen_elfnote_string(dsi, XEN_ELFNOTE_LOADER);
   7.263 -        const char *guest_os = xen_elfnote_string(dsi, XEN_ELFNOTE_GUEST_OS);
   7.264 -        const char *xen_version =
   7.265 -            xen_elfnote_string(dsi, XEN_ELFNOTE_XEN_VERSION);
   7.266 -
   7.267 -        if ( ( loader == NULL || strncmp(loader, "generic", 7) ) &&
   7.268 -             ( guest_os == NULL || strncmp(guest_os, "linux", 5) ) )
   7.269 -        {
   7.270 -            printk("ERROR: Will only load images built for the generic "
   7.271 -                   "loader or Linux images");
   7.272 -            return -EINVAL;
   7.273 -        }
   7.274 -
   7.275 -        if ( xen_version == NULL || strncmp(xen_version, "xen-3.0", 7) )
   7.276 -        {
   7.277 -            printk("ERROR: Xen will only load images built for Xen v3.0\n");
   7.278 -        }
   7.279 -    }
   7.280 -    else
   7.281 -    {
   7.282 -#if defined(__x86_64__) || defined(__i386__)
   7.283 -        printk("ERROR: Not a Xen-ELF image: "
   7.284 -               "No ELF notes or '__xen_guest' section found.\n");
   7.285 -        return -EINVAL;
   7.286 -#endif
   7.287 -    }
   7.288 -
   7.289 -    /*
   7.290 -     * A "bimodal" ELF note indicates the kernel will adjust to the
   7.291 -     * current paging mode, including handling extended cr3 syntax.
   7.292 -     * If we have ELF notes then PAE=yes implies that we must support
   7.293 -     * the extended cr3 syntax. Otherwise we need to find the
   7.294 -     * [extended-cr3] syntax in the __xen_guest string.
   7.295 -     */
   7.296 -    dsi->pae_kernel = PAEKERN_no;
   7.297 -    if ( dsi->__elfnote_section )
   7.298 -    {
   7.299 -        p = xen_elfnote_string(dsi, XEN_ELFNOTE_PAE_MODE);
   7.300 -        if ( p != NULL && strstr(p, "bimodal") != NULL )
   7.301 -            dsi->pae_kernel = PAEKERN_bimodal;
   7.302 -        else if ( p != NULL && strncmp(p, "yes", 3) == 0 )
   7.303 -            dsi->pae_kernel = PAEKERN_extended_cr3;
   7.304 -    }
   7.305 -    else
   7.306 -    {
   7.307 -        p = xen_guest_lookup(dsi, XEN_ELFNOTE_PAE_MODE);
   7.308 -        if ( p != NULL && strncmp(p, "yes", 3) == 0 )
   7.309 -        {
   7.310 -            dsi->pae_kernel = PAEKERN_yes;
   7.311 -            if ( !strncmp(p+3, "[extended-cr3]", 14) )
   7.312 -                dsi->pae_kernel = PAEKERN_extended_cr3;
   7.313 -        }
   7.314 -    }
   7.315 -
   7.316 -    /* Initial guess for v_start is 0 if it is not explicitly defined. */
   7.317 -    dsi->v_start =
   7.318 -        xen_elfnote_numeric(dsi, XEN_ELFNOTE_VIRT_BASE, &virt_base_defined);
   7.319 -    if ( !virt_base_defined )
   7.320 -        dsi->v_start = 0;
   7.321 -
   7.322 -    /*
   7.323 -     * If we are using the legacy __xen_guest section then elf_pa_off
   7.324 -     * defaults to v_start in order to maintain compatibility with
   7.325 -     * older hypervisors which set padd in the ELF header to
   7.326 -     * virt_base.
   7.327 -     *
   7.328 -     * If we are using the modern ELF notes interface then the default
   7.329 -     * is 0.
   7.330 -     */
   7.331 -    dsi->elf_paddr_offset = xen_elfnote_numeric(dsi, XEN_ELFNOTE_PADDR_OFFSET,
   7.332 -                                                &elf_pa_off_defined);
   7.333 -    if ( !elf_pa_off_defined )
   7.334 -    {
   7.335 -        if ( dsi->__elfnote_section )
   7.336 -            dsi->elf_paddr_offset = 0;
   7.337 -        else
   7.338 -            dsi->elf_paddr_offset = dsi->v_start;
   7.339 -    }
   7.340 -
   7.341 -    if ( elf_pa_off_defined && !virt_base_defined )
   7.342 -    {
   7.343 -        printk("ERROR: Neither ELF_PADDR_OFFSET nor VIRT_BASE found in"
   7.344 -               " Xen ELF notes.\n");
   7.345 -        return -EINVAL;
   7.346 -    }
   7.347 -
   7.348 -    for ( h = 0; h < ehdr->e_phnum; h++ )
   7.349 -    {
   7.350 -        phdr = (const Elf_Phdr *)(
   7.351 -            image + ehdr->e_phoff + (h*ehdr->e_phentsize));
   7.352 -        if ( !is_loadable_phdr(phdr) )
   7.353 -            continue;
   7.354 -        vaddr = phdr->p_paddr - dsi->elf_paddr_offset + dsi->v_start;
   7.355 -        if ( (vaddr + phdr->p_memsz) < vaddr )
   7.356 -        {
   7.357 -            printk("ERROR: ELF program header %d is too large.\n", h);
   7.358 -            return -EINVAL;
   7.359 -        }
   7.360 -
   7.361 -        if ( vaddr < kernstart )
   7.362 -            kernstart = vaddr;
   7.363 -        if ( (vaddr + phdr->p_memsz) > kernend )
   7.364 -            kernend = vaddr + phdr->p_memsz;
   7.365 -    }
   7.366 -
   7.367 -    dsi->v_kernentry = ehdr->e_entry;
   7.368 -
   7.369 -    virt_entry =
   7.370 -        xen_elfnote_numeric(dsi, XEN_ELFNOTE_ENTRY, &virt_entry_defined);
   7.371 -    if ( virt_entry_defined )
   7.372 -        dsi->v_kernentry = virt_entry;
   7.373 -
   7.374 -    if ( (kernstart > kernend) ||
   7.375 -         (dsi->v_kernentry < kernstart) ||
   7.376 -         (dsi->v_kernentry > kernend) ||
   7.377 -         (dsi->v_start > kernstart) )
   7.378 -    {
   7.379 -        printk("ERROR: ELF start or entries are out of bounds.\n");
   7.380 -        return -EINVAL;
   7.381 -    }
   7.382 -
   7.383 -    p = xen_elfnote_string(dsi, XEN_ELFNOTE_BSD_SYMTAB);
   7.384 -    if ( p != NULL && strncmp(p, "yes", 3) == 0 )
   7.385 -        dsi->load_symtab = 1;
   7.386 -
   7.387 -    dsi->v_kernstart = kernstart;
   7.388 -    dsi->v_kernend   = kernend;
   7.389 -    dsi->v_end       = dsi->v_kernend;
   7.390 -
   7.391 -    loadelfsymtab(dsi, 0);
   7.392 -
   7.393 -    return 0;
   7.394 -}
   7.395 -
   7.396 -int loadelfimage(struct domain_setup_info *dsi)
   7.397 -{
   7.398 -    char *image = (char *)dsi->image_addr;
   7.399 -    Elf_Ehdr *ehdr = (Elf_Ehdr *)dsi->image_addr;
   7.400 -    Elf_Phdr *phdr;
   7.401 -    unsigned long vaddr;
   7.402 -    int h;
   7.403 -  
   7.404 -    for ( h = 0; h < ehdr->e_phnum; h++ )
   7.405 -    {
   7.406 -        phdr = (Elf_Phdr *)(image + ehdr->e_phoff + (h*ehdr->e_phentsize));
   7.407 -        if ( !is_loadable_phdr(phdr) )
   7.408 -            continue;
   7.409 -        vaddr = phdr->p_paddr - dsi->elf_paddr_offset + dsi->v_start;
   7.410 -        if ( phdr->p_filesz != 0 )
   7.411 -            memcpy((char *)vaddr, image + phdr->p_offset, phdr->p_filesz);
   7.412 -        if ( phdr->p_memsz > phdr->p_filesz )
   7.413 -            memset((char *)vaddr + phdr->p_filesz, 0,
   7.414 -                   phdr->p_memsz - phdr->p_filesz);
   7.415 -    }
   7.416 -
   7.417 -    loadelfsymtab(dsi, 1);
   7.418 -
   7.419 -    return 0;
   7.420 -}
   7.421 -
   7.422 -#define ELFROUND (ELFSIZE / 8)
   7.423 -
   7.424 -static void loadelfsymtab(struct domain_setup_info *dsi, int doload)
   7.425 -{
   7.426 -    Elf_Ehdr *ehdr = (Elf_Ehdr *)dsi->image_addr, *sym_ehdr;
   7.427 -    Elf_Shdr *shdr;
   7.428 -    unsigned long maxva, symva;
   7.429 -    char *p, *image = (char *)dsi->image_addr;
   7.430 -    int h, i;
   7.431 -
   7.432 -    if ( !dsi->load_symtab )
   7.433 -        return;
   7.434 -
   7.435 -    maxva = (dsi->v_kernend + ELFROUND - 1) & ~(ELFROUND - 1);
   7.436 -    symva = maxva;
   7.437 -    maxva += sizeof(int);
   7.438 -    dsi->symtab_addr = maxva;
   7.439 -    dsi->symtab_len = 0;
   7.440 -    maxva += sizeof(Elf_Ehdr) + ehdr->e_shnum * sizeof(Elf_Shdr);
   7.441 -    maxva = (maxva + ELFROUND - 1) & ~(ELFROUND - 1);
   7.442 -    if ( doload )
   7.443 -    {
   7.444 -        p = (void *)symva;
   7.445 -        shdr = (Elf_Shdr *)(p + sizeof(int) + sizeof(Elf_Ehdr));
   7.446 -        memcpy(shdr, image + ehdr->e_shoff, ehdr->e_shnum*sizeof(Elf_Shdr));
   7.447 -    } 
   7.448 -    else
   7.449 -    {
   7.450 -        p = NULL;
   7.451 -        shdr = (Elf_Shdr *)(image + ehdr->e_shoff);
   7.452 -    }
   7.453 -
   7.454 -    for ( h = 0; h < ehdr->e_shnum; h++ ) 
   7.455 -    {
   7.456 -        if ( shdr[h].sh_type == SHT_STRTAB )
   7.457 -        {
   7.458 -            /* Look for a strtab @i linked to symtab @h. */
   7.459 -            for ( i = 0; i < ehdr->e_shnum; i++ )
   7.460 -                if ( (shdr[i].sh_type == SHT_SYMTAB) &&
   7.461 -                     (shdr[i].sh_link == h) )
   7.462 -                    break;
   7.463 -            /* Skip symtab @h if we found no corresponding strtab @i. */
   7.464 -            if ( i == ehdr->e_shnum )
   7.465 -            {
   7.466 -                if (doload) {
   7.467 -                    shdr[h].sh_offset = 0;
   7.468 -                }
   7.469 -                continue;
   7.470 -            }
   7.471 -        }
   7.472 -
   7.473 -        if ( (shdr[h].sh_type == SHT_STRTAB) ||
   7.474 -             (shdr[h].sh_type == SHT_SYMTAB) )
   7.475 -        {
   7.476 -            if (doload) {
   7.477 -                memcpy((void *)maxva, image + shdr[h].sh_offset,
   7.478 -                       shdr[h].sh_size);
   7.479 -
   7.480 -                /* Mangled to be based on ELF header location. */
   7.481 -                shdr[h].sh_offset = maxva - dsi->symtab_addr;
   7.482 -
   7.483 -            }
   7.484 -            dsi->symtab_len += shdr[h].sh_size;
   7.485 -            maxva += shdr[h].sh_size;
   7.486 -            maxva = (maxva + ELFROUND - 1) & ~(ELFROUND - 1);
   7.487 -        }
   7.488 -
   7.489 -        if ( doload )
   7.490 -            shdr[h].sh_name = 0;  /* Name is NULL. */
   7.491 -    }
   7.492 -
   7.493 -    if ( dsi->symtab_len == 0 )
   7.494 -    {
   7.495 -        dsi->symtab_addr = 0;
   7.496 -        return;
   7.497 -    }
   7.498 -
   7.499 -    if ( doload )
   7.500 -    {
   7.501 -        *(int *)p = maxva - dsi->symtab_addr;
   7.502 -        sym_ehdr = (Elf_Ehdr *)(p + sizeof(int));
   7.503 -        memcpy(sym_ehdr, ehdr, sizeof(Elf_Ehdr));
   7.504 -        sym_ehdr->e_phoff = 0;
   7.505 -        sym_ehdr->e_shoff = sizeof(Elf_Ehdr);
   7.506 -        sym_ehdr->e_phentsize = 0;
   7.507 -        sym_ehdr->e_phnum = 0;
   7.508 -        sym_ehdr->e_shstrndx = SHN_UNDEF;
   7.509 -    }
   7.510 -
   7.511 -    dsi->symtab_len = maxva - dsi->symtab_addr;
   7.512 -    dsi->v_end      = maxva;
   7.513 -}
   7.514 -
   7.515 -/*
   7.516 - * Local variables:
   7.517 - * mode: C
   7.518 - * c-set-style: "BSD"
   7.519 - * c-basic-offset: 4
   7.520 - * tab-width: 4
   7.521 - * indent-tabs-mode: nil
   7.522 - * End:
   7.523 - */