Get codebase completely working with LLVM

You can now build Cosmopolitan with Clang:

    make -j8 MODE=llvm
    o/llvm/examples/hello.com

The assembler and linker code is now friendly to LLVM too.
So it's not needed to configure Clang to use binutils under
the hood. If you love LLVM then you can now use pure LLVM.
This commit is contained in:
Justine Tunney 2021-02-08 09:19:00 -08:00
parent 0e36cb3ac4
commit e75ffde09e
4528 changed files with 7776 additions and 11640 deletions

View file

@ -1,5 +1,6 @@
#ifndef COSMOPOLITAN_LIBC_CALLS_SYSCALLS_H_
#define COSMOPOLITAN_LIBC_CALLS_SYSCALLS_H_
#include "libc/calls/struct/dirent.h"
#include "libc/calls/struct/iovec.h"
#include "libc/calls/struct/rlimit.h"
#include "libc/calls/struct/rusage.h"
@ -62,7 +63,6 @@ COSMOPOLITAN_C_START_
*/
typedef int sig_atomic_t;
typedef struct dirstream DIR;
extern const struct sigset kSigsetFull;
extern const struct sigset kSigsetEmpty;
@ -102,7 +102,6 @@ int execvp(const char *, char *const[]) paramsnonnull();
int execvpe(const char *, char *const[], char *const[]) paramsnonnull();
int faccessat(int, const char *, int, uint32_t);
int fadvise(int, uint64_t, uint64_t, int);
int fallocate(int, int32_t, int64_t, int64_t);
int fchmod(int, uint32_t) nothrow;
int fchmodat(int, const char *, uint32_t, uint32_t);
int fchown(int, uint32_t, uint32_t);
@ -147,7 +146,6 @@ int personality(uint64_t);
int pipe(int[hasatleast 2]);
int pipe2(int[hasatleast 2], int);
int posix_fadvise(int, uint64_t, uint64_t, int);
int posix_fallocate(int, int64_t, int64_t);
int posix_madvise(void *, uint64_t, int);
int raise(int);
int readlink(const char *, char *, size_t);

View file

@ -1,74 +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 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/calls/internal.h"
#include "libc/dce.h"
#include "libc/nt/enum/fsctl.h"
#include "libc/nt/files.h"
#include "libc/nt/struct/filezerodatainformation.h"
#include "libc/sysv/consts/falloc.h"
#include "libc/sysv/errfuns.h"
/**
* Manipulates underlying physical medium of file.
*
* This system call generalizes to many powerful use cases on Linux,
* such as creating gigantic sparse files that take up little space.
* This API can polyfill a certain subset of parameters safely, e.g.
* ones identical to ftruncate(), but errs on the side of caution.
*
* @param fd must be open for writing
* @param mode can be 0, FALLOC_xxx
* @param length is how much physical space to reserve / commit
* @return 0 on success, or -1 w/ errno
* @note limited availability on rhel5 and openbsd
* @see ftruncate()
*/
int fallocate(int fd, int32_t mode, int64_t offset, int64_t length) {
int rc;
uint32_t br;
if (mode == -1 /* our sysvconsts definition */) return eopnotsupp();
if (!mode && !length) return ftruncate(fd, offset);
if (IsLinux()) {
rc = sys_fallocate(fd, mode, offset, length);
if (rc == 0x011d) rc = enosys(); /*RHEL5:CVE-2010-3301*/
return rc;
} else if (!IsWindows()) {
return sys_posix_fallocate(fd, offset, length);
} else {
if (!__isfdkind(fd, kFdFile)) return ebadf();
if (mode == FALLOC_FL_ZERO_RANGE) {
if (DeviceIoControl(
g_fds.p[fd].handle, kNtFsctlSetZeroData,
&(struct NtFileZeroDataInformation){offset, offset + length},
sizeof(struct NtFileZeroDataInformation), NULL, 0, &br, NULL)) {
return 0;
} else {
return __winerr();
}
} else if (!mode && !offset) {
/*
* this should commit physical space
* but not guaranteed zero'd like linux
*/
return sys_ftruncate_nt(fd, length);
} else {
return enosys();
}
}
}

View file

