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

Subversion Repositories or1k_old

[/] [or1k_old/] [trunk/] [uclinux/] [uClinux-2.0.x/] [fs/] [binfmt_elf.c] - Diff between revs 625 and 701

Go to most recent revision | Show entire file | Details | Blame | View Log

Rev 625 Rev 701
Line 113... Line 113...
                p=putstring(p, array[--count]);
                p=putstring(p, array[--count]);
        }
        }
        return p;
        return p;
}
}
 
 
 
static unsigned long stringarraylen(int count, char ** array)
 
{
 
        int l = 4;
 
        while(count) {
 
                l += strlen(array[--count]);
 
                l++;
 
                l+=4;
 
        }
 
        return l;
 
}
 
 
int do_relocate(int dst_indx,
int do_relocate(int dst_indx,
                int rel_nb,
                int rel_nb,
                struct elf32_rel *rel_ptr,
                struct elf32_rel *rel_ptr,
                struct elf32_sym *sym_ptr,
                struct elf32_sym *sym_ptr,
                struct sec_add *sec)
                struct sec_add *sec)
Line 210... Line 221...
 
 
static inline int do_load_elf_binary(struct linux_binprm *bprm, struct pt_regs *regs)
static inline int do_load_elf_binary(struct linux_binprm *bprm, struct pt_regs *regs)
{
{
        struct elfhdr elf_ex;
        struct elfhdr elf_ex;
        struct file *file;
        struct file *file;
        unsigned char ibcs2_interpreter;
 
        int i,j;
        int i,j;
        int old_fs;
        int old_fs;
        struct elf32_shdr *elf_spnt, *elf_shdata;
        struct elf32_shdr *elf_spnt, *elf_shdata;
        int elf_exec_fileno;
        int elf_exec_fileno;
        unsigned long elf_entry = 0;
        unsigned long elf_entry = 0;
        int status;
        unsigned long code_start, code_end, code_len = 0;
        unsigned long start_code, end_code, start_data, end_data, start_brk, brk;
        unsigned long data_start, data_end, data_len = 0;
        unsigned long elf_stack;
        unsigned long bss_start, bss_end, bss_len = 0;
 
        unsigned long stack_len = 0;
        int rel_indx, symtab_indx = 0, strtab_indx = 0;
        int rel_indx, symtab_indx = 0, strtab_indx = 0;
        struct elf32_rel *rel_ptr;
        struct elf32_rel *rel_ptr;
        struct elf32_sym *sym_ptr = (struct elf32_sym *)0;
        struct elf32_sym *sym_ptr = (struct elf32_sym *)0;
        char *str_ptr = (char *)0;
        char *str_ptr = (char *)0;
        int retval;
        int retval;
 
 
        or32_consth_add = 0;
        or32_consth_add = 0;
        or32_consth_rel = 0;
        or32_consth_rel = 0;
        ibcs2_interpreter = 0;
 
        status = 0;
        current->personality = PER_LINUX;
 
 
 
        elf_exec_fileno = open_inode(bprm->inode, O_RDONLY);
 
 
 
        if (elf_exec_fileno < 0)
 
                return elf_exec_fileno;
 
 
 
        file = current->files->fd[elf_exec_fileno];
 
 
 
 
        elf_ex = *((struct elfhdr *) bprm->buf);        /* exec-header */
        elf_ex = *((struct elfhdr *) bprm->buf);        /* exec-header */
 
 
        if (elf_ex.e_ident[0] != 0x7f ||
        /* First of all, some simple consistency checks */
 
        if (elf_ex.e_type != ET_REL ||
 
                        0 /*!elf_check_arch(elf_ex.e_machine)*/ ||
 
                        !bprm->inode->i_op ||
 
                        !bprm->inode->i_op->default_file_ops ||
 
                        !bprm->inode->i_op->default_file_ops->mmap ||
 
                        elf_ex.e_ident[0] != 0x7f ||
            strncmp(&elf_ex.e_ident[1], "ELF", 3) != 0) {
            strncmp(&elf_ex.e_ident[1], "ELF", 3) != 0) {
                return -ENOEXEC;
                return -ENOEXEC;
        }
        }
 
 
        /* First of all, some simple consistency checks */
        if (flush_old_exec(bprm)) {
        if (elf_ex.e_type != ET_REL ||
                return -ENOMEM;
            (!elf_check_arch(elf_ex.e_machine)) ||
 
            (!bprm->inode->i_op || !bprm->inode->i_op->default_file_ops ||
 
             !bprm->inode->i_op->default_file_ops->mmap)) {
 
                return -ENOEXEC;
 
        }
        }
 
 
        if(elf_ex.e_shnum > ELF_SECTION_NB)
        if(elf_ex.e_shnum > ELF_SECTION_NB)
                return -ETOOMANYSECT;
                return -ETOOMANYSECT;
 
 
        for(i = 0; i < ELF_SECTION_NB; i++)
        for(i = 0; i < ELF_SECTION_NB; i++)
                sec[i].len = 0;
                sec[i].len = 0;
 
 
        /* Now read in all of the header information */
        /* Now read in all of the header information */
 
 
        elf_shdata = (struct elf32_shdr *) kmalloc(elf_ex.e_shnum *
        elf_shdata = (struct elf32_shdr *) kmalloc(elf_ex.e_shnum *
                                             elf_ex.e_shentsize, GFP_KERNEL);
                                             elf_ex.e_shentsize, GFP_KERNEL);
        if (elf_shdata == NULL) {
 
 
        if (elf_shdata == NULL)
                return -ENOMEM;
                return -ENOMEM;
        }
 
        retval = read_exec(bprm->inode, elf_ex.e_shoff, (char *) elf_shdata,
        retval = read_exec(bprm->inode, elf_ex.e_shoff, (char *) elf_shdata,
                           elf_ex.e_shentsize * elf_ex.e_shnum, 1);
                           elf_ex.e_shentsize * elf_ex.e_shnum, 1);
 
 
        if (retval < 0) {
        if (retval < 0) {
                kfree(elf_shdata);
                kfree(elf_shdata);
                return retval;
                return retval;
        }
        }
 
 
        elf_exec_fileno = open_inode(bprm->inode, O_RDONLY);
 
 
 
        if (elf_exec_fileno < 0) {
 
                kfree(elf_shdata);
 
                return elf_exec_fileno;
 
        }
 
        file = current->files->fd[elf_exec_fileno];
 
 
 
        elf_stack = ~0UL;
 
        start_code = ~0UL;
 
        end_code = 0;
 
        start_data = ~0UL;
 
        end_data = 0;
 
        start_brk = ~0UL;
 
        brk = 0;
 
 
 
        if (flush_old_exec(bprm)) {
 
                return -ENOMEM;
 
        }
 
 
 
        /* OK, This is the point of no return */
        /* OK, This is the point of no return */
 
 
        current->mm->end_data = 0;
        current->mm->end_data = 0;
        current->mm->end_code = 0;
        current->mm->end_code = 0;
 
 
Line 296... Line 299...
           address. */
           address. */
 
 
        old_fs = get_fs();
        old_fs = get_fs();
        set_fs(get_ds());
        set_fs(get_ds());
 
 
 
        /* Calculate the total size of memory needed */
        for(i = 0, elf_spnt = elf_shdata; i < elf_ex.e_shnum; i++, elf_spnt++) {
        for(i = 0, elf_spnt = elf_shdata; i < elf_ex.e_shnum; i++, elf_spnt++) {
                if((elf_spnt->sh_flags & SHF_ALLOC)) {
                if(elf_spnt->sh_type == SHT_PROGBITS) {
                        int elf_prot = PROT_READ;
 
                        unsigned long retval;
 
                        if (elf_spnt->sh_flags & SHF_WRITE)
 
                                elf_prot |= PROT_WRITE;
 
                        if (elf_spnt->sh_flags & SHF_EXECINSTR)
                        if (elf_spnt->sh_flags & SHF_EXECINSTR)
                                elf_prot |= PROT_EXEC;
                                code_len += (elf_spnt->sh_size + 3) & ~(3);
 
                        else if(elf_spnt->sh_flags & SHF_ALLOC)
                        if(elf_spnt->sh_size == 0)
                                data_len += (elf_spnt->sh_size + 3) & ~(3);
                                continue;
                }
 
                else if(elf_spnt->sh_type == SHT_NOBITS) {
 
                        if(elf_spnt->sh_flags & SHF_ALLOC)
 
                                bss_len += (elf_spnt->sh_size + 3) & ~(3);
 
                }
 
        }
 
 
 
        /* Allocate space */
                        retval = (unsigned long)do_mmap(NULL,
                        retval = (unsigned long)do_mmap(NULL,
                                                0,
                                                0,
                                                elf_spnt->sh_size,
                                        code_len + code_len + bss_len + stack_len,
                                                elf_prot,
                                        PROT_EXEC | PROT_WRITE | PROT_READ,
                                                0,
                                                0,
                                                0);
                                                0);
 
 
                        if(retval > (unsigned long)-4096) {
                        if(retval > (unsigned long)-4096) {
                                for(j = 0; j < elf_ex.e_shnum; j++)
 
                                        if(sec[j].len)
 
                                                do_munmap(sec[j].pm_add, sec[j].len);
 
                                kfree(elf_shdata);
                                kfree(elf_shdata);
                                return retval;
                                return retval;
                        }
                        }
 
 
                        sec[i].pm_add = retval;
        code_start = retval;
                        sec[i].vm_add = elf_spnt->sh_addr;
        code_end = code_start;
                        sec[i].len = elf_spnt->sh_size;
        data_start = code_start + code_len;
 
        data_end = data_start;
 
        bss_start = data_start + data_len;
 
        bss_end = bss_start;
 
        stack_len = 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);
 
 
 
        current->mm->executable = 0;
 
 
 
        /* Now copy sections in memory */
 
 
 
        for(i = 0, elf_spnt = elf_shdata; i < elf_ex.e_shnum; i++, elf_spnt++) {
 
 
 
                if(elf_spnt->sh_type == SHT_PROGBITS && elf_spnt->sh_flags & SHF_EXECINSTR) {
 
 
                        if(elf_spnt->sh_type == SHT_PROGBITS) {
 
                                retval = read_exec(bprm->inode, elf_spnt->sh_offset,
                                retval = read_exec(bprm->inode, elf_spnt->sh_offset,
                                                (char *)retval, elf_spnt->sh_size, 1);
                                        (char *)code_end, elf_spnt->sh_size, 1);
 
 
                                if (retval < 0) {
                                if (retval < 0) {
                                        for(j = 0; j < elf_ex.e_shnum; j++)
                                do_munmap(code_start, code_len + code_len + bss_len + stack_len);
                                                if(sec[j].len)
 
                                                        do_munmap(sec[j].pm_add, sec[j].len);
 
                                        kfree(elf_shdata);
                                        kfree(elf_shdata);
                                        return retval;
                                        return retval;
                                }
                                }
                        }
 
 
 
                        if(elf_spnt->sh_type == SHT_PROGBITS) {
                        sec[i].pm_add = code_end;
                                if(elf_spnt->sh_flags & SHF_EXECINSTR) {
                        sec[i].vm_add = elf_spnt->sh_addr;
                                        if(sec[i].pm_add < start_code)
 
                                                start_code = sec[i].pm_add;
                        code_end = code_end + ((elf_spnt->sh_size + 3) & ~(3));
                                        if((sec[i].pm_add + elf_spnt->sh_size) > end_code)
 
                                                end_code = sec[i].pm_add + elf_spnt->sh_size;
 
                                }
 
                                else {
 
                                        if(sec[i].pm_add < start_data)
 
                                                start_data = sec[i].pm_add;
 
                                        if((sec[i].pm_add + elf_spnt->sh_size) > end_data)
 
                                                end_data = sec[i].pm_add + elf_spnt->sh_size;
 
                                }
                                }
 
                else if (elf_spnt->sh_type == SHT_PROGBITS && elf_spnt->sh_flags & SHF_ALLOC) {
 
 
 
                        retval = read_exec(bprm->inode, elf_spnt->sh_offset,
 
                                        (char *)data_end, elf_spnt->sh_size, 1);
 
 
 
                        if (retval < 0) {
 
                                do_munmap(code_start, code_len + code_len + bss_len + stack_len);
 
                                kfree(elf_shdata);
 
                                return retval;
                        }
                        }
                        else if(elf_spnt->sh_type == SHT_NOBITS) {
 
                                if(sec[i].pm_add < start_brk)
                        sec[i].pm_add = data_end;
                                        start_brk = sec[i].pm_add;
                        sec[i].vm_add = elf_spnt->sh_addr;
                                if((sec[i].pm_add + elf_spnt->sh_size) > brk)
 
                                        brk = sec[i].pm_add + elf_spnt->sh_size;
                        data_end = data_end + ((elf_spnt->sh_size + 3) & ~(3));
                        }
                        }
 
                else if (elf_spnt->sh_type == SHT_NOBITS && elf_spnt->sh_flags & SHF_ALLOC) {
 
 
 
                        sec[i].pm_add = bss_end;
 
                        sec[i].vm_add = elf_spnt->sh_addr;
 
 
 
                        bss_end = bss_end + ((elf_spnt->sh_size + 3) & ~(3));
                }
                }
        }
        }
 
 
 
        /* Set bss and stack to zero */
 
        memset((void*)(bss_start), 0, bss_len + stack_len);
 
 
        for(i = 0, elf_spnt = elf_shdata; i < elf_ex.e_shnum; elf_spnt++, i++) {
        for(i = 0, elf_spnt = elf_shdata; i < elf_ex.e_shnum; elf_spnt++, i++) {
                if(elf_spnt->sh_type == SHT_SYMTAB && (elf_spnt->sh_size != 0)) {
                if(elf_spnt->sh_type == SHT_SYMTAB && (elf_spnt->sh_size != 0)) {
                        struct elf32_shdr *link_shdr;
                        struct elf32_shdr *link_shdr;
                        int sym_nb;
                        int sym_nb;
                        unsigned long retval;
                        unsigned long retval;
Line 379... Line 406...
                                                        0);
                                                        0);
                        if(retval > (unsigned long)-4096) {
                        if(retval > (unsigned long)-4096) {
                                for(j = 0; j < elf_ex.e_shnum; j++)
                                for(j = 0; j < elf_ex.e_shnum; j++)
                                                if(sec[j].len)
                                                if(sec[j].len)
                                                        do_munmap(sec[j].pm_add, sec[j].len);
                                                        do_munmap(sec[j].pm_add, sec[j].len);
 
                                do_munmap(code_start, code_len + code_len + bss_len + stack_len);
                                kfree(elf_shdata);
                                kfree(elf_shdata);
                                return retval;
                                return retval;
                        }
                        }
 
 
                        symtab_indx = i;
                        symtab_indx = i;
Line 394... Line 422...
                                        (char *)retval, elf_spnt->sh_size, 1);
                                        (char *)retval, elf_spnt->sh_size, 1);
                        if (retval < 0) {
                        if (retval < 0) {
                                for(j = 0; j < elf_ex.e_shnum; j++)
                                for(j = 0; j < elf_ex.e_shnum; j++)
                                        if(sec[j].len)
                                        if(sec[j].len)
                                                do_munmap(sec[j].pm_add, sec[j].len);
                                                do_munmap(sec[j].pm_add, sec[j].len);
 
                                do_munmap(code_start, code_len + code_len + bss_len + stack_len);
                                kfree(elf_shdata);
                                kfree(elf_shdata);
                                return retval;
                                return retval;
                        }
                        }
 
 
                        strtab_indx = elf_spnt->sh_link;
                        strtab_indx = elf_spnt->sh_link;
Line 412... Line 441...
                                                        0);
                                                        0);
                        if(retval > (unsigned long)-4096) {
                        if(retval > (unsigned long)-4096) {
                                for(j = 0; j < elf_ex.e_shnum; j++)
                                for(j = 0; j < elf_ex.e_shnum; j++)
                                        if(sec[j].len)
                                        if(sec[j].len)
                                                do_munmap(sec[j].pm_add, sec[j].len);
                                                do_munmap(sec[j].pm_add, sec[j].len);
 
                                do_munmap(code_start, code_len + code_len + bss_len + stack_len);
                        kfree(elf_shdata);
                        kfree(elf_shdata);
                        return retval;
                        return retval;
                        }
                        }
 
 
                        sec[strtab_indx].pm_add = retval;
                        sec[strtab_indx].pm_add = retval;
