Clean up some code

- Use good ELF technique in cosmo_dlopen()
- Make strerror() conform more to other libc impls
- Introduce __clear_cache() and use it in cosmo_dlopen()
- Remove libc/fmt/fmt.h header (trying to kill off LIBC_FMT)
This commit is contained in:
Justine Tunney 2023-11-16 16:34:53 -08:00
parent 7010a8081e
commit 68c7c9c1e0
No known key found for this signature in database
GPG key ID: BE714B4575D6E328
244 changed files with 378 additions and 588 deletions

View file

@ -0,0 +1,37 @@
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi
Copyright 2023 Justine Alexandra Roberts Tunney
Permission to use, copy, modify, and/or distribute this software for
any purpose with or without fee is hereby granted, provided that the
above copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
PERFORMANCE OF THIS SOFTWARE.
*/
void __clear_cache2(const void *base, const void *end) {
#ifdef __aarch64__
int icache, dcache;
const char *p, *pe = end;
static unsigned int ctr_el0 = 0;
if (!ctr_el0) asm volatile("mrs\t%0,ctr_el0" : "=r"(ctr_el0));
icache = 4 << (ctr_el0 & 15);
dcache = 4 << ((ctr_el0 >> 16) & 15);
for (p = (const char *)((uintptr_t)base & -dcache); p < pe; p += dcache) {
asm volatile("dc\tcvau,%0" : : "r"(p) : "memory");
}
asm volatile("dsb\tish" ::: "memory");
for (p = (const char *)((uintptr_t)base & -icache); p < pe; p += icache) {
asm volatile("ic\tivau,%0" : : "r"(p) : "memory");
}
asm volatile("dsb\tish\nisb" ::: "memory");
#endif
}

View file

