1/* 2 * Copyright (C) 2009 Michal Simek <monstr@monstr.eu> 3 * Copyright (C) 2009 PetaLogix 4 * Copyright (C) 2007 LynuxWorks, Inc. 5 * 6 * This file is subject to the terms and conditions of the GNU General Public 7 * License. See the file "COPYING" in the main directory of this archive 8 * for more details. 9 */ 10 11#include <linux/errno.h> 12#include <linux/linkage.h> 13 14/* 15 * int __strncpy_user(char *to, char *from, int len); 16 * 17 * Returns: 18 * -EFAULT for an exception 19 * len if we hit the buffer limit 20 * bytes copied 21 */ 22 23 .text 24.globl __strncpy_user; 25.type __strncpy_user, @function 26.align 4; 27__strncpy_user: 28 29 /* 30 * r5 - to 31 * r6 - from 32 * r7 - len 33 * r3 - temp count 34 * r4 - temp val 35 */ 36 addik r3,r7,0 /* temp_count = len */ 37 beqi r3,3f 381: 39 lbu r4,r6,r0 40 sb r4,r5,r0 41 42 addik r3,r3,-1 43 beqi r3,2f /* break on len */ 44 45 addik r5,r5,1 46 bneid r4,1b 47 addik r6,r6,1 /* delay slot */ 48 addik r3,r3,1 /* undo "temp_count--" */ 492: 50 rsubk r3,r3,r7 /* temp_count = len - temp_count */ 513: 52 rtsd r15,8 53 nop 54 .size __strncpy_user, . - __strncpy_user 55 56 .section .fixup, "ax" 57 .align 2 584: 59 brid 3b 60 addik r3,r0, -EFAULT 61 62 .section __ex_table, "a" 63 .word 1b,4b 64 65/* 66 * int __strnlen_user(char __user *str, int maxlen); 67 * 68 * Returns: 69 * 0 on error 70 * maxlen + 1 if no NUL byte found within maxlen bytes 71 * size of the string (including NUL byte) 72 */ 73 74 .text 75.globl __strnlen_user; 76.type __strnlen_user, @function 77.align 4; 78__strnlen_user: 79 addik r3,r6,0 80 beqi r3,3f 811: 82 lbu r4,r5,r0 83 beqid r4,2f /* break on NUL */ 84 addik r3,r3,-1 /* delay slot */ 85 86 bneid r3,1b 87 addik r5,r5,1 /* delay slot */ 88 89 addik r3,r3,-1 /* for break on len */ 902: 91 rsubk r3,r3,r6 923: 93 rtsd r15,8 94 nop 95 .size __strnlen_user, . - __strnlen_user 96 97 .section .fixup,"ax" 984: 99 brid 3b 100 addk r3,r0,r0 101 102 .section __ex_table,"a" 103 .word 1b,4b 104 105/* 106 * int __copy_tofrom_user(char *to, char *from, int len) 107 * Return: 108 * 0 on success 109 * number of not copied bytes on error 110 */ 111 .text 112.globl __copy_tofrom_user; 113.type __copy_tofrom_user, @function 114.align 4; 115__copy_tofrom_user: 116 /* 117 * r5 - to 118 * r6 - from 119 * r7, r3 - count 120 * r4 - tempval 121 */ 122 beqid r7, 0f /* zero size is not likely */ 123 andi r3, r7, 0x3 /* filter add count */ 124 bneid r3, 4f /* if is odd value then byte copying */ 125 or r3, r5, r6 /* find if is any to/from unaligned */ 126 andi r3, r3, 0x3 /* mask unaligned */ 127 bneid r3, 1f /* it is unaligned -> then jump */ 128 or r3, r0, r0 129 130/* at least one 4 byte copy */ 1315: lw r4, r6, r3 1326: sw r4, r5, r3 133 addik r7, r7, -4 134 bneid r7, 5b 135 addik r3, r3, 4 136 addik r3, r7, 0 137 rtsd r15, 8 138 nop 139 140 .section __ex_table,"a" 141 .word 5b, 0f; 142 .word 6b, 0f; 143 .text 144 1454: or r3, r0, r0 1461: lbu r4,r6,r3 1472: sb r4,r5,r3 148 addik r7,r7,-1 149 bneid r7,1b 150 addik r3,r3,1 /* delay slot */ 1510: 152 addik r3,r7,0 153 rtsd r15,8 154 nop 155 .size __copy_tofrom_user, . - __copy_tofrom_user 156 157 .section __ex_table,"a" 158 .word 1b, 0b; 159 .word 2b, 0b; 160 .text 161