diff options
Diffstat (limited to 'arch/um/os-Linux/main.c')
-rw-r--r-- | arch/um/os-Linux/main.c | 80 |
1 files changed, 41 insertions, 39 deletions
diff --git a/arch/um/os-Linux/main.c b/arch/um/os-Linux/main.c index aeeecc634733..1518f7a45a24 100644 --- a/arch/um/os-Linux/main.c +++ b/arch/um/os-Linux/main.c | |||
@@ -1,27 +1,21 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (C) 2000, 2001 Jeff Dike (jdike@karaya.com) | 2 | * Copyright (C) 2000 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com) |
3 | * Licensed under the GPL | 3 | * Licensed under the GPL |
4 | */ | 4 | */ |
5 | 5 | ||
6 | #include <unistd.h> | ||
7 | #include <stdio.h> | 6 | #include <stdio.h> |
8 | #include <stdlib.h> | 7 | #include <stdlib.h> |
9 | #include <string.h> | 8 | #include <unistd.h> |
10 | #include <signal.h> | ||
11 | #include <errno.h> | 9 | #include <errno.h> |
10 | #include <signal.h> | ||
11 | #include <string.h> | ||
12 | #include <sys/resource.h> | 12 | #include <sys/resource.h> |
13 | #include <sys/mman.h> | ||
14 | #include <sys/user.h> | ||
15 | #include "kern_util.h" | ||
16 | #include "as-layout.h" | 13 | #include "as-layout.h" |
17 | #include "mem_user.h" | ||
18 | #include "irq_user.h" | ||
19 | #include "user.h" | ||
20 | #include "init.h" | 14 | #include "init.h" |
21 | #include "uml-config.h" | 15 | #include "kern_constants.h" |
16 | #include "kern_util.h" | ||
22 | #include "os.h" | 17 | #include "os.h" |
23 | #include "um_malloc.h" | 18 | #include "um_malloc.h" |
24 | #include "kern_constants.h" | ||
25 | 19 | ||
26 | #define PGD_BOUND (4 * 1024 * 1024) | 20 | #define PGD_BOUND (4 * 1024 * 1024) |
27 | #define STACKSIZE (8 * 1024 * 1024) | 21 | #define STACKSIZE (8 * 1024 * 1024) |
@@ -31,13 +25,13 @@ static void set_stklim(void) | |||
31 | { | 25 | { |
32 | struct rlimit lim; | 26 | struct rlimit lim; |
33 | 27 | ||
34 | if(getrlimit(RLIMIT_STACK, &lim) < 0){ | 28 | if (getrlimit(RLIMIT_STACK, &lim) < 0) { |
35 | perror("getrlimit"); | 29 | perror("getrlimit"); |
36 | exit(1); | 30 | exit(1); |
37 | } | 31 | } |
38 | if((lim.rlim_cur == RLIM_INFINITY) || (lim.rlim_cur > STACKSIZE)){ | 32 | if ((lim.rlim_cur == RLIM_INFINITY) || (lim.rlim_cur > STACKSIZE)) { |
39 | lim.rlim_cur = STACKSIZE; | 33 | lim.rlim_cur = STACKSIZE; |
40 | if(setrlimit(RLIMIT_STACK, &lim) < 0){ | 34 | if (setrlimit(RLIMIT_STACK, &lim) < 0) { |
41 | perror("setrlimit"); | 35 | perror("setrlimit"); |
42 | exit(1); | 36 | exit(1); |
43 | } | 37 | } |
@@ -49,7 +43,7 @@ static __init void do_uml_initcalls(void) | |||
49 | initcall_t *call; | 43 | initcall_t *call; |
50 | 44 | ||
51 | call = &__uml_initcall_start; | 45 | call = &__uml_initcall_start; |
52 | while (call < &__uml_initcall_end){ | 46 | while (call < &__uml_initcall_end) { |
53 | (*call)(); | 47 | (*call)(); |
54 | call++; | 48 | call++; |
55 | } | 49 | } |
@@ -68,7 +62,8 @@ static void install_fatal_handler(int sig) | |||
68 | /* All signals are enabled in this handler ... */ | 62 | /* All signals are enabled in this handler ... */ |
69 | sigemptyset(&action.sa_mask); | 63 | sigemptyset(&action.sa_mask); |
70 | 64 | ||
71 | /* ... including the signal being handled, plus we want the | 65 | /* |
66 | * ... including the signal being handled, plus we want the | ||
72 | * handler reset to the default behavior, so that if an exit | 67 | * handler reset to the default behavior, so that if an exit |
73 | * handler is hanging for some reason, the UML will just die | 68 | * handler is hanging for some reason, the UML will just die |
74 | * after this signal is sent a second time. | 69 | * after this signal is sent a second time. |
@@ -76,7 +71,7 @@ static void install_fatal_handler(int sig) | |||
76 | action.sa_flags = SA_RESETHAND | SA_NODEFER; | 71 | action.sa_flags = SA_RESETHAND | SA_NODEFER; |
77 | action.sa_restorer = NULL; | 72 | action.sa_restorer = NULL; |
78 | action.sa_handler = last_ditch_exit; | 73 | action.sa_handler = last_ditch_exit; |
79 | if(sigaction(sig, &action, NULL) < 0){ | 74 | if (sigaction(sig, &action, NULL) < 0) { |
80 | printf("failed to install handler for signal %d - errno = %d\n", | 75 | printf("failed to install handler for signal %d - errno = %d\n", |
81 | errno); | 76 | errno); |
82 | exit(1); | 77 | exit(1); |
@@ -92,7 +87,8 @@ static void setup_env_path(void) | |||
92 | int path_len = 0; | 87 | int path_len = 0; |
93 | 88 | ||
94 | old_path = getenv("PATH"); | 89 | old_path = getenv("PATH"); |
95 | /* if no PATH variable is set or it has an empty value | 90 | /* |
91 | * if no PATH variable is set or it has an empty value | ||
96 | * just use the default + /usr/lib/uml | 92 | * just use the default + /usr/lib/uml |
97 | */ | 93 | */ |
98 | if (!old_path || (path_len = strlen(old_path)) == 0) { | 94 | if (!old_path || (path_len = strlen(old_path)) == 0) { |
@@ -125,38 +121,41 @@ int __init main(int argc, char **argv, char **envp) | |||
125 | setup_env_path(); | 121 | setup_env_path(); |
126 | 122 | ||
127 | new_argv = malloc((argc + 1) * sizeof(char *)); | 123 | new_argv = malloc((argc + 1) * sizeof(char *)); |
128 | if(new_argv == NULL){ | 124 | if (new_argv == NULL) { |
129 | perror("Mallocing argv"); | 125 | perror("Mallocing argv"); |
130 | exit(1); | 126 | exit(1); |
131 | } | 127 | } |
132 | for(i=0;i<argc;i++){ | 128 | for (i = 0; i < argc; i++) { |
133 | new_argv[i] = strdup(argv[i]); | 129 | new_argv[i] = strdup(argv[i]); |
134 | if(new_argv[i] == NULL){ | 130 | if (new_argv[i] == NULL) { |
135 | perror("Mallocing an arg"); | 131 | perror("Mallocing an arg"); |
136 | exit(1); | 132 | exit(1); |
137 | } | 133 | } |
138 | } | 134 | } |
139 | new_argv[argc] = NULL; | 135 | new_argv[argc] = NULL; |
140 | 136 | ||
141 | /* Allow these signals to bring down a UML if all other | 137 | /* |
138 | * Allow these signals to bring down a UML if all other | ||
142 | * methods of control fail. | 139 | * methods of control fail. |
143 | */ | 140 | */ |
144 | install_fatal_handler(SIGINT); | 141 | install_fatal_handler(SIGINT); |
145 | install_fatal_handler(SIGTERM); | 142 | install_fatal_handler(SIGTERM); |
146 | install_fatal_handler(SIGHUP); | 143 | install_fatal_handler(SIGHUP); |
147 | 144 | ||
148 | scan_elf_aux( envp); | 145 | scan_elf_aux(envp); |
149 | 146 | ||
150 | do_uml_initcalls(); | 147 | do_uml_initcalls(); |
151 | ret = linux_main(argc, argv); | 148 | ret = linux_main(argc, argv); |
152 | 149 | ||
153 | /* Disable SIGPROF - I have no idea why libc doesn't do this or turn | 150 | /* |
151 | * Disable SIGPROF - I have no idea why libc doesn't do this or turn | ||
154 | * off the profiling time, but UML dies with a SIGPROF just before | 152 | * off the profiling time, but UML dies with a SIGPROF just before |
155 | * exiting when profiling is active. | 153 | * exiting when profiling is active. |
156 | */ | 154 | */ |
157 | change_sig(SIGPROF, 0); | 155 | change_sig(SIGPROF, 0); |
158 | 156 | ||
159 | /* This signal stuff used to be in the reboot case. However, | 157 | /* |
158 | * This signal stuff used to be in the reboot case. However, | ||
160 | * sometimes a SIGVTALRM can come in when we're halting (reproducably | 159 | * sometimes a SIGVTALRM can come in when we're halting (reproducably |
161 | * when writing out gcov information, presumably because that takes | 160 | * when writing out gcov information, presumably because that takes |
162 | * some time) and cause a segfault. | 161 | * some time) and cause a segfault. |
@@ -167,17 +166,18 @@ int __init main(int argc, char **argv, char **envp) | |||
167 | 166 | ||
168 | /* disable SIGIO for the fds and set SIGIO to be ignored */ | 167 | /* disable SIGIO for the fds and set SIGIO to be ignored */ |
169 | err = deactivate_all_fds(); | 168 | err = deactivate_all_fds(); |
170 | if(err) | 169 | if (err) |
171 | printf("deactivate_all_fds failed, errno = %d\n", -err); | 170 | printf("deactivate_all_fds failed, errno = %d\n", -err); |
172 | 171 | ||
173 | /* Let any pending signals fire now. This ensures | 172 | /* |
173 | * Let any pending signals fire now. This ensures | ||
174 | * that they won't be delivered after the exec, when | 174 | * that they won't be delivered after the exec, when |
175 | * they are definitely not expected. | 175 | * they are definitely not expected. |
176 | */ | 176 | */ |
177 | unblock_signals(); | 177 | unblock_signals(); |
178 | 178 | ||
179 | /* Reboot */ | 179 | /* Reboot */ |
180 | if(ret){ | 180 | if (ret) { |
181 | printf("\n"); | 181 | printf("\n"); |
182 | execvp(new_argv[0], new_argv); | 182 | execvp(new_argv[0], new_argv); |
183 | perror("Failed to exec kernel"); | 183 | perror("Failed to exec kernel"); |
@@ -193,17 +193,18 @@ void *__wrap_malloc(int size) | |||
193 | { | 193 | { |
194 | void *ret; | 194 | void *ret; |
195 | 195 | ||
196 | if(!kmalloc_ok) | 196 | if (!kmalloc_ok) |
197 | return __real_malloc(size); | 197 | return __real_malloc(size); |
198 | else if(size <= UM_KERN_PAGE_SIZE) | 198 | else if (size <= UM_KERN_PAGE_SIZE) |
199 | /* finding contiguous pages can be hard*/ | 199 | /* finding contiguous pages can be hard*/ |
200 | ret = kmalloc(size, UM_GFP_KERNEL); | 200 | ret = kmalloc(size, UM_GFP_KERNEL); |
201 | else ret = vmalloc(size); | 201 | else ret = vmalloc(size); |
202 | 202 | ||
203 | /* glibc people insist that if malloc fails, errno should be | 203 | /* |
204 | * glibc people insist that if malloc fails, errno should be | ||
204 | * set by malloc as well. So we do. | 205 | * set by malloc as well. So we do. |
205 | */ | 206 | */ |
206 | if(ret == NULL) | 207 | if (ret == NULL) |
207 | errno = ENOMEM; | 208 | errno = ENOMEM; |
208 | 209 | ||
209 | return ret; | 210 | return ret; |
@@ -213,7 +214,7 @@ void *__wrap_calloc(int n, int size) | |||
213 | { | 214 | { |
214 | void *ptr = __wrap_malloc(n * size); | 215 | void *ptr = __wrap_malloc(n * size); |
215 | 216 | ||
216 | if(ptr == NULL) | 217 | if (ptr == NULL) |
217 | return NULL; | 218 | return NULL; |
218 | memset(ptr, 0, n * size); | 219 | memset(ptr, 0, n * size); |
219 | return ptr; | 220 | return ptr; |
@@ -227,7 +228,8 @@ void __wrap_free(void *ptr) | |||
227 | { | 228 | { |
228 | unsigned long addr = (unsigned long) ptr; | 229 | unsigned long addr = (unsigned long) ptr; |
229 | 230 | ||
230 | /* We need to know how the allocation happened, so it can be correctly | 231 | /* |
232 | * We need to know how the allocation happened, so it can be correctly | ||
231 | * freed. This is done by seeing what region of memory the pointer is | 233 | * freed. This is done by seeing what region of memory the pointer is |
232 | * in - | 234 | * in - |
233 | * physical memory - kmalloc/kfree | 235 | * physical memory - kmalloc/kfree |
@@ -245,12 +247,12 @@ void __wrap_free(void *ptr) | |||
245 | * there is a possibility for memory leaks. | 247 | * there is a possibility for memory leaks. |
246 | */ | 248 | */ |
247 | 249 | ||
248 | if((addr >= uml_physmem) && (addr < high_physmem)){ | 250 | if ((addr >= uml_physmem) && (addr < high_physmem)) { |
249 | if(kmalloc_ok) | 251 | if (kmalloc_ok) |
250 | kfree(ptr); | 252 | kfree(ptr); |
251 | } | 253 | } |
252 | else if((addr >= start_vm) && (addr < end_vm)){ | 254 | else if ((addr >= start_vm) && (addr < end_vm)) { |
253 | if(kmalloc_ok) | 255 | if (kmalloc_ok) |
254 | vfree(ptr); | 256 | vfree(ptr); |
255 | } | 257 | } |
256 | else __real_free(ptr); | 258 | else __real_free(ptr); |