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

Subversion Repositories or1k

Compare Revisions

  • This comparison shows the changes necessary to convert path
    /
    from Rev 700 to Rev 701
    Reverse comparison

Rev 700 → Rev 701

/trunk/uclinux/uClinux-2.0.x/fs/binfmt_elf.c
115,6 → 115,17
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 rel_nb,
struct elf32_rel *rel_ptr,
212,15 → 223,15
{
struct elfhdr elf_ex;
struct file *file;
unsigned char ibcs2_interpreter;
int i,j;
int old_fs;
struct elf32_shdr *elf_spnt, *elf_shdata;
int elf_exec_fileno;
unsigned long elf_entry = 0;
int status;
unsigned long start_code, end_code, start_data, end_data, start_brk, brk;
unsigned long elf_stack;
unsigned long code_start, code_end, code_len = 0;
unsigned long data_start, data_end, data_len = 0;
unsigned long bss_start, bss_end, bss_len = 0;
unsigned long stack_len = 0;
int rel_indx, symtab_indx = 0, strtab_indx = 0;
struct elf32_rel *rel_ptr;
struct elf32_sym *sym_ptr = (struct elf32_sym *)0;
229,23 → 240,34
 
or32_consth_add = 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 */
 
if (elf_ex.e_ident[0] != 0x7f ||
strncmp(&elf_ex.e_ident[1], "ELF", 3) != 0) {
return -ENOEXEC;
}
 
/* First of all, some simple consistency checks */
if (elf_ex.e_type != ET_REL ||
(!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)) {
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) {
return -ENOEXEC;
}
 
if (flush_old_exec(bprm)) {
return -ENOMEM;
}
 
if(elf_ex.e_shnum > ELF_SECTION_NB)
return -ETOOMANYSECT;
 
253,39 → 275,20
sec[i].len = 0;
 
/* Now read in all of the header information */
elf_shdata = (struct elf32_shdr *) kmalloc(elf_ex.e_shnum *
elf_ex.e_shentsize, GFP_KERNEL);
 
elf_shdata = (struct elf32_shdr *) kmalloc(elf_ex.e_shnum *
elf_ex.e_shentsize, GFP_KERNEL);
if (elf_shdata == NULL) {
if (elf_shdata == NULL)
return -ENOMEM;
}
 
retval = read_exec(bprm->inode, elf_ex.e_shoff, (char *) elf_shdata,
elf_ex.e_shentsize * elf_ex.e_shnum, 1);
 
if (retval < 0) {
kfree(elf_shdata);
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 */
 
current->mm->end_data = 0;
298,72 → 301,96
old_fs = get_fs();
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++) {
if((elf_spnt->sh_flags & SHF_ALLOC)) {
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)
elf_prot |= PROT_EXEC;
if(elf_spnt->sh_type == SHT_PROGBITS) {
if(elf_spnt->sh_flags & SHF_EXECINSTR)
code_len += (elf_spnt->sh_size + 3) & ~(3);
else if(elf_spnt->sh_flags & SHF_ALLOC)
data_len += (elf_spnt->sh_size + 3) & ~(3);
}
else if(elf_spnt->sh_type == SHT_NOBITS) {
if(elf_spnt->sh_flags & SHF_ALLOC)
bss_len += (elf_spnt->sh_size + 3) & ~(3);
}
}
 
if(elf_spnt->sh_size == 0)
continue;
/* Allocate space */
retval = (unsigned long)do_mmap(NULL,
0,
code_len + code_len + bss_len + stack_len,
PROT_EXEC | PROT_WRITE | PROT_READ,
0,
0);
 
retval = (unsigned long)do_mmap(NULL,
0,
elf_spnt->sh_size,
elf_prot,
0,
0);
if(retval > (unsigned long)-4096) {
kfree(elf_shdata);
return retval;
}
 
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);
code_start = retval;
code_end = code_start;
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) {
 
retval = read_exec(bprm->inode, elf_spnt->sh_offset,
(char *)code_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;
return retval;
}
sec[i].pm_add = code_end;
sec[i].vm_add = elf_spnt->sh_addr;
 
sec[i].pm_add = retval;
code_end = code_end + ((elf_spnt->sh_size + 3) & ~(3));
}
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;
}
sec[i].pm_add = data_end;
sec[i].vm_add = elf_spnt->sh_addr;
sec[i].len = elf_spnt->sh_size;
if(elf_spnt->sh_type == SHT_PROGBITS) {
retval = read_exec(bprm->inode, elf_spnt->sh_offset,
(char *)retval, elf_spnt->sh_size, 1);
if (retval < 0) {
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);
return retval;
}
}
 
