root/arch/x86/boot/string.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. memcmp
  2. bcmp
  3. strcmp
  4. strncmp
  5. strnlen
  6. atou
  7. simple_guess_base
  8. simple_strtoull
  9. simple_strtol
  10. strlen
  11. strstr
  12. strchr
  13. __div_u64_rem
  14. __div_u64
  15. _tolower
  16. _parse_integer_fixup_radix
  17. _parse_integer
  18. _kstrtoull
  19. kstrtoull

   1 // SPDX-License-Identifier: GPL-2.0-only
   2 /* -*- linux-c -*- ------------------------------------------------------- *
   3  *
   4  *   Copyright (C) 1991, 1992 Linus Torvalds
   5  *   Copyright 2007 rPath, Inc. - All Rights Reserved
   6  *
   7  * ----------------------------------------------------------------------- */
   8 
   9 /*
  10  * Very basic string functions
  11  */
  12 
  13 #include <linux/types.h>
  14 #include <linux/compiler.h>
  15 #include <linux/errno.h>
  16 #include <linux/limits.h>
  17 #include <asm/asm.h>
  18 #include "ctype.h"
  19 #include "string.h"
  20 
  21 #define KSTRTOX_OVERFLOW       (1U << 31)
  22 
  23 /*
  24  * Undef these macros so that the functions that we provide
  25  * here will have the correct names regardless of how string.h
  26  * may have chosen to #define them.
  27  */
  28 #undef memcpy
  29 #undef memset
  30 #undef memcmp
  31 
  32 int memcmp(const void *s1, const void *s2, size_t len)
  33 {
  34         bool diff;
  35         asm("repe; cmpsb" CC_SET(nz)
  36             : CC_OUT(nz) (diff), "+D" (s1), "+S" (s2), "+c" (len));
  37         return diff;
  38 }
  39 
  40 /*
  41  * Clang may lower `memcmp == 0` to `bcmp == 0`.
  42  */
  43 int bcmp(const void *s1, const void *s2, size_t len)
  44 {
  45         return memcmp(s1, s2, len);
  46 }
  47 
  48 int strcmp(const char *str1, const char *str2)
  49 {
  50         const unsigned char *s1 = (const unsigned char *)str1;
  51         const unsigned char *s2 = (const unsigned char *)str2;
  52         int delta = 0;
  53 
  54         while (*s1 || *s2) {
  55                 delta = *s1 - *s2;
  56                 if (delta)
  57                         return delta;
  58                 s1++;
  59                 s2++;
  60         }
  61         return 0;
  62 }
  63 
  64 int strncmp(const char *cs, const char *ct, size_t count)
  65 {
  66         unsigned char c1, c2;
  67 
  68         while (count) {
  69                 c1 = *cs++;
  70                 c2 = *ct++;
  71                 if (c1 != c2)
  72                         return c1 < c2 ? -1 : 1;
  73                 if (!c1)
  74                         break;
  75                 count--;
  76         }
  77         return 0;
  78 }
  79 
  80 size_t strnlen(const char *s, size_t maxlen)
  81 {
  82         const char *es = s;
  83         while (*es && maxlen) {
  84                 es++;
  85                 maxlen--;
  86         }
  87 
  88         return (es - s);
  89 }
  90 
  91 unsigned int atou(const char *s)
  92 {
  93         unsigned int i = 0;
  94         while (isdigit(*s))
  95                 i = i * 10 + (*s++ - '0');
  96         return i;
  97 }
  98 
  99 /* Works only for digits and letters, but small and fast */
 100 #define TOLOWER(x) ((x) | 0x20)
 101 
 102 static unsigned int simple_guess_base(const char *cp)
 103 {
 104         if (cp[0] == '0') {
 105                 if (TOLOWER(cp[1]) == 'x' && isxdigit(cp[2]))
 106                         return 16;
 107                 else
 108                         return 8;
 109         } else {
 110                 return 10;
 111         }
 112 }
 113 
 114 /**
 115  * simple_strtoull - convert a string to an unsigned long long
 116  * @cp: The start of the string
 117  * @endp: A pointer to the end of the parsed string will be placed here
 118  * @base: The number base to use
 119  */
 120 
 121 unsigned long long simple_strtoull(const char *cp, char **endp, unsigned int base)
 122 {
 123         unsigned long long result = 0;
 124 
 125         if (!base)
 126                 base = simple_guess_base(cp);
 127 
 128         if (base == 16 && cp[0] == '0' && TOLOWER(cp[1]) == 'x')
 129                 cp += 2;
 130 
 131         while (isxdigit(*cp)) {
 132                 unsigned int value;
 133 
 134                 value = isdigit(*cp) ? *cp - '0' : TOLOWER(*cp) - 'a' + 10;
 135                 if (value >= base)
 136                         break;
 137                 result = result * base + value;
 138                 cp++;
 139         }
 140         if (endp)
 141                 *endp = (char *)cp;
 142 
 143         return result;
 144 }
 145 
 146 long simple_strtol(const char *cp, char **endp, unsigned int base)
 147 {
 148         if (*cp == '-')
 149                 return -simple_strtoull(cp + 1, endp, base);
 150 
 151         return simple_strtoull(cp, endp, base);
 152 }
 153 
 154 /**
 155  * strlen - Find the length of a string
 156  * @s: The string to be sized
 157  */
 158 size_t strlen(const char *s)
 159 {
 160         const char *sc;
 161 
 162         for (sc = s; *sc != '\0'; ++sc)
 163                 /* nothing */;
 164         return sc - s;
 165 }
 166 
 167 /**
 168  * strstr - Find the first substring in a %NUL terminated string
 169  * @s1: The string to be searched
 170  * @s2: The string to search for
 171  */
 172 char *strstr(const char *s1, const char *s2)
 173 {
 174         size_t l1, l2;
 175 
 176         l2 = strlen(s2);
 177         if (!l2)
 178                 return (char *)s1;
 179         l1 = strlen(s1);
 180         while (l1 >= l2) {
 181                 l1--;
 182                 if (!memcmp(s1, s2, l2))
 183                         return (char *)s1;
 184                 s1++;
 185         }
 186         return NULL;
 187 }
 188 
 189 /**
 190  * strchr - Find the first occurrence of the character c in the string s.
 191  * @s: the string to be searched
 192  * @c: the character to search for
 193  */
 194 char *strchr(const char *s, int c)
 195 {
 196         while (*s != (char)c)
 197                 if (*s++ == '\0')
 198                         return NULL;
 199         return (char *)s;
 200 }
 201 
 202 static inline u64 __div_u64_rem(u64 dividend, u32 divisor, u32 *remainder)
 203 {
 204         union {
 205                 u64 v64;
 206                 u32 v32[2];
 207         } d = { dividend };
 208         u32 upper;
 209 
 210         upper = d.v32[1];
 211         d.v32[1] = 0;
 212         if (upper >= divisor) {
 213                 d.v32[1] = upper / divisor;
 214                 upper %= divisor;
 215         }
 216         asm ("divl %2" : "=a" (d.v32[0]), "=d" (*remainder) :
 217                 "rm" (divisor), "0" (d.v32[0]), "1" (upper));
 218         return d.v64;
 219 }
 220 
 221 static inline u64 __div_u64(u64 dividend, u32 divisor)
 222 {
 223         u32 remainder;
 224 
 225         return __div_u64_rem(dividend, divisor, &remainder);
 226 }
 227 
 228 static inline char _tolower(const char c)
 229 {
 230         return c | 0x20;
 231 }
 232 
 233 static const char *_parse_integer_fixup_radix(const char *s, unsigned int *base)
 234 {
 235         if (*base == 0) {
 236                 if (s[0] == '0') {
 237                         if (_tolower(s[1]) == 'x' && isxdigit(s[2]))
 238                                 *base = 16;
 239                         else
 240                                 *base = 8;
 241                 } else
 242                         *base = 10;
 243         }
 244         if (*base == 16 && s[0] == '0' && _tolower(s[1]) == 'x')
 245                 s += 2;
 246         return s;
 247 }
 248 
 249 /*
 250  * Convert non-negative integer string representation in explicitly given radix
 251  * to an integer.
 252  * Return number of characters consumed maybe or-ed with overflow bit.
 253  * If overflow occurs, result integer (incorrect) is still returned.
 254  *
 255  * Don't you dare use this function.
 256  */
 257 static unsigned int _parse_integer(const char *s,
 258                                    unsigned int base,
 259                                    unsigned long long *p)
 260 {
 261         unsigned long long res;
 262         unsigned int rv;
 263 
 264         res = 0;
 265         rv = 0;
 266         while (1) {
 267                 unsigned int c = *s;
 268                 unsigned int lc = c | 0x20; /* don't tolower() this line */
 269                 unsigned int val;
 270 
 271                 if ('0' <= c && c <= '9')
 272                         val = c - '0';
 273                 else if ('a' <= lc && lc <= 'f')
 274                         val = lc - 'a' + 10;
 275                 else
 276                         break;
 277 
 278                 if (val >= base)
 279                         break;
 280                 /*
 281                  * Check for overflow only if we are within range of
 282                  * it in the max base we support (16)
 283                  */
 284                 if (unlikely(res & (~0ull << 60))) {
 285                         if (res > __div_u64(ULLONG_MAX - val, base))
 286                                 rv |= KSTRTOX_OVERFLOW;
 287                 }
 288                 res = res * base + val;
 289                 rv++;
 290                 s++;
 291         }
 292         *p = res;
 293         return rv;
 294 }
 295 
 296 static int _kstrtoull(const char *s, unsigned int base, unsigned long long *res)
 297 {
 298         unsigned long long _res;
 299         unsigned int rv;
 300 
 301         s = _parse_integer_fixup_radix(s, &base);
 302         rv = _parse_integer(s, base, &_res);
 303         if (rv & KSTRTOX_OVERFLOW)
 304                 return -ERANGE;
 305         if (rv == 0)
 306                 return -EINVAL;
 307         s += rv;
 308         if (*s == '\n')
 309                 s++;
 310         if (*s)
 311                 return -EINVAL;
 312         *res = _res;
 313         return 0;
 314 }
 315 
 316 /**
 317  * kstrtoull - convert a string to an unsigned long long
 318  * @s: The start of the string. The string must be null-terminated, and may also
 319  *  include a single newline before its terminating null. The first character
 320  *  may also be a plus sign, but not a minus sign.
 321  * @base: The number base to use. The maximum supported base is 16. If base is
 322  *  given as 0, then the base of the string is automatically detected with the
 323  *  conventional semantics - If it begins with 0x the number will be parsed as a
 324  *  hexadecimal (case insensitive), if it otherwise begins with 0, it will be
 325  *  parsed as an octal number. Otherwise it will be parsed as a decimal.
 326  * @res: Where to write the result of the conversion on success.
 327  *
 328  * Returns 0 on success, -ERANGE on overflow and -EINVAL on parsing error.
 329  * Used as a replacement for the obsolete simple_strtoull. Return code must
 330  * be checked.
 331  */
 332 int kstrtoull(const char *s, unsigned int base, unsigned long long *res)
 333 {
 334         if (s[0] == '+')
 335                 s++;
 336         return _kstrtoull(s, base, res);
 337 }

/* [<][>][^][v][top][bottom][index][help] */