mirror of
https://github.com/jart/cosmopolitan.git
synced 2026-11-08 08:08:04 -10:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
98d06b23cc | ||
|
|
9ff65cff63 | ||
|
|
bef2cb05ff | ||
|
|
43885a76e4 | ||
|
|
74a85087de | ||
|
|
045632a743 | ||
|
|
9a10adac35 | ||
|
|
0c12c26e1d | ||
|
|
40b7da8422 | ||
|
|
640668931d | ||
|
|
1c34088ba0 | ||
|
|
bb92347158 | ||
|
|
8bfd56b59e | ||
|
|
a6baba1b07 | ||
|
|
c8383f25b4 | ||
|
|
64a9e6fe56 | ||
|
|
0ef36489c8 | ||
|
|
7c7bf4bb90 | ||
|
|
592f6ebc20 | ||
|
|
af8f2bd19f | ||
|
|
38bceaeb8f | ||
|
|
99f0491f04 | ||
|
|
e72a88ea70 | ||
|
|
9b4701b3bc | ||
|
|
f7ff515961 | ||
|
|
3afe3a3646 | ||
|
|
b4faaa7c57 | ||
|
|
c4991e53ac | ||
|
|
ad3944a3b6 | ||
|
|
29eac8e2a2 | ||
|
|
a5a3e78fcf | ||
|
|
e9a756e78b | ||
|
|
38af54a2dd | ||
|
|
77a92f517b | ||
|
|
3eb405e0e2 | ||
|
|
68b9479f0c | ||
|
|
d9df41c4d5 | ||
|
|
fc3c536ec2 | ||
|
|
77ddf4cb07 | ||
|
|
4d018306b3 | ||
|
|
b3bb93d1d9 | ||
|
|
980af27bbf | ||
|
|
957c61cbbf | ||
|
|
d3ff48c63f | ||
|
|
2ab9e9f7fd | ||
|
|
d5225a693b | ||
|
|
c72904b2f6 | ||
|
|
616717fa82 | ||
|
|
369aebfc48 | ||
|
|
5f8e9f14c1 | ||
|
|
c1e18e7903 | ||
|
|
f27808c4d2 | ||
|
|
2719080986 | ||
|
|
33418f6742 | ||
|
|
83a8686c06 | ||
|
|
8ab3a545c6 | ||
|
|
8ebe2e9020 | ||
|
|
51cd83f674 | ||
|
|
39b0a9c03e | ||
|
|
d50064a779 | ||
|
|
1226eb7a5e | ||
|
|
8834dde0c2 | ||
|
|
1ef63eb206 | ||
|
|
08793aa143 | ||
|
|
6db1200a7e | ||
|
|
a2753de7fd | ||
|
|
6715b670b1 | ||
|
|
fd75fd1467 | ||
|
|
5d80e8dbf6 | ||
|
|
eeb20775d2 | ||
|
|
cb19e172da | ||
|
|
df648fb174 | ||
|
|
9a6af92bed | ||
|
|
6ab01716ce | ||
|
|
21093044c0 | ||
|
|
b8a9fbbd01 | ||
|
|
81ce2e4cbc | ||
|
|
07db3004d6 | ||
|
|
b0566348b2 | ||
|
|
8fb24a8f88 | ||
|
|
a4b455185b | ||
|
|
6cb0354e19 | ||
|
|
b580080af1 | ||
|
|
8b33204f37 | ||
|
|
94bab1618d | ||
|
|
cafea9a0a5 | ||
|
|
16099801cc | ||
|
|
4cd02c29ed | ||
|
|
5ae2554c10 | ||
|
|
531ac85923 | ||
|
|
8d9fcb5e5a | ||
|
|
aa37a327ea | ||
|
|
c4205f8305 | ||
|
|
b3fb6cff43 | ||
|
|
2e5f662dfe | ||
|
|
5e7137097d | ||
|
|
f224a55d57 | ||
|
|
0c51995b2b | ||
|
|
a9f23ccd17 | ||
|
|
57d1bf7a9c | ||
|
|
ce17ed60df | ||
|
|
d27a47b0e2 | ||
|
|
390335eb45 | ||
|
|
492a8f4f53 | ||
|
|
636bc4007b | ||
|
|
b09096691a |
No files matched your search
+1
-1
@@ -2,7 +2,7 @@
|
||||
|
||||
/o
|
||||
/cosmocc
|
||||
/.prompt.jtlp
|
||||
/.cosmocc
|
||||
|
||||
# TODO: Find some way to have Python write to o/
|
||||
__pycache__
|
||||
|
||||
Vendored
+1
-2
@@ -48,11 +48,10 @@
|
||||
"notpossible=",
|
||||
"thatispacked=",
|
||||
"dontthrow=",
|
||||
"nocallback=",
|
||||
"dontcallback=",
|
||||
"relegated=",
|
||||
"hidden=",
|
||||
"textstartup=",
|
||||
"initarray=",
|
||||
"returnsnonnull=",
|
||||
"returnspointerwithnoaliases=",
|
||||
"printfesque(x)=",
|
||||
|
||||
+69
-45
@@ -2,23 +2,77 @@
|
||||
|
||||
We'd love to accept your patches! Please read this guide first.
|
||||
|
||||
## Identity Disclosure
|
||||
|
||||
This project does not accept anonymous contributions. Justine Tunney
|
||||
won't merge pull requests from strangers. In order to change the Cosmo
|
||||
codebase, and have your changes be upstreamed, she has to know who you
|
||||
are. You're encouraged to disclose your full name and email address to
|
||||
the public too, by including them in your git commit messages; however
|
||||
that's not a requirement; as we're happy to respect the wishes of
|
||||
contributors who prefer to remain anonymous to the public.
|
||||
|
||||
## Copyright Assignment
|
||||
|
||||
Please 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. Please use the same email address you use for git commits
|
||||
which should only contain original source code from you or other people
|
||||
who are also assigning copyright. Please note that, if you're employed,
|
||||
you may need to get your employer's approval beforehand. If you can not
|
||||
assign copyright due to local laws, then you may alternatively consider
|
||||
disclaiming it using the language in [Unlicense](https://unlicense.org)
|
||||
or [CC-0](http://creativecommons.org/share-your-work/public-domain/cc0)
|
||||
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. 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.
|
||||
|
||||
This is important because we can't produce 12kb single-file executables
|
||||
that comply with license requirements if we have to embed lots of them.
|
||||
Although that's less of an issue depending on the purpose of the files.
|
||||
For example, ownership is much less of a concern in the unit test files
|
||||
so you're encouraged to put your copyright on those, provided it's ISC.
|
||||
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
|
||||
get your employer's approval to do this beforehand. Even with big
|
||||
companies like Google, this process is quick and painless. Usually we
|
||||
see employers granting authorization in less than one day.
|
||||
|
||||
If you live in a country that doesn't recognize one's ability to assign
|
||||
copyright, then you may alternatively consider disclaiming it using the
|
||||
language in [Unlicense](https://unlicense.org) or
|
||||
[CC-0](http://creativecommons.org/share-your-work/public-domain/cc0).
|
||||
|
||||
If you're checking-in third party code, then you need to have headers at
|
||||
the top of each source file (but never header files) documenting its
|
||||
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
|
||||
|
||||
@@ -29,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).
|
||||
@@ -21,23 +21,23 @@
|
||||
# make -j8 -O MODE=tiny
|
||||
#
|
||||
# # build individual target
|
||||
# make -j8 -O o//examples/hello.com
|
||||
# o//examples/hello.com
|
||||
# make -j8 -O o//examples/hello
|
||||
# o//examples/hello
|
||||
#
|
||||
# # view source
|
||||
# less examples/hello.c
|
||||
#
|
||||
# # view binary
|
||||
# o//tool/viz/bing.com o//examples/hello.com |
|
||||
# o//tool/viz/fold.com
|
||||
# o//tool/viz/bing o//examples/hello |
|
||||
# o//tool/viz/fold
|
||||
#
|
||||
# # view transitive closure of legalese
|
||||
# o//tool/viz/bing.com -n o//examples/hello.com |
|
||||
# o//tool/viz/fold.com
|
||||
# o//tool/viz/bing -n o//examples/hello |
|
||||
# o//tool/viz/fold
|
||||
#
|
||||
# # basic debugging
|
||||
# make -j8 -O MODE=dbg o/dbg/examples/crashreport.com
|
||||
# o/examples/crashreport.com
|
||||
# make -j8 -O MODE=dbg o/dbg/examples/crashreport
|
||||
# o/examples/crashreport
|
||||
# less examples/crashreport.c
|
||||
#
|
||||
# # extremely tiny binaries
|
||||
@@ -51,7 +51,7 @@
|
||||
#
|
||||
# TROUBLESHOOTING
|
||||
#
|
||||
# make -j8 -O V=1 o//examples/hello.com
|
||||
# make -j8 -O V=1 o//examples/hello
|
||||
# make o//examples/life.elf -pn |& less
|
||||
# etc.
|
||||
#
|
||||
@@ -59,7 +59,7 @@
|
||||
#
|
||||
# build/config.mk
|
||||
|
||||
SHELL = build/bootstrap/cocmd.com
|
||||
SHELL = build/bootstrap/cocmd
|
||||
MAKEFLAGS += --no-builtin-rules
|
||||
|
||||
.SUFFIXES:
|
||||
@@ -77,8 +77,8 @@ COMMA := ,
|
||||
PWD := $(shell pwd)
|
||||
|
||||
# detect wsl2 running cosmopolitan binaries on the host by checking whether:
|
||||
# - user ran build/bootstrap/make.com, in which case make's working directory is in wsl
|
||||
# - user ran make, in which case cocmd.com's working directory is in wsl
|
||||
# - user ran build/bootstrap/make, in which case make's working directory is in wsl
|
||||
# - user ran make, in which case cocmd's working directory is in wsl
|
||||
ifneq ($(findstring //wsl.localhost/,$(CURDIR) $(PWD)),)
|
||||
$(warning wsl2 interop is enabled)
|
||||
$(error you need to run sudo sh -c 'echo -1 > /proc/sys/fs/binfmt_misc/WSLInterop')
|
||||
@@ -89,7 +89,7 @@ UNAME_S := $(shell uname -s)
|
||||
|
||||
# apple still distributes a 17 year old version of gnu make
|
||||
ifeq ($(MAKE_VERSION), 3.81)
|
||||
$(error please use build/bootstrap/make.com)
|
||||
$(error please use build/bootstrap/make)
|
||||
endif
|
||||
|
||||
LC_ALL = C
|
||||
@@ -101,31 +101,42 @@ 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
|
||||
GZIP = build/bootstrap/gzip.com
|
||||
ECHO = build/bootstrap/echo.com
|
||||
CHMOD = build/bootstrap/chmod.com
|
||||
TOUCH = build/bootstrap/touch.com
|
||||
PKG = build/bootstrap/package.com
|
||||
MKDEPS = build/bootstrap/mkdeps.com
|
||||
ZIPOBJ = build/bootstrap/zipobj.com
|
||||
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)
|
||||
AR = build/bootstrap/ar
|
||||
CP = build/bootstrap/cp
|
||||
RM = build/bootstrap/rm -f
|
||||
GZIP = build/bootstrap/gzip
|
||||
ECHO = build/bootstrap/echo
|
||||
CHMOD = build/bootstrap/chmod
|
||||
TOUCH = build/bootstrap/touch
|
||||
PKG = build/bootstrap/package
|
||||
MKDEPS = build/bootstrap/mkdeps
|
||||
ZIPOBJ = build/bootstrap/zipobj
|
||||
ZIPCOPY = build/bootstrap/zipcopy
|
||||
PECHECK = build/bootstrap/pecheck
|
||||
FIXUPOBJ = build/bootstrap/fixupobj
|
||||
MKDIR = build/bootstrap/mkdir -p
|
||||
COMPILE = build/bootstrap/compile -V9 -M2048m -P8192 $(QUOTA)
|
||||
|
||||
IGNORE := $(shell $(MKDIR) $(TMPDIR))
|
||||
|
||||
# the default build modes is empty string
|
||||
# on x86_64 hosts, MODE= is the same as MODE=x86_64
|
||||
# on aarch64 hosts, MODE= is changed to MODE=aarch64
|
||||
ifeq ($(MODE),)
|
||||
ifeq ($(UNAME_M),arm64)
|
||||
MODE := aarch64
|
||||
endif
|
||||
ifeq ($(UNAME_M),aarch64)
|
||||
MODE := aarch64
|
||||
endif
|
||||
endif
|
||||
|
||||
ifneq ($(findstring aarch64,$(MODE)),)
|
||||
ARCH = aarch64
|
||||
HOSTS ?= pi studio freebsdarm
|
||||
HOSTS ?= pi pi5 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)
|
||||
@@ -138,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
|
||||
@@ -158,18 +169,6 @@ else
|
||||
ADDR2LINE = $(TOOLCHAIN)addr2line
|
||||
endif
|
||||
|
||||
# the default build modes is empty string
|
||||
# on x86_64 hosts, MODE= is the same as MODE=x86_64
|
||||
# on aarch64 hosts, MODE= is changed to MODE=aarch64
|
||||
ifeq ($(MODE),)
|
||||
ifeq ($(UNAME_M),arm64)
|
||||
MODE := aarch64
|
||||
endif
|
||||
ifeq ($(UNAME_M),aarch64)
|
||||
MODE := aarch64
|
||||
endif
|
||||
endif
|
||||
|
||||
# primary build rules
|
||||
all: o
|
||||
o: o/$(MODE)
|
||||
@@ -188,7 +187,7 @@ o/$(MODE): \
|
||||
o/$(MODE)/: o/$(MODE)
|
||||
o/$(MODE)/.: o/$(MODE)
|
||||
|
||||
# check if we're using o//third_party/make/make.com
|
||||
# check if we're using o//third_party/make/make
|
||||
# we added sandboxing to guarantee cosmo's makefile is hermetic
|
||||
# it also shaves away 200ms of startup latency with native $(uniq)
|
||||
ifneq ($(LANDLOCKMAKE_VERSION),)
|
||||
@@ -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 \
|
||||
@@ -249,7 +247,6 @@ include libc/calls/BUILD.mk #─┐
|
||||
include libc/irq/BUILD.mk # ├──SYSTEMS RUNTIME
|
||||
include third_party/nsync/BUILD.mk # │ You can issue system calls
|
||||
include libc/runtime/BUILD.mk # │
|
||||
include third_party/double-conversion/BUILD.mk # │
|
||||
include libc/crt/BUILD.mk # │
|
||||
include third_party/dlmalloc/BUILD.mk #─┘
|
||||
include libc/mem/BUILD.mk #─┐
|
||||
@@ -284,7 +281,11 @@ include third_party/stb/BUILD.mk # │
|
||||
include third_party/mbedtls/BUILD.mk # │
|
||||
include third_party/ncurses/BUILD.mk # │
|
||||
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 # │
|
||||
include net/https/BUILD.mk # │
|
||||
@@ -296,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
|
||||
@@ -316,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
|
||||
@@ -328,6 +330,7 @@ include third_party/python/BUILD.mk
|
||||
include tool/build/BUILD.mk
|
||||
include tool/curl/BUILD.mk
|
||||
include third_party/qemu/BUILD.mk
|
||||
include third_party/libcxxabi/test/BUILD.mk
|
||||
include examples/BUILD.mk
|
||||
include examples/pyapp/BUILD.mk
|
||||
include examples/pylife/BUILD.mk
|
||||
@@ -412,17 +415,17 @@ o/$(MODE)/hdrs-old.txt: o/$(MODE)/.x $(MAKEFILES) $(call uniq,$(foreach x,$(HDRS
|
||||
$(file >$@) $(foreach x,$(HDRS) $(INCS),$(file >>$@,$(x)))
|
||||
|
||||
TAGS: private .UNSANDBOXED = 1
|
||||
TAGS: o/$(MODE)/srcs-old.txt $(SRCS) #o/$(MODE)/third_party/ctags/ctags.com
|
||||
TAGS: o/$(MODE)/srcs-old.txt $(SRCS) #o/$(MODE)/third_party/ctags/ctags
|
||||
@$(RM) $@
|
||||
@o/$(MODE)/third_party/ctags/ctags.com $(TAGSFLAGS) -L $< -o $@
|
||||
@o/$(MODE)/third_party/ctags/ctags $(TAGSFLAGS) -L $< -o $@
|
||||
|
||||
HTAGS: private .UNSANDBOXED = 1
|
||||
HTAGS: o/$(MODE)/hdrs-old.txt $(filter-out third_party/libcxx/%,$(HDRS)) #o/$(MODE)/third_party/ctags/ctags.com
|
||||
HTAGS: o/$(MODE)/hdrs-old.txt $(filter-out third_party/libcxx/%,$(HDRS)) #o/$(MODE)/third_party/ctags/ctags
|
||||
@$(RM) $@
|
||||
@build/htags o/$(MODE)/third_party/ctags/ctags.com -L $< -o $@
|
||||
@build/htags o/$(MODE)/third_party/ctags/ctags -L $< -o $@
|
||||
|
||||
loc: private .UNSANDBOXED = 1
|
||||
loc: o/$(MODE)/tool/build/summy.com
|
||||
loc: o/$(MODE)/tool/build/summy
|
||||
find -name \*.h -or -name \*.c -or -name \*.S | \
|
||||
$(XARGS) wc -l | grep total | awk '{print $$1}' | $<
|
||||
|
||||
@@ -438,8 +441,11 @@ COSMOPOLITAN_OBJECTS = \
|
||||
THIRD_PARTY_GETOPT \
|
||||
LIBC_LOG \
|
||||
LIBC_TIME \
|
||||
THIRD_PARTY_OPENMP \
|
||||
THIRD_PARTY_MUSL \
|
||||
THIRD_PARTY_ZLIB_GZ \
|
||||
THIRD_PARTY_LIBCXXABI \
|
||||
THIRD_PARTY_LIBUNWIND \
|
||||
LIBC_STDIO \
|
||||
THIRD_PARTY_GDTOA \
|
||||
THIRD_PARTY_REGEX \
|
||||
@@ -474,6 +480,7 @@ COSMOPOLITAN_OBJECTS = \
|
||||
LIBC_STR \
|
||||
LIBC_SYSV \
|
||||
LIBC_INTRIN \
|
||||
LIBC_NT_BCRYPTPRIMITIVES \
|
||||
LIBC_NT_KERNEL32 \
|
||||
LIBC_NEXGEN32E
|
||||
|
||||
@@ -509,12 +516,16 @@ COSMOPOLITAN_H_PKGS = \
|
||||
THIRD_PARTY_GETOPT \
|
||||
THIRD_PARTY_MUSL \
|
||||
THIRD_PARTY_ZLIB \
|
||||
THIRD_PARTY_ZLIB_GZ \
|
||||
THIRD_PARTY_REGEX
|
||||
|
||||
COSMOCC_PKGS = \
|
||||
$(COSMOPOLITAN_H_PKGS) \
|
||||
THIRD_PARTY_AARCH64 \
|
||||
THIRD_PARTY_LIBCXX \
|
||||
THIRD_PARTY_LIBCXXABI \
|
||||
THIRD_PARTY_LIBUNWIND \
|
||||
THIRD_PARTY_OPENMP \
|
||||
THIRD_PARTY_INTEL
|
||||
|
||||
o/$(MODE)/cosmopolitan.a: \
|
||||
@@ -539,19 +550,16 @@ o/cosmopolitan.h: o/cosmopolitan.h.txt \
|
||||
$(wildcard libc/integral/*) \
|
||||
$(foreach x,$(COSMOPOLITAN_H_PKGS),$($(x)_HDRS)) \
|
||||
$(foreach x,$(COSMOPOLITAN_H_PKGS),$($(x)_INCS))
|
||||
@$(ECHO) '#ifndef __STRICT_ANSI__' >$@
|
||||
@$(ECHO) '#define _COSMO_SOURCE' >>$@
|
||||
@$(ECHO) '#endif' >>$@
|
||||
@$(COMPILE) -AROLLUP -T$@ build/bootstrap/rollup.com @$< >>$@
|
||||
@$(COMPILE) -AROLLUP -T$@ build/bootstrap/rollup @$< >>$@
|
||||
|
||||
o/cosmopolitan.html: private .UNSANDBOXED = 1
|
||||
o/cosmopolitan.html: \
|
||||
o/$(MODE)/third_party/chibicc/chibicc.com.dbg \
|
||||
o/$(MODE)/third_party/chibicc/chibicc.dbg \
|
||||
$(filter-out %.s,$(foreach x,$(COSMOPOLITAN_OBJECTS),$($(x)_SRCS))) \
|
||||
$(SRCS) \
|
||||
$(filter-out %.cpp,$(filter-out %.cc,$(SRCS))) \
|
||||
$(HDRS)
|
||||
$(file >$(TMPDIR)/$(subst /,_,$@),$(filter-out %.s,$(foreach x,$(COSMOPOLITAN_OBJECTS),$($(x)_SRCS))))
|
||||
o/$(MODE)/third_party/chibicc/chibicc.com.dbg -J \
|
||||
$(file >$(TMPDIR)/$(subst /,_,$@),$(filter-out %.cpp,$(filter-out %.cc,$(filter-out %.s,$(foreach x,$(COSMOPOLITAN_OBJECTS),$($(x)_SRCS))))))
|
||||
o/$(MODE)/third_party/chibicc/chibicc.dbg -J \
|
||||
-fno-common -include libc/integral/normalize.inc -o $@ \
|
||||
-DCOSMO @$(TMPDIR)/$(subst /,_,$@)
|
||||
|
||||
@@ -574,13 +582,13 @@ TOOLCHAIN_ARTIFACTS = \
|
||||
o/$(MODE)/ape/ape-no-modify-self.o \
|
||||
o/$(MODE)/cosmopolitan.a \
|
||||
o/$(MODE)/third_party/libcxx/libcxx.a \
|
||||
o/$(MODE)/tool/build/march-native.com \
|
||||
o/$(MODE)/tool/build/ar.com \
|
||||
o/$(MODE)/tool/build/mktemper.com \
|
||||
o/$(MODE)/tool/build/fixupobj.com \
|
||||
o/$(MODE)/tool/build/zipcopy.com \
|
||||
o/$(MODE)/tool/build/apelink.com \
|
||||
o/$(MODE)/tool/build/pecheck.com
|
||||
o/$(MODE)/tool/build/march-native \
|
||||
o/$(MODE)/tool/build/ar \
|
||||
o/$(MODE)/tool/build/mktemper \
|
||||
o/$(MODE)/tool/build/fixupobj \
|
||||
o/$(MODE)/tool/build/zipcopy \
|
||||
o/$(MODE)/tool/build/apelink \
|
||||
o/$(MODE)/tool/build/pecheck
|
||||
else
|
||||
TOOLCHAIN_ARTIFACTS = \
|
||||
o/$(MODE)/ape/ape.elf \
|
||||
@@ -588,9 +596,9 @@ TOOLCHAIN_ARTIFACTS = \
|
||||
o/$(MODE)/libc/crt/crt.o \
|
||||
o/$(MODE)/cosmopolitan.a \
|
||||
o/$(MODE)/third_party/libcxx/libcxx.a \
|
||||
o/$(MODE)/tool/build/march-native.com \
|
||||
o/$(MODE)/tool/build/fixupobj.com \
|
||||
o/$(MODE)/tool/build/zipcopy.com
|
||||
o/$(MODE)/tool/build/march-native \
|
||||
o/$(MODE)/tool/build/fixupobj \
|
||||
o/$(MODE)/tool/build/zipcopy
|
||||
endif
|
||||
|
||||
.PHONY: toolchain
|
||||
|
||||
@@ -92,8 +92,8 @@ guaranteed to be compatible and furthermore includes our extensions for
|
||||
doing build system sandboxing.
|
||||
|
||||
```sh
|
||||
build/bootstrap/make.com -j8
|
||||
o//examples/hello.com
|
||||
build/bootstrap/make -j8
|
||||
o//examples/hello
|
||||
```
|
||||
|
||||
Since the Cosmopolitan repository is very large, you might only want to
|
||||
@@ -103,8 +103,8 @@ depends on core LIBC packages.
|
||||
|
||||
```sh
|
||||
rm -rf o//libc o//test
|
||||
build/bootstrap/make.com o//test/posix/signal_test.com
|
||||
o//test/posix/signal_test.com
|
||||
build/bootstrap/make o//test/posix/signal_test
|
||||
o//test/posix/signal_test
|
||||
```
|
||||
|
||||
Sometimes it's desirable to build a subset of targets, without having to
|
||||
@@ -112,21 +112,21 @@ list out each individual one. For example if you wanted to build and run
|
||||
all the unit tests in the `TEST_POSIX` package, you could say:
|
||||
|
||||
```sh
|
||||
build/bootstrap/make.com o//test/posix
|
||||
build/bootstrap/make o//test/posix
|
||||
```
|
||||
|
||||
Cosmopolitan provides a variety of build modes. For example, if you want
|
||||
really tiny binaries (as small as 12kb in size) then you'd say:
|
||||
|
||||
```sh
|
||||
build/bootstrap/make.com m=tiny
|
||||
build/bootstrap/make m=tiny
|
||||
```
|
||||
|
||||
You can furthermore cut out the bloat of other operating systems, and
|
||||
have Cosmopolitan become much more similar to Musl Libc.
|
||||
|
||||
```sh
|
||||
build/bootstrap/make.com m=tinylinux
|
||||
build/bootstrap/make m=tinylinux
|
||||
```
|
||||
|
||||
For further details, see [//build/config.mk](build/config.mk).
|
||||
@@ -179,11 +179,11 @@ end
|
||||
src
|
||||
```
|
||||
|
||||
You normally run the `.com.dbg` file under gdb. If you need to debug the
|
||||
`.com` file itself, then you can load the debug symbols independently as
|
||||
You normally run the `.dbg` file under gdb. If you need to debug the
|
||||
`` file itself, then you can load the debug symbols independently as
|
||||
|
||||
```sh
|
||||
gdb foo.com -ex 'add-symbol-file foo.com.dbg 0x401000'
|
||||
gdb foo -ex 'add-symbol-file foo.dbg 0x401000'
|
||||
```
|
||||
|
||||
## Platform Notes
|
||||
@@ -242,16 +242,16 @@ server. You're welcome to join us! <https://discord.gg/FwAVVu7eJ4>
|
||||
|
||||
## Support Vector
|
||||
|
||||
| Platform | Min Version | Circa |
|
||||
| :--- | ---: | ---: |
|
||||
| AMD | K8 Venus | 2005 |
|
||||
| Intel | Core | 2006 |
|
||||
| Linux | 2.6.18 | 2007 |
|
||||
| Windows | 8 [1] | 2012 |
|
||||
| Mac OS X | 15.6 | 2018 |
|
||||
| OpenBSD | 7 | 2021 |
|
||||
| FreeBSD | 13 | 2020 |
|
||||
| NetBSD | 9.2 | 2021 |
|
||||
| Platform | Min Version | Circa |
|
||||
| :--- | ---: | ---: |
|
||||
| AMD | K8 Venus | 2005 |
|
||||
| Intel | Core | 2006 |
|
||||
| Linux | 2.6.18 | 2007 |
|
||||
| Windows | 8 [1] | 2012 |
|
||||
| Darwin (macOS) | 23.1.0+ | 2023 |
|
||||
| OpenBSD | 7 | 2021 |
|
||||
| FreeBSD | 13 | 2020 |
|
||||
| NetBSD | 9.2 | 2021 |
|
||||
|
||||
[1] See our [vista branch](https://github.com/jart/cosmopolitan/tree/vista)
|
||||
for a community supported version of Cosmopolitan that works on Windows
|
||||
|
||||
+3
-13
@@ -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) \
|
||||
@@ -226,10 +220,10 @@ o/$(MODE)/ape/loader-xnu-clang.asm: ape/loader.c
|
||||
@$(COMPILE) -AOBJECTIFY.c $(CLANG) -DSUPPORT_VECTOR=8 -S -g0 $(APE_LOADER_FLAGS)
|
||||
|
||||
o/$(MODE)/ape/ape.elf: o/$(MODE)/ape/ape.elf.dbg
|
||||
@$(COMPILE) -AOBJBINCOPY -w build/bootstrap/objbincopy.com -f -o $@ $<
|
||||
@$(COMPILE) -AOBJBINCOPY -w build/bootstrap/objbincopy -f -o $@ $<
|
||||
|
||||
o/$(MODE)/ape/ape.macho: o/$(MODE)/ape/ape.elf.dbg
|
||||
@$(COMPILE) -AOBJBINCOPY -w build/bootstrap/objbincopy.com -fm -o $@ $<
|
||||
@$(COMPILE) -AOBJBINCOPY -w build/bootstrap/objbincopy -fm -o $@ $<
|
||||
|
||||
APE_LOADER_LDFLAGS = \
|
||||
-static \
|
||||
@@ -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
@@ -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 = .;
|
||||
}
|
||||
|
||||
|
||||
+91
-97
@@ -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,43 +96,51 @@ 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
|
||||
#define ELFDATA2LSB 1
|
||||
#define EM_AARCH64 183
|
||||
#define ET_EXEC 2
|
||||
#define ET_DYN 3
|
||||
#define PT_LOAD 1
|
||||
#define PT_DYNAMIC 2
|
||||
#define PT_INTERP 3
|
||||
#define EI_CLASS 4
|
||||
#define EI_DATA 5
|
||||
#define PF_X 1
|
||||
#define PF_W 2
|
||||
#define PF_R 4
|
||||
#define AT_PHDR 3
|
||||
#define AT_PHENT 4
|
||||
#define AT_PHNUM 5
|
||||
#define AT_PAGESZ 6
|
||||
#define AT_BASE 7
|
||||
#define AT_ENTRY 9
|
||||
#define AT_UID 11
|
||||
#define AT_EUID 12
|
||||
#define AT_GID 13
|
||||
#define AT_EGID 14
|
||||
#define AT_HWCAP 16
|
||||
#define AT_HWCAP2 16
|
||||
#define AT_SECURE 23
|
||||
#define AT_RANDOM 25
|
||||
#define AT_EXECFN 31
|
||||
#define ELFCLASS32 1
|
||||
#define ELFDATA2LSB 1
|
||||
#define EM_AARCH64 183
|
||||
#define ET_EXEC 2
|
||||
#define ET_DYN 3
|
||||
#define PT_LOAD 1
|
||||
#define PT_DYNAMIC 2
|
||||
#define PT_INTERP 3
|
||||
#define EI_CLASS 4
|
||||
#define EI_DATA 5
|
||||
#define PF_X 1
|
||||
#define PF_W 2
|
||||
#define PF_R 4
|
||||
#define AT_PHDR 3
|
||||
#define AT_PHENT 4
|
||||
#define AT_PHNUM 5
|
||||
#define AT_PAGESZ 6
|
||||
#define AT_BASE 7
|
||||
#define AT_FLAGS 8
|
||||
#define AT_FLAGS_PRESERVE_ARGV0_BIT 0
|
||||
#define AT_FLAGS_PRESERVE_ARGV0 (1 << AT_FLAGS_PRESERVE_ARGV0_BIT)
|
||||
#define AT_ENTRY 9
|
||||
#define AT_UID 11
|
||||
#define AT_EUID 12
|
||||
#define AT_GID 13
|
||||
#define AT_EGID 14
|
||||
#define AT_HWCAP 16
|
||||
#define AT_HWCAP2 16
|
||||
#define AT_SECURE 23
|
||||
#define AT_RANDOM 25
|
||||
#define AT_EXECFN 31
|
||||
|
||||
#define AUXV_WORDS 29
|
||||
#define AUXV_WORDS 31
|
||||
|
||||
/* from the xnu codebase */
|
||||
#define _COMM_PAGE_START_ADDRESS 0x0000000FFFFFC000ul
|
||||
@@ -322,17 +330,7 @@ static char AccessCommand(struct PathSearcher *ps, unsigned long pathlen) {
|
||||
if (pathlen && ps->path[pathlen - 1] != '/') ps->path[pathlen++] = '/';
|
||||
memmove(ps->path + pathlen, ps->name, ps->namelen);
|
||||
ps->path[pathlen + ps->namelen] = 0;
|
||||
if (!access(ps->path, X_OK)) {
|
||||
if (ps->indirect) {
|
||||
ps->namelen -= 4;
|
||||
ps->path[pathlen + ps->namelen] = 0;
|
||||
if (access(ps->path, X_OK) < 0) {
|
||||
Pexit(ps->path, -errno, "access(X_OK)");
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
return !access(ps->path, X_OK);
|
||||
}
|
||||
|
||||
static char SearchPath(struct PathSearcher *ps) {
|
||||
@@ -358,12 +356,8 @@ static char FindCommand(struct PathSearcher *ps) {
|
||||
ps->path[0] = 0;
|
||||
|
||||
/* paths are always 100% taken literally when a slash exists
|
||||
$ ape foo/bar.com arg1 arg2 */
|
||||
if (memchr(ps->name, '/', ps->namelen)) {
|
||||
return AccessCommand(ps, 0);
|
||||
}
|
||||
|
||||
/* we don't run files in the current directory
|
||||
$ ape foo/bar.com arg1 arg2
|
||||
we don't run files in the current directory
|
||||
$ ape foo.com arg1 arg2
|
||||
unless $PATH has an empty string entry, e.g.
|
||||
$ expert PATH=":/bin"
|
||||
@@ -371,8 +365,8 @@ static char FindCommand(struct PathSearcher *ps) {
|
||||
however we will execute this
|
||||
$ ape - foo.com foo.com arg1 arg2
|
||||
because cosmo's execve needs it */
|
||||
if (ps->literally && AccessCommand(ps, 0)) {
|
||||
return 1;
|
||||
if (ps->literally || memchr(ps->name, '/', ps->namelen)) {
|
||||
return AccessCommand(ps, 0);
|
||||
}
|
||||
|
||||
/* otherwise search for name on $PATH */
|
||||
@@ -382,7 +376,8 @@ static char FindCommand(struct PathSearcher *ps) {
|
||||
static char *Commandv(struct PathSearcher *ps, const char *name,
|
||||
const char *syspath) {
|
||||
ps->syspath = syspath ? syspath : "/bin:/usr/local/bin:/usr/bin";
|
||||
if (!(ps->namelen = StrLen((ps->name = name)))) return 0;
|
||||
ps->name = name;
|
||||
if (!(ps->namelen = ps->indirect ? ps->indirect : StrLen(ps->name))) return 0;
|
||||
if (ps->namelen + 1 > sizeof(ps->path)) return 0;
|
||||
if (FindCommand(ps)) {
|
||||
return ps->path;
|
||||
@@ -670,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) {
|
||||
@@ -684,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");
|
||||
@@ -822,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)) ==
|
||||
@@ -861,25 +854,27 @@ static const char *TryElf(struct ApeLoader *M, union ElfEhdrBuf *ebuf,
|
||||
auxv[7] = ebuf->ehdr.e_entry;
|
||||
auxv[8] = AT_PAGESZ;
|
||||
auxv[9] = pagesz;
|
||||
auxv[10] = AT_UID;
|
||||
auxv[11] = getuid();
|
||||
auxv[12] = AT_EUID;
|
||||
auxv[13] = geteuid();
|
||||
auxv[14] = AT_GID;
|
||||
auxv[15] = getgid();
|
||||
auxv[16] = AT_EGID;
|
||||
auxv[17] = getegid();
|
||||
auxv[18] = AT_HWCAP;
|
||||
auxv[19] = 0xffb3ffffu;
|
||||
auxv[20] = AT_HWCAP2;
|
||||
auxv[21] = 0x181;
|
||||
auxv[22] = AT_SECURE;
|
||||
auxv[23] = issetugid();
|
||||
auxv[24] = AT_RANDOM;
|
||||
auxv[25] = (long)M->rando;
|
||||
auxv[26] = AT_EXECFN;
|
||||
auxv[27] = (long)execfn;
|
||||
auxv[28] = 0;
|
||||
auxv[10] = AT_FLAGS;
|
||||
auxv[11] = M->ps.literally ? AT_FLAGS_PRESERVE_ARGV0 : 0;
|
||||
auxv[12] = AT_UID;
|
||||
auxv[13] = getuid();
|
||||
auxv[14] = AT_EUID;
|
||||
auxv[15] = geteuid();
|
||||
auxv[16] = AT_GID;
|
||||
auxv[17] = getgid();
|
||||
auxv[18] = AT_EGID;
|
||||
auxv[19] = getegid();
|
||||
auxv[20] = AT_HWCAP;
|
||||
auxv[21] = 0xffb3ffffu;
|
||||
auxv[22] = AT_HWCAP2;
|
||||
auxv[23] = 0x181;
|
||||
auxv[24] = AT_SECURE;
|
||||
auxv[25] = issetugid();
|
||||
auxv[26] = AT_RANDOM;
|
||||
auxv[27] = (long)M->rando;
|
||||
auxv[28] = AT_EXECFN;
|
||||
auxv[29] = (long)execfn;
|
||||
auxv[30] = 0;
|
||||
|
||||
/* we're now ready to load */
|
||||
Spawn(exe, fd, sp, e, p, &M->lib, M->ps.path);
|
||||
@@ -891,7 +886,7 @@ int main(int argc, char **argv, char **envp) {
|
||||
struct ApeLoader *M;
|
||||
long *sp, *sp2, *auxv;
|
||||
union ElfEhdrBuf *ebuf;
|
||||
char *p, *pe, *exe, *prog, *execfn, *shell;
|
||||
char *p, *pe, *exe, *prog, *execfn;
|
||||
|
||||
/* allocate loader memory in program's arg block */
|
||||
n = sizeof(struct ApeLoader);
|
||||
@@ -952,14 +947,19 @@ 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 = argc > 0 ? argv[0] : 0;
|
||||
execfn = 0;
|
||||
for (i = 0; envp[i]; ++i) {
|
||||
if (envp[i][0] == '_' && envp[i][1] == '=') {
|
||||
execfn = envp[i] + 2;
|
||||
}
|
||||
}
|
||||
prog = GetEnv(envp + i + 1, "executable_path");
|
||||
if (!execfn) {
|
||||
execfn = prog;
|
||||
}
|
||||
|
||||
/* sneak the system five abi back out of args */
|
||||
sp = (long *)(argv - 1);
|
||||
@@ -981,8 +981,8 @@ int main(int argc, char **argv, char **envp) {
|
||||
sp = sp2;
|
||||
|
||||
/* interpret command line arguments */
|
||||
if ((M->ps.indirect = argc > 0 ? GetIndirectOffset(argv[0]) : 0)) {
|
||||
/* if argv[0] is $prog.ape, then we strip off the .ape and run
|
||||
if ((M->ps.indirect = GetIndirectOffset(prog))) {
|
||||
/* if called as $prog.ape, then strip off the .ape and run the
|
||||
$prog. This allows you to use symlinks to trick the OS when
|
||||
a native executable is required. For example, let's say you
|
||||
want to use the APE binary /opt/cosmos/bin/bash as a system
|
||||
@@ -991,13 +991,7 @@ int main(int argc, char **argv, char **envp) {
|
||||
but it will if you say:
|
||||
ln -sf /usr/local/bin/ape /opt/cosmos/bin/bash.ape
|
||||
and then use #!/opt/cosmos/bin/bash.ape instead. */
|
||||
M->ps.literally = 0;
|
||||
if (*argv[0] == '-' && (shell = GetEnv(envp, "SHELL")) &&
|
||||
!StrCmp(argv[0] + 1, BaseName(shell))) {
|
||||
execfn = prog = shell;
|
||||
} else {
|
||||
prog = (char *)sp[1];
|
||||
}
|
||||
M->ps.literally = 1;
|
||||
argc = sp[0];
|
||||
argv = (char **)(sp + 1);
|
||||
} else if ((M->ps.literally = argc >= 3 && !StrCmp(argv[1], "-"))) {
|
||||
@@ -1011,7 +1005,7 @@ int main(int argc, char **argv, char **envp) {
|
||||
} else if (argc < 2) {
|
||||
Emit("usage: ape PROG [ARGV1,ARGV2,...]\n"
|
||||
" ape - PROG [ARGV0,ARGV1,...]\n"
|
||||
" ($0 = PROG.ape) [ARGV1,ARGV2,...]\n"
|
||||
" PROG.ape [ARGV1,ARGV2,...]\n"
|
||||
"actually portable executable loader silicon 1.10\n"
|
||||
"copyrights 2023 justine alexandra roberts tunney\n"
|
||||
"https://justine.lol/ape.html\n");
|
||||
|
||||
@@ -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
@@ -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;
|
||||
|
||||
+10
-12
@@ -18,8 +18,13 @@ fi
|
||||
|
||||
if [ "$(id -u)" -eq 0 ]; then
|
||||
SUDO=
|
||||
else
|
||||
elif command -v sudo >/dev/null 2>&1; then
|
||||
SUDO=sudo
|
||||
elif command -v doas >/dev/null 2>&1; then
|
||||
SUDO=doas
|
||||
else
|
||||
echo "need root or sudo" >&2
|
||||
exit
|
||||
fi
|
||||
|
||||
if command -v install >/dev/null 2>&1; then
|
||||
@@ -132,20 +137,13 @@ if [ x"$(uname -s)" = xLinux ]; then
|
||||
echo done >&2
|
||||
fi
|
||||
|
||||
uname_r="$(uname -r)"
|
||||
if printf '%s\n%s\n' 5.12 "$uname_r" | sort -CV; then
|
||||
FLAGS=FP
|
||||
else
|
||||
FLAGS=F
|
||||
fi
|
||||
|
||||
echo >&2
|
||||
echo registering APE with binfmt_misc >&2
|
||||
echo you may need to edit configs to persist across reboot >&2
|
||||
echo '$SUDO sh -c "echo '"'"':APE:M::MZqFpD::/usr/bin/ape:'"$FLAGS'"' >/proc/sys/fs/binfmt_misc/register"' >&2
|
||||
$SUDO sh -c "echo ':APE:M::MZqFpD::/usr/bin/ape:$FLAGS' >/proc/sys/fs/binfmt_misc/register" || exit
|
||||
echo '$SUDO sh -c "echo '"'"':APE-jart:M::jartsr::/usr/bin/ape:'"$FLAGS'"' >/proc/sys/fs/binfmt_misc/register"' >&2
|
||||
$SUDO sh -c "echo ':APE-jart:M::jartsr::/usr/bin/ape:$FLAGS' >/proc/sys/fs/binfmt_misc/register" || exit
|
||||
echo '$SUDO sh -c "echo '"'"':APE:M::MZqFpD::/usr/bin/ape:'"'"' >/proc/sys/fs/binfmt_misc/register"' >&2
|
||||
$SUDO sh -c "echo ':APE:M::MZqFpD::/usr/bin/ape:' >/proc/sys/fs/binfmt_misc/register" || exit
|
||||
echo '$SUDO sh -c "echo '"'"':APE-jart:M::jartsr::/usr/bin/ape:'"'"' >/proc/sys/fs/binfmt_misc/register"' >&2
|
||||
$SUDO sh -c "echo ':APE-jart:M::jartsr::/usr/bin/ape:' >/proc/sys/fs/binfmt_misc/register" || exit
|
||||
echo done >&2
|
||||
|
||||
if [ x"$(cat /proc/sys/fs/binfmt_misc/status)" = xdisabled ]; then
|
||||
|
||||
+7
-4
@@ -11,8 +11,13 @@ fi
|
||||
|
||||
if [ "$UID" = "0" ]; then
|
||||
SUDO=
|
||||
else
|
||||
elif command -v sudo >/dev/null 2>&1; then
|
||||
SUDO=sudo
|
||||
elif command -v doas >/dev/null 2>&1; then
|
||||
SUDO=doas
|
||||
else
|
||||
echo "need root or sudo" >&2
|
||||
exit
|
||||
fi
|
||||
|
||||
{
|
||||
@@ -54,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.
+1
-1
@@ -22,7 +22,7 @@
|
||||
#include "libc/macros.internal.h"
|
||||
|
||||
// Apple Mach-O Executable Headers
|
||||
// Fixups are applied by objbincopy.com
|
||||
// Fixups are applied by objbincopy
|
||||
// There must exist a MAC_LC_SEGMENT_64 for every PT_LOAD
|
||||
|
||||
.section .macho,"a",@progbits
|
||||
|
||||
+52
-27
@@ -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;
|
||||
@@ -876,7 +899,7 @@ __attribute__((__noreturn__)) static void ShowUsage(int os, int fd, int rc) {
|
||||
"NAME\n"
|
||||
"\n"
|
||||
" actually portable executable loader version " APE_VERSION_STR "\n"
|
||||
" copyright 2023 justine alexandra roberts tunney\n"
|
||||
" copyrights 2024 justine alexandra roberts tunney\n"
|
||||
" https://justine.lol/ape.html\n"
|
||||
"\n"
|
||||
"USAGE\n"
|
||||
@@ -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) {
|
||||
@@ -947,6 +970,7 @@ EXTERN_C __attribute__((__noreturn__)) void ApeLoader(long di, long *sp,
|
||||
} else if (SupportsNetbsd() && !os && ap[0] == AT_EXECFN_NETBSD) {
|
||||
os = NETBSD;
|
||||
} else if (SupportsLinux() && ap[0] == AT_FLAGS) {
|
||||
// TODO(mrdomino): maybe set/insert this when we are called as "ape -".
|
||||
arg0 = !!(ap[1] & AT_FLAGS_PRESERVE_ARGV0);
|
||||
}
|
||||
}
|
||||
@@ -978,7 +1002,8 @@ EXTERN_C __attribute__((__noreturn__)) void ApeLoader(long di, long *sp,
|
||||
ShowUsage(os, 2, 1);
|
||||
} else {
|
||||
if (argv[1][0] == '-') {
|
||||
rc = !(argv[1][1] == 'h' && !argv[1][2]) || !StrCmp(argv[1] + 1, "-help");
|
||||
rc = !((argv[1][1] == 'h' && !argv[1][2]) ||
|
||||
!StrCmp(argv[1] + 1, "-help"));
|
||||
ShowUsage(os, 1 + rc, rc);
|
||||
}
|
||||
prog = (char *)sp[2];
|
||||
|
||||
@@ -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.
File renamed without changes.
Binary file not shown.
Binary file not shown.
File renamed without changes.
Executable
BIN
Binary file not shown.
Binary file not shown.
File renamed without changes.
File renamed without changes.
Executable
BIN
Binary file not shown.
@@ -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
|
||||
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
Binary file not shown.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
@@ -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
|
||||
|
||||
|
||||
@@ -29,7 +29,14 @@ if ! UNZIP=$(command -v unzip 2>/dev/null); then
|
||||
printf '%s\n' "please download https://cosmo.zip/pub/cosmos/bin/unzip and put it on the system path" >&2
|
||||
abort
|
||||
fi
|
||||
if ! SHA256SUM=$(command -v sha256sum 2>/dev/null); then
|
||||
if command -v sha256sum >/dev/null 2>&1; then
|
||||
# can use system sha256sum
|
||||
true
|
||||
elif command -v shasum >/dev/null 2>&1; then
|
||||
sha256sum() {
|
||||
shasum -a 256 "$@"
|
||||
}
|
||||
else
|
||||
if [ ! -f build/sha256sum.c ]; then
|
||||
printf '%s\n' "$0: fatal error: you need to install sha256sum" >&2
|
||||
printf '%s\n' "please download https://cosmo.zip/pub/cosmos/bin/sha256sum and put it on the system path" >&2
|
||||
@@ -51,6 +58,9 @@ if ! SHA256SUM=$(command -v sha256sum 2>/dev/null); then
|
||||
"${CC}" -w -O2 -o "${SHA256SUM}.$$" build/sha256sum.c || abort
|
||||
mv -f "${SHA256SUM}.$$" "${SHA256SUM}" || abort
|
||||
fi
|
||||
sha256sum() {
|
||||
"${SHA256SUM}" "$@"
|
||||
}
|
||||
fi
|
||||
if WGET=$(command -v wget 2>/dev/null); then
|
||||
DOWNLOAD=$WGET
|
||||
@@ -82,7 +92,7 @@ if ! "${DOWNLOAD}" ${DOWNLOAD_ARGS} cosmocc.zip "${URL1}"; then
|
||||
"${DOWNLOAD}" ${DOWNLOAD_ARGS} cosmocc.zip "${URL2}" || die
|
||||
fi
|
||||
printf '%s\n' "${COSMOCC_SHA256SUM} *cosmocc.zip" >cosmocc.zip.sha256sum
|
||||
"${SHA256SUM}" -c cosmocc.zip.sha256sum || die
|
||||
sha256sum -c cosmocc.zip.sha256sum || die
|
||||
"${UNZIP}" cosmocc.zip || die
|
||||
rm -f cosmocc.zip cosmocc.zip.sha256sum
|
||||
|
||||
|
||||
+2
-2
@@ -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.
|
||||
@@ -66,7 +66,7 @@ set -- --regex-c='/^extern [^(]*(\*const \([^)]*\))(/\1/b' "$@"
|
||||
# struct WorstSoftwareEver;
|
||||
set -- --regex-c='/^struct.*;$/uehocruehcroue/b' "$@"
|
||||
|
||||
exec $TAGS \
|
||||
build/run $TAGS \
|
||||
-e \
|
||||
--langmap=c:.c.h \
|
||||
--exclude=libc/nt/struct/imagefileheader.internal.h \
|
||||
|
||||
+8
-8
@@ -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
|
||||
|
||||
+8
-7
@@ -22,13 +22,14 @@
|
||||
# - tool/build/runit.c
|
||||
# - 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: \
|
||||
o/$(MODE)/tool/build/runit.com \
|
||||
o/$(MODE)/tool/build/runitd.com \
|
||||
o/$(MODE)/%.com
|
||||
.PRECIOUS: o/$(MODE)/%.ok
|
||||
o/$(MODE)/%.ok: private .PLEDGE = stdio rpath wpath cpath proc fattr inet dns
|
||||
o/$(MODE)/%.ok: private .UNVEIL += r:/etc/resolv.conf
|
||||
o/$(MODE)/%.ok: \
|
||||
o/$(MODE)/tool/build/runit \
|
||||
o/$(MODE)/tool/build/runitd \
|
||||
o/$(MODE)/%
|
||||
@$(COMPILE) -wATEST -tT$@ $^ $(HOSTS)
|
||||
|
||||
.PHONY:
|
||||
o/tiny/tool/build/runit.com:
|
||||
o/tiny/tool/build/runit:
|
||||
+18
-31
@@ -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) $<
|
||||
@@ -75,17 +79,17 @@ o/$(MODE)/%.pkg:
|
||||
$(file >$(TMPSAFE).args,$(filter %.o,$^))
|
||||
@$(COMPILE) -APACKAGE -wT$@ $(PKG) $(OUTPUT_OPTION) $(addprefix -d,$(filter %.pkg,$^)) @$(TMPSAFE).args
|
||||
|
||||
o/$(MODE)/%.o: %.py o/$(MODE)/third_party/python/pyobj.com
|
||||
@$(COMPILE) -wAPYOBJ o/$(MODE)/third_party/python/pyobj.com $(PYFLAGS) -o $@ $<
|
||||
o/$(MODE)/%.o: %.py o/$(MODE)/third_party/python/pyobj
|
||||
@$(COMPILE) -wAPYOBJ o/$(MODE)/third_party/python/pyobj $(PYFLAGS) -o $@ $<
|
||||
|
||||
o/$(MODE)/%.pyc: %.py o/$(MODE)/third_party/python/pycomp.com
|
||||
@$(COMPILE) -wAPYCOMP o/$(MODE)/third_party/python/pycomp.com $(PYCFLAGS) -o $@ $<
|
||||
o/$(MODE)/%.pyc: %.py o/$(MODE)/third_party/python/pycomp
|
||||
@$(COMPILE) -wAPYCOMP o/$(MODE)/third_party/python/pycomp $(PYCFLAGS) -o $@ $<
|
||||
|
||||
o/$(MODE)/%.lua: %.lua o/$(MODE)/third_party/lua/luac.com
|
||||
@$(COMPILE) -wALUAC o/$(MODE)/third_party/lua/luac.com -s -o $@ $<
|
||||
o/$(MODE)/%.lua: %.lua o/$(MODE)/third_party/lua/luac
|
||||
@$(COMPILE) -wALUAC o/$(MODE)/third_party/lua/luac -s -o $@ $<
|
||||
|
||||
o/$(MODE)/%.lua.runs: %.lua o/$(MODE)/tool/net/redbean.com
|
||||
@$(COMPILE) -wALUA -tT$@ o/$(MODE)/tool/net/redbean.com $(LUAFLAGS) -i $<
|
||||
o/$(MODE)/%.lua.runs: %.lua o/$(MODE)/tool/net/redbean
|
||||
@$(COMPILE) -wALUA -tT$@ o/$(MODE)/tool/net/redbean $(LUAFLAGS) -i $<
|
||||
|
||||
################################################################################
|
||||
# LOCAL UNIT TESTS
|
||||
@@ -104,22 +108,22 @@ o/$(MODE)/%.lua.runs: %.lua o/$(MODE)/tool/net/redbean.com
|
||||
#
|
||||
# You could then run a command like:
|
||||
#
|
||||
# make -j8 o//test/libc/calls/openbsd_test.com.runs
|
||||
# make -j8 o//test/libc/calls/openbsd_test.runs
|
||||
#
|
||||
# You need PROT_EXEC permission since ftrace morphs the binary. It's
|
||||
# also worth mentioning that the pledge.com command can simulate what
|
||||
# also worth mentioning that the pledge command can simulate what
|
||||
# Landlock Make does:
|
||||
#
|
||||
# o//tool/build/pledge.com \
|
||||
# o//tool/build/pledge \
|
||||
# -v. -p 'stdio rpath wpath cpath tty prot_exec' \
|
||||
# o//test/libc/calls/openbsd_test.com \
|
||||
# o//test/libc/calls/openbsd_test \
|
||||
# ----ftrace
|
||||
#
|
||||
# This is useful in the event a test binary should run by itself, but
|
||||
# fails to run beneath Landlock Make. It's also useful sometimes to
|
||||
# override the verbosity when running tests:
|
||||
#
|
||||
# make V=5 TESTARGS=-b o//test/libc/calls/openbsd_test.com.runs
|
||||
# make V=5 TESTARGS=-b o//test/libc/calls/openbsd_test.runs
|
||||
#
|
||||
# This way, if for some reason a test should fail but calls exit(0),
|
||||
# then the stdout/stderr output, which would normally be suppressed,
|
||||
@@ -131,7 +135,7 @@ o/$(MODE)/%.runs: o/$(MODE)/%
|
||||
################################################################################
|
||||
# ELF ZIP FILES
|
||||
#
|
||||
# zipobj.com lets us do fast incremental linking of compressed data.
|
||||
# zipobj lets us do fast incremental linking of compressed data.
|
||||
# it's nice because if we link a hundred binaries that use the time zone
|
||||
# database, then that database only needs to be DEFLATE'd once.
|
||||
|
||||
@@ -179,23 +183,6 @@ o/$(MODE)/%.okk: private .UNSANDBOXED = 1
|
||||
o/$(MODE)/%.okk: %
|
||||
@$(COMPILE) -ACHECK.h $(COMPILE.cxx) -xc++ -g0 -o $@ $<
|
||||
|
||||
################################################################################
|
||||
# EXECUTABLE HELPERS
|
||||
|
||||
MAKE_SYMTAB_CREATE = \
|
||||
$(COMPILE) -wASYMTAB \
|
||||
o/$(MODE)/tool/build/symtab.com \
|
||||
-o $(TMPSAFE)/.symtab \
|
||||
$<
|
||||
|
||||
MAKE_SYMTAB_ZIP = \
|
||||
$(COMPILE) -AZIP -T$@ \
|
||||
o/$(MODE)/third_party/zip/zip.com \
|
||||
-b$(TMPDIR) \
|
||||
-9qj \
|
||||
$@ \
|
||||
$(TMPSAFE)/.symtab
|
||||
|
||||
################################################################################
|
||||
# EMACS ASSEMBLY GENERATION
|
||||
|
||||
|
||||
@@ -1,9 +1,8 @@
|
||||
#!/bin/sh
|
||||
if printf '%s\n' "$*" | grep aarch64 >/dev/null 2>&1; then
|
||||
if [ ! -f o/third_party/qemu/qemu-aarch64 ]; then
|
||||
make -j8 o/third_party/qemu/qemu-aarch64
|
||||
fi
|
||||
exec o/third_party/qemu/qemu-aarch64 "$@"
|
||||
UNAMEM=$(uname -m)
|
||||
UNAMES=$(uname -s)
|
||||
if [ x"$UNAMES" = x"Darwin" ] && [ x"$UNAMEM" = x"arm64" ]; then
|
||||
exec ape "$@"
|
||||
else
|
||||
exec "$@"
|
||||
fi
|
||||
@@ -0,0 +1,443 @@
|
||||
/*-*- 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 2022 Justine Alexandra Roberts Tunney │
|
||||
│ │
|
||||
│ Permission to use, copy, modify, and/or distribute this software for │
|
||||
│ any purpose with or without fee is hereby granted, provided that the │
|
||||
│ above copyright notice and this permission notice appear in all copies. │
|
||||
│ │
|
||||
│ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL │
|
||||
│ WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED │
|
||||
│ WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE │
|
||||
│ AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL │
|
||||
│ DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR │
|
||||
│ PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER │
|
||||
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
|
||||
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include <errno.h>
|
||||
#include <limits.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
// this file should not have dependencies, because everything will be
|
||||
// re-downloaded if the o/tool/sha256sum artifact becomes invalidated
|
||||
|
||||
#define PROG "sha256sum"
|
||||
#define USAGE \
|
||||
"\
|
||||
Usage: " PROG " [-?hbctw] [PATH...]\n\
|
||||
-h help\n\
|
||||
-c check mode\n\
|
||||
-b binary mode\n\
|
||||
-t textual mode\n\
|
||||
-w warning mode\n"
|
||||
|
||||
#define ROTR(a, b) (((a) >> (b)) | ((a) << (32 - (b))))
|
||||
#define CH(x, y, z) (((x) & (y)) ^ (~(x) & (z)))
|
||||
#define MAJ(x, y, z) (((x) & (y)) ^ ((x) & (z)) ^ ((y) & (z)))
|
||||
#define EP0(x) (ROTR(x, 2) ^ ROTR(x, 13) ^ ROTR(x, 22))
|
||||
#define EP1(x) (ROTR(x, 6) ^ ROTR(x, 11) ^ ROTR(x, 25))
|
||||
#define SIG0(x) (ROTR(x, 7) ^ ROTR(x, 18) ^ ((x) >> 3))
|
||||
#define SIG1(x) (ROTR(x, 17) ^ ROTR(x, 19) ^ ((x) >> 10))
|
||||
|
||||
struct Sha256Ctx {
|
||||
uint8_t data[64];
|
||||
uint32_t datalen;
|
||||
uint64_t bitlen;
|
||||
uint32_t state[8];
|
||||
};
|
||||
|
||||
static const uint32_t kSha256Tab[64] = {
|
||||
0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, //
|
||||
0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5, //
|
||||
0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, //
|
||||
0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174, //
|
||||
0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, //
|
||||
0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da, //
|
||||
0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, //
|
||||
0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967, //
|
||||
0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13, //
|
||||
0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85, //
|
||||
0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, //
|
||||
0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070, //
|
||||
0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, //
|
||||
0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3, //
|
||||
0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, //
|
||||
0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2, //
|
||||
};
|
||||
|
||||
static bool g_warn;
|
||||
static char g_mode;
|
||||
static bool g_check;
|
||||
static int g_mismatches;
|
||||
|
||||
static void Sha256Transform(uint32_t state[8], const uint8_t data[64]) {
|
||||
unsigned i;
|
||||
uint32_t a, b, c, d, e, f, g, h, t1, t2, m[64];
|
||||
for (i = 0; i < 16; ++i, data += 4) {
|
||||
m[i] = (uint32_t)data[0] << 24 | data[1] << 16 | data[2] << 8 | data[3];
|
||||
}
|
||||
for (; i < 64; ++i) {
|
||||
m[i] = SIG1(m[i - 2]) + m[i - 7] + SIG0(m[i - 15]) + m[i - 16];
|
||||
}
|
||||
a = state[0];
|
||||
b = state[1];
|
||||
c = state[2];
|
||||
d = state[3];
|
||||
e = state[4];
|
||||
f = state[5];
|
||||
g = state[6];
|
||||
h = state[7];
|
||||
for (i = 0; i < 64; ++i) {
|
||||
t1 = h + EP1(e) + CH(e, f, g) + kSha256Tab[i] + m[i];
|
||||
t2 = EP0(a) + MAJ(a, b, c);
|
||||
h = g;
|
||||
g = f;
|
||||
f = e;
|
||||
e = d + t1;
|
||||
d = c;
|
||||
c = b;
|
||||
b = a;
|
||||
a = t1 + t2;
|
||||
}
|
||||
state[0] += a;
|
||||
state[1] += b;
|
||||
state[2] += c;
|
||||
state[3] += d;
|
||||
state[4] += e;
|
||||
state[5] += f;
|
||||
state[6] += g;
|
||||
state[7] += h;
|
||||
}
|
||||
|
||||
static void Sha256Init(struct Sha256Ctx *ctx) {
|
||||
ctx->datalen = 0;
|
||||
ctx->bitlen = 0;
|
||||
ctx->state[0] = 0x6a09e667;
|
||||
ctx->state[1] = 0xbb67ae85;
|
||||
ctx->state[2] = 0x3c6ef372;
|
||||
ctx->state[3] = 0xa54ff53a;
|
||||
ctx->state[4] = 0x510e527f;
|
||||
ctx->state[5] = 0x9b05688c;
|
||||
ctx->state[6] = 0x1f83d9ab;
|
||||
ctx->state[7] = 0x5be0cd19;
|
||||
}
|
||||
|
||||
static void Sha256Update(struct Sha256Ctx *ctx, const uint8_t *data,
|
||||
long size) {
|
||||
long i;
|
||||
for (i = 0; i < size; ++i) {
|
||||
ctx->data[ctx->datalen] = data[i];
|
||||
ctx->datalen++;
|
||||
if (ctx->datalen == 64) {
|
||||
Sha256Transform(ctx->state, ctx->data);
|
||||
ctx->bitlen += 512;
|
||||
ctx->datalen = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void Sha256Final(struct Sha256Ctx *ctx, uint8_t *hash) {
|
||||
long i;
|
||||
i = ctx->datalen;
|
||||
ctx->data[i++] = 0x80;
|
||||
if (ctx->datalen < 56) {
|
||||
memset(ctx->data + i, 0, 56 - i);
|
||||
} else {
|
||||
memset(ctx->data + i, 0, 64 - i);
|
||||
Sha256Transform(ctx->state, ctx->data);
|
||||
memset(ctx->data, 0, 56);
|
||||
}
|
||||
ctx->bitlen += ctx->datalen * 8;
|
||||
ctx->data[63] = ctx->bitlen;
|
||||
ctx->data[62] = ctx->bitlen >> 8;
|
||||
ctx->data[61] = ctx->bitlen >> 16;
|
||||
ctx->data[60] = ctx->bitlen >> 24;
|
||||
ctx->data[59] = ctx->bitlen >> 32;
|
||||
ctx->data[58] = ctx->bitlen >> 40;
|
||||
ctx->data[57] = ctx->bitlen >> 48;
|
||||
ctx->data[56] = ctx->bitlen >> 56;
|
||||
Sha256Transform(ctx->state, ctx->data);
|
||||
for (i = 0; i < 4; ++i) {
|
||||
hash[i] = (ctx->state[0] >> (24 - i * 8)) & 0xff;
|
||||
hash[i + 4] = (ctx->state[1] >> (24 - i * 8)) & 0xff;
|
||||
hash[i + 8] = (ctx->state[2] >> (24 - i * 8)) & 0xff;
|
||||
hash[i + 12] = (ctx->state[3] >> (24 - i * 8)) & 0xff;
|
||||
hash[i + 16] = (ctx->state[4] >> (24 - i * 8)) & 0xff;
|
||||
hash[i + 20] = (ctx->state[5] >> (24 - i * 8)) & 0xff;
|
||||
hash[i + 24] = (ctx->state[6] >> (24 - i * 8)) & 0xff;
|
||||
hash[i + 28] = (ctx->state[7] >> (24 - i * 8)) & 0xff;
|
||||
}
|
||||
}
|
||||
|
||||
static char *FormatUint32(char *p, uint32_t x) {
|
||||
char t;
|
||||
size_t i, a, b;
|
||||
i = 0;
|
||||
do {
|
||||
p[i++] = x % 10 + '0';
|
||||
x = x / 10;
|
||||
} while (x > 0);
|
||||
p[i] = '\0';
|
||||
if (i) {
|
||||
for (a = 0, b = i - 1; a < b; ++a, --b) {
|
||||
t = p[a];
|
||||
p[a] = p[b];
|
||||
p[b] = t;
|
||||
}
|
||||
}
|
||||
return p + i;
|
||||
}
|
||||
|
||||
static char *FormatInt32(char *p, int32_t x) {
|
||||
if (x < 0) *p++ = '-', x = -(uint32_t)x;
|
||||
return FormatUint32(p, x);
|
||||
}
|
||||
|
||||
static size_t StrCat(char *dst, const char *src, size_t dsize) {
|
||||
size_t m, n = dsize;
|
||||
const char *p = dst;
|
||||
const char *q = src;
|
||||
while (n-- != 0 && *dst != '\0') dst++;
|
||||
m = dst - p;
|
||||
n = dsize - m;
|
||||
if (n-- == 0) {
|
||||
return m + strlen(src);
|
||||
}
|
||||
while (*src != '\0') {
|
||||
if (n != 0) {
|
||||
*dst++ = *src;
|
||||
n--;
|
||||
}
|
||||
src++;
|
||||
}
|
||||
*dst = '\0';
|
||||
return m + (src - q);
|
||||
}
|
||||
|
||||
static void GetOpts(int argc, char *argv[]) {
|
||||
int opt;
|
||||
g_mode = ' ';
|
||||
while ((opt = getopt(argc, argv, "?hbctw")) != -1) {
|
||||
switch (opt) {
|
||||
case 'w':
|
||||
g_warn = true;
|
||||
break;
|
||||
case 'c':
|
||||
g_check = true;
|
||||
break;
|
||||
case 't':
|
||||
g_mode = ' ';
|
||||
break;
|
||||
case 'b':
|
||||
g_mode = '*';
|
||||
break;
|
||||
case 'h':
|
||||
case '?':
|
||||
(void)write(1, USAGE, sizeof(USAGE) - 1);
|
||||
exit(0);
|
||||
default:
|
||||
(void)write(2, USAGE, sizeof(USAGE) - 1);
|
||||
exit(64);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void Write(int fd, const char *s, ...) {
|
||||
va_list va;
|
||||
char buf[512];
|
||||
buf[0] = 0;
|
||||
va_start(va, s);
|
||||
do {
|
||||
StrCat(buf, s, sizeof(buf));
|
||||
} while ((s = va_arg(va, const char *)));
|
||||
va_end(va);
|
||||
(void)write(fd, buf, strlen(buf));
|
||||
}
|
||||
|
||||
static bool IsModeCharacter(char c) {
|
||||
switch (c) {
|
||||
case ' ':
|
||||
case '*':
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
static bool IsSupportedPath(const char *path) {
|
||||
size_t i;
|
||||
for (i = 0;; ++i) {
|
||||
switch (path[i]) {
|
||||
case 0:
|
||||
if (i) return true;
|
||||
// fallthrough
|
||||
case '\r':
|
||||
case '\n':
|
||||
case '\\':
|
||||
Write(2, PROG, ": ", path, ": unsupported path\n", NULL);
|
||||
return false;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static bool GetDigest(const char *path, FILE *f, uint8_t digest[32]) {
|
||||
size_t got;
|
||||
uint8_t buf[512];
|
||||
struct Sha256Ctx ctx;
|
||||
Sha256Init(&ctx);
|
||||
while ((got = fread(buf, 1, sizeof(buf), f))) {
|
||||
Sha256Update(&ctx, buf, got);
|
||||
}
|
||||
if (ferror(f)) {
|
||||
Write(2, PROG, ": ", path, ": ", strerror(errno), "\n", NULL);
|
||||
return false;
|
||||
}
|
||||
Sha256Final(&ctx, digest);
|
||||
return true;
|
||||
}
|
||||
|
||||
static char *CopyHex(char *s, const void *p, size_t n) {
|
||||
const char *d, *e;
|
||||
for (d = (const char *)p, e = d + n; d < e; ++d) {
|
||||
*s++ = "0123456789abcdef"[(*d >> 4) & 15];
|
||||
*s++ = "0123456789abcdef"[(*d >> 0) & 15];
|
||||
}
|
||||
*s = 0;
|
||||
return s;
|
||||
}
|
||||
|
||||
static bool ProduceDigest(const char *path, FILE *f) {
|
||||
char hexdigest[65];
|
||||
char mode[2] = {g_mode};
|
||||
unsigned char digest[32];
|
||||
if (!IsSupportedPath(path)) return false;
|
||||
if (!GetDigest(path, f, digest)) return false;
|
||||
CopyHex(hexdigest, digest, 32);
|
||||
Write(1, hexdigest, " ", mode, path, "\n", NULL);
|
||||
return true;
|
||||
}
|
||||
|
||||
static char *Chomp(char *line) {
|
||||
size_t i;
|
||||
if (line) {
|
||||
for (i = strlen(line); i--;) {
|
||||
if (line[i] == '\r' || line[i] == '\n') {
|
||||
line[i] = '\0';
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return line;
|
||||
}
|
||||
|
||||
static int HexToInt(int c) {
|
||||
if ('0' <= c && c <= '9') {
|
||||
return c - '0';
|
||||
} else if ('a' <= c && c <= 'f') {
|
||||
return c - 'a' + 10;
|
||||
} else if ('A' <= c && c <= 'F') {
|
||||
return c - 'A' + 10;
|
||||
} else {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
static bool CheckDigests(const char *path, FILE *f) {
|
||||
FILE *f2;
|
||||
bool k = true;
|
||||
int a, b, i, line;
|
||||
const char *path2, *status;
|
||||
uint8_t wantdigest[32], gotdigest[32];
|
||||
char buf[64 + 2 + PATH_MAX + 1 + 1], *p;
|
||||
for (line = 0; fgets(buf, sizeof(buf), f); ++line) {
|
||||
if (!*Chomp(buf)) continue;
|
||||
for (p = buf, i = 0; i < 32; ++i) {
|
||||
if ((a = HexToInt(*p++ & 255)) == -1) goto InvalidLine;
|
||||
if ((b = HexToInt(*p++ & 255)) == -1) goto InvalidLine;
|
||||
wantdigest[i] = a << 4 | b;
|
||||
}
|
||||
if (*p++ != ' ') goto InvalidLine;
|
||||
if (!IsModeCharacter(*p++)) goto InvalidLine;
|
||||
path2 = p;
|
||||
if (!*path2) goto InvalidLine;
|
||||
if (!IsSupportedPath(path2)) continue;
|
||||
if ((f2 = fopen(path2, "rb"))) {
|
||||
if (GetDigest(path2, f2, gotdigest)) {
|
||||
if (!memcmp(wantdigest, gotdigest, 32)) {
|
||||
status = "OK";
|
||||
} else {
|
||||
status = "FAILED";
|
||||
++g_mismatches;
|
||||
k = false;
|
||||
}
|
||||
Write(1, path2, ": ", status, "\n", NULL);
|
||||
} else {
|
||||
k = false;
|
||||
}
|
||||
fclose(f2);
|
||||
} else {
|
||||
Write(2, PROG, ": ", path2, ": ", strerror(errno), "\n", NULL);
|
||||
k = false;
|
||||
}
|
||||
continue;
|
||||
InvalidLine:
|
||||
if (g_warn) {
|
||||
char linestr[12];
|
||||
FormatInt32(linestr, line + 1);
|
||||
Write(2, PROG, ": ", path, ":", linestr, ": ",
|
||||
"improperly formatted checksum line", "\n", NULL);
|
||||
}
|
||||
}
|
||||
if (ferror(f)) {
|
||||
Write(2, PROG, ": ", path, ": ", strerror(errno), "\n", NULL);
|
||||
k = false;
|
||||
}
|
||||
return k;
|
||||
}
|
||||
|
||||
static bool Process(const char *path, FILE *f) {
|
||||
if (g_check) {
|
||||
return CheckDigests(path, f);
|
||||
} else {
|
||||
return ProduceDigest(path, f);
|
||||
}
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
int i;
|
||||
FILE *f;
|
||||
bool k = true;
|
||||
GetOpts(argc, argv);
|
||||
if (optind == argc) {
|
||||
f = stdin;
|
||||
k &= Process("-", f);
|
||||
} else {
|
||||
for (i = optind; i < argc; ++i) {
|
||||
if ((f = fopen(argv[i], "rb"))) {
|
||||
k &= Process(argv[i], f);
|
||||
fclose(f);
|
||||
} else {
|
||||
Write(2, PROG, ": ", argv[i], ": ", strerror(errno), "\n", NULL);
|
||||
k = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (g_mismatches) {
|
||||
char ibuf[12];
|
||||
FormatInt32(ibuf, g_mismatches);
|
||||
Write(2, PROG, ": WARNING: ", ibuf, " computed checksum did NOT match\n",
|
||||
NULL);
|
||||
}
|
||||
return !k;
|
||||
}
|
||||
+1
-6
@@ -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
@@ -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
@@ -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.
|
||||
|
||||
@@ -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
@@ -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};
|
||||
@@ -0,0 +1,4 @@
|
||||
__notice(pl_mpeg_notice, "\
|
||||
PL_MPEG (MIT License)\n\
|
||||
Copyright(c) 2019 Dominic Szablewski\n\
|
||||
https://phoboslab.org");
|
||||
+1
-6
@@ -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
@@ -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
|
||||
|
||||
@@ -27,7 +27,7 @@
|
||||
#include "libc/log/log.h"
|
||||
#include "libc/macros.internal.h"
|
||||
#include "libc/math.h"
|
||||
#include "libc/mem/gc.internal.h"
|
||||
#include "libc/mem/gc.h"
|
||||
#include "libc/mem/mem.h"
|
||||
#include "libc/str/str.h"
|
||||
#include "libc/testlib/testlib.h"
|
||||
@@ -202,8 +202,8 @@ void *Gyarados(long dyw, long dxw, int dst[dyw][dxw], long syw, long sxw,
|
||||
CHECK_LE(sxn, sxw);
|
||||
CHECK_LE(dyn, dyw);
|
||||
CHECK_LE(dxn, dxw);
|
||||
CHECK_LT(_bsrl(syn) + _bsrl(sxn), 32);
|
||||
CHECK_LT(_bsrl(dyn) + _bsrl(dxn), 32);
|
||||
CHECK_LT(bsrl(syn) + bsrl(sxn), 32);
|
||||
CHECK_LT(bsrl(dyn) + bsrl(dxn), 32);
|
||||
CHECK_LE(dyw, 0x7fff);
|
||||
CHECK_LE(dxw, 0x7fff);
|
||||
CHECK_LE(syw, 0x7fff);
|
||||
|
||||
@@ -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
@@ -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
@@ -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
-1
@@ -18,7 +18,7 @@
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "dsp/tty/tty.h"
|
||||
#include "libc/mem/arraylist2.internal.h"
|
||||
#include "libc/mem/gc.internal.h"
|
||||
#include "libc/mem/gc.h"
|
||||
#include "libc/mem/mem.h"
|
||||
#include "libc/x/x.h"
|
||||
|
||||
|
||||
+1
-3
@@ -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};
|
||||
+1
-1
@@ -25,7 +25,7 @@
|
||||
#include "libc/calls/ucontext.h"
|
||||
#include "libc/log/log.h"
|
||||
#include "libc/macros.internal.h"
|
||||
#include "libc/mem/gc.internal.h"
|
||||
#include "libc/mem/gc.h"
|
||||
#include "libc/runtime/runtime.h"
|
||||
#include "libc/str/str.h"
|
||||
#include "libc/sysv/consts/fileno.h"
|
||||
|
||||
+104
-104
@@ -14,130 +14,130 @@ EXAMPLES_MAINS_S = $(filter %.S,$(EXAMPLES_FILES))
|
||||
EXAMPLES_MAINS_C = $(filter %.c,$(EXAMPLES_FILES))
|
||||
EXAMPLES_MAINS_CC = $(filter %.cc,$(EXAMPLES_FILES))
|
||||
|
||||
EXAMPLES_SRCS = \
|
||||
$(EXAMPLES_MAINS_S) \
|
||||
$(EXAMPLES_MAINS_C) \
|
||||
EXAMPLES_SRCS = \
|
||||
$(EXAMPLES_MAINS_S) \
|
||||
$(EXAMPLES_MAINS_C) \
|
||||
$(EXAMPLES_MAINS_CC)
|
||||
|
||||
EXAMPLES_MAINS = \
|
||||
$(EXAMPLES_MAINS_S) \
|
||||
$(EXAMPLES_MAINS_C) \
|
||||
EXAMPLES_MAINS = \
|
||||
$(EXAMPLES_MAINS_S) \
|
||||
$(EXAMPLES_MAINS_C) \
|
||||
$(EXAMPLES_MAINS_CC)
|
||||
|
||||
EXAMPLES_OBJS = \
|
||||
$(EXAMPLES_MAINS_S:%.S=o/$(MODE)/%.o) \
|
||||
$(EXAMPLES_MAINS_C:%.c=o/$(MODE)/%.o) \
|
||||
EXAMPLES_OBJS = \
|
||||
$(EXAMPLES_MAINS_S:%.S=o/$(MODE)/%.o) \
|
||||
$(EXAMPLES_MAINS_C:%.c=o/$(MODE)/%.o) \
|
||||
$(EXAMPLES_MAINS_CC:%.cc=o/$(MODE)/%.o)
|
||||
|
||||
EXAMPLES_COMS = \
|
||||
$(EXAMPLES_MAINS_S:%.S=o/$(MODE)/%.com) \
|
||||
$(EXAMPLES_MAINS_C:%.c=o/$(MODE)/%.com) \
|
||||
$(EXAMPLES_MAINS_CC:%.cc=o/$(MODE)/%.com)
|
||||
EXAMPLES_COMS = \
|
||||
$(EXAMPLES_MAINS_S:%.S=o/$(MODE)/%) \
|
||||
$(EXAMPLES_MAINS_C:%.c=o/$(MODE)/%) \
|
||||
$(EXAMPLES_MAINS_CC:%.cc=o/$(MODE)/%)
|
||||
|
||||
EXAMPLES_BINS = \
|
||||
$(EXAMPLES_COMS) \
|
||||
EXAMPLES_BINS = \
|
||||
$(EXAMPLES_COMS) \
|
||||
$(EXAMPLES_COMS:%=%.dbg)
|
||||
|
||||
EXAMPLES_DIRECTDEPS = \
|
||||
DSP_CORE \
|
||||
DSP_SCALE \
|
||||
DSP_TTY \
|
||||
LIBC_CALLS \
|
||||
LIBC_DLOPEN \
|
||||
LIBC_FMT \
|
||||
LIBC_INTRIN \
|
||||
LIBC_IRQ \
|
||||
LIBC_LOG \
|
||||
LIBC_MEM \
|
||||
LIBC_NEXGEN32E \
|
||||
LIBC_NT_ADVAPI32 \
|
||||
LIBC_NT_IPHLPAPI \
|
||||
LIBC_NT_KERNEL32 \
|
||||
LIBC_NT_NTDLL \
|
||||
LIBC_NT_USER32 \
|
||||
LIBC_NT_WS2_32 \
|
||||
LIBC_PROC \
|
||||
LIBC_RUNTIME \
|
||||
LIBC_SOCK \
|
||||
LIBC_STDIO \
|
||||
LIBC_STR \
|
||||
LIBC_SYSV \
|
||||
LIBC_SYSV_CALLS \
|
||||
LIBC_TESTLIB \
|
||||
LIBC_THREAD \
|
||||
LIBC_TIME \
|
||||
LIBC_TINYMATH \
|
||||
LIBC_VGA \
|
||||
LIBC_X \
|
||||
NET_HTTP \
|
||||
NET_HTTPS \
|
||||
THIRD_PARTY_AWK \
|
||||
THIRD_PARTY_COMPILER_RT \
|
||||
THIRD_PARTY_DLMALLOC \
|
||||
THIRD_PARTY_DOUBLECONVERSION \
|
||||
THIRD_PARTY_GDTOA \
|
||||
THIRD_PARTY_GETOPT \
|
||||
THIRD_PARTY_HIREDIS \
|
||||
THIRD_PARTY_LIBCXX \
|
||||
THIRD_PARTY_LINENOISE \
|
||||
THIRD_PARTY_LUA \
|
||||
THIRD_PARTY_MBEDTLS \
|
||||
THIRD_PARTY_MUSL \
|
||||
THIRD_PARTY_NSYNC \
|
||||
THIRD_PARTY_NSYNC_MEM \
|
||||
THIRD_PARTY_QUICKJS \
|
||||
THIRD_PARTY_SED \
|
||||
THIRD_PARTY_STB \
|
||||
THIRD_PARTY_TR \
|
||||
THIRD_PARTY_VQSORT \
|
||||
THIRD_PARTY_XED \
|
||||
THIRD_PARTY_ZLIB \
|
||||
TOOL_ARGS \
|
||||
TOOL_BUILD_LIB \
|
||||
EXAMPLES_DIRECTDEPS = \
|
||||
DSP_CORE \
|
||||
DSP_SCALE \
|
||||
DSP_TTY \
|
||||
LIBC_CALLS \
|
||||
LIBC_DLOPEN \
|
||||
LIBC_FMT \
|
||||
LIBC_INTRIN \
|
||||
LIBC_IRQ \
|
||||
LIBC_LOG \
|
||||
LIBC_MEM \
|
||||
LIBC_NEXGEN32E \
|
||||
LIBC_NT_ADVAPI32 \
|
||||
LIBC_NT_IPHLPAPI \
|
||||
LIBC_NT_KERNEL32 \
|
||||
LIBC_NT_NTDLL \
|
||||
LIBC_NT_USER32 \
|
||||
LIBC_NT_WS2_32 \
|
||||
LIBC_PROC \
|
||||
LIBC_RUNTIME \
|
||||
LIBC_SOCK \
|
||||
LIBC_STDIO \
|
||||
LIBC_STR \
|
||||
LIBC_SYSV \
|
||||
LIBC_SYSV_CALLS \
|
||||
LIBC_TESTLIB \
|
||||
LIBC_THREAD \
|
||||
LIBC_TIME \
|
||||
LIBC_TINYMATH \
|
||||
LIBC_VGA \
|
||||
LIBC_X \
|
||||
NET_HTTP \
|
||||
NET_HTTPS \
|
||||
THIRD_PARTY_AWK \
|
||||
THIRD_PARTY_COMPILER_RT \
|
||||
THIRD_PARTY_DLMALLOC \
|
||||
THIRD_PARTY_DOUBLECONVERSION \
|
||||
THIRD_PARTY_GDTOA \
|
||||
THIRD_PARTY_GETOPT \
|
||||
THIRD_PARTY_HIREDIS \
|
||||
THIRD_PARTY_LIBCXX \
|
||||
THIRD_PARTY_LINENOISE \
|
||||
THIRD_PARTY_LUA \
|
||||
THIRD_PARTY_MBEDTLS \
|
||||
THIRD_PARTY_MUSL \
|
||||
THIRD_PARTY_NSYNC \
|
||||
THIRD_PARTY_NSYNC_MEM \
|
||||
THIRD_PARTY_OPENMP \
|
||||
THIRD_PARTY_SED \
|
||||
THIRD_PARTY_STB \
|
||||
THIRD_PARTY_TR \
|
||||
THIRD_PARTY_VQSORT \
|
||||
THIRD_PARTY_XED \
|
||||
THIRD_PARTY_ZLIB \
|
||||
TOOL_ARGS \
|
||||
TOOL_BUILD_LIB \
|
||||
TOOL_VIZ_LIB
|
||||
|
||||
EXAMPLES_DEPS := \
|
||||
EXAMPLES_DEPS := \
|
||||
$(call uniq,$(foreach x,$(EXAMPLES_DIRECTDEPS),$($(x))))
|
||||
|
||||
o/$(MODE)/examples/examples.pkg: \
|
||||
$(EXAMPLES_OBJS) \
|
||||
o/$(MODE)/examples/examples.pkg: \
|
||||
$(EXAMPLES_OBJS) \
|
||||
$(foreach x,$(EXAMPLES_DIRECTDEPS),$($(x)_A).pkg)
|
||||
|
||||
o/$(MODE)/examples/unbourne.o: private \
|
||||
CPPFLAGS += \
|
||||
-DSTACK_FRAME_UNLIMITED \
|
||||
o/$(MODE)/examples/unbourne.o: private \
|
||||
CPPFLAGS += \
|
||||
-DSTACK_FRAME_UNLIMITED \
|
||||
-fpie
|
||||
|
||||
o/$(MODE)/examples/%.com.dbg: \
|
||||
$(EXAMPLES_DEPS) \
|
||||
o/$(MODE)/examples/%.o \
|
||||
o/$(MODE)/examples/examples.pkg \
|
||||
o/$(MODE)/examples/%.dbg: \
|
||||
$(EXAMPLES_DEPS) \
|
||||
o/$(MODE)/examples/%.o \
|
||||
o/$(MODE)/examples/examples.pkg \
|
||||
$(EXAMPLES_BOOTLOADER)
|
||||
@$(APELINK)
|
||||
|
||||
o/$(MODE)/examples/hellolua.com.dbg: \
|
||||
$(EXAMPLES_DEPS) \
|
||||
o/$(MODE)/examples/hellolua.o \
|
||||
o/$(MODE)/examples/hellolua.lua.zip.o \
|
||||
o/$(MODE)/examples/examples.pkg \
|
||||
o/$(MODE)/examples/hellolua.dbg: \
|
||||
$(EXAMPLES_DEPS) \
|
||||
o/$(MODE)/examples/hellolua.o \
|
||||
o/$(MODE)/examples/hellolua.lua.zip.o \
|
||||
o/$(MODE)/examples/examples.pkg \
|
||||
$(EXAMPLES_BOOTLOADER)
|
||||
@$(APELINK)
|
||||
|
||||
o/$(MODE)/examples/ispell.com.dbg: \
|
||||
$(EXAMPLES_DEPS) \
|
||||
o/$(MODE)/examples/ispell.o \
|
||||
o/$(MODE)/usr/share/dict/words.zip.o \
|
||||
o/$(MODE)/examples/examples.pkg \
|
||||
o/$(MODE)/examples/ispell.dbg: \
|
||||
$(EXAMPLES_DEPS) \
|
||||
o/$(MODE)/examples/ispell.o \
|
||||
o/$(MODE)/usr/share/dict/words.zip.o \
|
||||
o/$(MODE)/examples/examples.pkg \
|
||||
$(EXAMPLES_BOOTLOADER)
|
||||
@$(APELINK)
|
||||
|
||||
o/$(MODE)/examples/nesemu1.com.dbg: \
|
||||
$(EXAMPLES_DEPS) \
|
||||
o/$(MODE)/examples/nesemu1.o \
|
||||
o/$(MODE)/usr/share/rom/mario.nes.zip.o \
|
||||
o/$(MODE)/usr/share/rom/zelda.nes.zip.o \
|
||||
o/$(MODE)/usr/share/rom/tetris.nes.zip.o \
|
||||
o/$(MODE)/examples/examples.pkg \
|
||||
o/$(MODE)/examples/nesemu1.dbg: \
|
||||
$(EXAMPLES_DEPS) \
|
||||
o/$(MODE)/examples/nesemu1.o \
|
||||
o/$(MODE)/usr/share/rom/mario.nes.zip.o \
|
||||
o/$(MODE)/usr/share/rom/zelda.nes.zip.o \
|
||||
o/$(MODE)/usr/share/rom/tetris.nes.zip.o \
|
||||
o/$(MODE)/examples/examples.pkg \
|
||||
$(EXAMPLES_BOOTLOADER)
|
||||
@$(APELINK)
|
||||
|
||||
@@ -145,7 +145,7 @@ o/$(MODE)/examples/picol.o: private \
|
||||
CPPFLAGS += \
|
||||
-DSTACK_FRAME_UNLIMITED
|
||||
|
||||
o/$(MODE)/examples/picol.com.dbg: \
|
||||
o/$(MODE)/examples/picol.dbg: \
|
||||
$(EXAMPLES_DEPS) \
|
||||
o/$(MODE)/examples/picol.o \
|
||||
o/$(MODE)/examples/examples.pkg \
|
||||
@@ -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
|
||||
|
||||
@@ -166,8 +166,8 @@ o/$(MODE)/usr/share/dict/words: \
|
||||
################################################################################
|
||||
|
||||
.PHONY: o/$(MODE)/examples
|
||||
o/$(MODE)/examples: \
|
||||
o/$(MODE)/examples/package \
|
||||
o/$(MODE)/examples/pylife \
|
||||
o/$(MODE)/examples/pyapp \
|
||||
o/$(MODE)/examples: \
|
||||
o/$(MODE)/examples/package \
|
||||
o/$(MODE)/examples/pylife \
|
||||
o/$(MODE)/examples/pyapp \
|
||||
$(EXAMPLES_BINS)
|
||||
@@ -285,7 +285,7 @@ int main(int argc, char *argv[]) {
|
||||
// print all the ips that 0.0.0.0 would bind
|
||||
// Cosmo's GetHostIps() API is much easier than ioctl(SIOCGIFCONF)
|
||||
uint32_t *hostips;
|
||||
for (hostips = _gc(GetHostIps()), i = 0; hostips[i]; ++i) {
|
||||
for (hostips = gc(GetHostIps()), i = 0; hostips[i]; ++i) {
|
||||
kprintf("listening on http://%hhu.%hhu.%hhu.%hhu:%hu\n", hostips[i] >> 24,
|
||||
hostips[i] >> 16, hostips[i] >> 8, hostips[i], PORT);
|
||||
}
|
||||
@@ -339,7 +339,7 @@ int main(int argc, char *argv[]) {
|
||||
unassert(!pthread_attr_setguardsize(&attr, pagesz));
|
||||
unassert(!pthread_attr_setsigmask_np(&attr, &block));
|
||||
unassert(!pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, 0));
|
||||
pthread_t *th = _gc(calloc(threads, sizeof(pthread_t)));
|
||||
pthread_t *th = gc(calloc(threads, sizeof(pthread_t)));
|
||||
for (i = 0; i < threads; ++i) {
|
||||
int rc;
|
||||
++a_workers;
|
||||
|
||||
+2
-3
@@ -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:
|
||||
|
||||
+1
-1
@@ -50,7 +50,7 @@ void List(const char *path) {
|
||||
if (strcmp(path, ".") == 0) {
|
||||
vpath = "";
|
||||
} else if (!endswith(path, "/")) {
|
||||
vpath = _gc(xasprintf("%s/", path));
|
||||
vpath = gc(xasprintf("%s/", path));
|
||||
} else {
|
||||
vpath = path;
|
||||
}
|
||||
|
||||
+17
-17
@@ -14,13 +14,13 @@
|
||||
# GETTING STARTED
|
||||
#
|
||||
# # run these commands after cloning the cosmo repo on linux
|
||||
# $ make -j8 o//examples/pyapp/pyapp.com
|
||||
# $ o//examples/pyapp/pyapp.com
|
||||
# $ make -j8 o//examples/pyapp/pyapp
|
||||
# $ o//examples/pyapp/pyapp
|
||||
# cosmopolitan is cool!
|
||||
#
|
||||
# HOW IT WORKS
|
||||
#
|
||||
# $ pyobj.com -m -o pyapp.o pyapp.py
|
||||
# $ pyobj -m -o pyapp.o pyapp.py
|
||||
# $ ld -static -nostdlib -T o//ape/ape.lds ape.o crt.o \
|
||||
# pyapp.o \
|
||||
# cosmopolitan-python-stage2.a \
|
||||
@@ -29,19 +29,19 @@
|
||||
# cosmopolitan-bzip2.a \
|
||||
# cosmopolitan-python-stage1.a \
|
||||
# cosmopolitan.a
|
||||
# $ ./pyapp.com
|
||||
# $ ./pyapp
|
||||
# cosmopolitan is cool!
|
||||
#
|
||||
# NOTES
|
||||
#
|
||||
# If you enjoy this tutorial, let us know jtunney@gmail.com. If
|
||||
# If you enjoy this tutorial, let us know jtunney@gmail. If
|
||||
# you're building something cool, then we can we can add you to
|
||||
# our .gitowners file which grants you commit access so you can
|
||||
# indepnedently maintain your package, as part of the mono-repo
|
||||
|
||||
PKGS += PYAPP
|
||||
PYAPP = $(PYAPP_DEPS) o/$(MODE)/examples/pyapp/pyapp.a
|
||||
PYAPP_COMS = o/$(MODE)/examples/pyapp/pyapp.com
|
||||
PYAPP_COMS = o/$(MODE)/examples/pyapp/pyapp
|
||||
PYAPP_BINS = $(PYAPP_COMS) $(PYAPP_COMS:%=%.dbg)
|
||||
|
||||
# Specify our Cosmopolitan library dependencies
|
||||
@@ -58,7 +58,7 @@ PYAPP_DIRECTDEPS = \
|
||||
# them all out and arranges them in the correct order.
|
||||
PYAPP_DEPS := $(call uniq,$(foreach x,$(PYAPP_DIRECTDEPS),$($(x))))
|
||||
|
||||
# # Asks PYOBJ.COM to turn our Python source into an ELF object which
|
||||
# # Asks PYOBJ to turn our Python source into an ELF object which
|
||||
# # contains (a) embedded zip file artifacts of our .py file and .pyc
|
||||
# # which it it compiled; and (b) statically analyzed listings of our
|
||||
# # python namespaces and imports that GNU ld will use for tree shake
|
||||
@@ -71,18 +71,18 @@ PYAPP_DEPS := $(call uniq,$(foreach x,$(PYAPP_DIRECTDEPS),$($(x))))
|
||||
# in `.python/` (which is accessible via open() system calls, using
|
||||
# the synthetic path `"/zip/.python/"`) which means that if we want
|
||||
# to turn `pyapp/pyapp.py` into `.python/pyapp.py` so it's imported
|
||||
# using `import pyapp` then we can simply append to PYOBJ.COM flags
|
||||
# using `import pyapp` then we can simply append to PYOBJ flags
|
||||
# flags above asking it to strip one directory component and prefix
|
||||
# Lastly be sure that whenever you use this variable override trick
|
||||
# you only do it to .o files, since otherwise it'll ruin everything
|
||||
# Passing -m to PYOBJ.COM causes a C main() function to get yoinked
|
||||
# Passing -m to PYOBJ causes a C main() function to get yoinked
|
||||
# and it means our Python module can no longer be used as a library
|
||||
o/$(MODE)/examples/pyapp/pyapp.o: PYFLAGS += -m -C2 -P.python
|
||||
|
||||
# Asks PACKAGE.COM to sanity check our DIRECTDEPS and symbol graph.
|
||||
# Asks PACKAGE to sanity check our DIRECTDEPS and symbol graph.
|
||||
# This program functions as an incremental linker. It also provides
|
||||
# enhancements to the object code that GCC generated similar to LTO
|
||||
# so be certain that your .com.dbg rule depends on the .pkg output!
|
||||
# so be certain that your .dbg rule depends on the .pkg output!
|
||||
o/$(MODE)/examples/pyapp/pyapp.pkg: \
|
||||
o/$(MODE)/examples/pyapp/pyapp.o \
|
||||
$(foreach x,$(PYAPP_DIRECTDEPS),$($(x)_A).pkg)
|
||||
@@ -90,7 +90,7 @@ o/$(MODE)/examples/pyapp/pyapp.pkg: \
|
||||
# Ask GNU LD to link our APE executable within an ELF binary shell.
|
||||
# The CRT and APE dependencies are special dependencies that define
|
||||
# your _start() / WinMain() entrpoints as well as APE linker script
|
||||
o/$(MODE)/examples/pyapp/pyapp.com.dbg: \
|
||||
o/$(MODE)/examples/pyapp/pyapp.dbg: \
|
||||
$(PYAPP_DEPS) \
|
||||
o/$(MODE)/examples/pyapp/pyapp.pkg \
|
||||
o/$(MODE)/examples/pyapp/pyapp.o \
|
||||
@@ -98,10 +98,10 @@ o/$(MODE)/examples/pyapp/pyapp.com.dbg: \
|
||||
$(APE_NO_MODIFY_SELF)
|
||||
@$(COMPILE) -ALINK.ape $(LINK) $(LINKARGS) -o $@
|
||||
|
||||
# # Unwrap the APE .COM binary, that's embedded within the linked file
|
||||
# # Unwrap the APE binary, that's embedded within the linked file
|
||||
# # NOTE: This line can be commented out, since it's in build/rules.mk
|
||||
# o/$(MODE)/examples/pyapp/pyapp.com: \
|
||||
# o/$(MODE)/examples/pyapp/pyapp.com.dbg
|
||||
# o/$(MODE)/examples/pyapp/pyapp: \
|
||||
# o/$(MODE)/examples/pyapp/pyapp.dbg
|
||||
# $(OBJCOPY) -S -O binary $< $@
|
||||
|
||||
# Ensure that build config changes will invalidate build artifacts.
|
||||
@@ -112,5 +112,5 @@ o/$(MODE)/examples/pyapp/pyapp.o: \
|
||||
# and have it build all targets the package defines.
|
||||
.PHONY: o/$(MODE)/examples/pyapp
|
||||
o/$(MODE)/examples/pyapp: \
|
||||
o/$(MODE)/examples/pyapp/pyapp.com \
|
||||
o/$(MODE)/examples/pyapp/pyapp.com.dbg
|
||||
o/$(MODE)/examples/pyapp/pyapp \
|
||||
o/$(MODE)/examples/pyapp/pyapp.dbg
|
||||
+17
-17
@@ -14,13 +14,13 @@
|
||||
# GETTING STARTED
|
||||
#
|
||||
# # run these commands after cloning the cosmo repo on linux
|
||||
# $ make -j8 o//examples/pylife/pylife.com
|
||||
# $ o//examples/pylife/pylife.com
|
||||
# $ make -j8 o//examples/pylife/pylife
|
||||
# $ o//examples/pylife/pylife
|
||||
# cosmopolitan is cool!
|
||||
#
|
||||
# HOW IT WORKS
|
||||
#
|
||||
# $ pyobj.com -m -o pylife.o pylife.py
|
||||
# $ pyobj -m -o pylife.o pylife.py
|
||||
# $ ld -static -nostdlib -T o//ape/ape.lds ape.o crt.o \
|
||||
# pylife.o \
|
||||
# cosmopolitan-python-stage2.a \
|
||||
@@ -29,19 +29,19 @@
|
||||
# cosmopolitan-bzip2.a \
|
||||
# cosmopolitan-python-stage1.a \
|
||||
# cosmopolitan.a
|
||||
# $ ./pylife.com
|
||||
# $ ./pylife
|
||||
# cosmopolitan is cool!
|
||||
#
|
||||
# NOTES
|
||||
#
|
||||
# If you enjoy this tutorial, let us know jtunney@gmail.com. If
|
||||
# If you enjoy this tutorial, let us know jtunney@gmail. If
|
||||
# you're building something cool, then we can we can add you to
|
||||
# our .gitowners file which grants you commit access so you can
|
||||
# indepnedently maintain your package, as part of the mono-repo
|
||||
|
||||
PKGS += PYLIFE
|
||||
PYLIFE = $(PYLIFE_DEPS) o/$(MODE)/examples/pylife/pylife.a
|
||||
PYLIFE_COMS = o/$(MODE)/examples/pylife/pylife.com
|
||||
PYLIFE_COMS = o/$(MODE)/examples/pylife/pylife
|
||||
PYLIFE_BINS = $(PYLIFE_COMS) $(PYLIFE_COMS:%=%.dbg)
|
||||
|
||||
# Specify our Cosmopolitan library dependencies
|
||||
@@ -58,7 +58,7 @@ PYLIFE_DIRECTDEPS = \
|
||||
# them all out and arranges them in the correct order.
|
||||
PYLIFE_DEPS := $(call uniq,$(foreach x,$(PYLIFE_DIRECTDEPS),$($(x))))
|
||||
|
||||
# # Asks PYOBJ.COM to turn our Python source into an ELF object which
|
||||
# # Asks PYOBJ to turn our Python source into an ELF object which
|
||||
# # contains (a) embedded zip file artifacts of our .py file and .pyc
|
||||
# # which it it compiled; and (b) statically analyzed listings of our
|
||||
# # python namespaces and imports that GNU ld will use for tree shake
|
||||
@@ -71,18 +71,18 @@ PYLIFE_DEPS := $(call uniq,$(foreach x,$(PYLIFE_DIRECTDEPS),$($(x))))
|
||||
# in `.python/` (which is accessible via open() system calls, using
|
||||
# the synthetic path `"/zip/.python/"`) which means that if we want
|
||||
# to turn `pylife/pylife.py` into `.python/pylife.py` so it's imported
|
||||
# using `import pylife` then we can simply append to PYOBJ.COM flags
|
||||
# using `import pylife` then we can simply append to PYOBJ flags
|
||||
# flags above asking it to strip one directory component and prefix
|
||||
# Lastly be sure that whenever you use this variable override trick
|
||||
# you only do it to .o files, since otherwise it'll ruin everything
|
||||
# Passing -m to PYOBJ.COM causes a C main() function to get yoinked
|
||||
# Passing -m to PYOBJ causes a C main() function to get yoinked
|
||||
# and it means our Python module can no longer be used as a library
|
||||
o/$(MODE)/examples/pylife/pylife.o: PYFLAGS += -m -C2 -P.python
|
||||
|
||||
# Asks PACKAGE.COM to sanity check our DIRECTDEPS and symbol graph.
|
||||
# Asks PACKAGE to sanity check our DIRECTDEPS and symbol graph.
|
||||
# This program functions as an incremental linker. It also provides
|
||||
# enhancements to the object code that GCC generated similar to LTO
|
||||
# so be certain that your .com.dbg rule depends on the .pkg output!
|
||||
# so be certain that your .dbg rule depends on the .pkg output!
|
||||
o/$(MODE)/examples/pylife/pylife.pkg: \
|
||||
o/$(MODE)/examples/pylife/pylife.o \
|
||||
$(foreach x,$(PYLIFE_DIRECTDEPS),$($(x)_A).pkg)
|
||||
@@ -90,7 +90,7 @@ o/$(MODE)/examples/pylife/pylife.pkg: \
|
||||
# Ask GNU LD to link our APE executable within an ELF binary shell.
|
||||
# The CRT and APE dependencies are special dependencies that define
|
||||
# your _start() / WinMain() entrpoints as well as APE linker script
|
||||
o/$(MODE)/examples/pylife/pylife.com.dbg: \
|
||||
o/$(MODE)/examples/pylife/pylife.dbg: \
|
||||
$(PYLIFE_DEPS) \
|
||||
o/$(MODE)/examples/pylife/pylife.pkg \
|
||||
o/$(MODE)/examples/pylife/pylife.o \
|
||||
@@ -98,10 +98,10 @@ o/$(MODE)/examples/pylife/pylife.com.dbg: \
|
||||
$(APE_NO_MODIFY_SELF)
|
||||
@$(COMPILE) -ALINK.ape $(LINK) $(LINKARGS) -o $@
|
||||
|
||||
# # Unwrap the APE .COM binary, that's embedded within the linked file
|
||||
# # Unwrap the APE binary, that's embedded within the linked file
|
||||
# # NOTE: This line can be commented out, since it's in build/rules.mk
|
||||
# o/$(MODE)/examples/pylife/pylife.com: \
|
||||
# o/$(MODE)/examples/pylife/pylife.com.dbg
|
||||
# o/$(MODE)/examples/pylife/pylife: \
|
||||
# o/$(MODE)/examples/pylife/pylife.dbg
|
||||
# $(OBJCOPY) -S -O binary $< $@
|
||||
|
||||
# Ensure that build config changes will invalidate build artifacts.
|
||||
@@ -112,5 +112,5 @@ o/$(MODE)/examples/pylife/pylife.o: \
|
||||
# and have it build all targets the package defines.
|
||||
.PHONY: o/$(MODE)/examples/pylife
|
||||
o/$(MODE)/examples/pylife: \
|
||||
o/$(MODE)/examples/pylife/pylife.com \
|
||||
o/$(MODE)/examples/pylife/pylife.com.dbg
|
||||
o/$(MODE)/examples/pylife/pylife \
|
||||
o/$(MODE)/examples/pylife/pylife.dbg
|
||||
+4
-7
@@ -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
|
||||
|
||||
|
||||
+4
-4
@@ -80,10 +80,10 @@ void PrintFileMetadata(const char *pathname, struct stat *st) {
|
||||
DescribeFileType(st->st_mode), "owner id", st->st_uid, "group id",
|
||||
st->st_gid, "flags", st->st_flags, "gen", st->st_gen,
|
||||
"device id (if special)", st->st_rdev, "block size", st->st_blksize,
|
||||
"access time", _gc(xiso8601(&st->st_atim)), "modified time",
|
||||
_gc(xiso8601(&st->st_mtim)), "c[omplicated]time",
|
||||
_gc(xiso8601(&st->st_ctim)), "birthtime",
|
||||
_gc(xiso8601(&st->st_birthtim)));
|
||||
"access time", gc(xiso8601(&st->st_atim)), "modified time",
|
||||
gc(xiso8601(&st->st_mtim)), "c[omplicated]time",
|
||||
gc(xiso8601(&st->st_ctim)), "birthtime",
|
||||
gc(xiso8601(&st->st_birthtim)));
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
|
||||
@@ -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"
|
||||
|
||||
|
||||
+18
-20
@@ -128,7 +128,7 @@
|
||||
#include "libc/macros.internal.h"
|
||||
#include "libc/mem/alg.h"
|
||||
#include "libc/mem/alloca.h"
|
||||
#include "libc/mem/gc.internal.h"
|
||||
#include "libc/mem/gc.h"
|
||||
#include "libc/mem/mem.h"
|
||||
#include "libc/paths.h"
|
||||
#include "libc/runtime/runtime.h"
|
||||
@@ -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
@@ -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"
|
||||
|
||||
@@ -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
@@ -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
@@ -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
@@ -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
|
||||
|
||||
+1
-1
@@ -23,7 +23,7 @@
|
||||
* Changes permissions on file, e.g.:
|
||||
*
|
||||
* CHECK_NE(-1, chmod("foo/bar.txt", 0644));
|
||||
* CHECK_NE(-1, chmod("o/default/program.com", 0755));
|
||||
* CHECK_NE(-1, chmod("o/default/program", 0755));
|
||||
* CHECK_NE(-1, chmod("privatefolder/", 0700));
|
||||
*
|
||||
* The esoteric bits generally available on System Five are:
|
||||
|
||||
@@ -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,
|
||||
};
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
@@ -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) {
|
||||
|
||||
@@ -36,7 +36,7 @@ int sys_fchmodat2(int, const char *, unsigned, int);
|
||||
* Changes permissions on file, e.g.:
|
||||
*
|
||||
* CHECK_NE(-1, fchmodat(AT_FDCWD, "foo/bar.txt", 0644));
|
||||
* CHECK_NE(-1, fchmodat(AT_FDCWD, "o/default/program.com", 0755));
|
||||
* CHECK_NE(-1, fchmodat(AT_FDCWD, "o/default/program", 0755));
|
||||
* CHECK_NE(-1, fchmodat(AT_FDCWD, "privatefolder/", 0700));
|
||||
*
|
||||
* @param path must exist
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -71,7 +71,7 @@ static textwindows long GetSizeOfReparsePoint(int64_t fh) {
|
||||
}
|
||||
}
|
||||
if (x >= 0200) {
|
||||
z += _bsrl(tpenc(x)) >> 3;
|
||||
z += bsrl(tpenc(x)) >> 3;
|
||||
}
|
||||
++z;
|
||||
}
|
||||
|
||||
+1
-1
@@ -60,4 +60,4 @@ int fstat(int fd, struct stat *st) {
|
||||
return rc;
|
||||
}
|
||||
|
||||
__strong_reference(fstat, fstat64);
|
||||
__weak_reference(fstat, fstat64);
|
||||
@@ -33,11 +33,27 @@
|
||||
#include "libc/sysv/consts/fileno.h"
|
||||
#include "libc/sysv/errfuns.h"
|
||||
|
||||
static int Atoi(const char *str) {
|
||||
int c;
|
||||
unsigned x = 0;
|
||||
if (!*str) return -1;
|
||||
while ((c = *str++)) {
|
||||
if ('0' <= c && c <= '9') {
|
||||
x *= 10;
|
||||
x += c - '0';
|
||||
} else {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
return x;
|
||||
}
|
||||
|
||||
textwindows int sys_fstatat_nt(int dirfd, const char *path, struct stat *st,
|
||||
int flags) {
|
||||
|
||||
// handle special files
|
||||
if (startswith(path, "/dev/")) {
|
||||
int fd;
|
||||
if (!strcmp(path + 5, "tty")) {
|
||||
return sys_fstat_nt_special(kFdConsole, st);
|
||||
} else if (!strcmp(path + 5, "null")) {
|
||||
@@ -48,6 +64,8 @@ textwindows int sys_fstatat_nt(int dirfd, const char *path, struct stat *st,
|
||||
return sys_fstat_nt(STDOUT_FILENO, st);
|
||||
} else if (!strcmp(path + 5, "stderr")) {
|
||||
return sys_fstat_nt(STDERR_FILENO, st);
|
||||
} else if (startswith(path + 5, "fd/") && (fd = Atoi(path + 8)) != -1) {
|
||||
return sys_fstat_nt(fd, st);
|
||||
} else {
|
||||
return enoent();
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
@@ -87,4 +87,4 @@ int ftruncate(int fd, int64_t length) {
|
||||
return rc;
|
||||
}
|
||||
|
||||
__strong_reference(ftruncate, ftruncate64);
|
||||
__weak_reference(ftruncate, ftruncate64);
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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,
|
||||
};
|
||||
@@ -25,6 +25,7 @@
|
||||
#include "libc/errno.h"
|
||||
#include "libc/fmt/libgen.h"
|
||||
#include "libc/intrin/getenv.internal.h"
|
||||
#include "libc/intrin/strace.internal.h"
|
||||
#include "libc/limits.h"
|
||||
#include "libc/macros.internal.h"
|
||||
#include "libc/nt/runtime.h"
|
||||
@@ -117,6 +118,8 @@ static char *CopyWithCwd(const char *q, char *p, char *e) {
|
||||
|
||||
// if q exists then turn it into an absolute path. we also try adding
|
||||
// a .com suffix since the ape auto-appends it when resolving
|
||||
//
|
||||
// TODO(jart): is this still relevant?
|
||||
static int TryPath(const char *q, int com) {
|
||||
char *p;
|
||||
if (!(p = CopyWithCwd(q, g_prog.u.buf,
|
||||
@@ -260,5 +263,6 @@ static void InitProgramExecutableName(void) {
|
||||
*/
|
||||
char *GetProgramExecutableName(void) {
|
||||
cosmo_once(&g_prog.once, InitProgramExecutableName);
|
||||
STRACE("GetProgramExecutableName() → %#s", __program_executable_name);
|
||||
return __program_executable_name;
|
||||
}
|
||||
@@ -88,12 +88,14 @@ static ssize_t GetDevUrandom(char *p, size_t n) {
|
||||
int fd;
|
||||
ssize_t rc;
|
||||
BLOCK_SIGNALS;
|
||||
BLOCK_CANCELATION;
|
||||
fd = sys_openat(AT_FDCWD, "/dev/urandom", O_RDONLY | O_CLOEXEC, 0);
|
||||
if (fd != -1) {
|
||||
rc = sys_read(fd, p, n);
|
||||
} else {
|
||||
rc = -1;
|
||||
}
|
||||
ALLOW_CANCELATION;
|
||||
ALLOW_SIGNALS;
|
||||
return rc;
|
||||
}
|
||||
@@ -101,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);
|
||||
@@ -129,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
|
||||
@@ -188,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;
|
||||
|
||||
Loaded 100 of 2561 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user