Line 426... Line 456...
                                        (char *)retval, link_shdr->sh_size, 1);
                                        (char *)retval, link_shdr->sh_size, 1);
                        if (retval < 0) {
                        if (retval < 0) {
                                for(j = 0; j < elf_ex.e_shnum; j++)
                                for(j = 0; j < elf_ex.e_shnum; j++)
                                        if(sec[j].len)
                                        if(sec[j].len)
                                                do_munmap(sec[j].pm_add, sec[j].len);
                                                do_munmap(sec[j].pm_add, sec[j].len);
 
                                do_munmap(code_start, code_len + code_len + bss_len + stack_len);
                                kfree(elf_shdata);
                                kfree(elf_shdata);
                                return retval;
                                return retval;
                        }
                        }
 
 
                        sym_nb = sec[symtab_indx].len / sizeof(struct elf32_sym);
                        sym_nb = sec[symtab_indx].len / sizeof(struct elf32_sym);
Line 454... Line 485...
                                                        0);
                                                        0);
                        if(retval > (unsigned long)-4096) {
                        if(retval > (unsigned long)-4096) {
                                for(j = 0; j < elf_ex.e_shnum; j++)
                                for(j = 0; j < elf_ex.e_shnum; j++)
                                        if(sec[j].len)
                                        if(sec[j].len)
                                                do_munmap(sec[j].pm_add, sec[j].len);
                                                do_munmap(sec[j].pm_add, sec[j].len);
 
                                do_munmap(code_start, code_len + code_len + bss_len + stack_len);
                        kfree(elf_shdata);
                        kfree(elf_shdata);
                        return retval;
                        return retval;
                        }
                        }
 
 
                        sec[i].pm_add = retval;
                        sec[i].pm_add = retval;
