diff --git mlibc-clean/options/ansi/generic/stdio.cpp mlibc-workdir/options/ansi/generic/stdio.cpp index 070168f..7f20cb2 100644 --- mlibc-clean/options/ansi/generic/stdio.cpp +++ mlibc-workdir/options/ansi/generic/stdio.cpp @@ -8,6 +8,7 @@ #include #include #include +#include #include @@ -379,6 +380,20 @@ static void store_int(void *dest, unsigned int size, unsigned long long i) { } } +static void store_float(void *dest, unsigned int size, long double f) { + switch(size) { + case SCANF_TYPE_LL: + *(long double *)dest = f; + break; + case SCANF_TYPE_L: + *(double *)dest = f; + break; + default: + *(float *)dest = f; + break; + } +} + template static int do_scanf(H &handler, const char *fmt, __builtin_va_list args) { #define NOMATCH_CHECK(cond) ({ if(cond) return match_count; }) // if cond is true, matching error @@ -521,6 +536,141 @@ static int do_scanf(H &handler, const char *fmt, __builtin_va_list args) { } switch (*fmt) { + case 'a': + case 'A': + case 'E': + case 'e': + case 'G': + case 'g': + case 'F': + case 'f': { + bool is_negative = false; + long double divisor = 10; + long double result = 0; + int count = 0; + bool dot = false; + char c = handler.look_ahead(); + EOF_CHECK(c == '\0'); + + if((c == '-')) { + handler.consume(); + is_negative = true; + c = handler.look_ahead(); + } + + if((c == '+')) { + handler.consume(); + c = handler.look_ahead(); + } + + // nan? + if(tolower(c) == 'n') { + handler.consume(); + c = handler.look_ahead(); + if(tolower(c) != 'a') + return match_count; + + handler.consume(); + c = handler.look_ahead(); + if(tolower(c) != 'n') + return match_count; + + handler.consume(); + if(dest) + store_float(dest, type, NAN); + + continue; + } + + // inf? + if(tolower(c) == 'i') { + handler.consume(); + c = handler.look_ahead(); + size_t i; + for(i = 0; i < strlen("nfinity"); ++i) { + if (tolower(c) != "nfinity"[i]) + break; + handler.consume(); + c = handler.look_ahead(); + } + + NOMATCH_CHECK(i != 2 && i != 8); + + if(dest) + store_float(dest, type, is_negative ? -INFINITY : INFINITY); + + continue; + } + + // check if hexadecimal + if (c == '0') { + handler.consume(); + c = handler.look_ahead(); + if (tolower(c) == 'x') { + mlibc::infoLogger() << "mlibc: no support for hexadecimal floats on scanf" << frg::endlog; + return match_count; + } + + ++count; + } + + while(isdigit(c) || (dot == false && c == '.')) { + handler.consume(); + if(c == '.') { + dot = true; + c = handler.look_ahead(); + continue; + } + + long double character_value = c - '0'; + + if(dot) { + result = result + character_value / divisor; + divisor *= 10; + } else { + result = result * 10 + character_value; + } + + ++count; + c = handler.look_ahead(); + } + + NOMATCH_CHECK(count == 0); + + result = is_negative ? -result : result; + + // check for scientific notation + if (tolower(c) == 'e') { + handler.consume(); + c = handler.look_ahead(); + bool negative_exponent = false; + if(c == '+') { + handler.consume(); + c = handler.look_ahead(); + } + + if(c == '-') { + negative_exponent = true; + handler.consume(); + c = handler.look_ahead(); + } + + int exponent = 0; + + while(isdigit(c)) { + handler.consume(); + int value = c - '0'; + exponent = exponent * 10 + value; + c = handler.look_ahead(); + } + + result = result * powl(10, negative_exponent ? -exponent : exponent); + } + + if (dest) + store_float(dest, type, result); + break; + } case 'd': case 'u': base = 10; @@ -787,21 +937,24 @@ static int do_scanf(H &handler, const char *fmt, __builtin_va_list args) { } for (; *fmt != ']'; fmt++) { + auto fmt_unsigned = reinterpret_cast(fmt); + if (!*fmt) return EOF; if (*fmt == '-' && *fmt != ']') { fmt++; - for (char c = *(fmt - 2); c < *fmt; c++) + fmt_unsigned++; + for (unsigned char c = *(fmt_unsigned - 2); c < *fmt_unsigned; c++) scanset[1 + c] = 1 - invert; } - scanset[1 + *fmt] = 1 - invert; + scanset[1 + *fmt_unsigned] = 1 - invert; } char c = handler.look_ahead(); EOF_CHECK(c == '\0'); while (c && (!width || count < width)) { - handler.consume(); if (!scanset[1 + c]) break; + handler.consume(); if(type == SCANF_TYPE_L) append_to_wbuffer(c); diff --git mlibc-clean/options/glibc/generic/execinfo.cpp mlibc-workdir/options/glibc/generic/execinfo.cpp index 119574e..f9f1cde 100644 --- mlibc-clean/options/glibc/generic/execinfo.cpp +++ mlibc-workdir/options/glibc/generic/execinfo.cpp @@ -7,6 +7,7 @@ #include #include +#include namespace { @@ -52,33 +53,15 @@ _Unwind_Reason_Code trace(_Unwind_Context *context, void *arg) { } // namespace int backtrace(void **buffer, int size) { - if (size <= 0) - return 0; - - if (!libgccHandle) { - libgccHandle = dlopen("libgcc_s.so.1", RTLD_LAZY | RTLD_LOCAL); - if (!libgccHandle || libgccHandle.value() == nullptr) { - mlibc::infoLogger() << "Failed to load libgcc_s.so.1: " << (dlerror() ? dlerror() : "") << frg::endlog; - return 0; - } - - unwindBacktrace = reinterpret_cast(dlsym(libgccHandle.value(), "_Unwind_Backtrace")); - unwindGetIP = reinterpret_cast(dlsym(libgccHandle.value(), "_Unwind_GetIP")); - - if (!unwindBacktrace || !unwindGetIP) { - mlibc::infoLogger() << "Failed to find unwind functions in libgcc_s.so.1: " << dlerror() << frg::endlog; - return 0; - } - } - - UnwindState state{buffer, size}; - unwindBacktrace(trace, &state); - return state.current_frame; + mlibc::infoLogger() << "mlibc: backtrace() is a stub!" << frg::endlog; + errno = ENOSYS; + return -1; } char **backtrace_symbols(void *const *, int) { - __ensure(!"Not implemented"); - __builtin_unreachable(); + mlibc::infoLogger() << "mlibc: backtrace() is a stub!" << frg::endlog; + errno = ENOSYS; + return NULL; } void backtrace_symbols_fd(void *const *buffer, int size, int fd) { diff --git mlibc-clean/options/internal/include/bits/null.h mlibc-workdir/options/internal/include/bits/null.h index 176008f..4fddf21 100644 --- mlibc-clean/options/internal/include/bits/null.h +++ mlibc-workdir/options/internal/include/bits/null.h @@ -9,7 +9,7 @@ #ifndef __cplusplus # define NULL ((void *)0) #else -# define NULL 0 +# define NULL 0L #endif #endif /* MLIBC_NULL_H */ diff --git mlibc-clean/options/rtld/generic/main.cpp mlibc-workdir/options/rtld/generic/main.cpp index b2db152..e6438fe 100644 --- mlibc-clean/options/rtld/generic/main.cpp +++ mlibc-workdir/options/rtld/generic/main.cpp @@ -681,6 +681,9 @@ void *__dlapi_open(const char *file, int flags, void *returnAddress) { } } + if (isGlobal) + object->localScope = globalScope.get(); + Loader linker{object->localScope, nullptr, false, rts}; linker.linkObjects(object); linker.initObjects(initialRepository.get()); diff --git mlibc-clean/sysdeps/astral/generic/generic.cpp mlibc-workdir/sysdeps/astral/generic/generic.cpp index be7ad9e..80cc8d9 100644 --- mlibc-clean/sysdeps/astral/generic/generic.cpp +++ mlibc-workdir/sysdeps/astral/generic/generic.cpp @@ -47,6 +47,25 @@ namespace mlibc { return 0; } + int sys_readv(int fd, const struct iovec *iovs, int iovc, ssize_t *bytes_read) { + long r; + int error = syscall(SYSCALL_READV, &r, fd, (uint64_t)iovs, iovc); + *bytes_read = r; + return error; + } + + int sys_writev(int fd, const struct iovec *iovs, int iovc, ssize_t *bytes_written) { + long r; + int error = syscall(SYSCALL_WRITEV, &r, fd, (uint64_t)iovs, iovc); + *bytes_written = r; + return error; + } + + int sys_sysinfo(struct sysinfo *info) { + long r; + return syscall(SYSCALL_SYSINFO, &r, (uint64_t)info); + } + int sys_getcpu(int *cpu) { long ret; // can never fail diff --git mlibc-clean/sysdeps/astral/include/astral/syscall.h mlibc-workdir/sysdeps/astral/include/astral/syscall.h index 8414286..a6c4067 100644 --- mlibc-clean/sysdeps/astral/include/astral/syscall.h +++ mlibc-workdir/sysdeps/astral/include/astral/syscall.h @@ -100,6 +100,9 @@ #define SYSCALL_NICE 93 #define SYSCALL_FLOCK 94 #define SYSCALL_GETCPU 95 +#define SYSCALL_SYSINFO 96 +#define SYSCALL_WRITEV 97 +#define SYSCALL_READV 98 #ifndef __MLIBC_ABI_ONLY