binfmt_flat.c
来自「elinux jffs初始版本 具体了解JFFS的文件系统!」· C语言 代码 · 共 355 行
C
355 行
/* * linux/fs/binfmt_flat.c * * Copyright (C) 1991, 1992, 1996 Linus Torvalds */#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/a.out.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/flat.h>static int load_flat_binary(struct linux_binprm *, struct pt_regs * regs);extern void dump_thread(struct pt_regs *, struct user *);static struct linux_binfmt flat_format = {#ifndef MODULE NULL, NULL, load_flat_binary, NULL, NULL#else NULL, &mod_use_count_, load_flat_binary, NULL, NULL#endif};static unsigned long putstring(unsigned long p, char * string){ unsigned long l = strlen(string)+1;#ifdef DEBUG printk("put_string '%s'\n", string);#endif p -= l; memcpy((void*)p, string, l); return p;}static unsigned long putstringarray(unsigned long p, int count, char ** array){ /*p=putstring(p, "");*/ /*printk("p1=%x, array=%x\n", p, array); printk("array[0]=%x\n", array[0]);*/#ifdef DEBUG printk("putstringarray(%d)\n", count);#endif while(count) { p=putstring(p, array[--count]);#ifdef DEBUG printk("p2=%x\n", p);#endif } return p;}static unsigned long stringarraylen(int count, char ** array){ int l = 4; while(count) { l += strlen(array[--count]); l++; l+=4; } return l;}/* * create_flat_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_flat_tables(unsigned long pp, struct linux_binprm * bprm){ unsigned long *argv,*envp; unsigned long * sp; char * p = (char*)pp; int argc = bprm->argc; int envc = bprm->envc; sp = (unsigned long *) ((-(unsigned long)sizeof(char *)) & (unsigned long) p);#ifdef __alpha__/* whee.. test-programs are so much fun. */ put_user(0, --sp); put_user(0, --sp); if (bprm->loader) { put_user(0, --sp); put_user(0x3eb, --sp); put_user(bprm->loader, --sp); put_user(0x3ea, --sp); } put_user(bprm->exec, --sp); put_user(0x3e9, --sp);#endif sp -= envc+1; envp = sp; sp -= argc+1; argv = sp;#if defined(__i386__) || defined(__mc68000__) put_user(envp,--sp); put_user(argv,--sp);#endif 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 (unsigned long)sp;}/* * These are the functions used to load a.out style executables and shared * libraries. There is no binary dependent code anywhere else. */inline intdo_load_flat_binary(struct linux_binprm * bprm, struct pt_regs * regs){ struct flat_hdr * hdr; struct file * file; unsigned long error; unsigned long pos; unsigned long p = bprm->p; unsigned long data_len, bss_len, stack_len, code_len; current->personality = PER_LINUX; file = current->files->fd[open_inode(bprm->inode, O_RDONLY)]; #ifdef DEBUG printk("BINFMT_FLAT: Loading file: %x\n", file); show_free_areas();#endif /*for(i=0;i<16;i++) { printk("%.2x ", ((char*)error)[i] & 0xff); } printk("\n");*/ hdr = (struct flat_hdr*)bprm->buf; if (strncmp(hdr->magic, "bFLT", 4) || (hdr->rev != 1)) { printk("bad magic/rev\n"); return -ENOEXEC; } if (flush_old_exec(bprm)) { printk("unable to flush\n"); return -ENOMEM; } /*printk("hdr->entry = %d, hdr->data_start = %d, hdr->data_end = %d, hdr->bss_end = %d, hdr->stack_size = %d\n", hdr->entry, hdr->data_start, hdr->data_end, hdr->bss_end, hdr->stack_size);*/ /* OK, This is the point of no return */ code_len = hdr->data_start; data_len = hdr->data_end - hdr->data_start; bss_len = hdr->bss_end - hdr->data_end; stack_len = hdr->stack_size; /* Make room on stack for arguments & environment */ stack_len += strlen(bprm->filename) + 1; stack_len += stringarraylen(bprm->envc, bprm->envp); stack_len += stringarraylen(bprm->argc, bprm->argv); /*stack_len += 4-((pos+data_len+bss_len+stack_len) & 3);*/ /* Align stack */ /*printk("Stack = %d, (%d)\n", stack_len, stack_len & 3);*/ error = do_mmap(file, 0, code_len + data_len + bss_len + stack_len, PROT_READ|PROT_EXEC, 0, /* MAP_* */ 0);#ifdef DEBUG printk("BINFMT_FLAT: mmap returned: %x\n", error); show_free_areas();#endif if (is_in_rom(error)) {#ifdef DEBUG printk("BINFMT_FLAT: ROM mapping of file\n");#endif /* do_mmap returned a ROM mapping, so allocate RAM for data + bss + stack */ /*pos = kmalloc(data_len+bss_len+stack_len, GFP_KERNEL);*/ pos = do_mmap(0, 0, data_len+bss_len+stack_len, PROT_READ|PROT_WRITE|PROT_EXEC, 0, 0); #ifdef DEBUG printk("BINFMT_FLAT: Allocated data+bss+stack: %x\n", pos); show_free_areas();#endif /* And then fill it in */ /*printk("Reading data from %d-%d to %x\n", hdr->data_start, hdr->data_end - hdr->data_start, pos);*/ read_exec(bprm->inode, hdr->data_start, (char *)pos, data_len, 0); /*printk("Clearing %x to %x\n", pos+data_len, pos+data_len+bss_len+stack_len);*/ memset((void*)(pos + data_len), 0, bss_len + stack_len); } else {#ifdef DEBUG printk("BINFMT_FLAT: RAM mapping of file\n");#endif /* Since we got a RAM mapping, mmap has already allocated a block for us, and read in the data. . */ pos = error + code_len; } current->mm->start_code = error + hdr->entry; current->mm->end_code = error + hdr->data_start; current->mm->start_data = pos; current->mm->end_data = pos + data_len; current->mm->brk = pos + data_len + bss_len; /*printk("start_code: %x, end_code: %x\n", current->mm->start_code,current->mm->end_code); printk("start_data: %x, end_data: %x\n", current->mm->start_data,current->mm->end_data);*/ current->mm->rss = 0; current->suid = current->euid = current->fsuid = bprm->e_uid; current->sgid = current->egid = current->fsgid = bprm->e_gid; current->flags &= ~PF_FORKNOEXEC; current->mm->executable = bprm->inode; /*for(i=0;i<16;i++) { printk("%.2x ", ((char*)pos)[i] & 0xff); } printk("\n");*/ 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 = &flat_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 = pos + data_len + bss_len + stack_len - 4; #ifdef DEBUG printk("p=%x\n", p);#endif p = putstringarray(p, 1, &bprm->filename);#ifdef DEBUG printk("p(filename)=%x\n", p);#endif p = putstringarray(p, bprm->envc, bprm->envp);#ifdef DEBUG printk("p(envp)=%x\n", p);#endif p = putstringarray(p, bprm->argc, bprm->argv);#ifdef DEBUG printk("p(argv)=%x\n", p);#endif p = create_flat_tables(p, bprm);#ifdef DEBUG printk("p(create_flat_tables)=%x\n", p); printk("arg_start = %x\n", current->mm->arg_start); printk("arg_end = %x\n", current->mm->arg_end); printk("env_start = %x\n", current->mm->env_start); printk("env_end = %x\n", current->mm->env_end);#endif current->mm->start_stack = p; /*printk("start_stack: %x\n", current->mm->start_stack);*/ /* FIXME, wrong number of arguments.. what is a5?? start_thread(regs, current->mm->start_code, current->mm->start_data - hdr->data_start, p); */ if (current->flags & PF_PTRACED) send_sig(SIGTRAP, current, 0); return 0;}static intload_flat_binary(struct linux_binprm * bprm, struct pt_regs * regs){ int retval; MOD_INC_USE_COUNT; retval = do_load_flat_binary(bprm, regs); MOD_DEC_USE_COUNT; return retval;}int init_flat_binfmt(void) { return register_binfmt(&flat_format);}#ifdef MODULEint init_module(void) { return init_flat_binfmt();}void cleanup_module( void) { unregister_binfmt(&flat_format);}#endif
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?