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