Make improvements

- Let OpenMP be usable via cosmocc
- Let libunwind be usable via cosmocc
- Make X86_HAVE(AVXVNNI) work correctly
- Avoid using MAP_GROWSDOWN on qemu-aarch64
- Introduce in6addr_any and in6addr_loopback
- Have thread stacks use MAP_GROWSDOWN by default
- Ask OpenMP to not use filesystem to manage threads
- Make NI_MAXHOST and NI_MAXSERV available w/o _GNU_SOURCE
This commit is contained in:
Justine Tunney 2024-01-29 15:45:10 -08:00
parent 5f8e9f14c1
commit 369aebfc48
No known key found for this signature in database
GPG key ID: BE714B4575D6E328
36 changed files with 416 additions and 80 deletions

View file

@ -251,6 +251,7 @@ libc/isystem/uio.h \
libc/isystem/unistd.h \
libc/isystem/unordered_map \
libc/isystem/unordered_set \
libc/isystem/unwind.h \
libc/isystem/utility \
libc/isystem/utime.h \
libc/isystem/utmp.h \

View file

@ -24,11 +24,15 @@
/**
* Returns true if process is running under qemu-x86_64 or qemu-aarch64.
*/
int IsQemu(void) {
// qemu doesn't validate the advice argument
// we could also check if __getcwd(0, 0) raises efault
int e = errno;
int r = !sys_madvise(__executable_start, 16384, 127);
errno = e;
return r;
int IsQemuUser(void) {
static char rplus1;
if (!rplus1) {
// qemu doesn't validate the advice argument
// we could also check if __getcwd(0, 0) raises efault
int e = errno;
int r = !sys_madvise(__executable_start, 16384, 127);
errno = e;
rplus1 = r + 1;
}
return rplus1 - 1;
}

View file

@ -121,7 +121,7 @@ COSMOPOLITAN_C_START_
extern const int __hostos;
int IsQemu(void);
int IsQemuUser(void);
COSMOPOLITAN_C_END_
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */

View file

@ -649,8 +649,9 @@ void abort(void) wontreturn;
#pragma GCC diagnostic ignored "-Wformat-extra-args" /* todo: patch gcc */
#pragma GCC diagnostic ignored "-Wunused-function" /* contradicts dce */
#pragma GCC diagnostic ignored "-Wunused-const-variable" /* sooo ridiculous */
#pragma GCC diagnostic ignored "-Wbuiltin-declaration-mismatch"
#ifndef __cplusplus
#pragma GCC diagnostic ignored "-Wold-style-definition" /* orwellian bulls */
#pragma GCC diagnostic ignored "-Wold-style-definition" /* orwellian bullsh */
#endif
#ifndef __STRICT_ANSI__

View file

@ -103,7 +103,7 @@ void __get_main_stack(void **out_addr, size_t *out_size, int *out_guardsize) {
if (IsWindows()) {
*out_addr = (void *)GetStaticStackAddr(0);
*out_size = GetStaticStackSize();
*out_guardsize = GetGuardSize();
*out_guardsize = getauxval(AT_PAGESZ);
return;
}
int pagesz = getauxval(AT_PAGESZ);

4
libc/isystem/unwind.h Normal file
View file

@ -0,0 +1,4 @@
#ifndef _UNWIND_H
#define _UNWIND_H
#include "third_party/libunwind/include/unwind.h"
#endif /* _UNWIND_H */

View file

@ -31,28 +31,38 @@
// are quite toilsome.
//
// @see www.felixcloutier.com/x86/cpuid
kCpuids:.long 0,0,0,0 # EAX=0 (Basic Processor Info)
.long 0,0,0,0 # EAX=1 (Processor Info)
.long 0,0,0,0 # EAX=2
.long 0,0,0,0 # EAX=7 (Extended Features)
.long 0,0,0,0 # EAX=0x80000001 (NexGen32e)
.long 0,0,0,0 # EAX=0x80000007 (APM)
.long 0,0,0,0 # EAX=16h (CPU Frequency)
kCpuids:.long 0,0,0,0 // EAX=0 (Basic Processor Info)
.long 0,0,0,0 // EAX=1 (Processor Info)
.long 0,0,0,0 // EAX=2
.long 0,0,0,0 // EAX=7 (Extended Features)
.long 0,0,0,0 // EAX=0x80000001 (NexGen32e)
.long 0,0,0,0 // EAX=0x80000007 (APM)
.long 0,0,0,0 // EAX=16h (CPU Frequency)
.long 0,0,0,0 // EAX=7 ECX=1 (Extended Feats)
.endobj kCpuids,globl
.previous
.init.start 201,_init_kCpuids
push %rbx
push $0
push $0x16
push $0xffffffff80000007
push $0xffffffff80000001
push $1
push $7
push $0
push $0x16
push $0
push $0xffffffff80000007
push $0
push $0xffffffff80000001
push $0
push $7
push $0
push $2
push $0
push $1
mov %rdi,%r8
xor %eax,%eax
1: xor %ecx,%ecx
xor %ecx,%ecx
1: nop
#ifdef FEATURELESS
// It's been reported that GDB reverse debugging doesn't
// understand VEX encoding. The workaround is to put:
@ -62,6 +72,7 @@ kCpuids:.long 0,0,0,0 # EAX=0 (Basic Processor Info)
// Inside your ~/.cosmo.mk file.
xor %eax,%eax
xor %ebx,%ebx
xor %ecx,%ecx
xor %edx,%edx
#else
cpuid
@ -74,10 +85,11 @@ kCpuids:.long 0,0,0,0 # EAX=0 (Basic Processor Info)
xchg %eax,%edx
stosl
2: pop %rax
test %eax,%eax # EAX = stacklist->pop()
jz 3f # EAX 0 (EOL sentinel)
cmp KCPUIDS(0H,EAX)(%r8),%al # EAX CPUID.0 max leaf
jbe 1b # CPUID too new to probe
test %eax,%eax // EAX = stacklist->pop()
jz 3f // EAX 0 (EOL sentinel)
pop %rcx // HERE WE GO AGAIN CPUID
cmp KCPUIDS(0H,EAX)(%r8),%al // EAX CPUID.0 max leaf
jbe 1b // CPUID too new to probe
add $4*4,%rdi
jmp 2b
3: nop

View file

@ -8,7 +8,8 @@
#define KCPUIDS_80000001H 4
#define KCPUIDS_80000007H 5
#define KCPUIDS_16H 6
#define KCPUIDS_LEN 7
#define KCPUIDS_7H_1H 7
#define KCPUIDS_LEN 8
#define KCPUIDS_6H -1 /* TBD: Thermal and Power Management */
#define KCPUIDS_DH -1 /* TBD: Extended state features */
#define KCPUIDS_80000008H -1 /* TBD: AMD Miscellaneous */

View file

@ -37,6 +37,18 @@
#define _X86_CC_AVXVNNI 0
#endif
#ifdef __AVXVNNIINT8__
#define _X86_CC_AVXVNNIINT8 1
#else
#define _X86_CC_AVXVNNIINT8 0
#endif
#ifdef __AVXVNNIINT16__
#define _X86_CC_AVXVNNIINT16 1
#else
#define _X86_CC_AVXVNNIINT16 0
#endif
#ifdef __AVX512F__
#define _X86_CC_AVX512F 1
#else

View file

@ -28,7 +28,9 @@
#define X86_ARCH_CAPABILITIES 7H, EDX, 29, 0
#define X86_AVX 1H, ECX, 28, _X86_CC_AVX /* sandybridge c. 2012 */
#define X86_AVX2 7H, EBX, 5, _X86_CC_AVX2 /* haswell c. 2013 */
#define X86_AVXVNNI 7H, EAX, 4, _X86_CC_AVXVNNI
#define X86_AVXVNNI 7H_1H, EAX, 4, _X86_CC_AVXVNNI
#define X86_AVXVNNIINT8 7H_1H, EDX, 4, _X86_CC_AVXVNNIINT8
#define X86_AVXVNNIINT16 7H_1H, EDX, 10, _X86_CC_AVXVNNIINT16
#define X86_AVX512BW 7H, EBX, 30, 0
#define X86_AVX512CD 7H, EBX, 28, 0
#define X86_AVX512DQ 7H, EBX, 17, 0

View file

@ -23,6 +23,7 @@
#include "libc/runtime/memtrack.internal.h"
#include "libc/runtime/runtime.h"
#include "libc/runtime/stack.h"
#include "libc/sysv/consts/auxv.h"
#include "libc/sysv/consts/map.h"
#include "libc/sysv/consts/prot.h"
@ -42,10 +43,13 @@
void *NewCosmoStack(void) {
char *p;
if ((p = mmap(0, GetStackSize(), PROT_READ | PROT_WRITE,
MAP_STACK | MAP_ANONYMOUS, -1, 0)) != MAP_FAILED) {
MAP_ANONYMOUS |
(IsAarch64() && IsLinux() && IsQemuUser() ? MAP_PRIVATE
: MAP_STACK),
-1, 0)) != MAP_FAILED) {
if (IsAsan()) {
__asan_poison(p + GetStackSize() - 16, 16, kAsanStackOverflow);
__asan_poison(p, GetGuardSize(), kAsanStackOverflow);
__asan_poison(p, getauxval(AT_PAGESZ), kAsanStackOverflow);
}
return p;
} else {

22
libc/sock/in6addr_any.c Normal file
View file

@ -0,0 +1,22 @@
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
vi: set et ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi
Copyright 2024 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/sock/struct/sockaddr6.h"
#include "libc/sysv/consts/inaddr.h"
const struct in6_addr in6addr_any = IN6ADDR_ANY_INIT;

View file

@ -0,0 +1,22 @@
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
vi: set et ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi
Copyright 2024 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/sock/struct/sockaddr6.h"
#include "libc/sysv/consts/inaddr.h"
const struct in6_addr in6addr_loopback = IN6ADDR_LOOPBACK_INIT;

View file

@ -17,4 +17,7 @@ struct sockaddr_in6 { /* Linux+NT ABI */
uint32_t sin6_scope_id; /* rfc2553 */
};
extern const struct in6_addr in6addr_any;
extern const struct in6_addr in6addr_loopback;
#endif /* COSMOPOLITAN_LIBC_CALLS_STRUCT_SOCKADDR6_H_ */

View file

@ -38,7 +38,7 @@
errno_t pthread_attr_init(pthread_attr_t *attr) {
*attr = (pthread_attr_t){
.__stacksize = GetStackSize(),
.__guardsize = GetGuardSize(),
.__guardsize = getauxval(AT_PAGESZ),
};
return 0;
}

View file

@ -216,7 +216,9 @@ static errno_t pthread_create_impl(pthread_t *thread,
_pthread_free(pt, false);
return EINVAL;
}
if (pt->pt_attr.__guardsize == pagesize) {
if (pt->pt_attr.__guardsize == pagesize &&
!(IsAarch64() && IsLinux() && IsQemuUser())) {
// MAP_GROWSDOWN doesn't work very well on qemu-aarch64
pt->pt_attr.__stackaddr =
mmap(0, pt->pt_attr.__stacksize, PROT_READ | PROT_WRITE,
MAP_STACK | MAP_ANONYMOUS, -1, 0);