Пример #1
0
INT32 elf_readphdrs(struct pm_task *task, INT32 (*ioread)(struct fsio_event_source *iosrc, UINT32 size, ADDR ptr), INT32 (*ioseek)(struct fsio_event_source *iosrc, UINT32 offset))
{
	UINT32 size;

	// seek to program headers possition
	size = task->loader_inf.elf_header.e_phentsize * task->loader_inf.elf_header.e_phnum;

	task->loader_inf.elf_pheaders = (BYTE*)kmalloc(size);
    if(task->loader_inf.elf_pheaders == NULL)
    {
        return -1;
    }

    if(task->loader_inf.elf_pheaders == NULL)
    {
        return -1;
    }
    
	task->io_finished.callback = elf_readh_finished_callback;

	if(ioread(&task->io_event_src, size, task->loader_inf.elf_pheaders))
	{
        if(!elf_check(task)) return -1;

		task->loader_inf.stage = LOADER_STAGE_LOADED;
        return 1;
	}

	return 0;
}
Пример #2
0
void* load_executable(char* filename)
{
	// find file
	dir_entry* file = find_file(filename);

	// not found?
	if (!file) return 0;
	
	// calculate size and prepare buffer in kernel
    void* buffer = (void*) kmalloc(file->size + get_current_partition()->sectors_per_cluster * get_current_partition()->bytes_per_sector);

	// read to buffer
	read_file(file->cluster_high * 0x100 + file->cluster_low, buffer);

	// is it elf?
	if (elf_check(buffer)) return 0;
	
	// use program header to load
	Elf64_Phdr* ph = buffer + ((Elf64_Ehdr *) buffer)->e_phoff;
	uint64_t i;
	for (i = 0; i < ((Elf64_Ehdr *) buffer)->e_phnum; i++)
	{
		if (ph[i].p_type == 1)
		{
			if (!alloc_page((void*) ph[i].p_vaddr, ph[i].p_memsz / MEM_BLOCK_SIZE + 1)) return 0;
			memcpy((void*) ph[i].p_vaddr, buffer + ph[i].p_offset, ph[i].p_filesz);
		}
	}
    kfree(buffer);
    
	return (void*) ((uint64_t) ((Elf64_Ehdr *) buffer)->e_entry);
}
Пример #3
0
INT32 elf_readh_finished_callback(struct fsio_event_source *iosrc, INT32 ioret)
{
	struct pm_task *task = tsk_get(iosrc->id);
	struct pm_msg_response res_msg;

	res_msg.pm_type = (task->flags & TSK_SHARED_LIB)? PM_LOAD_LIBRARY : PM_CREATE_TASK;
	res_msg.status  = PM_IO_ERROR;
	res_msg.new_id_aux = 0;

	if(ioret != IO_RET_OK)
	{
        if(task->flags & TSK_SHARED_LIB)
        {
            // we where loading a shared lib..
            vmm_lib_loaded(task, FALSE);
        }
        else
        {
		    if(task->creator_task != 0xFFFF)
		        send_msg(task->creator_task, task->creator_task_port, &res_msg );
            task->io_finished.callback = elf_fileclosed_callback;
		    io_begin_close(iosrc);
        }
	}
	else
	{        
        if(elf_check(task))
		{
            if(task->flags & TSK_SHARED_LIB)
            {
                // we where loading a shared lib..
                vmm_lib_loaded(task, TRUE);
            }
            else
            {
			    /* Does this executable contain a PT_INTERP section? */
                int phnum = task->loader_inf.elf_header.e_phnum;
                struct Elf32_Phdr *phdr;
                int i;

                for(i = 0; i < phnum; i++)
                {
                    phdr = (struct Elf32_Phdr*)(task->loader_inf.elf_pheaders + task->loader_inf.elf_header.e_phentsize * i);
                    if(phdr->p_type == PT_INTERP)
                        break;
                }

                /*
                FIXME: We should get the name of the interpreter here..
                */
                if(!loader_task_loaded(task, (phdr->p_type == PT_INTERP)? "ld.so": NULL))
                {
                    if(task->flags & TSK_SHARED_LIB)
                    {
                        // we where loading a shared lib..
                        vmm_lib_loaded(task, FALSE);
                    }
                    else
                    {
                        task->io_finished.callback = elf_fileclosed_callback;
                        io_begin_close(iosrc);
                    }
                }
            }
		}
		else
		{
            if(task->flags & TSK_SHARED_LIB)
            {
                // we where loading a shared lib..
                vmm_lib_loaded(task, FALSE);
            }
            else
			{
                if(task->flags & TSK_SHARED_LIB)
                {
                    // we where loading a shared lib..
                    vmm_lib_loaded(task, FALSE);
                }
                else
                {
                    res_msg.status  = PM_INVALID_FILEFORMAT;
			        if(task->creator_task != 0xFFFF)
                        send_msg(task->creator_task, task->creator_task_port, &res_msg );
			
                    task->io_finished.callback = elf_fileclosed_callback;

			        /* Close the file */
			        io_begin_close(iosrc);
                }
            }
		}
	}
	return 1;
}
Пример #4
0
// elfファイルを解析して初期化する
int elf_init(char* buff)
{
	int i;
	struct Elf32_Phdr* ent,* ent_tmp;
	struct Elf32_Ehdr* elf_header;
	struct Elf32_Phdr* elf_program;

	printf("-------- elf_init --------\n");
	elf_header = (struct Elf32_Ehdr*)buff;
	if(elf_check(elf_header))
		return 1;

	m_magic[0] = elf_header->chare_ident[0];
	m_magic[0] = elf_header->chare_ident[1];
	m_magic[0] = elf_header->chare_ident[2];
	m_magic[0] = elf_header->chare_ident[3];
	m_fileclass = elf_header->chare_ident[4];
	m_endian =  elf_header->chare_ident[5];
	m_elf_version = elf_header->chare_ident[6];
	m_os_abi = elf_header->chare_ident[7];
	m_abi_version = elf_header->chare_ident[8];
	// e_ident[9...15]	未使用
	m_e_type = littletobig((unsigned char*)&elf_header->e_type, 2);
	m_e_machine = littletobig((unsigned char*)&elf_header->e_machine, 2);
	m_e_version = littletobig((unsigned char*)&elf_header->e_version, 4);
	m_e_entry = littletobig((unsigned char*)&elf_header->e_entry, 4);
	m_e_phoff = littletobig((unsigned char*)&elf_header->e_phoff, 4);
	m_e_shoff = littletobig((unsigned char*)&elf_header->e_shoff, 4);
	m_e_flags = littletobig((unsigned char*)&elf_header->e_flags, 4);
	m_e_ehsize =  littletobig((unsigned char*)&elf_header->e_ehsize, 2);
	m_e_phentsize = littletobig((unsigned char*)&elf_header->e_phentsize, 2);
	m_e_phnum =  littletobig((unsigned char*)&elf_header->e_phnum, 2);
	m_e_shentsize = littletobig((unsigned char*)&elf_header->e_shentsize, 2);
	m_e_shnum = littletobig((unsigned char*)&elf_header->e_shnum, 2);
	m_e_shstrndx = littletobig((unsigned char*)&elf_header->e_shstrndx, 2);

	// プログラムヘッダの数は不定なのでリスト構造で保持する
	ent = (struct Elf32_Phdr*)malloc(sizeof(struct Elf32_Phdr));
	m_program_hed = ent;

	// プログラムヘッダーの個数分繰り返す
	for(i = 0; i < m_e_phnum; i++)
	{
		// プログラムヘッダの開始番地取得
		elf_program = (struct Elf32_Phdr*)&buff[ m_e_phoff + m_e_phentsize * i ];
		
		// ヘッダの内容を保存
		ent->p_type = littletobig((unsigned char*)&elf_program->p_type, 4);
		ent->p_offset = littletobig((unsigned char*)&elf_program->p_offset, 4);
		ent->p_vaddr = littletobig((unsigned char*)&elf_program->p_vaddr, 4);
		ent->p_paddr = littletobig((unsigned char*)&elf_program->p_paddr, 4);
		ent->p_filesz = littletobig((unsigned char*)&elf_program->p_filesz, 4);
		ent->p_memsz = littletobig((unsigned char*)&elf_program->p_memsz, 4);
		ent->p_flags = littletobig((unsigned char*)&elf_program->p_flags, 4);
		ent->p_align = littletobig((unsigned char*)&elf_program->p_align, 4);
		ent->next = 0x00; // リストの終端コード 0x00

		// リスト構造で保存する
		ent_tmp = ent;
		ent = (struct Elf32_Phdr*)malloc(sizeof(struct Elf32_Phdr));
		ent_tmp->next = ent;
	}


	return 0;
}
Пример #5
0
/** Check a kernel image and determine the target type.
 * @param loader	LAOS loader data structure. */
