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

📄 binfmt_aout_cris.c

📁 elinux jffs初始版本 具体了解JFFS的文件系统!
💻 C
字号:
/* *  linux/fs/binfmt_aout_cris.c * *  Copyright (C) 1991, 1992, 1996  Linus Torvalds *  Copyright (C) 2000              Axis Communications AB * */#include <linux/module.h>#include <linux/fs.h>#include <linux/sched.h>#include <linux/kernel.h>#include <linux/mm.h>#include <linux/mman.h>#include <linux/errno.h>#include <linux/signal.h>#include <linux/string.h>#include <linux/stat.h>#include <linux/fcntl.h>#include <linux/ptrace.h>#include <linux/user.h>#include <linux/malloc.h>#include <linux/binfmts.h>#include <linux/personality.h>#include <asm/system.h>#include <asm/segment.h>#include <asm/pgtable.h>#include <asm/a.out.h>#include <asm/io.h>#undef DEBUG#define BDEBUG/* Do sanity checking.  Enable if you're paranoid or if they're after you. */#ifdef DEBUG#define SANITYCHECK_RELOC#endif#define MAX(a,b) ((a) > (b) ? (a) : (b))static int load_aout_cris_binary(struct linux_binprm *, struct pt_regs * regs);static struct linux_binfmt aout_cris_format = {#ifndef MODULE	NULL, NULL, load_aout_cris_binary, NULL, NULL#else	NULL, &mod_use_count_, load_aout_cris_binary, NULL, NULL#endif};static void set_brk(unsigned long start, unsigned long end){	start = PAGE_ALIGN(start);	end = PAGE_ALIGN(end);	if (end <= start)		return;#ifdef BDEBUG	printk("set_brk start %p end %p\n", start, end);#endif	do_mmap(NULL, start, end - start,		PROT_READ | PROT_WRITE | PROT_EXEC,		MAP_FIXED | MAP_PRIVATE, 0);}/* * create_aout_tables() parses the env- and arg-strings in new user * memory and creates the pointer tables from them, and puts their * addresses on the "stack", returning the new stack pointer value. */static unsigned long * create_aout_tables(char * p, struct linux_binprm * bprm){	unsigned long *argv,*envp;	unsigned long * sp;	int argc = bprm->argc;	int envc = bprm->envc;	sp = (unsigned long *) ((-(unsigned long)sizeof(char *)) & (unsigned long) p);	printk("create_aout_tables sp = 0x%p\n", sp);	sp -= envc+1;	envp = sp;	sp -= argc+1;	argv = sp;	/* remember where the argv and envp's start, by stacking their	 * addresses 	 */	put_user(envp,--sp);	put_user(argv,--sp);	/* and remember argc as well. */	put_user(argc,--sp);	current->mm->arg_start = (unsigned long) p;	while (argc-->0) {		put_user(p,argv++);		while (get_user(p++)) /* nothing */ ;	}	put_user(NULL,argv);	current->mm->arg_end = current->mm->env_start = (unsigned long) p;	while (envc-->0) {		put_user(p,envp++);		while (get_user(p++)) /* nothing */ ;	}	put_user(NULL,envp);	current->mm->env_end = (unsigned long) p;	return sp;}asmlinkage int system_call(void);void console_print_etrax(char *buf);/* * These are the functions used to load a.out style executables and shared * libraries.  There is no binary dependent code anywhere else. *//* mmap might return an error, but not all negative long's are errors, some might be  * addresses. */#define MMAP_ERRLIMIT 0xffff0000inline intdo_load_aout_cris_binary(struct linux_binprm * bprm, struct pt_regs * regs){	struct aout_cris_exec ex;	struct file * file;        int fd;	unsigned long error;	unsigned long p = bprm->p;	unsigned long fd_offset;	unsigned long rlim;	current->personality = PER_LINUX;	fd_offset = 0; /*N_TXTOFF(ex);*/	ex = *(struct aout_cris_exec *) bprm->buf;  /* exec-header */#ifdef BDEBUG	printk("BINFMT_AOUT_CRIS: Loading file: %x\n", file);	printk("  a_text %x, a_data %x\n", ex.a_text, ex.a_data);#endif		if (memcmp(ex.magic, "\x08\x01\xff\x01", 4)) {		printk("bad magic\n");		return -ENOEXEC;	}	if (flush_old_exec(bprm)) {		printk("unable to flush\n");		return -ENOMEM;	}		/* adjust text length to incorporate header */	ex.a_text += 0x20;		/* OK, This is the point of no return */	current->mm->end_code = ex.a_text +		(current->mm->start_code = N_TXTADDR(ex));	current->mm->end_data = ex.a_data +		(current->mm->start_data = N_DATADDR(ex));	current->mm->brk = ex.a_bss +		(current->mm->start_brk = N_BSSADDR(ex));#ifdef BDEBUG	printk("  start_code %p, end_code %p\n",	       current->mm->start_code,	       current->mm->end_code);	printk("  start_data %p, end_data %p\n",	       current->mm->start_data,	       current->mm->end_data);	printk("  start_brk %p, brk %p\n",	       current->mm->start_brk,	       current->mm->brk);#endif	current->mm->rss = 0;	current->mm->mmap = NULL;	current->suid = current->euid = current->fsuid = bprm->e_uid;	current->sgid = current->egid = current->fsgid = bprm->e_gid; 	current->flags &= ~PF_FORKNOEXEC;        fd = open_inode(bprm->inode, O_RDONLY);	if(fd < 0)		return fd;	file = current->files->fd[fd];		/* if we cant mmap the file, we need to read it in completely */		if (!file->f_op || !file->f_op->mmap) {		printk("  cannot mmap - reading whole file\n");		sys_close(fd);		do_mmap(NULL, 0, ex.a_text+ex.a_data,			PROT_READ|PROT_WRITE|PROT_EXEC,			MAP_FIXED|MAP_PRIVATE, 0);		read_exec(bprm->inode, fd_offset,			  (char *) N_TXTADDR(ex), ex.a_text+ex.a_data, 0);		goto beyond_if;	}#if 0	/* for now map text+data in same segment */	error = do_mmap(file, N_TXTADDR(ex), sizeof(ex) + ex.a_text + ex.a_data,			PROT_READ | PROT_EXEC | PROT_WRITE,			MAP_FIXED | MAP_PRIVATE | MAP_DENYWRITE | MAP_EXECUTABLE,			fd_offset);	sys_close(fd);	if (error != N_TXTADDR(ex)) {		printk("  could not mmap text+data segment: %d\n", error);		send_sig(SIGKILL, current, 0);		return error;	}#else	/* ok. mmap the text segment at the correct address */	error = do_mmap(file, N_TXTADDR(ex), ex.a_text,			PROT_READ | PROT_EXEC,			MAP_FIXED | MAP_PRIVATE | MAP_DENYWRITE | MAP_EXECUTABLE,			fd_offset);		if (error != N_TXTADDR(ex)) {		printk("  could not mmap text segment: %d\n", error);		sys_close(fd);		send_sig(SIGKILL, current, 0);		return error;	}	#if 0	printk("%x %x %x %x %x %x\n", *(long *)0x2020, *(long *)0x2024, *(long *)0x2028,	       *(long *)0x202c, *(long *)0x2030, *(long *)0x2034);#endif	/* and the data segment */	error = do_mmap(file, N_DATADDR(ex), ex.a_data,			PROT_READ | PROT_WRITE | PROT_EXEC,			MAP_FIXED | MAP_PRIVATE | MAP_DENYWRITE | MAP_EXECUTABLE,			fd_offset + ex.a_text);	sys_close(fd);	if (error != N_DATADDR(ex)) {		printk("  could not mmap data segment: %d\n", error);		send_sig(SIGKILL, current, 0);		return error;	}#endif beyond_if:	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 = &aout_cris_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)++;	set_brk(current->mm->start_brk, current->mm->brk);	p = setup_arg_pages(p, bprm);		p = (unsigned long) create_aout_tables((char *)p, bprm);	current->mm->start_stack = p;	/* Haven't really decided on these actual registers;	   have to look around.  Change later, maybe. */	/* for libc initial debug output */	regs->r9 = (unsigned long) console_print_etrax;		/* argc, argv and envp are on the stack. crt0.c should really	 * unstack them but because of legacy we do like this for now.	 */	regs->r3 = ((unsigned long *)p)[0];	regs->r4 = ((unsigned long *)p)[1];	regs->r5 = ((unsigned long *)p)[2];	regs->r2 = p; /* in theory, this isn't needed anymore */#ifdef BDEBUG	printk("start_thread at 0x%p, usp 0x%p\n", N_TXTADDR(ex) + 32, p);#endif	//TRACE_ON();	start_thread(regs, N_TXTADDR(ex) + 32, p);	if (current->flags & PF_PTRACED)		send_sig(SIGTRAP, current, 0);	return 0;}static intload_aout_cris_binary(struct linux_binprm * bprm, struct pt_regs * regs){	int retval;	MOD_INC_USE_COUNT;	retval = do_load_aout_cris_binary(bprm, regs);	MOD_DEC_USE_COUNT;	return retval;}int init_aout_cris_binfmt(void) {	return register_binfmt(&aout_cris_format);}#ifdef MODULEint init_module(void) {	return init_aout_cris_binfmt();}void cleanup_module( void) {	unregister_binfmt(&aout_cris_format);}#endif

⌨️ 快捷键说明

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