OpenCores
URL https://opencores.org/ocsvn/or1k/or1k/trunk

Subversion Repositories or1k

[/] [or1k/] [trunk/] [rc203soc/] [sw/] [uClinux/] [fs/] [binfmt_flat.c] - Diff between revs 1627 and 1765

Go to most recent revision | Only display areas with differences | Details | Blame | View Log

Rev 1627 Rev 1765
/*
/*
 *  linux/fs/binfmt_flat.c
 *  linux/fs/binfmt_flat.c
 *
 *
 *  Copyright (C) 1998  Kenneth Albanowski <kjahds@kjahds.com>
 *  Copyright (C) 1998  Kenneth Albanowski <kjahds@kjahds.com>
 *                      The Silver Hammer Group, Ltd.
 *                      The Silver Hammer Group, Ltd.
 *
 *
 *  This is a relatively simple binary format, intended solely to contain
 *  This is a relatively simple binary format, intended solely to contain
 *  the bare minimum needed to load and execute simple binaries, with
 *  the bare minimum needed to load and execute simple binaries, with
 *  special attention to executing from ROM, when possible.
 *  special attention to executing from ROM, when possible.
 *
 *
 *  Originally based on:
 *  Originally based on:
 *
 *
 *  linux/fs/binfmt_aout.c
 *  linux/fs/binfmt_aout.c
 *
 *
 *  Copyright (C) 1991, 1992, 1996  Linus Torvalds
 *  Copyright (C) 1991, 1992, 1996  Linus Torvalds
 */
 */
 
 
 
 
#include <linux/module.h>
#include <linux/module.h>
 
 
#include <linux/fs.h>
#include <linux/fs.h>
#include <linux/sched.h>
#include <linux/sched.h>
#include <linux/kernel.h>
#include <linux/kernel.h>
#include <linux/mm.h>
#include <linux/mm.h>
#include <linux/mman.h>
#include <linux/mman.h>
#include <linux/a.out.h>
#include <linux/a.out.h>
#include <linux/errno.h>
#include <linux/errno.h>
#include <linux/signal.h>
#include <linux/signal.h>
#include <linux/string.h>
#include <linux/string.h>
#include <linux/stat.h>
#include <linux/stat.h>
#include <linux/fcntl.h>
#include <linux/fcntl.h>
#include <linux/ptrace.h>
#include <linux/ptrace.h>
#include <linux/user.h>
#include <linux/user.h>
#include <linux/malloc.h>
#include <linux/malloc.h>
#include <linux/binfmts.h>
#include <linux/binfmts.h>
#include <linux/personality.h>
#include <linux/personality.h>
 
 
#include <asm/system.h>
#include <asm/system.h>
#include <asm/segment.h>
#include <asm/segment.h>
#include <asm/pgtable.h>
#include <asm/pgtable.h>
#include <asm/flat.h>
#include <asm/flat.h>
 
 
#undef DEBUG
#undef DEBUG
 
 
static int load_flat_binary(struct linux_binprm *, struct pt_regs * regs);
static int load_flat_binary(struct linux_binprm *, struct pt_regs * regs);
 
 
extern void dump_thread(struct pt_regs *, struct user *);
extern void dump_thread(struct pt_regs *, struct user *);
 
 
static struct linux_binfmt flat_format = {
static struct linux_binfmt flat_format = {
#ifndef MODULE
#ifndef MODULE
        NULL, NULL, load_flat_binary, NULL, NULL
        NULL, NULL, load_flat_binary, NULL, NULL
#else
#else
        NULL, &mod_use_count_, load_flat_binary, NULL, NULL
        NULL, &mod_use_count_, load_flat_binary, NULL, NULL
#endif
#endif
};
};
 
 
static unsigned long putstring(unsigned long p, char * string)
static unsigned long putstring(unsigned long p, char * string)
{
{
        unsigned long l = strlen(string)+1;
        unsigned long l = strlen(string)+1;
#ifdef DEBUG
#ifdef DEBUG
        printk("put_string '%s'\n", string);
        printk("put_string '%s'\n", string);
#endif
#endif
        p -= l;
        p -= l;
        memcpy((void*)p, string, l);
        memcpy((void*)p, string, l);
        return p;
        return p;
}
}
 
 
static unsigned long putstringarray(unsigned long p, int count, char ** array)
static unsigned long putstringarray(unsigned long p, int count, char ** array)
{
{
        /*p=putstring(p, "");*/
        /*p=putstring(p, "");*/
        /*printk("p1=%x, array=%x\n", p, array);
        /*printk("p1=%x, array=%x\n", p, array);
        printk("array[0]=%x\n", array[0]);*/
        printk("array[0]=%x\n", array[0]);*/
#ifdef DEBUG
#ifdef DEBUG
        printk("putstringarray(%d)\n", count);
        printk("putstringarray(%d)\n", count);
#endif
#endif
        while(count) {
        while(count) {
                p=putstring(p, array[--count]);
                p=putstring(p, array[--count]);
#ifdef DEBUG
#ifdef DEBUG
                printk("p2=%x\n", p);
                printk("p2=%x\n", p);
#endif
#endif
        }
        }
        return p;
        return p;
}
}
 
 
static unsigned long stringarraylen(int count, char ** array)
static unsigned long stringarraylen(int count, char ** array)
{
{
        int l = 4;
        int l = 4;
        while(count) {
        while(count) {
                l += strlen(array[--count]);
                l += strlen(array[--count]);
                l++;
                l++;
                l+=4;
                l+=4;
        }
        }
        return l;
        return l;
}
}
 
 
/*
/*
 * create_flat_tables() parses the env- and arg-strings in new user
 * create_flat_tables() parses the env- and arg-strings in new user
 * memory and creates the pointer tables from them, and puts their
 * memory and creates the pointer tables from them, and puts their
 * addresses on the "stack", returning the new stack pointer value.
 * addresses on the "stack", returning the new stack pointer value.
 */
 */
