#include #include #include #include #include void _start(void); noinline static void real_init(void) { struct stub_init_data init_data; unsigned long res; struct { void *ss_sp; int ss_flags; size_t ss_size; } stack = { .ss_size = STUB_DATA_PAGES * UM_KERN_PAGE_SIZE, }; struct { void *sa_handler_; unsigned long sa_flags; void *sa_restorer; unsigned long long sa_mask; } sa = { /* Need to set SA_RESTORER (but the handler never returns) */ .sa_flags = SA_ONSTACK | SA_NODEFER | SA_SIGINFO | 0x04000000, /* no need to mask any signals */ .sa_mask = 0, }; /* set a nice name */ stub_syscall2(__NR_prctl, PR_SET_NAME, (unsigned long)"uml-userspace"); /* read information from STDIN and close it */ res = stub_syscall3(__NR_read, 0, (unsigned long)&init_data, sizeof(init_data)); if (res != sizeof(init_data)) stub_syscall1(__NR_exit, 10); stub_syscall1(__NR_close, 0); /* map stub code + data */ res = stub_syscall6(STUB_MMAP_NR, init_data.stub_start, UM_KERN_PAGE_SIZE, PROT_READ | PROT_EXEC, MAP_FIXED | MAP_SHARED, init_data.stub_code_fd, init_data.stub_code_offset); if (res != init_data.stub_start) stub_syscall1(__NR_exit, 11); res = stub_syscall6(STUB_MMAP_NR, init_data.stub_start + UM_KERN_PAGE_SIZE, STUB_DATA_PAGES * UM_KERN_PAGE_SIZE, PROT_READ | PROT_WRITE, MAP_FIXED | MAP_SHARED, init_data.stub_data_fd, init_data.stub_data_offset); if (res != init_data.stub_start + UM_KERN_PAGE_SIZE) stub_syscall1(__NR_exit, 12); /* setup signal stack inside stub data */ stack.ss_sp = (void *)init_data.stub_start + UM_KERN_PAGE_SIZE; stub_syscall2(__NR_sigaltstack, (unsigned long)&stack, 0); /* register SIGSEGV handler */ sa.sa_handler_ = (void *) init_data.segv_handler; res = stub_syscall4(__NR_rt_sigaction, SIGSEGV, (unsigned long)&sa, 0, sizeof(sa.sa_mask)); if (res != 0) stub_syscall1(__NR_exit, 13); stub_syscall4(__NR_ptrace, PTRACE_TRACEME, 0, 0, 0); stub_syscall2(__NR_kill, stub_syscall0(__NR_getpid), SIGSTOP); stub_syscall1(__NR_exit, 14); __builtin_unreachable(); } void _start(void) { char *alloc; /* Make enough space for the stub (including space for alignment) */ alloc = __builtin_alloca((1 + 2 * STUB_DATA_PAGES - 1) * UM_KERN_PAGE_SIZE); asm volatile("" : "+r,m"(alloc) : : "memory"); real_init(); }