static int userspace_tramp()

in os-Linux/skas/process.c [243:296]


static int userspace_tramp(void *stack)
{
	void *addr;
	int fd;
	unsigned long long offset;

	ptrace(PTRACE_TRACEME, 0, 0, 0);

	signal(SIGTERM, SIG_DFL);
	signal(SIGWINCH, SIG_IGN);

	fd = phys_mapping(to_phys(__syscall_stub_start), &offset);
	addr = mmap64((void *) STUB_CODE, UM_KERN_PAGE_SIZE,
		      PROT_EXEC, MAP_FIXED | MAP_PRIVATE, fd, offset);
	if (addr == MAP_FAILED) {
		printk(UM_KERN_ERR "mapping mmap stub at 0x%lx failed, "
		       "errno = %d\n", STUB_CODE, errno);
		exit(1);
	}

	if (stack != NULL) {
		fd = phys_mapping(to_phys(stack), &offset);
		addr = mmap((void *) STUB_DATA,
			    UM_KERN_PAGE_SIZE, PROT_READ | PROT_WRITE,
			    MAP_FIXED | MAP_SHARED, fd, offset);
		if (addr == MAP_FAILED) {
			printk(UM_KERN_ERR "mapping segfault stack "
			       "at 0x%lx failed, errno = %d\n",
			       STUB_DATA, errno);
			exit(1);
		}
	}
	if (stack != NULL) {
		struct sigaction sa;

		unsigned long v = STUB_CODE +
				  (unsigned long) stub_segv_handler -
				  (unsigned long) __syscall_stub_start;

		set_sigstack((void *) STUB_DATA, UM_KERN_PAGE_SIZE);
		sigemptyset(&sa.sa_mask);
		sa.sa_flags = SA_ONSTACK | SA_NODEFER | SA_SIGINFO;
		sa.sa_sigaction = (void *) v;
		sa.sa_restorer = NULL;
		if (sigaction(SIGSEGV, &sa, NULL) < 0) {
			printk(UM_KERN_ERR "userspace_tramp - setting SIGSEGV "
			       "handler failed - errno = %d\n", errno);
			exit(1);
		}
	}

	kill(os_getpid(), SIGSTOP);
	return 0;
}