static unsigned long create_flat_tables(unsigned long pp, struct linux_binprm * bprm)
static unsigned long create_flat_tables(unsigned long pp, struct linux_binprm * bprm)
{
{
        unsigned long *argv,*envp;
        unsigned long *argv,*envp;
        unsigned long * sp;
        unsigned long * sp;
        char * p = (char*)pp;
        char * p = (char*)pp;
        int argc = bprm->argc;
        int argc = bprm->argc;
        int envc = bprm->envc;
        int envc = bprm->envc;
 
 
        sp = (unsigned long *) ((-(unsigned long)sizeof(char *)) & (unsigned long) p);
        sp = (unsigned long *) ((-(unsigned long)sizeof(char *)) & (unsigned long) p);
#ifdef __alpha__
#ifdef __alpha__
/* whee.. test-programs are so much fun. */
/* whee.. test-programs are so much fun. */
        put_user(0, --sp);
        put_user(0, --sp);
        put_user(0, --sp);
        put_user(0, --sp);
        if (bprm->loader) {
        if (bprm->loader) {
                put_user(0, --sp);
                put_user(0, --sp);
                put_user(0x3eb, --sp);
                put_user(0x3eb, --sp);
                put_user(bprm->loader, --sp);
                put_user(bprm->loader, --sp);
                put_user(0x3ea, --sp);
                put_user(0x3ea, --sp);
        }
        }
        put_user(bprm->exec, --sp);
        put_user(bprm->exec, --sp);
        put_user(0x3e9, --sp);
        put_user(0x3e9, --sp);
#endif
#endif
        sp -= envc+1;
        sp -= envc+1;
        envp = sp;
        envp = sp;
        sp -= argc+1;
        sp -= argc+1;
        argv = sp;
        argv = sp;
#if defined(__i386__) || defined(__mc68000__)
#if defined(__i386__) || defined(__mc68000__)
        put_user(envp,--sp);
        put_user(envp,--sp);
        put_user(argv,--sp);
        put_user(argv,--sp);
#endif
#endif
        put_user(argc,--sp);
        put_user(argc,--sp);
        current->mm->arg_start = (unsigned long) p;
        current->mm->arg_start = (unsigned long) p;
        while (argc-->0) {
        while (argc-->0) {
                put_user(p,argv++);
                put_user(p,argv++);
                while (get_user(p++)) /* nothing */ ;
                while (get_user(p++)) /* nothing */ ;
        }
        }
        put_user(NULL,argv);
        put_user(NULL,argv);
        current->mm->arg_end = current->mm->env_start = (unsigned long) p;
        current->mm->arg_end = current->mm->env_start = (unsigned long) p;
        while (envc-->0) {
        while (envc-->0) {
                put_user(p,envp++);
                put_user(p,envp++);
                while (get_user(p++)) /* nothing */ ;
                while (get_user(p++)) /* nothing */ ;
        }
        }
        put_user(NULL,envp);
        put_user(NULL,envp);
        current->mm->env_end = (unsigned long) p;
        current->mm->env_end = (unsigned long) p;
        return (unsigned long)sp;
        return (unsigned long)sp;
}
}
 
 
void do_reloc(struct flat_reloc * r)
void do_reloc(struct flat_reloc * r)
{
{
        unsigned long * ptr = (unsigned long*)
        unsigned long * ptr = (unsigned long*)
                (current->mm->start_data + r->offset);
                (current->mm->start_data + r->offset);
 
 
 
 
#ifdef DEBUG
#ifdef DEBUG
        printk("Relocation of variable at DATASEG+%x (address %p, currently %x) into segment %x+%x\n",
        printk("Relocation of variable at DATASEG+%x (address %p, currently %x) into segment %x+%x\n",
                r->offset, ptr, *ptr, r->type, *ptr);
                r->offset, ptr, *ptr, r->type, *ptr);
 
 
        printk("TEXTSEG=%x, DATASEG=%x, BSSSEG=%x\n",
        printk("TEXTSEG=%x, DATASEG=%x, BSSSEG=%x\n",
                current->mm->start_code,
                current->mm->start_code,
                current->mm->start_data,
                current->mm->start_data,
                current->mm->end_data);
                current->mm->end_data);
 
 
        printk("Relocation type = %d, offset = %d\n", r->type, r->offset);
        printk("Relocation type = %d, offset = %d\n", r->type, r->offset);
#endif
#endif
 
 
        switch (r->type) {
        switch (r->type) {
        case FLAT_RELOC_TYPE_TEXT:
        case FLAT_RELOC_TYPE_TEXT:
                *ptr += current->mm->start_code;
                *ptr += current->mm->start_code;
                break;
                break;
        case FLAT_RELOC_TYPE_DATA:
        case FLAT_RELOC_TYPE_DATA:
                *ptr += current->mm->start_data;
                *ptr += current->mm->start_data;
                break;
                break;
        case FLAT_RELOC_TYPE_BSS:
        case FLAT_RELOC_TYPE_BSS:
                *ptr += current->mm->end_data;
                *ptr += current->mm->end_data;
                break;
                break;
        default:
        default:
                printk("Unknown relocation\n");
                printk("Unknown relocation\n");
        }
        }
 
 
 
 
#ifdef DEBUG
#ifdef DEBUG
        printk("Relocation became %x\n", *ptr);
        printk("Relocation became %x\n", *ptr);
#endif
#endif
}
}
 
 
 
 
/*
/*
 * These are the functions used to load a.out style executables and shared
 * These are the functions used to load a.out style executables and shared
 * libraries.  There is no binary dependent code anywhere else.
 * libraries.  There is no binary dependent code anywhere else.
 */
 */
 
 
