Exemplo n.º 1
0
Arquivo: loader.c Projeto: anhkgg/temu
/* return < 0 if error, otherwise the number of bytes loaded in memory */
int load_elf(const char *filename, int64_t virt_to_phys_addend,
             uint64_t *pentry, uint64_t *lowaddr, uint64_t *highaddr)
{
    int fd, data_order, host_data_order, must_swab, ret;
    uint8_t e_ident[EI_NIDENT];

    fd = open(filename, O_RDONLY | O_BINARY);
    if (fd < 0) {
        perror(filename);
        return -1;
    }
    if (read(fd, e_ident, sizeof(e_ident)) != sizeof(e_ident))
        goto fail;
    if (e_ident[0] != ELFMAG0 ||
        e_ident[1] != ELFMAG1 ||
        e_ident[2] != ELFMAG2 ||
        e_ident[3] != ELFMAG3)
        goto fail;
#ifdef WORDS_BIGENDIAN
    data_order = ELFDATA2MSB;
#else
    data_order = ELFDATA2LSB;
#endif
    must_swab = data_order != e_ident[EI_DATA];

#ifdef TARGET_WORDS_BIGENDIAN
    host_data_order = ELFDATA2MSB;
#else
    host_data_order = ELFDATA2LSB;
#endif
    if (host_data_order != e_ident[EI_DATA])
        return -1;

    lseek(fd, 0, SEEK_SET);
    if (e_ident[EI_CLASS] == ELFCLASS64) {
        ret = load_elf64(fd, virt_to_phys_addend, must_swab, pentry,
                         lowaddr, highaddr);
    } else {
        ret = load_elf32(fd, virt_to_phys_addend, must_swab, pentry,
                         lowaddr, highaddr);
    }

    close(fd);
    return ret;

 fail:
    close(fd);
    return -1;
}
Exemplo n.º 2
0
static int
acrn_load_elf(struct vmctx *ctx, char *elf_file_name, unsigned long *entry,
		uint32_t *multiboot_flags)
{
	int i, ret = 0;
	FILE *fp;
	size_t read_len = 0;
	unsigned int *ptr32;
	char *elf_buf;
	Elf32_Ehdr *elf_ehdr;


	elf_buf = calloc(1, ELF_BUF_LEN);
	if (elf_buf == NULL) {
		fprintf(stderr, "Can't allocate elf buf\r\n");
		return -1;
	}

	fp = fopen(elf_file_name, "r");
	if (fp == NULL) {
		fprintf(stderr, "Can't open elf file: %s\r\n", elf_file_name);
		free(elf_buf);
		return -1;
	}

	read_len = fread(elf_buf, 1, ELF_BUF_LEN, fp);
	if (read_len != ELF_BUF_LEN) {
		fprintf(stderr, "Can't get %ld data from elf file\n",
				ELF_BUF_LEN);
	}

	/* Scan the first 8k to detect whether the elf needs multboot
	 * info prepared.
	 */
	ptr32 = (unsigned int *) elf_buf;
	for (i = 0; i <= ((ELF_BUF_LEN/4) - 3); i++) {
		if (ptr32[i] == MULTIBOOT_HEAD_MAGIC) {
			int j = 0;
			unsigned int sum = 0;

			/* According to multiboot spec 0.6.96 sec 3.1.2.
			 * There are three u32:
			 *  offset   field
			 *    0      multiboot_head_magic
			 *    4      flags
			 *    8      checksum
			 * The sum of these three u32 should be u32 zero.
			 */
			for (j = 0; j < 3; j++) {
				sum += ptr32[j + i];
			}

			if (0 == sum) {
				multiboot_image = 1;
				*multiboot_flags = ptr32[i + 1];
			}
			break;
		}
	}

	elf_ehdr = (Elf32_Ehdr *) elf_buf;

	if ((elf_ehdr->e_ident[EI_MAG0] != ELFMAG0) ||
		(elf_ehdr->e_ident[EI_MAG1] != ELFMAG1) ||
		(elf_ehdr->e_ident[EI_MAG2] != ELFMAG2) ||
		(elf_ehdr->e_ident[EI_MAG3] != ELFMAG3)) {
		fprintf(stderr, "This is not elf file\n");
		fclose(fp);
		free(elf_buf);

		return -1;
	}

	if (elf_ehdr->e_ident[EI_CLASS] == ELFCLASS32) {
		ret = load_elf32(ctx, fp, elf_buf);
	} else {
		fprintf(stderr, "No available 64bit elf loader ready yet\n");
		fclose(fp);
		free(elf_buf);
		return -1;
	}

	*entry = elf_ehdr->e_entry;
	free(elf_buf);

	return ret;
}
Exemplo n.º 3
0
/*
 * Executes a program.
 */
