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