/arch/i386/power/

main'>index : litmus-rt.git
The LITMUS^RT kernel.Bjoern Brandenburg
aboutsummaryrefslogblamecommitdiffstats
path: root/fs/binfmt_elf.c
blob: 4482a0673b1591869c63358a1db6a21582848252 (plain) (tree)
































                                                                             





                           
                      
                          



                        

                                                                            
                                                                                         
 



                                                             
                                                          
                                                                              




                                 
                                         
     
                                 














                                                                             

                                                    

  
                                                     
















                                                          


                                                  

               

















                                                                           


                                                                         







                                                                  
                                                                 














                                                         
                                   






                                                                         








                                                                              
 







                                                                      
                                                         
                              
              

                                             
                   











                                                                             
                                                       



                                               




                                                               
                         
                                        
                                                                   

                                                       
                                                          





















                                                                               
                                                              



                                          








                                                                           





                                                                              


                                                                        





                                       
                                                          

                            

                                                      

                                                                     







                                                          

                                                      

                                                                     
















                                                                      
                                                           

                               
                                                                  
 
                                           

                                                                 





                                                                            










                                                                        
                                                                  
                                                                          




























                                                                          


                                                                
                                               


                         

                                                                 







                                        

















                                                                              
                                                                      















                                                                                
                                          






















                                                                              












                                                                     

                                                             









                                                            

                                                                    






                          

                                                             

















                                                          
                                                            














                                                                               


















                                                                        
                      
                                                                       
      




                                                                 

                                                              


                                                                    
                           
                                                       
     
                                                       


      
                                                                           







                                                             
                                               



                                       
                                                      



                                                                 
                                               













                                                
                                                    













                                                                          






                                                                       
                                               


                         

                                                             





                                      
                                                      









                                                                     




















                                                                      





                                                             
                                                                     
                                                              



                                                                            

                                                                 










































                                                                                








                                                                                   

                                                                       






                                                        

                                                                           













                                                                     



































                                                                                   


















                                                                         




                                                








                                                                          
                                                                              




                                                                            
                                                              
                                          






                                                                      


                                                                       


                                                                         

                                                       


























                                                                               
                                                                             





                                                                          





                                               
 
                                                                         




                                                                     



                                                                              
                                                                           

                 
                                                                        
                                                     

                                                      

                                                                













                                                                              



                                       





                                                                       
                                                                            

                                                        
                                                                      
                                                      
                                         

































                                                                   
                                                                       





                                                                      
                                                         

                                                                     
                    

                                                                        
                                                                       
                                          
                                                    

                                                                 








                                                   
                                          

                                                    

                                             








                                                 



                                                                     
                         


                                            

                                         
                                                      

                                                                 



                                              












                                                                            
                                                      






































                                                                             
                               


                                   

                                                   






                                                                  








                                              
                                                                       







                                                             
                                                                         














































                                                                     

                                                              

















                                                                    
                                                          















                                                                         
                                                   
 
                                                                    
                                                                
                                 













                                                                









                                                                   
                                                                      
 



                                                                    



                                                                






                                                                              
 
                                                                           
                           
                                                                    
 
                                                          

 



















                                               

                                                                                        
 
                                                        
 
                                          


                                                                  
 



                                                               



                                            






                                                    



                 







                                                                        
                                                         























                                                         
                                                                            






















                                                                           

                                                                        

                                                        
                                                  






                                                                 
                                              

























                                                                           
                            

















                                                                    
                                            


                                              
                                                       

























                                                                           

                                                                           









                                                                          

                                                                         


                                     



                                                                            





                                                      

                                                                              






                                             

























                                                                               






                                                                       
                                                                             






                           
                                              
                                  
                                            













                                                                          
                               


                                 



                                               


                                                                              

                                                                              
                                                                              


























                                                                              
                                

                                                                   
                                                                        
                                           
                                                          

                                                     



                                                                   
                                  


















                                                                            



                                         
                           
                                                                     








                                                                   
                                                                               
                                                                
                                                                           
        
                    
 
                                                     





                                                     
                                                

                                  

                                                            












                                                                        

                                                                             










                                                  
                                 

                                                             

      




                                                      

                                                              






                                                                             
                                                     

                                                             








                                                 
                                                                


                                                                  



                                             










                                                 
                                                          

                                          

                                   
                                    

      

                                                       


                                                                              
                                                    
                                                                       

                                                  


                                     
 

                                                             

                                   
                                            




                                          
                                          



                                                                               
                                                     

                                                              



                                                                          

                                                    

                                                                            


















                                                                          



                   
                                           
































                                                                       
/*
 * linux/fs/binfmt_elf.c
 *
 * These are the functions used to load ELF format executables as used
 * on SVr4 machines.  Information on the format may be found in the book
 * "UNIX SYSTEM V RELEASE 4 Programmers Guide: Ansi C and Programming Support
 * Tools".
 *
 * Copyright 1993, 1994: Eric Youngdale (ericy@cais.com).
 */

