This stack check implementation leverages the compiler's profiling (gcc -p)
[linux-2.6.git] / arch / i386 / lib / getuser.S
1 /*
2  * __get_user functions.
3  *
4  * (C) Copyright 1998 Linus Torvalds
5  *
6  * These functions have a non-standard call interface
7  * to make them more efficient, especially as they
8  * return an error value in addition to the "real"
9  * return value.
10  */
11 #include <asm/thread_info.h>
12 #include <asm/asm_offsets.h>
13
14
15 /*
16  * __get_user_X
17  *
18  * Inputs:      %eax contains the address
19  *
20  * Outputs:     %eax is error code (0 or -EFAULT)
21  *              %edx contains zero-extended value
22  *
23  * These functions should not modify any other registers,
24  * as they get called from within inline assembly.
25  */
26
27 .text
28 .align 4
29 .globl __get_user_1
30 __get_user_1:
31         GET_THREAD_INFO(%edx)
32         cmpl TI_addr_limit(%edx),%eax
33         jae bad_get_user
34 1:      movzbl (%eax),%edx
35         xorl %eax,%eax
36         ret
37
38 .align 4
39 .globl __get_user_2
40 __get_user_2:
41         addl $1,%eax
42         jc bad_get_user
43         GET_THREAD_INFO(%edx)
44         cmpl TI_addr_limit(%edx),%eax
45         jae bad_get_user
46 2:      movzwl -1(%eax),%edx
47         xorl %eax,%eax
48         ret
49
50 .align 4
51 .globl __get_user_4
52 __get_user_4:
53         addl $3,%eax
54         jc bad_get_user
55         GET_THREAD_INFO(%edx)
56         cmpl TI_addr_limit(%edx),%eax
57         jae bad_get_user
58 3:      movl -3(%eax),%edx
59         xorl %eax,%eax
60         ret
61
62 bad_get_user:
63         xorl %edx,%edx
64         movl $-14,%eax
65         ret
66
67 .section __ex_table,"a"
68         .long 1b,bad_get_user
69         .long 2b,bad_get_user
70         .long 3b,bad_get_user
71 .previous