Line 468... Line 500...
                                        (char *)retval, elf_spnt->sh_size, 1);
                                        (char *)retval, elf_spnt->sh_size, 1);
                        if (retval < 0) {
                        if (retval < 0) {
                                for(j = 0; j < elf_ex.e_shnum; j++)
                                for(j = 0; j < elf_ex.e_shnum; j++)
                                        if(sec[j].len)
                                        if(sec[j].len)
                                                do_munmap(sec[j].pm_add, sec[j].len);
                                                do_munmap(sec[j].pm_add, sec[j].len);
 
                                do_munmap(code_start, code_len + code_len + bss_len + stack_len);
                                kfree(elf_shdata);
                                kfree(elf_shdata);
                                return retval;
                                return retval;
                        }
                        }
 
 
                        rel_indx = i;
                        rel_indx = i;
                        symtab_indx = elf_spnt->sh_link;
 
                        link_shdr = elf_shdata + symtab_indx;
                        link_shdr = elf_shdata + symtab_indx;
 
 
                        /* Now do relocations for the n-th section. n is read from
                        /* Now do relocations for the n-th section. n is read from
                           real setiona hader info field. */
                           real setiona hader info field. */
 
 
Line 486... Line 518...
 
 
                        if (retval < 0) {
                        if (retval < 0) {
                                for(j = 0; j < elf_ex.e_shnum; j++)
                                for(j = 0; j < elf_ex.e_shnum; j++)
                                        if(sec[j].len)
                                        if(sec[j].len)
                                                do_munmap(sec[j].pm_add, sec[j].len);
                                                do_munmap(sec[j].pm_add, sec[j].len);
 
                                do_munmap(code_start, code_len + code_len + bss_len + stack_len);
                                kfree(elf_shdata);
                                kfree(elf_shdata);
                                return retval;
                                return retval;
                        }
                        }
 
 
                        /* Now unmap rel section */
                        /* Now unmap rel section */