PUBLIC int sys_execve(const char *filename, const char **argv, const char **envp)
{
	int i;                /* Loop index.          */
	struct inode *inode;  /* File inode.          */
	struct region *reg;   /* Process region.      */
	addr_t entry;         /* Program entry point. */
	addr_t sp;            /* User stack pointer.  */
	char *name;           /* File name.           */
	char stack[ARG_MAX];  /* Stack size.          */

	/* Get file name. */
	if ((name = getname(filename)) == NULL)
		return (curr_proc->errno);

	/* Build arguments before freeing user memory. */
	kmemset(stack, 0, ARG_MAX);
	if (!(sp = buildargs(stack, ARG_MAX, argv, envp)))
	{
		putname(name);
		return (curr_proc->errno);
	}

	/* Get file's inode. */
	if ((inode = inode_name(name)) == NULL)
	{
		putname(name);
		return (curr_proc->errno);
	}

	/* Not a regular file. */
	if (!S_ISREG(inode->mode))
	{
		putname(name);
		inode_put(inode);
		return (-EACCES);
	}

	/* Not allowed. */
	if (!permission(inode->mode, inode->uid, inode->gid, curr_proc, MAY_EXEC, 0))
	{
		putname(name);
		inode_put(inode);
		return (-EACCES);
	}

	/* Close file descriptors. */
	for (i = 0; i < OPEN_MAX; i++)
	{
		if (curr_proc->close & (1 << i))
			do_close(i);
	}

	/* Detach process memory regions. */
	for (i = 0; i < NR_PREGIONS; i++)
		detachreg(curr_proc, &curr_proc->pregs[i]);
	
	/* Reset signal handlers. */
	curr_proc->restorer = NULL;
	for (i = 0; i < NR_SIGNALS; i++)
	{
		if (curr_proc->handlers[i] != SIG_DFL)
		{
			if (curr_proc->handlers[i] != SIG_IGN)
				curr_proc->handlers[i] = SIG_DFL;
		}
	}
	
	/* Load executable. */
	if (!(entry = load_elf32(inode)))
		goto die0;

	/* Attach stack region. */
	if ((reg = allocreg(S_IRUSR | S_IWUSR, PAGE_SIZE, REGION_DOWNWARDS)) == NULL)
		goto die0;
	if (attachreg(curr_proc, STACK(curr_proc), USTACK_ADDR - 1, reg))
		goto die1;
	unlockreg(reg);

	/* Attach heap region. */
	if ((reg = allocreg(S_IRUSR | S_IWUSR, PAGE_SIZE, REGION_UPWARDS)) == NULL)
		goto die0;
	if (attachreg(curr_proc, HEAP(curr_proc), UHEAP_ADDR, reg))
		goto die1;
	unlockreg(reg);
	
	inode_put(inode);
	putname(name);

	kmemcpy((void *)(USTACK_ADDR - ARG_MAX), stack, ARG_MAX);
	
	user_mode(entry, sp);
	
	/* Will not return. */
	return (0);

die1:
	unlockreg(reg);
	freereg(reg);
die0:
	inode_put(inode);
	putname(name);
	die(((SIGSEGV & 0xff) << 16) | (1 << 9));
	return (-1);
}