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