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