Make improvements

- Invent openatemp() API
- Invent O_UNLINK open flag
- Introduce getenv_secure() API
- Remove `git pull` from cosmocc
- Fix utimes() when path is NULL
- Fix mktemp() to never return NULL
- Fix utimensat() UTIME_OMIT on XNU
- Improve utimensat() code for RHEL5
- Turn `argv[0]` C:/ to /C/ on Windows
- Introduce tmpnam() and tmpnam_r() APIs
- Fix more const issues with internal APIs
- Permit utimes() on WIN32 in O_RDONLY mode
- Fix fdopendir() to check fd is a directory
- Fix recent crash regression in landlock make
- Fix futimens(AT_FDCWD, NULL) to return EBADF
- Use workaround so `make -j` doesn't fork bomb
- Rename dontdiscard to __wur (just like glibc)
- Fix st_size for WIN32 symlinks containing UTF-8
- Introduce stdio ext APIs needed by GNU coreutils
- Fix lstat() on WIN32 for symlinks to directories
- Move some constants from normalize.inc to limits.h
- Fix segv with memchr() and memcmp() overlapping page
- Implement POSIX fflush() behavior for reader streams
- Implement AT_SYMLINK_NOFOLLOW for utimensat() on WIN32
- Don't change read-only status of existing files on WIN32
- Correctly handle `0x[^[:xdigit:]]` case in strtol() functions
This commit is contained in:
Justine Tunney 2023-09-06 03:54:42 -07:00
parent 8596e83cce
commit f531acc8f9
No known key found for this signature in database
GPG key ID: BE714B4575D6E328
297 changed files with 1920 additions and 1681 deletions

View file

@ -347,7 +347,7 @@ static void __asan_exit(void) {
_Exit(99);
}
dontdiscard static __asan_die_f *__asan_die(void) {
static __wur __asan_die_f *__asan_die(void) {
if (_weaken(__die)) {
return _weaken(__die);
} else {
@ -707,8 +707,7 @@ static const char *__asan_describe_access_poison(signed char kind) {
}
}
static dontdiscard __asan_die_f *__asan_report_invalid_pointer(
const void *addr) {
static __wur __asan_die_f *__asan_report_invalid_pointer(const void *addr) {
kprintf("\n\e[J\e[1;31masan error\e[0m: this corruption at %p shadow %p\n",
addr, SHADOW(addr));
return __asan_die();
@ -825,9 +824,9 @@ static void __asan_report_memory_origin(const unsigned char *addr, int size,
}
}
dontdiscard static __asan_die_f *__asan_report(const void *addr, int size,
const char *message,
signed char kind) {
static __wur __asan_die_f *__asan_report(const void *addr, int size,
const char *message,
signed char kind) {
int i;
wint_t c;
signed char t;
@ -940,8 +939,8 @@ void __asan_verify_str(const char *p) {
__asan_verify_failed(UNSHADOW(f.shadow), 8, f);
}
static dontdiscard __asan_die_f *__asan_report_memory_fault(
void *addr, int size, const char *message) {
static __wur __asan_die_f *__asan_report_memory_fault(void *addr, int size,
const char *message) {
return __asan_report(addr, size, message,
__asan_fault(SHADOW(addr), -128).kind);
}

View file

@ -8,9 +8,9 @@ int _bsrl(long) pureconst;
int _bsrll(long long) pureconst;
#if defined(__GNUC__) && !defined(__STRICT_ANSI__)
#define _bsr(x) (__builtin_clz(x) ^ (sizeof(int) * CHAR_BIT - 1))
#define _bsrl(x) (__builtin_clzl(x) ^ (sizeof(long) * CHAR_BIT - 1))
#define _bsrll(x) (__builtin_clzll(x) ^ (sizeof(long long) * CHAR_BIT - 1))
#define _bsr(x) (__builtin_clz(x) ^ (sizeof(int) * 8 - 1))
#define _bsrl(x) (__builtin_clzl(x) ^ (sizeof(long) * 8 - 1))
#define _bsrll(x) (__builtin_clzll(x) ^ (sizeof(long long) * 8 - 1))
#endif
COSMOPOLITAN_C_END_

View file

@ -139,6 +139,10 @@ void bzero(void *p, size_t n) {
#ifdef __x86_64__
asm("xorl\t%k0,%k0" : "=r"(x));
#else
if (1) {
memset(p, 0, n);
return;
}
x = 0;
#endif
if (n <= 16) {

View file

@ -31,11 +31,11 @@ __msabi extern typeof(CreateDirectory) *const __imp_CreateDirectoryW;
* @note this wrapper takes care of ABI, STRACE(), and __winerr()
*/
textwindows bool32 CreateDirectory(const char16_t *lpPathName,
struct NtSecurityAttributes *lpSecurity) {
const struct NtSecurityAttributes *lpSec) {
bool32 ok;
ok = __imp_CreateDirectoryW(lpPathName, lpSecurity);
ok = __imp_CreateDirectoryW(lpPathName, lpSec);
if (!ok) __winerr();
NTTRACE("CreateDirectory(%#hs, %s) → %hhhd% m", lpPathName,
DescribeNtSecurityAttributes(lpSecurity), ok);
DescribeNtSecurityAttributes(lpSec), ok);
return ok;
}

View file

@ -32,8 +32,8 @@ __msabi extern typeof(CreateProcess) *const __imp_CreateProcessW;
*/
textwindows bool32
CreateProcess(const char16_t *opt_lpApplicationName, char16_t *lpCommandLine,
struct NtSecurityAttributes *opt_lpProcessAttributes,
struct NtSecurityAttributes *opt_lpThreadAttributes,
const struct NtSecurityAttributes *opt_lpProcessAttributes,
const struct NtSecurityAttributes *opt_lpThreadAttributes,
bool32 bInheritHandles, uint32_t dwCreationFlags,
void *opt_lpEnvironment, const char16_t *opt_lpCurrentDirectory,
const struct NtStartupInfo *lpStartupInfo,

View file

@ -32,7 +32,7 @@ __msabi extern typeof(CreateThread) *const __imp_CreateThread;
* @note this wrapper takes care of ABI, STRACE()
*/
textwindows int64_t
CreateThread(struct NtSecurityAttributes *lpThreadAttributes,
CreateThread(const struct NtSecurityAttributes *lpThreadAttributes,
size_t dwStackSize, void *lpStartAddress, void *lpParameter,
uint32_t dwCreationFlags, uint32_t *opt_lpThreadId) {
int64_t hHandle;

View file

@ -46,7 +46,6 @@ dontasan int __cxa_atexit(void *fp, void *arg, void *pred) {
/* asan runtime depends on this function */
unsigned i;
struct CxaAtexitBlock *b, *b2;
_Static_assert(ATEXIT_MAX == CHAR_BIT * sizeof(b->mask), "");
__cxa_lock();
b = __cxa_blocks.p;
if (!b) b = __cxa_blocks.p = &__cxa_blocks.root;

View file

@ -14,7 +14,7 @@ struct CxaAtexitBlocks {
void *fp;
void *arg;
void *pred;
} p[ATEXIT_MAX];
} p[32];
} * p, root;
};

View file

@ -44,6 +44,7 @@ const char *DescribeNtProcAccessFlags(char[256], uint32_t);
const char *DescribeNtStartFlags(char[128], uint32_t);
const char *DescribeNtSymlinkFlags(char[64], uint32_t);
const char *DescribeOpenFlags(char[128], int);
const char *DescribeOpenMode(char[15], int, int);
const char *DescribePersonalityFlags(char[128], int);
const char *DescribePollFlags(char[64], int);
const char *DescribePrctlOperation(int);
@ -97,6 +98,7 @@ const char *DescribeWhichPrio(char[12], int);
#define DescribeNtStartFlags(x) DescribeNtStartFlags(alloca(128), x)
#define DescribeNtSymlinkFlags(x) DescribeNtSymlinkFlags(alloca(64), x)
#define DescribeOpenFlags(x) DescribeOpenFlags(alloca(128), x)
#define DescribeOpenMode(x, y) DescribeOpenMode(alloca(15), x, y)
#define DescribePersonalityFlags(p) DescribePersonalityFlags(alloca(128), p)
#define DescribePollFlags(p) DescribePollFlags(alloca(64), p)
#define DescribeProtFlags(x) DescribeProtFlags(alloca(48), x)

View file

@ -20,7 +20,7 @@
#include "libc/intrin/kprintf.h"
#include "libc/macros.internal.h"
const char *(DescribeNtOverlapped)(char b[128], struct NtOverlapped *o) {
const char *(DescribeNtOverlapped)(char b[128], const struct NtOverlapped *o) {
int i = 0, n = 128;
bool gotsome = false;
if (!o) return "NULL";

View file

@ -5,7 +5,7 @@
#if !(__ASSEMBLER__ + __LINKER__ + 0)
COSMOPOLITAN_C_START_
const char *DescribeNtOverlapped(char[128], struct NtOverlapped *);
const char *DescribeNtOverlapped(char[128], const struct NtOverlapped *);
#define DescribeNtOverlapped(x) DescribeNtOverlapped(alloca(128), x)
COSMOPOLITAN_C_END_

View file

@ -21,8 +21,9 @@
#include "libc/intrin/describeflags.internal.h"
#include "libc/nt/struct/securityattributes.h"
const char *(DescribeNtSecurityAttributes)(char buf[32],
struct NtSecurityAttributes *p) {
const char *(
DescribeNtSecurityAttributes)(char buf[32],
const struct NtSecurityAttributes *p) {
if (p == &kNtIsInheritable) return "&kNtIsInheritable";
FormatInt64(buf, (uintptr_t)p);
return buf;

View file

@ -0,0 +1,40 @@
/*-*- 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.
*/
#include "libc/dce.h"
#include "libc/fmt/itoa.h"
#include "libc/intrin/describeflags.internal.h"
#include "libc/sysv/consts/o.h"
#define O_TMPFILE_LINUX 0x00410000
static bool IsCreatingFile(int flags) {
return (flags & O_CREAT) ||
(IsLinux() && (flags & O_TMPFILE_LINUX) == O_TMPFILE_LINUX);
}
const char *(DescribeOpenMode)(char buf[15], int flags, int mode) {
if (!IsCreatingFile(flags)) {
return "";
}
char *p = buf;
*p++ = ',';
*p++ = ' ';
FormatOctal32(p, mode, true);
return buf;
}

View file

@ -0,0 +1,47 @@
/*-*- 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 2021 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.
*/
#include "libc/fmt/itoa.h"
/**
* Converts unsigned 32-bit integer to octal string.
*
* @param p needs at least 12 bytes
* @param z ensures it starts with zero
* @return pointer to nul byte
*/
char *FormatOctal32(char p[hasatleast 13], uint32_t x, bool z) {
char t;
size_t i, a, b;
i = 0;
z = x && z;
do {
p[i++] = x % 8 + '0';
x = x / 8;
} while (x > 0);
if (z) p[i++] = '0';
p[i] = '\0';
if (i) {
for (a = 0, b = i - 1; a < b; ++a, --b) {
t = p[a];
p[a] = p[b];
p[b] = t;
}
}
return p + i;
}

View file

@ -34,6 +34,8 @@
#include "libc/sysv/consts/o.h"
#include "libc/thread/thread.h"
#define OPEN_MAX 16
#ifdef __x86_64__
__static_yoink("_init_g_fds");
#endif

View file

@ -31,7 +31,6 @@
char *getenv(const char *s) {
char **p;
struct Env e;
if (!s) return 0;
if (!(p = environ)) return 0;
e = __getenv(p, s);
#if SYSDEBUG

View file

@ -19,7 +19,7 @@
#include "libc/nt/struct/securityattributes.h"
const struct NtSecurityAttributes kNtIsInheritable = {
sizeof(struct NtSecurityAttributes),
NULL,
true,
.nLength = sizeof(struct NtSecurityAttributes),
.lpSecurityDescriptor = NULL,
.bInheritHandle = true,
};

View file

@ -36,7 +36,8 @@ kOpenFlags:
.e O_TRUNC,"TRUNC" //
.e O_CLOEXEC,"CLOEXEC" //
.e O_NONBLOCK,"NONBLOCK" //
.e O_TMPFILE,"TMPFILE" // linux, windows
.e O_TMPFILE,"TMPFILE" // linux
.e O_UNLINK,"UNLINK" // windows+unix
.e O_DIRECTORY,"DIRECTORY" // order matters
.e O_DIRECT,"DIRECT" // no-op on xnu/openbsd
.e O_APPEND,"APPEND" // weird on nt

View file

@ -22,7 +22,7 @@
#include "libc/str/str.h"
#ifndef __aarch64__
typedef char xmm_t __attribute__((__vector_size__(16), __aligned__(1)));
typedef char xmm_t __attribute__((__vector_size__(16), __aligned__(16)));
static inline const unsigned char *memchr_pure(const unsigned char *s,
unsigned char c, size_t n) {
@ -68,14 +68,22 @@ dontasan static inline const unsigned char *memchr_sse(const unsigned char *s,
* @return is pointer to first instance of c or NULL if not found
* @asyncsignalsafe
*/
void *memchr(const void *s, int c, size_t n) {
dontasan void *memchr(const void *s, int c, size_t n) {
#if defined(__x86_64__) && !defined(__chibicc__)
const void *r;
if (IsAsan()) __asan_verify(s, n);
r = memchr_sse(s, c, n);
const unsigned char *p = (const unsigned char *)s;
while (n && ((intptr_t)p & 15)) {
if (*p == (unsigned char)c) {
return (void *)p;
}
++p;
--n;
}
r = memchr_sse(p, c, n);
return (void *)r;
#else
return memchr_pure(s, c, n);
return (void *)memchr_pure(s, c, n);
#endif
}

View file

@ -22,113 +22,34 @@
#include "libc/str/str.h"
#ifndef __aarch64__
#define PMOVMSKB(x) __builtin_ia32_pmovmskb128(x)
typedef char xmm_t __attribute__((__vector_size__(16), __aligned__(1)));
#if defined(__x86_64__) && !defined(__chibicc__)
static dontinline antiquity int memcmp_sse(const unsigned char *p,
const unsigned char *q, size_t n) {
unsigned u;
if (n > 32) {
while (n > 16 + 16) {
if (!(u = PMOVMSKB(*(xmm_t *)p == *(xmm_t *)q) ^ 0xffff)) {
n -= 16;
p += 16;
q += 16;
} else {
u = __builtin_ctzl(u);
return p[u] - q[u];
}
}
}
if (!(u = PMOVMSKB(*(xmm_t *)p == *(xmm_t *)q) ^ 0xffff)) {
if (!(u = PMOVMSKB(*(xmm_t *)(p + n - 16) == *(xmm_t *)(q + n - 16)) ^
0xffff)) {
return 0;
} else {
u = __builtin_ctzl(u);
return p[n - 16 + u] - q[n - 16 + u];
}
} else {
u = __builtin_ctzl(u);
return p[u] - q[u];
}
}
_Microarchitecture("avx") static int memcmp_avx(const unsigned char *p,
const unsigned char *q,
size_t n) {
uint64_t w;
unsigned u;
if (n > 32) {
while (n >= 16 + 64) {
w = (uint64_t)PMOVMSKB(((xmm_t *)p)[0] == ((xmm_t *)q)[0]) << 000 |
(uint64_t)PMOVMSKB(((xmm_t *)p)[1] == ((xmm_t *)q)[1]) << 020 |
(uint64_t)PMOVMSKB(((xmm_t *)p)[2] == ((xmm_t *)q)[2]) << 040 |
(uint64_t)PMOVMSKB(((xmm_t *)p)[3] == ((xmm_t *)q)[3]) << 060;
if (w == -1) {
n -= 64;
p += 64;
q += 64;
} else {
w = __builtin_ctzll(w ^ -1);
return p[w] - q[w];
}
}
while (n > 16 + 16) {
if (!(u = PMOVMSKB(*(xmm_t *)p == *(xmm_t *)q) ^ 0xffff)) {
n -= 16;
p += 16;
q += 16;
} else {
u = __builtin_ctzl(u);
return p[u] - q[u];
}
}
}
if (!(u = PMOVMSKB(*(xmm_t *)p == *(xmm_t *)q) ^ 0xffff)) {
if (!(u = PMOVMSKB(*(xmm_t *)(p + n - 16) == *(xmm_t *)(q + n - 16)) ^
0xffff)) {
return 0;
} else {
u = __builtin_ctzl(u);
return p[n - 16 + u] - q[n - 16 + u];
}
} else {
u = __builtin_ctzl(u);
return p[u] - q[u];
}
}
#endif /* __x86_64__ */
/**
* Compares memory byte by byte.
*
* memcmp n=0 992 picoseconds
* memcmp n=1 1 ns/byte 738 mb/s
* memcmp n=2 661 ps/byte 1,476 mb/s
* memcmp n=3 551 ps/byte 1,771 mb/s
* memcmp n=4 248 ps/byte 3,936 mb/s
* memcmp n=5 198 ps/byte 4,920 mb/s
* memcmp n=6 165 ps/byte 5,904 mb/s
* memcmp n=7 141 ps/byte 6,889 mb/s
* memcmp n=8 124 ps/byte 7,873 mb/s
* memcmp n=9 110 ps/byte 8,857 mb/s
* memcmp n=15 44 ps/byte 22,143 mb/s
* memcmp n=16 41 ps/byte 23,619 mb/s
* memcmp n=17 77 ps/byte 12,547 mb/s
* memcmp n=31 42 ps/byte 22,881 mb/s
* memcmp n=32 41 ps/byte 23,619 mb/s
* memcmp n=33 60 ps/byte 16,238 mb/s
* memcmp n=80 53 ps/byte 18,169 mb/s
* memcmp n=128 38 ps/byte 25,194 mb/s
* memcmp n=256 32 ps/byte 30,233 mb/s
* memcmp n=16384 27 ps/byte 35,885 mb/s
* memcmp n=32768 29 ps/byte 32,851 mb/s
* memcmp n=131072 33 ps/byte 28,983 mb/s
* memcmp n=0 2 nanoseconds
* memcmp n=1 2 ns/byte 357 mb/s
* memcmp n=2 1 ns/byte 530 mb/s
* memcmp n=3 1 ns/byte 631 mb/s
* 𝗺𝗲𝗺𝗰𝗺𝗽 n=4 1 ns/byte 849 mb/s
* memcmp n=5 816 ps/byte 1,195 mb/s
* memcmp n=6 888 ps/byte 1,098 mb/s
* memcmp n=7 829 ps/byte 1,176 mb/s
* 𝗺𝗲𝗺𝗰𝗺𝗽 n=8 773 ps/byte 1,261 mb/s
* memcmp n=9 629 ps/byte 1,551 mb/s
* memcmp n=15 540 ps/byte 1,805 mb/s
* 𝗺𝗲𝗺𝗰𝗺𝗽 n=16 211 ps/byte 4,623 mb/s
* memcmp n=17 268 ps/byte 3,633 mb/s
* memcmp n=31 277 ps/byte 3,524 mb/s
* memcmp n=32 153 ps/byte 6,351 mb/s
* memcmp n=33 179 ps/byte 5,431 mb/s
* memcmp n=79 148 ps/byte 6,576 mb/s
* 𝗺𝗲𝗺𝗰𝗺𝗽 n=80 81 ps/byte 11 GB/s
* memcmp n=128 76 ps/byte 12 GB/s
* memcmp n=256 60 ps/byte 15 GB/s
* memcmp n=16384 51 ps/byte 18 GB/s
* memcmp n=32768 51 ps/byte 18 GB/s
* memcmp n=131072 52 ps/byte 18 GB/s
*
* @return an integer that's (1) equal to zero if `a` is equal to `b`,
* (2) less than zero if `a` is less than `b`, or (3) greater than
@ -137,62 +58,21 @@ _Microarchitecture("avx") static int memcmp_avx(const unsigned char *p,
*/
int memcmp(const void *a, const void *b, size_t n) {
int c;
unsigned u;
uint32_t k, i, j;
uint64_t w, x, y;
const unsigned char *p, *q;
if ((p = a) == (q = b) || !n) return 0;
if ((c = *p - *q)) return c;
#if defined(__x86_64__) && !defined(__chibicc__)
if (!IsTiny()) {
if (n <= 16) {
if (n >= 8) {
if (!(w = (x = ((uint64_t)p[0] << 000 | (uint64_t)p[1] << 010 |
(uint64_t)p[2] << 020 | (uint64_t)p[3] << 030 |
(uint64_t)p[4] << 040 | (uint64_t)p[5] << 050 |
(uint64_t)p[6] << 060 | (uint64_t)p[7] << 070)) ^
(y = ((uint64_t)q[0] << 000 | (uint64_t)q[1] << 010 |
(uint64_t)q[2] << 020 | (uint64_t)q[3] << 030 |
(uint64_t)q[4] << 040 | (uint64_t)q[5] << 050 |
(uint64_t)q[6] << 060 | (uint64_t)q[7] << 070)))) {
p += n - 8;
q += n - 8;
if (!(w = (x = ((uint64_t)p[0] << 000 | (uint64_t)p[1] << 010 |
(uint64_t)p[2] << 020 | (uint64_t)p[3] << 030 |
(uint64_t)p[4] << 040 | (uint64_t)p[5] << 050 |
(uint64_t)p[6] << 060 | (uint64_t)p[7] << 070)) ^
(y = ((uint64_t)q[0] << 000 | (uint64_t)q[1] << 010 |
(uint64_t)q[2] << 020 | (uint64_t)q[3] << 030 |
(uint64_t)q[4] << 040 | (uint64_t)q[5] << 050 |
(uint64_t)q[6] << 060 | (uint64_t)q[7] << 070)))) {
return 0;
}
}
u = __builtin_ctzll(w);
u = u & -8;
return ((x >> u) & 255) - ((y >> u) & 255);
} else if (n >= 4) {
if (!(k = (i = ((uint32_t)p[0] << 000 | (uint32_t)p[1] << 010 |
(uint32_t)p[2] << 020 | (uint32_t)p[3] << 030)) ^
(j = ((uint32_t)q[0] << 000 | (uint32_t)q[1] << 010 |
(uint32_t)q[2] << 020 | (uint32_t)q[3] << 030)))) {
p += n - 4;
q += n - 4;
if (!(k = (i = ((uint32_t)p[0] << 000 | (uint32_t)p[1] << 010 |
(uint32_t)p[2] << 020 | (uint32_t)p[3] << 030)) ^
(j = ((uint32_t)q[0] << 000 | (uint32_t)q[1] << 010 |
(uint32_t)q[2] << 020 | (uint32_t)q[3] << 030)))) {
return 0;
}
}
u = __builtin_ctzl(k);
u = u & -8;
return ((i >> u) & 255) - ((j >> u) & 255);
}
} else if (LIKELY(X86_HAVE(AVX))) {
return memcmp_avx(p, q, n);
unsigned u;
while (n >= 16 && (((uintptr_t)p & 0xfff) <= 0x1000 - 16 &&
((uintptr_t)q & 0xfff) <= 0x1000 - 16)) {
if (!(u = __builtin_ia32_pmovmskb128(*(xmm_t *)p == *(xmm_t *)q) ^
0xffff)) {
n -= 16;
p += 16;
q += 16;
} else {
return memcmp_sse(p, q, n);
u = __builtin_ctzl(u);
return p[u] - q[u];
}
}
#endif /* __x86_64__ */

View file

@ -18,6 +18,7 @@
*/
#include "libc/dce.h"
#include "libc/intrin/asan.internal.h"
#include "libc/limits.h"
#include "libc/nexgen32e/x86feature.h"
#include "libc/str/str.h"
#ifndef __aarch64__
@ -75,7 +76,7 @@ void *memrchr(const void *s, int c, size_t n) {
r = memrchr_sse(s, c, n);
return (void *)r;
#else
return memrchr_pure(s, c, n);
return (void *)memrchr_pure(s, c, n);
#endif
}

View file

@ -20,7 +20,7 @@
#include "libc/macros.internal.h"
.init.start 200,_init__mmi
movb $OPEN_MAX,_mmi+8
movb $16,_mmi+8
movl $_mmi+24,_mmi+16
movb $PTHREAD_MUTEX_RECURSIVE,__mmi_lock_obj+4(%rip)
.init.end 200,_init__mmi

View file

@ -17,6 +17,7 @@
PERFORMANCE OF THIS SOFTWARE.
*/
#include "libc/calls/struct/sigset.h"
#include "libc/limits.h"
#include "libc/sysv/consts/limits.h"
#include "libc/sysv/consts/sig.h"
#include "libc/sysv/errfuns.h"

View file

@ -17,6 +17,7 @@
PERFORMANCE OF THIS SOFTWARE.
*/
#include "libc/calls/struct/sigset.h"
#include "libc/limits.h"
#include "libc/sysv/errfuns.h"
/**

View file

@ -17,6 +17,7 @@
PERFORMANCE OF THIS SOFTWARE.
*/
#include "libc/calls/struct/sigset.h"
#include "libc/limits.h"
#include "libc/sysv/consts/limits.h"
#include "libc/sysv/errfuns.h"

View file

@ -107,14 +107,14 @@ dontasan char *strchr(const char *s, int c) {
unassert(!r || *r || !(c & 255));
return (char *)r;
#else
char *r;
const char *r;
for (c &= 255; (uintptr_t)s & 7; ++s) {
if ((*s & 255) == c) return s;
if ((*s & 255) == c) return (char *)s;
if (!*s) return NULL;
}
r = strchr_x64(s, c);
unassert(!r || *r || !c);
return r;
return (char *)r;
#endif
}

View file

@ -36,7 +36,7 @@
* @asyncsignalsafe
* @threadsafe
*/
privileged dontdiscard char *strsignal_r(int sig, char buf[21]) {
privileged char *strsignal_r(int sig, char buf[21]) {
const char *s;
if (!sig) {
return "0";

View file

@ -22,6 +22,7 @@
#include "libc/intrin/pushpop.internal.h"
#include "libc/intrin/strace.internal.h"
#include "libc/intrin/weaken.h"
#include "libc/limits.h"
#include "libc/log/color.internal.h"
#include "libc/log/internal.h"
#include "libc/log/libfatal.internal.h"
@ -218,7 +219,7 @@ static char *__ubsan_stpcpy(char *d, const char *s) {
}
}
dontdiscard static __ubsan_die_f *__ubsan_die(void) {
__wur static __ubsan_die_f *__ubsan_die(void) {
if (_weaken(__die)) {
return _weaken(__die);
} else {
@ -232,8 +233,8 @@ static void __ubsan_warning(const struct UbsanSourceLocation *loc,
loc->line, SUBTLE, description, RESET);
}
dontdiscard __ubsan_die_f *__ubsan_abort(const struct UbsanSourceLocation *loc,
const char *description) {
__wur __ubsan_die_f *__ubsan_abort(const struct UbsanSourceLocation *loc,
const char *description) {
kprintf("\n%s:%d: %subsan error%s: %s (tid %d)\n", loc->file, loc->line, RED2,
RESET, description, gettid());
return __ubsan_die();