diff options
author | Roland McGrath <roland@redhat.com> | 2008-01-30 07:30:44 -0500 |
---|---|---|
committer | Ingo Molnar <mingo@elte.hu> | 2008-01-30 07:30:44 -0500 |
commit | 69d0627a7f6e891189124d784d2fa90cae7c449a (patch) | |
tree | f39140f454b98a28846df7d0a1b9279a8b3b8d97 | |
parent | 16f4bc738d616962a844e80f7b1fcb52c626542a (diff) |
x86 vDSO: reorder vdso32 code
This reorders the code in the 32-bit vDSO images to put the signal
trampolines first and __kernel_vsyscall after them. The order does
not matter to userland, it just uses what AT_SYSINFO or e_entry
says. Since the signal trampolines are the same size in both
versions of the vDSO, putting them first is the simplest way to get
the addresses to line up. This makes it work to use a more compact
layout for the vDSO.
Signed-off-by: Roland McGrath <roland@redhat.com>
Cc: Andrew Morton <akpm@linux-foundation.org>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
-rw-r--r-- | arch/x86/vdso/vdso32/int80.S | 21 | ||||
-rw-r--r-- | arch/x86/vdso/vdso32/sigreturn.S | 20 | ||||
-rw-r--r-- | arch/x86/vdso/vdso32/syscall.S | 22 | ||||
-rw-r--r-- | arch/x86/vdso/vdso32/sysenter.S | 21 |
4 files changed, 47 insertions, 37 deletions
diff --git a/arch/x86/vdso/vdso32/int80.S b/arch/x86/vdso/vdso32/int80.S index 3c8e4c62ace3..be4b7a9a7cdd 100644 --- a/arch/x86/vdso/vdso32/int80.S +++ b/arch/x86/vdso/vdso32/int80.S | |||
@@ -1,15 +1,15 @@ | |||
1 | /* | 1 | /* |
2 | * Code for the vsyscall page. This version uses the old int $0x80 method. | 2 | * Code for the vDSO. This version uses the old int $0x80 method. |
3 | * | 3 | * |
4 | * NOTE: | 4 | * First get the common code for the sigreturn entry points. |
5 | * 1) __kernel_vsyscall _must_ be first in this page. | 5 | * This must come first. |
6 | * 2) there are alignment constraints on this stub, see vsyscall-sigreturn.S | ||
7 | * for details. | ||
8 | */ | 6 | */ |
7 | #include "sigreturn.S" | ||
9 | 8 | ||
10 | .text | 9 | .text |
11 | .globl __kernel_vsyscall | 10 | .globl __kernel_vsyscall |
12 | .type __kernel_vsyscall,@function | 11 | .type __kernel_vsyscall,@function |
12 | ALIGN | ||
13 | __kernel_vsyscall: | 13 | __kernel_vsyscall: |
14 | .LSTART_vsyscall: | 14 | .LSTART_vsyscall: |
15 | int $0x80 | 15 | int $0x80 |
@@ -47,7 +47,10 @@ __kernel_vsyscall: | |||
47 | .LENDFDEDLSI: | 47 | .LENDFDEDLSI: |
48 | .previous | 48 | .previous |
49 | 49 | ||
50 | /* | 50 | /* |
51 | * Get the common code for the sigreturn entry points. | 51 | * Pad out the segment to match the size of the sysenter.S version. |
52 | */ | 52 | */ |
53 | #include "sigreturn.S" | 53 | VDSO32_vsyscall_eh_frame_size = 0x44 |
54 | .section .data,"aw",@progbits | ||
55 | .space VDSO32_vsyscall_eh_frame_size-(.LENDFDEDLSI-.LSTARTFRAMEDLSI), 0 | ||
56 | .previous | ||
diff --git a/arch/x86/vdso/vdso32/sigreturn.S b/arch/x86/vdso/vdso32/sigreturn.S index 8d65a0a0eb70..cade2752928b 100644 --- a/arch/x86/vdso/vdso32/sigreturn.S +++ b/arch/x86/vdso/vdso32/sigreturn.S | |||
@@ -1,11 +1,12 @@ | |||
1 | /* | 1 | /* |
2 | * Common code for the sigreturn entry points on the vsyscall page. | 2 | * Common code for the sigreturn entry points in vDSO images. |
3 | * So far this code is the same for both int80 and sysenter versions. | 3 | * So far this code is the same for both int80 and sysenter versions. |
4 | * This file is #include'd by vsyscall-*.S to define them after the | 4 | * This file is #include'd by int80.S et al to define them first thing. |
5 | * vsyscall entry point. The kernel assumes that the addresses of these | 5 | * The kernel assumes that the addresses of these routines are constant |
6 | * routines are constant for all vsyscall implementations. | 6 | * for all vDSO implementations. |
7 | */ | 7 | */ |
8 | 8 | ||
9 | #include <linux/linkage.h> | ||
9 | #include <asm/unistd_32.h> | 10 | #include <asm/unistd_32.h> |
10 | #include <asm/asm-offsets.h> | 11 | #include <asm/asm-offsets.h> |
11 | 12 | ||
@@ -13,32 +14,29 @@ | |||
13 | #define SYSCALL_ENTER_KERNEL int $0x80 | 14 | #define SYSCALL_ENTER_KERNEL int $0x80 |
14 | #endif | 15 | #endif |
15 | 16 | ||
16 | /* XXX | ||
17 | Should these be named "_sigtramp" or something? | ||
18 | */ | ||
19 | |||
20 | .text | 17 | .text |
21 | .org __kernel_vsyscall+32,0x90 | ||
22 | .globl __kernel_sigreturn | 18 | .globl __kernel_sigreturn |
23 | .type __kernel_sigreturn,@function | 19 | .type __kernel_sigreturn,@function |
20 | ALIGN | ||
24 | __kernel_sigreturn: | 21 | __kernel_sigreturn: |
25 | .LSTART_sigreturn: | 22 | .LSTART_sigreturn: |
26 | popl %eax /* XXX does this mean it needs unwind info? */ | 23 | popl %eax /* XXX does this mean it needs unwind info? */ |
27 | movl $__NR_sigreturn, %eax | 24 | movl $__NR_sigreturn, %eax |
28 | SYSCALL_ENTER_KERNEL | 25 | SYSCALL_ENTER_KERNEL |
29 | .LEND_sigreturn: | 26 | .LEND_sigreturn: |
27 | nop | ||
30 | .size __kernel_sigreturn,.-.LSTART_sigreturn | 28 | .size __kernel_sigreturn,.-.LSTART_sigreturn |
31 | 29 | ||
32 | .balign 32 | ||
33 | .globl __kernel_rt_sigreturn | 30 | .globl __kernel_rt_sigreturn |
34 | .type __kernel_rt_sigreturn,@function | 31 | .type __kernel_rt_sigreturn,@function |
32 | ALIGN | ||
35 | __kernel_rt_sigreturn: | 33 | __kernel_rt_sigreturn: |
36 | .LSTART_rt_sigreturn: | 34 | .LSTART_rt_sigreturn: |
37 | movl $__NR_rt_sigreturn, %eax | 35 | movl $__NR_rt_sigreturn, %eax |
38 | SYSCALL_ENTER_KERNEL | 36 | SYSCALL_ENTER_KERNEL |
39 | .LEND_rt_sigreturn: | 37 | .LEND_rt_sigreturn: |
38 | nop | ||
40 | .size __kernel_rt_sigreturn,.-.LSTART_rt_sigreturn | 39 | .size __kernel_rt_sigreturn,.-.LSTART_rt_sigreturn |
41 | .balign 32 | ||
42 | .previous | 40 | .previous |
43 | 41 | ||
44 | .section .eh_frame,"a",@progbits | 42 | .section .eh_frame,"a",@progbits |
diff --git a/arch/x86/vdso/vdso32/syscall.S b/arch/x86/vdso/vdso32/syscall.S index 333bfb552c88..fe88d34f822f 100644 --- a/arch/x86/vdso/vdso32/syscall.S +++ b/arch/x86/vdso/vdso32/syscall.S | |||
@@ -1,13 +1,18 @@ | |||
1 | /* | 1 | /* |
2 | * Code for the vsyscall page. This version uses the syscall instruction. | 2 | * Code for the vDSO. This version uses the syscall instruction. |
3 | * | ||
4 | * First get the common code for the sigreturn entry points. | ||
5 | * This must come first. | ||
3 | */ | 6 | */ |
7 | #define SYSCALL_ENTER_KERNEL syscall | ||
8 | #include "sigreturn.S" | ||
4 | 9 | ||
5 | #include <asm/asm-offsets.h> | ||
6 | #include <asm/segment.h> | 10 | #include <asm/segment.h> |
7 | 11 | ||
8 | .text | 12 | .text |
9 | .globl __kernel_vsyscall | 13 | .globl __kernel_vsyscall |
10 | .type __kernel_vsyscall,@function | 14 | .type __kernel_vsyscall,@function |
15 | ALIGN | ||
11 | __kernel_vsyscall: | 16 | __kernel_vsyscall: |
12 | .LSTART_vsyscall: | 17 | .LSTART_vsyscall: |
13 | push %ebp | 18 | push %ebp |
@@ -61,9 +66,12 @@ __kernel_vsyscall: | |||
61 | .uleb128 4 | 66 | .uleb128 4 |
62 | .align 4 | 67 | .align 4 |
63 | .LENDFDE1: | 68 | .LENDFDE1: |
69 | .previous | ||
64 | 70 | ||
65 | /* | 71 | /* |
66 | * Get the common code for the sigreturn entry points. | 72 | * Pad out the segment to match the size of the sysenter.S version. |
67 | */ | 73 | */ |
68 | #define SYSCALL_ENTER_KERNEL syscall | 74 | VDSO32_vsyscall_eh_frame_size = 0x44 |
69 | #include "sigreturn.S" | 75 | .section .data,"aw",@progbits |
76 | .space VDSO32_vsyscall_eh_frame_size-(.LENDFDE1-.LSTARTFRAME), 0 | ||
77 | .previous | ||
diff --git a/arch/x86/vdso/vdso32/sysenter.S b/arch/x86/vdso/vdso32/sysenter.S index 109bfa394eaa..902d5fc11f1b 100644 --- a/arch/x86/vdso/vdso32/sysenter.S +++ b/arch/x86/vdso/vdso32/sysenter.S | |||
@@ -1,11 +1,10 @@ | |||
1 | /* | 1 | /* |
2 | * Code for the vsyscall page. This version uses the sysenter instruction. | 2 | * Code for the vDSO. This version uses the sysenter instruction. |
3 | * | 3 | * |
4 | * NOTE: | 4 | * First get the common code for the sigreturn entry points. |
5 | * 1) __kernel_vsyscall _must_ be first in this page. | 5 | * This must come first. |
6 | * 2) there are alignment constraints on this stub, see vsyscall-sigreturn.S | ||
7 | * for details. | ||
8 | */ | 6 | */ |
7 | #include "sigreturn.S" | ||
9 | 8 | ||
10 | /* | 9 | /* |
11 | * The caller puts arg2 in %ecx, which gets pushed. The kernel will use | 10 | * The caller puts arg2 in %ecx, which gets pushed. The kernel will use |
@@ -23,11 +22,12 @@ | |||
23 | * arg6 from the stack. | 22 | * arg6 from the stack. |
24 | * | 23 | * |
25 | * You can not use this vsyscall for the clone() syscall because the | 24 | * You can not use this vsyscall for the clone() syscall because the |
26 | * three dwords on the parent stack do not get copied to the child. | 25 | * three words on the parent stack do not get copied to the child. |
27 | */ | 26 | */ |
28 | .text | 27 | .text |
29 | .globl __kernel_vsyscall | 28 | .globl __kernel_vsyscall |
30 | .type __kernel_vsyscall,@function | 29 | .type __kernel_vsyscall,@function |
30 | ALIGN | ||
31 | __kernel_vsyscall: | 31 | __kernel_vsyscall: |
32 | .LSTART_vsyscall: | 32 | .LSTART_vsyscall: |
33 | push %ecx | 33 | push %ecx |
@@ -115,7 +115,8 @@ VDSO32_SYSENTER_RETURN: /* Symbol used by sysenter.c via vdso32-syms.h */ | |||
115 | .LENDFDEDLSI: | 115 | .LENDFDEDLSI: |
116 | .previous | 116 | .previous |
117 | 117 | ||
118 | /* | 118 | /* |
119 | * Get the common code for the sigreturn entry points. | 119 | * Emit a symbol with the size of this .eh_frame data, |
120 | */ | 120 | * to verify it matches the other versions. |
121 | #include "sigreturn.S" | 121 | */ |
122 | VDSO32_vsyscall_eh_frame_size = (.LENDFDEDLSI-.LSTARTFRAMEDLSI) | ||