1 #include <sys/ptrace.h> 2 #include <sys/prctl.h> 3 #include <asm/unistd.h> 4 #include <sysdep/stub.h> 5 #include <stub-data.h> 6 7 void _start(void); 8 9 noinline static void real_init(void) 10 { 11 struct stub_init_data init_data; 12 unsigned long res; 13 struct { 14 void *ss_sp; 15 int ss_flags; 16 size_t ss_size; 17 } stack = { 18 .ss_size = STUB_DATA_PAGES * UM_KERN_PAGE_SIZE, 19 }; 20 struct { 21 void *sa_handler_; 22 unsigned long sa_flags; 23 void *sa_restorer; 24 unsigned long long sa_mask; 25 } sa = { 26 /* Need to set SA_RESTORER (but the handler never returns) */ 27 .sa_flags = SA_ONSTACK | SA_NODEFER | SA_SIGINFO | 0x04000000, 28 /* no need to mask any signals */ 29 .sa_mask = 0, 30 }; 31 32 /* set a nice name */ 33 stub_syscall2(__NR_prctl, PR_SET_NAME, (unsigned long)"uml-userspace"); 34 35 /* Make sure this process dies if the kernel dies */ 36 stub_syscall2(__NR_prctl, PR_SET_PDEATHSIG, SIGKILL); 37 38 /* read information from STDIN and close it */ 39 res = stub_syscall3(__NR_read, 0, 40 (unsigned long)&init_data, sizeof(init_data)); 41 if (res != sizeof(init_data)) 42 stub_syscall1(__NR_exit, 10); 43 44 stub_syscall1(__NR_close, 0); 45 46 /* map stub code + data */ 47 res = stub_syscall6(STUB_MMAP_NR, 48 init_data.stub_start, UM_KERN_PAGE_SIZE, 49 PROT_READ | PROT_EXEC, MAP_FIXED | MAP_SHARED, 50 init_data.stub_code_fd, init_data.stub_code_offset); 51 if (res != init_data.stub_start) 52 stub_syscall1(__NR_exit, 11); 53 54 res = stub_syscall6(STUB_MMAP_NR, 55 init_data.stub_start + UM_KERN_PAGE_SIZE, 56 STUB_DATA_PAGES * UM_KERN_PAGE_SIZE, 57 PROT_READ | PROT_WRITE, MAP_FIXED | MAP_SHARED, 58 init_data.stub_data_fd, init_data.stub_data_offset); 59 if (res != init_data.stub_start + UM_KERN_PAGE_SIZE) 60 stub_syscall1(__NR_exit, 12); 61 62 /* setup signal stack inside stub data */ 63 stack.ss_sp = (void *)init_data.stub_start + UM_KERN_PAGE_SIZE; 64 stub_syscall2(__NR_sigaltstack, (unsigned long)&stack, 0); 65 66 /* register SIGSEGV handler */ 67 sa.sa_handler_ = (void *) init_data.segv_handler; 68 res = stub_syscall4(__NR_rt_sigaction, SIGSEGV, (unsigned long)&sa, 0, 69 sizeof(sa.sa_mask)); 70 if (res != 0) 71 stub_syscall1(__NR_exit, 13); 72 73 stub_syscall4(__NR_ptrace, PTRACE_TRACEME, 0, 0, 0); 74 75 stub_syscall2(__NR_kill, stub_syscall0(__NR_getpid), SIGSTOP); 76 77 stub_syscall1(__NR_exit, 14); 78 79 __builtin_unreachable(); 80 } 81 82 void _start(void) 83 { 84 char *alloc; 85 86 /* Make enough space for the stub (including space for alignment) */ 87 alloc = __builtin_alloca((1 + 2 * STUB_DATA_PAGES - 1) * UM_KERN_PAGE_SIZE); 88 asm volatile("" : "+r,m"(alloc) : : "memory"); 89 90 real_init(); 91 } 92