Пример #1
0
/*
 * loadelf_main
 *
 * Loads an ELF kernel to it's defined load address in the guest VM.
 * The kernel is loaded to its defined start point as set in the ELF header.
 *
 * Parameters:
 *  fd: file descriptor of a kernel file to load
 *  vcp: the VM create parameters, holding the exact memory map
 *  (out) vis: register state to set on init for this kernel
 *
 * Return values:
 *  0 if successful
 *  various error codes returned from read(2) or loadelf functions
 */
int
loadelf_main(int fd, struct vm_create_params *vcp, struct vcpu_init_state *vis)
{
	int r;
	uint32_t bootargsz;
	size_t n, stacksize;
	u_long marks[MARK_MAX];
	bios_memmap_t memmap[VMM_MAX_MEM_RANGES + 1];

	if ((r = read(fd, &hdr, sizeof(hdr))) != sizeof(hdr))
		return 1;

	memset(&marks, 0, sizeof(marks));
	if (memcmp(hdr.elf32.e_ident, ELFMAG, SELFMAG) == 0 &&
	    hdr.elf32.e_ident[EI_CLASS] == ELFCLASS32) {
		r = elf32_exec(fd, &hdr.elf32, marks, LOAD_ALL);
	} else if (memcmp(hdr.elf64.e_ident, ELFMAG, SELFMAG) == 0 &&
	    hdr.elf64.e_ident[EI_CLASS] == ELFCLASS64) {
		r = elf64_exec(fd, &hdr.elf64, marks, LOAD_ALL);
	}

	if (r)
		return (r);

	push_gdt();
	push_pt();
	n = create_bios_memmap(vcp, memmap);
	bootargsz = push_bootargs(memmap, n);
	stacksize = push_stack(bootargsz, marks[MARK_END]);

	vis->vis_rip = (uint64_t)marks[MARK_ENTRY];
	vis->vis_rsp = (uint64_t)(STACK_PAGE + PAGE_SIZE) - stacksize;
	vis->vis_gdtr.vsi_base = GDT_PAGE;

	return (0);
}
Пример #2
0
/*
 * Open 'filename', read in program and return -1 on error otherwise fd,
 * with file still open.
 * Also fills in marks.
 */
int
loadfile(const char *fname, u_long *marks, int flags)
{
	union {
#ifdef BOOT_ECOFF
		struct ecoff_exechdr coff;
#endif
#if defined(BOOT_ELF32) || (defined(BOOT_ELF) && ELFSIZE == 32)
		Elf32_Ehdr elf32;
#endif
#if defined(BOOT_ELF64) || (defined(BOOT_ELF) && ELFSIZE == 64)
		Elf64_Ehdr elf64;
#endif
#ifdef BOOT_AOUT
		struct exec aout;
#endif

	} hdr;
	ssize_t nr;
	int fd, rval;

	/* Open the file. */
	if ((fd = open(fname, 0)) < 0) {
		WARN(("open %s", fname ? fname : "<default>"));
		return -1;
	}

	/* Read the exec header. */
	if ((nr = read(fd, &hdr, sizeof(hdr))) != sizeof(hdr)) {
		WARN(("read header"));
		goto err;
	}

#ifdef BOOT_ECOFF
	if (!ECOFF_BADMAG(&hdr.coff)) {
		rval = coff_exec(fd, &hdr.coff, marks, flags);
	} else
#endif
#if defined(BOOT_ELF32) || (defined(BOOT_ELF) && ELFSIZE == 32)
	if (memcmp(hdr.elf32.e_ident, ELFMAG, SELFMAG) == 0 &&
	    hdr.elf32.e_ident[EI_DATA] == ELF_TARG_DATA &&
	    hdr.elf32.e_ident[EI_CLASS] == ELFCLASS32) {
		rval = elf32_exec(fd, &hdr.elf32, marks, flags);
	} else
#endif
#if defined(BOOT_ELF64) || (defined(BOOT_ELF) && ELFSIZE == 64)
	if (memcmp(hdr.elf64.e_ident, ELFMAG, SELFMAG) == 0 &&
	    hdr.elf64.e_ident[EI_DATA] == ELF_TARG_DATA &&
	    hdr.elf64.e_ident[EI_CLASS] == ELFCLASS64) {
		rval = elf64_exec(fd, &hdr.elf64, marks, flags);
	} else
#endif
#ifdef BOOT_AOUT
	if (OKMAGIC(N_GETMAGIC(hdr.aout))
#ifndef NO_MID_CHECK
	    && N_GETMID(hdr.aout) == MID_MACHINE
#endif
	    ) {
		rval = aout_exec(fd, &hdr.aout, marks, flags);
	} else
#endif
	{
		rval = 1;
		errno = EFTYPE;
		WARN(("%s", fname ? fname : "<default>"));
	}

	if (rval == 0) {
		PROGRESS(("=0x%lx\n", marks[MARK_END] - marks[MARK_START]));
		return fd;
	}
err:
	(void)close(fd);
	return -1;
}