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> | |
048eb582 | 10 | #include <asm/asm-offsets.h> |
1da177e4 LT |
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 | |
c5ec1983 | 33 | bnez v0, .Lfault |
1da177e4 LT |
34 | |
35 | FEXPORT(__strncpy_from_user_nocheck_asm) | |
36 | move v0, zero | |
37 | move v1, a1 | |
38 | .set noreorder | |
c5ec1983 | 39 | 1: EX(lbu, t0, (v1), .Lfault) |
1da177e4 | 40 | PTR_ADDIU v1, 1 |
930bff88 | 41 | R10KCBARRIER(0(ra)) |
1da177e4 LT |
42 | beqz t0, 2f |
43 | sb t0, (a0) | |
44 | PTR_ADDIU v0, 1 | |
1da177e4 | 45 | .set reorder |
619b6e18 MR |
46 | PTR_ADDIU a0, 1 |
47 | bne v0, a2, 1b | |
1da177e4 LT |
48 | 2: PTR_ADDU t0, a1, v0 |
49 | xor t0, a1 | |
c5ec1983 | 50 | bltz t0, .Lfault |
1da177e4 LT |
51 | jr ra # return n |
52 | END(__strncpy_from_user_asm) | |
53 | ||
c5ec1983 | 54 | .Lfault: li v0, -EFAULT |
1da177e4 LT |
55 | jr ra |
56 | ||
57 | .section __ex_table,"a" | |
c5ec1983 | 58 | PTR 1b, .Lfault |
1da177e4 | 59 | .previous |