#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/fs.h>
#include <linux/stat.h>
#include <linux/time.h>
#include <linux/mm.h>
#include <linux/mman.h>
#include <linux/a.out.h>
#include <linux/errno.h>
#include <linux/signal.h>
#include <linux/binfmts.h>
#include <linux/string.h>
#include <linux/file.h>
#include <linux/fcntl.h>
#include <linux/ptrace.h>
#include <linux/slab.h>
#include <linux/shm.h>
#include <linux/personality.h>
#include <linux/elfcore.h>
#include <linux/init.h>
#include <linux/highuid.h>
#include <linux/smp.h>
#include <linux/compiler.h>
#include <linux/highmem.h>
#include <linux/pagemap.h>
#include <linux/security.h>
#include <linux/syscalls.h>
#include <linux/random.h>
#include <linux/elf.h>
#include <linux/utsname.h>
#include <asm/uaccess.h>
#include <asm/param.h>
#include <asm/page.h>

static int load_elf_binary(struct linux_binprm *bprm, struct pt_regs *regs);
static int load_elf_library(struct file *);
static unsigned long elf_map (struct file *, unsigned long, struct elf_phdr *, int, int);

/*
 * If we don't support core dumping, then supply a NULL so we
 * don't even try.
 */
#if defined(USE_ELF_CORE_DUMP) && defined(CONFIG_ELF_CORE)
static int elf_core_dump(long signr, struct pt_regs *regs, struct file *file);
#else
#define elf_core_dump	NULL
#endif

#if ELF_EXEC_PAGESIZE > PAGE_SIZE
#define ELF_MIN_ALIGN	ELF_EXEC_PAGESIZE
#else
#define ELF_MIN_ALIGN	PAGE_SIZE
#endif

#ifndef ELF_CORE_EFLAGS
#define ELF_CORE_EFLAGS	0
#endif

#define ELF_PAGESTART(_v) ((_v) & ~(unsigned long)(ELF_MIN_ALIGN-1))
#define ELF_PAGEOFFSET(_v) ((_v) & (ELF_MIN_ALIGN-1))
#define ELF_PAGEALIGN(_v) (((_v) + ELF_MIN_ALIGN - 1) & ~(ELF_MIN_ALIGN - 1))

static struct linux_binfmt elf_format = {
		.module		= THIS_MODULE,
		.load_binary	= load_elf_binary,
		.load_shlib	= load_elf_library,
		.core_dump	= elf_core_dump,
		.min_coredump	= ELF_EXEC_PAGESIZE,
		.hasvdso	= 1
};

#define BAD_ADDR(x) ((unsigned long)(x) >= TASK_SIZE)

static int set_brk(unsigned long start, unsigned long end)
{
	start = ELF_PAGEALIGN(start);
	end = ELF_PAGEALIGN(end);
	if (end > start) {
		unsigned long addr;
		down_write(&current->mm->mmap_sem);
		addr = do_brk(start, end - start);
		up_write(&current->mm->mmap_sem);
		if (BAD_ADDR(addr))
			return addr;
	}
	current->mm->start_brk = current->mm->brk = end;
	return 0;
}

/* We need to explicitly zero any fractional pages
   after the data section (i.e. bss).  This would
   contain the junk from the file that should not
   be in memory
 */
static int padzero(unsigned long elf_bss)
{
	unsigned long nbyte;

	nbyte = ELF_PAGEOFFSET(elf_bss);
	if (nbyte) {
		nbyte = ELF_MIN_ALIGN - nbyte;
		if (clear_user((void __user *) elf_bss, nbyte))
			return -EFAULT;
	}
	return 0;
}

/* Let's use some macros to make this stack manipulation a litle clearer */
#ifdef CONFIG_STACK_GROWSUP
#define STACK_ADD(sp, items) ((elf_addr_t __user *)(sp) + (items))
#define STACK_ROUND(sp, items) \
	((15 + (unsigned long) ((sp) + (items))) &~ 15UL)
#define STACK_ALLOC(sp, len) ({ \
	elf_addr_t __user *old_sp = (elf_addr_t __user *)sp; sp += len; \
	old_sp; })
#else
#define STACK_ADD(sp, items) ((elf_addr_t __user *)(sp) - (items))
#define STACK_ROUND(sp, items) \
	(((unsigned long) (sp - items)) &~ 15UL)
#define STACK_ALLOC(sp, len) ({ sp -= len ; sp; })
#endif

