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