inline int
inline int
do_load_flat_binary(struct linux_binprm * bprm, struct pt_regs * regs)
do_load_flat_binary(struct linux_binprm * bprm, struct pt_regs * regs)
{
{
        struct flat_hdr * hdr;
        struct flat_hdr * hdr;
        struct file * file;
        struct file * file;
        unsigned long error;
        unsigned long error;
        unsigned long pos;
        unsigned long pos;
        unsigned long p = bprm->p;
        unsigned long p = bprm->p;
        unsigned long data_len, bss_len, stack_len, code_len;
        unsigned long data_len, bss_len, stack_len, code_len;
 
 
 
 
        current->personality = PER_LINUX;
        current->personality = PER_LINUX;
 
 
        file = current->files->fd[open_inode(bprm->inode, O_RDONLY)];
        file = current->files->fd[open_inode(bprm->inode, O_RDONLY)];
 
 
#ifdef DEBUG
#ifdef DEBUG
        printk("BINFMT_FLAT: Loading file: %x\n", file);
        printk("BINFMT_FLAT: Loading file: %x\n", file);
        show_free_areas();
        show_free_areas();
#endif
#endif
 
 
        hdr = (struct flat_hdr*)bprm->buf;
        hdr = (struct flat_hdr*)bprm->buf;
 
 
        if (strncmp(hdr->magic, "bFLT", 4) || (hdr->rev != 2)) {
        if (strncmp(hdr->magic, "bFLT", 4) || (hdr->rev != 2)) {
                printk("bad magic/rev (%ld, need %d)\n", hdr->rev, 2);
                printk("bad magic/rev (%ld, need %d)\n", hdr->rev, 2);
                return -ENOEXEC;
                return -ENOEXEC;
        }
        }
 
 
        if (flush_old_exec(bprm)) {
        if (flush_old_exec(bprm)) {
                printk("unable to flush\n");
                printk("unable to flush\n");
                return -ENOMEM;
                return -ENOMEM;
        }
        }
 
 
        /*printk("hdr->entry = %d, hdr->data_start = %d, hdr->data_end = %d, hdr->bss_end = %d, hdr->stack_size = %d\n",
        /*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->entry, hdr->data_start, hdr->data_end,
                hdr->bss_end, hdr->stack_size);*/
                hdr->bss_end, hdr->stack_size);*/
 
 
        /* OK, This is the point of no return */
        /* OK, This is the point of no return */
 
 
        code_len = hdr->data_start;
        code_len = hdr->data_start;
        data_len = hdr->data_end - hdr->data_start;
        data_len = hdr->data_end - hdr->data_start;
        bss_len = hdr->bss_end - hdr->data_end;
        bss_len = hdr->bss_end - hdr->data_end;
        stack_len = hdr->stack_size;
        stack_len = hdr->stack_size;
 
 
        /* Make room on stack for arguments & environment */
        /* Make room on stack for arguments & environment */
        stack_len += strlen(bprm->filename) + 1;
        stack_len += strlen(bprm->filename) + 1;
        stack_len += stringarraylen(bprm->envc, bprm->envp);
        stack_len += stringarraylen(bprm->envc, bprm->envp);
        stack_len += stringarraylen(bprm->argc, bprm->argv);
        stack_len += stringarraylen(bprm->argc, bprm->argv);
 
 
        /*stack_len += 4-((pos+data_len+bss_len+stack_len) & 3);*/ /* Align stack */
        /*stack_len += 4-((pos+data_len+bss_len+stack_len) & 3);*/ /* Align stack */
 
 
        /*printk("Stack = %d, (%d)\n", stack_len, stack_len & 3);*/
        /*printk("Stack = %d, (%d)\n", stack_len, stack_len & 3);*/
 
 
        error = do_mmap(file,
        error = do_mmap(file,
                0,
                0,
               code_len + data_len + bss_len + stack_len,
               code_len + data_len + bss_len + stack_len,
               PROT_READ|PROT_EXEC | ((hdr->flags & FLAT_FLAG_RAM) ? PROT_WRITE : 0),
               PROT_READ|PROT_EXEC | ((hdr->flags & FLAT_FLAG_RAM) ? PROT_WRITE : 0),
               0 /* MAP_* */,
               0 /* MAP_* */,
               0);
               0);
 
 
        if (error >= -4096) {
        if (error >= -4096) {
          printk("Unable to map flat executable, errno %d\n", (int)-error);
          printk("Unable to map flat executable, errno %d\n", (int)-error);
          return error; /* Beyond point of no return? Oh well... */
          return error; /* Beyond point of no return? Oh well... */
        }
        }
 
 
#ifdef DEBUG
#ifdef DEBUG
        printk("BINFMT_FLAT: mmap returned: %x\n", error);
        printk("BINFMT_FLAT: mmap returned: %x\n", error);
        show_free_areas();
        show_free_areas();
#endif
#endif
 
 
        current->mm->executable = 0;
        current->mm->executable = 0;
 
 
        if (is_in_rom(error)) {
        if (is_in_rom(error)) {
                unsigned long result;
                unsigned long result;
#ifdef DEBUG
#ifdef DEBUG
                printk("BINFMT_FLAT: ROM mapping of file\n");
                printk("BINFMT_FLAT: ROM mapping of file\n");
#endif
#endif
                /* do_mmap returned a ROM mapping, so allocate RAM for data + bss + stack */
                /* do_mmap returned a ROM mapping, so allocate RAM for data + bss + stack */
                /*pos = kmalloc(data_len+bss_len+stack_len, GFP_KERNEL);*/
                /*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);
                pos = do_mmap(0, 0, data_len+bss_len+stack_len, PROT_READ|PROT_WRITE|PROT_EXEC, 0, 0);
                if (pos >= (unsigned long)-4096) {
                if (pos >= (unsigned long)-4096) {
                        printk("Unable to allocate RAM for process, errno %d\n", (int)-pos);
                        printk("Unable to allocate RAM for process, errno %d\n", (int)-pos);
                        return pos;
                        return pos;
                }
                }
 
 
#ifdef DEBUG
#ifdef DEBUG
                printk("BINFMT_FLAT: Allocated data+bss+stack (%d bytes): %x\n", data_len+bss_len+stack_len, pos);
                printk("BINFMT_FLAT: Allocated data+bss+stack (%d bytes): %x\n", data_len+bss_len+stack_len, pos);
                show_free_areas();
                show_free_areas();
#endif
#endif
 
 
                /* And then fill it in */
                /* And then fill it in */
 
 
                /*printk("Reading data from %d-%d to %x\n", hdr->data_start, hdr->data_end - hdr->data_start, pos);*/
                /*printk("Reading data from %d-%d to %x\n", hdr->data_start, hdr->data_end - hdr->data_start, pos);*/
 
 
                result = read_exec(bprm->inode, hdr->data_start, (char *)pos,
                result = read_exec(bprm->inode, hdr->data_start, (char *)pos,
                          data_len, 0);
                          data_len, 0);
                if (result >= (unsigned long)-4096) {
                if (result >= (unsigned long)-4096) {
                          do_munmap(pos, 0);
                          do_munmap(pos, 0);
                          printk("Unable to read data+bss, errno %d\n", (int)-result);
                          printk("Unable to read data+bss, errno %d\n", (int)-result);
                }
                }
 
 
                /*printk("Clearing %x to %x\n", pos+data_len, pos+data_len+bss_len+stack_len);*/
                /*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);
                memset((void*)(pos + data_len), 0, bss_len + stack_len);
 
 
                if (bprm->inode->i_sb->s_flags & MS_SYNCHRONOUS) {
                if (bprm->inode->i_sb->s_flags & MS_SYNCHRONOUS) {
#ifdef DEBUG
#ifdef DEBUG
                        printk("Retaining inode\n");
                        printk("Retaining inode\n");
#endif
#endif
                        current->mm->executable = bprm->inode;
                        current->mm->executable = bprm->inode;
                        bprm->inode->i_count++;
                        bprm->inode->i_count++;
                }
                }
 
 
        } else {
        } else {
#ifdef DEBUG
#ifdef DEBUG
                printk("BINFMT_FLAT: RAM mapping of file\n");
                printk("BINFMT_FLAT: RAM mapping of file\n");
#endif
#endif
 
 
                /* Since we got a RAM mapping, mmap has already allocated a block for us, and
                /* Since we got a RAM mapping, mmap has already allocated a block for us, and
                   read in the data. . */
                   read in the data. . */
 
 
                pos = error + code_len;
                pos = error + code_len;
 
 
        }
        }
 
 
#ifdef DEBUG
#ifdef DEBUG
        printk("ROM mapping is %x, Entry point is %x, data_start is %x\n", error, hdr->entry, hdr->data_start);
        printk("ROM mapping is %x, Entry point is %x, data_start is %x\n", error, hdr->entry, hdr->data_start);
#endif
#endif
 
 
        current->mm->start_code = error + hdr->entry;
        current->mm->start_code = error + hdr->entry;
        current->mm->end_code = error + hdr->data_start;
        current->mm->end_code = error + hdr->data_start;
        current->mm->start_data = pos;
        current->mm->start_data = pos;
 
 
        current->mm->end_data = pos + data_len;
        current->mm->end_data = pos + data_len;
        current->mm->brk = pos + data_len + bss_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_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);*/
        printk("start_data: %x, end_data: %x\n", current->mm->start_data,current->mm->end_data);*/
 
 
        /*printk("Loaded flat file, BSS=%x, DATA=%x, TEXT=%x\n",
        /*printk("Loaded flat file, BSS=%x, DATA=%x, TEXT=%x\n",
                current->mm->end_data,
                current->mm->end_data,
                current->mm->start_data,
                current->mm->start_data,
                current->mm->start_code);*/
                current->mm->start_code);*/
 
 
        if (is_in_rom(error)) {
        if (is_in_rom(error)) {
                int r;
                int r;
                for(r=0;r<hdr->reloc_count;r++) {
                for(r=0;r<hdr->reloc_count;r++) {
                        struct flat_reloc * reloc = (struct flat_reloc*)
                        struct flat_reloc * reloc = (struct flat_reloc*)
                                (error + hdr->reloc_start + (sizeof(struct flat_reloc)*r));
                                (error + hdr->reloc_start + (sizeof(struct flat_reloc)*r));
                        do_reloc(reloc);
                        do_reloc(reloc);
                }
                }
        } else {
        } else {
                int r;
                int r;
                for(r=0;r<hdr->reloc_count;r++) {
                for(r=0;r<hdr->reloc_count;r++) {
                        struct flat_reloc reloc;
                        struct flat_reloc reloc;
                        unsigned long result = read_exec(bprm->inode,
                        unsigned long result = read_exec(bprm->inode,
                                hdr->reloc_start + (sizeof(struct flat_reloc)*r),
                                hdr->reloc_start + (sizeof(struct flat_reloc)*r),
                                (char *)&reloc,
                                (char *)&reloc,
                                sizeof(struct flat_reloc),
                                sizeof(struct flat_reloc),
                                0);
                                0);
                        if (result >= (unsigned long)-4096) {
                        if (result >= (unsigned long)-4096) {
                                printk("Failure reloading relocation\n");
                                printk("Failure reloading relocation\n");
                        } else
                        } else
                                do_reloc(&reloc);
                                do_reloc(&reloc);
                }
                }
        }
        }
 
 
        current->mm->rss = 0;
        current->mm->rss = 0;
        current->suid = current->euid = current->fsuid = bprm->e_uid;
        current->suid = current->euid = current->fsuid = bprm->e_uid;
        current->sgid = current->egid = current->fsgid = bprm->e_gid;
        current->sgid = current->egid = current->fsgid = bprm->e_gid;
        current->flags &= ~PF_FORKNOEXEC;
        current->flags &= ~PF_FORKNOEXEC;
 
 
 
 
 
 
        /*for(i=0;i<16;i++) {
        /*for(i=0;i<16;i++) {
                printk("%.2x ", ((char*)pos)[i] & 0xff);
                printk("%.2x ", ((char*)pos)[i] & 0xff);
        }
        }
        printk("\n");*/
        printk("\n");*/
 
 
 
 
 
 
        if (current->exec_domain && current->exec_domain->use_count)
        if (current->exec_domain && current->exec_domain->use_count)
                (*current->exec_domain->use_count)--;
                (*current->exec_domain->use_count)--;
        if (current->binfmt && current->binfmt->use_count)
        if (current->binfmt && current->binfmt->use_count)
                (*current->binfmt->use_count)--;
                (*current->binfmt->use_count)--;
        current->exec_domain = lookup_exec_domain(current->personality);
        current->exec_domain = lookup_exec_domain(current->personality);
        current->binfmt = &flat_format;
        current->binfmt = &flat_format;
        if (current->exec_domain && current->exec_domain->use_count)
        if (current->exec_domain && current->exec_domain->use_count)
                (*current->exec_domain->use_count)++;
                (*current->exec_domain->use_count)++;
        if (current->binfmt && current->binfmt->use_count)
        if (current->binfmt && current->binfmt->use_count)
                (*current->binfmt->use_count)++;
                (*current->binfmt->use_count)++;
 
 
        /*set_brk(current->mm->start_brk, current->mm->brk);*/
        /*set_brk(current->mm->start_brk, current->mm->brk);*/
 
 
        p = pos + data_len + bss_len + stack_len - 4;
        p = pos + data_len + bss_len + stack_len - 4;
 
 
