0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017 #define __NO_FORTIFY
0018 #include <linux/types.h>
0019 #include <linux/string.h>
0020 #include <linux/ctype.h>
0021 #include <linux/kernel.h>
0022 #include <linux/export.h>
0023 #include <linux/bug.h>
0024 #include <linux/errno.h>
0025 #include <linux/slab.h>
0026
0027 #include <asm/unaligned.h>
0028 #include <asm/byteorder.h>
0029 #include <asm/word-at-a-time.h>
0030 #include <asm/page.h>
0031
0032 #ifndef __HAVE_ARCH_STRNCASECMP
0033
0034
0035
0036
0037
0038
0039 int strncasecmp(const char *s1, const char *s2, size_t len)
0040 {
0041
0042 unsigned char c1, c2;
0043
0044 if (!len)
0045 return 0;
0046
0047 do {
0048 c1 = *s1++;
0049 c2 = *s2++;
0050 if (!c1 || !c2)
0051 break;
0052 if (c1 == c2)
0053 continue;
0054 c1 = tolower(c1);
0055 c2 = tolower(c2);
0056 if (c1 != c2)
0057 break;
0058 } while (--len);
0059 return (int)c1 - (int)c2;
0060 }
0061 EXPORT_SYMBOL(strncasecmp);
0062 #endif
0063
0064 #ifndef __HAVE_ARCH_STRCASECMP
0065 int strcasecmp(const char *s1, const char *s2)
0066 {
0067 int c1, c2;
0068
0069 do {
0070 c1 = tolower(*s1++);
0071 c2 = tolower(*s2++);
0072 } while (c1 == c2 && c1 != 0);
0073 return c1 - c2;
0074 }
0075 EXPORT_SYMBOL(strcasecmp);
0076 #endif
0077
0078 #ifndef __HAVE_ARCH_STRCPY
0079
0080
0081
0082
0083
0084 char *strcpy(char *dest, const char *src)
0085 {
0086 char *tmp = dest;
0087
0088 while ((*dest++ = *src++) != '\0')
0089 ;
0090 return tmp;
0091 }
0092 EXPORT_SYMBOL(strcpy);
0093 #endif
0094
0095 #ifndef __HAVE_ARCH_STRNCPY
0096
0097
0098
0099
0100
0101
0102
0103
0104
0105
0106
0107
0108
0109 char *strncpy(char *dest, const char *src, size_t count)
0110 {
0111 char *tmp = dest;
0112
0113 while (count) {
0114 if ((*tmp = *src) != 0)
0115 src++;
0116 tmp++;
0117 count--;
0118 }
0119 return dest;
0120 }
0121 EXPORT_SYMBOL(strncpy);
0122 #endif
0123
0124 #ifndef __HAVE_ARCH_STRLCPY
0125
0126
0127
0128
0129
0130
0131
0132
0133
0134
0135
0136 size_t strlcpy(char *dest, const char *src, size_t size)
0137 {
0138 size_t ret = strlen(src);
0139
0140 if (size) {
0141 size_t len = (ret >= size) ? size - 1 : ret;
0142 memcpy(dest, src, len);
0143 dest[len] = '\0';
0144 }
0145 return ret;
0146 }
0147 EXPORT_SYMBOL(strlcpy);
0148 #endif
0149
0150 #ifndef __HAVE_ARCH_STRSCPY
0151
0152
0153
0154
0155
0156
0157
0158
0159
0160
0161
0162
0163
0164
0165
0166
0167
0168
0169
0170
0171
0172
0173
0174
0175 ssize_t strscpy(char *dest, const char *src, size_t count)
0176 {
0177 const struct word_at_a_time constants = WORD_AT_A_TIME_CONSTANTS;
0178 size_t max = count;
0179 long res = 0;
0180
0181 if (count == 0 || WARN_ON_ONCE(count > INT_MAX))
0182 return -E2BIG;
0183
0184 #ifdef CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS
0185
0186
0187
0188
0189 if ((long)src & (sizeof(long) - 1)) {
0190 size_t limit = PAGE_SIZE - ((long)src & (PAGE_SIZE - 1));
0191 if (limit < max)
0192 max = limit;
0193 }
0194 #else
0195
0196 if (((long) dest | (long) src) & (sizeof(long) - 1))
0197 max = 0;
0198 #endif
0199
0200 while (max >= sizeof(unsigned long)) {
0201 unsigned long c, data;
0202
0203 c = read_word_at_a_time(src+res);
0204 if (has_zero(c, &data, &constants)) {
0205 data = prep_zero_mask(c, data, &constants);
0206 data = create_zero_mask(data);
0207 *(unsigned long *)(dest+res) = c & zero_bytemask(data);
0208 return res + find_zero(data);
0209 }
0210 *(unsigned long *)(dest+res) = c;
0211 res += sizeof(unsigned long);
0212 count -= sizeof(unsigned long);
0213 max -= sizeof(unsigned long);
0214 }
0215
0216 while (count) {
0217 char c;
0218
0219 c = src[res];
0220 dest[res] = c;
0221 if (!c)
0222 return res;
0223 res++;
0224 count--;
0225 }
0226
0227
0228 if (res)
0229 dest[res-1] = '\0';
0230
0231 return -E2BIG;
0232 }
0233 EXPORT_SYMBOL(strscpy);
0234 #endif
0235
0236
0237
0238
0239
0240
0241
0242
0243
0244
0245
0246
0247
0248
0249
0250
0251 char *stpcpy(char *__restrict__ dest, const char *__restrict__ src);
0252 char *stpcpy(char *__restrict__ dest, const char *__restrict__ src)
0253 {
0254 while ((*dest++ = *src++) != '\0')
0255 ;
0256 return --dest;
0257 }
0258 EXPORT_SYMBOL(stpcpy);
0259
0260 #ifndef __HAVE_ARCH_STRCAT
0261
0262
0263
0264
0265
0266 char *strcat(char *dest, const char *src)
0267 {
0268 char *tmp = dest;
0269
0270 while (*dest)
0271 dest++;
0272 while ((*dest++ = *src++) != '\0')
0273 ;
0274 return tmp;
0275 }
0276 EXPORT_SYMBOL(strcat);
0277 #endif
0278
0279 #ifndef __HAVE_ARCH_STRNCAT
0280
0281
0282
0283
0284
0285
0286
0287
0288
0289 char *strncat(char *dest, const char *src, size_t count)
0290 {
0291 char *tmp = dest;
0292
0293 if (count) {
0294 while (*dest)
0295 dest++;
0296 while ((*dest++ = *src++) != 0) {
0297 if (--count == 0) {
0298 *dest = '\0';
0299 break;
0300 }
0301 }
0302 }
0303 return tmp;
0304 }
0305 EXPORT_SYMBOL(strncat);
0306 #endif
0307
0308 #ifndef __HAVE_ARCH_STRLCAT
0309
0310
0311
0312
0313
0314
0315 size_t strlcat(char *dest, const char *src, size_t count)
0316 {
0317 size_t dsize = strlen(dest);
0318 size_t len = strlen(src);
0319 size_t res = dsize + len;
0320
0321
0322 BUG_ON(dsize >= count);
0323
0324 dest += dsize;
0325 count -= dsize;
0326 if (len >= count)
0327 len = count-1;
0328 memcpy(dest, src, len);
0329 dest[len] = 0;
0330 return res;
0331 }
0332 EXPORT_SYMBOL(strlcat);
0333 #endif
0334
0335 #ifndef __HAVE_ARCH_STRCMP
0336
0337
0338
0339
0340
0341 int strcmp(const char *cs, const char *ct)
0342 {
0343 unsigned char c1, c2;
0344
0345 while (1) {
0346 c1 = *cs++;
0347 c2 = *ct++;
0348 if (c1 != c2)
0349 return c1 < c2 ? -1 : 1;
0350 if (!c1)
0351 break;
0352 }
0353 return 0;
0354 }
0355 EXPORT_SYMBOL(strcmp);
0356 #endif
0357
0358 #ifndef __HAVE_ARCH_STRNCMP
0359
0360
0361
0362
0363
0364
0365 int strncmp(const char *cs, const char *ct, size_t count)
0366 {
0367 unsigned char c1, c2;
0368
0369 while (count) {
0370 c1 = *cs++;
0371 c2 = *ct++;
0372 if (c1 != c2)
0373 return c1 < c2 ? -1 : 1;
0374 if (!c1)
0375 break;
0376 count--;
0377 }
0378 return 0;
0379 }
0380 EXPORT_SYMBOL(strncmp);
0381 #endif
0382
0383 #ifndef __HAVE_ARCH_STRCHR
0384
0385
0386
0387
0388
0389
0390
0391
0392 char *strchr(const char *s, int c)
0393 {
0394 for (; *s != (char)c; ++s)
0395 if (*s == '\0')
0396 return NULL;
0397 return (char *)s;
0398 }
0399 EXPORT_SYMBOL(strchr);
0400 #endif
0401
0402 #ifndef __HAVE_ARCH_STRCHRNUL
0403
0404
0405
0406
0407
0408
0409
0410
0411 char *strchrnul(const char *s, int c)
0412 {
0413 while (*s && *s != (char)c)
0414 s++;
0415 return (char *)s;
0416 }
0417 EXPORT_SYMBOL(strchrnul);
0418 #endif
0419
0420
0421
0422
0423
0424
0425
0426
0427
0428
0429
0430 char *strnchrnul(const char *s, size_t count, int c)
0431 {
0432 while (count-- && *s && *s != (char)c)
0433 s++;
0434 return (char *)s;
0435 }
0436
0437 #ifndef __HAVE_ARCH_STRRCHR
0438
0439
0440
0441
0442
0443 char *strrchr(const char *s, int c)
0444 {
0445 const char *last = NULL;
0446 do {
0447 if (*s == (char)c)
0448 last = s;
0449 } while (*s++);
0450 return (char *)last;
0451 }
0452 EXPORT_SYMBOL(strrchr);
0453 #endif
0454
0455 #ifndef __HAVE_ARCH_STRNCHR
0456
0457
0458
0459
0460
0461
0462
0463
0464
0465 char *strnchr(const char *s, size_t count, int c)
0466 {
0467 while (count--) {
0468 if (*s == (char)c)
0469 return (char *)s;
0470 if (*s++ == '\0')
0471 break;
0472 }
0473 return NULL;
0474 }
0475 EXPORT_SYMBOL(strnchr);
0476 #endif
0477
0478 #ifndef __HAVE_ARCH_STRLEN
0479
0480
0481
0482
0483 size_t strlen(const char *s)
0484 {
0485 const char *sc;
0486
0487 for (sc = s; *sc != '\0'; ++sc)
0488 ;
0489 return sc - s;
0490 }
0491 EXPORT_SYMBOL(strlen);
0492 #endif
0493
0494 #ifndef __HAVE_ARCH_STRNLEN
0495
0496
0497
0498
0499
0500 size_t strnlen(const char *s, size_t count)
0501 {
0502 const char *sc;
0503
0504 for (sc = s; count-- && *sc != '\0'; ++sc)
0505 ;
0506 return sc - s;
0507 }
0508 EXPORT_SYMBOL(strnlen);
0509 #endif
0510
0511 #ifndef __HAVE_ARCH_STRSPN
0512
0513
0514
0515
0516
0517 size_t strspn(const char *s, const char *accept)
0518 {
0519 const char *p;
0520
0521 for (p = s; *p != '\0'; ++p) {
0522 if (!strchr(accept, *p))
0523 break;
0524 }
0525 return p - s;
0526 }
0527 EXPORT_SYMBOL(strspn);
0528 #endif
0529
0530 #ifndef __HAVE_ARCH_STRCSPN
0531
0532
0533
0534
0535
0536 size_t strcspn(const char *s, const char *reject)
0537 {
0538 const char *p;
0539
0540 for (p = s; *p != '\0'; ++p) {
0541 if (strchr(reject, *p))
0542 break;
0543 }
0544 return p - s;
0545 }
0546 EXPORT_SYMBOL(strcspn);
0547 #endif
0548
0549 #ifndef __HAVE_ARCH_STRPBRK
0550
0551
0552
0553
0554
0555 char *strpbrk(const char *cs, const char *ct)
0556 {
0557 const char *sc1, *sc2;
0558
0559 for (sc1 = cs; *sc1 != '\0'; ++sc1) {
0560 for (sc2 = ct; *sc2 != '\0'; ++sc2) {
0561 if (*sc1 == *sc2)
0562 return (char *)sc1;
0563 }
0564 }
0565 return NULL;
0566 }
0567 EXPORT_SYMBOL(strpbrk);
0568 #endif
0569
0570 #ifndef __HAVE_ARCH_STRSEP
0571
0572
0573
0574
0575
0576
0577
0578
0579
0580
0581
0582 char *strsep(char **s, const char *ct)
0583 {
0584 char *sbegin = *s;
0585 char *end;
0586
0587 if (sbegin == NULL)
0588 return NULL;
0589
0590 end = strpbrk(sbegin, ct);
0591 if (end)
0592 *end++ = '\0';
0593 *s = end;
0594 return sbegin;
0595 }
0596 EXPORT_SYMBOL(strsep);
0597 #endif
0598
0599 #ifndef __HAVE_ARCH_MEMSET
0600
0601
0602
0603
0604
0605
0606
0607
0608 void *memset(void *s, int c, size_t count)
0609 {
0610 char *xs = s;
0611
0612 while (count--)
0613 *xs++ = c;
0614 return s;
0615 }
0616 EXPORT_SYMBOL(memset);
0617 #endif
0618
0619 #ifndef __HAVE_ARCH_MEMSET16
0620
0621
0622
0623
0624
0625
0626
0627
0628
0629
0630 void *memset16(uint16_t *s, uint16_t v, size_t count)
0631 {
0632 uint16_t *xs = s;
0633
0634 while (count--)
0635 *xs++ = v;
0636 return s;
0637 }
0638 EXPORT_SYMBOL(memset16);
0639 #endif
0640
0641 #ifndef __HAVE_ARCH_MEMSET32
0642
0643
0644
0645
0646
0647
0648
0649
0650
0651
0652 void *memset32(uint32_t *s, uint32_t v, size_t count)
0653 {
0654 uint32_t *xs = s;
0655
0656 while (count--)
0657 *xs++ = v;
0658 return s;
0659 }
0660 EXPORT_SYMBOL(memset32);
0661 #endif
0662
0663 #ifndef __HAVE_ARCH_MEMSET64
0664
0665
0666
0667
0668
0669
0670
0671
0672
0673
0674 void *memset64(uint64_t *s, uint64_t v, size_t count)
0675 {
0676 uint64_t *xs = s;
0677
0678 while (count--)
0679 *xs++ = v;
0680 return s;
0681 }
0682 EXPORT_SYMBOL(memset64);
0683 #endif
0684
0685 #ifndef __HAVE_ARCH_MEMCPY
0686
0687
0688
0689
0690
0691
0692
0693
0694
0695 void *memcpy(void *dest, const void *src, size_t count)
0696 {
0697 char *tmp = dest;
0698 const char *s = src;
0699
0700 while (count--)
0701 *tmp++ = *s++;
0702 return dest;
0703 }
0704 EXPORT_SYMBOL(memcpy);
0705 #endif
0706
0707 #ifndef __HAVE_ARCH_MEMMOVE
0708
0709
0710
0711
0712
0713
0714
0715
0716 void *memmove(void *dest, const void *src, size_t count)
0717 {
0718 char *tmp;
0719 const char *s;
0720
0721 if (dest <= src) {
0722 tmp = dest;
0723 s = src;
0724 while (count--)
0725 *tmp++ = *s++;
0726 } else {
0727 tmp = dest;
0728 tmp += count;
0729 s = src;
0730 s += count;
0731 while (count--)
0732 *--tmp = *--s;
0733 }
0734 return dest;
0735 }
0736 EXPORT_SYMBOL(memmove);
0737 #endif
0738
0739 #ifndef __HAVE_ARCH_MEMCMP
0740
0741
0742
0743
0744
0745
0746 #undef memcmp
0747 __visible int memcmp(const void *cs, const void *ct, size_t count)
0748 {
0749 const unsigned char *su1, *su2;
0750 int res = 0;
0751
0752 #ifdef CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS
0753 if (count >= sizeof(unsigned long)) {
0754 const unsigned long *u1 = cs;
0755 const unsigned long *u2 = ct;
0756 do {
0757 if (get_unaligned(u1) != get_unaligned(u2))
0758 break;
0759 u1++;
0760 u2++;
0761 count -= sizeof(unsigned long);
0762 } while (count >= sizeof(unsigned long));
0763 cs = u1;
0764 ct = u2;
0765 }
0766 #endif
0767 for (su1 = cs, su2 = ct; 0 < count; ++su1, ++su2, count--)
0768 if ((res = *su1 - *su2) != 0)
0769 break;
0770 return res;
0771 }
0772 EXPORT_SYMBOL(memcmp);
0773 #endif
0774
0775 #ifndef __HAVE_ARCH_BCMP
0776
0777
0778
0779
0780
0781
0782
0783
0784
0785
0786
0787 int bcmp(const void *a, const void *b, size_t len)
0788 {
0789 return memcmp(a, b, len);
0790 }
0791 EXPORT_SYMBOL(bcmp);
0792 #endif
0793
0794 #ifndef __HAVE_ARCH_MEMSCAN
0795
0796
0797
0798
0799
0800
0801
0802
0803
0804 void *memscan(void *addr, int c, size_t size)
0805 {
0806 unsigned char *p = addr;
0807
0808 while (size) {
0809 if (*p == (unsigned char)c)
0810 return (void *)p;
0811 p++;
0812 size--;
0813 }
0814 return (void *)p;
0815 }
0816 EXPORT_SYMBOL(memscan);
0817 #endif
0818
0819 #ifndef __HAVE_ARCH_STRSTR
0820
0821
0822
0823
0824
0825 char *strstr(const char *s1, const char *s2)
0826 {
0827 size_t l1, l2;
0828
0829 l2 = strlen(s2);
0830 if (!l2)
0831 return (char *)s1;
0832 l1 = strlen(s1);
0833 while (l1 >= l2) {
0834 l1--;
0835 if (!memcmp(s1, s2, l2))
0836 return (char *)s1;
0837 s1++;
0838 }
0839 return NULL;
0840 }
0841 EXPORT_SYMBOL(strstr);
0842 #endif
0843
0844 #ifndef __HAVE_ARCH_STRNSTR
0845
0846
0847
0848
0849
0850
0851 char *strnstr(const char *s1, const char *s2, size_t len)
0852 {
0853 size_t l2;
0854
0855 l2 = strlen(s2);
0856 if (!l2)
0857 return (char *)s1;
0858 while (len >= l2) {
0859 len--;
0860 if (!memcmp(s1, s2, l2))
0861 return (char *)s1;
0862 s1++;
0863 }
0864 return NULL;
0865 }
0866 EXPORT_SYMBOL(strnstr);
0867 #endif
0868
0869 #ifndef __HAVE_ARCH_MEMCHR
0870
0871
0872
0873
0874
0875
0876
0877
0878
0879 void *memchr(const void *s, int c, size_t n)
0880 {
0881 const unsigned char *p = s;
0882 while (n-- != 0) {
0883 if ((unsigned char)c == *p++) {
0884 return (void *)(p - 1);
0885 }
0886 }
0887 return NULL;
0888 }
0889 EXPORT_SYMBOL(memchr);
0890 #endif
0891
0892 static void *check_bytes8(const u8 *start, u8 value, unsigned int bytes)
0893 {
0894 while (bytes) {
0895 if (*start != value)
0896 return (void *)start;
0897 start++;
0898 bytes--;
0899 }
0900 return NULL;
0901 }
0902
0903
0904
0905
0906
0907
0908
0909
0910
0911
0912 void *memchr_inv(const void *start, int c, size_t bytes)
0913 {
0914 u8 value = c;
0915 u64 value64;
0916 unsigned int words, prefix;
0917
0918 if (bytes <= 16)
0919 return check_bytes8(start, value, bytes);
0920
0921 value64 = value;
0922 #if defined(CONFIG_ARCH_HAS_FAST_MULTIPLIER) && BITS_PER_LONG == 64
0923 value64 *= 0x0101010101010101ULL;
0924 #elif defined(CONFIG_ARCH_HAS_FAST_MULTIPLIER)
0925 value64 *= 0x01010101;
0926 value64 |= value64 << 32;
0927 #else
0928 value64 |= value64 << 8;
0929 value64 |= value64 << 16;
0930 value64 |= value64 << 32;
0931 #endif
0932
0933 prefix = (unsigned long)start % 8;
0934 if (prefix) {
0935 u8 *r;
0936
0937 prefix = 8 - prefix;
0938 r = check_bytes8(start, value, prefix);
0939 if (r)
0940 return r;
0941 start += prefix;
0942 bytes -= prefix;
0943 }
0944
0945 words = bytes / 8;
0946
0947 while (words) {
0948 if (*(u64 *)start != value64)
0949 return check_bytes8(start, value, 8);
0950 start += 8;
0951 words--;
0952 }
0953
0954 return check_bytes8(start, value, bytes % 8);
0955 }
0956 EXPORT_SYMBOL(memchr_inv);