⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 elfload.c.svn-base

📁 我们自己开发的一个OSEK操作系统!不知道可不可以?
💻 SVN-BASE
📖 第 1 页 / 共 3 页
字号:
	*interp_load_addr = load_addr;	return ((abi_ulong) interp_elf_ex->e_entry) + load_addr;}/* Best attempt to load symbols from this ELF object. */static void load_symbols(struct elfhdr *hdr, int fd){    unsigned int i;    struct elf_shdr sechdr, symtab, strtab;    char *strings;    struct syminfo *s;#if (ELF_CLASS == ELFCLASS64)    // Disas uses 32 bit symbols    struct elf32_sym *syms32 = NULL;    struct elf_sym *sym;#endif    lseek(fd, hdr->e_shoff, SEEK_SET);    for (i = 0; i < hdr->e_shnum; i++) {	if (read(fd, &sechdr, sizeof(sechdr)) != sizeof(sechdr))	    return;#ifdef BSWAP_NEEDED	bswap_shdr(&sechdr);#endif	if (sechdr.sh_type == SHT_SYMTAB) {	    symtab = sechdr;	    lseek(fd, hdr->e_shoff		  + sizeof(sechdr) * sechdr.sh_link, SEEK_SET);	    if (read(fd, &strtab, sizeof(strtab))		!= sizeof(strtab))		return;#ifdef BSWAP_NEEDED	    bswap_shdr(&strtab);#endif	    goto found;	}    }    return; /* Shouldn't happen... */ found:    /* Now know where the strtab and symtab are.  Snarf them. */    s = malloc(sizeof(*s));    s->disas_symtab = malloc(symtab.sh_size);#if (ELF_CLASS == ELFCLASS64)    syms32 = malloc(symtab.sh_size / sizeof(struct elf_sym)                    * sizeof(struct elf32_sym));#endif    s->disas_strtab = strings = malloc(strtab.sh_size);    if (!s->disas_symtab || !s->disas_strtab)	return;    lseek(fd, symtab.sh_offset, SEEK_SET);    if (read(fd, s->disas_symtab, symtab.sh_size) != symtab.sh_size)	return;    for (i = 0; i < symtab.sh_size / sizeof(struct elf_sym); i++) {#ifdef BSWAP_NEEDED	bswap_sym(s->disas_symtab + sizeof(struct elf_sym)*i);#endif#if (ELF_CLASS == ELFCLASS64)        sym = s->disas_symtab + sizeof(struct elf_sym)*i;        syms32[i].st_name = sym->st_name;        syms32[i].st_info = sym->st_info;        syms32[i].st_other = sym->st_other;        syms32[i].st_shndx = sym->st_shndx;        syms32[i].st_value = sym->st_value & 0xffffffff;        syms32[i].st_size = sym->st_size & 0xffffffff;#endif    }#if (ELF_CLASS == ELFCLASS64)    free(s->disas_symtab);    s->disas_symtab = syms32;#endif    lseek(fd, strtab.sh_offset, SEEK_SET);    if (read(fd, strings, strtab.sh_size) != strtab.sh_size)	return;    s->disas_num_syms = symtab.sh_size / sizeof(struct elf_sym);    s->next = syminfos;    syminfos = s;}int load_elf_binary(struct linux_binprm * bprm, struct target_pt_regs * regs,                    struct image_info * info){    struct elfhdr elf_ex;    struct elfhdr interp_elf_ex;    struct exec interp_ex;    int interpreter_fd = -1; /* avoid warning */    abi_ulong load_addr, load_bias;    int load_addr_set = 0;    unsigned int interpreter_type = INTERPRETER_NONE;    unsigned char ibcs2_interpreter;    int i;    abi_ulong mapped_addr;    struct elf_phdr * elf_ppnt;    struct elf_phdr *elf_phdata;    abi_ulong elf_bss, k, elf_brk;    int retval;    char * elf_interpreter;    abi_ulong elf_entry, interp_load_addr = 0;    int status;    abi_ulong start_code, end_code, start_data, end_data;    abi_ulong reloc_func_desc = 0;    abi_ulong elf_stack;    char passed_fileno[6];    ibcs2_interpreter = 0;    status = 0;    load_addr = 0;    load_bias = 0;    elf_ex = *((struct elfhdr *) bprm->buf);          /* exec-header */#ifdef BSWAP_NEEDED    bswap_ehdr(&elf_ex);#endif    /* First of all, some simple consistency checks */    if ((elf_ex.e_type != ET_EXEC && elf_ex.e_type != ET_DYN) ||       				(! elf_check_arch(elf_ex.e_machine))) {	    return -ENOEXEC;    }    bprm->p = copy_elf_strings(1, &bprm->filename, bprm->page, bprm->p);    bprm->p = copy_elf_strings(bprm->envc,bprm->envp,bprm->page,bprm->p);    bprm->p = copy_elf_strings(bprm->argc,bprm->argv,bprm->page,bprm->p);    if (!bprm->p) {        retval = -E2BIG;    }    /* Now read in all of the header information */    elf_phdata = (struct elf_phdr *)malloc(elf_ex.e_phentsize*elf_ex.e_phnum);    if (elf_phdata == NULL) {	return -ENOMEM;    }    retval = lseek(bprm->fd, elf_ex.e_phoff, SEEK_SET);    if(retval > 0) {	retval = read(bprm->fd, (char *) elf_phdata,				elf_ex.e_phentsize * elf_ex.e_phnum);    }    if (retval < 0) {	perror("load_elf_binary");	exit(-1);	free (elf_phdata);	return -errno;    }#ifdef BSWAP_NEEDED    elf_ppnt = elf_phdata;    for (i=0; i<elf_ex.e_phnum; i++, elf_ppnt++) {        bswap_phdr(elf_ppnt);    }#endif    elf_ppnt = elf_phdata;    elf_bss = 0;    elf_brk = 0;    elf_stack = ~((abi_ulong)0UL);    elf_interpreter = NULL;    start_code = ~((abi_ulong)0UL);    end_code = 0;    start_data = 0;    end_data = 0;    for(i=0;i < elf_ex.e_phnum; i++) {	if (elf_ppnt->p_type == PT_INTERP) {	    if ( elf_interpreter != NULL )	    {		free (elf_phdata);		free(elf_interpreter);		close(bprm->fd);		return -EINVAL;	    }	    /* This is the program interpreter used for	     * shared libraries - for now assume that this	     * is an a.out format binary	     */	    elf_interpreter = (char *)malloc(elf_ppnt->p_filesz);	    if (elf_interpreter == NULL) {		free (elf_phdata);		close(bprm->fd);		return -ENOMEM;	    }	    retval = lseek(bprm->fd, elf_ppnt->p_offset, SEEK_SET);	    if(retval >= 0) {		retval = read(bprm->fd, elf_interpreter, elf_ppnt->p_filesz);	    }	    if(retval < 0) {	 	perror("load_elf_binary2");		exit(-1);	    }	    /* If the program interpreter is one of these two,	       then assume an iBCS2 image. Otherwise assume	       a native linux image. */	    /* JRP - Need to add X86 lib dir stuff here... */	    if (strcmp(elf_interpreter,"/usr/lib/libc.so.1") == 0 ||		strcmp(elf_interpreter,"/usr/lib/ld.so.1") == 0) {	      ibcs2_interpreter = 1;	    }#if 0	    printf("Using ELF interpreter %s\n", elf_interpreter);#endif	    if (retval >= 0) {		retval = open(path(elf_interpreter), O_RDONLY);		if(retval >= 0) {		    interpreter_fd = retval;		}		else {		    perror(elf_interpreter);		    exit(-1);		    /* retval = -errno; */		}	    }	    if (retval >= 0) {		retval = lseek(interpreter_fd, 0, SEEK_SET);		if(retval >= 0) {		    retval = read(interpreter_fd,bprm->buf,128);		}	    }	    if (retval >= 0) {		interp_ex = *((struct exec *) bprm->buf); /* aout exec-header */		interp_elf_ex=*((struct elfhdr *) bprm->buf); /* elf exec-header */	    }	    if (retval < 0) {		perror("load_elf_binary3");		exit(-1);		free (elf_phdata);		free(elf_interpreter);		close(bprm->fd);		return retval;	    }	}	elf_ppnt++;    }    /* Some simple consistency checks for the interpreter */    if (elf_interpreter){	interpreter_type = INTERPRETER_ELF | INTERPRETER_AOUT;	/* Now figure out which format our binary is */	if ((N_MAGIC(interp_ex) != OMAGIC) && (N_MAGIC(interp_ex) != ZMAGIC) &&	    	(N_MAGIC(interp_ex) != QMAGIC)) {	  interpreter_type = INTERPRETER_ELF;	}	if (interp_elf_ex.e_ident[0] != 0x7f ||	    	strncmp(&interp_elf_ex.e_ident[1], "ELF",3) != 0) {	    interpreter_type &= ~INTERPRETER_ELF;	}	if (!interpreter_type) {	    free(elf_interpreter);	    free(elf_phdata);	    close(bprm->fd);	    return -ELIBBAD;	}    }    /* OK, we are done with that, now set up the arg stuff,       and then start this sucker up */    {	char * passed_p;	if (interpreter_type == INTERPRETER_AOUT) {	    snprintf(passed_fileno, sizeof(passed_fileno), "%d", bprm->fd);	    passed_p = passed_fileno;	    if (elf_interpreter) {		bprm->p = copy_elf_strings(1,&passed_p,bprm->page,bprm->p);		bprm->argc++;	    }	}	if (!bprm->p) {	    if (elf_interpreter) {	        free(elf_interpreter);	    }	    free (elf_phdata);	    close(bprm->fd);	    return -E2BIG;	}    }    /* OK, This is the point of no return */    info->end_data = 0;    info->end_code = 0;    info->start_mmap = (abi_ulong)ELF_START_MMAP;    info->mmap = 0;    elf_entry = (abi_ulong) elf_ex.e_entry;    /* Do this so that we can load the interpreter, if need be.  We will       change some of these later */    info->rss = 0;    bprm->p = setup_arg_pages(bprm->p, bprm, info);    info->start_stack = bprm->p;    /* Now we do a little grungy work by mmaping the ELF image into     * the correct location in memory.  At this point, we assume that     * the image should be loaded at fixed address, not at a variable     * address.     */    for(i = 0, elf_ppnt = elf_phdata; i < elf_ex.e_phnum; i++, elf_ppnt++) {        int elf_prot = 0;        int elf_flags = 0;        abi_ulong error;	if (elf_ppnt->p_type != PT_LOAD)            continue;        if (elf_ppnt->p_flags & PF_R) elf_prot |= PROT_READ;        if (elf_ppnt->p_flags & PF_W) elf_prot |= PROT_WRITE;        if (elf_ppnt->p_flags & PF_X) elf_prot |= PROT_EXEC;        elf_flags = MAP_PRIVATE | MAP_DENYWRITE;        if (elf_ex.e_type == ET_EXEC || load_addr_set) {            elf_flags |= MAP_FIXED;        } else if (elf_ex.e_type == ET_DYN) {            /* Try and get dynamic programs out of the way of the default mmap               base, as well as whatever program they might try to exec.  This               is because the brk will follow the loader, and is not movable.  */            /* NOTE: for qemu, we do a big mmap to get enough space               without hardcoding any address */            error = target_mmap(0, ET_DYN_MAP_SIZE,                                PROT_NONE, MAP_PRIVATE | MAP_ANON,                                -1, 0);            if (error == -1) {                perror("mmap");                exit(-1);            }            load_bias = TARGET_ELF_PAGESTART(error - elf_ppnt->p_vaddr);        }        error = target_mmap(TARGET_ELF_PAGESTART(load_bias + elf_ppnt->p_vaddr),                            (elf_ppnt->p_filesz +                             TARGET_ELF_PAGEOFFSET(elf_ppnt->p_vaddr)),                            elf_prot,                            (MAP_FIXED | MAP_PRIVATE | MAP_DENYWRITE),                            bprm->fd,                            (elf_ppnt->p_offset -                             TARGET_ELF_PAGEOFFSET(elf_ppnt->p_vaddr)));        if (error == -1) {            perror("mmap");            exit(-1);        }#ifdef LOW_ELF_STACK        if (TARGET_ELF_PAGESTART(elf_ppnt->p_vaddr) < elf_stack)            elf_stack = TARGET_ELF_PAGESTART(elf_ppnt->p_vaddr);#endif        if (!load_addr_set) {            load_addr_set = 1;            load_addr = elf_ppnt->p_vaddr - elf_ppnt->p_offset;            if (elf_ex.e_type == ET_DYN) {                load_bias += error -                    TARGET_ELF_PAGESTART(load_bias + elf_ppnt->p_vaddr);                load_addr += load_bias;                reloc_func_desc = load_bias;            }        }        k = elf_ppnt->p_vaddr;        if (k < start_code)            start_code = k;        if (start_data < k)            start_data = k;        k = elf_ppnt->p_vaddr + elf_ppnt->p_filesz;        if (k > elf_bss)            elf_bss = k;        if ((elf_ppnt->p_flags & PF_X) && end_code <  k)            end_code = k;        if (end_data < k)            end_data = k;        k = elf_ppnt->p_vaddr + elf_ppnt->p_memsz;        if (k > elf_brk) elf_brk = k;    }    elf_entry += load_bias;    elf_bss += load_bias;    elf_brk += load_bias;    start_code += load_bias;    end_code += load_bias;    start_data += load_bias;    end_data += load_bias;    if (elf_interpreter) {	if (interpreter_type & 1) {	    elf_entry = load_aout_interp(&interp_ex, interpreter_fd);	}	else if (interpreter_type & 2) {	    elf_entry = load_elf_interp(&interp_elf_ex, interpreter_fd,					    &interp_load_addr);	}        reloc_func_desc = interp_load_addr;	close(interpreter_fd);	free(elf_interpreter);	if (elf_entry == ~((abi_ulong)0UL)) {	    printf("Unable to load interpreter\n");	    free(elf_phdata);	    exit(-1);	    return 0;	}    }    free(elf_phdata);    if (loglevel)	load_symbols(&elf_ex, bprm->fd);    if (interpreter_type != INTERPRETER_AOUT) close(bprm->fd);    info->personality = (ibcs2_interpreter ? PER_SVR4 : PER_LINUX);#ifdef LOW_ELF_STACK    info->start_stack = bprm->p = elf_stack - 4;#endif    bprm->p = create_elf_tables(bprm->p,		    bprm->argc,		    bprm->envc,                    &elf_ex,                    load_addr, load_bias,		    interp_load_addr,		    (interpreter_type == INTERPRETER_AOUT ? 0 : 1),		    info);    info->load_addr = reloc_func_desc;    info->start_brk = info->brk = elf_brk;    info->end_code = end_code;    info->start_code = start_code;    info->start_data = start_data;    info->end_data = end_data;    info->start_stack = bprm->p;    /* Calling set_brk effectively mmaps the pages that we need for the bss and break       sections */    set_brk(elf_bss, elf_brk);    padzero(elf_bss, elf_brk);#if 0    printf("(start_brk) %x\n" , info->start_brk);    printf("(end_code) %x\n" , info->end_code);    printf("(start_code) %x\n" , info->start_code);    printf("(end_data) %x\n" , info->end_data);    printf("(start_stack) %x\n" , info->start_stack);    printf("(brk) %x\n" , info->brk);#endif    if ( info->personality == PER_SVR4 )    {	    /* Why this, you ask???  Well SVr4 maps page 0 as read-only,	       and some applications "depend" upon this behavior.	       Since we do not have the power to recompile these, we	       emulate the SVr4 behavior.  Sigh.  */	    mapped_addr = target_mmap(0, qemu_host_page_size, PROT_READ | PROT_EXEC,                                      MAP_FIXED | MAP_PRIVATE, -1, 0);    }    info->entry = elf_entry;    return 0;}static int load_aout_interp(void * exptr, int interp_fd){    printf("a.out interpreter not yet supported\n");    return(0);}void do_init_thread(struct target_pt_regs *regs, struct image_info *infop){    init_thread(regs, infop);}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -