mirror of
https://github.com/jart/cosmopolitan.git
synced 2025-07-23 02:50:29 +00:00
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:
parent
7010a8081e
commit
68c7c9c1e0
244 changed files with 378 additions and 588 deletions
37
libc/intrin/__clear_cache.c
Normal file
37
libc/intrin/__clear_cache.c
Normal 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
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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
|
||||
*
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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"
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue