xref: /openbmc/linux/tools/include/nolibc/stdlib.h (revision 077d0a392446981cde2e8dd23090140bdd9fb728)
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