示例#1
0
bool
elf_loadFile(void *elfFile, bool phys, intptr_t offset)
{
	int i;
	
	if (elf_checkFile(elfFile) != 0) {
		return false;
	}

	for(i=0; i < elf_getNumProgramHeaders(elfFile); i++) {
		/* Load that section */
		uintptr_t dest, src;
		size_t len;
		if (phys) {
			dest = (uintptr_t) elf_getProgramHeaderPaddr(elfFile, i);
		} else {
			dest = (uintptr_t) elf_getProgramHeaderVaddr(elfFile, i);
		}
		dest += offset;
		len = elf_getProgramHeaderFileSize(elfFile, i);
		src = (uintptr_t) elfFile + elf_getProgramHeaderOffset(elfFile, i);
		memcpy((void*) dest, (void*) src, len);
		dest += len;
		memset((void*) dest, 0, elf_getProgramHeaderMemorySize(elfFile, i) - len);
	}

	return true;
}
示例#2
0
文件: main.c 项目: BwRy/seL4_tools
/*
 * Load an ELF file into physical memory at the given physical address.
 *
 * Return the byte past the last byte of the physical address used.
 */
static paddr_t load_elf(const char *name, void *elf,
                        paddr_t dest_paddr, struct image_info *info)
{
    uint64_t min_vaddr, max_vaddr;
    size_t image_size;

    /* Fetch image info. */
    elf_getMemoryBounds(elf, 0, &min_vaddr, &max_vaddr);
    max_vaddr = ROUND_UP(max_vaddr, PAGE_BITS);
    image_size = (size_t)(max_vaddr - min_vaddr);

    /* Ensure our starting physical address is aligned. */
    if (!IS_ALIGNED(dest_paddr, PAGE_BITS)) {
        printf("Attempting to load ELF at unaligned physical address!\n");
        abort();
    }

    /* Ensure that the ELF file itself is 4-byte aligned in memory, so that
     * libelf can perform word accesses on it. */
    if (!IS_ALIGNED(dest_paddr, 2)) {
        printf("Input ELF file not 4-byte aligned in memory!\n");
        abort();
    }

    /* Print diagnostics. */
    printf("ELF-loading image '%s'\n", name);
    printf("  paddr=[%lx..%lx]\n", dest_paddr, dest_paddr + image_size - 1);
    printf("  vaddr=[%lx..%lx]\n", (vaddr_t)min_vaddr, (vaddr_t)max_vaddr - 1);
    printf("  virt_entry=%lx\n", (vaddr_t)elf_getEntryPoint(elf));

    /* Ensure the ELF file is valid. */
    if (elf_checkFile(elf) != 0) {
        printf("Attempting to load invalid ELF file '%s'.\n", name);
        abort();
    }

    /* Ensure sane alignment of the image. */
    if (!IS_ALIGNED(min_vaddr, PAGE_BITS)) {
        printf("Start of image '%s' is not 4K-aligned!\n", name);
        abort();
    }

    /* Ensure that we region we want to write to is sane. */
    ensure_phys_range_valid(dest_paddr, dest_paddr + image_size);

    /* Copy the data. */
    unpack_elf_to_paddr(elf, dest_paddr);

    /* Record information about the placement of the image. */
    info->phys_region_start = dest_paddr;
    info->phys_region_end = dest_paddr + image_size;
    info->virt_region_start = (vaddr_t)min_vaddr;
    info->virt_region_end = (vaddr_t)max_vaddr;
    info->virt_entry = (vaddr_t)elf_getEntryPoint(elf);
    info->phys_virt_offset = dest_paddr - (vaddr_t)min_vaddr;

    /* Return address of next free physical frame. */
    return ROUND_UP(dest_paddr + image_size, PAGE_BITS);
}
示例#3
0
bool reios_loadElf(const string& elf) {

	FILE* f = fopen(elf.c_str(), "rb");
	if (!f) {
		return false;
	}
	fseek(f, 0, SEEK_END);
	size_t size = ftell(f);

	if (size > 16 * 1024 * 1024) {
		return false;
	}

	void* elfFile = malloc(size);
	memset(elfFile, 0, size);

	fseek(f, 0, SEEK_SET);
	fread(elfFile, 1, size, f);
	fclose(f);

	int i;
	bool phys = false;


	if (elf_checkFile(elfFile) != 0) {
		free(elfFile);
		return false;
	}

	for (i = 0; i < elf_getNumProgramHeaders(elfFile); i++) {
		/* Load that section */
		uint64_t dest, src;
		size_t len;
		if (phys) {
			dest = elf_getProgramHeaderPaddr(elfFile, i);
		}
		else {
			dest = elf_getProgramHeaderVaddr(elfFile, i);
		}
		len = elf_getProgramHeaderFileSize(elfFile, i);
		src = (uint64_t)(uintptr_t)elfFile + elf_getProgramHeaderOffset(elfFile, i);
		
		u8* ptr = GetMemPtr(dest, len);

		memcpy((void*)ptr, (void*)(uintptr_t)src, len);
		ptr += len;
		memset((void*)ptr, 0, elf_getProgramHeaderMemorySize(elfFile, i) - len);
	}

	return true;
}
示例#4
0
文件: main.c 项目: BwRy/seL4_tools
/*
 * ELF-loader for ARM systems.
 *
 * We are currently running out of physical memory, with an ELF file for the
 * kernel and one or more ELF files for the userspace image. (Typically there
 * will only be one userspace ELF file, though if we are running a multi-core
 * CPU, we may have multiple userspace images; one per CPU.) These ELF files
 * are packed into an 'ar' archive.
 *
 * The kernel ELF file indicates what physical address it wants to be loaded
 * at, while userspace images run out of virtual memory, so don't have any
 * requirements about where they are located. We place the kernel at its
 * desired location, and then load userspace images straight after it in
 * physical memory.
 *
 * Several things could possibly go wrong:
 *
 *  1. The physical load address of the kernel might want to overwrite this
 *  ELF-loader;
 *
 *  2. The physical load addresses of the kernel might not actually be in
 *  physical memory;
 *
 *  3. Userspace images may not fit in physical memory, or may try to overlap
 *  the ELF-loader.
 *
 *  We attempt to check for some of these, but some may go unnoticed.
 */
