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 /* read information from STDIN and close it */ 36 res = stub_syscall3(__NR_read, 0, 37 (unsigned long)&init_data, sizeof(init_data)); 38 if (res != sizeof(init_data)) 39 stub_syscall1(__NR_exit, 10); 40 41 stub_syscall1(__NR_close, 0); 42 43 /* map stub code + data */ 44 res = stub_syscall6(STUB_MMAP_NR, 45 init_data.stub_start, UM_KERN_PAGE_SIZE, 46 PROT_READ | PROT_EXEC, MAP_FIXED | MAP_SHARED, 47 init_data.stub_code_fd, init_data.stub_code_offset); 48 if (res != init_data.stub_start) 49 stub_syscall1(__NR_exit, 11); 50 51 res = stub_syscall6(STUB_MMAP_NR, 52 init_data.stub_start + UM_KERN_PAGE_SIZE, 53 STUB_DATA_PAGES * UM_KERN_PAGE_SIZE, 54 PROT_READ | PROT_WRITE, MAP_FIXED | MAP_SHARED, 55 init_data.stub_data_fd, init_data.stub_data_offset); 56 if (res != init_data.stub_start + UM_KERN_PAGE_SIZE) 57 stub_syscall1(__NR_exit, 12); 58 59 /* setup signal stack inside stub data */ 60 stack.ss_sp = (void *)init_data.stub_start + UM_KERN_PAGE_SIZE; 61 stub_syscall2(__NR_sigaltstack, (unsigned long)&stack, 0); 62 63 /* register SIGSEGV handler */ 64 sa.sa_handler_ = (void *) init_data.segv_handler; 65 res = stub_syscall4(__NR_rt_sigaction, SIGSEGV, (unsigned long)&sa, 0, 66 sizeof(sa.sa_mask)); 67 if (res != 0) 68 stub_syscall1(__NR_exit, 13); 69 70 stub_syscall4(__NR_ptrace, PTRACE_TRACEME, 0, 0, 0); 71 72 stub_syscall2(__NR_kill, stub_syscall0(__NR_getpid), SIGSTOP); 73 74 stub_syscall1(__NR_exit, 14); 75 76 __builtin_unreachable(); 77 } 78 79 void _start(void) 80 { 81 char *alloc; 82 83 /* Make enough space for the stub (including space for alignment) */ 84 alloc = __builtin_alloca((1 + 2 * STUB_DATA_PAGES - 1) * UM_KERN_PAGE_SIZE); 85 asm volatile("" : "+r,m"(alloc) : : "memory"); 86 87 real_init(); 88 } 89