Index: include/string.h =================================================================== --- include/string.h +++ include/string.h @@ -129,7 +129,7 @@ char *strstr(const char *, const char *) __pure; char *strtok(char * __restrict, const char * __restrict); #if __POSIX_VISIBLE >= 199506 || __XSI_VISIBLE >= 500 -char *strtok_r(char *, const char *, char **); +char *strtok_r(char * __restrict, const char * __restrict, char ** __restrict); #endif size_t strxfrm(char * __restrict, const char * __restrict, size_t); #if __BSD_VISIBLE @@ -145,8 +145,8 @@ void swab(const void * __restrict, void * __restrict, ssize_t); #endif /* _SWAB_DECLARED */ -int timingsafe_bcmp(const void *, const void *, size_t); -int timingsafe_memcmp(const void *, const void *, size_t); +int timingsafe_bcmp(const void *, const void *, size_t) __pure; +int timingsafe_memcmp(const void *, const void *, size_t) __pure; #endif /* __BSD_VISIBLE */ #if __POSIX_VISIBLE >= 200112 || defined(_XLOCALE_H_) Index: lib/libc/string/bcopy.c =================================================================== --- lib/libc/string/bcopy.c +++ lib/libc/string/bcopy.c @@ -40,7 +40,7 @@ #include -typedef intptr_t word; /* "word" used for optimal copy speed */ +typedef size_t word; /* "word" used for optimal copy speed */ #define wsize sizeof(word) #define wmask (wsize - 1) @@ -56,10 +56,11 @@ void * #ifdef MEMCOPY memcpy +(void * __restrict dst0, const void * __restrict src0, size_t length) #else memmove -#endif (void *dst0, const void *src0, size_t length) +#endif #else #include @@ -67,33 +68,37 @@ bcopy(const void *src0, void *dst0, size_t length) #endif { - char *dst = dst0; - const char *src = src0; - size_t t; - - if (length == 0 || dst == src) /* nothing to do */ + if (__predict_false(length == 0)) goto done; + u_char *dst = (u_char *)dst0; + const u_char *src = (const u_char *)src0; + size_t t; /* * Macros: loop-t-times; and loop-t-times, t>0 */ -#define TLOOP(s) if (t) TLOOP1(s) +#define TLOOP(s) for (; t; --t) { s; } #define TLOOP1(s) do { s; } while (--t) - if ((unsigned long)dst < (unsigned long)src) { +#ifndef MEMCOPY + if (dst < src) { +#endif /* * Copy forward. */ - t = (uintptr_t)src; /* only need low bits */ - if ((t | (uintptr_t)dst) & wmask) { + t = (size_t)src; /* only need low bits */ + if ((t | (size_t)dst) & wmask) { /* * Try to align operands. This cannot be done * unless the low bits match. */ - if ((t ^ (uintptr_t)dst) & wmask || length < wsize) + if ((t ^ (size_t)dst) & wmask || length < wsize) { t = length; - else - t = wsize - (t & wmask); + TLOOP1(*dst++ = *src++); + goto done; + } + + t = wsize - (t & wmask); length -= t; TLOOP1(*dst++ = *src++); } @@ -101,33 +106,39 @@ * Copy whole words, then mop up any trailing bytes. */ t = length / wsize; - TLOOP(*(word *)(void *)dst = *(const word *)(const void *)src; - src += wsize; dst += wsize); + TLOOP(*(word *)dst = *(const word *)src; dst += wsize; + src += wsize); t = length & wmask; TLOOP(*dst++ = *src++); +#ifndef MEMCOPY } else { /* * Copy backwards. Otherwise essentially the same. * Alignment works as before, except that it takes * (t&wmask) bytes to align, not wsize-(t&wmask). */ - src += length; dst += length; - t = (uintptr_t)src; - if ((t | (uintptr_t)dst) & wmask) { - if ((t ^ (uintptr_t)dst) & wmask || length <= wsize) + src += length; + t = (size_t)src; + + if ((t | (size_t)dst) & wmask) { + if ((t ^ (size_t)dst) & wmask || length <= wsize) { t = length; - else - t &= wmask; + TLOOP1(*--dst = *--src); + goto done; + } + + t &= wmask; length -= t; TLOOP1(*--dst = *--src); } t = length / wsize; - TLOOP(src -= wsize; dst -= wsize; - *(word *)(void *)dst = *(const word *)(const void *)src); + TLOOP(dst -= wsize; src -= wsize; + *(word *)dst = *(const word *)src); t = length & wmask; TLOOP(*--dst = *--src); } +#endif done: #if defined(MEMCOPY) || defined(MEMMOVE) return (dst0); Index: lib/libc/string/memccpy.3 =================================================================== --- lib/libc/string/memccpy.3 +++ lib/libc/string/memccpy.3 @@ -28,7 +28,7 @@ .\" @(#)memccpy.3 8.1 (Berkeley) 6/9/93 .\" $FreeBSD$ .\" -.Dd June 9, 1993 +.Dd July 4, 2021 .Dt MEMCCPY 3 .Os .Sh NAME @@ -39,7 +39,7 @@ .Sh SYNOPSIS .In string.h .Ft void * -.Fn memccpy "void *dst" "const void *src" "int c" "size_t len" +.Fn memccpy "void * restrict dst" "const void * restrict src" "int c" "size_t len" .Sh DESCRIPTION The .Fn memccpy Index: lib/libc/string/mempcpy.c =================================================================== --- lib/libc/string/mempcpy.c +++ lib/libc/string/mempcpy.c @@ -32,10 +32,12 @@ #include __FBSDID("$FreeBSD$"); +#include + #include void * -mempcpy(void *__restrict dst, const void *__restrict src, size_t len) +mempcpy(void * __restrict dst, const void * __restrict src, size_t len) { - return ((char *)memcpy(dst, src, len) + len); + return ((u_char *)memcpy(dst, src, len) + len); } Index: lib/libc/string/strtok.3 =================================================================== --- lib/libc/string/strtok.3 +++ lib/libc/string/strtok.3 @@ -44,7 +44,7 @@ .\" @(#)strtok.3 8.2 (Berkeley) 2/3/94 .\" $FreeBSD$ .\" -.Dd January 22, 2016 +.Dd July 4, 2021 .Dt STRTOK 3 .Os .Sh NAME @@ -55,9 +55,9 @@ .Sh SYNOPSIS .In string.h .Ft char * -.Fn strtok "char *str" "const char *sep" +.Fn strtok "char * restrict str" "const char * restrict sep" .Ft char * -.Fn strtok_r "char *str" "const char *sep" "char **last" +.Fn strtok_r "char * restrict str" "const char * restrict sep" "char ** restrict last" .Sh DESCRIPTION .Bf -symbolic This interface is obsoleted by Index: lib/libc/string/strtok.c =================================================================== --- lib/libc/string/strtok.c +++ lib/libc/string/strtok.c @@ -46,15 +46,15 @@ #endif #include -char *__strtok_r(char *, const char *, char **); +char *__strtok_r(char * __restrict, const char * __restrict, char ** __restrict); __weak_reference(__strtok_r, strtok_r); char * -__strtok_r(char *s, const char *delim, char **last) +__strtok_r(char * __restrict s, const char * __restrict delim, char ** __restrict last) { - char *spanp, *tok; - int c, sc; + const char *spanp, *tok; + char c, sc; if (s == NULL && (s = *last) == NULL) return (NULL); @@ -64,7 +64,7 @@ */ cont: c = *s++; - for (spanp = (char *)delim; (sc = *spanp++) != 0;) { + for (spanp = delim; (sc = *spanp++) != 0;) { if (c == sc) goto cont; } @@ -81,7 +81,7 @@ */ for (;;) { c = *s++; - spanp = (char *)delim; + spanp = delim; do { if ((sc = *spanp++) == c) { if (c == 0) @@ -89,7 +89,7 @@ else s[-1] = '\0'; *last = s; - return (tok); + return ((char *)tok); } } while (sc != 0); } @@ -97,7 +97,7 @@ } char * -strtok(char *s, const char *delim) +strtok(char * __restrict s, const char * __restrict delim) { static char *last; Index: lib/libc/string/strxfrm.3 =================================================================== --- lib/libc/string/strxfrm.3 +++ lib/libc/string/strxfrm.3 @@ -45,7 +45,7 @@ .Ft size_t .Fn strxfrm "char * restrict dst" "const char * restrict src" "size_t n" .Ft size_t -.Fn strxfrm_l "char * restrict dst" "const char *restrict src" "size_t n" "locale_t loc" +.Fn strxfrm_l "char * restrict dst" "const char * restrict src" "size_t n" "locale_t loc" .Sh DESCRIPTION The .Fn strxfrm Index: sys/libkern/strdup.c =================================================================== --- sys/libkern/strdup.c +++ sys/libkern/strdup.c @@ -54,7 +54,7 @@ } char * -strdup(const char *string, struct malloc_type *type) +strdup(const char * __restrict string, struct malloc_type *type) { return (strdup_flags(string, type, M_WAITOK)); Index: sys/libkern/strlcat.c =================================================================== --- sys/libkern/strlcat.c +++ sys/libkern/strlcat.c @@ -46,21 +46,21 @@ * If retval >= siz, truncation occurred. */ size_t -strlcat(char *dst, const char *src, size_t siz) +strlcat(char * __restrict dst, const char * __restrict src, size_t siz) { char *d = dst; const char *s = src; size_t n = siz; - size_t dlen; /* Find the end of dst and adjust bytes left but don't go past end */ - while (n-- != 0 && *d != '\0') - d++; - dlen = d - dst; - n = siz - dlen; + for (;; ++d, --n) { + if (n == 0) + return (siz + strlen(s)); + if (*d == '\0') + break; + } + const size_t dlen = siz - n; - if (n == 0) - return(dlen + strlen(s)); while (*s != '\0') { if (n != 1) { *d++ = *s; @@ -70,5 +70,5 @@ } *d = '\0'; - return(dlen + (s - src)); /* count does not include NUL */ + return (dlen + (s - src)); /* count does not include NUL */ } Index: sys/libkern/strncat.c =================================================================== --- sys/libkern/strncat.c +++ sys/libkern/strncat.c @@ -43,19 +43,18 @@ * are written at dst (at most n+1 bytes being appended). Return dst. */ char * -strncat(char *dst, const char *src, size_t n) +strncat(char * __restrict dst, const char * __restrict src, size_t n) { if (n != 0) { char *d = dst; - const char *s = src; - while (*d != 0) + while (*d != '\0') d++; do { - if ((*d = *s++) == '\0') - break; - d++; + if ((*d = *src) == '\0') + return (dst); + d++, src++; } while (--n != 0); *d = '\0'; } Index: sys/sys/libkern.h =================================================================== --- sys/sys/libkern.h +++ sys/sys/libkern.h @@ -129,7 +129,7 @@ void arc4random_buf(void *, size_t); uint32_t arc4random_uniform(uint32_t); void arc4rand(void *, u_int, int); -int timingsafe_bcmp(const void *, const void *, size_t); +int timingsafe_bcmp(const void *, const void *, size_t) __pure; void *bsearch(const void *, const void *, size_t, size_t, int (*)(const void *, const void *)); #ifndef HAVE_INLINE_FFS @@ -158,8 +158,8 @@ int fnmatch(const char *, const char *, int); int locc(int, char *, u_int); -void *memchr(const void *s, int c, size_t n); -void *memcchr(const void *s, int c, size_t n); +void *memchr(const void *s, int c, size_t n) __pure; +void *memcchr(const void *s, int c, size_t n) __pure; void *memmem(const void *l, size_t l_len, const void *s, size_t s_len); void qsort(void *base, size_t nmemb, size_t size, int (*compar)(const void *, const void *)); @@ -167,40 +167,40 @@ int (*compar)(void *, const void *, const void *)); u_long random(void); int scanc(u_int, const u_char *, const u_char *, int); -int strcasecmp(const char *, const char *); -char *strcasestr(const char *, const char *); +int strcasecmp(const char *, const char *) __pure; +char *strcasestr(const char *, const char *) __pure; char *strcat(char * __restrict, const char * __restrict); -char *strchr(const char *, int); -char *strchrnul(const char *, int); -int strcmp(const char *, const char *); +char *strchr(const char *, int) __pure; +char *strchrnul(const char *, int) __pure; +int strcmp(const char *, const char *) __pure; char *strcpy(char * __restrict, const char * __restrict); -char *strdup_flags(const char *__restrict, struct malloc_type *, int); size_t strcspn(const char *, const char *) __pure; -char *strdup(const char *__restrict, struct malloc_type *); -char *strncat(char *, const char *, size_t); -char *strndup(const char *__restrict, size_t, struct malloc_type *); -size_t strlcat(char *, const char *, size_t); -size_t strlcpy(char *, const char *, size_t); -size_t strlen(const char *); -int strncasecmp(const char *, const char *, size_t); -int strncmp(const char *, const char *, size_t); +char *strdup_flags(const char * __restrict, struct malloc_type *, int) __malloc_like; +char *strdup(const char * __restrict, struct malloc_type *) __malloc_like; +char *strncat(char * __restrict, const char * __restrict, size_t); +char *strndup(const char * __restrict, size_t, struct malloc_type *) __malloc_like; +size_t strlcat(char * __restrict, const char * __restrict, size_t); +size_t strlcpy(char * __restrict, const char * __restrict, size_t); +size_t strlen(const char *) __pure; +int strncasecmp(const char *, const char *, size_t) __pure; +int strncmp(const char *, const char *, size_t) __pure; char *strncpy(char * __restrict, const char * __restrict, size_t); -size_t strnlen(const char *, size_t); +size_t strnlen(const char *, size_t) __pure; char *strnstr(const char *, const char *, size_t); -char *strrchr(const char *, int); +char *strrchr(const char *, int) __pure; char *strsep(char **, const char *delim); -size_t strspn(const char *, const char *); -char *strstr(const char *, const char *); -int strvalid(const char *, size_t); +size_t strspn(const char *, const char *) __pure; +char *strstr(const char *, const char *) __pure; +int strvalid(const char *, size_t) __pure; #ifdef SAN_NEEDS_INTERCEPTORS #ifndef SAN_INTERCEPTOR #define SAN_INTERCEPTOR(func) \ __CONCAT(SAN_INTERCEPTOR_PREFIX, __CONCAT(_, func)) #endif -char *SAN_INTERCEPTOR(strcpy)(char *, const char *); -int SAN_INTERCEPTOR(strcmp)(const char *, const char *); -size_t SAN_INTERCEPTOR(strlen)(const char *); +char *SAN_INTERCEPTOR(strcpy)(char * __restrict, const char * __restrict); +int SAN_INTERCEPTOR(strcmp)(const char *, const char *) __pure; +size_t SAN_INTERCEPTOR(strlen)(const char *) __pure; #ifndef SAN_RUNTIME #define strcpy(d, s) SAN_INTERCEPTOR(strcpy)((d), (s)) #define strcmp(s1, s2) SAN_INTERCEPTOR(strcmp)((s1), (s2))