void load_images(struct image_info *kernel_info, struct image_info *user_info,
                 int max_user_images, int *num_images)
{
    int i;
    uint64_t kernel_phys_start, kernel_phys_end;
    paddr_t next_phys_addr;
    const char *elf_filename;
    unsigned long unused;

    /* Load kernel. */
    void *kernel_elf = cpio_get_file(_archive_start, "kernel.elf", &unused);
    if (kernel_elf == NULL) {
        printf("No kernel image present in archive!\n");
        abort();
    }
    if (elf_checkFile(kernel_elf)) {
        printf("Kernel image not a valid ELF file!\n");
        abort();
    }

    elf_getMemoryBounds(kernel_elf, 1, &kernel_phys_start, &kernel_phys_end);
    next_phys_addr = load_elf("kernel", kernel_elf,
                              (paddr_t)kernel_phys_start, kernel_info);

    /*
     * Load userspace images.
     *
     * We assume (and check) that the kernel is the first file in the archive,
     * and then load the (n+1)'th file in the archive onto the (n)'th CPU.
     */
    (void)cpio_get_entry(_archive_start, 0, &elf_filename, &unused);
    if (strcmp(elf_filename, "kernel.elf") != 0) {
        printf("Kernel image not first image in archive.\n");
        abort();
    }
    *num_images = 0;
    for (i = 0; i < max_user_images; i++) {
        /* Fetch info about the next ELF file in the archive. */
        void *user_elf = cpio_get_entry(_archive_start, i + 1,
                                        &elf_filename, &unused);
        if (user_elf == NULL) {
            break;
        }

        /* Load the file into memory. */
        next_phys_addr = load_elf(elf_filename, user_elf,
                                  next_phys_addr, &user_info[*num_images]);
        *num_images = i + 1;
    }
}
示例#5
0
文件: elf.c 项目: ahixon/papaya
int elf_load (addrspace_t dest_as, char *elf_file) {

    int num_headers;
    int err;
    int i;

    /* Ensure that the ELF file looks sane. */
    if (elf_checkFile(elf_file)){
        return seL4_InvalidArgument;
    }

    num_headers = elf_getNumProgramHeaders(elf_file);
    for (i = 0; i < num_headers; i++) {
        char *source_addr;
        unsigned long flags, file_size, segment_size, vaddr;

        /* Skip non-loadable segments (such as debugging data). */
        if (elf_getProgramHeaderType(elf_file, i) != PT_LOAD)
            continue;

        /* Fetch information about this segment. */
        source_addr = elf_file + elf_getProgramHeaderOffset(elf_file, i);
        file_size = elf_getProgramHeaderFileSize(elf_file, i);
        segment_size = elf_getProgramHeaderMemorySize(elf_file, i);
        vaddr = elf_getProgramHeaderVaddr(elf_file, i);
        flags = elf_getProgramHeaderFlags(elf_file, i);

        /* Copy it across into the vspace. */
        err = load_segment_directly_into_vspace(dest_as, source_addr,
            segment_size, file_size, vaddr,
            get_sel4_rights_from_elf(flags) & seL4_AllRights);

        if (err != 0) {
            return 1;
        }
    }

    return 0;
}
示例#6
0
bool
elf_getMemoryBounds(void *elfFile, bool phys, uint64_t *min, uint64_t *max)
{
	uint64_t mem_min = UINT64_MAX;
	uint64_t mem_max = 0;
	int i;

	if (elf_checkFile(elfFile) != 0) {
		return false;
	}

	for(i=0; i < elf_getNumProgramHeaders(elfFile); i++) {
		uint64_t sect_min, sect_max;

		if (elf_getProgramHeaderMemorySize(elfFile, i) == 0) {
			continue;
		}

		if (phys) {
			sect_min = elf_getProgramHeaderPaddr(elfFile, i);
		} else {
			sect_min = elf_getProgramHeaderVaddr(elfFile, i);
		}

		sect_max = sect_min + elf_getProgramHeaderMemorySize(elfFile, i);

		if (sect_max > mem_max) {
			mem_max = sect_max;
		}
		if (sect_min < mem_min) {
			mem_min = sect_min;
		}
	}
	*min = mem_min;
	*max = mem_max;

	return true;
};
示例#7
0
文件: elf.c 项目: 8l/sel4-riscv
int elf_load(seL4_RISCV_PageDirectory dest_as, char *elf_file) {

    int num_headers;
    int err;
    int i;

    /* Ensure that the ELF file looks sane. */
    if (elf_checkFile(elf_file)){
        return seL4_InvalidArgument;
    }

    num_headers = elf_getNumProgramHeaders(elf_file);
    for (i = 0; i < num_headers; i++) {
        char *source_addr;
        unsigned long flags, file_size, segment_size, vaddr;

        /* Skip non-loadable segments (such as debugging data). */
        if (elf_getProgramHeaderType(elf_file, i) != PT_LOAD)
            continue;

        /* Fetch information about this segment. */
        source_addr = elf_file + elf_getProgramHeaderOffset(elf_file, i);
        file_size = elf_getProgramHeaderFileSize(elf_file, i);
        segment_size = elf_getProgramHeaderMemorySize(elf_file, i);
        vaddr = elf_getProgramHeaderVaddr(elf_file, i);
        flags = elf_getProgramHeaderFlags(elf_file, i);

        /* Copy it across into the vspace. */
        dprintf(1, " * Loading segment %08x-->%08x\n", (int)vaddr, (int)(vaddr + segment_size));
        err = load_segment_into_vspace(dest_as, source_addr, segment_size, file_size, vaddr,
                                       get_sel4_rights_from_elf(flags) & seL4_AllRights);
        conditional_panic(err != 0, "Elf loading failed!\n");
    }

    return 0;
}
示例#8
0
static void elf_syms(FILE* out,const char* libfile)
{
	struct stat statbuf;

	printf("LIBFILE \"%s\"\n", libfile);
	int fd = open(libfile, O_RDONLY, 0);

	if (!fd)
	{
		printf("Failed to open file \"%s\"\n", libfile);
		return;
	}
	if (fstat(fd, &statbuf) < 0)
	{
		printf("Failed to fstat file \"%s\"\n", libfile);
		return;
	}

	{
		void* data = mmap(0, statbuf.st_size, PROT_READ, MAP_SHARED, fd, 0);
		close(fd);

		if (data == (void*)-1)
		{
			printf("Failed to mmap file \"%s\"\n", libfile);
			return;
		}

		//printf("MMap: %08p, %08X\n",data,statbuf.st_size);

		int dynsym=-1;
		int dynstr=-1;
		int strtab=-1;
		int symtab=-1;

		if (elf_checkFile(data)>=0)
		{
			int scnt=elf_getNumSections(data);

			for (int si=0;si<scnt;si++)
			{
				uint32_t section_type = elf_getSectionType(data, si);
				uint64_t section_link = elf_getSectionLink(data, si);
				switch (section_type) {
				case SHT_DYNSYM:
					fprintf(stderr, "DYNSYM");
					dynsym = si;
					if (section_link < scnt)
						dynstr = section_link;
					break;
				case SHT_SYMTAB:
					fprintf(stderr, "SYMTAB");
					symtab = si;
					if (section_link < scnt)
						strtab = section_link;
					break;
				default:
					break;;
				}
			}
		}
		else
		{
			printf("Invalid elf file\n");
		}

		// Use SHT_SYMTAB if available insteaf of SHT_DYNSYM
		// (there is more info here):
		if (symtab >= 0 && strtab >= 0)
		{
			dynsym = symtab;
			dynstr = strtab;
		}

		if (dynsym >= 0)
		{
			prof_head(out,"libsym",libfile);
			// printf("Found dymsym %d, and dynstr %d!\n",dynsym,dynstr);
			elf_symbol* sym=(elf_symbol*)elf_getSection(data,dynsym);
			elf64_symbol* sym64 = (elf64_symbol*) sym;

			bool elf32 = ((struct Elf32_Header*)data)->e_ident[EI_CLASS] == ELFCLASS32;
			size_t symbol_size = elf32 ? sizeof(elf_symbol) : sizeof(elf64_symbol);
			int symcnt = elf_getSectionSize(data,dynsym) / symbol_size;

			for (int i=0; i < symcnt; i++)
			{
				uint64_t st_value =  elf32 ? sym[i].st_value : sym64[i].st_value;
				uint32_t st_name  =  elf32 ? sym[i].st_name  : sym64[i].st_name;
				uint16_t st_shndx =  elf32 ? sym[i].st_shndx : sym64[i].st_shndx;
				uint16_t st_type  = (elf32 ? sym[i].st_info  : sym64[i].st_info) & 0xf;
				uint64_t st_size  =  elf32 ? sym[i].st_size  : sym64[i].st_size;
				if (st_type == STT_FUNC && st_value && st_name && st_shndx)
				{
					char* name=(char*)elf_getSection(data,dynstr);// sym[i].st_shndx
					// printf("Symbol %d: %s, %08" PRIx64 ", % " PRIi64 " bytes\n",
						// i, name + st_name, st_value, st_size);
					//PRIx64 & friends not in android ndk (yet?)
					fprintf(out,"%08x %d %s\n", (int)st_value, (int)st_size, name + st_name);
				}
			}
		}
		else
		{
			printf("No dynsym\n");
		}

		munmap(data,statbuf.st_size);
	}
}
示例#9
0
文件: boot_sys.c 项目: scan/seL4
BOOT_CODE static paddr_t
load_boot_module(multiboot_module_t* boot_module, paddr_t load_paddr)
{
    v_region_t v_reg;
    word_t entry;
    Elf_Header_t* elf_file = (Elf_Header_t*)(word_t)boot_module->start;

    if (!elf_checkFile(elf_file)) {
        printf("Boot module does not contain a valid ELF image\n");
        return 0;
    }

    v_reg = elf_getMemoryBounds(elf_file);
    entry = elf_file->e_entry;

    if (v_reg.end == 0) {
        printf("ELF image in boot module does not contain any segments\n");
        return 0;
    }
    v_reg.end = ROUND_UP(v_reg.end, PAGE_BITS);

    printf("size=0x%lx v_entry=%p v_start=%p v_end=%p ",
           v_reg.end - v_reg.start,
           (void*)entry,
           (void*)v_reg.start,
           (void*)v_reg.end
          );

    if (!IS_ALIGNED(v_reg.start, PAGE_BITS)) {
        printf("Userland image virtual start address must be 4KB-aligned\n");
        return 0;
    }
    if (v_reg.end + 2 * BIT(PAGE_BITS) > PPTR_USER_TOP) {
        /* for IPC buffer frame and bootinfo frame, need 2*4K of additional userland virtual memory */
        printf("Userland image virtual end address too high\n");
        return 0;
    }
    if ((entry < v_reg.start) || (entry >= v_reg.end)) {
        printf("Userland image entry point does not lie within userland image\n");
        return 0;
    }

    load_paddr = find_load_paddr(load_paddr, v_reg.end - v_reg.start);
    assert(load_paddr);

    /* fill ui_info struct */
    boot_state.ui_info.pv_offset = load_paddr - v_reg.start;
    boot_state.ui_info.p_reg.start = load_paddr;
    load_paddr += v_reg.end - v_reg.start;
    boot_state.ui_info.p_reg.end = load_paddr;
    boot_state.ui_info.v_entry = entry;

    printf("p_start=0x%lx p_end=0x%lx\n",
           boot_state.ui_info.p_reg.start,
           boot_state.ui_info.p_reg.end
          );

    if (!module_paddr_region_valid(
                boot_state.ui_info.p_reg.start,
                boot_state.ui_info.p_reg.end)) {
        printf("End of loaded userland image lies outside of usable physical memory\n");
        return 0;
    }

    /* initialise all initial userland memory and load potentially sparse ELF image */
    memzero(
        (void*)boot_state.ui_info.p_reg.start,
        boot_state.ui_info.p_reg.end - boot_state.ui_info.p_reg.start
    );
    elf_load(elf_file, boot_state.ui_info.pv_offset);

    return load_paddr;
}
示例#10
0
文件: elf.c 项目: KGG814/AOS
void elf_load(int pid, seL4_CPtr reply_cap, void *_args, int err) {
    if (TMP_DEBUG) printf("elf_load\n");

    elf_load_args *args = (elf_load_args *) _args;
    if (err) {
        eprintf("Error caught in elf_load\n");
        args->cb(pid, reply_cap, args->cb_args, err);
        free(args);
        return;  
    }

    char *elf_file = args->elf_file;
    int curr_header = args->curr_header;
    //addr_space *as = proc_table[pid];
    /* Ensure that the ELF file looks sane. */
    if (elf_checkFile(elf_file)){
        eprintf("Error caught in elf_load\n");
        args->cb(pid, reply_cap, args->cb_args, -1);
        free(args);
        return;
    }

    int num_headers = elf_getNumProgramHeaders(elf_file);
    if (curr_header < num_headers) {
        char *source_addr;
        unsigned long flags, file_size, segment_size, vaddr;

        /* Skip non-loadable segments (such as debugging data). */
        if (elf_getProgramHeaderType(elf_file, curr_header) != PT_LOAD) {
            args->curr_header++;
            elf_load(pid, reply_cap, args, 0);
        } else {
            /* Fetch information about this segment. */
            source_addr = elf_file + elf_getProgramHeaderOffset(elf_file, curr_header);
            file_size = elf_getProgramHeaderFileSize(elf_file, curr_header);
            segment_size = elf_getProgramHeaderMemorySize(elf_file, curr_header);
            vaddr = elf_getProgramHeaderVaddr(elf_file, curr_header);
            flags = elf_getProgramHeaderFlags(elf_file, curr_header);

            /* Copy it across into the vspace. */
            dprintf(1, " * Loading segment %08x-->%08x\n", (int)vaddr, (int)(vaddr + segment_size));
            // Set up load segment arguments
            args->curr_header++;
            load_segment_args *segment_args = malloc(sizeof(load_segment_args));
            
            if (segment_args == NULL) {
                eprintf("Error caught in elf_load\n");
                args->cb(pid, reply_cap, args->cb_args, -1);
                free(args);
                return;
            }

            segment_args->src = source_addr;
            segment_args->dst = vaddr;
            segment_args->pos = 0;
            segment_args->segment_size = segment_size;
            segment_args->file_size = file_size;
            segment_args->permissions = get_sel4_rights_from_elf(flags) & seL4_AllRights;
            segment_args->cb = elf_load;
            segment_args->cb_args = args;

            load_segment_into_vspace(pid, reply_cap, segment_args, 0);
        }
  
        //conditional_panic(err != 0, "Elf loading failed!\n");
    } else {
        // Do callback
        printf("Doing callback with pid :%d\n", pid);
        args->cb(pid, reply_cap, args->cb_args, 0);
        free(args);
    }

    if (TMP_DEBUG) printf("elf_load end\n");
}
示例#11
0
void elf_syms(FILE* out,const char* libfile)
{
	struct stat statbuf;

	printf("LIBFILE \"%s\"\n", libfile);
	int fd = open(libfile, O_RDONLY, 0);

	if (!fd)
	{
		printf("Failed to open file \"%s\"\n", libfile);
		return;
	}
	if (fstat(fd, &statbuf) < 0)
	{
		printf("Failed to fstat file \"%s\"\n", libfile);
		return;
	}

	{
		void* data = mmap(0, statbuf.st_size, PROT_READ, MAP_SHARED, fd, 0);
		close(fd);

		if (data == (void*)-1)
		{
			printf("Failed to mmap file \"%s\"\n", libfile);
			return;
		}

		//printf("MMap: %08p, %08X\n",data,statbuf.st_size);

		int dynsym=-1;
		int dynstr=-1;

		/*
			Section: 2 -> .dynsym
			Section: 3 -> .dynstr
		*/
		if (elf_checkFile(data)>=0)
		{
			int scnt=elf_getNumSections(data);

			for (int si=0;si<scnt;si++)
			{
				if (strcmp(".dynsym",elf_getSectionName(data,si))==0)
					dynsym=si;

			
				if (strcmp(".dynstr",elf_getSectionName(data,si))==0)
					dynstr=si;
			}
		}
		else
		{
			printf("Invalid elf file\n");
		}

		if (dynsym >= 0)
		{
			prof_head(out,"libsym",libfile);
		//	printf("Found dymsym %d, and dynstr %d!\n",dynsym,dynstr);
			elf_symbol* sym=(elf_symbol*)elf_getSection(data,dynsym);
			int symcnt=elf_getSectionSize(data,dynsym)/sizeof(elf_symbol);

			for (int i=0;i<symcnt;i++)
			{
				if (sym[i].st_value && sym[i].st_name && sym[i].st_shndx)
				{
					char* name=(char*)elf_getSection(data,dynstr);// sym[i].st_shndx

				//	printf("Symbol %d: %s, %08X, %d bytes\n",i,name+sym[i].st_name,sym[i].st_value,sym[i].st_size);
					fprintf(out,"%08X %d %s\n",sym[i].st_value,sym[i].st_size,name+sym[i].st_name);
				}
			}
		}
		else
		{
			printf("No dynsym\n");
		}

		munmap(data,statbuf.st_size);
	}
}