@ -24,7 +24,7 @@
* @param p needs at least 12 bytes
* @return pointer to nul byte
*/
privileged dontinline char *FormatUint32(char p[hasatleast 12], uint32_t x) {
dontinline char *FormatUint32(char p[hasatleast 12], uint32_t x) {
char t;
size_t i, a, b;
i = 0;
@ -49,7 +49,7 @@ privileged dontinline char *FormatUint32(char p[hasatleast 12], uint32_t x) {
* @param p needs at least 12 bytes
* @return pointer to nul byte
*/
privileged char *FormatInt32(char p[hasatleast 12], int32_t x) {
char *FormatInt32(char p[hasatleast 12], int32_t x) {
if (x < 0) *p++ = '-', x = -(uint32_t)x;
return FormatUint32(p, x);
}

View file

@ -18,32 +18,18 @@
*/
#include "libc/intrin/kprintf.h"
#include "ape/sections.internal.h"
#include "libc/calls/calls.h"
#include "libc/calls/state.internal.h"
#include "libc/calls/syscall-sysv.internal.h"
#include "libc/dce.h"
#include "libc/errno.h"
#include "libc/fmt/divmod10.internal.h"
#include "libc/fmt/fmt.h"
#include "libc/fmt/itoa.h"
#include "libc/fmt/magnumstrs.internal.h"
#include "libc/intrin/asan.internal.h"
#include "libc/intrin/asancodes.h"
#include "libc/intrin/asmflag.h"
#include "libc/intrin/atomic.h"
#include "libc/intrin/bits.h"
#include "libc/intrin/cmpxchg.h"
#include "libc/intrin/getenv.internal.h"
#include "libc/intrin/kprintf.h"
#include "libc/intrin/likely.h"
#include "libc/intrin/nomultics.internal.h"
#include "libc/intrin/safemacros.internal.h"
#include "libc/intrin/strace.internal.h"
#include "libc/intrin/weaken.h"
#include "libc/limits.h"
#include "libc/log/internal.h"
#include "libc/macros.internal.h"
#include "libc/mem/alloca.h"
#include "libc/nexgen32e/rdtsc.h"
#include "libc/nexgen32e/uart.internal.h"
#include "libc/nt/createfile.h"
@ -56,25 +42,21 @@
#include "libc/nt/process.h"
#include "libc/nt/runtime.h"
#include "libc/nt/thunk/msabi.h"
#include "libc/nt/winsock.h"
#include "libc/runtime/internal.h"
#include "libc/runtime/memtrack.internal.h"
#include "libc/runtime/runtime.h"
#include "libc/runtime/stack.h"
#include "libc/runtime/symbols.internal.h"
#include "libc/stdckdint.h"
#include "libc/str/str.h"
#include "libc/str/tab.internal.h"
#include "libc/str/utf16.h"
#include "libc/sysv/consts/at.h"
#include "libc/sysv/consts/auxv.h"
#include "libc/sysv/consts/f.h"
#include "libc/sysv/consts/fd.h"
#include "libc/sysv/consts/fileno.h"
#include "libc/sysv/consts/nr.h"
#include "libc/sysv/consts/o.h"
#include "libc/sysv/consts/prot.h"
#include "libc/thread/posixthread.internal.h"
#include "libc/thread/tls.h"
#include "libc/thread/tls2.internal.h"
#include "libc/vga/vga.internal.h"
@ -766,16 +748,9 @@ privileged static size_t kformat(char *b, size_t n, const char *fmt,
break;
} else {
type = 0;
#if defined(SYSDEBUG) && _NTTRACE
strerror_r(e, z, sizeof(z));
s = z;
#else
s = _strerrno(e);
if (!s) {
FormatInt32(z, e);
s = z;
if (!(s = _strerrno(e))) {
s = "EUNKNOWN";
}
#endif
goto FormatString;
}
}
@ -1145,8 +1120,7 @@ privileged void kvprintf(const char *fmt, va_list v) {
*
* Error numbers:
*
* - `%m` formats error (if strerror_wr if is linked)
* - `%m` formats errno number (if strerror_wr isn't linked)
* - `%m` formats errno as string
* - `% m` formats error with leading space if errno isn't zero
* - `%lm` means favor WSAGetLastError() over GetLastError() if linked
*

View file

@ -17,21 +17,20 @@
PERFORMANCE OF THIS SOFTWARE.
*/
#include "libc/dce.h"
#include "libc/fmt/fmt.h"
#include "libc/fmt/magnumstrs.internal.h"
#include "libc/intrin/safemacros.internal.h"
#include "libc/str/str.h"
_Alignas(1) static char strerror_buf[128];
/**
* Converts errno value to string non-reentrantly.
* Returns string describing `err`.
*
* The application shall not modify the string returned.
*
* @see strerror_r()
* @threadunsafe
*/
char *strerror(int err) {
if (IsTiny()) {
return (char *)firstnonnull(_strerrno(err), "EUNKNOWN");
} else {
_Alignas(1) static char buf[512];
strerror_r(err, buf, sizeof(buf));
return buf;
}
strerror_r(err, strerror_buf, sizeof(strerror_buf));
return strerror_buf;
}

View file

@ -16,25 +16,61 @@
TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
PERFORMANCE OF THIS SOFTWARE.
*/
#define ShouldUseMsabiAttribute() 1
#include "libc/dce.h"
#include "libc/intrin/strace.internal.h"
#include "libc/errno.h"
#include "libc/fmt/itoa.h"
#include "libc/fmt/magnumstrs.internal.h"
#include "libc/nt/runtime.h"
#include "libc/nt/thunk/msabi.h"
#include "libc/str/str.h"
// clang-format off
#if defined(SYSDEBUG) && _NTTRACE
privileged
#endif
/**
* Converts errno value to string.
*
* @param err is error number or zero if unknown
* @return 0 on success, or error code
* @return 0 on success, or errno on error
* @raise ERANGE if insufficient buffer was available, in which case a
* nul-terminated string is still copied to `buf`
*/
int strerror_r(int err, char *buf, size_t size) {
int winerr = IsWindows() ? __imp_GetLastError() : 0;
return strerror_wr(err, winerr, buf, size);
errno_t strerror_r(int err, char *buf, size_t size) {
int c;
char tmp[32];
char *p = buf;
char *pe = p + size;
// copy unix error information
const char *msg;
if (!err) {
msg = "No error information";
} else if (!(msg = _strerdoc(err))) {
FormatInt32(stpcpy(tmp, "Error "), err);
msg = tmp;
}
while ((c = *msg++) && p + 1 < pe) {
*p++ = c;
}
// copy windows error information
if (IsWindows()) {
uint32_t winerr;
if ((winerr = GetLastError()) != err) {
stpcpy(FormatUint32(stpcpy(tmp, " (win32 error "), winerr), ")");
msg = tmp;
while ((c = *msg++) && p + 1 < pe) {
*p++ = c;
}
}
}
// force nul terminator
if (p < pe) {
*p++ = 0;
}
// return result code
if (p < pe) {
return 0;
} else {
return ERANGE;
}
}

View file

@ -1,76 +0,0 @@
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi
Copyright 2022 Justine Alexandra Roberts Tunney
Permission to use, copy, modify, and/or distribute this software for
any purpose with or without fee is hereby granted, provided that the
above copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
PERFORMANCE OF THIS SOFTWARE.
*/
#define ShouldUseMsabiAttribute() 1
#include "libc/dce.h"
#include "libc/fmt/fmt.h"
#include "libc/fmt/magnumstrs.internal.h"
#include "libc/intrin/kprintf.h"
#include "libc/intrin/strace.internal.h"
#include "libc/macros.internal.h"
#include "libc/nt/enum/formatmessageflags.h"
#include "libc/nt/enum/lang.h"
#include "libc/nt/process.h"
#include "libc/str/str.h"
// clang-format off
#if defined(SYSDEBUG) && _NTTRACE
privileged
#endif
/**
* Converts errno value to string with explicit windows errno too.
*
* @param err is error number or zero if unknown
* @return 0 on success, or error code
*/
int strerror_wr(int err, uint32_t winerr, char *buf, size_t size) {
/* kprintf() weakly depends on this function */
int c, n;
char16_t winmsg[256];
const char *sym, *msg;
/* wanting = false; */
if (!(sym = _strerrno(err))) {
sym = "EUNKNOWN";
/* wanting = true; */
}
if (!(msg = _strerdoc(err))) {
msg = "No error information";
/* wanting = true; */
}
if (IsTiny()) {
if (!sym) sym = "EUNKNOWN";
for (; (c = *sym++); --size)
if (size > 1) *buf++ = c;
if (size) *buf = 0;
} else if (!IsWindows() /* || ((err == winerr || !winerr) && !wanting) */) {
ksnprintf(buf, size, "%s/%d/%s", sym, err, msg);
} else {
if ((n = __imp_FormatMessageW(
kNtFormatMessageFromSystem | kNtFormatMessageIgnoreInserts, 0,
winerr, MAKELANGID(kNtLangNeutral, kNtSublangDefault), winmsg,
ARRAYLEN(winmsg), 0))) {
while ((n && winmsg[n - 1] <= ' ') || winmsg[n - 1] == '.') --n;
ksnprintf(buf, size, "%s/%d/%s/%d/%.*hs", sym, err, msg, winerr, n,
winmsg);
} else {
ksnprintf(buf, size, "%s/%d/%s/%d", sym, err, msg, winerr);
}
}
return 0;
}

View file

@ -38,5 +38,5 @@ static char g_strsignal[21];
* @threadunsafe
*/
char *strsignal(int sig) {
return strsignal_r(sig, g_strsignal);
return (char *)strsignal_r(sig, g_strsignal);
}

View file

@ -16,7 +16,6 @@
TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
PERFORMANCE OF THIS SOFTWARE.
*/
#include "libc/fmt/itoa.h"
#include "libc/fmt/magnumstrs.internal.h"
#include "libc/str/str.h"
#include "libc/sysv/consts/sig.h"
@ -26,8 +25,7 @@
*
* This returns `"0"` for 0 which is the empty value. Symbolic names
* should be available for signals 1 through 32. If the system supports
* real-time signals, they're returned as `SIGRTMIN+%d`. For all other
* 32-bit signed integer, a plain integer representation is returned.
* real-time signals, they're returned as `SIGRTMIN+%d`.
*
* @param sig is signal number which should be in range 1 through 128
* @param buf may be used to store output having at least 15 bytes
@ -35,13 +33,14 @@
* @see sigaction()
* @asyncsignalsafe
*/
privileged char *strsignal_r(int sig, char buf[21]) {
privileged const char *strsignal_r(int sig, char buf[21]) {
char *p;
const char *s;
if (!sig) {
return "0";
}
if ((s = GetMagnumStr(kSignalNames, sig))) {
return (char *)s;
return s;
}
if (SIGRTMIN <= sig && sig <= SIGRTMAX) {
sig -= SIGRTMIN;
@ -54,9 +53,13 @@ privileged char *strsignal_r(int sig, char buf[21]) {
buf[6] = 'I';
buf[7] = 'N';
buf[8] = '+';
FormatInt32(buf + 9, sig);
p = buf + 9;
} else {
FormatInt32(buf, sig);
p = buf;
}
if (sig >= 100) *p++ = '0' + (unsigned char)sig / 100 % 10;
if (sig >= 10) *p++ = '0' + (unsigned char)sig / 10 % 10;
*p++ = '0' + (unsigned char)sig % 10;
*p = 0;
return buf;
}

View file

@ -17,7 +17,6 @@
PERFORMANCE OF THIS SOFTWARE.
*/
#include "libc/calls/calls.h"
#include "libc/fmt/fmt.h"
#include "libc/intrin/kprintf.h"
#include "libc/intrin/pushpop.internal.h"
#include "libc/intrin/strace.internal.h"