1 /* SPDX-License-Identifier: LGPL-2.1 OR MIT */
3 * stdlib function definitions for NOLIBC
4 * Copyright (C) 2017-2021 Willy Tarreau <w@1wt.eu>
7 #ifndef _NOLIBC_STDLIB_H
8 #define _NOLIBC_STDLIB_H
15 #include <linux/auxvec.h>
19 char user_p
[] __attribute__((__aligned__
));
22 /* Buffer used to store int-to-ASCII conversions. Will only be implemented if
23 * any of the related functions is implemented. The area is large enough to
24 * store "18446744073709551615" or "-9223372036854775808" and the final zero.
26 static __attribute__((unused
)) char itoa_buffer
[21];
29 * As much as possible, please keep functions alphabetically sorted.
32 /* must be exported, as it's used by libgcc for various divide functions */
33 __attribute__((weak
,unused
,noreturn
,section(".text.nolibc_abort")))
36 sys_kill(sys_getpid(), SIGABRT
);
40 static __attribute__((unused
))
41 long atol(const char *s
)
43 unsigned long ret
= 0;
60 return neg
? -ret
: ret
;
63 static __attribute__((unused
))
64 int atoi(const char *s
)
69 static __attribute__((unused
))
72 struct nolibc_heap
*heap
;
77 heap
= container_of(ptr
, struct nolibc_heap
, user_p
);
78 munmap(heap
, heap
->len
);
81 /* getenv() tries to find the environment variable named <name> in the
82 * environment array pointed to by global variable "environ" which must be
83 * declared as a char **, and must be terminated by a NULL (it is recommended
84 * to set this variable to the "envp" argument of main()). If the requested
85 * environment variable exists its value is returned otherwise NULL is
88 static __attribute__((unused
))
89 char *getenv(const char *name
)
94 for (idx
= 0; environ
[idx
]; idx
++) {
95 for (i
= 0; name
[i
] && name
[i
] == environ
[idx
][i
];)
97 if (!name
[i
] && environ
[idx
][i
] == '=')
98 return &environ
[idx
][i
+1];
104 static __attribute__((unused
))
105 unsigned long getauxval(unsigned long type
)
107 const unsigned long *auxv
= _auxv
;
114 if (!auxv
[0] && !auxv
[1]) {
119 if (auxv
[0] == type
) {
130 static __attribute__((unused
))
131 void *malloc(size_t len
)
133 struct nolibc_heap
*heap
;
135 /* Always allocate memory with size multiple of 4096. */
136 len
= sizeof(*heap
) + len
;
137 len
= (len
+ 4095UL) & -4096UL;
138 heap
= mmap(NULL
, len
, PROT_READ
|PROT_WRITE
, MAP_ANONYMOUS
|MAP_PRIVATE
,
140 if (__builtin_expect(heap
== MAP_FAILED
, 0))
147 static __attribute__((unused
))
148 void *calloc(size_t size
, size_t nmemb
)
150 size_t x
= size
* nmemb
;
152 if (__builtin_expect(size
&& ((x
/ size
) != nmemb
), 0)) {
158 * No need to zero the heap, the MAP_ANONYMOUS in malloc()
164 static __attribute__((unused
))
165 void *realloc(void *old_ptr
, size_t new_size
)
167 struct nolibc_heap
*heap
;
172 return malloc(new_size
);
174 heap
= container_of(old_ptr
, struct nolibc_heap
, user_p
);
175 user_p_len
= heap
->len
- sizeof(*heap
);
177 * Don't realloc() if @user_p_len >= @new_size, this block of
178 * memory is still enough to handle the @new_size. Just return
181 if (user_p_len
>= new_size
)
184 ret
= malloc(new_size
);
185 if (__builtin_expect(!ret
, 0))
188 memcpy(ret
, heap
->user_p
, user_p_len
);
189 munmap(heap
, heap
->len
);
193 /* Converts the unsigned long integer <in> to its hex representation into
194 * buffer <buffer>, which must be long enough to store the number and the
195 * trailing zero (17 bytes for "ffffffffffffffff" or 9 for "ffffffff"). The
196 * buffer is filled from the first byte, and the number of characters emitted
197 * (not counting the trailing zero) is returned. The function is constructed
198 * in a way to optimize the code size and avoid any divide that could add a
199 * dependency on large external functions.
201 static __attribute__((unused
))
202 int utoh_r(unsigned long in
, char *buffer
)
204 signed char pos
= (~0UL > 0xfffffffful
) ? 60 : 28;
210 in
-= (uint64_t)dig
<< pos
;
212 if (dig
|| digits
|| pos
< 0) {
214 dig
+= 'a' - '0' - 10;
215 buffer
[digits
++] = '0' + dig
;
223 /* converts unsigned long <in> to an hex string using the static itoa_buffer
224 * and returns the pointer to that string.
226 static __inline__
__attribute__((unused
))
227 char *utoh(unsigned long in
)
229 utoh_r(in
, itoa_buffer
);
233 /* Converts the unsigned long integer <in> to its string representation into
234 * buffer <buffer>, which must be long enough to store the number and the
235 * trailing zero (21 bytes for 18446744073709551615 in 64-bit, 11 for
236 * 4294967295 in 32-bit). The buffer is filled from the first byte, and the
237 * number of characters emitted (not counting the trailing zero) is returned.
238 * The function is constructed in a way to optimize the code size and avoid
239 * any divide that could add a dependency on large external functions.
241 static __attribute__((unused
))
242 int utoa_r(unsigned long in
, char *buffer
)
246 int pos
= (~0UL > 0xfffffffful
) ? 19 : 9;
250 for (dig
= 0, lim
= 1; dig
< pos
; dig
++)
253 if (digits
|| in
>= lim
|| !pos
) {
254 for (dig
= 0; in
>= lim
; dig
++)
256 buffer
[digits
++] = '0' + dig
;
264 /* Converts the signed long integer <in> to its string representation into
265 * buffer <buffer>, which must be long enough to store the number and the
266 * trailing zero (21 bytes for -9223372036854775808 in 64-bit, 12 for
267 * -2147483648 in 32-bit). The buffer is filled from the first byte, and the
268 * number of characters emitted (not counting the trailing zero) is returned.
270 static __attribute__((unused
))
271 int itoa_r(long in
, char *buffer
)
281 len
+= utoa_r(in
, ptr
);
285 /* for historical compatibility, same as above but returns the pointer to the
288 static __inline__
__attribute__((unused
))
289 char *ltoa_r(long in
, char *buffer
)
295 /* converts long integer <in> to a string using the static itoa_buffer and
296 * returns the pointer to that string.
298 static __inline__
__attribute__((unused
))
301 itoa_r(in
, itoa_buffer
);
305 /* converts long integer <in> to a string using the static itoa_buffer and
306 * returns the pointer to that string. Same as above, for compatibility.
308 static __inline__
__attribute__((unused
))
311 itoa_r(in
, itoa_buffer
);
315 /* converts unsigned long integer <in> to a string using the static itoa_buffer
316 * and returns the pointer to that string.
318 static __inline__
__attribute__((unused
))
319 char *utoa(unsigned long in
)
321 utoa_r(in
, itoa_buffer
);
325 /* Converts the unsigned 64-bit integer <in> to its hex representation into
326 * buffer <buffer>, which must be long enough to store the number and the
327 * trailing zero (17 bytes for "ffffffffffffffff"). The buffer is filled from
328 * the first byte, and the number of characters emitted (not counting the
329 * trailing zero) is returned. The function is constructed in a way to optimize
330 * the code size and avoid any divide that could add a dependency on large
331 * external functions.
333 static __attribute__((unused
))
334 int u64toh_r(uint64_t in
, char *buffer
)
336 signed char pos
= 60;
341 if (sizeof(long) >= 8) {
342 dig
= (in
>> pos
) & 0xF;
344 /* 32-bit platforms: avoid a 64-bit shift */
345 uint32_t d
= (pos
>= 32) ? (in
>> 32) : in
;
346 dig
= (d
>> (pos
& 31)) & 0xF;
349 dig
+= 'a' - '0' - 10;
351 if (dig
|| digits
|| pos
< 0)
352 buffer
[digits
++] = '0' + dig
;
359 /* converts uint64_t <in> to an hex string using the static itoa_buffer and
360 * returns the pointer to that string.
362 static __inline__
__attribute__((unused
))
363 char *u64toh(uint64_t in
)
365 u64toh_r(in
, itoa_buffer
);
369 /* Converts the unsigned 64-bit integer <in> to its string representation into
370 * buffer <buffer>, which must be long enough to store the number and the
371 * trailing zero (21 bytes for 18446744073709551615). The buffer is filled from
372 * the first byte, and the number of characters emitted (not counting the
373 * trailing zero) is returned. The function is constructed in a way to optimize
374 * the code size and avoid any divide that could add a dependency on large
375 * external functions.
377 static __attribute__((unused
))
378 int u64toa_r(uint64_t in
, char *buffer
)
380 unsigned long long lim
;
382 int pos
= 19; /* start with the highest possible digit */
386 for (dig
= 0, lim
= 1; dig
< pos
; dig
++)
389 if (digits
|| in
>= lim
|| !pos
) {
390 for (dig
= 0; in
>= lim
; dig
++)
392 buffer
[digits
++] = '0' + dig
;
400 /* Converts the signed 64-bit integer <in> to its string representation into
401 * buffer <buffer>, which must be long enough to store the number and the
402 * trailing zero (21 bytes for -9223372036854775808). The buffer is filled from
403 * the first byte, and the number of characters emitted (not counting the
404 * trailing zero) is returned.
406 static __attribute__((unused
))
407 int i64toa_r(int64_t in
, char *buffer
)
417 len
+= u64toa_r(in
, ptr
);
421 /* converts int64_t <in> to a string using the static itoa_buffer and returns
422 * the pointer to that string.
424 static __inline__
__attribute__((unused
))
425 char *i64toa(int64_t in
)
427 i64toa_r(in
, itoa_buffer
);
431 /* converts uint64_t <in> to a string using the static itoa_buffer and returns
432 * the pointer to that string.
434 static __inline__
__attribute__((unused
))
435 char *u64toa(uint64_t in
)
437 u64toa_r(in
, itoa_buffer
);
441 static __attribute__((unused
))
442 uintmax_t __strtox(const char *nptr
, char **endptr
, int base
, intmax_t lower_limit
, uintmax_t upper_limit
)
444 const char signed_
= lower_limit
!= 0;
445 unsigned char neg
= 0, overflow
= 0;
446 uintmax_t val
= 0, limit
, old_val
;
449 if (base
< 0 || base
> 36) {
454 while (isspace(*nptr
))
459 } else if (*nptr
== '-') {
465 limit
= -(uintmax_t)lower_limit
;
469 if ((base
== 0 || base
== 16) &&
470 (strncmp(nptr
, "0x", 2) == 0 || strncmp(nptr
, "0X", 2) == 0)) {
473 } else if (base
== 0 && strncmp(nptr
, "0", 1) == 0) {
476 } else if (base
== 0) {
483 if (c
>= '0' && c
<= '9')
485 else if (c
>= 'a' && c
<= 'z')
487 else if (c
>= 'A' && c
<= 'Z')
500 if (val
> limit
|| val
< old_val
)
510 *endptr
= (char *)nptr
;
511 return neg
? -val
: val
;
514 static __attribute__((unused
))
515 long strtol(const char *nptr
, char **endptr
, int base
)
517 return __strtox(nptr
, endptr
, base
, LONG_MIN
, LONG_MAX
);
520 static __attribute__((unused
))
521 unsigned long strtoul(const char *nptr
, char **endptr
, int base
)
523 return __strtox(nptr
, endptr
, base
, 0, ULONG_MAX
);
526 static __attribute__((unused
))
527 long long strtoll(const char *nptr
, char **endptr
, int base
)
529 return __strtox(nptr
, endptr
, base
, LLONG_MIN
, LLONG_MAX
);
532 static __attribute__((unused
))
533 unsigned long long strtoull(const char *nptr
, char **endptr
, int base
)
535 return __strtox(nptr
, endptr
, base
, 0, ULLONG_MAX
);
538 static __attribute__((unused
))
539 intmax_t strtoimax(const char *nptr
, char **endptr
, int base
)
541 return __strtox(nptr
, endptr
, base
, INTMAX_MIN
, INTMAX_MAX
);
544 static __attribute__((unused
))
545 uintmax_t strtoumax(const char *nptr
, char **endptr
, int base
)
547 return __strtox(nptr
, endptr
, base
, 0, UINTMAX_MAX
);
550 /* make sure to include all global symbols */
553 #endif /* _NOLIBC_STDLIB_H */