string.h 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215
  1. /* SPDX-License-Identifier: GPL-2.0 */
  2. /*
  3. * S390 version
  4. * Copyright IBM Corp. 1999
  5. * Author(s): Martin Schwidefsky ([email protected]),
  6. */
  7. #ifndef _S390_STRING_H_
  8. #define _S390_STRING_H_
  9. #ifndef _LINUX_TYPES_H
  10. #include <linux/types.h>
  11. #endif
  12. #define __HAVE_ARCH_MEMCPY /* gcc builtin & arch function */
  13. #define __HAVE_ARCH_MEMMOVE /* gcc builtin & arch function */
  14. #define __HAVE_ARCH_MEMSET /* gcc builtin & arch function */
  15. #define __HAVE_ARCH_MEMSET16 /* arch function */
  16. #define __HAVE_ARCH_MEMSET32 /* arch function */
  17. #define __HAVE_ARCH_MEMSET64 /* arch function */
  18. void *memcpy(void *dest, const void *src, size_t n);
  19. void *memset(void *s, int c, size_t n);
  20. void *memmove(void *dest, const void *src, size_t n);
  21. #ifndef CONFIG_KASAN
  22. #define __HAVE_ARCH_MEMCHR /* inline & arch function */
  23. #define __HAVE_ARCH_MEMCMP /* arch function */
  24. #define __HAVE_ARCH_MEMSCAN /* inline & arch function */
  25. #define __HAVE_ARCH_STRCAT /* inline & arch function */
  26. #define __HAVE_ARCH_STRCMP /* arch function */
  27. #define __HAVE_ARCH_STRCPY /* inline & arch function */
  28. #define __HAVE_ARCH_STRLCAT /* arch function */
  29. #define __HAVE_ARCH_STRLEN /* inline & arch function */
  30. #define __HAVE_ARCH_STRNCAT /* arch function */
  31. #define __HAVE_ARCH_STRNCPY /* arch function */
  32. #define __HAVE_ARCH_STRNLEN /* inline & arch function */
  33. #define __HAVE_ARCH_STRSTR /* arch function */
  34. /* Prototypes for non-inlined arch strings functions. */
  35. int memcmp(const void *s1, const void *s2, size_t n);
  36. int strcmp(const char *s1, const char *s2);
  37. size_t strlcat(char *dest, const char *src, size_t n);
  38. char *strncat(char *dest, const char *src, size_t n);
  39. char *strncpy(char *dest, const char *src, size_t n);
  40. char *strstr(const char *s1, const char *s2);
  41. #endif /* !CONFIG_KASAN */
  42. #undef __HAVE_ARCH_STRCHR
  43. #undef __HAVE_ARCH_STRNCHR
  44. #undef __HAVE_ARCH_STRNCMP
  45. #undef __HAVE_ARCH_STRPBRK
  46. #undef __HAVE_ARCH_STRSEP
  47. #undef __HAVE_ARCH_STRSPN
  48. #if defined(CONFIG_KASAN) && !defined(__SANITIZE_ADDRESS__)
  49. extern void *__memcpy(void *dest, const void *src, size_t n);
  50. extern void *__memset(void *s, int c, size_t n);
  51. extern void *__memmove(void *dest, const void *src, size_t n);
  52. /*
  53. * For files that are not instrumented (e.g. mm/slub.c) we
  54. * should use not instrumented version of mem* functions.
  55. */
  56. #define memcpy(dst, src, len) __memcpy(dst, src, len)
  57. #define memmove(dst, src, len) __memmove(dst, src, len)
  58. #define memset(s, c, n) __memset(s, c, n)
  59. #define strlen(s) __strlen(s)
  60. #define __no_sanitize_prefix_strfunc(x) __##x
  61. #ifndef __NO_FORTIFY
  62. #define __NO_FORTIFY /* FORTIFY_SOURCE uses __builtin_memcpy, etc. */
  63. #endif
  64. #else
  65. #define __no_sanitize_prefix_strfunc(x) x
  66. #endif /* defined(CONFIG_KASAN) && !defined(__SANITIZE_ADDRESS__) */
  67. void *__memset16(uint16_t *s, uint16_t v, size_t count);
  68. void *__memset32(uint32_t *s, uint32_t v, size_t count);
  69. void *__memset64(uint64_t *s, uint64_t v, size_t count);
  70. static inline void *memset16(uint16_t *s, uint16_t v, size_t count)
  71. {
  72. return __memset16(s, v, count * sizeof(v));
  73. }
  74. static inline void *memset32(uint32_t *s, uint32_t v, size_t count)
  75. {
  76. return __memset32(s, v, count * sizeof(v));
  77. }
  78. static inline void *memset64(uint64_t *s, uint64_t v, size_t count)
  79. {
  80. return __memset64(s, v, count * sizeof(v));
  81. }
  82. #if !defined(IN_ARCH_STRING_C) && (!defined(CONFIG_FORTIFY_SOURCE) || defined(__NO_FORTIFY))
  83. #ifdef __HAVE_ARCH_MEMCHR
  84. static inline void *memchr(const void * s, int c, size_t n)
  85. {
  86. const void *ret = s + n;
  87. asm volatile(
  88. " lgr 0,%[c]\n"
  89. "0: srst %[ret],%[s]\n"
  90. " jo 0b\n"
  91. " jl 1f\n"
  92. " la %[ret],0\n"
  93. "1:"
  94. : [ret] "+&a" (ret), [s] "+&a" (s)
  95. : [c] "d" (c)
  96. : "cc", "memory", "0");
  97. return (void *) ret;
  98. }
  99. #endif
  100. #ifdef __HAVE_ARCH_MEMSCAN
  101. static inline void *memscan(void *s, int c, size_t n)
  102. {
  103. const void *ret = s + n;
  104. asm volatile(
  105. " lgr 0,%[c]\n"
  106. "0: srst %[ret],%[s]\n"
  107. " jo 0b\n"
  108. : [ret] "+&a" (ret), [s] "+&a" (s)
  109. : [c] "d" (c)
  110. : "cc", "memory", "0");
  111. return (void *) ret;
  112. }
  113. #endif
  114. #ifdef __HAVE_ARCH_STRCAT
  115. static inline char *strcat(char *dst, const char *src)
  116. {
  117. unsigned long dummy = 0;
  118. char *ret = dst;
  119. asm volatile(
  120. " lghi 0,0\n"
  121. "0: srst %[dummy],%[dst]\n"
  122. " jo 0b\n"
  123. "1: mvst %[dummy],%[src]\n"
  124. " jo 1b"
  125. : [dummy] "+&a" (dummy), [dst] "+&a" (dst), [src] "+&a" (src)
  126. :
  127. : "cc", "memory", "0");
  128. return ret;
  129. }
  130. #endif
  131. #ifdef __HAVE_ARCH_STRCPY
  132. static inline char *strcpy(char *dst, const char *src)
  133. {
  134. char *ret = dst;
  135. asm volatile(
  136. " lghi 0,0\n"
  137. "0: mvst %[dst],%[src]\n"
  138. " jo 0b"
  139. : [dst] "+&a" (dst), [src] "+&a" (src)
  140. :
  141. : "cc", "memory", "0");
  142. return ret;
  143. }
  144. #endif
  145. #if defined(__HAVE_ARCH_STRLEN) || (defined(CONFIG_KASAN) && !defined(__SANITIZE_ADDRESS__))
  146. static inline size_t __no_sanitize_prefix_strfunc(strlen)(const char *s)
  147. {
  148. unsigned long end = 0;
  149. const char *tmp = s;
  150. asm volatile(
  151. " lghi 0,0\n"
  152. "0: srst %[end],%[tmp]\n"
  153. " jo 0b"
  154. : [end] "+&a" (end), [tmp] "+&a" (tmp)
  155. :
  156. : "cc", "memory", "0");
  157. return end - (unsigned long)s;
  158. }
  159. #endif
  160. #ifdef __HAVE_ARCH_STRNLEN
  161. static inline size_t strnlen(const char * s, size_t n)
  162. {
  163. const char *tmp = s;
  164. const char *end = s + n;
  165. asm volatile(
  166. " lghi 0,0\n"
  167. "0: srst %[end],%[tmp]\n"
  168. " jo 0b"
  169. : [end] "+&a" (end), [tmp] "+&a" (tmp)
  170. :
  171. : "cc", "memory", "0");
  172. return end - s;
  173. }
  174. #endif
  175. #else /* IN_ARCH_STRING_C */
  176. void *memchr(const void * s, int c, size_t n);
  177. void *memscan(void *s, int c, size_t n);
  178. char *strcat(char *dst, const char *src);
  179. char *strcpy(char *dst, const char *src);
  180. size_t strlen(const char *s);
  181. size_t strnlen(const char * s, size_t n);
  182. #endif /* !IN_ARCH_STRING_C */
  183. #endif /* __S390_STRING_H_ */