Line 505... Line 538...
        sec[strtab_indx].len = 0;
        sec[strtab_indx].len = 0;
 
 
        set_fs(old_fs);
        set_fs(old_fs);
        kfree(elf_shdata);
        kfree(elf_shdata);
 
 
        sys_close(elf_exec_fileno);
 
 
 
        current->personality = PER_LINUX;
 
 
 
        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);
Line 520... Line 549...
        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)++;
 
 
        bprm->p = do_mmap(0, 0, STACK_SIZE, PROT_READ|PROT_WRITE, 0, 0) + STACK_SIZE;
        bprm->p = bss_end + stack_len - 4;
 
 
        bprm->p = putstringarray(bprm->p, 1, &bprm->filename);
        bprm->p = putstringarray(bprm->p, 1, &bprm->filename);
 
 
        bprm->p = putstringarray(bprm->p, bprm->envc, bprm->envp);
        bprm->p = putstringarray(bprm->p, bprm->envc, bprm->envp);
 
 
Line 533... Line 562...
        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;
        bprm->p = (unsigned long)create_elf_tables((char *) bprm->p, bprm->argc, bprm->envc, regs);
        bprm->p = (unsigned long)create_elf_tables((char *) bprm->p, bprm->argc, bprm->envc, regs);
 
 
        current->mm->start_brk = start_brk;
        current->mm->brk = bss_end;
        current->mm->brk = brk;
        current->mm->start_code  = code_start;
        current->mm->start_code  = start_code;
        current->mm->end_code = code_end;
        current->mm->end_code = end_code;
        current->mm->start_data  = data_start;
        current->mm->start_data  = start_data;
        current->mm->end_data = data_end;
        current->mm->end_data = end_data;
 
        current->mm->start_stack = bprm->p;
        current->mm->start_stack = bprm->p;
 
 
        if(start_brk != ~0UL) {
_print("%s - %s:%d\n",__FILE__,__FUNCTION__,__LINE__);
                int nbyte = brk - start_brk;
_print("   start_code = %x\n", current->mm->start_code);
                char *fpnt = (char *)brk;
_print("   end_code = %x\n", current->mm->end_code);
 
_print("   start_data = %x\n", current->mm->start_data);
                do {
_print("   end_data = %x\n", current->mm->end_data);
                        put_user(0, fpnt++);
_print("   start_brk = %x\n", current->mm->start_brk);
                } while (--nbyte);
_print("   brk = %x\n", current->mm->brk);
        }
_print("   start_stack = %x\n", current->mm->start_stack);
 
_print("   arg_start = %x\n", current->mm->arg_start);
 
_print("   env_start = %x\n", current->mm->env_start);
 
_print("   env_end = %x\n", current->mm->env_end);
 
_print("   elf_entry = %x\n", elf_entry);
 
 
        start_thread(regs, elf_entry, bprm->p);
        start_thread(regs, elf_entry, bprm->p);
 
 
        if (current->flags & PF_PTRACED)
        if (current->flags & PF_PTRACED)
                send_sig(SIGTRAP, current, 0);
                send_sig(SIGTRAP, current, 0);

powered by: WebSVN 2.1.0

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