#ifdef DEBUG
#ifdef DEBUG
        printk("p=%x\n", p);
        printk("p=%x\n", p);
#endif
#endif
 
 
        p = putstringarray(p, 1, &bprm->filename);
        p = putstringarray(p, 1, &bprm->filename);
 
 
#ifdef DEBUG
#ifdef DEBUG
        printk("p(filename)=%x\n", p);
        printk("p(filename)=%x\n", p);
#endif
#endif
 
 
        p = putstringarray(p, bprm->envc, bprm->envp);
        p = putstringarray(p, bprm->envc, bprm->envp);
 
 
#ifdef DEBUG
#ifdef DEBUG
        printk("p(envp)=%x\n", p);
        printk("p(envp)=%x\n", p);
#endif
#endif
 
 
        p = putstringarray(p, bprm->argc, bprm->argv);
        p = putstringarray(p, bprm->argc, bprm->argv);
 
 
#ifdef DEBUG
#ifdef DEBUG
        printk("p(argv)=%x\n", p);
        printk("p(argv)=%x\n", p);
#endif
#endif
 
 
        p = create_flat_tables(p, bprm);
        p = create_flat_tables(p, bprm);
 
 
#ifdef DEBUG
#ifdef DEBUG
        printk("p(create_flat_tables)=%x\n", p);
        printk("p(create_flat_tables)=%x\n", p);
 
 
        printk("arg_start = %x\n", current->mm->arg_start);
        printk("arg_start = %x\n", current->mm->arg_start);
        printk("arg_end = %x\n", current->mm->arg_end);
        printk("arg_end = %x\n", current->mm->arg_end);
        printk("env_start = %x\n", current->mm->env_start);
        printk("env_start = %x\n", current->mm->env_start);
        printk("env_end = %x\n", current->mm->env_end);
        printk("env_end = %x\n", current->mm->env_end);