if(elf_spnt->sh_type == SHT_PROGBITS) {
if(elf_spnt->sh_flags & SHF_EXECINSTR) {
if(sec[i].pm_add < start_code)
start_code = sec[i].pm_add;
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_NOBITS) {
if(sec[i].pm_add < start_brk)
start_brk = sec[i].pm_add;
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++) {
if(elf_spnt->sh_type == SHT_SYMTAB && (elf_spnt->sh_size != 0)) {
struct elf32_shdr *link_shdr;
381,6 → 408,7
for(j = 0; j < elf_ex.e_shnum; j++)
if(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);
return retval;
}
396,6 → 424,7
for(j = 0; j < elf_ex.e_shnum; j++)
if(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);
return retval;
}
414,8 → 443,9
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);
return retval;
do_munmap(code_start, code_len + code_len + bss_len + stack_len);
kfree(elf_shdata);
return retval;
}
sec[strtab_indx].pm_add = retval;
428,6 → 458,7
for(j = 0; j < elf_ex.e_shnum; j++)
if(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);
return retval;
}
456,8 → 487,9
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);
return retval;
do_munmap(code_start, code_len + code_len + bss_len + stack_len);
kfree(elf_shdata);
return retval;
}
sec[i].pm_add = retval;
470,12 → 502,12
for(j = 0; j < elf_ex.e_shnum; j++)
if(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);
return retval;
}
rel_indx = i;
symtab_indx = elf_spnt->sh_link;
link_shdr = elf_shdata + symtab_indx;
 
/* Now do relocations for the n-th section. n is read from
488,6 → 520,7
for(j = 0; j < elf_ex.e_shnum; j++)
if(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);
return retval;
}
507,10 → 540,6
set_fs(old_fs);
kfree(elf_shdata);
 
sys_close(elf_exec_fileno);
 
current->personality = PER_LINUX;
 
if (current->exec_domain && current->exec_domain->use_count)
(*current->exec_domain->use_count)--;
if (current->binfmt && current->binfmt->use_count)
522,7 → 551,7
if (current->binfmt && 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);
 
535,23 → 564,26
current->flags &= ~PF_FORKNOEXEC;
bprm->p = (unsigned long)create_elf_tables((char *) bprm->p, bprm->argc, bprm->envc, regs);
 
current->mm->start_brk = start_brk;
current->mm->brk = brk;
current->mm->start_code = start_code;
current->mm->end_code = end_code;
current->mm->start_data = start_data;
current->mm->end_data = end_data;
current->mm->brk = bss_end;
current->mm->start_code = code_start;
current->mm->end_code = code_end;
current->mm->start_data = data_start;
current->mm->end_data = data_end;
current->mm->start_stack = bprm->p;
 
if(start_brk != ~0UL) {
int nbyte = brk - start_brk;
char *fpnt = (char *)brk;
_print("%s - %s:%d\n",__FILE__,__FUNCTION__,__LINE__);
_print(" start_code = %x\n", current->mm->start_code);
_print(" end_code = %x\n", current->mm->end_code);
_print(" start_data = %x\n", current->mm->start_data);
_print(" end_data = %x\n", current->mm->end_data);
_print(" start_brk = %x\n", current->mm->start_brk);
_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);
 
do {
put_user(0, fpnt++);
} while (--nbyte);
}
 
start_thread(regs, elf_entry, bprm->p);
 
if (current->flags & PF_PTRACED)

powered by: WebSVN 2.1.0

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