xref: /openbmc/linux/tools/include/nolibc/stdlib.h (revision ac90226d53051c1ae0f0e1b71596fb038ddb6cf6)
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 static __attribute__((unused))
27 long atol(const char *s)
28 {
29 	unsigned long ret = 0;
30 	unsigned long d;
31 	int neg = 0;
32 
33 	if (*s == '-') {
34 		neg = 1;
35 		s++;
36 	}
37 
38 	while (1) {
39 		d = (*s++) - '0';
40 		if (d > 9)
41 			break;
42 		ret *= 10;
43 		ret += d;
44 	}
45 
46 	return neg ? -ret : ret;
47 }
48 
49 static __attribute__((unused))
50 int atoi(const char *s)
51 {
52 	return atol(s);
53 }
54 
55 /* Converts the unsigned long integer <in> to its hex representation into
56  * buffer <buffer>, which must be long enough to store the number and the
57  * trailing zero (17 bytes for "ffffffffffffffff" or 9 for "ffffffff"). The
58  * buffer is filled from the first byte, and the number of characters emitted
59  * (not counting the trailing zero) is returned. The function is constructed
60  * in a way to optimize the code size and avoid any divide that could add a
61  * dependency on large external functions.
62  */
63 static __attribute__((unused))
64 int utoh_r(unsigned long in, char *buffer)
65 {
66 	signed char pos = (~0UL > 0xfffffffful) ? 60 : 28;
67 	int digits = 0;
68 	int dig;
69 
70 	do {
71 		dig = in >> pos;
72 		in -= (uint64_t)dig << pos;
73 		pos -= 4;
74 		if (dig || digits || pos < 0) {
75 			if (dig > 9)
76 				dig += 'a' - '0' - 10;
77 			buffer[digits++] = '0' + dig;
78 		}
79 	} while (pos >= 0);
80 
81 	buffer[digits] = 0;
82 	return digits;
83 }
84 
85 /* converts unsigned long <in> to an hex string using the static itoa_buffer
86  * and returns the pointer to that string.
87  */
88 static inline __attribute__((unused))
89 char *utoh(unsigned long in)
90 {
91 	utoh_r(in, itoa_buffer);
92 	return itoa_buffer;
93 }
94 
95 /* Converts the unsigned long integer <in> to its string representation into
96  * buffer <buffer>, which must be long enough to store the number and the
97  * trailing zero (21 bytes for 18446744073709551615 in 64-bit, 11 for
98  * 4294967295 in 32-bit). The buffer is filled from the first byte, and the
99  * number of characters emitted (not counting the trailing zero) is returned.
100  * The function is constructed in a way to optimize the code size and avoid
101  * any divide that could add a dependency on large external functions.
102  */
103 static __attribute__((unused))
104 int utoa_r(unsigned long in, char *buffer)
105 {
106 	unsigned long lim;
107 	int digits = 0;
108 	int pos = (~0UL > 0xfffffffful) ? 19 : 9;
109 	int dig;
110 
111 	do {
112 		for (dig = 0, lim = 1; dig < pos; dig++)
113 			lim *= 10;
114 
115 		if (digits || in >= lim || !pos) {
116 			for (dig = 0; in >= lim; dig++)
117 				in -= lim;
118 			buffer[digits++] = '0' + dig;
119 		}
120 	} while (pos--);
121 
122 	buffer[digits] = 0;
123 	return digits;
124 }
125 
126 /* Converts the signed 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 -9223372036854775808 in 64-bit, 12 for
129  * -2147483648 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  */
132 static __attribute__((unused))
133 int itoa_r(long in, char *buffer)
134 {
135 	char *ptr = buffer;
136 	int len = 0;
137 
138 	if (in < 0) {
139 		in = -in;
140 		*(ptr++) = '-';
141 		len++;
142 	}
143 	len += utoa_r(in, ptr);
144 	return len;
145 }
146 
147 /* for historical compatibility, same as above but returns the pointer to the
148  * buffer.
149  */
150 static inline __attribute__((unused))
151 char *ltoa_r(long in, char *buffer)
152 {
153 	itoa_r(in, buffer);
154 	return buffer;
155 }
156 
157 /* converts long integer <in> to a string using the static itoa_buffer and
158  * returns the pointer to that string.
159  */
160 static inline __attribute__((unused))
161 char *itoa(long in)
162 {
163 	itoa_r(in, itoa_buffer);
164 	return itoa_buffer;
165 }
166 
167 /* converts long integer <in> to a string using the static itoa_buffer and
168  * returns the pointer to that string. Same as above, for compatibility.
169  */
170 static inline __attribute__((unused))
171 char *ltoa(long in)
172 {
173 	itoa_r(in, itoa_buffer);
174 	return itoa_buffer;
175 }
176 
177 /* converts unsigned long integer <in> to a string using the static itoa_buffer
178  * and returns the pointer to that string.
179  */
180 static inline __attribute__((unused))
181 char *utoa(unsigned long in)
182 {
183 	utoa_r(in, itoa_buffer);
184 	return itoa_buffer;
185 }
186 
187 /* Converts the unsigned 64-bit integer <in> to its hex representation into
188  * buffer <buffer>, which must be long enough to store the number and the
189  * trailing zero (17 bytes for "ffffffffffffffff"). The buffer is filled from
190  * the first byte, and the number of characters emitted (not counting the
191  * trailing zero) is returned. The function is constructed in a way to optimize
192  * the code size and avoid any divide that could add a dependency on large
193  * external functions.
194  */
195 static __attribute__((unused))
196 int u64toh_r(uint64_t in, char *buffer)
197 {
198 	signed char pos = 60;
199 	int digits = 0;
200 	int dig;
201 
202 	do {
203 		if (sizeof(long) >= 8) {
204 			dig = (in >> pos) & 0xF;
205 		} else {
206 			/* 32-bit platforms: avoid a 64-bit shift */
207 			uint32_t d = (pos >= 32) ? (in >> 32) : in;
208 			dig = (d >> (pos & 31)) & 0xF;
209 		}
210 		if (dig > 9)
211 			dig += 'a' - '0' - 10;
212 		pos -= 4;
213 		if (dig || digits || pos < 0)
214 			buffer[digits++] = '0' + dig;
215 	} while (pos >= 0);
216 
217 	buffer[digits] = 0;
218 	return digits;
219 }
220 
221 /* converts uint64_t <in> to an hex string using the static itoa_buffer and
222  * returns the pointer to that string.
223  */
224 static inline __attribute__((unused))
225 char *u64toh(uint64_t in)
226 {
227 	u64toh_r(in, itoa_buffer);
228 	return itoa_buffer;
229 }
230 
231 /* Converts the unsigned 64-bit 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). The buffer is filled from
234  * the first byte, and the number of characters emitted (not counting the
235  * trailing zero) is returned. The function is constructed in a way to optimize
236  * the code size and avoid any divide that could add a dependency on large
237  * external functions.
238  */
239 static __attribute__((unused))
240 int u64toa_r(uint64_t in, char *buffer)
241 {
242 	unsigned long long lim;
243 	int digits = 0;
244 	int pos = 19; /* start with the highest possible digit */
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 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 -9223372036854775808). The buffer is filled from
265  * the first byte, and the number of characters emitted (not counting the
266  * trailing zero) is returned.
267  */
268 static __attribute__((unused))
269 int i64toa_r(int64_t in, char *buffer)
270 {
271 	char *ptr = buffer;
272 	int len = 0;
273 
274 	if (in < 0) {
275 		in = -in;
276 		*(ptr++) = '-';
277 		len++;
278 	}
279 	len += u64toa_r(in, ptr);
280 	return len;
281 }
282 
283 /* converts int64_t <in> to a string using the static itoa_buffer and returns
284  * the pointer to that string.
285  */
286 static inline __attribute__((unused))
287 char *i64toa(int64_t in)
288 {
289 	i64toa_r(in, itoa_buffer);
290 	return itoa_buffer;
291 }
292 
293 /* converts uint64_t <in> to a string using the static itoa_buffer and returns
294  * the pointer to that string.
295  */
296 static inline __attribute__((unused))
297 char *u64toa(uint64_t in)
298 {
299 	u64toa_r(in, itoa_buffer);
300 	return itoa_buffer;
301 }
302 
303 static __attribute__((unused))
304 int msleep(unsigned int msecs)
305 {
306 	struct timeval my_timeval = { msecs / 1000, (msecs % 1000) * 1000 };
307 
308 	if (sys_select(0, 0, 0, 0, &my_timeval) < 0)
309 		return (my_timeval.tv_sec * 1000) +
310 			(my_timeval.tv_usec / 1000) +
311 			!!(my_timeval.tv_usec % 1000);
312 	else
313 		return 0;
314 }
315 
316 /* This one is not marked static as it's needed by libgcc for divide by zero */
317 __attribute__((weak,unused))
318 int raise(int signal)
319 {
320 	return kill(getpid(), signal);
321 }
322 
323 static __attribute__((unused))
324 unsigned int sleep(unsigned int seconds)
325 {
326 	struct timeval my_timeval = { seconds, 0 };
327 
328 	if (sys_select(0, 0, 0, 0, &my_timeval) < 0)
329 		return my_timeval.tv_sec + !!my_timeval.tv_usec;
330 	else
331 		return 0;
332 }
333 
334 static __attribute__((unused))
335 int tcsetpgrp(int fd, pid_t pid)
336 {
337 	return ioctl(fd, TIOCSPGRP, &pid);
338 }
339 
340 #endif /* _NOLIBC_STDLIB_H */
341