static int
create_elf_tables(struct linux_binprm *bprm, struct elfhdr *exec,
		int interp_aout, unsigned long load_addr,
		unsigned long interp_load_addr)
{
	unsigned long p = bprm->p;
	int argc = bprm->argc;
	int envc = bprm->envc;
	elf_addr_t __user *argv;
	elf_addr_t __user *envp;
	elf_addr_t __user *sp;
	elf_addr_t __user *u_platform;
	const char *k_platform = ELF_PLATFORM;
	int items;
	elf_addr_t *elf_info;
	int ei_index = 0;
	struct task_struct *tsk = current;
	struct vm_area_struct *vma;

	/*
	 * If this architecture has a platform capability string, copy it
	 * to userspace.  In some cases (Sparc), this info is impossible
	 * for userspace to get any other way, in others (i386) it is
	 * merely difficult.
	 */
	u_platform = NULL;
	if (k_platform) {
		size_t len = strlen(k_platform) + 1;

		/*
		 * In some cases (e.g. Hyper-Threading), we want to avoid L1
		 * evictions by the processes running on the same package. One
		 * thing we can do is to shuffle the initial stack for them.
		 */

		p = arch_align_stack(p);

		u_platform = (elf_addr_t __user *)STACK_ALLOC(p, len);
		if (__copy_to_user(u_platform, k_platform, len))
			return -EFAULT;
	}

	/* Create the ELF interpreter info */
	elf_info = (elf_addr_t *)current->mm->saved_auxv;
#define NEW_AUX_ENT(id, val) \
	do { \
		elf_info[ei_index++] = id; \
		elf_info[ei_index++] = val; \
	} while (0)

#ifdef ARCH_DLINFO
	/* 
	 * ARCH_DLINFO must come first so PPC can do its special alignment of
	 * AUXV.
	 */
	ARCH_DLINFO;
#endif
	NEW_AUX_ENT(AT_HWCAP, ELF_HWCAP);
	NEW_AUX_ENT(AT_PAGESZ, ELF_EXEC_PAGESIZE);
	NEW_AUX_ENT(AT_CLKTCK, CLOCKS_PER_SEC);
	NEW_AUX_ENT(AT_PHDR, load_addr + exec->e_phoff);
	NEW_AUX_ENT(AT_PHENT, sizeof(struct elf_phdr));
	NEW_AUX_ENT(AT_PHNUM, exec->e_phnum);
	NEW_AUX_ENT(AT_BASE, interp_load_addr);
	NEW_AUX_ENT(AT_FLAGS, 0);
	NEW_AUX_ENT(AT_ENTRY, exec->e_entry);
	NEW_AUX_ENT(AT_UID, tsk->uid);
	NEW_AUX_ENT(AT_EUID, tsk->euid);
	NEW_AUX_ENT(AT_GID, tsk->gid);
	NEW_AUX_ENT(AT_EGID, tsk->egid);
 	NEW_AUX_ENT(AT_SECURE, security_bprm_secureexec(bprm));
	if (k_platform) {
		NEW_AUX_ENT(AT_PLATFORM,
			    (elf_addr_t)(unsigned long)u_platform);
	}
	if (bprm->interp_flags & BINPRM_FLAGS_EXECFD) {
		NEW_AUX_ENT(AT_EXECFD, bprm->interp_data);
	}
#undef NEW_AUX_ENT
	/* AT_NULL is zero; clear the rest too */
	memset(&elf_info[ei_index], 0,
	       sizeof current->mm->saved_auxv - ei_index * sizeof elf_info[0]);

	/* And advance past the AT_NULL entry.  */
	ei_index += 2;

	sp = STACK_ADD(p, ei_index);

	items = (argc + 1) + (envc + 1);
	if (interp_aout) {
		items += 3; /* a.out interpreters require argv & envp too */
	} else {
		items += 1; /* ELF interpreters only put argc on the stack */
	}
	bprm->p = STACK_ROUND(sp, items);

	/* Point sp at the lowest address on the stack */
#ifdef CONFIG_STACK_GROWSUP
	sp = (elf_addr_t __user *)bprm->p - items - ei_index;
	bprm->exec = (unsigned long)sp; /* XXX: PARISC HACK */
#else
	sp = (elf_addr_t __user *)bprm->p;
#endif


	/*
	 * Grow the stack manually; some architectures have a limit on how
	 * far ahead a user-space access may be in order to grow the stack.
	 */
	vma = find_extend_vma(current->mm, bprm->p);
	if (!vma)
		return -EFAULT;

	/* Now, let's put argc (and argv, envp if appropriate) on the stack */
	if (__put_user(argc, sp++))
		return -EFAULT;
	if (interp_aout) {
		argv = sp + 2;
		envp = argv + argc + 1;
		if (__put_user((elf_addr_t)(unsigned long)argv, sp++) ||
		    __put_user((elf_addr_t)(unsigned long)envp, sp++))
			return -EFAULT;
	} else {
		argv = sp;
		envp = argv + argc + 1;
	}

	/* Populate argv and envp */
	p = current->mm->arg_end = current->mm->arg_start;
	while (argc-- > 0) {
		size_t len;
		if (__put_user((elf_addr_t)p, argv++))
			return -EFAULT;
		len = strnlen_user((void __user *)p, MAX_ARG_STRLEN);
		if (!len || len > MAX_ARG_STRLEN)
			return 0;
		p += len;
	}
	if (__put_user(0, argv))
		return -EFAULT;
	current->mm->arg_end = current->mm->env_start = p;
	while (envc-- > 0) {
		size_t len;
		if (__put_user((elf_addr_t)p, envp++))
			return -EFAULT;
		len = strnlen_user((void __user *)p, MAX_ARG_STRLEN);
		if (!len || len > MAX_ARG_STRLEN)
			return 0;
		p += len;
	}
	if (__put_user(0, envp))
		return -EFAULT;
	current->mm->env_end = p;

	/* Put the elf_info on the stack in the right place.  */