Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
torvalds
GitHub Repository: torvalds/linux
Path: blob/master/tools/include/nolibc/stdlib.h
49129 views
1
/* SPDX-License-Identifier: LGPL-2.1 OR MIT */
2
/*
3
* stdlib function definitions for NOLIBC
4
* Copyright (C) 2017-2021 Willy Tarreau <[email protected]>
5
*/
6
7
/* make sure to include all global symbols */
8
#include "nolibc.h"
9
10
#ifndef _NOLIBC_STDLIB_H
11
#define _NOLIBC_STDLIB_H
12
13
#include "std.h"
14
#include "arch.h"
15
#include "types.h"
16
#include "sys.h"
17
#include "string.h"
18
#include <linux/auxvec.h>
19
20
struct nolibc_heap {
21
size_t len;
22
char user_p[] __attribute__((__aligned__));
23
};
24
25
/* Buffer used to store int-to-ASCII conversions. Will only be implemented if
26
* any of the related functions is implemented. The area is large enough to
27
* store "18446744073709551615" or "-9223372036854775808" and the final zero.
28
*/
29
static __attribute__((unused)) char itoa_buffer[21];
30
31
/*
32
* As much as possible, please keep functions alphabetically sorted.
33
*/
34
35
static __inline__
36
int abs(int j)
37
{
38
return j >= 0 ? j : -j;
39
}
40
41
static __inline__
42
long labs(long j)
43
{
44
return j >= 0 ? j : -j;
45
}
46
47
static __inline__
48
long long llabs(long long j)
49
{
50
return j >= 0 ? j : -j;
51
}
52
53
/* must be exported, as it's used by libgcc for various divide functions */
54
void abort(void);
55
__attribute__((weak,unused,noreturn,section(".text.nolibc_abort")))
56
void abort(void)
57
{
58
sys_kill(sys_getpid(), SIGABRT);
59
for (;;);
60
}
61
62
static __attribute__((unused))
63
long atol(const char *s)
64
{
65
unsigned long ret = 0;
66
unsigned long d;
67
int neg = 0;
68
69
if (*s == '-') {
70
neg = 1;
71
s++;
72
}
73
74
while (1) {
75
d = (*s++) - '0';
76
if (d > 9)
77
break;
78
ret *= 10;
79
ret += d;
80
}
81
82
return neg ? -ret : ret;
83
}
84
85
static __attribute__((unused))
86
int atoi(const char *s)
87
{
88
return atol(s);
89
}
90
91
static __attribute__((unused))
92
void free(void *ptr)
93
{
94
struct nolibc_heap *heap;
95
96
if (!ptr)
97
return;
98
99
heap = container_of(ptr, struct nolibc_heap, user_p);
100
munmap(heap, heap->len);
101
}
102
103
#ifndef NOLIBC_NO_RUNTIME
104
/* getenv() tries to find the environment variable named <name> in the
105
* environment array pointed to by global variable "environ" which must be
106
* declared as a char **, and must be terminated by a NULL (it is recommended
107
* to set this variable to the "envp" argument of main()). If the requested
108
* environment variable exists its value is returned otherwise NULL is
109
* returned.
110
*/
111
static __attribute__((unused))
112
char *getenv(const char *name)
113
{
114
int idx, i;
115
116
if (environ) {
117
for (idx = 0; environ[idx]; idx++) {
118
for (i = 0; name[i] && name[i] == environ[idx][i];)
119
i++;
120
if (!name[i] && environ[idx][i] == '=')
121
return &environ[idx][i+1];
122
}
123
}
124
return NULL;
125
}
126
#endif /* NOLIBC_NO_RUNTIME */
127
128
static __attribute__((unused))
129
void *malloc(size_t len)
130
{
131
struct nolibc_heap *heap;
132
133
/* Always allocate memory with size multiple of 4096. */
134
len = sizeof(*heap) + len;
135
len = (len + 4095UL) & -4096UL;
136
heap = mmap(NULL, len, PROT_READ|PROT_WRITE, MAP_ANONYMOUS|MAP_PRIVATE,
137
-1, 0);
138
if (__builtin_expect(heap == MAP_FAILED, 0))
139
return NULL;
140
141
heap->len = len;
142
return heap->user_p;
143
}
144
145
static __attribute__((unused))
146
void *calloc(size_t size, size_t nmemb)
147
{
148
size_t x = size * nmemb;
149
150
if (__builtin_expect(size && ((x / size) != nmemb), 0)) {
151
SET_ERRNO(ENOMEM);
152
return NULL;
153
}
154
155
/*
156
* No need to zero the heap, the MAP_ANONYMOUS in malloc()
157
* already does it.
158
*/
159
return malloc(x);
160
}
161
162
static __attribute__((unused))
163
void *realloc(void *old_ptr, size_t new_size)
164
{
165
struct nolibc_heap *heap;
166
size_t user_p_len;
167
void *ret;
168
169
if (!old_ptr)
170
return malloc(new_size);
171
172
heap = container_of(old_ptr, struct nolibc_heap, user_p);
173
user_p_len = heap->len - sizeof(*heap);
174
/*
175
* Don't realloc() if @user_p_len >= @new_size, this block of
176
* memory is still enough to handle the @new_size. Just return
177
* the same pointer.
178
*/
179
if (user_p_len >= new_size)
180
return old_ptr;
181
182
ret = malloc(new_size);
183
if (__builtin_expect(!ret, 0))
184
return NULL;
185
186
memcpy(ret, heap->user_p, user_p_len);
187
munmap(heap, heap->len);
188
return ret;
189
}
190
191
/* Converts the unsigned long integer <in> to its hex representation into
192
* buffer <buffer>, which must be long enough to store the number and the
193
* trailing zero (17 bytes for "ffffffffffffffff" or 9 for "ffffffff"). The
194
* buffer is filled from the first byte, and the number of characters emitted
195
* (not counting the trailing zero) is returned. The function is constructed
196
* in a way to optimize the code size and avoid any divide that could add a
197
* dependency on large external functions.
198
*/
199
static __attribute__((unused))
200
int utoh_r(unsigned long in, char *buffer)
201
{
202
signed char pos = (~0UL > 0xfffffffful) ? 60 : 28;
203
int digits = 0;
204
int dig;
205
206
do {
207
dig = in >> pos;
208
in -= (uint64_t)dig << pos;
209
pos -= 4;
210
if (dig || digits || pos < 0) {
211
if (dig > 9)
212
dig += 'a' - '0' - 10;
213
buffer[digits++] = '0' + dig;
214
}
215
} while (pos >= 0);
216
217
buffer[digits] = 0;
218
return digits;
219
}
220
221
/* converts unsigned long <in> to an hex string using the static itoa_buffer
222
* and returns the pointer to that string.
223
*/
224
static __inline__ __attribute__((unused))
225
char *utoh(unsigned long in)
226
{
227
utoh_r(in, itoa_buffer);
228
return itoa_buffer;
229
}
230
231
/* Converts the unsigned long integer <in> to its string representation into
232
* buffer <buffer>, which must be long enough to store the number and the
233
* trailing zero (21 bytes for 18446744073709551615 in 64-bit, 11 for
234
* 4294967295 in 32-bit). The buffer is filled from the first byte, and the
235
* number of characters emitted (not counting the trailing zero) is returned.
236
* The function is constructed in a way to optimize the code size and avoid
237
* any divide that could add a dependency on large external functions.
238
*/
239
static __attribute__((unused))
240
int utoa_r(unsigned long in, char *buffer)
241
{
242
unsigned long lim;
243
int digits = 0;
244
int pos = (~0UL > 0xfffffffful) ? 19 : 9;
245
int dig;
246
247
do {
248
for (dig = 0, lim = 1; dig < pos; dig++)
249
lim *= 10;
250
251
if (digits || in >= lim || !pos) {
252
for (dig = 0; in >= lim; dig++)
253
in -= lim;
254
buffer[digits++] = '0' + dig;
255
}
256
} while (pos--);
257
258
buffer[digits] = 0;
259
return digits;
260
}
261
262
/* Converts the signed long 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 -9223372036854775808 in 64-bit, 12 for
265
* -2147483648 in 32-bit). The buffer is filled from the first byte, and the
266
* number of characters emitted (not counting the trailing zero) is returned.
267
*/
268
static __attribute__((unused))
269
int itoa_r(long in, char *buffer)
270
{
271
char *ptr = buffer;
272
int len = 0;
273
274
if (in < 0) {
275
in = -(unsigned long)in;
276
*(ptr++) = '-';
277
len++;
278
}
279
len += utoa_r(in, ptr);
280
return len;
281
}
282
283
/* for historical compatibility, same as above but returns the pointer to the
284
* buffer.
285
*/
286
static __inline__ __attribute__((unused))
287
char *ltoa_r(long in, char *buffer)
288
{
289
itoa_r(in, buffer);
290
return buffer;
291
}
292
293
/* converts long integer <in> to a string using the static itoa_buffer and
294
* returns the pointer to that string.
295
*/
296
static __inline__ __attribute__((unused))
297
char *itoa(long in)
298
{
299
itoa_r(in, itoa_buffer);
300
return itoa_buffer;
301
}
302
303
/* converts long integer <in> to a string using the static itoa_buffer and
304
* returns the pointer to that string. Same as above, for compatibility.
305
*/
306
static __inline__ __attribute__((unused))
307
char *ltoa(long in)
308
{
309
itoa_r(in, itoa_buffer);
310
return itoa_buffer;
311
}
312
313
/* converts unsigned long integer <in> to a string using the static itoa_buffer
314
* and returns the pointer to that string.
315
*/
316
static __inline__ __attribute__((unused))
317
char *utoa(unsigned long in)
318
{
319
utoa_r(in, itoa_buffer);
320
return itoa_buffer;
321
}
322
323
/* Converts the unsigned 64-bit integer <in> to its hex representation into
324
* buffer <buffer>, which must be long enough to store the number and the
325
* trailing zero (17 bytes for "ffffffffffffffff"). The buffer is filled from
326
* the first byte, and the number of characters emitted (not counting the
327
* trailing zero) is returned. The function is constructed in a way to optimize
328
* the code size and avoid any divide that could add a dependency on large
329
* external functions.
330
*/
331
static __attribute__((unused))
332
int u64toh_r(uint64_t in, char *buffer)
333
{
334
signed char pos = 60;
335
int digits = 0;
336
int dig;
337
338
do {
339
if (sizeof(long) >= 8) {
340
dig = (in >> pos) & 0xF;
341
} else {
342
/* 32-bit platforms: avoid a 64-bit shift */
343
uint32_t d = (pos >= 32) ? (in >> 32) : in;
344
dig = (d >> (pos & 31)) & 0xF;
345
}
346
if (dig > 9)
347
dig += 'a' - '0' - 10;
348
pos -= 4;
349
if (dig || digits || pos < 0)
350
buffer[digits++] = '0' + dig;
351
} while (pos >= 0);
352
353
buffer[digits] = 0;
354
return digits;
355
}
356
357
/* converts uint64_t <in> to an hex string using the static itoa_buffer and
358
* returns the pointer to that string.
359
*/
360
static __inline__ __attribute__((unused))
361
char *u64toh(uint64_t in)
362
{
363
u64toh_r(in, itoa_buffer);
364
return itoa_buffer;
365
}
366
367
/* Converts the unsigned 64-bit integer <in> to its string representation into
368
* buffer <buffer>, which must be long enough to store the number and the
369
* trailing zero (21 bytes for 18446744073709551615). The buffer is filled from
370
* the first byte, and the number of characters emitted (not counting the
371
* trailing zero) is returned. The function is constructed in a way to optimize
372
* the code size and avoid any divide that could add a dependency on large
373
* external functions.
374
*/
375
static __attribute__((unused))
376
int u64toa_r(uint64_t in, char *buffer)
377
{
378
unsigned long long lim;
379
int digits = 0;
380
int pos = 19; /* start with the highest possible digit */
381
int dig;
382
383
do {
384
for (dig = 0, lim = 1; dig < pos; dig++)
385
lim *= 10;
386
387
if (digits || in >= lim || !pos) {
388
for (dig = 0; in >= lim; dig++)
389
in -= lim;
390
buffer[digits++] = '0' + dig;
391
}
392
} while (pos--);
393
394
buffer[digits] = 0;
395
return digits;
396
}
397
398
/* Converts the signed 64-bit integer <in> to its string representation into
399
* buffer <buffer>, which must be long enough to store the number and the
400
* trailing zero (21 bytes for -9223372036854775808). The buffer is filled from
401
* the first byte, and the number of characters emitted (not counting the
402
* trailing zero) is returned.
403
*/
404
static __attribute__((unused))
405
int i64toa_r(int64_t in, char *buffer)
406
{
407
char *ptr = buffer;
408
int len = 0;
409
410
if (in < 0) {
411
in = -(uint64_t)in;
412
*(ptr++) = '-';
413
len++;
414
}
415
len += u64toa_r(in, ptr);
416
return len;
417
}
418
419
/* converts int64_t <in> to a string using the static itoa_buffer and returns
420
* the pointer to that string.
421
*/
422
static __inline__ __attribute__((unused))
423
char *i64toa(int64_t in)
424
{
425
i64toa_r(in, itoa_buffer);
426
return itoa_buffer;
427
}
428
429
/* converts uint64_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 *u64toa(uint64_t in)
434
{
435
u64toa_r(in, itoa_buffer);
436
return itoa_buffer;
437
}
438
439
static __attribute__((unused))
440
uintmax_t __strtox(const char *nptr, char **endptr, int base, intmax_t lower_limit, uintmax_t upper_limit)
441
{
442
const char signed_ = lower_limit != 0;
443
unsigned char neg = 0, overflow = 0;
444
uintmax_t val = 0, limit, old_val;
445
char c;
446
447
if (base < 0 || base > 36) {
448
SET_ERRNO(EINVAL);
449
goto out;
450
}
451
452
while (isspace(*nptr))
453
nptr++;
454
455
if (*nptr == '+') {
456
nptr++;
457
} else if (*nptr == '-') {
458
neg = 1;
459
nptr++;
460
}
461
462
if (signed_ && neg)
463
limit = -(uintmax_t)lower_limit;
464
else
465
limit = upper_limit;
466
467
if ((base == 0 || base == 16) &&
468
(strncmp(nptr, "0x", 2) == 0 || strncmp(nptr, "0X", 2) == 0)) {
469
base = 16;
470
nptr += 2;
471
} else if (base == 0 && strncmp(nptr, "0", 1) == 0) {
472
base = 8;
473
nptr += 1;
474
} else if (base == 0) {
475
base = 10;
476
}
477
478
while (*nptr) {
479
c = *nptr;
480
481
if (c >= '0' && c <= '9')
482
c -= '0';
483
else if (c >= 'a' && c <= 'z')
484
c = c - 'a' + 10;
485
else if (c >= 'A' && c <= 'Z')
486
c = c - 'A' + 10;
487
else
488
goto out;
489
490
if (c >= base)
491
goto out;
492
493
nptr++;
494
old_val = val;
495
val *= base;
496
val += c;
497
498
if (val > limit || val < old_val)
499
overflow = 1;
500
}
501
502
out:
503
if (overflow) {
504
SET_ERRNO(ERANGE);
505
val = limit;
506
}
507
if (endptr)
508
*endptr = (char *)nptr;
509
return neg ? -val : val;
510
}
511
512
static __attribute__((unused))
513
long strtol(const char *nptr, char **endptr, int base)
514
{
515
return __strtox(nptr, endptr, base, LONG_MIN, LONG_MAX);
516
}
517
518
static __attribute__((unused))
519
unsigned long strtoul(const char *nptr, char **endptr, int base)
520
{
521
return __strtox(nptr, endptr, base, 0, ULONG_MAX);
522
}
523
524
static __attribute__((unused))
525
long long strtoll(const char *nptr, char **endptr, int base)
526
{
527
return __strtox(nptr, endptr, base, LLONG_MIN, LLONG_MAX);
528
}
529
530
static __attribute__((unused))
531
unsigned long long strtoull(const char *nptr, char **endptr, int base)
532
{
533
return __strtox(nptr, endptr, base, 0, ULLONG_MAX);
534
}
535
536
static __attribute__((unused))
537
intmax_t strtoimax(const char *nptr, char **endptr, int base)
538
{
539
return __strtox(nptr, endptr, base, INTMAX_MIN, INTMAX_MAX);
540
}
541
542
static __attribute__((unused))
543
uintmax_t strtoumax(const char *nptr, char **endptr, int base)
544
{
545
return __strtox(nptr, endptr, base, 0, UINTMAX_MAX);
546
}
547
548
#endif /* _NOLIBC_STDLIB_H */
549
550