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 #ifndef _NOLIBC_STDLIB_H 8 #define _NOLIBC_STDLIB_H 9 10 #include "std.h" 11 #include "arch.h" 12 #include "types.h" 13 #include "sys.h" 14 #include "string.h" 15 #include <linux/auxvec.h> 16 17 struct nolibc_heap { 18 size_t len; 19 char user_p[] __attribute__((__aligned__)); 20 }; 21 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. 25 */ 26 static __attribute__((unused)) char itoa_buffer[21]; 27 28 /* 29 * As much as possible, please keep functions alphabetically sorted. 30 */ 31 32 /* must be exported, as it's used by libgcc for various divide functions */ 33 __attribute__((weak,unused,noreturn,section(".text.nolibc_abort"))) 34 void abort(void) 35 { 36 sys_kill(sys_getpid(), SIGABRT); 37 for (;;); 38 } 39 40 static __attribute__((unused)) 41 long atol(const char *s) 42 { 43 unsigned long ret = 0; 44 unsigned long d; 45 int neg = 0; 46 47 if (*s == '-') { 48 neg = 1; 49 s++; 50 } 51 52 while (1) { 53 d = (*s++) - '0'; 54 if (d > 9) 55 break; 56 ret *= 10; 57 ret += d; 58 } 59 60 return neg ? -ret : ret; 61 } 62 63 static __attribute__((unused)) 64 int atoi(const char *s) 65 { 66 return atol(s); 67 } 68 69 static __attribute__((unused)) 70 void free(void *ptr) 71 { 72 struct nolibc_heap *heap; 73 74 if (!ptr) 75 return; 76 77 heap = container_of(ptr, struct nolibc_heap, user_p); 78 munmap(heap, heap->len); 79 } 80 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 86 * returned. getenv() is forcefully inlined so that the reference to "environ" 87 * will be dropped if unused, even at -O0. 88 */ 89 static __attribute__((unused)) 90 char *_getenv(const char *name, char **environ) 91 { 92 int idx, i; 93 94 if (environ) { 95 for (idx = 0; environ[idx]; idx++) { 96 for (i = 0; name[i] && name[i] == environ[idx][i];) 97 i++; 98 if (!name[i] && environ[idx][i] == '=') 99 return &environ[idx][i+1]; 100 } 101 } 102 return NULL; 103 } 104 105 static inline __attribute__((unused,always_inline)) 106 char *getenv(const char *name) 107 { 108 extern char **environ; 109 return _getenv(name, environ); 110 } 111 112 static __attribute__((unused)) 113 unsigned long getauxval(unsigned long type) 114 { 115 const unsigned long *auxv = _auxv; 116 unsigned long ret; 117 118 if (!auxv) 119 return 0; 120 121 while (1) { 122 if (!auxv[0] && !auxv[1]) { 123 ret = 0; 124 break; 125 } 126 127 if (auxv[0] == type) { 128 ret = auxv[1]; 129 break; 130 } 131 132 auxv += 2; 133 } 134 135 return ret; 136 } 137 138 static __attribute__((unused)) 139 void *malloc(size_t len) 140 { 141 struct nolibc_heap *heap; 142 143 /* Always allocate memory with size multiple of 4096. */ 144 len = sizeof(*heap) + len; 145 len = (len + 4095UL) & -4096UL; 146 heap = mmap(NULL, len, PROT_READ|PROT_WRITE, MAP_ANONYMOUS|MAP_PRIVATE, 147 -1, 0); 148 if (__builtin_expect(heap == MAP_FAILED, 0)) 149 return NULL; 150 151 heap->len = len; 152 return heap->user_p; 153 } 154 155 static __attribute__((unused)) 156 void *calloc(size_t size, size_t nmemb) 157 { 158 size_t x = size * nmemb; 159 160 if (__builtin_expect(size && ((x / size) != nmemb), 0)) { 161 SET_ERRNO(ENOMEM); 162 return NULL; 163 } 164 165 /* 166 * No need to zero the heap, the MAP_ANONYMOUS in malloc() 167 * already does it. 168 */ 169 return malloc(x); 170 } 171 172 static __attribute__((unused)) 173 void *realloc(void *old_ptr, size_t new_size) 174 { 175 struct nolibc_heap *heap; 176 size_t user_p_len; 177 void *ret; 178 179 if (!old_ptr) 180 return malloc(new_size); 181 182 heap = container_of(old_ptr, struct nolibc_heap, user_p); 183 user_p_len = heap->len - sizeof(*heap); 184 /* 185 * Don't realloc() if @user_p_len >= @new_size, this block of 186 * memory is still enough to handle the @new_size. Just return 187 * the same pointer. 188 */ 189 if (user_p_len >= new_size) 190 return old_ptr; 191 192 ret = malloc(new_size); 193 if (__builtin_expect(!ret, 0)) 194 return NULL; 195 196 memcpy(ret, heap->user_p, heap->len); 197 munmap(heap, heap->len); 198 return ret; 199 } 200 201 /* Converts the unsigned long integer <in> to its hex representation into 202 * buffer <buffer>, which must be long enough to store the number and the 203 * trailing zero (17 bytes for "ffffffffffffffff" or 9 for "ffffffff"). The 204 * buffer is filled from the first byte, and the number of characters emitted 205 * (not counting the trailing zero) is returned. The function is constructed 206 * in a way to optimize the code size and avoid any divide that could add a 207 * dependency on large external functions. 208 */ 209 static __attribute__((unused)) 210 int utoh_r(unsigned long in, char *buffer) 211 { 212 signed char pos = (~0UL > 0xfffffffful) ? 60 : 28; 213 int digits = 0; 214 int dig; 215 216 do { 217 dig = in >> pos; 218 in -= (uint64_t)dig << pos; 219 pos -= 4; 220 if (dig || digits || pos < 0) { 221 if (dig > 9) 222 dig += 'a' - '0' - 10; 223 buffer[digits++] = '0' + dig; 224 } 225 } while (pos >= 0); 226 227 buffer[digits] = 0; 228 return digits; 229 } 230 231 /* converts unsigned long <in> to an hex string using the static itoa_buffer 232 * and returns the pointer to that string. 233 */ 234 static inline __attribute__((unused)) 235 char *utoh(unsigned long in) 236 { 237 utoh_r(in, itoa_buffer); 238 return itoa_buffer; 239 } 240 241 /* Converts the unsigned long integer <in> to its string representation into 242 * buffer <buffer>, which must be long enough to store the number and the 243 * trailing zero (21 bytes for 18446744073709551615 in 64-bit, 11 for 244 * 4294967295 in 32-bit). The buffer is filled from the first byte, and the 245 * number of characters emitted (not counting the trailing zero) is returned. 246 * The function is constructed in a way to optimize the code size and avoid 247 * any divide that could add a dependency on large external functions. 248 */ 249 static __attribute__((unused)) 250 int utoa_r(unsigned long in, char *buffer) 251 { 252 unsigned long lim; 253 int digits = 0; 254 int pos = (~0UL > 0xfffffffful) ? 19 : 9; 255 int dig; 256 257 do { 258 for (dig = 0, lim = 1; dig < pos; dig++) 259 lim *= 10; 260 261 if (digits || in >= lim || !pos) { 262 for (dig = 0; in >= lim; dig++) 263 in -= lim; 264 buffer[digits++] = '0' + dig; 265 } 266 } while (pos--); 267 268 buffer[digits] = 0; 269 return digits; 270 } 271 272 /* Converts the signed long integer <in> to its string representation into 273 * buffer <buffer>, which must be long enough to store the number and the 274 * trailing zero (21 bytes for -9223372036854775808 in 64-bit, 12 for 275 * -2147483648 in 32-bit). The buffer is filled from the first byte, and the 276 * number of characters emitted (not counting the trailing zero) is returned. 277 */ 278 static __attribute__((unused)) 279 int itoa_r(long in, char *buffer) 280 { 281 char *ptr = buffer; 282 int len = 0; 283 284 if (in < 0) { 285 in = -in; 286 *(ptr++) = '-'; 287 len++; 288 } 289 len += utoa_r(in, ptr); 290 return len; 291 } 292 293 /* for historical compatibility, same as above but returns the pointer to the 294 * buffer. 295 */ 296 static inline __attribute__((unused)) 297 char *ltoa_r(long in, char *buffer) 298 { 299 itoa_r(in, buffer); 300 return buffer; 301 } 302 303 /* converts long integer <in> to a string using the static itoa_buffer and 304 * returns the pointer to that string. 305 */ 306 static inline __attribute__((unused)) 307 char *itoa(long in) 308 { 309 itoa_r(in, itoa_buffer); 310 return itoa_buffer; 311 } 312 313 /* converts long integer <in> to a string using the static itoa_buffer and 314 * returns the pointer to that string. Same as above, for compatibility. 315 */ 316 static inline __attribute__((unused)) 317 char *ltoa(long in) 318 { 319 itoa_r(in, itoa_buffer); 320 return itoa_buffer; 321 } 322 323 /* converts unsigned long integer <in> to a string using the static itoa_buffer 324 * and returns the pointer to that string. 325 */ 326 static inline __attribute__((unused)) 327 char *utoa(unsigned long in) 328 { 329 utoa_r(in, itoa_buffer); 330 return itoa_buffer; 331 } 332 333 /* Converts the unsigned 64-bit integer <in> to its hex representation into 334 * buffer <buffer>, which must be long enough to store the number and the 335 * trailing zero (17 bytes for "ffffffffffffffff"). The buffer is filled from 336 * the first byte, and the number of characters emitted (not counting the 337 * trailing zero) is returned. The function is constructed in a way to optimize 338 * the code size and avoid any divide that could add a dependency on large 339 * external functions. 340 */ 341 static __attribute__((unused)) 342 int u64toh_r(uint64_t in, char *buffer) 343 { 344 signed char pos = 60; 345 int digits = 0; 346 int dig; 347 348 do { 349 if (sizeof(long) >= 8) { 350 dig = (in >> pos) & 0xF; 351 } else { 352 /* 32-bit platforms: avoid a 64-bit shift */ 353 uint32_t d = (pos >= 32) ? (in >> 32) : in; 354 dig = (d >> (pos & 31)) & 0xF; 355 } 356 if (dig > 9) 357 dig += 'a' - '0' - 10; 358 pos -= 4; 359 if (dig || digits || pos < 0) 360 buffer[digits++] = '0' + dig; 361 } while (pos >= 0); 362 363 buffer[digits] = 0; 364 return digits; 365 } 366 367 /* converts uint64_t <in> to an hex string using the static itoa_buffer and 368 * returns the pointer to that string. 369 */ 370 static inline __attribute__((unused)) 371 char *u64toh(uint64_t in) 372 { 373 u64toh_r(in, itoa_buffer); 374 return itoa_buffer; 375 } 376 377 /* Converts the unsigned 64-bit integer <in> to its string representation into 378 * buffer <buffer>, which must be long enough to store the number and the 379 * trailing zero (21 bytes for 18446744073709551615). The buffer is filled from 380 * the first byte, and the number of characters emitted (not counting the 381 * trailing zero) is returned. The function is constructed in a way to optimize 382 * the code size and avoid any divide that could add a dependency on large 383 * external functions. 384 */ 385 static __attribute__((unused)) 386 int u64toa_r(uint64_t in, char *buffer) 387 { 388 unsigned long long lim; 389 int digits = 0; 390 int pos = 19; /* start with the highest possible digit */ 391 int dig; 392 393 do { 394 for (dig = 0, lim = 1; dig < pos; dig++) 395 lim *= 10; 396 397 if (digits || in >= lim || !pos) { 398 for (dig = 0; in >= lim; dig++) 399 in -= lim; 400 buffer[digits++] = '0' + dig; 401 } 402 } while (pos--); 403 404 buffer[digits] = 0; 405 return digits; 406 } 407 408 /* Converts the signed 64-bit integer <in> to its string representation into 409 * buffer <buffer>, which must be long enough to store the number and the 410 * trailing zero (21 bytes for -9223372036854775808). The buffer is filled from 411 * the first byte, and the number of characters emitted (not counting the 412 * trailing zero) is returned. 413 */ 414 static __attribute__((unused)) 415 int i64toa_r(int64_t in, char *buffer) 416 { 417 char *ptr = buffer; 418 int len = 0; 419 420 if (in < 0) { 421 in = -in; 422 *(ptr++) = '-'; 423 len++; 424 } 425 len += u64toa_r(in, ptr); 426 return len; 427 } 428 429 /* converts int64_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 *i64toa(int64_t in) 434 { 435 i64toa_r(in, itoa_buffer); 436 return itoa_buffer; 437 } 438 439 /* converts uint64_t <in> to a string using the static itoa_buffer and returns 440 * the pointer to that string. 441 */ 442 static inline __attribute__((unused)) 443 char *u64toa(uint64_t in) 444 { 445 u64toa_r(in, itoa_buffer); 446 return itoa_buffer; 447 } 448 449 /* make sure to include all global symbols */ 450 #include "nolibc.h" 451 452 #endif /* _NOLIBC_STDLIB_H */ 453