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 15 16 /* Buffer used to store int-to-ASCII conversions. Will only be implemented if 17 * any of the related functions is implemented. The area is large enough to 18 * store "18446744073709551615" or "-9223372036854775808" and the final zero. 19 */ 20 static __attribute__((unused)) char itoa_buffer[21]; 21 22 /* 23 * As much as possible, please keep functions alphabetically sorted. 24 */ 25 26 /* must be exported, as it's used by libgcc for various divide functions */ 27 __attribute__((weak,unused,noreturn,section(".text.nolibc_abort"))) 28 void abort(void) 29 { 30 sys_kill(sys_getpid(), SIGABRT); 31 for (;;); 32 } 33 34 static __attribute__((unused)) 35 long atol(const char *s) 36 { 37 unsigned long ret = 0; 38 unsigned long d; 39 int neg = 0; 40 41 if (*s == '-') { 42 neg = 1; 43 s++; 44 } 45 46 while (1) { 47 d = (*s++) - '0'; 48 if (d > 9) 49 break; 50 ret *= 10; 51 ret += d; 52 } 53 54 return neg ? -ret : ret; 55 } 56 57 static __attribute__((unused)) 58 int atoi(const char *s) 59 { 60 return atol(s); 61 } 62 63 /* Tries to find the environment variable named <name> in the environment array 64 * pointed to by global variable "environ" which must be declared as a char **, 65 * and must be terminated by a NULL (it is recommended to set this variable to 66 * the "envp" argument of main()). If the requested environment variable exists 67 * its value is returned otherwise NULL is returned. 68 */ 69 static __attribute__((unused)) 70 char *getenv(const char *name) 71 { 72 extern char **environ; 73 int idx, i; 74 75 if (environ) { 76 for (idx = 0; environ[idx]; idx++) { 77 for (i = 0; name[i] && name[i] == environ[idx][i];) 78 i++; 79 if (!name[i] && environ[idx][i] == '=') 80 return &environ[idx][i+1]; 81 } 82 } 83 return NULL; 84 } 85 86 /* Converts the unsigned long integer <in> to its hex representation into 87 * buffer <buffer>, which must be long enough to store the number and the 88 * trailing zero (17 bytes for "ffffffffffffffff" or 9 for "ffffffff"). The 89 * buffer is filled from the first byte, and the number of characters emitted 90 * (not counting the trailing zero) is returned. The function is constructed 91 * in a way to optimize the code size and avoid any divide that could add a 92 * dependency on large external functions. 93 */ 94 static __attribute__((unused)) 95 int utoh_r(unsigned long in, char *buffer) 96 { 97 signed char pos = (~0UL > 0xfffffffful) ? 60 : 28; 98 int digits = 0; 99 int dig; 100 101 do { 102 dig = in >> pos; 103 in -= (uint64_t)dig << pos; 104 pos -= 4; 105 if (dig || digits || pos < 0) { 106 if (dig > 9) 107 dig += 'a' - '0' - 10; 108 buffer[digits++] = '0' + dig; 109 } 110 } while (pos >= 0); 111 112 buffer[digits] = 0; 113 return digits; 114 } 115 116 /* converts unsigned long <in> to an hex string using the static itoa_buffer 117 * and returns the pointer to that string. 118 */ 119 static inline __attribute__((unused)) 120 char *utoh(unsigned long in) 121 { 122 utoh_r(in, itoa_buffer); 123 return itoa_buffer; 124 } 125 126 /* Converts the unsigned long integer <in> to its string representation into 127 * buffer <buffer>, which must be long enough to store the number and the 128 * trailing zero (21 bytes for 18446744073709551615 in 64-bit, 11 for 129 * 4294967295 in 32-bit). The buffer is filled from the first byte, and the 130 * number of characters emitted (not counting the trailing zero) is returned. 131 * The function is constructed in a way to optimize the code size and avoid 132 * any divide that could add a dependency on large external functions. 133 */ 134 static __attribute__((unused)) 135 int utoa_r(unsigned long in, char *buffer) 136 { 137 unsigned long lim; 138 int digits = 0; 139 int pos = (~0UL > 0xfffffffful) ? 19 : 9; 140 int dig; 141 142 do { 143 for (dig = 0, lim = 1; dig < pos; dig++) 144 lim *= 10; 145 146 if (digits || in >= lim || !pos) { 147 for (dig = 0; in >= lim; dig++) 148 in -= lim; 149 buffer[digits++] = '0' + dig; 150 } 151 } while (pos--); 152 153 buffer[digits] = 0; 154 return digits; 155 } 156 157 /* Converts the signed long integer <in> to its string representation into 158 * buffer <buffer>, which must be long enough to store the number and the 159 * trailing zero (21 bytes for -9223372036854775808 in 64-bit, 12 for 160 * -2147483648 in 32-bit). The buffer is filled from the first byte, and the 161 * number of characters emitted (not counting the trailing zero) is returned. 162 */ 163 static __attribute__((unused)) 164 int itoa_r(long in, char *buffer) 165 { 166 char *ptr = buffer; 167 int len = 0; 168 169 if (in < 0) { 170 in = -in; 171 *(ptr++) = '-'; 172 len++; 173 } 174 len += utoa_r(in, ptr); 175 return len; 176 } 177 178 /* for historical compatibility, same as above but returns the pointer to the 179 * buffer. 180 */ 181 static inline __attribute__((unused)) 182 char *ltoa_r(long in, char *buffer) 183 { 184 itoa_r(in, buffer); 185 return buffer; 186 } 187 188 /* converts long integer <in> to a string using the static itoa_buffer and 189 * returns the pointer to that string. 190 */ 191 static inline __attribute__((unused)) 192 char *itoa(long in) 193 { 194 itoa_r(in, itoa_buffer); 195 return itoa_buffer; 196 } 197 198 /* converts long integer <in> to a string using the static itoa_buffer and 199 * returns the pointer to that string. Same as above, for compatibility. 200 */ 201 static inline __attribute__((unused)) 202 char *ltoa(long in) 203 { 204 itoa_r(in, itoa_buffer); 205 return itoa_buffer; 206 } 207 208 /* converts unsigned long integer <in> to a string using the static itoa_buffer 209 * and returns the pointer to that string. 210 */ 211 static inline __attribute__((unused)) 212 char *utoa(unsigned long in) 213 { 214 utoa_r(in, itoa_buffer); 215 return itoa_buffer; 216 } 217 218 /* Converts the unsigned 64-bit integer <in> to its hex representation into 219 * buffer <buffer>, which must be long enough to store the number and the 220 * trailing zero (17 bytes for "ffffffffffffffff"). The buffer is filled from 221 * the first byte, and the number of characters emitted (not counting the 222 * trailing zero) is returned. The function is constructed in a way to optimize 223 * the code size and avoid any divide that could add a dependency on large 224 * external functions. 225 */ 226 static __attribute__((unused)) 227 int u64toh_r(uint64_t in, char *buffer) 228 { 229 signed char pos = 60; 230 int digits = 0; 231 int dig; 232 233 do { 234 if (sizeof(long) >= 8) { 235 dig = (in >> pos) & 0xF; 236 } else { 237 /* 32-bit platforms: avoid a 64-bit shift */ 238 uint32_t d = (pos >= 32) ? (in >> 32) : in; 239 dig = (d >> (pos & 31)) & 0xF; 240 } 241 if (dig > 9) 242 dig += 'a' - '0' - 10; 243 pos -= 4; 244 if (dig || digits || pos < 0) 245 buffer[digits++] = '0' + dig; 246 } while (pos >= 0); 247 248 buffer[digits] = 0; 249 return digits; 250 } 251 252 /* converts uint64_t <in> to an hex string using the static itoa_buffer and 253 * returns the pointer to that string. 254 */ 255 static inline __attribute__((unused)) 256 char *u64toh(uint64_t in) 257 { 258 u64toh_r(in, itoa_buffer); 259 return itoa_buffer; 260 } 261 262 /* Converts the unsigned 64-bit 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 18446744073709551615). The buffer is filled from 265 * the first byte, and the number of characters emitted (not counting the 266 * trailing zero) is returned. The function is constructed in a way to optimize 267 * the code size and avoid any divide that could add a dependency on large 268 * external functions. 269 */ 270 static __attribute__((unused)) 271 int u64toa_r(uint64_t in, char *buffer) 272 { 273 unsigned long long lim; 274 int digits = 0; 275 int pos = 19; /* start with the highest possible digit */ 276 int dig; 277 278 do { 279 for (dig = 0, lim = 1; dig < pos; dig++) 280 lim *= 10; 281 282 if (digits || in >= lim || !pos) { 283 for (dig = 0; in >= lim; dig++) 284 in -= lim; 285 buffer[digits++] = '0' + dig; 286 } 287 } while (pos--); 288 289 buffer[digits] = 0; 290 return digits; 291 } 292 293 /* Converts the signed 64-bit integer <in> to its string representation into 294 * buffer <buffer>, which must be long enough to store the number and the 295 * trailing zero (21 bytes for -9223372036854775808). The buffer is filled from 296 * the first byte, and the number of characters emitted (not counting the 297 * trailing zero) is returned. 298 */ 299 static __attribute__((unused)) 300 int i64toa_r(int64_t in, char *buffer) 301 { 302 char *ptr = buffer; 303 int len = 0; 304 305 if (in < 0) { 306 in = -in; 307 *(ptr++) = '-'; 308 len++; 309 } 310 len += u64toa_r(in, ptr); 311 return len; 312 } 313 314 /* converts int64_t <in> to a string using the static itoa_buffer and returns 315 * the pointer to that string. 316 */ 317 static inline __attribute__((unused)) 318 char *i64toa(int64_t in) 319 { 320 i64toa_r(in, itoa_buffer); 321 return itoa_buffer; 322 } 323 324 /* converts uint64_t <in> to a string using the static itoa_buffer and returns 325 * the pointer to that string. 326 */ 327 static inline __attribute__((unused)) 328 char *u64toa(uint64_t in) 329 { 330 u64toa_r(in, itoa_buffer); 331 return itoa_buffer; 332 } 333 334 #endif /* _NOLIBC_STDLIB_H */ 335