Merge branch 'master' of https://github.com/jart/cosmopolitan into lua-tls-api

This commit is contained in:
s0ph0s 2024-02-28 21:23:31 -05:00
commit 88d2662664
994 changed files with 28753 additions and 15030 deletions

View file

@ -48,11 +48,10 @@
"notpossible=", "notpossible=",
"thatispacked=", "thatispacked=",
"dontthrow=", "dontthrow=",
"nocallback=", "dontcallback=",
"relegated=", "relegated=",
"hidden=", "hidden=",
"textstartup=", "textstartup=",
"initarray=",
"returnsnonnull=", "returnsnonnull=",
"returnspointerwithnoaliases=", "returnspointerwithnoaliases=",
"printfesque(x)=", "printfesque(x)=",

View file

@ -16,10 +16,25 @@ contributors who prefer to remain anonymous to the public.
The first time you send a pull request, you need to send an email to The first time you send a pull request, you need to send an email to
Justine Tunney <jtunney@gmail.com> stating that you intend to assign her Justine Tunney <jtunney@gmail.com> stating that you intend to assign her
the copyright to the changes you contribute to Cosmopolitan. This only the copyright to the changes you contribute to Cosmopolitan. It only
applies to the code you *choose* to contribute. It only has to happen needs to happen once. This only applies to the code you *choose* to
once. The email should be sent from an email address associated with contribute. The email should be sent from an email address associated
your identity. Your email should link to your pull request. with your identity. Your email should link to your pull request.
To make things easy, here's an example of a good email you can use:
> **From**: YOUR NAME (yname@gmail.com)
> **To**: Justine Tunney (jtunney@gmail.com)
> **Subject**: Cosmopolitan Copyright Assignment for YOUR NAME
>
> Hi Justine,
>
> I made my first contribution to Cosmopolitan in
> https://github.com/jart/cosmopolitan/pull/XXXX could you please take a
> look? I intend to assign you the copyright to the changes I contribute
> to Cosmopolitan.
>
> Thanks!
Please note that in order to give Justine the copyright, it has to be Please note that in order to give Justine the copyright, it has to be
yours to give in the first place. If you're employed, then you should yours to give in the first place. If you're employed, then you should
@ -38,6 +53,27 @@ owners and the code should go in the `third_party/` folder. Every third
party project should have a `README.cosmo` file that documents its party project should have a `README.cosmo` file that documents its
provenance as well as any local changes you've made. provenance as well as any local changes you've made.
## Copyright Policy Exceptions
### Tests
You're encoraged to claim ownership of your test code. If you add a new
file under the `test/` directory, then you should put your name in the
ISC license header at the top of the file. If you add new test cases to
an existing unit test file, then you're encouraged to append a line with
your name to the existing copyright header of that file.
### Exceptional Features
Let's say you discovered a faster better way to implement `log10()` and
you want to give it to Cosmopolitan. In cases like this, it really isn't
appropriate for Justine to own your code. What you could do instead, is
write your own new and improved `log10.c` from scratch, put your name on
the top with the ISC license, and then add a `__notice()` directive so
that your name will be embedded inside every executable that links the
`log10()` function. This will help you get your name out there. Please
note you need get approval from Justine each time you want to do this.
## Style Guide ## Style Guide
You can use clang-format to automatically format your files: You can use clang-format to automatically format your files:
@ -47,34 +83,4 @@ clang-format -i -style=file tool/net/redbean.c
``` ```
If you use Emacs this can be automated on save for Cosmopolitan using If you use Emacs this can be automated on save for Cosmopolitan using
[tool/emacs/cosmo-format.el]([tool/emacs/cosmo-format.el]). [tool/emacs/cosmo-format.el](tool/emacs/cosmo-format.el).
### Source Files
- Must use include paths relative to the root of the repository
- Must have comment at top of file documenting copyright and license
- Must have notice embedding if not owned by Justine (exception: tests)
- May use language extensions that are supported by both GCC and Clang
- Should use Google indentation (otherwise use `/* clang-format off */`)
- Should use asm() instead of compiler APIs (exception: ctz, clz, memcpy)
### Header Files
- Must not have copyright or license comments
- Must have once guards (otherwise change `.h` to `.inc`)
- Must be ANSI C89 compatible to be included in the amalgamation header
- Must include its dependencies (exception: libc/integral/normalize.inc)
- Must not define objects (i.e. `cc -c -xc foo.h` will produce empty `.o`)
- Should not use typedefs
- Should not use forward declarations
- Should not include documentation comments
- Should not include parameter names in prototypes
- Should not pose problems if included by C++ or Assembly sources
- Should not declare non-ANSI code, at all, when the user requests ANSI
### Build Config
- Must not write files outside `o/`
- Must not communicate with Internet
- Must not depend on system libraries
- Must not depend on system commands (exception: sh, make, gzip, zip)

View file

@ -101,7 +101,6 @@ XARGS ?= xargs -P4 -rs8000
DOT ?= dot DOT ?= dot
CLANG = clang CLANG = clang
TMPDIR = o/tmp TMPDIR = o/tmp
AR = build/bootstrap/ar.com AR = build/bootstrap/ar.com
CP = build/bootstrap/cp.com CP = build/bootstrap/cp.com
RM = build/bootstrap/rm.com -f RM = build/bootstrap/rm.com -f
@ -137,7 +136,7 @@ ARCH = aarch64
HOSTS ?= pi studio freebsdarm HOSTS ?= pi studio freebsdarm
else else
ARCH = x86_64 ARCH = x86_64
HOSTS ?= freebsd rhel7 xnu win10 openbsd netbsd HOSTS ?= freebsd rhel7 xnu openbsd netbsd win10
endif endif
ZIPOBJ_FLAGS += -a$(ARCH) ZIPOBJ_FLAGS += -a$(ARCH)
@ -150,9 +149,9 @@ export MODE
export SOURCE_DATE_EPOCH export SOURCE_DATE_EPOCH
export TMPDIR export TMPDIR
COSMOCC = .cosmocc/3.2 COSMOCC = .cosmocc/3.3.2
TOOLCHAIN = $(COSMOCC)/bin/$(ARCH)-linux-cosmo- TOOLCHAIN = $(COSMOCC)/bin/$(ARCH)-linux-cosmo-
DOWNLOAD := $(shell build/download-cosmocc.sh $(COSMOCC) 3.2 28b48682595f0f46b45ab381118cdffdabc8fcfa29aa54e301fe6ffe35269f5e) DOWNLOAD := $(shell build/download-cosmocc.sh $(COSMOCC) 3.3.2 a695012ffbeac5e26e3c4a740debc15273f47e9a8bdc55e8b76a623154d5914b)
AS = $(TOOLCHAIN)as AS = $(TOOLCHAIN)as
CC = $(TOOLCHAIN)gcc CC = $(TOOLCHAIN)gcc
@ -207,9 +206,8 @@ endif
.UNVEIL += \ .UNVEIL += \
libc/integral \ libc/integral \
libc/stdbool.h \ libc/stdbool.h \
libc/disclaimer.inc \
rwc:/dev/shm \ rwc:/dev/shm \
rx:cosmocc \ rx:.cosmocc \
rx:build/bootstrap \ rx:build/bootstrap \
r:build/portcosmo.h \ r:build/portcosmo.h \
/proc/stat \ /proc/stat \
@ -299,6 +297,7 @@ include third_party/nsync/testing/BUILD.mk
include libc/testlib/BUILD.mk include libc/testlib/BUILD.mk
include tool/viz/lib/BUILD.mk include tool/viz/lib/BUILD.mk
include tool/args/BUILD.mk include tool/args/BUILD.mk
include test/math/BUILD.mk
include test/posix/BUILD.mk include test/posix/BUILD.mk
include test/libcxx/BUILD.mk include test/libcxx/BUILD.mk
include test/tool/args/BUILD.mk include test/tool/args/BUILD.mk
@ -481,6 +480,7 @@ COSMOPOLITAN_OBJECTS = \
LIBC_STR \ LIBC_STR \
LIBC_SYSV \ LIBC_SYSV \
LIBC_INTRIN \ LIBC_INTRIN \
LIBC_NT_BCRYPTPRIMITIVES \
LIBC_NT_KERNEL32 \ LIBC_NT_KERNEL32 \
LIBC_NEXGEN32E LIBC_NEXGEN32E
@ -556,9 +556,9 @@ o/cosmopolitan.html: private .UNSANDBOXED = 1
o/cosmopolitan.html: \ o/cosmopolitan.html: \
o/$(MODE)/third_party/chibicc/chibicc.com.dbg \ o/$(MODE)/third_party/chibicc/chibicc.com.dbg \
$(filter-out %.s,$(foreach x,$(COSMOPOLITAN_OBJECTS),$($(x)_SRCS))) \ $(filter-out %.s,$(foreach x,$(COSMOPOLITAN_OBJECTS),$($(x)_SRCS))) \
$(filter-out %.cc,$(SRCS)) \ $(filter-out %.cpp,$(filter-out %.cc,$(SRCS))) \
$(HDRS) $(HDRS)
$(file >$(TMPDIR)/$(subst /,_,$@),$(filter-out %.cc,$(filter-out %.s,$(foreach x,$(COSMOPOLITAN_OBJECTS),$($(x)_SRCS))))) $(file >$(TMPDIR)/$(subst /,_,$@),$(filter-out %.cpp,$(filter-out %.cc,$(filter-out %.s,$(foreach x,$(COSMOPOLITAN_OBJECTS),$($(x)_SRCS))))))
o/$(MODE)/third_party/chibicc/chibicc.com.dbg -J \ o/$(MODE)/third_party/chibicc/chibicc.com.dbg -J \
-fno-common -include libc/integral/normalize.inc -o $@ \ -fno-common -include libc/integral/normalize.inc -o $@ \
-DCOSMO @$(TMPDIR)/$(subst /,_,$@) -DCOSMO @$(TMPDIR)/$(subst /,_,$@)

View file

@ -157,7 +157,6 @@ o/$(MODE)/ape/ape-no-modify-self.o: \
ape/ape.S \ ape/ape.S \
ape/ape.h \ ape/ape.h \
ape/macros.internal.h \ ape/macros.internal.h \
ape/notice.inc \
ape/relocations.h \ ape/relocations.h \
ape/ape.internal.h \ ape/ape.internal.h \
libc/dce.h \ libc/dce.h \
@ -185,7 +184,6 @@ o/$(MODE)/ape/ape-copy-self.o: \
ape/ape.S \ ape/ape.S \
ape/ape.h \ ape/ape.h \
ape/macros.internal.h \ ape/macros.internal.h \
ape/notice.inc \
ape/relocations.h \ ape/relocations.h \
ape/ape.internal.h \ ape/ape.internal.h \
libc/dce.h \ libc/dce.h \

View file

