mirror of
https://github.com/jart/cosmopolitan.git
synced 2025-07-16 23:50:32 +00:00
Make improvements
- Get threads working on NetBSD - Get threads working on OpenBSD - Fix Emacs config for Emacs v28 - Improve --strace logging of sigset_t - Improve --strace logging of struct stat - Improve memory safety of DescribeThing functions - Refactor auto stack allocation into LIBC_RUNTIME - Introduce shell.com example which works on Windows - Refactor __strace_thing into DescribeThing functions - Document the CHECK macros and improve them in NDEBUG mode - Rewrite MAP_STACK so it uses FreeBSD behavior across platforms - Deprecate and discourage the use of MAP_GROWSDOWN (it's weird)
This commit is contained in:
parent
dd9ab01d25
commit
e7611a8476
101 changed files with 967 additions and 464 deletions
|
@ -1282,7 +1282,10 @@ void __asan_map_shadow(uintptr_t p, size_t n) {
|
|||
int prot, flag;
|
||||
struct DirectMap sm;
|
||||
struct MemoryIntervals *m;
|
||||
assert(!OverlapsShadowSpace((void *)p, n));
|
||||
if (OverlapsShadowSpace((void *)p, n)) {
|
||||
kprintf("error: %p size %'zu overlaps shadow space\n", p, n);
|
||||
_Exit(1);
|
||||
}
|
||||
m = weaken(_mmi);
|
||||
a = (0x7fff8000 + (p >> 3)) >> 16;
|
||||
b = (0x7fff8000 + (p >> 3) + (n >> 3) + 0xffff) >> 16;
|
||||
|
|
|
@ -46,6 +46,7 @@ relegated wontreturn void __assert_fail(const char *expr, const char *file,
|
|||
} else {
|
||||
rc = 24;
|
||||
}
|
||||
if (weaken(__die)) weaken(__die)();
|
||||
__restorewintty();
|
||||
_Exit(rc);
|
||||
}
|
27
libc/intrin/describedirfd.greg.c
Normal file
27
libc/intrin/describedirfd.greg.c
Normal file
|
@ -0,0 +1,27 @@
|
|||
/*-*- 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"
|
||||
#include "libc/intrin/describeflags.internal.h"
|
||||
#include "libc/sysv/consts/at.h"
|
||||
|
||||
const char *DescribeDirfd(char buf[hasatleast 12], int dirfd) {
|
||||
if (dirfd == AT_FDCWD) return "AT_FDCWD";
|
||||
FormatInt32(buf, dirfd);
|
||||
return buf;
|
||||
}
|
|
@ -1,5 +1,11 @@
|
|||
#ifndef COSMOPOLITAN_LIBC_INTRIN_DESCRIBEFLAGS_INTERNAL_H_
|
||||
#define COSMOPOLITAN_LIBC_INTRIN_DESCRIBEFLAGS_INTERNAL_H_
|
||||
#include "libc/calls/struct/iovec.h"
|
||||
#include "libc/calls/struct/rlimit.h"
|
||||
#include "libc/calls/struct/sigaction.h"
|
||||
#include "libc/calls/struct/sigset.h"
|
||||
#include "libc/calls/struct/stat.h"
|
||||
#include "libc/calls/struct/timespec.h"
|
||||
#include "libc/nt/struct/securityattributes.h"
|
||||
#if !(__ASSEMBLER__ + __LINKER__ + 0)
|
||||
COSMOPOLITAN_C_START_
|
||||
|
@ -15,8 +21,15 @@ const char *DescribeFlags(char *, size_t, struct DescribeFlags *, size_t,
|
|||
const char *DescribeMapFlags(int);
|
||||
const char *DescribeProtFlags(int);
|
||||
const char *DescribeRemapFlags(int);
|
||||
const char *DescribeRlimitName(int);
|
||||
const char *DescribeSeccompOperationFlags(int);
|
||||
const char *DescribePollFlags(char *, size_t, int);
|
||||
const char *DescribeStat(int, const struct stat *);
|
||||
const char *DescribeDirfd(char[hasatleast 12], int);
|
||||
const char *DescribeSigaction(char *, size_t, int, const struct sigaction *);
|
||||
const char *DescribeSigset(char *, size_t, int, const sigset_t *);
|
||||
const char *DescribeRlimit(char *, size_t, int, const struct rlimit *);
|
||||
const char *DescribeTimespec(char *, size_t, int, const struct timespec *);
|
||||
|
||||
const char *DescribeNtPageFlags(uint32_t);
|
||||
const char *DescribeNtStartFlags(uint32_t);
|
||||
|
@ -35,6 +48,8 @@ const char *DescribeNtConsoleModeOutputFlags(uint32_t);
|
|||
const char *DescribeNtFileFlagsAndAttributes(uint32_t);
|
||||
const char *DescribeNtSecurityAttributes(struct NtSecurityAttributes *);
|
||||
|
||||
void DescribeIov(const struct iovec *, int, ssize_t);
|
||||
|
||||
COSMOPOLITAN_C_END_
|
||||
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */
|
||||
#endif /* COSMOPOLITAN_LIBC_INTRIN_DESCRIBEFLAGS_INTERNAL_H_ */
|
||||
|
|
47
libc/intrin/describeframe.c
Normal file
47
libc/intrin/describeframe.c
Normal 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/intrin/kprintf.h"
|
||||
#include "libc/macros.internal.h"
|
||||
#include "libc/runtime/memtrack.internal.h"
|
||||
#include "libc/runtime/runtime.h"
|
||||
|
||||
#define ADDR(x) ((int64_t)((uint64_t)(x) << 32) >> 16)
|
||||
#define UNSHADOW(x) ((int64_t)(MAX(0, (x)-0x7fff8000)) << 3)
|
||||
#define FRAME(x) ((int)((x) >> 16))
|
||||
|
||||
noasan const char *DescribeFrame(int x) {
|
||||
/* asan runtime depends on this function */
|
||||
char *p;
|
||||
static char buf[32];
|
||||
if (IsShadowFrame(x)) {
|
||||
ksnprintf(buf, sizeof(buf), " /*shadow:%.12p*/", UNSHADOW(ADDR(x)));
|
||||
return buf;
|
||||
return " /*shadow*/ ";
|
||||
} else if (IsAutoFrame(x)) {
|
||||
return " /*automap*/";
|
||||
} else if (IsFixedFrame(x)) {
|
||||
return " /*fixed*/ ";
|
||||
} else if (IsArenaFrame(x)) {
|
||||
return " /*arena*/ ";
|
||||
} else if (IsStaticStackFrame(x)) {
|
||||
return " /*stack*/ ";
|
||||
} else {
|
||||
return "";
|
||||
}
|
||||
}
|
42
libc/intrin/describeiov.greg.c
Normal file
42
libc/intrin/describeiov.greg.c
Normal file
|
@ -0,0 +1,42 @@
|
|||
/*-*- 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. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/dce.h"
|
||||
#include "libc/intrin/asan.internal.h"
|
||||
#include "libc/intrin/describeflags.internal.h"
|
||||
#include "libc/intrin/kprintf.h"
|
||||
#include "libc/macros.internal.h"
|
||||
|
||||
void DescribeIov(const struct iovec *iov, int iovlen, ssize_t rem) {
|
||||
int i;
|
||||
if ((!IsAsan() && kisdangerous(iov)) ||
|
||||
(IsAsan() && !__asan_is_valid(iov, iovlen * sizeof(struct iovec)))) {
|
||||
kprintf("%p", iov);
|
||||
return;
|
||||
}
|
||||
kprintf("{");
|
||||
for (i = 0; rem && i < MIN(5, iovlen); ++i) {
|
||||
kprintf(
|
||||
"%s{%#.*hhs%s, %'zu}", i ? ", " : "",
|
||||
MAX(0, MIN(40, MIN(rem, iov[i].iov_len))), iov[i].iov_base,
|
||||
MAX(0, MIN(40, MIN(rem, iov[i].iov_len))) < iov[i].iov_len ? "..." : "",
|
||||
iov[i].iov_len);
|
||||
rem -= iov[i].iov_len;
|
||||
}
|
||||
kprintf("%s}", iovlen > 5 ? "..." : "");
|
||||
}
|
|
@ -25,6 +25,7 @@
|
|||
const char *DescribeMapFlags(int x) {
|
||||
_Alignas(char) static char mapflags[256];
|
||||
const struct DescribeFlags kMapFlags[] = {
|
||||
{MAP_STACK, "STACK"}, // order matters
|
||||
{MAP_ANONYMOUS, "ANONYMOUS"}, //
|
||||
{MAP_PRIVATE, "PRIVATE"}, //
|
||||
{MAP_SHARED, "SHARED"}, //
|
||||
|
@ -37,7 +38,6 @@ const char *DescribeMapFlags(int x) {
|
|||
{MAP_NORESERVE, "NORESERVE"}, //
|
||||
{MAP_NONBLOCK, "NONBLOCK"}, //
|
||||
{MAP_POPULATE, "POPULATE"}, //
|
||||
{MAP_STACK, "STACK"}, // order matters
|
||||
};
|
||||
return DescribeFlags(mapflags, sizeof(mapflags), kMapFlags,
|
||||
ARRAYLEN(kMapFlags), "MAP_", x);
|
||||
|
|
55
libc/intrin/describemapping.greg.c
Normal file
55
libc/intrin/describemapping.greg.c
Normal file
|
@ -0,0 +1,55 @@
|
|||
/*-*- 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/runtime/memtrack.internal.h"
|
||||
#include "libc/sysv/consts/map.h"
|
||||
#include "libc/sysv/consts/prot.h"
|
||||
|
||||
static noasan char DescribeMapType(int flags) {
|
||||
switch (flags & MAP_TYPE) {
|
||||
case MAP_FILE:
|
||||
return 'f';
|
||||
case MAP_PRIVATE:
|
||||
return 'p';
|
||||
case MAP_SHARED:
|
||||
return 's';
|
||||
case MAP_STACK:
|
||||
return 'S';
|
||||
default:
|
||||
return '?';
|
||||
}
|
||||
}
|
||||
|
||||
noasan char *DescribeProt(int prot, char p[hasatleast 4]) {
|
||||
p[0] = (prot & PROT_READ) ? 'r' : '-';
|
||||
p[1] = (prot & PROT_WRITE) ? 'w' : '-';
|
||||
p[2] = (prot & PROT_EXEC) ? 'x' : '-';
|
||||
p[3] = 0;
|
||||
return p;
|
||||
}
|
||||
|
||||
noasan char *DescribeMapping(int prot, int flags, char p[hasatleast 8]) {
|
||||
/* asan runtime depends on this function */
|
||||
DescribeProt(prot, p);
|
||||
p[3] = DescribeMapType(flags);
|
||||
p[4] = (flags & MAP_ANONYMOUS) ? 'a' : '-';
|
||||
p[5] = (flags & MAP_GROWSDOWN) ? 'G' : '-';
|
||||
p[6] = (flags & MAP_FIXED) ? 'F' : '-';
|
||||
p[7] = 0;
|
||||
return p;
|
||||
}
|
41
libc/intrin/describeopenflags.greg.c
Normal file
41
libc/intrin/describeopenflags.greg.c
Normal file
|
@ -0,0 +1,41 @@
|
|||
/*-*- 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. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/fmt/itoa.h"
|
||||
#include "libc/fmt/magnumstrs.internal.h"
|
||||
#include "libc/intrin/describeflags.internal.h"
|
||||
#include "libc/mem/alloca.h"
|
||||
#include "libc/sysv/consts/sol.h"
|
||||
|
||||
/**
|
||||
* Describes clock_gettime() clock argument.
|
||||
*/
|
||||
char *DescribeOpenFlags(int x) {
|
||||
char *s;
|
||||
int i, n;
|
||||
struct DescribeFlags *d;
|
||||
_Alignas(char) static char openflags[128];
|
||||
// TODO(jart): unify DescribeFlags and MagnumStr data structures
|
||||
for (n = 0; kOpenFlags[n].x != MAGNUM_TERMINATOR;) ++n;
|
||||
d = alloca(n * sizeof(struct DescribeFlags));
|
||||
for (i = 0; i < n; ++i) {
|
||||
d[i].flag = MAGNUM_NUMBER(kOpenFlags, i);
|
||||
d[i].name = MAGNUM_STRING(kOpenFlags, i);
|
||||
}
|
||||
return DescribeFlags(openflags, sizeof(openflags), d, n, "O_", x);
|
||||
}
|
35
libc/intrin/describerlimit.greg.c
Normal file
35
libc/intrin/describerlimit.greg.c
Normal file
|
@ -0,0 +1,35 @@
|
|||
/*-*- 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/calls/strace.internal.h"
|
||||
#include "libc/dce.h"
|
||||
#include "libc/intrin/asan.internal.h"
|
||||
#include "libc/intrin/kprintf.h"
|
||||
|
||||
const char *DescribeRlimit(char *buf, size_t bufsize, int rc,
|
||||
const struct rlimit *rlim) {
|
||||
if (rc == -1) return "n/a";
|
||||
if (!rlim) return "NULL";
|
||||
if ((!IsAsan() && kisdangerous(rlim)) ||
|
||||
(IsAsan() && !__asan_is_valid(rlim, sizeof(*rlim)))) {
|
||||
ksnprintf(buf, sizeof(buf), "%p", rlim);
|
||||
} else {
|
||||
ksnprintf(buf, bufsize, "{%'ld, %'ld}", rlim->rlim_cur, rlim->rlim_max);
|
||||
}
|
||||
return buf;
|
||||
}
|
47
libc/intrin/describerlimit_name.greg.c
Normal file
47
libc/intrin/describerlimit_name.greg.c
Normal 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/calls/strace.internal.h"
|
||||
#include "libc/fmt/itoa.h"
|
||||
#include "libc/sysv/consts/rlimit.h"
|
||||
|
||||
const char *DescribeRlimitName(int resource) {
|
||||
static char buf[12];
|
||||
if (resource == 127) return "n/a";
|
||||
if (resource == RLIMIT_AS) return "RLIMIT_AS";
|
||||
if (resource == RLIMIT_CPU) return "RLIMIT_CPU";
|
||||
if (resource == RLIMIT_FSIZE) return "RLIMIT_FSIZE";
|
||||
if (resource == RLIMIT_NPROC) return "RLIMIT_NPROC";
|
||||
if (resource == RLIMIT_NOFILE) return "RLIMIT_NOFILE";
|
||||
if (resource == RLIMIT_RSS) return "RLIMIT_RSS";
|
||||
if (resource == RLIMIT_DATA) return "RLIMIT_DATA";
|
||||
if (resource == RLIMIT_CORE) return "RLIMIT_CORE";
|
||||
if (resource == RLIMIT_STACK) return "RLIMIT_STACK";
|
||||
if (resource == RLIMIT_SIGPENDING) return "RLIMIT_SIGPENDING";
|
||||
if (resource == RLIMIT_MEMLOCK) return "RLIMIT_MEMLOCK";
|
||||
if (resource == RLIMIT_LOCKS) return "RLIMIT_LOCKS";
|
||||
if (resource == RLIMIT_MSGQUEUE) return "RLIMIT_MSGQUEUE";
|
||||
if (resource == RLIMIT_NICE) return "RLIMIT_NICE";
|
||||
if (resource == RLIMIT_RTPRIO) return "RLIMIT_RTPRIO";
|
||||
if (resource == RLIMIT_RTTIME) return "RLIMIT_RTTIME";
|
||||
if (resource == RLIMIT_SWAP) return "RLIMIT_SWAP";
|
||||
if (resource == RLIMIT_SBSIZE) return "RLIMIT_SBSIZE";
|
||||
if (resource == RLIMIT_NPTS) return "RLIMIT_NPTS";
|
||||
FormatInt32(buf, resource);
|
||||
return buf;
|
||||
}
|
85
libc/intrin/describestat.greg.c
Normal file
85
libc/intrin/describestat.greg.c
Normal file
|
@ -0,0 +1,85 @@
|
|||
/*-*- 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/dce.h"
|
||||
#include "libc/intrin/asan.internal.h"
|
||||
#include "libc/intrin/describeflags.internal.h"
|
||||
#include "libc/intrin/kprintf.h"
|
||||
|
||||
const char *DescribeStat(int rc, const struct stat *st) {
|
||||
_Alignas(char) static char buf[300];
|
||||
int i, n;
|
||||
|
||||
if (rc == -1) return "n/a";
|
||||
if (!st) return "NULL";
|
||||
if ((!IsAsan() && kisdangerous(st)) ||
|
||||
(IsAsan() && !__asan_is_valid(st, sizeof(*st)))) {
|
||||
ksnprintf(buf, sizeof(buf), "%p", st);
|
||||
return buf;
|
||||
}
|
||||
|
||||
i = 0;
|
||||
n = sizeof(buf);
|
||||
|
||||
i += ksnprintf(buf + i, n - i, "{.st_%s=%'ld", "size", st->st_size);
|
||||
|
||||
if (st->st_blocks) {
|
||||
i +=
|
||||
ksnprintf(buf + i, n - i, ", .st_blocks=%'lu/512", st->st_blocks * 512);
|
||||
}
|
||||
|
||||
if (st->st_mode) {
|
||||
i += ksnprintf(buf + i, n - i, ", .st_%s=%#o", "mode", st->st_mode);
|
||||
}
|
||||
|
||||
if (st->st_nlink != 1) {
|
||||
i += ksnprintf(buf + i, n - i, ", .st_%s=%'lu", "nlink", st->st_nlink);
|
||||
}
|
||||
|
||||
if (st->st_uid) {
|
||||
i += ksnprintf(buf + i, n - i, ", .st_%s=%lu", "uid", st->st_uid);
|
||||
}
|
||||
|
||||
if (st->st_gid) {
|
||||
i += ksnprintf(buf + i, n - i, ", .st_%s=%lu", "gid", st->st_gid);
|
||||
}
|
||||
|
||||
if (st->st_ino) {
|
||||
i += ksnprintf(buf + i, n - i, ", .st_%s=%lu", "ino", st->st_ino);
|
||||
}
|
||||
|
||||
if (st->st_gen) {
|
||||
i += ksnprintf(buf + i, n - i, ", .st_%s=%'lu", "gen", st->st_gen);
|
||||
}
|
||||
|
||||
if (st->st_flags) {
|
||||
i += ksnprintf(buf + i, n - i, ", .st_%s=%lx", "flags", st->st_flags);
|
||||
}
|
||||
|
||||
if (st->st_rdev) {
|
||||
i += ksnprintf(buf + i, n - i, ", .st_%s=%'lu", "rdev", st->st_rdev);
|
||||
}
|
||||
|
||||
if (st->st_blksize != PAGESIZE) {
|
||||
i += ksnprintf(buf + i, n - i, ", .st_%s=%'lu", "blksize", st->st_blksize);
|
||||
}
|
||||
|
||||
buf[i++] = '}';
|
||||
|
||||
return buf;
|
||||
}
|
35
libc/intrin/describetimespec.greg.c
Normal file
35
libc/intrin/describetimespec.greg.c
Normal file
|
@ -0,0 +1,35 @@
|
|||
/*-*- 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/dce.h"
|
||||
#include "libc/intrin/asan.internal.h"
|
||||
#include "libc/intrin/describeflags.internal.h"
|
||||
#include "libc/intrin/kprintf.h"
|
||||
|
||||
const char *DescribeTimespec(char *buf, size_t bufsize, int rc,
|
||||
const struct timespec *ts) {
|
||||
if (rc == -1) return "n/a";
|
||||
if (!ts) return "NULL";
|
||||
if ((!IsAsan() && kisdangerous(ts)) ||
|
||||
(IsAsan() && !__asan_is_valid(ts, sizeof(*ts)))) {
|
||||
ksnprintf(buf, bufsize, "%p", ts);
|
||||
} else {
|
||||
ksnprintf(buf, bufsize, "{%ld, %ld}", ts->tv_sec, ts->tv_nsec);
|
||||
}
|
||||
return buf;
|
||||
}
|
55
libc/intrin/formatint32.c
Normal file
55
libc/intrin/formatint32.c
Normal file
|
@ -0,0 +1,55 @@
|
|||
/*-*- 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 string.
|
||||
*
|
||||
* @param p needs at least 12 bytes
|
||||
* @return pointer to nul byte
|
||||
*/
|
||||
dontinline char *FormatUint32(char p[hasatleast 12], uint32_t x) {
|
||||
char t;
|
||||
size_t i, a, b;
|
||||
i = 0;
|
||||
do {
|
||||
p[i++] = x % 10 + '0';
|
||||
x = x / 10;
|
||||
} while (x > 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;
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts signed 32-bit integer to string.
|
||||
*
|
||||
* @param p needs at least 12 bytes
|
||||
* @return pointer to nul byte
|
||||
*/
|
||||
char *FormatInt32(char p[hasatleast 12], int32_t x) {
|
||||
if (x < 0) *p++ = '-', x = -(uint32_t)x;
|
||||
return FormatUint32(p, x);
|
||||
}
|
55
libc/intrin/formatint64.c
Normal file
55
libc/intrin/formatint64.c
Normal file
|
@ -0,0 +1,55 @@
|
|||
/*-*- 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 64-bit integer to string.
|
||||
*
|
||||
* @param p needs at least 21 bytes
|
||||
* @return pointer to nul byte
|
||||
*/
|
||||
dontinline char *FormatUint64(char p[static 21], uint64_t x) {
|
||||
char t;
|
||||
size_t i, a, b;
|
||||
i = 0;
|
||||
do {
|
||||
p[i++] = x % 10 + '0';
|
||||
x = x / 10;
|
||||
} while (x > 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;
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts signed 64-bit integer to string.
|
||||
*
|
||||
* @param p needs at least 21 bytes
|
||||
* @return pointer to nul byte
|
||||
*/
|
||||
char *FormatInt64(char p[static 21], int64_t x) {
|
||||
if (x < 0) *p++ = '-', x = -(uint64_t)x;
|
||||
return FormatUint64(p, x);
|
||||
}
|
|
@ -68,17 +68,22 @@ o/$(MODE)/libc/intrin/tls.greg.o \
|
|||
o/$(MODE)/libc/intrin/exit.greg.o \
|
||||
o/$(MODE)/libc/intrin/exit1.greg.o \
|
||||
o/$(MODE)/libc/intrin/gettid.greg.o \
|
||||
o/$(MODE)/libc/intrin/getenv.greg.o \
|
||||
o/$(MODE)/libc/intrin/createfile.greg.o \
|
||||
o/$(MODE)/libc/intrin/assertfail.greg.o \
|
||||
o/$(MODE)/libc/intrin/reopenfile.greg.o \
|
||||
o/$(MODE)/libc/intrin/deletefile.greg.o \
|
||||
o/$(MODE)/libc/intrin/createpipe.greg.o \
|
||||
o/$(MODE)/libc/intrin/closehandle.greg.o \
|
||||
o/$(MODE)/libc/intrin/describeiov.greg.o \
|
||||
o/$(MODE)/libc/intrin/openprocess.greg.o \
|
||||
o/$(MODE)/libc/intrin/createthread.greg.o \
|
||||
o/$(MODE)/libc/intrin/describestat.greg.o \
|
||||
o/$(MODE)/libc/intrin/findnextfile.greg.o \
|
||||
o/$(MODE)/libc/intrin/createprocess.greg.o \
|
||||
o/$(MODE)/libc/intrin/findfirstfile.greg.o \
|
||||
o/$(MODE)/libc/intrin/describeflags.greg.o \
|
||||
o/$(MODE)/libc/intrin/describerlimit.greg.o \
|
||||
o/$(MODE)/libc/intrin/removedirectory.greg.o \
|
||||
o/$(MODE)/libc/intrin/createnamedpipe.greg.o \
|
||||
o/$(MODE)/libc/intrin/unmapviewoffile.greg.o \
|
||||
|
@ -88,6 +93,7 @@ o/$(MODE)/libc/intrin/createdirectory.greg.o \
|
|||
o/$(MODE)/libc/intrin/flushfilebuffers.greg.o \
|
||||
o/$(MODE)/libc/intrin/terminateprocess.greg.o \
|
||||
o/$(MODE)/libc/intrin/describemapflags.greg.o \
|
||||
o/$(MODE)/libc/intrin/describetimespec.greg.o \
|
||||
o/$(MODE)/libc/intrin/getfileattributes.greg.o \
|
||||
o/$(MODE)/libc/intrin/getexitcodeprocess.greg.o \
|
||||
o/$(MODE)/libc/intrin/waitforsingleobject.greg.o \
|
||||
|
@ -104,6 +110,10 @@ o/$(MODE)/libc/intrin/ntconsolemode.o: \
|
|||
-ffreestanding \
|
||||
$(NO_MAGIC)
|
||||
|
||||
o/$(MODE)/libc/intrin/describeopenflags.greg.o: \
|
||||
OVERRIDE_CPPFLAGS += \
|
||||
-DSTACK_FRAME_UNLIMITED
|
||||
|
||||
o/$(MODE)/libc/intrin/asan.o \
|
||||
o/$(MODE)/libc/intrin/ubsan.o: \
|
||||
OVERRIDE_CFLAGS += \
|
||||
|
|
65
libc/intrin/kopenflags.S
Normal file
65
libc/intrin/kopenflags.S
Normal file
|
@ -0,0 +1,65 @@
|
|||
/*-*- mode:unix-assembly; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│
|
||||
│vi: set et ft=asm ts=8 tw=8 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/magnumstrs.internal.h"
|
||||
#include "libc/macros.internal.h"
|
||||
|
||||
.macro .e e s
|
||||
.long \e - kOpenFlags
|
||||
.long 1f - kOpenFlags
|
||||
.rodata.str1.1
|
||||
1: .string "\s"
|
||||
.previous
|
||||
.endm
|
||||
|
||||
.section .rodata
|
||||
.align 4
|
||||
.underrun
|
||||
kOpenFlags:
|
||||
.e O_RDWR,"RDWR" // order matters
|
||||
.e O_RDONLY,"RDONLY" //
|
||||
.e O_WRONLY,"WRONLY" //
|
||||
.e O_ACCMODE,"ACCMODE" // mask of prev three
|
||||
.e O_CREAT,"CREAT" //
|
||||
.e O_EXCL,"EXCL" //
|
||||
.e O_TRUNC,"TRUNC" //
|
||||
.e O_CLOEXEC,"CLOEXEC" //
|
||||
.e O_NONBLOCK,"NONBLOCK" //
|
||||
.e O_DIRECT,"DIRECT" // no-op on xnu/openbsd
|
||||
.e O_APPEND,"APPEND" // weird on nt
|
||||
.e O_TMPFILE,"TMPFILE" // linux, windows
|
||||
.e O_NOFOLLOW,"NOFOLLOW" // unix
|
||||
.e O_SYNC,"SYNC" // unix
|
||||
.e O_ASYNC,"ASYNC" // unix
|
||||
.e O_NOCTTY,"NOCTTY" // unix
|
||||
.e O_NOATIME,"NOATIME" // linux
|
||||
.e O_EXEC,"EXEC" // free/openbsd
|
||||
.e O_SEARCH,"SEARCH" // free/netbsd
|
||||
.e O_DSYNC,"DSYNC" // linux/xnu/open/netbsd
|
||||
.e O_RSYNC,"RSYNC" // linux/open/netbsd
|
||||
.e O_PATH,"PATH" // linux
|
||||
.e O_VERIFY,"VERIFY" // freebsd
|
||||
.e O_SHLOCK,"SHLOCK" // bsd
|
||||
.e O_EXLOCK,"EXLOCK" // bsd
|
||||
.e O_RANDOM,"RANDOM" // windows
|
||||
.e O_SEQUENTIAL,"SEQUENTIAL" // windows
|
||||
.e O_COMPRESSED,"COMPRESSED" // windows
|
||||
.e O_INDEXED,"INDEXED" // windows
|
||||
.long MAGNUM_TERMINATOR
|
||||
.endobj kOpenFlags,globl,hidden
|
||||
.overrun
|
|
@ -520,10 +520,13 @@ privileged static size_t kformat(char *b, size_t n, const char *fmt, va_list va,
|
|||
type = 0;
|
||||
goto FormatString;
|
||||
} else {
|
||||
if (p + 4 <= e) {
|
||||
if (p + 7 <= e) {
|
||||
*p++ = ' ';
|
||||
*p++ = 'e';
|
||||
*p++ = 'r';
|
||||
*p++ = 'r';
|
||||
*p++ = 'n';
|
||||
*p++ = 'o';
|
||||
*p++ = '=';
|
||||
}
|
||||
type = 0;
|
||||
|
@ -568,7 +571,7 @@ privileged static size_t kformat(char *b, size_t n, const char *fmt, va_list va,
|
|||
if (!__replstderr || __nocolor) {
|
||||
break;
|
||||
} else {
|
||||
s = "\r\033[K";
|
||||
s = "\r\e[K";
|
||||
goto FormatString;
|
||||
}
|
||||
|
||||
|
|
32
libc/intrin/popcnt.c
Normal file
32
libc/intrin/popcnt.c
Normal file
|
@ -0,0 +1,32 @@
|
|||
/*-*- 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 2020 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/bits/popcnt.h"
|
||||
|
||||
/**
|
||||
* Returns number of bits set in integer.
|
||||
*/
|
||||
uint64_t(popcnt)(uint64_t x) {
|
||||
x = x - ((x >> 1) & 0x5555555555555555);
|
||||
x = ((x >> 2) & 0x3333333333333333) + (x & 0x3333333333333333);
|
||||
x = (x + (x >> 4)) & 0x0f0f0f0f0f0f0f0f;
|
||||
x = (x + (x >> 32)) & 0xffffffff;
|
||||
x = x + (x >> 16);
|
||||
x = (x + (x >> 8)) & 0x0000007f;
|
||||
return x;
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue