Compare commits

...
56 Commits
Author SHA1 Message Date
Justine Tunney c8383f25b4 Release Cosmopolitan v3.3.2 2024-02-27 09:15:59 -08:00
Justine Tunney 64a9e6fe56 Fix compiler runtime for _Float16 type 2024-02-27 09:06:23 -08:00
Justine Tunney 0ef36489c8 Walk back most uses of __STRICT_ANSI__ 2024-02-27 04:09:49 -08:00
Justine Tunney 7c7bf4bb90 Release Cosmopolitan v3.3.1 2024-02-27 00:31:36 -08:00
Justine Tunney 592f6ebc20 Make quality improvements
- Write some more unit tests
- memcpy() on ARM is now faster
- Address the Musl complex math FIXME comments
- Some libm funcs like pow() now support setting errno
- Import the latest and greatest math functions from ARM
- Use more accurate atan2f() and log1pf() implementations
- atoi() and atol() will no longer saturate or clobber errno
2024-02-25 19:08:43 -08:00
Justine Tunney af8f2bd19f Shave 4kb off each binary 2024-02-25 11:11:34 -08:00
Justine Tunney 38bceaeb8f Give up on making clock_nanosleep() precise
Multiple projects I care about make the assumption that this isn't a
system call that sleeps for a particular number of nanonseconds, but
rather a function that parks processes on kernel scheduler quantums.
Anyone who wants the old behavior should use cosmo_clock_nanosleep()
2024-02-24 10:17:47 -08:00
Ivan Komarov 99f0491f04 Fix invalid XNU binaries generated by apelink in some edge cases (#1106)
* Fix `if...fi` generation in the generated APE shell script

A shell will fail with a syntax error on an empty `if` or `else` body.
That is, neither of these is allowed:

    # Empty `if`
    if [ ... ]; then
    fi

    # Empty `else`
    if [ ... ]; then
    ...
    else
    fi

There were two places where `apelink` could generate problematic `if`'s:

1. The XNU shell generation for aarch64 binaries when no loaders (either
   binary or source) are provided. They can't assimilate, so the resulting
   `else` body becomes empty.
   There is actually a code path guarded by the `gotsome` variable that
   inserts an extra `true` in this case, but the variable was never
   initialized, so in practice this code path didn't activate in my
   tests. This is fixed by initializing the variable.
2. The loader extraction code when no loaders are provided and XNU
   support is requested. This is fixed by adding a simliar code path
   that prevents an empty body from being generated.

* Update the apelink manual after commit d53c335

The `-s` option changed its meaning, but the docs weren't updated.
2024-02-23 08:11:27 -08:00
Justine Tunney e72a88ea70 Make fixups for libcrypt 2024-02-23 07:39:44 -08:00
Ivan Komarov 9b4701b3bc Don't include <crypt.h> from <stdlib.h> (#1112) 2024-02-23 07:18:35 -08:00
Ivan Komarov f7ff515961 *scanf() fixes to make TeX work (#1109)
* Fix reading the same symbol twice when using `{f,}scanf()`

PR #924 appears to use `unget()` subtly incorrectly when parsing
floating point numbers. The rest of the code only uses `unget()`
immediately followed by `goto Done;` to return back the symbol that
can't possibly belong to the directive we're processing.

With floating-point, however, the ungot characters could very well
be valid for the *next* directive, so we will essentially read them
twice. It can't be seen in `sscanf()` tests because `unget()` is a
no-op there, but the test I added for `fscanf()` fails like this:

        ...
        EXPECT_EQ(0xDEAD, i1)
                need 57005 (or 0xdead) =
                 got 908973 (or 0x000ddead)
        ...
        EXPECT_EQ(0xBEEF, i2)
                need 48879 (or 0xbeef) =
                 got 769775 (or 0x000bbeef)

This means we read 0xDDEAD instead of 0xDEAD and 0xBBEEF instead of
0xBEEF. I checked that both musl and glibc read 0xDEAD/0xBEEF, as
expected.

Fix the failing test by removing the unneeded `unget()` calls.

* Don't read invalid floating-point numbers in `*scanf()`

Currently, we just ignore any errors from `strtod()`. They can
happen either because no valid float can be parsed at all, or
because the state machine recognizes only a prefix of a valid
floating-point number.

Fix this by making sure `strtod()` parses everything we recognized,
provided it's non-empty. This requires to pop the last character
off the FP buffer, which is supposed to be parsed by the next
`*scanf()` directive.

* Make `%c` parsing in `*scanf()` respect the C standard

Currently, `%c`-style directives always succeed even if there
are actually fewer characters in the input than requested.

Before the fix, the added test fails like this:

        ...
        EXPECT_EQ(2, sscanf("ab", "%c %c %c", &c2, &c3, &c4))
                need 2 (or 0x02 or '\2' or ENOENT) =
                 got 3 (or 0x03 or '\3' or ESRCH)
        ...
        EXPECT_EQ(0, sscanf("abcd", "%5c", s2))
                need 0 (or 0x0 or '\0') =
                 got 1 (or 0x01 or '\1' or EPERM)

musl and glibc pass this test.
2024-02-23 07:15:30 -08:00
Justine Tunney 3afe3a3646 Fix broken link 2024-02-23 07:11:44 -08:00
Justine Tunney b4faaa7c57 Relax style guide 2024-02-23 06:55:37 -08:00
Justine Tunney c4991e53ac Document copyright policy exceptions 2024-02-23 06:53:46 -08:00
Justine Tunney ad3944a3b6 Support any HTTP method
It's now possible to use redbean Fetch() with arbitrary HTTP methods,
e.g. LIST which is used by Hashicorp. There's an eight char limit and
uppercase canonicalization still happens. This change also includes a
better function for launching a browser tab, that won't deadlock on a
headless workstation running Debian.

Closes #1107
2024-02-22 14:12:18 -08:00
Justine Tunney 29eac8e2a2 Fix regression in logger functions
The recent release broke things so that the logger wasn't logging by
default. This ensures that `__log_file` initializes in correct order
2024-02-22 14:08:20 -08:00
Justine Tunney a5a3e78fcf Make ftrace/strace C APIs work with cosmocc 2024-02-22 12:13:16 -08:00
Justine Tunney e9a756e78b Make --ftrace more crash proof with foreign code
Sometimes we need to interact with code that wasn't compiled using
`-fno-omit-frame-pointer`. For example, if a function pointer gets
passed and called by a foreign function, linked by cosmo_dlopen().
Function call tracing will now detect backtrace pointer corruption
and simply reduce the indentation level back to zero, as a result.
2024-02-22 11:06:31 -08:00
Justine Tunney 38af54a2dd Fix GCC version in cosmocc wrapper script
See #1111
2024-02-21 19:16:39 -08:00
Justine Tunney 77a92f517b Introduce getcpu() system call from glibc 2024-02-21 18:17:20 -08:00
Justine Tunney 3eb405e0e2 Resurrect <windows.h> as <windowsesque.h> 2024-02-21 16:41:11 -08:00
Justine Tunney 68b9479f0c Make cosmo.h work a little better 2024-02-21 16:40:09 -08:00
Justine Tunney d9df41c4d5 Add example email to CONTRIBUTING.md 2024-02-21 16:36:52 -08:00
Justine Tunney fc3c536ec2 Make --ftrace work better with cosmocc
This change causes cosmocc to use -fno-inline-functions-called-once by
default, unless -Os or -finline-functions-called-once is defined. This
is important since I believe it generally makes code go faster, and it
most importantly makes --ftrace output much more understandable, since
the trace will be more likely to reflect the actual shape of the code.
We've always used this flag in the mono repo when ftracing is enabled,
but it slipped my mind to incorporate this into the cosmocc toolchain.
2024-02-21 13:20:21 -08:00
Justine Tunney 77ddf4cb07 Fix fixupobj regression on MacOS ARM64 2024-02-21 12:13:54 -08:00
Justine Tunney 4d018306b3 Fix MODE=optlinux build 2024-02-20 14:24:56 -08:00
Justine Tunney b3bb93d1d9 Fix MODE=opt build 2024-02-20 14:12:12 -08:00
Justine Tunney 980af27bbf Fix documentation build 2024-02-20 13:40:46 -08:00
Justine Tunney 957c61cbbf Release Cosmopolitan v3.3
This change upgrades to GCC 12.3 and GNU binutils 2.42. The GNU linker
appears to have changed things so that only a single de-duplicated str
table is present in the binary, and it gets placed wherever the linker
wants, regardless of what the linker script says. To cope with that we
need to stop using .ident to embed licenses. As such, this change does
significant work to revamp how third party licenses are defined in the
codebase, using `.section .notice,"aR",@progbits`.

This new GCC 12.3 toolchain has support for GNU indirect functions. It
lets us support __target_clones__ for the first time. This is used for
optimizing the performance of libc string functions such as strlen and
friends so far on x86, by ensuring AVX systems favor a second codepath
that uses VEX encoding. It shaves some latency off certain operations.
It's a useful feature to have for scientific computing for the reasons
explained by the test/libcxx/openmp_test.cc example which compiles for
fifteen different microarchitectures. Thanks to the upgrades, it's now
also possible to use newer instruction sets, such as AVX512FP16, VNNI.

Cosmo now uses the %gs register on x86 by default for TLS. Doing it is
helpful for any program that links `cosmo_dlopen()`. Such programs had
to recompile their binaries at startup to change the TLS instructions.
That's not great, since it means every page in the executable needs to
be faulted. The work of rewriting TLS-related x86 opcodes, is moved to
fixupobj.com instead. This is great news for MacOS x86 users, since we
previously needed to morph the binary every time for that platform but
now that's no longer necessary. The only platforms where we need fixup
of TLS x86 opcodes at runtime are now Windows, OpenBSD, and NetBSD. On
Windows we morph TLS to point deeper into the TIB, based on a TlsAlloc
assignment, and on OpenBSD/NetBSD we morph %gs back into %fs since the
kernels do not allow us to specify a value for the %gs register.

OpenBSD users are now required to use APE Loader to run Cosmo binaries
and assimilation is no longer possible. OpenBSD kernel needs to change
to allow programs to specify a value for the %gs register, or it needs
to stop marking executable pages loaded by the kernel as mimmutable().

This release fixes __constructor__, .ctor, .init_array, and lastly the
.preinit_array so they behave the exact same way as glibc.

We no longer use hex constants to define math.h symbols like M_PI.
2024-02-20 13:27:59 -08:00
BONNAURE Olivier d3ff48c63f [Redbean] Feature / OnError(status, message) hook (#1103) 2024-02-14 01:55:50 -08:00
Justine Tunney 2ab9e9f7fd Make improvements
- Introduce portable sched_getcpu() api
- Support GCC's __target_clones__ feature
- Make fma() go faster on x86 in default mode
- Remove some asan checks from core libraries
- WinMain() now ensures $HOME and $USER are defined
2024-02-12 10:23:00 -08:00
Ivan Komarov d5225a693b libc headers: make <complex.h> work, add struct ipv6_mreq (#1100)
1. `libc/isystem/complex.h` (included when you do `#include <complex.h>`)
   defines `_COMPLEX_H`, and then proceeds to include `libc/complex.h`,
   which contains the actual complex-related declarations. However, they
   are *also* guarded by `_COMPLEX_H` and hence effectively ignored.
   Fix this by changing `_COMPLEX_H` to `COSMOPOLITAN_LIBC_COMPLEX_H_`,
   which is consistent with what the other headers (such as `math.h`) do.
2. Cosmopolitan could only support IPv4 multicast requests for sockets,
   since a declaration for `struct ipv6_mreq` was missing. Add support
   for IPv6, too, by adding the missing declaration.
2024-02-05 17:22:56 -05:00
Paul Kulchenko c72904b2f6 Fix redbean Fetch redirect with relative URL (#1034) 2024-02-02 10:02:29 -05:00
Justine Tunney 616717fa82 Fine tune OpenMP some more 2024-01-30 06:30:24 -08:00
Justine Tunney 369aebfc48 Make improvements
- Let OpenMP be usable via cosmocc
- Let libunwind be usable via cosmocc
- Make X86_HAVE(AVXVNNI) work correctly
- Avoid using MAP_GROWSDOWN on qemu-aarch64
- Introduce in6addr_any and in6addr_loopback
- Have thread stacks use MAP_GROWSDOWN by default
- Ask OpenMP to not use filesystem to manage threads
- Make NI_MAXHOST and NI_MAXSERV available w/o _GNU_SOURCE
2024-01-29 16:31:58 -08:00
Justine Tunney 5f8e9f14c1 Add OpenMP support 2024-01-28 22:39:02 -08:00
Justine Tunney c1e18e7903 Restore MODE=dbg support
We recently broke MODE=dbg support when we added C++ exception support.
This change adds the missing UBSAN interfaces, needed to get it working
again. Some of the ASAN checking in the SJLJ guts needed to be disabled
since I doubt anyone's combined the two features until now.
2024-01-26 23:07:18 -08:00
Justine Tunney f27808c4d2 Remove feature for embedding blink in ape scripts
Embedding Blink builds in Cosmo executables was a failed experiment. It
turned out to be easier than expected to let the mono repo have support
for multiple architectures. Blink still works great; it's supported and
recommended; just please use it as a separate program. For example, you
can use Blink to run Cosmo binaries on architectures like i486 / s390x.
2024-01-26 22:30:56 -08:00
Justine Tunney 2719080986 Add program for printing Windows network dev info 2024-01-26 22:29:23 -08:00
Trung Nguyen 33418f6742 libc: Fix __cxa_thread_atexit prototype (#1088)
The first parameter should be a function pointer.

Otherwise, this would conflict with the definition provided by
`libcxxabi`.
2024-01-22 10:23:28 -08:00
Trung Nguyen 83a8686c06 tool/cosmocc: Properly handle dependency output (#1091)
a2753de contains some regressions, causing `fixupobj` to be
inappropriately suppressed when `-MD` or `-MMD` is passed.

This commit reverts most changes by a2753de, and:
- Treats all invocations of the compiler with `-M` and `-MM` as with the
`cpp` intent, since these flags imply `-E`.
- Handle the dependency output path specified by `-MF`.
  + This is trivial for `cosmocross` since the script does not throw
  objects to and from temporary directories.
  + For `cosmocc`, the file names are calculated based on the `-MF`
  value provided by the user. If this flag is not specified, the script
  generates the file name based on the output file using GCC rules.
  Then, before calling the real compilers, an additional `-MF` flag is
  passed to override the dependency outputs with mangled file names.
2024-01-22 10:22:16 -08:00
Justine Tunney 8ab3a545c6 Increase build memory quota
If you install qemu-user from apt then glibc links a lot of address
space bloat that causes pthread_create() to ENOMEM (a.k.a. EAGAIN).
Boosting the virtual memory quota from 512m to 2048m will hopefully
future proof the build for the future, as Linux distros get fatter.
Please note this only applies to MODE=aarch64 on x86_64 builds when
you're using QEMU from Debian/Ubuntu rather than installing the one
cosmo provides in third_party/qemu/qemu-aarch64.gz. This change may
also be useful to people who are using the host compiler toolchain.
2024-01-22 10:02:30 -08:00
Justine Tunney 8ebe2e9020 Fix assertion error in pthread_create() 2024-01-22 10:02:30 -08:00
BONNAURE Olivier 51cd83f674 Add Curve25519 method in help.txt + add new specs file (#1096) 2024-01-21 06:58:48 -08:00
Justine Tunney 39b0a9c03e Fix scanf() %n off by one at eof
Fixes #1094
2024-01-20 15:06:16 -08:00
Justine Tunney d50064a779 Add Curve25519() API to Redbean 2024-01-20 01:06:19 -08:00
Justine Tunney 1226eb7a5e Fix gcc warning 2024-01-18 16:48:02 -08:00
Trung Nguyen 8834dde0c2 libcxx: Add missing implementation source files (#1089)
Added the implementation for `std::bad_any_cast` from upstream
`any.cpp`, and `std::bad_variant_access` from upstream `variant.cpp`.

This fixes missing `vtable` and `typeinfo` symbols when trying to link
code referencing these exception types.
2024-01-18 08:20:25 -08:00
Justine Tunney 1ef63eb206 Retire third_party/quickjs/
QuickJS cosmocc binaries are now being distributed on
https://bellard.org/quickjs/
2024-01-17 12:35:46 -08:00
Brian 08793aa143 Make ... optional in .args (#1086) 2024-01-15 16:20:50 -08:00
Trung Nguyen 6db1200a7e libc: Fix cxxabi.h header (#1087)
- `__cxa_*` runtime functions are expected to be in the `abi` namespace,
which is currently an alias for `__cxxabiv1`.
- Rely on the header provided by `libcxxabi` for functions that we do
not implement ourselves anymore.
2024-01-15 11:50:38 -08:00
Trung Nguyen a2753de7fd tool/cosmocc: Do not run fixupobj for text output (#1084)
Some compiler flags (such as -E or -MM) instruct GCC to only run the
preprocessor and produce certain text files.

In this case, we do not want to run `fixupobj` and make the tool fail
because the input is not an ELF64 binary.
2024-01-15 07:16:13 -08:00
Jōshin 6715b670b1 Skip the CAS on new_pos < 0 (#1080) 2024-01-12 21:08:28 -08:00
Justine Tunney fd75fd1467 Make std::pair trivial 2024-01-09 09:51:59 -08:00
Justine Tunney 5d80e8dbf6 Add more Intel microarchitectures 2024-01-09 01:54:26 -08:00
Justine Tunney eeb20775d2 Add dontthrow attribute to most libc functions
This will help C++ code that uses exceptions to be tinier. For example,
this change shaves away 1000 lines of assembly code from LLVM's libcxx,
which is 0.7% of all assembly instructions in the entire library.
2024-01-09 01:26:03 -08:00
1965 changed files with 126006 additions and 116536 deletions

No files matched your search

+1 -2
View File
@@ -48,11 +48,10 @@
"notpossible=",
"thatispacked=",
"dontthrow=",
"nocallback=",
"dontcallback=",
"relegated=",
"hidden=",
"textstartup=",
"initarray=",
"returnsnonnull=",
"returnspointerwithnoaliases=",
"printfesque(x)=",
+41 -35
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
Justine Tunney <jtunney@gmail.com> stating that you intend to assign her
the copyright to the changes you contribute to Cosmopolitan. This only
applies to the code you *choose* to contribute. It only has to happen
once. The email should be sent from an email address associated with
your identity. Your email should link to your pull request.
the copyright to the changes you contribute to Cosmopolitan. It only
needs to happen once. This only applies to the code you *choose* to
contribute. The email should be sent from an email address associated
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 ([email protected])
> **To**: Justine Tunney ([email protected])
> **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
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
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
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
[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)
[tool/emacs/cosmo-format.el](tool/emacs/cosmo-format.el).
+14 -10
View File
@@ -101,7 +101,6 @@ XARGS ?= xargs -P4 -rs8000
DOT ?= dot
CLANG = clang
TMPDIR = o/tmp
AR = build/bootstrap/ar.com
CP = build/bootstrap/cp.com
RM = build/bootstrap/rm.com -f
@@ -116,7 +115,7 @@ ZIPCOPY = build/bootstrap/zipcopy.com
PECHECK = build/bootstrap/pecheck.com
FIXUPOBJ = build/bootstrap/fixupobj.com
MKDIR = build/bootstrap/mkdir.com -p
COMPILE = build/bootstrap/compile.com -V9 -P4096 $(QUOTA)
COMPILE = build/bootstrap/compile.com -V9 -M2048m -P8192 $(QUOTA)
IGNORE := $(shell $(MKDIR) $(TMPDIR))
@@ -137,7 +136,7 @@ ARCH = aarch64
HOSTS ?= pi studio freebsdarm
else
ARCH = x86_64
HOSTS ?= freebsd rhel7 xnu win10 openbsd netbsd
HOSTS ?= freebsd rhel7 xnu openbsd netbsd win10
endif
ZIPOBJ_FLAGS += -a$(ARCH)
@@ -150,9 +149,9 @@ export MODE
export SOURCE_DATE_EPOCH
export TMPDIR
COSMOCC = .cosmocc/3.2
COSMOCC = .cosmocc/3.3.2
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
CC = $(TOOLCHAIN)gcc
@@ -207,9 +206,8 @@ endif
.UNVEIL += \
libc/integral \
libc/stdbool.h \
libc/disclaimer.inc \
rwc:/dev/shm \
rx:cosmocc \
rx:.cosmocc \
rx:build/bootstrap \
r:build/portcosmo.h \
/proc/stat \
@@ -286,6 +284,7 @@ include third_party/readline/BUILD.mk # │
include third_party/libunwind/BUILD.mk # |
include third_party/libcxxabi/BUILD.mk # |
include third_party/libcxx/BUILD.mk # │
include third_party/openmp/BUILD.mk # │
include third_party/double-conversion/BUILD.mk # │
include third_party/pcre/BUILD.mk # │
include third_party/less/BUILD.mk # │
@@ -298,7 +297,9 @@ include third_party/nsync/testing/BUILD.mk
include libc/testlib/BUILD.mk
include tool/viz/lib/BUILD.mk
include tool/args/BUILD.mk
include test/math/BUILD.mk
include test/posix/BUILD.mk
include test/libcxx/BUILD.mk
include test/tool/args/BUILD.mk
include third_party/linenoise/BUILD.mk
include third_party/maxmind/BUILD.mk
@@ -318,7 +319,6 @@ include third_party/argon2/BUILD.mk
include third_party/smallz4/BUILD.mk
include third_party/sqlite3/BUILD.mk
include third_party/mbedtls/test/BUILD.mk
include third_party/quickjs/BUILD.mk
include third_party/lz4cli/BUILD.mk
include third_party/zip/BUILD.mk
include third_party/xxhash/BUILD.mk
@@ -441,6 +441,7 @@ COSMOPOLITAN_OBJECTS = \
THIRD_PARTY_GETOPT \
LIBC_LOG \
LIBC_TIME \
THIRD_PARTY_OPENMP \
THIRD_PARTY_MUSL \
THIRD_PARTY_ZLIB_GZ \
THIRD_PARTY_LIBCXXABI \
@@ -479,6 +480,7 @@ COSMOPOLITAN_OBJECTS = \
LIBC_STR \
LIBC_SYSV \
LIBC_INTRIN \
LIBC_NT_BCRYPTPRIMITIVES \
LIBC_NT_KERNEL32 \
LIBC_NEXGEN32E
@@ -522,6 +524,8 @@ COSMOCC_PKGS = \
THIRD_PARTY_AARCH64 \
THIRD_PARTY_LIBCXX \
THIRD_PARTY_LIBCXXABI \
THIRD_PARTY_LIBUNWIND \
THIRD_PARTY_OPENMP \
THIRD_PARTY_INTEL
o/$(MODE)/cosmopolitan.a: \
@@ -552,9 +556,9 @@ o/cosmopolitan.html: private .UNSANDBOXED = 1
o/cosmopolitan.html: \
o/$(MODE)/third_party/chibicc/chibicc.com.dbg \
$(filter-out %.s,$(foreach x,$(COSMOPOLITAN_OBJECTS),$($(x)_SRCS))) \
$(filter-out %.cc,$(SRCS)) \
$(filter-out %.cpp,$(filter-out %.cc,$(SRCS))) \
$(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 \
-fno-common -include libc/integral/normalize.inc -o $@ \
-DCOSMO @$(TMPDIR)/$(subst /,_,$@)
+1 -11
View File
@@ -157,7 +157,6 @@ o/$(MODE)/ape/ape-no-modify-self.o: \
ape/ape.S \
ape/ape.h \
ape/macros.internal.h \
ape/notice.inc \
ape/relocations.h \
ape/ape.internal.h \
libc/dce.h \
@@ -173,8 +172,6 @@ o/$(MODE)/ape/ape-no-modify-self.o: \
libc/runtime/mman.internal.h \
libc/runtime/pc.internal.h \
libc/sysv/consts/prot.h \
ape/blink-linux-aarch64.gz \
ape/blink-xnu-aarch64.gz \
o/$(MODE)/ape/ape.elf
@$(COMPILE) \
-AOBJECTIFY.S \
@@ -187,7 +184,6 @@ o/$(MODE)/ape/ape-copy-self.o: \
ape/ape.S \
ape/ape.h \
ape/macros.internal.h \
ape/notice.inc \
ape/relocations.h \
ape/ape.internal.h \
libc/dce.h \
@@ -202,9 +198,7 @@ o/$(MODE)/ape/ape-copy-self.o: \
libc/runtime/e820.internal.h \
libc/runtime/mman.internal.h \
libc/runtime/pc.internal.h \
libc/sysv/consts/prot.h \
ape/blink-linux-aarch64.gz \
ape/blink-xnu-aarch64.gz
libc/sysv/consts/prot.h
@$(COMPILE) \
-AOBJECTIFY.S \
$(OBJECTIFY.S) \
@@ -263,10 +257,6 @@ endif
o/$(MODE)/ape/ape.o: ape/ape.S
@$(COMPILE) -AOBJECTIFY.S $(OBJECTIFY.S) $(OUTPUT_OPTION) -c $<
o/$(MODE)/ape/ape.o: \
ape/blink-linux-aarch64.gz \
ape/blink-xnu-aarch64.gz
o/$(MODE)/ape/ape.lds: \
ape/ape.lds \
ape/macros.internal.h \
+10 -5
View File
@@ -89,10 +89,12 @@ SECTIONS {
*(.ubsan.data)
}
.comment : {
__comment_start = .;
KEEP(*(.comment))
.notice : {
__notices = .;
KEEP(*(.notice))
BYTE(0);
BYTE(10);
BYTE(10);
}
.eh_frame_hdr : {
@@ -157,8 +159,11 @@ SECTIONS {
.init_array : {
__init_array_start = .;
KEEP(*(SORT_BY_INIT_PRIORITY(.init_array.*) SORT_BY_INIT_PRIORITY(.ctors.*)))
KEEP(*(.init_array EXCLUDE_FILE(*crtbegin.o *crtbegin?.o *crtend.o *crtend?.o ) .ctors))
KEEP(*(.preinit_array))
KEEP(*(SORT_BY_INIT_PRIORITY(.init_array.*)
SORT_BY_INIT_PRIORITY(.ctors.*)))
KEEP(*(.init_array))
KEEP(*(.ctors))
__init_array_end = .;
}
+21 -17
View File
@@ -39,7 +39,7 @@
/* maximum path size that cosmo can take */
#define PATHSIZE (PATH_MAX < 1024 ? PATH_MAX : 1024)
#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 {
int magic;
@@ -96,11 +96,16 @@ struct Syslib {
long (*sem_trywait)(int *);
long (*getrlimit)(int, struct rlimit *);
long (*setrlimit)(int, const struct rlimit *);
// v6 (2023-11-03)
/* v6 (2023-11-03) */
void *(*dlopen)(const char *, int);
void *(*dlsym)(void *, const char *);
int (*dlclose)(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
@@ -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;
if (prot1 & PROT_EXEC) {
#ifdef SIP_DISABLED
// if sip is disabled then we can load the executable segments
// off the binary into memory without needing to copy anything
// which provides considerably better performance for building
/* if sip is disabled then we can load the executable segments
off the binary into memory without needing to copy anything
which provides considerably better performance for building */
rc = sys_mmap(addr, size, prot1, flags, fd, p[i].p_offset & -pagesz);
if (rc < 0) {
if (rc == -EPERM) {
@@ -674,12 +679,12 @@ __attribute__((__noreturn__)) static void Spawn(const char *exe, int fd,
}
}
#else
// the issue is that if sip is enabled then, attempting to map
// it with exec permission will cause xnu to phone home a hash
// of the entire file to apple intelligence as a one time cost
// which is literally minutes for executables holding big data
// since there's no public apple api for detecting sip we read
// as the default strategy which is slow but it works for both
/* the issue is that if sip is enabled then, attempting to map
it with exec permission will cause xnu to phone home a hash
of the entire file to apple intelligence as a one time cost
which is literally minutes for executables holding big data
since there's no public apple api for detecting sip we read
as the default strategy which is slow but it works for both */
rc = sys_mmap(addr, size, (prot1 = PROT_READ | PROT_WRITE),
MAP_PRIVATE | MAP_FIXED | MAP_ANONYMOUS, -1, 0);
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,
* which prevents our program header overlap check from needlessly
* failing later on; it also shaves away a microsecond of latency,
* since every program header requires invoking at least 1 syscall
*/
/* merge adjacent loads that are contiguous with equal protection,
which prevents our program header overlap check from needlessly
failing later on; it also shaves away a microsecond of latency,
since every program header requires invoking at least 1 syscall */
for (i = 0; i + 1 < e->e_phnum;) {
if (p[i].p_type == PT_LOAD && p[i + 1].p_type == PT_LOAD &&
((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.dlclose = dlclose;
M->lib.dlerror = dlerror;
M->lib.pthread_cpu_number_np = pthread_cpu_number_np;
/* getenv("_") is close enough to at_execfn */
execfn = 0;
+20 -53
View File
@@ -33,7 +33,6 @@
│ αcτµαlly pδrταblε εxεcµταblε § program header │
╚─────────────────────────────────────────────────────────────────────────────*/
#include "ape/macros.internal.h"
#include "ape/notice.inc"
#include "ape/relocations.h"
#include "libc/calls/metalfile.internal.h"
#include "libc/dce.h"
@@ -700,36 +699,9 @@ apesh: .ascii "\n@\n#'\"\n" // sixth edition shebang
#endif /* APE_NO_MODIFY_SELF */
.ascii "exit $?\n"
.ascii "fi\n" // x86_64
// ...
// decentralized section (.apesh)
// ...
.ascii "PHDRS='' <<'@'\n"
.endobj apesh
// elf program headers get inserted here
// because they need to be in the first 4096 bytes
.section .emushprologue,"a",@progbits
emush: .ascii "\n@\n#'\"\n"
.ascii "s=$(uname -s 2>/dev/null) || s=Darwin\n"
// our script is running on a non-x86_64 architecture
// 1. `dd` out the appropriate blink vm blob
// 2. gunzip the blink virtual machine executable
// 3. relaunch this program inside the blink vm
.ascii "o=\"$(command -v \"$0\")\"\n"
.ascii "e=\"${TMPDIR:-${HOME:-.}}/.ape-blink-1.0.0\"\n"
.previous
// ...
// decentralized section (.emush)
// - __static_yoink("blink_linux_aarch64"); // for raspberry pi
// - __static_yoink("blink_xnu_aarch64"); // is apple silicon
// ...
.section .emushepilogue,"a",@progbits
.ascii "echo \"$0: this ape binary lacks $m support\" >&2\n"
.rept 16
.ascii "exit 127\n"
.endr
.ascii "echo error: this ape binary only supports x86_64 >&2\n"
.ascii "exit 1\n"
.previous
.endobj apesh
#ifdef APE_LOADER
.section .ape.loader,"a",@progbits
@@ -1799,49 +1771,31 @@ kernel: movabs $ape_stack_vaddr,%rsp
.type ape_text_nops,@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
.type ape_pad_head,@object
.hidden ape_pad_head
ape_pad_head:
.previous
.section .ape.pad.text,"a",@progbits
.type ape_pad_text,@object
.hidden ape_pad_text
ape_pad_text:
.previous
.section .ape.pad.privileged,"a",@progbits
.type ape_pad_privileged,@object
.hidden ape_pad_privileged
ape_pad_privileged:
.previous
.section .ape.pad.data,"a",@progbits
.type ape_pad_data,@object
.hidden ape_pad_data
ape_pad_data:
.previous
#if SupportsWindows()
.section .idata.ro,"a",@progbits
.type ape_idata_ro,@object
.hidden ape_idata_ro
ape_idata_ro:
.previous
#endif /* SupportsWindows() */
.section .dataprologue,"aw",@progbits
@@ -1849,32 +1803,45 @@ ape_idata_ro:
.globl __data_start
.hidden __data_start
__data_start:
.previous
.section .dataepilogue,"aw",@progbits
.type __data_end,@object
.globl __data_end
.hidden __data_end
__data_end:
.previous
.section .bssprologue,"aw",@nobits
.type __bss_start,@object
.globl __bss_start
.hidden __bss_start
__bss_start:
.previous
.section .bssepilogue,"aw",@nobits
.type __bss_end,@object
.globl __bss_end
.hidden __bss_end
__bss_end:
.previous
.section .fstls,"awT",@nobits
.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

+19 -45
View File
@@ -229,7 +229,6 @@ SECTIONS {
/* Real Mode */
KEEP(*(.head))
KEEP(*(.apesh))
KEEP(*(.text.head))
/* Executable & Linkable Format */
@@ -238,10 +237,6 @@ SECTIONS {
KEEP(*(.elf.phdrs))
ape_phdrs_end = .;
KEEP(*(.emushprologue))
KEEP(*(.emush))
KEEP(*(.emushepilogue))
/* OpenBSD */
. = ALIGN(. != 0 ? __SIZEOF_POINTER__ : 0);
ape_note = .;
@@ -287,12 +282,9 @@ SECTIONS {
KEEP(*(SORT_BY_NAME(.init.*)))
KEEP(*(.init))
KEEP(*(.initepilogue))
KEEP(*(.pltprologue))
*(.plt)
KEEP(*(.pltepilogue))
KEEP(*(.pltgotprologue))
*(.plt.got)
KEEP(*(.pltgotepilogue))
*(.iplt)
*(.text.startup .text.startup.*)
*(.text.exit .text.exit.*)
*(.text.unlikely .text.*_unlikely .text.unlikely.*)
@@ -301,7 +293,6 @@ SECTIONS {
KEEP(*(.textwindowsprologue))
*(.text.windows)
KEEP(*(.textwindowsepilogue))
KEEP(*(.blink))
*(SORT_BY_ALIGNMENT(.text.modernity))
*(SORT_BY_ALIGNMENT(.text.modernity.*))
*(SORT_BY_ALIGNMENT(.text.hot))
@@ -329,7 +320,7 @@ SECTIONS {
/*BEGIN: Read Only Data */
.rodata . : {
.rodata ALIGN(CONSTANT(COMMONPAGESIZE)) : {
KEEP(*(.rodata.pytab.0));
KEEP(*(.rodata.pytab.1));
KEEP(*(.rodata.pytab.2));
@@ -339,11 +330,11 @@ SECTIONS {
*(.ubsan.data)
/* Legal Notices */
#if !defined(IM_FEELING_NAUGHTY) || defined(EMBED_NOTICES)
KEEP(*(.commentprologue))
KEEP(*(.comment))
KEEP(*(.commentepilogue))
#endif
__notices = .;
KEEP(*(.notice))
BYTE(0);
BYTE(10);
BYTE(10);
/*BEGIN: read-only data that's only needed for initialization */
@@ -399,26 +390,28 @@ SECTIONS {
/*BEGIN: NT FORK COPYING */
KEEP(*(.dataprologue))
*(.data .data.*)
*(.gnu_extab)
*(.gcc_except_table .gcc_except_table.*)
*(.exception_ranges*)
*(.PyRuntime) /* for python */
*(.subrs) /* for emacs */
KEEP(*(SORT_BY_NAME(.sort.data.*)))
. += . > 0 ? CODE_GRANULE : 0;
KEEP(*(.gotprologue))
. = ALIGN(. != 0 ? __SIZEOF_POINTER__ : 0);
__got_start = .;
*(.got)
KEEP(*(.gotepilogue))
__got_end = .;
KEEP(*(.gotpltprologue))
*(.got.plt)
KEEP(*(.gotpltepilogue))
. = ALIGN(. != 0 ? __SIZEOF_POINTER__ : 0);
__init_array_start = .;
KEEP(*(.preinit_array))
KEEP(*(SORT_BY_INIT_PRIORITY(.init_array.*)
SORT_BY_INIT_PRIORITY(.ctors.*)))
KEEP(*(.ctors))
KEEP(*(.init_array))
KEEP(*(.preinit_array))
KEEP(*(.ctors))
__init_array_end = .;
. = ALIGN(. != 0 ? __SIZEOF_POINTER__ : 0);
@@ -435,7 +428,9 @@ SECTIONS {
. = ALIGN(. != 0 ? __SIZEOF_POINTER__ : 0);
KEEP(*(SORT_BY_NAME(.piro.data.sort.*)))
KEEP(*(.piro.pad.data))
*(.igot.plt)
KEEP(*(.dataepilogue))
. = ALIGN(. != 0 ? CONSTANT(COMMONPAGESIZE) : 0);
/*END: NT FORK COPYING */
_edata = .;
@@ -533,7 +528,9 @@ SECTIONS {
*(.piro.data.sort.iat.*)
#endif
*(__patchable_function_entries)
*(.note.gnu.property)
*(__mcount_loc)
*(.rela.dyn)
*(.discard)
*(.yoink)
}
@@ -613,29 +610,6 @@ SHSTUB2(ape_loader_dd_count,
? ROUNDUP(ape_loader_end - ape_loader, CONSTANT(COMMONPAGESIZE)) / 64
: 0);
#if defined(APE_IS_SHELL_SCRIPT) && !IsTiny()
#define IDENTITY(X) X
#define APE_DECLARE_FIXED_DECIMAL(F, X) \
X##_quad = DEFINED(X) ? ((F(X) < 1000000000 ? 32 : F(X) / 1000000000 % 10 + 48) << 000 | \
(F(X) < 100000000 ? 32 : F(X) / 100000000 % 10 + 48) << 010 | \
(F(X) < 10000000 ? 32 : F(X) / 10000000 % 10 + 48) << 020 | \
(F(X) < 1000000 ? 32 : F(X) / 1000000 % 10 + 48) << 030 | \
(F(X) < 100000 ? 32 : F(X) / 100000 % 10 + 48) << 040 | \
(F(X) < 10000 ? 32 : F(X) / 10000 % 10 + 48) << 050 | \
(F(X) < 1000 ? 32 : F(X) / 1000 % 10 + 48) << 060 | \
(F(X) < 100 ? 32 : F(X) / 100 % 10 + 48) << 070) : 0; \
X##_short = DEFINED(X) ? ((F(X) < 10 ? 32 : F(X) / 10 % 10 + 48) << 000 | \
(F(X) % 10 + 48) << 010) : 0
APE_DECLARE_FIXED_DECIMAL(RVA, blink_linux_aarch64);
APE_DECLARE_FIXED_DECIMAL(IDENTITY, blink_linux_aarch64_size);
APE_DECLARE_FIXED_DECIMAL(RVA, blink_xnu_aarch64);
APE_DECLARE_FIXED_DECIMAL(IDENTITY, blink_xnu_aarch64_size);
#endif /* APE_IS_SHELL_SCRIPT */
#if SupportsMetal()
v_ape_realsectors = MIN(0x70000 - IMAGE_BASE_REAL, ROUNDUP(RVA(_ezip), 512)) / 512;
v_ape_realbytes = v_ape_realsectors * 512;
+1 -3
View File
@@ -59,9 +59,7 @@ for x in .ape \
.ape-1.7 \
.ape-1.8 \
.ape-1.9 \
.ape-1.10 \
.ape-blink-0.9.2 \
.ape-blink-1.0.0; do
.ape-1.10; do
rm -f \
~/$x \
/tmp/$x \
Binary file not shown.
Binary file not shown.
+48 -25
View File
@@ -166,13 +166,6 @@
(unsigned long)(255 & (S)[1]) << 010 | \
(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 {
unsigned char e_ident[16];
unsigned short e_type;
@@ -340,23 +333,6 @@ static char *GetEnv(char **p, const char *s) {
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) {
char t;
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);
}
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) {
char ibuf[21];
ibuf[0] = 0;
@@ -901,7 +924,7 @@ EXTERN_C __attribute__((__noreturn__)) void ApeLoader(long di, long *sp,
long *auxv, *ap, *endp, *sp2;
char *p, *pe, *exe, *prog, **argv, **envp;
(void)Utox;
(void)Printf;
/* detect freebsd */
if (SupportsXnu() && dl == XNU) {
+7 -5
View File
@@ -2,7 +2,7 @@
#define COSMOPOLITAN_APE_SECTIONS_INTERNAL_H_
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 __privileged_start[] __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 __test_start[] __attribute__((__weak__));
extern unsigned char __ro[] __attribute__((__weak__));
extern uint8_t __data_start[] __attribute__((__weak__));
extern uint8_t __data_end[] __attribute__((__weak__));
extern uint8_t __bss_start[] __attribute__((__weak__));
extern uint8_t __bss_end[] __attribute__((__weak__));
extern unsigned char __data_start[] __attribute__((__weak__));
extern unsigned char __data_end[] __attribute__((__weak__));
extern unsigned char __bss_start[] __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__));
COSMOPOLITAN_C_END_
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
+58
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.
+4 -2
View File
@@ -54,7 +54,7 @@
#
ifeq ($(LANDLOCKMAKE_VERSION),)
TMPSAFE = $(join $(TMPDIR),$(subst /,_,$@)).tmp
TMPSAFE = $(join $(TMPDIR)/,$(subst /,_,$@)).tmp
else
TMPSAFE = $(TMPDIR)/
endif
@@ -93,7 +93,6 @@ DEFAULT_CCFLAGS += \
-frecord-gcc-switches
DEFAULT_COPTS ?= \
-fno-math-errno \
-fno-ident \
-fno-common \
-fno-gnu-unique \
@@ -138,6 +137,8 @@ MATHEMATICAL = \
DEFAULT_CPPFLAGS += \
-D_COSMO_SOURCE \
-DMODE='"$(MODE)"' \
-Wno-prio-ctor-dtor \
-Wno-unknown-pragmas \
-nostdinc \
-iquote. \
-isystem libc/isystem
@@ -163,6 +164,7 @@ DEFAULT_LDFLAGS = \
-nostdlib \
-znorelro \
--gc-sections \
-z noexecstack \
--build-id=none \
--no-dynamic-linker
+1 -1
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' "$@"
# 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' "$@"
# ctags doesn't understand function pointers, e.g.
+8 -8
View File
@@ -6,14 +6,14 @@ if [ -n "$OBJDUMP" ]; then
fi
find_objdump() {
if [ -x .cosmocc/3.2/bin/$1-linux-cosmo-objdump ]; then
OBJDUMP=.cosmocc/3.2/bin/$1-linux-cosmo-objdump
elif [ -x .cosmocc/3.2/bin/$1-linux-musl-objdump ]; then
OBJDUMP=.cosmocc/3.2/bin/$1-linux-musl-objdump
elif [ -x "$COSMO/.cosmocc/3.2/bin/$1-linux-cosmo-objdump" ]; then
OBJDUMP="$COSMO/.cosmocc/3.2/bin/$1-linux-cosmo-objdump"
elif [ -x "$COSMO/.cosmocc/3.2/bin/$1-linux-musl-objdump" ]; then
OBJDUMP="$COSMO/.cosmocc/3.2/bin/$1-linux-musl-objdump"
if [ -x .cosmocc/3.3.2/bin/$1-linux-cosmo-objdump ]; then
OBJDUMP=.cosmocc/3.3.2/bin/$1-linux-cosmo-objdump
elif [ -x .cosmocc/3.3.2/bin/$1-linux-musl-objdump ]; then
OBJDUMP=.cosmocc/3.3.2/bin/$1-linux-musl-objdump
elif [ -x "$COSMO/.cosmocc/3.3.2/bin/$1-linux-cosmo-objdump" ]; then
OBJDUMP="$COSMO/.cosmocc/3.3.2/bin/$1-linux-cosmo-objdump"
elif [ -x "$COSMO/.cosmocc/3.3.2/bin/$1-linux-musl-objdump" ]; then
OBJDUMP="$COSMO/.cosmocc/3.3.2/bin/$1-linux-musl-objdump"
else
echo "error: toolchain not found (try running 'cosmocc --update' or 'make' in the cosmo monorepo)" >&2
exit 1
+2 -1
View File
@@ -23,7 +23,8 @@
# - tool/build/runitd.c
.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)/tool/build/runit.com \
o/$(MODE)/tool/build/runitd.com \
+4
View File
@@ -39,6 +39,10 @@ o/$(MODE)/%.h: %.c
o/$(MODE)/%.o: %.cc
@$(COMPILE) -AOBJECTIFY.cxx $(OBJECTIFY.cxx) $(OUTPUT_OPTION) $<
@$(COMPILE) -AFIXUPOBJ -wT$@ $(FIXUPOBJ) $@
o/$(MODE)/%.o: %.cpp
@$(COMPILE) -AOBJECTIFY.cxx $(OBJECTIFY.cxx) $(OUTPUT_OPTION) $<
o/$(MODE)/%.lds: %.lds
@$(COMPILE) -APREPROCESS $(PREPROCESS.lds) $(OUTPUT_OPTION) $<
+1 -6
View File
@@ -35,12 +35,7 @@
#include "libc/stdio/stdio.h"
#include "libc/str/str.h"
#include "libc/sysv/consts/madv.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\"");
__static_yoink("pl_mpeg_notice");
/* clang-format off */
// -----------------------------------------------------------------------------
+2 -7
View File
@@ -27,17 +27,12 @@
│ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE │
│ SOFTWARE. │
╚─────────────────────────────────────────────────────────────────────────────*/
#include "dsp/mpeg/buffer.h"
#include "dsp/mpeg/demux.h"
#include "dsp/mpeg/buffer.h"
#include "dsp/mpeg/mpeg.h"
#include "libc/mem/mem.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\"");
__static_yoink("pl_mpeg_notice");
/* clang-format off */
// ----------------------------------------------------------------------------
+1 -6
View File
@@ -28,12 +28,7 @@
│ SOFTWARE. │
╚─────────────────────────────────────────────────────────────────────────────*/
#include "dsp/core/half.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\"");
__static_yoink("pl_mpeg_notice");
/**
* Computes Fixed-Point 8x8 Inverse Discrete Cosine Transform.
-6
View File
@@ -33,12 +33,6 @@
#include "libc/mem/mem.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 */
// -----------------------------------------------------------------------------
// plm_audio implementation
+2 -9
View File
@@ -41,12 +41,7 @@
#include "libc/str/str.h"
#include "libc/time/time.h"
#include "libc/x/x.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\"");
__static_yoink("pl_mpeg_notice");
// -----------------------------------------------------------------------------
// plm_video implementation
@@ -1104,7 +1099,7 @@ plm_video_t *plm_video_create_with_buffer(plm_buffer_t *buffer,
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[1] = (void *)PLM_VIDEO_MACROBLOCK_TYPE_INTRA;
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[2] = (void *)PLM_VIDEO_DCT_SIZE_CHROMINANCE;
}
const void *const plm_video_init_ctor[] initarray = {plm_video_init};
+4
View File
@@ -0,0 +1,4 @@
__notice(pl_mpeg_notice, "\
PL_MPEG (MIT License)\n\
Copyright(c) 2019 Dominic Szablewski\n\
https://phoboslab.org");
+1 -6
View File
@@ -32,12 +32,7 @@
#include "libc/mem/mem.h"
#include "libc/stdio/stdio.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\"");
__static_yoink("pl_mpeg_notice");
/* clang-format off */
// -----------------------------------------------------------------------------
+1 -6
View File
@@ -29,12 +29,7 @@
╚─────────────────────────────────────────────────────────────────────────────*/
#include "dsp/mpeg/mpeg.h"
#include "libc/macros.internal.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\"");
__static_yoink("pl_mpeg_notice");
/**
* @see YCbCr2RGB() in tool/viz/lib/ycbcr2rgb.c
+1 -2
View File
@@ -121,8 +121,7 @@ void *MagikarpY(long dys, long dxs, unsigned char d[restrict dys][dxs],
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_magikarp, kMagikarp[0], sizeof(g_magikarp));
}
const void *const g_magikarp_ctor[] initarray = {g_magikarp_init};
+1 -3
View File
@@ -21,7 +21,7 @@
struct Itoa8 kItoa8;
static textstartup void itoa8_init(void) {
__attribute__((__constructor__)) static textstartup void itoa8_init(void) {
int i;
uint8_t z;
uint32_t w;
@@ -41,5 +41,3 @@ static textstartup void itoa8_init(void) {
kItoa8.data[i] = w;
}
}
const void *const itoa8_init_ctor[] initarray = {itoa8_init};
+1 -3
View File
@@ -97,7 +97,7 @@ static int uncube(int x) {
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;
uint32_t i;
memcpy(g_ansi2rgb_, &kCgaPalette, sizeof(kCgaPalette));
@@ -114,5 +114,3 @@ static textstartup void rgb2ansi_init(void) {
g_ansi2rgb_[i].xt = i;
}
}
const void *const rgb2ansi_init_ctor[] initarray = {rgb2ansi_init};
+1 -3
View File
@@ -73,8 +73,6 @@ textstartup void ttyquantsetup(enum TtyQuantizationAlgorithm alg,
TTYQUANT()->blocks = blocks;
}
textstartup void ttyquant_init(void) {
__attribute__((__constructor__)) textstartup void ttyquant_init(void) {
ttyquantsetup(kTtyQuantXterm256, kTtyQuantRgb, kTtyBlocksUnicode);
}
const void *const ttyquant_init_ctor[] initarray = {ttyquant_init};
+2 -2
View File
@@ -85,7 +85,7 @@ EXAMPLES_DIRECTDEPS = \
THIRD_PARTY_MUSL \
THIRD_PARTY_NSYNC \
THIRD_PARTY_NSYNC_MEM \
THIRD_PARTY_QUICKJS \
THIRD_PARTY_OPENMP \
THIRD_PARTY_SED \
THIRD_PARTY_STB \
THIRD_PARTY_TR \
@@ -153,8 +153,8 @@ o/$(MODE)/examples/picol.com.dbg: \
$(APE_NO_MODIFY_SELF)
@$(APELINK)
o/$(MODE)/examples/nesemu1.o: private QUOTA += -M512m
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
+2 -3
View File
@@ -33,11 +33,10 @@
│ 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\
Copyright 2016 Salvatore Sanfilippo\n\
Contact: [email protected]\"\n\
.include \"libc/disclaimer.inc\"");
Contact: [email protected]");
/*
* This software has been modified by Justine Tunney to:
+4 -7
View File
@@ -67,13 +67,10 @@
* @see https://asciinema.org/
*/
asm(".ident\t\"\\n\\n\
FreeBSD Script (BSD-3 License)\\n\
Copyright (c) 2010, 2012 David E. O'Brien\\n\
Copyright (c) 1980, 1992, 1993\\n\
\tThe Regents of the University of California.\\n\
\tAll rights reserved.\"");
asm(".include \"libc/disclaimer.inc\"");
__notice(freebsd_script_notice, "\
FreeBSD Script (BSD-3 License)\n\
Copyright (c) 2010, 2012 David E. O'Brien\n\
Copyright (c) 1980, 1992, 1993 The Regents of the University of California");
#define DEF_BUF 65536
+1
View File
@@ -7,6 +7,7 @@
│ • http://creativecommons.org/publicdomain/zero/1.0/ │
╚─────────────────────────────────────────────────────────────────*/
#endif
#include "libc/calls/calls.h"
#include "libc/runtime/runtime.h"
#include "libc/stdio/stdio.h"
+17 -19
View File
@@ -2569,8 +2569,7 @@ static int shlex() {
case 'y':
case 'z':
p = buf;
while (buf++, is_in_name(*buf))
;
while (buf++, is_in_name(*buf));
yylval.name = stalloc(buf - p + 1);
*(char *)mempcpy(yylval.name, p, buf - p) = 0;
value = ARITH_VAR;
@@ -2994,7 +2993,7 @@ static const char *updatepwd(const char *dir) {
lim = (char *)stackblock() + 1;
if (*dir != '/') {
if (new[-1] != '/') USTPUTC('/', new);
if (new > lim &&*lim == '/') lim++;
if (new > lim && *lim == '/') lim++;
} else {
USTPUTC('/', new);
cdcomppath++;
@@ -6565,6 +6564,10 @@ struct job *makejob(union node *node, int nprocs) {
return jp;
}
#if defined(__GNUC__) && __GNUC__ >= 12
#pragma GCC diagnostic ignored "-Wuse-after-free"
#endif
static struct job *growjobtab(void) {
unsigned len;
long offset;
@@ -7446,8 +7449,7 @@ static int ulimitcmd(int argc, char **argv) {
what = optc;
}
}
for (l = limits; l->option != what; l++)
;
for (l = limits; l->option != what; l++);
set = *argptr ? 1 : 0;
if (set) {
char *p = *argptr;
@@ -7660,8 +7662,7 @@ static void setparam(char **argv) {
char **newparam;
char **ap;
int nparam;
for (nparam = 0; argv[nparam]; nparam++)
;
for (nparam = 0; argv[nparam]; nparam++);
ap = newparam = ckmalloc((nparam + 1) * sizeof *ap);
while (*argv) {
*ap++ = savestr(*argv++);
@@ -7701,8 +7702,7 @@ static int shiftcmd(int argc, char **argv) {
if (shellparam.malloc) ckfree(*ap1);
}
ap2 = shellparam.p;
while ((*ap2++ = *ap1++) != NULL)
;
while ((*ap2++ = *ap1++) != NULL);
shellparam.optind = 1;
shellparam.optoff = -1;
INTON;
@@ -8308,8 +8308,7 @@ static void parsefname(void) {
if (heredoclist == NULL)
heredoclist = here;
else {
for (p = heredoclist; p->next; p = p->next)
;
for (p = heredoclist; p->next; p = p->next);
p->next = here;
}
} else if (n->type == NTOFD || n->type == NFROMFD) {
@@ -8432,8 +8431,7 @@ static int xxreadtoken(void) {
case '\t':
continue;
case '#':
while ((c = pgetc()) != '\n' && c != PEOF)
;
while ((c = pgetc()) != '\n' && c != PEOF);
pungetc();
continue;
case '\n':
@@ -8553,7 +8551,7 @@ static int readtoken1(int firstc, char const *syntax, char *eofmark,
quotef = 0;
bqlist = NULL;
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 */
for (;;) { /* until end of line or end of word */
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
* we are at the end of the here document, this routine sets the c to PEOF.
*/
checkend : {
checkend: {
if (realeofmark(eofmark)) {
int markloc;
char *p;
@@ -8742,7 +8740,7 @@ checkend : {
* specifying the fd to be redirected. The variable "c" contains the
* first character of the redirection operator.
*/
parseredir : {
parseredir: {
char fd = *out;
union node *np;
np = (union node *)stalloc(sizeof(struct nfile));
@@ -8798,7 +8796,7 @@ parseredir : {
* Parse a substitution. At this point, we have read the dollar sign
* and nothing else.
*/
parsesub : {
parsesub: {
int subtype;
int typeloc;
char *p;
@@ -8910,7 +8908,7 @@ parsesub : {
* list of commands (passed by reference), and savelen is the number of
* characters on the top of the stack which must be preserved.
*/
parsebackq : {
parsebackq: {
struct nodelist **nlpp;
union node *n;
char *str;
@@ -9002,7 +9000,7 @@ parsebackq : {
/*
* Parse an arithmetic expansion (indicate start of one and set state)
*/
parsearith : {
parsearith: {
synstack_push(&synstack, synstack->prev ?: alloca(sizeof(*synstack)),
ARISYNTAX);
synstack->dblquote = 1;
+3 -6
View File
@@ -48,12 +48,9 @@
#include "third_party/musl/netdb.h"
// clang-format off
asm(".ident\t\"\\n\\n\
FreeBSD Whois (BSD-3 License)\\n\
Copyright (c) 1980, 1993\\n\
\tThe Regents of the University of California.\\n\
\tAll rights reserved.\"");
asm(".include \"libc/disclaimer.inc\"");
__notice(freebsd_whois_notice, "\
FreeBSD Whois (BSD-3 License)\n\
Copyright (c) 1980, 1993 The Regents of the University of California");
#define ABUSEHOST "whois.abuse.net"
#define ANICHOST "whois.arin.net"
+6
View File
@@ -142,6 +142,9 @@ libc/isystem/nsync_once.h \
libc/isystem/nsync_time.h \
libc/isystem/nsync_waiter.h \
libc/isystem/numeric \
libc/isystem/omp-tools.h \
libc/isystem/omp.h \
libc/isystem/ompx.h \
libc/isystem/optional \
libc/isystem/ostream \
libc/isystem/paths.h \
@@ -251,6 +254,7 @@ libc/isystem/uio.h \
libc/isystem/unistd.h \
libc/isystem/unordered_map \
libc/isystem/unordered_set \
libc/isystem/unwind.h \
libc/isystem/utility \
libc/isystem/utime.h \
libc/isystem/utmp.h \
@@ -273,6 +277,8 @@ LIBC_INCS = $(filter %.inc,$(LIBC_FILES))
LIBC_CHECKS = $(LIBC_HDRS_H:%=o/$(MODE)/%.ok)
LIBC_FILES := $(wildcard libc/*)
o/$(MODE)/libc/isystem/ompx.h.ok: private CPPFLAGS += -Wno-unknown-pragmas
.PHONY: o/$(MODE)/libc
o/$(MODE)/libc: o/$(MODE)/libc/calls \
o/$(MODE)/libc/crt \
+2 -2
View File
@@ -14,8 +14,8 @@
#define _ASSERT_H
COSMOPOLITAN_C_START_
void __assert_fail(const char *, const char *, int);
void unassert(const char *, const char *, int);
void __assert_fail(const char *, const char *, int) libcesque;
void unassert(const char *, const char *, int) libcesque;
#ifdef NDEBUG
#define assert(x) ((void)0)
+17 -4
View File
@@ -41,6 +41,7 @@ LIBC_CALLS_A_DIRECTDEPS = \
LIBC_INTRIN \
LIBC_NEXGEN32E \
LIBC_NT_ADVAPI32 \
LIBC_NT_BCRYPTPRIMITIVES \
LIBC_NT_IPHLPAPI \
LIBC_NT_KERNEL32 \
LIBC_NT_NTDLL \
@@ -72,12 +73,10 @@ $(LIBC_CALLS_A_OBJS): private \
-Wframe-larger-than=4096 \
-Walloca-larger-than=4096
ifneq ($(ARCH), aarch64)
# we always want -O3 because:
# 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/siginfo2cosmo.o \
o/$(MODE)/libc/calls/sigenter-freebsd.o \
o/$(MODE)/libc/calls/sigenter-netbsd.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 \
COPTS += \
-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
endif
@@ -132,7 +144,8 @@ endif
o/$(MODE)/libc/calls/pledge-linux.o: private \
CFLAGS += \
-Os \
-fPIC
-fPIC \
-ffreestanding
# these assembly files are safe to build on aarch64
o/$(MODE)/libc/calls/getcontext.o: libc/calls/getcontext.S
+168 -165
View File
@@ -72,184 +72,187 @@ COSMOPOLITAN_C_START_
typedef int sig_atomic_t;
bool32 isatty(int);
char *getcwd(char *, size_t);
char *realpath(const char *, char *) __wur;
char *ttyname(int);
int access(const char *, int) dontthrow;
int chdir(const char *);
int chmod(const char *, unsigned);
int chown(const char *, unsigned, unsigned);
int chroot(const char *);
int close(int);
int close_range(unsigned, unsigned, unsigned);
int closefrom(int);
int creat(const char *, unsigned);
int dup(int);
int dup2(int, int);
int dup3(int, int, int);
int execl(const char *, const char *, ...) nullterminated();
int execle(const char *, const char *, ...) nullterminated((1));
int execlp(const char *, const char *, ...) nullterminated();
int execv(const char *, char *const[]);
int execve(const char *, char *const[], char *const[]);
int execvp(const char *, char *const[]);
int faccessat(int, const char *, int, int);
int fchdir(int);
int fchmod(int, unsigned) dontthrow;
int fchmodat(int, const char *, unsigned, int);
int fchown(int, unsigned, unsigned);
int fchownat(int, const char *, unsigned, unsigned, int);
int fcntl(int, int, ...);
int fdatasync(int);
int fexecve(int, char *const[], char *const[]);
int flock(int, int);
int fork(void);
int fsync(int);
int ftruncate(int, int64_t);
int getdomainname(char *, size_t);
int getgroups(int, unsigned[]);
int gethostname(char *, size_t);
int getloadavg(double *, int);
bool32 isatty(int) libcesque;
char *getcwd(char *, size_t) dontthrow;
char *realpath(const char *, char *) libcesque __wur;
char *ttyname(int) libcesque;
int access(const char *, int) libcesque;
int chdir(const char *) libcesque;
int chmod(const char *, unsigned) libcesque;
int chown(const char *, unsigned, unsigned) libcesque;
int chroot(const char *) libcesque;
int close(int) libcesque;
int close_range(unsigned, unsigned, unsigned) libcesque;
int closefrom(int) libcesque;
int creat(const char *, unsigned) libcesque;
int dup(int) libcesque;
int dup2(int, int) libcesque;
int dup3(int, int, int) libcesque;
int execl(const char *, const char *, ...) nullterminated() libcesque;
int execle(const char *, const char *, ...) nullterminated((1)) libcesque;
int execlp(const char *, const char *, ...) nullterminated() libcesque;
int execv(const char *, char *const[]) libcesque;
int execve(const char *, char *const[], char *const[]) libcesque;
int execvp(const char *, char *const[]) libcesque;
int faccessat(int, const char *, int, int) libcesque;
int fchdir(int) libcesque;
int fchmod(int, unsigned) libcesque;
int fchmodat(int, const char *, unsigned, int) libcesque;
int fchown(int, unsigned, unsigned) libcesque;
int fchownat(int, const char *, unsigned, unsigned, int) libcesque;
int fcntl(int, int, ...) libcesque;
int fdatasync(int) libcesque;
int fexecve(int, char *const[], char *const[]) libcesque;
int flock(int, int) libcesque;
int fork(void) libcesque;
int fsync(int) libcesque;
int ftruncate(int, int64_t) libcesque;
int getdomainname(char *, size_t) libcesque;
int getgroups(int, unsigned[]) libcesque;
int gethostname(char *, size_t) libcesque;
int getloadavg(double *, int) libcesque;
int getpgid(int) libcesque;
int getpgrp(void) nosideeffect;
int getpid(void) nosideeffect libcesque;
int getppid(void);
int getpriority(int, unsigned);
int getpgrp(void) libcesque nosideeffect;
int getpid(void) libcesque nosideeffect;
int getppid(void) libcesque;
int getpriority(int, unsigned) libcesque;
int getsid(int) nosideeffect libcesque;
int ioctl(int, unsigned long, ...);
int issetugid(void);
int kill(int, int);
int killpg(int, int);
int lchmod(const char *, unsigned);
int lchown(const char *, unsigned, unsigned);
int link(const char *, const char *) dontthrow;
int linkat(int, const char *, int, const char *, int);
int mincore(void *, size_t, unsigned char *);
int mkdir(const char *, unsigned);
int mkdirat(int, const char *, unsigned);
int mknod(const char *, unsigned, uint64_t);
int nice(int);
int open(const char *, int, ...);
int openat(int, const char *, int, ...);
int pause(void);
int pipe(int[hasatleast 2]);
int pipe2(int[hasatleast 2], int);
int posix_fadvise(int, int64_t, int64_t, int);
int posix_madvise(void *, uint64_t, int);
int raise(int);
int reboot(int);
int remove(const char *);
int rename(const char *, const char *);
int renameat(int, const char *, int, const char *);
int rmdir(const char *);
int sched_yield(void);
int setegid(unsigned);
int seteuid(unsigned);
int setfsgid(unsigned);
int setfsuid(unsigned);
int setgid(unsigned);
int setgroups(size_t, const unsigned[]);
int setpgid(int, int);
int setpgrp(void);
int setpriority(int, unsigned, int);
int setregid(unsigned, unsigned);
int setreuid(unsigned, unsigned);
int setsid(void);
int setuid(unsigned);
int shm_open(const char *, int, unsigned);
int shm_unlink(const char *);
int sigignore(int);
int siginterrupt(int, int);
int symlink(const char *, const char *);
int symlinkat(const char *, int, const char *);
int tcgetpgrp(int);
int tcsetpgrp(int, int);
int truncate(const char *, int64_t);
int ttyname_r(int, char *, size_t);
int unlink(const char *);
int unlinkat(int, const char *, int);
int usleep(uint64_t);
int vfork(void) returnstwice;
int wait(int *);
int waitpid(int, int *, int);
int64_t clock(void);
int64_t time(int64_t *);
ssize_t copy_file_range(int, long *, int, long *, size_t, unsigned);
ssize_t lseek(int, int64_t, int);
ssize_t pread(int, void *, size_t, int64_t);
ssize_t pwrite(int, const void *, size_t, int64_t);
ssize_t read(int, void *, size_t);
ssize_t readlink(const char *, char *, size_t);
ssize_t readlinkat(int, const char *, char *, size_t);
ssize_t write(int, const void *, size_t);
unsigned alarm(unsigned);
unsigned getegid(void) nosideeffect;
unsigned geteuid(void) nosideeffect;
unsigned getgid(void) nosideeffect;
int ioctl(int, unsigned long, ...) libcesque;
int issetugid(void) libcesque;
int kill(int, int) libcesque;
int killpg(int, int) libcesque;
int lchmod(const char *, unsigned) libcesque;
int lchown(const char *, unsigned, unsigned) libcesque;
int link(const char *, const char *) libcesque;
int linkat(int, const char *, int, const char *, int) libcesque;
int mincore(void *, size_t, unsigned char *) libcesque;
int mkdir(const char *, unsigned) libcesque;
int mkdirat(int, const char *, unsigned) libcesque;
int mknod(const char *, unsigned, uint64_t) libcesque;
int nice(int) libcesque;
int open(const char *, int, ...) libcesque;
int openat(int, const char *, int, ...) libcesque;
int pause(void) libcesque;
int pipe(int[hasatleast 2]) libcesque;
int pipe2(int[hasatleast 2], int) libcesque;
int posix_fadvise(int, int64_t, int64_t, int) libcesque;
int posix_madvise(void *, uint64_t, int) libcesque;
int raise(int) libcesque;
int reboot(int) libcesque;
int remove(const char *) libcesque;
int rename(const char *, const char *) libcesque;
int renameat(int, const char *, int, const char *) libcesque;
int rmdir(const char *) libcesque;
int sched_yield(void) libcesque;
int setegid(unsigned) libcesque;
int seteuid(unsigned) libcesque;
int setfsgid(unsigned) libcesque;
int setfsuid(unsigned) libcesque;
int setgid(unsigned) libcesque;
int setgroups(size_t, const unsigned[]) libcesque;
int setpgid(int, int) libcesque;
int setpgrp(void) libcesque;
int setpriority(int, unsigned, int) libcesque;
int setregid(unsigned, unsigned) libcesque;
int setreuid(unsigned, unsigned) libcesque;
int setsid(void) libcesque;
int setuid(unsigned) libcesque;
int shm_open(const char *, int, unsigned) libcesque;
int shm_unlink(const char *) libcesque;
int sigignore(int) libcesque;
int siginterrupt(int, int) libcesque;
int symlink(const char *, const char *) libcesque;
int symlinkat(const char *, int, const char *) libcesque;
int tcgetpgrp(int) libcesque;
int tcsetpgrp(int, int) libcesque;
int truncate(const char *, int64_t) libcesque;
int ttyname_r(int, char *, size_t) libcesque;
int unlink(const char *) libcesque;
int unlinkat(int, const char *, int) libcesque;
int usleep(uint64_t) libcesque;
int vfork(void) libcesque returnstwice;
int wait(int *) libcesque;
int waitpid(int, int *, int) libcesque;
int64_t clock(void) libcesque;
int64_t time(int64_t *) libcesque;
ssize_t copy_file_range(int, long *, int, long *, size_t, unsigned) libcesque;
ssize_t lseek(int, int64_t, int) libcesque;
ssize_t pread(int, void *, size_t, int64_t) libcesque;
ssize_t pwrite(int, const void *, size_t, int64_t) libcesque;
ssize_t read(int, void *, size_t) libcesque;
ssize_t readlink(const char *, char *, size_t) libcesque;
ssize_t readlinkat(int, const char *, char *, size_t) libcesque;
ssize_t write(int, const void *, size_t) libcesque;
unsigned alarm(unsigned) libcesque;
unsigned getegid(void) libcesque nosideeffect;
unsigned geteuid(void) libcesque nosideeffect;
unsigned getgid(void) libcesque nosideeffect;
unsigned getuid(void) libcesque;
unsigned sleep(unsigned);
unsigned ualarm(unsigned, unsigned);
unsigned umask(unsigned);
void sync(void);
unsigned sleep(unsigned) libcesque;
unsigned ualarm(unsigned, unsigned) libcesque;
unsigned umask(unsigned) libcesque;
void sync(void) libcesque;
#if defined(_COSMO_SOURCE) || defined(_GNU_SOURCE)
int syncfs(int);
int prctl(int, ...);
int syncfs(int) libcesque;
int prctl(int, ...) libcesque;
int gettid(void) libcesque;
int setresgid(unsigned, unsigned, unsigned);
int setresuid(unsigned, unsigned, unsigned);
int getresgid(unsigned *, unsigned *, unsigned *);
int getresuid(unsigned *, unsigned *, unsigned *);
char *get_current_dir_name(void) __wur;
ssize_t splice(int, int64_t *, int, int64_t *, size_t, unsigned);
int memfd_create(const char *, unsigned int);
int execvpe(const char *, char *const[], char *const[]);
int euidaccess(const char *, int);
int eaccess(const char *, int);
int madvise(void *, uint64_t, int);
int setresgid(unsigned, unsigned, unsigned) libcesque;
int setresuid(unsigned, unsigned, unsigned) libcesque;
int getresgid(unsigned *, unsigned *, unsigned *) libcesque;
int getresuid(unsigned *, unsigned *, unsigned *) libcesque;
char *get_current_dir_name(void) libcesque __wur;
ssize_t splice(int, int64_t *, int, int64_t *, size_t, unsigned) libcesque;
int memfd_create(const char *, unsigned int) libcesque;
int execvpe(const char *, char *const[], char *const[]) libcesque;
int euidaccess(const char *, int) libcesque;
int eaccess(const char *, int) libcesque;
int madvise(void *, uint64_t, int) libcesque;
int getcpu(unsigned *, unsigned *) libcesque;
#endif
#ifdef _COSMO_SOURCE
bool32 fdexists(int);
bool32 fileexists(const char *);
bool32 ischardev(int);
bool32 isdirectory(const char *);
bool32 isexecutable(const char *);
bool32 isregularfile(const char *);
bool32 issymlink(const char *);
char *commandv(const char *, char *, size_t);
int __getcwd(char *, size_t);
bool32 fdexists(int) libcesque;
bool32 fileexists(const char *) libcesque;
bool32 ischardev(int) libcesque;
bool32 isdirectory(const char *) libcesque;
bool32 isexecutable(const char *) libcesque;
bool32 isregularfile(const char *) libcesque;
bool32 issymlink(const char *) libcesque;
char *commandv(const char *, char *, size_t) libcesque;
int __getcwd(char *, size_t) libcesque;
int clone(void *, void *, size_t, int, void *, void *, void *, void *);
int fadvise(int, uint64_t, uint64_t, int);
int makedirs(const char *, unsigned);
int pivot_root(const char *, const char *);
int pledge(const char *, const char *);
int seccomp(unsigned, unsigned, void *);
int sys_iopl(int);
int sys_ioprio_get(int, int);
int sys_ioprio_set(int, int, int);
int sys_mlock(const void *, size_t);
int sys_mlock2(const void *, size_t, int);
int sys_mlockall(int);
int sys_munlock(const void *, size_t);
int sys_munlockall(void);
int sys_personality(uint64_t);
int sys_ptrace(int, ...);
int fadvise(int, uint64_t, uint64_t, int) libcesque;
int makedirs(const char *, unsigned) libcesque;
int pivot_root(const char *, const char *) libcesque;
int pledge(const char *, const char *) libcesque;
int seccomp(unsigned, unsigned, void *) libcesque;
int sys_iopl(int) libcesque;
int sys_ioprio_get(int, int) libcesque;
int sys_ioprio_set(int, int, int) libcesque;
int sys_mlock(const void *, size_t) libcesque;
int sys_mlock2(const void *, size_t, int) libcesque;
int sys_mlockall(int) libcesque;
int sys_munlock(const void *, size_t) libcesque;
int sys_munlockall(void) libcesque;
int sys_personality(uint64_t) libcesque;
int sys_ptrace(int, ...) libcesque;
int sys_sysctl(const int *, unsigned, void *, size_t *, void *, size_t);
int tmpfd(void);
int touch(const char *, unsigned);
int unveil(const char *, const char *);
long ptrace(int, ...);
ssize_t copyfd(int, int, size_t);
ssize_t readansi(int, char *, size_t);
ssize_t tinyprint(int, const char *, ...) nullterminated();
void shm_path_np(const char *, char[hasatleast 78]);
int tmpfd(void) libcesque;
int touch(const char *, unsigned) libcesque;
int unveil(const char *, const char *) libcesque;
long ptrace(int, ...) libcesque;
ssize_t copyfd(int, int, size_t) libcesque;
ssize_t readansi(int, char *, size_t) libcesque;
ssize_t tinyprint(int, const char *, ...) libcesque nullterminated();
void shm_path_np(const char *, char[hasatleast 78]) libcesque;
#endif /* _COSMO_SOURCE */
int __wifstopped(int) pureconst;
int __wifcontinued(int) pureconst;
int __wifsignaled(int) pureconst;
int system(const char *) libcesque;
int __wifstopped(int) libcesque pureconst;
int __wifcontinued(int) libcesque pureconst;
int __wifsignaled(int) libcesque pureconst;
#if defined(_LARGEFILE64_SOURCE) || defined(_GNU_SOURCE)
#define lseek64 lseek
+27 -10
View File
@@ -21,12 +21,17 @@
#include "libc/dce.h"
#include "libc/errno.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/thread.h"
#define _CLOCK_REALTIME 0
#define _CLOCK_MONOTONIC 1
#define _CLOCK_REALTIME_COARSE 2
#define _CLOCK_BOOTTIME 3
#define _CLOCK_REALTIME 0
#define _CLOCK_MONOTONIC 1
#define _CLOCK_REALTIME_COARSE 2
#define _CLOCK_BOOTTIME 3
#define _CLOCK_PROCESS_CPUTIME_ID 4
#define _CLOCK_THREAD_CPUTIME_ID 5
static struct {
uint64_t base;
@@ -35,7 +40,7 @@ static struct {
textwindows int sys_clock_gettime_nt(int clock, struct timespec *ts) {
uint64_t t;
struct NtFileTime ft;
struct NtFileTime ft, ftExit, ftUser, ftKernel, ftCreation;
switch (clock) {
case _CLOCK_REALTIME:
if (ts) {
@@ -61,18 +66,30 @@ textwindows int sys_clock_gettime_nt(int clock, struct timespec *ts) {
*ts = timespec_frommillis(GetTickCount64());
}
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:
return -EINVAL;
}
}
static textstartup void winclock_init() {
__attribute__((__constructor__(40))) static textstartup void winclock_init() {
if (IsWindows()) {
QueryPerformanceCounter(&g_winclock.base);
QueryPerformanceFrequency(&g_winclock.freq);
}
}
const void *const winclock_ctor[] initarray = {
winclock_init,
};
+7 -18
View File
@@ -61,24 +61,13 @@ static int __clock_gettime_init(int clockid, struct timespec *ts) {
/**
* Returns nanosecond time.
*
* @param clock can be one of:
* - `CLOCK_REALTIME`: universally supported
* - `CLOCK_REALTIME_FAST`: ditto but faster on freebsd
* - `CLOCK_REALTIME_PRECISE`: ditto but better on freebsd
* - `CLOCK_REALTIME_COARSE`: : like `CLOCK_REALTIME_FAST` w/ Linux 2.6.32+
* - `CLOCK_MONOTONIC`: universally supported (except on XNU/NT w/o INVTSC)
* - `CLOCK_MONOTONIC_FAST`: ditto but faster on freebsd
* - `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 clock supports the following values across OSes:
* - `CLOCK_REALTIME`
* - `CLOCK_MONOTONIC`
* - `CLOCK_REALTIME_COARSE`
* - `CLOCK_MONOTONIC_COARSE`
* - `CLOCK_THREAD_CPUTIME_ID`
* - `CLOCK_PROCESS_CPUTIME_ID`
* @param ts is where the result is stored (or null to do clock check)
* @return 0 on success, or -1 w/ errno
* @raise EFAULT if `ts` points to invalid memory
+84
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;
}
+61
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;
}
+3 -107
View File
@@ -16,112 +16,10 @@
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
│ 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.internal.h"
#include "libc/dce.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/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.
@@ -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.
*
* @param clock may be
* - `CLOCK_REALTIME` to have nanosecond-accurate wall time sleeps
* - `CLOCK_REALTIME_COARSE` to not spin through scheduler quantum
* - `CLOCK_MONOTONIC` to base the sleep off the monotinic clock
* - `CLOCK_MONOTONIC_COARSE` to once again not do userspace spin
* - `CLOCK_REALTIME`
* - `CLOCK_MONOTONIC`
* @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 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;
}
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 = old;
return err;
+1 -1
View File
@@ -93,7 +93,7 @@ static int close_impl(int fd) {
*/
int close(int fd) {
int rc;
if (__isfdkind(fd, kFdZip)) { // XXX IsWindows()?
if (__isfdkind(fd, kFdZip)) { // XXX IsWindows()?
BLOCK_SIGNALS;
__fds_lock();
rc = close_impl(fd);
+1 -1
View File
@@ -66,4 +66,4 @@ int fadvise(int fd, uint64_t offset, uint64_t len, int advice) {
return rc;
}
__strong_reference(fadvise, fadvise64);
__weak_reference(fadvise, fadvise64);
+1 -4
View File
@@ -32,11 +32,8 @@
#include "libc/sysv/consts/o.h"
#include "libc/sysv/consts/s.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
static void __procfdname(char *buf, unsigned fd) {
+1
View File
@@ -27,6 +27,7 @@
#include "libc/elf/tinyelf.internal.h"
#include "libc/errno.h"
#include "libc/intrin/directmap.internal.h"
#include "libc/intrin/kprintf.h"
#include "libc/nt/memory.h"
#include "libc/nt/runtime.h"
#include "libc/runtime/runtime.h"
+1 -1
View File
@@ -60,4 +60,4 @@ int fstat(int fd, struct stat *st) {
return rc;
}
__strong_reference(fstat, fstat64);
__weak_reference(fstat, fstat64);
+1 -1
View File
@@ -102,4 +102,4 @@ int fstatat(int dirfd, const char *path, struct stat *st, int flags) {
return rc;
}
__strong_reference(fstatat, fstatat64);
__weak_reference(fstatat, fstatat64);
+1 -1
View File
@@ -87,4 +87,4 @@ int ftruncate(int fd, int64_t length) {
return rc;
}
__strong_reference(ftruncate, ftruncate64);
__weak_reference(ftruncate, ftruncate64);
+76
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;
}
+1 -5
View File
@@ -59,7 +59,7 @@ textwindows int sys_getloadavg_nt(double *a, int n) {
return rc;
}
static textstartup void sys_getloadavg_nt_init(void) {
__attribute__((__constructor__(40))) static textstartup void ntinitload(void) {
if (IsWindows()) {
load = 1;
cpus = __get_cpu_count() / 2;
@@ -67,7 +67,3 @@ static textstartup void sys_getloadavg_nt_init(void) {
GetSystemTimes(&idle1, &kern1, &user1);
}
}
const void *const sys_getloadavg_nt_ctor[] initarray = {
sys_getloadavg_nt_init,
};
+4 -3
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 rc;
if (IsWindows()) {
rc = RtlGenRandom(p, n) ? n : __winerr();
rc = ProcessPrng(p, n) ? n : __winerr();
} else if (have_getrandom) {
if (IsXnu() || IsOpenbsd()) {
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:
*
* - RtlGenRandom() on Windows
* - ProcessPrng() on Windows
* - getentropy() on XNU and OpenBSD
* - getrandom() on Linux, 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;
}
__attribute__((__constructor__)) static textstartup void getrandom_init(void) {
__attribute__((__constructor__(30))) static textstartup void getrandom_init(
void) {
int e, rc;
if (IsWindows() || IsMetal()) return;
BLOCK_CANCELATION;
+1 -1
View File
@@ -12,7 +12,7 @@
COSMOPOLITAN_C_START_
int ftok(const char *, int);
int ftok(const char *, int) libcesque;
COSMOPOLITAN_C_END_
#endif /* COSMOPOLITAN_LIBC_CALLS_IPC_H_ */
+11 -7
View File
@@ -24,11 +24,15 @@
/**
* Returns true if process is running under qemu-x86_64 or qemu-aarch64.
*/
int IsQemu(void) {
// qemu doesn't validate the advice argument
// we could also check if __getcwd(0, 0) raises efault
int e = errno;
int r = !sys_madvise(__executable_start, 16384, 127);
errno = e;
return r;
int IsQemuUser(void) {
static char rplus1;
if (!rplus1) {
// qemu doesn't validate the advice argument
// we could also check if __getcwd(0, 0) raises efault
int e = errno;
int r = !sys_madvise(__executable_start, 16384, 127);
errno = e;
rplus1 = r + 1;
}
return rplus1 - 1;
}
+1 -1
View File
@@ -93,4 +93,4 @@ int64_t lseek(int fd, int64_t offset, int whence) {
return rc;
}
__strong_reference(lseek, lseek64);
__weak_reference(lseek, lseek64);
+1 -1
View File
@@ -27,4 +27,4 @@ int lstat(const char *pathname, struct stat *st) {
return fstatat(AT_FDCWD, pathname, st, AT_SYMLINK_NOFOLLOW);
}
__strong_reference(lstat, lstat64);
__weak_reference(lstat, lstat64);
+3 -3
View File
@@ -1,9 +1,9 @@
#ifndef COSMOPOLITAN_LIBC_CALLS_MAKEDEV_H_
#define COSMOPOLITAN_LIBC_CALLS_MAKEDEV_H_
uint64_t makedev(uint32_t, uint32_t);
uint32_t major(uint64_t);
uint32_t minor(uint64_t);
uint64_t makedev(uint32_t, uint32_t) libcesque;
uint32_t major(uint64_t) libcesque;
uint32_t minor(uint64_t) libcesque;
#define major(x) major(x)
#define minor(x) minor(x)
+3 -1
View File
@@ -75,7 +75,9 @@ textstartup void InitializeMetalFile(void) {
memcpy(copied_base, (void *)(BANE + IMAGE_BASE_PHYSICAL), size);
__ape_com_base = copied_base;
__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);
}
}
+1 -1
View File
@@ -40,4 +40,4 @@ int mkostemp(char *template, unsigned flags) {
return openatemp(AT_FDCWD, template, 0, flags, 0);
}
__strong_reference(mkostemp, mkostemp64);
__weak_reference(mkostemp, mkostemp64);
+1 -1
View File
@@ -41,4 +41,4 @@ int mkostemps(char *template, int suffixlen, unsigned flags) {
return openatemp(AT_FDCWD, template, suffixlen, flags, 0);
}
__strong_reference(mkostemps, mkostemps64);
__weak_reference(mkostemps, mkostemps64);
+1 -1
View File
@@ -40,4 +40,4 @@ int mkstemp(char *template) {
return openatemp(AT_FDCWD, template, 0, 0, 0);
}
__strong_reference(mkstemp, mkstemp64);
__weak_reference(mkstemp, mkstemp64);
+1 -1
View File
@@ -42,4 +42,4 @@ int mkstemps(char *template, int suffixlen) {
return openatemp(AT_FDCWD, template, suffixlen, 0, 0);
}
__strong_reference(mkstemps, mkstemps64);
__weak_reference(mkstemps, mkstemps64);
+1 -1
View File
@@ -43,4 +43,4 @@ int open(const char *file, int flags, ...) {
return openat(AT_FDCWD, file, flags, mode);
}
__strong_reference(open, open64);
__weak_reference(open, open64);
+1 -1
View File
@@ -241,4 +241,4 @@ int openat(int dirfd, const char *path, int flags, ...) {
return rc;
}
__strong_reference(openat, openat64);
__weak_reference(openat, openat64);
+1 -1
View File
@@ -85,4 +85,4 @@ ssize_t pread(int fd, void *buf, size_t size, int64_t offset) {
return rc;
}
__strong_reference(pread, pread64);
__weak_reference(pread, pread64);
+1 -1
View File
@@ -21,7 +21,7 @@
char *program_invocation_short_name;
__attribute__((__constructor__)) static void //
__attribute__((__constructor__(10))) static textstartup void
program_invocation_short_name_init(void) {
char *p, *r;
if (!__argc) return;
+1 -1
View File
@@ -85,4 +85,4 @@ ssize_t pwrite(int fd, const void *buf, size_t size, int64_t offset) {
return rc;
}
__strong_reference(pwrite, pwrite64);
__weak_reference(pwrite, pwrite64);
+1 -1
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
* 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
* getauxval(AT_RANDOM), and if not we finally use RDTSC and getpid().
*
+2 -4
View File
@@ -22,8 +22,8 @@
#include "libc/nexgen32e/x86info.h"
#include "libc/stdio/rand.h"
textstartup void rdrand_init(int argc, char **argv, char **envp,
intptr_t *auxv) {
__attribute__((__constructor__(2))) textstartup void rdrand_init(
int argc, char **argv, char **envp, intptr_t *auxv) {
extern unsigned kMutableCpuids[KCPUIDS_LEN][4] asm("kCpuids");
/*
* 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);
}
}
const void *const g_rdrand_init[] initarray = {rdrand_init};
+2
View File
@@ -157,6 +157,8 @@ static textwindows struct Keystroke *NewKeystroke(void) {
struct Keystroke *k = KEYSTROKE_CONTAINER(e);
dll_remove(&__keystroke.free, &k->elem);
--__keystroke.freekeys;
// TODO(jart): What's wrong with GCC 12.3?
asm("" : "+r"(k));
k->buflen = 0;
return k;
}
+64
View File
@@ -0,0 +1,64 @@
/*-*- 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/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);
/**
* Returns ID of CPU on which thread is currently scheduled.
* @return cpu number on success, or -1 w/ errno
*/
int sched_getcpu(void) {
if (X86_HAVE(RDTSCP)) {
unsigned tsc_aux;
rdtscp(&tsc_aux);
return TSC_AUX_CORE(tsc_aux);
} else if (IsWindows()) {
struct NtProcessorNumber pn;
GetCurrentProcessorNumberEx(&pn);
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 {
unsigned cpu = 0;
int rc = sys_getcpu(&cpu, 0, 0);
if (rc == -1) return -1;
return cpu;
}
}
+16 -8
View File
@@ -32,6 +32,7 @@
#include "libc/intrin/bsf.h"
#include "libc/intrin/describebacktrace.internal.h"
#include "libc/intrin/dll.h"
#include "libc/intrin/kprintf.h"
#include "libc/intrin/strace.internal.h"
#include "libc/intrin/weaken.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
// 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) &&
!(atomic_load_explicit(&pt->pt_blkmask, memory_order_relaxed) &
(1ull << (sig - 1)))) {
!(pt->pt_blkmask & (1ull << (sig - 1)))) {
_pthread_ref(pt);
mark = pt;
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,
struct CosmoTib *tib) {
@@ -541,9 +550,10 @@ static void __sig_unmaskable(struct NtExceptionPointers *ep, int code, int sig,
intptr_t hStderr;
char sigbuf[21], s[128], *p;
hStderr = GetStdHandle(kNtStdErrorHandle);
p = stpcpy(s, "Terminating on uncaught ");
p = stpcpy(p, strsignal_r(sig, sigbuf));
p = stpcpy(p, ". Pass --strace and/or ShowCrashReports() for details.\n");
p = __sig_stpcpy(s, "Terminating on uncaught ");
p = __sig_stpcpy(p, strsignal_r(sig, sigbuf));
p = __sig_stpcpy(
p, ". Pass --strace and/or ShowCrashReports() for details.\n");
WriteFile(hStderr, s, p - s, 0, 0);
#endif
__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;
AddVectoredExceptionHandler(true, (void *)__sig_crash);
SetConsoleCtrlHandler((void *)__sig_console, true);
}
const void *const __sig_ctor[] initarray = {__sig_init};
#endif /* __x86_64__ */
+1 -1
View File
@@ -34,4 +34,4 @@ int stat(const char *path, struct stat *st) {
return fstatat(AT_FDCWD, path, st, 0);
}
__strong_reference(stat, stat64);
__weak_reference(stat, stat64);
+1 -1
View File
@@ -36,4 +36,4 @@ int statvfs(const char *path, struct statvfs *sv) {
}
}
__strong_reference(statvfs, statvfs64);
__weak_reference(statvfs, statvfs64);
+12 -10
View File
@@ -9,33 +9,33 @@ typedef struct cpu_set_t {
uint64_t __bits[16];
} cpu_set_t;
int sched_getcpu(void);
int sched_getaffinity(int, size_t, cpu_set_t *);
int sched_setaffinity(int, size_t, const cpu_set_t *);
int sched_getcpu(void) libcesque;
int sched_getaffinity(int, size_t, cpu_set_t *) libcesque;
int sched_setaffinity(int, size_t, const cpu_set_t *) libcesque;
#define CPU_SET(i, s) ((s)->__bits[(i) / 64] |= 1ull << ((i) % 64))
#define CPU_CLR(i, s) ((s)->__bits[(i) / 64] &= ~(1ull << ((i) % 64)))
#define CPU_ISSET(i, s) (!!((s)->__bits[(i) / 64] & (1ull << ((i) % 64))))
void CPU_ZERO(cpu_set_t *);
void CPU_ZERO(cpu_set_t *) libcesque;
#define CPU_ZERO(x) CPU_ZERO(x)
int CPU_COUNT(cpu_set_t *);
int CPU_COUNT(cpu_set_t *) libcesque;
#define CPU_COUNT(x) CPU_COUNT(x)
int CPU_EQUAL(cpu_set_t *, cpu_set_t *);
int CPU_EQUAL(cpu_set_t *, cpu_set_t *) libcesque;
#define CPU_EQUAL(x, y) CPU_EQUAL(x, y)
void CPU_AND(cpu_set_t *, cpu_set_t *, cpu_set_t *);
void CPU_AND(cpu_set_t *, cpu_set_t *, cpu_set_t *) libcesque;
#define CPU_AND(x, y, z) CPU_AND(x, y, z)
void CPU_OR(cpu_set_t *, cpu_set_t *, cpu_set_t *);
void CPU_OR(cpu_set_t *, cpu_set_t *, cpu_set_t *) libcesque;
#define CPU_OR(x, y, z) CPU_OR(x, y, z)
void CPU_XOR(cpu_set_t *, cpu_set_t *, cpu_set_t *);
void CPU_XOR(cpu_set_t *, cpu_set_t *, cpu_set_t *) libcesque;
#define CPU_XOR(x, y, z) CPU_XOR(x, y, z)
int CPU_COUNT_S(size_t, const cpu_set_t *);
int CPU_COUNT_S(size_t, const cpu_set_t *) libcesque;
#define CPU_COUNT_S(x, y) CPU_COUNT_S(x, y)
#define CPU_ALLOC_SIZE(n) \
@@ -53,5 +53,7 @@ int CPU_COUNT_S(size_t, const cpu_set_t *);
#define CPU_CLR_S(i, size, set) _CPU_S(i, size, set, &= ~)
#define CPU_ISSET_S(i, size, set) _CPU_S(i, size, set, &)
typedef cpu_set_t cpuset_t; /* for freebsd compatibility */
COSMOPOLITAN_C_END_
#endif /* COSMOPOLITAN_LIBC_CALLS_STRUCT_CPUSET_H_ */
+12 -12
View File
@@ -13,19 +13,19 @@ struct dirent { /* linux getdents64 abi */
struct dirstream;
typedef struct dirstream DIR;
DIR *fdopendir(int) __wur;
DIR *opendir(const char *) __wur;
int closedir(DIR *);
int dirfd(DIR *);
long telldir(DIR *);
struct dirent *readdir(DIR *);
int readdir_r(DIR *, struct dirent *, struct dirent **);
void rewinddir(DIR *);
void seekdir(DIR *, long);
int alphasort(const struct dirent **, const struct dirent **);
int versionsort(const struct dirent **, const struct dirent **);
DIR *fdopendir(int) libcesque __wur;
DIR *opendir(const char *) libcesque __wur;
int closedir(DIR *) libcesque;
int dirfd(DIR *) libcesque;
long telldir(DIR *) libcesque;
struct dirent *readdir(DIR *) libcesque;
int readdir_r(DIR *, struct dirent *, struct dirent **) libcesque;
void rewinddir(DIR *) libcesque;
void seekdir(DIR *, long) libcesque;
int alphasort(const struct dirent **, const struct dirent **) libcesque;
int versionsort(const struct dirent **, const struct dirent **) libcesque;
int scandir(const char *, struct dirent ***, int (*)(const struct dirent *),
int (*)(const struct dirent **, const struct dirent **));
int (*)(const struct dirent **, const struct dirent **)) libcesque;
COSMOPOLITAN_C_END_
#endif /* COSMOPOLITAN_LIBC_CALLS_STRUCT_DIRENT_H_ */
+5 -5
View File
@@ -7,11 +7,11 @@ struct iovec {
size_t iov_len;
};
ssize_t preadv(int, struct iovec *, int, int64_t);
ssize_t pwritev(int, const struct iovec *, int, int64_t);
ssize_t readv(int, const struct iovec *, int);
ssize_t vmsplice(int, const struct iovec *, int64_t, uint32_t);
ssize_t writev(int, const struct iovec *, int);
ssize_t preadv(int, struct iovec *, int, int64_t) libcesque;
ssize_t pwritev(int, const struct iovec *, int, int64_t) libcesque;
ssize_t readv(int, const struct iovec *, int) libcesque;
ssize_t vmsplice(int, const struct iovec *, int64_t, uint32_t) libcesque;
ssize_t writev(int, const struct iovec *, int) libcesque;
COSMOPOLITAN_C_END_
#endif /* COSMOPOLITAN_LIBC_CALLS_STRUCT_IOVEC_H_ */
+2 -2
View File
@@ -7,8 +7,8 @@ struct rlimit {
uint64_t rlim_max; /* maximum limit in bytes */
};
int getrlimit(int, struct rlimit *);
int setrlimit(int, const struct rlimit *);
int getrlimit(int, struct rlimit *) libcesque;
int setrlimit(int, const struct rlimit *) libcesque;
COSMOPOLITAN_C_END_
#endif /* COSMOPOLITAN_LIBC_CALLS_STRUCT_RLIMIT_H_ */
+4 -4
View File
@@ -22,10 +22,10 @@ struct rusage {
int64_t ru_nivcsw; /* involuntary context switches */
};
int getrusage(int, struct rusage *);
int wait3(int *, int, struct rusage *);
int wait4(int, int *, int, struct rusage *);
void rusage_add(struct rusage *, const struct rusage *);
int getrusage(int, struct rusage *) libcesque;
int wait3(int *, int, struct rusage *) libcesque;
int wait4(int, int *, int, struct rusage *) libcesque;
void rusage_add(struct rusage *, const struct rusage *) libcesque;
COSMOPOLITAN_C_END_
#endif /* COSMOPOLITAN_LIBC_CALLS_STRUCT_RUSAGE_H_ */
+7 -7
View File
@@ -7,13 +7,13 @@ struct sched_param {
int32_t sched_priority;
};
int sched_get_priority_max(int);
int sched_get_priority_min(int);
int sched_getparam(int, struct sched_param *);
int sched_getscheduler(int);
int sched_rr_get_interval(int, struct timespec *);
int sched_setparam(int, const struct sched_param *);
int sched_setscheduler(int, int, const struct sched_param *);
int sched_get_priority_max(int) libcesque;
int sched_get_priority_min(int) libcesque;
int sched_getparam(int, struct sched_param *) libcesque;
int sched_getscheduler(int) libcesque;
int sched_rr_get_interval(int, struct timespec *) libcesque;
int sched_setparam(int, const struct sched_param *) libcesque;
int sched_setscheduler(int, int, const struct sched_param *) libcesque;
COSMOPOLITAN_C_END_
#endif /* COSMOPOLITAN_LIBC_CALLS_STRUCT_SCHED_PARAM_H_ */
+2 -2
View File
@@ -17,8 +17,8 @@ struct sigaction {
sigset_t sa_mask;
};
sighandler_t signal(int, sighandler_t);
int sigaction(int, const struct sigaction *, struct sigaction *);
sighandler_t signal(int, sighandler_t) libcesque;
int sigaction(int, const struct sigaction *, struct sigaction *) libcesque;
COSMOPOLITAN_C_END_
#endif /* COSMOPOLITAN_LIBC_CALLS_STRUCT_SIGACTION_H_ */
+1 -1
View File
@@ -10,7 +10,7 @@ struct sigaltstack {
typedef struct sigaltstack stack_t;
int sigaltstack(const struct sigaltstack *, struct sigaltstack *);
int sigaltstack(const struct sigaltstack *, struct sigaltstack *) libcesque;
COSMOPOLITAN_C_END_
#endif /* COSMOPOLITAN_LIBC_CALLS_STRUCT_SIGALTSTACK_H_ */
+2 -2
View File
@@ -57,8 +57,8 @@ struct siginfo {
typedef struct siginfo siginfo_t;
#ifdef _COSMO_SOURCE
void __minicrash(int, siginfo_t *, void *);
char __is_stack_overflow(siginfo_t *, void *);
void __minicrash(int, siginfo_t *, void *) libcesque;
char __is_stack_overflow(siginfo_t *, void *) libcesque;
#endif
COSMOPOLITAN_C_END_
+2 -2
View File
@@ -20,8 +20,8 @@ struct statfs { /* cosmo abi */
char f_fstypename[16];
};
int statfs(const char *, struct statfs *);
int fstatfs(int, struct statfs *);
int statfs(const char *, struct statfs *) libcesque;
int fstatfs(int, struct statfs *) libcesque;
COSMOPOLITAN_C_END_
#endif /* COSMOPOLITAN_LIBC_CALLS_STRUCT_STATFS_H_ */
+1 -1
View File
@@ -19,7 +19,7 @@ struct sysinfo {
uint32_t mem_unit; /* ram stuff above is multiples of this */
};
int sysinfo(struct sysinfo *);
int sysinfo(struct sysinfo *) libcesque;
COSMOPOLITAN_C_END_
#endif /* COSMOPOLITAN_LIBC_CALLS_STRUCT_SYSINFO_H_ */
+27 -24
View File
@@ -8,35 +8,38 @@ struct timespec {
int64_t tv_nsec; /* nanoseconds */
};
int clock_getres(int, struct timespec *);
int clock_gettime(int, struct timespec *);
int clock_settime(int, const struct timespec *);
int clock_getres(int, struct timespec *) libcesque;
int clock_gettime(int, struct timespec *) libcesque;
int clock_settime(int, const struct timespec *) libcesque;
int clock_nanosleep(int, int, const struct timespec *, struct timespec *);
int futimens(int, const struct timespec[2]);
int nanosleep(const struct timespec *, struct timespec *);
int utimensat(int, const char *, const struct timespec[2], int);
int timespec_getres(struct timespec *, int);
int timespec_get(struct timespec *, int);
int futimens(int, const struct timespec[2]) libcesque;
int nanosleep(const struct timespec *, struct timespec *) libcesque;
int utimensat(int, const char *, const struct timespec[2], int) libcesque;
int timespec_getres(struct timespec *, int) libcesque;
int timespec_get(struct timespec *, int) libcesque;
#ifdef _COSMO_SOURCE
/* cosmopolitan libc's non-posix timespec library
removed by default due to emacs codebase clash */
int sys_clock_nanosleep(int, int, const struct timespec *, struct timespec *);
int cosmo_clock_nanosleep(int, int, const struct timespec *, struct timespec *);
#define timespec_zero ((struct timespec){0})
#define timespec_max ((struct timespec){0x7fffffffffffffff, 999999999})
int timespec_cmp(struct timespec, struct timespec) pureconst;
int64_t timespec_tomicros(struct timespec) pureconst;
int64_t timespec_tomillis(struct timespec) pureconst;
int64_t timespec_tonanos(struct timespec) pureconst;
struct timespec timespec_add(struct timespec, struct timespec) pureconst;
struct timespec timespec_fromnanos(int64_t) pureconst;
struct timespec timespec_frommicros(int64_t) pureconst;
struct timespec timespec_frommillis(int64_t) pureconst;
struct timespec timespec_real(void);
struct timespec timespec_mono(void);
struct timespec timespec_sleep(struct timespec);
int timespec_sleep_until(struct timespec);
struct timespec timespec_sub(struct timespec, struct timespec) pureconst;
struct timespec timespec_subz(struct timespec, struct timespec) pureconst;
libcesque int timespec_cmp(struct timespec, struct timespec) pureconst;
libcesque int64_t timespec_tomicros(struct timespec) pureconst;
libcesque int64_t timespec_tomillis(struct timespec) pureconst;
libcesque int64_t timespec_tonanos(struct timespec) pureconst;
libcesque struct timespec timespec_add(struct timespec,
struct timespec) pureconst;
libcesque struct timespec timespec_fromnanos(int64_t) pureconst;
libcesque struct timespec timespec_frommicros(int64_t) pureconst;
libcesque struct timespec timespec_frommillis(int64_t) pureconst;
libcesque struct timespec timespec_real(void) libcesque;
libcesque struct timespec timespec_mono(void) libcesque;
libcesque struct timespec timespec_sleep(struct timespec) libcesque;
libcesque int timespec_sleep_until(struct timespec) libcesque;
libcesque struct timespec timespec_sub(struct timespec,
struct timespec) pureconst;
libcesque struct timespec timespec_subz(struct timespec,
struct timespec) pureconst;
int sys_futex(int *, int, int, const struct timespec *, int *);
static inline struct timespec timespec_fromseconds(int64_t __x) {
return (struct timespec){__x};
+1 -1
View File
@@ -9,7 +9,7 @@ struct tms {
int64_t tms_cstime; /* children kernelspace time */
};
long times(struct tms *);
long times(struct tms *) libcesque;
COSMOPOLITAN_C_END_
#endif /* COSMOPOLITAN_LIBC_CALLS_STRUCT_TMS_H_ */
+1 -1
View File
@@ -14,7 +14,7 @@ struct utsname { /* cosmo abi */
char domainname[SYS_NMLN]; /* domain name */
};
int uname(struct utsname *);
int uname(struct utsname *) libcesque;
COSMOPOLITAN_C_END_
#endif /* COSMOPOLITAN_LIBC_CALLS_STRUCT_UTSNAME_H_ */
+1 -1
View File
@@ -18,7 +18,7 @@ int sys_fcntl_nt_setfl(int, unsigned);
int sys_pause_nt(void);
int64_t __fix_enotdir(int64_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);
void *GetProcAddressModule(const char *, const char *);
void WinMainForked(void);
+24 -24
View File
@@ -8,34 +8,34 @@ COSMOPOLITAN_C_START_
│ cosmopolitan § teletypewriter control ─╬─│┼
╚────────────────────────────────────────────────────────────────────────────│*/
int tcgetattr(int, struct termios *);
int tcsetattr(int, int, const struct termios *);
int tcgetattr(int, struct termios *) libcesque;
int tcsetattr(int, int, const struct termios *) libcesque;
int openpty(int *, int *, char *, const struct termios *,
const struct winsize *) paramsnonnull((1, 2));
int forkpty(int *, char *, const struct termios *, const struct winsize *)
paramsnonnull((1, 2)) __wur;
char *ptsname(int);
errno_t ptsname_r(int, char *, size_t);
const struct winsize *) libcesque paramsnonnull((1, 2));
int forkpty(int *, char *, const struct termios *,
const struct winsize *) libcesque paramsnonnull((1, 2)) __wur;
char *ptsname(int) libcesque;
errno_t ptsname_r(int, char *, size_t) libcesque;
int grantpt(int);
int unlockpt(int);
int posix_openpt(int) __wur;
int grantpt(int) libcesque;
int unlockpt(int) libcesque;
int posix_openpt(int) libcesque __wur;
int tcdrain(int);
int tcgetsid(int);
int tcflow(int, int);
int tcflush(int, int);
int tcsetsid(int, int);
int tcsendbreak(int, int);
void cfmakeraw(struct termios *);
int cfsetspeed(struct termios *, uint32_t);
int cfsetospeed(struct termios *, uint32_t);
int cfsetispeed(struct termios *, uint32_t);
uint32_t cfgetospeed(const struct termios *);
uint32_t cfgetispeed(const struct termios *);
int tcsetwinsize(int, const struct winsize *);
int tcgetwinsize(int, struct winsize *);
int tcdrain(int) libcesque;
int tcgetsid(int) libcesque;
int tcflow(int, int) libcesque;
int tcflush(int, int) libcesque;
int tcsetsid(int, int) libcesque;
int tcsendbreak(int, int) libcesque;
void cfmakeraw(struct termios *) libcesque;
int cfsetspeed(struct termios *, uint32_t) libcesque;
int cfsetospeed(struct termios *, uint32_t) libcesque;
int cfsetispeed(struct termios *, uint32_t) libcesque;
uint32_t cfgetospeed(const struct termios *) libcesque;
uint32_t cfgetispeed(const struct termios *) libcesque;
int tcsetwinsize(int, const struct winsize *) libcesque;
int tcgetwinsize(int, struct winsize *) libcesque;
COSMOPOLITAN_C_END_
#endif /* COSMOPOLITAN_LIBC_CALLS_TERMIOS_H_ */
Loaded 100 of 1965 files, more files were not shown because too many files have changed in this diff. Show more