binfmt_aout_cris_flat.c

来自「elinux jffs初始版本 具体了解JFFS的文件系统!」· C语言 代码 · 共 589 行 · 第 1/2 页

C
589
字号
		unsigned long symbols;                long relocs =                  do_mmap(file, 0,                          hdr->a_trsize + hdr->a_drsize,                          /* ??? FIXME:                               We get a rom mapping with this                              mmap unless PROT_WRITE, and then                              do_munmap() returns error because                              the "rom mapping" stuff does not                              work.  Unfortunately I don't know                              what it really should do.                               When is_in_rom() and all that                               "works", then remove PROT_WRITE                               below. */                          PROT_READ|PROT_WRITE, 0,                          32 + code_len + data_len);                if (relocs > MMAP_ERRLIMIT) {			printk("Couldn't mmap relocs.\n");                        sys_close(fd);                        send_sig(SIGKILL, current, 0);                        return -ENOMEM;                }                if (! perform_cris_aout_relocations(startaddr, code_len,                                                    dataaddr, data_len,                                                    bssaddr,                                                    bss_len,                                                    (void *) relocs,                                                    hdr->a_trsize,                                                    hdr->a_drsize,						    NULL, 0, NULL, 0,                                                    bprm->envp, bprm->envc,                                                    bprm->e_uid,                                                    bprm->e_uid != current->uid                                                    || bprm->e_gid != current->gid)) {			/* Probably because it needs symbols to resolve			   shared libraries; they're not mmap:ed as this			   could have been a statically linked			   executable, and we'd just waste time reading			   them in.  */			symbols =			     do_mmap(file, 0,				     hdr->a_syms + hdr->a_stringsize,				     /* ??? FIXME:					We get a rom mapping with this					mmap unless PROT_WRITE, and then					do_munmap() returns error because					the "rom mapping" stuff does not					work.  Unfortunately I don't know					what it really should do.					When is_in_rom() and all that					"works", then remove PROT_WRITE					below. */				     PROT_READ|PROT_WRITE, 0,				     32 + code_len + data_len + hdr->a_trsize + hdr->a_drsize);			if (symbols > MMAP_ERRLIMIT) {			     printk("Couldn't mmap symbols.\n");			     sys_close(fd);			     send_sig(SIGKILL, current, 0);			     return -ENOMEM;			}			/* A bit of a sanity check; the string-size is			   normally only located after the                           symbols.  We save an fseek here...                           But maybe it's stupid.  */			if (hdr->a_stringsize			    != get_user((long *) (symbols + hdr->a_syms))) {			     printk("Fishy string length in %s: 0x%lx should be 0x%lx\n",				    bprm->filename, hdr->a_stringsize, get_user((long *) (symbols + hdr->a_syms)));			     sys_close(fd);			     send_sig(SIGKILL, current, 0);			     return -ENOMEM;			}#if 0                        // TRACE_ON();                        printk("%d cycles, stack @ 0x%lx\n",CRIS_CYCLES(),                               current->kernel_stack_page);#endif			if (! perform_cris_aout_relocations(startaddr, code_len,							    dataaddr, data_len,							    bssaddr,							    bss_len,							    (void *) relocs,							    hdr->a_trsize,							    hdr->a_drsize,							    (void *) symbols,							    hdr->a_syms,							    (void *) symbols							    + hdr->a_syms,							    hdr->a_stringsize - 4,                                                            bprm->envp, bprm->envc,                                                            bprm->e_uid,                                                            bprm->e_uid != current->uid                                                            || bprm->e_gid != current->gid)) {			     /* Something fishy among them relocations. */			     printk("Fish among relocs and symbols of %s\n",				    bprm->filename);			     sys_close(fd);			     send_sig(SIGKILL, current, 0);			     return -ENOMEM;			}			/* Done; unmap the strings and symbols. */			do_munmap(symbols, hdr->a_syms + hdr->a_stringsize);                }                /* I don't think there's any use trying to keep                   it, re-cycling it for stack. */                do_munmap(relocs, hdr->a_trsize + hdr->a_drsize);        }        /* What would be a good stack size?  Your guess is as           good as mine.  Maybe the program knows, maybe not. */	/* NOTE do_mmap below uses kmalloc and its wasteful of memory	   if we don't have stack_len as a 2**x - 16. */	stack_len = hdr->stack_hint ? hdr->stack_hint : 16360;		/* Make room on stack for arguments & environment */	stack_len += strlen(bprm->filename) + 1 + 4;	stack_len += stringarraylen(bprm->envc, bprm->envp);	stack_len += stringarraylen(bprm->argc, bprm->argv);        /* Align on 4-byte boundary and add 4 bytes for           alignment of argv (envp will become "naturally"           aligned). */	stack_len += 8-((stack_len) & 3);        /* Get stack.  Trampolines and signal handlers may cause           execution on stack, so keep that flag (even though           nobody looks at the flags for NO_MM). */	/* since we stuff this in current->kernel_stack_page, it is later freed by	   kfree() and NOT do_munmap - better alloc it with kmalloc instead. later when	   CRIS has support for usp/ssp we don't need this.            Huh?  That last comment is moot; all this is due to NO_MM. */	/*	stackaddr = do_mmap(0, 0, stack_len, PROT_READ|PROT_WRITE|PROT_EXEC, 0, 0);	*/	current->mm->user_stack_size = stack_len;	stackaddr = alloc_kernel_stack();#ifdef BDEBUG	printk("pid %d: stack %p to %p.\n", current->pid, stackaddr,	       stackaddr + stack_len);#endif        /* Mapping failed? */        if(!stackaddr) {                sys_close(fd);                send_sig(SIGKILL, current, 0);                return -ENOMEM;        }        {                /* Avoid unnecessary indirection (makes ugly and slow assembly code). */                struct mm_struct *mm = current->mm;                struct task_struct *curr = current;                mm->start_code = startaddr;                mm->end_code = startaddr + code_len;                mm->start_data = dataaddr;                mm->end_data = dataaddr + data_len;#ifdef BDEBUG                printk("start_code: %x, end_code: %x\n", mm->start_code,mm->end_code);		printk("start_data: %x, end_data: %x\n", mm->start_data,mm->end_data);#endif                mm->rss = 0;                curr->suid = curr->euid = curr->fsuid = bprm->e_uid;                curr->sgid = curr->egid = curr->fsgid = bprm->e_gid;                curr->flags &= ~PF_FORKNOEXEC; 	                mm->executable = bprm->inode; 	                /*for(i=0;i<16;i++) {                        printk("%.2x ", ((char*)dataaddr)[i] & 0xff);                        }                        printk("\n");*/	                if (curr->exec_domain && curr->exec_domain->use_count)                  (*curr->exec_domain->use_count)--;                if (curr->binfmt && curr->binfmt->use_count)                  (*curr->binfmt->use_count)--;                curr->exec_domain = lookup_exec_domain(curr->personality);                curr->binfmt = &aout_cris_flat_format;                if (curr->exec_domain && curr->exec_domain->use_count)                  (*curr->exec_domain->use_count)++;                if (curr->binfmt && curr->binfmt->use_count)                  (*curr->binfmt->use_count)++;                /* Don't know what to put here for the moment. */                mm->start_brk = mm->brk = 0;                /* What's the - 4 for?  What's being put at that                   location?  Can we remove the -4? */                p = stackaddr + stack_len - 4;	#ifdef DEBUG                printk("p=%x\n", p);#endif	                p = create_aout_cris_flat_tables(p, bprm);#ifdef DEBUG                printk("p(create_aout_cris_flat_tables)=%x\n", p);	                printk("arg_start = %x\n", mm->arg_start);                printk("arg_end = %x\n", mm->arg_end);                printk("env_start = %x\n", mm->env_start);                printk("env_end = %x\n", mm->env_end);#endif                mm->start_stack = p;                /*printk("start_stack: %x\n", mm->start_stack);*/                /* Haven't really decided on these actual registers;                   have to look around.  Change later, maybe. */                regs->r6 = (unsigned long) system_call;                regs->r7 = dataaddr;                regs->r8 = bssaddr;		/* for libc initial debug output */		regs->r9 = (unsigned long) console_print_etrax;                regs->r3 = bprm->argc;                regs->r4 = mm->arg_end;     /* arg_end is at end of strings, start of table! */                regs->r5 = mm->env_end;     /* likewise */                regs->r2 = mm->start_stack; /* in theory, this isn't needed anymore */		/* mess with the stack and set the entry ip */                start_thread(regs, startaddr, p);#ifdef DEBUG		printk("started thread at 0x%x.\n", startaddr);#endif		/* free the old stack and remember the new so exit() can free it for us */		free_kernel_stack(current->kernel_stack_page);		current->kernel_stack_page = stackaddr;#if 0		/* this is just temporary while we dont HAVE any signal handling! */		current->blocked = 0xffffffff;  /* we dont want any signals! */#endif                if (curr->flags & PF_PTRACED)                        send_sig(SIGTRAP, curr, 0);        }	return 0;}#define readdw(x) get_user((udword *) (x))#define writedw(x,y) put_user((y), (udword *) (x))/* The things used to relocate look like this */struct reloctype{  udword address;  udword segsym;  udword addend;};static intload_aout_cris_flat_binary(struct linux_binprm * bprm, struct pt_regs * regs){	int retval;	MOD_INC_USE_COUNT;	retval = do_load_aout_cris_flat_binary(bprm, regs);	MOD_DEC_USE_COUNT;	return retval;}int init_aout_cris_flat_binfmt(void) {	return register_binfmt(&aout_cris_flat_format);}#ifdef MODULEint init_module(void) {	return init_aout_cris_flat_binfmt();}void cleanup_module( void) {	unregister_binfmt(&aout_cris_flat_format);}#endif

⌨️ 快捷键说明

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