]>
Commit | Line | Data |
---|---|---|
1da177e4 LT |
1 | /* |
2 | * This file is subject to the terms and conditions of the GNU General Public | |
3 | * License. See the file "COPYING" in the main directory of this archive | |
4 | * for more details. | |
5 | * | |
6 | * Copyright (c) 1996, 1999 by Ralf Baechle | |
7 | */ | |
8 | #include <linux/errno.h> | |
9 | #include <asm/asm.h> | |
10 | #include <asm/offset.h> | |
11 | #include <asm/regdef.h> | |
12 | ||
13 | #define EX(insn,reg,addr,handler) \ | |
14 | 9: insn reg, addr; \ | |
15 | .section __ex_table,"a"; \ | |
16 | PTR 9b, handler; \ | |
17 | .previous | |
18 | ||
19 | /* | |
20 | * Returns: -EFAULT if exception before terminator, N if the entire | |
21 | * buffer filled, else strlen. | |
22 | */ | |
23 | ||
24 | /* | |
25 | * Ugly special case have to check: we might get passed a user space | |
26 | * pointer which wraps into the kernel space. We don't deal with that. If | |
27 | * it happens at most some bytes of the exceptions handlers will be copied. | |
28 | */ | |
29 | ||
30 | LEAF(__strncpy_from_user_asm) | |
31 | LONG_L v0, TI_ADDR_LIMIT($28) # pointer ok? | |
32 | and v0, a1 | |
33 | bnez v0, fault | |
34 | ||
35 | FEXPORT(__strncpy_from_user_nocheck_asm) | |
36 | move v0, zero | |
37 | move v1, a1 | |
38 | .set noreorder | |
39 | 1: EX(lbu, t0, (v1), fault) | |
40 | PTR_ADDIU v1, 1 | |
41 | beqz t0, 2f | |
42 | sb t0, (a0) | |
43 | PTR_ADDIU v0, 1 | |
44 | bne v0, a2, 1b | |
45 | PTR_ADDIU a0, 1 | |
46 | .set reorder | |
47 | 2: PTR_ADDU t0, a1, v0 | |
48 | xor t0, a1 | |
49 | bltz t0, fault | |
50 | jr ra # return n | |
51 | END(__strncpy_from_user_asm) | |
52 | ||
53 | fault: li v0, -EFAULT | |
54 | jr ra | |
55 | ||
56 | .section __ex_table,"a" | |
57 | PTR 1b, fault | |
58 | .previous |