xref: /openbmc/linux/arch/x86/boot/string.c (revision 7ae9fb1b7ecbb5d85d07857943f677fd1a559b18)
197873a3dSThomas Gleixner // SPDX-License-Identifier: GPL-2.0-only
296ae6ea0SThomas Gleixner /* -*- linux-c -*- ------------------------------------------------------- *
396ae6ea0SThomas Gleixner  *
496ae6ea0SThomas Gleixner  *   Copyright (C) 1991, 1992 Linus Torvalds
596ae6ea0SThomas Gleixner  *   Copyright 2007 rPath, Inc. - All Rights Reserved
696ae6ea0SThomas Gleixner  *
796ae6ea0SThomas Gleixner  * ----------------------------------------------------------------------- */
896ae6ea0SThomas Gleixner 
996ae6ea0SThomas Gleixner /*
1096ae6ea0SThomas Gleixner  * Very basic string functions
1196ae6ea0SThomas Gleixner  */
1296ae6ea0SThomas Gleixner 
133d379225SVivek Goyal #include <linux/types.h>
14a9c640acSNick Desaulniers #include <linux/compiler.h>
15de50ce20SChao Fan #include <linux/errno.h>
16a9c640acSNick Desaulniers #include <linux/limits.h>
17216a3720SUros Bizjak #include <asm/asm.h>
183d379225SVivek Goyal #include "ctype.h"
19fac69d0eSNicholas Mc Guire #include "string.h"
2096ae6ea0SThomas Gleixner 
21de50ce20SChao Fan #define KSTRTOX_OVERFLOW       (1U << 31)
22de50ce20SChao Fan 
2318d5e6c3SMichael Davidson /*
2418d5e6c3SMichael Davidson  * Undef these macros so that the functions that we provide
2518d5e6c3SMichael Davidson  * here will have the correct names regardless of how string.h
2618d5e6c3SMichael Davidson  * may have chosen to #define them.
2718d5e6c3SMichael Davidson  */
2818d5e6c3SMichael Davidson #undef memcpy
2918d5e6c3SMichael Davidson #undef memset
3018d5e6c3SMichael Davidson #undef memcmp
3118d5e6c3SMichael Davidson 
memcmp(const void * s1,const void * s2,size_t len)32fb4cac57SVivek Goyal int memcmp(const void *s1, const void *s2, size_t len)
33fb4cac57SVivek Goyal {
34117780eeSH. Peter Anvin 	bool diff;
35216a3720SUros Bizjak 	asm("repe; cmpsb" CC_SET(nz)
36216a3720SUros Bizjak 	    : CC_OUT(nz) (diff), "+D" (s1), "+S" (s2), "+c" (len));
37fb4cac57SVivek Goyal 	return diff;
38fb4cac57SVivek Goyal }
39fb4cac57SVivek Goyal 
404ce97317SNick Desaulniers /*
414ce97317SNick Desaulniers  * Clang may lower `memcmp == 0` to `bcmp == 0`.
424ce97317SNick Desaulniers  */
bcmp(const void * s1,const void * s2,size_t len)434ce97317SNick Desaulniers int bcmp(const void *s1, const void *s2, size_t len)
444ce97317SNick Desaulniers {
454ce97317SNick Desaulniers 	return memcmp(s1, s2, len);
464ce97317SNick Desaulniers }
474ce97317SNick Desaulniers 
strcmp(const char * str1,const char * str2)4896ae6ea0SThomas Gleixner int strcmp(const char *str1, const char *str2)
4996ae6ea0SThomas Gleixner {
5096ae6ea0SThomas Gleixner 	const unsigned char *s1 = (const unsigned char *)str1;
5196ae6ea0SThomas Gleixner 	const unsigned char *s2 = (const unsigned char *)str2;
5296ae6ea0SThomas Gleixner 	int delta = 0;
5396ae6ea0SThomas Gleixner 
5496ae6ea0SThomas Gleixner 	while (*s1 || *s2) {
551c1d046bSArjun Sreedharan 		delta = *s1 - *s2;
5696ae6ea0SThomas Gleixner 		if (delta)
5796ae6ea0SThomas Gleixner 			return delta;
5896ae6ea0SThomas Gleixner 		s1++;
5996ae6ea0SThomas Gleixner 		s2++;
6096ae6ea0SThomas Gleixner 	}
6196ae6ea0SThomas Gleixner 	return 0;
6296ae6ea0SThomas Gleixner }
6396ae6ea0SThomas Gleixner 
strncmp(const char * cs,const char * ct,size_t count)64fa97bdf9SPekka Enberg int strncmp(const char *cs, const char *ct, size_t count)
65fa97bdf9SPekka Enberg {
66fa97bdf9SPekka Enberg 	unsigned char c1, c2;
67fa97bdf9SPekka Enberg 
68fa97bdf9SPekka Enberg 	while (count) {
69fa97bdf9SPekka Enberg 		c1 = *cs++;
70fa97bdf9SPekka Enberg 		c2 = *ct++;
71fa97bdf9SPekka Enberg 		if (c1 != c2)
72fa97bdf9SPekka Enberg 			return c1 < c2 ? -1 : 1;
73fa97bdf9SPekka Enberg 		if (!c1)
74fa97bdf9SPekka Enberg 			break;
75fa97bdf9SPekka Enberg 		count--;
76fa97bdf9SPekka Enberg 	}
77fa97bdf9SPekka Enberg 	return 0;
78fa97bdf9SPekka Enberg }
79fa97bdf9SPekka Enberg 
strnlen(const char * s,size_t maxlen)8096ae6ea0SThomas Gleixner size_t strnlen(const char *s, size_t maxlen)
8196ae6ea0SThomas Gleixner {
8296ae6ea0SThomas Gleixner 	const char *es = s;
8396ae6ea0SThomas Gleixner 	while (*es && maxlen) {
8496ae6ea0SThomas Gleixner 		es++;
8596ae6ea0SThomas Gleixner 		maxlen--;
8696ae6ea0SThomas Gleixner 	}
8796ae6ea0SThomas Gleixner 
8896ae6ea0SThomas Gleixner 	return (es - s);
8996ae6ea0SThomas Gleixner }
9096ae6ea0SThomas Gleixner 
atou(const char * s)9196ae6ea0SThomas Gleixner unsigned int atou(const char *s)
9296ae6ea0SThomas Gleixner {
9396ae6ea0SThomas Gleixner 	unsigned int i = 0;
9496ae6ea0SThomas Gleixner 	while (isdigit(*s))
9596ae6ea0SThomas Gleixner 		i = i * 10 + (*s++ - '0');
9696ae6ea0SThomas Gleixner 	return i;
9796ae6ea0SThomas Gleixner }
98fa97bdf9SPekka Enberg 
99fa97bdf9SPekka Enberg /* Works only for digits and letters, but small and fast */
100fa97bdf9SPekka Enberg #define TOLOWER(x) ((x) | 0x20)
101fa97bdf9SPekka Enberg 
simple_guess_base(const char * cp)102ce0aa5ddSYinghai Lu static unsigned int simple_guess_base(const char *cp)
103ce0aa5ddSYinghai Lu {
104ce0aa5ddSYinghai Lu 	if (cp[0] == '0') {
105ce0aa5ddSYinghai Lu 		if (TOLOWER(cp[1]) == 'x' && isxdigit(cp[2]))
106ce0aa5ddSYinghai Lu 			return 16;
107ce0aa5ddSYinghai Lu 		else
108ce0aa5ddSYinghai Lu 			return 8;
109ce0aa5ddSYinghai Lu 	} else {
110ce0aa5ddSYinghai Lu 		return 10;
111ce0aa5ddSYinghai Lu 	}
112ce0aa5ddSYinghai Lu }
113ce0aa5ddSYinghai Lu 
114ce0aa5ddSYinghai Lu /**
115ce0aa5ddSYinghai Lu  * simple_strtoull - convert a string to an unsigned long long
116ce0aa5ddSYinghai Lu  * @cp: The start of the string
117ce0aa5ddSYinghai Lu  * @endp: A pointer to the end of the parsed string will be placed here
118ce0aa5ddSYinghai Lu  * @base: The number base to use
119ce0aa5ddSYinghai Lu  */
simple_strtoull(const char * cp,char ** endp,unsigned int base)120fa97bdf9SPekka Enberg unsigned long long simple_strtoull(const char *cp, char **endp, unsigned int base)
121fa97bdf9SPekka Enberg {
122fa97bdf9SPekka Enberg 	unsigned long long result = 0;
123fa97bdf9SPekka Enberg 
124ce0aa5ddSYinghai Lu 	if (!base)
125ce0aa5ddSYinghai Lu 		base = simple_guess_base(cp);
126ce0aa5ddSYinghai Lu 
127fa97bdf9SPekka Enberg 	if (base == 16 && cp[0] == '0' && TOLOWER(cp[1]) == 'x')
128fa97bdf9SPekka Enberg 		cp += 2;
129fa97bdf9SPekka Enberg 
130fa97bdf9SPekka Enberg 	while (isxdigit(*cp)) {
131fa97bdf9SPekka Enberg 		unsigned int value;
132fa97bdf9SPekka Enberg 
133fa97bdf9SPekka Enberg 		value = isdigit(*cp) ? *cp - '0' : TOLOWER(*cp) - 'a' + 10;
134fa97bdf9SPekka Enberg 		if (value >= base)
135fa97bdf9SPekka Enberg 			break;
136fa97bdf9SPekka Enberg 		result = result * base + value;
137fa97bdf9SPekka Enberg 		cp++;
138fa97bdf9SPekka Enberg 	}
139fa97bdf9SPekka Enberg 	if (endp)
140fa97bdf9SPekka Enberg 		*endp = (char *)cp;
141fa97bdf9SPekka Enberg 
142fa97bdf9SPekka Enberg 	return result;
143fa97bdf9SPekka Enberg }
144291f3632SMatt Fleming 
simple_strtol(const char * cp,char ** endp,unsigned int base)145d52e7d5aSBaoquan He long simple_strtol(const char *cp, char **endp, unsigned int base)
146d52e7d5aSBaoquan He {
147d52e7d5aSBaoquan He 	if (*cp == '-')
148d52e7d5aSBaoquan He 		return -simple_strtoull(cp + 1, endp, base);
149d52e7d5aSBaoquan He 
150d52e7d5aSBaoquan He 	return simple_strtoull(cp, endp, base);
151d52e7d5aSBaoquan He }
152d52e7d5aSBaoquan He 
153291f3632SMatt Fleming /**
154291f3632SMatt Fleming  * strlen - Find the length of a string
155291f3632SMatt Fleming  * @s: The string to be sized
156291f3632SMatt Fleming  */
strlen(const char * s)157291f3632SMatt Fleming size_t strlen(const char *s)
158291f3632SMatt Fleming {
159291f3632SMatt Fleming 	const char *sc;
160291f3632SMatt Fleming 
161291f3632SMatt Fleming 	for (sc = s; *sc != '\0'; ++sc)
162291f3632SMatt Fleming 		/* nothing */;
163291f3632SMatt Fleming 	return sc - s;
164291f3632SMatt Fleming }
165291f3632SMatt Fleming 
166291f3632SMatt Fleming /**
167291f3632SMatt Fleming  * strstr - Find the first substring in a %NUL terminated string
168291f3632SMatt Fleming  * @s1: The string to be searched
169291f3632SMatt Fleming  * @s2: The string to search for
170291f3632SMatt Fleming  */
strstr(const char * s1,const char * s2)171291f3632SMatt Fleming char *strstr(const char *s1, const char *s2)
172291f3632SMatt Fleming {
173291f3632SMatt Fleming 	size_t l1, l2;
174291f3632SMatt Fleming 
175291f3632SMatt Fleming 	l2 = strlen(s2);
176291f3632SMatt Fleming 	if (!l2)
177291f3632SMatt Fleming 		return (char *)s1;
178291f3632SMatt Fleming 	l1 = strlen(s1);
179291f3632SMatt Fleming 	while (l1 >= l2) {
180291f3632SMatt Fleming 		l1--;
181291f3632SMatt Fleming 		if (!memcmp(s1, s2, l2))
182291f3632SMatt Fleming 			return (char *)s1;
183291f3632SMatt Fleming 		s1++;
184291f3632SMatt Fleming 	}
185291f3632SMatt Fleming 	return NULL;
186291f3632SMatt Fleming }
187f2844249SDave Jiang 
188f2844249SDave Jiang /**
189f2844249SDave Jiang  * strchr - Find the first occurrence of the character c in the string s.
190f2844249SDave Jiang  * @s: the string to be searched
191f2844249SDave Jiang  * @c: the character to search for
192f2844249SDave Jiang  */
strchr(const char * s,int c)193f2844249SDave Jiang char *strchr(const char *s, int c)
194f2844249SDave Jiang {
195f2844249SDave Jiang 	while (*s != (char)c)
196f2844249SDave Jiang 		if (*s++ == '\0')
197f2844249SDave Jiang 			return NULL;
198f2844249SDave Jiang 	return (char *)s;
199f2844249SDave Jiang }
200de50ce20SChao Fan 
__div_u64_rem(u64 dividend,u32 divisor,u32 * remainder)201de50ce20SChao Fan static inline u64 __div_u64_rem(u64 dividend, u32 divisor, u32 *remainder)
202de50ce20SChao Fan {
203de50ce20SChao Fan 	union {
204de50ce20SChao Fan 		u64 v64;
205de50ce20SChao Fan 		u32 v32[2];
206de50ce20SChao Fan 	} d = { dividend };
207de50ce20SChao Fan 	u32 upper;
208de50ce20SChao Fan 
209de50ce20SChao Fan 	upper = d.v32[1];
210de50ce20SChao Fan 	d.v32[1] = 0;
211de50ce20SChao Fan 	if (upper >= divisor) {
212de50ce20SChao Fan 		d.v32[1] = upper / divisor;
213de50ce20SChao Fan 		upper %= divisor;
214de50ce20SChao Fan 	}
215de50ce20SChao Fan 	asm ("divl %2" : "=a" (d.v32[0]), "=d" (*remainder) :
216de50ce20SChao Fan 		"rm" (divisor), "0" (d.v32[0]), "1" (upper));
217de50ce20SChao Fan 	return d.v64;
218de50ce20SChao Fan }
219de50ce20SChao Fan 
__div_u64(u64 dividend,u32 divisor)220de50ce20SChao Fan static inline u64 __div_u64(u64 dividend, u32 divisor)
221de50ce20SChao Fan {
222de50ce20SChao Fan 	u32 remainder;
223de50ce20SChao Fan 
224de50ce20SChao Fan 	return __div_u64_rem(dividend, divisor, &remainder);
225de50ce20SChao Fan }
226de50ce20SChao Fan 
_tolower(const char c)227de50ce20SChao Fan static inline char _tolower(const char c)
228de50ce20SChao Fan {
229de50ce20SChao Fan 	return c | 0x20;
230de50ce20SChao Fan }
231de50ce20SChao Fan 
_parse_integer_fixup_radix(const char * s,unsigned int * base)232de50ce20SChao Fan static const char *_parse_integer_fixup_radix(const char *s, unsigned int *base)
233de50ce20SChao Fan {
234de50ce20SChao Fan 	if (*base == 0) {
235de50ce20SChao Fan 		if (s[0] == '0') {
236de50ce20SChao Fan 			if (_tolower(s[1]) == 'x' && isxdigit(s[2]))
237de50ce20SChao Fan 				*base = 16;
238de50ce20SChao Fan 			else
239de50ce20SChao Fan 				*base = 8;
240de50ce20SChao Fan 		} else
241de50ce20SChao Fan 			*base = 10;
242de50ce20SChao Fan 	}
243de50ce20SChao Fan 	if (*base == 16 && s[0] == '0' && _tolower(s[1]) == 'x')
244de50ce20SChao Fan 		s += 2;
245de50ce20SChao Fan 	return s;
246de50ce20SChao Fan }
247de50ce20SChao Fan 
248de50ce20SChao Fan /*
249de50ce20SChao Fan  * Convert non-negative integer string representation in explicitly given radix
250de50ce20SChao Fan  * to an integer.
251de50ce20SChao Fan  * Return number of characters consumed maybe or-ed with overflow bit.
252de50ce20SChao Fan  * If overflow occurs, result integer (incorrect) is still returned.
253de50ce20SChao Fan  *
254de50ce20SChao Fan  * Don't you dare use this function.
255de50ce20SChao Fan  */
_parse_integer(const char * s,unsigned int base,unsigned long long * p)256de50ce20SChao Fan static unsigned int _parse_integer(const char *s,
257de50ce20SChao Fan 				   unsigned int base,
258de50ce20SChao Fan 				   unsigned long long *p)
259de50ce20SChao Fan {
260de50ce20SChao Fan 	unsigned long long res;
261de50ce20SChao Fan 	unsigned int rv;
262de50ce20SChao Fan 
263de50ce20SChao Fan 	res = 0;
264de50ce20SChao Fan 	rv = 0;
265de50ce20SChao Fan 	while (1) {
266de50ce20SChao Fan 		unsigned int c = *s;
267de50ce20SChao Fan 		unsigned int lc = c | 0x20; /* don't tolower() this line */
268de50ce20SChao Fan 		unsigned int val;
269de50ce20SChao Fan 
270de50ce20SChao Fan 		if ('0' <= c && c <= '9')
271de50ce20SChao Fan 			val = c - '0';
272de50ce20SChao Fan 		else if ('a' <= lc && lc <= 'f')
273de50ce20SChao Fan 			val = lc - 'a' + 10;
274de50ce20SChao Fan 		else
275de50ce20SChao Fan 			break;
276de50ce20SChao Fan 
277de50ce20SChao Fan 		if (val >= base)
278de50ce20SChao Fan 			break;
279de50ce20SChao Fan 		/*
280de50ce20SChao Fan 		 * Check for overflow only if we are within range of
281de50ce20SChao Fan 		 * it in the max base we support (16)
282de50ce20SChao Fan 		 */
283de50ce20SChao Fan 		if (unlikely(res & (~0ull << 60))) {
284de50ce20SChao Fan 			if (res > __div_u64(ULLONG_MAX - val, base))
285de50ce20SChao Fan 				rv |= KSTRTOX_OVERFLOW;
286de50ce20SChao Fan 		}
287de50ce20SChao Fan 		res = res * base + val;
288de50ce20SChao Fan 		rv++;
289de50ce20SChao Fan 		s++;
290de50ce20SChao Fan 	}
291de50ce20SChao Fan 	*p = res;
292de50ce20SChao Fan 	return rv;
293de50ce20SChao Fan }
294de50ce20SChao Fan 
_kstrtoull(const char * s,unsigned int base,unsigned long long * res)295de50ce20SChao Fan static int _kstrtoull(const char *s, unsigned int base, unsigned long long *res)
296de50ce20SChao Fan {
297de50ce20SChao Fan 	unsigned long long _res;
298de50ce20SChao Fan 	unsigned int rv;
299de50ce20SChao Fan 
300de50ce20SChao Fan 	s = _parse_integer_fixup_radix(s, &base);
301de50ce20SChao Fan 	rv = _parse_integer(s, base, &_res);
302de50ce20SChao Fan 	if (rv & KSTRTOX_OVERFLOW)
303de50ce20SChao Fan 		return -ERANGE;
304de50ce20SChao Fan 	if (rv == 0)
305de50ce20SChao Fan 		return -EINVAL;
306de50ce20SChao Fan 	s += rv;
307de50ce20SChao Fan 	if (*s == '\n')
308de50ce20SChao Fan 		s++;
309de50ce20SChao Fan 	if (*s)
310de50ce20SChao Fan 		return -EINVAL;
311de50ce20SChao Fan 	*res = _res;
312de50ce20SChao Fan 	return 0;
313de50ce20SChao Fan }
314de50ce20SChao Fan 
315de50ce20SChao Fan /**
316de50ce20SChao Fan  * kstrtoull - convert a string to an unsigned long long
317de50ce20SChao Fan  * @s: The start of the string. The string must be null-terminated, and may also
318de50ce20SChao Fan  *  include a single newline before its terminating null. The first character
319de50ce20SChao Fan  *  may also be a plus sign, but not a minus sign.
320de50ce20SChao Fan  * @base: The number base to use. The maximum supported base is 16. If base is
321de50ce20SChao Fan  *  given as 0, then the base of the string is automatically detected with the
322de50ce20SChao Fan  *  conventional semantics - If it begins with 0x the number will be parsed as a
323de50ce20SChao Fan  *  hexadecimal (case insensitive), if it otherwise begins with 0, it will be
324de50ce20SChao Fan  *  parsed as an octal number. Otherwise it will be parsed as a decimal.
325de50ce20SChao Fan  * @res: Where to write the result of the conversion on success.
326de50ce20SChao Fan  *
327de50ce20SChao Fan  * Returns 0 on success, -ERANGE on overflow and -EINVAL on parsing error.
328de50ce20SChao Fan  * Used as a replacement for the obsolete simple_strtoull. Return code must
329de50ce20SChao Fan  * be checked.
330de50ce20SChao Fan  */
kstrtoull(const char * s,unsigned int base,unsigned long long * res)331de50ce20SChao Fan int kstrtoull(const char *s, unsigned int base, unsigned long long *res)
332de50ce20SChao Fan {
333de50ce20SChao Fan 	if (s[0] == '+')
334de50ce20SChao Fan 		s++;
335de50ce20SChao Fan 	return _kstrtoull(s, base, res);
336de50ce20SChao Fan }
3375fafbebcSVamshi K Sthambamkadi 
_kstrtoul(const char * s,unsigned int base,unsigned long * res)3385fafbebcSVamshi K Sthambamkadi static int _kstrtoul(const char *s, unsigned int base, unsigned long *res)
3395fafbebcSVamshi K Sthambamkadi {
3405fafbebcSVamshi K Sthambamkadi 	unsigned long long tmp;
3415fafbebcSVamshi K Sthambamkadi 	int rv;
3425fafbebcSVamshi K Sthambamkadi 
3435fafbebcSVamshi K Sthambamkadi 	rv = kstrtoull(s, base, &tmp);
3445fafbebcSVamshi K Sthambamkadi 	if (rv < 0)
3455fafbebcSVamshi K Sthambamkadi 		return rv;
3465fafbebcSVamshi K Sthambamkadi 	if (tmp != (unsigned long)tmp)
3475fafbebcSVamshi K Sthambamkadi 		return -ERANGE;
3485fafbebcSVamshi K Sthambamkadi 	*res = tmp;
3495fafbebcSVamshi K Sthambamkadi 	return 0;
3505fafbebcSVamshi K Sthambamkadi }
3515fafbebcSVamshi K Sthambamkadi 
3525fafbebcSVamshi K Sthambamkadi /**
353*d632bf6fSLukas Bulwahn  * boot_kstrtoul - convert a string to an unsigned long
3545fafbebcSVamshi K Sthambamkadi  * @s: The start of the string. The string must be null-terminated, and may also
3555fafbebcSVamshi K Sthambamkadi  *  include a single newline before its terminating null. The first character
3565fafbebcSVamshi K Sthambamkadi  *  may also be a plus sign, but not a minus sign.
3575fafbebcSVamshi K Sthambamkadi  * @base: The number base to use. The maximum supported base is 16. If base is
3585fafbebcSVamshi K Sthambamkadi  *  given as 0, then the base of the string is automatically detected with the
3595fafbebcSVamshi K Sthambamkadi  *  conventional semantics - If it begins with 0x the number will be parsed as a
3605fafbebcSVamshi K Sthambamkadi  *  hexadecimal (case insensitive), if it otherwise begins with 0, it will be
3615fafbebcSVamshi K Sthambamkadi  *  parsed as an octal number. Otherwise it will be parsed as a decimal.
3625fafbebcSVamshi K Sthambamkadi  * @res: Where to write the result of the conversion on success.
3635fafbebcSVamshi K Sthambamkadi  *
3645fafbebcSVamshi K Sthambamkadi  * Returns 0 on success, -ERANGE on overflow and -EINVAL on parsing error.
3655fafbebcSVamshi K Sthambamkadi  * Used as a replacement for the simple_strtoull.
3665fafbebcSVamshi K Sthambamkadi  */
boot_kstrtoul(const char * s,unsigned int base,unsigned long * res)3675fafbebcSVamshi K Sthambamkadi int boot_kstrtoul(const char *s, unsigned int base, unsigned long *res)
3685fafbebcSVamshi K Sthambamkadi {
3695fafbebcSVamshi K Sthambamkadi 	/*
3705fafbebcSVamshi K Sthambamkadi 	 * We want to shortcut function call, but
3715fafbebcSVamshi K Sthambamkadi 	 * __builtin_types_compatible_p(unsigned long, unsigned long long) = 0.
3725fafbebcSVamshi K Sthambamkadi 	 */
3735fafbebcSVamshi K Sthambamkadi 	if (sizeof(unsigned long) == sizeof(unsigned long long) &&
3745fafbebcSVamshi K Sthambamkadi 	    __alignof__(unsigned long) == __alignof__(unsigned long long))
3755fafbebcSVamshi K Sthambamkadi 		return kstrtoull(s, base, (unsigned long long *)res);
3765fafbebcSVamshi K Sthambamkadi 	else
3775fafbebcSVamshi K Sthambamkadi 		return _kstrtoul(s, base, res);
3785fafbebcSVamshi K Sthambamkadi }
379