1 /* 2 * Copyright (C) 2000, 2001 Jeff Dike (jdike@karaya.com) 3 * Licensed under the GPL 4 */ 5 6 #include <unistd.h> 7 #include <stdio.h> 8 #include <stdlib.h> 9 #include <string.h> 10 #include <signal.h> 11 #include <errno.h> 12 #include <sys/resource.h> 13 #include <sys/mman.h> 14 #include <sys/user.h> 15 #include <asm/page.h> 16 #include "user_util.h" 17 #include "kern_util.h" 18 #include "mem_user.h" 19 #include "signal_user.h" 20 #include "time_user.h" 21 #include "irq_user.h" 22 #include "user.h" 23 #include "init.h" 24 #include "mode.h" 25 #include "choose-mode.h" 26 #include "uml-config.h" 27 #include "os.h" 28 29 /* Set in set_stklim, which is called from main and __wrap_malloc. 30 * __wrap_malloc only calls it if main hasn't started. 31 */ 32 unsigned long stacksizelim; 33 34 /* Set in main */ 35 char *linux_prog; 36 37 #define PGD_BOUND (4 * 1024 * 1024) 38 #define STACKSIZE (8 * 1024 * 1024) 39 #define THREAD_NAME_LEN (256) 40 41 static void set_stklim(void) 42 { 43 struct rlimit lim; 44 45 if(getrlimit(RLIMIT_STACK, &lim) < 0){ 46 perror("getrlimit"); 47 exit(1); 48 } 49 if((lim.rlim_cur == RLIM_INFINITY) || (lim.rlim_cur > STACKSIZE)){ 50 lim.rlim_cur = STACKSIZE; 51 if(setrlimit(RLIMIT_STACK, &lim) < 0){ 52 perror("setrlimit"); 53 exit(1); 54 } 55 } 56 stacksizelim = (lim.rlim_cur + PGD_BOUND - 1) & ~(PGD_BOUND - 1); 57 } 58 59 static __init void do_uml_initcalls(void) 60 { 61 initcall_t *call; 62 63 call = &__uml_initcall_start; 64 while (call < &__uml_initcall_end){; 65 (*call)(); 66 call++; 67 } 68 } 69 70 static void last_ditch_exit(int sig) 71 { 72 signal(SIGINT, SIG_DFL); 73 signal(SIGTERM, SIG_DFL); 74 signal(SIGHUP, SIG_DFL); 75 uml_cleanup(); 76 exit(1); 77 } 78 79 extern int uml_exitcode; 80 81 extern void scan_elf_aux( char **envp); 82 83 int main(int argc, char **argv, char **envp) 84 { 85 char **new_argv; 86 sigset_t mask; 87 int ret, i, err; 88 89 /* Enable all signals except SIGIO - in some environments, we can 90 * enter with some signals blocked 91 */ 92 93 sigemptyset(&mask); 94 sigaddset(&mask, SIGIO); 95 if(sigprocmask(SIG_SETMASK, &mask, NULL) < 0){ 96 perror("sigprocmask"); 97 exit(1); 98 } 99 100 #ifdef UML_CONFIG_CMDLINE_ON_HOST 101 /* Allocate memory for thread command lines */ 102 if(argc < 2 || strlen(argv[1]) < THREAD_NAME_LEN - 1){ 103 104 char padding[THREAD_NAME_LEN] = { 105 [ 0 ... THREAD_NAME_LEN - 2] = ' ', '\0' 106 }; 107 108 new_argv = malloc((argc + 2) * sizeof(char*)); 109 if(!new_argv) { 110 perror("Allocating extended argv"); 111 exit(1); 112 } 113 114 new_argv[0] = argv[0]; 115 new_argv[1] = padding; 116 117 for(i = 2; i <= argc; i++) 118 new_argv[i] = argv[i - 1]; 119 new_argv[argc + 1] = NULL; 120 121 execvp(new_argv[0], new_argv); 122 perror("execing with extended args"); 123 exit(1); 124 } 125 #endif 126 127 linux_prog = argv[0]; 128 129 set_stklim(); 130 131 new_argv = malloc((argc + 1) * sizeof(char *)); 132 if(new_argv == NULL){ 133 perror("Mallocing argv"); 134 exit(1); 135 } 136 for(i=0;i<argc;i++){ 137 new_argv[i] = strdup(argv[i]); 138 if(new_argv[i] == NULL){ 139 perror("Mallocing an arg"); 140 exit(1); 141 } 142 } 143 new_argv[argc] = NULL; 144 145 set_handler(SIGINT, last_ditch_exit, SA_ONESHOT | SA_NODEFER, -1); 146 set_handler(SIGTERM, last_ditch_exit, SA_ONESHOT | SA_NODEFER, -1); 147 set_handler(SIGHUP, last_ditch_exit, SA_ONESHOT | SA_NODEFER, -1); 148 149 scan_elf_aux( envp); 150 151 do_uml_initcalls(); 152 ret = linux_main(argc, argv); 153 154 /* Disable SIGPROF - I have no idea why libc doesn't do this or turn 155 * off the profiling time, but UML dies with a SIGPROF just before 156 * exiting when profiling is active. 157 */ 158 change_sig(SIGPROF, 0); 159 160 /* This signal stuff used to be in the reboot case. However, 161 * sometimes a SIGVTALRM can come in when we're halting (reproducably 162 * when writing out gcov information, presumably because that takes 163 * some time) and cause a segfault. 164 */ 165 166 /* stop timers and set SIG*ALRM to be ignored */ 167 disable_timer(); 168 169 /* disable SIGIO for the fds and set SIGIO to be ignored */ 170 err = deactivate_all_fds(); 171 if(err) 172 printf("deactivate_all_fds failed, errno = %d\n", -err); 173 174 /* Let any pending signals fire now. This ensures 175 * that they won't be delivered after the exec, when 176 * they are definitely not expected. 177 */ 178 unblock_signals(); 179 180 /* Reboot */ 181 if(ret){ 182 printf("\n"); 183 execvp(new_argv[0], new_argv); 184 perror("Failed to exec kernel"); 185 ret = 1; 186 } 187 printf("\n"); 188 return(uml_exitcode); 189 } 190 191 #define CAN_KMALLOC() \ 192 (kmalloc_ok && CHOOSE_MODE((os_getpid() != tracing_pid), 1)) 193 194 extern void *__real_malloc(int); 195 196 void *__wrap_malloc(int size) 197 { 198 void *ret; 199 200 if(!CAN_KMALLOC()) 201 return(__real_malloc(size)); 202 else if(size <= PAGE_SIZE) /* finding contiguos pages can be hard*/ 203 ret = um_kmalloc(size); 204 else ret = um_vmalloc(size); 205 206 /* glibc people insist that if malloc fails, errno should be 207 * set by malloc as well. So we do. 208 */ 209 if(ret == NULL) 210 errno = ENOMEM; 211 212 return(ret); 213 } 214 215 void *__wrap_calloc(int n, int size) 216 { 217 void *ptr = __wrap_malloc(n * size); 218 219 if(ptr == NULL) return(NULL); 220 memset(ptr, 0, n * size); 221 return(ptr); 222 } 223 224 extern void __real_free(void *); 225 226 extern unsigned long high_physmem; 227 228 void __wrap_free(void *ptr) 229 { 230 unsigned long addr = (unsigned long) ptr; 231 232 /* We need to know how the allocation happened, so it can be correctly 233 * freed. This is done by seeing what region of memory the pointer is 234 * in - 235 * physical memory - kmalloc/kfree 236 * kernel virtual memory - vmalloc/vfree 237 * anywhere else - malloc/free 238 * If kmalloc is not yet possible, then either high_physmem and/or 239 * end_vm are still 0 (as at startup), in which case we call free, or 240 * we have set them, but anyway addr has not been allocated from those 241 * areas. So, in both cases __real_free is called. 242 * 243 * CAN_KMALLOC is checked because it would be bad to free a buffer 244 * with kmalloc/vmalloc after they have been turned off during 245 * shutdown. 246 * XXX: However, we sometimes shutdown CAN_KMALLOC temporarily, so 247 * there is a possibility for memory leaks. 248 */ 249 250 if((addr >= uml_physmem) && (addr < high_physmem)){ 251 if(CAN_KMALLOC()) 252 kfree(ptr); 253 } 254 else if((addr >= start_vm) && (addr < end_vm)){ 255 if(CAN_KMALLOC()) 256 vfree(ptr); 257 } 258 else __real_free(ptr); 259 } 260