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

string.h (4964B)


      1/* SPDX-License-Identifier: LGPL-2.1 OR MIT */
      2/*
      3 * string function definitions for NOLIBC
      4 * Copyright (C) 2017-2021 Willy Tarreau <w@1wt.eu>
      5 */
      6
      7#ifndef _NOLIBC_STRING_H
      8#define _NOLIBC_STRING_H
      9
     10#include "std.h"
     11
     12static void *malloc(size_t len);
     13
     14/*
     15 * As much as possible, please keep functions alphabetically sorted.
     16 */
     17
     18static __attribute__((unused))
     19int memcmp(const void *s1, const void *s2, size_t n)
     20{
     21	size_t ofs = 0;
     22	char c1 = 0;
     23
     24	while (ofs < n && !(c1 = ((char *)s1)[ofs] - ((char *)s2)[ofs])) {
     25		ofs++;
     26	}
     27	return c1;
     28}
     29
     30static __attribute__((unused))
     31void *_nolibc_memcpy_up(void *dst, const void *src, size_t len)
     32{
     33	size_t pos = 0;
     34
     35	while (pos < len) {
     36		((char *)dst)[pos] = ((const char *)src)[pos];
     37		pos++;
     38	}
     39	return dst;
     40}
     41
     42static __attribute__((unused))
     43void *_nolibc_memcpy_down(void *dst, const void *src, size_t len)
     44{
     45	while (len) {
     46		len--;
     47		((char *)dst)[len] = ((const char *)src)[len];
     48	}
     49	return dst;
     50}
     51
     52/* might be ignored by the compiler without -ffreestanding, then found as
     53 * missing.
     54 */
     55__attribute__((weak,unused,section(".text.nolibc_memmove")))
     56void *memmove(void *dst, const void *src, size_t len)
     57{
     58	size_t dir, pos;
     59
     60	pos = len;
     61	dir = -1;
     62
     63	if (dst < src) {
     64		pos = -1;
     65		dir = 1;
     66	}
     67
     68	while (len) {
     69		pos += dir;
     70		((char *)dst)[pos] = ((const char *)src)[pos];
     71		len--;
     72	}
     73	return dst;
     74}
     75
     76/* must be exported, as it's used by libgcc on ARM */
     77__attribute__((weak,unused,section(".text.nolibc_memcpy")))
     78void *memcpy(void *dst, const void *src, size_t len)
     79{
     80	return _nolibc_memcpy_up(dst, src, len);
     81}
     82
     83/* might be ignored by the compiler without -ffreestanding, then found as
     84 * missing.
     85 */
     86__attribute__((weak,unused,section(".text.nolibc_memset")))
     87void *memset(void *dst, int b, size_t len)
     88{
     89	char *p = dst;
     90
     91	while (len--)
     92		*(p++) = b;
     93	return dst;
     94}
     95
     96static __attribute__((unused))
     97char *strchr(const char *s, int c)
     98{
     99	while (*s) {
    100		if (*s == (char)c)
    101			return (char *)s;
    102		s++;
    103	}
    104	return NULL;
    105}
    106
    107static __attribute__((unused))
    108int strcmp(const char *a, const char *b)
    109{
    110	unsigned int c;
    111	int diff;
    112
    113	while (!(diff = (unsigned char)*a++ - (c = (unsigned char)*b++)) && c)
    114		;
    115	return diff;
    116}
    117
    118static __attribute__((unused))
    119char *strcpy(char *dst, const char *src)
    120{
    121	char *ret = dst;
    122
    123	while ((*dst++ = *src++));
    124	return ret;
    125}
    126
    127/* this function is only used with arguments that are not constants or when
    128 * it's not known because optimizations are disabled.
    129 */
    130static __attribute__((unused))
    131size_t nolibc_strlen(const char *str)
    132{
    133	size_t len;
    134
    135	for (len = 0; str[len]; len++);
    136	return len;
    137}
    138
    139/* do not trust __builtin_constant_p() at -O0, as clang will emit a test and
    140 * the two branches, then will rely on an external definition of strlen().
    141 */
    142#if defined(__OPTIMIZE__)
    143#define strlen(str) ({                          \
    144	__builtin_constant_p((str)) ?           \
    145		__builtin_strlen((str)) :       \
    146		nolibc_strlen((str));           \
    147})
    148#else
    149#define strlen(str) nolibc_strlen((str))
    150#endif
    151
    152static __attribute__((unused))
    153size_t strnlen(const char *str, size_t maxlen)
    154{
    155	size_t len;
    156
    157	for (len = 0; (len < maxlen) && str[len]; len++);
    158	return len;
    159}
    160
    161static __attribute__((unused))
    162char *strdup(const char *str)
    163{
    164	size_t len;
    165	char *ret;
    166
    167	len = strlen(str);
    168	ret = malloc(len + 1);
    169	if (__builtin_expect(ret != NULL, 1))
    170		memcpy(ret, str, len + 1);
    171
    172	return ret;
    173}
    174
    175static __attribute__((unused))
    176char *strndup(const char *str, size_t maxlen)
    177{
    178	size_t len;
    179	char *ret;
    180
    181	len = strnlen(str, maxlen);
    182	ret = malloc(len + 1);
    183	if (__builtin_expect(ret != NULL, 1)) {
    184		memcpy(ret, str, len);
    185		ret[len] = '\0';
    186	}
    187
    188	return ret;
    189}
    190
    191static __attribute__((unused))
    192size_t strlcat(char *dst, const char *src, size_t size)
    193{
    194	size_t len;
    195	char c;
    196
    197	for (len = 0; dst[len];	len++)
    198		;
    199
    200	for (;;) {
    201		c = *src;
    202		if (len < size)
    203			dst[len] = c;
    204		if (!c)
    205			break;
    206		len++;
    207		src++;
    208	}
    209
    210	return len;
    211}
    212
    213static __attribute__((unused))
    214size_t strlcpy(char *dst, const char *src, size_t size)
    215{
    216	size_t len;
    217	char c;
    218
    219	for (len = 0;;) {
    220		c = src[len];
    221		if (len < size)
    222			dst[len] = c;
    223		if (!c)
    224			break;
    225		len++;
    226	}
    227	return len;
    228}
    229
    230static __attribute__((unused))
    231char *strncat(char *dst, const char *src, size_t size)
    232{
    233	char *orig = dst;
    234
    235	while (*dst)
    236		dst++;
    237
    238	while (size && (*dst = *src)) {
    239		src++;
    240		dst++;
    241		size--;
    242	}
    243
    244	*dst = 0;
    245	return orig;
    246}
    247
    248static __attribute__((unused))
    249int strncmp(const char *a, const char *b, size_t size)
    250{
    251	unsigned int c;
    252	int diff = 0;
    253
    254	while (size-- &&
    255	       !(diff = (unsigned char)*a++ - (c = (unsigned char)*b++)) && c)
    256		;
    257
    258	return diff;
    259}
    260
    261static __attribute__((unused))
    262char *strncpy(char *dst, const char *src, size_t size)
    263{
    264	size_t len;
    265
    266	for (len = 0; len < size; len++)
    267		if ((dst[len] = *src))
    268			src++;
    269	return dst;
    270}
    271
    272static __attribute__((unused))
    273char *strrchr(const char *s, int c)
    274{
    275	const char *ret = NULL;
    276
    277	while (*s) {
    278		if (*s == (char)c)
    279			ret = s;
    280		s++;
    281	}
    282	return (char *)ret;
    283}
    284
    285#endif /* _NOLIBC_STRING_H */