debuggers.hg
changeset 13658:a63d1af01b3d
libelf: use for hvm builder.
This patch switches over the hvm domain builder to libelf
(for loading hvmloader).
Signed-off-by: Gerd Hoffmann <kraxel@suse.de>
---
tools/libxc/xc_hvm_build.c | 220 +++++++++++++--------------------------------
1 file changed, 65 insertions(+), 155 deletions(-)
This patch switches over the hvm domain builder to libelf
(for loading hvmloader).
Signed-off-by: Gerd Hoffmann <kraxel@suse.de>
---
tools/libxc/xc_hvm_build.c | 220 +++++++++++++--------------------------------
1 file changed, 65 insertions(+), 155 deletions(-)
author | Emmanuel Ackaouy <ack@xensource.com> |
---|---|
date | Thu Jan 25 22:16:52 2007 +0000 (2007-01-25) |
parents | a754192ffce6 |
children | 4aa6044ab967 |
files | tools/libxc/xc_hvm_build.c |
line diff
1.1 --- a/tools/libxc/xc_hvm_build.c Thu Jan 25 22:16:52 2007 +0000 1.2 +++ b/tools/libxc/xc_hvm_build.c Thu Jan 25 22:16:52 2007 +0000 1.3 @@ -2,29 +2,22 @@ 1.4 * xc_hvm_build.c 1.5 */ 1.6 1.7 -#define ELFSIZE 32 1.8 #include <stddef.h> 1.9 #include <inttypes.h> 1.10 -#include "xg_private.h" 1.11 -#include "xc_private.h" 1.12 -#include "xc_elf.h" 1.13 #include <stdlib.h> 1.14 #include <unistd.h> 1.15 #include <zlib.h> 1.16 + 1.17 +#include "xg_private.h" 1.18 +#include "xc_private.h" 1.19 + 1.20 #include <xen/hvm/hvm_info_table.h> 1.21 #include <xen/hvm/params.h> 1.22 #include <xen/hvm/e820.h> 1.23 1.24 -#define SCRATCH_PFN 0xFFFFF 1.25 +#include <xen/libelf.h> 1.26 1.27 -#define HVM_LOADER_ENTR_ADDR 0x00100000 1.28 -static int 1.29 -parseelfimage( 1.30 - char *elfbase, unsigned long elfsize, struct domain_setup_info *dsi); 1.31 -static int 1.32 -loadelfimage( 1.33 - char *elfbase, int xch, uint32_t dom, unsigned long *parray, 1.34 - struct domain_setup_info *dsi); 1.35 +#define SCRATCH_PFN 0xFFFFF 1.36 1.37 int xc_set_hvm_param( 1.38 int handle, domid_t dom, int param, unsigned long value) 1.39 @@ -144,6 +137,48 @@ static void build_e820map(void *e820_pag 1.40 *(((unsigned char *)e820_page) + E820_MAP_NR_OFFSET) = nr_map; 1.41 } 1.42 1.43 +static int 1.44 +loadelfimage(struct elf_binary *elf, int xch, uint32_t dom, unsigned long *parray) 1.45 +{ 1.46 + privcmd_mmap_entry_t *entries = NULL; 1.47 + int pages = (elf->pend - elf->pstart + PAGE_SIZE - 1) >> PAGE_SHIFT; 1.48 + int i, rc = -1; 1.49 + 1.50 + /* map hvmloader address space */ 1.51 + entries = malloc(pages * sizeof(privcmd_mmap_entry_t)); 1.52 + if (NULL == entries) 1.53 + goto err; 1.54 + elf->dest = mmap(NULL, pages << PAGE_SHIFT, PROT_READ | PROT_WRITE, 1.55 + MAP_SHARED, xch, 0); 1.56 + if (MAP_FAILED == elf->dest) 1.57 + goto err; 1.58 + 1.59 + for (i = 0; i < pages; i++) 1.60 + { 1.61 + entries[i].va = (uintptr_t)elf->dest + (i << PAGE_SHIFT); 1.62 + entries[i].mfn = parray[(elf->pstart >> PAGE_SHIFT) + i]; 1.63 + entries[i].npages = 1; 1.64 + } 1.65 + rc = xc_map_foreign_ranges(xch, dom, entries, pages); 1.66 + if (rc < 0) 1.67 + goto err; 1.68 + 1.69 + /* load hvmloader */ 1.70 + elf_load_binary(elf); 1.71 + rc = 0; 1.72 + 1.73 + err: 1.74 + /* cleanup */ 1.75 + if (elf->dest) { 1.76 + munmap(elf->dest, pages << PAGE_SHIFT); 1.77 + elf->dest = NULL; 1.78 + } 1.79 + if (entries) 1.80 + free(entries); 1.81 + 1.82 + return rc; 1.83 +} 1.84 + 1.85 static int setup_guest(int xc_handle, 1.86 uint32_t dom, int memsize, 1.87 char *image, unsigned long image_size, 1.88 @@ -155,35 +190,35 @@ static int setup_guest(int xc_handle, 1.89 struct xen_add_to_physmap xatp; 1.90 struct shared_info *shared_info; 1.91 void *e820_page; 1.92 - struct domain_setup_info dsi; 1.93 - uint64_t v_end; 1.94 + struct elf_binary elf; 1.95 + uint64_t v_start, v_end; 1.96 int rc; 1.97 1.98 - memset(&dsi, 0, sizeof(struct domain_setup_info)); 1.99 + if (0 != elf_init(&elf, image, image_size)) 1.100 + goto error_out; 1.101 + elf_parse_binary(&elf); 1.102 + v_start = 0; 1.103 + v_end = (unsigned long long)memsize << 20; 1.104 1.105 - if ( (parseelfimage(image, image_size, &dsi)) != 0 ) 1.106 - goto error_out; 1.107 - 1.108 - if ( (dsi.v_kernstart & (PAGE_SIZE - 1)) != 0 ) 1.109 + if ( (elf.pstart & (PAGE_SIZE - 1)) != 0 ) 1.110 { 1.111 PERROR("Guest OS must load to a page boundary.\n"); 1.112 goto error_out; 1.113 } 1.114 1.115 - v_end = (unsigned long long)memsize << 20; 1.116 + IPRINTF("VIRTUAL MEMORY ARRANGEMENT:\n" 1.117 + " Loaded HVM loader: %016"PRIx64"->%016"PRIx64"\n" 1.118 + " TOTAL: %016"PRIx64"->%016"PRIx64"\n" 1.119 + " ENTRY ADDRESS: %016"PRIx64"\n", 1.120 + elf.pstart, elf.pend, 1.121 + v_start, v_end, 1.122 + elf_uval(&elf, elf.ehdr, e_entry)); 1.123 1.124 - IPRINTF("VIRTUAL MEMORY ARRANGEMENT:\n" 1.125 - " Loaded HVM loader: %016"PRIx64"->%016"PRIx64"\n" 1.126 - " TOTAL: %016"PRIx64"->%016"PRIx64"\n", 1.127 - dsi.v_kernstart, dsi.v_kernend, 1.128 - dsi.v_start, v_end); 1.129 - IPRINTF(" ENTRY ADDRESS: %016"PRIx64"\n", dsi.v_kernentry); 1.130 - 1.131 - if ( (v_end - dsi.v_start) > ((unsigned long long)nr_pages << PAGE_SHIFT) ) 1.132 + if ( (v_end - v_start) > ((unsigned long long)nr_pages << PAGE_SHIFT) ) 1.133 { 1.134 PERROR("Initial guest OS requires too much space: " 1.135 "(%lluMB is greater than %lluMB limit)\n", 1.136 - (unsigned long long)(v_end - dsi.v_start) >> 20, 1.137 + (unsigned long long)(v_end - v_start) >> 20, 1.138 ((unsigned long long)nr_pages << PAGE_SHIFT) >> 20); 1.139 goto error_out; 1.140 } 1.141 @@ -212,7 +247,7 @@ static int setup_guest(int xc_handle, 1.142 goto error_out; 1.143 } 1.144 1.145 - loadelfimage(image, xc_handle, dom, page_array, &dsi); 1.146 + loadelfimage(&elf, xc_handle, dom, page_array); 1.147 1.148 if ( (e820_page = xc_map_foreign_range( 1.149 xc_handle, dom, PAGE_SIZE, PROT_READ | PROT_WRITE, 1.150 @@ -255,7 +290,7 @@ static int setup_guest(int xc_handle, 1.151 1.152 free(page_array); 1.153 1.154 - ctxt->user_regs.eip = dsi.v_kernentry; 1.155 + ctxt->user_regs.eip = elf_uval(&elf, elf.ehdr, e_entry); 1.156 1.157 return 0; 1.158 1.159 @@ -314,131 +349,6 @@ static inline int is_loadable_phdr(Elf32 1.160 ((phdr->p_flags & (PF_W|PF_X)) != 0)); 1.161 } 1.162 1.163 -static int parseelfimage(char *elfbase, 1.164 - unsigned long elfsize, 1.165 - struct domain_setup_info *dsi) 1.166 -{ 1.167 - Elf32_Ehdr *ehdr = (Elf32_Ehdr *)elfbase; 1.168 - Elf32_Phdr *phdr; 1.169 - Elf32_Shdr *shdr; 1.170 - unsigned long kernstart = ~0UL, kernend=0UL; 1.171 - char *shstrtab; 1.172 - int h; 1.173 - 1.174 - if ( !IS_ELF(*ehdr) ) 1.175 - { 1.176 - xc_set_error(XC_INVALID_KERNEL, 1.177 - "Kernel image does not have an ELF header."); 1.178 - return -EINVAL; 1.179 - } 1.180 - 1.181 - if ( (ehdr->e_phoff + (ehdr->e_phnum * ehdr->e_phentsize)) > elfsize ) 1.182 - { 1.183 - xc_set_error(XC_INVALID_KERNEL, 1.184 - "ELF program headers extend beyond end of image."); 1.185 - return -EINVAL; 1.186 - } 1.187 - 1.188 - if ( (ehdr->e_shoff + (ehdr->e_shnum * ehdr->e_shentsize)) > elfsize ) 1.189 - { 1.190 - xc_set_error(XC_INVALID_KERNEL, 1.191 - "ELF section headers extend beyond end of image."); 1.192 - return -EINVAL; 1.193 - } 1.194 - 1.195 - /* Find the section-header strings table. */ 1.196 - if ( ehdr->e_shstrndx == SHN_UNDEF ) 1.197 - { 1.198 - xc_set_error(XC_INVALID_KERNEL, 1.199 - "ELF image has no section-header strings table (shstrtab)."); 1.200 - return -EINVAL; 1.201 - } 1.202 - shdr = (Elf32_Shdr *)(elfbase + ehdr->e_shoff + 1.203 - (ehdr->e_shstrndx*ehdr->e_shentsize)); 1.204 - shstrtab = elfbase + shdr->sh_offset; 1.205 - 1.206 - for ( h = 0; h < ehdr->e_phnum; h++ ) 1.207 - { 1.208 - phdr = (Elf32_Phdr *)(elfbase + ehdr->e_phoff + (h*ehdr->e_phentsize)); 1.209 - if ( !is_loadable_phdr(phdr) ) 1.210 - continue; 1.211 - if ( phdr->p_paddr < kernstart ) 1.212 - kernstart = phdr->p_paddr; 1.213 - if ( (phdr->p_paddr + phdr->p_memsz) > kernend ) 1.214 - kernend = phdr->p_paddr + phdr->p_memsz; 1.215 - } 1.216 - 1.217 - if ( (kernstart > kernend) || 1.218 - (ehdr->e_entry < kernstart) || 1.219 - (ehdr->e_entry > kernend) ) 1.220 - { 1.221 - xc_set_error(XC_INVALID_KERNEL, 1.222 - "Malformed ELF image."); 1.223 - return -EINVAL; 1.224 - } 1.225 - 1.226 - dsi->v_start = 0x00000000; 1.227 - 1.228 - dsi->v_kernstart = kernstart; 1.229 - dsi->v_kernend = kernend; 1.230 - dsi->v_kernentry = HVM_LOADER_ENTR_ADDR; 1.231 - 1.232 - dsi->v_end = dsi->v_kernend; 1.233 - 1.234 - return 0; 1.235 -} 1.236 - 1.237 -static int 1.238 -loadelfimage( 1.239 - char *elfbase, int xch, uint32_t dom, unsigned long *parray, 1.240 - struct domain_setup_info *dsi) 1.241 -{ 1.242 - Elf32_Ehdr *ehdr = (Elf32_Ehdr *)elfbase; 1.243 - Elf32_Phdr *phdr; 1.244 - int h; 1.245 - 1.246 - char *va; 1.247 - unsigned long pa, done, chunksz; 1.248 - 1.249 - for ( h = 0; h < ehdr->e_phnum; h++ ) 1.250 - { 1.251 - phdr = (Elf32_Phdr *)(elfbase + ehdr->e_phoff + (h*ehdr->e_phentsize)); 1.252 - if ( !is_loadable_phdr(phdr) ) 1.253 - continue; 1.254 - 1.255 - for ( done = 0; done < phdr->p_filesz; done += chunksz ) 1.256 - { 1.257 - pa = (phdr->p_paddr + done) - dsi->v_start; 1.258 - if ((va = xc_map_foreign_range( 1.259 - xch, dom, PAGE_SIZE, PROT_WRITE, 1.260 - parray[pa >> PAGE_SHIFT])) == 0) 1.261 - return -1; 1.262 - chunksz = phdr->p_filesz - done; 1.263 - if ( chunksz > (PAGE_SIZE - (pa & (PAGE_SIZE-1))) ) 1.264 - chunksz = PAGE_SIZE - (pa & (PAGE_SIZE-1)); 1.265 - memcpy(va + (pa & (PAGE_SIZE-1)), 1.266 - elfbase + phdr->p_offset + done, chunksz); 1.267 - munmap(va, PAGE_SIZE); 1.268 - } 1.269 - 1.270 - for ( ; done < phdr->p_memsz; done += chunksz ) 1.271 - { 1.272 - pa = (phdr->p_paddr + done) - dsi->v_start; 1.273 - if ((va = xc_map_foreign_range( 1.274 - xch, dom, PAGE_SIZE, PROT_WRITE, 1.275 - parray[pa >> PAGE_SHIFT])) == 0) 1.276 - return -1; 1.277 - chunksz = phdr->p_memsz - done; 1.278 - if ( chunksz > (PAGE_SIZE - (pa & (PAGE_SIZE-1))) ) 1.279 - chunksz = PAGE_SIZE - (pa & (PAGE_SIZE-1)); 1.280 - memset(va + (pa & (PAGE_SIZE-1)), 0, chunksz); 1.281 - munmap(va, PAGE_SIZE); 1.282 - } 1.283 - } 1.284 - 1.285 - return 0; 1.286 -} 1.287 - 1.288 /* xc_hvm_build 1.289 * 1.290 * Create a domain for a virtualized Linux, using files/filenames