@ -89,10 +89,12 @@ SECTIONS {
*(.ubsan.data) *(.ubsan.data)
} }
.comment : { .notice : {
__comment_start = .; __notices = .;
KEEP(*(.comment)) KEEP(*(.notice))
BYTE(0); BYTE(0);
BYTE(10);
BYTE(10);
} }
.eh_frame_hdr : { .eh_frame_hdr : {
@ -157,8 +159,11 @@ SECTIONS {
.init_array : { .init_array : {
__init_array_start = .; __init_array_start = .;
KEEP(*(SORT_BY_INIT_PRIORITY(.init_array.*) SORT_BY_INIT_PRIORITY(.ctors.*))) KEEP(*(.preinit_array))
KEEP(*(.init_array EXCLUDE_FILE(*crtbegin.o *crtbegin?.o *crtend.o *crtend?.o ) .ctors)) KEEP(*(SORT_BY_INIT_PRIORITY(.init_array.*)
SORT_BY_INIT_PRIORITY(.ctors.*)))
KEEP(*(.init_array))
KEEP(*(.ctors))
__init_array_end = .; __init_array_end = .;
} }

View file

@ -39,7 +39,7 @@
/* maximum path size that cosmo can take */ /* maximum path size that cosmo can take */
#define PATHSIZE (PATH_MAX < 1024 ? PATH_MAX : 1024) #define PATHSIZE (PATH_MAX < 1024 ? PATH_MAX : 1024)
#define SYSLIB_MAGIC ('s' | 'l' << 8 | 'i' << 16 | 'b' << 24) #define SYSLIB_MAGIC ('s' | 'l' << 8 | 'i' << 16 | 'b' << 24)
#define SYSLIB_VERSION 8 #define SYSLIB_VERSION 9 /* sync with libc/runtime/syslib.internal.h */
struct Syslib { struct Syslib {
int magic; int magic;
@ -96,11 +96,16 @@ struct Syslib {
long (*sem_trywait)(int *); long (*sem_trywait)(int *);
long (*getrlimit)(int, struct rlimit *); long (*getrlimit)(int, struct rlimit *);
long (*setrlimit)(int, const struct rlimit *); long (*setrlimit)(int, const struct rlimit *);
// v6 (2023-11-03) /* v6 (2023-11-03) */
void *(*dlopen)(const char *, int); void *(*dlopen)(const char *, int);
void *(*dlsym)(void *, const char *); void *(*dlsym)(void *, const char *);
int (*dlclose)(void *); int (*dlclose)(void *);
char *(*dlerror)(void); char *(*dlerror)(void);
/* MANDATORY (cosmo runtime won't load if version < 8)
---------------------------------------------------
OPTIONAL (cosmo lib should check __syslib->version) */
/* v9 (2024-01-31) */
int (*pthread_cpu_number_np)(size_t *);
}; };
#define ELFCLASS32 1 #define ELFCLASS32 1
@ -660,9 +665,9 @@ __attribute__((__noreturn__)) static void Spawn(const char *exe, int fd,
size = (p[i].p_vaddr & (pagesz - 1)) + p[i].p_filesz; size = (p[i].p_vaddr & (pagesz - 1)) + p[i].p_filesz;
if (prot1 & PROT_EXEC) { if (prot1 & PROT_EXEC) {
#ifdef SIP_DISABLED #ifdef SIP_DISABLED
// if sip is disabled then we can load the executable segments /* if sip is disabled then we can load the executable segments
// off the binary into memory without needing to copy anything off the binary into memory without needing to copy anything
// which provides considerably better performance for building which provides considerably better performance for building */
rc = sys_mmap(addr, size, prot1, flags, fd, p[i].p_offset & -pagesz); rc = sys_mmap(addr, size, prot1, flags, fd, p[i].p_offset & -pagesz);
if (rc < 0) { if (rc < 0) {
if (rc == -EPERM) { if (rc == -EPERM) {
@ -674,12 +679,12 @@ __attribute__((__noreturn__)) static void Spawn(const char *exe, int fd,
} }
} }
#else #else
// the issue is that if sip is enabled then, attempting to map /* the issue is that if sip is enabled then, attempting to map
// it with exec permission will cause xnu to phone home a hash it with exec permission will cause xnu to phone home a hash
// of the entire file to apple intelligence as a one time cost of the entire file to apple intelligence as a one time cost
// which is literally minutes for executables holding big data which is literally minutes for executables holding big data
// since there's no public apple api for detecting sip we read since there's no public apple api for detecting sip we read
// as the default strategy which is slow but it works for both as the default strategy which is slow but it works for both */
rc = sys_mmap(addr, size, (prot1 = PROT_READ | PROT_WRITE), rc = sys_mmap(addr, size, (prot1 = PROT_READ | PROT_WRITE),
MAP_PRIVATE | MAP_FIXED | MAP_ANONYMOUS, -1, 0); MAP_PRIVATE | MAP_FIXED | MAP_ANONYMOUS, -1, 0);
if (rc < 0) Pexit(exe, rc, "prog mmap anon"); if (rc < 0) Pexit(exe, rc, "prog mmap anon");
@ -812,12 +817,10 @@ static const char *TryElf(struct ApeLoader *M, union ElfEhdrBuf *ebuf,
} }
} }
/* /* merge adjacent loads that are contiguous with equal protection,
* merge adjacent loads that are contiguous with equal protection, which prevents our program header overlap check from needlessly
* which prevents our program header overlap check from needlessly failing later on; it also shaves away a microsecond of latency,
* failing later on; it also shaves away a microsecond of latency, since every program header requires invoking at least 1 syscall */
* since every program header requires invoking at least 1 syscall
*/
for (i = 0; i + 1 < e->e_phnum;) { for (i = 0; i + 1 < e->e_phnum;) {
if (p[i].p_type == PT_LOAD && p[i + 1].p_type == PT_LOAD && if (p[i].p_type == PT_LOAD && p[i + 1].p_type == PT_LOAD &&
((p[i].p_flags & (PF_R | PF_W | PF_X)) == ((p[i].p_flags & (PF_R | PF_W | PF_X)) ==
@ -944,6 +947,7 @@ int main(int argc, char **argv, char **envp) {
M->lib.dlsym = dlsym; M->lib.dlsym = dlsym;
M->lib.dlclose = dlclose; M->lib.dlclose = dlclose;
M->lib.dlerror = dlerror; M->lib.dlerror = dlerror;
M->lib.pthread_cpu_number_np = pthread_cpu_number_np;
/* getenv("_") is close enough to at_execfn */ /* getenv("_") is close enough to at_execfn */
execfn = 0; execfn = 0;

View file

@ -33,7 +33,6 @@
αcτµαlly pδrταblε εxεcµταblε § program header αcτµαlly pδrταblε εxεcµταblε § program header
*/ */
#include "ape/macros.internal.h" #include "ape/macros.internal.h"
#include "ape/notice.inc"
#include "ape/relocations.h" #include "ape/relocations.h"
#include "libc/calls/metalfile.internal.h" #include "libc/calls/metalfile.internal.h"
#include "libc/dce.h" #include "libc/dce.h"
@ -1772,49 +1771,31 @@ kernel: movabs $ape_stack_vaddr,%rsp
.type ape_text_nops,@object .type ape_text_nops,@object
.type __test_end,@object .type __test_end,@object
.section .commentprologue,"a",@progbits
.globl __comment_start
.type __comment_start,@object
.hidden __comment_start
__comment_start:/*
...
decentralized content
...
*/.previous
.section .commentepilogue,"a",@progbits
.byte 0
.previous
.section .ape.pad.head,"a",@progbits .section .ape.pad.head,"a",@progbits
.type ape_pad_head,@object .type ape_pad_head,@object
.hidden ape_pad_head .hidden ape_pad_head
ape_pad_head: ape_pad_head:
.previous
.section .ape.pad.text,"a",@progbits .section .ape.pad.text,"a",@progbits
.type ape_pad_text,@object .type ape_pad_text,@object
.hidden ape_pad_text .hidden ape_pad_text
ape_pad_text: ape_pad_text:
.previous
.section .ape.pad.privileged,"a",@progbits .section .ape.pad.privileged,"a",@progbits
.type ape_pad_privileged,@object .type ape_pad_privileged,@object
.hidden ape_pad_privileged .hidden ape_pad_privileged
ape_pad_privileged: ape_pad_privileged:
.previous
.section .ape.pad.data,"a",@progbits .section .ape.pad.data,"a",@progbits
.type ape_pad_data,@object .type ape_pad_data,@object
.hidden ape_pad_data .hidden ape_pad_data
ape_pad_data: ape_pad_data:
.previous
#if SupportsWindows() #if SupportsWindows()
.section .idata.ro,"a",@progbits .section .idata.ro,"a",@progbits
.type ape_idata_ro,@object .type ape_idata_ro,@object
.hidden ape_idata_ro .hidden ape_idata_ro
ape_idata_ro: ape_idata_ro:
.previous
#endif /* SupportsWindows() */ #endif /* SupportsWindows() */
.section .dataprologue,"aw",@progbits .section .dataprologue,"aw",@progbits
@ -1822,32 +1803,45 @@ ape_idata_ro:
.globl __data_start .globl __data_start
.hidden __data_start .hidden __data_start
__data_start: __data_start:
.previous
.section .dataepilogue,"aw",@progbits .section .dataepilogue,"aw",@progbits
.type __data_end,@object .type __data_end,@object
.globl __data_end .globl __data_end
.hidden __data_end .hidden __data_end
__data_end: __data_end:
.previous
.section .bssprologue,"aw",@nobits .section .bssprologue,"aw",@nobits
.type __bss_start,@object .type __bss_start,@object
.globl __bss_start .globl __bss_start
.hidden __bss_start .hidden __bss_start
__bss_start: __bss_start:
.previous
.section .bssepilogue,"aw",@nobits .section .bssepilogue,"aw",@nobits
.type __bss_end,@object .type __bss_end,@object
.globl __bss_end .globl __bss_end
.hidden __bss_end .hidden __bss_end
__bss_end: __bss_end:
.previous
.section .fstls,"awT",@nobits .section .fstls,"awT",@nobits
.align TLS_ALIGNMENT .align TLS_ALIGNMENT
.previous
.section .notice,"aR",@progbits
.asciz "\n\n\
Cosmopolitan\n\
Copyright 2024 Justine Alexandra Roberts Tunney\n\
\n\
Permission to use, copy, modify, and/or distribute this software for\n\
any purpose with or without fee is hereby granted, provided that the\n\
above copyright notice and this permission notice appear in all copies.\n\
\n\
THE SOFTWARE IS PROVIDED \"AS IS\" AND THE AUTHOR DISCLAIMS ALL\n\
WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED\n\
WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE\n\
AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL\n\
DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR\n\
PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER\n\
TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR\n\
PERFORMANCE OF THIS SOFTWARE."
.end .end
 

View file

@ -282,12 +282,9 @@ SECTIONS {
KEEP(*(SORT_BY_NAME(.init.*))) KEEP(*(SORT_BY_NAME(.init.*)))
KEEP(*(.init)) KEEP(*(.init))
KEEP(*(.initepilogue)) KEEP(*(.initepilogue))
KEEP(*(.pltprologue))
*(.plt) *(.plt)
KEEP(*(.pltepilogue))
KEEP(*(.pltgotprologue))
*(.plt.got) *(.plt.got)
KEEP(*(.pltgotepilogue)) *(.iplt)
*(.text.startup .text.startup.*) *(.text.startup .text.startup.*)
*(.text.exit .text.exit.*) *(.text.exit .text.exit.*)
*(.text.unlikely .text.*_unlikely .text.unlikely.*) *(.text.unlikely .text.*_unlikely .text.unlikely.*)
@ -323,7 +320,7 @@ SECTIONS {
/*BEGIN: Read Only Data */ /*BEGIN: Read Only Data */
.rodata . : { .rodata ALIGN(CONSTANT(COMMONPAGESIZE)) : {
KEEP(*(.rodata.pytab.0)); KEEP(*(.rodata.pytab.0));
KEEP(*(.rodata.pytab.1)); KEEP(*(.rodata.pytab.1));
KEEP(*(.rodata.pytab.2)); KEEP(*(.rodata.pytab.2));
@ -333,11 +330,11 @@ SECTIONS {
*(.ubsan.data) *(.ubsan.data)
/* Legal Notices */ /* Legal Notices */
#if !defined(IM_FEELING_NAUGHTY) || defined(EMBED_NOTICES) __notices = .;
KEEP(*(.commentprologue)) KEEP(*(.notice))
KEEP(*(.comment)) BYTE(0);
KEEP(*(.commentepilogue)) BYTE(10);
#endif BYTE(10);
/*BEGIN: read-only data that's only needed for initialization */ /*BEGIN: read-only data that's only needed for initialization */
@ -393,26 +390,28 @@ SECTIONS {
/*BEGIN: NT FORK COPYING */ /*BEGIN: NT FORK COPYING */
KEEP(*(.dataprologue)) KEEP(*(.dataprologue))
*(.data .data.*) *(.data .data.*)
*(.gnu_extab)
*(.gcc_except_table .gcc_except_table.*)
*(.exception_ranges*)
*(.PyRuntime) /* for python */ *(.PyRuntime) /* for python */
*(.subrs) /* for emacs */ *(.subrs) /* for emacs */
KEEP(*(SORT_BY_NAME(.sort.data.*))) KEEP(*(SORT_BY_NAME(.sort.data.*)))
. += . > 0 ? CODE_GRANULE : 0; . += . > 0 ? CODE_GRANULE : 0;
KEEP(*(.gotprologue)) . = ALIGN(. != 0 ? __SIZEOF_POINTER__ : 0);
__got_start = .;
*(.got) *(.got)
KEEP(*(.gotepilogue)) __got_end = .;
KEEP(*(.gotpltprologue))
*(.got.plt) *(.got.plt)
KEEP(*(.gotpltepilogue))
. = ALIGN(. != 0 ? __SIZEOF_POINTER__ : 0); . = ALIGN(. != 0 ? __SIZEOF_POINTER__ : 0);
__init_array_start = .; __init_array_start = .;
KEEP(*(.preinit_array))
KEEP(*(SORT_BY_INIT_PRIORITY(.init_array.*) KEEP(*(SORT_BY_INIT_PRIORITY(.init_array.*)
SORT_BY_INIT_PRIORITY(.ctors.*))) SORT_BY_INIT_PRIORITY(.ctors.*)))
KEEP(*(.ctors))
KEEP(*(.init_array)) KEEP(*(.init_array))
KEEP(*(.preinit_array)) KEEP(*(.ctors))
__init_array_end = .; __init_array_end = .;
. = ALIGN(. != 0 ? __SIZEOF_POINTER__ : 0); . = ALIGN(. != 0 ? __SIZEOF_POINTER__ : 0);
@ -429,7 +428,9 @@ SECTIONS {
. = ALIGN(. != 0 ? __SIZEOF_POINTER__ : 0); . = ALIGN(. != 0 ? __SIZEOF_POINTER__ : 0);
KEEP(*(SORT_BY_NAME(.piro.data.sort.*))) KEEP(*(SORT_BY_NAME(.piro.data.sort.*)))
KEEP(*(.piro.pad.data)) KEEP(*(.piro.pad.data))
*(.igot.plt)
KEEP(*(.dataepilogue)) KEEP(*(.dataepilogue))
. = ALIGN(. != 0 ? CONSTANT(COMMONPAGESIZE) : 0); . = ALIGN(. != 0 ? CONSTANT(COMMONPAGESIZE) : 0);
/*END: NT FORK COPYING */ /*END: NT FORK COPYING */
_edata = .; _edata = .;
@ -527,7 +528,9 @@ SECTIONS {
*(.piro.data.sort.iat.*) *(.piro.data.sort.iat.*)
#endif #endif
*(__patchable_function_entries) *(__patchable_function_entries)
*(.note.gnu.property)
*(__mcount_loc) *(__mcount_loc)
*(.rela.dyn)
*(.discard) *(.discard)
*(.yoink) *(.yoink)
} }

View file

@ -166,13 +166,6 @@
(unsigned long)(255 & (S)[1]) << 010 | \ (unsigned long)(255 & (S)[1]) << 010 | \
(unsigned long)(255 & (S)[0]) << 000) (unsigned long)(255 & (S)[0]) << 000)
#define DEBUG(VAR) \
{ \
char ibuf[19] = {0}; \
Utox(ibuf, VAR); \
Print(os, 2, ibuf, " " #VAR, "\n", 0l); \
}
struct ElfEhdr { struct ElfEhdr {
unsigned char e_ident[16]; unsigned char e_ident[16];
unsigned short e_type; unsigned short e_type;
@ -340,23 +333,6 @@ static char *GetEnv(char **p, const char *s) {
return 0; return 0;
} }
static char *Utox(char p[19], unsigned long x) {
int i;
if (x) {
*p++ = '0';
*p++ = 'x';
i = (__builtin_clzl(x) ^ (sizeof(long) * 8 - 1)) + 1;
i = (i + 3) & -4;
do {
*p++ = "0123456789abcdef"[(x >> (i -= 4)) & 15];
} while (i);
} else {
*p++ = '0';
}
*p = 0;
return p;
}
static char *Utoa(char p[20], unsigned long x) { static char *Utoa(char p[20], unsigned long x) {
char t; char t;
unsigned long i, a, b; unsigned long i, a, b;
@ -534,6 +510,53 @@ static long Print(int os, int fd, const char *s, ...) {
return Write(fd, b, n, os); return Write(fd, b, n, os);
} }
static long Printf(int os, int fd, const char *fmt, ...) {
int i;
char c;
int k = 0;
unsigned u;
char b[512];
const char *s;
unsigned long d;
__builtin_va_list va;
__builtin_va_start(va, fmt);
for (;;) {
switch ((c = *fmt++)) {
case '\0':
__builtin_va_end(va);
return Write(fd, b, k, os);
case '%':
switch ((c = *fmt++)) {
case 's':
for (s = __builtin_va_arg(va, const char *); s && *s; ++s) {
if (k < 512) b[k++] = *s;
}
break;
case 'd':
d = __builtin_va_arg(va, unsigned long);
for (i = 16; i--;) {
u = (d >> (i * 4)) & 15;
if (u < 10) {
c = '0' + u;
} else {
u -= 10;
c = 'a' + u;
}
if (k < 512) b[k++] = c;
}
break;
default:
if (k < 512) b[k++] = c;
break;
}
break;
default:
if (k < 512) b[k++] = c;
break;
}
}
}
static void Perror(int os, const char *thing, long rc, const char *reason) { static void Perror(int os, const char *thing, long rc, const char *reason) {
char ibuf[21]; char ibuf[21];
ibuf[0] = 0; ibuf[0] = 0;
@ -901,7 +924,7 @@ EXTERN_C __attribute__((__noreturn__)) void ApeLoader(long di, long *sp,
long *auxv, *ap, *endp, *sp2; long *auxv, *ap, *endp, *sp2;
char *p, *pe, *exe, *prog, **argv, **envp; char *p, *pe, *exe, *prog, **argv, **envp;
(void)Utox; (void)Printf;
/* detect freebsd */ /* detect freebsd */
if (SupportsXnu() && dl == XNU) { if (SupportsXnu() && dl == XNU) {

View file

@ -2,7 +2,7 @@
#define COSMOPOLITAN_APE_SECTIONS_INTERNAL_H_ #define COSMOPOLITAN_APE_SECTIONS_INTERNAL_H_
COSMOPOLITAN_C_START_ COSMOPOLITAN_C_START_
extern const char __comment_start[] __attribute__((__weak__)); extern const char __notices[] __attribute__((__weak__));
extern unsigned char __executable_start[] __attribute__((__weak__)); extern unsigned char __executable_start[] __attribute__((__weak__));
extern unsigned char __privileged_start[] __attribute__((__weak__)); extern unsigned char __privileged_start[] __attribute__((__weak__));
extern unsigned char _ehead[] __attribute__((__weak__)); extern unsigned char _ehead[] __attribute__((__weak__));
@ -18,10 +18,12 @@ extern unsigned char _tbss_end[] __attribute__((__weak__));
extern unsigned char _tls_align[] __attribute__((__weak__)); extern unsigned char _tls_align[] __attribute__((__weak__));
extern unsigned char __test_start[] __attribute__((__weak__)); extern unsigned char __test_start[] __attribute__((__weak__));
extern unsigned char __ro[] __attribute__((__weak__)); extern unsigned char __ro[] __attribute__((__weak__));
extern uint8_t __data_start[] __attribute__((__weak__)); extern unsigned char __data_start[] __attribute__((__weak__));
extern uint8_t __data_end[] __attribute__((__weak__)); extern unsigned char __data_end[] __attribute__((__weak__));
extern uint8_t __bss_start[] __attribute__((__weak__)); extern unsigned char __bss_start[] __attribute__((__weak__));
extern uint8_t __bss_end[] __attribute__((__weak__)); extern unsigned char __bss_end[] __attribute__((__weak__));
extern unsigned long __got_start[] __attribute__((__weak__));
extern unsigned long __got_end[] __attribute__((__weak__));
extern unsigned char ape_phdrs[] __attribute__((__weak__)); extern unsigned char ape_phdrs[] __attribute__((__weak__));
COSMOPOLITAN_C_END_ COSMOPOLITAN_C_END_

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View file

@ -0,0 +1,58 @@
--nocompress-debug-sections
--noexecstack
-Wa,--nocompress-debug-sections
-Wa,--noexecstack
-Wa,-msse2avx
-Werror=maybe-uninitialized
-Wno-literal-suffix
-Wno-unused-but-set-variable
-Wunsafe-loop-optimizations
-fbranch-target-load-optimize
-fcx-limited-range
-fdelete-dead-exceptions
-femit-struct-debug-baseonly
-ffp-int-builtin-inexact
-finline-functions-called-once
-fipa-pta
-fivopts
-flimit-function-alignment
-fmerge-constants
-fmodulo-sched
-fmodulo-sched-allow-regmoves
-fno-align-jumps
-fno-align-labels
-fno-align-loops
-fno-code-hoisting
-fno-cx-limited-range
-fno-fp-int-builtin-inexact
-fno-gnu-unique
-fno-inline-functions-called-once
-fno-instrument-functions
-fno-schedule-insns2
-fno-whole-program
-fopt-info-vec
-fopt-info-vec-missed
-freg-struct-return
-freschedule-modulo-scheduled-loops
-frounding-math
-fsched2-use-superblocks
-fschedule-insns
-fschedule-insns2
-fshrink-wrap
-fshrink-wrap-separate
-fsignaling-nans
-fstack-clash-protection
-ftracer
-ftrapv
-ftree-loop-im
-ftree-loop-vectorize
-funsafe-loop-optimizations
-fversion-loops-for-strides
-fwhole-program
-gdescribe-dies
-gstabs
-mcall-ms2sysv-xlogues
-mdispatch-scheduler
-mfpmath=sse+387
-mmitigate-rop
-mno-fentry

Binary file not shown.

View file

@ -54,7 +54,7 @@
# #
ifeq ($(LANDLOCKMAKE_VERSION),) ifeq ($(LANDLOCKMAKE_VERSION),)
TMPSAFE = $(join $(TMPDIR),$(subst /,_,$@)).tmp TMPSAFE = $(join $(TMPDIR)/,$(subst /,_,$@)).tmp
else else
TMPSAFE = $(TMPDIR)/ TMPSAFE = $(TMPDIR)/
endif endif
@ -93,7 +93,6 @@ DEFAULT_CCFLAGS += \
-frecord-gcc-switches -frecord-gcc-switches
DEFAULT_COPTS ?= \ DEFAULT_COPTS ?= \
-fno-math-errno \
-fno-ident \ -fno-ident \
-fno-common \ -fno-common \
-fno-gnu-unique \ -fno-gnu-unique \
@ -138,6 +137,8 @@ MATHEMATICAL = \
DEFAULT_CPPFLAGS += \ DEFAULT_CPPFLAGS += \
-D_COSMO_SOURCE \ -D_COSMO_SOURCE \
-DMODE='"$(MODE)"' \ -DMODE='"$(MODE)"' \
-Wno-prio-ctor-dtor \
-Wno-unknown-pragmas \
-nostdinc \ -nostdinc \
-iquote. \ -iquote. \
-isystem libc/isystem -isystem libc/isystem
@ -163,6 +164,7 @@ DEFAULT_LDFLAGS = \
-nostdlib \ -nostdlib \
-znorelro \ -znorelro \
--gc-sections \ --gc-sections \
-z noexecstack \
--build-id=none \ --build-id=none \
--no-dynamic-linker --no-dynamic-linker

View file

@ -55,7 +55,7 @@ set -- --regex-c='/_Atomic(\([^)]*\))/\1/b' "$@"
set -- --regex-c='/^\(\(hidden\|extern\|const\) \)*[_[:alpha:]][_[:alnum:]]*[ *][ *]*\([_[:alpha:]][_[:alnum:]]*[ *][ *]*\)*\([_[:alpha:]][_$[:alnum:]]*\)/\4/b' "$@" set -- --regex-c='/^\(\(hidden\|extern\|const\) \)*[_[:alpha:]][_[:alnum:]]*[ *][ *]*\([_[:alpha:]][_[:alnum:]]*[ *][ *]*\)*\([_[:alpha:]][_$[:alnum:]]*\)/\4/b' "$@"
# ctags doesn't understand function prototypes, e.g. # ctags doesn't understand function prototypes, e.g.
# bool isheap(void *p) dontthrow nocallback; # bool isheap(void *p) dontthrow dontcallback;
set -- --regex-c='/^[_[:alpha:]][_[:alnum:]]*[ *][ *]*\([_[:alpha:]][_[:alnum:]]*[ *][ *]*\)*\([_[:alpha:]][_$[:alnum:]]*\)(.*/\2/b' "$@" set -- --regex-c='/^[_[:alpha:]][_[:alnum:]]*[ *][ *]*\([_[:alpha:]][_[:alnum:]]*[ *][ *]*\)*\([_[:alpha:]][_$[:alnum:]]*\)(.*/\2/b' "$@"
# ctags doesn't understand function pointers, e.g. # ctags doesn't understand function pointers, e.g.

View file

@ -6,14 +6,14 @@ if [ -n "$OBJDUMP" ]; then
fi fi
find_objdump() { find_objdump() {
if [ -x .cosmocc/3.2/bin/$1-linux-cosmo-objdump ]; then if [ -x .cosmocc/3.3.2/bin/$1-linux-cosmo-objdump ]; then
OBJDUMP=.cosmocc/3.2/bin/$1-linux-cosmo-objdump OBJDUMP=.cosmocc/3.3.2/bin/$1-linux-cosmo-objdump
elif [ -x .cosmocc/3.2/bin/$1-linux-musl-objdump ]; then elif [ -x .cosmocc/3.3.2/bin/$1-linux-musl-objdump ]; then
OBJDUMP=.cosmocc/3.2/bin/$1-linux-musl-objdump OBJDUMP=.cosmocc/3.3.2/bin/$1-linux-musl-objdump
elif [ -x "$COSMO/.cosmocc/3.2/bin/$1-linux-cosmo-objdump" ]; then elif [ -x "$COSMO/.cosmocc/3.3.2/bin/$1-linux-cosmo-objdump" ]; then
OBJDUMP="$COSMO/.cosmocc/3.2/bin/$1-linux-cosmo-objdump" OBJDUMP="$COSMO/.cosmocc/3.3.2/bin/$1-linux-cosmo-objdump"
elif [ -x "$COSMO/.cosmocc/3.2/bin/$1-linux-musl-objdump" ]; then elif [ -x "$COSMO/.cosmocc/3.3.2/bin/$1-linux-musl-objdump" ]; then
OBJDUMP="$COSMO/.cosmocc/3.2/bin/$1-linux-musl-objdump" OBJDUMP="$COSMO/.cosmocc/3.3.2/bin/$1-linux-musl-objdump"
else else
echo "error: toolchain not found (try running 'cosmocc --update' or 'make' in the cosmo monorepo)" >&2 echo "error: toolchain not found (try running 'cosmocc --update' or 'make' in the cosmo monorepo)" >&2
exit 1 exit 1

View file

@ -23,7 +23,8 @@
# - tool/build/runitd.c # - tool/build/runitd.c
.PRECIOUS: o/$(MODE)/%.com.ok .PRECIOUS: o/$(MODE)/%.com.ok
o/$(MODE)/%.com.ok: private .PLEDGE = stdio rpath wpath cpath proc fattr inet o/$(MODE)/%.com.ok: private .PLEDGE = stdio rpath wpath cpath proc fattr inet dns
o/$(MODE)/%.com.ok: private .UNVEIL += r:/etc/resolv.conf
o/$(MODE)/%.com.ok: \ o/$(MODE)/%.com.ok: \
o/$(MODE)/tool/build/runit.com \ o/$(MODE)/tool/build/runit.com \
o/$(MODE)/tool/build/runitd.com \ o/$(MODE)/tool/build/runitd.com \

View file

@ -39,6 +39,7 @@ o/$(MODE)/%.h: %.c
o/$(MODE)/%.o: %.cc o/$(MODE)/%.o: %.cc
@$(COMPILE) -AOBJECTIFY.cxx $(OBJECTIFY.cxx) $(OUTPUT_OPTION) $< @$(COMPILE) -AOBJECTIFY.cxx $(OBJECTIFY.cxx) $(OUTPUT_OPTION) $<
@$(COMPILE) -AFIXUPOBJ -wT$@ $(FIXUPOBJ) $@
o/$(MODE)/%.o: %.cpp o/$(MODE)/%.o: %.cpp
@$(COMPILE) -AOBJECTIFY.cxx $(OBJECTIFY.cxx) $(OUTPUT_OPTION) $< @$(COMPILE) -AOBJECTIFY.cxx $(OBJECTIFY.cxx) $(OUTPUT_OPTION) $<

View file

@ -35,12 +35,7 @@
#include "libc/stdio/stdio.h" #include "libc/stdio/stdio.h"
#include "libc/str/str.h" #include "libc/str/str.h"
#include "libc/sysv/consts/madv.h" #include "libc/sysv/consts/madv.h"
__static_yoink("pl_mpeg_notice");
asm(".ident\t\"\\n\\n\
PL_MPEG (MIT License)\\n\
Copyright(c) 2019 Dominic Szablewski\\n\
https://phoboslab.org\"");
asm(".include \"libc/disclaimer.inc\"");
/* clang-format off */ /* clang-format off */
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------

View file

@ -27,17 +27,12 @@
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE. SOFTWARE.
*/ */
#include "dsp/mpeg/buffer.h"
#include "dsp/mpeg/demux.h" #include "dsp/mpeg/demux.h"
#include "dsp/mpeg/buffer.h"
#include "dsp/mpeg/mpeg.h" #include "dsp/mpeg/mpeg.h"
#include "libc/mem/mem.h" #include "libc/mem/mem.h"
#include "libc/str/str.h" #include "libc/str/str.h"
__static_yoink("pl_mpeg_notice");
asm(".ident\t\"\\n\\n\
PL_MPEG (MIT License)\\n\
Copyright(c) 2019 Dominic Szablewski\\n\
https://phoboslab.org\"");
asm(".include \"libc/disclaimer.inc\"");
/* clang-format off */ /* clang-format off */
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------

View file

@ -28,12 +28,7 @@
SOFTWARE. SOFTWARE.
*/ */
#include "dsp/core/half.h" #include "dsp/core/half.h"
__static_yoink("pl_mpeg_notice");
asm(".ident\t\"\\n\\n\
PL_MPEG (MIT License)\\n\
Copyright(c) 2019 Dominic Szablewski\\n\
https://phoboslab.org\"");
asm(".include \"libc/disclaimer.inc\"");
/** /**
* Computes Fixed-Point 8x8 Inverse Discrete Cosine Transform. * Computes Fixed-Point 8x8 Inverse Discrete Cosine Transform.

View file

@ -33,12 +33,6 @@
#include "libc/mem/mem.h" #include "libc/mem/mem.h"
#include "libc/str/str.h" #include "libc/str/str.h"
asm(".ident\t\"\\n\\n\
PL_MPEG (MIT License)\\n\
Copyright(c) 2019 Dominic Szablewski\\n\
https://phoboslab.org\"");
asm(".include \"libc/disclaimer.inc\"");
/* clang-format off */ /* clang-format off */
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
// plm_audio implementation // plm_audio implementation

View file

@ -41,12 +41,7 @@
#include "libc/str/str.h" #include "libc/str/str.h"
#include "libc/time/time.h" #include "libc/time/time.h"
#include "libc/x/x.h" #include "libc/x/x.h"
__static_yoink("pl_mpeg_notice");
asm(".ident\t\"\\n\\n\
PL_MPEG (MIT License)\\n\
Copyright(c) 2019 Dominic Szablewski\\n\
https://phoboslab.org\"");
asm(".include \"libc/disclaimer.inc\"");
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
// plm_video implementation // plm_video implementation
@ -1104,7 +1099,7 @@ plm_video_t *plm_video_create_with_buffer(plm_buffer_t *buffer,
return self; return self;
} }
static textstartup void plm_video_init(void) { __attribute__((__constructor__)) static textstartup void plm_video_init(void) {
PLM_VIDEO_MACROBLOCK_TYPE[0] = NULL; PLM_VIDEO_MACROBLOCK_TYPE[0] = NULL;
PLM_VIDEO_MACROBLOCK_TYPE[1] = (void *)PLM_VIDEO_MACROBLOCK_TYPE_INTRA; PLM_VIDEO_MACROBLOCK_TYPE[1] = (void *)PLM_VIDEO_MACROBLOCK_TYPE_INTRA;
PLM_VIDEO_MACROBLOCK_TYPE[2] = (void *)PLM_VIDEO_MACROBLOCK_TYPE_PREDICTIVE; PLM_VIDEO_MACROBLOCK_TYPE[2] = (void *)PLM_VIDEO_MACROBLOCK_TYPE_PREDICTIVE;
@ -1113,5 +1108,3 @@ static textstartup void plm_video_init(void) {
PLM_VIDEO_DCT_SIZE[1] = (void *)PLM_VIDEO_DCT_SIZE_CHROMINANCE; PLM_VIDEO_DCT_SIZE[1] = (void *)PLM_VIDEO_DCT_SIZE_CHROMINANCE;
PLM_VIDEO_DCT_SIZE[2] = (void *)PLM_VIDEO_DCT_SIZE_CHROMINANCE; PLM_VIDEO_DCT_SIZE[2] = (void *)PLM_VIDEO_DCT_SIZE_CHROMINANCE;
} }
const void *const plm_video_init_ctor[] initarray = {plm_video_init};

4
dsp/mpeg/notice.c Normal file
View file

@ -0,0 +1,4 @@
__notice(pl_mpeg_notice, "\
PL_MPEG (MIT License)\n\
Copyright(c) 2019 Dominic Szablewski\n\
https://phoboslab.org");

View file

@ -32,12 +32,7 @@
#include "libc/mem/mem.h" #include "libc/mem/mem.h"
#include "libc/stdio/stdio.h" #include "libc/stdio/stdio.h"
#include "libc/str/str.h" #include "libc/str/str.h"
__static_yoink("pl_mpeg_notice");
asm(".ident\t\"\\n\\n\
PL_MPEG (MIT License)\\n\
Copyright(c) 2019 Dominic Szablewski\\n\
https://phoboslab.org\"");
asm(".include \"libc/disclaimer.inc\"");
/* clang-format off */ /* clang-format off */
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------

View file

@ -29,12 +29,7 @@
*/ */
#include "dsp/mpeg/mpeg.h" #include "dsp/mpeg/mpeg.h"
#include "libc/macros.internal.h" #include "libc/macros.internal.h"
__static_yoink("pl_mpeg_notice");
asm(".ident\t\"\\n\\n\
PL_MPEG (MIT License)\\n\
Copyright(c) 2019 Dominic Szablewski\\n\
https://phoboslab.org\"");
asm(".include \"libc/disclaimer.inc\"");
/** /**
* @see YCbCr2RGB() in tool/viz/lib/ycbcr2rgb.c * @see YCbCr2RGB() in tool/viz/lib/ycbcr2rgb.c

View file

@ -121,8 +121,7 @@ void *MagikarpY(long dys, long dxs, unsigned char d[restrict dys][dxs],
return d; return d;
} }
static textstartup void g_magikarp_init() { __attribute__((__constructor__)) static textstartup void g_magikarp_init() {
memcpy(g_magkern, kMagkern[0], sizeof(g_magkern)); memcpy(g_magkern, kMagkern[0], sizeof(g_magkern));
memcpy(g_magikarp, kMagikarp[0], sizeof(g_magikarp)); memcpy(g_magikarp, kMagikarp[0], sizeof(g_magikarp));
} }
const void *const g_magikarp_ctor[] initarray = {g_magikarp_init};

View file

@ -21,7 +21,7 @@
struct Itoa8 kItoa8; struct Itoa8 kItoa8;
static textstartup void itoa8_init(void) { __attribute__((__constructor__)) static textstartup void itoa8_init(void) {
int i; int i;
uint8_t z; uint8_t z;
uint32_t w; uint32_t w;
@ -41,5 +41,3 @@ static textstartup void itoa8_init(void) {
kItoa8.data[i] = w; kItoa8.data[i] = w;
} }
} }
const void *const itoa8_init_ctor[] initarray = {itoa8_init};

View file

@ -97,7 +97,7 @@ static int uncube(int x) {
return x < 48 ? 0 : x < 115 ? 1 : (x - 35) / 40; return x < 48 ? 0 : x < 115 ? 1 : (x - 35) / 40;
} }
static textstartup void rgb2ansi_init(void) { __attribute__((__constructor__)) static textstartup void rgb2ansi_init(void) {
uint8_t c; uint8_t c;
uint32_t i; uint32_t i;
memcpy(g_ansi2rgb_, &kCgaPalette, sizeof(kCgaPalette)); memcpy(g_ansi2rgb_, &kCgaPalette, sizeof(kCgaPalette));
@ -114,5 +114,3 @@ static textstartup void rgb2ansi_init(void) {
g_ansi2rgb_[i].xt = i; g_ansi2rgb_[i].xt = i;
} }
} }
const void *const rgb2ansi_init_ctor[] initarray = {rgb2ansi_init};

View file

@ -73,8 +73,6 @@ textstartup void ttyquantsetup(enum TtyQuantizationAlgorithm alg,
TTYQUANT()->blocks = blocks; TTYQUANT()->blocks = blocks;
} }
textstartup void ttyquant_init(void) { __attribute__((__constructor__)) textstartup void ttyquant_init(void) {
ttyquantsetup(kTtyQuantXterm256, kTtyQuantRgb, kTtyBlocksUnicode); ttyquantsetup(kTtyQuantXterm256, kTtyQuantRgb, kTtyBlocksUnicode);
} }
const void *const ttyquant_init_ctor[] initarray = {ttyquant_init};

View file

@ -85,6 +85,7 @@ EXAMPLES_DIRECTDEPS = \
THIRD_PARTY_MUSL \ THIRD_PARTY_MUSL \
THIRD_PARTY_NSYNC \ THIRD_PARTY_NSYNC \
THIRD_PARTY_NSYNC_MEM \ THIRD_PARTY_NSYNC_MEM \
THIRD_PARTY_OPENMP \
THIRD_PARTY_SED \ THIRD_PARTY_SED \
THIRD_PARTY_STB \ THIRD_PARTY_STB \
THIRD_PARTY_TR \ THIRD_PARTY_TR \
@ -153,6 +154,7 @@ o/$(MODE)/examples/picol.com.dbg: \
@$(APELINK) @$(APELINK)
o/$(MODE)/usr/share/dict/words.zip.o: private ZIPOBJ_FLAGS += -C2 o/$(MODE)/usr/share/dict/words.zip.o: private ZIPOBJ_FLAGS += -C2
o/$(MODE)/examples/wut.o: private COPTS += -fopenmp
$(EXAMPLES_OBJS): examples/BUILD.mk $(EXAMPLES_OBJS): examples/BUILD.mk

View file

@ -33,11 +33,10 @@
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/ */
asm(".ident \"\n\ __notice(kilo_notice, "\
Kilo A very simple editor (BSD-2)\n\ Kilo A very simple editor (BSD-2)\n\
Copyright 2016 Salvatore Sanfilippo\n\ Copyright 2016 Salvatore Sanfilippo\n\
Contact: antirez@gmail.com\"\n\ Contact: antirez@gmail.com");
.include \"libc/disclaimer.inc\"");
/* /*
* This software has been modified by Justine Tunney to: * This software has been modified by Justine Tunney to:

View file

@ -67,13 +67,10 @@
* @see https://asciinema.org/ * @see https://asciinema.org/
*/ */
asm(".ident\t\"\\n\\n\ __notice(freebsd_script_notice, "\
FreeBSD Script (BSD-3 License)\\n\ FreeBSD Script (BSD-3 License)\n\
Copyright (c) 2010, 2012 David E. O'Brien\\n\ Copyright (c) 2010, 2012 David E. O'Brien\n\
Copyright (c) 1980, 1992, 1993\\n\ Copyright (c) 1980, 1992, 1993 The Regents of the University of California");
\tThe Regents of the University of California.\\n\
\tAll rights reserved.\"");
asm(".include \"libc/disclaimer.inc\"");
#define DEF_BUF 65536 #define DEF_BUF 65536

View file

@ -7,6 +7,7 @@
http://creativecommons.org/publicdomain/zero/1.0/ │ http://creativecommons.org/publicdomain/zero/1.0/ │
*/ */
#endif #endif
#include "libc/calls/calls.h"
#include "libc/runtime/runtime.h" #include "libc/runtime/runtime.h"
#include "libc/stdio/stdio.h" #include "libc/stdio/stdio.h"

View file

@ -2569,8 +2569,7 @@ static int shlex() {
case 'y': case 'y':
case 'z': case 'z':
p = buf; p = buf;
while (buf++, is_in_name(*buf)) while (buf++, is_in_name(*buf));
;
yylval.name = stalloc(buf - p + 1); yylval.name = stalloc(buf - p + 1);
*(char *)mempcpy(yylval.name, p, buf - p) = 0; *(char *)mempcpy(yylval.name, p, buf - p) = 0;
value = ARITH_VAR; value = ARITH_VAR;
@ -2994,7 +2993,7 @@ static const char *updatepwd(const char *dir) {
lim = (char *)stackblock() + 1; lim = (char *)stackblock() + 1;
if (*dir != '/') { if (*dir != '/') {
if (new[-1] != '/') USTPUTC('/', new); if (new[-1] != '/') USTPUTC('/', new);
if (new > lim &&*lim == '/') lim++; if (new > lim && *lim == '/') lim++;
} else { } else {
USTPUTC('/', new); USTPUTC('/', new);
cdcomppath++; cdcomppath++;
@ -6565,6 +6564,10 @@ struct job *makejob(union node *node, int nprocs) {
return jp; return jp;
} }
#if defined(__GNUC__) && __GNUC__ >= 12
#pragma GCC diagnostic ignored "-Wuse-after-free"
#endif
static struct job *growjobtab(void) { static struct job *growjobtab(void) {
unsigned len; unsigned len;
long offset; long offset;
@ -7446,8 +7449,7 @@ static int ulimitcmd(int argc, char **argv) {
what = optc; what = optc;
} }
} }
for (l = limits; l->option != what; l++) for (l = limits; l->option != what; l++);
;
set = *argptr ? 1 : 0; set = *argptr ? 1 : 0;
if (set) { if (set) {
char *p = *argptr; char *p = *argptr;
@ -7660,8 +7662,7 @@ static void setparam(char **argv) {
char **newparam; char **newparam;
char **ap; char **ap;
int nparam; int nparam;
for (nparam = 0; argv[nparam]; nparam++) for (nparam = 0; argv[nparam]; nparam++);
;
ap = newparam = ckmalloc((nparam + 1) * sizeof *ap); ap = newparam = ckmalloc((nparam + 1) * sizeof *ap);
while (*argv) { while (*argv) {
*ap++ = savestr(*argv++); *ap++ = savestr(*argv++);
@ -7701,8 +7702,7 @@ static int shiftcmd(int argc, char **argv) {
if (shellparam.malloc) ckfree(*ap1); if (shellparam.malloc) ckfree(*ap1);
} }
ap2 = shellparam.p; ap2 = shellparam.p;
while ((*ap2++ = *ap1++) != NULL) while ((*ap2++ = *ap1++) != NULL);
;
shellparam.optind = 1; shellparam.optind = 1;
shellparam.optoff = -1; shellparam.optoff = -1;
INTON; INTON;
@ -8308,8 +8308,7 @@ static void parsefname(void) {
if (heredoclist == NULL) if (heredoclist == NULL)
heredoclist = here; heredoclist = here;
else { else {
for (p = heredoclist; p->next; p = p->next) for (p = heredoclist; p->next; p = p->next);
;
p->next = here; p->next = here;
} }
} else if (n->type == NTOFD || n->type == NFROMFD) { } else if (n->type == NTOFD || n->type == NFROMFD) {
@ -8432,8 +8431,7 @@ static int xxreadtoken(void) {
case '\t': case '\t':
continue; continue;
case '#': case '#':
while ((c = pgetc()) != '\n' && c != PEOF) while ((c = pgetc()) != '\n' && c != PEOF);
;
pungetc(); pungetc();
continue; continue;
case '\n': case '\n':
@ -8553,7 +8551,7 @@ static int readtoken1(int firstc, char const *syntax, char *eofmark,
quotef = 0; quotef = 0;
bqlist = NULL; bqlist = NULL;
STARTSTACKSTR(out); STARTSTACKSTR(out);
loop : { /* for each line, until end of word */ loop: { /* for each line, until end of word */
CHECKEND(); /* set c to PEOF if at end of here document */ CHECKEND(); /* set c to PEOF if at end of here document */
for (;;) { /* until end of line or end of word */ for (;;) { /* until end of line or end of word */
CHECKSTRSPACE(4, out); /* permit 4 calls to USTPUTC */ CHECKSTRSPACE(4, out); /* permit 4 calls to USTPUTC */
@ -8701,7 +8699,7 @@ endword:
* is called, c is set to the first character of the next input line. If * is called, c is set to the first character of the next input line. If
* we are at the end of the here document, this routine sets the c to PEOF. * we are at the end of the here document, this routine sets the c to PEOF.
*/ */
checkend : { checkend: {
if (realeofmark(eofmark)) { if (realeofmark(eofmark)) {
int markloc; int markloc;
char *p; char *p;
@ -8742,7 +8740,7 @@ checkend : {
* specifying the fd to be redirected. The variable "c" contains the * specifying the fd to be redirected. The variable "c" contains the
* first character of the redirection operator. * first character of the redirection operator.
*/ */
parseredir : { parseredir: {
char fd = *out; char fd = *out;
union node *np; union node *np;
np = (union node *)stalloc(sizeof(struct nfile)); np = (union node *)stalloc(sizeof(struct nfile));
@ -8798,7 +8796,7 @@ parseredir : {
* Parse a substitution. At this point, we have read the dollar sign * Parse a substitution. At this point, we have read the dollar sign
* and nothing else. * and nothing else.
*/ */
parsesub : { parsesub: {
int subtype; int subtype;
int typeloc; int typeloc;
char *p; char *p;
@ -8910,7 +8908,7 @@ parsesub : {
* list of commands (passed by reference), and savelen is the number of * list of commands (passed by reference), and savelen is the number of
* characters on the top of the stack which must be preserved. * characters on the top of the stack which must be preserved.
*/ */
parsebackq : { parsebackq: {
struct nodelist **nlpp; struct nodelist **nlpp;
union node *n; union node *n;
char *str; char *str;
@ -9002,7 +9000,7 @@ parsebackq : {
/* /*
* Parse an arithmetic expansion (indicate start of one and set state) * Parse an arithmetic expansion (indicate start of one and set state)
*/ */
parsearith : { parsearith: {
synstack_push(&synstack, synstack->prev ?: alloca(sizeof(*synstack)), synstack_push(&synstack, synstack->prev ?: alloca(sizeof(*synstack)),
ARISYNTAX); ARISYNTAX);
synstack->dblquote = 1; synstack->dblquote = 1;

View file

@ -48,12 +48,9 @@
#include "third_party/musl/netdb.h" #include "third_party/musl/netdb.h"
// clang-format off // clang-format off
asm(".ident\t\"\\n\\n\ __notice(freebsd_whois_notice, "\
FreeBSD Whois (BSD-3 License)\\n\ FreeBSD Whois (BSD-3 License)\n\
Copyright (c) 1980, 1993\\n\ Copyright (c) 1980, 1993 The Regents of the University of California");
\tThe Regents of the University of California.\\n\
\tAll rights reserved.\"");
asm(".include \"libc/disclaimer.inc\"");
#define ABUSEHOST "whois.abuse.net" #define ABUSEHOST "whois.abuse.net"
#define ANICHOST "whois.arin.net" #define ANICHOST "whois.arin.net"

View file

@ -41,6 +41,7 @@ LIBC_CALLS_A_DIRECTDEPS = \
LIBC_INTRIN \ LIBC_INTRIN \
LIBC_NEXGEN32E \ LIBC_NEXGEN32E \
LIBC_NT_ADVAPI32 \ LIBC_NT_ADVAPI32 \
LIBC_NT_BCRYPTPRIMITIVES \
LIBC_NT_IPHLPAPI \ LIBC_NT_IPHLPAPI \
LIBC_NT_KERNEL32 \ LIBC_NT_KERNEL32 \
LIBC_NT_NTDLL \ LIBC_NT_NTDLL \
@ -72,12 +73,10 @@ $(LIBC_CALLS_A_OBJS): private \
-Wframe-larger-than=4096 \ -Wframe-larger-than=4096 \
-Walloca-larger-than=4096 -Walloca-larger-than=4096
ifneq ($(ARCH), aarch64)
# we always want -O3 because: # we always want -O3 because:
# it makes the code size smaller too # it makes the code size smaller too
# we need -mstringop-strategy=loop because:
# privileged code might generate memcpy call
o/$(MODE)/libc/calls/termios2host.o \ o/$(MODE)/libc/calls/termios2host.o \
o/$(MODE)/libc/calls/siginfo2cosmo.o \
o/$(MODE)/libc/calls/sigenter-freebsd.o \ o/$(MODE)/libc/calls/sigenter-freebsd.o \
o/$(MODE)/libc/calls/sigenter-netbsd.o \ o/$(MODE)/libc/calls/sigenter-netbsd.o \
o/$(MODE)/libc/calls/sigenter-openbsd.o \ o/$(MODE)/libc/calls/sigenter-openbsd.o \
@ -85,6 +84,19 @@ o/$(MODE)/libc/calls/sigenter-xnu.o \
o/$(MODE)/libc/calls/ntcontext2linux.o: private \ o/$(MODE)/libc/calls/ntcontext2linux.o: private \
COPTS += \ COPTS += \
-O3 \ -O3 \
-ffreestanding
ifeq ($(ARCH), x86_64)
# we need -mstringop-strategy=loop because:
# privileged code might generate memcpy call
o/$(MODE)/libc/calls/termios2host.o \
o/$(MODE)/libc/calls/siginfo2cosmo.o \
o/$(MODE)/libc/calls/sigenter-freebsd.o \
o/$(MODE)/libc/calls/sigenter-netbsd.o \
o/$(MODE)/libc/calls/sigenter-openbsd.o \
o/$(MODE)/libc/calls/sigenter-xnu.o \
o/$(MODE)/libc/calls/ntcontext2linux.o: private \
COPTS += \
-mstringop-strategy=loop -mstringop-strategy=loop
endif endif
@ -132,7 +144,8 @@ endif
o/$(MODE)/libc/calls/pledge-linux.o: private \ o/$(MODE)/libc/calls/pledge-linux.o: private \
CFLAGS += \ CFLAGS += \
-Os \ -Os \
-fPIC -fPIC \
-ffreestanding
# these assembly files are safe to build on aarch64 # these assembly files are safe to build on aarch64
o/$(MODE)/libc/calls/getcontext.o: libc/calls/getcontext.S o/$(MODE)/libc/calls/getcontext.o: libc/calls/getcontext.S

View file

@ -208,6 +208,7 @@ int execvpe(const char *, char *const[], char *const[]) libcesque;
int euidaccess(const char *, int) libcesque; int euidaccess(const char *, int) libcesque;
int eaccess(const char *, int) libcesque; int eaccess(const char *, int) libcesque;
int madvise(void *, uint64_t, int) libcesque; int madvise(void *, uint64_t, int) libcesque;
int getcpu(unsigned *, unsigned *) libcesque;
#endif #endif
#ifdef _COSMO_SOURCE #ifdef _COSMO_SOURCE
@ -247,6 +248,8 @@ ssize_t tinyprint(int, const char *, ...) libcesque nullterminated();
void shm_path_np(const char *, char[hasatleast 78]) libcesque; void shm_path_np(const char *, char[hasatleast 78]) libcesque;
#endif /* _COSMO_SOURCE */ #endif /* _COSMO_SOURCE */
int system(const char *) libcesque;
int __wifstopped(int) libcesque pureconst; int __wifstopped(int) libcesque pureconst;
int __wifcontinued(int) libcesque pureconst; int __wifcontinued(int) libcesque pureconst;
int __wifsignaled(int) libcesque pureconst; int __wifsignaled(int) libcesque pureconst;

View file

@ -21,12 +21,17 @@
#include "libc/dce.h" #include "libc/dce.h"
#include "libc/errno.h" #include "libc/errno.h"
#include "libc/fmt/wintime.internal.h" #include "libc/fmt/wintime.internal.h"
#include "libc/nt/accounting.h"
#include "libc/nt/runtime.h"
#include "libc/nt/synchronization.h" #include "libc/nt/synchronization.h"
#include "libc/nt/thread.h"
#define _CLOCK_REALTIME 0 #define _CLOCK_REALTIME 0
#define _CLOCK_MONOTONIC 1 #define _CLOCK_MONOTONIC 1
#define _CLOCK_REALTIME_COARSE 2 #define _CLOCK_REALTIME_COARSE 2
#define _CLOCK_BOOTTIME 3 #define _CLOCK_BOOTTIME 3
#define _CLOCK_PROCESS_CPUTIME_ID 4
#define _CLOCK_THREAD_CPUTIME_ID 5
static struct { static struct {
uint64_t base; uint64_t base;
@ -35,7 +40,7 @@ static struct {
textwindows int sys_clock_gettime_nt(int clock, struct timespec *ts) { textwindows int sys_clock_gettime_nt(int clock, struct timespec *ts) {
uint64_t t; uint64_t t;
struct NtFileTime ft; struct NtFileTime ft, ftExit, ftUser, ftKernel, ftCreation;
switch (clock) { switch (clock) {
case _CLOCK_REALTIME: case _CLOCK_REALTIME:
if (ts) { if (ts) {
@ -61,18 +66,30 @@ textwindows int sys_clock_gettime_nt(int clock, struct timespec *ts) {
*ts = timespec_frommillis(GetTickCount64()); *ts = timespec_frommillis(GetTickCount64());
} }
return 0; return 0;
case _CLOCK_PROCESS_CPUTIME_ID:
if (ts) {
GetProcessTimes(GetCurrentProcess(), &ftCreation, &ftExit, &ftKernel,
&ftUser);
*ts = WindowsDurationToTimeSpec(ReadFileTime(ftUser) +
ReadFileTime(ftKernel));
}
return 0;
case _CLOCK_THREAD_CPUTIME_ID:
if (ts) {
GetThreadTimes(GetCurrentThread(), &ftCreation, &ftExit, &ftKernel,
&ftUser);
*ts = WindowsDurationToTimeSpec(ReadFileTime(ftUser) +
ReadFileTime(ftKernel));
}
return 0;
default: default:
return -EINVAL; return -EINVAL;
} }
} }
static textstartup void winclock_init() { __attribute__((__constructor__(40))) static textstartup void winclock_init() {
if (IsWindows()) { if (IsWindows()) {
QueryPerformanceCounter(&g_winclock.base); QueryPerformanceCounter(&g_winclock.base);
QueryPerformanceFrequency(&g_winclock.freq); QueryPerformanceFrequency(&g_winclock.freq);
} }
} }
const void *const winclock_ctor[] initarray = {
winclock_init,
};

View file

@ -61,24 +61,13 @@ static int __clock_gettime_init(int clockid, struct timespec *ts) {
/** /**
* Returns nanosecond time. * Returns nanosecond time.
* *
* @param clock can be one of: * @param clock supports the following values across OSes:
* - `CLOCK_REALTIME`: universally supported * - `CLOCK_REALTIME`
* - `CLOCK_REALTIME_FAST`: ditto but faster on freebsd * - `CLOCK_MONOTONIC`
* - `CLOCK_REALTIME_PRECISE`: ditto but better on freebsd * - `CLOCK_REALTIME_COARSE`
* - `CLOCK_REALTIME_COARSE`: : like `CLOCK_REALTIME_FAST` w/ Linux 2.6.32+ * - `CLOCK_MONOTONIC_COARSE`
* - `CLOCK_MONOTONIC`: universally supported (except on XNU/NT w/o INVTSC) * - `CLOCK_THREAD_CPUTIME_ID`
* - `CLOCK_MONOTONIC_FAST`: ditto but faster on freebsd * - `CLOCK_PROCESS_CPUTIME_ID`
* - `CLOCK_MONOTONIC_PRECISE`: ditto but better on freebsd
* - `CLOCK_MONOTONIC_COARSE`: : like `CLOCK_MONOTONIC_FAST` w/ Linux 2.6.32+
* - `CLOCK_MONOTONIC_RAW`: is actually monotonic but needs Linux 2.6.28+
* - `CLOCK_PROCESS_CPUTIME_ID`: linux and bsd (NetBSD permits OR'd PID)
* - `CLOCK_THREAD_CPUTIME_ID`: linux and bsd (NetBSD permits OR'd TID)
* - `CLOCK_MONOTONIC_COARSE`: linux, freebsd
* - `CLOCK_PROF`: linux and netbsd
* - `CLOCK_BOOTTIME`: linux and openbsd
* - `CLOCK_REALTIME_ALARM`: linux-only
* - `CLOCK_BOOTTIME_ALARM`: linux-only
* - `CLOCK_TAI`: linux-only
* @param ts is where the result is stored (or null to do clock check) * @param ts is where the result is stored (or null to do clock check)
* @return 0 on success, or -1 w/ errno * @return 0 on success, or -1 w/ errno
* @raise EFAULT if `ts` points to invalid memory * @raise EFAULT if `ts` points to invalid memory

View file

@ -0,0 +1,84 @@
/*-*- 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/calls/calls.h"
#include "libc/calls/internal.h"
#include "libc/calls/struct/timespec.h"
#include "libc/errno.h"
#include "libc/runtime/clktck.h"
#include "libc/runtime/runtime.h"
#include "libc/sysv/consts/clock.h"
#include "libc/sysv/consts/timer.h"
/**
* Sleeps with higher accuracy at the cost of cpu.
*/
int cosmo_clock_nanosleep(int clock, int flags, const struct timespec *req,
struct timespec *rem) {
// pick clocks
int time_clock;
int sleep_clock;
if (clock == CLOCK_REALTIME || //
clock == CLOCK_REALTIME_PRECISE) {
time_clock = clock;
sleep_clock = CLOCK_REALTIME;
} else if (clock == CLOCK_MONOTONIC || //
clock == CLOCK_MONOTONIC_PRECISE) {
time_clock = clock;
sleep_clock = CLOCK_MONOTONIC;
} else if (clock == CLOCK_REALTIME_COARSE || //
clock == CLOCK_REALTIME_FAST) {
return sys_clock_nanosleep(CLOCK_REALTIME, flags, req, rem);
} else if (clock == CLOCK_MONOTONIC_COARSE || //
clock == CLOCK_MONOTONIC_FAST) {
return sys_clock_nanosleep(CLOCK_MONOTONIC, flags, req, rem);
} else {
return sys_clock_nanosleep(clock, flags, req, rem);
}
// sleep bulk of time in kernel
struct timespec start, deadline, remain, waitfor, now;
struct timespec quantum = timespec_fromnanos(1000000000 / CLK_TCK);
clock_gettime(time_clock, &start);
deadline = flags & TIMER_ABSTIME ? *req : timespec_add(start, *req);
if (timespec_cmp(start, deadline) >= 0) return 0;
remain = timespec_sub(deadline, start);
if (timespec_cmp(remain, quantum) > 0) {
waitfor = timespec_sub(remain, quantum);
if (sys_clock_nanosleep(sleep_clock, 0, &waitfor, rem) == -1) {
if (!flags && rem && errno == EINTR) {
*rem = timespec_add(*rem, quantum);
}
return -1;
}
}
// spin through final scheduling quantum
int rc = 0;
ftrace_enabled(-1);
do {
if (_check_cancel()) {
rc = -1;
break;
}
clock_gettime(time_clock, &now);
} while (timespec_cmp(now, deadline) < 0);
ftrace_enabled(+1);
return rc;
}

View file

@ -0,0 +1,61 @@
/*-*- 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/calls/calls.h"
#include "libc/calls/cp.internal.h"
#include "libc/calls/struct/timespec.h"
#include "libc/calls/struct/timespec.internal.h"
#include "libc/dce.h"
#include "libc/errno.h"
#include "libc/intrin/describeflags.internal.h"
#include "libc/intrin/strace.internal.h"
#include "libc/intrin/weaken.h"
#include "libc/sysv/errfuns.h"
#include "libc/thread/thread.h"
int sys_clock_nanosleep(int clock, int flags, //
const struct timespec *req, struct timespec *rem) {
int rc;
BEGIN_CANCELATION_POINT;
if (IsLinux() || IsFreebsd() || IsNetbsd()) {
rc = __sys_clock_nanosleep(clock, flags, req, rem);
} else if (IsXnu()) {
rc = sys_clock_nanosleep_xnu(clock, flags, req, rem);
} else if (IsOpenbsd()) {
rc = sys_clock_nanosleep_openbsd(clock, flags, req, rem);
} else if (IsWindows()) {
rc = sys_clock_nanosleep_nt(clock, flags, req, rem);
} else {
rc = enosys();
}
if (rc > 0) {
errno = rc;
rc = -1;
}
// system call support might not detect cancelation on bsds
if (rc == -1 && errno == EINTR && //
_weaken(pthread_testcancel_np) && //
_weaken(pthread_testcancel_np)()) {
rc = ecanceled();
}
END_CANCELATION_POINT;
STRACE("sys_clock_nanosleep(%s, %s, %s, [%s]) → %d% m",
DescribeClockName(clock), DescribeSleepFlags(flags),
DescribeTimespec(0, req), DescribeTimespec(rc, rem), rc);
return rc;
}

View file

@ -16,112 +16,10 @@
TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
PERFORMANCE OF THIS SOFTWARE. PERFORMANCE OF THIS SOFTWARE.
*/ */
#include "libc/assert.h"
#include "libc/calls/cp.internal.h"
#include "libc/calls/internal.h"
#include "libc/calls/struct/timespec.h" #include "libc/calls/struct/timespec.h"
#include "libc/calls/struct/timespec.internal.h"
#include "libc/dce.h" #include "libc/dce.h"
#include "libc/errno.h" #include "libc/errno.h"
#include "libc/intrin/describeflags.internal.h"
#include "libc/intrin/kprintf.h"
#include "libc/intrin/strace.internal.h"
#include "libc/intrin/weaken.h"
#include "libc/runtime/clktck.h"
#include "libc/runtime/runtime.h"
#include "libc/sysv/consts/clock.h"
#include "libc/sysv/consts/timer.h" #include "libc/sysv/consts/timer.h"
#include "libc/sysv/errfuns.h"
#include "libc/thread/thread.h"
static int sys_clock_nanosleep(int clock, int flags, //
const struct timespec *req,
struct timespec *rem) {
int rc;
BEGIN_CANCELATION_POINT;
if (IsLinux() || IsFreebsd() || IsNetbsd()) {
rc = __sys_clock_nanosleep(clock, flags, req, rem);
} else if (IsXnu()) {
rc = sys_clock_nanosleep_xnu(clock, flags, req, rem);
} else if (IsOpenbsd()) {
rc = sys_clock_nanosleep_openbsd(clock, flags, req, rem);
} else if (IsWindows()) {
rc = sys_clock_nanosleep_nt(clock, flags, req, rem);
} else {
rc = enosys();
}
if (rc > 0) {
errno = rc;
rc = -1;
}
// system call support might not detect cancelation on bsds
if (rc == -1 && errno == EINTR && //
_weaken(pthread_testcancel_np) && //
_weaken(pthread_testcancel_np)()) {
rc = ecanceled();
}
END_CANCELATION_POINT;
STRACE("sys_clock_nanosleep(%s, %s, %s, [%s]) → %d% m",
DescribeClockName(clock), DescribeSleepFlags(flags),
DescribeTimespec(0, req), DescribeTimespec(rc, rem), rc);
return rc;
}
static int cosmo_clock_nanosleep(int clock, int flags,
const struct timespec *req,
struct timespec *rem) {
// pick clocks
int time_clock;
int sleep_clock;
if (clock == CLOCK_REALTIME || //
clock == CLOCK_REALTIME_PRECISE) {
time_clock = clock;
sleep_clock = CLOCK_REALTIME;
} else if (clock == CLOCK_MONOTONIC || //
clock == CLOCK_MONOTONIC_PRECISE) {
time_clock = clock;
sleep_clock = CLOCK_MONOTONIC;
} else if (clock == CLOCK_REALTIME_COARSE || //
clock == CLOCK_REALTIME_FAST) {
return sys_clock_nanosleep(CLOCK_REALTIME, flags, req, rem);
} else if (clock == CLOCK_MONOTONIC_COARSE || //
clock == CLOCK_MONOTONIC_FAST) {
return sys_clock_nanosleep(CLOCK_MONOTONIC, flags, req, rem);
} else {
return sys_clock_nanosleep(clock, flags, req, rem);
}
// sleep bulk of time in kernel
struct timespec start, deadline, remain, waitfor, now;
struct timespec quantum = timespec_fromnanos(1000000000 / CLK_TCK);
unassert(!clock_gettime(time_clock, &start));
deadline = flags & TIMER_ABSTIME ? *req : timespec_add(start, *req);
if (timespec_cmp(start, deadline) >= 0) return 0;
remain = timespec_sub(deadline, start);
if (timespec_cmp(remain, quantum) > 0) {
waitfor = timespec_sub(remain, quantum);
if (sys_clock_nanosleep(sleep_clock, 0, &waitfor, rem) == -1) {
if (!flags && rem && errno == EINTR) {
*rem = timespec_add(*rem, quantum);
}
return -1;
}
}
// spin through final scheduling quantum
int rc = 0;
ftrace_enabled(-1);
do {
if (_check_cancel()) {
rc = -1;
break;
}
unassert(!clock_gettime(time_clock, &now));
} while (timespec_cmp(now, deadline) < 0);
ftrace_enabled(+1);
return rc;
}
/** /**
* Sleeps for particular amount of time. * Sleeps for particular amount of time.
@ -157,10 +55,8 @@ static int cosmo_clock_nanosleep(int clock, int flags,
* on OpenBSD it's good; on XNU it's bad; and on Windows it's ugly. * on OpenBSD it's good; on XNU it's bad; and on Windows it's ugly.
* *
* @param clock may be * @param clock may be
* - `CLOCK_REALTIME` to have nanosecond-accurate wall time sleeps * - `CLOCK_REALTIME`
* - `CLOCK_REALTIME_COARSE` to not spin through scheduler quantum * - `CLOCK_MONOTONIC`
* - `CLOCK_MONOTONIC` to base the sleep off the monotinic clock
* - `CLOCK_MONOTONIC_COARSE` to once again not do userspace spin
* @param flags can be 0 for relative and `TIMER_ABSTIME` for absolute * @param flags can be 0 for relative and `TIMER_ABSTIME` for absolute
* @param req can be a relative or absolute time, depending on `flags` * @param req can be a relative or absolute time, depending on `flags`
* @param rem shall be updated with the remainder of unslept time when * @param rem shall be updated with the remainder of unslept time when
@ -193,7 +89,7 @@ errno_t clock_nanosleep(int clock, int flags, //
return EINVAL; return EINVAL;
} }
errno_t old = errno; errno_t old = errno;
int rc = cosmo_clock_nanosleep(clock, flags, req, rem); int rc = sys_clock_nanosleep(clock, flags, req, rem);
errno_t err = !rc ? 0 : errno; errno_t err = !rc ? 0 : errno;
errno = old; errno = old;
return err; return err;

View file

@ -93,7 +93,7 @@ static int close_impl(int fd) {
*/ */
int close(int fd) { int close(int fd) {
int rc; int rc;
if (__isfdkind(fd, kFdZip)) { // XXX IsWindows()? if (__isfdkind(fd, kFdZip)) { // XXX IsWindows()?
BLOCK_SIGNALS; BLOCK_SIGNALS;
__fds_lock(); __fds_lock();
rc = close_impl(fd); rc = close_impl(fd);

View file

@ -32,11 +32,8 @@
#include "libc/sysv/consts/o.h" #include "libc/sysv/consts/o.h"
#include "libc/sysv/consts/s.h" #include "libc/sysv/consts/s.h"
#include "libc/sysv/errfuns.h" #include "libc/sysv/errfuns.h"
__static_yoink("musl_libc_notice");
asm(".ident\t\"\\n\\n\
Musl libc (MIT License)\\n\
Copyright 2005-2014 Rich Felker, et. al.\"");
asm(".include \"libc/disclaimer.inc\"");
// clang-format off // clang-format off
static void __procfdname(char *buf, unsigned fd) { static void __procfdname(char *buf, unsigned fd) {

View file

@ -27,6 +27,7 @@
#include "libc/elf/tinyelf.internal.h" #include "libc/elf/tinyelf.internal.h"
#include "libc/errno.h" #include "libc/errno.h"
#include "libc/intrin/directmap.internal.h" #include "libc/intrin/directmap.internal.h"
#include "libc/intrin/kprintf.h"
#include "libc/nt/memory.h" #include "libc/nt/memory.h"
#include "libc/nt/runtime.h" #include "libc/nt/runtime.h"
#include "libc/runtime/runtime.h" #include "libc/runtime/runtime.h"

76
libc/calls/getcpu.c Normal file
View file

@ -0,0 +1,76 @@
/*-*- 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/calls/calls.h"
#include "libc/calls/struct/cpuset.h"
#include "libc/calls/syscall_support-nt.internal.h"
#include "libc/dce.h"
#include "libc/errno.h"
#include "libc/nexgen32e/rdtscp.h"
#include "libc/nexgen32e/x86feature.h"
#include "libc/nt/struct/processornumber.h"
#include "libc/nt/synchronization.h"
#include "libc/runtime/syslib.internal.h"
#include "libc/sysv/errfuns.h"
int sys_getcpu(unsigned *opt_cpu, unsigned *opt_node, void *tcache);
int getcpu(unsigned *out_opt_cpu, unsigned *out_opt_node) {
unsigned cpu;
unsigned node;
if (X86_HAVE(RDTSCP)) {
unsigned tsc_aux;
rdtscp(&tsc_aux);
cpu = TSC_AUX_CORE(tsc_aux);
node = TSC_AUX_NODE(tsc_aux);
} else if (IsWindows()) {
struct NtProcessorNumber pn;
GetCurrentProcessorNumberEx(&pn);
cpu = 64 * pn.Group + pn.Number;
unsigned short node16;
if (GetNumaProcessorNodeEx(&pn, &node16)) {
node = node16;
} else {
return __winerr();
}
} else if (IsXnuSilicon()) {
if (__syslib->__version >= 9) {
size_t cpu64;
errno_t err = __syslib->__pthread_cpu_number_np(&cpu64);
if (!err) {
cpu = cpu64;
node = 0;
} else {
errno = err;
return -1;
}
} else {
return enosys();
}
} else {
int rc = sys_getcpu(&cpu, &node, 0);
if (rc == -1) return -1;
}
if (out_opt_cpu) {
*out_opt_cpu = cpu;
}
if (out_opt_node) {
*out_opt_node = node;
}
return 0;
}

View file

@ -59,7 +59,7 @@ textwindows int sys_getloadavg_nt(double *a, int n) {
return rc; return rc;
} }
static textstartup void sys_getloadavg_nt_init(void) { __attribute__((__constructor__(40))) static textstartup void ntinitload(void) {
if (IsWindows()) { if (IsWindows()) {
load = 1; load = 1;
cpus = __get_cpu_count() / 2; cpus = __get_cpu_count() / 2;
@ -67,7 +67,3 @@ static textstartup void sys_getloadavg_nt_init(void) {
GetSystemTimes(&idle1, &kern1, &user1); GetSystemTimes(&idle1, &kern1, &user1);
} }
} }
const void *const sys_getloadavg_nt_ctor[] initarray = {
sys_getloadavg_nt_init,
};

View file

@ -103,7 +103,7 @@ static ssize_t GetDevUrandom(char *p, size_t n) {
ssize_t __getrandom(void *p, size_t n, unsigned f) { ssize_t __getrandom(void *p, size_t n, unsigned f) {
ssize_t rc; ssize_t rc;
if (IsWindows()) { if (IsWindows()) {
rc = RtlGenRandom(p, n) ? n : __winerr(); rc = ProcessPrng(p, n) ? n : __winerr();
} else if (have_getrandom) { } else if (have_getrandom) {
if (IsXnu() || IsOpenbsd()) { if (IsXnu() || IsOpenbsd()) {
rc = GetRandomBsd(p, n, GetRandomEntropy); rc = GetRandomBsd(p, n, GetRandomEntropy);
@ -131,7 +131,7 @@ ssize_t __getrandom(void *p, size_t n, unsigned f) {
* *
* This random number seed generator obtains information from: * This random number seed generator obtains information from:
* *
* - RtlGenRandom() on Windows * - ProcessPrng() on Windows
* - getentropy() on XNU and OpenBSD * - getentropy() on XNU and OpenBSD
* - getrandom() on Linux, FreeBSD, and NetBSD * - getrandom() on Linux, FreeBSD, and NetBSD
* - sysctl(KERN_ARND) on older versions of FreeBSD and NetBSD * - sysctl(KERN_ARND) on older versions of FreeBSD and NetBSD
@ -190,7 +190,8 @@ ssize_t getrandom(void *p, size_t n, unsigned f) {
return rc; return rc;
} }
__attribute__((__constructor__)) static textstartup void getrandom_init(void) { __attribute__((__constructor__(30))) static textstartup void getrandom_init(
void) {
int e, rc; int e, rc;
if (IsWindows() || IsMetal()) return; if (IsWindows() || IsMetal()) return;
BLOCK_CANCELATION; BLOCK_CANCELATION;

View file

@ -75,7 +75,9 @@ textstartup void InitializeMetalFile(void) {
memcpy(copied_base, (void *)(BANE + IMAGE_BASE_PHYSICAL), size); memcpy(copied_base, (void *)(BANE + IMAGE_BASE_PHYSICAL), size);
__ape_com_base = copied_base; __ape_com_base = copied_base;
__ape_com_size = size; __ape_com_size = size;
KINFOF("%s @ %p,+%#zx", APE_COM_NAME, copied_base, size); // TODO(tkchia): LIBC_CALLS doesn't depend on LIBC_VGA so references
// to its functions need to be weak
// KINFOF("%s @ %p,+%#zx", APE_COM_NAME, copied_base, size);
} }
} }

View file

@ -21,7 +21,7 @@
char *program_invocation_short_name; char *program_invocation_short_name;
__attribute__((__constructor__)) static void // __attribute__((__constructor__(10))) static textstartup void
program_invocation_short_name_init(void) { program_invocation_short_name_init(void) {
char *p, *r; char *p, *r;
if (!__argc) return; if (!__argc) return;

View file

@ -52,7 +52,7 @@ static dontinline uint64_t rdrand_failover(void) {
* *
* If RDRAND isn't available (we check CPUID and we also disable it * If RDRAND isn't available (we check CPUID and we also disable it
* automatically for microarchitectures where it's slow or buggy) then * automatically for microarchitectures where it's slow or buggy) then
* we try getrandom(), RtlGenRandom(), or sysctl(KERN_ARND). If those * we try getrandom(), ProcessPrng(), or sysctl(KERN_ARND). If those
* aren't available then we try /dev/urandom and if that fails, we try * aren't available then we try /dev/urandom and if that fails, we try
* getauxval(AT_RANDOM), and if not we finally use RDTSC and getpid(). * getauxval(AT_RANDOM), and if not we finally use RDTSC and getpid().
* *

View file

@ -22,8 +22,8 @@
#include "libc/nexgen32e/x86info.h" #include "libc/nexgen32e/x86info.h"
#include "libc/stdio/rand.h" #include "libc/stdio/rand.h"
textstartup void rdrand_init(int argc, char **argv, char **envp, __attribute__((__constructor__(2))) textstartup void rdrand_init(
intptr_t *auxv) { int argc, char **argv, char **envp, intptr_t *auxv) {
extern unsigned kMutableCpuids[KCPUIDS_LEN][4] asm("kCpuids"); extern unsigned kMutableCpuids[KCPUIDS_LEN][4] asm("kCpuids");
/* /*
* Clear RDRAND on AMD models before Zen and then some * Clear RDRAND on AMD models before Zen and then some
@ -39,5 +39,3 @@ textstartup void rdrand_init(int argc, char **argv, char **envp,
kMutableCpuids[KCPUIDS_7H][KCPUIDS_EBX] &= ~(1u << 18); kMutableCpuids[KCPUIDS_7H][KCPUIDS_EBX] &= ~(1u << 18);
} }
} }
const void *const g_rdrand_init[] initarray = {rdrand_init};

View file

@ -157,6 +157,8 @@ static textwindows struct Keystroke *NewKeystroke(void) {
struct Keystroke *k = KEYSTROKE_CONTAINER(e); struct Keystroke *k = KEYSTROKE_CONTAINER(e);
dll_remove(&__keystroke.free, &k->elem); dll_remove(&__keystroke.free, &k->elem);
--__keystroke.freekeys; --__keystroke.freekeys;
// TODO(jart): What's wrong with GCC 12.3?
asm("" : "+r"(k));
k->buflen = 0; k->buflen = 0;
return k; return k;
} }

View file

@ -19,15 +19,19 @@
#include "libc/calls/calls.h" #include "libc/calls/calls.h"
#include "libc/calls/struct/cpuset.h" #include "libc/calls/struct/cpuset.h"
#include "libc/dce.h" #include "libc/dce.h"
#include "libc/errno.h"
#include "libc/nexgen32e/rdtscp.h" #include "libc/nexgen32e/rdtscp.h"
#include "libc/nexgen32e/x86feature.h" #include "libc/nexgen32e/x86feature.h"
#include "libc/nt/struct/processornumber.h" #include "libc/nt/struct/processornumber.h"
#include "libc/nt/synchronization.h" #include "libc/nt/synchronization.h"
#include "libc/runtime/syslib.internal.h"
#include "libc/sysv/errfuns.h"
int sys_getcpu(unsigned *opt_cpu, unsigned *opt_node, void *tcache); int sys_getcpu(unsigned *opt_cpu, unsigned *opt_node, void *tcache);
/** /**
* Returns ID of CPU on which thread is currently scheduled. * Returns ID of CPU on which thread is currently scheduled.
* @return cpu number on success, or -1 w/ errno
*/ */
int sched_getcpu(void) { int sched_getcpu(void) {
if (X86_HAVE(RDTSCP)) { if (X86_HAVE(RDTSCP)) {
@ -38,6 +42,19 @@ int sched_getcpu(void) {
struct NtProcessorNumber pn; struct NtProcessorNumber pn;
GetCurrentProcessorNumberEx(&pn); GetCurrentProcessorNumberEx(&pn);
return 64 * pn.Group + pn.Number; return 64 * pn.Group + pn.Number;
} else if (IsXnuSilicon()) {
if (__syslib->__version >= 9) {
size_t cpu;
errno_t err = __syslib->__pthread_cpu_number_np(&cpu);
if (!err) {
return cpu;
} else {
errno = err;
return -1;
}
} else {
return enosys();
}
} else { } else {
unsigned cpu = 0; unsigned cpu = 0;
int rc = sys_getcpu(&cpu, 0, 0); int rc = sys_getcpu(&cpu, 0, 0);

View file

@ -32,6 +32,7 @@
#include "libc/intrin/bsf.h" #include "libc/intrin/bsf.h"
#include "libc/intrin/describebacktrace.internal.h" #include "libc/intrin/describebacktrace.internal.h"
#include "libc/intrin/dll.h" #include "libc/intrin/dll.h"
#include "libc/intrin/kprintf.h"
#include "libc/intrin/strace.internal.h" #include "libc/intrin/strace.internal.h"
#include "libc/intrin/weaken.h" #include "libc/intrin/weaken.h"
#include "libc/nt/console.h" #include "libc/nt/console.h"
@ -441,8 +442,7 @@ textwindows void __sig_generate(int sig, int sic) {
// to unblock our sig once the wait operation is completed; when // to unblock our sig once the wait operation is completed; when
// that's the case we can cancel the thread's i/o to deliver sig // that's the case we can cancel the thread's i/o to deliver sig
if (atomic_load_explicit(&pt->pt_blocker, memory_order_acquire) && if (atomic_load_explicit(&pt->pt_blocker, memory_order_acquire) &&
!(atomic_load_explicit(&pt->pt_blkmask, memory_order_relaxed) & !(pt->pt_blkmask & (1ull << (sig - 1)))) {
(1ull << (sig - 1)))) {
_pthread_ref(pt); _pthread_ref(pt);
mark = pt; mark = pt;
break; break;
@ -518,6 +518,15 @@ static int __sig_crash_sig(struct NtExceptionPointers *ep, int *code) {
} }
} }
static char *__sig_stpcpy(char *d, const char *s) {
size_t i;
for (i = 0;; ++i) {
if (!(d[i] = s[i])) {
return d + i;
}
}
}
static void __sig_unmaskable(struct NtExceptionPointers *ep, int code, int sig, static void __sig_unmaskable(struct NtExceptionPointers *ep, int code, int sig,
struct CosmoTib *tib) { struct CosmoTib *tib) {
@ -541,9 +550,10 @@ static void __sig_unmaskable(struct NtExceptionPointers *ep, int code, int sig,
intptr_t hStderr; intptr_t hStderr;
char sigbuf[21], s[128], *p; char sigbuf[21], s[128], *p;
hStderr = GetStdHandle(kNtStdErrorHandle); hStderr = GetStdHandle(kNtStdErrorHandle);
p = stpcpy(s, "Terminating on uncaught "); p = __sig_stpcpy(s, "Terminating on uncaught ");
p = stpcpy(p, strsignal_r(sig, sigbuf)); p = __sig_stpcpy(p, strsignal_r(sig, sigbuf));
p = stpcpy(p, ". Pass --strace and/or ShowCrashReports() for details.\n"); p = __sig_stpcpy(
p, ". Pass --strace and/or ShowCrashReports() for details.\n");
WriteFile(hStderr, s, p - s, 0, 0); WriteFile(hStderr, s, p - s, 0, 0);
#endif #endif
__sig_terminate(sig); __sig_terminate(sig);
@ -657,12 +667,10 @@ textwindows int __sig_check(void) {
} }
} }
textstartup void __sig_init(void) { __attribute__((__constructor__(10))) textstartup void __sig_init(void) {
if (!IsWindows()) return; if (!IsWindows()) return;
AddVectoredExceptionHandler(true, (void *)__sig_crash); AddVectoredExceptionHandler(true, (void *)__sig_crash);
SetConsoleCtrlHandler((void *)__sig_console, true); SetConsoleCtrlHandler((void *)__sig_console, true);
} }
const void *const __sig_ctor[] initarray = {__sig_init};
#endif /* __x86_64__ */ #endif /* __x86_64__ */

View file

@ -19,8 +19,8 @@ int timespec_getres(struct timespec *, int) libcesque;
int timespec_get(struct timespec *, int) libcesque; int timespec_get(struct timespec *, int) libcesque;
#ifdef _COSMO_SOURCE #ifdef _COSMO_SOURCE
/* cosmopolitan libc's non-posix timespec library int sys_clock_nanosleep(int, int, const struct timespec *, struct timespec *);
removed by default due to emacs codebase clash */ int cosmo_clock_nanosleep(int, int, const struct timespec *, struct timespec *);
#define timespec_zero ((struct timespec){0}) #define timespec_zero ((struct timespec){0})
#define timespec_max ((struct timespec){0x7fffffffffffffff, 999999999}) #define timespec_max ((struct timespec){0x7fffffffffffffff, 999999999})
libcesque int timespec_cmp(struct timespec, struct timespec) pureconst; libcesque int timespec_cmp(struct timespec, struct timespec) pureconst;

View file

@ -18,7 +18,7 @@ int sys_fcntl_nt_setfl(int, unsigned);
int sys_pause_nt(void); int sys_pause_nt(void);
int64_t __fix_enotdir(int64_t, char16_t *); int64_t __fix_enotdir(int64_t, char16_t *);
int64_t __fix_enotdir3(int64_t, char16_t *, char16_t *); int64_t __fix_enotdir3(int64_t, char16_t *, char16_t *);
int64_t __winerr(void) nocallback privileged; int64_t __winerr(void) dontcallback privileged;
int64_t ntreturn(uint32_t); int64_t ntreturn(uint32_t);
void *GetProcAddressModule(const char *, const char *); void *GetProcAddressModule(const char *, const char *);
void WinMainForked(void); void WinMainForked(void);

View file

@ -130,7 +130,7 @@ typedef struct ucontext ucontext_t;
int getcontext(ucontext_t *) dontthrow; int getcontext(ucontext_t *) dontthrow;
int setcontext(const ucontext_t *) dontthrow; int setcontext(const ucontext_t *) dontthrow;
int swapcontext(ucontext_t *, const ucontext_t *) dontthrow returnstwice; int swapcontext(ucontext_t *, const ucontext_t *) dontthrow returnstwice;
void makecontext(ucontext_t *, void (*)(), int, ...) dontthrow nocallback; void makecontext(ucontext_t *, void *, int, ...) dontthrow dontcallback;
void __sig_restore(const ucontext_t *) wontreturn; void __sig_restore(const ucontext_t *) wontreturn;
COSMOPOLITAN_C_END_ COSMOPOLITAN_C_END_

View file

@ -82,15 +82,27 @@ static textwindows void GetNtName(char *name, int kind) {
} }
static inline textwindows int GetNtMajorVersion(void) { static inline textwindows int GetNtMajorVersion(void) {
#ifdef __x86_64__
return NtGetPeb()->OSMajorVersion; return NtGetPeb()->OSMajorVersion;
#else
return 0;
#endif
} }
static inline textwindows int GetNtMinorVersion(void) { static inline textwindows int GetNtMinorVersion(void) {
#ifdef __x86_64__
return NtGetPeb()->OSMinorVersion; return NtGetPeb()->OSMinorVersion;
#else
return 0;
#endif
} }
static inline textwindows int GetNtBuildNumber(void) { static inline textwindows int GetNtBuildNumber(void) {
#ifdef __x86_64__
return NtGetPeb()->OSBuildNumber; return NtGetPeb()->OSBuildNumber;
#else
return 0;
#endif
} }
static textwindows void GetNtVersion(char *p) { static textwindows void GetNtVersion(char *p) {

View file

@ -100,7 +100,7 @@ static const struct sock_filter kUnveilBlacklistLatestAbi[] = {
static int landlock_abi_version; static int landlock_abi_version;
static int landlock_abi_errno; static int landlock_abi_errno;
__attribute__((__constructor__)) void init_landlock_version() { __attribute__((__constructor__(40))) textstartup void init_landlock_version() {
int e = errno; int e = errno;
landlock_abi_version = landlock_abi_version =
landlock_create_ruleset(0, 0, LANDLOCK_CREATE_RULESET_VERSION); landlock_create_ruleset(0, 0, LANDLOCK_CREATE_RULESET_VERSION);

View file

@ -4,6 +4,7 @@ COSMOPOLITAN_C_START_
errno_t cosmo_once(_Atomic(uint32_t) *, void (*)(void)); errno_t cosmo_once(_Atomic(uint32_t) *, void (*)(void));
int systemvpe(const char *, char *const[], char *const[]) libcesque; int systemvpe(const char *, char *const[], char *const[]) libcesque;
char *GetProgramExecutableName(void);
COSMOPOLITAN_C_END_ COSMOPOLITAN_C_END_
#endif /* COSMOPOLITAN_LIBC_COSMO_H_ */ #endif /* COSMOPOLITAN_LIBC_COSMO_H_ */

View file

@ -18,7 +18,6 @@
*/ */
#include "libc/dce.h" #include "libc/dce.h"
#include "libc/macros.internal.h" #include "libc/macros.internal.h"
#include "libc/notice.inc"
.section .start,"ax",@progbits .section .start,"ax",@progbits
#if SupportsXnu() && defined(__x86_64__) #if SupportsXnu() && defined(__x86_64__)

View file

@ -1,6 +1,6 @@
#ifdef _COSMO_SOURCE
#ifndef COSMOPOLITAN_LIBC_DCE_H_ #ifndef COSMOPOLITAN_LIBC_DCE_H_
#define COSMOPOLITAN_LIBC_DCE_H_ #define COSMOPOLITAN_LIBC_DCE_H_
#ifdef _COSMO_SOURCE
/*─────────────────────────────────────────────────────────────────────────────╗ /*─────────────────────────────────────────────────────────────────────────────╗
cosmopolitan § autotune » dead code elimination cosmopolitan § autotune » dead code elimination
*/ */
@ -125,5 +125,5 @@ int IsQemuUser(void);
COSMOPOLITAN_C_END_ COSMOPOLITAN_C_END_
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ #endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */
#endif /* _COSMO_SOURCE */
#endif /* COSMOPOLITAN_LIBC_DCE_H_ */ #endif /* COSMOPOLITAN_LIBC_DCE_H_ */
#endif /* _COSMO_SOURCE */

View file

View file

@ -16,13 +16,11 @@ void *dlopen(const char *, int) libcesque;
void *dlsym(void *, const char *) libcesque; void *dlsym(void *, const char *) libcesque;
int dlclose(void *) libcesque; int dlclose(void *) libcesque;
#ifdef _COSMO_SOURCE
char *cosmo_dlerror(void) libcesque; char *cosmo_dlerror(void) libcesque;
void *cosmo_dlopen(const char *, int) libcesque; void *cosmo_dlopen(const char *, int) libcesque;
void *cosmo_dlsym(void *, const char *) libcesque; void *cosmo_dlsym(void *, const char *) libcesque;
void *cosmo_dltramp(void *) libcesque; void *cosmo_dltramp(void *) libcesque;
int cosmo_dlclose(void *) libcesque; int cosmo_dlclose(void *) libcesque;
#endif
COSMOPOLITAN_C_END_ COSMOPOLITAN_C_END_
#endif /* COSMOPOLITAN_LIBC_DLFCN_H_ */ #endif /* COSMOPOLITAN_LIBC_DLFCN_H_ */

View file

@ -920,17 +920,3 @@ char *cosmo_dlerror(void) {
STRACE("dlerror() → %#s", res); STRACE("dlerror() → %#s", res);
return res; return res;
} }
#ifdef __x86_64__
static textstartup void dlopen_init() {
if (IsLinux() || IsFreebsd()) {
// switch from %fs to %gs for tls
struct CosmoTib *tib = __get_tls();
__morph_tls();
__set_tls(tib);
}
}
const void *const dlopen_ctor[] initarray = {
dlopen_init,
};
#endif

View file

@ -55,7 +55,7 @@ foreign_tramp:
mov %rax,-0xc0(%rbp) mov %rax,-0xc0(%rbp)
// switch to foreign tls // switch to foreign tls
mov %fs:0,%rax mov %gs:0x30,%rax
mov %rax,-0xc8(%rbp) mov %rax,-0xc8(%rbp)
mov __foreign+8(%rip),%rdi mov __foreign+8(%rip),%rdi
call __set_tls call __set_tls

View file

@ -22,16 +22,15 @@ COSMOPOLITAN_C_START_
* @see libc/sysv/dos2errno.sh for multimapped numbers * @see libc/sysv/dos2errno.sh for multimapped numbers
*/ */
#if defined(__GNUC__) && defined(__aarch64__) && !defined(__STRICT_ANSI__) && \ #if defined(__GNUC__) && defined(__aarch64__) && !defined(__cplusplus)
!defined(__cplusplus)
/* this header is included by 700+ files; therefore we */ /* this header is included by 700+ files; therefore we */
/* hand-roll &__get_tls()->tib_errno to avoid #include */ /* hand-roll &__get_tls()->tib_errno to avoid #include */
/* cosmopolitan uses x28 as the tls register b/c apple */ /* cosmopolitan uses x28 as the tls register b/c apple */
#define errno \ #define errno \
(*({ \ (*__extension__({ \
errno_t *__ep; \ errno_t *__ep; \
asm("sub\t%0,x28,#192-0x3c" : "=r"(__ep)); \ __asm__("sub\t%0,x28,#192-0x3c" : "=r"(__ep)); \
__ep; \ __ep; \
})) }))
#else #else
#define errno (*__errno_location()) #define errno (*__errno_location())

View file

@ -16,44 +16,28 @@
TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
PERFORMANCE OF THIS SOFTWARE. PERFORMANCE OF THIS SOFTWARE.
*/ */
#include "libc/errno.h"
#include "libc/fmt/conv.h" #include "libc/fmt/conv.h"
#include "libc/limits.h"
#include "libc/stdckdint.h"
#include "libc/str/str.h" #include "libc/str/str.h"
/** /**
* Decodes decimal integer from ASCII string. * Turns string into int.
* *
* atoi 10 22𝑐 7𝑛𝑠 * Decimal is the only radix supported. Leading whitespace (as specified
* strtol 10 37𝑐 12𝑛𝑠 * by the isspace() function) is skipped over. Unlike strtol(), the atoi
* strtoul 10 35𝑐 11𝑛𝑠 * function has undefined behavior on error and it never changes `errno`
* wcstol 10 30𝑐 10𝑛𝑠
* wcstoul 10 30𝑐 10𝑛𝑠
* strtoimax 10 80𝑐 26𝑛𝑠
* strtoumax 10 78𝑐 25𝑛𝑠
* wcstoimax 10 77𝑐 25𝑛𝑠
* wcstoumax 10 76𝑐 25𝑛𝑠
* *
* @param s is a non-null nul-terminated string * @param nptr is a non-null nul-terminated string
* @return the decoded signed saturated integer * @return the decoded signed saturated integer
* @raise ERANGE on overflow
*/ */
int atoi(const char *s) { int atoi(const char *nptr) {
int x, c, d; int x, c, d;
do c = *s++; do c = *nptr++;
while (c == ' ' || c == '\t'); while (isspace(c));
d = c == '-' ? -1 : 1; d = c == '-' ? -1 : 1;
if (c == '-' || c == '+') c = *s++; if (c == '-' || c == '+') c = *nptr++;
for (x = 0; isdigit(c); c = *s++) { for (x = 0; isdigit(c); c = *nptr++) {
if (ckd_mul(&x, x, 10) || ckd_add(&x, x, (c - '0') * d)) { x *= 10;
errno = ERANGE; x += (c - '0') * d;
if (d > 0) {
return INT_MAX;
} else {
return INT_MIN;
}
}
} }
return x; return x;
} }

View file

@ -16,34 +16,29 @@
TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
PERFORMANCE OF THIS SOFTWARE. PERFORMANCE OF THIS SOFTWARE.
*/ */
#include "libc/errno.h"
#include "libc/fmt/conv.h" #include "libc/fmt/conv.h"
#include "libc/limits.h"
#include "libc/stdckdint.h"
#include "libc/str/str.h" #include "libc/str/str.h"
/** /**
* Decodes decimal integer from ASCII string. * Turns string into long.
* *
* @param s is a non-null nul-terminated string * Decimal is the only radix supported. Leading whitespace (as specified
* by the isspace() function) is skipped over. Unlike strtol(), the atoi
* function has undefined behavior on error and it never changes `errno`
*
* @param nptr is a non-null nul-terminated string
* @return the decoded signed saturated integer * @return the decoded signed saturated integer
*/ */
long atol(const char *s) { long atol(const char *nptr) {
long x; long x;
int c, d; int c, d;
do c = *s++; do c = *nptr++;
while (c == ' ' || c == '\t'); while (isspace(c));
d = c == '-' ? -1 : 1; d = c == '-' ? -1 : 1;
if (c == '-' || c == '+') c = *s++; if (c == '-' || c == '+') c = *nptr++;
for (x = 0; isdigit(c); c = *s++) { for (x = 0; isdigit(c); c = *nptr++) {
if (ckd_mul(&x, x, 10) || ckd_add(&x, x, (c - '0') * d)) { x *= 10;
errno = ERANGE; x += (c - '0') * d;
if (d > 0) {
return LONG_MAX;
} else {
return LONG_MIN;
}
}
} }
return x; return x;
} }

View file

@ -2,8 +2,7 @@
#define COSMOPOLITAN_LIBC_FMT_DIVMOD10_H_ #define COSMOPOLITAN_LIBC_FMT_DIVMOD10_H_
forceinline uint64_t __divmod10(uint64_t __x, unsigned *__r) { forceinline uint64_t __divmod10(uint64_t __x, unsigned *__r) {
#if defined(__STRICT_ANSI__) || !defined(__GNUC__) || \ #if !defined(__GNUC__) || (defined(__OPTIMIZE__) && !defined(__OPTIMIZE_SIZE__))
(defined(__OPTIMIZE__) && !defined(__OPTIMIZE_SIZE__))
*__r = __x % 10; *__r = __x % 10;
return __x / 10; return __x / 10;
#else #else

View file

@ -1,6 +1,6 @@
#ifdef _COSMO_SOURCE
#ifndef COSMOPOLITAN_LIBC_FMT_ITOA_H_ #ifndef COSMOPOLITAN_LIBC_FMT_ITOA_H_
#define COSMOPOLITAN_LIBC_FMT_ITOA_H_ #define COSMOPOLITAN_LIBC_FMT_ITOA_H_
#ifdef _COSMO_SOURCE
COSMOPOLITAN_C_START_ COSMOPOLITAN_C_START_
#define LengthInt64 __LengthInt64 #define LengthInt64 __LengthInt64
@ -42,5 +42,5 @@ libcesque size_t uint64toarray_fixed16(uint64_t, char[hasatleast 17], uint8_t);
libcesque size_t uint64toarray_radix8(uint64_t, char[hasatleast 24]); libcesque size_t uint64toarray_radix8(uint64_t, char[hasatleast 24]);
COSMOPOLITAN_C_END_ COSMOPOLITAN_C_END_
#endif /* _COSMO_SOURCE */
#endif /* COSMOPOLITAN_LIBC_FMT_ITOA_H_ */ #endif /* COSMOPOLITAN_LIBC_FMT_ITOA_H_ */
#endif /* _COSMO_SOURCE */

View file

@ -1,6 +1,6 @@
#ifdef _COSMO_SOURCE
#ifndef COSMOPOLITAN_LIBC_FMT_LEB128_H_ #ifndef COSMOPOLITAN_LIBC_FMT_LEB128_H_
#define COSMOPOLITAN_LIBC_FMT_LEB128_H_ #define COSMOPOLITAN_LIBC_FMT_LEB128_H_
#ifdef _COSMO_SOURCE
COSMOPOLITAN_C_START_ COSMOPOLITAN_C_START_
#define sleb64 __sleb64 #define sleb64 __sleb64
@ -16,5 +16,5 @@ int unzleb64(const char *, size_t, int64_t *) libcesque;
int unuleb64(const char *, size_t, uint64_t *) libcesque; int unuleb64(const char *, size_t, uint64_t *) libcesque;
COSMOPOLITAN_C_END_ COSMOPOLITAN_C_END_
#endif /* _COSMO_SOURCE */
#endif /* COSMOPOLITAN_LIBC_FMT_LEB128_H_ */ #endif /* COSMOPOLITAN_LIBC_FMT_LEB128_H_ */
#endif /* _COSMO_SOURCE */

View file

@ -16,8 +16,7 @@
#if !defined(__GNUC__) && __cplusplus + 0 >= 201103L #if !defined(__GNUC__) && __cplusplus + 0 >= 201103L
#define typeof(x) decltype(x) #define typeof(x) decltype(x)
#elif (defined(__STRICT_ANSI__) || !defined(__GNUC__)) && \ #elif !defined(__GNUC__) && __STDC_VERSION__ + 0 < 201112
__STDC_VERSION__ + 0 < 201112
#define typeof(x) __typeof(x) #define typeof(x) __typeof(x)
#endif #endif
@ -27,7 +26,7 @@
#endif /* C++11 */ #endif /* C++11 */
#else /* __cplusplus */ #else /* __cplusplus */
#if __STDC_VERSION__ + 0 < 201112 #if __STDC_VERSION__ + 0 < 201112
#if __GNUC__ + _MSC_VER + 0 && !defined(__STRICT_ANSI__) #if __GNUC__ + _MSC_VER + 0
#define _Alignof(x) __alignof(x) #define _Alignof(x) __alignof(x)
#else #else
#define _Alignof(x) /* basically all it ever did lool */ sizeof(x) #define _Alignof(x) /* basically all it ever did lool */ sizeof(x)
@ -36,7 +35,7 @@
#endif /* __cplusplus */ #endif /* __cplusplus */
#if !defined(__cplusplus) && !defined(inline) && __STDC_VERSION__ + 0 < 199901 #if !defined(__cplusplus) && !defined(inline) && __STDC_VERSION__ + 0 < 199901
#if !defined(__STRICT_ANSI__) && (defined(__GNUC__) || defined(_MSC_VER)) #if defined(__GNUC__) || defined(_MSC_VER)
#define inline __inline #define inline __inline
#else #else
#define inline #define inline
@ -49,7 +48,7 @@
#endif #endif
#if __STDC_VERSION__ + 0 < 201112 #if __STDC_VERSION__ + 0 < 201112
#if defined(__GNUC__) && !defined(__STRICT_ANSI__) #ifdef __GNUC__
#define _Alignas(x) __attribute__((__aligned__(x))) #define _Alignas(x) __attribute__((__aligned__(x)))
#elif defined(_MSC_VER) #elif defined(_MSC_VER)
#define _Alignas(x) __declspec(align(x)) #define _Alignas(x) __declspec(align(x))
@ -58,17 +57,15 @@
#ifdef _MSC_VER #ifdef _MSC_VER
#define __builtin_unreachable() __assume(false) #define __builtin_unreachable() __assume(false)
#elif defined(__STRICT_ANSI__) || \ #elif !((__GNUC__ + 0) * 100 + (__GNUC_MINOR__ + 0) >= 405 || \
!((__GNUC__ + 0) * 100 + (__GNUC_MINOR__ + 0) >= 405 || \ defined(__clang__) || defined(__INTEL_COMPILER) || \
defined(__clang__) || defined(__INTEL_COMPILER) || \ __has_builtin(__builtin_unreachable))
__has_builtin(__builtin_unreachable))
#define __builtin_unreachable() \ #define __builtin_unreachable() \
for (;;) { \ for (;;) { \
} }
#endif #endif
#if defined(__STRICT_ANSI__) || \ #if (!defined(__llvm__) && !__has_builtin(__builtin_assume))
(!defined(__llvm__) && !__has_builtin(__builtin_assume))
#define __builtin_assume(x) \ #define __builtin_assume(x) \
do { \ do { \
if (!(x)) __builtin_unreachable(); \ if (!(x)) __builtin_unreachable(); \
@ -134,9 +131,7 @@ typedef __UINTMAX_TYPE__ uintmax_t;
typedef long double max_align_t; typedef long double max_align_t;
#ifdef _COSMO_SOURCE #ifdef _COSMO_SOURCE
#if ((__GNUC__ + 0) * 100 + (__GNUC_MINOR__ + 0) >= 406 || \ #if (__GNUC__ + 0) * 100 + (__GNUC_MINOR__ + 0) >= 406 || defined(__llvm__)
defined(__llvm__)) && \
!defined(__STRICT_ANSI__)
typedef signed __int128 int128_t; typedef signed __int128 int128_t;
typedef unsigned __int128 uint128_t; typedef unsigned __int128 uint128_t;
#endif #endif
@ -159,7 +154,7 @@ typedef struct {
#include "libc/integral/lp64arg.inc" #include "libc/integral/lp64arg.inc"
#endif #endif
#define libcesque dontthrow nocallback #define libcesque dontthrow dontcallback
#define memcpyesque libcesque #define memcpyesque libcesque
#define strlenesque libcesque nosideeffect paramsnonnull() #define strlenesque libcesque nosideeffect paramsnonnull()
#define vallocesque \ #define vallocesque \
@ -169,11 +164,7 @@ typedef struct {
#define interruptfn nocallersavedregisters forcealignargpointer #define interruptfn nocallersavedregisters forcealignargpointer
#ifndef pureconst #ifndef pureconst
#ifndef __STRICT_ANSI__
#define pureconst __attribute__((__const__)) #define pureconst __attribute__((__const__))
#else
#define pureconst
#endif
#endif #endif
#ifndef forcealign #ifndef forcealign
@ -181,15 +172,9 @@ typedef struct {
#endif #endif
#define thatispacked __attribute__((__packed__)) #define thatispacked __attribute__((__packed__))
#ifndef __STRICT_ANSI__
#define printfesque(n) __attribute__((__format__(__gnu_printf__, n, n + 1))) #define printfesque(n) __attribute__((__format__(__gnu_printf__, n, n + 1)))
#define scanfesque(n) __attribute__((__format__(__gnu_scanf__, n, n + 1))) #define scanfesque(n) __attribute__((__format__(__gnu_scanf__, n, n + 1)))
#define strftimeesque(n) __attribute__((__format__(__strftime__, n, 0))) #define strftimeesque(n) __attribute__((__format__(__strftime__, n, 0)))
#else
#define printfesque(n)
#define scanfesque(n)
#define strftimeesque(n)
#endif
#ifndef privileged #ifndef privileged
#define privileged \ #define privileged \
@ -197,8 +182,7 @@ typedef struct {
#endif #endif
#ifndef wontreturn #ifndef wontreturn
#if !defined(__STRICT_ANSI__) && \ #if (__has_attribute(__noreturn__) || \
(__has_attribute(__noreturn__) || \
(__GNUC__ + 0) * 100 + (__GNUC_MINOR__ + 0) >= 208) (__GNUC__ + 0) * 100 + (__GNUC_MINOR__ + 0) >= 208)
#define wontreturn __attribute__((__noreturn__)) #define wontreturn __attribute__((__noreturn__))
#else #else
@ -207,8 +191,7 @@ typedef struct {
#endif #endif
#ifndef nosideeffect #ifndef nosideeffect
#if !defined(__STRICT_ANSI__) && \ #if (__has_attribute(__pure__) || \
(__has_attribute(__pure__) || \
(__GNUC__ + 0) * 100 + (__GNUC_MINOR__ + 0) >= 296) (__GNUC__ + 0) * 100 + (__GNUC_MINOR__ + 0) >= 296)
#define nosideeffect __attribute__((__pure__)) #define nosideeffect __attribute__((__pure__))
#else #else
@ -219,9 +202,8 @@ typedef struct {
#ifndef dontinline #ifndef dontinline
#ifdef _MSC_VER #ifdef _MSC_VER
#define dontinline __declspec(noinline) #define dontinline __declspec(noinline)
#elif !defined(__STRICT_ANSI__) && \ #elif (__has_attribute(__noinline__) || \
(__has_attribute(__noinline__) || \ (__GNUC__ + 0) * 100 + (__GNUC_MINOR__ + 0) >= 301)
(__GNUC__ + 0) * 100 + (__GNUC_MINOR__ + 0) >= 301)
#define dontinline __attribute__((__noinline__)) #define dontinline __attribute__((__noinline__))
#else #else
#define dontinline #define dontinline
@ -229,8 +211,7 @@ typedef struct {
#endif #endif
#ifndef dontclone #ifndef dontclone
#if !defined(__STRICT_ANSI__) && \ #if (__has_attribute(__noclone__) || \
(__has_attribute(__noclone__) || \
(__GNUC__ + 0) * 100 + (__GNUC_MINOR__ + 0) >= 405) (__GNUC__ + 0) * 100 + (__GNUC_MINOR__ + 0) >= 405)
#define dontclone __attribute__((__noclone__)) #define dontclone __attribute__((__noclone__))
#else #else
@ -242,8 +223,7 @@ typedef struct {
#ifdef __cplusplus #ifdef __cplusplus
#define forceinline inline #define forceinline inline
#else #else
#if !defined(__STRICT_ANSI__) && \ #if (__GNUC__ + 0) * 100 + (__GNUC_MINOR__ + 0) >= 302
(__GNUC__ + 0) * 100 + (__GNUC_MINOR__ + 0) >= 302
#if (__GNUC__ + 0) * 100 + (__GNUC_MINOR__ + 0) >= 403 || \ #if (__GNUC__ + 0) * 100 + (__GNUC_MINOR__ + 0) >= 403 || \
!defined(__cplusplus) || \ !defined(__cplusplus) || \
(defined(__clang__) && \ (defined(__clang__) && \
@ -267,8 +247,7 @@ typedef struct {
#endif /* forceinline */ #endif /* forceinline */
#ifndef __wur #ifndef __wur
#if !defined(__STRICT_ANSI__) && \ #if ((__GNUC__ + 0) * 100 + (__GNUC_MINOR__ + 0) >= 304 || \
((__GNUC__ + 0) * 100 + (__GNUC_MINOR__ + 0) >= 304 || \
__has_attribute(__warn_unused_result__)) __has_attribute(__warn_unused_result__))
#define __wur __attribute__((__warn_unused_result__)) #define __wur __attribute__((__warn_unused_result__))
#else #else
@ -277,8 +256,7 @@ typedef struct {
#endif #endif
#ifndef nullterminated #ifndef nullterminated
#if !defined(__STRICT_ANSI__) && \ #if __has_attribute(__sentinel__) || __GNUC__ + 0 >= 4
(__has_attribute(__sentinel__) || __GNUC__ + 0 >= 4)
#define nullterminated(x) __attribute__((__sentinel__ x)) #define nullterminated(x) __attribute__((__sentinel__ x))
#else #else
#define nullterminated(x) #define nullterminated(x)
@ -295,8 +273,7 @@ typedef struct {
#endif #endif
#ifndef externinline #ifndef externinline
#if !defined(__STRICT_ANSI__) && \ #if (!defined(__cplusplus) || \
(!defined(__cplusplus) || \
(__GNUC__ + 0) * 100 + (__GNUC_MINOR__ + 0) >= 403 || \ (__GNUC__ + 0) * 100 + (__GNUC_MINOR__ + 0) >= 403 || \
(defined(__clang__) && \ (defined(__clang__) && \
(defined(__GNUC_STDC_INLINE__) || defined(__GNUC_GNU_INLINE__)))) (defined(__GNUC_STDC_INLINE__) || defined(__GNUC_GNU_INLINE__))))
@ -311,8 +288,7 @@ typedef struct {
#endif #endif
#ifndef relegated #ifndef relegated
#if !defined(__STRICT_ANSI__) && \ #if (__has_attribute(__cold__) || \
(__has_attribute(__cold__) || \
(__GNUC__ + 0) * 100 + (__GNUC_MINOR__ + 0) >= 403) (__GNUC__ + 0) * 100 + (__GNUC_MINOR__ + 0) >= 403)
#define relegated __attribute__((__cold__)) #define relegated __attribute__((__cold__))
#else #else
@ -320,8 +296,7 @@ typedef struct {
#endif #endif
#endif #endif
#if !defined(__STRICT_ANSI__) && \ #if (__has_attribute(__warning__) || \
(__has_attribute(__warning__) || \
(__GNUC__ + 0) * 100 + (__GNUC_MINOR__ + 0) >= 403) (__GNUC__ + 0) * 100 + (__GNUC_MINOR__ + 0) >= 403)
#define warnifused(s) __attribute__((__warning__(s))) #define warnifused(s) __attribute__((__warning__(s)))
#else #else
@ -329,8 +304,7 @@ typedef struct {
#endif #endif
#ifndef firstclass #ifndef firstclass
#if !defined(__STRICT_ANSI__) && \ #if (__has_attribute(__hot__) || \
(__has_attribute(__hot__) || \
(__GNUC__ + 0) * 100 + (__GNUC_MINOR__ + 0) >= 403) (__GNUC__ + 0) * 100 + (__GNUC_MINOR__ + 0) >= 403)
#define firstclass __attribute__((__hot__)) #define firstclass __attribute__((__hot__))
#else #else
@ -339,8 +313,7 @@ typedef struct {
#endif #endif
#ifndef paramsnonnull #ifndef paramsnonnull
#if !defined(__STRICT_ANSI__) && \ #if (__has_attribute(__nonnull__) || \
(__has_attribute(__nonnull__) || \
(__GNUC__ + 0) * 100 + (__GNUC_MINOR__ + 0) >= 403) (__GNUC__ + 0) * 100 + (__GNUC_MINOR__ + 0) >= 403)
#define paramsnonnull(opt_1idxs) __attribute__((__nonnull__ opt_1idxs)) #define paramsnonnull(opt_1idxs) __attribute__((__nonnull__ opt_1idxs))
#else #else
@ -355,7 +328,7 @@ typedef struct {
#endif #endif
#if __STDC_VERSION__ + 0 < 199901L && !defined(restrict) #if __STDC_VERSION__ + 0 < 199901L && !defined(restrict)
#if !defined(__STRICT_ANSI__) && !defined(__cplusplus) && \ #if !defined(__cplusplus) && \
((__GNUC__ + 0) * 100 + (__GNUC_MINOR__ + 0) >= 301 || defined(_MSC_VER)) ((__GNUC__ + 0) * 100 + (__GNUC_MINOR__ + 0) >= 301 || defined(_MSC_VER))
#define restrict __restrict__ #define restrict __restrict__
#else #else
@ -364,20 +337,19 @@ typedef struct {
#endif #endif
#endif #endif
#ifndef nocallback #ifndef dontcallback
#if !defined(__STRICT_ANSI__) && \ #if (__has_attribute(__leaf__) || \
(__has_attribute(__leaf__) || \
(!defined(__llvm__) && \ (!defined(__llvm__) && \
(__GNUC__ + 0) * 100 + (__GNUC_MINOR__ + 0) >= 406)) (__GNUC__ + 0) * 100 + (__GNUC_MINOR__ + 0) >= 406))
#define nocallback __attribute__((__leaf__)) #define dontcallback __attribute__((__leaf__))
#else #else
#define nocallback #define dontcallback
#endif #endif
#endif #endif
#ifndef dontthrow #ifndef dontthrow
#if defined(__cplusplus) && !defined(__STRICT_ANSI__) && \ #if defined(__cplusplus) && \
(__has_attribute(dontthrow) || \ (__has_attribute(dontthrow) || \
(__GNUC__ + 0) * 100 + (__GNUC_MINOR__ + 0) >= 303) (__GNUC__ + 0) * 100 + (__GNUC_MINOR__ + 0) >= 303)
#define dontthrow __attribute__((__nothrow__)) #define dontthrow __attribute__((__nothrow__))
#elif defined(_MSC_VER) #elif defined(_MSC_VER)
@ -388,8 +360,7 @@ typedef struct {
#endif #endif
#ifndef returnstwice #ifndef returnstwice
#if !defined(__STRICT_ANSI__) && \ #if (__has_attribute(__returns_twice__) || \
(__has_attribute(__returns_twice__) || \
(__GNUC__ + 0) * 100 + (__GNUC_MINOR__ + 0) >= 402) (__GNUC__ + 0) * 100 + (__GNUC_MINOR__ + 0) >= 402)
#define returnstwice __attribute__((__returns_twice__)) #define returnstwice __attribute__((__returns_twice__))
#else #else
@ -398,8 +369,7 @@ typedef struct {
#endif #endif
#ifndef nodebuginfo #ifndef nodebuginfo
#if !defined(__STRICT_ANSI__) && \ #if __has_attribute(__nodebug__) || defined(__llvm__)
(__has_attribute(__nodebug__) || defined(__llvm__))
#define nodebuginfo __attribute__((__nodebug__)) #define nodebuginfo __attribute__((__nodebug__))
#else #else
#define nodebuginfo #define nodebuginfo
@ -414,8 +384,7 @@ typedef struct {
#endif #endif
#ifndef returnsnonnull #ifndef returnsnonnull
#if !defined(__STRICT_ANSI__) && \ #if (__has_attribute(__returns_nonnull__) || \
(__has_attribute(__returns_nonnull__) || \
(__GNUC__ + 0) * 100 + (__GNUC_MINOR__ + 0) >= 409) (__GNUC__ + 0) * 100 + (__GNUC_MINOR__ + 0) >= 409)
#define returnsnonnull __attribute__((__returns_nonnull__)) #define returnsnonnull __attribute__((__returns_nonnull__))
#else #else
@ -423,8 +392,7 @@ typedef struct {
#endif #endif
#endif #endif
#if !defined(__STRICT_ANSI__) && \ #if (__has_attribute(__assume_aligned__) || \
(__has_attribute(__assume_aligned__) || \
(__GNUC__ + 0) * 100 + (__GNUC_MINOR__ + 0) >= 409) (__GNUC__ + 0) * 100 + (__GNUC_MINOR__ + 0) >= 409)
#define returnsaligned(x) __attribute__((__assume_aligned__ x)) #define returnsaligned(x) __attribute__((__assume_aligned__ x))
#else #else
@ -432,8 +400,7 @@ typedef struct {
#endif #endif
#ifndef returnspointerwithnoaliases #ifndef returnspointerwithnoaliases
#if !defined(__STRICT_ANSI__) && \ #if (__has_attribute(__malloc__) || \
(__has_attribute(__malloc__) || \
(__GNUC__ + 0) * 100 + (__GNUC_MINOR__ + 0) >= 409) (__GNUC__ + 0) * 100 + (__GNUC_MINOR__ + 0) >= 409)
#define returnspointerwithnoaliases __attribute__((__malloc__)) #define returnspointerwithnoaliases __attribute__((__malloc__))
#elif defined(_MSC_VER) #elif defined(_MSC_VER)
@ -444,8 +411,7 @@ typedef struct {
#endif #endif
#ifndef attributeallocsize #ifndef attributeallocsize
#if !defined(__STRICT_ANSI__) && \ #if (__has_attribute(__alloc_size__) || \
(__has_attribute(__alloc_size__) || \
(__GNUC__ + 0) * 100 + (__GNUC_MINOR__ + 0) >= 409) (__GNUC__ + 0) * 100 + (__GNUC_MINOR__ + 0) >= 409)
#define attributeallocsize(x) __attribute__((__alloc_size__ x)) #define attributeallocsize(x) __attribute__((__alloc_size__ x))
#else #else
@ -454,8 +420,7 @@ typedef struct {
#endif #endif
#ifndef attributeallocalign #ifndef attributeallocalign
#if !defined(__STRICT_ANSI__) && \ #if (__has_attribute(__alloc_align__) || \
(__has_attribute(__alloc_align__) || \
(__GNUC__ + 0) * 100 + (__GNUC_MINOR__ + 0) >= 409) (__GNUC__ + 0) * 100 + (__GNUC_MINOR__ + 0) >= 409)
#define attributeallocalign(x) __attribute__((__alloc_align__ x)) #define attributeallocalign(x) __attribute__((__alloc_align__ x))
#else #else
@ -478,8 +443,7 @@ typedef struct {
#ifdef _COSMO_SOURCE #ifdef _COSMO_SOURCE
#ifndef dontinstrument #ifndef dontinstrument
#if !defined(__STRICT_ANSI__) && \ #if (__has_attribute(__no_instrument_function__) || \
(__has_attribute(__no_instrument_function__) || \
(__GNUC__ + 0) * 100 + (__GNUC_MINOR__ + 0) >= 204) (__GNUC__ + 0) * 100 + (__GNUC_MINOR__ + 0) >= 204)
#if ((__GNUC__ + 0) >= 7 && !defined(__chibicc__)) || \ #if ((__GNUC__ + 0) >= 7 && !defined(__chibicc__)) || \
__has_attribute(__patchable_function_entry__) __has_attribute(__patchable_function_entry__)
@ -495,8 +459,7 @@ typedef struct {
#endif #endif
#ifndef mayalias #ifndef mayalias
#if !defined(__STRICT_ANSI__) && \ #if (__has_attribute(__may_alias__) || \
(__has_attribute(__may_alias__) || \
(__GNUC__ + 0) * 100 + (__GNUC_MINOR__ + 0) >= 303) (__GNUC__ + 0) * 100 + (__GNUC_MINOR__ + 0) >= 303)
#define mayalias __attribute__((__may_alias__)) #define mayalias __attribute__((__may_alias__))
#else #else
@ -505,35 +468,26 @@ typedef struct {
#endif #endif
#ifndef dontoptimize #ifndef dontoptimize
#ifndef __STRICT_ANSI__
#if defined(__llvm__) || __has_attribute(__optnone__) #if defined(__llvm__) || __has_attribute(__optnone__)
#define dontoptimize __attribute__((__optnone__)) #define dontoptimize __attribute__((__optnone__))
#elif (__GNUC__ + 0) * 100 + (__GNUC_MINOR__ + 0) >= 407 || \ #elif (__GNUC__ + 0) * 100 + (__GNUC_MINOR__ + 0) >= 407 || \
__has_attribute(__optimize__) __has_attribute(__optimize__)
#define dontoptimize __attribute__((__optimize__(0))) #define dontoptimize __attribute__((__optimize__(0)))
#endif #endif
#else
#define dontoptimize
#endif
#endif #endif
#ifndef optimizesize #ifndef optimizesize
#ifndef __STRICT_ANSI__
#if (__GNUC__ + 0) * 100 + (__GNUC_MINOR__ + 0) >= 407 || \ #if (__GNUC__ + 0) * 100 + (__GNUC_MINOR__ + 0) >= 407 || \
__has_attribute(__optimize__) __has_attribute(__optimize__)
#define optimizesize __attribute__((__optimize__("s"))) #define optimizesize __attribute__((__optimize__("s")))
#elif defined(__llvm__) || __has_attribute(__optnone__) #elif defined(__llvm__) || __has_attribute(__optnone__)
#define optimizesize __attribute__((__optnone__)) #define optimizesize __attribute__((__optnone__))
#endif #endif
#else
#define optimizesize
#endif
#endif #endif
#ifndef optimizespeed #ifndef optimizespeed
/* warning: corrupts frame pointer; only use on leaf functions */ /* warning: corrupts frame pointer; only use on leaf functions */
#if !defined(__STRICT_ANSI__) && \ #if ((__GNUC__ + 0) * 100 + (__GNUC_MINOR__ + 0) >= 407 || \
((__GNUC__ + 0) * 100 + (__GNUC_MINOR__ + 0) >= 407 || \
__has_attribute(__optimize__)) __has_attribute(__optimize__))
#define optimizespeed __attribute__((__optimize__(3))) #define optimizespeed __attribute__((__optimize__(3)))
#else #else
@ -542,8 +496,7 @@ typedef struct {
#endif #endif
#ifndef unrollloops #ifndef unrollloops
#if !defined(__STRICT_ANSI__) && \ #if ((__GNUC__ + 0) * 100 + (__GNUC_MINOR__ + 0) >= 407 || \
((__GNUC__ + 0) * 100 + (__GNUC_MINOR__ + 0) >= 407 || \
__has_attribute(__optimize__)) __has_attribute(__optimize__))
#define unrollloops __attribute__((__optimize__("unroll-loops"))) #define unrollloops __attribute__((__optimize__("unroll-loops")))
#else #else
@ -552,8 +505,7 @@ typedef struct {
#endif #endif
#ifndef _Microarchitecture #ifndef _Microarchitecture
#if !defined(__STRICT_ANSI__) && \ #if (__has_attribute(__target__) || \
(__has_attribute(__target__) || \
(__GNUC__ + 0) * 100 + (__GNUC_MINOR__ + 0) >= 404) (__GNUC__ + 0) * 100 + (__GNUC_MINOR__ + 0) >= 404)
#define _Microarchitecture(march) __attribute__((__target__(march))) #define _Microarchitecture(march) __attribute__((__target__(march)))
#else #else
@ -572,64 +524,48 @@ typedef struct {
#endif #endif
#if ((__GNUC__ + 0) * 100 + (__GNUC_MINOR__ + 0) >= 408 || \ #if ((__GNUC__ + 0) * 100 + (__GNUC_MINOR__ + 0) >= 408 || \
__has_attribute(__no_sanitize_address__)) && \ __has_attribute(__no_sanitize_address__))
!defined(__STRICT_ANSI__)
#define dontasan __attribute__((__no_sanitize_address__)) #define dontasan __attribute__((__no_sanitize_address__))
#else #else
#define dontasan #define dontasan
#endif #endif
#if ((__GNUC__ + 0) * 100 + (__GNUC_MINOR__ + 0) >= 408 || \ #if ((__GNUC__ + 0) * 100 + (__GNUC_MINOR__ + 0) >= 408 || \
__has_attribute(__no_sanitize_undefined__)) && \ __has_attribute(__no_sanitize_undefined__))
!defined(__STRICT_ANSI__)
#define dontubsan __attribute__((__no_sanitize_undefined__)) #define dontubsan __attribute__((__no_sanitize_undefined__))
#else #else
#define dontubsan #define dontubsan
#endif #endif
#ifdef __STRICT_ANSI__
void abort(void) wontreturn;
#define notpossible abort()
#else
#ifdef __x86_64__ #ifdef __x86_64__
#define notpossible \ #define notpossible \
do { \ do { \
asm("nop\n\t" \ __asm__("nop\n\t" \
"ud2\n\t" \ "ud2\n\t" \
"nop"); \ "nop"); \
__builtin_unreachable(); \ __builtin_unreachable(); \
} while (0) } while (0)
#elif defined(__aarch64__) #elif defined(__aarch64__)
#define notpossible \ #define notpossible \
do { \ do { \
asm("udf\t#0\n\t" \ __asm__("udf\t#0\n\t" \
"nop"); \ "nop"); \
__builtin_unreachable(); \ __builtin_unreachable(); \
} while (0) } while (0)
#else #else
#define notpossible __builtin_trap() #define notpossible __builtin_trap()
#endif #endif
#endif
#define donothing \ #define donothing \
do { \ do { \
} while (0) } while (0)
#ifndef __STRICT_ANSI__
#define textstartup _Section(".text.startup") #define textstartup _Section(".text.startup")
#define textexit _Section(".text.exit") #define textexit _Section(".text.exit")
#define textreal _Section(".text.real") #define textreal _Section(".text.real")
#define texthead _Section(".text.head") #define texthead _Section(".text.head")
#define textwindows _Section(".text.windows") #define textwindows _Section(".text.windows")
#define antiquity _Section(".text.antiquity") #define antiquity _Section(".text.antiquity")
#else
#define textstartup
#define textexit
#define textreal
#define texthead
#define textwindows
#define antiquity
#endif
#ifdef __llvm__ #ifdef __llvm__
#define __builtin_ia32_movntdq(x, y) (*(x) = (y)) #define __builtin_ia32_movntdq(x, y) (*(x) = (y))
@ -639,81 +575,71 @@ void abort(void) wontreturn;
#define _Section(s) __attribute__((__section__(s))) #define _Section(s) __attribute__((__section__(s)))
#endif #endif
#if defined(__x86_64__) && !defined(__llvm__) #ifndef __llvm__
#define initarray _Section(".init_array,\"a\",@init_array #") #pragma GCC diagnostic ignored "-Wformat=0" /* todo: patch gcc */
#pragma GCC diagnostic ignored "-Wbuiltin-declaration-mismatch"
#pragma GCC diagnostic warning "-Wunknown-pragmas"
#else #else
#define initarray _Section(".init_array") #pragma GCC diagnostic ignored "-Wformat"
#pragma GCC diagnostic ignored "-Wconstant-logical-operand" /* what */
#pragma GCC diagnostic ignored "-Wunknown-warning-option"
#pragma GCC diagnostic ignored "-Wunknown-pragmas"
#pragma GCC diagnostic ignored "-Wstring-plus-int" /* features 4 losers */
#pragma GCC diagnostic ignored "-Wkeyword-compat" /* c++ upgrade */
#pragma GCC diagnostic ignored "-Wuser-defined-literals" /* reserved for me */
#endif #endif
#pragma GCC diagnostic ignored "-Wformat" /* todo: patch gcc */
#pragma GCC diagnostic ignored "-Wformat-extra-args" /* todo: patch gcc */ #pragma GCC diagnostic ignored "-Wformat-extra-args" /* todo: patch gcc */
#pragma GCC diagnostic ignored "-Wunused-function" /* contradicts dce */ #pragma GCC diagnostic ignored "-Wunused-function" /* contradicts dce */
#pragma GCC diagnostic ignored "-Wunused-const-variable" /* sooo ridiculous */ #pragma GCC diagnostic ignored "-Wunused-const-variable" /* sooo ridiculous */
#pragma GCC diagnostic ignored "-Wbuiltin-declaration-mismatch"
#ifndef __cplusplus #ifndef __cplusplus
#pragma GCC diagnostic ignored "-Wold-style-definition" /* orwellian bullsh */ #pragma GCC diagnostic ignored "-Wold-style-definition" /* orwellian bullsh */
#endif #endif
#ifndef __STRICT_ANSI__
#ifdef __x86_64__ #ifdef __x86_64__
#define DebugBreak() asm("int3") #define DebugBreak() __asm__("int3")
#else #else
#define DebugBreak() __builtin_trap() #define DebugBreak() __builtin_trap()
#endif #endif
#else
#define DebugBreak() (void)0
#endif
#endif /* _COSMO_SOURCE */ #endif /* _COSMO_SOURCE */
#ifndef __STRICT_ANSI__ #define __veil(CONSTRAINT, EXPRESSION) \
#define __veil(CONSTRAINT, EXPRESSION) \ __extension__({ \
({ \ autotype(EXPRESSION) VeiledValue = (EXPRESSION); \
autotype(EXPRESSION) VeiledValue = (EXPRESSION); \ __asm__("" : "=" CONSTRAINT ""(VeiledValue) : "0"(VeiledValue)); \
asm("" : "=" CONSTRAINT ""(VeiledValue) : "0"(VeiledValue)); \ VeiledValue; \
VeiledValue; \
}) })
#else
#define __veil(CONSTRAINT, EXPRESSION) (EXPRESSION)
#endif
#ifndef __STRICT_ANSI__ #define __conceal(CONSTRAINT, EXPRESSION) \
#define __conceal(CONSTRAINT, EXPRESSION) \ __extension__({ \
({ \ autotype(EXPRESSION) VeiledValue = (EXPRESSION); \
autotype(EXPRESSION) VeiledValue = (EXPRESSION); \ __asm__ volatile("" : "=" CONSTRAINT ""(VeiledValue) : "0"(VeiledValue)); \
asm volatile("" : "=" CONSTRAINT ""(VeiledValue) : "0"(VeiledValue)); \ VeiledValue; \
VeiledValue; \
}) })
#else
#define __conceal(CONSTRAINT, EXPRESSION) (EXPRESSION)
#endif
#ifndef __STRICT_ANSI__ #define __expropriate(EXPRESSION) \
#define __expropriate(EXPRESSION) \ __extension__({ \
({ \ __asm__ volatile("" ::"g"(EXPRESSION) : "memory"); \
asm volatile("" ::"g"(EXPRESSION) : "memory"); \ 0; \
0; \
}) })
#else
#define __expropriate(EXPRESSION) (EXPRESSION)
#endif
#if !defined(__STRICT_ANSI__) && !defined(__APPLE__) && defined(__x86_64__) #if !defined(__APPLE__) && defined(__x86_64__)
#define __yoink(SYMBOL) \ #define __yoink(SYMBOL) \
asm(".section .yoink\n\tnopl\t%0\n\t.previous" : : "m"(SYMBOL)) __asm__(".section .yoink\n\tnopl\t%0\n\t.previous" : : "m"(SYMBOL))
#elif defined(__aarch64__) #elif defined(__aarch64__)
#define __yoink(SYMBOL) \ #define __yoink(SYMBOL) \
asm(".section .yoink\n\tb\t%0\n\t.previous" : : "m"(SYMBOL)) __asm__(".section .yoink\n\tb\t%0\n\t.previous" : : "m"(SYMBOL))
#else #else
#define __yoink(SYMBOL) (void)0 #define __yoink(SYMBOL) (void)0
#endif #endif
#if !defined(__STRICT_ANSI__) && !defined(__APPLE__) && defined(__x86_64__) #if !defined(__APPLE__) && defined(__x86_64__)
#define __static_yoink(SYMBOLSTR) \ #define __static_yoink(SYMBOLSTR) \
asm(".section .yoink\n\tnopl\t\"" SYMBOLSTR "\"\n\t.previous") __asm__(".section .yoink\n\tnopl\t\"" SYMBOLSTR "\"\n\t.previous")
#elif defined(__aarch64__) #elif defined(__aarch64__)
#define __static_yoink(SYMBOLSTR) \ #define __static_yoink(SYMBOLSTR) \
asm(".section .yoink\n\tb\t\"" SYMBOLSTR "\"\n\t.previous") __asm__(".section .yoink\n\tb\t\"" SYMBOLSTR "\"\n\t.previous")
#else #else
#define __static_yoink(SYMBOLSTR) #define __static_yoink(SYMBOLSTR)
#endif #endif
@ -745,5 +671,22 @@ void abort(void) wontreturn;
#define __funline static inline #define __funline static inline
#endif #endif
#if defined(__x86_64__) && (defined(__GNUC__) || defined(__llvm__)) && \
!defined(__chibicc__) && defined(__OPTIMIZE__)
#define __target_clones(x) __attribute__((__target_clones__(x ",default")))
#else
#define __target_clones(x)
#endif
#if !defined(TINY) && !defined(__AVX__)
#define __vex __target_clones("avx")
#else
#define __vex
#endif
#define __notice(sym, str) \
__attribute__((__section__(".notice"), __aligned__(1))) const char sym[] = \
"\n\n" str
#define MACHINE_CODE_ANALYSIS_BEGIN_ #define MACHINE_CODE_ANALYSIS_BEGIN_
#define MACHINE_CODE_ANALYSIS_END_ #define MACHINE_CODE_ANALYSIS_END_

View file

@ -3,8 +3,8 @@
#endif #endif
#define __COSMOPOLITAN_MAJOR__ 3 #define __COSMOPOLITAN_MAJOR__ 3
#define __COSMOPOLITAN_MINOR__ 2 #define __COSMOPOLITAN_MINOR__ 3
#define __COSMOPOLITAN_PATCH__ 4 #define __COSMOPOLITAN_PATCH__ 2
#define __COSMOPOLITAN__ \ #define __COSMOPOLITAN__ \
(100000000 * __COSMOPOLITAN_MAJOR__ + 1000000 * __COSMOPOLITAN_MINOR__ + \ (100000000 * __COSMOPOLITAN_MAJOR__ + 1000000 * __COSMOPOLITAN_MINOR__ + \
__COSMOPOLITAN_PATCH__) __COSMOPOLITAN_PATCH__)

View file

@ -74,11 +74,15 @@ o//libc/intrin/memmove.o: private \
-fno-toplevel-reorder -fno-toplevel-reorder
o//libc/intrin/bzero.o \ o//libc/intrin/bzero.o \
o//libc/intrin/strlen.o \
o//libc/intrin/strchr.o \
o//libc/intrin/memchr.o \
o//libc/intrin/memrchr.o \
o//libc/intrin/memcmp.o \ o//libc/intrin/memcmp.o \
o//libc/intrin/memset.o \ o//libc/intrin/memset.o \
o//libc/intrin/memmove.o: private \ o//libc/intrin/memmove.o: private \
CFLAGS += \ CFLAGS += \
-O2 -finline -O2 -finline -foptimize-sibling-calls
o/$(MODE)/libc/intrin/bzero.o \ o/$(MODE)/libc/intrin/bzero.o \
o/$(MODE)/libc/intrin/memcmp.o \ o/$(MODE)/libc/intrin/memcmp.o \
@ -86,6 +90,13 @@ o/$(MODE)/libc/intrin/memmove.o: private \
CFLAGS += \ CFLAGS += \
-fpie -fpie
o/$(MODE)/libc/intrin/x86.o: private \
CFLAGS += \
-ffreestanding \
-fno-jump-tables \
-fpatchable-function-entry=0 \
-Os
# these assembly files are safe to build on aarch64 # these assembly files are safe to build on aarch64
o/$(MODE)/libc/intrin/aarch64/%.o: libc/intrin/aarch64/%.S o/$(MODE)/libc/intrin/aarch64/%.o: libc/intrin/aarch64/%.S
@$(COMPILE) -AOBJECTIFY.S $(OBJECTIFY.S) $(OUTPUT_OPTION) -c $< @$(COMPILE) -AOBJECTIFY.S $(OBJECTIFY.S) $(OUTPUT_OPTION) -c $<

View file

@ -3,7 +3,7 @@
Optimized Routines Optimized Routines
Copyright (c) 1999-2022, Arm Limited. Copyright (c) 2018-2024, Arm Limited.
Permission is hereby granted, free of charge, to any person obtaining Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the a copy of this software and associated documentation files (the
@ -26,14 +26,10 @@
*/ */
#include "libc/intrin/aarch64/asmdefs.internal.h" #include "libc/intrin/aarch64/asmdefs.internal.h"
.yoink arm_optimized_routines_notice
#define __memchr_aarch64 memchr #define __memchr_aarch64 memchr
.ident "\n\n\
Optimized Routines (MIT License)\n\
Copyright 2022 ARM Limited\n"
.include "libc/disclaimer.inc"
/* Assumptions: /* Assumptions:
* *
* ARMv8-a, AArch64 * ARMv8-a, AArch64

View file

@ -3,7 +3,7 @@
Optimized Routines Optimized Routines
Copyright (c) 1999-2022, Arm Limited. Copyright (c) 2018-2024, Arm Limited.
Permission is hereby granted, free of charge, to any person obtaining Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the a copy of this software and associated documentation files (the
@ -26,15 +26,11 @@
*/ */
#include "libc/intrin/aarch64/asmdefs.internal.h" #include "libc/intrin/aarch64/asmdefs.internal.h"
.yoink arm_optimized_routines_notice
#define __memcpy_aarch64_simd memcpy #define __memcpy_aarch64_simd memcpy
#define __memmove_aarch64_simd memmove #define __memmove_aarch64_simd memmove
.ident "\n\n\
Optimized Routines (MIT License)\n\
Copyright 2022 ARM Limited\n"
.include "libc/disclaimer.inc"
/* Assumptions: /* Assumptions:
* *
* ARMv8-a, AArch64, Advanced SIMD, unaligned accesses. * ARMv8-a, AArch64, Advanced SIMD, unaligned accesses.
@ -84,11 +80,12 @@ ENTRY (__memcpy_aarch64_simd)
PTR_ARG (1) PTR_ARG (1)
SIZE_ARG (2) SIZE_ARG (2)
add srcend, src, count add srcend, src, count
add dstend, dstin, count
cmp count, 128 cmp count, 128
b.hi L(copy_long) b.hi L(copy_long)
add dstend, dstin, count
cmp count, 32 cmp count, 32
b.hi L(copy32_128) b.hi L(copy32_128)
nop
/* Small copies: 0..32 bytes. */ /* Small copies: 0..32 bytes. */
cmp count, 16 cmp count, 16
@ -99,6 +96,18 @@ ENTRY (__memcpy_aarch64_simd)
str B_q, [dstend, -16] str B_q, [dstend, -16]
ret ret
.p2align 4
/* Medium copies: 33..128 bytes. */
L(copy32_128):
ldp A_q, B_q, [src]
ldp C_q, D_q, [srcend, -32]
cmp count, 64
b.hi L(copy128)
stp A_q, B_q, [dstin]
stp C_q, D_q, [dstend, -32]
ret
.p2align 4
/* Copy 8-15 bytes. */ /* Copy 8-15 bytes. */
L(copy16): L(copy16):
tbz count, 3, L(copy8) tbz count, 3, L(copy8)
@ -108,7 +117,6 @@ L(copy16):
str A_h, [dstend, -8] str A_h, [dstend, -8]
ret ret
.p2align 3
/* Copy 4-7 bytes. */ /* Copy 4-7 bytes. */
L(copy8): L(copy8):
tbz count, 2, L(copy4) tbz count, 2, L(copy4)
@ -118,6 +126,19 @@ L(copy8):
str B_lw, [dstend, -4] str B_lw, [dstend, -4]
ret ret
/* Copy 65..128 bytes. */
L(copy128):
ldp E_q, F_q, [src, 32]
cmp count, 96
b.ls L(copy96)
ldp G_q, H_q, [srcend, -64]
stp G_q, H_q, [dstend, -64]
L(copy96):
stp A_q, B_q, [dstin]
stp E_q, F_q, [dstin, 32]
stp C_q, D_q, [dstend, -32]
ret
/* Copy 0..3 bytes using a branchless sequence. */ /* Copy 0..3 bytes using a branchless sequence. */
L(copy4): L(copy4):
cbz count, L(copy0) cbz count, L(copy0)
@ -131,33 +152,11 @@ L(copy4):
L(copy0): L(copy0):
ret ret
.p2align 4 .p2align 3
/* Medium copies: 33..128 bytes. */
L(copy32_128):
ldp A_q, B_q, [src]
ldp C_q, D_q, [srcend, -32]
cmp count, 64
b.hi L(copy128)
stp A_q, B_q, [dstin]
stp C_q, D_q, [dstend, -32]
ret
.p2align 4
/* Copy 65..128 bytes. */
L(copy128):
ldp E_q, F_q, [src, 32]
cmp count, 96
b.ls L(copy96)
ldp G_q, H_q, [srcend, -64]
stp G_q, H_q, [dstend, -64]
L(copy96):
stp A_q, B_q, [dstin]
stp E_q, F_q, [dstin, 32]
stp C_q, D_q, [dstend, -32]
ret
/* Copy more than 128 bytes. */ /* Copy more than 128 bytes. */
L(copy_long): L(copy_long):
add dstend, dstin, count
/* Use backwards copy if there is an overlap. */ /* Use backwards copy if there is an overlap. */
sub tmp1, dstin, src sub tmp1, dstin, src
cmp tmp1, count cmp tmp1, count
@ -194,6 +193,9 @@ L(copy64_from_end):
stp A_q, B_q, [dstend, -32] stp A_q, B_q, [dstend, -32]
ret ret
.p2align 4
nop
/* Large backwards copy for overlapping copies. /* Large backwards copy for overlapping copies.
Copy 16 bytes and then align srcend to 16-byte alignment. */ Copy 16 bytes and then align srcend to 16-byte alignment. */
L(copy_long_backwards): L(copy_long_backwards):

View file

@ -3,7 +3,7 @@
Optimized Routines Optimized Routines
Copyright (c) 1999-2022, Arm Limited. Copyright (c) 2018-2024, Arm Limited.
Permission is hereby granted, free of charge, to any person obtaining Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the a copy of this software and associated documentation files (the
@ -26,14 +26,10 @@
*/ */
#include "libc/intrin/aarch64/asmdefs.internal.h" #include "libc/intrin/aarch64/asmdefs.internal.h"
.yoink arm_optimized_routines_notice
#define __memrchr_aarch64 memrchr #define __memrchr_aarch64 memrchr
.ident "\n\n\
Optimized Routines (MIT License)\n\
Copyright 2022 ARM Limited\n"
.include "libc/disclaimer.inc"
/* Assumptions: /* Assumptions:
* *
* ARMv8-a, AArch64, Advanced SIMD. * ARMv8-a, AArch64, Advanced SIMD.

View file

@ -3,7 +3,7 @@
Optimized Routines Optimized Routines
Copyright (c) 1999-2022, Arm Limited. Copyright (c) 2018-2024, Arm Limited.
Permission is hereby granted, free of charge, to any person obtaining Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the a copy of this software and associated documentation files (the
@ -26,14 +26,10 @@
*/ */
#include "libc/intrin/aarch64/asmdefs.internal.h" #include "libc/intrin/aarch64/asmdefs.internal.h"
.yoink arm_optimized_routines_notice
#define __memset_aarch64 memset #define __memset_aarch64 memset
.ident "\n\n\
Optimized Routines (MIT License)\n\
Copyright 2022 ARM Limited\n"
.include "libc/disclaimer.inc"
/* Assumptions: /* Assumptions:
* *
* ARMv8-a, AArch64, Advanced SIMD, unaligned accesses. * ARMv8-a, AArch64, Advanced SIMD, unaligned accesses.

View file

@ -3,7 +3,7 @@
Optimized Routines Optimized Routines
Copyright (c) 1999-2022, Arm Limited. Copyright (c) 2018-2024, Arm Limited.
Permission is hereby granted, free of charge, to any person obtaining Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the a copy of this software and associated documentation files (the
@ -26,14 +26,10 @@
*/ */
#include "libc/intrin/aarch64/asmdefs.internal.h" #include "libc/intrin/aarch64/asmdefs.internal.h"
.yoink arm_optimized_routines_notice
#define __stpcpy_aarch64 stpcpy #define __stpcpy_aarch64 stpcpy
.ident "\n\n\
Optimized Routines (MIT License)\n\
Copyright 2022 ARM Limited\n"
.include "libc/disclaimer.inc"
/* Assumptions: /* Assumptions:
* *
* ARMv8-a, AArch64, Advanced SIMD. * ARMv8-a, AArch64, Advanced SIMD.

View file

@ -3,7 +3,7 @@
Optimized Routines Optimized Routines
Copyright (c) 1999-2022, Arm Limited. Copyright (c) 2018-2024, Arm Limited.
Permission is hereby granted, free of charge, to any person obtaining Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the a copy of this software and associated documentation files (the
@ -26,15 +26,11 @@
*/ */
#include "libc/intrin/aarch64/asmdefs.internal.h" #include "libc/intrin/aarch64/asmdefs.internal.h"
.yoink arm_optimized_routines_notice
#define __strchr_aarch64 strchr #define __strchr_aarch64 strchr
#define __index_aarch64 index #define __index_aarch64 index
.ident "\n\n\
Optimized Routines (MIT License)\n\
Copyright 2022 ARM Limited\n"
.include "libc/disclaimer.inc"
/* Assumptions: /* Assumptions:
* *
* ARMv8-a, AArch64 * ARMv8-a, AArch64

View file

@ -3,7 +3,7 @@
Optimized Routines Optimized Routines
Copyright (c) 1999-2022, Arm Limited. Copyright (c) 2018-2024, Arm Limited.
Permission is hereby granted, free of charge, to any person obtaining Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the a copy of this software and associated documentation files (the
@ -26,14 +26,10 @@
*/ */
#include "libc/intrin/aarch64/asmdefs.internal.h" #include "libc/intrin/aarch64/asmdefs.internal.h"
.yoink arm_optimized_routines_notice
#define __strchrnul_aarch64 strchrnul #define __strchrnul_aarch64 strchrnul
.ident "\n\n\
Optimized Routines (MIT License)\n\
Copyright 2022 ARM Limited\n"
.include "libc/disclaimer.inc"
/* Assumptions: /* Assumptions:
* *
* ARMv8-a, AArch64 * ARMv8-a, AArch64

View file

@ -3,7 +3,7 @@
Optimized Routines Optimized Routines
Copyright (c) 1999-2022, Arm Limited. Copyright (c) 2018-2024, Arm Limited.
Permission is hereby granted, free of charge, to any person obtaining Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the a copy of this software and associated documentation files (the
@ -26,14 +26,10 @@
*/ */
#include "libc/intrin/aarch64/asmdefs.internal.h" #include "libc/intrin/aarch64/asmdefs.internal.h"
.yoink arm_optimized_routines_notice
#define __strcmp_aarch64 strcmp #define __strcmp_aarch64 strcmp
.ident "\n\n\
Optimized Routines (MIT License)\n\
Copyright 2022 ARM Limited\n"
.include "libc/disclaimer.inc"
/* Assumptions: /* Assumptions:
* *
* ARMv8-a, AArch64. * ARMv8-a, AArch64.

View file

@ -3,7 +3,7 @@
Optimized Routines Optimized Routines
Copyright (c) 1999-2022, Arm Limited. Copyright (c) 2018-2024, Arm Limited.
Permission is hereby granted, free of charge, to any person obtaining Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the a copy of this software and associated documentation files (the
@ -26,14 +26,10 @@
*/ */
#include "libc/intrin/aarch64/asmdefs.internal.h" #include "libc/intrin/aarch64/asmdefs.internal.h"
.yoink arm_optimized_routines_notice
#define __strcpy_aarch64 strcpy #define __strcpy_aarch64 strcpy
.ident "\n\n\
Optimized Routines (MIT License)\n\
Copyright 2022 ARM Limited\n"
.include "libc/disclaimer.inc"
/* Assumptions: /* Assumptions:
* *
* ARMv8-a, AArch64, Advanced SIMD. * ARMv8-a, AArch64, Advanced SIMD.

View file

@ -3,7 +3,7 @@
Optimized Routines Optimized Routines
Copyright (c) 1999-2022, Arm Limited. Copyright (c) 2018-2024, Arm Limited.
Permission is hereby granted, free of charge, to any person obtaining Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the a copy of this software and associated documentation files (the
@ -26,14 +26,10 @@
*/ */
#include "libc/intrin/aarch64/asmdefs.internal.h" #include "libc/intrin/aarch64/asmdefs.internal.h"
.yoink arm_optimized_routines_notice
#define __strlen_aarch64 strlen #define __strlen_aarch64 strlen
.ident "\n\n\
Optimized Routines (MIT License)\n\
Copyright 2022 ARM Limited\n"
.include "libc/disclaimer.inc"
/* Assumptions: /* Assumptions:
* *
* ARMv8-a, AArch64, Advanced SIMD, unaligned accesses. * ARMv8-a, AArch64, Advanced SIMD, unaligned accesses.

View file

@ -3,7 +3,7 @@
Optimized Routines Optimized Routines
Copyright (c) 1999-2022, Arm Limited. Copyright (c) 2018-2024, Arm Limited.
Permission is hereby granted, free of charge, to any person obtaining Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the a copy of this software and associated documentation files (the
@ -26,14 +26,10 @@
*/ */
#include "libc/intrin/aarch64/asmdefs.internal.h" #include "libc/intrin/aarch64/asmdefs.internal.h"
.yoink arm_optimized_routines_notice
#define __strncmp_aarch64 strncmp #define __strncmp_aarch64 strncmp
.ident "\n\n\
Optimized Routines (MIT License)\n\
Copyright 2022 ARM Limited\n"
.include "libc/disclaimer.inc"
/* Assumptions: /* Assumptions:
* *
* ARMv8-a, AArch64. * ARMv8-a, AArch64.

View file

@ -3,7 +3,7 @@
Optimized Routines Optimized Routines
Copyright (c) 1999-2022, Arm Limited. Copyright (c) 2018-2024, Arm Limited.
Permission is hereby granted, free of charge, to any person obtaining Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the a copy of this software and associated documentation files (the
@ -26,14 +26,10 @@
*/ */
#include "libc/intrin/aarch64/asmdefs.internal.h" #include "libc/intrin/aarch64/asmdefs.internal.h"
.yoink arm_optimized_routines_notice
#define __strnlen_aarch64 strnlen #define __strnlen_aarch64 strnlen
.ident "\n\n\
Optimized Routines (MIT License)\n\
Copyright 2022 ARM Limited\n"
.include "libc/disclaimer.inc"
/* Assumptions: /* Assumptions:
* *
* ARMv8-a, AArch64, Advanced SIMD. * ARMv8-a, AArch64, Advanced SIMD.

View file

@ -3,7 +3,7 @@
Optimized Routines Optimized Routines
Copyright (c) 1999-2022, Arm Limited. Copyright (c) 2018-2024, Arm Limited.
Permission is hereby granted, free of charge, to any person obtaining Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the a copy of this software and associated documentation files (the
@ -26,15 +26,11 @@
*/ */
#include "libc/intrin/aarch64/asmdefs.internal.h" #include "libc/intrin/aarch64/asmdefs.internal.h"
.yoink arm_optimized_routines_notice
#define __strrchr_aarch64 strrchr #define __strrchr_aarch64 strrchr
#define __rindex_aarch64 rindex #define __rindex_aarch64 rindex
.ident "\n\n\
Optimized Routines (MIT License)\n\
Copyright 2022 ARM Limited\n"
.include "libc/disclaimer.inc"
/* Assumptions: /* Assumptions:
* *
* ARMv8-a, AArch64 * ARMv8-a, AArch64

3
libc/intrin/armopt.c Normal file
View file

@ -0,0 +1,3 @@
__notice(arm_optimized_routines_notice, "\
Optimized Routines (MIT License)\n\
Copyright 2022 ARM Limited");

3
libc/intrin/chromium.c Normal file
View file

@ -0,0 +1,3 @@
__notice(chromium_notice, "\
Chromium (BSD-3 License)\n\
Copyright 2017 The Chromium Authors");

View file

@ -33,10 +33,6 @@ void __cxa_unlock(void) {
pthread_mutex_unlock(&__cxa_lock_obj); pthread_mutex_unlock(&__cxa_lock_obj);
} }
static textstartup void __cxa_init() { __attribute__((__constructor__(60))) static textstartup void __cxa_init() {
pthread_atfork(__cxa_lock, __cxa_unlock, __cxa_wipe); pthread_atfork(__cxa_lock, __cxa_unlock, __cxa_wipe);
} }
const void *const __cxa_ctor[] initarray = {
__cxa_init,
};

View file

@ -17,6 +17,8 @@
PERFORMANCE OF THIS SOFTWARE. PERFORMANCE OF THIS SOFTWARE.
*/ */
#include "libc/intrin/describebacktrace.internal.h" #include "libc/intrin/describebacktrace.internal.h"
#include "libc/intrin/kprintf.h"
#include "libc/intrin/weaken.h"
#include "libc/log/libfatal.internal.h" #include "libc/log/libfatal.internal.h"
#include "libc/nexgen32e/stackframe.h" #include "libc/nexgen32e/stackframe.h"
@ -28,6 +30,9 @@ dontinstrument const char *(DescribeBacktrace)(char buf[N],
char *pe = p + N; char *pe = p + N;
bool gotsome = false; bool gotsome = false;
while (fr) { while (fr) {
if (_weaken(kisdangerous) && _weaken(kisdangerous)(fr)) {
break;
}
if (p + 16 + 1 + 1 <= pe) { if (p + 16 + 1 + 1 <= pe) {
if (gotsome) { if (gotsome) {
*p++ = ' '; *p++ = ' ';

View file

@ -1,6 +1,6 @@
#ifdef _COSMO_SOURCE
#ifndef COSMOPOLITAN_LIBC_INTRIN_DLL_H_ #ifndef COSMOPOLITAN_LIBC_INTRIN_DLL_H_
#define COSMOPOLITAN_LIBC_INTRIN_DLL_H_ #define COSMOPOLITAN_LIBC_INTRIN_DLL_H_
#ifdef _COSMO_SOURCE
#define dll_make_first __dll_make_first #define dll_make_first __dll_make_first
#define dll_make_last __dll_make_last #define dll_make_last __dll_make_last
#define dll_remove __dll_remove #define dll_remove __dll_remove
@ -55,5 +55,5 @@ void dll_make_first(struct Dll **, struct Dll *) paramsnonnull((1)) libcesque;
void dll_splice_after(struct Dll *, struct Dll *) paramsnonnull((1)) libcesque; void dll_splice_after(struct Dll *, struct Dll *) paramsnonnull((1)) libcesque;
COSMOPOLITAN_C_END_ COSMOPOLITAN_C_END_
#endif /* _COSMO_SOURCE */
#endif /* COSMOPOLITAN_LIBC_INTRIN_DLL_H_ */ #endif /* COSMOPOLITAN_LIBC_INTRIN_DLL_H_ */
#endif /* _COSMO_SOURCE */

2
libc/intrin/fbclibm.c Normal file
View file

@ -0,0 +1,2 @@
__notice(freebsd_complex_notice, "FreeBSD Complex Math (BSD-2 License)\n\
Copyright (c) 2012 Stephen Montgomery-Smith <stephen@FreeBSD.ORG>");

Some files were not shown because too many files have changed in this diff Show more