Fix some issues and do some code cleanup

This commit is contained in:
Justine Tunney 2022-05-23 10:15:53 -07:00
parent 1f229e4efc
commit 312ed5c67c
72 changed files with 880 additions and 982 deletions

View file

@ -199,7 +199,7 @@ static char *__asan_utf8cpy(char *p, unsigned c) {
return p;
}
static void *__asan_memset(void *p, char c, size_t n) {
static void __asan_memset(void *p, char c, size_t n) {
char *b;
size_t i;
uint64_t x;
@ -207,29 +207,29 @@ static void *__asan_memset(void *p, char c, size_t n) {
x = 0x0101010101010101ul * (c & 255);
switch (n) {
case 0:
return p;
break;
case 1:
__builtin_memcpy(b, &x, 1);
return p;
break;
case 2:
__builtin_memcpy(b, &x, 2);
return p;
break;
case 3:
__builtin_memcpy(b, &x, 2);
__builtin_memcpy(b + 1, &x, 2);
return p;
break;
case 4:
__builtin_memcpy(b, &x, 4);
return p;
break;
case 5:
case 6:
case 7:
__builtin_memcpy(b, &x, 4);
__builtin_memcpy(b + n - 4, &x, 4);
return p;
break;
case 8:
__builtin_memcpy(b, &x, 8);
return p;
break;
case 9:
case 10:
case 11:
@ -240,7 +240,7 @@ static void *__asan_memset(void *p, char c, size_t n) {
case 16:
__builtin_memcpy(b, &x, 8);
__builtin_memcpy(b + n - 8, &x, 8);
return p;
break;
default:
if (n <= 64) {
i = 0;
@ -253,83 +253,10 @@ static void *__asan_memset(void *p, char c, size_t n) {
} else {
__repstosb(p, c, n);
}
return p;
break;
}
}
static void *__asan_mempcpy(void *dst, const void *src, size_t n) {
size_t i;
char *d;
const char *s;
uint64_t a, b;
d = dst;
s = src;
switch (n) {
case 0:
return d;
case 1:
*d = *s;
return d + 1;
case 2:
__builtin_memcpy(&a, s, 2);
__builtin_memcpy(d, &a, 2);
return d + 2;
case 3:
__builtin_memcpy(&a, s, 2);
__builtin_memcpy(&b, s + 1, 2);
__builtin_memcpy(d, &a, 2);
__builtin_memcpy(d + 1, &b, 2);
return d + 3;
case 4:
__builtin_memcpy(&a, s, 4);
__builtin_memcpy(d, &a, 4);
return d + 4;
case 5:
case 6:
case 7:
__builtin_memcpy(&a, s, 4);
__builtin_memcpy(&b, s + n - 4, 4);
__builtin_memcpy(d, &a, 4);
__builtin_memcpy(d + n - 4, &b, 4);
return d + n;
case 8:
__builtin_memcpy(&a, s, 8);
__builtin_memcpy(d, &a, 8);
return d + 8;
case 9:
case 10:
case 11:
case 12:
case 13:
case 14:
case 15:
case 16:
__builtin_memcpy(&a, s, 8);
__builtin_memcpy(&b, s + n - 8, 8);
__builtin_memcpy(d, &a, 8);
__builtin_memcpy(d + n - 8, &b, 8);
return d + n;
default:
if (n <= 64) {
i = 0;
do {
__builtin_memcpy(&a, s + i, 8);
asm volatile("" ::: "memory");
__builtin_memcpy(d + i, &a, 8);
} while ((i += 8) + 8 <= n);
for (; i < n; ++i) d[i] = s[i];
return d + i;
} else {
return __repmovsb(d, s, n);
}
}
}
static void *__asan_memcpy(void *dst, const void *src, size_t n) {
__asan_mempcpy(dst, src, n);
return dst;
}
static char *__asan_hexcpy(char *p, uint64_t x, uint8_t k) {
while (k) *p++ = "0123456789abcdef"[(x >> (k -= 4)) & 15];
return p;
@ -736,7 +663,7 @@ static void __asan_report_memory_origin(const unsigned char *addr, int size,
if (_base <= addr && addr < _end) {
__asan_report_memory_origin_image((intptr_t)addr, size);
} else if (IsAutoFrame((intptr_t)addr >> 16)) {
/* __asan_report_memory_origin_heap(addr, size); */
__asan_report_memory_origin_heap(addr, size);
}
}
@ -946,8 +873,8 @@ static void __asan_trace(struct AsanTrace *bt, const struct StackFrame *bp) {
#define __asan_trace __asan_rawtrace
static void *__asan_allocate(size_t a, size_t n, int underrun, int overrun,
struct AsanTrace *bt) {
void *__asan_allocate(size_t a, size_t n, int underrun, int overrun,
struct AsanTrace *bt) {
char *p;
size_t c;
struct AsanExtra *e;
@ -960,7 +887,7 @@ static void *__asan_allocate(size_t a, size_t n, int underrun, int overrun,
__asan_poison(p + n, c - n, overrun);
__asan_memset(p, 0xF9, n);
__asan_write48(&e->size, n);
__asan_memcpy(&e->bt, bt, sizeof(*bt));
__builtin_memcpy(&e->bt, bt, sizeof(*bt));
}
return p;
}
@ -1082,7 +1009,7 @@ static void *__asan_realloc_grow(void *p, size_t n, size_t m,
struct AsanTrace *bt) {
char *q;
if ((q = __asan_allocate(16, n, kAsanHeapUnderrun, kAsanHeapOverrun, bt))) {
__asan_memcpy(q, p, m);
__builtin_memcpy(q, p, m);
__asan_deallocate(p, kAsanHeapRelocated);
}
return q;

View file

@ -46,7 +46,6 @@ relegated wontreturn void __assert_fail(const char *expr, const char *file,
} else {
rc = 24;
}
if (weaken(__die)) weaken(__die)();
__restorewintty();
_Exit(rc);
}

View file

@ -23,6 +23,7 @@ const char *DescribeMapFlags(int);
const char *DescribeProtFlags(int);
const char *DescribeRemapFlags(int);
const char *DescribeRlimitName(int);
const char *DescribePersonalityFlags(int);
const char *DescribeSeccompOperationFlags(int);
const char *DescribePollFlags(char *, size_t, int);
const char *DescribeStat(int, const struct stat *);

View file

@ -0,0 +1,43 @@
/*-*- 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/intrin/describeflags.internal.h"
#include "libc/macros.internal.h"
#include "libc/nt/enum/accessmask.h"
#include "libc/nt/enum/filesharemode.h"
#include "libc/sysv/consts/personality.h"
static const struct DescribeFlags kPersonalityFlags[] = {
{ADDR_COMPAT_LAYOUT, "ADDR_COMPAT_LAYOUT"}, //
{READ_IMPLIES_EXEC, "READ_IMPLIES_EXEC"}, //
{ADDR_LIMIT_3GB, "ADDR_LIMIT_3GB"}, //
{FDPIC_FUNCPTRS, "FDPIC_FUNCPTRS"}, //
{STICKY_TIMEOUTS, "STICKY_TIMEOUTS"}, //
{MMAP_PAGE_ZERO, "MMAP_PAGE_ZERO"}, //
{ADDR_LIMIT_32BIT, "ADDR_LIMIT_32BIT"}, //
{WHOLE_SECONDS, "WHOLE_SECONDS"}, //
{ADDR_NO_RANDOMIZE, "ADDR_NO_RANDOMIZE"}, //
{SHORT_INODE, "SHORT_INODE"}, //
{UNAME26, "UNAME26"}, //
};
const char *DescribePersonalityFlags(int x) {
_Alignas(char) static char personalityflags[128];
return DescribeFlags(personalityflags, sizeof(personalityflags),
kPersonalityFlags, ARRAYLEN(kPersonalityFlags), "", x);
}

View file

@ -22,7 +22,17 @@
/**
* Returns process id.
*
* This function does not need to issue a system call. The PID is
* tracked by a global variable which is updated atfork(). The only
* exception is when the process is vfork()'d in which case a system
* call shall be issued.
*
* On Linux, and only Linux, the process id is guaranteed to be the same
* as gettid() for the main thread.
*
* @asyncsignalsafe
* @threadsafe
* @vforksafe
*/
int getpid(void) {

View file

@ -32,8 +32,25 @@ __msabi extern typeof(GetCurrentThreadId) *const __imp_GetCurrentThreadId;
* if this is the main thread. On NetBSD, gettid() for the main thread
* is always 1.
*
* This function issues a system call. That stops being the case as soon
* as __install_tls() is called. That'll happen automatically, when you
* call clone() and provide the TLS parameter. We assume that when a TLS
* block exists, then
*
* *(int *)(__get_tls() + 0x38)
*
* will contain the thread id. Therefore when issuing clone() calls, the
* `CLONE_CHILD_SETTID` and `CLONE_CHILD_CLEARTID` flags should use that
* index as its `ctid` memory.
*
* gettid (single threaded) l: 126𝑐 41𝑛𝑠
* gettid (tls enabled) l: 2𝑐 1𝑛𝑠
*
* The TLS convention is important for reentrant lock performance.
*
* @return thread id greater than zero or -1 w/ errno
* @asyncsignalsafe
* @threadsafe
*/
privileged int gettid(void) {
int rc;
@ -42,9 +59,7 @@ privileged int gettid(void) {
if (__tls_enabled) {
rc = *(int *)(__get_tls() + 0x38);
if (rc && rc != -1) {
return rc;
}
return rc;
}
if (IsWindows()) {

View file

@ -46,9 +46,14 @@ $(LIBC_INTRIN_A_OBJS): \
OVERRIDE_CFLAGS += \
-foptimize-sibling-calls
# we can't use asan and ubsan because:
# this is asan and ubsan
# we need -ffreestanding because:
# we don't want __builtin_memcpy() calling memcpy()
o/$(MODE)/libc/intrin/asan.o \
o/$(MODE)/libc/intrin/ubsan.o: \
OVERRIDE_CFLAGS += \
-ffreestanding \
-fno-sanitize=all \
-fno-stack-protector
@ -145,12 +150,6 @@ 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 += \
-fno-sanitize=all \
-fno-stack-protector
o//libc/intrin/memmove.o: \
OVERRIDE_CFLAGS += \
-fno-toplevel-reorder

View file

@ -857,7 +857,6 @@ privileged void kvprintf(const char *fmt, va_list v) {
*
* Specifiers:
*
* - `P` pid
* - `c` char
* - `o` octal
* - `b` binary
@ -873,6 +872,7 @@ privileged void kvprintf(const char *fmt, va_list v) {
* - `X` uppercase
* - `T` timestamp
* - `x` hexadecimal
* - `P` pid (or tid if threaded)
*
* Types:
*

View file

@ -22,9 +22,9 @@
/**
* Returns New Technology version, e.g.
*
* if (IsWindows() && NtGetVersion() >=k NtVersionWindows10) {...}
*
* This can only be called on Windows.
*
* @see IsAtLeastWindows10()
*/
textwindows noasan int NtGetVersion(void) {
return (NtGetPeb()->OSMajorVersion & 0xff) << 8 | NtGetPeb()->OSMinorVersion;

View file

@ -25,16 +25,8 @@
//
// @return 0 on success, or -1 w/ errno
sched_yield:
push %rbp
mov %rsp,%rbp
testb IsWindows()
jnz 1f
// UNIX Support
mov __NR_sched_yield,%eax
syscall
jmp 2f
#if SupportsWindows()
// Windows Support
//
// A value of zero, together with the bAlertable parameter set to
@ -44,12 +36,34 @@ sched_yield:
// threads ready to run and no user APCs are queued, the function
// returns immediately, and the thread continues execution.
// Quoth MSDN
1: xor %ecx,%ecx
testb IsWindows()
jz 1f
push %rbp
mov %rsp,%rbp
xor %ecx,%ecx
xor %edx,%edx
ntcall __imp_SleepEx
xor %eax,%eax
2: pop %rbp
pop %rbp
ret
#endif
#if SupportsSystemv()
// UNIX Support
1: mov __NR_sched_yield,%eax
#if SupportsBsd() && SupportsLinux()
clc
#endif
syscall
#if SupportsBsd()
jc systemfive_errno
#endif
#if SupportsLinux()
cmp $-4095,%rax
jae systemfive_error
#endif
#endif
2: ret
.endfn sched_yield,globl
.previous

View file

@ -44,23 +44,28 @@
* 0x003c 0x04 errno
*
*/
privileged void *__initialize_tls(char tib[hasatleast 64]) {
*(intptr_t *)tib = (intptr_t)tib;
*(intptr_t *)(tib + 0x08) = 0;
*(int *)(tib + 0x10) = -1; // exit code
*(intptr_t *)(tib + 0x30) = (intptr_t)tib;
*(int *)(tib + 0x38) = -1; // tid
*(int *)(tib + 0x3c) = __errno;
privileged void *__initialize_tls(char tib[64]) {
if (tib) {
*(intptr_t *)tib = (intptr_t)tib;
*(intptr_t *)(tib + 0x08) = 0;
*(int *)(tib + 0x10) = -1; // exit code
*(intptr_t *)(tib + 0x30) = (intptr_t)tib;
*(int *)(tib + 0x38) = -1; // tid
*(int *)(tib + 0x3c) = 0;
}
return tib;
}
/**
* Installs thread information block on main process.
*/
privileged void __install_tls(char tib[hasatleast 64]) {
privileged void __install_tls(char tib[64]) {
int ax, dx;
uint64_t magic;
unsigned char *p;
assert(tib);
assert(!__tls_enabled);
assert(*(int *)(tib + 0x38) != -1);
if (IsWindows()) {
if (!__tls_index) {
__tls_index = TlsAlloc();