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

📄 binfmt_elf.c

📁 elinux jffs初始版本 具体了解JFFS的文件系统!
💻 C
📖 第 1 页 / 共 3 页
字号:
	elf_interpreter = NULL;	start_code = ~0UL;	end_code = 0;	end_data = 0;	for (i = 0; i < elf_ex.e_phnum; i++) {		if (elf_ppnt->p_type == PT_INTERP) {			if (elf_interpreter != NULL) {				iput(interpreter_inode);				kfree(elf_phdata);				kfree(elf_interpreter);				sys_close(elf_exec_fileno);				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 *) kmalloc(elf_ppnt->p_filesz,							   GFP_KERNEL);			if (elf_interpreter == NULL) {				kfree(elf_phdata);				sys_close(elf_exec_fileno);				return -ENOMEM;			}			retval = read_exec(bprm->inode, elf_ppnt->p_offset,					   elf_interpreter,					   elf_ppnt->p_filesz, 1);			/* If the program interpreter is one of these two,			   then assume an iBCS2 image. Otherwise assume			   a native linux image. */			if (strcmp(elf_interpreter, "/usr/lib/libc.so.1") == 0 ||			strcmp(elf_interpreter, "/usr/lib/ld.so.1") == 0)				ibcs2_interpreter = 1;#if 0			printk("Using ELF interpreter %s\n", elf_interpreter);#endif			if (retval >= 0) {				old_fs = get_fs();	/* This could probably be optimized */				set_fs(get_ds());				retval = ret_namei = open_namei(elf_interpreter, 0, 0,					       &interpreter_inode, NULL);				set_fs(old_fs);			}			if (retval >= 0)				retval = permission(interpreter_inode, MAY_EXEC);			if (retval >= 0)				retval = S_ISREG(interpreter_inode->i_mode) ? 0 : -EACCES;			if (retval >= 0)				retval = read_exec(interpreter_inode, 0, bprm->buf, 128, 1);			if (retval >= 0) {				interp_ex = *((struct exec *) bprm->buf);	/* exec-header */				interp_elf_ex = *((struct elfhdr *) bprm->buf);		/* exec-header */			}			if (retval < 0) {				if (ret_namei >= 0)					iput(interpreter_inode);				kfree(elf_phdata);				kfree(elf_interpreter);				sys_close(elf_exec_fileno);				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) {			iput(interpreter_inode);			kfree(elf_interpreter);			kfree(elf_phdata);			sys_close(elf_exec_fileno);			return -ELIBBAD;		}	}	/* OK, we are done with that, now set up the arg stuff,	   and then start this sucker up */	if (!bprm->sh_bang) {		char *passed_p;		if (interpreter_type == INTERPRETER_AOUT) {			sprintf(passed_fileno, "%d", elf_exec_fileno);			passed_p = passed_fileno;			if (elf_interpreter) {				bprm->p = copy_strings(1, &passed_p, bprm->page, bprm->p, 2);				bprm->argc++;			}		}		if (!bprm->p) {			if (elf_interpreter) {				kfree(elf_interpreter);			}			iput(interpreter_inode);			kfree(elf_phdata);			sys_close(elf_exec_fileno);			return -E2BIG;		}	}	if (flush_old_exec(bprm)) {		iput(interpreter_inode);		return -ENOMEM;	}	/* OK, This is the point of no return */	current->mm->end_data = 0;	current->mm->end_code = 0;	current->mm->start_mmap = ELF_START_MMAP;	current->mm->mmap = NULL;	elf_entry = (unsigned long) elf_ex.e_entry;	/* Do this so that we can load the interpreter, if need be.  We will	   change some of these later */	current->mm->rss = 0;	bprm->p = setup_arg_pages(bprm->p, bprm);	current->mm->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. */	old_fs = get_fs();	set_fs(get_ds());	for (i = 0, elf_ppnt = elf_phdata; i < elf_ex.e_phnum; i++, elf_ppnt++) {		if (elf_ppnt->p_type == PT_LOAD) {			int elf_prot = 0;			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;			error = do_mmap(file,					ELF_PAGESTART(elf_ppnt->p_vaddr),					(elf_ppnt->p_filesz +				      ELF_PAGEOFFSET(elf_ppnt->p_vaddr)),					elf_prot,					(MAP_FIXED | MAP_PRIVATE |					 MAP_DENYWRITE | MAP_EXECUTABLE),					(elf_ppnt->p_offset -				     ELF_PAGEOFFSET(elf_ppnt->p_vaddr)));#ifdef LOW_ELF_STACK			if (ELF_PAGESTART(elf_ppnt->p_vaddr) < elf_stack)				elf_stack = ELF_PAGESTART(elf_ppnt->p_vaddr);#endif			if (!load_addr_set) {				load_addr = elf_ppnt->p_vaddr - elf_ppnt->p_offset;				load_addr_set = 1;			}			k = elf_ppnt->p_vaddr;			if (k < start_code)				start_code = k;			k = elf_ppnt->p_vaddr + elf_ppnt->p_filesz;			if (k > elf_bss)				elf_bss = k;#if 1			if ((elf_ppnt->p_flags & PF_X) && end_code < k)#else			if (!(elf_ppnt->p_flags & PF_W) && end_code < k)#endif				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;		}	}	set_fs(old_fs);	if (elf_interpreter) {		if (interpreter_type & 1)			elf_entry = load_aout_interp(&interp_ex,						     interpreter_inode);		else if (interpreter_type & 2)			elf_entry = load_elf_interp(&interp_elf_ex,						    interpreter_inode,						    &interp_load_addr);		iput(interpreter_inode);		kfree(elf_interpreter);		if (elf_entry == ~0UL) {			printk("Unable to load interpreter\n");			kfree(elf_phdata);			send_sig(SIGSEGV, current, 0);			return 0;		}	}	kfree(elf_phdata);	if (interpreter_type != INTERPRETER_AOUT)		sys_close(elf_exec_fileno);	current->personality = (ibcs2_interpreter ? PER_SVR4 : PER_LINUX);	if (current->exec_domain && current->exec_domain->use_count)		(*current->exec_domain->use_count)--;	if (current->binfmt && current->binfmt->use_count)		(*current->binfmt->use_count)--;	current->exec_domain = lookup_exec_domain(current->personality);	current->binfmt = &elf_format;	if (current->exec_domain && current->exec_domain->use_count)		(*current->exec_domain->use_count)++;	if (current->binfmt && current->binfmt->use_count)		(*current->binfmt->use_count)++;#ifndef VM_STACK_FLAGS	current->executable = bprm->inode;	bprm->inode->i_count++;#endif#ifdef LOW_ELF_STACK	current->start_stack = bprm->p = elf_stack - 4;#endif	current->suid = current->euid = current->fsuid = bprm->e_uid;	current->sgid = current->egid = current->fsgid = bprm->e_gid;	current->flags &= ~PF_FORKNOEXEC;	bprm->p = (unsigned long)	    create_elf_tables((char *) bprm->p,			      bprm->argc,			      bprm->envc,		  (interpreter_type == INTERPRETER_ELF ? &elf_ex : NULL),			      load_addr,			      interp_load_addr,			 (interpreter_type == INTERPRETER_AOUT ? 0 : 1));	if (interpreter_type == INTERPRETER_AOUT)		current->mm->arg_start += strlen(passed_fileno) + 1;	current->mm->start_brk = current->mm->brk = elf_brk;	current->mm->end_code = end_code;	current->mm->start_code = start_code;	current->mm->end_data = end_data;	current->mm->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);#if 0	printk("(start_brk) %x\n", current->mm->start_brk);	printk("(end_code) %x\n", current->mm->end_code);	printk("(start_code) %x\n", current->mm->start_code);	printk("(end_data) %x\n", current->mm->end_data);	printk("(start_stack) %x\n", current->mm->start_stack);	printk("(brk) %x\n", current->mm->brk);#endif	if (current->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.  */		error = do_mmap(NULL, 0, 4096, PROT_READ | PROT_EXEC,				MAP_FIXED | MAP_PRIVATE, 0);	}#ifdef ELF_PLAT_INIT	/*	 * The ABI may specify that certain registers be set up in special	 * ways (on i386 %edx is the address of a DT_FINI function, for	 * example.  This macro performs whatever initialization to	 * the regs structure is required.	 */	ELF_PLAT_INIT(regs);#endif	start_thread(regs, elf_entry, bprm->p);	if (current->flags & PF_PTRACED)		send_sig(SIGTRAP, current, 0);	return 0;}static int load_elf_binary(struct linux_binprm *bprm, struct pt_regs *regs){	int retval;	MOD_INC_USE_COUNT;	retval = do_load_elf_binary(bprm, regs);	MOD_DEC_USE_COUNT;	return retval;}/* This is really simpleminded and specialized - we are loading an   a.out library that is given an ELF header. */static inline int do_load_elf_library(int fd){	struct file *file;	struct elfhdr elf_ex;	struct elf_phdr *elf_phdata = NULL;	struct inode *inode;	unsigned long len;	int elf_bss;	int retval;	unsigned long bss;	int error;	int i, j, k;	len = 0;	file = current->files->fd[fd];	inode = file->f_inode;	elf_bss = 0;	if (!file || !file->f_op)		return -EACCES;	/* seek to the beginning of the file */	if (file->f_op->lseek) {		if ((error = file->f_op->lseek(inode, file, 0, 0)) != 0)			return -ENOEXEC;	} else		file->f_pos = 0;	set_fs(KERNEL_DS);	error = file->f_op->read(inode, file, (char *) &elf_ex, sizeof(elf_ex));	set_fs(USER_DS);	if (error != sizeof(elf_ex))		return -ENOEXEC;	if (elf_ex.e_ident[0] != 0x7f ||	    strncmp(&elf_ex.e_ident[1], "ELF", 3) != 0)		return -ENOEXEC;	/* First of all, some simple consistency checks */	if (elf_ex.e_type != ET_EXEC || elf_ex.e_phnum > 2 ||	    !elf_check_arch(elf_ex.e_machine) ||	    (!inode->i_op || !inode->i_op->default_file_ops->mmap))		return -ENOEXEC;	/* Now read in all of the header information */	if (sizeof(struct elf_phdr) * elf_ex.e_phnum > PAGE_SIZE)		 return -ENOEXEC;	elf_phdata = (struct elf_phdr *)	    kmalloc(sizeof(struct elf_phdr) * elf_ex.e_phnum, GFP_KERNEL);	if (elf_phdata == NULL)		return -ENOMEM;	retval = read_exec(inode, elf_ex.e_phoff, (char *) elf_phdata,			   sizeof(struct elf_phdr) * elf_ex.e_phnum, 1);	j = 0;	for (i = 0; i < elf_ex.e_phnum; i++)		if ((elf_phdata + i)->p_type == PT_LOAD)			j++;	if (j != 1) {		kfree(elf_phdata);		return -ENOEXEC;	}	while (elf_phdata->p_type != PT_LOAD)		elf_phdata++;	/* Now use mmap to map the library into memory. */	error = do_mmap(file,			ELF_PAGESTART(elf_phdata->p_vaddr),			(elf_phdata->p_filesz +			 ELF_PAGEOFFSET(elf_phdata->p_vaddr)),			PROT_READ | PROT_WRITE | PROT_EXEC,			MAP_FIXED | MAP_PRIVATE | MAP_DENYWRITE,			(elf_phdata->p_offset -			 ELF_PAGEOFFSET(elf_phdata->p_vaddr)));	k = elf_phdata->p_vaddr + elf_phdata->p_filesz;	if (k > elf_bss)		elf_bss = k;	if (error != ELF_PAGESTART(elf_phdata->p_vaddr)) {		kfree(elf_phdata);		return error;	}	padzero(elf_bss);	len = ELF_PAGESTART(elf_phdata->p_filesz + elf_phdata->p_vaddr + ELF_EXEC_PAGESIZE - 1);	bss = elf_phdata->p_memsz + elf_phdata->p_vaddr;	if (bss > len)		do_mmap(NULL, len, bss - len,			PROT_READ | PROT_WRITE | PROT_EXEC,			MAP_FIXED | MAP_PRIVATE, 0);	kfree(elf_phdata);	return 0;}static int load_elf_library(int fd){	int retval;	MOD_INC_USE_COUNT;	retval = do_load_elf_library(fd);	MOD_DEC_USE_COUNT;	return retval;}/* * Note that some platforms still use traditional core dumps and not * the ELF core dump.  Each platform can select it as appropriate. */#ifdef USE_ELF_CORE_DUMP/* * ELF core dumper * * Modelled on fs/exec.c:aout_core_dump() * Jeremy Fitzhardinge <jeremy@sw.oz.au> *//*

⌨️ 快捷键说明

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