1 // SPDX-License-Identifier: GPL-2.0 2 /* 3 * linux/lib/string.c 4 * 5 * Copyright (C) 1991, 1992 Linus Torvalds 6 */ 7 8 /* 9 * This file should be used only for "library" routines that may have 10 * alternative implementations on specific architectures (generally 11 * found in <asm-xx/string.h>), or get overloaded by FORTIFY_SOURCE. 12 * (Specifically, this file is built with __NO_FORTIFY.) 13 * 14 * Other helper functions should live in string_helpers.c. 15 */ 16 17 #define __NO_FORTIFY 18 #include <linux/bits.h> 19 #include <linux/bug.h> 20 #include <linux/ctype.h> 21 #include <linux/errno.h> 22 #include <linux/limits.h> 23 #include <linux/linkage.h> 24 #include <linux/stddef.h> 25 #include <linux/string.h> 26 #include <linux/types.h> 27 28 #include <asm/page.h> 29 #include <asm/rwonce.h> 30 #include <asm/unaligned.h> 31 #include <asm/word-at-a-time.h> 32 33 #ifndef __HAVE_ARCH_STRNCASECMP 34 /** 35 * strncasecmp - Case insensitive, length-limited string comparison 36 * @s1: One string 37 * @s2: The other string 38 * @len: the maximum number of characters to compare 39 */ 40 int strncasecmp(const char *s1, const char *s2, size_t len) 41 { 42 /* Yes, Virginia, it had better be unsigned */ 43 unsigned char c1, c2; 44 45 if (!len) 46 return 0; 47 48 do { 49 c1 = *s1++; 50 c2 = *s2++; 51 if (!c1 || !c2) 52 break; 53 if (c1 == c2) 54 continue; 55 c1 = tolower(c1); 56 c2 = tolower(c2); 57 if (c1 != c2) 58 break; 59 } while (--len); 60 return (int)c1 - (int)c2; 61 } 62 EXPORT_SYMBOL(strncasecmp); 63 #endif 64 65 #ifndef __HAVE_ARCH_STRCASECMP 66 int strcasecmp(const char *s1, const char *s2) 67 { 68 int c1, c2; 69 70 do { 71 c1 = tolower(*s1++); 72 c2 = tolower(*s2++); 73 } while (c1 == c2 && c1 != 0); 74 return c1 - c2; 75 } 76 EXPORT_SYMBOL(strcasecmp); 77 #endif 78 79 #ifndef __HAVE_ARCH_STRCPY 80 char *strcpy(char *dest, const char *src) 81 { 82 char *tmp = dest; 83 84 while ((*dest++ = *src++) != '\0') 85 /* nothing */; 86 return tmp; 87 } 88 EXPORT_SYMBOL(strcpy); 89 #endif 90 91 #ifndef __HAVE_ARCH_STRNCPY 92 char *strncpy(char *dest, const char *src, size_t count) 93 { 94 char *tmp = dest; 95 96 while (count) { 97 if ((*tmp = *src) != 0) 98 src++; 99 tmp++; 100 count--; 101 } 102 return dest; 103 } 104 EXPORT_SYMBOL(strncpy); 105 #endif 106 107 #ifndef __HAVE_ARCH_STRSCPY 108 ssize_t strscpy(char *dest, const char *src, size_t count) 109 { 110 const struct word_at_a_time constants = WORD_AT_A_TIME_CONSTANTS; 111 size_t max = count; 112 long res = 0; 113 114 if (count == 0 || WARN_ON_ONCE(count > INT_MAX)) 115 return -E2BIG; 116 117 #ifdef CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS 118 /* 119 * If src is unaligned, don't cross a page boundary, 120 * since we don't know if the next page is mapped. 121 */ 122 if ((long)src & (sizeof(long) - 1)) { 123 size_t limit = PAGE_SIZE - ((long)src & (PAGE_SIZE - 1)); 124 if (limit < max) 125 max = limit; 126 } 127 #else 128 /* If src or dest is unaligned, don't do word-at-a-time. */ 129 if (((long) dest | (long) src) & (sizeof(long) - 1)) 130 max = 0; 131 #endif 132 133 /* 134 * read_word_at_a_time() below may read uninitialized bytes after the 135 * trailing zero and use them in comparisons. Disable this optimization 136 * under KMSAN to prevent false positive reports. 137 */ 138 if (IS_ENABLED(CONFIG_KMSAN)) 139 max = 0; 140 141 while (max >= sizeof(unsigned long)) { 142 unsigned long c, data; 143 144 c = read_word_at_a_time(src+res); 145 if (has_zero(c, &data, &constants)) { 146 data = prep_zero_mask(c, data, &constants); 147 data = create_zero_mask(data); 148 *(unsigned long *)(dest+res) = c & zero_bytemask(data); 149 return res + find_zero(data); 150 } 151 *(unsigned long *)(dest+res) = c; 152 res += sizeof(unsigned long); 153 count -= sizeof(unsigned long); 154 max -= sizeof(unsigned long); 155 } 156 157 while (count) { 158 char c; 159 160 c = src[res]; 161 dest[res] = c; 162 if (!c) 163 return res; 164 res++; 165 count--; 166 } 167 168 /* Hit buffer length without finding a NUL; force NUL-termination. */ 169 if (res) 170 dest[res-1] = '\0'; 171 172 return -E2BIG; 173 } 174 EXPORT_SYMBOL(strscpy); 175 #endif 176 177 /** 178 * stpcpy - copy a string from src to dest returning a pointer to the new end 179 * of dest, including src's %NUL-terminator. May overrun dest. 180 * @dest: pointer to end of string being copied into. Must be large enough 181 * to receive copy. 182 * @src: pointer to the beginning of string being copied from. Must not overlap 183 * dest. 184 * 185 * stpcpy differs from strcpy in a key way: the return value is a pointer 186 * to the new %NUL-terminating character in @dest. (For strcpy, the return 187 * value is a pointer to the start of @dest). This interface is considered 188 * unsafe as it doesn't perform bounds checking of the inputs. As such it's 189 * not recommended for usage. Instead, its definition is provided in case 190 * the compiler lowers other libcalls to stpcpy. 191 */ 192 char *stpcpy(char *__restrict__ dest, const char *__restrict__ src); 193 char *stpcpy(char *__restrict__ dest, const char *__restrict__ src) 194 { 195 while ((*dest++ = *src++) != '\0') 196 /* nothing */; 197 return --dest; 198 } 199 EXPORT_SYMBOL(stpcpy); 200 201 #ifndef __HAVE_ARCH_STRCAT 202 char *strcat(char *dest, const char *src) 203 { 204 char *tmp = dest; 205 206 while (*dest) 207 dest++; 208 while ((*dest++ = *src++) != '\0') 209 ; 210 return tmp; 211 } 212 EXPORT_SYMBOL(strcat); 213 #endif 214 215 #ifndef __HAVE_ARCH_STRNCAT 216 char *strncat(char *dest, const char *src, size_t count) 217 { 218 char *tmp = dest; 219 220 if (count) { 221 while (*dest) 222 dest++; 223 while ((*dest++ = *src++) != 0) { 224 if (--count == 0) { 225 *dest = '\0'; 226 break; 227 } 228 } 229 } 230 return tmp; 231 } 232 EXPORT_SYMBOL(strncat); 233 #endif 234 235 #ifndef __HAVE_ARCH_STRLCAT 236 size_t strlcat(char *dest, const char *src, size_t count) 237 { 238 size_t dsize = strlen(dest); 239 size_t len = strlen(src); 240 size_t res = dsize + len; 241 242 /* This would be a bug */ 243 BUG_ON(dsize >= count); 244 245 dest += dsize; 246 count -= dsize; 247 if (len >= count) 248 len = count-1; 249 __builtin_memcpy(dest, src, len); 250 dest[len] = 0; 251 return res; 252 } 253 EXPORT_SYMBOL(strlcat); 254 #endif 255 256 #ifndef __HAVE_ARCH_STRCMP 257 /** 258 * strcmp - Compare two strings 259 * @cs: One string 260 * @ct: Another string 261 */ 262 int strcmp(const char *cs, const char *ct) 263 { 264 unsigned char c1, c2; 265 266 while (1) { 267 c1 = *cs++; 268 c2 = *ct++; 269 if (c1 != c2) 270 return c1 < c2 ? -1 : 1; 271 if (!c1) 272 break; 273 } 274 return 0; 275 } 276 EXPORT_SYMBOL(strcmp); 277 #endif 278 279 #ifndef __HAVE_ARCH_STRNCMP 280 /** 281 * strncmp - Compare two length-limited strings 282 * @cs: One string 283 * @ct: Another string 284 * @count: The maximum number of bytes to compare 285 */ 286 int strncmp(const char *cs, const char *ct, size_t count) 287 { 288 unsigned char c1, c2; 289 290 while (count) { 291 c1 = *cs++; 292 c2 = *ct++; 293 if (c1 != c2) 294 return c1 < c2 ? -1 : 1; 295 if (!c1) 296 break; 297 count--; 298 } 299 return 0; 300 } 301 EXPORT_SYMBOL(strncmp); 302 #endif 303 304 #ifndef __HAVE_ARCH_STRCHR 305 /** 306 * strchr - Find the first occurrence of a character in a string 307 * @s: The string to be searched 308 * @c: The character to search for 309 * 310 * Note that the %NUL-terminator is considered part of the string, and can 311 * be searched for. 312 */ 313 char *strchr(const char *s, int c) 314 { 315 for (; *s != (char)c; ++s) 316 if (*s == '\0') 317 return NULL; 318 return (char *)s; 319 } 320 EXPORT_SYMBOL(strchr); 321 #endif 322 323 #ifndef __HAVE_ARCH_STRCHRNUL 324 /** 325 * strchrnul - Find and return a character in a string, or end of string 326 * @s: The string to be searched 327 * @c: The character to search for 328 * 329 * Returns pointer to first occurrence of 'c' in s. If c is not found, then 330 * return a pointer to the null byte at the end of s. 331 */ 332 char *strchrnul(const char *s, int c) 333 { 334 while (*s && *s != (char)c) 335 s++; 336 return (char *)s; 337 } 338 EXPORT_SYMBOL(strchrnul); 339 #endif 340 341 /** 342 * strnchrnul - Find and return a character in a length limited string, 343 * or end of string 344 * @s: The string to be searched 345 * @count: The number of characters to be searched 346 * @c: The character to search for 347 * 348 * Returns pointer to the first occurrence of 'c' in s. If c is not found, 349 * then return a pointer to the last character of the string. 350 */ 351 char *strnchrnul(const char *s, size_t count, int c) 352 { 353 while (count-- && *s && *s != (char)c) 354 s++; 355 return (char *)s; 356 } 357 358 #ifndef __HAVE_ARCH_STRRCHR 359 /** 360 * strrchr - Find the last occurrence of a character in a string 361 * @s: The string to be searched 362 * @c: The character to search for 363 */ 364 char *strrchr(const char *s, int c) 365 { 366 const char *last = NULL; 367 do { 368 if (*s == (char)c) 369 last = s; 370 } while (*s++); 371 return (char *)last; 372 } 373 EXPORT_SYMBOL(strrchr); 374 #endif 375 376 #ifndef __HAVE_ARCH_STRNCHR 377 /** 378 * strnchr - Find a character in a length limited string 379 * @s: The string to be searched 380 * @count: The number of characters to be searched 381 * @c: The character to search for 382 * 383 * Note that the %NUL-terminator is considered part of the string, and can 384 * be searched for. 385 */ 386 char *strnchr(const char *s, size_t count, int c) 387 { 388 while (count--) { 389 if (*s == (char)c) 390 return (char *)s; 391 if (*s++ == '\0') 392 break; 393 } 394 return NULL; 395 } 396 EXPORT_SYMBOL(strnchr); 397 #endif 398 399 #ifndef __HAVE_ARCH_STRLEN 400 size_t strlen(const char *s) 401 { 402 const char *sc; 403 404 for (sc = s; *sc != '\0'; ++sc) 405 /* nothing */; 406 return sc - s; 407 } 408 EXPORT_SYMBOL(strlen); 409 #endif 410 411 #ifndef __HAVE_ARCH_STRNLEN 412 size_t strnlen(const char *s, size_t count) 413 { 414 const char *sc; 415 416 for (sc = s; count-- && *sc != '\0'; ++sc) 417 /* nothing */; 418 return sc - s; 419 } 420 EXPORT_SYMBOL(strnlen); 421 #endif 422 423 #ifndef __HAVE_ARCH_STRSPN 424 /** 425 * strspn - Calculate the length of the initial substring of @s which only contain letters in @accept 426 * @s: The string to be searched 427 * @accept: The string to search for 428 */ 429 size_t strspn(const char *s, const char *accept) 430 { 431 const char *p; 432 433 for (p = s; *p != '\0'; ++p) { 434 if (!strchr(accept, *p)) 435 break; 436 } 437 return p - s; 438 } 439 EXPORT_SYMBOL(strspn); 440 #endif 441 442 #ifndef __HAVE_ARCH_STRCSPN 443 /** 444 * strcspn - Calculate the length of the initial substring of @s which does not contain letters in @reject 445 * @s: The string to be searched 446 * @reject: The string to avoid 447 */ 448 size_t strcspn(const char *s, const char *reject) 449 { 450 const char *p; 451 452 for (p = s; *p != '\0'; ++p) { 453 if (strchr(reject, *p)) 454 break; 455 } 456 return p - s; 457 } 458 EXPORT_SYMBOL(strcspn); 459 #endif 460 461 #ifndef __HAVE_ARCH_STRPBRK 462 /** 463 * strpbrk - Find the first occurrence of a set of characters 464 * @cs: The string to be searched 465 * @ct: The characters to search for 466 */ 467 char *strpbrk(const char *cs, const char *ct) 468 { 469 const char *sc; 470 471 for (sc = cs; *sc != '\0'; ++sc) { 472 if (strchr(ct, *sc)) 473 return (char *)sc; 474 } 475 return NULL; 476 } 477 EXPORT_SYMBOL(strpbrk); 478 #endif 479 480 #ifndef __HAVE_ARCH_STRSEP 481 /** 482 * strsep - Split a string into tokens 483 * @s: The string to be searched 484 * @ct: The characters to search for 485 * 486 * strsep() updates @s to point after the token, ready for the next call. 487 * 488 * It returns empty tokens, too, behaving exactly like the libc function 489 * of that name. In fact, it was stolen from glibc2 and de-fancy-fied. 490 * Same semantics, slimmer shape. ;) 491 */ 492 char *strsep(char **s, const char *ct) 493 { 494 char *sbegin = *s; 495 char *end; 496 497 if (sbegin == NULL) 498 return NULL; 499 500 end = strpbrk(sbegin, ct); 501 if (end) 502 *end++ = '\0'; 503 *s = end; 504 return sbegin; 505 } 506 EXPORT_SYMBOL(strsep); 507 #endif 508 509 #ifndef __HAVE_ARCH_MEMSET 510 /** 511 * memset - Fill a region of memory with the given value 512 * @s: Pointer to the start of the area. 513 * @c: The byte to fill the area with 514 * @count: The size of the area. 515 * 516 * Do not use memset() to access IO space, use memset_io() instead. 517 */ 518 void *memset(void *s, int c, size_t count) 519 { 520 char *xs = s; 521 522 while (count--) 523 *xs++ = c; 524 return s; 525 } 526 EXPORT_SYMBOL(memset); 527 #endif 528 529 #ifndef __HAVE_ARCH_MEMSET16 530 /** 531 * memset16() - Fill a memory area with a uint16_t 532 * @s: Pointer to the start of the area. 533 * @v: The value to fill the area with 534 * @count: The number of values to store 535 * 536 * Differs from memset() in that it fills with a uint16_t instead 537 * of a byte. Remember that @count is the number of uint16_ts to 538 * store, not the number of bytes. 539 */ 540 void *memset16(uint16_t *s, uint16_t v, size_t count) 541 { 542 uint16_t *xs = s; 543 544 while (count--) 545 *xs++ = v; 546 return s; 547 } 548 EXPORT_SYMBOL(memset16); 549 #endif 550 551 #ifndef __HAVE_ARCH_MEMSET32 552 /** 553 * memset32() - Fill a memory area with a uint32_t 554 * @s: Pointer to the start of the area. 555 * @v: The value to fill the area with 556 * @count: The number of values to store 557 * 558 * Differs from memset() in that it fills with a uint32_t instead 559 * of a byte. Remember that @count is the number of uint32_ts to 560 * store, not the number of bytes. 561 */ 562 void *memset32(uint32_t *s, uint32_t v, size_t count) 563 { 564 uint32_t *xs = s; 565 566 while (count--) 567 *xs++ = v; 568 return s; 569 } 570 EXPORT_SYMBOL(memset32); 571 #endif 572 573 #ifndef __HAVE_ARCH_MEMSET64 574 /** 575 * memset64() - Fill a memory area with a uint64_t 576 * @s: Pointer to the start of the area. 577 * @v: The value to fill the area with 578 * @count: The number of values to store 579 * 580 * Differs from memset() in that it fills with a uint64_t instead 581 * of a byte. Remember that @count is the number of uint64_ts to 582 * store, not the number of bytes. 583 */ 584 void *memset64(uint64_t *s, uint64_t v, size_t count) 585 { 586 uint64_t *xs = s; 587 588 while (count--) 589 *xs++ = v; 590 return s; 591 } 592 EXPORT_SYMBOL(memset64); 593 #endif 594 595 #ifndef __HAVE_ARCH_MEMCPY 596 /** 597 * memcpy - Copy one area of memory to another 598 * @dest: Where to copy to 599 * @src: Where to copy from 600 * @count: The size of the area. 601 * 602 * You should not use this function to access IO space, use memcpy_toio() 603 * or memcpy_fromio() instead. 604 */ 605 void *memcpy(void *dest, const void *src, size_t count) 606 { 607 char *tmp = dest; 608 const char *s = src; 609 610 while (count--) 611 *tmp++ = *s++; 612 return dest; 613 } 614 EXPORT_SYMBOL(memcpy); 615 #endif 616 617 #ifndef __HAVE_ARCH_MEMMOVE 618 /** 619 * memmove - Copy one area of memory to another 620 * @dest: Where to copy to 621 * @src: Where to copy from 622 * @count: The size of the area. 623 * 624 * Unlike memcpy(), memmove() copes with overlapping areas. 625 */ 626 void *memmove(void *dest, const void *src, size_t count) 627 { 628 char *tmp; 629 const char *s; 630 631 if (dest <= src) { 632 tmp = dest; 633 s = src; 634 while (count--) 635 *tmp++ = *s++; 636 } else { 637 tmp = dest; 638 tmp += count; 639 s = src; 640 s += count; 641 while (count--) 642 *--tmp = *--s; 643 } 644 return dest; 645 } 646 EXPORT_SYMBOL(memmove); 647 #endif 648 649 #ifndef __HAVE_ARCH_MEMCMP 650 /** 651 * memcmp - Compare two areas of memory 652 * @cs: One area of memory 653 * @ct: Another area of memory 654 * @count: The size of the area. 655 */ 656 #undef memcmp 657 __visible int memcmp(const void *cs, const void *ct, size_t count) 658 { 659 const unsigned char *su1, *su2; 660 int res = 0; 661 662 #ifdef CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS 663 if (count >= sizeof(unsigned long)) { 664 const unsigned long *u1 = cs; 665 const unsigned long *u2 = ct; 666 do { 667 if (get_unaligned(u1) != get_unaligned(u2)) 668 break; 669 u1++; 670 u2++; 671 count -= sizeof(unsigned long); 672 } while (count >= sizeof(unsigned long)); 673 cs = u1; 674 ct = u2; 675 } 676 #endif 677 for (su1 = cs, su2 = ct; 0 < count; ++su1, ++su2, count--) 678 if ((res = *su1 - *su2) != 0) 679 break; 680 return res; 681 } 682 EXPORT_SYMBOL(memcmp); 683 #endif 684 685 #ifndef __HAVE_ARCH_BCMP 686 /** 687 * bcmp - returns 0 if and only if the buffers have identical contents. 688 * @a: pointer to first buffer. 689 * @b: pointer to second buffer. 690 * @len: size of buffers. 691 * 692 * The sign or magnitude of a non-zero return value has no particular 693 * meaning, and architectures may implement their own more efficient bcmp(). So 694 * while this particular implementation is a simple (tail) call to memcmp, do 695 * not rely on anything but whether the return value is zero or non-zero. 696 */ 697 int bcmp(const void *a, const void *b, size_t len) 698 { 699 return memcmp(a, b, len); 700 } 701 EXPORT_SYMBOL(bcmp); 702 #endif 703 704 #ifndef __HAVE_ARCH_MEMSCAN 705 /** 706 * memscan - Find a character in an area of memory. 707 * @addr: The memory area 708 * @c: The byte to search for 709 * @size: The size of the area. 710 * 711 * returns the address of the first occurrence of @c, or 1 byte past 712 * the area if @c is not found 713 */ 714 void *memscan(void *addr, int c, size_t size) 715 { 716 unsigned char *p = addr; 717 718 while (size) { 719 if (*p == (unsigned char)c) 720 return (void *)p; 721 p++; 722 size--; 723 } 724 return (void *)p; 725 } 726 EXPORT_SYMBOL(memscan); 727 #endif 728 729 #ifndef __HAVE_ARCH_STRSTR 730 /** 731 * strstr - Find the first substring in a %NUL terminated string 732 * @s1: The string to be searched 733 * @s2: The string to search for 734 */ 735 char *strstr(const char *s1, const char *s2) 736 { 737 size_t l1, l2; 738 739 l2 = strlen(s2); 740 if (!l2) 741 return (char *)s1; 742 l1 = strlen(s1); 743 while (l1 >= l2) { 744 l1--; 745 if (!memcmp(s1, s2, l2)) 746 return (char *)s1; 747 s1++; 748 } 749 return NULL; 750 } 751 EXPORT_SYMBOL(strstr); 752 #endif 753 754 #ifndef __HAVE_ARCH_STRNSTR 755 /** 756 * strnstr - Find the first substring in a length-limited string 757 * @s1: The string to be searched 758 * @s2: The string to search for 759 * @len: the maximum number of characters to search 760 */ 761 char *strnstr(const char *s1, const char *s2, size_t len) 762 { 763 size_t l2; 764 765 l2 = strlen(s2); 766 if (!l2) 767 return (char *)s1; 768 while (len >= l2) { 769 len--; 770 if (!memcmp(s1, s2, l2)) 771 return (char *)s1; 772 s1++; 773 } 774 return NULL; 775 } 776 EXPORT_SYMBOL(strnstr); 777 #endif 778 779 #ifndef __HAVE_ARCH_MEMCHR 780 /** 781 * memchr - Find a character in an area of memory. 782 * @s: The memory area 783 * @c: The byte to search for 784 * @n: The size of the area. 785 * 786 * returns the address of the first occurrence of @c, or %NULL 787 * if @c is not found 788 */ 789 void *memchr(const void *s, int c, size_t n) 790 { 791 const unsigned char *p = s; 792 while (n-- != 0) { 793 if ((unsigned char)c == *p++) { 794 return (void *)(p - 1); 795 } 796 } 797 return NULL; 798 } 799 EXPORT_SYMBOL(memchr); 800 #endif 801 802 static void *check_bytes8(const u8 *start, u8 value, unsigned int bytes) 803 { 804 while (bytes) { 805 if (*start != value) 806 return (void *)start; 807 start++; 808 bytes--; 809 } 810 return NULL; 811 } 812 813 /** 814 * memchr_inv - Find an unmatching character in an area of memory. 815 * @start: The memory area 816 * @c: Find a character other than c 817 * @bytes: The size of the area. 818 * 819 * returns the address of the first character other than @c, or %NULL 820 * if the whole buffer contains just @c. 821 */ 822 void *memchr_inv(const void *start, int c, size_t bytes) 823 { 824 u8 value = c; 825 u64 value64; 826 unsigned int words, prefix; 827 828 if (bytes <= 16) 829 return check_bytes8(start, value, bytes); 830 831 value64 = value; 832 #if defined(CONFIG_ARCH_HAS_FAST_MULTIPLIER) && BITS_PER_LONG == 64 833 value64 *= 0x0101010101010101ULL; 834 #elif defined(CONFIG_ARCH_HAS_FAST_MULTIPLIER) 835 value64 *= 0x01010101; 836 value64 |= value64 << 32; 837 #else 838 value64 |= value64 << 8; 839 value64 |= value64 << 16; 840 value64 |= value64 << 32; 841 #endif 842 843 prefix = (unsigned long)start % 8; 844 if (prefix) { 845 u8 *r; 846 847 prefix = 8 - prefix; 848 r = check_bytes8(start, value, prefix); 849 if (r) 850 return r; 851 start += prefix; 852 bytes -= prefix; 853 } 854 855 words = bytes / 8; 856 857 while (words) { 858 if (*(u64 *)start != value64) 859 return check_bytes8(start, value, 8); 860 start += 8; 861 words--; 862 } 863 864 return check_bytes8(start, value, bytes % 8); 865 } 866 EXPORT_SYMBOL(memchr_inv); 867