1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
| /*
| * This file is subject to the terms and conditions of the GNU General Public
| * License. See the file "COPYING" in the main directory of this archive
| * for more details.
| *
| * Copyright (C) 1996, 1999 by Ralf Baechle
| * Copyright (C) 2011 MIPS Technologies, Inc.
| */
| #include <linux/errno.h>
| #include <asm/asm.h>
| #include <asm/asm-offsets.h>
| #include <asm/export.h>
| #include <asm/regdef.h>
|
| #define EX(insn,reg,addr,handler) \
| 9: insn reg, addr; \
| .section __ex_table,"a"; \
| PTR 9b, handler; \
| .previous
|
| /*
| * Returns: -EFAULT if exception before terminator, N if the entire
| * buffer filled, else strlen.
| */
|
| /*
| * Ugly special case have to check: we might get passed a user space
| * pointer which wraps into the kernel space. We don't deal with that. If
| * it happens at most some bytes of the exceptions handlers will be copied.
| */
|
| .macro __BUILD_STRNCPY_ASM func
| LEAF(__strncpy_from_\func\()_asm)
| LONG_L v0, TI_ADDR_LIMIT($28) # pointer ok?
| and v0, a1
| bnez v0, .Lfault\@
|
| move t0, zero
| move v1, a1
| .ifeqs "\func","kernel"
| 1: EX(lbu, v0, (v1), .Lfault\@)
| .else
| 1: EX(lbue, v0, (v1), .Lfault\@)
| .endif
| PTR_ADDIU v1, 1
| R10KCBARRIER(0(ra))
| sb v0, (a0)
| beqz v0, 2f
| PTR_ADDIU t0, 1
| PTR_ADDIU a0, 1
| bne t0, a2, 1b
| 2: PTR_ADDU v0, a1, t0
| xor v0, a1
| bltz v0, .Lfault\@
| move v0, t0
| jr ra # return n
| END(__strncpy_from_\func\()_asm)
|
| .Lfault\@:
| li v0, -EFAULT
| jr ra
|
| .section __ex_table,"a"
| PTR 1b, .Lfault\@
| .previous
|
| .endm
|
| #ifndef CONFIG_EVA
| /* Set aliases */
| .global __strncpy_from_user_asm
| .set __strncpy_from_user_asm, __strncpy_from_kernel_asm
| EXPORT_SYMBOL(__strncpy_from_user_asm)
| #endif
|
| __BUILD_STRNCPY_ASM kernel
| EXPORT_SYMBOL(__strncpy_from_kernel_asm)
|
| #ifdef CONFIG_EVA
| .set push
| .set eva
| __BUILD_STRNCPY_ASM user
| .set pop
| EXPORT_SYMBOL(__strncpy_from_user_asm)
| #endif
|
|