@ -29,7 +29,6 @@
* since the prior extends logically and the latter physically
* @return 0 on success, or -1 w/ errno
* @asyncsignalsafe
* @see fallocate()
*/
int ftruncate(int fd, int64_t length) {
if (!IsWindows()) {

View file

@ -19,13 +19,13 @@
#include "libc/macros.h"
.source __FILE__
/ Obtains WIN32 magic path, e.g. GetTempPathA.
/
/ @param rax is address of ANSI path provider function
/ @param rdi is output buffer
/ @param rdx is output buffer size in bytes that's >0
/ @return eax is string length w/ NUL that's ≤ edx
/ @return rdi is rdi+edx
// Obtains WIN32 magic path, e.g. GetTempPathA.
//
// @param rax is address of ANSI path provider function
// @param rdi is output buffer
// @param rdx is output buffer size in bytes that's >0
// @return eax is string length w/ NUL that's ≤ edx
// @return rdi is rdi+edx
.text.startup
__getntsyspath:
push %rbp
@ -40,14 +40,14 @@ __getntsyspath:
cmovbe %edx,%eax
cmp $1,%eax # leave empty strings empty
jbe 1f
cmpb $'\\,-1(%rdi,%rax) # guarantee trailing slash
cmpb $'\\',-1(%rdi,%rax) # guarantee trailing slash
je 1f
movw $'\\,(%rdi,%rax)
movw $'\\',(%rdi,%rax)
inc %eax
1: inc %rdi # change backslash to slash
cmpb $'\\,-1(%rdi)
cmpb $'\\',-1(%rdi)
jne 2f
movb $'/,-1(%rdi)
movb $'/',-1(%rdi)
2: .loop 1b
leave
ret

View file

@ -22,8 +22,8 @@
#include "libc/sysv/errfuns.h"
textwindows int sys_getsetpriority_nt(int which, unsigned who, int value,
int (*impl)(int)) {
int (*impl)(int)) {
if (which != PRIO_PROCESS && which != PRIO_PGRP) return einval();
if (who && abs(who) != getpid() && abs(who) != gettid()) return eopnotsupp();
if (who && who != getpid() && who != gettid()) return eopnotsupp();
return impl(value);
}

View file

@ -19,9 +19,9 @@
#include "libc/macros.h"
.source __FILE__
/ Calls GetTempPathA() w/ different API.
/
/ @see GetSystemDirectoryA(), GetWindowsDirectoryA()
// Calls GetTempPathA() w/ different API.
//
// @see GetSystemDirectoryA(), GetWindowsDirectoryA()
GetTempPathA_flunk:
xchg %rcx,%rdx
jmp *__imp_GetTempPathA(%rip)

View file

@ -120,7 +120,6 @@ i32 sys_dup3(i32, i32, i32) hidden;
i32 sys_execve(const char *, char *const[], char *const[]) hidden;
i32 sys_faccessat(i32, const char *, i32, u32) hidden;
i32 sys_fadvise(i32, i64, i64, i32) hidden;
i32 sys_fallocate(i64, i32, i64, i64) hidden;
i32 sys_fchdir(i32) hidden;
i32 sys_fchmod(i32, u32) hidden;
i32 sys_fchmodat(i32, const char *, u32, u32) hidden;
@ -158,7 +157,6 @@ i32 sys_openat(i32, const char *, i32, ...) hidden;
i32 sys_pause(void) hidden;
i32 sys_pipe(i32[hasatleast 2]) hidden;
i32 sys_pipe2(i32[hasatleast 2], u32) hidden;
i32 sys_posix_fallocate(i64, i64, i64) hidden;
i32 sys_posix_openpt(i32) hidden;
i32 sys_renameat(i32, const char *, i32, const char *) hidden;
i32 sys_sched_setaffinity(i32, u64, const void *) hidden;
@ -277,7 +275,7 @@ ssize_t sys_write_nt(struct Fd *, const struct iovec *, size_t, ssize_t) hidden;
int64_t ntreturn(uint32_t);
void WinMainForked(void) hidden;
void *GetProcAddressModule(const char *, const char *) hidden;
int sys_getsetpriority_nt(int, unsigned, int, int (*)(int));
int sys_getsetpriority_nt(int, int, int, int (*)(int));
void ntcontext2linux(struct ucontext *, const struct NtContext *) hidden;
struct NtOverlapped *offset2overlap(int64_t, struct NtOverlapped *) hidden;
bool32 ntsetprivilege(i64, const char16_t *, u32) hidden;

View file

@ -22,9 +22,9 @@
#define BYTES 64
/ RII constant holding 'C:/WINDOWS/SYSTEM32' directory.
/
/ @note guarantees trailing slash if non-empty
// RII constant holding 'C:/WINDOWS/SYSTEM32' directory.
//
// @note guarantees trailing slash if non-empty
.initbss 300,_init_kNtSystemDirectory
kNtSystemDirectory:
.zero BYTES

View file

@ -22,9 +22,9 @@
#define BYTES 64
/ RII constant holding 'C:/WINDOWS' directory.
/
/ @note guarantees trailing slash if non-empty
// RII constant holding 'C:/WINDOWS' directory.
//
// @note guarantees trailing slash if non-empty
.initbss 300,_init_kNtWindowsDirectory
kNtWindowsDirectory:
.zero BYTES

View file

@ -22,10 +22,10 @@
#define kTmpPathMax 80
/ RII constant holding /tmp/ directory.
/
/ @note on win32 this is firstNonNull($TMP, $TEMP, $PWD)
/ @note guarantees trailing slash if non-empty
// RII constant holding /tmp/ directory.
//
// @note on win32 this is firstNonNull($TMP, $TEMP, $PWD)
// @note guarantees trailing slash if non-empty
.initbss 300,_init_kTmpPath
kTmpPath:
.zero kTmpPathMax
@ -33,8 +33,8 @@ kTmpPath:
.previous
.init.start 300,_init_kTmpPath
movl $'/|'t<<010|'m<<020|'p<<030,(%rdi)
movw $'/,4(%rdi)
movl $'/'|'t'<<010|'m'<<020|'p'<<030,(%rdi)
movw $'/',4(%rdi)
#if SupportsWindows()
pushpop kTmpPathMax,%rdx
ezlea GetTempPathA_flunk,ax

View file

@ -19,10 +19,10 @@
#include "libc/nexgen32e/x86feature.h"
#include "libc/macros.h"
/ Returns timestamp without needing system calls.
/
/ @return seconds since unix epoch in %st0
/ @note uses microsecond scale fallback on k8 or vm
// Returns timestamp without needing system calls.
//
// @return seconds since unix epoch in %st0
// @note uses microsecond scale fallback on k8 or vm
.initbss 202,_init_nowl
nowl: .quad 0
.endobj nowl,globl

View file

@ -1,33 +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 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/calls/calls.h"
#include "libc/dce.h"
#include "libc/sysv/errfuns.h"
/**
* Manipulates underlying physical medium of file, the POSIX way.
*
* @param fd must be open for writing
* @param length is how much physical space to reserve
* @return 0 on success, or -1 w/ errno
* @see fallocate(), ftruncate()
*/
int posix_fallocate(int fd, int64_t offset, int64_t length) {
return fallocate(fd, 0, offset, length);
}

View file

@ -19,18 +19,19 @@
#include "libc/calls/calls.h"
#include "libc/calls/termios.h"
#include "libc/errno.h"
#include "libc/fmt/fmt.h"
#include "libc/fmt/itoa.h"
#include "libc/sysv/consts/termios.h"
#include "libc/sysv/errfuns.h"
errno_t ptsname_r(int fd, char *buf, size_t size) {
int pty;
char tb[32];
if (size) {
if (!buf) return einval();
if (ioctl(fd, TIOCGPTN, &pty) == -1) return errno;
if (snprintf(buf, size, "/dev/pts/%d", pty) >= size) {
return (errno = ERANGE);
}
int64toarray_radix10(pty, stpcpy(tb, "/dev/pts/"));
if (strlen(tb) + 1 >= size) return (errno = ERANGE);
stpcpy(buf, tb);
/* TODO(jart): OpenBSD OMG */
}
return 0;

View file

@ -19,10 +19,10 @@
#include "libc/macros.h"
.source __FILE__
/ Sets effective group ID.
/
/ @param %edi is group id
/ @see setgid(), getauxval(AT_SECURE)
// Sets effective group ID.
//
// @param %edi is group id
// @see setgid(), getauxval(AT_SECURE)
setegid:push %rbp
mov %rsp,%rbp
.profilable

View file

@ -19,10 +19,10 @@
#include "libc/macros.h"
.source __FILE__
/ Sets effective user ID.
/
/ @param %edi is user id
/ @see setuid(), getauxval(AT_SECURE)
// Sets effective user ID.
//
// @param %edi is user id
// @see setuid(), getauxval(AT_SECURE)
seteuid:push %rbp
mov %rsp,%rbp
.profilable

View file

@ -16,6 +16,7 @@
TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
PERFORMANCE OF THIS SOFTWARE.
*/
#include "libc/assert.h"
#include "libc/bits/bits.h"
#include "libc/calls/calls.h"
#include "libc/calls/internal.h"
@ -134,15 +135,15 @@ static void sigaction_native2cosmo(union metasigaction *sa) {
* @vforksafe
*/
int(sigaction)(int sig, const struct sigaction *act, struct sigaction *oldact) {
_Static_assert(sizeof(struct sigaction) > sizeof(struct sigaction_linux) &&
sizeof(struct sigaction) > sizeof(struct sigaction_xnu_in) &&
sizeof(struct sigaction) > sizeof(struct sigaction_xnu_out) &&
sizeof(struct sigaction) > sizeof(struct sigaction_freebsd) &&
sizeof(struct sigaction) > sizeof(struct sigaction_openbsd) &&
sizeof(struct sigaction) > sizeof(struct sigaction_netbsd));
int64_t arg4, arg5;
int rc, rva, oldrva;
struct sigaction *ap, copy;
assert(sizeof(struct sigaction) > sizeof(struct sigaction_linux) &&
sizeof(struct sigaction) > sizeof(struct sigaction_xnu_in) &&
sizeof(struct sigaction) > sizeof(struct sigaction_xnu_out) &&
sizeof(struct sigaction) > sizeof(struct sigaction_freebsd) &&
sizeof(struct sigaction) > sizeof(struct sigaction_openbsd) &&
sizeof(struct sigaction) > sizeof(struct sigaction_netbsd));
if (IsMetal()) return enosys(); /* TODO: Signals on Metal */
if (!(0 < sig && sig < NSIG)) return einval();
if (sig == SIGKILL || sig == SIGSTOP) return einval();

View file

@ -20,16 +20,16 @@
#include "libc/macros.h"
.source __FILE__
/ BSD signal handler.
/
/ This is needed because (1) a signal is allowed to trigger at
/ just about any time, and leaf functions (e.g. memcpy) aren't
/ required to leave Cosmopolitan's image base register alone.
/
/ @param %edi is the signal number
/ @param %rsi will be passed for sigactions
/ @param %rdx will be passed for sigactions
/ @return true if handler was invoked
// BSD signal handler.
//
// This is needed because (1) a signal is allowed to trigger at
// just about any time, and leaf functions (e.g. memcpy) aren't
// required to leave Cosmopolitan's image base register alone.
//
// @param %edi is the signal number
// @param %rsi will be passed for sigactions
// @param %rdx will be passed for sigactions
// @return true if handler was invoked
__sigenter:
push %rbp
mov %rsp,%rbp

View file

@ -10,5 +10,8 @@ struct dirent { /* linux getdents64 abi */
char d_name[256]; /* NUL-terminated basename */
};
struct dirstream;
typedef struct dirstream DIR;
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */
#endif /* COSMOPOLITAN_LIBC_CALLS_STRUCT_DIRENT_H_ */

View file

@ -21,6 +21,7 @@
#include "libc/calls/struct/stat.h"
#include "libc/dce.h"
#include "libc/fmt/fmt.h"
#include "libc/fmt/itoa.h"
#include "libc/log/log.h"
#include "libc/nt/console.h"
#include "libc/nt/enum/consolemodeflags.h"
@ -58,7 +59,7 @@ static int ttyname_linux(int fd, char *buf, size_t size) {
struct stat st1, st2;
if (!isatty(fd)) return errno;
char name[PATH_MAX];
snprintf(name, sizeof(name), "/proc/self/fd/%d", fd);
int64toarray_radix10(fd, stpcpy(name, "/proc/self/fd/"));
ssize_t got;
got = readlink(name, buf, size);
if (got == -1) return errno;

View file

@ -4,7 +4,5 @@
typedef void (*sighandler_t)(int);
typedef void (*sighandler_t)(int);
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */
#endif /* COSMOPOLITAN_LIBC_CALLS_TYPEDEF_SIGHANDLER_T_H_ */