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 + -
显示快捷键?