cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

stdlib.h (10609B)


      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#include "string.h"
     15
     16struct nolibc_heap {
     17	size_t	len;
     18	char	user_p[] __attribute__((__aligned__));
     19};
     20
     21/* Buffer used to store int-to-ASCII conversions. Will only be implemented if
     22 * any of the related functions is implemented. The area is large enough to
     23 * store "18446744073709551615" or "-9223372036854775808" and the final zero.
     24 */
     25static __attribute__((unused)) char itoa_buffer[21];
     26
     27/*
     28 * As much as possible, please keep functions alphabetically sorted.
     29 */
     30
     31/* must be exported, as it's used by libgcc for various divide functions */
     32__attribute__((weak,unused,noreturn,section(".text.nolibc_abort")))
     33void abort(void)
     34{
     35	sys_kill(sys_getpid(), SIGABRT);
     36	for (;;);
     37}
     38
     39static __attribute__((unused))
     40long atol(const char *s)
     41{
     42	unsigned long ret = 0;
     43	unsigned long d;
     44	int neg = 0;
     45
     46	if (*s == '-') {
     47		neg = 1;
     48		s++;
     49	}
     50
     51	while (1) {
     52		d = (*s++) - '0';
     53		if (d > 9)
     54			break;
     55		ret *= 10;
     56		ret += d;
     57	}
     58
     59	return neg ? -ret : ret;
     60}
     61
     62static __attribute__((unused))
     63int atoi(const char *s)
     64{
     65	return atol(s);
     66}
     67
     68static __attribute__((unused))
     69void free(void *ptr)
     70{
     71	struct nolibc_heap *heap;
     72
     73	if (!ptr)
     74		return;
     75
     76	heap = container_of(ptr, struct nolibc_heap, user_p);
     77	munmap(heap, heap->len);
     78}
     79
     80/* getenv() tries to find the environment variable named <name> in the
     81 * environment array pointed to by global variable "environ" which must be
     82 * declared as a char **, and must be terminated by a NULL (it is recommended
     83 * to set this variable to the "envp" argument of main()). If the requested
     84 * environment variable exists its value is returned otherwise NULL is
     85 * returned. getenv() is forcefully inlined so that the reference to "environ"
     86 * will be dropped if unused, even at -O0.
     87 */
     88static __attribute__((unused))
     89char *_getenv(const char *name, char **environ)
     90{
     91	int idx, i;
     92
     93	if (environ) {
     94		for (idx = 0; environ[idx]; idx++) {
     95			for (i = 0; name[i] && name[i] == environ[idx][i];)
     96				i++;
     97			if (!name[i] && environ[idx][i] == '=')
     98				return &environ[idx][i+1];
     99		}
    100	}
    101	return NULL;
    102}
    103
    104static inline __attribute__((unused,always_inline))
    105char *getenv(const char *name)
    106{
    107	extern char **environ;
    108	return _getenv(name, environ);
    109}
    110
    111static __attribute__((unused))
    112void *malloc(size_t len)
    113{
    114	struct nolibc_heap *heap;
    115
    116	/* Always allocate memory with size multiple of 4096. */
    117	len  = sizeof(*heap) + len;
    118	len  = (len + 4095UL) & -4096UL;
    119	heap = mmap(NULL, len, PROT_READ|PROT_WRITE, MAP_ANONYMOUS|MAP_PRIVATE,
    120		    -1, 0);
    121	if (__builtin_expect(heap == MAP_FAILED, 0))
    122		return NULL;
    123
    124	heap->len = len;
    125	return heap->user_p;
    126}
    127
    128static __attribute__((unused))
    129void *calloc(size_t size, size_t nmemb)
    130{
    131	void *orig;
    132	size_t res = 0;
    133
    134	if (__builtin_expect(__builtin_mul_overflow(nmemb, size, &res), 0)) {
    135		SET_ERRNO(ENOMEM);
    136		return NULL;
    137	}
    138
    139	/*
    140	 * No need to zero the heap, the MAP_ANONYMOUS in malloc()
    141	 * already does it.
    142	 */
    143	return malloc(res);
    144}
    145
    146static __attribute__((unused))
    147void *realloc(void *old_ptr, size_t new_size)
    148{
    149	struct nolibc_heap *heap;
    150	size_t user_p_len;
    151	void *ret;
    152
    153	if (!old_ptr)
    154		return malloc(new_size);
    155
    156	heap = container_of(old_ptr, struct nolibc_heap, user_p);
    157	user_p_len = heap->len - sizeof(*heap);
    158	/*
    159	 * Don't realloc() if @user_p_len >= @new_size, this block of
    160	 * memory is still enough to handle the @new_size. Just return
    161	 * the same pointer.
    162	 */
    163	if (user_p_len >= new_size)
    164		return old_ptr;
    165
    166	ret = malloc(new_size);
    167	if (__builtin_expect(!ret, 0))
    168		return NULL;
    169
    170	memcpy(ret, heap->user_p, heap->len);
    171	munmap(heap, heap->len);
    172	return ret;
    173}
    174
    175/* Converts the unsigned long integer <in> to its hex representation into
    176 * buffer <buffer>, which must be long enough to store the number and the
    177 * trailing zero (17 bytes for "ffffffffffffffff" or 9 for "ffffffff"). The
    178 * buffer is filled from the first byte, and the number of characters emitted
    179 * (not counting the trailing zero) is returned. The function is constructed
    180 * in a way to optimize the code size and avoid any divide that could add a
    181 * dependency on large external functions.
    182 */
    183static __attribute__((unused))
    184int utoh_r(unsigned long in, char *buffer)
    185{
    186	signed char pos = (~0UL > 0xfffffffful) ? 60 : 28;
    187	int digits = 0;
    188	int dig;
    189
    190	do {
    191		dig = in >> pos;
    192		in -= (uint64_t)dig << pos;
    193		pos -= 4;
    194		if (dig || digits || pos < 0) {
    195			if (dig > 9)
    196				dig += 'a' - '0' - 10;
    197			buffer[digits++] = '0' + dig;
    198		}
    199	} while (pos >= 0);
    200
    201	buffer[digits] = 0;
    202	return digits;
    203}
    204
    205/* converts unsigned long <in> to an hex string using the static itoa_buffer
    206 * and returns the pointer to that string.
    207 */
    208static inline __attribute__((unused))
    209char *utoh(unsigned long in)
    210{
    211	utoh_r(in, itoa_buffer);
    212	return itoa_buffer;
    213}
    214
    215/* Converts the unsigned long integer <in> to its string representation into
    216 * buffer <buffer>, which must be long enough to store the number and the
    217 * trailing zero (21 bytes for 18446744073709551615 in 64-bit, 11 for
    218 * 4294967295 in 32-bit). The buffer is filled from the first byte, and the
    219 * number of characters emitted (not counting the trailing zero) is returned.
    220 * The function is constructed in a way to optimize the code size and avoid
    221 * any divide that could add a dependency on large external functions.
    222 */
    223static __attribute__((unused))
    224int utoa_r(unsigned long in, char *buffer)
    225{
    226	unsigned long lim;
    227	int digits = 0;
    228	int pos = (~0UL > 0xfffffffful) ? 19 : 9;
    229	int dig;
    230
    231	do {
    232		for (dig = 0, lim = 1; dig < pos; dig++)
    233			lim *= 10;
    234
    235		if (digits || in >= lim || !pos) {
    236			for (dig = 0; in >= lim; dig++)
    237				in -= lim;
    238			buffer[digits++] = '0' + dig;
    239		}
    240	} while (pos--);
    241
    242	buffer[digits] = 0;
    243	return digits;
    244}
    245
    246/* Converts the signed long integer <in> to its string representation into
    247 * buffer <buffer>, which must be long enough to store the number and the
    248 * trailing zero (21 bytes for -9223372036854775808 in 64-bit, 12 for
    249 * -2147483648 in 32-bit). The buffer is filled from the first byte, and the
    250 * number of characters emitted (not counting the trailing zero) is returned.
    251 */
    252static __attribute__((unused))
    253int itoa_r(long in, char *buffer)
    254{
    255	char *ptr = buffer;
    256	int len = 0;
    257
    258	if (in < 0) {
    259		in = -in;
    260		*(ptr++) = '-';
    261		len++;
    262	}
    263	len += utoa_r(in, ptr);
    264	return len;
    265}
    266
    267/* for historical compatibility, same as above but returns the pointer to the
    268 * buffer.
    269 */
    270static inline __attribute__((unused))
    271char *ltoa_r(long in, char *buffer)
    272{
    273	itoa_r(in, buffer);
    274	return buffer;
    275}
    276
    277/* converts long integer <in> to a string using the static itoa_buffer and
    278 * returns the pointer to that string.
    279 */
    280static inline __attribute__((unused))
    281char *itoa(long in)
    282{
    283	itoa_r(in, itoa_buffer);
    284	return itoa_buffer;
    285}
    286
    287/* converts long integer <in> to a string using the static itoa_buffer and
    288 * returns the pointer to that string. Same as above, for compatibility.
    289 */
    290static inline __attribute__((unused))
    291char *ltoa(long in)
    292{
    293	itoa_r(in, itoa_buffer);
    294	return itoa_buffer;
    295}
    296
    297/* converts unsigned long integer <in> to a string using the static itoa_buffer
    298 * and returns the pointer to that string.
    299 */
    300static inline __attribute__((unused))
    301char *utoa(unsigned long in)
    302{
    303	utoa_r(in, itoa_buffer);
    304	return itoa_buffer;
    305}
    306
    307/* Converts the unsigned 64-bit integer <in> to its hex representation into
    308 * buffer <buffer>, which must be long enough to store the number and the
    309 * trailing zero (17 bytes for "ffffffffffffffff"). The buffer is filled from
    310 * the first byte, and the number of characters emitted (not counting the
    311 * trailing zero) is returned. The function is constructed in a way to optimize
    312 * the code size and avoid any divide that could add a dependency on large
    313 * external functions.
    314 */
    315static __attribute__((unused))
    316int u64toh_r(uint64_t in, char *buffer)
    317{
    318	signed char pos = 60;
    319	int digits = 0;
    320	int dig;
    321
    322	do {
    323		if (sizeof(long) >= 8) {
    324			dig = (in >> pos) & 0xF;
    325		} else {
    326			/* 32-bit platforms: avoid a 64-bit shift */
    327			uint32_t d = (pos >= 32) ? (in >> 32) : in;
    328			dig = (d >> (pos & 31)) & 0xF;
    329		}
    330		if (dig > 9)
    331			dig += 'a' - '0' - 10;
    332		pos -= 4;
    333		if (dig || digits || pos < 0)
    334			buffer[digits++] = '0' + dig;
    335	} while (pos >= 0);
    336
    337	buffer[digits] = 0;
    338	return digits;
    339}
    340
    341/* converts uint64_t <in> to an hex string using the static itoa_buffer and
    342 * returns the pointer to that string.
    343 */
    344static inline __attribute__((unused))
    345char *u64toh(uint64_t in)
    346{
    347	u64toh_r(in, itoa_buffer);
    348	return itoa_buffer;
    349}
    350
    351/* Converts the unsigned 64-bit integer <in> to its string representation into
    352 * buffer <buffer>, which must be long enough to store the number and the
    353 * trailing zero (21 bytes for 18446744073709551615). The buffer is filled from
    354 * the first byte, and the number of characters emitted (not counting the
    355 * trailing zero) is returned. The function is constructed in a way to optimize
    356 * the code size and avoid any divide that could add a dependency on large
    357 * external functions.
    358 */
    359static __attribute__((unused))
    360int u64toa_r(uint64_t in, char *buffer)
    361{
    362	unsigned long long lim;
    363	int digits = 0;
    364	int pos = 19; /* start with the highest possible digit */
    365	int dig;
    366
    367	do {
    368		for (dig = 0, lim = 1; dig < pos; dig++)
    369			lim *= 10;
    370
    371		if (digits || in >= lim || !pos) {
    372			for (dig = 0; in >= lim; dig++)
    373				in -= lim;
    374			buffer[digits++] = '0' + dig;
    375		}
    376	} while (pos--);
    377
    378	buffer[digits] = 0;
    379	return digits;
    380}
    381
    382/* Converts the signed 64-bit integer <in> to its string representation into
    383 * buffer <buffer>, which must be long enough to store the number and the
    384 * trailing zero (21 bytes for -9223372036854775808). The buffer is filled from
    385 * the first byte, and the number of characters emitted (not counting the
    386 * trailing zero) is returned.
    387 */
    388static __attribute__((unused))
    389int i64toa_r(int64_t in, char *buffer)
    390{
    391	char *ptr = buffer;
    392	int len = 0;
    393
    394	if (in < 0) {
    395		in = -in;
    396		*(ptr++) = '-';
    397		len++;
    398	}
    399	len += u64toa_r(in, ptr);
    400	return len;
    401}
    402
    403/* converts int64_t <in> to a string using the static itoa_buffer and returns
    404 * the pointer to that string.
    405 */
    406static inline __attribute__((unused))
    407char *i64toa(int64_t in)
    408{
    409	i64toa_r(in, itoa_buffer);
    410	return itoa_buffer;
    411}
    412
    413/* converts uint64_t <in> to a string using the static itoa_buffer and returns
    414 * the pointer to that string.
    415 */
    416static inline __attribute__((unused))
    417char *u64toa(uint64_t in)
    418{
    419	u64toa_r(in, itoa_buffer);
    420	return itoa_buffer;
    421}
    422
    423#endif /* _NOLIBC_STDLIB_H */