aboutsummaryrefslogtreecommitdiffstats
path: root/arch/um
diff options
context:
space:
mode:
authorJeff Dike <jdike@addtoit.com>2006-07-10 07:45:06 -0400
committerLinus Torvalds <torvalds@g5.osdl.org>2006-07-10 16:24:23 -0400
commit23bbd586ed7894982fd9323f63b2065afbb77773 (patch)
tree6fec4b69d2c4bafd134efc886f700654606c56fe /arch/um
parent8633c2331e738218c7356633e1c4adb75726225f (diff)
[PATCH] uml: fix static binary segfault
When UML is built as a static binary, it segfaults when run. The reason is that a memory hole that is present in dynamic binaries isn't there in static binaries, and it contains essential stuff. This fix removes the code which maps some anonymous memory into that hole and cleans up some related code. Signed-off-by: Jeff Dike <jdike@addtoit.com> Cc: Paolo 'Blaisorblade' Giarrusso <blaisorblade@yahoo.it> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'arch/um')
-rw-r--r--arch/um/include/skas/mode_kern_skas.h3
-rw-r--r--arch/um/include/tt/mode_kern_tt.h3
-rw-r--r--arch/um/kernel/mem.c11
-rw-r--r--arch/um/kernel/physmem.c2
-rw-r--r--arch/um/kernel/skas/mem.c11
-rw-r--r--arch/um/kernel/tt/mem.c10
-rw-r--r--arch/um/kernel/um_arch.c9
-rw-r--r--arch/um/kernel/uml.lds.S13
8 files changed, 28 insertions, 34 deletions
diff --git a/arch/um/include/skas/mode_kern_skas.h b/arch/um/include/skas/mode_kern_skas.h
index 651350adfe03..9cd9c6ec9a63 100644
--- a/arch/um/include/skas/mode_kern_skas.h
+++ b/arch/um/include/skas/mode_kern_skas.h
@@ -29,8 +29,7 @@ extern void flush_tlb_mm_skas(struct mm_struct *mm);
29extern void force_flush_all_skas(void); 29extern void force_flush_all_skas(void);
30extern long execute_syscall_skas(void *r); 30extern long execute_syscall_skas(void *r);
31extern void before_mem_skas(unsigned long unused); 31extern void before_mem_skas(unsigned long unused);
32extern unsigned long set_task_sizes_skas(unsigned long *host_size_out, 32extern unsigned long set_task_sizes_skas(unsigned long *task_size_out);
33 unsigned long *task_size_out);
34extern int start_uml_skas(void); 33extern int start_uml_skas(void);
35extern int external_pid_skas(struct task_struct *task); 34extern int external_pid_skas(struct task_struct *task);
36extern int thread_pid_skas(struct task_struct *task); 35extern int thread_pid_skas(struct task_struct *task);
diff --git a/arch/um/include/tt/mode_kern_tt.h b/arch/um/include/tt/mode_kern_tt.h
index fb2d3d76685a..a4fc63057195 100644
--- a/arch/um/include/tt/mode_kern_tt.h
+++ b/arch/um/include/tt/mode_kern_tt.h
@@ -30,8 +30,7 @@ extern void flush_tlb_mm_tt(struct mm_struct *mm);
30extern void force_flush_all_tt(void); 30extern void force_flush_all_tt(void);
31extern long execute_syscall_tt(void *r); 31extern long execute_syscall_tt(void *r);
32extern void before_mem_tt(unsigned long brk_start); 32extern void before_mem_tt(unsigned long brk_start);
33extern unsigned long set_task_sizes_tt(unsigned long *host_size_out, 33extern unsigned long set_task_sizes_tt(unsigned long *task_size_out);
34 unsigned long *task_size_out);
35extern int start_uml_tt(void); 34extern int start_uml_tt(void);
36extern int external_pid_tt(struct task_struct *task); 35extern int external_pid_tt(struct task_struct *task);
37extern int thread_pid_tt(struct task_struct *task); 36extern int thread_pid_tt(struct task_struct *task);
diff --git a/arch/um/kernel/mem.c b/arch/um/kernel/mem.c
index 44e41a35f000..61280167c560 100644
--- a/arch/um/kernel/mem.c
+++ b/arch/um/kernel/mem.c
@@ -24,8 +24,6 @@
24#include "init.h" 24#include "init.h"
25#include "kern_constants.h" 25#include "kern_constants.h"
26 26
27extern char __binary_start;
28
29/* Changed during early boot */ 27/* Changed during early boot */
30unsigned long *empty_zero_page = NULL; 28unsigned long *empty_zero_page = NULL;
31unsigned long *empty_bad_page = NULL; 29unsigned long *empty_bad_page = NULL;
@@ -65,8 +63,6 @@ static void setup_highmem(unsigned long highmem_start,
65 63
66void mem_init(void) 64void mem_init(void)
67{ 65{
68 unsigned long start;
69
70 max_low_pfn = (high_physmem - uml_physmem) >> PAGE_SHIFT; 66 max_low_pfn = (high_physmem - uml_physmem) >> PAGE_SHIFT;
71 67
72 /* clear the zero-page */ 68 /* clear the zero-page */
@@ -81,13 +77,6 @@ void mem_init(void)
81 free_bootmem(__pa(brk_end), uml_reserved - brk_end); 77 free_bootmem(__pa(brk_end), uml_reserved - brk_end);
82 uml_reserved = brk_end; 78 uml_reserved = brk_end;
83 79
84 /* Fill in any hole at the start of the binary */
85 start = (unsigned long) &__binary_start & PAGE_MASK;
86 if(uml_physmem != start){
87 map_memory(uml_physmem, __pa(uml_physmem), start - uml_physmem,
88 1, 1, 0);
89 }
90
91 /* this will put all low memory onto the freelists */ 80 /* this will put all low memory onto the freelists */
92 totalram_pages = free_all_bootmem(); 81 totalram_pages = free_all_bootmem();
93 totalhigh_pages = highmem >> PAGE_SHIFT; 82 totalhigh_pages = highmem >> PAGE_SHIFT;
diff --git a/arch/um/kernel/physmem.c b/arch/um/kernel/physmem.c
index 166cb09cae4c..abafa64b8727 100644
--- a/arch/um/kernel/physmem.c
+++ b/arch/um/kernel/physmem.c
@@ -317,7 +317,7 @@ void map_memory(unsigned long virt, unsigned long phys, unsigned long len,
317 } 317 }
318} 318}
319 319
320extern int __syscall_stub_start, __binary_start; 320extern int __syscall_stub_start;
321 321
322void setup_physmem(unsigned long start, unsigned long reserve_end, 322void setup_physmem(unsigned long start, unsigned long reserve_end,
323 unsigned long len, unsigned long long highmem) 323 unsigned long len, unsigned long long highmem)
diff --git a/arch/um/kernel/skas/mem.c b/arch/um/kernel/skas/mem.c
index 7e5b8f165cf2..27bbf54b1e52 100644
--- a/arch/um/kernel/skas/mem.c
+++ b/arch/um/kernel/skas/mem.c
@@ -9,20 +9,19 @@
9#include "mem_user.h" 9#include "mem_user.h"
10#include "skas.h" 10#include "skas.h"
11 11
12unsigned long set_task_sizes_skas(unsigned long *host_size_out, 12unsigned long set_task_sizes_skas(unsigned long *task_size_out)
13 unsigned long *task_size_out)
14{ 13{
15 /* Round up to the nearest 4M */ 14 /* Round up to the nearest 4M */
16 unsigned long top = ROUND_4M((unsigned long) &host_size_out); 15 unsigned long host_task_size = ROUND_4M((unsigned long)
16 &host_task_size);
17 17
18#ifdef CONFIG_HOST_TASK_SIZE 18#ifdef CONFIG_HOST_TASK_SIZE
19 *host_size_out = ROUND_4M(CONFIG_HOST_TASK_SIZE); 19 *host_size_out = ROUND_4M(CONFIG_HOST_TASK_SIZE);
20 *task_size_out = CONFIG_HOST_TASK_SIZE; 20 *task_size_out = CONFIG_HOST_TASK_SIZE;
21#else 21#else
22 *host_size_out = top;
23 if (!skas_needs_stub) 22 if (!skas_needs_stub)
24 *task_size_out = top; 23 *task_size_out = host_task_size;
25 else *task_size_out = CONFIG_STUB_START & PGDIR_MASK; 24 else *task_size_out = CONFIG_STUB_START & PGDIR_MASK;
26#endif 25#endif
27 return ((unsigned long) set_task_sizes_skas) & ~0xffffff; 26 return host_task_size;
28} 27}
diff --git a/arch/um/kernel/tt/mem.c b/arch/um/kernel/tt/mem.c
index 4ae8c5c1e3b3..84a23b14f770 100644
--- a/arch/um/kernel/tt/mem.c
+++ b/arch/um/kernel/tt/mem.c
@@ -24,11 +24,13 @@ void before_mem_tt(unsigned long brk_start)
24#define SIZE ((CONFIG_NEST_LEVEL + CONFIG_KERNEL_HALF_GIGS) * 0x20000000) 24#define SIZE ((CONFIG_NEST_LEVEL + CONFIG_KERNEL_HALF_GIGS) * 0x20000000)
25#define START (CONFIG_TOP_ADDR - SIZE) 25#define START (CONFIG_TOP_ADDR - SIZE)
26 26
27unsigned long set_task_sizes_tt(unsigned long *host_size_out, 27unsigned long set_task_sizes_tt(unsigned long *task_size_out)
28 unsigned long *task_size_out)
29{ 28{
29 unsigned long host_task_size;
30
30 /* Round up to the nearest 4M */ 31 /* Round up to the nearest 4M */
31 *host_size_out = ROUND_4M((unsigned long) &host_size_out); 32 host_task_size = ROUND_4M((unsigned long) &host_task_size);
32 *task_size_out = START; 33 *task_size_out = START;
33 return START; 34
35 return host_task_size;
34} 36}
diff --git a/arch/um/kernel/um_arch.c b/arch/um/kernel/um_arch.c
index a50a0aac8faa..7896cf98232d 100644
--- a/arch/um/kernel/um_arch.c
+++ b/arch/um/kernel/um_arch.c
@@ -330,6 +330,8 @@ EXPORT_SYMBOL(end_iomem);
330 330
331#define MIN_VMALLOC (32 * 1024 * 1024) 331#define MIN_VMALLOC (32 * 1024 * 1024)
332 332
333extern char __binary_start;
334
333int linux_main(int argc, char **argv) 335int linux_main(int argc, char **argv)
334{ 336{
335 unsigned long avail, diff; 337 unsigned long avail, diff;
@@ -374,8 +376,9 @@ int linux_main(int argc, char **argv)
374 376
375 printf("UML running in %s mode\n", mode); 377 printf("UML running in %s mode\n", mode);
376 378
377 uml_start = CHOOSE_MODE_PROC(set_task_sizes_tt, set_task_sizes_skas, 379 uml_start = (unsigned long) &__binary_start;
378 &host_task_size, &task_size); 380 host_task_size = CHOOSE_MODE_PROC(set_task_sizes_tt,
381 set_task_sizes_skas, &task_size);
379 382
380 /* 383 /*
381 * Setting up handlers to 'sig_info' struct 384 * Setting up handlers to 'sig_info' struct
@@ -395,7 +398,7 @@ int linux_main(int argc, char **argv)
395 physmem_size += UML_ROUND_UP(brk_start) - UML_ROUND_UP(&_end); 398 physmem_size += UML_ROUND_UP(brk_start) - UML_ROUND_UP(&_end);
396 } 399 }
397 400
398 uml_physmem = uml_start; 401 uml_physmem = uml_start & PAGE_MASK;
399 402
400 /* Reserve up to 4M after the current brk */ 403 /* Reserve up to 4M after the current brk */
401 uml_reserved = ROUND_4M(brk_start) + (1 << 22); 404 uml_reserved = ROUND_4M(brk_start) + (1 << 22);
diff --git a/arch/um/kernel/uml.lds.S b/arch/um/kernel/uml.lds.S
index af11915ce0a8..8eca47a6ff08 100644
--- a/arch/um/kernel/uml.lds.S
+++ b/arch/um/kernel/uml.lds.S
@@ -7,13 +7,16 @@ jiffies = jiffies_64;
7 7
8SECTIONS 8SECTIONS
9{ 9{
10 /*This must contain the right address - not quite the default ELF one.*/ 10 /* This must contain the right address - not quite the default ELF one.*/
11 PROVIDE (__executable_start = START); 11 PROVIDE (__executable_start = START);
12 . = START + SIZEOF_HEADERS; 12 /* Static binaries stick stuff here, like the sigreturn trampoline,
13 * invisibly to objdump. So, just make __binary_start equal to the very
14 * beginning of the executable, and if there are unmapped pages after this,
15 * they are forever unusable.
16 */
17 __binary_start = START;
13 18
14 /* Used in arch/um/kernel/mem.c. Any memory between START and __binary_start 19 . = START + SIZEOF_HEADERS;
15 * is remapped.*/
16 __binary_start = .;
17 20
18#ifdef MODE_TT 21#ifdef MODE_TT
19 .remap_data : { UNMAP_PATH (.data .bss) } 22 .remap_data : { UNMAP_PATH (.data .bss) }