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 size_t x = size * nmemb; 132 133 if (__builtin_expect(size && ((x / size) != nmemb), 0)) { 134 SET_ERRNO(ENOMEM); 135 return NULL; 136 } 137 138 /* 139 * No need to zero the heap, the MAP_ANONYMOUS in malloc() 140 * already does it. 141 */ 142 return malloc(x); 143 } 144 145 static __attribute__((unused)) 146 void *realloc(void *old_ptr, size_t new_size) 147 { 148 struct nolibc_heap *heap; 149 size_t user_p_len; 150 void *ret; 151 152 if (!old_ptr) 153 return malloc(new_size); 154 155 heap = container_of(old_ptr, struct nolibc_heap, user_p); 156 user_p_len = heap->len - sizeof(*heap); 157 /* 158 * Don't realloc() if @user_p_len >= @new_size, this block of 159 * memory is still enough to handle the @new_size. Just return 160 * the same pointer. 161 */ 162 if (user_p_len >= new_size) 163 return old_ptr; 164 165 ret = malloc(new_size); 166 if (__builtin_expect(!ret, 0)) 167 return NULL; 168 169 memcpy(ret, heap->user_p, heap->len); 170 munmap(heap, heap->len); 171 return ret; 172 } 173 174 /* Converts the unsigned long integer <in> to its hex representation into 175 * buffer <buffer>, which must be long enough to store the number and the 176 * trailing zero (17 bytes for "ffffffffffffffff" or 9 for "ffffffff"). The 177 * buffer is filled from the first byte, and the number of characters emitted 178 * (not counting the trailing zero) is returned. The function is constructed 179 * in a way to optimize the code size and avoid any divide that could add a 180 * dependency on large external functions. 181 */ 182 static __attribute__((unused)) 183 int utoh_r(unsigned long in, char *buffer) 184 { 185 signed char pos = (~0UL > 0xfffffffful) ? 60 : 28; 186 int digits = 0; 187 int dig; 188 189 do { 190 dig = in >> pos; 191 in -= (uint64_t)dig << pos; 192 pos -= 4; 193 if (dig || digits || pos < 0) { 194 if (dig > 9) 195 dig += 'a' - '0' - 10; 196 buffer[digits++] = '0' + dig; 197 } 198 } while (pos >= 0); 199 200 buffer[digits] = 0; 201 return digits; 202 } 203 204 /* converts unsigned long <in> to an hex string using the static itoa_buffer 205 * and returns the pointer to that string. 206 */ 207 static inline __attribute__((unused)) 208 char *utoh(unsigned long in) 209 { 210 utoh_r(in, itoa_buffer); 211 return itoa_buffer; 212 } 213 214 /* Converts the unsigned long integer <in> to its string representation into 215 * buffer <buffer>, which must be long enough to store the number and the 216 * trailing zero (21 bytes for 18446744073709551615 in 64-bit, 11 for 217 * 4294967295 in 32-bit). The buffer is filled from the first byte, and the 218 * number of characters emitted (not counting the trailing zero) is returned. 219 * The function is constructed in a way to optimize the code size and avoid 220 * any divide that could add a dependency on large external functions. 221 */ 222 static __attribute__((unused)) 223 int utoa_r(unsigned long in, char *buffer) 224 { 225 unsigned long lim; 226 int digits = 0; 227 int pos = (~0UL > 0xfffffffful) ? 19 : 9; 228 int dig; 229 230 do { 231 for (dig = 0, lim = 1; dig < pos; dig++) 232 lim *= 10; 233 234 if (digits || in >= lim || !pos) { 235 for (dig = 0; in >= lim; dig++) 236 in -= lim; 237 buffer[digits++] = '0' + dig; 238 } 239 } while (pos--); 240 241 buffer[digits] = 0; 242 return digits; 243 } 244 245 /* Converts the signed long integer <in> to its string representation into 246 * buffer <buffer>, which must be long enough to store the number and the 247 * trailing zero (21 bytes for -9223372036854775808 in 64-bit, 12 for 248 * -2147483648 in 32-bit). The buffer is filled from the first byte, and the 249 * number of characters emitted (not counting the trailing zero) is returned. 250 */ 251 static __attribute__((unused)) 252 int itoa_r(long in, char *buffer) 253 { 254 char *ptr = buffer; 255 int len = 0; 256 257 if (in < 0) { 258 in = -in; 259 *(ptr++) = '-'; 260 len++; 261 } 262 len += utoa_r(in, ptr); 263 return len; 264 } 265 266 /* for historical compatibility, same as above but returns the pointer to the 267 * buffer. 268 */ 269 static inline __attribute__((unused)) 270 char *ltoa_r(long in, char *buffer) 271 { 272 itoa_r(in, buffer); 273 return buffer; 274 } 275 276 /* converts long integer <in> to a string using the static itoa_buffer and 277 * returns the pointer to that string. 278 */ 279 static inline __attribute__((unused)) 280 char *itoa(long in) 281 { 282 itoa_r(in, itoa_buffer); 283 return itoa_buffer; 284 } 285 286 /* converts long integer <in> to a string using the static itoa_buffer and 287 * returns the pointer to that string. Same as above, for compatibility. 288 */ 289 static inline __attribute__((unused)) 290 char *ltoa(long in) 291 { 292 itoa_r(in, itoa_buffer); 293 return itoa_buffer; 294 } 295 296 /* converts unsigned long integer <in> to a string using the static itoa_buffer 297 * and returns the pointer to that string. 298 */ 299 static inline __attribute__((unused)) 300 char *utoa(unsigned long in) 301 { 302 utoa_r(in, itoa_buffer); 303 return itoa_buffer; 304 } 305 306 /* Converts the unsigned 64-bit integer <in> to its hex representation into 307 * buffer <buffer>, which must be long enough to store the number and the 308 * trailing zero (17 bytes for "ffffffffffffffff"). The buffer is filled from 309 * the first byte, and the number of characters emitted (not counting the 310 * trailing zero) is returned. The function is constructed in a way to optimize 311 * the code size and avoid any divide that could add a dependency on large 312 * external functions. 313 */ 314 static __attribute__((unused)) 315 int u64toh_r(uint64_t in, char *buffer) 316 { 317 signed char pos = 60; 318 int digits = 0; 319 int dig; 320 321 do { 322 if (sizeof(long) >= 8) { 323 dig = (in >> pos) & 0xF; 324 } else { 325 /* 32-bit platforms: avoid a 64-bit shift */ 326 uint32_t d = (pos >= 32) ? (in >> 32) : in; 327 dig = (d >> (pos & 31)) & 0xF; 328 } 329 if (dig > 9) 330 dig += 'a' - '0' - 10; 331 pos -= 4; 332 if (dig || digits || pos < 0) 333 buffer[digits++] = '0' + dig; 334 } while (pos >= 0); 335 336 buffer[digits] = 0; 337 return digits; 338 } 339 340 /* converts uint64_t <in> to an hex string using the static itoa_buffer and 341 * returns the pointer to that string. 342 */ 343 static inline __attribute__((unused)) 344 char *u64toh(uint64_t in) 345 { 346 u64toh_r(in, itoa_buffer); 347 return itoa_buffer; 348 } 349 350 /* Converts the unsigned 64-bit integer <in> to its string representation into 351 * buffer <buffer>, which must be long enough to store the number and the 352 * trailing zero (21 bytes for 18446744073709551615). The buffer is filled from 353 * the first byte, and the number of characters emitted (not counting the 354 * trailing zero) is returned. The function is constructed in a way to optimize 355 * the code size and avoid any divide that could add a dependency on large 356 * external functions. 357 */ 358 static __attribute__((unused)) 359 int u64toa_r(uint64_t in, char *buffer) 360 { 361 unsigned long long lim; 362 int digits = 0; 363 int pos = 19; /* start with the highest possible digit */ 364 int dig; 365 366 do { 367 for (dig = 0, lim = 1; dig < pos; dig++) 368 lim *= 10; 369 370 if (digits || in >= lim || !pos) { 371 for (dig = 0; in >= lim; dig++) 372 in -= lim; 373 buffer[digits++] = '0' + dig; 374 } 375 } while (pos--); 376 377 buffer[digits] = 0; 378 return digits; 379 } 380 381 /* Converts the signed 64-bit integer <in> to its string representation into 382 * buffer <buffer>, which must be long enough to store the number and the 383 * trailing zero (21 bytes for -9223372036854775808). The buffer is filled from 384 * the first byte, and the number of characters emitted (not counting the 385 * trailing zero) is returned. 386 */ 387 static __attribute__((unused)) 388 int i64toa_r(int64_t in, char *buffer) 389 { 390 char *ptr = buffer; 391 int len = 0; 392 393 if (in < 0) { 394 in = -in; 395 *(ptr++) = '-'; 396 len++; 397 } 398 len += u64toa_r(in, ptr); 399 return len; 400 } 401 402 /* converts int64_t <in> to a string using the static itoa_buffer and returns 403 * the pointer to that string. 404 */ 405 static inline __attribute__((unused)) 406 char *i64toa(int64_t in) 407 { 408 i64toa_r(in, itoa_buffer); 409 return itoa_buffer; 410 } 411 412 /* converts uint64_t <in> to a string using the static itoa_buffer and returns 413 * the pointer to that string. 414 */ 415 static inline __attribute__((unused)) 416 char *u64toa(uint64_t in) 417 { 418 u64toa_r(in, itoa_buffer); 419 return itoa_buffer; 420 } 421 422 /* make sure to include all global symbols */ 423 #include "nolibc.h" 424 425 #endif /* _NOLIBC_STDLIB_H */ 426