hv: lib: Add several missing standard string/memory APIs

Integrating libfdt requires the presence of these APIs.

Tracked-On: #8838
Signed-off-by: Yifan Liu <yifan1.liu@intel.com>
Acked-by: Wang Yu1 <yu1.wang@intel.com>
This commit is contained in:
Yifan Liu
2025-11-03 08:24:21 +00:00
committed by acrnsi-robot
parent ac7e07e01b
commit 390db422d8
5 changed files with 183 additions and 57 deletions

View File

@@ -32,6 +32,8 @@ void memcpy_backwards(void *d, const void *s, size_t slen);
#endif
int32_t memcpy_s(void *d, size_t dmax, const void *s, size_t slen);
int memcmp(const void *s1, const void *s2, size_t count);
void *memmove(void *d, const void *s, size_t slen);
void *memchr(const void *s, int c, size_t slen);
#endif /* MEMORY_LIB_H */

View File

@@ -38,11 +38,16 @@ static inline bool is_eol(char c)
int32_t strcmp(const char *s1_arg, const char *s2_arg);
int32_t strncmp(const char *s1_arg, const char *s2_arg, size_t n_arg);
int32_t strncpy_s(char *d, size_t dmax, const char *s, size_t slen);
char *strchr(char *s_arg, char ch);
char *strchr(const char *s_arg, char ch);
size_t strnlen_s(const char *str_arg, size_t maxlen_arg);
int64_t strtol_deci(const char *nptr);
uint64_t strtoul_hex(const char *nptr);
uint64_t strtoul(const char * nptr, char **endptr, int base);
char *strstr_s(const char *str1, size_t maxlen1, const char *str2, size_t maxlen2);
int32_t strncat_s(char *dest, size_t dmax, const char *src, size_t slen);
size_t strlen(const char *str);
size_t strnlen(const char *str, size_t count);
char *strrchr(const char *s, char ch);
char *strcpy(char *d, const char *s);
#endif /* RTL_H */

View File

@@ -24,6 +24,7 @@ typedef unsigned short uint16_t;
typedef signed int int32_t;
typedef unsigned int uint32_t;
typedef unsigned long uint64_t;
typedef unsigned long uintptr_t;
typedef signed long int64_t;
typedef unsigned int size_t;
typedef __builtin_va_list va_list;

View File

@@ -66,3 +66,61 @@ int32_t memcpy_s(void *d, size_t dmax, const void *s, size_t slen)
return ret;
}
int memcmp(const void *s1, const void *s2, size_t count)
{
const char *t1 = s1;
const char *t2 = s2;
int ret = 0;
for (; count > 0 && (*t1 == *t2); count--) {
t1++;
t2++;
}
if (count > 0) {
ret = *(unsigned char *)t1 - *(unsigned char *)t2;
}
return ret;
}
void *memmove(void *d, const void *s, size_t slen)
{
char *t1 = (char *)d;
const char *t2 = (char *)s;
if (d == s) {
/* do nothing */
} else if (d < s) {
while (slen > 0) {
*t1++ = *t2++;
slen--;
}
} else {
t1 = (char *)d + slen - 1;
t2 = (char *)s + slen - 1;
while (slen > 0) {
*t1-- = *t2--;
slen--;
}
}
return d;
}
void *memchr(const void *s, int c, size_t slen)
{
void *ret = NULL;
const unsigned char *t;
for (t = s; slen > 0; slen--) {
if ((unsigned char)c == *t++) {
ret = (void *)(t - 1);
break;
}
}
return ret;
}

View File

@@ -6,19 +6,81 @@
#include <rtl.h>
#include <logmsg.h>
static inline char hex_digit_value(char ch)
uint64_t strtoul(const char * nptr, char **endptr, int base)
{
char c;
if (('0' <= ch) && (ch <= '9')) {
c = ch - '0';
} else if (('a' <= ch) && (ch <= 'f')) {
c = ch - 'a' + 10;
} else if (('A' <= ch) && (ch <= 'F')) {
c = ch - 'A' + 10;
const char *s;
unsigned long acc, cutoff;
int c;
int neg, any, cutlim;
/*
* See strtol for comments as to the logic used.
*/
s = nptr;
do {
c = (unsigned char) *s++;
} while (is_space(c));
if (c == '-') {
neg = 1;
c = *s++;
} else {
c = -1;
neg = 0;
if (c == '+')
c = *s++;
}
return c;
if ((base == 0 || base == 16) &&
c == '0' && (*s == 'x' || *s == 'X')) {
c = s[1];
s += 2;
base = 16;
}
if (base == 0) {
base = c == '0' ? 8 : 10;
}
cutoff = ULONG_MAX / (unsigned long)base;
cutlim = ULONG_MAX % (unsigned long)base;
for (acc = 0, any = 0;; c = (unsigned char) *s++) {
if (c >= '0' && c <= '9') {
c -= '0';
} else if (c >= 'A' && c <= 'Z') {
c -= 'A' - 10;
} else if (c >= 'a' && c <= 'z') {
c -= 'a' - 10;
} else {
break;
}
if (c >= base) {
break;
}
if (any < 0) {
continue;
}
if (acc > cutoff || (acc == cutoff && c > cutlim)) {
any = -1;
acc = ULONG_MAX;
} else {
any = 1;
acc *= (unsigned long)base;
acc += c;
}
}
if (neg && any > 0) {
acc = -acc;
}
if (endptr != 0) {
*endptr = (char *) (any ? s - 1 : nptr);
}
return (acc);
}
/*
@@ -26,58 +88,56 @@ static inline char hex_digit_value(char ch)
*/
uint64_t strtoul_hex(const char *nptr)
{
const char *s = nptr;
char c, digit;
uint64_t acc, cutoff, cutlim;
uint64_t base = 16UL;
int32_t any;
/*
* See strtol for comments as to the logic used.
*/
do {
c = *s;
s++;
} while (is_space(c));
if ((c == '0') && ((*s == 'x') || (*s == 'X'))) {
c = s[1];
s += 2;
}
cutoff = ULONG_MAX / base;
cutlim = ULONG_MAX % base;
acc = 0UL;
any = 0;
digit = hex_digit_value(c);
while (digit >= 0) {
if ((acc > cutoff) || ((acc == cutoff) && ((uint64_t)digit > cutlim))) {
any = -1;
break;
} else {
acc *= base;
acc += (uint64_t)digit;
}
c = *s;
s++;
digit = hex_digit_value(c);
}
if (any < 0) {
acc = ULONG_MAX;
}
return acc;
return strtoul(nptr, NULL, 16);
}
char *strchr(char *s_arg, char ch)
char *strchr(const char *s_arg, char ch)
{
char *s = s_arg;
const char *s = s_arg;
while ((*s != '\0') && (*s != ch)) {
++s;
}
return ((*s) != '\0') ? s : NULL;
return ((*s) != '\0') ? (char *)s : NULL;
}
size_t strlen(const char *str)
{
unsigned long ret;
for (ret = 0; *str != '\0'; str++) {
ret++;
}
return ret;
}
size_t strnlen(const char *str, size_t count)
{
unsigned long ret;
for (ret = 0; (*str != '\0') && (ret < count); str++) {
ret++;
}
return ret;
}
char *strrchr(const char *s, char ch)
{
const char *last = s + strlen(s);
while (last > s && *last != ch) {
last--;
}
return (*last != ch) ? NULL : (char *)last;
}
char *strcpy(char *d, const char *s)
{
char *ret = d;
while ((*d++ = *s++) != '\0') { }
return ret;
}
/*