xref: /linux/tools/include/nolibc/stdlib.h (revision 3785289f97e2118b157332ffaae9fd2ec71237c8)
1 /* SPDX-License-Identifier: LGPL-2.1 OR MIT */
2 /*
3  * stdlib function definitions for NOLIBC
4  * Copyright (C) 2017-2021 Willy Tarreau <w@1wt.eu>
5  */
6 
7 /* make sure to include all global symbols */
8 #include "nolibc.h"
9 
10 #ifndef _NOLIBC_STDLIB_H
11 #define _NOLIBC_STDLIB_H
12 
13 #include "std.h"
14 #include "arch.h"
15 #include "types.h"
16 #include "sys.h"
17 #include "string.h"
18 #include <linux/auxvec.h>
19 
20 struct nolibc_heap {
21 	size_t	len;
22 	char	user_p[] __attribute__((__aligned__));
23 };
24 
25 /* Buffer used to store int-to-ASCII conversions. Will only be implemented if
26  * any of the related functions is implemented. The area is large enough to
27  * store "18446744073709551615" or "-9223372036854775808" and the final zero.
28  */
29 static __attribute__((unused)) char itoa_buffer[21];
30 
31 /*
32  * As much as possible, please keep functions alphabetically sorted.
33  */
34 
35 /* must be exported, as it's used by libgcc for various divide functions */
36 void abort(void);
37 __attribute__((weak,unused,noreturn,section(".text.nolibc_abort")))
38 void abort(void)
39 {
40 	sys_kill(sys_getpid(), SIGABRT);
41 	for (;;);
42 }
43 
44 static __attribute__((unused))
45 long atol(const char *s)
46 {
47 	unsigned long ret = 0;
48 	unsigned long d;
49 	int neg = 0;
50 
51 	if (*s == '-') {
52 		neg = 1;
53 		s++;
54 	}
55 
56 	while (1) {
57 		d = (*s++) - '0';
58 		if (d > 9)
59 			break;
60 		ret *= 10;
61 		ret += d;
62 	}
63 
64 	return neg ? -ret : ret;
65 }
66 
67 static __attribute__((unused))
68 int atoi(const char *s)
69 {
70 	return atol(s);
71 }
72 
73 static __attribute__((unused))
74 void free(void *ptr)
75 {
76 	struct nolibc_heap *heap;
77 
78 	if (!ptr)
79 		return;
80 
81 	heap = container_of(ptr, struct nolibc_heap, user_p);
82 	munmap(heap, heap->len);
83 }
84 
85 /* getenv() tries to find the environment variable named <name> in the
86  * environment array pointed to by global variable "environ" which must be
87  * declared as a char **, and must be terminated by a NULL (it is recommended
88  * to set this variable to the "envp" argument of main()). If the requested
89  * environment variable exists its value is returned otherwise NULL is
90  * returned.
91  */
92 static __attribute__((unused))
93 char *getenv(const char *name)
94 {
95 	int idx, i;
96 
97 	if (environ) {
98 		for (idx = 0; environ[idx]; idx++) {
99 			for (i = 0; name[i] && name[i] == environ[idx][i];)
100 				i++;
101 			if (!name[i] && environ[idx][i] == '=')
102 				return &environ[idx][i+1];
103 		}
104 	}
105 	return NULL;
106 }
107 
108 static __attribute__((unused))
109 void *malloc(size_t len)
110 {
111 	struct nolibc_heap *heap;
112 
113 	/* Always allocate memory with size multiple of 4096. */
114 	len  = sizeof(*heap) + len;
115 	len  = (len + 4095UL) & -4096UL;
116 	heap = mmap(NULL, len, PROT_READ|PROT_WRITE, MAP_ANONYMOUS|MAP_PRIVATE,
117 		    -1, 0);
118 	if (__builtin_expect(heap == MAP_FAILED, 0))
119 		return NULL;
120 
121 	heap->len = len;
122 	return heap->user_p;
123 }
124 
125 static __attribute__((unused))
126 void *calloc(size_t size, size_t nmemb)
127 {
128 	size_t x = size * nmemb;
129 
130 	if (__builtin_expect(size && ((x / size) != nmemb), 0)) {
131 		SET_ERRNO(ENOMEM);
132 		return NULL;
133 	}
134 
135 	/*
136 	 * No need to zero the heap, the MAP_ANONYMOUS in malloc()
137 	 * already does it.
138 	 */
139 	return malloc(x);
140 }
141 
142 static __attribute__((unused))
143 void *realloc(void *old_ptr, size_t new_size)
144 {
145 	struct nolibc_heap *heap;
146 	size_t user_p_len;
147 	void *ret;
148 
149 	if (!old_ptr)
150 		return malloc(new_size);
151 
152 	heap = container_of(old_ptr, struct nolibc_heap, user_p);
153 	user_p_len = heap->len - sizeof(*heap);
154 	/*
155 	 * Don't realloc() if @user_p_len >= @new_size, this block of
156 	 * memory is still enough to handle the @new_size. Just return
157 	 * the same pointer.
158 	 */
159 	if (user_p_len >= new_size)
160 		return old_ptr;
161 
162 	ret = malloc(new_size);
163 	if (__builtin_expect(!ret, 0))
164 		return NULL;
165 
166 	memcpy(ret, heap->user_p, user_p_len);
167 	munmap(heap, heap->len);
168 	return ret;
169 }
170 
171 /* Converts the unsigned long integer <in> to its hex representation into
172  * buffer <buffer>, which must be long enough to store the number and the
173  * trailing zero (17 bytes for "ffffffffffffffff" or 9 for "ffffffff"). The
174  * buffer is filled from the first byte, and the number of characters emitted
175  * (not counting the trailing zero) is returned. The function is constructed
176  * in a way to optimize the code size and avoid any divide that could add a
177  * dependency on large external functions.
178  */
179 static __attribute__((unused))
180 int utoh_r(unsigned long in, char *buffer)
181 {
182 	signed char pos = (~0UL > 0xfffffffful) ? 60 : 28;
183 	int digits = 0;
184 	int dig;
185 
186 	do {
187 		dig = in >> pos;
188 		in -= (uint64_t)dig << pos;
189 		pos -= 4;
190 		if (dig || digits || pos < 0) {
191 			if (dig > 9)
192 				dig += 'a' - '0' - 10;
193 			buffer[digits++] = '0' + dig;
194 		}
195 	} while (pos >= 0);
196 
197 	buffer[digits] = 0;
198 	return digits;
199 }
200 
201 /* converts unsigned long <in> to an hex string using the static itoa_buffer
202  * and returns the pointer to that string.
203  */
204 static __inline__ __attribute__((unused))
205 char *utoh(unsigned long in)
206 {
207 	utoh_r(in, itoa_buffer);
208 	return itoa_buffer;
209 }
210 
211 /* Converts the unsigned long integer <in> to its string representation into
212  * buffer <buffer>, which must be long enough to store the number and the
213  * trailing zero (21 bytes for 18446744073709551615 in 64-bit, 11 for
214  * 4294967295 in 32-bit). The buffer is filled from the first byte, and the
215  * number of characters emitted (not counting the trailing zero) is returned.
216  * The function is constructed in a way to optimize the code size and avoid
217  * any divide that could add a dependency on large external functions.
218  */
219 static __attribute__((unused))
220 int utoa_r(unsigned long in, char *buffer)
221 {
222 	unsigned long lim;
223 	int digits = 0;
224 	int pos = (~0UL > 0xfffffffful) ? 19 : 9;
225 	int dig;
226 
227 	do {
228 		for (dig = 0, lim = 1; dig < pos; dig++)
229 			lim *= 10;
230 
231 		if (digits || in >= lim || !pos) {
232 			for (dig = 0; in >= lim; dig++)
233 				in -= lim;
234 			buffer[digits++] = '0' + dig;
235 		}
236 	} while (pos--);
237 
238 	buffer[digits] = 0;
239 	return digits;
240 }
241 
242 /* Converts the signed long integer <in> to its string representation into
243  * buffer <buffer>, which must be long enough to store the number and the
244  * trailing zero (21 bytes for -9223372036854775808 in 64-bit, 12 for
245  * -2147483648 in 32-bit). The buffer is filled from the first byte, and the
246  * number of characters emitted (not counting the trailing zero) is returned.
247  */
248 static __attribute__((unused))
249 int itoa_r(long in, char *buffer)
250 {
251 	char *ptr = buffer;
252 	int len = 0;
253 
254 	if (in < 0) {
255 		in = -(unsigned long)in;
256 		*(ptr++) = '-';
257 		len++;
258 	}
259 	len += utoa_r(in, ptr);
260 	return len;
261 }
262 
263 /* for historical compatibility, same as above but returns the pointer to the
264  * buffer.
265  */
266 static __inline__ __attribute__((unused))
267 char *ltoa_r(long in, char *buffer)
268 {
269 	itoa_r(in, buffer);
270 	return buffer;
271 }
272 
273 /* converts long integer <in> to a string using the static itoa_buffer and
274  * returns the pointer to that string.
275  */
276 static __inline__ __attribute__((unused))
277 char *itoa(long in)
278 {
279 	itoa_r(in, itoa_buffer);
280 	return itoa_buffer;
281 }
282 
283 /* converts long integer <in> to a string using the static itoa_buffer and
284  * returns the pointer to that string. Same as above, for compatibility.
285  */
286 static __inline__ __attribute__((unused))
287 char *ltoa(long in)
288 {
289 	itoa_r(in, itoa_buffer);
290 	return itoa_buffer;
291 }
292 
293 /* converts unsigned long integer <in> to a string using the static itoa_buffer
294  * and returns the pointer to that string.
295  */
296 static __inline__ __attribute__((unused))
297 char *utoa(unsigned long in)
298 {
299 	utoa_r(in, itoa_buffer);
300 	return itoa_buffer;
301 }
302 
303 /* Converts the unsigned 64-bit integer <in> to its hex representation into
304  * buffer <buffer>, which must be long enough to store the number and the
305  * trailing zero (17 bytes for "ffffffffffffffff"). The buffer is filled from
306  * the first byte, and the number of characters emitted (not counting the
307  * trailing zero) is returned. The function is constructed in a way to optimize
308  * the code size and avoid any divide that could add a dependency on large
309  * external functions.
310  */
311 static __attribute__((unused))
312 int u64toh_r(uint64_t in, char *buffer)
313 {
314 	signed char pos = 60;
315 	int digits = 0;
316 	int dig;
317 
318 	do {
319 		if (sizeof(long) >= 8) {
320 			dig = (in >> pos) & 0xF;
321 		} else {
322 			/* 32-bit platforms: avoid a 64-bit shift */
323 			uint32_t d = (pos >= 32) ? (in >> 32) : in;
324 			dig = (d >> (pos & 31)) & 0xF;
325 		}
326 		if (dig > 9)
327 			dig += 'a' - '0' - 10;
328 		pos -= 4;
329 		if (dig || digits || pos < 0)
330 			buffer[digits++] = '0' + dig;
331 	} while (pos >= 0);
332 
333 	buffer[digits] = 0;
334 	return digits;
335 }
336 
337 /* converts uint64_t <in> to an hex string using the static itoa_buffer and
338  * returns the pointer to that string.
339  */
340 static __inline__ __attribute__((unused))
341 char *u64toh(uint64_t in)
342 {
343 	u64toh_r(in, itoa_buffer);
344 	return itoa_buffer;
345 }
346 
347 /* Converts the unsigned 64-bit integer <in> to its string representation into
348  * buffer <buffer>, which must be long enough to store the number and the
349  * trailing zero (21 bytes for 18446744073709551615). The buffer is filled from
350  * the first byte, and the number of characters emitted (not counting the
351  * trailing zero) is returned. The function is constructed in a way to optimize
352  * the code size and avoid any divide that could add a dependency on large
353  * external functions.
354  */
355 static __attribute__((unused))
356 int u64toa_r(uint64_t in, char *buffer)
357 {
358 	unsigned long long lim;
359 	int digits = 0;
360 	int pos = 19; /* start with the highest possible digit */
361 	int dig;
362 
363 	do {
364 		for (dig = 0, lim = 1; dig < pos; dig++)
365 			lim *= 10;
366 
367 		if (digits || in >= lim || !pos) {
368 			for (dig = 0; in >= lim; dig++)
369 				in -= lim;
370 			buffer[digits++] = '0' + dig;
371 		}
372 	} while (pos--);
373 
374 	buffer[digits] = 0;
375 	return digits;
376 }
377 
378 /* Converts the signed 64-bit integer <in> to its string representation into
379  * buffer <buffer>, which must be long enough to store the number and the
380  * trailing zero (21 bytes for -9223372036854775808). The buffer is filled from
381  * the first byte, and the number of characters emitted (not counting the
382  * trailing zero) is returned.
383  */
384 static __attribute__((unused))
385 int i64toa_r(int64_t in, char *buffer)
386 {
387 	char *ptr = buffer;
388 	int len = 0;
389 
390 	if (in < 0) {
391 		in = -(uint64_t)in;
392 		*(ptr++) = '-';
393 		len++;
394 	}
395 	len += u64toa_r(in, ptr);
396 	return len;
397 }
398 
399 /* converts int64_t <in> to a string using the static itoa_buffer and returns
400  * the pointer to that string.
401  */
402 static __inline__ __attribute__((unused))
403 char *i64toa(int64_t in)
404 {
405 	i64toa_r(in, itoa_buffer);
406 	return itoa_buffer;
407 }
408 
409 /* converts uint64_t <in> to a string using the static itoa_buffer and returns
410  * the pointer to that string.
411  */
412 static __inline__ __attribute__((unused))
413 char *u64toa(uint64_t in)
414 {
415 	u64toa_r(in, itoa_buffer);
416 	return itoa_buffer;
417 }
418 
419 static __attribute__((unused))
420 uintmax_t __strtox(const char *nptr, char **endptr, int base, intmax_t lower_limit, uintmax_t upper_limit)
421 {
422 	const char signed_ = lower_limit != 0;
423 	unsigned char neg = 0, overflow = 0;
424 	uintmax_t val = 0, limit, old_val;
425 	char c;
426 
427 	if (base < 0 || base > 36) {
428 		SET_ERRNO(EINVAL);
429 		goto out;
430 	}
431 
432 	while (isspace(*nptr))
433 		nptr++;
434 
435 	if (*nptr == '+') {
436 		nptr++;
437 	} else if (*nptr == '-') {
438 		neg = 1;
439 		nptr++;
440 	}
441 
442 	if (signed_ && neg)
443 		limit = -(uintmax_t)lower_limit;
444 	else
445 		limit = upper_limit;
446 
447 	if ((base == 0 || base == 16) &&
448 	    (strncmp(nptr, "0x", 2) == 0 || strncmp(nptr, "0X", 2) == 0)) {
449 		base = 16;
450 		nptr += 2;
451 	} else if (base == 0 && strncmp(nptr, "0", 1) == 0) {
452 		base = 8;
453 		nptr += 1;
454 	} else if (base == 0) {
455 		base = 10;
456 	}
457 
458 	while (*nptr) {
459 		c = *nptr;
460 
461 		if (c >= '0' && c <= '9')
462 			c -= '0';
463 		else if (c >= 'a' && c <= 'z')
464 			c = c - 'a' + 10;
465 		else if (c >= 'A' && c <= 'Z')
466 			c = c - 'A' + 10;
467 		else
468 			goto out;
469 
470 		if (c >= base)
471 			goto out;
472 
473 		nptr++;
474 		old_val = val;
475 		val *= base;
476 		val += c;
477 
478 		if (val > limit || val < old_val)
479 			overflow = 1;
480 	}
481 
482 out:
483 	if (overflow) {
484 		SET_ERRNO(ERANGE);
485 		val = limit;
486 	}
487 	if (endptr)
488 		*endptr = (char *)nptr;
489 	return neg ? -val : val;
490 }
491 
492 static __attribute__((unused))
493 long strtol(const char *nptr, char **endptr, int base)
494 {
495 	return __strtox(nptr, endptr, base, LONG_MIN, LONG_MAX);
496 }
497 
498 static __attribute__((unused))
499 unsigned long strtoul(const char *nptr, char **endptr, int base)
500 {
501 	return __strtox(nptr, endptr, base, 0, ULONG_MAX);
502 }
503 
504 static __attribute__((unused))
505 long long strtoll(const char *nptr, char **endptr, int base)
506 {
507 	return __strtox(nptr, endptr, base, LLONG_MIN, LLONG_MAX);
508 }
509 
510 static __attribute__((unused))
511 unsigned long long strtoull(const char *nptr, char **endptr, int base)
512 {
513 	return __strtox(nptr, endptr, base, 0, ULLONG_MAX);
514 }
515 
516 static __attribute__((unused))
517 intmax_t strtoimax(const char *nptr, char **endptr, int base)
518 {
519 	return __strtox(nptr, endptr, base, INTMAX_MIN, INTMAX_MAX);
520 }
521 
522 static __attribute__((unused))
523 uintmax_t strtoumax(const char *nptr, char **endptr, int base)
524 {
525 	return __strtox(nptr, endptr, base, 0, UINTMAX_MAX);
526 }
527 
528 #endif /* _NOLIBC_STDLIB_H */
529