linux/arch/x86/boot/string.c
<<
>>
Prefs
   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
  32int 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 */
  43int bcmp(const void *s1, const void *s2, size_t len)
  44{
  45        return memcmp(s1, s2, len);
  46}
  47
  48int 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
  64int 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
  80size_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
  91unsigned 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
 102static 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 */
 120unsigned long long simple_strtoull(const char *cp, char **endp, unsigned int base)
 121{
 122        unsigned long long result = 0;
 123
 124        if (!base)
 125                base = simple_guess_base(cp);
 126
 127        if (base == 16 && cp[0] == '0' && TOLOWER(cp[1]) == 'x')
 128                cp += 2;
 129
 130        while (isxdigit(*cp)) {
 131                unsigned int value;
 132
 133                value = isdigit(*cp) ? *cp - '0' : TOLOWER(*cp) - 'a' + 10;
 134                if (value >= base)
 135                        break;
 136                result = result * base + value;
 137                cp++;
 138        }
 139        if (endp)
 140                *endp = (char *)cp;
 141
 142        return result;
 143}
 144
 145long simple_strtol(const char *cp, char **endp, unsigned int base)
 146{
 147        if (*cp == '-')
 148                return -simple_strtoull(cp + 1, endp, base);
 149
 150        return simple_strtoull(cp, endp, base);
 151}
 152
 153/**
 154 * strlen - Find the length of a string
 155 * @s: The string to be sized
 156 */
 157size_t strlen(const char *s)
 158{
 159        const char *sc;
 160
 161        for (sc = s; *sc != '\0'; ++sc)
 162                /* nothing */;
 163        return sc - s;
 164}
 165
 166/**
 167 * strstr - Find the first substring in a %NUL terminated string
 168 * @s1: The string to be searched
 169 * @s2: The string to search for
 170 */
 171char *strstr(const char *s1, const char *s2)
 172{
 173        size_t l1, l2;
 174
 175        l2 = strlen(s2);
 176        if (!l2)
 177                return (char *)s1;
 178        l1 = strlen(s1);
 179        while (l1 >= l2) {
 180                l1--;
 181                if (!memcmp(s1, s2, l2))
 182                        return (char *)s1;
 183                s1++;
 184        }
 185        return NULL;
 186}
 187
 188/**
 189 * strchr - Find the first occurrence of the character c in the string s.
 190 * @s: the string to be searched
 191 * @c: the character to search for
 192 */
 193char *strchr(const char *s, int c)
 194{
 195        while (*s != (char)c)
 196                if (*s++ == '\0')
 197                        return NULL;
 198        return (char *)s;
 199}
 200
 201static inline u64 __div_u64_rem(u64 dividend, u32 divisor, u32 *remainder)
 202{
 203        union {
 204                u64 v64;
 205                u32 v32[2];
 206        } d = { dividend };
 207        u32 upper;
 208
 209        upper = d.v32[1];
 210        d.v32[1] = 0;
 211        if (upper >= divisor) {
 212                d.v32[1] = upper / divisor;
 213                upper %= divisor;
 214        }
 215        asm ("divl %2" : "=a" (d.v32[0]), "=d" (*remainder) :
 216                "rm" (divisor), "0" (d.v32[0]), "1" (upper));
 217        return d.v64;
 218}
 219
 220static inline u64 __div_u64(u64 dividend, u32 divisor)
 221{
 222        u32 remainder;
 223
 224        return __div_u64_rem(dividend, divisor, &remainder);
 225}
 226
 227static inline char _tolower(const char c)
 228{
 229        return c | 0x20;
 230}
 231
 232static const char *_parse_integer_fixup_radix(const char *s, unsigned int *base)
 233{
 234        if (*base == 0) {
 235                if (s[0] == '0') {
 236                        if (_tolower(s[1]) == 'x' && isxdigit(s[2]))
 237                                *base = 16;
 238                        else
 239                                *base = 8;
 240                } else
 241                        *base = 10;
 242        }
 243        if (*base == 16 && s[0] == '0' && _tolower(s[1]) == 'x')
 244                s += 2;
 245        return s;
 246}
 247
 248/*
 249 * Convert non-negative integer string representation in explicitly given radix
 250 * to an integer.
 251 * Return number of characters consumed maybe or-ed with overflow bit.
 252 * If overflow occurs, result integer (incorrect) is still returned.
 253 *
 254 * Don't you dare use this function.
 255 */
 256static unsigned int _parse_integer(const char *s,
 257                                   unsigned int base,
 258                                   unsigned long long *p)
 259{
 260        unsigned long long res;
 261        unsigned int rv;
 262
 263        res = 0;
 264        rv = 0;
 265        while (1) {
 266                unsigned int c = *s;
 267                unsigned int lc = c | 0x20; /* don't tolower() this line */
 268                unsigned int val;
 269
 270                if ('0' <= c && c <= '9')
 271                        val = c - '0';
 272                else if ('a' <= lc && lc <= 'f')
 273                        val = lc - 'a' + 10;
 274                else
 275                        break;
 276
 277                if (val >= base)
 278                        break;
 279                /*
 280                 * Check for overflow only if we are within range of
 281                 * it in the max base we support (16)
 282                 */
 283                if (unlikely(res & (~0ull << 60))) {
 284                        if (res > __div_u64(ULLONG_MAX - val, base))
 285                                rv |= KSTRTOX_OVERFLOW;
 286                }
 287                res = res * base + val;
 288                rv++;
 289                s++;
 290        }
 291        *p = res;
 292        return rv;
 293}
 294
 295static int _kstrtoull(const char *s, unsigned int base, unsigned long long *res)
 296{
 297        unsigned long long _res;
 298        unsigned int rv;
 299
 300        s = _parse_integer_fixup_radix(s, &base);
 301        rv = _parse_integer(s, base, &_res);
 302        if (rv & KSTRTOX_OVERFLOW)
 303                return -ERANGE;
 304        if (rv == 0)
 305                return -EINVAL;
 306        s += rv;
 307        if (*s == '\n')
 308                s++;
 309        if (*s)
 310                return -EINVAL;
 311        *res = _res;
 312        return 0;
 313}
 314
 315/**
 316 * kstrtoull - convert a string to an unsigned long long
 317 * @s: The start of the string. The string must be null-terminated, and may also
 318 *  include a single newline before its terminating null. The first character
 319 *  may also be a plus sign, but not a minus sign.
 320 * @base: The number base to use. The maximum supported base is 16. If base is
 321 *  given as 0, then the base of the string is automatically detected with the
 322 *  conventional semantics - If it begins with 0x the number will be parsed as a
 323 *  hexadecimal (case insensitive), if it otherwise begins with 0, it will be
 324 *  parsed as an octal number. Otherwise it will be parsed as a decimal.
 325 * @res: Where to write the result of the conversion on success.
 326 *
 327 * Returns 0 on success, -ERANGE on overflow and -EINVAL on parsing error.
 328 * Used as a replacement for the obsolete simple_strtoull. Return code must
 329 * be checked.
 330 */
 331int kstrtoull(const char *s, unsigned int base, unsigned long long *res)
 332{
 333        if (s[0] == '+')
 334                s++;
 335        return _kstrtoull(s, base, res);
 336}
 337
 338static int _kstrtoul(const char *s, unsigned int base, unsigned long *res)
 339{
 340        unsigned long long tmp;
 341        int rv;
 342
 343        rv = kstrtoull(s, base, &tmp);
 344        if (rv < 0)
 345                return rv;
 346        if (tmp != (unsigned long)tmp)
 347                return -ERANGE;
 348        *res = tmp;
 349        return 0;
 350}
 351
 352/**
 353 * kstrtoul - convert a string to an unsigned long
 354 * @s: The start of the string. The string must be null-terminated, and may also
 355 *  include a single newline before its terminating null. The first character
 356 *  may also be a plus sign, but not a minus sign.
 357 * @base: The number base to use. The maximum supported base is 16. If base is
 358 *  given as 0, then the base of the string is automatically detected with the
 359 *  conventional semantics - If it begins with 0x the number will be parsed as a
 360 *  hexadecimal (case insensitive), if it otherwise begins with 0, it will be
 361 *  parsed as an octal number. Otherwise it will be parsed as a decimal.
 362 * @res: Where to write the result of the conversion on success.
 363 *
 364 * Returns 0 on success, -ERANGE on overflow and -EINVAL on parsing error.
 365 * Used as a replacement for the simple_strtoull.
 366 */
 367int boot_kstrtoul(const char *s, unsigned int base, unsigned long *res)
 368{
 369        /*
 370         * We want to shortcut function call, but
 371         * __builtin_types_compatible_p(unsigned long, unsigned long long) = 0.
 372         */
 373        if (sizeof(unsigned long) == sizeof(unsigned long long) &&
 374            __alignof__(unsigned long) == __alignof__(unsigned long long))
 375                return kstrtoull(s, base, (unsigned long long *)res);
 376        else
 377                return _kstrtoul(s, base, res);
 378}
 379