unsigned long load_elf_image ( unsigned long guest_image_start, unsigned long guest_image_size, unsigned long vm_pmem_start ) { struct Elf_Ehdr *ehdr = ( struct Elf_Ehdr * ) guest_image_start; // [DEBUG] // printf ( "Entry point address: %x\n", ( unsigned long ) ehdr->e_entry ); int i; for ( i = 0; i < ehdr->e_phnum; i++ ) { struct Elf_Phdr *phdr = get_elf_phdr ( ehdr, i ); if ( ! is_loadable_phdr ( phdr ) ) { continue; } /* [DEBUG] */ // printf ( "[%x] vaddr=%x, paddr=%x, filesz=%x, memsz=%x\n", i, phdr->p_vaddr, phdr->p_paddr, phdr->p_filesz, phdr->p_memsz ); if ( phdr->p_filesz > 0 ) { memmove ( ( char * ) ( vm_pmem_start + phdr->p_paddr ), ( ( char * ) ehdr ) + phdr->p_offset, phdr->p_filesz ); } size_t len = phdr->p_memsz - phdr->p_filesz; if ( len > 0 ) { memset ( ( char * ) ( vm_pmem_start + phdr->p_paddr + phdr->p_filesz ), 0, len ); } } printf ( "ELF image loaded.\n" ); return ehdr->e_entry; }
int loadelfimage(struct domain_setup_info *dsi) { char *elfbase = (char *)dsi->image_addr; Elf_Ehdr *ehdr = (Elf_Ehdr *)dsi->image_addr; Elf_Phdr *phdr; int h; for ( h = 0; h < ehdr->e_phnum; h++ ) { phdr = (Elf_Phdr *)(elfbase + ehdr->e_phoff + (h*ehdr->e_phentsize)); if ( !is_loadable_phdr(phdr) ) continue; if ( phdr->p_filesz != 0 ) memcpy((char *)phdr->p_paddr, elfbase + phdr->p_offset, phdr->p_filesz); if ( phdr->p_memsz > phdr->p_filesz ) memset((char *)phdr->p_paddr + phdr->p_filesz, 0, phdr->p_memsz - phdr->p_filesz); } loadelfsymtab(dsi, 1); return 0; }
int parseelfimage(struct domain_setup_info *dsi) { Elf_Ehdr *ehdr = (Elf_Ehdr *)dsi->image_addr; Elf_Phdr *phdr; Elf_Shdr *shdr; unsigned long kernstart = ~0UL, kernend=0UL; char *shstrtab, *guestinfo=NULL; char *elfbase = (char *)dsi->image_addr; int h; const char *p; if ( !elf_sanity_check(ehdr) ) return -EINVAL; if ( (ehdr->e_phoff + (ehdr->e_phnum*ehdr->e_phentsize)) > dsi->image_len ) { printk("ELF program headers extend beyond end of image.\n"); return -EINVAL; } if ( (ehdr->e_shoff + (ehdr->e_shnum*ehdr->e_shentsize)) > dsi->image_len ) { printk("ELF section headers extend beyond end of image.\n"); return -EINVAL; } /* Find the section-header strings table. */ if ( ehdr->e_shstrndx == SHN_UNDEF ) { printk("ELF image has no section-header strings table (shstrtab).\n"); return -EINVAL; } shdr = (Elf_Shdr *)(elfbase + ehdr->e_shoff + (ehdr->e_shstrndx*ehdr->e_shentsize)); shstrtab = elfbase + shdr->sh_offset; /* Find the special '__xen_guest' section and check its contents. */ for ( h = 0; h < ehdr->e_shnum; h++ ) { shdr = (Elf_Shdr *)(elfbase + ehdr->e_shoff + (h*ehdr->e_shentsize)); if ( strcmp(&shstrtab[shdr->sh_name], "__xen_guest") != 0 ) continue; guestinfo = elfbase + shdr->sh_offset; if ( (strstr(guestinfo, "LOADER=generic") == NULL) && (strstr(guestinfo, "GUEST_OS=linux") == NULL) ) { printk("ERROR: Xen will only load images built for the generic " "loader or Linux images\n"); return -EINVAL; } if ( (strstr(guestinfo, "XEN_VER=xen-3.0") == NULL) ) { printk("ERROR: Xen will only load images built for Xen v3.0\n"); return -EINVAL; } #ifdef CONFIG_VMM_SECURITY_SCID { char* str_id; char* str_end; if ( ((str_id = strstr(guestinfo, "SCID=")) == NULL) ) { printk("ERROR: Security Class ID is not specified\n"); return -EINVAL; } str_id += strlen("SCID="); dsi->scid = simple_strtoul(str_id, &str_end, 10); if (dsi->scid < 0) { printk("ERROR: Security Class ID is not vaild\n"); return -EINVAL; } } #endif break; } dsi->xen_section_string = guestinfo; for ( h = 0; h < ehdr->e_phnum; h++ ) { phdr = (Elf_Phdr *)(elfbase + ehdr->e_phoff + (h*ehdr->e_phentsize)); if ( !is_loadable_phdr(phdr) ) continue; if ( phdr->p_paddr < kernstart ) kernstart = phdr->p_paddr; if ( (phdr->p_paddr + phdr->p_memsz) > kernend ) kernend = phdr->p_paddr + phdr->p_memsz; } if ( (kernstart > kernend) || (ehdr->e_entry < kernstart) || (ehdr->e_entry > kernend) ) { printk("Malformed ELF image.\n"); return -EINVAL; } dsi->v_start = kernstart; if ( guestinfo != NULL ) { if ( (p = strstr(guestinfo, "VIRT_BASE=")) != NULL ) dsi->v_start = simple_strtoul(p+10, &p, 0); if ( (p = strstr(guestinfo, "BSD_SYMTAB")) != NULL ) dsi->load_symtab = 1; } dsi->v_kernstart = kernstart; dsi->v_kernend = kernend; dsi->v_kernentry = ehdr->e_entry; dsi->v_end = dsi->v_kernend; loadelfsymtab(dsi, 0); return 0; }