Beispiel #1
0
/*
 * We give a *copy* of the faultinfo in the regs to segv.
 * This must be done, since nesting SEGVs could overwrite
 * the info in the regs. A pointer to the info then would
 * give us bad data!
 */
unsigned long segv(struct faultinfo fi, unsigned long ip, int is_user, void *sc)
{
	struct siginfo si;
	void *catcher;
	int err;
        int is_write = FAULT_WRITE(fi);
        unsigned long address = FAULT_ADDRESS(fi);

        if(!is_user && (address >= start_vm) && (address < end_vm)){
                flush_tlb_kernel_vm();
                return(0);
        }
	else if(current->mm == NULL)
		panic("Segfault with no mm");

	if (SEGV_IS_FIXABLE(&fi) || SEGV_MAYBE_FIXABLE(&fi))
		err = handle_page_fault(address, ip, is_write, is_user, &si.si_code);
	else {
		err = -EFAULT;
		/* A thread accessed NULL, we get a fault, but CR2 is invalid.
		 * This code is used in __do_copy_from_user() of TT mode. */
		address = 0;
	}

	catcher = current->thread.fault_catcher;
	if(!err)
		return(0);
	else if(catcher != NULL){
		current->thread.fault_addr = (void *) address;
		do_longjmp(catcher, 1);
	}
	else if(current->thread.fault_addr != NULL)
		panic("fault_addr set but no fault catcher");
        else if(!is_user && arch_fixup(ip, sc))
		return(0);

 	if(!is_user)
		panic("Kernel mode fault at addr 0x%lx, ip 0x%lx",
		      address, ip);

	if (err == -EACCES) {
		si.si_signo = SIGBUS;
		si.si_errno = 0;
		si.si_code = BUS_ADRERR;
		si.si_addr = (void __user *)address;
                current->thread.arch.faultinfo = fi;
		force_sig_info(SIGBUS, &si, current);
	} else if (err == -ENOMEM) {
		printk("VM: killing process %s\n", current->comm);
		do_exit(SIGKILL);
	} else {
		BUG_ON(err != -EFAULT);
		si.si_signo = SIGSEGV;
		si.si_addr = (void __user *) address;
                current->thread.arch.faultinfo = fi;
		force_sig_info(SIGSEGV, &si, current);
	}
	return(0);
}
Beispiel #2
0
int um_execve(char *file, char **argv, char **env)
{
	int err;

	err = execve1(file, argv, env);
	if(!err) 
		do_longjmp(current->thread.exec_buf, 1);
	return(err);
}
int
main(int argc, char *argv[])
{
  printf("main()\n");
  do_setjmp();
  another_function();
  do_longjmp();
  printf("exiting main()\n");
  exit(EXIT_SUCCESS);
}
Beispiel #4
0
int main(int argc, char** argv) 
{
#if defined(__amd64__) || defined(__x86_64__)
    printf("x86_64 sizeof(long int)=%d, sizeof(long)=%d, "
        "sizeof(int)=%d, __WORDSIZE=%d, __GLIBC__=%d, __GLIBC_MINOR__=%d\n", 
        (int)sizeof(long int), (int)sizeof(long), (int)sizeof(int), 
        (int)__WORDSIZE, (int)__GLIBC__, (int)__GLIBC_MINOR__);
#else
    printf("arm sizeof(long int)=%d, sizeof(long)=%d, "
        "sizeof(int)=%d, __GLIBC__=%d,__GLIBC_MINOR__=%d\n", 
        (int)sizeof(long int), (int)sizeof(long), (int)sizeof(int), 
        (int)__GLIBC__, (int)__GLIBC_MINOR__);
#endif

    do_longjmp();
    
    printf("terminated\n");

    return 0;
}
Beispiel #5
0
void bus_handler(int sig, union uml_pt_regs *regs)
{
	if(current->thread.fault_catcher != NULL)
		do_longjmp(current->thread.fault_catcher, 1);
	else relay_signal(sig, regs);
}