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 (__builtin_expect(length == 0, 0)) goto done; - /* * 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) { + u_char *dst = (u_char *)dst0; + const u_char *src = (const u_char *)src0; + size_t t; + +#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 @@ -37,5 +37,5 @@ void * mempcpy(void *__restrict dst, const void *__restrict src, size_t len) { - return ((char *)memcpy(dst, src, len) + len); + return (void *)((unsigned 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,18 +46,18 @@ #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; - if (s == NULL && (s = *last) == NULL) - return (NULL); + if (s == NULL) + s = *last; /* * Skip (span) leading delimiters (s += strspn(s, delim), sort of). @@ -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/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))