void laos_arch_check(laos_loader_t *loader) {
	if(!elf_check(loader->kernel, ELFCLASS32, ELFDATA2LSB, ELF_EM_ARM))
		boot_error("Kernel image is not for this architecture");

	loader->target = TARGET_TYPE_32BIT;
}
Пример #6
0
int _exec(void *image, size_t size, int flags) {
	struct slt32_header *slt_hdr;
	struct slt32_entry *slt;
	struct elf32_ehdr *exec;
	struct elf_cache cache;
	void  *entry;
	size_t i;

	const char *soname;
	char imgname[28];

	/* check executable */
	if (elf_check(image)) {
		return 1;
	}

	/*** POINT OF MAYBE RETURNING IF YOU, y'know, have to... ***/

	/* copy executable high */
	exec = (void*) sltalloc("dl.img:exec", size);

	if ((uintptr_t) image % PAGESZ) {
		/* not aligned, copy */
		page_anon(exec, size, PROT_READ | PROT_WRITE);
		memcpy(exec, image, size);
	}
	else {
		/* aligned, use paging */
		page_self(image, exec, size);
	}

	/*** POINT OF NO RETURN ***/

	/* load dependencies */
	for (i = 0;; i++) {
		soname = _dep(exec, i, 0);
		if (!soname) break;

		strlcpy(imgname, "dl.img:", 28);
		strlcat(imgname, soname, 28);

		slt = sltget_name(imgname);
		if (!slt) continue;

		_load((void*) slt->base, slt->size, RTLD_LAZY | RTLD_GLOBAL | RTLD_OVERWRITE);

		sltfree_name(imgname);
	}

	/* clear lower memory */
	slt     = (void*) SLT_BASE;
	slt_hdr = (void*) SLT_BASE;

	for (i = slt_hdr->first; i; i = slt[i].next) {
		if (slt[i].flags & SLT_FLAG_CLEANUP) {
			page_free((void*) slt[i].base, slt[i].size);
		}
	}

	/* load executable */
	elf_load(exec, 0);
	exec  = (void*) 0x100000;
	entry = (void*) exec->e_entry;

	elf_gencache(&cache, exec, 1);
	elfc_relocate_all(&cache);

	/* remove executable image */
	sltfree_name("dl.img:exec");

	/* reset event handler */
	_when(0);

	/* enter executable */
	dl_enter(entry);

	return 1;
}