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