#endif
#endif
 
 
        current->mm->start_stack = p;
        current->mm->start_stack = p;
 
 
        /*printk("start_stack: %x\n", current->mm->start_stack);*/
        /*printk("start_stack: %x\n", current->mm->start_stack);*/
 
 
        /*(*(volatile unsigned char *)0xdeadbee0) = 1;*/
        /*(*(volatile unsigned char *)0xdeadbee0) = 1;*/
 
 
#ifdef DEBUG    
#ifdef DEBUG    
        show_free_areas();
        show_free_areas();
#endif
#endif
 
 
        start_thread(regs, current->mm->start_code /*, current->mm->start_data*/ /*- hdr->data_start*/, p);
        start_thread(regs, current->mm->start_code /*, current->mm->start_data*/ /*- hdr->data_start*/, p);
 
 
        if (current->flags & PF_PTRACED)
        if (current->flags & PF_PTRACED)
                send_sig(SIGTRAP, current, 0);
                send_sig(SIGTRAP, current, 0);
        return 0;
        return 0;
}
}
 
 
static int
static int
load_flat_binary(struct linux_binprm * bprm, struct pt_regs * regs)
load_flat_binary(struct linux_binprm * bprm, struct pt_regs * regs)
{
{
        int retval;
        int retval;
 
 
        MOD_INC_USE_COUNT;
        MOD_INC_USE_COUNT;
        retval = do_load_flat_binary(bprm, regs);
        retval = do_load_flat_binary(bprm, regs);
        MOD_DEC_USE_COUNT;
        MOD_DEC_USE_COUNT;
        return retval;
        return retval;
}
}
 
 
int init_flat_binfmt(void) {
int init_flat_binfmt(void) {
        return register_binfmt(&flat_format);
        return register_binfmt(&flat_format);
}
}
 
 
#ifdef MODULE
#ifdef MODULE
int init_module(void) {
int init_module(void) {
        return init_flat_binfmt();
        return init_flat_binfmt();
}
}
 
 
void cleanup_module( void) {
void cleanup_module( void) {
        unregister_binfmt(&flat_format);
        unregister_binfmt(&flat_format);
}
}
#endif
#endif
 
 
 
 

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.